From cc0b22d0ede0f5fc35f54f2966284c68a6750a30 Mon Sep 17 00:00:00 2001 From: luisleo526 Date: Thu, 10 Sep 2026 23:47:57 +0800 Subject: [PATCH] Refactor reservation growth and Pine market instruction ownership --- CMakeLists.txt | 2 + docs/Doxyfile | 1 + docs/frozen-market-instruction.md | 87 +++++ docs/pages/abi-stability.md | 39 ++- docs/pages/exit-leg-activation.md | 5 +- docs/pages/fill-model.md | 122 +++++-- docs/pages/index.md | 2 + docs/reservation-expansion-candidate.md | 27 ++ .../pineforge/compat/pine/exit_activation.hpp | 2 +- .../compat/pine/frozen_market_instruction.hpp | 72 ++++ include/pineforge/compat/pine/order_birth.hpp | 2 +- .../pineforge/compat/pine/order_priority.hpp | 2 +- .../compat/pine/reservation_expansion.hpp | 17 + include/pineforge/engine.hpp | 59 ++-- include/pineforge/pending_order_mirror.hpp | 33 +- include/pineforge/reservation_expansion.hpp | 53 +++ scripts/check_broker_state_hash_coverage.py | 123 ++++++- scripts/check_script_cpp_abi.py | 133 ++++++- scripts/gen_pending_order_mirror.py | 55 ++- scripts/test_broker_state_hash_coverage.py | 96 ++++- scripts/test_reservation_expansion_mirror.py | 59 ++++ src/compat/pine/reservation_expansion.cpp | 28 ++ src/engine_fills.cpp | 164 ++++----- src/engine_state_hash.cpp | 28 +- src/engine_strategy_commands.cpp | 114 ++---- src/engine_stream.cpp | 2 +- src/pending_order_mirror.cpp | 42 ++- src/reservation_expansion.cpp | 36 ++ tests/CMakeLists.txt | 9 + tests/fixtures/frozen_market/README.md | 7 + tests/fixtures/frozen_market/ff54_fields.inc | 143 ++++++++ .../ff54_pending_order_mirror.hpp | 170 +++++++++ .../reservation_expansion/ff54-fields.inc | 143 ++++++++ .../ff54_pending_order_mirror.hpp | 170 +++++++++ .../script_cpp_abi/baseff54/README.md | 1 + .../script_cpp_abi/baseff54/headers.json.gz | Bin 0 -> 143735 bytes .../script_cpp_abi/baseff54/manifest.json | 90 +++++ .../script_cpp_abi/growthbf312/README.md | 1 + .../growthbf312/headers.json.gz | Bin 0 -> 144048 bytes .../script_cpp_abi/growthbf312/manifest.json | 94 +++++ tests/reservation_expansion_test_access.hpp | 100 ++++++ tests/test_frozen_market_instruction.cpp | 328 ++++++++++++++++++ tests/test_live_order_derived.cpp | 12 +- tests/test_live_state_hash.cpp | 21 +- tests/test_pine_transaction_settlement.cpp | 151 ++++++++ tests/test_pooc_global_full_exit.cpp | 4 +- tests/test_reservation_expansion.cpp | 268 ++++++++++++++ 47 files changed, 2806 insertions(+), 311 deletions(-) create mode 100644 docs/frozen-market-instruction.md create mode 100644 docs/reservation-expansion-candidate.md create mode 100644 include/pineforge/compat/pine/frozen_market_instruction.hpp create mode 100644 include/pineforge/compat/pine/reservation_expansion.hpp create mode 100644 include/pineforge/reservation_expansion.hpp create mode 100644 scripts/test_reservation_expansion_mirror.py create mode 100644 src/compat/pine/reservation_expansion.cpp create mode 100644 src/reservation_expansion.cpp create mode 100644 tests/fixtures/frozen_market/README.md create mode 100644 tests/fixtures/frozen_market/ff54_fields.inc create mode 100644 tests/fixtures/frozen_market/ff54_pending_order_mirror.hpp create mode 100644 tests/fixtures/reservation_expansion/ff54-fields.inc create mode 100644 tests/fixtures/reservation_expansion/ff54_pending_order_mirror.hpp create mode 100644 tests/fixtures/script_cpp_abi/baseff54/README.md create mode 100644 tests/fixtures/script_cpp_abi/baseff54/headers.json.gz create mode 100644 tests/fixtures/script_cpp_abi/baseff54/manifest.json create mode 100644 tests/fixtures/script_cpp_abi/growthbf312/README.md create mode 100644 tests/fixtures/script_cpp_abi/growthbf312/headers.json.gz create mode 100644 tests/fixtures/script_cpp_abi/growthbf312/manifest.json create mode 100644 tests/reservation_expansion_test_access.hpp create mode 100644 tests/test_frozen_market_instruction.cpp create mode 100644 tests/test_pine_transaction_settlement.cpp create mode 100644 tests/test_reservation_expansion.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b157db1..4125ce4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,8 @@ add_library(pineforge STATIC src/engine_stream.cpp src/engine_strategy_commands.cpp src/engine_trade_accessors.cpp + src/reservation_expansion.cpp + src/compat/pine/reservation_expansion.cpp src/pending_order_mirror.cpp src/magnifier.cpp src/math.cpp diff --git a/docs/Doxyfile b/docs/Doxyfile index 0607775..ef7d609 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -90,6 +90,7 @@ INPUT = ../include/pineforge/pineforge.h \ pages/install.md \ pages/integration-cmake.md \ pages/lifecycle.md \ + pages/fill-model.md \ pages/streaming.md \ pages/live-surface.md \ pages/report-schema.md \ diff --git a/docs/frozen-market-instruction.md b/docs/frozen-market-instruction.md new file mode 100644 index 0000000..452e856 --- /dev/null +++ b/docs/frozen-market-instruction.md @@ -0,0 +1,87 @@ +# Frozen Pine market instruction + +This is a bounded representation migration of an existing Pine compatibility +policy. `compat::pine::FrozenMarketInstruction` replaces six independent +PendingOrder sidecars with one exclusive source operation. It does not make +the existing cohort selector a generic native execution contract. + +## Source operation and state ownership + +| Role | Live owned facts | Existing facts consumed | +| --- | --- | --- | +| Ordinary | None | Ordinary sizing and execution state | +| Transaction | Own units; frozen total transaction units | Requested side; immutable placement-cap snapshot | +| TargetedClose | Explicit target entry ID | Original QuantityRequest Units; immutable created-position side | + +Only complete role construction and whole-operation revocation are supported. +Transaction and TargetedClose are mutually exclusive; there are no independent +membership, cap-retention or close-side switches. Revocation destroys the active +payload. A targeted close has no second quantity authority: later reservation +changes leave QuantityRequest's original Units amount intact. + +A source transaction captures the same expression as before: + + own + opposite position held net of earlier same-bar closes + + opposite pending entries' own units + +Its retained-over-cap property is true only when the Transaction role is active +and `over_pyramiding_cap_at_placement` is true. The former duplicate calculation +and the placement snapshot use the same position-side/count/cap expression; +none of those inputs changes between the two capture sites. A targeted close's +buy direction is its captured position side being SHORT. + +The own amount must be positive and finite. A positive-infinite total caused +by source-sum overflow remains representable because the prior source capture +allowed it. This is not a validated native execution amount. The existing +finite-total execution guards still exclude it from frozen transaction sizing; +ordinary sizing follows the same prior path. No new overflow admission policy +is introduced by this structural change. + +## Compatibility boundary retained + +The selector, full-book admission and execution scopes are unchanged: historical +close calculation; FIXED sizing; default FIFO; pyramiding at most one; no costs, +slippage, magnifier, stream or risk extensions. Exact source conditions remain +in `same_bar_market_tx_scope_is_live` and its command producers. + +The complete pending book must contain only accepted operations and at most +two MARKET entries with distinct IDs. An unrelated priced/raw/bracket/close-all +order, a third market entry, or leaving the scope revokes the source operations +for the whole book. Subsequent native dispatch uses the prior ordinary paths. +Same-ID replacement and named cancellation/recreation construct a fresh +operation with a new incarnation and current source snapshots. + +TargetedClose is intentionally not named ReducePosition. Existing Pine behavior +can materialize an opening artifact lot if the originally targeted side is gone +and a matching entry remains pending later in the source execution order. That +path remains intact. Lowering this source operation into separate generic +native transaction/reduction instructions remains future adapter work. + +This migration removes three direct PendingOrder booleans, rather than claiming +that an entire engine has reached a four-flag goal. The Pine cohort selector and +source-operation discriminator survive and must remain in compatibility audits. +No Pine selection predicate has been moved into the native contract by renaming. + +## Observation and compatibility + +The existing 142-field public pending-order mirror is append-only. Every old +field retains its type, size and offset, including the old full-prefix trailing +padding. The six old `sbmt_*` outputs are derived projections only; they are not +writable engine state. Ordinary/revoked operations project false flags and NaN +legacy quantity values exactly as the old inactive sidecars did. + +Six fields append the source kind, own/total units and target ID (char[64], +truncation indicator and full string hash). The broker hash folds the kind and +only its live payload; QuantityRequest and placement facts are already folded +at their owning order. Metadata mutation checks refuse hidden nested fields, +changed variant/enum alternatives, removed or conditional folds, and waivers. +The aggregate representation uses internal engine/PendingOrder ABI v7 and +broker/stream fingerprint epoch7. The complete mirror has155 fields: the142 +shipped fields, seven reservation facts and these six Pine instruction facts. +Public C ABI4 and stream API1 are unchanged. + +`test_frozen_market_instruction` uses literal price-100 fixtures and direct +native command transitions. It pins role construction, amounts in both +orientations, quantity ownership, whole-book revocation, replacement, +cancellation, hash sensitivity, string truncation and the full public prefix. +It does not use external tapes, expected provider trades or a grader. diff --git a/docs/pages/abi-stability.md b/docs/pages/abi-stability.md index e167ce3..0c9abb7 100644 --- a/docs/pages/abi-stability.md +++ b/docs/pages/abi-stability.md @@ -112,34 +112,45 @@ notice: - The shape of internal log lines (use them for humans, not parsers). Rebuild generated and native C++ objects against matching engine headers and -runtime. Owner-bound leg activation changes `PendingOrder` layout again; both -`PendingOrder` and `BacktestEngine` use internal `engine_script_run_v6`. Exact -shipped149/v5 headers are compiled before mismatch links. Native and -generated-style old engine callers, plus standalone priority callers using -`vector` without any engine-method reference, must reject the -v6 archive. Matching current and historical symbol-control links must succeed. -Earlier base38/v2, f864/v3 and c45/v4 controls remain. A compilation failure -cannot masquerade as stale-layout rejection; no pairing executable runs. +runtime. Exact-owner reservation expansion and typed Pine market instructions +change `PendingOrder` layout after +shipped ff54/v6; both `PendingOrder` and `BacktestEngine` now use internal +`engine_script_run_v7`. Exact shipped ff54/v6 headers are authenticated before +compilation. Old native and generated-style engine callers and standalone +priority callers using `vector` must reject the v7 archive. +Matching current and historical symbol-control links must succeed. Earlier +base38/v2, f864/v3, c45/v4 and shipped149/v5 controls remain. Every translation +unit must compile before a mismatch link is accepted; no pairing executable runs. + +The standalone `ReservationExpansionCapture`, `ReservationExpansion` and +`ReservationGrowthSource` types establish their first C++ contract in the inline +`reservation_expansion_v1` namespace, including out-of-line methods. This version +is independent of the containing engine epoch. A frozen unshipped bf312 header +closure provides a negative control for the preceding unversioned draft; these +types did not exist in shipped ff54. Standalone method and capture-argument +pairings reject both stale directions, with matching positives. Inline accessors +still require matching headers; namespace versioning is not a serialization ABI. `PINEFORGE_HAS_SCRIPT_RUN_PREPARE_V1` remains 1: it describes the existing hook capability, not the class layout version. Regenerate and rebuild a strategy module to obtain complete script-state reset; replacing an archive does not retrofit an old module. Public C function signatures, `PF_ABI_VERSION` (4), and `strategy_stream_api_version()` (1) are unchanged. The pending-order v1 -mirror keeps all 128 shipped149 field names/types/offsets and its full old prefix; +mirror keeps all 142 shipped ff54 field names/types/offsets and its full old prefix; new typed facts append, and removed native booleans survive only as read-only derived outputs. Size-limited reads keep old callers within their buffers. Namespace versioning protects referenced internal C++ symbols; it does not validate an erased `pf_strategy_t` handle. Use a handle only with functions from its creating strategy module. A fully self-contained old module can still use -its own matching runtime; this check does not turn it into a v6 module. +its own matching runtime; this check does not turn it into a v7 module. The integrated representation advances the broker fingerprint domain to -`pineforge-broker-state/v6` and stream fingerprint version to 6. These identify -changed serialized leg owner/bounds and Pine placement evidence, alongside -existing quantity, predecessor and birth facts. The Pine component schema remains 1; it is -independent of the aggregate fingerprint version. Prior v2/v3/v4/v5 fingerprints are +`pineforge-broker-state/v7` and stream fingerprint version to 7. These identify +changed serialized reservation capture/source ownership and Pine instruction +roles/payloads, alongside existing +leg activation, quantity, predecessor and birth facts. The Pine component schema remains 1; it is +independent of the aggregate fingerprint version. Prior v2/v3/v4/v5/v6 fingerprints are not comparable. Fingerprints are replay checks, not serialized checkpoints or complete hashes of private strategy state. The native runner already binds its strategy-library SHA; its ledger format and Python provenance fingerprints diff --git a/docs/pages/exit-leg-activation.md b/docs/pages/exit-leg-activation.md index 758246e..703c55d 100644 --- a/docs/pages/exit-leg-activation.md +++ b/docs/pages/exit-leg-activation.md @@ -54,7 +54,8 @@ other historical execution rules remain separate work. The effective-level accessor still reports resolved levels rather than masking eligibility. The internal object layout changes and requires matching C++ headers/library. -Both PendingOrder and BacktestEngine now use internal v6 with broker/stream -fingerprint v6. Exact shipped149/v5 engine and standalone PendingOrder clients +The activation slice shipped with internal v6. Subsequent reservation ownership +integration advances PendingOrder and BacktestEngine to v7 with broker/stream +fingerprint v7. Exact shipped ff54/v6 and earlier149/v5 standalone PendingOrder clients are checked by compile/link-only mismatch controls with matching positives. Public C ABI 4, stream API 1 and pending mirror version 1 are preserved. diff --git a/docs/pages/fill-model.md b/docs/pages/fill-model.md index cceba66..172bd6d 100644 --- a/docs/pages/fill-model.md +++ b/docs/pages/fill-model.md @@ -1,15 +1,30 @@ -# Broker state and fill ownership - -The broker processes a source-ordered command book against a price path. Its -physical position, logical close claims, reserved quantities and pyramiding -capacity are separate ledgers. A Pine entry ID is a reusable name; the order -incarnation and position cycle identify the owners of those ledgers. - -This document describes the first extracted ownership model. Other order, -reservation and path state is still represented in `BacktestEngine` and -`PendingOrder`; their consolidation is ongoing. The current economic rules -retain their tested domains. Moving a rule into a type does not establish -that it describes every TradingView configuration. +# Order execution model {#fill_model} + +PineForge is being developed as an independent C++ backtest and forward-execution +engine. Its native contracts describe orders, exposure, reservations and actual +execution events. Pine source interpretation belongs to the frontend boundary. +TradingView comparisons are compatibility evidence for a declared configuration; +they do not define every native operation. + +The migration is incomplete. The current engine still contains Pine-specific +admission and scheduling rules, and the ordinary bar scan and callback-driven +scan are separate. The responsibilities below guide their consolidation without +claiming that a single unified scheduler already exists. + +## Responsibilities + +| Submodel | Owned facts and transitions | Boundary | +|---|---|---| +| Command admission | Original quantity request, placement observation, accepted instruction identity, rejection cause | A source frontend interprets its calls; native admission operates on explicit transaction or position intent. | +| Exposure and reservation | Position cycle, physical quantity, reservation owner, admitted growth sources, committed growth and retirement | A proposed add is not an executed add. There is one mutable reservation capacity. | +| Trigger lifecycle | Stop/limit/trail definitions, activation bounds and owner binding, stop-limit activation and trail progress | An unready leg cannot supply a price or authorize a ready sibling. | +| Execution schedule | Candidate identity, event coordinate, dependency and explicit priority | Ordering does not grant admission, create quantity or activate a leg. | +| Settlement and observation | Executed quantity, physical lots, paid fees, OCA effects, risk follow-up and callbacks | Publish observations after the corresponding state change; report projections must not change admission equity. | + +These are responsibilities, not five independently switchable modes. Direction, +order kind, quantity intent and an outstanding owned claim are normal domain +state. Encoding unrelated permissions as enum values or moving them to another +object does not simplify the model. ## What qualifies as a generic flag @@ -37,6 +52,32 @@ scores are regression evidence, not a justification for keeping a compensating flag. Actual conflicting TradingView observations belong in an anomaly review record, separate from an unknown rule or an engine defect. +## Identity and quantity + +Every accepted pending object receives a fresh `incarnation`. A user-supplied ID +can be reused, and same-ID replacement can retain queue priority; neither implies +that the new object owns the old object's claims. `replaced_order_incarnation` +records the exact predecessor. A position cycle similarly distinguishes two +positions that happen to have the same direction. + +`QuantityRequest` retains the original Units, Fraction or All request and its +reservation basis. The executable `PendingOrder::qty` can change through OCA +reduction or committed reserved growth. That does not rewrite the original +request, reclassify its historical partial/full meaning, or create another +quantity ledger. + +An expansion capture belongs to an exact EXIT object and exposure cycle. Selected +source orders carry the receiving EXIT incarnation. After an actual primary fill, +the receiver gains only the positive same-side quantity increase belonging to its +captured cycle. A canceled or logically retired receiver cannot redirect that +growth to another exit with the same user ID. + +The first later successful entry-like admission closes the capture's population. +Canceling that later admission does not erase its historical cause. Previously +captured sources can still pay their exact receiver; later unrelated adds do not +join the capture. An old-cycle capture loses live-All authority while its ordinary +finite reservation remains available for the normal settlement path. + ## Opening checkpoint An accepted opening or add can create an opening-affordability checkpoint. @@ -77,6 +118,27 @@ Four historical long/short lifecycle labels had no economic consumers. They have been removed, along with their producers; the numerical floor-zero rules and their trade fixtures remain. Those labels are not alternate model states. +## Current dispatch sequence + +The ordinary pending-order scan updates risk state, processes due opening work, +finalizes source cohorts, updates trailing/relative prices and orders the book. +It then classifies and matches an exact pending handle. A pre-exit margin slice +can change the book between matching and dispatch, so the handle is resolved +again before applying the selected order. + +The primary fill updates physical exposure. Reservation growth is settled at the +existing post-primary checkpoint, before that order's OCA and risk follow-up. +Logically retired objects cannot be dispatched again while awaiting compaction. +Callbacks use committed fill events; a declined or zero-effect attempt is not +itself a fill event. Pine's optional quota interpretation separately observes +the attempt stages its own contract specifies. + +There is no universal `risk > exit > entry` priority. A forced action and a user +order have event coordinates, and an earlier event must be accounted before a +later one. Forced liquidation cannot be suppressed by an unready user stop. +An earlier risk fill can also invalidate the quantity or owner of a later +candidate, requiring another resolution of its identity and eligibility. + ## Distinct execution domains An opening receipt is broker-local. It is not an identity for every output: @@ -94,6 +156,28 @@ different information. The opening ownership extraction changes none of their path, callback or warmup policies. Terminal-close deferral is still selected by the existing financial policy; it has not been generalized by this model. +## Remaining consolidation + +The complete scheduler should build immutable candidates, choose the earliest +eligible event coordinate, satisfy causal dependencies, and then apply explicit +priority and stable submission identity. Losing candidate scans must not commit +trigger activation. Dependency cycles must be reported rather than hidden by +another pairwise preference. + +The existing two-sort arrangement does not yet provide that contract. In +particular, the sibling comparator has reproduced ordering-law failures for +unrelated interleavings and mixed trailing/non-trailing exits. Grouping by owner +alone does not repair the mixed-leg case. Replacing these sorts is separate from +the reservation-ownership change and requires its own native ordering tests and +Cloud compatibility assessment. + +A native reduction must never create new exposure. Some existing Pine close +interpretations can produce a new transaction after their old target disappears; +that interpretation must remain explicit at the source boundary until lowering +to native operations is complete. The current engine also has separate forward +ingress, callback, affordability and per-leg lifecycle work. This page does not +claim those migrations or the large-function cleanup are finished. + ## Verification and compatibility Literal state tests exercise consume-before-use, exempt presence, replacement, @@ -103,11 +187,9 @@ fixed reference population is required before reporting parity preservation. Hashes supplement those comparisons; a matching fingerprint is not a proof that all hidden strategy state is equal. -The new receipt replaces protected C++ members and changes the fingerprint -representation. Rebuild generated and native modules against matching headers -and runtime. The cap extraction advances the internal class namespace to -`engine_script_run_v3`, broker hash domain to `pineforge-broker-state/v3`, and -stream fingerprint prefix to 3. These pairing/serialization versions change -no financial rule; public C signatures, POD layouts and API versions remain -unchanged. See -[ABI stability](abi-stability.md). +Internal C++ layouts and broker/stream fingerprint domains are versioned separately +from the public C ABI and its append-only pending-order mirror. Rebuild generated +and native modules against matching headers and runtime. See +[ABI stability](@ref abi_stability) for the current versions and stale-object +pairing checks. A lower Boolean field count is not proof that every compatibility +policy or possible order history has been covered. diff --git a/docs/pages/index.md b/docs/pages/index.md index c9e1eba..59129ea 100644 --- a/docs/pages/index.md +++ b/docs/pages/index.md @@ -57,6 +57,8 @@ consumption. `pf_report_t` layout and the equity curve. - I'm a transpiler / backend author + Read **[Order execution model](@ref fill_model)** for native ownership, + reservation and ordering contracts and the remaining frontend boundary work. Read **[Coverage](@ref coverage)** — the complete map of which Pine v6 surface this runtime owns versus what your codegen has to emit inline. diff --git a/docs/reservation-expansion-candidate.md b/docs/reservation-expansion-candidate.md new file mode 100644 index 0000000..c08018d --- /dev/null +++ b/docs/reservation-expansion-candidate.md @@ -0,0 +1,27 @@ +# Reservation expansion ownership + +Reservation expansion and typed Pine instructions change the internal order +layout relative to ff54. The engine/PendingOrder namespace is +`engine_script_run_v7`, with broker/stream fingerprint epoch7. Standalone capture, +expansion and growth-source types establish `reservation_expansion_v1`. +Public C ABI4, stream API1 and pending-mirror schema1 remain unchanged. The +142-field shipped mirror prefix is preserved; seven reservation facts and six +Pine instruction facts append in the combined155-field mirror. + +The EXIT owns a capture of cycle and side plus its first later admitted +incarnation. Its selected MARKET sources own exact receiver receipts. A new +successful capture can explicitly reassign a pending source; erasure or +replacement alone never transfers it. Executable `qty` is the only mutable +finite capacity. Original QuantityRequest intent and reservation basis remain +historical. Open capture permits live-All only for its captured exposure. + +Pine still owns selection, timing, OCA ordering, risk behavior and the separate +margin-revival direct-close path. Exact multiple-tracker routing and captured +cycle validity are source corrections, not proven behavior-neutral changes. +The existing dispatch retirement ledger prevents replay and excludes retired +receivers before physical compaction; no second consumed bit or owner map exists. + +Native literal tests are in `tests/test_reservation_expansion.cpp`; old and new +C++ header/link boundaries are checked by `scripts/check_script_cpp_abi.py`. +They establish bounded ownership and pairing contracts. Compatibility outcomes +require a separate assessment with unchanged reference evidence. diff --git a/include/pineforge/compat/pine/exit_activation.hpp b/include/pineforge/compat/pine/exit_activation.hpp index 5024b01..479bd69 100644 --- a/include/pineforge/compat/pine/exit_activation.hpp +++ b/include/pineforge/compat/pine/exit_activation.hpp @@ -9,7 +9,7 @@ namespace pineforge { enum class PositionSide; -inline namespace engine_script_run_v6 { struct PendingOrder; } +inline namespace engine_script_run_v7 { struct PendingOrder; } } namespace pineforge::compat::pine { diff --git a/include/pineforge/compat/pine/frozen_market_instruction.hpp b/include/pineforge/compat/pine/frozen_market_instruction.hpp new file mode 100644 index 0000000..824bd34 --- /dev/null +++ b/include/pineforge/compat/pine/frozen_market_instruction.hpp @@ -0,0 +1,72 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace pineforge { +inline namespace engine_script_run_v7 { struct PendingOrder; } +} + +namespace pineforge::compat::pine { + +enum class FrozenMarketInstructionKind { Ordinary, Transaction, TargetedClose }; + +// Pine source interpretation retained at command admission. This is not a +// generic native reduce-position operation: its existing close-artifact path +// can open an artifact lot after the original side has disappeared. Native +// lowering of that behavior remains a separate adapter-boundary change. +// The transaction keeps its own admitted units and total transaction units; +// a targeted close uses QuantityRequest's original resolved Units amount. +class FrozenMarketInstruction { +public: + struct Transaction { + double own_units; + double transaction_units; + }; + struct TargetedClose { + std::string target_id; + }; + FrozenMarketInstruction() = default; + static FrozenMarketInstruction transaction(double own, double total) { + if (!std::isfinite(own) || own <= 0.0 || std::isnan(total) || total < own) + throw std::invalid_argument("invalid frozen market transaction amounts"); + // Keep the existing execution-side finite-total guard. A positive + // overflowed source sum is not silently replaced by an ordinary order + // or a second default-sized amount by this representation change. + return FrozenMarketInstruction(Transaction{own, total}); + } + static FrozenMarketInstruction targeted_close(std::string target, + const QuantityRequest& request) { + if (target.empty() || !request.intent() + || request.intent()->kind() != QuantityIntent::Kind::Units + || !std::isfinite(request.intent()->units()) || request.intent()->units() <= 0.0) + throw std::invalid_argument("targeted close requires a resolved positive units request"); + return FrozenMarketInstruction(TargetedClose{std::move(target)}); + } + FrozenMarketInstructionKind kind() const { + return static_cast(value_.index()); + } + bool active() const { return !std::holds_alternative(value_); } + const Transaction* transaction() const { return std::get_if(&value_); } + const TargetedClose* targeted_close() const { return std::get_if(&value_); } + void revoke() { value_ = std::monostate{}; } +private: + using Value = std::variant; + explicit FrozenMarketInstruction(Value value) : value_(std::move(value)) {} + Value value_; +}; + +// Full-book admission is one source-policy step before native matching. +// source_scope_live is the engine's current selector result, not stored state. +void finalize_frozen_market_book(std::vector& orders, bool source_scope_live); + +} // namespace pineforge::compat::pine + +namespace pineforge { +using PineFrozenMarketInstruction = compat::pine::FrozenMarketInstruction; +} // namespace pineforge diff --git a/include/pineforge/compat/pine/order_birth.hpp b/include/pineforge/compat/pine/order_birth.hpp index b57ffe0..14fef7d 100644 --- a/include/pineforge/compat/pine/order_birth.hpp +++ b/include/pineforge/compat/pine/order_birth.hpp @@ -1,7 +1,7 @@ #pragma once #include "../../order_birth.hpp" -namespace pineforge { inline namespace engine_script_run_v6 { struct PendingOrder; } } +namespace pineforge { inline namespace engine_script_run_v7 { struct PendingOrder; } } namespace pineforge::compat::pine { // Historical Pine permissions remain policy, not physical birth facts. diff --git a/include/pineforge/compat/pine/order_priority.hpp b/include/pineforge/compat/pine/order_priority.hpp index 86aac96..71e69e1 100644 --- a/include/pineforge/compat/pine/order_priority.hpp +++ b/include/pineforge/compat/pine/order_priority.hpp @@ -5,7 +5,7 @@ #include #include -namespace pineforge { inline namespace engine_script_run_v6 { struct PendingOrder; } } +namespace pineforge { inline namespace engine_script_run_v7 { struct PendingOrder; } } namespace pineforge::compat::pine { struct OrderPriorityContext { diff --git a/include/pineforge/compat/pine/reservation_expansion.hpp b/include/pineforge/compat/pine/reservation_expansion.hpp new file mode 100644 index 0000000..da131c7 --- /dev/null +++ b/include/pineforge/compat/pine/reservation_expansion.hpp @@ -0,0 +1,17 @@ +#pragma once +#include +#include +#include +namespace pineforge { +enum class PositionSide; +inline namespace engine_script_run_v7 { struct PendingOrder; } +} +namespace pineforge::compat::pine { +// Called only for omitted explicit exit qty. Pine owns the population selector; +// native capture/closure/resize never reads these compatibility settings. +std::vector select_reservation_growth_sources(const std::vector& book, + const std::string& from_entry, bool process_on_close, bool effectively_flat, + double percent, int bar, PositionSide side); +bool admits_reservation_expansion(const std::vector& selected, + bool partial, double reserved, double live); +} // namespace pineforge::compat::pine diff --git a/include/pineforge/engine.hpp b/include/pineforge/engine.hpp index 64c7322..82fc87d 100644 --- a/include/pineforge/engine.hpp +++ b/include/pineforge/engine.hpp @@ -14,6 +14,8 @@ #include "bar.hpp" #include "broker_events.hpp" #include "quantity_intent.hpp" +#include "reservation_expansion.hpp" +#include "compat/pine/frozen_market_instruction.hpp" #include "leg_activation.hpp" #include "compat/pine/exit_activation.hpp" #include "order_birth.hpp" @@ -406,7 +408,7 @@ enum class ShortSeedCollisionRole : uint8_t { // PendingOrder crosses out-of-line helper boundaries independently of the // engine class, so its changed layout must carry the same internal epoch. -inline namespace engine_script_run_v6 { +inline namespace engine_script_run_v7 { struct PendingOrder { std::string id; std::string from_entry; // for exit orders @@ -857,23 +859,10 @@ struct PendingOrder { // qty_percent remain the executable/reserved values used by existing Pine // reservation rules; their later reduction cannot rewrite caller intent. QuantityRequest quantity_request; - // Narrow POOC global-full-exit candidate. ``qty`` deliberately keeps the - // normal finite reservation so sibling exits see and respect its capacity. - // At fill time this bit upgrades that one reservation to the full live - // position, covering same-bar MARKET pyramid adds that were already - // pending when the exit was placed. Any later admitted entry-like order - // clears the bit, making the finite qty the automatic conservative - // fallback—even when that later order is placed on a future bar. - bool pooc_global_full_exit_dynamic_qty = false; - // Persistent half of the bounded POOC relation. Unlike ``dynamic_qty``, - // later entries do not clear this bit: pre-exit adds may still be waiting - // to fill when invalidation occurs. Each successfully filled bound add - // grows this EXIT's finite qty by its exact same-side position delta. - bool pooc_global_full_exit_tracks_bound_adds = false; - // Set only on qualifying high-level MARKET adds already pending when the - // tracking global EXIT is placed. Same-id replacement constructs a fresh - // PendingOrder and therefore drops the relation; later orders never get it. - bool pooc_global_full_exit_bound_add = false; + // EXIT-owned exposure capture and source-owned exact receiver receipt. + // The public legacy flags are one-way projections of these causal facts. + ReservationExpansion reservation_expansion; + ReservationGrowthSource reservation_growth_source; // round 8 family S — TradingView's same-bar MARKET transaction (ledger // note log-20260905t143024z-76025577; 15 lab tv sensor tapes famS-dbl-*, // famS-rev-plus-close, famS-adm-{es,nq}-{1e6,500k} on CME_MINI:ES1!/NQ1! @@ -911,14 +900,11 @@ struct PendingOrder { // dropped, so its same-id close finds no pending entry and is cancelled // (LONG 1, no artifact row). The generalized form of the short-seed // collision kernel (finding 272), with which it agrees on that book. - bool sbmt_member = false; - double sbmt_own_qty = std::numeric_limits::quiet_NaN(); - double sbmt_tx_qty = std::numeric_limits::quiet_NaN(); - bool sbmt_kept_over_cap = false; - // strategy.close member: frozen target and broker side (buy closes a - // short). The target id is order.id without the "__close__" prefix. - double sbmt_close_qty = std::numeric_limits::quiet_NaN(); - bool sbmt_close_buy = false; + // One typed source instruction. Transaction quantities live here; a + // targeted close consumes quantity_request's resolved original Units. + // Cap and closing-side facts remain the existing immutable placement + // snapshots, rather than separately writable coordination booleans. + PineFrozenMarketInstruction pine_frozen_market_instruction; // design-declined-reversal-close-leg: set at the KI-54 percent-of-equity // reversal-decline site when this pending FULL close was co-queued AFTER, // and on the same bar as, the declined MARKET reversal entry targeting the @@ -1033,7 +1019,7 @@ struct PendingOrder { ShortSeedCollisionRole::NONE; }; - } // inline namespace engine_script_run_v6 (PendingOrder) + } // inline namespace engine_script_run_v7 (PendingOrder) // default_qty_type constants (matches TradingView) enum class QtyType { FIXED = 0, PERCENT_OF_EQUITY = 1, CASH = 2 }; @@ -1091,7 +1077,7 @@ struct StrategyOverrides { // v6 adds explicit owner-bound exit-leg activation and Pine placement evidence. // Version the mangled class name so older headers' member offsets/vtable cannot // silently bind out-of-line members of this different object layout. -inline namespace engine_script_run_v6 { +inline namespace engine_script_run_v7 { class BacktestEngine { protected: // --- Position state --- @@ -2169,8 +2155,11 @@ class BacktestEngine { && std::isfinite(order.affordability_placement_equity) && order.affordability_placement_equity > 0.0 && order.affordability_held_qty == 0.0 - && (!order.sbmt_member || (order.sbmt_tx_qty == order.sbmt_own_qty - && !order.sbmt_kept_over_cap)); + && (!order.pine_frozen_market_instruction.active() + || (order.pine_frozen_market_instruction.transaction() + && order.pine_frozen_market_instruction.transaction()->transaction_units + == order.pine_frozen_market_instruction.transaction()->own_units + && !order.over_pyramiding_cap_at_placement)); if (!default_all_in && !explicit_fixed) return false; const double mark = default_all_in ? order.sizing_mark : order.affordability_signal_price; @@ -3983,7 +3972,7 @@ class BacktestEngine { const PendingOrder& order) const; bool short_seed_collision_final_short_is_live( const PendingOrder& order) const; - // round 8 family S (PendingOrder::sbmt_member): the same-bar MARKET + // round 8 family S (PendingOrder::pine_frozen_market_instruction): the same-bar MARKET // transaction's scope, the close-artifact predicate (rule 4) and the // frozen-transaction reversal kernel (rules 1/2). bool same_bar_market_tx_scope_is_live() const; @@ -4253,7 +4242,7 @@ class BacktestEngine { double& qp_io, bool& is_partial_io, double& reserved_qty_out); - void invalidate_unsafe_pooc_global_full_exit_dynamic_qty(); + void close_reservation_capture_populations(uint64_t admitted_incarnation); // execute_market_entry / execute_partial_exit_* helpers (defined in // engine_orders.cpp). @@ -4976,12 +4965,12 @@ class BacktestEngine { // strategy.order size at the signal close), a // MARKET's frozen broker transaction // (paired_flat_market_transaction_qty; a - // same-bar-market member's sbmt_tx_qty from + // same-bar-market transaction's frozen total from // FLAT or as a kept over-cap add), or what one // of the two MARKET reversal kernels opens: // a same-bar-market member against an // opposite live position opens the remainder - // sbmt_tx_qty - min(sbmt_tx_qty, live qty) + // transaction_units - min(transaction_units, live qty) // (apply_same_bar_market_tx_reversal), and the // exact SHORT-seed collision's final short // re-opens the residual pyramid_entries_[0].qty @@ -5129,5 +5118,5 @@ class BacktestEngine { void trace(const std::string& name, int value) { trace(name, static_cast(value)); } }; -} // inline namespace engine_script_run_v6 +} // inline namespace engine_script_run_v7 } // namespace pineforge diff --git a/include/pineforge/pending_order_mirror.hpp b/include/pineforge/pending_order_mirror.hpp index 3d23478..fd34cba 100644 --- a/include/pineforge/pending_order_mirror.hpp +++ b/include/pineforge/pending_order_mirror.hpp @@ -1,5 +1,5 @@ // GENERATED by scripts/gen_pending_order_mirror.py from include/pineforge/engine.hpp -- do not edit. -// 94 PendingOrder members mirrored (142 POD fields incl. struct_version/size). +// 88 PendingOrder members mirrored (155 POD fields incl. struct_version/size). #pragma once #include @@ -98,16 +98,16 @@ typedef struct pf_pending_order_v1_s { uint64_t comment_hash64; uint8_t requested_partial; // deprecated, derived output only uint8_t full_percent_exit_request; // deprecated, derived output only - uint8_t pooc_global_full_exit_dynamic_qty; - uint8_t pooc_global_full_exit_tracks_bound_adds; - uint8_t pooc_global_full_exit_bound_add; + uint8_t pooc_global_full_exit_dynamic_qty; // deprecated, derived output only + uint8_t pooc_global_full_exit_tracks_bound_adds; // deprecated, derived output only + uint8_t pooc_global_full_exit_bound_add; // deprecated, derived output only uint8_t created_while_in_position; // deprecated, derived output only - uint8_t sbmt_member; - double sbmt_own_qty; - double sbmt_tx_qty; - uint8_t sbmt_kept_over_cap; - double sbmt_close_qty; - uint8_t sbmt_close_buy; + uint8_t sbmt_member; // deprecated, derived output only + double sbmt_own_qty; // deprecated, derived output only + double sbmt_tx_qty; // deprecated, derived output only + uint8_t sbmt_kept_over_cap; // deprecated, derived output only + double sbmt_close_qty; // deprecated, derived output only + uint8_t sbmt_close_buy; // deprecated, derived output only uint8_t suppress_as_declined_reversal_close; uint8_t dormant_bracket; uint8_t dormant_reissue_pending; @@ -154,6 +154,19 @@ typedef struct pf_pending_order_v1_s { uint8_t pine_exit_activation_limit_continuation_present; int32_t pine_exit_activation_limit_continuation_cause; uint64_t pine_exit_activation_limit_continuation_fill; + int64_t reservation_expansion_position_cycle; + uint8_t reservation_expansion_present; + int32_t reservation_expansion_side; + uint8_t reservation_expansion_first_later_admission_present; + uint64_t reservation_expansion_first_later_admission; + uint8_t reservation_growth_source_present; + uint64_t reservation_growth_source_reservation_owner; + uint64_t pine_frozen_market_instruction_kind; + double pine_frozen_market_instruction_own_units; + double pine_frozen_market_instruction_transaction_units; + char pine_frozen_market_instruction_target_id[64]; + uint8_t pine_frozen_market_instruction_target_id_truncated; + uint64_t pine_frozen_market_instruction_target_id_hash64; } pf_pending_order_v1_t; /* One row of the self-describing layout table returned by diff --git a/include/pineforge/reservation_expansion.hpp b/include/pineforge/reservation_expansion.hpp new file mode 100644 index 0000000..b4302c9 --- /dev/null +++ b/include/pineforge/reservation_expansion.hpp @@ -0,0 +1,53 @@ +#pragma once +#include +#include + +namespace pineforge { +enum class PositionSide; + +// First standalone C++ ABI for the reservation ownership model. +inline namespace reservation_expansion_v1 { + +// The containing EXIT incarnation owns this capture. Admission is an immutable +// historical cause; neither cancellation nor a new exposure erases the receipt. +struct ReservationExpansionCapture { + int64_t position_cycle; + PositionSide side; + std::optional first_later_admission; +}; + +class ReservationExpansion { +public: + void capture(uint64_t receiver, int64_t cycle, PositionSide side, double capacity); + void close_population(uint64_t admitted_incarnation); + const std::optional& capture() const { return capture_; } + bool population_open() const { return capture_ && !capture_->first_later_admission; } + bool owns_exposure(int64_t cycle, PositionSide side) const; + bool live_all(int64_t cycle, PositionSide side) const { + return population_open() && owns_exposure(cycle, side); + } + // The caller resolves the exact actionable receiver. This operation knows + // only exposure facts and the committed primary delta; qty is the sole + // mutable capacity, and QuantityRequest is never rebased here. + // Preconditions for standalone callers: finite nonnegative qty, endpoint + // quantities and epsilon; the resulting capacity must remain finite. The + // caller supplies real before/after exposure facts. This method preserves + // the native after_qty > before_qty + epsilon arithmetic without repricing + // or re-rounding; it does not validate every standalone precondition. + void grow(double& qty, int64_t before_cycle, PositionSide before_side, double before_qty, + int64_t after_cycle, PositionSide after_side, double after_qty, double epsilon) const; +private: + std::optional capture_; +}; + +// The containing source incarnation is the source identity. This is the only +// authoritative edge; replacement is allowed only at a new successful capture. +class ReservationGrowthSource { +public: + void assign_capture(uint64_t source, uint64_t receiver); + const std::optional& reservation_owner() const { return reservation_owner_; } +private: + std::optional reservation_owner_; +}; +} // inline namespace reservation_expansion_v1 +} // namespace pineforge diff --git a/scripts/check_broker_state_hash_coverage.py b/scripts/check_broker_state_hash_coverage.py index be8190e..9654f5d 100644 --- a/scripts/check_broker_state_hash_coverage.py +++ b/scripts/check_broker_state_hash_coverage.py @@ -195,6 +195,16 @@ def _class_fields(src: str, name: str) -> dict[str, str]: continue if re.fullmatch(r"(?:bool|ExitLegActivationBounds)\s+\w+\([^;{}]*\)\s+const", decl): continue # declared read-only value query, never a stored field + reservation_methods = { + "ReservationExpansion": { + "void capture(uint64_t receiver, int64_t cycle, PositionSide side, double capacity)", + "void close_population(uint64_t admitted_incarnation)", + "void grow(double& qty, int64_t before_cycle, PositionSide before_side, double before_qty, int64_t after_cycle, PositionSide after_side, double after_qty, double epsilon) const", + }, + "ReservationGrowthSource": {"void assign_capture(uint64_t source, uint64_t receiver)"}, + } + if decl in reservation_methods.get(name, set()): + continue # exact declared operations, never a blanket declaration waiver if decl and not decl.startswith("using "): match = re.fullmatch(r"((?:(?:static|constexpr|const)\s+)*[\w:<>]+)\s+(\w+)(?:\s*=\s*[^,]+)?", decl) if not match or match[2] in fields: @@ -384,6 +394,40 @@ def _quantity_request_coverage(quantity: str, source: str) -> None: if prefix.count("{") != prefix.count("}"): raise ValueError("quantity request hash must be unconditional inside its order loop") +def _pine_frozen_market_instruction_coverage(header: str, source: str) -> None: + """An exclusive instruction, with each live payload folded in its owner loop.""" + header = _strip_cpp_comments(header) + if _class_fields(header, "FrozenMarketInstruction") != {"value_": "Value"}: + raise ValueError("FrozenMarketInstruction fields changed; classify every frozen fact") + for name, fields in [ + ("Transaction", [("double", "own_units"), ("double", "transaction_units")]), + ("TargetedClose", [("std::string", "target_id")]), + ]: + if struct_members(header, name) != fields: + raise ValueError(name + " instruction payload changed; update hash and mirror") + if not re.search(r"using\s+Value\s*=\s*std::variant\s*;", header): + raise ValueError("FrozenMarketInstruction variant discriminator changed") + body = _one_braced_body(header, + r"enum\s+class\s+FrozenMarketInstructionKind\s*\{", "FrozenMarketInstructionKind") + if [x.strip() for x in body.split(",")] != ["Ordinary", "Transaction", "TargetedClose"]: + raise ValueError("FrozenMarketInstructionKind hash encoding changed") + loop = _collection_loop_body(source, "pending_orders_", "o") + expected = """f.i(static_cast(o.pine_frozen_market_instruction.kind())); + if (const auto* transaction = o.pine_frozen_market_instruction.transaction()) { + f.d(transaction->own_units); f.d(transaction->transaction_units); + } + if (const auto* close = o.pine_frozen_market_instruction.targeted_close()) { + f.s(close->target_id); + }""" + compact = re.sub(r"\s+", "", loop) + folded = re.sub(r"\s+", "", expected) + if compact.count(folded) != 1: + raise ValueError("frozen market instruction requires every live field and role discriminator") + prefix = compact[:compact.index(folded)] + if prefix.count("{") != prefix.count("}") or (prefix and prefix[-1] not in ";}"): + raise ValueError("frozen market instruction hash must be unconditional in its order loop") + + def _birth_coverage(header: str, source: str) -> None: header = _strip_cpp_comments(header) expected = { @@ -449,8 +493,60 @@ def _exit_activation_coverage(activation: str, policy: str, source: str) -> None raise ValueError("exit activation hash block must be unconditional") +def _reservation_expansion_fields(header: str) -> None: + header = _strip_cpp_comments(header) + expected = { + "ReservationExpansion": {"capture_": "std::optional"}, + "ReservationExpansionCapture": {"position_cycle": "int64_t", "side": "PositionSide", "first_later_admission": "std::optional"}, + "ReservationGrowthSource": {"reservation_owner_": "std::optional"}, + } + for name, fields in expected.items(): + if _class_fields(header, name) != fields: + raise ValueError(name + " fields changed; every capture/source fact must be hashed") + +def _reservation_expansion_coverage(header: str, source: str) -> None: + _reservation_expansion_fields(header) + loop = _collection_loop_body(source, "pending_orders_", "o") + expected = """f.b(o.reservation_expansion.capture().has_value()); + if (const auto& capture = o.reservation_expansion.capture()) { + f.i(capture->position_cycle); + f.i(static_cast(capture->side)); + f.b(capture->first_later_admission.has_value()); + if (const auto& admission = capture->first_later_admission) { + f.u(*admission); + } + } + f.b(o.reservation_growth_source.reservation_owner().has_value()); + if (const auto& receiver = o.reservation_growth_source.reservation_owner()) { + f.u(*receiver); + }""" + compact = re.sub(r"\s+", "", loop) + folded = re.sub(r"\s+", "", expected) + if compact.count(folded) != 1: + raise ValueError("reservation capture/source encoding needs every nested fact and discriminator once") + prefix = compact[:compact.index(folded)] + if prefix.count("{") != prefix.count("}") or (prefix and prefix[-1] not in ";}"): + raise ValueError("reservation capture/source hash block must be unconditional") + + +def _reservation_expansion_version_coverage(header: str, source: str) -> None: + """Standalone layout-sensitive types and methods own their first ABI.""" + declaration = _one_braced_body(_strip_cpp_comments(header), + r"inline\s+namespace\s+reservation_expansion_v1\s*\{", "reservation ABI") + implementation = _one_braced_body(_strip_cpp_comments(source), + r"inline\s+namespace\s+reservation_expansion_v1\s*\{", "reservation implementation ABI") + for name in ("ReservationExpansionCapture", "ReservationExpansion", "ReservationGrowthSource"): + if not re.search(r"\b(?:class|struct)\s+" + name + r"\s*\{", declaration): + raise ValueError(name + " must belong to reservation_expansion_v1") + for name in ("ReservationExpansion::capture", "ReservationExpansion::close_population", + "ReservationExpansion::owns_exposure", "ReservationExpansion::grow", + "ReservationGrowthSource::assign_capture"): + if not re.search(r"\b" + re.escape(name) + r"\s*\(", implementation): + raise ValueError(name + " must be implemented in reservation_expansion_v1") + + def _runtime_version_coverage(header: str, source: str, stream: str) -> None: - """The v6 layout and serialized-state contracts must advance together. + """The v7 layout and serialized-state contracts must advance together. Pin the actual hash entry points, rather than accepting a version string mentioned in a comment or an unrelated helper. Public C ABI versions have @@ -458,18 +554,18 @@ def _runtime_version_coverage(header: str, source: str, stream: str) -> None: """ header = _strip_cpp_comments(header) namespaces = re.findall(r"inline\s+namespace\s+(engine_script_run_v\d+)\s*\{", header) - if namespaces != ["engine_script_run_v6", "engine_script_run_v6"]: - raise ValueError("PendingOrder and BacktestEngine layouts require internal namespace engine_script_run_v6") + if namespaces != ["engine_script_run_v7", "engine_script_run_v7"]: + raise ValueError("PendingOrder and BacktestEngine layouts require internal namespace engine_script_run_v7") broker = _one_braced_body(source, r"uint64_t\s+BacktestEngine::broker_state_hash\(\)\s+const\s*\{", "broker hash") - if not re.match(r'\s*Fnv\s+f;\s*f\.s\("pineforge-broker-state/v6"\);', broker): - raise ValueError("broker hash must start with pineforge-broker-state/v6") + if not re.match(r'\s*Fnv\s+f;\s*f\.s\("pineforge-broker-state/v7"\);', broker): + raise ValueError("broker hash must start with pineforge-broker-state/v7") stream_body = _one_braced_body(_strip_cpp_comments(stream), r"uint64_t\s+BacktestEngine::stream_state_hash\(\)\s+const\s*\{", "stream hash") compact = re.sub(r"\s+", "", stream_body) - fold = "integer(6);integer(broker_state_hash());" + fold = "integer(7);integer(broker_state_hash());" if compact.count(fold) != 1: - raise ValueError("stream hash requires version 6 followed by the broker hash") + raise ValueError("stream hash requires version 7 followed by the broker hash") prefix = compact[:compact.index(fold)] if prefix.count("{") != prefix.count("}") or (prefix and prefix[-1] not in ";}"): raise ValueError("stream version fold must be unconditional at function scope") @@ -484,6 +580,12 @@ def main(root: Path = ROOT) -> int: src = _strip_cpp_comments(src_raw) try: _runtime_version_coverage(hpp, src, (root / "src/engine_stream.cpp").read_text()) + _reservation_expansion_version_coverage( + (root / "include/pineforge/reservation_expansion.hpp").read_text(), + (root / "src/reservation_expansion.cpp").read_text()) + _reservation_expansion_coverage((root / "include/pineforge/reservation_expansion.hpp").read_text(), src) + _pine_frozen_market_instruction_coverage( + (root / "include/pineforge/compat/pine/frozen_market_instruction.hpp").read_text(), src) _birth_coverage((root / "include/pineforge/order_birth.hpp").read_text(), src) _exit_activation_coverage((root / "include/pineforge/leg_activation.hpp").read_text(), (root / "include/pineforge/compat/pine/exit_activation.hpp").read_text(), src) @@ -504,8 +606,11 @@ def main(root: Path = ROOT) -> int: return 1 waivers = {k: v for k, v in all_waivers.items() if not k.startswith((PENDING_WAIVER_PREFIX, PYRAMID_WAIVER_PREFIX))} - if "pending_order.quantity_request" in all_waivers: - print("check_broker_state_hash_coverage: quantity_request cannot be waived", file=sys.stderr) + if {"pending_order.reservation_expansion", "pending_order.reservation_growth_source"} & all_waivers.keys(): + print("check_broker_state_hash_coverage: reservation capture/source cannot be waived", file=sys.stderr) + return 1 + if {"pending_order.quantity_request", "pending_order.pine_frozen_market_instruction"} & all_waivers.keys(): + print("check_broker_state_hash_coverage: quantity_request and pine_frozen_market_instruction cannot be waived", file=sys.stderr) return 1 po_waivers = {k[len(PENDING_WAIVER_PREFIX):]: v for k, v in all_waivers.items() if k.startswith(PENDING_WAIVER_PREFIX)} diff --git a/scripts/check_script_cpp_abi.py b/scripts/check_script_cpp_abi.py index afed8a7..2752b02 100644 --- a/scripts/check_script_cpp_abi.py +++ b/scripts/check_script_cpp_abi.py @@ -16,7 +16,7 @@ BASE_COMMIT = "38dc73e5503fe5395458e5f8df2a2ad78054a1ae" BASE_ENGINE_SHA256 = "06c937a1ccd31815ca7775268ac699ffdfddb1a1f19de4628b777f37e9a6d193" -CURRENT_NAMESPACE = "engine_script_run_v6" +CURRENT_NAMESPACE = "engine_script_run_v7" BASE_NAMESPACE = "engine_script_run_v2" FIXTURE = Path(__file__).resolve().parents[1] / "tests/fixtures/script_cpp_abi/base38" @@ -30,13 +30,14 @@ def entry_diagnostic(lines, namespace, method): def frozen_headers(destination, fixture=FIXTURE, commit=BASE_COMMIT, - namespace=BASE_NAMESPACE, engine_sha=BASE_ENGINE_SHA256): + namespace=BASE_NAMESPACE, engine_sha=BASE_ENGINE_SHA256, tree=None): """Authenticate and unpack the exact tracked base38 header closure.""" manifest = json.loads((fixture / "manifest.json").read_text()) if (manifest["source_commit"] != commit or manifest["internal_namespace"] != namespace - or manifest["files"]["pineforge/engine.hpp"]["sha256"] != engine_sha): - raise RuntimeError("stale-header fixture does not identify the pinned base38 contract") + or manifest["files"]["pineforge/engine.hpp"]["sha256"] != engine_sha + or (tree is not None and manifest.get("source_tree") != tree)): + raise RuntimeError("stale-header fixture does not identify the pinned contract") archive = (fixture / "headers.json.gz").read_bytes() if hashlib.sha256(archive).hexdigest() != manifest["archive_sha256"]: raise RuntimeError("stale-header fixture archive digest mismatch") @@ -130,7 +131,12 @@ def main(): parser.add_argument("--include", required=True) parser.add_argument("--generated-include", required=True) parser.add_argument("--extra-flag", action="append", default=[]) + parser.add_argument("--receipt", type=Path) args = parser.parse_args() + receipt = {"library_sha256": hashlib.sha256(Path(args.library).read_bytes()).hexdigest(), + "current_namespace": CURRENT_NAMESPACE, + "standalone_namespace": "reservation_expansion_v1", + "executable_runs": 0, "compiles": [], "links": []} # Literal diagnostic controls guard the link-failure parser itself. for namespace in (BASE_NAMESPACE, CURRENT_NAMESPACE): report_only = [f"undefined pineforge::{namespace}::BacktestEngine::fill_report(pineforge::ReportC*) const"] @@ -154,6 +160,16 @@ def main(): frozen_headers(activation_include, FIXTURE.parent / "base149", "149f77ce16ef84c6da77e67d812bf8fa88e51cde", "engine_script_run_v5", "5ba773889d947e4fdab3995cc55f22f88ab037a86e0ad4016a126d297ce82eed") + shipped_include = root / "baseff54/include" + frozen_headers(shipped_include, FIXTURE.parent / "baseff54", + "ff54a557ac751244dafd60df0bb22886ec35792d", "engine_script_run_v6", + "d5d74b2b0542ce7aa2bf3e0a95bac8d05318ce15494148f4f07f92c7e332b237", + "60431e5da18d4bce0777f0e3b4df03d41163c350") + growth_include = root / "growthbf312/include" + frozen_headers(growth_include, FIXTURE.parent / "growthbf312", + "ff54a557ac751244dafd60df0bb22886ec35792d", "engine_script_run_v6", + "381a18d59f20ff94c6eed9dec40497fdaa175637fc96169a0a9875a38b071736", + "bf312b9d5a705d3d0ca16d4fb897e16c6e73b0d1") common = [args.compiler, "-std=c++17", "-O0", *args.extra_flag] def compile_object(name, source, include): @@ -168,6 +184,9 @@ def compile_object(name, source, include): if compiled.returncode: raise RuntimeError(name + " failed to compile (not a pairing rejection):\n" + compiled.stderr) + receipt["compiles"].append({"name": name, "exit": compiled.returncode, + "source_sha256": hashlib.sha256(source.encode()).hexdigest(), + "object_sha256": hashlib.sha256(obj.read_bytes()).hexdigest()}) return obj current_native = compile_object("current_native", caller(CURRENT_NAMESPACE), args.include) @@ -214,6 +233,62 @@ def compile_object(name, source, include): BASE_SYMBOL_CONTROL.replace("engine_script_run_v2", "engine_script_run_v5"), activation_include) activation_priority = compile_object("base149_pending_priority", priority_caller, activation_include) activation_priority_symbols = compile_object("base149_pending_priority_symbols", priority_symbols, activation_include) + shipped_native = compile_object("baseff54_native", caller("engine_script_run_v6"), shipped_include) + shipped_generated = compile_object("baseff54_generated", caller("engine_script_run_v6", True), shipped_include) + shipped_symbols = compile_object("baseff54_symbol_control", + BASE_SYMBOL_CONTROL.replace("engine_script_run_v2", "engine_script_run_v6"), shipped_include) + shipped_priority = compile_object("baseff54_pending_priority", priority_caller, shipped_include) + shipped_priority_symbols = compile_object("baseff54_pending_priority_symbols", priority_symbols, shipped_include) + + reservation_caller = '''#include +int main(int argc, char**) { + pineforge::ReservationExpansion expansion; + pineforge::ReservationGrowthSource source; + const auto side = static_cast(argc); + double capacity = 4.0; + expansion.capture(1, 1, side, capacity); + expansion.close_population(2); + expansion.grow(capacity, 1, side, 1.0, 1, side, 2.0, 1e-10); + source.assign_capture(3, 1); + return expansion.owns_exposure(1, side) ? 0 : 1; +} +''' + reservation_symbols = '''#include +namespace pineforge { +void ReservationExpansion::capture(uint64_t, int64_t, PositionSide, double) {} +void ReservationExpansion::close_population(uint64_t) {} +bool ReservationExpansion::owns_exposure(int64_t, PositionSide) const { return false; } +void ReservationExpansion::grow(double&, int64_t, PositionSide, double, + int64_t, PositionSide, double, double) const {} +void ReservationGrowthSource::assign_capture(uint64_t, uint64_t) {} +} +''' + reservation_assertions = '''#include +static_assert(std::is_same::value); +static_assert(std::is_same::value); +static_assert(std::is_same::value); +''' + current_reservation = compile_object("current_standalone_reservation", + reservation_caller + reservation_assertions, args.include) + draft_reservation = compile_object("growthbf312_unversioned_reservation", reservation_caller, growth_include) + draft_reservation_symbols = compile_object("growthbf312_reservation_symbols", reservation_symbols, growth_include) + capture_caller = '''#include +void pairing_capture(const pineforge::ReservationExpansionCapture&); +int main() { + pineforge::ReservationExpansionCapture capture{1, static_cast(1), {}}; + pairing_capture(capture); +} +''' + capture_provider = '''#include +void pairing_capture(const pineforge::ReservationExpansionCapture&) {} +''' + current_capture = compile_object("current_capture_argument", capture_caller, args.include) + draft_capture = compile_object("growthbf312_capture_argument", capture_caller, growth_include) + current_capture_symbols = compile_object("current_capture_symbols", capture_provider, args.include) + draft_capture_symbols = compile_object("growthbf312_capture_symbols", capture_provider, growth_include) def link(name, obj, runtime, missing_namespace=None): linked = subprocess.run( @@ -224,6 +299,7 @@ def link(name, obj, runtime, missing_namespace=None): if linked.returncode: raise RuntimeError(name + " positive control failed to link:\n" + linked.stderr) print(name + ": linked (not executed)") + receipt["links"].append({"name": name, "outcome": "linked", "exit": 0}) return if not linked.returncode: raise RuntimeError(name + " stale C++ pairing unexpectedly linked") @@ -240,6 +316,8 @@ def link(name, obj, runtime, missing_namespace=None): + "BacktestEngine entry symbols") for method in required_methods: print(" " + entries[method].strip()) + receipt["links"].append({"name": name, "outcome": "expected_rejection", + "exit": linked.returncode, "diagnostics": list(entries.values())}) link("current_native_to_current", current_native, args.library) link("current_generated_to_current", current_generated, args.library) @@ -271,12 +349,21 @@ def link(name, obj, runtime, missing_namespace=None): link("current_native_to_v5_symbol_control", current_native, activation_symbols, CURRENT_NAMESPACE) link("current_generated_to_v5_symbol_control", current_generated, activation_symbols, CURRENT_NAMESPACE) link("base149_pending_priority_to_v5_symbols", activation_priority, activation_priority_symbols) + link("baseff54_native_to_v6_symbols", shipped_native, shipped_symbols) + link("baseff54_generated_to_v6_symbols", shipped_generated, shipped_symbols) + link("baseff54_native_to_current", shipped_native, args.library, "engine_script_run_v6") + link("baseff54_generated_to_current", shipped_generated, args.library, "engine_script_run_v6") + link("current_native_to_v6_symbols", current_native, shipped_symbols, CURRENT_NAMESPACE) + link("current_generated_to_v6_symbols", current_generated, shipped_symbols, CURRENT_NAMESPACE) + link("baseff54_pending_priority_to_v6_symbols", shipped_priority, shipped_priority_symbols) for name, obj, runtime, expected in [ + ("baseff54_pending_priority_to_current", shipped_priority, args.library, "pineforge::engine_script_run_v6::PendingOrder"), + ("current_pending_priority_to_v6_symbols", current_priority, shipped_priority_symbols, "pineforge::engine_script_run_v7::PendingOrder"), ("base149_pending_priority_to_current", activation_priority, args.library, "pineforge::engine_script_run_v5::PendingOrder"), - ("current_pending_priority_to_v5_symbols", current_priority, activation_priority_symbols, "pineforge::engine_script_run_v6::PendingOrder"), + ("current_pending_priority_to_v5_symbols", current_priority, activation_priority_symbols, "pineforge::engine_script_run_v7::PendingOrder"), ("basec45_pending_priority_to_current", prior_priority, args.library, "pineforge::PendingOrder"), ("current_pending_priority_to_v4_symbols", current_priority, prior_priority_symbols, - "pineforge::engine_script_run_v6::PendingOrder"), + "pineforge::engine_script_run_v7::PendingOrder"), ]: result = subprocess.run([*common, str(obj), str(runtime), "-pthread", "-o", str(root / name)], capture_output=True, text=True, timeout=60) @@ -284,7 +371,39 @@ def link(name, obj, runtime, missing_namespace=None): or "OrderPriority::select(" not in result.stderr or expected not in result.stderr): raise RuntimeError(name + " did not reject the expected PendingOrder type: " + result.stderr) print(name + ": rejected stale standalone PendingOrder argument type (not executed)") - print("20 translation units compiled; 13 positive links; 21 rejected links; no executable run") + receipt["links"].append({"name": name, "outcome": "expected_rejection", + "exit": result.returncode, "diagnostics": result.stderr}) + + link("current_reservation_to_current", current_reservation, args.library) + link("draft_reservation_to_draft_symbols", draft_reservation, draft_reservation_symbols) + link("current_capture_to_current_symbols", current_capture, current_capture_symbols) + link("draft_capture_to_draft_symbols", draft_capture, draft_capture_symbols) + for name, obj, runtime, expected in [ + ("draft_reservation_to_current", draft_reservation, args.library, + ["pineforge::ReservationExpansion::capture(", "pineforge::ReservationGrowthSource::assign_capture("]), + ("current_reservation_to_draft_symbols", current_reservation, draft_reservation_symbols, + ["pineforge::reservation_expansion_v1::ReservationExpansion::capture(", + "pineforge::reservation_expansion_v1::ReservationGrowthSource::assign_capture("]), + ("draft_capture_to_current_symbols", draft_capture, current_capture_symbols, + ["pairing_capture(pineforge::ReservationExpansionCapture const&)"]), + ("current_capture_to_draft_symbols", current_capture, draft_capture_symbols, + ["pairing_capture(pineforge::reservation_expansion_v1::ReservationExpansionCapture const&)"]), + ]: + result = subprocess.run([*common, str(obj), str(runtime), "-pthread", "-o", str(root / name)], + capture_output=True, text=True, timeout=60) + if (result.returncode == 0 or "undefined" not in result.stderr.lower() + or any(needle not in result.stderr for needle in expected)): + raise RuntimeError(name + " did not reject the expected reservation ABI: " + result.stderr) + print(name + ": rejected stale standalone reservation ABI (not executed)") + receipt["links"].append({"name": name, "outcome": "expected_rejection", + "exit": result.returncode, "diagnostics": result.stderr}) + linked = sum(item["outcome"] == "linked" for item in receipt["links"]) + rejected = sum(item["outcome"] == "expected_rejection" for item in receipt["links"]) + receipt["summary"] = {"compiled": len(receipt["compiles"]), "linked": linked, "rejected": rejected} + if args.receipt: + args.receipt.write_text(json.dumps(receipt, indent=2) + "\n") + print(f"{len(receipt['compiles'])} translation units compiled; {linked} positive links; " + f"{rejected} rejected links; no executable run") if __name__ == "__main__": diff --git a/scripts/gen_pending_order_mirror.py b/scripts/gen_pending_order_mirror.py index f740407..41d512a 100644 --- a/scripts/gen_pending_order_mirror.py +++ b/scripts/gen_pending_order_mirror.py @@ -61,6 +61,9 @@ # Public v1 is append-only. Removed native fields survive only as one-way # deprecated output projections at their original offsets. LEGACY_OUTPUTS = { + "pooc_global_full_exit_dynamic_qty": "src.reservation_expansion.population_open() ? 1 : 0", + "pooc_global_full_exit_tracks_bound_adds": "src.reservation_expansion.capture().has_value() ? 1 : 0", + "pooc_global_full_exit_bound_add": "src.reservation_growth_source.reservation_owner().has_value() ? 1 : 0", "coof_suppress_stop_on_entry_bar": "src.pine_exit_activation.holds_stop() ? 1 : 0", "coof_suppress_limit_on_entry_bar": "src.pine_exit_activation.holds_limit() ? 1 : 0", "created_during_coof_recalc": "src.birth.from_fill() ? 1 : 0", @@ -71,8 +74,34 @@ "created_while_in_position": "src.type == OrderType::EXIT && src.created_position_side != PositionSide::FLAT ? 1 : 0", "requested_partial": "src.quantity_request.is_partial(1e-9, 1e-9) ? 1 : 0", "full_percent_exit_request": "src.quantity_request.requests_all() ? 1 : 0", + "sbmt_member": "src.pine_frozen_market_instruction.active() ? 1 : 0", + "sbmt_own_qty": "src.pine_frozen_market_instruction.transaction() ? src.pine_frozen_market_instruction.transaction()->own_units : std::numeric_limits::quiet_NaN()", + "sbmt_tx_qty": "src.pine_frozen_market_instruction.transaction() ? src.pine_frozen_market_instruction.transaction()->transaction_units : std::numeric_limits::quiet_NaN()", + "sbmt_kept_over_cap": "src.pine_frozen_market_instruction.transaction() && src.over_pyramiding_cap_at_placement ? 1 : 0", + "sbmt_close_qty": "src.pine_frozen_market_instruction.targeted_close() ? src.quantity_request.intent()->units() : std::numeric_limits::quiet_NaN()", + "sbmt_close_buy": "src.pine_frozen_market_instruction.targeted_close() && src.created_position_side == PositionSide::SHORT ? 1 : 0", } COMPOSITE_MAP = { + "ReservationExpansion": [ + # An eight-byte first field preserves ff54's entire 142-field object, + # including trailing padding, before any appended smaller fields. + ("position_cycle", "int64_t", "src.{m}.capture() ? src.{m}.capture()->position_cycle : 0"), + ("present", "uint8_t", "src.{m}.capture().has_value() ? 1 : 0"), + ("side", "int32_t", "src.{m}.capture() ? static_cast(src.{m}.capture()->side) : 0"), + ("first_later_admission_present", "uint8_t", "src.{m}.capture() && src.{m}.capture()->first_later_admission ? 1 : 0"), + ("first_later_admission", "uint64_t", "src.{m}.capture() && src.{m}.capture()->first_later_admission ? *src.{m}.capture()->first_later_admission : 0"), + ], + "ReservationGrowthSource": [ + ("present", "uint8_t", "src.{m}.reservation_owner().has_value() ? 1 : 0"), + ("reservation_owner", "uint64_t", "src.{m}.reservation_owner() ? *src.{m}.reservation_owner() : 0"), + ], + "PineFrozenMarketInstruction": [ + # Start after the full ff54 142-field prefix, including trailing padding. + ("kind", "uint64_t", "static_cast(src.{m}.kind())"), + ("own_units", "double", "src.{m}.transaction() ? src.{m}.transaction()->own_units : 0.0"), + ("transaction_units", "double", "src.{m}.transaction() ? src.{m}.transaction()->transaction_units : 0.0"), + ("target_id", "std::string", "src.{m}.targeted_close() ? src.{m}.targeted_close()->target_id : std::string()"), + ], "ExitLegActivation": [ ("owner_cycle", "int64_t", "src.{m}.bounds() ? src.{m}.bounds()->position_cycle : 0"), ("present", "uint8_t", "src.{m}.bounds().has_value() ? 1 : 0"), @@ -211,6 +240,8 @@ def classify(ms: list[tuple[str, str]], waivers: dict[str, str]): """Return (mirrored, waived) where mirrored = [(cpp_type, name)] kept in the POD and waived = [(cpp_type, name, reason)]. Aborts on an unmapped, unwaived type or a waiver naming a non-member.""" + if {"reservation_expansion", "reservation_growth_source"} & waivers.keys(): + _fail("reservation expansion and source receipts cannot be waived") names = {n for _, n in ms} orphans = sorted(w for w in waivers if w not in names) if orphans: @@ -228,6 +259,11 @@ def classify(ms: list[tuple[str, str]], waivers: dict[str, str]): def generate() -> tuple[str, str]: + # Share the strict nested storage census; newly stored fields cannot hide + # behind an unchanged composite-map name. Imported lazily (checker also + # uses this module's PendingOrder parser). + from check_broker_state_hash_coverage import _reservation_expansion_fields + _reservation_expansion_fields((ROOT / "include/pineforge/reservation_expansion.hpp").read_text()) mirrored, waived = classify(members(), load_waivers()) fields: list[str] = [] copies: list[str] = [] @@ -238,8 +274,8 @@ def generate() -> tuple[str, str]: if name not in LEGACY_OUTPUTS and native.get(name) != kind: _fail(f"public v1 prefix member {name} needs an explicit derived projection") prefix_names = {name for _, name in prefix} - # Preserve the full 149f77c extension as well as the original c45 prefix. - existing_extension = ["replaced_order_incarnation", "birth", "pine_birth_reach", "quantity_request"] + # Preserve all 142 ff54 fields, including activation, before new composites. + existing_extension = ["replaced_order_incarnation", "birth", "pine_birth_reach", "quantity_request", "leg_activation", "pine_exit_activation"] tail = [(native[name], name) for name in existing_extension] tail += [(kind, name) for kind, name in mirrored if name not in prefix_names and name not in existing_extension] @@ -254,9 +290,18 @@ def generate() -> tuple[str, str]: for suffix, ct, expr in COMPOSITE_MAP[t]: prefix = "quantity" if t == "QuantityRequest" else m name = f"{prefix}_{suffix}" - fields.append(f" {ct} {name};") - copies.append(f" out->{name} = {expr.format(m=m)};") - descs.append((name, ct)) + if ct in STRING_TYPES: + fields += [f" char {name}[{STR_CAP}];", + f" uint8_t {name}_truncated;", + f" uint64_t {name}_hash64;"] + copies.append(f" copy_str({expr.format(m=m)}, out->{name}, &out->{name}_truncated, &out->{name}_hash64);") + descs += [(name, f"char[{STR_CAP}]"), + (f"{name}_truncated", "uint8_t"), + (f"{name}_hash64", "uint64_t")] + else: + fields.append(f" {ct} {name};") + copies.append(f" out->{name} = {expr.format(m=m)};") + descs.append((name, ct)) elif t in STRING_TYPES: fields += [f" char {m}[{STR_CAP}];", f" uint8_t {m}_truncated;", diff --git a/scripts/test_broker_state_hash_coverage.py b/scripts/test_broker_state_hash_coverage.py index afa5398..3f210e2 100644 --- a/scripts/test_broker_state_hash_coverage.py +++ b/scripts/test_broker_state_hash_coverage.py @@ -15,6 +15,9 @@ ROOT = Path(__file__).resolve().parents[1] HEADER = (ROOT / "include/pineforge/engine.hpp").read_text() +EXPANSION = (ROOT / "include/pineforge/reservation_expansion.hpp").read_text() +EXPANSION_SOURCE = (ROOT / "src/reservation_expansion.cpp").read_text() +FROZEN = (ROOT / "include/pineforge/compat/pine/frozen_market_instruction.hpp").read_text() QUANTITY = (ROOT / "include/pineforge/quantity_intent.hpp").read_text() EVENTS = (ROOT / "include/pineforge/broker_events.hpp").read_text() ACTIVATION = (ROOT / "include/pineforge/leg_activation.hpp").read_text() @@ -30,13 +33,16 @@ class PhysicalLotCoverage(unittest.TestCase): def check(self, header=HEADER, source=SOURCE, waivers=WAIVERS, events=EVENTS, - intraday=INTRADAY, policy=POLICY, obligation=OBLIGATION, stream=STREAM, quantity=QUANTITY, birth=BIRTH, activation=ACTIVATION, exit_policy=EXIT_POLICY): + intraday=INTRADAY, policy=POLICY, obligation=OBLIGATION, stream=STREAM, quantity=QUANTITY, birth=BIRTH, activation=ACTIVATION, exit_policy=EXIT_POLICY, expansion=EXPANSION, expansion_source=EXPANSION_SOURCE, frozen=FROZEN): with tempfile.TemporaryDirectory(prefix="pf-lot-hash-check-") as temp: root = Path(temp) for name, content in [ ("include/pineforge/engine.hpp", header), + ("include/pineforge/compat/pine/frozen_market_instruction.hpp", frozen), ("include/pineforge/broker_events.hpp", events), ("include/pineforge/quantity_intent.hpp", quantity), + ("include/pineforge/reservation_expansion.hpp", expansion), + ("src/reservation_expansion.cpp", expansion_source), ("include/pineforge/order_birth.hpp", birth), ("include/pineforge/leg_activation.hpp", activation), ("include/pineforge/compat/pine/exit_activation.hpp", exit_policy), @@ -59,6 +65,72 @@ def check(self, header=HEADER, source=SOURCE, waivers=WAIVERS, events=EVENTS, output.write(str(exc.code)) return code, output.getvalue() + def test_standalone_reservation_abi_is_versioned_in_header_and_source(self): + for old in ("reservation_expansion_v0", "reservation_expansion_v2"): + self.assertEqual(self.check(expansion=EXPANSION.replace( + "reservation_expansion_v1", old))[0], 1) + self.assertEqual(self.check(expansion_source=EXPANSION_SOURCE.replace( + "reservation_expansion_v1", old))[0], 1) + for name in ("ReservationExpansionCapture", "ReservationExpansion", "ReservationGrowthSource"): + self.assertEqual(self.check(expansion=EXPANSION.replace( + name + " {", name + "Outside {"))[0], 1) + + def test_every_capture_and_source_fold_is_required(self): + for fold in ["f.b(o.reservation_expansion.capture().has_value());", + "f.i(capture->position_cycle);", "f.i(static_cast(capture->side));", + "f.b(capture->first_later_admission.has_value());", "f.u(*admission);", + "f.b(o.reservation_growth_source.reservation_owner().has_value());", "f.u(*receiver);"]: + with self.subTest(fold=fold): + self.assertEqual(self.check(source=SOURCE.replace(fold, ""))[0], 1) + self.assertEqual(self.check(source=SOURCE.replace(fold, "/* " + fold + " */"))[0], 1) + self.assertEqual(self.check(source=SOURCE.replace(fold, fold.replace("f.", "wrong.")))[0], 1) + for owner in ["reservation_expansion", "reservation_growth_source"]: + self.assertEqual(self.check(waivers=WAIVERS + "\npending_order." + owner + " # forbidden\n")[0], 1) + + def test_capture_nested_storage_cannot_hide(self): + for field in ["std::optional capture_;", "int64_t position_cycle;", + "PositionSide side;", "std::optional first_later_admission;", + "std::optional reservation_owner_;"]: + with self.subTest(field=field): + self.assertEqual(self.check(expansion=EXPANSION.replace(field,field + " int hidden;"))[0],1) + self.assertEqual(self.check(expansion=EXPANSION.replace(field,field.replace("int64_t", "int").replace("PositionSide", "int").replace("ReservationExpansionCapture", "int")))[0],1) + + def test_capture_folds_cannot_be_conditional_rebound_or_duplicated(self): + start = SOURCE.index(" f.b(o.reservation_expansion.capture().has_value());") + end = SOURCE.index(" // Suppressed-close", start) + block = SOURCE[start:end] + for mutated in ["if (false) {" + block + "}", block + block, + block.replace("capture = o.reservation_expansion.capture()", "capture = foreign.capture()"), + block.replace("receiver = o.reservation_growth_source.reservation_owner()", "receiver = foreign.reservation_owner()"), + block.replace("admission = capture->first_later_admission", "admission = foreign.first_later_admission"), + "if(false) " + block]: + with self.subTest(mutated=mutated): + self.assertEqual(self.check(source=SOURCE[:start] + mutated + SOURCE[end:])[0],1) + def test_frozen_instruction_live_payloads_and_role_cannot_escape(self): + for fold in ["f.i(static_cast(o.pine_frozen_market_instruction.kind()));", + "f.d(transaction->own_units);", "f.d(transaction->transaction_units);", + "f.s(close->target_id);"]: + for replacement in ["", "// " + fold, "if (false) " + fold, + fold.replace("f.", "other.")]: + with self.subTest(fold=fold, replacement=replacement): + self.assertIn(fold, SOURCE) + self.assertEqual(self.check(source=SOURCE.replace(fold, replacement))[0], 1) + self.assertEqual(self.check(source=SOURCE.replace(fold, "") + "\n" + fold)[0], 1) + self.assertEqual(self.check(waivers=WAIVERS + + "\npending_order.pine_frozen_market_instruction # attempted omission\n")[0], 1) + + def test_frozen_instruction_new_fields_and_alternatives_fail_closed(self): + for old, new in [ + ("double own_units;", "double own_units; double hidden;"), + ("std::string target_id;", "std::string target_id; uint64_t hidden;"), + ("Value value_;", "Value value_; bool hidden_;"), + ("std::monostate, Transaction, TargetedClose", "std::monostate, TargetedClose, Transaction"), + ("Ordinary, Transaction, TargetedClose", "Ordinary, Transaction, TargetedClose, Extra"), + ]: + with self.subTest(old=old): + self.assertIn(old, FROZEN) + self.assertEqual(self.check(frozen=FROZEN.replace(old, new))[0], 1) + def test_exit_activation_has_complete_unconditional_coverage(self): for fold in ["f.b(o.leg_activation.bounds().has_value());", "f.i(bounds->position_cycle);", "f.i(bounds->stop_first_bar);", "f.i(bounds->limit_first_bar);", @@ -99,26 +171,26 @@ def test_quantity_model_additions_and_variant_drift_fail_closed(self): self.assertIn(old, QUANTITY) self.assertEqual(self.check(quantity=QUANTITY.replace(old, new))[0], 1) - def test_layout_and_hash_versions_must_match_v6_contract(self): - self.assertIn("engine_script_run_v6", HEADER) - self.assertIn('f.s("pineforge-broker-state/v6");', SOURCE) - self.assertIn("integer(6); integer(broker_state_hash());", STREAM) - self.assertEqual(self.check(header=HEADER.replace("engine_script_run_v6", "engine_script_run_v2"))[0], 1) + def test_layout_and_hash_versions_must_match_v7_contract(self): + self.assertIn("engine_script_run_v7", HEADER) + self.assertIn('f.s("pineforge-broker-state/v7");', SOURCE) + self.assertIn("integer(7); integer(broker_state_hash());", STREAM) + self.assertEqual(self.check(header=HEADER.replace("engine_script_run_v7", "engine_script_run_v2"))[0], 1) for replacement in ['f.s("pineforge-broker-state/v2");', '', - '// f.s("pineforge-broker-state/v6");']: + '// f.s("pineforge-broker-state/v7");']: self.assertEqual(self.check(source=SOURCE.replace( - 'f.s("pineforge-broker-state/v6");', replacement))[0], 1) + 'f.s("pineforge-broker-state/v7");', replacement))[0], 1) for replacement in ["integer(2); integer(broker_state_hash());", "integer(broker_state_hash());", - "if (false) { integer(6); integer(broker_state_hash()); }"]: + "if (false) { integer(7); integer(broker_state_hash()); }"]: self.assertEqual(self.check(stream=STREAM.replace( - "integer(6); integer(broker_state_hash());", replacement))[0], 1) + "integer(7); integer(broker_state_hash());", replacement))[0], 1) def test_version_folds_in_unrelated_helpers_do_not_cover_entry_points(self): - broker_fold = 'f.s("pineforge-broker-state/v6");' + broker_fold = 'f.s("pineforge-broker-state/v7");' altered = SOURCE.replace(broker_fold, '') + '\nvoid other() { ' + broker_fold + ' }\n' self.assertEqual(self.check(source=altered)[0], 1) - stream_fold = "integer(6); integer(broker_state_hash());" + stream_fold = "integer(7); integer(broker_state_hash());" altered = STREAM.replace(stream_fold, '') + '\nvoid other() { ' + stream_fold + ' }\n' self.assertEqual(self.check(stream=altered)[0], 1) diff --git a/scripts/test_reservation_expansion_mirror.py b/scripts/test_reservation_expansion_mirror.py new file mode 100644 index 0000000..08a2c5a --- /dev/null +++ b/scripts/test_reservation_expansion_mirror.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +"""Metadata-only mutations of the exact nested reservation mirror contract.""" +from contextlib import redirect_stderr, redirect_stdout +from io import StringIO +from pathlib import Path +import tempfile +import unittest +from unittest.mock import patch +import gen_pending_order_mirror as mirror + +ROOT = Path(__file__).resolve().parents[1] +HEADER = (ROOT / 'include/pineforge/reservation_expansion.hpp').read_text() + +class ReservationMirror(unittest.TestCase): + def test_complete_schema_and_generated_output(self): + header, source = mirror.generate() + self.assertEqual(header, mirror.OUT_H.read_text()) + self.assertEqual(source, mirror.OUT_C.read_text()) + self.assertIn('155 POD fields', header) + + def test_every_nested_mapping_is_observable(self): + original = mirror.generate() + for typename in ['ReservationExpansion', 'ReservationGrowthSource']: + values = mirror.COMPOSITE_MAP[typename] + for index, (name, kind, expression) in enumerate(values): + for mutation in ['omit', 'name', 'type', 'value']: + with self.subTest(typename=typename, field=name, mutation=mutation): + changed = values.copy() + if mutation == 'omit': del changed[index] + if mutation == 'name': changed[index] = ('wrong_' + name, kind, expression) + if mutation == 'type': changed[index] = (name, 'double' if kind != 'double' else 'int64_t', expression) + if mutation == 'value': changed[index] = (name, kind, '0') + with patch.dict(mirror.COMPOSITE_MAP, {typename:changed}): + self.assertNotEqual(mirror.generate(), original) + with redirect_stdout(StringIO()): self.assertEqual(mirror.main(['--check']), 1) + + def test_legacy_projection_mutations_are_observable(self): + for field in ['pooc_global_full_exit_dynamic_qty', 'pooc_global_full_exit_tracks_bound_adds', 'pooc_global_full_exit_bound_add']: + with self.subTest(field=field), patch.dict(mirror.LEGACY_OUTPUTS, {field:'0'}), redirect_stdout(StringIO()): + self.assertEqual(mirror.main(['--check']),1) + + def test_nested_storage_growth_fails_generation(self): + for declaration in ['std::optional capture_;', + 'int64_t position_cycle;', 'PositionSide side;', + 'std::optional first_later_admission;', + 'std::optional reservation_owner_;']: + with self.subTest(declaration=declaration), tempfile.TemporaryDirectory() as temp: + root = Path(temp) + path = root / 'include/pineforge/reservation_expansion.hpp' + path.parent.mkdir(parents=True) + path.write_text(HEADER.replace(declaration,declaration + ' int hidden;')) + with patch.object(mirror,'ROOT',root), self.assertRaises(ValueError): mirror.generate() + + def test_receipts_cannot_be_waived(self): + for field in ['reservation_expansion','reservation_growth_source']: + with self.subTest(field=field), self.assertRaises(SystemExit), redirect_stderr(StringIO()): + mirror.classify(mirror.members(),{field:'forbidden'}) + +if __name__ == '__main__': unittest.main() diff --git a/src/compat/pine/reservation_expansion.cpp b/src/compat/pine/reservation_expansion.cpp new file mode 100644 index 0000000..0a6cdea --- /dev/null +++ b/src/compat/pine/reservation_expansion.cpp @@ -0,0 +1,28 @@ +#include +#include +#include "../../engine_internal.hpp" + +namespace pineforge::compat::pine { +std::vector select_reservation_growth_sources(const std::vector& book, + const std::string& from_entry, bool process_on_close, bool effectively_flat, + double percent, int bar, PositionSide side) { + if (!from_entry.empty() || !process_on_close || effectively_flat + || percent < 100.0 - internal::kFullPercentEps) return {}; + std::vector selected; + for (const auto& source : book) { + if (source.type != OrderType::MARKET && source.type != OrderType::ENTRY + && source.type != OrderType::RAW_ORDER) continue; + const auto requested = source.is_long ? PositionSide::LONG : PositionSide::SHORT; + if (source.created_bar != bar || source.type != OrderType::MARKET + || source.birth.from_fill() || source.over_pyramiding_cap_at_placement + || requested != side || source.created_position_side != side) return {}; + selected.push_back(source.incarnation); + } + return selected; +} +bool admits_reservation_expansion(const std::vector& selected, + bool partial, double reserved, double live) { + return !selected.empty() && !partial && std::isfinite(reserved) + && reserved >= live - internal::kFullQtyEps; +} +} // namespace pineforge::compat::pine diff --git a/src/engine_fills.cpp b/src/engine_fills.cpp index eb5db22..88959e1 100644 --- a/src/engine_fills.cpp +++ b/src/engine_fills.cpp @@ -177,13 +177,14 @@ bool internal::dual_stop_margin_decline_can_continue_path( // resting priced order, a strategy.exit bracket, a close_all, a third entry, // a same-id pair) is outside the tapes; strip the membership so every order // takes its established kernel, byte-identical to the pre-famS engine. -void BacktestEngine::finalize_same_bar_market_tx_book() { +void compat::pine::finalize_frozen_market_book( + std::vector& orders, bool source_scope_live) { bool any_member = false; bool exact = true; int market_members = 0; std::string first_market_id; - for (const PendingOrder& order : pending_orders_) { - if (!order.sbmt_member) { + for (const PendingOrder& order : orders) { + if (!order.pine_frozen_market_instruction.active()) { exact = false; continue; } @@ -197,17 +198,17 @@ void BacktestEngine::finalize_same_bar_market_tx_book() { } } } - if (!any_member || (exact && same_bar_market_tx_scope_is_live())) return; - for (PendingOrder& order : pending_orders_) { - order.sbmt_member = false; - order.sbmt_own_qty = std::numeric_limits::quiet_NaN(); - order.sbmt_tx_qty = std::numeric_limits::quiet_NaN(); - order.sbmt_kept_over_cap = false; - order.sbmt_close_qty = std::numeric_limits::quiet_NaN(); - order.sbmt_close_buy = false; + if (!any_member || (exact && source_scope_live)) return; + for (PendingOrder& order : orders) { + order.pine_frozen_market_instruction.revoke(); } } +void BacktestEngine::finalize_same_bar_market_tx_book() { + compat::pine::finalize_frozen_market_book( + pending_orders_, same_bar_market_tx_scope_is_live()); +} + // A carried long can owe the broker's one-contract money-rounding trim at // the OPEN before its resting take-profit/stop is reached later on the path. // The full-bar exit pass used to erase that position first. Covered controls @@ -3932,8 +3933,7 @@ void BacktestEngine::sort_orders_by_fill_phase(const Bar& bar) { && std::isnan(order.trail_offset) && std::isnan(order.profit_ticks) && std::isnan(order.loss_ticks) - && !order.pooc_global_full_exit_dynamic_qty - && !order.pooc_global_full_exit_tracks_bound_adds + && !order.reservation_expansion.capture() && !order.suppress_as_declined_reversal_close && std::isfinite(order.suppressed_close_consumed_ledger_qty) && order.suppressed_close_consumed_ledger_qty > kQtyEpsilon; @@ -4165,9 +4165,9 @@ void BacktestEngine::sort_orders_by_fill_phase(const Bar& bar) { // rank with the buys; the key is a pure function of the order. if (pa == 0) { auto sbmt_sell_rank = [](const PendingOrder& o) { - if (!o.sbmt_member) return 0; + if (!o.pine_frozen_market_instruction.active()) return 0; const bool buy = o.type == OrderType::MARKET - ? o.is_long : o.sbmt_close_buy; + ? o.is_long : (o.created_position_side == PositionSide::SHORT); return buy ? 0 : 1; }; const int ra = sbmt_sell_rank(a); @@ -4494,10 +4494,10 @@ bool BacktestEngine::same_bar_market_tx_scope_is_live() const { // close is cancelled (rev-plus-close, dbl-short-swapped: no artifact row). bool BacktestEngine::same_bar_market_close_artifact_is_live( const PendingOrder& order) const { - if (!order.sbmt_member + if (!order.pine_frozen_market_instruction.targeted_close() || order.type != OrderType::EXIT - || !std::isfinite(order.sbmt_close_qty) - || order.sbmt_close_qty <= kQtyEpsilon + || !std::isfinite(order.quantity_request.intent()->units()) + || order.quantity_request.intent()->units() <= kQtyEpsilon || order.created_bar + 1 != bar_index_ || order.suppress_as_declined_reversal_close || position_side_ == PositionSide::FLAT @@ -4505,13 +4505,14 @@ bool BacktestEngine::same_bar_market_close_artifact_is_live( return false; } const PositionSide target_side = - order.sbmt_close_buy ? PositionSide::SHORT : PositionSide::LONG; + order.created_position_side; if (position_side_ == target_side) return false; if (order.id.size() <= kClosePrefix.size() || order.id.compare(0, kClosePrefix.size(), kClosePrefix) != 0) { return false; } - const std::string target_id = order.id.substr(kClosePrefix.size()); + const std::string& target_id = order.pine_frozen_market_instruction.targeted_close()->target_id; + if (order.id.substr(kClosePrefix.size()) != target_id) return false; const auto live = std::find_if(pending_orders_.begin(), pending_orders_.end(), [&](const PendingOrder& pending) { return same_pending_order(pending, order); }); if (live == pending_orders_.end()) return false; @@ -4519,10 +4520,10 @@ bool BacktestEngine::same_bar_market_close_artifact_is_live( for (size_t j = self + 1; j < pending_orders_.size(); ++j) { const PendingOrder& sib = pending_orders_[j]; if (sib.type == OrderType::MARKET - && sib.sbmt_member + && sib.pine_frozen_market_instruction.transaction() && sib.id == target_id && sib.created_bar == order.created_bar - && sib.is_long != order.sbmt_close_buy) { + && sib.is_long != (order.created_position_side == PositionSide::SHORT)) { return true; } } @@ -4541,7 +4542,7 @@ void BacktestEngine::apply_same_bar_market_tx_reversal( double& trail_best_path_state) { const PositionSide requested = order.is_long ? PositionSide::LONG : PositionSide::SHORT; - const double tx = order.sbmt_tx_qty; + const double tx = order.pine_frozen_market_instruction.transaction()->transaction_units; const double close_qty = std::min(tx, position_qty_); if (close_qty >= position_qty_ - kQtyEpsilon) { execute_market_exit(fill_price); @@ -4798,7 +4799,8 @@ void BacktestEngine::compact_filled_pending_orders( && pending_orders_[read].created_position_side == closed_side && !resting_limit_entry_carry // round 8 family S, rule 2 (lockstep with classify_order_eligibility). - && !pending_orders_[read].sbmt_kept_over_cap; + && !(pending_orders_[read].pine_frozen_market_instruction.transaction() + && pending_orders_[read].over_pyramiding_cap_at_placement); if (!is_filled(pending_orders_[read].incarnation) && !stale_same_direction_entry_after_exit) { if (write != read) pending_orders_[write] = std::move(pending_orders_[read]); @@ -4944,24 +4946,24 @@ int BacktestEngine::probe_fill_qty(int index, double fill_price, double* qty, *partition = 1; kernel_close_only = !(residual > kQtyEpsilon); sized = true; - } else if (o.type == OrderType::MARKET && o.sbmt_member - && std::isfinite(o.sbmt_tx_qty) && o.sbmt_tx_qty > kQtyEpsilon + } else if (o.type == OrderType::MARKET && o.pine_frozen_market_instruction.transaction() + && std::isfinite(o.pine_frozen_market_instruction.transaction()->transaction_units) && o.pine_frozen_market_instruction.transaction()->transaction_units > kQtyEpsilon && same_bar_market_tx_scope_is_live()) { if (opposite_live_position) { - const double close_qty = std::min(o.sbmt_tx_qty, position_qty_); - const double remainder = o.sbmt_tx_qty - close_qty; + const double close_qty = std::min(o.pine_frozen_market_instruction.transaction()->transaction_units, position_qty_); + const double remainder = o.pine_frozen_market_instruction.transaction()->transaction_units - close_qty; *qty = remainder; *partition = 1; kernel_close_only = !(remainder > kQtyEpsilon); sized = true; - } else if (position_side_ == requested_side && o.sbmt_kept_over_cap) { - *qty = o.sbmt_tx_qty; + } else if (position_side_ == requested_side && o.over_pyramiding_cap_at_placement) { + *qty = o.pine_frozen_market_instruction.transaction()->transaction_units; *partition = 1; sized = true; } else if (position_side_ == PositionSide::FLAT - && std::isfinite(o.sbmt_own_qty) - && o.sbmt_tx_qty > o.sbmt_own_qty + kQtyEpsilon) { - *qty = o.sbmt_tx_qty; + && std::isfinite(o.pine_frozen_market_instruction.transaction()->own_units) + && o.pine_frozen_market_instruction.transaction()->transaction_units > o.pine_frozen_market_instruction.transaction()->own_units + kQtyEpsilon) { + *qty = o.pine_frozen_market_instruction.transaction()->transaction_units; *partition = 1; sized = true; } @@ -5265,6 +5267,10 @@ void BacktestEngine::apply_filled_order_to_state( bool admitted_flat_on_price_gap_band = false; { PendingOrder& order = pending_orders_.at(order_index); + // A deferred-compaction object is not actionable twice. The owned copy + // of this dispatch may still settle after scheduling its own retirement. + if (std::find(retired_incarnations.begin(), retired_incarnations.end(), order.incarnation) + != retired_incarnations.end()) return; cap_origin = max_intraday_filled_orders_.origin( pine_cap_clock(), pine_cap_calculation(), order.incarnation, broker_fill_event_seq_); auto decline_and_cancel = [&]() { @@ -5351,7 +5357,7 @@ void BacktestEngine::apply_filled_order_to_state( && std::isnan(order.qty) && default_qty_type_ == QtyType::FIXED && position_side_ != PositionSide::FLAT - && !order.sbmt_member) { + && !order.pine_frozen_market_instruction.active()) { const PositionSide requested = order.is_long ? PositionSide::LONG : PositionSide::SHORT; const bool same_side_at_creation = @@ -5768,7 +5774,7 @@ void BacktestEngine::apply_filled_order_to_state( return true; }; if (order.type == OrderType::MARKET && std::isnan(order.qty) - && !order.affordability_close_only && !order.sbmt_member + && !order.affordability_close_only && !order.pine_frozen_market_instruction.active() && position_side_ == PositionSide::FLAT && (order.created_position_side == PositionSide::FLAT || order.created_after_position_close_in_bar) @@ -6185,9 +6191,11 @@ void BacktestEngine::apply_filled_order_to_state( // FIXED/no-fee orders carry the transaction marker even // when no sibling exists. Exclude an expanded transaction, // not an otherwise-unused default sizing declaration. - && (!order.sbmt_member - || (order.sbmt_tx_qty == order.sbmt_own_qty - && !order.sbmt_kept_over_cap)) + && (!order.pine_frozen_market_instruction.active() + || (order.pine_frozen_market_instruction.transaction() + && order.pine_frozen_market_instruction.transaction()->transaction_units + == order.pine_frozen_market_instruction.transaction()->own_units + && !order.over_pyramiding_cap_at_placement)) && order.created_bar == bar_index_ - 1 && order.oca_type == 0 && order.oca_name.empty() && pending_orders_.size() == 1 @@ -6305,6 +6313,7 @@ void BacktestEngine::apply_filled_order_to_state( if (position_side_ == PositionSide::SHORT) return -position_qty_; return 0.0; }; + const int64_t position_cycle_before_fill = position_cycle_seq_; const PositionSide position_side_before_fill = position_side_; const double position_qty_before_fill = position_qty_; const size_t pyramid_lots_before_fill = pyramid_entries_.size(); @@ -6450,33 +6459,23 @@ void BacktestEngine::apply_filled_order_to_state( primary_fill_applied ? compat::pine::FillOutcome::Committed : compat::pine::FillOutcome::NoEffect, cap_origin); - // Bounded POOC global-exit growth. Only MARKET adds that were already - // pending when the one tracking EXIT was armed carry this relation bit. - // Grow its ordinary finite reservation by the actual same-side quantity - // delta—not requested qty—so fill-time rejection, zero-fill, reversal, or - // flat-open role changes add nothing. The tracking bit intentionally - // survives dynamic-marker invalidation: a post-exit order can be admitted - // before this pre-exit add reaches the POOC close fill point. - if (order.type == OrderType::MARKET - && order.pooc_global_full_exit_bound_add) { - const PositionSide requested_side = order.is_long - ? PositionSide::LONG : PositionSide::SHORT; - const bool successful_same_side_add = - requested_side == order.created_position_side - && position_side_before_fill == requested_side - && position_side_ == requested_side - && position_qty_ > position_qty_before_fill + kQtyEpsilon; - if (successful_same_side_add) { - const double added_qty = - position_qty_ - position_qty_before_fill; - for (auto& candidate : pending_orders_) { - if (candidate.type != OrderType::EXIT - || !candidate.pooc_global_full_exit_tracks_bound_adds - || !std::isfinite(candidate.qty)) { - continue; - } - candidate.qty += added_qty; - break; // reservation accounting admits at most one tracker + // Settle at the existing post-primary checkpoint, before OCA/risk. Source + // receipts are the only edges; historical dead-owner receipts never fall + // back to another EXIT, even when labels or queue priority match. + if (order.type == OrderType::MARKET && order.reservation_growth_source.reservation_owner()) { + const PositionSide requested = order.is_long ? PositionSide::LONG : PositionSide::SHORT; + const uint64_t receiver = *order.reservation_growth_source.reservation_owner(); + if (requested == order.created_position_side && position_side_before_fill == requested + && position_side_ == requested + && std::find(retired_incarnations.begin(), retired_incarnations.end(), receiver) + == retired_incarnations.end()) { + for (auto& target : pending_orders_) { + if (target.incarnation != receiver) continue; + if (target.type == OrderType::EXIT) + target.reservation_expansion.grow(target.qty, + position_cycle_before_fill, position_side_before_fill, position_qty_before_fill, + position_cycle_seq_, position_side_, position_qty_, kQtyEpsilon); + break; } } } @@ -6925,7 +6924,7 @@ bool BacktestEngine::replaced_percent_short_market_is_live( || (order.replaced_order_incarnation == 0) || order.replaced_default_market_incarnation == 0 || !std::isnan(order.qty) || order.qty_type >= 0 - || order.affordability_close_only || order.sbmt_member + || order.affordability_close_only || order.pine_frozen_market_instruction.active() || order.created_bar != bar_index_ - 1 || order.birth.from_fill() || order.created_after_position_close_in_bar @@ -6980,7 +6979,7 @@ bool BacktestEngine::replaced_percent_short_market_is_live( || other.created_after_position_close_in_bar || !std::isnan(other.qty) || other.qty_type >= 0 || other.frozen_default_qty != order.frozen_default_qty - || other.affordability_close_only || other.sbmt_member + || other.affordability_close_only || other.pine_frozen_market_instruction.active() || !other.oca_name.empty() || other.oca_type != 0) return false; } return true; @@ -7089,8 +7088,8 @@ void BacktestEngine::apply_market_order_fill(PendingOrder& order, double fill_pr // the frozen size. The ordinary single-entry shapes (tx == own) below // stay byte-identical. bool sbmt_flat_frozen_tx = false; - if (order.sbmt_member && std::isfinite(order.sbmt_tx_qty) - && order.sbmt_tx_qty > kQtyEpsilon + if (order.pine_frozen_market_instruction.transaction() && std::isfinite(order.pine_frozen_market_instruction.transaction()->transaction_units) + && order.pine_frozen_market_instruction.transaction()->transaction_units > kQtyEpsilon && same_bar_market_tx_scope_is_live()) { const PositionSide requested = order.is_long ? PositionSide::LONG : PositionSide::SHORT; @@ -7100,11 +7099,11 @@ void BacktestEngine::apply_market_order_fill(PendingOrder& order, double fill_pr trail_best_path_state); return; } - if (position_side_ == requested && order.sbmt_kept_over_cap) { + if (position_side_ == requested && order.over_pyramiding_cap_at_placement) { // dbl-long-mirror-closefirst: the kept Long buys its frozen 2 // while still long (long 3) before the Short and close-Long // sell — an add past the pyramiding cap, never a rejected add. - const double add_qty = order.sbmt_tx_qty; + const double add_qty = order.pine_frozen_market_instruction.transaction()->transaction_units; const double entry_fill = apply_fill_slippage(fill_price, order.is_long); if (std::isfinite(entry_fill) && add_qty > kQtyEpsilon) { @@ -7141,8 +7140,8 @@ void BacktestEngine::apply_market_order_fill(PendingOrder& order, double fill_pr } sbmt_flat_frozen_tx = position_side_ == PositionSide::FLAT - && std::isfinite(order.sbmt_own_qty) - && order.sbmt_tx_qty > order.sbmt_own_qty + kQtyEpsilon; + && std::isfinite(order.pine_frozen_market_instruction.transaction()->own_units) + && order.pine_frozen_market_instruction.transaction()->transaction_units > order.pine_frozen_market_instruction.transaction()->own_units + kQtyEpsilon; } // A default-sized market order carries a quantity frozen at the signal @@ -7181,7 +7180,7 @@ void BacktestEngine::apply_market_order_fill(PendingOrder& order, double fill_pr const double dispatch_qty = paired_flat_market ? order.paired_flat_market_transaction_qty : (sbmt_flat_frozen_tx - ? order.sbmt_tx_qty + ? order.pine_frozen_market_instruction.transaction()->transaction_units : (frozen ? order.frozen_default_qty : order.qty)); const int dispatch_qty_type = paired_flat_market ? -1 @@ -7471,16 +7470,16 @@ void BacktestEngine::apply_exit_order_fill(PendingOrder& order, double fill_pric // position, exactly the short-seed kernel's min(S, L) above. bool sbmt_frozen_close = false; double sbmt_frozen_close_qty = std::numeric_limits::quiet_NaN(); - if (order.sbmt_member && std::isfinite(order.sbmt_close_qty) - && order.sbmt_close_qty > kQtyEpsilon + if (order.pine_frozen_market_instruction.targeted_close() && std::isfinite(order.quantity_request.intent()->units()) + && order.quantity_request.intent()->units() > kQtyEpsilon && same_bar_market_tx_scope_is_live()) { const PositionSide target_side = - order.sbmt_close_buy ? PositionSide::SHORT : PositionSide::LONG; + order.created_position_side; if (position_side_ != target_side) { if (!same_bar_market_close_artifact_is_live(order)) return; - const double qty = std::min(order.sbmt_close_qty, position_qty_); + const double qty = std::min(order.quantity_request.intent()->units(), position_qty_); const double entry_fill = - apply_fill_slippage(fill_price, /*is_buy=*/order.sbmt_close_buy); + apply_fill_slippage(fill_price, /*is_buy=*/(order.created_position_side == PositionSide::SHORT)); if (!std::isfinite(entry_fill) || qty <= kQtyEpsilon) return; const double total_qty = position_qty_ + qty; position_entry_price_ = @@ -7505,12 +7504,12 @@ void BacktestEngine::apply_exit_order_fill(PendingOrder& order, double fill_pric return; } sbmt_frozen_close = true; - sbmt_frozen_close_qty = std::min(order.sbmt_close_qty, position_qty_); + sbmt_frozen_close_qty = std::min(order.quantity_request.intent()->units(), position_qty_); } double qp = std::isnan(order.qty_percent) ? 100.0 : std::clamp(order.qty_percent, 0.0, 100.0); const bool dynamic_full_live_qty = - order.pooc_global_full_exit_dynamic_qty; + order.reservation_expansion.live_all(position_cycle_seq_, position_side_); bool has_explicit_qty_to_close = !dynamic_full_live_qty && !std::isnan(order.qty); double qty_before_exit = position_qty_; @@ -8345,7 +8344,8 @@ BacktestEngine::OrderEligibility BacktestEngine::classify_order_eligibility( && !resting_limit_entry_carry && !coqueued_within_cap && !same_id_stop_preserved_by_deferred_close_all - && !order.sbmt_kept_over_cap) { + && !(order.pine_frozen_market_instruction.transaction() + && order.over_pyramiding_cap_at_placement)) { return OrderEligibility::Remove; } diff --git a/src/engine_state_hash.cpp b/src/engine_state_hash.cpp index 704892e..36c858c 100644 --- a/src/engine_state_hash.cpp +++ b/src/engine_state_hash.cpp @@ -88,7 +88,7 @@ uint64_t BacktestEngine::broker_state_hash() const { Fnv f; // v6 includes resolved exit-leg owner/coordinates and immutable Pine placement evidence. // It is a serialization boundary, independent of the public C ABI version. - f.s("pineforge-broker-state/v6"); + f.s("pineforge-broker-state/v7"); // --- Position core --- f.i(static_cast(position_side_)); @@ -211,8 +211,13 @@ uint64_t BacktestEngine::broker_state_hash() const { f.u(o.signal_close_mc_fill_seq); // Round-8 family S same-bar MARKET transaction (sizing frozen at // placement) and its strategy.close(id) companion. - f.b(o.sbmt_member); f.d(o.sbmt_own_qty); f.d(o.sbmt_tx_qty); - f.b(o.sbmt_kept_over_cap); f.d(o.sbmt_close_qty); f.b(o.sbmt_close_buy); + f.i(static_cast(o.pine_frozen_market_instruction.kind())); + if (const auto* transaction = o.pine_frozen_market_instruction.transaction()) { + f.d(transaction->own_units); f.d(transaction->transaction_units); + } + if (const auto* close = o.pine_frozen_market_instruction.targeted_close()) { + f.s(close->target_id); + } // KI-65 dual same-bar opposite-MARKET pairing candidate/finalization. f.b(o.paired_flat_market_candidate); f.d(o.paired_flat_market_own_qty); @@ -291,10 +296,19 @@ uint64_t BacktestEngine::broker_state_hash() const { f.d(o.explicit_slipped_signal_close); // Round-7 default-percent stop placement basis. f.d(o.default_stop_placement_signal_close); - // POOC global-full-exit relation bits. - f.b(o.pooc_global_full_exit_dynamic_qty); - f.b(o.pooc_global_full_exit_tracks_bound_adds); - f.b(o.pooc_global_full_exit_bound_add); + f.b(o.reservation_expansion.capture().has_value()); + if (const auto& capture = o.reservation_expansion.capture()) { + f.i(capture->position_cycle); + f.i(static_cast(capture->side)); + f.b(capture->first_later_admission.has_value()); + if (const auto& admission = capture->first_later_admission) { + f.u(*admission); + } + } + f.b(o.reservation_growth_source.reservation_owner().has_value()); + if (const auto& receiver = o.reservation_growth_source.reservation_owner()) { + f.u(*receiver); + } // Suppressed-close ledger re-credit amounts. f.d(o.suppressed_close_consumed_ledger_qty); f.d(o.suppressed_close_retired_ledger_qty); diff --git a/src/engine_strategy_commands.cpp b/src/engine_strategy_commands.cpp index 5a0fd56..abdc48b 100644 --- a/src/engine_strategy_commands.cpp +++ b/src/engine_strategy_commands.cpp @@ -25,6 +25,7 @@ #include "engine_internal.hpp" #include +#include #include #include @@ -330,10 +331,10 @@ void BacktestEngine::strategy_entry(const std::string& id, bool is_long, || sib.id == id) { continue; } - if (sib.type == OrderType::MARKET && sib.sbmt_member - && std::isfinite(sib.sbmt_own_qty)) { + if (sib.type == OrderType::MARKET && sib.pine_frozen_market_instruction.transaction() + && std::isfinite(sib.pine_frozen_market_instruction.transaction()->own_units)) { sbmt_opp_market_pending = true; - sbmt_opp_pending_own += sib.sbmt_own_qty; + sbmt_opp_pending_own += sib.pine_frozen_market_instruction.transaction()->own_units; } else if (sib.type == OrderType::MARKET || sib.type == OrderType::ENTRY || sib.type == OrderType::RAW_ORDER) { @@ -651,11 +652,8 @@ void BacktestEngine::strategy_entry(const std::string& id, bool is_long, const double held_opposite = opposite_live ? std::max(0.0, position_qty_ - pending_close_qty_in_bar_) : 0.0; - order.sbmt_member = true; - order.sbmt_own_qty = sbmt_own_qty; - order.sbmt_tx_qty = - sbmt_own_qty + held_opposite + sbmt_opp_pending_own; - order.sbmt_kept_over_cap = sbmt_over_cap; + order.pine_frozen_market_instruction = PineFrozenMarketInstruction::transaction( + sbmt_own_qty, sbmt_own_qty + held_opposite + sbmt_opp_pending_own); } if (paired_flat_market_candidate) { order.paired_flat_market_candidate = true; @@ -838,7 +836,7 @@ void BacktestEngine::strategy_entry(const std::string& id, bool is_long, } pending_orders_.push_back(std::move(order)); - invalidate_unsafe_pooc_global_full_exit_dynamic_qty(); + close_reservation_capture_populations(pending_orders_.back().incarnation); } void BacktestEngine::strategy_close(const std::string& id, @@ -1867,8 +1865,8 @@ void BacktestEngine::strategy_exit(const std::string& id, const std::string& fro &replaced_dormant, &replaced_dormant_stop); double reserved_qty = std::numeric_limits::quiet_NaN(); - bool bind_global_full_exit_dynamic_qty = false; - std::vector pooc_global_full_exit_bound_add_indices; + bool capture_expansion = false; + std::vector selected_reservation_sources; // Additional bracket legs beyond the primary one (see the leg-multiplicity // block in the explicit-qty branch below). Empty on every other path. std::vector extra_leg_qtys; @@ -2069,39 +2067,10 @@ void BacktestEngine::strategy_exit(const std::string& id, const std::string& fro // separate branch, while from_entry, partial, RAW_ORDER, priced, // opposite, prior-bar, COOF-recalc, over-cap, and mixed-queue shapes // retain the established frozen reservation. - bool eligible_global_full_exit_dynamic_qty = false; - if (from_entry.empty() - && process_orders_on_close_ - && !effectively_flat - && qp >= 100.0 - kFullPercentEps) { - bool found_qualifying_add = false; - bool entry_queue_is_bounded = true; - for (std::size_t i = 0; i < pending_orders_.size(); ++i) { - const PendingOrder& o = pending_orders_[i]; - if (o.type != OrderType::MARKET - && o.type != OrderType::ENTRY - && o.type != OrderType::RAW_ORDER) { - continue; - } - const PositionSide entry_dir = o.is_long - ? PositionSide::LONG : PositionSide::SHORT; - const bool qualifies = o.created_bar == bar_index_ - && o.type == OrderType::MARKET - && !o.birth.from_fill() - && !o.over_pyramiding_cap_at_placement - && entry_dir == position_side_ - && o.created_position_side == position_side_; - if (!qualifies) { - entry_queue_is_bounded = false; - break; - } - found_qualifying_add = true; - pooc_global_full_exit_bound_add_indices.push_back(i); - } - eligible_global_full_exit_dynamic_qty = - found_qualifying_add - && entry_queue_is_bounded; - } + selected_reservation_sources = compat::pine::select_reservation_growth_sources( + pending_orders_, from_entry, process_orders_on_close_, effectively_flat, + qp, bar_index_, position_side_); + bool eligible_expansion = !selected_reservation_sources.empty(); if (!bind_to_pending_reversal_entry) { if (!compute_exit_reserved_qty( @@ -2109,16 +2078,12 @@ void BacktestEngine::strategy_exit(const std::string& id, const std::string& fro qp, is_partial, reserved_qty)) { return; } - eligible_global_full_exit_dynamic_qty = - eligible_global_full_exit_dynamic_qty - && !is_partial - && std::isfinite(reserved_qty) - && reserved_qty >= live_pos_qty - kFullQtyEps; + eligible_expansion = compat::pine::admits_reservation_expansion( + selected_reservation_sources, is_partial, reserved_qty, live_pos_qty); } // The pending order stores this below after the common construction. - bind_global_full_exit_dynamic_qty = - eligible_global_full_exit_dynamic_qty; + capture_expansion = eligible_expansion; } PendingOrder order; @@ -2144,15 +2109,6 @@ void BacktestEngine::strategy_exit(const std::string& id, const std::string& fro // requests retain their original fraction until a live owner binds them. if (has_explicit_qty || std::isfinite(reserved_qty)) order.quantity_request.reserve(reserved_qty, live_pos_qty); - order.pooc_global_full_exit_dynamic_qty = - bind_global_full_exit_dynamic_qty; - order.pooc_global_full_exit_tracks_bound_adds = - bind_global_full_exit_dynamic_qty; - if (bind_global_full_exit_dynamic_qty) { - for (std::size_t index : pooc_global_full_exit_bound_add_indices) { - pending_orders_[index].pooc_global_full_exit_bound_add = true; - } - } // OCA-name plumbing: ``strategy.exit`` supports oca_name (Pine v6) so // siblings in different OCA groups can fire independently. The cancel // sweep predicate (engine_fills.cpp::apply_filled_order_to_state → @@ -2242,7 +2198,20 @@ void BacktestEngine::strategy_exit(const std::string& id, const std::string& fro } if (extra_leg_qtys.empty()) { + if (capture_expansion) + order.reservation_expansion.capture(order.incarnation, position_cycle_seq_, + position_side_, order.qty); + const uint64_t receiver = order.incarnation; pending_orders_.push_back(std::move(order)); + // Publication succeeded; selected identities survive vector reallocation. + // A new legitimate capture explicitly reassigns each authoritative edge. + if (capture_expansion) { + for (auto& source : pending_orders_) { + if (std::find(selected_reservation_sources.begin(), selected_reservation_sources.end(), + source.incarnation) != selected_reservation_sources.end()) + source.reservation_growth_source.assign_capture(source.incarnation, receiver); + } + } return; } @@ -2473,21 +2442,15 @@ void BacktestEngine::strategy_order(const std::string& id, bool is_long, double } pending_orders_.push_back(std::move(order)); - invalidate_unsafe_pooc_global_full_exit_dynamic_qty(); + close_reservation_capture_populations(pending_orders_.back().incarnation); } -void BacktestEngine::invalidate_unsafe_pooc_global_full_exit_dynamic_qty() { - // This helper is called only after a later entry-like placement was - // successfully admitted. The oracle covers adds already pending BEFORE - // the global exit, not any order emitted after it—even another same-side - // MARKET add. Clear every still-live marker, including candidates carried - // into a later bar; their finite ``qty`` remains the conservative - // reservation automatically. - for (auto& o : pending_orders_) { - if (o.type == OrderType::EXIT) { - o.pooc_global_full_exit_dynamic_qty = false; - } - } +void BacktestEngine::close_reservation_capture_populations(uint64_t admitted_incarnation) { + // Called only after an ENTRY/MARKET/RAW admission has actually appended. + // Queue priority can be retained on replacement; this cause cannot. + for (auto& order : pending_orders_) + if (order.type == OrderType::EXIT) + order.reservation_expansion.close_population(admitted_incarnation); } // ──────────────────────────────────────────────────────────────────── @@ -2869,9 +2832,8 @@ uint64_t BacktestEngine::queue_deferred_close_order( && std::isfinite(consumed_ledger_qty) && qty_to_close > eps && position_side_ != PositionSide::FLAT) { - order.sbmt_member = true; - order.sbmt_close_qty = qty_to_close; - order.sbmt_close_buy = position_side_ == PositionSide::SHORT; + order.pine_frozen_market_instruction = PineFrozenMarketInstruction::targeted_close( + id, order.quantity_request); } const uint64_t incarnation = order.incarnation; diff --git a/src/engine_stream.cpp b/src/engine_stream.cpp index 1e522ed..11943d2 100644 --- a/src/engine_stream.cpp +++ b/src/engine_stream.cpp @@ -678,7 +678,7 @@ uint64_t BacktestEngine::stream_state_hash() const { integer(static_cast(bar.timestamp)); real(bar.open); real(bar.high); real(bar.low); real(bar.close); real(bar.volume); }; - integer(6); integer(broker_state_hash()); + integer(7); integer(broker_state_hash()); integer(static_cast(stream_phase_)); integer(static_cast(stream_input_mode_)); integer(static_cast(stream_input_tf_ms_)); diff --git a/src/pending_order_mirror.cpp b/src/pending_order_mirror.cpp index e6e82a7..5f676e6 100644 --- a/src/pending_order_mirror.cpp +++ b/src/pending_order_mirror.cpp @@ -108,16 +108,16 @@ void fill_pending_order_mirror(const PendingOrder& src, pf_pending_order_v1_t* o copy_str(src.comment, out->comment, &out->comment_truncated, &out->comment_hash64); out->requested_partial = src.quantity_request.is_partial(1e-9, 1e-9) ? 1 : 0; out->full_percent_exit_request = src.quantity_request.requests_all() ? 1 : 0; - out->pooc_global_full_exit_dynamic_qty = src.pooc_global_full_exit_dynamic_qty ? 1 : 0; - out->pooc_global_full_exit_tracks_bound_adds = src.pooc_global_full_exit_tracks_bound_adds ? 1 : 0; - out->pooc_global_full_exit_bound_add = src.pooc_global_full_exit_bound_add ? 1 : 0; + out->pooc_global_full_exit_dynamic_qty = src.reservation_expansion.population_open() ? 1 : 0; + out->pooc_global_full_exit_tracks_bound_adds = src.reservation_expansion.capture().has_value() ? 1 : 0; + out->pooc_global_full_exit_bound_add = src.reservation_growth_source.reservation_owner().has_value() ? 1 : 0; out->created_while_in_position = src.type == OrderType::EXIT && src.created_position_side != PositionSide::FLAT ? 1 : 0; - out->sbmt_member = src.sbmt_member ? 1 : 0; - out->sbmt_own_qty = src.sbmt_own_qty; - out->sbmt_tx_qty = src.sbmt_tx_qty; - out->sbmt_kept_over_cap = src.sbmt_kept_over_cap ? 1 : 0; - out->sbmt_close_qty = src.sbmt_close_qty; - out->sbmt_close_buy = src.sbmt_close_buy ? 1 : 0; + out->sbmt_member = src.pine_frozen_market_instruction.active() ? 1 : 0; + out->sbmt_own_qty = src.pine_frozen_market_instruction.transaction() ? src.pine_frozen_market_instruction.transaction()->own_units : std::numeric_limits::quiet_NaN(); + out->sbmt_tx_qty = src.pine_frozen_market_instruction.transaction() ? src.pine_frozen_market_instruction.transaction()->transaction_units : std::numeric_limits::quiet_NaN(); + out->sbmt_kept_over_cap = src.pine_frozen_market_instruction.transaction() && src.over_pyramiding_cap_at_placement ? 1 : 0; + out->sbmt_close_qty = src.pine_frozen_market_instruction.targeted_close() ? src.quantity_request.intent()->units() : std::numeric_limits::quiet_NaN(); + out->sbmt_close_buy = src.pine_frozen_market_instruction.targeted_close() && src.created_position_side == PositionSide::SHORT ? 1 : 0; out->suppress_as_declined_reversal_close = src.suppress_as_declined_reversal_close ? 1 : 0; out->dormant_bracket = src.dormant_bracket ? 1 : 0; out->dormant_reissue_pending = src.dormant_reissue_pending ? 1 : 0; @@ -164,6 +164,17 @@ void fill_pending_order_mirror(const PendingOrder& src, pf_pending_order_v1_t* o out->pine_exit_activation_limit_continuation_present = src.pine_exit_activation.evidence() && src.pine_exit_activation.evidence()->limit_continuation ? 1 : 0; out->pine_exit_activation_limit_continuation_cause = src.pine_exit_activation.evidence() && src.pine_exit_activation.evidence()->limit_continuation ? static_cast(src.pine_exit_activation.evidence()->limit_continuation->cause) : 0; out->pine_exit_activation_limit_continuation_fill = src.pine_exit_activation.evidence() && src.pine_exit_activation.evidence()->limit_continuation ? src.pine_exit_activation.evidence()->limit_continuation->observed_fill_sequence : 0; + out->reservation_expansion_position_cycle = src.reservation_expansion.capture() ? src.reservation_expansion.capture()->position_cycle : 0; + out->reservation_expansion_present = src.reservation_expansion.capture().has_value() ? 1 : 0; + out->reservation_expansion_side = src.reservation_expansion.capture() ? static_cast(src.reservation_expansion.capture()->side) : 0; + out->reservation_expansion_first_later_admission_present = src.reservation_expansion.capture() && src.reservation_expansion.capture()->first_later_admission ? 1 : 0; + out->reservation_expansion_first_later_admission = src.reservation_expansion.capture() && src.reservation_expansion.capture()->first_later_admission ? *src.reservation_expansion.capture()->first_later_admission : 0; + out->reservation_growth_source_present = src.reservation_growth_source.reservation_owner().has_value() ? 1 : 0; + out->reservation_growth_source_reservation_owner = src.reservation_growth_source.reservation_owner() ? *src.reservation_growth_source.reservation_owner() : 0; + out->pine_frozen_market_instruction_kind = static_cast(src.pine_frozen_market_instruction.kind()); + out->pine_frozen_market_instruction_own_units = src.pine_frozen_market_instruction.transaction() ? src.pine_frozen_market_instruction.transaction()->own_units : 0.0; + out->pine_frozen_market_instruction_transaction_units = src.pine_frozen_market_instruction.transaction() ? src.pine_frozen_market_instruction.transaction()->transaction_units : 0.0; + copy_str(src.pine_frozen_market_instruction.targeted_close() ? src.pine_frozen_market_instruction.targeted_close()->target_id : std::string(), out->pine_frozen_market_instruction_target_id, &out->pine_frozen_market_instruction_target_id_truncated, &out->pine_frozen_market_instruction_target_id_hash64); } namespace { @@ -315,6 +326,19 @@ const pf_field_desc_t kLayout[] = { PF_PO_FIELD(pine_exit_activation_limit_continuation_present, "uint8_t"), PF_PO_FIELD(pine_exit_activation_limit_continuation_cause, "int32_t"), PF_PO_FIELD(pine_exit_activation_limit_continuation_fill, "uint64_t"), + PF_PO_FIELD(reservation_expansion_position_cycle, "int64_t"), + PF_PO_FIELD(reservation_expansion_present, "uint8_t"), + PF_PO_FIELD(reservation_expansion_side, "int32_t"), + PF_PO_FIELD(reservation_expansion_first_later_admission_present, "uint8_t"), + PF_PO_FIELD(reservation_expansion_first_later_admission, "uint64_t"), + PF_PO_FIELD(reservation_growth_source_present, "uint8_t"), + PF_PO_FIELD(reservation_growth_source_reservation_owner, "uint64_t"), + PF_PO_FIELD(pine_frozen_market_instruction_kind, "uint64_t"), + PF_PO_FIELD(pine_frozen_market_instruction_own_units, "double"), + PF_PO_FIELD(pine_frozen_market_instruction_transaction_units, "double"), + PF_PO_FIELD(pine_frozen_market_instruction_target_id, "char[64]"), + PF_PO_FIELD(pine_frozen_market_instruction_target_id_truncated, "uint8_t"), + PF_PO_FIELD(pine_frozen_market_instruction_target_id_hash64, "uint64_t"), }; #undef PF_PO_FIELD diff --git a/src/reservation_expansion.cpp b/src/reservation_expansion.cpp new file mode 100644 index 0000000..ad6acca --- /dev/null +++ b/src/reservation_expansion.cpp @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +namespace pineforge { +inline namespace reservation_expansion_v1 { +void ReservationExpansion::capture(uint64_t receiver, int64_t cycle, PositionSide side, double capacity) { + if (capture_ || receiver == 0 || cycle <= 0 + || (side != PositionSide::LONG && side != PositionSide::SHORT) + || !std::isfinite(capacity) || capacity <= 0) + throw std::invalid_argument("invalid or repeated reservation expansion capture"); + capture_ = ReservationExpansionCapture{cycle, side, std::nullopt}; +} +void ReservationExpansion::close_population(uint64_t admitted_incarnation) { + if (admitted_incarnation == 0) + throw std::invalid_argument("reservation closure requires an admitted incarnation"); + if (population_open()) capture_->first_later_admission = admitted_incarnation; +} +bool ReservationExpansion::owns_exposure(int64_t cycle, PositionSide side) const { + return capture_ && capture_->position_cycle == cycle && capture_->side == side; +} +void ReservationExpansion::grow(double& qty, + int64_t before_cycle, PositionSide before_side, double before_qty, + int64_t after_cycle, PositionSide after_side, double after_qty, double epsilon) const { + if (owns_exposure(before_cycle, before_side) && owns_exposure(after_cycle, after_side) + && std::isfinite(qty) && after_qty > before_qty + epsilon) + qty += after_qty - before_qty; +} +void ReservationGrowthSource::assign_capture(uint64_t source, uint64_t receiver) { + if (source == 0 || receiver == 0 || source == receiver) + throw std::invalid_argument("reservation source requires distinct live incarnations"); + reservation_owner_ = receiver; +} +} // inline namespace reservation_expansion_v1 +} // namespace pineforge diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5a7de69..4638944 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,4 +1,7 @@ set(TEST_SOURCES + test_reservation_expansion + test_frozen_market_instruction + test_pine_transaction_settlement test_exit_leg_activation test_exit_activation_routes test_pending_order_core @@ -369,6 +372,12 @@ add_test( ${PROJECT_SOURCE_DIR}/scripts/test_broker_state_hash_coverage.py ) +add_test( + NAME test_reservation_expansion_mirror_mutations + COMMAND ${Python3_EXECUTABLE} + ${PROJECT_SOURCE_DIR}/scripts/test_reservation_expansion_mirror.py +) + # When PINEFORGE_ENABLE_COVERAGE is ON we also instrument the test # binaries — header-only code (Series, na, color, log, math::pine_random) # is otherwise reported as 0% because it's only inlined into test TUs. diff --git a/tests/fixtures/frozen_market/README.md b/tests/fixtures/frozen_market/README.md new file mode 100644 index 0000000..6379a39 --- /dev/null +++ b/tests/fixtures/frozen_market/README.md @@ -0,0 +1,7 @@ +# Frozen public mirror prefix + +`ff54_pending_order_mirror.hpp` is copied byte-for-byte from engine +ff54a557ac751244dafd60df0bb22886ec35792d. `ff54_fields.inc` enumerates its +142 fields for compile-time type, size and offset assertions. The native +frozen instruction extends the public snapshot only after this full prefix. +This fixture contains no strategy, tape or expected trades. diff --git a/tests/fixtures/frozen_market/ff54_fields.inc b/tests/fixtures/frozen_market/ff54_fields.inc new file mode 100644 index 0000000..a98fa60 --- /dev/null +++ b/tests/fixtures/frozen_market/ff54_fields.inc @@ -0,0 +1,143 @@ +// Frozen ff54 public descriptor prefix: all 142 fields. +PF_PREFIX_FIELD(struct_version) +PF_PREFIX_FIELD(size) +PF_PREFIX_FIELD(id) +PF_PREFIX_FIELD(id_truncated) +PF_PREFIX_FIELD(id_hash64) +PF_PREFIX_FIELD(from_entry) +PF_PREFIX_FIELD(from_entry_truncated) +PF_PREFIX_FIELD(from_entry_hash64) +PF_PREFIX_FIELD(type) +PF_PREFIX_FIELD(is_long) +PF_PREFIX_FIELD(limit_price) +PF_PREFIX_FIELD(stop_price) +PF_PREFIX_FIELD(trail_points) +PF_PREFIX_FIELD(trail_price) +PF_PREFIX_FIELD(trail_offset) +PF_PREFIX_FIELD(profit_ticks) +PF_PREFIX_FIELD(loss_ticks) +PF_PREFIX_FIELD(qty) +PF_PREFIX_FIELD(qty_type) +PF_PREFIX_FIELD(qty_percent) +PF_PREFIX_FIELD(oca_name) +PF_PREFIX_FIELD(oca_name_truncated) +PF_PREFIX_FIELD(oca_name_hash64) +PF_PREFIX_FIELD(oca_type) +PF_PREFIX_FIELD(created_bar) +PF_PREFIX_FIELD(created_seq) +PF_PREFIX_FIELD(incarnation) +PF_PREFIX_FIELD(created_by_same_id_replacement) +PF_PREFIX_FIELD(replaced_default_market_incarnation) +PF_PREFIX_FIELD(declined_by_replaced_short_market) +PF_PREFIX_FIELD(replaced_exit_order_incarnation) +PF_PREFIX_FIELD(recreated_after_named_cancelled_entry_incarnation) +PF_PREFIX_FIELD(named_cancel_surviving_exit_incarnation) +PF_PREFIX_FIELD(stop_limit_activated) +PF_PREFIX_FIELD(coof_suppress_stop_on_entry_bar) +PF_PREFIX_FIELD(coof_suppress_limit_on_entry_bar) +PF_PREFIX_FIELD(created_during_coof_recalc) +PF_PREFIX_FIELD(coof_born_at_close_recalc) +PF_PREFIX_FIELD(coof_born_mid_bar) +PF_PREFIX_FIELD(coof_cascade_seg_i) +PF_PREFIX_FIELD(coof_cascade_inflight_fires) +PF_PREFIX_FIELD(created_position_side) +PF_PREFIX_FIELD(created_position_cycle_seq) +PF_PREFIX_FIELD(created_after_position_close_in_bar) +PF_PREFIX_FIELD(over_pyramiding_cap_at_placement) +PF_PREFIX_FIELD(same_id_stop_deferred_close_all_bar) +PF_PREFIX_FIELD(same_id_stop_deferred_close_all_incarnation) +PF_PREFIX_FIELD(reverses_same_bar_market_from_flat) +PF_PREFIX_FIELD(paired_flat_market_candidate) +PF_PREFIX_FIELD(paired_flat_market_own_qty) +PF_PREFIX_FIELD(paired_flat_market_signal_close) +PF_PREFIX_FIELD(paired_flat_market_signal_equity) +PF_PREFIX_FIELD(paired_flat_market_signal_margin_pct) +PF_PREFIX_FIELD(paired_flat_market_signal_pointvalue) +PF_PREFIX_FIELD(paired_flat_market_signal_fx) +PF_PREFIX_FIELD(paired_flat_market_peer_seq) +PF_PREFIX_FIELD(paired_flat_market_transaction_qty) +PF_PREFIX_FIELD(default_flat_market_gross_candidate) +PF_PREFIX_FIELD(tv_carry_qty) +PF_PREFIX_FIELD(frozen_default_qty) +PF_PREFIX_FIELD(default_stop_placement_qty) +PF_PREFIX_FIELD(default_stop_placement_equity) +PF_PREFIX_FIELD(default_stop_placement_signal_close) +PF_PREFIX_FIELD(default_stop_sizing_price) +PF_PREFIX_FIELD(sizing_equity) +PF_PREFIX_FIELD(sizing_price) +PF_PREFIX_FIELD(sizing_fx) +PF_PREFIX_FIELD(sizing_mark) +PF_PREFIX_FIELD(opening_affordability_exemption_candidate) +PF_PREFIX_FIELD(explicit_flat_admission_candidate) +PF_PREFIX_FIELD(explicit_placement_equity) +PF_PREFIX_FIELD(explicit_slipped_signal_close) +PF_PREFIX_FIELD(affordability_placement_equity) +PF_PREFIX_FIELD(affordability_signal_price) +PF_PREFIX_FIELD(affordability_held_qty) +PF_PREFIX_FIELD(affordability_close_only) +PF_PREFIX_FIELD(rounded_signal_cost_close_only) +PF_PREFIX_FIELD(signal_close_mc_bar) +PF_PREFIX_FIELD(signal_close_mc_entry_incarnation) +PF_PREFIX_FIELD(signal_close_mc_fill_seq) +PF_PREFIX_FIELD(signal_close_mc_remaining_qty) +PF_PREFIX_FIELD(comment) +PF_PREFIX_FIELD(comment_truncated) +PF_PREFIX_FIELD(comment_hash64) +PF_PREFIX_FIELD(requested_partial) +PF_PREFIX_FIELD(full_percent_exit_request) +PF_PREFIX_FIELD(pooc_global_full_exit_dynamic_qty) +PF_PREFIX_FIELD(pooc_global_full_exit_tracks_bound_adds) +PF_PREFIX_FIELD(pooc_global_full_exit_bound_add) +PF_PREFIX_FIELD(created_while_in_position) +PF_PREFIX_FIELD(sbmt_member) +PF_PREFIX_FIELD(sbmt_own_qty) +PF_PREFIX_FIELD(sbmt_tx_qty) +PF_PREFIX_FIELD(sbmt_kept_over_cap) +PF_PREFIX_FIELD(sbmt_close_qty) +PF_PREFIX_FIELD(sbmt_close_buy) +PF_PREFIX_FIELD(suppress_as_declined_reversal_close) +PF_PREFIX_FIELD(dormant_bracket) +PF_PREFIX_FIELD(dormant_reissue_pending) +PF_PREFIX_FIELD(dormant_original_stop_price) +PF_PREFIX_FIELD(dormant_hold_bar) +PF_PREFIX_FIELD(dormant_reversal_kill_bar) +PF_PREFIX_FIELD(dormant_trail_best) +PF_PREFIX_FIELD(dormant_trail_best_start) +PF_PREFIX_FIELD(dormant_trail_leg_dead) +PF_PREFIX_FIELD(suppressed_close_consumed_ledger_qty) +PF_PREFIX_FIELD(suppressed_close_retired_ledger_qty) +PF_PREFIX_FIELD(short_seed_collision_role) +PF_PREFIX_FIELD(replaced_order_incarnation) +PF_PREFIX_FIELD(birth_timestamp) +PF_PREFIX_FIELD(birth_cause) +PF_PREFIX_FIELD(birth_bar) +PF_PREFIX_FIELD(birth_cursor_domain) +PF_PREFIX_FIELD(birth_cursor_position) +PF_PREFIX_FIELD(birth_cursor_index) +PF_PREFIX_FIELD(birth_cursor_count) +PF_PREFIX_FIELD(birth_cursor_price) +PF_PREFIX_FIELD(birth_first_fill) +PF_PREFIX_FIELD(birth_last_fill) +PF_PREFIX_FIELD(birth_evaluation_ordinal) +PF_PREFIX_FIELD(pine_birth_reach) +PF_PREFIX_FIELD(quantity_intent_kind) +PF_PREFIX_FIELD(quantity_intent_units) +PF_PREFIX_FIELD(quantity_intent_numerator) +PF_PREFIX_FIELD(quantity_intent_denominator) +PF_PREFIX_FIELD(quantity_reservation_present) +PF_PREFIX_FIELD(quantity_reservation_units) +PF_PREFIX_FIELD(quantity_reservation_basis_units) +PF_PREFIX_FIELD(leg_activation_owner_cycle) +PF_PREFIX_FIELD(leg_activation_present) +PF_PREFIX_FIELD(leg_activation_stop_first_bar) +PF_PREFIX_FIELD(leg_activation_limit_first_bar) +PF_PREFIX_FIELD(pine_exit_activation_owner_cycle_at_birth) +PF_PREFIX_FIELD(pine_exit_activation_present) +PF_PREFIX_FIELD(pine_exit_activation_entry_bar_at_birth) +PF_PREFIX_FIELD(pine_exit_activation_direction_at_birth) +PF_PREFIX_FIELD(pine_exit_activation_cursor_price_at_birth) +PF_PREFIX_FIELD(pine_exit_activation_stop_level_at_birth) +PF_PREFIX_FIELD(pine_exit_activation_limit_level_at_birth) +PF_PREFIX_FIELD(pine_exit_activation_limit_continuation_present) +PF_PREFIX_FIELD(pine_exit_activation_limit_continuation_cause) +PF_PREFIX_FIELD(pine_exit_activation_limit_continuation_fill) diff --git a/tests/fixtures/frozen_market/ff54_pending_order_mirror.hpp b/tests/fixtures/frozen_market/ff54_pending_order_mirror.hpp new file mode 100644 index 0000000..3d23478 --- /dev/null +++ b/tests/fixtures/frozen_market/ff54_pending_order_mirror.hpp @@ -0,0 +1,170 @@ +// GENERATED by scripts/gen_pending_order_mirror.py from include/pineforge/engine.hpp -- do not edit. +// 94 PendingOrder members mirrored (142 POD fields incl. struct_version/size). +#pragma once +#include + +/* C-compatible value snapshot of one resting pineforge::PendingOrder + * (spec 3.6). struct_version identifies the field set (this file: + * 1); size is sizeof(pf_pending_order_v1_t) as the producer + * compiled it. Strings are copied into a NUL-terminated char[64] + * (name_truncated = 1 when the source was longer than 63 bytes) with + * name_hash64 = FNV-1a 64 of the FULL source string. Enums are their + * int32 value; bool is 0/1 in a uint8_t. Append-only, like every + * pineforge.h POD. */ +typedef struct pf_pending_order_v1_s { + uint32_t struct_version; + uint32_t size; + char id[64]; + uint8_t id_truncated; + uint64_t id_hash64; + char from_entry[64]; + uint8_t from_entry_truncated; + uint64_t from_entry_hash64; + int32_t type; + uint8_t is_long; + double limit_price; + double stop_price; + double trail_points; + double trail_price; + double trail_offset; + double profit_ticks; + double loss_ticks; + double qty; + int32_t qty_type; + double qty_percent; + char oca_name[64]; + uint8_t oca_name_truncated; + uint64_t oca_name_hash64; + int32_t oca_type; + int32_t created_bar; + int64_t created_seq; + uint64_t incarnation; + uint8_t created_by_same_id_replacement; // deprecated, derived output only + uint64_t replaced_default_market_incarnation; + uint8_t declined_by_replaced_short_market; + uint64_t replaced_exit_order_incarnation; // deprecated, derived output only + uint64_t recreated_after_named_cancelled_entry_incarnation; + uint64_t named_cancel_surviving_exit_incarnation; + uint8_t stop_limit_activated; + uint8_t coof_suppress_stop_on_entry_bar; // deprecated, derived output only + uint8_t coof_suppress_limit_on_entry_bar; // deprecated, derived output only + uint8_t created_during_coof_recalc; // deprecated, derived output only + uint8_t coof_born_at_close_recalc; // deprecated, derived output only + uint8_t coof_born_mid_bar; // deprecated, derived output only + int32_t coof_cascade_seg_i; + uint8_t coof_cascade_inflight_fires; + int32_t created_position_side; + int64_t created_position_cycle_seq; + uint8_t created_after_position_close_in_bar; + uint8_t over_pyramiding_cap_at_placement; + int32_t same_id_stop_deferred_close_all_bar; + uint64_t same_id_stop_deferred_close_all_incarnation; + uint8_t reverses_same_bar_market_from_flat; + uint8_t paired_flat_market_candidate; + double paired_flat_market_own_qty; + double paired_flat_market_signal_close; + double paired_flat_market_signal_equity; + double paired_flat_market_signal_margin_pct; + double paired_flat_market_signal_pointvalue; + double paired_flat_market_signal_fx; + int64_t paired_flat_market_peer_seq; + double paired_flat_market_transaction_qty; + uint8_t default_flat_market_gross_candidate; + double tv_carry_qty; + double frozen_default_qty; + double default_stop_placement_qty; + double default_stop_placement_equity; + double default_stop_placement_signal_close; + double default_stop_sizing_price; + double sizing_equity; + double sizing_price; + double sizing_fx; + double sizing_mark; + uint8_t opening_affordability_exemption_candidate; + uint8_t explicit_flat_admission_candidate; + double explicit_placement_equity; + double explicit_slipped_signal_close; + double affordability_placement_equity; + double affordability_signal_price; + double affordability_held_qty; + uint8_t affordability_close_only; + uint8_t rounded_signal_cost_close_only; + int32_t signal_close_mc_bar; + uint64_t signal_close_mc_entry_incarnation; + uint64_t signal_close_mc_fill_seq; + double signal_close_mc_remaining_qty; + char comment[64]; + uint8_t comment_truncated; + uint64_t comment_hash64; + uint8_t requested_partial; // deprecated, derived output only + uint8_t full_percent_exit_request; // deprecated, derived output only + uint8_t pooc_global_full_exit_dynamic_qty; + uint8_t pooc_global_full_exit_tracks_bound_adds; + uint8_t pooc_global_full_exit_bound_add; + uint8_t created_while_in_position; // deprecated, derived output only + uint8_t sbmt_member; + double sbmt_own_qty; + double sbmt_tx_qty; + uint8_t sbmt_kept_over_cap; + double sbmt_close_qty; + uint8_t sbmt_close_buy; + uint8_t suppress_as_declined_reversal_close; + uint8_t dormant_bracket; + uint8_t dormant_reissue_pending; + double dormant_original_stop_price; + int32_t dormant_hold_bar; + int32_t dormant_reversal_kill_bar; + double dormant_trail_best; + double dormant_trail_best_start; + uint8_t dormant_trail_leg_dead; + double suppressed_close_consumed_ledger_qty; + double suppressed_close_retired_ledger_qty; + int32_t short_seed_collision_role; + uint64_t replaced_order_incarnation; + int64_t birth_timestamp; + int32_t birth_cause; + int32_t birth_bar; + int32_t birth_cursor_domain; + int32_t birth_cursor_position; + int32_t birth_cursor_index; + int32_t birth_cursor_count; + double birth_cursor_price; + uint64_t birth_first_fill; + uint64_t birth_last_fill; + uint64_t birth_evaluation_ordinal; + int32_t pine_birth_reach; + uint64_t quantity_intent_kind; + double quantity_intent_units; + double quantity_intent_numerator; + double quantity_intent_denominator; + uint8_t quantity_reservation_present; + double quantity_reservation_units; + double quantity_reservation_basis_units; + int64_t leg_activation_owner_cycle; + uint8_t leg_activation_present; + int64_t leg_activation_stop_first_bar; + int64_t leg_activation_limit_first_bar; + int64_t pine_exit_activation_owner_cycle_at_birth; + uint8_t pine_exit_activation_present; + int32_t pine_exit_activation_entry_bar_at_birth; + int32_t pine_exit_activation_direction_at_birth; + double pine_exit_activation_cursor_price_at_birth; + double pine_exit_activation_stop_level_at_birth; + double pine_exit_activation_limit_level_at_birth; + uint8_t pine_exit_activation_limit_continuation_present; + int32_t pine_exit_activation_limit_continuation_cause; + uint64_t pine_exit_activation_limit_continuation_fill; +} pf_pending_order_v1_t; + +/* One row of the self-describing layout table returned by + * strategy_pending_order_layout(): field name, C type spelling + * ("uint8_t", "int32_t", "int64_t", "uint64_t", "double", "char[64]", + * "uint32_t"), byte offset inside pf_pending_order_v1_t, byte size. */ +typedef struct pf_field_desc_s { + const char* name; + const char* type; + uint32_t offset; + uint32_t size; +} pf_field_desc_t; +#define PF_PENDING_ORDER_STRUCT_VERSION 1 +#define PF_PENDING_ORDER_STR_CAP 64 diff --git a/tests/fixtures/reservation_expansion/ff54-fields.inc b/tests/fixtures/reservation_expansion/ff54-fields.inc new file mode 100644 index 0000000..01f6e49 --- /dev/null +++ b/tests/fixtures/reservation_expansion/ff54-fields.inc @@ -0,0 +1,143 @@ +// Frozen ff54 field order, types and offsets; generated from its Git object. +OLD_FIELD(struct_version, "uint32_t") +OLD_FIELD(size, "uint32_t") +OLD_FIELD(id, "char[64]") +OLD_FIELD(id_truncated, "uint8_t") +OLD_FIELD(id_hash64, "uint64_t") +OLD_FIELD(from_entry, "char[64]") +OLD_FIELD(from_entry_truncated, "uint8_t") +OLD_FIELD(from_entry_hash64, "uint64_t") +OLD_FIELD(type, "int32_t") +OLD_FIELD(is_long, "uint8_t") +OLD_FIELD(limit_price, "double") +OLD_FIELD(stop_price, "double") +OLD_FIELD(trail_points, "double") +OLD_FIELD(trail_price, "double") +OLD_FIELD(trail_offset, "double") +OLD_FIELD(profit_ticks, "double") +OLD_FIELD(loss_ticks, "double") +OLD_FIELD(qty, "double") +OLD_FIELD(qty_type, "int32_t") +OLD_FIELD(qty_percent, "double") +OLD_FIELD(oca_name, "char[64]") +OLD_FIELD(oca_name_truncated, "uint8_t") +OLD_FIELD(oca_name_hash64, "uint64_t") +OLD_FIELD(oca_type, "int32_t") +OLD_FIELD(created_bar, "int32_t") +OLD_FIELD(created_seq, "int64_t") +OLD_FIELD(incarnation, "uint64_t") +OLD_FIELD(created_by_same_id_replacement, "uint8_t") +OLD_FIELD(replaced_default_market_incarnation, "uint64_t") +OLD_FIELD(declined_by_replaced_short_market, "uint8_t") +OLD_FIELD(replaced_exit_order_incarnation, "uint64_t") +OLD_FIELD(recreated_after_named_cancelled_entry_incarnation, "uint64_t") +OLD_FIELD(named_cancel_surviving_exit_incarnation, "uint64_t") +OLD_FIELD(stop_limit_activated, "uint8_t") +OLD_FIELD(coof_suppress_stop_on_entry_bar, "uint8_t") +OLD_FIELD(coof_suppress_limit_on_entry_bar, "uint8_t") +OLD_FIELD(created_during_coof_recalc, "uint8_t") +OLD_FIELD(coof_born_at_close_recalc, "uint8_t") +OLD_FIELD(coof_born_mid_bar, "uint8_t") +OLD_FIELD(coof_cascade_seg_i, "int32_t") +OLD_FIELD(coof_cascade_inflight_fires, "uint8_t") +OLD_FIELD(created_position_side, "int32_t") +OLD_FIELD(created_position_cycle_seq, "int64_t") +OLD_FIELD(created_after_position_close_in_bar, "uint8_t") +OLD_FIELD(over_pyramiding_cap_at_placement, "uint8_t") +OLD_FIELD(same_id_stop_deferred_close_all_bar, "int32_t") +OLD_FIELD(same_id_stop_deferred_close_all_incarnation, "uint64_t") +OLD_FIELD(reverses_same_bar_market_from_flat, "uint8_t") +OLD_FIELD(paired_flat_market_candidate, "uint8_t") +OLD_FIELD(paired_flat_market_own_qty, "double") +OLD_FIELD(paired_flat_market_signal_close, "double") +OLD_FIELD(paired_flat_market_signal_equity, "double") +OLD_FIELD(paired_flat_market_signal_margin_pct, "double") +OLD_FIELD(paired_flat_market_signal_pointvalue, "double") +OLD_FIELD(paired_flat_market_signal_fx, "double") +OLD_FIELD(paired_flat_market_peer_seq, "int64_t") +OLD_FIELD(paired_flat_market_transaction_qty, "double") +OLD_FIELD(default_flat_market_gross_candidate, "uint8_t") +OLD_FIELD(tv_carry_qty, "double") +OLD_FIELD(frozen_default_qty, "double") +OLD_FIELD(default_stop_placement_qty, "double") +OLD_FIELD(default_stop_placement_equity, "double") +OLD_FIELD(default_stop_placement_signal_close, "double") +OLD_FIELD(default_stop_sizing_price, "double") +OLD_FIELD(sizing_equity, "double") +OLD_FIELD(sizing_price, "double") +OLD_FIELD(sizing_fx, "double") +OLD_FIELD(sizing_mark, "double") +OLD_FIELD(opening_affordability_exemption_candidate, "uint8_t") +OLD_FIELD(explicit_flat_admission_candidate, "uint8_t") +OLD_FIELD(explicit_placement_equity, "double") +OLD_FIELD(explicit_slipped_signal_close, "double") +OLD_FIELD(affordability_placement_equity, "double") +OLD_FIELD(affordability_signal_price, "double") +OLD_FIELD(affordability_held_qty, "double") +OLD_FIELD(affordability_close_only, "uint8_t") +OLD_FIELD(rounded_signal_cost_close_only, "uint8_t") +OLD_FIELD(signal_close_mc_bar, "int32_t") +OLD_FIELD(signal_close_mc_entry_incarnation, "uint64_t") +OLD_FIELD(signal_close_mc_fill_seq, "uint64_t") +OLD_FIELD(signal_close_mc_remaining_qty, "double") +OLD_FIELD(comment, "char[64]") +OLD_FIELD(comment_truncated, "uint8_t") +OLD_FIELD(comment_hash64, "uint64_t") +OLD_FIELD(requested_partial, "uint8_t") +OLD_FIELD(full_percent_exit_request, "uint8_t") +OLD_FIELD(pooc_global_full_exit_dynamic_qty, "uint8_t") +OLD_FIELD(pooc_global_full_exit_tracks_bound_adds, "uint8_t") +OLD_FIELD(pooc_global_full_exit_bound_add, "uint8_t") +OLD_FIELD(created_while_in_position, "uint8_t") +OLD_FIELD(sbmt_member, "uint8_t") +OLD_FIELD(sbmt_own_qty, "double") +OLD_FIELD(sbmt_tx_qty, "double") +OLD_FIELD(sbmt_kept_over_cap, "uint8_t") +OLD_FIELD(sbmt_close_qty, "double") +OLD_FIELD(sbmt_close_buy, "uint8_t") +OLD_FIELD(suppress_as_declined_reversal_close, "uint8_t") +OLD_FIELD(dormant_bracket, "uint8_t") +OLD_FIELD(dormant_reissue_pending, "uint8_t") +OLD_FIELD(dormant_original_stop_price, "double") +OLD_FIELD(dormant_hold_bar, "int32_t") +OLD_FIELD(dormant_reversal_kill_bar, "int32_t") +OLD_FIELD(dormant_trail_best, "double") +OLD_FIELD(dormant_trail_best_start, "double") +OLD_FIELD(dormant_trail_leg_dead, "uint8_t") +OLD_FIELD(suppressed_close_consumed_ledger_qty, "double") +OLD_FIELD(suppressed_close_retired_ledger_qty, "double") +OLD_FIELD(short_seed_collision_role, "int32_t") +OLD_FIELD(replaced_order_incarnation, "uint64_t") +OLD_FIELD(birth_timestamp, "int64_t") +OLD_FIELD(birth_cause, "int32_t") +OLD_FIELD(birth_bar, "int32_t") +OLD_FIELD(birth_cursor_domain, "int32_t") +OLD_FIELD(birth_cursor_position, "int32_t") +OLD_FIELD(birth_cursor_index, "int32_t") +OLD_FIELD(birth_cursor_count, "int32_t") +OLD_FIELD(birth_cursor_price, "double") +OLD_FIELD(birth_first_fill, "uint64_t") +OLD_FIELD(birth_last_fill, "uint64_t") +OLD_FIELD(birth_evaluation_ordinal, "uint64_t") +OLD_FIELD(pine_birth_reach, "int32_t") +OLD_FIELD(quantity_intent_kind, "uint64_t") +OLD_FIELD(quantity_intent_units, "double") +OLD_FIELD(quantity_intent_numerator, "double") +OLD_FIELD(quantity_intent_denominator, "double") +OLD_FIELD(quantity_reservation_present, "uint8_t") +OLD_FIELD(quantity_reservation_units, "double") +OLD_FIELD(quantity_reservation_basis_units, "double") +OLD_FIELD(leg_activation_owner_cycle, "int64_t") +OLD_FIELD(leg_activation_present, "uint8_t") +OLD_FIELD(leg_activation_stop_first_bar, "int64_t") +OLD_FIELD(leg_activation_limit_first_bar, "int64_t") +OLD_FIELD(pine_exit_activation_owner_cycle_at_birth, "int64_t") +OLD_FIELD(pine_exit_activation_present, "uint8_t") +OLD_FIELD(pine_exit_activation_entry_bar_at_birth, "int32_t") +OLD_FIELD(pine_exit_activation_direction_at_birth, "int32_t") +OLD_FIELD(pine_exit_activation_cursor_price_at_birth, "double") +OLD_FIELD(pine_exit_activation_stop_level_at_birth, "double") +OLD_FIELD(pine_exit_activation_limit_level_at_birth, "double") +OLD_FIELD(pine_exit_activation_limit_continuation_present, "uint8_t") +OLD_FIELD(pine_exit_activation_limit_continuation_cause, "int32_t") +OLD_FIELD(pine_exit_activation_limit_continuation_fill, "uint64_t") diff --git a/tests/fixtures/reservation_expansion/ff54_pending_order_mirror.hpp b/tests/fixtures/reservation_expansion/ff54_pending_order_mirror.hpp new file mode 100644 index 0000000..3d23478 --- /dev/null +++ b/tests/fixtures/reservation_expansion/ff54_pending_order_mirror.hpp @@ -0,0 +1,170 @@ +// GENERATED by scripts/gen_pending_order_mirror.py from include/pineforge/engine.hpp -- do not edit. +// 94 PendingOrder members mirrored (142 POD fields incl. struct_version/size). +#pragma once +#include + +/* C-compatible value snapshot of one resting pineforge::PendingOrder + * (spec 3.6). struct_version identifies the field set (this file: + * 1); size is sizeof(pf_pending_order_v1_t) as the producer + * compiled it. Strings are copied into a NUL-terminated char[64] + * (name_truncated = 1 when the source was longer than 63 bytes) with + * name_hash64 = FNV-1a 64 of the FULL source string. Enums are their + * int32 value; bool is 0/1 in a uint8_t. Append-only, like every + * pineforge.h POD. */ +typedef struct pf_pending_order_v1_s { + uint32_t struct_version; + uint32_t size; + char id[64]; + uint8_t id_truncated; + uint64_t id_hash64; + char from_entry[64]; + uint8_t from_entry_truncated; + uint64_t from_entry_hash64; + int32_t type; + uint8_t is_long; + double limit_price; + double stop_price; + double trail_points; + double trail_price; + double trail_offset; + double profit_ticks; + double loss_ticks; + double qty; + int32_t qty_type; + double qty_percent; + char oca_name[64]; + uint8_t oca_name_truncated; + uint64_t oca_name_hash64; + int32_t oca_type; + int32_t created_bar; + int64_t created_seq; + uint64_t incarnation; + uint8_t created_by_same_id_replacement; // deprecated, derived output only + uint64_t replaced_default_market_incarnation; + uint8_t declined_by_replaced_short_market; + uint64_t replaced_exit_order_incarnation; // deprecated, derived output only + uint64_t recreated_after_named_cancelled_entry_incarnation; + uint64_t named_cancel_surviving_exit_incarnation; + uint8_t stop_limit_activated; + uint8_t coof_suppress_stop_on_entry_bar; // deprecated, derived output only + uint8_t coof_suppress_limit_on_entry_bar; // deprecated, derived output only + uint8_t created_during_coof_recalc; // deprecated, derived output only + uint8_t coof_born_at_close_recalc; // deprecated, derived output only + uint8_t coof_born_mid_bar; // deprecated, derived output only + int32_t coof_cascade_seg_i; + uint8_t coof_cascade_inflight_fires; + int32_t created_position_side; + int64_t created_position_cycle_seq; + uint8_t created_after_position_close_in_bar; + uint8_t over_pyramiding_cap_at_placement; + int32_t same_id_stop_deferred_close_all_bar; + uint64_t same_id_stop_deferred_close_all_incarnation; + uint8_t reverses_same_bar_market_from_flat; + uint8_t paired_flat_market_candidate; + double paired_flat_market_own_qty; + double paired_flat_market_signal_close; + double paired_flat_market_signal_equity; + double paired_flat_market_signal_margin_pct; + double paired_flat_market_signal_pointvalue; + double paired_flat_market_signal_fx; + int64_t paired_flat_market_peer_seq; + double paired_flat_market_transaction_qty; + uint8_t default_flat_market_gross_candidate; + double tv_carry_qty; + double frozen_default_qty; + double default_stop_placement_qty; + double default_stop_placement_equity; + double default_stop_placement_signal_close; + double default_stop_sizing_price; + double sizing_equity; + double sizing_price; + double sizing_fx; + double sizing_mark; + uint8_t opening_affordability_exemption_candidate; + uint8_t explicit_flat_admission_candidate; + double explicit_placement_equity; + double explicit_slipped_signal_close; + double affordability_placement_equity; + double affordability_signal_price; + double affordability_held_qty; + uint8_t affordability_close_only; + uint8_t rounded_signal_cost_close_only; + int32_t signal_close_mc_bar; + uint64_t signal_close_mc_entry_incarnation; + uint64_t signal_close_mc_fill_seq; + double signal_close_mc_remaining_qty; + char comment[64]; + uint8_t comment_truncated; + uint64_t comment_hash64; + uint8_t requested_partial; // deprecated, derived output only + uint8_t full_percent_exit_request; // deprecated, derived output only + uint8_t pooc_global_full_exit_dynamic_qty; + uint8_t pooc_global_full_exit_tracks_bound_adds; + uint8_t pooc_global_full_exit_bound_add; + uint8_t created_while_in_position; // deprecated, derived output only + uint8_t sbmt_member; + double sbmt_own_qty; + double sbmt_tx_qty; + uint8_t sbmt_kept_over_cap; + double sbmt_close_qty; + uint8_t sbmt_close_buy; + uint8_t suppress_as_declined_reversal_close; + uint8_t dormant_bracket; + uint8_t dormant_reissue_pending; + double dormant_original_stop_price; + int32_t dormant_hold_bar; + int32_t dormant_reversal_kill_bar; + double dormant_trail_best; + double dormant_trail_best_start; + uint8_t dormant_trail_leg_dead; + double suppressed_close_consumed_ledger_qty; + double suppressed_close_retired_ledger_qty; + int32_t short_seed_collision_role; + uint64_t replaced_order_incarnation; + int64_t birth_timestamp; + int32_t birth_cause; + int32_t birth_bar; + int32_t birth_cursor_domain; + int32_t birth_cursor_position; + int32_t birth_cursor_index; + int32_t birth_cursor_count; + double birth_cursor_price; + uint64_t birth_first_fill; + uint64_t birth_last_fill; + uint64_t birth_evaluation_ordinal; + int32_t pine_birth_reach; + uint64_t quantity_intent_kind; + double quantity_intent_units; + double quantity_intent_numerator; + double quantity_intent_denominator; + uint8_t quantity_reservation_present; + double quantity_reservation_units; + double quantity_reservation_basis_units; + int64_t leg_activation_owner_cycle; + uint8_t leg_activation_present; + int64_t leg_activation_stop_first_bar; + int64_t leg_activation_limit_first_bar; + int64_t pine_exit_activation_owner_cycle_at_birth; + uint8_t pine_exit_activation_present; + int32_t pine_exit_activation_entry_bar_at_birth; + int32_t pine_exit_activation_direction_at_birth; + double pine_exit_activation_cursor_price_at_birth; + double pine_exit_activation_stop_level_at_birth; + double pine_exit_activation_limit_level_at_birth; + uint8_t pine_exit_activation_limit_continuation_present; + int32_t pine_exit_activation_limit_continuation_cause; + uint64_t pine_exit_activation_limit_continuation_fill; +} pf_pending_order_v1_t; + +/* One row of the self-describing layout table returned by + * strategy_pending_order_layout(): field name, C type spelling + * ("uint8_t", "int32_t", "int64_t", "uint64_t", "double", "char[64]", + * "uint32_t"), byte offset inside pf_pending_order_v1_t, byte size. */ +typedef struct pf_field_desc_s { + const char* name; + const char* type; + uint32_t offset; + uint32_t size; +} pf_field_desc_t; +#define PF_PENDING_ORDER_STRUCT_VERSION 1 +#define PF_PENDING_ORDER_STR_CAP 64 diff --git a/tests/fixtures/script_cpp_abi/baseff54/README.md b/tests/fixtures/script_cpp_abi/baseff54/README.md new file mode 100644 index 0000000..f098a37 --- /dev/null +++ b/tests/fixtures/script_cpp_abi/baseff54/README.md @@ -0,0 +1 @@ +Exact shipped ff54/v6 header closure. Compile/link controls only; no executable runs. diff --git a/tests/fixtures/script_cpp_abi/baseff54/headers.json.gz b/tests/fixtures/script_cpp_abi/baseff54/headers.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..0da72b00f85c53075cbe3a37063050587373c81a GIT binary patch literal 143735 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ΠP1tN26S^hq#iC7#P=S3vT^jg(NG+D$HyX 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 F2LM~F_Xq$0 literal 0 HcmV?d00001 diff --git a/tests/fixtures/script_cpp_abi/baseff54/manifest.json b/tests/fixtures/script_cpp_abi/baseff54/manifest.json new file mode 100644 index 0000000..a641d77 --- /dev/null +++ b/tests/fixtures/script_cpp_abi/baseff54/manifest.json @@ -0,0 +1,90 @@ +{ + "source_commit": "ff54a557ac751244dafd60df0bb22886ec35792d", + "source_tree": "60431e5da18d4bce0777f0e3b4df03d41163c350", + "internal_namespace": "engine_script_run_v6", + "archive": "headers.json.gz", + "archive_sha256": "206bdd71c0a6a7955b97b9b63ae437b3b5119d7ebcf6d9f2b506084caba48674", + "generated_dependency": "pineforge/version.h comes from the matching current configure; no frozen layout uses its value.", + "files": { + "pineforge/bar.hpp": { + "sha256": "665c2528dca64ac9474de622dfd7ffdb540ff91316f70317e39aada158d1e0de", + "git_blob": "836f73daab382e9c8d5a6d03a942a921e39b756f" + }, + "pineforge/broker_events.hpp": { + "sha256": "4f3d9948a4d1604750901fa3982d6ea49bd50dd15a86c4e5d690b83d1f5f23c0", + "git_blob": "2972d53c7b039af266f4da161301c01eec54c16d" + }, + "pineforge/compat/pine/exit_activation.hpp": { + "sha256": "c6a538e6dfc5c0e70f434e92e0d8329b40ffc7e87051ae2d1d9754d9db8c9a6d", + "git_blob": "5024b013c36df956cef1d77db067a68284067322" + }, + "pineforge/compat/pine/intraday_cap.hpp": { + "sha256": "0ac0eab34625ab9a974037ff8c0217603a01deb81599350a4b24f7bf48ac0cbd", + "git_blob": "0aba76b6a78251df33e92f19290473adecf5a61e" + }, + "pineforge/compat/pine/intraday_order_budget.hpp": { + "sha256": "43f7700f9c66c630ab8a9d8fd899eecb03c2fd9aabff11d2dc2b7fa85f92981b", + "git_blob": "730d941fffa3939e375489f40a50901ccea9ec87" + }, + "pineforge/compat/pine/order_birth.hpp": { + "sha256": "db379949112f0cd363fba4aecc5f7ad952f7c3eea0eec0425bcc3367dd4505b9", + "git_blob": "b57ffe0eba7bd10b4e0588e48ef8fa8e82b629ae" + }, + "pineforge/compat/pine/order_priority.hpp": { + "sha256": "0e77af11357cf9b2e3255ef2ef871ac0cd319b6548568c549f64c2598115f4d9", + "git_blob": "86aac9629e40ad19b7308468e95389598a9436e2" + }, + "pineforge/engine.hpp": { + "sha256": "d5d74b2b0542ce7aa2bf3e0a95bac8d05318ce15494148f4f07f92c7e332b237", + "git_blob": "64c73225dd3d67eaae9f0937651c2683ac94937e" + }, + "pineforge/leg_activation.hpp": { + "sha256": "859d75d0ae90ec3cc109765da066b37c3bbbff9c7c840368fbdd05dc7e178f3f", + "git_blob": "4160c841782800853bb574219b3dad2ca8aa0cc6" + }, + "pineforge/magnifier.hpp": { + "sha256": "c0ed220b6df054b44596a434d4f48b1c3e960ca329bb8644a405a608175e06ff", + "git_blob": "1bbc910a869d162900d7610fa0bd9a88776b7b0f" + }, + "pineforge/na.hpp": { + "sha256": "0e8c256fcdeda94a0855458fa3b8c4ad4f9864dc2aecce969934f6bea82fd0a5", + "git_blob": "e98505aadc68a09cbe5a14aacf591a799a15ecd2" + }, + "pineforge/order_birth.hpp": { + "sha256": "0eadb3e2a92248fbc8e6ba8f94285b15b0e83d7a0396f5904b40c216619604e4", + "git_blob": "ed4a4038e9d079c92b4ebd777a5f22f1f1256b0c" + }, + "pineforge/order_priority.hpp": { + "sha256": "25bb7898972153b044675245db230c1171644856ef904f4dd02353b8968d433b", + "git_blob": "3e9fa5ee4121971a7962db8a60859aba6fb9ec95" + }, + "pineforge/pending_order_mirror.hpp": { + "sha256": "a9b2eae6cbcab2b26a9ab6ba2463086f03857f5c52aae5c83b9ea5ccd5dd5444", + "git_blob": "3d23478be41bb88c08e5c54fa40e71547455c2a9" + }, + "pineforge/pineforge.h": { + "sha256": "1e0def60e31f529dcb821502c0f7104b473c06be0fa1df713be0f408e04e9288", + "git_blob": "232cd6c66d3f6e6ffdcffdf246e6a9dcce3ef3f8" + }, + "pineforge/position_close_obligation.hpp": { + "sha256": "6f6ad0aaca952dda7a9386cb78e57705b3494364dbd8970b0a051fe99d05b777", + "git_blob": "09576ee0f2a1d49becc46f5701f4369cf8f87bf6" + }, + "pineforge/quantity_intent.hpp": { + "sha256": "c4cc0f1cd5d6ed1f248825712a5ba4b4f5a808b787c05c58971934b89d770b90", + "git_blob": "41262fee5aa2db4032fc008542c573032563629b" + }, + "pineforge/series.hpp": { + "sha256": "e7709f67df9046c9eba163c2dbe91f8161084a955265ccf6b163355856c0afde", + "git_blob": "61baaef2c351d37b0d6a5eb179e91ce670eb83c3" + }, + "pineforge/session_time.hpp": { + "sha256": "f58c94bfae948e08fa21e52f20eae3940b31e398d83b800baf3a31f3a5fde669", + "git_blob": "af3a4472d852e0965947c006d0b6ad85304539e7" + }, + "pineforge/timeframe.hpp": { + "sha256": "5e4c312da463fdcff55e0887188523c8bbf85a2ae62f3317a2b23f22fe0161e2", + "git_blob": "3d1bc9d495ac7e5b39ea5bae57c9d9afe580192b" + } + } +} diff --git a/tests/fixtures/script_cpp_abi/growthbf312/README.md b/tests/fixtures/script_cpp_abi/growthbf312/README.md new file mode 100644 index 0000000..13c3906 --- /dev/null +++ b/tests/fixtures/script_cpp_abi/growthbf312/README.md @@ -0,0 +1 @@ +Exact unshipped growth tree bf312 header closure: engine v6 with unversioned standalone reservation types. This is a draft ABI negative control, not a released ff54 definition. Compile/link controls only; no executable runs. diff --git a/tests/fixtures/script_cpp_abi/growthbf312/headers.json.gz b/tests/fixtures/script_cpp_abi/growthbf312/headers.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..62fac8df891dedf6c51cbc1ae9389a484d8f1c99 GIT binary patch literal 144048 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%0DxkL$p?(kT;X+)lZ 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 GWd{J__jFqT literal 0 HcmV?d00001 diff --git a/tests/fixtures/script_cpp_abi/growthbf312/manifest.json b/tests/fixtures/script_cpp_abi/growthbf312/manifest.json new file mode 100644 index 0000000..f9c7c32 --- /dev/null +++ b/tests/fixtures/script_cpp_abi/growthbf312/manifest.json @@ -0,0 +1,94 @@ +{ + "source_commit": "ff54a557ac751244dafd60df0bb22886ec35792d", + "source_tree": "bf312b9d5a705d3d0ca16d4fb897e16c6e73b0d1", + "internal_namespace": "engine_script_run_v6", + "archive": "headers.json.gz", + "archive_sha256": "7a585b1e66020b516d73e75bd763473ecb6248f51073ddd1cb2f16cf83c4d331", + "generated_dependency": "pineforge/version.h comes from the matching current configure; no frozen layout uses its value.", + "files": { + "pineforge/bar.hpp": { + "sha256": "665c2528dca64ac9474de622dfd7ffdb540ff91316f70317e39aada158d1e0de", + "git_blob": "836f73daab382e9c8d5a6d03a942a921e39b756f" + }, + "pineforge/broker_events.hpp": { + "sha256": "4f3d9948a4d1604750901fa3982d6ea49bd50dd15a86c4e5d690b83d1f5f23c0", + "git_blob": "2972d53c7b039af266f4da161301c01eec54c16d" + }, + "pineforge/compat/pine/exit_activation.hpp": { + "sha256": "c6a538e6dfc5c0e70f434e92e0d8329b40ffc7e87051ae2d1d9754d9db8c9a6d", + "git_blob": "5024b013c36df956cef1d77db067a68284067322" + }, + "pineforge/compat/pine/intraday_cap.hpp": { + "sha256": "0ac0eab34625ab9a974037ff8c0217603a01deb81599350a4b24f7bf48ac0cbd", + "git_blob": "0aba76b6a78251df33e92f19290473adecf5a61e" + }, + "pineforge/compat/pine/intraday_order_budget.hpp": { + "sha256": "43f7700f9c66c630ab8a9d8fd899eecb03c2fd9aabff11d2dc2b7fa85f92981b", + "git_blob": "730d941fffa3939e375489f40a50901ccea9ec87" + }, + "pineforge/compat/pine/order_birth.hpp": { + "sha256": "db379949112f0cd363fba4aecc5f7ad952f7c3eea0eec0425bcc3367dd4505b9", + "git_blob": "b57ffe0eba7bd10b4e0588e48ef8fa8e82b629ae" + }, + "pineforge/compat/pine/order_priority.hpp": { + "sha256": "0e77af11357cf9b2e3255ef2ef871ac0cd319b6548568c549f64c2598115f4d9", + "git_blob": "86aac9629e40ad19b7308468e95389598a9436e2" + }, + "pineforge/engine.hpp": { + "sha256": "381a18d59f20ff94c6eed9dec40497fdaa175637fc96169a0a9875a38b071736", + "git_blob": "40cece96402fae406e0f6c8d92d051fa232d2c18" + }, + "pineforge/leg_activation.hpp": { + "sha256": "859d75d0ae90ec3cc109765da066b37c3bbbff9c7c840368fbdd05dc7e178f3f", + "git_blob": "4160c841782800853bb574219b3dad2ca8aa0cc6" + }, + "pineforge/magnifier.hpp": { + "sha256": "c0ed220b6df054b44596a434d4f48b1c3e960ca329bb8644a405a608175e06ff", + "git_blob": "1bbc910a869d162900d7610fa0bd9a88776b7b0f" + }, + "pineforge/na.hpp": { + "sha256": "0e8c256fcdeda94a0855458fa3b8c4ad4f9864dc2aecce969934f6bea82fd0a5", + "git_blob": "e98505aadc68a09cbe5a14aacf591a799a15ecd2" + }, + "pineforge/order_birth.hpp": { + "sha256": "0eadb3e2a92248fbc8e6ba8f94285b15b0e83d7a0396f5904b40c216619604e4", + "git_blob": "ed4a4038e9d079c92b4ebd777a5f22f1f1256b0c" + }, + "pineforge/order_priority.hpp": { + "sha256": "25bb7898972153b044675245db230c1171644856ef904f4dd02353b8968d433b", + "git_blob": "3e9fa5ee4121971a7962db8a60859aba6fb9ec95" + }, + "pineforge/pending_order_mirror.hpp": { + "sha256": "5c1daae5baefd4a442f463aed61844fac98a07837525bd1a538731c732236051", + "git_blob": "20358bf3d878b8c431deaa12c833d0f9ec77482b" + }, + "pineforge/pineforge.h": { + "sha256": "1e0def60e31f529dcb821502c0f7104b473c06be0fa1df713be0f408e04e9288", + "git_blob": "232cd6c66d3f6e6ffdcffdf246e6a9dcce3ef3f8" + }, + "pineforge/position_close_obligation.hpp": { + "sha256": "6f6ad0aaca952dda7a9386cb78e57705b3494364dbd8970b0a051fe99d05b777", + "git_blob": "09576ee0f2a1d49becc46f5701f4369cf8f87bf6" + }, + "pineforge/quantity_intent.hpp": { + "sha256": "c4cc0f1cd5d6ed1f248825712a5ba4b4f5a808b787c05c58971934b89d770b90", + "git_blob": "41262fee5aa2db4032fc008542c573032563629b" + }, + "pineforge/reservation_expansion.hpp": { + "sha256": "24f5dc4ea210032d3005578515813a2f69b6bc48beb1415156792684904b17c7", + "git_blob": "039d0a06b173949f0e9703189bae805ad065fedb" + }, + "pineforge/series.hpp": { + "sha256": "e7709f67df9046c9eba163c2dbe91f8161084a955265ccf6b163355856c0afde", + "git_blob": "61baaef2c351d37b0d6a5eb179e91ce670eb83c3" + }, + "pineforge/session_time.hpp": { + "sha256": "f58c94bfae948e08fa21e52f20eae3940b31e398d83b800baf3a31f3a5fde669", + "git_blob": "af3a4472d852e0965947c006d0b6ad85304539e7" + }, + "pineforge/timeframe.hpp": { + "sha256": "5e4c312da463fdcff55e0887188523c8bbf85a2ae62f3317a2b23f22fe0161e2", + "git_blob": "3d1bc9d495ac7e5b39ea5bae57c9d9afe580192b" + } + } +} diff --git a/tests/reservation_expansion_test_access.hpp b/tests/reservation_expansion_test_access.hpp new file mode 100644 index 0000000..53f96f7 --- /dev/null +++ b/tests/reservation_expansion_test_access.hpp @@ -0,0 +1,100 @@ +#pragma once +#include +#include +#include +#include +#include + +namespace pineforge { +void fill_pending_order_mirror(const PendingOrder&, pf_pending_order_v1_t*); +const pf_field_desc_t* pending_order_layout(int*); +} + +namespace reservation_test { +// Literal white-box tests at the existing native checkpoints, with no product +// test export, changed access specifier, or altered class definition. Explicit +// template instantiation can name a private member (C++ [temp.explicit]). +template struct Access { + friend auto access(Tag) { return Member; } +}; +#define CHECKPOINT(Tag, method) \ + struct Tag { friend auto access(Tag); }; \ + template struct Access +CHECKPOINT(Dispatch, apply_filled_order_to_state); +CHECKPOINT(Compact, compact_filled_pending_orders); +CHECKPOINT(Reduce, reduce_oca_group); +CHECKPOINT(CancelGroup, cancel_oca_group); +CHECKPOINT(Flat, reset_position_state_to_flat); +CHECKPOINT(Open, open_fresh_position); +CHECKPOINT(Revive, revive_position_brackets_after_margin_call_partial); +#undef CHECKPOINT + +using namespace pineforge; +constexpr double missing = std::numeric_limits::quiet_NaN(); +class Book : public BacktestEngine { +public: + Book() { + initial_capital_=100000; commission_value_=0; margin_long_=margin_short_=0; + pyramiding_=20; process_orders_on_close_=true; qty_step_=std::ldexp(1.0,-32); + current_bar_={100,100,100,100,1,0}; next_position_cycle_seq_=7; + next_order_incarnation_=40; + } + void on_bar(const Bar&) override {} + std::vector retired; + double trail=missing; int closed_bar=-1; uint64_t closed_id=0; bool was_long=false; + PendingOrder& get(const std::string& id) { + for(auto& o:pending_orders_) if(o.id==id) return o; + throw std::logic_error("missing " + id); + } + bool has(const std::string& id)const { + for(auto& o:pending_orders_) if(o.id==id) return true; + return false; + } + const std::vector& book()const{return pending_orders_;} + void add(const char* id,double qty=2,bool is_long=true,const char* group="",int oca=0) { + strategy_entry(id,is_long,missing,missing,qty,"",group,oca); + } + void priced(const char* id) {strategy_entry(id,true,120,missing,2);} + void raw(const char* id,double qty=2,bool is_long=true,const char* group="",int oca=0) { + strategy_order(id,is_long,qty,missing,missing,group,oca); + } + void exit(const char* id="E",double units=missing,const char* group="",double percent=100, + const char* binding="",double stop=90) { + strategy_exit(id,binding,120,stop,missing,missing,missing,percent,"",units,group); + } + void inert(const char* id="E") {strategy_exit(id,"",missing,missing);} + void cancel(const char* id){strategy_cancel(id);} + void cancel_all(){strategy_cancel_all();} + void advance(){++bar_index_; current_bar_.timestamp=bar_index_*60000LL;} + void step(){process_pending_orders(current_bar_);} + void fire(const char* id,bool compact=true) { + size_t i=0; while(i*access(Dispatch{}))(i,100,false,current_bar_,trail,closed_bar,closed_id,was_long,retired,false); + if(compact) finish(); + } + void finish() { + (this->*access(Compact{}))(retired,closed_bar,closed_id,was_long); + retired.clear();closed_bar=-1;closed_id=0;was_long=false; + } + void reduce(const char* group,double qty){(this->*access(Reduce{}))(group,"",qty);} + void cancel_group(const char* group){(this->*access(CancelGroup{}))(group,"");} + void flatten(){(this->*access(Flat{}))();} + void open(bool is_long=true,double qty=10){(this->*access(Open{}))(is_long?PositionSide::LONG:PositionSide::SHORT,100,qty,"fresh",next_order_incarnation_++);} + void revive(double price){(this->*access(Revive{}))(price);} + void seed(double qty=10){add("seed",qty);fire("seed");advance();} + void standard(double requested=2,const char* source_group="",const char* exit_group="") { + seed();add("A",requested,true,source_group);next_order_incarnation_=50;exit("E",missing,exit_group); + } + void cap(int value){pyramiding_=value;} + void pooc(bool value){process_orders_on_close_=value;} + void halt(bool value){risk_halted_=value;} + void close_partial(double qty){strategy_close("seed","",qty,missing,true);} + void reset(){run(nullptr,0);} + void sort_book(){std::reverse(pending_orders_.begin(),pending_orders_.end());} + double quantity()const{return position_qty_;} + int64_t cycle()const{return position_cycle_seq_;} + uint64_t owner(const char* id="A"){return get(id).reservation_growth_source.reservation_owner().value_or(0);} + uint64_t closure(const char* id="E"){const auto& c=get(id).reservation_expansion.capture();return c?c->first_later_admission.value_or(0):0;} + bool live_all(const char* id="E"){return get(id).reservation_expansion.live_all(cycle(),position_side_);} +}; +} // namespace reservation_test diff --git a/tests/test_frozen_market_instruction.cpp b/tests/test_frozen_market_instruction.cpp new file mode 100644 index 0000000..a1a479e --- /dev/null +++ b/tests/test_frozen_market_instruction.cpp @@ -0,0 +1,328 @@ +// Literal native instruction and book transitions. No external data, reference +// trades, strategy compiler or campaign grading participates in this test. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace pineforge { +void fill_pending_order_mirror(const PendingOrder&, pf_pending_order_v1_t*); +const pf_field_desc_t* pending_order_layout(int*); +} + +namespace frozen_prefix { +#include "fixtures/frozen_market/ff54_pending_order_mirror.hpp" +} + +using namespace pineforge; +using compat::pine::FrozenMarketInstruction; +using compat::pine::FrozenMarketInstructionKind; +#define PF_PREFIX_FIELD(name) \ + static_assert(offsetof(pf_pending_order_v1_t, name) == \ + offsetof(frozen_prefix::pf_pending_order_v1_t, name), "frozen prefix offset"); \ + static_assert(std::is_same::value, "frozen prefix type"); \ + static_assert(sizeof(pf_pending_order_v1_t::name) == \ + sizeof(frozen_prefix::pf_pending_order_v1_t::name), "frozen prefix size"); +#include "fixtures/frozen_market/ff54_fields.inc" +#undef PF_PREFIX_FIELD +static_assert(offsetof(pf_pending_order_v1_t, pine_frozen_market_instruction_kind) >= + sizeof(frozen_prefix::pf_pending_order_v1_t), "preserve old trailing padding"); + +namespace { +const double nan = std::numeric_limits::quiet_NaN(); +const double inf = std::numeric_limits::infinity(); +int failures = 0; +#define CHECK(cond) do { if (!(cond)) { \ + std::fprintf(stderr, "FAIL %s:%d %s\n", __FILE__, __LINE__, #cond); ++failures; \ +} } while (0) + +template void invalid(Function make) { + try { make(); CHECK(false); } + catch (const std::invalid_argument&) {} +} + +pf_pending_order_v1_t mirror(const PendingOrder& order) { + pf_pending_order_v1_t result; + fill_pending_order_mirror(order, &result); + return result; +} + +void exclusive_instruction_and_revocation() { + FrozenMarketInstruction ordinary; + CHECK(ordinary.kind() == FrozenMarketInstructionKind::Ordinary); + CHECK(!ordinary.active() && !ordinary.transaction() && !ordinary.targeted_close()); + for (double own : {0.0, -1.0, nan, inf}) + invalid([&] { return FrozenMarketInstruction::transaction(own, 2); }); + for (double total : {0.0, 1.0, nan, -inf}) + invalid([&] { return FrozenMarketInstruction::transaction(2, total); }); + auto transaction = FrozenMarketInstruction::transaction(2, 5); + CHECK(transaction.active() && !transaction.targeted_close()); + CHECK(transaction.transaction()->own_units == 2); + CHECK(transaction.transaction()->transaction_units == 5); + transaction.revoke(); + CHECK(!transaction.active() && !transaction.transaction()); + transaction.revoke(); + CHECK(transaction.kind() == FrozenMarketInstructionKind::Ordinary); + + QuantityRequest request; + invalid([&] { return FrozenMarketInstruction::targeted_close("E", request); }); + request.request(QuantityIntent::all()); + invalid([&] { return FrozenMarketInstruction::targeted_close("E", request); }); + request.request(QuantityIntent::fraction(1, 2)); + invalid([&] { return FrozenMarketInstruction::targeted_close("E", request); }); + for (double units : {0.0, -1.0, nan, inf}) { + request.request(QuantityIntent::units(units)); + invalid([&] { return FrozenMarketInstruction::targeted_close("E", request); }); + } + request.request(QuantityIntent::units(3)); + invalid([&] { return FrozenMarketInstruction::targeted_close("", request); }); + auto close = FrozenMarketInstruction::targeted_close("E", request); + CHECK(close.kind() == FrozenMarketInstructionKind::TargetedClose); + CHECK(close.active() && !close.transaction()); + CHECK(close.targeted_close()->target_id == "E"); + request.reserve(1, 3); + CHECK(request.intent()->units() == 3); // Reservation does not change source units. + close.revoke(); + CHECK(!close.active() && !close.targeted_close()); +} + +class Book : public BacktestEngine { +public: + Book() { + initial_capital_ = 1000000; + default_qty_type_ = QtyType::FIXED; + default_qty_value_ = 1; + commission_value_ = 0; + margin_long_ = margin_short_ = 0; + pyramiding_ = 1; + bar_index_ = 0; + current_bar_ = {100, 100, 100, 100, 1, 0}; + } + void on_bar(const Bar&) override {} + void entry(const std::string& id, bool buy, double units) { + strategy_entry(id, buy, nan, nan, units); + } + void step() { + ++bar_index_; + current_bar_ = {100, 100, 100, 100, 1, int64_t(bar_index_) * 60000}; + process_pending_orders(current_bar_); + } + void seed(bool buy, double units) { entry("seed", buy, units); step(); } + void close_seed() { strategy_close("seed"); } + void cancel(const std::string& id) { strategy_cancel(id); } + void finalize() { compat::pine::finalize_frozen_market_book(pending_orders_, true); } + + void priced() { strategy_entry("priced", true, 90, nan, 1); } + void raw() { strategy_order("raw", true, 1); } + void bracket() { strategy_exit("bracket", "A", 120, 90); } + void close_all() { strategy_close_all(); } + void leave_scope() { compat::pine::finalize_frozen_market_book(pending_orders_, false); } + double position() const { return position_qty_; } + PositionSide side() const { return position_side_; } + const std::vector& orders() const { return pending_orders_; } + PendingOrder& order(const std::string& id) { + for (auto& o : pending_orders_) if (o.id == id) return o; + std::string present; + for (const auto& o : pending_orders_) present += " " + o.id; + throw std::logic_error("missing literal order " + id + "; present:" + present); + } + void put(PendingOrder order) { pending_orders_.push_back(std::move(order)); } +}; + +void capture_amounts_and_immutable_placement() { + for (bool seed_buy : {false, true}) { + Book book; book.seed(seed_buy, 3); + CHECK(book.position() == 3); + book.entry("opposite", !seed_buy, 2); + const auto& first = book.order("opposite"); + CHECK(first.pine_frozen_market_instruction.transaction()->own_units == 2); + CHECK(first.pine_frozen_market_instruction.transaction()->transaction_units == 5); + CHECK(!mirror(first).sbmt_kept_over_cap); + book.entry("same", seed_buy, 4); + const auto& retained = book.order("same"); + CHECK(retained.pine_frozen_market_instruction.transaction()->own_units == 4); + CHECK(retained.pine_frozen_market_instruction.transaction()->transaction_units == 6); + CHECK(retained.over_pyramiding_cap_at_placement); + CHECK(mirror(retained).sbmt_kept_over_cap == 1); + const auto old_incarnation = book.order("opposite").incarnation; + book.entry("opposite", !seed_buy, 5); + const auto& replacement = book.order("opposite"); + CHECK(replacement.incarnation != old_incarnation); + CHECK(replacement.replaced_order_incarnation == old_incarnation); + // Own 5 + held opposite 3 + pending opposite's own 4, never its total 6. + CHECK(replacement.pine_frozen_market_instruction.transaction()->own_units == 5); + CHECK(replacement.pine_frozen_market_instruction.transaction()->transaction_units == 12); + CHECK(replacement.created_position_side == (seed_buy ? PositionSide::LONG : PositionSide::SHORT)); + book.finalize(); + CHECK(book.order("same").pine_frozen_market_instruction.active()); + CHECK(mirror(book.order("same")).sbmt_kept_over_cap == 1); + } +} + +void targeted_close_has_one_quantity_authority() { + for (bool buy : {false, true}) { + Book book; book.seed(buy, 3); book.close_seed(); + auto& close = book.order("__close__seed"); + CHECK(close.pine_frozen_market_instruction.targeted_close()->target_id == "seed"); + CHECK(!close.pine_frozen_market_instruction.transaction()); + CHECK(close.quantity_request.intent()->units() == 3); + const auto before = mirror(close); + CHECK(before.sbmt_member == 1 && before.sbmt_close_qty == 3); + CHECK(before.sbmt_close_buy == (buy ? 0 : 1)); + CHECK(!before.sbmt_kept_over_cap && std::isnan(before.sbmt_tx_qty)); + close.quantity_request.reserve(1, 3); + close.qty = 1; // Execution reservation differs; original close still resolves to 3. + CHECK(mirror(close).sbmt_close_qty == 3); + CHECK(close.quantity_request.reservation()->units == 1); + book.step(); + CHECK(book.position() == 0); + CHECK(book.orders().empty()); + book.entry("fresh", !buy, 2); + CHECK(book.order("fresh").pine_frozen_market_instruction.transaction()->own_units == 2); + CHECK(book.order("fresh").pine_frozen_market_instruction.transaction()->transaction_units == 2); + } +} + +void whole_book_revocation() { + using Add = void (Book::*)(); + for (Add add : {&Book::priced, &Book::raw, &Book::bracket, &Book::leave_scope}) { + Book book; book.entry("A", true, 2); book.entry("B", false, 3); + (book.*add)(); book.finalize(); + CHECK(book.orders().size() >= 2); + for (const auto& order : book.orders()) { + CHECK(!order.pine_frozen_market_instruction.active()); + const auto legacy = mirror(order); + CHECK(!legacy.sbmt_member && !legacy.sbmt_kept_over_cap && !legacy.sbmt_close_buy); + CHECK(std::isnan(legacy.sbmt_own_qty) && std::isnan(legacy.sbmt_tx_qty)); + CHECK(std::isnan(legacy.sbmt_close_qty)); + } + } + Book third; third.entry("A", true, 1); third.entry("B", false, 2); + third.entry("C", true, 3); third.finalize(); + CHECK(third.orders().size() == 3); + for (const auto& order : third.orders()) CHECK(!order.pine_frozen_market_instruction.active()); + Book all; all.seed(true, 3); all.entry("A", false, 1); all.close_all(); all.finalize(); + for (const auto& order : all.orders()) CHECK(!order.pine_frozen_market_instruction.active()); + // The generic cap snapshot alone never creates the removed retention permit. + PendingOrder ordinary{}; ordinary.over_pyramiding_cap_at_placement = true; + CHECK(!mirror(ordinary).sbmt_kept_over_cap); +} + +void cancellation_recreation_and_noop() { + Book book; book.entry("A", true, 2); book.entry("B", false, 3); + const auto cancelled = book.order("B").incarnation; + book.cancel("B"); book.entry("B", false, 4); + const auto& fresh = book.order("B"); + CHECK(fresh.incarnation != cancelled); + // That separate receipt only records a priced-entry cancel with a + // surviving exit. A MARKET cancellation must not borrow such a receipt. + CHECK(fresh.recreated_after_named_cancelled_entry_incarnation == 0); + CHECK(fresh.pine_frozen_market_instruction.transaction()->own_units == 4); + CHECK(fresh.pine_frozen_market_instruction.transaction()->transaction_units == 6); + book.cancel("A"); book.cancel("B"); + CHECK(book.orders().empty()); + book.close_seed(); // No position/owner: no close payload or permit is created. + CHECK(book.orders().empty()); + book.entry("B", false, 1); + CHECK(book.order("B").pine_frozen_market_instruction.transaction()->transaction_units == 1); + book.cancel("B"); book.priced(); + CHECK(!book.order("priced").pine_frozen_market_instruction.active()); +} + +void hash_and_mirror_live_facts() { + Book base; PendingOrder order{}; order.id = "M"; + base.put(order); + const auto empty_hash = base.broker_state_hash(); + Book transaction = base; + transaction.order("M").pine_frozen_market_instruction = FrozenMarketInstruction::transaction(2, 5); + const auto tx_hash = transaction.broker_state_hash(); + CHECK(tx_hash != empty_hash); + auto tx = mirror(transaction.order("M")); + CHECK(tx.pine_frozen_market_instruction_kind == 1); + CHECK(tx.pine_frozen_market_instruction_own_units == 2 && tx.sbmt_own_qty == 2); + CHECK(tx.pine_frozen_market_instruction_transaction_units == 5 && tx.sbmt_tx_qty == 5); + CHECK(std::strcmp(tx.pine_frozen_market_instruction_target_id, "") == 0); + for (auto amounts : {std::pair{3, 5}, {2, 6}}) { + Book changed = transaction; + changed.order("M").pine_frozen_market_instruction = FrozenMarketInstruction::transaction(amounts.first, amounts.second); + CHECK(changed.broker_state_hash() != tx_hash); + } + transaction.order("M").pine_frozen_market_instruction.revoke(); + CHECK(transaction.broker_state_hash() == empty_hash); + + Book close = base; + auto& c = close.order("M"); + c.type = OrderType::EXIT; + c.created_position_side = PositionSide::SHORT; + c.quantity_request.request(QuantityIntent::units(3)); + const std::string target(90, 'x'); + c.pine_frozen_market_instruction = FrozenMarketInstruction::targeted_close(target, c.quantity_request); + const auto close_hash = close.broker_state_hash(); + auto cm = mirror(c); + CHECK(cm.pine_frozen_market_instruction_kind == 2); + CHECK(cm.pine_frozen_market_instruction_target_id_truncated == 1); + CHECK(std::strlen(cm.pine_frozen_market_instruction_target_id) == 63); + uint64_t expected = 1469598103934665603ULL; + for (unsigned char ch : target) { expected ^= ch; expected *= 1099511628211ULL; } + CHECK(cm.pine_frozen_market_instruction_target_id_hash64 == expected); + Book changed = close; + changed.order("M").pine_frozen_market_instruction = FrozenMarketInstruction::targeted_close(target + "y", c.quantity_request); + CHECK(changed.broker_state_hash() != close_hash); + CHECK(mirror(changed.order("M")).pine_frozen_market_instruction_target_id_hash64 != expected); + changed = close; changed.order("M").quantity_request.request(QuantityIntent::units(4)); + CHECK(changed.broker_state_hash() != close_hash); + changed = close; changed.order("M").created_position_side = PositionSide::LONG; + CHECK(changed.broker_state_hash() != close_hash && !mirror(changed.order("M")).sbmt_close_buy); + c.pine_frozen_market_instruction.revoke(); + cm = mirror(c); + CHECK(!cm.sbmt_member && !cm.sbmt_close_buy && std::isnan(cm.sbmt_close_qty)); + CHECK(cm.pine_frozen_market_instruction_kind == 0 && !cm.pine_frozen_market_instruction_target_id[0]); + + int count = 0; + const auto* layout = pending_order_layout(&count); + CHECK(count == 155); + CHECK(std::strcmp(layout[149].name, "pine_frozen_market_instruction_kind") == 0); +} + +void overflowed_total_retains_existing_finite_execution_guard() { + Book book; book.entry("M", true, 2); + auto& order = book.order("M"); + order.pine_frozen_market_instruction = FrozenMarketInstruction::transaction(2, inf); + CHECK(order.pine_frozen_market_instruction.active()); + CHECK(std::isinf(mirror(order).sbmt_tx_qty)); + double qty = 0; int close_only = -1, partition = -1; + CHECK(book.probe_fill_qty(0, 100, &qty, &close_only, &partition) == 0); + CHECK(qty == 2 && partition == 0 && close_only == 0); + // Positive source-total overflow cannot enable the expanded-transaction arm. + book.step(); + CHECK(book.position() == 2 && book.side() == PositionSide::LONG); +} +} // namespace + +int main() { + const std::pair cases[] = { + {"exclusive operation", exclusive_instruction_and_revocation}, + {"capture and placement", capture_amounts_and_immutable_placement}, + {"target quantity", targeted_close_has_one_quantity_authority}, + {"whole book revocation", whole_book_revocation}, + {"cancel and recreate", cancellation_recreation_and_noop}, + {"hash and mirror", hash_and_mirror_live_facts}, + {"overflow total", overflowed_total_retains_existing_finite_execution_guard}, + }; + for (const auto& item : cases) { + try { item.second(); } + catch (const std::exception& error) { + std::fprintf(stderr, "FAIL %s: %s\n", item.first, error.what()); + ++failures; + } + } + std::printf("frozen market instruction: %d failure(s)\n", failures); + return failures ? 1 : 0; +} diff --git a/tests/test_live_order_derived.cpp b/tests/test_live_order_derived.cpp index 1f242d6..75d08d5 100644 --- a/tests/test_live_order_derived.cpp +++ b/tests/test_live_order_derived.cpp @@ -365,7 +365,7 @@ void test_sbmt_kernels() { CHECK(i >= 0); if (i >= 0) { const PendingOrder& o = s.pending_order_at(i); - CHECK(o.sbmt_member && near(o.sbmt_tx_qty, 2.0) && near(o.sbmt_own_qty, 1.0)); + CHECK(o.pine_frozen_market_instruction.active() && near(o.pine_frozen_market_instruction.transaction()->transaction_units, 2.0) && near(o.pine_frozen_market_instruction.transaction()->own_units, 1.0)); CHECK(s.probe_fill_qty(i, 100.0, &qty, &close_only, &partition) == 0); CHECK(near(qty, 1.0) && partition == kFrozenPlacement && close_only == 0); } @@ -378,7 +378,7 @@ void test_sbmt_kernels() { CHECK(i >= 0); if (i >= 0) { const PendingOrder& o = s.pending_order_at(i); - CHECK(o.sbmt_member && near(o.sbmt_tx_qty, 2.0)); + CHECK(o.pine_frozen_market_instruction.active() && near(o.pine_frozen_market_instruction.transaction()->transaction_units, 2.0)); CHECK(s.probe_fill_qty(i, 100.0, &qty, &close_only, &partition) == 0); CHECK(near(qty, 0.0) && partition == kFrozenPlacement && close_only == 1); } @@ -391,7 +391,7 @@ void test_sbmt_kernels() { CHECK(i >= 0); if (i >= 0) { const PendingOrder& o = s.pending_order_at(i); - CHECK(o.sbmt_member && o.sbmt_kept_over_cap && near(o.sbmt_tx_qty, 2.0)); + CHECK(o.pine_frozen_market_instruction.active() && (o.pine_frozen_market_instruction.transaction() && o.over_pyramiding_cap_at_placement) && near(o.pine_frozen_market_instruction.transaction()->transaction_units, 2.0)); CHECK(s.probe_fill_qty(i, 100.0, &qty, &close_only, &partition) == 0); CHECK(near(qty, 2.0) && partition == kFrozenPlacement && close_only == 0); } @@ -399,7 +399,7 @@ void test_sbmt_kernels() { const int j = find_market(s, "Short", false); CHECK(j >= 0); if (j >= 0) { - CHECK(near(s.pending_order_at(j).sbmt_tx_qty, 2.0)); + CHECK(near(s.pending_order_at(j).pine_frozen_market_instruction.transaction()->transaction_units, 2.0)); CHECK(s.probe_fill_qty(j, 100.0, &qty, &close_only, &partition) == 0); CHECK(near(qty, 1.0) && partition == kFrozenPlacement && close_only == 0); } @@ -414,8 +414,8 @@ void test_sbmt_kernels() { const int j = find_market(s, "Short", false); CHECK(i >= 0 && j >= 0); if (i >= 0 && j >= 0) { - CHECK(near(s.pending_order_at(i).sbmt_tx_qty, 1.0)); - CHECK(near(s.pending_order_at(j).sbmt_tx_qty, 2.0)); + CHECK(near(s.pending_order_at(i).pine_frozen_market_instruction.transaction()->transaction_units, 1.0)); + CHECK(near(s.pending_order_at(j).pine_frozen_market_instruction.transaction()->transaction_units, 2.0)); CHECK(s.probe_fill_qty(i, 100.0, &qty, &close_only, &partition) == 0); CHECK(near(qty, 1.0) && partition == kAtFill && close_only == 0); CHECK(s.probe_fill_qty(j, 100.0, &qty, &close_only, &partition) == 0); diff --git a/tests/test_live_state_hash.cpp b/tests/test_live_state_hash.cpp index f32af26..5858efa 100644 --- a/tests/test_live_state_hash.cpp +++ b/tests/test_live_state_hash.cpp @@ -353,9 +353,12 @@ class Probe final : public BacktestEngine { s.pending_orders_[0].over_pyramiding_cap_at_placement = !s.pending_orders_[0].over_pyramiding_cap_at_placement; }}, - {"pending_orders_[].sbmt_member", [](Probe& s) { - if (!s.pending_orders_.empty()) - s.pending_orders_[0].sbmt_member = !s.pending_orders_[0].sbmt_member; + {"pending_orders_[].pine_frozen_market_instruction", [](Probe& s) { + if (!s.pending_orders_.empty()) { + auto& instruction = s.pending_orders_[0].pine_frozen_market_instruction; + if (instruction.active()) instruction.revoke(); + else instruction = PineFrozenMarketInstruction::transaction(1, 2); + } }}, {"pending_orders_[].short_seed_collision_role", [](Probe& s) { if (!s.pending_orders_.empty()) @@ -443,17 +446,13 @@ class Probe final : public BacktestEngine { if (!s.pending_orders_.empty()) s.pending_orders_[0].explicit_flat_admission_candidate = !s.pending_orders_[0].explicit_flat_admission_candidate; }}, - {"pending_orders_[].pooc_global_full_exit_dynamic_qty", [](Probe& s) { - if (!s.pending_orders_.empty()) - s.pending_orders_[0].pooc_global_full_exit_dynamic_qty = !s.pending_orders_[0].pooc_global_full_exit_dynamic_qty; - }}, - {"pending_orders_[].pooc_global_full_exit_tracks_bound_adds", [](Probe& s) { + {"pending_orders_[].reservation_expansion", [](Probe& s) { if (!s.pending_orders_.empty()) - s.pending_orders_[0].pooc_global_full_exit_tracks_bound_adds = !s.pending_orders_[0].pooc_global_full_exit_tracks_bound_adds; + s.pending_orders_[0].reservation_expansion.capture(50,7,PositionSide::LONG,10); }}, - {"pending_orders_[].pooc_global_full_exit_bound_add", [](Probe& s) { + {"pending_orders_[].reservation_growth_source", [](Probe& s) { if (!s.pending_orders_.empty()) - s.pending_orders_[0].pooc_global_full_exit_bound_add = !s.pending_orders_[0].pooc_global_full_exit_bound_add; + s.pending_orders_[0].reservation_growth_source.assign_capture(41,50); }}, {"pending_orders_[].signal_close_mc_remaining_qty", [](Probe& s) { if (!s.pending_orders_.empty()) s.pending_orders_[0].signal_close_mc_remaining_qty = 424242.5; diff --git a/tests/test_pine_transaction_settlement.cpp b/tests/test_pine_transaction_settlement.cpp new file mode 100644 index 0000000..9443104 --- /dev/null +++ b/tests/test_pine_transaction_settlement.cpp @@ -0,0 +1,151 @@ +// Literal settlement controls for the existing Pine source interpretation. +// These commands intentionally exercise the Pine close-artifact contract; +// they do not claim that a generic native reduction can open exposure. +#include +#include +#include +#include +#include +#include + +using namespace pineforge; +namespace { +int failures = 0; +#define CHECK(condition) do { if (!(condition)) { \ + std::fprintf(stderr, "FAIL %s:%d %s\n", __FILE__, __LINE__, #condition); \ + ++failures; } } while (0) + +class Book : public BacktestEngine { +public: + Book() { + initial_capital_ = 1000000; + default_qty_type_ = QtyType::FIXED; + default_qty_value_ = 1; + commission_value_ = 0; + slippage_ = 0; + margin_long_ = margin_short_ = 0; + pyramiding_ = 1; + bar_index_ = 0; + current_bar_ = {100, 100, 100, 100, 1, 0}; + } + void on_bar(const Bar&) override {} + void entry(const std::string& id, bool buy, double amount) { + const double nan = std::numeric_limits::quiet_NaN(); + strategy_entry(id, buy, nan, nan, amount); + } + void settle() { + ++bar_index_; + current_bar_ = {100, 100, 100, 100, 1, int64_t(bar_index_) * 60000}; + process_pending_orders(current_bar_); + } + void close_seed() { strategy_close("seed"); } + void change_close_reservation() { + for (auto& order : pending_orders_) { + if (order.id == "__close__seed") { + order.qty = 1; + order.quantity_request.reserve(1, 3); + return; + } + } + CHECK(false); + } + double signed_exposure() const { + return position_side_ == PositionSide::FLAT ? 0 + : position_side_ == PositionSide::LONG ? position_qty_ : -position_qty_; + } + uint64_t fills() const { return broker_fill_event_seq_; } + const std::vector& rows() const { return trades_; } + const std::vector& lots() const { return pyramid_entries_; } +}; + +void check_rows(const Book& book, const std::vector& ids, + const std::vector& amounts, bool seed_buy) { + CHECK(book.rows().size() == ids.size()); + if (book.rows().size() != ids.size()) return; + for (size_t i = 0; i < ids.size(); ++i) { + const auto& row = book.rows()[i]; + CHECK(row.entry_id == ids[i]); + CHECK(row.qty == amounts[i]); + CHECK(row.is_long == (i == 0 ? seed_buy : true)); + CHECK(row.entry_price == 100 && row.exit_price == 100); + CHECK(row.pnl == 0 && row.commission == 0); + CHECK(row.exit_bar_index == 2); + CHECK(row.entry_bar_index == (i == 0 ? 1 : 2)); + CHECK(row.entry_incarnation != 0); + if (i > 0) CHECK(row.entry_incarnation != book.rows()[0].entry_incarnation); + if (i > 1) CHECK((row.entry_incarnation == book.rows()[1].entry_incarnation) == seed_buy); + } +} + +void settle_batch(bool seed_buy, double seed, double opposite, double same, + bool close, bool alter_reservation = false) { + Book book; + book.entry("seed", seed_buy, seed); + book.settle(); + CHECK(book.signed_exposure() == (seed_buy ? seed : -seed)); + CHECK(book.rows().empty() && book.fills() == 1); + book.entry("opposite", !seed_buy, opposite); + book.entry("seed", seed_buy, same); + if (close) book.close_seed(); + // Explicit native reservation checkpoint: the original close Units stay3. + // This is not a claim that a Pine source call changes this reservation. + if (alter_reservation) book.change_close_reservation(); + book.settle(); + + // Buy-before-sell, frozen signed transaction quantities, and FIFO give + // these independent integer conservation results at the same price. + double expected = seed_buy ? same : -same; + if (close) expected = seed_buy ? same - seed + : -(same - std::min(seed, opposite)); + CHECK(book.signed_exposure() == expected); + CHECK(book.fills() == (close ? 4u : 3u)); + if (seed_buy) { + if (close) check_rows(book, {"seed", "seed", "seed"}, + {seed, opposite, seed}, true); + else check_rows(book, {"seed", "seed"}, {seed, opposite}, true); + } else { + if (close) check_rows(book, {"seed", "opposite", "__close__seed"}, + {seed, opposite, std::min(seed, opposite)}, false); + else check_rows(book, {"seed", "opposite"}, {seed, opposite}, false); + } + double lot_total = 0; + for (const auto& lot : book.lots()) lot_total += lot.qty; + CHECK(lot_total == std::abs(expected)); + std::printf("settlement side=%s seed=%.0f opposite=%.0f same=%.0f close=%d reserve=%d exposure=%.0f rows=%zu fills=%llu\n", + seed_buy ? "long" : "short", seed, opposite, same, close, + alter_reservation, book.signed_exposure(), book.rows().size(), + static_cast(book.fills())); + const auto row_count = book.rows().size(); + const auto fill_count = book.fills(); + book.settle(); + CHECK(book.signed_exposure() == expected); + CHECK(book.rows().size() == row_count && book.fills() == fill_count); +} + +void vanished_target_without_matching_entry_cannot_open_artifact() { + Book book; + book.entry("seed", false, 3); + book.settle(); + book.entry("opposite", true, 2); + book.entry("different", false, 4); + book.close_seed(); + book.settle(); + CHECK(book.signed_exposure() == -4); + CHECK(book.fills() == 3); + check_rows(book, {"seed", "opposite"}, {3, 2}, false); + for (const auto& lot : book.lots()) CHECK(lot.entry_id != "__close__seed"); +} +} // namespace + +int main() { + for (bool buy : {false, true}) { + settle_batch(buy, 1, 1, 1, false); + settle_batch(buy, 1, 1, 1, true); + settle_batch(buy, 3, 2, 4, false); + settle_batch(buy, 3, 2, 4, true); + } + settle_batch(false, 3, 2, 4, true, true); + vanished_target_without_matching_entry_cannot_open_artifact(); + std::printf("Pine transaction settlement: %d failure(s)\n", failures); + return failures ? 1 : 0; +} diff --git a/tests/test_pooc_global_full_exit.cpp b/tests/test_pooc_global_full_exit.cpp index 01f24f6..45991da 100644 --- a/tests/test_pooc_global_full_exit.cpp +++ b/tests/test_pooc_global_full_exit.cpp @@ -107,7 +107,7 @@ class ReservationProbe final : public BacktestEngine { for (const auto& order : pending_orders_) { if (order.type == OrderType::EXIT && order.id == "EXIT") { later_bar_exit_dynamic_qty_ = - order.pooc_global_full_exit_dynamic_qty; + order.reservation_expansion.population_open(); post_fill_exit_qty_ = order.qty; } if (order.type == OrderType::EXIT @@ -174,7 +174,7 @@ class ReservationProbe final : public BacktestEngine { exit_qty_ = order.qty; exit_qty_percent_ = order.qty_percent; exit_dynamic_qty_ = - order.pooc_global_full_exit_dynamic_qty; + order.reservation_expansion.population_open(); } } } diff --git a/tests/test_reservation_expansion.cpp b/tests/test_reservation_expansion.cpp new file mode 100644 index 0000000..a751dd1 --- /dev/null +++ b/tests/test_reservation_expansion.cpp @@ -0,0 +1,268 @@ +// Ten literal native contracts, derived from causal facts and integer/dyadic +// quantities. No canonical trades, tape, Pine/corpus, reference or grader. +#include "reservation_expansion_test_access.hpp" +#include +#include +#include +namespace prior_growth_mirror { +#include "fixtures/reservation_expansion/ff54_pending_order_mirror.hpp" +} +using namespace reservation_test; +namespace { +int checks=0,failures=0; +#define CHECK(x) do {++checks;if(!(x)){++failures;std::fprintf(stderr,"FAIL %d: %s\n",__LINE__,#x);}}while(0) +#define OLD_FIELD(name, type) static_assert(offsetof(pf_pending_order_v1_t,name)==offsetof(prior_growth_mirror::pf_pending_order_v1_t,name),"ff54 offset " #name); +#include "fixtures/reservation_expansion/ff54-fields.inc" +#undef OLD_FIELD +static_assert(offsetof(pf_pending_order_v1_t,reservation_expansion_position_cycle)>=sizeof(prior_growth_mirror::pf_pending_order_v1_t),"preserve ff54 trailing padding"); +void history(const PendingOrder& e,double units=10,double basis=10,bool partial=false) { + CHECK(e.quantity_request.reservation()); + if(!e.quantity_request.reservation())return; + CHECK(e.quantity_request.reservation()->units==units); + CHECK(e.quantity_request.reservation()->basis_units==basis); + CHECK(e.quantity_request.is_partial(1e-9,1e-9)==partial); +} +void capture_and_committed_growth() { + Book b;b.standard(3,"source"); + CHECK(b.owner()==50 && b.get("A").incarnation==41); + CHECK(b.get("E").reservation_expansion.capture()->position_cycle==7); + CHECK(b.get("E").reservation_expansion.capture()->side==PositionSide::LONG); + CHECK(b.live_all() && b.get("E").quantity_request.requests_all()); + // A requested 3. Native OCA reduces its executable capacity to 2 before + // dispatch; growth must consume committed delta, not the original request. + CHECK(b.get("A").qty==3);b.reduce("source",1);CHECK(b.get("A").qty==2); + b.fire("A");CHECK(b.quantity()==12 && b.get("E").qty==12);history(b.get("E")); + CHECK(b.live_all());b.close_partial(2);CHECK(b.quantity()==10);history(b.get("E")); + b.fire("E");CHECK(!b.has("E") && b.quantity()==0); + Book short_side;short_side.add("seed",10,false);short_side.fire("seed");short_side.advance(); + short_side.add("A",2,false);short_side.exit();CHECK(short_side.live_all()); + CHECK(short_side.get("E").reservation_expansion.capture()->side==PositionSide::SHORT); + short_side.fire("A");CHECK(short_side.quantity()==12 && short_side.get("E").qty==12); + ReservationGrowthSource invalid_source; + for(auto ids:std::vector>{{0,50},{41,0},{41,41}}) { + bool threw=false;try{invalid_source.assign_capture(ids.first,ids.second);}catch(const std::invalid_argument&){threw=true;}CHECK(threw); + } + ReservationExpansion invalid; + for(auto f:std::vector>{ + [&]{invalid.capture(0,7,PositionSide::LONG,10);}, + [&]{invalid.capture(50,0,PositionSide::LONG,10);}, + [&]{invalid.capture(50,7,PositionSide::FLAT,10);}, + [&]{invalid.capture(50,7,PositionSide::LONG,0);}, + [&]{invalid.close_population(0);}}) { + bool threw=false;try{f();}catch(const std::invalid_argument&){threw=true;}CHECK(threw); + } + invalid.capture(50,7,PositionSide::LONG,10); + bool threw=false;try{invalid.capture(50,8,PositionSide::LONG,10);}catch(const std::invalid_argument&){threw=true;}CHECK(threw); +} +void closure_is_causal() { + Book b;b.standard();b.add("B",4);const auto cause=b.get("B").incarnation; + CHECK(cause==51 && b.closure()==51 && !b.live_all()); + b.cancel("B");CHECK(b.closure()==51);b.fire("A");CHECK(b.get("E").qty==12); + b.add("C",4);CHECK(b.closure()==51);b.fire("C");CHECK(b.quantity()==16 && b.get("E").qty==12); + b.fire("E");CHECK(!b.has("E") && b.quantity()==4); + Book rejected;rejected.standard();rejected.cap(1);rejected.pooc(false);rejected.priced("B"); + CHECK(!rejected.has("B") && rejected.closure()==0 && rejected.live_all()); + Book declined;declined.standard();declined.add("B");auto first=declined.get("B").incarnation; + declined.halt(true);declined.fire("B");CHECK(!declined.has("B") && declined.closure()==first); + CHECK(declined.get("E").qty==10);declined.halt(false);declined.fire("A");CHECK(declined.get("E").qty==12); + for(bool raw:{false,true}) { + Book later;later.standard();later.advance(); + if(raw)later.raw("later");else later.priced("later"); + CHECK(later.closure()==later.get("later").incarnation); + later.cancel("later");CHECK(!later.live_all()); + } +} +void priority_is_not_identity() { + Book b;b.standard();const auto priority=b.get("A").created_seq; + CHECK(priorityposition_cycle==7); + CHECK(!b.live_all());b.open(true,20);CHECK(b.cycle()==8 && b.closure()==0 && !b.live_all()); + CHECK(b.get("E").leg_activation.bounds()->position_cycle==8); + b.fire("A");CHECK(b.quantity()==22 && b.get("E").qty==10); + b.fire("E");CHECK(b.quantity()==12 && !b.has("E")); // finite reservation still works + Book raw;raw.standard();raw.flatten();raw.raw("fresh",20);raw.fire("fresh");CHECK(raw.cycle()==8); + raw.fire("A");CHECK(raw.get("E").qty==10 && !raw.live_all()); + Book recaptured;recaptured.standard();recaptured.flatten();recaptured.open(true,20);recaptured.exit(); + CHECK(recaptured.get("E").reservation_expansion.capture()->position_cycle==8 && recaptured.live_all()); + // Source birth cycle 7 is not a Pine exclusion: intentional cycle-8 capture. + CHECK(recaptured.get("A").created_position_cycle_seq==7);recaptured.fire("A");CHECK(recaptured.get("E").qty==22); + Book retired;retired.standard();retired.retired.push_back(50);retired.fire("A",false); + CHECK(retired.has("E") && retired.get("E").qty==10 && retired.quantity()==12);retired.finish();CHECK(!retired.has("E")); + Book dormant;dormant.standard();dormant.get("E").dormant_bracket=true; + dormant.fire("E",false);CHECK(dormant.retired.empty() && dormant.live_all()); + dormant.fire("A");CHECK(dormant.get("E").qty==12 && dormant.get("E").dormant_bracket); + dormant.revive(100);CHECK(!dormant.get("E").dormant_bracket && dormant.live_all()); + dormant.fire("E");CHECK(dormant.quantity()==0 && !dormant.has("E")); + Book direct;direct.standard();direct.get("E").dormant_bracket=true;direct.revive(80); + CHECK(direct.quantity()==0 && !direct.has("E")); // direct revival close erases receiver + if(direct.has("A")){CHECK(direct.owner()==50);direct.fire("A");CHECK(!direct.has("E"));} + Book rearmed;rearmed.standard();rearmed.get("E").dormant_bracket=true;rearmed.exit(); + CHECK(rearmed.get("E").dormant_bracket && rearmed.get("E").dormant_reissue_pending); + CHECK(rearmed.owner()==rearmed.get("E").incarnation && rearmed.closure()==0); + rearmed.fire("A");CHECK(rearmed.get("E").qty==12); + Book copy;copy.standard();Book same=copy;CHECK(copy.broker_state_hash()==same.broker_state_hash()); + copy.reset();CHECK(copy.book().empty());CHECK(same.owner()==50 && same.live_all()); + copy.seed();copy.add("A");CHECK(copy.owner()==0); +} +void mirror_and_fingerprint() { + Book b;b.standard();pf_pending_order_v1_t m{};fill_pending_order_mirror(b.get("E"),&m); + CHECK(m.pooc_global_full_exit_dynamic_qty==1 && m.pooc_global_full_exit_tracks_bound_adds==1); + CHECK(m.reservation_expansion_present==1 && m.reservation_expansion_position_cycle==7 && m.reservation_expansion_side==1); + CHECK(m.reservation_expansion_first_later_admission_present==0 && m.reservation_expansion_first_later_admission==0); + b.add("B");fill_pending_order_mirror(b.get("E"),&m); + CHECK(m.pooc_global_full_exit_dynamic_qty==0 && m.reservation_expansion_first_later_admission_present==1 && m.reservation_expansion_first_later_admission==51); + b.cancel("E");fill_pending_order_mirror(b.get("A"),&m); + CHECK(m.pooc_global_full_exit_bound_add==1 && m.reservation_growth_source_present==1 && m.reservation_growth_source_reservation_owner==50); + fill_pending_order_mirror(b.get("B"),&m);CHECK(m.pooc_global_full_exit_bound_add==0 && m.reservation_growth_source_present==0 && m.reservation_growth_source_reservation_owner==0); + Book base;base.standard();base.add("B");const auto hash=base.broker_state_hash(); + const std::vector>> mutations={ + {"capture presence",[](Book& x){x.get("E").reservation_expansion={};}}, + {"cycle",[](Book& x){auto& c=x.get("E").reservation_expansion;c={};c.capture(50,8,PositionSide::LONG,10);c.close_population(51);}}, + {"side",[](Book& x){auto& c=x.get("E").reservation_expansion;c={};c.capture(50,7,PositionSide::SHORT,10);c.close_population(51);}}, + {"closure presence",[](Book& x){auto& c=x.get("E").reservation_expansion;c={};c.capture(50,7,PositionSide::LONG,10);}}, + {"closure incarnation",[](Book& x){auto& c=x.get("E").reservation_expansion;c={};c.capture(50,7,PositionSide::LONG,10);c.close_population(53);}}, + {"source presence",[](Book& x){x.get("A").reservation_growth_source={};}}, + {"source owner",[](Book& x){x.get("A").reservation_growth_source.assign_capture(41,52);}}, + }; + const char* mutation_fields[]={"reservation_expansion_present", "reservation_expansion_position_cycle", + "reservation_expansion_side", "reservation_expansion_first_later_admission_present", + "reservation_expansion_first_later_admission", "reservation_growth_source_present", + "reservation_growth_source_reservation_owner"}; + size_t mutation_index=0; + for(const auto& test:mutations){ + Book changed=base;test.second(changed);CHECK(changed.broker_state_hash()!=hash); + const char* id=mutation_index<5?"E":"A"; + pf_pending_order_v1_t before{},after{}; + fill_pending_order_mirror(base.get(id),&before);fill_pending_order_mirror(changed.get(id),&after); + int count=0;const auto* fields=pending_order_layout(&count);const pf_field_desc_t* field=nullptr; + for(int j=0;j(&before)+field->offset, + reinterpret_cast(&after)+field->offset,field->size)!=0); + ++mutation_index;std::printf("hash/mirror mutation: %s\n",test.first); + } + int n=0;const auto* layout=pending_order_layout(&n);CHECK(n==155); + int i=0; +#define OLD_FIELD(field, ctype) CHECK(std::strcmp(layout[i].name,#field)==0); CHECK(std::strcmp(layout[i].type,ctype)==0); CHECK(layout[i].offset==offsetof(prior_growth_mirror::pf_pending_order_v1_t,field)); ++i; +#include "fixtures/reservation_expansion/ff54-fields.inc" +#undef OLD_FIELD + CHECK(i==142); + const char* new_fields[]={"reservation_expansion_position_cycle","reservation_expansion_present","reservation_expansion_side","reservation_expansion_first_later_admission_present","reservation_expansion_first_later_admission","reservation_growth_source_present","reservation_growth_source_reservation_owner"}; + for(auto name:new_fields){CHECK(std::strcmp(layout[i].name,name)==0);CHECK(layout[i].offset>=sizeof(prior_growth_mirror::pf_pending_order_v1_t));++i;} + CHECK(strategy_pending_order_get(&base,0,&m,sizeof(m))==0); + std::vector bytes(sizeof(m)+8,0xA5); + CHECK(strategy_pending_order_get(&base,0,bytes.data(),sizeof(prior_growth_mirror::pf_pending_order_v1_t))==0); + CHECK(std::memcmp(bytes.data(),&m,sizeof(prior_growth_mirror::pf_pending_order_v1_t))==0); + for(size_t j=sizeof(prior_growth_mirror::pf_pending_order_v1_t);jkind()==QuantityIntent::Kind::Fraction); + const auto prior=fraction.get("E");fraction.exit();CHECK(fraction.get("E").incarnation!=prior.incarnation); + CHECK(fraction.get("E").quantity_request.requests_all() && !prior.quantity_request.requests_all()); + // Other selection exclusions, unchanged Pine ownership. + for(int kind=0;kind<5;++kind){Book x;x.seed();x.add("A"); + if(kind==0)x.pooc(false); + if(kind==1)x.get("A").over_pyramiding_cap_at_placement=true; + if(kind==2)x.get("A").is_long=false; + if(kind==3)x.get("A").created_position_side=PositionSide::SHORT; + if(kind==4)x.get("A").created_bar-=1; + x.exit();CHECK(!x.get("E").reservation_expansion.capture() && x.owner()==0); + } +} +} +int main(){ + const std::pair cases[]={ + {"1 capture/committed growth",capture_and_committed_growth},{"2 causal closure",closure_is_causal}, + {"3 priority versus incarnation",priority_is_not_identity},{"4 death/rearm/recapture",target_death_and_recapture}, + {"5 attempts/retirement",attempts_and_retirement},{"6 OCA capacity",oca_capacity_and_history}, + {"7 old/new multiple-tracker witness",multiple_tracker_witness},{"8 cycle/retirement/dormancy",cycle_retirement_and_dormancy}, + {"9 mirror/fingerprint",mirror_and_fingerprint},{"10 historical intent/selection",historical_quantity_and_selection}}; + for(auto test:cases){std::printf("contract: %s\n",test.first);try{test.second();}catch(const std::exception& e){++failures;std::fprintf(stderr,"FAIL contract %s: %s\n",test.first,e.what());}} + std::printf("%d checks, %d failures\n",checks,failures);return failures?1:0; +}