▌tickfoundry
实时采集中EN登录获取数据 →
§ 教程

如何回测 Hyperliquid
基于当时真实存在的订单簿。

python · pandas免费样本日TickFoundry · 2026-09-24 · 基于免费的 Hyperliquid 样本日运行

基于 K 线的 Hyperliquid 回测,是按某个价格而不是对着订单簿来成交每一笔订单的,而且从不支付手续费。这会错得多离谱,取决于币种。样本日 BTC 的订单簿很深,价差只有一个 tick,因此一笔 $100k 市价单的成本只比中间价高半个 tick,而成交记录中的吃单手续费是它的五十倍。HYPE 的 25 个可见档位只挂着约 $0.2M:同样一笔 $100k 订单在典型时刻要比中间价多付 2.2 bps,而一笔 $1M 订单在一天中 99% 的时间都放不进可见订单簿。本教程用 pandas 加载历史订单簿,按该区块上实际挂着的各档价位逐档吃单,为每一笔模拟订单定价,并按成交记录计入手续费。所有数字都来自免费样本日和文中展示的脚本。

用样本数据跟着做:Hyperliquid · 2026-08-12 · BTC + HYPE · hl_l1 / hl_l2 / hl_trades · 约 250 MB。
免费拉取 →↓ hl_slippage.py

为什么 K 线和快照都不够

Hyperliquid 大约每 71.5 ms 出一个区块。样本日 BTC 的订单簿在其中 68.7% 的区块里发生了变化,共 824,716 个订单簿状态,而链上归档只发布了 15,999 个订单簿快照,每 5.4 秒一个。快照序列大约只能看到五十分之一的 BTC 订单簿状态。info API 则只返回当前的订单簿。

而真正要紧的订单,恰恰是那些逐档吃单的订单。从成交还原出每一笔吃单订单后可以看到,BTC 只有 5.3% 的吃单订单(HYPE 为 11.9%)以不止一个价格成交,但在两个币种上,它们都占了当天吃单名义金额的 61%。按中间价或最新成交价给这些订单定价的回测,在真正能推动价格的大部分成交量上都是错的。

第 1 步 · 获取历史订单簿

Hyperliquid 数据按天出售,可按币种筛选:选好日期范围、数据表和币种,数据包里每张表、每个币种、每一天各一个 parquet 文件。有三种获取方式:

免费样本日

2026-08-12,币种任选,上限 1.0 GB,免费账户即可。不消耗市场·日额度。

拉取 →
任意币种,任意日期

自 2025-01-25 以来的每一个永续合约、现货交易对和 HIP-3 市场,通过 Hyperliquid 套餐或附加包获取。

归档里有什么 →
REST API

Explorer 及以上套餐:为一组币种请求一段日期范围,轮询状态,再流式下载数据包。示例代码见下方。

API 文档 →
通过 API 请求一个月的 HYPE 订单簿与成交python
import requests, time
API = "https://tickfoundry.com/api/v1" # Explorer and up
H = {"Authorization": "Bearer tf_live_…"} # minted in the dashboard
job = requests.post(f"{API}/hyperliquid/downloads", headers=H, json={
"start": "2026-08-01", "end": "2026-08-31",
"datasets": ["hl_l2", "hl_trades"],
"coins": ["HYPE"],
}).json()
while (s := requests.get(f"{API}/downloads/{job['id']}", headers=H).json())["status"] == "staging":
time.sleep(10)
open("hyperliquid.zip", "wb").write(requests.get(s["url"], headers=H).content)

自己动手搭建(从请求方付费的 S3 中拉取链上订单事件归档,再回放重建订单簿),仅流量与算力费用就约需 $10,000。

第 2 步 · 用 pandas 加载数据

数据包按表组织:hl_l2/date=D/<COIN>/l2.parquet,hl_l1 和 hl_trades 同理,另有 quality/date=D/<COIN>.json。行以 msg_seq(区块高度)为键,这是值得信赖的排序依据;ts_src_ms 是区块自身的时间。订单簿表中,25 档内有任何变化的区块各占一行,采用宽表列 bid_px_1 … ask_sz_25,每档的挂单笔数在 bid_n_* / ask_n_* 中。数量以币为单位。

load.pypython
import pandas as pd
# the free sample day, pulled from /catalog/hyperliquid and unzipped
book = pd.read_parquet("hl_l2/date=2026-08-12/BTC/l2.parquet") # 25-level book, a row per block it changed
trades = pd.read_parquet("hl_trades/date=2026-08-12/BTC/trades.parquet") # every fill: taker side, wallet, fee
top = pd.read_parquet("hl_l1/date=2026-08-12/BTC/l1.parquet") # top of book, every change
# msg_seq is the block height and orders everything; ts_src_ms is block time
book = book.sort_values("msg_seq")
book["ts"] = pd.to_datetime(book.ts_src_ms, unit="ms", utc=True)
book["mid"] = (book.best_bid + book.best_ask) / 2
# or every coin and day in the pull at once; date comes from the path
books = pd.read_parquet("hl_l2", columns=["coin", "msg_seq", "ts_src_ms", "best_bid", "best_ask"])

完整字段说明和覆盖范围注意事项见 Hyperliquid schema 文档(英文)。

第 3 步 · 逐档吃单测算滑点

这样,为市价单定价就是对每一行做算术:从每一档依次取用美元金额,直到订单成交完毕,再做除法。由于行的间隔并不规则(繁忙的一秒有几十行,清淡的一秒一行都没有),要按每个订单簿状态的存续时长加权,这样统计量回答的才是“这笔订单在一天中随机某一刻会付出多少成本”。当 25 档的挂单量小于订单规模时,结果是 NaN,而不是猜测值。

hl_slippage.py · 下表数据的生成脚本python
# hl_slippage.py (core) — the full script is linked above
import numpy as np
def walk(px, sz, usd):
"""Average fill price of a market order for `usd` notional, taking levels
best-first (px/sz: rows x 25). NaN where the 25 levels hold less."""
cost = px * sz # $ resting at each level
cum = np.nancumsum(cost, axis=1)
take = np.minimum(cost, np.maximum(usd - (cum - cost), 0)) # $ taken per level
qty = np.nansum(take / px, axis=1)
with np.errstate(divide="ignore", invalid="ignore"):
return np.where(cum[:, -1] >= usd, usd / qty, np.nan)
levels = range(1, 26)
ask_px = book[[f"ask_px_{i}" for i in levels]].to_numpy()
ask_sz = book[[f"ask_sz_{i}" for i in levels]].to_numpy() # size in coin units
mid = book.mid.to_numpy()
live_ms = book.ts_src_ms.shift(-1).sub(book.ts_src_ms).fillna(0).to_numpy() # time-weight
vwap = walk(ask_px, ask_sz, 1_000_000)
slip_bps = (vwap / mid - 1) * 1e4 # worse than mid, per book state
print("fits in 25 levels:", live_ms[~np.isnan(vwap)].sum() / live_ms.sum())
BTC
824,716 次订单簿变化 · 215,511 笔成交 · 成交额 $1,697M · 价差 0.16 bps(一个 tick) · 25 档内买盘 $10.2M / 卖盘 $8.7M
市价单25 档内可容纳相对中间价 · 中位数相对中间价 · p90相对最优价 · 中位数
买入 $10,000100.0%0.080.080.00
卖出 $10,000100.0%0.080.080.00
买入 $100,000100.0%0.080.480.00
卖出 $100,000100.0%0.080.460.00
买入 $1,000,000100.0%0.351.310.27
卖出 $1,000,000100.0%0.291.260.21
HYPE
667,808 次订单簿变化 · 154,728 笔成交 · 成交额 $170M · 价差中位数 0.18 bps,均值 0.23 · 25 档内买盘 $0.19M / 卖盘 $0.20M
市价单25 档内可容纳相对中间价 · 中位数相对中间价 · p90相对最优价 · 中位数
买入 $10,000100.0%0.331.370.21
卖出 $10,000100.0%0.321.410.19
买入 $100,00096.4%2.203.322.08
卖出 $100,00097.4%2.373.442.26
买入 $1,000,0000.9%———
卖出 $1,000,0000.4%———

2026-08-12 UTC · 滑点单位为 bps,即平均成交价比参考价差出的部分 · 按当天文件夹覆盖的 23.8 小时做时间加权 · “可容纳”指一天中 25 档能吃下整笔订单的时间占比;$1M 的 HYPE 订单能被容纳的时间太少,其成本数字没有意义,因此留空。

123450$1k$10k$100k$1M$10MBTC 成交记录中的吃单手续费中位数,4.3 bpsBTCHYPE相对中间价 bps · 市价买入
按订单规模划分的市价买入相对中间价成本中位数,时间加权,2026-08-12。每条线止于 25 个可见档位能吃下该订单的时间不足一天 85% 之处:BTC 为 $5M,HYPE 为 $100k。

把它和大多数回测的假设对照来看。在 BTC 上,约 $200k 以内按中间价成交只差半个 tick,一笔 $1M 订单的成本中位数为 0.35 bps,每十个时刻中有一个达到 1.3 bps。虚线才是更大的那个数字:同一天成交记录中的吃单手续费中位数为 4.3 bps,所以在 BTC 上,决定短周期策略能否存活的是手续费,而不是订单簿。在 HYPE 上,问题出在订单簿:一笔 $100k 订单会深入可见的 25 档,成本中位数为 2.2 bps;到 $200k 时,一天中超过一半的时间可见订单簿都太薄。

第 4 步 · 让回测真实可信的规则

每笔订单都用它前一个区块的订单簿定价
所有数据按 msg_seq 排序。对于在区块 N 做出的决策,对 N−1 或之前的最后一行订单簿逐档吃单;在 msg_seq 上做一次 merge_asof,就能处理整张信号表。
按成交记录计入手续费
hl_trades 的每一笔成交都带有 fee、fee_token 和 builder_fee。当天的吃单手续费中位数 BTC 为 4.3 bps,HYPE 为 3.9;可以用你自己的费率档位,但绝不能是零。
清楚 25 档到哪里为止
BTC 的 25 档跨度约 3.8 bps,HYPE 约 5 bps。如果订单大于可见订单簿,剩余部分只能靠模型估计:缩小规模、拆单,或在结果中注明。
一天是一段区块范围,而不是一个日历日
每个 date= 文件夹对应一段区块:2026-08-12 从 00:09:56 持续到次日 00:00:47(UTC)。按 ts_src_ms 筛选;窗口跨越午夜时,要把相邻的一天也拉取下来。
用真实的吃单订单校准
把 hl_trades 按 (oid, msg_seq) 分组,还原每一笔真实的吃单订单,然后检查你在相同规模、相同区块下的模拟成交是否落在真实成交的位置。
阅读质量文件和注意事项
quality/date=D/<COIN>.json 以 Hyperliquid 自己的快照为基准给当天打分(样本日 BTC 的最优买价在其中 99.73% 的快照上吻合)。README 列出了你所选范围内已知的数据缺口和合成成交时段。
从成交记录还原吃单订单python
# every taker order of the day, rebuilt from its fills: one order id, one block
t = trades.assign(usd=trades.price * trades["size"])
orders = t.groupby(["oid", "msg_seq"]).agg(side=("side", "first"), usd=("usd", "sum"),
prices=("price", "nunique"), fee=("fee", "sum"))
walked = orders[orders.prices > 1]
print(f"{len(walked) / len(orders):.1%} of taker orders filled at more than one price,")
print(f"{walked.usd.sum() / orders.usd.sum():.1%} of taker notional")

按中间价成交的假设在哪里错得最离谱

上面的中位数描述的是普通时刻。代价高昂的是行情快速变化的时刻,而基于 K 线的回测恰恰在这些时刻记下它最漂亮的交易。样本日 12:30 UTC,BTC 在一分钟内下跌 34.8 bps,其间最高到最低的振幅为 52.6 bps。卖方 25 档当天挂单的中位数为 $8.7M,此时最低跌到 $196k;价差从一个 tick 扩大到 5.45 bps;一笔在典型时刻成本为 0.35 bps 的 $1M 市价买单,在这一分钟内的成本中位数为 0.76 bps,最差瞬间达到 9.41 bps,并且在这一分钟里有 3.8% 的时间放不进可见订单簿。

HYPE 最快的一分钟出现在 14:36 UTC,上涨 52.2 bps。它的 25 档从中位数约 $195k 降到每侧约 $71k,一笔中位数成本为 2.2 bps 的 $100k 买单,在那一分钟最差的瞬间成本高达 34.9 bps。基于 K 线定价的回测永远看不到这两个数字。

领先-滞后研究中的 Hyperliquid 订单簿(英文)→Polymarket 版回测教程

常见问题

Hyperliquid 提供历史订单簿数据吗?
没有能直接拿来模拟成交的形式。info API 只返回当前的订单簿,而不是过去的。链上公开归档里有定期的订单簿快照(2026-08-12 当天共 15,999 个,约每 5.4 秒一个),以及原始订单事件流,后者必须逐个区块回放才能还原每一次订单簿变化。那一天 BTC 的订单簿变化了 824,716 次。TickFoundry 将这条事件流回放为 25 档订单簿、盘口最优价和成交记录,覆盖自 2025-01-25 以来的每一个币种。
可以免费回测 Hyperliquid 吗?
可以。任何免费账户都能拉取固定的样本日 2026-08-12,币种任选,每次拉取上限 1.0 GB,且不消耗市场·日额度。BTC 和 HYPE 加上全部三张表约 250 MB。无需绑卡。
25 档订单簿的深度够回测用吗?
取决于币种,文件本身会告诉你。样本日 BTC 的 25 档跨度约 3.8 bps,每侧约 $10M,基本全天都能容纳一笔 $1M 的市价单,$5M 的订单则在一天中 89% 的时间能容纳。HYPE 的 25 档跨度约 5 bps,每侧约 $0.2M:$100k 的订单在一天中 96% 的时间能容纳,$1M 则不到 1%。超出可见档位的那部分成本只是模型估计,而不是数据。
手续费在数据中如何体现?
hl_trades 中的每一笔成交都带有 fee 和 fee_token(永续合约为 USDC)、单独的 builder_fee、吃单方钱包地址、closed_pnl 和 start_position。样本日的吃单手续费中位数 BTC 为 4.3 bps,HYPE 为 3.9 bps。在 BTC 上,这大约是一笔 $1M 订单逐档吃单成本的十二倍,所以只建模滑点而忽略手续费的回测,把误差的主次弄反了。
重建的订单簿有多准确?
每个币种·日都附带一个质量文件,把我们回放出的订单簿与 Hyperliquid 自己发布的每一个快照逐一比对。2026-08-12 当天,在 15,999 个快照中,BTC 的最优买价吻合率为 99.73%,最优卖价为 99.67%;HYPE 分别为 99.51% 和 99.41%。你所选日期范围内已知的覆盖问题,列在数据包 README 和文档中。
哪些 Python 工具可以读取?
各表均为 parquet 格式,每张表、每个币种、每一天一个文件,pandas、polars、DuckDB 和 Arrow 都能直接读取;pd.read_parquet("hl_l2") 可以一次读入整次拉取的数据。Hyperliquid 数据不提供 CSV 版本。本教程只用到 pandas 和 numpy。
在你真正交易的币种上跑一遍。

样本日覆盖平台上的所有币种,而不只是这两个。用免费账户拉取你所交易币种在 2026-08-12 的数据,脚本无需修改即可运行:python hl_slippage.py . SOL ETH。

拉取免费样本日 →自 2025-01-25 起的所有币种