PineForge unreleased
Deterministic PineScript v6 backtest runtime — C ABI reference
Loading...
Searching...
No Matches
execution.hpp
Go to the documentation of this file.
1#pragma once
2
4#include "order_action.hpp"
5#include <cstddef>
6#include <cstdint>
7#include <optional>
8#include <string>
9#include <variant>
10#include <vector>
11
13
14// Whole-book reduction is explicit: it never relies on a rounded aggregate
15// quantity being exactly equal to the sum of individual physical lots.
16struct Flatten {};
17using Action = std::variant<Flatten, order_action::Reduce, order_action::Transact>;
18
19// Why a closed row exited, as a value the closer records rather than a string
20// a reader decodes. The numbers ARE the public C contract
21// (strategy_closed_trade_close_cause, pineforge.h), so they are append-only:
22// 0 is the documented "no cause recorded" value, never an error.
23//
24// Unspecified leaves the classification to the generic facts already on the
25// row (open_at_end -> RangeEnd, exit_from_bracket -> Bracket, otherwise
26// Script). Liquidation and RiskLimit are what a kernel-originated request
27// carries (native_order::RequestOrigin::KernelLiquidation / KernelRisk), and
28// Bracket is what a host request its owner's fill armed carries when it only
29// closes (a native_order::WaitForApplied owner with a Reduce, Flatten or
30// host-sized close intent, the relation native_toolkit::submit_bracket
31// builds); a host that runs its own forced-close policy — the Pine adapter's
32// margin call, its strategy.risk.max_intraday_loss close and its filled-order
33// cap close — records its own cause on the row it produced.
34enum class CloseCause : std::uint8_t {
36 Script = 1,
42};
43
44// The caller has already matched/admitted the action and resolved its price.
45// Settlement does not apply another lot step, price grid, slippage or entry cap.
46struct Fill {
47 double price;
48 std::string id;
49 std::string comment;
50 uint64_t incarnation = 0;
51 // An observed execution charge in account currency, including rebates.
52 // Otherwise the engine's configured schedule quotes the current fill.
53 std::optional<double> commission_account = std::nullopt;
54 // Appended last so every existing aggregate initializer keeps its meaning.
56};
57
58enum class Status {
61 // Caller-supplied lifecycle targets/revisions/operations that cannot be
62 // applied to the current pending book. Not durable engine state.
64 // Invalid or unavailable run-local opening exposure on a scoped close.
65 // Existing whole-book entry points do not return this status.
67};
68
69struct Result {
71 // Aggregate projections of the physical effects; the lot/trade roster is
72 // authoritative. Opening units are signed; closing units are nonnegative.
73 double closed_units = 0.0;
74 double opened_units = 0.0;
75 // This execution's current ticket and committed-row references. Zero when
76 // the result is not Applied. Native terminal events copy these facts.
77 double current_ticket = 0.0;
78 std::size_t first_trade_index = 0;
79 std::size_t closed_trade_count = 0;
81};
82
83// Stack-bound physical coordinates for one settlement. Native supplies time
84// and index from the matching point and leaves the trail carry empty; the
85// settling path fills it in for a trail exit. `account_fx` is the
86// account-currency rate the execution's rows convert at; empty, they convert
87// at the engine's rate at its presented clock (active_account_currency_fx()).
89 int64_t effective_time_ms = 0;
91 std::optional<double> preceding_exit_trail_peak;
92 std::optional<double> account_fx;
93};
94
95// Stack-local inspect facts. Destroyed at the end of one matching step.
98 double closed_units = 0.0;
99 double opened_units = 0.0;
101 std::size_t resulting_lot_count = 0;
103 double current_ticket = 0.0;
104 bool would_open = false;
105 bool incoming_short = false;
106};
107
108// One pre-close operation on an exact pending identity. created_seq 0 and
109// Target{0,0} are actual expected values, not wildcards. The coordinator
110// allocates the batch cause and does not rewrite operation payloads.
118
119// Engaging this batch allocates one observation frame on a successful
120// commit even when operations is empty. Empty optional means no allocation.
121// Phase must be a valid exit_legs::Phase even for an empty operations list.
123 exit_legs::Phase phase = exit_legs::Phase::Observation;
124 std::vector<LifecycleIntent> operations;
125};
126
127// Exact pending EXIT to remove after old-cycle unbind and before any
128// quoted opening bind. Fields are the initial snapshot before this
129// execution's own effects; incarnation 0 is refused.
131 uint64_t incarnation = 0;
132 int64_t created_seq = 0;
134 uint64_t expected_revision = 0;
135};
136
137// Transient, stack-local effects for one native settlement preparation. Not
138// stored, hashed, replayed, or reusable execution authority.
140 std::optional<LifecycleBatch> pre_close;
141 std::vector<PendingRemoval> removals;
142};
143
144} // namespace pineforge::execution
std::variant< Flatten, order_action::Reduce, order_action::Transact > Action
Definition execution.hpp:17
std::variant< BindOwner, Suspend, StageReplacement, CancelDeferredActivation, Restore, CompleteBarrier, Observe, Cancel > Operation
std::optional< double > commission_account
Definition execution.hpp:53
std::vector< LifecycleIntent > operations
std::vector< PendingRemoval > removals
std::optional< LifecycleBatch > pre_close
std::optional< double > preceding_exit_trail_peak
Definition execution.hpp:91