Login Page - Create Account

Support Board


Date/Time: Mon, 10 Aug 2026 07:39:39 +0000



Post From: custom DTC trading service — new order not correlating with local order record

[2026-08-10 04:01:52]
User144502 - Posts: 7
Setup
Running a custom DTC Protocol trading server (Python, JSON encoding) that bridges Sierra Chart to the Schwab Trader API. `Server Address = 127.0.0.1:11099`, `Primary Connection Encoding = JSON`, `Skip Encoding Request for Primary Connection = Yes`, `Trade Simulation Mode` unchecked.

Symptom
After `SUBMIT_NEW_SINGLE_ORDER` and a correct, prompt `ORDER_UPDATE` reply, Sierra Chart does not update the order record it created locally when the order was placed. Instead it creates a **second, separate** internal order record from the `ORDER_UPDATE`, leaving the original stuck at `Order Sent` until it independently times out (~55–65 seconds later) with a "Trade Order Error - Order timed-out waiting for response from service/exchange server... Service Order ID: (none)" message — even though the server's reply was already received and processed correctly, just not matched to the original.

Concrete example (BULL, 1 share, limit buy @ 6.94)

Entry Time  Symbol  Status  Internal Order ID  Service Order ID  LastOrderActionSource
22:52:55.085  BULL  Order Sent  59876  (empty)  BULL[M] Daily #1 | User order entry | Last: 7.3199997 | AOE=false | AOU=false
22:52:55.507  BULL-  Open  59877  1007524020155  schwab-dtc-bridge (New) | New order originated from external service


Both records carry the same `ClientOrderID` value (`59876.50810`, sent by Sierra Chart in the original `SUBMIT_NEW_SINGLE_ORDER` and echoed back unchanged in the server's `ORDER_UPDATE`). The second record (59877) appeared **422ms** after the first, at essentially the same instant the server's `ORDER_UPDATE` was sent — so the reply is fast and is being processed, just not correlated to 59876.

59876 subsequently produced, in Sierra Chart's Trade Service Log:
```
Requesting order status for non-responsive order. Time since last action: 62.9 seconds | Symbol: BULL | TradeAccount: roth_haiyang | InternalOrderID: 59876 | Current Status: Order Sent
Trade Order Error - Order timed-out waiting for response from service/exchange server. Internal Order ID: 59876. Service Order ID: (none). Symbol: BULL. Account: roth_haiyang
```

59877 shows correctly (`Open`, correct price/quantity/`Service Order ID`) and can be canceled reliably from the Trade Orders Window.

What's been verified on the server side

The server's `ORDER_UPDATE` for the immediate acknowledgment (sent right after the order is confirmed placed, before any other network activity) contains:

```json
{
"Type": 301,
"TotalNumMessages": 1,
"MessageNumber": 1,
"ClientOrderID": "59876.50810",
"ServerOrderID": "1007524020155",
"TradeAccount": "brokerage",
"Symbol": "BULL",
"OrderStatus": 4,
"OrderUpdateReason": 2,
"OrderType": 2,
"BuySell": 1,
"Price1": 6.94,
"Price2": null,
"TimeInForce": 2,
"OrderQuantity": 1,
"FilledQuantity": 0.0,
"RemainingQuantity": 1
}
```

- `ClientOrderID` matches exactly what Sierra Chart sent in `SUBMIT_NEW_SINGLE_ORDER`.
- `ServerOrderID` is a proper string (this was previously sent as a bare JSON number by mistake and has been corrected — the symptom persisted either way).
- `OrderStatus = 4` (`ORDER_STATUS_OPEN`, "order is open and working" per the documented enum) and `OrderUpdateReason = 2` (`NEW_ORDER_ACCEPTED`) — both per the ORDER_UPDATE documentation.
- `TotalNumMessages = 1`, `MessageNumber = 1` per the documented value for an unsolicited report.
- Confirmed via socket-level timing instrumentation that the message is written and drained to the TCP socket in ~0ms every time — the delay is not on the server's send side.

Also tried and reverted: sending an initial `OrderStatus = ORDER_STATUS_ORDER_SENT` (1) handshake before the real acknowledgment, on the theory that Sierra Chart's local record (which starts in that state) might need to see it echoed back first. This made things worse — it created a **third**, separate, incomplete order record (`Order Type: Unknown`, since the handshake carries no order details), confirming (per your own documentation) that a server should never set that status, and that the correlation mechanism isn't reacting to status value at all.

Two additional experiments tried since the above, both disproven live

**1. Lossy JSON number encoding for `ClientOrderID`.** Theory: if `ClientOrderID` (shaped like `"59876.50810"`) were sent as a bare/unquoted JSON number rather than a quoted string, Python's default JSON parser would silently drop the trailing zero and reformat it slightly differently on the way back out (confirmed via direct repro: `59876.50810` round-trips to `59876.5081`), which could break an exact-text-match correlation. Added diagnostic logging of `ClientOrderID`'s raw value and type on receipt. Result on a fresh live order (INTC, `ClientOrderID = "61218.54096"`): logged as `python type: str`, byte-identical both directions. Sierra Chart does send this field as a proper JSON string. Same duplicate-record symptom occurred anyway. This is ruled out.

**2. Order status lifecycle sequencing.** Theory: every acknowledgment sent so far jumped straight to `OrderStatus = 4` (`ORDER_STATUS_OPEN`), skipping a `ORDER_STATUS_PENDING_OPEN` (2) step that a real broker/DTC server would normally send first (New → PendingNew → Open). Changed the server to send `OrderStatus = 2` as the immediate acknowledgment (still a single, complete message with full order details — not an empty handshake), followed shortly after by a second `ORDER_UPDATE` transitioning to the real status (`OrderUpdateReason = 3`, `GENERAL_ORDER_UPDATE`) once available. Result on a fresh live order (GOOG): same duplicate-record symptom (`InternalOrderID 61889` stuck at "Order Sent"; a second record `61890` created as `Open`). One interesting new observation: the duplicate record's `LastOrderActionSource` text changed from the earlier "(New) | New order originated from external service" to **"(Order update)"** — it now appears the row-creation was triggered by the *second* message (`OrderUpdateReason = 3`) rather than the first (`OrderUpdateReason = 2`), i.e. the `PENDING_OPEN` message seems to have been silently ignored entirely rather than acted on. Either way, a new, uncorrelated row was still created rather than the original being updated in place. This is also ruled out as the mechanism, though the `LastOrderActionSource` label tracking `OrderUpdateReason` this precisely may be a useful clue for your engineers.

Question

What determines whether an incoming `ORDER_UPDATE` is matched to the pending order record Sierra Chart created locally when it sent `SUBMIT_NEW_SINGLE_ORDER`, versus being treated as an independently-discovered order from the external service? Is there a field, timing requirement, or connection setting involved beyond matching `ClientOrderID` that isn't covered in the DTC Messages and Procedures documentation? We've now ruled out message field correctness (every field checked against the documented spec), JSON encoding/type fidelity of `ClientOrderID`, `TotalNumMessages`/`MessageNumber` values, and `OrderStatus` lifecycle sequencing (`PENDING_OPEN` before `OPEN`) as explanations — the correlation failure appears to happen regardless of any of these.