Skip to content

R5 wave 2: native margin model, calculation timing, stream-mode HTF subscriptions (L4/L5/L6b) - #262

Merged
luisleo526 merged 4 commits into
mainfrom
r5/int2-20260920
Sep 20, 2026
Merged

luisleo526 merged 4 commits into
mainfrom
r5/int2-20260920

Conversation

@luisleo526

Copy link
Copy Markdown
Collaborator

What

Three more lanes of the native feature-parity roadmap (#256), each its own commit, opt-in for native hosts and byte-neutral for the Pine adapter (never edited):

Lane Native capability
L4 margin model NativeMarginModel (per-side initial + maintenance margin, liquidation sizing RestoreMinimum / ShortfallMultiple / Flatten, PathAdverseExtreme / CalculationOnly checks); kernel-originated liquidation requests (RequestOrigin::KernelLiquidation, CancelReason::Superseded, MarginCallEvent); native_liquidation_price(), resolve_margin_call_units, on_native_margin_call
L5 calculation timing NativeCalculationTrigger (BarClose / BarCloseAndFills / EveryModeledPoint), max_recalculations_per_point, NativeOpenBarView; on_native_recalculate (all calculations route through it, default forwards to on_native_bar), on_native_sub_bar, current_partial_bar(); documented callback chronology
L6b stream HTF subscriptions accepted by stream_begin; warmup == batch, live buckets delivered with the batch rule; a subscribed stream takes confirmed bars only

Plus a commit porting the three lanes' hash-neutrality guards to native_run_spec_digest() (machine-independent; proven under TZDIR/TZ variations).

Evidence

  • Per lane: supervisor fresh ci_verify release PASS (499 / 499 / 501); lane tests 166 / all scenarios / 299 checks incl. adapter twins and fail-before runs.
  • Integrated: ctest 516/516, ci_verify release 29/29 + kernel 24/24 stages PASS; epochs still v3 / v6 / v18 exactly once.
  • Campaign sweep on this tree: running (exp-r5-int2-wave2-20260920); merge only on no regression (net 0 accepted).

Merge with rebase (one commit per lane).

🤖 Generated with Claude Code

https://claude.ai/code/session_01CSmYixVAp4NqWpBZxkrLPT

luisleo526 and others added 4 commits September 20, 2026 12:17
…uidation, host hooks (R5 lane L4)

native_run_spec_v3: `margin` (NativeMarginModel: initial_long/short,
optional maintenance_long/short, NativeLiquidationSizing RestoreMinimum |
ShortfallMultiple | Flatten with shortfall_multiple, liquidation_min_units,
NativeLiquidationCheck PathAdverseExtreme | CalculationOnly), mutually
exclusive with initial_margin_fraction and folded into the continuation
hash only when present. With maintenance set the kernel computes the
liquidation level at each script-bar open and after each applied fill and
rests a kernel-originated Reduce/Flatten at that level (RequestOrigin
KernelLiquidation on the definition, hashed only when not Host;
CancelReason::Superseded on re-price; MarginCallEvent joins CommandEvent).
engine_script_run_v18 gains native_liquidation_price(),
resolve_margin_call_units(const NativeMarginCallView&) and
on_native_margin_call(). TradingView's call sizing, rounded-money rule
and tick-quantized call pricing stay in the adapter, which is untouched.

Tests: tests/test_native_margin_model.cpp (166 checks: neutrality without
`margin` pinned by event count and hash against the pre-lane library,
per-side admission, the three sizing policies, liquidation price,
Superseded re-pricing with one live liquidation request, host override,
call after applied, CalculationOnly, mutual exclusion, twin of the
adapter's margin call). ci_verify release PASS (499). Design:
docs/design/native-feature-parity.md A.3.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSmYixVAp4NqWpBZxkrLPT
(cherry picked from commit 3cb8dbec67c2569dc656baf9ea842556c38aab65)
…point, partial-bar view, open-only bar view (R5 lane L5)

native_run_spec_v3: NativeCalculationTrigger { BarClose (default),
BarCloseAndFills, EveryModeledPoint }, max_recalculations_per_point, and
NativeOpenBarView { Complete (default), OpenOnly } — folded into the
continuation hash only when not default. engine_script_run_v18: every
calculation is routed through on_native_recalculate(bar, ctx, reason,
cause), whose default forwards to on_native_bar; on_native_sub_bar fires
after each lower-timeframe sub-bar's path; current_partial_bar() gives the
O/H/L/C/volume up to the cursor. Chronology contract: match and settle ->
on_native_applied FIFO -> (BarCloseAndFills) one recalculation at the fill
cursor from the existing notification drain under its re-entrancy guard,
bounded per point; requests born in callbacks follow the existing birth
rule (born_on_remaining_path untouched); EveryModeledPoint recalculates at
each magnifier sample / observed print in batch and stream. Recalculations
add no report points. Pine's COOF scheduler and language-state rollback
stay in the adapter, which is untouched.

Tests: tests/test_native_calc_timing.cpp (BarClose default pinned, fill
cascade with the bound, every-modeled-point in batch/intrabar/stream,
sub-bar hook, OpenOnly view, no extra report points, twin against the
adapter's calc_on_order_fills path). ci_verify release PASS (499).
Design: docs/design/native-feature-parity.md A.4.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSmYixVAp4NqWpBZxkrLPT
(cherry picked from commit dc59f8639a0610f713a18add011a01d1a2588fbf)
stream_begin with declared subscriptions is accepted: the historical warmup
resolves the series exactly as a batch of the same bars would (registration,
feed install, prepare_native_security_feeds and the lookahead projection run
over the warmup input), the bucket left open at the warmup/live boundary
becomes the pump's cursor, and each accepted live bar extends the buckets and
delivers on_native_timeframe_bar with the batch delivery rule (lookahead off:
before the completing bar's calculation; lookahead on: at the bucket's first
bar). stream_end never delivers a partial bucket. A stream that declares a
series takes confirmed bars only: stream_push_tick(s) and stream_advance_time
refuse by name. The subscription delivery cursors and the warmup boundary
fold into the continuation hash only when subscriptions are declared, so
every spec without a series keeps its identity. No public symbol, no
virtual, no epoch change.

Tests: tests/test_native_htf_subscriptions_stream.cpp (299 checks: warmup ==
batch buckets and delivery points, live completion before the calculation,
lookahead on, no partial bucket at stream_end, series accessor across the
boundary, tick refusal, neutrality of a spec without a series);
fail-before: 24 failures against the previous consumer. ci_verify release
and native PASS.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSmYixVAp4NqWpBZxkrLPT
(cherry picked from commit 356175f3562b90e49f7d2fb329b035a7528d4eaa)
…st()

The continuation identity folds the host's resolved timezone resources —
this tree's zoneinfo root is /private/var/db/timezone/tz/2026c.1.0/zoneinfo,
a glibc runner's is /usr/share/zoneinfo — so a raw native_continuation_hash()
or stream_state_hash() constant pinned on one machine cannot pass on another.
The three wave-2 lane tests pinned exactly that, the same way the wave-1 lanes
did before b07c57a retired it.

native_run_spec_digest() (native_run_spec_v3) is the consumer's own spec fold
and nothing else; it never reaches hash_tz_identity, which belongs to
continuation_hash() alone. Each of the three tests now pins that digest for
its lane's default spec, asserts it is unchanged when the lane's fields are
restated at their defaults and moves when one is set, and keeps every event,
fill, book, trade and counter assertion it already made:

  test_native_margin_model        margin absent folds nothing; a model left at
                                  every default still moves the fold.
  test_native_calc_timing         BarClose/Complete/8 restated folds nothing,
                                  and the recalculation bound is inert on its
                                  own; trigger or open-bar view moves it.
  test_native_htf_subscriptions_  an empty series list stated outright folds
  stream                          nothing; declaring one moves it.

The remaining continuation and stream-state comparisons are between two runs
in this process. Proven under TZDIR=/nonexistent and TZ=Asia/Kolkata (note
that Darwin ignores TZDIR by design, src/native_calendar.cpp:820-829, so those
runs show insensitivity, not the cross-machine move itself). continuation_hash,
hash_spec's field order and every lane's semantics are untouched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@luisleo526
luisleo526 merged commit b0cec54 into main Sep 20, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant