Tutorial 10 min read

Claude AI for Trading: Using Tool Use with Financial APIs

Build a Claude-powered trading analyst using Anthropic's tool use feature and the TickAtlas API for real-time market data. Includes complete Python implementation.

8Sections
4Code samples
10Min read
TutorialCategory

Why Claude for Trading Analysis?

Claude excels at nuanced analysis and following complex instructions. Its tool use capability lets you connect it to live market data APIs, and its large context window means it can analyze extensive historical patterns in a single conversation. For trading analysis, Claude's tendency to express uncertainty honestly is a feature, not a bug — you want your AI to say "the signals are mixed" rather than hallucinate conviction.

Defining Tools for Claude

Anthropic's tool use syntax is slightly different from OpenAI's. Here is how to define the TickAtlas API tools for Claude:

Shell Defining Tools for Claude
tools = [
    {
        "name": "get_technical_indicators",
        "description": "Fetch real-time technical indicator values for a forex or crypto trading pair from the TickAtlas API.",
        "input_schema": {
            "type": "object",
            "properties": {
                "symbol": {
                    "type": "string",
                    "description": "The trading pair symbol, e.g. EURUSD, XAUUSD, BTCUSD"
                },
                "timeframe": {
                    "type": "string",
                    "enum": ["M5", "M15", "H1", "H4", "D1"],
                    "description": "The candle timeframe"
                },
                "indicators": {
                    "type": "string",
                    "description": "Comma-separated indicator names: RSI_14, MACD_main, MACD_signal, MACD_hist, BB_upper, BB_middle, BB_lower, ADX, ATR_14, EMA_10, EMA_20, Stochastic_K, Stochastic_D, Ichimoku_tenkan, Ichimoku_kijun"
                }
            },
            "required": ["symbol", "timeframe", "indicators"]
        }
    },
    {
        "name": "get_price_quote",
        "description": "Get the current bid/ask price for a trading pair.",
        "input_schema": {
            "type": "object",
            "properties": {
                "symbol": {
                    "type": "string",
                    "description": "The trading pair symbol"
                }
            },
            "required": ["symbol"]
        }
    },
    {
        "name": "get_ohlc_history",
        "description": "Fetch historical OHLC candle data for backtesting or trend analysis.",
        "input_schema": {
            "type": "object",
            "properties": {
                "symbol": {"type": "string"},
                "timeframe": {"type": "string"},
                "limit": {"type": "integer", "description": "Number of candles (max 1000)"}
            },
            "required": ["symbol", "timeframe"]
        }
    }
]

Implementing Tool Handlers

Python Implementing Tool Handlers
import json
import requests

CLAW_API_KEY = "your_tickatlas_api_key"
CLAW_BASE = "https://tickatlas.com/v1"
CLAW_HEADERS = {"X-API-Key": CLAW_API_KEY}

def handle_tool(name: str, inputs: dict) -> str:
    """Route tool calls to the TickAtlas API."""
    if name == "get_technical_indicators":
        # The endpoint returns all 42; trim to the keys Claude asked for.
        resp = requests.get(f"{CLAW_BASE}/indicators", params={
            "symbol": inputs["symbol"],
            "timeframe": inputs["timeframe"],
        }, headers=CLAW_HEADERS)
        all_ind = resp.json()["data"]["indicators"]
        wanted = [k.strip() for k in inputs["indicators"].split(",")]
        return json.dumps({k: all_ind[k] for k in wanted if k in all_ind})

    elif name == "get_price_quote":
        resp = requests.get(f"{CLAW_BASE}/quote", params={
            "symbol": inputs["symbol"]
        }, headers=CLAW_HEADERS)
        return resp.text

    elif name == "get_ohlc_history":
        resp = requests.get(f"{CLAW_BASE}/ohlc", params={
            "symbol": inputs["symbol"],
            "timeframe": inputs["timeframe"],
            "limit": inputs["bars"]
        }, headers=CLAW_HEADERS)
        return resp.text

    return '{"error": "Unknown tool"}'

The Conversation Loop

Python The Conversation Loop
import anthropic
import json

client = anthropic.Anthropic()

SYSTEM = """You are a professional trading analyst with access to
real-time market data. When analyzing markets:
1. Always fetch live data before making claims about current conditions
2. Cite specific indicator values in your analysis
3. Consider multiple timeframes when relevant
4. Note any conflicting signals honestly
5. Never recommend specific trade entries — provide analysis only"""

def analyze(question: str) -> str:
    messages = [{"role": "user", "content": question}]

    while True:
        response = client.messages.create(
            model="claude-sonnet-4-20250514",
            max_tokens=4096,
            system=SYSTEM,
            tools=tools,
            messages=messages
        )

        # Check if Claude wants to use a tool
        if response.stop_reason == "tool_use":
            # Add Claude's response (with tool_use blocks)
            messages.append({"role": "assistant", "content": response.content})

            # Process each tool call
            tool_results = []
            for block in response.content:
                if block.type == "tool_use":
                    result = handle_tool(block.name, block.input)
                    tool_results.append({
                        "type": "tool_result",
                        "tool_use_id": block.id,
                        "content": result
                    })

            messages.append({"role": "user", "content": tool_results})
        else:
            # Claude is done — extract text response
            return "".join(
                b.text for b in response.content if b.type == "text"
            )

# Example usage
analysis = analyze("Analyze XAUUSD — is it a good time to buy gold?")
print(analysis)

Example Output

"Based on the current data for XAUUSD on the H1 timeframe: RSI is at 42.3 (neutral territory), MACD histogram is slightly positive at 0.45 indicating mild bullish momentum, and the price at $2,341.50 is sitting just above the Bollinger middle band ($2,338.20). The ADX at 18.7 suggests the market is not strongly trending in either direction. On the H4 timeframe, the picture is slightly more bearish — RSI is at 38.1 and price is below the EMA 21. The signals are mixed: short-term momentum is mildly bullish, but the larger timeframe trend is neutral to bearish. I would not characterize this as a strong buying opportunity based on the technical indicators alone."

Advanced: Multi-Step Analysis

Claude can chain multiple tool calls in a single turn. Ask it to "compare the momentum of all major pairs" and it will fetch indicators for EURUSD, GBPUSD, USDJPY, AUDUSD, and USDCHF in sequence, then synthesize the results into a comparative analysis.

Shell Advanced: Multi-Step Analysis
# Claude will automatically make multiple tool calls
analysis = analyze("""
    Compare RSI and MACD across EURUSD, GBPUSD, USDJPY, and XAUUSD
    on both H1 and H4 timeframes. Which pair has the strongest
    momentum right now?
""")
# Claude fetches 8 sets of indicators (4 pairs x 2 timeframes)
# and synthesizes the results

Claude vs ChatGPT for Trading

Claude Strengths

  • More cautious and honest about uncertainty
  • Larger context window for extensive analysis
  • Better at following detailed system prompts
  • Extended thinking for complex analysis

ChatGPT Strengths

  • Broader plugin ecosystem
  • More direct/decisive in recommendations
  • Code interpreter for on-the-fly calculations
  • Established custom GPT marketplace

Further Reading

Run this against live data.

Every account starts pay-as-you-go with $2.50 of credit and no card. Paste the key into the samples above and the requests work unchanged.

Prefer the API to the article

Build it instead of reading about it.

Create a key, run the first request, then extend one layer at a time. Every account starts pay-as-you-go with $2.50 of credit — no card required.