Ⅲ · 逐项对照 — 3.1

指标计算模型

先分清输入契约、状态准备与图表渲染,再比较 MQL5、NautilusTrader 与 LEAN 的指标实现。

先把一个“指标”拆成三件事

无论是 EMA、ATR 还是 SMC 的结构标注,讨论前要区分三件不同的工作:

  1. 计算:公式如何从价格或成交数据得到新值。
  2. 状态准备:一个滚动公式在作出判断前,是否已经收到足够的历史样本。
  3. 显示:结果是否、以及用什么界面画给人看。

之前把这三件事压进一个表格,才会出现“预热、内置数量、向量化、四个方法”都看不出在说什么的问题。

计算时,谁推进指标?

同一条 EMA 公式,先区分“谁把数据交给指标”MQL5 自定义指标:终端给数组,开发者决定从哪里重算OnCalculate(...)time[] · OHLC[]prev_calculated = N开发者循环从 N 附近开始,补算受影响 bar历史变化时 N 可能回到 0指标 buffer每根 bar 一个结果供图表 / CopyBufferNautilusTrader / LEAN:框架持续推送单个输入,指标自己保存滚动状态bar / quote / data point一次一个时序输入indicator.update / handle_*更新窗口、计数与当前值value / currentinitialized / is_ready 后可用“拉取 / 推送”描述输入契约,不描述数学公式。EMA、ATR、FVG 等逻辑都可以在两种模型中实现。
MQL5 的重点是用 prev_calculated 避免整段重复计算;Nautilus 与 LEAN 的重点是让指标对象在每次更新后保留自己的内部状态。
维度 MQL5 自定义指标 NautilusTrader LEAN
输入契约 终端调用 OnCalculate,传入完整价格数组与 prev_calculated 策略或引擎把 bar、quote 或 trade tick 送入指标 指标接收 data point、bar 或 trade bar,可手动或自动更新
开发者需要处理 决定从哪根 bar 起重算,并写入对应 buffer 订阅合适数据,并在需要时将 bar/tick 交给指标 创建或注册指标,决定自动订阅还是手动 update
当前值何时可信 自己定义足够样本和空值规则 initialized 表示指标输入已满足其要求 is_ready 表示满足指标定义的最小样本数
结果读取 指标 buffer,其他程序可用 CopyBuffer 读取 指标对象的当前值,例如 .value 指标对象的当前值,例如 .current.value

prev_calculated 只是终端告诉指标“上次成功处理到哪里”的增量计算线索;历史补齐或变化后,终端会把它重置为 0 MQL5 文档。它不是“预热完成”的标记。

上一版表格中的“4 个方法”已删除。它把不同职责混成了一个数字:Nautilus 常见的 handle_barhandle_quote_tickhandle_trade_tick 是三种输入形式,reset 是清空状态的生命周期操作,它们不是四个可互换的指标公式接口。

“预热”到底是什么

“预热”不是另一个指标:它只是先把历史样本按正常顺序喂给滚动状态策略开始决策第一个可交易时刻没有预热:EMA(5) 刚开始累计bar 1bar 2bar 3bar 4bar 5第 5 个样本才 ready开始后前 4 根,指标窗口不完整有预热:过去 5 根先进入同一个 update 过程历史 1历史 2历史 3历史 4历史 5窗口已完整第一个可交易时刻已 ready
LEAN 可以用 set_warm_up 或指标预热辅助方法完成这件事;Nautilus 与 MQL5 也可以加载历史后逐条推进。区别主要是框架是否提供约定和就绪标识。

以 EMA(20) 为例,预热指在正式交易判断前,把至少足以建立状态的较早数据依次送进同一个指标对象。不是另算一套 EMA,也不是把历史结果直接塞给策略。

  • LEAN 可以设置算法级 set_warm_up,或为某个指标请求历史并用预热辅助方法推进。预热期的数据会进入算法,但不能下单 官方文档
  • NautilusTrader 可以请求或装载历史数据,再让指标按通常的 bar/tick 路径推进;是否何时开始交易由策略自己约束。
  • MQL5 指标 初次 OnCalculate 已可拿到终端提供的历史数组。开发者需要自行决定前 N 根是否输出空值,EA 若依赖该指标也需要自行约定何时才开始交易。

“向量化”是研究里的批量计算方式

向量化不是某个框架的开关。它表示把一整列或多列数据交给 NumPy、pandas、DuckDB 等工具批量计算,例如对百万行收盘价一次求滚动均线,而不是用 Python 循环逐根推进。

运行中的事件驱动策略仍应按时间顺序维护状态;研究中则可以对完整历史做批量计算。两者可以复用同一个公式,却必须核对窗口起点、时区、bar 收盘约定和缺失值处理,否则“向量化版本”与线上版本可能得出不同结果。

“内置指标数量”也不再作为对比列。它只表示某个库随包提供了多少类,无法说明是否覆盖所需公式、能否组合、数据质量是否合适,更不等于策略能力。实际工作里更有用的是先确认输入类型、就绪条件和输出语义。

MQL5 的指标是否同时负责计算和绘制?

计算与绘制可以分开理解,区别在“显示绑定发生在哪里”MQL5 自定义指标:同一个指标程序可计算,也可把数据 buffer 交给终端绘制OnCalculate计算每根 bar 的值INDICATOR_DATA buffer结果数组DRAW_LINE / DRAW_* MT5 图表自动画也可以不画DRAW_NONE / 计算 buffer独立计算与展示:先输出有业务含义的数据,再显式选择一个消费者指标 / 策略计算 EMA、FVG、信号语义记录时间、价格、区间、状态、来源显式渲染或不渲染KLineCharts · Plotly · 报告 · 告警同一记录可供多个消费者使用这不是“换了一个画图组件”而已:渲染器不再拥有指标定义。但若选择 KLineCharts,仍需把已有标注转换成它需要的绘制调用。
MQL5 允许计算缓冲区和不绘制指标,因而并非绝对耦合。独立架构的差别是把“何时、在哪里、用什么画”从指标定义中显式拿出来。

答案是:**默认的终端使用方式更紧密,但不是绝对绑死。**MQL5 自定义指标在同一程序中通过 OnCalculate 写 buffer;标为 INDICATOR_DATA 的 buffer 可映射到 DRAW_LINEDRAW_CANDLES 等终端绘制类型。它也可以使用 INDICATOR_CALCULATIONSDRAW_NONE 或普通数组,只计算而不直接画图 MQL5 文档

在独立架构中,Nautilus 或 LEAN 指标本身通常不自带浏览器图形。策略先产出带时间、价格、区间和状态的指标值或标注记录,再由 KLineCharts、Plotly、报告或告警模块选择如何消费。若选 KLineCharts,当然仍需调用它的绘制 API;本质差异不在“是否要调用画图组件”,而在渲染器不会反过来定义指标计算和业务语义。

对 Giles SMC 这类源码,较稳妥的拆分是:识别 swing、FVG、OB 的计算逻辑先输出可验证的记录;MT5 buffer 或浏览器矩形只是这些记录的不同呈现方式。这样同一条 FVG 既能画在图上,也能被研究统计或风控规则读取。