Tick Modellerinde Düzensiz Zaman: Sürekli Zaman Kodlamaları ve Düz Konumsal Yerleştirmeler
Zaman çubukları, olay zamanlamasını bozan keyfi bir sıkıştırmadır ve bunun yerine etkinlik, çubuk sınırlarını tanımlamalıdır; bu argüman, 17 çubuk türü ve çalışan jeneratörlerle, Algoritmik Ticaret için Çubuk Türleri ve Toplama Yöntemleri bölümünde tam olarak yapılmıştır. Bu makale bundan bir adım sonra, hiç kimsenin çözemediği kısımdan başlıyor: İşaretleme, hacim veya dengesizlik çubuklarına geçiş yaptığınızda bile, onları beslediğiniz model hala düzenli aralıklarla yer alıyor. Bir nn.TransformerEncoder öğrenilmiş bir konumsal yerleştirme ile, işaretin 6. konumdan 200 mikrosaniye veya 40 saniye sonra gelmesine bakılmaksızın, konum 7'yi "yedinci yuva" olarak ele alır. Varışlar arası süre - etkinlik çubuklarının korunması için oluşturulduğu şey - giriş katmanında tekrar atılır.
Dolayısıyla bu makalenin ele aldığı soru dar kapsamlı ve test edilebilir bir sorudur: Bir işaret gerçekten gerçekleştiğinde bir dizi modeli nasıl anlatılmalıdır ve karmaşık yanıt önemsiz olanı yenebilir mi?
Varsayılan arka plan

Aşağıdakiler, tümü zaten bu blogda ele alınan önkoşullardır ve bunların hiçbiri burada yeniden türetilmemiştir:
- Mikroyapı gürültüsü ve alış-satış sıçraması. Roll'un örtülü yayılma modeli, fiyat birimlerindeki ilk prensiplerden fiyat getirilerindeki negatif seri kovaryansı türetiyor ve yaygın uygulama hatasına dikkat çekiyor: ML ile Alış-Satış Yayılma Modellemesi.
- Sipariş defteri özellikleri. Kitap dengesizliği, ağırlıklı orta fiyat, 1-5 seviyeleri üzerindeki derinlik oranı, kitap baskısı ve yayılma/kene oranı aynı makalede tablo halinde verilmiştir; OBI ve hacim ağırlıklı mid türevleri (ağırlıklı mid'in Stoikov'un mikro fiyatı olmadığı uyarısı da dahil) DeepLOB: Limit Emir Kitaplarında Derin Öğrenme'ta yer alıyor.
- Sipariş akışı ve ticaret yoğunluğu. Ticaret dengesizliği, VPIN ve Kyle'ın lambdası yayılma modelleme makalesinde yer almaktadır; zamanlama özellikleri olarak sıralar arası aralık ve Hawkes'ın kendi kendine uyarılma yoğunluğu Dijital Parmak İzi: Trader Identification belgesinde yer almaktadır. Ham
1/dtBaşlangıçta önerilen bu taslağın yoğunluğu, oradaki Hawkes formülasyonunun daha zayıf bir versiyonudur. - Gün içi durağan olmama. U şeklindeki hacim modeli, sessiz dönemlerde genişleyen yayılma ve günün saati sin/cos kodlaması, piyasa rejimi özellikleri olarak yayılma modellemesinde ele alınmaktadır.
- Etiketler. Her iki yumuşatma kuralı (gelecekteki ortalamaya karşılık cari fiyat, gelecekteki ortalamaya karşı önceki ortalama), eşik ile üç sınıflı ayrıklaştırma ve LOBFrame'in etiket duyarlılığı hakkındaki uyarısı Ve DeepLOB makalesinde bulunmaktadır.
- Sınıf dengesizliği. Ölü bölge durumunda FLAT sınıfı hakimdir; bu nedenle raporlanabilir ölçü doğruluktan ziyade F1'dir; aynı makale.
- Çubuk doldurma süresi. Bir ses seviyesi çubuğunun doldurulması için gereken duvar saati süresi, tıklama modeli için kullanılabilir bir özelliktir; bunu üreten jeneratörler Çubuk Türleri ve Toplama Yöntemleri bölümünde yer almaktadır.
Açıkça belirtmeye değer bir şey var çünkü bu taslağın orijinal versiyonu yanlış anlamıştı: %50,0'dan %50,5'e bir yön doğruluğu sıçraması kesinlikle kârlı değildir. DeepLOB makalesinde tartışılan LOBFrame'in temel noktası, tahmin edilen bir hareketin, doğruluğun bir anlam ifade etmesinden önce yayılımı temizleyecek kadar büyük olması gerektiğidir ve bu blogdaki dürüst olumsuz sonuç, aksini varsaydığınızda gerçekleşen şeydir.
Temel

Temel kodlayıcı olarak DeepLOB tarzı bir CNN-Inception-LSTM olduğunu varsayalım; mimari, doğrulanmış FI-2010 Kurulum 2 numaraları (F1 83,40 / doğruluk 84,47) ), LOBFrame uyarıları ve çalışan bir PyTorch yeniden uygulaması, DeepLOB: Limit Emir Kitaplarında Derin Öğrenme belgesinde yer almaktadır. Aşağıdaki hiçbir şey bu kodlayıcıyı değiştirmez; asıl soru, giriş temsiline neyin ekleneceğidir.
Düzensiz Zamanı Kodlamanın Üç Yolu

Seçenek A: düz bir özellik olarak delta_t
Önemsiz cevap. Ekle (log-dönüştürülmüş, z-puanlı) OFI ve kitap dengesizliğinin yanı sıra özellik vektöründe bir sütun daha olarak yerleştirir ve standart öğrenilmiş konumsal yerleştirmeyi korur. Hiçbir maliyeti yoktur, bir girdi boyutu ekler ve çoğu üretim adımı modelinin gerçekte yaptığı da budur.
Bu, her meraklı önerinin yenmek zorunda olduğu koldur ve daha meraklı alternatifler öneren gazetelerden atlanan koldur.
Seçenek B: sürekli zamanlı konumsal kodlama
Ayrık konumsal yerleştirmeyi, öğrenilebilir zaman ölçekleri üzerinden geçen zamanın sinüzoidal fonksiyonuyla değiştirin:
Neresi mikrosaniyelerden saniyelere kadar log aralıklı olarak başlatılan öğrenilebilir zaman ölçeği parametreleridir. Amaçlanan etki, dikkatin olayları zaman indeksi yerine zamansal alaka düzeyine göre ağırlıklandırabilmesidir - 200 mikrosaniye önceki büyük bir ticarete, 50 milisaniye önceki küçük bir ticaretten farklı bir şekilde ulaşılabilir olmalıdır.
Öğrenilebilir kısım ilginç kısımdır. 1 mikrosaniyeden 10 saniyeye kadar log aralıklı zaman ölçeklerini başlatır ve eğitirseniz, zaman ölçeklerinin bittiği yer başlı başına bir ölçümdür: milisaniye sonuna doğru çökerlerse, model size birkaç milisaniyenin ötesindeki her şeyin birbirinin yerine geçebileceğini söyler ve bu, mimariyle değil, pazarla ilgili bir bulgudur.
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 bir kodlayıcıya bırakıldığında tam olarak bir satırın yerini alır; konumsal gömme eklentisi:
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, :])
Kodlayıcı standart metni yeni bir şey değil; aynı nn.TransformerEncoderLayer iskele zaten yayılmış modelleme bölümünde Mimari 2 olarak yayınlanmıştır. Sadece ContinuousTimeEncoding ve öğrenilebilir zaman ölçeği argümanı.
Seçenek C: işaretler arasındaki sürekli gizli durum (ODE-RNN)
En ilkeli seçenek, gizli durumu Nöral ODE tarafından modellenen sürekli zamanlı bir süreç olarak ele alır (Chen ve diğerleri, 2018). İşaretler arasında gizli durum öğrenilmiş bir diferansiyel denkleme göre gelişir:
Bir onay işareti geldiğinde durum şu gözlemle güncellenir:
Bu ODE-RNN çerçevesidir. Düzensiz aralıkları bir girdi özelliği olarak değil yapısal olarak ele alır: çözücü tam olarak entegre olur olaylar arasında, dolgu olmadan, enterpolasyon olmadan ve bilgilerin kaybedilmesine neden olacak yeniden örnekleme adımı olmadan.
Maliyet hesaplamaya dayalıdır. ODE çözümleyicileri sıralıdır ve paralelleştirilmesi zordur, bu da bu kolun bir gecikme bütçesinden kurtulma olasılığını en düşük kol haline getirir - bu tür iddiaların yapılmadan önce nasıl ölçülmesi gerektiği konusunda IPC Tax ve backtest motor hız merdiveni'da oluşturulan gecikme disiplinine bakın. Buraya bir dağıtım adayı olarak değil, açık zaman modellemenin satın alabileceği şeylerin üst sınırı olarak dahil edilmiştir.
Olay Ağırlıklı Dikkat

İkinci, ortogonal bir fikir: tüm işaretler eşit derecede bilgilendirici değildir. İhalede 100 hisselik bir ticaret rutindir. Üç fiyat seviyesini kapsayan bir ticaret rejim değişikliğidir. Bunu doğrudan dikkatin içine enjekte edebiliriz. Bir etkinlik önem puanı tanımlayın:
Neresi ticaret boyutudur, fiyat değişimi, Son zamanlardaki oynaklık ve çok seviyeli bir taramayı işaretler. Softmax'tan önce dikkat kayıtlarına ekleyin:
ile . Model, keyfi dikkat kalıplarını öğrenme yeteneğini koruyor ancak piyasayı harekete geçiren işlemlere karşı önyargılı olmaya başlıyor.
Bu icat edilmiş bir formül. İşlevsel biçim, üç terimin seçimi ve softplus'ın tümü tahminlerden ibarettir ve burada yalnızca yanma kapasitesinden ziyade önyargının yardımcı olduğunu gösteren hiçbir şey yoktur.
Çok Ufuklu Başlıklar

Farklı ufuklar farklı kararlara yol açar, birden fazla ufuk çıkışına sahip ortak bir kodlayıcı, ufuk başına ayrı modelleri yener ve ortak kayıp düzenli hale gelir. Bu argüman artı niceliksel çıktılar ve yorumlanabilirlik, Temporal Fusion Transformer for Trading belgesinde yapılmıştır. Tik işaretine özgü tek kısım ufuk kümesidir: Günler yerine 1, 10, 50 ve 100 olay; bu, ufukların patlamalar sırasında duvar saati süresinde büyük ölçüde örtüştüğü ve sessiz dönemlerde neredeyse hiç örtüşmediği anlamına gelir; günlük ufuk literatürünün asla başa çıkmak zorunda olmadığı bir komplikasyon.
Olaylarda Tasfiye Ölçülmelidir

Temizlenmiş ileri yürüme doğrulaması, İleri Yürüme Optimizasyonu (bağlantılı, yuvarlanan, kombinatoryal temizlenmiş CV, WFER, bozulma oranı) ve çalışma purged_walk_forward() yayılma modellemede açık bir tasfiye ve ambargo boşluğu mevcut. İleriye dönük önyargı sınıflandırması, bu tür sızıntıların rapor edilen Sharpe'a neler yapabileceğini ölçüyor.
Tik verilerine özgü olan tek şey: Milisaniye aralıklarla bitişik tikler neredeyse kopyalardır, bu nedenle günler cinsinden boyutlandırılmış bir temizleme aralığı, bir patlama bir saniye içinde neredeyse aynı 500 örneği koyduğunda anlamsızdır. Boşluğun olaylara göre boyutlandırılması gerekir ve doğru boyut, bir kağıttan kopyalanacak bir sabit değil, enstrümanınızın patlama yapısıyla ilgili ampirik bir sorudur.
Bu iddiayı test etmek ucuz; olaylardaki boşlukları süpürün ve F1'in onayını buna karşı planlayın. Boşluk genişleyip düzleştikçe F1 doğrulaması düşerse, düzleşme noktası sizin boşluğunuzdur; eğer hiç düşmüyorsa bitişik kene sızıntısı sandığınız sorun değildi.
Buna Karar Veren Deney

Yukarıdaki her şey mimaridir. Hiçbiri kanıt değil. Makale, aşağıdakiler çalıştırılana kadar bu blogun çubuğunu temizlemez:
Kurulum. Bir veri kümesini (BTC/USDT işlemleri kurum veri kümesidir), bir kodlayıcıyı, bir etiket tanımını ve bir temizlenmiş bölünmeyi düzeltin. Tam olarak bir şeyi değiştirin.
Üç kol.
| Kol | Zaman bilgisi | Konumsal kodlama |
|---|---|---|
| bir | ham giriş özelliği olarak | düz öğrenilmiş konumsal yerleştirme |
| B | hiçbiri, kodlamanın ötesinde | ContinuousTimeEncoding (öğrenilebilir zaman ölçekleri) |
| C | ve sürekli zamanlı kodlama özelliği olarak | ContinuousTimeEncoding |
Ne bildirilmeli?
- Sınıf başına F1, doğruluk değil — ölü bölge etiketi altında FLAT sınıfı hakimdir ve doğruluk, DeepLOB makalesinde tam olarak belirtilen nedenden dolayı bilgi verici değildir.
- Farklı tohumlarla tekrarlanan çalışmalardan elde edilen güven aralığı. Kollar arasındaki 0,4 puanlık F1 boşluğu, kollar olmadan hiçbir şey ifade etmez.
- Uygun zaman çizelgeleri. Yazdır
torch.exp(model.time_encoding.log_timescales)eğitimden sonra. Yerleştikleri yer deneydeki en ilginç sayıdır ve bunu elde etmek bir satıra mal olur. - Kol başına donanım ve duvar saati maliyeti, IPC Tax tarzında — açıklanan donanıma göre N üzerinden medyan olarak ölçülmüştür. B kolu, bir F1 puanının kesri için A kolu çıkarım süresinin 3 katı kadar maliyete sahipse, cevap budur.
Varsa negatif sonucu bildirin. "Sürekli zamanlı kodlama aşırı beslemeden hiçbir şey satın almaz bir özellik olarak, 30 günlük BTC tıklamaları", hiç kimsenin ölçmediği üç mimariyi kapsayan bir araştırmadan daha faydalı bir yazıdır. Bu aynı zamanda bu blogdaki, dikkatle oluşturulmuş kenarların dürüst doğrulama altında buharlaşma eğiliminde olduğu yönündeki genel bulguyla da tutarlı olacaktır.
Bunun Nerede Durduğu

Ortaya çıkarılan soru gerçektir: Düzensiz aralıklı olaylarla beslenen dizi modelleri hâlâ zamandan ziyade konumu kodlamaktadır ve blogun mevcut kapsamı - yayılma modellemesindeki Transformer kodlayıcı dahil - düz öğrenilmiş konumsal yerleştirmeyi kullanmaktadır. Sürekli zamanlı kodlamalar, ODE-RNN gizli durumu ve olay ağırlıklı dikkat, bunu düzeltmenin üç yoludur.
Eksik olan şey, onu düzeltmenin önemli olduğuna dair herhangi bir kanıttır. Üçü de şu anda bulgular değil konulardır. Belirleyici ölçüm, sabit bir kodlayıcı ve sabit arındırılmış bir bölme üzerinde üç kollu bir ablasyondur; bir güven aralığı ve uygun zaman çizelgeleri ile sınıf başına F1'i rapor eder - ve henüz çalıştırılmamıştır.
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.