← लेखों की सूची पर वापस जाएँ
August 13, 2026
5 मिनट का पठन

Updating the Volume Curve Intraday: Does Adaptive Forecasting Actually Help?

Updating the Volume Curve Intraday: Does Adaptive Forecasting Actually Help?
#microstructure
#liquidity
#execution
#prediction
#order-book

TWAP, VWAP और POV में हमने BTCUSDT के 90 दिनों के L2 रीप्ले पर तीनों शेड्यूलरों की आमने-सामने तुलना की और एक निष्कर्ष पर पहुँचे, जिसे जानबूझकर खुला छोड़ा गया था: क्रिप्टो में पाइपलाइन की सबसे कमजोर कड़ी slicing नहीं, बल्कि वॉल्यूम कर्व है। उस लेख में हमने सरल संस्करण जानबूझकर इस्तेमाल किया — सप्ताह के दिन × दिन के समय पर आधारित median कर्व, जिसे साप्ताहिक रूप से refit किया गया और पूरे ट्रेडिंग दिन स्थिर रखा गया। और पाया कि TWAP पर VWAP का पूरा edge forecast quality है: realized volume-curve error के आधार पर, सबसे अच्छे forecast वाले दिनों के tercile में VWAP लगभग 4 bps से TWAP को हराता है, जबकि सबसे खराब tercile में यह अंतर noise में बदल जाता है।

यह परिणाम एक विशिष्ट, falsifiable follow-up का संकेत देता है। यदि VWAP केवल उन दिनों जीतता है जब कर्व सही निकला, तो ऐसा forecaster जो दिन आगे बढ़ने के साथ खुद को सुधारता है कुछ खराब-tercile दिनों को अच्छे दिनों में बदल देना चाहिए। या फिर ऐसा नहीं होना चाहिए — और इस लेख का दिलचस्प संस्करण वही है जिसमें ऐसा नहीं होता, क्योंकि क्रिप्टो का खराब tercile cascade days और news days हैं, और ठीक उन्हीं दिनों पहले दो घंटों का observed volume अगले दो घंटों के बारे में सबसे कम informative होता है।

यह लेख intraday updater लागू करता है, उसे उसी harness के विरुद्ध चलाता है, और static curve के मुकाबले IS delta रिपोर्ट करता है — केवल mean नहीं, बल्कि distribution और final-quartile number भी।

क्या टेस्ट किया जा रहा है

Observed trading activity से adaptive volume-curve prior अपडेट करना

Static curve एक prior है: प्रति bucket अपेक्षित volume fractions का एक fixed vector u={u1,,uB}u = \{u_1, \ldots, u_B\}, जिसे offline अनुमानित किया गया है। Adaptive version इसे अपडेट किए जाने वाले prior की तरह देखता है। cc buckets बीत जाने और actual volumes V1,,VcV_1, \ldots, V_c देखने के बाद, आपके पास static curve द्वारा फेंक दी जाने वाली नई जानकारी के दो टुकड़े होते हैं:

  1. Level estimate. यदि prior कहता है कि buckets 1..c1..c में दिन का fraction icui\sum_{i \le c} u_i होना चाहिए और उनमें icVi\sum_{i\le c} V_i units आए, तो implied full-day total V^=icVi/icui\hat{V} = \sum_{i \le c} V_i \big/ \sum_{i \le c} u_i है। यह today-is-a-heavy-day / today-is-a-dead-day signal है, और पहले bucket से उपलब्ध होता है।
  2. Shape correction. यदि बीते हुए buckets का realized shape prior shape से व्यवस्थित रूप से अलग है, तो remaining buckets भी अलग हो सकते हैं — लेकिन केवल तब जब intraday volume-curve errors दिन के भीतर autocorrelated हों, जो स्वयं एक empirical question है और ऐसी assumption नहीं जिसे हम बिना जाँच के कर सकें।

नीचे का implementation (1) का पूरा उपयोग करता है और (2) का बिल्कुल नहीं: यह untouched prior tail को updated total पर renormalize करता है। यह conservative version है और सही पहला experiment भी, क्योंकि यदि pure level update ही उपलब्ध delta का अधिकांश भाग पकड़ लेता है, तो shape machinery अनुचित complexity होगी।

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

इस code में दो विवरण experiment को संचालित करते हैं। Prior सप्ताह के दिन के अनुसार conditioned median curve है, pooled mean नहीं — एक ऐसे market में इसका महत्व क्यों है जहाँ एक liquidation cascade दस मिनट में दिन के volume का 15% हो सकता है, इसके लिए VWAP article का volume-curve section देखें। और level update external ADV estimate की ओर shrink किया गया है, जिसका weight elapsed prior fraction के बराबर है, क्योंकि पहले bucket में implied_total लगभग शून्य संख्या से विभाजित एक observation है। Unshrunk updater ठीक तब सबसे खराब काम करता है जब दिन का सबसे बड़ा हिस्सा खराब करने के लिए अभी बाकी हो।

परीक्षण हार्नेस

Adaptive forecasting research harness में parallel execution paths

TWAP/VWAP/POV run के समान, इसलिए numbers line by line comparable हैं:

  • Instrument/data: BTCUSDT perpetual, L2 replay के 90 दिन (top 20 levels, 100 ms) और trades tape; हर जगह UTC, funding timestamps flagged।
  • Parent orders: 500, horizon T=4T = 4h, trailing 30-day ADV का 0.75% size, buy side, decision price = शुरुआत का mid। Published run जैसे ही random start times।
  • Arms: (A) static weekly-refit curve पर VWAP — published baseline; (B) उसी prior पर intraday updating वाला VWAP; (C) floor के रूप में TWAP।
  • Metrics: decision price के bps में IS, fees included, arrival के मुकाबले — mean, median, standard deviation, 95th percentile और हर parent के final quartile का IS रिपोर्ट किया जाएगा। VWAP slippage केवल diagnostic के रूप में log किया जाएगा, scoreboard के रूप में कभी नहीं; VWAP article का benchmark section एक worked case दिखाता है जहाँ VWAP slippage और arrival IS दो algorithms को विपरीत क्रम में rank करते हैं। Full IS decomposition, जिसमें opportunity-cost term भी शामिल है, implementation shortfall और TCA में है।

परिणाम

क्या यह वहाँ मदद करता है जहाँ इसकी ज़रूरत है?

Headline mean यहाँ सबसे कम interesting number है। Published result ने स्थापित किया कि VWAP–TWAP gap realized volume-curve error के साथ monotone है, इसलिए adaptive arm को उसी तरह score करना होगा: 90 दिनों को static forecast और realized bucket volumes के बीच L1L_1 distance के आधार पर terciles में बाँटें, फिर हर tercile के भीतर adaptive-minus-static IS delta रिपोर्ट करें।

दोनों outcomes publishable हैं और उनके अर्थ विपरीत हैं:

  • Good tercile में केंद्रित delta। Updater उन दिनों को refine कर रहा है जो पहले से आसान थे। Cost distribution पर net effect cosmetic है; tail — जिसे hard-horizon alpha-driven parent वास्तव में चुकाता है — अपरिवर्तित है। इसका अर्थ होगा कि intraday updater weakest link का समाधान नहीं है, और shape-correction तथा cross-asset routes आगे देखने की जगह हैं।
  • Bad tercile में केंद्रित delta। Updater वही काम कर रहा है जिसके लिए बनाया गया था: cascade और news days पकड़ना, जहाँ static curve सबसे अधिक गलत होती है। यही outcome execution loop में जोड़ी गई state को justify करेगा।

नकारात्मक परिणाम अपेक्षित है और इसे साफ़-साफ़ रिपोर्ट करना चाहिए। जो mechanism crypto volume curves को कठिन बनाता है — cascade एक regime break है, level shift नहीं — वही level-update forecaster को हराता है: जब तक बीते buckets आपको बताते हैं कि आज heavy day है, तब तक heavy हिस्सा खत्म हो चुका हो सकता है। honest negative देखें कि यह ब्लॉग ऐसे परिणाम क्यों प्रकाशित करता है।

Book slope: क्या इससे कुछ जुड़ता है?

Abstract limit-order-book depth landscape और liquidity slope

Draft feature set में एक feature ऐसा है जिसे इस ब्लॉग में कहीं और कवर नहीं किया गया: book slope, यानी touch से दूर जाते हुए cumulative depth कितनी तेजी से जमा होती है। Top KK levels पर CumVol(d)=α+βd\text{CumVol}(d) = \alpha + \beta d fit करें; बड़ा β\beta मतलब depth touch पर केंद्रित है, छोटा β\beta मतलब यह पूरे book में पतला फैला है।

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])

इस claim का एकमात्र उपयोगी संस्करण measured version है: क्या मौजूदा feature set में book_slope जोड़ने से volume forecast या उससे मिलने वाला IS AR/EWMA baseline से आगे जाता है? spread modeling article standard तय करता है — trivial baseline से ऊपर skill report करें और horizon बताएं, क्योंकि ये series persistence से dominated हैं और headline R² अधिकतर autocorrelation मापता है।

यह लेख जानबूझकर क्या दोबारा derive नहीं करता

सीमित quantitative pipeline के भीतर केंद्रित research module

नीचे की हर चीज़ ब्लॉग पर पहले से अधिक गहराई में मौजूद है, और इसे यहाँ दोबारा समझाने से केवल एक कमजोर दूसरा संस्करण बनेगा:

  • Liquidity measurement. Roll estimator (signed-root fix और price-units-vs-returns trap के साथ) और Kyle's lambda: spread modeling with machine learning। Kyle's lambda को Almgren-Chriss में permanent-impact coefficient के रूप में वास्तविक Binance aggTrades पर भी calibrate किया गया है। Walk-the-book sweep cost: slippage and cost models
  • Order book features. Weighted mid (जो Stoikov का microprice नहीं है — वह martingale-adjusted है), multi-level book imbalance, OFI और पूरा LOB feature taxonomy: DeepLOB और spread modeling
  • Intraday patterns. Equity U-shape उस market के लिए गलत model है जिसका कोई close नहीं; उसकी जगह आने वाली crypto session/funding/weekly structure और day-of-week × time-of-day grid VWAP article में है। Cyclical time-of-day encoding spread article की feature table में है।
  • Scheduled events. Deribit 08:00 UTC expiries, US macro at 12:30/14:00 UTC और CME settlements — इन्हें dummies की तरह treat करें, baseline curve को pollute न करने दें; concrete crypto calendar VWAP article में है। ऊपर का adaptive updater event handler नहीं है और इसे ऐसा बनने के लिए नहीं कहा जाना चाहिए।
  • Models. Purged, embargoed walk-forward CV के साथ gradient boosting (plain TimeSeriesSplit overlapping forward-window target पर leak करता है) spread modeling में है; CNN-LSTM family, 40-feature/10-level input tensor, LOBFrame और replication-crisis discussion DeepLOB में हैं। खास तौर पर ध्यान दें कि recurrent layer से पहले level axis collapse नहीं होना चाहिए।
  • Child-order decision. Passive बनाम aggressive एक calculated break-even p=δ/(Π+δ)p^* = \delta/(\Pi + \delta) है, hard-coded spread threshold नहीं: child order execution tactics। Participation-rate targeting endogenous है — आपके अपने fills tape पर print होते हैं — और correction VWAP article में है।
  • Venue fragmentation. Smart order routing in crypto, जिसमें per-venue TCA scorecard implementation shortfall में है।
  • Production latency. DeepLOB का production section; ध्यान दें कि spread article inference-time claims को पहले ही qualify करता है — 2000-round LightGBM Python से tens of microseconds में predict करता है, compiled predictor के साथ केवल single-digit।

Adversarial dynamics को section के बजाय एक paragraph चाहिए। Displayed depth आंशिक रूप से performative है, और detection mechanics — cancel rate, wall build-up speed, price के पास पहुँचने पर behavior, layering — queue position and wall analysis में concrete PIQ-based method के साथ कवर हैं। यह लेख केवल एक delta जोड़ सकता है: इन्हें forecaster inputs की तरह लेना — cancel-to-trade ratio, touch पर mean resting time और दिखाई देने के 100 ms के भीतर cancel होने वाली depth का fraction, elapsed-bucket signal के साथ volume model में देना। मौजूदा feature set के ऊपर skill जोड़ते हैं या नहीं, यह open measurement है, claim नहीं।

निष्कर्ष

अनिश्चितता से measured execution result तक पहुँचता evidence path

Test किया जा रहा claim छोटा है और ब्लॉग ने इसे falsify करने की conditions पहले ही तय कर दी हैं: VWAP article ने स्थापित किया कि VWAP का edge पूरी तरह forecast quality है और forecast उन दिनों fail होता है जिनकी cost सबसे अधिक होती है। Intraday updater या तो इसे ठीक करता है या नहीं, और उत्तर 500-parent replay के bad tercile में एक number है।

यह लेख replay के बिना production system पर कोई bps figure नहीं लगाएगा। "well-tuned liquidity prediction saves 2–5 bps, the difference between a Sharpe of 1.5 and 2.0" जैसे claims ठीक वही genre हैं जिसे deflated Sharpe and multiple testing dismantle करने के लिए मौजूद है: unsourced, unconditioned और dispersion के बिना। यहाँ मायने रखने वाला number worst tercile of days का final-quartile IS है; या तो वह measured है या report नहीं किया जाएगा।

blog.disclaimer

Authors

Eugen Soloviov
Eugen Soloviov

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.

Newsletter

बाज़ार से आगे रहें

AI ट्रेडिंग इनसाइट्स, मार्केट एनालिसिस और प्लेटफ़ॉर्म अपडेट के लिए हमारे न्यूज़लेटर को सब्सक्राइब करें।

हम आपकी गोपनीयता का सम्मान करते हैं। किसी भी समय अनसब्सक्राइब करें।