[R]2 - Reversion
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © zamansiz74

//@version=5
indicator("[R]2 - Version 2", overlay=false)
// Input
o1 = input.bool(defval = true, title = "-------------[R]eversion--------------" )
periods = input.int(defval = 5, title="Periods")
length = input.int(defval = 10, title="Length")
threshold = input.float(5.0, step=1,title="Threshold")
multiplier = input.float(defval = 3.0, step=0.5, title="Multiplier")
median = input.bool(defval = true, title = "Calculate with median")
weighted = input.bool(defval = false, title = "Weighted average")
signal_by_changing_direction = input.bool(defval = false, title = "Signal when changing direction")

// PART 1
sum = 0.0
avg = 0.0

var float xyz = close
var float multi = 1
var bool buySignal = false
var float sumPrice = na
var int count = 0
var float avgPrice = na
var float distanceAvg = 0.0
var color clr = color.rgb(0,0,0,0)

// User-defined function to calculate the median
median(src, periods) =>
    sorted = array.new_float(periods)
    for i = 0 to periods - 1
        array.push(sorted, src[i])
    array.sort(sorted)
    mid = int(periods / 2)
    periods % 2 == 0 ? (array.get(sorted, mid) + array.get(sorted, mid - 1)) / 2 : array.get(sorted, mid)


// Loop for calculating the average...
sum := ta.ema(close, periods) * periods

//...or the meridian
if (median == false)
    if(weighted==false)
        avg := sum / periods
    else
        avg := ta.wma(close,periods)
else
    if(weighted==false)
        avg := median(ta.sma(close, periods), periods)
    else
        avg := median(ta.wma(close, periods), periods)

// Check if the current bar is a multiple of Periods
if bar_index % periods == 0 
    if na(xyz* multi) or math.abs(xyz - avg * multi) >= threshold
        xyz := avg * multi 

// 
if (close > xyz  and xyz == xyz[1] and buySignal == false)
    buySignal := true
    multi := (100-multiplier)/100
    xyz := avg * multi

if (close < xyz  and xyz == xyz[1] and buySignal == true)
    buySignal := false
    multi := (100+multiplier)/100
    xyz := avg * multi
// 
//---------------------------------------X
if barstate.isfirst
    sumPrice := na
    count := 0

if buySignal != buySignal[1]
    // When the buySignal variable changes, save the average of the previous period.
    if count > 0
        avgPrice := sumPrice / count

    // Reset the values to calculate the average for the new period
    sumPrice := close
    count := 1

else
    // Add the prices between the state changes
    sumPrice += close
    count += 1

// Calculate distance between close and avgPrice
distance = ta.ema(close - avgPrice,length)
distance2 = ta.ema(distance,length)
if signal_by_changing_direction
    clr := distance - distance2< 0 ? color.rgb(255,0,0,80) : color.rgb(0,255,0,80)
else
    clr := distance < 0 ? color.rgb(255,0,0,80) : color.rgb(0,255,0,80)

// PLOT 
// Draw continuous line at 0
hline(0, title="Nulllinie", color=color.gray, linestyle=hline.style_dotted, linewidth=3)  // Hier setzen wir den Linienstil auf gepunktet (hline.style_dotted)
hli = plot(0, title="Nulllinie", color=color.black, linewidth = 0, display = display.none)

// Linie zeichnen, um den Abstand darzustellen
dis = plot(distance, title="", style=plot.style_histogram, color=clr, linewidth=1)

fill(hli, dis,clr)

// Alert!
alertcondition((nz(clr) != nz(clr[1])), title="[R]2", message="{{ticker}}, change of direction!")

