You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的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);
}

额外优化说明

  1. 给第二条线设置了不同的颜色(Gold),确保两条线能被清晰区分
  2. 新增了独立的EMA周期参数InpPeriodEMA2,让两条VIDYA均线有不同的平滑特性,避免走势过度重叠
  3. 统一了两条线的PLOT_DRAW_BEGIN值,取两个EMA周期的最大值,确保计算起点一致
  4. 修正了第二条线的递推公式,符合VIDYA的标准计算逻辑

内容的提问来源于stack exchange,提问作者Ken

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 03:55:13