Avtim

研究

Maker-only orders: what "post-only" means on each venue and why a quoting engine cannot live without it

A limit order that would cross the book gets filled as a taker, pays the taker fee, and is not the trade you wanted. Post-only flags exist to prevent exactly that. They are spelled differently on every exchange and behave differently in the corners.

研究文章以英文发布。

2026年10月26日 阅读约 4 分钟 #orders#market-making#venues

A market maker earns the spread by being on the passive side of trades. A limit order placed just inside the best offer is passive only if, by the time it reaches the matching engine, the best offer is still above it. If the market moved in the meantime, the order crosses, executes against the resting book, and the maker has just paid the taker fee for a trade in the wrong direction. Over thousands of quotes a day this is not a rounding error; it is a large share of the toxic flow a quoting engine suffers.

A post-only order is a limit order with an instruction: if executing it would make it a taker, do not execute it. Depending on the venue, the order is then either rejected or re-priced to rest at the best non-crossing level. Either outcome is better than an accidental taker fill.

How each venue spells it

Venue Spot Derivatives If the order would cross
Binance Order type LIMIT_MAKER timeInForce = GTX Rejected (“Order would immediately match and take”)
Bybit timeInForce = PostOnly timeInForce = PostOnly Rejected
OKX ordType = post_only ordType = post_only Rejected
Bitget force = post_only force = post_only Rejected
KuCoin postOnly = true postOnly = true Rejected
Gate time_in_force = poc (“pending or cancelled”) tif = poc Rejected
MEXC Order type LIMIT_MAKER Order type = 2 (“post-only maker”) Rejected

Two behaviours are worth knowing beyond the table. Some venues, and some order types on some venues, re-price a crossing post-only order instead of rejecting it, so that it rests one tick away from the best opposite price. That is convenient, and it means your order is now at a price you did not choose. Check the documentation of the exact endpoint you use, and check it again after the venue’s next API version. And on venues where the post-only rejection is returned through the private order stream rather than in the HTTP response, the connector must treat “order not found” after a post-only placement as a possible rejection, not as a lost message.

What post-only does not do

It does not protect against being picked off. A post-only order that rests is still a resting order; if the market moves through it, it fills as a maker, at a price that is now stale. Post-only removes accidental taker fills, not adverse selection. The defence against adverse selection is speed of cancellation and quote placement, which is a different problem.

It does not change fees retroactively. A venue’s maker rebate applies to fills that were passive at execution; post-only guarantees that any fill you get was passive, which is the point.

It interacts with self-trade prevention. If you run several accounts or several strategies on one venue, a post-only order from one can be rejected because it would match your own resting order from another. Venues with configurable self-trade prevention let you choose which side is cancelled; without it, the post-only rejection is what you get.

Why a quoting engine should default to it

Our own quoting engines place every quote as post-only and treat a taker order as a deliberate, separately logged action. The reasons are practical:

  • Fees. The difference between maker and taker fee on a perpetual venue is often the entire expected profit of a quote.
  • Direction. An accidental taker fill is a fill in the direction the market just moved, which is the direction you least want exposure in.
  • Accounting. When every passive fill is guaranteed passive, the strategy’s realised edge can be computed from fills alone, without reconstructing which side of the book each one came from.
  • Rate limits. A rejected post-only order costs one request. An accidental taker fill costs the hedge that follows it, which is several.

The only cost is the rejection itself: a quote that would have crossed is not placed, and the engine must re-quote. For a maker that is the correct outcome, since the price it wanted no longer exists.

A note on emulation

Venues without a post-only flag can be handled by checking the quote against the latest book before sending, but the check is only as good as the age of the book. Between the last update and the matching engine’s state there is a window of a few milliseconds in which the emulation is wrong. For the venues in the table it is unnecessary; all of them have a native flag on both spot and derivatives.


由 Avtim 工程团队撰写。文中引用的交易所文档数据在撰写时有效;交易场所会在不另行通知的情况下更改限制,因此在以此为基础进行开发之前请先核实。本文内容不构成投资建议。