مسیر Quant Developer · بخش ۲: اقتصاد و ریسک Market Making · درس ۶
Inventory Risk و Skew
وقتی فقط یک طرف سفارشهای بازارساز پر میشود، موجودی جمع میشود و حرکت قیمت PnL را جابهجا میکند؛ Skew، اندازه نامتقارن و سقف موجودی این ریسک را کنترل میکنند.
۱. وقتی فقط یک طرف پر میشود
در درس اول گفتیم ممکن است سفارش خرید بازارساز پر شود ولی سفارش فروشش نه. در درس پنجم یاد گرفتیم قیمتها را دور Fair Value بچینیم. حالا ببینیم وقتی این قیمتها نامتوازن پر میشوند چه اتفاقی میافتد.
Inventory یا موجودی، مقدار داراییای است که بازارساز در هر لحظه در دست دارد. آن را با q نشان میدهیم: q مثبت یعنی دارایی خریدهای و نگه داشتهای (Long)، q منفی یعنی بیشتر فروختهای تا خریدهای (Short). هر حرکت قیمت، سود و زیان موجودی را اینطور تغییر میدهد:
یک سناریوی ساده با دفتر سفارش درس اول: بازار آرامآرام پایین میرود و فروشندهها سه بار سفارش خرید تو را پر میکنند، هر بار 0.1 BTC. حالا q = 0.3 است. اگر قیمت ۱۰۰ دلار دیگر پایین برود:
برای مقایسه، یک رفتوبرگشت کامل 0.1 BTC با Spread بیستدلاری، پیش از کارمزد ۲ دلار سود دارد (درس ۱). یعنی یک حرکت صددلاری کوچک، درآمد ۱۵ رفتوبرگشت را پاک میکند.
این ریسک با زمان و نوسان بزرگ میشود
اگر قیمت مثل یک گام تصادفی حرکت کند، انحراف معیار سود و زیان موجودی در افق زمانی t تقریباً این است:
که σ نوسان قیمت در هر واحد زمان است. با یک نوسان فرضی ۳۰ دلار در دقیقه و q = 0.3، نوسان PnL در یک دقیقه ۹ دلار و در یک ساعت حدود 0.3 × 30 × √60 ≈ 70 دلار است. بازارسازی که برای درآمد ۲ دلاری هر رفتوبرگشت کار میکند، نمیتواند چنین ریسکی را بیمدیریت رها کند. مفاهیم نوسان و انحراف معیار را در درس ۹ دقیقتر میسازیم.
۲. ایده Skew: قیمتها را برخلاف موجودی جابهجا کن
اگر موجودی مثبت داری، میخواهی احتمال فروش بیشتر و احتمال خرید کمتر شود. راه ساده این است که هر دو قیمت را کمی پایین ببری. فروش ارزانتر جذابتر میشود و خرید پایینتر کمتر پر میشود. به این کار Skew میگویند.
ابتدا یک قیمت مرجع شخصی میسازیم که به آن Reservation Price میگویند؛ قیمتی که با توجه به موجودی فعلی، برایت فرقی نمیکند بخری یا بفروشی:
h همان نیماسپرد درس ۵ است و k ضریب Skew: به ازای هر بیتکوین موجودی، مرکز قیمتهایت چند دلار جابهجا شود. برای سادگی در این درس Fair Value را همان Mid دفتر درس ۱ یعنی 100,000 میگیریم، با h = 10 و k = 50 دلار به ازای هر BTC:
| موجودی q | Reservation Price | Bid | Ask | اثر |
|---|---|---|---|---|
| صفر | 100,000 | 99,990 | 100,010 | متقارن، مثل درس ۱ |
| 0.2 (Long) | 99,990 | 99,980 | 100,000 | فروش داخل Spread و اول صف؛ خرید پشت 0.7 BTC در سطح دوم |
| 0.2 (Short) | 100,010 | 100,000 | 100,020 | برعکس: خرید داخل Spread، فروش عقبتر |
| 0.4 (Long) | 99,980 | 99,970 | 99,990 | فروش به Best Bid رسیده است؛ پایین را ببین |
ردیف آخر یک حالت خرابی واقعی را نشان میدهد. Ask محاسبهشده 99,990 دقیقاً روی Best Bid بازار است؛ چنین سفارشی فوراً بهعنوان Taker معامله میشود (یا اگر Post-Only باشد رد میشود، درس ۳). سیستم باید قیمت را محدود کند، مثلاً Ask را حداقل یک Tick بالای Best Bid، یعنی 99,991 بگذارد، یا آگاهانه تصمیم بگیرد که برای خروج از موجودی Taker شود.
۳. دو ابزار دیگر: اندازه نامتقارن و سقف موجودی
Skew فقط قیمت را جابهجا میکند. دو ابزار مکمل هم داریم:
اندازه نامتقارن (Asymmetric Sizing): وقتی Long هستی، حجم سفارش خرید را کوچک و حجم فروش را بزرگ کن. یک قاعده خطی ساده با اندازه پایه 0.1 BTC و سقف موجودی 0.5 BTC:
با q = 0.3، حجم خرید 0.04 و حجم فروش 0.16 BTC میشود. با q = 0.5 حجم خرید صفر است؛ یعنی قاعده اندازه، خودش سقف موجودی را هم اعمال میکند. (برای q منفی به همین شکل برعکس عمل میکند و در عمل باید حجمها را به بازه مجاز و Lot Size محدود کرد.)
سقف موجودی (Inventory Limit): معمولاً دو لایه دارد:
| لایه | رفتار | مثال فرضی |
|---|---|---|
| سقف نرم | Skew و اندازه نامتقارن شدیدتر میشوند | از 0.3 BTC به بالا |
| سقف سخت | سفارش سمتی که موجودی را بیشتر میکند اصلاً ثبت نمیشود | 0.5 BTC |
| خروج اضطراری | موجودی با سفارش Taker یا ابزار دیگری کم میشود | بالاتر از سقف سخت، مثلاً بعد از یک جهش قیمت |
خروج با Taker یعنی Spread و کارمزد Taker میپردازی؛ هزینهاش را در درس ۷ حساب میکنیم. پوشش ریسک با ابزار دیگر (مثلاً قرارداد آتی) موضوع درس ۲۱ است و تعیین خود سقف بر اساس سرمایه موضوع درس ۲۴.
۴. شبیهسازی: با Skew و بدون Skew
حالا یک آزمایش کنترلشده. فرضهای این دنیای ساختگی:
- Mid یک گام تصادفی بدون روند است: هر گام (مثلاً یک ثانیه) با انحراف معیار ۲ دلار.
- Fair Value همان Mid است و نیماسپرد ۱۰ دلار.
- احتمال پر شدن هر سفارش در هر گام با فاصلهاش از Mid کم میشود:
A × exp(−κ × δ)با A = 0.5 و κ = 0.1. سفارشی با فاصله ۱۰ دلار در هر گام حدود ۱۸٪ شانس پر شدن دارد. - هر سفارش دستکم ۱ دلار با Mid فاصله دارد؛ یعنی Skew هر قدر هم شدید باشد، از وسط Spread عبور نمیکند (همان محافظ بخش ۲).
- هر پر شدن 0.1 BTC است. کارمزد صفر است و پر شدنها هیچ اطلاعاتی درباره قیمت آینده ندارند (فرضی خوشبینانه).
- ۵۰۰ مسیر مستقل، هر کدام ۳,۶۰۰ گام (یک ساعت ثانیهای).
import numpy as np
def simulate(k, paths=500, steps=3_600, seed=42):
"""k = skew in USDT per 1 BTC of inventory. Returns inventory paths and final PnL."""
rng = np.random.default_rng(seed)
h, size, sigma = 10.0, 0.1, 2.0 # half spread, fill size (BTC), mid move per step
A, kappa = 0.5, 0.1 # fill prob = A * exp(-kappa * distance from mid)
mid = np.full(paths, 100_000.0)
q = np.zeros(paths) # inventory in BTC
cash = np.zeros(paths)
q_hist = np.empty((steps, paths))
for t in range(steps):
r = mid - k * q # skewed center of our quotes
bid = np.minimum(r - h, mid - 1) # never cross: stay at least 1 USDT from mid
ask = np.maximum(r + h, mid + 1)
buy = rng.random(paths) < A * np.exp(-kappa * (mid - bid)) # someone sells to us
sell = rng.random(paths) < A * np.exp(-kappa * (ask - mid)) # someone buys from us
q += size * (buy.astype(float) - sell)
cash += size * (sell * ask - buy * bid)
q_hist[t] = q
mid += rng.normal(0, sigma, paths)
pnl = cash + q * mid # mark-to-market at the final mid
return q_hist, pnl
for k in (0, 50):
q_hist, pnl = simulate(k)
print(f"k={k:>2}: inventory std={q_hist[-1].std():.2f} BTC, "
f"max |q|={np.abs(q_hist).max():.1f} BTC, "
f"PnL mean={pnl.mean():.0f}, std={pnl.std():.0f} USDT")
خروجی:
k= 0: inventory std=3.34 BTC, max |q|=13.6 BTC, PnL mean=1316, std=274 USDT
k=50: inventory std=0.09 BTC, max |q|=0.5 BTC, PnL mean=1174, std=32 USDT
- بیشترین موجودی بدون Skew
- 13.6 BTC
- بیشترین موجودی با Skew (k = 50)
- 0.5 BTC
- انحراف معیار PnL بدون Skew
- 274 USDT
- انحراف معیار PnL با Skew
- 32 USDT
چطور این اعداد را بخوانیم:
- بدون Skew، موجودی یک گام تصادفی است. هر پر شدن خرید یا فروش موجودی را 0.1 جابهجا میکند و هیچ نیرویی آن را به صفر برنمیگرداند. انحراف معیارش با جذر زمان رشد میکند و در بدترین مسیر به 13.6 BTC رسید؛ یعنی بیش از یک میلیون دلار ریسک جهتدار برای استراتژیای که قرار بود از Spread درآمد داشته باشد.
- با Skew، موجودی به صفر برمیگردد. در هیچ مسیری از 0.5 BTC بالاتر نرفت، بدون اینکه سقف سختی در کد باشد.
- بها: میانگین PnL حدود ۱۱٪ کمتر شد (1,174 در برابر 1,316)، چون بخشی از معاملات نزدیک Fair Value انجام شد. در عوض پراکندگی PnL بیش از ۸ برابر کم شد. به ازای هر واحد ریسک، استراتژی با Skew بسیار بهتر است.
۵. از قاعده دستی تا مدل
در این درس k یک عدد ثابت و دستی بود. سؤال طبیعی این است: k «درست» چقدر است؟ مدل Avellaneda–Stoikov (۲۰۰۸) دقیقاً همین را رسمی میکند. در آن مدل Reservation Price این شکل را دارد:
که s قیمت میانی، γ ضریب ریسکگریزی، σ² واریانس قیمت و T − t زمان باقیمانده تا پایان افق است. یعنی همان k این درس، در آن مدل برابر γ × σ² × (T − t) است: هرچه بازار پرنوسانتر و تو ریسکگریزتر باشی، Skew شدیدتر است. فرضها، Spread بهینه و محدودیتهای این مدل را در درس ۱۱ کامل بررسی میکنیم و در درس ۱۲ نسخهای با سقف موجودی (Guéant–Lehalle–Fernandez-Tapia) را میبینیم.
۶. تمرین این درس
گزینه مناسب هر سؤال را انتخاب کن و در پایان نتیجه را ببین.
درس بعدی
در این درس سود و زیان را فقط بهصورت «نقد بهعلاوه موجودی ضرب در قیمت» حساب کردیم. در درس هفتم آن را دقیق باز میکنیم: Spread Capture، کارمزد و PnL؛ تفاوت سود ناخالص و خالص، تحققیافته و تحققنیافته، و اینکه چطور کل PnL را به سهم Spread، سهم موجودی و سهم کارمزد تجزیه کنیم.
این مطلب صرفاً آموزشی است و توصیه خرید، فروش یا سرمایهگذاری نیست.