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. 运行时数据如何到达策略
準備階段:根據回測區間(或實盤當前時刻)、策略的 data_types 與 window_length,引擎從 DataSource 取出對應區間內的數據,並按時間步預先或按需切出每個時間步的“數據窗口”。
每步運行前:對於當前要運行的 Group 內的每個策略,引擎調用 update_running_data_window,把當前步對應的數據窗口寫入該策略的內部狀態(按 dtype_id 索引)。
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.*字段,且不得與靜態數據混合調用;使用過程數據的策略將自動走動態回測路徑(逐步生成信號、逐步成交)。
4.6. 6. 参考数据(若有)
除策略聲明的 data_types 外,qteasy 支持“參考數據”(如某隻指數的收盤價,用於計算市場收益等)。參考數據與主數據的區別在於:通常與資產池無一一對應關係,在策略中也可通過相應的 dtype_id 或專用接口獲取。具體配置與引用方式見當前版本文檔與 API。
4.7. 7. 小结
“聲明 → 引擎注入 → get_data 引用”保證了:
回測與實盤使用同一套數據視圖與訪問方式;
策略無法越權訪問未聲明或未來的數據,從機制上避免未來函數;
接口統一、易於維護與擴展。
“聲明 → 引擎注入 → get_data 引用”同樣適用於過程數據,只是過程數據不需聲明、由運行層按步注入,且僅在使用時觸發動態回測路徑。更多用法見《使用教程》與《API 參考》。