Skip to content

Partial fills#

Binance can fill an order across multiple matches at different prices. HookTrader normalises this so each order lands as a single trade-leg record with the qty-weighted average fill price.

Where partials show up#

  • Entry MARKET order — usually fills in one shot, but on thin testnet liquidity (or unusually large size on mainnet) you may see multiple matches. The leg row aggregates them.
  • TP STOP_MARKET / TAKE_PROFIT_MARKET algos — these are reduceOnly. The qty is capped at the current position, so partials are rare but possible if the position has just been reduced by another action.
  • Manual reduceOnly closes — same as above.

Why a leg can show "less qty than expected"#

A few legitimate scenarios:

  1. Lot-size roundingreduce_position with a percent that doesn't divide cleanly into the position rounds down to the nearest LOT_SIZE step.
  2. Position already smaller than expected — another action already reduced it. ReduceOnly clamps to the actual remaining qty.
  3. Race with exchange take-profit — the exchange filled a take-profit between HookTrader reading the position and sending the close order. The close sees less position than expected.

In case 3, HookTrader logs and continues. If the position was actually closed by the exchange (just not by HookTrader's order), it detects this and updates the trade accordingly.

"Closed without a leg" — exchange beat HookTrader to the close#

If HookTrader tries to close part of a position that the exchange has already closed via a take-profit order, Binance rejects the request. HookTrader treats that as a sign that the exchange acted first and checks what happened:

  • If HookTrader finds the matching fill on the exchange, it records it as part of the trade history.
  • If the position is genuinely flat but no matching fill can be found, HookTrader marks the trade as closed. The realised PnL for that fill may be missing from the trade's total because there's no fill data to attribute.

To avoid this race entirely, run cancel_algo_orders at the TP level where you want strategy-driven closes to be authoritative.

Emergency close#

If the resting SL fails to fire and the autonomous monitor detects the position is past its stop, HookTrader places a reduceOnly MARKET close. The leg phase is emergency_close. The trade is marked stopped.

Aggregate qty rule for trades#

The trade's recorded qty is the entry qty only. Do not compute PnL as (exit - entry) * qty * direction — it understates scale-in trades.

For accurate accounting use:

Gross P&L is the sum of realised P&L across all close legs. Net P&L subtracts total commission — only when all legs share the same commission asset.

See Commissions for the MIXED-asset edge case.

What you see in the UI#

  • Each trade leg shows its order's avg fill price, the qty filled, the realised PnL (close legs only), and the commission paid + asset.
  • The Live Trades header re-sums these for the open trade.
  • History rows aggregate to the trade level.