4. 策略如何声明与使用数据

4.1. 1. 策略层在整体中的位置

策略层负责两件事:声明“需要什么数据”(以及多长窗口、是否使用最新周期),以及在 realize() 中“用数据算信号”。数据不由策略主动拉取,而是由运行层根据声明在每一步准备好并注入,策略仅通过 get_data(dtype_id) 按 id 获取。这样回测与实盘使用完全相同的数据视图与调用方式。

4.2. 2. 策略如何声明需要的数据

在策略类初始化(__init__)时,通过以下属性声明对数据的需求:

  • data_types:一个或多个 DataType 对象(或列表/字典)。每个 DataType 对应一种“可引用的信息”,并对应唯一的 dtype_id(如 close_E_d)。

  • window_length:历史数据窗口长度(如 20 表示最近 20 个周期)。可为标量(作用于所有声明的数据类型)或按 dtype 分别指定。

  • use_latest_data_cycle:是否只使用“最新一个周期”的数据(如仅用最新截面做选股),可按 dtype 分别设置。

声明后,引擎会知道该策略需要哪些 dtype_id、多长窗口,从而在运行前准备相应的数据窗口并在每一步更新注入。

4.3. 3. 运行时数据如何到达策略

  1. 准备阶段:根据回测区间(或实盘当前时刻)、策略的 data_types 与 window_length,引擎从 DataSource 取出对应区间内的数据,并按时间步预先或按需切出每个时间步的“数据窗口”。

  2. 每步运行前:对于当前要运行的 Group 内的每个策略,引擎调用 update_running_data_window,把当前步对应的数据窗口写入该策略的内部状态(按 dtype_id 索引)。

  3. realize() 内:策略通过 get_data(dtype_id) 按 id 取出已注入的窗口数据(numpy 数组),用于计算信号。无需传参,也无需关心数据来自哪张表。

因此,数据流是“声明 → 引擎按步注入 → get_data 引用”,策略代码不包含任何“读表”或“拉取”逻辑。

4.4. 4. 数据窗口的含义

  • 时间维度:window_length 表示“回溯多少个周期”。例如日频、window_length=20 表示最近 20 个交易日的数据;数组形状通常为 (n_periods,) 或 (n_assets, n_periods),最后一维为时间,最后一列为最近一期。

  • 多资产时的形状:不同策略基类对数据的组织方式略有差异:

    • RuleIterator:通常按资产迭代,每次 realize() 看到的是单资产的时间序列或截面。

    • FactorSorter:多资产截面(如每只股票一个因子值),用于排序选股。

    • GeneralStg:多资产、多 dtype 的窗口,返回与资产数相同长度的信号数组。

具体形状以 API 与策略基类文档为准;本系列强调“窗口由引擎按声明准备、策略用 get_data 按 id 取用”。

4.5. 5. 过程数据(proc.*)

除上述“声明 → 引擎注入”的静态历史数据外,qteasy 支持过程数据:依赖回测/实盘执行路径的状态(如当前持仓、现金、历史成交记录等)。过程数据无需在 data_types 中声明,由 Backtester(回测)或 Trader(实盘)在运行时维护并注入。

  • 访问方式:在 realize() 中通过 self.get_data('proc.own_cash')self.get_data('proc.trade_records', lag=0) 等形式按需获取;支持 lag(步或时间如 '1d')与 window(如 '5d')参数。

  • 约束:一次调用仅允许一个 proc.* 字段,且不得与静态数据混合调用;使用过程数据的策略将自动走动态回测路径(逐步生成信号、逐步成交)。

详见 过程数据(proc.*)与动态回测

4.6. 6. 参考数据(若有)

除策略声明的 data_types 外,qteasy 支持“参考数据”(如某只指数的收盘价,用于计算市场收益等)。参考数据与主数据的区别在于:通常与资产池无一一对应关系,在策略中也可通过相应的 dtype_id 或专用接口获取。具体配置与引用方式见当前版本文档与 API。

4.7. 7. 小结

“声明 → 引擎注入 → get_data 引用”保证了:

  • 回测与实盘使用同一套数据视图与访问方式;

  • 策略无法越权访问未声明或未来的数据,从机制上避免未来函数;

  • 接口统一、易于维护与扩展。

“声明 → 引擎注入 → get_data 引用”同样适用于过程数据,只是过程数据不需声明、由运行层按步注入,且仅在使用时触发动态回测路径。更多用法见《使用教程》与《API 参考》。