Bir işlemin ortasında kâğıt işlem stratejisini yeniden başlattık ve önceki çalıştırmada ürettiği diziden farklı bir emir dizisi elde ettik. Aynı piyasa verisi, aynı strateji sürümü, aynı hesap bakiyesi. Sinyal hesaplaması tutuyordu. Stratejinin pozisyonuna ve bekleyen emirlere dair belleği ise tutmuyordu.
Uyumsuzluğun izini bir günlük tekrar oynatma çalışmasıyla sürdük. Çıkardığımız ders basitti: yazılımınız için yeniden başlatma da bir piyasa olayıdır. Stratejinin durumunu nasıl yeniden oluşturduğunu test etmezseniz, kusursuz görünen bir geriye dönük test, neye sahip olduğunu unutan bir kâğıt işlem sistemini gizleyebilir.
09:10 — Sıradan bir pozisyon seçtik
Test stratejisi likit bir sürekli vadeli işlem sözleşmesinde işlem yapıyordu: kısa hareketli ortalama uzun olanın üzerine çıktığında uzun pozisyon açıyor, ters kesişimde pozisyondan çıkıyordu. Tekrar oynatmaya, zaten açık olan küçük bir pozisyonla ve pozisyonu azaltmak için bekleyen, yalnızca azaltma yönünde çalışan bir limit emirle başladık. Böylece kurtarma sırasında yeniden oluşturulması gereken iki bilgi vardı: neye sahip olduğumuz ve borsadan ne yapmasını zaten istediğimiz.
Kontrol noktasında hesapta 0.04 kontrat vardı. 0.01 için verilen emir açıktı. Strateji süreci bu iki değeri belleğinde önbelleğe almıştı, ancak başlangıç akışı yalnızca pozisyonu getiriyordu. Önbellekteki emri yok olmuş saydı.
09:25 — İlk mükerrer emir ortaya çıktı
Yeniden başlatılınca strateji mevcut uzun pozisyonu gördü, sinyal mantığını çalıştırdı ve pozisyonu azaltmak için bir 0.01 emri daha gönderdi. Artık kâğıt işlem ortamında iki etkin emir vardı. Tek başlarına ikisi de hatalı değildi. Ancak ikisi de gerçekleşirse amaçlanan miktarın iki katı satılabilirdi.
İlk başta sinyal döngüsünü suçladık. Sorun döngüde değil, eksik anlık görüntüdeydi. Strateji, “Hangi pozisyona sahibim?” diye sordu ama “Hangi emirler hâlâ beklemede?” diye hiç sormadı.
| Yeniden başlatma sonrası durum | Sürecin inandığı | Hesaptaki gerçek durum |
|---|---|---|
| Pozisyon | 0.04 uzun | 0.04 uzun |
| Açık azaltma emirleri | Yok | Her biri 0.01 olan iki emir |
| Bir emir gerçekleşirse hedeflenen pozisyon | 0.03 uzun | 0.02 uzun olabilir |
10:00 — Kurtarmayı düzelttik, ardından bir zamanlama sınırı bulduk
Yeni kararları etkinleştirmeden önce başlangıçta durumu hesaptaki pozisyonlardan ve açık emirlerden yeniden oluşturacak şekilde değişiklik yaptık. Böylece mükerrer emir sorunu çözüldü. Sonra bağlantı kesintisini daha karmaşık hâle getirdik: strateji çevrimdışıyken bir emir gerçekleşti ve gerçekleşme bildirimi yeniden bağlandıktan sonra geldi.
Hesap anlık görüntüsü gerçekleşen emri zaten yansıtıyordu. Ardından gelen gecikmiş bildirim, yerel pozisyonu ikinci kez azalttı. Birkaç saniyeliğine strateji, hesapta 0.03 olmasına rağmen 0.02 kontratı olduğunu sandı. Bir sonraki yeniden dengeleme işlemi gerçekte olmayan bir pozisyon açığına dayanıyordu.
Mutabakat kuralları ekledik: başlangıç noktası olarak hesap anlık görüntüsünü kullanmak, burada zaten yansıtılmış gerçekleşmeleri yok saymak için olay tanımlayıcılarından yararlanmak ve ilk eşitleme tamamlanana kadar emir göndermemek. Bildirim geç gelebilir veya iki kez ulaşabilir. Kurtarma süreci her iki durumu da tolere etmeli.
13:40 — Tekrar oynatma, gözden kaçması kolay bir uyumsuzluğu yakaladı
Aynı fiyat hareketini özgün çalıştırmada ve yeniden başlatılmış çalıştırmada tekrar oynattık. Nihai K&Z değerlerini karşılaştırmak sorunu ortaya çıkarmazdı: piyasa tersine döndükten sonra iki sürüm de aynı pozisyonla sona erdi. Emir olaylarını karşılaştırınca sorun görünür hâle geldi.
Her kararı, okuduğu durumla birlikte kaydettik: pozisyon, açık emirler, işlenen son gerçekleşme tanımlayıcısı, sinyal değeri ve strateji sürümü. İlk farklılaşan olayın nedeni böylece belliydi. Bir çalıştırma bekleyen emir görürken diğeri boş liste görmüştü. Daha sonra birinde gerçekleşme iki kez uygulanmıştı.
Bakiye aynı noktada bitse bile davranışın aynı olduğu kanıtlanmış olmaz. Özellikle kurtarma sınırlarının çevresinde karar ve emir dizilerini karşılaştırın.
16:20 — Bir dahaki sefere neyi farklı yapardık
Hesap durumundaki geçişleri kontrol etmeden önce fiyat verisini tekrar oynatmak için fazla zaman harcamıştık. Bir dahaki sefere önce hata durumlarını oluşturur, piyasa hareketini de neredeyse sabit tutardık. Böylece oynak bir hareket tanıyı bulandırmadan yazılım hatasını kolayca görebilirdik.
- Pozisyon ve kısmen gerçekleşmiş bir emir varken yeniden başlatın.
- Emri gönderdikten sonra bağlantıyı kesin, ardından gerçekleşme bildirimi gelmeden yeniden bağlanın.
- Aynı gerçekleşme olayını iki kez iletin ve durumu yalnızca bir kez değiştirdiğini doğrulayın.
- Pozisyonlar ve açık emirler için mutabakat tamamlanana kadar yeni emirleri engelleyin.
- Kesintisiz ve yeniden başlatılmış çalıştırmaların karar ve emir kayıtlarını karşılaştırın.
Kurtarma anlık görüntüsünü strateji sürümü ve olay günlüğüyle birlikte kaydetmeyi de öğrendik. Böylece birinin tam yeniden bağlantı sırasını hatırlamasına bel bağlamak yerine hatayı dakikalar içinde yeniden üretebildik.
Yalnızca süreci çalışır durumda kaldığı sürece doğru davranan bir kâğıt işlem stratejisi, tam bir provadan geçmiş sayılmaz. Pozisyon açıkken yeniden başlatın, gerçekleşmelerin gecikmeli gelmesini sağlayın ve ardından gönderdiği her emri inceleyin. Amaç, hiç hata yapmadığını kanıtlamak değil. Kâğıt işlem hesabı aynı dersi size ansızın vermek zorunda kalmadan önce kurtarma davranışını görünür kılmaktır.
← Tüm yazılar


