fix: preserve direct short reversal affordability#134
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends the engine’s “omitted-quantity, 100% of equity, MARKET short at 100% short margin” affordability + lifecycle semantics so they also apply to direct LONG→SHORT auto-reversals, and ensures that provenance is preserved across broker-driven margin reductions while being cleared on script-driven lifecycle mutations and resets.
Changes:
- Add a new lifecycle provenance bit for direct LONG→SHORT default-sized MARKET reversals, and thread it through fill classification and margin-call fallback selection.
- Clear the new provenance on position resets, fresh openings, adds, and script-driven reductions; preserve it across broker margin-call reductions.
- Add a focused, high-coverage test suite and wire it into the CTest build.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
tests/test_direct_short_reversal_affordability.cpp |
New focused test harness covering direct short-reversal affordability lifecycle behavior, exclusions, and reset/mutation rules. |
tests/CMakeLists.txt |
Registers the new test target in the test suite build. |
src/engine_orders.cpp |
Ensures the new direct-reversal lifecycle provenance is cleared on full resets, fresh openings, and script-driven partial reductions (but not broker margin-call reductions). |
src/engine_fills.cpp |
Detects eligible direct LONG→SHORT default-sized reversals at fill time, sets/clears the new provenance, and includes it in floor-zero / one-contract fallback selection during margin calls. |
include/pineforge/engine.hpp |
Documents and adds the new per-position lifecycle provenance flag for direct short reversals; updates existing short-opening event docs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+652
to
656
| // both the close-then-open shape that reaches the fill from FLAT and the | ||
| // direct LONG-to-SHORT auto-reversal shape. The one-shot bit queues the | ||
| // fill-price affordability pass and then one ordinary adverse-price pass | ||
| // on that same bar, even when the opening check itself is a no-op. | ||
| bool close_then_short_opening_requires_adverse_retry_ = false; |
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
affordability lifecycle to direct LONG-to-SHORT auto-reversals at 100%
short margin.
on script-driven reductions, accepted adds, fresh/raw openings, full closes,
and run reset.
one-contract floor-zero fallback.
other margins, priced orders, slippage, process-on-close, calc-on-fill,
magnifier, streaming, OCA membership, lifecycle mutations, and reset
behavior.
Generic-semantics guard
Strategy-specific fixes are forbidden. The changed production code contains
no slug, author, title, filename, source-text pattern, corpus metadata,
strategy-name, indicator-name, or specific order-ID predicates. Eligibility is
derived only from broker-visible order topology, sizing, margin, execution
phase, and position lifecycle state. Validation strategies are witnesses, not
production selectors.
Validation
2^3cells completed; B-only was thesole active zero-DOWN cell.
byte-identical to the accepted exploratory cell; ordinary ABI, zero matrix
macros, and zero automatic ladder invocations.
no-trades row, five established transpile errors, one established run error,
and zero compile/driver/timeout errors.
365 Excellent / 37 Strong / 3 Moderate / 2 Weak; 1 tier UP, 0 tier DOWN.
were byte-identical before and after.
The full sweep changed 15 engine trade tapes. This PR therefore claims
0 tier DOWN, not the broader claim that every underlying metric ismonotonic. The sole tier promotion was
markittick-alpha-signal-engine-pro-markittick, Strong to Excellent(
exitP90 0.0239 -> 0.0016,pnlP90 1.1697 -> 0.0842).Immutable pins
a12cdbc43b284a440a1dc3ad8f33a3cdb5f1f643b66971dd18dc09d5552e6631483be29948d653c1ab690a62cb18b05f3bbf3d16c2ec06be07555380bc97151503ae2cafccbe298b188488bf84f24439075b271bb0bfcd0908daccf8f1d79a7ab0991602Two preserved preflight attempts failed before semantic execution because of
system Python 3.8 and a missing generated version header. The successful gates
above pinned Python 3.13.13 and a standard candidate build.