Скачать MetaTrader 5

Как найти фрактал?

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Нет времени на изучение MQL5? Закажи приложение у разработчика!
Andrey Asafov
240
Andrey Asafov 2010.10.15 10:28 

Необходимо найти самый первый от текущего бара фрактал. Код:

int Fractal;
int OnInit()
{
    Fractal=iFractals(_Symbol, _Period);
    return(0);
}

void OnTick()
{
    double FractalDown[], FractalUp[], price;
    int i;
    string txt;
    CopyBuffer(Fractal, 0, 0, Bars(_Symbol, _Period), FractalUp);
    CopyBuffer(Fractal, 1, 0, Bars(_Symbol, _Period), FractalDown);
    for(i=0; i<Bars(_Symbol, _Period); i++)
    {
        if(FractalUp[i]>0)
        {
            price=FractalUp[i];
            txt="Фрактал найден сверху";
            break;
        }
        if(FractalDown[i]>0)
        {
            price=FractalDown[i];
            txt="Фрактал найден снизу";
            break;
        }
    }
    Alert(txt,"Значение=",price,"Номер бара=",i);
}

После запуска выдаётся сообщение

"Фрактал найден сверху Значение=1.797693134862316e+308 Номер бара=0"

Подскажите, в чём ошибка?

Дмитрий Александрович
1705
Дмитрий Александрович 2010.10.15 10:40  
AsAn:

Необходимо найти самый первый от текущего бара фрактал. Код:

После запуска выдаётся сообщение

"Фрактал найден сверху Значение=1.797693134862316e+308 Номер бара=0"

Подскажите, в чём ошибка?


---Тут я написал какую-то чушь :)---
Rashid Umarov
Админ
11815
Rashid Umarov 2010.10.15 10:44  

Поиск по числу (https://www.mql5.com/ru/search?keyword=1.797693134862316e%2B308) выдает статью Индикатор от индикатора в MQL5. В ней есть объяснение:

Пустые значения в индикаторных буферах и DBL_MAX

Первые 14 элементов массива price[] с индексами от 0 до 13 включительно содержат одно и то же значение, равное 1.797693134862316e+308. Вы будете часто встречаться с этим числом, потому что это значение встроенной константы EMPTY_VALUE, специально предусмотренной для выделения пустых значений в индикаторном буфере.

Заполнять пустые значения нулями не является универсальным решением, так как некоторые индикаторы выдают это значение  как допустимое.  Именно по этой причине все встроенные в терминал индикаторы выдают для пустых значений именно это число. Величина 1.797693134862316e+308 для этих целей была выбрана не случайно, так как это максимально возможное значение для типа double и для  удобства в языке MQL5 оно представлено специальной константой DBL_MAX.

Если вы хотите проверить, не является ли некое число типа double пустым значение, то вы можете сравнить его либо с константой EMPTY_VALUE либо с константой DBL_MAX. Оба варианта равносильны, но использование константы EMPTY_VALUE для задания пустого значения предпочтительнее для лучшей читаемости кода.

Кроме  того, есть пример поиска фракталов и в Документации в разделе Способы привязки объектов:

void OnStart()
  {
//--- служебные массивы
   double Ups[],Downs[];
   datetime Time[];
//--- установим для массивов признак таймсерии
   ArraySetAsSeries(Ups,true);
   ArraySetAsSeries(Downs,true);
   ArraySetAsSeries(Time,true);
//--- создадим хэндл индикатора Fractals
   int FractalsHandle=iFractals(NULL,0);
   Print("FractalsHandle = ",FractalsHandle);
//--- сбросим код ошибки
   ResetLastError();
//--- попытаемся скопировать значения индикатора
   int copied=CopyBuffer(FractalsHandle,0,0,1000,Ups);
   if(copied<=0)
     {
      Print("Не удалось скопировать верхние фракталы. Error = ",GetLastError());
      return;
     }
 
   ResetLastError();
//--- попытаемся скопировать значения индикатора
   copied=CopyBuffer(FractalsHandle,1,0,1000,Downs);
   if(copied<=0)
     {
      Print("Не удалось скопировать нижние фракталы. Error = ",GetLastError());
      return;
     }
 
   ResetLastError();
//--- скопируем таймсерию,содержащую время открытия последних 1000 баров
   copied=CopyTime(NULL,0,0,1000,Time);
   if(copied<=0)
     {
      Print("Не удалось скопировать времена открытия за последние 1000 баров");
      return;
     }
 
   int upcounter=0,downcounter=0; // будем в них подсчитывать количество стрелок
   bool created;// будем получать результат попытки создания объекта
   for(int i=2;i<copied;i++)// пробежимся по значениям индикатора iFractals
     {
      if(Ups[i]!=EMPTY_VALUE)// нашли верхний фрактал
        {
         if(upcounter<10)// создаем не более 10 объектов "вверх"
           {
            //--- попробуем создать объект "вверх"
            created=ObjectCreate(0,string(Time[i]),OBJ_ARROW_THUMB_UP,0,Time[i],Ups[i]);
            if(created)// если создался - сделаем ему тюнинг
              {
               //--- точка привязки снизу, чтобы не наезжать на бар
               ObjectSetInteger(0,string(Time[i]),OBJPROP_ANCHOR,ANCHOR_BOTTOM);
               //--- последний штрих - покрасим
               ObjectSetInteger(0,string(Time[i]),OBJPROP_COLOR,Blue);
               upcounter++;
              }
           }
        }
      if(Downs[i]!=EMPTY_VALUE)// нашли нижний фрактал 
        {
         if(downcounter<10)// создаем не более 10 объектов "вниз"
           {
            //--- попробуем создать объект "вниз"
            created=ObjectCreate(0,string(Time[i]),OBJ_ARROW_THUMB_DOWN,0,Time[i],Downs[i]);
            if(created)// если создался - сделаем ему тюнинг
              {
               //--- точка привязки сверху, чтобы не наезжать на бар
               ObjectSetInteger(0,string(Time[i]),OBJPROP_ANCHOR,ANCHOR_TOP);
               //--- последний штрих - покрасим
               ObjectSetInteger(0,string(Time[i]),OBJPROP_COLOR,Red);
               downcounter++;
              }
           }
        }
     }
  }



Andrey Asafov
240
Andrey Asafov 2010.10.15 16:33  
Rosh:

Поиск по числу (https://www.mql5.com/ru/search?keyword=1.797693134862316e%2B308) выдает статью Индикатор от индикатора в MQL5. В ней есть объяснение:

Кроме  того, есть пример поиска фракталов и в Документации в разделе Способы привязки объектов:



Спасибо, разобрался.

Вот в такой реализации получаю нужные мне результаты:

int Fractal;
int OnInit()
{
    Fractal=iFractals(_Symbol, _Period);
    return(0);
}

void OnTick()
{
    double FractalDown[], FractalUp[], price;
    int i;
    string txt;
    CopyBuffer(Fractal, 0, 0, Bars(_Symbol, _Period), FractalUp);
    CopyBuffer(Fractal, 1, 0, Bars(_Symbol, _Period), FractalDown);
    ArraySetAsSeries(FractalUp);
    ArraySetAsSeries(FractalDown);
    for(i=0; i<Bars(_Symbol, _Period); i++)
    {
        if(FractalUp[i]!=EMPTY_VALUE)
        {
            price=FractalUp[i];
            txt="Фрактал найден сверху";
            break;
        }
        if(FractalDown[i]!=EMPTY_VALUE)
        {
            price=FractalDown[i];
            txt="Фрактал найден снизу";
            break;
        }
    }
    Alert(txt,"Значение=",price,"Номер бара=",i);
}


Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий