MT4 Optimization / Backtest Confusion

[B]Originally posted in the wrong forum[/B]

Perhaps someone can help me identify the issue, or else confirm that it’s something I can’t ever fix because MT4 doesn’t work - here’s the issue:

I developed an EA, very simple one that places trades based on high/low channels. I have an input for the EA on time frames and run the optimization to see what’s best between M1 and D1.

7 results come back, and I take one to run in “visual mode” to see my exits/entries are all working as they should. But that backtest is completely different from the Optimization.

I go back to optimize, get the same results as before, take a different setting and run it on back test, and again, completely different results.

I go back to optimize - and now, the optimization results are completely different, off by as much as 50k.

To be clear, I’m using Tick Data through TickStory (and their launcher), with embeded spreads, I also have a spread editor which set everything to a static spread of my choosing. I disconnected the MT4 platform, so it’s not getting new spread and when I check the symbol properties in the backtester, the spread I chose is there. Since so many attribute this to a spread issue, I can confirm it’s not.

Just, what is going on?? The logic in the EA is SUPER SIMPLE, so I know it’s not the entries that are wrong, if they were I’d see that in the visual mode as well, but that’s all correct - I’m so confused …

If MT4 is dead, then can someone perhaps also suggest strong brokers outside of US/Canada (their rules I don’t like). I was trying on AxiTrader, and I’ve worked with Pepperstone who have cAlgo and MT5 … but I’d like to keep my MT4 if possible - help

Post #2

Ok, I JUST figured out what was causing the changes in results - it’s the “Timeframe” on the backtester settings itself, which is odd.

I went through the whole of my code, everything which uses a timeframe to get data (Channel, ADX, ATR, etc) are all using the input value of the timeframe, yet if I change the setting on the tester, it changes the results. I also have the “Every Tick” setting on the tester, so technically, as soon as a tick is hit on the input timeframe setting I have, it should trigger the trade regardless of the timeframe selected on the tester - why does this value change my results?

Here’s the code (simple Turtle with ADX filter as featured in a book that I liked)

input int               LongPeriod=55;
input int               ADXPeriod=14;
input int               Slip=3;
input double            LotSize=1.0;


int MagicNumber = 10001;

int OnInit()

void OnDeinit(const int reason)


void OnTick()
      int cntTurtle = 0;      

      int Slippage = Slip;
      if (Digits == 5 || Digits == 3) { Slippage = Slip * 10; }
      // Get ADX Values
      double adxValue1, adxValue2;
      adxValue1 = iADX(Symbol(),TimeFrame,14,PRICE_CLOSE,MODE_MAIN,0);      
      adxValue2 = iADX(Symbol(),TimeFrame,14,PRICE_CLOSE,MODE_MAIN,1);      

      int Counter;
      for (Counter = 0; Counter <= OrdersTotal()-1; Counter++)
         if(OrderSelect(Counter, SELECT_BY_POS))
            if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
               if(adxValue2 > 40 && adxValue1 < adxValue2 ) {
               // Bishop
                  double CloseLots = OrderLots();
                  if(OrderCloseTime() == 0 && OrderType() == OP_BUY) {
                     bool OC = OrderClose(OrderTicket(), CloseLots, Bid, Slippage, Orange);
                  } else if(OrderCloseTime() == 0 && OrderType() == OP_SELL) {
                     bool OC = OrderClose(OrderTicket(), CloseLots, Ask, Slippage, Orange);

    // Check for any trades opened that day

      if(cntTurtle == 0)
         if(adxValue1>adxValue2) { 
            // ADX Good

            double ttlHigh, ttlLow, tHigh, tLow;
            // Get Turtle Values
            ttlHigh = High[iHighest(Symbol(),TimeFrame,MODE_HIGH,55,1)];
            ttlLow = Low[iLowest(Symbol(),TimeFrame,MODE_LOW,55,1)];
            tHigh = iHigh(Symbol(),TimeFrame,0);
            tLow = iLow(Symbol(),TimeFrame,0);
            // Turtles

            // Ask = Open Buy Orders, Close Sell Orders
            // Bid = Open Sell Orders, Close Buy Orders
            if(tHigh>ttlHigh || tLow<ttlLow) {
                datetime now = Time[0], bod = now - 86400;
                for(int iPos=OrdersHistoryTotal()-1; iPos >= 0; iPos--) if (
                   OrderSelect(iPos, SELECT_BY_POS, MODE_HISTORY)  // Only orders w/
                &&  OrderMagicNumber()  == MagicNumber
                &&  OrderSymbol()       == Symbol()   
                &&  OrderCloseTime()    >= bod
                ){ cntTurtle++; }
            if(cntTurtle == 0)
               if(tHigh>ttlHigh) {
                  double lstBarLow;
                  lstBarLow = Low[iLowest(Symbol(),TimeFrame,MODE_LOW,2,1)];
                  double ATRSL = Ask - (iATR(Symbol(),TimeFrame,14,0) * 2);
                  if(ATRSL < lstBarLow) { lstBarLow = ATRSL; }
                  bool OC = OrderSend(Symbol(), OP_BUY, LotSize, Ask, Slippage, lstBarLow, 0, "Turtle", MagicNumber, 0, Green);
               } else if (tLow<ttlLow) {
                  double lstBarHigh;
                  lstBarHigh = High[iHighest(Symbol(),TimeFrame,MODE_HIGH,2,1)];
                  double ATRSL = Bid + (iATR(Symbol(),TimeFrame,14,0) * 2);
                  if(ATRSL > lstBarHigh) { lstBarHigh = ATRSL; }
                  bool OC = OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, lstBarHigh, 0, "Turtle", MagicNumber, 0, Red);

One more question I guess, lets say I do the optimization, I find that the “tester” timeframe, combined with my “input” timeframes give me a favorable result, would it be reproduce-able in forward testing I wonder?

And here is my admission of “newb” code, missing something so obvious it’s silly. For those who also miss (I hope I’m not alone) - here’s how I fixed it.

The code uses High[], Time[] and Low[] which by default uses the “Current Time Frame” and is whatever you select in the Tester. Change this for iHigh(), iTime(), iLow() and set the shift, time frame and symbols manually which will give you the desired results.

To answer my own question though, I could find favourable results by modifying which time frames are changed where as well. Finally, I have some accurate testing data :slight_smile:

This newb is signing off - happy trading :slight_smile:

  1. MT4 is not dead
  2. If you trade opens en closes at the right moments in visual mode, your script is in order also.

Are you very certain that your script runs the backtest with the exact same inputs as from the optimizer? Something must be different.

Ignore the above, I misread your last post. It appears that you found the answer yourself. Good on you. I cannot delete the post, so I just explain that I wanted to delete it if I could… :slight_smile:

But I am a bit confused how your script compiled with Hour[] instead of Hour().

Hour[] and iHour() are both in-built with mql4, however Hour[] comes from the the current symbol/timeframe properties only, all it will accept is the offset. iHour() lets you choose the Symbol/Timeframe and take the offset. All depends on what you’re working with really.

:slight_smile: I must be tired. Because you started talking about current timeframe I read High as Hour. High[] does compile Hour[] doesn’t. :slight_smile:

Thanks for the effort you took.

Axitrader? Pepperstone? You work in Australia?

Actually I’m in Canada, however the Canadian and US rules for Forex I don’t like, so taking my money offshore.