PineForge v0.13.1-379-g9b50973
Deterministic PineScript v6 backtest runtime — C ABI reference
Loading...
Searching...
No Matches
source/market_admission.hpp
Go to the documentation of this file.
1#pragma once
2// The TradingView market-admission observation journal: every field of
3// `Configuration` is a strategy() declaration parameter and every event is a
4// TradingView admission review, so this is source-layer state (R5 lane N14:
5// moved from include/pineforge/market_admission.hpp, where no kernel
6// translation unit consumed it). It is hashed through the source host's
7// extension fold (src/source/pine_state_hash.cpp), never by the kernel.
9#include <cstdint>
10#include <functional>
11#include <limits>
12#include <memory>
13#include <optional>
14#include <string>
15#include <variant>
16#include <vector>
17
19inline namespace market_admission_v2 {
20constexpr double absent = std::numeric_limits<double>::quiet_NaN();
21enum class CommandKind : int64_t { Entry, Raw, Cancel, CancelAll };
28
29// Immutable observed configuration, not selectable compatibility profiles.
31 bool process_on_close = false;
32 bool calc_on_fills = false;
33 bool magnifier = false;
34 bool fill_recalculation = false;
35 bool scheduler = false;
36 int slippage = 0;
37 int pyramiding = 0;
40 double long_margin = 0;
41 double short_margin = 0;
42 double commission_value = 0;
44 double pointvalue = 1;
45 double fx = 1;
46 double quantity_step = 0;
47 double mintick = 0;
50 double drawdown_limit = 0;
52 double position_limit = 0;
53 bool fill_cap_active = false;
54 bool risk_halted = false;
55};
57 double limit = absent;
58 double stop = absent;
59};
61 double limit = absent;
62 double stop = absent;
66};
68 double quantity = absent;
69 double equity = absent;
70 double price = absent;
71 double mark = absent;
72 double fx = absent;
73};
101 uint64_t sequence = 0;
103 int bar = -1;
104 // Zero only for the batch review; per-order receipts name their origin.
105 uint64_t target_command = 0;
106};
108 uint64_t sequence = 0;
109 uint64_t cause_fill = 0;
110 int bar = -1;
111 uint64_t target_command = 0;
112};
113
114class Draft {
115public:
116 void bind(std::shared_ptr<const CommandObservation> observation);
117 void reviewed(ReviewReceipt receipt);
118 void sizing_revised(SizingRevision receipt);
119 const std::shared_ptr<const CommandObservation>& observation() const { return observation_; }
120 const std::optional<ReviewReceipt>& review() const { return review_; }
121 const std::optional<SizingRevision>& sizing_revision() const { return sizing_revision_; }
122private:
123 std::shared_ptr<const CommandObservation> observation_;
124 std::optional<ReviewReceipt> review_;
125 std::optional<SizingRevision> sizing_revision_;
126};
128 uint64_t incarnation = 0;
129 int64_t priority = 0;
130 int bar = -1;
131 int type = 0;
133 // Raw requested direction captured with the physical book row. This is
134 // needed to reconstruct a flat-born MARKET peer; placement_side is the
135 // held position side and is FLAT for that peer.
136 bool buy = false;
137 std::string id;
138 std::string oca_name;
139 int oca_type = 0;
143};
145 std::shared_ptr<const CommandObservation> observation;
148 std::vector<BookObservation> before;
149 std::vector<uint64_t> removed;
150};
151// Actual resolution output kinds. No selector/member bit is retained.
166 int64_t position_cycle = 0;
167 std::vector<BookObservation> book;
168 std::vector<BookObservation> reviewed;
169 std::vector<InstructionResolution> resolutions;
170 std::vector<uint64_t> causes;
171};
180using Event = std::variant<CommandEvent, ReviewEvent, SizingEvent>;
181using FieldValue = std::variant<uint64_t, int64_t, double, std::string>;
182struct Field { std::string path; FieldValue value; };
183using FieldVisitor = std::function<void(const Field&)>;
184void reflect(const Draft& value, const std::string& path, const FieldVisitor& visit);
185void reflect(const Event& value, const std::string& path, const FieldVisitor& visit);
186
187class Allocation;
188class Journal {
189public:
190 Journal() = default;
191 Journal(const Journal& other);
192 Journal& operator=(const Journal& other);
193 Journal(Journal&& other);
194 Journal& operator=(Journal&& other);
195 // Raw allocations must be appended or abandoned. Production producers use
196 // reserve() so failed construction/unwinding abandons the unfinished event.
197 uint64_t next_sequence();
199 void abandon(uint64_t sequence) noexcept;
200 void append(Event event);
201 const std::vector<Event>& events() const { return events_; }
202 uint64_t sequence_frontier() const { return next_sequence_; }
203 void reset();
204 // Keep actual causes still referenced by history, instructions or settlement.
205 void retain(const std::vector<uint64_t>& sequences);
206 void reflect(const std::string& path, const FieldVisitor& visit) const;
207private:
208 friend class Allocation;
209 void release_allocation(uint64_t sequence) noexcept;
210 uint64_t next_sequence_ = 1;
211 uint64_t active_allocations_ = 0;
212 std::vector<uint64_t> outstanding_sequences_;
213 std::vector<Event> events_;
214};
215// Ephemeral ownership of an unfinished event. Completed/reclaimed IDs cannot
216// be re-created by keeping this handle: append consumes the journal allocation.
218public:
219 Allocation(const Allocation&) = delete;
220 Allocation& operator=(const Allocation&) = delete;
221 Allocation(Allocation&& other) noexcept;
223 ~Allocation() noexcept;
224 uint64_t sequence() const { return sequence_; }
225private:
226 friend class Journal;
227 Allocation(Journal& journal, uint64_t sequence) noexcept
228 : journal_(&journal), sequence_(sequence) {}
229 Journal* journal_;
230 uint64_t sequence_;
231};
232// Ephemeral call frame; only its completed immutable record enters the journal.
234public:
235 CommandCapture(Allocation allocation, CommandObservation input, std::vector<BookObservation> before,
236 std::function<void(CommandEvent)> complete);
239 ~CommandCapture() noexcept(false);
240 const CommandObservation& input() const { return input_; }
241 void outcome(Outcome outcome) { outcome_ = outcome; }
242 void bind(Draft& draft, std::optional<SizingObservation> sizing,
243 double explicit_equity, double explicit_price);
244private:
245 Allocation allocation_;
246 CommandObservation input_;
247 std::vector<BookObservation> before_;
248 Outcome outcome_ = Outcome::NoAdmission;
249 std::function<void(CommandEvent)> complete_;
250};
252public:
253 ReviewCapture(Allocation allocation, ReviewEvent event,
254 std::function<void(ReviewEvent)> complete);
255 ReviewCapture(const ReviewCapture&) = delete;
257 ~ReviewCapture() noexcept(false);
258 ReviewReceipt receipt_for(const Draft& draft) const;
259 void reject(uint64_t incarnation) {
260 InstructionResolution result;result.incarnation=incarnation;result.kind=ResolutionKind::Rejected;
261 event_.resolutions.push_back(result);
262 }
263 InstructionResolution transaction(uint64_t incarnation,uint64_t peer,int64_t priority,
264 int64_t peer_priority,double quantity) {
265 InstructionResolution result{incarnation,ResolutionKind::PairedTransaction,peer,priority,peer_priority,quantity};
266 event_.resolutions.push_back(result);return result;
267 }
268private:
269 Allocation allocation_;
270 ReviewEvent event_;
271 std::function<void(ReviewEvent)> complete_;
272};
273std::vector<Field> fields(const Draft& draft);
274uint64_t read_unsigned(const std::vector<Field>& fields, const std::string& path);
275int64_t read_integer(const std::vector<Field>& fields, const std::string& path);
276double read_double(const std::vector<Field>& fields, const std::string& path);
277std::string read_string(const std::vector<Field>& fields, const std::string& path);
278uint64_t sequence(const Event& event);
279} // inline namespace market_admission_v2
280} // namespace pineforge::admission
Allocation & operator=(Allocation &&)=delete
Allocation & operator=(const Allocation &)=delete
CommandCapture(Allocation allocation, CommandObservation input, std::vector< BookObservation > before, std::function< void(CommandEvent)> complete)
void bind(Draft &draft, std::optional< SizingObservation > sizing, double explicit_equity, double explicit_price)
CommandCapture & operator=(const CommandCapture &)=delete
const std::shared_ptr< const CommandObservation > & observation() const
const std::optional< ReviewReceipt > & review() const
void bind(std::shared_ptr< const CommandObservation > observation)
const std::optional< SizingRevision > & sizing_revision() const
void reflect(const std::string &path, const FieldVisitor &visit) const
void retain(const std::vector< uint64_t > &sequences)
InstructionResolution transaction(uint64_t incarnation, uint64_t peer, int64_t priority, int64_t peer_priority, double quantity)
ReviewCapture(Allocation allocation, ReviewEvent event, std::function< void(ReviewEvent)> complete)
ReviewCapture & operator=(const ReviewCapture &)=delete
std::variant< uint64_t, int64_t, double, std::string > FieldValue
uint64_t read_unsigned(const std::vector< Field > &fields, const std::string &path)
std::string read_string(const std::vector< Field > &fields, const std::string &path)
int64_t read_integer(const std::vector< Field > &fields, const std::string &path)
std::vector< Field > fields(const Draft &draft)
std::function< void(const Field &)> FieldVisitor
double read_double(const std::vector< Field > &fields, const std::string &path)
void reflect(const Draft &value, const std::string &path, const FieldVisitor &visit)
std::variant< CommandEvent, ReviewEvent, SizingEvent > Event
admission::Draft MarketAdmissionDraft
admission::Journal MarketAdmissionJournal
std::shared_ptr< const CommandObservation > observation