Repository navigation
Pine adapter: the same-pass position view after a close fill, the close's owed follow-up, open-marketable exits first, and same-side global exits, pinned by TradingView controls - #347
Merged
Conversation
…sition view Under process_orders_on_close, exit() fills a re-issued strategy.exit of a one-lot short whose stop or limit is already through the bar's close at the call (its current-close path, execute_current). Unlike an ordinary close_all (KI-64), it did not freeze the script's position view, so the rest of the pass read strategy.position_size == 0 and a reset strategy.position_avg_price. A late observer, strategy.position_size[1] < 0 and strategy.position_size == 0, then fired one bar early, and an exit cooldown blocked the next bar's entry. The scraped job-2947 probe on BINANCE:ETHUSDT.P 15 lost its 2026-01-08 23:30 UTC short and every later trade this way. TradingView fills that exit at the close, after the pass: the pass keeps the pre-fill size and average. The adapter now freezes the script's position view before it executes the exit, as close_all does. Once the fill has left the book flat, the generated strategy.position_avg_price read (position_entry_price_ behind a non-zero signed_position_size()) keeps the pre-fill average until the pass ends. PineStrategyHost:: hold_script_average_price writes it, and release_script_average_price restores the flat book's 0 right after on_source_bar, before the orders the pass placed settle. No codegen change. Each part has its own switch, PoocCloseFillViewSwitches:: current_exit_keeps_position_view and current_exit_keeps_average_price (on; tests clear them). Both act only at that call site. close_all's own average read and the intraday-cap close at the call are unchanged. Pinned by 15 synthetic lab tv --no-note controls on BINANCE:ETHUSDT.P 15m, 2026-01-08..10. Each was exported twice, the two exports are byte-identical, rangeProof is covered on both, and every prediction was written before its export: 0 TradingView counterexamples. tests/fixtures/pooc_close_fill_view holds 11 of them with their frozen generated strategies (codegen c1df8a6): - Nine equal TradingView row for row, entry ids included. These are the re-issued stop exit's size read, its cooldown observer, its ATR-stop cooldown at 100 % of equity, its average read and its limit leg, plus the long mirror, strategy.close, close_all and a first-issue exit, which never moved. - Two are known divergences the rule leaves open. close_all's average read is AVGPRE on TradingView and AVGOTHER in the engine. After the re-issued exit, TradingView keeps the pre-fill strategy.opentrades, closedtrades, openprofit, netprofit and equity; the engine reads them after the fill. test_pooc_close_fill_view_tapes clears each part and requires the departures recorded in switch_off_departures.json. The average part moves 2 tapes; the view part moves the 5 re-issued short tapes. It also requires every tape's stream to equal its backtest with both parts on and off. Last, it records every tape's per-bar broker-state hash with the average part on and off: position_entry_price_ is hashed, so the hashes must be equal wherever the trades are, and otherwise first differ after the exit bar's fold. A hold that outlived its pass fails it: with the release_script_average_price() call removed, the trades stay the same and the hashes of the re-issued exit tapes differ from the exit bar's fold on. The four cooldown controls of tests/fixtures/margin_call_rules stay equal. Fail-before: the test module does not compile against the parent tree (pooc_close_fill_view_switches is not a member of detail). With both parts cleared, the five re-issued short tapes depart from TradingView, as on the parent. Whole-suite per-run trade dumps (%.17g, every field) against the parent: the dumps cover 670 processes and 56,558 runs. Every pre-existing run-pass keeps its trades with both parts on and with both off. The only differences are the new test, the repetition counts of timing-calibrated loops and the run order of a test that runs two hosts on two threads; their distinct runs are identical. No witness re-pin. The transient flag is waived in broker_state_hash_waivers.txt: it is false at every fold. Documentation anchors into the four edited files are carried by an exact line map from the parent (245 moved, 0 stuck). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…frozen close sizes and their over-fill lot, and the open's lot-by-lot follow-up
R-A (MarginScheduleSwitches::close_follow_up_after_script): a carried
process_orders_on_close short's lagged follow-up owed to its bar's close is
held through the close's own check (rule 7 still drops it where the close is
short) and booked after the script, ahead of the close's fills, at the same
print. A strategy.close(id) of the whole one-lot book (flush_pending_closes)
or a close_all() placed there keeps the size the script saw: a transaction
that crosses zero and opens the excess as a lot of its own, under the close
order's label. That lot is credited to the close ledger and the pyramiding
records ahead of the entry beside it, so the next open's nameless margin
calls take it first in first out, as the kernel does from the book, and a
later strategy.close of that entry closes all of the entry's units. A
reversal entry's excess joins its own lot (apply_frozen_reversal_close).
Partial closes, closes of several lots and the twin outside
process_orders_on_close keep today's sizing (margin_schedule_rules
frozen/close-id stays a known divergence). No tape runs pyramiding above 1,
so the pyramiding-record credit is unexercised.
Beside that lot only a market entry filling at the close it was placed at is
exempt: from the pyramiding-0 refusal, and a default-sized one from the
fill-time affordability check too (a scraped OANDA:EURUSD 15 probe, job-2550,
2026-04-09 01:45 UTC: TradingView fills a default-sized "LONG" of 18624.97
beside the 0.56 over-fill lot). Priced entries and later fills keep every
gate; no tape decides those shapes. One of them changes against the parent
tree, which opens no over-fill lot: an explicit stop entry placed at that
close at pyramiding 0 fills on the next bar there, and is refused here as a
same-side add beside the lot.
R-B (MarginOpeningSwitches::lot_by_lot_open_follow_up): on a fractional lot
grid, the close-sized call at the next open takes a book of several lots the
close's fills opened, first in first out, and its follow-up is checked lot by
lot (open_print_lot_follow_up_units). One-lot books keep
open_print_follow_up_units, and whole-share books of several lots keep the
previous rules. On a fractional book of several lots a short's booked
re-check now runs as well (the parent tree never entered this schedule for
several lots); nothing follows it, since no tape decides that follow-up.
Tests: tests/fixtures/margin_open_rules lots/ holds 10 synthetic TradingView
controls (62 trades), each exported twice with identical output and
predicted before export. All 10 match row for row and stream to the
backtest's trades; the parent tree matches none of the first 8. Two of them
close the entry by id after the open's calls (strategy.close("L"), with an
explicit and with a default-sized L). Off alone, close_follow_up_after_script
loses 7 tapes and lot_by_lot_open_follow_up 9. margin_open_rules: 53 tapes,
all match. The job-2550 probe's trades now equal TradingView's 3761 rows.
Whole-suite per-run trade dumps (%.17g, every field) with both switches on
and off: only the lots/ tapes move. Documentation: both switches' rows, the
counts, and the anchor digits carried by an exact line map.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
… the exit legs marketable there TradingView, pinned on 25 synthetic controls (each exported twice, byte-identical, every prediction written before its export): at a market entry that opens the book from flat at a bar's open, the exit legs it released that are already marketable at that open -- a short's stop at or below the open's tick or its limit at or above it, a long's mirror -- fill there first, and the opening margin check then runs on the book they leave (nothing after a whole exit). A leg the bar reaches only later on its path, one tick after the open included, never preempts: the check's call books at the fill first. Both sides. Four more controls make the strategy.exit global (no from_entry) and place it with the entry: TradingView books each exactly as its bound control. ab9714b's rule -- a 1x short skips the opening trim when an exit leg touches anywhere on the entry bar -- is refuted by TradingView on its own shape (test_margin_call_1x_long_entry_fill scenario E's settings and bar: 0.008 ETH called at the open, then the stop closes 3.492). For a market entry opening the book from flat at the open (one lot, no add, no book of several entries, neither process_orders_on_close nor calc_on_order_fills) the adapter asks the legs that fill released whether they are marketable at the open (priced_exit_precedes_opening). The released legs (opening_released_leg) are those bound to the entry's request, those bound to its id and materialized at the fill on the book's side, and a global leg placed while the book was flat whose request follows the entry's. Every other leg (a strategy.exit without from_entry placed before the entry or while a position was held, a leg carried from an earlier bar or lot) is still asked ab9714b's question, and every other fill (stop and limit entries, reversals, adds, books of several entries, process_orders_on_close, calc_on_order_fills) keeps that rule. The scope is narrower than the pin's wording because the wider form (every market fill at the open, every live leg) moved the state hashes of two synthetic witnesses, test_adapter_quiet_bar (18 runs) and test_publication_witness (10 runs): hash-only, every trade field equal in a whole-suite dump, through legs the kernel never fills at that open, whose owed check then lingered. Which exclusion each of the last 8 runs needed was not bisected. Known divergences of the kept rule: - Two are committed as tapes the test lists in kKnownDivergences: TradingView calls a short reversal (out of a 0.001 long) and a short stop entry gapped at the open (a sell stop above the close) before their stop on the path, as it does the market entry; the engine books the stop 3.5 with no call. - A global strategy.exit placed before the entry, while the book is flat, has no tape. TradingView voids an exit called while no position is held and no entry order is working (its exit-binding pins), so, by inference, it calls such a short at the open print. The engine keeps a leg there that never fills, at the open or later, and still asks ab9714b's question of it: the short's opening call is skipped whenever the bar touches the leg's stop, and the short is called at the path's extreme instead, the same with the switch off. The leg stays out of the released legs for an engine-only reason: counted, it defers the check to a fill that never comes, which drops the check, a long's too (in test_adapter_quiet_bar Random32 that moved only the state hash). - Adds, books of several entries, limit entries, process_orders_on_close and calc_on_order_fills stay on that rule without a tape. A partial exit at the open owes the check after its own fill (open_exit_first_bar_: 0.0032 called after a 0.0004 stop, as TradingView books it); the record is cleared at the next bar open if no released leg fills. The opening check's body moves unchanged into run_opening_checkpoint so both points run the same branch. Switch MarginOpeningSwitches::open_marketable_exit_first, default on; off restores the previous rule (every deterministic run-pass of the suite books the parent tree's trades, field for field). Tests: the 31 controls are tapes in tests/fixtures/margin_open_rules exit-order/ (53 trades). margin_open_rules now holds 84 tapes and 244 trades: 82 match, the 2 listed divergences still differ, forward == backtest on all 84, and the switch off loses 17 (15 of the 25 pinned controls, which the parent tree misses, and the two global controls that tell the rules apart). Scenario E of test_margin_call_1x_long_entry_fill (twin and base copy) books TradingView's shape, 0.1996 @100 "Margin call" then 99.7504 @105; its twin-parity rewrite entry is extended. Docs: the switch row and counts, and every anchor into the moved files re-anchored by an exact line map. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…it beside a same-side add too A strategy.exit with no from_entry, called while a position is held beside an entry order of the HELD side (an add resting at a limit or a stop, placed earlier in the same calculation, or queued by a fill recalculation), still took that pending add as its parent (observe_staged_parent in exit()): #345 skipped only an entry order of the other side. With the add's price basis, a profit or trail leg rested at the add's limit plus its ticks and filled at the next open, so a script booked thousands of one-bar trades; a loss leg, and any leg beside a stop add, waited for the add's fill, which never came, and the position ran to the end of the range. A market add at the pyramiding cap never became a pending parent. TradingView binds such an exit to the held position whatever the side of the order beside it. In 36 pairs of synthetic `lab tv --no-note` controls on NYSE:F 15m (a resting limit add, a resting stop add, or a market add at the cap; profit, loss, profit and loss, and trail legs; long and short; calc_on_order_fills off and on; every prediction written before its export), each add script's List of Trades is byte-identical to its control's: 0 counterexamples. The skip now drops its side term, so the exit keeps the held position's side and entry price. Under calc_on_order_fills one more path departed: the profit-and-loss bracket the exit stages in the entry's fill recalculation (the chart-tick scope) counted the resting add as a competing order of the source book, which took the bracket's chart-tick reach (its threshold moved half a tick beyond a level the on-grid test misreads by one ULP), so a limit the fill bar's high reaches exactly filled one bar late. flush_pending_bracket_legs now leaves the entry orders of the held side out of the census of a held global exit's leg. Two switches (ExitBindingRuleSwitches, on; tests clear them): global_exit_binds_held_position (extended, sizeof unchanged) and the new held_exit_bracket_ignores_same_side_entries (sizeof 5 -> 6). Kernel untouched; no stream gate. Not in scope: an add that fills while the exit works (TradingView gives each entry its own exit levels and books FIFO; the engine books one exit at the average price) is a separate rule. Tests: tests/fixtures/same_side_exit holds the 36 add tapes and their 20 controls (exact Pine bytes, TradingView's List of Trades, provenance, frozen generated C++ of codegen c1df8a69); test_same_side_exit_tapes requires 38 tapes equal to TradingView row for row and the other 18 to depart exactly at their recorded row (the same row in a control and its add tapes: the trailing leg and calc_on_order_fills re-entries, another rule's); with global_exit_binds_held_position off exactly the 32 resting-add tapes move, with held_exit_bracket_ignores_same_side_entries off exactly the 4 calc_on_order_fills profit-and-loss add tapes; no control and no cap tape moves. The calc_on_order_fills add tapes are refused by a forward stream; every other add tape streams (1 and 30 bars of history, every run of the feed between two nights) to the backtest's trades. test_exit_binding_tapes sets the new switch in every_part() and lists it. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
| sys.path.insert(0, str(scripts)) | ||
| from run_strategy import Strategy, _check_abi, inputs_run_kwargs # noqa: E402 | ||
|
|
||
| class TapeStrategy(Strategy): |
| _check_abi(self.lib) | ||
| self._setup_signatures() | ||
|
|
||
| class StreamStrategy(Strategy): |
| sys.path.insert(0, str(scripts)) | ||
| from run_strategy import Strategy, _check_abi, _load_bars, inputs_run_kwargs # noqa: E402 | ||
|
|
||
| class TapeStrategy(Strategy): |
| _check_abi(self.lib) | ||
| self._setup_signatures() | ||
|
|
||
| class StreamStrategy(Strategy): |
luisleo526
marked this pull request as ready for review
October 6, 2026 01:22
luisleo526
added a commit
that referenced
this pull request
Oct 6, 2026
* docs: release notes and version scoping for v1.3.0 CHANGELOG 1.3.0: confirmed-bar admission in pineforge-live (#342), the Pine adapter changes of #341, #345 and #347, tests and docs (#343, #344); no report key changes; the state-hash recipe additions of #341 and #347, domain tags and the v19 epoch unchanged; migration. Version scoping: README, install.md and public-contract.md name v1.3.0, its tarballs, the engine1.3.0-codegen1.3.0 image and the 1.3.0 pair. The confirmed-bar receipt and its admission, marked unreleased after 1.2.0 by #342, ship in 1.3.0 (README, strategy-capabilities.md, runner/README.md). Codegen license lines (README, LEGAL.md, docs/pages/index.md): the PineForge Source License 1.2 from codegen 1.3.0; 1.2.0 keeps 1.1, releases up to 1.1.0 the PolyForm Noncommercial terms. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> * docs: release 1.3.0's grades in the README and the changelog, from the facts tokens The README's release sentence moves to the releases[1.3.0] tokens, and its main-scoreboard lines re-render the values defe41f (#343) rendered at pineforge-release 3e39d64, and the 1.3.0 changelog says which registry baseline grades the release and why that baseline is the release's code, all rendered from pineforge-release facts/facts.json at ff21de0 (#32). The changelog sentence extends the last line of the "What a script author sees" bullet that 0e1ced7 added. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pine adapter: four more TradingView rules pinned by synthetic controls
Four adapter-only changes (
src/source/,include/pineforge/source/, tests and docs; no kernel,grader, metric, tolerance or codegen change). Each rule part sits behind its own test-only switch,
default on, so a regression bisects per rule. One commit per change.
1. A re-issued exit filled at its call keeps the pass's position view (
detail::PoocCloseFillViewSwitches)Under
process_orders_on_close, the adapter fills a re-issuedstrategy.exitof a one-lot short at thecall when its stop or limit is already through the bar's close. Unlike
strategy.close_all(), it did notfreeze the script's position view, so the rest of the pass read
strategy.position_size == 0and a resetstrategy.position_avg_price. A late exit observer (strategy.position_size[1] < 0 and strategy.position_size == 0) then fired one bar early, and an exit cooldown blocked the next entry.TradingView fills that exit at the close, after the pass. The adapter now freezes the position view
before it executes the exit, and once the fill has left the book flat,
strategy.position_avg_pricekeeps the pre-fill average until the pass ends (no codegen change). The hold is released right after the
script, before the bar's broker state is folded.
Evidence:
lab tv --no-note, two byte-identical exportseach, predictions written before export): 0 counterexamples. 11 are committed as
tests/fixtures/pooc_close_fill_view: 9 equal TradingView row for row, entry ids included (there-issued stop exit's size read, cooldown observer, ATR-stop cooldown at 100 % of equity, average read
and limit leg, plus the long mirror,
strategy.close,close_alland a first-issue exit, which nevermoved); 2 are known divergences (below).
tapes, each away from TradingView. Every tape streams to its backtest's trades with both parts on and
off.
the trades are, otherwise first different after the exit bar. With the release call removed the test
fails on 6 tapes at the exit bar's fold, so a hold that outlives its pass cannot go unnoticed.
trade lists; nothing else in the population moves.
Known divergences:
close_all's ownstrategy.position_avg_priceread: TradingView keeps the pre-fill average; theengine's freeze there covers the size only (
short-close-all-average).strategy.opentrades,closedtrades,openprofit,netprofitandequity; the engine reads them after the fill(
short-reissued-exit-reads).strategy.closethat fills at the call under an active intraday cap freezes nothing (no tape).2. A POOC close's owed follow-up after the script, frozen close sizes and their over-fill lot, and the open's lot-by-lot follow-up (
MarginScheduleSwitches::close_follow_up_after_script,MarginOpeningSwitches::lot_by_lot_open_follow_up)process_orders_on_closeshort's margin-call follow-up owed to its bar's close is bookedafter the script, ahead of the close's fills, at the same print. A
strategy.close(id)of the wholeone-lot book or a
close_all()placed there keeps the size the script saw, so the order crosses zeroand opens the excess as a lot of its own. That lot is credited to the close ledger ahead of the entry
beside it, so a later
strategy.closeof that entry closes all of the entry's units.and a default-sized one is not refused by the fill-time affordability check.
first in first out and its follow-up is checked lot by lot.
Evidence:
before export), committed as
tests/fixtures/margin_open_rules/lots/(62 TradingView trades): 10/10row for row, forward == backtest. Off alone, the close switch loses 7 tapes and the lot-by-lot switch
9.
else in the population moves.
Known divergences and unpinned shapes:
process_orders_on_closekeeps its old size (margin_schedule_rulesfrozen/close-idstays a listed divergence); partial closes and closes of several lots keep today'ssizing.
changes against the previous release, unpinned either way: an explicit stop entry placed at that close at
pyramiding 0 is refused as a same-side add beside the lot, where the previous release filled it on the
next bar.
(no tape decides that follow-up); whole-share books of several lots keep the previous rules. No tape
runs pyramiding above 1, so the lot's pyramiding-record credit is unexercised.
3. A market entry's opening check at its open fill follows the exit legs marketable there (
MarginOpeningSwitches::open_marketable_exit_first)At a market entry that opens the book from flat at a bar's open, the exit legs it released that are
already marketable at that open (a short's stop at or below the open's tick or its limit at or above it,
a long's mirror) fill there first, and the opening margin check runs on the book they leave. A leg the bar
reaches only later on its path never preempts: the check's call books at the fill first. A
strategy.exitwithoutfrom_entryplaced with the entry counts as a released leg. The previous rule (a1x short skips its opening margin call whenever its bar touches any exit leg) is refuted by TradingView
on its own test shape.
Evidence:
predictions written before export), committed as
tests/fixtures/margin_open_rules/exit-order/(53TradingView trades): 29 row for row, 2 listed divergences (below); forward == backtest on all.
Turning the switch off loses 17 tapes. A legacy scenario (
test_margin_call_1x_long_entry_fillE) nowbooks TradingView's shape: 0.1996 "Margin call" at the open, then the stop.
15m script goes from 233 to 588/588 exact TradingView rows. Rows lost on two scripts all lie after
their first, pre-existing miss (equity cascades).
Known divergences:
open print before their stop on the path, as it does the market entry; the engine keeps the previous
rule there.
strategy.exitplaced before the entry, while flat. TradingView ignoresan exit called while no position is held and no entry order is working, so, by inference, it calls such
a short at the open print. The engine keeps that call as a leg that never fills and still lets it
preempt the short's call (the short is called at the path's extreme instead; the same with the switch
off). The leg stays outside the released legs for an engine-only reason: counted, it would defer the
check to a fill that never comes and drop the check, a long's too.
process_orders_on_closeandcalc_on_order_fillskeepthe previous rule without a tape.
4. A global exit called while a position is held binds to it beside a same-side add too (
ExitBindingRuleSwitches)A
strategy.exitwith nofrom_entry, called while a position is held beside an entry order of theheld side (an add resting at a limit or a stop, placed earlier in the same calculation, or queued by a
fill recalculation), took that pending add as its parent. A profit or trailing leg then rested at the
add's limit and closed the position at the next open, so a script booked thousands of one-bar trades; a
loss leg, and any leg beside a stop add, waited for the add's fill, which never came, and the position ran
to the end of the range. The exit now binds to the held position and its average price, whatever the side
of the order beside it. Under
calc_on_order_fillsthe bracket the exit stages in the entry's fillrecalculation no longer counts the held side's entry orders as competing orders (they moved its threshold
half a tick, so a limit the fill bar's high reaches exactly filled one bar late).
Evidence:
add at the pyramiding cap; profit, loss, profit and loss, and trailing legs; long and short;
calc_on_order_fillsoff and on; predictions written before export): every add script's List of Tradesis byte-identical to its control's, 0 counterexamples.
tests/fixtures/same_side_exitcommits all 56 tapes: 38 equal TradingView row for row; 18 depart atone recorded row, the same row in a control and its add tapes (the trailing leg and
calc_on_order_fillsre-entries, another rule's). Off, the binding switch moves exactly the 32resting-add tapes and the bracket switch exactly the 4
calc_on_order_fillsprofit-and-loss add tapes.Every non-
calc_on_order_fillsadd tape streams to its backtest over every run of the feed.Known divergences: the 18 rows above (trailing-stop and
calc_on_order_fillsre-entry gaps that thecontrols share); an add that fills while the exit works (TradingView gives each entry its own exit levels
and books first in first out, the engine books one exit at the average price) is a separate rule, not
changed here.
Release note
Verification
run in the CI release profile), and each intermediate commit passes on its own.
test_pooc_close_fill_view_tapes9 + 2 known;test_margin_open_rules_tapes82/84 tapes, 244 TradingView rows, forward == backtest 84/84, everyswitch costs tapes (lot-by-lot 9, open exit order 17, close follow-up 7);
test_same_side_exit_tapes38 + 18 known;test_margin_schedule_rules_tapes38/39, forward 39/39;test_margin_call_rules_tapes258/266 (all switches off: 140);test_margin_opposite_tapes63,504checks;
test_exit_binding_tapesforward == backtest 36/36;test_cross_side_exit_tapes11 + 4 known;test_adapter_quiet_bar276/276 andtest_publication_witness156/156 pinned runs unchanged.alone and the four together, with a per-run dump of every trade field (
%.17g): every run that one changemoves equals that change's run in the combined engine, every other run equals the previous release's, and
no run is moved by two changes. Each change's own tests give the same trades alone and combined. The
four changes' population movers do not overlap.
Population gate
One whole-population sweep of this head's exact tree (
exp-px-wave-r3-gate-20261006, attempt 1; engine3219563e, codegen main3e50082f, populationcf857209), graded against the active baselinepineforge-parity-baseline-20261005-engine-a9544d36:eth-scraped-15 job-2947-seanvtran-svt-30m-options-swing-indicator(hard lane): the same-pass position view after a fill at the close (change 1);eurusd-15 job-2550-spiritedcheeta2101-quanloki-qqe-system-opposite-signal-only-points: the close's owed follow-up and the over-fill lot (change 2);eth-scraped-15 blitz-locked-macd-pullback-sniper-trend-adx-filtered-strategy(hard lane): an exit marketable at the open goes first (change 3).e7921e2433a449d1b0859d2bac0536e5663a06820030b091e451529a37487b68(7,989 graded).🤖 Generated with Claude Code