HL 分析指标方法论

本文档详细描述 /hl/* 下每一个量化指标的计算方式、所依赖的链上原语,以及各自的边界与局限。伪代码与线上服务端行为逐行对齐,不含任何尚未落地的设计。

版本:2026-04-21


引言

所有 HL 分析类接口都衍生自我们从 Hyperliquid 摄入的四条链上数据流:

  1. 账户权益快照(Account Value Snapshots,snapshots_perp) —— 每个地址永续账户的按市值计价(mark-to-market)权益,由 Hyperliquid 节点每 5–10 分钟采样一次。
  2. 累计盈亏快照(Accumulated PnL Snapshots,accum_pnls) —— 以地址和时间为键的已实现 + 未实现盈亏(realized + unrealized PnL)时间序列。
  3. 成交与已成交订单(fills, filled_orders) —— 逐笔成交执行记录,每笔成交一行。
  4. 账本更新(user_ledger_updates) —— 账户层级的所有余额变动事件:充值、提现、内部转账、金库(vault)资金流动。

本文档所述的每一个指标,都是以上四张表的确定性函数。我们不会注入任何私有的平滑处理、评分或基准叠加。如果你需要语义不同的指标(例如夏普比率(Sharpe)、索提诺比率(Sortino)、相对基准收益等),请参阅 自定义指标计算 一节,了解如何基于我们的原语自行推导。


约定

约定项取值
时间所有时间戳均以 Unix 毫秒(UTC)返回。在文档明确支持的位置,入参可使用 Unix 毫秒或 RFC 3339 两种格式。
计价货币所有金额均为 USD 等值,按快照时刻 Hyperliquid 内部 mark price 换算。不做汇率换算。
地址格式全小写、带 0x 前缀的 20 字节十六进制。服务端会统一归一化。
小数精度计算采用任意精度 decimal(shopspring/decimal)。响应序列化时保留完整精度,客户端不应假设固定小数位数。
作用域scope=perp 为默认值,也是目前回撤与行为类指标唯一支持的作用域。现货余额不计入。
时间窗口语义days=N 表示 [now − N·24h, now]。窗口在请求到达时由服务端求值。

指标方法论

最大回撤(Max Drawdown) —— /hl/max-drawdown, /hl/batch-max-drawdown

用途。 在请求窗口内,对地址永续账户权益计算最大的峰值-谷值(peak-to-trough)跌幅,并对净资金流(net capital flows)做去污(decontamination)修正,使得提现不会被记为亏损,充值也不会把峰值抬升重置。

输入数据。

  • snapshots_perp.account_value —— 该地址在每个节点快照时刻的 mark-to-market 永续账户权益。
  • user_ledger_updates —— 窗口内永续账户的净资金进出(充值、提现、现货↔永续划转、金库流动)。

算法(净资金流去污的峰值-谷值回撤)。 给定窗口内按时间排序的账户权益快照序列 s_0, s_1, …, s_n,我们向前遍历,维护候选的 (peak, trough) 对。对每一对,计算从 peak.timetrough.time 之间观察到的净资金流 netIn。修正后的有效峰值/谷值为:

if netIn > 0:
    effectivePeak   = peak.value + netIn
    effectiveTrough = trough.value
elif netIn < 0:
    effectivePeak   = peak.value
    effectiveTrough = trough.value + |netIn|
else:
    effectivePeak, effectiveTrough = peak.value, trough.value

if effectiveTrough >= effectivePeak or effectivePeak == 0:
    drawdown = 0
else:
    drawdown = (effectivePeak − effectiveTrough) / effectivePeak

窗口内 drawdown 最大的那一对即为最终结果。

为什么要做去污。 若不做净资金流修正:一个用户亏损 5k 之后再充值 10k,会被错误地显示为"已经恢复"(因为原始权益上升);而一个提现 10k 的用户,会被错误地记为回撤了 10k。去污修正把净资金流视为外生因素,仅度量真实的交易盈亏。

参数。

  • days ∈ {1, 7, 30, 60, 90}。HTTP 层强制限制在 [1, 90] 区间。
  • scope = perp(隐式)。

响应结构。

{
  "high":        { "time": 1714000000000, "value": "123456.78" },
  "low":         { "time": 1714100000000, "value": "100000.00" },
  "maxDrawdown": "0.19",
  "netIn":       "5000.00"
}

netInhigh.timelow.time 区间内的净资金流(不是整个请求窗口的)。

已知限制 —— 保留期截断(Retention Truncation)。 snapshots_perp 在存储层的保留期是 30 天。即使客户端请求 days=60days=90,送入算法的快照序列也只回溯到 30 天前。因此返回的回撤实际上是 [now − min(30d, days), now] 区间内的真实回撤。详见 数据保留期与历史深度


权益曲线(Portfolio / Equity Curve) —— /hl/portfolio/{address}/{window}

用途。 输出一段适合绘制权益曲线(equity curve)的按市值计价账户权益时间序列。

输入数据。 accum_pnls.perp_value(在该表同时填充了永续+现货的场景下,也以 TotalValue 字段暴露)。每一行是与 Hyperliquid 节点快照对齐的账户权益快照。

窗口与采样。

window回溯长度采样方式
day最近 24 小时全部快照(约 50–200 个点)
week最近 7 天全部快照(约 500–1000 个点)
month最近 30 天降采样为每 12 小时一个点(约 60 个点)
allTime从 2025-12-06 15:00 UTC 起每天 1 个点

2025-12-06T15:00 这个锚点是当前数据集的起始时间戳,硬编码在服务端;window=allTime 的请求不会返回早于该时间点的数据。

权益口径。 返回的 valuemark-to-market 权益,同时包含已累计到账户的已实现盈亏(realized PnL)与所有未平仓仓位的未实现盈亏(unrealized PnL)。我们不把序列拆分成已实现/未实现,也不拆分成充值/交易盈亏。如果你需要一条去除资金流干扰的 ROI 曲线,请参考 自定义指标计算,结合 /hl/ledger-updates/net-flow 进行二次加工。

响应结构。

{
  "address": "0x…",
  "window":  "week",
  "points":  [ { "time": 1714000000000, "accountValue": "123456.78" } ]
}

已知限制 —— 保留期截断。 accum_pnls 的保留期是 90 天。尽管 window=allTime 名义上从 2025-12-06 开始,实际返回的最早一点不会早于 90 天前。这是有意为之的行为,将来会在 API 参考文档中补充说明。


净资金流(Net Flow) —— /hl/ledger-updates/net-flow/{address}, /hl/ledger-updates/batch-net-flow

用途。 在窗口内,地址净流入 Hyperliquid 永续与现货账户的 USD 金额。用于对收益率做去污(decontamination)处理,把盈亏和资金流区分开来。

输入数据。 user_ledger_updates,按地址与时间窗口过滤。

计入的事件类型。

  • L1 充值(链上桥入)。
  • L1 提现(桥出,记负)。
  • 内部现货 ↔ 永续划转(在 netPerpInnetSpotIn 同时以相反符号计入,以保证总账对齐)。
  • 金库(vault)的充值与提现。

不计入的事件类型。

  • spotTransfer(钱包到钱包的现货转账,未跨越 Hyperliquid 永续/现货边界)。
  • subAccountTransfer(主账户与子账户之间的记账变动 —— 对母账户的整体资本并无影响)。

计算方式。 按类别对带符号的 USD 等值金额求和,返回形如:

{
  "address":   "0x…",
  "netPerpIn": "12345.00",
  "netSpotIn": "678.90"
}

参数。

  • days ∈ {1, 7, 30, 60, 90, 0}。days=0 表示"全部历史"。

已知限制 —— 保留期截断。 user_ledger_updates 的保留期是 90 天。实务上,days=0days=90 返回相同的结果。我们不回填(backfill)保留期之前的事件。


交易者行为统计(Trader Behaviour) —— /hl/traders/{address}/addr-stat, /hl/traders/batch-behavior-metrics

用途。 以滚动窗口汇总地址的交易行为画像,返回一组行为统计指标。

输入数据。 预聚合的物化表 positions_dex_1dpositions_dex_7dpositions_dex_30d(每个地址一行,字段是对应窗口的聚合结果)。当 period=0(保留期内"全部历史")时,回落到对 fillsfilled_orders 的区间扫描,受常量 behaviorMetricsMaxLookbackDays = 90 约束,最多回溯 90 天。

字段。

字段口径
winRate窗口内 closedPositionsWithPnl>0 / totalClosedPositions
maxDrawdown与上文最大回撤算法一致,在区间聚合表中预先算好。
totalPnl窗口内所有已平仓仓位的已实现盈亏求和,USD。
orderCount窗口内不同已成交订单的计数。
closedPositionCount窗口内开仓并完全平仓的仓位数。
avgPositionDurationSec已平仓仓位 (close_time − open_time) 的均值,单位秒。
profitLossRatiomean(盈利平仓的盈利额) / mean(亏损平仓的亏损绝对值)。任一侧为空时返回 0。

参数。

  • period ∈ {1, 7, 30, 0}。超出该集合的取值一律拒绝。
  • period=0 在服务端被截断为最多 90 天的回溯。

不提供的指标。 夏普比率(Sharpe)、索提诺比率(Sortino)、Calmar 比率、盈利因子(Profit Factor),以及相对基准的 alpha,均有意不纳入。这些指标依赖无风险利率、采样频率、基准等主观选择,我们更希望由客户端显式决定。自定义指标计算 一节会演示如何基于我们已经暴露的原语把它们拼出来。


数据保留期与历史深度

我们运行的是滚动的热数据集(rolling hot dataset),目前尚未维护冷归档。截至 2026-04-21,生效的保留期策略如下:

保留期影响到的接口
fills90 天行为指标、自定义成交查询
filled_orders90 天行为指标
accum_pnls90 天权益曲线
user_ledger_updates90 天净资金流
positions_dex_{1,7,30}d按日滚动重算行为指标
snapshots_perp30 天最大回撤
snapshots_position30 天仓位状态查询
trades30 天K 线、最新成交查询
fundings30 天资金费率序列
completed-trades(仓位)90 天历史平仓仓位

实务影响。 任何名义窗口超过底层表保留期的请求,都会被静默地在截断后的序列上求值。接口不会报错 —— 它会透明地做 clamp。这里把行为明确写入方法论,方便客户端与自有回填数据做对齐。

路线图。 冷归档(S3 上的 Parquet)在规划中,但尚未上线。在它落地之前,超过上述保留期的数据无法通过本 API 获取。


已知局限

  1. 超过 30 天的回撤窗口会被截断。 目前 /hl/max-drawdowndays=60days=90 实际返回的是 30 天回撤。响应结构暂未携带 effectiveWindowDays 字段,未来版本会补上。在此之前,请把 days≥30 统一理解为"30 天最大回撤"。

  2. Portfolio 的 allTime 窗口以 90 天保留期为上限,而非硬编码的 2025-12-06 锚点。 锚点定义了我们愿意返回的最早日期;保留期定义了我们实际拥有的最早日期。

  3. 行为指标的 period=0 是 90 天近似。 period=0 下计算得到的首次成交时间、总订单数、加仓摘要等字段,都只反映最近 90 天。对于在该窗口之前就已经开始在 Hyperliquid 交易的地址,其"首次成交时间"会是保留期内最早的一笔成交,而不是真正的起点。

  4. 净资金流不包含保留期之外的充值。 若某地址的首次充值发生在查询时间点 90 天以前,它的 netPerpIn 会比朴素的链上求和结果偏小。

  5. 不做子账户聚合。 每个地址独立查询。如果一个交易者使用多个地址,聚合逻辑由客户端自行处理。

  6. 不做滑点、手续费归一化。 盈亏数据直接来自 Hyperliquid 账本,已经包含支付的交易所手续费。我们不区分总盈亏(gross)与净盈亏(net)。

  7. 无实时性保证。 快照是最终一致的。Hyperliquid 节点到 API 的端到端时延通常在 10–30 秒;在高成交量时段因反压(back-pressure),可能延长到数分钟量级。


基于原语计算自定义指标

以下给出在客户端侧构建常见风险调整类指标的几种示例做法,完全只使用上文暴露的接口。

资金流去污的 ROI(Capital-Flow-Decontaminated ROI)

原始 ROI = equity[T]/equity[0] − 1 受充提资金影响,会失真。修正后的 ROI:

equity = /hl/portfolio/{addr}/{window}.points      # time, accountValue
flows  = /hl/ledger-updates/net-flow/{addr}?days=N # netPerpIn + netSpotIn

ROI_adj = (equity[T] − equity[0] − netTotalIn) / (equity[0] + max(0, netTotalIn))

若需要时间序列形式,可采用修正 Dietz(Modified Dietz)或时间加权收益率(TWR)方法,把资金流事件作为子区间边界来切分。

夏普比率(Sharpe Ratio)

选择一个采样区间 Δt(例如从 allTime portfolio 窗口中取日频),然后:

r_i   = equity[t_i] / equity[t_i-1] − 1            # 单期收益
r̄     = mean(r_i)
σ     = stddev(r_i)
Sharpe_annualised = (r̄ − r_f · Δt) / σ · sqrt(periodsPerYear)

r_f 是你自己选定的无风险利率;我们不强加任何默认值。

索提诺比率(Sortino Ratio)

与夏普同构,但用下行偏差(downside deviation)替代 σ:

σ_d = sqrt( mean( min(0, r_i − τ)^2 ) )   # τ 为目标收益,通常取 0
Sortino = (r̄ − τ) / σ_d · sqrt(periodsPerYear)

盈利因子(Profit Factor)

由行为指标出发,profitLossRatio × (winRate / (1 − winRate)) 在盈亏两侧交易平均规模符合返回均值的假设下,代数上恰好等于盈利因子 sum(wins)/sum(|losses|)。若要更严格的计算,请直接查询成交数据,自行计算:

PF = Σ positive_realised_pnl / |Σ negative_realised_pnl|

如对本文档有疑问、发现口径差异,或希望我们新增某个指标,请联系对接的商务/技术支持。

您对本页面是否满意?