feat(ibkr): CP API v1 order write-path wire layer#136
Conversation
Design for the second oath-adapter-ibkr slice: the CP API v1 order write path (place / reply-confirm / cancel / status / live-orders) as a pure wire layer — request-body serde DTOs, the order/reply union response, and Endpoint descriptors mirroring IBKR JSON. No transport/auth/domain translation; ADR-0022/0026 untouched. Fixtures live-captured in-slice. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Task-by-task TDD plan for the CP API v1 order write path: Endpoint constructors + Method::Delete, request DTOs (first serialize direction), the OrderPlaceReply union, cancel/status/live-orders response DTOs, capture.sh order-dance extension, live-capture reconcile, gated live round-trip test, and README/CHANGELOG. Derived from the approved spec. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reviewer-approved polish across the cpapi write-path branch: - order.rs: drop stale "(added in later tasks)" from the module doc, since the response DTOs are now all present. - tests/order.rs: extend the two OrderPlaceReply union decode tests to assert the full opposite shape is absent, not just 4 of 6 fields. - spec §3.1: sync the OrderPlaceReply/CancelResponse snippet to the implementation's (correct) field spellings so Task 6 reconciliation starts from the right shape.
Live-captured (paper DUP…, sanitized) fixtures + DTO/capture.sh fixes from a
real place→confirm→cancel dance. Live-wire truths:
- place/reply confirmation `order_id` is a STRING; status/live/cancel `order_id`
is an INTEGER (confirms the faithful-mirror split).
- `order/status` limit price is `limit_price` (string), not `price`; sizes are
strings ("1.0"); adds `account`.
- `account/orders` price is a STRING ("1.00") not a number; `orderType` value is
"Limit"; first call returns an EMPTY snapshot (warming) → capture.sh now polls.
- a plain far-below-market LIMIT raises no reply warning (place → confirmation
directly) → capture.sh saves that confirmation; questions fixture stays a
documented representative.
- cancel returns conid:-1, account:null.
Gated live round-trip test passes against the real gateway.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- arm the live-test CancelGuard as soon as an order id is known (initial confirmation or each confirmed reply), closing the question-flow window where a mid-round-trip panic could strand a resting order; - scrub ephemeral gateway ids/timestamps (request_id/server_id/order_time/ lastExecutionTime) from the order_status/live_orders fixtures for consistency with the account/order-id sanitization; - clarify the capture.sh no-question log line. Live round-trip re-verified against the paper gateway; no resting order. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (17)
📝 WalkthroughWalkthroughThe IBKR CPAPI adapter now includes order placement, reply confirmation, cancellation, status, and live-order wire DTOs and endpoints. It adds fixture-based serialization/decoding tests, paper capture automation, an ignored live round-trip test, documentation, and changelog entries. ChangesIBKR CPAPI order write path
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Closes #135.
The second
oath-adapter-ibkrslice: the Client Portal API v1 (cpapi) order write path as a pure, transport-agnostic wire layer — following the read path (#127/#129/#131).What's in it
Serializedirection):OrderRequest,PlaceOrderRequest,ReplyConfirm.OrderPlaceReply(the place/reply union — one all-optional struct, not a serdeuntaggedenum),CancelResponse,OrderStatus,LiveOrders/LiveOrder.Endpointdescriptors: place / reply-confirm / cancel / order-status / live-orders (addsMethod::Delete).just ibkr-captureextended to drive the real place → confirm → cancel dance and capture sanitized fixtures.#[ignore]live round-trip test (place → confirm → cancel), built via the request DTOs +Endpointconstructors, with aDrop-guard best-effort cancel.Boundary (unchanged from the read path)
No transport, no auth, no OATH-domain translation, no order-safety semantics — ADR-0022 / ADR-0026 stay untouched. Order modify deferred (YAGNI).
Faithful-mirror splits (reconciled against a real paper gateway)
order_idis a string; status/live/cancelorder_idis an integer.order/statusis snake_case-native (limit_price/sizes are strings);account/ordersis camelCase-native (orderId/orderType/totalSizerenamed,pricea string)./iserver/account/ordersreturns an empty snapshot on the first call (snapshot warming) → the capture polls until populated.Fixtures are real, sanitized paper captures (account
DU0000000, ids placeholdered).just cigreen; the gated live round-trip was verified against the real gateway (no resting order).🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Tests
Documentation