Fungsi itu bernama enter_pack. Itu seharusnya sudah menjadi peringatan. Seorang agen riset telah menulis cash-and-carry BTC: ketika perpetual diperdagangkan lebih dari delapan basis poin di atas spot, beli spot, short perp, diam saja. Funding dan basis akan mengurus sisanya. Backtest mengisi kedua leg dalam milidetik yang sama, di mid, plus satu tick kesopanan. Kurva ekuitasnya berupa tangga. Tidak ada yang akan menyebutnya seru. Itulah nilai jualnya.
Kami mempromosikannya ke paper pada hari Senin.
Senin: pack yang selalu terisi
Sinyal pertama masuk pada 11:17 UTC. Basis di layar 9.4 bps, perp mahal. Di backtest, enter_pack mengembalikan dua fill dan residual nol. Di paper, fungsi itu mengembalikan fill spot 0.40 BTC di ask, dan short resting di perp yang tidak terisi.
Spot sudah membayar biaya taker 4 bp dan spread sekitar 1 bp. Harga perp yang kami inginkan masih ada di buku, lalu tidak. Dua puluh detik kemudian basis yang dikutip 5 bps, karena kami baru saja lift spot. Empat puluh detik kemudian perp terisi, setelah pergerakan. Kami sudah packed. Kami packed pada basis yang tidak lagi menutup biaya masuk dan keluar.
Backtest akan mencatat "+9.4 bps carry, residual 0." Blotter punya biaya taker spot 4 bps, long tanpa lindung 40 detik, dan gap entri sekitar 5. Saya punya sampel satu dan, tetap, terlalu percaya pada tangga itu.
Selasa: kami membuka fungsinya
enter_pack menerima daftar leg dan target mid. Fungsi itu melakukan loop, mengisi setiap leg pada mid * (1 ± slip), dan menulis satu baris portofolio. Tidak ada timestamp kedua. Tidak ada cabang di mana leg dua tidak ada. Unit test meng-assert residual == 0.
Itulah tes yang membuat kita merasa dewasa. Tes itu tidak akan pernah gagal.
Kami memecah pack menjadi dua order dengan state masing-masing: submitted, partial, filled, canceled. Incomplete menjadi objek first-class. Replay historis masih tidak punya buku yang nyata, jadi kami curang. Tunda fill kedua dengan draw dari waktu tunggu Senin (mean 26 detik, ekor yang tidak saya sukai), dan geser harganya sebesar apa pun yang dilakukan spot dalam jendela itu. Kasar, tetapi tangganya tumbuh takik sebelum makan siang: pack yang masuk pada 3 bps, pack yang tidak pernah menjadi pack.
Rabu: tiga detik, lalu buang
Jika leg kedua belum on dalam tiga detik, flatten yang pertama. Seharusnya kami mulai dari situ. Kedengarannya konservatif sampai kita menghitung harga abort-nya. Flatten berarti kita menyeberangi spot untuk masuk dan menyeberanginya lagi untuk keluar. Dua biaya taker, dua spread, tanpa carry, tanpa funding. Di replay yang ditulis ulang, abort itu tidak jarang. Mereka mengelompok pada bar di mana basis tampak paling "nyata," yang biasanya bar di mana sesuatu sudah mengalir melalui spot.
Pada Rabu malam kami punya tujuh belas sinyal paper untuk diperdebatkan.
| Backtest, Senin pagi | Paper, sampai Rabu | |
|---|---|---|
| Entri | Kedua leg di mid, satu timestamp | Spot di ask; perp 5–40s kemudian, atau tidak pernah |
| Residual | Selalu 0 | Tanpa lindung pada 10 dari 17 sinyal |
| Biaya pada trade yang berjalan | Dua taker | Dua taker, atau empat jika kami abort |
| Pendorong PnL | Basis + funding | Apa pun yang dilakukan spot saat kami menunggu |
Seorang rekan masih punya notebook yang memperlakukan pack sebagai produk listed, BTC_CARRY, dengan "pajak eksekusi" flat 2 bp. Saya suka notebook itu. Notebook itu menghasilkan tangga yang sama seperti yang dihasilkan agen. Pajak adalah mean. Orphan adalah distribusi. Mean tidak tertabrak di jam yang tipis; 0.40 BTC spot sisa bisa.
Kamis: sisa, lalu kopi
Tiga detik menggugurkan hampir semuanya begitu kami juga menunggu di antrean. Kami longgarkan paper menjadi lima belas. Pada 02:11 UTC Kamis, spot terisi dan perp tidak. Saya masih dalam fase duka "akan rest, akan lift" ketika saya pergi membuat kopi.
02:11:08 terisi BTCUSDT 0.40 beli
02:11:08 submitted BTCUSDT-PERP 0.40 jual, post-only
02:11:41 masih working
02:26:00 mark residual −18.1 bps
BTC turun 18 bps dalam jendela yang sepi. Residual adalah keseluruhan trade. Funding, ketika tercetak, mengkredit perp yang tidak kami miliki. Spot hanya duduk di situ sebagai long. Jalur overnight backtest asli tidak pernah berisi posisi satu-leg, jadi tidak pernah menanyakan pertanyaan yang kami tanyakan pada setiap buku lain: berapa bar terburuk yang bisa dicetak sisa ini, dan di mana stop untuk posisi yang tidak kami maksudkan untuk dipegang?
Tujuh pack lengkap itu juga bukan pahlawan. Pada saat leg kedua tercetak, lift spot kami sendiri sudah menekan indeks, dan basis entri 3–5 bps lebih buruk daripada snapshot yang memicu sinyal. Ambang delapan bps adalah angka tentang sebuah layar.
Apa yang akan kami lewati lain kali
Kami tidak akan merilis multi-leg sebagai fungsi fill tunggal. Aturan yang sama untuk carry perp-spot, calendar, atau call vertical yang diajukan agen sebagai dua limit lalu merayakan ketika keduanya "fill" di mid.
- State order per-leg, termasuk partial. Perlakukan pack sebagai induk dari dua tiket.
- Timer max-orphan yang benar-benar terpicu, dan jalur flatten yang membayar dua spread saat keluar.
- Mark-to-book pada residual, dengan stop yang diukur untuk sisa. Net yang packed adalah nosional yang salah.
- Tidak ada carry yang dikredit, tidak ada funding yang diakru, sampai kedua leg on. Incomplete adalah incomplete.
- Tolak mid-on-mid sebagai default untuk apa pun yang punya dua tiket. Jika harus menebak, tebak lebih buruk pada leg yang tipis dan lebih belakangan pada fill kedua.
Dan kami tidak akan membiarkan test_pack_is_atomic masuk ke repo. Atomic adalah properti matching engine, bukan fungsi helper. BTC spot dan BTC perpetual adalah dua buku yang kadang bersajak. Paper adalah tempat mereka berhenti bersajak, yang merupakan satu-satunya alasan tangga itu pernah menarik.



