Ⅲ · 逐项对照 — 3.4

两种风控架构

LEAN 的风险模型调整目标持仓;NautilusTrader 的 RiskEngine 验证具体订单。先区分输入和输出,才知道各自解决什么场景。

先区分两层,不把“风控”当成一个类名集合

风险控制至少可发生在两个时点:

  1. 交易意图还是“目标持仓”时:组合本来想把 EURUSD 配到 40%,但组合回撤、行业集中度或单品种止损规则要求改成 0 或更小仓位。
  2. 已经是一张“具体订单”时:这张订单的价格精度、数量、名义金额、账户影响和提交频率是否合规。

LEAN Algorithm Framework 的 RiskManagementModel 主要处理第一层,NautilusTrader 的 RiskEngine 主要处理第二层。它们不是同一功能的两种写法。

问题一:组合想持有多少?LEAN 的风险模型调整目标持仓Portfolio Construction目标:EURUSD +40%PortfolioTargetRiskManagementModel例:组合回撤、行业敞口、单品种止损 / 止盈Execution调整后目标:EURUSD = 0据此生成实际订单目标集合只返回需要改的目标模型可以串联:前一个模型的调整后目标交给下一个模型。它是策略层政策,不是每一笔订单的格式校验器。问题二:这张具体订单现在能否安全提交?Nautilus RiskEngine 把守订单入口Submit / Modify command价格、数量、方向、reduce_only 等具体字段RiskEngine精度 / 数量 / 名义金额 / 现金影响交易状态 / reduce_only / 提交与改单限速通过,或给出标准拒绝原因ExecutionEngine路由到 ExecutionClient再由券商作最终检查拒绝:OrderDenied / OrderModifyRejectedRiskEngine 默认位于 submit 与 modify 路径。取消与查询并不经过它;配置 bypass 时也会跳过预交易检查与限速。因此两者可并存:先用组合策略决定目标,再用订单闸门防止不合格或异常频率的具体订单进入执行链路。
LEAN 关注“目标持仓是否仍符合风险政策”;Nautilus 关注“当前这一张订单是否满足预交易约束”。名字相同,但输入、输出和适合解决的场景不同。

LEAN:风险模型怎样工作

在 Algorithm Framework 中,Portfolio Construction 产生 PortfolioTarget,表示“最终希望持有多少单位”。每个风险模型接收目标集合和算法状态,只返回需要被改动的目标;多个模型按加入顺序依次处理前一个模型的结果 官方文档

内置模型 它监看的对象 触发后通常交给 Execution 的调整 适合先验证的场景
MaximumDrawdownPercentPortfolio 整个组合相对起始值或峰值的回撤 全组合清仓目标,并取消相关 insights 组合总损失达到熔断线
MaximumSectorExposureRiskManagementModel 同一行业的目标敞口 缩小超出上限的行业目标 股票组合的行业集中度约束
MaximumDrawdownPercentPerSecurity 单品种持仓的未实现亏损 该品种归零目标,并取消其 insight 单标的固定止损
MaximumUnrealizedProfitPercentPerSecurity 单品种未实现盈利 该品种归零目标 固定获利退出
TrailingStopRiskManagementModel 单品种从最高未实现利润回撤的幅度 该品种归零目标 移动止损
CompositeRiskManagementModel / NullRiskManagementModel 多个规则或不修改目标 依次组合,或保持原目标 组合规则,或显式关闭该策略层

这张表的关键不是“LEAN 自带多少类”,而是输入与输出都是 PortfolioTarget。因此自定义模型可以读取组合状态、市场状态或外部风险指标,再返回缩仓、清仓或重分配的目标。反过来,它不是通用的订单字段验证器。直接发出的订单、券商保证金和交易所规则仍需要相应的交易与券商层处理。

NautilusTrader:RiskEngine 真正检查什么

Nautilus 的 RiskEngine 是每个回测、sandbox 和实盘系统都有的执行组件。默认情况下,它位于 submit 与 modify 路径,检查失败时生成 OrderDeniedOrderModifyRejected;取消和查询命令不走这道检查 官方执行文档

检查类别 具体检查或配置 它防的是什么
订单与标的约束 价格与触发价精度、正价格规则、数量精度、最小/最大基础数量、GTD 是否已过期 错误单位、越界数量、过期订单进入执行链路
改变敞口的约束 reduce_only 不得扩大关联仓位;交易状态可为 ACTIVEHALTEDREDUCING 暂停时仍开新仓,或平仓单意外加仓
金额与账户影响 每订单名义金额上限、标的名义金额限制、现金账户余额影响 手误把数量放大,或现金账户无法覆盖订单
运行保护 提交和改单速率限制;重复 ID 防护仍保留 循环 bug 触发异常下单或改单洪流

它的公开配置重点是 bypass、提交/改单速率和按标的设置的 max_notional_per_order;部分字段与账户检查是引擎固定执行逻辑 本地已检视配置接口bypass=True 会跳过预交易检查与限速,因此“它是闸门”描述的是默认运行路径,不是不可绕开的安全保证。

Nautilus 没有替你预置的是什么

RiskEngine 不等于一套组合回撤、行业暴露或移动止损模型库。它可以阻止一张不合格的订单,却不会仅因为“全组合回撤达到 8%”而自动替你设计减仓政策。若需要这类组合政策,应由策略或单独的监督组件读取 Portfolio、仓位和市场状态,形成目标或交易状态控制,再让具体订单继续穿过 RiskEngine。

因此更准确的组合方式是:先用组合策略决定“想持有什么”,再用订单风控确认“这张订单能不能发”。无论选择哪套框架,券商和交易所仍是最后一道规则检查。

MQL5 中,一个 EA 可以用 PositionsTotal()OrdersTotal() 读取账户信息并实现上述任意政策,但标准 EA 结构不提供跨实例统一的组合目标层或预交易闸门。是否需要把这些做成共享服务,取决于未来实际的账户、策略和部署边界,不能由当前文档预设。