Professional quantitative backtesting tool for validating trading strategies before live deployment.
回测框架采用参数优化迭代流程,逐步优化策略参数:
根据数据类型和市场特性自动选择合适的数据源:
内置专业金融指标计算和风险评估:
| 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 |
python3 backtest.py --strategy sma_crossover --ticker 600036 --start 2025-01-01 --end 2025-03-31
python3 backtest.py --strategy rsi --ticker 000001 --start 2025-01-01 --end 2025-03-31 --upper 65 --lower 35
# 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
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
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)
Formula: (Return - RiskFree) / StdDev
Shows worst-case loss scenario
Better for asymmetric return distributions
Allows comparing trades of different sizes
Location: ~/.openclaw/workspace/trading/a_stock_complete.db
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.txt
# Strategy B: RSI
python3 backtest.py --strategy rsi --ticker 600036 --start 2025-01-01 --end 2025-03-31 > rsi_results.txt
# Compare
cat sma_results.txt rsi_results.txt | grep "Sharpe\|Return\|Drawdown"
.shift(1) when necessary for signal lag❌ 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
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
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
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
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
共 1 个版本