trade.PositionModify deliberately sets wrong SL/TP

 

I'm experiencing a very strange behaviour on MT5 with 

trade.PositionModify() calls.

I have an EA that automatically sets SL and TP for every new order, no matter whether stoplimit(= order) or market order(= position).

The strange thing is, it works fine for 3 times or so, sometimes only once, then on the next trade SL and TP are very much smaller, allthough same calculation and 

almmost same SL/TP as price may have moved a little bit in between.

the smaller value, when this error occuirs, seems to be always the same, as if some default was used but IM a tno point providing such default.

 There is no error thrown. The call itself returns true and when I read the ResultRetcode() it always gives me 10009 which is  TRADE_RETCODE_DONE.


as you can see on the screen shot and the order list below from 5 orders 4 have been modified correctly but the one selected has different SL/TP values.

This happens totally out of any pattern. Sometimes after some correctly modifed trades sometimes right on the first one.

I do print our SL and TPs right before the modification and they are always correct.

I already chased the thing through the debugger but was not able to reproduce the error for a single time.

following he relevant code:

// here Sl and TP get calculated
    tradeUtils.CalculateSLTP(positionPriceOpen, positionVolume, Symbol(), calcType, sl, tp, tpSlFactor, balancePercentage, slPoints, riskLineName, fixedRiskAmount);
    if (sl!=0) {
      int direction = 0;
      if(positionType==POSITION_TYPE_BUY) {
        sl = NormalizeDouble(positionPriceOpen - sl, Digits());
        tp = NormalizeDouble(positionPriceOpen + tp, Digits());
        direction = 1;
      }
      if (positionType==POSITION_TYPE_SELL) {
        sl = NormalizeDouble(positionPriceOpen + sl, Digits());
        tp = NormalizeDouble(positionPriceOpen - tp, Digits());
        direction = -1;
      }
      ResetLastError();
      if (direction !=0 && sl>0 && tp >= 0) { // no stoplimt order or negative stops allowed
        if (sl!=positionSL) { // onl if different from current SL
          if (!trade.PositionModify(positionTicket, sl, tp)) { // always true
            errorTicket = positionTicketAsString;
            errorTitle = "POSITION: modification error " + trade.ResultRetcode();
            errorMsg = "Ticket " + positionTicketAsString +
                        "\n@ " +DoubleToString(positionPriceOpen, Digits()) + 
                        "\nSL "+DoubleToString(sl, Digits()) + 
                        "\nTP "+DoubleToString(tp, Digits()) + "\n\n";
            errorUtils.BuildErrorMessage(errorMsg, errorTitle, calcType);
            Comment("POSITION RES CODE ERR: " + trade.ResultRetcode() + "\nSL: " + sl + "\nTP: " + tp);
          } else {
            ticketsProcessedSuccessfully += positionTicketAsString + ";";
            Comment("POSITION RES CODE SUCC: " + trade.ResultRetcode() + "\nSL: " + sl + "\nTP: " + tp); // result code is 10009 - success
            return true;
          }
        }
      } else {
        errorTicket = positionTicketAsString;
        errorTitle = "POSITION: negative stops are not wllowed ";
        errorMsg = "Ticket " + positionTicketAsString +
                    "\n@ " +DoubleToString(positionPriceOpen, Digits()) + 
                    "\nSL "+DoubleToString(sl, Digits()) + 
                    "\nTP "+DoubleToString(tp, Digits()) + "\n\n";
        errorUtils.BuildErrorMessage(errorMsg, errorTitle, calcType);
      }
    }
  }



following the code that invokes the code above

// gets invoked by the EA's OnTradeTransaction() method 
void TradeManagerLib::OnTradeTransaction(const MqlTradeTransaction& trans,
                                            const MqlTradeRequest& request,
                                                const MqlTradeResult& result) {
  if (DoDisable) {
    return;
  }
  if (result.retcode==TRADE_RETCODE_DONE) { 
    // upper code is contained in the Scan() method                                                
    if (Scan(CalculationType, TPSLFactor, BalancePercentage, SLPoints, RiskLineName, FixeRiskAmount)) {
      return;
    }
  }                                                
}
Files:
 

I managed t produce some error info but doesn'T makle things clearer:

as the screen shot shows the ResultRetcode() is 10016 ( TRADE_RETCODE_INVALID_STOPS ) and the messae box prints the values that have been used.

To me this looks like valid stops for a SELL market order:

entry price at ~ 51000

SL ~ 61000

TP: 24696

still the modify call returns false and return code is 10016

 
Enable both Ask and Bid prices in the chart settings.
 
Vladimir Karputov:
Enable both Ask and Bid prices in the chart settings.

Are you refering to the Bid/Ask price lines? They both are activated and showing. Just so close you cannot see clearly on the screen shot.

Is your idea that the spread is so wide that either TP or SL are invalid? That's not the case. I made an extreme example to make sure.

 
Vladimir Karputov:
Enable both Ask and Bid prices in the chart settings.
is it possible that there is a limit for SL/TP? Some max distance?
 

thanks for the forward,. I will check.

Reason: