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

 
lynxntech #:
зачем тут 2 раза вызывается функция?
Обсчитывает текущий бар, и закрытый предыдущий, иначе индикатор "плывёт" на различных моделях тестера (по ценам открытия и тд.) и реале
 
Aleksei Stepanenko #:
Обсчитывает текущий бар, и закрытый предыдущий, иначе индикатор "плывёт" на различных моделях тестера (по ценам открытия и тд.) и реале

т.е. обрабатываются только 2 бара свежих всегда, остальное надежда на терминал

 

Яндекс тоже с ума сходит



 
lynxntech #:

зачем тут 2 раза вызывается функция?

Работает точно так-же, как вот этот код. Только, как по мне, вариант со switch гораздо более очевидный и читаемый.

Предстасьте тот код в следующем виде:

//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-1;
      ArrayInitialize(BufferXXX,EMPTY_VALUE); // инициализация буферов начальными значениями
     }
//--- Цикл
   for(int i=limit; i>=0 && !IsStopped(); i--)
      calculate(i);

Представьте, что rates_total = 100, а prev_calculated = 101. Тогда цикл for превратится в это:

calculate(1);
calculate(0);
lynxntech #:
нет проверки на изменение истории, кто знает когда она может понадобиться.

Вот она:

   switch(rates_total - prev_calculated)
     {
      case 0:
         calculate(0);
         break;
      case 1:
         calculate(1);
         calculate(0);
         break;
      default:
         // Здесь буфферы будут предварительно инициализированы пустым значением (это псевдокод)
         for(int i = rates_total - 1; i >= 0; i--)
            calculate(i);
         break;
     }
 
Vladislav Boyko #:

Работает точно так-же, как вот этот код. Только, как по мне, вариант со switch гораздо более очевидный и читаемый.

Предстасьте тот код в следующем виде:

Представьте, что rates_total = 100, а prev_calculated = 101. Тогда цикл for превратится в это:

Вот она:

Не дорого функцию вызывать?

В кейсах можно лимиты обозначить одной строкой и далее цикл без функции, если код небольшой, должно быть быстрее

 
Vladislav Boyko #:
Я в свое время с большим трудом понял логику вычислений переменной limit

Ниже код встроенного в МТ4 MACD

   int i,limit;
//--- last counted bar will be recounted
   limit=rates_total-prev_calculated;
   if(prev_calculated>0)
      limit++;
//---
   for(i=0; i<limit; i++)
      ExtMacdBuffer[i]=iMA(NULL,0,InpFastEMA,0,MODE_EMA,PRICE_CLOSE,i)-iMA(NULL,0,InpSlowEMA,0,MODE_EMA,PRICE_CLOSE,i);

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

 
lynxntech #:
Не дорого функцию вызывать?

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

Дороже писать километровые функции. Чем длиннее становится ваш код, тем более безумной становится идея отказываться от разбиения на функции (хотя такая идея является безумной по своей сути).

Не даром умные дядьки советуют разбивать функции, которые не помещаются на экран. "Не помещается на один экран" - уже достаточно веский повод что бы из одной фунции сделать несколько.

lynxntech #:
В кейсах можно лимиты обозначить одной строкой и далее цикл без функции, если код небольшой, должно быть быстрее

Нет смысла задумываться о производительности говоря о таких вещах. Вы не сможете измерить разницу в скорости работы варианта со switch и варианта с циклом. Потому что разницы нет.

Для меня преимущество варианта со switch заключается в том, что он более читаемый и так гораздо меньше шансов случайно сделать баг. Возможно, это субъективная история. Возможно, для кого-то limit + цикл выглядит понятней/очевидней.


А что касается вот этого

То тех форс-мажоров не должно происходить нахрен вообще. А если уже и произошло (очень редкое событие), то ничего страшного, что индикатор потратит пару десятков лишних миллисекунд раз в полгода. Зато после форс-мажора значения буфферов точно будут корректными.
 
Vladislav Boyko #:

Работает точно так-же, как вот этот код. Только, как по мне, вариант со switch гораздо более очевидный и читаемый.

Предстасьте тот код в следующем виде:

Представьте, что rates_total = 100, а prev_calculated = 101. Тогда цикл for превратится в это:

Вот она:

Это где можно такое посмотреть? Когда бывает так, чтобы посчитанных баров было больше чем есть на графике???

И вот ещё тема для обсуждения:

Код из вашего сообщения

//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-1;
      ArrayInitialize(BufferXXX,EMPTY_VALUE); // инициализация буферов начальными значениями
     }
//--- Цикл
   for(int i=limit; i>=0 && !IsStopped(); i--)
      calculate(i);

Зачем заполнять массив пустым значением или нулём перед заполнением рабочими значениями? Ведь по любому будет перебор всех баров и весь буфер будет заполнен…

 
Alexey Viktorov #:

Это где можно такое посмотреть? Когда бывает так, чтобы посчитанных баров было больше чем есть на графике???

Встречается такая проверка в кодах, может когда-то имело место быть, а может и сейчас актуально, темный лес тут, вроде копеечная проверка, можно и включить ее

 
lynxntech #:

Встречается такая проверка в кодах, может когда-то имело место быть, а может и сейчас актуально, темный лес тут, вроде копеечная проверка, можно и включить ее

В mql3 и не такое могло быть. Но это не значит, что и в mql5 сейчас надо делать такую проверку.