1
0
Files
leopard-analysis/openspec/changes/archive/2026-01-27-refactor-backtest-script/tasks.md
2026-01-27 18:30:41 +08:00

367 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Tasks: Refactor Backtest Script
## 1. 项目设置和依赖
- [x] 1.1 创建 requirements.txt 文件,列出所有必需的 Python 包pandas, numpy, backtesting, sqlalchemy
- [ ] 1.2 安装项目依赖pip install -r requirements.txt
- [x] 1.3 配置数据库凭证(在 backtest.py 中硬编码)
- 设置 DB_HOST = '81.71.3.24'
- 设置 DB_NAME = 'leopard_dev'
- 设置 DB_USER = 'your_username'
- 设置 DB_PASSWORD = 'your_password'
- 根据实际开发环境修改这些值
---
## 3. 策略模板实现
- [x] 3.1 创建 strategy.py 文件,包含策略模板和示例
- [x] 3.2 实现 calculate_indicators(data) 函数
- 计算 SMA10, SMA30, SMA60, SMA120 指标
- 使用 data['Close'].rolling(window=N).mean() 方法
- 将结果添加到 DataFramedata['sma10'] 等)
- 返回添加了指标列的 DataFrame
- [x] 3.3 实现 get_strategy() 函数
- 返回 SmaCross 类
- 添加函数文档字符串说明用途
- [x] 3.4 实现 SmaCross 策略类
- 继承 backtesting.Strategy
- 定义类属性short_period = 10, long_period = 30
- 实现 init() 方法:使用 self.I() 注册 sma10 和 sma30 指标
- 实现 next() 方法:使用 crossover() 检测金叉和死叉,执行买卖操作
- [x] 3.5 添加详细的代码注释和文档字符串
- 文件开头描述策略逻辑
- 每个函数添加参数和返回值说明
- 策略类参数添加注释(如 short_period 的含义)
## 4. 策略动态加载功能
- [x] 4.1 在 backtest.py 中实现 load_strategy(strategy_file) 函数
- 使用 importlib.util.spec_from_file_location() 加载模块
- 使用 importlib.util.module_from_spec() 创建模块对象
- 使用 spec.loader.exec_module() 执行模块
- [x] 4.2 实现接口验证逻辑
- 检查模块是否有 calculate_indicators 属性hasattr 检查)
- 检查模块是否有 get_strategy 属性
- 验证 get_strategy() 返回的是类对象isinstance 检查)
- 验证策略类继承自 backtesting.Strategyissubclass 检查)
- [x] 4.3 实现异常处理
- 捕获 FileNotFoundError策略文件不存在
- 捕获 ImportError模块导入失败
- 捕获 AttributeError接口不完整
- 输出清晰的错误信息:"策略文件 {file} 加载失败: {error}"
- [x] 4.4 返回策略组件
- 返回元组:(calculate_indicators 函数, strategy_class)
## 5. 命令行参数解析
- [x] 5.1 实现 parse_arguments() 函数
- 使用 argparse.ArgumentParser 创建解析器
- 添加 --code 参数必需help: 股票代码)
- 添加 --start-date 参数必需help: 回测开始日期)
- 添加 --end-date 参数必需help: 回测结束日期)
- 添加 --strategy-file 参数必需help: 策略文件路径)
- 添加 --cash 参数可选default=100000help: 初始资金)
- 添加 --commission 参数可选default=0.002help: 手续费率)
- 添加 --output 参数可选help: HTML 输出文件路径)
- 添加 --warmup-days 参数可选default=365help: 预热天数,默认一年)
- [x] 5.2 实现参数验证
- 检查日期格式YYYY-MM-DD使用 datetime.strptime() 验证
- 检查策略文件是否存在os.path.isfile()
- 验证数值参数为正数cash, commission
- [x] 5.3 添加友好的错误提示
- 参数错误时显示帮助信息
- 日期格式错误时提示正确格式
## 6. 结果输出功能
- [x] 6.1 实现 print_stats(stats) 函数
- 创建 INDICATOR_MAPPING 字典(英文键 → 中文标签)
- 遍历 stats 对象的键值对
- 使用中文标签格式化输出
- [x] 6.2 实现格式化逻辑
- 实现 format_value(value, cn_name, key) 辅助函数
- 百分比和比率类值保留 2 位小数
- 金额类值保留 2 位小数
- 次数类值取整
- 其他值保留 4 位小数
- [x] 6.3 添加输出格式化
- 输出标题:"回测结果"(使用 "=" * 60 分隔)
- 每个指标独占一行
- 确保中英文对齐美观
## 7. 主流程编排
- [x] 7.1 实现 main() 函数,编排完整流程
- 调用 parse_arguments() 解析参数
- 调用 load_data_from_db() 加载数据
- 调用 load_strategy() 加载策略
- 调用 calculate_indicators() 计算指标
- 创建 Backtest 对象并执行
- 调用 print_stats() 输出结果
- [x] 7.2 添加进度提示信息
- 数据加载前:输出 "加载股票数据: {code} ({start_date} ~ {end_date})"
- 数据加载后:输出 "数据加载完成,共 {N} 条记录"
- 策略加载前:输出 "加载策略: {strategy_file}"
- 指标计算后:输出 "指标计算完成"
- 回测开始:输出 "开始回测..."
- 回测完成:输出 "回测完成!"
- [x] 7.3 实现回测执行
- 使用 Backtest(data, strategy_class, cash=args.cash, commission=args.commission, finalize_trades=True)
- 调用 bt.run() 执行回测
- 保存返回的 stats 对象
## 8. HTML 图表生成
- [x] 8.1 实现可选的图表生成逻辑
- 检查 args.output 参数是否指定
- 仅当指定时才调用 bt.plot()
- [x] 8.2 生成 HTML 图表文件
- 使用 bt.plot(filename=args.output, show=False) 生成文件
- show=False 确保在无头环境中也能生成
- 输出提示:"图表已保存到: {filepath}"
- [x] 8.3 添加异常处理
- 捕获图表生成异常
- 输出警告:"图表生成失败,但回测已完成: {error}"
- 不影响统计信息的正常输出
- 确保主流程正常退出(状态码 0
## 9. 全局错误处理
- [x] 9.1 在 main() 函数外层添加 try-except
- 捕获所有未预期的异常
- 输出错误信息和堆栈跟踪traceback.print_exc()
- 使用非零状态码退出
- [x] 9.2 实现特定错误的状态码映射
- 数据库错误:状态码 2
- 文件操作错误:状态码 3
- 参数错误:状态码 4
- 其他错误:状态码 1
- [x] 9.3 添加 `if __name__ == '__main__':` 入口
- 调用 main() 函数
- 确保脚本可直接执行和作为模块导入
## 10. 文档和示例(可选)
- [ ] 10.1 创建 README.md 文档(可选)
- [ ] 10.2 添加内联文档到 backtest.py
- [ ] 10.3 添加使用示例到 README
## 11. 测试和验证
- [ ] 11.1 测试基础回测流程
- [ ] 11.2 测试 HTML 图表生成
- [ ] 11.3 测试错误处理
- [ ] 11.4 测试不同策略
- [ ] 11.5 验证输出格式
## 12. 代码质量检查
- [ ] 12.1 运行代码检查工具(可选)
- [ ] 12.2 验证依赖版本兼容性
- [ ] 12.3 最终代码审查
---
## 3. 策略模板实现
- [x] 3.1 创建 strategy.py 文件,包含策略模板和示例
- [x] 3.2 实现 calculate_indicators(data) 函数
- 计算 SMA10, SMA30, SMA60, SMA120 指标
- 使用 data['Close'].rolling(window=N).mean() 方法
- 将结果添加到 DataFramedata['sma10'] 等)
- 返回添加了指标列的 DataFrame
- [x] 3.3 实现 get_strategy() 函数
- 返回 SmaCross 类
- 添加函数文档字符串说明用途
- [x] 3.4 实现 SmaCross 策略类
- 继承 backtesting.Strategy
- 定义类属性short_period = 10, long_period = 30
- 实现 init() 方法:使用 self.I() 注册 sma10 和 sma30 指标
- 实现 next() 方法:使用 crossover() 检测金叉和死叉,执行买卖操作
- [x] 3.5 添加详细的代码注释和文档字符串
- 文件开头描述策略逻辑
- 每个函数添加参数和返回值说明
- 策略类参数添加注释(如 short_period 的含义)
---
## 4. 策略动态加载功能
- [x] 4.1 在 backtest.py 中实现 load_strategy(strategy_file) 函数
- 使用 importlib.util.spec_from_file_location() 加载模块
- 使用 importlib.util.module_from_spec() 创建模块对象
- 使用 spec.loader.exec_module() 执行模块
- [x] 4.2 实现接口验证逻辑
- 检查模块是否有 calculate_indicators 属性hasattr 检查)
- 检查模块是否有 get_strategy 属性
- 验证 get_strategy() 返回的是类对象isinstance 检查)
- 验证策略类继承自 backtesting.Strategyissubclass 检查)
- [x] 4.3 实现异常处理
- 捕获 FileNotFoundError策略文件不存在
- 捕获 ImportError模块导入失败
- 捕获 AttributeError接口不完整
- 输出清晰的错误信息:"策略文件 {file} 加载失败: {error}"
- [x] 4.4 返回策略组件
- 返回元组:(calculate_indicators 函数, strategy_class)
---
## 5. 命令行参数解析
- [x] 5.1 实现 parse_arguments() 函数
- 使用 argparse.ArgumentParser 创建解析器
- 添加 --code 参数必需help: 股票代码)
- 添加 --start-date 参数必需help: 回测开始日期)
- 添加 --end-date 参数必需help: 回测结束日期)
- 添加 --strategy-file 参数必需help: 策略文件路径)
- 添加 --cash 参数可选default=100000help: 初始资金)
- 添加 --commission 参数可选default=0.002help: 手续费率)
- 添加 --output 参数可选help: HTML 输出文件路径)
- 添加 --warmup-days 参数可选default=365help: 预热天数,默认一年)
- [x] 5.2 实现参数验证
- 检查日期格式YYYY-MM-DD使用 datetime.strptime() 验证
- 检查策略文件是否存在os.path.isfile()
- 验证数值参数为正数cash, commission
- [x] 5.3 添加友好的错误提示
- 参数错误时显示帮助信息
- 日期格式错误时提示正确格式
---
## 6. 结果输出功能
- [x] 6.1 实现 print_stats(stats) 函数
- 创建 INDICATOR_MAPPING 字典(英文键 → 中文标签)
- 遍历 stats 对象的键值对
- 使用中文标签格式化输出
- [x] 6.2 实现格式化逻辑
- 实现 format_value(value, cn_name, key) 辅助函数
- 百分比和比率类值保留 2 位小数
- 金额类值保留 2 位小数
- 次数类值取整
- 其他值保留 4 位小数
- [x] 6.3 添加输出格式化
- 输出标题:"回测结果"(使用 "=" * 60 分隔)
- 每个指标独占一行
- 确保中英文对齐美观
---
## 7. 主流程编排
- [x] 7.1 实现 main() 函数,编排完整流程
- 调用 parse_arguments() 解析参数
- 调用 load_data_from_db() 加载数据
- 调用 load_strategy() 加载策略
- 调用 calculate_indicators() 计算指标
- 创建 Backtest 对象并执行
- 调用 print_stats() 输出结果
- [x] 7.2 添加进度提示信息
- 数据加载前:输出 "加载股票数据: {code} ({start_date} ~ {end_date})"
- 数据加载后:输出 "数据加载完成,共 {N} 条记录"
- 策略加载前:输出 "加载策略: {strategy_file}"
- 指标计算后:输出 "指标计算完成"
- 回测开始:输出 "开始回测..."
- 回测完成:输出 "回测完成!"
- [x] 7.3 实现回测执行
- 使用 Backtest(data, strategy_class, cash=args.cash, commission=args.commission, finalize_trades=True)
- 调用 bt.run() 执行回测
- 保存返回的 stats 对象
- [x] 8.1 实现可选的图表生成逻辑
- 检查 args.output 参数是否指定
- 仅当指定时才调用 bt.plot()
- [x] 8.2 生成 HTML 图表文件
- 使用 bt.plot(filename=args.output, show=False) 生成文件
- show=False 确保在无头环境中也能生成
- 输出提示:"图表已保存到: {filepath}"
- [x] 8.3 添加异常处理
- 捕获图表生成异常
- 输出警告:"图表生成失败,但回测已完成: {error}"
- 不影响统计信息的正常输出
- 确保主流程正常退出(状态码 0
---
## 9. 全局错误处理
- [ ] 9.1 在 main() 函数外层添加 try-except
- 捕获所有未预期的异常
- 输出错误信息和堆栈跟踪traceback.print_exc()
- 使用非零状态码退出
- [ ] 9.2 实现特定错误的状态码映射
- 数据库错误:状态码 2
- 文件操作错误:状态码 3
- 参数错误:状态码 4
- 其他错误:状态码 1
- [ ] 9.3 添加 `if __name__ == '__main__':` 入口
- 调用 main() 函数
- 确保脚本可直接执行和作为模块导入
---
## 10. 文档和示例
- [ ] 10.1 创建 README.md 文档(可选)
- 说明项目用途和功能
- 提供安装步骤pip install -r requirements.txt
- 提供使用示例(基础用法、自定义参数、不同策略)
- 说明策略文件接口规范
- 说明环境变量配置DB_USER, DB_PASSWORD
- [ ] 10.2 添加内联文档到 backtest.py
- 文件开头添加模块文档字符串
- 说明命令行参数和用法
- 提供使用示例
- [ ] 10.3 添加使用示例到 README
```bash
# 基础用法
python backtest.py --code 000001.SZ --start-date 2024-01-01 --end-date 2025-12-31 --strategy-file strategy.py
# 自定义参数
python backtest.py --code 000001.SZ --start-date 2024-01-01 --end-date 2025-12-31 --strategy-file strategy.py --cash 500000 --commission 0.001 --output result.html
```
---
## 11. 测试和验证
- [ ] 11.1 测试基础回测流程
- 执行 `python backtest.py --code 000001.SZ --start-date 2024-01-01 --end-date 2025-12-31 --strategy-file strategy.py`
- 验证数据加载成功
- 验证策略加载成功
- 验证回测执行成功
- 验证统计信息输出正确
- [ ] 11.2 测试 HTML 图表生成
- 执行带 `--output` 参数的命令
- 验证 HTML 文件成功生成
- 验证图表内容正确(价格曲线、资金曲线等)
- [ ] 11.3 测试错误处理
- 测试无效股票代码(应提示未找到数据)
- 测试无效日期格式(应提示格式错误)
- 测试策略文件不存在(应提示文件不存在)
- 测试数据库连接失败(应提示连接错误)
- 测试策略接口不完整(应提示缺少函数)
- [ ] 11.4 测试不同策略
- 创建 strategies/macd_strategy.py
- 使用新策略执行回测
- 验证动态加载功能正常
- [ ] 11.5 验证输出格式
- 检查控制台输出使用中文标签
- 检查数值格式化正确(小数位数)
- 检查 HTML 文件可正常打开
---
## 12. 代码质量检查
- [ ] 12.1 运行代码检查工具(可选)
- 使用 pylint 或 flake8 检查代码风格
- 修复警告和错误
- [ ] 12.2 验证依赖版本兼容性
- 检查 backtesting 库版本兼容性
- 检查 pandas 和 numpy 版本要求
- [ ] 12.3 最终代码审查
- 对照设计文档检查实现是否完整
- 对照规范文档检查所有场景是否覆盖
- 确保代码遵循设计决策