← Maqolalarga qaytish
May 26, 2026
5 daqiqa o'qish

DeepLOB: Limit order kitobida chuqur o'rganish

DeepLOB: Limit order kitobida chuqur o'rganish
#deep-learning
#order-book
#LOB
#microstructure
#HFT
#market-making
📖
Part 5 of 6 · Collection
Order Book & Market Microstructure

Limit order kitobi (LOB) zamonaviy elektron bozorlarning markaziy ma'lumotlar tuzilmasidir. Har bir bid, har bir ask, har bir bekor qilish — barchasi LOB ichida yashaydi. O'nlab yillar davomida miqdoriy tadqiqotchilar bu ma'lumotlardan qo'lda xususiyatlar yaratib kelishgan: order imbalance nisbatlari, vaznlangan mid-price'lar, navbat pozitsiyasi signallari. DeepLOB esa boshqa yo'lni tanladi — u ushbu xususiyatlarni gibrid CNN-LSTM arxitekturasi yordamida xom order book snapshotlaridan bevosita o'rganadi.

Zhang, Zohren va Roberts tomonidan Oxford-Man institutida 2019-yilda nashr etilgan DeepLOB shuni ko'rsatdiki, xom kitob ma'lumotlarida end-to-end o'qitilgan yagona chuqur tarmoq mid-price harakatini bashorat qilishda kuchli klassik bazaviy modellar bilan raqobatlasha oladi yoki ulardan ustun keladi. Ammo dalillar haqida aniq bo'lishimiz kerak. Ko'pchilik maqolalar keltiradigan FI-2010 benchmark to'plami — mualliflarning o'zlari buni yetarli emas deb hisoblashadi: "juda qisqa, downsample qilingan va kamroq likvid bozordan olingan" — va ular London Fond Birjasi (LSE) ma'lumotlari asosida ancha kattaroq ikkinchi baholashni o'zlarining kuchliroq natijasi sifatida taqdim etishadi. Ushbu LSE tadqiqoti beshta o'qitish aksiyasi va beshta test aksiyasining taxminan bir yillik davrini, 100 milliondan ortiq namunani qamrab oladi va transfer learning'ni namoyish etadi: bitta aksiyalar to'plamida o'qitilgan model hali ko'rilmagan aksiyalarda ham bashorat qila oladi. Aynan shu transfer natija, FI-2010 reytingi emas, maqolaning haqiqiy bosh xulosasidir. Ushbu maqolada biz arxitekturani, matematikani, haqiqiy raqamlarni va ishlaydigan PyTorch qayta implementatsiyasini tahlil qilamiz.

Ma'lumotlar tuzilmasi sifatida limit order kitobi

Isometric view of a limit order book: stacked bid and ask volume levels forming a depth tensor around the mid-price

Limit order kitobi ikkita saralangan ro'yxatni saqlaydi — bidlar (sotib olish buyurtmalari) va asklar (sotish buyurtmalari) — har biri narx darajasi bo'yicha tashkil etilgan. Har bir darajada kitob narxni va turgan buyurtmalarning umumiy hajmini qayd etadi.

LL darajali order kitobi uchun tt vaqtidagi bitta snapshot 4L4L qiymatlardan iborat vektordir:

xt=[p1a,v1a,p1b,v1b,p2a,v2a,p2b,v2b,,pLa,vLa,pLb,vLb]\mathbf{x}_t = [p_1^{a}, v_1^{a}, p_1^{b}, v_1^{b}, p_2^{a}, v_2^{a}, p_2^{b}, v_2^{b}, \ldots, p_L^{a}, v_L^{a}, p_L^{b}, v_L^{b}]

bu yerda piap_i^{a} va viav_i^{a}ii darajadagi ask narxi va hajmi, pibp_i^{b}, vibv_i^{b} esa mos ravishda bid tomonidagi qiymatlar. 1-daraja eng yaxshi bid va eng yaxshi askni (BBO) o'z ichiga oladi; ularning farqi bid-ask spreadidir.

FI-2010 benchmark to'plamida L=10L = 10, ya'ni har bir snapshot uchun 40 ta xususiyat. FI-2010 NASDAQ Nordic'dagi beshta fin aksiyasidan (Kesko, Outokumpu, Sampo, Rautaruukki, Wartsila) o'n ketma-ket savdo kunida, 2010-yil 1-14-iyun davomida yig'ilgan taxminan 4 million xom limit-order xabari asosida qurilgan. Muhim jihati shundaki, DeepLOB 4 million snapshotda o'qitilmaydi: benchmark bu xabarlarni (har 10 hodisada bir marta) downsample qilib, 394,337 ta namunadan iborat normallashtirilgan ko'rinishga keltiradi. Model aslida ko'radigan narsa aynan shu downsample qilingan, normallashtirilgan shakl — bu mualliflar FI-2010'ni yakuniy so'z sifatida qabul qilishdan ogohlantirishining sabablaridan biridir.

Mid-price va uning harakatlari

tt vaqtidagi mid-price eng yaxshi bid va askning o'rtachasidir:

ptmid=p1a(t)+p1b(t)2p_t^{mid} = \frac{p_1^{a}(t) + p_1^{b}(t)}{2}

DeepLOB mid-price harakatining yo'nalishini kk hodisalik kelajak gorizontida bashorat qiladi. Yorliq (label) tekislangan return, lekin adabiyotda ikkita tekislash konventsiyasi borligiga e'tibor bering — ular bir-birining o'rnini bosa olmaydi:

  • Kelajak-o'rtacha vs hozirgi narx (Tsantekidis va boshq.): keyingi kk hodisadagi o'rtacha mid-price'ni xom hozirgi mid-price bilan solishtiradi.
  • Kelajak-o'rtacha vs oldingi-o'rtacha (Ntakaris va boshq., FI-2010'ning kanonik yorlig'i, shuningdek DeepLOB o'zining LSE ma'lumotlari uchun ishlatgan usul): ham etalon, ham maqsad tekislangan.
lt(k)=m+(t)m(t)m(t),m(t)=1ki=0k1ptimid,m+(t)=1ki=1kpt+imidl_t(k) = \frac{m_+(t) - m_-(t)}{m_-(t)}, \qquad m_-(t) = \frac{1}{k}\sum_{i=0}^{k-1} p_{t-i}^{mid}, \quad m_+(t) = \frac{1}{k}\sum_{i=1}^{k} p_{t+i}^{mid}

Etalonni tekislash (nafaqat kelajakni) yakka tick tebranishlaridan kelib chiquvchi yorliq shovqinini sezilarli darajada kamaytiradi, shuning uchun oldingi/keyingi-o'rtacha shakli afzal ko'riladi. Qaysi birini ishlatishingizdan qat'i nazar, uzluksiz return ±α\pm\alpha qat'iy chegaralar yordamida uchta sinfga — yuqoriga, pastga, statsionar — diskretlashtiriladi:

yt={1if lt(k)>α0if lt(k)α1if lt(k)<αy_t = \begin{cases} 1 & \text{if } l_t(k) > \alpha \\ 0 & \text{if } |l_t(k)| \leq \alpha \\ -1 & \text{if } l_t(k) < -\alpha \end{cases}

FI-2010 to'plami beshta bashorat gorizonti uchun yorliqlarni taqdim etadi: k{10,20,30,50,100}k \in \{10, 20, 30, 50, 100\} hodisa.

An'anaviy LOB xususiyatlari

Chuqur o'rganishdan oldin tadqiqotchilar qo'lda yaratilgan xususiyatlarga tayanishgan. Ularni tushunish muhim, chunki DeepLOB atayin ko'plarini eslatadigan tarzda tuzilgan — uning arxitekturasi bu miqdorlar bilan motivatsiyalangan, garchi ularni aynan takrorlamasa ham.

Order Book Imbalance (OBI)

Eng ko'p ishlatiladigan mikrostruktura signali. Kitobning yuqori qismida:

OBI1=v1bv1av1b+v1a\text{OBI}_1 = \frac{v_1^{b} - v_1^{a}}{v_1^{b} + v_1^{a}}

Ask hajmiga nisbatan ko'proq bid hajmi yuqoriga bosim borligini ko'rsatadi. Ko'p darajali imbalance LL darajalar bo'yicha agregatlanadi:

OBIL=i=1Lvibi=1Lviai=1Lvib+i=1Lvia\text{OBI}_L = \frac{\sum_{i=1}^{L} v_i^{b} - \sum_{i=1}^{L} v_i^{a}}{\sum_{i=1}^{L} v_i^{b} + \sum_{i=1}^{L} v_i^{a}}

Hajm bo'yicha vaznlangan mid-price

Standart mid-price ikkala tomonni teng vaznlaydi. Hajm bo'yicha vaznlangan mid-price (shuningdek vaznlangan mid yoki VAMP deb ham ataladi) kitobning og'irroq tomoniga qarab og'adi. Kitob yuqorisidagi imbalance'ni I=v1b/(v1b+v1a)I = v_1^{b}/(v_1^{b}+v_1^{a}) deb yozsak, bu ikki narxning imbalance-vaznlangan o'rtachasi bo'ladi:

pwmid=Ip1a+(1I)p1b=v1bp1a+v1ap1bv1b+v1ap^{wmid} = I\, p_1^{a} + (1 - I)\, p_1^{b} = \frac{v_1^{b}\, p_1^{a} + v_1^{a}\, p_1^{b}}{v_1^{b} + v_1^{a}}

Kesishma-vaznlashga e'tibor bering: ask narxi bid hajmi bilan vaznlanadi va aksincha. Bid hajmi ustunlik qilganda (I1I \to 1), vaznlangan mid askka qarab siljiydi — bu imbalance'ga ega kitob og'irroq tomonga siljib hal bo'lishini kutish bilan mos keladi.

Nomlash haqida bir ogohlantirish. Bu statik, hajm bo'yicha vaznlangan mid Stoikov'ning microprice'i emas. Stoikov'ning micro-price'i (2018) — spread va imbalance qanday rivojlanishi uchun rekursiv tuzatishdan olingan martingale bilan sozlangan baholovchi Mt+g(I,S)M_t + g(I, S); uning butun mohiyati shundaki, sodda vaznlangan mid noxolis va martingale emas. Bu ikki alohida obyekt; biz bu yerda vaznlangan midni uning soddaligi uchun ishlatamiz, microprice o'rniga emas.

Depth Imbalance

Kitobning shaklini BBO'dan tashqarida o'lchaydi:

DIi=vibviavib+via,i=1,,L\text{DI}_i = \frac{v_i^{b} - v_i^{a}}{v_i^{b} + v_i^{a}}, \quad i = 1, \ldots, L

Spread va nisbiy spread

st=p1a(t)p1b(t),strel=stptmids_t = p_1^{a}(t) - p_1^{b}(t), \qquad s_t^{rel} = \frac{s_t}{p_t^{mid}}

Bu xususiyatlar kuchli, lekin cheklangan. Ularni yaratish uchun soha bilimi kerak, ular murakkab nolineer o'zaro ta'sirlarni qamrab olmaydi va ketma-ket snapshotlar bo'yicha vaqtinchalik dinamikani hisobga olmaydi. DeepLOB bu uch cheklovning barchasini hal qiladi.

DeepLOB arxitekturasi

DeepLOB architecture: a raw order-book tensor flowing through convolutional layers, an inception module, and an LSTM

Arxitektura har biri o'ziga xos rolga ega uchta blokdan iborat:

  1. Konvolyutsion blok — order book snapshotidan fazoviy xususiyatlarni ajratib oladi
  2. Inception moduli — ko'p miqyosli vaqtinchalik naqshlarni ushlaydi
  3. LSTM blok — vaqt bo'yicha ketma-ket bog'liqliklarni modellashtiradi

Tarmoqning kirishi (T,L×4)(T, L \times 4) shaklidagi tenzor bo'lib, TT — orqaga qarash oynasi (maqolada 100 vaqt qadami), L×4=40L \times 4 = 40 esa ikkala tomondagi 10 daraja narx va hajm uchun.

1-blok: konvolyutsion xususiyat ajratish

Birinchi konvolyutsion qatlamlar narx va hajm o'rtasidagi o'zaro ta'sirlarni har bir darajada o'rganish uchun xususiyat o'lchami bo'yicha ishlaydi.

1-qatlam: filtr o'lchami 1×21 \times 2 va qadami (1,2)(1, 2) bo'lgan konvolyutsiya har bir narx-hajm juftligiga qo'llaniladi. Bu har bir (pi,vi)(p_i, v_i) juftligini bitta xususiyatga jamlaydi — bu har bir darajada "narx-hajm o'zaro ta'siri"ni hisoblashga o'xshaydi. Kenglik 40 dan 20 gacha qisqaradi.

2-qatlam: 1×21 \times 2, qadami (1,2)(1, 2) konvolyutsiya bir xil darajadagi mos bid-ask juftliklari bo'yicha ishlaydi. Bu har bir darajadagi spread va imbalance ma'lumotini ushlaydi. Kenglik 20 dan 10 gacha qisqaradi.

3-qatlam: 1×101 \times 10 konvolyutsiya barcha 10 daraja bo'yicha integratsiya qilib, chuqurlik o'lchamini 1 kenglikka torait iradi. Bu har bir vaqt qadami uchun to'liq chuqurlik profilini kodlaydigan yagona agregatlangan xususiyatni hosil qiladi.

Har bir 1×21 \times 2 / 1×101 \times 10 qadamdan keyin vaqt o'qi bo'yicha ikkita (4,1)(4, 1) konvolyutsiya keladi, har biri LeakyReLU aktivatsiyasi va batch normallashtirish bilan. E'tibor bering, padding=(1, 0) bilan bu (4,1)(4, 1) konvolyutsiyalar vaqt o'lchamini saqlab qolmaydi: har biri uni bir qadamga qisqartiradi (Tout=Tin1T_{\text{out}} = T_{\text{in}} - 1). 1-3-bloklardagi olti xil qatlam bo'yicha vaqt o'qi inception modulidan oldin 100 dan 94 gacha qisqaradi — quyidagi koddagi shakl izohlari buni aniq ko'rsatadi.

Dizayn atayin katta fazoviy filtrlardan qochadi. 1×21 \times 2 filtrlar LOB ma'lumotlarining tabiiy juftlash tuzilmasini — narx bilan hajm, bid bilan ask — hurmat qiladi. Bu induktiv moyillik hal qiluvchi ahamiyatga ega: 3×33 \times 3 filtr qo'shni darajalar va tomonlarni moliyaviy ma'noga ega bo'lmagan tarzda aralashtirib yuborar edi.

2-blok: inception moduli

Konvolyutsion blok 40 ta xususiyatni ixcham fazoviy tasvirga (kenglik 1) qisqartirgandan so'ng, inception moduli bir vaqtning o'zida bir nechta vaqtinchalik miqyoslardagi naqshlarni ushlash uchun vaqt o'lchami bo'yicha ishlaydi.

DeepLOB inception moduli to'rtta parallel yo'lga ega bo'lib, har biri 32 kanal hosil qiladi, barchasi birlashtiriladi:

  • 1×11 \times 1 bottleneck \to 3×13 \times 1 vaqtinchalik konv: qisqa muddatli vaqtinchalik naqshlar (3 vaqt qadami)
  • 1×11 \times 1 bottleneck \to 5×15 \times 1 vaqtinchalik konv: o'rtacha muddatli vaqtinchalik naqshlar (5 vaqt qadami)
  • 3×13 \times 1 max-pool \to 1×11 \times 1 konv: tekislangan, downsample qilingan ko'rinishni saqlaydigan pooling yo'li
  • (1×11 \times 1 qisqartirishlar vaqtinchalik konvolyutsiyalardan oldin nuqta-vaqtdagi bottleneck vazifasini bajaradi)

Har bir vaqtinchalik yo'l simmetrik padding'dan foydalanadi, shunda vaqt o'lchami inception blokida saqlanadi (yuqoridagi konv bloklardan farqli o'laroq). Chiqishlar kanal o'lchami bo'yicha birlashtiriladi, bu tarmoqqa bir vaqtning o'zida ko'p miqyosli vaqtinchalik xususiyatlarga kirish imkonini beradi.

Bu GoogLeNet inception arxitekturasidan ilhomlangan, lekin 2D tasvirlar o'rniga 1D vaqtinchalik ma'lumotlar uchun moslashtirilgan. Asosiy g'oya shundaki, LOB dinamikasi bir nechta vaqt miqyosida amal qiladi: tick-ma-tick shovqin, qisqa muddatli momentum va uzunroq gorizontdagi mean reversion bir vaqtning o'zida mavjud.

Quyidagi PyTorch qayta implementatsiyasi kodni o'qilishi oson qilib qolish uchun soddalashtirilgan uch yo'lli variantni (ikkita vaqtinchalik konv plyus 1×11\times1 yo'l) taqdim etadi; u max-pool yo'lini o'tkazib yuboradi. Buni aniq ta'kidlaymiz, chunki bu maqoladan chetlanish, asl moduldan farq qiladi.

3-blok: LSTM ketma-ketlik modellashtirishi

Inception modulining chiqishi butun TT uzunlikdagi ketma-ketlikni qayta ishlaydigan LSTM qatlamiga uzatiladi. LSTM konvolyutsiyalar o'zi qo'lga kirita olmaydigan uzoq masofali vaqtinchalik bog'liqliklarni — rejim o'zgarishlari, kun vaqtidagi effektlar va rivojlanib boruvchi bozor sharoitlarini — ushlaydi.

LSTM'ning yakuniy yashirin holati softmax aktivatsiyasi bilan to'liq bog'langan qatlamdan o'tkazilib, uchta sinf (yuqoriga, pastga, statsionar) bo'yicha ehtimollik taqsimotini hosil qiladi.

Yo'qotish funksiyasi

Model kategorik cross-entropy bilan o'qitiladi:

L=1Ni=1Nc=13yi,clog(y^i,c)\mathcal{L} = -\frac{1}{N} \sum_{i=1}^{N} \sum_{c=1}^{3} y_{i,c} \log(\hat{y}_{i,c})

bu yerda yi,cy_{i,c} — one-hot kodlangan haqiqiy yorliq, y^i,c\hat{y}_{i,c} esa cc sinfi uchun bashorat qilingan ehtimollik.

PyTorch qayta implementatsiyasi

Asl DeepLOB TensorFlow backend'idagi Keras'da qurilgan; mualliflarning repozitoriyasi (zcakhaa) keyinchalik PyTorch portini qo'shdi. Quyidagi kod bizning o'zimizning ko'rgazmali PyTorch qayta implementatsiyamiz, rasmiy versiya emas. U maqoladan biz kod ichida belgilagan ikki jihatda farq qiladi: inception max-pool yo'lini o'tkazib yuboradi (to'rtta o'rniga uchta yo'l) va kanal sonlarini kattalashtiradi. Maqola konv bloklar davomida 16 filtr va inception yo'l boshiga 32 filtr ishlatadi (LSTM kirishi 3×32=963 \times 32 = 96), bu taxminan 60 ming parametrli ixcham modelni beradi. Quyidagi kod bo'lagi 32 konv / 64 inception filtrlarini ishlatadi (LSTM kirishi 192) — ichki jihatdan izchil va ishga tushiriladigan, lekin asl nusxadan og'irroq. Maqolaga mos kelish uchun konv kanallarini 16 ga, inception kanallarini 32 ga va input_size=96 ga o'rnating.

import torch
import torch.nn as nn


class DeepLOB(nn.Module):
    """
    DeepLOB-style CNN-Inception-LSTM for limit order books.
    Reimplementation inspired by Zhang, Zohren, Roberts (2019),
    IEEE Transactions on Signal Processing, arXiv:1808.03668.

    NOTE: this is an illustrative reimplementation, NOT the official model.
    Differences from the paper:
      - inception has 3 paths here vs 4 in the paper (max-pool path omitted);
      - channel counts are scaled up (paper: 16 conv / 32 inception, input 96).

    Input shape: (batch_size, 1, T, 40)
        T = lookback window (e.g. 100)
        40 = 10 levels x 4 features (ask_price, ask_vol, bid_price, bid_vol)
    """

    def __init__(self, num_classes: int = 3, T: int = 100):
        super().__init__()
        self.num_classes = num_classes

        self.conv1 = nn.Sequential(
            nn.Conv2d(1, 32, kernel_size=(1, 2), stride=(1, 2)),
            nn.LeakyReLU(negative_slope=0.01),
            nn.BatchNorm2d(32),
            nn.Conv2d(32, 32, kernel_size=(4, 1), padding=(1, 0)),  # time -1
            nn.LeakyReLU(negative_slope=0.01),
            nn.BatchNorm2d(32),
            nn.Conv2d(32, 32, kernel_size=(4, 1), padding=(1, 0)),  # time -1
            nn.LeakyReLU(negative_slope=0.01),
            nn.BatchNorm2d(32),
        )

        self.conv2 = nn.Sequential(
            nn.Conv2d(32, 32, kernel_size=(1, 2), stride=(1, 2)),
            nn.LeakyReLU(negative_slope=0.01),
            nn.BatchNorm2d(32),
            nn.Conv2d(32, 32, kernel_size=(4, 1), padding=(1, 0)),  # time -1
            nn.LeakyReLU(negative_slope=0.01),
            nn.BatchNorm2d(32),
            nn.Conv2d(32, 32, kernel_size=(4, 1), padding=(1, 0)),  # time -1
            nn.LeakyReLU(negative_slope=0.01),
            nn.BatchNorm2d(32),
        )

        self.conv3 = nn.Sequential(
            nn.Conv2d(32, 32, kernel_size=(1, 10)),
            nn.LeakyReLU(negative_slope=0.01),
            nn.BatchNorm2d(32),
            nn.Conv2d(32, 32, kernel_size=(4, 1), padding=(1, 0)),  # time -1
            nn.LeakyReLU(negative_slope=0.01),
            nn.BatchNorm2d(32),
            nn.Conv2d(32, 32, kernel_size=(4, 1), padding=(1, 0)),  # time -1
            nn.LeakyReLU(negative_slope=0.01),
            nn.BatchNorm2d(32),
        )

        self.inp1 = nn.Sequential(
            nn.Conv2d(32, 64, kernel_size=(1, 1), padding=(0, 0)),
            nn.LeakyReLU(negative_slope=0.01),
            nn.BatchNorm2d(64),
        )
        self.inp2 = nn.Sequential(
            nn.Conv2d(32, 64, kernel_size=(1, 1), padding=(0, 0)),
            nn.LeakyReLU(negative_slope=0.01),
            nn.BatchNorm2d(64),
            nn.Conv2d(64, 64, kernel_size=(3, 1), padding=(1, 0)),
            nn.LeakyReLU(negative_slope=0.01),
            nn.BatchNorm2d(64),
        )
        self.inp3 = nn.Sequential(
            nn.Conv2d(32, 64, kernel_size=(1, 1), padding=(0, 0)),
            nn.LeakyReLU(negative_slope=0.01),
            nn.BatchNorm2d(64),
            nn.Conv2d(64, 64, kernel_size=(5, 1), padding=(2, 0)),
            nn.LeakyReLU(negative_slope=0.01),
            nn.BatchNorm2d(64),
        )

        self.lstm = nn.LSTM(
            input_size=192,  # 64 * 3 paths from the simplified inception
            hidden_size=64,
            num_layers=1,
            batch_first=True,
        )

        self.fc = nn.Linear(64, num_classes)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        """
        Args:
            x: Tensor of shape (batch, 1, T, 40)
        Returns:
            Tensor of shape (batch, num_classes)
        """
        h = self.conv1(x)   # (batch, 32, T-2, 20)
        h = self.conv2(h)   # (batch, 32, T-4, 10)
        h = self.conv3(h)   # (batch, 32, T-6, 1)   e.g. T=100 -> 94

        h_inp1 = self.inp1(h)  # (batch, 64, T-6, 1)
        h_inp2 = self.inp2(h)  # (batch, 64, T-6, 1)
        h_inp3 = self.inp3(h)  # (batch, 64, T-6, 1)
        h = torch.cat([h_inp1, h_inp2, h_inp3], dim=1)  # (batch, 192, T-6, 1)

        h = h.squeeze(-1)          # (batch, 192, T-6)
        h = h.permute(0, 2, 1)     # (batch, T-6, 192)

        h, _ = self.lstm(h)
        h = h[:, -1, :]  # take last hidden state

        out = self.fc(h)
        return out

Ma'lumotlarni oldindan qayta ishlash

FI-2010 to'plami z-score normallashtirilgan holda keladi. Jonli order book ma'lumotlari uchun xuddi shunday normallashtirish kerak:

import numpy as np
from torch.utils.data import Dataset


class LOBDataset(Dataset):
    """Dataset for limit order book snapshots."""

    def __init__(
        self,
        data: np.ndarray,
        labels: np.ndarray,
        T: int = 100,
    ):
        """
        Args:
            data: shape (num_snapshots, 40), raw LOB features
            labels: shape (num_snapshots,), class labels {0, 1, 2}
            T: lookback window length
        """
        self.data = data
        self.labels = labels
        self.T = T

        self.mean = data[:len(data) // 2].mean(axis=0)
        self.std = data[:len(data) // 2].std(axis=0)
        self.std[self.std == 0] = 1.0
        self.data = (self.data - self.mean) / self.std

    def __len__(self) -> int:
        return len(self.data) - self.T

    def __getitem__(self, idx: int):
        x = self.data[idx : idx + self.T].reshape(1, self.T, 40)
        y = self.labels[idx + self.T - 1]
        return torch.tensor(x, dtype=torch.float32), torch.tensor(
            y, dtype=torch.long
        )

O'qitish tsikli

def train_deeplob(
    model: DeepLOB,
    train_loader,
    val_loader,
    epochs: int = 50,
    lr: float = 0.01,
    device: str = "cuda",
):
    model = model.to(device)
    criterion = nn.CrossEntropyLoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=lr, eps=1)

    best_val_f1 = 0.0
    for epoch in range(epochs):
        model.train()
        train_loss = 0.0
        for x_batch, y_batch in train_loader:
            x_batch = x_batch.to(device)
            y_batch = y_batch.to(device)

            optimizer.zero_grad()
            logits = model(x_batch)
            loss = criterion(logits, y_batch)
            loss.backward()
            optimizer.step()
            train_loss += loss.item()

        model.eval()
        all_preds, all_labels = [], []
        with torch.no_grad():
            for x_val, y_val in val_loader:
                x_val = x_val.to(device)
                preds = model(x_val).argmax(dim=1).cpu()
                all_preds.extend(preds.numpy())
                all_labels.extend(y_val.numpy())

        from sklearn.metrics import f1_score
        val_f1 = f1_score(all_labels, all_preds, average="weighted")

        print(
            f"Epoch {epoch+1}/{epochs} | "
            f"Train Loss: {train_loss/len(train_loader):.4f} | "
            f"Val F1: {val_f1:.4f}"
        )

        if val_f1 > best_val_f1:
            best_val_f1 = val_f1
            torch.save(model.state_dict(), "deeplob_best.pt")

Asl maqoladagi asosiy o'qitish giperparametrlari:

  • Optimizator: Adam, ϵ=1\epsilon = 1 bilan (odatiy holatdan katta — shovqinli moliyaviy ma'lumotlarda yangilanishlarni barqarorlashtirishga yordam beradi)
  • O'qitish tezligi: 0.01
  • Batch hajmi: 32
  • Orqaga qarash oynasi: T=100T = 100 vaqt qadami

Biz validatsiyada aniqlik o'rniga vaznlangan F1'ni kuzatamiz, chunki uchta sinf muvozanatsiz — va, keyingi bo'limda ko'rsatilganidek, F1 aynan shu sababdan asl maqola ta'kidlaydigan metrikadir.

DeepLOB nimani ushlash uchun qurilgan

Microstructure signals DeepLOB learns: order-flow imbalance, queue dynamics, and volume-weighted mid-price pressure

DeepLOB'ning yoqimli jihatlaridan biri shundaki, uning bloklari yuqoridagi qo'lda yaratilgan xususiyatlar bilan qanchalik yaqin motivatsiyalangan. Bu yerda ehtiyot bo'lishimiz kerak: maqola bularni o'qitilgan tarmoqning isbotlangan xususiyatlari sifatida emas, dizayn intuitsiyalari sifatida taqdim etadi. U filtr vizualizatsiyalarini, aktivatsiya-imbalance korrelyatsiyalarini yoki LSTM nimaga e'tibor qaratishi haqidagi tahlilni nashr etmaydi. Shuning uchun quyidagini o'lchangan topilmalar emas, arxitektura niyati sifatida o'qing.

Birinchi konvolyutsion blok. 1×21 \times 2 filtrlar har bir darajada narx bilan hajmni juftlaydi. Tuzilishi jihatidan bu hajm bo'yicha vaznlangan narxni hosil qiluvchi operatsiya bilan bir xil — maqola birinchi qatlamni uning xususiyat xaritalari micro-price'ga o'xshash miqdorni hosil qilishini ta'kidlab motivatsiyalaydi. Tarmoq shu oilaga tegishli narsani qayta tiklashga qurilgan; biz uning aniq bir baholovchini isbotlangan tarzda qayta kashf etishini da'vo qilmaymiz.

Ikkinchi konvolyutsion blok. Bid-ask juftliklari bo'yicha ishlash orqali bu filtrlar bir nechta darajada imbalance'ga o'xshash xususiyatlarni o'rganishga moslashtirilgan — bu yana isbotlangan korrelyatsiya emas, qurilish orqali.

Inception moduli. Ko'p miqyosli vaqtinchalik konvolyutsiyalar turli chastotalardagi momentumni ushlash uchun mo'ljallangan: 1×11\times1 yo'l nuqta-vaqt tuzilmasiga, 3×13\times1 yo'l qisqa muddatli tendensiyalarga, 5×15\times1 yo'l biroz uzunroqlarga va (to'liq modulda) max-pool yo'li tekislangan ko'rinishga javob beradi.

LSTM qatlami. Rekurrent komponenta konvolyutsiyalar ifodalay olmaydigan uzoq masofali bog'liqliklar xotirasini — rejim o'zgarishlari va kun vaqtidagi effektlarni — qo'shadi. Biz kuchliroq da'volardan (masalan, LSTM volatil rejimlarda so'nggi ma'lumotlarni qayta vaznlaydigan "moslashuvchan e'tibor"ni amalga oshiradi degan) qochamiz; maqola buni ko'rsatmaydi.

FI-2010'dagi samaradorlik

Asl maqola ikkita protokolni baholaydi. 1-sozlama to'plamning ilgari normallashtirish bo'linishidan foydalanadi; 2-sozlama esa keyingi ko'pchilik ishlar solishtiradigan chuqur-o'rganish sozlamasidir. FI-2010 sinflar bo'yicha muvozanatsiz bo'lgani uchun, maqola aniqlik o'rniga F1'ni ta'kidlaydi va neyron bo'lmagan bazaviy modellar (SVM, MLP) uchun aniqlik/eslash asosidagi ko'rsatkichlarni beradi. Mana haqiqiy 2-sozlama raqamlari (F1, %):

Horizon (k) SVM MLP CNN-I LSTM DeepLOB
10 35.88 48.27 55.21 66.33 83.40
20 72.82
50 80.35

k=10k = 10 da DeepLOB shuningdek 83.40 F1 bilan bir qatorda 84.47% aniqlikni ham keltiradi. 2-sozlama faqat k{10,20,50}k \in \{10, 20, 50\} ni beradi — bu yerda k=100k = 100 qatori yo'q. (1-sozlama k{10,50,100}k \in \{10, 50, 100\} ni beradi, DeepLOB F1 mos ravishda 77.66 / 74.96 / 76.58.) Yuqoridagi tire belgilari maqola bu protokolda ushbu gorizontlarda jadvalga kiritmagan bazaviy katakchalarni bildiradi.

Bir nechta kuzatuv e'tiborga loyiq:

  1. DeepLOB qisqa gorizontda bazaviy modellardan katta farq bilan ustun keladi. k=10k = 10 da uning F1'i (83.40) LSTM (66.33), CNN-I (55.21), MLP (48.27) va SVM (35.88) dan ancha yuqori. Sifat tartibi — chuqur rekurrent-konvolyutsion modellar sodda CNN'lar, MLP'lar va SVM'lardan ustun — mustahkam xulosadir.
  2. Gorizont tendensiyasi monoton emas, "uzoqroq oson" degani emas. 2-sozlama bo'yicha DeepLOB'ning F1'i kk ning 10205010 \to 20 \to 50 o'zgarishida 83.4072.8280.3583.40 \to 72.82 \to 80.35 ga o'zgaradi — bu U-shaklidagi naqsh bo'lib, k=20k=20 eng qiyini, toza yuqoriga qarab yurish emas. Gorizont "osonroq"mi yoki yo'qmi ko'p jihatdan sozlamaga, α\alpha chegarasiga va yorliq-tekislash sxemasiga bog'liq; bu raqamlarga universal qonun sifatida qaramaslik kerak.
  3. DeepLOB har bir katakchada har bir klassik usuldan ustun kelmaydi. C(TABL) kabi kuchli bazaviy modellarga qarshi ba'zi gorizontlarda farq torayadi, shuning uchun "barcha klassik yondashuvlardan hamma joyda ustun" degan ta'rif haddan tashqari bo'rttirilgan bo'ladi. Himoya qilinadigan da'vo shuki, u raqobatbardosh-eng yaxshiga yaqin va qisqa gorizontda aniq eng yaxshi.

Va yana bir bor: maqolaning o'z nuqtai nazari shuki, FI-2010 masalani hal qilish uchun juda kichik va juda downsample qilingan. Uning kuchliroq dalili LSE tadqiqoti bo'lib, unda DeepLOB bitta aksiyalar to'plamida o'qitiladi va hali ham ko'rilmagan aksiyalarda bashorat qiladi — bu FI-2010 ko'rsata olmaydigan transfer-learning natijasi.

LOBFrame va replikatsiya inqirozi

Diverging in-sample and out-of-sample curves illustrating the order-book deep-learning replication crisis

LOBFrame benchmark freymvorki (Briola, Bartolucci, Aste, 2024) bu natijalarga sog'lom fikr qo'shimchasini beradi. DeepLOB'ning arxitekturasi puxta bo'lsa-da, freymvork bir nechta muhim ogohlantirishlarni ta'kidlaydi:

Mikrostruktura bog'liqligi. Model samaradorligi turli mikrostruktura xususiyatlariga ega aksiyalar bo'yicha sezilarli darajada farq qiladi. Likvid, katta-tick aksiyalarni bashorat qilish illikvid, kichik-tick asboblarga qaraganda osonroq. Bitta aksiyada kuchli ko'ringan model boshqasida sezilarli darajada yomonlashishi mumkin.

Bashorat vs foyda. Yuqori tasniflash aniqligi avtomatik ravishda savdo foydasiga aylanmaydi. LOBFrame bashorat qilingan harakat bid-ask spreadini yopish uchun yetarlicha katta ekanligiga bog'liq metrikalarni ta'kidlaydi. Model spreadni yengish uchun yetarlicha tez-tez va yetarlicha katta harakatlarda to'g'ri bo'lishi kerak — tor spredli aksiyalar uchun bu chegara yuqori.

Yorliq sezuvchanligi. α\alpha chegarasi va kk gorizonti tanlovi ham keltirilgan aniqlikka, ham bashoratlarning amaliy qiymatiga sezilarli ta'sir ko'rsatadi. Juda tor yorliqlar shovqinli maqsadlarni, juda keng yorliqlar esa arzimas darajada "aniq", ammo foydasiz bashoratlarni ishlab chiqaradi.

DeepLOB'dan tashqarida: hozirgi manzara

Constellation of modern order-book forecasting approaches orbiting the original DeepLOB model

DeepLOB nashr etilganidan beri bir nechta kengaytmalar paydo bo'ldi:

Limit order kitoblari uchun transformerlar (Wallbridge, 2020). Keyingi adabiyotda ko'pincha erkin tarzda "TransLOB" deb atalgan bu model aslida kauzal/dilated konvolyutsion xususiyat ajratuvchi bo'lib, undan keyin maskalangan ko'p boshli self-attention keladi — bu shunchaki LSTM Transformerga almashtirilgan DeepLOB emas; u inception+konv stekni qayta ishlatmaydi. U o'z davri uchun yangi FI-2010 state-of-the-art natijasini keltirgan.

Kripto-soha variantlari. Bir nechta guruhlar DeepLOB uslubidagi arxitekturalarni kriptovalyuta bozorlariga qo'llaydi, bu yerda order book dinamikasi aksiyalardan sezilarli farq qiladi — kengroq spredlar, 24/7 savdo va qayta o'qitishni talab qiladigan boshqacha ishtirokchilar tarkibi.

Attention bilan kengaytirilgan variantlar. Bir qator ishlar inception va LSTM bloklari orasiga ko'p boshli attention qo'shadi, bu tarmoqqa hozirgi bashorat uchun eng informativ darajalar yoki vaqt qadamlariga e'tibor qaratish imkonini beradi.

LOB-Bench (Nagy, Frey, Li, Sarkar, Vyetrenko, Zohren, Calinescu, Foerster, 2025). Bu benchmark e'tiborni bashoratdan generatsiyaga qaratadi, order book ma'lumotlarining generativ modellari qanchalik realistik ekanligini baholaydi — bu yo'nalishli bashoratdan ko'ra backtesting va agent o'qitish uchun dolzarb.

Ishlab chiqarish uchun amaliy fikrlar

Agar siz jonli savdo tizimida DeepLOB uslubidagi modelni joylashtirishni ko'rib chiqayotgan bo'lsangiz, bir nechta muhandislik masalalari yuzaga keladi:

Kechikish

Model sizning savdo tizimingizning kechikish byudjeti ichida bashoratlarni ishlab chiqarishi kerak. Sub-millisekund kechikishlarda ishlaydigan HFT tizimlar uchun optimallashtirilgan PyTorch inference ham juda sekin bo'lishi mumkin. Variantlarga quyidagilar kiradi:

  • TensorRT optimallashtirish bilan ONNX eksport
  • INT8'ga kvantlash
  • Eng kechikishga sezgir ilovalar uchun FPGA joylashtirish

Ma'lumotlar quvuri

Model belgilangan chastotada normallashtirilgan, tekislangan order book snapshotlarini kutadi. Amalda LOB yangilanishlari asinxron tarzda keladi. Sizga quyidagilar kerak:

  • Hozirgi kitob holatini saqlaydigan snapshot qayta tiklash dvigateli
  • (T,40)(T, 40) kirish tenzorini ishlab chiqaradigan belgilangan chastotali sampler
  • Aylanma statistika yordamida onlayn normallashtirish

Xususiyat barqarorligi

O'qitish ma'lumotlarida hisoblangan Z-score normallashtirish parametrlari vaqt o'tishi bilan siljiydi. Narxlar o'zgaradi, volatillik rejimlari siljiydi, bozor tuzilmasi rivojlanadi. Ishlab chiqarish tizimiga quyidagilar kerak:

  • Aylanma normallashtirish oynalari (masalan, statistikani kunlik qayta hisoblash)
  • Modelni qayta o'qitishni ishga tushirish uchun rejim aniqlash
  • Kirish taqsimoti siljishini kuzatish

Mikrostrukturaga ortiqcha moslashish (overfitting)

LOB naqshlari maydonga va asbobga xosdir. NASDAQ aksiyalarida o'qitilgan model Binance BTC/USDT'da qayta o'qitmasdan ishlamaydi. Hatto bir xil maydonda ham modellar quyidagilarga ortiqcha moslashishi mumkin:

  • Tick hajmi rejimi (katta-tick vs kichik-tick aksiyalar)
  • Kun vaqti naqshlari (ochilish auktsioni, tushlik pasayishi, yopilish krossi)
  • Vaqt o'tishi bilan o'zgaruvchi market maker xatti-harakati

Xulosa

DeepLOB chuqur o'rganishning bozor mikrostrukturasiga toza, yaxshi motivatsiyalangan qo'llanilishini ifodalaydi. Uning uch bloklik arxitekturasi — fazoviy xususiyatlar uchun CNN, ko'p miqyosli vaqtinchalik naqshlar uchun inception, ketma-ket bog'liqliklar uchun LSTM — limit order kitobi ma'lumotlarining tuzilmasiga tabiiy ravishda mos keladi.

Asosiy g'oya nafaqat chuqur model qo'lda yaratilgan xususiyatlarga teng kela olishi yoki ulardan ustun kelishi emas, balki arxitekturaning induktiv moyilliklari — 1×21 \times 2 filtrlar, inception parallelizmi, rekurrent xotira — order book qanday ishlashi haqidagi haqiqiy soha bilimini kodlashi. Bu moliyaviy ma'lumotlarga tashlangan umumiy chuqur tarmoq emas; bu limit order kitobining o'ziga xos geometriyasi atrofida ishlab chiqilgan arxitektura. Va uning eng ishonchli dalili mualliflarning o'zlari ishonmaydigan FI-2010 reytingi emas, balki LSE ma'lumotlarining bir yillik davri bo'yicha transfer-learning natijasidir.

Amaliyotchilar uchun DeepLOB kuchli bazaviy model va foydali qurilish bloki hisoblanadi. Tadqiqotchilar uchun u shuni ko'rsatadiki, puxta arxitektura dizayni — nafaqat model ko'lami — tuzilgan moliyaviy ma'lumotlar bo'yicha samaradorlikni belgilaydi. Faqat haqiqiy raqamlarni keltirishni, yorliq sxemasini kuzatishni va tasniflash aniqligini savdo foydasidan ancha uzoq narsa sifatida qabul qilishni unutmang.


References

  1. Zhang, Z., Zohren, S., & Roberts, S. (2019). DeepLOB: Deep Convolutional Neural Networks for Limit Order Books. IEEE Transactions on Signal Processing, 67(11), 3001-3012. arXiv:1808.03668

  2. Ntakaris, A., Magris, M., Kanniainen, J., Gabbouj, M., & Iosifidis, A. (2018). Benchmark Dataset for Mid-Price Forecasting of Limit Order Book Data with Machine Learning Methods. Journal of Forecasting, 37(8), 852-866. arXiv:1705.03233

  3. Briola, A., Bartolucci, S., & Aste, T. (2024). Deep Limit Order Book Forecasting (LOBFrame). arXiv:2403.09267

  4. Wallbridge, J. (2020). Transformers for Limit Order Books. arXiv:2003.00130

  5. Cont, R., Kukanov, A., & Stoikov, S. (2014). The Price Impact of Order Book Events. Journal of Financial Econometrics, 12(1), 47-88.

  6. Stoikov, S. (2018). The Micro-Price: A High-Frequency Estimator of Future Prices. Quantitative Finance, 18(12), 1959-1966.

  7. Nagy, P., Frey, S., Li, K., Sarkar, B., Vyetrenko, S., Zohren, S., Calinescu, A., & Foerster, J. (2025). LOB-Bench: Benchmarking Generative AI for Finance — an Application to Limit Order Book Data. ICML 2025. arXiv:2502.09172

  8. DeepLOB code (original in Keras/TensorFlow; the repository also provides a PyTorch port): github.com/zcakhaa/DeepLOB-Deep-Convolutional-Neural-Networks-for-Limit-Order-Books

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

Bozordan bir qadam oldinda bo'ling

Sun'iy intellekt savdo tahlillari, bozor tahlili va platforma yangiliklari uchun bizning xabarnomaga obuna bo'ling.

Biz sizning maxfiyligingizni hurmat qilamiz. Istalgan vaqtda obunadan chiqishingiz mumkin.