Backtesting Multi-Symbol Ticks - cBot loads wrong time-frame

Created at 30 Jan 2021, 13:38
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!
ctid2514471's avatar

ctid2514471

Joined 23.01.2021

Backtesting Multi-Symbol Ticks - cBot loads wrong time-frame
30 Jan 2021, 13:38


 I'm working on a ticks-based multi-symbol cBot, on cTrader 3.8.

I think I have found a bug in the backtesting behaviour with multiple Symbols - Any Symbols used that are not the Main/Chart Symbol, seem to only get Ticks data for 'today', rather than the DateTime the Backtest is running in.

The Code of the indicator (with a stub Calculate) are supplied below. The Calculate() stub just shows a basic movement plot (One tick versus the last).

I have a LOG() method to print logs to the chart - My Print() statements in an Indicator don't seem to come out anywhere when used in a cBot??? (Is that normal?) - Anyway, this is not the main issue.

1) First, to prove the indicator works:

a) Add the indicator to any Symbol chart view, on any timeframe

b) You should see red and blue plots showing the movements on GBPUSD and EURUSD

Something Like this:

 

2) Now, to show it going wrong in Backtesting:

a) Add the Indicator to any cBot (e.g. Martingale), GBPUSD, t1

b) Turn on VisualMode, set Speed to 1x

c) Set the Backtesting data to 'Tick data from Server'

d) Pick a 1-day range at least a week or so in the past

Run the backtesting.

What you will probably see is something like this:

Notice that we are only getting the Indicator plot for GBPUSD.

If you look at the text Logging I've put on the Chart - You can see why:

The 'Main' Symbol for the chart (GBPUSD) has loaded data for the correct target timeframe: ~ 13/Jan/2020

BUT the other 'non-primary' symbol only has data for part of the last trading day - 29/Jan/2020. So it's not going to be able to get any results for 13/Jan/2020.

If you run the backtesting on an unrelated symbol, neither plot shows up.

I suppose I could use LoadMoreHistory() to get more data back from 29/Jan to 13/Jan, but surely I am not supposed to do that... It's a lot of data, and what if I wanted to test back 6 months!

 

So, is this a bug, or am I doing something wrong?

 

 

using System;
using System.Text;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        [Output("GBPUSD", LineColor = "Red")]
        public IndicatorDataSeries out1 { get; set; }
        [Output("EURUSD", LineColor = "Blue")]
        public IndicatorDataSeries out2 { get; set; }

        private Symbol[] USDSyms;
        private Bars[] SymbolBars;

        protected override void Initialize()
        {
            USDSyms = Symbols.GetSymbols("GBPUSD", "EURUSD");
            SymbolBars = new Bars[USDSyms.Length];
            SymbolBars[0] = MarketData.GetBars(TimeFrame, USDSyms[0].Name);
            SymbolBars[1] = MarketData.GetBars(TimeFrame, USDSyms[1].Name);
        }

        public override void Calculate(int index)
        {
            Bars bars1 = SymbolBars[0], bars2 = SymbolBars[1];

            // Debug to show loaded 'Bars' time ranges:
            if (index % 10 == 0)
            {
                LOG("Bars    time[0]: " + Bars[0].OpenTime.ToString() + ", time[n]: " + Bars[Bars.Count - 1].OpenTime.ToString());
                LOG("bars[1] time[0]: " + bars1[0].OpenTime.ToString() + ", time[n]: " + bars1[bars1.Count - 1].OpenTime.ToString());
                LOG("bars[1] time[0]: " + bars2[0].OpenTime.ToString() + ", time[n]: " + bars2[bars2.Count - 1].OpenTime.ToString());
            }

            int i;
            i = bars1.OpenTimes.GetIndexByTime(Bars[index].OpenTime);
            if (i > 0)
                out1[index] = bars1[i].Close - bars1[i - 1].Close;

            i = bars2.OpenTimes.GetIndexByTime(Bars[index].OpenTime);
            if (i > 0)
                out2[index] = bars2[i].Close - bars2[i - 1].Close;
        }



        // Facility to log 30 lines of scrolling text to the top-left corner of the chart:
        private string[] LOGs = new string[10];
        private void LOG(string message)
        {
            var output = new StringBuilder();
            for (int i = 1; i < LOGs.Length; ++i)
                output.AppendLine(LOGs[i - 1] = LOGs[i]);
            output.AppendLine(LOGs[LOGs.Length - 1] = message);
            Chart.DrawStaticText("LOGS", output.ToString(), VerticalAlignment.Top, HorizontalAlignment.Left, Color.Wheat);
        }


    }
}

 

 

 


@ctid2514471
Replies

ctid2514471
30 Jan 2021, 14:32

By the way - At first I thought this only affected a cBot running with a Ticks Timeframe, but I think it also may happen with other timeframes (still affecting the loaded DateTime periods for 'non-primary' symbols referenced in the cBot)

cTrader's caching of data can make behaviour different here from one run to the next.

Testers: Maybe re-start cTrader if in doubt, to clear its cache!


@ctid2514471