Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions include/pineforge/engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,14 +215,14 @@ struct PendingOrder {
// become ordinary carried orders on the next bar.
bool coof_born_at_close_recalc = false;
// KI-67 cascade provenance: true when this order was placed by a MID-BAR
// fill recalc (a recalc chain triggered by a fill that did NOT occur at the
// fill recalc (a recalc chain that did not own the first fill event at the
// bar-open tick). Such "cascade" orders are eligible ONLY at the remaining
// EXTREME waypoints (W1/W2) of the historical 4-tick path — never
// intra-segment at an exact level and never at C — for the bar they are
// born on; at bar end they convert to ordinary resting orders. Orders born
// in the BAR-OPEN recalc (or resting at bar start) keep standard exact-level
// semantics and leave this false. Scoped to the historical path; the
// magnifier path (bar_magnifier_enabled_) ignores this bit entirely.
// in that first BAR-OPEN recalc (or resting at bar start) keep standard
// exact-level semantics and leave this false. Scoped to the historical
// path; the magnifier path (bar_magnifier_enabled_) ignores this bit.
//
// ENTRY cascade orders use the plain "extreme-waypoint only" reach above.
// strategy.exit cascade orders follow the finer KI-67 Model S rule
Expand All @@ -236,12 +236,12 @@ struct PendingOrder {
// lets it EXACT-level fill on every SUBSEQUENT leg, and (when
// coof_cascade_inflight_fires) gap-fills it at the in-flight leg-end waypoint.
int8_t coof_cascade_seg_i = -1;
// KI-67 exit cascade: true when the exit level lies inside the in-flight
// remainder (ap -> leg-end waypoint) in the trigger direction on a
// NON-terminal in-flight leg, so it gap-fills same-bar AT that waypoint price
// (Model S clause 1: limits better than level, stops worse). False otherwise
// — subsequent legs fill at the exact level and a terminal in-flight leg
// (seg_i == 2) or off-path (seg_i < 0) rolls to the next bar.
// KI-67 exit cascade: true when the exit may gap-fill at the in-flight
// leg-end waypoint. Normally its level lies inside the in-flight remainder
// in the trigger direction (Model S clause 1). The one scoped extension is
// a marketable LIMIT born after a later same-O fill: it is held through leg
// 0 and gets its gap attempt at W1. Marketable STOP never uses that extension.
// Otherwise subsequent legs exact-fill, while a terminal/off-path order rolls.
bool coof_cascade_inflight_fires = false;
PositionSide created_position_side = PositionSide::FLAT;
// Monotonic identity of the live position instance at placement. Side
Expand Down Expand Up @@ -1602,11 +1602,17 @@ class BacktestEngine {
bool coof_fill_recalc_active_ = false;
bool coof_cursor_is_bar_close_ = false;
bool coof_evaluating_path_segment_ = false;
// KI-67: true while the active fill recalc chain was triggered by a fill AT
// the bar-open tick (O). Orders placed while this holds keep STANDARD
// exact-level semantics; orders placed while it is false are MID-BAR cascade
// orders (see PendingOrder::coof_born_mid_bar).
// KI-67: true only while the active fill recalc owns the FIRST fill event
// at the bar-open tick (O). Orders placed while this holds keep STANDARD
// exact-level semantics. Later fills at that same O, like fills at every
// other path point, are MID-BAR cascades (PendingOrder::coof_born_mid_bar).
bool coof_recalc_at_bar_open_ = false;
// True only while executing a fill recalc triggered by a later fill event
// at O, after the first O fill has already consumed bar-open provenance.
// Such a recalc is mid-bar for KI-67 and resumes on leg 0 (O->W1). This bit
// lets strategy.exit apply the one pinned exception: a marketable LIMIT may
// resume at W1, while marketable STOP suppression remains whole-entry-bar.
bool coof_recalc_after_first_open_fill_ = false;
// KI-67: true only during a point-bar evaluation that sits AT an extreme
// waypoint (W1 or W2) of the historical 4-tick path. Cascade orders born
// this bar may fill only while this holds; on segments, at O, at C, and on
Expand Down
27 changes: 20 additions & 7 deletions src/engine_run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,9 @@ uint64_t BacktestEngine::execute_coof_script_body(
coof_scheduler_active_ = true;
coof_fill_recalc_active_ = is_fill_recalc;
coof_cursor_is_bar_close_ = cursor_is_bar_close;
// KI-67: a fill recalc is "bar-open" only when its triggering fill occurred
// at the open tick; orders it places keep standard semantics. Any other
// recalc (segment/extreme/close fill) is mid-bar and places cascade orders.
// KI-67: only the first fill event at O owns "bar-open" provenance and
// places standard orders. A later fill at the same O, like a fill at any
// segment/extreme/close point, is mid-bar and places cascade orders.
coof_recalc_at_bar_open_ = is_fill_recalc && recalc_at_bar_open;
coof_cursor_price_ = broker_cursor_price;
coof_direct_fill_events_remaining_ = direct_fill_event_budget;
Expand All @@ -176,6 +176,7 @@ uint64_t BacktestEngine::execute_coof_script_body(
}
coof_fill_recalc_active_ = false;
coof_recalc_at_bar_open_ = false;
coof_recalc_after_first_open_fill_ = false;
coof_direct_fill_events_remaining_ = 0;
return broker_fill_event_seq_ - before;
}
Expand All @@ -197,9 +198,16 @@ uint64_t BacktestEngine::run_coof_recalc_chain(
const uint64_t used = events_already + total_events;
const uint64_t direct_budget =
used < max_events ? max_events - used : 0;
// Only the first fill event at O owns bar-open provenance. A direct or
// separately-dispatched later fill at that same O is a KI-67 cascade
// recalc whose remaining path starts on leg 0 (O->W1).
const bool first_open_fill_recalc =
recalc_at_bar_open && events_already == 0 && handled == 1;
coof_recalc_after_first_open_fill_ =
recalc_at_bar_open && !first_open_fill_recalc;
const uint64_t direct = execute_coof_script_body(
script_bar, broker_cursor_price, /*is_fill_recalc=*/true,
cursor_is_bar_close, recalc_at_bar_open,
cursor_is_bar_close, first_open_fill_recalc,
direct_budget);
total_events += direct;
pending_recalcs += direct;
Expand Down Expand Up @@ -257,6 +265,7 @@ void BacktestEngine::dispatch_bar_calc_on_order_fills() {
coof_hist_path_index_ = -1;
coof_cascade_recalc_leg_ = -1;
coof_cascade_force_wp_gap_ = false;
coof_recalc_after_first_open_fill_ = false;

double path[4];
fill_bar_path_points(script_bar, path);
Expand All @@ -269,9 +278,9 @@ void BacktestEngine::dispatch_bar_calc_on_order_fills() {
bool filled_at_bar_open_point) {
const uint64_t before = fill_events;
cursor = fill.fill_price;
// A recalc chain triggered by a fill AT the open tick is "bar-open" and
// places STANDARD orders; any other fill point triggers a MID-BAR
// recalc that places cascade orders (PendingOrder::coof_born_mid_bar).
// The recalc chain receives O-point provenance, but only its first fill
// event is classified as bar-open. A later fill at the same O is a
// leg-0 cascade (PendingOrder::coof_born_mid_bar).
fill_events += run_coof_recalc_chain(
script_bar, cursor, cursor_is_close, filled_at_bar_open_point,
fill.fill_events, kNoFillEventBudget, fill_events);
Expand Down Expand Up @@ -427,6 +436,7 @@ void BacktestEngine::dispatch_bar_calc_on_order_fills() {
coof_scheduler_active_ = false;
coof_fill_recalc_active_ = false;
coof_recalc_at_bar_open_ = false;
coof_recalc_after_first_open_fill_ = false;
coof_cursor_is_bar_close_ = false;
coof_evaluating_path_segment_ = false;
coof_at_extreme_waypoint_ = false;
Expand Down Expand Up @@ -507,6 +517,7 @@ void BacktestEngine::reset_run_state() {
coof_scheduler_active_ = false;
coof_fill_recalc_active_ = false;
coof_recalc_at_bar_open_ = false;
coof_recalc_after_first_open_fill_ = false;
coof_cursor_is_bar_close_ = false;
coof_evaluating_path_segment_ = false;
coof_at_extreme_waypoint_ = false;
Expand Down Expand Up @@ -846,6 +857,7 @@ void BacktestEngine::run_magnified_bar_calc_on_order_fills(
coof_scheduler_active_ = true;
coof_cursor_is_bar_close_ = false;
coof_evaluating_path_segment_ = false;
coof_recalc_after_first_open_fill_ = false;

double cursor = ticks.front().price;
int64_t cursor_ts = ticks.front().timestamp;
Expand Down Expand Up @@ -974,6 +986,7 @@ void BacktestEngine::run_magnified_bar_calc_on_order_fills(
coof_scheduler_active_ = false;
coof_fill_recalc_active_ = false;
coof_recalc_at_bar_open_ = false;
coof_recalc_after_first_open_fill_ = false;
coof_cursor_is_bar_close_ = false;
coof_evaluating_path_segment_ = false;
coof_at_extreme_waypoint_ = false;
Expand Down
56 changes: 47 additions & 9 deletions src/engine_strategy_commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,9 @@ void BacktestEngine::strategy_entry(const std::string& id, bool is_long,
order.created_during_coof_recalc = coof_fill_recalc_active_;
order.coof_born_at_close_recalc =
coof_fill_recalc_active_ && coof_cursor_is_bar_close_;
// KI-67: a fill recalc that was NOT triggered at the bar-open tick is a
// mid-bar recalc; orders it places are cascade orders (eligible only at the
// remaining extreme waypoints of the historical 4-tick path).
// KI-67: a fill recalc without first-O provenance is mid-bar. This includes
// later fills at that same O; orders it places are cascade orders eligible
// only at the remaining extreme waypoints of the historical 4-tick path.
order.coof_born_mid_bar =
coof_fill_recalc_active_ && !coof_recalc_at_bar_open_;
order.created_position_side = position_side_;
Expand Down Expand Up @@ -1110,22 +1110,53 @@ void BacktestEngine::strategy_exit(const std::string& id, const std::string& fro
coof_fill_recalc_active_ && coof_cursor_is_bar_close_;
// KI-67: a fill recalc that was NOT triggered at the bar-open tick is a
// mid-bar recalc; orders it places are cascade orders (eligible only at the
// remaining extreme waypoints of the historical 4-tick path).
// remaining extreme waypoints of the historical 4-tick path). The new
// later-same-O refinement is priced/non-trail only: a trail born in that
// exact cell retains its established standard/open path reach. Otherwise
// the refinement would newly hold it to W1/W2 instead of letting it arm and
// cross continuously on the remaining legs. Magnifier keeps its own tick
// model and is unchanged.
const bool preserve_later_same_open_trail_provenance =
!bar_magnifier_enabled_ && has_trail_request
&& coof_fill_recalc_active_ && !coof_recalc_at_bar_open_
&& coof_recalc_after_first_open_fill_
&& coof_cascade_recalc_leg_ == 0;
order.coof_born_mid_bar =
coof_fill_recalc_active_ && !coof_recalc_at_bar_open_;
coof_fill_recalc_active_ && !coof_recalc_at_bar_open_
&& !preserve_later_same_open_trail_provenance;
// A priced exit born after a later fill at the SAME O is already held by
// the KI-67 cascade gate for its in-flight leg 0. The pinned exception is
// LIMIT-only: a marketable limit may resume at W1. A marketable stop keeps
// the established whole-entry-bar suppression (including M1).
const bool later_same_open_priced_exit_on_entry_bar =
!bar_magnifier_enabled_ && order.coof_born_mid_bar
&& coof_recalc_after_first_open_fill_
&& coof_cascade_recalc_leg_ == 0
&& position_open_bar_ == bar_index_
&& (!std::isnan(stop_price) || !std::isnan(limit_price))
&& std::isnan(trail_points) && std::isnan(trail_price);
bool stop_marketable_at_coof_cursor = false;
bool limit_marketable_at_coof_cursor = false;
bool later_same_open_marketable_limit = false;
if (coof_fill_recalc_active_ && coof_scheduler_active_
&& std::isfinite(coof_cursor_price_)
&& position_side_ != PositionSide::FLAT
&& position_open_bar_ == bar_index_) {
const bool closing_long = position_side_ == PositionSide::LONG;
const bool stop_marketable = !std::isnan(stop_price)
stop_marketable_at_coof_cursor = !std::isnan(stop_price)
&& (closing_long ? coof_cursor_price_ <= stop_price
: coof_cursor_price_ >= stop_price);
const bool limit_marketable = !std::isnan(limit_price)
limit_marketable_at_coof_cursor = !std::isnan(limit_price)
&& (closing_long ? coof_cursor_price_ >= limit_price
: coof_cursor_price_ <= limit_price);
order.coof_suppress_stop_on_entry_bar = stop_marketable;
order.coof_suppress_limit_on_entry_bar = limit_marketable;
later_same_open_marketable_limit =
later_same_open_priced_exit_on_entry_bar
&& limit_marketable_at_coof_cursor;
order.coof_suppress_stop_on_entry_bar =
stop_marketable_at_coof_cursor;
order.coof_suppress_limit_on_entry_bar =
limit_marketable_at_coof_cursor
&& !later_same_open_marketable_limit;
}
// KI-67 exit cascade (Model S). Record this mid-bar cascade exit's in-flight
// leg so the historical dispatch gate can hold it on that leg's remainder,
Expand All @@ -1147,6 +1178,13 @@ void BacktestEngine::strategy_exit(const std::string& id, const std::string& fro
order.coof_cascade_inflight_fires = internal::cascade_exit_inflight_fires(
current_bar_, coof_cursor_price_, si, position_side_,
order.stop_price, order.limit_price);
// The second fill at O has already consumed the only same-point refill
// exception. A marketable LIMIT born from that refill is held through
// O->W1 by the cascade gate, then gets one gap attempt at W1. STOP never
// enters this exception and retains its whole-entry-bar suppression.
if (later_same_open_marketable_limit) {
order.coof_cascade_inflight_fires = true;
}
}
// Position-derived captures use the post-batched-close view (see
// live_pos_qty above) so an exit armed after a same-bar strategy.close
Expand Down
Loading
Loading