PineForge v1.4.0-4-g873b25da
Deterministic PineScript v6 backtest runtime — C ABI reference
Loading...
Searching...
No Matches
pine_host_reads.hpp
Go to the documentation of this file.
1#pragma once
2
3// R5 lane D2-C: the source layer's reads of the run it serves, taken in place.
4//
5// NativeStrategyHost answers its reads of kernel state out of line and by
6// value: native_state() builds a whole NativeStateView -- the failure record
7// and its context included -- for the one field a caller wants,
8// current_execution_point() copies the callback's point, execution_consumer()
9// is a call, and the Pine layer asks them some fifteen times a bar before it
10// places an order. The consumer already holds each answer for as long as it
11// cannot change: the run's lifecycle, spec and phase for the run, the
12// callback's point for the callback, the book until the next settlement. So
13// the layer reads them there, through these inline forms, each answering
14// exactly what the accessor it stands for answers at the same moment
15// (tests/test_adapter_in_place_reads.cpp holds them to the accessors at every
16// callback). One fact derived from the spec -- whether the chart aggregates
17// its input bars -- is taken once per run and kept with the consumer for the
18// host (run_aggregates_input_bars, the host cache of R5 lane PERF-P7).
19// Not installed API.
20
21#include "../native_execution_consumer.hpp"
22
23#include <cstdint>
24#include <optional>
25
26namespace pineforge::source {
27
29
30namespace detail {
31
32// NativeStrategyHost::execution_consumer(), as the native consumer it is.
33inline NativeExecutionConsumer& run_consumer(const NativeStrategyHost& host) {
34 return NativeExecutionConsumer::bound(host);
35}
36
37// native_state()'s kind, spec and phase: the view's fields the source layer
38// reads, filled as view() fills them.
39struct RunState {
40 NativeLifecycleKind kind = NativeLifecycleKind::Unconfigured;
41 const NativeRunSpec* spec = nullptr;
42 NativeRunPhase phase = NativeRunPhase::Batch;
43};
45 const NativeExecutionConsumer& consumer = NativeExecutionConsumer::bound(host);
46 if (consumer.running())
47 return {NativeLifecycleKind::Running, consumer.state_spec(), consumer.state_phase()};
48 const NativeStateView view = consumer.view();
49 return {view.kind, view.spec, view.phase};
50}
51
52// native_state().kind / .spec / .phase alone.
54 return run_consumer(host).state_kind();
55}
56inline const NativeRunSpec* run_spec(const NativeStrategyHost& host) {
57 return run_consumer(host).state_spec();
58}
60 return run_consumer(host).state_phase();
61}
62
63// physical_position().
65 return run_consumer(host).position(host);
66}
67
68// current_execution_point(), by reference: null where it answers nullopt.
69// Valid inside the callback that asked.
71 return run_consumer(host).current_point();
72}
73
74// The source layer's state parked with the consumer for one run (R5 lane
75// PERF-P7's NativeHostCache: the adapter's lookup index derives from this,
76// pine_adapter.cpp). The consumer drops it at every run begin and never reads
77// it. `owner` and `run` are the adapter and run counter it was adopted for;
78// the facts below are the running spec's, taken once at the run's begin
79// (take_run_facts) and fixed with the spec for the run.
80extern const char kPineRunCacheKind;
81struct PineRunCache : NativeHostCache {
82 PineRunCache() noexcept : NativeHostCache(&kPineRunCacheKind) {}
83 const void* owner = nullptr;
84 std::uint64_t run = 0;
85 std::optional<bool> aggregates_input_bars;
86 // Reads the facts answered (the witness's probe), apart from the
87 // lookups the index answers.
88 std::uint64_t fact_answers = 0;
89};
90
91// The consumer's PineRunCache for the adapter at `owner` in run `run`, or null.
92inline PineRunCache* run_cache(const NativeExecutionConsumer& consumer, const void* owner,
93 std::uint64_t run) noexcept {
94 NativeHostCache* const cache = consumer.host_cache();
95 if (cache == nullptr || cache->kind() != &kPineRunCacheKind) return nullptr;
96 auto* facts = static_cast<PineRunCache*>(cache);
97 return facts->owner == owner && facts->run == run ? facts : nullptr;
98}
99
100// Whether a script bar of the chart gathers several input bars -- the
101// kernel's answer (NativeStrategyHost::native_aggregates_input_bars) -- for the
102// adapter at `owner` in run `run`: while the run runs, the answer taken at its
103// begin; otherwise, or when the consumer keeps no host cache
104// (set_host_cache(false), the reference tests/test_adapter_in_place_reads.cpp
105// compares against), asked of the consumer.
106inline bool run_aggregates_input_bars(const NativeExecutionConsumer& consumer,
107 const void* owner, std::uint64_t run) {
108 if (consumer.running()) {
109 if (PineRunCache* facts = run_cache(consumer, owner, run);
110 facts != nullptr && facts->aggregates_input_bars) {
111 ++facts->fact_answers;
112 return *facts->aggregates_input_bars;
113 }
114 }
115 return consumer.aggregates_input();
116}
117
118// Takes the facts above for the run that has just begun (on_native_run_begin).
119void take_run_facts(NativeExecutionConsumer& consumer, const PineExecutionAdapter& adapter,
120 std::uint64_t run);
121
122} // namespace detail
123} // namespace pineforge::source
The public native host: an abstract subclass of BacktestEngine with no PineScript on it.
NativeRunPhase
Which driving is Running: a batch run(), a stream's internal warmup, or its realtime leg.
NativeLifecycleKind
Where a host stands.
RunState run_state(const NativeStrategyHost &host)
NativePhysicalPosition run_position(const NativeStrategyHost &host)
void take_run_facts(NativeExecutionConsumer &consumer, const PineExecutionAdapter &adapter, std::uint64_t run)
const NativeCurrentPointView * callback_point(const NativeStrategyHost &host)
bool run_aggregates_input_bars(const NativeExecutionConsumer &consumer, const void *owner, std::uint64_t run)
const NativeRunSpec * run_spec(const NativeStrategyHost &host)
NativeExecutionConsumer & run_consumer(const NativeStrategyHost &host)
NativeRunPhase run_phase(const NativeStrategyHost &host)
PineRunCache * run_cache(const NativeExecutionConsumer &consumer, const void *owner, std::uint64_t run) noexcept
NativeLifecycleKind run_kind(const NativeStrategyHost &host)
What current_execution_point() answers inside a callback: the point's decision context,...
The book as one aggregate: signed units, the volume-weighted average entry price and the number of op...
The flattened run state native_state() answers: the lifecycle kind, a borrowed pointer to the staged ...
One complete setup value, staged/copied by NativeStrategyHost before it is applied at begin.