К написанию статьи по переходу с МТ4 на МТ5. Публикация рабочих материалов.

11 февраля 2017, 06:15
Yury Kirillov
9
959

В настоящий момент высокую актуальность имеют решения по переходу с платформы МТ4 - практически прекратившей своё развитие, но широко используемой и имеющей объёмный багаж наработок, на платформу МТ5 - динамично развивающуюся, но относительно небогатую в плане накопленных программных реализаций. Данная статья призвана облегчить перенос программных решений на новую платформу. Рассмотрен пример переноса советника в МТ5 с сохранением функциональности МТ4. Для облегчения понимания материала использован процедурный подход, без объектно ориентированного программирования.

Постановка задачи.


За отправную точку нашего материала возьмем советник автора Sergey Rashevskiy https://www.mql5.com/ru/users/urdala в частности советник NewMartin_V1.1.mq4 https://www.mql5.com/ru/code/17143 код советника приведён ниже

 


//+------------------------------------------------------------------+
//|                                               NewMartin_V1.0.mq4 |
//|                                          Сергей urdala Рашевский |
//|                                                   urdala@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Сергей urdala Рашевский"
#property link      "urdala@mail.ru"
#property version   "1.00"
#property strict
extern double Lot    = 0.1//Объем первого ордера
extern double TP     = 1;   //Тейкпрофит в % от цены
extern double SL     = 1;   //Стоплосс в % от цены
extern double KefLot = 2.0//Коэффициент увеличения лота в случае убытка
extern int    MaxNom = 5;   //Максимальная длинна серии ордеров
extern int    Shema  = 0;   //Схема работы

int i=0;
int LastProf = 0;
int Slippage = 1;
bool chk;
double Lots;
string com;
datetime LastTime,LastUpd;
string StrShema="";
//////////////////////////////////////////////////////////////////////
int OnInit()
  {
   LastTime = 0;
   LastUpd  = 0;
   for(i=1;i<=MaxNom;i++)
     {
      StrShema=StrShema+"-"+(string)CheckNom(i,Shema);
     }
   Print("Схема работы : ",StrShema);
   return(INIT_SUCCEEDED);
  }
//////////////////////////////////////////////////////////////////////
void OnDeinit(const int reason)
  {

  }
//////////////////////////////////////////////////////////////////////
void OnTick()
  {
//////////////////////////////////////////////////////////////////////
//проверка на наличие открытых ордеров
   int openord=OrdersTotal();
   if(openord>0){LastTime=Time[0];return;}
//////////////////////////////////////////////////////////////////////
//определяем начало бара
   if(LastTime == Time[0])return;
   LastTime=Time[0];
//////////////////////////////////////////////////////////////////////
//анализируем последний ордер в истории
   if(OrderSelect(OrdersHistoryTotal()-1,SELECT_BY_POS,MODE_HISTORY))
     {
      if(OrderProfit()>0)LastProf=1;
      else LastProf=-1;
     }
   else LastProf=0;
//////////////////////////////////////////////////////////////////////
//рассчитываем объем и открываем ордер
   int nom = 1;
   if(LastProf<0 && (int)OrderComment()<MaxNom)
     {
      int sh1 = StringFind(OrderComment(),"(");
      int sh2 = StringFind(OrderComment(),")");
      if(sh1>=0 && sh2>=0)
        {
         string stroka = StringSubstr(OrderComment(),sh1+1,sh2-sh1-1);
         nom = (int)stroka;
         if(nom < MaxNom)
           {
            Lots= NormalizeDouble(Lot*MathPow(KefLot,(int)nom),2);
            nom ++;
            com ="("+(string)nom+")";
           }
           else {Lots= Lot;com = "(1)";nom=1;}
        }
        else {Lots= Lot;com = "(1)";nom=1;}
     }
   else {Lots= Lot;com = "(1)";nom=1;}
   if(CheckNom(nom,Shema)==0)OpenOrder(Symbol(),OP_BUY,Lots,Ask,Ask-SL/100*Ask,Ask+TP/100*Ask,com,0);
   else OpenOrder(Symbol(),OP_SELL,Lots,Bid,Bid+SL/100*Bid,Bid-TP/100*Bid,com,0);
//////////////////////////////////////////////////////////////////////
  }
/////////////////////////////////////////////////////////////////////
/////////                 Функции                   /////////////////
/////////////////////////////////////////////////////////////////////
int CheckNom(int nom,int shema)
  {
   int a = nom;
   int b = shema >> (a-1);
   int c = b & 1;
   return(c);
  }
//////////////////////////////////////////////////////////////////////
int OpenOrder(string symb,int cmd,double lot,double price,double stoploss,double takeprofit,string comf,int magic)
  {
   if(AccountFreeMarginCheck(Symbol(),cmd,lot)<=0)return(0);
   int err=0,f=0,ticket=0;
   color clr=CLR_NONE;
   while(f<10)
     {
      RefreshRates();
      if(cmd==0){price=MarketInfo(symb,MODE_ASK);clr=RoyalBlue;}
      if(cmd==1){price=MarketInfo(symb,MODE_BID);clr=Red;}
      ticket=OrderSend(symb,cmd,lot,NormalizeDouble(price,Digits),Slippage,0,0,comf,magic,0,clr);
      err=GetLastError();
      if(err==0break;
      Print(WindowExpertName(),symb,"  при открытии ордера.",err);
      f++;
      Sleep(1000);
     }
   if(ticket>0 && (takeprofit!=0 || stoploss!=0))
     {
      if(OrderSelect(ticket,SELECT_BY_TICKET))ModifyOrder(OrderTicket(),OrderOpenPrice(),stoploss,takeprofit);
     }
   return(ticket);
  }
/////////////////////////////////////////////////////////////////////////
int CloseOrder(int ticket,double lots)
  {
   int err=0,f=0;
   double price=0;
   if(!OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))return(0);
   if(lots==0)lots=OrderLots();
   if(lots<MarketInfo(OrderSymbol(),MODE_MINLOT))lots=MarketInfo(OrderSymbol(),MODE_MINLOT);
   while(f<10)
     {
      RefreshRates();
      if(OrderType()==0)price=Bid;
      if(OrderType()==1)price=Ask;
      if(OrderType()>1){chk=OrderDelete(ticket);return(0);}
      chk = OrderClose(ticket,lots,NormalizeDouble(price,Digits),Slippage,Goldenrod);
      err = GetLastError();
      if(err==0break;
      Print(WindowExpertName(),OrderSymbol(),"  при закрытии ордера.",err);
      f++;
      Sleep(1000);
     }
   return(0);
  }
/////////////////////////////////////////////////////////////////////////
int ModifyOrder(int ticket,double price,double stoploss,double takeprofit)
  {
   int err,f=0;
   while(f<10)
     {
      RefreshRates();
      chk = OrderModify(ticket,NormalizeDouble(price,Digits),NormalizeDouble(stoploss,Digits),NormalizeDouble(takeprofit,Digits),0,CLR_NONE);
      err = GetLastError();
      if(err==0break;
      Print(WindowExpertName(),OrderSymbol(),"  при модификации ордера",err);
      Sleep(1000);
      f++;
     }
   return(0);
  }
//////////////////////////////////////////////////////////////////////////


 Результатом должен быть советник без изменений работающий как на платформе МТ4, так и на платформе МТ5, как можно более точно совпадающий по механизму и результатам работы с исходным советником. 


Описание методики.


Рабочий пример.


Выводы и результаты.