PositionCloseBy not working in real accounts

 

My EA is operating with Buy/Sell Limit orders on hedge accounts.

When the buy and sell positions are equals, the EA uses CTrade.PositionCloseBy() to close a buy position with a sell position with the same volume. This strategy works very well in the demo account, but it does not work on the real account on the same broker.

The broker is Modal (brazil). I asked them about the problem and they said me that it's an EA error and not a platform problem. Can you help me to understand better why the closeBy positions does not work?


The order type filling is ORDER_FILLING_RETURN.

I did na operation on the real and demo accounts at same time and the outputs were:

DEMO:

Demo history


REAL:

REAL

 
bool IsCloseBy( const string Symb )
{
  return(SymbolInfoInteger(Symb, SYMBOL_ORDER_MODE) & SYMBOL_ORDER_CLOSEBY);
}
 
fxsaber:
PrintFormat("%s: %d", symbolInfo.TradeModeDescription(), IsCloseBy(symbol.Name()));


Returns:

2018.07.24 11:52:36.392 FIC(WINQ18,H1)  Full access: 1
 
Rafael Caetano Pinto:


This strategy works very well in the demo account, but it does not work on the real account on the same broker.

What is your code ? What is in the log ?

 
Alain Verleyen:

What is your code ? What is in the log ?


The code is very complex, but I did a simple version that has the error:

//+------------------------------------------------------------------+
//|                                                  TestCloseBy.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <Trade\Trade.mqh>;

input ulong MagicNumber = 1;
input uint  HILOTicks = 2;

CTrade trade;
double tick;
ulong posTicket, tpTicket;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   trade.LogLevel(LOG_LEVEL_ALL);
   trade.SetExpertMagicNumber(MagicNumber);
   trade.SetTypeFilling(ORDER_FILLING_RETURN);
   tick = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  
  MqlRates candles[1], candle;
  if(CopyRates(_Symbol, _Period, 0, 1, candles)<0) {
    PrintFormat("%s: Error %d",__FUNCTION__, GetLastError());
    return;
  }
  candle = candles[0];
  
  if(candle.high - candle.low >= HILOTicks*tick && PositionsTotal() == 0 && OrdersTotal() == 0){
     if(candle.close == candle.high){
         trade.SellLimit(1, candle.close + tick, _Symbol, /*SL*/ candle.close+10*tick, /*TP*/ candle.close-4*tick);

         switch(trade.ResultRetcode()) {
         case TRADE_RETCODE_PLACED:
         case TRADE_RETCODE_DONE:
            posTicket = 0;
            tpTicket = 0;
            break;
         default:
            PrintFormat("%s: Error: SELL %d(%s)",__FUNCTION__, trade.ResultRetcode(),trade.ResultRetcodeDescription());
         }
     }else if(candle.close == candle.low){
         trade.BuyLimit (1, candle.close - tick, _Symbol, /*SL*/ candle.close-10*tick, /*TP*/ candle.close+4*tick);

         switch(trade.ResultRetcode()) {
         case TRADE_RETCODE_PLACED:
         case TRADE_RETCODE_DONE:
            posTicket = 0;
            tpTicket = 0;
            break;
         default:
            PrintFormat("%s: Error: BUY  %d(%s)",__FUNCTION__, trade.ResultRetcode(),trade.ResultRetcodeDescription());
         }
     }
  }
  
//---
   
  }
//+------------------------------------------------------------------+

void  OnTradeTransaction( 
   const MqlTradeTransaction&    trans,
   const MqlTradeRequest&        request,
   const MqlTradeResult&         result
){
   if(trans.type == TRADE_TRANSACTION_HISTORY_ADD && trans.order_state == ORDER_STATE_FILLED && (trans.deal_type == DEAL_TYPE_BUY || trans.deal_type == DEAL_TYPE_SELL)){

      if(trans.price_tp != 0 && trans.price_sl != 0){ //is an original position

         PositionSelectByTicket(trans.order);
         if(MagicNumber != PositionGetInteger(POSITION_MAGIC) || _Symbol != trans.symbol) return;
         
         posTicket = trans.order;
         ENUM_POSITION_TYPE state = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);

         if(state == POSITION_TYPE_SELL){
            trade.BuyLimit (1, trans.price_tp, _Symbol);             //Put the buy limit TP
         }else if(state == POSITION_TYPE_BUY){
            trade.SellLimit (1, trans.price_tp, _Symbol);             //Put the sell limit TP
         }

         trade.PositionModify(trans.order, trans.price_sl, 0.0);  //Removes the original TP

      } else if(trans.price_sl == 0 && trans.price_tp == 0){ // is a buy/sell limit TP
         tpTicket = trans.order;
         trade.PositionCloseBy(posTicket, tpTicket);
         
         switch(trade.ResultRetcode()) {
         case TRADE_RETCODE_PLACED:
         case TRADE_RETCODE_DONE:
            PrintFormat("CLOSE Ticket: %d by %d %s", posTicket, tpTicket, trade.ResultRetcodeDescription());
            posTicket = 0;
            tpTicket = 0;
            break;
         default:
            PrintFormat("%s: Error: Closing %d by %d %d(%s)",__FUNCTION__, posTicket, tpTicket, trade.ResultRetcode(),trade.ResultRetcodeDescription());
         }
      }
   }
}


DEMO:

demo history

demo log

demo log2

REAL:

real history

real log

real log2

The real account threws 10011 (TRADE_RETCODE_ERROR). But I was unable to identify the cause that behavior :/


The error line is on trade.mqh:1621

res=::OrderSend(request,result);
 
Rafael Caetano Pinto:

Do you want to replace tp-market with an limit-order?

That there were no negative slippage?

 
fxsaber:

Do you want to replace tp-market with an limit-order?

That there were no negative slippage?

Do you want to replace tp-market with an limit-order?

Yes. After hedge the operation with a buy and a sell positions, I want close both. When I use the default mt5 tp-market, seems that the MT5 closes the position by Market instead of put the order in the book. This approach has some hard-solved problems, like: connection issues and high volatility Market periods.


That there were no negative slippage?

The tick costs is 1 BRL. The position costs is 0.13 BRL. This EA is a scalper. There is a lot of advantages if I could do it works well. :)

 
ServerName?
 
fxsaber:
ServerName?

Real: ModalMais-MetaTrader 5

Demo: ModalMais-Demo

But in brazil you will need to make a preregistry on broker before you will be able to use your MT5 account. The user account is created by broker and send by Email.

 

Update:


I called to the broker and they said me that the only way I could solve this problem is using this forum because they dont have access to their own MT5 server (only metaquotes team has) and dont have access to the server configuration either. :/


In MQL5 Forum we trust.

 
Rafael Caetano Pinto:

Update:


I called to the broker and they said me that the only way I could solve this problem is using this forum because they dont have access to their own MT5 server (only metaquotes team has) and dont have access to the server configuration either. :/


In MQL5 Forum we trust.

loool...I am suggesting you to find an other broker.