How do you call a function from within a second function? Online help is not cutting it - page 2

 
nadiawicket:

Why is this code:

Not having my desired effect of only selecting the order if its OrderOpenTime() is larger than the previous one?


Because you are comparing the same ticket! You might as well be using this, because it does the same thing.

bool CompareTheSameTicketExpectADifferentResult__WHYYYY()
{
   datetime time1;
   if(OrderSelect(0,SELECT_BY_POS))
      time1 = OrderOpenTime();
   if(OrderSelect(0,SELECT_BY_POS))
      if(OrderOpenTime() > time1)
         return true;
   return false;
}
 

Awesome posts btw Ill sort this out hopefully so confused thx 

 
nadiawicket:

Awesome posts btw Ill sort this out hopefully so confused thx 


If you're looking for the absolute most simple implementation without any other functionality then you could try this.

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
//---
    if(SelectMostRecentlyOpenedTicket())
      Print("The ticket selected is ",OrderTicket());
}
//+------------------------------------------------------------------+
bool SelectMostRecentlyOpenedTicket()
{
   int ticket=0;
   datetime time=0;
   for(int i=OrdersTotal()-1;OrderSelect(i,SELECT_BY_POS);i--)
   {
      if(OrderOpenTime() > time)
      {
         ticket = OrderTicket();
         time = OrderOpenTime();
      }
   }
   return OrderSelect(ticket,SELECT_BY_TICKET);
}
 
nicholishen:

If you're looking for the absolute most simple implementation without any other functionality then you could try this.


awesome this looks it!! lemme check it out, you the best help online ever

 

Thanks a zillion zillion zillion zillion, I finally got it down with your 

bool SelectMostRecentlyOpenedTicket()
  {
   int ticket=0;
   datetime time=0;
   for(int i=OrdersTotal()-1;OrderSelect(i,SELECT_BY_POS);i--)
     {
      if(OrderOpenTime()>time)
        {
         ticket=OrderTicket();
         time=OrderOpenTime();
        }
     }
   return OrderSelect(ticket,SELECT_BY_TICKET);
  }
 
for(int i=OrdersTotal()-1;OrderSelect(i,SELECT_BY_POS);i--)

Do not do this when there is any delay inside the loop (server calls, sleep etc.) Any delays and you could break out of the loop prematurely and miss other valid orders.

Instead use:
for(int i=OrdersTotal()-1;i>=0;--i)if(OrderSelect(i,SELECT_BY_POS) )
Or
int i=OrdersTotal(); while(i>0)if(OrderSelect(--i,SELECT_BY_POS) )

In the presence of multiple orders (one EA multiple charts, multiple EAs, manual trading,) because while you are waiting for the current operation (closing, deleting, modifying) to complete, any number of other operations on other orders could have concurrently happened and changed the position indexing:
  1. For non-FIFO (US brokers,) (or the EA only opens one order per symbol,) you can simply count down in a position loop, and you won't miss orders. Get in the habit of always counting down.
              Loops and Closing or Deleting Orders - MQL4 and MetaTrader 4 - MQL4 programming forum
  2. For FIFO (US brokers,) and you (potentially) process multiple orders per symbol, you must count up and on a successful operation, reprocess all positions (set index to -1 before continuing.)
  3. and check OrderSelect in case earlier positions were deleted.
              What are Function return values ? How do I use them ? - MQL4 and MetaTrader 4 - MQL4 programming forum
               Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles
  4. and if you (potentially) process multiple orders, must call RefreshRates() after server calls if you want to use the Predefined Variables (Bid/Ask) or OrderClosePrice() instead, on the next order/server call.
 
whroeder1:

Do not do this when there is any delay inside the loop (server calls, sleep etc.) Any delays and you could break out of the loop prematurely and miss other valid orders.

Instead use:
Or


Those examples whroeder provided would face the same challenge if a new order arrived. If you want to totally avoid order-collision issues then don't use either of our examples and instead restart the loop if it detects a new order.

 for(int total=OrdersTotal(),i=total-1;OrderSelect(i,SELECT_BY_POS);i--)
   {
      if(OrdersTotal() != total)
      {
         i=total=OrdersTotal();
         continue;
      }
      //rest of code here
   }
 
nicholishen: If you want to totally avoid order-collision issues then don't use either of our examples and instead restart the loop if it detects a new order.

No need. The current code didn't add a new order, so no need to look at new ones.

 
whroeder1:

No need. The current code didn't add a new order, so no need to look at new ones.


No, but an EA on a separate thread could have, isn't that the point you were trying to make? Otherwise calling OrderSelect outside of the loop declaration and inside of the for-block is redundant because you're checking the iterator twice, once in the for loop and once again in the OrderSelect function. What would cause OrderSelect to return false other than array out of range?

 
  1. Yes a separate thread could have, so what? The point I made was a separate thread could delete/remove/close earlier trades and that changes positions and must be accounted for. Other threads adding later positions are irrelevant.
  2. Read the link previously provided. It shows examples how OrderSelect would return false.




Reason: