纯 MQL5 货币对强弱指标·综合运用
📊

纯 MQL5 货币对强弱指标·综合运用

(3/3)· 实时强弱面板写完了代码,却卡在刷新卡顿与配色失焦?本篇收口数据更新、显示优化与跨周期验证

进阶 第 3/3 篇
很多自建指标跑几天就失真,不是算法错了,而是定时器没设计好、刷新把主线程拖死。还有人把强弱极值用同一种灰阶显示,盯盘时根本分不清谁在领涨谁在掉队。把更新机制和视觉权重先定清楚,仪表盘才真正能用。

「60秒节拍器:货币强度值的定时刷新机制」

货币强度指标能不能用,先看数据鲜不鲜。核心是一条定时器逻辑:默认每 60 秒对所有货币对强度做一次全量重算与重绘,让面板始终贴近当下盘口。 刷新不是硬覆盖,而是先清旧对象再写新标签。UpdateDisplay 里用 ObjectsDeleteAll 按前缀 'SPPanel_Value_' 删掉上一轮数值,再循环前 10 个排序后的货币对,以 '%+.1f' 格式带正负号输出 H1/H4/D1 涨跌幅与综合强度,列对齐、颜色区分强弱。 定时器有两种写法。OnTimer 靠全局计数器 g_timer_counter 累加到 InpUpdateInterval 才触发;RefreshData 则用 TimeCurrent 减上次更新时间做间隔判断,并与服务器时间对齐,避免高负载账户被重复刷新拖慢。外汇与贵金属杠杆高、跳空频繁,定时间隔过短可能加大 MT5 终端负担,建议先在模拟盘验证。 别把正态当圣经:InpUpdateInterval 默认 60 只是参考值,伦敦-纽约重叠时段流动性高,可试 30 秒;亚盘冷清时拉长到 120 秒反而更稳。

MQL5 / C++
class="type">void OnTimer() {
   g_timer_counter++;
   if(g_timer_counter >= InpUpdateInterval) {
      CalculateStrengths();
      SortStrengthData();
      UpdateDisplay();
      g_timer_counter = class="num">0;
   }
}
class="type">void UpdateDisplay() {
   class=class="str">"cmt">// Remove old values
   ObjectsDeleteAll(class="num">0, "SPPanel_Value_");
   
   class=class="str">"cmt">// Update strong pairs
   for(class="type">int i = class="num">0; i < class="num">10 && i < g_pairs_count; i++) {
      class="type">class="kw">string text = StringFormat("%s  %+.1f  %+.1f  %+.1f  %+.1f",
         g_strength_data[i].pair,
         g_strength_data[i].h1_change,
         g_strength_data[i].h4_change,
         g_strength_data[i].d1_change,
         g_strength_data[i].strength);
      
      CreateLabel("SPPanel_Value_Strong_" + IntegerToString(i),
         text, class="num">30, class="num">90 + i * class="num">25, InpStrongColor);
   }
}
class="type">void RefreshData() {
   class="kw">static class="type">class="kw">datetime last_update = class="num">0;
   class="type">class="kw">datetime current_time = TimeCurrent();
   
   class=class="str">"cmt">// Check if an update is needed
   if(current_time - last_update >= InpUpdateInterval) {
      CalculateStrengths();
      SortStrengthData();
      UpdateDisplay();
      last_update = current_time;
   }
}

面板数字对齐与强弱色阶怎么落地

多货币强度面板如果只堆数字,盯盘时眼睛会瞎。把每个货币对的一小时、四小时、日线变动和综合强度按固定宽度打印,列才能对齐——比如用 %+6.1f 控宽,正号负号都占同样字符位,扫一眼就知道哪行偏离大。 颜色不是好看而已。代码里 strength 大于 0 走 InpStrongColor、小于 0 走 InpWeakColor,正负一眼分;更关键的是 ApplyColorCoding 先抓全样本里绝对值最大的 strength 当分母,再算每个品种的 strength_ratio 去映射渐变色。色越艳,波动贡献越大,最活跃的品种会自己跳出来。 外汇和贵金属波动受杠杆与消息驱动,高风险,色阶只帮你缩小观察范围,不替代仓位控制。开 MT5 把这段贴进指标,调 InpStrongColor / InpWeakColor 两个外部参数,就能直接看自己 broker 的品种强弱分布。

MQL5 / C++
<span class="keyword">class="type">void</span> UpdatePairDisplay(<span class="keyword">const</span> <span class="keyword">class="type">class="kw">string</span> label_suffix, <span class="keyword">const</span> <span class="keyword">class="type">class="kw">string</span> <span class="keyword">value</span>, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">const</span> class="type">color clr, <span class="keyword">const</span> <span class="keyword">class="type">int</span> position) {
&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="type">class="kw">string</span> text = StringFormat(<span class="class="type">class="kw">string">"%s %+class="num">6.1f %+class="num">6.1f %+class="num">6.1f %+class="num">6.1f"</span>,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">value</span>.pair,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">value</span>.h1_change,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">value</span>.h4_change,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">value</span>.d1_change,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">value</span>.strength);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;class="type">color display_color = <span class="keyword">value</span>.strength &gt; <span class="number">class="num">0</span> ? InpStrongColor : InpWeakColor;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;CreateLabel(<span class="class="type">class="kw">string">"SPPanel_"</span> + label_suffix,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position &lt; <span class="number">class="num">10</span> ? <span class="number">class="num">30</span> : <span class="number">class="num">420</span>,&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">// X coordinate</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="number">class="num">90</span> + (position % <span class="number">class="num">10</span>) * <span class="number">class="num">25</span>, <span class="comment">class=class="str">"cmt">// Y coordinate</span>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;display_color,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="number">class="num">9</span>);
}
<span class="keyword">class="type">void</span> ApplyColorCoding() {
&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">// Dynamically detecting boundaries for class="type">color coding</span>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="type">class="kw">double</span> max_strength = <span class="number">class="num">0</span>;
&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">for</span>(<span class="keyword">class="type">int</span> i = <span class="number">class="num">0</span>; i &lt; g_pairs_count; i++) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span>(<span class="functions">MathAbs</span>(g_strength_data[i].strength) &gt; max_strength)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_strength = <span class="functions">MathAbs</span>(g_strength_data[i].strength);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">// Apply gradient coloring</span>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">for</span>(<span class="keyword">class="type">int</span> i = <span class="number">class="num">0</span>; i &lt; g_pairs_count; i++) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="type">class="kw">double</span> strength_ratio = g_strength_data[i].strength / max_strength;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="type">color</span> intensity = GetColorIntensity(strength_ratio);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UpdatePairColor(i, intensity);
&nbsp;&nbsp;&nbsp;&nbsp;}
}

◍ 跨周期验证强度仪表盘的计算一致性

把仪表盘接上真实行情后,先别急着拿来信号,先在多个周期上核对它算出来的强弱值是否自洽。同一套货币强度逻辑,如果在 M1 和 D1 上给出互相打架的结论,说明加权或平滑环节有隐性 bug。 实际截图中,左侧强势区里 EURCAD 的多周期方向以正为主,可以作为多头锚定品种;右侧弱势区里 CADCHF 在 H4 读数为 -0.5、D1 读数为 -1.8,综合疲软度约 -1.1。这组数字说明指标在高周期上的偏离更明显,对可持续弱趋势的捕捉比小周期更干净。 验证时建议手动切到 H4 和 D1 各挂一次,对比面板数值与肉眼 K 线斜率是否同向。外汇与贵金属杠杆高、跳空频繁,跨周期信号仅代表概率倾向,不能直接当作入场依据。

「最后说句实在话」

这套货币强度面板把 H1、H4、D1 三周期都拉进加权评分,整体强度值由三个周期共同贡献,盘面上能直接看到 28 个货币对被实时排序。它背后的思路是把市场当成一个互联系统,而不是孤立看单边,这点跟单纯盯美元基数派的做法不一样。 评论区里有人坚持只用美元作基数算 7 个主力对,认为 28 对太重;也有人反驳说那样会丢掉「货币强度」这个概念本身。两种路线在 MT5 里都能验证,你下载 Currency_Strength_Panel.mq5(约 20 KB)跑一遍,对比自己用 EURUSD*USDJPY 手算的交叉强度,就知道哪边更贴合你的盘感。 外汇和贵金属杠杆高、波动突兀,任何强度排序都只是概率倾向,别拿它当进出场保证。开模拟盘先跑两周,再谈真金白银。

把跨周期扫描交给小布盯盘
这些诊断小布盯盘的 AIGC 已内置,打开对应品种页即可看到 H1/H4/D1 的货币强度棱镜,不用自己维护 MT5 定时器也能比对篮子关系。

常见问题

常见做法是对 D1 权重低频率更新、H1 高频轻量拉取,避免每 tick 重算 28 对篮子;具体要结合品种流动性和 CPU 占用实测,倾向 1–5 秒分级触发。
可能是各周期权重未归一,或取价时点错位;需在更新系统里统一时间戳基准,并在测试环节逐周期核对均值偏移。
可以,小布盯盘品种页内置了 H1/H4/D1 的货币关系棱镜与极值高亮,省去自己写定时器和配色逻辑的过程。
动态分位更抗波动,固定阈值在趋势市容易全红全绿;概率上动态评分适配不同波动率品种更稳。
篮子关系会随利率预期突变反转,贵金属还受实物供需扰动,属高风险品类,信号仅作概率参考而非方向保证。