📝

Draft article

This draft is visible to admins and superusers only. Sign in with an authorized account.

← Makalelere geri dön
August 23, 2026
5 dakikalık okuma

Trade Classification When You Have No Side Flag: Tick, Quote, Lee-Ready, BVC

Trade Classification When You Have No Side Flag: Tick, Quote, Lee-Ready, BVC
#microstructure
#trade-classification
#Lee-Ready
#order-flow
#deep-learning

Önce çoğu mikro yapı ders kitabının başladığı problem versiyonunu bir kenara bırakalım. Bu blogun gerçekten işlem yaptığı platformlarda işlem yönünü çıkarsamanız gerekmez — yön zaten bir alandır. Binance aggTrades verisi isBuyerMaker alanını, Bybit işlem akışı ise side alanını sağlar. Bar oluşturma makalesi saldırgan tarafı doğrudan bu işaretten alır ve hiç sınıflandırıcı çalıştırmaz:

def on_trade(self, timestamp: int, price: float, qty: float, is_buyer_maker: bool):
    side = -1 if is_buyer_maker else 1

Bu, nanosecond çözünürlükte ve ücretsiz gerçek etikettir. Modern bir kripto CEX akışından işaretli emir akışı oluşturuyorsanız bu makaleye ihtiyacınız yoktur.

Dört durumda buna ihtiyacınız vardır ve bunlar önemsenmeyecek kadar nadir değildir:

  1. Yalnızca barlarınız var. Tarihsel OHLCV, çoğu sağlayıcının sattığı ve çoğu backtestin kullandığı veridir; işlem akışı hiç arşivlenmemiş olabilir ya da araştırmanın değerini aşan bir maliyete sahip olabilir. Aşağıdaki BVC problemi budur.
  2. Platform tarafı işaretlemiyor. Küçük CEX'ler, hisse senedi TAQ tarzı veri kümeleri ve 2017 öncesi arşivlerin neredeyse tamamı yalnızca fiyat ve miktar verir.
  3. DEX ve zincir üstü akış. Bir swap olayı hangi tokenın hangi yönde hareket ettiğini söyler; ancak yönlendirilmiş çok adımlı bir işlemde veya toplayıcıda saldırganlığı atfetmek için başvurulacak bir işaret yoktur.
  4. Yayımlanmış araştırmayı tekrarlıyorsunuz. Kyle lambda tahminleri, VPIN, spread ayrıştırmaları — mikro yapının neredeyse tamamı Lee-Ready ile sınıflandırılmış veriye dayanır; dolayısıyla karşılaştırılabilirlik için gerçek tarafı okumak yerine onların sınıflandırıcısını çalıştırmanız gerekir.

Devamında kural seti, en önemli hata modu, toplu hacim kısayolu ve bunların tamamını ölçmek için bir protokol yer alıyor — çünkü kripto, hisse senedi literatürünün hiç sahip olmadığı etiketleri size sunar.

Tick testi

Tick testi olay dizisi

Mevcut işlem fiyatı PtP_t ile bir önceki fiyatı karşılaştırın:

dttick={+1if Pt>Pt11if Pt<Pt1dt1tickif Pt=Pt1d_t^{\text{tick}} = \begin{cases} +1 & \text{if } P_t > P_{t-1} \\ -1 & \text{if } P_t < P_{t-1} \\ d_{t-1}^{\text{tick}} & \text{if } P_t = P_{t-1} \end{cases}

Sezgi şudur: alıcı tarafından başlatılan işlemler ask'i kaldırıp fiyatı yükseltir; satıcı tarafından başlatılan işlemler bid'e vurup fiyatı düşürür. Sıfır tick'ler önceki işareti ileri taşır; hataların çoğu burada oluşur — tek tick spread'e sahip likit bir enstrümanda ardışık işlemlerin çoğu aynı fiyattan gerçekleşir.

sign = np.sign(np.diff(prices, prepend=prices[0]))
sign[sign == 0] = np.nan
directions = pd.Series(sign).ffill().fillna(1).astype(int).values

Aynı ileri taşıma semantiğine sahip üretim uygulaması, zaman barlarının ötesinde bulunan tick ve hacim dengesizliği barı üreticilerinde _tick_sign() olarak zaten mevcut — ikinci bir kopya tutmak yerine bunu yeniden kullanın.

Quote kuralı

Bid ask geometrisinde konumlanan işlemler

Ardışık işlemleri karşılaştırmak yerine işlem fiyatını geçerli orta noktaya Mt=(At+Bt)/2M_t = (A_t + B_t)/2 göre karşılaştırın:

dtquote={+1if Pt>Mt1if Pt<Mtundefinedif Pt=Mtd_t^{\text{quote}} = \begin{cases} +1 & \text{if } P_t > M_t \\ -1 & \text{if } P_t < M_t \\ \text{undefined} & \text{if } P_t = M_t \end{cases}
def quote_rule(trade_prices: np.ndarray,
               bid_prices: np.ndarray,
               ask_prices: np.ndarray) -> np.ndarray:
    """Classify trades using the quote rule.

    Returns +1 (buy), -1 (sell), or 0 (unclassified) for midpoint trades.
    """
    midpoints = (bid_prices + ask_prices) / 2.0
    directions = np.zeros(len(trade_prices), dtype=int)
    directions[trade_prices > midpoints] = 1
    directions[trade_prices < midpoints] = -1
    return directions

Quote kuralı tick testinden kesin olarak daha fazla bilgi kullanır, ancak başka bir noktada başarısız olur: tam olarak mid'de gerçekleşen işlemler hakkında hiçbir şey söylemez. Spread'i dar ve tick ile sınırlı bir enstrümanda bu uç bir durum değildir — akışın büyük bir bölümüdür. Kuralın bir geri dönüş yöntemine ihtiyacı vardır; Lee-Ready bunun için kullanılır.

Lee-Ready: hibrit yöntem ve eski quote varsayımı

İşlem akışı ve gecikmeli quote yüzeyi

Lee ve Ready (1991) ikisini birleştirdi: quote kuralını uygulayın, midpoint'teki işlemler için tick testine dönün.

dtLR={dtquoteif PtMtdttickif Pt=Mtd_t^{\text{LR}} = \begin{cases} d_t^{\text{quote}} & \text{if } P_t \neq M_t \\ d_t^{\text{tick}} & \text{if } P_t = M_t \end{cases}
def lee_ready(trade_prices: np.ndarray,
              bid_prices: np.ndarray,
              ask_prices: np.ndarray,
              quote_lag: int = 0) -> np.ndarray:
    """Lee-Ready classification.

    quote_lag : number of quote observations to lag (0 = contemporaneous).
                Set > 0 only if your quote feed is known to trail the trade
                feed; see the discussion of the 5-second rule below.

    Depends on tick_test() with carry-forward semantics — the `_tick_sign()`
    implementation from /blog/beyond-time-bars-candle-construction.
    """
    if quote_lag > 0:
        bid = np.concatenate([bid_prices[:quote_lag], bid_prices[:-quote_lag]])
        ask = np.concatenate([ask_prices[:quote_lag], ask_prices[:-quote_lag]])
    else:
        bid, ask = bid_prices, ask_prices

    directions = quote_rule(trade_prices, bid, ask)

    unclassified = directions == 0
    if unclassified.any():
        directions[unclassified] = tick_test(trade_prices)[unclassified]

    return directions

Makalenin daha ilginç yarısı, genellikle gerekçesi açıklanmadan tekrarlanan kısımdır. Lee ve Ready yalnızca bir hibrit önermedi; her işlemi beş saniye önce geçerli olan quote ile karşılaştırmayı önerdi. Bu sayı piyasaya ilişkin bir modelleme tercihi değildir. Bir raporlama artefaktını düzeltir: 1980'lerin NYSE konsolide bandında işlemler ve quote'lar farklı gecikmelere sahip farklı kanallardan yayılıyordu ve quote'lar ait oldukları işlemlerden önce gelme eğilimindeydi. Bu nedenle bir işlemi aynı anda basılmış quote ile karşılaştırmak, onu zaten yansıtan bir quote ile karşılaştırmak demekti — tam olarak piyasayı hareket ettiren işlemlerde işareti tersine çeviriyordu.

Bunu kriptoya taşıyan herkes için iki sonuç çıkar.

5 saniye kuralı eskimiştir ve uygulanması doğrudan zararlıdır. Artık var olmayan bir yayılım gecikmesini düzeltir. Hisse senedi piyasaları 1990'ların ortasında bu farkı kapattı; bir kripto platformunun işlem ve emir defteri delta akışları aynı sıra alanını paylaşır ve aynı eşleştirme motoru tarafından mikrosaniye çözünürlüğünde damgalanır. BTCUSDT'te beş saniye bir senkronizasyon toleransı değil, yüzlerce emir defteri güncellemesidir. Quote'ları beş saniye geciktirmek eski quote'ları düzeltmez, onları üretir. Kendi kaydınızda gerçek bir fark ölçmediyseniz quote_lag=0 kullanın.

Ancak temel sorun yeni bir biçimde varlığını sürdürür. Quote'ların eskimesi artık borsanın değil, pipeline'ınızın hatasıdır. Emir defterini WebSocket delta akışından yeniden oluşturup işlemleri duvar saati zaman damgasıyla birleştirdiğinizde, arabelleğe alma, snapshot yeniden senkronizasyon politikanız ve saatinize bağlı bir gecikme eklersiniz. Emir defterini okuyan bir sınıflandırıcıya güvenmeden önce bunu ölçün: bir zaman aralığını yeniden oynatın, işlemleri emir defteri durumuyla birleştirin ve hangilerinin birleştirilmiş [bid, ask] aralığının dışında kaldığını kontrol edin. Birleşik ask'in üzerinde gerçekleşen işlem, eşleştirdiğiniz emir defterinin eski olduğunu kanıtlar.

Düzeltme Lee ve Ready'ninkinden farklıdır; hata modu aynıdır.

Toplu Hacim Sınıflandırması

Yön sınıfına göre hacim kümeleri

Easley, Lopez de Prado ve O'Hara (2012) farklı bir probleme saldırır: tek tek işlemleri hiç görmüyorsanız ne olacak? BVC, bir bar içindeki toplam hacmi standartlaştırılmış fiyat değişiminin standart normal CDF'si ile bölerek sınıflandırır:

Vtbuy=VtΦ(ΔPtσΔP),Vtsell=VtVtbuyV_t^{\text{buy}} = V_t \cdot \Phi\left(\frac{\Delta P_t}{\sigma_{\Delta P}}\right), \qquad V_t^{\text{sell}} = V_t - V_t^{\text{buy}}

burada ΔPt=PtclosePtopen\Delta P_t = P_t^{\text{close}} - P_t^{\text{open}} ve σΔP\sigma_{\Delta P} bar fiyat değişimlerinin standart sapmasıdır.

from scipy.stats import norm

def bulk_volume_classification(open_prices: np.ndarray,
                               close_prices: np.ndarray,
                               volumes: np.ndarray,
                               sigma: float | None = None) -> tuple:
    """Split bar volume into buy/sell using the BVC rule.

    Returns (buy_volume, sell_volume) as continuous, not integer, splits.
    """
    delta_p = close_prices - open_prices

    if sigma is None:
        sigma = max(float(np.std(delta_p)), 1e-8)

    buy_fraction = norm.cdf(delta_p / sigma)
    return volumes * buy_fraction, volumes * (1.0 - buy_fraction)

BVC farklı bir araçtır, daha kötü değildir; nedenini üç özellik açıklar. İşlemleri sınıflandırmaz — bir oran üretir; bu nedenle değişmeden kapanan bir bar, içindeki her işlem için yazı tura atmak yerine 50/50 bölünür. Tüketiciniz işlem başına işarete ihtiyaç duyuyorsa BVC bunu sağlayamaz. Tape yerine barlar üzerinde çalışır; asıl amaç da budur: işlem seviyesi verisi olmadığında burada işe yarayan tek yöntemdir. Ayrıca σ\sigma sonuçları değiştiren serbest bir parametredir — tüm örneklem tahmini lookahead içerir, kısa bir hareketli tahmin ise Φ\Phi'yi doyuma ulaştırıp her barı 0/100'e iter. Bu tercih bir duyarlılık taramasını hak eder, varsayılan bir değeri değil.

Orijinal makale, BVC'nin VPIN tahmini için işlem seviyesi sınıflandırmasını yeterince yakından izlediğini bildirir. Kesin doğruluk rakamları bar boyutuna, enstrümana ve σ\sigma tahmin edicisine büyük ölçüde bağlıdır; ikincil kaynaklarda verilen rakamlar nadiren üçünü birden belirtir. Hisse senedi çalışmasındaki bir sonucu buraya taşımayın — ölçün.

Sınıflandırmaya özgü tek özellik

Vurgulanan mikro yapı sinyali

Bir kural çalıştırmak yerine bunu yapmak üzere model eğitiyorsanız özellik setinin çoğu zaten yayımlanmıştır: spread, derinlik dengesizliği, işlem akışı dengesizliği ve hareketli gerçekleşen volatilite makine öğrenmesiyle spread modelleme içinde tabloya dökülüp uygulanmıştır; çok seviyeli emir defteri özellikleri de DeepLOB içindedir. Bunları kullanın.

Bu probleme özgü ve her iki kaynakta da yer almayan özellik, işlemin spread içindeki konumudur:

relative_pricet=PtBtAtBt\text{relative\_price}_t = \frac{P_t - B_t}{A_t - B_t}

Bid'deki işlem 0'a, ask'teki işlem 1'e, mid'deki işlem 0.5'e karşılık gelir. Bu, quote kuralının sürekli genellemesidir: midpoint'te eşiklemek yerine modele mesafeyi verir; böylece model 0.95'teki işlemin neredeyse kesinlikle alım, 0.55'tekinin ise ancak zayıf bilgi taşıdığını öğrenebilir. [0,1][0, 1] dışındaki değerler önceki bölümdeki eski quote teşhisidir; kırpmak yerine kayda alınmaları gerekir.

Bu özellikler üzerinde boosting tabanlı bir baseline için makine öğrenmesiyle spread modelleme içinde yayımlanan pipeline'ı kullanın ve hedefi ikili olarak değiştirin — özellikle arındırılmış ve embargo uygulanmış walk-forward CV'sini koruyun. Bir mikro yapı sınıflandırıcısını basit TimeSeriesSplit ile değerlendirmeyin; bu makale ve walk-forward optimizasyonu elde edilen sayının neden iyimser olduğunu açıklar. Emir defteri snapshot'ları üzerindeki sıralı modeller için DeepLOB referans mimaridir ve oradaki eğitim hususları değişmeden geçerlidir.

Doğru ölçüm: kripto etiketleri size verir

Etiketlenmiş kripto piyasa verisi akışı

Hisse senedi işlem sınıflandırması literatüründeki her doğruluk rakamı, gerçek değer için bir proxy'ye göre tahmin edilir — TORQ, denetim izi alt örnekleri veya tek bir platformun iç kayıtları — çünkü gerçek saldırgan taraf hiç yayımlanmadı. Kripto bunu yayımlar. Binance aggTrades içindeki isBuyerMaker, her işlem için ücretsiz etikettir. Dolayısıyla deney herkesin kullanımına açıktır ve kripto için yayımlanmış halini bulamadım. Protokol:

Veri. Bir aylık BTCUSDT aggTrades ve book ticker akışı; her işlem, hemen öncesinde geçerli olan bid ve ask ile birleştirilir. Spread geniş olduğunda ne olduğunu görmek için bunu likiditesi düşük bir altcoinde tekrarlayın.

Etiket. direction = -1 if is_buyer_maker else +1. Ardından işareti atın ve her yöntemi yalnızca fiyat ve quote verisi üzerinde çalıştırın.

Yöntemler. Tick testi, quote kuralı, quote_lag=0 ile Lee-Ready, tarihsel 5 saniyelik gecikmeyle Lee-Ready (eskimiş kuralın verdiği zararı ölçmek için) ve çeşitli bar boyutlarında BVC; bunları bar başına gerçek alım hacmi oranıyla karşılaştırın.

Ayrıştırmalar. Genel doğruluk en az ilginç sayıdır. Spread rejimine (tek tick'e karşı geniş — spread sabitlendiğinde tick testinin ileri taşıması çökmelidir), işlemin mid'de gerçekleşip gerçekleşmediğine (quote kuralının çekimser kaldığı ve Lee-Ready geri dönüşünün tüm işi yaptığı durumu ayırmak için), işlem büyüklüğüne (aggTrades girdileri sweep'tir; büyük işlemler etkiyi belirler ve yanlış işaretlendiğinde en pahalı sonucu doğurur) ve volatilite rejimine (BVC'nin σ\sigma değeri tahmin edilir, dolayısıyla hatası yapısı gereği rejime bağlıdır) göre ayırın.

Yöntem Genel Mid'de Dar spread Geniş spread Büyük işlemler
Tick test
Quote kuralı
Lee-Ready (gecikme 0)
Lee-Ready (5 sn gecikme)
BVC (bar başına oran) n/a n/a

Doğruluk hedef değildir

Sınıflandırma sınırı ve uygulama etkisi

DeepLOB makalesinin çerçeveleme disiplinini kullanırsak: sınıflandırma doğruluğu bir sonuç değil, sonuca girdi sağlayan bir ölçüdür. Kimse bir işlemin işaretini trade etmez — işaretlerin tamamından hesaplanan bir şeyi trade eder; hatalar buna tarafsız biçimde aktarılmaz. İşlemlerin %10'unda rastgele hata yapan bir sınıflandırıcı ile büyük ve fiyatı hareket ettiren %10'luk işlemlerde sistematik hata yapan bir sınıflandırıcı, doğrulukları aynı olsa bile çok farklı işaretli emir akışı üretir. Tick testinin ileri taşıma başarısızlığı özellikle yatay fiyatla ilişkilidir — işaretli akışın bilgi taşıması gereken rejim. Bu nedenle gerçek çıktı başlık sayısı değil, yukarıdaki ayrıştırmalardır.

Gerçek etiketlerle sonraki soru doğrudan ölçülebilir: ilgilendiğiniz miktarı gerçek işaretlerden tahmin edin, her sınıflandırıcının işaretleriyle yeniden tahmin edin ve farkı raporlayın.

  • Fiyat etkisi. Sabit pencerelerde mid-price değişimlerini işaretli net taker akışı üzerine regresyonlayın — tahmin edici slippage maliyet modelleri içinde zaten tanımlanmış, kamuya açık Binance verileri üzerindeki çalışan uygulaması da Almgren-Chriss optimal execution içindedir. Burada yeniden tanımlamayın; iki kez çalıştırıp uyarlanmış katsayıyı karşılaştırın.
  • Tahmin edici olarak emir akışı dengesizliği. Gerçek işaretlerle ve sınıflandırılmış işaretlerle OFI ile ileri getiriler arasındaki korelasyonu hesaplayın. Bu korelasyondaki bozulma yanlış sınıflandırmanın maliyetidir ve anlamlı tek birimle ifade edilir.
  • Toksisite metrikleri. VPIN ve işlem akışı dengesizliği özellikleri sınıflandırılmış hacmi kullanır; her ikisi de makine öğrenmesiyle spread modelleme içinde ele alınmıştır. Sınıflandırma hatasına duyarlılıkları aynı şekilde ölçülebilir.

Buradan çıkarılacak sonuç

Çözülmüş emir akışı haritası

Platformunuz saldırgan taraf işareti sağlıyorsa onu kullanın. Kriptonun çoğunda, çoğu zaman durum budur.

Sağlamıyorsa eşzamanlı quote'larla Lee-Ready doğru varsayılandır — doğru olduğu için değil, standart olduğu için; üç on yıllık yayımlanmış tahminlerle karşılaştırılabilirlik, doğrulayamayacağınız birkaç doğruluk puanından daha değerlidir. Beş saniye kuralı 1980'lerin tape gecikmesinden kalma bir fosildir; modern verilerde tekrarlanması, ortadan kaldırmak için tasarlandığı eskimeyi yeniden üretir. Yalnızca barlarınız varsa BVC gerçekten çalışan tek seçenektir ve farklı bir soruyu yanıtlar: işlem işareti değil, hacim bölüşümü.

Her durumda kriptonun ücretsiz verdiği etiketlere göre ölçüm yapın, sonucu spread rejimi ve işlem büyüklüğüne göre ayrıştırın ve doğru sınıflandırılan yüzdeyi değil, hatanın sonraki aşamalara maliyetini raporlayın.

Sorumluluk Reddi: Bu makalede sağlanan bilgiler yalnızca eğitim ve bilgilendirme amaçlıdır ve finansal, yatırım veya ticaret tavsiyesi niteliği taşımaz. Kripto para ticareti önemli bir kayıp riski içerir.

Yazarlar

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

Piyasanın Önünde Olun

Özel yapay zeka ticaret içgörüleri, piyasa analizi ve platform güncellemeleri için bültenimize abone olun.

Gizliliğinize saygı duyuyoruz. İstediğiniz zaman abonelikten çıkabilirsiniz.