FABRKNT
Perp DEX Primer — DIY Perp track の前提となる永久先物の仕組み
Perp Primer
レッスン 3 / 4·CONTENT40 分70 XP
コース
Perp DEX Primer — DIY Perp track の前提となる永久先物の仕組み
レッスンの役割
CONTENT
順序
3 / 4

レッスン2 — Margin model — collateral、leverage、equity、4 状態

問い

L0 で perp、L1 で funding を立てた。どちらも「ポジションを持っているトレーダー」を抽象的に扱った。L2 はその抽象に踏み込む — 「ポジション」が具体的にドルと比率で何か、venue はどんなときに force-close できるか、それが margin model。

原理(最小モデル)

  • Position を記述する 5 量. collateral(入金 USDC)/ position_size(符号付き、+ long / − short BTC unit)/ notional(|position_size| × mark = 現在ドル exposure)/ unrealized_pnl((mark − entry) × position_size = mark で閉じたときの未確定損益)/ equity(collateral + unrealized_pnl = venue 上での実質純資産)。
  • トレーダー直接操作は 2 量のみ. collateral(入出金)+ position_size(取引)。残り 3 量(notional / unrealized_pnl / equity)は venue が block ごとに mark から計算。
  • Initial margin と maintenance margin. Initial = ポジション開設時に必要な collateral ratio(Hyperliquid ~10%、leverage 10× 相当)/ Maintenance = ポジション保持時の最低ライン(Hyperliquid ~2%、tier で変動)= 開設後、損失で margin ratio が initial 以下に落ちても open のまま、maintenance を下回ると force-close。
  • 4 状態. Safe(margin ratio ≥ initial)/ AtRisk(initial > ratio ≥ maintenance、追加取引禁止 / ポジション増額禁止 / 縮小と入金は OK)/ Liquidatable(ratio < maintenance かつ equity ≥ 0、venue が force-close)/ Underwater(equity < 0、損失が collateral を超えた、insurance fund 出動)。
  • 4 状態 → engine 動作対応. Safe = 全操作 OK、AtRisk = 新規取引拒否、Liquidatable = engine が force-close 発火(L3 で詳述)、Underwater = force-close + 不足分を insurance fund 補填。
  • Cross-margin vs isolated margin. Cross = アカウント全 collateral が全ポジションの裏付け(1 つの含み益が別の含み損を相殺)、Isolated = ポジションごとに collateral 分離(1 つ liquidate されても他は無傷)。Hyperliquid デフォルト cross(積極的資金効率、洗練ユーザー向け)、isolated はオプション。
  • Funding が equity に効く経路. 各 interval で equity += -funding_payment(支払えば減、受け取れば増)→ margin ratio 変化 → 状態境界を越えうる、Funding が単に「コスト」でなく liquidation を早める力 にもなる。
  • 1 ポジションを 5 mark で追う「経路」. entry $100k → mark $90k(含み損、AtRisk 寸前)→ $80k(Liquidatable、force-close 発火)→ $70k(Underwater、insurance fund 出動)の段階を 4 状態で追える。

具体例 + ステップで組み立てる

Margin model — collateral、leverage、equity、4 状態

ゴール

このレッスンで掴む概念:

  • Perp position を記述する 5 つの量: collateral、position size、notional、unrealized PnL、equity。それぞれの計算式、意味、venue が実際に track するもの。
  • Initial vs maintenance margin — venue が使う 2 つのしきい値、それぞれがトレーダーに何を許可するか。
  • Margin health の 4 状態 — Safe、AtRisk、Liquidatable、Underwater。それぞれが engine の許可/強制動作に対応する。
  • Cross-margin vs isolated margin — 同じ数学、違うスコープ。Hyperliquid が cross をデフォルトにする理由。
  • 同じ position を 5 つの mark で追う — 1 つの position が状態境界を渡る様子を順に見る。

このレッスンを終えると、以下に答えられる:

  • 「$10k を deposit して BTC に 5× leverage を取ったら、notional はいくらか?」
  • 「AtRisk と Liquidatable は何が違うのか?」
  • 「なぜ Hyperliquid は 10% initial / 2% maintenance を使うのか?」

おさらい

レッスン0 で perp とは何かを立て、レッスン1 で funding が mark を index に anchor する仕組みを見た。どちらも「ポジションを持っているトレーダー」を抽象的に扱った。

レッスン2 ではその抽象に踏み込む。「ポジション」が具体的にドルと比率で何なのか。Venue はどんなときに force-close できるのか。これが margin model だ。

5 つの量

Perp position は 5 つの数値で完全に記述できる:

意味
collateral(トレーダーが入金)ポジションを裏付ける USDC
position_size(符号付き: + long、− short)BTC を何 unit long / short しているか
notional|position_size| × markmark 価格での現在のドル exposure
unrealized_pnl(mark − entry) × position_sizemark で閉じたときの損益。まだ確定していない
equitycollateral + unrealized_pnlvenue 上でのトレーダーの実質的な純資産

トレーダーが直接操作するのは collateral(入出金)と position_size(取引)の 2 つ。残り 3 つは venue が block ごとに mark から計算する。

具体例:

collateral     = $10,000
position_size  = +0.5 BTC   (long)
entry          = $100,000
mark           = $100,000
notional       = 0.5 × 100,000 = $50,000
unrealized_pnl = (100,000 − 100,000) × 0.5 = $0
equity         = 10,000 + 0 = $10,000

PnL がゼロなので、ポジションを開いた直後は equity = collateral。Mark が動けば equity もそれに合わせて動く。

Leverage

Leverage は collateral と notional の間の倍率だ:

leverage = notional / collateral

例: leverage = 50,000 / 10,000 = 5×。Collateral $1 ごとに BTC への 5× の exposure を持っている。

Leverage は informational だ。エンジンは「leverage 上限」を直接強制しない — margin ratio のしきい値(次節)を強制する。実効 leverage の上限はそこから出てくる、もっと柔軟な形で。

2 つのしきい値: initial vs maintenance margin

Initial margin はトレーダーが position を 開く / 増やす ときに必要な ratio。Hyperliquid は ~10%。開く時点での最大 leverage はおおよそ 10× になる。

Maintenance margin はトレーダーが position を 持ち続ける ときに必要な ratio。これを下回ると engine が force-close する。Hyperliquid は ~2%(tier によって変わる — 大きな position ほど maintenance も高い)。

2 つのしきい値が異なるのは意図的だ:

  • Initial > maintenance: initial を辛うじてクリアして開いたトレーダーには、liquidation に達する前に少し adverse な mark の動きを耐える余裕がある
  • ギャップがなければ、ぎりぎりで開いた position は不利な tick が来た瞬間に必ず liquidate する
  • ギャップは venue がトレーダーに与える バッファ。Liquidation に至る前に意思決定する(collateral を足す、partial close する、など)時間を確保する
  • 同時に、これはシステム側の防衛ラインでもある。 Maintenance を割った瞬間に「即破綻」ではなく、清算エンジンが force-close 注文を市場に流し込んで約定するまでの スリッページ + 起動レイテンシの吸収余地 を、このギャップが用意している。レッスン3 で見る force-close 注文は、この余地を予算として使って執行される — 余地が薄ければ薄いほど、insurance fund が負担する不足分が膨らむ。
  • 反例で見る必然性 (Initial = Maintenance が危険な理由): もし initial と maintenance が同じ 2% なら、2.01% で開いたポジションは 1 tick の微小逆行だけで即 Liquidatable になる。急変時は、清算注文が板に入り約定するまでの短い遅延中に ratio が 0% を割って Underwater へ突き抜ける確率が高い。Initial と Maintenance のギャップは、トレーダー保護だけでなく、システム全体のソルベンシーを守る「スリッページ・クッション」 そのものだ。

Margin ratio が中心的な量:

margin_ratio = equity / notional

例: margin_ratio = 10,000 / 50,000 = 20% = 2,000 bps

20% は Hyperliquid の initial 10% と maintenance 2% の両方を大幅に超えている。Position は Safe

4 状態

エンジンは非 flat な各 position を margin ratio に基づき 4 状態に分類する:

状態条件エンジンの動作
Saferatio ≥ initial_margin_bps(≥ 10%)トレーダーは新規 / 追加できる
AtRiskratio ∈ [maintenance, initial)(2% ≤ x < 10%)保持は可、新規リスクは禁止
Liquidatableratio < maintenance, equity ≥ 0(< 2% だが underwater ではない)Market で force-close、残額をトレーダーに返す
Underwaterequity < 0(損失が collateral を超えた)Force-close + insurance fund が不足を吸収(レッスン3 のトピック)

Liquidatable と Underwater の区別は、残余を誰が負担するか を決めるので重要だ。Liquidatable ではトレーダーの残 collateral が close + fee をカバーする。Underwater でも close は実行されるが、トレーダーが払いきれない分は venue の insurance fund が負担する。

これが Build OpenHL — Liquidation コースが MarginHealth enum として実装する 4 状態分類だ。同じ 4 状態、同じ境界条件。

4 状態の遷移を 1 本の軸で見る

margin_ratio を高 → 低の 1 本の数直線として眺めると、4 状態は隣接する 4 区間に対応する:

   高 ◄────────────── margin_ratio = equity / notional ──────────────► 低 / 負
       20%             10%                   2%                0%
   ─────┼──────────────┼─────────────────────┼─────────────────┼─────────►
        │              │                     │                 │
        │  ┌────────┐  │   ┌──────────┐      │ ┌────────────┐  │ ┌──────────┐
        │  │  Safe  │  │   │  AtRisk  │      │ │Liquidatable│  │ │Underwater│
        │  │        │  │   │          │      │ │            │  │ │          │
        │  │ 新規 / │  │   │ 保持のみ │      │ │ engine が  │  │ │ engine が│
        │  │  追加  │  │   │ 可、新規 │      │ │ force-close│  │ │ close +  │
        │  │  可    │  │   │  禁止    │      │ │            │  │ │ insurance│
        │  └────────┘  │   └──────────┘      │ └────────────┘  │ │   fund   │
        │              ▲                     ▲                 ▲ └──────────┘
        │     initial margin (10%)   maintenance margin (2%)  equity = 0
        │              │                     │                 │
        │   ratio ≥    │  maintenance ≤      │  0 ≤ ratio <    │  equity < 0
        │   initial    │  ratio < initial    │  maintenance    │  (notional は正)
        │              │                     │                 │
        │  条件分岐:   │  分岐:              │  分岐:          │  分岐:
        │  if ratio    │  else if ratio      │  else if equity │  else
        │   ≥ initial  │   ≥ maintenance     │   ≥ 0           │   { Underwater }
        │   {Safe}     │   {AtRisk}          │   {Liquidatable}│
        │                                                      │
        └─────── 上記の数値例 ($10k coll、0.5 BTC long、entry $100k) ────────────┐
                                                                                  │
              Safe → AtRisk      の境界: mark = $88,889  (entry から −11.1%)      │
              AtRisk → Liquidatable の境界: mark = $81,633  (entry から −18.4%)   │
              Liquidatable → Underwater の境界: mark = $80,000  (entry から −20.0%) │
                                                                                  │
        ───────────────────────────────────────────────────────────────────────────┘

この図のとおり、MarginHealth enum の判定は margin_ratio (および equity の符号) という単一スカラーに対する 4 区間分類 に還元できる。レッスン3 ではこの 4 区間それぞれで「engine が実際に何をするか」を順に辿る — SafeAtRisk は何もしない (=トレーダー側の自由)、Liquidatable は force-close 注文を market に流す、Underwater は force-close + insurance fund 引き出し。コードの分岐は数直線の区間に 1 対 1 で対応する — これが Rust の match MarginHealth { Safe => …, AtRisk => …, Liquidatable => …, Underwater => … } で綺麗に書ける理由だ。

計算例 — 同じ position、5 つの mark 価格

トレーダー: $10k collateral、0.5 BTC long、entry $100,000。Hyperliquid params(initial 10%、maintenance 2%)。

MarkNotionalPnLEquityRatio状態
$100,000$50,000$0$10,00020.0%Safe (初期状態)
$95,000$47,500−$2,500$7,50015.8%Safe
$88,889$44,444−$5,556$4,44410.0%Safe ↔ AtRisk 境界 (理論値)
$85,000$42,500−$7,500$2,5005.9%AtRisk
$82,000$41,000−$9,000$1,0002.4%AtRisk (ぎりぎり)
$81,633$40,816−$9,184$8162.0%AtRisk ↔ Liquidatable 境界 (理論値)
$81,500$40,750−$9,250$7501.8%Liquidatable
$80,000$40,000−$10,000$00.0%Liquidatable (残余ゼロ — 次 tick で Underwater 化リスク)
$78,000$39,000−$11,000−$1,000−2.6%Underwater

境界を越える瞬間が 2 つある:

  1. Safe → AtRisk (mark $88,889 が境界、entry から −11.1%): 表の $95,000 → $85,000 の間。$88,889 を下回ると、トレーダーは保持はできるが、position を追加することも新規 position を取ることもできなくなる。UI が警告を出すのも通常この時点。
  2. AtRisk → Liquidatable (mark $81,633 が境界、entry から −18.4%): 表の $82,000 → $81,500 の間。$81,633 を下回ると、エンジンが force-close を発動する。Maintenance を下回ると、collateral がもう取引と liquidation fee を払いきれない。

この例では、Liquidatable に到達するのに必要な mark 下落は entry から 約 18.4% だけ ($81,633 / $100,000)。これは leverage の逆数に近い: 5× leverage (notional/equity = $50k/$10k) で adverse 18.4%(≈ 1/5 × maintenance ギャップ)の動きで吹き飛ぶ。10× で ~9%、50× だと ~1.8%(日中ふつうに見る幅)。

エンジン上では leverage は risk 対称的: 高 leverage = 有利な動きで大きな upside、ただし小さな adverse な動きで liquidate する。数学はどちらの方向にも肩を持たない。Position を開いた時点でトレーダーが risk profile を選んだだけだ。

Cross-margin vs isolated margin

ここまでは「トレーダーが 1 ポジション持っている」前提で話した。実際には、トレーダーは同時に複数(BTC、ETH、HYPE、SOL、...)持てる。Venue が複数 position の collateral を共有させる方法が 2 つある:

Cross-margin(Hyperliquid のデフォルト): すべての position が 1 つの collateral pool を共有する。Margin ratio は notional の 合計 に対して 合計 equity で計算する。利益が出ている BTC long が、損失中の ETH short のバッファになる。トレーダーにとっても engine にとっても単純。

Isolated margin(Hyperliquid では asset 単位で opt-in): 各 position が専用の collateral subset を持つ。1 つの position が liquidate しても他の position に影響しない。「他の損失で連鎖されたくない確信あるポジション」に使う。

数学は同じ — margin_ratio = equity / notional — 違うのは スコープ だけ。Cross は合計、isolated は per-position。

Hyperliquid はバッファ効果を望むトレーダーが大半なので cross をデフォルトにしている。Isolated は opt-in。

Hyperliquid 固有の点

  • Initial margin の tier: Hyperliquid は実際には tiered initial margin を使う。「~10%」は小さい position に対するベースライン。Position size が asset ごとのしきい値を超えると、initial margin 要件が上がる(大口 BTC position だと 20% / 30% を要求されうる)。単独トレーダーへの systemic exposure に上限を当てる仕組み。
  • Maintenance margin の tier: 同じく — 大きい position ほど maintenance も高い。DIY Perp track では教育目的で flat なしきい値に単純化しているが、本番デプロイは tiered。
  • Cross-margin がデフォルト: トレーダーは USDC を 1 度 deposit して、どの market でも取引できる。
  • Margin 計算は consensus 内: すべての validator が同じ snapshot から同じ margin ratio を計算する。これが Build OpenHL — Liquidation コースの レッスン1 が教える determinism property の根拠。

よくある誤解

「Liquidation は position がゼロになったとき起きる」。 違う — liquidation は maintenance しきい値で起きる。ゼロ equity の だ。Maintenance とゼロの間のバッファ(notional の ~2%)が liquidation fee と close order の slippage を吸収する。ゼロまで待ったら、トレーダーの残額はもう fee を払えない。

「Leverage が高い = profit が高い」。 Leverage が高い = collateral 単位あたりの position size が大きい。Collateral に対する % リターンは、gain でも loss でも大きくなる。Expected value は leverage で変わらない — 変わるのは variance だけ。

「Cross-margin は isolated より常に良い」。 違う。Cross が良いのは、すべての position が好意的に相関しているとき(long だけの portfolio など)。Cross が 悪い のは、1 つの position が不釣り合いに吹き飛んだとき — portfolio 全体を liquidate しうる。Isolated はその risk を隔離する。Cross vs isolated は本物の risk management の判断であって、ただのデフォルトではない。

次のレッスン(レッスン3)

レッスン3 — Liquidation、insurance fund、ADL。状態を分類した。次は position が Liquidatable や Underwater に渡ったとき 何が起きるか を順に辿る。エンジンが close order を出す、matching engine が約定させる、fee が insurance fund に流れる、不足が fund を drain する、稀に insurance fund が枯渇すると ADL が発動する。

レッスン3 を終えると、perp の機構の完全なモデルが手に入る。そして Build OpenHL — Liquidation コースの レッスン4〜7(margin math + 分類 + close order 生成)が「すでに理解している内容の Rust 実装」として読めるようになる。

合格基準

  • 5 量(collateral / position_size / notional / unrealized_pnl / equity)の計算式と意味を即答できる。
  • トレーダー直接操作の 2 量と venue 計算の 3 量を区別できる。
  • Initial vs maintenance margin の意味(開設しきい値 vs 保持しきい値)を即答できる。
  • 4 状態(Safe / AtRisk / Liquidatable / Underwater)と各々の engine 動作を即答できる。
  • Cross-margin vs isolated margin の trade-off と Hyperliquid のデフォルト選択を即答できる。
  • Funding が equity に効く経路と状態境界を越えうる仕組みを 1 文で説明できる。
  • 1 ポジションを mark を下げながら 4 状態で追う「経路」を順に説明できる。

まとめ(3行)

  • Margin model = 5 量(collateral / position_size / notional / unrealized_pnl / equity)+ 2 しきい値(initial ~10% / maintenance ~2%)+ 4 状態(Safe / AtRisk / Liquidatable / Underwater)。
  • Cross-margin デフォルト(Hyperliquid)= アカウント全 collateral が全ポジションを裏付け、isolated はオプション、funding が equity に効くことで状態境界を越えうる。
  • 次レッスン L3 で AtRisk → Liquidatable → Underwater 境界での実動作(force-close + insurance fund 補填 + 最終手段 ADL)を辿り、Liquidation コース実装はこの 4 状態を Rust 状態機械として表現したもの。