σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft Academyالمسارات
Ctrl K
AO
+1.2k متعلّم
تسجيل الدخولانضم ↗
المسارات
AO
+1.2k متعلّم
تسجيل الدخول
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
مسار Python›الوحدة 11 · أنظمة الإنتاج والنماذج المتقدمة›الموضوع 11.4·~1 سخبير

تنفيذ TWAP

الموضع في المسارالوحدة 11 من 11 · الموضوع 4 من 13
11.4 تنفيذ TWAP
—درجة المختبر— / 100إجمالي XP—التتابع—

لماذا لا نرسله كله دفعة واحدة

اشترِ 200,000 سهم بأمر سوق واحد وستلتهم دفتر الأوامر: تُنفَّذ الأسهم الأولى بأفضل سعر عرض والتالية بسعر أسوأ وهكذا، ويرفع كل من يراك تشتري أسعاره. وهذا الأثر السوقي كلفة حقيقية، غالبًا أكبر من العمولة. وخوارزمية التنفيذ تقطع الأمر إلى أوامر فرعية أصغر تُرسل عبر الزمن ليُمتص كل منها بأثر أقل. وأبسطها TWAP، خوارزمية متوسط السعر المرجّح بالزمن: قسّم الكمية إلى أجزاء متساوية وأرسل جزءًا في كل لحظة من لحظات متباعدة بانتظام بين بداية ونهاية.

# Splitting 10 shares into 3 child orders: whole shares, earlier pieces take the extra
def twap_schedule(total, slices):
    size, extra = divmod(total, slices)
    return [size + (1 if index < extra else 0) for index in range(slices)]

print(twap_schedule(10, 3))                          # [4, 3, 3]
print(twap_schedule(200_000, 8))                     # [25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000]
print(sum(twap_schedule(10_001, 7)))                 # 10001   nothing is lost to rounding

الجدول: كم ومتى

لجدول TWAP جزءان. الأحجام تقسم الإجمالي إلى n قطعة من أسهم صحيحة تختلف بسهم واحد على الأكثر وتجمع الأمر بدقة: تعطي divmod(total, n) الحجم الأساسي وعدد القطع التي تأخذ سهمًا زائدًا. والأوقات هي n وقت بدء متباعدة بانتظام بين البداية والنهاية: start + i * (end - start) / n. وأمر ليوم كامل بـ 200,000 سهم في 40 جزءًا هو 5,000 سهم كل عشر دقائق يرسلها مجدول كالذي في الموضوع السابق. وتُعشوِن التطبيقات الحقيقية الأحجام والأوقات قليلًا لأن النمط المنتظم تمامًا يسهل على الآخرين رصده والتداول ضده.

# When each slice starts: a trading day from 09:30 to 16:00 in 13 half-hour slices (seconds since midnight)
def slice_times(start, end, slices):
    step = (end - start) / slices
    return [start + index * step for index in range(slices)]

times = slice_times(9.5 * 3600, 16 * 3600, 13)
print(times[0], times[1] - times[0])                 # 34200.0 1800.0   09:30 and a slice every 30 minutes
print(times[-1] / 3600)                              # 15.5             the last slice starts at 15:30, the end (16:00) is not a start time

قياسه: متوسط سعر التنفيذ والانزلاق

بعد تنفيذ الأجزاء يكون متوسط سعر التنفيذ هو متوسط أسعار التنفيذ مرجّحًا بالكميات sum(price * quantity) / sum(quantity): التنفيذ الكبير يُحتسب أكثر من الصغير، فالمتوسط البسيط للأسعار خاطئ. ولتقييم النتيجة قارنها بـ سعر الوصول، سعر السوق لحظة اتخاذ القرار. والفرق هو الانزلاق (slippage) ويُعبَّر عنه بـ نقاط الأساس (1 نقطة = 0.01%): في الشراء (المتوسط - الوصول) / الوصول * 10,000 وفي البيع الإشارة المعاكسة فيكون الرقم الموجب كلفة دائمًا. وهذا جوهر نقص التنفيذ (implementation shortfall)، الطريقة المعيارية لتقييم تنفيذ.

# Average fill price (quantity-weighted) and slippage against the arrival price, in basis points
def average_fill_price(fills):
    return sum(price * quantity for price, quantity in fills) / sum(quantity for _, quantity in fills)

def slippage_bps(avg_price, arrival_price, side):
    sign = 1 if side == "buy" else -1
    return sign * (avg_price - arrival_price) / arrival_price * 10000

fills = [(100.0, 400), (100.2, 300), (100.4, 300)]
average = average_fill_price(fills)
print(round(average, 2), sum(price for price, _ in fills) / 3)      # 100.18 100.2   the plain mean of the prices is not the answer
print(round(slippage_bps(average, 100.0, "buy"), 2))                # 18.0   a buy that averaged 100.18 against an arrival of 100.00 cost 18 bp
print(round(slippage_bps(average, 100.0, "sell"), 2))               # -18.0  the same prices would have been a gain for a seller
# A toy run: the price drifts up while we buy 10 slices; the slippage is what the drift cost us
prices = [100.00, 100.03, 100.05, 100.04, 100.08, 100.10, 100.09, 100.12, 100.15, 100.14]     # price at each slice time
pieces = [100] * 10                                                                         # TWAP: equal child orders

arrival = prices[0]
fills = list(zip(prices, pieces))
average = sum(p * q for p, q in fills) / sum(pieces)
print(round(average, 4))                             # 100.08
print(round((average - arrival) / arrival * 10000, 1))      # 8.0   bp of slippage for buying into a rising market
ما يمكن توقعه يمكن استغلالهيتجاهل TWAP السوق: يتداول الكمية نفسها في اللحظات الهادئة والنشطة، وبصمته المنتظمة يمكن التعرف عليها والتقدم عليها. وهو أساس معقول حين لا رأي لك في الحجم وتريد البساطة. والتحسينات هي الموضوع التالي: اتباع منحنى حجم اليوم (VWAP) وتحديد سقف لحصتك من حجم كل فترة وعشونة الأحجام والأوقات والتوقف أو التباطؤ حين يهرب السعر منك. وقارن دائمًا انزلاق الخوارزمية بمرجع بسيط في الأيام نفسها قبل أن تثق بها.
  • الأوامر الكبيرة تحرك السعر؛ وخوارزمية التنفيذ ترسل أوامر فرعية أصغر عبر الزمن. ويرسل TWAP أجزاء متساوية في أوقات متباعدة بانتظام.
  • الأحجام: divmod(total, n) مع الأسهم الزائدة في القطع الأولى؛ الأوقات: start + i * (end - start) / n.
  • قيّم التنفيذ بمتوسط سعره المرجّح بالكميات مقابل سعر الوصول بنقاط الأساس؛ والرقم الموجب كلفة.

التالي: تنفيذ VWAP، اتباع حجم اليوم بدل الساعة.

المختبر: ما الذي يُقيَّم

  • حدّد حجم كل جزء باستخدام twap_schedule25 نقطة
  • وزّع الأجزاء زمنيًا باستخدام slice_times25 نقطة
  • احسب متوسط تنفيذاتك باستخدام average_fill_price25 نقطة
  • سعّر الكلفة باستخدام slippage_bps25 نقطة
المستكشف · lab-133-1
▾ lab-133-1
…
bash · داخل المتصفح
learner@quantcraft:~/lab-133-1$
لم يتم تحميل Python بعدPythonLn 1, Col 1Spaces: 4UTF-8

هل تريد إعادة ضبط هذا الموضوع؟

سيعود كل ما في lab-133-1 إلى الملفات الابتدائية وستُمسح الطرفية. ستفقد حلّك الحالي ولا يمكن التراجع عن ذلك.

سيُعاد ضبطه
  • main.py ← الشيفرة الابتدائية
  • سجل الطرفية ومخرجات الاختبارات
  • التغييرات غير المُرسلة
سيُحتفظ به
  • أفضل درجة في المختبر
  • نقاط XP والتتابع
  • تقدّم المحاضرة والملاحظات

سجّل الدخول لتشغيل الكود الخاص بك.

قراءة كل المحاضرات مجانية. أنشئ حسابًا أو سجّل الدخول لتشغيل الكود وتنفيذ الاختبارات وتسليم هذا المختبر.

  • بيئة تطوير داخل المتصفح مع طرفية bash — لا حاجة لتثبيت أي شيء
  • تصحيح فوري ونقاط خبرة ومكانك في المسار
إنشاء حسابتسجيل الدخول
أو
المتابعة عبر GitHub