Building a Multi-Agent Trading System with Claude and TickAtlas
Design and implement a multi-agent trading system where specialized AI agents handle analysis, risk management, and execution using real-time market data.
Why Multiple Agents?
A single monolithic trading AI tries to do everything: analyze charts, evaluate risk, interpret news, and decide position sizes. This leads to bloated prompts, inconsistent outputs, and difficulty debugging.
A multi-agent architecture assigns each responsibility to a specialized agent. The Technical Analyst reads indicators. The Risk Manager sizes positions. The Execution Agent handles order logic. Each agent is small, testable, and replaceable.
Reads indicators, identifies setups
Sizes positions, sets stops
Validates and routes orders
System Architecture
TickAtlas API (real-time data)
|
[Data Layer] -- fetches indicators, OHLCV, spreads
|
[Analyst Agent] -- identifies trade setups
|
[Risk Manager Agent] -- evaluates risk, sizes position
|
[Execution Agent] -- validates and prepares order
|
[Human Review] -- final approval before execution
The Data Layer
import requests
import json
from dataclasses import dataclass
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://tickatlas.com/v1"
@dataclass
class MarketSnapshot:
symbol: str
timeframe: str
close: float
rsi: float
macd_hist: float
ema_50: float
ema_200: float
atr: float
stochastic_k: float
def fetch_snapshot(symbol: str, timeframe: str) -> MarketSnapshot:
"""Fetch all indicators needed for analysis."""
indicators = ["RSI_14", "MACD", "EMA_50", "EMA_200", "ATR_14", "STOCHASTIC"]
values = {}
ohlcv = {}
for ind in indicators:
resp = requests.get(
f"{BASE_URL}/indicator",
headers={"X-API-Key": API_KEY},
params={"symbol": symbol, "indicator": ind, "timeframe": timeframe},
)
data = resp.json()["data"]
values[ind] = data["values"]
if not ohlcv:
ohlcv = data["ohlcv"]
return MarketSnapshot(
symbol=symbol,
timeframe=timeframe,
close=ohlcv["close"],
rsi=values["RSI_14"]["rsi"],
macd_hist=values["MACD"]["histogram"],
ema_50=values["EMA_50"]["value"],
ema_200=values["EMA_200"]["value"],
atr=values["ATR_14"]["atr"],
stochastic_k=values["STOCHASTIC"]["k"],
) Agent 1: Technical Analyst
import anthropic
claude = anthropic.Anthropic()
ANALYST_PROMPT = """You are a technical analyst. Based on the data below,
identify any trade setup. Respond in JSON.
Symbol: {symbol} ({timeframe})
Close: {close}
RSI(14): {rsi}
MACD Histogram: {macd_hist}
EMA 50: {ema_50}
EMA 200: {ema_200}
Stochastic %K: {stochastic_k}
Respond with:
{{"setup_found": true/false, "direction": "long"/"short"/null,
"reasoning": "...", "confidence": "low"/"medium"/"high",
"entry_zone": [low, high]}}"""
def analyst_agent(snapshot: MarketSnapshot) -> dict:
response = claude.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=500,
messages=[{"role": "user", "content": ANALYST_PROMPT.format(
symbol=snapshot.symbol, timeframe=snapshot.timeframe,
close=snapshot.close, rsi=snapshot.rsi,
macd_hist=snapshot.macd_hist, ema_50=snapshot.ema_50,
ema_200=snapshot.ema_200, stochastic_k=snapshot.stochastic_k,
)}],
)
return json.loads(response.content[0].text) Agent 2: Risk Manager
RISK_PROMPT = """You are a risk manager. Given this trade setup and account
info, determine position sizing and stop placement.
Trade Setup: {setup}
ATR(14): {atr}
Account Balance: \${balance}
Max Risk Per Trade: {risk_pct}%
Respond with:
{{"approved": true/false, "position_size_lots": X.XX,
"stop_loss": X.XXXXX, "take_profit": X.XXXXX,
"risk_amount": X.XX, "risk_reward_ratio": X.X,
"rejection_reason": null/"reason"}}"""
def risk_manager_agent(
setup: dict, snapshot: MarketSnapshot,
balance: float = 10000, risk_pct: float = 1.0
) -> dict:
response = claude.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=500,
messages=[{"role": "user", "content": RISK_PROMPT.format(
setup=json.dumps(setup), atr=snapshot.atr,
balance=balance, risk_pct=risk_pct,
)}],
)
return json.loads(response.content[0].text) Orchestrating the Pipeline
def run_trading_pipeline(symbol: str, timeframe: str) -> dict:
"""Run the full multi-agent trading pipeline."""
# Step 1: Fetch market data
snapshot = fetch_snapshot(symbol, timeframe)
# Step 2: Analyst identifies setup
setup = analyst_agent(snapshot)
if not setup["setup_found"]:
return {"action": "NO_TRADE", "reason": "No setup found"}
# Step 3: Risk manager evaluates
risk = risk_manager_agent(setup, snapshot)
if not risk["approved"]:
return {"action": "REJECTED", "reason": risk["rejection_reason"]}
# Step 4: Return for human review (never auto-execute)
return {
"action": "PENDING_REVIEW",
"symbol": symbol,
"direction": setup["direction"],
"confidence": setup["confidence"],
"entry_zone": setup["entry_zone"],
"stop_loss": risk["stop_loss"],
"take_profit": risk["take_profit"],
"position_size": risk["position_size_lots"],
"risk_amount": risk["risk_amount"],
"reasoning": setup["reasoning"],
}
# Run on multiple symbols
for sym in ["EURUSD", "GBPUSD", "XAUUSD"]:
result = run_trading_pipeline(sym, "H4")
print(f"\n{sym}: {result['action']}")
if result["action"] == "PENDING_REVIEW":
print(f" Direction: {result['direction']}")
print(f" Size: {result['position_size']} lots")
print(f" SL: {result['stop_loss']} / TP: {result['take_profit']}") Key Design Principles
Each agent has a single responsibility
The analyst never calculates position sizes. The risk manager never identifies setups. Clean boundaries make each agent easier to test and improve independently.
Data flows one direction
Raw data goes in, structured decisions come out. No circular dependencies between agents. The pipeline is linear and predictable.
Human in the loop
The system generates trade proposals, not trade executions. A human reviews and approves before any real money moves. This is non-negotiable.
Related Reading
Try this with live data
Every account gets $2.50 in free PAYG credits. No card required — paste your API key and run the code above against live broker data.
Keep reading
All articles- Tutorial 11 min read
24/7 Crypto Monitoring: Building Always-On Analysis Systems
Build a monitoring system that watches crypto markets around the clock, detects significant moves, and sends alerts when conditions match your criteria.
March 28, 2026
- Tutorial 12 min read
How to Build an AI Market Analyst That Runs 24/7
Build a production-ready AI market analyst that monitors forex and crypto markets around the clock, generates daily briefings, and alerts you to opportunities via Telegram.
March 28, 2026
- Tutorial 10 min read
Using ATR for Dynamic Stop-Loss Placement
Learn how to use Average True Range (ATR) to set volatility-adjusted stop losses that adapt to market conditions, with full code examples.
March 28, 2026