-1

Right now I select all history trades using a loop whenever there is a new history trade (onTimer handler with 1 second timer period):

/*
      3.) History Trades      
   */      

      static int historyTradesTotal=0;       
       if(OrdersHistoryTotal()==historyTradesTotal) return;
       historyTradesTotal = OrdersHistoryTotal();


         int i,hstTotal = OrdersHistoryTotal();
         string historical_trades = "";

         for(i=hstTotal; i >= 0; i--)
         {
     //---- check selection result
           if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) continue;

           historical_trades = historical_trades +

              "historical_trades|" +
              version + "|" +
              DID + "|" +
              IntegerToString(AccountNumber()) + "|" +   
              IntegerToString(OrderTicket()) + "|" +
              TimeToString(OrderOpenTime(), TIME_DATE|TIME_SECONDS) + "|" +
              TimeToString(OrderCloseTime(), TIME_DATE|TIME_SECONDS) + "|" +
              IntegerToString(OrderType()) + "|" +
              DoubleToString(OrderLots(),2) + "|" +
              OrderSymbol() + "|" +
              DoubleToString(OrderOpenPrice(),5) + "|" +
              DoubleToString(OrderClosePrice(),5) + "|" +
              DoubleToString(OrderStopLoss(),5) + "|" +
              DoubleToString(OrderTakeProfit(),5) + "|" +
              DoubleToString(OrderCommission(),2) + "|" + 
              DoubleToString(OrderSwap(),2) + "|" +
              DoubleToString(OrderProfit(),2) + "|" +
              "<" + OrderComment() + ">|"; 
         }
}

So now how can I just select the orders that have been closed between the last onTimer event to avoid looping through all trades whenever a new one is closed all the time?

The solution should also consider the rare case if two or more trades are closed parallely within one second e.g..

JSRB
  • 2,492
  • 1
  • 17
  • 48

2 Answers2

3
  int i = OrdersHistoryTotal(); 
  int a = OrdersHistoryTotal() - 10;
  int b = OrdersHistoryTotal();
   
  for (i = a;i < b ;i++)
     {
           if (OrderSelect(i,SELECT_BY_POS, MODE_HISTORY) == true)
              {      
                
                 Alert("orders found"+ OrderTicket() + " " + OrderCloseTime());
              
              }
     }

This code works and it's starts from the 10th order from the most previous order in history but if you wanted to check just the previous order you could subsitute 10 for 1 in int a. if you want to check only the last 5 orders change 10 to 5. Simple.

2

That is not possible in MQL4. Orders are stored and returned by their ids, you cannot apply custom sort. so you have to loop over them all starting from the last to find the one you need. Alternative is to keep all the open orders in CArrayInt or array (add when a new trade is open, delete when found a closed one, read/write when doing init/deinit) and check the live_trades_array elements are still open. That might be much faster if your ea has just several orders and several different ea's on the platform.

Daniel Kniaz
  • 4,603
  • 2
  • 14
  • 20