The Code for the Sample SMA has a big error!

Created at 16 Dec 2012, 07:00
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!
lec0456's avatar

lec0456

Joined 14.11.2012

The Code for the Sample SMA has a big error!
16 Dec 2012, 07:00


So, I'm going out on a limb here but here goes...

First, the index value for the Calculate event is equal to MarketSeries.Count-1.  You can throw a quick print statement to verify:

Print("index="+index+ " MarketSeriesCount-1="+(MarketSeries.Close.Count-1));

But we know that the Market Series close at this value is not final because the bar has not completed!

Notwithstanding, the Calculate event in the sample SMA code uses the following loop:

 

for (int i = index - Periods + 1; i <= index; i++)

This loop includes adding the current index value, MarketSeries.Close.Count-1 to the average which is invalid data.

If you place a print statement at the end of the code, like so:

Print("{0,20}{1,20}{2,20}{3,20}{4,20}",opentime,index,Result[index],Result[index-1],"Indicator");

and backtest a robot you will get 2 values printed per index and some will be different!

To fix the problem you need to adjust the loop, like so:

for (int i = index - Periods; i < index; i++)

This adds the values for the previous closing values that are valid.  When you backtest all the values are consistent.

Correct me if I'm wrong or correct the code if its wrong!  I look forward to comments...


@lec0456
Replies

lec0456
16 Dec 2012, 07:12

Here is a robot to test the indicator
Remember you have to put the print statement in the indicator!

//#reference: C:\Users\<yourpath>\Documents\cAlgo\Sources\Indicators\Sample SMA.algo // ------------------------------------------------------------------------------- // ------------------------------------------------------------------------------- using System; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.Indicators; namespace cAlgo.Robots { [Robot] public class TestIndicatorBot : Robot { private SampleSMA sma; protected override void OnStart() { sma = Indicators.GetIndicator<SampleSMA>(MarketSeries.Close,10); } protected override void OnBar() { if (Trade.IsExecuting) return; //** Indicator calculations and Analysis int t0 = MarketSeries.Close.Count-1;//** t0 results are not final because the bar has not completed int t1 = t0 - 1; if(t1<0)return;//** prevent crash caused by posibly using a negetive index value DateTime opentime = MarketSeries.OpenTime[t0]; double MA1t1 = sma.Result[t0]; double MA1t2 = sma.Result[t1]; Print("{0,20}{1,20}{2,20}{3,20}{4,20}",opentime,t0,MA1t1,MA1t2,"OnBar"); } }//** End of class ********* }//** End of namespace *********

 


@lec0456

admin
18 Dec 2012, 12:56

Hello,

Actually to test if the code in the sample is correct or not, simply use the 'Sample SMA' on a chart with a period of 1. If last value is Current Close price then the code is correct.

Additionally, after testing the code below:

for (int i = index - Periods; i < index; i++)

with input parameter of 1, you can clearly see the the prices are off and last SMA with 1 period is not the current close.

Please let us know if you have any more question.


@admin

lec0456
19 Dec 2012, 08:13

RE:

Well, what you are saying then is that on the current bar then the SMA will be changing with the close.  When I put my cursor over the very last bar it is changing with the close.  however, this is the instability I am refering to.  On mySma the sma at T is the previous close if you use 1 period.

So,I am asking, At any time T, should the MA consist of the previous x closing prices or should it include the the current closing price which is still unknown during live execution?  

I would really apprieciate if you would explain this...


@lec0456

lec0456
02 Apr 2013, 17:57

Hi Support,

I am back to investigating this issue because of accuracy concerns.  To recap,  my concern is that if you use an SMA on a Market Closing price and include the index value, you will get unstable results.  because At the index value the close is not final.  We had some discussion above but i never got a final answer...  If I use a 1 period SMA the result for values less than index(ie. index-1) are equal to the close but the value for index is shifting.  Which means that if a robot uses the current SMA value it will be off when on bar event is called.


@lec0456

cAlgo_Fanatic
03 Apr 2013, 17:49

In the robot simply use the values up to index -1. 


@cAlgo_Fanatic

lec0456
04 Apr 2013, 01:46

ok, yes you could do that but if you use the market open then you are using the previous open when the current open is stable.  So here is what I did:

 

public override void Calculate(int index)
        {
            int t0=index;
            if(t0<paramPeriods)return;//** prevent crash caused by posibly using a negetive index value
            if(double.IsNaN(Source[t0]))return;
            
            double sum=0;

			if(Source==MarketSeries.Open)
			{
				for (int x = t0 - paramPeriods + 1; x <= t0; x++) // this will include calculations using index where High, Low, & Close values are not final.
				{sum+=Source[x];}									// if you use the open, calculations will be the same as the SMA included with cAlgo
			}
			else
			{
				for (int x = t0 - paramPeriods; x < t0; x++) // this will include the last 10 values not including index because values are not final except for the open.
				{sum+=Source[x];}								// these results wll be different from the SMA included with cAlgo
			}
			
			Result[index]=sum/paramPeriods;
            //DateTime opentime= MarketSeries.OpenTime[index];
            //Print("{0,20}{1,20}{2,20}{3,20}{4,20}",opentime,index,Result[index],Result[index-1],"Indicator");
        }




@lec0456

lec0456
04 Apr 2013, 01:54

So, this way the SMA is now valid at index and only using market data that is final in its calculations.  

Unless there is some reason you want the sma to be on tick which doesn't make sence to me because it is period based.


@lec0456

cAlgo_Fanatic
04 Apr 2013, 14:17

But then you are assigning a value at index which should be the value at the previous index. In other words, you are shifting back 1 bar. 


@cAlgo_Fanatic

lec0456
04 Apr 2013, 16:53

I am shifting back one bar if the SMA is based on the close, high or low because of what I have been asking.  Since these values are not final( or valid )at index you shouldn't use them to calculate the SMA.    Above you recomended to only use the values index-1, which is shifting the values back one bar as well.

What was happening to me was that if I made a calculation based on the SMA value at index and index-1 when the next bar comes(i.e. index advances one)  the SMA at index should be equal to index-1, but sometimes it would not be equal because the SMA was not using the final value of the closing.  Its a little hard to explain.  When the on bar is triggered it calculates the SMA and continues to update the same index value until the next on bar it triggered. So you get different values at the begiining verses the end of the on bar.  thats what my issue is or what I am trying to solve...

If you are using the SMA for manual trading and eyeballing trades, its not going to matter one bit but if you are using the SMA for calculations you will get erratic results.

If you use the SMA the way it is, then you have to use index-1, which is shifting back one bar.  Which is fine except for when you want the SMA based on the Open because then you are shifting back when you don't have to.  At index the open is final. 

I guess the other way to do it is use index -1 when calcualting off of the close, high or low; but use index when calculating off of the open but that creates programing complexity.

 

 


@lec0456

cAlgo_Fanatic
05 Apr 2013, 09:46

I understand what you mean but this is not an error. This is the way it is supposed to be. For as long as you understand how it works you can use it properly. Moreover, you can design your own cutom indicators as you like. 


@cAlgo_Fanatic

lec0456
05 Apr 2013, 22:20

Ok


@lec0456