RSI 与 Wilder 的 RSI 计算问题

Mik*_*ith 3 c# algorithm technical-indicator

我无法获得平滑的 RSI。下图来自 freestockcharts.com。计算使用此代码。

public static double CalculateRsi(IEnumerable<double> closePrices)
{
    var prices = closePrices as double[] ?? closePrices.ToArray();

    double sumGain = 0;
    double sumLoss = 0;
    for (int i = 1; i < prices.Length; i++)
    {
        var difference = prices[i] - prices[i - 1];
        if (difference >= 0)
        {
            sumGain += difference;
        }
        else
        {
            sumLoss -= difference;
        }
    }

    if (sumGain == 0) return 0;
    if (Math.Abs(sumLoss) < Tolerance) return 100;

    var relativeStrength = sumGain / sumLoss;

    return 100.0 - (100.0 / (1 + relativeStrength));
}
Run Code Online (Sandbox Code Playgroud)

/sf/...th-index-using-some-programming-language-js-c

这似乎是没有平滑处理的纯 RSI。平滑 RSI 是如何计算的?我尝试更改它以适应这两个站点的定义,但是输出不正确。它几乎没有被平滑。

(我没有足够的代表来发布链接)

tc2000 -> Indicators -> RSI_and_Wilder_s_RSI (Wilder's smoothing = Previous MA value + (1/n periods * (Close - Previous MA)))

priceactionlab -> wilders-cutlers-and-harris-relative-strength-index (RS = EMA(Gain(n), n)/EMA(Loss(n), n))
Run Code Online (Sandbox Code Playgroud)

有人真的可以用一些样本数据进行计算吗?

怀尔德的 RSI 与 RSI 在此输入图像描述

Roo*_*lie 5

为了计算 RSI,您需要一个周期来计算它。正如维基百科所述,14 的使用频率很高。

所以计算步骤如下:

周期 1 - 13,RSI = 0

第 14 期:

AverageGain = TotalGain / PeriodCount;
AverageLoss = TotalLoss / PeriodCount;
RS = AverageGain / AverageLoss;
RSI = 100 - 100 / (1 + RS);
Run Code Online (Sandbox Code Playgroud)

第 15 期 - 至 (N) 期:

if (Period(N)Change > 0
  AverageGain(N) = ((AverageGain(N - 1) * (PeriodCount - 1)) + Period(N)Change) / PeriodCount;
else
  AverageGain(N) = (AverageGain(N - 1) * (PeriodCount - 1)) / PeriodCount;

if (this.Change < 0)
  AverageLoss(N) = ((AverageLoss(N - 1) * (PeriodCount - 1)) + Math.Abs(Period(N)Change)) / PeriodCount;
else
  AverageLoss(N) = (AverageLoss(N - 1) * (PeriodCount - 1)) / PeriodCount;

RS = AverageGain / AverageLoss;
RSI = 100 - (100 / (1 + RS));
Run Code Online (Sandbox Code Playgroud)

此后,为了平滑这些值,您需要将特定时期的移动平均值应用于 RSI 值。为此,请从最后一个指数到第一个指数遍历 RSI 值,并根据之前的 x 个平滑周期计算当前周期的平均值。

完成后,只需反转值列表即可获得预期的顺序:

List<double> SmoothedRSI(IEnumerable<double> rsiValues, int smoothingPeriod)
{
  if (rsiValues.Count() <= smoothingPeriod)
    throw new Exception("Smoothing period too large or too few RSI values passed.");

  List<double> results = new List<double>();
  List<double> reversedRSIValues = rsiValues.Reverse().ToList();

  for (int i = 1; i < reversedRSIValues.Count() - smoothingPeriod - 1; i++)
    results.Add(reversedRSIValues.Subset(i, i + smoothingPeriod).Average());

  return results.Reverse().ToList();
}
Run Code Online (Sandbox Code Playgroud)

Subset方法只是一个简单的扩展方法,如下:

public static List<double> Subset(this List<double> values, int start, int end)
{
  List<double> results = new List<double>();

  for (int i = start; i <= end; i++)
    results.Add(values[i]);

  return results;
}
Run Code Online (Sandbox Code Playgroud)

免责声明,我没有测试代码,但它应该让您了解如何应用平滑。