Oliver Velez Indicator
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Rginah1974

//@version=4
study("Oliver Velez Indicator", shorttitle="OVI", overlay=true)
//use_HA = input.bool(false, title='Use HeikinAshi data?', group='HeikinAshi')
// Input parameters for Elephant Bars
lookback = input(5, title="Lookback Period", minval=1, group='Elephantbars')
multiplier = input(1.5, title="Size Multiplier", type=input.float, minval=0.1, group='Elephantbars')


//input parameters Tailbars
input_tail_ratio = input(2.0, title="Tail Ratio", type=input.float, group= "tailbars")
input_opposite_wick_ratio = input(0.2, title="Opposite Wick Ratio", type=input.float, group= "tailbars")


// Input parameters for Moving Averages
shortLength = input(20, title="Short MA Length", minval=1, group='MAs')
longLength = input(200, title="Long MA Length", minval=1, group='MAs')
maType = input(title="MA Type", defval="SMA", options=["SMA", "EMA", "WMA", "VWMA", "SMMA", "HullMA", "TEMA"], group='MAs')

// Moving Average function
ma(src, length, ma_type) =>
    if ma_type == "SMA"
        sma(src, length)
    else if ma_type == "EMA"
        ema(src, length)
    else if ma_type == "WMA"
        wma(src, length)
    else if ma_type == "VWMA"
        vwma(src, length)
    else if ma_type == "HullMA"
        wma(2 * wma(src, length / 2) - wma(src, length), round(sqrt(length)))
    else if ma_type == "TEMA"
        3 * ema(src, length) - 3 * ema(ema(src, length), length) + ema(ema(ema(src, length), length), length)
    else
        na

// Calculate average candle size and volume
avg_candle_size = sum(abs(close - open), lookback) / lookback
avg_volume = sum(volume, lookback) / lookback


// Calculate body size, and tailsize proportions
body_size = abs(close - open)
tail_size = close > open ? open - low : close - low
upper_wick_size = close > open ? high - close : high - open
opposite_wick_size = close > open ? high - open : high - close

// Calculate Moving Averages
shortMA = ma(close, shortLength, maType)
longMA = ma(close, longLength, maType)

// Define the touch_shortMA function
touch_shortMA(i) => (low[i] <= shortMA[i] and high[i] >= shortMA[i])

// Identify Elephant Bars with additional conditions
is_bullish = (close - open) > (multiplier * avg_candle_size) and volume > avg_volume and (touch_shortMA(0) or touch_shortMA(1) or touch_shortMA(2) or touch_shortMA(3) or touch_shortMA(4))
is_bearish = (open - close) > (multiplier * avg_candle_size) and volume > avg_volume and (touch_shortMA(0) or touch_shortMA(1) or touch_shortMA(2) or touch_shortMA(3) or touch_shortMA(4))

//Identify Tailbars with conditions
is_bullish_tailbar1 = (tail_size > body_size * input_tail_ratio) and close > open and (upper_wick_size <= tail_size * input_opposite_wick_ratio)
is_bullish_tailbar2 = (tail_size > body_size * input_tail_ratio) and close < open and (upper_wick_size <= tail_size * input_opposite_wick_ratio)
is_bearish_tailbar1 = (upper_wick_size > body_size * input_tail_ratio) and close < open and (tail_size <= upper_wick_size * input_opposite_wick_ratio)
is_bearish_tailbar2 = (upper_wick_size > body_size * input_tail_ratio) and close > open and (tail_size <= upper_wick_size * input_opposite_wick_ratio)

// Plot elephantbar signals
//plotshape(is_bullish, style=shape.circle, location=location.abovebar, color=color.aqua, size=size.tiny)
//plotshape(is_bearish, style=shape.circle, location=location.belowbar, color=color.fuchsia, size=size.tiny)
//candle color:
barcolor(is_bullish ? color.aqua : is_bearish ? color.fuchsia : na)


//plot tailbar signals
barcolor(is_bullish_tailbar1 ? color.aqua : na)
barcolor(is_bullish_tailbar2 ? color.blue : na)
barcolor(is_bearish_tailbar1 ? color.fuchsia : na)
barcolor(is_bearish_tailbar2 ? color.orange : na)

//plotshape(is_bullish_tailbar1 or is_bullish_tailbar2, title="Bullish Tail Bar", location=location.belowbar, color=color.green, style=shape.arrowup, size=size.small)
//plotshape(is_bearish_tailbar1 or is_bearish_tailbar2, title="Bearish Tail Bar", location=location.abovebar, color=color.red, style=shape.arrowdown, size=size.small)

plot(is_bullish_tailbar1 or is_bullish_tailbar2 ? low : na, color=color.aqua, linewidth=1, style=plot.style_circles)
plot(is_bearish_tailbar1 or is_bearish_tailbar2 ? high : na, color=color.fuchsia, linewidth=1, style=plot.style_circles)
plot(is_bullish_tailbar2 ? low : na, color=color.blue, linewidth=1, style=plot.style_circles)
plot(is_bearish_tailbar2 ? high : na, color=color.orange, linewidth=1, style=plot.style_circles)

// Plot Moving Averages
plot(shortMA, title="Short MA", color=color.aqua, linewidth=2)
plot(longMA, title="Long MA", color=color.fuchsia, linewidth=2)

// Add Keltner Channel1
mult = input(3.0, "Multiplier",group='KeltnerChannel1')
keltnerSource = input(title="Keltner Channel Source", defval="Short MA", options=["Short MA", "Long MA"],group='KeltnerChannel1')
BandsStyle = input("Range", options = ["Average True Range", "True Range", "Range"], title="Bands Style",group='KeltnerChannel1')
atrlength = input(14, "ATR Length",group='KeltnerChannel1')

keltnerMA = keltnerSource == "Short MA" ? shortMA : longMA
keltnerLength = keltnerSource == "Short MA" ? shortLength : longLength
rangema = BandsStyle == "True Range" ? tr : BandsStyle == "Average True Range" ? atr(atrlength) : rma(high - low, keltnerLength)
keltnerUpper = keltnerMA + rangema * mult
keltnerLower = keltnerMA - rangema * mult

// Plot the Keltner Channel on the chart
u = plot(keltnerUpper, color=color.rgb(255, 82, 82, 100), title="Keltner Channel Upper1", linewidth=1)
//plot(keltnerMA, color=color.blue, title="Keltner Channel Basis", linewidth=1)
l = plot(keltnerLower, color=color.rgb(255, 82, 82, 100), title="Keltner Channel Lower1", linewidth=1)

// Fill the Keltner Channel with white color and 20% transparency
fill(u, l, color=color.white, transp=90)

// Add Keltner Channel2
mult1 = input(3.0, "Multiplier",group='KeltnerChannel2')
keltnerSource1 = input(title="Keltner Channel Source", defval="Short MA", options=["Short MA", "Long MA"],group='KeltnerChannel2')
BandsStyle1 = input("Range", options = ["Average True Range", "True Range", "Range"], title="Bands Style",group='KeltnerChannel2')
atrlength1= input(14, "ATR Length",group='KeltnerChannel2')

keltnerMA1 = keltnerSource1 == "Short MA" ? shortMA : longMA
keltnerLength1 = keltnerSource1 == "Short MA" ? shortLength : longLength
rangema1 = BandsStyle1 == "True Range" ? tr : BandsStyle == "Average True Range" ? atr(atrlength1) : rma(high - low, keltnerLength1)
keltnerUpper1 = keltnerMA1 + rangema1 * mult1
keltnerLower1 = keltnerMA1 - rangema1 * mult1

// Plot the Keltner Channel on the chart
u1 = plot(keltnerUpper1, color=color.rgb(255, 82, 82, 100), title="Keltner Channel Upper2", linewidth=1)
//plot(keltnerMA1, color=color.rgb(33, 149, 243, 100), title="Keltner Channel Basis", linewidth=1)
l1 = plot(keltnerLower1, color=color.rgb(255, 82, 82, 100), title="Keltner Channel Lower2", linewidth=1)

// Fill the Keltner Channel with white color and 20% transparency
fill(u1, l1, color=color.white, transp=90)