How to get data from orders generated in strategy tester (offline) and write to .csv file ?

 

Hi everyone, I'm trying to run a backtest on an EA (using offline charts), and then call a routine from the deinit() function that will extract certain information about each trade generated in the strategy tester.

(On a side note - specically, I am working on getting the drawdown (and run up) stats at the individual trade level for each trade in a backtest for the purpose of computing certain statistics, such as Maximum Favorable Excursion (MFE) and Maximum Adverse Excursion (MAE), and Jack Schwager's Average Maximum Retracement (AMR).

I want to write the data to a .csv file, where I can open it with Excel and use a macro to process the data into the stats I am after on a spreadsheet.

What I need help with:

I know how to do everything except access the orders generated in the backtest. When I add the following code (see below) to my deinit() function, it returns "0" for the OrdersTotal() function, which is assigned to the variable int "totals." (I used a Print("Total #" + totals) statement to get the count). So I guess OrdersTotal() only counts the orders under the "accounts" tab, which is referring to the orders associated with the account #. Is this correct? If so, then is there another function I can use for the backtest-generated orders? Or is there a way to set the backtest-generated orders as the orders read in the accounts tab by the OrdersTotal() function?

I have been struggling with this for a while and I could use a few pointers. So, if anyone could help me with this, I'd appreciate it. Thanks.

Th deinit() code I am working with (from the mql4 code library):

(Note: I am just using the items in the FileWrite() function as placeholders for now just to get it working. Later, I will customize these to the data I want).

int deinit() 
{ 
   if(IsTesting()==true)
      int handle=FileOpen("OrdersReport.csv",FILE_WRITE|FILE_CSV,",");
         if(handle<0) return(0);
  // write header
            FileWrite(handle,"#","open price","open time","symbol","lots");
      int total=OrdersTotal();
  // write open orders
      for(int pos=0;pos<total;pos++)
      {
         if(OrderSelect(pos,SELECT_BY_POS)==false) //continue;
            FileWrite(handle,OrderTicket(),OrderOpenPrice(),OrderOpenTime(),OrderSymbol(),OrderLots());
      }
      FileClose(handle);
   
return(0); 
 
outofdebt:

When I add the following code (see below) to my deinit() function, it returns "0" for the OrdersTotal() function, which is assigned to the variable int "totals." (I used a Print("Total #" + totals) statement to get the count). So I guess OrdersTotal() only counts the orders under the "accounts" tab, which is referring to the orders associated with the account #. Is this correct?

No, it's not correct, I have a function to check open and pending orders and it works fine in the Strategy Tester, I don't use offline charts but i don't think that would be causing this issue. I don't know for a fact . . but perhaps the issue is that you are trying to do this from deinit . . . perhaps you could move the code out of deinit for testing purposes to see if it works . . . ?
 

At the end of a test run, all open orders are closed by the tester. So by the time deinit runs OrdersTotal will ALWAYS be zero.

Why don't you try reading the HISTORY list, not the OPEN list.

    static datetime lastClose;  datetime lastClosePrev = lastClose;
    for(int pos=0; pos < OrdersHistoryTotal(); pos++) if (
        OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY)   // Only orders w/
    &&  OrderCloseTime()    > lastClosePrev             // not yet processed,
    &&  OrderMagicNumber()  == magic.number             // my magic number
    &&  OrderSymbol()       == Symbol()                 // and my pair.
    &&  OrderType()         <= OP_SELL){// Avoid cr/bal forum.mql4.com/32363#325360
        lastClose = OrderCloseTime();
...
I don't know if you can do it in deinit, you may have to do it in start.
 
WHRoeder:

At the end of a test run, all open orders are closed by the tester. So by the time deinit runs OrdersTotal will ALWAYS be zero.

Why don't you try reading the HISTORY list, not the OPEN list.

I don't know if you can do it in deinit, you may have to do it in start.

Cool! That is exactly what I needed! Thanks. I have tried similar things, but for some reason I could not get the OrdersHistoryTotal() function to work. But it works now! All I did was change this:

if(OrderSelect(pos,SELECT_BY_POS)==false) continue;

to this:

if(OrderSelect(pos,SELECT_BY_POS, MODE_HISTORY)==false) continue;
and this:
OrdersTotal()

to this:

OrdersHistoryTotal()
It now does what I want ... and yes - it does work fine after the backtest in the deinit() function.
Reason: