get_balance
Retrieve account balance details including equity, available margin, margin used, and unrealized PnL from perpetual futures exchanges.
Instructions
Get account balance (equity, available margin, margin used, unrealized PnL) on an exchange
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| exchange | Yes | Exchange name: pacifica, hyperliquid, or lighter |
Implementation Reference
- src/exchanges/hyperliquid.ts:293-339 (handler)Implementation of getBalance in the HyperliquidAdapter. It fetches the clearinghouse state and calculates equity, available balance, margin used, and unrealized PnL.
async getBalance(): Promise<ExchangeBalance> { const state = await this._getClearinghouseState(); const s = state as Record<string, unknown>; const margin = (s?.marginSummary ?? {}) as Record<string, unknown>; const cross = (s?.crossMarginSummary ?? {}) as Record<string, unknown>; const marginUsed = Number(margin.totalMarginUsed ?? cross.totalMarginUsed ?? 0); // Sum unrealized PnL directly from positions (reliable for both main + dex accounts) const positions = (s?.assetPositions ?? []) as Record<string, unknown>[]; let unrealizedPnl = 0; for (const entry of positions) { const pos = (entry.position ?? entry) as Record<string, unknown>; unrealizedPnl += Number(pos.unrealizedPnl ?? 0); } let equity: number; let available: number; if (!this._dex) { // Unified account: spot USDC total IS the true equity (includes perp margin as "hold"). // perp accountValue is a subset — adding both double-counts. try { const spotState = await this._getSpotClearinghouseState(); const balances = (spotState?.balances ?? []) as Record<string, unknown>[]; const usdc = balances.find((b) => String(b.coin).startsWith("USDC")); const spotTotal = usdc?.total !== undefined ? Number(usdc.total) : NaN; const spotHold = Number(usdc?.hold ?? 0); equity = !isNaN(spotTotal) ? spotTotal : Number(margin.accountValue ?? cross.accountValue ?? 0); available = !isNaN(spotTotal) ? spotTotal - spotHold : Number(s?.withdrawable ?? 0); } catch { // Spot API failed — fall back to perp-only values equity = Number(margin.accountValue ?? cross.accountValue ?? 0); available = Number(s?.withdrawable ?? 0); } } else { // Dex account: perp clearinghouse is the only source equity = Number(margin.accountValue ?? cross.accountValue ?? 0); available = Number(s?.withdrawable ?? 0); } return { equity: String(equity), available: String(available), marginUsed: String(marginUsed), unrealizedPnl: String(unrealizedPnl), }; }