Live Test Checklist — Rithmic
Run this against a real Rithmic demo/test-gateway account once a real RithmicTransport implementation exists (see docs/RITHMIC_TRANSPORT.md for what that requires and the swap-in steps) — before trusting this connector with real money. Every item here exercises real, already-built, already-unit-tested code (against FakeRithmicTransport) for the first time against an actual Rithmic gateway; nothing on this list requires writing new code, only running the existing connector against something real.
Mirrors the format of docs/BROKER_INTEGRATION_REPORT.md's own per-broker validation checklists.
1. Authentication
- [ ]
connect()with valid username/password/systemName succeeds;
RithmicConnector.isConnected() reports true.
- [ ]
connect()with an invalid password fails withConnectorAuthError
and a clear message (not a generic/opaque failure).
- [ ]
connect()with a valid login but no accounts entitled fails with
ConnectorAuthError ("no accounts were returned").
- [ ]
connect()with an explicitaccountIdselects that specific
account when the login has more than one.
- [ ] The Add Broker wizard's Test Connection step, end to end, against
a real demo login, returns real balance/equity in its success summary.
2. Market Data
- [ ]
streamPrice()for an actively-traded contract (e.g. the current
front-month ES or NQ) delivers bid/ask updates within a reasonable interval of subscribing.
- [ ] Quotes stop arriving after calling the returned
Unsubscribe. - [ ]
connector_market_data_latency_ms(visible via
GET /api/health/market-data) shows a plausible, non-zero value after a live subscription.
3. Orders
- [ ] Market order:
placeOrderwithtype: 'market'fills and is
reflected as an open position within the position-sync window.
- [ ] Limit order:
placeOrderwithtype: 'limit'and a price away
from the market appears as a working order in the Rithmic-provided platform's own order book, matching the price sent.
- [ ] Stop order:
placeOrderwithtype: 'stop'appears correctly
with the trigger price sent.
- [ ] Stop-limit order:
placeOrderwithtype: 'stop_limit'
appears with BOTH the trigger price (stopPrice) and the limit price (price) set correctly and distinctly — this is the one order type unique to this connector (MT5/TradeLocker/Tradovate reject it defensively; see docs/BROKER_INTEGRATION_REPORT.md).
- [ ] A pushed
onOrderUpdate/onFillUpdatefor each of the above
arrives and is delivered via streamOrders()/logged correctly.
4. Order Modification
- [ ]
modifyOrderon a still-working limit order changes its price,
confirmed against the Rithmic-provided platform.
- [ ] The modified order's new price is reflected in the next
getOpenOrders() read.
5. Order Cancellation
- [ ]
closeOrderon a still-pending (not yet filled) order id cancels
it — confirmed it disappears from getOpenOrders() and from the Rithmic-provided platform's order book.
6. Position Closing
- [ ]
closeOrderon an open position's id (its symbol — see
normalize.ts's positionId convention) closes the full position.
- [ ] The position disappears from both
getPositions()and a
subsequent onPositionUpdate push (quantity reaching 0).
- [ ] A partial close (closing less than the full open quantity, if
supported by however closePosition ends up implemented) is correctly reported as partial_close, not close.
7. Disconnect Recovery
- [ ] Killing network connectivity mid-session is detected — either by a
failed reconciliation poll tick or by the next heartbeat() call failing — within one heartbeatIntervalMs/reconciliationIntervalMs window.
- [ ]
RithmicConnector's state transitions to'error', and structured
logs show Scheduling Rithmic reconnect.
8. Reconnect Recovery
- [ ] Once connectivity is restored, the connector automatically
reconnects (structured logs show Rithmic reconnect succeeded) without manual intervention.
- [ ] After reconnecting,
PositionSynchronizationService.reconcileMaster
(or the position-sync reconciliation tick) correctly identifies any trade that happened ON Rithmic *during* the outage (a missed open or close) — see docs/RITHMIC_TRANSPORT.md's note that this is exactly the scenario RithmicPositionService's reconciliation poll exists for.
- [ ]
connector_reconnect_success_total{platform="rithmic"}increments
(visible via /api/health).
9. Latency Validation
- [ ]
connector_order_latency_msshows plausible values (compare
against the Rithmic-provided platform's own fill-confirmation timing) after placing several real orders.
- [ ]
connector_position_sync_latency_msshows plausible values for
both push-driven updates (should be very low — just the local diffing cost) and the reconciliation poll path (naturally higher — a full snapshot fetch).
- [ ] None of the three latency metrics show implausible outliers
(multi-second) under normal conditions — if they do, investigate before considering this connector production-ready.
10. Copy Engine Validation
Everything in tests/rithmic-copy-engine-validation.test.ts passes against FakeRithmicTransport already (18 tests — one master → many followers, many masters → many followers, all 4 lot-sizing modes, reverse copy, symbol mapping, pending orders, partial close, SL/TP updates, emergency stop, pause/resume, duplicate prevention, queue processing, reconnect recovery). This section is about confirming the SAME behavior holds with a real Rithmic account as the signal source:
- [ ] Open a real position on a Rithmic demo master account with an
active copy relationship to a follower (any platform) — confirm it copies with the configured lot-sizing mode applied correctly.
- [ ] Modify the master's position (add to it) — confirm the follower
receives the resulting modify event.
- [ ] Partially close the master's position — confirm the follower's
position is partially closed by the correct proportion.
- [ ] Fully close the master's position — confirm the follower's
position closes.
- [ ] Trigger Pause on the relationship mid-session — confirm a
subsequent master trade is NOT copied. Resume — confirm the next one IS.
- [ ] Trigger Emergency Stop All — confirm no relationship for that user
copies further, regardless of platform.
11. Error Handling
- [ ] An order rejected by Rithmic (e.g. insufficient margin) surfaces
as OrderResult.status: 'rejected' with a meaningful reason, not a thrown exception the caller has to guess about.
- [ ] A transient network error during any transport call is retried
(connector_retry_total{platform="rithmic"} increments) rather than immediately failing the whole operation.
- [ ] Every error surfaced to the Add Broker wizard / Broker Status /
Connection Diagnostics UI is a clear, actionable message — no raw stack traces or opaque codes reaching the user.