82using CloseDecision = std::variant<std::monostate, CloseNow, CloseNextOpen>;
97 configuration_.limit = limit;
103 const std::optional<CloseCause>&
due_cause()
const {
return due_cause_; }
109 return active() || (configuration_.count_pooc_full_close && budget_.transfer());
116 void metadata(
const std::string& key,
double value) {
121 const bool enabled = std::isfinite(value) && value > 0.0;
122 if (key ==
"intraday_cap_skip_noop_market_fills") {
123 configuration_.skip_noop_market = enabled;
124 declared_ |= kDeclaredSkipNoopMarket;
125 }
else if (key ==
"intraday_cap_defer_pooc_close") {
126 configuration_.defer_pooc_close = enabled;
127 declared_ |= kDeclaredDeferPoocClose;
128 }
else if (key ==
"intraday_cap_count_pooc_full_close_fills") {
129 configuration_.count_pooc_full_close = enabled;
130 declared_ |= kDeclaredCountPoocFullClose;
140 if (!(declared_ & kDeclaredSkipNoopMarket)) configuration_.skip_noop_market =
true;
141 if (!(declared_ & kDeclaredDeferPoocClose)) configuration_.defer_pooc_close =
true;
142 if (!(declared_ & kDeclaredCountPoocFullClose))
143 configuration_.count_pooc_full_close =
true;
145 std::uint8_t
declared()
const {
return declared_; }
159 return !(session.size() >= 9 && session[4] ==
'-'
166 clock.timestamp, clock.timezone, clock.session)};
169 return {clock.chart_day * 100 + clock.chart_month};
176 void decline(uint64_t incarnation) { budget_.decline(incarnation); }
178 uint64_t incarnation, uint64_t latest_fill)
const {
179 return configuration_.count_pooc_full_close
180 && budget_.can_inherit(
risk_day(clock), c.
bar, incarnation, latest_fill)
194 const auto result = budget_.admit_matched_attempt(
195 day, configuration_.limit, context.
bar,
196 configuration_.count_pooc_full_close ? attempt.
incarnation : 0,
206 budget_.expire_transfer();
209 return active() && configuration_.count_pooc_full_close && full
214 uint64_t fill,
const std::vector<ContinuationCandidate>& candidates) {
216 for (
const auto& candidate : candidates) {
218 || candidate.is_long == (before ==
Side::Long))
continue;
220 selected = &candidate;
222 budget_.count_committed_close(
risk_day(clock), configuration_.limit,
227 int64_t cycle,
Prices prices) {
229 if (side ==
Side::Flat) { budget_.latch();
return {}; }
230 const uint64_t action = next_action_++;
232 "Close Position (Max number of filled orders in one day)"};
233 if (configuration_.defer_pooc_close && ordinary(c)
252 budget_.expire_transfer();
253 if (due_cause_ && bar > due_cause_->trigger_bar) due_cause_.reset();
266 static constexpr std::uint8_t kDeclaredSkipNoopMarket = 1;
267 static constexpr std::uint8_t kDeclaredDeferPoocClose = 2;
268 static constexpr std::uint8_t kDeclaredCountPoocFullClose = 4;
270 CapConfiguration configuration_;
271 std::uint8_t declared_ = 0;
272 IntradayOrderBudget budget_;
273 std::optional<CloseCause> due_cause_;
274 uint64_t next_action_ = 1;
void decline(uint64_t incarnation)
const CapConfiguration & configuration() const
void adopt_script_count()
CapAttachment attachment() const
void metadata(const std::string &key, double value)
AttemptOrigin origin(const CapClock &clock, const Calculation &c, uint64_t incarnation, uint64_t latest_fill) const
void after_immediate_close_attempt()
std::uint8_t declared() const
static constexpr uint64_t schema_version
DirectCloseRouting direct_close_routing(const Calculation &c, bool full) const
void ordinary_open(int bar)
static OrderRiskDay risk_day(const CapClock &clock)
void restore_replay_configuration(CapAttachment attachment, const CapConfiguration &configuration, std::uint8_t declared) noexcept
static bool uses_chart_clock(const std::string &session)
Admission pre_dispatch(const CapClock &clock, const Calculation &context, const MatchedAttempt &attempt, uint64_t latest_fill)
uint64_t next_action() const
IntradayCap(CapAttachment attachment=CapAttachment::None)
const IntradayOrderBudget & budget() const
const std::optional< CloseCause > & due_cause() const
void committed_close(const CapClock &clock, const Calculation &c, Side before, uint64_t fill, const std::vector< ContinuationCandidate > &candidates)
bool legacy_limit_is_zero() const
void outcome(FillOutcome outcome, AttemptOrigin origin)
CloseDecision post_dispatch(const Admission &admission, const Calculation &c, const MatchedAttempt &attempt, Side side, int64_t cycle, Prices prices)
IntradayCap & operator=(int limit)
Placement placement(const CapClock &clock)
std::variant< std::monostate, CloseNow, CloseNextOpen > CloseDecision
int64_t session_trading_day_index(int64_t ms, const std::string &tz, const std::string &session)
Broker trading-day ordinal on the unmerged symbol session clock.
int hhmm_to_minutes(const std::string &hhmm)
std::optional< QuotaTrigger > trigger
bool count_pooc_full_close
broker::PositionCloseRequest request
broker::PositionCloseRequest request