كسب الفارق وتحمّل المخاطرة
يعرض صانع السوق سعر شراء وسعر بيع وينتظر. وحين يضرب بائع سعر الشراء ويأخذ مشترٍ سعر البيع يشتري الصانع رخيصًا ويبيع غاليًا ويحتفظ بـالفارق. هذا هو الدخل. والكلفة مخاطر المخزون: ففي ما بين الصفقتين يحمل الصانع مركزًا تتحرك قيمته مع السعر، وينفَّذ عليه في الغالب من يعرف أكثر (الانتقاء المعاكس) لا من لا يعرف. وصناعة السوق الجيدة توازن بين أسعار ضيقة بما يكفي لتُصاب كثيرًا وواسعة بما يكفي لتعوّض المخاطرة، مع إبقاء المخزون قرب الصفر.
# The income: buy at the bid, sell at the ask, keep the spread
bid, ask, size = 99.95, 100.05, 100
cash = -bid * size + ask * size
print(round(cash, 2)) # 10.0 a round trip of 100 shares earned the 0.10 spread
# The risk: between the two trades the price moves against the inventory
inventory, mid_after = 100, 99.80
print(round(inventory * (mid_after - bid), 2)) # -15.0 the position lost more than the spread would have earnedAvellaneda-Stoikov: أين نسعّر
يقدم نموذج أفيلانيدا-ستويكوف جوابًا بصيغة مغلقة. أولًا سعر الاحتياط r = mid - q * gamma * sigma^2 * tau هو المكان الذي يسعد الصانع بالتداول عنده بحسب المخزون q: الصانع الطويل (q > 0) ينبغي أن يقيّم الأصل دون السعر الوسطي ويسعّر أدنى لجذب المشترين، والقصير يسعّر أعلى. وتحدد النفور من المخاطرة gamma والتقلب sigma والزمن المتبقي tau مقدار الميل. ثانيًا الفارق الأمثل gamma * sigma^2 * tau + (2 / gamma) * ln(1 + gamma / k) من جزأين: رسم لمخاطرة حمل المركز حتى الأفق وحدٌّ لتدفق الأوامر حيث تقول k مدى سرعة جفاف التنفيذات كلما بعدت عن السعر الوسطي. والأسعار المعلنة r - spread/2 وr + spread/2.
# The reservation price leans against inventory: long -> quote lower, short -> quote higher
def reservation_price(mid, inventory, gamma, sigma, tau):
return mid - inventory * gamma * sigma ** 2 * tau
for inventory in (-50, 0, 50):
print(inventory, round(reservation_price(100.0, inventory, 0.1, 0.2, 1.0), 4))
# -50 100.2 short: quote higher to buy back
# 0 100.0 flat: centred on the mid
# 50 99.8 long: quote lower to sell# The optimal spread and the two quotes around the reservation price
import math
def optimal_spread(gamma, sigma, tau, k):
return gamma * sigma ** 2 * tau + (2 / gamma) * math.log(1 + gamma / k)
def make_quotes(mid, inventory, gamma, sigma, tau, k):
centre = mid - inventory * gamma * sigma ** 2 * tau
half = optimal_spread(gamma, sigma, tau, k) / 2
return centre - half, centre + half
print(round(optimal_spread(0.1, 0.2, 1.0, 1.5), 4)) # 1.2948
bid, ask = make_quotes(100.0, 0, 0.1, 0.2, 1.0, 1.5)
print(round(bid, 4), round(ask, 4)) # 99.3526 100.6474 symmetric around the mid when flat
bid, ask = make_quotes(100.0, 50, 0.1, 0.2, 1.0, 1.5)
print(round(bid, 4), round(ask, 4)) # 99.1526 100.4474 long 50: both quotes move down by 0.2المخزون والتنفيذات والأرباح والخسائر
تتبع الحالة برقمين: المخزون والنقد. حين يُضرب سعر الشراء تكون قد اشتريت: يرتفع المخزون وينقص النقد بمقدار price * quantity؛ وحين يؤخذ سعر البيع تكون قد بعت: العكس. وثروتك في أي لحظة هي النقد مضافًا إليه المخزون مقيّمًا بالسعر الوسطي cash + inventory * mid وتغيرها هو أرباحك وخسائرك. وتأتي من الفارق المكتسب ومن حركات السعر أثناء حمل المخزون؛ والتسعير حول سعر الاحتياط يعيد المخزون إلى الصفر لأن الجانب الذي يخفضه يصبح أكثر جاذبية. وللحدود أهمية عملية: سقف صارم للمخزون وتوقف في الأسواق السريعة وتحقق عند كل تسعيرة من أن سعر الشراء دون سعر البيع.
# Booking fills and marking the book to market
def apply_fill(state, side, price, quantity):
inventory, cash = state
if side == "bid":
return inventory + quantity, cash - price * quantity
return inventory - quantity, cash + price * quantity
state = (0, 0.0)
state = apply_fill(state, "bid", 99.95, 100) # our bid is hit: we buy 100
print(state) # (100, -9995.0)
state = apply_fill(state, "ask", 100.05, 100) # our ask is hit: we sell 100
print(state) # (0, 10.0) flat again, and the spread is the profit
inventory, cash = apply_fill(state, "bid", 99.9, 50)
print(round(cash + inventory * 99.9, 2)) # 10.0 marked at the price we just paid, the equity is unchanged- يكسب صانع السوق الفارق لكنه يتحمل مخاطر المخزون والانتقاء المعاكس؛ والهدف: ضيق بما يكفي ليتداول وواسع بما يكفي ليُعوَّض ومخزون قرب الصفر.
- يميل سعر الاحتياط
mid - q * gamma * sigma^2 * tauعكس المخزون؛ ويكبر الفارقgamma * sigma^2 * tau + (2/gamma) ln(1 + gamma/k)مع التقلب المرجّح بنفور المخاطرة والزمن. - تتبع المخزون والنقد وقيّم بالسعر الوسطي وافرض حدود مخزون صارمة واختبر الاستراتيجية في محاكٍ على بيانات مسجلة قبل استعمالها حيًّا.
التالي: نموذج هستون، تقلب هو نفسه عشوائي.
المختبر: ما الذي يُقيَّم
- مِل عكس المخزون باستخدام
reservation_price25 نقطة - حدّد العرض باستخدام
optimal_spread25 نقطة - سعّر الجانبين باستخدام
make_quotes25 نقطة - سجّل تنفيذًا باستخدام
apply_fill25 نقطة