Algoritmik Trading için QuestDB: Emir Defterlerinden Üretim Mimarisine
3/3 — ayrıca şu dillerde mevcuttur: RU · ZH
Sorumluluk reddi: Bu makalede sunulan bilgiler yalnızca eğitim ve bilgilendirme amaçlıdır; finansal, yatırım veya alım-satım tavsiyesi niteliği taşımaz. Kripto para birimi ticareti önemli kayıp riski içermektedir.
QuestDB serimizin son bölümüne hoş geldiniz. 1. Bölüm'de depolama mimarisini ele aldık. 2. Bölüm'de SQL uzantılarını inceledik. Şimdi her şeyi bir araya getirelim: gerçek zamanlı analitik için materyalize görünümler, 2D dizilerle yerel emir defteri depolama ve üretim ortamındaki bir algoritmik trading platformu için referans mimari.
Materyalize Görünümler: Tel Hızında Ön Hesaplamalı Analitik
Kademeli materyalize görünümler: ham tick verileri giderek daha kaba toplama katmanlarından geçer; her seviye önemli ölçüde daha küçük bir veri setini işler
SAMPLE BY QuestDB'nin en çok kullanılan sorgusuysa, materyalize görünümler de en etkili optimizasyonudur. Kavram basittir: her gösterge paneli yenilemesinde veya API çağrısında OHLCV toplamalarını hesaplamak yerine, bunları bir kez önceden hesaplayın ve sonucu sürekli güncel tutun.
Temel OHLC Materyalize Görünüm
CREATE MATERIALIZED VIEW trades_OHLC_15m
WITH BASE 'trades'
REFRESH IMMEDIATE
AS
SELECT timestamp, symbol,
first(price) AS open,
max(price) AS high,
min(price) AS low,
last(price) AS close,
sum(quantity) AS volume
FROM trades
SAMPLE BY 15m;
Tanımın tamamı budur. trades tablosuna her yeni satır eklendiğinde, QuestDB bu görünümü otomatik olarak ve artımlı biçimde yeniler. Tam bir yeniden hesaplama yapılmaz — yalnızca etkilenen zaman dilimleri güncellenir. trades_OHLC_15m'ye yapılan sorgular, çok daha küçük ve önceden toplanmış bir veri kümesinde basit arama işlemlerine dönüşür.
Performans farkı çarpıcıdır. Milyarlarca satır içeren bir tabloda OHLC verisi için temel tablonun sorgulanması 200 ms sürebilir. Materyalize görünüm aynı sonucu 5 ms'nin altında döndürür. Birden fazla eş zamanlı gösterge paneli kullanıcısıyla bu yalnızca bir optimizasyon değil; duyarlı bir sistem ile çöken bir sistem arasındaki farkı belirler.
Kademeli Görünümler: Tek Kaynaktan Çok Zaman Dilimi
Materyalize görünümlerin mimari açıdan zarif hale geldiği yer burasıdır. Bunları zincirleyebilirsiniz — her görünüm bir sonrakini besler ve tek bir ham veri kaynağından hiyerarşik bir toplama seviyeleri yapısı oluşturur:
-- Ham işlemlerden 1 saniyelik barlar
CREATE MATERIALIZED VIEW ohlc_1s AS
SELECT timestamp, symbol,
first(price) AS open, max(price) AS high,
min(price) AS low, last(price) AS close,
sum(quantity) AS volume
FROM trades
SAMPLE BY 1s;
-- 1 saniyelik barlardan 5 saniyelik barlar
CREATE MATERIALIZED VIEW ohlc_5s AS
SELECT timestamp, symbol,
first(open) AS open, max(high) AS high,
min(low) AS low, last(close) AS close,
sum(volume) AS volume
FROM ohlc_1s
SAMPLE BY 5s;
-- 5 saniyelik barlardan 1 dakikalık barlar
CREATE MATERIALIZED VIEW ohlc_1m AS
SELECT timestamp, symbol,
first(open) AS open, max(high) AS high,
min(low) AS low, last(close) AS close,
sum(volume) AS volume
FROM ohlc_5s
SAMPLE BY 1m;
Her seviye bir öncekinden çok daha küçük bir veri setini işler. 1 dakikalık görünüm ham işlemleri taramaz — yalnızca önceden toplanmış 5 saniyelik barları okur. Bu kademeli örüntü istediğiniz sayıda zaman dilimine ölçeklenir: 1s → 5s → 1m → 5m → 15m → 1h → 4h → 1d.
100'den fazla borsadan veri alan bir kripto veri platformu için bu, tüm OHLC dağıtım boru hattının omurgasıdır.
Yenileme Stratejileri
QuestDB, her biri farklı iş yüklerine uygun üç yenileme modu sunar:
REFRESH IMMEDIATE, her temel tablo işleminden sonra zaman uyumsuz bir yenileme tetikler. Saniye altı gecikmenin önemli olduğu gerçek zamanlı gösterge panelleri için en iyi seçenektir.
REFRESH EVERY 1h (zamanlayıcı tabanlı), güncellemeleri periyodik yenilemelere gruplandırır. Her mikro-toplu işlemde yenileme tetiklemek ek yük yaratacak yüksek verimli alma işlemleri için daha uygundur.
REFRESH PERIOD (LENGTH 1d TIME ZONE 'Europe/London' DELAY 2h), takvimle hizalı dönemler tanımlar. "Gecikme" geç gelen veriler için hesap verir — işlem seansından saatler sonra düzeltme akışı gönderebilecek piyasalar için kritiktir.
REFRESH MANUAL tam kontrol sağlar. Görünüm yalnızca açıkça bir REFRESH komutu çalıştırdığınızda güncellenir — gün sonu mutabakat iş akışları için yararlıdır.
LATEST ON Hızlandırma Örüntüsü
En güçlü örüntülerden biri, anlık portföy anlık görüntüleri için materyalize görünümleri LATEST ON ile birleştirir. Her sembolün en son fiyatı için 1,3 milyar ham satırın taranması saniyeler alır. Ancak günlük önceden toplanmış bir görünümle:
CREATE MATERIALIZED VIEW trades_latest_1d AS
SELECT timestamp, symbol, side,
last(price) AS price,
last(quantity) AS quantity,
last(timestamp) AS latest
FROM trades
SAMPLE BY 1d;
LATEST ON sorgusu milyarlarca yerine yaklaşık 25.000 önceden toplanmış satırı tarar:
SELECT symbol, side, price, quantity, latest AS timestamp
FROM (
trades_latest_1d
LATEST ON timestamp PARTITION BY symbol, side
)
ORDER BY timestamp DESC;
Saniyelerden milisaniyelere. Üretim ortamındaki trading gösterge panelleri, büyük veri kümeleri üzerinde gerçek zamanlı duyarlılığı bu şekilde elde eder.
TTL: Otomatik Veri Yaşam Döngüsü
Materyalize görünümler, otomatik veri sona erme için TTL (yaşam süresi) politikalarını destekler:
CREATE MATERIALIZED VIEW ohlc_1h AS (
SELECT timestamp, symbol,
avg(price) AS avg_price
FROM trades
SAMPLE BY 1h
) PARTITION BY WEEK TTL 8 WEEKS;
Bu, 8 haftalık saatlik veriyi korurken eski bölümleri otomatik olarak siler. Üç katmanlı depolama motoruyla birleştiğinde doğal bir veri yaşam döngüsü elde edersiniz: ham tikler WAL → sütunlu depolama → nesne depolamada Parquet üzerinden akarken, materyalize görünümler uygulamalarınızın gerçekten sorguladığı önceden toplanmış özetleri korur.
2D Diziler: Yerel Emir Defteri Analitiği
3D emir defteri derinliği: alış ve satış seviyeleri yerel 2D diziler olarak depolanır; SIMD ile optimize edilmiş spread hesaplamaları ve likidite analizi mümkün kılınır
QuestDB 9.0, gerçek şekilli ve adımlı, NumPy benzeri N-boyutlu diziler sundu; bu diziler sıfır kopyayla yaygın işlemleri (dilimleme, transpoze etme) gerçekleştirir. Trading için öldürücü uygulama emir defteri depolamadır.
Geleneksel Sorun
Tarihsel olarak, bir ilişkisel veritabanında emir defteri anlık görüntüleri depolamak ağrılıydı. İki seçeneğiniz vardı: fiyat seviyesi başına bir satır (satır patlaması, derinlik sorgulaması pahalı) ya da bid1_price, bid1_size, bid2_price, bid2_size gibi sabit sayıda sütun (katı, savurgan ve çirkin).
QuestDB'nin 2D dizileri her iki sorunu da ortadan kaldırır:
CREATE TABLE market_data (
timestamp TIMESTAMP,
symbol SYMBOL,
bids DOUBLE[][],
asks DOUBLE[][]
) TIMESTAMP(timestamp) PARTITION BY HOUR;
Her bids ve asks sütunu, birinci satırın fiyatları ve ikinci satırın her seviyedeki hacimleri içerdiği 2D bir dizi depolar. 20 seviyeli bir emir defteri 40 ayrı sütun değil, tek bir kompakt dizidir.
SQL'de Emir Defteri Analitiği
Spread hesaplama — en temel ve en sık hesaplanan metrik:
SELECT timestamp,
spread(bids[1][1], asks[1][1]) AS spread
FROM market_data
WHERE symbol = 'EURUSD'
AND timestamp IN today();
spread() fonksiyonu, en iyi satış ve en iyi alış arasındaki farkı hesaplayan yerleşik bir fonksiyondur. bids[1][1], alış dizisinin birinci satırındaki (fiyatlar) birinci elemana (en iyi fiyat) erişir.
Daha gelişmiş analitik için — likidite derinliği, emir defteri dengesizliği, belirli bir fiyat seviyesinde işlem gerçekleşme olasılığı — dizi dilimleme ve vektörleştirilmiş işlemler önceden karmaşık sorguları kolaylaştırır:
-- Hedef fiyatın vurulacağı seviyeyi bul
-- ve o seviyeye kadar tüm hacimleri topla
DECLARE @target := bids[1][1] * 1.01;
SELECT timestamp,
array_sum(asks[2][1:level_idx]) AS volume_to_fill
FROM market_data
WHERE symbol = 'EURUSD';
SIMD ile optimize edilmiş dizi işlemleri, milyonlarca anlık görüntü üzerinde bile bu hesaplamaların donanıma yakın hızda çalışmasını sağlar.
Dizi Verilerinin Alımı
QuestDB'nin istemci kütüphaneleri yerel dizi alımını destekler. Python istemcisi doğrudan NumPy dizileriyle entegre olur:
import numpy as np
from questdb.ingress import Sender
bids = np.array([[9.3, 9.2, 9.1], [100, 200, 150]]) # fiyatlar, hacimler
asks = np.array([[9.5, 9.6, 9.7], [80, 160, 120]])
with Sender.from_conf("http::addr=localhost:9000;") as sender:
sender.row(
'market_data',
symbols={'symbol': 'EURUSD'},
columns={'bids': bids, 'asks': asks},
at=timestamp
)
Protokol Sürüm 2, dizileri ikili biçimde kodlar; bu, metin tabanlı protokollere kıyasla bant genişliğini ve sunucu tarafı ayrıştırma ek yükünü önemli ölçüde azaltır. Sembol başına saniyede binlerce anlık görüntü alabileceğiniz yüksek frekanslı emir defteri alımı için bu verimlilik önem taşır.
C/C++ istemcileri, mevcut trading sistemi veri yapılarından sıfır kopyalı alıma olanak tanıyan şekil tanımlayıcılara sahip düz satır-büyük diziler kullanır.
Her Şeyi Bir Araya Getirme: Referans Mimari
Referans mimari: borsa bağlayıcıları, sütunlu veritabanı çekirdeği, analitik katmanı, strateji motoru ve izleme gösterge panelleri — tümü birbirine bağlı
Kripto piyasaları için eksiksiz bir QuestDB destekli algoritmik trading platformu tasarlayalım. Bu mimari; birden fazla borsadan alımı, gerçek zamanlı analitiği, geri testi ve strateji yürütmeyi yönetir.
Veri Alım Katmanı
Veri alımı: birden fazla borsa bağlayıcısı, gerçek zamanlı piyasa verilerini WebSocket boru hatlarından ILP aracılığıyla QuestDB'ye aktarır
Borsalara (Binance, Bybit, OKX vb.) kurulan birden fazla WebSocket bağlantısı, ham piyasa verilerini ILP üzerinden HTTP ile QuestDB'ye iletir. Her borsa bağlayıcısı ayrı bir süreçtir; bu, izolasyon ve hata toleransı sağlar.
Veri akışları şunları içerir: işlemler (timestamp, sembol, taraf, fiyat, miktar), emir defteri anlık görüntüleri (timestamp, sembol, bids[][], asks[][]) ve yardımcı akışlar olarak fonlama oranları/tasfiyeler.
Alım verimi hedefi: tüm borsalar genelinde saniyede milyonlarca satır. QuestDB'nin WAL'ı bunu rahatça karşılar; yinelenenlerin kaldırılma özelliği ise fazlalıklı borsa bağlantılarından gelen kaçınılmaz tekrarları yakalar.
Gerçek Zamanlı Analitik Katmanı
Materyalize görünümler, analitik katmanının çekirdeğini oluşturur:
Ham işlemler → ohlc_1s → ohlc_5s → ohlc_1m → ohlc_5m → ohlc_15m → ohlc_1h → ohlc_1d
Her seviye artımlı olarak yenilenir. QuestDB'nin yerel eklentisi aracılığıyla bağlanan bir Grafana gösterge paneli, mum çubuk grafikleri için bu görünümleri sorgular ve ne kadar geçmiş veri bulunursa bulunsun 5 ms'nin altında yanıt süresi elde eder.
Ek materyalize görünümler şunları hesaplar: sembol ve gün başına VWAP (hacim ağırlıklı ortalama fiyat), kayan volatilite tahminleri ve borsalar arası spread izleme.
Önceden toplanmış görünümlere karşı LATEST ON sorguları, gerçek zamanlı portföy gösterge panelini besler — mevcut pozisyonları, gerçekleşmemiş K/Z'yi ve borsa başına maruziyeti gösterir.
Strateji Motoru
Strateji motoru: gerçek zamanlı gösterge hesaplaması algoritmik karar vermeyi besler; alış/satış yürütme yolları materyalize görünümler tarafından optimize edilir
Trading stratejileri, mevcut piyasa durumu ve geçmiş örüntüler için QuestDB'yi sorgular. QuestDB'nin PG wire protokolü, PostgreSQL sürücüsüne sahip herhangi bir dilin bağlanabileceği anlamına gelir: araştırma stratejileri için Python, gecikmeye duyarlı yürütme için Rust veya C++.
Stratejiler için temel sorgu örüntüleri: işlem dolum zamanındaki piyasa koşullarıyla işlem gerçekleşmelerini eşleştirmek için ASOF JOIN, her olay etrafındaki kısa vadeli metrikleri hesaplamak için WINDOW JOIN ve gerçek zamanlı gösterge hesaplaması (RSI, Bollinger Bantları, ATR) için pencere fonksiyonları.
Gecikmeye kritik stratejiler için önceden hesaplanmış materyalize görünümler sorgu süresini en aza indirir. 50 sembolü izleyen bir ızgara botu, her tik'te 50 ayrı hareketli ortalama hesaplamak zorunda değildir — bunları materyalize görünümden okur.
Geri Test Boru Hattı
Geçmiş veriler nesne depolamada Parquet olarak bulunur. QuestDB bunları şeffaf biçimde sorgular; ancak ağır geri test iş yükleri için veriler aynı zamanda Polars, Pandas veya DuckDB tarafından doğrudan okunabilir — veritabanı tamamen devre dışı bırakılır.
Bu çift erişim örüntüsü güçlüdür: canlı strateji, gerçek zamanlı kararlar için QuestDB'nin SQL arayüzünü kullanırken geri test çerçevesi aynı verileri toplu işlem için Parquet/Arrow üzerinden okur. Aynı veri, iki optimize erişim yolu.
İzleme ve İşlem Sonrası Analiz
HORIZON JOIN, işlem sonrası analiz boru hattını güçlendirir:
- Kayma analizi: Yürütme fiyatını dolum zamanındaki orta fiyatla karşılaştırın
- Markout eğrileri: Her dolumdan sonra 1 sn, 5 sn, 30 sn, 60 sn'de fiyat evrimini izleyin
- Uygulama açığı: Yürütme maliyetlerini spread, geçici etki ve kalıcı etkiye ayrıştırın
- Mekan puanlama: Sipariş yönlendirmesini optimize etmek için borsalar arasındaki dolum kalitesini karşılaştırın
Bu analizler zamanlanmış sorgular olarak çalışır; sonuçları izleme gösterge panellerini besleyen özel tablolara yazar. Uyarı kuralları anormalliklerde tetiklenir — ani kayma artışları, alışılmadık markout örüntüleri veya belirli mekanlarda bozulmuş dolum kalitesi.
Performans Değerlendirmeleri
Üretim performans ayarı: gecikme, verim ve bellek izleme ile sıcak-ılık-soğuk veri yaşam döngüsü
Üretim dağıtımlarından bazı pratik notlar:
Bölüm boyutlandırma: Günde milyonlarca satır içeren kripto tick verisi için PARTITION BY HOUR genellikle en uygun seçenektir. Bu, hem depolama hem de sorgu performansı açısından bireysel bölümleri yönetilebilir tutar.
Materyalize görünüm kademeleme: Çok fazla ara seviye oluşturmayın. Her seviye yenileme gecikmesi ekler. Çoğu kullanım durumu için 3-4 seviye (1s → 1m → 15m → 1d), sorgu performansı ile veri tazeliği arasında iyi bir denge sağlar.
Yinelenen kaldırma ek yükü: Fazlalıklı veri kaynaklarına sahip tablolarda yinelenenlerin kaldırılmasını etkinleştirin. Maliyet, benzersiz zaman damgalı veriler için minimumdur; ancak sütun düzeyinde yinelenen kaldırma gerektiren çok sayıda aynı zaman damgalı satırla artar.
Bellek tahsisi: QuestDB'nin sıfır GC motoru verimlidir; ancak sıcak bölümler ve yazma önbelleği için yeterli bellek ayırın. Yerleşik metrik uç noktası aracılığıyla izleyin.
İstemci protokol seçimi: Alım için ILP over HTTP kullanın (otomatik yeniden denemeler ve sağlık kontrolleriyle). Sorgular için PG wire kullanın. ILP Protokol Sürüm 2 (ikili kodlama), dizi verileri ve yüksek verimli çift değerler için önemli ölçüde daha verimlidir.
QuestDB ve Alternatifler
Rekabetçi manzara: QuestDB'nin TimescaleDB, ClickHouse, InfluxDB ve kdb+ ile temel yetenek boyutlarında karşılaştırılması
Trading'de yaygın kullanılan veritabanlarına karşı kısa bir konumlandırma:
TimescaleDB'ye karşı: TimescaleDB, zaman serisi uzantılarına sahip PostgreSQL'dir. PG'nin genelliğini miras alır ancak ek yükünü de. QuestDB'nin yerel sütunlu motoru ve SIMD yürütmesi, zaman serisi iş yüklerinde önemli ölçüde daha iyi sorgu performansı sunar; ASOF JOIN gibi özellikler ise doğrudan TimescaleDB karşılığına sahip değildir.
ClickHouse'a karşı: ClickHouse, büyük veri kümeleri üzerinde analitik sorgularda mükemmeldir. Ancak zaman serisi için özel olarak tasarlanmamıştır — yerel ASOF JOIN yok, FILL ile SAMPLE BY yok, emir defterleri için 2D dizi yok. Karma OLAP + zaman serisi iş yüklerinde ClickHouse kazanabilir; saf trading verisi için QuestDB daha ergonomiktir.
InfluxDB'ye karşı: InfluxDB, çok borsalı kripto verisi için ağrılı olan yüksek kardinalite sınırlamalarına sahiptir. Sorgu dili (Flux, artık kullanımdan kaldırıldı; InfluxQL), QuestDB'nin SQL uzantılarının ifade gücünden yoksundur. Büyük geçmiş sorguların performansı genellikle daha kötüdür.
kdb+/q'ya karşı: HFT için altın standart. kdb+, belirli tek iş parçacıklı vektör işlemleri için daha hızlıdır ve q dili inanılmaz derecede özlüdür. Ancak tescilli, pahalıdır ve dik bir öğrenme eğrisine sahiptir. QuestDB, maliyetin çok küçük bir kısmıyla standart SQL ve açık kaynaklı lisanslama ile yeteneklerin %80-90'ını sunar.
Sonuç: Trading'i Anlayan Bir Veritabanı
Bu üç makale boyunca QuestDB'nin mimarisini (WAL, sütunlu ve Parquet ile üç katmanlı depolama), SQL uzantılarını (SAMPLE BY, ASOF JOIN, HORIZON JOIN, WINDOW JOIN, LATEST ON, TWAP) ve pratik uygulamalarını (materyalize görünümler, emir defteri dizileri, referans mimari) ele aldık.
Ana tema tutarlıdır: QuestDB, tam olarak algoritmik trading'in ürettiği iş yükleri için tasarlanmıştır. Sizi veritabanının etrafından dolaşmaya zorlamaz — aksine, temelleri trading kavramlarıyla doğrudan eşleşir. OHLC toplamı tek satırlıktır. İşlem-kotasyon hizalaması tek bir JOIN'dir. İşlem sonrası analiz, çok sayfalık PL/SQL prosedürü değil bir HORIZON JOIN'dir.
Trading altyapısı oluşturan ekipler için — ister kripto piyasa veri platformu, ister nicel araştırma ortamı, isterse tam algoritmik trading motoru olsun — QuestDB ciddi bir değerlendirmeye değer. Açık kaynaklı sürüm çoğu kullanım durumunu karşılar; Enterprise sürümü ise düzenlenmiş ortamlar için boşlukları doldurur.
Finansal veri altyapısı manzarası hızla gelişmektedir. Piyasaların dilini konuşan veritabanları kazanacaktır. QuestDB akıcıdır.
İyi işlemler, gecikmeleriniz düşük olsun.
Atıf
@software{soloviov2025questdb_algotrading_p3,
author = {Soloviov, Eugen},
title = {QuestDB for Algorithmic Trading: From Order Books to Production Architecture},
year = {2025},
url = {https://marketmaker.cc/tr/blog/post/questdb-algotrading-production},
version = {0.1.0},
description = {Gerçek zamanlı analitik için materyalize görünümler, 2D dizi emir defteri analitiği ve QuestDB destekli bir algoritmik trading platformu için referans mimari.}
}
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.