Beta 回测器
用于在实盘部署前验证交易策略的专业量化回测工具。
应用的设计模式
1. 迭代式优化模式 (Iterative Optimization Pattern)
回测框架采用参数优化迭代流程,逐步优化策略参数:
- 参数扫描: 自动遍历参数空间(如SMA的fast/slow、RSI的超买/超卖阈值)
- 网格搜索: 测试不同参数组合,找到最优风险收益比
- 验证集: 使用walk-forward分析避免过拟合
2. 情境感知工具选择 (Context-Aware Tool Selection)
根据数据类型和市场特性自动选择合适的数据源:
- 数据源适配: A股使用本地SQLite数据库,美股/加密货币使用Yahoo Finance
- 时间框架感知: 15分钟K线用于短线策略,日线用于中长线策略
- 资产类别识别: 自动处理股票代码格式转换(如000001 → 000001.SZ)
3. 特定领域智能 (Domain-Specific Intelligence)
内置专业金融指标计算和风险评估:
- 性能指标: Sharpe、Sortino、最大回撤、胜率、期望收益
- 风险调整: 考虑手续费和滑点的实盘模拟
- 权益曲线: 可视化回测结果,支持多策略对比
功能概述
- 在历史 OHLCV 数据上测试策略(股票、加密货币、外汇)
- 计算性能指标(Sharpe、Sortino、最大回撤、胜率)
- 生成权益曲线和回撤图表
- 并排比较多个策略
- 优化参数以获得最佳风险调整收益
- 带有备用数据源的错误处理
- 支持策略比较的 A/B 测试
支持的策略
| 策略 | 描述 | 关键参数 | 最佳适用 | |----------|-------------|----------------|----------| | SMA 交叉 | 快速/慢速移动平均线交叉 | 快速 (8-14),慢速 (21-65) | 趋势跟踪 | | RSI | RSI 超买/超卖反转 | 周期 (14),上限 (70),下限 (30) | 均值回归 | | MACD | MACD 信号线交叉 | 快速 (12),慢速 (26),信号 (9) | 动量交易 | | 布林带 | 在布林带处均值回归 | 周期 (20),标准差 (2) | 波动率交易 | | 自定义 | 用户定义的入场/出场逻辑 | 自定义 | 特定策略 |
使用示例
基本回测
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
迭代优化示例
步骤 1:使用默认参数建立基线
python3 backtest.py --strategy sma_crossover --ticker 600036 --start 2025-01-01 --end 2025-03-31
# Result: Sharpe 1.25, Return +12.3%
步骤 2:测试参数变体
# 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%
步骤 3:选择最优参数(fast=8, slow=21) 步骤 4:在样本外数据上验证(2025-04-01 至 2025-06-30)
错误处理与验证
数据验证
- ✅ 在查询前检查数据库是否存在
- ✅ 验证日期范围是否有效
- ✅ 优雅处理空结果集
- ✅ 转换股票代码(例如 000001 → 000001.SZ)
错误恢复
- ❌ 数据库未找到 → 显示包含路径的错误
- ❌ 日期范围内无数据 → 警告用户
- ❌ 无效股票代码 → 尝试格式转换
- ❌ 查询错误 → 返回 None 并记录异常
输入验证清单
- [ ] 开始日期 < 结束日期
- [ ] 股票代码格式有效(6 位数字)
- [ ] 策略名称受支持
- [ ] 初始资金 > 0
- [ ] 手续费率合理(0.0001-0.005)
指标说明
- Sharpe 比率:风险调整收益(>1 良好,>2 优秀)
- 最大回撤:从峰值到谷底的最大损失(-10% 可接受)
- 胜率:盈利交易百分比(具有良好风险收益比时 >50% 可盈利)
- Sortino 比率:类似 Sharpe,但只惩罚下行波动率
- R 倍数:按风险归一化的收益(1R = 每笔交易最大损失)
公式:(Return - RiskFree) / StdDev
显示最坏情况损失场景
更适合非对称收益分布
允许比较不同规模的交易
要求
- Python 3.8+
- pandas、numpy、matplotlib(自动安装)
- 包含 OHLCV 数据的 SQLite 数据库(a_stock_complete.db)
- 股票代码格式:XXXXXX.SH(上海)或 XXXXXX.SZ(深圳)
数据源
- 默认:本地 SQLite(a_stock_complete.db)
- CSV 上传:提供你自己的 OHLCV 数据
- API:Tiger API 用于专业数据
位置:~/.openclaw/workspace/trading/a_stock_complete.db
A/B 测试支持
在同一数据集上比较多个策略:
# 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"
最佳实践
1. 避免过拟合
- 使用 walk-forward 分析(用过去训练,用未来验证)
- 保持参数搜索空间合理(不要优化过多参数)
- 使用多个标的验证策略稳健性
2. 包含交易成本
- 始终包含手续费(0.05%)和滑点(0.1%)
- 实盘交易会产生这些成本 - 回测应反映现实
- 测试敏感性:使用 0.02%、0.05%、0.1% 手续费运行
3. 检查前视偏差
- 确保指标只使用过去数据
- 不得窥探未来价格
- 必要时使用
.shift(1)实现信号滞后
4. 验证数据质量
- 检查缺失 K 线或间隔
- 验证 OHLC 一致性(high ≥ open/close ≥ low)
- 移除异常值(>10% 的每日波动通常是错误)
5. 测试边界情况
- 市场崩盘(例如 2020 年 COVID 崩盘)
- 低波动时期(例如 2017 年)
- 震荡横盘市场(例如 2023 年)
工作流示例:完整策略开发
- 数据准备
- 从数据库加载历史数据
- 清洗并验证数据质量
- 检查缺失 K 线
- 策略定义
- 选择入场/出场标准
- 定义仓位规模
- 设置止损/止盈规则
- 初步回测
- 使用默认参数运行
- 分析基本指标(Sharpe、回撤)
- 参数优化(迭代)
- 网格搜索参数空间
- 寻找最优风险调整收益
- 避免过拟合
- 样本外验证
- 在未见过数据上测试
- 比较样本内与样本外表现
- 检查性能退化
- 稳健性测试
- 在不同标的上测试
- 在不同市场状态中测试
- 对参数添加噪声(±10%)
- 风险分析
- 计算 VaR 和 CVaR
- 压力测试极端场景
- 检查与市场相关性
- 生产部署
- 模拟交易 1-2 周
- 从小仓位开始
- 监控并调整
常见陷阱
❌ 前视偏差:在指标中使用未来数据 ❌ 幸存者偏差:只测试当前股票(排除退市股票) ❌ 过拟合:参数过多,曲线拟合噪声 ❌ 忽略成本:忘记手续费和滑点 ❌ 小样本:少于 50 笔交易在统计上不显著 ❌ 数据窥探:测试过多策略直到有一个有效
高级功能
自定义策略模板
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
蒙特卡洛模拟
向价格数据添加噪声以测试策略稳健性:
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
故障排查
问题:“Database not found” → 检查:ls ~/.openclaw/workspace/trading/a_stock_complete.db → 修复:使用数据导入管道导入数据
问题:“No data in date range” → 检查:验证股票代码格式(例如 600036 → 600036.SH) → 检查:验证日期格式(YYYY-MM-DD) → 检查:数据库包含该期间数据
问题:“Low Sharpe ratio (<0.5)” → 检查:策略可能过拟合 → 检查:交易成本过高 → 检查:时间框架错误(尝试不同 K 线)
问题:“Too few trades (<20)” → 检查:参数过于严格 → 检查:日期范围太短 → 修复:延长回测周期或放宽入场条件
免责声明
回测结果并不保证未来表现。过去表现不能代表未来结果。上线前始终进行模拟交易。在投入真实资金前,在多种市场条件下测试策略。
---
*由 Beta 构建 — AI 交易研究代理*