Login Page - Create Account

Support Board


Date/Time: Fri, 25 Sep 2026 18:41:06 +0000



[Programming Help] - custom DTC trading service — new order not correlating with local order record

View Count: 269

[2026-08-10 04:01:52]
User144502 - Posts: 9
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: 24974
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
[2026-08-11 04:45:02]
User144502 - Posts: 9
Thank you for the pointer about order IDs needing to be constant and
plain ASCII -- that sent me down the right path. I added byte-level
logging on every ORDER_UPDATE my DTC server sends and confirmed the order
IDs were constant, plain ASCII, and byte-identical to what Sierra Chart
sent in SUBMIT_NEW_SINGLE_ORDER every time. The duplicate was still
happening, so I kept digging, and wanted to share what I found in case
it's useful to you or the next person who hits this.

For a pattern-matched Symbol Settings entry, Sierra Chart's
SUBMIT_NEW_SINGLE_ORDER arrives with Symbol="" and the resolved ticker in
Exchange (e.g. Symbol="", Exchange="CSCO"). My server had been echoing
ORDER_UPDATE back with the normalized shape instead (Symbol="CSCO",
Exchange="") -- same ticker, different field. Once I changed it to echo
Symbol/Exchange back in the exact shape Sierra Chart originally sent them,
the duplicate stopped happening -- confirmed across two separate live
orders.

Before that fix, the pattern was: a second Trade Orders Window row would
appear (a new Internal Order ID, LastOrderActionSource showing my
server's name) with the real ServerOrderID and status, while the original
locally-created "Order Sent" row (matching ClientOrderID, no
ServerOrderID) stayed stuck and quietly disappeared roughly 60-90 seconds
later.

If you happen to know whether Symbol/Exchange shape is intentionally part
of order correlation, I'd love to know -- otherwise no need to chase it
further on your end, just figured this was worth passing along since it
took a while to isolate.

Thanks for your help on this!
Date Time Of Last Edit: 2026-08-11 04:45:39
[2026-08-11 06:13:50]
Sierra_Chart Engineering - Posts: 24974
We are checking on this. What we described regarding order matching based on order IDs, is from memory, and generally how this works. We would not have thought the symbol would be involved in this.

We will check on this.

Also, the way that the Symbol and Exchange are being set during order transmission is wrong. We have to see why that would be the case. That would relate to the Symbol-Exchange delimiter provided from the server. Maybe the delimiter is not set right.
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
[2026-08-11 06:23:58]
Sierra_Chart Engineering - Posts: 24974
We can see that the symbol does have to match, and we question whether that makes sense. The way all of it is designed has evolved over time based on various scenarios encountered in order to provide the most reliable and safest order matching.

We also see, that you must be setting the delimiter in the logon response, and that is what is causing the problem with the symbol not being correct during order transmission:
LogonResponse::SymbolExchangeDelimiter
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
[2026-08-13 02:32:58]
User144502 - Posts: 9
Thank you for your prompt reply! Much appreciated!

To post a message in this thread, you need to log in with your Sierra Chart account:

Login

Login Page - Create Account