Malam Ketika Backtest Saya Membohongi Saya

Suatu malam, sebuah backtest memberi tahu saya bahwa saya telah mengubah saldo awal yang sederhana menjadi 2.792 triliun won — lebih besar daripada output tahunan sebagian besar perekonomian di planet ini. Saya menatapnya. Selama beberapa menit, sebagian dari diri saya yang tenang dan tamak mulai mencari-cari alasan mengapa angka itu mungkin nyata.

Itu tidak nyata. Itu adalah bug. Dan bug itu ternyata jauh lebih mendidik daripada strategi pemenang mana pun, karena ia adalah bug tentang satu hal yang menjadi alasan keberadaan sebuah backtest: realitas.

Angka yang seharusnya membuat saya takut

Saya sedang menjalankan pencarian parameter — ribuan konfigurasi, masing-masing diputar ulang melintasi data historis dan diperingkat berdasarkan hasil akhir. Sebagian besar kembali dengan hasil biasa. Satu kembali dengan hasil gila.

Gila-yang-menguntungkan-Anda adalah keluaran paling berbahaya yang dapat dihasilkan sebuah sistem, karena ia datang dengan mengenakan wajah keberhasilan. Sebuah run yang merugi membuat Anda melakukan debug. Sebuah run yang “berhasil” membuat Anda merayakannya. Penelitian kritisnya bersifat asimetris, dan ia berjalan ke arah yang justru salah: kita menginterogasi hasil yang tidak kita sukai dan meloloskan begitu saja hasil yang kita cintai. Saya nyaris meloloskan yang ini begitu saja.

Insting yang harus saya pelajari — dengan cara yang sulit — adalah kebalikannya. Semakin spektakuler hasilnya, semakin pasti bahwa ada sesuatu yang rusak. Pasar tidak menyerahkan GDP sebuah negara kecil kepada seorang pembangun pemula. Jika simulasi Anda mengatakan demikian, maka simulasi itu sedang berbohong, dan satu-satunya tugas Anda adalah mencari tahu caranya.

Kesalahan satu: mempertaruhkan seluruh akun, setiap kali

Cacat pertama ada pada position sizing. Setiap trade dibuat berukuran pada dasarnya seluruh akun, dan keuntungannya langsung digabungkan kembali ke dalam taruhan berikutnya. Pada saat Anda melakukan itu, Anda berhenti memodelkan trading dan mulai memodelkan deret geometri. Sebuah rangkaian yang cukup panjang dari hasil yang bahkan sedikit menguntungkan — atau noise murni yang kebetulan jatuh ke arah yang benar cukup sering — tidak tumbuh, melainkan meledak. Matematikanya melarikan diri dari realitas dan tidak pernah menoleh ke belakang.

Inilah hal yang memikat tentang backtest yang sepenuhnya menggabungkan keuntungan: ia tidak memerlukan strategi yang bagus untuk menghasilkan angka yang hebat. Ia hanya memerlukan trade yang cukup banyak dan simulator yang cukup murah hati untuk membiarkan taruhan terus berjalan. Penggabungan keuntungan mengubah kecondongan statistik yang samar dan tak bermakna menjadi kurva eksponensial, dan kurva eksponensial sepanjang ribuan trade menghasilkan angka yang terlihat seperti takdir namun tidak berarti apa-apa. Saldo astronomis itu bukanlah bukti adanya keunggulan. Itu adalah bukti eksposur seluruh akun yang diterapkan pada keacakan.

Kesalahan dua: simulator yang tidak bisa mati

Cacat kedua lebih buruk, karena ia bersifat filosofis. Backtester saya tidak memiliki absorbing barrier — tidak ada titik di mana akun tersebut benar-benar mati. Maka ketika serangkaian trade buruk menyeret saldo turun sebesar 99,99%, simulasinya tidak berhenti. Ia membiarkan mayat itu tetap di atas meja dan membiarkannya terus melakukan trading. Dan dari saldo yang nyaris nol itu, sebuah rentetan keberuntungan “menghidupkan kembali” akun tersebut dan membawanya naik kembali ke ketinggian yang konyol.

Dalam akun nyata, pemulihan semacam itu mustahil. Nol adalah nol. Saldo yang sudah terlikuidasi tidak mendapat babak kedua — Anda keluar dari permainan, secara permanen, dan tidak ada rentetan kemenangan di masa depan yang dapat menjangkau kembali melintasi waktu untuk menyelamatkan Anda. Dengan membiarkan akun yang bangkrut tetap melakukan trading, kode saya secara diam-diam telah menghapus aturan paling penting dalam seluruh dunia trading: bahwa kehancuran itu final. Segala sesuatu yang mengalir dari sana — seluruh fantasi itu — mengikuti secara logis dari satu batasan yang hilang. Simulasi itu bukan memodelkan strategi yang bertahan hidup. Ia memodelkan strategi yang telah diizinkan untuk mati, lalu dilarang untuk tetap mati.

Optimizer sedang memburu titik buta saya

Inilah bagian yang paling lama saya pahami: pencarian parameter itu tidak tersandung pada konfigurasi absurd tersebut secara kebetulan. Ia pergi mencarinya.

Sebuah pencarian atas ribuan konfigurasi bukanlah pengamat yang netral. Ia adalah lawan yang mengoptimalkan apa pun metrik yang Anda berikan kepadanya. Jika metrik Anda adalah “saldo akhir” dan simulator Anda memiliki titik lemah — sebuah tempat di mana hal-hal yang tidak realistis secara diam-diam diizinkan terjadi — maka pencarian itu akan menemukan titik lemah tersebut dan menyandarkan seluruh bebannya di sana. Ia tidak memberi imbalan kepada strategi terbaik. Ia memberi imbalan kepada konfigurasi yang paling efisien mengeksploitasi celah antara simulasi Anda dan realitas.

Maka hasil triliunan won itu bukanlah satu bug malang yang muncul secara acak. Itu adalah konsekuensi yang dapat diprediksi dari mengarahkan sebuah optimizer yang kuat ke sebuah simulator yang dapat ditipu. Setiap kelemahan yang Anda tinggalkan dalam sebuah backtest menjadi, di bawah pencarian, sebuah strategi. Optimizer adalah mesin untuk menemukan secara tepat asumsi-asumsi yang lupa Anda paksakan.

Pertandanya

Gabungkan kesalahan-kesalahan itu dan Anda mendapatkan sebuah mesin yang memproduksi keajaiban. Ia dapat bertahan dari apa pun, sehingga ia bertahan dari segalanya; ia mempertaruhkan segalanya, sehingga ketika ia bertahan, ia bertahan secara luar biasa; dan sebuah pencarian secara diam-diam menyetelnya agar melakukan keduanya sekeras mungkin. Keluarannya bukanlah kinerja sebuah strategi. Itu adalah bentuk dari bug itu sendiri, yang digambarkan dalam angka-angka yang sangat besar.

Inilah mengapa “bertahan hidup lebih dulu” bukanlah sekadar slogan. Sebuah backtest yang tidak bisa bangkrut akan, jika diberi cukup banyak konfigurasi untuk ditelusuri, selalu pada akhirnya memunculkan satu yang terlihat seperti kejeniusan — bukan karena konfigurasi itu bagus, melainkan karena pencarian itu dengan sabar menambang titik buta simulator Anda. Angka yang mengesankan itu adalah gejalanya. Kebangkrutan yang hilang itu adalah penyakitnya.

Perbaikan yang membosankan

Perbaikannya tidak glamor. Ukuran posisi menjadi sebagian kecil tetap dari akun, bukan keseluruhannya, sehingga sebuah kemenangan tidak bisa menggelinding membesar menjadi omong kosong dan sebuah kerugian tidak bisa bersifat semua-atau-tidak-sama-sekali. Simulator mendapatkan kondisi kehancuran yang nyata: jatuh di bawah saldo bertahan minimum dan run pun berakhir, ditandai mati, titik. Dan ia mendapatkan ukuran order minimum, sehingga trade yang terlalu kecil untuk eksis di pasar nyata tidak bisa secara diam-diam menjaga akun yang sekarat tetap di alat bantu hidup.

Tidak satu pun dari ini merupakan ide yang cerdas. Tidak ada wawasan di dalamnya, tidak ada keunggulan. Itu adalah simulasi yang akhirnya bersedia mematuhi batasan-batasan yang realitas tidak pernah longgarkan — biaya yang tidak memaafkan Anda, likuiditas yang tidak tak terbatas, dan sebuah nol yang darinya Anda tidak bisa kembali. Sebagian besar pekerjaan membangun backtest yang jujur adalah persis ini: bukan membuatnya lebih pintar, melainkan menolak membiarkannya curang. Tanggung jawab pertama sebuah backtest yang jujur bukanlah menunjukkan keuntungan kepada Anda. Tanggung jawabnya adalah mampu menunjukkan kehancuran kepada Anda.

Mengapa saya berhenti memercayai kabar baik

Inilah bagian yang tidak nyaman. Bug itu mudah. Hal yang sulit adalah bahwa saya nyaris tidak memeriksanya — karena angka itu menguntungkan saya, dan saya menginginkan itu benar. Sebuah hasil yang bertentangan dengan Anda akan diinterogasi. Sebuah hasil yang menyanjung Anda akan dipercaya.

Asimetri itulah tempat sebagian besar penipuan diri dalam pekerjaan ini berdiam. Bukannya orang tidak bisa menemukan bug mereka; melainkan mereka berhenti mencari pada saat sebuah bug mulai membayar mereka. Pasar pada akhirnya akan menagih harga penuh untuk setiap asumsi nyaman yang tidak pernah Anda periksa — tetapi sebuah backtest akan dengan senang hati membiarkan Anda memegang asumsi itu selama berbulan-bulan, karena ia, secara konstruksi, adalah satu-satunya tempat di mana menjadi salah itu gratis.

Apa yang sebenarnya diubahnya

Maka disiplin yang saya pertahankan dari triliunan won palsu itu hampir tidak ada hubungannya dengan position sizing. Ia mengubah urutan kepercayaan saya. Sebuah hasil yang terlihat bagus kini dianggap bersalah sampai terbukti tidak bersalah: sebelum saya bertanya “bagaimana ia melakukan ini?”, saya bertanya “apa yang rusak di sini?” — dan saya berusaha, dengan sengaja, untuk merusaknya sendiri sebelum pasar mendapatkan kesempatan itu. Hasil-hasil yang bertahan dari perlakuan bermusuhan itu adalah satu-satunya yang saya izinkan diri saya percayai, dan jumlahnya jauh lebih sedikit daripada yang saya harapkan.

Sebuah backtester yang tidak bisa kehilangan segalanya bukanlah optimistis. Ia sedang berbohong. Dan kebohongan paling berbahaya yang dapat ia katakan adalah kebohongan yang sudah Anda harapkan untuk dengar sejak awal.

— Tidak ada sinyal, tidak ada imbal hasil, bukan nasihat investasi.