Mql5 backtesting: CopyTicksRange function doesn't work

 

Hello guys,

I'm using CopyTicksRange function in my EA to get MqlTick data for some calculations, but CopyTicksRange doesn't work when back-testing. Any solutions?

 
Phuc Nguyen:

Hello guys,

I'm using CopyTicksRange function in my EA to get MqlTick data for some calculations, but CopyTicksRange doesn't work when back-testing. Any solutions?

What makes your think CopyTicksRange is not working when backtesting ? It is working.
 
Alain Verleyen:
What makes your think CopyTicksRange is not working when backtesting ? It is working.

@Alain Verleyen

Hi Alain,

When back-testing, the count it returns is always 0. When I run in a demo account, the count returns is more than 1.000.000.

Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Account Properties
Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Account Properties
  • www.mql5.com
, then each symbol positions will be closed in the same order, in which they are opened, starting with the oldest one. In case of an attempt to close positions in a different order, the trader will receive an appropriate error. There are several types of accounts that can be opened on a trade server. The type of account on which an MQL5 program...
 
Phuc Nguyen:

@Alain Verleyen

Hi Alain,

When back-testing, the count it returns is always 0. When I run in a demo account, the count returns is more than 1.000.000.

I said you CopyTicksRange() is working in the Strategy Tester. Use it properly.

You didn't provide any useful information to say more.

 
Alain Verleyen:

I said you CopyTicksRange() is working in the Strategy Tester. Use it properly.

You didn't provide any useful information to say more.

@Alain Verleyen

Hi Alain,

This is my code snippet to calculate Renko bars, where I use CopyTicksRanges() to have high accuracy:

            ulong from_msc = from * 1000;
            MqlTick ticks[];
            
            int count = CopyTicksRange(_Symbol, ticks, COPY_TICKS_INFO, from_msc);
            if (count < 0)
            {
                Print("ERROR: ", ErrorDescription(GetLastError()));
                return false;
            }
            
            _tick = ticks[0];
            
            bars[1] = new UpdatableBar(_tick.bid, _tick.bid, _tick.bid, _tick.bid);
            bars[0] = new UpdatableBar(0, 0, 0, 0);
            
            for (int i = 1; i < count; i++)
            {
                _tick = ticks[i];
                Bar* previousBar = bars[1];
                
                if (_tick.bid >= previousBar.High() + _barHeight)
                {
                    int barOpenedCount = int(MathFloor((_tick.bid - previousBar.High()) / _barHeight));
                    while (barOpenedCount > 0)
                    {
                        double open = previousBar.High();
                        double close = open + _barHeight;
                        double high = close;
                        double low = open;
                        
                        UpdatableBar* currentBar = bars[0];
                        currentBar.Update(open, high, low, close);
                        
                        delete bars[Count() - 1];
                        for (int j = Count() - 1; j > 0; j--)
                        {
                            bars[j] = bars[j - 1];
                        }
                        
                        previousBar = bars[1];
                        bars[0] = new UpdatableBar(0, 0, 0, 0);
                        barOpenedCount--;
                    }
                }
                else if (_tick.bid <= previousBar.Low() - _barHeight)
                {
                    int barOpenedCount = int(MathFloor((previousBar.Low() - _tick.bid) / _barHeight));
                    while (barOpenedCount > 0)
                    {
                        double open = previousBar.Low();
                        double close = open - _barHeight;
                        double high = open;
                        double low = close;
                        
                        UpdatableBar* currentBar = bars[0];
                        currentBar.Update(open, high, low, close);
                        
                        delete bars[Count() - 1];
                        for (int j = Count() - 1; j > 0; j--)
                        {
                            bars[j] = bars[j - 1];
                        }
                        
                        previousBar = bars[1];
                        bars[0] = new UpdatableBar(0, 0, 0, 0);
                        barOpenedCount--;
                    }
                }
            }

where from is the point of time when the first bar begin, _tick is a global variable of type MqlTick, bars is a also a global variable (Bar* bars[]), and Bar is the base class of UpdatableBar.

When backtesting, I set from = TimeCurrent() - 60 * 60 * 24 * 5 (5 days ago). Back tested from 01/01/2019 to 31/12/2019, CopyTicksRange() returned no tick (count = 0). When running on a demo account, it returned a lot of ticks.

Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Account Properties
Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Account Properties
  • www.mql5.com
, then each symbol positions will be closed in the same order, in which they are opened, starting with the oldest one. In case of an attempt to close positions in a different order, the trader will receive an appropriate error. There are several types of accounts that can be opened on a trade server. The type of account on which an MQL5 program...
 
Phuc Nguyen:

@Alain Verleyen

Hi Alain,

This is my code snippet to calculate Renko bars, where I use CopyTicksRanges() to have high accuracy:

where from is the point of time when the first bar begin, _tick is a global variable of type MqlTick, bars is a also a global variable (Bar* bars[]), and Bar is the base class of UpdatableBar.

When backtesting, I set from = TimeCurrent() - 60 * 60 * 24 * 5 (5 days ago). Back tested from 01/01/2019 to 31/12/2019, CopyTicksRange() returned no tick (count = 0). When running on a demo account, it returned a lot of ticks.

In the Strategy Tester ticks are only available for the tested period. If you want ticks for 5 days back you need to start 5 days sooner, and check when your real starting date is reached.

void OnTick(void)
  {
...
  MqlTick ticks[];
  datetime from = TimeCurrent() - 60 * 60 * 24 * 5;
  ulong from_msc = from * 1000;
  int count =CopyTicksRange(_Symbol,ticks,COPY_TICKS_INFO,from_msc);
  if (count < 0)
    {
    Print("ERROR: ", _LastError);
    }
  else if(count>0)
    {
    Print(count," ticks copied");
    }
  }
2020.05.26 12:23:02.862    Core 01    2018.12.26 06:00:13   1 ticks copied
2020.05.26 12:23:02.862    Core 01    2018.12.27 00:00:08   59459 ticks copied
2020.05.26 12:23:02.862    Core 01    2018.12.28 00:00:34   209384 ticks copied
2020.05.26 12:23:02.862    Core 01    2018.12.31 00:01:34   326135 ticks copied
2020.05.26 12:23:02.862    Core 01    2019.01.02 06:00:00   172010 ticks copied
2020.05.26 12:23:02.862    Core 01    2019.01.03 00:00:06   185717 ticks copied
2020.05.26 12:23:02.862    Core 01    2019.01.04 00:00:19   328429 ticks copied
2020.05.26 12:23:02.862    Core 01    2019.01.07 00:03:47   366971 ticks copied
 
Alain Verleyen:

In the Strategy Tester ticks are only available for the tested period. If you want ticks for 5 days back you need to start 5 days sooner, and check when your real starting date is reached.

2020.05.26 12:23:02.862    Core 01    2018.12.26 06:00:13   1 ticks copied
2020.05.26 12:23:02.862    Core 01    2018.12.27 00:00:08   59459 ticks copied
2020.05.26 12:23:02.862    Core 01    2018.12.28 00:00:34   209384 ticks copied
2020.05.26 12:23:02.862    Core 01    2018.12.31 00:01:34   326135 ticks copied
2020.05.26 12:23:02.862    Core 01    2019.01.02 06:00:00   172010 ticks copied
2020.05.26 12:23:02.862    Core 01    2019.01.03 00:00:06   185717 ticks copied
2020.05.26 12:23:02.862    Core 01    2019.01.04 00:00:19   328429 ticks copied
2020.05.26 12:23:02.862    Core 01    2019.01.07 00:03:47   366971 ticks copied

@Alain Verleyen

Hi Alain,

I've realized that CopyTicksRange() doesn't work in OnInit(). Your code snippet runs well in OnTick(), but in OnInit() the count is always 0, even from is forward or backward. This problem doesn't happen on a demo account.

 
Phuc Nguyen:

@Alain Verleyen

Hi Alain,

I've realized that CopyTicksRange() doesn't work in OnInit(). Your code snippet runs well in OnTick(), but in OnInit() the count is always 0, even from is forward or backward. This problem doesn't happen on a demo account.

you might need the copyticks to pass the ticks data to tick receiving array and copyticksrange from there...i tried in my EA and it worked
 
roshjardine:
you might need the copyticks to pass the ticks data to tick receiving array and copyticksrange from there...i tried in my EA and it worked

@roshjardine

Hi Rosh,

CopyTicks still not work in OnInit(). If from_msc and count parameters are 0, it throws "Not enough memory" error. If I pass from_msc, the function returns no tick.

 
Phuc Nguyen:

@Alain Verleyen

Hi Alain,

I've realized that CopyTicksRange() doesn't work in OnInit(). Your code snippet runs well in OnTick(), but in OnInit() the count is always 0, even from is forward or backward. This problem doesn't happen on a demo account.

An other time, please don't waste people time, and post ALL the relevant information from the very beginning.

You should NEVER use functions which deal with ticks or OHLC prices in on OnInit().

 
Alain Verleyen:

An other time, please don't waste people time, and post ALL the relevant information from the very beginning.

You should NEVER use functions which deal with ticks or OHLC prices in on OnInit().

I already have a solution. Thank you everyone.