How to Build a Forex Trading Bot with Python in 2026
A complete guide to building a production-ready forex trading bot using Python, the TickAtlas API for real-time data, and proven risk management techniques.
Why Python for Forex Bots?
Python dominates algorithmic trading for good reason. Its ecosystem of libraries like requests, pandas, and numpy makes data manipulation trivial, and its readable syntax means you can focus on strategy logic instead of fighting with language quirks. In 2026, Python remains the fastest path from idea to live trading bot.
This tutorial walks you through building a forex bot that fetches real-time indicator data from the TickAtlas API, evaluates a multi-indicator strategy, and generates actionable signals.
Prerequisites
- Python 3.10 or newer
- A TickAtlas API key (free tier works for development)
- Basic understanding of forex markets and technical indicators
pip install requests pandas
Step 1: Build the API Client
First, create a reusable client class that handles authentication, rate limiting, and error handling. This wrapper will be the foundation of your bot.
import requests
import time
class TickAtlasClient:
BASE_URL = "https://tickatlas.com/v1"
def __init__(self, api_key: str):
self.session = requests.Session()
self.session.headers.update({
"X-API-Key": api_key,
"Accept": "application/json"
})
self._last_request = 0
def _rate_limit(self):
"""Enforce minimum 200ms between requests."""
elapsed = time.time() - self._last_request
if elapsed < 0.2:
time.sleep(0.2 - elapsed)
self._last_request = time.time()
def get_indicators(self, symbol: str, timeframe: str,
indicators: list[str]) -> dict:
self._rate_limit()
resp = self.session.get(f"{self.BASE_URL}/indicators", params={
"symbol": symbol,
"timeframe": timeframe,
"indicators": ",".join(indicators)
})
resp.raise_for_status()
return resp.json()
def get_ohlc(self, symbol: str, timeframe: str,
bars: int = 100) -> dict:
self._rate_limit()
resp = self.session.get(f"{self.BASE_URL}/ohlc", params={
"symbol": symbol,
"timeframe": timeframe,
"bars": bars
})
resp.raise_for_status()
return resp.json() Step 2: Define the Strategy
Our strategy uses RSI and MACD confluence. A buy signal fires when RSI exits oversold territory while MACD confirms bullish momentum. This combination filters out a large portion of false signals.
class ForexStrategy:
def __init__(self):
self.rsi_oversold = 30
self.rsi_overbought = 70
def evaluate(self, indicators: dict) -> str:
rsi = indicators["RSI_14"]["value"]
macd = indicators["MACD"]["histogram"]
# Buy: RSI crossing up from oversold + MACD histogram positive
if rsi > self.rsi_oversold and rsi < 45 and macd > 0:
return "BUY"
# Sell: RSI crossing down from overbought + MACD histogram negative
if rsi < self.rsi_overbought and rsi > 55 and macd < 0:
return "SELL"
return "HOLD" Step 3: Fetch Live Data
Here is what the API returns when you request RSI and MACD for EURUSD on the H1 timeframe:
// GET /v1/indicators?symbol=EURUSD&timeframe=H1&indicators=RSI_14,MACD
{
"success": true,
"data": {
"symbol": "EURUSD",
"timeframe": "H1",
"indicators": {
"RSI_14": {
"value": 34.7,
"signal": "neutral"
},
"MACD": {
"macd_line": -0.00023,
"signal_line": -0.00031,
"histogram": 0.00008
}
},
"timestamp": "2026-03-28T14:00:00Z"
}
} Step 4: The Main Trading Loop
The bot runs in a continuous loop, checking for signals every time a new candle closes. For H1, that means one check per hour.
import os
from datetime import datetime
def run_bot():
client = TickAtlasClient(os.environ["CLAW_API_KEY"])
strategy = ForexStrategy()
symbols = ["EURUSD", "GBPUSD", "USDJPY", "XAUUSD"]
print(f"[{datetime.utcnow()}] Bot started. Monitoring {len(symbols)} pairs.")
while True:
for symbol in symbols:
try:
data = client.get_indicators(
symbol=symbol,
timeframe="H1",
indicators=["RSI_14", "MACD"]
)
signal = strategy.evaluate(data["data"]["indicators"])
if signal != "HOLD":
print(f"[{datetime.utcnow()}] {signal} signal on {symbol}")
# Execute trade via your broker API here
except Exception as e:
print(f"Error fetching {symbol}: {e}")
time.sleep(3600) # Wait for next H1 candle
if __name__ == "__main__":
run_bot() Step 5: Add Risk Management
No bot is complete without position sizing and stop losses. Use ATR (Average True Range) from the API to set dynamic stops that adapt to market volatility.
def calculate_position_size(account_balance: float,
risk_percent: float,
atr_value: float,
stop_multiplier: float = 2.0) -> float:
"""Risk-based position sizing using ATR."""
risk_amount = account_balance * (risk_percent / 100)
stop_distance = atr_value * stop_multiplier
position_size = risk_amount / stop_distance
return round(position_size, 2)
# Example: $10,000 account, 1% risk, ATR = 0.0012
size = calculate_position_size(10000, 1.0, 0.0012)
# Returns: 41.67 (micro lots) Step 6: Logging and Monitoring
Every signal and trade should be logged. When something goes wrong at 3 AM, your logs are the only thing that will tell you why.
import logging
logging.basicConfig(
filename="trading_bot.log",
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s"
)
logger = logging.getLogger("forex_bot")
logger.info(f"BUY signal on EURUSD | RSI: 34.7 | MACD hist: 0.00008")
logger.info(f"Position size: 0.42 lots | SL: 1.0823 | TP: 1.0871") Common Pitfalls
Overfitting to Historical Data
If your strategy has 20 parameters, it is curve-fitted, not robust. Keep it simple.
Ignoring Spreads and Slippage
Use the /v1/spread endpoint to factor real spread data into your backtests.
No Rate Limit Handling
Always respect API rate limits. The client class above handles this automatically.
Next Steps
You now have a working forex bot skeleton. To make it production-ready:
- Backtest your strategy with historical OHLC data before risking real money
- Add Telegram notifications so you know when the bot trades
- Review the top 10 indicators for trading bots to refine your strategy
- Read our scaling guide when you are ready for more pairs and faster data
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