diff --git a/tests/gate-corpus/ok/AAPL__session-ismarket-nyse-rth-01.pine b/tests/gate-corpus/ok/AAPL__session-ismarket-nyse-rth-01.pine deleted file mode 100644 index ff93ace..0000000 --- a/tests/gate-corpus/ok/AAPL__session-ismarket-nyse-rth-01.pine +++ /dev/null @@ -1,16 +0,0 @@ -// TV_RUN_NEEDED: tv_trades.csv missing — capture in TradingView: -// Symbol: AAPL TF: 5m Range: 2024-01-02..2024-03-29 -// Save List of Trades → tv_trades.csv in this directory. - -//@version=6 -strategy("Session ismarket NYSE RTH gate", overlay=true, - default_qty_type=strategy.fixed, default_qty_value=1) - -// Only trade when inside NYSE regular trading hours (09:30–16:00 ET). -// session.ismarket uses syminfo.session which the validator injects via -// syminfo_overrides → session = "0930-1600". -if session.ismarket - if ta.crossover(ta.sma(close, 9), ta.sma(close, 21)) - strategy.entry("Long", strategy.long) - if ta.crossunder(ta.sma(close, 9), ta.sma(close, 21)) - strategy.close("Long") diff --git a/tests/gate-corpus/ok/AAPL__time-tradingday-daily-reset-counter-01.pine b/tests/gate-corpus/ok/AAPL__time-tradingday-daily-reset-counter-01.pine deleted file mode 100644 index 94a9c02..0000000 --- a/tests/gate-corpus/ok/AAPL__time-tradingday-daily-reset-counter-01.pine +++ /dev/null @@ -1,44 +0,0 @@ -// TV_RUN_NEEDED: tv_trades.csv missing — capture in TradingView: -// Symbol: AAPL TF: 30m Range: 2024-01-01..2024-06-01 -// Save List of Trades → tv_trades.csv in this directory. -// -// This Pine Script® code is licensed under Apache-2.0 -// SPDX-License-Identifier: Apache-2.0 -// © PineForge contributors 2026 -// -// Parity probe: time_tradingday — daily trade-counter reset -// -// Purpose: Verify that ta.change(time_tradingday) fires exactly once per -// NYSE RTH session open (09:30 ET), resetting a daily trade counter. -// Counter even → go long; counter odd → close position. -// -// Uses AAPL on 30 m bars with the default NYSE session ("0930-1600:23456") -// so that time_tradingday advances at each new RTH open. - -//@version=6 -strategy("time_tradingday daily reset counter", - overlay=true, - default_qty_type=strategy.fixed, - default_qty_value=1, - initial_capital=10000, - commission_type=strategy.commission.percent, - commission_value=0.0) - -// Count how many entries (long+flat signals) we have fired today. -// Reset at each new trading day. -var int daily_counter = 0 - -bool new_trading_day = ta.change(time_tradingday) != 0 - -if new_trading_day - daily_counter := 0 - -// Even counter → long entry; odd counter → close. -if daily_counter % 2 == 0 - if strategy.position_size == 0 - strategy.entry("L", strategy.long) - daily_counter += 1 -else - if strategy.position_size > 0 - strategy.close("L") - daily_counter += 1 diff --git a/tests/gate-corpus/ok/QQQ__session-ispremarket-nasdaq-01.pine b/tests/gate-corpus/ok/QQQ__session-ispremarket-nasdaq-01.pine deleted file mode 100644 index 84dad3d..0000000 --- a/tests/gate-corpus/ok/QQQ__session-ispremarket-nasdaq-01.pine +++ /dev/null @@ -1,16 +0,0 @@ -// TV_RUN_NEEDED: tv_trades.csv missing — capture in TradingView: -// Symbol: QQQ TF: 5m Range: 2024-01-02..2024-03-29 -// Save List of Trades → tv_trades.csv in this directory. - -//@version=6 -strategy("Session ispremarket NASDAQ gate", overlay=true, - default_qty_type=strategy.fixed, default_qty_value=1) - -// Enter long during premarket (04:00–09:30 ET) on bullish momentum; -// flatten at market open. -if session.ispremarket - if close > open - strategy.entry("PreLong", strategy.long) - -if session.ismarket - strategy.close_all() diff --git a/tests/gate-corpus/ok/SPY__session-firstbar-vwap-anchor-01.pine b/tests/gate-corpus/ok/SPY__session-firstbar-vwap-anchor-01.pine deleted file mode 100644 index 270ccf7..0000000 --- a/tests/gate-corpus/ok/SPY__session-firstbar-vwap-anchor-01.pine +++ /dev/null @@ -1,29 +0,0 @@ -// TV_RUN_NEEDED: tv_trades.csv missing — capture in TradingView: -// Symbol: SPY TF: 5m Range: 2024-01-02..2024-03-29 -// Save List of Trades → tv_trades.csv in this directory. - -//@version=6 -strategy("Session isfirstbar VWAP anchor", overlay=true, - default_qty_type=strategy.fixed, default_qty_value=1) - -// Anchor VWAP to the first bar of each trading session using session.isfirstbar. -// Buy when close crosses above session VWAP; sell when it crosses below. - -var float cum_pv = 0.0 -var float cum_vol = 0.0 - -if session.isfirstbar - cum_pv := 0.0 - cum_vol := 0.0 - -if session.ismarket - cum_pv := cum_pv + hlc3 * volume - cum_vol := cum_vol + volume - -session_vwap = cum_vol > 0 ? cum_pv / cum_vol : close - -if session.ismarket - if ta.crossover(close, session_vwap) - strategy.entry("Long", strategy.long) - if ta.crossunder(close, session_vwap) - strategy.close("Long") diff --git a/tests/gate-corpus/ok/SPY__session-lastbar-flatten-01.pine b/tests/gate-corpus/ok/SPY__session-lastbar-flatten-01.pine deleted file mode 100644 index 05c868b..0000000 --- a/tests/gate-corpus/ok/SPY__session-lastbar-flatten-01.pine +++ /dev/null @@ -1,19 +0,0 @@ -// TV_RUN_NEEDED: tv_trades.csv missing — capture in TradingView: -// Symbol: SPY TF: 5m Range: 2024-01-02..2024-03-29 -// Save List of Trades → tv_trades.csv in this directory. - -//@version=6 -strategy("Session islastbar flatten", overlay=true, - default_qty_type=strategy.fixed, default_qty_value=1) - -// Enter on SMA crossover within session; flatten all positions on the -// last bar of the session (session.islastbar) to avoid overnight holds. - -if session.ismarket - if ta.crossover(ta.sma(close, 9), ta.sma(close, 21)) - strategy.entry("Long", strategy.long) - -// Flatten on last session bar — session.islastbar_regular == session.islastbar -// in engine (single session string; see session_time.hpp limitation comment). -if session.islastbar - strategy.close_all() diff --git a/tests/gate-corpus/ok/crypto-htf__mtf-htf-monthly-ema-cross-01.pine b/tests/gate-corpus/ok/crypto-htf__mtf-htf-monthly-ema-cross-01.pine deleted file mode 100644 index 8a76289..0000000 --- a/tests/gate-corpus/ok/crypto-htf__mtf-htf-monthly-ema-cross-01.pine +++ /dev/null @@ -1,26 +0,0 @@ -// This Pine Script® code is licensed under Apache-2.0 -// SPDX-License-Identifier: Apache-2.0 -// © PineForge contributors 2026 -// -// PF MTF-isolate probe — monthly ("M") HTF EMA(6) via request.security. -// Isolates CALENDAR-MONTH aggregation: unlike "60"/"240"/"D" (fixed-width -// HTF buckets), the "M" timeframe rolls on variable-length calendar months -// (28–31 days, DST-agnostic). This exercises the engine's HTF bucket-boundary -// detection for irregular periods end-to-end. The HTF EMA(6) is computed -// INSIDE the request.security context so EMA state advances once per closed -// month, then is held flat across every intraday bar of that month. Trades -// fire when the LTF close crosses the held monthly EMA — any month-boundary -// or roll/seed drift surfaces as extra/early/missing crossings. -//@version=6 -strategy("PF MTF isolate - monthly EMA(6) cross", shorttitle="MTF_MEMA", - overlay=true, initial_capital=1000000, currency=currency.USD, - 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) - -float mema = request.security(syminfo.tickerid, "M", ta.ema(close, 6), lookahead=barmerge.lookahead_off) - -if ta.crossover(close, mema) - strategy.entry("L", strategy.long, comment="close x-over monthly EMA") -if ta.crossunder(close, mema) - strategy.entry("S", strategy.short, comment="close x-under monthly EMA") diff --git a/tests/gate-corpus/ok/crypto-leverage__leverage-margin-call-perp-5x-01.pine b/tests/gate-corpus/ok/crypto-leverage__leverage-margin-call-perp-5x-01.pine deleted file mode 100644 index 609534e..0000000 --- a/tests/gate-corpus/ok/crypto-leverage__leverage-margin-call-perp-5x-01.pine +++ /dev/null @@ -1,54 +0,0 @@ -// This Pine Script® code is licensed under Apache-2.0 -// SPDX-License-Identifier: Apache-2.0 -// © PineForge contributors 2026 -// -// leverage-margin-call-perp-5x-01 — forced-liquidation / margin-call probe. -// -// Purpose: isolate TradingView's broker-emulator FORCED LIQUIDATION -// (margin call) behavior for an IN-POSITION long held through an adverse -// move at 5x leverage. The strategy declaration sets -// `margin_long=20, margin_short=20` (20% required margin == 5x leverage). -// A single, oversized long is entered once near the start of the feed and -// then NEVER exited by the script. If price falls far enough that the -// position's losses exhaust the posted margin, TradingView's emulator -// injects a "Margin Call" exit row that the script itself never issued. -// -// The PineForge engine currently has no in-position liquidation path: it -// holds the entry indefinitely and produces no margin-call exit. This -// probe is EXPECTED TO EXPOSE that gap — the divergence (TV emits a -// Margin Call exit, engine does not) is the finding, not a bug to mask. -// When exporting TV's List of Trades, be sure to capture the rows whose -// Type / Signal is "Margin Call" (TV labels the forced exit explicitly). -// -// Logic is intentionally minimal: one large fixed-qty long on the first -// bar after warmup, sized so that a routine adverse 15m perp move at 5x -// can wipe the margin. No exit, no pyramiding beyond the single entry. -// -// TV setup: 15m chart on BINANCE:ETHUSDT.P (Binance USDT-M perpetual). -// Set the Strategy Tester margin to 20% long / 20% short to match the -// `margin_long=20, margin_short=20` declaration (TV reads these from the -// script header, but verify the Properties tab shows 20/20). Export -// "List of Trades" — INCLUDING the Margin Call row — to tv_trades.csv. -//@version=6 -strategy("leverage-margin-call-perp-5x-01", shorttitle="lev_mc5x", - overlay=true, initial_capital=1000000, currency=currency.USD, - 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, - margin_long=20, margin_short=20) - -// ---- one early, oversized long held with NO exit -------------------- -// Enter once: first bar at/after bar_index 50 (post-warmup) while flat. -// qty is sized to ~5x notional of initial_capital so a modest adverse -// move exhausts the 20% margin and triggers TV's forced liquidation. -bool fire = bar_index >= 50 and strategy.position_size == 0 and strategy.closedtrades == 0 - -// Notional target ≈ 5 × initial_capital; qty = target_notional / close. -float target_notional = 5000000.0 -float qty_lev = math.round(target_notional / close * 1000) / 1000 - -if fire and qty_lev > 0 - strategy.entry("LEV", strategy.long, qty=qty_lev, comment="5x held long, no exit") - -// No strategy.close / strategy.exit anywhere: the only way this position -// can leave the book is TradingView's forced-liquidation (Margin Call). diff --git a/tests/gate-corpus/ok/forex__symbol-fx-5dp-eurusd-01.pine b/tests/gate-corpus/ok/forex__symbol-fx-5dp-eurusd-01.pine deleted file mode 100644 index d9a8531..0000000 --- a/tests/gate-corpus/ok/forex__symbol-fx-5dp-eurusd-01.pine +++ /dev/null @@ -1,32 +0,0 @@ -// This Pine Script® code is licensed under Apache-2.0 -// SPDX-License-Identifier: Apache-2.0 -// © PineForge contributors 2026 -// -// PF symbol/FX 5-decimal probe — plain SMA(20) vs SMA(50) crossover on a -// 5-dp forex instrument (OANDA:EURUSD, mintick 0.00001). Isolates two things -// the ETH-USDT feed cannot exercise: -// 1. 5-decimal price scale (prices ~1.0xxxx, not ~1800), so any latent -// assumption about price magnitude / tick granularity surfaces. -// 2. Sub-pip slippage rounding: slippage=2 ticks * mintick 0.00001 = 0.00002 -// added/subtracted at fill, which must round to the 5th decimal exactly. -// strategy.close on the opposite signal keeps the position flat-or-long/flat- -// or-short with no pyramiding, so each fill is a clean single-leg adjudication. -//@version=6 -strategy("PF FX 5dp - SMA20/50 cross", shorttitle="FX5DP", - overlay=true, initial_capital=1000000, currency=currency.USD, - commission_type=strategy.commission.percent, commission_value=0, slippage=2, - default_qty_type=strategy.fixed, default_qty_value=1, pyramiding=1, - process_orders_on_close=false) - -fast = ta.sma(close, 20) -slow = ta.sma(close, 50) - -longCond = ta.crossover(fast, slow) -shortCond = ta.crossunder(fast, slow) - -if longCond - strategy.close("S", comment="close short") - strategy.entry("L", strategy.long, comment="sma cross up") -if shortCond - strategy.close("L", comment="close long") - strategy.entry("S", strategy.short, comment="sma cross dn") diff --git a/tests/gate-corpus/ok/futures__symbol-futures-pointvalue-es-01.pine b/tests/gate-corpus/ok/futures__symbol-futures-pointvalue-es-01.pine deleted file mode 100644 index a691400..0000000 --- a/tests/gate-corpus/ok/futures__symbol-futures-pointvalue-es-01.pine +++ /dev/null @@ -1,36 +0,0 @@ -// This Pine Script® code is licensed under Apache-2.0 -// SPDX-License-Identifier: Apache-2.0 -// © PineForge contributors 2026 -// -// Parity probe: ES futures point-value PnL multiplier + 0.25-tick snap. -// -// Purpose: Isolate the per-instrument PnL scaling on a real CME futures -// contract. CME_MINI:ES1! has syminfo.pointvalue = 50 (USD per index -// point per contract) and syminfo.mintick = 0.25. With 1-contract fixed -// sizing, cash_per_contract commission ($2.10/contract) and slippage=1 -// tick, every closed trade's gross PnL must equal -// (exit_px - entry_px) * 50 and fills must snap to 0.25 boundaries. -// Plain SMA(9)/SMA(21) cross drives flat-to-long/long-to-flat so the -// trade set is deterministic and the PnL multiplier is the only moving -// part vs. the default crypto (pointvalue=1, mintick=0.01) behaviour. - -//@version=6 -strategy("ES point-value 9/21 SMA cross", - initial_capital=1000000, - currency=currency.USD, - commission_type=strategy.commission.cash_per_contract, - commission_value=2.10, - slippage=1, - default_qty_type=strategy.fixed, - default_qty_value=1, - pyramiding=1, - process_orders_on_close=false) - -fast = ta.sma(close, 9) -slow = ta.sma(close, 21) - -if ta.crossover(fast, slow) - strategy.entry("L", strategy.long) - -if ta.crossunder(fast, slow) - strategy.close("L") diff --git a/tests/gate-corpus/ok/us-equity__symbol-equity-rth-gaps-aapl-01.pine b/tests/gate-corpus/ok/us-equity__symbol-equity-rth-gaps-aapl-01.pine deleted file mode 100644 index abf78b1..0000000 --- a/tests/gate-corpus/ok/us-equity__symbol-equity-rth-gaps-aapl-01.pine +++ /dev/null @@ -1,34 +0,0 @@ -// This Pine Script® code is licensed under Apache-2.0 -// SPDX-License-Identifier: Apache-2.0 -// © PineForge contributors 2026 -// -// Isolates: US-equity regular-trading-hours (RTH) session gating combined with -// overnight gap handling on a 5m intraday feed. Plain RSI(14) oversold/overbought -// crosses (30/70) drive entries, but every order is gated by session.ismarket so -// only bars inside NYSE/NASDAQ regular hours (09:30–16:00 ET) can trade. This -// exercises the exchange-tz (America/New_York) vs chart-tz day boundary, the RTH -// session filter, and how the engine treats the overnight gap between the prior -// 16:00 close and the next 09:30 open (RSI series continuity across the gap). - -//@version=6 -strategy("Symbol equity RTH + overnight gaps AAPL", overlay=true, - initial_capital=1000000, currency=currency.USD, - 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) - -// RSI(14) on close — series spans the overnight gap continuously (no per-day -// reset), so the cross can latch on the first RTH bar after the gap. -rsiVal = ta.rsi(close, 14) - -// Only act on bars inside regular trading hours. session.ismarket is backed by -// syminfo.session, injected by the harness via runtime_overrides.session = -// "0930-1600" with timezone America/New_York. -inRth = session.ismarket - -// Oversold cross up 30 → long; overbought cross down 70 → flat. Gated by RTH. -if inRth and ta.crossover(rsiVal, 30) - strategy.entry("Long", strategy.long) - -if inRth and ta.crossunder(rsiVal, 70) - strategy.close("Long") diff --git a/tests/gate-corpus/ok/us-equity__us-equity-exchange-tz-intraday-cap-01.pine b/tests/gate-corpus/ok/us-equity__us-equity-exchange-tz-intraday-cap-01.pine deleted file mode 100644 index ad08fda..0000000 --- a/tests/gate-corpus/ok/us-equity__us-equity-exchange-tz-intraday-cap-01.pine +++ /dev/null @@ -1,30 +0,0 @@ -// This Pine Script® code is licensed under Apache-2.0 -// SPDX-License-Identifier: Apache-2.0 -// © PineForge contributors 2026 -// -// PF probe (SCAFFOLD) — US-equity intraday-cap day rollover on a REAL session -// (#19 / #26). BLOCKED: needs a real RTH US-equity intraday OHLCV feed in -// corpus/data/ AND a matching TradingView export. See README. -// -// Purpose: validate that max_intraday_filled_orders resets on the EXCHANGE -// trading day for a real-session instrument. The engine keys the gate off -// chart_timezone_ (deliberate — probe-97 crypto evidence); for US equities -// the serving layer pins chart_timezone_ = America/New_York. This probe is -// the missing evidence that chart_tz pinning yields the correct rollover when -// chart_tz != UTC and the symbol has a real 09:30-16:00 session with -// overnight gaps. -// -//@version=6 -strategy("US-equity intraday cap (scaffold)", overlay=true, initial_capital=1000000, currency=currency.USD, process_orders_on_close=false, pyramiding=0, default_qty_type=strategy.fixed, default_qty_value=1) - -// Cap is a strategy.risk.* call in the body, NOT a strategy() parameter. -strategy.risk.max_intraday_filled_orders(5) - -// Plain dual-MA crossover — the cap is the surface under test. -fast = ta.sma(close, 9) -slow = ta.sma(close, 21) - -if ta.crossover(fast, slow) - strategy.entry("Long", strategy.long) -if ta.crossunder(fast, slow) - strategy.entry("Short", strategy.short)