MQL4: Пишем один советник сразу для MT4 и MT5

Приветствую вас, друзья!

Многие из вас наверняка уже не раз сталкивались с таким неудобством: написали советник на языке mql4, а потом захотелось попробовать поиграться с ним в MetaTrader 5. Переписывать заново весь код — довольно кропотливое и долгое занятие, к тому же приходится сначала разобраться с работой уже имеющегося. Писать два разных советника отдельно для MT4 и для MT5 — тоже накладно по времени. Именно эту задачу мы с вами сегодня и решим в новом видео уроке.

Итак, что же делать? Ответ прост — написать один советник сразу для двух терминалов. Ведь по большей части языки mql4 и mql5 отличаются не так уж и сильно, многие методы и основная структура у скриптов на этих языках схожая. Если бы можно было писать общий код в одном скрипте, а отличающиеся участки просто каким-то образом переписать на обоих языках и заставить компилятор самому выбрать нужные куски кода, это сэкономило бы кучу времени и нервов.

К счастью, MetaEditor поддерживает директивы условной компиляции препроцессора. И сегодня мы на очень простом примере рассмотрим, как это делается.

#ifdef identifier 
   // код, находящийся здесь, компилируется, если 
identifier уже был определен для препроцессора 
в команде #define.
#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  = 0.1;

Теперь можно написать методы для покупки и продажи:

bool Buy(double price,double sl,double tp)
{
#ifdef __MQL4__
int ticket = OrderSend(Symbol(), 0, LT, price, Slip, sl, tp, "", MN);
if (ticket<0) {
PrintFormat("OrderSend error %d",GetLastError());
}
#endif

#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);
}

Метод для продажи подобен методу buy(). Над стратегией в данном примере думать особо не будем, получим условие на открытие случайным образом и поместим этот код в OnTick():

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);
}

Заключение

Вот и все. Теперь можно компилировать код в MetaEditor 4 и в терминале MetaTrader 4 он будет работать. Можно скомпилировать советник в MetaEditor 5 и он будет нормально работать в терминале MetaTrader 5. При всем при этом для смены терминала не нужно переписывать ни строчки кода — все будет нормально компилироваться и работать.

Тема на форуме

С уважением, Дмитрий аkа Silentspec
TradeLikeaPro.ru

Уроки по MQL , , ,