🧩
用标准库类在图表上创建自定义市场报价面板
图形对象标准库面板
用标准库类做自定义文本表
MQL5 标准库提供了 CObject / CChartObject / CList 等基类,可快速搭出图表上的自定义信息面板。文章的目标是在图表上动态显示一组品种的买/卖价、涨跌色,替代或补充自带 Market Watch。核心是 TableDisplay 类继承 CList,把所有文本图形对象作为链表管理,支持添加/插入/删除/清空。
面板结构与对象管理
- CChartObjectLabel(OBJ_LABEL):显示文字,绑定像素坐标,滚动不移动,用于标题与字段。
- CChartObjectEdit(OBJ_EDIT):可交互输入字段,文中用作只读信息显示。
- CChartObjectText / CChartObjectButton:同系列的其他控件。
- 每个字段对象通过 AddFieldObject / AddTitleObject 加入链表,用 SetText 改文字、SetColor 改颜色。
定时器刷新机制
文中用 EventSetTimer(1) 每秒触发 OnTimer,在 OnTimer 里用 SymbolInfoTick 取买卖价,与上次价格比较决定涨跌色,再 SetText/SetColor 更新并 ChartRedraw。注意:用 OnTimer 而非 OnTick,这样不依赖报价跳动也能稳定刷新。
void OnTimer()
{
for(int i=0; i<NUMBER; i++)
{
MqlTick tick; SymbolInfoTick(names[i], tick);
if(tick.time>times[i])
{
Table1.SetText(i, DoubleToString(tick.bid, (int)SymbolInfoInteger(names[i],SYMBOL_DIGITS)));
if(tick.bid>rates[i]) Table1.SetColor(i,Lime);
else if(tick.bid<rates[i]) Table1.SetColor(i,Red);
else Table1.SetColor(i,Yellow);
rates[i]=tick.bid; times[i]=tick.time;
}
}
ChartRedraw(0);
}
唯一名与坐标网格
图表上每个图形对象必须有唯一名,否则会互相覆盖。文章用 GetTickCount 生成唯一名,并加 ObjectFind 校验避免同毫秒冲突。定位用网格步长(GetSystemMetrics 算 chart_width_step/height_step)实现分辨率无关布局,避免不同图表尺寸下重叠。
坑与注意
⚠ 面板类 EA 的常见雷
1) 对象名冲突:连续 GetTickCount 可能同毫秒,必须用静态计数+ObjectFind 校验,否则新对象覆盖旧的。2) 坐标重算:像素坐标随图表尺寸变化,要用网格步长自适应,别写死像素。3) 性能:品种多、刷新频繁时对象数量大,OnDeinit 里务必 EventKillTimer + Table1.Clear() 释放,防止内存泄漏。4) 本文未含点击下单,要下单需自己加 OnChartEvent 处理 OBJ_EVENT_CLICK。
常见问题
OnTick 只在有报价跳动时触发,若行情清淡可能几秒不刷新,面板看着像卡住。OnTimer(1) 每秒稳定触发一次,无论有没有报价都能更新买卖价与涨跌色,体验更顺畅。
MT5 的图形对象靠名字区分,同名对象会被后者覆盖或冲突。面板里每个标题、每个字段都是独立对象,必须用唯一名(如带时间戳/计数的名字)才能保证它们各显示各的、互不覆盖。
原文没有点击下单功能,只做信息展示。要加下单,需要在 OnChartEvent 里处理 OBJ_EVENT_CLICK,判断点到的是哪一行对象,再调 CTrade 下单。这属于在原文基础上的二次开发。