Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions blueprints/us-equities/engine-nautilus/acceptance-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@ dated evidence.
| [Alpaca paper smoke](../paper-e2e-20260921/paper-receipt.json) | One SPY long-to-flat roundtrip, two actual submissions/full fills, -$0.08 cash-matched gross PnL, zero final positions/open orders; a fresh completed-trial recovery added zero writes |
| Broader native acceptance | SPY/LEAN parity, native in-flight faults, streaming reconciliation, IBKR, strategy merit and continuous service remain open |

**Superseding note, 2026-10-01 (trading lane owner).** The table keeps its September 21 status. Since then:
- On 2026-09-23 the frozen SPY comparison's `one_zero` case ran natively on 2.0.0rc5 and passed against the frozen
LEAN oracle ([`spy-parity/verdict-v2.json`](spy-parity/verdict-v2.json): verdict PASS, complete, 0 failed).
- The other five cases have no mapping yet ([`spy-parity/mapping-manifest-v2.json`](spy-parity/mapping-manifest-v2.json),
`dependent_comparison_status`):
- `one_stress` is blocked by `costs_and_rounding_stress`;
- `two_zero`, `adaptive_stress` and `over_limit` by `margin_and_adaptive_state`;
- `two_stress` by both.
The gate `spy-lean-parity` (`catalogs/us-equities/gates-20260922.json`) records the `one_zero` PASS only.
- IBKR acceptance step 1 (read-only, execution disabled) passed on the 2.0.0rc5 native adapter on 2026-09-23
([`evidence/receipts/ibkr-readonly-acceptance-20260923.json`](../../../evidence/receipts/ibkr-readonly-acceptance-20260923.json)).
Steps 2-4 remain open.

See [`docs/decisions/2026-10-01-trading-layer-verdicts.md`](../../../docs/decisions/2026-10-01-trading-layer-verdicts.md).

The AAPL run uses retrospective same-close decisions and synthetic fill liquidity;
known corporate-action dates were excluded. It does not implement the SPY
converter or oracle below. The paper smoke observed full fills and recovery of an
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ orders (ibapi probe).

## Blockers for the gate

**Update, 2026-10-01** (supersedes the #4983 bullet below; see
`docs/decisions/2026-10-01-trading-layer-verdicts.md`): nautilus_trader#4983 is a stale v1.227.0 report for rc5.
At tag `v2.0.0rc5` the execution engine denies an order only when `handles_order_venue` is false, and the IB
execution client returns `true` (source reading, not an rc5 order observation). The open rc5 obstacles on the
recovery and reconciliation paths that steps 3-4 exercise are #5007, #5057 and #5060 (`rc5_blockers` in
`catalogs/us-equities/runtime-target.json`); #4946 is fixed on develop in no release.

- Native stock orders (steps 2-4): [nautilus_trader#4983](https://github.com/nautechsystems/nautilus_trader/issues/4983),
the execution client's `IB` venue never matches the `SMART` instrument venue,
so every stock order is denied locally.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ for that gate.

## Why 1.231.0

**Update, 2026-10-01** (supersedes the #4983 statement in this section): #4983 is reclassified as a stale v1.227.0
report for rc5 (source reading at tag `v2.0.0rc5`; `rc5_reclassified_reports` in
`catalogs/us-equities/runtime-target.json`). The rc5 obstacles that remain are on the recovery and reconciliation
paths: #5007, #5057 and #5060 (`rc5_blockers` there). rc5's IBKR stock-order path stays unqualified until native
paper execution.

The pinned 2.0.0rc5 Rust IB adapter denies every stock order locally: the
execution client's `IB` venue never matches the `SMART` instrument venue
([nautilus_trader#4983](https://github.com/nautechsystems/nautilus_trader/issues/4983),
Expand Down
2 changes: 1 addition & 1 deletion catalogs/us-equities/gates-20260922.json
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@
"pointer": "/status",
"equals": "passed"
},
"note": "Paper orders through NautilusTrader's own IB execution engine, 2026-09-23 (status unchanged): blueprints/us-equities/engine-nautilus/ibkr-paper-orders/evidence/receipt-20260923-passed.json, NautilusTrader 1.231.0 Python IB adapter on the official ibapi 10.45.1, paper Gateway 10.50.1e. C1 resting SPY buy accepted, C2 canceled, C3 marketable buy filled 768.56, C4 flatten filled 768.50, net -2.08 USD after 2.02 USD commissions, 3 of 6 orders, independent official-ibapi flat proof 0 positions and 0 open orders. An earlier run refused while the Gateway API was Read-Only (IB 321). Not flipped: reconnect with an open order, restart reconciliation and the step-4 kill switch are not yet run, and 1.231.0 is not the pinned 2.0.0rc5 destination (whose stock orders are blocked by nautilus_trader#4983; PR #5041 open), so a flip needs those cases plus a dated version-selection record. Partial evidence, 2026-09-23 (status unchanged): evidence/receipts/ibkr-readonly-acceptance-20260923.json. Acceptance-plan section 5 step 1 (read-only, execution disabled) passed on a signed-in paper IB Gateway 10.50 with both the official ibapi 10.45.1 client (paper DU account check, every request complete, 0 positions, 0 open orders, SPY conId 756733 ARCA, REALTIME quote within the 900 s age limit, bars) and the NautilusTrader 2.0.0rc5 native HistoricalInteractiveBrokersClient (SPY.ARCA resolved, 5 daily and 390 five-minute bars). Steps 2-4 (client-id ownership, bounded paper orders, reconnect/restart reconciliation) are not run: native stock orders are denied locally by nautilus_trader#4983 (open). rc5's Rust ibapi =3.3.0 classifies IB notice 2188 as fatal (source-verified, rust-ibapi#764, fixed in v4.0.0; nautilus_trader PR #5041 pins =4.1.0); one pre-market native bar failure was observed. runtime-target.json next_acceptance separate-paper-adapters: bounded_alpaca_paper_smoke_passed_ibkr_pending. Execution and steps 2-4 remain unexercised. Required receipt schema, preregistered here (no receipt exists yet at receipt_path ibkr-acceptance/receipt.json or of kind native_ibkr_local_acceptance; the step-1 probes refuse to write there): {\"schema_version\": 1, \"kind\": \"native_ibkr_local_acceptance\", \"status\": \"passed\", \"broker\": \"ibkr\"}. The checker only verifies /status == \"passed\"; /kind names the receipt type but is not itself a result, so it is not the flip condition. That a signed-in TWS or IB Gateway actually accepted the adapter locally is qualified manually before the dated commit that flips this gate. After-hours paper orders, 2026-09-23 (status unchanged): blueprints/us-equities/engine-nautilus/ibkr-paper-orders/evidence/receipt-20260923-post-incomplete.json, plan-post.json (outsideRth), 18:58 ET: resting buy accepted and cancelled, marketable buy filled 768.01, flatten timed out at 45 s and cleanup filled 767.96, realized -2.07 USD with commission, flat proof passed; status incomplete on the C4 step timeout."
"note": "Upstream re-check, 2026-10-01 (status unchanged; supersedes the #4983 statements below; see docs/decisions/2026-10-01-trading-layer-verdicts.md): nautilus_trader#4983 is a stale v1.227.0 report for rc5. At tag v2.0.0rc5 (1b0a49d2) the execution engine denies an order only when handles_order_venue is false (crates/execution/src/engine/mod.rs:2222), and the IB execution client returns true (crates/adapters/interactive_brokers/src/execution/core.rs:491-496); source reading, not an rc5 order observation. The open rc5 obstacles on the recovery and reconciliation paths are #5007, #5057 and #5060; #4946 is fixed on develop (ed6fc8bf) in no release; PR #5041 (open) lists them as covered. Paper orders through NautilusTrader's own IB execution engine, 2026-09-23 (status unchanged): blueprints/us-equities/engine-nautilus/ibkr-paper-orders/evidence/receipt-20260923-passed.json, NautilusTrader 1.231.0 Python IB adapter on the official ibapi 10.45.1, paper Gateway 10.50.1e. C1 resting SPY buy accepted, C2 canceled, C3 marketable buy filled 768.56, C4 flatten filled 768.50, net -2.08 USD after 2.02 USD commissions, 3 of 6 orders, independent official-ibapi flat proof 0 positions and 0 open orders. An earlier run refused while the Gateway API was Read-Only (IB 321). Not flipped: reconnect with an open order, restart reconciliation and the step-4 kill switch are not yet run, and 1.231.0 is not the pinned 2.0.0rc5 destination (whose stock orders are blocked by nautilus_trader#4983; PR #5041 open), so a flip needs those cases plus a dated version-selection record. Partial evidence, 2026-09-23 (status unchanged): evidence/receipts/ibkr-readonly-acceptance-20260923.json. Acceptance-plan section 5 step 1 (read-only, execution disabled) passed on a signed-in paper IB Gateway 10.50 with both the official ibapi 10.45.1 client (paper DU account check, every request complete, 0 positions, 0 open orders, SPY conId 756733 ARCA, REALTIME quote within the 900 s age limit, bars) and the NautilusTrader 2.0.0rc5 native HistoricalInteractiveBrokersClient (SPY.ARCA resolved, 5 daily and 390 five-minute bars). Steps 2-4 (client-id ownership, bounded paper orders, reconnect/restart reconciliation) are not run: native stock orders are denied locally by nautilus_trader#4983 (open). rc5's Rust ibapi =3.3.0 classifies IB notice 2188 as fatal (source-verified, rust-ibapi#764, fixed in v4.0.0; nautilus_trader PR #5041 pins =4.1.0); one pre-market native bar failure was observed. runtime-target.json next_acceptance separate-paper-adapters: bounded_alpaca_paper_smoke_passed_ibkr_pending. Execution and steps 2-4 remain unexercised. Required receipt schema, preregistered here (no receipt exists yet at receipt_path ibkr-acceptance/receipt.json or of kind native_ibkr_local_acceptance; the step-1 probes refuse to write there): {\"schema_version\": 1, \"kind\": \"native_ibkr_local_acceptance\", \"status\": \"passed\", \"broker\": \"ibkr\"}. The checker only verifies /status == \"passed\"; /kind names the receipt type but is not itself a result, so it is not the flip condition. That a signed-in TWS or IB Gateway actually accepted the adapter locally is qualified manually before the dated commit that flips this gate. After-hours paper orders, 2026-09-23 (status unchanged): blueprints/us-equities/engine-nautilus/ibkr-paper-orders/evidence/receipt-20260923-post-incomplete.json, plan-post.json (outsideRth), 18:58 ET: resting buy accepted and cancelled, marketable buy filled 768.01, flatten timed out at 45 s and cleanup filled 767.96, realized -2.07 USD with commission, flat proof passed; status incomplete on the C4 step timeout."
},
{
"id": "live-go",
Expand Down
67 changes: 60 additions & 7 deletions catalogs/us-equities/runtime-target.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,64 @@
"not_established": "The pinned 2.0.0rc5 Rust adapter path, reconnect/restart reconciliation, the kill switch, and the after-hours run (receipt-20260923-post-incomplete.json, incomplete on the C4 step timeout).",
"source": "blueprints/us-equities/engine-nautilus/ibkr-paper-orders/README.md"
},
"rc5_blockers_note": "2026-10-01 (gh api and source reading at tag v2.0.0rc5, commit 1b0a49d2; not observed on this host): #4983 moved to rc5_reclassified_reports as a stale v1.227.0 report, and the rc5 obstacles on the recovery and risk paths that IBKR acceptance steps 3-4 exercise are listed here instead. The structure and per-issue facts follow PR #280 (2026-09-25); the states were re-read on 2026-10-01. The rc5 IBKR stock-order path stays unqualified until native paper execution. Owner's record: docs/decisions/2026-10-01-trading-layer-verdicts.md.",
"rc5_blockers": [
{
"ref": "https://github.com/nautechsystems/nautilus_trader/issues/5007",
"state": "open",
"state_checked_at": "2026-10-01",
"path": "restart recovery: startup fill reconciliation",
"reported_against": "2.0.0rc5 (crates/adapters/interactive_brokers/src/execution/core.rs at 1b0a49d)",
"effect": "generate_fill_reports sends the prefixed AccountId as the execution filter's account code, so TWS rejects the fill query with error 321 and startup reconciliation gets no historical fills.",
"upstream_fix": "Listed as covered by open PR #5041; in no release."
},
{
"ref": "https://github.com/nautechsystems/nautilus_trader/issues/5057",
"state": "open",
"state_checked_at": "2026-10-01",
"path": "restart recovery: working orders from a previous session",
"reported_against": "2.0.0rc6.dev20260921; traced on 2.0.0rc5 in the issue thread",
"effect": "An IB PreSubmitted order reconciles as an unhandled SUBMITTED external order, and every later update for it fails with 'Trader ID not found', so the node cannot manage or cancel working orders it finds after a restart.",
"upstream_fix": "Listed as covered by open PR #5041; in no release."
},
{
"ref": "https://github.com/nautechsystems/nautilus_trader/issues/5060",
"state": "open",
"state_checked_at": "2026-10-01",
"path": "reconciliation: execution queries and external fills",
"reported_against": "2.0.0rc5 and develop",
"effect": "reqExecutions replies are replayed as live fills, fills for orders the node did not place become refused reduce-only orders, and the position check waits on them.",
"upstream_fix": "Listed as covered by open PR #5041; in no release."
},
{
"ref": "https://github.com/nautechsystems/nautilus_trader/issues/4946",
"state": "closed",
"state_checked_at": "2026-10-01",
"path": "pre-trade risk: account-scoped checks",
"reported_against": "2.0.0rc4; the fail-open branch is at crates/risk/src/engine/mod.rs:1218-1234 at tag v2.0.0rc5",
"effect": "For a broker-routed SMART instrument the account registered under venue IB is not found, so every account-scoped pre-trade check (max_notional_per_order, free balance, cumulative notional) is skipped with only a debug log.",
"upstream_fix": "Closed 2026-09-25T11:03:11Z by develop commit ed6fc8bf47fd37dda97d63b9b2df160719ee2bac ('Apply pre-trade risk to the destination execution account'), which is in no release (the newest release is the prerelease v2.0.0rc5; GitHub's releases/latest is v1.231.0; read 2026-10-01); PR #5041 also lists it as covered."
}
],
"rc5_reclassified_reports": [
{
"ref": "https://github.com/nautechsystems/nautilus_trader/issues/4983",
"state": "open",
"state_checked_at": "2026-09-24",
"effect": "The rc5 Rust adapter's execution client venue IB never matches the SMART instrument venue, so every stock order is denied locally."
"state_checked_at": "2026-10-01",
"reported_against": "v1.227.0 (Rust adapter), filed 2026-09-12",
"reported_effect": "The execution client venue IB never matches the SMART instrument venue, so every stock order is denied locally.",
"classification": "stale for rc5",
"reclassified_at": "2026-10-01",
"basis": "Source reading, not an rc5 order observation: at tag v2.0.0rc5 (1b0a49d2) crates/execution/src/engine/mod.rs:2222 denies an order only when client.handles_order_venue(order_venue) is false, and the IB execution client overrides it to return true (crates/adapters/interactive_brokers/src/execution/core.rs:491-496). First recorded in PR #280 on 2026-09-25 and in the 2026-09-26 trading convergence record (PR #358).",
"decision_record": "docs/decisions/2026-10-01-trading-layer-verdicts.md"
}
],
"upstream_ibapi_pin": {
"state_checked_at": "2026-09-24",
"state_checked_at": "2026-10-01",
"rc5_pin": "Rust ibapi =3.3.0 (Cargo.toml at tag v2.0.0rc5)",
"notice_2188_issue": "wboayue/rust-ibapi#764 closed 2026-08-27 by merged PR #765 (in v4.0.0); not listed as a blocker",
"pin_update": "nautechsystems/nautilus_trader PR #5041 (open) changes the pin to =4.1.0"
"pin_update": "nautechsystems/nautilus_trader PR #5041 (open, not merged, head 7a88a0c9 on 2026-10-01) changes the root Cargo.toml pin from =3.3.0 to =4.2.0; no release contains it",
"pin_update_note": "Records before 2026-09-25 said =4.1.0; the PR's Cargo.toml diff (gh api pulls/5041/files) names ibapi 4.2.0."
},
"paper_socket_defaults": {
"tws": 7497,
Expand All @@ -91,7 +136,15 @@
"sources": [
"https://nautilustrader.io/docs/latest/integrations/interactive_brokers/",
"https://github.com/nautechsystems/nautilus_trader/issues/4983",
"https://github.com/nautechsystems/nautilus_trader/pull/5041"
"https://github.com/nautechsystems/nautilus_trader/pull/5041",
"https://github.com/nautechsystems/nautilus_trader/issues/5007",
"https://github.com/nautechsystems/nautilus_trader/issues/5057",
"https://github.com/nautechsystems/nautilus_trader/issues/5060",
"https://github.com/nautechsystems/nautilus_trader/issues/4946",
"https://github.com/nautechsystems/nautilus_trader/commit/ed6fc8bf47fd37dda97d63b9b2df160719ee2bac",
"https://github.com/nautechsystems/nautilus_trader/blob/1b0a49d2792a9432a3aca3fcb617ce7a630d905e/crates/execution/src/engine/mod.rs#L2222",
"https://github.com/nautechsystems/nautilus_trader/blob/1b0a49d2792a9432a3aca3fcb617ce7a630d905e/crates/adapters/interactive_brokers/src/execution/core.rs#L491-L496",
"https://github.com/nautechsystems/nautilus_trader/blob/1b0a49d2792a9432a3aca3fcb617ce7a630d905e/crates/risk/src/engine/mod.rs#L1218-L1234"
]
},
{
Expand Down Expand Up @@ -153,9 +206,9 @@
{
"id": "separate-paper-adapters",
"status": "bounded_alpaca_paper_smoke_passed_ibkr_1231_python_paper_passed_rc5_pending",
"scope": "Alpaca1SPY long-flat trial passed with2actual writes, -0.08USD cash-matched gross PnL, no positions/open orders, and completed-trial recovery with0additional writes. Five unchanged upstream read-only tests passed. IBKR: a bounded 2026-09-23 paper run through NautilusTrader 1.231.0's Python IB adapter passed (accept, cancel, fill, flatten; net -2.08 USD; flat), which is not rc5 destination acceptance; rc5 stock orders remain blocked by nautilus_trader#4983 (open). Continuous operation, native in-flight broker faults (see broker-state-failures), Elite 1000/min throughput (200/min measured; see adaptive_practice native_paper_capacity) and IBKR reconnect/restart reconciliation remain separate.",
"scope": "Alpaca1SPY long-flat trial passed with2actual writes, -0.08USD cash-matched gross PnL, no positions/open orders, and completed-trial recovery with0additional writes. Five unchanged upstream read-only tests passed. IBKR: a bounded 2026-09-23 paper run through NautilusTrader 1.231.0's Python IB adapter passed (accept, cancel, fill, flatten; net -2.08 USD; flat), which is not rc5 destination acceptance; rc5 stock orders are unqualified: nautilus_trader#4983 is reclassified as a stale v1.227.0 report (rc5_reclassified_reports), and the open rc5 obstacles are #5007, #5057 and #5060 (rc5_blockers), as of 2026-10-01. Continuous operation, native in-flight broker faults (see broker-state-failures), Elite 1000/min throughput (200/min measured; see adaptive_practice native_paper_capacity) and IBKR reconnect/restart reconciliation remain separate.",
"executed_evidence_ref": "blueprints/us-equities/engine-nautilus/ibkr-paper-orders/evidence/receipt-20260923-passed.json",
"rc5_blocker": "https://github.com/nautechsystems/nautilus_trader/issues/4983"
"rc5_blocker": "superseded 2026-10-01: see this file's IBKR entry, rc5_blockers (#5007, #5057, #5060 open; #4946 fixed on develop in no release) and rc5_reclassified_reports (#4983); fix candidate PR #5041 (open)"
}
],
"limitations": [
Expand Down
Loading
Loading