orders: assert outside-RTH on a replace from the resubmitted order (ibx#247) - #249
Open
userFRM wants to merge 1 commit into
Open
orders: assert outside-RTH on a replace from the resubmitted order (ibx#247)#249userFRM wants to merge 1 commit into
userFRM wants to merge 1 commit into
Conversation
…bx#247) The replace hard-coded tag 6433=1 with a comment claiming it preserved the original. It could not: the tracked `types::Order` the replace is rebuilt from carries no outside-RTH field. Placement emits 6433 only when the caller asks for it, so an order placed with `outside_rth=false` — the default — was opted into the extended session by its first modify. For a resting stop that is the difference between triggering in RTH only and triggering on a thin extended-hours print. `OrderRequest::Modify` now carries the flag from the order the caller resubmitted, and the replace emits 6433 only when it is set. The caller's order is the right source rather than the cached one: `track_order` overwrites the cache with the resubmitted order at the end of every `place_order`, modify included, so the cache holds the previous resubmission and reading it would ignore an explicit change on this call. Price and qty already flow this way. With the flag set the emitted message is unchanged, 6433 keeping its captured position between 6122 and 38; with it clear the tag is the only thing absent. A test drives the Modify arm over a loopback socket and pins both polarities at the wire, since nothing in-tree exercised that encoder before — which is why the hard-coded tag survived. `Context::modify` takes the flag for the same reason, and `OrderRequest::Modify` gains a field, so this is a source-breaking change for direct constructors of either. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Jul 30, 2026
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
6433=1(src/engine/hot_loop/order_builder.rs, Modify arm) with a comment claiming it preserved the original. It cannot:types::Order(src/types.rs:251-266), the record the replace is rebuilt from, has no outside-RTH field.outside_rth=false— the default — was opted into the extended session by its first modify. For a resting stop that is the difference between triggering in RTH only and triggering on a thin extended-hours print. It hits every modified order, not only bracket children.OrderRequest::Modifynow carries the flag from the resubmitted order and the replace emits 6433 only when set.Why the caller's order rather than the cached one
track_orderoverwrites the cachedApiOrderwith the caller's order at the end of everyplace_order, modify branch included (src/client_core.rs:768-773), so the cache holds the previous resubmission. Reading it would use a stale flag and ignore an explicit change on this call. Price and qty already come from the resubmitted order, andplace_orderwith a tracked id is the documented modify entry point, so caller-supplied is both the coherent source and the consistent one.Wire
With the flag set the message is unchanged — 6433 keeps its captured position between 6122 and 38. With it clear, the absent tag is the only difference. The conditional is a literal split rather than a positional insert, so the ordering is correct by construction.
Test
Nothing in-tree exercised the Modify arm's encoder, which is why a hard-coded tag survived there.
modify_emits_outside_rth_only_when_the_caller_set_itdrives the arm over a loopback socket and asserts|6122=c|6433=1|38=50|when the flag is set and no6433when clear. Reintroducing the unconditional tag fails it; moving the tag to the tail fails it on the positional assertion.cargo test --lib— 804 pass. The twoconfig::expiry_testsfailures and theib_paper_compatE0063s are present onmainbefore this branch; the sixModifyliterals in that target are updated so this adds no new errors.Scope and caveats
Breaking:
OrderRequest::Modifygains a field andContext::modifygains an argument, both public.EClient::place_orderand the Python signatures are unchanged. That reads like the 0.8.0 lane rather than 0.7.2 — your call.What this does not claim: I have no capture for how the gateway treats an absent 6433 on a
35=G. Under either reading the bug this targets is fixed — an RTH-only order can no longer come back extended-hours-enabled, and an explicittruestill asserts the tag. The open case is placed-truethen modified withfalse: if absence means "unchanged" rather than "false", the order stays outside-RTH. I could not settle that on paper, because the only readback path isreq_open_orders, which serves local state thattrack_orderhas already overwritten with the caller's own values — so it echoes the input rather than reporting the gateway.Test plan
cargo test --offline --lib— 804 passed. The 2 failures areconfig::expiry_tests::{named_zone_converts_with_dst, instant_round_trips_to_wire}, which fail on the base commit too: the host has no legacy timezone files (fixed separately in config: resolve the legacy timezone names IB states its times in (ibx#335) #336).cargo check --offline --features python— clean.modify_emits_outside_rth_only_when_the_caller_set_itby name.🤖 Generated with Claude Code