Files
ramseshk 526a40b01e Rename VIP→Tier, recalculate equity curve on fee tier change
Renamed all "VIP N" to "Tier N" in config, server, and HTML dropdowns.

Added recalc_equity_curve() that rebuilds the equity curve with new
fee rates. Previously the equity curve was passed through unchanged
when switching tiers, so the chart visually stayed identical even
though PnL numbers changed. Now each tier produces its own curve.

Example OBI historical: Tier 0 equity ends at 141.5, Tier 6 at 149.7 —
the chart visibly shifts up as fees drop from 4.5bp to 2.4bp taker.
2026-08-04 09:12:07 +00:00

92 lines
3.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Hyperliquid fee tiers — perps and spot, base rates + staking discounts.
Source: https://hyperliquid.gitbook.io/hyperliquid-docs/trading/fees
Fee = base_rate × staking_multiplier
Staking tiers are based on staked HYPE tokens.
"""
from dataclasses import dataclass, field
from typing import Optional
# ── Perps fee tiers (base rates) ──
PERPS_TIERS = {
0: {"name": "Tier 0", "volume": 0, "taker": 0.00045, "maker": 0.00015},
1: {"name": "Tier 1", "volume": 5_000_000, "taker": 0.00040, "maker": 0.00012},
2: {"name": "Tier 2", "volume": 25_000_000, "taker": 0.00035, "maker": 0.00008},
3: {"name": "Tier 3", "volume": 100_000_000,"taker": 0.00030, "maker": 0.00004},
4: {"name": "Tier 4", "volume": 500_000_000, "taker": 0.00028, "maker": 0.00000},
5: {"name": "Tier 5", "volume": 2_000_000_000, "taker": 0.00026, "maker": 0.00000},
6: {"name": "Tier 6", "volume": 7_000_000_000, "taker": 0.00024, "maker": 0.00000},
}
# ── Spot fee tiers (base rates) ──
SPOT_TIERS = {
0: {"name": "Tier 0", "volume": 0, "taker": 0.00070, "maker": 0.00040},
1: {"name": "Tier 1", "volume": 100_000, "taker": 0.00060, "maker": 0.00030},
2: {"name": "Tier 2", "volume": 1_000_000, "taker": 0.00050, "maker": 0.00020},
3: {"name": "Tier 3", "volume": 10_000_000, "taker": 0.00040, "maker": 0.00010},
4: {"name": "Tier 4", "volume": 50_000_000, "taker": 0.00030, "maker": 0.00005},
5: {"name": "Tier 5", "volume": 200_000_000, "taker": 0.00020, "maker": 0.00000},
6: {"name": "Tier 6", "volume": 1_000_000_000,"taker":0.00010,"maker": -0.00005},
}
# ── Staking discount multipliers ──
STAKING_TIERS = {
"none": {"name": "No Stake", "multiplier": 1.00},
"wood": {"name": "Wood", "multiplier": 0.95},
"bronze": {"name": "Bronze", "multiplier": 0.90},
"silver": {"name": "Silver", "multiplier": 0.85},
"gold": {"name": "Gold", "multiplier": 0.80},
"platinum": {"name": "Platinum", "multiplier": 0.70},
"diamond": {"name": "Diamond", "multiplier": 0.60},
}
def effective_rate(base_rate: float, staking_tier: str = "none") -> float:
"""Calculate effective fee rate after staking discount."""
mult = STAKING_TIERS.get(staking_tier, STAKING_TIERS["none"])["multiplier"]
return base_rate * mult
def get_perp_fees(vip_tier: int, staking_tier: str = "none", fee_model: str = "taker") -> float:
"""Get effective perp fee for a given VIP tier and staking tier."""
tier = PERPS_TIERS.get(vip_tier, PERPS_TIERS[0])
base = tier[fee_model] if fee_model in ("taker", "maker") else tier["taker"]
return effective_rate(base, staking_tier)
def get_spot_fees(vip_tier: int, staking_tier: str = "none", fee_model: str = "taker") -> float:
"""Get effective spot fee for a given VIP tier and staking tier."""
tier = SPOT_TIERS.get(vip_tier, SPOT_TIERS[0])
base = tier[fee_model] if fee_model in ("taker", "maker") else tier["taker"]
return effective_rate(base, staking_tier)
def fee_tier_from_volume(volume_14d: float, market: str = "perps") -> int:
"""Determine fee tier from 14-day rolling volume."""
tiers = PERPS_TIERS if market == "perps" else SPOT_TIERS
current = 0
for t in sorted(tiers.keys()):
if volume_14d >= tiers[t]["volume"]:
current = t
return current
# ── Strategy-specific defaults (matching existing classification) ──
STRATEGY_FEE_MODELS = {
"Order Book Imbalance": "taker",
"Iceberg Detection": "taker",
"Funding Rate Arb": "taker",
"Pairs Trading": "taker",
"Avellaneda-Stoikov": "maker",
"Momentum Breakout": "taker",
"Mean Reversion": "taker",
"Hawkes OFI": "taker",
"Deep LOB": "maker",
"Cartea-Jaimungal": "maker",
"Queue Imbalance": "taker",
"Guéant Market Making": "maker",
}