Не отображается индикатор..... ошибка в ДНК или "неправильные пчелы", помогите определиться )

 

Возможно уже было, но..... нашел только про "правильно-не-правильно", у меня другая проблема.

Написал индикатор, который должен.... впрочем, код выкладываю, - там все откомментировано.
Работает корректно, считает все правильно (листинг значений переменных выводил - ошибок нет - все пишется куда и как нужно)

Проблемы:
- режим визуализации: после прикрепления к графику - не отображается, причем, независимо от того вызывается он в эксперте или нет. По "стоп" визуализации, если вызывался в эксперте, то тут же отображается (.... ну "как надо" все - Pic1,2).

Когда бросаешь на статический график любого таймфрейма, тоже все нормально (Pic3,4). Картинки загрузить не получилось - в аттаче есть + простой фрактал с той же логикой (для проверки).


В общем, в поисках ошибки извилину единственную уже выпрямил, помощи прошу.... дальше сдвинуться не могу, очень не хочется случайные (?) результаты вслепую обрабатывать.

Файлы:
work.rar  102 kb
 

PS. ... и код целиком не грузиться, хотя и не большой, двумя частями покажу

Part One


//--------------------------------------------------------------------
// i_Model_Fractal_3in1.mq4
// Мультифреймовый Фрактальный ZigZag
// Работает со всеми, в т.ч. и нестандартными таймфреймами,
// Ограничения:
// - старшие ТФ должны быть кратны рабочему
// - рабочий ТФ <= самому мелкому из старших
// - TFSmall < TFMidle && TFMidle < TFLarge
// - TFLarge <=43200 (месяц) 
//--------------------------------------------------------------------
#property copyright "Copyright © 2008, BiViSi Corp."
#property link      "riderfin@bk.ru"
#property link      "ICQ 499949112"
 
#property indicator_chart_window    
#property indicator_buffers 3       
//---- стиль  индикаторной линии
#property indicator_color1 Blue 
#property indicator_color2 Red
#property indicator_color3 Yellow        
#property indicator_style1 0
#property indicator_style2 0
#property indicator_style3 0
#property indicator_width1 3
#property indicator_width2 2
#property indicator_width3 1
//---- ВХОДНЫЕ ПАРАМЕТРЫ ИНДИКАТОРА 
extern int TFLarge=1440;
extern int TFMidle=240;
extern int TFSmall=60;
 
double Large[],Midle[], Small[]; // Объявление массивов (под буферы индикатора)
datetime PrevTimePer[4]; // Массив под времена последнего расчета по каждому ТФ
static datetime PrevTimeCalc; 
static int CurPeriod;
//--------------------------------------------------------------------
int init() 
{
   SetIndexBuffer(0,Large); SetIndexStyle(0,DRAW_SECTION); SetIndexEmptyValue(0,0.0);
   SetIndexBuffer(1,Midle); SetIndexStyle(1,DRAW_SECTION); SetIndexEmptyValue(1,0.0); 
   SetIndexBuffer(2,Small); SetIndexStyle(2,DRAW_SECTION); SetIndexEmptyValue(2,0.0);
   PrevTimeCalc=0; 
   ArrayInitialize(PrevTimePer,0);
   CurPeriod=Period();
   return;              
}
//--------------------------------------------------------------------
int start()
{
   // контроль ТФ и введенных параметров - 
   // ????????????????????????  это можно вынести в init ?????????????????????????????
   if (CurPeriod > TFSmall) {Alert ("Период графика должен быть меньше или равен ", TFSmall, " мин.");return;}
   if (TFSmall >= TFMidle || TFMidle >= TFLarge || TFLarge>43200 ||
       MathCeil(TFSmall/CurPeriod) != TFSmall/CurPeriod || MathCeil(TFMidle/CurPeriod) != TFMidle/CurPeriod ||
       MathCeil(TFLarge/CurPeriod) != TFLarge/CurPeriod) {Alert ("Некорректный выбор таймфреймов для расчета!!!");return;}
   
   // Непосредственно "наше ВСЁ"     
   FractalCalc(); // вычисление 5-ти барных фракталов на старших таймфреймах по барам текущего
   //ClearFractal(); // очистка (удаление) лишних экстремумов, для формирования правильного зигзага
                   // если эту функцию закомментить, то код совсем коротенький будет, но все равно
                   // как надо не отображается - этот кусок не показываю
   return;
}
 

Part Two


//======================================================================
// вычисление узлов зигзага на эмуляции старших ТФ и отображение на текущем
//======================================================================
void FractalCalc ()
{   
   // не использую  конструкцию типа int IC=IndicatorCounted(); и т.д.
   // как-то слабо представляю нужна ли она здесь и как ее сюда вставить...... ???????
   // 
   // без нее все достаточно экономно, но сомнения есть........
   
   // Экономия №1 - вычисление один раз только на полностью сформировавшемся баре рабочего ТФ
   if (PrevTimeCalc == Time[0]) return; else PrevTimeCalc=Time[0];
   int VolExt=150, NumberExt, Per; // вычисление "VolExt+1" последних фракталов (без учета последующей очистки)   
   int y, x, k, i, j;
   int t1, t2, t3, t4, t5;                     // время последнего бара тек ТФ, закрывающего бар №1-5 старшего ТФ
   int limit1, limit2, limit3, limit4, limit5; // номер последнего бара тек ТФ, закрывающего бар №1-5 старшего ТФ
   int up1,up2,up3,up4,up5,dn1,dn2,dn3,dn4,dn5;// номера баров тек ТФ с пиками и донышками соотв барам 1-5 старшего ТФ
   for (y=1; y<=3; y++) // цикл по рассчитываемым ТФ
      {
      if (y==1) Per=TFLarge; if (y==2) Per=TFMidle; if (y==3) Per=TFSmall;
      // Экономия №2 - Вычисляем потенциальные изломы только с окончанием формирования бара старшего ТФ
      if (PrevTimePer[y] !=0)
         { 
         if (Per<43200 && (TimeCurrent()- TimeSeconds(PrevTimePer[y]))<Per*60 )continue;
         if (Per==43200 && Month()==TimeMonth(PrevTimePer[y]))continue;
         }
      PrevTimePer[y]=Time[0]; 
      // инициализация.... если использовать IndicatorCounted(), то эту строку нужно убирать
      if (y==1) ArrayInitialize(Large,0.0); if (y==2) ArrayInitialize(Midle,0.0); if (y==3) ArrayInitialize(Small,0.0);
      NumberExt=0;
      k=Per/CurPeriod;
      i=MathCeil(Bars/k)-5; // ограничение цикла - в зависимости от того какой ТФ обсчитываем
      for (x=1; x<=i; x++) 
         {
         // находим пики и донышки
         t1=MathCeil(TimeCurrent()/Per/60)*Per*60-x*Per*60+(k-1)*CurPeriod*60; // время начала последнего бара тек ТФ, закрывающего бар №1 старшего ТФ
         t2=t1-k*CurPeriod*60; t3=t2-k*CurPeriod*60; t4=t3-k*CurPeriod*60; t5=t4-k*CurPeriod*60;
         limit1=iBarShift(NULL,0,t1); limit2=iBarShift(NULL,0,t2); limit3=iBarShift(NULL,0,t3);
         limit4=iBarShift(NULL,0,t4); limit5=iBarShift(NULL,0,t5);         
         up1=iHighest(NULL,0,MODE_HIGH,k,limit1);up2=iHighest(NULL,0,MODE_HIGH,k,limit2);up3=iHighest(NULL,0,MODE_HIGH,k,limit3);
         up4=iHighest(NULL,0,MODE_HIGH,k,limit4);up5=iHighest(NULL,0,MODE_HIGH,k,limit5);
         dn1=iLowest(NULL,0,MODE_LOW,k,limit1);dn2=iLowest(NULL,0,MODE_LOW,k,limit2);dn3=iLowest(NULL,0,MODE_LOW,k,limit3);
         dn4=iLowest(NULL,0,MODE_LOW,k,limit4);dn5=iLowest(NULL,0,MODE_LOW,k,limit5);
         // ищем фракталы
         if(High[up3]>High[up2] && High[up3]>High[up1] && High[up3]>=High[up4] && High[up3]>=High[up5])
            {
            if (y==1)Large[up3]=High[up3]; if (y==2)Midle[up3]=High[up3]; if (y==3) Small[up3]=High[up3];    
            NumberExt++;
            }
         if(Low[dn3]<Low[dn2] && Low[dn3]<Low[dn1] && Low[dn3]<=Low[dn4] && Low[dn3]<=Low[dn5])
            {
            if (y==1)Large[dn3]=Low[dn3]; if (y==2)Midle[dn3]=Low[dn3]; if (y==3) Small[dn3]=Low[dn3];    
            NumberExt++;
            }
         if (NumberExt>VolExt) break;
         }         
      }
   return;
}
 

Хорошо работает. Аккуратно написано => ДНК Ok!
Отображается только на Н1


Этот код заморочен, подчеркнутое всегда истинно (В выходные отдыхать надо)))


if (TFSmall >= TFMidle || TFMidle >= TFLarge || TFLarge>43200 ||
       MathCeil(TFSmall/CurPeriod) != TFSmall/CurPeriod || MathCeil(TFMidle/CurPeriod) != TFMidle/CurPeriod ||
       MathCeil(TFLarge/CurPeriod) != TFLarge/CurPeriod)
 

Если так, то отображается везде где разрешено кроме М1. (М5, М15, М30, Н1 - О.k)
Т.е. Вы наткнулись на такую особенность: если индиктор пропустил тик, то его данные пропадают.

// if (PrevTimeCalc == Time[0]) return; else PrevTimeCalc=Time[0];
P.S. Расчет индикатора очень*быстрый, ускорения не требует, => ограничениями можно не грузиться.
Разве что длину истории ограничить например до 1500, и то вроде как не требуется.
 
Korey:

Хорошо работает. Аккуратно написано => ДНК Ok!
Отображается только на Н1


Этот код заморочен, подчеркнутое всегда истинно (В выходные отдыхать надо)))


if (TFSmall >= TFMidle || TFMidle >= TFLarge || TFLarge>43200 ||
       MathCeil(TFSmall/CurPeriod) != TFSmall/CurPeriod || MathCeil(TFMidle/CurPeriod) != TFMidle/CurPeriod ||
       MathCeil(TFLarge/CurPeriod) != TFLarge/CurPeriod)

:) старался - мне эта беда спать уже не дает....  и все-таки:

- в приведенном куске кода никаких заморочек, я писал в комменте, что TFLarge, TFMidle, TFSmall могут быть нестандартными (например: рабочий -  30, а TFLarge ошибочно выставлен не кратным ему  - 1000.....), впрочем, это мелочь

- не понял что означает "хорошо" работает и "Отображается только на Н1" - хорошо работает, это когда получаешь то что хочешь, а япосле вашего поста еще раз проверил - все как было так и осталось ).... а отображается он не только на H1, везде, вот только либо постфактум, либо на статике....

 

 
Korey:

Если так, то отображается везде где разрешено кроме М1. (М5, М15, М30, Н1 - О.k)
Т.е. Вы наткнулись на такую особенность: если индиктор пропустил тик, то его данные пропадают.

// if (PrevTimeCalc == Time[0]) return; else PrevTimeCalc=Time[0];
P.S. Расчет индикатора очень*быстрый, ускорения не требует, => ограничениями можно не грузиться.
Разве что длину истории ограничить например до 1500, и то вроде как не требуется.

пока писал пропустил вот это, сейчас осмыслю

 

to rider

1. Проверил на реале, кроме М1 все прекрасно, просто отлично. Почему М1 не отображает пока не понятно.
2. если юзером ввeдены неправильные настройки, то чем отказываться от работы проще установить их по умолчанию.

 
Korey:

to rider

1. Проверил на реале, кроме М1 все прекрасно, просто отлично. Почему М1 не отображает пока не понятно.
2. если юзером ввeдены неправильные настройки, то чем отказываться от работы проще установить их по умолчанию.

на М1 тоже отображается - график назад прокрутите )

но с визуализацией (я имею ввиду тестирование) проблема так и осталась: if (PrevTimeCalc == Time[0]) return; else PrevTimeCalc=Time[0]; - закомментарил, но все осталось попрежнему

Да и не должна эта строка мешать.... ну пропустил тик, так на следующем посчитает.....

 

без экономии времени стоит как вкопанный.
Включаем экономию - на первый тик есть отображение, затем исчезает.
Для безопасной работы в поиск бара лучше добавить FALSE

limit1=iBarShift(NULL,0,t1,FALSE); limit2=iBarShift(NULL,0,t2,FALSE); limit3=iBarShift(NULL,0,t3,FALSE);
         limit4=iBarShift(NULL,0,t4,FALSE); limit5=iBarShift(NULL,0,t5,FALSE);
 
Korey:

без экономии времени стоит как вкопанный.
Включаем экономию - на первый тик есть отображение, затем исчезает.
Для безопасной работы в поиск бара лучше добавить FALSE

limit1=iBarShift(NULL,0,t1,FALSE); limit2=iBarShift(NULL,0,t2,FALSE); limit3=iBarShift(NULL,0,t3,FALSE);
         limit4=iBarShift(NULL,0,t4,FALSE); limit5=iBarShift(NULL,0,t5,FALSE);

у меня работает (сore duo 2400, 2GB), правда процессор % на 80 грузит, только все равно ни на первом, ни дальше ничего не отображает.

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

Причина обращения: