EMA Power Ranking [wbburgin]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © wbburgin

//@version=5
indicator("EMA Power Ranking [wbburgin]",overlay = true,max_bars_back=5000)

maLength = input.int(100,"MA LENGTH",group="Moving Averages")
format = input.string("Pure EMA",options=["Pure EMA","RMA","Volatility-Weighted EMA","Volume-Weighted EMA","Cumulative Volatility-Weighted EMA","Inverse Volatility-Weighted MA","TRMA"],title="MA Type",group="Moving Averages")
showMAs = input.bool(false,"Show MA's",group="Moving Averages")
screenlength = input.int(0,"Screen Length",minval=0,maxval=2,group="Precision")
lookBack = input.int(100,"Volatility Period (in bars)",group="Config",tooltip="Only necessary for volatility-weighted MAs")

//Functions
calc_elma(float priceType,int length,float weightType) =>
    sum = math.sum(weightType,length)
    data = 0.0
    data := (nz(data[1]) * (sum - weightType)/sum) + (weightType*priceType/sum)
    data
    //The Elastic Moving Average (ELMA) calculates the continuous weighted average by weightType. Inspired by
    //LazyBear's 'Elastic Volume Moving Average' indicator and generalized for any weight type.

cumVolatility() =>
    currentIndex = switch
        close>=open and open==low => (close-open)-(high-close)
        close>=open and open>=low => (close-open)-(high-close)+(open-low)
        close<=open and open==high => (close-open)+(close-low)
        close<=open and open<=high => (close-open)+(close-low)-(high-open)
    cIndex = ta.cum(currentIndex)
    //The cumulative volatility function uses a body-wick analysis to determine resistance and indexes this resistance.

volatility(float source,int length) =>
    2*(ta.highest(source,length)-ta.lowest(source,length))/(ta.highest(source,length)+ta.lowest(source,length))
    //The volatility function uses my personal definition of volatility - the relationship between the median and the
    //average - to identify a correlative coefficient. Data analysis confirms a 1:1 correlation with the "Beta"
    //statistic in traditional wealth markets.

// Pure EMA's
ema1 = ta.ema(close,maLength)
ema2 = ta.ema(close,maLength*2)
ema3 = ta.ema(close,maLength*3)
ema4 = ta.ema(close,maLength*4)
ema5 = ta.ema(close,maLength*5)

//RMA
rma1= ta.rma(close,maLength)
rma2= ta.rma(close,maLength*2)
rma3= ta.rma(close,maLength*3)
rma4= ta.rma(close,maLength*4)
rma5= ta.rma(close,maLength*5)

//VWEMA's
volatility = volatility(close,lookBack)
vwema1 = calc_elma(close, maLength,volatility)
vwema2 = calc_elma(close, maLength*2,volatility)
vwema3 = calc_elma(close, maLength*3,volatility)
vwema4 = calc_elma(close, maLength*4,volatility)
vwema5 = calc_elma(close, maLength*5,volatility)

//Volume-Weighted EMA's
vw1 = calc_elma(close,maLength,volume)
vw2 = calc_elma(close,maLength*2,volume)
vw3 = calc_elma(close,maLength*3,volume)
vw4 = calc_elma(close,maLength*4,volume)
vw5 = calc_elma(close,maLength*5,volume)

//Cumulative Volatility-Weighted EMA's
cumVol = cumVolatility()
c1 = calc_elma(close,maLength,cumVol)
c2 = calc_elma(close,maLength*2,cumVol)
c3 = calc_elma(close,maLength*3,cumVol)
c4 = calc_elma(close,maLength*4,cumVol)
c5 = calc_elma(close,maLength*5,cumVol)

//Inverse Volatility-Weighted EMA
inverseVolatility = 1/volatility(close,lookBack)
iv1 = calc_elma(close,maLength,inverseVolatility)
iv2 = calc_elma(close,maLength*2,inverseVolatility)
iv3 = calc_elma(close,maLength*3,inverseVolatility)
iv4 = calc_elma(close,maLength*4,inverseVolatility)
iv5 = calc_elma(close,maLength*5,inverseVolatility)

//Assignment
ema100 = switch
    format=="Pure EMA"=>ema1
    format=="RMA"=>rma1
    format=="Volatility-Weighted EMA"=>vwema1
    format=="Volume-Weighted EMA"=>vw1
    format=="Cumulative Volatility-Weighted EMA"=>c1
    format=="Inverse Volatility-Weighted MA"=>iv1
ema200 = switch
    format=="Pure EMA"=>ema2
    format=="RMA"=>rma2
    format=="Volatility-Weighted EMA"=>vwema2
    format=="Volume-Weighted EMA"=>vw2
    format=="Cumulative Volatility-Weighted EMA"=>c2
    format=="Inverse Volatility-Weighted MA"=>iv2
ema300 = switch
    format=="Pure EMA"=>ema3
    format=="RMA"=>rma3
    format=="Volatility-Weighted EMA"=>vwema3
    format=="Volume-Weighted EMA"=>vw3
    format=="Cumulative Volatility-Weighted EMA"=>c3
    format=="Inverse Volatility-Weighted MA"=>iv3
ema400 = switch
    format=="Pure EMA"=>ema4
    format=="RMA"=>rma4
    format=="Volatility-Weighted EMA"=>vwema4
    format=="Volume-Weighted EMA"=>vw4
    format=="Cumulative Volatility-Weighted EMA"=>c4
    format=="Inverse Volatility-Weighted MA"=>iv4
ema500 = switch
    format=="Pure EMA"=>ema5
    format=="RMA"=>rma5
    format=="Volatility-Weighted EMA"=>vwema5
    format=="Volume-Weighted EMA"=>vw5
    format=="Cumulative Volatility-Weighted EMA"=>c5
    format=="Inverse Volatility-Weighted MA"=>iv5

//Calculation
emadif0= ema100-ema200
emadif1= ema200-ema300
emadif2= ema300-ema400
emadif3= ema400-ema500

rising0 = emadif0>emadif0[1]
rising1 = emadif1>emadif1[1]
rising2 = emadif2>emadif2[1]
rising3 = emadif3>emadif3[1]

over0 = ema100>ema200
over1 = ema200>ema300
over2 = ema300>ema400
over3 = ema400>ema500

//States
state0 = switch
    rising0==true and over0==true => "up0"
    rising0==false and over0==false => "dn0"
    => "osc0"
state1 = switch
    rising1==true and over1==true => "up1"
    rising1==false and over1==false => "dn1"
    => "osc1"
state2 = switch
    rising2==true and over2==true => "up2"
    rising2==false and over2==false => "dn2"
    => "osc2"
state3 = switch
    rising3==true and over3==true => "up3"
    rising3==false and over3==false => "dn3"
    => "osc3"

//Buy and Sell Conditions
condition = switch //Normal
    (state0[1] == "dn0")and(state1[1] == "dn1")and(state0!="dn0")=>"buy"
    (state0[1] == "up0")and(state1[1] == "up1")and(state0!="up0")=>"sell"

condition_1 = switch //dx
    (state0[1] == "dn0")and(state1[1] == "dn1")and(state2[1] == "dn2")and(state0!="dn0")=>"buy"
    (state0[1] == "up0")and(state1[1] == "up1")and(state2[1] == "up2")and(state0!="up0")=>"sell"

condition_2 = switch //d2x
    (state0[1] == "dn0")and(state1[1] == "dn1")and(state2[1] == "dn2")and(state3[1] == "dn3")and(state0!="dn0")=>"buy"
    (state0[1] == "up0")and(state1[1] == "up1")and(state2[1] == "up2")and(state3[1] == "up3")and(state0!="up0")=>"sell"

//Assigning Signals
bullSignal = switch
    screenlength==0 => condition=="buy"
    screenlength==1 => condition_1=="buy"
    screenlength==2 => condition_2=="buy"

bearSignal = switch
    screenlength==0 => condition=="sell"
    screenlength==1 => condition_1=="sell"
    screenlength==2 => condition_2=="sell"

//Plotting
plotshape(bullSignal,title="Buy Condition",style=shape.triangleup,location=location.belowbar,color=color.lime,size=size.tiny)
plotshape(bearSignal,title="Sell Condition",style=shape.triangledown,location=location.abovebar,color=color.red,size=size.tiny)

bg0 = switch
    state0 == "osc0" => color.new(color.yellow,95)
    state0 == "up0" => color.new(color.green,95)
    state0 == "dn0" => color.new(color.red,95)
bg1 = switch
    state1 == "osc1" => color.new(color.yellow,95)
    state1 == "up1" => color.new(color.green,95)
    state1 == "dn1" => color.new(color.red,95)
bg2 = switch
    state2 == "osc2" => color.new(color.yellow,95)
    state2 == "up2" => color.new(color.green,95)
    state2 == "dn2" => color.new(color.red,95)
bg3 = switch
    state3 == "osc3" => color.new(color.yellow,95)
    state3 == "up3" => color.new(color.green,95)
    state3 == "dn3" => color.new(color.red,95)

bgcolor(bg0)
bgcolor(bg1)
bgcolor(bg2)
bgcolor(bg3)


plot(showMAs==true?ema100:na,color=color.white,title="MA 100")
plot(showMAs==true?ema200:na,color=color.yellow,title="MA 200")
plot(showMAs==true?ema300:na,color=color.red,title="MA 300")

//Updated