PineForge v1.4.0-4-g873b25da
Deterministic PineScript v6 backtest runtime — C ABI reference
Loading...
Searching...
No Matches
pine_quiet_bar.hpp
Go to the documentation of this file.
1#pragma once
2
3// R5 lane PERF-L4: the Pine adapter's quiet-bar gates.
4//
5// Every TradingView policy hook the adapter runs at a bar boundary is first
6// asked whether its body has anything to act on -- a live handle of the
7// family it handles, a queued command, a held position, an armed rule or
8// configuration -- and is not run when it has not. The gate sits at the
9// hook's per-bar call site (on_bar_open, on_bar_close, the host's source
10// publication), or at the top of a hook that is also reached elsewhere. Each
11// precondition is the hook's own logic restated as the condition under which
12// its body changes nothing and calls no kernel mutator, so a skipped hook
13// leaves the adapter, the kernel and every hash exactly as the body would
14// have. A gate never fires on an unbound adapter: the hook then refuses
15// through require_host() exactly as it always did.
16//
17// Two test-only switches build the witness's references
18// (tests/test_adapter_quiet_bar.cpp); the shipped library sets neither:
19// PINEFORGE_PINE_QUIET_BAR_GATES=0 compiles every gate out: the ungated
20// reference the differential row runs;
21// PINEFORGE_PINE_QUIET_BAR_PROBE=1 counts every gate decision per hook:
22// the cost and coverage rows.
23// Not part of the installed API.
24
25#include <cstddef>
26#include <cstdint>
27
28#ifndef PINEFORGE_PINE_QUIET_BAR_GATES
29#define PINEFORGE_PINE_QUIET_BAR_GATES 1
30#endif
31#ifndef PINEFORGE_PINE_QUIET_BAR_PROBE
32#define PINEFORGE_PINE_QUIET_BAR_PROBE 0
33#endif
34
36
37// One entry per gated hook, in the order a bar reaches them.
38enum class QuietHook : std::uint8_t {
39 ReceiptRead, // observe_terminal_receipts: no command above the cursor
40 DelayedRelease, // release_delayed_orders at the open: nothing delayed
41 L4cPriority, // update_l4c_priority at the open: no pair to rank
42 OpenMarketAdmission, // apply_open_market_admission: no entry of the prior bar
43 OpenMarketableSells, // defer_open_marketable_sells: no marketable stop-entry pair
44 GappedBracketReaccept, // reaccept_gapped_bracket_behind_same_id_add: no market add
45 DualEntryPath, // on_bar_open's flat two-stop arbitration: no touched pair
46 CoofTail, // flush_coof_tail at the open: nothing staged
47 CoofDeclinedReversal, // suspend_coof_declined_reversal_at_open: no reversal entry
48 DueCapClose, // execute_due_cap_close: no filled-orders cap close due
49 SlippedPoocMoney, // submit_slipped_pooc_opening_money_call: out of scope
50 TvMoneyLongMargin, // submit_tv_money_long_margin_call: out of scope
51 TvMoneyTrailMargin, // schedule_tv_money_long_margin_before_trail: out of scope
52 OpenMarginCheckpoints, // on_bar_open's open/path margin block: flat book
53 DeclinedReversalAtOpen, // declined_reversal_at_open: no reversal entry
54 IntradayLossClose, // submit_intraday_loss_close at the open: no loss rule
55 IntradayLossPath, // schedule_intraday_loss_path at the open: no loss rule
56 PreopenMarginSlice, // schedule_preopen_margin_slice: no default-percent opening
57 BracketLegs, // flush_pending_bracket_legs at publication: nothing staged
58 PendingCloses, // flush_pending_closes at publication: no close batch
59 PendingEntries, // flush_pending_entries at publication: nothing queued
60 RelativeExits, // anchor_relative_exits at publication: none queued
61 PoocLimitEntryFills, // flush_pooc_marketable_limit_entry_fills: no entry of this bar
62 PoocExitFills, // flush_pooc_marketable_exit_fills: no exit leg of this bar
63 DeferredSellAdmission, // admit_deferred_open_marketable_sells: none deferred
64 ThrottledReopens, // rearm_throttled_reopens at the close: none throttled
65 TerminalExplicitMarket, // apply_terminal_explicit_market_policy: no entry pair
66 CloseMarginCheckpoints, // on_bar_close's short checkpoints: out of scope
68};
69
70inline constexpr std::size_t kQuietHookCount = static_cast<std::size_t>(QuietHook::Count);
71
72#if PINEFORGE_PINE_QUIET_BAR_PROBE
73// Per hook: how often its gate was asked, and how often the answer was quiet.
74struct QuietBarCounts {
75 std::uint64_t asked[kQuietHookCount] = {};
76 std::uint64_t quiet[kQuietHookCount] = {};
77};
78QuietBarCounts& quiet_bar_counts() noexcept;
79#endif
80
81// True when the hook is skipped: `quiet` is the hook's exact no-op
82// precondition, evaluated where the hook would run.
83inline bool skip_quiet(QuietHook hook, bool quiet) noexcept {
84#if PINEFORGE_PINE_QUIET_BAR_PROBE
85 auto& counts = quiet_bar_counts();
86 ++counts.asked[static_cast<std::size_t>(hook)];
87 if (quiet) ++counts.quiet[static_cast<std::size_t>(hook)];
88#else
89 (void)hook;
90#endif
91 return PINEFORGE_PINE_QUIET_BAR_GATES != 0 && quiet;
92}
93
94} // namespace pineforge::source::detail
constexpr std::size_t kQuietHookCount
bool skip_quiet(QuietHook hook, bool quiet) noexcept
#define PINEFORGE_PINE_QUIET_BAR_GATES