Backtesting on Multi Timeframe

Created at 09 Apr 2024, 14:56
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
SE

sebastien.t

Joined 12.03.2024

Backtesting on Multi Timeframe
09 Apr 2024, 14:56


Good day,

 

I built a Cbot that running on H1 but checking some data on the Daily and H4 timeframe. 

On every timeframe, H1, H4 and Daily, I am retrieving the data with that piece of code :

Bars _OfTimeFrameBars = MarketData.GetBars(OfTimeFrame, SymbolName);

 

The bot is working perfectly well on the Live market. But when I try to run a Backtest session, I am able to launch the backtest but nothing happens. 

 

See this short video

https://www.loom.com/share/188695596c3e40e5871401caca245370?sid=e7262122-1c6f-47de-b52c-23968bc9554b

Thank you for your help

 


@sebastien.t
Replies

PanagiotisCharalampous
10 Apr 2024, 06:05

Hi there,

Feel free to share the cBot code with us so that we can investigate further.

Best regards,

Panagiotis


@PanagiotisCharalampous

sebastien.t
20 Apr 2024, 10:02

RE: Backtesting on Multi Timeframe

PanagiotisCharalampous said: 

Hi there,

Feel free to share the cBot code with us so that we can investigate further.

Best regards,

Panagiotis

Good day, thank you for your answer. 

I can't share my full bot with you, I spent so many weeks/months to build my model…

But I can share a very simple piece of code that even doesn't work on Backtesting b ut works perfectly fine on a classic run.

I tried to run it on NSDQ and EURUSD on backtesting mode. the process starts but runs forever without any log

Thank you

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
   [Robot(AccessRights = AccessRights.None)]
   public class EasyHistoLoad : Robot
   {
       

       protected override void OnStart()
       {
 

           DateTime time_to_test = Bars[Bars.Count()-5].OpenTime.AddDays(-15);
           Print(time_to_test);
 

           // Get m1 Bars
           Bars _OfTimeFrameBars = MarketData.GetBars(TimeFrame.Minute, SymbolName);
           var LastOpenTimeLoaded = _OfTimeFrameBars.OpenTimes[0];
           Print("_OfTimeFrameBars.OpenTimes[0] "+ _OfTimeFrameBars.OpenTimes[0] + " time_to_test "+ time_to_test);
           while (_OfTimeFrameBars.OpenTimes[0] > time_to_test){
               var numberOfLoadedBars = _OfTimeFrameBars.LoadMoreHistory();

               Print("_OfTimeFrameBars.OpenTimes[0] "+ _OfTimeFrameBars.OpenTimes[0] + " time_to_test "+ time_to_test);
               if (LastOpenTimeLoaded==_OfTimeFrameBars.OpenTimes[0]){
                   Print( SymbolName + " Error could not load deeper historical data, last data is "+_OfTimeFrameBars.OpenTimes[0]);
                   
               }
               LastOpenTimeLoaded=_OfTimeFrameBars.OpenTimes[0];
           }

           Print("Finish to load, first bar is "+_OfTimeFrameBars.OpenTimes[0]);
       }

       protected override void OnTick()
       {
           // Handle price updates here
       }

       protected override void OnStop()
       {
           // Handle cBot stop here
       }
   }
}


@sebastien.t

PanagiotisCharalampous
22 Apr 2024, 06:18

Hi there,

Your problem is here

           while (_OfTimeFrameBars.OpenTimes[0] > time_to_test){
               var numberOfLoadedBars = _OfTimeFrameBars.LoadMoreHistory();

LoadMoreHistory does not work in backtesting therefore your code enters an infinite loop.

Best regards,

Panagiotis


@PanagiotisCharalampous

sebastien.t
22 Apr 2024, 07:44

RE: Backtesting on Multi Timeframe

Good day,

thank you for your answer. 

Do you have a workaround? 

The idea of my code/bot is to check some data in the past for the H4 to know if I am bullish or bearish and the to deep dive in the 1 minute chart. 

Basically I have to go 60 bars on the timeframe and then go to the m1. Let s say I want to backtest from the 1st february, I check the H4 10 days before (60*4/24), that should be around mid of January and then I check some data on that date on the m1.

So most of the time I need to LoadMoreHistory on the m1.

Thank you

Seb

PanagiotisCharalampous said: 

Hi there,

Your problem is here

           while (_OfTimeFrameBars.OpenTimes[0] > time_to_test){               var numberOfLoadedBars = _OfTimeFrameBars.LoadMoreHistory();

LoadMoreHistory does not work in backtesting therefore your code enters an infinite loop.

Best regards,

Panagiotis

 


@sebastien.t

PanagiotisCharalampous
22 Apr 2024, 08:53

RE: RE: Backtesting on Multi Timeframe

sebastien.t said: 

Good day,

thank you for your answer. 

Do you have a workaround? 

The idea of my code/bot is to check some data in the past for the H4 to know if I am bullish or bearish and the to deep dive in the 1 minute chart. 

Basically I have to go 60 bars on the timeframe and then go to the m1. Let s say I want to backtest from the 1st february, I check the H4 10 days before (60*4/24), that should be around mid of January and then I check some data on that date on the m1.

So most of the time I need to LoadMoreHistory on the m1.

Thank you

Seb

PanagiotisCharalampous said: 

Hi there,

Your problem is here

           while (_OfTimeFrameBars.OpenTimes[0] > time_to_test){               var numberOfLoadedBars = _OfTimeFrameBars.LoadMoreHistory();

LoadMoreHistory does not work in backtesting therefore your code enters an infinite loop.

Best regards,

Panagiotis

 

Hi Seb,

The workaround I use is to start the backtesting at earlier dates so that all the necessary information is loaded, while skipping all trading operations until a custom defined date. So I have a set of parameters like this

which replace the backtesting start date and I move my backtesting start date as far in the past as I want.

Best regards,

Panagiotis


@PanagiotisCharalampous

sebastien.t
22 Apr 2024, 09:11

RE: RE: RE: Backtesting on Multi Timeframe

Thank s for your answer, that seems a very nice option!

 

PanagiotisCharalampous said: 

sebastien.t said: 

Good day,

thank you for your answer. 

Do you have a workaround? 

The idea of my code/bot is to check some data in the past for the H4 to know if I am bullish or bearish and the to deep dive in the 1 minute chart. 

Basically I have to go 60 bars on the timeframe and then go to the m1. Let s say I want to backtest from the 1st february, I check the H4 10 days before (60*4/24), that should be around mid of January and then I check some data on that date on the m1.

So most of the time I need to LoadMoreHistory on the m1.

Thank you

Seb

PanagiotisCharalampous said: 

Hi there,

Your problem is here

           while (_OfTimeFrameBars.OpenTimes[0] > time_to_test){               var numberOfLoadedBars = _OfTimeFrameBars.LoadMoreHistory();

LoadMoreHistory does not work in backtesting therefore your code enters an infinite loop.

Best regards,

Panagiotis

 

Hi Seb,

The workaround I use is to start the backtesting at earlier dates so that all the necessary information is loaded, while skipping all trading operations until a custom defined date. So I have a set of parameters like this

which replace the backtesting start date and I move my backtesting start date as far in the past as I want.

Best regards,

Panagiotis

 


@sebastien.t

sebastien.t
22 Apr 2024, 19:44 ( Updated at: 23 Apr 2024, 05:47 )

RE: RE: RE: RE: Backtesting on Multi Timeframe

Hi Panagiotis,

I tried to use your workaround but it doesn't really work for 2 reasons :

1/ if I want to backtest the bot that I use on Live market I can't change a lot of code and so I have to keep using the same functions. It seems that even if the history date are loaded (I can see see it if I check the date with Bars[0]), I can't recall that data with the MarketData.GetBars

2/ To run the Backtest I have to choose 1 timeframe (let s say H1) but in my bot I need check the historical data of the H4 and the Daily. And so even if I start the backtest to beofre my “real” backtesting date to load the data, it loads only the data for H1 and not for H4/Daily.

Here is my code

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using cAlgo.API;

using cAlgo.API.Collections;

using cAlgo.API.Indicators;

using cAlgo.API.Internals;


 

namespace cAlgo.Robots

{

[Robot(AccessRights = AccessRights.None)]

public class EasyHistoLoad : Robot

{

 

[Parameter("Backtest On/Off", Group = "BackTest", DefaultValue = false)]

public bool BackTest { get; set; }


 

[Parameter("Backtest Date", Group = "BackTest", DefaultValue = "2024/03/01 01:00:00")]

public string BackTestDate { get; set; }


 

protected override void OnStart()

{

// To learn more about cTrader Automate visit our Help Center:

// https://help.ctrader.com/ctrader-automate


 

// Print(Bars.Count());

DateTime time_to_test = Bars[Bars.Count()-5].OpenTime.AddDays(-15);

// Print(time_to_test);

// Get m1 Bars

 

if(BackTest && Bars.Last().OpenTime>DateTime.Parse(BackTestDate)){


 

Bars _OfTimeFrameBars = MarketData.GetBars(TimeFrame.Minute, SymbolName);

var LastOpenTimeLoaded = _OfTimeFrameBars.OpenTimes[0];

 

Print("Bars[0].OpenTime " + Bars[0].OpenTime+ " _OfTimeFrameBars.OpenTimes[0] "+ _OfTimeFrameBars.OpenTimes[0] + " time_to_test "+ time_to_test);

if (_OfTimeFrameBars.OpenTimes[0] > time_to_test){

Print("_OfTimeFrameBars is not using Bars history already loaded");


 

}


 

}

}


 

protected override void OnBarClosed()

{

DateTime time_to_test = Bars[Bars.Count()-5].OpenTime.AddDays(-15);

 

if(BackTest && Bars.Last().OpenTime>DateTime.Parse(BackTestDate)){


 

Bars _OfTimeFrameBars = MarketData.GetBars(TimeFrame.Minute, SymbolName);

var LastOpenTimeLoaded = _OfTimeFrameBars.OpenTimes[0];

 

 

Print("Bars[0].OpenTime " + Bars[0].OpenTime+ " _OfTimeFrameBars.OpenTimes[0] "+ _OfTimeFrameBars.OpenTimes[0] + " time_to_test "+ time_to_test);

if (_OfTimeFrameBars.OpenTimes[0] > time_to_test){

 

Print("_OfTimeFrameBars is not using Bars history already loaded");

 

}


 

 

}

}


 

protected override void OnStop()

{

// Handle cBot stop here

}

}

}

 

 

 

 

 

 

 

sebastien.t said: 

Thank s for your answer, that seems a very nice option!

 

PanagiotisCharalampous said: 

sebastien.t said: 

Good day,

thank you for your answer. 

Do you have a workaround? 

The idea of my code/bot is to check some data in the past for the H4 to know if I am bullish or bearish and the to deep dive in the 1 minute chart. 

Basically I have to go 60 bars on the timeframe and then go to the m1. Let s say I want to backtest from the 1st february, I check the H4 10 days before (60*4/24), that should be around mid of January and then I check some data on that date on the m1.

So most of the time I need to LoadMoreHistory on the m1.

Thank you

Seb

PanagiotisCharalampous said: 

Hi there,

Your problem is here

           while (_OfTimeFrameBars.OpenTimes[0] > time_to_test){               var numberOfLoadedBars = _OfTimeFrameBars.LoadMoreHistory();

LoadMoreHistory does not work in backtesting therefore your code enters an infinite loop.

Best regards,

Panagiotis

 

Hi Seb,

The workaround I use is to start the backtesting at earlier dates so that all the necessary information is loaded, while skipping all trading operations until a custom defined date. So I have a set of parameters like this

which replace the backtesting start date and I move my backtesting start date as far in the past as I want.

Best regards,

Panagiotis

 

 


@sebastien.t

PanagiotisCharalampous
23 Apr 2024, 06:05

RE: RE: RE: RE: RE: Backtesting on Multi Timeframe

sebastien.t said: 

Hi Panagiotis,

I tried to use your workaround but it doesn't really work for 2 reasons :

1/ if I want to backtest the bot that I use on Live market I can't change a lot of code and so I have to keep using the same functions. It seems that even if the history date are loaded (I can see see it if I check the date with Bars[0]), I can't recall that data with the MarketData.GetBars

2/ To run the Backtest I have to choose 1 timeframe (let s say H1) but in my bot I need check the historical data of the H4 and the Daily. And so even if I start the backtest to beofre my “real” backtesting date to load the data, it loads only the data for H1 and not for H4/Daily.

Here is my code

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using cAlgo.API;

using cAlgo.API.Collections;

using cAlgo.API.Indicators;

using cAlgo.API.Internals;


 

namespace cAlgo.Robots

{

[Robot(AccessRights = AccessRights.None)]

public class EasyHistoLoad : Robot

{

 

[Parameter("Backtest On/Off", Group = "BackTest", DefaultValue = false)]

public bool BackTest { get; set; }


 

[Parameter("Backtest Date", Group = "BackTest", DefaultValue = "2024/03/01 01:00:00")]

public string BackTestDate { get; set; }


 

protected override void OnStart()

{

// To learn more about cTrader Automate visit our Help Center:

// https://help.ctrader.com/ctrader-automate


 

// Print(Bars.Count());

DateTime time_to_test = Bars[Bars.Count()-5].OpenTime.AddDays(-15);

// Print(time_to_test);

// Get m1 Bars

 

if(BackTest && Bars.Last().OpenTime>DateTime.Parse(BackTestDate)){


 

Bars _OfTimeFrameBars = MarketData.GetBars(TimeFrame.Minute, SymbolName);

var LastOpenTimeLoaded = _OfTimeFrameBars.OpenTimes[0];

 

Print("Bars[0].OpenTime " + Bars[0].OpenTime+ " _OfTimeFrameBars.OpenTimes[0] "+ _OfTimeFrameBars.OpenTimes[0] + " time_to_test "+ time_to_test);

if (_OfTimeFrameBars.OpenTimes[0] > time_to_test){

Print("_OfTimeFrameBars is not using Bars history already loaded");


 

}


 

}

}


 

protected override void OnBarClosed()

{

DateTime time_to_test = Bars[Bars.Count()-5].OpenTime.AddDays(-15);

 

if(BackTest && Bars.Last().OpenTime>DateTime.Parse(BackTestDate)){


 

Bars _OfTimeFrameBars = MarketData.GetBars(TimeFrame.Minute, SymbolName);

var LastOpenTimeLoaded = _OfTimeFrameBars.OpenTimes[0];

 

 

Print("Bars[0].OpenTime " + Bars[0].OpenTime+ " _OfTimeFrameBars.OpenTimes[0] "+ _OfTimeFrameBars.OpenTimes[0] + " time_to_test "+ time_to_test);

if (_OfTimeFrameBars.OpenTimes[0] > time_to_test){

 

Print("_OfTimeFrameBars is not using Bars history already loaded");

 

}


 

 

}

}


 

protected override void OnStop()

{

// Handle cBot stop here

}

}

}

 

 

 

 

 

 

 

sebastien.t said: 

Thank s for your answer, that seems a very nice option!

 

PanagiotisCharalampous said: 

sebastien.t said: 

Good day,

thank you for your answer. 

Do you have a workaround? 

The idea of my code/bot is to check some data in the past for the H4 to know if I am bullish or bearish and the to deep dive in the 1 minute chart. 

Basically I have to go 60 bars on the timeframe and then go to the m1. Let s say I want to backtest from the 1st february, I check the H4 10 days before (60*4/24), that should be around mid of January and then I check some data on that date on the m1.

So most of the time I need to LoadMoreHistory on the m1.

Thank you

Seb

PanagiotisCharalampous said: 

Hi there,

Your problem is here

           while (_OfTimeFrameBars.OpenTimes[0] > time_to_test){               var numberOfLoadedBars = _OfTimeFrameBars.LoadMoreHistory();

LoadMoreHistory does not work in backtesting therefore your code enters an infinite loop.

Best regards,

Panagiotis

 

Hi Seb,

The workaround I use is to start the backtesting at earlier dates so that all the necessary information is loaded, while skipping all trading operations until a custom defined date. So I have a set of parameters like this

which replace the backtesting start date and I move my backtesting start date as far in the past as I want.

Best regards,

Panagiotis

 

 

Hi Seb,

  1. I did not understand what the problem is here, sorry
  2. You should retrieve the data on start, before the if condition. That's the whole point of the workaround
        protected override void OnStart()

        {
            // To learn more about cTrader Automate visit our Help Center:

            // https://help.ctrader.com/ctrader-automate

            // Print(Bars.Count());

            DateTime time_to_test = Bars[Bars.Count() - 5].OpenTime.AddDays(-15);
            
            Bars _OfTimeFrameBars = MarketData.GetBars(TimeFrame.Minute, SymbolName);

            Print("Bars[0].OpenTime " + Bars[0].OpenTime + " _OfTimeFrameBars.OpenTimes[0] " + _OfTimeFrameBars.OpenTimes[0] + " time_to_test " + time_to_test);

            // Print(time_to_test);

            // Get m1 Bars

            if (BackTest && Bars.Last().OpenTime > DateTime.Parse(BackTestDate))
            {
                

                var LastOpenTimeLoaded = _OfTimeFrameBars.OpenTimes[0];

                if (_OfTimeFrameBars.OpenTimes[0] > time_to_test)
                {
                    Print("_OfTimeFrameBars is not using Bars history already loaded");
                }
            }
        }

@PanagiotisCharalampous

sebastien.t
24 Apr 2024, 08:28 ( Updated at: 25 Apr 2024, 05:47 )

RE: RE: RE: RE: RE: RE: Backtesting on Multi Timeframe

Thank you @Panagiotis for your help. now my backtesting is working!

 

PanagiotisCharalampous said: 

sebastien.t said: 

Hi Panagiotis,

I tried to use your workaround but it doesn't really work for 2 reasons :

1/ if I want to backtest the bot that I use on Live market I can't change a lot of code and so I have to keep using the same functions. It seems that even if the history date are loaded (I can see see it if I check the date with Bars[0]), I can't recall that data with the MarketData.GetBars

2/ To run the Backtest I have to choose 1 timeframe (let s say H1) but in my bot I need check the historical data of the H4 and the Daily. And so even if I start the backtest to beofre my “real” backtesting date to load the data, it loads only the data for H1 and not for H4/Daily.

Here is my code

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using cAlgo.API;

using cAlgo.API.Collections;

using cAlgo.API.Indicators;

using cAlgo.API.Internals;


 

namespace cAlgo.Robots

{

[Robot(AccessRights = AccessRights.None)]

public class EasyHistoLoad : Robot

{

 

[Parameter("Backtest On/Off", Group = "BackTest", DefaultValue = false)]

public bool BackTest { get; set; }


 

[Parameter("Backtest Date", Group = "BackTest", DefaultValue = "2024/03/01 01:00:00")]

public string BackTestDate { get; set; }


 

protected override void OnStart()

{

// To learn more about cTrader Automate visit our Help Center:

// https://help.ctrader.com/ctrader-automate


 

// Print(Bars.Count());

DateTime time_to_test = Bars[Bars.Count()-5].OpenTime.AddDays(-15);

// Print(time_to_test);

// Get m1 Bars

 

if(BackTest && Bars.Last().OpenTime>DateTime.Parse(BackTestDate)){


 

Bars _OfTimeFrameBars = MarketData.GetBars(TimeFrame.Minute, SymbolName);

var LastOpenTimeLoaded = _OfTimeFrameBars.OpenTimes[0];

 

Print("Bars[0].OpenTime " + Bars[0].OpenTime+ " _OfTimeFrameBars.OpenTimes[0] "+ _OfTimeFrameBars.OpenTimes[0] + " time_to_test "+ time_to_test);

if (_OfTimeFrameBars.OpenTimes[0] > time_to_test){

Print("_OfTimeFrameBars is not using Bars history already loaded");


 

}


 

}

}


 

protected override void OnBarClosed()

{

DateTime time_to_test = Bars[Bars.Count()-5].OpenTime.AddDays(-15);

 

if(BackTest && Bars.Last().OpenTime>DateTime.Parse(BackTestDate)){


 

Bars _OfTimeFrameBars = MarketData.GetBars(TimeFrame.Minute, SymbolName);

var LastOpenTimeLoaded = _OfTimeFrameBars.OpenTimes[0];

 

 

Print("Bars[0].OpenTime " + Bars[0].OpenTime+ " _OfTimeFrameBars.OpenTimes[0] "+ _OfTimeFrameBars.OpenTimes[0] + " time_to_test "+ time_to_test);

if (_OfTimeFrameBars.OpenTimes[0] > time_to_test){

 

Print("_OfTimeFrameBars is not using Bars history already loaded");

 

}


 

 

}

}


 

protected override void OnStop()

{

// Handle cBot stop here

}

}

}

 

 

 

 

 

 

 

sebastien.t said: 

Thank s for your answer, that seems a very nice option!

 

PanagiotisCharalampous said: 

sebastien.t said: 

Good day,

thank you for your answer. 

Do you have a workaround? 

The idea of my code/bot is to check some data in the past for the H4 to know if I am bullish or bearish and the to deep dive in the 1 minute chart. 

Basically I have to go 60 bars on the timeframe and then go to the m1. Let s say I want to backtest from the 1st february, I check the H4 10 days before (60*4/24), that should be around mid of January and then I check some data on that date on the m1.

So most of the time I need to LoadMoreHistory on the m1.

Thank you

Seb

PanagiotisCharalampous said: 

Hi there,

Your problem is here

           while (_OfTimeFrameBars.OpenTimes[0] > time_to_test){               var numberOfLoadedBars = _OfTimeFrameBars.LoadMoreHistory();

LoadMoreHistory does not work in backtesting therefore your code enters an infinite loop.

Best regards,

Panagiotis

 

Hi Seb,

The workaround I use is to start the backtesting at earlier dates so that all the necessary information is loaded, while skipping all trading operations until a custom defined date. So I have a set of parameters like this

which replace the backtesting start date and I move my backtesting start date as far in the past as I want.

Best regards,

Panagiotis

 

 

Hi Seb,

  1. I did not understand what the problem is here, sorry
  2. You should retrieve the data on start, before the if condition. That's the whole point of the workaround
        protected override void OnStart()        {            // To learn more about cTrader Automate visit our Help Center:            // https://help.ctrader.com/ctrader-automate            // Print(Bars.Count());            DateTime time_to_test = Bars[Bars.Count() - 5].OpenTime.AddDays(-15);                        Bars _OfTimeFrameBars = MarketData.GetBars(TimeFrame.Minute, SymbolName);            Print("Bars[0].OpenTime " + Bars[0].OpenTime + " _OfTimeFrameBars.OpenTimes[0] " + _OfTimeFrameBars.OpenTimes[0] + " time_to_test " + time_to_test);            // Print(time_to_test);            // Get m1 Bars            if (BackTest && Bars.Last().OpenTime > DateTime.Parse(BackTestDate))            {                                var LastOpenTimeLoaded = _OfTimeFrameBars.OpenTimes[0];                if (_OfTimeFrameBars.OpenTimes[0] > time_to_test)                {                    Print("_OfTimeFrameBars is not using Bars history already loaded");                }            }        }

 


@sebastien.t