Skip to content

feat(hyperliquid): populate UserTrade marketId/outcomeId/fee; synthesize closed+all orders#1255

Merged
realfishsam merged 1 commit into
mainfrom
feat/hl-usertrade-fields-and-closed-orders
Jun 21, 2026
Merged

feat(hyperliquid): populate UserTrade marketId/outcomeId/fee; synthesize closed+all orders#1255
realfishsam merged 1 commit into
mainfrom
feat/hl-usertrade-fields-and-closed-orders

Conversation

@realfishsam

Copy link
Copy Markdown
Contributor

Summary

Two HL gaps surfaced by ground-truth assertion checks against real active wallets:

UserTrade enrichment

  • Trade.outcomeId and new UserTrade.marketId / UserTrade.fee are now populated by HL's normalizeUserTrade from raw.coin and raw.fee. Previously every HL fill came back with marketId=null, outcomeId=null, fee=null — consumers couldn't tell which market a fill was on.
  • Wired through existing coinToMarketId / coinToOutcomeId helpers (same ones used by normalizeOpenOrder).

Closed + all orders

  • HL exposes no closed-orders endpoint. fetchClosedOrders now synthesizes by grouping userFills by oid and excluding currently-open oids. VWAP price, summed size for amount/filled, summed fee, earliest fill time as timestamp.
  • fetchAllOrders = openOrders ∪ closedOrders.
  • ponytail: comment marks the limitation: cancelled-with-no-fills orders aren't reconstructable from the public info API.

Verified (Python + TS, ground-truth against HL raw API)

Wallet 0x6476… (2000 fills): both SDKs return 2000/2000 trades with marketId / outcomeId / fee populated, identical sample.

Wallet 0x5af8… (7 open, 104 unique fill-only oids):

fetchClosedOrders → 104 (matches raw expected count exactly)
fetchAllOrders    → 111 = 7 open + 104 closed
sample closed: id=474427504352 market=hl-outcome-207 side=buy status=filled
               amount=13 filled=13 remaining=0 price=0.00012 fee=0

Identical on both SDKs.

…ize closed+all orders from fills

UserTrade enrichment:
- Widen UnifiedUserTrade with optional marketId, fee fields.
- HL normalizeUserTrade now sets marketId, outcomeId, fee on every fill
  using the existing coinToMarketId / coinToOutcomeId helpers and the
  raw.fee field. Previously these were undefined, leaving consumers
  unable to tell which market a fill was on.
- Verified against an active wallet (0x6476...): 2000/2000 trades now
  fully populated in both Python and TS SDKs.

Closed + all orders:
- HL has no closed-orders endpoint. Synthesize from userFills by
  grouping fills by oid and excluding oids that are currently open.
- VWAP for the synthesized price, sum of sizes for filled/amount,
  sum of fees, earliest fill time as the order timestamp.
- ponytail comment notes the limitation: cancelled-with-no-fills orders
  are not visible to the public info API and cannot be reconstructed.
- fetchAllOrders = open ∪ closed.
- Verified against 0x5af8... (7 open + 104 derived closed = 111 all),
  identical counts and sample output across Python and TS.
@realfishsam realfishsam merged commit b569238 into main Jun 21, 2026
8 of 15 checks passed
@realfishsam realfishsam deleted the feat/hl-usertrade-fields-and-closed-orders branch June 21, 2026 17:48
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