Position sizing: from the stop, not from the balance
The single most useful habit in automated trading is computing size from the distance to your stop. It is also the one most bots get almost right and then lose to fees.
Vizanix engineering · about the author
- SECTION
- Bot architecture
- PUBLISHED
- 2026-08-28
- CHAPTERS
- 6
- READ NEXT
- 3
- LANGUAGE
- written in English
There are two ways to decide how big a position should be. You can pick a notional — “trade 5% of the account” — or you can pick a loss — “risk 1% if the stop is hit” — and derive the notional from where the stop sits. Only the second one keeps risk constant across instruments.
The base formula
Risk in currency divided by the distance to the stop gives quantity:
risk_usd = equity * risk_pct / 100
distance = abs(entry - stop)
qty = risk_usd / distance
notional = qty * entryA tight stop produces a large position; a wide stop produces a small one. That inversion is the whole point — it means a volatile instrument and a quiet one carry the same money at risk. Our position size calculator does exactly this, and the ATR stop calculator shows the volatility-scaled version.
Then fees eat the assumption
The formula above says you lose exactly risk_usd when the stop hits. You do not. You also pay commission on the way in and on the way out, and the stop is usually a taker exit.
The correction is small in percentage terms and large in aggregate. Fold the fee into the distance rather than discovering it in the P&L:
# Effective loss on a stop-out = price move + entry fee + exit fee.
fee_in = maker_rate if entry_is_limit else taker_rate
fee_out = taker_rate # stops are taker exits
cost_pct = (fee_in + fee_out) / 100
effective_distance = distance + entry * cost_pct
qty = risk_usd / effective_distanceThe tighter the stop, the more the fee matters. At a stop distance of 0.3% on a venue charging 0.055% taker, commissions are a third of the intended risk. This is why scalping strategies that look profitable in a backtest so often are not — see the break-even calculator.
Margin is reserved with fees too
On a leveraged venue there is a second correction. The exchange holds initial margin plus commission on the notional, so the largest position your balance supports is roughly free / (1 + leverage × fee_rate), not free × leverage.
At 10× that ceiling is about 99% of free balance; at 50× it is closer to 96%. A bot that sizes to exactly 100% gets rejected on precisely the orders it cared most about.
Then the exchange rounds you
Whatever quantity you computed, the venue will only accept multiples of qtyStep, above minOrderQty, above minNotionalValue. Order of operations matters:
- Round the quantity down to
qtyStep. Rounding up can breach margin. - Check
minOrderQtyafter rounding. - Check
minNotionalValueafter rounding — rounding down can drop you under it. - If the result is below the minimum, decline the trade. Do not round up to reach it: that silently takes more risk than the strategy authorised.
And then the balance moves anyway
Even with all of the above correct, the venue can still answer 110004 insufficient balance. Another position moved. Funding settled. A second process took margin. The balance you read a moment ago is history.
Our executor handles this with a retry ladder rather than a failure: read the fresh remaining balance, shrink the size, re-quote — up to five attempts, stopping at the venue's minimum lot. A rejected signal becomes a smaller position, which is almost always what the operator would have chosen.
What to expose
Whatever the sizing logic, make its inputs visible in the audit log: equity used, risk percentage, stop distance, fee assumption, pre-rounding quantity, post-rounding quantity, and any retry. When a position turns out to be a different size than expected — and it will — that record is the difference between a five-minute answer and an afternoon.
This article describes engineering practice. It is not investment advice. Vizanix develops software and does not promise trading returns.