Updating the Volume Curve Intraday: Does Adaptive Forecasting Actually Help?
في TWAP وVWAP وPOV شغّلنا المجدولات الثلاثة وجهًا لوجه على إعادة تشغيل L2 لـ BTCUSDT لمدة 90 يومًا، وتوصلنا إلى نتيجة تركناها عمدًا كجرح مفتوح: في العملات المشفرة، منحنى الحجم هو أضعف حلقة في خط الأنابيب، وليس التقسيم. نشر ذلك المقال النسخة البسيطة عن قصد — منحنى قائم على الوسيط، مشروط بتركيب يوم الأسبوع × وقت اليوم، يعاد ملاءمته أسبوعيًا ويبقى ثابتًا خلال يوم التداول. ووجد أن الميزة الكاملة لـ VWAP على TWAP هي جودة التنبؤ: عند تكييف المقارنة مع خطأ منحنى الحجم المحقق، يتفوق VWAP على TWAP بنحو 4 نقاط أساس في الثلث الأفضل من الأيام من حيث التنبؤ، بينما تنهار الفجوة إلى ضجيج في الثلث الأسوأ.
تستلزم تلك النتيجة متابعة محددة قابلة للدحض. إذا كان VWAP يفوز فقط في الأيام التي صادف أن أصاب فيها المنحنى، فينبغي لمتنبئ يصحح نفسه مع تقدم اليوم أن يحول بعض أيام الثلث السيئ إلى أيام جيدة. أو لا ينبغي له ذلك — والنسخة المثيرة للاهتمام من هذه المقالة هي التي لا يفعل فيها، لأن الثلث السيئ في العملات المشفرة هو أيام الانهيارات وأيام الأخبار، وتلك هي بالضبط الأيام التي تكون فيها أول ساعتين من الحجم المرصود أقل إفادة بشأن الساعتين التاليتين.
تطبق هذه المقالة أداة التحديث خلال اليوم، وتشغلها على خط الاختبار المطابق، وتبلغ عن دلتا IS مقارنة بالمنحنى الثابت — مع التوزيع ورقم الربع الأخير، لا المتوسط فقط.
ما الذي نختبره؟

المنحنى الثابت هو سابق: متجه ثابت لكسور الحجم المتوقعة لكل سلة، مقدر دون اتصال. أما النسخة التكيفية فتتعامل معه كسابق ينبغي تحديثه. بعد انقضاء من السلال ورصد الأحجام الفعلية ، تكون لديك معلومتان جديدتان يهملهما المنحنى الثابت:
- تقدير المستوى. إذا قال السابق إن السلال يفترض أن تحمل الكسر من اليوم، بينما حملت وحدة، فإن إجمالي اليوم الكامل الضمني هو . وهذه إشارة إلى أن اليوم ثقيل أو ميت، وهي متاحة منذ السلة الأولى.
- تصحيح الشكل. إذا انحرف الشكل المحقق للسلال المنقضية بصورة منتظمة عن شكل السابق، فقد تنحرف السلال المتبقية أيضًا — لكن فقط إذا كانت أخطاء منحنى الحجم خلال اليوم مترابطة ذاتيًا داخل اليوم، وهذا سؤال تجريبي بحد ذاته وليس افتراضًا يحق لنا أخذه مجانًا.
يستخدم التنفيذ أدناه (1) بالكامل ولا يستخدم (2) إطلاقًا: فهو يعيد تطبيع ذيل السابق الذي لم يُمس على الإجمالي المحدث. هذه هي النسخة المحافظة، وهي التجربة الأولى الصحيحة، لأنه إذا كان تحديث المستوى الخالص يلتقط معظم الدلتا المتاحة، فإن آلية الشكل تعقيد غير مبرر.
import numpy as np
from typing import Optional
class AdaptiveVolumePredictor:
"""
Bayesian-style adaptive volume profile predictor.
Combines a prior (the offline day-of-week x time-of-day curve)
with volume observed so far today to produce an updated forecast
for the remaining buckets.
"""
def __init__(self, historical_profiles: np.ndarray):
"""
Args:
historical_profiles: shape (n_days, n_buckets), each row sums to 1.0.
Use the median-based, day-of-week-conditioned curve from the
TWAP/VWAP/POV article -- a pooled mean curve is misspecified
and will make the adaptive version look better than it is by
giving it a weaker baseline to beat.
"""
self.prior_profile = np.median(historical_profiles, axis=0)
self.prior_profile /= self.prior_profile.sum()
self.prior_iqr = np.subtract(*np.percentile(historical_profiles, [75, 25], axis=0))
self.n_buckets = len(self.prior_profile)
def predict(
self,
observed_volumes: np.ndarray,
current_bucket: int,
total_volume_estimate: Optional[float] = None,
) -> np.ndarray:
"""
Predict absolute volume for every bucket: realized values for elapsed
buckets, forecasts for the remainder.
Args:
observed_volumes: actual volumes in buckets 0..current_bucket-1
current_bucket: index of the current bucket (0-based)
total_volume_estimate: external ADV estimate (optional prior on level)
"""
profile = np.zeros(self.n_buckets)
if current_bucket == 0:
base = total_volume_estimate if total_volume_estimate else 1.0
return self.prior_profile * base
profile[:current_bucket] = observed_volumes[:current_bucket]
observed_total = observed_volumes[:current_bucket].sum()
expected_fraction_so_far = self.prior_profile[:current_bucket].sum()
if expected_fraction_so_far > 0.01:
implied_total = observed_total / expected_fraction_so_far
else:
implied_total = observed_total * self.n_buckets
if total_volume_estimate:
w_obs = expected_fraction_so_far
implied_total = w_obs * implied_total + (1 - w_obs) * total_volume_estimate
remaining_prior = self.prior_profile[current_bucket:]
remaining_sum = remaining_prior.sum()
if remaining_sum > 0:
remaining_volume = max(0.0, implied_total - observed_total)
profile[current_bucket:] = remaining_prior / remaining_sum * remaining_volume
return profile
هناك تفصيلان في ذلك الكود يحملان جوهر التجربة. السابق هو منحنى الوسيط المشروط بيوم الأسبوع، وليس متوسطًا مجمعًا — ولمعرفة سبب أهمية ذلك في سوق يمكن أن يشكل فيه انهيار تصفية واحد 15% من حجم اليوم خلال عشر دقائق، راجع قسم منحنى الحجم في مقالة VWAP. وتُجرى عملية تحديث المستوى بعد تقليصها نحو تقدير ADV خارجي بوزن يساوي الكسر السابق المنقضي، لأن implied_total في السلة الأولى هو مشاهدة واحدة مقسومة على رقم قريب من الصفر. أداة تحديث غير مقلصة تؤدي أسوأ عمل لها بالضبط عندما يكون أمامها معظم اليوم لإفساده.
خط الاختبار

مطابق لتشغيل TWAP/VWAP/POV، بحيث تكون الأرقام قابلة للمقارنة سطرًا بسطر:
- الأداة/البيانات: عقد BTCUSDT الدائم، إعادة تشغيل L2 لمدة 90 يومًا (أعلى 20 مستوى، 100 ms) بالإضافة إلى شريط التداولات. التوقيت UTC طوال الوقت؛ وطوابع التمويل معلّمة.
- أوامر الأصل: 500 أمرًا، أفق h، حجم يساوي 0.75% من ADV المتحرك لـ 30 يومًا، جهة شراء، وسعر القرار هو الوسط عند البداية. أوقات البدء العشوائية نفسها المستخدمة في التشغيل المنشور.
- الأذرع: (A) VWAP على المنحنى الثابت المعاد ملاءمته أسبوعيًا — خط الأساس المنشور؛ (B) VWAP على السابق نفسه مع تحديث خلال اليوم؛ (C) TWAP كأرضية.
- المقاييس: IS بنقاط أساس من سعر القرار، مع الرسوم، مقارنة بالوصول — يُبلغ عنها كالمتوسط والوسيط والانحراف المعياري والمئين 95 وIS للربع الأخير من كل أصل. يُسجل انزلاق VWAP كتشخيص فقط، لا كلوحة نتائج؛ إذ يوضح قسم معيار VWAP حالة عملية يرتب فيها انزلاق VWAP وIS عند الوصول خوارزميتين بترتيبين متعاكسين. ويتبع تفكيك IS الكامل، بما في ذلك حد تكلفة الفرصة، implementation shortfall وTCA.
النتائج
هل يساعد حيث نحتاج إليه؟
المتوسط الرئيسي هو أقل رقم إثارة للاهتمام هنا. فقد أثبتت النتيجة المنشورة أن فجوة VWAP–TWAP رتيبة في خطأ منحنى الحجم المحقق، ولذلك يجب تقييم الذراع التكيفية بالطريقة نفسها: قسّم الأيام التسعين إلى أثلاث حسب مسافة بين التنبؤ الثابت والأحجام المحققة للسلال، ثم أبلغ عن دلتا IS التكيفية ناقص الثابت داخل كل ثلث.
النتيجتان قابلتان للنشر، ومعناهما متعاكس:
- تركز الدلتا في الثلث الجيد. الأداة تحدّث الأيام التي كانت سهلة أصلًا. الأثر الصافي على توزيع التكلفة تجميلي؛ والذيل — وهو ما يدفعه أصل موجّه بألفا وذي أفق صارم — لم يتغير. وهذا يعني أن أداة التحديث خلال اليوم ليست حل الحلقة الأضعف، وأن مسارات تصحيح الشكل والأصول المتقاطعة هي ما ينبغي النظر إليه بعد ذلك.
- تركز الدلتا في الثلث السيئ. الأداة تؤدي الوظيفة التي بُنيت لها: التقاط أيام الانهيار والأخبار التي يكون فيها المنحنى الثابت أشد خطأ. وهذه هي النتيجة التي تبرر إضافة الحالة إلى حلقة التنفيذ.
النتيجة السلبية هي المتوقعة وتستحق الإبلاغ عنها بوضوح. فالآلية التي تجعل منحنيات الحجم في العملات المشفرة صعبة — الانهيار هو انقطاع في النظام، لا تحول في المستوى — هي بالضبط الآلية التي تهزم متنبئ تحديث المستوى: فعندما تخبرك السلال المنقضية أن اليوم ثقيل، قد يكون الجزء الثقيل قد انتهى. راجع النتيجة السلبية الصادقة لمعرفة سبب نشر هذه النتائج في المدونة.
ميل الدفتر: هل يضيف شيئًا؟

هناك ميزة في مجموعة الميزات الأولية لا تغطيها المدونة في موضع آخر: ميل الدفتر، أي سرعة تراكم العمق التراكمي عند الابتعاد عن نقطة اللمس. طابق عبر أعلى مستويات؛ فقيمة الكبيرة تعني أن العمق متركز عند نقطة اللمس، بينما تعني الصغيرة أنه موزع على الدفتر بصورة رقيقة.
def book_slope(prices: np.ndarray, volumes: np.ndarray, mid: float) -> float:
"""Slope of cumulative depth vs. distance from mid. One side only."""
distances = np.abs(prices - mid)
return float(np.polyfit(distances, np.cumsum(volumes), 1)[0])
النسخة الوحيدة من هذا الادعاء التي تستحق طرحها هي نسخة مقاسة: هل تؤدي إضافة book_slope إلى مجموعة الميزات الحالية إلى تحريك تنبؤ الحجم، أو IS الناتج، بما يتجاوز خط أساس AR/EWMA؟ تضع مقالة نمذجة السبريد المعيار — أبلغ عن المهارة فوق خط أساس تافه مع ذكر الأفق، لأن هذه السلاسل تهيمن عليها الاستمرارية، وR² الرئيسي يقيس الارتباط الذاتي في الغالب.
ما لا تعيد هذه المقالة اشتقاقه عمدًا

كل ما يلي موجود أصلًا في المدونة بمزيد من العمق، وإعادة شرحه هنا لن تؤدي إلا إلى إنشاء نسخة ثانية أضعف:
- قياس السيولة. مقدر Roll (مع إصلاح الجذر ذي الإشارة وفخ وحدات السعر مقابل العوائد) وlambda الخاصة بـ Kyle: نمذجة السبريد باستخدام التعلم الآلي. كما تُعاير lambda الخاصة بـ Kyle على
aggTradesحقيقية من Binance بوصفها معامل التأثير الدائم في Almgren-Chriss. تكلفة اجتياح الدفتر: نماذج الانزلاق والتكلفة. - ميزات دفتر الأوامر. الوسط الموزون (وهو ليس microprice الخاص بـ Stoikov — فذلك معدلّل كميًا على أنه مارتينغال)، واختلال الدفتر متعدد المستويات، وOFI، والتصنيف الكامل لميزات LOB: DeepLOB ونمذجة السبريد.
- الأنماط خلال اليوم. شكل U الخاص بالأسهم هو النموذج الخاطئ لسوق بلا إغلاق؛ أما بنية جلسات وفunding وأسابيع العملات المشفرة التي تحل محله، بالإضافة إلى شبكة يوم الأسبوع × وقت اليوم، ففي مقالة VWAP. وترميز وقت اليوم الدوري موجود في جدول ميزات مقالة السبريد.
- الأحداث المجدولة. انتهاء صلاحية Deribit عند 08:00 UTC، والاقتصاد الكلي الأمريكي عند 12:30/14:00 UTC، وتسويات CME — تعامل معها كمتغيرات صورية بدل تلويث منحنى خط الأساس؛ والتقويم المشفر الملموس موجود في مقالة VWAP. أداة التحديث التكيفية أعلاه ليست معالج أحداث، ولا ينبغي مطالبتها بأن تكون كذلك.
- النماذج. Gradient boosting مع CV walk-forward مطهر ومحجوز (إذ يتسرب
TimeSeriesSplitالعادي عبر الهدف ذي النافذة المستقبلية المتداخلة) موجود في نمذجة السبريد؛ وعائلة CNN-LSTM، وموتر الإدخال ذي 40 ميزة/10 مستويات، وLOBFrame، ونقاش أزمة التكرار موجودة في DeepLOB. لاحظ خصوصًا أنه لا يجوز دمج محور المستوى قبل الطبقة التكرارية. - قرار الأمر الابن. الاختيار بين السلبي والعدواني هو نقطة تعادل محسوبة ، وليس عتبة سبريد مبرمجة ثابتًا: تكتيكات تنفيذ الأمر الابن. واستهداف معدل المشاركة داخلي — إذ تظهر عمليات التنفيذ الخاصة بك على الشريط — والتصحيح موجود في مقالة VWAP.
- تجزؤ المنصات. التوجيه الذكي للأوامر في العملات المشفرة، مع بطاقة تقييم TCA لكل منصة في implementation shortfall.
- زمن الإنتاج. قسم الإنتاج في DeepLOB؛ لاحظ أن مقالة السبريد تؤهل بالفعل ادعاءات زمن الاستدلال — يتنبأ LightGBM ذو 2000 جولة في عشرات الميكروثواني من Python، ولا يصبح بزمن أحادي الرقم إلا باستخدام متنبئ مترجم.
الديناميات الخصومية تستحق فقرة واحدة لا قسمًا كاملًا. فالعمق المعروض استعراضي جزئيًا، وآليات الكشف — معدل الإلغاء، وسرعة بناء الجدار، والسلوك عند اقتراب السعر، والتدرج — مغطاة بطريقة ملموسة قائمة على PIQ في تحليل موضع الطابور والجدار. والفرق الوحيد الذي يمكن أن تضيفه هذه المقالة هو معاملتها كـ مدخلات للمتنبئ: نسبة الإلغاء إلى التداول، ومتوسط زمن البقاء عند نقطة اللمس، وحصة العمق التي تُلغى خلال 100 ms من ظهورها، وإدخالها إلى نموذج الحجم إلى جانب إشارة السلة المنقضية. وما إذا كانت تضيف مهارة فوق مجموعة الميزات الحالية هو قياس مفتوح، لا ادعاء.
الخلاصة

الادعاء قيد الاختبار ضيق، وقد أعدت المدونة بالفعل شروط دحضه: فقد أثبتت مقالة VWAP أن ميزة VWAP هي بالكامل جودة التنبؤ، وأن التنبؤ يفشل في الأيام التي تكلف أكثر. إما أن تصلح أداة التحديث خلال اليوم ذلك أو لا تصلحه، والإجابة هي رقم في الثلث السيئ من إعادة تشغيل تضم 500 أصل.
ما لن تفعله هذه المقالة هو إرفاق رقم بنقاط الأساس بنظام إنتاج من دون إعادة تشغيل تقف وراءه. ادعاءات من نوع "التنبؤ المضبوط جيدًا بالسيولة يوفر 2–5 نقاط أساس، وهو الفرق بين Sharpe بقيمة 1.5 و2.0" هي بالضبط النوع الذي وُجدت Sharpe المنزوعة التضخم والاختبارات المتعددة لتفكيكه: غير موثق المصدر، وغير مشروط، ولا تصاحبه أبدًا درجة التشتت. الرقم المهم هنا هو IS للربع الأخير في الثلث الأسوأ من الأيام، وهو إما مقاس أو لا ينبغي الإبلاغ عنه.
Authors
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.