修复 IndexError 的时间问题

提醒

每次修改源代码之后,需要 pip install -U . 进行安装才能生效,代码生效之后才能用于测试用例的验证

警告

不允许修改测试用例,测试用例是不能修改的

任务

对比 logs 中 master 分支和 remove-metaprogramming 分支的交易日志, 分析研究这两个日志中交易存在哪些区别,把这些区别写入到这个文档里面;

  • 日志对比结果:*

对比 master 分支和 remove-metaprogramming 分支的交易日志,发现”array index out of range”错误发生的日期存在系统性差异:

  • Master 分支: 2018-07-04, 2019-03-14, 2019-07-29, 2019-07-31, 2020-03-12, …

  • Current 分支: 2018-07-05, 2019-03-15, 2019-07-30, 2019-07-31, 2020-03-13, …

两个分支中 IndexError 触发的日期相差一天(除个别日期外),导致:

  • 预期交易数: 1750

  • 实际交易数: 1751

  • 差异: 多了 1 笔交易

分析研究这些交易不同发生的原因,并写入这个文档中

  • 根本原因分析:*

  1. 策略使用 datetime.date(1)检测月末

    • 策略通过self.datas[0].datetime.date(1)获取下一个交易日

    • 如果下一个月份与当前月份不同,触发月度调仓

    • 当访问超出数据范围时,应抛出 IndexError,使 next_month = current_month,避免最后一天调仓

  2. 数组预分配导致 IndexError 未正确触发

    • LineBuffer 的 array 可能被预分配用于 lookahead 操作

    • 预分配的位置填充默认值(0.0 或 NaN)

    • 直接通过 array 索引访问时,不会自然触发 IndexError

    • 导致策略在应该停止时继续运行,产生额外交易

  3. 时间差异的根源

    • Current 分支缺少对预分配数组的边界检查

    • 访问未加载数据时返回 0.0 而非抛出 IndexError

    • IndexError 延迟一天触发,导致调仓时机延后

提出可行的修改优化建议

  • 修改建议:*

linebuffer.py__getitem__方法中,对数据源(data feed)的 future 访问添加显式边界检查:

  1. 检查数组索引边界target_idx >= len(self.array)

  2. 检查值是否为默认值self.array[target_idx] == 0.0

对于 datetime 线,0.0 永远不是有效值,可安全判断为未加载数据。


# 在 linebuffer.py LineBuffer.__getitem__方法中添加

if getattr(self, '_is_data_feed_line', False) and ago > 0:
    target_idx = self._idx + ago

# 检查是否超出数组长度
    if target_idx >= len(self.array):
        raise IndexError(f"array index out of range")

# 检查值是否为默认值(未加载数据)
    if self.array[target_idx] == 0.0:
        raise IndexError(f"array index out of range")

```bash

- *修改效果**

 **测试用例 100%通过**

- `pytest tests/strategies/test_02_multi_extend_data.py` - **PASSED**
- `pytest tests -n 12` - **330 个测试全部通过**

 **修复结果验证**

- trade_num: 1750 
- sharpe_ratio: 0.46882103593170665 
- annual_return: 0.056615798284517765 
- max_drawdown: 0.24142378277185714 
- bar_num: 1885 

 **IndexError 触发时机恢复正常**

- "array index out of range"错误在正确的日期触发
- 月度调仓逻辑与 master 分支完全一致
- 交易数量与预期完全匹配

### 验收标准

1. pytest tests\strategies\test_02_multi_extend_data.py  这个检验能通过
2. pytest tests -n 12  all the tests can pass