hlscreen is a read-only Rust workspace for Hyperliquid spot market-data recording, replay, feature calculation, and terminal screening.
The project is publicly maintained by RSI Tech. Copyright is owned by Rafal Sikora; project and confidential contact is info@rsitech.ai.
It is built for operators and researchers who want a local-first way to inspect public Hyperliquid spot microstructure without touching wallets, private keys, account streams, or order endpoints.
hlscreen is an independent open-source project. It is not affiliated with, endorsed by, or sponsored by Hyperliquid. Hyperliquid names and marks belong to their respective owners.
Current release: 0.1.2, a read-only live-data preview with bounded local validation. Recording, replay, screening, deterministic terminal rendering, health checks, and a native Apple Silicon macOS release package are implemented, but unattended production readiness and hosted multi-platform artifacts are not yet proven. It is not a trading bot, hosted service, or capital-touching execution system.
Latest live validation: a 2026-07-21 15-minute supervised all-symbol run at
commit 1c2851a covered 314 spot markets through 943 public subscriptions
and processed 300,147 WebSocket messages / 308,104 normalized events. It
stopped cleanly with 0 reconnects, gaps, parser drops, or failed backfills,
then passed two replay confidence checks with zero drift, missing, or extra
rows. See the
machine-readable soak report.
Implemented today:
- Public Hyperliquid REST metadata parsing for
spotMetaandspotMetaAndAssetCtxs. - Public WebSocket parsing for trades, BBO, selected-symbol L2 snapshots, all-mids, active asset context, and candles, with deterministic fixtures kept for tests.
- Bounded public WebSocket live screen with duration-based shutdown, heartbeat pings, inbound inactivity detection, rate-limited reconnect/resubscribe, optional raw/normalized recording, and all-symbol subscription budgeting.
- Bounded live recording through a fail-closed writer queue so disk I/O does not silently drop or stall market-data ingestion.
- Adaptive Ratatui live cockpit for TTY sessions and
--tuismoke captures, with differential rendering, non-bursting refresh timers, a true display-only pause, watchlist, detail, market internals rail, real 1m OHLC/volume chart, book, tape, status bar, color, persisted display preferences, visible wide/medium/narrow layout profiles, resize-aware layouts, keyboard pane zoom, mouse pane focus, and command-palette editing for filters, presets, and sort order. - Wide Ratatui headers include a selected-pair quote rail with bid/ask share, spread, top-book depth, flow, and an explicit public-BBO read-only marker.
- Deterministic non-TTY terminal rendering for market rows, scan KPIs, selected-pair microstructure detail, read-only safety state, operations health, and keyboard command rail.
- Confidence-aware feature snapshots and TUI rows for fresh, sparse, duplicate, and explicit gap/parser/backlog quality inputs.
- Persisted confidence baselines plus
hls replay --verify-paritydrift detection for local replay checks. - Deterministic score breakdowns, screen-rule score fields, and
hls explainwhy-ranked output for replayed or fixture-backed rows. - Compressed raw public message recording, normalized replay JSONL, analytical Parquet export/replay with schema manifests, and local SQLite metadata with unique, path-safe run IDs and registry-path validation.
- Deterministic screening DSL and built-in screen presets.
- Health snapshots, reconnect simulation, TUI health rendering, and read-only local API helpers.
- Plain and bounded-live loopback servers handle SIGINT/SIGTERM on Unix and CTRL-C on Windows, stop HTTP/WebSocket work, release the listener, and report signal-listener failures instead of claiming a clean stop.
- Deterministic public fixture benchmark packs through
hls bench. - Low-cardinality metrics snapshots in
hls doctor --live --json, including Prometheus text output. - Manual
hls backfilland opt-inhls live --record --backfill-gapscoarse public candle coverage with durable partial/unrepaired attempt evidence. - Bounded standalone Wasm row-annotation extensions that reject imports, network/filesystem/private/trading permissions, oversized modules, hash mismatches, and excess memory/output.
- Hardened cargo-dist candidate packaging with pull-request artifact builds, SHA-256 checksums, a source archive, CycloneDX SBOM, auditable Rust binaries, SHA-pinned actions, and tag-only publication/provenance.
Not implemented yet:
- Supported long-running localhost daemon/service lifecycle.
- Hosted release binaries for macOS Intel, Linux, and Windows; those targets remain source-build only until their native-runner artifacts pass the same package and runtime checks as the Apple Silicon archive.
- Production alert delivery/operations, validated canonical production microstructure metrics, service-backed analog search, and multi-day supervised soak proof.
- Private account access, fee-tier lookup, and realized-fill modeling are outside the public/read-only trust boundary rather than partially implemented.
These committed SVGs are deterministic terminal captures generated from the current binary and used for documentation regression. Real public WebSocket smoke evidence is tracked in Production readiness and the machine-readable soak evidence.
Regenerate these assets with:
python3 scripts/generate-screenshots.pyhlscreen is read-only market-data infrastructure.
It does not provide:
- Wallet connection.
- Private-key handling.
- Order placement.
- Cancel/withdrawal/exchange-action routes.
- Leverage or execution controls.
- Financial advice.
- Profitability claims.
Scores and presets are screening heuristics only. They are not signals, recommendations, or strategy proof.
Local server lifecycle and validation are fail-closed but remain experimental:
hls serverandhls server --livebind only to loopback. A supported signal stops new HTTP accepts, live publication and public WebSocket work, drains connection tasks, releases the port, and exits zero. This is not an authenticated daemon or unattended service guarantee. The local process smoke proves plain-server SIGTERM behavior on Unix. Shared signal mapping and live-publisher cancellation are unit-tested; the live process path and Windows CTRL-C branch are not runtime-proven by that smoke.- Public REST backfill is limited to 1,100 weighted units per rolling minute; live and server WebSocket clients keep outbound messages to 1,900 per rolling minute and new connections to 29 per rolling minute. Those are application headroom limits below the documented exchange ceilings, not an availability guarantee.
- Local analog replay keeps only five-minute samples and the newest 288 candidates per symbol. It omits sub-five-minute and older historical states.
- Hosted-surface reads are finite: 120 seconds per
ghAPI call and 10 seconds for the local Git SHA read by default. Test overrides are limited to 1–600 seconds throughHLS_GH_READ_TIMEOUT_SECSand 1–60 seconds throughHLS_LOCAL_GIT_TIMEOUT_SECS; invalid or oversized values fail before conversion, and a timeout is a redacted gate failure.
See Deployment status for the remaining supervisor, durability, authentication, observability, soak, and recovery limits.
The latest release provides a native Apple Silicon macOS archive and matching SHA-256 checksum on the GitHub Releases page. Download both files and verify them before unpacking:
shasum -a 256 -c hlscreen-aarch64-apple-darwin.tar.gz.sha256
tar -xzf hlscreen-aarch64-apple-darwin.tar.gz
./hlscreen-aarch64-apple-darwin/bin/hls --help
./hlscreen-aarch64-apple-darwin/bin/hls doctor --data-dir /tmp/hlscreen-doctormacOS Intel, Linux, and Windows remain source-build targets for this release; no prebuilt archive is claimed for them.
Starting with v0.1.1, the Apple Silicon Mach-O binary is signed with the
maintainer's Developer ID Application identity (Team 2NY8A789TN) with the
hardened runtime enabled. Starting with v0.1.2, the binary is also notarized
by Apple, and Gatekeeper assesses it as Notarized Developer ID; each
release's notes state its exact notarization status. The ticket is validated
online because a bare Mach-O inside a tar.gz cannot carry a stapled ticket.
Verify the SHA-256 checksum above and, if needed, inspect the signature with
codesign --verify --strict --display -vv bin/hls.
Build requirements:
rustupwith the repository's Rust 1.88-or-newer toolchain.- A native build toolchain for your platform:
- macOS: Xcode Command Line Tools (
xcode-select --install). - Debian/Ubuntu Linux:
build-essential. - Windows: MSVC C++ Build Tools with the Desktop development with C++ workload.
- macOS: Xcode Command Line Tools (
Contributor validation additionally requires Git, Python 3, the rustfmt and
clippy rustup components, and pkg-config on Linux. A network connection is
needed for public REST metadata and live public WebSocket commands; fixture,
replay, and local-only commands can run without exchange network access.
Platform contract for the v0.1.2 release:
| Platform | Target | Current evidence |
|---|---|---|
| macOS Apple Silicon | aarch64-apple-darwin |
Published native archive; clean local package/install smoke and fresh-download verification |
| macOS Intel | x86_64-apple-darwin |
Source build configured; no published binary artifact |
| Ubuntu-compatible x86-64 Linux | x86_64-unknown-linux-gnu |
Source build configured; no published binary artifact |
| Windows 10/11 x86-64 | x86_64-pc-windows-msvc |
Source build configured; no published binary artifact or Windows terminal runtime proof |
Rust 1.88 is the minimum supported Rust version. Other targets may build but are not part of the first release contract.
Build:
cargo build --workspace --all-features --lockedRun the fast local validation gate while iterating:
scripts/check.sh fastThis checks formatting, the locked workspace dependency graph, workspace tests,
and diff hygiene. Use scripts/check.sh pr before opening a pull request; it
adds full clippy, release, rustdoc, screenshot, and release-packaging checks.
Initialize a local data directory:
./target/debug/hls init --data-dir /tmp/hlscreen-smoke
./target/debug/hls doctor --data-dir /tmp/hlscreen-smokehls init writes config.toml as a reviewed configuration draft.
Runtime commands currently use explicit CLI flags; hls doctor loads the file to
validate its read-only safety settings. Treat the command help as the current
configuration contract until runtime-wide config precedence is implemented.
Fetch read-only public spot metadata:
./target/debug/hls symbols --top 5Run the current workspace's interactive public live screen:
cargo run -p hls-cli -- tuihls tui is the default interactive workstation entrypoint. It enables the
Ratatui cockpit, tracks the top 10 public spot pairs, refreshes once per second,
uses the ANSI color theme by default, and runs until q, Esc, Ctrl-C, or
SIGTERM. Its default --duration-secs 0 means run until an operator stops it;
pass a positive duration for automation. It remains read-only: no wallet,
private stream, signing, order route, or execution capability is loaded.
For a shell-wide hls command, install the exact checked-out workspace once:
cargo install --path crates/hls-cli --locked --force
hls tuiUse hls live --tui when you want a scripted recording run with explicit
storage flags:
tmpdir="$(mktemp -d /tmp/hlscreen-live.XXXXXX)"
./target/debug/hls live \
--all-symbols \
--duration-secs 900 \
--refresh-secs 60 \
--tui \
--record \
--raw \
--normalized \
--run-id allpairs-15m \
--data-dir "$tmpdir"
./target/debug/hls replay --data-dir "$tmpdir" --run-id allpairs-15m
./target/debug/hls replay --data-dir "$tmpdir" --run-id allpairs-15m --verify-parityRun a short public live smoke for one symbol:
./target/debug/hls tui \
--symbols HYPE/USDC \
--duration-secs 30 \
--refresh-secs 5Optionally evaluate a local-only alert playbook in the TUI:
./target/debug/hls tui \
--symbols HYPE/USDC \
--alert-playbook-file tests/fixtures/microstructure/alert_playbook_tui_watch.jsonAlert evaluation runs on draw ticks outside WebSocket ingestion. Press 6 to
focus the Status pane, then use j/k to navigate the bounded newest-first
history. The playbook validator rejects every action except local_only.
Run the same smoke while recording raw and normalized local evidence:
./target/debug/hls live \
--symbols HYPE/USDC \
--duration-secs 30 \
--refresh-secs 5 \
--tui \
--record \
--raw \
--normalized \
--run-id one-symbol-live \
--data-dir "$(mktemp -d /tmp/hlscreen-live.XXXXXX)"TTY keyboard controls for the Ratatui hls tui / hls live --tui cockpit:
↑/↓ork/j: move the focused market row, or navigate alert history while the Status pane is focused.←/→or[/]: cycle pane focus across watchlist, detail, chart, book, tape, and ops/status.PgUp/PgDn,Home,End: jump through the visible board.w/1,i/2,c/3,b/4,r/5,o/6: focus watchlist, instrument detail, chart, book, tape/recent trades, and ops/status panes.Enter: focus the selected symbol detail pane when no command editor is open.h/H: focus the health/status operations pane.Tab/Shift+Tab: cycle detail views: overview, flow, quality, metadata, explain.g: open the symbol jump editor with a live candidate radar;Enterselects the first visible row matching a display pair or feed ID,Esccancels./: open the validated filter editor;Enterapplies,Esccancels, empty input clears the custom filter.p: open the preset editor;Enterapplies,Esccancels, empty input clears the preset.s: open the sort editor;Enterapplies,Esccancels, empty input clears the custom sort.t: cycle chart window: 1m, 5m, 15m, 30m, 60m.z: expand/collapse the focused pane while keeping the header, controls, and read-only status visible.d: cycle row density.?orF1: show/hide help.Space: freeze/unfreeze displayed rows, candles, and public prints while ingestion, recording, navigation, and health counters continue.qorEsc: cleanly stop the live run.
TTY mouse controls for terminals with mouse reporting enabled:
- Wheel over a pane: scrolls that pane's native control, so watchlist moves rows, detail cycles views, and chart cycles windows.
- Click a watchlist row: selects that pair.
- Click an inactive pane rail/tab: focuses that pane.
- Click the already-active pane rail/tab: expands or collapses that pane, matching
z. - Click detail view tabs, chart window tabs, or header command controls: activates the visible read-only display control.
- Click the market internals rail: rows/heat/up/down focuses watchlist, tradeability/staleness focuses status, flow focuses tape, and depth focuses book.
- On wide terminals, click the selected-pair quote rail: symbol/quote focuses detail, bid/ask/top-book focuses book, and flow focuses tape.
- Wide charts fuse public candles and time-and-sales with print markers and an orderflow ribbon; these are read-only public trade/candle lenses, not fills or advice.
- On ultra-wide terminals, click the top
CMD DOCKfor pane focus, symbol jump, filter, preset, sort, chart window, density, zoom, pause, help, and quit. - On medium and standard-wide terminals, click the header
CMD g / p s t d z sp ? qrail for symbol jump, filter, preset, sort, timeframe, density, zoom, pause, help, and quit. - Click the bottom
ACTION STRIPin wide/medium terminals: activates visible controls such as symbol jump, density, pause, filter, preset, sort, chart window, help, and quit. - Standard-wide watchlists keep a selected-row context rail under the scanner table when there is enough height, so row actions, leaders, and read-only scan context remain visible even when the left column is narrower.
- On narrow terminals, the compact
/pstdzsp h? qrail is clickable: filter, preset, sort, timeframe, density, zoom, pause, health/status, help, and quit. - On very short terminals under 20 rows, the TUI switches to a clickable
MICRO LAYOUTcommand/pane rail that keeps the focused pane, resize-safe controls, color diagnostics, and read-only status visible.
Color defaults to always for hls tui and hls live --tui, so the Ratatui workstation uses
the ANSI theme out of the box. Use --color auto to follow terminal and
environment detection, or --color never for deterministic monochrome output.
Medium and wide layouts show the active visual path in the top header and bottom
action strip, such as VISUAL ansi-neon active or VISUAL plain fallback, so
screenshots make color mode drift obvious without crowding narrow terminals.
The legacy HLS_FORCE_COLOR=1, CLICOLOR_FORCE=1, and FORCE_COLOR=1
environment overrides still force color in auto; NO_COLOR=1 or TERM=dumb
still disables color in auto. Explicit --color always overrides NO_COLOR.
The interactive renderer owns stderr while the alternate screen is active; stdin and stderr must both remain attached to a TTY for the default unbounded session. Redirecting stderr disables interactive terminal ownership. Stdout is reserved for the completion summary after terminal restoration.
To verify which binary and terminal policy the shell is actually using:
command -v hls
hls --version
hls doctor --terminalThe version must include ratatui-workstation, and doctor --terminal reports
the executable path, working directory, TTY state, renderer, TERM,
COLORTERM, TMUX, NO_COLOR, and force/auto color decisions without creating
the data directory. If the renderer tag is missing, the shell found an older
binary. Reinstall from this checkout, then run hash -r in Bash/Zsh (or
rehash in shells that provide it). When multiple worktrees exist, confirm the
source being built with git rev-parse --show-toplevel and
git rev-parse --short HEAD; cargo run -p hls-cli -- tui always uses the
current workspace and avoids an unrelated global install.
Live TTY sessions persist display-only TUI preferences at
<data-dir>/tui-preferences.toml, including the active view, row density, and
chart window. Delete that file to return to the default overview/balanced/15m
layout. This file does not contain wallet, private stream, or order-route data.
hlscreen keeps Hyperliquid's transport IDs separate from user-facing symbols.
For example, live spotMeta currently maps display HYPE/USDC to feed ID
@107, and UETH/USDC to @151. The live command accepts display pairs
case-insensitively with either slash or hyphen separators, e.g. HYPE/USDC or
hype-usdc, and subscribes to the correct feed ID internally. Use hls symbols
to inspect the current mapping.
Run deterministic fixture commands for tests or offline docs:
./target/debug/hls live \
--symbols @107 \
--fixture-file tests/fixtures/hyperliquid/ws_mock_live.ndjson \
--preset thin_books \
--onceRecord and replay deterministic fixture data:
tmpdir="$(mktemp -d /tmp/hlscreen-smoke.XXXXXX)"
./target/debug/hls record \
--symbols @107 \
--fixture-file tests/fixtures/hyperliquid/ws_mock_live.ndjson \
--raw \
--normalized \
--run-id smoke \
--data-dir "$tmpdir"
./target/debug/hls replay --data-dir "$tmpdir" --run-id smoke
./target/debug/hls replay --data-dir "$tmpdir" --run-id smoke --verify-parityScreen deterministic fixture rows:
./target/debug/hls screen \
--fixture-file tests/fixtures/hyperliquid/ws_mock_live.ndjson \
--where 'spread_bps < 75 and tob_depth_usd > 100' \
--sort ret_5m:descExplain why a replayed or fixture-backed symbol ranked:
./target/debug/hls explain \
--fixture-file tests/fixtures/microstructure/resilience_shock.ndjson \
--symbol @107Print health JSON:
./target/debug/hls doctor --live --json
./target/debug/hls server --print-healthRun the deterministic public benchmark pack:
./target/debug/hls bench \
--manifest tests/fixtures/microstructure/benchmark_gap_replay.json \
--repo-root . \
--jsonAdditional local read-only commands include hls export-parquet, hls alerts,
hls analog, and hls extension. Run each command with --help for its explicit
fixture/replay inputs and output options.
Workspace crates:
hls-core: shared config, symbols, errors, state, health, and telemetry contracts.hls-hyperliquid: public Hyperliquid REST/WebSocket parsing and connection helpers.hls-store: compressed raw capture, normalized replay data, analytical Parquet, metadata registry, replay readers, and benchmark packs.hls-features: rolling feature windows and formulas.hls-screen: screening DSL, presets, and row filtering/sorting.hls-tui: terminal rendering.hls-server: read-only local API response helpers.hls-cli: command routing and operator workflows.
See docs/architecture.md.
Local recording writes under the configured data directory:
raw/ws/run=<run-id>/part-*.ndjson.zstnormalized/events/run=<run-id>/part-*.ndjsonhls.sqlite
Other opt-in commands can write config.toml, tui-preferences.toml, alert
history JSONL, analog-index JSON, confidence baselines, and Parquet datasets
with schema manifests. See the privacy document for the complete inventory.
These files are local artifacts and should not be committed.
Run IDs are unique recording identities, not paths. They may contain ASCII
letters, numbers, ., -, and _, are limited to 128 bytes, and cannot be
reused in the same data directory. Replay rejects registry file paths that are
absolute or contain parent-directory traversal.
See docs/data-format.md and docs/PRIVACY.md.
The screening DSL supports:
- Boolean operators:
and,or - Comparisons:
>,>=,<,<=,==,!= - Literals: numbers, strings, booleans
- Function:
abs(field)for numeric fields - Sort syntax:
field:asc,field:desc,abs(field):asc,abs(field):desc - Safety bounds: at most 256 nested parenthesis levels and 256 total boolean operators per filter; oversized filters fail without replacing the active rule.
Examples are in examples/screen-rules.md.
- Architecture
- Production readiness
- Data format
- Feature definitions
- Threat model
- Privacy
- Roadmap
- Release checklist
- Extension contract
- Latest supervised soak evidence
Read CONTRIBUTING.md before opening a PR.
The short version:
scripts/check.sh prSecurity issues should follow SECURITY.md. General support guidance is in SUPPORT.md.
Licensed under the Apache License, Version 2.0. Copyright 2026 Rafal Sikora; publicly maintained by RSI Tech. See LICENSE, NOTICE, and MAINTAINERS.md.