PineForge unreleased
Deterministic PineScript v6 backtest runtime — C ABI reference
Loading...
Searching...
No Matches
native_bar_views.hpp
Go to the documentation of this file.
1#pragma once
2
3// CR-150 P00 declarations only. DESIGN.md revision 6, section 2.2:337-378.
4// This separate namespace is the side channel; native_run_spec_v3 and
5// native_host.hpp keep their existing layouts (2.2:339-345; 6:1328-1329).
6#include <pineforge/bar.hpp>
8
9#include <cstddef>
10#include <cstdint>
11#include <optional>
12#include <string>
13#include <vector>
14
15namespace pineforge {
16inline namespace native_bar_views_v1 {
17
18/// Borrowed OHLCV span, exactly the layout specified in 2.2:347-348.
19/// The caller owns the bars. No owning vector or copied bar is introduced.
21 const Bar* data;
22 std::size_t size;
23};
24
25/// Borrowed instrument feed, exactly 2.2:349. bars.size is also the number
26/// of close_ms entries. Validation still checks the same bars, close times,
27/// ordering and column lengths as today's vector feed (2.2:361-363).
28/// The borrowed-feed caller keeps both arrays alive until replacement,
29/// clearing or strategy_free (6:1321-1327).
32 const std::int64_t* close_ms;
33};
34
35/// RESOLVED V2: completed below with the protocol approved by CORE-TOP's
36/// rev 6 amendment (10-18 19:24), proposal plus required changes 1-9.
37/// DESIGN coordinates use the baseline identified in the contract map.
39
40/// Effective feed data (DESIGN 2.2:354-375; RESOLVED V1). Owned feeds keep
41/// their independently observable close count for validation and the digest's
42/// missing-close zero fallback. A borrowed feed has close_count == bars.size.
45 const std::int64_t* close_ms;
46 std::size_t close_count;
47};
48
49/// Explicit read context (RESOLVED V1, required changes 1-4). Zero feed count
50/// means owned vectors for every feed; the table pointer is then ignored.
51/// Otherwise the nonnull table count equals the spec's metadata count, and
52/// slot i binds entry i. Null slot: use owned vectors. Nonnull slot: present
53/// borrowed data, including {{nullptr,0},nullptr} for an installed empty feed;
54/// it never falls back to owned data. No metadata entry means absent.
55/// Metadata/columns stay in NativeInstrumentFeed, with empty owning bar/close
56/// vectors for a borrowed slot. Mixed owned/borrowed slots are allowed.
57/// Nonempty borrowed arrays are nonnull, immutable, and have bars.size rows.
58///
59/// Consumer staging copies descriptors and the table, not the arrays. Caller
60/// descriptors/table may die after staging; arrays live through every use of
61/// the accepted binding, through the public run exit. Installed-feed owners
62/// also keep arrays alive until replacement, clearing or strategy_free.
63/// The active query exposes no pending slot. Context pointers are borrowed
64/// until replacement/detachment/destruction; the segment is empty until the
65/// kernel selects one. The const source prevents readers selecting a segment.
66///
67/// At every public run exit, including abort/error, detach tables/source and
68/// segment, releasing borrowed pointers after retaining scalar counts/content
69/// digests for identity. A detached Ready binding is never admitted: that is
70/// engine_invariant. A lower-path source bound at stream_begin is likewise
71/// engine_invariant. Staging/query are private consumer members, not functions
72/// taking a public host (required changes 1-2).
79
80/// Common accessor (DESIGN 2.2:355-375). Always select a nonnull override,
81/// including a present-empty one; otherwise expose owned data and its actual
82/// close count. No padding/copying. The caller MUST pass its slot or nullptr
83/// explicitly: no default argument (required change 3).
85 const NativeInstrumentFeed& owned,
86 const NativeInstrumentFeedView* borrowed) noexcept;
87
88/// Existing full validation and zero-fee normalization over effective data.
89/// At binding, table/spec count mismatch or nonempty null bars reports
90/// {InvalidInstrumentFeedBar, InstrumentFeedBars}; nonempty null closes
91/// reports {InvalidInstrumentFeedClose, InstrumentFeedClose}. A borrowed slot
92/// with nonempty owning bars/closes reports the corresponding bar/close pair.
93/// Existing key/timeframe/duplicate, bar value/order, close length/bounds and
94/// column checks keep their order and typed calendar/allocation catches.
95/// A source requires lower_tf metadata with empty owning lower bars; otherwise
96/// report {InvalidIntrabarPath, IntrabarTimeframe}. No new C failure code.
97///
98/// Also route the adapter's projection validation through this overload,
99/// using the context built from its store. The host stages after lending feed
100/// bytes and before projection (required change 5). Pending state is not read
101/// through the consumer's active query. Context-free v3 APIs stay unchanged.
103 NativeRunSpec& spec, const NativeBarViews& views) noexcept;
104
105/// The same feed-only validation over effective data, retaining all existing
106/// refusal ordering and typed catches (DESIGN 2.2:361-363).
108 const std::vector<NativeInstrumentFeed>& feeds,
109 const NativeBarViews& views) noexcept;
110
111/// The same feeds-first, auxiliary-feed, then subscription judgement over
112/// effective data, also at both begin declarations (DESIGN 2.2:361-363).
114 const std::vector<NativeTimeframeSubscription>& subscriptions,
115 const std::string& input_tf,
116 bool timeframe_undetected,
117 const std::optional<NativeAuxiliaryFeed>& auxiliary_feed,
118 const std::vector<NativeInstrumentFeed>& instrument_feeds,
119 const NativeBarViews& views) noexcept;
120
121/// Same count, metadata, ordered OHLCV/timestamp/close/columns fold and feed
122/// NaN canonicalization (DESIGN 2.2:364-375). Valid live descriptors are a
123/// precondition; owned close lengths remain total, missing closes fold zero.
125 const std::vector<NativeInstrumentFeed>& feeds,
126 const NativeBarViews& views) noexcept;
127
128/// Portable spec fold with an explicit context, sharing the existing fold
129/// and relative run base; never infer external storage through a registry.
130/// May re-walk a source and propagate exceptions; never invent a failure hash.
131/// The one-argument v3 form remains the owned-value API.
132///
133/// DESIGN 5 timing amendment (required change 8): configure takes immutable
134/// feed/lower component digests eagerly after normalization succeeds and
135/// before its first member write. Lower-walk exceptions propagate unchanged;
136/// nothing is published, and they are NOT converted into validation refusals.
137/// Keep these components through combined-cache invalidation and detachment,
138/// so the noexcept continuation query never walks released input. The outer
139/// spec fold may stay lazy; standalone context overloads may walk and throw.
141 const NativeRunSpec& spec, const NativeBarViews& views);
142
143/// Four-operation source (DESIGN 2.2:350-351; 5:1237-1262, as amended).
144/// Null source means owned-vector fallback; a nonnull source is present even
145/// when count() == 0. The consumer exclusively owns the provider from applied
146/// configure to detachment at public run exit. Immutable borrowed input lives
147/// through that exit; destruction must not read it. Calls are serialized, with
148/// no concurrent/reentrant walks. Concrete factories/policy/storage stay L16's.
149/// Every operation exposes the same complete logical path. Whole-input fallback
150/// is decided before emitting any aggregated prefix; no mixed prefix/suffix.
152public:
153 /// Synchronous ordered callback; bar lives for this call only. true
154 /// continues, false stops normally. Context may be null; callback is
155 /// neither retained nor allowed to throw.
156 using Visitor = bool (*)(void* context, const Bar& bar) noexcept;
157
158 virtual ~NativeLowerPathSource() noexcept = default;
159
160 /// Fixed lifetime row count, including zero (required change 7). The
161 /// first call may walk or use the construction pre-scan; subsequent calls
162 /// return the cached scalar in O(1). No segment/look-ahead invalidation.
163 /// Operational failure throws. Overflow throws coded std::overflow_error,
164 /// run_options_rejected with option intrabar_path, never a wrapped count.
165 virtual std::size_t count() const = 0;
166
167 /// Fresh whole-path walk, true only if complete and false only for visitor
168 /// stop. Null visitor is coded engine_invariant / std::logic_error. Source
169 /// failures throw. Never overwrite active segment/look-ahead, including
170 /// when a digest is read inside a callback.
171 virtual bool for_each(Visitor visitor, void* context) const = 0;
172
173 /// Ordered contiguous rows with begin_ms <= timestamp < end_ms. Equal
174 /// bounds give an empty view; reversed bounds are coded engine_invariant
175 /// / std::logic_error. Each bound is non-decreasing across calls; windows
176 /// may repeat OR overlap, including overlap rows. A decreasing bound is
177 /// the same invariant error (required change 6). Repeats return the same
178 /// active storage. Replace a window only after its script bar finishes.
179 /// Prepare look-ahead here; failures expose no partial new segment.
181 std::int64_t begin_ms, std::int64_t end_ms) = 0;
182
183 /// Null before the first segment; otherwise the first path bar at/after
184 /// its end, or null at exhaustion, including for an empty segment. The
185 /// separate one-bar buffer stays fixed until a different segment is
186 /// selected. It may skip multiple empty chart bars; repeated queries do
187 /// not advance or overwrite the active segment. Within a segment, use its
188 /// next contiguous row; only the last row needs this look-ahead.
189 virtual const Bar* next_after_segment() const noexcept = 0;
190};
191
192/// Null delegates to the vector digest; nonnull replaces only lower count/
193/// walk. Preserve variant/metadata and raw double bits (no NaN normalization),
194/// folding count before visitation. Unexpected visitor stop or count/visit
195/// mismatch is coded engine_invariant; operational failures propagate, never
196/// a sentinel digest. Configure-time handling is the eager rule above.
197/// Preflight still owns lower-bar validation and the INT_MAX refusal. Runtime
198/// segment-generation failures are coded run_options_rejected, option
199/// intrabar_path; allocation exceptions take the existing run-entry handler.
201 const IntrabarPath& path,
203
204// RESOLVED V1/V2 reader and guard work remains L15a/L15b/L16's implementation:
205// the contract map lists all reads, including projection validation (change 5).
206// Add this header/source and its namespace check to the native ownership guard,
207// and pin the context spec-digest sibling block beside the existing fold.
208
209} // inline namespace native_bar_views_v1
210} // namespace pineforge
Four-operation source (DESIGN 2.2:350-351; 5:1237-1262, as amended).
virtual std::size_t count() const =0
Fixed lifetime row count, including zero (required change 7).
virtual bool for_each(Visitor visitor, void *context) const =0
Fresh whole-path walk, true only if complete and false only for visitor stop.
virtual const Bar * next_after_segment() const noexcept=0
Null before the first segment; otherwise the first path bar at/after its end, or null at exhaustion,...
bool(*)(void *context, const Bar &bar) noexcept Visitor
Synchronous ordered callback; bar lives for this call only.
virtual NativeBarView segment(std::int64_t begin_ms, std::int64_t end_ms)=0
Ordered contiguous rows with begin_ms <= timestamp < end_ms.
std::uint64_t native_instrument_feeds_digest(const std::vector< NativeInstrumentFeed > &feeds, const NativeBarViews &views) noexcept
Same count, metadata, ordered OHLCV/timestamp/close/columns fold and feed NaN canonicalization (DESIG...
NativeRunSpecValidation validate_native_instrument_feeds(const std::vector< NativeInstrumentFeed > &feeds, const NativeBarViews &views) noexcept
The same feed-only validation over effective data, retaining all existing refusal ordering and typed ...
std::uint64_t native_run_spec_digest(const NativeRunSpec &spec, const NativeBarViews &views)
Portable spec fold with an explicit context, sharing the existing fold and relative run base; never i...
std::uint64_t native_intrabar_path_digest(const IntrabarPath &path, const NativeLowerPathSource *source)
Null delegates to the vector digest; nonnull replaces only lower count/ walk.
NativeRunSpecValidation validate_native_timeframe_subscriptions(const std::vector< NativeTimeframeSubscription > &subscriptions, const std::string &input_tf, bool timeframe_undetected, const std::optional< NativeAuxiliaryFeed > &auxiliary_feed, const std::vector< NativeInstrumentFeed > &instrument_feeds, const NativeBarViews &views) noexcept
The same feeds-first, auxiliary-feed, then subscription judgement over effective data,...
NativeInstrumentFeedReadView native_instrument_feed_view(const NativeInstrumentFeed &owned, const NativeInstrumentFeedView *borrowed) noexcept
Common accessor (DESIGN 2.2:355-375).
NativeRunSpecValidation normalize_native_run_spec(NativeRunSpec &spec, const NativeBarViews &views) noexcept
Existing full validation and zero-fee normalization over effective data.
Borrowed OHLCV span, exactly the layout specified in 2.2:347-348.
Explicit read context (RESOLVED V1, required changes 1-4).
const NativeInstrumentFeedView *const * instrument_feeds
Effective feed data (DESIGN 2.2:354-375; RESOLVED V1).
Borrowed instrument feed, exactly 2.2:349.
An owned lower-timeframe execution path.
Another instrument's own bars of one timeframe, installed as data.
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.