AM2
Андрей

 
Уровень 35

  Торгую в компаниях:


Группа "Программирование на MQL"

Рейтинг 280



Советник "МТ45" или как написать эксперт, который будет работать на МТ4 и на МТ5

Сегодня задался вопросом написания универсального эксперта и посмотрел какие варианты нам предлагает язык MQL.

Оказалось что такой вариант реализуется достаточно просто, с помощью директивы условной компиляции препроцессора. Заменять нам потребуется совсем немного, т.к. MQL4 понимает многие фразы из MQL5.


#ifdef identifier 
   // код, находящийся здесь, компилируется, если identifier уже был определен для препроцессора в команде <b>#define</b>. 
#endif


В коде для МТ5 будем заменять переменные из MQL4 c помощью директивы #define:


#ifdef __MQL5__ 
#define OrdersTotal  PositionsTotal
#endif 


В шапке советника будут следующие переменные:


input int Stop = 300; // лось
input int Take = 400; // язь
input int Slip = 100; // реквот
input int MN   = 123; // магик
input double LT  = 1; // лот


Функции для совершения торговых операций будут выглядеть следующим образом:

Покупка:


//+------------------------------------------------------------------+
//|  совершает покупку                                               |
//+------------------------------------------------------------------+
bool Buy(double price,double sl,double tp)
  {
//--- покупка в MQL4
#ifdef __MQL4__
   int ticket=OrderSend(Symbol(),0,LT,price,Slip,sl,tp,"",MN);
   if(ticket<0)
      PrintFormat("OrderSend error %d",GetLastError());
#endif
//--- покупка в MQL5         
#ifdef __MQL5__
//--- объявление и инициализация запроса и результата
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
//--- параметры запроса
   request.action   =TRADE_ACTION_DEAL;                     // тип торговой операции
   request.symbol   =Symbol();                              // символ
   request.volume   =LT;                                    // объем 
   request.type     =0;                                     // тип ордера
   request.price    =price;                                 // цена для открытия
   request.sl       =sl;                                    // цена StopLoss
   request.tp       =tp;                                    // цена TakeProfit
   request.deviation=Slip;                                  // допустимое отклонение от цены
   request.magic    =MN;                                    // MagicNumber ордера
//--- отправка запроса
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());     // если отправить запрос не удалось, вывести код ошибки
//--- информация об операции
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
#endif  
//---
   return(false);
  }


Продажа:


//+------------------------------------------------------------------+
//| совершает продажу                                                |
//+------------------------------------------------------------------+
bool Sell(double price,double sl,double tp)
  {
//--- продажа в MQL4
#ifdef __MQL4__
   int ticket=OrderSend(Symbol(),1,LT,price,Slip,sl,tp,"",MN);
   if(ticket<0)
      PrintFormat("OrderSend error %d",GetLastError());
#endif
//--- продажа в MQL5         
#ifdef __MQL5__
//--- объявление и инициализация запроса и результата
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
//--- параметры запроса
   request.action   =TRADE_ACTION_DEAL;                     // тип торговой операции
   request.symbol   =Symbol();                              // символ
   request.volume   =LT;                                    // объем 
   request.type     =1;                                     // тип ордера
   request.price    =price;                                 // цена для открытия
   request.sl       =sl;                                    // цена StopLoss
   request.tp       =tp;                                    // цена TakeProfit
   request.deviation=Slip;                                  // допустимое отклонение от цены
   request.magic    =MN;                                    // MagicNumber ордера
//--- отправка запроса
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());     // если отправить запрос не удалось, вывести код ошибки
//--- информация об операции
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
#endif  
//---
   return(false);
  }


Условие для торговой операции получим случайным образом:

int oper=(int)(GetTickCount()%2); // остаток от деления на два всегда либо 0 либо 1


И пропишем открытие позиций по условию:


   int oper=(int)(GetTickCount()%2); // остаток от деления на два всегда либо 0 либо 1

   if(oper==0)
     {
      double price=Ask;
      double SL=NormalizeDouble(Bid-Stop*_Point,_Digits);
      double TP=NormalizeDouble(Bid+Take*_Point,_Digits);
      Buy(Ask,SL,TP);
     }

   if(oper==1)
     {
      double price=Bid;
      double SL=NormalizeDouble(Ask+Stop*_Point,_Digits);
      double TP=NormalizeDouble(Ask-Take*_Point,_Digits);
      Sell(Ask,SL,TP);
     }


Проверим советник в тестере МТ4:



Затем в МТ5:



Урааа получилось! *budenov* 

И вот у нас есть универсальный советник, который работает в обоих терминалах:


//+------------------------------------------------------------------+
//|                                                        MT45.mq45 |
//|                                              Copyright 2017, AM2 |
//|                                      http://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, AM2"
#property link      "http://www.forexsystems.biz"
#property version   "1.00"
#property strict

//--- введем предопределенные переменные из MQL4 для универсальности кода
#ifdef __MQL5__ 
#define OrdersTotal  PositionsTotal
#endif 

input int Stop = 300; // лось
input int Take = 400; // язь
input int Slip = 100; // реквот
input int MN   = 123; // магик
input double LT  = 1; // лот
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//|  совершает покупку                                               |
//+------------------------------------------------------------------+
bool Buy(double price,double sl,double tp)
  {
//--- покупка в MQL4
#ifdef __MQL4__
   int ticket=OrderSend(Symbol(),0,LT,price,Slip,sl,tp,"",MN);
   if(ticket<0)
      PrintFormat("OrderSend error %d",GetLastError());
#endif
//--- покупка в MQL5         
#ifdef __MQL5__
//--- объявление и инициализация запроса и результата
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
//--- параметры запроса
   request.action   =TRADE_ACTION_DEAL;                     // тип торговой операции
   request.symbol   =Symbol();                              // символ
   request.volume   =LT;                                    // объем 
   request.type     =0;                                     // тип ордера
   request.price    =price;                                 // цена для открытия
   request.sl       =sl;                                    // цена StopLoss
   request.tp       =tp;                                    // цена TakeProfit
   request.deviation=Slip;                                  // допустимое отклонение от цены
   request.magic    =MN;                                    // MagicNumber ордера
//--- отправка запроса
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());     // если отправить запрос не удалось, вывести код ошибки
//--- информация об операции
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
#endif  
//---
   return(false);
  }
//+------------------------------------------------------------------+
//| совершает продажу                                                |
//+------------------------------------------------------------------+
bool Sell(double price,double sl,double tp)
  {
//--- продажа в MQL4
#ifdef __MQL4__
   int ticket=OrderSend(Symbol(),1,LT,price,Slip,sl,tp,"",MN);
   if(ticket<0)
      PrintFormat("OrderSend error %d",GetLastError());
#endif
//--- продажа в MQL5         
#ifdef __MQL5__
//--- объявление и инициализация запроса и результата
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
//--- параметры запроса
   request.action   =TRADE_ACTION_DEAL;                     // тип торговой операции
   request.symbol   =Symbol();                              // символ
   request.volume   =LT;                                    // объем 
   request.type     =1;                                     // тип ордера
   request.price    =price;                                 // цена для открытия
   request.sl       =sl;                                    // цена StopLoss
   request.tp       =tp;                                    // цена TakeProfit
   request.deviation=Slip;                                  // допустимое отклонение от цены
   request.magic    =MN;                                    // MagicNumber ордера
//--- отправка запроса
   if(!OrderSend(request,result))
      PrintFormat("OrderSend error %d",GetLastError());     // если отправить запрос не удалось, вывести код ошибки
//--- информация об операции
   PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
#endif  
//---
   return(false);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   int oper=(int)(GetTickCount()%2); // остаток от деления на два всегда либо 0 либо 1
   double price=0,sl=0,tp=0;

   double ASK=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   double BID=SymbolInfoDouble(_Symbol,SYMBOL_BID);

   if(OrdersTotal()<1)
     {
      if(oper==0)
        {
         price=NormalizeDouble(ASK,_Digits);
         sl=NormalizeDouble(BID-Stop*_Point,_Digits);
         tp=NormalizeDouble(BID+Take*_Point,_Digits);
         Buy(ASK,sl,tp);
        }

      if(oper==1)
        {
         price=NormalizeDouble(BID,_Digits);
         sl=NormalizeDouble(ASK+Stop*_Point,_Digits);
         tp=NormalizeDouble(ASK-Take*_Point,_Digits);
         Sell(BID,sl,tp);
        }
     }
  }
//+------------------------------------------------------------------+



П.С. Подобным образом можно создавать и более сложные советники.
Скачать советник можно по ссылке: www.opentraders.ru/downloads/1655/
  • +7
  • Просмотров: 10460
  • 9 сентября 2017, 11:40
  • AM2
Понравилcя материал? Не забудьте поставить плюс и поделиться в социальной сети!

Вступите в группу "Программирование на MQL", чтобы следить за обновлениями
ПРИСОЕДИНИТЬСЯ К ГРУППЕ
присоединиться
  Предыдущая запись в группе
Как написать тестер для бинарных опционов
25 декабря 2016
22 октября 2017

Брокер для ваших роботов, 15 лет на рынке

Комментарии (1)

+
0
Сначала нужно советник переносить в МетаЭдитор 5, а затем компилировать.Сразу не получается: компилируется под мт4
Редактирован: 25 января 2019, 11:55
avatar

  20  alex30774 Сообщений: 748

  • 21 января 2019, 18:38

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