原帖由 flyingatom 于 2009-1-1 16:37 发表 首先祝各位胡同同仁新年快乐! 我有一个关于RSI的计算问题请教大家。symbol: BGU, Interval: 5, I got following data (for close)12/22/2008 14:45:00 32.5512/22/2008 14:50:00 32.35412/22/2008 14:55:00 31.9412 ...
没时间看你的问题了,下面是俺算RSI的程序,可能跟第一个数值需要250天的平均有关,记得写这段的时候也是怎么凑都不对,好像挺trick,最后对了,但现在记不得哪个地方trick了。
/// <summary>
/// Returns RSI starting from "daysAgo" for "countDays".
/// RSI Formular:
/// RSI = 100 - 100 / ( 1 + RS )
/// RS = Average Gains / Average Loss
/// Average Gain = [(previous Average Gain) x (n - 1) + current Gain] / n
/// First Average Gain = Total of Gains during past m periods / m
/// Average Loss = [(previous Average Loss) x (n - 1) + current Loss] / n
/// First Average Loss = Total of Losses during past m periods / m
/// </summary>
public decimal RSI(int daysAgo, int countDays)
{
decimal averageGain, averageLoss;
return RSI(daysAgo, countDays, out averageGain, out averageLoss);
}
public decimal RSI(int daysAgo, int countDays,
out decimal averageGain, out decimal averageLoss)
{
averageGain = 0M;
averageLoss = 0M;
if (countDays <= 0 || this.closes == null || this.closes.Length <= 0)
return 0M;
// Min 15 days data is required.
if (this.closes.Length - daysAgo < 15)
return 0M;
// Leave at least one day to calculate the RS.
int count = this.closes.Length - daysAgo - 1;
int i = 1;
int j = 0;
// For the first average gain 250 days of data is preferred.
if (count > 250)
count = 250;
// Calculate the first average gain.
for (; i <= count; i++, j++)
{
decimal gain = this.closes - this.closes[i - 1];
if (gain > 0M)
averageGain += gain;
else
averageLoss -= gain;
}
// Since the very first data is not counted.
averageGain /= j;
averageLoss /= j;
for (; i < this.closes.Length - daysAgo; i++)
{
decimal gain = this.closes - this.closes[i - 1];
if (gain > 0M)
{
averageGain = (averageGain * (countDays - 1) + gain) / countDays;
averageLoss = averageLoss * (countDays - 1) / countDays;
}
else
{
averageGain = averageGain * (countDays - 1) / countDays;
averageLoss = (averageLoss * (countDays - 1) - gain) / countDays;
}
}
if (averageLoss == 0M)
return 100M;
return (100M - 100M / (1M + averageGain / averageLoss));
} |