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

ぐ巨炮叔叔 提交于 2019-12-06 06:10:09

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()
                                        }
      }
}
Roman Komůrka

The problem is in your call to a built-in OrderModify() function.

OrderStopLoss() == OrderModify() will evaluate as false which in turn will evaluate as 0 since == is a comparison operator.

An OrderStopLoss() is a call to another built-in function (not a variable), you can't save anything to it so OrderStopLoss() = 4 wouldn't work either.

From the MQL4 documentation:

bool  OrderModify( int        ticket,      // ticket 
                   double     price,       // price 
                   double     stoploss,    // stop loss 
                   double     takeprofit,  // take profit 
                   datetime   expiration,  // expiration 
                   color      arrow_color  // color 
                   );

In your case that would be the following, assuming ModBuy is already defined somewhere in the code:

ModBuy = OrderModify(  OrderTicket(),      // <-ticket from record OrderSelect()'d
                       OrderOpenPrice(),   // <-price  from current record
                       OrderOpenPrice(),   // <-price  from current record
                       OrderTakeProfit(),  // <-TP     from current record
                       0,                  // ( cannot set P/O expiration for M/O )
                       buycolor            // ( set a color for a GUI marker )
                       );

Or you could just use any other valid value instead of the second OrderOpenPrice() to set a new stoploss.

I'm really sorry, I'm new to Stackoverflow, this is the revised code I now have based on everyone's comments & recommendation's below

 **Local Declarations**
  pnlPoints            =  0;
  point                =  MarketInfo(Symbol(),MODE_POINT);
  stopLevel            =  int(MarketInfo(Symbol(),MODE_STOPLEVEL)+MarketInfo (Symbol(),MODE_SPREAD));
  sl                   =  NormalizeDouble(OrderStopLoss(),Digits);
  tp                   =  OrderTakeProfit();
  cmd                  =  OrderType();
  breakeven            =  100;

  **Global Variables**
  double   pnlPoints;
  double   price,sl,tp;
  double   point;
  int      stopLevel;
  int      cmd;
  int      breakeven;
  double   newSL;
                for(int b = OrdersTotal()-1; b>=0; b--)
                {
                if((OrderSelect(b,SELECT_BY_POS,MODE_TRADES))==true)
                price = MarketInfo(Symbol(),MODE_BID);
                newSL = NormalizeDouble(OrderOpenPrice(),Digits);
                pnlPoints = (price - OrderOpenPrice())/point;
                   {
                   if(OrderType()==OP_BUY)
                      if(OrderMagicNumber() == Period())
                         if((price-newSL)/point>=stopLevel)
                            if(pnlPoints>=breakeven)
                               if(sl!=newSL)
                                  ModBuy = OrderModify(OrderTicket(),OrderOpenPrice(),newSL,tp,buycolor);
                                   else if(ModBuy == false)
                                   {
                                   Print("OrderModify failed with error #",GetLastError());
                                   }
                   }              
                }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!