Нереально сильно тормозит программа!!!

 

Написал индикатор SMA, который отвечает за расчёт просто скользящей средней в качестве расчётов для скользящей взял такую формулу (high+low+close)/3.
Намного сильнее тормозит (примерно в 2 раза сильнее чем встроенный mooving average), когда кручу график на маленьких таймфреймах :((
Посмотреть код скользящей средней из встроенных индикаторов нельзя, почему так?
Выкладываю свой код. Обработку входящих тиков пока не делал. Это мой первый индикатор. Не понимаю, почему он такой тормознутый получился...

#property copyright "Copyright 2020, MetaQuotes Software Corp."

#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window

#property indicator_buffers 1
#property indicator_plots 1
#property indicator_label1 "SMA"
#property indicator_color1 clrYellow
#property indicator_type1 DRAW_SECTION
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

input int period_sma = 14;
int bars;
double sma_buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   SetIndexBuffer(0, sma_buffer, INDICATOR_DATA);
   string short_name=StringFormat("SMA(%d)",period_sma);
   IndicatorSetString(INDICATOR_SHORTNAME,short_name);
   PlotIndexSetString(0,PLOT_LABEL,short_name);
   IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
//--- indicator buffers mapping

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//---
   if(prev_calculated==0)
   {
      bars = rates_total;//Bars(_Symbol, _Period);
      if( bars < period_sma) 
         {
            printf("Слишком мало баров на графике для расчета индикатора");
            return 1;
         }
      else if (period_sma <= 0) 
         {
            printf("Некорректное значение периода скользящей средней"); 
            return 2;
         }
      double arr_sma[];
      ArrayResize(arr_sma, period_sma);
      double sum=0;
      int k = 0;
      for (int j = bars-1; j >= bars - period_sma; j--)
      {
         arr_sma[k] = NormalizeDouble( ( iHigh(_Symbol,_Period,j) + iLow(_Symbol,_Period,j) + iClose(_Symbol,_Period,j) ) / 3, _Digits);
         sum += arr_sma[k];
         sma_buffer[bars-j-1] = sum / (k+1);
         k++;
      }
      k=0;
      for (int i = bars-1 - period_sma; i >=0; i--)
      {
         sum -= arr_sma[k];
         arr_sma[k] = NormalizeDouble( ( iHigh(_Symbol,_Period,i) + iLow(_Symbol,_Period,i) + iClose(_Symbol,_Period,i) ) / 3, _Digits);
         sum += arr_sma[k];
         k++;
         if(k==period_sma){k=0;}
         sma_buffer[bars-i-1] = sum / period_sma;
      }
   }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
Открой новые возможности в MetaTrader 5 с сообществом и сервисами MQL5
Открой новые возможности в MetaTrader 5 с сообществом и сервисами MQL5
  • 2021.03.07
  • www.mql5.com
MQL5: язык торговых стратегий для MetaTrader 5, позволяет писать собственные торговые роботы, технические индикаторы, скрипты и библиотеки функций
 
Dmitry Fedoseev:
www.mql5.com/ru/code/77

И...? Ответа я не получил :(

 
Разобрался. Люто тормозило из-за этой строчки кода: 
#property indicator_type1 DRAW_SECTION
Поменял 
DRAW_SECTION
На 
DRAW_LINE
И всё залетало.
С DRAW_SECTION всё нереально тормозит даже не производя никаких расчётов. Для примера код снизу можете скопировать и убедиться в этом.
В зигзаге все же используется DRAW_SECTION и он почему не тормозит.
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window

#property indicator_buffers 1
#property indicator_plots 1
#property indicator_label1 "SMA"
#property indicator_color1 clrYellow
#property indicator_type1 DRAW_SECTION
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//---

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Вроде разобрался. По умолчанию индикаторный буфер заполняется нулевыми значениями. И, соответственно, DRAW_SECTION рисует черточки между ноликами. Очень-очень много черточек.
Если вставить такой код в секции инициализации, то все зависания при прокрутке графика исчезают.
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0); 
Но, я всё равно считаю, что так быть не должно.
 
Dmitry Fedoseev:
www.mql5.com/ru/code/77
Урок, кстати, в вашей ссылке нереально сложный для новичков.
Не понимаю зачем в нём сразу пишется такой сложный индикатор. Как новичок могу сказать, что мало кто сможет осилить его. Скорее всего, он отобьёт желание у новичка разобраться в MQL, возможно навсегда.
В моём же случае спасло только то, что не стал пытаться его осилить. А учился сам по справочнику. И по кодам из примеров.
 
MisterRight:
Урок, кстати, в вашей ссылке нереально сложный для новичков.
Не понимаю зачем в нём сразу пишется такой сложный индикатор. Как новичок могу сказать, что мало кто сможет осилить его. Скорее всего, он отобьёт желание у новичка разобраться в MQL, возможно навсегда.
В моём же случае спасло только то, что не стал пытаться его осилить. А учился сам по справочнику. И по кодам из примеров.

Мопед не мой, я просто разместил объяву...

MisterRight:

...
Посмотреть код скользящей средней из встроенных индикаторов нельзя, почему так?
...

Это не урок, а библиотека от создателей терминала для самостоятельного расчета средних. 
 
Посмотрите в директории \Indicators\Examples - там есть MACD штатный (два мувинга). Простой мувинг почему-то убрали.
 
//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2020, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."

#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window

#property indicator_buffers 2
#property indicator_plots 1
#property indicator_label1 "SMA"
#property indicator_color1 clrYellow
#property indicator_type1 DRAW_SECTION
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

input int period_sma = 14;

int bars;
double sma_buffer[];
double arr_sma[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {

   SetIndexBuffer(0, sma_buffer, INDICATOR_DATA);
   SetIndexBuffer(1,arr_sma,INDICATOR_CALCULATIONS);

   string short_name=StringFormat("SMA(%d)",period_sma);
   IndicatorSetString(INDICATOR_SHORTNAME,short_name);
   PlotIndexSetString(0,PLOT_LABEL,short_name);
   IndicatorSetInteger(INDICATOR_DIGITS, _Digits);

//--- indicator buffers mapping
   if(period_sma <= 0)
     {
      printf("Некорректное значение периода скользящей средней");
      return INIT_PARAMETERS_INCORRECT;
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//---
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(close,true);
   
   bars = rates_total;//Bars(_Symbol, _Period);
   if(bars < period_sma)
     {
      printf("Слишком мало баров на графике для расчета индикатора");
      return 0;
     }

   double sum=0;
   int k = 0;
   for(int j = bars-1; j >= bars - period_sma; j--)
     {
      arr_sma[k] = NormalizeDouble((high[j] + low[j] + close[j]) / 3, _Digits);
      sum += arr_sma[k];
      sma_buffer[bars-j-1] = sum / (k+1);
      k++;
     }
   k=0;
   for(int i = bars-1 - period_sma; i >=0; i--)
     {
      sum -= arr_sma[k];
      arr_sma[k] = NormalizeDouble((high[i] + low[i] + close[i]) / 3, _Digits);
      sum += arr_sma[k];
      k++;

      if(k==period_sma)
         k=0;

      sma_buffer[bars-i-1] = sum / period_sma;
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

Осмелился немного подрихтовать код. Тормозов ни при перемещении графика на м1 ни в тестере не увидел. Можно еще более экономным сделать если задействовать расчеты только тех участков, которые изменились и только их рисовать. Примеры в терминале есть.

 
Alexandr Gavrilin:

Осмелился немного подрихтовать код. Тормозов ни при перемещении графика на м1 ни в тестере не увидел. Можно еще более экономным сделать если задействовать расчеты только тех участков, которые изменились и только их рисовать. Примеры в терминале есть.

Спасибо)
Но тормоза всё равно есть если в начало истории на м5 или м1 погрузиться, так что, думаю, лучше DRAW_SECTION не использовать.
Зачем arr_sma устанавливать, как индикаторный буфер. Это же статичный массив.

Открой новые возможности в MetaTrader 5 с сообществом и сервисами MQL5
Открой новые возможности в MetaTrader 5 с сообществом и сервисами MQL5
  • 2021.03.13
  • www.mql5.com
MQL5: язык торговых стратегий для MetaTrader 5, позволяет писать собственные торговые роботы, технические индикаторы, скрипты и библиотеки функций