1
0
Files
leopard-analysis/openspec/specs/backtest-cli/spec.md
2026-01-27 18:30:41 +08:00

8.1 KiB
Raw Blame History

Spec: Backtest CLI

ADDED Requirements

Requirement: 命令行参数解析

回测脚本 SHALL 通过命令行参数接收用户输入,参数 SHALL 包含股票代码、时间范围、策略文件、回测参数等。

Scenario: 基础回测执行

  • WHEN 用户执行 python backtest.py --code 000001.SZ --start-date 2024-01-01 --end-date 2025-12-31 --strategy-file strategy.py
  • THEN 系统解析所有必需参数,无错误提示
  • THEN 开始执行回测流程
  • THEN 回测完成后输出统计信息到控制台

Scenario: 可选参数未指定

  • WHEN 用户未指定 --cash 参数
  • THEN 系统使用默认值 100000 作为初始资金
  • WHEN 用户未指定 --commission 参数
  • THEN 系统使用默认值 0.002 作为手续费率
  • WHEN 用户未指定 --output 参数
  • THEN 系统不生成 HTML 图表文件

Scenario: 必需参数缺失

  • WHEN 用户未提供 --code 参数
  • THEN 系统输出错误信息:"错误: 需要以下参数: --code"
  • THEN 系统退出并返回非零状态码
  • WHEN 用户未提供 --start-date--end-date 参数
  • THEN 系统输出对应的错误信息
  • THEN 系统退出并返回非零状态码

Scenario: 自定义参数值

  • WHEN 用户指定 --cash 500000 --commission 0.001 --output result.html
  • THEN 系统使用指定的 500000 作为初始资金
  • THEN 系统使用指定的 0.001 作为手续费率
  • THEN 回测完成后生成 HTML 图表到 result.html

Requirement: 数据库数据加载

回测脚本 SHALL 从 PostgreSQL 数据库加载指定股票的历史价格数据,并自动处理复权。

Scenario: 成功加载数据

  • WHEN 用户指定有效的股票代码和时间范围
  • THEN 系统连接数据库并执行查询
  • THEN 返回 DataFrame包含列: [Open, High, Low, Close, Volume, factor]
  • THEN DataFrame 的索引为 trade_date (DatetimeIndex)
  • THEN 数据已应用复权计算price * factor

Scenario: 数据库连接失败

  • WHEN 数据库连接失败(凭证错误、网络问题等)
  • THEN 系统捕获异常并输出错误信息:"数据库连接失败: {error}"
  • THEN 系统退出并返回非零状态码

Scenario: 未找到股票数据

  • WHEN 指定的股票代码或时间范围内无数据
  • THEN 系统抛出 ValueError: "未找到股票 {code} 在指定时间范围内的数据"
  • THEN 主流程捕获异常并输出友好错误信息
  • THEN 系统退出并返回非零状态码

Scenario: 数据验证

  • WHEN 数据库返回的 DataFrame 为空
  • THEN 系统提示数据为空并退出
  • WHEN 数据库返回的 DataFrame 少于 10 条记录
  • THEN 系统提示数据不足并退出

Requirement: 策略动态加载

回测脚本 SHALL 支持动态加载指定路径的策略文件,并验证策略接口。

Scenario: 加载有效策略文件

  • WHEN 用户指定 --strategy-file strategy.py
  • THEN 系统通过 importlib 加载该模块
  • THEN 系统获取模块的 calculate_indicators 函数
  • THEN 系统调用模块的 get_strategy() 函数获取策略类
  • THEN 系统返回 (calculate_indicators, strategy_class) 元组

Scenario: 策略文件不存在

  • WHEN 用户指定的策略文件路径不存在
  • THEN 系统捕获 FileNotFoundError
  • THEN 输出错误信息:"策略文件 {file} 不存在"
  • THEN 系统退出并返回非零状态码

Scenario: 策略接口不完整

  • WHEN 策略文件缺少 calculate_indicators 函数
  • THEN 系统捕获 AttributeError
  • THEN 输出错误信息:"策略文件 {file} 缺少 calculate_indicators 函数"
  • THEN 系统退出并返回非零状态码
  • WHEN 策略文件缺少 get_strategy 函数
  • THEN 系统捕获 AttributeError
  • THEN 输出错误信息:"策略文件 {file} 缺少 get_strategy 函数"
  • THEN 系统退出并返回非零状态码

Scenario: 加载子目录中的策略

  • WHEN 用户指定 --strategy-file strategies/macd_strategy.py
  • THEN 系统正确加载子目录中的策略模块
  • THEN 系统成功获取策略类和指标计算函数

Requirement: 指标计算

回测脚本 SHALL 在执行回测前调用策略的指标计算函数,将技术指标添加到数据集中。

Scenario: 成功计算指标

  • WHEN 系统调用 calculate_indicators(data)
  • THEN 函数接收包含 [Open, High, Low, Close, Volume, factor] 的 DataFrame
  • THEN 函数计算策略所需的指标(如 SMA, MACD, RSI
  • THEN 函数返回添加了指标列的 DataFrame
  • THEN DataFrame 保留原始列,新增指标列

Scenario: 指标计算产生 NaN 值

  • WHEN 滚动窗口计算导致前 N 行的指标值为 NaN
  • THEN DataFrame 包含 NaN 值(系统不自动删除)
  • THEN Backtest 框架在回测时会跳过 NaN 值的行

Scenario: 指标计算函数抛出异常

  • WHEN calculate_indicators(data) 执行时抛出异常
  • THEN 主流程捕获异常
  • THEN 输出错误信息:"指标计算失败: {error}"
  • THEN 系统退出并返回非零状态码

Requirement: 回测执行

回测脚本 SHALL 使用 backtesting 库执行回测,传入数据、策略和参数。

Scenario: 成功执行回测

  • WHEN 系统调用 Backtest(data, strategy_class, cash=..., commission=...).run()
  • THEN Backtest 初始化时调用策略类的 init() 方法
  • THEN Backtest 逐个时间步调用策略类的 next() 方法
  • THEN 系统返回包含回测统计信息的 stats 对象

Scenario: 回测参数传递

  • WHEN 用户指定 --cash 500000 --commission 0.001
  • THEN Backtest 实例化时使用 cash=500000
  • THEN Backtest 实例化时使用 commission=0.001
  • THEN Backtest 实例化时使用 finalize_trades=True

Scenario: 回测运行时错误

  • WHEN 策略的 next() 方法执行时抛出异常
  • THEN backtesting 库捕获异常
  • THEN 系统输出错误信息和堆栈跟踪
  • THEN 系统退出并返回非零状态码

Requirement: 结果输出

回测脚本 SHALL 将回测统计信息格式化输出到控制台,并可选生成 HTML 图表文件。

Scenario: 控制台输出

  • WHEN 回测成功完成
  • THEN 系统调用 print_stats(stats) 函数
  • THEN 系统输出回测统计信息,使用中文标签
  • THEN 输出内容包括:最终收益、总收益率、年化收益率、最大回撤、胜率等
  • THEN 数值格式化(保留 2 位小数)

Scenario: 生成 HTML 图表

  • WHEN 用户指定 --output result.html
  • THEN 系统调用 bt.plot(filename='result.html', show=False)
  • THEN 系统生成 HTML 文件到 result.html
  • THEN 系统输出提示:"图表已保存到: result.html"
  • THEN 图表包含价格曲线、资金曲线、买卖信号等

Scenario: 不生成 HTML 图表

  • WHEN 用户未指定 --output 参数
  • THEN 系统不调用 bt.plot() 方法
  • THEN 系统不生成任何图表文件
  • THEN 系统仅输出控制台统计信息

Scenario: 图表生成失败

  • WHEN bt.plot() 方法执行时抛出异常
  • THEN 系统捕获异常
  • THEN 系统输出警告:"图表生成失败,但回测已完成: {error}"
  • THEN 系统不影响控制台统计信息的输出
  • THEN 系统正常退出(返回状态码 0

Requirement: 错误处理

回测脚本 SHALL 对所有可能的错误进行捕获和处理,提供友好的错误提示。

Scenario: 数据库错误

  • WHEN 数据库操作抛出 sqlalchemy.exc.SQLAlchemyError
  • THEN 系统输出错误信息:"数据库错误: {error}"
  • THEN 系统退出并返回状态码 2

Scenario: 文件操作错误

  • WHEN 图表文件保存失败(权限、磁盘空间等)
  • THEN 系统输出错误信息:"文件操作错误: {error}"
  • THEN 系统退出并返回状态码 3

Scenario: 未预期的错误

  • WHEN 发生其他未捕获的异常
  • THEN 系统输出错误信息:"未知错误: {error}"
  • THEN 系统输出完整的堆栈跟踪
  • THEN 系统退出并返回状态码 1