التنفيذ ليس يقينًا
يفترض الاختبار الساذج أن أمرًا بأي حجم يُنفَّذ بالسعر الموجود في البيانات. وتواجه الأوامر الحقيقية ثلاثة أسئلة. ما عمق الدفتر: أمر السوق يأخذ أفضل عرض أولًا ثم التالي، فيدفع الأمر الكبير متوسط سعر أسوأ. وهل بلغ السوق حدّي: الأمر المحدد يحصل على السعر المطلوب أو أفضل، لكن فقط إن بلغه التداول. وكم أستطيع أن آخذ: الأمر الكبير لا يمكن أن يكون إلا جزءًا من حجم الشمعة، فيُنفَّذ على أجزاء عبر الزمن.
def fill_market_order(book, quantity):
remaining = quantity
cost = 0.0
filled = 0
for price, size in book: # cheapest offer first
if remaining <= 0:
break
take = min(size, remaining)
cost += take * price
filled += take
remaining -= take
if filled == 0:
return 0.0, 0
return cost / filled, filled
book = [(50.00, 300), (50.02, 500), (50.05, 1000)]
print(fill_market_order(book, 200)) # (50.0, 200) inside the first level
print(fill_market_order(book, 600)) # (50.01, 600) 300 at 50.00 and 300 at 50.02
print(fill_market_order(book, 5000)) # (50.0333, 1800) the whole book; 3,200 shares stay unfilled# The average price and the slippage against the best offer grow with the size
def average_price(book, quantity):
remaining, cost, filled = quantity, 0.0, 0
for price, size in book:
take = min(size, remaining)
cost += take * price
filled += take
remaining -= take
return cost / filled
book = [(50.00, 300), (50.02, 500), (50.05, 1000)]
for quantity in (100, 300, 800, 1800):
avg = average_price(book, quantity)
print(quantity, round(avg, 4), round((avg - 50.00) / 50.00 * 10000, 2), "bps above the best offer")الأوامر المحددة والفجوات
مع بيانات الشموع (الافتتاح والأدنى والأعلى) لا ترى المسار داخل الشمعة بل أطرافه فقط. أمر شراء محدد عند L يُنفَّذ إن بلغ أدنى الشمعة L أو أقل. والسعر L إلا إذا افتتحت الشمعة دون L: فقد قفز السوق فوق حدّك فتُنفَّذ عند الافتتاح وهو أفضل. وأمر البيع المحدد صورته المعكوسة. والأمر المحدد الذي لُمس فقط قد لا يُنفَّذ في الواقع لأن الطابور أمامك خُدم أولًا، فهذا هو الحد المتفائل.
def limit_fill(side, limit, bar_open, bar_low, bar_high):
if side == "buy" and bar_low <= limit:
return min(bar_open, limit) # a gap below the limit fills at the better open
if side == "sell" and bar_high >= limit:
return max(bar_open, limit)
return None
print(limit_fill("buy", 49.95, 50.10, 49.90, 50.20)) # 49.95 traded down through the limit
print(limit_fill("buy", 49.95, 49.90, 49.80, 50.20)) # 49.9 opened below: filled at the open
print(limit_fill("buy", 49.95, 50.10, 50.00, 50.20)) # None never reached
print(limit_fill("sell", 50.15, 50.00, 49.90, 50.20)) # 50.15تنفيذ أمر كبير
تستخدم كثير من مكاتب التنفيذ حد المشاركة: ألا تأخذ أكثر من 10% مثلًا من الحجم. وفي شمعة جرى فيها تداول 40,000 سهم يكون ذلك 4,000 مقربة للأسفل. فيستغرق أمر بـ5,000 سهم شمعتين لا شمعة. والمرور على الشموع حلقة تحمل الكمية المتبقية: كل شمعة تنفّذ min(remaining, int(volume * participation))، والشموع بعد اكتمال الأمر لا تنفّذ شيئًا.
def partial_fill(quantity, bar_volume, participation):
return min(quantity, int(bar_volume * participation))
def fill_over_bars(quantity, volumes, participation):
remaining = quantity
fills = []
for volume in volumes:
filled = partial_fill(remaining, volume, participation)
fills.append(filled)
remaining -= filled
return fills
fills = fill_over_bars(5000, [40000, 30000, 80000, 100000], 0.1)
print(fills, sum(fills)) # [4000, 1000, 0, 0] 5000- يعبر أمر السوق الدفتر مستوى بعد مستوى؛ ومتوسط السعر مرجح بالحجم ويسوء مع الحجم، والدفتر الرقيق ينفّذ جزءًا فقط.
- يُنفَّذ الأمر المحدد إن بلغت الشمعة الحد، وعند الافتتاح إن قفزت فوقه؛ واللمس وحده قد لا يُنفَّذ في الواقع.
- تحدّ سقوف المشاركة كل شمعة بـ
int(volume * participation)؛ وحلقة تحمل الكمية المتبقية عبر الشموع.
التالي: نموذج تسعير الأصول الرأسمالية وبيتا، قياس ما يأتي من العائد من السوق.
المختبر: ما الذي يُقيَّم
- اعبر دفتر الأوامر باستخدام
fill_market_order25 نقطة - قرّر هل بُلغ الحد باستخدام
limit_fill25 نقطة - احترم الحجم باستخدام
partial_fill25 نقطة - نفّذ الأمر عبر الزمن باستخدام
fill_over_bars25 نقطة