Role Reversal Detection Alert [MsF]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Trader_Morry

//@version=5
indicator(title='Role Reversal Detection Alert [MsF]', shorttitle='R&R Detection', overlay=true, max_bars_back = 5000)

////////
// Input values 
// [
ibaseHValue    = input.float(defval = 135.2, title = "Input Horizontal Value")
ibaseBandPips  = input.int(defval = 10, title = "Band Range by pips")
ibaseLineColor = input.color(defval = color.blue, title = "Line Color", inline = "iLine")
ibaseLineWidth = input.int(defval = 1, title = "Line Width", inline = "iLine")
ibaseBandColor = input.color(defval = color.blue, title = "Band Color", inline = "iBand")
ibaseBandWidth = input.int(defval = 1, title = "Band Width", inline = "iBand")
iLong          = true //input.bool(defval = true, title = "Long  Detection")
iShort         = true //input.bool(defval = true, title = "Short Detection")
iLookBackCBars = 18 // count of previous Bars for Judging touch in center
// ]

// Defines
// [
LONG  =  1
SHORT = -1
// ]

// Functions
// [
check_touch_center(aLongShort, aBars) =>
    var touch = false
    if ( aLongShort == LONG )
        for i=1 to aBars-1
            if ibaseHValue >= low[i]
                touch := true
                break
    else if ( aLongShort == SHORT )
        for i=1 to aBars-1
            if ibaseHValue <= high[i]
                touch := true
                break
    touch
// ]

// Main Program
// [
_pips = ibaseBandPips*syminfo.mintick*10
// Base line
var line line_Base = na
line.delete(line_Base)
line_Base := line.new(bar_index, ibaseHValue, bar_index+1, ibaseHValue, extend = extend.both, color = ibaseLineColor, width = ibaseLineWidth)

// Upper Band line
var line line_Upper = na
line.delete(line_Upper)
line_Upper := line.new(bar_index, ibaseHValue+_pips, bar_index+1, ibaseHValue+_pips, extend = extend.both, color = ibaseBandColor, style = line.style_dashed, width = ibaseBandWidth)

// Lower Band line
var line line_Lower = na
line.delete(line_Lower)
line_Lower := line.new(bar_index, ibaseHValue-_pips, bar_index+1, ibaseHValue-_pips, extend = extend.both, color = ibaseBandColor, style = line.style_dashed, width = ibaseBandWidth)

//// Alert
//   [
// 終値で帯を抜けた場合
alert_long_BO  = (close[2] < ibaseHValue+_pips and close[1] >= ibaseHValue+_pips)?true:false
alert_short_BO = (close[2] > ibaseHValue-_pips and close[1] <= ibaseHValue-_pips)?true:false
// センタータッチチェック
alert_long_CT  = check_touch_center(LONG , iLookBackCBars)
alert_short_CT = check_touch_center(SHORT, iLookBackCBars)
// ALL check Long/Short
alert_long     = iLong  and alert_long_BO  and alert_long_CT
alert_short    = iShort and alert_short_BO and alert_short_CT

//alertcondition(alert_long or alert_short,"Role Reversal Alert","Detect Role Reversal!!")
alertcondition(alert_long,"[long] Role Reversal Alert","Detect Role Reversal - long!!")
alertcondition(alert_short,"[short] Role Reversal Alert","Detect Role Reversal - short!!")
//   ]
// ]
