Советник на основе свечных комбинаций, трудности написания - страница 2

 
Fantar:

Я нашёл но не пойму куда надо что вставлять, мне надо вставить вот этот трал.

Без последовательного изучения уч-ка и док-ии и не поймёте...

 
Самый простой и логичный ответ ...:)Метод научного тыка тоже не плох:) Плюс трал и код советника готов осталось понять после какой строчки советника нужно вставить трал.
 
Fantar:
Самый простой и логичный ответ ...:)Метод научного тыка тоже не плох:)

:-)

Разберитесь с работой с функциями. Ставьте (подключайте) функцю трала, куда Вам надо в код, согласно логики работы программы для этого нужна структурная ёё схема, типа "если, то, иначе, все." В школе/институте бейсик/паскаль учили?

 
Roman.:

:-)

Разберитесь с работой с функциями. Ставьте (подключайте) функцю трала, куда Вам надо в код, согласно логики работы программы для этого нужна структурная ёё схема, типа "если, то, иначе, все." В школе/институте бейсик/паскаль учили?


4 года назад в институте учили 2 месяца паскаль самое элементарное 2+3=5.

Тему интересную Вы кинули сейчас буду читать, но сильно большой объём информации, в голове останиться 30%

 
Fantar:

4 года назад в институте учили 2 месяца паскаль самое элементарное 2+3=5.

Тему интересную Вы кинули сейчас буду читать, но сильно большой объём информации, в голове останиться 30%

Вспоминайте! Не сразу всё переваривайте, но ПОСТЕПЕННО (дозировано). После пятого прочтения с конспектированием и вопросами-ответами на форуме в новичковской ветке "Любых вопросов..." станет, уверяю Вас, 100500%!

(у самого так же было!) :-)

 
leonid553:

Приветствую всех!

У меня вот обнаружились ссылки на заявленную тему ветки:

https://www.mql5.com/ru/code/11200 - индюк по свечным паттернам

https://www.mql5.com/ru/forum/107681/page2 - аналог. ветка в тему


Вот что получилось по примерам, результата не какого:(

extern int       Lots=1;    //объём торгов    
extern int       Target=15; //тейк профит

int    MagicNumber = 89354658;
string MagicName = "DojiTrader";

int      eDirection = 0; //условие
int      SigP = 0;       //условие
int      OpenTime=1;     
extern   int   iTicket;             // уникальный номер (тикет) открытой позиции
extern   int   iTmfrm;              // период, по барам которого следует тралить (1, 5, 15, 30, 60, 240, 1440, 10080, 43200)
extern   int   iBars_n = 3;         // кол-во баров, по которым следует тралить
extern   int   iIndent = 3;         // отступ от тени бара, на котором размещается стоплосс
extern   bool  bTrlinloss = false;  // следует ли тралить на участке лоссов (между курсом стоплосса и открытия)

/////////////////////////////////////////////////////////////////////////////////////////////
int start()
  {       
   int orders = 0;
   int i = 0;           
   TrailingByShadows(iTicket,iTmfrm,iBars_n,iIndent,bTrlinloss);   // добавил к тралу это
   for(i = 0; i < OrdersTotal(); i++ )  
   {      
      OrderSelect(i,SELECT_BY_POS);     
      if( OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol())
      {
         orders ++; //если нет не 1го открытого ордера то разрешается открытие ордера +1
         break;
      }
   }
///////////////////////////////////////////////////////////////////////////////////////////// 
   for(i = 1; i < OrdersTotal(); i++ )  //количество открытых ордеров на 1 больше
   {
      OrderSelect(i,SELECT_BY_POS);  
      if( OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol())
      {
         orders ++; 
         break;
      }
   }   
 ///////////////////////////////////////////////////////////////////////////////////////////////  
   if(orders < 1 )
      {
         for(i = 1; i < Bars; i++ )
      {
            //Определяем додж
            if(Open[i]==Close[i])
         {
            eDirection = 1;
            break;
         }    
     }
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
      if(i < 3 && i > 0)
      {      
         //Определяем подтверждающие сигналы
        if(SigP == 0)
          {      
           if(High[i] < Close[1]&&Ask>High[1])
            {
               SigP = 1; //сигнал на покупку             
            }
           if(Low[i] > Close[1]&&Ask<Low[1])
             {
               SigP = -1; //сигнал на продажу
             }
          }                       
      }
      else
      {
         SigP = 0;
      }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

      //Додж покупаем
      if (eDirection==1 && SigP ==1 && iBarShift(NULL,0,OpenTime) != 0 && Ask>High[1])
       {
         OrderSend(Symbol(),OP_BUY,Lots,Ask,5,Low[i]-3*Point,Ask+15*Point,MagicName,MagicNumber,0,Green);
         OpenTime = iTime(NULL,0,0);
       }
      //Додж продаём
      if(eDirection == 1 && SigP==-1 && iBarShift(NULL,0,OpenTime) != 0 && Ask<Low[1])
       {
        OrderSend(Symbol(),OP_SELL,Lots,Bid,5,High[i]+3*Point,Bid-Target*Point,MagicName,MagicNumber,0,Red);
        OpenTime = iTime(NULL,0,0);
       }
   }    
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   
   return(0); 
  }
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
////////////////////////////////////////////////////// и всё что идёт ниже
void TrailingByShadows(int ticket,int tmfrm,int bars_n, int indent,bool trlinloss)
   {  
   
   int i; // counter
   double new_extremum;
   
   // проверяем переданные значения
   if ((bars_n<1) || (indent<0) || (ticket==0) || ((tmfrm!=1) && (tmfrm!=5) && (tmfrm!=15) && (tmfrm!=30) && (tmfrm!=60) && (tmfrm!=240) && (tmfrm!=1440) && (tmfrm!=10080) && (tmfrm!=43200)) || (!OrderSelect(ticket,SELECT_BY_TICKET)))
      {
      Print("Трейлинг функцией TrailingByShadows() невозможен из-за некорректности значений переданных ей аргументов.");
      return(0);
      } 
   
   // если длинная позиция (OP_BUY), находим минимум bars_n свечей
   if (OrderType()==OP_BUY)
      {
      for(i=1;i<=bars_n;i++)
         {
         if (i==1) new_extremum = iLow(Symbol(),tmfrm,i);
         else 
         if (new_extremum>iLow(Symbol(),tmfrm,i)) new_extremum = iLow(Symbol(),tmfrm,i);
         }         
      
      // если тралим и в зоне убытков
      if (trlinloss==true)
         {
         // если найденное значение "лучше" текущего стоплосса позиции, переносим 
         if ((((new_extremum - indent*Point)>OrderStopLoss()) || (OrderStopLoss()==0)) && (new_extremum - indent*Point<Bid-MarketInfo(Symbol(),MODE_STOPLEVEL)*Point))
         if (!OrderModify(ticket,OrderOpenPrice(),new_extremum - indent*Point,OrderTakeProfit(),OrderExpiration()))            
         Print("Не удалось модифицировать ордер №",OrderTicket(),". Ошибка: ",GetLastError());
         }
      else
         {
         // если новый стоплосс не только лучше предыдущего, но и курса открытия позиции
         if ((((new_extremum - indent*Point)>OrderStopLoss()) || (OrderStopLoss()==0)) && ((new_extremum - indent*Point)>OrderOpenPrice()) && (new_extremum - indent*Point<Bid-MarketInfo(Symbol(),MODE_STOPLEVEL)*Point))
         if (!OrderModify(ticket,OrderOpenPrice(),new_extremum-indent*Point,OrderTakeProfit(),OrderExpiration()))
         Print("Не удалось модифицировать ордер №",OrderTicket(),". Ошибка: ",GetLastError());
         }
      }
      
   // если короткая позиция (OP_SELL), находим минимум bars_n свечей
   if (OrderType()==OP_SELL)
      {
      for(i=1;i<=bars_n;i++)
         {
         if (i==1) new_extremum = iHigh(Symbol(),tmfrm,i);
         else 
         if (new_extremum<iHigh(Symbol(),tmfrm,i)) new_extremum = iHigh(Symbol(),tmfrm,i);
         }         
           
      // если тралим и в зоне убытков
      if (trlinloss==true)
         {
         // если найденное значение "лучше" текущего стоплосса позиции, переносим 
         if ((((new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point)<OrderStopLoss()) || (OrderStopLoss()==0)) && (new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point>Ask+MarketInfo(Symbol(),MODE_STOPLEVEL)*Point))
         if (!OrderModify(ticket,OrderOpenPrice(),new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point,OrderTakeProfit(),OrderExpiration()))
         Print("Не удалось модифицировать ордер №",OrderTicket(),". Ошибка: ",GetLastError());
         }
      else
         {
         // если новый стоплосс не только лучше предыдущего, но и курса открытия позиции
         if ((((new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point)<OrderStopLoss()) || (OrderStopLoss()==0)) && ((new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point)<OrderOpenPrice()) && (new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point>Ask+MarketInfo(Symbol(),MODE_STOPLEVEL)*Point))
         if (!OrderModify(ticket,OrderOpenPrice(),new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point,OrderTakeProfit(),OrderExpiration()))
         Print("Не удалось модифицировать ордер №",OrderTicket(),". Ошибка: ",GetLastError());
         }      
      }      
   }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
Файлы:
zyugwhte.mq4  8 kb
 
Fantar:

Добрый день всем. Пытаюсь написать советник на основе свечных комбинаций, но как оказалось это не так легко. Когда советник был готов (я так думал) в его работе оказались ошибки, которые я начал исправлять. На данном этапе я не могу справится с 1й проблемой ПОМОГИТЕ ПОЖАЛУЙСТА.

Итак. Советник я попытался максимально упростить, чтоб легче было в нем разобраться. Свечную комбинацию использую самую элементарную - ДОДЖ. После того как образовался додж (Open[i]==Close[i]) я жду подтверждающего сигнала-цена закрытия следующего бара должна быть выше максимума High[i] < Close[1] (покупка) или цена закрытия следующего бара должна быть ниже минимума доджа Low[i] > Close[1] (продажа).

Сигнал на покупку:

-когда выполнилось условие цена закрытия 1го бара после доджа (Close[1]), выше его максимума. Покупаем сразу, как только Ask>High[1] (цена выше максимума, 1го бара после доджа).

Сигнал на продажу:

-когда выполнилось условие цена закрытия 1го бара после доджа (Close[1]), нижу его минимума. Продаем сразу, как только Ask<Low[1] (цена нижу минимума, 1го бара после доджа).

Проблема в том, что:

-сигнал на покупку бывает срабатывает когда цена Ask не пробила максимум бара High[1], а равна ей или на 1-2 пункта нижу.

-сигнал на продажу бывает срабатывает когда цена Ask не пробила минимум бара Low[1], а равна ей или на 1-2 пункта выше.

ПОМОГИТЕ ПОЖАЛУЙСТА. На форуме не нашел похожих тем.


Смотрю Вы пытаетесь использовать TrailingByShadows.

В начале программы воткните

#import "TrailingFuncLib.ex4"
void TrailingByShadows(int ticket,int tmfrm,int bars_n, int indent,bool trlinloss);
#import

И потом вызывайте эту функцию для любого тикета, когда необходимо. При этом необходимо, чтобы TrailingFuncLib.ex4 находилось в папке WashPutьKmetatraderu\experts\libraries. Нет необходимости вставлять весь код себе в программу.

Кроме того, кусок вашего кода:

  TrailingByShadows(iTicket,iTmfrm,iBars_n,iIndent,bTrlinloss);   // добавил к тралу это
Предварительно не выбран iTicket, а он обязательно должен предварительно выбираться с помощью OrderSelect(.......)
 

Вот так должно работать:

for (i = OrdersTotal()-1; i >= 0; i--) {
   if (!OrderSelect(i, SELECT_BY_POS)) continue;
   TrailingByShadows(OrderTicket(),iTmfrm,iBars_n,iIndent,bTrlinloss);   // добавил к тралу это
}
 

iicux и Sepulca СПАСИБО ВАМ ОГРОМНОЕ ваши варианты оба работают)))Сейчас буду пытаться играть с настройками, допустим чтоб при достижении ТР, S/L и Т/Р подымались или опускались на, допустим, 15 пунктов. Надеюсь с помощью TrailingByShadows это можно реализовать, если нет скажите пожалуйста.

 

На данном этапе, код имеет вид.

extern int       Lots=1;    //объём торгов    
extern int       Target=15; //тейк профит
int    MagicNumber = 89354658;
string MagicName = "DojiTrader";
int      eDirection = 0; //условие
int      SigP = 0;       //условие
int      OpenTime=1;     

extern   int   iTicket;             // уникальный номер (тикет) открытой позиции
extern   int   iTmfrm;              // период, по барам которого следует тралить (1, 5, 15, 30, 60, 240, 1440, 10080, 43200)
extern   int   iBars_n = 3;         // кол-во баров, по которым следует тралить
extern   int   iIndent = 3;         // отступ от тени бара, на котором размещается стоплосс
extern   bool  bTrlinloss = false;  // следует ли тралить на участке лоссов (между курсом стоплосса и открытия)

/////////////////////////////////////////////////////////////////////////////////////////////
int start()
  {       
   int orders = 0;
   int i = 0;           
    for (i = OrdersTotal()-1; i >= 0; i--)                                //для трала
    {                       
    if (!OrderSelect(i, SELECT_BY_POS)) continue;                         //для трала
    TrailingByShadows(OrderTicket(),iTmfrm,iBars_n,iIndent,bTrlinloss);   //для трала
    }
   for(i = 0; i < OrdersTotal(); i++ )  
   {      
      OrderSelect(i,SELECT_BY_POS);     
      if( OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol())
      {
         orders ++; //если нет не 1го открытого ордера то разрешается открытие ордера +1
         break;
      }
   }
///////////////////////////////////////////////////////////////////////////////////////////// 
   for(i = 1; i < OrdersTotal(); i++ )  //количество открытых ордеров на 1 больше
      {
      OrderSelect(i,SELECT_BY_POS);  
      if( OrderMagicNumber() == MagicNumber && OrderSymbol() == Symbol())
      {
         orders ++; 
         break;
      }
   }   
 ///////////////////////////////////////////////////////////////////////////////////////////////  
   if(orders < 1 )
      {
         for(i = 1; i < Bars; i++ )
      {
            //Определяем додж
            if(Open[i]==Close[i])
         {
            eDirection = 1;
            break;
         }    
     }
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
      if(i < 3 && i > 0)
      {      
         //Определяем подтверждающие сигналы
        if(SigP == 0)
          {      
           if(High[i] < Close[1]&&Ask>High[1])
            {
               SigP = 1; //сигнал на покупку             
            }
           if(Low[i] > Close[1]&&Ask<Low[1])
             {
               SigP = -1; //сигнал на продажу
             }
          }                       
      }
      else
      {
         SigP = 0;
      }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

      //Додж покупаем
      if (eDirection==1 && SigP ==1 && iBarShift(NULL,0,OpenTime) != 0 && Ask>High[1])
       {
         OrderSend(Symbol(),OP_BUY,Lots,Ask,5,Low[i]-3*Point,Ask+15*Point,MagicName,MagicNumber,0,Green);
         OpenTime = iTime(NULL,0,0);
       }
      //Додж продаём
      if(eDirection == 1 && SigP==-1 && iBarShift(NULL,0,OpenTime) != 0 && Ask<Low[1])
       {
        OrderSend(Symbol(),OP_SELL,Lots,Bid,5,High[i]+3*Point,Bid-Target*Point,MagicName,MagicNumber,0,Red);
        OpenTime = iTime(NULL,0,0);
       }
   }    
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   
   return(0); 
  }

//+------------------------------------------------------------------+
//// Всё что ниже для трала
void TrailingByShadows(int ticket,int tmfrm,int bars_n, int indent,bool trlinloss)
   {  
   
   int i; // counter
   double new_extremum;
   
   // проверяем переданные значения
   if ((bars_n<1) || (indent<0) || (ticket==0) || ((tmfrm!=1) && (tmfrm!=5) && (tmfrm!=15) && (tmfrm!=30) && (tmfrm!=60) && (tmfrm!=240) && (tmfrm!=1440) && (tmfrm!=10080) && (tmfrm!=43200)) || (!OrderSelect(ticket,SELECT_BY_TICKET)))
      {
      Print("Трейлинг функцией TrailingByShadows() невозможен из-за некорректности значений переданных ей аргументов.");
      return(0);
      } 
   
   // если длинная позиция (OP_BUY), находим минимум bars_n свечей
   if (OrderType()==OP_BUY)
      {
      for(i=1;i<=bars_n;i++)
         {
         if (i==1) new_extremum = iLow(Symbol(),tmfrm,i);
         else 
         if (new_extremum>iLow(Symbol(),tmfrm,i)) new_extremum = iLow(Symbol(),tmfrm,i);
         }         
      
      // если тралим и в зоне убытков
      if (trlinloss==true)
         {
         // если найденное значение "лучше" текущего стоплосса позиции, переносим 
         if ((((new_extremum - indent*Point)>OrderStopLoss()) || (OrderStopLoss()==0)) && (new_extremum - indent*Point<Bid-MarketInfo(Symbol(),MODE_STOPLEVEL)*Point))
         if (!OrderModify(ticket,OrderOpenPrice(),new_extremum - indent*Point,OrderTakeProfit(),OrderExpiration()))            
         Print("Не удалось модифицировать ордер №",OrderTicket(),". Ошибка: ",GetLastError());
         }
      else
         {
         // если новый стоплосс не только лучше предыдущего, но и курса открытия позиции
         if ((((new_extremum - indent*Point)>OrderStopLoss()) || (OrderStopLoss()==0)) && ((new_extremum - indent*Point)>OrderOpenPrice()) && (new_extremum - indent*Point<Bid-MarketInfo(Symbol(),MODE_STOPLEVEL)*Point))
         if (!OrderModify(ticket,OrderOpenPrice(),new_extremum-indent*Point,OrderTakeProfit(),OrderExpiration()))
         Print("Не удалось модифицировать ордер №",OrderTicket(),". Ошибка: ",GetLastError());
         }
      }
      
   // если короткая позиция (OP_SELL), находим минимум bars_n свечей
   if (OrderType()==OP_SELL)
      {
      for(i=1;i<=bars_n;i++)
         {
         if (i==1) new_extremum = iHigh(Symbol(),tmfrm,i);
         else 
         if (new_extremum<iHigh(Symbol(),tmfrm,i)) new_extremum = iHigh(Symbol(),tmfrm,i);
         }         
           
      // если тралим и в зоне убытков
      if (trlinloss==true)
         {
         // если найденное значение "лучше" текущего стоплосса позиции, переносим 
         if ((((new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point)<OrderStopLoss()) || (OrderStopLoss()==0)) && (new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point>Ask+MarketInfo(Symbol(),MODE_STOPLEVEL)*Point))
         if (!OrderModify(ticket,OrderOpenPrice(),new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point,OrderTakeProfit(),OrderExpiration()))
         Print("Не удалось модифицировать ордер №",OrderTicket(),". Ошибка: ",GetLastError());
         }
      else
         {
         // если новый стоплосс не только лучше предыдущего, но и курса открытия позиции
         if ((((new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point)<OrderStopLoss()) || (OrderStopLoss()==0)) && ((new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point)<OrderOpenPrice()) && (new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point>Ask+MarketInfo(Symbol(),MODE_STOPLEVEL)*Point))
         if (!OrderModify(ticket,OrderOpenPrice(),new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point,OrderTakeProfit(),OrderExpiration()))
         Print("Не удалось модифицировать ордер №",OrderTicket(),". Ошибка: ",GetLastError());
         }      
      }      
   }
//+------------------------------------------------------------------+