Vektörleştirilmiş Bir Geriye Dönük Test: Sinyaller, Pozisyonlar, İleriye Bakmayı Önlemek için Kaydırma, İşlem Maliyetleri ve Sermaye Eğrisi
Pozisyon kaydırması, işlem başına maliyetler, sermaye eğrisi ve bir karşılaştırma ölçütüyle (benchmark) kıyaslama dahil olmak üzere, pandas'ta hareketli ortalama kuralının eksiksiz vektörleştirilmiş bir geriye dönük testini oluşturun.
Neler öğreneceksiniz
- Vektörleştirilmiş bir geriye dönük testin beş sütunlu yapısı: sinyal, pozisyon, varlık getirisi, maliyet ve strateji getirisi.
- Pozisyon sütunundaki
shift(1)ifadesinin neden dürüst bir testi ileriye bakan bir fanteziden ayıran tek satır olduğu. - Pozisyon değişikliklerinde orantılı işlem maliyetlerinin nasıl uygulanacağı ve euro cinsinden bir sermaye eğrisinin nasıl oluşturulacağı.
- Vektörleştirilmiş bir testin neyi modelleyip neyi modelleyemeyeceği ve 8. dersteki olay güdümlü motora ne zaman ihtiyaç duyulduğu.
Açıklama
Vektörleştirilmiş bir geriye dönük test, çubuk çubuk döngü kurmak yerine sütun işlemleriyle tüm geçmişi tek seferde hesaplar. "Sistematik Trading" kursundaki elektronik tablo geriye dönük testi bu yapıya sahipti; pandas bunu onlarca yıllık veri üzerinde milisaniyeler içinde çalıştırır. Kapanışta işlem yapan long-nakit veya sürekli piyasada kalan kurallar için uygundur; çubuk içi stoplar ve belirli gerçekleşme fiyatları 8. dersin işidir.
Adım 1, sinyal. signal = (close > sma(close, 50)).astype(int), kapanış 50 günlük ortalamasının üzerindeyse 1, değilse 0 verir. Bu, t çubuğunun kapanışında bildiğiniz şeyi tanımlar.
Adım 2, pozisyon. Henüz görmediğiniz bir kapanışa göre işlem yapamazsınız; t çubuğunun sinyalini en erken t + 1 çubuğunda tutabilirsiniz, dolayısıyla position = signal.shift(1).fillna(0). Pozisyon sütununun t satırı artık "t çubuğu boyunca tutulan ve t − 1 çubuğunun sonunda karar verilen pozisyon" anlamına gelir. Kaydırmayı atlamak, stratejinin t çubuğunun getirisini t çubuğunun kapanışını kullanarak kazanmasına izin verir; bu da ileriye bakma yanlılığıdır (look-ahead bias): karar anında mevcut olmayan bilgiyi kullanmak.
Adım 3, varlık getirisi. ret = close.pct_change().fillna(0) (5. ders). t çubuğu boyunca tutulan pozisyon t − 1 çubuğunun kapanışında belirlendiği için position * ret, t çubuğu için brüt strateji getirisidir. Örtük varsayım, emrin t − 1 çubuğunun kapanışında gerçekleştiğidir; bir sonraki açılışta gerçekleşen emirleri 8. ders ele alıyor.
Adım 4, maliyetler. Komisyon, spread ve kayma, değişen pozisyon birimi başına orantılı bir oran olarak modellenir: turnover = position.diff().abs().fillna(0), nakitten long'a geçerken veya geri dönerken 1, yön değiştirmede 2'dir. cost = turnover * c; burada c, kesir olarak tek yönlü maliyettir (0.1% için 0.001). Maliyet, getiri sütununa pozisyonun değiştiği çubukta girer.
Adım 5, strateji getirisi ve sermaye. strat = position * ret - cost ve equity = capital * (1 + strat).cumprod(). Al-ve-tut karşılaştırma ölçütü capital * (1 + ret).cumprod()'dir. Her ikisini de her zaman aynı metriklerle karşılaştırın (9. ders); al-ve-tut stratejisini nakitle seyreltmek, düşüşü ve getiriyi aynı oranda azaltır; bu bir beceri değildir.
Varsayımları belirtin: pozisyon, her gün yeniden yatırılan sermayenin bir oranıdır; emirler kapanışta gerçekleşir; maliyetler orantılıdır; nakit faiz getirmez; temettüler yalnızca düzeltilmiş veri yoluyla yansır; vergiler dikkate alınmaz. Test böylece tek ve dar bir soruyu yanıtlar: zamanlama kuralı, maliyetlerden sonra, varlığı elde tutmaya kıyasla bir şey kattı mı?
Çıktıya güvenmeden önce yapılacak kontroller. (1) Maliyeti sıfıra ve sinyali sabit 1'e ayarlayın; sermaye tam olarak al-ve-tut stratejisine eşit olmalıdır. (2) Gidiş-dönüş işlemleri turnover.sum() / 2 ile sayın ve makul olup olmadığını kontrol edin. (3) Göstergenin ısınma dönemindeki NaN satırlarının sahte bir işlem değil, sıfır pozisyon verdiğinden emin olun.
Çözümlü örnek
Varsayımsal örnek: euro cinsinden sekiz kapanış: 100, 101, 103, 102, 104, 103, 101, 100; kapanış 3 günlük SMA'sının kesin olarak üzerindeyse long, değilse nakit; tek yönlü maliyet 0.1%; sermaye €10,000; faiz, temettü veya vergi yok.
| Çubuk | Kapanış | SMA3 | Sinyal | Pozisyon | Getiri | Devir | Strateji | Sermaye € |
|---|---|---|---|---|---|---|---|---|
| 0 | 100 | – | 0 | 0 | 0 | 0 | 0 | 10,000.00 |
| 1 | 101 | – | 0 | 0 | +1.000% | 0 | 0 | 10,000.00 |
| 2 | 103 | 101.33 | 1 | 0 | +1.980% | 0 | 0 | 10,000.00 |
| 3 | 102 | 102.00 | 0 | 1 | −0.971% | 1 | −1.071% | 9,892.91 |
| 4 | 104 | 103.00 | 1 | 0 | +1.961% | 1 | −0.100% | 9,883.02 |
| 5 | 103 | 103.00 | 0 | 1 | −0.962% | 1 | −1.062% | 9,778.11 |
| 6 | 101 | 102.67 | 0 | 0 | −1.942% | 1 | −0.100% | 9,768.33 |
| 7 | 100 | 101.33 | 0 | 0 | −0.990% | 0 | 0 | 9,768.33 |
3. çubuk: 2. çubuktaki sinyal 1'di (103 > 101.33), dolayısıyla 3. çubuk boyunca pozisyon 1'dir. Varlık 103 → 102 düştü (−0.971%), 1'lik devir 0.1% maliyet getirir, strateji getirisi −1.071%, sermaye 10,000 × (1 − 0.01071) = €9,892.91. 3. çubukta kapanış SMA'ya eşittir, dolayısıyla kesin kural 0 verir ve pozisyon 4. çubuk boyunca kapatılır (maliyet 0.1%, pozisyon yok). Nihai sermaye €9,768.33'tür (−2.32%); al-ve-tut ise tam olarak €10,000'dır. Maliyetler dört tek yönlü işlemde €39.36 götürmüştür.
Şimdi ileriye bakan versiyon, kaydırılmış position yerine signal kullanılarak: strateji 2. ve 4. çubuklar boyunca, yani ancak kapandıktan sonra tespit edebileceği iki yükseliş gününde pozisyon "tutar" ve €10,356.65 ile kapanır (+3.57%). Eksik tek bir shift(1), −2.32%'yi +3.57%'ye çevirmiştir.
Sık yapılan hata
position = signal.shift(1); getiriler düz pct_change()'dir.Uygulama etkinliği
Kâğıt üzerinde, aynı sekiz kapanış ve kuralla: (a) 0.2%'lik tek yönlü maliyetle nihai sermayeyi yeniden hesaplayın; (b) gidiş-dönüş işlem sayısını belirtin; (c) bir meslektaşınız "işleme ilk günden başlanabilsin" diye SMA'nın ilk NaN değerlerini kapanışla doldurmayı öneriyor; bunun neden sorun olduğunu kısaca açıklayın.
Çözümü göster
(a) Yalnızca dört devir çubuğu değişir. 3. çubuk: −1.171% → €9,882.91; 4. çubuk: −0.2% → €9,863.15; 5. çubuk: −1.162% → €9,748.58; 6. çubuk: −0.2% → €9,729.09. Nihai kayıp, 0.1%'deki 2.32%'ye karşılık 2.71%'dir; maliyet oranını iki katına çıkarmak €39.24 ek yük getirmiştir.
(b) Devir toplamı 4 tek yönlü değişikliktir, dolayısıyla 2 gidiş-dönüş işlem vardır (3. çubuk boyunca giriş, 4. çubukta çıkış; 5. çubukta giriş, 6. çubukta çıkış).
(c) SMA'yı kapanışla doldurmak, henüz var olmayan bir göstergeden işlemler yaratır; dolayısıyla bu işlemlerin mantığı test edilen kuraldan farklıdır. Isınma döneminde sıfır pozisyon tutun ve kaç çubuğun hariç tutulduğunu not edin.
Sınırlamalar: sekiz çubuk kuralı değil, mekaniği kanıtlar; orantılı maliyetler ve kapanışta gerçekleşme varsayımı, likiditesi düşük enstrümanlarda kaymayı olduğundan düşük gösterir.
Önemli çıkarımlar
- Vektörleştirilmiş bir geriye dönük test beş sütundan oluşur: sinyal, pozisyon (kaydırılmış), varlık getirisi, devir üzerinden maliyet, strateji getirisi; sermaye kümülatif çarpımdır.
position = signal.shift(1)pazarlık konusu değildir; onu kaldırıp sonucun nasıl şiştiğini izleyerek test edin.- Maliyetleri
position.diff().abs()üzerinden uygulayın ve her zaman aynı varsayımlarla al-ve-tut stratejisiyle karşılaştırın. - Vektörleştirilmiş testler kapanıştan kapanışa kurallar için uygundur; stoplar, pozisyon büyüklüğü ve gerçekçi emir gerçekleşmeleri 8. dersteki olay güdümlü motoru gerektirir.
Sonraki adım
8. ders olay güdümlü bir geriye dönük test oluşturuyor: ATR stopları, pozisyon büyüklüğü ve R-katlarıyla ölçülen bir işlem listesi içeren çubuk çubuk ilerleyen bir döngü.
Öz değerlendirme
Soruları yanıtlayın, ardından yanıtlarınızı kontrol edin. İstediğiniz kadar tekrar deneyebilirsiniz.
Kendi tekrarınız için otomatik öz değerlendirme. Cevaplarınız tarayıcınızda kontrol edilir; bunları görmez ve değerlendirmeyiz. Bu bir sınav veya yeterlilik değildir.
İlerlemeniz
“Tamamlandı” yalnızca dersi bitirdiğinizi işaretlediğiniz anlamına gelir. Anlayışınızın bir sınavı değildir. İlerleme ve notlar yalnızca bu cihazdaki bu tarayıcıda saklanır — bir hesapta değil.