HyperliquidDailyMetricsDatabase
Documentation for eth_defi.hyperliquid.daily_metrics.HyperliquidDailyMetricsDatabase Python class.
- class HyperliquidDailyMetricsDatabase
Bases:
eth_defi.hyperliquid.vault_metrics_db.HyperliquidMetricsDatabaseBaseDuckDB database for storing Hyperliquid vault daily metrics.
Inherits shared metadata and lifecycle methods from
HyperliquidMetricsDatabaseBase.Stores daily share price time series and vault metadata. The share prices are computed using time-weighted returns from the Hyperliquid API portfolio history.
Example:
from pathlib import Path from eth_defi.hyperliquid.daily_metrics import HyperliquidDailyMetricsDatabase db = HyperliquidDailyMetricsDatabase(Path("/tmp/metrics.duckdb")) # Query vault data df = db.get_all_daily_prices() print(df) db.close()Attributes summary
price_tableName of the price table (set by subclass).
time_columnName of the time column in the price table (
"date"or"timestamp").Methods summary
__init__(path)close()Close the database connection.
delete_vault_daily_prices(vault_address)Delete all daily price records for a vault.
Detect vaults with anomalous share price data.
fetch_vault_metadata(session, summary, timeout)Fetch vault details and persist permission evidence before price checks.
Get all daily price data across all vaults.
Return all vault addresses that have any price data.
Get metadata for all vaults.
get_existing_dates(vault_address)Get all dates with existing data for a vault.
Get the latest leader_fraction for each vault.
get_leader_fraction_history(vault_address)Get the recorded leader_fraction snapshots for a vault.
Read independent permissions, including explicit unknown responses.
get_recently_tracked_addresses([within_days])Return vault addresses with price data within the last within_days days.
Get the number of unique vaults with price data.
get_vault_daily_price_count(vault_address)Get the number of daily price records for a vault.
get_vault_daily_prices(vault_address)Get daily price data for a specific vault.
get_vault_last_date(vault_address)Get the last date with price data for a vault.
mark_vaults_disappeared(known_addresses)Set TVL to zero for vaults that disappeared from the API.
Recompute share prices for all vaults in the database.
recompute_vault_share_prices(vault_address)Recompute share prices for a vault from stored tvl/pnl data.
record_bulk_closures(summaries, received_at)Record explicit bulk-list closures even for filtered-out drained vaults.
record_permission(vault, info)Persist a successful coherent response before any price processing.
record_permission_error(vault_address, error)Record failed fetch/parse attempts separately from successful unknowns.
save()Flush pending writes to disk.
tombstone_stale_vaults(known_api_addresses)Write tombstone rows for vaults whose wind-down window has expired.
update_historical_daily_flows(vault_address, ...)Backfill ledger flows on existing historical price observations.
update_vault_tvl_bulk(updates)Bulk-update TVL and APR without mixing permission source responses.
upsert_daily_prices(rows[, cutoff_date])Bulk upsert daily price rows for a vault.
upsert_price_batch(rows, columns)Apply a deduplicated staging batch using hash joins, without ART indexes.
upsert_vault_metadata(vault_address, name, ...)Insert or update a vault's metadata.
- __init__(path)
- Parameters
path (pathlib.Path) –
- Return type
None
- upsert_daily_prices(rows, cutoff_date=None)
Bulk upsert daily price rows for a vault.
- Parameters
rows (list[eth_defi.hyperliquid.daily_metrics.HyperliquidDailyPriceRow]) –
List of
HyperliquidDailyPriceRowitems.Permission compatibility fields on new rows may accompany the latest source price. They never replace independent response observations, and matching-key updates preserve their original values and clock.
The flow columns (
daily_deposit_countetc.) should beNonefor dates outside the backfill window and0for dates with no activity within the backfill window.COALESCEpreserves existing values whenNoneis passed.cutoff_date (Optional[datetime.date]) – If provided, only store rows up to this date (inclusive). Used for incremental scanning / testing.
- Return type
None
- get_all_daily_prices()
Get all daily price data across all vaults.
- Returns
DataFrame with all daily price records, ordered by vault then date.
- Return type
- get_vault_daily_prices(vault_address)
Get daily price data for a specific vault.
- Parameters
vault_address (eth_typing.evm.HexAddress) – Vault address to query.
- Returns
DataFrame with price records for this vault, ordered by date.
- Return type
- update_historical_daily_flows(vault_address, daily_flows, start_date, end_date)
Backfill ledger flows on existing historical price observations.
A normal scan can only attach flow data to portfolio observations that Hyperliquid still returns. Because the API downsamples old portfolio history, an old daily price row may remain in DuckDB even though a new
vaultDetailsresponse no longer contains that date. This method updates those existing rows directly from separately fetcheduserNonFundingLedgerUpdatesdata. Dates without a ledger event are explicitly stored as zero, which distinguishes a proven zero-flow day from an unknown historical day.Existing price, NAV, PnL, and metadata values are never changed. The update is intentionally allowed to replace an old zero withdrawal, because older parser versions read Hyperliquid’s zero-valued
usdcplaceholder instead ofnetWithdrawnUsd.- Parameters
vault_address (eth_typing.evm.HexAddress) – Lowercase or checksummed Hyperliquid vault address.
daily_flows (dict[datetime.date, tuple[int, int, float, float]]) – Ledger events aggregated by UTC date as
(deposit_count, withdrawal_count, deposit_usd, withdrawal_usd).start_date (datetime.date) – First existing daily observation to backfill, inclusive.
end_date (datetime.date) – Last existing daily observation to backfill, inclusive.
- Returns
Number of existing daily price rows updated.
- Return type
- get_existing_dates(vault_address)
Get all dates with existing data for a vault.
- Parameters
vault_address (eth_typing.evm.HexAddress) – Vault address to query.
- Returns
Set of dates that already have data in the database.
- Return type
- get_vault_daily_price_count(vault_address)
Get the number of daily price records for a vault.
- Parameters
vault_address (eth_typing.evm.HexAddress) – Vault address to query.
- Returns
Number of daily price records.
- Return type
- get_vault_last_date(vault_address)
Get the last date with price data for a vault.
- Parameters
vault_address (eth_typing.evm.HexAddress) – Vault address to query.
- Returns
The latest date, or None if no data.
- Return type
- get_leader_fraction_history(vault_address)
Get the recorded leader_fraction snapshots for a vault.
Returns only rows where
leader_fractionwas recorded (non-NULL). These are compatibility values attached to portfolio dates; they are not independent observations and cannot establish fresh capacity. Use the permission sidecar’scapacity_observed_atand coherent source inputs when checking the age of a leader-capital measurement.- Parameters
vault_address (eth_typing.evm.HexAddress) – Vault address to query (will be lowercased).
- Returns
DataFrame with columns
dateandleader_fraction, ordered by date ascending. Empty if no snapshots recorded.- Return type
- delete_vault_daily_prices(vault_address)
Delete all daily price records for a vault.
Used by the healing script to clear corrupted share prices before re-computing from fresh API data.
- Parameters
vault_address (eth_typing.evm.HexAddress) – Vault address to delete.
- Returns
Number of rows deleted.
- Return type
- recompute_vault_share_prices(vault_address)
Recompute share prices for a vault from stored tvl/pnl data.
Uses the stored
tvl(total_assets),daily_pnl(pnl_update), andcumulative_pnlcolumns to reconstructnetflow_update, then feeds the data through_calculate_share_price()with the current chain-linked epoch reset logic.This allows healing of share price data without re-fetching from the Hyperliquid API.
- Parameters
vault_address (eth_typing.evm.HexAddress) – Vault address to recompute.
- Returns
Dict with before/after statistics:
{"rows": int, "old_sp_min": float, "old_sp_max": float, "new_sp_min": float, "new_sp_max": float, "epoch_resets": int, "changed_rows": int}- Return type
- recompute_all_share_prices()
Recompute share prices for all vaults in the database.
Iterates over every vault and calls
recompute_vault_share_prices()for each.- Returns
Summary dict:
{"total_vaults": int, "vaults_with_changes": int, "vaults_with_epoch_resets": int, "total_changed_rows": int, "per_vault": dict[str, dict]}- Return type
- detect_broken_vaults()
Detect vaults with anomalous share price data.
Checks for four classes of breakage:
Extreme daily returns (> 10,000%): typically epoch reset artefacts where share price jumped to/from 1.0
Share price at cap (>= 9,999): overflow from zero total_supply
Share price stuck at 1.0: share price identical for 5+ rows, suggesting failed epoch reset logic
Missing epoch_reset column: rows computed with old code that lacked the
epoch_resetcolumn (all NULL)
- Returns
DataFrame with columns:
vault_address,name,issue_type,affected_rows,example_value- Return type
- close()
Close the database connection.
- Return type
None
- fetch_vault_metadata(session, summary, timeout)
Fetch vault details and persist permission evidence before price checks.
Both collectors use this path so failed parsing still retains a successful response receipt. Database failures propagate instead of being treated as a retryable provider failure. See the Hyperliquid info endpoint.
- Parameters
session (eth_defi.hyperliquid.session.HyperliquidSession) – Rate-limited API session.
summary (eth_defi.hyperliquid.vault.VaultSummary) – Vault selected from the bulk catalogue.
timeout (float) – HTTP request timeout in seconds.
- Returns
Parsed metadata, or
Noneafter a recorded fetch/parse failure.- Return type
- get_all_tracked_addresses()
Return all vault addresses that have any price data.
- get_all_vault_metadata()
Get metadata for all vaults.
- Returns
DataFrame with one row per vault.
- Return type
- get_latest_leader_fractions()
Get the latest leader_fraction for each vault.
Reads the latest genuine permission snapshot per vault. If that response omits leader share, the previous value is not carried forwards. Inferred legacy snapshots are available in historical price exports instead. This catalogue lookup does not certify freshness; missing timing metadata does not invalidate a recorded historical share or policy cap.
- Returns
Dict mapping lowercased vault address to leader_fraction.
- Return type
- get_permission_observations()
Read independent permissions, including explicit unknown responses.
New source responses retain their receipt clock. Recovered legacy records are separately labelled when the price clock is inferred.
- Returns
Observation and uncertainty-boundary frame.
- Return type
- get_recently_tracked_addresses(within_days=4)
Return vault addresses with price data within the last within_days days.
Uses a pure date cutoff so that whole-day semantics are preserved for the daily table (DATE column) and behave identically for the HF table (TIMESTAMP column — DuckDB casts DATE to midnight).
- get_vault_count()
Get the number of unique vaults with price data.
- Return type
- mark_vaults_disappeared(known_addresses)
Set TVL to zero for vaults that disappeared from the API.
Also writes tombstone price rows so downstream consumers see a fresh row reflecting removal.
- Parameters
known_addresses (set[eth_typing.evm.HexAddress]) – Lowercased vault addresses currently present in the bulk API.
- Return type
None
- record_bulk_closures(summaries, received_at)
Record explicit bulk-list closures even for filtered-out drained vaults.
Only
isClosed=truesupplies deny evidence. Bulk open/missing flags cannot establish permission or inferallowDeposits. Each record is a coherent partial source response with its own availability clock. Repeated identical bulk denials do not refresh this clock; append again after a later genuine response changes or clears the recorded closure.- Parameters
summaries (list[eth_defi.hyperliquid.vault.VaultSummary]) – Newly fetched stats-data vault summaries.
received_at (datetime.datetime) – Immediate UTC receipt bound after bulk fetch.
- Returns
None.- Return type
None
- record_permission(vault, info)
Persist a successful coherent response before any price processing.
Unknown flags are observations too and supersede previously known flags.
- Parameters
vault (eth_defi.hyperliquid.vault.HyperliquidVault) – Client retaining the raw response receipt.
info (Optional[eth_defi.hyperliquid.vault.VaultInfo]) – Parsed source response.
- Returns
None.- Return type
None
- record_permission_error(vault_address, error)
Record failed fetch/parse attempts separately from successful unknowns.
A failed HTTP request does not supersede an earlier known permission.
- Parameters
vault_address (eth_typing.evm.HexAddress) – Attempted vault address.
error (BaseException) – Fetch or response parsing failure, stored by type only.
- Returns
None.- Return type
None
- save()
Flush pending writes to disk.
- Return type
None
- tombstone_stale_vaults(known_api_addresses, wind_down_days=4)
Write tombstone rows for vaults whose wind-down window has expired.
A vault is eligible for tombstoning when:
It has existing price data in the database
It is NOT present in the current bulk API listing
Its most recent price row is older than
wind_down_daysIt does not already have a tombstone row
The tombstone carries forward the last known share_price and cumulative_pnl so return calculations are not distorted.
- update_vault_tvl_bulk(updates)
Bulk-update TVL and APR without mixing permission source responses.
Only updates rows that already exist in
vault_metadata.
- upsert_price_batch(rows, columns)
Apply a deduplicated staging batch using hash joins, without ART indexes.
Permission fields in prices are compatibility fields only. Price-only updates preserve the original write clock and cannot refresh permissions. Existing constrained databases require the backed-up recovery migration.
- upsert_vault_metadata(vault_address, name, leader, description, is_closed, relationship_type, create_time, commission_rate, follower_count, tvl, apr, allow_deposits=None, flow_data_earliest_date=None)
Insert or update a vault’s metadata.
- Parameters
vault_address (eth_typing.evm.HexAddress) – Vault address (will be lowercased).
flow_data_earliest_date (Optional[datetime.date]) – Earliest date for which daily deposit/withdrawal flow data has been backfilled.
Nonemeans no flow data yet.name (str) –
leader (eth_typing.evm.HexAddress) –
relationship_type (str) –
create_time (Optional[datetime.datetime]) –
- Return type
None