完成回测脚本
This commit is contained in:
@@ -0,0 +1,366 @@
|
||||
# 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() 方法
|
||||
- 将结果添加到 DataFrame(data['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.Strategy(issubclass 检查)
|
||||
- [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=100000,help: 初始资金)
|
||||
- 添加 --commission 参数(可选,default=0.002,help: 手续费率)
|
||||
- 添加 --output 参数(可选,help: HTML 输出文件路径)
|
||||
- 添加 --warmup-days 参数(可选,default=365,help: 预热天数,默认一年)
|
||||
- [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() 方法
|
||||
- 将结果添加到 DataFrame(data['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.Strategy(issubclass 检查)
|
||||
- [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=100000,help: 初始资金)
|
||||
- 添加 --commission 参数(可选,default=0.002,help: 手续费率)
|
||||
- 添加 --output 参数(可选,help: HTML 输出文件路径)
|
||||
- 添加 --warmup-days 参数(可选,default=365,help: 预热天数,默认一年)
|
||||
- [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 最终代码审查
|
||||
- 对照设计文档检查实现是否完整
|
||||
- 对照规范文档检查所有场景是否覆盖
|
||||
- 确保代码遵循设计决策
|
||||
Reference in New Issue
Block a user