AM2
Андрей

 
Уровень 35

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


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

Рейтинг 283



Советник "МТ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
  • Просмотров: 10711
  • 9 сентября 2017, 11:40
  • AM2
Понравилcя материал? Не забудьте поставить плюс и поделиться в социальной сети!

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

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

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

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

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

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

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