26 Ağustos 2026 · piyasa verisi

Tek bir 1 dakikalık barın anatomisi: OHLCV'nin backtest'inize söylemediği her şey

Tek bir 1 dakikalık barın anatomisi: OHLCV'nin backtest'inize söylemediği her şey

İşte tek bir bar. Binance USDⓈ-M perpetual, BTCUSDT, 13:46:00 UTC'de başlayan dakika. Bu bar, klines endpoint'inden on iki değerlik çıplak bir dizi olarak geldi ve perakende ile ona yakın kesimdeki kantitatif araştırmalarda en yaygın kullanılan tek girdi birimi. Ürettiğimiz hemen her strateji, bu şekle benzer bir şeye dokunuyor.

O hâlde onu indeks indeks parçalarına ayıralım ve bir backtest'in bunun ne kadarını yanlış anladığını görelim.

İndeksDeğerAd
01773495960000açılış zamanı (ms)
1"84120.50"açılış
2"84177.90"en yüksek
3"84098.10"en düşük
4"84163.40"kapanış
5"38.417"temel hacim (BTC)
61773496019999kapanış zamanı (ms)
7"3232108.94"kotasyon hacmi (USDT)
81204işlem sayısı
9"21.883"taker alış temel hacmi
10"1841203.55"taker alış kotasyon hacmi
11"0"yok say

[0] ve [6]: bu hangi dakika ve bunu hangi saat söylüyor

Açılış zamanı 1773495960000, kapanış zamanı 1773496019999. İkincisine dikkat edin: 19999 ile bitiyor, yani bir sonraki barın açılışından tam bir milisaniye önce. Pencere yarı açık ve borsa size bunu açıkça söylüyor. Peşine düştüğüm veri hatalarının yarısı, birinin her iki uç noktayı da dahil sayıp sınırdaki bir işlemi iki kez saymasıyla ya da her 5 dakikalık barın komşusundan bir milisaniye ödünç alacak şekilde bir resample hizalamasıyla başladı.

Zaman damgaları borsanın eşleştirme motoru (matching engine) saatidir. Sizin saatiniz değil, veri sağlayıcınızın alım saati değil ve funding anlık görüntüsünün kullandığı saat de değil. Bir kline serisini farklı bir endpoint'ten çekilmiş bir funding rate serisiyle ya da open interest serisiyle birleştirdiğinizde, çoğu zaman birbirleriyle yaklaşık bir saniye içinde uyuşan kaynakları birleştiriyorsunuz demektir. 1 dakikalık bir strateji için bu, birleştirilen her satırda 1.7%'lik bir zamanlama hatası anlamına gelir. Dakikanın altındaki her şey için ise bu ölümcüldür.

Ve bu bar, açılışında damgalanmış. İçerdiği bilgi 13:46:59.999'a kadar bilinemez. Her indeksleme kuralı sorusu — bir kaydırma yapmalı mıyım, olay zamanı olarak bar-kapanış mı yoksa bar-açılış zaman damgalarını mı kullanmalıyım — aslında kılık değiştirmiş aynı lookahead (ileriye bakma) sorusudur.

[1] "84120.50": alım satım yapamayacağınız açılış

Açılış, pencere içinde gerçekleşen ilk işlemin fiyatıdır. Başka iki kişi arasında tamamlanmış bir işlemdir. Bar, dataframe'inizde bir satır olarak var olduğunda, o fiyat artık altmış saniyelik geçmişe ait olur.

Önceki bar 84109.80'de kapanmış, yani iki bitişik 1 dakikalık bar arasındaki boşlukta $10.70'lık bir fiyat hareketi var. Bu, grafikte görünmeyen 1.3 baz puana ve taker ücretinin kabaca dörtte birine denk geliyor. Sorun yok diyebilirsiniz. Ama aynı seriye bir alt perp üzerinde bir ABD CPI açıklaması sırasında bakın, bu barlar arası boşluklar 15 ila 40 baz puana çıkıyor. Bar kapanışında sinyal üretip bir sonraki barın açılışında fill alan bir backtest, boşluğun sıfır olduğunu sessizce varsayıyor demektir — ve boşluk tam olarak önemli olmadığı zamanlarda sıfırdır.

[2] ve [3]: "84177.90" en yüksek, "84098.10" en düşük

Çoğu fill motoru tam da burada can veriyor, o yüzden bu bölüm uzun olacak.

En yüksek ve en düşük, değinilen uç fiyatlardır. Ne büyüklük ne de süre taşırlar. Aynı dakikaya ait ham trade tape'e bakıldığında, 84100.00 ve altındaki her şey, 1.4 saniyelik bir pencere içinde dokuz işlemde toplam 0.62 BTC'ydi. Yani 84100'de bir backtest stop'u "fill" olur — ve pozisyonunuz 3 BTC ise, aşağı giderken görünen tüm defteri yemişsiniz ve kalan büyüklüğünüz 84105–84130 aralığındaki geri dönüşte bir yerlerde gerçekleşmiş demektir. Bar, en düşüğün 84098.10 olduğunu söylüyor. Ama bar, orada sadece $52,000'lık nominal işlem gördüğünü söylemiyor.

1204dakikadaki işlem sayısı
0.032 BTCortalama işlem büyüklüğü (~$2.7k)
0.62 BTCen düşük seviyede veya altında işlem gören toplam hacim
57%hacmin alıcı kaynaklı kısmı

Diğer yön daha kötü, çünkü sizi pohpohluyor. Diyelim ki 84175'te bekleyen bir limit satış emriniz var. Barın en yükseği 84177.90, yani saf bir motor sizi 84175'te fill eder ve taker maliyeti yerine maker rebate'i kaydeder. Bu fill'in gerçekten gerçekleşip gerçekleşmediği, o fiyat seviyesindeki sıra konumuna bağlıdır — bunu bar bilemez ve muhtemelen siz de hiç kaydetmediniz. Değinilmiş olmak, doldurulmuş olmak anlamına gelmez.

Fill motorumuzda karar kıldığımız kural şu: bekleyen bir limit emri, ancak bar seviyenin içinden geçerse, sadece seviyeye değmesi yetmez. Tam uç tick'te gerçekleşen fill'ler, trade tape'ten fiyat-bazında hacim kanıtı gerektirir, aksi hâlde reddedilir. Bu kural, tipik bir mean-reversion defterindeki işlemlerin yaklaşık 6%'sını elemiş ve bir adayın backtest Sharpe'ını 1.9'dan 1.1'e düşürmüştür. O aday hiçbir zaman gerçek değildi; fill kuralı bunu söylemeye yetecek kadar dürüst olan ilk şeydi sadece.

İlgili bir tuzak: bar-içi (intrabar) rota. Bir barın aralığı hem stop'unuzu hem de take-profit'inizi kapsıyorsa, OHLCV size hangisinin önce gerçekleştiğini söyleyemez. Her motorun bir kural benimsemesi gerekir. Bizimki her zaman stop-first varsayar; bu kötümser bir yaklaşımdır, zaman zaman yanlış çıkar ama asla sahte bir kazanç üretmez. Motorunuz take-profit-first varsayıyorsa, geniş aralıklı barlar belirsizlikten kâr üretecektir — ve geniş aralıklı barlar tam olarak PnL dağılımınıza hakim olan barlardır.

[4] "84163.40": bardaki en az sağlam sayı

Kapanış, pencerede gerçekleşen son işlemdir. Hepsi bu. 13:46:59.8'de bir pozisyonunu tamamlayan bir botun 0.002 BTC'lik küsuratlı (odd-lot) emri olabilir. Yapısal olarak bu kadar keyfi olan bu tek tick, çoğu araştırma pipeline'ının her sinyali hesaplamak, her pozisyonu mark etmek ve her çıkışı değerlendirmek için kullandığı şeydir.

BTC perp'lerinde bunun pek önemi yok; ama 04:00 UTC'de ince bir altcoin perp'inde son derece önemli hâle geliyor ve aynı dakika için iki farklı platformun kapanışları arasındaki fark, işlem başına tüm edge'inizi aşabilir. Bir stratejinin PnL'i özellikle kapanışa bağlıysa, bunu bunun yerine borsanın mark price'ıyla mark ederek yeniden çalıştırıyoruz; bu fiyat endeks türevlidir ve manipüle edilmesi çok daha zordur. Sonuçlar farklılaşıyorsa, strateji artifact'i alım satıma konu ediyor demektir.

[5] ve [7]: "38.417" ve "3232108.94", hacim hangi birimde

Temel hacim BTC, kotasyon hacmi USDT. Burada ikisi de var, ki bu her platformun gösterdiği bir nezaket değil. Bunun önemli olmasının nedeni, platformlar arası agregasyon. Coin-margined kontratlar, $100 nominal değerindeki kontratlar cinsinden kote edilir. Bazı hisse senedi feed'leri round lot cinsinden bildirir. Tahmin piyasası platformları, bir payın dolar bazlı ikili (binary) bir hak talebi olduğu pay sayılarını bildirir. Karışık bir evrende "hacmi" tek bir nominal birime normalize etmeden toplamak, tamamen saçma bir likidite sıralaması üretir — ve bu saçmalık, incelemeden sağ çıkacak kadar istikrarlı görünen bir saçmalık olur.

Her şeyi alım anında kotasyon nominaline normalize edin. Ham alanı da saklayın, ama bir stratejinin onu asla görmesine izin vermeyin.

[8] 1204: etki modelinizi belirlemesi gereken alan

İşlem sayısına bölünen temel hacim, ortalama 0.032 BTC'lik, yaklaşık $2,700'lük bir işlem büyüklüğü verir. Aday stratejiniz tek seferde $250,000 girmek istiyorsa, bu, o dakikadaki tipik işlemin büyüklüğünün kabaca 92 katı olmayı istemek demektir. Genel geçer bir 5-bps'lik slippage sabiti değil, işte bu sayı, karekök etki teriminizi belirlemelidir. Bar başına katılım oranını birinci sınıf bir sütun olarak hesaplıyoruz ve medyan girişi bar nominalinin birkaç yüzdesini aşan stratejileri reddediyoruz, çünkü bunun ötesindeki her şey kurgudur.

İşlem sayısı ayrıca garip dakikaları ucuza tespit etmenizi sağlar. Hacim normal, işlem sayısı 11'e mi düşmüş? Biri blok işlem yapmıştır. Hacim normal, işlem sayısı 9,000'e mi çıkmış? Bu, küçük parçalar hâlinde öğütülen bir likidasyon çığıdır.

[9] ve [10]: "21.883", herkesin çöpe attığı alan

Taker alış temel hacmi. Bu bardaki 38.417 BTC'nin 21.883'ü alıcı kaynaklıydı, yani işaretli hacim deltası +5.349 BTC ve saldırgan dağılımı alıcılar lehine 57/43. Borsa size emir akışı dengesizliğini bedavaya veriyor — çoğu insanın hiç okumadığı bir alanda, çünkü pandas sütunu onlar için adlandırmadı.

Bunun tek başına getiriyi öngördüğünü iddia etmiyorum; saf delta stratejileri, ücret defterine bağış yapmanın en güvenilir yollarından biridir. Ama bu, fiyattan gerçekten farklı bir ölçümdür, zaten yapmakta olduğunuz istekle aynı istekte mevcuttur ve satın alınan bir ralli ile satıcıların çekildiği için gerçekleşen bir ralliyi birbirinden ayırt etmenizi sağlar. Bu ikisi OHLC'de birbirinin aynı görünür ve on dakika sonra farklı davranır. Araştırma ajanımız, bunu yayınlayan bir platformda taker dağılımını göz ardı eden bir hipotezi, masada kanıt bırakmak olarak değerlendiriyor.

[11] "0": yok say — ve burada olmayan her şey

İndeks 11, kalıcı olarak sıfır olan, kullanımdan kaldırılmış bir alandır. Daha ilginç olanı, bu barın içermediği şeylerin listesi: bid yok, ask yok, spread yok, book depth yok, funding rate yok, open interest yok, likidasyon yok, mark price yok, index price yok. Ve en önemlisi, sizin emrinizin maker mı yoksa taker mı olacağını bilmenin bir yolu yok — ki bu, bu platformda 0.045% ödemekle 0.01% kazanmak arasındaki farktır.

Yani yalnızca klines üzerine kurulu herhangi bir ücret modeli, bir sayının kıyafetini giymiş bir varsayımdır. Biz bunu, her stratejiyi baştan execution stilini beyan etmeye zorlayarak ve aksini kanıtlayamayan her şeyden taker ücreti keserek çözüyoruz.

Hiç görünmeyen bar

Son parça, ve majör paritelerin dışında en sert ısıran parça. Sıfır işlemli bir dakika, hiçbir kline üretmez. Vendor'lar ve kütüphaneler bunu genellikle forward-fill yapar: open = high = low = close = önceki kapanış, hacim 0. Göstergeniz mutlu mesut hesaplama yapar. Stratejiniz geçerli bir satır görür ve dünyada hiç kimsenin o enstrümanı alıp satmadığı bir dakikada sinyal üretebilir.

Aldığımız orta ölçekli bir perp'te, on iki aylık bir pencerede 1 dakikalık barların 4.1%'i sıfır işlem içeriyordu. O sembol üzerindeki bir mean-reversion adayı, girişlerinin 38%'ini sentetik barlar üzerinde yapıyordu, çünkü düz sentetik fiyatlar, bir hareketli ortalamadan sapmayı ölçen her şey için tam bir cazibe merkezidir. Backtest sonuçları muhteşemdi. Aslında verideki boşlukları alıp satıyordu.

İşte bu yüzden ingest katmanı artık her bar için, her resample'da yayılan bir synthetic boolean taşıyor ve doğrulama sürecimiz, işlemleri bunun üzerinde kümelenen her stratejiyi eliyor. Ucuz bir sütun. Bugüne kadar yazdığımız herhangi bir indikatörden daha fazla adayı öldürdü.

On iki değer. Dördü rutin olarak yanlış okunuyor, ikisi rutin olarak atılıyor, ve bunların tamamı bir kategori olarak satırda yok ve motor tarafından hayal ediliyor. Bir sonraki backtest'inizden önce, kendi deponuzdan ham bir bar çekin ve fill mantığınızın her alan hakkında ne varsaydığına karşı her alanı yüksek sesle okuyun. Bu yirmi dakikalık bir egzersiz ve bunu yapıp hiçbir şey bulmayan birini hiç görmedim.

ohlcvpiyasa mikroyapısıveri mühendisliğibacktestingkripto vadeli işlemler
← Tüm yazılar