From e4c30215d052b5514aedefe10ddef66fd60cb9f4 Mon Sep 17 00:00:00 2001 From: rux-eth Date: Wed, 16 Sep 2026 22:53:23 -0500 Subject: [PATCH] PartialFillExchange: remove a resting order filled for exactly its leaves_qty When a trade fills a resting order for exactly its remaining quantity, the comparison 'filled_qty > order.leaves_qty' takes the else branch: fill() sets leaves_qty to 0 and the status to Filled, but the order is never pushed to filled_orders, so it stays in 'orders' and in its price-level set. The next event that matches the level (another trade at the price, or a best-price sweep in on_best_bid_update / on_best_ask_update) calls fill() on a Filled order, which returns InvalidOrderStatus and aborts the elapse. Use '>=' so an exact fill is removed like an over-fill. Reproduced on real Hyperliquid L2 + tape data with one-lot post-only orders (about 1 hit per 20k orders); a minimal case is a resting bid of 1.0 behind 2.0 of displayed depth, then a 3.0 sell print at the price followed by any later print at the same price. --- hftbacktest/src/backtest/proc/partialfillexchange.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hftbacktest/src/backtest/proc/partialfillexchange.rs b/hftbacktest/src/backtest/proc/partialfillexchange.rs index be57af6ae..645eab216 100644 --- a/hftbacktest/src/backtest/proc/partialfillexchange.rs +++ b/hftbacktest/src/backtest/proc/partialfillexchange.rs @@ -152,7 +152,7 @@ where // q_ahead is negative since is_filled is true and its value represents the // executable quantity of this order after execution in the queue ahead of this // order. - let exec_qty = if filled_qty > order.leaves_qty { + let exec_qty = if filled_qty >= order.leaves_qty { self.filled_orders.push(order.order_id); order.leaves_qty } else { @@ -192,7 +192,7 @@ where // q_ahead is negative since is_filled is true and its value represents the // executable quantity of this order after execution in the queue ahead of this // order. - let exec_qty = if filled_qty > order.leaves_qty { + let exec_qty = if filled_qty >= order.leaves_qty { self.filled_orders.push(order.order_id); order.leaves_qty } else {