OpenClaw Backtester
by @cry779
Professional backtesting framework for trading strategies. Tests SMA crossover, RSI, MACD, Bollinger Bands, and custom strategies on historical data. Generat...
clawhub install openclaw-backtester📖 About This Skill
name: backtester description: Professional backtesting framework for trading strategies. Tests SMA crossover, RSI, MACD, Bollinger Bands, and custom strategies on historical data. Generates equity curves, drawdown analysis, and performance metrics. Use when validating trading strategies, comparing backtest results, or optimizing strategy parameters. metadata: openclaw: emoji: "📈" requires: bins: [python3] always: false
Beta Backtester
Professional quantitative backtesting tool for validating trading strategies before live deployment.
Design Patterns Applied
1. 迭代式优化模式 (Iterative Optimization Pattern)
回测框架采用参数优化迭代流程,逐步优化策略参数:2. 情境感知工具选择 (Context-Aware Tool Selection)
根据数据类型和市场特性自动选择合适的数据源:3. 特定领域智能 (Domain-Specific Intelligence)
内置专业金融指标计算和风险评估:What It Does
Strategies Supported
| Strategy | Description | Key Parameters | Best For | |----------|-------------|----------------|----------| | SMA Crossover | Fast/slow moving average crossover | fast (8-14), slow (21-65) | Trend following | | RSI | RSI overbought/oversold reversals | period (14), upper (70), lower (30) | Mean reversion | | MACD | MACD signal line crossovers | fast (12), slow (26), signal (9) | Momentum trading | | Bollinger Bands | Mean reversion at bands | period (20), std (2) | Volatility trading | | Custom | User-defined entry/exit logic | Custom | Specialized strategies |
Usage Examples
Basic Backtest
python3 backtest.py --strategy sma_crossover --ticker 600036 --start 2025-01-01 --end 2025-03-31
Parameter Optimization
python3 backtest.py --strategy rsi --ticker 000001 --start 2025-01-01 --end 2025-03-31 --upper 65 --lower 35
Multi-Strategy Comparison
# Run multiple strategies and compare
python3 backtest.py --strategy sma_crossover --ticker 600519 --start 2025-01-01 --end 2025-03-31
python3 backtest.py --strategy macd --ticker 600519 --start 2025-01-01 --end 2025-03-31
python3 backtest.py --strategy rsi --ticker 600519 --start 2025-01-01 --end 2025-03-31
Output Example
BACKTEST RESULTS: SMA_CROSSOVER | 600036 | 2025-01-01 to 2025-03-31
============================================================
📊 Performance Metrics
Total Return: +18.2%
Annual Return: +9.8%
Sharpe Ratio: 1.45 (Good)
Max Drawdown: -8.7% (Acceptable)
Win Rate: 62% (Above average)
Total Trades: 32
Best Trade: +6.8%
Worst Trade: -3.2%
Avg Hold Time: 10 days📈 Equity Curve
2025-01-15: $10,000 → $10,350 (Entry: SMA cross up)
2025-01-28: $10,350 → $10,520 (Exit: SMA cross down)
2025-02-10: $10,520 → $10,890 (Entry: SMA cross up)
2025-03-05: $10,890 → $11,820 (Exit: SMA cross down)
2025-03-20: $11,820 → $11,820 (Current position)
⚙️ Strategy Parameters
Fast SMA: 8
Slow SMA: 21
Commission: 0.05%
Slippage: 0.1%
Initial Capital: $100,000
Iterative Optimization Example
Step 1: Baseline with default parameters
python3 backtest.py --strategy sma_crossover --ticker 600036 --start 2025-01-01 --end 2025-03-31
Result: Sharpe 1.25, Return +12.3%
Step 2: Test parameter variations
# Test fast=8, slow=21
python3 backtest.py --strategy sma_crossover --ticker 600036 --fast 8 --slow 21
Result: Sharpe 1.45, Return +18.2%
Test fast=10, slow=30
python3 backtest.py --strategy sma_crossover --ticker 600036 --fast 10 --slow 30
Result: Sharpe 1.18, Return +14.5%
Step 3: Select optimal parameters (fast=8, slow=21) Step 4: Validate on out-of-sample data (2025-04-01 to 2025-06-30)
Error Handling & Validation
Data Validation
Error Recovery
Input Validation Checklist
Metrics Explained
Requirements
Data Sources
A/B Testing Support
Compare multiple strategies on same dataset:
# Strategy A: SMA Crossover
python3 backtest.py --strategy sma_crossover --ticker 600036 --start 2025-01-01 --end 2025-03-31 > sma_results.txtStrategy B: RSI
python3 backtest.py --strategy rsi --ticker 600036 --start 2025-01-01 --end 2025-03-31 > rsi_results.txtCompare
cat sma_results.txt rsi_results.txt | grep "Sharpe\|Return\|Drawdown"
Best Practices
1. Avoid Overfitting
2. Include Transaction Costs
3. Check for Look-Ahead Bias
.shift(1) when necessary for signal lag4. Validate Data Quality
5. Test Edge Cases
Workflow Example: Full Strategy Development
1. Data Preparation - Load historical data from database - Clean and validate data quality - Check for missing bars
2. Strategy Definition - Choose entry/exit criteria - Define position sizing - Set stop-loss/take-profit rules
3. Initial Backtest - Run with default parameters - Analyze basic metrics (Sharpe, drawdown)
4. Parameter Optimization (Iterative) - Grid search parameter space - Find optimal risk-adjusted return - Avoid overfitting
5. Out-of-Sample Validation - Test on unseen data - Compare in-sample vs out-of-sample performance - Check for degradation
6. Robustness Testing - Test on different instruments - Test in different market regimes - Add noise to parameters (±10%)
7. Risk Analysis - Calculate VaR and CVaR - Stress test extreme scenarios - Check correlation with market
8. Production Deployment - Paper trade for 1-2 weeks - Start with small position size - Monitor and adjust
Common Pitfalls
❌ Look-ahead bias: Using future data in indicators ❌ Survivorship bias: Only testing current stocks (excluding delisted) ❌ Overfitting: Too many parameters, curve-fitting noise ❌ Ignoring costs: Forgetting commission and slippage ❌ Small sample: <50 trades is statistically insignificant ❌ Data snooping: Testing too many strategies until one works
Advanced Features
Custom Strategy Template
def calculate_custom_strategy(df: pd.DataFrame, param1: int, param2: float) -> pd.DataFrame:
"""User-defined strategy"""
df = df.copy()
# Your logic here
df['signal'] = 0
df.loc[entry_condition, 'signal'] = 1 # Buy
df.loc[exit_condition, 'signal'] = -1 # Sell
df['position'] = df['signal'].diff()
return df
Monte Carlo Simulation
Add noise to price data to test strategy robustness:def add_noise(df: pd.DataFrame, noise_pct: float = 0.01) -> pd.DataFrame:
"""Add random noise to prices"""
df = df.copy()
noise = np.random.normal(0, noise_pct, len(df))
df['close'] = df['close'] * (1 + noise)
return df
Troubleshooting
Problem: "Database not found"
→ Check: ls ~/.openclaw/workspace/trading/a_stock_complete.db
→ Fix: Import data using data ingestion pipeline
Problem: "No data in date range" → Check: Verify stock code format (e.g., 600036 → 600036.SH) → Check: Verify date format (YYYY-MM-DD) → Check: Database has data for that period
Problem: "Low Sharpe ratio (<0.5)" → Check: Strategy might be overfit → Check: Transaction costs too high → Check: Wrong time frame (try different bars)
Problem: "Too few trades (<20)" → Check: Parameter too restrictive → Check: Date range too short → Fix: Extend backtest period or relax entry criteria
Disclaimer
Backtested results do NOT guarantee future performance. Past performance is not indicative of future results. Always paper trade before going live. Test strategies in multiple market conditions before risking real capital.
*Built by Beta — AI Trading Research Agent*
📋 Tips & Best Practices
1. Avoid Overfitting
2. Include Transaction Costs
3. Check for Look-Ahead Bias
.shift(1) when necessary for signal lag