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

 

Народ почему этот метод трала не работает?

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;  // следует ли тралить на участке лоссов (между курсом стоплосса и открытия)
extern   double TrailingStop = 3.0;

/////////////////////////////////////////////////////////////////////////////////////////////
int start()
  {       
   int orders = 0;
   int i = 0;           

   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);
       }
 ////////////////////////////////////////////////////////////////  
     if(TrailingStop>0)
    {
     OrderSelect(i,SELECT_BY_TICKET);
     if(Bid-OrderOpenPrice()>Point*TrailingStop)
       {
        if(OrderStopLoss()<Bid-Point*TrailingStop)
          {
           OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Blue);
           return(0);
          }
       }
    }
////////////////////////////////////////////////////////////   
   }    
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   
   return(0); 
  }

//+------------------------------------------------------------------+
 
Fantar:

Народ почему этот метод трала не работает?

Откуда Вы взяли его?

 
Fantar:

Народ почему этот метод трала не работает?


OrderSelect(i,SELECT_BY_TICKET)
i - это не ТИКЕТ
 
Roman.:

Откуда Вы взяли его?


Журналы про форекс читал и увидел этот метод, если интересно http://www.lepreconreview.com/arhiv-jyrnala/year/2010/page/2 вот ссылка 4-й выпуск страница 67. Там описывался советник на на основе этого трала. Что значит восклицательный знак в этой выражении -!OrderModify()????

Вот второй вариант от куда брал - https://docs.mql4.com/ru/trading/ordermodify

Сейчас код переделал, вроде работает. Можно чтоб на графике во время тестирования отображались тралинговые позиции?

 if(TrailingStop>0)
    {
     OrderSelect(12345,SELECT_BY_TICKET);
     if(Bid-OrderOpenPrice()<Point*TrailingStop)
       {
        if(OrderStopLoss()<Bid-Point*TrailingStop)
          {
           OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Blue);
           return(0);
          }
       }
    }

 
Fantar:

Журналы про форекс читал и увидел этот метод, если интересно http://www.lepreconreview.com/arhiv-jyrnala/year/2010/page/2 вот ссылка 4-й выпуск страница 67. Там описывался советник на на основе этого трала. Что значит восклицательный знак в этой выражении -!OrderModify()????

Вот второй вариант от куда брал - https://docs.mql4.com/ru/trading/ordermodify

1. Разберите по шагам трал учебника, многое прояснится.

В прицепе - библиотека тралов от Ю.Дзюбан - разбирайте код, ставьте нужные, пробуйте, добавляйте свои варианты. Заново велосипед изобретать не надо.

Сам её пользую на реале - всё работает исправно. Взял ф-ии из этой библиотеки и их юзаю. Полностью эту библу не подключал. Юзаю отдельные ф-ии из неё.

2. !OrderModify()???? -ответ.

! НЕ (логическое отрицание) ! х ИСТИНА(1), если значение операнда ЛОЖЬ(0), и ЛОЖЬ(0), если значение операнда не ЛОЖЬ(0).


Учите учебник и документацию. Нет желания - идите прямиком в раздел работа - там делают код по Вашему ТЗ за приемлемые средства.

Файлы:
 

2. !OrderModify()???? -ответ.

! НЕ (логическое отрицание) ! х ИСТИНА(1), если значение операнда ЛОЖЬ(0), и ЛОЖЬ(0), если значение операнда не ЛОЖЬ(0).


Учите учебник и документацию. Нет желания - идите прямиком в раздел работа - там делают код по Вашему ТЗ за приемлемые средства.


Я понимаю что это логическая операция НЕ. Я не понимаю как это НЕ модифицировать ордер. В ф-ии TrailingByShadows перед каждым OrderModify() стоит восклицательный знак.
 
Fantar:
Я понимаю что это логическая операция НЕ. Я не понимаю как это НЕ модифицировать ордер. В ф-ии TrailingByShadows перед каждым OrderModify() стоит восклицательный знак.

Условие, упоминаемое Вами, скорее выглядит так:

if (!OrderModify ())
{
    //какое-то действие (скорее всего Print())
}

Это означает, что если функция OrderModify() вернула значение false, то...

 
Fantar:

Народ почему этот метод трала не работает?

Чтобы работал упоминаемый библиотечный трал, нужно добавить к коду:

extern int    Trail_TF                 = 0;          // таймфрейм трейлинга
extern bool   TrailLOSS_ON             = FALSE;      // Включение трейлинга на LOSS`e
extern int    BarsToShadows            = 0;          // Количество баров, по теням которых необходимо трейлинговать (от 1 и больше)
extern int    Indent_Sh                = 0;          // Отступ (пп.) - расстояние от макс\мин свечи, на которое переносится SL (от 0)
#import "TrailingByShadows.ex4"
    void TrailingByShadows (int ticket, int tmfrm, int bars_n, int indent, bool trlinloss);
#import
int start()
{
    //---- Вставить этот код (в любое место)
    for (i = OrdersTotal() - 1; i >= 0; i--)
    {
        if (!OrderSelect (i, SELECT_BY_POS)) continue;
        if (OrderMagicNumber() != MagicNumber) continue;
        if (OrderSymbol() != Symbol()) continue;
        TrailingByShadows (OrderTicket(), Trail_TF, BarsToShadows, Indent_Sh, TrailLOSS_ON);
    }   
}
а сам файл библиотеки TrailingByShadows.mq4 должен лежать в папке terminal\experts\libraries.
 
Fantar:

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

Ещё один вариант подключения упомянутого трейлинга - сделать подключаемую *.mgh библиотеку. Например, так:

//+------------------------------------------------------------------+
//|                                            TrailingByShadows.mqh |
//|                                                              I_D |
//|                                            http://www.mymmk.com/ |
//+------------------------------------------------------------------+
#property copyright "I_D"
#property link      "http://www.mymmk.com/"

extern   int   iTmfrm  0;              // период, по барам которого следует тралить (1, 5, 15, 30, 60, 240, 1440, 10080, 43200)
extern   int   iBars_n = 3;         // кол-во баров, по которым следует тралить
extern   int   iIndent = 3;         // отступ от тени бара, на котором размещается стоплосс
extern   bool  bTrlinloss = false;  // следует ли тралить на участке лоссов (между курсом стоплосса и открытия)
//+------------------------------------------------------------------+
//| ТРЕЙЛИНГ ПО ТЕНЯМ N СВЕЧЕЙ                                       |
//| При запуске эксперта ему необходимо указать уникальный номер     |
//| (тикет) открытой позиции, а также определить параметры трейлинга:|
//| количество баров, по теням которых необходимо трейлинговать      |
//| (от 1 и больше) и отступ (пунктов) - расстояние от макс. (мин.)  |
//| свечи, на которое переносится стоплосс (от 0), переключатель     |
//| trlinloss указывает, следует ли трейлинговать на участке         |
//| "стоплосс-курс открытия позиции.                                 |
//+------------------------------------------------------------------+
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!=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());
         }      
      }      
   }
//+------------------------------------------------------------------+

Обратите внимание на расширение библиотеки: TrailingByShadows.mqh. Её не нужно компилировать и лежать она должна в другом месте: terminal\experts\include

В коде нужно прописать её вызов:

#include      <TrailingByShadows.mqh>

И в start() добавть только:

int start()
{
    //---- Вставить этот код (в любое место)
    for (i = OrdersTotal() - 1; i >= 0; i--)
    {
        if (!OrderSelect (i, SELECT_BY_POS) continue;
        if (!OrderMagicNumber() != MagicNumber) continue;
        if (OrderSymbol() != Symbol()) continue;
        TrailingByShadows (OrderTicket(), iTmfrm, iBars_n, iIndent, bTrlinloss);
    }   
}
 

Добрый день, если советник проверяет условия стратегии и открывает ордер на первом тике (начале) бара:


static int bar;
if(Time[0]==bar) return;
bar=Time[0];


то

1) Всегда ли будет успевать открывать (проверять условия) ордер, или первый тик недостаточен ?

2) Если недостаточен и пропускается много сделок, то как можно грамотно расширить диапазон, напр. до 3-х первых тиков?

Спасибо за внимание!

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