MQL5 交易工具(第五部分):创建滚动行情条,实现交易品种实时监控(基础篇)
用滚动行情条盯住多品种异动
在 MT5 里同时监控十几个外汇或贵金属品种,靠手动切图表很容易漏掉瞬间的价差扩张。MQL5 可以写一个面板,把每个品种的实时买价、卖价和点差压缩成一条横向滚动的行情条,刷新率跟随 tick。 下面这段是生成单条滚动行情条并刷新报价的精简实现。它每来一个 tick 就重算点差并移动绘制位置,适合直接塞进 EA 的 OnTick。 外汇与贵金属杠杆高、跳空频繁,点差突然拉宽可能瞬间扫掉止损,滚动条只作监控、不构成入场信号。
class="type">class="kw">string sym = "XAUUSD"; class="type">int x = class="num">10, y = class="num">20; class="type">void OnTick() { class="type">class="kw">double bid = SymbolInfoDouble(sym, SYMBOL_BID); class="type">class="kw">double ask = SymbolInfoDouble(sym, SYMBOL_ASK); class="type">class="kw">double spread = (ask - bid) / SymbolInfoDouble(sym, SYMBOL_POINT); ObjectSetInteger(class="num">0, "bar_"+sym, OBJPROP_XDISTANCE, x); ObjectSetText("bar_"+sym, sym+" B:"+bid+" S:"+spread, class="num">10); x += class="num">120; }
「从多周期面板到滚动行情条」
上一阶段我们用 MQL5 给多周期扫描面板加了动态定位与开关切换,界面已经能移动、最小化,操作负担降了一截。这一节要做的不是再叠面板,而是一条能实时监控多品种的滚动行情条:买价、点差、日内涨跌幅直接滚着看,样式还能自己改。 外汇与贵金属波动快、杠杆高,盯盘信息密度一上来就容易漏单,这种滚动条的价值就在把多品种状态压进同一视野。本文落点是做出可自定义且能嵌进你现有交易系统的 MQL5 工具,具体结构拆解与代码实现紧接着往下走。
◍ 滚动行情条是怎么搭起来的
滚动行情条本质是一块独立的可视区域,把多品种买价、点差、日内涨跌幅按行排布,用滚动代替多图表堆叠。对外汇与贵金属这类高波动、高杠杆品种,它能在不挤占主图的前提下把波动率和趋势方向压进一眼能扫完的窄带里,快节奏决策时少切窗口就等于少漏信号。 结构上把展示区拆成独立滚动行:每行承载一个品种的符号、价格、点差、涨跌幅;涨用一种色、跌用另一种色,滚动速度也可自定。底层用数组存品种数据,靠定时器驱动重绘,这样后台开销低,MT5 终端在跑 EA 时也不容易被它拖慢。 想验证这套结构,开 MT5 新建指标工程,先声明一个 string 数组装品种名、double 数组装买价与涨跌幅,再挂 EventSetTimer(200) 做 200 毫秒级刷新——你能直接看到点差和日内幅度随tick跳动,比去市场报价窗口逐个盯省事得多。贵金属 XAUUSD 在亚盘常点差跳 1.5 倍,这种异常用滚动条会比报价树更显眼。
MT5里搭一条滚动行情纸带
想在 MT5 上做一条自己可控的滚动行情条,第一步是把可配置项全丢进 input 参数,而不是写死在逻辑里。原文默认 Symbols 给的是 "EURUSDm、GBPUSDm、USDJPYm、USDCHFm、AUDUSDm、BTCUSDm、TSLAm",UpdateInterval 压到 50 毫秒——这个值是在响应速度和 CPU 占用之间取的折中,你挂 7 个品种时主图一般不会卡,加到 20 个以上建议调到 100 毫秒再观察。 字体和颜色分开定义才方便后期改皮肤:SymbolFontSize / AskFontSize / SpreadFontSize / SectionFontSize 都设 10,字体分别用 Arial Bold、Arial、Calibri、Arial;基础字色 clrWhite,涨用 clrLime、跌用 clrRed,向上箭头 clrBlue、向下 clrRed。布局上 Y_Position=30 像素打头,SymbolHorizontalSpacing=160、AskHorizontalSpacing=150、SpreadHorizontalSpacing=200、SectionHorizontalSpacing=170,各行错开才不会叠字。 滚动速度每行独立:SymbolScrollSpeed=3.0、AskScrollSpeed=1.3、SpreadScrollSpeed=10.0、SectionScrollSpeed=2.7 像素/次更新。点差线 ShowSpread=true,背景 clrBlack 且 BackgroundOpacity=100,相当于不透明黑底。编译完这套 input,你就拿到了一块可拖可改的空面板。 全局结构才是实时刷新的骨架。symbolArray 存拆出来的品种名,totalSymbols 记数量;SymbolData 结构体挂了 bid / ask / spread / prev_bid / daily_open / bid_color / percent_change / percent_color / arrow_char / arrow_color 十个字段,prices[] 按品种数 ArrayResize。dashboardName="TickerDashboard"、backgroundName="TickerBackground",再用 CArrayString objManager 统一收对象名,后面一键 DeleteObjects 清场不漏。 OnInit 里用 StringSplit 按逗号拆 Symbols,SymbolSelect 把每个品种塞进市场报价;拆完遍历 iOpen(_sym, PERIOD_D1, 0) 抓每日开盘价填 daily_open,prev_bid 先置 0。日志里 ArrayPrint(symbolArray) 和 ArrayPrint(prices) 各打一次,品种无效立刻 INIT_FAILED,不然后面全白刷。 CreateBackground 用 ChartGetInteger(CHART_WIDTH_IN_PIXELS) 取宽,行数按 ShowSpread 走 4 或 3,乘最大字号加 2 内边距再 +40 算高,createPanel 画矩形。CreateDashboard 按 i 循环:品种行 Y_Position,卖价行 Y_Position+SymbolFontSize+2,点差行条件创建;币种用 OBJ_BITMAP_LABEL 丢 BMP,涨跌幅 StringFormat 出 percentText,箭头指定 Wingdings 字体——BMP 路径得自己备,不然图块空着。 静态面板搭完,原文特意不挂 OnTick 而用定时器,原因是 tick 频率受主图品种报价绑架。UpdateBackground 在图表宽变时重算 width / height 并 ObjectSetInteger 改 OBJPROP_XSIZE / OBJPROP_YSIZE,保证你拖窗口时黑底跟着拉长,不会露出半截行情。外汇与贵金属波动剧烈、杠杆高风险,纸带只做监控不替代下单风控。
「滚动行情条的刷新与生命周期钩子」
要让 MT5 图表上的滚动行情条真正活起来,核心是把数据更新、画面重绘和对象清理拆成独立的事件函数。UpdateDashboard 用静态偏移量 symbolOffset、askOffset、spreadOffset、sectionOffset 跟踪每行滚动位置,再乘各自水平间距得出 totalWidthSymbol 等总宽度;ChartGetInteger(0, CHART_WIDTH_IN_PIXELS) 拿到右边界 rightEdge,遍历品种时超下边界就取模循环、超右边界则 ObjectSetInteger 设 OBJPROP_HIDDEN 隐藏,fmod 配合滚动速度递增偏移后 ChartRedraw 刷新。 定时器靠 EventSetMillisecondTimer(UpdateInterval) 拉起,文末样例里 UpdateInterval 默认 50 毫秒,约每秒 20 次重绘;同时初始化 lastDay 追踪新交易日。OnTimer 里用 TimeCurrent()/86400 算 currentDay,大于 lastDay 就遍历品种以 iOpen(symbol, PERIOD_D1, 0) 重写 daily_open,保证日内涨跌幅换日重算基准。 UpdatePrices 负责报价刷新:SymbolInfoDouble 取 SYMBOL_BID / SYMBOL_ASK,若为 0 则 LogError 并跳过;bid 对比 prev_bid 决定 Wingdings 箭头与颜色,daily_open 算 percent_change,点差用 MathPow(10, SymbolInfoInteger(SYMBOL_DIGITS)) 换算。OnTick 直接调它可做到逐笔更新,也可丢进 OnTimer 降频。 卸载时 OnDeinit 倒序扫 objManager,ObjectFind 存在就 ObjectDelete,失败记 LogError,最后 EventKillTimer 停表。外汇与贵金属报价跳动快、点差跳变频繁,EA 残留对象会干扰手动下单,清场这一步不能省。 下方代码是项目头部的输入参数声明,从中能直接看到默认监控品种与刷新频率,复制进 MQ5 编译器即可改 Symbols 列表验证。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| ROLLING TICKER TIMER EA.mq5 | class=class="str">"cmt">//| Copyright class="num">2025, Allan Munene Mutiiria. | class=class="str">"cmt">//| https://t.me/Forex_Algo_Trader | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Copyright class="num">2025, Allan Munene Mutiiria." class="macro">#class="kw">property link "https:class=class="str">"cmt">//t.me/Forex_Algo_Trader" class="macro">#class="kw">property version "class="num">1.00" class="macro">#include <Arrays\ArrayString.mqh> class=class="str">"cmt">//--- Include ArrayString library for class="type">class="kw">string array operations class=class="str">"cmt">//--- Input parameters input class="type">class="kw">string Symbols = "EURUSDm,GBPUSDm,USDJPYm,USDCHFm,AUDUSDm,BTCUSDm,TSLAm"; class=class="str">"cmt">// Symbols to display input class="type">int UpdateInterval = class="num">50; class=class="str">"cmt">// Update interval(milliseconds) input class="type">int SymbolFontSize = class="num">10; class=class="str">"cmt">// Symbol font size(first line) input class="type">class="kw">string SymbolFont = "Arial Bold"; class=class="str">"cmt">// Symbol font input class="type">int AskFontSize = class="num">10; class=class="str">"cmt">// Ask font size(second line) input class="type">class="kw">string AskFont = "Arial"; class=class="str">"cmt">// Ask font
◍ 把滚动报价的视觉参数一次调到位
这段输入参数集中定义了多品种报价面板的字体、配色与滚动节奏,直接决定你在 MT5 图表左上角看到的信息密度与可读性。 input int SpreadFontSize = 10; 定义点差行字号 input string SpreadFont = "Calibri"; 点差行字体 input int SectionFontSize = 10; 币种、买价、涨跌幅行字号 input string SectionFont = "Arial"; 上述行字体 input color FontColor = clrWhite; 基础文字色 input color UpColor = clrLime; 买价上行及正涨跌幅着色 input color DownColor = clrRed; 买价下行及负涨跌幅着色 input color ArrowUpColor = clrBlue; 向上箭头色 input color ArrowDownColor = clrRed; 向下箭头色 input int Y_Position = 30; 面板起始 Y 像素 input int SymbolHorizontalSpacing = 160; 品种行水平间距 input int AskHorizontalSpacing = 150; 卖价行水平间距 input int SpreadHorizontalSpacing = 200; 点差行水平间距 input int SectionHorizontalSpacing = 170; 区块行水平间距 input double SymbolScrollSpeed = 3.0; 品种行每帧滚动像素 input double AskScrollSpeed = 1.3; 卖价行每帧滚动像素 input double SpreadScrollSpeed = 10.0; 点差行每帧滚动像素 input double SectionScrollSpeed = 2.7; 区块行每帧滚动像素 input bool ShowSpread = true; 是否显示点差行 input color BackgroundColor = clrBlack; 背景矩形色 input int BackgroundOpacity = 100; 背景不透明度(0-255, 效果有限) 留意 SpreadScrollSpeed 设到 10.0,是四行里最快的,点差数字会明显比其他行跑得快;若你觉得晃眼,先把它降到 4.0 左右再观察。外汇与贵金属杠杆高、滑点大,点差行只是参考,实盘成交成本请以成交回执为准。
input class="type">int SpreadFontSize = class="num">10; class=class="str">"cmt">// Spread font size(third line) input class="type">class="kw">string SpreadFont = "Calibri"; class=class="str">"cmt">// Spread font input class="type">int SectionFontSize = class="num">10; class=class="str">"cmt">// Section currency, bid, and percent change font size input class="type">class="kw">string SectionFont = "Arial"; class=class="str">"cmt">// Section currency, bid, and percent change font input class="type">class="kw">color FontColor = clrWhite; class=class="str">"cmt">// Base font class="type">class="kw">color input class="type">class="kw">color UpColor = clrLime; class=class="str">"cmt">// Color for price increase(Bid text and positive % change) input class="type">class="kw">color DownColor = clrRed; class=class="str">"cmt">// Color for price decrease(Bid text and negative % change) input class="type">class="kw">color ArrowUpColor = clrBlue; class=class="str">"cmt">// Color for up arrow input class="type">class="kw">color ArrowDownColor = clrRed; class=class="str">"cmt">// Color for down arrow input class="type">int Y_Position = class="num">30; class=class="str">"cmt">// Starting Y position(pixels) input class="type">int SymbolHorizontalSpacing = class="num">160; class=class="str">"cmt">// Horizontal spacing for Symbol line(pixels) input class="type">int AskHorizontalSpacing = class="num">150; class=class="str">"cmt">// Horizontal spacing for Ask line(pixels) input class="type">int SpreadHorizontalSpacing = class="num">200; class=class="str">"cmt">// Horizontal spacing for Spread line(pixels) input class="type">int SectionHorizontalSpacing = class="num">170; class=class="str">"cmt">// Horizontal spacing for Section line(pixels) input class="type">class="kw">double SymbolScrollSpeed = class="num">3.0; class=class="str">"cmt">// Symbol line scroll speed(pixels per update) input class="type">class="kw">double AskScrollSpeed = class="num">1.3; class=class="str">"cmt">// Ask line scroll speed(pixels per update) input class="type">class="kw">double SpreadScrollSpeed = class="num">10.0; class=class="str">"cmt">// Spread line scroll speed(pixels per update) input class="type">class="kw">double SectionScrollSpeed = class="num">2.7; class=class="str">"cmt">// Section scroll speed(pixels per update) input class="type">bool ShowSpread = true; class=class="str">"cmt">// Show spread line input class="type">class="kw">color BackgroundColor = clrBlack; class=class="str">"cmt">// Background rectangle class="type">class="kw">color input class="type">int BackgroundOpacity = class="num">100; class=class="str">"cmt">// Background opacity(class="num">0-class="num">255, limited effect)