Geçen hafta not defterini gönderdin: aynı sinyal, aynı enstrüman evreni, BTCUSDT sürekli vadeli işlemlerinde aynı 14 aylık veri. Tek değişiklik yürütmeydi. Spread'i geçmeyi bırakıp bir tik içeride alış emirlerini beklemeye aldın; Sharpe 0.42'den 2.14'e çıktı. Bunun gerçek olup olmadığını ya da bir şeyi bozup bozmadığını sordun.
Bir şeyi bozdun. Hatanın tam olarak nerede olduğunu adım adım anlatmak istiyorum; çünkü hata tek satırda, ama buradan çıkarılacak ders o satırdan çok daha büyük.
İşte motorundan kopyaladığım gerçekleşme kuralın:
if bar.low <= limit_price: fill(limit_price)
Bu kural şunu söylüyor: bu dakika içinde piyasa benim fiyatımda ya da altında bir işlem yaptıysa emrim benim fiyatımdan gerçekleşti. Gerçekte kodladığı şey, fiyatın seviyene değdiği. Değmek, gerçekleşmek demek değildir. Bu ikisinin arasında bir kuyruk var ve sen kuyruğu boş varsaymışsın.
Önünde ne var
BTCUSDT sürekli vadeli işlemlerinde 84,120.0 fiyatından alış emri verdiğinde, orada zaten bekleyen emirlerin arkasına girersin. Bu kontratın en iyi alış fiyatında, günün saatine bağlı olarak genellikle 4 ile 30 BTC arasında emir bekler; örneklem dönemindeki medyan yaklaşık 12 BTC. Senin emrin 0.4 BTC. İşlem yapabilmen için satıcıların, senden önce gelen herkesi geçecek kadar toplam hacimle o seviyeye satış yapması ve bunu seviye iptal edilmeden ya da piyasa fiyatı yukarı taşımadan önce gerçekleştirmesi gerekir.
Dolayısıyla backtest'inin sorması gereken soru "fiyat 84,120.0'a ulaştı mı" değil, "emrim orada beklerken en az 12.4 BTC'lik piyasa satış emri 84,120.0'da gerçekleşti mi" olmalı. Bunlar birbirinden çok farklı olaylar. Verilerinde aralarında yaklaşık üç kat fark var.
Üç gerçekleşme kuralı, üç farklı strateji
Sinyalini aynı girişlerle ve üç farklı yürütme modeliyle yeniden çalıştırdım. Alfa aynı, ücretler aynı, funding aynı. Yalnızca gerçekleşme mantığı değişti.
| Gerçekleşme kuralı | Gerçekleşmeler | Gerçekleşme sonrası ortalama 60s avantaj | Sharpe |
|---|---|---|---|
Temas: low <= limit | 4,180 | +2.6 bp | 2.14 |
Kesin aşma: low < limit - 1 tick | 1,712 | +0.4 bp | 0.61 |
| Seviye hacmine dayalı kuyruk simülasyonu | 1,306 | +0.9 bp | 0.77 |
Ortadaki satır, herkesin önce denediği kaba düzeltme: gerçekleşme saymak için piyasanın fiyatını kesin olarak aşmış olması gerekir; mantık şu: fiyat öte tarafa geçtiyse seni tüketmiş olmalı. Genel yönü doğru ve hayali gerçekleşmelerin çoğunu ortadan kaldırıyor. Ama ciddi bir yanlılık da yaratıyor; birazdan ona geleceğim.
En alttaki satır geliştirmen gereken model. L3 akışı ya da emir bazında yeniden oluşturma gerektirmiyor. Gerekli verilerin çoğu zaten elinde.
aggTrades verisinden kurabileceğin bir kuyruk simülasyonu
Kline'lar yerine toplu işlem akışını çek. Her işlem kaydı fiyatı, miktarı, zaman damgasını ve piyasa emrini başlatanın alıcı mı satıcı mı olduğunu gösteren maker tarafı bayrağını içerir. Kendi pasif emrinin işe yarar bir simülasyonunu kurmak için bu kadarı yeterli:
- Emrin piyasaya verildiğinde fiyat seviyesinde bekleyen hacmin anlık görüntüsünü al. Yalnızca 100ms'lik bir emir defteri akışın varsa son anlık görüntüyü kullan; düzelttiğin hatanın yanında bu hata küçük kalır.
queue_ahead = resting_sizedeğerini ata. Temkinli davranıp en sona geldiğini varsay. Seviyeyi oluşturan sen değilsen zaten en sonda olursun.- İşlem akışını tara. Fiyatında ya da altında gerçekleşen her satış başlatıcılı işlem, miktarı kadar
queue_aheaddeğerini azaltır. Değer negatife düştüğünde emrin o zaman damgasında, kendi fiyatından gerçekleşir. - Fiyat bir tik uzaklaşırsa kuyruğu sıfırlama. Azalt. Seviye güncelliğini yitirince önündeki emirlerin bir kısmı iptal olur, bir kısmı kalır. Seviyeden uzak geçen her tam saniyede %30-40 azalma, yeniden oluşturduğum verilerle iki uç varsayımdan da daha iyi örtüştü.
- Stratejin emri iptal edip yeniden verecekse, yeni emri yeni fiyat seviyesinin sonuna ekle. İnsanların atladığı adım bu; geriye kalan hayali gerçekleşmeler de burada saklı.
2. adımda bana itiraz etmek isteyeceksin. Evet, bazen öne yakın olursun; çünkü seviye oluşur oluşmaz emir vermişsindir. Peki, bunu varsayma; ölç. Emir verildiği andaki bekleyen hacmi kaydet ve emirlerinin ne kadarının gerçekten erken sıraya girdiğini veriler söylesin. Senin stratejinde bu oran %11'di; çünkü sinyalin bir hareketten sonra geliyor. Yani katıldığın seviye zaten oluşmuş ve üzerinde kalabalık var.
Gerçekleşen emirlerin, keşke gerçekleşmeselerdi diyeceğin emirler
Şimdi asıl önemli noktaya, kesin aşma kuralının neden yanlı olduğuna gelelim.
Alış emrinin tamamen ne zaman tüketildiğini düşün. Satış baskısı, seviyedeki hacmin tamamını yiyecek kadar güçlü olduğunda olur. Yani doğası gereği, piyasanın fiyatını aşağı doğru geçtiği anda. Gerçekleşeceğinden en emin olduğun emirler, hemen zararda kaldığın emirlerdir.
Gerçekleşmelerini nasıl oluştuklarına göre ayır ve 60 saniyelik mark-out'u ölç:
| Gerçekleşme türü | Gerçekleşmelerin payı | 60s mark-out |
|---|---|---|
| Seviyede işlem oldu, fiyat sıçrayarak yükseldi | 38% | +3.1 bp |
| Seviyede işlem oldu, fiyat yatay kaldı | 21% | +0.2 bp |
| Fiyat 2+ tik aşağıya geçti | 41% | −2.4 bp |
Saf backtest'in bu üç grubun tamamını verdi ve hepsini maliyetsiz varsaydı. Kesin aşma kuralı neredeyse yalnızca üçüncü grubu verir; bu nedenle avantajı kuyruk simülasyonundakinden de fazla düştü. İkisi de doğru değil. Kuyruk simülasyonu gerçekçi bir karışım sunuyor ve oyunun tamamı bu karışımda: pasif yürütme spread'i kazandırırken ters seçim bedelini de ödetir; bu ikisi arasındaki oran, stratejinin gerçekte ne olduğudur.
Eski hisse senedi masasının yaklaşımı hâlâ geçerli: maker emri, piyasaya yazdığın bedelsiz bir opsiyondur. Biri, kullanmaya değdiğinde bu opsiyonu kullanır. Backtest'in primi topladı ama opsiyonun bir de ödeme yükümlülüğü olduğunu unuttu.
Gerçekleşmeyen işlemler yalnızca maliyeti değil, stratejiyi de değiştirir
En çok üzerinde durmanı istediğim nokta bu. Taker yürütmesini kötü modellediğinde doğru işlemleri yanlış fiyattan alırsın ve ücret düzeltmesi sorunun çoğunu giderir. Maker yürütmesini kötü modellediğinde ise tamamen yanlış işlemler kümesini alırsın. 4,180 girişinin yaklaşık 2,900'ü hiç gerçekleşmedi. Bunların bazıları en iyi sinyallerindi; hızla yükselip geri dönen mumlarda ortaya çıktılar. Piyasanın senden uzaklaşmasının tam da bekleneceği hareketler bunlar.
Bu yüzden gerçekleşmeyen emir kolunun gerçek bir mantığı olmalı. Sinyal geçersiz hale gelene kadar giriş gerçekleşmezse strateji ne yapıyor? Taker emriyle peşinden gidip spread'i ve piyasa etkisini mi ödüyor? Daha aşağıya yeni emir verip farklı bir giriş maliyetini mi kabul ediyor? İşlemi atlayıp pozisyonsuz mu kalıyor? Her seçenek özkaynak eğrisini kayda değer ölçüde değiştirir; hiçbiri "emrin gerçekleştiğini varsay" değildir. Çalışmalarımızda dürüst bir takip kuralı eklemek (emir 20 saniye içinde gerçekleşmezse piyasa emriyle geçmek, kaymayı 3 bp ile sınırlamak), kaçırılan işlemlerin yaklaşık üçte birini ve saf modelle kuyruk simülasyonlu Sharpe arasındaki farkın yaklaşık yarısını geri kazandırdı. Bu gerçekten ilginç bir sonuç ve ancak gerçekleşme modeli soruyu anlamlı kılacak kadar gerçekçi olduğunda ortaya çıkıyor.
Ucuz bir sağlama kontrolü, 10 dakika: canlı kağıt işlem günlüğünle backtest'ini aynı dönem için karşılaştır. PnL'yi değil, gerçekleşme oranını karşılaştır. Backtest bekleyen emirlerin %100'ünü, kağıt işlemlerinse %34'ünü gerçekleştiriyorsa stratejileri karşılaştırmıyorsun; gerçekleşme modelinde hata var. Tek bir getiri rakamına bakmadan önce bunu düzelt.
Hazır yakalamışken iki küçük nokta daha
Yalnızca maker olma emirlerinin reddedilmesi. Maker ücret kademesini garantilemek için yalnızca maker emirlerini kullanıyorsan ve kararınla borsanın onayı arasında emir defteri değişirse, emir beklemeye geçmek yerine reddedilir. Kağıt işlem günlüklerimizde normal saatlerde BTCUSDT denemelerinin %3-6'sı, ABD TÜFE verisinin açıklandığı dakikadan sonraysa %15'ten fazlası böyle sonuçlanıyor. Reddedilen emir gerçekleşmiş emir de değildir, gerçekleşmeyi bekleyen emir de; hiç var olmamış bir işlemdir. Backtest'inde bu durum yoksa en çok önem verdiğin piyasa koşullarında işlem sayın şişer.
Kendi işlemlerinin önlenmesi ve piyasadaki etkin. 0.4 BTC ile BTCUSDT'yi hareket ettirmiyorsun; o yüzden bunu atlayabilirsin. Ama bunu, en iyi alış-satış kademesindeki toplam değerin sık sık $15k'ın altında olduğu orta piyasa değerli bir altcoin sürekli vadeli işleminde çalıştırmak istediğini söylemiştin. Orada emrin, kuyrukta anlamlı bir paya sahip ve kaydettiğin önündeki kuyruk hacmi, son emrinin orada bulunmasının etkisini içeriyor. Emir büyüklüğün bekleyen seviyenin yaklaşık %10'unu aştığında simülasyonun, diğer katılımcıların sana tepki verdiğini hesaba katmalı. Açıkçası o noktada kağıt işlemlere, senin ya da benim yazabileceğimiz her simülasyondan daha çok güvenirim.
Kuyruk simülasyonuyla yeniden çalıştır ve gerçekleşme türüne göre ayrılmış mark-out tablosunu gönder. Sıçrama grubu hâlâ avantajın çoğunu taşıyorsa ve aşma grubu avantajın tamamını silmiyorsa, kağıt işlemlere taşımaya değer bir şey olabilir. Her şey hiç alamayacağın 2,900 gerçekleşmeden ibaretse, bunu dört hafta boyunca kağıt hesabının not defterindeki gibi davranmadığını izledikten sonra değil, şimdi öğrenmek daha iyi.
← Tüm yazılar

