Paste the complete source into TradingView Pine Editor and use standard one-minute candles with Regular trading hours selected on a US stock whose exchange timezone is America/New_York. R marks the completed entry-decision bar and F the failed-reclaim decision bar. The Data Window exposes the frozen reference, state and submitted attempt count. Compare those values with the timeline before interpreting a strategy report.
Original long-only research example. The final source passed Pineify syntax validation; syntax validation does not establish market performance or verify a chart feed.pine
//@version=6
strategy("Previous close reclaim research", overlay = true, initial_capital = 100000,
pyramiding = 0, margin_long = 100, commission_type = strategy.commission.cash_per_contract,
commission_value = 0.005, slippage = 1, process_orders_on_close = false,
calc_on_every_tick = false, calc_on_order_fills = false)
int maxAttempts = input.int(2, "Maximum entry attempts per session", minval = 1, maxval = 3)
int shares = input.int(100, "Shares per entry", minval = 1)
string zone = "America/New_York"
if barstate.isfirst
if not chart.is_standard or not timeframe.isminutes or timeframe.multiplier != 1
runtime.error("Use standard one-minute candles.")
if syminfo.type != "stock" or syminfo.timezone != zone or syminfo.session != session.regular
runtime.error("Use a US stock with New York exchange time and regular session selected.")
string regularTicker = ticker.modify(syminfo.tickerid, session = session.regular)
float priorClose = request.security(regularTicker, "1D", close[1], lookahead = barmerge.lookahead_on)
bool newSession = barstate.isfirst or time("1D") != time("1D")[1]
int openMinute = hour(time, zone) * 60 + minute(time, zone)
int closeMinute = hour(time_close, zone) * 60 + minute(time_close, zone)
// 0 WAIT, 1 ARMED, 2 ENTRY_PENDING, 3 LONG, 4 EXIT_PENDING, 5 DONE
var int state = 5
var int attempts = 0
var float baseline = na
bool entryDecision = false
bool failureDecision = false
if barstate.isconfirmed
if newSession
strategy.cancel_all()
baseline := priorClose
attempts := 0
state := openMinute == 570 and not na(baseline) and baseline > 0 ? 0 : 5
if strategy.position_size != 0
strategy.close_all(comment = "Residual position at new session")
state := 5
bool missingMinute = not newSession and time != time_close[1]
bool stopSession = missingMinute or closeMinute >= 660 or not session.ismarket
if stopSession
strategy.cancel_all()
if strategy.position_size > 0
strategy.close_all(comment = "Time or data exit")
state := 5
else if state != 5
if strategy.position_size > 0
state := 3
if close <= baseline
strategy.close("Long", comment = "Failed reclaim")
state := 4
failureDecision := true
else if state == 2
// No filled position at the next calculation: stop, do not keep resubmitting.
strategy.cancel_all()
state := 5
else if attempts >= maxAttempts
state := 5
else if state == 4
// Exit has filled. This flat bar can arm a fresh attempt, but cannot enter.
state := low < baseline ? 1 : 0
else if state == 0
if low < baseline
state := 1
else if state == 1 and close > baseline and close[1] <= baseline
strategy.entry("Long", strategy.long, qty = shares)
attempts += 1
state := 2
entryDecision := true
plot(baseline, "Frozen previous regular close", color = color.blue, style = plot.style_stepline)
plot(state, "State: 0 wait, 1 armed, 2 pending, 3 long, 4 exit, 5 done", display = display.data_window)
plot(attempts, "Attempts submitted", display = display.data_window)
plotshape(entryDecision, "Entry decision at bar close", shape.triangleup, location.belowbar, color.green, text = "R")
plotshape(failureDecision, "Failure decision at bar close", shape.xcross, location.abovebar, color.red, text = "F")