Backtesting Multi-Symbol Ticks - cBot loads wrong time-frame
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
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