trade.PositionModify deliberately sets wrong SL/TP

 

I'm experiencing a very strange behaviour on MT5 with 

trade.PositionModify() calls.(the other issues withthe negative price is another issue)

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.

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.

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 upper code

// 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;
    }
  }                                                
}
Dateien:
 

So einen Fehler, wen der EA nicht tut was er soll, kann man doch mit dem Debugger (mit hist. Daten) ganz einfach erkennen.

Genau vor der Berechnung von SL und TP anhalten und Anweisung für Anweisung abarbeiten und dabei die Werte kontrollieren - ist ganz einfach.

PS.: Wir können hier deutsch sprechen :)

 
Carl Schreiber:

So einen Fehler, wen der EA nicht tut was er soll, kann man doch mit dem Debugger (mit hist. Daten) ganz einfach erkennen.

Genau vor der Berechnung von SL und TP anhalten und Anweisung für Anweisung abarbeiten und dabei die Werte kontrollieren - ist ganz einfach.

PS.: Wir können hier deutsch sprechen :)

hm, ja, gute Idee, bin ich noch gar nicht drauf gekommen :)

Hab mir nur die Werte angeschaut und da die immer korrekt sind, keine Fehler Codes fallen und sogar der modify call selbst true zurückgibt, obwohl das nicht immer

relevant ist ... aber klar,werd's probieren. Ich könnte mir allerdings auch vorstellen, dass mein request zufällig manchmal mit einem tick zusammenfällt ...

ich hole mir natürlich vorher den open preis aber wenn dazwischen und meineM modify call eine preisänderung stattfindet könnte das das Problem sein.

aif jeden Fall danke für deinen Hinweis

 
Carl Schreiber:

So einen Fehler, wen der EA nicht tut was er soll, kann man doch mit dem Debugger (mit hist. Daten) ganz einfach erkennen.

Genau vor der Berechnung von SL und TP anhalten und Anweisung für Anweisung abarbeiten und dabei die Werte kontrollieren - ist ganz einfach.

PS.: Wir können hier deutsch sprechen :)

tja, ich habs bedürchtet. im Debugger konnte ich den Fehler kein einziges Mal reproduzieren.

 
ranxero:

tja, ich habs bedürchtet. im Debugger konnte ich den Fehler kein einziges Mal reproduzieren.

Ich hab die frage nicht ganz verstanden, aber es fehlt auch ein relevanter code anteil

 
ranxero:

tja, ich habs bedürchtet. im Debugger konnte ich den Fehler kein einziges Mal reproduzieren.

Dann hast du noch nicht den richtigen Umgang damit gelernt.

Und eines fehlt in deinem Thread.

Wo ist die Fehlermeldung


Schreibe dir diese Anweisung an die Stelle wo der Fehler auftritt. Du kannst sie so gestalten, dass du den Fehler auf jeden Fall abfängst. Alles andere sind ausreden :-)

Ist ein Schema!

if (value_error != value)
    {
      DebugBreak()
    }


Dann kannst du in Ruhe dir die Werte zur Berechnung ansehen.


Noch was.

Wenn du die TransActions auswertest musst du einiges beachten.

Es braucht manchmal 2 durchläufe bis die richtige Response ausgewertet werden datrf. Da musst du mit zählern arbeiten.

Siehe Doku dazu. Aber vielleicht weißt du es denn im Code, der eigentlich nutzlos ist da nur stücke, steht nichts .

 
Christian:
Dann hast du noch nicht den richtigen Umgang damit gelernt.

Und eines fehlt in deinem Thread.

Wo ist die Fehlermeldung


Schreibe dir diese Anweisung an die Stelle wo der Fehler auftritt. Du kannst sie so gestalten, dass du den Fehler auf jeden Fall abfängst. Alles andere sind ausreden :-)

Ist ein Schema!

Dann kannst du in Ruhe dir die Werte zur Berechnung ansehen.


Noch was.

Wenn du die TransActions auswertest musst du einiges beachten.

Es braucht manchmal 2 durchläufe bis die richtige Response ausgewertet werden datrf. Da musst du mit zählern arbeiten.

Siehe Doku dazu. Aber vielleicht weißt du es denn im Code, der eigentlich nutzlos ist da nur stücke, steht nichts .

Das ist wahrscheinlich der Punkt, die Auswertung der Response. Im Debugger konnte ich den Fehler kein einziges mal reproduzieren. Die Werte für SL/TP sind wie erwartet.

Ich denke schon, dass ich den relevanten code geschickt habe. SL/TP Berechnung ist jedes mal gleich. Man sieht ja auch an der erfolgreichen Modfikation, dass es nicht an den Werten an sich liegt.

3x oder so gehts gut und plötzlich nicht.

Ich habe es jetzt umgestellt und lasse bei jedem Tick prüfen. Das läuft bisher ohne Ausfälle. Sobald ich eine Order/Position mir SL = 0 gefunden habe arbeite ich sie ab und verlasse dann die Schleife über alle Orders/Positions.

auf jeden Fall danke für deine Mühe

 
ranxero:

Das ist wahrscheinlich der Punkt, die Auswertung der Response. Im Debugger konnte ich den Fehler kein einziges mal reproduzieren. Die Werte für SL/TP sind wie erwartet.

Ich denke schon, dass ich den relevanten code geschickt habe. SL/TP Berechnung ist jedes mal gleich. Man sieht ja auch an der erfolgreichen Modfikation, dass es nicht an den Werten an sich liegt.

3x oder so gehts gut und plötzlich nicht.

Ich habe es jetzt umgestellt und lasse bei jedem Tick prüfen. Das läuft bisher ohne Ausfälle. Sobald ich eine Order/Position mir SL = 0 gefunden habe arbeite ich sie ab und verlasse dann die Schleife über alle Orders/Positions.

auf jeden Fall danke für deine Mühe

Weil ich gerade drüber gestolpert bin.

Bibliothek um die Events zu speichern.

https://www.mql5.com/de/code/22166

Dazu ein Artikel wie man mit dem Event korrekt umgeht.

https://www.mql5.com/de/articles/1111

TradeTransactions
TradeTransactions
  • www.mql5.com
Zugriff auf die Daten von OnTradeTransaction an beliebiger Stelle innerhalb einer Anwendung
Grund der Beschwerde: