Repository navigation
Pine adapter: admission fill half, close-first entries, point order, exit tombstones and pyramiding records - #335
Merged
Merged
Conversation
…r, exit tombstones, pyramiding records
TradingView admits an order in two halves: rules 2 and 5 at the signal close,
then one price-scale check at the fill. This change turns the fill half on and
adds the TradingView behaviours that the fixtures under
tests/fixtures/admission_rules pin. Each rule has its own internal switch in
MarginRuleSwitches. All switches are on, and only tests change one.
- unified_placement: the placement half, split out of fill_price_recheck. A
reversal that rule 5 refuses stays placed, marked signal_price_refused. It
drops at its fill, and the script's later close of the held id stays an
ordinary close.
- fill_price_recheck, now on: the whole order drops iff
sig10(sig10(E_signal) / (Q m)) is under the slipped tick-built fill quote.
The tie band is removed. Inside the unified scope, the explicit market
long's money check on the unslipped next-bar quote is never reached.
- close_first_admission: an entry the script placed on the same bar behind its
own strategy.close(<held id>) or strategy.close_all() of the position it
opposes is checked by rule 2 only.
- It fills flat with its frozen quantity.
- The fact is recorded once, at the close or close_all call, and stamped on
the entry at its entry() call.
- point_fills_before_margin: at the open, the queued orders execute first,
then the exits the open reaches, then the margin check on what is left. Two
kinds of order fill before that check:
- a protective strategy.exit stop or limit that the opening print reaches
and whose entry holds units of the position; an exit armed for an entry
that holds nothing fills nothing there. from_entry_units, the units an
exit's entry holds, is shared with the process_orders_on_close bracket
ranking in flush_pending_bracket_legs, whose inert exit also needs an
entry with no working order; each site keeps its own test;
- a close the script placed ahead of its opposite entry.
Two shapes keep the earlier order:
- A process_orders_on_close short's call sized at the previous close,
while the open does not re-size it, is a queued order, so it executes
before a stop the open gaps through (TradingView's tape of
axealgo-tp-sl-toolkit-axealgo on OANDA:XAUUSD: the call of 1, then the
stop's 1.62). A call the open re-sizes is the open's own check, after the
exits; no tape decides that shape yet.
- A partial exit fills first only when what it leaves is margined; a
remainder still short keeps the call at the open first. No tape decides
that case yet.
test_point_order_open_call pins both shapes, each with a control.
- exit_child_tombstones: a partial exit child that filled is never revived for
the entry incarnation it filled under.
- pyramiding_ledger_records: under pyramiding above one, the cap counts the
open close-ledger records, one per entry fill not yet booked, not the
physical lots. An exit armed for one opening books that opening first.
Every rule runs only on a power-of-ten lot grid, which every tape and every
population member uses. The unified admission also leaves out
calc_on_order_fills, the bar magnifier, stops that reverse, default-sized
stops, a resting book and same-open pairs; those keep the earlier rules. New
durable state is folded into the source-adapter hash only while it is set.
Three rules are left out, because nothing tells them apart from the current
behaviour. Decision counters ran over every ctest fixture and 198 replayed
population scripts and found no divergence:
- the commission-0 POOC unit: 23,510 calls;
- the whole-book add at the signal close: 413 calls;
- the lagged follow-up on whole-share grids: 1 call.
docs/pine-adapter-kernel-notes.md section 1.8 names the TradingView control
each one needs.
Fixtures:
- tests/fixtures/admission_rules: 73 TradingView tapes in four groups,
gap_admission, point_order_and_book, stop_priority and explicit_short.
- The engine reproduces all 73, and 56 of the 59 NYSE:F tapes book the same
trades as a backtest and as a stream; the other three cross a holiday
that a stream takes as an in-session gap.
- Each of the six rules above loses tapes when turned off alone.
- test_qty_step_lot_grid_case, the hosted lot-grid case, still books every
recorded row exactly, with and without the 1e-05 grid.
- The explicit-short twin control in test_taro_price_gap_admission_l4d is
re-pinned on TradingView's own tape of it (explicit_short/offset0-fill).
TradingView fills that order, so its literal check moves to the -.00032
offset, where the order is declined.
- The margin_call_rules, margin_ledger_rules and forward-replay lists drop the
entries the fill half now reproduces.
- test_integer_flat_budget_tie_l4d asserts the one row it moves. On a 0.01
lot grid, rule 2 drops a default long from flat one ulp under the cost, as
TradingView's margin_ledger_rules tape eth-flat-m100-ulp-under does.
The witness tables move on hash fields only. Every closed trade of every
run-pass is identical, field for field, to the parent commit's.
The margin-rules notes said the unified admission ships off; it now ships
on, so these sentences of docs/pine-adapter-kernel-notes.md are replaced:
- "Two narrowings keep the scraped population's orders on the earlier rules"
- "Outside that scope the engine's earlier admission rules run unchanged."
- "The tree ships this unified admission off"
- "gates it whole, its fill half and the placement half's reach"
- "With it on, the scraped population lost orders"
- "keeps the earlier scopes: an explicit quantity from flat"
- "With the shipped switches the engine reproduces 170"
- "The tests list 3 single-position and 104 ledger tapes"
- "The fill re-check, and with it the unified admission"
- "On the scraped population it dropped reversals and openings"
- "The tapes pin the check only at a one-tick"
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
luisleo526
force-pushed
the
px/admission-fill-n34
branch
from
October 4, 2026 15:41
ed36a01 to
075469d
Compare
luisleo526
marked this pull request as ready for review
October 4, 2026 16:51
luisleo526
added a commit
that referenced
this pull request
Oct 4, 2026
On a gathered chart (a script timeframe above the input timeframe), pin K5 keeps every entry row of the run, so the sweep at each bar open (erase_retired_rows) walked a table that grows with the run, re-finding each row and binary-searching the askable origins before reading the row's own pin: the per-bar cost rose with every entry placed. The sweep now reads the rows straight off the table's storage, in the same incarnation order (PlacementTable::visit_rows), and tests a row's own pin before the searches. It keeps and erases exactly the rows it did. Alongside, each value-identical: decimal_grid_exponent forms its nineteen powers once, by the same expressions; gain_loss_regime and slipped_long_margin_scope read the configuration before the run; on_bar_open takes the point-order scan only under the point order; the narrow-scope margin and admission helpers stay out of line (two) or out of line and cold (six), and thirteen of their scope tests are hinted rare. The recovery is for gathered charts. With the script timeframe equal to the input timeframe the table stays small, the sweep is cheap anyway, and the cost the margin, sizing and admission rules added since 14b05c9 remains (native example batch median +5.7 %); the next commit takes it. No decision, order of operations, hashed field or floating-point value moves: against the admission change (#335) the witness harvests (every pinned state hash), a per-trade dump of all 21 Trade fields (%.17g, every run pass), the no-hash digests and the tape suites are byte-identical, and release ctest passes with the receipt rows. Doc citation digits re-anchored. Timing, measured on the admission change (#335) before its final rebase (same library): Xeon 8375C, CPU 2, 61 rotating blocks x 3 independent builds per tree x 5 runs, paired block bootstrap; every 95% interval within 0.21 points, * = it covers 0. percent vs native ta-sma bracket udt vcp batch median, gathered (1 m input, 3 m script) 14b05c9 +0.05* -0.05* -1.95 -0.38 -0.29 #335 (parent) -4.31 -2.56 -2.98 -3.63 -2.07 batch median, ungathered (1 m input, 1 m script) 14b05c9 +5.70 -0.33 +0.07* +4.19 +2.09 #335 (parent) -1.06 -3.01 -1.24 -1.00 -2.25 stream p95, gathered 14b05c9 +0.89 -0.18 -0.90 +2.77 +3.41 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
luisleo526
added a commit
that referenced
this pull request
Oct 4, 2026
…on; no sort or copy for a lone command The margin and admission scopes are asked several times a bar, and on a run outside them -- no power-of-ten lot step, a commission, pyramiding above one -- the configuration alone answers. Those conjuncts are now formed when the configuration is set (set_configuration and set_staged_configuration, the only writers of config_ and staged_), so such a bar answers each scope with one read instead of a call; inside a scope its own tests run as before, and the rule switches are still read at every ask. The unified admission at resolve_terms moves out of line unchanged, and the realized-money fold returns at once when nothing was booked since the last one. Alongside, on the same per-bar path: the same-bar command flush no longer stable-sorts a one-command queue (std::stable_sort still took a temporary buffer and moved the command, its whole placement snapshot included, through it and back) and keeps the queue's storage for the next bar; cancel_bracket_siblings and apply_fx_opening_margin_slice decide before copying the filled row; close_all records the close-first fact from the point and position it has already read; on_bar_open forms the opening print only under the point order; the retired-row sweep's visitors are inlined. No decision, order of operations, hashed field or floating-point value moves. Against the previous commit: the whole-suite dump (every closed and range-end trade with all 21 Trade fields at %.17g, every recorded per-bar, broker and stream state hash) is byte-identical on 659 of 663 process files (4 of them matched by content: their name hashes a temp-path argument), and the other 4 differ by run, not by tree (a timing-calibrated row, a stack-address row, two concurrent writers identical when run alone, twice in each tree); the 30 witness harvests (no re-pin) and 176 tape and witness executables are byte-identical; release ci_verify 859/859 with the receipt rows; corpus 312/312, moved 0. The seven new members are functions of the folded configuration and are waived as such. Doc citation digits re-anchored. Timing (Xeon 8375C, CPU 2; 4 independent builds per tree resampled as a random effect, blocks paired; percent against 14b05c9, 95% CI; largest build-to-build A/A 0.11 % / 0.27 % on the whole-batch median): whole-batch median stream mean per call stream p95 script timeframe = input timeframe (81 blocks) native example -1.5 [-1.5,-1.4] -2.8 [-2.8,-2.7] -2.1 [-2.2,-2.1] ta-sma-dual-cross -1.9 [-2.0,-1.9] -0.5 [-0.5,-0.4] +0.4 [+0.4,+0.5] bracket-aurora +0.2 [+0.1,+0.2] -0.7 [-0.8,-0.7] +1.0 [+1.0,+1.1] udt-regime-stack +0.4 [+0.4,+0.5] -0.8 [-0.9,-0.8] +0.4 [+0.3,+0.5] composite-vcp +2.6 [+2.5,+2.6] +1.6 [+1.5,+1.6] +2.2 [+2.1,+2.3] 1-minute input under a 3-minute script (41 blocks) native example -5.2 [-5.3,-5.0] -4.4 [-4.5,-4.3] -5.0 [-5.1,-4.9] ta-sma-dual-cross -2.2 [-2.3,-2.1] -1.2 [-1.3,-1.1] +0.2 [+0.1,+0.5] bracket-aurora -3.6 [-3.7,-3.5] -3.3 [-3.4,-3.2] -5.8 [-5.9,-5.7] udt-regime-stack -2.6 [-2.8,-2.5] -2.3 [-2.4,-2.2] -0.4 [-0.7,-0.1] composite-vcp † -0.4 [-0.5,-0.2] +0.4 [+0.3,+0.4] +2.0 [+2.0,+2.2] † Not a property of this commit: this row moves with the size of the process environment. setenv("TZ") (src/timezone.cpp) costs one heap trim and re-grow per run, about 85 us over 5,003 bars, and the row reads -0.3 to -0.6 with some environment sizes and +1.5 (+1.9 against the previous commit) with others. Whole-batch differences under 0.5 % read as at par. In the same runs the previous commit stood at +5.6, -0.3, +0.1, +4.2, +2.0 (script timeframe = input timeframe) and -0.2, -0.1, -2.0, -0.4, -0.1 (3-minute script) on the whole-batch median, and the admission change (#335) at +6.7, +2.9, +1.4, +5.2, +4.4 and +4.5, +2.6, +1.1, +3.4, +2.0. composite-vcp's remaining gap is the session clock in src/session_time.cpp (time() with a session argument every bar), which this commit does not touch. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
luisleo526
added a commit
that referenced
this pull request
Oct 4, 2026
…ssion rules (#336) * Pine adapter: the retired-row sweep reads the placement rows in place On a gathered chart (a script timeframe above the input timeframe), pin K5 keeps every entry row of the run, so the sweep at each bar open (erase_retired_rows) walked a table that grows with the run, re-finding each row and binary-searching the askable origins before reading the row's own pin: the per-bar cost rose with every entry placed. The sweep now reads the rows straight off the table's storage, in the same incarnation order (PlacementTable::visit_rows), and tests a row's own pin before the searches. It keeps and erases exactly the rows it did. Alongside, each value-identical: decimal_grid_exponent forms its nineteen powers once, by the same expressions; gain_loss_regime and slipped_long_margin_scope read the configuration before the run; on_bar_open takes the point-order scan only under the point order; the narrow-scope margin and admission helpers stay out of line (two) or out of line and cold (six), and thirteen of their scope tests are hinted rare. The recovery is for gathered charts. With the script timeframe equal to the input timeframe the table stays small, the sweep is cheap anyway, and the cost the margin, sizing and admission rules added since 14b05c9 remains (native example batch median +5.7 %); the next commit takes it. No decision, order of operations, hashed field or floating-point value moves: against the admission change (#335) the witness harvests (every pinned state hash), a per-trade dump of all 21 Trade fields (%.17g, every run pass), the no-hash digests and the tape suites are byte-identical, and release ctest passes with the receipt rows. Doc citation digits re-anchored. Timing, measured on the admission change (#335) before its final rebase (same library): Xeon 8375C, CPU 2, 61 rotating blocks x 3 independent builds per tree x 5 runs, paired block bootstrap; every 95% interval within 0.21 points, * = it covers 0. percent vs native ta-sma bracket udt vcp batch median, gathered (1 m input, 3 m script) 14b05c9 +0.05* -0.05* -1.95 -0.38 -0.29 #335 (parent) -4.31 -2.56 -2.98 -3.63 -2.07 batch median, ungathered (1 m input, 1 m script) 14b05c9 +5.70 -0.33 +0.07* +4.19 +2.09 #335 (parent) -1.06 -3.01 -1.24 -1.00 -2.25 stream p95, gathered 14b05c9 +0.89 -0.18 -0.90 +2.77 +3.41 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> * Pine adapter: margin and admission scopes answer from the configuration; no sort or copy for a lone command The margin and admission scopes are asked several times a bar, and on a run outside them -- no power-of-ten lot step, a commission, pyramiding above one -- the configuration alone answers. Those conjuncts are now formed when the configuration is set (set_configuration and set_staged_configuration, the only writers of config_ and staged_), so such a bar answers each scope with one read instead of a call; inside a scope its own tests run as before, and the rule switches are still read at every ask. The unified admission at resolve_terms moves out of line unchanged, and the realized-money fold returns at once when nothing was booked since the last one. Alongside, on the same per-bar path: the same-bar command flush no longer stable-sorts a one-command queue (std::stable_sort still took a temporary buffer and moved the command, its whole placement snapshot included, through it and back) and keeps the queue's storage for the next bar; cancel_bracket_siblings and apply_fx_opening_margin_slice decide before copying the filled row; close_all records the close-first fact from the point and position it has already read; on_bar_open forms the opening print only under the point order; the retired-row sweep's visitors are inlined. No decision, order of operations, hashed field or floating-point value moves. Against the previous commit: the whole-suite dump (every closed and range-end trade with all 21 Trade fields at %.17g, every recorded per-bar, broker and stream state hash) is byte-identical on 659 of 663 process files (4 of them matched by content: their name hashes a temp-path argument), and the other 4 differ by run, not by tree (a timing-calibrated row, a stack-address row, two concurrent writers identical when run alone, twice in each tree); the 30 witness harvests (no re-pin) and 176 tape and witness executables are byte-identical; release ci_verify 859/859 with the receipt rows; corpus 312/312, moved 0. The seven new members are functions of the folded configuration and are waived as such. Doc citation digits re-anchored. Timing (Xeon 8375C, CPU 2; 4 independent builds per tree resampled as a random effect, blocks paired; percent against 14b05c9, 95% CI; largest build-to-build A/A 0.11 % / 0.27 % on the whole-batch median): whole-batch median stream mean per call stream p95 script timeframe = input timeframe (81 blocks) native example -1.5 [-1.5,-1.4] -2.8 [-2.8,-2.7] -2.1 [-2.2,-2.1] ta-sma-dual-cross -1.9 [-2.0,-1.9] -0.5 [-0.5,-0.4] +0.4 [+0.4,+0.5] bracket-aurora +0.2 [+0.1,+0.2] -0.7 [-0.8,-0.7] +1.0 [+1.0,+1.1] udt-regime-stack +0.4 [+0.4,+0.5] -0.8 [-0.9,-0.8] +0.4 [+0.3,+0.5] composite-vcp +2.6 [+2.5,+2.6] +1.6 [+1.5,+1.6] +2.2 [+2.1,+2.3] 1-minute input under a 3-minute script (41 blocks) native example -5.2 [-5.3,-5.0] -4.4 [-4.5,-4.3] -5.0 [-5.1,-4.9] ta-sma-dual-cross -2.2 [-2.3,-2.1] -1.2 [-1.3,-1.1] +0.2 [+0.1,+0.5] bracket-aurora -3.6 [-3.7,-3.5] -3.3 [-3.4,-3.2] -5.8 [-5.9,-5.7] udt-regime-stack -2.6 [-2.8,-2.5] -2.3 [-2.4,-2.2] -0.4 [-0.7,-0.1] composite-vcp † -0.4 [-0.5,-0.2] +0.4 [+0.3,+0.4] +2.0 [+2.0,+2.2] † Not a property of this commit: this row moves with the size of the process environment. setenv("TZ") (src/timezone.cpp) costs one heap trim and re-grow per run, about 85 us over 5,003 bars, and the row reads -0.3 to -0.6 with some environment sizes and +1.5 (+1.9 against the previous commit) with others. Whole-batch differences under 0.5 % read as at par. In the same runs the previous commit stood at +5.6, -0.3, +0.1, +4.2, +2.0 (script timeframe = input timeframe) and -0.2, -0.1, -2.0, -0.4, -0.1 (3-minute script) on the whole-batch median, and the admission change (#335) at +6.7, +2.9, +1.4, +5.2, +4.4 and +4.5, +2.6, +1.1, +3.4, +2.0. composite-vcp's remaining gap is the session clock in src/session_time.cpp (time() with a session argument every bar), which this commit does not touch. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> * Tests: run the lookup-index and live-state scaling rows serially in Release Under a parallel ctest the lookup-index scaling row once read 6.15 against its 5.0 bound, and 4.08 when run alone; the live-state scaling row failed the same way under load. RUN_SERIAL keeps other rows off the box while these two time their legs, in Release, where their ratios gate. A whole Release suite at -j 28 read 3.99-4.01 with it and 3.82-4.83 without, for about a minute more wall time. No source or behaviour change. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
luisleo526
added a commit
that referenced
this pull request
Oct 5, 2026
* docs: release notes and version scoping for v1.2.0 CHANGELOG: the Unreleased section becomes 1.2.0 (2026-10-05), a minor release that adds the compiled execution-capabilities extension to the C ABI (PF_CAPABILITIES_API_VERSION, strategy_capabilities_api_version, strategy_capabilities_receipt). One bullet per change since v1.1.0 with its PR (#328, #330, #331, #332, #333, #334, #335, #336, #337, #338 and the session-clock change, written #VCP until its PR number exists), the recipe additions under State hashes (#328, #330, #335; domain tags and epoch unchanged), Report keys (docker/run_json.py is byte-identical to v1.1.0's, so no key changes) and Migration. Version scoping: README, install and public-contract pages name v1.2.0 and codegen 1.2.0; "since the next release" and "fixed on main" in the capabilities guide and the runner guide become 1.2.0 and 1.1.0 (#325). Lines that state what an earlier release shipped stay. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> * docs: 1.2.0's grades from the facts tokens, #339, and codegen's license - CHANGELOG: the session-clock change is #339 (merged as 52292db), in place of the #VCP token of 3082fbd; the "What a script author sees" bullet of 3082fbd now states release 1.2.0's grades (registry baseline pineforge-parity-baseline-20261005-engine-52292db9: 7,970 excellent / 19 strong of 7,989, none below strong) instead of the main scoreboard at 6b77f06. - README: the release sentence names 1.2.0 and renders releases[1.2.0], and the main scoreboard renders the same baseline, from pineforge-release facts/facts.json at 0c2f6838 (the facts export for the 1.2.0 release). - README, LEGAL.md, docs/pages/index.md: pineforge-codegen is under the PineForge Source License 1.1 from its release 1.2.0; releases up to 1.1.0 keep the PolyForm Noncommercial terms they shipped with. 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.
TradingView admits an order in two halves: rules 2 and 5 at the signal close,
then one price-scale check at the fill. This change turns the fill half on and
adds the TradingView behaviours that the fixtures under
tests/fixtures/admission_rules pin. Each rule has its own internal switch in
MarginRuleSwitches. All switches are on, and only tests change one.
reversal that rule 5 refuses stays placed, marked signal_price_refused. It
drops at its fill, and the script's later close of the held id stays an
ordinary close.
sig10(sig10(E_signal) / (Q m)) is under the slipped tick-built fill quote.
The tie band is removed. Inside the unified scope, the explicit market
long's money check on the unslipped next-bar quote is never reached.
own strategy.close() or strategy.close_all() of the position it
opposes is checked by rule 2 only.
the entry at its entry() call.
then the exits the open reaches, then the margin check on what is left. Two
kinds of order fill before that check:
and whose entry holds units of the position; an exit armed for an entry
that holds nothing fills nothing there. from_entry_units, the units an
exit's entry holds, is shared with the process_orders_on_close bracket
ranking in flush_pending_bracket_legs, whose inert exit also needs an
entry with no working order; each site keeps its own test;
Two shapes keep the earlier order:
while the open does not re-size it, is a queued order, so it executes
before a stop the open gaps through (TradingView's tape of
axealgo-tp-sl-toolkit-axealgo on OANDA:XAUUSD: the call of 1, then the
stop's 1.62). A call the open re-sizes is the open's own check, after the
exits; no tape decides that shape yet.
remainder still short keeps the call at the open first. No tape decides
that case yet.
test_point_order_open_call pins both shapes, each with a control.
the entry incarnation it filled under.
open close-ledger records, one per entry fill not yet booked, not the
physical lots. An exit armed for one opening books that opening first.
Every rule runs only on a power-of-ten lot grid, which every tape and every
population member uses. The unified admission also leaves out
calc_on_order_fills, the bar magnifier, stops that reverse, default-sized
stops, a resting book and same-open pairs; those keep the earlier rules. New
durable state is folded into the source-adapter hash only while it is set.
Three rules are left out, because nothing tells them apart from the current
behaviour. Decision counters ran over every ctest fixture and 198 replayed
population scripts and found no divergence:
docs/pine-adapter-kernel-notes.md section 1.8 names the TradingView control
each one needs.
Fixtures:
gap_admission, point_order_and_book, stop_priority and explicit_short.
trades as a backtest and as a stream; the other three cross a holiday
that a stream takes as an in-session gap.
recorded row exactly, with and without the 1e-05 grid.
re-pinned on TradingView's own tape of it (explicit_short/offset0-fill).
TradingView fills that order, so its literal check moves to the -.00032
offset, where the order is declined.
entries the fill half now reproduces.
lot grid, rule 2 drops a default long from flat one ulp under the cost, as
TradingView's margin_ledger_rules tape eth-flat-m100-ulp-under does.
The witness tables move on hash fields only. Every closed trade of every
run-pass is identical, field for field, to the parent commit's.
The margin-rules notes said the unified admission ships off; it now ships
on, so these sentences of docs/pine-adapter-kernel-notes.md are replaced:
Co-Authored-By: Claude Opus 5.5 (1M context) [email protected]
Measurement
Full population against the active baseline: 7,989 probes, all measured, 6 up, 0 down, all strong → excellent:
Disclosure: the NSE:NIFTY 15m rise rests on the trade count alone. Its exact TradingView rows are unchanged (668 → 668), and its unmatched pairs go from 1 to 2: a same-bar reversal and an opposite add are filled in the other order. That ordering is filed as a pin item; no tape decides it today.
At trade level, against the base: 184 probes match TradingView better, 1 is mixed (+6 / −1 exact rows), 1 is the NIFTY case above, and 0 are worse. In all, 2,547 exact rows are gained and 1 is lost. The witness tables move no trade. CI profiles are posted as
pineforge/verify; the sweep is posted aspineforge/parity.🤖 Generated with Claude Code