Skip to content

fix(symbolConverter): return 0 szDecimals for outcome markets - #195

Open
pucedoteth wants to merge 1 commit into
nktkas:mainfrom
pucedoteth:fix-outcome-sz-decimals
Open

pucedoteth wants to merge 1 commit into
nktkas:mainfrom
pucedoteth:fix-outcome-sz-decimals

Conversation

@pucedoteth

Copy link
Copy Markdown

What & why

SymbolConverter.getSzDecimals returns 5 for every outcome market, but outcome shares trade in whole units, so it should be 0.

Evidence:

  • The Hyperliquid app hardcodes it. Its bundle (app.hyperliquid.xyz/assets/index-*.js) builds outcome rows with szDecimals:0,coinKind:"outcome".
  • Live mainnet data has no fractional sizes. I checked 2,466 recentTrades across 304 outcome coins, then 332 open outcome orders and 267 non-zero outcome balances from 96 of the traders. Every size was an integer.

Since getSzDecimals feeds both formatters, 5 breaks orders built the way docs/guides/market-orders.md shows:

formatSize("12.5", 5);             // "12.5"   (fractional share size)
formatPrice("0.29128", 5);         // "0.2"
formatPrice("0.29128", 5, "spot"); // "0.291"

formatSize("12.5", 0);             // "12"
formatPrice("0.29128", 0);         // "0.29128"

0.29128 is a real resting bid on #32530. With 5, an IOC buy priced off it gets cut to 0.2 and doesn't fill.

The change is the constant in _processOutcomeMarkets, plus the JSDoc example, docs/utilities.md and the outcome getSzDecimals() test.

Type of change

  • Bug fix
  • New API method / feature
  • Schema/type update to match the Hyperliquid API
  • Breaking change

Testing

  • deno test -A tests/utils/symbolConverter.test.ts: 2 passed (27 steps). With only src/utils/_symbolConverter.ts reverted, the outcome getSzDecimals() step fails (5 vs 0).
  • deno task check passes (fmt, lint, type check, jsdoc sync, export sync).
  • I did not send a fractional-size outcome order to the exchange, so the rejection itself is inferred from the app and the live data above.

Written with AI assistance (Claude Code).

🤖 Generated with Claude Code

Outcome shares trade in whole units. The Hyperliquid app formats outcome
markets with szDecimals 0, and live mainnet outcome trades, open orders and
balances all have integer sizes.

Reporting 5 let formatSize keep fractional share sizes and made formatPrice
cap prices at 1 decimal (perp) or 3 decimals (spot), so a 0.29128 quote was
truncated to 0.2 or 0.291.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
JulienKervarrec added a commit to JulienKervarrec/hyperliquid that referenced this pull request Sep 25, 2026
…he loop

Same behaviour as before: a slug produced by more than one outcome side is
left unregistered. Registration now stays as on main and the ambiguous slugs
are removed afterwards, so the szDecimals lines touched by nktkas#195 are left
alone and the two changes merge cleanly in either order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Signed-off-by: Julien Kervarrec <114134889+JulienKervarrec@users.noreply.github.com>
JulienKervarrec added a commit to JulienKervarrec/hyperliquid that referenced this pull request Sep 25, 2026
The collision test only needs to know that a unique slug is still
registered. Checking for a numeric szDecimals instead of 5 keeps it valid
if nktkas#195 changes that value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Signed-off-by: Julien Kervarrec <114134889+JulienKervarrec@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant