Just Another RSI
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © HeWhoMustNotBeNamed

//   __    __            __       __  __                  __       __                        __      __    __              __      _______             __    __                                          __ 
//  /  |  /  |          /  |  _  /  |/  |                /  \     /  |                      /  |    /  \  /  |            /  |    /       \           /  \  /  |                                        /  |
//  $$ |  $$ |  ______  $$ | / \ $$ |$$ |____    ______  $$  \   /$$ | __    __   _______  _$$ |_   $$  \ $$ |  ______   _$$ |_   $$$$$$$  |  ______  $$  \ $$ |  ______   _____  ____    ______    ____$$ |
//  $$ |__$$ | /      \ $$ |/$  \$$ |$$      \  /      \ $$$  \ /$$$ |/  |  /  | /       |/ $$   |  $$$  \$$ | /      \ / $$   |  $$ |__$$ | /      \ $$$  \$$ | /      \ /     \/    \  /      \  /    $$ |
//  $$    $$ |/$$$$$$  |$$ /$$$  $$ |$$$$$$$  |/$$$$$$  |$$$$  /$$$$ |$$ |  $$ |/$$$$$$$/ $$$$$$/   $$$$  $$ |/$$$$$$  |$$$$$$/   $$    $$< /$$$$$$  |$$$$  $$ | $$$$$$  |$$$$$$ $$$$  |/$$$$$$  |/$$$$$$$ |
//  $$$$$$$$ |$$    $$ |$$ $$/$$ $$ |$$ |  $$ |$$ |  $$ |$$ $$ $$/$$ |$$ |  $$ |$$      \   $$ | __ $$ $$ $$ |$$ |  $$ |  $$ | __ $$$$$$$  |$$    $$ |$$ $$ $$ | /    $$ |$$ | $$ | $$ |$$    $$ |$$ |  $$ |
//  $$ |  $$ |$$$$$$$$/ $$$$/  $$$$ |$$ |  $$ |$$ \__$$ |$$ |$$$/ $$ |$$ \__$$ | $$$$$$  |  $$ |/  |$$ |$$$$ |$$ \__$$ |  $$ |/  |$$ |__$$ |$$$$$$$$/ $$ |$$$$ |/$$$$$$$ |$$ | $$ | $$ |$$$$$$$$/ $$ \__$$ |
//  $$ |  $$ |$$       |$$$/    $$$ |$$ |  $$ |$$    $$/ $$ | $/  $$ |$$    $$/ /     $$/   $$  $$/ $$ | $$$ |$$    $$/   $$  $$/ $$    $$/ $$       |$$ | $$$ |$$    $$ |$$ | $$ | $$ |$$       |$$    $$ |
//  $$/   $$/  $$$$$$$/ $$/      $$/ $$/   $$/  $$$$$$/  $$/      $$/  $$$$$$/  $$$$$$$/     $$$$/  $$/   $$/  $$$$$$/     $$$$/  $$$$$$$/   $$$$$$$/ $$/   $$/  $$$$$$$/ $$/  $$/  $$/  $$$$$$$/  $$$$$$$/ 
//                                                                                                                                                                                                          
//                                                                                                                                                                                                          
//
//@version=5
indicator("Just Another RSI", shorttitle='jaRSI', overlay=false, max_lines_count=500, max_labels_count=500, max_boxes_count=500)

import HeWhoMustNotBeNamed/arrayutils/20 as pa

source = input.source(close, 'jaRSI Source')
rsiLength = input.int(11, 'jaRSI Length', step=5, minval=5)
useMedianGainLoss = input.bool(false, 'Use median gain/loss')
jaRSI(source, length, useMedianGainLoss=false, initialLength=100, maxLength=500)=>
    var sourceArray = array.new<float>(initialLength, 0)
    change = source - (array.size(sourceArray) > 0 ? array.get(sourceArray, 0) : source)
    pa.unshift(sourceArray, source, maxLength)
    
    var gainArray = array.new<float>(initialLength, 0)
    var lossArray = array.new<float>(initialLength, 0)
    if(change > 0)
        pa.unshift(gainArray, math.max(0, change), maxLength)
    if(change < 0)
        pa.unshift(lossArray, math.abs(math.min(0, change)), maxLength)
    
    shortGainArray = array.slice(gainArray, 0, length)
    shortLossArray = array.slice(lossArray, 0, length)
    averageGain = useMedianGainLoss?array.median(shortGainArray):array.sum(shortGainArray)
    averageLoss = useMedianGainLoss?array.median(shortLossArray):array.sum(shortLossArray)

    rs = averageGain/averageLoss
    rsi = 100 - (100/(1+rs))

max = hline(100, 'Max', color=color.silver, linewidth=1, linestyle=hline.style_dashed, editable=false)
bearish = hline(40, 'Bearish', color=color.silver, linewidth=1, linestyle=hline.style_dashed, editable=true)
bullish = hline(60, 'Bullish', color=color.silver, linewidth=1, linestyle=hline.style_dashed, editable=true)
min = hline(0, 'Min', color=color.silver, linewidth=1, linestyle=hline.style_dashed, editable=false)

fill(max, bullish, color.new(color.green, 80), 'Bullish Region', editable=true)
fill(min, bearish, color.new(color.red, 80), 'Bearish Region', editable=true)

jarsi = jaRSI(source, rsiLength, useMedianGainLoss)
plot(jarsi, 'jaRSI', color=color.purple, editable=true)
