Conversation
…aves_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.
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 0 |
| Duplication | -17 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What happens
In
PartialFillExchange, when a trade fills a resting order for exactly its remainingquantity,
check_if_buy_filled/check_if_sell_filledtake theelsebranch of(
hftbacktest/src/backtest/proc/partialfillexchange.rs, two sites).fill()then setsleaves_qtyto 0 and the status toFilled, but the order is never pushed tofilled_orders,so
remove_filled_orders()leaves it inself.ordersand in its price-level set. The next eventthat matches the level — another trade at the price, or a best-price sweep in
on_best_bid_update/on_best_ask_update— callsfill()on aFilledorder, which returnsBacktestError::InvalidOrderStatus, and the elapse aborts (return code 14 through the Pythonbinding). The backtest cannot be resumed past that event.
Fix
Use
>=at both sites so an exact fill is removed like an over-fill. Two characters; no otherbehaviour changes (an exact fill already produced the
Filledstatus and the response).Reproduction
Real Hyperliquid L2 + tape data (2025-10-10),
HashMapMarketDepthBacktest,RiskAdverseQueueModel,PartialFillExchange, constant order latency: with one-lot post-only orders across 182 assets theabort fires about once per 20,000 orders. A minimal synthetic case: a resting bid of 1.0 at a price
with 2.0 displayed ahead of it, then a sell trade of 3.0 at that price (fills the 2.0 ahead and
exactly the 1.0), then any later trade at the same price →
InvalidOrderStatus.Notes
py-v2.4.4); the fix branch is one commit ontop of that tag. Happy to rebase onto
master.Filled-status guard infill()is what surfaces the stale order; the guard is right, thebookkeeping before it is what this PR corrects.