Problem with pending orders deletion

 

Hi all,


My goal is to write a simple EA that cancels pending buy stops or sell stops whenever current price moves past original stop price.

The EA - code attached below - works flawlessly for test sell stops (commented code for test sell stop). Yet, for test buy stops, the EA cancels pending order always in the next tick. To sum up, in strategy tester, no issues for sell stops; but for buy stops, it creates a test pending order, close it in the next tick, then creates another test order, close it immediately - and this process repeats indefinitely.

I am kindly asking for your input on what I missing here, since the code seems "symmetrical" for two order types from my standpoint and I can't understand such a behavior. Maybe something obvious is missing or typo is present?


Code:

// Include libraries
#include <Trade\Trade.mqh>
#include <Trade\OrderInfo.mqh>
// Add class instances
CTrade trade;
COrderInfo my_order;

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   
   // get the Ask price
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits);
   
   // get the Bid price
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits);

      // if no open positions and no order, open test pending order(s)
      if (PositionsTotal() == 0 && OrdersTotal() == 0)
      { 
       // test order buy stop
       trade.BuyStop(0.10, Ask + 100*_Point, _Symbol, Bid - 40*_Point, Ask + 250*_Point, ORDER_TIME_GTC, 0, 0);
   
       // test order sell stop
       //trade.SellStop(0.10, Bid - 100*_Point, _Symbol, Ask + 40*_Point, Bid - 250*_Point, ORDER_TIME_GTC, 0, 0);
      }
      

      
    // close pending orders that move past stop
    for(int i = OrdersTotal()-1; i>=0; i--) // count all currency pair positions
    {
     if(my_order.SelectByIndex(i))
     if(my_order.Symbol() == Symbol())
     if(my_order.OrderType() == ORDER_TYPE_BUY_STOP || my_order.OrderType() == ORDER_TYPE_SELL_STOP)
     if( MathAbs(my_order.PriceStopLimit() - my_order.PriceCurrent()) > 1*MathAbs(my_order.PriceStopLimit() - my_order.StopLoss()) )
      {
       trade.OrderDelete(my_order.Ticket());
       
      }// End if
   
     }//End for loop
   
  } // End OnTick

Testing history sample screenshot for buy stops is attached as well.

My gratitude for your time, folks!

The Fundamentals of Testing in MetaTrader 5
The Fundamentals of Testing in MetaTrader 5
  • www.mql5.com
What are the differences between the three modes of testing in MetaTrader 5, and what should be particularly looked for? How does the testing of an EA, trading simultaneously on multiple instruments, take place? When and how are the indicator values calculated during testing, and how are the events handled? How to synchronize the bars from different instruments during testing in an "open prices only" mode? This article aims to provide answers to these and many other questions.
Files:
Screen.png  173 kb
 

Check the value this is returning :

my_order.PriceStopLimit()

It's not what you are thinking it is.

 
Alain Verleyen #:

Check the value this is returning :

It's not what you are thinking it is.

Thanks for the input! According to manual, it: Gets the price of a pending order. Did I get it wrong and it works only for stop limits? I also tried PriceOpen - then my code stops working even for sell stops.

My logical condition idea is: if the absolute value between pending stop order price and current price is bigger than the absolute value of stop size (i.e., difference between order price and stop loss) -  it means price's moved past stop, and then I want EA to cancel pending stop order.

I would be grateful for an advise on which function should I use instead to get the pending stop order price, dear Alain!

 
Alain Verleyen #:

Check the value this is returning :

It's not what you are thinking it is.

I was able re-assess and write another code that works for sell stops but not for buy stops

    for(int i = OrdersTotal()-1; i>=0; i--) // count all currency pair positions
     if(m_order.SelectByIndex(i)) // access order properties by index
      if(m_order.Symbol() == Symbol())
       if(m_order.OrderType() == ORDER_TYPE_SELL_STOP)
         if(MathAbs(m_deal.Price() - m_order.PriceCurrent()) > 1*MathAbs(m_deal.Price() - m_order.StopLoss()))
           m_trade.OrderDelete(m_order.Ticket());

I also tried m_order.PriceOpen instead of m_deal.Price() - no success neither.

I realize that your help is fully voluntary, yet I would be grateful if you might help me with why the above snippet does not work when I add order type buy stop. Or any advices on how to make it work. For me, as for a novice in mql5, it would have been a dealbreaker.

 
Stanislav Hetalo #:

Thanks for the input! According to manual, it: Gets the price of a pending order. Did I get it wrong and it works only for stop limits? I also tried PriceOpen - then my code stops working even for sell stops.

My logical condition idea is: if the absolute value between pending stop order price and current price is bigger than the absolute value of stop size (i.e., difference between order price and stop loss) -  it means price's moved past stop, and then I want EA to cancel pending stop order.

I would be grateful for an advise on which function should I use instead to get the pending stop order price, dear Alain!

You need to understand what you are doing rather than trying all kind of senseless things.

PriceStopLimit() is for stop limit orders, not useful in your case. It's written nowhere that's it's the "price of a pending order".

         if(MathAbs(m_deal.Price() - m_order.PriceCurrent()) > 1*MathAbs(m_deal.Price() - m_order.StopLoss()))

Using a deal price doesn't make sense here as your order is pending, there is no deal at all !

     if( MathAbs(my_order.PriceStopLimit() - my_order.PriceCurrent()) > 1*MathAbs(my_order.PriceStopLimit() - my_order.StopLoss()) )
      {
       trade.OrderDelete(my_order.Ticket());
       
      }// End if

What is the above supposed to do ? When do you want to delete your order ?

I also tried PriceOpen - then my code stops working even for sell stops.

Do you check why ?

 

Alain Verleyen #:

You need to understand what you are doing rather than trying all kind of senseless things.

Sure, just learning by doing - yes, sometimes I am doing irrelevant things.

PriceStopLimit() is for stop limit orders, not useful in your case. It's written nowhere that's it's the "price of a pending order".

Got my mistake. Even though documentation say that explicitly - screenshot attached. But I've realized that this is implied for stop limit orders only.

What is the above supposed to do ? When do you want to delete your order ?

Whenever current price moves past stop loss level (i.e., the distance between an open price and a current price is greater than that between open price and stop loss level).

Do you check why ?

That's what I actually struggle with - this seems like a proper option, which does not work. Hence, I can't get whether I made a mistake in a logical condition, variables, syntax or maybe there is a problem with a machine setup - can't locate the issue on my own. In short, I am not sure how to properly check why PriceOpen does not work given the previous statement (should it?). That's why asking for community input.


Anyway, I remember the help is discretionary and grateful for your time, Alain!

Files:
Screen.png  22 kb
 
Stanislav Hetalo #:

Whenever current price moves past stop loss level (i.e., the distance between an open price and a current price is greater than that between open price and stop loss level).

Then code that, PriceOpen(), PriceCurrent(), Stoploss(). 

If it doesn't work then print the values in the Experts log to check why, or use the debugger. I would also suggest you to code BUY STOP and SELL STOP logic independently, it will be easier for you.

 
Alain Verleyen #:

Then code that, PriceOpen(), PriceCurrent(), Stoploss(). 

If it doesn't work then print the values in the Experts log to check why, or use the debugger. I would also suggest you to code BUY STOP and SELL STOP logic independently, it will be easier for you.

Thanks for the insight, Alain!

I printed values to the journal and found that PriceCurrent() function does not return correct value (while all other functions work correctly). It returns 0.0 as a current price. I wonder why it is happening (I'm not sure how to use debugger yet)? I have read through documentation of this function (https://www.mql5.com/en/docs/standardlibrary/tradeclasses/corderinfo/corderinfopricecurrent) and I don't see any errors in the function use.

Any hints what did I miss?

Code:

   // close pending orders that moved past stop   
   for(int i = OrdersTotal()-1; i>=0; i--) // returns the number of current orders
      if(m_order.SelectByIndex(i))     // selects the pending order by index for further access to its properties
       if(m_order.OrderType() == ORDER_TYPE_BUY_STOP)
         if(m_order.Symbol() == Symbol())
            Print("Price open:", m_order.PriceOpen());
            Print("Price current:", m_order.PriceCurrent());
            Print("Stop loss:", m_order.StopLoss());
            Print("Symbol:", m_order.Symbol());
              if(m_order.PriceCurrent() < m_order.StopLoss())
                 m_trade.OrderDelete(m_order.Ticket());

Screenshot from the experts log is attached.

Grateful for your time!

 

Screenshot from the experts log is attached.

Grateful for your time!


Added missing screenshot

By the way, are there any other way to access current price by current symbol for pending stop order?

Files:
Screen.png  176 kb
Reason: