RSI vs BITFINEX BTC Longs/Shorts Margin Ratio Percentage Rank
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © EltAlt

//@version=5

// -------------------------------------------------------------------------------------------------------------------
//
// Authors:  @EltAlt
// Revision: v1.03
// Date:     16-June-2022
//
// Description
// ===================================================================================================================
//
// This indicator should be used on a BTC chart. By default it plots the RSI of the current token with a color based
// on percentage rank the RSI of BITFINEX:BTCUSDLONGS divided by BITFINEX:BTCUSDSHORTS, with a plot of the moving
// average of the RSI. In the indicator options you can select to total any of of the availble BITFINEX LONG and SHORT
// tokens.
//
// The available ratio options are:
//     • BITFINEX:BTCUSDLONGS : BITFINEX:BTCUSDSHORTS
//     • BITFINEX:BTCUSTLONGS : BITFINEX:BTCUSTSHORTS
//     • BITFINEX:BTCEURLONGS : BITFINEX:BTCEURSHORTS
//     • BITFINEX:BTCEUTLONGS : BITFINEX:BTCEUTSHORTS
//     • BITFINEX:BTCJPYLONGS : BITFINEX:BTCJPYSHORTS
//     • BITFINEX:BTCGBPLONGS : BITFINEX:BTCGBPSHORTS
//
// The three plot options are:
//     • Colored RSI - RSI plotted with colors based on the Longs/Shorts ratio
//     • Background Color - White RSI plot with Longs/Shorts ratio as background color
//     • RSI + Ratio - White RSI with Longs/Shorts ratio plotted in color
//
// By default it also plots a short term moving average and it can also plot the raw ratio rather than the percentage
// rank if selected.
//
// Alerts can be triggered and or shown on the chart when the Ratio is Above / Below specified values, with the
// option to filter by the RSI being beyond the displayed upper and lower limits and or the RSI above / below its
// moving average.
//
// ===================================================================================================================
//
// I would gladly accept any suggestions to improve the script.
// If you encounter any problems please share them with me.
//
// Changlog
// ===================================================================================================================
//
// 1.00 • First public release
// 1.01 • Added transparency options for above / below MA
// 1.02 • Added options so that all of the BITFINEX:BTCxxxLONGS and BITFINEX:BTCxxxSHORTS pairs can be selected
//      • Added RBlG spectrum, I like Red Black Green spectrum as a background color
//      • Moved to a drop down list for plot style
// 1.03 • Aligned with 'RSI vs Longs/Shorts Margin Ratio Percentage Rank' v1.01
//      • Got rid of the average, not needed
//      • Added alerts
//      • Moved request.security to a function
//
//
// ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
//
//
// ============ 'RSI vs BITFINEX BTC Longs/Shorts Margin Ratio'

indicator('RSI vs BITFINEX BTC Longs/Shorts Margin Ratio',
          shorttitle='RSI vs Longs/Shorts',
          overlay = false, 
          timeframe='', 
          timeframe_gaps=true)


// ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
// ============ Inputs

rsioption    = 'Colored RSI'
bkgoption    = 'Background Color'
ratoption    = 'RSI + Ratio'
typetip      = 'The three plot options are:\nColored RSI - RSI plotted with colors based on the Longs/Shorts ratio\nBackground Color - White RSI plot with Longs/Shorts ratio as background color\nRSI + Ratio - White RSI with Longs/Shorts ratio plotted in color'

usd          = input.bool (true,  'USD', group = 'BITFINEX Source symbols: BTCxxxLONGS and BTCxxxSHORTS', inline = '1', tooltip = 'The more you select the slower the indicator will become.')
ust          = input.bool (false, 'UST', group = "BITFINEX Source symbols: BTCxxxLONGS and BTCxxxSHORTS", inline = '1')
eur          = input.bool (false, 'EUR', group = 'BITFINEX Source symbols: BTCxxxLONGS and BTCxxxSHORTS', inline = '1')
eut          = input.bool (false, 'EUT', group = 'BITFINEX Source symbols: BTCxxxLONGS and BTCxxxSHORTS', inline = '1')
jpy          = input.bool (false, 'JPY', group = 'BITFINEX Source symbols: BTCxxxLONGS and BTCxxxSHORTS', inline = '1')
gbp          = input.bool (false, 'GBP', group = 'BITFINEX Source symbols: BTCxxxLONGS and BTCxxxSHORTS', inline = '1')

plottype     = input.string (rsioption , 'Plot Style', options=[rsioption, bkgoption, ratoption], tooltip = typetip)
plotbktab    = input.int (defval = 60, maxval=100, minval=0, title = 'Transparency Above MA', inline='0')
plotbktbe    = input.int (defval = 75, maxval=100, minval=0, title = 'Below MA', inline='0')
usepctrank   = input.bool (true, 'Use the percentrank of the ratio?', inline='1')
pctlbk       = input.int  (500, title='     Lookback', inline='1')
plotrange    = input.string ('RGB Spectrum', 'Color Type', options=['RGB Spectrum', 'RBlG Spectrum', 'RB Spectrum', 'RG Spectrum', 'Solid Color'], inline='2')
plotcolor    = input.color  (#FFFF00, '        Solid Color', inline='2')
plothilow    = input.bool (true, 'Plot High/Low Lines', inline='2')

length       = input (14, 'Length', inline='1', group='RSI Settings')
rsiupper     = input (70, 'Upper',  inline='1', group='RSI Settings')
rsilower     = input (30, 'Lower',  inline='1', group='RSI Settings')

plotma       = input.bool   (true, 'Plot RSI MA', inline='1', group='RSI Moving Average Settings')
malength     = input.int    (5, 'Length', inline='1', group='RSI Moving Average Settings')
matype       = input.string ('EMA', 'Type', options=['SMA', 'EMA', 'VWMA'], inline='1', group='RSI Moving Average Settings')

alerts       = input.bool (true, 'Plot Visable Alerts', inline='1', group='Alerts')
a_rsibands   = input.bool (true, 'RSI Beyond Bands', inline='2', group='Alerts')
a_rsima      = input.bool (true, 'RSI MA Filter', inline='2', group='Alerts')
a_ratiobelow = input.int (5,  'Ratio Below', inline='3', group='Alerts')
a_ratioabove = input.int (95, 'Ratio Above', inline='3', group='Alerts')

// ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
// ============ Functions

f_color (_type, _solidcolor, _percent) =>
    _color = switch _type
        'RGB Spectrum' => _percent >= 50 ? color.from_gradient(_percent, 50, 100, #0AFF00, #FF2900): color.from_gradient(_percent, 0, 49, #0000FF, #0AFF00)
        'RBlG Spectrum' => _percent >= 50 ? color.from_gradient(_percent, 50, 100, #000000, #FF2900): color.from_gradient(_percent, 0, 49, #0AFF00, #000000)
        'RB Spectrum' => color.from_gradient(_percent, 0, 100, #0000FF, #FF2900)
        'RG Spectrum' => color.from_gradient(_percent, 0, 100, #00FF00, #FF0000)
        'Solid Color' => _solidcolor

f_ma (_type, _source, _length) => _type == 'VWMA' ? ta.vwma ( _source, _length ) : _type == 'EMA' ? ta.ema ( _source, _length ) : ta.sma ( _source, _length )

f_btfnx (_currency, _direction) => request.security (ticker.new ('BITFINEX', 'BTC' + _currency + _direction), timeframe.period, close)

// ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
// ============ Calculations

longs = 0.0
longs += usd ? f_btfnx ('USD', 'LONGS') : 0
longs += ust ? f_btfnx ('UST', 'LONGS') : 0
longs += eur ? f_btfnx ('EUR', 'LONGS') : 0
longs += eut ? f_btfnx ('EUT', 'LONGS') : 0
longs += jpy ? f_btfnx ('JPY', 'LONGS') : 0
longs += gbp ? f_btfnx ('GBP', 'LONGS') : 0

shorts = 0.0
shorts += usd ? f_btfnx ('USD', 'SHORTS') : 0
shorts += ust ? f_btfnx ('UST', 'SHORTS') : 0
shorts += eur ? f_btfnx ('EUR', 'SHORTS') : 0
shorts += eut ? f_btfnx ('EUT', 'SHORTS') : 0
shorts += jpy ? f_btfnx ('JPY', 'SHORTS') : 0
shorts += gbp ? f_btfnx ('GBP', 'SHORTS') : 0

plotratio   = plottype == ratoption
plotbkgrd   = plottype == bkgoption
rsilong     = ta.rsi (longs, length)
rsishort    = ta.rsi (shorts, length)
rsiclose    = ta.rsi (close, length)
rsiratio    = ta.rsi (longs / shorts, length)
rsima       = plotma ? f_ma (matype, rsiclose, malength) : na
pctrank     = usepctrank ? ta.percentrank (rsiratio, pctlbk) : na
ratioplot   = usepctrank ? pctrank : rsiratio
ratio_color = f_color (plotrange, plotcolor, ratioplot)
bottcolor   = plotrange == 'RG Spectrum' or plotrange == 'RBlG Spectrum' ? color.green : color.blue

// ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
// ============ Alerts

hghalert = (ratioplot > a_ratioabove)
           and (a_rsibands ? rsiclose > rsiupper : true)
		   and (a_rsima ? rsiclose < rsima : true)

lowalert = (ratioplot < a_ratiobelow)
           and (a_rsibands ? rsiclose < rsilower : true)
		   and (a_rsima ? rsiclose > rsima : true)

alertcondition (hghalert, title='RSI vs Longs/Shorts High Alert!', message='High Alert')
alertcondition (lowalert, title='RSI vs Longs/Shorts Low Alert!',  message='Low Alert')


// ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
// ============ Plots

plotshape (alerts ? hghalert : na, style=shape.triangledown, color=color.red,  location=location.top,    size=size.tiny, title='High Alert')
plotshape (alerts ? lowalert : na, style=shape.triangleup,   color=color.lime, location=location.bottom, size=size.tiny, title='Low Alert')

bgcolor (plotbkgrd ? color.new(ratio_color, rsiclose > rsima ? plotbktab : plotbktbe) : na)

p_bandTop = hline (plothilow ? 100 : na, "100", color.red, hline.style_solid)
p_bandBot = hline (plothilow ?   0 : na,   "0", bottcolor,  hline.style_solid)
p_bandUpp = hline(rsiupper,  "Upper Band", color.new(color.silver,50), hline.style_dashed)
p_bandMid = hline(50,  "50", color.new(color.silver,75), hline.style_dashed)
p_bandLow = hline(rsilower, "Lower Band", color.new(color.silver,50), hline.style_dashed)
fill(p_bandUpp, p_bandLow, color.new(color.silver,96), title = "Background")

plot(plotratio or plotbkgrd ? na : rsiclose, 'Ratio Color RSI', color=ratio_color, linewidth=2)

p_ratio = plot(plotratio ? ratioplot : na, 'Long / Short Ratio', color=ratio_color)
p_rsi = plot(plotratio or plotbkgrd ? rsiclose : na, 'RSI', color=color.white, linewidth=2)
fill(p_ratio, p_rsi, color=color.new(ratio_color, rsiclose < rsima ? plotbktbe : plotbktab), fillgaps=true) 

plot(plotma ? rsima : na, 'RSI MA', color=color.silver, linewidth=1)
