fix(http): send market orders as FrontendMarket, not GTC - #80
Merged
ifdario merged 1 commit intoAug 21, 2026
Merged
Conversation
market_open() documented and shipped "Hyperliquid native FrontendMarket order type, fills immediately up to the worst acceptable price", but built the order with TimeInForce::Gtc. A market buy at a limit below market would rest as a passive GTC limit instead of filling immediately, and a GTC sell would never fill unless price crossed. FrontendMarket is the Hyperliquid-protocol market order (Limit + tif=FrontendMarket); the variant existed but was never actually used. Also fix PriceTick::tick_for(): the docs specify integer digits as floor(log10(price)) + 1, but the code used ceil(log10(price)). The two agree except when log10(price) is exact — i.e. price is a power of ten — where ceil undercounts the digits by one and returns a tick ten times too fine (1000 → 0.01 instead of 0.1 for a 5-significant-figure market). Add power-of-ten regression test. 149 tests pass; no new clippy warnings. Co-Authored-By: Claude <noreply@anthropic.com>
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.
Summary
Two related price-handling fixes in the trading path.
1.
market_opensends real market orders (was sending GTC limits)market_open()is documented as using Hyperliquid's nativeFrontendMarketorder type ("fills immediately up to the provided worst acceptable limit price"), and the exampleexamples/hypercore/market_order.rssays the same — but the code built the order withTimeInForce::Gtc:TimeInForce::FrontendMarkethas always existed (src/hypercore/types/mod.rs) but was never actually used anywhere. The practical impact on live trading:limit_px(worst acceptable) is below the current ask rests as a passive GTC limit instead of filling — the caller believes they're filled, their position isn't.limit_pxabove the current bid never fills unless price crosses it.FIX:
Gtc→FrontendMarket. This is the Hyperliquid-protocol market order (aLimitwithtif: FrontendMarket), matching the frontend semantics the method documents.2.
PriceTick::tick_forcorrect at powers of tentick_for's doc algorithm issig_figs = floor(log10(price)) + 1, but the code usedceil(log10(price)). The two agree for every non-power-of-ten price and disagree exactly at powers of ten, whereceilundercounts the integer digits by one and returns a tick ten times too fine:10000.10.01❌0.1✅1000.010.001❌0.01✅10.00010.00001❌0.0001✅Visible on any market with
max_decimals≥ the computed value (e.g. a perp/spot with lowsz_decimals);round/round_by_sideinherit it. No existing test covered a power-of-ten price — addedpower_of_ten_prices_keep_five_sig_figs.Testing
cargo test --lib: 149 passed, 0 failed.mainare unchanged).