hyperliquid.position

Documentation for eth_defi.hyperliquid.position Python module.

Hyperliquid vault position history reconstruction.

This module provides functionality for reconstructing historical position events (opens, closes, increases, decreases) from Hyperliquid vault fill data.

The Hyperliquid API does not provide a direct position history endpoint, so we must reconstruct position events by processing trade fills chronologically and tracking position state changes.

API Endpoints Used

  • userFillsByTime - Paginated fill history with time range support

  • clearinghouseState - Current open positions (for validation)

Pagination Strategy

The userFillsByTime endpoint has these constraints:

  • Max 2,000 fills per response

  • Only 10,000 most recent fills accessible

  • Time-based pagination using startTime and endTime (milliseconds)

To paginate backwards through history:

  1. Query with desired startTime and endTime

  2. Use the oldest fill’s timestamp - 1ms as the next endTime

  3. Repeat until no more fills or startTime reached

Example:

from datetime import datetime, timedelta
from eth_defi.hyperliquid.session import create_hyperliquid_session
from eth_defi.hyperliquid.position import (
    fetch_vault_fills,
    reconstruct_position_history,
)

session = create_hyperliquid_session()
vault_address = "0x3df9769bbbb335340872f01d8157c779d73c6ed0"

# Fetch fills for the last 30 days (returns an iterator)
start_time = datetime.now() - timedelta(days=30)
fills = fetch_vault_fills(session, vault_address, start_time=start_time)

# Reconstruct position events (also returns an iterator)
for event in reconstruct_position_history(fills):
    print(f"{event.timestamp}: {event.event_type} {event.direction} {event.coin} size={event.size} @ {event.price}")

Module Attributes

MAX_FILLS_PER_REQUEST

Maximum fills returned per API request

MAX_TOTAL_FILLS

Maximum total fills accessible via API

Functions

fetch_vault_fills(session, vault_address[, ...])

Fetch all fills for a vault with automatic pagination.

fetch_vault_fills_iterator(session, ...[, ...])

Iterate over fills for a vault with automatic pagination.

get_position_summary(events)

Generate a summary of position activity from events.

reconstruct_position_history(fills)

Reconstruct position open/close events from fill history.

validate_position_reconstruction(fills)

Validate position reconstruction against API's startPosition field.

Classes

Fill

Parsed fill data from Hyperliquid API.

PositionDirection

Direction of a position.

PositionEvent

Represents a position change event reconstructed from fill data.

PositionEventType

Type of position event.

MAX_FILLS_PER_REQUEST = 2000

Maximum fills returned per API request

MAX_TOTAL_FILLS = 10000

Maximum total fills accessible via API

class PositionEventType

Bases: enum.Enum

Type of position event.

open = 'open'

Opening a new position from flat

close = 'close'

Closing entire position to flat

increase = 'increase'

Increasing position size (same direction)

decrease = 'decrease'

Decreasing position size (same direction)

class PositionDirection

Bases: enum.Enum

Direction of a position.

class PositionEvent

Bases: object

Represents a position change event reconstructed from fill data.

Position events are derived by processing fills chronologically and detecting when positions are opened, closed, increased, or decreased.

event_type: eth_defi.hyperliquid.position.PositionEventType

Type of position event

coin: str

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

direction: eth_defi.hyperliquid.position.PositionDirection

Position direction

size: decimal.Decimal

Size of this fill (always positive)

price: decimal.Decimal

Execution price

timestamp: datetime.datetime

Event timestamp

position_after: decimal.Decimal

Position size after this event (positive = long, negative = short)

realized_pnl: decimal.Decimal | None

Realized PnL for closes/decreases (None for opens/increases)

fill_hash: str | None

Transaction hash

order_id: int | None

Order ID

trade_id: int | None

Trade ID

fee: decimal.Decimal | None

Fee paid

fee_token: str | None

Fee token (e.g., “USDC”)

__init__(event_type, coin, direction, size, price, timestamp, position_after, realized_pnl=None, fill_hash=None, order_id=None, trade_id=None, fee=None, fee_token=None)
Parameters
Return type

None

class Fill

Bases: object

Parsed fill data from Hyperliquid API.

This is an intermediate representation of raw API fill data with proper typing.

coin: str

Asset symbol

side: str

Trade side: “B” (buy) or “A” (sell/ask)

size: decimal.Decimal

Fill size

price: decimal.Decimal

Fill price

timestamp_ms: int

Timestamp in milliseconds

start_position: decimal.Decimal

Position size before this fill

closed_pnl: decimal.Decimal

Closed PnL (for position reductions)

direction_hint: str

Direction hint from API (e.g., “Open Long”, “Close Short”)

hash: str | None

Transaction hash

order_id: int | None

Order ID

trade_id: int | None

Trade ID

fee: decimal.Decimal

Fee paid

fee_token: str

Fee token

classmethod from_api_response(data)

Parse a fill from API response data.

Parameters

data (dict) – Raw fill dict from API

Returns

Parsed Fill object

Return type

eth_defi.hyperliquid.position.Fill

property timestamp: datetime.datetime

Convert millisecond timestamp to datetime.

__init__(coin, side, size, price, timestamp_ms, start_position, closed_pnl, direction_hint, hash, order_id, trade_id, fee, fee_token)
Parameters
Return type

None

fetch_vault_fills(session, vault_address, start_time=None, end_time=None, server_url='https://api.hyperliquid.xyz', timeout=30.0, aggregate_by_time=False)

Fetch all fills for a vault with automatic pagination.

Fetches trade fills from the Hyperliquid API using the userFillsByTime endpoint with automatic pagination to handle API limits.

The fills are yielded in chronological order (oldest first) for position reconstruction.

Note: This function collects all fills before yielding to ensure chronological ordering. For memory-constrained scenarios with very large fill histories, consider using fetch_vault_fills_iterator() which yields fills in API order (not chronological).

Example:

from datetime import datetime, timedelta
from eth_defi.hyperliquid.session import create_hyperliquid_session
from eth_defi.hyperliquid.position import fetch_vault_fills

session = create_hyperliquid_session()
vault = "0x3df9769bbbb335340872f01d8157c779d73c6ed0"

# Fetch last 7 days of fills
fills = list(
    fetch_vault_fills(
        session,
        vault,
        start_time=datetime.now() - timedelta(days=7),
    )
)
print(f"Fetched {len(fills)} fills")
Parameters
  • session (requests.sessions.Session) – HTTP session with retry logic from create_hyperliquid_session()

  • vault_address (eth_typing.evm.HexAddress) – Vault address to fetch fills for

  • start_time (datetime.datetime | None) – Start of time range (inclusive). Defaults to 30 days ago.

  • end_time (datetime.datetime | None) – End of time range (inclusive). Defaults to current time.

  • server_url (str) – Hyperliquid API URL

  • timeout (float) – HTTP request timeout in seconds

  • aggregate_by_time (bool) – When True, partial fills from the same crossing order are combined

Returns

Iterator of fills sorted by timestamp ascending (oldest first)

Raises

requests.HTTPError – If the HTTP request fails after retries

Return type

Iterator[eth_defi.hyperliquid.position.Fill]

fetch_vault_fills_iterator(session, vault_address, start_time=None, end_time=None, server_url='https://api.hyperliquid.xyz', timeout=30.0, aggregate_by_time=False)

Iterate over fills for a vault with automatic pagination.

Memory-efficient version of fetch_vault_fills() that yields fills one at a time instead of loading all into memory.

Note that fills are yielded in API order (newest first per batch), not chronological order. Use fetch_vault_fills() if you need chronological ordering.

Parameters
  • session (requests.sessions.Session) – HTTP session with retry logic

  • vault_address (eth_typing.evm.HexAddress) – Vault address to fetch fills for

  • start_time (datetime.datetime | None) – Start of time range (inclusive)

  • end_time (datetime.datetime | None) – End of time range (inclusive)

  • server_url (str) – Hyperliquid API URL

  • timeout (float) – HTTP request timeout in seconds

  • aggregate_by_time (bool) – When True, partial fills are combined

Returns

Iterator yielding Fill objects

Return type

Iterator[eth_defi.hyperliquid.position.Fill]

reconstruct_position_history(fills)

Reconstruct position open/close events from fill history.

Processes fills chronologically to detect position state changes:

  • Open: New position from flat (size was 0)

  • Close: Position closed to flat (size becomes 0)

  • Increase: Position size increased (same direction)

  • Decrease: Position size decreased (same direction, not to 0)

When a trade flips position direction (e.g., long to short), it generates two events: a close of the old position and an open of the new position.

Example:

from eth_defi.hyperliquid.position import (
    fetch_vault_fills,
    reconstruct_position_history,
)

fills = fetch_vault_fills(session, vault_address)
events = list(reconstruct_position_history(fills))

# Filter for just opens and closes
trades = [
    e
    for e in events
    if e.event_type
    in (
        PositionEventType.open,
        PositionEventType.close,
    )
]

for trade in trades:
    print(f"{trade.timestamp}: {trade.event_type.value} {trade.direction.value} {trade.coin}")
Parameters

fills (Iterable[eth_defi.hyperliquid.position.Fill]) – Iterable of fills sorted by timestamp ascending (oldest first). Use fetch_vault_fills() or fetch_vault_fills_iterator() to obtain this.

Returns

Iterator of position events in chronological order

Return type

Iterator[eth_defi.hyperliquid.position.PositionEvent]

validate_position_reconstruction(fills)

Validate position reconstruction against API’s startPosition field.

The Hyperliquid API includes a startPosition field in each fill showing the position size before that fill. This function validates that our position tracking matches the API’s values.

Parameters

fills (list[eth_defi.hyperliquid.position.Fill]) – List of fills sorted by timestamp ascending

Returns

True if reconstruction matches API data, False otherwise

Return type

bool

get_position_summary(events)

Generate a summary of position activity from events.

Parameters

events (list[eth_defi.hyperliquid.position.PositionEvent]) – List of position events from reconstruct_position_history()

Returns

Dict mapping coin to summary stats

Return type

dict[str, dict]