It turns out you can use MT4’s Strategy Tester to collect trading data on your portfolio EA that can then be analyzed by MT4 Tracker. This is very useful because it allows you to analyze each strategy’s performance and potentially exclude it from the portfolio before you use the portfolio EA in a demo or live account. Furthermore, MT4’s Strategy Tester uses your broker’s data — which may be slightly different than the data set used to generate / train the strategies in your portfolio EA.
By default, the *.mq4 portfolio EA created by EA Studio does not use an ‘OnDeinit’ function. You can safely add the code below anywhere in the source code file and it will be called by Strategy Tester when the back testing completes. The code inside this OnDeinit() function only executes during back testing — as you can see from the use of the conditional ‘if(true == MQLInfoInteger(MQL_TESTER))’.
MT4 Tracker can also insert this code for you. When you follow the procedure to exclude strategies from the portfolio EA then MT4 Tracker will insert the OnDeinit() function, in addition to modifying the source code to exclude strategies.
//+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // $(MT4 TRACKER ) void OnDeinit(const int reason) { if(true == MQLInfoInteger(MQL_TESTER)) { string strLogFilename = "StrategyTester" + "_" + _Symbol + "_" + IntegerToString(_Period) + ".log"; // If the file already exists, then delete it... int handle = FileOpen( strLogFilename, FILE_READ | FILE_TXT ); if (handle != INVALID_HANDLE) { FileClose(handle); FileDelete(strLogFilename); handle = INVALID_HANDLE; } // Create the LogFile... handle = FileOpen(strLogFilename,FILE_CSV|FILE_WRITE|FILE_READ,","); if (handle < 0) { Print("*** ERROR: OnDeInit: Could not create log file: ", strLogFilename ); return; } int PosType; double Lots; datetime OpenTime; double OpenPrice; double StopLossPrice; double TakeProfitPrice; double Profit; double Commission; // long Ticket; string PosComment; long MagicNumber; int iHistoryTotal = OrdersHistoryTotal(); for(int i = 0; i < iHistoryTotal; i++) { if(!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) { // Print("Error with OrderSelect: ",GetErrorDescription(GetLastError())); // Comment("Cannot check current position!"); continue; } if(OrderType()==OP_BUYLIMIT || OrderType()==OP_SELLLIMIT || OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP) { // Print("Trade [" + IntegerToString(i) + "]: Pending Order"); continue; // A pending order. } PosType = OrderType(); OpenTime = OrderOpenTime(); OpenPrice = OrderLots() * OrderOpenPrice(); Lots = OrderLots(); Commission = OrderCommission(); Profit = OrderProfit() + OrderCommission(); StopLossPrice = OrderStopLoss(); TakeProfitPrice = OrderTakeProfit(); PosComment = OrderComment(); MagicNumber = OrderMagicNumber(); string text = "Trade [" + IntegerToString(i) + "]: " "Time=" + TimeToString(OpenTime,TIME_SECONDS) +", "+ "Type=" + (PosType==OP_BUY ? "Long" : "Short") +", "+ "Lots=" + DoubleToString(Lots,2) +", "+ "Price=" + DoubleToString(OpenPrice,_Digits) +", "+ "StopLoss=" + DoubleToString(StopLossPrice,_Digits) +", "+ "TakeProfit=" + DoubleToString(TakeProfitPrice,_Digits) +", "+ "Commission=" + DoubleToString(Commission,2) +", "+ "MagicNumber=" + IntegerToString(MagicNumber) +", "+ "Profit=" + DoubleToString(Profit,2); string text2 = IntegerToString(MagicNumber) + "::" + DoubleToString(Profit,2); // Write line to log file... FileWrite( handle, text2 ); } FileFlush(handle); FileClose(handle); } return; }