SAFE MARGINE_OS
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © shakibsharifian
//OPEN SOURCE
//@version=5
indicator("SAFE MARGINE_OS",overlay=true)

txtOpt1="OC-Based"
txtOpt2="HL-Based"
txtOpt3="MID-Based"


//Counter
countIt(mtd,bkw,val)=>
    int cnt=0
    for int ii=0 to bkw-1
        if (mtd==txtOpt1) and (val>=math.min(close[ii],open[ii]) and val<=math.max(close[ii],open[ii]))
            cnt:=cnt+1
        if (mtd==txtOpt2) and (val>=low[ii] and val<=high[ii])
            cnt:=cnt+1
        if (mtd==txtOpt3) and (val>=low[ii] and val<=high[ii])
            cnt:=cnt+1

    cnt

array_scalerMult(a,b)=>
    itr=array.size(a)
    float sum=0
    for int i=0 to itr-1
        sum:=sum+(array.get(a,i)*array.get(b,i))
    sum

balanceCal(setArr,cntSetArr)=>
    float res=na
    res:=(array_scalerMult(setArr,cntSetArr)/array.sum(cntSetArr))
    res

bk = input.int(24, minval=1, title='BACKWARD',group='GENERAL',inline='a')
//marg = input.int(25, minval=1,maxval=100, title='MARGINE(%)',group='GENERAL',inline='b')
mem = input.int(100, minval=1, title='MEMORY',group='GENERAL',inline='c')
refresh=input.int(600000,minval=1,title='REFRESH in mili-Sec',group='GENERAL',inline='d')
string mtd = input.string(txtOpt1,title='Method',options=[txtOpt1,txtOpt2,txtOpt3],group='METHODOLOGY',inline='a')

bool safeVis=input.bool(true,title='Show Safest',group='DISPLAY',inline='a')
bool balVis=input.bool(true,title='Show Balance',group='DISPLAY',inline='b')
bool avgSafeVis=input.bool(true,title='Show AVG Safest',group='DISPLAY',inline='d')
bool supBalVis=input.bool(true,title='Show Super Balance',group='DISPLAY',inline='e')


//INI
var memo=array.new<float>()
var memo2=array.new<float>()
setPoints=array.new<float>()

float highRng=na
float lowRng=na
float balanceRef=na

//MAIN
for int i=0 to bk-1
    if (mtd==txtOpt1)
        array.push(setPoints,close[i])
        array.push(setPoints,open[i])
    if (mtd==txtOpt2)
        array.push(setPoints,high[i])
        array.push(setPoints,low[i])
    if (mtd==txtOpt3)
        array.push(setPoints,hl2[i])
        array.push(setPoints,ohlc4[i])

array.sort(setPoints,order.ascending)
cntSetPoint=array.new<int>(array.size(setPoints),0)
if bk<bar_index
    for int rdIt=0 to (2*bk)-1
        thisCnt=countIt(mtd,bk,array.get(setPoints,rdIt))
        array.set(cntSetPoint,rdIt,thisCnt)
    orderedCntId=array.sort_indices(cntSetPoint,order.descending)

    highRng:=array.get(setPoints,array.get(orderedCntId,0))

    highPer=int((array.get(cntSetPoint,array.get(orderedCntId,0))/bk)*100)

    lbl=label.new(bar_index+2,highRng,'Safety: '+str.tostring(highPer)+'% in '+str.tostring(highRng),style=label.style_label_left,textcolor=color.black,color=color.white)
    lblSafeVis=safeVis==true?1:0
    label.delete(lbl[lblSafeVis])

hiRngPl=plot(highRng, title="High Range", color=safeVis==true?color.new(#c4dbd7, 55):na, linewidth=2)
//loRngPl=plot(lowRng, title="Low Range", color = na, linewidth=2)
//closePL=plot(close,color=na)
//fill(hiRngPl,loRngPl,title='Safest',color=color.new(#c4dbd7, 15))
//fill(closePL,hiRngPl,title='Status',color=close>highRng?color.new(#78f192, 85):color.new(#f3727d, 85))


balanceRef:=balanceCal(setPoints,cntSetPoint)
balanceRefPl=plot(balanceRef, title="Balance", color=balVis==true?color.new(#eed64d, 0):na, linewidth=1,style=plot.style_cross)

lblbalRef=label.new(bar_index+2,balanceRef,'balance: '+str.tostring(balanceRef),style=label.style_label_left,textcolor=color.black,color=color.white)
lblBalVis=balVis==true?1:0
label.delete(lblbalRef[lblBalVis])

if (time%refresh)==0
    array.push(memo,highRng)
    array.push(memo2,balanceRef)

if array.size(memo)>mem
    delIt=array.shift(memo)

if array.size(memo2)>mem
    delIt=array.shift(memo2)

balance=array.avg(memo)
superBalance=array.avg(memo2)

balancePl=plot(balance, title="AVG SAFE", color=avgSafeVis==true?color.new(#df46b8, 0):na, linewidth=1,style=plot.style_line)
lblbal=label.new(bar_index+2,balance,'AVG SAFE: '+str.tostring(balance),style=label.style_label_left,textcolor=color.black,color=color.white)
lblAvgSafeVis=avgSafeVis==true?1:0
label.delete(lblbal[lblAvgSafeVis])

superBalancePl=plot(superBalance, title="Super Balance", color=supBalVis==true?color.new(#64f564, 0):na, linewidth=1,style=plot.style_line)
lblbalAvg=label.new(bar_index+2,superBalance,'Super balance: '+str.tostring(superBalance),style=label.style_label_left,textcolor=color.black,color=color.white)
lblSupBalVis=supBalVis==true?1:0
label.delete(lblbalAvg[lblSupBalVis])
