// This Pine Script® code is licensed under Apache-2.0
// SPDX-License-Identifier: Apache-2.0
// © PineForge contributors 2026
//
// PF probe bos-curv-probe-01-swing-bos-trigger — pivot-based break-of-structure
// Clean-room: written from validation goal, not from source.
//
// Purpose: isolates a break-of-structure detector built on `ta.pivothigh` /
// `ta.pivotlow`. The engine surfaces under test are the pivot left/right
// confirmation logic and the cross-bar `var float` last-confirmed-pivot
// state used to detect a close-through-pivot break. BOS triggers are a
// staple of structural strategies; small differences in WHEN a pivot
// confirms (right-bar count) cascade into different break bars.
//
// Validation goal: bit-exact entries on the bar that closes above the most
// recently confirmed pivot high (long) or below the most recently confirmed
// pivot low (short). Pass = identical trade list vs TradingView.
//
// TV setup: 15m chart, ETH-USDT-USDT (Binance USDT-M Perpetual). Full window
// matching corpus/data/ohlcv_ETH-USDT-USDT_15m.csv. Strategy properties:
// leave defaults from script header. Export "List of trades" → tv_trades.csv.
//@version=6
strategy("PF probe bos-curv-probe-01-swing-bos-trigger", shorttitle="PF_bos01_BOS",
overlay=true, initial_capital=1000000,
commission_type=strategy.commission.percent, commission_value=0,
slippage=0, default_qty_type=strategy.fixed, default_qty_value=1,
pyramiding=1, process_orders_on_close=false)
// ---- inputs --------------------------------------------------------
int i_left = input.int(5, "Pivot left bars", minval=1)
int i_right = input.int(5, "Pivot right bars", minval=1)
// ---- pivot detection ----------------------------------------------
float ph = ta.pivothigh(high, i_left, i_right)
float pl = ta.pivotlow(low, i_left, i_right)
// ---- last-confirmed pivot state -----------------------------------
var float last_ph = na
var float last_pl = na
if not na(ph)
last_ph := ph
if not na(pl)
last_pl := pl
// ---- break detection (close through last pivot) -------------------
bool bos_long = not na(last_ph) and close > last_ph and close[1] <= nz(last_ph[1], last_ph)
bool bos_short = not na(last_pl) and close < last_pl and close[1] >= nz(last_pl[1], last_pl)
// ---- order routing ------------------------------------------------
if bos_long and strategy.position_size <= 0
strategy.entry("L", strategy.long, qty=1, comment="bos long")
if bos_short and strategy.position_size >= 0
strategy.entry("S", strategy.short, qty=1, comment="bos short")