HL 数据分析方法论
本文档描述 AiCoin 开放 API 下
/hl/*路径暴露的各项量化指标的精确计算口径。
AiCoin 开放 API 参考文档。逐条说明 /hl/* 下暴露的每个量化指标是如何计算的、依赖哪些链上原始数据、以及边界条件位于何处。其中的伪代码与线上服务端的实际行为逐行对应,不存在任何"理论值"或"规划中"的成分。
版本:2026-04-21
导言
所有 HL 分析类接口都派生自我们从 Hyperliquid 接入的四条链上数据流:
- 账户价值快照(Account Value Snapshots)(
snapshots_perp)—— 每个地址永续账户的按市值计价(mark-to-market)权益,由 Hyperliquid 节点每 5–10 分钟采样一次。 - 累计盈亏快照(Accumulated PnL Snapshots)(
accum_pnls)—— 以地址和时间为键的已实现 + 未实现盈亏时间序列。 - 成交 / 成交订单(Fills / Filled Orders)(
fills、filled_orders)—— 每笔成交一条记录的逐笔执行明细。 - 账本变动(Ledger Updates)(
user_ledger_updates)—— 账户层面每一次余额变动事件:充值、提现、内部转账、金库(vault)进出。
本文档描述的每一个指标,都是上述四张表中某一个或多个的确定性函数。我们不会注入任何专有的平滑、打分或基准叠加层。如果你需要具备不同语义的指标(夏普比率、索提诺比率、相对基准收益等),请参见 自定义指标的计算方法 一节,了解如何基于我们的基础数据自行推导。
通用约定
| 约定 | 取值 |
|---|---|
| 时间 | 所有返回的时间戳均为 Unix 毫秒(UTC)。文档中明确支持的入参可为 Unix 毫秒或 RFC 3339 格式。 |
| 计价货币 | 所有金额均为美元等值,按快照时刻 Hyperliquid 内部标记价格计算,无任何汇率换算。 |
| 地址格式 | 小写的 0x 前缀 20 字节十六进制,服务端会自动规范化。 |
| 小数精度 | 计算使用任意精度十进制(shopspring/decimal)。响应以完整精度序列化;客户端不应假设固定的小数位数。 |
| 范围 | scope=perp 是默认且目前唯一支持的 scope(用于回撤与行为类指标),现货余额被排除在外。 |
| 时间窗口语义 | days=N 表示 [now − N·24h, now],窗口由服务端在请求时刻实时计算。 |
各指标方法论
最大回撤(Max Drawdown)—— /hl/max-drawdown、/hl/batch-max-drawdown
用途。 在指定窗口内,地址永续账户价值的最大峰值-谷值(peak-to-trough)跌幅,并对净资金流进行调整,使得提现不会被计为亏损、充值也不会重置峰值。
输入数据。
snapshots_perp.account_value—— 地址在每个节点快照时刻的按市值计价永续权益。user_ledger_updates—— 窗口期内流入/流出永续账户的净资金流(充值、提现、现货↔永续划转、金库进出)。
算法(净流入去污的峰值-谷值回撤)。
给定窗口内按时间排序的账户价值快照序列 s_0, s_1, …, s_n,我们向前遍历,维护一对候选的 (peak, trough)。对每一对候选,计算 peak.time 与 trough.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"
}
netIn 是 high.time 到 low.time 之间的净资金流,而不是整个窗口内的。
已知边界 —— 保留期截断。 snapshots_perp 在存储层只保留 30 天。即使请求传入 days=60 或 days=90,算法实际拿到的快照序列也只能回溯 30 天。因此返回的回撤实际上是 [now − min(30d, days), now] 区间内的真实回撤。参见 数据保留期与历史深度。
组合 / 权益曲线 —— /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 起至今 | 每天一个点 |
2025-12-06T15:00 这一锚点是当前数据集的起始时间戳,硬编码写入代码;window=allTime 的请求永远不会返回早于该时间点的数据。
数值定义。 返回的值是 按市值计价(mark-to-market) 的权益,包含已累积到账户的已实现盈亏(realized PnL),以及任何持仓上的未实现盈亏(unrealized PnL)。我们不会把序列拆分成已实现 vs. 未实现、也不会拆分成充值 vs. 交易盈亏。如果你需要一条已去除资金流干扰的 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 天前。这是有意为之的行为,我们会在接口文档中显式说明。
净资金流(Net Flow)—— /hl/ledger-updates/net-flow/{address}、/hl/ledger-updates/batch-net-flow
用途。 地址在指定窗口内向 Hyperliquid 永续和现货账户净转入的美元金额。可用于对收益进行去污,把盈亏(PnL)与现金流区分开。
输入数据。 user_ledger_updates,按地址和窗口过滤。
纳入计算的事件类型。
- L1 充值(链上 bridge 转入)。
- L1 提现(bridge 转出,记为负数)。
- 内部现货 ↔ 永续转账(在
netPerpIn和netSpotIn中以相反符号计入,保证总额自洽)。 - 金库(vault)充值与提现。
排除的事件类型。
spotTransfer(钱包到钱包的现货划转,未跨 Hyperliquid 永续/现货边界)。subAccountTransfer(主账户与其子账户之间的账簿调整 —— 这类事件不改变主账户的总资金)。
计算方式。 按类别对签名美元等值金额求和,返回格式为:
{
"address": "0x…",
"netPerpIn": "12345.00",
"netSpotIn": "678.90"
}
参数。
days∈ {1, 7, 30, 60, 90, 0}。days=0表示"全部时间"。
已知边界 —— 保留期截断。 user_ledger_updates 保留 90 天。因此 days=0 和 days=90 在实际效果上返回相同的数据,我们不会回填保留期之外的历史事件。
交易者行为(Trader Behaviour)—— /hl/traders/{address}/addr-stat、/hl/traders/batch-behavior-metrics
用途。 一组以滚动窗口为口径的行为类统计,刻画地址的交易风格。
输入数据。 预聚合的物化表 positions_dex_1d、positions_dex_7d、positions_dex_30d(每个地址一行,汇总对应周期内的聚合结果)。当 period=0("保留期内全部时间")时,计算回退到对 fills 和 filled_orders 做范围扫描,受常量 behaviorMetricsMaxLookbackDays = 90 限制,最多回溯 90 天。
字段。
| 字段 | 定义 |
|---|---|
winRate | 窗口内 closedPositionsWithPnl>0 / totalClosedPositions,即盈利平仓数 / 全部平仓数。 |
maxDrawdown | 与上文最大回撤同一套算法,在周期聚合表上预先计算。 |
totalPnl | 窗口内平仓已实现盈亏总和,单位美元。 |
orderCount | 窗口内不同成交订单的数量。 |
closedPositionCount | 窗口内开仓并完全平仓的仓位数量。 |
avgPositionDurationSec | 平仓仓位的 (close_time − open_time) 均值,单位秒。 |
profitLossRatio | mean(盈利平仓的收益) / mean(|亏损平仓的亏损|)。若任一侧为空,取 0。 |
参数。
period∈ {1, 7, 30, 0}。超出该集合的取值会被拒绝。period=0在服务端被限制为最多回溯 90 天。
不提供的指标。 夏普比率(Sharpe Ratio)、索提诺比率(Sortino Ratio)、Calmar 比率、盈利因子(Profit Factor)、基准相对 alpha 等指标,我们刻意不提供。它们都依赖于对无风险利率、采样频率、参照基准的选择,而我们更希望客户端根据自己的需求显式地做这些假设。自定义指标的计算方法 一节展示了如何基于现有的基础数据把这些指标拼装出来。
数据保留期与历史深度
我们运行的是一个滚动的热数据集,当前没有冷备归档。截至 2026-04-21,生效的保留期策略如下:
| 表名 | 保留期 | 影响的接口 |
|---|---|---|
fills | 90 天 | 行为指标、自定义成交查询 |
filled_orders | 90 天 | 行为指标 |
accum_pnls | 90 天 | 权益曲线 |
user_ledger_updates | 90 天 | 净资金流 |
positions_dex_{1,7,30}d | 滚动,每日重算 | 行为指标 |
snapshots_perp | 30 天 | 最大回撤 |
snapshots_position | 30 天 | 持仓状态查询 |
trades | 30 天 | K 线、最新成交查询 |
fundings | 30 天 | 资金费率时间序列 |
completed-trades(仓位) | 90 天 | 历史平仓查询 |
实际影响。 任何请求若名义窗口超出了底层表的保留期,服务端会在截断后的序列上计算,接口不会报错 —— 它会透明地做 clamp。本文档显式说明这一行为,方便客户端自行对账回填。
规划。 冷备归档(S3 上的 Parquet)已列入 roadmap,但尚未上线。在冷备落地之前,超出上述保留期的数据无法通过本 API 获取。
已知局限
-
超过 30 天的回撤窗口会被截断。
/hl/max-drawdown下days=60和days=90当前返回的仍是 30 天回撤。响应 schema 目前还没有effectiveWindowDays字段,我们会在后续版本中补上。在此之前,请把days≥30的返回统一当作"30 天最大回撤"处理。 -
组合
allTime窗口实际受 90 天保留期限制,而非硬编码的 2025-12-06 锚点限制。 锚点定义的是"我们愿意返回的最早日期",保留期定义的是"我们实际拥有的最早日期"。 -
行为指标
period=0是一个 90 天的近似。period=0下计算出来的首笔成交时间、订单总量、加仓摘要只反映最近 90 天。对于比这更早就在 Hyperliquid 上交易的地址,其"首笔成交时间"是保留期内最早的成交,而不是真正的起始。 -
净资金流不含保留期之前的充值。 如果一个地址的初始充值发生在查询时间的 90 天以前,它的
netPerpIn会明显小于朴素链上求和的结果。 -
不做子账户聚合。 每个地址都独立查询。如果某个交易者使用多个地址,跨地址聚合由客户端自行负责。
-
不做滑点与手续费归一化。 盈亏(PnL)数值直接来自 Hyperliquid 账本,已经包含支付的交易所手续费。我们不区分毛 PnL 与净 PnL。
-
不提供实时性保证。 快照是最终一致的。从 Hyperliquid 节点到 API 的端到端典型时延约 10–30 秒;在高峰期因反压(back-pressure)可能延长到几分钟。
自定义指标的计算方法
下面几则示例演示了如何在客户端基于现有接口构建常见的风险调整指标,三者都只依赖上文介绍的基础接口。
资金流去污后的 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, Time-Weighted Return)公式。
夏普比率(Sharpe Ratio)
选定一个采样间隔 Δt(例如从 allTime 组合窗口按日采样),然后:
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|),前提是盈利与亏损单笔的平均规模与接口返回的均值一致。如果需要更严格的计算,请直接查询 fills 表并计算:
PF = Σ 正的已实现盈亏 / |Σ 负的已实现盈亏|
如遇口径疑问、数据分歧或新指标需求,请联系对接的商务或技术支持。