execution
order-sizing
exchanges
trading-infrastructure
crypto

The Last Mile of Execution: Turning a Target Into an Order an Exchange Will Accept

Jonny Bravo
  -  

...

The Last Mile of Execution: Turning a Target Into an Order an Exchange Will Accept

Your strategy decides something clean: hold $1,000 of BTC perp. The engine translates that to a base quantity: 1000 / price. Then you hand it to the exchange, and the exchange rejects it — because the real world has rules your clean number ignored. Quantities must come in increments of some lot size. There's a minimum order amount. There's a minimum notional cost. Floating-point arithmetic produced 0.09999999999999998 when you meant 0.1, and the venue's filter says no.

This is the last mile of execution, and it's where a surprising number of trading systems quietly bleed. Not with a crash — with a silent drop. The order gets rejected, the position never opens, and the strategy that backtested beautifully simply... doesn't trade, and nobody notices until the monthly P&L is mysteriously flat. The strategy was fine. The translation from "what I want" to "what the exchange will accept" was broken.

We treat that translation as a first-class problem with one job: produce a quantity the exchange will actually take, or honestly return nothing.

Every constraint, in the right order

The sizing function applies the full stack of exchange constraints — lot size, minimum amount, minimum cost — and the order it applies them in is the entire ballgame:

def calculate_actual_target_quantity( raw_quantity, reference_price, lot_size=None, min_amount=None, min_cost=None, symbol="UNKNOWN", exchange="UNKNOWN"): """Calculate the actual target quantity after applying all exchange constraints: - Lot size rounding - Minimum quantity requirements - Minimum cost requirements This ensures quantities are exchange-compliant and can be executed."""

Direction is preserved up front so a short never accidentally becomes a long during rounding — sign is extracted, magnitude is worked on, sign is restored at the end:

sign = 1 if raw_quantity > 0 else -1 quantity = abs(raw_quantity) quantity = round(quantity, 6) # tame floating-point dust before any comparison

The floating-point detail that saves real trades

Here's the kind of bug that only shows up in production, and the code guards against it explicitly. Floating-point math produces values like 0.09999999999999998 when the true answer is 0.1. Compare that naively against a lot size of 0.1 and you conclude the quantity is below the lot size — so you drop the trade. The strategy wanted to trade; the IEEE 754 representation said otherwise.

# If lot_size is specified, round up to nearest lot_size if we're very close. # This handles floating-point precision issues where 0.09999999999999998 should be 0.1. if lot_size and lot_size > 0: tolerance = lot_size * 1e-6 remainder = quantity % lot_size if remainder > 0 and (lot_size - remainder) < tolerance: quantity = quantity + (lot_size - remainder) quantity = round(quantity, 6)

A tiny tolerance relative to the lot size: if you're within a rounding error of the next increment, snap up to it. This is the difference between a trade that fills and a trade that vanishes — and it's exactly the kind of detail you only get right after watching it go wrong on a live venue.

"Most restrictive wins" — and the honest None

Minimum amount and minimum cost are two different floors, and the exchange enforces both. The function computes the effective minimum as the more restrictive of the two — converting the cost floor into a quantity floor at the current price — and lifts the order to clear it:

min_quantity_from_cost = min_cost / reference_price if (min_cost and reference_price > 0) else None if min_amount and min_quantity_from_cost: effective_min_quantity = max(min_amount, min_quantity_from_cost) elif min_amount: effective_min_quantity = min_amount elif min_quantity_from_cost: effective_min_quantity = min_quantity_from_cost

Then lot-size rounding is applied, with a careful correction: if rounding down to a lot boundary dropped you back below the minimum, round up a lot instead. After all of it, there's a final validation — and if the quantity still can't satisfy every rule, the function returns None:

if effective_min_quantity and quantity < effective_min_quantity: logging.warning(f"Quantity {quantity} below minimum ... for {symbol} on {exchange}") return None if min_cost and reference_price > 0: if quantity * reference_price < min_cost: logging.warning(f"Cost {quantity*reference_price:.2f} below minimum {min_cost:.2f} ...") return None

That None is the most important value the function returns. It means: this target cannot be expressed as a valid order on this exchange, and I will not send a malformed one. A position too small to meet the venue's minimum simply isn't opened, and the reason is logged with the symbol and exchange. No silent rejection, no malformed order burning a run-window retry — an explicit, logged, intentional decline.

Why the unglamorous last mile is where trust is won

Nobody writes a landing page about lot-size rounding. It's the least sexy code in the entire stack. And it is precisely the code that determines whether the strategy you so carefully backtested actually trades when the money is real.

A platform that nails the last mile — that handles floating-point dust, reconciles two different minimums, preserves direction, and declines honestly when a target is unexpressible — is a platform where the gap between "what the strategy decided" and "what hit the exchange" is closed correctly, every time, across every venue's idiosyncratic rules. A platform that skips it has a beautiful research tool sitting on top of an execution layer that randomly eats trades.

The strategy is the idea. This is the part that makes the idea happen in a market that doesn't care how clean your number was. Getting it right isn't glamorous. It's just the difference between a backtest and a track record.


Strategies target clean dollar amounts; the executor turns them into exchange-compliant orders — or declines, loudly. See how execution works →

Article Contents

Related Articles

© 2026 Fluxy, Inc. All rights reserved.