Hi Steema,
Based on our comparison study we found calculation mismatch in RSI Financial Function of TeeChart. Please have a look on attched file and kindly let us know resolution and reason of mismatch.
It would be a great feature, if RSI has following properties separately:
1] Series
2] Values like (Close, High, Low, Open)
3] Period
Please share us the formula of Weighted Moving Average (WMA) that Teechart is currently using for calculation.
RSI (Relative Strenghth Index) formula calculation
-
- Guru
- Posts: 1603
- Joined: Fri Nov 15, 2002 12:00 am
Re: RSI (Relative Strenghth Index) formula calculation
The following code:Quant wrote:Based on our comparison study we found calculation mismatch in RSI Financial Function of TeeChart. Please have a look on attched file and kindly let us know resolution and reason of mismatch.
Code: Select all
private void InitializeChart()
{
tChart1.Aspect.View3D = false;
Candle candle = new Candle(tChart1.Chart);
candle.Add(DateTime.Parse("07/11/1994"), 1283, 1283, 1283, 1283);
candle.Add(DateTime.Parse("08/11/1994"), 1281, 1281, 1281, 1281);
candle.Add(DateTime.Parse("09/11/1994"), 1259, 1259, 1259, 1259);
candle.Add(DateTime.Parse("10/11/1994"), 1241, 1241, 1241, 1241);
candle.Add(DateTime.Parse("11/11/1994"), 1223, 1223, 1223, 1223);
candle.Add(DateTime.Parse("14/11/1994"), 1210, 1210, 1210, 1210);
candle.Add(DateTime.Parse("15/11/1994"), 1208, 1208, 1208, 1208);
candle.Add(DateTime.Parse("16/11/1994"), 1232, 1232, 1232, 1232);
candle.Add(DateTime.Parse("17/11/1994"), 1247, 1247, 1247, 1247);
candle.Add(DateTime.Parse("21/11/1994"), 1248, 1248, 1248, 1248);
candle.Add(DateTime.Parse("22/11/1994"), 1236, 1236, 1236, 1236);
candle.Add(DateTime.Parse("23/11/1994"), 1221, 1221, 1221, 1221);
candle.Add(DateTime.Parse("24/11/1994"), 1230, 1230, 1230, 1230);
candle.Add(DateTime.Parse("25/11/1994"), 1246, 1246, 1246, 1246);
candle.Add(DateTime.Parse("29/11/1994"), 1252, 1252, 1252, 1252);
candle.Add(DateTime.Parse("30/11/1994"), 1246, 1246, 1246, 1246);
candle.Add(DateTime.Parse("01/12/1994"), 1240, 1240, 1240, 1240);
candle.Add(DateTime.Parse("02/12/1994"), 1233, 1233, 1233, 1233);
candle.Add(DateTime.Parse("05/12/1994"), 1229, 1229, 1229, 1229);
candle.Add(DateTime.Parse("06/12/1994"), 1215, 1215, 1215, 1215);
candle.Add(DateTime.Parse("07/12/1994"), 1194, 1194, 1194, 1194);
candle.Add(DateTime.Parse("08/12/1994"), 1177, 1177, 1177, 1177);
candle.Add(DateTime.Parse("09/12/1994"), 1182, 1182, 1182, 1182);
candle.Add(DateTime.Parse("12/12/1994"), 1153, 1153, 1153, 1153);
candle.Add(DateTime.Parse("13/12/1994"), 1136, 1136, 1136, 1136);
candle.Add(DateTime.Parse("14/12/1994"), 1147, 1147, 1147, 1147);
candle.Add(DateTime.Parse("15/12/1994"), 1161, 1161, 1161, 1161);
FastLine fast = new FastLine(tChart1.Chart);
fast.VertAxis = VerticalAxis.Right;
tChart1.Axes.Right.Grid.Visible = false;
RSIFunction rsi = new RSIFunction(tChart1.Chart);
rsi.Style = RSIStyle.Close;
rsi.PeriodStyle = PeriodStyles.NumPoints;
rsi.Period = 12;
fast.Function = rsi;
fast.DataSource = candle;
fast.CheckDataSource();
}
private void button4_Click_1(object sender, EventArgs e)
{
Steema.TeeChart.Export.TextFormat text = tChart1.Export.Data.Text;
text.IncludeHeader = true;
text.IncludeIndex = true;
text.IncludeLabels = true;
text.IncludeSeriesTitle = true;
text.Save(@"D:\tmp\testData.txt");
}
Best Regards,
Christopher Ireland / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
Re: RSI (Relative Strenghth Index) formula calculation
Dear Steema,
We checked your sample code with our sample values, but we still find value mismatch. FYI we have attached excel file with new values. Following is the source code we used:
We checked your sample code with our sample values, but we still find value mismatch. FYI we have attached excel file with new values. Following is the source code we used:
Code: Select all
public Form2()
{
InitializeComponent();
InitializeChart();
}
private void InitializeChart()
{
tChart1.Aspect.View3D = false;
Candle candle = new Candle(tChart1.Chart);
candle.Add(DateTime.Parse("11/07/1994"), 1283, 1283, 1283, 1283);
candle.Add(DateTime.Parse("11/08/1994"), 1281, 1281, 1281, 1281);
candle.Add(DateTime.Parse("11/09/1994"), 1259, 1259, 1259, 1259);
candle.Add(DateTime.Parse("11/10/1994"), 1241, 1241, 1241, 1241);
candle.Add(DateTime.Parse("11/11/1994"), 1223, 1223, 1223, 1223);
candle.Add(DateTime.Parse("11/14/1994"), 1210, 1210, 1210, 1210);
candle.Add(DateTime.Parse("11/15/1994"), 1208, 1208, 1208, 1208);
candle.Add(DateTime.Parse("11/16/1994"), 1232, 1232, 1232, 1232);
candle.Add(DateTime.Parse("11/17/1994"), 1247, 1247, 1247, 1247);
candle.Add(DateTime.Parse("11/21/1994"), 1248, 1248, 1248, 1248);
candle.Add(DateTime.Parse("11/22/1994"), 1236, 1236, 1236, 1236);
candle.Add(DateTime.Parse("11/23/1994"), 1221, 1221, 1221, 1221);
candle.Add(DateTime.Parse("11/24/1994"), 1230, 1230, 1230, 1230);
candle.Add(DateTime.Parse("11/25/1994"), 1246, 1246, 1246, 1246);
candle.Add(DateTime.Parse("11/29/1994"), 1252, 1252, 1252, 1252);
candle.Add(DateTime.Parse("11/30/1994"), 1246, 1246, 1246, 1246);
candle.Add(DateTime.Parse("12/01/1994"), 1240, 1240, 1240, 1240);
candle.Add(DateTime.Parse("12/02/1994"), 1233, 1233, 1233, 1233);
candle.Add(DateTime.Parse("12/05/1994"), 1229, 1229, 1229, 1229);
candle.Add(DateTime.Parse("12/06/1994"), 1215, 1215, 1215, 1215);
candle.Add(DateTime.Parse("12/07/1994"), 1194, 1194, 1194, 1194);
candle.Add(DateTime.Parse("12/08/1994"), 1177, 1177, 1177, 1177);
candle.Add(DateTime.Parse("12/09/1994"), 1182, 1182, 1182, 1182);
candle.Add(DateTime.Parse("12/12/1994"), 1153, 1153, 1153, 1153);
candle.Add(DateTime.Parse("12/13/1994"), 1136, 1136, 1136, 1136);
candle.Add(DateTime.Parse("12/14/1994"), 1147, 1147, 1147, 1147);
candle.Add(DateTime.Parse("12/15/1994"), 1161, 1161, 1161, 1161);
FastLine fast = new FastLine(tChart1.Chart);
fast.VertAxis = VerticalAxis.Right;
tChart1.Axes.Right.Grid.Visible = false;
RSIFunction rsi = new RSIFunction(tChart1.Chart);
rsi.Style = RSIStyle.Close;
rsi.PeriodStyle = PeriodStyles.NumPoints;
rsi.Period = 14;
fast.Function = rsi;
fast.DataSource = candle;
fast.CheckDataSource();
tChart1.MouseDoubleClick += new MouseEventHandler(tChart1_MouseDoubleClick);
}
void tChart1_MouseDoubleClick(object sender, MouseEventArgs e)
{
tChart1.ShowEditor();
}
private void button4_Click_1(object sender, EventArgs e)
{
Steema.TeeChart.Export.TextFormat text = tChart1.Export.Data.Text;
text.IncludeHeader = true;
text.IncludeIndex = true;
text.IncludeLabels = true;
text.IncludeSeriesTitle = true;
text.Save(@"D:\tmp\testData.txt");
}
- Attachments
-
- RSI2.zip
- (10.95 KiB) Downloaded 823 times
-
- Guru
- Posts: 1603
- Joined: Fri Nov 15, 2002 12:00 am
Re: RSI (Relative Strenghth Index) formula calculation
Attached latest excel with TeeChart calculations in green, with the equivalent calculation in dark green.
As you can see, the difference is in the calculation of the averages. TeeChart calculates a correct Simple Moving Average, which is the average the RSI was originally designed to use, as you can read here. The calculation takes the previous n points and averages them. The calculation you use, on the other hand, does not do this. It takes the previous average, adds a single point to it, and recalculates, which does not give the same result.
As you can see, the difference is in the calculation of the averages. TeeChart calculates a correct Simple Moving Average, which is the average the RSI was originally designed to use, as you can read here. The calculation takes the previous n points and averages them. The calculation you use, on the other hand, does not do this. It takes the previous average, adds a single point to it, and recalculates, which does not give the same result.
Best Regards,
Christopher Ireland / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
Re: RSI (Relative Strenghth Index) formula calculation
Dear Steema,
We used following excel sheet for RSI calculation :
http://stockcharts.com/education/indica ... is/RSI.xls
We are not saying that you have used errorneous formula for RSI Calculation, but its result is not expected as per our benchmark testing. We verified the values (computed using formula mentioned in above excel file) with other Financial Charting Software's values, and it matches perfectly. In previously attached excel files, we mentioned the benchmark values in a column named as "RSI Calculated from Other Software" which is taken from that financial charting software.
What we shared with you is verified from valid resources and most importantly it is currently expected by users. Because they gonna compare the same with other Financial Charting Software and if they find any major differences in those values or calculation, they definitely going to raise this issue.
So we would like to suggest to add new type of RSI calculation in TeeChart according to above excel formula.
We used following excel sheet for RSI calculation :
http://stockcharts.com/education/indica ... is/RSI.xls
We are not saying that you have used errorneous formula for RSI Calculation, but its result is not expected as per our benchmark testing. We verified the values (computed using formula mentioned in above excel file) with other Financial Charting Software's values, and it matches perfectly. In previously attached excel files, we mentioned the benchmark values in a column named as "RSI Calculated from Other Software" which is taken from that financial charting software.
What we shared with you is verified from valid resources and most importantly it is currently expected by users. Because they gonna compare the same with other Financial Charting Software and if they find any major differences in those values or calculation, they definitely going to raise this issue.
So we would like to suggest to add new type of RSI calculation in TeeChart according to above excel formula.
-
- Guru
- Posts: 1603
- Joined: Fri Nov 15, 2002 12:00 am
Re: RSI (Relative Strenghth Index) formula calculation
Thank you for the suggestion.Quant wrote:So we would like to suggest to add new type of RSI calculation in TeeChart according to above excel formula.
TeeChart has tens of thousands of existing users, a proportion of whom will be already using the RSI function as it is - changing the function calculation would give these users unexpected results.
As I'm sure you understand, we at Steema prefer to use documented evidence of a function's algorithms, and you will also understand that the evidence you present in favour of your calculation is not clearly and transparently documented. The wikipedia article on RSI is quite clear, as I have already linked to here:
Code: Select all
If the last close is the same as the previous, both U and D are zero. The average U and D are calculated using an n-period exponential moving average (EMA) in AIQ's version of RSI. Wilder's original version uses an n-period simple moving average (SMA).[3]
Best Regards,
Christopher Ireland / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
Re: RSI (Relative Strenghth Index) formula calculation
Dear Steema,
Thanks for adding this type of RSI Calculation as an enhancement to your TeeChart. But we need to implement this at our side ASAP, and any help to achieve this would be greatly appreciated, since it is urgently required by our users.
Thanks for adding this type of RSI Calculation as an enhancement to your TeeChart. But we need to implement this at our side ASAP, and any help to achieve this would be greatly appreciated, since it is urgently required by our users.
-
- Guru
- Posts: 1603
- Joined: Fri Nov 15, 2002 12:00 am
Re: RSI (Relative Strenghth Index) formula calculation
There is nothing to stop you deriving your own classes and making all the necessary calculations you need. Here is an example of the classes I mean:Quant wrote:Thanks for adding this type of RSI Calculation as an enhancement to your TeeChart. But we need to implement this at our side ASAP, and any help to achieve this would be greatly appreciated, since it is urgently required by our users.
Code: Select all
public class MyRSIFunction : RSIFunction
{
private RSIAverageType fAverageType;
private Steema.TeeChart.Styles.Series iSeries;
private ValueList Closes, Opens, Lows, Highs;
private double seedAverageUp, seedAverageDown;
private MyRSIStyle fStyle;
public MyRSIFunction(Chart c) : base(c)
{
fAverageType = RSIAverageType.SMA;
}
public MyRSIFunction() : this(null)
{
}
/// <summary>
/// Sets the RSI function to use either Open or Close values.
/// </summary>
public new MyRSIStyle Style
{
get { return fStyle; }
set
{
if (fStyle != value)
{
fStyle = value;
this.Recalculate();
}
}
}
public override void AddPoints(Array source)
{
seedAverageUp = double.NaN;
seedAverageDown = double.NaN;
base.AddPoints(source);
}
private ValueList GetYValueList(Series series, string AListName)
{
AListName = AListName.ToUpper();
for (int t = 2; t < series.ValuesLists.Count; t++)
if (AListName == series.ValuesLists[t].Name.ToUpper())
return series.ValuesLists[t];
return series.YValues;
}
public override double Calculate(Series source, int first, int last)
{
if(AverageType == RSIAverageType.EMA)
{
int NumPoints;
double tmpClose, Ups, Downs, result;
if (iSeries != source)
{
Closes = GetYValueList(source, Texts.ValuesClose);
Opens = GetYValueList(source, Texts.ValuesOpen);
Lows = GetYValueList(source, Texts.ValuesLow);
Highs = GetYValueList(source, Texts.ValuesHigh);
iSeries = source;
}
NumPoints = (last - first) + 1;
Ups = 0;
Downs = 0;
if (double.IsNaN(seedAverageDown) || double.IsNaN(seedAverageUp))
{
switch (this.Style)
{
case MyRSIStyle.OpenClose:
for (int t = first; t <= last; ++t)
{
tmpClose = Closes[t];
if (Opens[t] > tmpClose) Downs = Downs + tmpClose;
else Ups = Ups + tmpClose;
}
break;
case MyRSIStyle.Close:
for (int t = first + 1; t <= last; ++t)
{
tmpClose = Closes[t] - Closes[t - 1];
if (tmpClose < 0) Downs = Downs - tmpClose;
else Ups = Ups + tmpClose;
}
break;
case MyRSIStyle.Open:
for (int t = first + 1; t <= last; ++t)
{
tmpClose = Opens[t] - Opens[t - 1];
if (tmpClose < 0) Downs = Downs - tmpClose;
else Ups = Ups + tmpClose;
}
break;
case MyRSIStyle.High:
for (int t = first + 1; t <= last; ++t)
{
tmpClose = Highs[t] - Highs[t - 1];
if (tmpClose < 0) Downs = Downs - tmpClose;
else Ups = Ups + tmpClose;
}
break;
case MyRSIStyle.Low:
for (int t = first + 1; t <= last; ++t)
{
tmpClose = Lows[t] - Lows[t - 1];
if (tmpClose < 0) Downs = Downs - tmpClose;
else Ups = Ups + tmpClose;
}
break;
}
Downs = Downs / (NumPoints - 1);
Ups = Ups / (NumPoints - 1);
seedAverageDown = Downs;
seedAverageUp = Ups;
}
else
{
switch (this.Style)
{
case MyRSIStyle.OpenClose:
tmpClose = Closes[last];
if (Opens[last] > tmpClose) Downs = tmpClose;
else Ups = tmpClose;
break;
case MyRSIStyle.Close:
tmpClose = Closes[last] - Closes[last - 1];
if (tmpClose < 0) Downs = Math.Abs(tmpClose);
else Ups = tmpClose;
break;
case MyRSIStyle.Open:
tmpClose = Opens[last] - Opens[last - 1];
if (tmpClose < 0) Downs = Math.Abs(tmpClose);
else Ups = tmpClose;
break;
case MyRSIStyle.High:
tmpClose = Highs[last] - Highs[last - 1];
if (tmpClose < 0) Downs = Math.Abs(tmpClose);
else Ups = tmpClose;
break;
case MyRSIStyle.Low:
tmpClose = Lows[last] - Lows[last - 1];
if (tmpClose < 0) Downs = Math.Abs(tmpClose);
else Ups = tmpClose;
break;
}
seedAverageDown = ((seedAverageDown * (NumPoints - 1)) + Downs) / NumPoints;
seedAverageUp = ((seedAverageUp * (NumPoints - 1)) + Ups) / NumPoints;
}
if (seedAverageDown != 0)
{
result = 100.0 - (100.0 / (1.0 + Math.Abs(seedAverageUp / seedAverageDown)));
if (result < 0) result = 0;
else
if (result > 100) result = 100;
}
else result = 100;
return result;
}
else
{
return base.Calculate(source, first, last);
}
}
/// <summary>
/// Sets the RSI function to use either SMA or EMA as its averaging algorithm.
/// </summary>
#if DESIGNATTRIBUTES
[DefaultValue(typeof(RSIAverageType), "SMA")]
#endif
#if STORE || WINDOWS_PHONE
public new RSIAverageType AverageType
#else
public RSIAverageType AverageType
#endif
{
get { return fAverageType; }
set
{
if (fAverageType != value)
{
fAverageType = value;
this.Recalculate();
}
}
}
}
/// <summary>
/// Used in see cref="RSIFunction.Style"/> property.
/// </summary>
public enum MyRSIStyle
{
/// <summary>
/// Uses Close values comparative to their respective Open Values.
/// </summary>
OpenClose,
/// <summary>
/// Uses Close values comparative to prior Close values.
/// </summary>
Close,
/// <summary>
/// Uses Open values comparative to prior Open values.
/// </summary>
Open,
/// <summary>
/// Uses High values comparative to prior High values.
/// </summary>
High,
/// <summary>
/// Uses Low values comparative to prior Low values.
/// </summary>
Low
}
/// <summary>
/// Used in see cref="RSIFunction.Style"/> property.
/// </summary>
public enum RSIAverageType
{
/// <summary>
/// Simple Moving Average.
/// </summary>
SMA,
/// <summary>
/// Exponential Moving Average.
/// </summary>
EMA
}
Code: Select all
private void InitializeChart()
{
tChart1.Aspect.View3D = false;
Candle candle = new Candle(tChart1.Chart);
candle.Add(DateTime.Parse("07/11/1994"), 1283, 1283, 1283, 1283);
candle.Add(DateTime.Parse("08/11/1994"), 1281, 1281, 1281, 1281);
candle.Add(DateTime.Parse("09/11/1994"), 1259, 1259, 1259, 1259);
candle.Add(DateTime.Parse("10/11/1994"), 1241, 1241, 1241, 1241);
candle.Add(DateTime.Parse("11/11/1994"), 1223, 1223, 1223, 1223);
candle.Add(DateTime.Parse("14/11/1994"), 1210, 1210, 1210, 1210);
candle.Add(DateTime.Parse("15/11/1994"), 1208, 1208, 1208, 1208);
candle.Add(DateTime.Parse("16/11/1994"), 1232, 1232, 1232, 1232);
candle.Add(DateTime.Parse("17/11/1994"), 1247, 1247, 1247, 1247);
candle.Add(DateTime.Parse("21/11/1994"), 1248, 1248, 1248, 1248);
candle.Add(DateTime.Parse("22/11/1994"), 1236, 1236, 1236, 1236);
candle.Add(DateTime.Parse("23/11/1994"), 1221, 1221, 1221, 1221);
candle.Add(DateTime.Parse("24/11/1994"), 1230, 1230, 1230, 1230);
candle.Add(DateTime.Parse("25/11/1994"), 1246, 1246, 1246, 1246);
candle.Add(DateTime.Parse("29/11/1994"), 1252, 1252, 1252, 1252);
candle.Add(DateTime.Parse("30/11/1994"), 1246, 1246, 1246, 1246);
candle.Add(DateTime.Parse("01/12/1994"), 1240, 1240, 1240, 1240);
candle.Add(DateTime.Parse("02/12/1994"), 1233, 1233, 1233, 1233);
candle.Add(DateTime.Parse("05/12/1994"), 1229, 1229, 1229, 1229);
candle.Add(DateTime.Parse("06/12/1994"), 1215, 1215, 1215, 1215);
candle.Add(DateTime.Parse("07/12/1994"), 1194, 1194, 1194, 1194);
candle.Add(DateTime.Parse("08/12/1994"), 1177, 1177, 1177, 1177);
candle.Add(DateTime.Parse("09/12/1994"), 1182, 1182, 1182, 1182);
candle.Add(DateTime.Parse("12/12/1994"), 1153, 1153, 1153, 1153);
candle.Add(DateTime.Parse("13/12/1994"), 1136, 1136, 1136, 1136);
candle.Add(DateTime.Parse("14/12/1994"), 1147, 1147, 1147, 1147);
candle.Add(DateTime.Parse("15/12/1994"), 1161, 1161, 1161, 1161);
FastLine fast = new FastLine(tChart1.Chart);
fast.VertAxis = VerticalAxis.Right;
tChart1.Axes.Right.Grid.Visible = false;
MyRSIFunction rsi = new MyRSIFunction(tChart1.Chart);
rsi.Style = MyRSIStyle.Close;
rsi.AverageType = RSIAverageType.EMA;
rsi.PeriodStyle = PeriodStyles.NumPoints;
rsi.Period = 14;
fast.Function = rsi;
fast.DataSource = candle;
fast.CheckDataSource();
}
private void button4_Click(object sender, EventArgs e)
{
Steema.TeeChart.Export.TextFormat text = tChart1.Export.Data.Text;
text.IncludeHeader = true;
text.IncludeIndex = true;
text.IncludeLabels = true;
text.IncludeSeriesTitle = true;
text.Save(@"C:\tmp\testData.txt");
}
Best Regards,
Christopher Ireland / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |