KINSKI USDT Market Cap Dominance
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © KINSKI

//@version=5
indicator('KINSKI USDT Market Cap Dominance', shorttitle='USDT Market Cap Dominance', precision=0, overlay=false)


//************  Colors
color colorDefault = #9900FF
color colorUptrend = #00FF11
color colorDowntrend = #FF0004

color valColorsUpTrendHistogram = #007007, color valColorsUpTrendStrongHistogram = #00FF11, color valColorsUpWeakHistogram = #007a08, color valColorsUpTrendStrongHintHistogram = #e8be00
color valColorsDownTrendHistogram = #8A0002, color valColorsDownTrendStrongHistogram = #FF0004, color valColorsDownTrendWeakHistogram = #750001

color valColorsNeutral = #4f4f4f, color valColorMA = #9900FF


//********** Functions
_funcLineStyle(_type) =>
    switch _type
        "Circles" => plot.style_circles
        "Stepline" => plot.style_stepline
        "Line With Breaks" => plot.style_linebr
        "Step Line With Diamonds" => plot.style_stepline_diamond
        =>
            plot.style_line

// Smoothed Moving Average (SMMA)
_funcSMMA(_src, _len) =>
    tmpSMA = ta.sma(_src, _len)
    tmpVal = 0.0
    na(tmpVal[1]) ? tmpSMA : (tmpVal[1] * (_len - 1) + _src) / _len

// Triple EMA (TEMA)
_funcTEMA(_src, _len) =>
    ema1 = ta.ema(_src, _len)
    ema2 = ta.ema(ema1, _len)
    ema3 = ta.ema(ema2, _len)
    3 * (ema1 - ema2) + ema3

// Double Expotential Moving Average (DEMA)
_funcDEMA(_src, _len) =>
    2 * ta.ema(_src, _len) - ta.ema(ta.ema(_src, _len), _len)

// Exponential Hull Moving Average (EHMA)
_funcEHMA(_src, _len) =>
    tmpVal = math.max(2, _len)
    ta.ema(2 * ta.ema(_src, tmpVal / 2) - ta.ema(_src, tmpVal), math.round(math.sqrt(tmpVal)))

// Kaufman's Adaptive Moving Average (KAMA)
_funcKAMA(_src, _len) =>
    tmpVal = 0.0
    sum_1 = math.sum(math.abs(_src - _src[1]), _len)
    sum_2 = math.sum(math.abs(_src - _src[1]), _len)
    nz(tmpVal[1]) + math.pow((sum_1 != 0 ? math.abs(_src - _src[_len]) / sum_2 : 0) * (0.666 - 0.0645) + 0.0645, 2) * (_src - nz(tmpVal[1]))

// Variable Index Dynamic Average (VIDYA)
_funcVIDYA(_src, _len) =>
    _diff = ta.change(_src)
    _uppperSum = math.sum(_diff > 0 ? math.abs(_diff) : 0, _len)
    _lowerSum = math.sum(_diff < 0 ? math.abs(_diff) : 0, _len)
    _chandeMomentumOscillator = (_uppperSum - _lowerSum) / (_uppperSum + _lowerSum)
    _factor = 2 / (_len + 1)
    tmpVal = 0.0
    _src * _factor * math.abs(_chandeMomentumOscillator) + nz(tmpVal[1]) * (1 - _factor * math.abs(_chandeMomentumOscillator))

// Coefficient of Variation Weighted Moving Average (COVWMA)
_funcCOVWMA(_src, _len) =>
    _coefficientOfVariation = ta.stdev(_src, _len) / ta.sma(_src, _len)
    _cw = _src * _coefficientOfVariation
    math.sum(_cw, _len) / math.sum(_coefficientOfVariation, _len)

// Fractal Adaptive Moving Average (FRAMA)
_funcFRAMA(_src, _len) =>
    _coefficient = -4.6
    _n3 = (ta.highest(high, _len) - ta.lowest(low, _len)) / _len
    _hd2 = ta.highest(high, _len / 2)
    _ld2 = ta.lowest(low, _len / 2)
    _n2 = (_hd2 - _ld2) / (_len / 2)
    _n1 = (_hd2[_len / 2] - _ld2[_len / 2]) / (_len / 2)
    _dim = _n1 > 0 and _n2 > 0 and _n3 > 0 ? (math.log(_n1 + _n2) - math.log(_n3)) / math.log(2) : 0
    _alpha = math.exp(_coefficient * (_dim - 1))
    _sc = _alpha < 0.01 ? 0.01 : _alpha > 1 ? 1 : _alpha
    ta.cum(1) <= 2 * _len ? _src : _src * _sc + nz(_src[1]) * (1 - _sc)

// Karobein
_funcKarobein(_src, _len) =>
    tmpMA = ta.ema(_src, _len)
    tmpUpper  = ta.ema(tmpMA < tmpMA[1] ? tmpMA/tmpMA[1] : 0, _len)
    tmpLower  = ta.ema(tmpMA > tmpMA[1] ? tmpMA/tmpMA[1] : 0, _len)
    tmpRescaleResult  = (tmpMA/tmpMA[1]) / (tmpMA/tmpMA[1] + tmpLower)
    (2*((tmpMA/tmpMA[1]) / (tmpMA/tmpMA[1] + tmpRescaleResult * tmpUpper)) - 1) * 100

// RSX based Noise Remover based Noise Remover
_funcRemoveNoise(_src, _len) =>
    f8 = 100 * _src
    f10 = nz(f8[1])
    v8 = f8 - f10

    f18 = 3 / (_len + 2)
    f20 = 1 - f18

    f28 = 0.0
    f28 := f20 * nz(f28[1]) + f18 * v8

    f30 = 0.0
    f30 := f18 * f28 + f20 * nz(f30[1])
    vC = f28 * 1.5 - f30 * 0.5

    f38 = 0.0
    f38 := f20 * nz(f38[1]) + f18 * vC

    f40 = 0.0
    f40 := f18 * f38 + f20 * nz(f40[1])
    v10 = f38 * 1.5 - f40 * 0.5

    f48 = 0.0
    f48 := f20 * nz(f48[1]) + f18 * v10

    f50 = 0.0
    f50 := f18 * f48 + f20 * nz(f50[1])
    v14 = f48 * 1.5 - f50 * 0.5

    f58 = 0.0
    f58 := f20 * nz(f58[1]) + f18 * math.abs(v8)

    f60 = 0.0
    f60 := f18 * f58 + f20 * nz(f60[1])
    v18 = f58 * 1.5 - f60 * 0.5

    f68 = 0.0
    f68 := f20 * nz(f68[1]) + f18 * v18

    f70 = 0.0
    f70 := f18 * f68 + f20 * nz(f70[1])
    v1C = f68 * 1.5 - f70 * 0.5

    f78 = 0.0
    f78 := f20 * nz(f78[1]) + f18 * v1C

    f80 = 0.0
    f80 := f18 * f78 + f20 * nz(f80[1])
    v20 = f78 * 1.5 - f80 * 0.5

    f88_ = 0.0
    f90_ = 0.0

    f88 = 0.0
    f90_ := nz(f90_[1]) == 0 ? 1 : nz(f88[1]) <= nz(f90_[1]) ? nz(f88[1]) + 1 : nz(f90_[1]) + 1
    f88 := nz(f90_[1]) == 0 and _len - 1 >= 5 ? _len - 1 : 5

    f0 = f88 >= f90_ and f8 != f10 ? 1 : 0
    f90 = f88 == f90_ and f0 == 0 ? 0 : f90_

    v4_ = f88 < f90 and v20 > 0 ? (v14 / v20 + 1) * 50 : 50
    v4_ > 100 ? 100 : v4_ < 0 ? 0 : v4_

// calculate the moving average with the transferred settings
_funcCalcMA(_type, _src, _len) =>
    float ma = switch _type
        "COVWMA" => _funcCOVWMA(_src, _len)
        "DEMA" => _funcDEMA(_src, _len)
        "EMA" => ta.ema(_src, _len)
        "EHMA" => _funcEHMA(_src, _len)
        "HMA" => ta.hma(_src, _len)
        "KAMA" => _funcKAMA(_src, _len)
        "RMA" => ta.rma(_src, _len)
        "RSX based Noise Remover" => _funcRemoveNoise(_src, _len)
        "SMA" => ta.sma(_src, _len)
        "SMMA" => _funcSMMA(_src, _len)
        "TEMA" => _funcTEMA(_src, _len)
        "FRAMA" => _funcFRAMA(_src, _len)
        "VWMA" => ta.vwma(_src, _len)
        "VIDYA" => _funcVIDYA(_src, _len)
        "WMA" => ta.wma(_src, _len)
        "Karobein" => _funcKarobein(_src, _len)
        =>
            float(na)

_funcCalcHistogramColor(_val) =>
    conditionColors_1 = _val > nz(_val[1]) ? valColorsUpTrendStrongHistogram : valColorsUpTrendHistogram
    conditionColors_2 = _val < nz(_val[1]) ? valColorsDownTrendStrongHistogram : valColorsDownTrendHistogram
    (_val == -0.00 or _val == 0.00) ? valColorsNeutral : _val > 0 ? conditionColors_1 : conditionColors_2

_funcHistogram(_type, _src, _len) =>
    tmpHistogramSignal = _funcCalcMA(_type, _src, _len)
    tmpHistogram = _src - tmpHistogramSignal
    tmpAdvancedRatingColor = _funcCalcHistogramColor(tmpHistogram)
    [tmpHistogram, tmpAdvancedRatingColor]


//********** Inputs
bool inputShowAsHistogram = input.bool(title='Show as Histogram', group='Settings', defval=false)
string inputUsdtVariant = input.string(title='Variant', group='Settings', defval='CRYPTOCAP:USDT.D', options=['CRYPTOCAP:USDT', 'CRYPTOCAP:USDT.D', 'CRYPTOCAP:OTHERS.D'])
inputTimeframe = input.timeframe("", "Resolution:", group="Settings")
inputSource = input(title='Source', group='Settings', defval=close)

string inputMaType = input.string(title='Smoothing: Type', group='Smoothing', defval='WMA', options=['DISABLED', 'COVWMA', 'DEMA', 'EMA', 'EHMA', 'FRAMA', 'HMA', 'KAMA', 'Karobein', 'RMA', 'RSX based Noise Remover', 'SMA', 'SMMA', 'TEMA', 'VIDYA', 'VWMA', 'WMA'])
int inputMaLength = input.int(title='Smoothing: Period', group='Smoothing', minval=1, maxval=1000, defval=5)

// Histogram
string inputHistogramType = input.string(title='Smoothing:', group='Histogram', defval='WMA', options=['DISABLED', 'COVWMA', 'DEMA', 'EMA', 'EHMA', 'FRAMA', 'HMA', 'KAMA', 'Karobein', 'RMA', 'RSX based Noise Remover', 'SMA', 'SMMA', 'TEMA', 'VIDYA', 'VWMA', 'WMA'])
int inputHistogramLength = input.int(title='Period:', group='Histogram', defval=4, maxval=100)

// Styles
bool inputShowUpDownMovements = input.bool(title='Show Up/Down Movemnts', group='Style', defval=false)
color inputColorDefault = input(title='Color: Default', group='Style', defval=colorDefault)
color inputColorUptrend = input(title='Color: Uptrend', group='Style', defval=colorUptrend)
color inputColorDowntrend = input(title='Color: Downtrend', group='Style', defval=colorDowntrend)
int inputLineWidth = input.int(title='Size', group='Style', minval=1, maxval=4, defval=2, step=1)
int inputLineTransparency = input.int(title='Transparency', group='Style', minval=0, maxval=100, defval=0, step=4)
string inputLineStyle = input.string(title='Type', group='Style', defval='Line', options=['Line', 'Stepline', 'Step Line With Diamonds', 'Circles'])



//********** Calculation
float valUsdtMarketCap = request.security(inputUsdtVariant, inputTimeframe, inputSource)
float valUsdtMarketCapFinal = inputMaType != 'DISABLED' ? _funcCalcMA(inputMaType, valUsdtMarketCap, inputMaLength) : valUsdtMarketCap
bool valIsUptrend = valUsdtMarketCapFinal > nz(valUsdtMarketCapFinal[1])
color valFinalColor = inputShowUpDownMovements ? (valIsUptrend ? inputColorUptrend : inputColorDowntrend) : inputColorDefault

[valPlotHistogram, valPlotHistogramColor] = _funcHistogram(inputHistogramType, valUsdtMarketCapFinal, inputHistogramLength)


//************  Plotting
plot(inputShowAsHistogram ? na : valUsdtMarketCapFinal-valPlotHistogram, title='USDT', color=color.new(valFinalColor, inputLineTransparency), linewidth=inputLineWidth, style=_funcLineStyle(inputLineStyle))
plot(inputShowAsHistogram ? valPlotHistogram : na, title='Histogram', style=plot.style_columns, color=color.new(valPlotHistogramColor, 0), linewidth=2)
