Back to blogWebSocket Mirroring for Tradovate: Preserve Time in Force

WebSocket Mirroring for Tradovate: Preserve Time in Force

T

TradeDupe

9 min read

Practical, operator ready Tradovate how to for preserving leader time in force across follower accounts. Covers WebSocket mirroring, OAuth safeguards,...

Yes, you can preserve a leader order's time in force when copying trades on Tradovate, and you should treat it as a hard rule rather than a nice-to-have. Copy the leader's exact `timeInForce` and any `expireTime` onto every follower order, or run a cancel-and-replace sequence when that value needs to change. Tradovate's API will reject a modify request that alters TIF unless you restate the original value in the same call.

*

> TL;DR: > > - Preserving a leader order's time in force requires restating the exact value during each order placement or modification, avoiding API rejections. > - When modifying a TIF, cancel the follower order first, then place a new one with the updated TIF, rather than attempting a direct change. > - Bracket orders with expiration times must carry those values through all legs, and account for suspended states until the primary fills. > - Latency and order execution timing significantly influence price divergence between leader and follower accounts, making WebSocket mirroring essential. > - TradeDupe handles TIF mirroring by copying original values via WebSocket and restating TIF during modifications, with additional safeguards for risk control.

*

Table of Contents

How Tradovate order fields control time in force

Tradovate's order model treats time in force as a first-class field, not an afterthought. The example order payloads published in Tradovate's API repository show `timeInForce` values such as `Day`, `GTC`, `IOC`, and `FOK` sitting alongside `expireTime` and `activationTime` fields, and every `placeOrder` call also requires `action`, `symbol`, `orderQty`, and `orderType` to be valid.

Bracket orders add a wrinkle. The primary order goes in first, and the take-profit and stop-loss legs sit in a suspended state until that primary fill triggers them into working orders. Any `expireTime` you set applies to that lifecycle, not just to the initial submission, so a leader's exit timing only mirrors correctly if you carry the same expiration logic through the whole bracket, not just the entry.

A few field behaviors matter enough to call out directly:

  • `timeInForce` accepts `Day`, `GTC`, `IOC`, and `FOK`, and the value you submit at placement is the value the API expects to see again on any modify.
  • `expireTime` and `activationTime` control duration and delayed starts, and both need to travel with the order state you're mirroring, not just the price and quantity.
  • Modify requests must restate the existing TIF or the API rejects them, a pattern confirmed repeatedly in Tradovate's own forum threads.
  • Non-manual orders, which almost every mirrored follower order is, require the `isAutomated` flag set to `true`.

Building a checklist to mirror TIF across follower accounts

A copy-trading pipeline that respects TIF needs to capture, store, and reapply order state consistently, and that discipline is what separates a stable mirroring system from one that throws intermittent rejections under load.

  1. Capture the leader order's full state the moment it fires, including `timeInForce`, `expireTime`, `clOrdId`, and any bracket fields, and persist it before you touch a single follower account.
  2. When placing each follower order, set an identical `timeInForce` and `expireTime`, and include the correct `accountId` or `accountSpec` along with `isAutomated: true`.
  3. If a change to the leader order would alter its TIF, do not attempt a straight modify. Cancel the follower order first, then place a new order carrying the new TIF.
  4. Use idempotent client order IDs for every follower order and keep an order-state store you can reconcile against, so a retried request never creates a duplicate position.
  5. For bracket orders, build the TP and SL legs in the follower payload using the correct bracket fields, and preserve their `expireTime` values wherever the API supports it.

Pro Tip: Store the leader's original order payload verbatim, not just the parsed fields you think you'll need. When Tradovate's API changes a validation rule, having the raw payload lets you replay and debug without guessing what was actually sent.

Diagnosing the errors you'll hit mirroring TIF

The most common failure mode has a name on Tradovate's own forum: "Cannot Modify Time In Force." Multiple traders reporting this error found that the API rejects modify requests attempting to change TIF, and the fix in nearly every case was adding the original `timeInForce` back into the modify body rather than trying to change it directly.

Bracket order rejections tend to come from a different source: wrong `orderType` values on the TP or SL leg, or missing explicit prices. Forum threads on bracket order behavior around expiration show that brackets are created suspended and only become working once the primary order fills, so any time-based exit logic you want has to account for that suspended window, sometimes with application-layer logic rather than a native field.

A few other patterns show up often enough to watch for:

  • Race conditions between a leader fill and a follower fill can create duplicate or mismatched positions, and sequencing or queuing the follower calls with a reconciliation pass afterward closes that gap.
  • Latency between the leader's fill event and the follower's order placement is the single biggest driver of price divergence in multi-account mirroring.

Slower follower fills widen the gap between leader and follower entry prices, and websocket-based mirroring closes that gap far more reliably than polling-based or desktop-hop architectures. Retrying failed placements with backoff, rather than firing repeated instant retries, also reduces the odds of a duplicate fill during a brief API hiccup.

Building a runbook for reliable TIF mirroring at scale

Preserving TIF correctly is only half the job. The other half is making sure that fidelity doesn't come at the cost of blown accounts when something goes wrong at 2 a.m.

  • Set per-account max-contract limits and quantity multipliers before any follower order goes out, so a leader's size doesn't overwhelm a smaller follower account.
  • Lean on broker-enforced daily loss limits and profit targets set directly on Tradovate, and pair them with rogue-trade detection at the copier level to catch orders the follower account didn't actually intend to place.
  • Keep order-state logs, run fill reconciliation regularly, and wire up alerting through a webhook or Discord integration so a stuck order gets noticed in minutes, not hours.
  • Test the full mirroring flow on evaluation accounts first, and keep flatten-all and cancel-all commands ready alongside idempotent request handling for when a session needs to shut down fast.

Pro Tip: Run a weekly reconciliation pass comparing leader fills against follower fills, even when nothing looks broken. Small TIF mismatches tend to surface as position drift long before they show up as an outright error.

Why exact parameter preservation matters more than it looks

Why exact parameter preservation matters more than it looks — overview diagram
Why exact parameter preservation matters more than it looks — overview diagram

Strict TIF mirroring simplifies life in ways that aren't obvious until an account gets audited by a prop firm. When every follower order carries the leader's exact `timeInForce` and `expireTime`, reconciliation becomes a matter of comparing two logs rather than reconstructing intent after the fact, and that matters when a firm disputes a fill.

That said, exact mirroring can't run unchecked. A leader's order size or duration might not fit every follower account's risk profile, which is why per-account limits have to sit alongside strict parameter fidelity, not instead of it. TradeDupe's real-time mirroring and OAuth-based connection model were built around that balance: preserve what the leader intended, but never let fidelity override an account's own guardrails.

> — Andres

How TradeDupe handles TIF mirroring in production

TradeDupe was built specifically for Tradovate, and preserving order intent is the core of how it mirrors trades. When a leader account fires an order, TradeDupe carries the same `timeInForce` and `expireTime` onto every enabled follower account over a live WebSocket stream, and if that order needs to change in a way that would alter its TIF, TradeDupe restates the original value on modify rather than letting a rejection break the mirror.

TradeDupe
TradeDupe

The platform layers safeguards on top of that fidelity:

  • Connections run through Tradovate's official OAuth flow, so passwords are never stored and nothing runs on a local PC or VPS.
  • Rogue-trade detection flags follower trades the copier didn't place, and per-account toggles let you pull any single account out of the mirror instantly.
  • Daily loss limits and profit targets are enforced by Tradovate itself, not just by the copier, which keeps risk control in the broker's hands where it belongs.

If you're running multiple Tradovate accounts across firms like Apex Trader Funding, Tradeify, or MyFundedFutures, you can get started with TradeDupe and connect your first leader and follower accounts in about 10 minutes, backed by a 7-day free trial with one-click cancellation.

Sources

For hands-on work, start with Tradovate's order payload examples and the bracket order expiration thread for lifecycle details, plus TradeDupe's own notes on its mirroring architecture and multi-account playbook for operational context.

FAQ

Why does Tradovate reject my order modification requests?

Tradovate's API rejects modify requests that try to change an order's time in force without restating it, a pattern documented across multiple forum threads. Include the existing `timeInForce` value in your modify payload, or cancel the order and place a new one with the updated TIF instead.

What is the difference between Day, GTC, IOC, and FOK orders?

A Day order expires at the end of the trading session, while GTC (good til canceled) stays working until you cancel it. IOC (immediate or cancel) and FOK (fill or kill) demand instant execution, with IOC allowing partial fills and FOK requiring the entire order to fill immediately or not at all.

Do bracket orders on Tradovate support their own expiration times?

Bracket orders can carry `expireTime` values, but the take-profit and stop-loss legs stay suspended until the primary order fills, as shown in Tradovate's community discussions on bracket lifecycle. When the API's native expiration behavior doesn't cover your use case, an application-layer timed cancel or market close fills the gap.

How does TradeDupe keep follower orders in sync with the leader's time in force?

TradeDupe mirrors every leader fill to enabled follower accounts over a live WebSocket stream and copies the same `timeInForce` and `expireTime` onto each follower order. If a leader order's TIF needs to change, TradeDupe restates the original value on the modify request rather than letting Tradovate's API reject it outright.

What causes execution differences between leader and follower accounts?

Latency between the leader's fill event and the follower's order placement is the main driver of price divergence in multi-account copying. Server-side WebSocket mirroring reduces that gap compared to desktop or VPS-based setups, which is why sequencing, retries with backoff, and reconciliation logs matter for keeping fills consistent across accounts.

For educational purposes only. Not financial advice. Futures trading involves substantial risk of loss and is not suitable for every investor.