In early January 2023, right after the launch of ChatGPT, I set out to build an automated cryptocurrency trading bot and backtesting engine in Python.
The goal was straightforward: build a modular, headless system that could ingest real-time exchange candle data, compute technical indicators (RSI, MACD, Moving Averages), execute automated limit/market orders, and simulate strategies against historical market data before risking live capital.
The modular trading bot pipeline: from CCXT data ingestion to strategy execution and historical backtesting
Core Architecture & Strategy Components
The project was structured into four distinct modules:
E:\DevCode\Python\tradingbot\
├── ccxt_client.py # Exchange API wrapper & rate-limit handler
├── dan-mean-reversion-bot.py # Live execution daemon with RSI/MACD triggers
├── danbacktest.py # Historical simulation runner & plot generator
├── trades.log # Live CSV execution log
└── config.txt # API keys, trading pairs, and risk thresholds
1. Real-Time Exchange Ingestion (CCXT)
The bot utilized the ccxt library to interface with cryptocurrency exchanges. Because exchange APIs strictly enforce rate limits, the wrapper implemented a token-bucket backoff queue to ensure order book queries and balance checks never triggered temporary IP bans.
import ccxt
import time
def init_exchange(api_key, api_secret):
exchange = ccxt.binance({
'apiKey': api_key,
'secret': api_secret,
'enableRateLimit': True,
'options': {'defaultType': 'spot'}
})
return exchange
2. The Mean-Reversion & RSI Strategy Engine
The live daemon (dan-mean-reversion-bot.py) polled 15-minute and 1-hour candle intervals. When the 14-period Relative Strength Index (RSI) dropped below 30 (oversold) and price deviated significantly from the 20-period Exponential Moving Average (EMA), the bot initiated progressive scale-in buy orders.
def check_rsi_trigger(df, oversold_threshold=30, overbought_threshold=70):
current_rsi = df['rsi'].iloc[-1]
if current_rsi <= oversold_threshold:
return "BUY"
elif current_rsi >= overbought_threshold:
return "SELL"
return "HOLD"
Historical Backtesting & Visual Verification
Before running strategies live, the backtest engine (danbacktest.py) simulated thousands of historical candles across pairs like BTC/USDT, SOL/USDT, and LINK/USDT, factoring in realistic taker fees (0.075%) and slippage.
The runner automatically plotted indicator performance and equity curves using Matplotlib:
Historical MACD signal cross analysis and entry triggers generated by danbacktest.py on BTC/USDT
Multi-pair indicator verification on SOL/USDT testing trend continuation vs mean-reversion exits
Live Trade Execution & Logging
When deployed in production, all order actions were piped to a structured execution log (trades.log) tracking timestamp, strategy trigger, pair, fill price, quantity, and dollar value:
2023-01-30 01:20:12,rsi,buy,THETA/USDT,1.101,0.200,0.2202
2023-01-30 02:11:01,rsi,buy,TRX/USDT,0.06319,11.00,0.6950
2023-01-30 04:02:51,rsi,sell,BTC/USDT,23710.0,0.00002,0.4742
2023-01-30 07:17:09,rsi,buy,LINK/USDT,7.236,0.200,1.4472
2023-01-30 14:52:04,rsi,sell,TRX/USDT,0.06298,11.00,0.6927
Key Takeaways
Building the trading bot provided invaluable experience in asynchronous API handling, state persistence, risk management, and indicator mathematics.
While the system proved highly profitable during strong trending market phases, it also highlighted the importance of market regime detection and stop-loss discipline when volatility turns.
To read about the real-world operational lessons and market realities of running this bot, check out my companion article on getting rich with trading bots: bull runs, bear traps, and algorithmic reality. You can also explore how I automate Linux infrastructure in creating simple background systemd service units.