Ⅱ · 框架解剖 — 2.4

LEAN · 时间片、订单事件与策略流水线

LEAN 将同一时点可用的数据整理成 Slice,再推进组合状态、算法回调与可选的策略模型。

一个 Slice 内发生什么

IDataFeed 不把每条原始输入直接交给策略,而是由引擎将同一时点可用的数据整理为 Slice。在一个时间片内,引擎处理定时事件与标的变更,更新价格、现金和已有订单的成交状态,然后再将 Slice 投递给算法。

一次时间片的推进1 · IDataFeed取下一批可用数据2 · Slice同一时点的数据容器3 · Engine状态与定时事件4 · QCAlgorithmon_data(slice)quote bars · trade bars · ticks · 公司行为 · 标的变更 …策略层可选的 Algorithm FrameworkUniverse标的集合AlphaInsightPortfolioPortfolioTargetRisk调整 TargetExecution订单请求不用此结构时,策略可直接在 `on_data`、定时事件和订单事件中组织自己的逻辑。订单事件形成另一条回路算法订单请求Market / Limit / TargetITransactionHandler成交模型或 brokeragePortfolio / Transactions状态更新on_order_event算法处理订单事实数据回调和订单事件是不同入口,但它们通过 Portfolio、Transactions 与 Security 状态在下一次策略决策中相遇。
LEAN 的关键单位是 Slice。策略既可直接处理 Slice,也可把它送入可选的策略流水线;订单结果则通过事务处理和订单事件回到同一算法运行时。

因此,算法的 on_data(slice) 面对的是一个带时间边界的数据容器,而不是单一字段。它可以包含 quote bar、trade bar、tick、期权链、期货链、拆股、分红和标的代码变更等对象 官方文档

订单事件不只发生在 on_data

算法发起订单请求后,ITransactionHandler 使用回测成交模型或 brokerages 处理它。订单接受、成交、撤单和拒绝等结果会以 on_order_event 等回调回到算法,并更新 PortfolioTransactions 可见的状态。

on_data、定时事件与订单事件分别是不同的入口。策略实现应按照事件语义处理状态,而不是假设所有订单变化都只在下一次行情回调时出现。

可选的 Algorithm Framework

若采用 Algorithm Framework,策略层可按照下面的五段组织:

UniverseSelectionModel  → 标的集合
AlphaModel              → Insight
PortfolioConstruction   → PortfolioTarget
RiskManagement          → 调整后的 PortfolioTarget
ExecutionModel          → 订单请求

这是一种可选的策略分工。也可以直接在 QCAlgorithmon_data、定时事件与订单事件中编写逻辑。选择前者时,InsightPortfolioTarget 让观点、目标仓位和订单请求成为三个可检查的中间对象;选择后者时,策略仍然经过同一套 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 源码的职责拆分为共同样本讨论。