Bug de inconsistência na cor dos candles

 

Eu fiz um indicador de coloração básico porém na maioria das vezes que adiciono ele ao gráfico a coloração está errada.

O vídeo abaixo mostra o bug:

https://streamable.com/9pvqf

Na segunda vez que adicionei o indicador as cores estão corretas, na primeira não.

Código:

#property indicator_buffers 7
#property indicator_plots 2

#property indicator_label1 "Candles"
#property indicator_color1 Green, Red
#property indicator_type1 DRAW_COLOR_CANDLES

#property indicator_label2 "MA"
#property indicator_color2 Green, Red, Yellow
#property indicator_type2 DRAW_COLOR_LINE
#property indicator_width2 2

double buffer_open[], buffer_high[], buffer_low[], buffer_close[];
double candle_color[];

int MA;
double buffer_ma[];
double ma_color[];

int OnInit() {
   SetIndexBuffer(0, buffer_open, INDICATOR_DATA);
   SetIndexBuffer(1, buffer_high, INDICATOR_DATA);
   SetIndexBuffer(2, buffer_low, INDICATOR_DATA);
   SetIndexBuffer(3, buffer_close, INDICATOR_DATA);
   SetIndexBuffer(4, candle_color, INDICATOR_COLOR_INDEX);
   
   SetIndexBuffer(5, buffer_ma, INDICATOR_DATA);
   SetIndexBuffer(6, ma_color, INDICATOR_COLOR_INDEX);
   
   MA = iMA(_Symbol, _Period, 20, 0, MODE_SMA, PRICE_CLOSE);

   return(0);
}

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[]) {              
   int start;
   if (prev_calculated == 0) {
      start = 1;
   } else {
      start = prev_calculated - 1;
   }
   
   CopyBuffer(MA, 0, 0, rates_total, buffer_ma);
   
   for (int i = start; i < rates_total; i++) {
      if (buffer_ma[i] > buffer_ma[i - 1]) {
         ma_color[i] = 0;
      } else if (buffer_ma[i] < buffer_ma[i - 1]) {
         ma_color[i] = 1;
      } else {
         ma_color[i] = 2;
      }
   
      buffer_open[i] = open[i];
      buffer_high[i] = high[i];
      buffer_low[i] = low[i];
      buffer_close[i] = close[i];
      
      if (close[i] > close[i - 1] && buffer_ma[i] > buffer_ma[i - 1]) {
         candle_color[i] = 0;
      } else if (close[i] < close[i - 1] && buffer_ma[i] < buffer_ma[i - 1]) {
         candle_color[i] = 1;
      }
   }             
   
   return(rates_total);
}
O2caJbYiGY.mp4 - Streamable
O2caJbYiGY.mp4 - Streamable
  • streamable.com
Check out this video on Streamable using your phone, tablet or desktop.
 

Divide teu código em 2 indicadores, um para os candles e outro para a média.

Veja se acontece esse bug em algum individual, vai ajustando ele separado e quando estiver sem nenhum bug, faz a fusão dos dois.

Reparei que vc não adicionou o tipo chart nas propriedades, ou faltou colar. O metatrader quando compilei já definiu chart_windows, seria bom definir manualmente.

Aqui não deu o bug informado.

 
prsc:

Divide teu código em 2 indicadores, um para os candles e outro para a média.

Veja se acontece esse bug em algum individual, vai ajustando ele separado e quando estiver sem nenhum bug, faz a fusão dos dois.

Reparei que vc não adicionou o tipo chart nas propriedades, ou faltou colar. O metatrader quando compilei já definiu chart_windows, seria bom definir manualmente.

Aqui não deu o bug informado.

Não tem como separar e fazer exatamente o mesmo indicador pro candle porque ele depende da MA. Mas até agora não tive nenhum problema com a MA então o bug com certeza ta na parte da coloração dos candles.

O problema é que ele acontece algumas vezes e outras não, então pra mim não tem sentido ser um erro no cálculo. Só se tem alguma relação com os buffers.

Você adicionou e tirou o indicador repetidamente e nenhuma das vezes deu o bug?

 

Sim, adicionei várias vezes, funcionou normal.

Olha como separando não pinta todos os candles

#property indicator_chart_window
#property indicator_buffers 6
#property indicator_plots 2

#property indicator_label1 "Candles"
#property indicator_color1 clrGreen, clrRed
#property indicator_type1 DRAW_COLOR_CANDLES

double buffer_open[], buffer_high[], buffer_low[], buffer_close[];
double candle_color[];
int MA;
double buffer_ma[];

int OnInit() {
   SetIndexBuffer(0, buffer_open, INDICATOR_DATA);
   SetIndexBuffer(1, buffer_high, INDICATOR_DATA);
   SetIndexBuffer(2, buffer_low, INDICATOR_DATA);
   SetIndexBuffer(3, buffer_close, INDICATOR_DATA);
   SetIndexBuffer(4, candle_color, INDICATOR_COLOR_INDEX);
   SetIndexBuffer(5, buffer_ma, INDICATOR_DATA);
   MA = iMA(_Symbol, _Period, 25, 0, MODE_SMA, PRICE_CLOSE);

   return(0);
}

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[]) {              
   int start;
   if (prev_calculated == 0) {
      start = 1;
   } else {
      start = prev_calculated - 1;
   }
   
   CopyBuffer(MA, 0, 0, rates_total, buffer_ma);
   
   for (int i = start; i < rates_total; i++) {
      //if (buffer_ma[i] > buffer_ma[i - 1]) {
      //   ma_color[i] = 0;
      //} else if (buffer_ma[i] < buffer_ma[i - 1]) {
      //   ma_color[i] = 1;
      //} else {
      //   ma_color[i] = 2;
      //}
   
      buffer_open[i] = open[i];
      buffer_high[i] = high[i];
      buffer_low[i] = low[i];
      buffer_close[i] = close[i];
      
      if (close[i] > close[i - 1] && buffer_ma[i] > buffer_ma[i - 1]) {
         candle_color[i] = 0;
      } else if (close[i] < close[i - 1] && buffer_ma[i] < buffer_ma[i - 1]) {
         candle_color[i] = 1;
      }
   }             
   
   return(rates_total);
}


Fiz um modelo que uso para os candles, e também tem diferença, não pinta todos os candles, deve ser porque a condição que vc adicionou não está sendo satisfeita.


#property indicator_chart_window
#property indicator_buffers 7
#property indicator_plots 2

#property indicator_label1 "Candles"
//#property indicator_color1 clrGreen, clrRed
#property indicator_type1 DRAW_COLOR_CANDLES
color  ColorOf[3]={CLR_NONE,clrGreen,clrRed}; //Adicionado

#property indicator_label2 "MA"
#property indicator_color2 Green, Red, Yellow
#property indicator_type2 DRAW_COLOR_LINE
#property indicator_width2 2

double buffer_open[], buffer_high[], buffer_low[], buffer_close[];
double candle_color[];

int MA;
double buffer_ma[];
double ma_color[];

int OnInit() {
   SetIndexBuffer(0, buffer_open, INDICATOR_DATA);
   SetIndexBuffer(1, buffer_high, INDICATOR_DATA);
   SetIndexBuffer(2, buffer_low, INDICATOR_DATA);
   SetIndexBuffer(3, buffer_close, INDICATOR_DATA);
   SetIndexBuffer(4, candle_color, INDICATOR_COLOR_INDEX);
   
   //Adicionado
   PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,3);
   //---- Em conjunto com o "color ColorOf[3]"
   for(int i=1;i<3;i++)
      PlotIndexSetInteger(0,PLOT_LINE_COLOR,i,ColorOf[i]);
      IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
   //----
   SetIndexBuffer(5, buffer_ma, INDICATOR_DATA);
   SetIndexBuffer(6, ma_color, INDICATOR_COLOR_INDEX);
   MA = iMA(_Symbol, _Period, 25, 0, MODE_SMA, PRICE_CLOSE);

   return(0);
}

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[]) {              
   int start;
   if (prev_calculated == 0) {
      start = 1;
   } else {
      start = prev_calculated - 1;
   }
   
   CopyBuffer(MA, 0, 0, rates_total, buffer_ma);
   
   for (int i = start; i < rates_total; i++) {
      if (buffer_ma[i] > buffer_ma[i - 1]) {
         ma_color[i] = 0;
      } else if (buffer_ma[i] < buffer_ma[i - 1]) {
         ma_color[i] = 1;
      } else {
         ma_color[i] = 2;
      }
   
      buffer_open[i] = open[i];
      buffer_high[i] = high[i];
      buffer_low[i] = low[i];
      buffer_close[i] = close[i];
      
      if (close[i] > close[i - 1] && buffer_ma[i] > buffer_ma[i - 1]) {
         candle_color[i] = 1;
      } else if (close[i] < close[i - 1] && buffer_ma[i] < buffer_ma[i - 1]) {
         candle_color[i] = 2;
      }
   }             
   
   return(rates_total);
}


Onde está //adicionado foi o que inseri para colorir, um modelo padrão que tou usando e funciona bem.

Não sei muito também dos detalhes técnicos, estou inciando e apanhando muito, mas o que pude ajudar está ai.

Abraço.

 
Iervolino:

Eu fiz um indicador de coloração básico porém na maioria das vezes que adiciono ele ao gráfico a coloração está errada.

O vídeo abaixo mostra o bug:

https://streamable.com/9pvqf

Na segunda vez que adicionei o indicador as cores estão corretas, na primeira não.

Código:

Bom dia,

o código está deixando o buffer candle_color com sujeira. Correção está abaixo


      if(buffer_ma[i]>buffer_ma[i-1])
        {
         if(close[i]>close[i-1])
            candle_color[i]=0;
         else
           // defina uma cor
        }

      if(buffer_ma[i]<=buffer_ma[i-1])
        {
         if(close[i]<close[i-1])
            candle_color[i]=1;
         else
           // defina uma cor
        }
 
Rogerio Giannetti Torres:

Bom dia,

o código está deixando o buffer candle_color com sujeira. Correção está abaixo


Muito obrigado!

Acredito que o bug foi corrigido, mas agora fiquei em dúvida.

Porque analisando a condição na mesma linha, tanto do candle quanto da MA, ele causa esse bug?

E está correto dessa forma?

   for (int i = start; i < rates_total; i++) {
      buffer_open[i] = open[i];
      buffer_high[i] = high[i];
      buffer_low[i] = low[i];
      buffer_close[i] = close[i];   
   
      if (buffer_ma[i] > buffer_ma[i - 1]) {
         ma_color[i] = 0;
         if (close[i] > close[i - 1])
            candle_color[i] = 0;
         else
            candle_color[i] = EMPTY_VALUE;
      } else if (buffer_ma[i] < buffer_ma[i - 1]) {
         ma_color[i] = 1;
         if (close[i] < close[i - 1])
            candle_color[i] = 1;
         else
            candle_color[i] = EMPTY_VALUE;
      } else {
         ma_color[i] = 2;
      }     
   }
Razão: