//
@version=6
strategy(
title="USTEC NY AM FV No Max Trades No Wait BOS 3 Candles",
overlay=true,
max_labels_count=500,
max_lines_count=500,
pyramiding=0,
process_orders_on_close=true,
initial_capital=100000,
currency=currency.USD,
default_qty_type=strategy.fixed,
default_qty_value=0.1,
margin_long=1,
margin_short=1
)
// =====================
// INPUTS
// =====================
tz = input.string("America/New_York", "Timezone")
// NY AM ONLY
nyOpenHour =
input.int(9, "NY AM Open Hour", minval=0, maxval=23)
nyOpenMinute =
input.int(30, "NY AM Open Minute", minval=0, maxval=59)
// No first 3-minute wait.
// Strategy can trade from 9:30 onward.
continuationEnd =
input.int(10, "Continuation Ends After Minutes", minval=1)
// 9:30 to 11:00 = 90 minutes
sessionEndMinutes =
input.int(90, "Stop Trading After Minutes", minval=10)
closeAtSessionEnd = input.bool(true, "Close Open Trade At 11:00 NY Time")
// BOS fixed to last 3 candles
bosLookback = 3
maxCounterWick = input.float(0.20, "Max Counter Wick %", minval=0.01, maxval=0.50, step=0.01)
minBodyPercent = input.float(0.50, "Minimum Body %", minval=0.10, maxval=1.00, step=0.05)
atrLength =
input.int(14, "ATR Length")
// ATR FILTER
useMinATR = input.bool(true, "Do Not Trade If ATR Is Below Minimum")
minATRToTrade = input.float(8.0, "Minimum ATR To Trade", minval=0.0, step=0.5)
// RISK MODEL
riskReward = input.float(2.0, "Take Profit R Multiple", minval=0.5, step=0.1)
requireRoomToFairValue = input.bool(false, "Reversion Requires Room To Fair Value")
qty = input.float(0.1, "Position Size", minval=0.01, step=0.01)
showLabels = input.bool(true, "Show Buy/Sell Labels")
showSLTP = input.bool(true, "Show Entry / SL / TP Lines")
showSessionLabels = input.bool(true, "Show NY AM Open Label")
lineLength =
input.int(25, "Line Length", minval=5, maxval=100)
buyLabelOffset =
input.int(1, "Buy Label Offset Right", minval=0, maxval=20)
sellLabelOffset =
input.int(1, "Sell Label Offset Left", minval=0, maxval=20)
// =====================
// TIME LOGIC
// =====================
h = hour(time, tz)
m = minute(time, tz)
// Only reset at NY AM 9:30
isNYAMOpen = h == nyOpenHour and m == nyOpenMinute
newSession = isNYAMOpen
// =====================
// SESSION STATE
// =====================
var float fairValue = na
var int sessionStartBar = na
var int openingDirection = 0
if newSession
fairValue := open
sessionStartBar := bar_index
openingDirection := close >= open ? 1 : -1
if showSessionLabels
label.new(
x=bar_index,
y=open,
text="NY AM FV RESET\n09:30 Open: " str.tostring(open, format.mintick),
xloc=
xloc.bar_index,
style=
label.style_label_down,
color=color.yellow,
textcolor=
color.black
)
barsFromOpen = not na(sessionStartBar) ? bar_index - sessionStartBar : na
// NY AM trading window: 9:30 to 11:00
inTradingWindow = not na(barsFromOpen) and barsFromOpen >= 0 and barsFromOpen <= sessionEndMinutes
inContinuationWindow = inTradingWindow and barsFromOpen <= continuationEnd
inReversionWindow = inTradingWindow and barsFromOpen > continuationEnd
sessionExpired = not na(barsFromOpen) and barsFromOpen > sessionEndMinutes
// =====================
// CANDLE STRENGTH / DISPLACEMENT
// =====================
candleRange = high - low
body = math.abs(close - open)
bodyPercent = candleRange > 0 ? body / candleRange : 0.0
bullCounterWick = candleRange > 0 ? (high - close) / candleRange : 1.0
bearCounterWick = candleRange > 0 ? (close - low) / candleRange : 1.0
bullDisplacement = close > open and bullCounterWick <= maxCounterWick and bodyPercent >= minBodyPercent
bearDisplacement = close < open and bearCounterWick <= maxCounterWick and bodyPercent >= minBodyPercent
// =====================
// BREAK OF STRUCTURE — ONLY LAST 3 CANDLES
// =====================
priorHigh = ta.highest(high[1], bosLookback)
priorLow = ta.lowest(low[1], bosLookback)
bullBOS = close > priorHigh
bearBOS = close < priorLow
bullSetup = bullDisplacement and bullBOS
bearSetup = bearDisplacement and bearBOS
// =====================
// ATR STOP BUCKETS ATR FILTER
// =====================
atr = ta.atr(atrLength)
atrOK = not useMinATR or atr >= minATRToTrade
// NORMAL STOP LOSS
stopPoints = atr > 20 ? 50.0 : atr >= 7 ? 25.0 : 16.5
// TP = 2R by default
targetPoints = stopPoints * riskReward
// =====================
// SIGNAL RULES
// =====================
// Continuation:
// 9:30–9:40 by default.
buyContinuation = inContinuationWindow and openingDirection == 1 and close > fairValue and bullSetup
sellContinuation = inContinuationWindow and openingDirection == -1 and close < fairValue and bearSetup
// Reversion:
// after 9:40 until 11:00.
longRoomOK = not requireRoomToFairValue or fairValue >= close stopPoints
shortRoomOK = not requireRoomToFairValue or fairValue <= close - stopPoints
buyReversion = inReversionWindow and close < fairValue and bullSetup and longRoomOK
sellReversion = inReversionWindow and close > fairValue and bearSetup and shortRoomOK
flat = strategy.position_size == 0
// No max-trades rule.
// It can keep taking trades as long as it is flat and inside NY AM window.
canTrade = barstate.isconfirmed and flat and atrOK and inTradingWindow
buySignal = canTrade and (buyContinuation or buyReversion)
sellSignal = canTrade and (sellContinuation or sellReversion)
// =====================
// PLOTS
// =====================
plot(fairValue, title="NY AM Fair Value Open", color=color.yellow, linewidth=2, style=
plot.style_linebr)
bgcolor(inContinuationWindow ?
color.new(
color.green, 92) : na)
bgcolor(inReversionWindow ?
color.new(
color.orange, 92) : na)
// =====================
// BUY ORDER
// =====================
if buySignal
entryPrice = close
stopPrice = entryPrice - stopPoints
targetPrice = entryPrice targetPoints
reason = buyContinuation ? "CONTINUATION" : "REVERSION"
strategy.entry(id="BUY", direction=strategy.long, qty=qty)
strategy.exit(id="BUY EXIT", from_entry="BUY", stop=stopPrice, limit=targetPrice)
if showLabels
label.new(
x=bar_index buyLabelOffset,
y=low,
text="BUY\nNY AM " reason "\nBOS: Last 3 candles\nEntry: " str.tostring(entryPrice, format.mintick) "\nSL: " str.tostring(stopPrice, format.mintick) "\nTP " str.tostring(riskReward) "R: " str.tostring(targetPrice, format.mintick) "\nATR: " str.tostring(atr, "#.##"),
xloc=
xloc.bar_index,
style=
label.style_label_left,
color=color.lime,
textcolor=
color.black
)
if showSLTP
line.new(x1=bar_index, y1=entryPrice, x2=bar_index lineLength, y2=entryPrice, xloc=
xloc.bar_index, color=color.lime, style=
line.style_dotted)
line.new(x1=bar_index, y1=stopPrice, x2=bar_index lineLength, y2=stopPrice, xloc=
xloc.bar_index, color=
color.red)
line.new(x1=bar_index, y1=targetPrice, x2=bar_index lineLength, y2=targetPrice, xloc=
xloc.bar_index, color=
color.green)
// =====================
// SELL ORDER
// =====================
if sellSignal
entryPrice = close
stopPrice = entryPrice stopPoints
targetPrice = entryPrice - targetPoints
reason = sellContinuation ? "CONTINUATION" : "REVERSION"
strategy.entry(id="SELL", direction=strategy.short, qty=qty)
strategy.exit(id="SELL EXIT", from_entry="SELL", stop=stopPrice, limit=targetPrice)
if showLabels
label.new(
x=bar_index - sellLabelOffset,
y=high,
text="SELL\nNY AM " reason "\nBOS: Last 3 candles\nEntry: " str.tostring(entryPrice, format.mintick) "\nSL: " str.tostring(stopPrice, format.mintick) "\nTP " str.tostring(riskReward) "R: " str.tostring(targetPrice, format.mintick) "\nATR: " str.tostring(atr, "#.##"),
xloc=
xloc.bar_index,
style=
label.style_label_right,
color=
color.red,
textcolor=color.white
)
if showSLTP
line.new(x1=bar_index, y1=entryPrice, x2=bar_index lineLength, y2=entryPrice, xloc=
xloc.bar_index, color=
color.red, style=
line.style_dotted)
line.new(x1=bar_index, y1=stopPrice, x2=bar_index lineLength, y2=stopPrice, xloc=
xloc.bar_index, color=
color.red)
line.new(x1=bar_index, y1=targetPrice, x2=bar_index lineLength, y2=targetPrice, xloc=
xloc.bar_index, color=
color.green)
// =====================
// NY AM SESSION END FLATTEN
// =====================
if closeAtSessionEnd and sessionExpired and strategy.position_size != 0
strategy.close_all(comment="NY AM 11:00 Close")
// =====================
// ALERTS
// =====================
alertcondition(buySignal, title="BUY NY AM BOS 3", message="USTEC NY AM BUY signal. BOS uses last 3 candles.")
alertcondition(sellSignal, title="SELL NY AM BOS 3", message="USTEC NY AM SELL signal. BOS uses last 3 candles.")