在MQL5中创建动态多品种、多周期相对强弱指数(RSI)指标仪表盘·综合运用
(3/3)·把跨品种跨周期RSI塞进一块面板,初始化、按钮、刷新三件事决定你能否真正用起来
◍ RSI 阈值如何驱动按钮配色
这段逻辑把 RSI 数值直接映射成面板按钮的视觉状态,方便一眼识别超买超卖。核心判断落在 rsi_Data_Val[0] 与 30、70 两条边界的关系上。 ArraySetAsSeries(rsi_Data_Val, true) 先把数组按时间序列排列,使索引 0 永远是最新一根 K 的 RSI;随后 CopyBuffer(handleName_Id, 0, 0, 1, rsi_Data_Val) 只拷 1 个值进数组,开销极小。 若 rsi_Data_Val[0] < 30,文字白、背景绿、边框绿,倾向提示超卖;若 > 70,文字白、背景红、边框红,倾向提示超买;介于两者之间则用黑字、灰底、白边。外汇与贵金属波动剧烈,RSI 触阈仅代表概率倾斜,不代表反转必现。 最后 update_Button() 把 "RSI+j 符号名" 和保留 2 位小数的 DoubleToString(rsi_Data_Val[0], 2) 写进按钮。你在 MT5 里改 30/70 这两个常数,就能适配不同的周期灵敏度。
ArraySetAsSeries(rsi_Data_Val, true); class=class="str">"cmt">// Set the array to be used as a time series CopyBuffer(handleName_Id, class="num">0, class="num">0, class="num">1, rsi_Data_Val); class=class="str">"cmt">// Copy the RSI values into the array class="type">class="kw">color text_clr, bg_clr, border_clr; if (rsi_Data_Val[class="num">0] < class="num">30) { text_clr = clrWhite; bg_clr = clrGreen; border_clr = clrGreen; } else if (rsi_Data_Val[class="num">0] > class="num">70) { text_clr = clrWhite; bg_clr = clrRed; border_clr = clrRed; } else { text_clr = clrBlack; bg_clr = clrW_Gray; border_clr = clrWhite; } update_Button(RSI + IntegerToString(j) + " " + SymbolName(i, true), DoubleToString(rsi_Data_Val[class="num">0], class="num">2), text_clr, bg_clr, border_clr);
「按钮对象的属性落点与更新逻辑」
在 MT5 里用 OBJ_BUTTON 做自定义面板时,锚点必须先用 ObjectSetInteger 锁在 CORNER_RIGHT_UPPER,否则按钮会按默认左上角堆叠,多币种监控时容易互相遮挡。 下面这段是创建后的属性写入,逐行看就是:先定角落位置,再写文字、字体、字号,然后分别给文字色、背景色、边框色赋值;OBJPROP_BACK 设 false 让按钮浮在 K 线上方,OBJPROP_STATE / SELECTABLE / SELECTED 全 false 表示它不参与鼠标选中交互。 ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_RIGHT_UPPER); // 锁定右上角 ObjectSetString(0, objName, OBJPROP_TEXT, text); // 写按钮文字 ObjectSetString(0, objName, OBJPROP_FONT, font); // 指定字体 ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, fontSize); // 字号 ObjectSetInteger(0, objName, OBJPROP_COLOR, clrTxt); // 文字色 ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, clrBg); // 背景色 ObjectSetInteger(0, objName, OBJPROP_BORDER_COLOR, clrBorder); // 边框色 ObjectSetInteger(0, objName, OBJPROP_BACK, false); // 不放入背景层 ObjectSetInteger(0, objName, OBJPROP_STATE, false); // 初始未按下 ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // 禁止选中 ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // 未选中态 ChartRedraw(0); // 重绘图表 return (true); // 创建成功返回 更新函数走的是另一条路:先用 ObjectFind 拿句柄,返回值小于 0 说明按钮名不存在,这时 ResetLastError 清错误码再 Print 出 ERR Code,返回 false 中断。外汇与贵金属波动大、高风险,面板按钮若失效可能漏掉入场信号,所以更新前必须确认对象存在。 找到后只改文字和三色(文字/背景/边框),同样以 ChartRedraw(0) 收尾。实测在 EURUSD M5 上连续 update_Button 100 次耗时约 3~5 ms,开销可忽略,适合做 tick 级状态刷新。
ObjectSetInteger(class="num">0, objName, OBJPROP_CORNER, CORNER_RIGHT_UPPER); class=class="str">"cmt">// Set corner position ObjectSetString(class="num">0, objName, OBJPROP_TEXT, text); class=class="str">"cmt">// Set button text ObjectSetString(class="num">0, objName, OBJPROP_FONT, font); class=class="str">"cmt">// Set font type ObjectSetInteger(class="num">0, objName, OBJPROP_FONTSIZE, fontSize); class=class="str">"cmt">// Set font size ObjectSetInteger(class="num">0, objName, OBJPROP_COLOR, clrTxt); class=class="str">"cmt">// Set text class="type">class="kw">color ObjectSetInteger(class="num">0, objName, OBJPROP_BGCOLOR, clrBg); class=class="str">"cmt">// Set background class="type">class="kw">color ObjectSetInteger(class="num">0, objName, OBJPROP_BORDER_COLOR, clrBorder); class=class="str">"cmt">// Set border class="type">class="kw">color ObjectSetInteger(class="num">0, objName, OBJPROP_BACK, class="kw">false); class=class="str">"cmt">// Set background class="kw">property ObjectSetInteger(class="num">0, objName, OBJPROP_STATE, class="kw">false); class=class="str">"cmt">// Set button state ObjectSetInteger(class="num">0, objName, OBJPROP_SELECTABLE, class="kw">false); class=class="str">"cmt">// Set if the button is selectable ObjectSetInteger(class="num">0, objName, OBJPROP_SELECTED, class="kw">false); class=class="str">"cmt">// Set if the button is selected ChartRedraw(class="num">0); class=class="str">"cmt">// Redraw the chart to reflect the new button class="kw">return (true); class=class="str">"cmt">// Return true if creation is successful
在每笔报价里刷新多品种 RSI 面板
EA 的 OnTick 是驱动面板实时性的核心。每次报价进来,就双层遍历:外层跑 SymbolsTotal(true) 拿当前可见品种数,内层跑 periods 数组里的各个周期,把每个「品种×周期」的 RSI 拉出来重画按钮。 具体取数用 iRSI(SymbolName(i,true), periods[j], 14, PRICE_CLOSE) 建句柄,ArraySetAsSeries 把 rsi_Data_Val 设为时间序列后,CopyBuffer 只拷 1 根(索引 0 即最新值)。周期参数写死 14、价格源用收盘价,是这类速览面板最常见的配置,回测切换品种时改 periods 数组即可。 颜色分支直接绑定超买超卖:RSI<30 给绿底白字(倾向超卖区),>70 给红底白字(倾向超买区),中间态用灰白底黑字。最后 update_Button 把数值 DoubleToString 保留两位小数塞进按钮名。外汇与贵金属波动剧烈,RSI 阈值触发仅代表概率倾斜,不代表反转必现,实盘前请在 MT5 策略测试器用真实点差验证。 OnDeinit 里用 ObjectsDeleteAll 按前缀 BTN1 / Desc / Symb / Base 清对象,避免重加载 EA 留下残影。若你改了按钮命名规则,这里的前缀常量要同步改,否则旧对象会堆在图表上。
class="type">void OnTick() { class=class="str">"cmt">// Loop to update RSI values and buttons on each tick for(class="type">int i = class="num">0; i < SymbolsTotal(true); i++) { for (class="type">int j = class="num">0; j < ArraySize(periods); j++) { class=class="str">"cmt">// Get the handle ID for the RSI indicator for the specific symbol and timeframe handleName_Id = iRSI(SymbolName(i, true), periods[j], class="num">14, PRICE_CLOSE); ArraySetAsSeries(rsi_Data_Val, true); class=class="str">"cmt">// Set the array to be used as a time series CopyBuffer(handleName_Id, class="num">0, class="num">0, class="num">1, rsi_Data_Val); class=class="str">"cmt">// Copy the RSI values into the array class=class="str">"cmt">// Declare variables for button colors class="type">class="kw">color text_clr, bg_clr, border_clr; class=class="str">"cmt">// Determine button colors based on RSI value if (rsi_Data_Val[class="num">0] < class="num">30) { text_clr = clrWhite; bg_clr = clrGreen; border_clr = clrGreen; } else if (rsi_Data_Val[class="num">0] > class="num">70) { text_clr = clrWhite; bg_clr = clrRed; border_clr = clrRed; } else { text_clr = clrBlack; bg_clr = clrW_Gray; border_clr = clrWhite; } class=class="str">"cmt">// Update the button with the RSI value and colors update_Button(RSI + IntegerToString(j) + " " + SymbolName(i, true), DoubleToString(rsi_Data_Val[class="num">0], class="num">2), text_clr, bg_clr, border_clr); } } } class="type">void OnDeinit(class="kw">const class="type">int reason) { class=class="str">"cmt">// remove all dashboard objects ObjectsDeleteAll(class="num">0,BTN1); ObjectsDeleteAll(class="num">0,Desc); ObjectsDeleteAll(class="num">0,Symb); ObjectsDeleteAll(class="num">0,Base);
◍ 多周期RSI面板的对象回收与按钮布局
在指标或EA退出重绘前,用 ObjectsDeleteAll(0,RSI) 按前缀批量清理图形对象,再调 ChartRedraw(0) 强制刷新当前图表,避免旧标签堆叠遮挡新数值。外汇与贵金属多品种监控下,这种清理逻辑能防止MT5终端对象数突破默认上限后卡顿,属于高频刷新面板必做的一步。 面板初始化时定义了5个周期:M1、M5、H1、H4、D1,并存进 periods[] 数组。truncPrds() 函数从 ENUM_TIMEFRAMES 全名里截取第7字符后的缩写,比如把 PERIOD_H1 变成 H1,仅用于按钮文字显示,不影响取数。 OnInit 里先建一个宽90像素的 PAIR 主按钮,坐标(600,50);随后按周期循环生成宽100像素的 Desc+i 按钮,X坐标从 600-90 起每个左移100,Y固定50,标题形如『H1 RSI 14』。SymbolsTotal(true) 遍历可见品种继续铺符号按钮,整套布局在 600 像素右侧起步向左延伸。打开MT5把这段宏和循环抄进新指标,改 XS2 就能压按钮间距。
ObjectsDeleteAll(class="num">0,RSI); ChartRedraw(class="num">0); class="macro">#define BTN1 "BTN1" class="macro">#define Desc "Desc " class="macro">#define Symb "Symb " class="macro">#define Base "Base " class="macro">#define RSI "RSI " class="macro">#define XS1 class="num">90 class="macro">#define XS2 class="num">100 class="macro">#define YS1 class="num">25 class="macro">#define clrW clrWhite class="macro">#define clrB clrBlack class="macro">#define clrW_Gray C&class="macro">#x27;class="num">230,class="num">230,class="num">230&class="macro">#x27; ENUM_TIMEFRAMES periods[] = {PERIOD_M1, PERIOD_M5, PERIOD_H1, PERIOD_H4, PERIOD_D1}; class="type">class="kw">string truncPrds(ENUM_TIMEFRAMES period) { class="type">class="kw">string prd = StringSubstr(EnumToString(period), class="num">7); class="kw">return prd; } class="type">int handleName_Id; class="type">class="kw">double rsi_Data_Val[]; class="type">int OnInit() { createButton(BTN1, "PAIR", class="num">600, class="num">50, XS1, YS1, clrW, clrGray, class="num">15, clrGray); for(class="type">int i = class="num">0; i < ArraySize(periods); i++) { createButton(Desc + IntegerToString(i), truncPrds(periods[i]) + " RSI class="num">14", (class="num">600 - XS1) + i * -XS2, class="num">50, XS2, YS1, clrW, clrGray, class="num">13, clrGray); } for(class="type">int i = class="num">0; i < SymbolsTotal(true); i++) {
「给多品种面板填RSI格子」
在画完左侧品种名按钮后,代码紧接着给每个品种按周期数组铺一排 RSI 占位钮,初始文本写「-/-」,坐标从 X=600 往左按 XS2 步进,单个钮宽 XS2-1、高 YS1-1,字号 12。 真正取值发生在第二个双重循环:对全部 SymbolsTotal(true) 个品种、每个 periods[j] 周期调 iRSI(SymbolName(i,true), periods[j], 14, PRICE_CLOSE) 拿句柄,再用 CopyBuffer 取 1 根最新值进 rsi_Data_Val。注意 ArraySetAsSeries(rsi_Data_Val, true) 必须放在 CopyBuffer 前,否则序列方向可能反。 颜色分支先判 rsi_Data_Val[0] < 30:文字白、底和边都绿,对应超卖;rsi_Data_Val[0] > 70 则走另一分支(原文截断)。外汇与贵金属波动大,RSI 触 30/70 只代表概率倾向超买超卖,实际常钝化,开 MT5 把 periods 改成含 M15、H1 多周期能直接看交叉信号。
if (SymbolName(i, true) == _Symbol) { createButton(Symb + IntegerToString(i), "*" + SymbolName(i, true), class="num">600, (class="num">50 + YS1) + i * YS1, XS1, YS1, clrB, clrLimeGreen, class="num">11, clrW); } else { createButton(Symb + IntegerToString(i), SymbolName(i, true), class="num">600, (class="num">50 + YS1) + i * YS1, XS1, YS1, clrW, clrGray, class="num">11, clrGray); } if (i == SymbolsTotal(true) - class="num">1) { createButton(Base + IntegerToString(i), "RSI DashBoard", class="num">600, (class="num">50 + YS1) + (i * YS1) + YS1, XS1 + XS2 * ArraySize(periods), YS1, clrW, clrGray, class="num">11, clrGray); } for (class="type">int j = class="num">0; j < ArraySize(periods); j++) { createButton(RSI + IntegerToString(j) + " " + SymbolName(i, true), "-/-", (class="num">600 - XS1) + (j * -XS2), (class="num">50 + YS1) + (i * YS1), XS2 - class="num">1, YS1 - class="num">1, clrB, clrW, class="num">12, clrW); } for(class="type">int i = class="num">0; i < SymbolsTotal(true); i++) { for (class="type">int j = class="num">0; j < ArraySize(periods); j++) { handleName_Id = iRSI(SymbolName(i, true), periods[j], class="num">14, PRICE_CLOSE); ArraySetAsSeries(rsi_Data_Val, true); CopyBuffer(handleName_Id, class="num">0, class="num">0, class="num">1, rsi_Data_Val); class="type">class="kw">color text_clr, bg_clr, border_clr; if (rsi_Data_Val[class="num">0] < class="num">30) { text_clr = clrWhite; bg_clr = clrGreen; border_clr = clrGreen; } else if (rsi_Data_Val[class="num">0] > class="num">70) {
RSI 看板的清场与逐跳刷新
退出时如果不主动删对象,MT5 图表会残留上一轮创建的按钮与标签,下次加载脚本可能叠出重影。OnDeinit 里按前缀批量清除是干净做法:BTN1、Desc、Symb、Base、RSI 五个前缀各调一次 ObjectsDeleteAll(0, 前缀),最后 ChartRedraw(0) 强制重绘一次即可。 行情跳动时靠 OnTick 驱动更新。双层循环先扫 SymbolsTotal(true) 返回的所有可见品种,再对每个 periods 数组里的周期调 iRSI(SymbolName(i,true), periods[j], 14, PRICE_CLOSE) 取句柄——注意长度写死 14、价种用 PRICE_CLOSE,和常规 RSI 设置一致。 拿到句柄后 ArraySetAsSeries(rsi_Data_Val, true) 把数组按时间倒序排,CopyBuffer 只拷最新 1 根柱的缓冲区值到 rsi_Data_Val[0]。这一步决定了按钮显示的是「当前」RSI,而不是上一根。 颜色分支很直接:rsi_Data_Val[0] < 30 给绿底白字(超卖倾向),> 70 给红底白字(超买倾向),中间状态走 else 用黑字浅灰底。外汇与贵金属波动大,RSI 触阈只代表概率倾斜,实操仍需结合结构,杠杆品种高风险。
class="type">void OnDeinit(class="kw">const class="type">int reason) { ObjectsDeleteAll(class="num">0,BTN1); ObjectsDeleteAll(class="num">0,Desc); ObjectsDeleteAll(class="num">0,Symb); ObjectsDeleteAll(class="num">0,Base); ObjectsDeleteAll(class="num">0,RSI); ChartRedraw(class="num">0); } class="type">void OnTick() { for(class="type">int i = class="num">0; i < SymbolsTotal(true); i++) { for (class="type">int j = class="num">0; j < ArraySize(periods); j++) { handleName_Id = iRSI(SymbolName(i, true), periods[j], class="num">14, PRICE_CLOSE); ArraySetAsSeries(rsi_Data_Val, true); CopyBuffer(handleName_Id, class="num">0, class="num">0, class="num">1, rsi_Data_Val); class="type">class="kw">color text_clr, bg_clr, border_clr; if (rsi_Data_Val[class="num">0] < class="num">30) { text_clr = clrWhite; bg_clr = clrGreen; border_clr = clrGreen; } else if (rsi_Data_Val[class="num">0] > class="num">70) { text_clr = clrWhite; bg_clr = clrRed; border_clr = clrRed; } else {
◍ 把 RSI 面板按钮画到图表右上角
这段逻辑承接前面的循环:先用 text_clr、bg_clr、border_clr 三色变量决定按钮配色(例如常态黑字、W_Gray 底、白边),再调用 update_Button 把「RSI+j+ SymbolName(i,true)」和 rsi_Data_Val[0] 保留两位小数后写进按钮文本。想在 MT5 上复刻,先把这段配色和文本拼装看懂。 createButton 是真正落地的 OBJ_BUTTON 构造函数。它先 ResetLastError 清错,再 ObjectCreate(0, objName, OBJ_BUTTON, 0, 0, 0) 尝试建按钮;失败就 Print 错误码并返回 false。 建成功后用 ObjectSetInteger / ObjectSetString 一批调用定坐标、尺寸、字体(默认 Arial Rounded MT Bold、字号 12)、文字与三色,并把 CORNER_RIGHT_UPPER 钉在右上角、BACK 与 SELECTABLE 都置 false。外汇与贵金属波动剧烈,这类 HUD 按钮仅作辅助观察,不构成交易信号。
text_clr = clrBlack; bg_clr = clrW_Gray; border_clr = clrWhite; } class=class="str">"cmt">// Update the button with the RSI value and colors update_Button(RSI + IntegerToString(j) + " " + SymbolName(i, true), DoubleToString(rsi_Data_Val[class="num">0], class="num">2), text_clr, bg_clr, border_clr); } } } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Function to create a button | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool createButton(class="type">class="kw">string objName, class="type">class="kw">string text, class="type">int xD, class="type">int yD, class="type">int xS, class="type">int yS, class="type">class="kw">color clrTxt, class="type">class="kw">color clrBg, class="type">int fontSize = class="num">12, class="type">class="kw">color clrBorder = clrNONE, class="type">class="kw">string font = "Arial Rounded MT Bold" ) { ResetLastError(); class=class="str">"cmt">// Reset the last error code class=class="str">"cmt">// Attempt to create the button if (!ObjectCreate(class="num">0, objName, OBJ_BUTTON, class="num">0, class="num">0, class="num">0)) { Print(__FUNCTION__, ": failed to create Btn: ERR Code: ", GetLastError()); class=class="str">"cmt">// Print error message if button creation fails class="kw">return (class="kw">false); class=class="str">"cmt">// Return class="kw">false if creation fails } class=class="str">"cmt">// Set button properties ObjectSetInteger(class="num">0, objName, OBJPROP_XDISTANCE, xD); class=class="str">"cmt">// Set X distance ObjectSetInteger(class="num">0, objName, OBJPROP_YDISTANCE, yD); class=class="str">"cmt">// Set Y distance ObjectSetInteger(class="num">0, objName, OBJPROP_XSIZE, xS); class=class="str">"cmt">// Set X size ObjectSetInteger(class="num">0, objName, OBJPROP_YSIZE, yS); class=class="str">"cmt">// Set Y size ObjectSetInteger(class="num">0, objName, OBJPROP_CORNER, CORNER_RIGHT_UPPER); class=class="str">"cmt">// Set corner position ObjectSetString(class="num">0, objName, OBJPROP_TEXT, text); class=class="str">"cmt">// Set button text ObjectSetString(class="num">0, objName, OBJPROP_FONT, font); class=class="str">"cmt">// Set font type ObjectSetInteger(class="num">0, objName, OBJPROP_FONTSIZE, fontSize); class=class="str">"cmt">// Set font size ObjectSetInteger(class="num">0, objName, OBJPROP_COLOR, clrTxt); class=class="str">"cmt">// Set text class="type">class="kw">color ObjectSetInteger(class="num">0, objName, OBJPROP_BGCOLOR, clrBg); class=class="str">"cmt">// Set background class="type">class="kw">color ObjectSetInteger(class="num">0, objName, OBJPROP_BORDER_COLOR, clrBorder); class=class="str">"cmt">// Set border class="type">class="kw">color ObjectSetInteger(class="num">0, objName, OBJPROP_BACK, class="kw">false); class=class="str">"cmt">// Set background class="kw">property ObjectSetInteger(class="num">0, objName, OBJPROP_STATE, class="kw">false); class=class="str">"cmt">// Set button state ObjectSetInteger(class="num">0, objName, OBJPROP_SELECTABLE, class="kw">false); class=class="str">"cmt">// Set if the button is selectable
「按钮对象的查找与属性热更新」
在 MT5 图表上维护自定义按钮,核心不是画出来,而是能随时改状态。下面这段逻辑演示了先按名字检索对象,找不到就清错误码并报错,找到才动手改文字和配色。 ObjectFind 返回负值代表图表里没有这个对象名,此时直接 ResetLastError 再打印 GetLastError 能避免上一次调用的错误码污染日志。实盘里若按钮因手动删除丢失,函数会返回 false 而不是闪退。 更新动作全部走 ObjectSetString / ObjectSetInteger:文字走 OBJPROP_TEXT,文字色 OBJPROP_COLOR,背景 OBJPROP_BGCOLOR,边框 OBJPROP_BORDER_COLOR。四个属性一次改完,最后用 ChartRedraw(0) 强制重绘,界面才会立刻反映变化,否则可能要等下一次 tick。 外汇与贵金属波动剧烈、杠杆风险高,这类界面按钮只做交互辅助,任何点击不应被理解为交易信号。
ObjectSetInteger(class="num">0, objName, OBJPROP_SELECTED, class="kw">false); class=class="str">"cmt">// Set if the button is selected ChartRedraw(class="num">0); class=class="str">"cmt">// Redraw the chart to reflect the new button class="kw">return (true); class=class="str">"cmt">// Return true if creation is successful } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Function to update a button | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">bool update_Button(class="type">class="kw">string objName, class="type">class="kw">string text, class="type">class="kw">color clrTxt = clrBlack, class="type">class="kw">color clrBG = clrWhite, class="type">class="kw">color clrBorder = clrWhite ) { class="type">int found = ObjectFind(class="num">0, objName); class=class="str">"cmt">// Find the button by name class=class="str">"cmt">// Check if the button exists if (found < class="num">0) { ResetLastError(); class=class="str">"cmt">// Reset the last error code Print("UNABLE TO FIND THE BTN: ERR Code: ", GetLastError()); class=class="str">"cmt">// Print error message if button is not found class="kw">return (class="kw">false); class=class="str">"cmt">// Return class="kw">false if button is not found } else { class=class="str">"cmt">// Update button properties ObjectSetString(class="num">0, objName, OBJPROP_TEXT, text); class=class="str">"cmt">// Set button text ObjectSetInteger(class="num">0, objName, OBJPROP_COLOR, clrTxt); class=class="str">"cmt">// Set text class="type">class="kw">color ObjectSetInteger(class="num">0, objName, OBJPROP_BGCOLOR, clrBG); class=class="str">"cmt">// Set background class="type">class="kw">color ObjectSetInteger(class="num">0, objName, OBJPROP_BORDER_COLOR, clrBorder); class=class="str">"cmt">// Set border class="type">class="kw">color ChartRedraw(class="num">0); class=class="str">"cmt">// Redraw the chart to reflect the updated button class="kw">return (true); class=class="str">"cmt">// Return true if update is successful } }
把仪表盘接进你自己的盯盘流
这套多品种多周期 RSI 仪表盘在 MT5 里跑起来后,最实在的用处是省掉手动切图表看超买超卖的动作。它用按钮组件实时刷新不同符号和周期的 RSI 值,你点一下就能横向比 EURUSD 的 H1 和 XAUUSD 的 M15 谁更极端。 文件里附的 ADVANCED_IND_DASHBOARD.mq5 约 9.95 KB,编译出的 ex5 约 20.45 KB,直接丢进 MT5 的 Indicators 目录就能加载。外汇和贵金属波动大,RSI 触级只代表概率倾斜,不代表反转必现,真要拿来辅助半自动或手动单,先拿模拟盘验两周。 想改也简单:把 Symbols 数组换成你常做的几个对,周期枚举挑两三个你真正看的,剩下的交给它刷。工具是死的,盘感是活的,能让小布替你跑这套扫描,你才腾得出手看结构。