Bot ~20 min setup
Discord Bot Integration
Bring live market data to your Discord server. Slash commands for indicators and quotes, rich embeds with color-coded signals, and scheduled hourly market updates.
Prerequisites
Choose Python (discord.py) or JavaScript (discord.js):
bash
# Python
pip install discord.py requests
# JavaScript
npm install discord.js - Create a bot at discord.com/developers
- Enable the applications.commands scope
- Invite the bot to your server with slash command permissions
Python Bot (discord.py)
python
import os
import discord
from discord import app_commands
from discord.ext import commands, tasks
import requests
CLAW_API_KEY = os.environ["CLAW_API_KEY"]
DISCORD_TOKEN = os.environ["DISCORD_BOT_TOKEN"]
CLAW_BASE = "https://tickatlas.com/v1"
intents = discord.Intents.default()
bot = commands.Bot(command_prefix="!", intents=intents)
def claw_request(endpoint: str, params: dict) -> dict:
resp = requests.get(
f"{CLAW_BASE}/{endpoint}",
headers={"X-API-Key": CLAW_API_KEY},
params=params,
timeout=10,
)
resp.raise_for_status()
return resp.json()
@bot.event
async def on_ready():
await bot.tree.sync()
hourly_update.start()
print(f"Bot ready: {bot.user}")
@bot.tree.command(name="rsi", description="Get RSI for a trading symbol")
@app_commands.describe(symbol="Symbol (e.g. EURUSD)", timeframe="Timeframe (default: H1)")
async def rsi(interaction: discord.Interaction, symbol: str, timeframe: str = "H1"):
await interaction.response.defer()
try:
data = claw_request("indicator", {
"symbol": symbol.upper(), "indicator": "RSI_14", "timeframe": timeframe.upper(),
})
color = discord.Color.green() if data["value"] < 40 else (
discord.Color.red() if data["value"] > 60 else discord.Color.gold()
)
embed = discord.Embed(
title=f"RSI(14) for {data['symbol']}",
color=color,
)
embed.add_field(name="Value", value=f"**{data['value']:.2f}**", inline=True)
embed.add_field(name="Signal", value=data["signal"].capitalize(), inline=True)
embed.add_field(name="Timeframe", value=timeframe.upper(), inline=True)
embed.add_field(name="Close Price", value=str(data["ohlc"]["close"]), inline=True)
embed.set_footer(text=f"Data age: {data['metadata']['data_age_seconds']}s")
await interaction.followup.send(embed=embed)
except Exception as e:
await interaction.followup.send(f"Error: {e}")
@bot.tree.command(name="summary", description="Get AI market summary for a symbol")
@app_commands.describe(symbol="Symbol", timeframe="Timeframe (default: H1)")
async def summary(interaction: discord.Interaction, symbol: str, timeframe: str = "H1"):
await interaction.response.defer()
try:
data = claw_request("summary", {
"symbol": symbol.upper(), "timeframe": timeframe.upper(),
})
bias_colors = {"bullish": discord.Color.green(), "bearish": discord.Color.red(), "neutral": discord.Color.gold()}
embed = discord.Embed(
title=f"AI Summary: {data['symbol']} ({timeframe.upper()})",
description=data["narrative"],
color=bias_colors.get(data["bias"], discord.Color.default()),
)
embed.add_field(name="Bias", value=f"**{data['bias'].upper()}**", inline=True)
embed.add_field(name="Confidence", value=f"**{data['confidence']}%**", inline=True)
await interaction.followup.send(embed=embed)
except Exception as e:
await interaction.followup.send(f"Error: {e}")
bot.run(DISCORD_TOKEN) Scheduled Channel Updates
Post automatic market summaries to a designated channel every hour:
python
MARKET_CHANNEL_ID = 123456789012345678 # Your channel ID
@tasks.loop(hours=1)
async def hourly_update():
channel = bot.get_channel(MARKET_CHANNEL_ID)
if not channel:
return
symbols = ["EURUSD", "GBPUSD", "XAUUSD", "BTCUSD"]
embed = discord.Embed(
title="Hourly Market Update",
color=discord.Color.blue(),
timestamp=discord.utils.utcnow(),
)
for sym in symbols:
try:
data = claw_request("indicator", {
"symbol": sym, "indicator": "RSI_14", "timeframe": "H1",
})
summary_data = claw_request("summary", {"symbol": sym, "timeframe": "H1"})
embed.add_field(
name=sym,
value=(
f"RSI: **{data['value']:.1f}** ({data['signal']})\n"
f"Bias: **{summary_data['bias']}** ({summary_data['confidence']}%)"
),
inline=True,
)
except Exception:
embed.add_field(name=sym, value="Data unavailable", inline=True)
embed.set_footer(text="Powered by TickAtlas API")
await channel.send(embed=embed)
@hourly_update.before_loop
async def before_hourly():
await bot.wait_until_ready() Slash Commands
| Command | Description |
|---|---|
| /rsi EURUSD H1 | RSI value with colored embed |
| /summary XAUUSD H4 | AI market analysis embed |
| /quote GBPUSD | Live bid/ask/spread |
| /screener RSI_14 30 | Find oversold instruments |