Repository navigation
fix(oca): REDUCE reduces sibling qty by filled amount - #5
Merged
Merged
Conversation
Pine v6 strategy.oca.reduce semantics: when one sibling fills qty Q, the remaining siblings have their qty reduced by Q rather than being cancelled outright (which is strategy.oca.cancel behaviour). The prior implementation routed both oca_type==1 (CANCEL) and oca_type==2 (REDUCE) through cancel_oca_group, wiping every other sibling on first fill. Add reduce_oca_group helper that decrements each sibling's qty by the just-filled qty (computed from |signed_pos_after - signed_pos_before|), removing siblings whose qty falls to <= 0. Default-sized siblings (qty == NaN) cannot have a meaningful per-order qty applied at place time, so we conservatively cancel them — matching the prior behaviour for that subset. Corpus parity: 168 -> 176 excellent (+8), driven by validation probes 52/63/72/93/95/96 and several MTF/typed-matrix probes flipping from strong/moderate to excellent.
Add tests/test_strategy_oca.cpp covering: - 2-sibling REDUCE partial: A fills qty 3 -> B's qty 5 -> 2 - 3-sibling REDUCE: A fills qty 2 -> B,C qty 4 -> 2 - REDUCE full-fill cascade: filled qty >= sibling qty drops sibling to 0 - CANCEL unchanged: full sibling wipe on first fill - NONE unchanged: siblings independent, no auto action Uses a BacktestEngine subclass that snapshots pending_orders_ each bar to read remaining qty without needing a public accessor.
luisleo526
added a commit
that referenced
this pull request
Jun 10, 2026
…it-fix sweep - pine_v6_audit_master: mark #5/#6/#31/#32/#35 and ~14 minors [RESOLVED 2026-06-10] against codegen 974cda7 (UNSUPPORTED_CONST_NAMESPACES, chart.bg/fg_color, bare ta.<name> reads, export, derived syminfo warning set, str.replace/timestamp//=/%=/string()/int()/openprofit_percent/ country-GB/TZ/round_to_mintick/array fixes); headline 1 critical + ~40 minor; next steps now point at first_index, size() int typing, O4/O5/O7, and corpus probe gaps - pine_v6_coverage_detail: surgical row refresh (varip/footprint/ volume_row/color()/color.from_gradient/max_bars_back/ timeframe.from_seconds/indicator()/array.new_* drawing types -> hard-reject; syminfo metadata -> get_syminfo_metadata; prefix derived; tz-aware bare time vars; input.source/color/time backings); bucket totals re-counted by delta (181/228/216/175/141) with counting-basis footnote; staleness banner replaced by 2026-06-10 reconciliation note - corpus: bump submodule for README category-table reconciliation (ta=61, mtf=16, input=2; per-row report sums) Co-authored-by: Cursor <[email protected]>
luisleo526
added a commit
that referenced
this pull request
Sep 24, 2026
… new/delete form through INT17b's one allocator
Four slice-B rows defined their own partial set of the replaceable global
allocation functions to count heap allocations -- the pattern INT17b found
aborting under the Linux sanitizers job (alloc-dealloc-mismatch: libstdc++'s
temporary buffers take the NOTHROW operator new, left as ASan's, and give it
back through a SIZED operator delete the test had routed to free()):
test_native_intrabar_scratch PERF-L1 plain/array/nothrow new, plain/sized delete
test_adapter_quiet_bar (+ its PERF-L4 plain/array new, plain/sized delete
_probe and _ungated builds)
test_adapter_command_allocations PERF-L5 plain/array new, plain/sized delete
test_native_match_allocations PERF-L5 plain/array new, plain/sized delete
Each now includes tests/global_allocation_replacement.hpp (all twenty forms,
one malloc/free allocator) instead:
* intrabar_scratch, command_allocations, match_allocations take the
difference of global_allocation::allocations around the span they
counted before (the run; the one re-issued strategy.exit call; the
window between script bars kFirstCounted and kLastCounted), the
style of INT17b's counted conversions; their on/off flag had no other
reader and is gone.
* quiet_bar keeps its body: `allocations` is now a reference to the
shared count (the _l4d twin's precedent), reset where it was reset,
and `count_allocations` still says whether a bar records its count.
Every recorded span lies inside the run it was counted over, so each
per-bar entry is the count it was.
Nothing under src/ or include/ changes (engine code has no over-aligned
allocation, so the aligned forms add nothing to a count). The four rows
print exactly what they printed before the change, line for line, on the
Mac release build: intrabar 0.003-0.045 allocations/bar per path, quiet
bars 4 per stretch (nothing live: 4) magnifier off and on, the re-issued
exit 301 allocations over 42 calls, the matcher 0 per window for every
book. No assertion, bound or pinned value changes.
Fail-before, the sanitizers profile on spark (Linux aarch64, GCC 13.3,
ci_verify's own configure argv, the job's ASAN_OPTIONS/UBSAN_OPTIONS plus
detect_stack_use_after_return=0): the four TUs as the lanes wrote them,
compiled with the sanitizer build's own compile and link commands --
test_adapter_quiet_bar aborts: AddressSanitizer:
test_adapter_command_allocations alloc-dealloc-mismatch (operator new vs free)
#1 operator delete(void*, unsigned long) <the test's own sized delete>
#2 std::__detail::__return_temporary_buffer<PendingSameBarCommand>
#5 std::stable_sort in PineExecutionAdapter::flush_pending_same_bar_commands
allocated by: operator new(unsigned long, std::nothrow_t const&) (asan)
test_native_intrabar_scratch passes (8 passed)
test_native_match_allocations passes (ok)
-- the mechanism INT17b fixed, so both adapter rows would have failed CI's
sanitizers job; the two kernel rows are converted so no counting test is
left with a partial set. After: all four pass there. A grep of tests/ for
global operator new/delete definitions now finds only the helper and the
uncompiled legacy base tests/test_pending_order_mirror_no_alloc.cpp that
INT17b left as it is.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
strategy.oca.reducesemantics — when one sibling fills qty Q, other siblings now have their qty REDUCED by Q (matching TV) instead of being cancelled outright (which isstrategy.oca.cancelbehaviour).reduce_oca_grouphelper inengine_orders.cpp;apply_filled_order_to_statecomputesfilled_qtyfrom signed position delta and dispatches to eithercancel_oca_group(type 1) orreduce_oca_group(type 2). Default-sized (qty == NaN) siblings still cancel since per-order qty is unknown at place time.tests/test_strategy_oca.cpp(5 cases / 14 assertions) covering REDUCE partial 2/3-sibling, full-fill cascade, plus CANCEL/NONE no-regression sanity.Parity
community/IES,validation_lower_tf/lower-tf-probe-02-bool-array) — neither uses OCA, likely unrelated noise.oca-three-way-probe-02-multi-group-partial) windowed-out (no-compare-trades-interior); engine emits 5 trades vs 0 in window — REDUCE shifted trade timing as expected.Test plan
ctest23/23 pass (was 22, +1 new)test_strategy_oca14/14 assertions pass