Обсуждение статьи "От начального до среднего уровня: Индикатор (III)"

 

Опубликована статья От начального до среднего уровня: Индикатор (III):

В данной статье мы рассмотрим, как объявлять различные индикаторы графического представления, такие как DRAW_COLOR_LINE и DRAW_FILLING. Кроме того, конечно же, мы научимся строить графики по нескольким индикаторам простым, практичным и быстрым способом. Это может действительно изменить ваш взгляд на MetaTrader 5 и рынок в целом.

В предыдущей статье "От начального до среднего уровня: Индикатор (II)", мы узнали много нового, поскольку продемонстрировали, как реализовать скользящую среднюю очень просто, практично и совершенно функционально. Однако то, что было показано, можно считать лишь кратким введением в мир программирования на MQL5, поскольку материал достаточно базовый, простой и понятный. Но мы можем сделать гораздо больше.

Итак, постарайтесь разобраться в представленных здесь концепциях. Не стоит просто копировать код и не думайте, что если вы не можете сделать это, то никто другой тоже не сможет. Понимание концепции важнее, чем понимание самого кода, поскольку код может меняться в зависимости от того, кто его пишет. в то время как концепция всегда останется. Мы начнем с чего-то очень простого, поскольку то, что вы увидите, может стать очень сложным, если мы внезапно применим некоторые функциональные возможности.


Автор: CODE X

 
Уважаемые все.
Япытаюсь построить пользовательский индикатор на основе iBand.
После долгих поисков я решил написать здесь, может быть кто-то сможет мне помочь.
Вот полный индикатор.
//Это MQL5\Indicators\Anhnt\iBand_Display.mq5
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   3

//--- сюжет Середина
#property indicator_label1  "Middle"
#property indicator_type1   DRAW_LINE

//--- сюжет Верхний
#property indicator_label2  "Upper"
#property indicator_type2   DRAW_LINE

//--- сюжет Нижний
#property indicator_label3  "Lower"
#property indicator_type3   DRAW_LINE

//==================================================
// Входные параметры
//==================================================
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>
//==================================================
// Индикаторные буферы
//==================================================
double MiddleBuffer[];
double UpperBuffer[];
double LowerBuffer[];

//==================================================
// Глобальные переменные
//==================================================
int g_bb_handle = INVALID_HANDLE;

//https://www.mql5.com/ru/docs/indicators/ibands
//--- мы сохраним количество значений в индикаторе Bollinger Bands

//+------------------------------------------------------------------+
int OnInit()
{
   //==================================================
   // Установите буферы
   //==================================================
   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);   

   //================================================== 
   // Примените значения INPUT к графикам (безопасный для времени выполнения способ)
   //==================================================
   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);
   //==================================================
   // Создайте ручку 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/ru/docs/indicators/ibands&amp;nbsp;  
   //--- подождите, пока iBands не будет готов
   int calculated = BarsCalculated(g_bb_handle);
   if(calculated <= InpBBPeriod)
      return 0;   
      // Print("DEBUG from OnCalculate After Waiting BarsCalculated | Symbol=", _Symbol,
      // " | Period="", _Period,
      // " | BarsCalculated(iBands)=", calculated); 
   //--- Этот блок выполняется при первоначальном присоединении индикатора к графику
   if(prev_calculated == 0)
   {
      ArrayInitialize(MiddleBuffer, EMPTY_VALUE);
      ArrayInitialize(UpperBuffer,  EMPTY_VALUE);
      ArrayInitialize(LowerBuffer,  EMPTY_VALUE);

      int to_copy = MathMin(calculated, rates_total);

      // Скопируйте все доступные данные за один раз
      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,
      // " | Period="", _Period,
      // " | BarsCalculated(iBands)=", calculated);
      return rates_total;    
   }   
   //--- Этот блок выполняется при каждом новом открытии бара
   if(prev_calculated != rates_total && prev_calculated != 0)
   {
      //==================================================
   // NEXT RUNS:
   // Обновляем только самый новый бар (индекс 0).
   // НЕ сдвигайте массивы вручную (серия сама справится с этим).
   //==================================================
      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  [],   // Средний буфер
   double &upper_values [],   // UpperBuffer
   double &lower_values [],   // LowerBuffer
   int shift,                 // shift = 0 → realtime
   int ind_handle,
   int amount
)
{
   // ПРИМЕЧАНИЕ:
   // В настоящее время не используется.
   // Сохраняется для будущих помощников / логики EA, как и планировалось.

   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;
}
Очень просто, я просто хочу, чтобы пользователь мог показывать или скрывать отдельные линии, такие как BASE_LINE,UPPER_BAND,LOWER_BAND и только пользовательский цвет.
Проблема 1:
Вы можете увидеть на картинке в приложении, я не знаю, почему у меня есть зеленый под графиком.
Файлы:
Problem_1.jpg  217 kb
 
Nguyen Tuấn Anh # :
Карос.
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. Все очень просто, я хочу разрешить пользователю отображать отдельные линии, такие как BASE_LINE, UPPER_BAND, LOWER_BAND, а также персональный кор.
Проблема 1:
Как видно на изображении в приложении, не видно, что на экране есть зеленая область.
Эти зеленые линии - индикатор громкости. Чтобы отключить его, нужно открыть свойства графика и выключить индикатор объема. Или просто установите цвет объема на CL_NONE, и тогда эти зеленые линии исчезнут.