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

مسیر Quant Developer · بخش ۲: اقتصاد و ریسک Market Making · درس ۵

Fair Value و قیمت‌گذاری

ارزش منصفانه چیست، چرا آخرین قیمت معامله و حتی Mid Price تخمین کاملی از آن نیستند، و بازارساز چطور قیمت‌هایش را دور Fair Value می‌چیند.

سطح: متوسط۱۲ دقیقه مطالعه

۱. سؤال اول بازارساز: «همین الان این دارایی چقدر می‌ارزد؟»

در چهار درس اول دیدیم بازار چطور کار می‌کند: دفتر سفارش، صف، Maker و Taker، و جریان سفارش‌ها. از این درس وارد بخش دوم مسیر می‌شویم: اقتصاد Market Making؛ یعنی چرا یک استراتژی پول درمی‌آورد یا پول از دست می‌دهد.

همه‌چیز از یک عدد شروع می‌شود: Fair Value یا ارزش منصفانه. Fair Value بهترین تخمین تو از قیمتی است که دارایی «باید» همین الان با آن معامله شود؛ به زبان دقیق‌تر، انتظار تو از قیمت در آینده نزدیک با توجه به همه اطلاعاتی که داری. این عدد را هیچ‌جا نمی‌بینی. باید آن را تخمین بزنی.

چرا این‌قدر مهم است؟ چون هر سفارش بازارساز در واقع یک شرط نسبت به Fair Value است:

Buy Edge = Fair Value − Bid Price
Sell Edge = Ask Price − Fair Value

اگر Fair Value واقعاً 100,000 باشد و تو در 99,990 بخری، به‌طور متوسط ۱۰ دلار به ازای هر بیت‌کوین جلو هستی. اما اگر Fair Value در واقع 99,980 بوده و تو خبر نداشتی، همان خرید ۱۰ دلار زیان انتظاری دارد. پس کیفیت تخمین Fair Value مستقیماً روی سود و زیان می‌نشیند. در درس اول هم دیدیم «Pricing Engine» اولین جزء منطقی سیستم بعد از دریافت داده است.

برای تخمین Fair Value سه کاندیدای ساده داریم: آخرین قیمت معامله، Mid Price و Microprice. هر سه را روی همان دفتر سفارش درس اول بررسی می‌کنیم:

قیمت (USDT) حجم (BTC)
100,030 0.9
100,020 0.5
100,010 0.3
اسپرد 20 USDT
99,990 0.4
99,980 0.7
99,970 1.2
دفتر سفارش نمایشی BTC/USDT: سفارش‌های فروش (Ask) بالا، سفارش‌های خرید (Bid) پایین. بهترین قیمت‌ها پررنگ شده‌اند.

۲. آخرین قیمت معامله: عددی که همه می‌بینند

Last Price یا آخرین قیمت معامله همان عددی است که روی نمودارها و صفحه اول اپلیکیشن صرافی می‌بینی. ساده و در دسترس است، ولی برای قیمت‌گذاری انتخاب بدی است.

فرض کن دفتر سفارش بالا هیچ تغییری نکند و فقط چهار معامله کوچک پشت سر هم انجام شود:

معاملهسمت Takerقیمت معامله (Last Price)Mid Price
۱فروش (به Bid می‌خورد)99,990100,000
۲خرید (از Ask برمی‌دارد)100,010100,000
۳خرید100,010100,000
۴فروش99,990100,000

آخرین قیمت مدام ۲۰ دلار بالا و پایین می‌پرد، در حالی که هیچ اطلاع تازه‌ای درباره ارزش دارایی وارد بازار نشده است. فقط Taker گاهی خریدار بوده و گاهی فروشنده. به این پدیده Bid-Ask Bounce می‌گویند. یکی از نتایجش این است که تغییرات پیاپی Last Price همبستگی منفی دارند؛ Richard Roll در سال ۱۹۸۴ از همین همبستگی منفی برای تخمین Spread فقط از روی قیمت معاملات استفاده کرد.

دو مشکل دیگر هم هست:

  • کهنگی: در بازار کم‌معامله، آخرین معامله ممکن است چند دقیقه پیش انجام شده باشد و دیگر چیزی درباره وضعیت فعلی نگوید.
  • معاملات بزرگ: در درس سوم دیدیم یک خرید Market به حجم 1 BTC آخرین تکه‌اش را در 100,030 پر کرد. آن عدد یک لحظه Last Price است، ولی فقط نشان می‌دهد یک نفر عجله داشت.

۳. Mid Price: بهتر، ولی کور نسبت به حجم

Mid Price را در درس دوم دیدیم: میانگین Best Bid و Best Ask. نسبت به Last Price سه مزیت دارد: از هر دو طرف دفتر استفاده می‌کند، با هر تغییر دفتر به‌روز می‌شود (نه فقط با معامله)، و Bid-Ask Bounce ندارد. در جدول بالا Mid در تمام مدت 100,000 ماند.

ضعف Mid این است که حجم را نمی‌بیند. دو دفتر سفارش را مقایسه کن که هر دو Best Bid برابر 99,990 و Best Ask برابر 100,010 دارند:

حجم Best Bidحجم Best AskMid
دفتر A (دفتر درس ۱)0.40.3100,000
دفتر B5.00.05100,000

در دفتر B فقط 0.05 BTC در 100,010 مانده است. کافی است یک خریدار کوچک بیاید تا این سطح تمام شود و Best Ask به 100,020 برسد؛ در حالی که برای پایین بردن Best Bid باید ۵ بیت‌کوین فروش بیاید. احتمال اینکه قدم بعدی قیمت رو به بالا باشد خیلی بیشتر است. Mid هر دو دفتر را یکسان می‌بیند.

۴. Microprice: وزن دادن به حجم

راه ساده برای دیدن این عدم توازن، Order Book Imbalance است: چه سهمی از حجم بالای دفتر در سمت خرید است؟

I = Bid Size / (Bid Size + Ask Size)

با این عدد، میانگین وزنی Bid و Ask را می‌سازیم. به این تخمین Microprice (یا Size-Weighted Mid) می‌گویند:

Microprice = I × Ask + (1 − I) × Bid

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

Microprice = Mid + Spread × (I − 0.5)

برای دفتر درس ۱: حجم Bid برابر 0.4 و حجم Ask برابر 0.3 است؛ پس I = 0.4 / 0.7 ≈ 0.571 و:

Microprice = 100,000 + 20 × (0.571 − 0.5) ≈ 100,001.43

برای دفتر B، I = 5 / 5.05 ≈ 0.990 و Microprice ≈ 100,009.80؛ یعنی تقریباً روی Ask.

Last Price (اگر آخرین Taker خریدار بود)
100,010
Mid Price
100,000
Order Book Imbalance
0.571
Microprice
100,001.43

Microprice هم بی‌عیب نیست:

  • فقط سطح اول را می‌بیند. نسخه‌های کامل‌تر چند سطح دفتر را با وزن کمتر وارد می‌کنند.
  • فریب‌پذیر است. سفارش بزرگی که فقط برای نمایش ثبت و بعد لغو می‌شود (Spoofing) می‌تواند Imbalance را جابه‌جا کند.
  • رابطه حجم و حرکت قیمت ثابت نیست. اینکه Imbalance واقعاً حرکت بعدی را پیش‌بینی کند، یک فرض است که باید روی داده آزموده شود.

در عمل Fair Value اغلب ترکیبی از چند منبع است: Microprice، قیمت همان دارایی در بازارهای دیگر، قیمت قرارداد آتی (درس ۲۲ و ۲۳) و جریان معاملات اخیر (درس ۴). ولی اسکلت همه آن‌ها همین است: یک عدد که از Mid «هوشمندتر» باشد.

۵. قیمت‌گذاری دور Fair Value

وقتی Fair Value را داری، ساده‌ترین قاعده قیمت‌گذاری این است که با فاصله مساوی دو طرفش قیمت بدهی:

Bid = Fair Value − Half Spread
Ask = Fair Value + Half Spread

با Microprice دفتر درس ۱ و نیم‌اسپرد ۱۰ دلار:

Bid = 100,001.43 − 10 = 99,991.43
Ask = 100,001.43 + 10 = 100,011.43

این قیمت‌ها روی شبکه قیمت مجاز نیستند. با Tick Size فرضی ۱ دلار (همان فرض کد درس ۳) باید گرد شوند. قاعده محافظه‌کارانه این است که همیشه به نفع خودت گرد کنی: Bid رو به پایین و Ask رو به بالا. نتیجه: خرید در 99,991 و فروش در 100,012.

حالا ببین چه شد:

  • خرید ما در 99,991 بالاتر از Best Bid فعلی (99,990) است؛ پس Best Bid جدید و نفر اول صف می‌شویم (همان «راه میان‌بر» درس ۳).
  • فروش ما در 100,012 پشت Best Ask (100,010) می‌نشیند و احتمال پر شدنش کمتر است.

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

دو محافظ همیشه لازم است:

  1. عبور نکردن از طرف مقابل. اگر Fair Value ناگهان جهش کند، ممکن است Bid محاسبه‌شده به Best Ask برسد یا از آن بگذرد. در این حالت سفارش Taker می‌شود یا با Post-Only رد می‌شود (درس ۳). سیستم باید این حالت را تشخیص دهد، نه اینکه کورکورانه سفارش بفرستد.
  2. تازه بودن Fair Value. اگر Fair Value با تأخیر به‌روز شود، قیمت‌هایت به یک عدد کهنه گره خورده‌اند و معامله‌گرهای سریع‌تر دقیقاً همان‌ها را برمی‌دارند. این موضوع درس ۸ است.

۶. در کد: Mid، Microprice و قیمت‌گذاری

اول همان محاسبه‌های بالا:

import math

def mid(bid, ask):
    return (bid + ask) / 2

def microprice(bid, ask, bid_size, ask_size):
    """Size-weighted mid: leans toward the side with LESS size."""
    imbalance = bid_size / (bid_size + ask_size)
    return imbalance * ask + (1 - imbalance) * bid

def quotes(fair_value, half_spread, tick=1):
    """Quote around fair value; round bid down and ask up to the tick grid."""
    bid = math.floor((fair_value - half_spread) / tick) * tick
    ask = math.ceil((fair_value + half_spread) / tick) * tick
    return bid, ask

# Top of the lesson-1 book: 99,990 x 0.4 | 100,010 x 0.3
fv = microprice(99_990, 100_010, 0.4, 0.3)
print(mid(99_990, 100_010))   # 100000.0
print(round(fv, 2))           # 100001.43
print(quotes(fv, 10))         # (99991, 100012)

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

import numpy as np

rng = np.random.default_rng(7)
n = 10_000

# Hidden "true" value: a random walk around 100,000 (synthetic, not real data)
value = 100_000 + np.cumsum(rng.normal(0, 3, n))

# Book on a 10-USDT grid with a 20-USDT spread that contains the true value
bid = np.round(value / 10) * 10 - 10
ask = bid + 20

# Assumption of this toy world: the closer value is to the ask,
# the heavier the bid queue (size imbalance carries information)
pos = (value - bid) / 20                      # 0.25 .. 0.75
bid_size = np.clip(pos + rng.normal(0, 0.1, n), 0.05, None)
ask_size = np.clip(1 - pos + rng.normal(0, 0.1, n), 0.05, None)

mid = (bid + ask) / 2
imb = bid_size / (bid_size + ask_size)
micro = imb * ask + (1 - imb) * bid
# Each trade hits the bid or lifts the ask at random
last = np.where(rng.random(n) < 0.5, bid, ask)

for name, est in [("last", last), ("mid", mid), ("micro", micro)]:
    rmse = np.sqrt(np.mean((est - value) ** 2))
    print(f"{name:6s} RMSE vs true value: {rmse:5.2f} USDT")

خروجی:

last   RMSE vs true value: 10.41 USDT
mid    RMSE vs true value:  2.88 USDT
micro  RMSE vs true value:  1.52 USDT

RMSE یا ریشه میانگین مربع خطا، فاصله معمول هر تخمین از ارزش واقعی است. خطای Last Price تقریباً برابر نیم‌اسپرد (۱۰ دلار) است؛ یعنی Bid-Ask Bounce بر آن غالب است. Mid خطا را به حدود ۲.۹ دلار می‌رساند و Microprice تقریباً نصف آن.

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

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

سؤال ۱: Best Bid برابر 99,990 با حجم 0.2 و Best Ask برابر 100,010 با حجم 0.6 است. Microprice چقدر است؟
سؤال ۲: چرا آخرین قیمت معامله مبنای خوبی برای قیمت‌گذاری بازارساز نیست؟
سؤال ۳: Fair Value برابر 100,004.6، نیم‌اسپرد 8 دلار و Tick Size برابر 1 دلار است. با گرد کردن محافظه‌کارانه، قیمت‌های خرید و فروش چه می‌شوند؟
سؤال ۴: حجم Best Bid خیلی بیشتر از حجم Best Ask است. Microprice نسبت به Mid کجاست؟

درس بعدی

در درس ششم سراغ اولین ریسک واقعی بازارساز می‌رویم: Inventory Risk. وقتی فقط یک طرف سفارش‌هایت پر می‌شود و موجودی جمع می‌کنی، هر حرکت قیمت مستقیماً سود و زیانت را جابه‌جا می‌کند. خواهیم دید چطور با Skew کردن همین قیمت‌های دور Fair Value، موجودی را کنترل کنیم.

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