# Conflicts: # .gitignore # README.md # cycles/backtest.py # main.py # pyproject.toml # uv.lock
Cycles - Cryptocurrency Trading Strategy Backtesting Framework
A comprehensive Python framework for backtesting cryptocurrency trading strategies using technical indicators, with advanced features like machine learning price prediction to eliminate lookahead bias.
Table of Contents
- Overview
- Features
- Quick Start
- Project Structure
- Core Modules
- Configuration
- Usage Examples
- API Documentation
- Testing
- Contributing
- License
Overview
Cycles is a sophisticated backtesting framework designed specifically for cryptocurrency trading strategies. It provides robust tools for:
- Strategy Backtesting: Test trading strategies across multiple timeframes with comprehensive metrics
- Technical Analysis: Built-in indicators including SuperTrend, RSI, Bollinger Bands, and more
- Machine Learning Integration: Eliminate lookahead bias using XGBoost price prediction
- Multi-timeframe Analysis: Support for various timeframes from 1-minute to daily data
- Performance Analytics: Detailed reporting with profit ratios, drawdowns, win rates, and fee calculations
Key Goals
- Realistic Trading Simulation: Eliminate common backtesting pitfalls like lookahead bias
- Modular Architecture: Easy to extend with new indicators and strategies
- Performance Optimization: Parallel processing for efficient large-scale backtesting
- Comprehensive Analysis: Rich reporting and visualization capabilities
Features
🚀 Core Features
- Multi-Strategy Backtesting: Test multiple trading strategies simultaneously
- Advanced Stop Loss Management: Precise stop-loss execution using 1-minute data
- Fee Integration: Realistic trading fee calculations (OKX exchange fees)
- Parallel Processing: Efficient multi-core backtesting execution
- Rich Analytics: Comprehensive performance metrics and reporting
📊 Technical Indicators
- SuperTrend: Multi-parameter SuperTrend indicator with meta-trend analysis
- RSI: Relative Strength Index with customizable periods
- Bollinger Bands: Configurable period and standard deviation multipliers
- Extensible Framework: Easy to add new technical indicators
🤖 Machine Learning
- Price Prediction: XGBoost-based closing price prediction
- Lookahead Bias Elimination: Realistic trading simulations
- Feature Engineering: Advanced technical feature extraction
- Model Persistence: Save and load trained models
📈 Data Management
- Multiple Data Sources: Support for various cryptocurrency exchanges
- Flexible Timeframes: 1-minute to daily data aggregation
- Efficient Storage: Optimized data loading and caching
- Google Sheets Integration: External data source connectivity
Quick Start
Prerequisites
- Python 3.10 or higher
- UV package manager (recommended)
- Git
Installation
-
Clone the repository:
git clone <repository-url> cd Cycles -
Install dependencies:
uv sync -
Activate virtual environment:
source .venv/bin/activate # Linux/Mac # or .venv\Scripts\activate # Windows
Basic Usage
-
Prepare your configuration file (
config.json):{ "start_date": "2023-01-01", "stop_date": "2023-12-31", "initial_usd": 10000, "timeframes": ["5T", "15T", "1H", "4H"], "stop_loss_pcts": [0.02, 0.05, 0.10] } -
Run a backtest:
uv run python main.py --config config.json -
View results: Results will be saved in timestamped CSV files with comprehensive metrics.
Project Structure
Cycles/
├── cycles/ # Core library modules
│ ├── Analysis/ # Technical analysis indicators
│ │ ├── boillinger_band.py
│ │ ├── rsi.py
│ │ └── __init__.py
│ ├── utils/ # Utility modules
│ │ ├── storage.py # Data storage and management
│ │ ├── system.py # System utilities
│ │ ├── data_utils.py # Data processing utilities
│ │ └── gsheets.py # Google Sheets integration
│ ├── backtest.py # Core backtesting engine
│ ├── supertrend.py # SuperTrend indicator implementation
│ ├── charts.py # Visualization utilities
│ ├── market_fees.py # Trading fee calculations
│ └── __init__.py
├── docs/ # Documentation
│ ├── analysis.md # Analysis module documentation
│ ├── utils_storage.md # Storage utilities documentation
│ └── utils_system.md # System utilities documentation
├── data/ # Data directory (not in repo)
├── results/ # Backtest results (not in repo)
├── xgboost/ # Machine learning components
├── OHLCVPredictor/ # Price prediction module
├── main.py # Main execution script
├── test_bbrsi.py # Example strategy test
├── pyproject.toml # Project configuration
├── requirements.txt # Dependencies
├── uv.lock # UV lock file
└── README.md # This file
Core Modules
Backtest Engine (cycles/backtest.py)
The heart of the framework, providing comprehensive backtesting capabilities:
from cycles.backtest import Backtest
results = Backtest.run(
min1_df=minute_data,
df=timeframe_data,
initial_usd=10000,
stop_loss_pct=0.05,
debug=False
)
Key Features:
- Meta-SuperTrend strategy implementation
- Precise stop-loss execution using 1-minute data
- Comprehensive trade logging and statistics
- Fee-aware profit calculations
Technical Analysis (cycles/Analysis/)
Modular technical indicator implementations:
RSI (Relative Strength Index)
from cycles.Analysis.rsi import RSI
rsi_calculator = RSI(period=14)
data_with_rsi = rsi_calculator.calculate(df, price_column='close')
Bollinger Bands
from cycles.Analysis.boillinger_band import BollingerBands
bb = BollingerBands(period=20, std_dev_multiplier=2.0)
data_with_bb = bb.calculate(df)
Data Management (cycles/utils/storage.py)
Efficient data loading, processing, and result storage:
from cycles.utils.storage import Storage
storage = Storage(data_dir='./data', logging=logging)
data = storage.load_data('btcusd_1-min_data.csv', '2023-01-01', '2023-12-31')
Configuration
Backtest Configuration
Create a config.json file with the following structure:
{
"start_date": "2023-01-01",
"stop_date": "2023-12-31",
"initial_usd": 10000,
"timeframes": [
"1T", // 1 minute
"5T", // 5 minutes
"15T", // 15 minutes
"1H", // 1 hour
"4H", // 4 hours
"1D" // 1 day
],
"stop_loss_pcts": [0.02, 0.05, 0.10, 0.15]
}
Environment Variables
Set the following environment variables for enhanced functionality:
# Google Sheets integration (optional)
export GOOGLE_SHEETS_CREDENTIALS_PATH="/path/to/credentials.json"
# Data directory (optional, defaults to ./data)
export DATA_DIR="/path/to/data"
# Results directory (optional, defaults to ./results)
export RESULTS_DIR="/path/to/results"
Usage Examples
Basic Backtest
import json
from cycles.utils.storage import Storage
from cycles.backtest import Backtest
# Load configuration
with open('config.json', 'r') as f:
config = json.load(f)
# Initialize storage
storage = Storage(data_dir='./data')
# Load data
data_1min = storage.load_data(
'btcusd_1-min_data.csv',
config['start_date'],
config['stop_date']
)
# Run backtest
results = Backtest.run(
min1_df=data_1min,
df=data_1min, # Same data for 1-minute strategy
initial_usd=config['initial_usd'],
stop_loss_pct=0.05,
debug=True
)
print(f"Final USD: {results['final_usd']:.2f}")
print(f"Number of trades: {results['n_trades']}")
print(f"Win rate: {results['win_rate']:.2%}")
Multi-Timeframe Analysis
from main import process
# Define timeframes to test
timeframes = ['5T', '15T', '1H', '4H']
stop_loss_pcts = [0.02, 0.05, 0.10]
# Create tasks for parallel processing
tasks = [
(timeframe, data_1min, stop_loss_pct, 10000)
for timeframe in timeframes
for stop_loss_pct in stop_loss_pcts
]
# Process each task
for task in tasks:
results, trades = process(task, debug=False)
print(f"Timeframe: {task[0]}, Stop Loss: {task[2]:.1%}")
for result in results:
print(f" Final USD: {result['final_usd']:.2f}")
Custom Strategy Development
from cycles.Analysis.rsi import RSI
from cycles.Analysis.boillinger_band import BollingerBands
def custom_strategy(df):
"""Example custom trading strategy using RSI and Bollinger Bands"""
# Calculate indicators
rsi = RSI(period=14)
bb = BollingerBands(period=20, std_dev_multiplier=2.0)
df_with_rsi = rsi.calculate(df.copy())
df_with_bb = bb.calculate(df_with_rsi)
# Define signals
buy_signals = (
(df_with_bb['close'] < df_with_bb['LowerBand']) &
(df_with_bb['RSI'] < 30)
)
sell_signals = (
(df_with_bb['close'] > df_with_bb['UpperBand']) &
(df_with_bb['RSI'] > 70)
)
return buy_signals, sell_signals
API Documentation
Core Classes
Backtest
Main backtesting engine with static methods for strategy execution.
Methods:
run(min1_df, df, initial_usd, stop_loss_pct, debug=False): Execute backtestcheck_stop_loss(...): Check stop-loss conditions using 1-minute datahandle_entry(...): Process trade entry logichandle_exit(...): Process trade exit logic
Storage
Data management and persistence utilities.
Methods:
load_data(filename, start_date, stop_date): Load and filter historical datasave_data(df, filename): Save processed datawrite_backtest_results(...): Save backtest results to CSV
SystemUtils
System optimization and resource management.
Methods:
get_optimal_workers(): Determine optimal number of parallel workersget_memory_usage(): Monitor memory consumption
Configuration Parameters
| Parameter | Type | Description | Default |
|---|---|---|---|
start_date |
string | Backtest start date (YYYY-MM-DD) | Required |
stop_date |
string | Backtest end date (YYYY-MM-DD) | Required |
initial_usd |
float | Starting capital in USD | Required |
timeframes |
array | List of timeframes to test | Required |
stop_loss_pcts |
array | Stop-loss percentages to test | Required |
Testing
Running Tests
# Run all tests
uv run pytest
# Run specific test file
uv run pytest test_bbrsi.py
# Run with verbose output
uv run pytest -v
# Run with coverage
uv run pytest --cov=cycles
Test Structure
test_bbrsi.py: Example strategy testing with RSI and Bollinger Bands- Unit tests for individual modules (add as needed)
- Integration tests for complete workflows
Example Test
# test_bbrsi.py demonstrates strategy testing
from cycles.Analysis.rsi import RSI
from cycles.Analysis.boillinger_band import BollingerBands
def test_strategy_signals():
# Load test data
storage = Storage()
data = storage.load_data('test_data.csv', '2023-01-01', '2023-02-01')
# Calculate indicators
rsi = RSI(period=14)
bb = BollingerBands(period=20)
data_with_indicators = bb.calculate(rsi.calculate(data))
# Test signal generation
assert 'RSI' in data_with_indicators.columns
assert 'UpperBand' in data_with_indicators.columns
assert 'LowerBand' in data_with_indicators.columns
Contributing
Development Setup
- Fork the repository
- Create a feature branch:
git checkout -b feature/new-indicator - Install development dependencies:
uv sync --dev - Make your changes following the coding standards
- Add tests for new functionality
- Run tests:
uv run pytest - Submit a pull request
Coding Standards
- Maximum file size: 250 lines
- Maximum function size: 50 lines
- Documentation: All public functions must have docstrings
- Type hints: Use type hints for all function parameters and returns
- Error handling: Include proper error handling and meaningful error messages
- No emoji: Avoid emoji in code and comments
Adding New Indicators
- Create a new file in
cycles/Analysis/ - Follow the existing pattern (see
rsi.pyorboillinger_band.py) - Include comprehensive docstrings and type hints
- Add tests for the new indicator
- Update documentation
Performance Considerations
Optimization Tips
- Parallel Processing: Use the built-in parallel processing for multiple timeframes
- Data Caching: Cache frequently used calculations
- Memory Management: Monitor memory usage for large datasets
- Efficient Data Types: Use appropriate pandas data types
Benchmarks
Typical performance on modern hardware:
- 1-minute data: ~1M candles processed in 2-3 minutes
- Multiple timeframes: 4 timeframes × 4 stop-loss values in 5-10 minutes
- Memory usage: ~2-4GB for 1 year of 1-minute BTC data
Troubleshooting
Common Issues
-
Memory errors with large datasets:
- Reduce date range or use data chunking
- Increase system RAM or use swap space
-
Slow performance:
- Enable parallel processing
- Reduce number of timeframes/stop-loss values
- Use SSD storage for data files
-
Missing data errors:
- Verify data file format and column names
- Check date range availability in data
- Ensure proper data cleaning
Debug Mode
Enable debug mode for detailed logging:
# Set debug=True for detailed output
results = Backtest.run(..., debug=True)
License
This project is licensed under the MIT License. See the LICENSE file for details.
Changelog
Version 0.1.0 (Current)
- Initial release
- Core backtesting framework
- SuperTrend strategy implementation
- Technical indicators (RSI, Bollinger Bands)
- Multi-timeframe analysis
- Machine learning price prediction
- Parallel processing support
For more detailed documentation, see the docs/ directory or visit our documentation website.
Support: For questions or issues, please create an issue on GitHub or contact the development team.