Kami me-restart strategi paper di tengah transaksi dan mendapatkan urutan order yang berbeda dari sebelum restart. Data pasar sama, versi strategi sama, saldo akun sama. Perhitungan sinyalnya cocok. Namun, ingatan strategi tentang posisi dan order tertunda tidak cocok.
Kami menelusuri ketidakcocokan itu dalam sesi replay selama sehari. Pelajarannya sederhana: bagi perangkat lunak Anda, restart adalah peristiwa pasar. Jika Anda tidak menguji cara strategi membangun ulang state-nya, backtest yang mulus bisa menyamarkan sistem paper yang lupa apa saja yang dimilikinya.
09:10 — Kami memilih posisi yang sederhana
Strategi uji ini memperdagangkan kontrak perpetual yang likuid: masuk posisi long saat moving average pendek menembus ke atas moving average yang lebih panjang, lalu keluar saat terjadi persilangan sebaliknya. Kami memulai replay dengan posisi kecil yang sudah terbuka dan order limit reduce-only yang masih aktif untuk menguranginya. Dengan begitu, proses pemulihan harus membangun ulang 2 hal: aset yang kami miliki dan tindakan yang sudah kami minta kepada bursa.
Saat checkpoint, akun memegang 0.04 kontrak. Order terbuka untuk 0.01. Proses strategi menyimpan kedua nilai itu di memori, tetapi proses startup-nya hanya mengambil posisi. Order yang tersimpan dianggap sudah tidak ada.
09:25 — Order duplikat pertama muncul
Setelah restart, strategi melihat posisi long yang ada, menjalankan logika sinyal, lalu mengirim order lain untuk mengurangi posisi sebesar 0.01. Kini ada 2 order aktif di venue paper. Masing-masing order tidak bermasalah jika berdiri sendiri. Namun, keduanya bisa menjual 2 kali jumlah yang dimaksudkan jika sama-sama terisi.
Awalnya kami menyalahkan loop sinyal. Masalahnya bukan di loop, melainkan snapshot yang tidak lengkap. Strategi bertanya, “Posisi apa yang saya miliki?” tetapi tidak pernah bertanya, “Order mana yang masih aktif?”
| State setelah restart | Yang dipercaya proses | Yang dimiliki akun |
|---|---|---|
| Posisi | Long 0.04 | Long 0.04 |
| Order pengurangan posisi yang terbuka | Tidak ada | 2 order masing-masing sebesar 0.01 |
| Eksposur yang dimaksudkan setelah 1 order terisi | Long 0.03 | Bisa menjadi long 0.02 |
10:00 — Kami memperbaiki pemulihan, lalu menemukan masalah waktu
Kami mengubah startup agar membangun ulang state dari posisi akun dan order terbuka sebelum mengaktifkan keputusan baru. Duplikat pun hilang. Lalu kami membuat kondisi putus koneksi yang lebih rumit: satu order terisi saat strategi offline, dan notifikasi pengisian baru tiba setelah koneksi tersambung kembali.
Snapshot akun sudah mencerminkan order yang terisi itu. Notifikasi yang terlambat kemudian mengurangi posisi lokal untuk kedua kalinya. Selama beberapa detik, strategi mengira posisinya 0.02 kontrak, padahal akun memegang 0.03. Penyeimbangan ulang berikutnya didasarkan pada kekurangan posisi yang sebenarnya tidak ada.
Kami menambahkan aturan rekonsiliasi: jadikan snapshot akun sebagai titik awal, gunakan ID peristiwa untuk mengabaikan pengisian yang sudah tercermin di snapshot, dan jangan kirim order sebelum sinkronisasi awal selesai. Notifikasi bisa terlambat atau terkirim 2 kali. Proses pemulihan harus bisa menangani keduanya.
13:40 — Replay menangkap ketidakcocokan yang luput terlihat
Kami memutar ulang pergerakan harga yang sama untuk sesi awal dan sesi setelah restart. Jika hanya membandingkan P&L akhir, masalahnya akan terlewat: kedua versi berakhir dengan posisi yang sama setelah pasar berbalik arah. Perbandingan peristiwa orderlah yang mengungkapkannya.
Kami mencatat setiap keputusan beserta state yang dibacanya: posisi, order terbuka, ID pengisian terakhir yang diproses, nilai sinyal, dan versi strategi. Dengan begitu, peristiwa pertama yang menyimpang bisa dijelaskan. Satu sesi melihat order aktif, sedangkan sesi lain melihat daftar kosong. Kemudian, salah satu sesi memproses pengisian yang sama 2 kali.
Saldo akhir yang sama tidak membuktikan perilaku yang sama. Bandingkan urutan keputusan dan order, terutama di sekitar titik pemulihan.
16:20 — Apa yang akan kami lakukan lain kali
Kami menghabiskan terlalu banyak waktu memutar ulang data harga sebelum memeriksa perubahan state akun. Lain kali, kami akan lebih dulu menyimulasikan kasus kegagalan dan menjaga pergerakan pasar hampir datar. Dengan begitu, kesalahan perangkat lunak mudah terlihat tanpa pergerakan volatil yang mengaburkan diagnosis.
- Restart saat ada posisi dan order yang terisi sebagian.
- Putuskan koneksi setelah order dikirim, lalu sambungkan kembali sebelum notifikasi pengisian tiba.
- Kirim peristiwa pengisian yang sama 2 kali dan pastikan state hanya berubah sekali.
- Tahan pengiriman order baru sampai posisi dan order terbuka sama-sama selesai direkonsiliasi.
- Bandingkan log keputusan dan order antara sesi tanpa putus dan sesi setelah restart.
Kami juga belajar untuk menyimpan snapshot pemulihan bersama versi strategi dan log peristiwa. Kegagalan bisa direproduksi dalam hitungan menit, tanpa bergantung pada ingatan seseorang tentang urutan koneksi ulang yang persis.
Strategi paper yang hanya berperilaku benar selama prosesnya tetap berjalan belum menjalani simulasi menyeluruh. Restart saat posisi masih terbuka, buat pengisian terlambat tiba, lalu periksa setiap order yang dikirim setelahnya. Tujuannya bukan membuktikan bahwa strategi tidak akan pernah gagal. Tujuannya membuat proses pemulihannya terlihat sebelum akun paper mengajarkan pelajaran yang sama secara mendadak.
← Semua artikel


