Repository navigation
feat(exchange): keep Hyperliquid market orders within the bound around the mark - #491
Merged
Merged
Conversation
A stale trade price can sit far above the market. A market buy now goes out at the lower of trade x (1 + bound) and mark x (1 + bound) (ADR-0059). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A market sell now goes out at the higher of trade x (1 - bound) and mark x (1 - bound), so a stale low trade cannot sell far under the market. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A trade alone could be stale, so a missing mark is a missing price (ADR-0059). The order raises and nothing is sent, as with no trade today. Older market tests now cache a mark that does not bind. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
.env.example, the adapter docstring and the config comment still said last trade x (1 +/- bound). ADR-0030 and ADR-0059 now say the cap is built. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MarcosACH
commented
Oct 13, 2026
MarcosACH
left a comment
Owner
Author
There was a problem hiding this comment.
Review of ralph/issue-467 @ 5e8edbf
Reviewer: code-review skill
Reviewed: 2026-10-12
Optimization axis: correctness
Mechanical
- ruff format: pass
- ruff check: pass
- mypy: pass
- lint-imports: pass (7 kept, 0 broken)
- pytest: pass (2038 passed, 49 skipped, coverage gate ≥90% met)
Findings
[NIT] R001 — docs/adr/0030-instrument-universe-and-order-mapping.md:50 — Build status rewritten inside an existing amendment
Category: docs
Why: ADRs are append-corrected (docs/agents/adr-reading.md). This PR changes "Not built yet." inside the ADR-0059 amendment block, but in ADR-0059 it appends a new (Built in #467) block. The two ADRs now record the same fact in two different ways.
Fix: Restore "Not built yet." and append a short **(Built in [#467](...):** ...**)** block after it, as done in ADR-0059.
Status: open
Checked and clean
- All four acceptance criteria of #467 are met. Each one has a test faked at HTTP. Limit tests place with no trade and no mark, so "limit unchanged" is covered.
- The price rule matches ADR-0059:
minfor a buy,maxfor a sell, then passive quantization. Rounding can only make the price tighter. - A missing mark raises before any send, the same path as a missing trade. Nothing reaches the wire (
post.requests == []). - The mark cache is in memory, like the trade cache. After a restart both refill from the feed, so recovery does not change.
- The
HyperliquidFeedalready publishesMarkTickfromactiveAssetCtxon the same bus. Replay publishes one too. So no wiring change is needed. - Docs-sync:
.env.example, the adapter docstring, the config comment, ADR-0059, and the module map all agree.CONTEXT.mdalready said it. Paper is untouched. - Live flatten before the first mark is out of scope. #475 owns it.
Summary
- BLOCKING: 0 open
- WARN: 0 open
- NIT: 1 open
- Merge: READY
Ralph-State: ready
…dment Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
Author
|
R001 — Status: resolved — 3fe9a5c ADR-0030 keeps its original amendment text. The build note is now a new |
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.
Closes #467
A market order on Hyperliquid was priced from the last trade only. A stale trade can send an order far from the market. Say a short is held, the last trade is 100, and the mark has fallen to 96. A buy at 105 is about 9% above the market, not 5%.
Now the adapter caps every market order by the mark too, inside the same
SLIPPAGE_BOUND(ADR-0059).trade × (1 + bound)andmark × (1 + bound).trade × (1 − bound)andmark × (1 − bound).placeraises and sends nothing. This is the same as with no trade today.Docs:
.env.example, the adapter docstring, the config comment, and the ADR-0030 and ADR-0059 notes now say the price is capped by the mark.Live flatten is still refused, so it cannot send a close before the first mark arrives. #475 owns that, and a comment there says flatten must count a symbol as priced only once it has a trade and a mark.
Tests
Hyperliquid, faked at HTTP:
pytest,ruff,mypy, andlint-importsare green.🤖 Generated with Claude Code