Hyperliquid fill 接口响应体详解

官方文档地址

Info endpoint | Hyperliquid Docs
The info endpoint is used to fetch information about the exchange and specific users. The different request bodies result in different corresponding response body schemas.

这是一个 Hyperliquid fill(成交记录) 的响应体示例(常见于 userFills 接口、WebSocket userFills 推送或类似地方),下面逐字段解释:

{
  "coin": "xyz:AMD",                  // 资产符号。对于 HIP-3(多 dex)资产会带前缀,比如 xyz:、 purp: 等;普通 perp 就是单纯币种如 BTC、ETH
  "px": "213.47",                     // **成交价格**(成交时的执行价格)
  "sz": "0.912",                      // **本次成交数量**(这次 fill 实际成交的张数/币数)
  "side": "A",                        // 成交方向: "B" = Buy(买入),"A" = Sell(卖出 / Ask)
  "time": 1770215435819,              // **成交时间戳**(毫秒级 Unix timestamp)
  "startPosition": "0.912",           // **本次成交前的持仓大小**(正数=多头,负数=空头)。用于帮助计算/校验持仓变化
  "dir": "Close Long",                // **本次成交的持仓影响方向**(前端显示用),常见值:
                                      //   Open Long   → 开多
                                      //   Open Short  → 开空
                                      //   Close Long  → 平多
                                      //   Close Short → 平空
                                      //   Buy / Sell  → 现货或不影响持仓的情况
  "closedPnl": "-11.688192",          // **本次成交实现的已实现盈亏**(只有平仓方向才有非零值,单位通常是 USDC)
  "hash": "0x23eb7bda8746a46f25650434aa96720206b200c02249c341c7b4272d464a7e59",
                                      // **L1 交易哈希**(上链的交易哈希,可在浏览器查看)
  "oid": 311561736864,                // **订单 ID**(order id),本次 fill 所属的 maker/taker 订单的 oid
  "crossed": true,                    // 是否**吃单(taker)**:true = 吃掉了订单簿上的流动性(taker),false = 挂单成交(maker)
  "fee": "0.01682",                   // **本次成交手续费**(金额)
  "tid": 833777413644058,             // **成交 ID**(全局唯一的 trade/fill ID,通常比 oid 更唯一)
  "liquidation": {                    // **如果是强平成交**,这里会有内容;否则为 null 或不存在
    "liquidatedUser": "0x324f74880ccee9a05282614d3f80c09831a36774",  // 被强平的用户地址
    "markPx": "214.04",               // 强平时的标记价格
    "method": "market"                // 强平方式(market = 市价强平)
  },
  "feeToken": "USDC",                 // 手续费扣除的代币(目前几乎都是 USDC)
  "twapId": null                      // 如果是 TWAP 订单的一部分,这里会有 TWAP 的 id;否则 null
}

字段总结对比表(最常用字段)

 
字段 中文含义 是否必有 典型值示例 备注
coin 资产 BTC, SOL, xyz:AMD HIP-3 资产带前缀
px 成交价格 "213.47" 字符串,注意精度
sz 本次成交量 "0.912"字符串
side 买卖方向 "B" / "A" B=买 A=卖
time 时间戳 毫秒级
dir 持仓方向(显示用) "Close Long" 最直观判断是开/平仓
closedPnl 实现盈亏 "-11.688192" / "0.0" 平仓才有非零值
startPosition 成交前持仓 "0.912" / "-5.0" 判断持仓变化非常有用
crossed 是否 taker true/false true=吃单,付 taker 费
fee 手续费金额 "0.01682"
oid 订单ID 311561736864 对应你下的订单
tid 成交ID 833777413644058 全局唯一
hash 上链交易哈希 0x23eb... 可查区块链浏览器
liquidation 强平信息 object / null 只在强平 fill 出现
feeToken 手续费币种 "USDC" 目前基本固定
twapId TWAP ID null / number TWAP 分拆成交才有值

这份结构基本覆盖了目前(2026年初)Hyperliquid perp 和 HIP-3 资产的 fill 返回格式。如果你在写风控、pnl 计算、对账系统,强烈建议重点关注 startPosition → sz → dir → closedPnl 这几个字段的组合,它们能完整重现持仓和盈亏变化路径。

注意 liquidation 这个字段一般不存在,存在就意味着是强平的!

强平检测脚本

#!/usr/bin/env python3
"""
爆仓检测测试脚本
直接从 API 获取数据,验证 liquidation 字段
"""
from hyperliquid.info import Info
from datetime import datetime
import sys


def test_liquidation(address: str):
    """检测指定地址的爆仓记录"""

    print("=" * 80)
    print("🔍 爆仓检测测试")
    print("=" * 80)
    print(f"\n地址: {address}")
    print("-" * 80)

    info = Info(skip_ws=True)

    # 1. 直接从 API 获取 fills 数据
    print("\n【步骤1】从 API 获取交易记录...")
    fills = info.user_fills_by_time(address, start_time=0)
    print(f"  获取 {len(fills)} 条记录")

    # 2. 检测爆仓记录
    print("\n【步骤2】检测爆仓记录...")
    liquidations = []

    for fill in fills:
        liq_info = fill.get('liquidation')
        if liq_info:
            liquidations.append({
                'time': fill.get('time'),
                'coin': fill.get('coin'),
                'side': fill.get('side'),
                'price': fill.get('px'),
                'size': fill.get('sz'),
                'closedPnl': fill.get('closedPnl'),
                'dir': fill.get('dir'),
                'liquidation': liq_info,
                'hash': fill.get('hash')
            })

    if liquidations:
        print(f"\n  ⚠️  发现 {len(liquidations)} 笔爆仓记录:")
        print("-" * 80)

        total_loss = 0.0
        for i, liq in enumerate(liquidations, 1):
            time_str = datetime.fromtimestamp(liq['time'] / 1000).strftime('%Y-%m-%d %H:%M:%S')
            pnl = float(liq['closedPnl'])
            total_loss += pnl

            print(f"\n  [{i}] {time_str}")
            print(f"      币种: {liq['coin']}")
            print(f"      方向: {liq['dir']} ({liq['side']})")
            print(f"      价格: {liq['price']}")
            print(f"      数量: {liq['size']}")
            print(f"      已实现盈亏: ${pnl:,.2f}")
            print(f"      清算详情:")
            print(f"        - 被清算用户: {liq['liquidation'].get('liquidatedUser', 'N/A')}")
            print(f"        - 标记价格: {liq['liquidation'].get('markPx', 'N/A')}")
            print(f"        - 清算方式: {liq['liquidation'].get('method', 'N/A')}")
            print(f"      交易哈希: {liq['hash']}")

        print("\n" + "=" * 80)
        print(f"📊 爆仓统计")
        print("=" * 80)
        print(f"  总爆仓次数: {len(liquidations)}")
        print(f"  总爆仓损失: ${total_loss:,.2f}")

        # 按币种统计
        coin_stats = {}
        for liq in liquidations:
            coin = liq['coin']
            if coin not in coin_stats:
                coin_stats[coin] = {'count': 0, 'loss': 0.0}
            coin_stats[coin]['count'] += 1
            coin_stats[coin]['loss'] += float(liq['closedPnl'])

        print(f"\n  按币种统计:")
        for coin, stats in sorted(coin_stats.items(), key=lambda x: x[1]['loss']):
            print(f"    {coin}: {stats['count']} 次, ${stats['loss']:,.2f}")
    else:
        print("\n  ✅ 未发现爆仓记录")

    # 3. 对比数据库数据(可选)
    print("\n" + "=" * 80)
    print("📋 数据结构对比")
    print("=" * 80)

    if fills:
        last_fill = fills[-1]
        print("\n  API 返回的完整字段:")
        for key in sorted(last_fill.keys()):
            value = last_fill[key]
            if key == 'liquidation' and value:
                print(f"    ✅ {key}: {value}")
            else:
                print(f"    {key}: {type(value).__name__}")

        print("\n  数据库存储的字段:")
        db_fields = ['address', 'time', 'coin', 'side', 'price', 'size', 'closed_pnl', 'fee', 'hash']
        for field in db_fields:
            print(f"    {field}")
        print(f"    ❌ liquidation (未存储)")

    return liquidations


def main():
    # 默认测试地址
    default_address = "0x324f74880ccee9a05282614d3f80c09831a36774"

    if len(sys.argv) > 1:
        address = sys.argv[1]
    else:
        address = input(f"请输入地址 (默认={default_address}): ").strip()
        if not address:
            address = default_address

    test_liquidation(address)


if __name__ == "__main__":
    main()

Read more

跑步的技巧(滚动落地)

“滚动落地(rolling contact / rolling foot strike)”不是一种教条式的“脚法”,而是一种 让冲击沿着整只脚、整条后链逐级传递的落地机制。 它的核心不是“你先用哪儿着地”,而是: 你的脚落地之后,冲击是不是像轮子一样滚过去,而不是像锤子一样砸下去。 这就是滚动落地的本质。 一、什么叫“滚动落地”? 你可以把它理解成两种完全不同的落地方式: 1. 砸地(撞击式) 脚像锤子一样拍到地上: * 要么后跟先砸 * 要么前掌先戳 * 冲击集中在一个点 * 一个结构瞬间吃掉大部分载荷 结果就是: * 后跟砸 → 膝盖难受 * 前掌戳 → 前脚掌磨烂 * 都不是长跑友好模式 这叫 撞击式着地(impact strike)。 2. 滚地(滚动式) 脚像轮胎一样“滚”过地面: * 不是某一点硬砸 * 而是外侧中足先轻触 * 再向前滚到前掌 * 最后从大脚趾蹬离

By SHI XIAOLONG

AMI的优越性

世界模型(World Models)的具体例子 如下,我按类型分类,便于理解。每类都附带实际实现、演示效果和应用场景。 1. Yann LeCun / Meta 的 JEPA 系列(最直接对应“世界模型”概念) 这些是 LeCun 主张的非生成式抽象预测世界模型代表。 * I-JEPA(Image JEPA,2023) 输入一张图像,模型把不同区域(context 和 target)编码成抽象表示,然后预测 target 的表示(不在像素级别重建)。 例子:给定一张遮挡了部分物体的图片,模型能预测“被遮挡物体的大致位置和属性”,构建对物体持久性和空间关系的理解。 这是一个“原始世界模型”,能学习物理常识(如物体不会凭空消失)。 * V-JEPA / V-JEPA 2(Video JEPA,

By SHI XIAOLONG

什么是:“世界模型(World Models)”

世界模型(World Models) 是人工智能领域的一个核心概念,尤其在 Yann LeCun 等研究者推动的下一代 AI 架构中占据中心位置。它指的是 AI 系统在内部构建的对现实世界的抽象模拟或内部表示,让机器能够像人类或动物一样“理解”物理世界、预测未来、规划行动。 简单比喻 想象你闭上眼睛也能“看到”房间里的物体会如何移动、碰撞或掉落——这就是你大脑里的世界模型。AI 的世界模型就是类似的“数字孪生”(digital twin)或“内部模拟器”:它不是简单记住数据,而是学习世界的动态、因果关系和物理直觉(如重力、物体持久性、遮挡、因果等)。 为什么需要世界模型? 当前主流的大型语言模型(LLM) 擅长处理文本(统计模式预测),但存在根本局限: * 缺乏对物理世界的真正理解 → 容易“幻觉”、无法可靠规划。 * 样本效率低 → 人类/

By SHI XIAOLONG

K线周期可配置化设计方案

K线周期可配置化设计方案 1. 背景与目标 当前 Beta 套利策略的 K 线周期硬编码为 "1h",分散在多个文件中。需要: 1. 将 K 线周期从 1h 改为 2h 2. 提取为环境变量 BETA_ARB_KLINE_INTERVAL,使其可在 .env 中配置 2. 影响范围分析 2.1 需要修改的文件(共 6 个) 文件 硬编码位置 修改内容 src/trading/config.py BetaArbConfig dataclass 新增 kline_interval 字段,

By SHI XIAOLONG