Discussão do artigo "Do básico ao intermediário: Indicador (III)"

 

Novo artigo Do básico ao intermediário: Indicador (III) foi publicado:

Neste artigo iremos ver como declarar diversos indicadores de plotagem, como DRAW_COLOR_LINE e DRAW_FILLING. Além é claro, aprender como plotar indicadores múltiplos de uma forma muito simples, prática e pouco trabalhosa. Agora que realmente pode mudar a sua forma de enxergar o MetaTrader 5 e o mercado em geral.

No artigo anterior Do básico ao intermediário: Indicador (II), tivemos um momento de bastante diversão e aprendizado. Já que foi demonstrado como poderíamos implementar uma média móvel de forma muito simples, prática e perfeitamente funcional. Mas aquilo que foi mostrado, podemos dizer que foi apenas uma breve introdução, ao que seria o mundo de um programador MQL5. Visto que aquele material é bem básico, simples e direto. Mas podemos fazer muito mais do que o que foi mostrado.

Então meu caro leitor, tente compreender os conceitos adotados aqui. Não tente simplesmente copiar o código ou achar, que só por você não está conseguindo fazer, ninguém mais sabe como fazer está ou aquela coisa. Entender o conceito é mais importante do que entender o próprio código. Já que o código pode vir a mudar dependendo de quem o estiver escrevendo. Porém o conceito irá sempre se manter. Então vamos começar com algo bem simples. Já que o que será visto pode vir a ser muito complicado se já aplicarmos certas funcionalidades assim, de uma hora para outra.

Autor: CODE X

 
Prezados.
Estou tentando criar um indicador personalizado com base no iBand.
Depois de muita pesquisa, decidi postar aqui, talvez alguém possa me ajudar.
Aqui está o indicador completo.
/Este é o MQL5\Indicators\Anhnt\iBand_Display.mq5
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   3

//--- plot Middle
#property indicator_label1  "Middle"
#property indicator_type1   DRAW_LINE

//--- plot Upper
#property indicator_label2  "Upper"
#property indicator_type2   DRAW_LINE

//--- plot Lower
#property indicator_label3  "Lower"
#property indicator_type3   DRAW_LINE

//==================================================
// Parâmetros de entrada
//==================================================
input int      InpBBPeriod      = 14;
input ENUM_APPLIED_PRICE inp_Applied_Price   = PRICE_MEDIAN;
input double   InpBBDeviation   = 2.0;
input int      InpBBShift       = 0;

input color    InpMiddleColor   = clrYellow;
input color    InpUpperColor    = clrYellow;
input color    InpLowerColor    = clrYellow;

input int      InpMiddleWidth   = 2;
input int      InpUpperWidth    = 2;
input int      InpLowerWidth    = 2;

input bool inp_BB_Show_Upper   = true;
input bool inp_BB_Show_Middle  = true;
input bool inp_BB_Show_Lower   = true;

input ENUM_LINE_STYLE InpMiddleStyle = STYLE_DOT;
input ENUM_LINE_STYLE InpUpperStyle  = STYLE_DOT;
input ENUM_LINE_STYLE InpLowerStyle  = STYLE_DOT;
//==================================================
#include <Anhnt/Configuration/NamingConfiguration.mqh>
//==================================================
// Bufferes indicadores
//==================================================
double MiddleBuffer[];
double UpperBuffer[];
double LowerBuffer[];

//==================================================
// Variáveis globais
//==================================================
int g_bb_handle = INVALID_HANDLE;

//https://www.mql5.com/pt/docs/indicators/ibands
//--- manteremos o número de valores no indicador Bollinger Bands

//+------------------------------------------------------------------+
int OnInit()
{
   //==================================================
   // Definir buffers
   //==================================================
   SetIndexBuffer(BASE_LINE,  MiddleBuffer, INDICATOR_DATA);
   SetIndexBuffer(UPPER_BAND, UpperBuffer,  INDICATOR_DATA);
   SetIndexBuffer(LOWER_BAND, LowerBuffer,  INDICATOR_DATA);

   ArraySetAsSeries(MiddleBuffer, true);
   ArraySetAsSeries(UpperBuffer,  true);
   ArraySetAsSeries(LowerBuffer,  true);   

   //================================================== 
   // Aplicar valores INPUT aos gráficos (modo seguro em tempo de execução)
   //==================================================
   PlotIndexSetInteger(BASE_LINE,  PLOT_LINE_COLOR, InpMiddleColor);
   PlotIndexSetInteger(UPPER_BAND, PLOT_LINE_COLOR, InpUpperColor);
   PlotIndexSetInteger(LOWER_BAND, PLOT_LINE_COLOR, InpLowerColor);

   PlotIndexSetInteger(BASE_LINE,  PLOT_LINE_STYLE, InpMiddleStyle);
   PlotIndexSetInteger(UPPER_BAND, PLOT_LINE_STYLE, InpUpperStyle);
   PlotIndexSetInteger(LOWER_BAND, PLOT_LINE_STYLE, InpLowerStyle);

   PlotIndexSetInteger(BASE_LINE,  PLOT_LINE_WIDTH, InpMiddleWidth);
   PlotIndexSetInteger(UPPER_BAND, PLOT_LINE_WIDTH, InpUpperWidth);
   PlotIndexSetInteger(LOWER_BAND, PLOT_LINE_WIDTH, InpLowerWidth);   

   PlotIndexSetInteger(
         BASE_LINE,
         PLOT_DRAW_TYPE,
         inp_BB_Show_Middle ? DRAW_LINE : DRAW_NONE
   );

   PlotIndexSetInteger(
         UPPER_BAND,
         PLOT_DRAW_TYPE,
         inp_BB_Show_Upper ? DRAW_LINE : DRAW_NONE
   );

   PlotIndexSetInteger(
         LOWER_BAND,
         PLOT_DRAW_TYPE,
         inp_BB_Show_Lower ? DRAW_LINE : DRAW_NONE
   );
   string name = SMT_PREFIX + SMT_BB_NAME +
                 "(" + (string)InpBBPeriod + "," +
                 DoubleToString(InpBBDeviation, 1) + ")";  
   
                                   
   IndicatorSetString(INDICATOR_SHORTNAME, name);
   //==================================================
   // Criar identificador de iBands
   //==================================================
   g_bb_handle = iBands(
      _Symbol,
      _Period,
      InpBBPeriod,
      InpBBShift,
      InpBBDeviation,
      inp_Applied_Price
   );
   if(g_bb_handle == INVALID_HANDLE)
   {
      Print("iBand_Display INIT FAILED. Unable to create iBands handle. GetLastError = ", GetLastError());
      return INIT_FAILED;
   }
      
   Print("iBand_Display INIT SUCCESS");
   return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
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[]
)
{
   //https://www.mql5.com/pt/docs/indicators/ibands&amp;nbsp;  
   //--- esperar até que o iBands esteja pronto
   int calculated = BarsCalculated(g_bb_handle);
   if(calculated <= InpBBPeriod)
      return 0;   
      // Print("DEBUG from OnCalculate After Waiting BarsCalculated | Symbol=", _Symbol,
      // " | Período=", _Período,
      // " | BarsCalculated(iBands)=", calculado); 
   //--- Esse bloco é executado quando o indicador é inicialmente anexado a um gráfico
   if(prev_calculated == 0)
   {
      ArrayInitialize(MiddleBuffer, EMPTY_VALUE);
      ArrayInitialize(UpperBuffer,  EMPTY_VALUE);
      ArrayInitialize(LowerBuffer,  EMPTY_VALUE);

      int to_copy = MathMin(calculated, rates_total);

      // Copiar todos os dados disponíveis de uma só vez
      CopyBuffer(g_bb_handle, BASE_LINE,  0, to_copy, MiddleBuffer);
      CopyBuffer(g_bb_handle, UPPER_BAND, 0, to_copy, UpperBuffer);
      CopyBuffer(g_bb_handle, LOWER_BAND, 0, to_copy, LowerBuffer);
      // Print("DEBUG from OnCalculate First Initial | Symbol=", _Symbol,
      // " | Período=", _Período,
      // " | BarsCalculated(iBands)=", calculado);
      return rates_total;    
   }   
   //--- Esse bloco é executado a cada nova barra aberta
   if(prev_calculated != rates_total && prev_calculated != 0)
   {
      //==================================================
   // PRÓXIMAS EXECUÇÕES:
   // Atualizar somente a barra mais nova (índice 0).
   // NÃO altere as matrizes manualmente (as séries cuidam disso).
   //==================================================
      double tmp[1];
      if(CopyBuffer(g_bb_handle, BASE_LINE, 0, 1, tmp) > 0)
      MiddleBuffer[0] = tmp[0];

      if(CopyBuffer(g_bb_handle, UPPER_BAND, 0, 1, tmp) > 0)
         UpperBuffer[0] = tmp[0];

      if(CopyBuffer(g_bb_handle, LOWER_BAND, 0, 1, tmp) > 0)
         LowerBuffer[0] = tmp[0];
      return rates_total;      
   }  
   return rates_total;
}
//+------------------------------------------------------------------+

bool FillArraysFromBuffers(
   double &base_values  [],   // MiddleBuffer
   double &upper_values [],   // UpperBuffer
   double &lower_values [],   // LowerBuffer
   int shift,                 // shift = 0 → tempo real
   int ind_handle,
   int amount
)
{
   // OBSERVAÇÃO:
   // Atualmente não é usado.
   // Mantido para lógica futura de auxiliar/ EA conforme planejado.

   ResetLastError();
   if(CopyBuffer(ind_handle, BASE_LINE,  -shift, amount, base_values) < 0)
      return false;
   if(CopyBuffer(ind_handle, UPPER_BAND, -shift, amount, upper_values) < 0)
      return false;
   if(CopyBuffer(ind_handle, LOWER_BAND, -shift, amount, lower_values) < 0)
      return false;
   return true;
}
É muito fácil. Só quero permitir que o usuário mostre ou oculte linhas individuais, como BASE_LINE,UPPER_BAND,LOWER_BAND e apenas a cor personalizada.
O problema 1 é:
Você pode ver na imagem anexa que não sei por que tenho verde no gráfico.
Arquivos anexados:
Problem_1.jpg  217 kb
 
Nguyen Tuấn Anh # :
Caros.
Estou tentando criar um indicador personalizado baseado no iBand.
Depois de muita pesquisa, decidi postar aqui, talvez alguém possa me ajudar.
Aqui está o indicador completo. Muito simples, eu só quero permitir que o usuário mostre ou oculte linhas individuais, como BASE_LINE, UPPER_BAND, LOWER_BAND e apenas a cor personalizada.
O problema 1 é:
Como você pode ver na imagem em anexo, não sei por que há uma área verde embaixo do gráfico.
Essas linhas verdes são o indicador de volume. Para desativar isso, você deve abrir as propriedades do gráfico e desativar o indicador de volume. Ou simplesmente definir a cor do volume como CL_NONE, para que essas linhas verdes desapareçam.