CTrade PositionClose() not working

 

I'm using the native OrderSend() function in order to open a new position using the below function:

uint SendSLTPOrder(long const magic_number,ENUM_ORDER_TYPE orderType,double volume,double price,double stopLoss,double takeProfit)
  {
   MqlTradeRequest request={0};
   request.action=TRADE_ACTION_DEAL;
   request.magic=magic_number;
   request.symbol=_Symbol;
   request.volume=volume;
   request.sl=NormalizeDouble(stopLoss,_Digits);
   request.tp=NormalizeDouble(takeProfit,_Digits); 
   request.price=price;
   request.type=orderType;
   request.type_filling=ORDER_FILLING_FOK;
   request.deviation=5;
   MqlTradeResult result={0};
   OrderSend(request,result);

   Print(__FUNCTION__,":",result.comment);
   if(result.retcode==10016) Print(result.bid,result.ask,result.price);

   return result.retcode;
  }

That is working very fine.

However closing an opened position is not working, I tried to loop through orders to close them but OrdersTotal() is always returning zero knowing that there are already opened orders.

on the other hand the PositionsTotal() function is returning the number of opened orders correctly, so I tried to use the CTrade PositionClose() function to close all opened orders as shown below, but it is not closing any order:

void CloseAll()
  {
   for(int i=PositionsTotal()-1;i>=0; i--)
     {
        {
         if(!trade.PositionClose(PositionGetSymbol(i),5))
           {
            Print(PositionGetSymbol(i),"PositionClose() method failed. Return code=",trade.ResultRetcode(),
                  ". Code description: ",trade.ResultRetcodeDescription());
           }
         else
           {
            Print(PositionGetSymbol(i),"PositionClose() method executed successfully. Return code=",trade.ResultRetcode(),
                  " (",trade.ResultRetcodeDescription(),")");
           }
        }
     }

  }

it only prints the following:

2019.07.01 01:55:27.138 2019.06.28 19:30:00   GBPJPYPositionClose() method failed. Return code=10006. Code description: rejected

Here is the full code:

//+------------------------------------------------------------------+
//|                                                     MyExpert.mq5 |
//|                        Copyright 2019, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#include <Trade\Trade.mqh>

//--- object of class CTrade
CTrade trade;
CSymbolInfo mysymbol;
int m_nLastBars=-1;

MqlParam params[];      // Array for storing indicators parameters
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

   double _mafast[],_maslow[];

   int mfvd = iMA(_Symbol,_Period,5,0,MODE_SMA,PRICE_CLOSE);
   int msvd = iMA(_Symbol,_Period,50,0,MODE_SMA,PRICE_CLOSE);

   ArraySetAsSeries(_mafast,true);
   ArraySetAsSeries(_maslow,true);

   if(CopyBuffer(mfvd,0,0,20,_mafast) < 0){Print("CopyBufferMA_fast error =",GetLastError());}
   if(CopyBuffer(msvd,0,0,20,_maslow) < 0){Print("CopyBufferMA_fast error =",GetLastError());}

//ArrayPrint(_mafast);
//ArrayPrint(_maslow);

   if(!isNewCandle())
      return;

   double sl,tp;
   double sl_dollars=100;
   double tp_dollars=100;
   double volume=0.1;
   long const magic=10;
   double sltp_result[2];

   if(_mafast[0]>_maslow[0])
     {
      if(_mafast[0]>_mafast[3])
        {
         if(PositionsTotal()==0)
           {
            calculateSLTP(sltp_result,ORDER_TYPE_BUY,sl_dollars,tp_dollars,volume);
            sl = sltp_result[0];
            tp = sltp_result[1];
            SendSLTPOrder(magic,ORDER_TYPE_BUY,volume,NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits),sl,tp);
           }
        }
      else
        {
         if(PositionsTotal()>=1)
           {
            CloseAll();
            DeleteAllOrdersByMagic(magic);
           }
        }
     }
   else if(_mafast[0]<_maslow[0])
     {
      if(_mafast[0]<_mafast[3])
        {
         if(PositionsTotal()==0)
           {
            sl = sltp_result[0];
            tp = sltp_result[1];
            calculateSLTP(sltp_result,ORDER_TYPE_SELL,sl_dollars,tp_dollars,volume);
            SendSLTPOrder(magic,ORDER_TYPE_SELL,volume,NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits),sl,tp);
           }
        }
      else
        {
         if(PositionsTotal()>=1)
           {
            CloseAll();
            DeleteAllOrdersByMagic(magic);
           }
        }

     }
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void calculateSLTP[](double &sltp_result[],ENUM_ORDER_TYPE orderType,double sl_dollars,double tp_dollars,double volume)
  {
// Rates Structure for the data of the Last incomplete BAR
   MqlRates BarData[1];
   CopyRates(Symbol(),Period(),0,1,BarData); // Copy the data of last incomplete BAR
   double Latest_Close_Price1=BarData[0].close; // Copy latest close prijs
   double pip_value=(1/MathPow(10,_Digits))*(volume*100)*AccountInfoInteger(ACCOUNT_LEVERAGE);

   printf((1/MathPow(10,_Digits)));
   printf(AccountInfoInteger(ACCOUNT_LEVERAGE));

   double sl_sub_pips=((int)(sl_dollars/pip_value))/MathPow(10,_Digits);
   double tp_sub_pips=((int)(tp_dollars/pip_value))/MathPow(10,_Digits);
   double spread=NormalizeDouble(SymbolInfoDouble(Symbol(),SYMBOL_ASK)-SymbolInfoDouble(Symbol(),SYMBOL_BID),_Digits);

   if(orderType==ORDER_TYPE_BUY_STOP || orderType==ORDER_TYPE_BUY_LIMIT || orderType==ORDER_TYPE_BUY_STOP_LIMIT || orderType==ORDER_TYPE_BUY)
     {
      sltp_result[0] = SymbolInfoDouble(_Symbol,SYMBOL_ASK) - sl_sub_pips - spread;
      sltp_result[1] = SymbolInfoDouble(_Symbol,SYMBOL_ASK) + tp_sub_pips + spread;
     }
   else
     {
      sltp_result[0]=SymbolInfoDouble(_Symbol,SYMBOL_BID)+sl_sub_pips + spread;
      sltp_result[1]=SymbolInfoDouble(_Symbol,SYMBOL_BID)-tp_sub_pips - spread;
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
uint SendSLTPOrder(long const magic_number,ENUM_ORDER_TYPE orderType,double volume,double price,double stopLoss,double takeProfit)
  {
//--- prepare a request
   MqlTradeRequest request={0};
   request.action=TRADE_ACTION_DEAL;         // setting a pending order
   request.magic=magic_number;                  // ORDER_MAGIC
   request.symbol=_Symbol;                      // symbol
   request.volume=volume;                          // volume in 0.1 lots
   request.sl=NormalizeDouble(stopLoss,_Digits);                              // Stop Loss is not specified
   request.tp=NormalizeDouble(takeProfit,_Digits); 
   request.price=price;  // open price                                // Take Profit is not specified     
//--- form the order type
   request.type=orderType;
   request.type_filling=ORDER_FILLING_FOK;
   request.deviation=5;                // order type
//--- send a trade request
   MqlTradeResult result={0};
   OrderSend(request,result);
//--- write the server reply to log  
   Print(__FUNCTION__,":",result.comment);
   if(result.retcode==10016) Print(result.bid,result.ask,result.price);
//--- return code of the trade server reply
   return result.retcode;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
uint SendPendingOrder(long const magic_number,ENUM_ORDER_TYPE orderType,double volume,double price,double stopLoss,double takeProfit)
  {
//--- prepare a request
   MqlTradeRequest request={0};
   request.action=TRADE_ACTION_PENDING;         // setting a pending order
   request.magic=magic_number;                  // ORDER_MAGIC
   request.symbol=_Symbol;                      // symbol
   request.volume=volume;                          // volume in 0.1 lots
   request.sl=NormalizeDouble(stopLoss,_Digits);                                // Stop Loss is not specified
   request.tp=NormalizeDouble(takeProfit,_Digits);                                // Take Profit is not specified     
//--- form the order type
   request.type=orderType;                // order type
//--- form the price for the pending order
   request.price=price;  // open price
//--- send a trade request
   MqlTradeResult result={0};
   OrderSend(request,result);
//--- write the server reply to log  
   Print(__FUNCTION__,":",result.comment);
   if(result.retcode==10016) Print(result.bid,result.ask,result.price);
//--- return code of the trade server reply
   return result.retcode;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DeleteAllOrdersByMagic(long const magic_number)
  {
   ulong order_ticket;
//--- go through all pending orders
   for(int i=OrdersTotal()-1;i>=0;i--)
      if((order_ticket=OrderGetTicket(i))>0)
         //--- order with appropriate ORDER_MAGIC
         if(magic_number==OrderGetInteger(ORDER_MAGIC))
           {
            MqlTradeResult result={0};
            MqlTradeRequest request={0};
            request.order=order_ticket;
            request.action=TRADE_ACTION_REMOVE;
            OrderSend(request,result);
            //--- write the server reply to log
            Print(__FUNCTION__,": ",result.comment," reply code ",result.retcode);
           }

//---
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseAll()
  {
   for(int i=PositionsTotal()-1;i>=0; i--)
     {
        {
         if(!trade.PositionClose(PositionGetSymbol(i),5))
           {
            Print(PositionGetSymbol(i),"PositionClose() method failed. Return code=",trade.ResultRetcode(),
                  ". Code description: ",trade.ResultRetcodeDescription());
           }
         else
           {
            Print(PositionGetSymbol(i),"PositionClose() method executed successfully. Return code=",trade.ResultRetcode(),
                  " (",trade.ResultRetcodeDescription(),")");
           }
        }
     }

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool isNewCandle()
  {
   int nBars=Bars(Symbol(),PERIOD_CURRENT);
   if(m_nLastBars!=nBars)
     {
      m_nLastBars=nBars;
      return true;
     }
   return false;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

Thanks in advance!!

 

You are mixing code usable (PositionGetSymbol) on a netting account while your account is an hedging one.

Please read the documentation and search on the forum, this has been asked and answered numerous time.

 

Change PositionGetSymbol(i) to PositionGetTicket(i)

void CloseAll()
  {
   for(int i=PositionsTotal()-1;i>=0; i--)
     {
        {
         if(!trade.PositionClose(PositionGetTicket(i),5))
           {
            Print(PositionGetSymbol(i),"PositionClose() method failed. Return code=",trade.ResultRetcode(),
                  ". Code description: ",trade.ResultRetcodeDescription());
           }
         else
           {
            Print(PositionGetSymbol(i),"PositionClose() method executed successfully. Return code=",trade.ResultRetcode(),
                  " (",trade.ResultRetcodeDescription(),")");
           }
        }
     }

  }
MohammdFneish:

I'm using the native OrderSend() function in order to open a new position using the below function:

That is working very fine.

However closing an opened position is not working, I tried to loop through orders to close them but OrdersTotal() is always returning zero knowing that there are already opened orders.

on the other hand the PositionsTotal() function is returning the number of opened orders correctly, so I tried to use the CTrade PositionClose() function to close all opened orders as shown below, but it is not closing any order:

it only prints the following:

Here is the full code:

Thanks in advance!!

 
Edwin Hernando Artunduaga Quiñonez Great thanks man, you are my hero !!
Reason: