A sophisticated algorithmic trading bot implementing copula-based pairs trading for cryptocurrency futures markets. The strategy is based on the academic paper "Copula-Based Trading of Cointegrated Cryptocurrency Pairs" by Masood Tadi & Jiri Witzany (2023).
This bot implements a market-neutral trading strategy that:
- Uses Bitcoin (BTC) as a reference asset to hedge altcoin exposure
- Identifies cointegrated spread pairs using statistical tests
- Models dependence structure using Gaussian copulas
- Generates trading signals based on conditional probabilities
- Trades on Binance Futures with configurable leverage
- Automated Formation Phase: Weekly selection of top cointegrated pairs
- Real-time Trading: 5-minute interval signal generation and execution
- Risk Management: Position sizing, leverage control, and stop-loss
- State Persistence: Saves copula parameters and trading state
- Comprehensive Logging: Detailed logs for monitoring and debugging
- Fetch 21 days of historical 5-minute OHLCV data
- Calculate spreads for all altcoin pairs:
S_i(t) = BTC(t) - beta_i * ALT_i(t) - Test cointegration using both Engle-Granger (ADF) and Kapetanios-Shin-Snell (KSS) tests
- Rank cointegrated pairs by Kendall's Tau correlation
- Select top pair and fit Gaussian copula
- Fetch current prices for BTC and selected altcoins
- Calculate conditional probabilities:
h_1|2andh_2|1 - Generate signals based on thresholds:
- LONG S1, SHORT S2: when
h_1|2 < alpha1ANDh_2|1 > 1-alpha1 - SHORT S1, LONG S2: when
h_1|2 > 1-alpha1ANDh_2|1 < alpha1 - CLOSE: when both probabilities near 0.5 (within alpha2)
- LONG S1, SHORT S2: when
- Execute market orders on Binance Futures
Based on the original paper (2-year backtest):
- Annualized Return: 37-76%
- Sharpe Ratio: 0.97-3.77
- Win Rate: 55-67%
- Max Drawdown: ~25-35%
WARNING: Past performance does not guarantee future results. Always test thoroughly before live trading.
btc_mn_copulas/
├── src/
│ ├── __init__.py
│ ├── config.py # Configuration management
│ ├── logger.py # Logging setup
│ ├── binance_client.py # Binance API wrapper
│ ├── copula_model.py # Copula calculations and signals
│ ├── formation.py # Weekly formation phase
│ ├── trading.py # Trading execution
│ └── state_manager.py # State persistence
├── tests/
│ ├── __init__.py
│ ├── test_config.py
│ ├── test_copula_model.py
│ └── test_state_manager.py
├── logs/ # Log files (auto-generated)
├── state/ # State persistence (auto-generated)
├── main.py # Main orchestrator
├── pyproject.toml # Dependencies
├── .env.example # Environment template
└── README.md # This file
- Python >= 3.12
- Binance Futures account (or Testnet account)
- API keys with Futures trading permissions
- Clone the repository:
git clone <repository-url>
cd btc_mn_copulas- Install dependencies:
# Using uv (recommended)
# 1. Install uv: https://docs.astral.sh/uv/getting-started/installation/
# curl -LsSf https://astral.sh/uv/install.sh | sh
# 2. Sync dependencies
uv sync- Configure environment:
cp .env.example .env
# Edit .env with your API keys and preferences- Get Binance API keys:
- Testnet (recommended for testing): https://testnet.binancefuture.com/
- Live: https://www.binance.com/en/my/settings/api-management
Edit .env file with your settings:
# API Configuration
BINANCE_API_KEY=your_api_key_here
BINANCE_API_SECRET=your_api_secret_here
USE_TESTNET=true # Set to false for live trading
# Trading Parameters
CAPITAL_PER_LEG=20000 # USDT per leg
MAX_LEVERAGE=3 # 1-3x recommended
ENTRY_THRESHOLD=0.10 # alpha1 (0.10 = 10th percentile)
EXIT_THRESHOLD=0.10 # alpha2
# Altcoin Universe
ALTCOINS=ETHUSDT,BNBUSDT,ADAUSDT,XRPUSDT,SOLUSDT,AVAXUSDT
# Formation & Trading Schedule
FORMATION_DAYS=21 # Days of data for formation
TRADING_INTERVAL_MINUTES=5 # Trading frequencyTestnet (recommended first):
# Ensure USE_TESTNET=true in .env
python main.pyLive Trading:
# Set USE_TESTNET=false in .env
python main.pyYou can run backtests without any API keys! The backtester automatically downloads high-quality 5-minute data from Binance Vision (public S3 bucket).
# Basic run (defaults to Q1 2025 if not specified, but arguments are required)
python backtest.py --start 2025-01 --end 2025-03
# Custom date range and capital
python backtest.py --start 2024-01 --end 2024-06 --initial-capital 50000
# Run in parallel mode (faster for long periods)
python backtest.py --start 2024-01 --end 2024-12 --parallel- No API Keys Needed: Uses public data.
- Data Source: Binance Vision (official historical data).
- Interval: 5-minute candles.
- Output: Generates a tearsheet report in
backtest_results/tearsheet/report.html.
The bot will:
- Initialize all components
- Load existing formation state (if available)
- Schedule weekly formation phase (Mondays 00:00 UTC)
- Schedule 5-minute trading cycles
- Run continuously until stopped (Ctrl+C)
# Run all tests
pytest
# Run with coverage
pytest --cov=src --cov-report=html
# Run specific test file
pytest tests/test_copula_model.py -vTo manually trigger a formation phase without waiting for the schedule:
from src.config import get_config
from src.binance_client import BinanceClient
from src.formation import FormationManager
config = get_config()
client = BinanceClient(config.binance.api_key, config.binance.api_secret, testnet=True)
formation = FormationManager(client, config.trading.altcoins, config.trading.formation_days)
# Run formation
spread_pair = formation.run_formation()
print(f"Selected pair: {spread_pair.alt1} - {spread_pair.alt2}")
print(f"Parameters: beta1={spread_pair.beta1:.6f}, beta2={spread_pair.beta2:.6f}, rho={spread_pair.rho:.4f}")Logs are written to logs/trading.log with rotation:
# View live logs
tail -f logs/trading.log
# Search for signals
grep "SIGNAL" logs/trading.log
# Check errors
grep "ERROR" logs/trading.logAll trades are logged to state/trade_log.jsonl:
# View recent trades
tail -n 20 state/trade_log.jsonl | jq .
# Count successful trades
grep '"status":"success"' state/trade_log.jsonl | wc -lCheck current state:
from src.state_manager import StateManager
manager = StateManager()
summary = manager.get_state_summary()
print(summary)IMPORTANT WARNINGS:
- Start with Testnet: Always test thoroughly on Binance Futures Testnet before live trading
- Capital at Risk: Only trade with capital you can afford to lose
- Leverage Risk: Higher leverage amplifies both gains and losses
- Market Conditions: Strategy performance varies with market conditions
- Fees: Account for trading fees (0.04% taker, 0.02% maker on Binance)
- API Security: Never share API keys; use IP whitelisting
- Monitoring: Always monitor the bot; don't run unattended initially
- Start with low capital (e.g., $1,000 per leg)
- Use low leverage (1-2x)
- Monitor daily drawdown and set stop-loss if needed
- Run paper trading for at least 2 weeks first
1. API Key Error:
ValueError: BINANCE_API_KEY and BINANCE_API_SECRET must be set
Solution: Create .env file from .env.example and add your API keys
2. No Cointegrated Pairs:
Formation phase failed - no suitable pairs found!
Solution: Market conditions may not have cointegrated pairs. Wait for next formation cycle or adjust altcoin universe
3. Insufficient Balance:
Error placing market order: Insufficient balance
Solution: Reduce CAPITAL_PER_LEG or deposit more USDT to Futures wallet
4. Position Already Open:
Solution: Bot tracks position state in state/state.json. Clear state if needed: rm state/state.json
# Install with dev dependencies
uv sync --all-extras
# Run tests with coverage
pytest --cov=src --cov-report=term-missing
# Format code (optional)
black src/ tests/The current implementation uses Gaussian copula. To add Student-t, Clayton, or other copulas:
- Implement copula CDF and conditional CDF in
src/copula_model.py - Add parameter estimation method
- Update
FormationManagerto test multiple copulas and select by AIC - Add tests in
tests/test_copula_model.py
- Original Paper: Tadi, M., & Witzany, J. (2023). "Copula-Based Trading of Cointegrated Cryptocurrency Pairs"
- Binance Futures API: https://binance-docs.github.io/apidocs/futures/en/
- Copula Theory: Nelsen, R. B. (2006). "An Introduction to Copulas"
- Cointegration: Engle, R. F., & Granger, C. W. (1987). "Co-integration and error correction"