Results from indicator are different on the chart than when used in a robot
Results from indicator are different on the chart than when used in a robot
11 Mar 2013, 04:58
I have an indicator I use in a robot but the results is posts to the chart are different from the results is provides to my robot. This is very eratic. I would really aprieciate some help with this issue as it renders the platform useless.
Here is the code for the indicator:
//#reference: C:\Users\lcespedes\Documents\cAlgo\Sources\Indicators\myMASlope.algo using System; using cAlgo.API; using cAlgo.API.Indicators; namespace cAlgo.Indicators { [Indicator(IsOverlay = false, ScalePrecision=2)] public class myTrend : Indicator { [Parameter(DefaultValue = 240)] public int paramPeriods {get; set;} [Parameter(DefaultValue = .8)] public double paramSlopeLimit {get; set;} [Parameter(DefaultValue = .05)] public double paramSlopeTolerance {get; set;} [Output("TrendUpPlot", PlotType = PlotType.Points, Thickness = 5, Color = Colors.Green)] public IndicatorDataSeries TrendUpIndicator { get; set; } [Output("TrendDnPlot", PlotType = PlotType.Points, Thickness = 5, Color = Colors.Red)] public IndicatorDataSeries TrendDnIndicator { get; set; } [Output("RangingPlot", PlotType = PlotType.Points, Thickness = 5, Color = Colors.White)] public IndicatorDataSeries RangingIndicator { get; set; } private myMASlope maslope; private bool isTrendingUp; private bool isTrendingDn; private bool isRanging; protected override void Initialize(){maslope = Indicators.GetIndicator<myMASlope>(paramPeriods,paramSlopeLimit);} public override void Calculate(int index) { //** skip printing bar until moving average data is calculated int t0=index; if(double.IsNaN(maslope.Result[index]))return; decimal MASlope=(decimal) maslope.Result[index]; //if the MA is ranging it must reach a certain slope before considered ranging. decimal MAUpTrendLimit=(decimal)paramSlopeLimit; decimal MADnTrendLimit=(decimal)paramSlopeLimit; //Once it is trending in a direction it must reach a certain slope tolerance //past zero before it is considered an end to the trend and begins ranging. if (isTrendingUp)MAUpTrendLimit=(decimal)-paramSlopeTolerance; if (isTrendingDn)MADnTrendLimit=(decimal)-paramSlopeTolerance; isTrendingUp =(MASlope>MAUpTrendLimit); isTrendingDn =(MASlope<-MADnTrendLimit); isRanging = !isTrendingUp && !isTrendingDn; if (isTrendingUp)TrendUpIndicator[index]=1; if (isTrendingDn)TrendDnIndicator[index]=-1; if (isRanging) RangingIndicator[index]=0; Print("{0:MM/dd/yyyy HH:mm} Trend:{1} | {2} | {3} | {4}", MarketSeries.OpenTime[t0],paramPeriods,TrendUpIndicator[t0],RangingIndicator[t0],TrendDnIndicator[t0]); } } }
Hereis the code for the Robot:
//#reference: C:\Users\lcespedes\Documents\cAlgo\Sources\Indicators\myTrend.algo using System; using System.Collections.Generic; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.Indicators; using cAlgo.API.Requests; namespace cAlgo.Robots { [Robot] public class TestTrendBot : Robot { private myTrend trendShort; protected override void OnStart(){trendShort = Indicators.GetIndicator<myTrend>(60,1.9,.6);} protected override void OnBar() { if (Trade.IsExecuting) return; int t0 = MarketSeries.Close.Count-1;//** t0 results are not final because the bar has not completed Print("{0:MM/dd/yyyy HH:mm} Shrt:{1} | {2} | {3}", MarketSeries.OpenTime[t0],trendShort.TrendUpIndicator[t0],trendShort.RangingIndicator[t0],trendShort.TrendDnIndicator[t0]); } } }
Here is the code for the indicator used by the indicator:
using System; using cAlgo.API; using cAlgo.API.Indicators; namespace cAlgo.Indicators { [Indicator(IsOverlay = false, ScalePrecision = 2, AutoRescale=true)] public class myMASlope : Indicator { [Parameter(DefaultValue = 60)] public int Periods { get; set; } [Parameter(DefaultValue = 2.4)] public double paramLimit { get; set; } [Output("MA Slope", PlotType = PlotType.Histogram, Thickness = 2, Color = Colors.Purple)] public IndicatorDataSeries Result { get; set; } [Output("UpperLimit", PlotType = PlotType.Line, LineStyle=LineStyle.DotsRare,Thickness = 1, Color = Colors.Red)] public IndicatorDataSeries UpperLimit { get; set; } [Output("LowerLimit", PlotType = PlotType.Line, LineStyle=LineStyle.DotsRare, Thickness = 1, Color = Colors.Red)] public IndicatorDataSeries LowerLimit { get; set; } [Output("Peak", PlotType = PlotType.Line, LineStyle=LineStyle.DotsRare,Thickness = 1, Color = Colors.Red)] public IndicatorDataSeries Peak { get; set; } [Output("Valley", PlotType = PlotType.Line, LineStyle=LineStyle.DotsRare, Thickness = 1, Color = Colors.Red)] public IndicatorDataSeries Valley { get; set; } [Output("Center", LineStyle=LineStyle.DotsRare, Color = Colors.White)] public IndicatorDataSeries CenterLine { get; set; } private SimpleMovingAverage MA; protected override void Initialize(){MA = Indicators.SimpleMovingAverage(MarketSeries.Open,Periods);} public override void Calculate(int index) { int t0 = index; int t1 = t0 - 1; if(t1<0)return;//** prevent crash caused by posibly using a negetive index value if(double.IsNaN(MA.Result[t1]))return; //** skip printing bar until moving average data is calculated //Print("{0,20} | {1,20} | {2,20}",MarketSeries.OpenTime[t0],MA.Result[t0],Math.Round((MA.Result[t0]-MA.Result[t1])/Symbol.PointSize,2)); //Peak[index]=5;// equal to half a pip //Valley[index]=-5; UpperLimit[index]=paramLimit; LowerLimit[index]=-paramLimit; CenterLine[index]=0; Result[index]= Math.Round((MA.Result[t0]-MA.Result[t1])/Symbol.PointSize,2); } } }
Replies
lec0456
11 Mar 2013, 18:54
( Updated at: 21 Dec 2023, 09:20 )
RE:
Hello,
The print statements from the indicator and the robot match. If this is not the issue please provide us with some more information (i.e. a screenshot indicating the difference or some more explanation).
Also please ensure you are using the same parameters for the indicator and the robot as the default parameters for the myTrend are not the same used in the Robot:
trendShort = Indicators.GetIndicator<myTrend>(60, 1.9, .6);Whereas, the myTrend default parameters are: 240, 0.8,0.05
ok yes, I used the correct parameters for the indicator as in the robot (60,1.9,.6) If you look at 3/7/13 at 8am the indicator shows 0 or ranging but the print statement in the robot shows -1 or down trend.
Realize I simplified the robot so you could troubleshoot the issue but it does more stuff than just print.
Right, so if you backtest the robot you will see print statements from the robot and the indicator and they match. But if you apply the indicator to the chart you get different results.
Capture1 shows the indicator as applied to the chart, make note of the log at time 3/7/13 8am trend is indicating 0
Now look at the Robot, Capture 1a shows the trend as -1
See what I mean??
@lec0456
lec0456
12 Mar 2013, 00:34
( Updated at: 21 Dec 2023, 09:20 )
OK, I did some more troubleshooting and what is happenening is that your indicator simplemoving average is giving different values to the robots than outputing to the chart.
So, first you can forget the my trend indicator I sent you it is not the issue.
I placed a print statement in the MASlope indicator, like so:
Print("{0,20:MM/dd/yyyy HH:mm} | {1,20} | {2,20} | {3,20}",MarketSeries.OpenTime[t0],MA.Result[t0],MA.Result[t1],Math.Round((MA.Result[t0]-MA.Result[t1])/Symbol.PointSize,2));
In the robot I took out the print statement and placed a dummy variable to read the indicator otherwise it will not print in the log, like so:
double test=trendShort.TrendDnIndicator[t0];
The log of the indicator looks like this
:
The log of the robot looks like this:
The values for the moving averages are different! So the slopes are different and thats why my trend indicator was acting erratic.
@lec0456
cAlgo_Fanatic
12 Mar 2013, 11:53
( Updated at: 21 Dec 2023, 09:20 )
Please remove all the code except for the print statements which should be identical in order to verify that the indicator produces the same results.
These are the logs for Period 60 m1 timeframe:
The code:
Indicator:
[Parameter(DefaultValue = 60)] public int Periods { get; set; } private SimpleMovingAverage MA; int t0 = -1; protected override void Initialize() { MA = Indicators.SimpleMovingAverage(MarketSeries.Open, Periods);
} public override void Calculate(int index) { if(!IsRealTime) return; if(t0!= index) // Force to print only once per bar { t0 = index; int t1 = t0 - 1; Print("{0,20} | {1,20} | {2,20} | {3,20} ",MarketSeries.OpenTime[t0],MA.Result[t0], MA.Result[t1],Math.Round((MA.Result[t0]-MA.Result[t1])/Symbol.PointSize,2)); } }
The Robot:
SimpleMovingAverage MA; protected override void OnStart() { MA = Indicators.SimpleMovingAverage(MarketSeries.Open, 60); } protected override void OnBar() { int t0 = MarketSeries.Close.Count - 1;//** t0 results are not final because the bar has not completed int t1 = t0-1; Print("{0,20} | {1,20} | {2,20} | {3,20} ",MarketSeries.OpenTime[t0],MA.Result[t0], MA.Result[t1],Math.Round((MA.Result[t0]-MA.Result[t1])/Symbol.PointSize,2)); }
@cAlgo_Fanatic
lec0456
12 Mar 2013, 19:15
But you are not using the indicator as a reference in the robot! you are recalculating within the robot. that defeats the whole purpose of having indicators! also the values do not differ throughout the whole series some times they are the same and sometimes they are not. Thats what makes it erratic. Also are you only testing this in realtime because I have been backtesting? I see the IsRealTime statement in your indicator, thats why I'm asking?
But I am going to strip down both the indicator and the robot and send you the code with the results...give me a couple hours...
@lec0456
lec0456
13 Mar 2013, 01:25
( Updated at: 21 Dec 2023, 09:20 )
The erratic behavior is repeating itself
Ok so I created simplifed indicators and robots and the sma's are still giving differnet results...
Here is the code for the indicator I used:
using System; using cAlgo.API; using cAlgo.API.Indicators; namespace cAlgo.Indicators { [Indicator(IsOverlay = false)] public class testMASlopeIndicator : Indicator { [Output("MA Slope", PlotType = PlotType.Histogram, Thickness = 2, Color = Colors.Purple)] public IndicatorDataSeries Result { get; set; } private SimpleMovingAverage SMA; int t0=-1; protected override void Initialize(){SMA=Indicators.SimpleMovingAverage(MarketSeries.Open,60);} public override void Calculate(int index) { if(t0!=index) { t0 = index; int t1 = t0 - 1; if(t1<0)return;//** prevent crash caused by posibly using a negetive index value if(double.IsNaN(SMA.Result[t1]))return; //** skip printing bar until moving average data is calculated Print("{0,20:MM/dd/yyyy HH:mm} | MA {1,30} | {2,30} | {3,30}",MarketSeries.OpenTime[t0],SMA.Result[t0],SMA.Result[t1],Math.Round((SMA.Result[t0]-SMA.Result[t1])/Symbol.PointSize,2)); Result[index]= Math.Round((SMA.Result[t0]-SMA.Result[t1])/Symbol.PointSize,2); } } } }
Here is the code for the robot i used:
//#reference: C:\Users\lcespedes\Documents\cAlgo\Sources\Indicators\testMASlopeIndicator.algo using System; using System.Collections.Generic; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.Indicators; using cAlgo.API.Requests; namespace cAlgo.Robots { [Robot] public class TestMASlopeBot : Robot { private testMASlopeIndicator slope; protected override void OnStart(){ slope = Indicators.GetIndicator<testMASlopeIndicator>();} protected override void OnBar() { if (Trade.IsExecuting) return; int t0=MarketSeries.Close.Count-1;//** t0 results are not final because the bar has not completed double test=slope.Result[t0]; } } }
I backtested for the last 7 days, used 60 periods for the SMA, Market Open data and 1 minute time frame. Here are the results for 7:32am and 8am for the robot and indicator...
Slope Robot @732am on 3/7/13
Slope Indicator @8am on 3/7/13
Slope Robot @8am on 3/7/13
Do you see how sometimes the values are the same and sometimes they differ? If you notice the numbers don't get back in sync until 7:46am. Do you see what I'm talking about now?
@lec0456
cAlgo_Fanatic
13 Mar 2013, 12:09
RE:
i like the way you get the indicator to only print once, could you explain how that works?? I never understood why it printed twice in the first place...
int t0 = -1 // initialize field to -1 //... // Force to print only once per bar within Calculate(int index) if(t0!= index) // if global field is not equal to index { t0 = index;
Print... // etc. }
Since the Calculate() event is called on each tick that means that it will execute the code multiple times per bar. In order to Print only once per bar just add the print statement within an if statement to check if the index is not the same as with the previous call. The global field t0 will be assigned to value of the parameter index if they are not the same and the print will execute. The next call will not execute the print statement if t0 equals index since the condition will fail.
@cAlgo_Fanatic
cAlgo_Fanatic
13 Mar 2013, 12:13
RE: RE:
lec0456 said:BTW, this is using ICmarkets data and that first log is the Slope Indicator @7:34am on 3/7/13
I mean 7:32am
So far we cannot reproduce the issue. We will continue testing and if something is identified we will let you know.
Regards,
@cAlgo_Fanatic
lec0456
13 Mar 2013, 18:32
( Updated at: 21 Dec 2023, 09:20 )
Actually, I checked the results for your exact indicator and robot and at 7:32am on 3/713 it causes the same issue. So, you don't even have to have a reference to the custom indicator.
So, the SimpleMovingAverage is not giving the same results as robots when backtesting. Could you please send me screen shots of your results for 3/7/13at 7:32 am for each? and could you please use ICmarkets data.
@lec0456
lec0456
13 Mar 2013, 19:26
I will tell you what I think the issue could be...Using a double to hold all indicator values will introduce randomness in calculations because the use of decimals and division are not precise with doubles. With C# You need to use decimal data type. Thats just a hunch...
@lec0456
lec0456
13 Mar 2013, 20:25
I ran the same tests against FXPro data and the indicator and the Robot SMA's match. I notice the versions of cAlgo are different. the version of FXpro cAlgo is 1.0.26115 and ICMarkets cAlgo is 1.0.26114. Don't know if that is the difference but you can clearly see that IC Markets is giving different values for SMA between the indicators and Robots. please investigate!
@lec0456
cAlgo_Fanatic
14 Mar 2013, 14:18
We are investigating the issue and will let you know.
@cAlgo_Fanatic
cAlgo_Development
14 Mar 2013, 15:33
Bug is reproduced and will be fixed
The reason of this incorrect behavior is a bug in our tick generation algorithm used in backtesting. We generate ticks using Minute trend bars. And in rare cases when one bar contains only two or three ticks, algorithm generates ticks so that last tick is goes to next bar. For that bar you can see that close price is incorrect and for next bar, open price is incorrect.
Fix for this bug will be released approximately in two weeks.
Thank you very much for this report.
@cAlgo_Development
cAlgo_Development
29 Apr 2013, 17:54
Yes, the fix must be already released. Please check that results are the same now.
@cAlgo_Development
cAlgo_Fanatic
11 Mar 2013, 11:07
Hello,
The print statements from the indicator and the robot match. If this is not the issue please provide us with some more information (i.e. a screenshot indicating the difference or some more explanation).
Also please ensure you are using the same parameters for the indicator and the robot as the default parameters for the myTrend are not the same used in the Robot:
Whereas, the myTrend default parameters are: 240, 0.8,0.05
@cAlgo_Fanatic