Скачать MetaTrader 5
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Документация доступна в CHM и PDF. Скачай в удобном тебе виде!
Vasyl Nosal
18457
Vasyl Nosal 2016.03.02 15:49  
shanty:
Оно то всё понятно. Но есть один момент. Что если по какой-то причине определённый бар не просчитается ? В тот момент уже будет просчитано баров на 1 больше. Соответственно, будет сдвиг в итарации просчитанных баров. Я понимаю, что обычно подобных вариантов не возникнет, но всё же ситуация может быть подобная. Тогда как быть?

Просто используй мой код.

Я 4 страницы боролся на mql5 с флудерами и модераторами. Итог того что можно выжать это код приведённый выше.

Victor Demihov
618
Victor Demihov 2016.03.03 17:31  

barabashkakvn, ну так вот, например, Василий у себя в коде шаблона индюка, который он выложил тоже накуралесил. Там на каждом тике происходит инициализация массивов буферных и обнуление счётчика counted при условииif (all - counted > 1). Вот так:

if (all - counted > 1)
   {
      ArrayInitialize (up_arr, EMPTY_VALUE);
      ArrayInitialize(down_arr, EMPTY_VALUE);
      counted = 0;
   }

 Я против ничего не имею, Василий смог написать так. Но у меня другие подходы. Предпочитаю писать прямо и читабельно, чтобы всё было красиво. Так вот. Если работать таким образом, используя для подсчёта переменную prev_calculated, то скажу прямо. Реализация конченнейшая. Как я и писал выше. Я сразу написал, что мне интересно работать не со всем графиком, а с его частью. Например, если в терминале имеется история за много лет ТФ=М1. Какой мне резон просчитывать всю историю? Я уже видел, как некоторые индюки просчитываю достаточно длительное время такие промежутки времени. Меня это не далеко вдохновляет. Почему реализация конченная? Покажу на примере:

Есть у меня метод простенький для подсчёта количества баров, которые находятся на графике до заданной в вводном параметре индюка:

//+---------------------------------------------------------------------------------------------------------------------------------------+
//|                                        Проверка общего количества рабочей баровой таймсерии                                           |
//+---------------------------------------------------------------------------------------------------------------------------------------+
int RatesCount()
{
   for (int i = 0; i < Bars - 1; i++)
   {
      currentRatesCount++;                         // Количество рабочей баровой таймсерии
      
      if (i_dtBuffLimitTime >= Time[i])  break;
   }
   return (currentRatesCount);
}

 Так вот, на выходе имеем количество баров, которое необходимо просчитать. Больше мне нафиг не нужно. Особо расписывать всё не буду, а покажу что у меня в 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[])
{
   if (!bootstrap) return(0);
   
   if (lastBarTime != Time[i_TF])
   {
      ratesCount++;                                 // Появился новый бар в рассчитываемой таймсерии
      lastBarTime = Time[i_TF];
   }
      
      int limit = GetRecalcIndex (prev_calculated); // Определим первый расчетный бар
      
      ZigZag (limit);                               // Расчет значений индикатора
   
//--- return value of prev_calculated for next call
   return (rates_total);
}

 

//+---------------------------------------------------------------------------------------------------------------------------------------+
//|                                                       Расчет значений индикатора                                                      |
//+---------------------------------------------------------------------------------------------------------------------------------------+
void ZigZag (int limit)
{
   for (int i = limit; i > 0; i--)                 // По всем новым барам
   {
      if (i == 2)
        Print (__FUNCTION__, " :: ratesCount = ", ratesCount);
      Print (__FUNCTION__, " :: i = ", i);
      int trend = GetTrend(i);                     // Получение направления на баре i
      
      if (trend != tendency[i+1])                  // Направление на текущем баре отличается от направления на предыдущем баре.
      {
         TrendChangeOrMissing (trend, i);          // Возможно, произошла смена тренда
         continue;
      }
      
      tendency[i] = trend;                         // Направление не изменяется
      
      if (trend == TREND_UP)                       // Сохранение восходящего тренда
      {
         CheckHigh(i);                             // Обновление максимума
         continue;
      }
         
      if (trend == TREND_DOWN)                     // Сохранение нисходящего тренда
      {
         CheckLow(i);                              // Обновление минимума
      }
   }
}

 

//+---------------------------------------------------------------------------------------------------------------------------------------+
//|                               Определение индекса бара, с которого необходимо производить перерасчет                                  |
//+---------------------------------------------------------------------------------------------------------------------------------------+
int GetRecalcIndex (const int& prev_calculated)
{
   int countedBars = prev_calculated;
   if (countedBars == 0)                           // Кол-во посчитанных баров - 0. Будут
   {                                               // ..пересчитаны все буфера с самого начала
      Print (__FUNCTION__, " :: at FIRST ; prev_calculated = ", prev_calculated);
      ArrayInitialize (ZZBuf, EMPTY_VALUE);        // Очистка буфера экстремумов Zig-Zag'а
      ArrayInitialize (tendency, 0);               // Обнуление буфера направления движения цены
      return (ratesCount - 2);                     // Начинаем со второго бара истории
   }
   Print (__FUNCTION__, " :: LATER ; prev_calculated = ", prev_calculated);
   Print (__FUNCTION__, " :: LATER ; countedBars = ", countedBars);
   Print (__FUNCTION__, " :: LATER ; ratesCount - countedBars = ", ratesCount - countedBars);
   return (ratesCount - countedBars - 1);          // Начинаем с нового бара
}

 Так вот чётко видно, что в функции ZigZag (int limit) в цикле for (int i = limit; i > 0; i--) я просчитаю только столько баров сколько я получил в результате работы функции RatesCount(), которая отрабатывает в ИНИТЕ. Так вот, при запуске терминала всё просчитывается верно, а дальше начинается полнейшая хрень. Терминал, есс-но не втыкает, что я не нуждаюсь в просчёте всей истории, и возвращает мне на втором тике prev_calculated != ratesCount, как это должно быть, а количество, как я понял, всех баров, которые имеются у меня в истории, есс-но с учётом ограничений заданных в настройках терминала.

Неужели других вариантов нет вообще? 

Vasyl Nosal
18457
Vasyl Nosal 2016.03.03 18:00  

Я пообещал на росийскоязычной части форума не помагать больше, но поскольку это ещё старый разговор, то.

Берёшь мой код

и меняешь

 if(i>Bars-20) i=Bars-20;

 на

 if(i>твои_бары) i=твои_бары;

 

 

 

 

P.S. all - counted может быть только при подкачке истории:)))))))))))))))) 

Alexey Viktorov
5949
Alexey Viktorov 2016.03.03 18:11  
shanty:

barabashkakvn, ну так вот, например, Василий у себя в коде шаблона индюка, который он выложил тоже накуралесил. Там на каждом тике происходит инициализация массивов буферных и обнуление счётчика counted при условииif (all - counted > 1). Вот так:

 Я против ничего не имею, Василий смог написать так. Но у меня другие подходы. Предпочитаю писать прямо и читабельно, чтобы всё было красиво. Так вот. Если работать таким образом, используя для подсчёта переменную prev_calculated, то скажу прямо. Реализация конченнейшая. Как я и писал выше. Я сразу написал, что мне интересно работать не со всем графиком, а с его частью. Например, если в терминале имеется история за много лет ТФ=М1. Какой мне резон просчитывать всю историю? Я уже видел, как некоторые индюки просчитываю достаточно длительное время такие промежутки времени. Меня это не далеко вдохновляет. Почему реализация конченная? Покажу на примере:

Есть у меня метод простенький для подсчёта количества баров, которые находятся на графике до заданной в вводном параметре индюка:

 Так вот, на выходе имеем количество баров, которое необходимо просчитать. Больше мне нафиг не нужно. Особо расписывать всё не буду, а покажу что у меня в OnCalculate() и несколько сопутствующих функциях и что вижу в журнале:

 

 

 Так вот чётко видно, что в функции ZigZag (int limit) в цикле for (int i = limit; i > 0; i--) я просчитаю только столько баров сколько я получил в результате работы функции RatesCount(), которая отрабатывает в ИНИТЕ. Так вот, при запуске терминала всё просчитывается верно, а дальше начинается полнейшая хрень. Терминал, есс-но не втыкает, что я не нуждаюсь в просчёте всей истории, и возвращает мне на втором тике prev_calculated != ratesCount, как это должно быть, а количество, как я понял, всех баров, которые имеются у меня в истории, есс-но с учётом ограничений заданных в настройках терминала.

Неужели других вариантов нет вообще? 

Твоя проблема в этой строке

   for (int i = limit; i > 0; i--)                 // По всем новым барам

В моём графике 5217 баров, этот код обрабатывает только 17 баров и по завершении цикла prev_calculated возвращает 5217, соответственно дальше обрабатывается только последний бар.

 int i, limit = rates_total - prev_calculated-5200;
  
   for(i = limit; i >= 0; i--)
    {
     if(i >= limit - 1) continue;
      Buff[i] = i%5;
    }
   return(rates_total);

Затем, когда появится новый бар, rates_total будет равен 5218 и будет обработано два последних бара первый и нулевой. Дальше prev_calculated вернёт 5218 и всё повторится...

Victor Demihov
618
Victor Demihov 2016.03.04 16:05  
eevviill:

Я пообещал на росийскоязычной части форума не помагать больше, но поскольку это ещё старый разговор, то. 

Мне ты ничего не обещал )) Видать придётся так абы-как и делать, ибо нормально не выйдет. А модераторы молчат, т.к. им сказать по ходу не чего. Бсполезные встроенные переменные висят мёртвым грузом.. Пофиг, пусть пока будет так.

Такое я тоже думал, но я пишу по ходу пьесы всегда всё так, чтоб потом можно было перенести на другую платформу. А с такими кривыми "вкроплениями" придётся по возится чутка больше если что. 

Алексей Тарабанов
7247
Алексей Тарабанов 2016.03.04 19:47  

Функция OnCalculate возвращает: 

 //--- return value of prev_calculated for next call

   return (rates_total);
Алексей Тарабанов
7247
Алексей Тарабанов 2016.03.04 20:13  
eevviill:

Я пообещал на росийскоязычной части форума не помагать больше, но поскольку это ещё старый разговор, то.

Берёшь мой код

и меняешь

 на

 

 

 

 

P.S. all - counted может быть только при подкачке истории:)))))))))))))))) 

 

Я не брал на себя зеркальных обязательств и в курсе дела насчет подкачки истории при обращении к IndicatorCounted (документацию иногда читаю). Но, извините, проблема совсем не в этом. 
Victor Demihov
618
Victor Demihov 2016.03.04 21:10  
tara:

Функция OnCalculate возвращает: 

 //--- return value of prev_calculated for next call

И не в склад и не в лад,.. поцелуй дрова в живот. ВОт..!)))
Алексей Тарабанов
7247
Алексей Тарабанов 2016.03.04 21:50  
Вот, так вот... 
/ /12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий