""" Hyperliquid 接入测试脚本 用法: source venv/bin/activate HL_API_PRIVATE_KEY="0x你的API钱包私钥" \ HL_ACCOUNT_ADDRESS="0x你的MetaMask地址" \ python scripts/test_hyperliquid.py 会做以下验证(只读,不下单): 1. 连通性检查 2. 账户 USDC 余额 3. BTC-PERP 当前价格 4. 当前持仓 5. 模拟开仓参数(不实际下单) 加 --trade 参数才会真正下一个 0.001 BTC 的小仓位并立即平掉(mainnet 慎用) """ import asyncio import argparse import os import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from app.services.hyperliquid import HyperliquidTrader async def main(do_trade: bool): api_key = os.getenv("HL_API_PRIVATE_KEY") or os.getenv("HL_API_KEY", "") account = os.getenv("HL_ACCOUNT_ADDRESS", "") if not api_key: print("❌ 缺少 HL_API_PRIVATE_KEY 环境变量") print(" export HL_API_PRIVATE_KEY='0x你的API钱包私钥'") sys.exit(1) if not account: print("❌ 缺少 HL_ACCOUNT_ADDRESS 环境变量") print(" export HL_ACCOUNT_ADDRESS='0x你的MetaMask地址'") sys.exit(1) mainnet = os.getenv("HL_MAINNET", "true").lower() != "false" net_label = "MAINNET" if mainnet else "TESTNET" print(f"\n=== Hyperliquid 接入测试 ({net_label}) ===\n") trader = HyperliquidTrader( api_private_key=api_key, account_address=account, leverage=3, mainnet=mainnet, ) # 1. USDC 余额 print("① 查询 USDC 余额...") balance = await trader.get_balance() print(f" 可提取余额: ${balance:.2f} USDC") if balance < 10: print(" ⚠️ 余额不足 $10,交易可能失败") else: print(" ✅ 余额充足") # 2. BTC mid price print("\n② 查询 BTC-PERP 价格...") try: from hyperliquid.info import Info base_url = "https://api.hyperliquid.xyz" if mainnet else "https://api.hyperliquid-testnet.xyz" info = Info(base_url, skip_ws=True) mids = info.all_mids() btc_price = float(mids.get("BTC", 0)) print(f" BTC mid price: ${btc_price:,.2f}") print(" ✅ 价格获取正常") except Exception as e: print(f" ❌ 价格获取失败: {e}") # 3. 当前持仓 print("\n③ 查询当前持仓...") positions = await trader.get_open_positions() if positions: for p in positions: side = "多" if p["szi"] > 0 else "空" print(f" {p['coin']} {side}仓: {abs(p['szi'])} 张 @ 均价 ${p['entry_px']:,.2f} 未实现盈亏: ${p['unrealized_pnl']:.2f}") print(f" 共 {len(positions)} 个持仓") else: print(" 无持仓 ✅") # 4. 模拟开仓参数 print("\n④ 模拟开仓参数(不实际下单)...") sz_dec = await trader._get_sz_decimals("BTC") mid = await trader._mid_price("BTC") size_usd = 100 size_coins = round(size_usd / mid, sz_dec) limit_buy = round(mid * 1.01, 1) print(f" 开多 $100 notional:") print(f" → 数量: {size_coins} BTC") print(f" → 限价(1%滑点): ${limit_buy:,.1f}") print(f" → 杠杆: 3x 隔离保证金") print(f" → 所需保证金: ${size_usd / 3:.2f} USDC") # 5. 真实测试下单(需要 --trade 参数) if do_trade: print(f"\n⑤ 真实下单测试 (0.001 BTC long → 立即平仓)...") if not mainnet: print(" 使用 testnet,无需担心资金损失") else: print(" ⚠️ MAINNET 真实资金!继续中...") try: result = await trader.open_position("BTC", "long", size_usd=50) print(f" ✅ 开仓成功: fill_price=${result['fill_price']:,.2f}, size={result['size_coins']} BTC") await asyncio.sleep(2) close = await trader.close_position("BTC") print(f" ✅ 平仓成功: fill_price=${close['fill_price']:,.2f}") except Exception as e: print(f" ❌ 下单失败: {e}") else: print("\n提示: 加 --trade 参数进行真实下单+平仓测试") print("\n=== 测试完成 ===") if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--trade", action="store_true", help="执行真实下单+平仓测试") args = parser.parse_args() asyncio.run(main(args.trade))