Anda mengirim notebook itu kepada saya Minggu malam, dan sejak itu saya membiarkannya terbuka di monitor kedua. Momentum lintas-seksi, 150 perpetual Binance USDⓈ-M teratas berdasarkan volume dolar 30 hari, rebalance mingguan, long pada desil teratas dan short pada desil terbawah, 2021-01 hingga 2026-06. Sharpe 2.31, drawdown maksimum 14.2%, dan model biaya yang menurut saya sudah masuk akal: taker saat masuk, taker saat keluar, funding dihitung per interval, komponen slippage yang meningkat sesuai ukuran posisi Anda relatif terhadap order book. Bagian sulitnya sudah Anda kerjakan dengan benar. Lalu Anda bertanya mengapa paper trading selama enam minggu hasilnya datar, dan apakah edge-nya sudah memudar.
Edge-nya tidak memudar. Edge itu memang tidak pernah ada dalam backtest. Lihat sel 4:
info = requests.get(BASE + "/fapi/v1/exchangeInfo").json()
symbols = [s["symbol"] for s in info["symbols"]
if s["status"] == "TRADING" and s["quoteAsset"] == "USDT"]
Anda memanggil endpoint itu pada Juni 2026 dan memakai jawabannya untuk menentukan apa yang bisa diperdagangkan pada Maret 2021. Setiap simbol dalam daftar itu bertahan hingga Juni 2026, karena memang begitu daftar tersebut dibentuk. Itulah seluruh masalahnya, dan dampaknya lebih besar daripada gabungan semua komponen lain dalam model biaya Anda.
Informasi yang tidak akan diberikan endpoint itu
Tidak ada riwayat di exchangeInfo. Tidak ada parameter asOf, arsip, ataupun changelog. Isinya hanya potret kondisi saat ini, dan Binance tidak pernah menjanjikan lebih dari itu. Saat kontrak dihapus dari listing, entrinya dihapus dari respons dan ticker-nya tidak lagi ada menurut API. Sejak 2019, Binance telah mendaftarkan lebih dari 600 perpetual USDⓈ-M dan menghentikan jauh lebih dari seratus di antaranya. BTS, COCOS, TOMO, RAY, FTT, SC, serta sederet panjang kontrak musim altcoin 2021 yang sempat berjaya selama satu kuartal, lalu makin sepi sampai venue menghapusnya.
Coba pikirkan aset mana yang disukai layar momentum 30 hari. Bukan BTC. Layar itu menyukai aset yang baru saja naik tiga kali lipat karena lonjakan saat listing dan siklus Twitter. Kelompok aset seperti itu sangat tumpang tindih dengan aset yang akhirnya dihapus dari listing, dan filter universe Anda menyingkirkan aset-aset yang tumpang tindih itu.
Saya menjalankan ulang strategi Anda menggunakan arsip snapshot kami, universe point-in-time, sinyal yang sama, dan biaya yang sama. Hasil Sharpe-nya 0.74 dengan drawdown 31%. Sekitar dua perlima selisihnya berasal dari aset yang dihapus dari listing dan tidak pernah bisa Anda pegang. Seperempat lainnya berasal dari masalah kebalikannya, yang lebih samar dan saya duga akan lebih sulit Anda terima.
Sisi lain mesin waktu: simbol yang belum ada saat itu
Fitur Anda menghitung return 90 hari. Jendela rolling Anda adalah min_periods=20, karena Anda menetapkannya sekali agar warmup tidak menghapus kuartal pertama sampel, lalu tidak pernah meninjaunya lagi. Jadi, kontrak yang baru listing 21 hari lalu mendapat skor momentum berdasarkan pergerakan harga pascalisting selama tiga minggu. Skornya masuk desil teratas kira-kira setiap kali listing-nya berjalan baik, lalu kontrak itu masuk ke portofolio Anda.
Bagian itu masih bisa dibilang sah. Yang tidak sah adalah ini: provider Anda mengisi data historis sebagian simbol dengan data spot atau indeks dari sebelum kontrak perp-nya ada, sehingga beberapa kontrak memiliki riwayat kline yang mendahului onboardDate mereka sendiri. Anda bisa memeriksanya dalam sekitar satu menit. Gabungkan tabel harga dengan tanggal onboard, lalu hitung jumlah baris sebelum tanggal listing. Dalam data Anda ada 41 simbol dengan bar sebelum listing, dan salah satunya, pada musim panas 2023, menyumbang kenaikan 6% dalam satu minggu pada kurva ekuitas dari posisi di kontrak yang baru akan ada sembilan hari kemudian.
String ticker bukanlah pengenal. Itu label yang disewakan oleh exchange, terkadang dua kali.
Ini membawa kita ke soal pergantian nama. MATICUSDT menjadi POLUSDT. FTMUSDT menjadi SUSDT melalui konversi 1:1. Situasi LUNA pada Mei 2022 menyisakan LUNCUSDT, lalu muncul LUNAUSDT baru yang berbagi akar ticker dengan aset yang kehilangan hampir seluruh nilainya. Jika loader Anda menggunakan string simbol sebagai kunci lalu menggabungkan semua file yang ditemukan, setidaknya ada satu seri dengan diskontinuitas yang bukan pergerakan harga, dan fitur momentum Anda akan membaca diskontinuitas itu sebagai sinyal terkuat dalam seluruh cross-section.
Hal lain yang berubah diam-diam
Begitu Anda menerima bahwa daftar simbol berubah seiring waktu, argumen yang sama berlaku untuk setiap kolom lain dalam respons itu. Anda menggunakan nilai hari ini untuk semuanya.
| Kolom | Perubahannya | Dampaknya |
|---|---|---|
| status | TRADING → SETTLING → dihapus | Survivorship; posisi keluar palsu pada harga penutupan yang tidak pernah diperdagangkan |
| onboardDate | Listing baru setiap minggu; tidak tersedia untuk simbol yang sudah dihapus | Memperdagangkan kontrak sebelum kontrak itu ada |
| tickSize / stepSize | Disesuaikan seiring perubahan tingkat harga | Pembulatan order dan harga limit yang akan ditolak |
| minNotional | Dinaikkan dari waktu ke waktu pada order book yang tipis | Posisi kecil yang akan ditolak router live Anda |
| fundingIntervalHours | 8h selama bertahun-tahun, lalu 4h atau 1h pada banyak simbol | Perhitungan carry meleset 2–3× tepat pada altcoin yang dipegang layar Anda |
| leverage brackets | Tingkat dan margin pemeliharaan direvisi | Pemodelan likuidasi dan kapasitas margin |
Dalam kasus Anda, funding adalah masalah yang paling besar. Loop akrual Anda mengasumsikan tiga pembayaran per hari untuk seluruh periode historis. Porsi yang cukup besar dari portofolio altcoin beralih ke funding setiap empat jam, dan posisi short pada aset dengan funding tinggi menjadi sumber banyak PnL simulasi Anda. Selisihnya bukan sekadar kesalahan pembulatan. Besarnya bisa berkali-kali lipat.
Penghapusan dari listing itu sendiri adalah sebuah peristiwa, dan Anda belum memodelkannya
Dalam pengujian ulang point-in-time Anda, saya memberi strategi itu asumsi keluar yang cukup murah hati. Penghapusan nyata mengikuti urutan yang sudah ditetapkan: pengumuman, biasanya tujuh hingga empat belas hari sebelumnya, lalu periode reduce-only, kemudian penyelesaian paksa pada harga mark. Pengumuman adalah informasi publik dan Anda bisa bertindak atasnya, jadi simulasi yang jujur adalah keluar pada harga penutupan hari pengumuman. Namun, pada penghapusan altcoin yang umum, harga penutupan itu sudah 10-20% di bawah harga minggu sebelumnya, order book-nya tipis, dan komponen slippage Anda perlu memperhitungkan bahwa kondisi pasarnya sudah berbeda. Jika mesin eksekusi Anda memberi harga penyelesaian tanpa dampak pasar, Anda diam-diam membuat aset yang sedang mati bisa diperdagangkan pada nilai wajarnya.
Kalau Anda tidak pernah mengarsipkan exchangeInfo, belum terlambat. Dump publik di data.binance.vision/data/futures/um/monthly/klines/ masih menyimpan direktori untuk simbol yang sudah dihapus lama setelah API melupakannya. Telusuri daftar direktori, lalu gunakan file bulanan pertama dan terakhir untuk setiap simbol guna memperkirakan rentang listing dan penghapusannya tanpa vendor. Ini rekonstruksi, bukan catatan resmi, dan tidak akan memulihkan ukuran tick atau interval funding. Namun, ini akan memberi tahu Anda simbol mana yang ada pada waktu tertentu. Informasi itu mencakup 80% kebutuhan Anda untuk hari Senin.
Yang perlu saya minta Anda bangun sebelum menyentuh sinyal itu lagi
- Cron yang mengambil exchangeInfo setiap hari dari semua venue yang Anda riset, lalu menyimpannya di object storage dengan tanggal sebagai kunci. Setelah dikompresi dengan gzip, ukurannya kurang dari setengah megabyte. Biaya penyimpanan selama sepuluh tahun hanya selisih pembulatan di S3, dan sebagai gantinya Anda mendapat kemampuan riset yang tidak bisa dibeli belakangan.
- Asset master yang dibuat dari snapshot tersebut: satu baris untuk setiap (venue, symbol, valid_from, valid_to), lengkap dengan seluruh kolom. Bandingkan snapshot yang berurutan untuk membuatnya, dan perlakukan setiap perubahan kolom sebagai baris baru.
- Fungsi universe dengan argumen timestamp wajib.
universe(ts), jangan pernahuniverse(). Buat agar opsi default tidak mungkin digunakan, sehingga tak seorang pun, termasuk diri Anda di masa depan pada pukul 1am, bisa tanpa sengaja mengambil daftar survivor. - Pemeriksaan pra-listing di loader data: tidak boleh ada bar sebelum
onboard_tsdikurangi satu hari. Gagalkan prosesnya, jangan sekadar memberi peringatan. - ID instrumen internal yang stabil dan tetap sama saat nama berubah, sementara ticker hanya menjadi atribut. Petakan POL dan MATIC ke satu ID, lalu tandai redenominasi agar logika kontinuitas bisa menolak penggabungan seri yang melintasinya.
Lakukan itu, lalu jalankan ulang. Perkiraan saya hasilnya akan mendekati 0.74 yang saya dapat, dan pertanyaan menariknya menjadi apakah angka 0.74 yang mencakup aset-aset mati itu masih punya sesuatu yang layak diuji lewat paper trading. Mungkin saja. Momentum lintas-seksi pada kontrak perp bukan strategi kosong, dan sebagian dari yang tersisa setelah universe diperbaiki adalah carry nyata dari sisi short. Anda juga akan melihat hasil paper trading dan backtest mulai sejalan, karena paper trading selama ini selalu berjalan dengan universe point-in-time. Memang hanya itu pilihan yang tersedia.
P.S. Ini bukan keanehan khusus kripto, hanya lebih kentara di sini. Peneliti saham sudah lama bergulat dengan return delisting dan ticker yang didaur ulang sejak CRSP mulai mendistribusikannya, dan pasar prediksi membawa masalah ini ke titik ekstrem: setiap kontrak kedaluwarsa secara desain, jadi universe-nya hanya berisi listing dan penghapusan. Jika Anda menerapkan layar ini ke Kalshi, bangun asset master terlebih dahulu. Di sana memang tidak ada jenis riwayat lain.
← Semua artikel


