RSI Crayons
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//@version=5
indicator(title='RSI Crayons', 
     shorttitle='RSI Crayons', 
     overlay=true, timeframe="", timeframe_gaps=true)

//INPUT
almaoffset = input.float(title='ALMA Offset', defval=0.85, step=0.01, group='Special MA Settings', inline='03')
almasigma = input.float(title='Sigma', defval=6, group='Special MA Settings', inline='03')
a1 = input.float(title='Tillson T3 Volume Factor', defval=0.7, group='Special MA Settings', inline='5', step=0.001)

f_t3(_source, _length, _a1) =>
    _output = (-_a1 * _a1 * _a1) * (ta.ema(ta.ema(ta.ema(ta.ema(ta.ema(ta.ema(_source, _length), _length), _length), _length), _length), _length)) + (3 * _a1 * _a1 + 3 * _a1 * _a1 * _a1) * (ta.ema(ta.ema(ta.ema(ta.ema(ta.ema(_source, _length), _length), _length), _length), _length)) + (-6 * _a1 * _a1 - 3 * _a1 - 3 * _a1 * _a1 * _a1) * (ta.ema(ta.ema(ta.ema(ta.ema(_source, _length), _length), _length), _length)) + (1 + 3 * _a1 + _a1 * _a1 * _a1 + 3 * _a1 * _a1) * (ta.ema(ta.ema(ta.ema(_source, _length), _length), _length))
    _output

MA(source, length, type) =>
     type == 'SMA' ? ta.sma(source, length) : 
     type == 'EMA' ? ta.ema(source, length) : 
     type == 'SMMA (RMA)' ? ta.rma(source, length) : 
     type == 'WMA' ? ta.wma(source, length) : 
     type == 'VWMA' ? ta.vwma(source, length) : 
     type == 'ALMA' ? ta.alma(source, length, almaoffset, almasigma) : 
     type == 'Tillson T3' ? f_t3(source, length, a1) : na

//MOVING AVERAGE FUNCTION  
MA1_type = input.string('SMMA (RMA)', '', inline='FAST MA', options=['SMA', 'EMA', 'SMMA (RMA)', 'WMA', 'VWMA', 'ALMA', 'Tillson T3'], group='Moving Average          Source          Length')
MA1_Source = input.source(close, '', inline='FAST MA', group='Moving Average          Source          Length')
MA1_length = input.int(14, '', inline='FAST MA', minval=1, group='Moving Average          Source          Length')
rsima = MA(MA1_Source, MA1_length, MA1_type)

//COLORS
dump = input.int(30, minval=1, maxval=49, title='RSI => Oversold Threshold', group='Moving Average          Source          Length', inline='15')
backoversold = input.color(color.new(color.aqua, 90), 'Fill', group='Moving Average          Source          Length', inline='15')
fomo = input.int(70, minval=51, title='RSI Overheated Threshold', group='Moving Average          Source          Length', inline='16')
backoverheated = input.color(color.new(color.purple, 90), 'Fill', group='Moving Average          Source          Length', inline='16')
colorback = input.bool(defval=true, title='Fill Background When Overheated/Oversold?', group='Moving Average          Source          Length', inline='17')
plotbasis = input.bool(defval=false, title='Plot Basis?', group='Moving Average          Source          Length', inline='27')
colorbasis = input.bool(defval=false, title='Color Basis With Trend?', group='Moving Average          Source          Length', inline='27')
basisreg = input.color(color.blue, '', group='Moving Average          Source          Length', inline='27')

//CALCS
up = MA(math.max(ta.change(MA1_Source), 0), MA1_length, MA1_type)
down = MA(-math.min(ta.change(MA1_Source), 0), MA1_length, MA1_type)
rsival = down == 0 ? 100 : up == 0 ? 0 : 100 - 100 / (1 + up / down)
overheated = rsival >= fomo and close > open
oversold = rsival <= dump and close < open

var grad = array.new_color(na)
if barstate.isfirst
    array.push(grad, #ffffff)
    array.push(grad, #ff00ff)
    array.push(grad, #ff00e8)
    array.push(grad, #ff00d2)
    array.push(grad, #ff00bd)
    array.push(grad, #ff00aa)
    array.push(grad, #ff0097)
    array.push(grad, #ff0086)
    array.push(grad, #ff2277)
    array.push(grad, #ff3669)
    array.push(grad, #ff455d)
    array.push(grad, #ff5252)
    array.push(grad, #ff594c)
    array.push(grad, #ff6146)
    array.push(grad, #ff6940)
    array.push(grad, #ff703a)
    array.push(grad, #ff7833)
    array.push(grad, #ff802c)
    array.push(grad, #ff8824)
    array.push(grad, #ff901b)
    array.push(grad, #ff9810)
    array.push(grad, #ffa000)
    array.push(grad, #ffb300)
    array.push(grad, #ffc500)
    array.push(grad, #ffd800)
    array.push(grad, #ffec00)
    array.push(grad, #ffff00)
    array.push(grad, #e3ff00)
    array.push(grad, #c3ff00)
    array.push(grad, #9eff00)
    array.push(grad, #6fff00)
    array.push(grad, #00ff00)
    array.push(grad, #00f83c)
    array.push(grad, #00f057)
    array.push(grad, #00e86a)
    array.push(grad, #00df79)
    array.push(grad, #00d686)
    array.push(grad, #00cd8f)
    array.push(grad, #00c496)
    array.push(grad, #00ba9a)
    array.push(grad, #00b09b)
    array.push(grad, #26a69a)
    array.push(grad, #00a5a6)
    array.push(grad, #00a3b4)
    array.push(grad, #00a1c4)
    array.push(grad, #009dd4)
    array.push(grad, #0099e3)
    array.push(grad, #0094f1)
    array.push(grad, #008cfa)
    array.push(grad, #0083ff)
    array.push(grad, #0077ff)

rsivalfinal = math.floor(rsival / 2)

//color logic fix
candleup = close > open
candledn = open > close
colorup = math.round(math.avg(50,rsivalfinal))
colordn = math.round(math.avg(0,rsivalfinal))

//color adjustment
adjustedcolor = if candleup
    array.get(grad, colorup)
else
    array.get(grad, colordn)

barcolor(color.new(adjustedcolor, 100 - math.floor(rsival)), title='RSI Crayons')

//EXTRA BACKGROUND HIGHLIGHTING
iff_8 = oversold ? backoversold : na
iff_9 = overheated ? backoverheated : iff_8
bgcolor(colorback == false ? na : iff_9)

basecolor = colorbasis ? array.get(grad, rsivalfinal) : basisreg
p0 = plot(plotbasis ? rsima : na, title='MA Line', color=basecolor, linewidth=4)

//ALERTS
alertcondition(overheated != 0, 'RSI Above Overheated Threshold Value', 'RSI Above Overheated Threshold Value')
alertcondition(oversold != 0, 'RSI Below Oversold Threshold Value', 'RSI Below Oversold Threshold Value')