Backtesting Multi-Currency EA - page 3

 

I wanted to publish this at that time, but looked horribly on the front page:

Logics of a Portfolio EA 

 

Hi guys and gals,

I ran into this issue too some time ago and we discussed it here: https://www.mql5.com/en/forum/1642

My EA has an open prices only strategy and I wanted to stick to that to save time during backtesting (obviously).

The solution I devised is as follows:

  1. use the most active pair during the main trading period of your EA as the 'driver' (the chart that produces the ticks).
  2. in each onTick() check whether your driver entered a new bar
    1. if there's no new bar, wait a little longer
    2. if there's a new bar, distribute the OnTick() message to your individual traders (each trader is responsible for one currency pair)
  3. in the trader check whether the last time of the trader's currency pair is equal to the "new bar time" from the driver
    1. if yes, you can continue as normal
    2. if no, you have to treat the closing price of the current bar as the opening price you're looking for and if you're looking for info from previous bars take this "off by one" situation into account.

I will cut and paste the important sections of code from my EA below here. I hope this will be of any help to you!

Cheers!


// this is from the Trader base class

    // manage a new tick and predetermines whether a new bar hast started
    virtual void onTick() {
        MqlRates rates[1];
    
        // check the rates of the tick stream we're attached to (_Symbol!!!)
        if (CopyRates(_Symbol, _period, 0, 1, rates) != 1) {
            Print("CopyRates of ", _Symbol, " failed");
            return;
        }

        if (_newBar = (rates[0].time != _currBarTime)) {
            _prevBarTime = _currBarTime;  // remember the previous bar time
            _currBarTime = rates[0].time;  // remember the current bar time
        }

    }


// this is the actual trader for a specific currency pair

    // checks whether a new trade (closing or opening) is to be performed
    void checkForTrade(void) {    
    
        MqlRates rates[3];

        if (CopyRates(_symbol, _period, 0, 3, rates) != 3) {
            Print("CopyRates of ", _symbol, " failed");
            return;
        }

        bool inSameBar = (rates[2].time == _currBarTime);  // _currBarTime determined in OnTick()!


        double sBuf[3];  // signal buffer! 2: current bar, 1: previous bar, 0: current - 2 

        if (CopyBuffer(_ind, SIGNAL3, 0, 3, sBuf) != 3) {
            Print("copy signal from indicator failed, no data");
            return;
        }    
        
        
        // first close exiting orders
        double v0 = inSameBar ? sBuf[0] : sBuf[1];  // determine the actual 'previous' bar
        double v1 = inSameBar ? sBuf[1] : sBuf[2];  // determine the actual 'current' bar
        
        if (_volume > 0) {
            if (crossesZeroDownwards(v0, v1)) {  // cross down?
                setReqVolume(0);  // close this order
                tradeCloses = true;
            }    
        } else if (_volume < 0) {
            if (crossesZeroUpwards(v0, v1)) {  // cross up?
                setReqVolume(0);  // close this order
                tradeCloses = true;
            }    
        }

        ...
Tick generation - Open bar only
  • www.mql5.com
The whole list printed shows also many discrepancies in times.
 

Just came across this problem myself. You've guessed it, trying to port from JForex to MQL5! I'm beginning to wish I hadn't bothered, though I suppose the deadline extension helps :)

Looks like MetaQuotes still haven't fixed it.

MT5 forex doesn't appear to support DOM.

isNewBar won't help me.

Seems a ridiculous state of affairs.

Does anyone know if anything has changed inside MT5 regarding this issue?

Does anyone know of a solution that works for a multi-currency strategy that is expecting to be fed ticks?

Yours in frustration,

Jim

 
TradingGurus:

Just came across this problem myself. You've guessed it, trying to port from JForex to MQL5! I'm beginning to wish I hadn't bothered, though I suppose the deadline extension helps :)

Looks like MetaQuotes still haven't fixed it.

MT5 forex doesn't appear to support DOM.

isNewBar won't help me.

Seems a ridiculous state of affairs.

Does anyone know if anything has changed inside MT5 regarding this issue?

Does anyone know of a solution that works for a multi-currency strategy that is expecting to be fed ticks?

Yours in frustration,

Jim


Try using OnTimer() with 1 second timer instead of OnTick().
 

Hi enivid,

enivid:
Try using OnTimer() with 1 second timer instead of OnTick().

Thanks for the suggestion. Your solution works far better than any of the others I've tried, certainly for our requirements.

However running multi-currency backtests against different pairs still produces slightly different results.

Doesn't inspire huge amounts of confidence!

I'm off to burn a lot more midnight oil now!

Cheers,

Jim

 
enivid:
Try using OnTimer() with 1 second timer instead of OnTick().

TradingGurus:

  

However running multi-currency backtests against different pairs still produces slightly different results.

Jim, I use the OnTimer solution with 1 second in my contest portfolio EA. If your strategy relies on every tick, then yes, you will get different results when using OnTimer vs OnTick on a single currency since more than one tick per second is possible. I found that it usually makes the most difference when the "missing" tick created a new bar high or low. You can check the previous bar high/low and current bar high/low for any changes and insert these as a "missing tick" when they occur, unless of course the current tick created the new bar high/low.

 Also remember that the MetaTrader Strategy Tester only simulates tick data. Depending on how sensitive your strategy is with tick movement, this simulation may have a significant impact on back-testing vs forward testing.

 - Patrick 

 
Hi Patrick,
Pix:

If your strategy relies on every tick, then yes, you will get different results when using OnTimer vs OnTick on a single currency since more than one tick per second is possible.

 - Patrick 


That's not quite what I meant. Our (still only potential!) contest EA trades all 12 pairs. Using OnTimer() only, I get different backtest results if I select GBP/USD in strategy tester rather then EUR/USD for example.

I am all too familiar with the limitations of MT4 when backtesting using simulated ticks. Unfortunately it looks like MT5 isn't a whole lot better!

Jim

 

We were extremely keen to get this all going with ticks for historical reasons, but we've given up. Just can't get things consistent.

We've bitten the bullet, and are now working with 1 minute bars with the help of OnTimer() and isNewBar().

Things have begun to look vaguely sensible at long last, and what's more there's still 4 hours to go to the championship deadline :)

Jim
 

Finally submitted our EA with about 5 minutes to spare before the deadline.

One backtest under its belt, and no optimization.

Never having done this before, can anyone tell me if it still stands a chance of getting approved?

If so, will we be allowed to fiddle with the input settings over the next week, or not?

Jim

 
TradingGurus:

Finally submitted our EA with about 5 minutes to spare before the deadline.

One backtest under its belt, and no optimization.

Never having done this before, can anyone tell me if it still stands a chance of getting approved?

If so, will we be allowed to fiddle with the input settings over the next week, or not?

Jim

Good Luck Jim!

 If your EA backtested correctly within 2010.01.01 up to 2010.08.01 without any errors (trade errors, etc.) and a profit, then you will likely get approved, as long as your personal info is also correct. However, you will not be able to change anything from this point forward, including settings (input parameters)

I hope to see your bot in action!

- Patrick 

Reason: