slippage-budget-enforcement
Use when executing any taker (Ioc or market) order on HyperLiquid to calculate the maximum allowable slippage budget, enforce price tolerance before submission, detect post-fill slippage violations, and abort or resize orders that would exceed the session slippage cap.
- License 许可
- GPL-3.0
- 最近更新
- 2026-07-02
- Stars
- ★ 1
- Forks
- 0
01 前言 Front Matter
- name
- slippage-budget-enforcement
- category
- agentic
- description
- Use when executing any taker (Ioc or market) order on HyperLiquid to calculate the maximum allowable slippage budget, enforce price tolerance before submission, detect post-fill slippage violations, and abort or resize orders that would exceed the session slippage cap.
03 SKILL.md 正文
Slippage Budget Enforcement
When This Skill Activates
Apply this skill on every taker order (tif: "Ioc" or market) before
submission and again after fill confirmation. Also apply when:
- A maker (
Alo) order has been rejected and taker execution is being considered as fallback - A cascade exit or kill-switch triggers a market order and a worst-case slippage estimate is needed for position sizing the exit
- Session-level slippage has accumulated and a new taker order would breach the session cap
- Book depth has thinned significantly and the expected fill price for a given size must be estimated before committing
Core Principle
Slippage on taker orders is not random noise — it is a predictable function of order size relative to available book depth. Large taker orders walk the book, consuming successive price levels and filling at proggressively worse prices. On HyperLiquid’s thin-book perp markets, a $50k market order in low-liquidity conditions can incur 10–20 bps of slippage — equivalent to paying taker fee twice.
Rule: Before submitting any taker order, simulate the fill by walking the live order book. If the simulated slippage exceeds the order’s slippage budget, either reduce order size or abort. Never submit a taker order blind.
Slippage Budget Framework
Per-Order Slippage Budget
The per-order slippage budget is derived from the trade’s expected edge
minus the taker fee already accounted for in maker-order-preference-fee-reduction:
def per_order_slippage_budget_bps(
expected_move_bps: float, # from strategy signal
taker_fee_bps: float = 3.5, # base tier: 0.035% = 3.5 bps
min_net_edge_bps: float = 2.0, # minimum edge to keep after all costs
) -> float:
"""
Maximum slippage that still leaves a minimum net edge after
taker fee and slippage are both deducted.
"""
budget = expected_move_bps - taker_fee_bps - min_net_edge_bps
return max(0.0, budget) # 0.0 = no slippage tolerance; do not trade
# Example: expected move = 15 bps, taker fee = 3.5 bps, min edge = 2 bps
# slippage_budget = 15 - 3.5 - 2.0 = 9.5 bps
#
# Example: expected move = 8 bps
# slippage_budget = 8 - 3.5 - 2.0 = 2.5 bps (very tight; consider maker entry)
#
# Example: expected move = 5 bps
# slippage_budget = 5 - 3.5 - 2.0 = -0.5 → clamped to 0.0
# → Do not use taker. Taker fee alone consumes more than expected move minus min edge.
Session Slippage Cap
Beyond per-order budgets, enforce a hard session-level slippage cap to prevent cumulative slippage from silently eroding P&L:
SESSION_SLIPPAGE_CAP_BPS = 20.0 # total across all taker fills in session
SESSION_SLIPPAGE_WARN_BPS = 15.0 # warning threshold: reduce taker aggression
# Session tracking (in-memory; reset at session start):
class SlippageTracker:
def __init__(self):
self.session_slippage_bps: float = 0.0
self.taker_fills: list = []
def record_fill(self, expected_price: float, fill_price: float,
side: str, notional_usd: float) -> float:
if side == "buy":
slippage_bps = (fill_price - expected_price) / expected_price * 10000
else:
slippage_bps = (expected_price - fill_price) / expected_price * 10000
slippage_bps = max(0.0, slippage_bps) # only count adverse slippage
self.session_slippage_bps += slippage_bps
self.taker_fills.append({
"expected_price": expected_price,
"fill_price": fill_price,
"slippage_bps": slippage_bps,
"notional_usd": notional_usd,
})
return slippage_bps
def can_place_taker(self, estimated_slippage_bps: float) -> tuple[bool, str]:
projected = self.session_slippage_bps + estimated_slippage_bps
if projected >= SESSION_SLIPPAGE_CAP_BPS:
return False, "session_cap_breached"
if self.session_slippage_bps >= SESSION_SLIPPAGE_WARN_BPS:
return True, "warning_reduce_size"
return True, "ok"
Book Walk Simulation
Before submitting any taker order, simulate the fill by walking the
live l2Book to estimate expected fill price and slippage:
def simulate_taker_fill(
l2book: dict,
side: str, # "buy" consumes asks; "sell" consumes bids
order_size_usd: float,
mid_price: float,
) -> dict:
"""
Walk the order book to estimate average fill price and slippage
for a taker order of order_size_usd notional.
Returns fill estimate with slippage_bps and fill_coverage_pct.
"""
levels = l2book["levels"][1] if side == "buy" else l2book["levels"][0]
# levels format: [{"px": price_str, "sz": size_str, "n": num_orders}, ...]
# buy: walk asks ascending; sell: walk bids descending
remaining_usd = order_size_usd
total_cost = 0.0
total_filled = 0.0
for level in levels:
level_px = float(level["px"])
level_sz = float(level["sz"]) # size in base asset
level_usd = level_sz * level_px
fill_usd = min(remaining_usd, level_usd)
fill_sz = fill_usd / level_px
total_cost += fill_sz * level_px
total_filled += fill_sz
remaining_usd -= fill_usd
if remaining_usd <= 0:
break
if total_filled == 0:
return {"feasible": False, "reason": "no_book_depth"}
avg_fill_price = total_cost / total_filled
fill_coverage = (order_size_usd - remaining_usd) / order_size_usd
if side == "buy":
slippage_bps = (avg_fill_price - mid_price) / mid_price * 10000
else:
slippage_bps = (mid_price - avg_fill_price) / mid_price * 10000
return {
"feasible": fill_coverage >= 0.95, # require 95% fill or reject
"avg_fill_price": avg_fill_price,
"slippage_bps": max(0.0, slippage_bps),
"fill_coverage_pct": fill_coverage * 100,
"unfilled_usd": remaining_usd,
"levels_consumed": sum(1 for _ in levels), # approximate
}
Interpreting Book Walk Results
| Result | Condition | Action |
|---|---|---|
feasible: True, slippage ≤ budget |
Full fill, within budget | Submit order as sized |
feasible: True, slippage > budget |
Full fill but too costly | Reduce size until slippage ≤ budget |
feasible: False, coverage < 95% |
Insufficient depth | Reduce size to available depth × 0.80 |
feasible: False, no depth |
Book empty / extreme cascade | Abort. Use liquidation-cascade-risk protocol |
Size Reduction to Meet Slippage Budget
When the simulated slippage exceeds budget, binary-search for the maximum order size that stays within budget:
def max_size_within_budget(
l2book: dict,
side: str,
mid_price: float,
slippage_budget_bps: float,
initial_size_usd: float,
min_size_usd: float = 100.0,
) -> float:
"""
Binary search for largest order size whose simulated slippage
is <= slippage_budget_bps. Returns 0.0 if min_size_usd also exceeds budget.
"""
lo, hi = min_size_usd, initial_size_usd
for _ in range(12): # 12 iterations -> 0.02% precision
mid_size = (lo + hi) / 2
result = simulate_taker_fill(l2book, side, mid_size, mid_price)
if not result["feasible"] or result["slippage_bps"] > slippage_budget_bps:
hi = mid_size
else:
lo = mid_size
# Final check at lo:
result = simulate_taker_fill(l2book, side, lo, mid_price)
if not result["feasible"] or result["slippage_bps"] > slippage_budget_bps:
return 0.0 # even minimum size exceeds budget; abort
return lo
Pre-Submission Enforcement Checklist
Run this checklist in order before every taker order submission:
1. Compute per-order slippage budget:
budget_bps = per_order_slippage_budget_bps(expected_move_bps)
└── budget_bps == 0.0? → ABORT. Taker fee alone kills the edge.
2. Check session cap:
can_place, status = tracker.can_place_taker(estimated_slippage_bps)
├── can_place == False → ABORT. Session slippage cap reached.
└── status == "warning_reduce_size" → Halve order size before continuing.
3. Simulate book walk:
sim = simulate_taker_fill(l2book, side, order_size_usd, mid_price)
├── sim.feasible == False → Reduce size per depth or ABORT.
└── sim.slippage_bps > budget_bps → Run max_size_within_budget().
├── adjusted_size > 0 → Continue at adjusted size.
└── adjusted_size == 0 → ABORT.
4. Submit order at adjusted_size with price_tolerance:
worst_acceptable_price = mid_price ± (budget_bps / 10000 * mid_price)
# Use this as the limit price on an Ioc order to cap worst-case fill:
# {"t": {"limit": {"tif": "Ioc"}}, "p": worst_acceptable_price, ...}
# Do NOT use pure market orders unless cascade/kill-switch override.
5. Post-fill: record actual slippage via tracker.record_fill()
└── actual_slippage_bps > budget_bps? → Log violation. Flag for review.
Defensive Override: Cascade and Kill-Switch Exits
When a CRITICAL cascade exit or kill-switch fires, the slippage budget framework is suspended — fill certainty takes absolute priority over cost:
def submit_defensive_exit(
side: str,
size_usd: float,
mid_price: float,
reason: str, # "cascade_critical", "kill_switch", "stop_breach"
) -> dict:
# No budget check. No book walk. Submit market order immediately.
order = {
"orders": [{
"a": asset_index,
"b": side == "buy",
"p": "0", # market order price field (ignored)
"s": str(size_base_asset),
"r": True, # reduce-only
"t": {"market": {}}
}],
"grouping": "na"
}
# Log defensive override for RL replay buffer:
log_event({
"event": "defensive_exit",
"reason": reason,
"size_usd": size_usd,
"slippage_budget_suspended": True,
"estimated_slippage_bps": simulate_taker_fill(
l2book, side, size_usd, mid_price
).get("slippage_bps", "unknown"),
})
return order
Log the estimated slippage even on defensive exits so the RL replay buffer learns the true cost of cascade conditions and can incorporate that into future position-sizing decisions.
Slippage by Asset and Condition Reference
Typical observed slippage ranges on HyperLiquid for a $10k taker order under different book conditions (verify from live fills):
| Asset | Normal Book | Thin Book | During Cascade |
|---|---|---|---|
| BTC | 0.2–0.5 bps | 1–3 bps | 5–20 bps |
| ETH | 0.3–0.8 bps | 1.5–4 bps | 8–25 bps |
| SOL | 0.5–1.5 bps | 3–8 bps | 15–40 bps |
| Mid-cap alts | 1–3 bps | 5–15 bps | 20–100+ bps |
These are illustrative estimates, not guarantees. Always use the live book walk simulation for actual order sizing. Slippage during cascades can exceed these ranges significantly.
Failure Modes to Avoid
- Submitting market orders without book walk: Market orders on thin books can fill 10–50 bps worse than expected. Even for defensive exits, estimate the slippage and log it — the data informs future sizing.
- Setting slippage tolerance as a fixed percentage: A fixed 0.1% tolerance ignores current book depth, asset liquidity, and order size. Slippage tolerance must be computed per-order from the budget framework.
- Reusing a stale book walk result: The l2Book snapshot used for simulation must be fetched at submission time, not cached from the last polling cycle. In volatile markets, book depth changes in < 1s.
- Not splitting large taker orders: If
max_size_within_budget()returns a size much smaller than the target, consider splitting into multiple smaller taker orders spaced 500ms–1s apart to allow the book to replenish between fills. Never send all size simultaneously against a thin book. - Ignoring
fill_coverage_pct: A simulated fill that only covers 70% of the order size will leave 30% unfilled asIocremainder. That remainder may need a separate maker order to complete, changing the execution plan and cost model. - Double-counting slippage and taker fee: Slippage (adverse price movement through the book) and taker fee (exchange charge on notional) are separate costs. The slippage budget framework accounts for both independently. Do not lump them together in a single "cost" estimate.
Integration with Other Skills
maker-order-preference-fee-reduction(execution/): Determines whether taker execution is warranted. This skill governs how much slippage is acceptable once taker is chosen. Always run in sequence.limit-offset-bps-calculation(execution/): Governs the maker path. If this skill’s budget check returns0.0(taker not viable), fall back to that skill to place anAlolimit instead.liquidation-cascade-risk(regime-detection/): Cascade CRITICAL overrides this skill’s budget enforcement. Also providesbook_fragilitywhich sets the expectation for how bad slippage will be before the book walk is run.kelly-position-sizing-perps(risk/): Position size output from Kelly sizing is theinitial_size_usdinput tomax_size_within_budget(). If the book cannot absorb the Kelly size within the slippage budget, the executed size must be reduced; the risk model must be informed of the actual executed size for exposure tracking.
Audit JSONL Schema
{
"event": "taker_order_slippage_check",
"asset": "SOL",
"timestamp_utc": "2026-04-07T22:00:00Z",
"side": "sell",
"target_size_usd": 25000,
"expected_move_bps": 18.0,
"taker_fee_bps": 3.5,
"slippage_budget_bps": 12.5,
"book_walk_slippage_bps": 7.2,
"book_walk_coverage_pct": 100.0,
"within_budget": true,
"adjusted_size_usd": 25000,
"worst_acceptable_price": 138.143,
"session_slippage_bps_before": 4.1,
"session_slippage_cap_bps": 20.0,
"defensive_override": false,
"order_result": "filled",
"actual_fill_price": 138.155,
"actual_slippage_bps": 6.8,
"budget_violation": false
}
Quick Decision Tree
Taker order needed — enforce slippage budget:
│
├── Is this a DEFENSIVE EXIT (cascade/kill-switch/stop breach)?
│ └── YES → Submit market order. Log estimated slippage. Skip budget checks.
│
└── Normal taker execution path:
│
├── 1. budget = per_order_slippage_budget_bps(expected_move)
│ └── budget == 0? → ABORT. Use Alo instead.
│
├── 2. can_place, status = tracker.can_place_taker(estimated_slippage)
│ ├── can_place False? → ABORT. Session cap hit.
│ └── status "warning"? → Halve size. Continue.
│
├── 3. sim = simulate_taker_fill(l2book, side, size, mid)
│ ├── sim.slippage > budget? → max_size_within_budget()
│ │ ├── adjusted > 0? → Use adjusted size.
│ │ └── adjusted == 0? → ABORT. Use Alo.
│ └── sim.feasible False? → Reduce to depth × 0.80. Re-simulate.
│
└── 4. Submit Ioc at worst_acceptable_price.
Post-fill: tracker.record_fill(). Log audit event.
04 同仓库更多 Skills
supermemory
Supermemory is a state-of-the-art memory and context infrastructure for AI agents. Use this skill when building applications that need persistent memory, user personalization, long-term context retention, or semantic search across knowledge bases. It provides Memory API for learned user context, User Profiles for static/dynamic facts, and RAG for semantic search. Perfect for chatbots, assistants, and knowledge-intensive applications.
wolverine-strategy
WOLVERINE v2.0 — HYPE alpha hunter. Entry-only scanner, DSL-exit-only architecture. v1.1 lost -22.7% because the scanner's thesis exit chopped 25/27 trades before DSL could manage them. v2.0 removes thesis exit entirely. Scanner decides entries (score 8+, 4H/1H aligned, SM consensus). DSL manages all exits (wide Phase 1 for HYPE volatility, trailing tiers starting at +15% ROE). Leverage lowered to 7x. Max 4 entries/day. 3-hour cooldown between entries. DSL exit managed by plugin runtime via runtime.yaml.
wolf-strategy
WOLF v6.3 — Fully autonomous multi-strategy trading for Hyperliquid perps via Senpi MCP. Manages multiple strategies simultaneously, each with independent wallets, budgets, slots, and DSL configs. 5+N cron architecture: 5 shared wolf crons (Emerging Movers 3min, SM Flip 5min, Watchdog 5min, Risk Guardian 5min, Health Check 10min) plus one DSL v5.2 cron per strategy (native Hyperliquid SL sync via dsl-dynamic-stop-loss skill v5.3.1). Same asset can be traded in different strategies simultaneously. Enter early on first jumps, not at confirmed peaks. Dynamic risk-based leverage per strategy. Requires Senpi MCP connection, python3, mcporter CLI, OpenClaw cron system, and dsl-dynamic-stop-loss skill (provides dsl-cli.py + dsl-v5.py).
wolf-howl
HOWL v2 — Hunt, Optimize, Win, Learn. Nightly self-improvement loop for the WOLF autonomous trading strategy. Runs once per day (via cron) to review all trades from the last 24 hours, compute win rates, analyze signal quality correlation, evaluate DSL tier performance, identify missed opportunities, and produce concrete improvement suggestions for the wolf-strategy skill. v2 adds fee drag ratio (FDR) analysis, holding period bucketing, LONG vs SHORT regime detection, rotation cost tracking, cumulative drift detection, and gross vs net profit factor separation. Use when setting up daily trade review automation, analyzing trading performance, or improving an autonomous trading strategy through data-driven feedback loops. Requires Senpi MCP connection, mcporter CLI, and OpenClaw cron system.
whale-index
Auto-mirror top Discovery traders on Hyperliquid. Scans top 50 traders, scores on PnL rank (35%), win rate (25%), consistency (20%), hold time (10%), drawdown (10%). Creates 2-5 mirror strategies with overlap checks. Daily rebalance with 2-day watch period before swaps. Use when setting up trader mirroring, copy trading, or portfolio auto-rebalancing based on Discovery leaderboard performance.
vixen-strategy
VIXEN v1.0 — Dual-mode emerging movers scanner. Built from FOX v1.6 live trading data (+34.5% ROI). Two entry modes: STALKER (steady accumulation, score 6+, catches the SM buildup BEFORE the explosion) and STRIKER (violent FIRST_JUMP, score 9+, with raw volume confirmation to filter blow-off tops). 2-hour per-asset cooldown after Phase 1 exits. DSL High Water Mode mandatory.