Composite Momentum Indicator
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © federalTacos5392

//@version=5
indicator("Composite Momentum Oscillator", overlay=false)

// Input parameters
lookback_period = input.int(500, title="Look-back Period")
overbought_threshold=input(1.2, title= "Overbought Threshold")
oversold_threshold=input(-1.2, title= "Oversold Threshold")

// selection of osscilators 
include_stochastic = input.bool(true, title="Include Stochastic Z-Score")
include_rsi = input.bool(true, title="Include RSI Z-Score")
include_uo = input.bool(true, title="Include Ultimate Oscillator Z-Score")
include_cci = input.bool(true, title="Include CCI Z-Score")
include_co = input.bool(true, title="Include Chaikin Oscillator Z-Score")
include_mfi =input.bool(true, title="Include Money Flow Index Z-Score")
include_kri =input.bool(true, title="Include Kairi Relative Index Z-Score")
include_wpr=input.bool(true,title="Include Williams % R")
include_ao=input.bool(true,title= "Awesome Oscillator")

// Custom Lengths 
SOL=input(14, title="Stochastic length" )
MFIL=input(14, title="Money Flow Index Length")
RSIL=input(14, title="RSI Length")
UOL1= input(7, title= "Ultimate Oscilator Length1")
UOL2= input(14, title= "Ultimate Oscilator Length2")
UOL3= input(28, title= "Ultimate Oscilator Length3" )
CCIL=input(20, title="Comodity Channel Inedx Length")
COL1=input(3, title="Chinkin Oscilator fast Length")
COL2=input(10, title="Chinkin Oscilator slow Length")
KRIL=input(14, title="Kairi Relative Index Length" )
WPRL=input(14,title= "Williams % R")
AOL1=input(5, title="Awesome Oscilator fast Length")
AOL2=input(34, title="Awesome Oscilator slow Length")


// Calculate Stochastic Oscillator (Fast Line)
stochastic_fast_k = ta.stoch(close, high, low, SOL)
stochastic_fast_zscore = (stochastic_fast_k - ta.sma(stochastic_fast_k, lookback_period)) / ta.stdev(stochastic_fast_k, lookback_period)

// Calculate Awesome Oscilator
ao = ta.sma(hl2,AOL1) - ta.sma(hl2,AOL2)
ao_zscore=(ao- ta.sma(ao, lookback_period)) / ta.stdev(ao, lookback_period)

// Calculate Williams % R
_pr(WPRL) =>
	max = ta.highest(WPRL)
	min = ta.lowest(WPRL)
	100 * (close - max) / (max - min)
wpr = _pr(WPRL)
wpr_zscore=(wpr- ta.sma(wpr, lookback_period)) / ta.stdev(wpr, lookback_period)

// Calculate Money Flow Index
mfi=ta.mfi(hlc3,MFIL)
mfi_zscore=(mfi - ta.sma(mfi, lookback_period)) / ta.stdev(mfi, lookback_period)
// Calculate RSI
rsi = ta.rsi(close, RSIL)
rsi_zscore = (rsi - ta.sma(rsi, lookback_period)) / ta.stdev(rsi, lookback_period)

// Calculate KRI
sma= ta.sma(close, KRIL)
kri = (close-sma)/sma
kri_zscore = (kri - ta.sma(kri, lookback_period)) / ta.stdev(kri, lookback_period)

// Custom Ultimate Oscillator Calculation
length1 = UOL1
length2 = UOL2
length3 = UOL3
average(bp, tr_, length) => ta.sma(bp, length) / ta.sma(tr_, length)
high_ = ta.highest(high, 2)
low_ = ta.lowest(low, 2)
bp = close - low_
tr_ = high_ - low_
avg7 = average(bp, tr_, length1)
avg14 = average(bp, tr_, length2)
avg28 = average(bp, tr_, length3)
uo = 100 * (4 * avg7 + 2 * avg14 + avg28) / 7
uo_zscore = (uo - ta.sma(uo, lookback_period)) / ta.stdev(uo, lookback_period)

// Calculate Commodity Channel Index (CCI)
cci = ta.cci(close, CCIL)
cci_zscore = (cci - ta.sma(cci, lookback_period)) / ta.stdev(cci, lookback_period)

// calculate chaikin oscilator (CO)
var cumVol = 0.
cumVol += nz(volume)
if barstate.islast and cumVol == 0
    runtime.error("No volume is provided by the data vendor.")
co = ta.ema(ta.accdist, COL1) - ta.ema(ta.accdist, COL2)
co_zscore = (co - ta.sma(co, lookback_period))/ta.stdev(co, lookback_period)

// Calculate the average z-score based on selected inputs
z_scores = array.new_float(0)
if include_stochastic
    array.push(z_scores, stochastic_fast_zscore)
if include_rsi
    array.push(z_scores, rsi_zscore)
if include_uo
    array.push(z_scores, uo_zscore)
if include_cci
    array.push(z_scores, cci_zscore)
if include_co
    array.push(z_scores,co_zscore)
if include_mfi
    array.push(z_scores,mfi_zscore)
if include_kri
    array.push(z_scores,kri_zscore)
if include_wpr
    array.push(z_scores, wpr_zscore)
if include_ao
    array.push(z_scores, ao_zscore)
average_zscore = array.size(z_scores) > 0 ? array.avg(z_scores) : 0

// Define the color based on the Z-score average value
colorCondition = average_zscore > overbought_threshold ? color.green : average_zscore < oversold_threshold ? color.red : color.blue
sma_average_zscore = ta.sma(average_zscore,3)

// Plot the composite momentum oscillator with the conditional color
plot1 = plot(average_zscore, title="Composite Momentum Oscillator", color=colorCondition)
plot (sma_average_zscore,color=color.black, title = "smoothed line")

// Plot Lines at 0, 3, -3, 2, -2, 1, -1
hline(0, "Center Line", color=color.blue, linestyle=hline.style_solid)
hline(3, "Upper 3", color=color.red, linestyle=hline.style_solid)
hline(-3, "Lower -3", color=color.green, linestyle=hline.style_solid)
hline(2, "Upper 2", color=color.red, linestyle=hline.style_dashed)
hline(-2, "Lower -2", color=color.green, linestyle=hline.style_dashed)
overbought = hline(1, "Upper 1", color=color.red, linestyle=hline.style_dotted)
oversold = hline(-1, "Lower -1", color=color.green, linestyle=hline.style_dotted)
midLinePlot = plot(0, color = na, editable = false, display = display.none)
fill(plot1, midLinePlot, 3, overbought_threshold, top_color = color.new(color.green, 0), bottom_color = color.new(color.green, 100),  title = "Overbought Gradient Fill")
fill(plot1, midLinePlot, oversold_threshold,  -3,  top_color = color.new(color.red, 100), bottom_color = color.new(color.red, 0),      title = "Oversold Gradient Fill")

