indicator.Count is 0 when referenced in cBot's first OnBar and changes to correct 201 if referenced again without doing anything else
indicator.Count is 0 when referenced in cBot's first OnBar and changes to correct 201 if referenced again without doing anything else
02 Dec 2024, 12:30
Is this a known problem, in backtest on 5.0.46?
With this in OnBar, 2 consecutive statements just writing lines with .Count values to a log file:
mjsWriteLine("A Bars.Count=" + Bars.Count + " _mjsEMA.EMA.Count=" + _mjsEMA.EMA.Count + " _mjsEMA.EMA2.Count=" + _mjsEMA.EMA2.Count
+ " _mjsEMA.EMA3.Count=" + _mjsEMA.EMA3.Count);
mjsWriteLine("B Bars.Count=" + Bars.Count + " _mjsEMA.EMA.Count=" + _mjsEMA.EMA.Count + " _mjsEMA.EMA2.Count=" + _mjsEMA.EMA2.Count
+ " _mjsEMA.EMA3.Count=" + _mjsEMA.EMA3.Count);
…I get this output:
A Bars.Count=201 _mjsEMA.EMA.Count=0 _mjsEMA.EMA2.Count=0 _mjsEMA.EMA3.Count=201
B Bars.Count=201 _mjsEMA.EMA.Count=201 _mjsEMA.EMA2.Count=201 _mjsEMA.EMA3.Count=201
Other logging during backtest shows first OnBar (for index=0) starting and showing indicator's Count as 0 (many times if have many Print stmts), then 201 Calculate calls in the indicator, then the rest of the first OnBar logic (with the correct .Count number). The history Calculates for the indicator seem to be being done too late, surely the first OnBar in a cBot should see all its indicator's Counts already at 201, same as its own Bars.Count ?
Regards Martin
Replies
firemyst
03 Dec 2024, 00:31
RE: indicator.Count is 0 when referenced in cBot's first OnBar and changes to correct 201 if referenced again without doing anything else
martins said:
Further tests with Print(DateTime.Now.ToString("HH:mm:ss.ffff") + …) & some System.Threading.Thread.Sleep calls in both an indicator & a cbot shows that making a reference, in the first OnBar call, to the .Count of a NON-DISPLAY IndicatorDataSeries (one WITHOUT a "[Output …] attribute) DOES NOT trigger the indicator to start making Calculate calls - the Calculate calls for the 200 history Bars seem only to be triggered by the first reference to the .Count of any DISPLAY IndicatorDataSeries (one WITH [Output…]) but even then, the initial zero count is returned to the cBot and incorporated into a Print buffer before the Calculates happen.
Then the OnBar pauses while the 200 or so history Calculates happen for the Bars prior to the backtest start time, then the buffer gets put into log.txt and the Log screen, and subsequent references in the first OnBar to .Count of any display or non-display IndicatorDataSeries give correct values (because all the history Calculates have been run).
It seem in we have to make 2 references in a cBot's first OnBar (when index=0) to an indicator's IndicatorDataSeries having the [Output…] clause (making it, if the indicator were run independently, a display line not just a calculated series) in order to get a proper value - is this correct and documented or is it a bug?
I know this means nothing, but I applaud your research in trying to figure it all out and am looking forward to updates.
@firemyst
martins
03 Dec 2024, 00:46
( Updated at: 03 Dec 2024, 01:11 )
RE: RE: indicator.Count is 0 when referenced in cBot's first OnBar and changes to correct 201 if referenced again without doing anything else
firemyst said:
martins said:
Further tests with Print(DateTime.Now.ToString("HH:mm:ss.ffff") + …) & some System.Threading.Thread.Sleep calls in both an indicator & a cbot shows that making a reference, in the first OnBar call, to the .Count of a NON-DISPLAY IndicatorDataSeries (one WITHOUT a "[Output …] attribute) DOES NOT trigger the indicator to start making Calculate calls - the Calculate calls for the 200 history Bars seem only to be triggered by the first reference to the .Count of any DISPLAY IndicatorDataSeries (one WITH [Output…]) but even then, the initial zero count is returned to the cBot and incorporated into a Print buffer before the Calculates happen.
Then the OnBar pauses while the 200 or so history Calculates happen for the Bars prior to the backtest start time, then the buffer gets put into log.txt and the Log screen, and subsequent references in the first OnBar to .Count of any display or non-display IndicatorDataSeries give correct values (because all the history Calculates have been run).
It seem in we have to make 2 references in a cBot's first OnBar (when index=0) to an indicator's IndicatorDataSeries having the [Output…] clause (making it, if the indicator were run independently, a display line not just a calculated series) in order to get a proper value - is this correct and documented or is it a bug?
I know this means nothing, but I applaud your research in trying to figure it all out and am looking forward to updates.
It all started with some NaN values causing initial trades which didn't look right!
It might be deliberate, so that if you ..GetIndicator<…> loads of them but don't actually use them all you don't waste cpu & memory initialising & then maintaining the redundant ones every new Bar or Tick. If so maybe there's doc about it, but where.
@martins
PanagiotisCharalampous
03 Dec 2024, 07:46
Hi there,
Can you please share the complete code so that we can investigate?
Best regards,
Panagiotis
@PanagiotisCharalampous
martins
03 Dec 2024, 22:36
( Updated at: 03 Dec 2024, 23:29 )
RE: indicator.Count is 0 when referenced in cBot's first OnBar and changes to correct 201 if referenced again without doing anything else
It's not quite as bad as initially thought, but only accessing non-display indicators (without [Output…] suffixes) in OnBar always gives Count=0 & NaN values.
These demos might be a bit OTT but show the problem (they only really needed Output & NonOutput). Using the default parameters, it will log NonOutput.Count=0 (and Nan values) in the first 10 OnBar calls, then the 200+ history Calculates will run (because OnBar starts accessing Output.Count too), and it'll be normal from there on (Output & NonOutput having proper values).
Also see that the ‘popup text’ doesn't always change as you move the mouse across different lines - it should say the name of the highlighted line but tends to stay ‘stuck’ on the first one you crossed - this could be related to the other case re ‘popup text apprears for unticked lines’).
#define ONBAR // include an OnBar method (or comment out this line)
//#define ONBARCLOSED // include an OnBarClosed method (or comment out this line)
using System;
using cAlgo.API;
using cAlgo.API.Indicators;
//using cAlgo.API.Indicators;
//using cAlgo.API.Internals;
//using cAlgo.Indicators;
//using mjsDemoOutputAndNonOutput;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AddIndicators = true)]
public class mjsDemoZeroInIndicatorCount : Robot
{
[Parameter("robot Sleep (ms)", DefaultValue = 0)] public int robotSleep { get; set; } // makes no difference other than speed, eg 50 or 200 millisecs every Bar
[Parameter("indic Sleep (ms)", DefaultValue = 0)] public int indicSleep { get; set; } // makes no difference other than speed, eg 5 or 20, cBot just suspended while Calculates catch up
[Parameter("Trigger Calculates (call #)", DefaultValue = "10")] public int triggerCalculates { get; set; } // get Output.Count in OnBar call # (to trigger Calculates if not already run)
[Parameter("Stop at OnBar (call #)", DefaultValue = "-1")] public int parmStopOnBar { get; set; } // for example: don't bother running to backtest end-date
[Parameter("Count of [Output]", DefaultValue = "false")] public bool referOutput { get; set; } // true will cause Calculates immediately, ie normal indicator operation
[Parameter("Count of [NonOutput]", DefaultValue = "true")] public bool referNonOutput { get; set; } // if only non-display series are accessed, the indicator doesn't 'get going', just Initialize
[Parameter("Count of Standard", DefaultValue = "false")] public bool referStandard { get; set; } // true will cause Calculates immediately, ie normal indicator operation
[Parameter("Value of [Output]", DefaultValue = "false")] public bool valueOutput { get; set; } // true will cause Calculates immediately, ie normal indicator operation
[Parameter("Value of [NonOutput]", DefaultValue = "true")] public bool valueNonOutput { get; set; } // if only non-display series are accessed, the indicator doesn't 'get going', just Initialize
[Parameter("Value of Standard", DefaultValue = "false")] public bool valueStandard { get; set; } // true will cause Calculates immediately, ie normal indicator operation
private DonchianChannel _standardIndic;
private mjsDemoOutputAndNonOutput _demoIndic;
protected override void OnStart()
{
printMethod = " OnStart: ";
Logit("started");
Logit("Server.Time=" + Server.Time + " Bars.Count=" + Bars.Count + " Bars.Last(0).OpenTime=" + Bars.Last(0).OpenTime + " countOnBar=" + countOnBar);
try
{
_standardIndic = Indicators.DonchianChannel(50);
_demoIndic = Indicators.GetIndicator<mjsDemoOutputAndNonOutput>(1.005, indicSleep);
}
catch { Logit("an indicator failed to start"); Stop(); }
Logit("ending");
}
string printMethod;
void Logit(string msg)
{
Print(DateTime.Now.ToString("HH:mm:ss.ffff") + printMethod + msg);
}
int countOnBar = 0;
#if ONBAR // include an OnBar method
protected override void OnBar()
{
printMethod = " OnBar: ";
Logit("started");
doBarStuff();
Logit("ending");
}
#endif
#if ONBARCLOSED // include an OnBarClosed method
protected override void OnBarClosed()
{
printMethod = " OnBarClosed: ";
Logit("started");
doBarStuff();
Logit("ending");
}
#endif
void doBarStuff()
{
Logit("Server.Time=" + Server.Time + " Bars.Count=" + Bars.Count + " Bars.Last(0).OpenTime=" + Bars.Last(0).OpenTime + " countOnBar=" + countOnBar);
if (robotSleep > 0)
{
Logit("System.Threading.Thread.Sleep(" + robotSleep + ") starting");
System.Threading.Thread.Sleep(robotSleep);
Logit("System.Threading.Thread.Sleep(" + robotSleep + ") done");
}
if (triggerCalculates >= 0 && countOnBar == triggerCalculates)
{
Logit("turn on getting a 'display' Output.Count next in order to trigger history Calculates (due to countOnBar=" + countOnBar + " == parmStopOnBar=" + triggerCalculates);
referOutput = true;
}
// for (int i=0; i<100; i++) Print("Print some stuff x");
// if (Bars.Count <= 203)
{
if (referNonOutput)
{
Logit("get _demoIndic.NonOutput.Count next");
Print("_demoIndic.NonOutput.Count=" + _demoIndic.NonOutput.Count);
Print("_demoIndic.NonOutput2.Count=" + _demoIndic.NonOutput.Count);
Print("_demoIndic.NonOutput3.Count=" + _demoIndic.NonOutput.Count);
Print("_demoIndic.NonOutput4.Count=" + _demoIndic.NonOutput.Count);
Print("_demoIndic.NonOutput5.Count=" + _demoIndic.NonOutput.Count);
Print("_demoIndic.NonOutput6.Count=" + _demoIndic.NonOutput.Count);
Print("_demoIndic.NonOutput7.Count=" + _demoIndic.NonOutput.Count);
Print("_demoIndic.NonOutput8.Count=" + _demoIndic.NonOutput.Count);
Print("_demoIndic.NonOutput9.Count=" + _demoIndic.NonOutput.Count);
Print("_demoIndic.NonOutput10.Count=" + _demoIndic.NonOutput.Count);
Print("_demoIndic.NonOutput11.Count=" + _demoIndic.NonOutput.Count);
Print("_demoIndic.NonOutput12.Count=" + _demoIndic.NonOutput.Count);
Print("_demoIndic.NonOutput13.Count=" + _demoIndic.NonOutput.Count);
Print("_demoIndic.NonOutput14.Count=" + _demoIndic.NonOutput.Count);
Print("_demoIndic.NonOutput15.Count=" + _demoIndic.NonOutput.Count);
Print("_demoIndic.NonOutput16.Count=" + _demoIndic.NonOutput.Count);
Logit("_demoIndic.NonOutput.Count=" + _demoIndic.NonOutput.Count);
Logit("_demoIndic.NonOutput.Count=" + _demoIndic.NonOutput.Count);
Logit("_demoIndic.NonOutput.Count=" + _demoIndic.NonOutput.Count);
}
if (referOutput)
{
Logit("get _demoIndic.Output.Count next");
Print("_demoIndic.Output.Count=" + _demoIndic.Output.Count);
Print("_demoIndic.Output2.Count=" + _demoIndic.Output2.Count);
Print("_demoIndic.Output3.Count=" + _demoIndic.Output3.Count);
Print("_demoIndic.Output4.Count=" + _demoIndic.Output4.Count);
Print("_demoIndic.Output5.Count=" + _demoIndic.Output5.Count);
Print("_demoIndic.Output6.Count=" + _demoIndic.Output6.Count);
Print("_demoIndic.Output7.Count=" + _demoIndic.Output7.Count);
Print("_demoIndic.Output8.Count=" + _demoIndic.Output8.Count);
Print("_demoIndic.Output9.Count=" + _demoIndic.Output9.Count);
Print("_demoIndic.Output10.Count=" + _demoIndic.Output10.Count);
Print("_demoIndic.Output11.Count=" + _demoIndic.Output11.Count);
Print("_demoIndic.Output12.Count=" + _demoIndic.Output12.Count);
Print("_demoIndic.Output13.Count=" + _demoIndic.Output13.Count);
Print("_demoIndic.Output14.Count=" + _demoIndic.Output14.Count);
Print("_demoIndic.Output15.Count=" + _demoIndic.Output15.Count);
Print("_demoIndic.Output16.Count=" + _demoIndic.Output16.Count);
Print("_demoIndic.Output17.Count=" + _demoIndic.Output17.Count);
Print("_demoIndic.Output18.Count=" + _demoIndic.Output18.Count);
Print("_demoIndic.Output19.Count=" + _demoIndic.Output19.Count);
Print("_demoIndic.Output20.Count=" + _demoIndic.Output20.Count);
Print("_demoIndic.Output21.Count=" + _demoIndic.Output21.Count);
Print("_demoIndic.Output22.Count=" + _demoIndic.Output22.Count);
Print("_demoIndic.Output23.Count=" + _demoIndic.Output23.Count);
Print("_demoIndic.Output24.Count=" + _demoIndic.Output24.Count);
Logit("_demoIndic.Output.Count=" + _demoIndic.Output.Count);
Logit("_demoIndic.Output.Count=" + _demoIndic.Output.Count);
Logit("_demoIndic.Output.Count=" + _demoIndic.Output.Count);
}
if (referStandard)
{
Logit("get _standardIndic.Middle.Count next");
Logit("_standardIndic.Middle.Count=" + _standardIndic.Middle.Count);
Logit("_standardIndic.Middle.Count=" + _standardIndic.Middle.Count);
Logit("_standardIndic.Middle.Count=" + _standardIndic.Middle.Count);
}
int i = 0; // or Count-1
if (valueNonOutput) // will be all NaN if Count is 0 and Calculates haven't run yet
{
Logit("get _demoIndic.NonOutput[" + i + "] next");
Print("_demoIndic.NonOutput[" + i + "]=" + _demoIndic.NonOutput[i]);
Print("_demoIndic.NonOutput2[" + i + "]=" + _demoIndic.NonOutput2[i]);
Print("_demoIndic.NonOutput3[" + i + "]=" + _demoIndic.NonOutput3[i]);
Print("_demoIndic.NonOutput4[" + i + "]=" + _demoIndic.NonOutput4[i]);
Print("_demoIndic.NonOutput5[" + i + "]=" + _demoIndic.NonOutput5[i]);
Print("_demoIndic.NonOutput6[" + i + "]=" + _demoIndic.NonOutput6[i]);
Print("_demoIndic.NonOutput7[" + i + "]=" + _demoIndic.NonOutput7[i]);
Print("_demoIndic.NonOutput8[" + i + "]=" + _demoIndic.NonOutput8[i]);
Print("_demoIndic.NonOutput9[" + i + "]=" + _demoIndic.NonOutput9[i]);
Print("_demoIndic.NonOutput10[" + i + "]=" + _demoIndic.NonOutput10[i]);
Print("_demoIndic.NonOutput11[" + i + "]=" + _demoIndic.NonOutput11[i]);
Print("_demoIndic.NonOutput12[" + i + "]=" + _demoIndic.NonOutput12[i]);
Print("_demoIndic.NonOutput13[" + i + "]=" + _demoIndic.NonOutput13[i]);
Print("_demoIndic.NonOutput14[" + i + "]=" + _demoIndic.NonOutput14[i]);
Print("_demoIndic.NonOutput15[" + i + "]=" + _demoIndic.NonOutput15[i]);
Print("_demoIndic.NonOutput16[" + i + "]=" + _demoIndic.NonOutput16[i]);
Logit("_demoIndic.NonOutput[" + i + "]=" + _demoIndic.NonOutput[i]);
Logit("_demoIndic.NonOutput[" + i + "]=" + _demoIndic.NonOutput[i]);
Logit("_demoIndic.NonOutput[" + i + "]=" + _demoIndic.NonOutput[i]);
}
if (valueOutput)
{
Logit("get _demoIndic.Output[" + i + "] next");
Logit("_demoIndic.Output[" + i + "]=" + _demoIndic.Output[i]);
Logit("_demoIndic.Output[" + i + "]=" + _demoIndic.Output[i]);
Logit("_demoIndic.Output[" + i + "]=" + _demoIndic.Output[i]);
}
if (valueStandard)
{
Logit("get _standardIndic.Middle[" + i + "] next");
Logit("_standardIndic.Middle[" + i + "]=" + _standardIndic.Middle[i]);
Logit("_standardIndic.Middle[" + i + "]=" + _standardIndic.Middle[i]);
Logit("_standardIndic.Middle[" + i + "]=" + _standardIndic.Middle[i]);
}
}
if (parmStopOnBar >= 0 && countOnBar == parmStopOnBar)
{
Logit("Stop() due to countOnBar=" + countOnBar + " == parmStopOnBar=" + parmStopOnBar);
Stop();
}
countOnBar++;
}
}
}
=========================================================
using System;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
namespace cAlgo
{
[Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
public class mjsDemoOutputAndNonOutput : Indicator
{
[Parameter("Above/Below Factor", DefaultValue = "1.005")] public string Factor { get; set; }
[Parameter("Sleep (ms)", DefaultValue = 10)] public int parmSleep { get; set; }
[Output("Output")] public IndicatorDataSeries Output { get; set; }
[Output("Output2")] public IndicatorDataSeries Output2 { get; set; }
[Output("Output3")] public IndicatorDataSeries Output3 { get; set; }
[Output("Output4")] public IndicatorDataSeries Output4 { get; set; }
[Output("Output5")] public IndicatorDataSeries Output5 { get; set; }
[Output("Output6")] public IndicatorDataSeries Output6 { get; set; }
[Output("Output7")] public IndicatorDataSeries Output7 { get; set; }
[Output("Output8")] public IndicatorDataSeries Output8 { get; set; }
[Output("Output9")] public IndicatorDataSeries Output9 { get; set; }
[Output("Output10")] public IndicatorDataSeries Output10 { get; set; }
[Output("Output11")] public IndicatorDataSeries Output11 { get; set; }
[Output("Output12")] public IndicatorDataSeries Output12 { get; set; }
[Output("Output13")] public IndicatorDataSeries Output13 { get; set; }
[Output("Output14")] public IndicatorDataSeries Output14 { get; set; }
[Output("Output15")] public IndicatorDataSeries Output15 { get; set; }
[Output("Output16")] public IndicatorDataSeries Output16 { get; set; }
[Output("Output17")] public IndicatorDataSeries Output17 { get; set; }
[Output("Output18")] public IndicatorDataSeries Output18 { get; set; }
[Output("Output19")] public IndicatorDataSeries Output19 { get; set; }
[Output("Output20")] public IndicatorDataSeries Output20 { get; set; }
[Output("Output21")] public IndicatorDataSeries Output21 { get; set; }
[Output("Output22")] public IndicatorDataSeries Output22 { get; set; }
[Output("Output23")] public IndicatorDataSeries Output23 { get; set; }
[Output("Output24")] public IndicatorDataSeries Output24 { get; set; }
public IndicatorDataSeries NonOutput { get; set; }
public IndicatorDataSeries NonOutput2 { get; set; }
public IndicatorDataSeries NonOutput3 { get; set; }
public IndicatorDataSeries NonOutput4 { get; set; }
public IndicatorDataSeries NonOutput5 { get; set; }
public IndicatorDataSeries NonOutput6 { get; set; }
public IndicatorDataSeries NonOutput7 { get; set; }
public IndicatorDataSeries NonOutput8 { get; set; }
public IndicatorDataSeries NonOutput9 { get; set; }
public IndicatorDataSeries NonOutput10 { get; set; }
public IndicatorDataSeries NonOutput11 { get; set; }
public IndicatorDataSeries NonOutput12 { get; set; }
public IndicatorDataSeries NonOutput13 { get; set; }
public IndicatorDataSeries NonOutput14 { get; set; }
public IndicatorDataSeries NonOutput15 { get; set; }
public IndicatorDataSeries NonOutput16 { get; set; }
protected override void Initialize()
{
printMethod = " Initialise: ";
Logit("started - Factor=" + Factor + " Sleep=" + parmSleep);
Logit("Server.Time=" + Server.Time + " Bars.Count=" + Bars.Count + " Bars.Last(0).OpenTime=" + Bars.Last(0).OpenTime + " countCalculate=" + countCalculate);
NonOutput = CreateDataSeries();
NonOutput2 = CreateDataSeries();
NonOutput3 = CreateDataSeries();
NonOutput4 = CreateDataSeries();
NonOutput5 = CreateDataSeries();
NonOutput6 = CreateDataSeries();
NonOutput7 = CreateDataSeries();
NonOutput8 = CreateDataSeries();
NonOutput9 = CreateDataSeries();
NonOutput10 = CreateDataSeries();
NonOutput11 = CreateDataSeries();
NonOutput12 = CreateDataSeries();
NonOutput13 = CreateDataSeries();
NonOutput14 = CreateDataSeries();
NonOutput15 = CreateDataSeries();
NonOutput16 = CreateDataSeries();
if (parmSleep > 0)
{
Logit("System.Threading.Thread.Sleep(" + parmSleep + ") starting");
System.Threading.Thread.Sleep(parmSleep);
Logit("System.Threading.Thread.Sleep(" + parmSleep + ") done");
}
Logit("ending");
}
int countCalculate = 0;
public override void Calculate(int index)
{
printMethod = " Calculate: ";
Logit("started");
Logit("Server.Time=" + Server.Time + " index=" + index + " Bars[index].OpenTime=" + Bars[index].OpenTime + " countCalculate=" + countCalculate);
if (parmSleep > 0)
{
Logit("System.Threading.Thread.Sleep(" + parmSleep + ") starting");
System.Threading.Thread.Sleep(parmSleep);
Logit("System.Threading.Thread.Sleep(" + parmSleep + ") done");
}
Output[index] = Bars[index].Close * 1.001;
Output2[index] = Bars[index].Close * 1.002;
Output3[index] = Bars[index].Close * 1.003;
Output4[index] = Bars[index].Close * 1.004;
Output5[index] = Bars[index].Close * 1.005;
Output6[index] = Bars[index].Close * 1.006;
Output7[index] = Bars[index].Close * 1.007;
Output8[index] = Bars[index].Close * 1.008;
Output9[index] = Bars[index].Close * 1.009;
Output10[index] = Bars[index].Close * 1.010;
Output11[index] = Bars[index].Close * 1.011;
Output12[index] = Bars[index].Close * 1.012;
Output13[index] = Bars[index].Close * 1.013;
Output14[index] = Bars[index].Close * 1.014;
Output15[index] = Bars[index].Close * 1.015;
Output16[index] = Bars[index].Close * 1.016;
Output17[index] = Bars[index].Close * 1.017;
Output18[index] = Bars[index].Close * 1.018;
Output19[index] = Bars[index].Close * 1.019;
Output20[index] = Bars[index].Close * 1.020;
Output21[index] = Bars[index].Close * 1.021;
Output22[index] = Bars[index].Close * 1.022;
Output23[index] = Bars[index].Close * 1.023;
Output24[index] = Bars[index].Close * 1.024;
NonOutput[index] = Bars[index].Close / 1.001;
NonOutput2[index] = Bars[index].Close / 1.002;
NonOutput3[index] = Bars[index].Close / 1.003;
NonOutput4[index] = Bars[index].Close / 1.004;
NonOutput5[index] = Bars[index].Close / 1.005;
NonOutput6[index] = Bars[index].Close / 1.006;
NonOutput7[index] = Bars[index].Close / 1.007;
NonOutput8[index] = Bars[index].Close / 1.008;
NonOutput9[index] = Bars[index].Close / 1.009;
NonOutput10[index] = Bars[index].Close / 1.010;
NonOutput11[index] = Bars[index].Close / 1.011;
NonOutput12[index] = Bars[index].Close / 1.012;
NonOutput13[index] = Bars[index].Close / 1.013;
NonOutput14[index] = Bars[index].Close / 1.014;
NonOutput15[index] = Bars[index].Close / 1.015;
NonOutput16[index] = Bars[index].Close / 1.016;
Logit("Server.Time=" + Server.Time + " index=" + index + " Output.Count=" + Output.Count + " Output[" + index + "]=" + Output[index]
+ " NonOutput.Count=" + NonOutput.Count + " NonOutput[" + index + "]=" + NonOutput[index] + " countCalculate=" + countCalculate);
countCalculate++;
Logit("ending");
}
string printMethod;
void Logit(string msg)
{
Print(DateTime.Now.ToString("HH:mm:ss.ffff") + printMethod + msg);
}
}
}
Later thoughts: Are the Series without an [Output] suffix ignored, by the part of cTrader that initiates running Calculates because, without [Output], they are unknown to that part?
If so, could there be a new keyword added in [Output] to say ‘not to be displayed’ - possibly the equivalent of a (permanently) unticked [Output] IndicatorDataSeries ?
Thanks Martin
@martins
PanagiotisCharalampous
05 Dec 2024, 08:12
Hi martins,
Any chance you can provide a simpler code (the minimum required to reproduce the issue)? I have a hard time navigating through all of this code and understand the problem.
Best regards,
Panagiotis
@PanagiotisCharalampous
martins
03 Dec 2024, 00:26 ( Updated at: 03 Dec 2024, 00:34 )
Further tests with Print(DateTime.Now.ToString("HH:mm:ss.ffff") + …) & some System.Threading.Thread.Sleep calls in both an indicator & a cbot shows that making a reference, in the first OnBar call, to the .Count of a NON-DISPLAY IndicatorDataSeries (one WITHOUT a "[Output …] attribute) DOES NOT trigger the indicator to start making Calculate calls - the Calculate calls for the 200 history Bars seem only to be triggered by the first reference to the .Count of any DISPLAY IndicatorDataSeries (one WITH [Output…]) but even then, the initial zero count is returned to the cBot and incorporated into a Print buffer before the Calculates happen.
Then the OnBar pauses while the 200 or so history Calculates happen for the Bars prior to the backtest start time, then the buffer gets put into log.txt and the Log screen, and subsequent references in the first OnBar to .Count of any display or non-display IndicatorDataSeries give correct values (because all the history Calculates have been run).
It seem we have to initially make 2 references in a cBot's first OnBar call (i.e. when index=0) to an indicator's IndicatorDataSeries having the [Output…] clause in order to get a proper value - is this correct and documented or is it a bug?
@martins