What is lot size? Quantity step, minimums and contract units
Figures on this page are as of 2026-09. Fees, limits and margin tiers change — check the venue's own docs.
Lot size is the set of rules a venue applies to order quantity for a symbol — a minimum, a maximum, and a step size that every quantity must be an exact multiple of — so a size your code computes has to be moved onto that grid before the order can be accepted.
Almost everyone meets it the same way: a position-sizing formula returns a number with too many decimals and the order is refused. The fix everyone learns is “round down”. This page is about what comes after that: which filter applies to which order type, how minimum quantity and minimum notional interact, what the quantity actually counts on different venues, and how to round in a way that also survives partial exits and closing orders.
The general case for rounding down, and for skipping a trade rather than rounding up to a minimum, is covered in how to calculate position size and symbol filters and minimum order sizes. This page assumes both.
Why this matters now
Three things make lot size harder than it looks:
- There is more than one quantity rule per symbol. On Binance spot,
MARKETorders have a quantity filter of their own. - Quantity is not always counted in coins. Some venues’ formulas are written in contracts, and the grid applies to whatever the order field counts.
- A quantity check and a value check both apply. A size can be a perfect multiple of the step and still fail because it is worth too little.
How it actually works
- The venue publishes the quantity rules per symbol. On Binance spot these
are the
LOT_SIZEandMARKET_LOT_SIZEfilters inGET /api/v3/exchangeInfo. Binance lists them among the per-symbol values that change without notice, so treat them as data, not constants. LOT_SIZEis the symbol’s quantity rule;MARKET_LOT_SIZEis the same kind of rule forMARKETorders. Both reject a quantity that is too high, too low, or off the step.- Value checks run separately.
MIN_NOTIONALrejects an order whoseprice * quantityis too low;NOTIONALrejects one outside a range with both a minimum and a maximum. - The rejection names the filter — on spot, as
-1013with amsgsuch as “Filter failure: LOT_SIZE”. - On USDⓈ-M futures, the same violations have their own codes. An
off-step quantity is
-4023 QTY_NOT_INCREASED_BY_STEP_SIZE, “Qty not increased by step size.” A too-small order is-4164 MIN_NOTIONAL: “Order’s notional must be no smaller than %s (unless you choose reduce only)”. The threshold is in the futuresexchangeInfofilters. - Hyperliquid publishes size precision per market as
szDecimalsin itsmetainfo response, with the rules on its tick-and-lot-size page, and rejects small orders with “Order must have minimum value of …” — the threshold is embedded in the string, so read it from the error-responses page rather than from any article, including this one.
LOT_SIZE vs MARKET_LOT_SIZE
The split causes a specific bug. A client places a limit order sized against
LOT_SIZE, the order does not fill, and a fallback path converts it to a
market order of the same quantity. That quantity was never checked against
MARKET_LOT_SIZE, and the fallback — usually the urgent path, such as
exiting — is the one that gets rejected with “Filter failure:
MARKET_LOT_SIZE”.
Validate against the filter for the order type you are about to send, at the moment you decide the type, not when you first computed the size.
Minimum quantity vs minimum notional
| Rule | Unit | Depends on price? | What fails it |
|---|---|---|---|
| Minimum quantity | Quantity units | No | A small size in any market |
| Step size | Quantity units | No | Too many decimals, or a non-multiple |
| Minimum notional | Money | Yes | A small size at a low price |
Maximum notional (NOTIONAL) | Money | Yes | A large size at a high price |
The notional rules are the ones that move. The same quantity can pass at one price and fail at another, so they must be checked at runtime against the order’s actual price, not validated once in a config file. For how notional is computed on different contract types, see what is notional value.
One exception is worth knowing. The futures -4164 message itself says
reduce-only orders are exempt from the minimum notional. That matters when
closing a small leftover position: sent as a
reduce-only order, it is not blocked by
the value floor. It still has to be on the step grid.
Contracts vs coins
The step applies to whatever the order’s quantity field counts, and that is not the same thing everywhere. What the venues’ own formulas show:
| Venue | Published formula | What that tells you |
|---|---|---|
| Binance spot | Notional = price * quantity | Quantity is in units of the asset |
| Bybit USDT perpetual | Order value = qty × executed price | Quantity multiplies price directly |
| OKX USDT-margined swap | Fee = rate × (contracts × multiplier × contract size × fill price) | Position value is built from a number of contracts |
| Hyperliquid perps | Initial margin = position_size * mark_price / leverage | Size is in units of the asset, with per-market decimals |
If a venue sizes orders in contracts, the conversion comes before the rounding: turn your coin quantity into a contract count using the instrument’s contract size and multiplier, then round the count down to the step. Rounding the coin quantity and converting afterwards can land between contracts. Inverse contracts add a further twist, covered in inverse vs linear contracts.
Rounding a computed size down, safely
from decimal import Decimal, ROUND_FLOOR
def order_qty(ideal: str, step: str, min_qty: str, max_qty: str,
min_notional: str, price: str) -> str | None:
s = Decimal(step)
q = (Decimal(ideal) / s).to_integral_value(rounding=ROUND_FLOOR) * s
cap = (Decimal(max_qty) / s).to_integral_value(rounding=ROUND_FLOOR) * s
q = min(q, cap)
if q < Decimal(min_qty) or q * Decimal(price) < Decimal(min_notional):
return None # does not fit the risk budget: skip, do not round up
return format(q.normalize(), "f")
- Inputs are strings. Building decimals from floats imports the float’s error; the same reasoning is laid out for prices in what is tick size.
- Division by the step, then floor. This works for any step, not only powers of ten, and always moves toward less risk.
- The maximum is also floored. Capping at a maximum that is itself off the grid would reintroduce the error.
Noneis an answer. A caller that receives no quantity should not place a trade; the position size calculator gives the ideal size, and this function decides whether it is expressible.
Partial exits and closing orders
Rounding down is safe for entries. For exits it needs one more rule: compute the last piece as a remainder, never independently.
Suppose you close half a position, then the rest. If each half is computed as
“position ÷ 2, rounded down”, the two pieces can sum to less than the
position, leaving a residue. If that residue is smaller than the step, it
cannot be expressed as a valid quantity at all. Instead, round the first piece
down and send the second as position − first piece. If the position was on
the grid, the remainder is too, and the two orders close it exactly. The
trade-offs of scaling out are in
partial exits and expectancy.
The same reasoning applies to closing a position you did not size yourself: read the exact position quantity the venue reports and send that, rather than recomputing it from your own records.
Where the boundary should sit
- Sizing produces an ideal; the lot filter decides what is sendable. Keep these as two functions, and let the second one refuse.
- Check the filter that matches the order type, including on fallback paths.
- Check notional at the order’s price, at send time.
- Convert units before rounding on venues that count contracts.
- Size exits as remainders, and close positions from the venue’s reported quantity.
- Never let a model’s number reach the order field directly. A model asked for a size returns a plausible decimal with no knowledge of the step; it is an input to this routine, not its output.
FAQ
What is lot size in crypto trading?
Lot size is the set of per-symbol rules for order quantity: a minimum, a
maximum and a step size the quantity must be a multiple of. On Binance spot
they are published as the LOT_SIZE filter, with a separate
MARKET_LOT_SIZE filter for market orders. A quantity that breaks them is rejected
before it reaches the matching engine.
What is the difference between LOT_SIZE and MARKET_LOT_SIZE?
Both constrain quantity on Binance spot. LOT_SIZE is the symbol’s general
quantity rule, and MARKET_LOT_SIZE is a separate rule for MARKET orders.
A quantity checked only against LOT_SIZE is not guaranteed to pass
MARKET_LOT_SIZE, so a client that falls back from a limit order to a market
order must re-check the quantity against the market filter.
What is the difference between minimum quantity and minimum notional?
Minimum quantity is measured in units of the asset or contract and does not depend on price. Minimum notional is measured in money — price times quantity — so the same quantity can pass at one price and fail at another. Check both at send time, using the price the order will actually carry.
What does “Qty not increased by step size” mean on Binance futures?
It is error -4023 on USDⓈ-M futures: the order quantity is not an exact
multiple of the symbol’s step size. Round the quantity down to the step using
decimal arithmetic, and read the current step from the futures exchange
information, since it is set per symbol and can change.