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 supportclearinghouseState- 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
startTimeandendTime(milliseconds)
To paginate backwards through history:
Query with desired
startTimeandendTimeUse the oldest fill’s timestamp - 1ms as the next
endTimeRepeat until no more fills or
startTimereached
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
Maximum fills returned per API request |
|
Maximum total fills accessible via API |
Functions
|
Fetch all fills for a vault with automatic pagination. |
|
Iterate over fills for a vault with automatic pagination. |
|
Generate a summary of position activity from events. |
|
Reconstruct position open/close events from fill history. |
Validate position reconstruction against API's startPosition field. |
Classes
Parsed fill data from Hyperliquid API. |
|
Direction of a position. |
|
Represents a position change event reconstructed from fill data. |
|
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.EnumType 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 PositionEvent
Bases:
objectRepresents 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
- 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)
- fee: decimal.Decimal | None
Fee paid
- __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
event_type (eth_defi.hyperliquid.position.PositionEventType) –
coin (str) –
direction (eth_defi.hyperliquid.position.PositionDirection) –
size (decimal.Decimal) –
price (decimal.Decimal) –
timestamp (datetime.datetime) –
position_after (decimal.Decimal) –
realized_pnl (decimal.Decimal | None) –
fill_hash (str | None) –
order_id (int | None) –
trade_id (int | None) –
fee (decimal.Decimal | None) –
fee_token (str | None) –
- Return type
None
- class Fill
Bases:
objectParsed fill data from Hyperliquid API.
This is an intermediate representation of raw API fill data with proper typing.
- size: decimal.Decimal
Fill size
- price: decimal.Decimal
Fill price
- start_position: decimal.Decimal
Position size before this fill
- closed_pnl: decimal.Decimal
Closed PnL (for position reductions)
- fee: decimal.Decimal
Fee paid
- 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
- 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
coin (str) –
side (str) –
size (decimal.Decimal) –
price (decimal.Decimal) –
timestamp_ms (int) –
start_position (decimal.Decimal) –
closed_pnl (decimal.Decimal) –
direction_hint (str) –
hash (str | None) –
order_id (int | None) –
trade_id (int | None) –
fee (decimal.Decimal) –
fee_token (str) –
- 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
userFillsByTimeendpoint 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
- 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
- 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()orfetch_vault_fills_iterator()to obtain this.- Returns
Iterator of position events in chronological order
- Return type
- validate_position_reconstruction(fills)
Validate position reconstruction against API’s startPosition field.
The Hyperliquid API includes a
startPositionfield 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
- 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