首页 / 交易学院 / 一个面板看遍多周期多品种:用 OOP 搭通用 MT5 观察面板
一个面板看遍多周期多品种:用 OOP 搭通用 MT5 观察面板
🖥️

一个面板看遍多周期多品种:用 OOP 搭通用 MT5 观察面板

EA 开发实战 难度 · 高级 2011 15 分钟阅读
多周期多货币观察面板SpyAgentCTable面向对象 GUI

交易时你常想同时看:当前品种在不同周期下的 RSI、或当前周期下多个货币对的时价与涨跌。MT5 自带的“市场报价”窗口很弱,无法满足“自定义条件行”的需求。本文给出一个面向对象方案:建一个通用面板,既能多时间表模式(同品种、不同周期),也能多货币模式(同周期、不同品种),而且增删显示内容几乎不碰面板本体代码。

一、两种工作模式与设计目标

面板支持两种模式。多时间表模式:基于当前交易品种、但切到不同时间表计算每一行(比如同时看 M1/M5/H1 的 RSI)。多货币模式:基于当前时间表、但切到不同交易品种算每一行(比如同时看 EURUSD/GBPUSD/USDJPY 的时价)。设计目标是“通用”——不管你想加价格、指标值还是自定义买卖条件,面板核心代码都不用改,只写一个小类描述“这一行显示什么”。

二、类图:CTable、CRow 与 SpyAgent 的分工

核心由三个角色构成。CTable 是面板主体,负责在图表上画图、管理所有行对象。CRow 是“一行显示内容”的基类,所有具体行都从它派生。SpyAgent 是一个特殊指标,只在多货币模式下用——它被派到其它交易品种图表上“监听”,一旦那些品种有新报价,就发事件通知 CTable 刷新。三者各司其职,是典型的高内聚设计。

三、具体行类:从 CRow 派生的四种示例

作者给出四个示例派生类,展示“一行能显示什么”。CPriceRow 显示当前买价;CPriceChangeRow 显示当前柱的价格变化,可切换为数值、百分比或上下箭头;CRSIRow 显示指定周期的 RSI 值;CPriceMARow 显示一个自定义条件,比如“SMA(20) 是否大于时价”。关键点是:这四个只是样例,你完全可以从 CRow 派生自己的类,显示任意指标或逻辑——面板不因新行而改代码。

四、CTable 的两种构造函数

CTable 提供两个构造函数对应两种模式。多时间表构造函数收一个时间周期数组,内部把 symbols 数组全部填成当前品种,再把 tfMode 置真。多货币构造函数收一个品种数组,把 timeframes 全部填成当前周期,tfMode 置假,并给每个“非当前品种”发一个 SpyAgent 指标去监听。两种构造都先调 Init() 设默认外观参数(字体、单元格宽高、颜色)。

// 多时间帧模式构造函数(节选)
CTable::CTable(ENUM_TIMEFRAMES &tfs[])
  {
   ArrayResize(timeframes, ArraySize(tfs));
   ArrayCopy(timeframes, tfs);
   tfMode = true;                       // 标记为多时间表模式
   ArrayResize(symbols, ArraySize(tfs));
   for(int i=0; i<ArraySize(tfs); i++)
      symbols[i] = Symbol();            // 所有行都用当前品种
   Init();                              // 设置字体/单元格等默认参数
  }

五、SpyAgent 与跨图表事件通知

多货币模式下,其它品种的图表在自己 OnCalculate 时不会自动告诉当前面板。SpyAgent 指标就是桥梁:它被 iCustom 挂到每个目标品种上,当那个品种有新报价(新订单号)时,发一个 CHARTEVENT_CUSTOM 类型事件给 CTable 所在的图表。CTable 在自己 OnChartEvent 里接收事件后,只刷新对应那一行,不重画整表,效率很高。这是 MT5 多图表协同的经典套路。

性能提示:SpyAgent 只在“有新订单号”时才发事件,CTable 收到后只更新受影响的行对象,避免每 tick 全表重绘。如果你面板行很多,这种“事件驱动 + 局部刷新”比轮询所有品种救命得多。

六、添加一行与重画:AddRow / Update

往面板加内容只需一句 AddRow(new CPriceRow(...)),它会把行对象加进 CList、并调用该行的 Init(symbols, timeframes) 完成初始化。真正把内容画到图表上的是 Update():它先按模式决定列数(tfMode 用 timeframes 长度,否则用 symbols 长度),再逐行取每行的名称与数值,用 DrawLabel 把文字标签画到对应单元格。析构时 CTable 会遍历删掉所有以 nameBase 为前缀的对象,避免图表残留。

七、小结

这个面板示范了 OOP 在 MT5 GUI 上的威力:CTable 管绘制、CRow 管“每行显示什么”、SpyAgent 管跨品种监听,三者解耦。你要扩展功能,不是改面板,而是从 CRow 派生一个新类——加一行价格、一行自定义条件都只是一行 AddRow 的事。把它作为“自定义监控面板”的骨架,比每次手写几十个 OBJ_LABEL 清爽且可维护得多。

常见问题

多时间表模式:固定当前交易品种,切不同时间周期计算每行(如同时看 M1/M5/H1 的 RSI);多货币模式:固定当前周期,切不同交易品种算每行(如同时看 EURUSD/GBPUSD 的时价)。前者用时间周期数组构造,后者用品种数组构造。
它是多货币模式下的监听指标,被 iCustom 挂到每个目标品种图表上。当那些品种出现新报价(新订单号)时,发 CHARTEVENT_CUSTOM 事件给 CTable 所在图表,触发局部刷新。没有它,其它品种的更新不会自动通知当前面板。
不用。只要从 CRow 派生一个新类(定义这一行显示什么,比如某个指标值或自定义条件),然后 AddRow(new 你的类) 即可。CTable 本体代码完全不动,这正是 OOP 解耦的价值。
不会。SpyAgent 只在“有新订单号”时发事件,CTable 收到后只更新受影响的行对象,不每 tick 全表重绘。这种“事件驱动 + 局部刷新”对多行面板很关键,比轮询所有品种高效得多。
CPriceRow 显示当前买价;CPriceChangeRow 显示当前柱价格变化(可切换数值/百分比/箭头);CRSIRow 显示指定周期 RSI 值;CPriceMARow 显示一个自定义条件如“SMA(20) 是否大于时价”。它们只是样例,你可从 CRow 派生任意自定义行。