为何我的MQL5指标仅显示一条VIDYA均线而非两条?
问题分析与修复方案
核心问题1:两条均线颜色完全重叠
你的代码中,两条VIDYA均线的颜色都设置为Navy(深蓝色),即使两条线实际存在,也会因为颜色一致而重叠在一起,看起来像是只有一条线。
核心问题2:第二条VIDYA的计算逻辑错误
VIDYA的标准递推公式为:
VIDYA[i] = 价格[i] * k + VIDYA[i-1] * (1 - k)
其中k = 2/(1+EMA周期) * |CMO值|(对应你的ExtF*mul_CMO)。但你给第二条均线的计算式错误地给(1-ExtF*mul_CMO)乘了2,完全违背了VIDYA的平滑逻辑,会导致数值异常,甚至可能和第一条线走势严重偏离(但颜色相同你无法察觉)。
修复后的完整代码
#property copyright "2009-2020, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property description "Double Variable Index Dynamic Average" //--- indicator settings #property indicator_chart_window #property indicator_buffers 2 #property indicator_plots 2 #property indicator_type1 DRAW_LINE #property indicator_color1 Navy // 第一条线保留深蓝色 #property indicator_width1 3 #property indicator_label1 "VIDYA 1" #property indicator_type2 DRAW_LINE #property indicator_color2 Gold // 第二条线改为金色,和第一条区分 #property indicator_width2 3 #property indicator_label2 "VIDYA 2" #property indicator_applied_price PRICE_MEDIAN //--- input parameters input int InpPeriodCMO = 9; // Period CMO input int InpPeriodEMA = 12; // Period EMA for VIDYA 1 input int InpPeriodEMA2 = 24; // Period EMA for VIDYA 2 input int InpShift = 0; // Indicator's shift //--- indicator buffer double VIDYA_Buffer_1[]; double VIDYA_Buffer_2[]; double ExtF1; // 第一条线的平滑因子 double ExtF2; // 第二条线的平滑因子 //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ void OnInit() { //--- indicator buffers mapping SetIndexBuffer(0, VIDYA_Buffer_1, INDICATOR_DATA); SetIndexBuffer(1, VIDYA_Buffer_2, INDICATOR_DATA); //--- sets first bar from what index will be drawn int drawBegin = MathMax(InpPeriodEMA, InpPeriodEMA2) + InpPeriodCMO -1; PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, drawBegin); PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, drawBegin); //--- sets indicator shift PlotIndexSetInteger(0, PLOT_SHIFT, InpShift); PlotIndexSetInteger(1, PLOT_SHIFT, InpShift); //--- name for indicator label string short_name = StringFormat("Double VIDYA(%d,%d/%d)", InpPeriodCMO, InpPeriodEMA, InpPeriodEMA2); IndicatorSetString(INDICATOR_SHORTNAME,short_name); PlotIndexSetString(0, PLOT_LABEL, "VIDYA "+IntegerToString(InpPeriodEMA)); PlotIndexSetString(1, PLOT_LABEL, "VIDYA "+IntegerToString(InpPeriodEMA2)); //--- calculate smooth factors for both lines ExtF1 = 2.0/(1.0+InpPeriodEMA); ExtF2 = 2.0/(1.0+InpPeriodEMA2); } //+------------------------------------------------------------------+ //| Variable Index Dynamic Average | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) { int drawBegin = MathMax(InpPeriodEMA, InpPeriodEMA2) + InpPeriodCMO -1; if(rates_total < drawBegin) return(0); //--- int i,start; if(prev_calculated < drawBegin) { start = drawBegin; for(i = 0; i<start; i++) { VIDYA_Buffer_1[i] = price[i]; VIDYA_Buffer_2[i] = price[i]; } } else start = prev_calculated-1; //--- main cycle for(i = start; i<rates_total && !IsStopped(); i++) { double mul_CMO = MathAbs(CalculateCMO(i,InpPeriodCMO,price)); //--- 正确计算两条VIDYA均线 VIDYA_Buffer_1[i] = price[i]*ExtF1*mul_CMO + VIDYA_Buffer_1[i-1]*(1-ExtF1*mul_CMO); VIDYA_Buffer_2[i] = price[i]*ExtF2*mul_CMO + VIDYA_Buffer_2[i-1]*(1-ExtF2*mul_CMO); } //--- OnCalculate done. Return new prev_calculated. return(rates_total); } //+------------------------------------------------------------------+ //| Chande Momentum Oscillator | //+------------------------------------------------------------------+ double CalculateCMO(int pos,const int period,const double &price[]) { double res = 0.0; double sum_up = 0.0,sum_down = 0.0; //--- if(pos >= period && pos<ArraySize(price)) { for(int i = 0; i<period; i++) { double diff = price[pos-i]-price[pos-i-1]; if(diff>0.0) sum_up += diff; else sum_down += (-diff); } if(sum_up+sum_down != 0.0) res = (sum_up-sum_down)/(sum_up+sum_down); } //--- return(res); }
额外优化说明
- 给第二条线设置了不同的颜色(Gold),确保两条线能被清晰区分
- 新增了独立的EMA周期参数
InpPeriodEMA2,让两条VIDYA均线有不同的平滑特性,避免走势过度重叠 - 统一了两条线的
PLOT_DRAW_BEGIN值,取两个EMA周期的最大值,确保计算起点一致 - 修正了第二条线的递推公式,符合VIDYA的标准计算逻辑
内容的提问来源于stack exchange,提问作者Ken
相关产品推荐
相关产品推荐

