← Quay lại danh sách bài viết
August 13, 2026
5 phút đọc

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

Trong TWAP, VWAP và POV, chúng tôi đã so sánh trực tiếp cả ba bộ lập lịch trên 90 ngày replay L2 của BTCUSDT và đi đến một kết luận cố ý để ngỏ: trong crypto, mắt xích yếu nhất của pipeline là đường cong khối lượng, không phải việc chia lệnh. Bài viết đó cố ý dùng phiên bản đơn giản — đường cong trung vị theo ngày trong tuần × thời điểm trong ngày, refit hàng tuần và giữ cố định suốt ngày giao dịch. Kết quả cho thấy toàn bộ lợi thế của VWAP so với TWAP nằm ở chất lượng dự báo: khi điều kiện theo sai số đường cong khối lượng thực tế, VWAP thắng TWAP khoảng 4 bps ở tercile ngày có dự báo tốt nhất, còn khoảng cách này tan vào nhiễu ở tercile tệ nhất.

Kết quả đó dẫn đến một follow-up cụ thể và có thể bác bỏ. Nếu VWAP chỉ thắng vào những ngày đường cong tình cờ đúng, thì một forecaster tự hiệu chỉnh khi ngày trôi qua phải biến một phần các ngày trong tercile tệ thành ngày tốt. Hoặc không — và phiên bản thú vị của bài viết này là khi nó không làm được, vì tercile tệ của crypto là các ngày cascade và ngày có tin tức, chính là những ngày mà hai giờ đầu về khối lượng quan sát được ít cho biết nhất về hai giờ tiếp theo.

Bài viết này triển khai intraday updater, chạy nó trên cùng harness và báo cáo IS delta so với đường cong tĩnh — kèm phân phối và con số final-quartile, không chỉ giá trị trung bình.

Đang kiểm thử điều gì

Cập nhật prior đường cong khối lượng thích ứng từ hoạt động giao dịch quan sát được

Đường cong tĩnh là một prior: vector cố định u={u1,,uB}u = \{u_1, \ldots, u_B\} gồm các phân số khối lượng kỳ vọng theo bucket, được ước lượng offline. Phiên bản thích ứng coi nó là prior cần cập nhật. Sau khi cc bucket đã trôi qua và bạn quan sát các khối lượng thực tế V1,,VcV_1, \ldots, V_c, bạn có hai mẩu thông tin mới mà đường cong tĩnh loại bỏ:

  1. Ước lượng mức. Nếu prior cho rằng các bucket 1..c1..c phải chứa phân số icui\sum_{i \le c} u_i của ngày và chúng chứa icVi\sum_{i\le c} V_i đơn vị, tổng cả ngày suy ra là V^=icVi/icui\hat{V} = \sum_{i \le c} V_i \big/ \sum_{i \le c} u_i. Đây là tín hiệu today-is-a-heavy-day / today-is-a-dead-day, có ngay từ bucket đầu tiên.
  2. Hiệu chỉnh hình dạng. Nếu hình dạng thực tế của các bucket đã trôi qua lệch có hệ thống so với hình dạng prior, các bucket còn lại cũng có thể lệch — nhưng chỉ khi sai số đường cong khối lượng trong ngày có tự tương quan, vốn là một câu hỏi thực nghiệm chứ không phải giả định có thể mặc nhiên đưa vào.

Phần triển khai dưới đây dùng đầy đủ (1) và hoàn toàn không dùng (2): nó chuẩn hóa lại phần đuôi prior chưa chạm vào theo tổng đã cập nhật. Đây là phiên bản bảo thủ và là thí nghiệm đầu tiên đúng đắn, vì nếu chỉ cập nhật mức đã bắt được phần lớn delta khả dụng thì bộ máy hiệu chỉnh hình dạng là phức tạp không chính đáng.

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

Hai chi tiết trong code này quyết định thí nghiệm. Prior là đường cong trung vị theo ngày trong tuần, không phải trung bình gộp — để hiểu vì sao điều đó quan trọng trong thị trường mà một đợt thanh lý cascade có thể chiếm 15% khối lượng ngày trong mười phút, xem phần đường cong khối lượng của bài VWAP. Việc cập nhật mức được thu hẹp về phía ước lượng ADV bên ngoài với trọng số bằng phân số prior đã trôi qua, vì ở bucket đầu tiên implied_total là một quan sát chia cho một số gần bằng không. Updater không thu hẹp hoạt động tệ nhất đúng lúc nó còn nhiều thời gian trong ngày nhất để gây hỏng.

Harness kiểm thử

Các luồng thực thi song song trong harness nghiên cứu dự báo thích ứng

Giống hệt lần chạy TWAP/VWAP/POV, nên các con số có thể so sánh từng dòng:

  • Công cụ/dữ liệu: perpetual BTCUSDT, 90 ngày replay L2 (20 mức đầu, 100 ms) cộng với tape giao dịch. Dùng UTC xuyên suốt; đánh dấu timestamp funding.
  • Lệnh cha: 500, horizon T=4T = 4h, kích thước bằng 0,75% ADV 30 ngày gần nhất, phía mua, giá quyết định = mid lúc bắt đầu. Cùng các thời điểm bắt đầu ngẫu nhiên như lần chạy đã công bố.
  • Các nhánh: (A) VWAP trên đường cong tĩnh refit hàng tuần — baseline đã công bố; (B) VWAP trên cùng prior với cập nhật trong ngày; (C) TWAP làm sàn.
  • Chỉ số: IS tính bằng bps của giá quyết định, đã gồm phí, so với lúc đến — báo cáo mean, median, độ lệch chuẩn, percentile 95 và IS của quartile cuối ở mỗi lệnh cha. Slippage VWAP chỉ được ghi log như chẩn đoán, không bao giờ làm scoreboard; phần benchmark của bài VWAP có một ví dụ cho thấy slippage VWAP và arrival IS xếp hạng hai thuật toán theo thứ tự ngược nhau. Phân rã IS đầy đủ, bao gồm cả chi phí cơ hội, nằm trong implementation shortfall và TCA.

Kết quả

Nó có giúp đúng nơi cần giúp không?

Giá trị trung bình headline là con số kém thú vị nhất ở đây. Kết quả đã công bố cho thấy khoảng cách VWAP–TWAP đơn điệu theo sai số đường cong khối lượng thực tế, nên nhánh thích ứng phải được chấm theo cùng cách: chia 90 ngày thành các tercile theo khoảng cách L1L_1 giữa dự báo tĩnh và khối lượng bucket thực tế, rồi báo cáo IS delta thích ứng-trừ-tĩnh trong từng tercile.

Cả hai kết quả đều có thể công bố và mang ý nghĩa trái ngược:

  • Delta tập trung ở tercile tốt. Updater đang tinh chỉnh những ngày vốn đã dễ. Tác động ròng lên phân phối chi phí chỉ là hình thức; phần đuôi — thứ mà một lệnh cha do alpha điều khiển với chân trời cứng thực sự phải trả — không đổi. Điều này cho thấy updater trong ngày không sửa được mắt xích yếu nhất, và cần tìm tiếp ở hiệu chỉnh hình dạng cùng các hướng cross-asset.
  • Delta tập trung ở tercile tệ. Updater đang làm đúng nhiệm vụ được xây dựng: bắt được ngày cascade và ngày tin tức, khi đường cong tĩnh sai nhiều nhất. Đây là kết quả biện minh cho việc thêm state vào vòng lặp thực thi.

Kết quả âm là điều được kỳ vọng và đáng được báo cáo thẳng thắn. Cơ chế khiến đường cong khối lượng crypto khó — cascade là một regime break, không phải dịch chuyển mức — chính là cơ chế đánh bại forecaster cập nhật mức: đến khi các bucket đã trôi qua cho bạn biết hôm nay là ngày khối lượng lớn, phần khối lượng lớn có thể đã kết thúc. Xem kết quả âm trung thực để hiểu vì sao blog này công bố những kết quả đó.

Độ dốc sổ lệnh: có thêm được gì không?

Cảnh quan độ sâu sổ lệnh giới hạn trừu tượng và độ dốc thanh khoản

Một feature trong bộ feature nháp chưa được đề cập ở nơi khác trên blog: độ dốc sổ lệnh, tức tốc độ độ sâu tích lũy tăng lên khi rời khỏi touch. Fit CumVol(d)=α+βd\text{CumVol}(d) = \alpha + \beta d trên KK mức đầu; β\beta lớn nghĩa là độ sâu tập trung ở touch, β\beta nhỏ nghĩa là nó trải mỏng trên toàn sổ.

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

Phiên bản duy nhất đáng đưa ra của claim này là phiên bản được đo: thêm book_slope vào bộ feature hiện có có làm dự báo khối lượng, hoặc IS tạo ra, vượt baseline AR/EWMA không? Bài viết spread modeling đặt tiêu chuẩn — báo cáo skill trên một baseline tầm thường với horizon được nêu rõ, vì các chuỗi này bị chi phối bởi persistence và R² headline chủ yếu đo tự tương quan.

Điều bài viết này cố ý không suy diễn lại

Mô-đun nghiên cứu tập trung trong một pipeline định lượng có giới hạn

Mọi thứ dưới đây đã có trên blog với độ sâu lớn hơn, và giải thích lại ở đây chỉ tạo ra một phiên bản thứ hai yếu hơn:

  • Đo lường thanh khoản. Ước lượng Roll (với signed-root fix và bẫy price-units-vs-returns) cùng Kyle's lambda: spread modeling bằng machine learning. Kyle's lambda cũng được hiệu chỉnh trên aggTrades Binance thực tế như hệ số tác động vĩnh viễn trong Almgren-Chriss. Chi phí sweep walk-the-book: mô hình slippage và chi phí.
  • Feature sổ lệnh. Weighted mid (hoàn toàn không phải microprice của Stoikov — nó đã được điều chỉnh theo martingale), book imbalance đa mức, OFI và toàn bộ taxonomy feature LOB: DeepLOBspread modeling.
  • Mẫu hình trong ngày. U-shape của cổ phiếu là mô hình sai cho thị trường không có giờ đóng; cấu trúc phiên/funding/hàng tuần của crypto thay thế nó, cùng lưới ngày trong tuần × thời điểm trong ngày, nằm trong bài VWAP. Mã hóa thời điểm trong ngày theo chu kỳ nằm trong bảng feature của bài spread.
  • Sự kiện theo lịch. Đáo hạn Deribit 08:00 UTC, dữ liệu vĩ mô Mỹ lúc 12:30/14:00 UTC, settlement CME — hãy xử lý chúng như biến giả thay vì để chúng làm nhiễm đường cong baseline; lịch crypto cụ thể nằm trong bài VWAP. Intraday updater ở trên không phải event handler và không nên yêu cầu nó trở thành một event handler.
  • Mô hình. Gradient boosting với purged, embargoed walk-forward CV (plain TimeSeriesSplit làm rò rỉ qua target cửa sổ tiến chồng lấn) nằm trong spread modeling; họ CNN-LSTM, tensor đầu vào 40-feature/10-level, LOBFrame và phần thảo luận về khủng hoảng tái lập nằm trong DeepLOB. Đặc biệt lưu ý không được gộp trục level trước layer hồi quy.
  • Quyết định child order. Passive so với aggressive là break-even tính được p=δ/(Π+δ)p^* = \delta/(\Pi + \delta), không phải threshold spread hard-code: chiến thuật thực thi child order. Target participation-rate là nội sinh — chính fill của bạn xuất hiện trên tape — và phần hiệu chỉnh nằm trong bài VWAP.
  • Phân mảnh venue. Smart order routing trong crypto, với scorecard TCA từng venue trong implementation shortfall.
  • Độ trễ production. Phần production của DeepLOB; lưu ý bài spread đã đủ điều kiện hóa các claim về thời gian suy luận — LightGBM 2000 vòng dự báo trong hàng chục microsecond từ Python, chỉ còn một chữ số microsecond khi dùng predictor đã biên dịch.

Động lực đối nghịch xứng đáng một đoạn văn chứ không phải một mục riêng. Độ sâu hiển thị mang tính trình diễn một phần, và cơ chế phát hiện — tỷ lệ hủy, tốc độ dựng wall, hành vi khi giá tiến gần, layering — được trình bày bằng phương pháp cụ thể dựa trên PIQ trong phân tích vị trí hàng đợi và wall. Delta duy nhất bài này có thể thêm là coi chúng như đầu vào forecaster: tỷ lệ cancel-to-trade, thời gian resting trung bình tại touch và phần độ sâu bị hủy trong vòng 100 ms sau khi xuất hiện, đưa vào mô hình khối lượng cùng tín hiệu bucket đã trôi qua. Chúng có tăng skill so với bộ feature hiện có hay không là phép đo còn bỏ ngỏ, không phải claim.

Kết luận

Lộ trình bằng chứng từ bất định đến kết quả thực thi được đo lường

Claim đang kiểm thử rất hẹp và blog đã đặt sẵn điều kiện để bác bỏ nó: bài VWAP xác lập rằng edge của VWAP hoàn toàn là chất lượng dự báo và dự báo thất bại vào những ngày tốn kém nhất. Intraday updater hoặc khắc phục điều đó hoặc không, và câu trả lời là một con số trong tercile tệ của replay 500 lệnh cha.

Bài viết này sẽ không gắn con số bps cho hệ thống production nếu không có replay phía sau. Những claim kiểu "well-tuned liquidity prediction saves 2–5 bps, the difference between a Sharpe of 1.5 and 2.0" chính là thể loại mà Sharpe giảm phát và multiple testing tồn tại để tháo dỡ: không nguồn, không điều kiện và không bao giờ đi kèm độ phân tán. Con số quan trọng ở đây là IS quartile cuối trong tercile ngày tệ nhất; hoặc nó được đo, hoặc không được báo cáo.

Tuyên bố miễn trừ trách nhiệm: Thông tin được cung cấp trong bài viết này chỉ nhằm mục đích giáo dục và thông tin, không cấu thành lời khuyên về tài chính, đầu tư hoặc giao dịch. Giao dịch tiền mã hóa tiềm ẩn rủi ro thua lỗ đáng kể.

Tác Giả

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

Đi Trước Thị Trường

Đăng ký nhận bản tin của chúng tôi để có những thông tin chuyên sâu độc quyền về AI trading, phân tích thị trường và các cập nhật nền tảng.

Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất kỳ lúc nào.