IOC vs FOK, Market and Limit Orders: Order Types for Algorithmic Forex Execution Wednesday November 4th, 2026 – Posted in: Arbitrage Software, Forex trading

BJF TRADING GROUP · FOREX EXECUTION

IOC, FOK, Market or Limit: Choosing the Order That Fits the Trade

An order type is a decision about what you would rather suffer: a worse price, a smaller fill, or no fill at all. This guide shows how each instruction behaves in the book, in FIX messages and under last look, with worked numbers for an algorithm that has to choose in milliseconds.

Short answer: IOC vs FOK. An Immediate-or-Cancel (IOC) order takes whatever is available now at your price or better and cancels the rest, so a partial fill is possible. A Fill-or-Kill (FOK) order must fill in full immediately or it is cancelled completely, so you get all of it or nothing. Use IOC when any part of the size is useful, and FOK when a partial position would be worse than none.

Order type and time in force are two separate decisions

Most glossaries list market, limit, stop, IOC and FOK as if they were five options from the same menu. They are not. Two independent questions sit behind them, and an algorithm has to answer both for every order:

  • What price am I willing to accept? That is the order type: market (any price), limit (this price or better), stop (activate when a trigger trades or is quoted).
  • How long may the order stay alive? That is the time in force, or TIF: immediately (IOC, FOK), until the end of the session (Day), until cancelled (GTC) or until a set time (GTD).

So IOC and FOK are not alternatives to a limit order. They are lifetimes attached to one. “Limit IOC” and “Limit FOK” are the two most common aggressive instructions in algorithmic forex, and the FIX protocol keeps the two decisions in separate fields: OrdType (tag 40) and TimeInForce (tag 59).

PriceOrder type, tag 40Market, limit, stop, stop-limit. Sets the worst price you accept.
TimeTime in force, tag 59IOC, FOK, Day, GTC, GTD. Sets how long the order may wait.
SizeFill ruleFull only (FOK), any size (IOC), or a minimum quantity (tag 110) where supported.

Market orders in forex: what “at market” really means

A market order says: fill me now, the price is secondary. It has no limit, so it carries the highest certainty of execution and no protection against the price you get. If the book has moved or is thin, the order walks up through the available levels until the size is done. That cost is slippage, covered in depth in our guide on how to measure and reduce forex slippage.

Forex adds two details that exchange-based explanations skip:

  • There is no single central book. Your broker or ECN shows an aggregated stream from several liquidity providers. “At market” means at the best price your venue can get from that stream, not at a universal market price.
  • A market order still has an implicit lifetime. Many venues treat market orders as IOC or FOK internally: fill what can be filled now and report the rest. Some let you add a maximum deviation, which effectively turns the order into a limit. Do not assume; read the venue’s specification.

The practical role of a market order in an algorithm is narrow. It belongs where not trading is the bigger danger, such as closing a position that has lost its hedge.

Limit, marketable limit and stop orders

Passive limit orders

A limit order placed away from the current price rests in the book and waits. A buy limit below the ask does not take liquidity; it offers it. You may earn the spread instead of paying it, but you take on queue risk and adverse selection: passive orders tend to get filled when the market is moving through them. Passive orders are normally paired with Day, GTC or GTD.

Marketable limit orders

A buy limit priced at or above the current ask executes immediately, like a market order, but it cannot fill beyond its limit. This “marketable limit” is the workhorse of automated execution. Combined with IOC, it means: take liquidity now, down to this price, and leave nothing behind in the book.

The price improvement point is often misunderstood. A limit is the worst acceptable price, not the fill price. If you buy with a limit at 1.08510 and the ask is 1.08502, you should receive 1.08502 or the next levels up to your limit.

Stop and stop-limit orders

A stop order is dormant until the trigger is reached, and then it becomes a market order. A stop-limit becomes a limit order instead. The first guarantees activation, not the price. The second caps the price but can leave you unfilled exactly when the market gaps, which is an unpleasant property for a protective stop. Where the stop lives also matters: a stop held on the venue survives your disconnection, while a stop simulated in your own software does not.

Time in force: the full list

Instruction FIX 59 Lifetime Partial fill? Typical use
Day 0 Until the session ends Yes Passive quotes during a defined session
GTC (Good Till Cancel) 1 Until cancelled Yes Resting entries, take-profit and stop orders
IOC (Immediate or Cancel) 3 Executes at once, rest cancelled Yes Taking liquidity when any part of the size helps
FOK (Fill or Kill) 4 Full size at once or nothing No All-or-nothing entries and fixed-size legs
GTD (Good Till Date) 6 Until a specified time (tag 126 or 432) Yes Quotes with a hard expiry, such as before a news release

Values are from the FIX 4.4 specification. Venues normally support only part of the list, and some restrict a TIF to certain order types, so the rules of engagement of your broker override any table in an article.

IOC vs FOK vs market: one order book, three results

Take a concrete case. An algorithm wants to buy 2,000,000 EURUSD. Best ask is 1.08500, and this is the visible offer side when the order arrives:

Ask price Available size Cumulative
1.08500 500,000 500,000
1.08501 500,000 1,000,000
1.08503 1,000,000 2,000,000
1.08506 2,000,000 4,000,000
Order book walk comparing a market order, an IOC limit and a FOK limit for a 2 million EURUSD buy: the market order fills fully at 1.085018, the IOC fills 1 million at 1.085005, and the FOK is cancelled
The same book, three instructions. The book is a constructed example; the arithmetic is exact.
Instruction Filled Average price Cost vs best ask Result
Market, 2M 2,000,000 1.085018 0.175 pip, about $35 Done, at a price you did not choose
Limit 1.08502 IOC, 2M 1,000,000 1.085005 0.05 pip, about $5 Half the size, 1M cancelled
Limit 1.08502 FOK, 2M 0 None $0 Killed: only 1M at or below the limit
Limit 1.08503 FOK, 2M 2,000,000 1.085018 0.175 pip, about $35 Filled: the limit was wide enough

The last row is the subtle one. One extra tenth of a pip turned the FOK from no trade into a full fill, at a better average than its limit. FOK does not mean “tight”. It means “the whole size must fit under this price at this moment”. The IOC and the FOK at the same limit see the same liquidity. They differ only in what they do when it is not enough.

There is also no universally cheaper instruction. The $5 IOC looks like a bargain against the $35 market order, but it delivered half of the position. If the remaining 1M has to be bought later at a worse price, the comparison changes. That cost of the missing size is what the rest of this guide is about.

How the orders look in FIX

On a FIX API connection you state each instruction explicitly in a NewOrderSingle message (35=D). Simplified to the fields that matter, the IOC order from the example looks like this:

35=D | 11=A1001 | 55=EUR/USD | 54=1 | 38=2000000 | 40=2 | 44=1.08502 | 59=3

Change 59=3 to 59=4 and the same order becomes FOK. Remove the price and set 40=1 and it is a market order. The header, checksum, timestamps and account fields are left out here, and symbol format varies by venue: some use numeric symbol IDs.

Tag Field Values you will meet
40 OrdType 1 Market, 2 Limit, 3 Stop, 4 Stop-limit, D Previously quoted
59 TimeInForce 0 Day, 1 GTC, 3 IOC, 4 FOK, 6 GTD
110 MinQty Minimum quantity that must execute, where supported
150 ExecType 0 New, F Trade, 4 Canceled, 8 Rejected, C Expired
39 OrdStatus 0 New, 1 Partially filled, 2 Filled, 4 Canceled, 8 Rejected, C Expired
14 / 151 CumQty / LeavesQty Filled so far / still open. LeavesQty 0 means the order is finished
31 / 32 / 6 LastPx / LastQty / AvgPx Price and size of this fill / average across all fills

The tricky part is not sending the order but reading the answer. One IOC can produce a sequence of ExecutionReports (35=8), and how the remainder is reported depends on the venue.

FIX lifecycle of a 2 million IOC order: NewOrderSingle, two trade execution reports with CumQty rising to 1 million, then a cancel or expire report for the remaining 1 million with LeavesQty zero, and the algorithm hedging only the filled quantity
An IOC is complete only when LeavesQty reaches 0. Your position is CumQty, never the quantity you requested.

Some venues send an extra acknowledgement (150=0) before the fills. Others deliver one aggregated fill. FIX 4.2 sessions use different ExecType values for fills (1 and 2) than FIX 4.3 and later (F). A robust handler therefore keys on CumQty, LeavesQty and OrdStatus, not on a fixed number of messages. The walk-through of the FIX protocol explains the session layer underneath these messages.

Full-amount liquidity and last look: why forex is different

Stock-market explanations assume a central limit order book where a displayed offer is firm. Forex venues can behave differently in two ways that directly affect IOC and FOK.

Sweepable vs full-amount liquidity. In a sweepable book, an order can take several levels from several providers, like the example above. In full-amount pricing, a provider quotes one price for the entire size and the tiers are not additive, so a FOK for 2M should be matched against the 2M tier, not against the sum of the 1M quotes. The same-looking depth display can therefore mean different things.

Last look. Where a provider applies last look, your order is a request that it may still reject after a short hold. An FOK can be rejected although the book displayed enough size at the moment you sent it, and an IOC can come back smaller than displayed. The FX Global Code asks providers that use last look to disclose this practice to clients, so ask for that disclosure. Rejects from last look are visible in your log only if you record them. The mechanics are covered in our guide to broker execution, A-book, B-book and last look.

Why this matters for measurement: an aggressive order on a last-look venue can show excellent slippage statistics, because only the fills that suited the provider are in the sample. A low average slippage combined with a high reject rate is not good execution.

Where to place the limit: a worked model

For an IOC or FOK the key parameter is not the TIF but the limit price. Set it at the current quote and most signals miss. Leave it unlimited and the worst fills eat the edge. Between those extremes there is a calculable answer.

Consider a short-lived signal with an expected edge of 1.2 pips after commissions, measured from the signal price. Between the signal and arrival at the venue the price moves. Assume two regimes: in 80% of cases the price drifts about 0.2 pip against you (standard deviation 0.3 pip), and in 20% a fast move carries it around 2 pips away (standard deviation 1 pip). These inputs are illustrative. In practice you estimate them from your own order log.

Illustrative model: expected net pips per signal rises with limit tolerance, peaks near 0.82 pips at a tolerance of about 1.2 pips, and falls to 0.64 pips for an unlimited market order, while the fill rate rises from 21 percent to 100 percent
Illustrative model, not trading results: 1.2-pip edge and a two-regime price drift. A fill occurs when drift is within the tolerance.
Limit tolerance from signal price Fill rate Average net per fill Expected net per signal
0 pip (limit at the signal price) 20.7% 1.38 pips 0.29 pip
0.3 pip 51.3% 1.18 pips 0.61 pip
0.6 pip 74.3% 1.05 pips 0.78 pip
1.2 pips (equal to the edge) 84.2% 0.98 pip 0.82 pip
2.0 pips 90.0% 0.89 pip 0.80 pip
No limit (market order) 100% 0.64 pip 0.64 pip

Three conclusions hold well beyond this example:

  • The best limit is the break-even price, not the quote. Any fill that still leaves positive expected profit is worth taking. In this model the maximum sits exactly where the tolerance equals the edge, because the next marginal fill earns zero.
  • The curve is flat near the top. Between 0.8 and 2 pips, expected profit barely changes. You do not need a precise tolerance, but you do need one.
  • Average fill price is a misleading target. The tightest limit has the best price per fill (1.38 pips) and the worst result per signal (0.29 pip), because 79% of the signals never trade.

The model ignores queue effects and assumes the whole size fills whenever the limit is reached. For larger orders, repeat the calculation with your real depth, since the limit also decides how much size can fit. Check the assumptions with data: our guide to the gap between backtests and live execution shows how to bring execution time into a test.

Handling partial fills without creating new risk

A partial fill is not an error, but it is a new state that the algorithm must have a rule for. FOK avoids this state on the entry; IOC moves the problem into your logic. Decide the policy before going live:

Remainder policy When it fits Risk to control
Accept and manage what was filled Entries with a size-independent edge Position too small to cover fixed costs
Re-send the remainder at a new price Signal still valid, edge still above tolerance Chasing. Cap retries and re-check the edge each time
Hedge or complete on another venue Multi-leg trades Different lot steps and a second chance of no fill
Flatten the filled part A fill below the viable size Paying the spread twice

Two-leg trades need the most care. Suppose a hedged trade buys 2M on venue A with IOC and sells on venue B. If A fills 1M and the algorithm still sells the planned 2M, it holds an open 1M short. At about $100 per pip per million on EURUSD, a 10-pip move against that position costs $1,000, which easily exceeds the edge of many trades. The rule is simple: size the second leg from CumQty of the first, never from the requested quantity.

Also convert to the size grid of the second venue. If leg one fills 1,370,000 and venue B accepts steps of 100,000, you can hedge 1,400,000 or 1,300,000, not the exact size. Set a rule for that residual as well, and treat an unhedged residual as a risk limit.

FOK on the first leg removes the size mismatch but creates more no-trade events. FOK on the second leg is usually a poor choice: when the first leg is already filled, a killed hedge leaves you fully exposed. That second leg is exactly where certainty of execution is worth paying for.

Which order for which strategy

Decision flowchart for choosing an order type: if the position must change now use market or a wide IOC; if a partial fill is useless use FOK; if taking liquidity with any useful size use limit IOC; otherwise rest a passive limit with Day, GTC or GTD
A starting point for the decision. The venue rules and your fill data have the final say.
Situation Reasonable default Reasoning
Latency arbitrage entry Limit IOC at the break-even price The edge decays in milliseconds; a partial fill still earns, and the limit stops the tail
First leg of a hedged pair Limit FOK or IOC with hedging by CumQty FOK protects sizing; IOC gains fill rate but needs better logic
Second leg, when the first is filled Market or wide IOC Being unhedged is the larger risk
News-driven entry Limit IOC, tight size Spreads and depth change quickly, and a market order has no ceiling
Emergency exit or stop-out Market or wide IOC, repeated until flat Certainty first; FOK can leave the position open
Pairs or statistical trades Limit IOC or short-lived passive limit The holding period is longer, so spread paid matters more than speed
Spread capture and rebalancing Passive limit, Day or GTD You are paid for waiting, and you must cancel before news and rollover

Execution also depends on timing. Around rollover and news, spreads widen and depth thins, so a limit that fills well at London noon can fail or turn expensive in those windows. Make tolerance and size depend on the current spread instead of fixing them for the whole day. A deeper look at speed-sensitive strategies is available in our guide to latency arbitrage.

Seven steps to configure order execution

1

Price the missed trade. Decide what no fill costs. For an optional entry it is zero; for a hedge or an exit it is open risk.

2

Compute the worst acceptable price. Take the expected edge, subtract commission and a safety margin, and set the limit at that break-even.

3

Choose the lifetime. Use IOC or FOK for taking liquidity and Day, GTC or GTD for resting orders.

4

Set the smallest useful fill. Use FOK, or a minimum quantity where supported, if small fills cannot cover fixed costs.

5

Write the remainder rule. Define retries, a maximum number of attempts and what happens to any unhedged residual.

6

Confirm the venue rules. Check supported order type and TIF pairs, size steps, how remainders are reported and whether last look applies.

7

Log and review. Record every order, including rejects and cancels, and adjust the limit from real fill data.

Common mistakes in automated order handling

  • Assuming the requested size was filled. Position must come from execution reports, not from the order you sent.
  • Treating a killed FOK as a system error. It is a normal outcome. Alerting on each one trains you to ignore alerts; alert on the rate instead.
  • Retrying at the same price in a loop. If the price has moved, the retry fails too, and fast retries may break message limits. Re-price, or stop.
  • Ignoring the unknown state. When no response arrives, the order may still be live or filled. Query it with an OrderStatusRequest (35=H) or reconcile the position after reconnecting before sending a replacement.
  • Reusing ClOrdID values. A unique tag 11 for each order, including every retry, is what makes reconciliation possible.
  • Using stale prices for the limit. A limit computed from a delayed quote is either too tight or too generous. A fast price feed makes the tolerance meaningful.
  • Testing with perfect fills. A backtest that fills every order in full at the quote cannot tell market from IOC from FOK. Model depth and rejects, or forward-test with small size.
  • Carrying settings between venues. A tolerance tuned on one broker says little about another, because depth, last look and latency all differ.

What to measure

Choosing an order type is an empirical question, and only a complete log can answer it. Reports should cover signals and attempts, not just completed trades.

Metric Definition What it tells you
Fill ratio Filled quantity / requested quantity Too low means the limit is tight or depth is thin
Reject rate Rejected or killed orders / orders sent A sudden rise suggests liquidity or broker changes
Slippage Fill price minus reference price at signal, signed Execution cost per filled trade
Round-trip time Order sent to first execution report Whether the venue is slowing down, by time of day
Net per signal Total result / all signals, including missed ones The number that should drive the tolerance

Split these figures by symbol, venue, hour and order type, and compare the results before and after every change. SharpTrader shows orders and performance statistics with PnL, slippage and execution time, which is a practical base for this kind of review. Which order types and TIF values are available in a given setup depends on the connector and on the broker, so confirm them for your own account.

Build execution around your own data

SharpTrader connects to brokers over FIX API and other protocols, runs arbitrage and non-arbitrage strategies, and records slippage and execution time for each order. To tune parameters against that data, the SharpTrader Optimizer automates the search.

Explore SharpTraderSharpTrader Optimizer

Free arbitrage scanner + short email course

Get the free scanner link and a few short, practical emails from Boris: what a price gap really means after costs, how to test a strategy before risking real money, and which tools fit your market. No hype.

By submitting, you agree to receive emails from BJF Trading Group about arbitrage tools and trading software. Unsubscribe anytime. See our Privacy Policy.

Frequently asked questions

What is the difference between IOC and FOK?

Both execute immediately and never rest in the book. IOC accepts a partial fill and cancels the unfilled remainder. FOK requires the entire quantity to fill at once, otherwise the whole order is cancelled and nothing trades.

Is FOK better than IOC?

Neither is better in general. FOK suits trades where a partial position is useless or complicates a hedge. IOC usually trades more often, because some size gets done, but your algorithm must handle partial fills correctly.

Can a FOK order be partially filled?

No. By definition a FOK order either fills in full or not at all. If you see a partial execution, the order was not a true FOK at that venue, so check how the broker maps the instruction.

What happens to the unfilled part of an IOC order?

It is cancelled immediately and never rests in the book. On FIX you receive an execution report that closes the order, usually as Canceled or Expired depending on the venue, with LeavesQty of 0.

Is a market order the same as an IOC order?

Not exactly. A market order has no price limit, while an IOC normally has one. Many venues do run market orders with IOC or FOK behavior, so the lifetime can match, but only a limit protects the price.

What are the FIX values for IOC and FOK?

In the TimeInForce field, tag 59, IOC is 3 and FOK is 4. The order type is set separately in tag 40, where 1 is market and 2 is limit.

Do all forex brokers support IOC and FOK?

No. Support depends on the broker, the platform and the connection type. FIX API connections usually expose more control, but each venue publishes its own list of accepted order type and time-in-force combinations.

This article is educational and is not investment advice. The order book and the model are illustrative examples, not trading results. Trading foreign exchange involves a significant risk of loss.