PineForge v0.13.1-379-g9b50973
Deterministic PineScript v6 backtest runtime — C ABI reference
Loading...
Searching...
No Matches
market_driver.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <pineforge/bar.hpp>
5
6#include <cstdint>
7#include <optional>
8#include <string>
9
10namespace pineforge {
11inline namespace native_run_spec_v3 { struct NativeRunSpec; }
12inline namespace native_driver_v5 {
13
14// Semantic versions hashed into native continuation identity.
15inline constexpr const char* kNativeDriverSemanticVersion = "native-driver/v5";
16inline constexpr const char* kNativeConsumerSemanticVersion = "native-consumer/v7";
17inline constexpr const char* kNativeCalendarSemanticVersion = "native-calendar/v1";
18
19/// Where a driver point's price came from. Confirmed is a confirmed input bar's
20/// own label; ObservedPrint a realtime tick; the two ModeledOHLC values and
21/// AfterCalculationClose are the modeled waypoints of a confirmed bar's path;
22/// CarriedOpen is a quiet tradable interval's carried last price; PartialFinalized
23/// a partially finalized observed slot; Calculation the script calculation point
24/// itself; CurrentExecution a synchronous execute_current. A host reads it off
25/// NativeDecisionContext::coordinate and never has to infer it.
37
38/// Which leg of a modeled OHLC walk a point sits on. None is a discrete point (a
39/// calculation, an observed print); Open, High, Low and Close are the waypoints,
40/// in the order NativeRunSpec::path_order resolves. A margin check point's
41/// cursor.point.path_phase is the waypoint the check was taken at.
42enum class NativePathPhase : std::uint8_t {
43 None = 0,
44 Open = 1,
45 High = 2,
46 Low = 3,
47 Close = 4,
48};
49
50/// How a script interval or a higher-timeframe bucket was closed. Confirmed means
51/// its own last contributing bar closed it; LazyComplete that the NEXT interval's
52/// first input did — a session-clipped bar, or a hole over the last slot;
53/// SessionShortened that the session close clipped it; PartialFinalized that a
54/// stream end finalized a forming observed slot. Delivered on
55/// NativeTimeframeBarContext::completion for a bucket and on the coordinate for a
56/// calculation.
63
64/// Everything the kernel knows about WHERE a point is, as one owning value: its
65/// event ordinal, the interval index, the nominal and scheduled-eligible opens,
66/// the last traded close, the next period and next input opens, the effective time
67/// the account converts and hashes at, the source price time, and the three
68/// classifications above. A host reads it through NativeDecisionContext; mutating
69/// a copy cannot move the consumer's floor, matching time or after-calculation
70/// coordinate.
85
86/// One point the driver produced: its coordinate, the raw price before slippage or
87/// any grid, the provider's sequence for an observed print (nullopt otherwise),
88/// and whether the point is a matching point, an excursion sample, or both.
89/// Recorded in the event history as the NativeEventKind::Driver rows
90/// native_events() returns.
93 double raw_price = 0.0;
94 std::optional<uint64_t> sequence;
95 bool matching = false;
96 bool excursion = false;
97};
98
99// Generic facts about the retained intrabar driver. They let a host project
100// run diagnostics without consulting a source scheduler or borrowing driver
101// state. Counts are cumulative for the run except the two current-script-bar
102// shape fields.
110
111// Presentation snapshot copied onto the callback stack. Mutating these
112// fields cannot change the consumer's decision floor, matching time, or
113// after-calculation coordinate.
116 int64_t decision_floor_ms = 0;
119 // A non-magnified run is the one-element intrabar path. The sub-bar
120 // timestamp is deliberately separate from the script label: execution
121 // ledgers use the former while script-time policy uses the latter.
122 int sub_index = 0;
123 int sub_count = 1;
125 int64_t sub_bar_open_ms = 0;
128};
129
130// Pump-produced events obtain ordinals from the consumer allocator.
132public:
133 virtual ~INativeDriverSink() = default;
134 /// The consumer's ordinal allocator, called by the pump for every event it
135 /// produces. Implemented by the kernel's own consumer; a host never implements
136 /// this interface.
137 virtual uint64_t allocate_native_ordinal() = 0;
138 /// A point at which live requests may match. The consumer runs the matching pass
139 /// here; excursion-only points do not reach it.
140 virtual void on_native_matching_point(const NativeDriverPoint& point) = 0;
141 /// A point that updates open lots' favorable and adverse excursions without
142 /// offering a match.
143 virtual void on_native_excursion(const NativeDriverPoint& point) = 0;
144 /// The script bar's calculation point, with the complete script bar and its
145 /// coordinate. The consumer turns it into the host's on_native_bar /
146 /// on_native_recalculate call.
147 virtual void on_native_calculation(const Bar& script_bar, const NativeCoordinate& coordinate) = 0;
148};
149
150/// Whether a bar can be admitted at all: finite positive OHLC with
151/// high >= max(open, close) and low <= min(open, close), and a finite nonnegative
152/// volume. A run's NativeFeedTolerance may relax the positivity and the volume
153/// half; this is the strict predicate those bits are measured against. It is also
154/// what refuses a bar of an auxiliary feed (InvalidAuxiliaryFeedBar).
155bool native_bar_structurally_valid(const Bar& bar) noexcept;
156
157// Confirmed-bar labels admitted by v9: the immutable nominal slot origin
158// and the scheduled clipped eligible opening. Both identify one slot key
159// `interval.open_ms`. Mid-slot and other off-grid timestamps are refused.
161 const native_calendar::NativeInterval& interval, int64_t timestamp) noexcept {
162 return timestamp == interval.open_ms || timestamp == interval.eligible_open_ms;
163}
164
165// Canonical exclusive completion of a confirmed input slot. Source-price
166// time remains a separate fact (bar.timestamp / last print).
168 const native_calendar::NativeInterval& interval) noexcept {
169 return interval.next_period_open_ms;
170}
171
172// ---------------------------------------------------------------------------
173// Shared pure input preflight (host + runner)
174//
175// Exact signature the runner worker should bind:
176// NativeInputPreflightResult
177// preflight_native_inputs(const NativeRunSpec& spec,
178// const Bar* bars,
179// int n,
180// NativeInputPolicy policy);
181//
182// Calendar-aware, allocation of diagnostic text is the caller's job.
183// No host reset, callback, identity mutation, high-water change, or
184// decision-floor change. Parses the spec's session/timezone/input_tf
185// on each call. Batch may be sparse; StreamWarmup refuses missing
186// in-session bars after a closed gap by walking next_input_open_ms
187// through interval_containing (Fri 16 -> Mon 11 cannot skip Mon 09:30).
188// Warmup complete-script policy is NOT decided here.
189// ---------------------------------------------------------------------------
190enum class NativeInputPolicy : std::uint8_t {
191 Batch = 0,
193};
194
195/// Why a bar array was refused before the run touched anything. NullArray and
196/// InvalidCount are the argument shape; StructuralInvalid is
197/// native_bar_structurally_valid; Unaligned and OffGridLabel are the slot label;
198/// NotStrictlyIncreasing and OverlappingSlot the ordering; InSessionGap a missing
199/// in-session slot, which only a stream warmup refuses; CalendarFailure a calendar
200/// the spec's own timezone and session could not resolve. A preflight refusal
201/// leaves the host Ready or Running and does NOT raise the decision floor.
215
216/// What preflight_native_inputs answers: the error and the first offending bar's
217/// index, or -1 when the refusal is not about one bar. ok() and the explicit
218/// operator bool are the success reads.
221 int index = -1; // first offending bar, or -1 when not index-specific
222
223 constexpr bool ok() const noexcept {
225 }
226 constexpr explicit operator bool() const noexcept { return ok(); }
227};
228
229/// Judge a whole bar array against a run spec before any of it is consumed, under
230/// NativeInputPolicy::Batch (sparse input is admitted; missing in-session slots
231/// are legal) or ::StreamWarmup (every provided slot must be a complete confirmed
232/// interval and an in-session gap is refused). Every public begin runs it first,
233/// which is why an invalid array leaves the lifecycle where it was instead of
234/// failing the host.
236 const NativeRunSpec& spec,
237 const Bar* bars,
238 int n,
239 NativeInputPolicy policy);
240
241} // inline namespace native_driver_v5
242} // namespace pineforge
virtual void on_native_excursion(const NativeDriverPoint &point)=0
A point that updates open lots' favorable and adverse excursions without offering a match.
virtual uint64_t allocate_native_ordinal()=0
The consumer's ordinal allocator, called by the pump for every event it produces.
virtual void on_native_calculation(const Bar &script_bar, const NativeCoordinate &coordinate)=0
The script bar's calculation point, with the complete script bar and its coordinate.
virtual void on_native_matching_point(const NativeDriverPoint &point)=0
A point at which live requests may match.
NativeInputPreflightResult preflight_native_inputs(const NativeRunSpec &spec, const Bar *bars, int n, NativeInputPolicy policy)
Judge a whole bar array against a run spec before any of it is consumed, under NativeInputPolicy::Bat...
bool native_confirmed_bar_label_admitted(const native_calendar::NativeInterval &interval, int64_t timestamp) noexcept
constexpr const char * kNativeConsumerSemanticVersion
constexpr const char * kNativeDriverSemanticVersion
int64_t native_canonical_input_completion(const native_calendar::NativeInterval &interval) noexcept
NativeCompletionKind
How a script interval or a higher-timeframe bucket was closed.
constexpr const char * kNativeCalendarSemanticVersion
NativeInputPreflightError
Why a bar array was refused before the run touched anything.
bool native_bar_structurally_valid(const Bar &bar) noexcept
Whether a bar can be admitted at all: finite positive OHLC with high >= max(open, close) and low <= m...
NativePathPhase
Which leg of a modeled OHLC walk a point sits on.
NativePriceProvenance
Where a driver point's price came from.
Everything the kernel knows about WHERE a point is, as one owning value: its event ordinal,...
One point the driver produced: its coordinate, the raw price before slippage or any grid,...
What preflight_native_inputs answers: the error and the first offending bar's index,...
One complete setup value, staged/copied by NativeStrategyHost before it is applied at begin.