رفتن به محتوای اصلی
سرفصل مسیر Quant Developer

مسیر Quant Developer · بخش ۶: Hedging و بازار مشتقات · درس ۲۴

Inventory Limits و Capital Allocation

چطور از نوسان و تحمل زیان به سقف موجودی برسیم، محدودیت نرم و سخت چه فرقی دارند، و سرمایه و ریسک را چطور بین جفت‌ارزها و صرافی‌ها تقسیم کنیم.

سطح: متوسط تا پیشرفته۱۴ دقیقه مطالعه

۱. چرا Skew و هج کافی نیستند

تا اینجا سه ابزار برای کنترل موجودی داشتیم: Skew در درس ۶، هج در درس ۲۱، و مدل‌هایی مثل Guéant–Lehalle–Fernandez-Tapia در درس ۱۲ که سقف موجودی را مستقیماً داخل مسئله بهینه‌سازی می‌گذارند. هر کدام نقطه شکستی دارند:

  • Skew به طرف مقابل نیاز دارد. در یک سقوط یک‌طرفه، هیچ‌کس از تو نمی‌خرد، هرقدر هم قیمتت را پایین بیاوری.
  • هج به صرافی دوم، اتصال سالم و وجه تضمین کافی نیاز دارد. در درس ۲۲ دیدیم موقعیت هج‌شده هم می‌تواند Liquidate شود.
  • مدل فقط به اندازه فرض‌هایش خوب است؛ نوسان ثابت، پر شدن مستقل، و نبود جهش قیمت.

Inventory Limit آخرین خط دفاع است: عددی که موتور ریسک بدون توجه به نظر مدل اجرا می‌کند. این درس درباره این است که این عدد از کجا می‌آید و سرمایه کل را چطور بین جفت‌ارزها و صرافی‌ها پخش کنیم.

۲. از نوسان و تحمل زیان به سقف موجودی

سؤال درست این نیست که «چقدر موجودی زیاد است»، بلکه این است: اگر مجبور شوم موجودی را ببندم، با چه اطمینانی حداکثر چقدر زیان می‌کنم؟ سه ورودی لازم است:

  • تحمل زیان L: مثلاً ۱,۰۰۰ دلار برای این جفت‌ارز.
  • افق بستن h: زمانی که برای بستن یا هج کامل موجودی با هزینه قابل قبول لازم داری. این عدد یک روز نیست؛ برای BTC شاید یک ساعت، برای یک آلت‌کوین کم‌عمق چند ساعت.
  • نوسان در همان افق σ_h و یک ضریب اطمینان z؛ برای ۹۹٪ یک‌طرفه در توزیع نرمال، z حدود 2.326 است.

اگر زیان ۹۹ درصدی موجودی Q در افق h برابر z × σ_h × Q × P باشد، سقف موجودی:

Q_max = L / (z × σ_h × P)

این شهود Value at Risk (VaR) است: زیانی که با احتمال ۹۹٪ از آن بیشتر نمی‌شود، با فرض توزیع نرمال. با نوسان روزانه فرضی ۳٪ برای BTC و افق یک ساعت (همان ۰.۶۱٪ درس ۲۱):

Q_max = 1,000 / (2.326 × 0.61% × 100,000) ≈ 0.70 BTC

حالا ضعف‌های این عدد را صادقانه ببینیم:

  • دم‌های پهن: در درس ۹ دیدیم بازده رمزارز دم‌های پهن‌تری از توزیع نرمال دارد. زیان واقعی ۹۹ درصدی از فرمول بیشتر است.
  • نوسان ثابت نیست: درست وقتی موجودی گیر کرده، نوسان معمولاً بالاست. برای همین سقف را با نوسان تحت فشار (Stressed Volatility) حساب می‌کنند. با دو برابر نوسان، سقف نصف می‌شود: حدود 0.35 BTC. یعنی موجودی 0.5 BTC که از درس ۲۱ با آن کار کردیم، با این معیار باید زودتر هج می‌شد.
  • افق کش می‌آید: وقتی نقدشوندگی می‌رود، بستن یک ساعته چهار ساعت طول می‌کشد و σ_h دو برابر می‌شود.
  • VaR درباره ۱٪ باقی‌مانده ساکت است. نمی‌گوید در بدترین روزها زیان ۱,۲۰۰ دلار است یا ۱۲,۰۰۰. معیارهایی مثل Expected Shortfall (میانگین زیان در همان دم ۱٪) این را بهتر نشان می‌دهند، ولی آن‌ها هم به مدل وابسته‌اند.
  • جهش قیمت: هیچ سقفی جلوی زیان یک جهش ناگهانی قیمت را روی موجودی فعلی نمی‌گیرد؛ فقط اندازه آن را محدود می‌کند.

۳. محدودیت نرم و سخت

اگر سیستم فقط یک سقف داشته باشد، رفتارش ناپیوسته می‌شود: تا لحظه‌ای عادی نقل قول می‌دهد و ناگهان همه‌چیز متوقف می‌شود. بهتر است چند پله داشته باشی که هر کدام واکنش تندتری دارند:

ناحیه (درصد از Q_max)نوعواکنش سیستم
تا ۵۰٪عادیSkew معمول درس ۶
۵۰٪ تا ۸۰٪نرمSkew تندتر، حجم کمتر در سمتی که موجودی را بالا می‌برد، شروع هج با باند درس ۲۱
۸۰٪ تا ۱۰۰٪نرمتوقف کامل نقل قول در سمت افزایشی، فقط سفارش‌هایی که موجودی را کم می‌کنند
بالای ۱۰۰٪سختلغو همه سفارش‌های افزایشی، هج یا بستن فوری تا زیر محدودیت نرم، هشدار به انسان

محدودیت نرم رفتار استراتژی را تغییر می‌دهد و خودش ممکن است گاهی رد شود. محدودیت سخت هرگز نباید رد شود؛ پس باید قبل از ارسال سفارش بررسی شود، نه بعد از پر شدن.

یک نکته مهندسی که زیاد اشتباه می‌شود: بررسی سخت باید بدترین حالت را ببیند، یعنی موجودی فعلی به‌اضافه همه سفارش‌های باز در همان جهت:

Worst-case Inventory = Inventory + Σ open buy orders

اگر موجودی 0.5 BTC است و 0.3 BTC سفارش خرید باز در دفتر داری، بدترین حالت 0.8 BTC است. با سقف سخت 0.70، حتی سفارش‌هایی که الان باز هستند از سقف عبور می‌کنند و سفارش خرید تازه نباید ثبت شود. یک موج فروش می‌تواند همه آن‌ها را در چند میلی‌ثانیه پر کند، قبل از اینکه سیستم فرصت لغو داشته باشد.

سقف موجودی تنها محدودیت نیست. یک موتور ریسک معمولاً این‌ها را هم دارد:

  • حداکثر اندازه هر سفارش: در برابر خطای انسانی یا باگ (Fat Finger).
  • سقف زیان روزانه: اگر زیان روز از حدی گذشت، استراتژی متوقف شود تا یک انسان بررسی کند.
  • سقف تعداد سفارش باز و نرخ ارسال: هم برای قوانین صرافی، هم در برابر حلقه‌های معیوب در کد.
  • سقف ارزش هر صرافی: که در بخش ۵ به آن می‌رسیم.

توقف خودکار کل سیستم وقتی یکی از این‌ها نقض شود، موضوع درس ۲۷ (Kill Switch و Circuit Breaker) است.

۴. تخصیص سرمایه و بودجه ریسک

بازارسازی روی چند جفت‌ارز و چند صرافی، سرمایه را در جاهای مختلف قفل می‌کند:

  • موجودی دو طرف: برای نقل قول خرید و فروش در Spot، هم USDT لازم داری و هم خود دارایی، در هر صرافی جداگانه.
  • وجه تضمین هج: در صرافی Perp، با بافری که در بخش ۶ حساب می‌کنیم.
  • ذخیره متعادل‌سازی: موجودی در گردش بین صرافی‌ها (درس ۲۳).

اشتباه رایج این است که سرمایه را مساوی بین جفت‌ارزها تقسیم کنیم. چیزی که باید تقسیم شود بودجه ریسک است: به هر جفت‌ارز سهمی از زیان قابل تحمل بده و سقف موجودی‌اش را با فرمول بخش ۲ از آن دربیاور. جفت‌ارزی که نوسان بیشتری دارد یا دیرتر بسته می‌شود، با همان بودجه ریسک، سقف کوچک‌تری می‌گیرد.

ریسک‌ها با هم جمع نمی‌شوند، ولی تقریباً جمع می‌شوند

اگر سه جفت‌ارز داری که هر کدام بودجه ۱,۰۰۰ دلار دارند، ریسک سبد برابر ۳,۰۰۰ دلار نیست. ریسک سبد به همبستگی بستگی دارد. با v_i به‌عنوان انحراف معیار PnL هر موقعیت به دلار و ρ_ij همبستگی‌ها:

σ_portfolio = √( Σ_i Σ_j v_i × v_j × ρ_ij )

مشکل اینجاست که در رمزارز همبستگی‌ها بالاست و در سقوط‌ها به یک نزدیک می‌شوند. سه جفت‌ارز Long در عمل یک موقعیت بزرگ BTC است. برای همین علاوه بر سقف هر جفت‌ارز، یک سقف کل روی مواجهه معادل BTC هم لازم است: موقعیت هر دارایی ضربدر β آن نسبت به BTC (همان β درس ۲۱)، جمع روی همه دارایی‌ها.

۵. ریسک تمرکز

تمرکز فقط در دارایی نیست:

  • تمرکز دارایی: همان بحث بالا؛ تنوع ظاهری بین آلت‌کوین‌هایی که همه با BTC حرکت می‌کنند.
  • تمرکز صرافی: هر دلاری که در یک صرافی است، طلب تو از آن صرافی است (درس ۲۳). سقف درصدی برای سرمایه در هر صرافی، اندازه بدترین سناریو، یعنی توقف برداشت یا ورشکستگی، را محدود می‌کند.
  • تمرکز در دارایی مبنا: اگر همه نقل قول‌ها به USDT است، کل سرمایه در معرض ریسک همان یک استیبل‌کوین است.
  • تمرکز در نقدشوندگی: اگر سقف موجودی تو با کل عمق دفتر سفارش قابل مقایسه است، افق بستن واقعی خیلی بیشتر از فرض تو است، چون خودت قیمت را جابه‌جا می‌کنی (درس ۴).

۶. بافر وجه تضمین

در درس ۲۲ دیدیم Short با اهرم ۱۰ با ۹.۵٪ افزایش قیمت Liquidate می‌شود. برای هج، سؤال را برعکس می‌پرسیم: چقدر وجه تضمین لازم است تا موقعیت هج یک حرکت فرضی s را بدون Liquidation تحمل کند؟ برای Short با ارزش N و نرخ نگهداری m، بعد از افزایش s زیان N × s است و حد نگهداری روی ارزش جدید N × (1 + s) حساب می‌شود:

Margin ≥ N × (s + m × (1 + s))

بافر کافی یعنی اهرمی که واقعاً استفاده می‌کنی، خیلی کمتر از اهرمی است که صرافی اجازه می‌دهد. در عمل چیزهای دیگری هم به آن اضافه می‌شود: Funding منفی که دارایی حساب را آرام‌آرام کم می‌کند، و زمانی که انتقال وجه از صرافی دیگر طول می‌کشد.

۷. یک مثال کامل در Python

همه را کنار هم بگذاریم: سه جفت‌ارز با نوسان و افق بستن متفاوت، بودجه ریسک ۱,۰۰۰ دلار برای هر کدام، ضریب فشار دو برابر نوسان، بررسی ریسک سبد، و بافر وجه تضمین برای هج BTC. همه اعداد فرضی‌اند.

import numpy as np

z99 = 2.326                     # one-sided 99% quantile of the normal distribution
loss_budget = 1_000             # max tolerated loss per pair over the unwind horizon (USDT)
stress = 2.0                    # size for twice the normal volatility

# All numbers are hypothetical
pairs = ["BTC", "ETH", "ALT"]
daily_vol = np.array([0.03, 0.04, 0.08])
unwind_hours = np.array([1, 1, 4])          # time needed to flatten at acceptable cost
corr = np.array([[1.00, 0.85, 0.70],
                 [0.85, 1.00, 0.75],
                 [0.70, 0.75, 1.00]])

# Per-pair limit: z * sigma_h * stress * notional = loss_budget
sigma_h = daily_vol * np.sqrt(unwind_hours / 24)
limit = loss_budget / (z99 * sigma_h * stress)
for p, s, l in zip(pairs, sigma_h, limit):
    print(f"{p}: sigma over unwind {s:.2%}, limit {l:>7,.0f} USDT")

# Portfolio check: everything at its limit, all long, 1-day horizon
pos = limit
vol_usd = pos * daily_vol                    # 1-day 1-sigma PnL of each position
var_sum = z99 * vol_usd.sum()                # if correlation were 1
var_port = z99 * np.sqrt(vol_usd @ corr @ vol_usd)
var_indep = z99 * np.sqrt((vol_usd ** 2).sum())
print(f"1-day 99% VaR: corr=1 {var_sum:,.0f} | with corr {var_port:,.0f} | independent {var_indep:,.0f}")

# Margin buffer for a perp hedge of the BTC limit: survive a 20% adverse move
mm_rate, shock = 0.005, 0.20
buffer = limit[0] * (shock + mm_rate * (1 + shock))
print(f"BTC hedge margin to survive {shock:.0%}: {buffer:,.0f} USDT "
      f"(effective leverage {limit[0] / buffer:.1f}x)")
BTC: sigma over unwind 0.61%, limit  35,103 USDT
ETH: sigma over unwind 0.82%, limit  26,327 USDT
ALT: sigma over unwind 3.27%, limit   6,582 USDT
1-day 99% VaR: corr=1 6,124 | with corr 5,692 | independent 3,674
BTC hedge margin to survive 20%: 7,231 USDT (effective leverage 4.9x)

سه برداشت از این خروجی:

  1. سقف‌ها خیلی متفاوت‌اند. BTC حدود 35,100 دلار (حدود 0.35 BTC) می‌گیرد و ALT فقط حدود 6,600 دلار؛ با اینکه بودجه ریسک هر دو یکی است. نوسان روزانه حدود ۲.۷ برابر و افق بستن چهار برابر (که σ_h را با ضریب √4 یعنی دو برابر دیگر بالا می‌برد)، سقف ALT را حدود ۵.۳ برابر کوچک‌تر کرده است.
  2. تنوع تقریباً هیچ کمکی نمی‌کند. با همبستگی‌های فرضی ۰.۷ تا ۰.۸۵، VaR سبد فقط ۷٪ از حالت همبستگی کامل کمتر است. اگر فرض استقلال می‌کردیم (۳,۶۷۴)، ریسک را به‌شدت دست‌کم می‌گرفتیم.
  3. افق است که همه‌چیز را تعیین می‌کند. سقف‌ها برای بستن در یک تا چهار ساعت تنظیم شده‌اند. اگر صرافی قطع شود و سیستم یک روز کامل با موجودی در سقف گیر کند، VaR روزانه حدود ۵,۷۰۰ دلار است؛ تقریباً شش برابر بودجه هر جفت‌ارز، و این هنوز با نوسان عادی و توزیع نرمال است.

برای هج BTC هم، تحمل حرکت ۲۰ درصدی حدود ۷,۲۰۰ دلار وجه تضمین می‌خواهد؛ یعنی اهرم مؤثر حدود ۵، هر قدر هم که صرافی اجازه اهرم بالاتر بدهد.

۸. تمرین این درس

گزینه مناسب هر سؤال را انتخاب کن و در پایان نتیجه را ببین.

سؤال ۱: تحمل زیان ۲,۰۰۰ دلار، z برابر 2.326، نوسان در افق بستن ۰.۵٪ و قیمت 100,000 است. سقف موجودی تقریباً چقدر است؟
سؤال ۲: موجودی 0.5 BTC است، 0.3 BTC سفارش خرید باز داری و سقف سخت 0.7 BTC است. سیستم با یک سفارش خرید تازه 0.1 BTC چه باید بکند؟
سؤال ۳: چرا جمع سقف‌های جداگانه چند آلت‌کوین، ریسک واقعی سبد را خوب نشان نمی‌دهد؟
سؤال ۴: Short با ارزش 50,000 دلار برای هج داری و می‌خواهی حرکت ۳۰ درصدی را بدون Liquidation تحمل کنی. نرخ نگهداری ۰.۵٪ است. حداقل وجه تضمین چقدر است؟

درس بعدی

بخش ششم اینجا تمام می‌شود و از درس ۲۵ وارد بخش هفتم، Production و کنترل ریسک، می‌شویم. درس ۲۵ درباره Asyncio و معماری Trading System است: چطور در Python چند جریان داده بازار، مدیریت سفارش، Hedger و بررسی‌های ریسک همین درس را هم‌زمان در یک Event Loop اجرا کنیم، بی‌آنکه یک بخش کند بقیه را متوقف کند، و این اجزا را چطور از هم جدا کنیم که هر کدام جداگانه قابل آزمون باشند.

این مطلب صرفاً آموزشی است و توصیه خرید، فروش یا سرمایه‌گذاری نیست.