hybrid-perps-spec

Risk Control & Hedging Scenarios

Document Version: v1.0 Last Updated: 2026-04-09 Author: Claude Code Status: Specification Phase


Scenario Overview

This document details the core business scenarios for platform risk control and hedge engine (L6). Covers net exposure monitoring, automatic hedge triggers, capital management, routing mode switching, risk reserve management, circuit breaker mechanisms, multi-asset capital allocation, and hedge buffer issues—8 key scenarios total.

Each scenario is based on the “方案二 (Internalization + Threshold Hedging)” dual-account architecture:


SC-RH-001: Net Exposure Grows from Zero to Trigger Hedge

Scenario Background: Throughout a day, users continuously go long BTC. Platform accepts these small orders via L3 (INTERNAL internalization), and net exposure grows from $0. When accumulated net exposure crosses $100K threshold, L6 hedge engine triggers automatic hedge, opening hedge position on HL hedge account.

Input:

Decision Rule:

net_exposure = cumulative_INTERNAL_long - cumulative_INTERNAL_short

if (net_exposure > $100K):
    hedge_ratio = 50%
    hedge_amount = net_exposure * hedge_ratio
    execute_hedge(amount=hedge_amount, direction="long", symbol="BTC")
else:
    skip_hedge()

current_net_exposure = $95K + $8K = $103K > $100K
→ hedge_amount = $103K * 50% = $51.5K

Output:

Monitoring Points:

Fallback on Failure:


SC-RH-002: Hedge Account Capital Insufficient

Scenario Background: Platform needs to hedge $400K internal exposure, but hedge account only has $100K available capital. At 3x leverage, can only cover $300K, creating $100K gap. System intelligently raises leverage or triggers capital top-up, ensuring hedge capacity isn’t constrained by capital.

Input:

Decision Rule:

required_hedge = net_exposure * hedge_ratio = $400K * 50% = $200K

available_capacity = account_capital * current_leverage = $100K * 3x = $300K

if (required_hedge <= available_capacity):
    execute_hedge(amount=required_hedge)
else:
    required_leverage = required_hedge / account_capital = $200K / $100K = 2x
    if (required_leverage <= max_leverage):
        increase_leverage_to(required_leverage)
        execute_hedge(amount=required_hedge)
        trigger_fund_request()
    else:
        partial_hedge = account_capital * max_leverage
        execute_hedge(amount=partial_hedge)
        alert("Capital insufficient", severity=P1)

In this scenario:

Output:

Monitoring Points:

Fallback on Failure:


SC-RH-003: BTC Drops 10%, Hedge Position Floating Loss

Scenario Background: Platform hedge account holds BTC long $500K (3x leverage), base capital $166.67K. Suddenly BTC market price drops 10%, hedge position incurs $50K floating loss, margin ratio drops from 500% to 350%. System must emergency-supplement from risk reserve to maintain hedge account health.

Input:

Decision Rule:

account_equity = account_capital + unrealized_pnl = $200K - $50K = $150K
maintenance_margin_requirement = hedge_position / max_leverage_allowed
                               = $500K / 5x = $100K (conservative estimate)

margin_ratio = account_equity / maintenance_margin_requirement = $150K / $100K = 150%

if (margin_ratio < 500%):
    shortage = (target_ratio * maintenance - account_equity)
                = (5 * $100K) - $150K = $350K

    # Top-up minimum safe amount
    supplement = min(shortage, available_reserve)
    transfer_from_reserve(supplement)

if (shortage > available_reserve):
    alert("Reserve insufficient to cover floating loss", severity=P0)
    reduce_hedge_position()

In this scenario:

Output:

Monitoring Points:

Fallback on Failure:


SC-RH-004: Automatic Routing Mode Switch (NORMAL → HL_MODE)

Scenario Background: Platform normally runs in NORMAL_MODE ($10K threshold), internal exposure stable at $300K–$400K. Suddenly large user/institution orders flood in, INTERNAL net exposure rapidly spikes to $800K, far exceeding safe capacity. System must detect and auto-switch to HL_MODE, forcing all new orders to Hyperliquid, preventing exposure runaway.

Input:

Decision Rule:

def check_routing_mode():
    if (net_exposure > HL_MODE_threshold):
        if (current_mode != HL_MODE):
            switch_mode(NORMAL → HL_MODE)
            halt_internal_orders()
            notify_risk_manager()

check_point_A: net_exposure = $550K → OK, stay NORMAL_MODE
check_point_B: net_exposure = $550K + $220K (first two orders) = $770K → Approaching threshold, alert
check_point_C: net_exposure = $770K + $150K = $920K > $800K → Trigger auto-switch

# All subsequent orders route to HL
Order_4($50K) → HL (not INTERNAL)
Order_5($80K) → HL

Output:

Monitoring Points:

Fallback on Failure:


SC-RH-005: Risk Reserve Falls Below $200K

Scenario Background: Platform has accumulated $450K risk reserve (from net user losses in INTERNAL trading). Due to favorable market, users profit continuously, reserve gets consumed for hedge float supplements and operation costs. Reserve balance declines daily, finally drops below $200K safety floor. System must trigger reserve supplement flow, pause or restrict internalization trading.

Input:

Decision Rule:

def monitor_reserve():
    if (reserve < $500K):
        severity = "YELLOW"  # Alert: recommend top-up
    if (reserve < $300K):
        severity = "ORANGE"  # Warning: start restricting internalization
    if (reserve < $200K):
        severity = "RED"     # Emergency: halt internalization
        action = "halt_internal_trading"

Current reserve = $180K < $200K → RED
→ halt_internal_trading()
→ switch_mode(NORMAL → HL_MODE / or FULL_HL)
→ notify_admin(urgency=P0)

Output:

Monitoring Points:

Fallback on Failure:


SC-RH-006: Daily Loss Circuit Breaker Triggers

Scenario Background: Platform’s INTERNAL internalization has daily PnL swings. Normal daily variance ±$20K, but extreme days may see concentrated user profit, platform net loss. System implements daily loss circuit breaker: when daily INTERNAL net loss reaches $500K, auto-halt betting, preventing extreme risk.

Input:

Decision Rule:

# After each INTERNAL execution, accumulate daily loss
daily_loss = sum(all_internal_trades_pnl_today)

if (daily_loss < -$100K):
    log_alert("Daily loss alert", severity=P2)
    notify_risk_manager()

if (daily_loss < -$500K):
    log_alert("Daily loss circuit breaker", severity=P0)
    halt_internal_trading()
    switch_mode(HL_MODE)
    update_circuit_breaker_status(TRIGGERED)

# Next day 00:00 UTC auto-reset
if (utc_hour == 0 and utc_minute == 0):
    reset_daily_loss_counter()
    circuit_breaker_status = RESET
    if (mode == HL_MODE_due_to_loss):
        # Auto-try to restore NORMAL_MODE (if other metrics allow)
        try_restore_normal_mode()

Timeline example:

09:30 - Daily loss -$20K (OK)
12:15 - Daily loss -$80K (OK)
14:45 - Daily loss -$120K → Alert P2
16:20 - Daily loss -$350K → Alert upgraded P1
18:05 - Daily loss -$510K > -$500K → Breaker triggers P0
        → Halt INTERNAL betting
        → Switch HL_MODE
        → circuit_breaker = TRIGGERED
        → Notify Risk Manager + CTO

Next day 2026-04-10 00:00:00 UTC:
        → daily_loss_counter = 0
        → circuit_breaker = RESET
        → Try restore NORMAL_MODE (if exposure permits)

Output:

Monitoring Points:

Fallback on Failure:


SC-RH-007: Multi-Asset Hedge, Capital Allocation

Scenario Background: Platform supports multi-asset trading (BTC, ETH, SOL, etc.). On high-volatility day, multiple assets accumulate large net exposure, all need hedging. But hedge account’s available capital is limited, can’t fully satisfy all assets. System must implement intelligent capital allocation: rank by exposure size, prioritize covering largest, smaller may switch to HL_MODE.

Input:

Decision Rule:

def allocate_hedge_across_symbols():
    total_demand = sum(symbol.exposure * hedge_ratio for symbol in symbols)
    total_capacity = account_capital * current_leverage

    if (total_demand <= total_capacity):
        # Sufficient, satisfy all
        for symbol in symbols:
            execute_hedge(symbol, symbol.exposure * hedge_ratio)
    else:
        # Insufficient, allocate by size priority
        symbols_by_size = sort_by_exposure(symbols, desc=True)
        remaining_capacity = total_capacity

        for symbol in symbols_by_size:
            required = symbol.exposure * hedge_ratio
            if (remaining_capacity >= required):
                execute_hedge(symbol, required)
                remaining_capacity -= required
            else:
                # Can't satisfy, split handling
                if (remaining_capacity > 0):
                    execute_hedge(symbol, remaining_capacity)
                    remaining_capacity = 0
                # Remaining exposure switch to HL_MODE
                alert(f"{symbol} exposure switch to HL_MODE")
                switch_symbol_to_hl(symbol)

Execution order in this scenario:
1. BTC (largest) → Hedge $480K (consumes $160K capital @ 3x)
   remaining = $600K - $160K = $440K

2. ETH (medium) → Hedge $150K (consumes $50K capital @ 3x)
   remaining = $440K - $50K = $390K

3. SOL (smallest) → Need $75K
   Can actually hedge: $390K / 3x = $130K (covers $75K)
   Hedge $75K (consumes $25K capital @ 3x)
   remaining = $390K - $25K = $365K

Result: All assets satisfiable ✓

Output:

Monitoring Points:

Fallback on Failure:


SC-RH-008: Concentrated User Close Causes Over-hedge

Scenario Background: Platform hedged large user’s BTC long $800K (INTERNAL) via HL hedge account long $640K (80% hedge + 10% buffer). That user suddenly closes all positions within 1 hour. INTERNAL exposure drops $800K → $0. Platform hedge account must de-hedge from $640K → $0, but can’t de-hedge too fast (slippage, market impact). Must execute in batches, gradually.

Input:

Decision Rule:

def adjust_hedge_on_position_change():
    new_exposure = get_current_net_exposure()
    current_hedge = get_current_hedge_position()

    # Calculate target based on hedge threshold and ratio
    if (new_exposure < HEDGE_THRESHOLD):
        target_hedge = 0
    else:
        target_hedge = new_exposure * hedge_ratio

    hedge_adjustment = current_hedge - target_hedge

    if (hedge_adjustment > 0):
        # Need de-hedge
        reduce_hedge(hedge_adjustment)
    elif (hedge_adjustment < 0):
        # Need add hedge
        increase_hedge(-hedge_adjustment)

# In this scenario:
trigger_point_1: exposure = $800K - $150K = $650K
                target_hedge = $650K * 80% = $520K
                adjust = $640K - $520K = $120K (need reduce $120K)
                execute_reduce($120K, max_rate=$200K/min)

trigger_point_2: exposure = $450K
                target_hedge = $450K * 80% = $360K
                adjust = $520K - $360K = $160K (need reduce $160K)
                execute_reduce($160K, max_rate=$200K/min)

...finally...

trigger_point_N: exposure = $0 < $100K_threshold
                target_hedge = 0
                adjust = remaining_hedge (full de-hedge)
                execute_reduce_all(remaining_hedge, max_rate=$200K/min)

Each reduction limited to max $200K/min (prevent market impact)

Output:

Monitoring Points:

Fallback on Failure:


SC-RH-009: (Reserved) Internalization Execution vs. Hedge Directive Race Condition

This scenario detailed in “Edge Cases & Extreme Conditions” (06-edge-cases.md) SC-EC-009.


SC-RH-010: (Reserved) HL API Rate Limiting Causes Hedge Delay

This scenario detailed in “Edge Cases & Extreme Conditions” (06-edge-cases.md) SC-EC-010.


Appendix: Key Metrics & Alert Thresholds Summary

Metric Alert Threshold (Yellow) Trigger Threshold (Red) Action
Net Exposure $500K $800K Switch HL_MODE
Hedge Account Margin Ratio 300% 150% Top-up capital
Risk Reserve $300K $200K Halt internalization
Daily Net Loss -$100K -$500K Circuit breaker
HL API Latency 200ms 500ms Fallback/Switch HL
Data Sync Latency 1s 5s Alert + manual

End of Document