Fidelity Gate: Backtesting Coarse-to-Fine Menipu Anda Lebih Cepat, Kecuali Proxy Murah Memberi Peringkat yang Sama dengan yang Mahal
Bagian dari seri "Backtests Without Illusions".
Setiap pencarian parameter yang serius akan menabrak tembok yang sama: ruang pencarian sangat besar, dan setiap evaluasi yang jujur itu mahal. Strategi multi-timeframe dengan belasan threshold dan tiga periode indikator, dievaluasi lewat walk-forward split multi-fold, bisa memakan waktu beberapa detik per konfigurasi. Sepuluh ribu konfigurasi berarti berjam-jam. Maka Anda mencari jalan pintas, dan jalan pintas itu selalu gagasan yang sama: evaluasi secara murah, promosikan hanya yang bertahan ke pengujian yang mahal. Saring sepuluh ribu konfigurasi pada satu fold, simpan beberapa ratus teratas, jalankan itu pada semua fold. Saring pada candle per jam, lalu drill down ke resolusi 1 detik hanya untuk para finalis.
Inilah pencarian coarse-to-fine — drill-down, multi-fidelitas, successive halving, Hyperband, ASHA — dan ini adalah salah satu gagasan yang benar-benar bagus dalam optimasi. Ia bisa mengubah komputasi sehari menjadi satu jam. Kami memakainya. Tetapi ia menyembunyikan jebakan yang begitu diam-diam sehingga kebanyakan orang yang menerapkannya tidak pernah memeriksanya, dan jebakan itu adalah: seluruh metode ini berasumsi bahwa proxy murah Anda mengurutkan konfigurasi dengan cara yang sama seperti evaluasi yang mahal. Jika tidak, Anda bukan mencari lebih cepat. Anda membuang para pemenang masa depan Anda di gate pertama dan mempromosikan noise — Anda hanya membohongi diri sendiri lebih cepat.
Artikel ini membahas satu pengukuran yang memberi tahu Anda apakah drill-down Anda nyata atau sekadar delusi. Kami menjalankannya pada pencarian multi-timeframe kami sendiri, dan jawabannya tidak nyaman: pada fidelity termurah, proxy kami mengurutkan konfigurasi hampir secara acak (Spearman ρ ≈ 0.03). Jika kami melakukan pruning secara agresif pada fidelity itu — seperti yang diundang oleh setiap default ASHA siap pakai — kami akan membuang para pemenang akhir pada ronde pertama. Solusinya adalah gate wajib yang berjalan sebelum pencarian: ukur korelasi peringkat, dan menolak melakukan pruning di bawah fidelity yang bisa dipercaya.
Apa Sebenarnya Pencarian Multi-Fidelitas Itu

Keluarga metode ini memiliki satu bentuk. Anda mendefinisikan fidelity (juga disebut resource atau budget): sebuah dial dari murah ke mahal yang, pada nilai maksimumnya, memberikan objektif yang sebenarnya. Kemudian Anda menjalankan konfigurasi pada fidelity rendah, mengurutkan peringkatnya, menyimpan sebagian terbaik, dan menjalankan ulang hanya para penyintas itu pada fidelity yang lebih tinggi — mengulanginya hingga sejumlah kecil finalis telah dievaluasi pada fidelity penuh.
Successive halving (Jamieson & Talwalkar, 2016) adalah intinya: mulai dengan N konfigurasi pada resource minimum, simpan 1/η teratas, kalikan resource dengan η, ulangi. Hyperband (Li et al., 2018) membungkus successive halving dalam sebuah loop luar yang melakukan hedging di berbagai starting resource, sehingga Anda tidak perlu menebak seberapa agresif harus melakukan pruning. ASHA (Li et al., 2020) adalah versi asinkron yang ramah-paralel. Elimination rate η adalah satu-satunya kenop yang mereka bagi bersama; default kanonisnya adalah η = 3 — simpan sepertiga teratas pada setiap rung, lipatgandakan tiga kali budget-nya.
Fidelity itu sendiri bisa berupa hampir apa saja dari murah ke mahal yang konvergen ke kebenaran:
- Jumlah fold walk-forward. Evaluasi pada 1 fold, lalu 2, lalu 3, hingga K. Ini adalah fidelity yang kita pelajari di bawah, karena ini adalah yang paling alami untuk backtest dengan rolling out-of-sample split.
- Resolusi candle. Saring pada bar 1 jam, promosikan ke 1 menit, drill down ke 1 detik atau raw trade hanya untuk para finalis. Ini adalah gagasan drill-down adaptif yang diterapkan pada pencarian, bukan pada simulasi fill.
- Panjang histori, epoch, subsample dataset — fidelity klasik ala ML.
Dalam backtest, fold dan resolusi adalah dua hal yang paling penting, dan — inilah inti dari seluruh artikel ini — keduanya tidak sama amannya. Salah satunya memiliki bias yang secara diam-diam memilih parameter yang salah, tidak peduli seberapa hati-hati Anda melakukan gating.
Satu Asumsi yang Menjadi Fondasi Segalanya

Mari tuliskan apa yang sebenarnya dibutuhkan successive halving agar benar. Ia tidak membutuhkan fidelity murah untuk memberikan nilai objektif yang tepat — tidak ada yang peduli bahwa satu fold melaporkan Sharpe yang berbeda dari enam fold. Ia membutuhkan sesuatu yang lebih lemah tetapi jauh lebih spesifik: fidelity murah harus mengurutkan konfigurasi dengan cara yang sama seperti fidelity yang mahal. Jika konfigurasi A mengalahkan konfigurasi B pada fidelity penuh, A seharusnya cenderung mengalahkan B juga pada fidelity rendah. Itu saja. Itu juga segalanya.
Secara formal, besaran yang menentukan apakah drill-down berhasil adalah korelasi peringkat antara objektif fidelity-rendah dan fidelity-tinggi, di seluruh ruang konfigurasi. Jika korelasi itu tinggi, para penyintas ronde murah adalah konfigurasi yang sama dengan yang akan memenangkan ronde mahal, dan Anda menghemat komputasi secara gratis. Jika rendah, ronde murah adalah filter acak: ia membuang konfigurasi bagus dan mempromosikan yang buruk, dan Anda telah menghabiskan budget untuk mempercepat langkah menuju jawaban yang lebih buruk. Tidak ada setelan η di tengah-tengah yang bisa menyelamatkan Anda — proxy yang buruk, jika di-pruning secara lembut, tetap membocorkan para pemenang; jika di-pruning secara agresif, ia mendarahkan mereka habis-habisan.
Kegagalannya tidak terlihat dengan cara yang biasa. Pencarian selesai, melaporkan seorang juara, sang juara terlihat baik-baik saja in-sample. Tidak ada error yang muncul. Anda baru menemukan bahwa proxy itu berbohong ketika sang juara berantakan out-of-sample — dan pada saat itu Anda sudah menyalahkan strateginya, bukan pencarian yang memilihnya. Jadi disiplin yang sama selalu menjadi kesimpulan seri ini: ukur hal yang diasumsikan oleh metode, sebelum Anda mempercayai metode itu. Untuk drill-down, hal yang harus diukur adalah korelasi peringkat, dan pengukurannya murah.
Mengukurnya: Fidelity Gate

Gate ini adalah eksperimen kecil yang Anda jalankan sekali, sebelum pencarian sesungguhnya, pada ruang yang sama dengan yang akan Anda cari. Prosedurnya:
- Ambil beberapa ratus konfigurasi secara acak dari ruang parameter (kami memakai ~200 — cukup untuk estimasi Spearman yang stabil, cukup murah untuk terjangkau).
- Evaluasi masing-masing pada setiap rung fidelity: pada 1 fold, 2 fold, … hingga K fold penuh. Untuk fidelity berbasis jumlah-fold ini hampir gratis, karena fold yang Anda hitung untuk rung murah dipakai ulang pada rung yang mahal — sebuah rata-rata kumulatif.
- Untuk setiap rung
r, hitung korelasi peringkat Spearman antara peringkat r-fold dan peringkat K-fold penuh, di seluruh ~200 konfigurasi tersebut. - Rung pertama di mana ρ melewati ambang batas (kami memakai ρ ≥ 0.5) adalah fidelity paling dangkal yang boleh Anda gunakan untuk melakukan pruning. Di bawah itu, peringkatnya terlalu noisy untuk dipercaya; Anda tidak boleh mengeliminasi konfigurasi di sana.
Semuanya hanya beberapa lusin baris kode. Intinya:
def fidelity_check(cache, n_probe, seed=7):
"""Spearman ρ: cumulative mean over the first r folds (in FOLD_ORDER)
vs the full K-fold objective, on n_probe random configs."""
rng = np.random.default_rng(seed)
k = len(FOLDS)
per_fold = np.empty((k, n_probe))
order_win = np.array([list(FOLDS[fi]) for fi in FOLD_ORDER], np.int64)
for j in range(n_probe):
p = _unit_to_params(rng.random(len(PNAMES))) # random config
scores, *_ = eval_group(cache, p, _sp_of(p)[None, :], order_win, False)
per_fold[:, j] = scores[0] # score on each fold
cums = np.cumsum(per_fold, axis=0) / np.arange(1, k + 1)[:, None] # r-fold mean
rhos = []
for r in range(1, k):
rho = spearmanr(cums[r - 1], cums[-1]).statistic # r folds vs all K
rhos.append(0.0 if math.isnan(rho) else rho)
return rhos
Perhatikan satu detail yang disengaja: fold diambil dalam urutan FOLD_ORDER, sebuah urutan interleaved (berselang-seling) yang bergantian antara irisan awal dan akhir kalender (fold 0, lalu fold tengah, lalu fold 1, lalu fold yang lebih akhir, …). Ini sangat penting dan menjadi topik bagian selanjutnya: artinya "1 fold" adalah satu irisan yang mencakup bagian tengah histori, dan "2 fold" adalah satu irisan awal ditambah satu irisan akhir — tidak pernah berupa jendela terkini yang berurutan. Fidelity murah menjadi lebih murah dengan menggunakan fold yang lebih sedikit, bukan yang lebih baru.
Hasil: Satu Fold Mengurutkan Hampir Secara Acak

Berikut yang dilaporkan gate, dijalankan pada dua setup multi-timeframe kami. Angka tersebut adalah Spearman ρ antara peringkat r-fold dan peringkat K-fold penuh di seluruh ~200 konfigurasi acak — seberapa setia peringkat fidelity-murah memprediksi peringkat fidelity-penuh.
Fold r |
Run Multi-TF | Rezim yang lebih sulit |
|---|---|---|
| 1 | +0.43 | +0.03 |
| 2 | +0.67 | +0.43 |
| 3 | +0.78 | +0.78 |
| 4 | +0.82 | — |
| 5 | +0.91 | +0.91 |
Bacalah kolom rezim-yang-lebih-sulit terlebih dahulu, karena itulah yang mengkhawatirkan. Pada satu fold, ρ = 0.03. Itu bukan korelasi yang lemah; itu sama sekali tidak ada korelasi — peringkat satu-fold dari dua ratus konfigurasi secara statistik tidak bisa dibedakan dari hasil mengacak mereka. Sebuah run successive halving yang dikonfigurasi (seperti kebanyakan, secara default) untuk mulai melakukan pruning pada min_resource = 1 akan, dalam rezim ini, melakukan pemotongan pertama dan paling agresifnya berdasarkan lempar koin. Konfigurasi yang pada akhirnya akan menang pada fidelity penuh memiliki peluang 50/50 untuk bertahan pada ronde pertama itu sendiri. Pada saat Anda mencapai fidelity di mana peringkat mulai berarti sesuatu (ρ = 0.78 pada tiga fold), sebagian besar dari mereka sudah lenyap.
Kolom multi-TF lebih ringan tetapi menyampaikan poin yang sama dengan cara berbeda. Bahkan di sana, satu fold memberikan ρ = 0.43 — di bawah gate 0.5 kami. Ini terlihat seperti korelasi yang lumayan, dan itulah bahayanya: 0.43 cukup tinggi untuk membuat Anda lengah dan cukup rendah untuk membocorkan konfigurasi terbaik Anda. Hanya pada dua fold (ρ = 0.67) barulah peringkat menjadi bisa dipercaya.
Dua hal bisa digeneralisasi dari sini. Pertama, ρ pada satu fold bergantung pada rezim dan tidak bisa diandalkan — kami mengukur nilainya berkisar dari 0.03 hingga 0.43 di berbagai setup, dan pada kedua kasus itu, satu fold saja tidak pernah melewati ambang batas. Kedua, ρ naik secara monoton dan cepat: pada tiga fold kedua setup berada di 0.78, dan pada lima fold keduanya konvergen ke 0.91. Sinyalnya ada di sana; Anda hanya perlu mengeluarkan cukup fidelity untuk melihatnya. Tugas gate adalah menemukan rung yang tepat di mana "cukup" itu mulai berlaku — dan melarang pruning di bawahnya.
Mengapa Satu Fold Begitu Noisy
Noise ini bukan bug dalam konstruksi fold kami; ia bersifat intrinsik, dan memahami alasannya akan mencegah Anda "memperbaikinya" dengan cara yang salah. Satu fold walk-forward adalah jendela yang pendek — berminggu-minggu dari satu rezim pasar. Skor strategi pada jendela itu didominasi oleh seberapa kebetulan parameternya cocok dengan rezim tersebut, yang hanya berkaitan secara longgar dengan seberapa baik ia bergeneralisasi. Dua konfigurasi yang benar-benar berbeda kualitasnya bisa bertukar posisi pada satu fold hanya karena salah satunya kebetulan menangkap tren yang ada di fold itu. Objektif pada satu fold adalah estimator dengan varians tinggi dari objektif yang sebenarnya Anda pedulikan, dan korelasi peringkat justru adalah hal pertama yang dihancurkan oleh varians tinggi — Anda bisa mempertahankan rata-rata dari sebuah estimator sementara peringkatnya murni noise.
Menambahkan fold merata-ratakan varians itu. Setiap fold adalah pengambilan sampel kondisi pasar yang sebagian independen; rata-rata r-fold adalah estimator dengan varians lebih rendah, dan peringkatnya konvergen menuju peringkat fidelity-penuh. Itulah persisnya kenaikan ρ = 0.03 → 0.43 → 0.78 → 0.91: bukan objektifnya yang berubah, melainkan estimasi peringkatnya yang menstabil seiring keberuntungan spesifik-rezim yang saling merata-ratakan. Pelajarannya adalah bahwa fidelity, untuk sebuah backtest, pada dasarnya adalah soal berapa banyak rezim independen yang telah Anda sampel — dan satu rezim hampir tidak pernah cukup untuk dijadikan dasar peringkat.
Ini juga menjelaskan mengapa rezim yang lebih sulit mulai di 0.03 sementara run multi-TF mulai di 0.43. Dalam rezim yang lebih sulit, satu fold itu lebih idiosinkratik terhadap rezimnya — skor satu-fold dari tiap konfigurasi lebih banyak didorong oleh keberuntungan dan lebih sedikit oleh edge yang tahan lama, sehingga peringkatnya lebih mendekati acak. Gate membaca perbedaan itu secara otomatis dan merespons dengan menuntut lebih banyak fold sebelum ia mau melakukan pruning. Anda tidak perlu tahu sebelumnya rezim mana yang sedang Anda hadapi; Anda mengukurnya.
Gate dalam Kode: Menaikkan Fidelity Minimum Secara Otomatis
Output dari gate adalah satu bilangan bulat: min_resource, fidelity paling dangkal yang diizinkan bagi ASHA untuk melakukan pruning. Aturannya mekanis — telusuri rung satu per satu, ambil yang pertama yang ρ-nya melewati ambang batas:
RHO_GATE = 0.5
min_res = len(FOLDS) # default: pruning OFF (full fidelity)
rhos = fidelity_check(cache, n_probe=200) # [ρ@1, ρ@2, …, ρ@(K-1)]
passing = [r for r, rho in enumerate(rhos, 1) if rho >= RHO_GATE]
if passing:
min_res = passing[0] # first rung that clears the gate
pruner = SuccessiveHalvingPruner(min_resource=min_res, reduction_factor=3)
Telusuri ini pada dua run tersebut. Pada setup multi-TF, ρ@1 = 0.43 gagal melewati gate tetapi ρ@2 = 0.67 melewatinya, sehingga min_resource dinaikkan otomatis menjadi 2: ASHA menjalankan setiap konfigurasi pada setidaknya dua fold sebelum diizinkan mengeliminasi apa pun, lalu melakukan pruning secara normal dari situ. Pada rezim yang lebih sulit, ρ@1 = 0.03 dan ρ@2 = 0.43 keduanya gagal; ρ@3 = 0.78 adalah yang pertama lolos, sehingga min_resource menjadi 3. Dan fallback yang krusial: jika tidak ada rung yang mencapai 0.5, passing kosong dan min_resource tetap di K — pruning dimatikan sepenuhnya, dan pencarian secara elegan berdegradasi menjadi pencarian fidelity-penuh biasa, bukan pencarian cepat yang salah. Drill-down yang tidak bisa membuktikan proxy-nya, secara sederhana menolak untuk melakukan pruning.
Ini adalah seluruh filosofi dalam satu baris alur kontrol. Default dari setiap library successive halving adalah "lakukan pruning mulai dari min_resource = 1, percayai rung yang murah." Gate menggantinya dengan "lakukan pruning mulai dari rung pertama yang menurut data bisa dipercaya, dan jika tidak ada, jangan lakukan pruning." Biayanya satu probe ~200-konfigurasi di muka, dan itu mengubah drill-down dari sebuah tindakan iman menjadi keputusan yang terukur. Elimination rate η = 3 tetap tidak berubah; gate tidak menyentuh seberapa keras Anda melakukan pruning, hanya seberapa dini Anda diizinkan untuk mulai.
Satu catatan kejujuran yang terlihat dalam kode di atas: menaikkan min_resource menggerus percepatan yang didapat. Melakukan pruning pada 3 fold alih-alih 1 fold berarti setiap konfigurasi — termasuk yang akan Anda buang — harus membayar biaya tiga fold. Itulah harga dari kebenaran, dan itu adalah pertukaran yang tepat: percepatan 2x yang lebih kecil pada pencarian yang menemukan pemenang sejati mengalahkan percepatan 6x pada pencarian yang membuang mereka. Gate membuat pertukaran itu secara eksplisit, bukan menyembunyikannya.
Sumbu Murah yang Salah: Histori yang Lebih Pendek Adalah Jebakan
Ada satu fidelity murah yang menggoda, jelas, dan bias, dan layak disebutkan namanya secara eksplisit karena semua orang meraihnya terlebih dahulu: histori yang lebih pendek. Saring konfigurasi pada bulan terakhir, promosikan para penyintas ke dua tahun penuh. Ini murah secara trivial dan terasa seperti gagasan yang sama dengan fold yang lebih sedikit. Padahal bukan.
Fold yang lebih sedikit dan histori yang lebih pendek berbeda dalam satu hal yang menentukan. Fidelity berbasis jumlah-fold, jika dilakukan dengan benar, tetap mencakup seluruh kalender — ia hanya mengambil sampel secara lebih kasar. Fidelity berbasis histori-lebih-pendek mengambil sampel dari satu sub-interval kalender secara padat. Dan sub-interval dari histori pasar adalah sebuah rezim yang spesifik. Ketika Anda mengurutkan peringkat konfigurasi pada bulan terakhir, Anda tidak mendapatkan estimasi yang noisy-tapi-tak-bias dari peringkat mereka pada periode penuh; Anda mendapatkan estimasi yang bias yang secara sistematis menguntungkan konfigurasi yang di-tuning untuk rezim bulan lalu. Naikkan ukuran sampel sebanyak apa pun yang Anda mau — rata-ratakan lebih banyak konfigurasi, lebih banyak trial — dan biasnya tidak akan mengecil, karena itu bukan varians. Anda akan mempromosikan konfigurasi yang paling cocok dengan jendela penyaringan, dan itu justru konfigurasi yang paling mungkin overfit terhadap rezim yang sementara.
Inilah mengapa fidelity kami menelusuri fold dalam urutan interleaved (berselang-seling), bukan secara kronologis. Dengan K fold tersebar di seluruh histori, "1 fold" adalah satu irisan dekat bagian tengah, "2 fold" adalah satu irisan awal dan satu irisan akhir, "3 fold" tersebar di awal/tengah/akhir — setiap level fidelity, bahkan yang termurah sekalipun, mengambil sampel dari seluruh kalender. Proxy murah adalah pandangan kasar dari seluruh periode, bukan pandangan tajam dari satu irisannya saja. Interleaving itulah yang membuat fidelity berbasis jumlah-fold hanya sekadar noisy (bisa disembuhkan oleh gate), bukan bias (yang tidak bisa diperbaiki oleh gate mana pun — ρ yang tinggi terhadap target yang bias hanya memastikan bahwa Anda akan secara konsisten memilih konfigurasi yang cocok-dengan-rezim). Jika satu-satunya cara Anda membuat fidelity lebih murah adalah dengan membuatnya lebih baru, Anda tidak memiliki fidelity yang valid. Buatlah lebih kasar sebagai gantinya.
Resolusi sebagai Sumbu Murah yang Jujur
Sumbu murah lainnya menghindari bias itu sepenuhnya, dan ia adalah pasangan alami dari drill-down adaptif yang kami jelaskan untuk simulasi fill: resolusi candle. Saring seluruh ruang pada bar 1 jam, promosikan para penyintas ke 1 menit, dan drill down ke 1 detik atau raw trade hanya untuk segelintir finalis. Candle yang lebih kasar pada histori penuh yang sama lebih murah untuk dievaluasi — lebih sedikit bar, lintasan indikator lebih cepat, simulasi lebih cepat — dan, tidak seperti jendela yang lebih pendek, pandangan kasar dari seluruh kalender itu tidak bias: ia melihat setiap rezim, hanya dengan detail intrabar yang lebih sedikit.
Resolusi dan fold adalah sumbu fidelity yang saling melengkapi, dan fidelity gate berlaku untuk keduanya. Sebelum Anda mempercayai penyaringan 1-jam, jalankan probe yang sama: ambil ~200 konfigurasi, beri skor pada mereka di 1 jam dan di 1 menit, dan ukur korelasi peringkatnya. Jika ρ(1j, 1m) tinggi, penyaringan pada resolusi jam itu aman dan Anda telah membeli percepatan besar secara jujur. Jika rendah — yang terjadi ketika edge strategi tersebut hidup dalam struktur intrabar yang dihaluskan hilang oleh candle per jam — maka penyaringan per jam adalah filter acak untuk strategi tersebut, dan gate memberi tahu Anda untuk mulai dengan yang lebih halus. Aturannya tidak pernah berubah: Anda hanya diizinkan melakukan pruning pada suatu fidelity setelah Anda mengukur bahwa peringkatnya sesuai dengan kebenaran.
Kedua sumbu ini juga gagal dengan cara yang berlawanan, dan itu berguna. Resolusi yang kasar kehilangan informasi intrabar; fold yang lebih sedikit kehilangan informasi lintas-rezim. Strategi momentum pada horizon harian mungkin mengurutkan peringkat dengan sempurna pada candle per jam tetapi butuh banyak fold untuk merata-ratakan keberuntungan rezim; strategi scalping mungkin baik-baik saja pada sedikit fold tetapi berantakan di atas resolusi 1 detik. Gate, dijalankan per-sumbu, memberi tahu Anda pada fidelity mana Anda mampu berhemat untuk strategi ini — alih-alih mengasumsikan jawaban yang kebetulan nyaman.
Dari Mana Penghematan Itu Sebenarnya Berasal
Satu catatan penting yang menjaga drill-down tetap jujur: fidelity hanya menghemat komputasi di tempat biaya itu sebenarnya berada. Pada engine multi-timeframe kami, bagian yang mahal adalah precomputing indikator — sinyal HMA multi-timeframe dan sinyal separation — yang dibayar sekali per konfigurasi, sebelum fold mana pun dijalankan. Simulasi per-fold pada sinyal yang sudah di-cache relatif murah. Jadi pruning berdasarkan jumlah fold hanya menghemat biaya simulasi, bukan biaya indikator yang mendominasi; fidelity berbasis jumlah-fold itu nyata, tetapi plafonnya lebih rendah dari yang disarankan oleh rasio fold mentah.
Sumbu resolusi, sebaliknya, menyerang biaya yang dominan secara langsung: candle yang lebih kasar berarti lebih sedikit bar untuk menghitung indikator di atasnya, sehingga baik precompute yang mahal maupun simulasi yang murah mengecil bersama-sama. Ini bukan detail sepele — ini menentukan drill-down mana yang layak dibangun. Sebelum Anda berinvestasi dalam pencarian multi-fidelitas, tanyakan ke mana perginya detik-detik komputasi Anda. Jika 90%-nya adalah precompute indikator yang dibagi bersama di seluruh fold, fidelity berbasis jumlah-fold hanya memberi Anda sedikit keuntungan, sementara fidelity resolusi memberi Anda banyak. Lakukan profiling terlebih dahulu; sumbu murah yang tepat adalah yang menghilangkan biaya yang benar-benar Anda miliki, dan ia tetap harus melewati gate.
Di Mana Ini Terhubung
Fidelity gate menempati posisi tertentu dalam rantai higiene backtest seri ini:
- Ini berada di hulu dari kendali overfitting. Drill-down yang melakukan pruning berdasarkan proxy yang buruk adalah cara baru untuk overfit — Anda membiarkan rung awal yang noisy memilih para finalis Anda. Sang juara tetap harus bertahan dari Deflated Sharpe dan PBO, dan jumlah trial yang memasok gate-gate itu harus mencakup setiap trial yang di-pruning, bukan hanya para penyintas — pruning tidak membuat sebuah trial bebas dari buku besar multiple-testing.
- Ini berbagi musuh yang sama dengan plateau analysis: sebuah konfigurasi yang menang pada satu fold atau satu jendela penyaringan dan tidak di tempat lain adalah artefak cocok-dengan-rezim yang sama, yang keduanya dirancang untuk ditolak. Gate menolak untuk memilih berdasarkan fold semacam itu; plateau analysis menolak untuk mempercayai juara yang hanya bertumpu pada satu fold.
- Ini mengasumsikan walk-forward split yang jujur di baliknya — fold yang mencakup seluruh kalender, out-of-sample disisihkan — dan ini adalah pelengkap di waktu-pencarian untuk drill-down yang kami bangun untuk simulasi fill: prinsip coarse-to-fine yang sama, diterapkan pada konfigurasi mana yang dievaluasi alih-alih seberapa presisi mengisi mereka.
- Dan ini bergantung sepenuhnya pada fidelity yang bebas-kebocoran pada setiap rung. Jika rung murah memiliki bias look-ahead yang tidak dimiliki rung yang mahal, ρ mengukur kesepakatan dengan target yang terkontaminasi dan gate justru mengesahkan sebuah kebocoran. Ukurlah korelasi peringkat, ya — tetapi pada objektif yang jujur.
Gagasan pemersatunya, sekali lagi, adalah yang terus-menerus diulang seri ini: sebuah backtest adalah eksperimen statistik, dan setiap jalan pintas di dalamnya adalah hipotesis yang wajib Anda uji. Hipotesis dari drill-down adalah "peringkat murah ≈ peringkat mahal." Ini bisa diuji dalam ~200 konfigurasi. Ujilah.
Kesimpulan Utama
- Pencarian coarse-to-fine bertumpu pada satu asumsi: proxy murah mengurutkan konfigurasi seperti yang mahal. Bukan nilai yang sama — peringkat yang sama. Jika korelasi peringkat rendah, pruning yang agresif membuang pemenang masa depan Anda dan mempromosikan noise. Anda mencari lebih cepat menuju jawaban yang lebih buruk.
- Ukur sebelum Anda mempercayainya. Ambil ~200 konfigurasi acak, beri skor pada setiap rung fidelity, dan hitung Spearman ρ antara setiap rung murah dan peringkat fidelity-penuh. Ini hanya beberapa lusin baris kode dan satu probe yang murah.
- Satu fold mengurutkan hampir secara acak. Kami mengukur ρ@1 mulai dari 0.03 (lempar koin) hingga 0.43 (masih di bawah ambang kepercayaan) tergantung rezimnya; ia naik menjadi 0.67, 0.78, 0.82, dan 0.91 seiring bertambahnya fold. Default
min_resource = 1dari setiap ASHA siap pakai, untuk sebuah backtest, biasanya salah. - Naikkan otomatis fidelity minimum ke rung pertama di mana ρ ≥ 0.5, dan jika tidak ada yang lolos, jangan lakukan pruning sama sekali. Gate berubah menjadi
min_resource = 2untuk satu setup dan3untuk yang lebih sulit; fallback-nya berdegradasi secara elegan menjadi pencarian fidelity-penuh. Kebenaran memakan biaya sebagian percepatan — bayarlah itu. - Pilih sumbu murah berdasarkan apakah ia bias, bukan berdasarkan apakah ia murah. Histori yang lebih pendek itu bias — ia memilih parameter yang cocok-dengan-rezim dan tidak ada ukuran sampel yang bisa memperbaiki itu. Gunakan fold yang lebih sedikit yang mencakup seluruh kalender (interleaved, bukan berurutan) atau resolusi yang lebih kasar pada seluruh periode. Dan keluarkan sumbu murah di tempat biaya Anda sebenarnya berada.
Drill-down adalah salah satu percepatan terbaik dalam backtesting, dan salah satu yang paling mudah berubah menjadi cara yang lebih cepat untuk membohongi diri sendiri. Perbedaan antara keduanya adalah satu angka yang bisa Anda ukur sebelum pencarian dimulai. Jika proxy Anda tidak bisa membuktikan bahwa ia mengurutkan seperti kebenarannya, itu bukan proxy — itu adalah generator angka acak dengan profil biaya yang masuk akal.
Penulis
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.