hl-research 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hl_research-0.1.0/.gitignore +57 -0
- hl_research-0.1.0/LICENSE +21 -0
- hl_research-0.1.0/PKG-INFO +427 -0
- hl_research-0.1.0/README.md +383 -0
- hl_research-0.1.0/hl_research/__init__.py +5 -0
- hl_research-0.1.0/hl_research/__version__.py +3 -0
- hl_research-0.1.0/hl_research/_internal/__init__.py +1 -0
- hl_research-0.1.0/hl_research/_internal/logging.py +1 -0
- hl_research-0.1.0/hl_research/_internal/time.py +1 -0
- hl_research-0.1.0/hl_research/analytics/__init__.py +1 -0
- hl_research-0.1.0/hl_research/analytics/behavior.py +208 -0
- hl_research-0.1.0/hl_research/analytics/counterfactual.py +53 -0
- hl_research-0.1.0/hl_research/analytics/funding_arb.py +90 -0
- hl_research-0.1.0/hl_research/analytics/funding_predict.py +73 -0
- hl_research-0.1.0/hl_research/analytics/liquidations.py +1 -0
- hl_research-0.1.0/hl_research/analytics/types.py +183 -0
- hl_research-0.1.0/hl_research/analytics/vaults.py +148 -0
- hl_research-0.1.0/hl_research/analytics/wrapped.py +315 -0
- hl_research-0.1.0/hl_research/api/__init__.py +1 -0
- hl_research-0.1.0/hl_research/api/client.py +168 -0
- hl_research-0.1.0/hl_research/api/errors.py +40 -0
- hl_research-0.1.0/hl_research/api/info.py +157 -0
- hl_research-0.1.0/hl_research/api/types.py +305 -0
- hl_research-0.1.0/hl_research/backtest/__init__.py +1 -0
- hl_research-0.1.0/hl_research/backtest/engine.py +168 -0
- hl_research-0.1.0/hl_research/backtest/fills.py +53 -0
- hl_research-0.1.0/hl_research/backtest/metrics.py +127 -0
- hl_research-0.1.0/hl_research/backtest/optimizer.py +103 -0
- hl_research-0.1.0/hl_research/backtest/portfolio.py +153 -0
- hl_research-0.1.0/hl_research/backtest/strategy.py +129 -0
- hl_research-0.1.0/hl_research/backtest/walkforward.py +69 -0
- hl_research-0.1.0/hl_research/cache/__init__.py +1 -0
- hl_research-0.1.0/hl_research/cache/paths.py +19 -0
- hl_research-0.1.0/hl_research/cache/schema.py +90 -0
- hl_research-0.1.0/hl_research/cache/store.py +527 -0
- hl_research-0.1.0/hl_research/cache/sync.py +234 -0
- hl_research-0.1.0/hl_research/cli/__init__.py +1 -0
- hl_research-0.1.0/hl_research/cli/backtest.py +591 -0
- hl_research-0.1.0/hl_research/cli/context.py +74 -0
- hl_research-0.1.0/hl_research/cli/data.py +415 -0
- hl_research-0.1.0/hl_research/cli/funding.py +246 -0
- hl_research-0.1.0/hl_research/cli/main.py +103 -0
- hl_research-0.1.0/hl_research/cli/scan.py +1 -0
- hl_research-0.1.0/hl_research/cli/tui.py +17 -0
- hl_research-0.1.0/hl_research/cli/vault.py +277 -0
- hl_research-0.1.0/hl_research/cli/wallet.py +466 -0
- hl_research-0.1.0/hl_research/data/__init__.py +1 -0
- hl_research-0.1.0/hl_research/data/candles.py +22 -0
- hl_research-0.1.0/hl_research/data/fills.py +23 -0
- hl_research-0.1.0/hl_research/data/frames.py +26 -0
- hl_research-0.1.0/hl_research/data/funding.py +20 -0
- hl_research-0.1.0/hl_research/data/universe.py +11 -0
- hl_research-0.1.0/hl_research/data/vaults.py +20 -0
- hl_research-0.1.0/hl_research/presentation/__init__.py +1 -0
- hl_research-0.1.0/hl_research/presentation/ascii.py +211 -0
- hl_research-0.1.0/hl_research/presentation/plots.py +130 -0
- hl_research-0.1.0/hl_research/presentation/progress.py +85 -0
- hl_research-0.1.0/hl_research/presentation/report.py +597 -0
- hl_research-0.1.0/hl_research/presentation/tables.py +952 -0
- hl_research-0.1.0/hl_research/presentation/templates/backtest.html.j2 +280 -0
- hl_research-0.1.0/hl_research/presentation/templates/vault.html.j2 +254 -0
- hl_research-0.1.0/hl_research/presentation/templates/wrapped.html.j2 +455 -0
- hl_research-0.1.0/hl_research/presentation/theme.py +92 -0
- hl_research-0.1.0/hl_research/py.typed +1 -0
- hl_research-0.1.0/hl_research/tui/__init__.py +1 -0
- hl_research-0.1.0/hl_research/tui/app.py +622 -0
- hl_research-0.1.0/hl_research/tui/screens/__init__.py +1 -0
- hl_research-0.1.0/hl_research/tui/screens/_models.py +42 -0
- hl_research-0.1.0/hl_research/tui/screens/backtest.py +69 -0
- hl_research-0.1.0/hl_research/tui/screens/funding.py +74 -0
- hl_research-0.1.0/hl_research/tui/screens/home.py +60 -0
- hl_research-0.1.0/hl_research/tui/screens/settings.py +49 -0
- hl_research-0.1.0/hl_research/tui/screens/vault.py +94 -0
- hl_research-0.1.0/hl_research/tui/screens/wallet.py +77 -0
- hl_research-0.1.0/hl_research/tui/styles.tcss +175 -0
- hl_research-0.1.0/hl_research/tui/widgets/__init__.py +1 -0
- hl_research-0.1.0/hl_research/tui/widgets/asset_picker.py +67 -0
- hl_research-0.1.0/hl_research/tui/widgets/candle_chart.py +1 -0
- hl_research-0.1.0/hl_research/tui/widgets/funding_strip.py +1 -0
- hl_research-0.1.0/pyproject.toml +97 -0
- hl_research-0.1.0/tests/__init__.py +1 -0
- hl_research-0.1.0/tests/fixtures/hl/book.json +8 -0
- hl_research-0.1.0/tests/fixtures/hl/candles.json +14 -0
- hl_research-0.1.0/tests/fixtures/hl/clearinghouse_state.json +34 -0
- hl_research-0.1.0/tests/fixtures/hl/fills.json +18 -0
- hl_research-0.1.0/tests/fixtures/hl/funding_history.json +8 -0
- hl_research-0.1.0/tests/fixtures/hl/meta.json +24 -0
- hl_research-0.1.0/tests/fixtures/hl/meta_and_asset_ctxs.json +25 -0
- hl_research-0.1.0/tests/fixtures/hl/orders.json +15 -0
- hl_research-0.1.0/tests/fixtures/hl/trades.json +12 -0
- hl_research-0.1.0/tests/fixtures/hl/user_funding.json +12 -0
- hl_research-0.1.0/tests/fixtures/hl/vault_details.json +13 -0
- hl_research-0.1.0/tests/fixtures/hl/vault_summaries.json +10 -0
- hl_research-0.1.0/tests/test_analytics.py +255 -0
- hl_research-0.1.0/tests/test_api.py +184 -0
- hl_research-0.1.0/tests/test_backtest.py +241 -0
- hl_research-0.1.0/tests/test_cache_data.py +130 -0
- hl_research-0.1.0/tests/test_cli_snapshots.py +538 -0
- hl_research-0.1.0/tests/test_funding_vault.py +215 -0
- hl_research-0.1.0/tests/test_package.py +7 -0
- hl_research-0.1.0/tests/test_sync.py +127 -0
- hl_research-0.1.0/tests/test_tui_models.py +253 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
|
|
8
|
+
# Distribution
|
|
9
|
+
build/
|
|
10
|
+
dist/
|
|
11
|
+
*.egg-info/
|
|
12
|
+
*.egg
|
|
13
|
+
wheels/
|
|
14
|
+
|
|
15
|
+
# Virtual envs
|
|
16
|
+
.venv/
|
|
17
|
+
venv/
|
|
18
|
+
.env
|
|
19
|
+
|
|
20
|
+
# Tooling caches
|
|
21
|
+
.mypy_cache/
|
|
22
|
+
.ruff_cache/
|
|
23
|
+
.pytest_cache/
|
|
24
|
+
.coverage
|
|
25
|
+
.coverage.*
|
|
26
|
+
coverage.xml
|
|
27
|
+
htmlcov/
|
|
28
|
+
.tox/
|
|
29
|
+
.nox/
|
|
30
|
+
|
|
31
|
+
# uv
|
|
32
|
+
.uv/
|
|
33
|
+
|
|
34
|
+
# IDE
|
|
35
|
+
.vscode/
|
|
36
|
+
.idea/
|
|
37
|
+
*.swp
|
|
38
|
+
*.swo
|
|
39
|
+
|
|
40
|
+
# OS
|
|
41
|
+
.DS_Store
|
|
42
|
+
Thumbs.db
|
|
43
|
+
|
|
44
|
+
# Project
|
|
45
|
+
*.parquet
|
|
46
|
+
*.duckdb
|
|
47
|
+
.hl-research-cache/
|
|
48
|
+
|
|
49
|
+
# Notebook checkpoints
|
|
50
|
+
.ipynb_checkpoints/
|
|
51
|
+
|
|
52
|
+
# mkdocs
|
|
53
|
+
site/
|
|
54
|
+
|
|
55
|
+
# Local-only
|
|
56
|
+
scratch/
|
|
57
|
+
tmp/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Matthew Rahm (ramenxbt)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hl-research
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local-first quantitative research toolkit for Hyperliquid.
|
|
5
|
+
Project-URL: Homepage, https://github.com/ramenxbt/hl-research
|
|
6
|
+
Project-URL: Repository, https://github.com/ramenxbt/hl-research
|
|
7
|
+
Project-URL: Issues, https://github.com/ramenxbt/hl-research/issues
|
|
8
|
+
Author-email: Matthew Rahm <ramenxbt@users.noreply.github.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: backtesting,cli,hyperliquid,quant,research
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Python: >=3.12
|
|
21
|
+
Requires-Dist: duckdb<2.0,>=1.0
|
|
22
|
+
Requires-Dist: httpx[http2]<1.0,>=0.27
|
|
23
|
+
Requires-Dist: jinja2<4.0,>=3.1
|
|
24
|
+
Requires-Dist: matplotlib<4.0,>=3.9
|
|
25
|
+
Requires-Dist: plotly<6.0,>=5.22
|
|
26
|
+
Requires-Dist: polars<2.0,>=1.0
|
|
27
|
+
Requires-Dist: pydantic<3.0,>=2.7
|
|
28
|
+
Requires-Dist: rich<14.0,>=13.7
|
|
29
|
+
Requires-Dist: textual<1.0,>=0.65
|
|
30
|
+
Requires-Dist: typer<1.0,>=0.12
|
|
31
|
+
Provides-Extra: all
|
|
32
|
+
Requires-Dist: matplotlib<4.0,>=3.9; extra == 'all'
|
|
33
|
+
Requires-Dist: optuna<4.0,>=3.6; extra == 'all'
|
|
34
|
+
Requires-Dist: plotly<6.0,>=5.22; extra == 'all'
|
|
35
|
+
Requires-Dist: textual<1.0,>=0.65; extra == 'all'
|
|
36
|
+
Provides-Extra: optimize
|
|
37
|
+
Requires-Dist: optuna<4.0,>=3.6; extra == 'optimize'
|
|
38
|
+
Provides-Extra: plot
|
|
39
|
+
Requires-Dist: matplotlib<4.0,>=3.9; extra == 'plot'
|
|
40
|
+
Requires-Dist: plotly<6.0,>=5.22; extra == 'plot'
|
|
41
|
+
Provides-Extra: tui
|
|
42
|
+
Requires-Dist: textual<1.0,>=0.65; extra == 'tui'
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
|
|
45
|
+
# hl-research
|
|
46
|
+
|
|
47
|
+
[](https://pypi.org/project/hl-research/)
|
|
48
|
+
[](https://pypi.org/project/hl-research/)
|
|
49
|
+
[](LICENSE)
|
|
50
|
+
[](https://github.com/ramenxbt/hl-research/actions/workflows/ci.yml)
|
|
51
|
+
|
|
52
|
+
**A Python toolkit for quantitative research on Hyperliquid.** Pulls historical data from the HL info API on demand, caches it locally as Parquet, and ships research primitives for backtesting, wallet behavior analysis, vault inspection, and funding research. Runs from a laptop. No infrastructure.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install hl-research
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## The headline feature
|
|
61
|
+
|
|
62
|
+
Paste a wallet, get a self-contained HTML report:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
hlr data pull-fills 0xabc... --since 2024-01-01
|
|
66
|
+
hlr wallet wrapped 0xabc... --out wrapped.html
|
|
67
|
+
open wrapped.html
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+

|
|
71
|
+
|
|
72
|
+
PnL by asset, hour-of-day pattern, hold-time distribution, funding ledger, behavior cluster, counterfactual vs holding spot, top wins and losses. One file. Shareable.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Contents
|
|
77
|
+
|
|
78
|
+
- [Quickstart](#quickstart)
|
|
79
|
+
- [What you get](#what-you-get)
|
|
80
|
+
- [Tour by command group](#tour-by-command-group)
|
|
81
|
+
- [Architecture](#architecture)
|
|
82
|
+
- [FAQ](#faq)
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Quickstart
|
|
87
|
+
|
|
88
|
+
Requires Python 3.12 or newer.
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pip install hl-research
|
|
92
|
+
|
|
93
|
+
# Pull cache for one asset
|
|
94
|
+
hlr data pull BTC --since 2024-01-01
|
|
95
|
+
hlr data pull-funding BTC --since 2024-01-01
|
|
96
|
+
|
|
97
|
+
# See what's cached
|
|
98
|
+
hlr data ls
|
|
99
|
+
|
|
100
|
+
# Inspect a wallet (live)
|
|
101
|
+
hlr wallet inspect 0xabc...
|
|
102
|
+
|
|
103
|
+
# Build the wrapped report
|
|
104
|
+
hlr data pull-fills 0xabc... --since 2024-01-01
|
|
105
|
+
hlr wallet wrapped 0xabc... --out wrapped.html
|
|
106
|
+
|
|
107
|
+
# Browse interactively
|
|
108
|
+
hlr tui
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Every command supports `--json` for piping into scripts. Report commands accept `--out PATH` for standalone HTML artifacts.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## What you get
|
|
116
|
+
|
|
117
|
+
| Command group | What it does |
|
|
118
|
+
| --- | --- |
|
|
119
|
+
| `hlr data` | Incremental Parquet cache (DuckDB metadata) over the HL info API |
|
|
120
|
+
| `hlr wallet` | Inspect any wallet, build wrapped reports, list fills and funding |
|
|
121
|
+
| `hlr funding` | Funding-rate history, cross-asset heatmap, perp-perp basis, naive prediction |
|
|
122
|
+
| `hlr vault` | List, rank, and inspect HLP and user vaults |
|
|
123
|
+
| `hlr backtest` | Run strategy files written in plain Python, grid + random optimization, walk-forward |
|
|
124
|
+
| `hlr tui` | Six-screen Textual app over the same data layer |
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Tour by command group
|
|
129
|
+
|
|
130
|
+
### `hlr data` — local cache
|
|
131
|
+
|
|
132
|
+
The cache is the foundation. Everything else reads from it.
|
|
133
|
+
|
|
134
|
+
```text
|
|
135
|
+
$ hlr data ls
|
|
136
|
+
|
|
137
|
+
KIND ENTITY INTERVAL ROWS SIZE SINCE UNTIL UPDATED
|
|
138
|
+
────────────────────────────────────────────────────────────────────────────────────────────────
|
|
139
|
+
candles BTC 1h 720 34.68 KB 2024-04-01 2024-04-30 2026-05-19 15:44
|
|
140
|
+
candles ETH 1h 720 34.95 KB 2024-04-01 2024-04-30 2026-05-19 15:44
|
|
141
|
+
candles SOL 1h 720 35.12 KB 2024-04-01 2024-04-30 2026-05-19 15:44
|
|
142
|
+
fills 0xa1b2…0000 — 18 6.27 KB 2024-04-01 2024-04-12 2026-05-19 15:44
|
|
143
|
+
funding BTC — 720 14.16 KB 2024-04-01 2024-04-30 2026-05-19 15:44
|
|
144
|
+
funding ETH — 720 14.27 KB 2024-04-01 2024-04-30 2026-05-19 15:44
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
```text
|
|
148
|
+
$ hlr data info
|
|
149
|
+
╭─ cache ──────────────────────────────────────────────────────────────────────╮
|
|
150
|
+
│ │
|
|
151
|
+
│ CACHE DIRECTORY ~/.cache/hl-research │
|
|
152
|
+
│ TOTAL SIZE 203.08 KB │
|
|
153
|
+
│ FILES 9 │
|
|
154
|
+
│ DATASETS 9 │
|
|
155
|
+
│ LAST SYNC 2026-05-19 15:44 │
|
|
156
|
+
│ │
|
|
157
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Incremental by default — re-running `pull` resumes from the last cached candle.
|
|
161
|
+
|
|
162
|
+
### `hlr wallet` — paste an address
|
|
163
|
+
|
|
164
|
+
Live account state:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
hlr wallet inspect 0xabc...
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Behavioral wrapped report (see screenshot above) — the headline artifact:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
hlr wallet wrapped 0xabc... --out wrapped.html
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Without `--out` you get a terminal summary:
|
|
177
|
+
|
|
178
|
+
```text
|
|
179
|
+
╭─ wallet wrapped ─────────────────────────────────────────────────────────────╮
|
|
180
|
+
│ │
|
|
181
|
+
│ WALLET 0xa1b2…0000 │
|
|
182
|
+
│ PERIOD 2024-04-01 → 2024-04-12 │
|
|
183
|
+
│ REALIZED PNL +$4,240.00 │
|
|
184
|
+
│ FUNDING NET $0.00 │
|
|
185
|
+
│ WIN RATE 88.9% │
|
|
186
|
+
│ TRADES 9 │
|
|
187
|
+
│ CLUSTER chad │
|
|
188
|
+
│ Win rate was at least 65% and total PnL exceeded 1k. │
|
|
189
|
+
│ │
|
|
190
|
+
│ HOLD vs ACTUAL -$17,908.51 (pass --out to write the full HTML report) │
|
|
191
|
+
│ │
|
|
192
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Behavior clusters are rules-based — `revenge_trader`, `funding_farmer`, `scalper`, `swing_trader`, `chad`, `leverage_addict`, `hold_and_pray`, `balanced`. The output includes the reason that triggered the classification.
|
|
196
|
+
|
|
197
|
+
### `hlr funding` — rates, basis, prediction
|
|
198
|
+
|
|
199
|
+
Cross-asset funding snapshot, sorted by absolute rate, annualized APR on the right:
|
|
200
|
+
|
|
201
|
+
```text
|
|
202
|
+
$ hlr funding heatmap
|
|
203
|
+
|
|
204
|
+
ASSET RATE
|
|
205
|
+
──────────────────────────────────────────────────────────────────────────────────────────────
|
|
206
|
+
BTC +0.0147% │████████████████████████████ +16.1% APR
|
|
207
|
+
SOL +0.0134% │█████████████████████████ +14.7% APR
|
|
208
|
+
HYPE -0.0059% ███████████│ -6.4% APR
|
|
209
|
+
ETH +0.0014% │███ +1.5% APR
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
History + sparkline:
|
|
213
|
+
|
|
214
|
+
```text
|
|
215
|
+
$ hlr funding history BTC
|
|
216
|
+
╭─ funding history ────────────────────────────────────────────────────────────╮
|
|
217
|
+
│ │
|
|
218
|
+
│ ASSET BTC │
|
|
219
|
+
│ OBSERVATIONS 720 │
|
|
220
|
+
│ RANGE 2024-04-01 → 2024-04-30 │
|
|
221
|
+
│ LATEST +0.0147% / period │
|
|
222
|
+
│ MEAN +0.0126% / period │
|
|
223
|
+
│ │
|
|
224
|
+
│ ▄▂▁▁▄▄▅▇▅▂▇█▄▂▆▇▄▆▂▁▂▇▅▃▅▆▅▆▃▂▂▃▃▃▇▂▃▅▁▁▇▆▇▇▃▂▆▇▃▁ │
|
|
225
|
+
│ │
|
|
226
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Perp-vs-perp basis leaderboard:
|
|
230
|
+
|
|
231
|
+
```text
|
|
232
|
+
$ hlr funding arb BTC
|
|
233
|
+
|
|
234
|
+
PAIR LATEST BASIS ANNUALIZED MEAN BASIS N
|
|
235
|
+
────────────────────────────────────────────────────────────
|
|
236
|
+
BTC / HYPE +0.0206% +22.52% +0.0168% 720
|
|
237
|
+
BTC / ETH +0.0133% +14.60% +0.0035% 720
|
|
238
|
+
BTC / SOL +0.0013% +1.45% -0.0036% 720
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Naive EWMA prediction with disclaimer:
|
|
242
|
+
|
|
243
|
+
```text
|
|
244
|
+
$ hlr funding predict BTC
|
|
245
|
+
╭─ funding prediction ─────────────────────────────────────────────────────────╮
|
|
246
|
+
│ │
|
|
247
|
+
│ PREDICTED RATE +0.0111% │
|
|
248
|
+
│ LOWER (95%) +0.0013% │
|
|
249
|
+
│ UPPER (95%) +0.0209% │
|
|
250
|
+
│ │
|
|
251
|
+
│ Naive EWMA baseline. Do not trade on this without a real model. │
|
|
252
|
+
│ │
|
|
253
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### `hlr backtest` — strategies in plain Python
|
|
257
|
+
|
|
258
|
+
```python
|
|
259
|
+
# my_strategy.py
|
|
260
|
+
from hl_research.backtest.strategy import Order, Strategy
|
|
261
|
+
|
|
262
|
+
class MeanReversion(Strategy):
|
|
263
|
+
def __init__(self):
|
|
264
|
+
super().__init__()
|
|
265
|
+
self._lookback = []
|
|
266
|
+
|
|
267
|
+
def on_candle(self, candle, ctx):
|
|
268
|
+
self._lookback.append(candle.close)
|
|
269
|
+
if len(self._lookback) > 20:
|
|
270
|
+
self._lookback.pop(0)
|
|
271
|
+
mean = sum(self._lookback) / len(self._lookback)
|
|
272
|
+
position = ctx.positions.get(candle.asset)
|
|
273
|
+
held = position.size if position else 0.0
|
|
274
|
+
if candle.close < mean * 0.99 and held <= 0:
|
|
275
|
+
return [Order(asset=candle.asset, side="buy", size=0.05, kind="market")]
|
|
276
|
+
if candle.close > mean * 1.01 and held > 0:
|
|
277
|
+
return [Order(asset=candle.asset, side="sell", size=abs(held),
|
|
278
|
+
kind="market", reduce_only=True)]
|
|
279
|
+
return []
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
```text
|
|
283
|
+
$ hlr backtest run my_strategy.py --asset BTC
|
|
284
|
+
|
|
285
|
+
╭─ backtest ───────────────────────────────────────────────────────────────────╮
|
|
286
|
+
│ │
|
|
287
|
+
│ STRATEGY MeanReversion │
|
|
288
|
+
│ ASSET BTC │
|
|
289
|
+
│ PERIOD 2024-04-01 → 2024-04-30 │
|
|
290
|
+
│ │
|
|
291
|
+
│ TOTAL RETURN -2.43% │
|
|
292
|
+
│ SHARPE -1.18 │
|
|
293
|
+
│ MAX DRAWDOWN -2.43% │
|
|
294
|
+
│ HIT RATE +0.00% │
|
|
295
|
+
│ PROFIT FACTOR 0.00 │
|
|
296
|
+
│ TRADES 4 │
|
|
297
|
+
│ NET FUNDING -$149.27 │
|
|
298
|
+
│ │
|
|
299
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
300
|
+
|
|
301
|
+
╭─ equity ─────────────────────────────────────────────────────────────────────╮
|
|
302
|
+
│ │
|
|
303
|
+
│ ████████▇▇▆▆▆▆▆▆▆▆▆▆▆▆▅▅▄▄▄▄▄▄▄▄▄▄▄▃▃▃▃▃▃▃▃▃▃▃▂▂▁▁▁▁▁▁▁▁▁▁▁▁ │
|
|
304
|
+
│ │
|
|
305
|
+
│ START $100,000.00 END $97,571.67 │
|
|
306
|
+
│ PEAK $100,000.00 TROUGH $97,571.67 │
|
|
307
|
+
│ CHANGE -$2,428.33 (-2.43%) │
|
|
308
|
+
│ │
|
|
309
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
The example loses money on this short window — backtesting on a month of one asset is a sanity check, not an alpha signal.
|
|
313
|
+
|
|
314
|
+
Optimization and walk-forward:
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
hlr backtest optimize my_strategy.py --param "lookback:10..30:5"
|
|
318
|
+
hlr backtest walk-forward my_strategy.py --window 90d --step 30d
|
|
319
|
+
hlr backtest run my_strategy.py --asset BTC --out report.html
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### `hlr tui` — interactive Textual app
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
hlr tui
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Two-pane layout with six sections. `1`–`6` to switch, `/` for the asset picker, `r` to reload, `q` to quit. All views reuse the same cache and analytics the CLI uses.
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## Architecture
|
|
333
|
+
|
|
334
|
+
```text
|
|
335
|
+
HL info endpoint
|
|
336
|
+
│
|
|
337
|
+
▼
|
|
338
|
+
api/ typed httpx client, retries, rate limit
|
|
339
|
+
│
|
|
340
|
+
▼
|
|
341
|
+
cache/ Parquet on disk, DuckDB metadata, incremental sync
|
|
342
|
+
│
|
|
343
|
+
▼
|
|
344
|
+
data/ Polars LazyFrames, pure transforms
|
|
345
|
+
│
|
|
346
|
+
├──▶ analytics/ wrapped, behavior, counterfactual, funding, vault
|
|
347
|
+
├──▶ backtest/ event loop, fill simulation, metrics, optimizer
|
|
348
|
+
└──▶ presentation/ Rich tables, Plotly charts, Jinja2 reports
|
|
349
|
+
│
|
|
350
|
+
└──▶ cli/, tui/
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
The data layer never calls presentation. Presentation never calls the API. The CLI binds the two. Pure functions in `analytics/`, frozen dataclasses everywhere, mypy strict across 79 source files.
|
|
354
|
+
|
|
355
|
+
Cache layout on disk:
|
|
356
|
+
|
|
357
|
+
```
|
|
358
|
+
~/.cache/hl-research/
|
|
359
|
+
├── meta.duckdb # sync state, asset and vault tables
|
|
360
|
+
└── data/
|
|
361
|
+
├── candles/asset=BTC/interval=1h/2024-04.parquet
|
|
362
|
+
├── funding/asset=BTC/2024.parquet
|
|
363
|
+
├── fills/wallet=0xabc.../2024-Q2.parquet
|
|
364
|
+
└── vaults/address=0xvault.../trades.parquet
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
Partitioned for Polars and DuckDB. Re-pulling resumes from the last cached row.
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## FAQ
|
|
372
|
+
|
|
373
|
+
**Does this need a Hyperliquid account?**
|
|
374
|
+
No. Every endpoint hl-research uses is public.
|
|
375
|
+
|
|
376
|
+
**Does it trade?**
|
|
377
|
+
No. hl-research is read-only by design. It never holds keys, places orders, or signs anything.
|
|
378
|
+
|
|
379
|
+
**What data is missing?**
|
|
380
|
+
L2 microstructure history. Tick-level book data isn't available from the public API and we can't reconstruct it without a continuous ingestor. Candles, funding, fills, and vault state are all here.
|
|
381
|
+
|
|
382
|
+
**How big does the cache get?**
|
|
383
|
+
~50MB for two years of top-20 assets at 1h candles + funding. Active trader wallet fills add 1-10MB per wallet.
|
|
384
|
+
|
|
385
|
+
**Can I use this in a notebook?**
|
|
386
|
+
Yes — see [`examples/basic_backtest.ipynb`](examples/basic_backtest.ipynb) and [`examples/wallet_analysis.ipynb`](examples/wallet_analysis.ipynb). Every CLI command has a programmatic equivalent under `hl_research.*`.
|
|
387
|
+
|
|
388
|
+
**What about live mode?**
|
|
389
|
+
On the v0.2 roadmap. Today everything is on-demand from the REST endpoint.
|
|
390
|
+
|
|
391
|
+
**How do I contribute?**
|
|
392
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md). Issues and PRs welcome.
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## Install
|
|
397
|
+
|
|
398
|
+
```bash
|
|
399
|
+
pip install hl-research
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
Or with [uv](https://github.com/astral-sh/uv):
|
|
403
|
+
|
|
404
|
+
```bash
|
|
405
|
+
uv pip install hl-research
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
Optional extras:
|
|
409
|
+
|
|
410
|
+
```bash
|
|
411
|
+
pip install "hl-research[plot]" # matplotlib + plotly for charts
|
|
412
|
+
pip install "hl-research[tui]" # Textual interactive app
|
|
413
|
+
pip install "hl-research[all]" # everything
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
## Docs
|
|
417
|
+
|
|
418
|
+
Full reference at [ramenxbt.github.io/hl-research](https://ramenxbt.github.io/hl-research/).
|
|
419
|
+
|
|
420
|
+
- [Quickstart](https://ramenxbt.github.io/hl-research/quickstart/)
|
|
421
|
+
- [Command reference](https://ramenxbt.github.io/hl-research/commands/data/)
|
|
422
|
+
- [Writing a strategy](https://ramenxbt.github.io/hl-research/reference/strategies/)
|
|
423
|
+
- [Architecture](https://ramenxbt.github.io/hl-research/reference/architecture/)
|
|
424
|
+
|
|
425
|
+
## License
|
|
426
|
+
|
|
427
|
+
MIT. See [LICENSE](LICENSE).
|