一个面板看遍多周期多品种:用 OOP 搭通用 MT5 观察面板
交易时你常想同时看:当前品种在不同周期下的 RSI、或当前周期下多个货币对的时价与涨跌。MT5 自带的“市场报价”窗口很弱,无法满足“自定义条件行”的需求。本文给出一个面向对象方案:建一个通用面板,既能多时间表模式(同品种、不同周期),也能多货币模式(同周期、不同品种),而且增删显示内容几乎不碰面板本体代码。
一、两种工作模式与设计目标
面板支持两种模式。多时间表模式:基于当前交易品种、但切到不同时间表计算每一行(比如同时看 M1/M5/H1 的 RSI)。多货币模式:基于当前时间表、但切到不同交易品种算每一行(比如同时看 EURUSD/GBPUSD/USDJPY 的时价)。设计目标是“通用”——不管你想加价格、指标值还是自定义买卖条件,面板核心代码都不用改,只写一个小类描述“这一行显示什么”。
二、类图:CTable、CRow 与 SpyAgent 的分工
核心由三个角色构成。CTable 是面板主体,负责在图表上画图、管理所有行对象。CRow 是“一行显示内容”的基类,所有具体行都从它派生。SpyAgent 是一个特殊指标,只在多货币模式下用——它被派到其它交易品种图表上“监听”,一旦那些品种有新报价,就发事件通知 CTable 刷新。三者各司其职,是典型的高内聚设计。
- CTable:面板核心类,绘制表格并管理行对象列表(CList)
- CRow:所有行的基类,扩展它即可定义新行要显示什么
- SpyAgent:多货币模式下监听其它品种的指标,发 CHARTEVENT_CUSTOM 通知 CTable
- CPriceRow / CPriceChangeRow / CRSIRow / CPriceMARow:CRow 的四个示例派生类
三、具体行类:从 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 多图表协同的经典套路。
六、添加一行与重画: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 清爽且可维护得多。