[Invalid stops] error code 4756 on Position Modify

 

Hi,

I'm running a code on XAUUSD, and I get this error. I don't know why it tries to modify a position with the same SL/TP level already assigned. Could someone help me to solve this? Thanks

I know that is an error to use NormalizeDouble on prices, but I get the same error also with funcion like:

...
double tickSize = SymbolInfoDouble( _Symbol, SYMBOL_TRADE_TICK_SIZE );
...
double normalised_price = round( price / tick_size ) * tick_size;
...
// Or use a function
double Round2Ticksize( double price )
{
   double tick_size = SymbolInfoDouble( _Symbol, SYMBOL_TRADE_TICK_SIZE );
   return( round( price / tick_size ) * tick_size );
};

Journal:

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:15:00   failed modify #20117 buy 0.01 XAUUSD.r sl: 0.00, tp: 2286.00 -> sl: 0.00, tp: 2286.00 [Invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:15:00   CTrade::OrderSend: modify position #20117 XAUUSD.r (sl: 0.00, tp: 2286.00) [invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:30:00   failed modify #20121 buy 0.15 XAUUSD.r sl: 0.00, tp: 2286.00 -> sl: 0.00, tp: 2286.00 [Invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:30:00   CTrade::OrderSend: modify position #20121 XAUUSD.r (sl: 0.00, tp: 2286.00) [invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:30:00   failed modify #20120 buy 0.08 XAUUSD.r sl: 0.00, tp: 2286.00 -> sl: 0.00, tp: 2286.00 [Invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:30:00   CTrade::OrderSend: modify position #20120 XAUUSD.r (sl: 0.00, tp: 2286.00) [invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:30:00   failed modify #20119 buy 0.04 XAUUSD.r sl: 0.00, tp: 2286.00 -> sl: 0.00, tp: 2286.00 [Invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:30:00   CTrade::OrderSend: modify position #20119 XAUUSD.r (sl: 0.00, tp: 2286.00) [invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:30:00   failed modify #20118 buy 0.02 XAUUSD.r sl: 0.00, tp: 2286.00 -> sl: 0.00, tp: 2286.00 [Invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:30:00   CTrade::OrderSend: modify position #20118 XAUUSD.r (sl: 0.00, tp: 2286.00) [invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:30:00   failed modify #20117 buy 0.01 XAUUSD.r sl: 0.00, tp: 2286.00 -> sl: 0.00, tp: 2286.00 [Invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:30:00   CTrade::OrderSend: modify position #20117 XAUUSD.r (sl: 0.00, tp: 2286.00) [invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:45:00   failed modify #20121 buy 0.15 XAUUSD.r sl: 0.00, tp: 2286.00 -> sl: 0.00, tp: 2286.00 [Invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:45:00   CTrade::OrderSend: modify position #20121 XAUUSD.r (sl: 0.00, tp: 2286.00) [invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:45:00   failed modify #20120 buy 0.08 XAUUSD.r sl: 0.00, tp: 2286.00 -> sl: 0.00, tp: 2286.00 [Invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:45:00   CTrade::OrderSend: modify position #20120 XAUUSD.r (sl: 0.00, tp: 2286.00) [invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:45:00   failed modify #20119 buy 0.04 XAUUSD.r sl: 0.00, tp: 2286.00 -> sl: 0.00, tp: 2286.00 [Invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:45:00   CTrade::OrderSend: modify position #20119 XAUUSD.r (sl: 0.00, tp: 2286.00) [invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:45:00   failed modify #20118 buy 0.02 XAUUSD.r sl: 0.00, tp: 2286.00 -> sl: 0.00, tp: 2286.00 [Invalid stops]

2024.05.29 17:32:55.748 Core 31 2024.05.01 07:45:00   CTrade::OrderSend: modify position #20118 XAUUSD.r (sl: 0.00, tp: 2286.00) [invalid stops]


//+------------------------------------------------------------------+ 
void ModificaTP_Globale(){

      
   double tp, sl;

   int tot_pos = PositionsTotal();
   
   ulong ticket; 
   
   for(int i = tot_pos -1; i >= 0; i--){
   
      ticket = PositionGetTicket(i);
       
      sl = PositionGetDouble(POSITION_SL);
                     
      if(PositionGetInteger(POSITION_MAGIC) == MagicNumber && PositionGetString(POSITION_SYMBOL) == Symbol()) {
   
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){
         
            tp = NormalizeDouble(CalcoloPrezzoMedio() + TakeProfit*Point(),Digits());
            
            if(MathRound(PositionGetDouble(POSITION_TP)) != MathRound(tp)) trade.PositionModify(ticket, sl, tp); 
            
         }
         
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL){
         
            tp = NormalizeDouble(CalcoloPrezzoMedio() - TakeProfit*Point(),Digits());

            if(MathRound(PositionGetDouble(POSITION_TP)) != MathRound(tp)) trade.PositionModify(ticket, sl, tp); 
        
         }
      }
   }
}
 

Well, I couldn't spot anything wrong here. Notice that we don't now what CalcoloPrezzoMedio() returns, nor what the variable TakeProfit actually is. But here are a few tips:


1 - make sure the tp is above the bid on long positions and below the ask in short positions before modifying it. If you try to modify a position and the new tp doesn't meet these conditions, you'll get an error.

2 - I'm not sure if what you mentioned was this, but normalize you tp by tick size using your function Round2Ticksize like this:

tp = Roudn2Ticksize(CalcoloPrezzoMedio() + TakeProfit*Point());
tp = Round2Ticksize(CalcoloPrezzoMedio() - TakeProfit*Point());

3 - if nothing works, set a breakpoint at the line that calls trade.PositionModify and check what the current bid/ask is and what the tp to be set is equal to. It's a good start to fix your problem.

 

Hi

You need to check if TP is correct for the current trade and current prices. As was mentioned – TP has t be above bid/below ask – but you need to check also if the distance from bid/ask is enough.

Brokers set the minimal distance to the current price called stoplevel and freezelevel, so you need to check this also and if it’s too close, set TP at this minimum allowed distance.

void ModificaTP_Globale(){
…
double stoplevel = ( int ) MathMax( SymbolInfoInteger(Symbol(), SYMBOL_TRADE_FREEZE_LEVEL ), SymbolInfoInteger( Symbol(), SYMBOL_TRADE_STOPS_LEVEL ) )*_Point;
MqlTick lastTick;
   if(!SymbolInfoTick(_Symbol, lastTick)){
      Print("Getting last tick information failed: "+IntegerToString(GetLastError()));
      return (-1);
   }
…
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){
         
            tp = NormalizeDouble(Round2TickSize(CalcoloPrezzoMedio() + TakeProfit*Point(),Digits()));
        if(tp-lastTick.bid < stoplevel){
                tp = NormalizeDouble(Round2TickSize( lastTick.bid + stoplevel), _Digits);       
        }
            
            if(NormalizeDouble(PositionGetDouble(POSITION_TP), _Digits) != NormalizeDouble(tp,_Digits) 
        trade.PositionModify(ticket, sl, tp); 
            
         }
         
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL){
         
            tp = NormalizeDouble(Round2TickSize(CalcoloPrezzoMedio() - TakeProfit*Point(),Digits()));
        if(lastTick.ask -tp < stoplevel){
                tp = NormalizeDouble(Round2TickSize( lastTick.ask- stoplevel), _Digits);        
        }
            
            if(NormalizeDouble(PositionGetDouble(POSITION_TP), _Digits) != NormalizeDouble(tp,_Digits) 
        trade.PositionModify(ticket, sl, tp); 
        
         }

Have a nice weekend