Order Flow Imbalance: The Cont-Kukanov-Stoikov Event Decomposition
Bu blogdaki kitaplardan türetilen sinyallerin çoğu anlık görüntüler: şu anda her iki tarafta ne kadar sesin durduğudur. Sipariş akışı dengesizliği farklı bir nesnedir. Bu, iki anlık görüntü arasındaki güncelleme akışının tek bir imzalı miktara ayrıştırılmasıdır; bu miktar, bir piyasa satışını saydığı gibi teklifin iptalini de sayar.
Bu ayrıştırma bu makalenin konusudur. Spesifik olarak: onu tanımlayan Cont-Kukanov-Stoikov (2014) olay göstergeleri, Xu-Gould-Howison (2019) çok düzeyli uzantısı ve bunun temel bileşen azaltımı ve feed'iniz ticaret yönünü etiketlemediğinde ihtiyaç duyduğunuz Lee-Ready ve Toplu Hacim Sınıflandırması kuralları.
Önceden bir çerçeveleme notu, çünkü aşağıdaki her rakamı nasıl okumanız gerektiğini yönetir. CKS belgesindeki meşhur %50-65 R-kare, eşzamanlı bir regresyondur: bir aralıktaki fiyat değişimi, aynı aralıktaki sipariş akışına göre regrese edilir. Bu, fiyat hareketlerinin bir tahmini değil, bir analizidir. Bunu, günlük özsermaye getiri modelinin açıkladığı %1-2'lik varyansla karşılaştırıldığında, elmalar portakallar şeklindedir ve bu blog, DeepLOB ve tahmin-kâr açığı ve dürüst olumsuz sonuç'da uzun uzadıya tartışıyor; bu ikisini birleştirmenin eğitimlerin tuzağa dönüştüğünü gösteriyor. Kesinlikle gecikmeli bir OFI regresyonu meşru ve çok daha küçük bir sayıdır. Bu makale bunlardan birini bildirmiyor.
Neden İşlemler Değil, Sipariş Akışı

Sürekli limitli emir defterindeki fiyat değişikliği tam olarak dört mekanizma aracılığıyla gerçekleşir: Bir piyasada alım, dinlenme taleplerini tüketir; bir piyasa satışı kalan teklifleri tüketir; Teklifin iptal edilmesi desteği ortadan kaldırır ve teklifin düşmesine neden olur; Satıştaki yeni limit emri direnç katıyor. Sadece ilk ikisi takastır. Son ikisi hacim bazlı herhangi bir ölçümde görünmez (VWAP, denge hacmi, imzalı ticaret akışı) ve çoğu yerde emir-işlem oranı 10:1'i aşıyor, dolayısıyla görünmez kısım büyük kısımdır. OFI'nin kullanışlılık iddiasının tamamı, dört mekanizmanın tamamını aynı ölçekte fiyatlandırmasıdır. (Veri yapısı olarak kitap ve standart anlık görüntü özellik vektörü için bkz. DeepLOB.)
Cont-Kukanov-Stoikov OFI Modeli

Temel model Cont, Kukanov ve Stoikov'un 2014 tarihli "Sipariş Defteri Olaylarının Fiyat Etkisi" (Finansal Ekonometri Dergisi) başlıklı makalesinden alınmıştır.
Sipariş Akışı Dengesizliğinin Tanımlanması
En iyi teklif fiyatını , en iyi satış fiyatını ve bunların boyutlarını ve düşünün. ve 'deki ardışık gözlemler arasında:
alıcı tarafı ve satıcı tarafı olay katkılarının olduğu yer:
Basit bir dille ifade edersek: En iyi teklif fiyatı yükselirse, yeni satın alma ilgisi ortaya çıktı; bunun tam boyutunu pozitif olarak sayın. Düşerse, satın alma faizi ortadan kalkar; eski miktarı çıkarın. Fiyat değişmediyse yalnızca boyut değişikliğini sayın. Sor tarafı ayna görüntüsüdür.
Buradaki zarafet, bu üç gösterge dalının kitabın üst kısmındaki olası tüm geçişleri kapsamasıdır, böylece her güncelleme tam olarak tek bir imzalı sayıyla eşleşir. Ticari sınıflandırma yok, yan etiket yok, mesaj düzeyinde feed gerekli değil; birbirini takip eden iki anlık görüntü yeterlidir.
Aralıklar Üzerindeki Toplama
kitap güncellemelerini içeren aralığı için:
Doğrusal Fiyat Etki Modeli
burada orta fiyattaki değişikliktir, fiyat etki katsayısıdır ve artık gürültüdür. ABD hisse senetlerinde 10 saniye ila 1 dakikalık aralıklarla CKS, hisse başına %50-65 eş zamanlı rapor ediyor. Tekrar ediyorum: aynı aralıkta, ileriye dönük değil.
Kesitsel Ölçeklendirme
CKS ayrıca darbe katsayısının derinlikle ters orantılı olduğunu da gösterdi:
where is average resting volume at the best bid and ask. Aynı akış, ince bir kitapta fiyatı daha da ileri itiyor. Bu, modelin seviyeyi yeniden ayarlamadan mekanlar arasında aktarım yapan tek parçasıdır çünkü bir sayıdan ziyade bir ilişkiyi öngörür ve farklı derinlikteki kripto çiftleri üzerinde doğrudan test edilebilir.
Çok Seviyeli Sipariş Akışı Dengesizliği (MLOFI)

Orijinal model yalnızca kitabın üst kısmını kullanır. Xu, Gould ve Howison (2019) bunu seviyelerine kadar genişletti.
Tanım
burada aynı üç dallı formülü 'inci alış/satış çiftine uygular.
Çok Düzeyli Fiyat Etkisi
Nasdaq hisse senetleriyle ilgili yayınlanan bulgu, her ek seviyenin örnek dışı eklediği; bir seviyeden beşe kabaca yüzde 10-15 puan çıktığı, marjinal kazanımların hala on seviyesinde olduğu yönünde. Katsayılar monoton bir şekilde azalır, : kitabın üst kısmı baskındır, ancak daha derin seviyeler önemsiz olmayan artımlı sinyal taşır.
Bunun bir kripto kitabında hayatta kalıp kalmayacağı bu makaledeki en ilginç açık sorudur. Kripto defterleri daha incedir ve çok daha derinlemesine çalkalanmıştır ve Nasdaq sipariş defterinden çıktığınızda 2-5 seviyelerin hiçbir şey eklememesi tamamen akla yatkındır.
Ana Bileşen Azaltma
Bitişik düzeydeki OFI'ler yüksek düzeyde korelasyona sahiptir (yayınlanan özsermaye sonuçlarında 0,8'in üzerinde), dolayısıyla temel bileşen ayrıştırması doğaldır. Bildirilen ilk bileşen, toplam varyansın %89'undan fazlasını yakalar ve tek bir toplu sinyal görevi görür:
OFI kovaryans matrisinin önde gelen özvektörü ile. Pratik çekiciliği, eşdoğrusal bir regresyonu tek bir iyi koşullandırılmış skalere indirgemesidir; verileriniz üzerindeki varyans payı daha düşük çıksa bile yapmaya değer.
İşlemlerin Sınıflandırılması: Alış ve Satış Başlatıldı

OFI'nin ticari sınıflandırmaya ihtiyacı yoktur. Ancak bunu ticarete dayalı önlemlerle karşılaştırmak istiyorsanız veya yalnızca toplu çubuklarınız varsa, yön çıkarımı yapmanız gerekir.
Alıntı Kuralı
ticari fiyatını geçerli orta nokta ile karşılaştırın:
Orta noktanın üzerinde bir işlem muhtemelen alıcının teklifi kaldırması anlamına geliyordu; altında, teklifi veren bir satıcı var.
Lee-Ready algoritması (1991), kotasyon kuralının belirsiz olduğu tam olarak orta noktadaki işlemler için geri dönüş onay kuralına sahip kotasyon kuralıdır. Onay kuralı (son fiyat değişikliğinin işareti, önceki tarafı sıfır adımla ileriye taşır) zaten çalışan bir _tick_sign() gönderen Zaman çubuklarının ötesinde içinde türetilmiş ve uygulanmıştır. Bildirilen Lee-Ready sınıflandırma doğruluğu pazara ve döneme bağlı olarak %72-85'tir.
Toplu Hacim Sınıflandırması (BVC)
Bireysel alım satımlar atanamadığında (birleştirilmiş çubuklar, halka açık mum API'lerinin çoğu) Easley, Lopez de Prado ve O'Hara'nın Toplu Hacim Sınıflandırması, bir çubuğun hacminin satın alma fraksiyonunu normalleştirilmiş fiyat değişiminden tahmin eder:
standart normal CDF ve son fiyat değişikliklerinden tahmin edilen ile. Onay düzeyi sınıflandırmasından daha az doğrudur ancak OHLCV üzerinde çalışır.
OFI Ne Değildir

Üç komşu nicelik OFI ile karıştırılıyor. Her biri bu blogun başka bir yerinde uygun şekilde ele alınmıştır; burada önemli olan ayrımlardır.
Statik emir defteri dengesizliği (OBI) anlık görüntü versiyonudur; kalan teklif hacmine karşı kalan teklif hacmi, etkinlik takibi yoktur. Formül ve çok düzeyli formu için DeepLOB'un geleneksel LOB özelliklerine bakın. OFI'nin asıl amacı zıtlıktır: OBI size kitabın durumunu anlatır, OFI size kitabın oraya nasıl geldiğini anlatır.
Ticaret dengesizliği (TI) ve bunun hacim ağırlıklı çeşitleri, makine öğrenimi ile yayılma modellemesinde sürekli özellikler olarak tanımlanan ve uygulanan imzalı ticaret akışıdır. İlişkiyle ilgili yayınlanmış bir sonuç burada yük taşıyor: OFI ve TI orta fiyat değişikliklerinde regresörler olarak birlikte girildiğinde TI istatistiksel olarak anlamsız hale geliyor. İçeriği kapsanmıştır. Bu, işlemler yerine defter olaylarını izlemek için ampirik bir durumdur; neredeyse işlem haline gelen olaylar, gerçekleşenlerle aynı bilgileri taşır.
Hacim ağırlıklı orta bir dengesizlik ölçüsü değil, bir gerçeğe uygun değer tahmincisidir ve DeepLOB kapsamına girmektedir - bunun Stoikov'un mikro fiyatı olmadığı yönündeki adlandırma uyarısı da dahil olmak üzere, bu, saf ağırlıklı ortanın önyargılı olması nedeniyle tam olarak oluşturulmuş martingale ayarlı bir tahmincisidir.
Python Uygulaması

düzeylerine genelleştirilmiş CKS ayrıştırmasının doğrudan uygulaması.
Temel OFI Hesaplaması
import numpy as np
import pandas as pd
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class OrderBookSnapshot:
timestamp: float
bid_prices: np.ndarray # best bid at index 0, descending
ask_prices: np.ndarray # best ask at index 0, ascending
bid_sizes: np.ndarray
ask_sizes: np.ndarray
@dataclass
class OFICalculator:
"""
Computes Order Flow Imbalance from consecutive order book snapshots.
Supports multi-level OFI (MLOFI) up to `n_levels` deep.
"""
n_levels: int = 5
prev_snapshot: Optional[OrderBookSnapshot] = field(default=None, init=False)
def compute_level_ofi(
self,
prev_price: float, curr_price: float,
prev_size: float, curr_size: float,
side: str
) -> float:
"""Compute single-level OFI contribution for bid or ask side."""
if side == "bid":
if curr_price > prev_price:
return curr_size # new level appeared above
elif curr_price < prev_price:
return -prev_size # old level disappeared
else:
return curr_size - prev_size # same level, size changed
else: # ask side
if curr_price < prev_price:
return curr_size # new level appeared below
elif curr_price > prev_price:
return -prev_size # old level disappeared
else:
return curr_size - prev_size # same level, size changed
def update(self, snapshot: OrderBookSnapshot) -> Optional[np.ndarray]:
"""
Process new snapshot, return MLOFI vector of shape (n_levels,).
Returns None on first call (no previous snapshot to compare).
"""
if self.prev_snapshot is None:
self.prev_snapshot = snapshot
return None
prev = self.prev_snapshot
n = min(self.n_levels, len(snapshot.bid_prices), len(prev.bid_prices))
ofi = np.zeros(n)
for level in range(n):
e_buy = self.compute_level_ofi(
prev.bid_prices[level], snapshot.bid_prices[level],
prev.bid_sizes[level], snapshot.bid_sizes[level],
side="bid"
)
e_sell = self.compute_level_ofi(
prev.ask_prices[level], snapshot.ask_prices[level],
prev.ask_sizes[level], snapshot.ask_sizes[level],
side="ask"
)
ofi[level] = e_buy - e_sell
self.prev_snapshot = snapshot
return ofi
Windows'ta Toplama
@dataclass
class OFIAggregator:
"""
Aggregates raw OFI updates into fixed time windows.
Emits the regression inputs (aggregated MLOFI) and target (delta mid).
"""
window_seconds: float = 10.0
n_levels: int = 5
calculator: OFICalculator = field(init=False)
buffer: list = field(default_factory=list, init=False)
window_start: float = 0.0
def __post_init__(self):
self.calculator = OFICalculator(n_levels=self.n_levels)
def on_snapshot(self, snapshot: OrderBookSnapshot) -> Optional[dict]:
"""
Feed a new order book snapshot.
Returns aggregated window dict when a window completes, else None.
"""
ofi_vec = self.calculator.update(snapshot)
if ofi_vec is None:
self.window_start = snapshot.timestamp
return None
if not self.buffer:
self.window_start = snapshot.timestamp
self.buffer.append({
"timestamp": snapshot.timestamp,
"ofi": ofi_vec.copy(),
"mid": (snapshot.bid_prices[0] + snapshot.ask_prices[0]) / 2,
})
elapsed = snapshot.timestamp - self.window_start
if elapsed >= self.window_seconds:
return self._flush()
return None
def _flush(self) -> dict:
"""Aggregate buffered OFI updates into a single window record."""
ofi_matrix = np.array([b["ofi"] for b in self.buffer])
agg_ofi = ofi_matrix.sum(axis=0) # shape: (n_levels,)
result = {
"window_start": self.window_start,
"window_end": self.buffer[-1]["timestamp"],
"n_updates": len(self.buffer),
"mid_open": self.buffer[0]["mid"],
"mid_close": self.buffer[-1]["mid"],
"delta_mid": self.buffer[-1]["mid"] - self.buffer[0]["mid"],
"ofi_level1": agg_ofi[0],
"ofi_total": agg_ofi.sum(),
"mlofi": agg_ofi,
}
self.buffer.clear()
return result
Toplayıcının ne yayınladığına dikkat edin: aynı pencere üzerinde mlofi ve delta_mid. Eş zamanlı gerileme budur. Tahmine dayalı bir sonuç elde etmek için, penceresinin mlofi penceresini penceresinin delta_mid ile eşleştirin ve çok daha kötü bir uyum bekleyin.
Ticaret Sınıflandırması (Lee-Ready)
def classify_trades_lee_ready(
trades: pd.DataFrame,
quotes: pd.DataFrame
) -> pd.DataFrame:
"""
Classify trades as buy (+1) or sell (-1) using Lee-Ready:
quote rule first, tick rule as fallback at the midpoint.
Parameters
----------
trades : DataFrame with columns ['timestamp', 'price', 'size']
quotes : DataFrame with columns ['timestamp', 'bid', 'ask']
Returns
-------
trades with added 'side' column
"""
trades = trades.sort_values("timestamp").copy()
quotes = quotes.sort_values("timestamp")
trades = pd.merge_asof(
trades, quotes,
on="timestamp",
direction="backward"
)
trades["mid"] = (trades["bid"] + trades["ask"]) / 2
trades["side"] = np.where(
trades["price"] > trades["mid"], 1,
np.where(trades["price"] < trades["mid"], -1, 0)
)
trades["price_diff"] = trades["price"].diff()
tick_sign = np.sign(trades["price_diff"])
tick_sign = tick_sign.replace(0, np.nan).ffill().fillna(1)
midpoint_mask = trades["side"] == 0
trades.loc[midpoint_mask, "side"] = tick_sign[midpoint_mask].astype(int)
return trades
Sinyalin Normalleştirilmesi
class OFISignal:
"""
Rolling z-score normalization of aggregated OFI.
Deliberately does NOT convert OFI into a predicted return: that
requires a fitted beta, and beta is venue-, pair- and regime-specific.
Fit it on your own data before wiring this into anything.
"""
def __init__(self, window_seconds: float = 10.0, n_levels: int = 5,
lookback: int = 100):
self.aggregator = OFIAggregator(
window_seconds=window_seconds, n_levels=n_levels,
)
self.lookback = lookback
self.ofi_history: list[float] = []
def process(self, snapshot: OrderBookSnapshot) -> Optional[dict]:
agg = self.aggregator.on_snapshot(snapshot)
if agg is None:
return None
ofi = agg["ofi_level1"]
self.ofi_history.append(ofi)
if len(self.ofi_history) > self.lookback:
self.ofi_history.pop(0)
if len(self.ofi_history) >= 20:
arr = np.array(self.ofi_history)
mu, sigma = arr.mean(), arr.std()
zscore = (ofi - mu) / max(sigma, 1e-10)
else:
zscore = 0.0
return {**agg, "ofi_zscore": zscore}
OFI'nin Takıldığı Yer

Piyasa yapıcılığı. OFI, Avellaneda-Stoikov piyasa yapıcısında: 'de zaten türetilmiş ve kodlanmış stok çarpıklığının üstüne, rayiç değere ilişkin tahmine dayalı bir çarpıklık terimi olarak giriyor. İki terim farklı soruları yanıtlıyor - akış terimi fiyatın nereye gittiğini söylüyor, envanter terimi ise neyi tutmaya gücünüzün yettiğini söylüyor - ve yayınlanan makale, pozitif envanterin neden her iki teklifi de aşağıya ittiği de dahil olmak üzere ikincisini kapsıyor. Büyük bir aynı zamanda tüccar kimliğinin dijital parmak izleri ve anormallik tespiti içinde kataloglanan savunma tepkileri (genişletme, küçültme, bir tarafa çekme) için makul bir ters seçim tetikleyicisidir.
Yürütme. OFI, ayrı bir aciliyet denetleyicisi değil, taktik katmanının doldurma olasılığı tahmini için bir girdidir. Karşılıklı çapraz karar, açık bir başabaş aritmetiğidir — ile — ve alt emir yürütme taktikleri içinde yaşar; bu aynı zamanda taktik katmanının aciliyeti asla kendi pazar görüşünden yeniden türetmemesi gerektiğini, çünkü bu aynı fikirde olmayan iki kontrolör yarattığını savunur.
Pratik Hususlar

Sinyal yarı ömrü ve yuvarlanan yeniden kalibrasyon. Bu, OFI'ye özgü kısımdır. OFI'nin tahmin içeriği, likit enstrümanlarda milisaniyelerden saniyelere kadar uzanan bir zaman ölçeğinde azalır; bu, toplama penceresinin serbest bir parametre olmadığı, ufuktaki bir bahis olduğu anlamına gelir. Ve bir sabit değildir: gün içinde, derinlikle ve planlanmış olaylar etrafında hareket eder, böylece herhangi bir üretim uyumu, bir değeri bir geçmiş testten sabitlemek yerine, değişen pencerelerde yeniden tahmin eder.
Buradaki diğer her şey başka bir yerde ele alınmıştır. Gecikme bütçeleri ve ortak yerleşim / FPGA / çekirdek atlama merdiveni: DeepLOB'un üretim bölümü. U şeklindeki gün içi likidite modeli ve değişen normalleşme istatistikleri: spread modelleme. Mekan bazında yeniden kalibrasyon ve Nasdaq'a takılan bir modelin neden dokunulmadan bir kripto çiftine aktarılmayacağını: tekrar DeepLOB, parçalanma tarafı akıllı sıra yönlendirme ile.
Manipülasyon. Bu modele özgü ve açıkça belirtilmeye değer bir sonuç vardır: CKS ayrıştırması, herhangi bir niyet veya ısrar kavramı olmadan, her olayı yalnızca boyutuna göre ağırlıklandırır. Bu nedenle, bir sahtekarlık yerleştirme ve iptal etme boyutu, yapısı gereği tam ağırlıkta doğrudan sinyale enjekte edilir. Tespit buluşsal yöntemleri (iptal oranları, sipariş yaşam süreleri, fiyat yaklaşırken duvar davranışı) kuyruk konumu ve sipariş defteri duvar analizi; mekanlar arası hayalet likidite akıllı sipariş yönlendirmesinde mevcuttur.
Temel Çıkarımlar

-
OFI bir anlık görüntü değil, bir olay ayrıştırmasıdır. Üç dallı gösterge formülü, her kitap başı geçişini (fiyat artışı, fiyat düşüşü, boyut değişikliği) ardışık iki anlık görüntüden tek bir imzalı sayıya eşler ve başka hiçbir şey yapmaz.
-
R-kare başlığı eşzamanlıdır. CKS %50-65 rakamı aynı aralıktaki fiyat hareketlerini ayrıştırır; bu bir tahmin değildir ve ileriye dönük getiri modelleriyle karşılaştırılmamalıdır.
-
Çok seviyeli OFI seviyeleri ekler ve PCA bunları daraltır. Yayınlanan artımlı ve %89 varyans sonuçları Nasdaq hisse senetlerinden alınmıştır. Derinliğin hala bir kripto kitabına yardımcı olup olmadığı burada test edilmemiştir.
-
OFI ticaret dengesizliğini kapsar. Ortaklaşa girildiğinde TI önemsiz hale gelir - OFI'nin gördüğü ve TI'nın yapamadığı iptaller fark yaratır.
-
Modelin niyeti kördür. Boyuta göre eşit ağırlıklandırma, onu taklit edilebilir kılan şeydir.
-
Bu makaledeki hiçbir şey ölçülmemiştir. Alıntılanan her sayı hisse senedi literatüründen alınmıştır. Bu sinyal sermayeye ulaşmadan önce, kendi kitap verilerinize uyum sağlanması, gecikmeli bir spesifikasyonun ayrıca raporlanması ve kenarın ücretlerden ve spreadden sağ çıkıp çıkmadığının kontrol edilmesi gerekir.
Daha Fazla Okuma

- Devam, R., Kukanov, A. ve Stoikov, S. (2014). "Sipariş Defteri Olaylarının Fiyat Etkisi." Finansal Ekonometri Dergisi, 12(1), 47-88.
- Xu, K., Gould, M. ve Howison, S. (2019). "Limitli Emir Defterinde Çok Seviyeli Emir Akışı Dengesizliği." arXiv:1907.06230.
- Kolm, P., Turiel, J. ve Westray, N. (2023). "Derin Emir Akışı Dengesizliği: Limit Emir Defterinden Çoklu Ufuklardaki Alfanın Çıkarılması." Matematiksel Finans, 33(4).
- Lee, C. ve Hazır, M. (1991). "Gün İçi Verilerden Ticaret Yönünün Çıkarılması." Finans Dergisi, 46(2), 733-746.
- Easley, D., Lopez de Prado, M. ve O'Hara, M. (2012). "Yüksek Frekanslı Bir Dünyada Akış Toksisitesi ve Likidite." Finansal Araştırmaların İncelenmesi, 25(5), 1457-1493.
Yazarlar
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.