MQL5交易工具(第六部分):带脉冲动画与控件的动态全息仪表盘(基础篇)
「给MT5面板加脉冲动画与控件」
在 MT5 里做自定义面板,很多人只画静态矩形和文字,其实用 CWndContainer 配合定时器就能做出带脉冲呼吸效果的控件。脉冲动画本质是在 OnTimer 里按帧改对象透明度或尺寸,视觉上提示某指标越过阈值。 下面这段是最小可跑骨架:建一个容器、一个按钮、一个随脉冲缩放的标签。注意 OnTimer 的周期建议设 50ms,太慢会卡顿,太快吃 CPU。外汇与贵金属波动快,这类面板只作辅助提示,信号误触发概率不低,高风险品种请谨慎依赖。
class="macro">#include <Controls/Dialog.mqh> class="macro">#include <Controls/Button.mqh> class="macro">#include <Controls/Label.mqh> CAppDialog g_dlg; CButton g_btn; CLabel g_pulse; class="type">int g_tick=class="num">0; class="type">int OnInit(){ g_dlg.Create(class="num">0,"Holo",class="num">0,class="num">100,class="num">100,class="num">300,class="num">200); g_btn.Create(class="num">0,"BTN",class="num">0,class="num">110,class="num">110,class="num">180,class="num">140); g_pulse.Create(class="num">0,"P",class="num">0,class="num">120,class="num">120,class="num">260,class="num">160); g_dlg.Add(g_btn); g_dlg.Add(g_pulse); g_dlg.Run(); EventSetTimer(class="num">50); class="kw">return(INIT_SUCCEEDED); } class="type">void OnTimer(){ g_tick++; class="type">class="kw">double s=class="num">1+class="num">0.1*sin(g_tick*class="num">0.2); g_pulse.SizeTo(class="num">160*s,class="num">40*s); }
class="macro">#include <Controls/Dialog.mqh> class="macro">#include <Controls/Button.mqh> class="macro">#include <Controls/Label.mqh> CAppDialog g_dlg; CButton g_btn; CLabel g_pulse; class="type">int g_tick=class="num">0; class="type">int OnInit(){ g_dlg.Create(class="num">0,"Holo",class="num">0,class="num">100,class="num">100,class="num">300,class="num">200); g_btn.Create(class="num">0,"BTN",class="num">0,class="num">110,class="num">110,class="num">180,class="num">140); g_pulse.Create(class="num">0,"P",class="num">0,class="num">120,class="num">120,class="num">260,class="num">160); g_dlg.Add(g_btn); g_dlg.Add(g_pulse); g_dlg.Run(); EventSetTimer(class="num">50); class="kw">return(INIT_SUCCEEDED); } class="type">void OnTimer(){ g_tick++; class="type">class="kw">double s=class="num">1+class="num">0.1*sin(g_tick*class="num">0.2); g_pulse.SizeTo(class="num">160*s,class="num">40*s); }
◍ 从滚动条到全息盘:这一篇要造什么
上一篇我们用 MQL5 搓了个滚动行情条,能实时盯单一品种的价格、点差和涨跌幅。这一篇把格局打开:做一个动态全息仪表盘,把多品种、多周期的指标一并铺开。 核心要落地的指标是两个——相对强弱指数(RSI)和基于平均真实波幅(ATR)的波动率。前者看超买超卖倾向,后者量化当前价格波动风险,对外汇和贵金属这类高杠杆品种尤其要盯着 ATR 变化。 仪表盘还会带脉冲动画、排序和交互控件,不是纯静态面板。系列里规划了架构解析、MQL5 实现、回测、结论四块,读完你大概率能在 MT5 里跑起一个可自定义的多品种监控界面,但具体效果依赖你自己的品种池和周期参数。
把多周期监控塞进一个面板
全息仪表盘不是简单堆指标,而是把多品种、多周期、RSI 与波动率这类信号收拢到同一块 UI 里,再叠排序和预警。对做价格行为的人来说,价值在于不用切图就能横向比强弱,缩短从「看到」到「验证」的路径。 架构上,数据层用数组承接,ATR、RSI 各自建指标句柄;交互层靠按钮切视图,排序函数和脉冲动画负责把异常值顶到眼前。所有刷新逻辑收进一个主循环,动态重绘 UI,这样品种数或周期变了也不用重写结构。 外汇与贵金属波动快、滑点风险高,这类面板只解决「发现机会」,不解决「该不该下手」。开 MT5 前先想清楚你要同时盯几个符号——超过 8 个还没做视图分组,循环刷新就会拖慢终端响应。
「搭一个全息仪表盘的底子」
要在 MT5 里把这套全息仪表盘跑起来,先别急着画界面,得把基础数据和输入参数定清楚。引入 <Arrays\ArrayString.mqh> 管品种列表、<Files\FileTxt.mqh> 写错误日志,输入参数里把基础字号锁在 9、字体选 Calibri、X/Y 偏移各 30 像素,面板背景深瓦灰、上涨深天蓝、下跌暗深红、网格银色,这些都能不改代码直接调。 默认开脉冲动画,面板宽 730 像素,ATR 和 RSI 周期都设 14,波动率预警阈值 2.0%,发光色道奇蓝,动画速度 30 毫秒、脉冲 3 次——这组数直接决定你眼睛看到的高亮节奏。全局数组得提前开好:prices_PrevArray 存历史价算变动,volatility_Array 存波动率,bid_array、spread_array(长整型点差)、change_array(涨跌幅%)、vol_array、rsi_array、indices(排序索引)一个不能少;periods 覆盖 PERIOD_M1 到 PERIOD_W1,日志名 Holographic_Dashboard_Log.txt,sortMode 初始 0。
| 对象管理用 CObjectManager 继承 CArrayString,AddObject 往里塞名失败就记日志;DeleteAllObjects 倒序遍历、ObjectFind 查存在再 ObjectDelete,最后 ChartRedraw 刷图。LogError 用 CFileTxt 以 FILE_WRITE | FILE_TXT | FILE_COMMON 写公共目录日志,Ask/Bid/Spread/PercentChange/TruncPeriod 都是格式化取数,取不到返 N/A,前期价为 0 时涨跌幅强制 0.00%。 |
|---|
HolographicPulse 是视觉核心:EnableAnimations 为 false 直接退,否则按 PulseCycles 跑循环,OBJPROP_COLOR 切 glowClr 主色来回、Sleep(delay) 与 Sleep(delay/2) 错开,激活元素就闪起来了。createText/createButton/createPanel/createLine 四个工厂函数都先 ResetLastError、ObjectFind 判存在再建,线条用 OBJ_RECTANGLE_LABEL 模拟,名含 Glow 的 YSIZE 设 3、ZORDER 设 -1 压底层。 InitDashboard 里 chartWidth/Height 取自 CHART_WIDTH_IN_PIXELS / CHART_HEIGHT_IN_PIXELS,fontSize 按宽比 800 缩放 BaseFontSize,panelHeight = 70 + (ArraySize(periods)+1)*18 + 40 + (totalSymbols+1)*18 + 50。画完 DashboardPanel 深底、Header 与偏移 1 像素的 HeaderGlow、SubHeader 显 _Symbol+TruncPeriod(_Period),TF 区四个标题加 Separator 与 Separator_Glow 双线,三个按钮 TOGGLE DASHBOARD / NEXT TF / SORT 定位写死,末了 ChartRedraw(0)。 OnInit 先 ObjectsDeleteAll 清图表,SymbolsTotal 赋 totalSymbols,为 0 直接 INIT_FAILED;十二个数组 ArrayResize 到品种数或周期数,prices_PrevArray 与 volatility_Array 再 ArrayInitialize 清零。外汇与贵金属波动剧烈,这类面板只做监控辅助,信号误闪概率不低,实盘前请在策略测试器或模拟盘先验一遍布局与句柄。
◍ 把多周期多品种面板跑通:初始化、回收与实时刷新
EA 启动时要先给每个时间周期和交易品种挂上 ATR、RSI 句柄。周期侧遍历 periods 数组,用 iATR(_Symbol, periods[i], ATR_Period) 和 iRSI(_Symbol, periods[i], RSI_Period, PRICE_CLOSE) 拿句柄;品种侧遍历 totalSymbols,用 SymbolName(i,true) 取 symbol 后挂 PERIOD_H1 上的同类句柄。任一返回 INVALID_HANDLE 就 LogError 并回 INIT_FAILED,否则 InitDashboard 建 UI、dashboardVisible=true、回 INIT_SUCCEEDED。 退出时必须放资源,不然 MT5 图表会留垃圾对象。OnDeinit 里先 ObjectsDeleteAll(-1) 删全部图表对象,负值就记日志;再 objManager.DeleteAllObjects() 清管理器对象。随后对 atr_handles_tf / rsi_handles_tf / atr_handles_sym / rsi_handles_sym 四个数组跑 ArraySize + IndicatorRelease,只释非 INVALID_HANDLE 的句柄。 刷新逻辑放在 OnTick:dashboardVisible 为 false 直接 return。ChartGetInteger(CHART_WIDTH_IN_PIXELS) 取宽,fontSize = chartWidth/800.0,cellWidth=PanelWidth/8,cellHeight=18,周期区 y 从 Y_Offset+75 起。每个周期用 iOpen/iClose(偏移0) 取开收,CopyBuffer 从 atr_handles_tf[i] 抄 ATR;close>0 时 vol=ATR/close*100%。rsi_handles_tf[i] 抄出 rsi,>50 标 ↑ 用 UpColor,<50 标 ↓ 用 DownColor,匹配 _Period 就 HolographicPulse 高亮,每行 y+=cellHeight。 品种区 y+=50 后遍历 totalSymbols:SymbolName(true) 取名,SymbolInfoDouble(SYMBOL_BID) 拿 bid,SymbolInfoInteger(SYMBOL_SPREAD) 拿点差,失败跳过高风险外汇/贵金属品种。iClose(PERIOD_H1) 取 close,算 change 相对 prices_PrevArray[i],vol 同前,rsi 同前,全存数组并更新 prices_PrevArray。 排序用冒泡:indices 初值 0~totalSymbols-1,sortMode 0 名称升序 / 1 波动率降序 / 2 涨跌幅绝对值降序 / 3 RSI 降序,按对应数组比较交换。显示时当前 _Symbol 加 * 并染 ActiveColor;change>0 用 UpColor,<0 下箭头染 DownColor;vol>Vol_Alert_Threshold 染 UpColor;rsi>70 染 DownColor(超买)、<30 染 UpColor(超卖)。ArrowUp 用 Wingdings 的 CharToString(236),ArrowDown 用 238。高波动对品种名调 HolographicPulse。 交互走 OnChartEvent:CHARTEVENT_OBJECT_CLICK 里 ToggleBtn 切 dashboardVisible 并重建;SwitchTFBtn 用 (currentIdx+1)%ArraySize(periods) 切 ChartSetSymbolPeriod;SortBtn 用 (sortMode+1)%4 循环并改按钮文字。编译后每次报价面板实时变,按钮能隐显、切周期、换排序。外汇/贵金属波动剧烈,句柄泄漏或排序错乱都可能让面板卡死,建议开 MT5 用 EURUSD+H1 先单品种验证再扩。
面板参数与全局数组的落地配置
这套多品种监控面板的输入参数直接决定了 MT5 图表上的可读性与告警灵敏度。BaseFontSize 默认 9、FontType 用 Calibri,是为了在 730px 宽的面板里塞下多个品种而不挤作一团;X_Offset 与 Y_Offset 均为 30,意味着面板左上角距图表边界各留 30 像素。 波动率与动量的阈值设定值得手动改:ATR_Period 和 RSI_Period 都取 14,属于日线波段常用的中性周期;Vol_Alert_Threshold 设为 2.0 表示当 ATR 测算的波动超过 2% 时才触发告警,外汇与贵金属品种在高杠杆下触发概率偏高,实盘须自行下调以控噪音。 动画类参数里 AnimationSpeed 30ms、PulseCycles 3 圈,仅影响全息脉冲观感,和信号逻辑无关。若你机器卡顿,把 EnableAnimations 设 false 即可省去重绘开销。 全局数组 prices_PrevArray、volatility_Array、bid_array 在 OnInit 之前声明,负责承接前一价、波动率序列与实时买价;它们为空时首帧不画线,属正常初始化现象,开 MT5 加载后第二根 tick 即补满。
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="macro">#include <Files\FileTxt.mqh> class=class="str">"cmt">//--- Include FileTxt library for text file operations class=class="str">"cmt">// Input Parameters input class="type">int BaseFontSize = class="num">9; class=class="str">"cmt">// Base Font Size input class="type">class="kw">string FontType = "Calibri"; class=class="str">"cmt">// Font Type(Professional) input class="type">int X_Offset = class="num">30; class=class="str">"cmt">// X Offset input class="type">int Y_Offset = class="num">30; class=class="str">"cmt">// Y Offset input class="type">class="kw">color PanelColor = clrDarkSlateGray; class=class="str">"cmt">// Panel Background Color input class="type">class="kw">color TitleColor = clrWhite; class=class="str">"cmt">// Title/Symbol Color input class="type">class="kw">color DataColor = clrLightGray; class=class="str">"cmt">// Bid/Neutral Color input class="type">class="kw">color ActiveColor = clrLime; class=class="str">"cmt">// Active Timeframe/Symbol Color input class="type">class="kw">color UpColor = clrDeepSkyBlue; class=class="str">"cmt">// Uptrend Color input class="type">class="kw">color DownColor = clrCrimson; class=class="str">"cmt">// Downtrend Color input class="type">class="kw">color LineColor = clrSilver; class=class="str">"cmt">// Grid Line Color input class="type">bool EnableAnimations = true; class=class="str">"cmt">// Enable Pulse Animations input class="type">int PanelWidth = class="num">730; class=class="str">"cmt">// Panel Width(px) input class="type">int ATR_Period = class="num">14; class=class="str">"cmt">// ATR Period for Volatility input class="type">int RSI_Period = class="num">14; class=class="str">"cmt">// RSI Period input class="type">class="kw">double Vol_Alert_Threshold = class="num">2.0; class=class="str">"cmt">// Volatility Alert Threshold(%) input class="type">class="kw">color GlowColor = clrDodgerBlue; class=class="str">"cmt">// Glow Color for holographic effect input class="type">int AnimationSpeed = class="num">30; class=class="str">"cmt">// Animation delay in ms for pulse input class="type">int PulseCycles = class="num">3; class=class="str">"cmt">// Number of pulse cycles for animations class=class="str">"cmt">// Global Variables class="type">class="kw">double prices_PrevArray[]; class=class="str">"cmt">//--- Array for previous prices class="type">class="kw">double volatility_Array[]; class=class="str">"cmt">//--- Array for volatility values class="type">class="kw">double bid_array[]; class=class="str">"cmt">//--- Array for bid prices