The script detects when the price has spent enough time above or below a dynamic acceptable-value band, and then fails to maintain that position (returning inside the band). It then evaluates the quality of this reversal to produce a readiness score (0–100) and a structured plan (risk, target, invalidation).
It is a decision engine and not a generator of simplistic signals. It prioritizes confluence: acceptance duration + quality of the failure + clear risk + room for movement.
Alerts are triggered by these status changes, but they are warning indicators, not trading orders.
// =========================================================
// Price Acceptance Reversal Planner [AGPro Series]
// Conversion ProRealTime / ProBuilder
// Original : Pine Script v6 — AGProLabs
// ---------------------------------------------------------
// PARAMETRES
// ---------------------------------------------------------
// Moteur
AnchorLen = 34 // Acceptance Anchor Length (5-240)
AtrLen = 14 // ATR Length (5-100)
VolumeLen = 34 // Volume Baseline Length (5-220)
TargetLookback = 72 // Target Room Lookback (20-300)
// Sensibilité : 1=Responsive, 2=Balanced, 3=Strict
//SensMode = 2
// Confirmation : 1=Realtime, 2=Close Acceptance, 3=Close+Volume, 4=Strict
//ConfirmMode = 2
// Modèle Planner
BandWidthAtr = 0.58 // Acceptance Band Width ATR
MinAcceptBars = 4 // Minimum Acceptance Bars
FailDistAtr = 0.10 // Failure Close Distance ATR
InvalBuffAtr = 0.24 // Invalidation Shelf Buffer ATR
TargetFallAtr = 1.35 // Target Room ATR Fallback
CleanRoomAtr = 1.85 // Clean Room Target ATR
MinRevScore = 64 // Minimum Reversal Score
WatchScoreMin = 52 // Acceptance Watch Score
// Visuel
//ShowBand = 1 // 1=oui, 0=non
//ShowRails = 1 // 1=oui, 0=non
LabelOffAtr = 0.95 // Label Offset ATR
// ---------------------------------------------------------
// AJUSTEMENTS SENSIBILITE
// ---------------------------------------------------------
IF SensMode = 1 THEN
AcceptNeed = MAX(MinAcceptBars - 1, 2)
FailNeed = MAX(FailDistAtr * 0.65, 0)
BodyNeed = 0.20
CloseNeed = 0.56
ELSIF SensMode = 3 THEN
AcceptNeed = MinAcceptBars + 2
FailNeed = FailDistAtr * 1.35
BodyNeed = 0.34
CloseNeed = 0.68
ELSE
AcceptNeed = MinAcceptBars
FailNeed = FailDistAtr
BodyNeed = 0.28
CloseNeed = 0.62
ENDIF
// ---------------------------------------------------------
// CALCULS DE BASE
// ---------------------------------------------------------
AtrRaw = AverageTrueRange[AtrLen]
MyAtr = MAX(AtrRaw, pipsize)
// hlc3 en Pine = (high+low+close)/3 = typicalprice en PRT
Anchors = ExponentialAverage[AnchorLen]((high + low + close) / 3)
BandHalf = MyAtr * BandWidthAtr
BandTop = Anchors + BandHalf
BandBot = Anchors - BandHalf
BandMid = Anchors
CandleRange = MAX(high - low, pipsize)
Body = ABS(close - open)
BodyShare = Body / CandleRange
CloseLoc = (close - low) / CandleRange
VolBase = Average[VolumeLen](volume)
IF VolBase > 0 THEN
VolRatio = volume / VolBase
ELSE
VolRatio = 1
ENDIF
AboveBand = close > BandTop
BelowBand = close < BandBot
InsideBand = close <= BandTop AND close >= BandBot
// ---------------------------------------------------------
// COMPTEURS D'ACCEPTANCE
// ---------------------------------------------------------
IF AboveBand THEN
UpperAcceptCnt = UpperAcceptCnt + 1
ELSE
UpperAcceptCnt = 0
ENDIF
IF BelowBand THEN
LowerAcceptCnt = LowerAcceptCnt + 1
ELSE
LowerAcceptCnt = 0
ENDIF
UpperAcceptPrior = UpperAcceptCnt[1]
LowerAcceptPrior = LowerAcceptCnt[1]
HadUpperAccept = UpperAcceptPrior >= AcceptNeed
HadLowerAccept = LowerAcceptPrior >= AcceptNeed
// ---------------------------------------------------------
// SCORES DE FAILURE (normalisés 0-100)
// ---------------------------------------------------------
// Upper Failure Distance
UpperFailDist = (BandTop - close) / MyAtr
// Lower Failure Distance
LowerFailDist = (close - BandBot) / MyAtr
// --- Bear Close Failure Score = norm_high(UpperFailDist, FailNeed, 0.95) ---
spanBCF = MAX(0.95 - FailNeed, 0.000001)
BearCloseFailScore = MAX(0, MIN(100, (UpperFailDist - FailNeed) / spanBCF * 100))
// --- Bull Close Failure Score = norm_high(LowerFailDist, FailNeed, 0.95) ---
BullCloseFailScore = MAX(0, MIN(100, (LowerFailDist - FailNeed) / spanBCF * 100))
// --- Bear Close Location Score = norm_high(1-CloseLoc, CloseNeed-0.14, 0.92) ---
spanBCL = MAX(0.92 - (CloseNeed - 0.14), 0.000001)
BearCloseLocScore = MAX(0, MIN(100, ((1 - CloseLoc) - (CloseNeed - 0.14)) / spanBCL * 100))
// --- Bull Close Location Score = norm_high(CloseLoc, CloseNeed-0.14, 0.92) ---
BullCloseLocScore = MAX(0, MIN(100, (CloseLoc - (CloseNeed - 0.14)) / spanBCL * 100))
// --- Body Score = norm_high(BodyShare, BodyNeed*0.65, 0.74) ---
spanBody = MAX(0.74 - BodyNeed * 0.65, 0.000001)
BodyScoreVal = MAX(0, MIN(100, (BodyShare - BodyNeed * 0.65) / spanBody * 100))
// --- Direction Scores ---
IF close < open THEN
BearDirScore = 88
ELSIF close < close[1] THEN
BearDirScore = 58
ELSE
BearDirScore = 28
ENDIF
IF close > open THEN
BullDirScore = 88
ELSIF close > close[1] THEN
BullDirScore = 58
ELSE
BullDirScore = 28
ENDIF
// --- Volume Score = norm_high(VolRatio, 0.85, 1.75) ---
spanVol = MAX(1.75 - 0.85, 0.000001)
VolScoreVal = MAX(0, MIN(100, (VolRatio - 0.85) / spanVol * 100))
// --- Time Scores ---
// Bear Time = norm_high(UpperAcceptPrior, AcceptNeed, AcceptNeed+9)
spanTime = MAX(9, 0.000001)
BearTimeScore = MAX(0, MIN(100, (UpperAcceptPrior - AcceptNeed) / spanTime * 100))
BullTimeScore = MAX(0, MIN(100, (LowerAcceptPrior - AcceptNeed) / spanTime * 100))
// ---------------------------------------------------------
// TARGETS & INVALIDATION
// ---------------------------------------------------------
IF BandTop > close THEN
BullTarget = BandTop
ELSE
BullTarget = close + MyAtr * TargetFallAtr
ENDIF
IF BandBot < close THEN
BearTarget = BandBot
ELSE
BearTarget = close - MyAtr * TargetFallAtr
ENDIF
BullRoomAtr = (BullTarget - close) / MyAtr
BearRoomAtr = (close - BearTarget) / MyAtr
// Room Scores = norm_high(roomAtr, 0.35, CleanRoomAtr)
spanRoom = MAX(CleanRoomAtr - 0.35, 0.000001)
BullRoomScore = MAX(0, MIN(100, (BullRoomAtr - 0.35) / spanRoom * 100))
BearRoomScore = MAX(0, MIN(100, (BearRoomAtr - 0.35) / spanRoom * 100))
BullInval = low - MyAtr * InvalBuffAtr
BearInval = high + MyAtr * InvalBuffAtr
BullRiskAtr = (close - BullInval) / MyAtr
BearRiskAtr = (BearInval - close) / MyAtr
// Risk Scores = peak_score(riskAtr, 0.22, 0.95, 3.20)
// Montée de 0.22 à 0.95, descente de 0.95 à 3.20
IF BullRiskAtr <= 0.95 THEN
spanRiskUp = MAX(0.95 - 0.22, 0.000001)
BullRiskScore = MAX(0, MIN(100, (BullRiskAtr - 0.22) / spanRiskUp * 100))
ELSE
spanRiskDn = MAX(3.20 - 0.95, 0.000001)
BullRiskScore = MAX(0, MIN(100, (3.20 - BullRiskAtr) / spanRiskDn * 100))
ENDIF
IF BearRiskAtr <= 0.95 THEN
spanRiskUp2 = MAX(0.95 - 0.22, 0.000001)
BearRiskScore = MAX(0, MIN(100, (BearRiskAtr - 0.22) / spanRiskUp2 * 100))
ELSE
spanRiskDn2 = MAX(3.20 - 0.95, 0.000001)
BearRiskScore = MAX(0, MIN(100, (3.20 - BearRiskAtr) / spanRiskDn2 * 100))
ENDIF
// ---------------------------------------------------------
// SCORES COMPOSITES
// ---------------------------------------------------------
// Failure Risk
BullFailRisk = MAX(0, MIN(100, BullTimeScore * 0.34 + BullCloseFailScore * 0.30 + BullCloseLocScore * 0.20 + VolScoreVal * 0.16))
BearFailRisk = MAX(0, MIN(100, BearTimeScore * 0.34 + BearCloseFailScore * 0.30 + BearCloseLocScore * 0.20 + VolScoreVal * 0.16))
// Reversal Scores
BullRevScore = MAX(0, MIN(100, BullTimeScore * 0.18 + BullCloseFailScore * 0.22 + BodyScoreVal * 0.13 + BullDirScore * 0.12 + VolScoreVal * 0.10 + BullRoomScore * 0.15 + BullRiskScore * 0.10))
BearRevScore = MAX(0, MIN(100, BearTimeScore * 0.18 + BearCloseFailScore * 0.22 + BodyScoreVal * 0.13 + BearDirScore * 0.12 + VolScoreVal * 0.10 + BearRoomScore * 0.15 + BearRiskScore * 0.10))
// ---------------------------------------------------------
// CONDITIONS DE CONFIRMATION
// ---------------------------------------------------------
IF ConfirmMode = 3 THEN
VolPass = VolRatio >= 1.0
ELSIF ConfirmMode = 4 THEN
VolPass = VolRatio >= 1.10
ELSE
VolPass = 1
ENDIF
IF ConfirmMode = 4 THEN
BullClosePass = close > BandMid
BearClosePass = close < BandMid
ELSE
BullClosePass = close > BandBot + MyAtr * FailNeed
BearClosePass = close < BandTop - MyAtr * FailNeed
ENDIF
// ---------------------------------------------------------
// SIGNAUX REVERSAL READY
// ---------------------------------------------------------
BullReady = HadLowerAccept AND BullClosePass AND CloseLoc >= CloseNeed AND BodyShare >= BodyNeed * 0.70 AND VolPass AND BullRevScore >= MinRevScore
BearReady = HadUpperAccept AND BearClosePass AND CloseLoc <= (1 - CloseNeed) AND BodyShare >= BodyNeed * 0.70 AND VolPass AND BearRevScore >= MinRevScore
NewReversal = BullReady OR BearReady
// ---------------------------------------------------------
// PREVIEW SCORES (quand pas de setup actif)
// ---------------------------------------------------------
PreviewScore = MAX(BullRevScore, BearRevScore)
PreviewFailRisk = MAX(BullFailRisk, BearFailRisk)
// ---------------------------------------------------------
// GESTION ETAT ACTIF
// ---------------------------------------------------------
ONCE ActiveDir = 0
ONCE ActiveScore = 0
ONCE ActiveFailRisk = 0
ONCE ActiveInval = 0
ONCE ActiveTarget = 0
ONCE ActiveTrigger = 0
ONCE ActiveRoomAtr = 0
ONCE ActiveState = 0 // 0=NoSetup, 1=BullRev, -1=BearRev, 2=Invalidated
ONCE ActiveTargetHit = 0
ONCE ActiveUntilBar = 0
ONCE LastEventBar = -999
ONCE LastWatchBar = -999
ForwardBars = 30
CooldownBars = 18
WatchSpacing = 36
// Mise à jour état actif
IF NewReversal THEN
IF BullReady THEN
ActiveDir = 1
ActiveScore = BullRevScore
ActiveFailRisk = BullFailRisk
ActiveTarget = BullTarget
ActiveInval = BullInval
ActiveTrigger = BandBot
ActiveRoomAtr = BullRoomAtr
ActiveState = 1
ELSE
ActiveDir = -1
ActiveScore = BearRevScore
ActiveFailRisk = BearFailRisk
ActiveTarget = BearTarget
ActiveInval = BearInval
ActiveTrigger = BandTop
ActiveRoomAtr = BearRoomAtr
ActiveState = -1
ENDIF
ActiveTargetHit = 0
ActiveUntilBar = barindex + ForwardBars
ENDIF
ActiveValid = ActiveDir <> 0 AND barindex <= ActiveUntilBar
// Vérification invalidation
Invalidated = 0
IF ActiveValid AND ActiveDir = 1 AND close < ActiveInval THEN
Invalidated = 1
ENDIF
IF ActiveValid AND ActiveDir = -1 AND close > ActiveInval THEN
Invalidated = 1
ENDIF
IF Invalidated THEN
ActiveState = 2
ActiveUntilBar = barindex
ENDIF
// Vérification target atteint
TargetHit = 0
IF ActiveValid AND ActiveTargetHit = 0 AND NOT Invalidated THEN
IF ActiveDir = 1 AND high >= ActiveTarget THEN
TargetHit = 1
ActiveTargetHit = 1
ENDIF
IF ActiveDir = -1 AND low <= ActiveTarget THEN
TargetHit = 1
ActiveTargetHit = 1
ENDIF
ENDIF
// ---------------------------------------------------------
// WATCH CONDITIONS
// ---------------------------------------------------------
// Score de watch simplifié
WatchUpperRaw = BearTimeScore * 0.55 + VolScoreVal * 0.20
WatchUpperVal = MAX(0, MIN(100, WatchUpperRaw))
UpperWatch = UpperAcceptCnt = AcceptNeed AND WatchUpperVal >= WatchScoreMin AND NOT NewReversal
WatchLowerRaw = BullTimeScore * 0.55 + VolScoreVal * 0.20
WatchLowerVal = MAX(0, MIN(100, WatchLowerRaw))
LowerWatch = LowerAcceptCnt = AcceptNeed AND WatchLowerVal >= WatchScoreMin AND NOT NewReversal
// ---------------------------------------------------------
// GRADE (pour affichage)
// ---------------------------------------------------------
// A+=86+, A=76+, B=64+, C=52+, D=reste
IF ActiveValid THEN
ScoreDisplay = ActiveScore
ELSE
ScoreDisplay = PreviewScore
ENDIF
// ---------------------------------------------------------
// PREPARATION DES SORTIES
// ---------------------------------------------------------
// Bande d'acceptance
IF ShowBand THEN
PlotBandTop = BandTop
PlotBandBot = BandBot
PlotBandMid = BandMid
ELSE
PlotBandTop = undefined
PlotBandBot = undefined
PlotBandMid = undefined
ENDIF
// Rails actifs
IF ShowRails AND ActiveValid AND NOT Invalidated THEN
r1x = ActiveTrigger
r2x = ActiveInval
r3x = ActiveTarget
ELSE
r1x = undefined
r2x = undefined
r3x = undefined
ENDIF
// ---------------------------------------------------------
// SIGNAUX VISUELS SUR LE GRAPHIQUE
// ---------------------------------------------------------
// Bull Reversal Ready
IF BullReady AND (barindex - LastEventBar) >= CooldownBars THEN
DRAWTEXT("▲ BULL REV", barindex, low - MyAtr * LabelOffAtr) COLOURED(34, 197, 166)
LastEventBar = barindex
ENDIF
// Bear Reversal Ready
IF BearReady AND (barindex - LastEventBar) >= CooldownBars THEN
DRAWTEXT("▼ BEAR REV", barindex, high + MyAtr * LabelOffAtr) COLOURED(244, 114, 182)
LastEventBar = barindex
ENDIF
// Upper Watch
IF UpperWatch AND (barindex - LastWatchBar) >= WatchSpacing AND NOT NewReversal THEN
DRAWTEXT("◆ UPR WATCH", barindex, high + MyAtr * LabelOffAtr * 0.7) COLOURED(245, 189, 92)
LastWatchBar = barindex
ENDIF
// Lower Watch
IF LowerWatch AND (barindex - LastWatchBar) >= WatchSpacing AND NOT NewReversal THEN
DRAWTEXT("◆ LWR WATCH", barindex, low - MyAtr * LabelOffAtr * 0.7) COLOURED(245, 189, 92)
LastWatchBar = barindex
ENDIF
// Invalidation
IF Invalidated AND (barindex - LastEventBar) >= CooldownBars THEN
IF ActiveDir = 1 THEN
DRAWTEXT("✕ INVAL", barindex, low - MyAtr * LabelOffAtr * 0.5) COLOURED(239, 68, 68)
ELSE
DRAWTEXT("✕ INVAL", barindex, high + MyAtr * LabelOffAtr * 0.5) COLOURED(239, 68, 68)
ENDIF
LastEventBar = barindex
ENDIF
// Target atteint
IF TargetHit THEN
IF ActiveDir = 1 THEN
DRAWTEXT("★ TARGET", barindex, high + MyAtr * LabelOffAtr * 0.5) COLOURED(129, 140, 248)
ELSE
DRAWTEXT("★ TARGET", barindex, low - MyAtr * LabelOffAtr * 0.5) COLOURED(129, 140, 248)
ENDIF
ENDIF
// ---------------------------------------------------------
// PANNEAU D'INFORMATION (ancré en haut à droite)
// Syntaxe PRT : anchor(topright, xshift, yshift)
// Variables injectées via #variable#
// ---------------------------------------------------------
ScoreRound = ROUND(ScoreDisplay)
FailRiskRound = ROUND(MAX(BullFailRisk, BearFailRisk))
IF ActiveValid THEN
FailRiskRound = ROUND(ActiveFailRisk)
ENDIF
RoomAtrDisp = ROUND(ActiveRoomAtr * 10) / 10
IF islastbarupdate THEN
// --- Header ---
drawtext("AG Pro PAR Planner", -200, -10, Dialog, Bold,12) anchor(topright, xshift, yshift) coloured(37, 99, 235, 255)
// --- State ---
IF ActiveValid AND ActiveState = 1 THEN
drawtext("State: Bull Reversal", -200, -30, Dialog, Bold,12) anchor(topright, xshift, yshift) coloured(34, 197, 166, 255)
ELSIF ActiveValid AND ActiveState = -1 THEN
drawtext("State: Bear Reversal", -200, -30, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(244, 114, 182, 255)
ELSIF ActiveValid AND ActiveState = 2 THEN
drawtext("State: Invalidated", -200, -30, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(239, 68, 68, 255)
ELSIF AboveBand THEN
drawtext("State: Upper Accept (#UpperAcceptCnt#)", -200, -30, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(245, 189, 92, 255)
ELSIF BelowBand THEN
drawtext("State: Lower Accept (#LowerAcceptCnt#)", -200, -30, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(245, 189, 92, 255)
ELSE
drawtext("State: Inside Band", -200, -30, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(148, 163, 184, 255)
ENDIF
// --- Score ---
IF ScoreDisplay >= 86 THEN
drawtext("Score: #ScoreRound#/100 A+", -200, -50, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(34, 197, 166, 255)
ELSIF ScoreDisplay >= 76 THEN
drawtext("Score: #ScoreRound#/100 A", -200, -50, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(34, 197, 166, 255)
ELSIF ScoreDisplay >= 64 THEN
drawtext("Score: #ScoreRound#/100 B", -200, -50, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(34, 197, 166, 255)
ELSIF ScoreDisplay >= 52 THEN
drawtext("Score: #ScoreRound#/100 C", -200, -50, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(245, 189, 92, 255)
ELSE
drawtext("Score: #ScoreRound#/100 D", -200, -50, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(129, 140, 248, 255)
ENDIF
// --- Failure Risk ---
IF FailRiskRound >= MinRevScore THEN
drawtext("Failure Risk: #FailRiskRound#/100", -200, -70, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(34, 197, 166, 255)
ELSIF FailRiskRound >= WatchScoreMin THEN
drawtext("Failure Risk: #FailRiskRound#/100", -200, -70, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(245, 189, 92, 255)
ELSE
drawtext("Failure Risk: #FailRiskRound#/100", -200, -70, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(129, 140, 248, 255)
ENDIF
// --- Room (affiché seulement si setup actif) ---
IF ActiveValid AND ActiveState <> 2 THEN
drawtext("Room: #RoomAtrDisp# ATR", -200, -90, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(129, 140, 248, 255)
ELSE
drawtext("Room: -", -200, -90, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(148, 163, 184, 255)
ENDIF
// --- Action ---
IF ActiveValid AND ActiveState = 2 THEN
drawtext("Action: Invalidated", -200, -110, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(239, 68, 68, 255)
ELSIF ActiveValid AND ActiveTargetHit THEN
drawtext("Action: Target Review", -200, -110, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(129, 140, 248, 255)
ELSIF ActiveValid AND ActiveScore >= 78 THEN
drawtext("Action: Review Reversal", -200, -110, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(34, 197, 166, 255)
ELSIF ActiveValid THEN
drawtext("Action: Wait Pullback", -200, -110, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(148, 163, 184, 255)
ELSIF HadUpperAccept THEN
drawtext("Action: Watch Upper Fail", -200, -110, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(245, 189, 92, 255)
ELSIF HadLowerAccept THEN
drawtext("Action: Watch Lower Fail", -200, -110, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(245, 189, 92, 255)
ELSE
drawtext("Action: Stand Aside", -200, -110, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(148, 163, 184, 255)
ENDIF
// --- Détails techniques ---
drawtext("ATR: #MyAtr#", -200, -140, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(220, 150, 020, 255)
drawtext("Vol Ratio: #VolRatio#", -200, -160, Dialog, Bold,14) anchor(topright, xshift, yshift) coloured(220, 150, 020, 255)
ENDIF
// ---------------------------------------------------------
// COLORATION DES BARRES
// ---------------------------------------------------------
IF BullReady THEN
BACKGROUNDCOLOR(34, 197, 166, 80)
ENDIF
IF BearReady THEN
BACKGROUNDCOLOR(244, 114, 182, 80)
ENDIF
IF Invalidated THEN
BACKGROUNDCOLOR(239, 68, 68, 85)
ENDIF
// ---------------------------------------------------------
// RETURN UNIQUE (obligatoire en PRT)
// ---------------------------------------------------------
RETURN PlotBandTop COLOURED(129, 140, 248) AS "Band High", PlotBandBot COLOURED(129, 140, 248) AS "Band Low", PlotBandMid COLOURED(148, 163, 184) STYLE(dottedline, 1) AS "Anchor", r1x COLOURED(34, 197, 166) STYLE(dottedline, 2) AS "Trigger Rail", r2x COLOURED(239, 68, 68) STYLE(dottedline, 1) AS "Invalidation", r3x COLOURED(129, 140, 248) STYLE(line, 1) AS "Target Room"