交易货币篮子时可用的形态。第三部分·综合运用
多品种几何均值与快慢线差的实现骨架
这段逻辑把多个交易品种收拢成一个综合数值,再套快慢均线做差。GetValue 先对 iCount 个品种取收盘价,按 bDirect 标记决定是否取倒数,连乘后开 iCount 次方,用 NormalizeDouble 按 _Digits 精度返回,本质是构造一个跨品种几何均值序列 ma[]。 OnCalculate 里首次计算或数据缺口超过 1 根时,全量刷 ma[] 与 ind[]:ind[i] = 快 EMA(ma) - 慢 EMA(ma),慢线周期由 InpSlowEMA 控制;只来新 tick 时仅更新 0 号元素,避免重复算历史。 GetMA 是简单滑动求和雏形,循环把 arr[index+j] 累加 period 次,尚未除周期,调用方拿到的还是未归一的和,接自己策略时要补均值化。外汇与贵金属跨品种组合高风险,几何均值对单边品种倒数处理会放大回撤,参数先在小周期模拟再上实盘。
class="type">class="kw">double GetValue(class="type">int shift) { class="type">class="kw">double res=class="num">1.0,d; class="type">class="kw">double dBuf[class="num">1]; for(class="type">int i=class="num">0; i<iCount; i++) { d=CopyClose(pair[i],PERIOD_CURRENT,shift,class="num">1,dBuf); if(!bDirect[i]) dBuf[class="num">0]=class="num">1/dBuf[class="num">0]; res*=dBuf[class="num">0]; }class=class="str">"cmt">//结束 for (class="type">int i = class="num">0; i < iCount; i++) class="kw">return (NormalizeDouble(MathPow(res, class="num">1/(class="type">class="kw">double)iCount), _Digits) ); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 自定义指标迭代函数 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">class="kw">double t; class="type">int OnCalculate(class="kw">const class="type">int rates_total, class="kw">const class="type">int prev_calculated, class="kw">const class="type">class="kw">datetime &time[], class="kw">const class="type">class="kw">double &open[], class="kw">const class="type">class="kw">double &high[], class="kw">const class="type">class="kw">double &low[], class="kw">const class="type">class="kw">double &close[], class="kw">const class="type">long &tick_volume[], class="kw">const class="type">long &volume[], class="kw">const class="type">int &spread[]) { if(prev_calculated==class="num">0 || rates_total>prev_calculated+class="num">1) { class="type">int rt=rates_total; for(class="type">int i=class="num">1; i<rt; i++) { ma[i]= GetValue(i); } rt=rates_total - InpSlowEMA; for(class="type">int i=class="num">1; i<rt; i++) { ind[i] = GetMA(ma, i, InpFastEMA, _Digits) - GetMA(ma, i, InpSlowEMA, _Digits); } } else { ma[class="num">0]= GetValue(class="num">0); ind[class="num">0] = GetMA(ma, class="num">0, InpFastEMA, _Digits) - GetMA(ma, class="num">0, InpSlowEMA, _Digits); } class=class="str">"cmt">//--- 返回 prev_calculated 的值用于下次调用 class="kw">return(rates_total); } class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">class="kw">double GetMA(class="kw">const class="type">class="kw">double& arr[], class="type">int index , class="type">int period, class="type">int digit) { class="type">class="kw">double m = class="num">0; for (class="type">int j = class="num">0; j < period; j++) m += arr[index + j];
◍ 均值计算与精度归一的实现细节
这段收尾代码把累加后的总和 m 除以 period 得到滑动均值,再用 NormalizeDouble 按当前品种小数位 digit 做精度截断,避免浮点误差导致报价位数错乱。 在实盘里若 digit 取错(比如黄金用了外汇的 4 位),返回值会直接偏离真实价位多个点,下单或画线都会失真。 开 MT5 后把这段代码接在你自己的 iMA 模拟循环末尾,打印 NormalizeDouble(m,digit) 与手动算的均值差,能快速验证 digit 来源是否匹配品种。
m /= period; class="kw">return (NormalizeDouble(m,digit));
「篮子信号落地与未竟的统计缺口」
组合指标穿越超卖/超买边界、且基准与报价货币各自的 WPR 或 STOCH 出现背离时,形态有效度偏高。稳妥做法是等蜡烛收线,确认突破成立后再在挂载指标的那一个货币对上动手,而不是抢影线。 离场看组合振荡器回到近零区或碰触反向边界;若走向近零,就把已开单的止损推到盈亏平衡。要警惕假买入信号——指标若没奔零,而在突破超买/超卖后折返、再次交叉并锁在区间边界之后,原止损逻辑就可能被触发。 WPR/STOCH 显示篮子整体状态时,形态结构一致,但入场要扩到篮子内全部货币,止损位需重新测算。文中所用指标在 wpr2.zip 存档内,可直接挂 MT5 验证。MA 交集若发生在边界突破附近,算辅助确认;组合趋势指标形态仅作附加信号,不单独建议入场。 当前阶段仍给不出带意义的统计胜率,历史研究缺失是这类形态的底色缺陷。外汇与贵金属杠杆高、回撤凶,上述规则只提高可操作性,不承诺概率优势,后续文章再补回测。
随文附带的指标与文件包
这一节把全文用到的程序资产列清,方便直接去 MT5 里加载验证。压缩包 wpr.zip 体积 3.22 KB,里面是 testWPRusd 指标的源码与执行模块,外加 wpr.mq5 这个基础 WPR 技术指标的代码;testIndex+WPR.mq5 则是把 WPR 套在货币篮子指数方程上重算并绘制的组合指标。 index.zip(3.25 KB)含两个分别绑定美元与欧元篮子的指数指标,testIndexMACD.zip(1.65 KB)是基于 MACD 的简易趋势判断指标,wpr2.zip(4.83 KB)给出了示意入场与离场的标记逻辑。外汇与贵金属杠杆高、回撤快,这些指标仅作方法演示,实盘信号可能出现背离。 作者在原讨论里提到,自己常用的指标由多文件构成,启动不易出错,但 MT5 市场规则只允许单 ex5 文件发布,所以文中方案无法直接上架商店。想复现,就把对应 mq5 在本地编译,注意把依赖文件放在同一目录。