orders: restate OutsideRTH on a modify instead of asserting it (ibx#312) - #319
orders: restate OutsideRTH on a modify instead of asserting it (ibx#312)#319userFRM wants to merge 1 commit into
Conversation
Every replace carried `6433=1`. The comment beside it said "preserve from original", but the value was a literal and there was nothing to preserve from: `Order` did not track OutsideRTH, so the flag the order was submitted with was gone by the time a modify was built. The result is that modifying any order turns on extended-hours eligibility, whichever way the order was placed. A resting stop submitted for regular hours only — the default, since the submit path omits 6433 unless asked for it — becomes eligible to trigger outside them the first time its price or quantity is touched. Nothing reports the change: the gateway accepts the flag, the replace is acknowledged normally, and the order reads back as the caller intended apart from the one field they never set. The exposure is a thin pre- or post-session print taking out a stop at a level the regular session never traded. `Order` now carries the flag, set from the submit request and from the recovery record on reconnect, and the replace restates it. A replace also builds a fresh tracked order from the original, so the flag is carried across that too — without it the first replace would be right and every later one wrong, which is the shape that survives a casual test. When the order is not eligible the tag is omitted, which is what the submit path does for the same order, so the two agree rather than contradicting each other one message apart. The replace tag list moved into a free function so the wire shape can be tested without a live connection. Its position in the message is unchanged, and an order submitted outside RTH produces the same bytes it did before. The tests drive the real send path over a loopback pair and read back what was written, so they cover what the engine records and what it puts on the wire. Passing the flag straight through as false at the callsite, dropping it at any of the submits, or dropping it across a replace each fail them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
a9b69c2 to
371f891
Compare
|
Three mutations were slipping through, and the most important one covered the path every public-client order actually takes.
Also fixed a placement slip of my own: Independent verification worth recording: the outside-RTH submit and modify are byte-identical to the base across both commits, and for an ordinary RTH replace the only difference is the removed |
|
Closing in favour of #249, which fixes the same defect. The underlying bug was filed twice — #247 and #312 — and each attracted its own PR. #249 is the one to keep, and not only because it is a third the size. The two take opposite positions on where the flag comes from, and that difference outlives the outside-RTH question:
In this API a modify is a full resubmission — The recovery-record hunk here exists to feed the stored field, so it goes with the approach rather than being an independent fix. If a recovered order's 6433 needs to reach callers on the status path, that deserves its own issue on its own merits. One thing worth keeping from this branch: |
Summary
6433=1. The comment beside it read "OutsideRTH (preserve from original)", but the value was a literal and there was nothing to preserve it from —types::Orderhad no field for the flag, so what the order was submitted with was gone by the time a modify was built.EClient::place_orderon an already-tracked id, andContext::modify.Closes #312.
Change
Ordercarries the flag, set from the submit request and from the CCP recovery record, where the server restates the order and the flag is on the wire.Omitting the tag rather than sending
6433=0also leaves the server's own setting alone in the case where the original order is not tracked.Wire shape
For an order submitted outside RTH the replace is byte-identical to before, including the tag's position in the message. The tag list moved into a free function so that can be asserted without a live connection.
Tests
The tests drive the real send path over a loopback pair and read back what was written, so they cover both what the engine records and what it puts on the wire. Each of these fails them:
falseat the callsitecargo test --lib: 808 pass. The twoconfig::expiry_testsfailures are pre-existing and unrelated (timezone data). No new clippy warnings.Related
#318 — four order types (adaptive, algo, what-if, adjustable stop) return before the extended-attribute block and never record the flag at all, along with the parent link and OCA group. Pre-existing and separate; found while tracing where the flag comes from.