Ⅱ · 框架解剖 — 2.4
LEAN · 时间片、订单事件与策略流水线
LEAN 将同一时点可用的数据整理成 Slice,再推进组合状态、算法回调与可选的策略模型。
一个 Slice 内发生什么
IDataFeed 不把每条原始输入直接交给策略,而是由引擎将同一时点可用的数据整理为 Slice。在一个时间片内,引擎处理定时事件与标的变更,更新价格、现金和已有订单的成交状态,然后再将 Slice 投递给算法。
因此,算法的 on_data(slice) 面对的是一个带时间边界的数据容器,而不是单一字段。它可以包含 quote bar、trade bar、tick、期权链、期货链、拆股、分红和标的代码变更等对象 官方文档。
订单事件不只发生在 on_data 内
算法发起订单请求后,ITransactionHandler 使用回测成交模型或 brokerages 处理它。订单接受、成交、撤单和拒绝等结果会以 on_order_event 等回调回到算法,并更新 Portfolio 和 Transactions 可见的状态。
on_data、定时事件与订单事件分别是不同的入口。策略实现应按照事件语义处理状态,而不是假设所有订单变化都只在下一次行情回调时出现。
可选的 Algorithm Framework
若采用 Algorithm Framework,策略层可按照下面的五段组织:
UniverseSelectionModel → 标的集合
AlphaModel → Insight
PortfolioConstruction → PortfolioTarget
RiskManagement → 调整后的 PortfolioTarget
ExecutionModel → 订单请求
这是一种可选的策略分工。也可以直接在 QCAlgorithm 的 on_data、定时事件与订单事件中编写逻辑。选择前者时,Insight 与 PortfolioTarget 让观点、目标仓位和订单请求成为三个可检查的中间对象;选择后者时,策略仍然经过同一套 Engine 数据、事务和结果处理边界。
一个最小算法入口
class MyAlgorithm(QCAlgorithm):
def initialize(self):
fx = self.add_forex("EURUSD", Resolution.MINUTE, Market.OANDA)
self.symbol = fx.symbol
def on_data(self, slice):
bar = slice.quote_bars.get(self.symbol)
if bar:
self.set_holdings(self.symbol, 0.5)
def on_order_event(self, order_event):
pass
示例只展示入口位置,不表达策略建议。策略的指标、多周期聚合、风险规则和执行方法将在第三章以 Giles SMC 源码的职责拆分为共同样本讨论。