2

Im trying to recreate Tradingviews pine script RSI code into Javascript code. But having a hard time figuring out how it works. I made the basic RSI using a normal moving average calculation. But the pine script uses exponential weighted moving average. And there documentation is really hard to follow to me. This is the pine script.

//@version=4
study(title="Relative Strength Index", shorttitle="RSI", format=format.price, precision=2, resolution="")
len = input(14, minval=1, title="Length")
src = input(close, "Source", type = input.source)
up = rma(max(change(src), 0), len)
down = rma(-min(change(src), 0), len)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
plot(rsi, "RSI", color=#7E57C2)
band1 = hline(70, "Upper Band", color=#787B86)
bandm = hline(50, "Middle Band", color=color.new(#787B86, 50))
band0 = hline(30, "Lower Band", color=#787B86)
fill(band1, band0, color=color.rgb(126, 87, 194, 90), title="Background")

This is what I could make of it in Javascript:

// Period = 200
// Close variable is 200 closed values. Where [0] in array = oldest, [199] in array = newest value.

/**
 * Relative strength index. Based on closed periods.
 * 
 * @param {Array} close 
 * @param {Integer} period 
 * @returns 
 */
function calculateRSI(close, period) {

    // Only calculate if it is worth it. First {period - 1} amount of calculations aren't correct anyway.
    if (close.length < period) {
        return 50;
    }

    let averageGain = 0;
    let averageLoss = 0;
    const alpha = 1 / period;

    // Exponential weighted moving average.
    for (let i = 1; i < period; i++)
    {
        let change = close[i] - close[i - 1];

        if (change >= 0) {
            averageGain = alpha * change + (1 - alpha) * averageGain;
        } else {
            averageLoss = alpha * -change + (1 - alpha) * averageLoss;
        }
    }

    // Tried this too, but seems to not really matter.
    // To get an actual average.
    // averageGain /= period;
    // averageLoss /= period;

    // Calculate relative strength index. Where it can only be between 0 and 100.
    var rsi = 100 - (100 / (1 + (averageGain / averageLoss)));

    return rsi;
}

The results this function gives on my chart is not too bad, but it just isn't the same as I have it in Tradingview. I belive im missing something that the pine script does and I don't.

Things I dont understand of the pine script:

  • When does it do a for loop? I don't see it in there functions. If they don't, how do they calculate the average for a period of longer than 2? You have to loop for that right?
  • How does the rma function work? This is their docs.

I might have too many questions on this, but I think if you show a somewhat working example in Javascript of the RSI calculation like they do. Then I can probably make sense of it.

Is my calculation in Javascript correct to the one in the pine script?

Allart
  • 830
  • 11
  • 33
  • It will probably be easier for you to go back to the original description of the RSI calcs by Wilder in his "New Concepts in Technical Trading Systems" book, which includes the average calcs. The "RMA" acronym is not by Wilder, btw; but it's used by some platforms to name the EMA variation Wilder created. – PineCoders-LucF Jan 12 '22 at 15:56
  • There is no loop in the Pine version of RMA because none is needed; the [Pine runtime](https://www.tradingview.com/pine-script-docs/en/v5/language/Execution_model.html) does the work for us. Wilder was always looking for simple ways to calculate his stuff because he did the calcs by hand. RMA uses a recursive calc where it starts from its previous value and only requires adding the new value to it. – PineCoders-LucF Jan 12 '22 at 15:56
  • @PineCoders-LucF Its been some time and I went for the easier route. I would've liked to get it the way Tradingview does but currently made it in a way thats profitable too so im happy :) – Allart Feb 08 '22 at 14:24

0 Answers0