1
0
Files
2026-01-27 18:30:41 +08:00

14 KiB
Raw Permalink Blame History

Tasks: Refactor Backtest Script

1. 项目设置和依赖

  • 1.1 创建 requirements.txt 文件,列出所有必需的 Python 包pandas, numpy, backtesting, sqlalchemy
  • 1.2 安装项目依赖pip install -r requirements.txt
  • 1.3 配置数据库凭证(在 backtest.py 中硬编码)
    • 设置 DB_HOST = '81.71.3.24'
    • 设置 DB_NAME = 'leopard_dev'
    • 设置 DB_USER = 'your_username'
    • 设置 DB_PASSWORD = 'your_password'
    • 根据实际开发环境修改这些值

3. 策略模板实现

  • 3.1 创建 strategy.py 文件,包含策略模板和示例
  • 3.2 实现 calculate_indicators(data) 函数
    • 计算 SMA10, SMA30, SMA60, SMA120 指标
    • 使用 data['Close'].rolling(window=N).mean() 方法
    • 将结果添加到 DataFramedata['sma10'] 等)
    • 返回添加了指标列的 DataFrame
  • 3.3 实现 get_strategy() 函数
    • 返回 SmaCross 类
    • 添加函数文档字符串说明用途
  • 3.4 实现 SmaCross 策略类
    • 继承 backtesting.Strategy
    • 定义类属性short_period = 10, long_period = 30
    • 实现 init() 方法:使用 self.I() 注册 sma10 和 sma30 指标
    • 实现 next() 方法:使用 crossover() 检测金叉和死叉,执行买卖操作
  • 3.5 添加详细的代码注释和文档字符串
    • 文件开头描述策略逻辑
    • 每个函数添加参数和返回值说明
    • 策略类参数添加注释(如 short_period 的含义)

4. 策略动态加载功能

  • 4.1 在 backtest.py 中实现 load_strategy(strategy_file) 函数
    • 使用 importlib.util.spec_from_file_location() 加载模块
    • 使用 importlib.util.module_from_spec() 创建模块对象
    • 使用 spec.loader.exec_module() 执行模块
  • 4.2 实现接口验证逻辑
    • 检查模块是否有 calculate_indicators 属性hasattr 检查)
    • 检查模块是否有 get_strategy 属性
    • 验证 get_strategy() 返回的是类对象isinstance 检查)
    • 验证策略类继承自 backtesting.Strategyissubclass 检查)
  • 4.3 实现异常处理
    • 捕获 FileNotFoundError策略文件不存在
    • 捕获 ImportError模块导入失败
    • 捕获 AttributeError接口不完整
    • 输出清晰的错误信息:"策略文件 {file} 加载失败: {error}"
  • 4.4 返回策略组件
    • 返回元组:(calculate_indicators 函数, strategy_class)

5. 命令行参数解析

  • 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: 预热天数,默认一年)
  • 5.2 实现参数验证
    • 检查日期格式YYYY-MM-DD使用 datetime.strptime() 验证
    • 检查策略文件是否存在os.path.isfile()
    • 验证数值参数为正数cash, commission
  • 5.3 添加友好的错误提示
    • 参数错误时显示帮助信息
    • 日期格式错误时提示正确格式

6. 结果输出功能

  • 6.1 实现 print_stats(stats) 函数
    • 创建 INDICATOR_MAPPING 字典(英文键 → 中文标签)
    • 遍历 stats 对象的键值对
    • 使用中文标签格式化输出
  • 6.2 实现格式化逻辑
    • 实现 format_value(value, cn_name, key) 辅助函数
    • 百分比和比率类值保留 2 位小数
    • 金额类值保留 2 位小数
    • 次数类值取整
    • 其他值保留 4 位小数
  • 6.3 添加输出格式化
    • 输出标题:"回测结果"(使用 "=" * 60 分隔)
    • 每个指标独占一行
    • 确保中英文对齐美观

7. 主流程编排

  • 7.1 实现 main() 函数,编排完整流程
    • 调用 parse_arguments() 解析参数
    • 调用 load_data_from_db() 加载数据
    • 调用 load_strategy() 加载策略
    • 调用 calculate_indicators() 计算指标
    • 创建 Backtest 对象并执行
    • 调用 print_stats() 输出结果
  • 7.2 添加进度提示信息
    • 数据加载前:输出 "加载股票数据: {code} ({start_date} ~ {end_date})"
    • 数据加载后:输出 "数据加载完成,共 {N} 条记录"
    • 策略加载前:输出 "加载策略: {strategy_file}"
    • 指标计算后:输出 "指标计算完成"
    • 回测开始:输出 "开始回测..."
    • 回测完成:输出 "回测完成!"
  • 7.3 实现回测执行
    • 使用 Backtest(data, strategy_class, cash=args.cash, commission=args.commission, finalize_trades=True)
    • 调用 bt.run() 执行回测
    • 保存返回的 stats 对象

8. HTML 图表生成

  • 8.1 实现可选的图表生成逻辑
    • 检查 args.output 参数是否指定
    • 仅当指定时才调用 bt.plot()
  • 8.2 生成 HTML 图表文件
    • 使用 bt.plot(filename=args.output, show=False) 生成文件
    • show=False 确保在无头环境中也能生成
    • 输出提示:"图表已保存到: {filepath}"
  • 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 文档(可选)
  • 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. 策略模板实现

  • 3.1 创建 strategy.py 文件,包含策略模板和示例
  • 3.2 实现 calculate_indicators(data) 函数
    • 计算 SMA10, SMA30, SMA60, SMA120 指标
    • 使用 data['Close'].rolling(window=N).mean() 方法
    • 将结果添加到 DataFramedata['sma10'] 等)
    • 返回添加了指标列的 DataFrame
  • 3.3 实现 get_strategy() 函数
    • 返回 SmaCross 类
    • 添加函数文档字符串说明用途
  • 3.4 实现 SmaCross 策略类
    • 继承 backtesting.Strategy
    • 定义类属性short_period = 10, long_period = 30
    • 实现 init() 方法:使用 self.I() 注册 sma10 和 sma30 指标
    • 实现 next() 方法:使用 crossover() 检测金叉和死叉,执行买卖操作
  • 3.5 添加详细的代码注释和文档字符串
    • 文件开头描述策略逻辑
    • 每个函数添加参数和返回值说明
    • 策略类参数添加注释(如 short_period 的含义)

4. 策略动态加载功能

  • 4.1 在 backtest.py 中实现 load_strategy(strategy_file) 函数
    • 使用 importlib.util.spec_from_file_location() 加载模块
    • 使用 importlib.util.module_from_spec() 创建模块对象
    • 使用 spec.loader.exec_module() 执行模块
  • 4.2 实现接口验证逻辑
    • 检查模块是否有 calculate_indicators 属性hasattr 检查)
    • 检查模块是否有 get_strategy 属性
    • 验证 get_strategy() 返回的是类对象isinstance 检查)
    • 验证策略类继承自 backtesting.Strategyissubclass 检查)
  • 4.3 实现异常处理
    • 捕获 FileNotFoundError策略文件不存在
    • 捕获 ImportError模块导入失败
    • 捕获 AttributeError接口不完整
    • 输出清晰的错误信息:"策略文件 {file} 加载失败: {error}"
  • 4.4 返回策略组件
    • 返回元组:(calculate_indicators 函数, strategy_class)

5. 命令行参数解析

  • 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: 预热天数,默认一年)
  • 5.2 实现参数验证
    • 检查日期格式YYYY-MM-DD使用 datetime.strptime() 验证
    • 检查策略文件是否存在os.path.isfile()
    • 验证数值参数为正数cash, commission
  • 5.3 添加友好的错误提示
    • 参数错误时显示帮助信息
    • 日期格式错误时提示正确格式

6. 结果输出功能

  • 6.1 实现 print_stats(stats) 函数
    • 创建 INDICATOR_MAPPING 字典(英文键 → 中文标签)
    • 遍历 stats 对象的键值对
    • 使用中文标签格式化输出
  • 6.2 实现格式化逻辑
    • 实现 format_value(value, cn_name, key) 辅助函数
    • 百分比和比率类值保留 2 位小数
    • 金额类值保留 2 位小数
    • 次数类值取整
    • 其他值保留 4 位小数
  • 6.3 添加输出格式化
    • 输出标题:"回测结果"(使用 "=" * 60 分隔)
    • 每个指标独占一行
    • 确保中英文对齐美观

7. 主流程编排

  • 7.1 实现 main() 函数,编排完整流程
    • 调用 parse_arguments() 解析参数
    • 调用 load_data_from_db() 加载数据
    • 调用 load_strategy() 加载策略
    • 调用 calculate_indicators() 计算指标
    • 创建 Backtest 对象并执行
    • 调用 print_stats() 输出结果
  • 7.2 添加进度提示信息
    • 数据加载前:输出 "加载股票数据: {code} ({start_date} ~ {end_date})"
    • 数据加载后:输出 "数据加载完成,共 {N} 条记录"
    • 策略加载前:输出 "加载策略: {strategy_file}"
    • 指标计算后:输出 "指标计算完成"
    • 回测开始:输出 "开始回测..."
    • 回测完成:输出 "回测完成!"
  • 7.3 实现回测执行
    • 使用 Backtest(data, strategy_class, cash=args.cash, commission=args.commission, finalize_trades=True)
    • 调用 bt.run() 执行回测
    • 保存返回的 stats 对象
  • 8.1 实现可选的图表生成逻辑
    • 检查 args.output 参数是否指定
    • 仅当指定时才调用 bt.plot()
  • 8.2 生成 HTML 图表文件
    • 使用 bt.plot(filename=args.output, show=False) 生成文件
    • show=False 确保在无头环境中也能生成
    • 输出提示:"图表已保存到: {filepath}"
  • 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
    # 基础用法
    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 最终代码审查
    • 对照设计文档检查实现是否完整
    • 对照规范文档检查所有场景是否覆盖
    • 确保代码遵循设计决策