Stablecoin Dominance (USDT, USDC & BUSD) Credits to lysergik
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © lysergik

//@version=5
indicator(title="Aggregated Stablecoin Dominance",
     shorttitle="AggrStableDom", format=format.percent, precision=3)

// data sources \\
usdt = request.security('USDT.D', timeframe.period, close)
usdc = request.security('USDC.D', timeframe.period, close)
busd = request.security('(BUSD_MARKETCAP*100)/CRYPTOCAP:TOTAL', timeframe.period, close)

usdt_o = request.security('USDT.D', timeframe.period, open)
usdc_o = request.security('USDC.D', timeframe.period, open)
busd_o = request.security('(BUSD_MARKETCAP*100)/CRYPTOCAP:TOTAL', timeframe.period, open)

usdt_h = request.security('USDT.D', timeframe.period, high)
usdc_h = request.security('USDC.D', timeframe.period, high)
busd_h = request.security('(BUSD_MARKETCAP*100)/CRYPTOCAP:TOTAL', timeframe.period, high)

usdt_l = request.security('USDT.D', timeframe.period, low)
usdc_l = request.security('USDC.D', timeframe.period, low)
busd_l = request.security('(BUSD_MARKETCAP*100)/CRYPTOCAP:TOTAL', timeframe.period, low)

// inputs \\
use_candles = input.bool(false, 'Use Candles Instead', group='Total Dominance')
heikin = input.bool(true, 'Heikin Candles', group='Total Dominance')

use_fma = input.bool(true, 'Show Fast Moving Average', group='Moving Averages')
use_sma = input.bool(true, 'Show Slow Moving Average', group='Moving Averages')
predict_ema = input.bool(true, 'Show MA Prediction', group='Moving Averages')

f_length = input.int(21, 'Fast MA Length', minval=2, group='Moving Averages')
s_length = input.int(50, 'Slow MA Length', minval=2, group='Moving Averages')
ema = input.bool(true, 'Use EMA instead of SMA', group='Moving Averages')

col = input.bool(true, 'Color MAs to Reflect the Trend', group='Color')
colInvert = input.bool(false, 'Invert MA Coloring', group='Color')

bb = input.bool(false, 'Use Bollinger Bands', group='Bollinger Bands')
bb_sig = input.bool(false, 'Show Bollinger Bands Multi-Signals (beta)', group='Bollinger Bands')
length = input.int(21, minval=1, group='Bollinger Bands')
mult = input.float(2.618, minval=0.001, maxval=50, group='Bollinger Bands')

// math \\
totalDom = usdt + usdc + busd
totalDom_o = usdt_o + usdc_o + busd_o
totalDom_h = usdt_h + usdc_h + busd_h
totalDom_l = usdt_l + usdc_l + busd_l

// === CANDLES ===
src(_src)  => 
    Close  = not heikin ? totalDom : math.avg(totalDom_o, totalDom_h, totalDom_l, totalDom)
    Open   = float(na)
    Open  := not heikin ? totalDom_o  : na(Open[1]) ? (totalDom_o + totalDom) / 2 : (nz(Open[1]) + nz(Close[1])) / 2
    High   = not heikin ? totalDom_h  : math.max(totalDom_h, math.max(Open, Close))
    Low    = not heikin ? totalDom_l   : math.min(totalDom_l,  math.min(Open, Close))
    HL2    = not heikin ? math.avg(totalDom_l, totalDom_h)   : math.avg(High, Low) 
    HLC3   = not heikin ? math.avg(totalDom_l, totalDom_h, totalDom)  : math.avg(High, Low, Close) 
    OHLC4  = not heikin ? math.avg(totalDom_o, totalDom_h, totalDom_l, totalDom) : math.avg(Open, High, Low, Close)
    Price  = _src == 'close' ? Close : _src == 'open' ? Open : _src == 'high' ? High : _src == 'low' ? Low : _src == 'hl2' ? HL2 : _src == 'hlc3' ? HLC3 : OHLC4  
    Source = math.round(Price / syminfo.mintick) * syminfo.mintick  // PineCoders method for aligning Pine prices with chart instrument prices

src = math.avg(totalDom_h,totalDom_l,totalDom)
basis = ta.vwma(src, length)
dev = mult * ta.stdev(src, length)
upper_1= basis + (0.236*dev)
upper_2= basis + (0.382*dev)
upper_3= basis + (0.5*dev)
upper_4= basis + (0.618*dev)
upper_5= basis + (0.764*dev)
upper_6= basis + (1*dev)
lower_1= basis - (0.236*dev)
lower_2= basis - (0.382*dev)
lower_3= basis - (0.5*dev)
lower_4= basis - (0.618*dev)
lower_5= basis - (0.764*dev)
lower_6= basis - (1*dev)

fMA = 0.00
sMA = 0.00
string predict_type = "EMA"

if ema
    fMA := ta.ema(totalDom, f_length)
    sMA := ta.ema(totalDom, s_length)
    predict_type := "EMA"
else
    fMA := ta.sma(totalDom, f_length)
    sMA := ta.sma(totalDom, s_length)
    predict_type := "SMA"

ma(_type, _src, _len) =>
    if _type == "EMA"
        ta.ema(_src, _len)
    else if _type == "SMA"
        ta.sma(_src, _len)

ma_prediction(_type, _src, _period, _offset) => (ma(_type, _src, _period - _offset) * (_period - _offset) + _src * _offset) / _period

longemapredictor_1 = ma_prediction(predict_type, totalDom, s_length, 1)
longemapredictor_2 = ma_prediction(predict_type, totalDom, s_length, 2)
longemapredictor_3 = ma_prediction(predict_type, totalDom, s_length, 3)
longemapredictor_4 = ma_prediction(predict_type, totalDom, s_length, 4)
longemapredictor_5 = ma_prediction(predict_type, totalDom, s_length, 5)

shortemapredictor_1 = ma_prediction(predict_type, totalDom, f_length, 1)
shortemapredictor_2 = ma_prediction(predict_type, totalDom, f_length, 2)
shortemapredictor_3 = ma_prediction(predict_type, totalDom, f_length, 3)
shortemapredictor_4 = ma_prediction(predict_type, totalDom, f_length, 4)
shortemapredictor_5 = ma_prediction(predict_type, totalDom, f_length, 5)

// logic \\
isBullish = totalDom <= fMA ? true : false
slowIsBelow = sMA < fMA ? true : false

isBelow(_v2, _v1) =>
    out = false
    if _v1 > _v2
        out := true

BB_bullCross = (ta.crossunder(src,upper_6)) or (ta.crossover(src, lower_4) or ta.crossunder(src, basis)) ? true : false
BB_bearCross = (ta.crossover(src,lower_6)) or (ta.crossunder(src, upper_4) or ta.crossover(src, basis)) ? true : false

// front-end \\
f_plot = plot(use_fma ? fMA : na, 'Fast Moving Average', color=col ? color.black : color.blue, linewidth=2)
s_plot = plot(use_sma ? sMA : na, 'Slow Moving Average', color=color.white, linewidth=2)

dom_plot = plot(totalDom, 'Combined Dominance', color=use_candles ? na : color.white, trackprice=true)

barColor   = not use_candles ? na : src('close') >= src('open') ? color.purple : color.teal
plotcandle(src('open'), src('high'), src('low'), src('close'),
     'Candles', color=barColor, wickcolor=not use_candles ? na : color.new(color.white, 50), bordercolor=na)

color fastCol =
     not colInvert ? (isBullish and col ? color.rgb(0,255,0,70) : not isBullish and col ? color.rgb(255,0,0,70) : na) :
     (isBullish and col ? color.rgb(255,0,0,70) : not isBullish and col ? color.rgb(0,255,0,70) : na)
     
color slowCol =
     not colInvert ? (slowIsBelow and col ? color.new(color.purple,75) : not slowIsBelow and col ? color.new(color.aqua,75) : na) :
     (slowIsBelow and col ? color.new(color.aqua,75) : not slowIsBelow and col ? color.new(color.purple,75) : na)

fill(dom_plot, f_plot, color=fastCol)
fill(f_plot, s_plot, color=slowCol)

plot(usdt, 'USDT Dominance', color=color.aqua, display=display.none)
plot(usdc, 'USDC Dominance', color=color.purple, display=display.none)
plot(busd, 'BUSD Dominance', color=color.yellow, display=display.none)

plot(bb ? basis : na, color=color.white, linewidth=2, style=plot.style_stepline)
p1 = plot(bb ? upper_1 : na, color=color.white, linewidth=1, title="0.236", display=display.none)
p2 = plot(bb ? upper_2 : na, color=color.aqua, linewidth=1, title="0.382", display=display.none)
p3 = plot(bb ? upper_3 : na, color=color.white, linewidth=1, title="0.5", display=display.none)
p4 = plot(bb ? upper_4 : na, color=color.orange, linewidth=1, title="0.618")
p5 = plot(bb ? upper_5 : na, color=color.white, linewidth=1, title="0.764", display=display.none)
p6 = plot(bb ? upper_6 : na, color=color.gray, linewidth=2, title="1")
p13 = plot(bb ? lower_1 : na, color=color.white, linewidth=1, title="0.236", display=display.none)
p14 = plot(bb ? lower_2 : na, color=color.aqua, linewidth=1, title="0.382", display=display.none)
p15 = plot(bb ? lower_3 : na, color=color.white, linewidth=1, title="0.5", display=display.none)
p16 = plot(bb ? lower_4 : na, color=color.orange, linewidth=1, title="0.618")
p17 = plot(bb ? lower_5 : na, color=color.white, linewidth=1, title="0.764", display=display.none)
p18 = plot(bb ? lower_6 : na, color=color.gray, linewidth=2, title="1")

plot(predict_ema and use_sma ? longemapredictor_1 : na, color=isBelow(shortemapredictor_1, longemapredictor_1) ? color.white : color.gray,
     linewidth=2, style=plot.style_cross, offset=1, show_last=1, editable=false)
plot(predict_ema and use_sma ? longemapredictor_2 : na, color=isBelow(shortemapredictor_2, longemapredictor_2) ? color.white : color.gray,
     linewidth=2, style=plot.style_cross, offset=2, show_last=1, editable=false)
plot(predict_ema and use_sma ? longemapredictor_3 : na, color=isBelow(shortemapredictor_3, longemapredictor_3) ? color.white : color.gray,
     linewidth=2, style=plot.style_cross, offset=3, show_last=1, editable=false)
plot(predict_ema and use_sma ? longemapredictor_4 : na, color=isBelow(shortemapredictor_4, longemapredictor_4) ? color.white : color.gray,
     linewidth=2, style=plot.style_cross, offset=4, show_last=1, editable=false)
plot(predict_ema and use_sma ? longemapredictor_5 : na, color=isBelow(shortemapredictor_5, longemapredictor_5) ? color.white : color.gray,
     linewidth=2, style=plot.style_cross, offset=5, show_last=1, editable=false)

plot(predict_ema and use_fma ? shortemapredictor_1 : na, color=isBelow(shortemapredictor_1, longemapredictor_1) ? color.aqua : color.purple,
     linewidth=2, style=plot.style_cross, offset=1, show_last=1, editable=false)
plot(predict_ema and use_fma ? shortemapredictor_2 : na, color=isBelow(shortemapredictor_2, longemapredictor_2) ? color.aqua : color.purple,
     linewidth=2, style=plot.style_cross, offset=2, show_last=1, editable=false)
plot(predict_ema and use_fma ? shortemapredictor_3 : na, color=isBelow(shortemapredictor_3, longemapredictor_3) ? color.aqua : color.purple,
     linewidth=2, style=plot.style_cross, offset=3, show_last=1, editable=false)
plot(predict_ema and use_fma ? shortemapredictor_4 : na, color=isBelow(shortemapredictor_4, longemapredictor_4) ? color.aqua : color.purple,
     linewidth=2, style=plot.style_cross, offset=4, show_last=1, editable=false)
plot(predict_ema and use_fma ? shortemapredictor_5 : na, color=isBelow(shortemapredictor_5, longemapredictor_5) ? color.aqua : color.purple,
     linewidth=2, style=plot.style_cross, offset=5, show_last=1, editable=false)

var line realLine = na
varip lineVis = false
if use_candles and
     ((lineVis == false and not barstate.isconfirmed) or
     (barstate.isrealtime and barstate.islast and not barstate.isconfirmed))
    
    line.delete(id=realLine)
    realLine := line.new(x1=bar_index[1], y1=totalDom, x2=bar_index, y2=totalDom, width=1, extend=extend.both)
    line.set_color(id=realLine, color=totalDom > totalDom_o ? color.purple : totalDom < totalDom_o ? color.teal : color.white)
    line.set_style(id=realLine, style=line.style_dashed)
    
if barstate.isconfirmed
    line.delete(id=realLine)
    lineVis := false
    
// Table
var table TA_Display = table.new(position.bottom_right, 14, 4)

if barstate.islast
    table.cell(TA_Display, 0, 0, 'TOTAL', text_color=color.white, text_size=size.auto, bgcolor=color.black)
    table.cell(TA_Display, 1, 0, str.format('{0}%', totalDom), text_color=ta.change(totalDom) > 0 ? color.red : color.green, text_size=size.auto, bgcolor=color.black)
    table.cell(TA_Display, 0, 1, 'USDT', text_color=color.white, text_size=size.auto, bgcolor=color.black)
    table.cell(TA_Display, 1, 1, str.format('{0}%', usdt), text_color=ta.change(usdt) > 0 ? color.red : color.green, text_size=size.auto, bgcolor=color.black)
    table.cell(TA_Display, 0, 2, 'USDC', text_color=color.white, text_size=size.auto, bgcolor=color.black)
    table.cell(TA_Display, 1, 2, str.format('{0}%', usdc), text_color=ta.change(usdc) > 0 ? color.red : color.green, text_size=size.auto, bgcolor=color.black)
    table.cell(TA_Display, 0, 3, 'BUSD', text_color=color.white, text_size=size.auto, bgcolor=color.black)
    table.cell(TA_Display, 1, 3, str.format('{0}%', busd), text_color=ta.change(busd) > 0 ? color.red : color.green, text_size=size.auto, bgcolor=color.black)

// Signals
plotshape(BB_bullCross and bb_sig ? upper_6 : na, 'BB Bull Cross', style=shape.xcross,
     color=color.lime, location=location.absolute, size=size.tiny)
     
plotshape(BB_bearCross and bb_sig ? lower_6 : na, 'BB Bear Cross', style=shape.xcross,
     color=color.red, location=location.absolute, size=size.tiny)