R5 wave 2: native margin model, calculation timing, stream-mode HTF subscriptions (L4/L5/L6b) - #262
Merged
Merged
Conversation
…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>
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.
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):
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_callNativeCalculationTrigger(BarClose / BarCloseAndFills / EveryModeledPoint),max_recalculations_per_point,NativeOpenBarView;on_native_recalculate(all calculations route through it, default forwards toon_native_bar),on_native_sub_bar,current_partial_bar(); documented callback chronologystream_begin; warmup == batch, live buckets delivered with the batch rule; a subscribed stream takes confirmed bars onlyPlus a commit porting the three lanes' hash-neutrality guards to
native_run_spec_digest()(machine-independent; proven underTZDIR/TZvariations).Evidence
ci_verify releasePASS (499 / 499 / 501); lane tests 166 / all scenarios / 299 checks incl. adapter twins and fail-before runs.ci_verify release29/29 +kernel24/24 stages PASS; epochs still v3 / v6 / v18 exactly once.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