Приветствую вас, друзья!
Многие из вас наверняка уже не раз сталкивались с таким неудобством: написали советник на языке 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