PineForge unreleased
Deterministic PineScript v6 backtest runtime — C ABI reference
Loading...
Searching...
No Matches
runtime_context.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <pineforge/bar.hpp>
6
7#include <cstddef>
8#include <cstdint>
9#include <functional>
10#include <memory>
11#include <optional>
12#include <stdexcept>
13#include <string>
14#include <vector>
15
16#define PINEFORGE_HAS_RUNTIME_CONTEXT_SERVICE_V1 1
17
18namespace pineforge {
19
21 int ratio = 1;
22 int seconds = 0;
23};
24std::optional<RuntimeSubdivision> runtime_subdivision(
25 const std::string& input_timeframe, const std::string& requested_timeframe);
26std::vector<Bar> runtime_subdivide(const Bar&, RuntimeSubdivision);
27
29 std::uint64_t generation = 0;
30 std::uint64_t serial = 0;
31 std::uint64_t owner = 0;
33 return a.generation == b.generation && a.serial == b.serial && a.owner == b.owner;
34 }
36 return !(a == b);
37 }
38};
39
40// A scope, not ownership of the array. The caller promises immutable input
41// until this scope ends. Its destruction revokes every service binding before
42// the caller may destroy/reuse the array. Multi-entry callers keep this scope
43// alive themselves, or bind an owning RuntimeHistorySource instead.
45public:
46 RuntimeBatchLease(const Bar* bars, std::size_t count);
50private:
51 struct State;
52 State* state_ = nullptr;
54};
55
57public:
58 virtual ~RuntimeHistorySource() = default;
59 virtual std::uint64_t size() const = 0;
60 virtual Bar read(std::uint64_t index) const = 0;
61};
62
64 // A spill threshold, never a refusal limit. Zero uses direct spill and
65 // fixed IO buffers. Neither option is read by static request machinery.
66 std::size_t runtimeHistoryResidentBytes = 64u * 1024u * 1024u;
67 std::optional<std::uint64_t> runtimeHistoryBudgetBytes = std::nullopt;
68 // A seekable disk filesystem. A memory-backed temp directory cannot
69 // satisfy the resident-memory contract. No environment-variable lookup.
71};
72
73class RuntimeHistoryBudgetExhausted : public std::runtime_error, public RunFailureInfo {
74public:
76 std::uint64_t used, std::uint64_t needed);
77 const std::uint64_t configured, used, needed;
78};
79
81 std::uint64_t accepted = 0;
82 std::uint64_t accounted_bytes = 0;
83 std::uint64_t resident_bytes = 0;
84 std::uint64_t spool_bytes = 0;
85 std::uint64_t contexts = 0;
86 // Categories include evaluator ownership, not just the history provider.
87 // A false complete flag makes accounted_bytes an unusable UINT64_MAX
88 // sentinel. The separate categories remain observed lower bounds.
90};
91
97
100 std::uint64_t index = 0;
101 // Exclusive accepted-input frontier of THIS callback. A nested request
102 // must not read beyond it, even while its parent is catching up.
103 std::uint64_t frontier = 0;
104};
105
108public:
109 virtual ~RuntimeContextEvaluator() = default;
111 const RuntimeContextEvent&) = 0;
112 // Includes the concrete object and actual owned allocations, including
113 // unused capacity and backing. Incomplete observations return UINT64_MAX.
114 virtual std::uint64_t storage_bytes() const noexcept = 0;
115 // Compose all evaluators into ONE observation to count shared ownership
116 // once across contexts. Legacy scalar reporters cannot establish that
117 // identity contract and stay explicitly incomplete under a hard budget.
118 virtual void observe_owned_storage(OwnedStorage& out) const noexcept {
120 }
121};
122
128
129// Provider-neutral contexts. No legacy subscription ids, Pine values or
130// registry references cross this interface. Handles survive new registrations;
131// reset/end_run invalidate them. One service belongs to one execution thread.
133public:
134 using Factory = std::function<std::unique_ptr<RuntimeContextEvaluator>()>;
139
142 bool history_enabled() const noexcept;
143 void reset();
144 void end_run() noexcept;
146 void bind_source(std::shared_ptr<const RuntimeHistorySource>);
148 void accept_batch(std::uint64_t exclusive_frontier);
149 void append_live(const Bar&);
150 std::uint64_t accepted_frontier() const noexcept;
151 std::uint64_t callback_frontier() const noexcept;
152 std::uint64_t frontier_before(std::int64_t exclusive_time_ms) const;
154
156 void advance(RuntimeContextHandle, std::uint64_t exclusive_frontier);
159 RuntimeHistoryUsage usage() const noexcept;
160private:
161 struct Impl;
162 std::unique_ptr<Impl> impl_;
163 Impl& impl();
164};
165
166} // namespace pineforge
RunFailureInfo(RunFailureCode code, const RunFailureArgs &args) noexcept
RuntimeBatchLease(const RuntimeBatchLease &)=delete
RuntimeBatchLease & operator=(const RuntimeBatchLease &)=delete
RuntimeBatchLease(const Bar *bars, std::size_t count)
virtual ~RuntimeContextEvaluator()=default
virtual void consume(RuntimeContextService &, RuntimeContextHandle, const RuntimeContextEvent &)=0
virtual std::uint64_t storage_bytes() const noexcept=0
virtual void observe_owned_storage(OwnedStorage &out) const noexcept
RuntimeContextHandle active_context() const noexcept
RuntimeContextEvaluator & published(RuntimeContextHandle)
std::uint64_t callback_frontier() const noexcept
RuntimeContextService & operator=(const RuntimeContextService &)
void accept_batch(std::uint64_t exclusive_frontier)
std::uint64_t accepted_frontier() const noexcept
void bind_batch(const RuntimeBatchLease &)
void bind_source(std::shared_ptr< const RuntimeHistorySource >)
void configure(RuntimeHistoryOptions)
void advance(RuntimeContextHandle, std::uint64_t exclusive_frontier)
void release(RuntimeContextHandle)
RuntimeContextHandle get_or_create(const RuntimeContextKey &, const Factory &)
RuntimeContextService(const RuntimeContextService &)
RuntimeHistoryUsage usage() const noexcept
std::function< std::unique_ptr< RuntimeContextEvaluator >()> Factory
bool history_enabled() const noexcept
std::uint64_t frontier_before(std::int64_t exclusive_time_ms) const
RuntimeHistoryBudgetExhausted(std::uint64_t configured, std::uint64_t used, std::uint64_t needed)
virtual std::uint64_t size() const =0
virtual ~RuntimeHistorySource()=default
virtual Bar read(std::uint64_t index) const =0
RuntimeStorageObservationIncomplete(OwnedStorageUsage usage)
std::optional< RuntimeSubdivision > runtime_subdivision(const std::string &input_timeframe, const std::string &requested_timeframe)
std::vector< Bar > runtime_subdivide(const Bar &, RuntimeSubdivision)
friend bool operator==(RuntimeContextHandle a, RuntimeContextHandle b) noexcept
friend bool operator!=(RuntimeContextHandle a, RuntimeContextHandle b) noexcept
std::optional< std::uint64_t > runtimeHistoryBudgetBytes