I Connected Claude AI to Freqtrade in 5 Lines of Code published: true.

# python# trading# ai# opensource
I Connected Claude AI to Freqtrade in 5 Lines of Code published: true.PULSE Protocol

The problem with AI-driven trading bots You want to use Claude or GPT to analyze the market and...

The problem with AI-driven trading bots

You want to use Claude or GPT to analyze the market and trade automatically. The usual approach looks like this:

  1. Call the AI API
  2. Parse the response (pray the format is consistent)
  3. Map it to Binance/Bybit API calls
  4. Handle authentication, signatures, rate limits
  5. Write all of this from scratch for every exchange

You end up with hundreds of lines of glue code before writing a single line of actual trading logic.

There's a better way.


PULSE Protocol

PULSE is an open-source semantic messaging standard for AI-to-AI communication. Think of it as a universal language — every agent speaks PULSE, regardless of whether it's Claude, GPT, Freqtrade, or Binance.

A PULSE message looks like this:

PulseMessage(
    action="ACT.RECOMMEND.ACTION",
    parameters={
        "pair": "BTC/USDT",
        "direction": "long",
        "confidence": 0.92,
        "reason": "RSI < 25, bullish divergence on 4h"
    }
)
Enter fullscreen mode Exit fullscreen mode

Same format. Every agent. Every exchange. No custom parsers.

Today I'm releasing pulse-freqtrade — a PULSE adapter for Freqtrade, the most popular open-source crypto trading bot framework.


What pulse-freqtrade does

Two things:

1. Control a running Freqtrade bot via PULSE messages

from pulse_freqtrade import FreqtradeAdapter
from pulse.message import PulseMessage

adapter = FreqtradeAdapter(
    url="http://localhost:8080",
    username="freqtrader",
    password="SuperSecurePassword",
)
adapter.connect()

# Check open trades
response = adapter.send(PulseMessage(action="ACT.QUERY.STATUS", parameters={}))
trades = response.content["parameters"]["result"]

# Force buy
adapter.send(PulseMessage(
    action="ACT.TRANSACT.REQUEST",
    parameters={"pair": "BTC/USDT", "stake_amount": 100}
))

# Stop the bot
adapter.send(PulseMessage(action="ACT.STOP", parameters={}))
Enter fullscreen mode Exit fullscreen mode

2. Inject AI signals into your strategy at runtime

Your strategy extends PulseStrategy instead of IStrategy. A SignalListener starts an HTTP endpoint on port 9999. Any external AI agent POSTs a signal there — your strategy picks it up on the next candle.


The full setup: Claude → Freqtrade

Here's a complete working example.

Step 1: Install

pip install pulse-freqtrade pulse-anthropic
Enter fullscreen mode Exit fullscreen mode

Step 2: Write your strategy

Create user_data/strategies/claude_strategy.py:

from pulse_freqtrade import PulseStrategy, SignalListener

class ClaudeStrategy(PulseStrategy):
    timeframe = "1h"
    pulse_agent_id = "claude-trader"

    # Start AI signal listener
    _listener = SignalListener(port=9999)
    _listener.start()

    def populate_entry_trend(self, dataframe, metadata):
        # Check signals from Claude
        signals = self.get_pulse_signals(metadata["pair"])

        if signals:
            signal = signals[0]
            params = signal.content["parameters"]

            if params["direction"] == "long" and params["confidence"] > 0.80:
                dataframe["enter_long"] = 1
                return dataframe

        # Fallback: your normal RSI logic
        dataframe.loc[dataframe["rsi"] < 30, "enter_long"] = 1
        return dataframe

    def populate_exit_trend(self, dataframe, metadata):
        signals = self.get_pulse_signals(metadata["pair"])

        if signals:
            if signals[0].content["parameters"]["direction"] == "short":
                dataframe["exit_long"] = 1
                return dataframe

        dataframe.loc[dataframe["rsi"] > 70, "exit_long"] = 1
        return dataframe
Enter fullscreen mode Exit fullscreen mode

Step 3: Write the Claude agent

This runs separately — on your machine, a server, anywhere:

import requests
from pulse_anthropic import AnthropicAdapter
from pulse.message import PulseMessage

# Ask Claude to analyze the market
adapter = AnthropicAdapter(api_key="sk-ant-...")
analysis = adapter.send(PulseMessage(
    action="ACT.ANALYZE.SENTIMENT",
    parameters={
        "text": """
        BTC/USDT 1h chart:
        - RSI: 23 (oversold)
        - Price: $83,200, below 200 SMA
        - Last 3 candles: bullish divergence
        - Volume: 40% above average

        Should I open a long position?
        Answer with JSON: {"direction": "long/short/neutral", "confidence": 0-1, "reason": "..."}
        """
    }
))

# Parse Claude's response
import json
result = json.loads(analysis.content["parameters"]["result"]["content"])

# Send to Freqtrade via PULSE
requests.post("http://localhost:9999/", json={
    "action": "ACT.RECOMMEND.ACTION",
    "parameters": {
        "pair": "BTC/USDT",
        "direction": result["direction"],
        "confidence": result["confidence"],
        "reason": result["reason"],
        "agent_id": "claude-sonnet"
    }
})

print(f"Signal sent: {result['direction']} ({result['confidence']:.0%} confidence)")
# Signal sent: long (92% confidence)
Enter fullscreen mode Exit fullscreen mode

Step 4: Start Freqtrade normally

freqtrade trade \
  --config config.json \
  --strategy ClaudeStrategy \
  --enable-rest-api
Enter fullscreen mode Exit fullscreen mode

That's it. Claude analyzes → sends PULSE signal → Freqtrade executes.


Why not just call the Freqtrade REST API directly?

You could. But then you have to:

  • Write custom HTTP code for every integration
  • Parse different response formats from different exchanges
  • Rewrite everything if you switch from Claude to GPT (or vice versa)
  • Handle authentication separately for each system

With PULSE, every component speaks the same language:

# Today: Claude drives Freqtrade on Binance
from pulse_anthropic import AnthropicAdapter
from pulse_binance import BinanceAdapter

# Tomorrow: GPT drives Freqtrade on Bybit
from pulse_openai import OpenAIAdapter
from pulse_bybit import BybitAdapter

# Your strategy code: unchanged
Enter fullscreen mode Exit fullscreen mode

Bonus: Monitor multiple bots

Running a trend bot and a mean-reversion bot simultaneously? Monitor both in one place:

from pulse_freqtrade import FreqtradeAdapter
from pulse.message import PulseMessage

bots = {
    "trend-bot":     FreqtradeAdapter(url="http://localhost:8080", ...),
    "reversal-bot":  FreqtradeAdapter(url="http://localhost:8081", ...),
}

for name, adapter in bots.items():
    adapter.connect()
    response = adapter.send(PulseMessage(action="ACT.QUERY.STATUS", parameters={}))
    trades = response.content["parameters"]["result"]
    profit = adapter.get_profit()

    print(f"{name}: {len(trades)} open trades | profit: {profit['profit_all_percent']:.2f}%")

# trend-bot:    3 open trades | profit: +4.21%
# reversal-bot: 1 open trade  | profit: +1.87%
Enter fullscreen mode Exit fullscreen mode

Supported PULSE actions

PULSE Action What it does in Freqtrade
ACT.QUERY.STATUS Get open trades
ACT.QUERY.BALANCE Get portfolio balance
ACT.QUERY.LIST Get trade history
ACT.QUERY.DATA Get OHLCV candles for a pair
ACT.QUERY.PROFIT Get profit/loss summary
ACT.TRANSACT.REQUEST Force open a trade
ACT.CANCEL Force close a trade
ACT.START Start the bot
ACT.STOP Stop the bot
ACT.RELOAD Reload config

Install

pip install pulse-freqtrade
Enter fullscreen mode Exit fullscreen mode

The bigger picture

pulse-freqtrade is part of the PULSE Protocol ecosystem — 11 packages that let any AI system talk to any other AI system using a common semantic language:

pulse-protocol     — core protocol
pulse-openai       — GPT adapter
pulse-anthropic    — Claude adapter
pulse-gemini       — Gemini adapter
pulse-ollama       — local models (Llama, Mistral)
pulse-binance      — Binance exchange
pulse-bybit        — Bybit exchange
pulse-kraken       — Kraken exchange
pulse-okx          — OKX exchange
pulse-gateway      — secure API gateway
pulse-freqtrade    — Freqtrade bot ← new
Enter fullscreen mode Exit fullscreen mode

Every package uses the same message format. Mix and match freely.


Questions? Drop them in the comments. Happy to help with setup or strategy ideas.

The code is open source, Apache 2.0, free forever.