Support Board
Date/Time: Mon, 10 Aug 2026 07:39:38 +0000
[Programming Help] - custom DTC trading service — new order not correlating with local order record
View Count: 17
| [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. |
| [2026-08-10 06:24:55] |
| Sierra_Chart Engineering - Posts: 24451 |
|
This is definitely a problem with the Order IDs. They must be matching. That is with certainty. It is completely dependent on the order IDs. For order IDs only use these two fields: ServerOrderID ClientOrderID Reference: Trading Related Messages: ORDER_UPDATE [s_OrderUpdate structure] Server >> Client Do not change them. They must be constant throughout the life of the order. Sierra Chart is going to set the client order identifier as the client. We have not done testing but looking at the Sierra Chart parsing of JSON fields, whether there is quote marks or not, around the order identifier, does not matter. But it is important that it is plain ASCII text. Sierra Chart Support - Engineering Level Your definitive source for support. Other responses are from users. Try to keep your questions brief and to the point. Be aware of support policy: https://www.sierrachart.com/index.php?l=PostingInformation.php#GeneralInformation For the most reliable, advanced, and zero cost futures order routing, use the Teton service: Sierra Chart Teton Futures Order Routing Date Time Of Last Edit: 2026-08-10 06:31:32
|
To post a message in this thread, you need to log in with your Sierra Chart account:
