Обсуждение статьи "Поиск свечных паттернов с помощью MQL5"

 

Опубликована статья Поиск свечных паттернов с помощью MQL5:

В этой статье мы поговорим о том, как автоматически определять свечные паттерны с помощью MQL5.

  • Паттерн "Просвет в облаках"

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

Piercing line (Просвет в облаках)

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

Автор: Mohamed Abdelmaaboud

 

советник не работает на графике

 

Действительно, ничего не работает ни как Советник ни как Индикатор.

Вообще ничего не показывает. Ни Реал ни на Истории.

 
Спасибо за ваши добрые комментарии. Если вы скачаете прикрепленные к статье файлы, они будут рабочими. Вы можете загрузить и протестировать их из исходного кода, и вы найдете сигнал каждой описанной свечи, появляющийся на графике, как указано в статье. Я перепроверил их после загрузки и обнаружил, что они работают.
 
Я так понял Эксперт начинает работать только с момента его добавления на график, и он не показывает уже на прошедшей истории. У меня он заработал на 1мин ТаймФрейме. Добавил все остальные чтобы убедиться, что они работают.    Спасибо за ответ.
 
А почему вы сделали это как Советник, ведь он не торгует а всего лишь ищет и показывает. Также если пробую добавить на график сразу все ваши Советники то наверное есть ограничение в МТ5, так как при добавлении нового удаляет один из предыдущего, не больше 2 разрешает. Значит появляется логический вывод, что это должен быть Индикатор, и желательно один а не несколько. А уже потом на него ссылаться из Кода Советника для выставления Ордеров. Может вы попробуете переделать. Спасибо Огромное.
 
Спасибо за ваш комментарий. Сначала мне нужно уточнить, что вы можете сделать это так, как вам нужно, это может быть индикатор, который может обнаружить и показать их, или советник, который может дать вам необходимые действия, такие как торговля, если вы хотите, и вы можете объединить их в продвинутый советник. чтобы получить их все при правильном исполнении, которые будут прикреплены к графику как один советник. здесь нет правды или лжи, цель здесь только образовательная, чтобы поделиться тем, как мы можем кодировать эти типы моделей свечей, после чего вы можете использовать их в своей подходящей программе, будь то индикатор или советник.
 
Mohamed Abdelmaaboud #:
Спасибо за ваш комментарий. Сначала мне нужно уточнить, что вы можете сделать это так, как вам нужно, это может быть индикатор, который может обнаружить и показать их, или советник, который может дать вам необходимые действия, такие как торговля, если вы хотите, и вы можете объединить их в продвинутый советник. чтобы получить их все при правильном исполнении, которые будут прикреплены к графику как один советник. здесь нет правды или лжи, цель здесь только образовательная, чтобы поделиться тем, как мы можем кодировать эти типы моделей свечей, после чего вы можете использовать их в своей подходящей программе, будь то индикатор или советник.

Я так и сделал, объединил все в один советник. Но когда попробовал записать как Индикатор, в терминале всё равно загружается как Советник. Что-то нужно менять в Коде, но что именно я не знаю, не сильно разбираюсь. Ещё я заметил, что нужна его доработка в плане, что когда меняется Тайм Фрейм, на другой то сигнал остаётся на графике и уже на новом не соответствует бару на том же месте. По идее при смене нужно, чтобы удалялся или сохранялся только на том Тайм Фрейме где он был обнаружен. На всякий случай выставлю собраный мой Код, посмотрите что можно подправить или оптимизировать, я всего лишь скопировал со всех советников в один, но думаю там можно объявить некоторые переменные в начале, чтобы не повторяться в Коде несколько раз.   

//+------------------------------------------------------------------+
//|                                                PATTERN-INDIK.mq5 |
//|                                            Copyright 2023,VIKTOR |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023,VIKTOR"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+ createObj1 = Doji                                                |
//+ createObj2 = Hammer                                              |
//+ createObj3 = Engulfing                                           |
//+ createObj4 = Piercing                                            |
//+ createObj5 = Star                                                |
//+ createObj6 = threeInside                                         |
//+------------------------------------------------------------------+
void OnTick()
  {
   getDoji();
   getHammer(0.07,0.7);
   getEngulfing();
   getPiercing();
   getStar(0.5);
   getthreeInside();
  }
int getDoji()
  {
   datetime time  =iTime  (_Symbol,PERIOD_CURRENT,1);
   double   open  =iOpen  (_Symbol,PERIOD_CURRENT,1);
   double   high  =iHigh  (_Symbol,PERIOD_CURRENT,1);
   double   low   =iLow   (_Symbol,PERIOD_CURRENT,1);
   double   close =iClose (_Symbol,PERIOD_CURRENT,1);
   
//Doji
   if(open==close)
     {
      createObj1a(time,low,217, clrBlack,"Doji");
        {
         return 1;
        }
     }
   return 0;
  }
void createObj1a(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal at ",time, " at ",DoubleToString(price,_Digits)," (",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }
//+------------------------------------------------------------------+
int getHammer(double smallShadowRatio, double longShadowRatio)
  {
//creating variables for prices data - open,  high, low, close
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double candleSize=high-low;
//green hammer
   if(open<close)
     {
      if(high-close < candleSize*smallShadowRatio)
        {
         if(open-low>candleSize*longShadowRatio)
            createObj2(time,low,217, clrGreen,"Hammer");
           {
            return 1;
           }
        }
     }
//red hammer
   if(open>close)
     {
      if(high-open<candleSize*smallShadowRatio)
        {
         if(close-low>candleSize*longShadowRatio)
            createObj2(time,high,218,clrRed,"Hammer");
           {
            return 1;
           }
        }
     }
//green inverse hammer
   if(open<close)
     {
      if(open-low < candleSize*smallShadowRatio)
        {
         if(high-close>candleSize*longShadowRatio)
            createObj2(time,low,217, clrGreen,"Inverted Hammer");
           {
            return -1;
           }
        }
     }
//red inverse hammer
   if(open>close)
     {
      if(close-low < candleSize*smallShadowRatio)
        {
         if(high-open>candleSize*longShadowRatio)
            createObj2(time,high,218, clrRed,"Inverted Hammer");
           {
            return -1;
           }
        }
     }
   return 0;
  }
void createObj2(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }
//+------------------------------------------------------------------+
int getEngulfing()
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   if(open<close)
     {
      if(open2>close2)
        {
         if(high>high2&&low<low2)
           {
            if(close>open2&&open<close2)
              {
               createObj3(time,low,217, clrGreen,"Bullish Engulfing");
                 {
                  return 1;
                 }
              }
           }
        }
     }
   if(open>close)
     {
      if(open2<close2)
        {
         if(high>high2&&low<low2)
           {
            if(close<open2&&open>close2)
              {
               createObj3(time,high,218, clrRed,"Bearish Engulfing");
                 {
                  return -1;
                 }
              }
           }
        }
     }
   return 0;
  }
void createObj3(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }
//+------------------------------------------------------------------+
int getPiercing()
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   double candleSize2=high2-low2;
   double candleMidPoint2=high2-(candleSize2/2);
   if(open<close)
     {
      if(open2>close2)
        {
         if(open<low2)
           {
            if(close>candleMidPoint2&&close<high2)
              {
               createObj4(time,low,217, clrGreen,"Piercing");
                 {
                  return 1;
                 }
              }
           }
        }
     }
   if(open>close)
     {
      if(open2<close2)
        {
         if(open>high2)
           {
            if(close<candleMidPoint2&&close>low2)
              {
               createObj4(time,high,218, clrRed,"Dark Cloud");
                 {
                  return -1;
                 }
              }
           }
        }
     }
   return 0;
  }
void createObj4(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }
//+------------------------------------------------------------------+
int getStar(double middleCandleRatio)
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   double open3=iOpen(_Symbol,PERIOD_CURRENT,3);
   double high3=iHigh(_Symbol,PERIOD_CURRENT,3);
   double low3=iLow(_Symbol,PERIOD_CURRENT,3);
   double close3=iClose(_Symbol,PERIOD_CURRENT,3);
   double candleSize=high-low;
   double candleSize2=high2-low2;
   double candleSize3=high3-low3;
   if(open<close)
     {
      if(open3>close3)
        {
         if(candleSize2<candleSize*middleCandleRatio && candleSize2<candleSize3*middleCandleRatio)
           {
            createObj5(time,low,217, clrGreen,"Morning Star");
              {
               return 1;
              }
           }
        }
     }
   if(open>close)
     {
      if(open3<close3)
        {
         if(candleSize2<candleSize*middleCandleRatio && candleSize2<candleSize3*middleCandleRatio)
           {
            createObj5(time,high,218, clrRed,"Evening Star");
              {
               return -1;
              }
           }
        }
     }
   return 0;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void createObj5(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }
//+------------------------------------------------------------------+
int getthreeInside()
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   double open3=iOpen(_Symbol,PERIOD_CURRENT,3);
   double high3=iHigh(_Symbol,PERIOD_CURRENT,3);
   double low3=iLow(_Symbol,PERIOD_CURRENT,3);
   double close3=iClose(_Symbol,PERIOD_CURRENT,3);
   if(open3>close3)
     {
      if(open2<close2)
        {
         if(open2>low3&&close2<high3)
           {
            if(open<close&&open>open2&&open<close2)
              {
               if(close>high3)
                 {
                  createObj6(time,low,217, clrGreen,"3 Inside Up");
                    {
                     return 1;
                    }
                 }
              }
           }
        }
     }
   if(open3<close3)
     {
      if(open2>close2)
        {
         if(open2<high3&&close2>low3)
           {
            if(open>close&&open<open2&&open>close2)
              {
               if(close<low3)
                 {
                  createObj6(time,high,218, clrRed,"3 Inside Down");
                    {
                     return -1;
                    }
                 }
              }
           }
        }
     }
   return 0;
  }
void createObj6(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }
//+------------------------------------------------------------------+
 
FINANSE-BOND #:

Я так и сделал, объединил все в один советник. Но когда попробовал записать как Индикатор, в терминале всё равно загружается как Советник. Что-то нужно менять в Коде, но что именно я не знаю, не сильно разбираюсь. Ещё я заметил, что нужна его доработка в плане, что когда меняется Тайм Фрейм, на другой то сигнал остаётся на графике и уже на новом не соответствует бару на том же месте. По идее при смене нужно, чтобы удалялся или сохранялся только на том Тайм Фрейме где он был обнаружен. На всякий случай выставлю собраный мой Код, посмотрите что можно подправить или оптимизировать, я всего лишь скопировал со всех советников в один, но думаю там можно объявить некоторые переменные в начале, чтобы не повторяться в Коде несколько раз.   

Советник и индикатор отличаются только тем, что имеют немного разные обработчики событий и индикатор имеет возможность рисования линий либо на самом графике либо в отдельном окне, когда речь идет о свечных паттернах, данный тип кода абсолютно избыточен в остальных случаях и вы лишь ограничите возможности вашего кода данными шагами. Здесь нужна правильная парадигма построения индикаторов, когда то давно я это понял и индикаторы почти не писал, все исполнял в виде эксперта. Кроме того данный код очень легко в последующем адаптировать к торговле, если вы внимательно посмотрите на код вы увидите что там идет работа с объектами, так зачем вам ограничивать себя функционалом индикатора? Все правильно, что вы докопались до человека

 

Я не докопался, я написал, что не силён в Коде поэтому и поделился своими выводами как пользователь, а также попросил немножко урезать что то в Коде что я не знаю где и как объявить некоторые переменные, которые повторяются. Также недавно смотрел видео, что пишут Советник на внешнем индикаторе. Поэтому я и говорил что если делать Индикатор то потом на него можно ссылаться в Советнике и брать от него данные. Может вы что то подправите если можете ?

 
Если кому то, не будет лень прикрутите пожалуйста в Код Приказы на Покупку и продажу, раз уж это Советник.
Причина обращения: