1 dakikalık mumlardan oluşan bir takvim yılı 525,600 satır içermeli. BTCUSDT sürekli vadeli işlemleri için 2025 verisini çektiğimizde 525,557 satır geldi; 43 dakika eksikti, tamlık oranı %99.992 idi. Aynı borsadaki orta ölçekli bir altcoin sürekli vadeli işleminde, aynı veri çekme işlemi ve aynı kod yolu 1,247 satır eksik döndü: %99.76. Aynı yıl için ABD hisse senetlerinin dakika serisinde ise kripto serisine kıyasla yaklaşık 427,000 satır daha az vardı; bu hiç boşluk sayılmaz, yalnızca piyasanın kapandığını gösterir.
Bu sayılardan üçü sıkıcı. Bin kelimeye değer olanı 43.
Veri çerçevenizdeki bir boşluğa benzeyen 4 farklı durum
43 dakikaya geçmeden önce sınıflandırmayı açıklayalım; çünkü boşlukları ele alan kodların çoğu daha bu katmanda yanlış çalışıyor. Yerel parquet dosyanızda bir satır yoksa bunun hangi durumdan kaynaklandığını bilemezsiniz ve her durum için doğru yaklaşım farklıdır.
| Tür | Gerçekte ne oldu | Nasıl görünür | Doğru yaklaşım |
|---|---|---|---|
| İşlem olmadı | Piyasa açıktı; o dakika kimse alış ve satış fiyatı arasındaki fark üzerinden işlem yapmadı | Bazı uç noktalarda sıfır hacimli mum (OHLC değerleri aynı, trades=0), bazılarında eksik satır | Olduğu gibi bırakın. Gerçek bir bilgidir: kimse işlem yapmak istemedi. |
| Borsa devre dışı | Eşleştirme motoru kapalıydı; planlı da olabilir, plansız da | Eksik satır, bazen art arda birkaç tane | Eski veri olarak işaretleyin. Bu aralıkta işlem yapmayın. |
| Enstrüman işlemleri durduruldu | LULD bandı aşıldı, haber bekleniyor veya borsadan çıkarılma bildirimi var | Eksik satırın ardından açılış müzayedesi işlemi gelir | Eski veri olarak işaretleyin ve yeniden açılışı bir süreksizlik olarak ele alın. |
| Sizden kaynaklı | İstek sınırına takılan sayfalama, bir sayfayı atlayan yeniden deneme veya döngüde saat dilimi sınırı hatası | Yukarıdakilerden ayırt edilemeyen eksik satır | Tespit edip veriyi yeniden çekin. Düzeltebileceğiniz tek durum bu. |
Borsalar tablonun ilk satırındaki durumda farklı davranıyor; sorun da burada başlıyor. Coinbase'in mum uç noktası boş zaman dilimlerini tamamen atlar, bu yüzden likiditesi düşük bir paritenin geçmişi gerçek boşluklarla doludur. Binance'in klines uç noktası ise genellikle hacmi 0 olan, açılış=en yüksek=en düşük=kapanış değerleri önceki işlemin fiyatında sabitlenmiş sentetik bir mum döndürür. Altta yatan gerçek aynı, görünüm farklıdır; tam dakikalık bir ızgaraya yeniden indeksleme yapan yükleyici ise size söylemeden birini diğerine dönüştürür. Boşluk doldurucuyu yazdıktan sonra değil, önce borsanızın nasıl davrandığını kontrol edin.
Altcoindeki 1,247 eksik dakikanın neredeyse tamamı birinci kategorideydi: pazar günü UTC 04:00'te sığ bir emir defteri, işlem yapan yok. Can sıkıcı ama anlaşılması kolay ve büyük ölçüde zararsız; çünkü strateji zaten o saatlerde işlem yapmayacaktı. Tam da bu yüzden ona bakmayı bırakıp 43 dakikaya geri döndüm.
43 dakika rastgele dağılmamıştı
Eksiklikler eşit dağılsaydı, bir yıla yayılmış 43 dakika sekiz buçuk günde bir görülen, tek başına duran 43 boşluk olurdu; her biri yuvarlama hatası kadar önemsiz kalırdı. Ama öyle olmadı. Boşluklar 6 kümeydi: biri art arda 19 dakika, biri 11, ikisi 4 dakika ve birkaç ikili küme. 43 ayrı aksilik değil, 6 olay.
Üstelik bu olaylar, önemsediğiniz değişkene bağlı. Borsalar yoğun yük altında devre dışı kalır ve fiyat hareket ederken yük altındadır. Yılın her saatini gerçekleşen volatiliteye göre gruplandırıp eksik dakikaların nerede olduğunu inceledim: %61'i en yüksek dilimdeydi. Herhangi bir dakikanın eksik olma koşulsuz olasılığı %0.008. En yüksek volatilite dilimindeki bir saatte bulunma koşuluyla ise bu oran yaklaşık %0.05; 6 kat daha yüksek ve üstelik kümelenmiş durumda.
Dolayısıyla veri kalitesi panonuzdaki tamlık metriği yanlış şeyi ölçüyor. %99.992, artık üzerinde düşünmeniz gerekmeyen bir veri kümesi gibi görünüyor. Oysa bu oran, stratejiniz hiçbir şey yapmadığı saatlerde eksiksiz, her şeyi yaptığı saatlerde ise delik deşik olan bir seriyi tanımlıyor. Volatilite genişlemesinde sinyal üreten bir momentum sisteminin boşluğa denk gelme olasılığı, başlıktaki sayının ima ettiğinden kayda değer ölçüde yüksek; üstelik boşluk, işlem devam ederken ortaya çıkıyor.
İleri doldurma 3 satır sonra neye yol açıyor
Bunu yazmama neden olan hatayı anlatayım. 19 dakikalık kümeyi ele alın. Standart veri temizliği: tam dakikalık ızgaraya yeniden indeksleyin, OHLC değerlerini son kapanış fiyatıyla ileri doldurun ve hacmi sıfırlayın. Seri artık kesintisizdir ve göstergeleriniz tek bir NaN bile görünmeden çalışır.
Bu 19 mumda high == low == close. Her birinin gerçek aralığı sıfırdır. Bu pencere için hesaplanan ATR(14), borsa kesintisinden önce yaklaşık 240 USDT olan seviyesinden borsa geri gelene kadar yaklaşık 34'e iner; penceredeki hayatta kalan 5 gerçek mum ortalamanın tamamını taşır. Şimdi bunu, sıradan size = risk_budget / ATR türündeki volatiliteye göre ölçeklenen pozisyon boyutlandırıcısına verin. Pozisyon büyüklüğü 7 katına çıkar.
Bir sonraki gerçek mum, borsa yeniden açıldığında oluşan fiyattır ve sakin bir mum değildir. Bizim örneğimizde, kesinti öncesindeki son kapanıştan %1.8 uzakta açıldı. Geriye dönük test, var olamayacak bir gerçekleşmeyle, kimsenin fiyat vermediği bir seviyede, %1.8'lik boşluğa 7 kat büyüklüğünde pozisyonla rahatça girdi. Bu tek sentetik işlem, özsermaye eğrisinde bir aydan fazla gerçek P&L'den daha değerliydi; üstelik yanlış yönde. Tüm bunlar, veri çerçevesini derli toplu göstermek için yazılmış tek bir veri temizleme satırından kaynaklandı.
Satırları doldurmak yerine silmek de çözüm değil; aynı hatanın başka biçimi. Satırları silerseniz tamsayı indeksli geriye dönük pencereleriniz yanıltır: "20 barlık EMA" artık kesinti boyunca duvar saatine göre 39 dakikayı kapsar, sınırın iki yanındaki bar getirisi %1.8'lik sıçramanın tamamını tek dakikalık hareketmiş gibi ele alır ve bar başına volatilite tahmini bunu 60 sigma'lık bir olay olarak okur. Hiçbir uyarı almazsınız. İndeks hâlâ monoton artar.
Yeniden örnekleme sorunu görünmez kılar
Araştırmaların çoğu 1 dakikalık mumlarla değil, birleştirilmiş verilerle çalışır ve birleştirme sorunu örtbas eder. Veriyi 5 dakikalık aralıklara yeniden örneklediğinizde, 19 dakikalık bir boşluk 4 muma dönüşür; bunların ilk ve sonuncusu kısmi olur. Pandas, geriye kalan 2 dakikadan makul görünen bir OHLC hesaplar ve bunu 5 dakikadan oluşturulmuş bir mumla aynı şekilde etiketler. Çıktıda aralarındaki farkı gösteren hiçbir şey yoktur.
Bildiğim en ucuz çözüm: Her yeniden örnekleme boyunca bars_in_window sütununu taşıyın ve asla silmeyin. Her satırda tek bir tamsayı bulunması, sonraki aşamalardaki tüm mumların güvenilir olup olmadığı sorularını yanıtlanabilir kılar. Ayrıca, yürütme katmanının kullanabileceği biçimde aynı bilgiyi sunan seconds_since_last_real_print değerini de taşıyoruz.
Uyguladığımız politika
Ajanlarımız artık şu adımları sırayla uyguluyor:
- Asla sessizce yeniden indekslemeyin. Yükleyici bir boşluk manifesti oluşturur: başlangıç, bitiş, uzunluk ve boşluğun 4 kategoriden hangisine girdiğine dair tahmin. Eksik dakika kümesi 3 bardan kısaysa ve çevresindeki barların hacmi düşükse bu, işlem yapılmayan bir dakikadır. Aktif saatlerde bundan daha uzun süren her şey, aksi kanıtlanana kadar borsa kesintisi sayılır.
- Yorumlamadan önce veriyi yeniden çekin. İlk dönemdeki boşluklarımızın yarısı sayfalama hatalarından kaynaklanıyordu. Farklı bir uç noktadan veya başka bir veri sağlayıcıdan ikinci kez veri çekmek, dördüncü kategoriyi çözer ve herhangi bir yargıya varmak gerekmeden sorunu küçültür.
- Boşluk doldurmak yerine güncellik eşiği kullanın. Stratejiye bir
data_agegirdisi ve katı bir kural verin: Son gerçek işlem fiyatı N bardan eskiyse yeni pozisyon açmayın; açık pozisyonları ise yeniden açılışta yalnızca açıkça belirtilmiş boşluk riski iskontosu içeren bir fiyatla piyasa emri kullanarak kapatın. Gerçekleşmesi mümkün olmayan işlemler, hiç gerçekleşmeyen işlemlerden daha kötüdür. - Göstergelere kurgu değil NaN verin. İleri doldurulmuş fiyatlar özellik katmanına asla ulaşmaz. ATR hesaplanamıyorsa tanımsızdır; tanımsız değer pozisyonun kapalı kalması demektir. Açık bir hata, sessizce 7 katına çıkmaktan iyidir.
- Boşluklara göre koşullandırılmış performansı raporlayın. Yayımladığımız her geriye dönük testte, kesinti çevresindeki işlemler hariç tutularak hesaplanan P&L, manşet sonuçla birlikte gösterilir. Sonucu bu işlemler taşıyorsa, o sonuç bir veri artefaktıdır.
Bugün yapabileceğiniz hızlı bir denetim: Eksik dakikaları art arda gelen kümeler halinde gruplayın, sonra geriye dönük testinizdeki işlemlerin ne kadarının bir kümenin başlangıç veya bitiş sınırından sonraki 30 dakika içinde açılıp kapandığını kontrol edin. Oran %1'in altındaysa boşluklar muhtemelen sonucu etkilemiyordur. %5 veya üzerindeyse özsermaye eğriniz kısmen borsa kesintilerinin hikâyesini anlatıyor demektir.
Güvenmeyi öğrendiğim işaret, eksikliğin büyüklüğünden çok biçimi. Hacimsiz saatlere dağılmış binlerce boşluğu olan veri kümesi genellikle sorun çıkarmaz. Birkaç sıkı kümesi olan veri kümesi ise yoğun yükte bir şeylerin bozulduğunu anlatır; yoğun yükte bozulan şey de stratejinizin işlem yaptığı yerdir.
← Tüm yazılar


