PineForge unreleased
Deterministic PineScript v6 backtest runtime — C ABI reference
Loading...
Searching...
No Matches
native_host.hpp
Go to the documentation of this file.
1#pragma once
2
8
9#include <cstddef>
10#include <cstdint>
11#include <limits>
12#include <optional>
13#include <string>
14#include <string_view>
15#include <type_traits>
16#include <variant>
17#include <vector>
18
19namespace pineforge {
20inline namespace engine_script_run_v19 {
21
22/// Where a host stands. Read it off native_state().kind; nothing else reports it.
23/// Unconfigured is a fresh host, Ready a staged spec, Running a consumed begin
24/// (with NativeRunPhase saying which driving), Completed a finished run whose
25/// lots and live requests stay visible but not actionable, and Failed a durable
26/// first failure. Cooperative Aborted permits same-key, higher-run reuse;
27/// other failures need a new host. Pinned by tests/test_native_host_repairs.cpp.
28enum class NativeLifecycleKind : std::uint8_t {
30 Ready = 1,
33 Failed = 4,
34};
35
36/// Which driving is Running: a batch run(), a stream's internal warmup, or its
37/// realtime leg. Folded into native_continuation_hash() on purpose — a consumer
38/// mid-warmup and one mid-realtime are not interchangeable continuations — which
39/// is why a batch and a stream over identical bars record different per-bar
40/// broker-state hashes while booking identical trades.
41enum class NativeRunPhase : std::uint8_t {
42 Batch = 0,
43 Warmup = 1,
45};
46
47/// How a Completed run ended: a batch reached the last bar, or a stream was
48/// ended. Reporting only; the book, the report and every hash are what the run
49/// left.
50enum class NativeCompletion : std::uint8_t {
53};
54
55/// The durable first failure of a run, in NativeFailure::code. InvalidSpecification
56/// is a refused spec at configure, Contract a lifecycle misuse (a second
57/// configure, a run number at or under the high water), Preflight a bar array the
58/// driver refused, UnsupportedSource a source-only setter or command on a bare
59/// host, CallbackException a host callback that threw or a C callback that
60/// returned non-zero, and Aborted a cooperative abort. The rest are internal
61/// exhaustion states with no rollback promise. Later run/stream_* calls refuse;
62/// only Aborted permits configure_native with the same key and higher run.
78
79/// Which operation was in flight when the failure latched — the second half of
80/// "what went wrong", beside NativeFailureCode. Presentation only; the kernel
81/// takes no decision on it.
82enum class NativeFailureOperation : std::uint16_t {
83 None = 0,
85 Begin = 2,
87 Input = 4,
91 Stream = 8,
92};
93
94/// In-run failure references. Identifiers belong to NativeFailed.spec->identity;
95/// they never carry a second RunIdentity string. Kind is a bit-union of the
96/// typed alternatives below (Cause=1, Recipient=2, Cursor=4).
107
108/// The event ordinal a failure was caused by, 0 when absent. Populated only when
109/// native_failure_has_cause() is true for the context's kind.
111 std::uint64_t ordinal = 0; // 0 = absent
112};
113
114/// The request incarnation a failure was addressed to, 0 when absent. Populated
115/// only when native_failure_has_recipient() is true.
117 std::uint64_t incarnation = 0; // 0 = absent
118};
119
120/// Where on the modeled path a failure happened: the driver point's coordinate and
121/// its interpolation position t. Populated only when native_failure_has_cursor()
122/// is true.
125 double t = 0.0;
126};
127
128/// The three in-run facts a failure may carry, tagged by kind. Copy and move are
129/// allocation-free — this is what a failed host reports from inside a callback —
130/// and the predicates below say which alternatives are populated rather than
131/// asking a caller to decode the bit-union itself.
138
139/// The bit-union under NativeFailureContextKind: Cause=1, Recipient=2, Cursor=4.
140/// Prefer the three predicates below to testing these bits by hand.
141constexpr std::uint8_t native_failure_context_bits(NativeFailureContextKind kind) noexcept {
142 return static_cast<std::uint8_t>(kind);
143}
144/// Whether a context of this kind populates its NativeInRunCause.
146 return (native_failure_context_bits(kind) & 1u) != 0;
147}
148/// Whether a context of this kind populates its NativeInRunRecipient.
150 return (native_failure_context_bits(kind) & 2u) != 0;
151}
152/// Whether a context of this kind populates its NativeInRunCursor.
154 return (native_failure_context_bits(kind) & 4u) != 0;
155}
156/// Whether this context populates its NativeInRunCause. The overload a reader of
157/// native_state().failure.context wants.
158constexpr bool native_failure_has_cause(const NativeFailureContext& context) noexcept {
159 return native_failure_has_cause(context.kind);
160}
161/// Whether this context populates its NativeInRunRecipient.
162constexpr bool native_failure_has_recipient(const NativeFailureContext& context) noexcept {
163 return native_failure_has_recipient(context.kind);
164}
165/// Whether this context populates its NativeInRunCursor.
166constexpr bool native_failure_has_cursor(const NativeFailureContext& context) noexcept {
167 return native_failure_has_cursor(context.kind);
168}
169
170/// The kind that says exactly these three alternatives are populated.
172 bool cause, bool recipient, bool cursor) noexcept {
173 return static_cast<NativeFailureContextKind>(
174 (cause ? 1u : 0u) | (recipient ? 2u : 0u) | (cursor ? 4u : 0u));
175}
176
177/// A context carrying one causing event ordinal. A zero ordinal is "absent" and
178/// yields the None kind rather than a Cause with nothing in it.
179inline NativeFailureContext native_failure_cause(std::uint64_t ordinal) noexcept {
180 NativeFailureContext context;
181 if (ordinal == 0) return context;
183 context.cause.ordinal = ordinal;
184 return context;
185}
186/// A context carrying one addressed request incarnation. A zero incarnation is
187/// "absent", as above.
188inline NativeFailureContext native_failure_recipient(std::uint64_t incarnation) noexcept {
189 NativeFailureContext context;
190 if (incarnation == 0) return context;
192 context.recipient.incarnation = incarnation;
193 return context;
194}
195/// A context carrying one path cursor. A cursor is always meaningful, so there is
196/// no absent spelling.
197inline NativeFailureContext native_failure_cursor(NativeCoordinate point, double t = 0.0) noexcept {
198 NativeFailureContext context;
200 context.cursor.point = point;
201 context.cursor.t = t;
202 return context;
203}
204
205/// Copies only ordinals/incarnation/cursor scalars. Foreign run identities are
206/// dropped rather than stored under the failed spec's identity.
208 const native_order::RunIdentity& run,
209 const native_order::EventId* cause,
210 const native_order::RequestHandle* recipient,
211 const native_order::MatchCursor* cursor) noexcept {
212 NativeFailureContext context;
213 bool has_cause = false;
214 bool has_recipient = false;
215 bool has_cursor = false;
216 if (cause != nullptr && cause->ordinal != 0 && cause->run == run) {
217 has_cause = true;
218 context.cause.ordinal = cause->ordinal;
219 }
220 if (recipient != nullptr && recipient->incarnation != 0 && recipient->run == run) {
221 has_recipient = true;
222 context.recipient.incarnation = recipient->incarnation;
223 }
224 if (cursor != nullptr) {
225 has_cursor = true;
226 context.cursor.point = cursor->point;
227 context.cursor.t = cursor->t;
228 }
229 context.kind = native_failure_context_kind(has_cause, has_recipient, has_cursor);
230 return context;
231}
232
233/// The durable record native_state().failure answers: the code, the operation it
234/// happened in, an optional event ordinal and discriminator, and the
235/// allocation-free context. last_error() is presentation text beside it and is
236/// never the authority. Copy and move do not allocate.
244
245/// The NativeLifecycle alternatives, one per NativeLifecycleKind. Ready, Running
246/// and Completed own a copy of the staged spec; Failed owns it only when configure
247/// got that far. NativeStateView is the flattened read a host uses; this variant is
248/// the consumer's own storage.
253struct NativeFailed { std::optional<NativeRunSpec> spec; NativeFailure failure; };
254
255/// The lifecycle as one value. Exhaustive over the five alternatives above.
258
259/// The RunIdentity the failed spec carried, or nullptr when configure failed
260/// before staging one. This is how a caller names the run a failure belongs to
261/// without the failure carrying a second identity string of its own.
263 const NativeFailed& failed) noexcept {
264 return failed.spec ? &failed.spec->identity : nullptr;
265}
266
267static_assert(std::is_trivially_copyable_v<NativeInRunCause>);
268static_assert(std::is_trivially_copyable_v<NativeInRunRecipient>);
269static_assert(std::is_trivially_copyable_v<NativeInRunCursor>);
270static_assert(std::is_trivially_copyable_v<NativeFailureContext>);
271static_assert(std::is_trivially_copyable_v<NativeFailure>);
272static_assert(std::is_nothrow_copy_constructible_v<NativeFailure>);
273static_assert(std::is_nothrow_copy_assignable_v<NativeFailure>);
274static_assert(std::is_nothrow_move_constructible_v<NativeFailed>);
275static_assert(std::is_nothrow_move_assignable_v<NativeFailed>);
276
277/// The flattened run state native_state() answers: the lifecycle kind, a borrowed
278/// pointer to the staged spec (nullptr when Unconfigured), the phase, how a
279/// Completed run ended, the durable failure, the consumed run-number high water
280/// and the monotonic decision floor. The spec pointer is valid until the next
281/// configure or begin. C spelling: strategy_native_state_v1 (no spec, no failure context).
291
292/// The book as one aggregate: signed units, the volume-weighted average entry
293/// price and the number of open physical lots. physical_position() answers it;
294/// native_open_lots(mark) is the same book lot by lot. C spelling:
295/// strategy_native_position_v1.
297 double signed_units = 0.0;
298 double average_price = 0.0;
299 std::size_t lot_count = 0;
300};
301
302/// Owning value row for one open physical lot, copied at query time by
303/// native_open_lots(mark) — the lot-by-lot view of the same book
304/// physical_position() aggregates. Every field is what the book already
305/// holds; nothing is computed that the kernel does not already keep.
306///
307/// Identity: `ordinal` is the lot's position in the book (oldest first),
308/// `entry_incarnation` the request record whose fill opened it (never
309/// reused; 0 only for a legacy synthetic lot) and `cycle` the position cycle
310/// the lot belongs to (the value BindOpening / BindOpenings name).
311///
312/// Booking: `entry_label` / `entry_comment` are the opening request's own,
313/// `entry_time_ms` / `entry_bar_index` its fill point, `entry_price` the
314/// booked price, `signed_units` the lot's remaining units (> 0 long, < 0
315/// short) and `entry_commission` the entry fee still on the lot in account
316/// currency — a partial realization takes its share with it.
317///
318/// Marked: `unrealized_pnl` is the lot's own term of native_marked_equity(mark)
319/// — the move from `entry_price` to `mark`, in account currency, less
320/// `entry_commission` — so the marked equity is the realized balance plus the
321/// sum of these rows. `favorable_excursion` / `adverse_excursion` are the
322/// largest moves for and against the lot the kernel has sampled along the
323/// delivered path, in account currency, with `mark` itself folded in; both
324/// are gross of fees and never negative. A host that owns lot excursions
325/// (owns_lot_excursions) keeps its own sampler, so for that run the kernel's
326/// two fields fold `mark` alone. A NaN `mark` keeps every booking fact,
327/// leaves `unrealized_pnl` NaN and folds nothing into the excursions.
329 std::size_t ordinal = 0;
330 std::uint64_t entry_incarnation = 0;
331 std::int64_t cycle = 0;
332 native_order::Side side = native_order::Side::Long;
333 std::string entry_label;
334 std::string entry_comment;
335 std::int64_t entry_time_ms = 0;
337 double entry_price = 0.0;
338 double signed_units = 0.0;
339 double entry_commission = 0.0;
340 double mark = std::numeric_limits<double>::quiet_NaN();
341 double unrealized_pnl = std::numeric_limits<double>::quiet_NaN();
343 double adverse_excursion = 0.0;
344};
345
346/// Callback-local view of the same FIFO row. Text borrows the physical lot;
347/// arbitrary label/comment widths require no per-row allocation.
349 std::size_t ordinal = 0;
350 std::uint64_t entry_incarnation = 0;
351 std::int64_t cycle = 0;
352 native_order::Side side = native_order::Side::Long;
353 std::string_view entry_label;
354 std::string_view entry_comment;
355 std::int64_t entry_time_ms = 0;
357 double entry_price = 0.0;
358 double signed_units = 0.0;
359 double entry_commission = 0.0;
360 double mark = std::numeric_limits<double>::quiet_NaN();
361 double unrealized_pnl = std::numeric_limits<double>::quiet_NaN();
363 double adverse_excursion = 0.0;
364};
365
366/// The account row that follows an applied execution in the event history: the
367/// shared ordinal, the effective time, the marked equity, the realized balance and
368/// the signed book after it. One per applied execution, so an applied event and
369/// its observation share an ordinal — advance an event cursor by the last returned
370/// ordinal, never mid-group.
372 uint64_t ordinal = 0;
373 int64_t effective_time_ms = 0;
374 double marked_equity = 0.0;
375 double realized_balance = 0.0;
376 double signed_units = 0.0;
377};
378
379/// Which of NativeMarketEvent's three alternatives is populated.
380enum class NativeEventKind : std::uint8_t {
384};
385
386/// One owning row of native_events(after_ordinal): a command event, a driver point
387/// or an account observation, tagged by kind. Later commands and the next run's
388/// reset do not invalidate a row already returned. C spelling: strategy_native_events_v1,
389/// one tagged POD with each kind's documented fields; the rest is C++-only in 1.0.
392 uint64_t ordinal = 0;
393 std::optional<native_order::CommandEvent> command;
394 std::optional<NativeDriverPoint> driver;
395 std::optional<NativeAccountObservation> account;
396};
397
398/// Whether a setup call applied its value or refused it. Failed leaves engine
399/// storage untouched.
400enum class NativeSetupStatus : std::uint8_t { Applied = 0, Failed = 1 };
401
402/// What configure_native answers: the status and, on refusal, the first error
403/// field validate_native_run_spec found. A refusal changes nothing — there is no
404/// partial apply.
409
410/// What configure_native_fx_curve answers: the status and, on refusal, the curve
411/// validation with the index of the first bad point. A refusal leaves the staged
412/// curve as it was.
417
418/// Why append_auxiliary_bars refused. Every enumerator is one of the causes
419/// that call's contract already names, and none of them is a run-spec field, so
420/// this is its own word list rather than a NativeRunSpecError: the appended
421/// bars are a live input, not a staged value. HostFailed and Reentrant are the
422/// two legality refusals every public stream input shares — a host that has
423/// already latched its durable failure, and a call made from inside a callback
424/// or an in-flight input, which is itself the Contract failure that latches
425/// one. The rest change nothing and do not fail the host.
426enum class NativeAuxiliaryAppendError : std::uint8_t {
427 None = 0,
428 /// The host had already failed; nothing was read.
430 /// Called from inside a callback or an in-flight input. This call LATCHES
431 /// NativeFailureCode::Contract — it is the one refusal here that does.
433 /// The run is not on its realtime leg (a batch, or a stream still in
434 /// warmup). There is no live feed to append to.
436 /// The run declared no auxiliary feed, in its spec or at begin.
438 /// A null array with a non-zero count. A null array of zero bars is
439 /// accepted and is a no-op.
441 /// `index` is a bar native_bar_structurally_valid refuses.
443 /// `index` is a bar that is not strictly after its predecessor — the one
444 /// before it in this call, or the feed's last bar for index 0.
446 /// The first bar opened inside an input period the run has already
447 /// accepted. Its slice is closed, and folding it late would build a series
448 /// no batch of the same bars could.
450 /// Growing the appended-bar store threw. This one DOES fail the host.
452};
453
454/// What append_auxiliary_bars_result answers: the status, the refusal by name,
455/// and which bar OF THIS CALL it stopped on. `index` is 0 for every refusal
456/// that is not about one bar, and for an Applied append. A refusal appends
457/// nothing — there is no partial append.
463
464/// Which price a current execution settles at: the active callback's quote as
465/// presented, or that quote on the instrument's nearest tick. Configured
466/// directional slippage applies once either way.
467enum class NativeCurrentPriceRule : std::uint8_t { AsPresented = 0, NearestTick = 1 };
468/// Where a price came from: the callback's own market decision point, or the
469/// execution it is anchored to. A current execution inherits its cause's quote, so
470/// a chain does not compound slippage.
471enum class NativeCurrentQuoteKind : std::uint8_t { MarketDecision = 0, ExecutionAnchor = 1 };
472
473/// Read-only owning-value facts for one candidate. The host is already the
474/// engine, so no engine handle or prepared execution token is exposed here.
502
503/// Ephemeral factual view of one prepared execution before any physical effect.
520
521/// The host is consulted before generic opening-margin admission. Admit keeps
522/// the native default gate; AdmitWithHostMargin lets a host that owns the
523/// source-compatible margin rule take responsibility for that one check.
524/// Proceed remains an alias for the v7 spelling used by existing C++ callers.
525enum class NativePrecommitVerdict : std::uint8_t {
526 Admit = 0,
530};
531
532/// Ephemeral factual view of one kernel-issued liquidation before its units
533/// are fixed. `position` is the physical book being liquidated, `mark` the
534/// sizing price the kernel measured the breach at, `equity` the marked equity
535/// there and `required` the maintenance requirement of the whole position at
536/// that same mark. A host that answers with a value owns the slice quantity.
544
545/// Which kernel check point is about to test the maintenance requirement.
546/// BarOpen is the script bar's open, after on_native_bar_open and before the
547/// bar's own matching; AfterApplied is the re-arm that follows a point's
548/// applied fills, the only mid-path check of a bar walked on its modeled
549/// waypoints; IntrabarSample is every later delivered sample of a run whose
550/// intrabar path is matched as continuous segments (IntrabarPath::lower_tf
551/// with SampleEligibility::ContinuousSegments), which has no whole-bar
552/// waypoint model: each is measured at its own price immediately before it
553/// is matched, as the bar's first sample is at BarOpen, so a breach inside the
554/// bar rests its liquidation at the sample that crossed and the path reaches
555/// it there. A one-price distribution path (synthesized, or
556/// DistributionSamples) is not offered it -- a request armed at a discrete
557/// point is matched only at a later one -- and is checked at its first
558/// sample and after fills;
559/// Calculation is the script calculation of a CalculationOnly model; FxRoll is
560/// a step of the
561/// run's declared NativeFxCurve: the first driver point the account converts
562/// at a different rate than the point before it, offered immediately before
563/// that point is matched, with the price where the walk left it -- the
564/// requirement moved though no price did. A run that declares no curve has no
565/// such point, and a CalculationOnly model, which measures at its calculation
566/// alone, is not offered it. These are the kernel's own points: a broker model
567/// that checks somewhere else is a host policy, expressed by suppressing the
568/// points it does not share.
569enum class NativeMarginCheckKind : std::uint32_t {
575};
576
577/// Ephemeral factual view of one kernel check point, offered to the host
578/// before the check runs. `mark` is the price the kernel would measure the
579/// breach at; the modeled path phase is `cursor.point.path_phase`.
583 double mark = 0.0;
585 /// Whether the model already holds a liquidation resting from an earlier
586 /// admitted point. A host that suppresses points -- and therefore owns
587 /// when a slice sized on a book that has since shrunk is re-sized -- needs
588 /// to tell "re-size the live slice" from "take a new one" apart. The
589 /// default host admits every point and never reads this.
591};
592
593/// Ephemeral factual view of the numbers the kernel is about to compare, at
594/// one check point, BEFORE the breach test. `equity` is the marked equity on
595/// the model's own basis and `required` the kernel's maintenance requirement
596/// of the whole position at `mark`; both are exactly what the kernel would
597/// compare if the host answered nullopt.
606
607/// The host's answer to one requirement view. `required` and `equity` replace
608/// the kernel's two numbers for this check point only -- they are a broker's
609/// money rule (a rounded requirement, a fee-adjusted equity), never a second
610/// account. `force_breach` makes the kernel proceed past `required > equity`
611/// even when the answered numbers do not meet it; the sizing policy and
612/// resolve_margin_call_units then decide the slice as usual.
614 double required = 0.0;
615 double equity = 0.0;
616 bool force_breach = false;
617};
618
619/// Which trigger of an anchored leg the owner's fill is about to supply.
620enum class NativeAnchoredTrigger : std::uint8_t {
621 Limit = 0,
622 Stop = 1,
624};
625
626/// Ephemeral read-only facts of one anchored-leg materialization (L7b),
627/// offered to the host exactly once, before the ArmedEvent is built. `owner`
628/// is the request whose fill arms the leg, `owner_applied_ordinal` that fill's
629/// ExecutionAppliedEvent, `owner_lot_incarnation` the lot it opened,
630/// `owner_fill_price` its resolved price and `owner_cursor` its cursor. `leg`
631/// is the anchored request, `leg_side` the side it trades on (a closing leg
632/// trades against the lot the fill opened), `trigger` which trigger receives
633/// the level, `offset` the anchor's resolved offset in price units,
634/// `price_tick` the run's tick (0 when the run has none) and `kernel_level`
635/// the level the kernel would install: fill + offset after the anchor's own
636/// rounding. A host that answers with a value owns the installed level; the
637/// kernel's representability check still applies.
651
652/// The run's generic risk ledger (L9), as the kernel holds it. Every field is
653/// zero / absent for a run that declares no NativeRunSpec::risk.
654///
655/// `blocked` is whether openings are refused right now, and `reason` names the
656/// limit that did it — a drawdown or consecutive-loss-days block lasts to the
657/// end of the run, the two intraday blocks to the end of their own day.
658/// `day_ordinal` is the risk day the ledger is on (the spec's own day basis),
659/// `fills_today` the applied fills counted in it, `consecutive_loss_days` the
660/// streak of days that closed with a realized loss, `peak_equity` the running
661/// peak of the marked equity and `day_open_equity` the equity the current day
662/// opened at. `has_day` is false before the first evaluated point.
664 bool blocked = false;
665 std::optional<native_order::RiskLimitKind> reason;
666 bool has_day = false;
667 std::int64_t day_ordinal = 0;
668 std::uint64_t fills_today = 0;
669 std::uint32_t consecutive_loss_days = 0;
670 double peak_equity = 0.0;
671 double day_open_equity = 0.0;
672};
673
674/// What current_execution_point() answers inside a callback: the point's decision
675/// context, its price, which quote that price is, and the ordinal the quote came
676/// from. nullopt outside a decision point. C spelling: pf_native_decision_v1's
677/// price and quote_kind, on every callback (no quote origin ordinal).
684
685/// Read-only projection of a live generic Trail request. Before its arm is
686/// reached, activated is false and the numeric/ordinal fields are zero. Once
687/// armed, best_price and current_level are the exact raw matcher values and
688/// activation_ordinal identifies the TrailArm event that began tracking.
690 bool activated = false;
691 double best_price = 0.0;
692 double current_level = 0.0;
693 std::uint64_t activation_ordinal = 0;
694};
695
696/// Owning value row for one live request, copied at query time. The
697/// definition is the accepted (and, for an anchored leg, already materialized)
698/// request; remaining is what is left to execute; trigger_state is where the
699/// request's own trigger has reached. Later commands do not invalidate a row
700/// that was already returned.
706
707/// Which of a request's two free-text identity fields a bulk predicate reads.
708/// Both are host text the kernel only copies and compares: Comment is the
709/// established cancel_where selector and keeps value 0, Label is the field a
710/// host that names its orders puts its own id in.
711enum class NativeRequestField : std::uint8_t { Comment = 0, Label = 1 };
712
713/// Why a current-execution command cannot be consumed here. Every value is a fact
714/// about the command or the phase, never a host verdict: the host's own veto is
715/// validate_execution_precommit. strategy_native_execute_current_v1 answers the
716/// same verdicts in C.
722
723/// A synchronous execution of one request accepted or replaced in this very
724/// callback: a target handle and a price rule, and nothing else. Membership,
725/// quantity and ownership come from the request; this command cannot supply
726/// another selection, a saved cursor, a price, a ticket or a prepared financial
727/// plan. Pinned by tests/test_native_current_execution.cpp.
732
733/// Recomputed observations, never an apply token. Readiness is the financial
734/// pre-source preparation boundary, independent of account projection validity
735/// and excluding opening admission and late counter/lifecycle checks. A
736/// readiness of execution::Status::UnrepresentableQuantity is a quantity the
737/// settlement cannot book exactly on this book, which execute_current answers
738/// as a MatchRejectedEvent with MatchRejectReason::UnrepresentableQuantity;
739/// the run goes on. The request core's check that the fill can be taken off
740/// the request's own units, and the quantity grid's re-check of a boundary
741/// Reduce, are made at execution only, so a request whose preview is Applied
742/// can still be refused that way.
744 std::optional<NativeCurrentRefusal> refusal;
745 std::optional<execution::Status> settlement_readiness;
747 std::vector<double> closed_row_pnl;
748 std::optional<native_order::MatchRejectReason> terms_rejection;
749 std::optional<native_order::CancelReason> terms_cancellation;
750};
751
752/// What execute_current answers: a refusal, or the applied outcome. Execution
753/// revalidates, so a preview obtained earlier is an observation and never an
754/// apply token.
758
759/// Borrowed begin-call facts. The bar/input/syminfo/override pointers expire when
760/// prepare_native_begin returns; retained configuration must copy them by
761/// value (for example into NativeRunSpec::intrabar).
763 const Bar* bars = nullptr;
764 int n = 0;
765 std::string input_tf;
766 std::string script_tf;
767 bool bar_magnifier = false;
773 const InputsMap* inputs = nullptr;
774 /// The rich run overload's symbol metadata is borrowed only for this
775 /// callback. A provider that uses it must copy the fields it needs into
776 /// its retained NativeRunSpec/staged metadata before returning.
777 const SymInfo* syminfo = nullptr;
778 const void* overrides_opaque = nullptr;
779 bool is_stream = false;
780 int warmup_n = 0;
781 /// Which public overload began the run: the bare run(bars, n) lifecycle
782 /// (true) or a timeframe-aware / magnified / stream begin (false). A host
783 /// may keep lifecycle surfaces (for example its higher-timeframe series
784 /// evaluators) off for the bare overload; empty timeframes alone do not
785 /// identify it, they only request auto-detection.
786 bool simple_run = false;
787};
788
789/// Accepted input facts presented before the generic consumer aggregates the
790/// bar into its script interval or evaluates any matching point. This is not a
791/// source-language callback: native hosts may observe raw input cadence through
792/// it without taking ownership of matching or aggregation.
799
800/// One accepted realtime print before native matching at its current decision
801/// point. The Bar is a value presentation of that print (O=H=L=C=price,
802/// volume=print quantity, timestamp=print timestamp); no source-language
803/// policy is embedded here. Sequence zero retains the public TradeTick
804/// sentinel meaning “provider did not supply a sequence”.
809
810/// One completed higher-timeframe bucket of a declared subscription
811/// (NativeRunSpec::subscriptions), presented before the calculation of the
812/// input bar it is delivered on.
813///
814/// `subscription` indexes NativeRunSpec::subscriptions. `interval` is the
815/// bucket's own calendar interval: its period at the subscription's timeframe,
816/// located by its first contributing bar through the run's session calendar,
817/// and left zeroed when that lookup has no answer. For a series built from the
818/// auxiliary feed (NativeSeriesSource::AuxiliaryFeed) a contributing bar is a
819/// FEED bar, while `delivered_at_ms` stays the accepted input it rides on.
820/// `completion` is Confirmed when the bucket completed on its own last
821/// contributing input bar, a bucket the session close clips included, and
822/// LazyComplete when the next period's first input closed it (a feed hole over
823/// its last slot). `delivered_at_ms` is the input bar the delivery rides on:
824/// under lookahead_off the input that completed the bucket (its own last
825/// contributing bar when Confirmed, the next period's first input bar when
826/// LazyComplete); under lookahead_on the bucket's first contributing bar.
828 std::size_t subscription = 0;
830 NativeCompletionKind completion = NativeCompletionKind::Confirmed;
831 std::int64_t delivered_at_ms = 0;
832};
833
834/// Why the kernel is asking the host to calculate. BarClose is the script
835/// bar's own calculation and is delivered for every run, whatever the spec's
836/// NativeCalculationTrigger is: every calculation is routed through
837/// on_native_recalculate, whose default forwards to on_native_bar, so a host
838/// that only implements on_native_bar sees exactly what it saw before.
839/// OrderFill is one recalculation at the cursor of an applied execution
840/// (NativeCalculationTrigger::BarCloseAndFills and above) and carries that
841/// event as its cause. Tick is one recalculation at a modeled path point or
842/// an observed print (NativeCalculationTrigger::EveryModeledPoint). SubBar is
843/// reserved: a lower-timeframe sub-bar has its own hook, on_native_sub_bar,
844/// and is never delivered through on_native_recalculate.
845enum class NativeCalculationReason : std::uint8_t {
848 Tick = 2,
850};
851
852// Most-derived native strategy host. Binds NativeExecutionConsumer in the
853// protected engine constructor. Noncopyable and nonmovable. Lives in the
854// same inline engine epoch as BacktestEngine so old-header/new-library
855// linkage cannot resolve an unversioned constructor against a different
856// base layout.
857#define PINEFORGE_HAS_NATIVE_STRATEGY_HOST_V19 1
858/// The public native host: an abstract subclass of BacktestEngine with no
859/// PineScript on it. Subclass it, override on_native_bar (the only pure-virtual),
860/// configure_native(spec), then run() or the stream_* family. Noncopyable and
861/// nonmovable: the constructor binds the native consumer, and there is no
862/// attach/replace switch. Do not override the inherited on_bar (it is final) and
863/// do not write protected engine fields. The whole surface, feature by feature, is
864/// docs/pages/native-engine.md; a worked host is examples/native/hello_kernel.cpp.
866public:
873
874 /// The engine's own bar entry, taken over by the native consumer and sealed. A
875 /// native host calculates in on_native_bar; this override is what makes overriding
876 /// on_bar a compile error rather than a silently dead callback.
877 void on_bar(const Bar& bar) final;
878
879 /// Offered once per begin, before the run starts, with the begin's own arguments —
880 /// the bars, the timeframe literals, the magnifier settings, and the rich
881 /// overload's InputsMap / SymInfo / opaque overrides. A provider that reads them
882 /// must copy what it needs before returning: the views expire with the call. The
883 /// default does nothing, which is every bare host. No C spelling: a C run is
884 /// declared up front with strategy_configure_native_ext_v1.
885 virtual void prepare_native_begin(const NativeBeginArgs&) {}
886 /// Offered once per successful begin, after the reset and before any bar. It is
887 /// the one place declare_timeframe_subscriptions and declare_auxiliary_feed are
888 /// legal, and the kernel registers the declared series only after it returns — so
889 /// a host that registers evaluators of its own here keeps them. native_series_bar
890 /// answers nullopt for every index inside it, because nothing is registered yet.
891 /// C spelling: pf_native_callbacks_v1::on_run_begin.
892 virtual void on_native_run_begin() {}
893 /// Called once for every accepted confirmed input bar, before that bar is
894 /// aggregated or matched. It has no current execution point.
895 virtual void on_native_input(const Bar&, const NativeInputContext&) {}
896 /// Called once for every accepted realtime print, before matching at that
897 /// point. inspect_current_execution/execute_current are legal here.
898 virtual void on_native_tick(const Bar&, const NativeTickContext&) {}
899 /// One completed bucket of a declared higher-timeframe subscription,
900 /// delivered on an accepted input bar before that input is aggregated,
901 /// matched or calculated. Never called for a spec whose `subscriptions`
902 /// are empty. native_series_bar() already answers with this bar here.
903 /// A series built from the auxiliary feed may deliver several buckets on
904 /// one input, oldest first.
906 /// Precedes the matching pass at the script bar's open decision point.
907 /// inspect_current_execution/execute_current are legal in this hook. A host
908 /// that has none says so: declare_native_bar_open_hook(false).
909 virtual void on_native_bar_open(const Bar&, const NativeDecisionContext&) {}
910 /// The current decision point remains valid for the complete callback.
911 /// A host may therefore execute a command after its own script-body work
912 /// returns, before the consumer advances beyond this calculation point.
913 virtual void on_native_bar(const Bar& bar, const NativeDecisionContext& context) = 0;
914
915 /// EVERY calculation of the run arrives here first, including the script
916 /// bar's own close calculation (reason BarClose, cause nullptr), whose
917 /// default forwarding keeps on_native_bar the complete contract for a host
918 /// that never opts into another cadence.
919 ///
920 /// reason OrderFill: one recalculation at an applied execution's cursor,
921 /// driven from the applied-notification drain after that event's
922 /// on_native_applied and bounded by
923 /// NativeRunSpec::max_recalculations_per_point. `cause` is that event and
924 /// is valid only for this call. reason Tick: one recalculation at a
925 /// modeled path point or an observed print, with a null cause.
926 ///
927 /// `bar` is the bar the calculation is about: the script bar under
928 /// delivery in batch, the print's value bar for a stream Tick. It is the
929 /// COMPLETE script bar even mid-path; current_partial_bar() is the
930 /// lookahead-free bar so far, through the last path point consumed (at an
931 /// OrderFill inside a segment, the segment's origin). Commands and
932 /// execute_current are legal here exactly as in on_native_applied.
933 virtual void on_native_recalculate(const Bar& bar, const NativeDecisionContext& ctx,
936 (void)reason;
937 (void)cause;
938 on_native_bar(bar, ctx);
939 }
940
941 /// One completed lower-timeframe sub-bar of an IntrabarPath::lower_tf
942 /// path, delivered after that sub-bar's whole matching path and before the
943 /// next sub-bar's. Never called for a run without a retained lower feed:
944 /// a synthesized path and a plain confirmed bar have no sub-bars of their
945 /// own. The decision point is the sub-bar's last modeled point, so
946 /// commands and execute_current are legal and a request born here follows
947 /// the ordinary birth rule.
948 virtual void on_native_sub_bar(const Bar& sub, const NativeDecisionContext& ctx) {
949 (void)sub;
950 (void)ctx;
951 }
952
953 /// The calculate-on-fill hook: offered once per applied execution, FIFO, after the
954 /// account record and the group/owner/dependency drains. Commands are legal here,
955 /// and a request born here is eligible on the remaining path suffix of a
956 /// continuous segment. Event values stay valid for the call. Throwing latches
957 /// CallbackException. C spelling: pf_native_callbacks_v1::on_applied.
960
961 /// The fill-terms hook, consulted at every matching candidate. Return a resolved
962 /// price, and units for an unresolved HostSized request; the default is the
963 /// identity price with no units, which is what every bare host wants. Answering no
964 /// units for a HostSized candidate is MatchRejectReason::TermsUnresolved. It does
965 /// not supply a second matcher, book or cash path. C spelling: on_execution_terms
966 /// (price, shape, grid) and on_close_units (a host-sized close's units only).
968 const NativeExecutionTermsFacts& facts) const {
969 return {facts.default_resolved_price, std::nullopt,
970 native_order::OpeningShape::Transact};
971 }
972 /// The last gate before a physical effect, offered once per Applied-ready attempt
973 /// and never during inspect_current_execution. Proceed takes the kernel's own
974 /// path, Refuse records a nonfinancial HostPrecommit rejection, and
975 /// AdmitWithHostMargin hands that one opening margin check to the host. The
976 /// default proceeds; a host that keeps it says so:
977 /// declare_native_precommit_hook(false). C spelling:
978 /// pf_native_callbacks_v1::on_precommit, the view flattened into
979 /// pf_native_precommit_view_v1.
984
985 /// Consulted at EVERY kernel check point, BEFORE the breach test, exactly
986 /// as resolve_execution_terms is consulted before a fill is booked. The
987 /// kernel still owns the mechanism -- the level solve, the check points,
988 /// the kernel-originated request, its Superseded re-pricing, the receipt
989 /// and on_native_margin_call; this hook only supplies the two numbers that
990 /// comparison is made of, where brokers legitimately differ. nullopt keeps
991 /// the kernel's own. A host may therefore raise a call the kernel would
992 /// not make (a rounded requirement, a fee-adjusted equity, force_breach)
993 /// or veto one it would (answer numbers that do not breach). Source-
994 /// language money quirks -- TradingView's ten-significant-digit rounding,
995 /// for one -- belong in this hook, never in the run spec.
996 virtual std::optional<NativeMarginDecision> resolve_margin_requirement(
997 const NativeMarginRequirementView&) const {
998 return std::nullopt;
999 }
1000 /// Consulted at each kernel check point before anything is evaluated. A
1001 /// host whose broker model does not check there answers false, and the
1002 /// kernel does not evaluate, re-arm or withdraw at that point: the margin
1003 /// state is left exactly as the last admitted check point left it.
1004 /// Every point the run's check mode reaches is offered, including the ones
1005 /// where the book is flat or the live side has no maintenance fraction --
1006 /// withdrawing a resting liquidation is part of the check. CalculationOnly
1007 /// rests nothing, so it offers only the points it could act on.
1009 return true;
1010 }
1011 /// The kernel's own liquidation sizing, offered to the host before the
1012 /// reduction rests. Returning nullopt keeps the run spec's sizing policy;
1013 /// a returned value is clamped into (0, held] and wins over it. It keeps
1014 /// the last word on units, including over a forced breach.
1015 virtual std::optional<double> resolve_margin_call_units(
1016 const NativeMarginCallView&) const {
1017 return std::nullopt;
1018 }
1019 /// A kernel-issued liquidation that filled. It is delivered after the
1020 /// ordinary on_native_applied for the same fill, with the same cursor.
1022
1023 /// The level an anchored leg (FromOwnerFill) is about to be armed at,
1024 /// offered to the host exactly once per materialization, before the
1025 /// ArmedEvent is built. Returning nullopt installs the kernel level
1026 /// (fill + offset after the anchor's rounding); a returned value is the
1027 /// level to install, still subject to the kernel's representability
1028 /// check, whose failure is the existing PreparationError path. The
1029 /// mechanism (the arm, the once-only materialization, the ArmedEvent,
1030 /// matching) stays the kernel's; only the policy of where the level sits
1031 /// is the host's, exactly as resolve_execution_terms owns the fill price.
1032 virtual std::optional<double> resolve_anchored_level(
1033 const NativeAnchoredLevelView&) const {
1034 return std::nullopt;
1035 }
1036
1037 /// RULING A48 — the ONE generic per-lot excursion capability. A host that
1038 /// returns true here takes ownership of every open lot's favorable/adverse
1039 /// excursion: the consumer stops sampling excursion at matched trigger
1040 /// prices and the closing row takes both magnitudes from
1041 /// closed_lot_excursion(). Facts in, magnitudes out; nothing about the
1042 /// host's price model crosses the boundary in either direction.
1043 virtual bool owns_lot_excursions() const noexcept { return false; }
1044 /// The per-lot excursion a host owns, consulted for every closing row once
1045 /// owns_lot_excursions() answers true. Returning the declined value gives that row
1046 /// the kernel's own zero magnitudes, because nothing was sampled for it — the
1047 /// consumer stops sampling at matched trigger prices for the whole run as soon as
1048 /// ownership is declared. C spelling: pf_native_callbacks_v1::on_lot_excursion,
1049 /// where installing the hook IS declaring ownership.
1051 const ClosedLotExcursionFacts&) const {
1052 return {};
1053 }
1054
1055 /// Which of two optional hooks this host implements (R5 lane D2-A). A host
1056 /// that declares nothing implements both, which is every host written before
1057 /// the declarations existed; a declaration stands, across runs, until the
1058 /// host makes another. Neither moves a value: each lets the kernel skip work
1059 /// whose only reader is a hook the host does not have.
1060 ///
1061 /// declare_native_bar_open_hook(false): on_native_bar_open does nothing, so
1062 /// the kernel does not call it. It keeps every effect of the call's boundary
1063 /// that is its own -- the decision context, the point's epoch, the complete
1064 /// bar at the point's instant, the abort check and the drain of the applied
1065 /// notifications -- so the run is the run of a host whose hook is empty. C
1066 /// spelling: a pf_native_callbacks_v1 without on_bar_open declares it.
1067 void declare_native_bar_open_hook(bool implemented);
1068 /// declare_native_precommit_hook(false): validate_execution_precommit is the
1069 /// default admission, so the kernel does not consult it, and builds the
1070 /// settlement preview it would have been shown (prepare, then project) only
1071 /// for a host that owns lot excursions, whose closed_lot_excursion every
1072 /// closing row of that preview consults. The abort check that follows the
1073 /// hook is kept. C spelling: a pf_native_callbacks_v1 without on_precommit
1074 /// declares it.
1075 void declare_native_precommit_hook(bool implemented);
1076
1077 /// The bar so far, folded from the path points this script bar has
1078 /// already consumed: open of its first point, running high/low, close at
1079 /// the last point consumed. A discrete point — the open of the bar or of a
1080 /// sub-bar, a distribution sample, an observed print — is folded before
1081 /// its callbacks run, so there the bar closes at the cursor. A fill inside
1082 /// a segment (a trigger crossed between two path points) comes before the
1083 /// walk reaches the segment's destination: its on_native_applied and its
1084 /// OrderFill recalculation read a bar that still ends at the segment's
1085 /// origin and does not hold the fill price. It never runs ahead of the
1086 /// cursor. Volume is the activity actually consumed so far — the completed
1087 /// lower-timeframe sub-bars of an intrabar path, or the prints of an
1088 /// observed stream — and stays 0 for a modeled path with no intrabar
1089 /// volume of its own. Valid in the bar-open, applied, tick, sub-bar and
1090 /// recalculation callbacks; nullopt outside a path walk, including in the
1091 /// bar's own close calculation, where the host already holds the complete
1092 /// bar.
1093 std::optional<Bar> current_partial_bar() const;
1094 /// How many recalculations the kernel has driven this run, and how many it
1095 /// suppressed because a point had already spent its
1096 /// max_recalculations_per_point budget. Observation only.
1097 std::uint64_t native_recalculation_count() const;
1098 /// How many recalculations max_recalculations_per_point dropped at their matching
1099 /// point. The executions themselves were still applied and still delivered to
1100 /// on_native_applied; only the calculation they would have driven was skipped. C
1101 /// spelling: strategy_native_recalculations_v1, beside the driven count.
1102 std::uint64_t native_recalculations_skipped() const;
1103
1104 /// The active callback's quote and calendar-derived decision context, as an owning
1105 /// value. nullopt outside a decision point. C spelling:
1106 /// pf_native_decision_v1::price / ::quote_kind, on every callback.
1107 std::optional<NativeCurrentPointView> current_execution_point() const;
1108 /// Where one live trail's own trigger has reached: activated, the running best,
1109 /// the current level and the ordinal it activated at. nullopt when the handle is
1110 /// not a live trail. C spelling: strategy_native_trail_state_v1, with
1111 /// PF_NATIVE_ABSENT for the empty. Pinned by tests/test_native_trail_state_l5k.cpp.
1112 std::optional<NativeTrailState> trail_state(
1113 const native_order::RequestHandle& target) const;
1114 /// A read-only preview of a current execution: the settlement readiness, any typed
1115 /// refusal or terms outcome, and the ordered closed-row P&L for an Applied-ready
1116 /// command. It is never an apply token — execute_current revalidates, and editing
1117 /// the preview cannot authorize or alter a fill. No C spelling in 1.0 (C-SURFACE-2,
1118 /// 1.1.0): strategy_native_execute_current_v1 applies the command, so it is no preview.
1120 /// Consume, synchronously, a request accepted or replaced in this very callback.
1121 /// Answers a refusal or the applied outcome; applied effects and relationship
1122 /// drains are visible before the call returns. Only the named target is consumed.
1123 /// C spelling: strategy_native_execute_current_v1.
1125
1126 /// Append one kernel-owned equity point at this host's report mark.
1127 /// Returns true only in a running KernelRecordedAtHostMarks run; false
1128 /// changes nothing. Call at the desired mark inside a native callback.
1129 /// This is reporting only: it does not book cash or place an order. A
1130 /// host that records per-point broker hashes still owns those hash rows.
1131 /// No C spelling: the C spec cannot select KernelRecordedAtHostMarks.
1132 bool mark_native_report_point(int64_t report_ts);
1133
1134 /// The latest completed bucket delivered for a declared subscription, or
1135 /// nullopt before its first delivery / for an unknown index. Legal inside
1136 /// every native callback, including on_native_timeframe_bar itself. A
1137 /// gaps = true series answers nullopt again on every input bar it
1138 /// delivered nothing on.
1139 std::optional<Bar> native_series_bar(std::size_t subscription) const;
1140
1141 /// Declare this run's higher-timeframe series from inside
1142 /// on_native_run_begin, for a host whose series are known only to its own
1143 /// begin-time registration. The list REPLACES the staged spec's
1144 /// `subscriptions`, and the kernel registers from the staged spec after
1145 /// this callback returns, so a host's own registration cannot erase the
1146 /// kernel's and the run's continuation identity folds what actually ran.
1147 /// Legal only inside on_native_run_begin: anywhere else, and for a list
1148 /// this run's input timeframe would refuse (the same validation
1149 /// configure_native applies), it stages nothing, changes nothing and
1150 /// answers false. Not virtual: the host calls the kernel here, never the
1151 /// other way round.
1152 ///
1153 /// The bool cannot tell those two refusals apart:
1154 /// declare_timeframe_subscriptions_result below answers the same call by
1155 /// name and this spelling is exactly `... .status == Applied`.
1157 std::vector<NativeTimeframeSubscription> subscriptions);
1158 /// The same call, answered the way configure_native answers the identical
1159 /// validation: Applied, or Failed with the first error field
1160 /// validate_native_timeframe_subscriptions found. A call made outside
1161 /// on_native_run_begin -- or on a host that has already failed -- judged
1162 /// no list at all and is NativeRunSpecError::WrongPhase at
1163 /// NativeRunSpecField::None. Same commands, same staging, same
1164 /// refusals as the bool spelling above.
1166 std::vector<NativeTimeframeSubscription> subscriptions);
1167
1168 /// The same begin-time hook for NativeRunSpec::auxiliary_feed: the feed
1169 /// REPLACES the staged spec's own (nullopt withdraws it), and the kernel
1170 /// registers from the staged spec after on_native_run_begin returns. It is
1171 /// judged together with the series staged at that moment, so a host that
1172 /// names both here declares the feed first and its AuxiliaryFeed series
1173 /// second. Legal only inside on_native_run_begin: anywhere else, for a
1174 /// feed this run's input timeframe would refuse, and for one that would
1175 /// leave a staged AuxiliaryFeed series without its bars, it changes
1176 /// nothing and answers false. Not virtual.
1177 ///
1178 /// Three refusals, one bit: declare_auxiliary_feed_result below answers
1179 /// the same call by name, and this spelling is `... .status == Applied`.
1180 bool declare_auxiliary_feed(std::optional<NativeAuxiliaryFeed> feed);
1181 /// The same call, answered the way configure_native answers the identical
1182 /// validation: Applied, or Failed with the first error field the judged
1183 /// feed-and-series pair produced (AuxiliaryFeedNotFinerThanInput for a
1184 /// feed the input refuses, SubscriptionWithoutAuxiliaryFeed for a
1185 /// withdrawal that would strand a staged series). Outside
1186 /// on_native_run_begin nothing was judged: WrongPhase at
1187 /// NativeRunSpecField::None.
1188 NativeSetupResult declare_auxiliary_feed_result(std::optional<NativeAuxiliaryFeed> feed);
1189
1190 /// A realtime stream's later bars of its declared auxiliary feed. They
1191 /// join the feed behind every bar it holds and ride on the next accepted
1192 /// input whose period they opened before — the routing rule a batch of the
1193 /// same bars applies. Legal between stream inputs on a Realtime run that
1194 /// declared a feed. Refused by name, changing nothing and without failing
1195 /// the host: bars out of order or not after the feed's last bar, a bar
1196 /// with invalid OHLCV, and a bar that opened inside an input period
1197 /// already accepted (its slice is closed; no batch could build that
1198 /// series). Calling it from inside a callback is the contract failure
1199 /// every reentrant stream input is.
1200 ///
1201 /// "By name" is what append_auxiliary_bars_result below answers; this
1202 /// spelling is its `status == NativeSetupStatus::Applied` and carries none
1203 /// of the names.
1204 bool append_auxiliary_bars(const Bar* bars, std::size_t n);
1205 /// The same call, answering NativeAuxiliaryAppendError and the bar of this
1206 /// call it stopped on. Same commands, same appended bars, same latched
1207 /// Contract failure for a reentrant call; last_error() stays the
1208 /// presentation text beside it.
1210
1211 /// The only setup call. Copies the candidate spec, normalizes it and stages it
1212 /// atomically: Unconfigured or a Completed run with a larger run number becomes
1213 /// Ready, and a refusal is Failed with no partial apply. Calling it again while
1214 /// Ready is a Contract failure — use a new host to change unconsumed setup. C spelling:
1215 /// strategy_configure_native_v1 / _ext_v1, typed refusal _ext_result_v1.
1217 /// Stage the run's immutable FX epoch, legal only while Ready. Parallel
1218 /// timestamp/rate arrays of equal length, strictly increasing timestamps, finite
1219 /// positive rates; an empty curve clears it and restores the scalar account_fx
1220 /// fallback. Refused with WrongPhase once the run is Running. C spelling:
1221 /// strategy_configure_native_fx_curve_v1, typed refusal _fx_curve_ext_v1.
1223 /// The whole run state as one owning read. The only observation of the lifecycle
1224 /// and of the durable failure; last_error() is presentation text beside it. C
1225 /// spelling: strategy_native_state_v1.
1227
1228 /// Accept one complete request. Answers Accepted with a timeline ordinal and a
1229 /// RequestHandle, or Rejected with a rejection ordinal and a reason. Acceptance is
1230 /// not a fill: no lot and no fee moves here. Legal from a native callback in
1231 /// Batch/Warmup/Realtime, or between realtime inputs on the same thread. C
1232 /// spelling: strategy_native_submit_v1.
1234 /// Replace one live request: validate first, then retire that incarnation and
1235 /// birth a successor with a new handle, a new priority and a predecessor link. A
1236 /// ReplaceRejected leaves the target live; a same-run absent, replaced or terminal
1237 /// handle is NotWorking, a foreign or malformed one InvalidHandle. Every outcome
1238 /// is an event, and no outcome moves a lot. C spelling:
1239 /// strategy_native_replace_v1.
1241 const native_order::Request& request);
1242 /// The deliberately narrow market-default convenience: the same acceptance path as
1243 /// submit, but it REFUSES a nondefault trigger, capacity, owner or group rather
1244 /// than dropping it. No C spelling, by design — the same request is
1245 /// strategy_native_submit_v1 with PF_NATIVE_TRIGGER_MARKET and a zero-filled
1246 /// struct.
1248 /// The same market-default convenience for a replace; see submit_market.
1250 const native_order::Request& request);
1251 /// Replace with options. ReplaceOptions{retain_trigger_state = true} carries the
1252 /// predecessor's live trigger state — a tracking trail's best, an already active
1253 /// stop — into the successor instead of restarting it. Predecessor and successor
1254 /// must hold the same trigger alternative, and a retained best must still produce
1255 /// a representable level; otherwise the replacement is rejected and the
1256 /// predecessor stays live. keep_handle re-prices the request in place: the
1257 /// answer's successor is the target itself, its waiting children and roster
1258 /// entries stay, and it ranks as the newest request, where a successor would.
1259 /// keep_binding lets a close bound to the book keep that binding when the book
1260 /// still has it at the successor's first evaluation, with no CloseBound event.
1261 /// No C spelling: the C replace takes no options.
1263 const native_order::Request& request,
1265 /// Cancel one live request by handle. A live request becomes Cancelled; a same-run
1266 /// absent, replaced or already terminal handle is NotWorking; a foreign or
1267 /// malformed handle is InvalidHandle. Every outcome is an event. C spelling:
1268 /// strategy_native_cancel_v1.
1270 /// Working-book snapshot and bulk cancellation. cancel_all returns how
1271 /// many requests left the book (one CancelledEvent each, dependants
1272 /// included); cancel_where cancels exactly the live requests carrying that
1273 /// comment and returns how many of them it cancelled.
1274 ///
1275 /// The second form chooses which identity field the text is compared
1276 /// against: NativeRequestField::Comment is the one-argument form, and
1277 /// NativeRequestField::Label addresses the requests by their label, the
1278 /// one-call equivalent of cancelling every order a host issued under its
1279 /// own id. Neither form indexes anything: both walk the live book once,
1280 /// like cancel_all, so a label may be reused, replaced or left empty
1281 /// without any bookkeeping to keep in step. Text that matches nothing is
1282 /// not a command.
1283 std::vector<NativeWorkingRequest> native_working_requests() const;
1284 /// Live-order reads, owning accessor's visibility; spilled rows may allocate and do scratch I/O.
1285 /// Callbacks may read or write their own scratch store, but issue no host
1286 /// commands. False returns cancelled, even for the last row.
1288 void native_visit_working_requests(void*, void (*)(void*, const NativeWorkingRequest&)) const;
1289 std::optional<NativeWorkingRequest> native_working_request(
1290 const native_order::RequestHandle&) const;
1291 /// Withdraw every live request, dependants of a cancelled owner included, and
1292 /// answer how many left the book. One CancelledEvent per request. C spelling:
1293 /// strategy_native_cancel_all_v1.
1294 std::size_t cancel_all();
1295 /// Withdraw exactly the live requests carrying this comment, and answer how many
1296 /// of those left the book. An unknown comment is not a command. The comment is
1297 /// free host text the kernel only copies and compares, and it is not indexed: this
1298 /// walks the live book once, exactly as cancel_all does.
1299 std::size_t cancel_where(std::string_view comment);
1300 /// The same predicate over either identity text. NativeRequestField::Label
1301 /// addresses requests by Request::label — the one call that withdraws every live
1302 /// request a host issued under one of its own order ids. "" is the text a request
1303 /// carrying no such field matches. C spelling:
1304 /// strategy_native_cancel_where_v1(host, text, PF_NATIVE_FIELD_LABEL).
1305 std::size_t cancel_where(std::string_view text, NativeRequestField field);
1306 /// Open a roster a later close can bind to. The handle is what a
1307 /// native_order::BindCohort owner names. C spelling:
1308 /// strategy_native_cohort_open_v1.
1310 /// Enroll one accepted opening's handle in a roster. C spelling:
1311 /// strategy_native_cohort_add_v1.
1313 /// Take one opening back off a roster. C spelling:
1314 /// strategy_native_cohort_remove_v1.
1316
1317 /// The book as one aggregate, copied out. C spelling:
1318 /// strategy_native_position_v1.
1320 /// The book lot by lot, oldest first, marked at `mark`: one NativeOpenLot
1321 /// per physical lot (physical_position().lot_count rows), copied at query
1322 /// time. Legal wherever physical_position() is; observation only, it
1323 /// moves no fill, no hash and no row.
1324 std::vector<NativeOpenLot> native_open_lots(double mark) const;
1325 detail::ScratchStatus visit_native_open_lots(double mark, void*, bool (*)(void*, const NativeOpenLotView&)) const;
1326 void native_visit_open_lots(double mark, void*, void (*)(void*, const NativeOpenLotView&)) const;
1327 detail::ScratchStatus visit_native_open_lot_values(void*, bool (*)(void*, std::uint64_t, double, double)) const;
1328 /// The account's equity marked at this price: the realized balance plus every open
1329 /// lot's own fee-net term, which is exactly what native_open_lots(mark) sums. It
1330 /// moves nothing. C spelling: strategy_native_marked_equity_v1.
1331 double native_marked_equity(double mark) const;
1332 /// The units a kernel-sized intent resolves to under this run's spec at a
1333 /// sizing price, a marked equity and an account FX rate -- as a pure query.
1334 /// units = cash / (price * point_value * fx), cash the basis value or
1335 /// fraction * equity, net of the percent fee reserve when the intent asks
1336 /// for it, then the intent's grid policy: this is the same function the
1337 /// kernel runs at acceptance (SizeTime::AtAcceptance) and at the candidate
1338 /// (AtMatch), so a host that gates a command on its quantity before it
1339 /// submits reads the number here rather than keeping its own copy of the
1340 /// conversion. nullopt when the run is not configured or the basis is
1341 /// unresolvable at those inputs (non-positive money or denominator, a
1342 /// below-one-step quotient under SnapToGrid). Observation only: it moves
1343 /// nothing and freezes nothing.
1344 std::optional<double> native_sized_units(const native_order::Sized& sized, double price,
1345 double equity, double fx) const;
1346 /// The price at which the marked equity falls below the run's maintenance
1347 /// requirement for the live position's side. nullopt when the run declares
1348 /// no margin model, the side has no maintenance fraction, the book is flat,
1349 /// or no finite price solves the breach (a long at full maintenance).
1350 std::optional<double> native_liquidation_price() const;
1351 /// Whether the configured run's script bars are buckets the kernel gathers
1352 /// from its input bars -- native_calendar::pairing_aggregates of the
1353 /// pairing it resolved for the spec's input and script timeframes -- rather
1354 /// than the input bars themselves. False for a chart-timeframe run
1355 /// (byte-identical literals), an undetected timeframe, or no configured spec.
1357 /// The run's generic risk ledger. Every field is its zero for a run that
1358 /// declares no NativeRunSpec::risk; observation only, it moves nothing.
1360 /// Owning snapshots copied at query time. Later commands/reset do not
1361 /// invalidate already returned values. The rows are what the run's
1362 /// NativeRunSpec::event_retention keeps: under Window the command events
1363 /// the host has not yet acknowledged, and no driver point or account row;
1364 /// a read from below native_event_window_start() starts there.
1365 std::vector<NativeMarketEvent> native_events(uint64_t after_ordinal) const;
1366 /// The host has read every event through `through_ordinal` (R5 lane V19-B).
1367 /// Under NativeEventRetention::Window the kernel drops the acknowledged
1368 /// command events at the next script-bar boundary -- never one its own live
1369 /// state still reads -- and keeps every event above the acknowledgement for
1370 /// a later read. The first call also marks the host as one that polls:
1371 /// until a host acknowledges, the kernel treats it as served by its
1372 /// callbacks alone and closes its window at every script-bar end, so a
1373 /// polling host acknowledges at its run begin (0 is legal: "nothing read
1374 /// yet"). An acknowledgement is never lowered by a later, smaller one; one
1375 /// above the event high water acknowledges the high water, never events
1376 /// that have not happened; and before a run begins, or once it has ended,
1377 /// it records nothing (the next begin starts a new journal). Full and
1378 /// Commands keep the whole journal whatever is acknowledged. C spelling:
1379 /// strategy_native_acknowledge_events_v1.
1380 void native_acknowledge_events(uint64_t through_ordinal);
1381 /// The oldest ordinal a read can still return: every command event at or
1382 /// above it is retained, and native_events(after) for an `after` below it
1383 /// starts here, the events before it having been dropped by the window.
1384 /// 1 while nothing was dropped, which is every run under Full or Commands.
1385 /// C spelling: strategy_native_event_window_v1.
1387 /// The run's monotonic decision floor in epoch milliseconds — the same value
1388 /// NativeStateView::decision_floor_ms carries. Every request's birth is compared
1389 /// against this floor, not against a later lowered clock, and a refused preflight
1390 /// does not raise it. C spelling: pf_native_state_v1::decision_floor_ms.
1391 int64_t native_decision_floor() const;
1392 /// The highest run_number this host has consumed. It lives OUTSIDE per-run reset,
1393 /// so a later run on the same host needs a strictly larger number; a fresh host
1394 /// reads 0 and may therefore replay the same logical run. C spelling:
1395 /// pf_native_state_v1::consumed_high_water.
1397 /// The consumer's continuation identity: what a stream resumes against. It folds
1398 /// the run's resolved timezone identity by its content — the kind, the effective
1399 /// definition and a digest of the zone resources actually read — and not by where
1400 /// they live, so two hosts carrying the same tzdata release answer the same value
1401 /// for the same spec over the same bars (R5 lane E23). A tzdata update that
1402 /// rewrites the zone's rules moves it, which is why it is still not a source
1403 /// constant: pin `native_run_spec_digest(spec)` for that, and compare continuation
1404 /// values between runs. C spelling:
1405 /// strategy_native_continuation_hash_v1.
1407 /// The closed rows (the engine's trades_) are part of broker_state_hash(), folded
1408 /// once each through a running digest (pineforge-broker-state/v19). A row is final
1409 /// once the applied notification of the execution that booked it has returned; a
1410 /// host may amend it until then. A host that amends or reorders a final row names
1411 /// the first row it changed here, before the next hash read, and the kernel folds
1412 /// the rows from there again. Debug builds re-fold every digested row at a run's end
1413 /// and abort if one changed unannounced.
1414 void native_closed_rows_amended(std::size_t first_row);
1415
1417
1418protected:
1419 // Native hosts use the engine's unpresented report values by default.
1420 // A host adding a whole-array presenter must override this eligibility.
1421 bool report_presenter_supports_non_full() const noexcept override { return true; }
1422 // broker_state_hash() folds the continuation the kernel latched at the
1423 // run's last script report point (NativeReportPolicy::KernelRecorded), so a
1424 // finished run answers its last per-bar row's value, recording on or off.
1425 // Before the first point, and under a policy whose host owns the report
1426 // cadence, it folds the live continuation.
1427 std::uint64_t broker_state_hash_projection() const override;
1428};
1429
1430} // inline namespace engine_script_run_v19
1431} // namespace pineforge
virtual bool margin_check_allowed(const NativeMarginCheckPoint &) const
Consulted at each kernel check point before anything is evaluated.
native_order::ReplaceResult replace_market(const native_order::RequestHandle &target, const native_order::Request &request)
The same market-default convenience for a replace; see submit_market.
detail::ScratchStatus visit_native_open_lots(double mark, void *, bool(*)(void *, const NativeOpenLotView &)) const
native_order::CohortHandle cohort_open()
Open a roster a later close can bind to.
detail::ScratchStatus visit_native_open_lot_values(void *, bool(*)(void *, std::uint64_t, double, double)) const
virtual void on_native_tick(const Bar &, const NativeTickContext &)
Called once for every accepted realtime print, before matching at that point.
virtual bool owns_lot_excursions() const noexcept
RULING A48 — the ONE generic per-lot excursion capability.
NativeStateView native_state() const
The whole run state as one owning read.
std::optional< Bar > native_series_bar(std::size_t subscription) const
The latest completed bucket delivered for a declared subscription, or nullopt before its first delive...
virtual void on_native_bar_open(const Bar &, const NativeDecisionContext &)
Precedes the matching pass at the script bar's open decision point.
std::optional< Bar > current_partial_bar() const
The bar so far, folded from the path points this script bar has already consumed: open of its first p...
std::uint64_t native_recalculation_count() const
How many recalculations the kernel has driven this run, and how many it suppressed because a point ha...
virtual void on_native_margin_call(const native_order::MarginCallEvent &)
A kernel-issued liquidation that filled.
virtual ClosedLotExcursion closed_lot_excursion(const ClosedLotExcursionFacts &) const
The per-lot excursion a host owns, consulted for every closing row once owns_lot_excursions() answers...
uint64_t native_event_window_start() const
The oldest ordinal a read can still return: every command event at or above it is retained,...
void declare_native_bar_open_hook(bool implemented)
Which of two optional hooks this host implements (R5 lane D2-A).
virtual std::optional< double > resolve_anchored_level(const NativeAnchoredLevelView &) const
The level an anchored leg (FromOwnerFill) is about to be armed at, offered to the host exactly once p...
NativeCurrentExecutionResult execute_current(const NativeCurrentExecution &)
Consume, synchronously, a request accepted or replaced in this very callback.
NativeStrategyHost(const NativeStrategyHost &)=delete
std::vector< NativeWorkingRequest > native_working_requests() const
Working-book snapshot and bulk cancellation.
std::optional< NativeCurrentPointView > current_execution_point() const
The active callback's quote and calendar-derived decision context, as an owning value.
NativeRiskState native_risk_state() const
The run's generic risk ledger.
std::optional< double > native_liquidation_price() const
The price at which the marked equity falls below the run's maintenance requirement for the live posit...
native_order::ReplaceResult replace(const native_order::RequestHandle &target, const native_order::Request &request, native_order::ReplaceOptions options)
Replace with options.
virtual void on_native_bar(const Bar &bar, const NativeDecisionContext &context)=0
The current decision point remains valid for the complete callback.
virtual void on_native_timeframe_bar(const Bar &, const NativeTimeframeBarContext &)
One completed bucket of a declared higher-timeframe subscription, delivered on an accepted input bar ...
int64_t native_decision_floor() const
The run's monotonic decision floor in epoch milliseconds — the same value NativeStateView::decision_f...
std::size_t cancel_all()
Withdraw every live request, dependants of a cancelled owner included, and answer how many left the b...
NativeFxCurveSetupResult configure_native_fx_curve(const NativeFxCurve &curve)
Stage the run's immutable FX epoch, legal only while Ready.
NativeCurrentExecutionPreview inspect_current_execution(const NativeCurrentExecution &) const
A read-only preview of a current execution: the settlement readiness, any typed refusal or terms outc...
virtual void on_native_applied(const native_order::ExecutionAppliedEvent &, const NativeDecisionContext &)
The calculate-on-fill hook: offered once per applied execution, FIFO, after the account record and th...
virtual void on_native_run_begin()
Offered once per successful begin, after the reset and before any bar.
virtual void prepare_native_begin(const NativeBeginArgs &)
Offered once per begin, before the run starts, with the begin's own arguments — the bars,...
double native_marked_equity(double mark) const
The account's equity marked at this price: the realized balance plus every open lot's own fee-net ter...
bool append_auxiliary_bars(const Bar *bars, std::size_t n)
A realtime stream's later bars of its declared auxiliary feed.
NativePhysicalPosition physical_position() const
The book as one aggregate, copied out.
bool native_aggregates_input_bars() const
Whether the configured run's script bars are buckets the kernel gathers from its input bars – native_...
NativeSetupResult declare_timeframe_subscriptions_result(std::vector< NativeTimeframeSubscription > subscriptions)
The same call, answered the way configure_native answers the identical validation: Applied,...
std::size_t cancel_where(std::string_view text, NativeRequestField field)
The same predicate over either identity text.
NativeSetupResult configure_native(const NativeRunSpec &spec)
The only setup call.
std::size_t cancel_where(std::string_view comment)
Withdraw exactly the live requests carrying this comment, and answer how many of those left the book.
native_order::ReplaceResult replace(const native_order::RequestHandle &target, const native_order::Request &request)
Replace one live request: validate first, then retire that incarnation and birth a successor with a n...
NativeStrategyHost & operator=(NativeStrategyHost &&)=delete
native_order::SubmitResult submit(const native_order::Request &request)
Accept one complete request.
uint64_t native_consumed_high_water() const
The highest run_number this host has consumed.
void on_bar(const Bar &bar) final
The engine's own bar entry, taken over by the native consumer and sealed.
bool declare_timeframe_subscriptions(std::vector< NativeTimeframeSubscription > subscriptions)
Declare this run's higher-timeframe series from inside on_native_run_begin, for a host whose series a...
void native_closed_rows_amended(std::size_t first_row)
The closed rows (the engine's trades_) are part of broker_state_hash(), folded once each through a ru...
std::vector< NativeOpenLot > native_open_lots(double mark) const
The book lot by lot, oldest first, marked at mark: one NativeOpenLot per physical lot (physical_posit...
virtual std::optional< NativeMarginDecision > resolve_margin_requirement(const NativeMarginRequirementView &) const
Consulted at EVERY kernel check point, BEFORE the breach test, exactly as resolve_execution_terms is ...
NativeStrategyHost & operator=(const NativeStrategyHost &)=delete
uint64_t native_continuation_hash() const
The consumer's continuation identity: what a stream resumes against.
virtual void on_native_sub_bar(const Bar &sub, const NativeDecisionContext &ctx)
One completed lower-timeframe sub-bar of an IntrabarPath::lower_tf path, delivered after that sub-bar...
detail::ScratchStatus visit_native_working_requests(void *, bool(*)(void *, const NativeWorkingRequest &)) const
Live-order reads, owning accessor's visibility; spilled rows may allocate and do scratch I/O.
void native_acknowledge_events(uint64_t through_ordinal)
The host has read every event through through_ordinal (R5 lane V19-B).
std::vector< NativeMarketEvent > native_events(uint64_t after_ordinal) const
Owning snapshots copied at query time.
bool declare_auxiliary_feed(std::optional< NativeAuxiliaryFeed > feed)
The same begin-time hook for NativeRunSpec::auxiliary_feed: the feed REPLACES the staged spec's own (...
void declare_native_precommit_hook(bool implemented)
declare_native_precommit_hook(false): validate_execution_precommit is the default admission,...
void cohort_remove(native_order::CohortHandle cohort, native_order::RequestHandle origin)
Take one opening back off a roster.
std::uint64_t native_recalculations_skipped() const
How many recalculations max_recalculations_per_point dropped at their matching point.
std::optional< double > native_sized_units(const native_order::Sized &sized, double price, double equity, double fx) const
The units a kernel-sized intent resolves to under this run's spec at a sizing price,...
virtual std::optional< double > resolve_margin_call_units(const NativeMarginCallView &) const
The kernel's own liquidation sizing, offered to the host before the reduction rests.
std::uint64_t broker_state_hash_projection() const override
virtual void on_native_input(const Bar &, const NativeInputContext &)
Called once for every accepted confirmed input bar, before that bar is aggregated or matched.
bool report_presenter_supports_non_full() const noexcept override
virtual native_order::ExecutionTerms resolve_execution_terms(const NativeExecutionTermsFacts &facts) const
The fill-terms hook, consulted at every matching candidate.
virtual NativePrecommitVerdict validate_execution_precommit(const NativePrecommitView &) const
The last gate before a physical effect, offered once per Applied-ready attempt and never during inspe...
virtual void on_native_recalculate(const Bar &bar, const NativeDecisionContext &ctx, NativeCalculationReason reason, const native_order::ExecutionAppliedEvent *cause)
EVERY calculation of the run arrives here first, including the script bar's own close calculation (re...
NativeAuxiliaryAppendResult append_auxiliary_bars_result(const Bar *bars, std::size_t n)
The same call, answering NativeAuxiliaryAppendError and the bar of this call it stopped on.
void native_visit_open_lots(double mark, void *, void(*)(void *, const NativeOpenLotView &)) const
std::optional< NativeWorkingRequest > native_working_request(const native_order::RequestHandle &) const
NativeStrategyHost(NativeStrategyHost &&)=delete
bool mark_native_report_point(int64_t report_ts)
Append one kernel-owned equity point at this host's report mark.
native_order::SubmitResult submit_market(const native_order::Request &request)
The deliberately narrow market-default convenience: the same acceptance path as submit,...
std::optional< NativeTrailState > trail_state(const native_order::RequestHandle &target) const
Where one live trail's own trigger has reached: activated, the running best, the current level and th...
void cohort_add(native_order::CohortHandle cohort, native_order::RequestHandle origin)
Enroll one accepted opening's handle in a roster.
void native_visit_working_requests(void *, void(*)(void *, const NativeWorkingRequest &)) const
NativeSetupResult declare_auxiliary_feed_result(std::optional< NativeAuxiliaryFeed > feed)
The same call, answered the way configure_native answers the identical validation: Applied,...
native_order::CancelResult cancel(const native_order::RequestHandle &target)
Cancel one live request by handle.
constexpr bool native_failure_has_recipient(NativeFailureContextKind kind) noexcept
Whether a context of this kind populates its NativeInRunRecipient.
NativeFailureContext native_failure_recipient(std::uint64_t incarnation) noexcept
A context carrying one addressed request incarnation.
NativeFailureOperation
Which operation was in flight when the failure latched — the second half of "what went wrong",...
NativeCompletion
How a Completed run ended: a batch reached the last bar, or a stream was ended.
constexpr std::uint8_t native_failure_context_bits(NativeFailureContextKind kind) noexcept
The bit-union under NativeFailureContextKind: Cause=1, Recipient=2, Cursor=4.
NativeFailureContext native_failure_cause(std::uint64_t ordinal) noexcept
A context carrying one causing event ordinal.
NativeRunPhase
Which driving is Running: a batch run(), a stream's internal warmup, or its realtime leg.
NativeFailureContextKind
In-run failure references.
NativeEventKind
Which of NativeMarketEvent's three alternatives is populated.
std::variant< NativeUnconfigured, NativeReady, NativeRunning, NativeCompleted, NativeFailed > NativeLifecycle
The lifecycle as one value. Exhaustive over the five alternatives above.
constexpr bool native_failure_has_cursor(NativeFailureContextKind kind) noexcept
Whether a context of this kind populates its NativeInRunCursor.
NativeFailureCode
The durable first failure of a run, in NativeFailure::code.
NativeCurrentQuoteKind
Where a price came from: the callback's own market decision point, or the execution it is anchored to...
NativeFailureContext native_failure_cursor(NativeCoordinate point, double t=0.0) noexcept
A context carrying one path cursor.
constexpr NativeFailureContextKind native_failure_context_kind(bool cause, bool recipient, bool cursor) noexcept
The kind that says exactly these three alternatives are populated.
NativeFailureContext native_failure_context_in_run(const native_order::RunIdentity &run, const native_order::EventId *cause, const native_order::RequestHandle *recipient, const native_order::MatchCursor *cursor) noexcept
Copies only ordinals/incarnation/cursor scalars.
NativeAnchoredTrigger
Which trigger of an anchored leg the owner's fill is about to supply.
const native_order::RunIdentity * native_failed_run_identity(const NativeFailed &failed) noexcept
The RunIdentity the failed spec carried, or nullptr when configure failed before staging one.
NativeSetupStatus
Whether a setup call applied its value or refused it.
NativeCalculationReason
Why the kernel is asking the host to calculate.
NativeCurrentPriceRule
Which price a current execution settles at: the active callback's quote as presented,...
NativeAuxiliaryAppendError
Why append_auxiliary_bars refused.
@ NoAuxiliaryFeed
The run declared no auxiliary feed, in its spec or at begin.
@ NotRealtime
The run is not on its realtime leg (a batch, or a stream still in warmup).
@ Reentrant
Called from inside a callback or an in-flight input.
@ UnorderedBars
index is a bar that is not strictly after its predecessor — the one before it in this call,...
@ HostFailed
The host had already failed; nothing was read.
@ InvalidBar
index is a bar native_bar_structurally_valid refuses.
@ InputPeriodAlreadyAccepted
The first bar opened inside an input period the run has already accepted.
@ AllocationFailure
Growing the appended-bar store threw. This one DOES fail the host.
NativeCurrentRefusal
Why a current-execution command cannot be consumed here.
std::variant< NativeCurrentRefusal, native_order::ExecutionAppliedEvent, native_order::NoEffectEvent, native_order::MatchRejectedEvent, native_order::CancelledEvent > NativeCurrentExecutionResult
What execute_current answers: a refusal, or the applied outcome.
NativePrecommitVerdict
The host is consulted before generic opening-margin admission.
NativeMarginCheckKind
Which kernel check point is about to test the maintenance requirement.
NativeRequestField
Which of a request's two free-text identity fields a bulk predicate reads.
NativeLifecycleKind
Where a host stands.
constexpr bool native_failure_has_cause(NativeFailureContextKind kind) noexcept
Whether a context of this kind populates its NativeInRunCause.
NativeCompletionKind
How a script interval or a higher-timeframe bucket was closed.
std::shared_ptr< const RequestDefinition > DefinitionRef
std::variant< AllowanceUnset, AllowanceUnits, AllowanceAllScope, AllowanceDeferred > Allowance
std::variant< execution::Book, execution::OpeningExposure, SelectedExposure > ExecutionScope
What one execution acted on: the whole book, one opening's exposure, or a bound selection.
NativeCandidatePriceKind
Which price a candidate is being offered at: the point's own price, or the request's trigger level (a...
std::variant< RemainingUnbound, RemainingFlattenAll, RemainingUnits, RemainingDeferred, NoTarget > Remaining
std::variant< RemainingProjectionUnbound, RemainingProjectionFlattenAll, RemainingProjectionUnits, RemainingProjectionDeferred, RemainingProjectionNoTarget > RemainingProjection
std::variant< execution::Flatten, order_action::Reduce, order_action::Transact, execution::ReverseTo > ExecutionPlan
The settlement shape one execution takes.
std::variant< MarketReady, LimitReady, StopIdle, StopActive, StopLimitPending, StopLimitLive, TrailWaitArm, TrailTrack, TrailActive > TriggerState
MagnifierDistribution
Definition magnifier.hpp:7
std::unordered_map< std::string, std::string > InputsMap
Definition engine.hpp:502
The account row that follows an applied execution in the event history: the shared ordinal,...
Ephemeral read-only facts of one anchored-leg materialization (L7b), offered to the host exactly once...
What append_auxiliary_bars_result answers: the status, the refusal by name, and which bar OF THIS CAL...
bool simple_run
Which public overload began the run: the bare run(bars, n) lifecycle (true) or a timeframe-aware / ma...
const SymInfo * syminfo
The rich run overload's symbol metadata is borrowed only for this callback.
Recomputed observations, never an apply token.
std::optional< native_order::MatchRejectReason > terms_rejection
std::optional< native_order::CancelReason > terms_cancellation
A synchronous execution of one request accepted or replaced in this very callback: a target handle an...
What current_execution_point() answers inside a callback: the point's decision context,...
Read-only owning-value facts for one candidate.
bool shared_cursor_collision
A retained crossing can share a rounded cursor quote with another request's level.
native_order::NativeCandidatePriceKind price_kind
The three in-run facts a failure may carry, tagged by kind.
The durable record native_state().failure answers: the code, the operation it happened in,...
What configure_native_fx_curve answers: the status and, on refusal, the curve validation with the ind...
The event ordinal a failure was caused by, 0 when absent.
Where on the modeled path a failure happened: the driver point's coordinate and its interpolation pos...
The request incarnation a failure was addressed to, 0 when absent.
Accepted input facts presented before the generic consumer aggregates the bar into its script interva...
Ephemeral factual view of one kernel-issued liquidation before its units are fixed.
Ephemeral factual view of one kernel check point, offered to the host before the check runs.
bool liquidation_resting
Whether the model already holds a liquidation resting from an earlier admitted point.
The host's answer to one requirement view.
Ephemeral factual view of the numbers the kernel is about to compare, at one check point,...
One owning row of native_events(after_ordinal): a command event, a driver point or an account observa...
std::optional< NativeAccountObservation > account
std::optional< native_order::CommandEvent > command
std::optional< NativeDriverPoint > driver
Callback-local view of the same FIFO row.
Owning value row for one open physical lot, copied at query time by native_open_lots(mark) — the lot-...
The book as one aggregate: signed units, the volume-weighted average entry price and the number of op...
Ephemeral factual view of one prepared execution before any physical effect.
The run's generic risk ledger (L9), as the kernel holds it.
std::optional< native_order::RiskLimitKind > reason
What configure_native answers: the status and, on refusal, the first error field validate_native_run_...
The flattened run state native_state() answers: the lifecycle kind, a borrowed pointer to the staged ...
One accepted realtime print before native matching at its current decision point.
One completed higher-timeframe bucket of a declared subscription (NativeRunSpec::subscriptions),...
Read-only projection of a live generic Trail request.
The NativeLifecycle alternatives, one per NativeLifecycleKind.
Owning value row for one live request, copied at query time.
Everything the kernel knows about WHERE a point is, as one owning value: its event ordinal,...
What validate_native_fx_curve and configure_native_fx_curve report: the error and the index of the el...
An immutable account-currency FX curve: parallel arrays of effective-from timestamps in epoch millise...
A host-maintained, run-scoped roster identity.
One committed execution: the definition, the cursor, the resolved price and units,...
A kernel-issued liquidation that actually filled.
A candidate the run refused, with its MatchRejectReason and the cursor it was refused at.
A reduction or a flatten that had nothing to close: terminal, with no execution identity,...
Replacement behaviour that is not expressible in the successor request.
Aggregate field order keeps market construction: Request{Transact{1.0}, "buy", "comment"}...
A kernel-sized opening.
Allocation-free facts suitable for the host's durable failure variant.
One complete setup value, staged/copied by NativeStrategyHost before it is applied at begin.