Modifying stop orders ?

 

Any suggestions on this, before I stray into a dead end ?

//------------------------  
void ModifyPending()
   {// The globals PriceBuy, SL_BUY are generated by indicators etc and may not always be 'sensible', especially in relation to eachother and current market price
   int  MoveStep = 50;//External
   bool NewPrice = FALSE;
   bool NewStop = FALSE;
   bool NewPriceValid = FALSE;
   bool NewStopValid = FALSE;
   for (int i = 0; i < OrdersTotal(); i++)
      {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == FALSE) break;
      if (OrderType() == OP_BUYSTOP && OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
         {
     
        
         if (MathAbs(PriceBuy - OrderOpenPrice() > Point) NewPrice = TRUE;
         if (MathAbs(SL_BUY - OrderStopLoss() > Point) NewStop = TRUE;
         if () NewPriceValid = TRUE;
         if () NewStopValid = TRUE;
         
         
         
         if ( (NewPriceValid && NewStopValid) && (NewStop || NewPrice) )
            {//Both levels are valid (avoiding Error130), at least one will be changed (avoiding Error1):
            OrderModify(OrderTicket(), PriceBuy, SL_BUY, OrderTakeProfit(), 0, Blue);
            continue;
            }
            
            
            
            

         }
//----

      }
   return(0);
   }
//------------------------

Here I first check if there are new price and/or new stop for the order. Next is to check if those obey the stoplevel limitations, correct ?

--------------------------------------------

StopLevel Minimum Distance Limitation.

Order Type Open Price Close Price StopLoss (SL) TakeProfit (TP)
Buy Ask Bid Bid - SL > StopLevel TP - Bid > StopLevel
Sell Bid Ask SL - Ask > StopLevel Ask - TP > StopLevel
*
BuyStop OpenPrice - Ask > StopLevel OpenPrice - SL > StopLevel TP - OpenPrice > StopLevel
SellStop Bid - OpenPrice > StopLevel SL - OpenPrice > StopLevel OpenPrice - TP > StopLevel

----------------

 
Test the function in the Back-Tester. If you get any Errors then Log the Error# and go from there.
 

Yes here is the code I came up with:

//------------------------  
void ModifyPending()
   {
   int  MoveStep = 50;//External
   bool NewPrice = FALSE;
   bool NewStop = FALSE;
   bool NewPriceValid = FALSE;
   bool NewStopValid = FALSE;
   for (int i = 0; i < OrdersTotal(); i++)
      {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == FALSE) break;
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
         {      
         if (OrderType() == OP_BUYSTOP)
            {
            NewPrice = FALSE;
            NewStop = FALSE;
            NewPriceValid = FALSE;
            NewStopValid = FALSE;
            if (MathAbs(PriceBuy - OrderOpenPrice()) > MoveStep * Point) NewPrice = TRUE;
            if (MathAbs(SL_BUY - OrderStopLoss()) > Point) NewStop = TRUE;
            if ((OrderOpenPrice() - Ask)     > (StopLevel * Point) ) NewPriceValid = TRUE;
            if ((OrderOpenPrice() - SL_BUY)  > (StopLevel * Point) ) NewStopValid = TRUE;                  
            if ( (NewPriceValid && NewStopValid) && (NewStop || NewPrice) )
               {//Both levels are valid (avoiding Error130), at least one will be changed (avoiding Error1):
               OrderModify(OrderTicket(), PriceBuy, SL_BUY, OrderTakeProfit(), 0, Blue);
               if(GetLastError()==130) Print("222222222");
               continue;
               }
            }
//----
         if (OrderType() == OP_SELLSTOP)
            {
            NewPrice = FALSE;
            NewStop = FALSE;
            NewPriceValid = FALSE;
            NewStopValid = FALSE;
            if (MathAbs(PriceSell - OrderOpenPrice()) > MoveStep * Point) NewPrice = TRUE;
            if (MathAbs(SL_SELL - OrderStopLoss()) > Point) NewStop = TRUE;
            if ((Bid - OrderOpenPrice())     > (StopLevel * Point) ) NewPriceValid = TRUE;
            if ((SL_SELL - OrderOpenPrice()) > (StopLevel * Point) ) NewStopValid = TRUE;                  
            if ( (NewPriceValid && NewStopValid) && (NewStop || NewPrice) )
               {//Both levels are valid (avoiding Error130), at least one will be changed (avoiding Error1):
               OrderModify(OrderTicket(), PriceSell, SL_SELL, OrderTakeProfit(), 0, Red);
               if(GetLastError()==130) Print("555555555");
               continue;
               }
            }
         }         
      }
   return(0);
   }
//------------------------

Looks pretty sound and I cant find anything wrong with it. Seems to work fairly OK, but I still get the dreaded 130 on rare occasions. A tick BT from 2010.01.01 - 2012.03.28 reveals two places (one long, one short) where I get E130. Mismatched Chart Errors = 0.

Journal:

2012.04.15 00:34:55 2011.12.14 23:00 #__22 EURUSD,H1: modify #2072 sell stop 0.10 EURUSD at 1.29461 sl: 1.29893 tp: 1.27961 ok
2012.04.15 00:34:55 2011.12.14 23:00 #__22 EURUSD,H1: modify #2070 buy stop 0.10 EURUSD at 1.30100 sl: 1.29746 tp: 1.32152 ok
2012.04.15 00:34:53 2011.12.08 09:00 #__22 EURUSD,H1: modify #2052 buy stop 0.10 EURUSD at 1.34287 sl: 1.34058 tp: 1.35787 ok
2012.04.15 00:34:53 2011.12.08 09:00 #__22 EURUSD,H1: modify #2051 sell stop 0.10 EURUSD at 1.33929 sl: 1.34284 tp: 1.32007 ok
2012.04.15 00:34:53 2011.12.08 08:00 #__22 EURUSD,H1: modify #2052 buy stop 0.10 EURUSD at 1.34287 sl: 1.33953 tp: 1.35787 ok
2012.04.15 00:34:53 2011.12.08 08:00 #__22 EURUSD,H1: modify #2051 sell stop 0.10 EURUSD at 1.33929 sl: 1.34135 tp: 1.32007 ok
2012.04.15 00:34:53 2011.12.08 07:00 #__22 EURUSD,H1: modify #2052 buy stop 0.10 EURUSD at 1.34287 sl: 1.33967 tp: 1.35787 ok
2012.04.15 00:34:53 2011.12.08 07:00 #__22 EURUSD,H1: modify #2051 sell stop 0.10 EURUSD at 1.33929 sl: 1.34102 tp: 1.32007 ok
2012.04.15 00:34:53 2011.12.08 06:00 #__22 EURUSD,H1: modify #2052 buy stop 0.10 EURUSD at 1.34287 sl: 1.33945 tp: 1.35787 ok
2012.04.15 00:34:53 2011.12.08 06:00 #__22 EURUSD,H1: modify #2051 sell stop 0.10 EURUSD at 1.33917 sl: 1.34104 tp: 1.32007 ok
2012.04.15 00:34:52 2011.12.05 01:18 #__22 EURUSD,H1: 222222222
2012.04.15 00:34:52 2011.12.05 01:18 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:52 2011.12.05 01:18 #__22 EURUSD,H1: 222222222
2012.04.15 00:34:52 2011.12.05 01:18 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:52 2011.12.05 01:18 #__22 EURUSD,H1: 222222222
2012.04.15 00:34:52 2011.12.05 01:18 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:52 2011.12.05 01:18 #__22 EURUSD,H1: 222222222
2012.04.15 00:34:52 2011.12.05 01:18 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:52 2011.12.05 01:16 #__22 EURUSD,H1: 222222222
2012.04.15 00:34:52 2011.12.05 01:16 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:52 2011.12.05 01:16 #__22 EURUSD,H1: 222222222
2012.04.15 00:34:52 2011.12.05 01:16 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:52 2011.12.05 01:16 #__22 EURUSD,H1: 222222222
2012.04.15 00:34:52 2011.12.05 01:16 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:52 2011.12.05 01:16 #__22 EURUSD,H1: 222222222
2012.04.15 00:34:52 2011.12.05 01:16 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:52 2011.12.05 01:16 #__22 EURUSD,H1: 222222222
2012.04.15 00:34:52 2011.12.05 01:16 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:52 2011.12.05 01:16 #__22 EURUSD,H1: 222222222
2012.04.15 00:34:52 2011.12.05 01:16 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:52 2011.12.05 01:16 #__22 EURUSD,H1: 222222222
2012.04.15 00:34:52 2011.12.05 01:16 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:52 2011.12.05 01:16 #__22 EURUSD,H1: 222222222
2012.04.15 00:34:52 2011.12.05 01:16 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:48 2011.11.18 01:01 #__22 EURUSD,H1: 555555555
2012.04.15 00:34:48 2011.11.18 01:01 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:48 2011.11.18 01:01 #__22 EURUSD,H1: 555555555
2012.04.15 00:34:48 2011.11.18 01:01 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:48 2011.11.18 01:01 #__22 EURUSD,H1: 555555555
2012.04.15 00:34:48 2011.11.18 01:01 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:48 2011.11.18 01:01 #__22 EURUSD,H1: 555555555
2012.04.15 00:34:48 2011.11.18 01:01 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:48 2011.11.18 01:00 #__22 EURUSD,H1: 555555555
2012.04.15 00:34:48 2011.11.18 01:00 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:48 2011.11.18 01:00 #__22 EURUSD,H1: 555555555
2012.04.15 00:34:48 2011.11.18 01:00 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:48 2011.11.18 01:00 #__22 EURUSD,H1: 555555555
2012.04.15 00:34:48 2011.11.18 01:00 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:48 2011.11.18 01:00 #__22 EURUSD,H1: 555555555
2012.04.15 00:34:48 2011.11.18 01:00 #__22 EURUSD,H1: OrderModify error 130
2012.04.15 00:34:48 2011.11.16 23:11 #__22 EURUSD,H1: close #1990 sell 0.10 EURUSD at 1.34547 sl: 1.35003 tp: 1.32785 at price 1.34546
2012.04.15 00:34:48 2011.11.16 23:10 Tester: order #1991, sell 0.10 EURUSD is opened at 1.34520
2012.04.15 00:34:48 2011.11.16 23:00 #__22 EURUSD,H1: open #1991 sell stop 0.10 EURUSD at 1.34520 sl: 1.34805 tp: 1.33020 ok
2012.04.15 00:34:48 2011.11.16 22:38 Tester: order #1990, sell 0.10 EURUSD is opened at 1.34547
2012.04.15 00:34:48 2011.11.16 22:00 #__22 EURUSD,H1: modify #1983 buy stop 0.10 EURUSD at 1.35537 sl: 1.35097 tp: 1.39461 ok
2012.04.15 00:34:48 2011.11.16 21:00 #__22 EURUSD,H1: modify #1983 buy stop 0.10 EURUSD at 1.35577 sl: 1.35137 tp: 1.39461 ok
2012.04.15 00:34:48 2011.11.16 20:00 #__22 EURUSD,H1: modify #1983 buy stop 0.10 EURUSD at 1.35577 sl: 1.35181 tp: 1.39461 ok

 
Error 130 is concerned mostly with Current_Price vs Stoploss_Distance from it. Make room for something which looks like if( MathAbs(Bid-SL_BUY)>StopLevel*Point ){ Error_130_Check=true; }
 

This is wrong

if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == FALSE) break;

You need a continue not a break.

 
You are of course perpetrating the evil "comparing un-normalised doubles" error, so they may compare greater than but actually be equal when normalised.
 
Actually none of the above. But I found the problem(s), will show you the code after I've cleaned it up a bit.
 

Ok here is the final and error free code:

//------------------------  
void ModifyPending()
   {
   int  MoveStep = 50;//External
   bool NewPrice;
   bool NewStop;
   bool NewPriceValid;
   bool NewStopValid;
   for (int i = 0; i < OrdersTotal(); i++)
      {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == FALSE) continue;
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
         {
         NewPrice = FALSE;
         NewStop = FALSE;
         NewPriceValid = FALSE;
         NewStopValid = FALSE;
         if (OrderType() == OP_BUYSTOP)
            {
            if (MathAbs(PriceBuy - OrderOpenPrice()) > MoveStep * Point) NewPrice = TRUE;//There is a new open price for the order
            if ((PriceBuy - Ask) > StopLevel * Point   ) NewPriceValid = TRUE;//That new price is outside of StopLevel
            if (MathAbs(OrderStopLoss() - SL_BUY) > Point) NewStop = TRUE;//There is a new SL price for the order
            if (MathAbs(OrderStopLoss() - SL_BUY) > StopLevel * Point) NewStopValid = TRUE;//That new price is outside of StopLevel
            if (NewPriceValid && NewStopValid && (NewPrice || NewStop))//Both open price and SL price are valid, one or both will be updated
               {//Both levels are valid (avoiding Error130), at least one will be changed (avoiding Error1):
               OrderModify(OrderTicket(), PriceBuy, SL_BUY, OrderTakeProfit(), 0, Blue);
               continue;
               }
            }
         if (OrderType() == OP_SELLSTOP)
            {
            if (MathAbs(PriceSell - OrderOpenPrice()) > MoveStep * Point) NewPrice = TRUE;//There is a new open price for the order
            if ((Bid - PriceSell) > StopLevel * Point   ) NewPriceValid = TRUE;//That new price is outside of StopLevel
            if (MathAbs(OrderStopLoss() - SL_SELL) > Point) NewStop = TRUE;//There is a new SL price for the order
            if (MathAbs(OrderStopLoss() - SL_SELL) > StopLevel * Point) NewStopValid = TRUE;//That new price is outside of StopLevel
            if ( (NewPriceValid && NewStopValid) && (NewPrice || NewStop))//Both open price and SL price are valid, one or both will be updated
               {//Both levels are valid (avoiding Error130), at least one will be changed (avoiding Error1):
               OrderModify(OrderTicket(), PriceSell, SL_SELL, OrderTakeProfit(), 0, Red);
               continue;
               }
            }
         }
      }
   return(0);
   }
//------------------------
 

So if the OrderModify fails you carry on regardless, and don't report it :-(

And if you have more than one order to modify you don't RefreshRates :-(

 

Nooo! This is the core logic, fit for BT but not (yet) for live. Still, even the earlier flawed and buggy code has done well on FT.... here it took over for another EA 2 weeks ago at order 85:

 
DayTrader:

Still, even the earlier flawed and buggy code has done well on FT.... here it took over for another EA 2 weeks ago at order 85:

Nice :-)