📝

Draft article

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

← Maqolalarga qaytish
August 22, 2026
5 daqiqa o'qish

Irregular Time in Tick Models: Continuous-Time Encodings vs. Plain Positional Embeddings

Irregular Time in Tick Models: Continuous-Time Encodings vs. Plain Positional Embeddings
#HFT
#tick-data
#deep-learning
#high-frequency
#prediction

Vaqt barlari hodisalar vaqtini buzadigan ixtiyoriy siqishdir, shuning uchun bar chegaralarini faoliyat belgilashi kerak. Bu fikr 17 xil bar turi va ishlaydigan generatorlari bilan Algoritmik savdo uchun bar turlari va agregatsiya usullari maqolasida to'liq ko'rsatilgan. Ushbu maqola undan bir qadam keyin, hali hal qilinmagan muammodan boshlanadi: tick, volume yoki imbalance barlariga o'tganingizdan keyin ham ularga beradigan model muntazam oraliqlarni taxmin qiladi. O'rganilgan pozitsion embeddingga ega nn.TransformerEncoder 7-pozitsiyani "yettinchi slot" deb qabul qiladi: bu tick 6-pozitsiyadan 200 mikrosekund yoki 40 soniya o'tib kelganining farqi yo'q. Hodisalar oralig'idagi vaqt — activity barlari aynan saqlashi kerak bo'lgan narsa — kirish qatlamida yana yo'qotiladi.

Demak, ushbu maqolaning savoli tor va tekshiriladigan: tick qachon sodir bo'lganini sequence modelga qanday bildirish kerak va murakkab yechim oddiy yechimdan ustunmi?

Zarur asoslar

Noqonuniy hodisa pulslari

Quyidagilar zarur bo'lgan asoslar. Ularning barchasi ushbu blogda allaqachon yoritilgan va bu yerda qayta chiqarilmaydi:

  • Mikrostruktura shovqini va bid-ask bounce. Rollning yashirin spread modeli tick daromadlaridagi manfiy ketma-ket kovariatsiyani narx birliklarida, birinchi tamoyillardan chiqaradi va keng tarqalgan implementatsiya xatosini ko'rsatadi: ML bilan bid-ask spreadini modellashtirish.
  • Order book xususiyatlari. Book imbalance, weighted mid-price, 1–5-darajalar bo'yicha depth ratio, book pressure va spread/tick ratio shu maqolada jadvalga kiritilgan; OBI hamda volume-weighted mid derivatsiyalari, weighted mid Stoikovning microprice'i emasligi haqidagi izoh bilan birga, DeepLOB: Limit Order Books uchun deep learning maqolasida berilgan.
  • Order flow va savdo intensivligi. Trade imbalance, VPIN va Kyle lambda spread modeling maqolasida; orderlar oralig'i va vaqt xususiyati sifatidagi Hawkes self-excitation intensivligi Raqamli iz: treyderni aniqlash maqolasida. Ushbu qoralama dastlab taklif qilgan sodda 1/dt intensivlik u yerdagi Hawkes formulasining zaifroq ko'rinishidir.
  • Kun ichidagi nostatsionarlik. U-shakldagi volume pattern, sokin davrlarda spreadning kengayishi va kun vaqtining sin/cos kodlanishi spread modeling maqolasida bozor rejimi xususiyatlari sifatida yoritilgan.
  • Label'lar. Ikkala smoothing konvensiyasi (future mean va current price; future mean va previous mean), α\alpha threshold bilan uch sinfli discretization hamda LOBFrame'ning label'lar α\alpha va kk ga sezgirligi haqidagi ogohlantirishi DeepLOB maqolasida berilgan.
  • Sinf nomutanosibligi. Dead zone bo'lsa, FLAT sinfi ustunlik qiladi. Shu sababli hisobot metrikasi accuracy emas, F1 bo'lishi kerak.
  • Bar to'lish davomiyligi. Volume bar to'lishi uchun ketadigan devor vaqti tick modeli uchun foydali xususiyatdir; uni yaratadigan generatorlar Bar turlari va agregatsiya usullari maqolasida.

Ushbu qoralamaning dastlabki versiyasi xato qilgani uchun bir narsani ochiq aytish kerak: yo'nalish aniqligining 50,0% dan 50,5% gacha oshishi o'z-o'zidan foydali degani emas. DeepLOB maqolasida muhokama qilingan LOBFrame'ning asosiy fikri shuki, aniqlik nimanidir anglatishidan oldin bashorat qilingan harakat spreadni qoplash uchun yetarlicha katta bo'lishi kerak. Halol salbiy natija aksini taxmin qilganda nima bo'lishini ko'rsatadi.

Bazaviy model

Asosiy ketma-ket hodisalarni kodlash

Bazaviy encoder sifatida DeepLOB uslubidagi CNN-Inception-LSTM'ni olaylik; arxitektura, tasdiqlangan FI-2010 Setup 2 raqamlari (F1 83.40 / accuracy 84.47, k=10k=10 da), LOBFrame ogohlantirishlari va ishlaydigan PyTorch qayta implementatsiyasi DeepLOB: Limit Order Books uchun deep learning maqolasida berilgan. Quyida bu encoderni o'zgartirmaymiz — savol uning kirish tasviriga nima qo'shilishida.

Notekis vaqtni kodlashning uchta usuli

Muqobil tartibsiz vaqt kodlashlari

Variant A: delta_t oddiy xususiyat sifatida

Oddiy javob: Δti=titi1\Delta t_i = t_i - t_{i-1} ni (log-transformatsiya qilingan, z-score ga keltirilgan) OFI va book imbalance yonida feature vektorining yana bir ustuni sifatida qo'shing va standart o'rganiladigan positional embeddingni saqlang. Bu hech qanday xarajat talab qilmaydi, bitta input o'lchamini qo'shadi va ishlab chiqarishdagi tick modellarining aksariyati amalda shunday ishlaydi.

Har qanday murakkabroq taklif aynan shu variantdan ustun kelishi kerak, ammo murakkab alternativalarni taklif qiladigan maqolalar ko'pincha bu bazani umuman keltirmaydi.

Variant B: uzluksiz vaqtli positional encoding

Diskret positional embeddingni o'tgan vaqtning o'rganiladigan time-scale'lar bo'yicha sinusoidal funksiyasi bilan almashtiring:

TE(Δt)=[sin(Δtτ1),cos(Δtτ1),,sin(Δtτd),cos(Δtτd)]\text{TE}(\Delta t) = \left[\sin\left(\frac{\Delta t}{\tau_1}\right), \cos\left(\frac{\Delta t}{\tau_1}\right), \ldots, \sin\left(\frac{\Delta t}{\tau_d}\right), \cos\left(\frac{\Delta t}{\tau_d}\right)\right]

bu yerda τ1,,τd\tau_1, \ldots, \tau_d mikrosekundlardan sekundlargacha log-oraliqda initsializatsiya qilinadigan o'rganiladigan time-scale parametrlari. Maqsad — attention hodisalarni slot indeksi bilan emas, vaqt bo'yicha muhimligi bilan og'irliklashi: 200 mikrosekund oldingi yirik trade'ga 50 millisekund oldingi kichik trade'dan boshqacha murojaat qilinishi kerak.

Qiziq tomoni — o'rganiladigan qism. Time-scale'larni 1 mikrosekunddan 10 sekundgacha log-oraliqda initsializatsiya qilib, modelni o'qitsangiz, time-scale'lar qayerda yakunlanishining o'zi o'lchovdir: agar ular millisekundlar tomon yig'ilsa, model bir necha millisekunddan keyingi hamma narsa o'zaro almashinadigan ekanini aytadi. Bu arxitektura haqida emas, bozor haqida xulosa.

import numpy as np
import torch
import torch.nn as nn

class ContinuousTimeEncoding(nn.Module):
    """Sinusoidal encoding for irregular inter-arrival times."""
    def __init__(self, d_model: int, num_timescales: int = 64):
        super().__init__()
        log_timescales = torch.linspace(
            np.log(1e-6), np.log(10.0), num_timescales
        )
        self.log_timescales = nn.Parameter(log_timescales)
        self.proj = nn.Linear(num_timescales * 2, d_model)

    def forward(self, delta_t: torch.Tensor) -> torch.Tensor:
        """
        Args:
            delta_t: (batch, seq_len) inter-arrival times in seconds
        Returns:
            (batch, seq_len, d_model) time encoding
        """
        timescales = torch.exp(self.log_timescales)  # (num_timescales,)
        scaled = delta_t.unsqueeze(-1) / timescales.unsqueeze(0).unsqueeze(0)
        encoding = torch.cat([torch.sin(scaled), torch.cos(scaled)], dim=-1)
        return self.proj(encoding)

Standart encoderga qo'shilganda, u aynan bitta qatorni — positional embedding qo'shiladigan qatorni — almashtiradi:

class TickTransformer(nn.Module):
    def __init__(self, input_dim: int, d_model: int = 128,
                 nhead: int = 8, num_layers: int = 4, num_classes: int = 3):
        super().__init__()
        self.feature_proj = nn.Linear(input_dim, d_model)
        self.time_encoding = ContinuousTimeEncoding(d_model)
        encoder_layer = nn.TransformerEncoderLayer(
            d_model=d_model, nhead=nhead,
            dim_feedforward=d_model * 4,
            dropout=0.1, batch_first=True
        )
        self.encoder = nn.TransformerEncoder(
            encoder_layer, num_layers=num_layers
        )
        self.head = nn.Linear(d_model, num_classes)

    def forward(self, features: torch.Tensor,
                delta_t: torch.Tensor) -> torch.Tensor:
        h = self.feature_proj(features) + self.time_encoding(delta_t)
        h = self.encoder(h)
        return self.head(h[:, -1, :])

Encoderning asosiy boilerplate'i yangi emas — xuddi shu nn.TransformerEncoderLayer karkasi spread modeling maqolasida Architecture 2 sifatida allaqachon e'lon qilingan. Yangilik faqat ContinuousTimeEncoding va o'rganiladigan time-scale g'oyasida.

Variant C: ticklar orasidagi uzluksiz latent holat (ODE-RNN)

Eng prinsipial variant latent holatni Neural ODE modellashtiradigan uzluksiz vaqt jarayoni deb qaraydi (Chen et al., 2018). Ticklar orasida hidden state o'rganiladigan differensial tenglama bo'yicha rivojlanadi:

dhdt=fθ(h(t),t)\frac{d\mathbf{h}}{dt} = f_\theta(\mathbf{h}(t), t)

Shomil kelganda, holat kuzatuv bilan yangilanadi:

h(ti+)=Update(h(ti),xi)\mathbf{h}(t_i^+) = \text{Update}(\mathbf{h}(t_i^-), \mathbf{x}_i)

Bu ODE-RNN framework'idir. U notekis oraliqlarni input feature sifatida emas, strukturaviy tarzda boshqaradi: solver hodisalar orasidagi aynan Δti\Delta t_i vaqt davomida integrallaydi, padding, interpolation yoki ma'lumot yo'qoladigan resampling bosqichisiz.

Narxi — hisoblash xarajati. ODE solver'lari ketma-ket ishlaydi va ularni parallel qilish qiyin, shuning uchun bu variant latency budget'ga sig'ishi eng qiyinidir. Bunday da'volarni ilgari surishdan oldin ularni qanday o'lchash kerakligi IPC solig'i maqolasidagi latency intizomi va backtest engine tezlik pog'onasida ko'rsatilgan. Bu variant deployment nomzodi sifatida emas, explicit time modeling nimalar berishi mumkinligining yuqori chegarasi sifatida kiritilgan.

Hodisa og'irliklariga ega attention

Tadbirning vaznli diqqat maydoni

Ikkinchi, ortogonal g'oya: barcha ticklar bir xil darajada informativ emas. Bid narxida 100 ta aksiya bilan savdo odatiy holat. Uchta narx darajasini supurib o'tadigan trade esa regime change hisoblanadi. Bu prior'ni attention'ga bevosita qo'shish mumkin. Hodisa muhimligi score'ini aniqlaymiz:

wi=softplus(α1log(qi)+α2Δpi/σ+α31[sweepi])w_i = \text{softplus}\left(\alpha_1 \cdot \log(q_i) + \alpha_2 \cdot |\Delta p_i| / \sigma + \alpha_3 \cdot \mathbb{1}[\text{sweep}_i]\right)

bu yerda qiq_i — trade size, Δpi\Delta p_i — price change, σ\sigma — yaqindagi volatility, sweepi\text{sweep}_i esa bir nechta darajani supurishni bildiradi. Uni softmaxdan oldin attention logits'ga qo'shing:

Attention(Q,K,V)=softmax(QKTdk+W)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}} + \mathbf{W}\right) V

Wij=wj\mathbf{W}_{ij} = w_j bo'lsin. Model istalgan attention pattern'larini o'rganish qobiliyatini saqlab qoladi, lekin bozorni siljitgan trade'larga dastlabki moyillik bilan boshlaydi.

Bu o'ylab topilgan formula. Funksional shakl, uchta hadni tanlash va softplus — barchasi taxmin; bu yerda ushbu bias foydali ekanini, shunchaki model capacity'sini sarflamasligini ko'rsatadigan hech qanday dalil yo'q.

Bir nechta ufq uchun head'lar

Ko‘p gorizontni bashorat qilish lentalari

Turli ufqlar turli qarorlar uchun foydali; bir nechta horizon output'lariga ega umumiy encoder har bir horizon uchun alohida modellardan ustun keladi, joint loss esa regularizatsiya qiladi. Bu fikr, shuningdek quantile output'lar va interpretability Temporal Fusion Transformer for Trading maqolasida berilgan. Tick'ga xos yagona jihat horizon to'plamidir: kunlar emas, 1, 10, 50 va 100 hodisa. Shu sababli burst paytida horizonlar wall-clock vaqtida kuchli ustma-ust tushadi, sokin davrda esa deyarli umuman tushmaydi — daily-horizon adabiyoti duch kelmaydigan murakkablik.

Purging hodisalar bilan o'lchanishi kerak

Hodisa maydonini istisno qilish oralig'i

Purged walk-forward validation Walk-Forward Optimization maqolasida boshidan oxirigacha yoritilgan (anchored, rolling, combinatorial purged CV, WFER, degradation rate); aniq purge va embargo gap'iga ega ishlaydigan purged_walk_forward() esa spread modelingda berilgan. Look-ahead bias taksonomiyasi bunday leakage'lar hisobotdagi Sharpe'ga nima qilishini miqdoriy ko'rsatadi.

Tick data'ning o'ziga xos tomoni shuki, millisekundlar bilan ajralgan qo'shni ticklar deyarli dublikatdir. Shuning uchun kunlar bilan o'lchangan purge gap burst bir soniya ichiga 500 ta deyarli bir xil sample'ni joylashtirganda ma'nosiz. Gap hodisalar bilan o'lchanishi kerak; uning to'g'ri kattaligi maqoladan ko'chiriladigan konstanta emas, instrumentingizdagi burst tuzilishi haqidagi empirik savoldir.

Bu da'voni tekshirish oson: event'lardagi purge gap'ni sweep qiling va validation F1 ni unga nisbatan chizing. Agar gap kengayganda validation F1 pasayib, keyin tekislansa, tekislanish nuqtasi sizning gap'ingiz; agar u umuman pasaymasa, adjacent-tick leakage siz o'ylagan muammo bo'lmagan.

Javob beradigan tajriba

Boshqariladigan vaqtinchalik modelni baholash

Yuqoridagilarning barchasi arxitektura haqida. Hech biri dalil emas. Quyidagi ishlar bajarilmaguncha, maqola ushbu blogning talabiga javob bermaydi:

Sozlama. Bitta dataset'ni (BTC/USDT trade'lari asosiy dataset), bitta encoder'ni, bitta label ta'rifini va bitta purged split'ni o'zgarmas qilib qo'ying. Aynan bitta omilni o'zgartiring.

Uch variant.

Variant Vaqt ma'lumoti Positional encoding
A Δt\Delta t raw input feature sifatida oddiy o'rganiladigan positional embedding
B encoding'dan tashqari hech narsa yo'q ContinuousTimeEncoding (o'rganiladigan time-scale'lar)
C Δt\Delta t feature va uzluksiz vaqt encoding'i sifatida ContinuousTimeEncoding

Nima haqida xabar berish kerak.

  1. Har bir sinf uchun F1, accuracy emas: dead-zone label ostida FLAT sinfi ustunlik qiladi va DeepLOB maqolasida tushuntirilgan sababga ko'ra accuracy informativ emas.
  2. Confidence interval, turli seed'lar bilan takroriy run'lardan hisoblangan. Variantlar orasidagi 0,4 punktlik F1 farqi usiz hech narsani anglatmaydi.
  3. O'rganilgan time-scale'lar. Training'dan keyin torch.exp(model.time_encoding.log_timescales) ni chiqaring. Ular qayerda joylashishi tajribadagi eng qiziq raqam; uni olish uchun bir qator yetarli.
  4. Har bir variant uchun hardware va wall-clock xarajati, IPC solig'i uslubida: oshkor qilingan qurilmada o'lchang va N ta run bo'yicha medianani oling. Agar B varianti A ga nisbatan inference vaqtini F1 punktining kichik ulushi evaziga 3 baravar oshirsa, javob shu.

Salbiy natija bo'lsa, uni ham hisobot qiling. "BTC ticklarining 30 kunida Δt\Delta t ni feature sifatida berish bilan solishtirganda uzluksiz vaqt encoding'i hech narsa bermaydi" — hech kim o'lchamagan uchta arxitektura sharhidan foydaliroq post. Bu blogdagi umumiy xulosaga ham mos: ehtiyotkorlik bilan qurilgan edge'lar halol validation ostida ko'pincha yo'qoladi.

Hozirgi holat

Uzluksiz vaqt tadqiqot yoʻli

Ochiq savol haqiqiy: notekis oraliqlarda keladigan hodisalar bilan oziqlantirilgan sequence model'lar hanuz vaqtni emas, pozitsiyani kodlaydi. Blogdagi mavjud materiallar, jumladan spread modeling maqolasidagi Transformer encoder, oddiy o'rganiladigan positional embeddingdan foydalanadi. Uzluksiz vaqt encoding'i, ODE-RNN latent holati va event-weighted attention — buni tuzatishning uch yo'li.

Yetishmayotgani — bu tuzatish muhim ekanini ko'rsatadigan dalil. Hozircha uchalasi ham natija emas, mavzu. Hal qiluvchi o'lchov — fixed encoder va fixed purged split ustidagi uch variantli ablation: class-wise F1, confidence interval va o'rganilgan time-scale'lar hisobot qilinadi. Bu tajriba hali o'tkazilmagan.

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.