# ==========================================
# Title: M&T Band Reversal Scanner (MTF Latched Version)
# Description: Scans for interactions with bands anchored to HTF Opens.
# Optimization: Uses 'GetTime' logic to identify HTF anchors without "Secondary Period" errors.
# Ported By: TheInvestorToolkit.com
# ==========================================
# ==========================================
# 1. INPUTS
# ==========================================
input anchorPeriod = {default "DAY", "WEEK", "MONTH", "QUARTER", "YEAR"};
input bandSide = {default Lower, Upper};
input scanMode = {default "Touched / Breached", "Holding Beyond", "Reclaimed / Reversal", "Near Level"};
input bandLookback = 10;
input bandMult = 4.0;
input percentThreshold = 1.0;
# ==========================================
# 2. ROBUST ANCHOR DETECTION (Scanner Friendly)
# ==========================================
# We detect the "New Period" without using the 'script' block or AggregationPeriod
def isNew;
switch (anchorPeriod) {
case DAY:
isNew = GetYYYYMMDD() != GetYYYYMMDD()[1];
case WEEK:
isNew = GetWeek() != GetWeek()[1];
case MONTH:
isNew = GetMonth() != GetMonth()[1];
case QUARTER:
isNew = GetMonth() != GetMonth()[1] and (GetMonth() == 1 or GetMonth() == 4 or GetMonth() == 7 or GetMonth() == 10);
case YEAR:
isNew = GetYear() != GetYear()[1];
}
# Latch the Open Price of that period
rec latchedOpen = CompoundValue(1, if isNew then open else latchedOpen[1], open);
# ==========================================
# 3. BAND MATH
# ==========================================
def stableDist = close - latchedOpen;
# To capture the volatility of the "Period Peaks" as requested in the original logic:
# We track the max/min excursion from the latched open
rec runMax = CompoundValue(1, if isNew then 0 else Max(runMax[1], stableDist), 0);
rec runMin = CompoundValue(1, if isNew then 0 else Min(runMin[1], stableDist), 0);
# Note: For the scanner stability, we calculate Standard Deviation
# of the 'stableDist' (Current price vs Anchor) over the lookback.
def distSD = stDev(stableDist, bandLookback);
def bandUp = latchedOpen + (distSD * bandMult);
def bandDn = latchedOpen - (distSD * bandMult);
# ==========================================
# 4. SMART SCAN LOGIC
# ==========================================
def isLower = bandSide == bandSide.Lower;
def targetLevel = if isLower then bandDn else bandUp;
def eventTouch = if isLower then low <= targetLevel else high >= targetLevel;
def isBeyond = if isLower then close < targetLevel else close > targetLevel;
def isReclaimed = if isLower
then low <= targetLevel and close > targetLevel
else high >= targetLevel and close < targetLevel;
def dist = if isLower then AbsValue(low - targetLevel) else AbsValue(high - targetLevel);
def isNear = (dist <= (targetLevel * (percentThreshold / 100))) or isBeyond;
# ==========================================
# 5. FINAL OUTPUT
# ==========================================
plot Scan = if scanMode == scanMode."Touched / Breached" then eventTouch
else if scanMode == scanMode."Holding Beyond" then isBeyond
else if scanMode == scanMode."Reclaimed / Reversal" then isReclaimed
else isNear;