Fix orderless position cache indexing - #4688
Conversation
Synthetic spread leg fills create positions without backing orders. Preserve the position indexes while skipping the invalid order-to-position mapping and its database entry. Resolves nautechsystems#4628
|
Hi @pengpengyi92, Thanks for the PR. The NETTING change correctly removes the invalid I found three issues to address before merge:
Note: the HEDGING correlation contract is not clearly documented, so I'll follow up on that policy and documentation work. Until then, I think this PR should preserve the existing behavior. When you're able, could you address the recovery and index-rebuild gaps, and preserve HEDGING correlation for now. |
e4b43c7 to
c2cca4c
Compare
c2cca4c to
8df8df9
Compare
|
Hi @pengpengyi92, Thanks for addressing the earlier feedback. I found one remaining HEDGING edge case: When an orderless leg position flips, the closed position and the new open position both retain the same When you're able, could you restrict that lookup to the open position, or otherwise select the current flipped position, and add a regression covering an initial fill, an opposite-side overfill that flips the position, and a subsequent fill for the same synthetic leg ID? |
|
Thanks for catching this, Chris. I restricted the orderless HEDGING correlation lookup to open positions, so after a virtual position flips, the closed predecessor is ignored and the current open flipped position is reused. I added a regression covering an initial buy fill, an opposite-side sell overfill that flips it, and a subsequent sell fill with the same synthetic leg ID; it asserts that only the closed original and open flipped position remain, and that the later fill updates the flipped position. Verification: the focused regression passes, and cargo test -p nautilus-execution completed with 1031 passed, 0 failed, and 1 ignored. This change is intentionally limited to this orderless HEDGING flip edge case and does not try to define the broader undocumented correlation policy. I would be very happy to keep discussing or refine the contract if you think the selection semantics should be expressed differently. |
|
Hi @pengpengyi92, Thanks for addressing the HEDGING flip case. Restricting the lookup to open positions fixes the live execution path. I found three remaining issues, two blockers and one smaller cache issue:
When you are able, could you make replay reproduce the fill -> flip state, filter or migrate stale persisted mappings during load, and keep an empty |
|
Thanks Chris — I addressed all three points in
Regression coverage includes the complete Verification:
I kept the change scoped to the orderless position lifecycle and did not try to define the broader HEDGING correlation policy or add an adapter schema migration. |
RELEASES.md(maintainers keep it current to avoid merge conflicts)Summary
Synthetic spread leg fills intentionally create positions without backing orders, but the cache previously persisted and rebuilt order associations for the absent synthetic order.
This change adds an explicit orderless-position path which:
order_positionmapping;position_ordersbucket so orderless position queries and index rebuilds remain valid;PositionOpenedreplacement.Related issues/PRs
Closes #4628
Type of change
Breaking change details (if applicable)
Not applicable.
Documentation
docs/developer_guide/docs.md)make py-stubsand committed the generated outputNo documentation or PyO3 binding changes.
Testing
Affected code paths are already covered by the test suite
I added/updated tests to cover new or changed logic
cargo test -p nautilus-model events::order::filled::tests(10 passed)cargo test -p nautilus-common cache::tests(282 passed; 2 ignored)cargo test -p nautilus-event-store replay::tests(44 passed)cargo test -p nautilus-event-store(all test targets passed)cargo test -p nautilus-execution --test exec_engine(222 passed)cargo clippy -p nautilus-model -p nautilus-common -p nautilus-execution -p nautilus-event-store --lib --tests -- -D warningscargo fmt --all -- --checkRegression coverage includes live and replayed HEDGING flips, subsequent-fill correlation, legacy cache upgrade loading, empty orderless reverse-index buckets before and after
clear_index() -> build_index(), and cache integrity.