Search code examples
algorithmic-tradingmql4metatrader4mt4

Why MQL4 OrderModify() will not modify the order when backtesting?


I'm trying to ADD a stop loss to my open market orders in MetaTrader 4 when a position gets 100 pips "to the good" which is to be equal to the Order Open Price;

OrderStopLoss() == OrderOpenPrice()

But this isn't happening.

I've added Print() & GetLastError() functions and nothing is coming up in the journal, so it must be something in my coding - but cannot see what would be wrong.

OK this is what I have so far, one for loop for the buy, one for the sell. I've also Normalized the "doubles" as I have been advised to do & have also declared the BuyMod & SellMod to "true" at the very top. This should ensure that the default won't resort to false. I also thought it might be helpful if I told you I have the MetaEditor version 5 build 1241:)

The following code I have is the following;

/*Breakeven Order Modification*/
bool BuyMod               =  true;
bool SellMod              =  true;
                for(int b = OrdersTotal()-1;b>=0;b--)
                {
                if(OrderSelect(b,SELECT_BY_POS,MODE_TRADES))
                   {
                   double   aBidPrice   =  MarketInfo(Symbol(),MODE_BID);
                   double   anOpenPrice =  OrderOpenPrice();
                   double   aNewTpPrice =  OrderTakeProfit();
                   double   aCurrentSL  =  OrderStopLoss();
                   double   aNewSLPrice =  anOpenPrice;
                   double   pnlPoints   =  (aBidPrice - anOpenPrice)/_Point;
                   double   stopPoints  =  (aBidPrice - aNewSLPrice)/_Point;
                   int      stopLevel   =  int(MarketInfo(Symbol(),MODE_STOPLEVEL));
                   int      aTicket     =  OrderTicket();
                   if(OrderType() == OP_BUY)
                   if(stopPoints >= stopLevel)
                   if(aTicket > 0)
                   if(pnlPoints >= breakeven)
                   if(aNewSLPrice != aCurrentSL)
                      {
                      BuyMod = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(aNewSLPrice,Digits),NormalizeDouble(aNewTpPrice,Digits),0,buycolor);
                      SendMail("Notification of Order Modification for Ticket#"+IntegerToString(OrderTicket(),10),"Good news! Order Ticket#"+IntegerToString(OrderTicket(),10)+"has been changed to breakeven");
                      }
                   }
                }
                for(int s = OrdersTotal()-1; s>=0; s--)
                {
                if(OrderSelect(s,SELECT_BY_POS,MODE_TRADES))
                   {
                   double   anAskPrice  =  MarketInfo(Symbol(),MODE_ASK);
                   double   anOpenPrice =  OrderOpenPrice();
                   double   aNewTpPrice =  OrderTakeProfit();
                   double   aCurrentSL  =  OrderStopLoss();
                   double   aNewSLPrice =  anOpenPrice;
                   double   pnlPoints   =  (anOpenPrice - anAskPrice)/_Point;
                   double   stopPoints  =  (aNewSLPrice - anAskPrice)/_Point;
                   int      stopLevel   =  int(MarketInfo(Symbol(),MODE_STOPLEVEL));
                   int      aTicket     =  OrderTicket();
                   if(OrderType()== OP_SELL)
                   if(stopPoints >= stopLevel)
                   if(pnlPoints >= breakeven)
                   if(aNewSLPrice != aCurrentSL)
                   if(aTicket > 0)
                      {
                      SellMod = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(aNewSLPrice,Digits),NormalizeDouble(aNewTpPrice,Digits),0,sellcolor);
                      SendMail("Notification of Order Modification for Ticket#"+IntegerToString(OrderTicket(),10),"Good news! Order Ticket#"+IntegerToString(OrderTicket(),10)+"has been changed to breakeven");
                      }
                   }
                }

trading algorithmic-trading mql4 metatrader4

shareeditdeleteflag

edited just now

asked 2 days ago

Todd Gilbey 264

You might want to know, StackOverflow does not promote duplicate questions. ( see the


Solution

  • Besides meeting an MQL4 syntax-rules,
    there are more conditions:


    A first hidden trouble is in number rounding issues.

    MetaQuotes, Inc., recommends wherever possible, to normalise float values into a proper price-representation.

    Thus,
    wherever a price goes into a server-side instruction { OrderSend(), OrderModify(), ... } one shall always prepare such aPriceDOMAIN value
    by a call to NormalizeDouble( ... , _Digits ), before a normalised price hits any server-side instruction call.

    May sound rather naive, but this saves you issues with server-side rejections.

    Add NormalizeDouble() calls into your code on a regular base as your life-saving vest.


    A second, even a better hidden trouble is in STOP_ZONE-s and FREEZE_ZONE-s

    While not visible directly, any Broker set's in their respective Terms & Conditions these parameters.

    In practice,
    this means, if you instruct { OrderSend() | OrderModify() } to set / move aPriceDOMAIN level to be setup too close to current actual Ask/Bid ( violating a Broker-forbidden STOP_ZONE )
    or
    to delete / modify aPriceDOMAIN level of TP or SL, that are already set and is right now, within a Broker-forbidden FREEZE_ZONE distance from actual Ask/Bid,
    such instruction will not be successfully accepted and executed.

    So besides calls to the NormalizeDouble(), always wait a bit longer as the price moves "far" enough and regularly check for not violating forbidden STOP_ + FREEZE_ zones before ordering any modifications in your order-management part of your algotrading projects.

    Anyway, Welcome to Wild Worlds of MQL4

    Update: while StackOverflow is not a Do-a-Homework site, let me propose a few directions for the solution:

    for ( int b = OrdersTotal() - 1; b >= 0; b-- ) // ________________________ // I AM NOT A FAN OF db.Pool-looping, but will keep original approach for context purposes
    {     if (  ( OrderSelect( b, SELECT_BY_POS, MODE_TRADES ) ) == true )
          {    // YES, HAVE TO OPEN A CODE-BLOCK FOR if()-POSITIVE CASE:
               // ------------------------------------------------------
                  double aBidPRICE   = MarketInfo( Symbol(), MODE_BID );       // .UPD
                  double anOpenPRICE     = OrderOpenPrice();                   // .SET FROM a db.Pool Current Record
                  double aNewTpPRICE     = OrderTakeProfit();                  // .SET FROM a db.Pool Current Record
                  double aCurrentSlPRICE = OrderStopLoss();                    // .SET FROM a db.Pool Current Record
                  double aNewSlPRICE     = anOpenPRICE;                        // .SET
                  double  pnlPOINTs      = ( aBidPRICE - anOpenPRICE )/_Point; // .SET
                  double stopPOINTs      = ( aBidPRICE - aNewSlPRICE )/_Point; // .SET
               // ------------------------------------------------------------ // .TEST
                  if (                        OP_BUY    == OrderType()        )
                       if (                   Period()  == OrderMagicNumber() )
                            if (             stopPOINTa >  stopLevel          )
                                 if (         pnlPOINTs >= breakeven          )
                                      if (  aNewSlPRICE != aCurrentSlPRICE    )
                                      {  // YES, HAVE TO OPEN A BLOCK {...}-CODE-BLOCK FOR THE if()if()if()if()-chain's-POSITIVE CASE:
                                         // -------------------------------------------------------------------------------------------
                                            int aBuyMOD = OrderModify( OrderTicket(),
                                                                       OrderOpenPrice(),
                                                                       NormalizeDouble( aNewSlPRICE, Digits ),
                                                                       NormalizeDouble( aNewTpPRICE, Digits ),
                                                                       0,
                                                                       buycolor
                                                                       );
                                            switch( aBuyMOD )
                                            {   case ( NULL  ): { ...; break; } // FAIL ( ANALYSE ERROR )
                                                default:        { ...; break; } // PASS OrderModify()
                                            }
          }
    }