Logo
新用户订阅 RPC,首月享 6.5 折优惠查看优惠
OnFinality Learn
集成与开发阅读约 12 分钟

Hyperliquid clearinghouseState:解读保证金与清算风险

学习如何通过 info API 读取 Hyperliquid clearinghouseState,区分全仓与逐仓保证金,并计算可据以行动的清算距离。

TL;DR

Hyperliquid 的 clearinghouseState info 请求返回账户的保证金摘要、各资产持仓以及全仓维持保证金数值。info 端点是一个无需认证的只读 POST 请求,因此监控进程永远不需要私钥。全仓保证金账户在各持仓之间共享抵押品,而逐仓持仓则独立计算保证金,因此账户级摘要不能套用到单个逐仓持仓上。清算价格是根据维持保证金要求和杠杆推导出来的,而非直接返回,所以应从维持保证金缓冲中计算距离。本文展示一个可运行的 Node.js 监控程序、一张待填写的结​​果表,以及那些会让过期或误读的响应看起来比实际更健康的失效模式。

clearinghouseState info 请求及其文档化的响应结构

Hyperliquid 通过 info API 暴露账户状态,这是一个只读接口,接受向 info 路径发送 POST 请求,请求体为 JSON 并指定请求类型。clearinghouseState 请求接收一个用户地址,返回账户的保证金摘要、各资产持仓以及一个全仓维持保证金字段。Hyperliquid 关于永续合约 info 端点的文档描述了响应结构,包括带有数量、开仓价格和持仓价值的各资产持仓条目,以及包含账户价值、已用保证金总额和总名义持仓的保证金摘要。

请将确切的字段名及任何附加字段视为已有文档说明,但可能随 API 版本变化。正确的习惯是:先记录一次原始响应,对照 Hyperliquid 文档:永续合约 info 端点 确认字段名,然后再编写读取它们的代码。硬编码你在某篇博客文章中看到的字段名,正是监控程序悄悄开始返回 undefined 并报告账户健康的原因。

如果你更倾向于使用托管路径,也可以通过 Hyperliquid RPC 端点(RPC Assistant) 查询同一账户,但请求体和响应结构属于协议本身,而非提供商。缓存、速率限制和重试语义等提供商特定行为因提供商而异,并各有文档说明,因此请针对你实际调用的端点进行验证。

  • clearinghouseState 是只读 info 请求;它不会下单或撤单。
  • 响应包含账户级保证金摘要以及各资产持仓条目。
  • 字段名有文档说明,但在硬编码前应针对当前响应进行验证。

为什么 info API 和 exchange API 是不同的接口

info 端点是一个无需认证的只读 POST 请求。下单、撤单以及任何改变状态的操作都需要使用私钥对 exchange 端点进行签名。这种分离是构建清算警报时最重要的安全特性:只读取 clearinghouseState 的监控进程永远不需要私钥,因此即使监控程序被攻破也无法转移资金。

这一点值得明确说明,因为另一种模式——在仪表盘或告警服务中嵌入签名密钥——会把只读风险工具变成托管风险。如果你的监控程序需要在触发阈值时采取行动,请将签名密钥放在具有独立授权边界的单独进程中,让监控程序发出事件而非交易。

API 服务 页面描述了 OnFinality 如何暴露这些接口,而 Hyperliquid API 错误处理与订单拒绝 一文则介绍了签名侧请求被拒绝时会发生什么。对于监控而言,只读路径才是关键。

  • Info 端点:只读 POST,无需认证,无需私钥。
  • Exchange 端点:签名请求,需要私钥,会改变状态。
  • 不要让任何只需读取账户状态的进程持有签名密钥。

全仓保证金、逐仓保证金,以及为什么这一区分会改变每一个数字

在全仓保证金账户中,抵押品在各持仓之间共享,因此一个持仓的健康状况取决于整个账户。在逐仓持仓中,保证金仅分配给该持仓,因此其健康状况只取决于自身的抵押品和规模。Hyperliquid 的保证金文档 Hyperliquid 文档:保证金 描述了这两种模式以及适用的维持保证金要求。

这一区分是错误风险数字最常见的来源。调用方如果读取账户级保证金摘要并将其套用到单个逐仓持仓上,会计算出毫无意义的清算距离,因为账户摘要包含逐仓持仓无法使用的抵押品。在计算任何东西之前,先确定该持仓处于哪种模式,以及哪种摘要适用于它。

读者接下来会搜索的账户模式词汇——组合保证金、全仓与逐仓、抵押资产、统一账户和对冲模式——描述的都是同一个分叉。如果你不确定账户使用哪种模式,最安全的做法是分别读取持仓条目和账户摘要,在输出中分别标注,绝不将它们混为一个数字。

  • 全仓保证金:抵押品共享,持仓健康取决于整个账户。
  • 逐仓保证金:抵押品按持仓分配,健康仅取决于该持仓。
  • 绝不要将账户级摘要套用到逐仓持仓上。

避免经典错误的逐字段读取顺序

先读取账户级字段:账户价值和已用保证金总额给出保证金比率,全仓维持保证金给出清算前的缓冲。然后读取各资产持仓条目,它们描述的是持仓而非账户。混淆两者是错误风险数字最常见的来源,因为持仓的名义价值不等于账户的总名义持仓。

一个有用的纪律是将账户摘要和持仓条目打印在分开的区块中,并加上明确标签,这样输出的读者就能看出每个数字来自哪一层级。当你计算距离时,在结果旁边写明公式,这样数字就可以被审计,而不是被盲目信任。

Hyperliquid 资金费率机制 一文解释了资金费累积如何在两次轮询之间改变账户价值,这就是为什么即使没有发生交易,账户级字段也可能漂移。

  • 账户级:账户价值、已用保证金总额、全仓维持保证金。
  • 持仓级:各资产的数量、开仓价格、持仓价值。
  • 在输出中为每个区块加标签,使每个数字的来源可见。

为什么清算价格是推导出来的而非直接返回

账户端点并不承诺提供清算价格。清算价格是一个推导量:它取决于维持保证金要求、杠杆、持仓规模以及该持仓或账户可用的抵押品。由于这些输入会随资金费、新持仓和保证金模式而变化,返回的清算价格会是一个立即过期的快照。

实际后果是,你应该从维持保证金缓冲计算距离,而不是试图读取清算价格。缓冲是交易所自身用来决定何时采取行动的数值,因此从它推导出的距离比从你猜测的公式推导出的价格更接近机制本身。

如果你想要一个类似价格的数字用于仪表盘,请推导它,并将其标注为带有公式的估算值。不要将其呈现为交易所提供的值。

  • 清算价格由维持保证金、杠杆、规模和抵押品推导而来。
  • 维持保证金缓冲是交易所据以行动的数值。
  • 任何类似价格的输出都应标注为估算值并附上公式。

一个可运行的 Node.js clearinghouseState 监控程序

下面的监控程序会 POST 文档化的 clearinghouseState info 请求体,读取响应,并打印各资产的数量和名义价值以及账户的维持保证金缓冲。然后它会打印一个明确标注的、附有公式的清算距离计算值,以便读者审计。请将端点和地址替换为你自己的。

代码以防御性方式读取字段名,并在字段缺失时打印一次原始响应,这是发现 API 版本重命名了某个字段的最快方法。它不签署任何内容,也不需要私钥。

// monitor.js — read-only Hyperliquid clearinghouseState monitor
// Run: node monitor.js
// No private key required. Info endpoint is read-only.

const ENDPOINT = process.env.HL_INFO_URL || 'https://api.hyperliquid.xyz/info';
const USER = process.env.HL_USER || '0xYourAccountAddress';

async function fetchClearinghouseState(user) {
  const res = await fetch(ENDPOINT, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ type: 'clearinghouseState', user })
  });
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json();
}

function num(v) {
  const n = Number(v);
  return Number.isFinite(n) ? n : null;
}

function printState(state) {
  const summary = state.marginSummary || {};
  const accountValue = num(summary.accountValue);
  const totalMarginUsed = num(summary.totalMarginUsed);
  const totalNtlPos = num(summary.totalNtlPos);
  const crossMaint = num(state.crossMaintenanceMargin);

  console.log('--- ACCOUNT SUMMARY ---');
  console.log('accountValue        :', accountValue);
  console.log('totalMarginUsed     :', totalMarginUsed);
  console.log('totalNtlPos         :', totalNtlPos);
  console.log('crossMaintenanceMargin:', crossMaint);

  if (accountValue !== null && totalMarginUsed !== null && totalMarginUsed > 0) {
    console.log('marginRatio         :', (totalMarginUsed / accountValue).toFixed(4));
  }

  console.log('--- POSITIONS ---');
  for (const p of state.assetPositions || []) {
    const pos = p.position || {};
    const szi = num(pos.szi);
    const entry = num(pos.entryPx);
    const posValue = num(pos.positionValue);
    console.log({
      coin: pos.coin,
      szi,
      entryPx: entry,
      positionValue: posValue
    });
  }

  // Distance to liquidation, derived from the maintenance-margin buffer.
  // Formula: distance = (accountValue - crossMaintenanceMargin) / accountValue
  // This is an estimate, not a venue-provided liquidation price.
  if (accountValue !== null && crossMaint !== null && accountValue > 0) {
    const buffer = accountValue - crossMaint;
    const distance = buffer / accountValue;
    console.log('--- COMPUTED DISTANCE (estimate) ---');
    console.log('formula: (accountValue - crossMaintenanceMargin) / accountValue');
    console.log('buffer  :', buffer.toFixed(2));
    console.log('distance:', distance.toFixed(4));
  } else {
    console.log('Missing fields; dumping raw response for inspection:');
    console.log(JSON.stringify(state, null, 2));
  }
}

(async () => {
  try {
    const state = await fetchClearinghouseState(USER);
    printState(state);
  } catch (err) {
    console.error('monitor failed:', err.message);
    process.exitCode = 1;
  }
})();

一张针对你自己账户填写的结果表

在多个时间点针对你自己的账户运行监控程序,记录账户价值、已用保证金总额、维持保证金和计算出的距离。这会将一个模糊的“我离清算有多近”问题转化为可以设定阈值的趋势。下表是一个模板;数值由你测量,而非由我们断言。

由于资金费累积会在两次轮询之间改变账户价值,单次读数不是趋势。以固定间隔读取,记录期间发生的任何交易或转账,并关注距离列的方向而非其绝对值。

  • 结果表列:时间戳、账户价值、已用保证金总额、全仓维持保证金、计算距离、备注。
  • 以固定间隔读取,使趋势具有可比性。
  • 在备注列记录交易和转账,以便解释阶跃变化。

失效模式:过期缓存、索引路径、资金费漂移,以及对错误字段告警

过期的缓存响应会让账户看起来比实际更健康。如果你的提供商缓存 info 响应,那么轮询速度快于缓存刷新的监控程序会反复看到同一状态并错过变动。请对照提供商的文档验证缓存行为,并考虑使用缓存清除参数或第二个端点进行确认。

一个持仓可能存在于某个交易所或资产索引路径上,而不存在于另一个路径上,因此只读取一个路径的监控程序可能会在别处有持仓时报告账户为空。资金费累积会在没有交易的情况下于两次轮询之间改变账户价值,这就是为什么计算一次并存储的距离不是距离。而仅对账户价值告警是一个陷阱:维持保证金缓冲才是真正预测清算的数值,因此看起来舒适的账户价值可能建立在薄缓冲之上。

Hyperliquid 历史市场数据Hyperliquid 预言机价格与拍卖信息 两篇文章介绍了相邻的数据接口,可帮助你交叉核对账户端点报告的内容。

  • 过期缓存:反复返回同一状态,错过变动。
  • 索引路径:持仓在一个路径上可见而在另一个路径上不可见。
  • 资金费漂移:账户价值在没有交易的情况下变化。
  • 错误字段:对账户价值而非维持保证金缓冲告警。

排查报告错误风险数字的监控程序

当数字看起来不对时,首先转储原始响应,并将字段名与当前文档进行比对。被重命名的字段会返回 undefined,而对 undefined 进行算术运算会产生 NaN,许多仪表盘会将其渲染为零。其次,确认保证金模式:如果持仓是逐仓的,账户级摘要不适用,修复方法是读取持仓自身的抵押品而非账户的。

第三,检查单位。有些字段是字符串,有些是数字,有些经过了缩放。请显式解析,并将解析后的值与原始值一起记录。第四,将响应的时间戳与你的轮询时间进行比对;如果提供商有缓存,响应可能比你想象的更旧。

如果你通过托管端点调用,RPC 定价 页面描述了计划级行为,而 OnFinality Learn 中心 将相关的 Hyperliquid 文章汇集在一处。

  • 在信任算术之前,先转储原始响应并验证字段名。
  • 在套用账户摘要之前,先确认保证金模式。
  • 显式解析并记录单位;字符串和缩放整数很常见。
  • 将响应时间戳与轮询时间比对以检测缓存。

纯观察型风险工具的局限与权衡

这是一个观察工具。它读取状态并计算一个数字;它不预测清算时机,也无法看到持仓在两次轮询之间被交易所自身引擎平仓。每分钟轮询一次的监控程序有一分钟盲区,再高的公式精度也无法消除这一点。

权衡在于轮询频率与成本之间。更快的轮询缩小盲区,但会增加请求量并提高触及提供商速率限制的可能性,后者因提供商而异,并按计划有文档说明。另一个权衡是简单性与完整性之间:只读取 clearinghouseState 的监控程序易于推理,但对其他索引路径上的持仓视而不见;而读取所有内容的监控程序则更难审计。

在工具本身中说明这些局限。一个没有公式、时间戳和盲区说明的距离数字会招致过度自信。

  • 仅观察:不预测清算时机。
  • 轮询之间存在盲区;频率与成本和速率限制之间存在权衡。
  • 简单性与完整性:单一路径可审计但不完整。

后续步骤:从单次读数到带阈值的趋势

首先运行一次监控程序,并对照当前响应确认字段名。然后以固定间隔运行,填写结果表,并对距离列而非账户价值设置阈值。当距离越过阈值时,发出一个事件;将任何签名密钥保留在单独的进程中。

要进一步深入,可添加第二个数据源进行交叉核对,阅读 Hyperliquid 资金费率机制 一文了解资金费如何改变账户价值,并使用 Hyperliquid RPC 端点(RPC Assistant) 参考来确认你调用的端点。OnFinality Learn 中心 汇集了完整的 Hyperliquid 系列文章,而 API 服务 页面描述了如何通过 OnFinality 访问这些接口。

  • 确认一次字段名,然后以固定间隔自动化。
  • 对计算出的距离设置阈值,而非账户价值。
  • 让签名密钥远离监控进程。
  • 在采取行动前用第二个数据源交叉核对。

永远不用担心基础设施

OnFinality 消除了 DevOps 的繁重工作,让您能够更聪明、更快地构建。

开始