Set the mode, dates and parameters explicitly before adding this draft to a standard candle chart. It uses a prior-window fit, bar-close decisions and a bracket submitted with the entry. The signal-date filter uses bar opening time at or after the start and closing time strictly before the end. Earlier bars may supply warm-up data, but cannot open positions. The source passed Pineify syntax validation on October 17, 2026. Review its chart behavior and order timing before use; compilation alone does not establish numerical or execution accuracy.
Pine v6 research example; syntax checked October 17, 2026. No return or live-execution claim.pine
//@version=6
strategy("Frozen regression hypotheses", overlay=true, initial_capital=10000, default_qty_type=strategy.fixed, default_qty_value=10, pyramiding=0, commission_type=strategy.commission.percent, commission_value=0.05, slippage=1, margin_long=100, calc_on_every_tick=false, calc_on_order_fills=false, process_orders_on_close=false, max_bars_back=501)
mode = input.string("Breakout", "Hypothesis", options=["Breakout", "Reversion"])
n = input.int(20, "Fit bars", minval=3, maxval=500)
k = input.float(2.0, "Band multiplier", minval=0.5, step=0.5)
hold = input.int(10, "Maximum holding bars", minval=1)
startTime = input.time(timestamp("01 Jan 2024 00:00 +0000"), "Signal start")
endTime = input.time(timestamp("01 Jan 2025 00:00 +0000"), "Signal end (exclusive)")
// One fit from the n completed bars before the signal bar.
float meanX = (n - 1) / 2.0
float sumY = 0.0
float numerator = 0.0
bool valid = bar_index >= n
for x = 0 to n - 1
float y = close[n - x]
valid := valid and not na(y) and y > 0
sumY += y
numerator += (x - meanX) * y
float slope = numerator / (n * (n * n - 1) / 12.0)
float intercept = sumY / n - slope * meanX
float sse = 0.0
for x = 0 to n - 1
float residual = close[n - x] - (intercept + slope * x)
sse += residual * residual
float d = math.sqrt(sse / n)
float center = intercept + slope * n
float upper = center + k * d
float lower = center - k * d
float previousUpper = intercept + slope * (n - 1) + k * d
valid := valid and d >= syminfo.mintick
bool breakout = valid and slope > 0 and close[1] <= previousUpper and close > upper
bool reversion = valid and low <= lower and close > lower and close < center
float rawStop = mode == "Breakout" ? center : lower - d
float rawTarget = mode == "Breakout" ? upper + 2 * d : center
float stopPrice = math.floor(rawStop / syminfo.mintick) * syminfo.mintick
float targetPrice = math.floor(rawTarget / syminfo.mintick) * syminfo.mintick
bool selected = mode == "Breakout" ? breakout : reversion
bool inDates = time >= startTime and time_close < endTime
bool exitedThisBar = strategy.closedtrades > nz(strategy.closedtrades[1])
var float frozenStop = na
var float frozenTarget = na
bool signal = barstate.isconfirmed and inDates and strategy.position_size == 0 and not exitedThisBar and selected and stopPrice > 0 and stopPrice < close and close < targetPrice
if signal
frozenStop := stopPrice
frozenTarget := targetPrice
strategy.entry("Long", strategy.long)
strategy.exit("Bracket", "Long", stop=frozenStop, limit=frozenTarget)
if strategy.position_size > 0
strategy.exit("Bracket", "Long", stop=frozenStop, limit=frozenTarget)
int barsHeld = bar_index - strategy.opentrades.entry_bar_index(0) + 1
bool gapOutside = strategy.position_avg_price <= frozenStop or strategy.position_avg_price >= frozenTarget
if gapOutside or barsHeld >= hold or time_close >= endTime
strategy.close("Long", comment="Gap, time or date exit")
plot(valid ? center : na, "Prior-fit projection", color=color.gray)
plot(valid ? upper : na, "Prior-fit upper", color=color.blue)
plot(valid ? lower : na, "Prior-fit lower", color=color.blue)
plot(strategy.position_size > 0 or signal ? frozenStop : na, "Frozen stop", color=color.red, style=plot.style_linebr)
plot(strategy.position_size > 0 or signal ? frozenTarget : na, "Frozen target", color=color.green, style=plot.style_linebr)
plotshape(signal, title="Confirmed signal", style=shape.triangleup, location=location.belowbar, color=color.blue, size=size.tiny)