Modelim Yarının Gazetesini Okuyordu
Bir süre boyunca modellerimden biri dahi gibi görünüyordu. Backtest’i temiz, kendinden emin, neredeyse fazlasıyla pürüzsüzdü. Sonunda işe yarayan bir şey inşa ettiğime inanmak istiyordum.
Aslında saklamaya değer hiçbir şey öğrenmemişti. Hile yapmayı öğrenmişti — sessizce, kendi inşa ettiğim bir sızıntı aracılığıyla; bu sızıntı, geçmişte ne yapacağına karar vermeden önce ona gelecekten bilgi okumasına izin veriyordu.
Şüpheli derecede iyi öğrenci
Beklediğinizden biraz daha iyi performans gösteren bir model heyecan vericidir. Hak ettiğinden çok daha iyi performans gösteren bir model ise sizi korkutmalı. Benimki ikinci türdendi: gerçek piyasaların pürüzlü olduğu yerde pürüzsüz, belirsiz olması gereken yerde kendinden emindi.
Önceki bir yazıda, en tehlikeli sonucun sizi pohpohlayan sonuç olduğunu yazmıştım. Bu, aynı dersti yine — daha incelikli bir kostümle. Sayılar bu sefer saçma değildi — sadece fazla iyiydiler ve “fazla iyi” kendi başına bir tehlike işaretidir, çünkü piyasalarda gerçek avantaj küçük, gürültülü ve zorlukla kazanılan bir şeydir. Piyasayı çözmüş gibi görünen bir model, neredeyse her zaman bunun yerine simülasyonunuzda bir çatlak bulmuştur.
Gelecek nereden sızdı
Çatlak normalizasyondaydı — bir modelin onlardan öğrenebilmesi için ham girdileri yeniden ölçeklendirdiğiniz o gösterişsiz adımda. Normalize etmek için istatistiklere ihtiyacınız vardır: bir merkez, bir yayılım. Ve ben bu istatistikleri tüm veri kümesi üzerinden bir defada hesapladım.
İşte o tek tercih, geleceğin sızdığı yerdir. İstatistikleri tüm geçmiş boyunca hesaplayıp sonra bunları geçmişteki bir noktaya uyguladığınızda, o geçmiş andaki her “normalize edilmiş” değer, henüz gerçekleşmemiş veriler hakkındaki bilgiyi sessizce içinde kodlar. Model, herhangi bir ana baktığında, tüm zaman çizelgesinin biçimi hakkında — geleceği de dahil — örtük olarak bilgilendiriliyordu. Yarının fiyatlarını hiçbir zaman doğrudan görmedi. Buna ihtiyacı da yoktu. İçine yarının karıştığı bir havayı soluyordu.
İleriye bakma sızıntısını inşa etmek neden bu kadar kolay
İleriye bakma yanlılığını tehlikeli kılan şey, onu yaratmanın zor olması değildir. Aksi takdirde sıradan görünen ön işleme adımları içinden süzülmesidir. Kodu yazmanın en doğal, en okunaklı yolu — ölçekleyicinizi veriye oturtmak, sonra veriyi dönüştürmek — zaman serileri için zaten yanlıştır ve hiçbir şey şikâyet etmez. Hiçbir istisna fırlatılmaz. Hiçbir test kırmızıya dönmez. Sayılar tamamen makul görünür. Tek belirti, modelinizin olması gerekenden daha iyi olmasıdır ki bu da araştırmaya en az motive olduğunuz tek belirtidir.
Sızıntının tuzağı budur: bir hata gibi görünmez. Başarı gibi görünür.
İşaret: burada parlak, dışarıda ölü
Yine de, tek başına kanıt olmasa da, ele veren bir imza vardır. İleriye bakma sızıntısıyla bozulmuş bir model, üzerinde ayarlandığı veride parlak olma ve gizlice göz atamadığı veriyle karşılaştığı anda dağılma eğilimindedir. Örneklem içi ihtişam ile örneklem dışı çöküş arasındaki büyük bir uçurum, sızıntının bir uyarı işaretidir — gerçi bu aşırı uyumdan, rejim değişiminden ya da hafife aldığınız maliyetlerden de kaynaklanabilir. Benim durumumda suçlu sızıntıydı.
Dolayısıyla önemli olan test hiçbir zaman “backtest ne kadar iyi?” değildi. “Simülasyonu dürüst hale getirdiğimde ne kadar kötüleşiyor?” idi. Sızıntıyı kapattığımda performans düştü — ve o düşüş, acı verici olsa da, sistemin bana gösterdiği ilk güvenilir sayıydı.
Çözüm: henüz bilemeyeceğiniz hiçbir şeyi asla kullanmayın
Onarım bir prensiptir, bir kod satırı değil: simülasyonun herhangi bir anında, model yalnızca o anda ya da ondan önce var olan bilgiyi kullanabilir. Normalizasyon için bu, istatistikleri geçmişin kayan bir penceresinden türetmek anlamına gelir — belirli bir zamana kadar mevcut olana oturtmak, asla tüm zaman çizelgesine değil ve asla geleceğin tek bir noktasına değil.
Bu daha yavaştır. Daha zahmetlidir. Daha kötü görünen backtest’ler üretir. Bu üçünün hepsi maliyet değil, birer özelliktir; çünkü her biri, simülasyonun modele zaman yolculuğu yapmasına izin vermeyi reddetmesidir. Dürüst bir hat, görünür performansta bir vergi öder ve bu vergi, gerçekten güvenebileceğiniz sayıların bedelidir.
Sızıntı tek bir hata değil, bir ailedir
Bunu düzeltmenin en zor kısmı normalleştirici değildi. Normalleştiricinin yalnızca bir kapı olduğunu ve geleceğin birçok yerden içeri girebileceğini fark etmekti. Aynı hata, etiketlerin nasıl oluşturulduğunda, gizlice tüm bir seriyi özetleyen özniteliklerde, geçmiş ile geleceğe birlikte dokunan herhangi bir ön işleme adımında saklanır. Bir sızıntıyı kapatırsınız ve sızıntıyı kapatmış olmazsınız; yalnızca neye benzediğini öğrenmiş olursunuz, böylece diğerlerini bulmaya gidebilirsiniz.
İleriye bakmayı düzeltilecek bir hata olarak düşünmeyi bıraktım ve onu denetlenecek bir özellik olarak ele almaya başladım — artık bilerek avladığım bir şey; bir sonuç fazla temiz görünüyorsa, geleceğin henüz kontrol etmediğim bir yerden içeri girdiği varsayımıyla.
Backtest’ler hile yapmayı neden ödüllendirir
Tüm bunların altında, backtest’lerle ilgili rahatsız edici bir gerçek yatar: beceriyi geriye dönük öngörüden ayırt edemezler. Bir backtest, piyasayı gerçekten önceden sezen bir model ile sessizce cevap anahtarını okuyan bir modele tam olarak aynı şekilde ödeme yapar. İkisi de güzel bir eğri üretir. Kesinlikle ileriye dönük, görülmemiş veri, onları ayırmaya başlayan daha güçlü testtir — gerçi bu bile tek başına bir hattın sızıntısız olduğunu kanıtlayamaz.
İşte bu yüzden “backtest’te iyi gitti” bir soruşturmanın başlangıcıdır, sonu değil. İyi görünen bir öz sermaye eğrisi bir sorudur: bu model bunu hak etti mi, yoksa kazara hile yapmasına mı izin verdim? Dürüst araştırmanın tüm disiplini, bu soruyu piyasa sizin için sormadan önce sormayı öğrenmekten ibarettir.
Yarının gazetesini okuyan bir model her zaman dahi gibi görünecektir. Dahilik sizindir, onun değil — ve tamamen kapatmayı unuttuğunuz sızıntıda yaşar.
— Sinyal yok, getiri yok, yatırım tavsiyesi değildir.