Converting MT4 EA to MT5 EA problem closing orders

 

Hi guys,

My EA does everything correctly except for closing orders. The EA compiles with no errors. Do my CloseAtMiddleBand(), closebuy() and closesell() functions look ok? 

//+------------------------------------------------------------------+
//|                                                   EA Builder.mq5 |
//|                                        Copyright 2018, Tim Smith |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, Tim Smith"
#property link      "https://www.mql5.com"
#property version   "1.00"

input double LotSize=0.1;
input int StopLoss=30;
input int TakeProfit=10;
input int WaitTime=15;
input int MagicNumber=1234;
double poen;

#include <mq4.mqh>

int MAHandle = INVALID_HANDLE;
int MAHandle2 = INVALID_HANDLE;
int MAHandle3 = INVALID_HANDLE;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {

 //MAHandle = iMA(NULL,0, 50, 1, MODE_SMA, PRICE_CLOSE);
 
 MAHandle =iBands(NULL,0,20,1,2,PRICE_CLOSE);
 
   if(MAHandle == INVALID_HANDLE)
     {
      Print("Error creating MA indicator");
      return(INIT_FAILED);
     }
    
     MAHandle2 = iBands(NULL,0,20,1,2,PRICE_CLOSE);
 
   if(MAHandle2 == INVALID_HANDLE)
     {
      Print("Error creating MA indicator");
      return(INIT_FAILED);
     } 
     
       MAHandle3 =iBands(NULL,0,20,1,2,PRICE_CLOSE);
 
   if(MAHandle3 == INVALID_HANDLE)
     {
      Print("Error creating MA indicator");
      return(INIT_FAILED);
     } 

if (Digits==3 || Digits==5) poen=10*Point; else poen=Point;

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

   CheckForBollingerBandTrade();
 
   CloseAtMiddleBand();
 
  }
//+------------------------------------------------------------------+
double MAGet(const int index)
  {
   double ma[1];
   // reset error code 
   ResetLastError();
   // fill a part of the ma array with values from the indicator buffer that has 0 index 
   if(CopyBuffer(MAHandle,2,index,1,ma) < 0)
     {
      // if the copying fails, tell the error code 
      PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
      // quit with zero result - it means that the indicator is considered as not calculated 
      return(0);
     }
   return(ma[0]);
  }
  
  double MAGet2(const int index)
  {
   double bb[1];
   // reset error code 
   ResetLastError();
   // fill a part of the ma array with values from the indicator buffer that has 0 index 
   if(CopyBuffer(MAHandle2,0,index,1,bb) < 0)
     {
      // if the copying fails, tell the error code 
      PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
      // quit with zero result - it means that the indicator is considered as not calculated 
      return(0);
     }
   return(bb[0]);
  }
  
   double MAGet3(const int index)
  {
   double bu[1];
   // reset error code 
   ResetLastError();
   // fill a part of the ma array with values from the indicator buffer that has 0 index 
   if(CopyBuffer(MAHandle3,1,index,1,bu) < 0)
     {
      // if the copying fails, tell the error code 
      PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
      // quit with zero result - it means that the indicator is considered as not calculated 
      return(0);
     }
   return(bu[0]);
  }
  
  void CheckForBollingerBandTrade()
{

double tps = 0,tpb = 0,sls =0,slb =0;
int buyticket=0,sellticket=0; 
sls=Ask-StopLoss*poen; 
//slb=Bid+StopLoss*poen;
//tps=Ask+TakeProfit*poen;
//tpb=Bid-TakeProfit*poen;
static datetime TimeSent;
 
      if(Ask<MAGet(0))
      
      
      if(OpenOrdersThisPair(Symbol())<=3)
      if (TimeCurrent() >= TimeSent + (WaitTime *60))
      if (OrderSend(Symbol(),OP_BUY,LotSize,Ask,3,sls,0,NULL,MagicNumber,0,Green))
      TimeSent = TimeCurrent();
      if(buyticket>0)
      if (OrderModify(buyticket,OrderOpenPrice(),0,0,0,CLR_NONE))
          Print("Order ",buyticket," was successfully modified.");
           else Print("Order ",buyticket," was NOT successfully modified.",GetLastError());
           
           
      if(Bid>MAGet3(0))
      
      
      if(OpenOrdersThisPair(Symbol())<=3)
      if (TimeCurrent() >= TimeSent + (WaitTime *60))
      if (OrderSend(Symbol(),OP_SELL,LotSize,Bid,3,slb,0,NULL,MagicNumber,0,Red))
      TimeSent = TimeCurrent();
      if(sellticket>0)
      if (OrderModify(sellticket,OrderOpenPrice(),0,0,0,CLR_NONE))
            Print("Order ",sellticket," was successfully modified.");
            else Print("Order ",sellticket," was NOT successfully modified.",GetLastError());                  
    
}

void CloseAtMiddleBand()

{
   
      if (Bid>MAGet2(0))closebuy();
       if(Ask<MAGet2(0))closesell();
}

//+------------------------------------------------------------------+
//|    Close orders                                                  |
//+------------------------------------------------------------------+

 void closebuy()
{

     for(int i=OrdersTotal() -1; i >= 0; i--)
    {
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
       if(OrderType()==OP_BUY)  
        if( OrderMagicNumber() == MagicNumber)
       
       if (!OrderClose(OrderTicket(),OrderLots(),Bid,3,CLR_NONE))
          Print("Closed", OrderTicket(), "successfully");
             else Print("Buy order",OrderTicket(), "was NOT closed successfully");
             
    }
}

 void closesell()
{
 
 
      for(int i=OrdersTotal()-1; i >= 0; i--)
     
    {
     if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
      if (OrderType()==OP_SELL)
       if( OrderMagicNumber() == MagicNumber)
      
        if (!OrderClose(OrderTicket(),OrderLots(),Ask,3,CLR_NONE))
          Print("Closed", OrderTicket(), "successfully");
             else Print("Buy order",OrderTicket(), "was NOT closed successfully");
             
    }
}
  
//+------------------------------------------------------------------+
//checks to see if any orders open on this currency pair.
//+------------------------------------------------------------------+
  int OpenOrdersThisPair(string pair)
{
  int total=0;
 
   for(int i=OrdersTotal()-1; i >= 0; i--)
          {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()== pair)total++;
          }
          return (total);
}


 
mq4.mqh ?
 
timothysmith78:

Hi guys,

My EA does everything correctly except for closing orders. The EA compiles with no errors. Do my CloseAtMiddleBand(), closebuy() and closesell() functions look ok? 

Are you sure it's not just a logging issue ?

   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderType()==OP_SELL)
            if(OrderMagicNumber()==MagicNumber)

               if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,CLR_NONE))
                  Print("Closed",OrderTicket(),"successfully");
      else Print("Buy order",OrderTicket(),"was NOT closed successfully");
     }

The else statement is related to the first if, not the last.

 
Alain Verleyen:

Are you sure it's not just a logging issue ?

The else statement is related to the first if, not the last.

Hi Alain, 

Thanks for helping me try and sort this out.

I have reworked the closebuy() and closesell() functions but unfortunately, the EA still isn't closing my open positions. I'm thinking maybe it is an issue with the mq4.mqh file, but I'm not sure as the EA opens orders correctly!

I have attached the mq4.mqh file that I'm using. I downloaded it from ForexFactory.

I saw in build 1870 that MQ have added iHigh, iLow etc. The bridge between MQL4 & 5 is getting narrower - great to see!  Hopefully I manage to solve this problem.

 void closebuy()
{

     for(int i=OrdersTotal() -1; i >= 0; i--)
    {
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
      {
       if(OrderType()==OP_BUY) 
        {
        if(OrderMagicNumber() == MagicNumber)
          { 
         if (!OrderClose(OrderTicket(),OrderLots(),Bid,3,CLR_NONE))
       
          Print("Closed", OrderTicket(), "successfully");
          
             else Print("Buy order",OrderTicket(), "was NOT closed successfully");
        }   
      }
    }
  }
}

 void closesell()
{
 
 
      for(int i=OrdersTotal()-1; i >= 0; i--)
     
    {
     if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {
      if (OrderType()==OP_SELL)
      {
       if( OrderMagicNumber() == MagicNumber)
        {
        if (!OrderClose(OrderTicket(),OrderLots(),Ask,3,CLR_NONE))
        
          Print("Closed", OrderTicket(), "successfully");
          else Print("Buy order",OrderTicket(), "was NOT closed successfully");
        } 
      }
     }
   }
 }
Files:
mq4.mqh  86 kb
 

I think it's called:

  static bool MT4OrderClose( const int Ticket, const double dLots, const double Price, const int SlipPage, const color Arrow_Color = clrNONE )
  {
    bool Res = ::PositionSelectByTicket(Ticket);

    if (Res)
    {
      MqlTradeRequest Request = {0};

      Request.action = TRADE_ACTION_DEAL;
      Request.position = Ticket;

      Request.symbol = ::PositionGetString(POSITION_SYMBOL);

      Request.volume = dLots;
      Request.price = Price;

      Request.deviation = SlipPage;

      Request.type = (ENUM_ORDER_TYPE)(1 - ::PositionGetInteger(POSITION_TYPE));

      Request.type_filling = MT4ORDERS::GetFilling(Request.symbol, (uint)Request.deviation);

      Res = MT4ORDERS::NewOrderSend(Request);
    }

    return(Res);
  }
MT4OrderClose();

Oh i just noticed later on its declared as:

bool OrderClose( const int Ticket, const double dLots, const double Price, const int SlipPage, const color Arrow_Color = clrNONE )
{
  return(MT4ORDERS::MT4OrderClose(Ticket, dLots, Price, SlipPage, Arrow_Color));
}

So it should indeed do the job.

You can also look here to find alternative route: https://www.mql5.com/en/docs/constants/tradingconstants/enum_trade_request_actions
Documentation on MQL5: Standard Constants, Enumerations and Structures / Trade Constants / Trade Operation Types
Documentation on MQL5: Standard Constants, Enumerations and Structures / Trade Constants / Trade Operation Types
  • www.mql5.com
Trading is done by sending orders to open positions using the OrderSend() function, as well as to place, modify or delete pending orders. Each trade order refers to the type of the requested operation. Trading operations are described in the ENUM_TRADE_REQUEST_ACTIONS enumeration...
 

that cannot work, you have to select the Position and close the position not the order


amando

 
timothysmith78:

Hi Alain, 

Thanks for helping me try and sort this out.

I have reworked the closebuy() and closesell() functions but unfortunately, the EA still isn't closing my open positions. I'm thinking maybe it is an issue with the mq4.mqh file, but I'm not sure as the EA opens orders correctly!

I have attached the mq4.mqh file that I'm using. I downloaded it from ForexFactory.

I saw in build 1870 that MQ have added iHigh, iLow etc. The bridge between MQL4 & 5 is getting narrower - great to see!  Hopefully I manage to solve this problem.

I can only suggest you to learn and use the mql5 trading system.

Anyway, you need to debug your code to identify if the problem is in your code or in the library. Is the closebuy (closesell) function called ? If it's in the library, good luck to debug it.

 

timothysmith78:

I'm thinking maybe it is an issue with the mq4.mqh file, but I'm not sure as the EA opens orders correctly!

I have attached the mq4.mqh file that I'm using. I downloaded it from ForexFactory.

This mqh-file is based on a very old version of another library.

Look at the original. It works correctly.


PS

//+------------------------------------------------------------------+
//|                                                   EA Builder.mq5 |
//|                                        Copyright 2018, Tim Smith |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, Tim Smith"
#property link      "https://www.mql5.com"
#property version   "1.00"

input double LotSize=0.1;
input int StopLoss=30;
input int TakeProfit=10;
input int WaitTime=15;
input int MagicNumber=1234;
double poen;

//#include <mq4.mqh>
#include <MT4Orders.mqh> // https://www.mql5.com/en/code/16006

#define Digits SymbolInfoInteger(_Symbol, SYMBOL_DIGITS) 
#define Point SymbolInfoDouble(_Symbol, SYMBOL_POINT) 
#define Bid SymbolInfoDouble(_Symbol, SYMBOL_BID) 
#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK) 

int MAHandle = INVALID_HANDLE;
int MAHandle2 = INVALID_HANDLE;
int MAHandle3 = INVALID_HANDLE;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {

 //MAHandle = iMA(NULL,0, 50, 1, MODE_SMA, PRICE_CLOSE);
 
 MAHandle =iBands(NULL,0,20,1,2,PRICE_CLOSE);
 
   if(MAHandle == INVALID_HANDLE)
     {
      Print("Error creating MA indicator");
      return(INIT_FAILED);
     }
    
     MAHandle2 = iBands(NULL,0,20,1,2,PRICE_CLOSE);
 
   if(MAHandle2 == INVALID_HANDLE)
     {
      Print("Error creating MA indicator");
      return(INIT_FAILED);
     } 
     
       MAHandle3 =iBands(NULL,0,20,1,2,PRICE_CLOSE);
 
   if(MAHandle3 == INVALID_HANDLE)
     {
      Print("Error creating MA indicator");
      return(INIT_FAILED);
     } 

if (Digits==3 || Digits==5) poen=10*Point; else poen=Point;

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

   CheckForBollingerBandTrade();
 
   CloseAtMiddleBand();
 
  }
//+------------------------------------------------------------------+
double MAGet(const int index)
  {
   double ma[1];
   // reset error code 
   ResetLastError();
   // fill a part of the ma array with values from the indicator buffer that has 0 index 
   if(CopyBuffer(MAHandle,2,index,1,ma) < 0)
     {
      // if the copying fails, tell the error code 
      PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
      // quit with zero result - it means that the indicator is considered as not calculated 
      return(0);
     }
   return(ma[0]);
  }
  
  double MAGet2(const int index)
  {
   double bb[1];
   // reset error code 
   ResetLastError();
   // fill a part of the ma array with values from the indicator buffer that has 0 index 
   if(CopyBuffer(MAHandle2,0,index,1,bb) < 0)
     {
      // if the copying fails, tell the error code 
      PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
      // quit with zero result - it means that the indicator is considered as not calculated 
      return(0);
     }
   return(bb[0]);
  }
  
   double MAGet3(const int index)
  {
   double bu[1];
   // reset error code 
   ResetLastError();
   // fill a part of the ma array with values from the indicator buffer that has 0 index 
   if(CopyBuffer(MAHandle3,1,index,1,bu) < 0)
     {
      // if the copying fails, tell the error code 
      PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
      // quit with zero result - it means that the indicator is considered as not calculated 
      return(0);
     }
   return(bu[0]);
  }
  
  void CheckForBollingerBandTrade()
{

double tps = 0,tpb = 0,sls =0,slb =0;
TICKET_TYPE buyticket=0,sellticket=0; 
sls=Ask-StopLoss*poen; 
//slb=Bid+StopLoss*poen;
//tps=Ask+TakeProfit*poen;
//tpb=Bid-TakeProfit*poen;
static datetime TimeSent;
 
      if(Ask<MAGet(0))
      
      
      if(OpenOrdersThisPair(Symbol())<=3)
      if (TimeCurrent() >= TimeSent + (WaitTime *60))
      if (OrderSend(Symbol(),OP_BUY,LotSize,Ask,3,sls,0,NULL,MagicNumber,0,Green))
      TimeSent = TimeCurrent();
      if(buyticket>0)
      if (OrderModify(buyticket,OrderOpenPrice(),0,0,0,CLR_NONE))
          Print("Order ",buyticket," was successfully modified.");
           else Print("Order ",buyticket," was NOT successfully modified.",GetLastError());
           
           
      if(Bid>MAGet3(0))
      
      
      if(OpenOrdersThisPair(Symbol())<=3)
      if (TimeCurrent() >= TimeSent + (WaitTime *60))
      if (OrderSend(Symbol(),OP_SELL,LotSize,Bid,3,slb,0,NULL,MagicNumber,0,Red))
      TimeSent = TimeCurrent();
      if(sellticket>0)
      if (OrderModify(sellticket,OrderOpenPrice(),0,0,0,CLR_NONE))
            Print("Order ",sellticket," was successfully modified.");
            else Print("Order ",sellticket," was NOT successfully modified.",GetLastError());                  
    
}

void CloseAtMiddleBand()

{
   
      if (Bid>MAGet2(0))closebuy();
       if(Ask<MAGet2(0))closesell();
}

//+------------------------------------------------------------------+
//|    Close orders                                                  |
//+------------------------------------------------------------------+

 void closebuy()
{

     for(int i=OrdersTotal() -1; i >= 0; i--)
    {
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
       if(OrderType()==OP_BUY)  
        if( OrderMagicNumber() == MagicNumber)
       
       if (!OrderClose(OrderTicket(),OrderLots(),Bid,3,CLR_NONE))
          Print("Closed", OrderTicket(), "successfully");
             else Print("Buy order",OrderTicket(), "was NOT closed successfully");
             
    }
}

 void closesell()
{
 
 
      for(int i=OrdersTotal()-1; i >= 0; i--)
     
    {
     if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
      if (OrderType()==OP_SELL)
       if( OrderMagicNumber() == MagicNumber)
      
        if (!OrderClose(OrderTicket(),OrderLots(),Ask,3,CLR_NONE))
          Print("Closed", OrderTicket(), "successfully");
             else Print("Buy order",OrderTicket(), "was NOT closed successfully");
             
    }
}
  
//+------------------------------------------------------------------+
//checks to see if any orders open on this currency pair.
//+------------------------------------------------------------------+
  int OpenOrdersThisPair(string pair)
{
  int total=0;
 
   for(int i=OrdersTotal()-1; i >= 0; i--)
          {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()== pair)total++;
          }
          return (total);
}
MT4Orders
MT4Orders
  • votes: 56
  • 2016.10.10
  • fxsaber
  • www.mql5.com
This library allows to work with the orders in MQL5 (MT5-hedge) in the same way as in MQL4. That is, the order language system (OLS) becomes identical to MQL4. At the same time, it is still possible to use the MQL5 order system in parallel. In particular, the standard MQL5 library will continue to fully operate. It is not necessary to choose...
 
fxsaber:

This mqh-file is based on a very old version of another library.

Look at the original. It works correctly.

Hi fxsaber,

Thanks very much for directing me to this library. It has solved my problem! I've added a few additional defines, such as the Bid and Ask from the other library I was using.

Thanks also to the other community members for your help, you guys are great!

Thanks, Tim



Reason: