Рассчитать RSI на основе Kraken OHLC - PullRequest
0 голосов
/ 06 мая 2018

Я хочу точно отразить значения RSI на cryptowatch.de (в моем случае LTC-EUR), я использовал сайт stockcharts.com , который объясняет, как рассчитать RSI, чтобы написать калькулятор в Javascript (узел).

Пока мой код:

// data is an array of open-prices in descending date order (the current price is the last element)
function calculateRSI(data) {
  data = data.reverse(); // Reverse to handle it better
  let avgGain = 0;
  let aveLoss = 0;

  // Calculate first 14 periods
  for (let i = 0; i < 14; i++) {
    const ch = data[i] - data[i + 1];

    if (ch >= 0) {
      avgGain += ch;
    } else {
      aveLoss -= ch;
    }
  }

  avgGain /= 14;
  aveLoss /= 14;

  // Smooth values 250 times
  for (let i = 14; i < 264; i++) {
    const ch = data[i] - data[i + 1];

    if (ch >= 0) {
      avgGain = (avgGain * 13 + ch) / 14;
      aveLoss = (aveLoss * 13) / 14;
    } else {
      avgGain = (avgGain * 13) / 14;
      aveLoss = (aveLoss * 13 - ch) / 14;
    }
  }

  // Calculate relative strength index
  const rs = avgGain / aveLoss;
  return 100 - 100 / (1 + rs);
}

Но результат всегда далек от значений, которые отображаются в cryptowatch.de , что не так? Как правильно рассчитать? (Пост на других языках программирования тоже подойдет)

Спасибо @jingx, но результаты все еще не верны

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

Как правильно рассчитать это? (Публикация на других языках программирования тоже подойдет)

Хорошо, позвольте мне добавить один такой из QuantFX модуль

Можно встретить много формулировок, некоторые с примерами, некоторые с наборами данных проверки, поэтому позвольте мне выбрать одну такую, используя оформленный numba.jit код Python с несколькими numpy векторизованными приемами:

def RSI_func( priceVEC, RSI_period = 14 ):
    """
    __doc__ 
    USE:
             RSI_func( priceVEC, RSI_period = 14 )

             Developed by J. Welles Wilder and introduced in his 1978 book,
             New Concepts in Technical Trading Systems, the Relative Strength Index
             (RSI) is an extremely useful and popular momentum oscillator.

             The RSI compares the magnitude of a stock's recent gains
             to the magnitude of its recent losses and turns that information
             into a number that ranges from 0 to 100.

             It takes a single parameter, the number of time periods to use
             in the calculation. In his book, Wilder recommends using 14 periods.

             The RSI's full name is actually rather unfortunate as it is easily
             confused with other forms of Relative Strength analysis such as
             John Murphy's "Relative Strength" charts and IBD's "Relative Strength"
             rankings.

             Most other kinds of "Relative Strength" stuff involve using
             more than one stock in the calculation. Like most true indicators,
             the RSI only needs one stock to be computed.

             In order to avoid confusion,
             many people avoid using the RSI's full name and just call it "the RSI."

             ( Written by Nicholas Fisher)

    PARAMS:  
             pricesVEC  - a vector of price-DOMAIN-alike data in natural order
             RSI_period - a positive integer for an RSI averaging period

    RETURNS:
             a vector of RSI values

    EXAMPLE:
             >>> RSI_func( np.asarray( [ 46.1250, 47.1250, 46.4375, 46.9375, 44.9375,
                                         44.2500, 44.6250, 45.7500, 47.8125, 47.5625,
                                         47.0000, 44.5625, 46.3125, 47.6875, 46.6875,
                                         45.6875, 43.0625, 43.5625, 44.8750, 43.6875
                                         ]
                                       ),
                           RSI_period = 14  
                           )

             array( [ 51.77865613,  51.77865613,  51.77865613,  51.77865613,  51.77865613,  51.77865613,  51.77865613,
                      51.77865613,  51.77865613,  51.77865613,  51.77865613,  51.77865613,  51.77865613,
                      51.77865613,  48.47708511,  41.07344947,  42.86342911,  47.38184958,  43.99211059
                      ]
                    )
             OUGHT BE:
                      51.779,       48.477,       41.073,       42.863,       47.382,       43.992
             [PASSED]
    Ref.s:
             >>> http://cns.bu.edu/~gsc/CN710/fincast/Technical%20_indicators/Relative%20Strength%20Index%20(RSI).htm
    """
    deltas           =  np.diff( priceVEC )
    seed             =  deltas[:RSI_period]
    up               =  seed[seed >= 0].sum() / RSI_period
    down             = -seed[seed <  0].sum() / RSI_period
    rs               =  up / down
    rsi              =   50. * np.ones_like( priceVEC )                 # NEUTRAL VALUE PRE-FILL
    rsi[:RSI_period] =  100. - ( 100. / ( 1. + rs ) )

    for i in np.arange( RSI_period, len( priceVEC )-1 ):
        delta = deltas[i]

        if  delta   >  0:
            upval   =  delta
            downval =  0.
        else:
            upval   =  0.
            downval = -delta

        up   = ( up   * ( RSI_period - 1 ) + upval   ) / RSI_period
        down = ( down * ( RSI_period - 1 ) + downval ) / RSI_period

        rs      = up / down

        rsi[i]  = 100. - ( 100. / ( 1. + rs ) )

    return rsi[:-1]

Учитывая, что вы хотели " точно отразить" чей-то график", существует самый безопасный способ перепроверить, какую формулировку они фактически использовали для расчета RSI. Обычно можно увидеть различия, поэтому для совпадения « точный » требуется своего рода исследование того, что они фактически использовали для генерации своих данных (также обратите внимание на соответствующую административную разницу (и) смещения UTC, если работаете с D1- сроки).

0 голосов
/ 07 мая 2018

Вы, вероятно, пропустили сглаживание avgLoss, когда это усиление, и avgGain, когда это убыток, т.е. в цикле сглаживания:

if (ch >= 0) {
  avgGain = (avgGain * 13 + ch) / 14;
  aveLoss = (aveLoss * 13) / 14;
} else {
  avgGain = (avgGain * 13) / 14;
  aveLoss = (aveLoss * 13 - ch) / 14;
}
...