fbpx
Tickerly Trading bot service logo

BLOG

Partial Fills in Trading Bots: Track 5 FIX Fields, Prevent State Bugs

by

A partial fill is an order that executes for only part of the requested quantity, and a correct bot treats each fill as an event. It updates CumQty, recomputes LeavesQty from the exchange report, and never assumes full execution. Then it follows its strategy: wait, convert the remainder, or reprice it.


TL;DR:

  • Market orders can partially fill and expire, while resting limit orders may remain open; read ExecType, OrdStatus, CumQty, LastQty, LastPx, and LeavesQty from reports.
  • Treat the exchange’s CumQty and LeavesQty as authoritative, make report handlers idempotent, and query status after reconnects or cancel requests before changing exposure.
  • Patient handling waits until a timeout and risks delay; aggressive handling converts the remainder to market, while adaptive repricing trades between speed and slippage.
  • Attach protective orders only to filled quantity, resize them as CumQty grows, and block replacement orders until cancellation is confirmed to prevent doubled exposure.
  • Test partial fills followed by cancels, duplicated or out of order reports, and rate limits; after outages, reconcile status and balances before trading again.

Tickerly
Automate TradingView Strategy Execution
Tickerly turns TradingView strategies into trading bots, helping active traders automate execution across crypto, forex, and stock exchanges.

Visit Tickerly

Table of Contents

How do exchanges report a partial fill?

Exchange documentation describes a partial fill as an order that executes for only part of the requested quantity because liquidity at the target price runs out. Market orders can be partially filled and then expire, while limit orders may rest on the book with a remaining quantity. FIX-style APIs define LeavesQty (Tag 151) as OrderQty (Tag 38) minus CumQty (Tag 14).

Read these fields from every execution report:

  • ExecType (150): the event that produced this message, such as a trade or a cancel.
  • OrdStatus (39): the state of the order as a whole, such as partially filled, filled or canceled.
  • CumQty (14): the total filled so far, your running evidence of execution.
  • LastQty (32) and LastPx (31): the size and price of this single fill.
  • LeavesQty (151): the open amount, which can be zero in terminal states like canceled.

Some exchanges send a partial-fill report followed immediately by a cancel report when a market order sweeps the book and cannot complete, with a text reason attached, as shown in Gemini’s FIX example. A resting limit order, by contrast, usually stays working with LeavesQty above zero. Schemas differ by venue, but broker execution reports commonly carry AvgPrice, ClOrdId, CumQty, LastQty and LeavesQty, so a parser can cover many of them. For the market versus limit distinction, see our market vs. limit orders checklist.

How should a bot track order state?

Separate submission from execution. Developers who treat them as distinct processes avoid bugs such as an oversized protective stop-loss that exceeds what you actually hold. The fix is an explicit execution state machine in which fill acknowledgments and cancel rejections are distinct transitions, not a slippage constant.

A workable model moves from PendingNew to New to PartiallyFilled, then ends in Filled or Canceled. Correlate every event by ClOrdID and ExecID, and keep these rules:

  • Update CumQty and AvgPx from each authoritative report, and derive LeavesQty from the exchange’s numbers rather than your local arithmetic.
  • Make every handler idempotent, so a replayed or duplicated execution report changes nothing the second time.
  • After a reconnect or a cancel request, query order status and reconcile cumulative fills instead of overwriting state with the latest packet.
  • Log each event with ExecID and TransactTime, so audits and debugging can replay exactly what the exchange told you.

Idempotency matters most around the cancel race, where a fill arrives after you asked to cancel. A bot that trusts the last message it saw will size its next order wrong. A bot that reconciles cumulative quantity will not.

Pro Tip: Store the exchange’s CumQty as the source of truth and treat your own running total as a cache. When the two disagree, the exchange wins and you log the discrepancy.

Exchange fill total checked against bot cache

For how sizing should react once the true filled amount is known, read our guide to position sizing methods for bots.

Which partial fill strategies should your bot use?

Three templates cover most needs, and handler examples for patient, aggressive and adaptive approaches exist in open tooling. Each trades execution certainty against slippage and latency.

  1. Patient: wait for the fill with a configurable timeout. On timeout, cancel and optionally convert the remainder to a market order. You pay the least in slippage but accept the most time risk.
  2. Aggressive: if the filled percentage sits below a threshold, cancel and replace the remainder with a market order immediately. You secure execution and accept worse prices.
  3. Adaptive: move the limit price in small steps toward the market, or resubmit smaller limit slices sized by visible depth. It balances the first two but needs more state and more messages.

Supporting tactics make any of the three safer:

  • Bracket and OCO patterns: attach protective orders sized to the filled quantity, and resize them as CumQty grows.
  • Trailing stops: let them follow only the portion actually held.
  • Partial-aware sizing: compute the next order from LeavesQty, not the original target.
  • Double-submit guards: block a replacement order until the cancel is confirmed, since a late fill can otherwise double your exposure.

Our overview of bot strategy essentials shows where these choices fit in the wider design.

What breaks partial fill logic in production?

The classic failure is the cancel race. If your code assumes a single message settles an order’s fate, a fill that lands after the cancel request leaves you holding more than you planned. Reconcile with CumQty and LeavesQty every time. Out-of-order messages and dropped connections cause similar damage, so after any outage, query order status and check balances before trading again. Background on how brokers handle this flow is in our piece on how brokers power automated trading.

Test before going live:

  • Simulate partial fills, including a partial followed by a cancel.
  • Run against exchange testnets and unit test every state transition.
  • Load-test rate-limit behavior, because repricing strategies send many messages.
  • Alert on repeated partials, unexpected LeavesQty growth, and frequent convert-to-market events.

Pro Tip: Replay a recorded session containing out-of-order and duplicated reports through your handler. If the final state differs from the first pass, your handlers are not idempotent.

Why robust partial fill handling decides outcomes

Most bot losses I see traced back to state, not signals. An execution state machine and idempotent handlers give you correct sizing, readable audits and far less surprise slippage. They also make your bot boring in the best way. If you want more detail on what a managed setup records, our automated trading FAQ and the alert log are good next reads.

— Jay

Reliable execution and order tracking with Tickerly

If you would rather not write and maintain this state machine yourself, we connect your TradingView strategies to exchanges within a fraction of a second of each alert, with no VPS for direct exchange connections and no custom code. Two parts of the partial-fill problem are handled for you. Tickerly sends every exit reduce-only, so an exit sized for more than a partial fill actually left you holding is trimmed to what you hold instead of opening a position in the opposite direction. And the alert log records every order and the exchange’s response, so a rejection or an unexpected size is visible straight away. What Tickerly does not do is reconcile your strategy’s idea of the position against the exchange: after an outage, check that the two agree, and use a close all alert to reset a symbol to flat if they don’t. You can run multiple strategies and assets side by side, including crypto, forex and stocks. See our automated trading plans, which start at Level 2 for 19 USD per month, with Level 3 at 29 USD, Level 4 at 39 USD, and Level 4 Ultra for 2,500 alerts a day.

Tickerly

FAQ

Does a trading bot work?

A bot works when it executes a defined strategy consistently and handles order states correctly, including partial fills. Results still depend on the strategy and market conditions, and no bot removes trading risk.

Using a bot on your own brokerage account is generally legal in the United States, but you must follow your broker’s terms and rules against spoofing and wash trading. Federal automated trading rules proposed in 2015-2016 were withdrawn in 2020, so regulation remains principles-based. Check your own jurisdiction.

What is LeavesQty in a partial fill?

LeavesQty is the quantity still open on an order, calculated as OrderQty minus CumQty. A bot should read it from each execution report rather than compute it locally.

Should a bot cancel or keep waiting after a partial fill?

It depends on your strategy. A patient bot waits until a timeout, while an aggressive bot converts the remainder to a market order at once. Either way, confirm the cancel before resubmitting to avoid doubling exposure.

Sources

This article was produced with Al assistance and reviewed for accuracy. It is provided for general information only and is not professional or financial advice.

Tags :

Latest Post