Logo
新用户订阅 RPC,首月享 6.5 折优惠查看优惠
OnFinality Learn
网络与协议指南阅读约 14 分钟

Hyperliquid 资金费率机制:predictedFundings 与 fundingHistory 对比

了解 Hyperliquid 每小时资金费如何累积,predictedFundings 与 fundingHistory 有何区别,以及如何通过 /info API 计算并核对持仓的实际资金费支付。

TL;DR

在 Hyperliquid 上,资金费是多头与空头之间的定期转账,用于将永续合约的标记价格拉向其标的指数,并按每小时时间表累积,费率以每小时为单位表示。/info 端点暴露两个不同的对象:predictedFundings 是每个场所/资产对的前瞻性估算,会在区间内变化;fundingHistory 是已在有限窗口内累积的实际每小时费率。两者都不是用户的实际支付;你需要根据持仓名义价值、实际费率和持有小时数来计算,然后与账户价值历史进行核对。本指南解释该机制、读取界面、算术方法,以及常见错误,例如使用八小时惯例进行年化,或将 HIP-3 场所报价与主永续合约数字进行比较。

为什么永续合约需要资金费

永续期货没有到期日,因此没有任何机制像有到期日的合约结算那样,强制其价格回归标的现货或指数。资金费替代了缺失的结算:它是订单簿多头与空头之间定期发生的现金转移,从而产生激励,让折价交易的一方被持有,溢价交易的一方被减少。当永续合约价格高于指数时,多头支付空头;当低于指数时,空头支付多头。该机制在官方 Hyperliquid 资金费文档 中有描述,这是时间表和参数的权威一手来源。

对于构建仪表盘或机器人的人来说,实际后果是:资金费并不是交易所单独向你收取的费用。它是一种点对点转移,其符号取决于你的方向,其大小取决于永续合约与指数之间的价差。如果你做多且费率为正,你的持仓会因资金费而亏损;如果你做空,你会收到资金费。搞错符号约定是 PnL 归因错误最常见的单一来源。

  • 永续合约 = 无到期日,因此资金费替代了结算压力。
  • 正费率:多头支付空头。负费率:空头支付多头。
  • 费率响应的是永续合约与预言机之间的价差,而不是现货交易量。

每小时累积惯例,以及为什么“乘以三”是个 bug

在 Hyperliquid 上,资金费按每小时时间表累积,公布的费率以每小时为单位表示。许多较旧的场所报价八小时费率,因此如果开发者沿用将报价费率乘以三来得到日费率的习惯,就会将 Hyperliquid 资金费高估三倍。正确的日费率是小时费率乘以 24,正确的年化费率取决于你明确说明的复利假设。确切的钳制边界、区间以及返回费率的精度都是文档化的值;请将它们视为“文档化/可能变化”,并对照当前文档确认,而不是在机器人中硬编码常量。

一旦区间正确,持仓的支付就很直接:支付 = 持仓名义价值 x 资金费率 x 持有小时数,符号从持仓角度取。正费率下的多头持仓支付为负(它支付);正费率下的空头持仓支付为正(它收取)。由于费率是按小时计算的,根据文档化的时间表,持有不足一小时的持仓不会被收取整小时费用,但在依赖亚小时精度之前,你应核对确切的累积边界。

  • Hyperliquid 费率按小时计算;不要沿用八小时惯例。
  • 日费率 = 小时费率 x 24。年化需要说明复利假设。
  • 支付 = 名义价值 x 费率 x 小时数,符号从持仓角度取。

溢价与利率构成:真正推动费率变化的因素

从概念上讲,永续合约资金费率由溢价成分和利率成分组成:溢价成分反映永续合约标记价格与标的指数之间的偏离程度,利率成分反映双方之间的持有成本。在 Hyperliquid 上,费率响应的是永续合约与预言机之间的价差,而不是现货交易量,这就是为什么即使市场清淡,只要永续合约持续偏斜,仍可能承载可观的费率。锚定该价差的预言机价格在我们的 Hyperliquid 预言机价格与构建者拍卖 指南中有介绍。

由于费率是实时价差的函数,它不是你可以缓存一整天的常量。它会在区间内更新,这正是 API 将预测值与实际历史分开的原因。如果你的策略依赖资金费,你既需要前瞻性估算来做决策,也需要实际序列来做账。

  • 溢价成分跟踪永续合约与指数之间的价差。
  • 利率成分反映双方之间的持有成本。
  • 费率是动态的;不要将其缓存为每日常量。

predictedFundings:前瞻性估算,而非支付

predictedFundings 返回每个场所/资产对当前的预测资金费。它是一个前瞻性估算,会在区间内变化,是决策的正确输入:鉴于资金费的走向,我应该开仓、持有还是平仓?它不是你将实际支付的费率,因为实际费率是在累积时确定的。将预测值视为信号,而不是会计数字。

场所拆分在这里很重要。Hyperliquid 支持多个场所,包括 HIP-3 dex 以及永续和现货对,predictedFundings 按场所/资产对返回条目。将 HIP-3 dex 报价与主永续合约数字进行比较是类别错误,会悄悄破坏套利筛选。始终按场所和资产两者来键控查询,并在解析之前对照官方 Hyperliquid info 端点参考 确认请求和响应结构。

  • predictedFundings = 前瞻性估算,会在区间内变化。
  • 用它来决策,而不是用来做账。
  • 按场所和资产两者键控;切勿盲目跨场所比较。

fundingHistory:有限窗口内的实际每小时费率

fundingHistory 返回已在有限窗口内累积的实际每小时费率。这是会计、PnL 归因和回测的输入,因为这些费率确实发生了。窗口是有限的,因此假设它是无限的是一个真实的失败模式:如果你请求的历史超过端点返回的范围,你会悄悄得到被截断的序列,回测会从错误的位置开始。长度和时间窗口的行为如文档所述;请确认当前边界,而不是假设固定数量。

资金费快照和资金费支付是不同的对象。fundingHistory 给你费率;它不给你账户支付的美元金额。要得到支付,你必须将实际费率序列与持仓名义价值和持有期结合起来。这一区别是正确读取资金费的核心,也是为什么仅绘制 fundingHistory 的仪表盘看起来正确,却报告错误 PnL 的原因。

  • fundingHistory = 实际费率,有限窗口,用于会计和回测。
  • 费率不是支付;你必须将其与名义价值和小时数结合。
  • 不要假设窗口是无限的。

从永续账户状态计算实际资金费

要计算账户的实际资金费,请通过 clearinghouseState 读取持仓的永续账户状态、其入场名义价值和保证金,然后将其与 fundingHistory 中的实际每小时费率序列结合。持仓名义价值乘以每个实际小时费率,再对持有小时数求和,就得到 PnL 中的资金费成分。将结果与账户自身的价值历史核对,以捕捉符号错误:如果你计算出的资金费使账户价值变动方向与观察到的变化相反,那么你的符号约定就是反的。

这是一种验证方法,而不是测量结果。请用你自己的端点和账户填写下面的结果表,以便数字可由你复现。我们的 Hyperliquid 历史与市场数据 API 指南涵盖了这些序列的检索方面;本页涵盖机制和算术。

  • 读取 clearinghouseState 获取持仓、入场名义价值和保证金。
  • 与 fundingHistory 中的实际每小时费率序列结合。
  • 与账户价值历史核对,以捕捉符号错误。

可运行的 Node 脚本:预测费率、实际序列、年化数字、支付

下面的脚本获取某个币种的 predictedFundings 和 fundingHistory,打印当前预测小时费率、最近 N 个实际费率、明确说明复利假设的年化数字,以及给定持仓规模在给定小时数内的计算资金费支付。将端点替换为你自己的提供商 URL,并调整币种和持仓参数。它仅使用原生 /info API 和 Node 内置的 fetch。

请注意,这里的年化数字使用简单的 24 x 365 乘法,没有复利,脚本会打印该假设,因此你不会将其误认为复利收益。如果你更喜欢复利,请说明并更改公式;关键是假设是明确的,而不是隐藏的。

// funding.js — Node 18+ (built-in fetch)
const ENDPOINT = process.env.HL_INFO_URL || 'https://api.hyperliquid.xyz/info';
const COIN = process.env.COIN || 'BTC';
const POSITION_NOTIONAL = Number(process.env.NOTIONAL || 10000); // USD
const HOURS_HELD = Number(process.env.HOURS || 24);
const LAST_N = Number(process.env.LAST_N || 24);

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

function annualiseSimple(hourlyRate) {
  // Simple (non-compounded) annualisation: hourly * 24 * 365
  return hourlyRate * 24 * 365;
}

(async () => {
  // 1) Current predicted funding for each venue/asset pair
  const predicted = await post({ type: 'predictedFundings' });
  const match = (predicted || []).find(
    (row) => JSON.stringify(row).includes(COIN)
  );
  console.log('predictedFundings match:', JSON.stringify(match, null, 2));

  // 2) Realised per-hour rates over a bounded window
  const history = await post({
    type: 'fundingHistory',
    coin: COIN,
    startTime: Date.now() - 1000 * 60 * 60 * 24 * 7,
  });
  const rates = (history || []).map((r) => Number(r.fundingRate));
  const lastN = rates.slice(-LAST_N);
  console.log(`last ${lastN.length} realised hourly rates:`, lastN);

  const latestRealised = lastN[lastN.length - 1] ?? 0;
  console.log('latest realised hourly rate:', latestRealised);
  console.log(
    'annualised (simple, x24x365, no compounding):',
    annualiseSimple(latestRealised)
  );

  // 3) Funding payment for a position over N hours
  // payment = notional * rate * hours, signed from the position's perspective.
  // Positive rate => longs pay shorts. Flip sign for a short position.
  const isLong = true;
  const sign = isLong ? -1 : 1;
  const payment = sign * POSITION_NOTIONAL * latestRealised * HOURS_HELD;
  console.log(
    `funding payment for ${isLong ? 'long' : 'short'} ` +
      `${POSITION_NOTIONAL} USD over ${HOURS_HELD}h: ${payment.toFixed(4)} USD`
  );
})().catch((e) => {
  console.error('funding script failed:', e.message);
  process.exit(1);
});

结果表:用你自己的端点测量资金费

使用下表记录你的端点实际返回的内容。不要将任何行视为 OnFinality 特定的测量值;这些是供你从自己的提供商和账户填写的字段。运行上面的脚本,然后将计算出的支付与你在同一窗口内观察到的账户价值变化进行核对。

如果计算出的支付与观察到的账户价值变化符号不一致,则你的持仓方向或费率符号是反的。如果大小不一致,请检查你使用的是实际费率还是预测费率,以及你的持有小时数是否与累积边界匹配。

  • 币种/场所:你查询的确切资产和场所对。
  • 预测小时费率:查询时来自 predictedFundings 的值。
  • 最新实际小时费率:来自 fundingHistory 的最后一条记录。
  • 年化(简单,x24x365):已说明假设,无复利。
  • 持仓名义价值和持有小时数:你的输入。
  • 计算出的资金费支付:名义价值 x 费率 x 小时数,带符号。
  • 观察到的账户价值变化:来自你自己的价值历史。
  • 符号匹配?大小匹配?记录任何差异。

读取 Hyperliquid 资金费时的常见失败

下面的失败是最常破坏资金费仪表盘或套利机器人的情况。每一个都是机制误解,而不是 API bug,这就是它们能通过代码审查的原因。对于请求级问题,例如格式错误的请求体或被拒绝的订单,请参阅 Hyperliquid API 错误处理与订单拒绝

将预测值当作实际值读取是最具破坏性的:它使你的会计依赖于一个在区间内变化的值。用错误的区间进行年化会以固定倍数高估或低估。假设资金费窗口是无限的会悄悄截断回测。忽略场所拆分会破坏跨场所比较。将未实现 PnL 与资金费混在一起会混淆两个不同的 PnL 成分。假设 API 未承诺的精度或舍入会产生随时间累积的漂移。

  • 将预测值当作实际值读取。
  • 使用八小时惯例而不是每小时进行年化。
  • 假设资金费窗口是无限的。
  • 忽略场所拆分(HIP-3 dex 与主永续合约)。
  • 将未实现 PnL 与资金费混在一起。
  • 假设 API 未承诺的精度或舍入。

故障排除检查清单

当资金费数字看起来不对时,按顺序完成此检查清单。它从最便宜的检查(符号)到最昂贵的检查(与账户历史核对)。如果你调试的是连接或订阅行为而不是算术,我们的 Hyperliquid WebSocket 订阅 指南涵盖了流式方面。

将检查清单与你的代码放在一起,这样下一个接触资金费模块的人就有明确的路径。大多数资金费 bug 会在第一步或第二步被捕获。

  • 确认费率是按小时,而不是按八小时。
  • 确认你在会计中使用的是实际值(fundingHistory),而不是预测值。
  • 确认符号与你的持仓方向匹配。
  • 确认场所/资产键与持仓的实际场所匹配。
  • 确认历史窗口未被截断。
  • 将计算出的支付与账户价值历史核对。
  • 确认没有硬编码的钳制或精度常量偏离文档。

限制与假设

本指南描述文档化的机制和 API 结构;它不主张任何 OnFinality 特定的费率、延迟或限制。所有上限、窗口和精度都是“文档化/可能变化”,应对照当前 Hyperliquid 文档和你的提供商文档进行确认。脚本中的年化数字使用简单乘法,没有复利,并且该假设是打印出来的,而不是隐藏的。

核对方法假设你可以读取与资金费序列同一窗口内的自己的账户价值历史。如果你的价值历史粒度比每小时累积更粗,预期会有小残差,并将其视为测量噪声而不是 bug。关于提供商选择和端点行为,请参阅 Hyperliquid RPC 端点与提供商

  • 不主张任何 OnFinality 特定的费率、延迟或限制。
  • 上限、窗口、精度:文档化/可能变化。
  • 年化假设是简单的、非复利的,并且已说明。
  • 核对残差可能反映价值历史粒度。

后续步骤

首先针对你自己的端点运行脚本并填写结果表。然后将实际序列接入你的 PnL 归因,使资金费成为一等成分,而不是残差。如果你正在构建套利筛选,请在排名机会之前按场所和资产键控每次比较。

关于交易、OHLCV 和资金费历史的检索方面,请阅读 Hyperliquid 历史与市场数据 API。关于锚定溢价的预言机价格,请阅读 Hyperliquid 预言机价格与构建者拍卖。要选择端点,请从 Hyperliquid RPC 端点与提供商 开始,关于计划和吞吐量请参阅 RPC 定价API 服务。在 OnFinality Learn 中心Hyperliquid 网络页面 浏览更多机制指南。

  • 运行脚本,填写结果表,与账户历史核对。
  • 使资金费成为一等 PnL 成分。
  • 按场所和资产键控套利比较。
  • 在硬编码之前,对照当前文档确认所有上限和窗口。

永远不用担心基础设施

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

开始