Best way to filter Orders with Symbol and Magic Number

 

Which will be more effective, reliable and faster?

Code 1 :

void CloseOpenAndPendingTrades(int trade_close_magic)
  {
   for(int pos_0 = OrdersTotal() - 1; pos_0 >= 0; pos_0--)
     {
      OrderSelect(pos_0, SELECT_BY_POS, MODE_TRADES);
      if(OrderSymbol() != Symbol() || OrderMagicNumber() != trade_close_magic)
         continue;

      if(OrderType() > OP_SELL)
         OrderDelete(OrderTicket());
      else
        {
         if(OrderType() == OP_BUY)
            OrderClose(OrderTicket(), OrderLots(), Bid, 3, CLR_NONE);
         else
            OrderClose(OrderTicket(), OrderLots(), Ask, 3, CLR_NONE);
        }
     }
  }

Code 2 :

void CloseOpenAndPendingTrades(int trade_close_magic)
  {
   for(int pos_0 = OrdersTotal() - 1; pos_0 >= 0; pos_0--)
     {
      OrderSelect(pos_0, SELECT_BY_POS, MODE_TRADES);
      if(OrderSymbol() == Symbol() && OrderMagicNumber() == trade_close_magic)
         {

      if(OrderType() > OP_SELL)
         OrderDelete(OrderTicket());
      else
        {
         if(OrderType() == OP_BUY)
            OrderClose(OrderTicket(), OrderLots(), Bid, 3, CLR_NONE);
         else
            OrderClose(OrderTicket(), OrderLots(), Ask, 3, CLR_NONE);
        }
     }
  }
}


Using not Equal to (or) using Equal to?

 
anuj71:

Which will be more effective, reliable and faster?

Code 1 :


Code 2 :


Using not Equal to (or) using Equal to?



Builtin operators && and || perform short-circuit evaluation (do not evaluate the second operand if the result is known after evaluating the first), but overloaded operators behave like regular function calls and always evaluate both operands.


Edit:

Only optimization I can see is switching the statements, because one us using a variable, while the other has two function calls.

Depending on the optimization by the compiler, it might be irrelevant.

Edit2:
Unequal evaluates faster, if the values are actually not equal, while equal evaluation always checks the full value. Neglect the difference, it's not measurable.
 

Doesn't matter.

You are trying to save nanoseconds in order to execute trading functions that will last milliseconds - million times slower than "if" statements.

If you want to make this function faster - buy yourself a VPN close to the broker's server.

Otherwise, "if" statement reordering can save you maybe 0.0001% of the total execution time.


Regarding reliability - you should, at least, check the return value of every OrderXXX function and react in case of an error.

 

    Don't use negative logic.
              Expert Placing one pair stoploss on other pair. - MQL4 programming forum - Page 2 #17 (2020)

  1. Always test your select.
              OrderModify changing all open orders reguardless of ticket# - MQL4 programming forum #1.2 (2020)

  2. String comparisons are the slowest operations; always put them last.

  3.  if(OrderType() > OP_SELL)
    This is bad style. You are assuming the numerical values of an enumeration.
    bool OrderIsPending(int type=EMPTY){ return !OrderIsOpened(type); }
    bool OrderIsOpen(int type=EMPTY){
       if(type == EMPTY)  type = OrderType();
       return type == OP_BUY || type == OP_SELL;
    }
    
  4. There is no need to create pending orders in code.

    1. The pending has the slight advantage, A) you are closer to the top of the queue (filled quicker), B) there's no round trip network delay (filled quicker.)

      Don't worry about it unless you're scalping M1 or trading news.

    2. Humans can't watch the screen 24/7, so they use pending orders; EAs can, so no need for pending orders, have it wait until the market reaches the trigger price and just open an order.

  5. Bid and Ask do not update in your loop.

    MT4: You can use OrderClosePrice() instead of Bid/Ask and be direction independent — no need to check order type to get the close price.

    void CloseOpenAndPendingTrades(int trade_close_magic)
      {
       for(int pos_0 = OrdersTotal() - 1; pos_0 >= 0; pos_0--) if(
          OrderSelect(pos_0, SELECT_BY_POS)
       && OrderMagicNumber() == trade_close_magic
       && OrderSymbol() == Symbol()
       ){
          if(OrderType() > OP_SELL)
             OrderDelete(OrderTicket());
          else
                OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 3, CLR_NONE);
       }
    }
 

William Roeder #:

 if(OrderType() > OP_SELL)

    You mean using  if(OrderType() > OP_SELL) is not a good practices. So, alternatively i can use like this

    if(OrderType() == OP_BUYLIMIT || OrderType() == OP_BUYSTOP || OrderType() == OP_SELLLIMIT || OrderType() == OP_SELLSTOP)
    
    //OR
    
    if(OrderType() != OP_BUY && OrderType() != OP_SELL)
    William Roeder #:
    MT4: You can use OrderClosePrice()



    It says, this provide the value of Closed Price of closed order which is selected. Are you sure OrderClosePrice() will work with Open (OP_BUY/OP_SELL) orders?

     
    William Roeder #:
    Don't use negative logic

    What's wrong with negative logic? If negative logic is abandoned, each new if statement will add a new level of nesting. Moreover, negative logic is used primarily to avoid unnecessary nesting.

    (If I understand correctly what you mean by negative logic)

    (I read this post, but I didn't understand what's wrong with negative logic)


    In the code below, the functions f1() and f2() work the same. Which function do you think is better?

    void OnStart() {}
    
    bool condition1();
    bool condition2();
    bool condition3();
    bool condition4();
    
    void f1()
      {
       //...
       //__SOME_CALCULATIONS__
       //...
       if(!condition1())
          return;
       //...
       //__SOME_CALCULATIONS__
       //...
       if(!condition2())
         {
          //...
          //__SOME_CALCULATIONS__
          //...
          return;
         }
       //...
       //__SOME_CALCULATIONS__
       //...
       if(!condition3())
          return;
       //...
       //__SOME_CALCULATIONS__
       //...
       if(!condition4())
          return;
       //...
       //__SOME_CALCULATIONS__
       //...
      }
    
    void f2()
      {
       if(condition1())
         {
          //...
          //__SOME_CALCULATIONS__
          //...
          if(condition2())
            {
             //...
             //__SOME_CALCULATIONS__
             //...
             if(condition3())
               {
                //...
                //__SOME_CALCULATIONS__
                //...
                if(condition4())
                  {
                   //...
                   //__SOME_CALCULATIONS__
                   //...
                  }
               }
            }
          else
            {
             //...
             //__SOME_CALCULATIONS__
             //...
            }
         }
      }
     
    Vladislav Boyko #: What's wrong with negative logic?

    Usually wrong code.

    This rejects all orders
    if(OrderType() != OP_BUY || OrderType() != OP_SELL) continue;

    How long did it take you to see the error?

     
    William Roeder #:

    Usually wrong code.

    Typos like this happen😄

    William Roeder #:
    How long did it take you to see the error?

    In this case, not for long, since you showed one line and hinted that there was an error there. I don't know how long it would take to see this in a large EA code. It would probably also depend on the duration of continuous work and the amount of coffee drunk😄

    But I believe that such typos are not caused by the use of negative logic. That is, it’s just a typo and negative logic is not to blame.

    A typo of the same type without negative logic:

    if(OrderType() == OP_BUY && OrderType() == OP_SELL)

    I spent a long time developing without using negative logic and suffered from excessive nesting. Once I tried negative logic and it became a real breakthrough for me at the time. From that moment on, I never went back to nesting.

    Well, it’s worth adding that negative logic is closely related to the widespread use of functions/methods. A huge code written inside one OnTick is terrible, regardless of the use or not of negative logic. Exactly like functions/methods that are several screens in size.

    Complex things become simple and understandable if you break them into small parts (functions/methods/objects). Negative logic makes these parts of code even more readable and understandable.

     
    William Roeder #:

    Usually wrong code.

    This rejects all orders

    How long did it take you to see the error?

    This will not reject all the orders. it will reject only Market Executed/Open Order. it is still valid for Pending orders (Limit & Stop)

     
    anuj71 #: This will not reject all the orders. it will reject only Market Executed/Open Order. it is still valid for Pending orders (Limit & Stop)

    Thank-you for proving my point. It does reject all orders.

    if(OrderType() != OP_BUY || OrderType() != OP_SELL) continue;
     OrderType not buy
    not sell
    either
    Buy
    false
     true true
    Sell
    true
     false true
    Buy Stop
    true
     true true
    Sell Stop
    true
     true true
    Buy Limit
    true
     true true
    Sell Limit
    true  true true
     

    To obtain negation of Boolean expressions:

    First approach:

    It is the easiest one to understand. Just use a NOT (!) operator in front of the original Boolean expression and your negated Boolean expression is ready. For example

          if(OrderSymbol() == Symbol() && OrderMagicNumber() == trade_close_magic)
          {
            // processing..
          }
    
    The negated expression will be:
          if( ! (OrderSymbol() == Symbol() && OrderMagicNumber() == trade_close_magic) )
             continue;
    
    NOTICE: you need an extra pair of parentheses around the the original Boolean expression.


    Second approach:

    All you have to do is distribute the NOT (!) operator, according De Morgan’s Laws for negation of Boolean logic.
    !(a && b) is equivalent to !a || !b
    !(a || b) is equivalent to !a && !b
    

    Here’s an easy way to remember De Morgan’s Laws: move the NOT inside, AND becomes OR and OR becomes AND, and flip other operators (== becomes !=, < becomes >=, and > becomes <=).

    The negated expression will be:

          if(OrderSymbol() != Symbol() || OrderMagicNumber() != trade_close_magic)
             continue;
    
    No extra pair of  parentheses is needed!

    Regarding William's comment: <Don't use negative logic.>

    to avoid confusion with negated expressions, always imagine (or write) first the non-negated version, then NEGATE later.

     Edit:

    For optimization of filtering by multiple criteria (symbol, magic, type, etc..) , it is better to test first for the most specific criterion, then less specific criterion. This will causes early rejection of the if condition and results in faster code (utilizing the short-circuit evaluation).  

    https://runestone.academy/ns/books/published/csawesome/Unit3-If-Statements/topic-3-6-DeMorgan.html


    Reason: