PineForge v0.13.1-379-g9b50973
Deterministic PineScript v6 backtest runtime — C ABI reference
Loading...
Searching...
No Matches
intraday_order_budget.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <optional>
5#include <utility>
6
8
9// Identity supplied by the engine's existing risk clock, not an indicator's
10// possibly merged daily bar. This type deliberately does not select a clock.
11struct OrderRiskDay { int64_t key; };
12inline bool operator==(OrderRiskDay a, OrderRiskDay b) { return a.key == b.key; }
13inline bool operator!=(OrderRiskDay a, OrderRiskDay b) { return !(a == b); }
14
15// One counted, committed close can lend its quota slot to one designated
16// opposite order. The two operations still emit separate broker fill events,
17// FIFO rows and callbacks. A slot is never identified by a reusable Pine ID.
24
26
28public:
29 const std::optional<OrderRiskDay>& day() const { return day_; }
30 int charged_slots() const { return charged_slots_; }
31 bool latched() const { return latched_; }
32 const std::optional<CloseQuotaTransfer>& transfer() const { return transfer_; }
33
34 // Renew quota and retire its continuation atomically. A forced close due
35 // from the previous day has a separate lifetime and is not stored here.
37 if (day_ && *day_ == day) return;
38 day_ = day;
39 charged_slots_ = 0;
40 latched_ = false;
42 }
43 void latch() { if (day_) latched_ = true; }
44 void expire_transfer() { transfer_.reset(); }
45 void decline(uint64_t incarnation) {
46 if (transfer_ && transfer_->inheritor == incarnation) expire_transfer();
47 }
48 bool can_inherit(OrderRiskDay day, int bar, uint64_t incarnation,
49 uint64_t latest_committed_fill) const {
50 return transfer_ && day_ && *day_ == day && transfer_->day == day
51 && transfer_->source_bar == bar && incarnation != 0
52 && transfer_->inheritor == incarnation
53 && transfer_->close_fill == latest_committed_fill;
54 }
55
56 // The established policy charges a matched attempt BEFORE dispatch. It
57 // can charge a no-op; factor A filters only its proven MARKET subset at
58 // the caller. Do not silently reinterpret this as a committed-fill count.
59 // Both charging methods require the caller's positive configured limit.
61 uint64_t incarnation,
62 uint64_t latest_committed_fill) {
64 const bool inherited = can_inherit(day, bar, incarnation,
65 latest_committed_fill);
66 if (latched_ && !inherited) return QuotaAdmission::Blocked;
67 if (inherited) expire_transfer();
68 else ++charged_slots_;
69 return charged_slots_ >= limit ? QuotaAdmission::ReachedLimit
71 }
72
73 // Called only AFTER the direct close commits and receives a broker fill
74 // sequence. An uncounted close cannot create a transferable debit.
75 void count_committed_close(OrderRiskDay day, int limit, uint64_t close_fill,
76 int source_bar, uint64_t inheritor) {
79 if (latched_) return;
80 ++charged_slots_;
81 if (inheritor != 0) {
82 transfer_ = CloseQuotaTransfer{day, close_fill, source_bar, inheritor};
83 }
84 if (charged_slots_ >= limit) latch();
85 }
86
87private:
88 std::optional<OrderRiskDay> day_;
89 int charged_slots_ = 0;
90 bool latched_ = false;
91 std::optional<CloseQuotaTransfer> transfer_;
92};
93
94} // namespace pineforge::compat::pine
bool can_inherit(OrderRiskDay day, int bar, uint64_t incarnation, uint64_t latest_committed_fill) const
void count_committed_close(OrderRiskDay day, int limit, uint64_t close_fill, int source_bar, uint64_t inheritor)
QuotaAdmission admit_matched_attempt(OrderRiskDay day, int limit, int bar, uint64_t incarnation, uint64_t latest_committed_fill)
const std::optional< OrderRiskDay > & day() const
const std::optional< CloseQuotaTransfer > & transfer() const
bool operator==(OrderRiskDay a, OrderRiskDay b)
bool operator!=(OrderRiskDay a, OrderRiskDay b)