hyperliquid.trade_history

Documentation for eth_defi.hyperliquid.trade_history Python module.

Hyperliquid account trade history reconstruction.

Reconstructs historical closed positions, open positions, and round-trip trades for any Hyperliquid account (vaults or normal addresses) by combining:

  • Fill history from userFillsByTime

  • Funding payments from userFunding

  • Current positions from clearinghouseState

The module groups individual fills into round-trip trades (open→close) with VWAP entry/exit prices, funding costs, and realised PnL.

API endpoints used

  • userFillsByTime — paginated fill history (max 10K fills accessible)

  • userFunding — paginated funding payment history

  • clearinghouseState — current open positions with unrealised PnL

Example:

from eth_defi.hyperliquid.session import create_hyperliquid_session
from eth_defi.hyperliquid.trade_history import fetch_account_trade_history

session = create_hyperliquid_session()
address = "0x1e37a337ed460039d1b15bd3bc489de789768d5e"

history = fetch_account_trade_history(session, address)

print(f"Open trades: {len(history.open_trades)}")
print(f"Closed trades: {len(history.closed_trades)}")
for trade in history.closed_trades[:5]:
    print(f"  {trade.coin} {trade.direction.value}: PnL={trade.net_pnl:.2f}")

Module Attributes

MAX_FUNDING_PER_REQUEST

Maximum funding payments returned per API request

Functions

attach_funding_to_trades(closed_trades, ...)

Attach funding payments to the appropriate round-trip trades.

compute_event_share_prices(fills, ...[, ...])

Compute event-accurate share prices from actual ledger events.

create_share_price_dataframe(events)

Convert share price events to a pandas DataFrame.

create_trade_summary_dataframe(trades)

Convert round-trip trades to a pandas DataFrame for tabular display.

fetch_account_funding(session, address[, ...])

Fetch all funding payments for an account with automatic pagination.

fetch_account_trade_history(session, address)

Fetch and reconstruct complete trade history for a Hyperliquid account.

group_fills_into_trades(events[, fills])

Group position events into round-trip trades.

Classes

AccountTradeHistory

Complete trade history snapshot for a Hyperliquid account.

FundingPayment

A single funding payment from the Hyperliquid userFunding endpoint.

RoundTripTrade

A round-trip trade from position open through close.

SharePriceEvent

A single event in the share price time series.

MAX_FUNDING_PER_REQUEST = 500

Maximum funding payments returned per API request

class FundingPayment

Bases: object

A single funding payment from the Hyperliquid userFunding endpoint.

Funding is paid/received periodically (typically hourly) for open perpetual positions. Negative USDC means funding was paid by the holder; positive means funding was received.

coin: str

Asset symbol (e.g., “BTC”, “ETH”)

funding_rate: decimal.Decimal

Funding rate applied

usdc: decimal.Decimal

USD amount (negative = paid, positive = received)

position_size: decimal.Decimal

Position size at the time of the funding event

timestamp: datetime.datetime

Funding event timestamp

timestamp_ms: int

Timestamp in milliseconds (for storage)

hash: str | None

Transaction hash

n_samples: int

Number of samples aggregated

classmethod from_api_response(data)

Parse a funding payment from API response data.

The userFunding API returns entries with a delta sub-object containing the actual funding fields (coin, usdc, szi, fundingRate).

Parameters

data (dict) – Raw funding dict from userFunding API response.

Returns

Parsed FundingPayment object.

Return type

eth_defi.hyperliquid.trade_history.FundingPayment

__init__(coin, funding_rate, usdc, position_size, timestamp, timestamp_ms, hash=None, n_samples=1)
Parameters
Return type

None

class RoundTripTrade

Bases: object

A round-trip trade from position open through close.

Groups individual fills from position-open to position-close with volume-weighted average entry/exit prices, funding costs, and PnL.

For positions that were already open before the data window, is_complete is False and entry_price may be unknown.

coin: str

Asset symbol (e.g., “BTC”, “ETH”)

direction: eth_defi.hyperliquid.position.PositionDirection

Trade direction

is_open: bool

Whether the position is still open

is_complete: bool

Whether we have the full open→close lifecycle (False when position was already open before data window)

opened_at: datetime.datetime

Timestamp when the position was first opened (or earliest known fill)

closed_at: datetime.datetime | None

Timestamp when the position was closed (None if still open)

entry_price: decimal.Decimal

Volume-weighted average entry price

exit_price: decimal.Decimal | None

Volume-weighted average exit price (None if still open or no exits)

max_size: decimal.Decimal

Maximum position size reached during the trade

current_size: decimal.Decimal

Current position size (0 if closed)

realised_pnl: decimal.Decimal

Realised PnL from fills (sum of closed_pnl)

funding_pnl: decimal.Decimal

Total funding payments during this trade

total_fees: decimal.Decimal

Total fees paid across all fills

net_pnl: decimal.Decimal

Net PnL (realised_pnl + funding_pnl - total_fees)

unrealised_pnl: decimal.Decimal | None

Unrealised PnL from clearinghouse state (open trades only)

fills: list[eth_defi.hyperliquid.position.Fill]

All fills belonging to this trade

funding_payments: list[eth_defi.hyperliquid.trade_history.FundingPayment]

All funding payments during this trade’s lifetime

duration: datetime.timedelta | None

Duration of the trade

fill_count: int

Number of fills

__init__(coin, direction, is_open, is_complete, opened_at, closed_at, entry_price, exit_price, max_size, current_size, realised_pnl, funding_pnl, total_fees, net_pnl, unrealised_pnl, fills=<factory>, funding_payments=<factory>, duration=None, fill_count=0, _entry_cost=Decimal('0'), _entry_size=Decimal('0'), _exit_cost=Decimal('0'), _exit_size=Decimal('0'))
Parameters
Return type

None

class AccountTradeHistory

Bases: object

Complete trade history snapshot for a Hyperliquid account.

Combines current open positions, historical closed trades, open trades, all fills, and funding payments into a single result.

address: eth_typing.evm.HexAddress

Account address (vault or user)

snapshot_time: datetime.datetime

Timestamp when this snapshot was taken

open_positions: list[eth_defi.hyperliquid.api.AssetPosition]

Current open positions from clearinghouse state

closed_trades: list[eth_defi.hyperliquid.trade_history.RoundTripTrade]

Historical closed round-trip trades

open_trades: list[eth_defi.hyperliquid.trade_history.RoundTripTrade]

Currently open round-trip trades

fills: list[eth_defi.hyperliquid.position.Fill]

All individual fills in the time range

funding_payments: list[eth_defi.hyperliquid.trade_history.FundingPayment]

All funding payments in the time range

margin_summary: eth_defi.hyperliquid.api.MarginSummary

Perp account margin summary

start_time: datetime.datetime

Time range start

end_time: datetime.datetime

Time range end

fills_truncated: bool

Whether the fill history was truncated by the 10K API limit

__init__(address, snapshot_time, open_positions, closed_trades, open_trades, fills, funding_payments, margin_summary, start_time, end_time, fills_truncated)
Parameters
Return type

None

fetch_account_funding(session, address, start_time=None, end_time=None, timeout=30.0)

Fetch all funding payments for an account with automatic pagination.

Fetches funding payment history from the Hyperliquid API using the userFunding endpoint with automatic forward pagination.

Payments are yielded in chronological order (oldest first).

Example:

from datetime import datetime, timedelta
from eth_defi.hyperliquid.session import create_hyperliquid_session
from eth_defi.hyperliquid.trade_history import fetch_account_funding

session = create_hyperliquid_session()
address = "0x1e37a337ed460039d1b15bd3bc489de789768d5e"

payments = list(
    fetch_account_funding(
        session,
        address,
        start_time=datetime.now() - timedelta(days=7),
    )
)
print(f"Fetched {len(payments)} funding payments")
Parameters
Returns

Iterator of funding payments sorted by timestamp ascending (oldest first).

Raises

requests.HTTPError – If the HTTP request fails after retries.

Return type

Iterator[eth_defi.hyperliquid.trade_history.FundingPayment]

group_fills_into_trades(events, fills=None)

Group position events into round-trip trades.

Processes position events chronologically and groups them into round-trip trades. Each trade tracks a position from open to close (or to the current state if still open).

When a position was already open before the data window (i.e. the earliest fill has a non-zero start_position), the trade is marked as is_complete=False.

Parameters
Returns

Tuple of (closed_trades, open_trades).

Return type

tuple[list[eth_defi.hyperliquid.trade_history.RoundTripTrade], list[eth_defi.hyperliquid.trade_history.RoundTripTrade]]

attach_funding_to_trades(closed_trades, open_trades, funding_payments)

Attach funding payments to the appropriate round-trip trades.

For each funding payment, finds the trade for that coin active at the payment timestamp and attributes the funding cost/income to it.

Modifies trades in place.

Parameters
Return type

None

fetch_account_trade_history(session, address, start_time=None, end_time=None, timeout=30.0)

Fetch and reconstruct complete trade history for a Hyperliquid account.

Orchestrates fetching fills, funding payments, and current positions, then reconstructs round-trip trades with full PnL accounting.

Example:

from eth_defi.hyperliquid.session import create_hyperliquid_session
from eth_defi.hyperliquid.trade_history import fetch_account_trade_history

session = create_hyperliquid_session()
address = "0x1e37a337ed460039d1b15bd3bc489de789768d5e"

history = fetch_account_trade_history(session, address)

for trade in history.closed_trades:
    print(f"{trade.coin} {trade.direction.value}: entry={trade.entry_price} exit={trade.exit_price} PnL={trade.net_pnl}")
Parameters
Returns

Complete trade history snapshot.

Return type

eth_defi.hyperliquid.trade_history.AccountTradeHistory

create_trade_summary_dataframe(trades)

Convert round-trip trades to a pandas DataFrame for tabular display.

Parameters

trades (list[eth_defi.hyperliquid.trade_history.RoundTripTrade]) – List of round-trip trades from fetch_account_trade_history().

Returns

DataFrame with one row per trade.

Return type

pandas.DataFrame

class SharePriceEvent

Bases: object

A single event in the share price time series.

Each event represents a state change that affects the vault’s share price: a deposit, withdrawal, trading PnL, or funding payment.

timestamp: datetime.datetime

Event timestamp

event_type: str

Type of event: “deposit”, “withdraw”, “fill_pnl”, “funding”

total_assets: float

Total assets (NAV) after this event

total_supply: float

Total supply of shares after this event

share_price: float

Share price after this event

delta: float

Change in assets from this event

epoch_reset: bool

Whether an epoch reset occurred

coin: str | None

Coin involved (for fill_pnl and funding events)

__init__(timestamp, event_type, total_assets, total_supply, share_price, delta, epoch_reset=False, coin=None)
Parameters
Return type

None

compute_event_share_prices(fills, funding_payments, ledger_events, initial_total_assets=0.0)

Compute event-accurate share prices from actual ledger events.

Unlike the portfolio-history-derived share prices (which suffer from resolution artefacts — see README-hyperliquid-vault-limitations.md), this function uses actual event data:

  • Deposits: Exact amounts from userNonFundingLedgerUpdates

  • Withdrawals: Exact amounts from userNonFundingLedgerUpdates

  • Trading PnL: Realised PnL from individual fills (closed_pnl)

  • Funding payments: USD amounts from userFunding

This eliminates the resolution-dependent netflow derivation that causes share price spikes in the current pipeline.

The share price model follows ERC-4626 mechanics:

  • share_price = total_assets / total_supply

  • Deposits mint shares: shares_minted = deposit_amount / share_price

  • Withdrawals burn shares: shares_burned = withdrawal_amount / share_price

  • PnL and funding change total_assets but not total_supply

  • Share price starts at 1.00 at first deposit

Parameters
Returns

List of SharePriceEvent objects in chronological order.

Return type

list[eth_defi.hyperliquid.trade_history.SharePriceEvent]

create_share_price_dataframe(events)

Convert share price events to a pandas DataFrame.

Parameters

events (list[eth_defi.hyperliquid.trade_history.SharePriceEvent]) – List of SharePriceEvent from compute_event_share_prices().

Returns

DataFrame with timestamp index and columns for total_assets, total_supply, share_price, event_type, delta, epoch_reset.

Return type

pandas.DataFrame