Новая версия платформы MetaTrader 5 build 2815: Доступ к стакану цен из Python, улучшения в отладчике и профилировщике - страница 7

 
BillionerClub:

Сегодня тоже самое искал но не нашел. В некоторые индикаторах, на высоких таймфремах, вообще ничего не меняется, но многие часы в течении дня  не нужно вызывается функция OnCalculate. Хотя может и есть решение

if(rates_total-prev_calculated == 0) 
  {
   // Новый тик на текущем баре
  }
if(rates_total-prev_calculated == 1) 
  {
   // Новый бар
  }
if(rates_total-prev_calculated > 1) 
  {
   // Первый запуск или изменения в истории
  }

Таким образом, в OnCalculate() можно делать экономные расчёты:

//+------------------------------------------------------------------+
//| 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[])
  {

//+------------------------------------------------------------------+
//| OnCalculate Блок кода для работы с индикатором:                  |
//+------------------------------------------------------------------+
//--- Организация экономных расчётов индикатора
//--- Установка массивов OnCalculate как таймсерий
//--- рассчёт идёт от начала истории до текущих данных + совместимость с MQL4
   ArraySetAsSeries(open,true);
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(close,true);
   ArraySetAsSeries(tick_volume,true);
   ArraySetAsSeries(volume,true);
   ArraySetAsSeries(spread,true);

//--- Установка массивов рисуемых буферов индикатора как таймсерий
   ArraySetAsSeries(Buffer1,true);
   ArraySetAsSeries(Buffer2,true);

//--- Проверка на минимальное количество баров для расчёта
//--- (Не обязательно 2 - количество баров индивидуально для разных индиаторов)
   if(rates_total<2) return 0;

//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated;
//--- Если первый запуск или изменения в истории
   if(limit>1)
     {
      limit=rates_total-1;
      ArrayInitialize(Buffer1,EMPTY_VALUE);
      ArrayInitialize(Buffer2,EMPTY_VALUE);
     }
//--- Подготовка данных
//--- Цикл для расчёта буферов индикатора, на основании значений которых строятся рисуемые буферы
//--- Этот цикл не нужен, если индикатор не строится на предварительно рассчитанных буферах
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      // код для подготовки расчётных буферов индикатора
     }
//--- Расчёт индикатора
//--- Вот здесь внутри можно задать условие, что если limit == 0,
//--- то return(rates_total) - тогда будет производиться расчёт только на открытии нового бара
//--- либо сделать цикл до i>0, но тогда теряется гибкость и универсальность цикла
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      Buffer1[i]=high[i];
      Buffer2[i]=low[i];
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Artyom Trishkin:

Таким образом, в OnCalculate() можно делать экономные расчёты:

Варианты игнорировать очередной(на каждом тике) OnCalculate и принудительно return_ить могут быть индивидуальные, но до появления нового бара товар -  FMCG). И это даже не экономия, а целесообразность - расчёты кривятся.

 
Artyom Trishkin:

Таким образом, в OnCalculate() можно делать экономные расчёты:

Нужно другое решение, таких индикаторов может быть штук 30 и более

 
Mikhail Mishanin:

Варианты игнорировать очередной(на каждом тике) OnCalculate и принудительно return_ить могут быть индивидуальные, но до появления нового бара товар -  FMCG). И это даже не экономия, а целесообразность - расчёты кривятся.

Платформой заложено, что индикаторы срабатывают на каждый тик. И их не пропускают.

В то же время, в OnCalculate() очень просто и быстро обнаружить факт открытия нового бара. Зачем для этого вводить ещё одну бесполезную функцию?

 
BillionerClub:

Нужно другое решение, таких индикаторов может быть штук 30 и более

У меня таких индикаторов - с таким расчётом, написано несколько тысяч. И даже переписанных со старых с иными расчётами. В том числе, и работающих только на открытии бара.

Нужно просто понимать что делаете и сто переделываете.

Впрочем, это уже не по теме.

 
Artyom Trishkin:

У меня таких индикаторов - с таким расчётом, написано несколько тысяч. И даже переписанных со старых с иными расчётами. В том числе, и работающих только на открытии бара.

Нужно просто понимать что делаете и сто переделываете.

Впрочем, это уже не по теме.

Парадокс - у Вас несколько тысяч индикаторов которые ограничивают срабатывание OnCalculate на каждом тике, т.е. работают БЕСПОЛЕЗНО каждый тик чтоб НЕ СРАБОТАТЬ, и Вы при этом утверждаете что событие/функция будет бесполезной. Вчера вообще пришла мысль предложить ввести пользовательское событие с некими настройками на которое сделать возможность подписываться из индикаторов и экспертов. И обойтись тогда во многом без глобальных переменных, файлов и т.п. в пределах одного терминала.

 
Mikhail Mishanin:

Парадокс - у Вас несколько тысяч индикаторов которые ограничивают срабатывание OnCalculate на каждом тике, т.е. работают БЕСПОЛЕЗНО каждый тик чтоб НЕ СРАБОТАТЬ, и Вы при этом утверждаете что событие/функция будет бесполезной. Вчера вообще пришла мысль предложить ввести пользовательское событие с некими настройками на которое сделать возможность подписываться из индикаторов и экспертов. И обойтись тогда во многом без глобальных переменных, файлов и т.п. в пределах одного терминала.

У меня вот такое работает: один эксперт создаёт до тысячи экземпляров объектов, каждый из которых работает как отдельный эксперт, учитывает свои сделки, пишет свои логи и файлы состояния, но все они пользуются общими индикторами.

 
Artyom Trishkin:

У меня таких индикаторов - с таким расчётом, написано несколько тысяч. И даже переписанных со старых с иными расчётами. В том числе, и работающих только на открытии бара.

Нужно просто понимать что делаете и сто переделываете.

Впрочем, это уже не по теме.

В некоторых индикаторах ничего не меняется 1-2 месяца и их пересчет не имеет смысла

Иметь возможность строить независимые от тика,  индикаторы, и иметь глобальное воздействие на индикаторы, запушенные на разных чартах, через сервис, решило бы эти задачи

 
Mikhail Mishanin:

Парадокс - у Вас несколько тысяч индикаторов которые ограничивают срабатывание OnCalculate на каждом тике, т.е. работают БЕСПОЛЕЗНО каждый тик чтоб НЕ СРАБОТАТЬ, и Вы при этом утверждаете что событие/функция будет бесполезной. Вчера вообще пришла мысль предложить ввести пользовательское событие с некими настройками на которое сделать возможность подписываться из индикаторов и экспертов. И обойтись тогда во многом без глобальных переменных, файлов и т.п. в пределах одного терминала.

OnCalculate() - системная функция, обрабатывающая событие Calculate. Она срабатывает на каждом тике.
И выход из расчётов не создаёт проблем и бесполезной работы - индикатор просто не рассчитывается и не перерисовывается.
Но системная функция обязана сработать на каждый тик. И уже вам решать - обработать этот тик, или нет.

Но за вас, и для вас никто не будет делать экономного расчёта в ваших собственных программах - вам дали инструмент, и вам решать как его использовать, особенно тогда, когда всё для этого есть.

Документация по MQL5: Обработка событий / OnCalculate
Документация по MQL5: Обработка событий / OnCalculate
  • www.mql5.com
OnCalculate - Обработка событий - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Renat Fatkhullin
Куда мне писать по поводу найденной ошибке в описании? А то куда не пишу везде игнорируют.
Причина обращения: