Validasi Multi-Simbol: Uji Strategi Anda pada Semua Pasangan
Artikel dari seri "Backtest Tanpa Ilusi"
Anda mengoptimalkan strategi pada ETHUSDT. 25 bulan data, 12+ parameter. Backtest menunjukkan PnL +55%, 500 transaksi, MaxDD -0,9%, posisi terbuka 15% dari waktu. Kurva ekuitas naik dengan mulus. Parameter lolos analisis plateau — optimum terlihat lebar. Walk-forward menghasilkan WFER > 0,6. Bootstrap Monte Carlo menunjukkan persentil ke-5 yang positif.
Semuanya sempurna. Kecuali satu hal: Anda menguji strategi pada satu instrumen saja.
Anda menjalankan algoritma yang sama dengan parameter yang sama pada BTCUSDT — PnL +8%. Pada SOLUSDT — PnL -12%. Pada DOGEUSDT — PnL -34%. Strategi yang lolos semua pengujian pada ETH ternyata tidak menguntungkan pada sebagian besar pasangan lainnya.
Ini bukan bug. Ini adalah jebakan simbol tunggal — salah satu bentuk overfitting paling umum dan berbahaya dalam algotrading.
Jebakan Instrumen Tunggal

Mengoptimalkan strategi pada satu simbol pada dasarnya adalah menyesuaikan strategi tersebut dengan dinamika harga aset tertentu. Meskipun Anda menjalankan walk-forward, meskipun bootstrap menunjukkan interval kepercayaan yang lebar — semua pemeriksaan ini dilakukan dalam satu deret waktu.
Walk-forward memeriksa ketangguhan sepanjang waktu: apakah parameter bekerja pada data masa depan dari instrumen yang sama. Monte Carlo memeriksa ketangguhan sepanjang urutan perdagangan: dapatkah strategi bertahan dengan urutan yang berbeda. Namun tidak satu pun dari metode ini memeriksa ketangguhan sepanjang instrumen: apakah strategi bekerja pada aset lain dengan karakteristik yang berbeda.
Jika strategi menguntungkan hanya pada ETHUSDT — strategi tersebut menangkap bukan inefisiensi pasar, melainkan struktur spesifik dari deret harga ETH:
- Pola kandil khas yang unik untuk ETH
- Level volatilitas spesifik yang menjadi acuan threshold
- Kekhasan likuiditas dan mikrostruktur dari pasangan ini
- Korelasi dengan BTC, khas dari periode tertentu
Semua ini bukan edge. Ini adalah curve fitting pada level instrumen.
Kelompok Simbol (Tier) di Pasar Kripto

Tidak semua mata uang kripto setara. Untuk validasi multi-simbol yang bermakna, Anda perlu memahami bahwa instrumen dibagi menjadi kelompok-kelompok dengan karakteristik yang berbeda secara fundamental.
Tier 1: Blue Chips (BTC, ETH)
Likuiditas tinggi, volatilitas relatif rendah, aliran institusional. Korelasi dengan makro (S&P 500, DXY, suku bunga Fed). Buku pesanan yang dalam, spread ketat, suku pendanaan yang stabil. Volatilitas harian tipikal: 2-4%.
Tier 2: Large Caps (SOL, BNB, ADA, XRP, AVAX)
Likuiditas sedang, volatilitas tinggi. Pergerakan sering didorong oleh dinamika sektor (L1 vs L2, DeFi vs infra). Suku pendanaan lebih volatil. Spread lebih lebar. Volatilitas harian tipikal: 4-6%.
Tier 3: Mid Caps (DOGE, SHIB, PEPE, ARB, OP)
Meme coin dan token narasi. Volatilitas tinggi, korelasi rendah dengan faktor fundamental. Pergerakan ditentukan oleh media sosial, listing, narasi. Buku pesanan tipis di beberapa bursa. Volatilitas harian tipikal: 6-10%.
Tier 4: Low Caps (Listing Baru)
Volatilitas ekstrem, buku pesanan tipis, risiko manipulasi. Seringkali sejarah tidak cukup untuk backtest penuh. Volatilitas harian tipikal: 10-20%+.
Tabel Ringkasan Karakteristik
| Karakteristik | Tier 1 | Tier 2 | Tier 3 | Tier 4 |
|---|---|---|---|---|
| Volatilitas harian | 2-4% | 4-6% | 6-10% | 10-20%+ |
| Spread rata-rata (perp) | 0,01-0,02% | 0,02-0,05% | 0,05-0,15% | 0,1-0,5%+ |
| Kedalaman buku pesanan (top 5 bps) | $5-50M | $1-10M | $100K-2M | $10K-200K |
| Suku pendanaan (rata-rata abs) | 0,005-0,01% | 0,01-0,03% | 0,02-0,08% | 0,05-0,2%+ |
| Korelasi dengan BTC | 0,85-0,95 | 0,6-0,85 | 0,3-0,7 | 0,1-0,5 |
| Riwayat minimum | 5+ tahun | 2-5 tahun | 6 bln - 3 tahun | < 6 bln |
Setiap tier adalah "dunia" tersendiri dengan mikrostrukturnya sendiri. Strategi yang disetel untuk Tier 1 memasuki lingkungan asing ketika berpindah ke Tier 3.
Metodologi Validasi Multi-Simbol

Langkah 1: Optimalkan pada Satu Simbol
Pilih simbol untuk optimasi — misalnya, ETHUSDT. Jalankan pipeline lengkap: optimasi Optuna, analisis plateau, walk-forward. Tetapkan parameternya.
Langkah 2: Uji pada Simbol dari Tier yang Sama
Jalankan strategi dengan parameter yang sama pada 5-10 simbol dari tier yang sama. Untuk Tier 1 ini terbatas (BTC + ETH), tetapi untuk Tier 2 dan Tier 3 ada cukup banyak simbol.
Langkah 3: Uji pada Simbol dari Tier Lain
Jalankan strategi pada 3-5 simbol dari setiap tier lainnya. Ini adalah ujian terberat: jika strategi bekerja pada ETHUSDT (Tier 1) dan pada DOGEUSDT (Tier 3), probabilitas curve fitting sangat minimal.
Langkah 4: Analisis Hasil per Kelompok
Agregasikan metrik berdasarkan tier dan nilai ketangguhan lintas-simbol.
Metrik untuk Setiap Simbol
Untuk setiap simbol, catat:
- PnL — total imbal hasil
- MaxDD — drawdown maksimum
- N trades — jumlah transaksi
- Win rate — fraksi transaksi menguntungkan
- PnL/active day — imbal hasil per satuan waktu aktif (lebih detail di PnL berdasarkan waktu aktif)
Kriteria Kelulusan
Strategi lulus validasi multi-simbol jika:
- Menguntungkan pada >= 60% simbol di tier yang sama
- Rata-rata PnL di seluruh kelompok positif
- MaxDD tidak meningkat secara dramatis (tidak lebih dari 2-3x relatif terhadap simbol optimasi)
- Jika strategi hanya menguntungkan pada simbol optimasi — tolak
Contoh: Tiga Strategi, Tiga Hasil

Mari kita pertimbangkan contoh konkret. Tiga strategi (Strategi A, Strategi B, Strategi C), dioptimalkan pada ETHUSDT, diuji pada 12 simbol di empat tier.
Strategi A (Dioptimalkan pada ETHUSDT)
Parameter: PnL +55%, ~500 transaksi, ~15% waktu aktif, MaxDD ~0,9%.
| Simbol | Tier | PnL | MaxDD | N trades | Win rate | PnL/hari aktif |
|---|---|---|---|---|---|---|
| ETHUSDT* | 1 | +55,2% | -0,9% | 491 | 52,1% | 0,48% |
| BTCUSDT | 1 | +31,4% | -1,8% | 478 | 50,8% | 0,27% |
| SOLUSDT | 2 | +22,7% | -3,1% | 512 | 49,2% | 0,18% |
| BNBUSDT | 2 | +18,3% | -2,7% | 467 | 48,9% | 0,16% |
| AVAXUSDT | 2 | +8,1% | -4,5% | 498 | 47,6% | 0,07% |
| ADAUSDT | 2 | -3,2% | -6,1% | 445 | 46,1% | -0,03% |
| DOGEUSDT | 3 | -12,8% | -9,4% | 531 | 44,3% | -0,10% |
| SHIBUSDT | 3 | -18,7% | -12,1% | 487 | 43,1% | -0,16% |
| PEPEUSDT | 3 | -24,3% | -14,8% | 556 | 42,7% | -0,18% |
| ARBUSDT | 3 | -7,4% | -7,2% | 419 | 45,8% | -0,07% |
| OPUSDT | 3 | -5,1% | -6,8% | 402 | 46,2% | -0,05% |
* — simbol optimasi
Hasil per tier:
| Tier | Simbol | Menguntungkan | Rata-rata PnL | Rata-rata MaxDD |
|---|---|---|---|---|
| Tier 1 | 2 | 2 (100%) | +43,3% | -1,4% |
| Tier 2 | 4 | 3 (75%) | +11,5% | -4,1% |
| Tier 3 | 5 | 0 (0%) | -13,7% | -10,1% |
Kesimpulan: Strategi A bekerja pada Tier 1-2 tetapi sama sekali gagal pada Tier 3. Ini adalah strategi tipikal yang disetel untuk lingkungan volatilitas rendah. Untuk portofolio blue chips dan large caps — dapat diterima. Untuk penggunaan universal — tidak.
Strategi B (Dioptimalkan pada ETHUSDT)
Parameter: PnL +25%, ~40 transaksi, ~5% waktu aktif.
| Simbol | Tier | PnL | MaxDD | N trades | Win rate |
|---|---|---|---|---|---|
| ETHUSDT* | 1 | +25,1% | -2,3% | 38 | 57,9% |
| BTCUSDT | 1 | +21,8% | -2,8% | 41 | 56,1% |
| SOLUSDT | 2 | +19,4% | -3,5% | 44 | 54,5% |
| BNBUSDT | 2 | +16,7% | -3,1% | 37 | 54,1% |
| AVAXUSDT | 2 | +12,3% | -4,2% | 42 | 52,4% |
| ADAUSDT | 2 | +8,9% | -4,8% | 39 | 51,3% |
| DOGEUSDT | 3 | +4,2% | -6,7% | 48 | 47,9% |
| SHIBUSDT | 3 | -1,3% | -8,4% | 45 | 46,7% |
| PEPEUSDT | 3 | -3,8% | -9,1% | 52 | 46,2% |
| ARBUSDT | 3 | +6,1% | -5,8% | 40 | 50,0% |
| OPUSDT | 3 | +3,7% | -6,2% | 38 | 50,0% |
Hasil per tier:
| Tier | Simbol | Menguntungkan | Rata-rata PnL | Rata-rata MaxDD |
|---|---|---|---|---|
| Tier 1 | 2 | 2 (100%) | +23,5% | -2,6% |
| Tier 2 | 4 | 4 (100%) | +14,3% | -3,9% |
| Tier 3 | 5 | 3 (60%) | +1,8% | -7,2% |
Kesimpulan: Strategi B menguntungkan pada 9 dari 11 simbol (82%). Rata-rata PnL positif di semua tier. MaxDD tumbuh secara dapat diprediksi seiring tier. Ini adalah strategi yang tangguh dengan edge pasar yang nyata. Meskipun PnL pada simbol optimasi lebih sederhana (+25% vs +55%), Strategi B jauh lebih andal daripada Strategi A.
Strategi C (Dioptimalkan pada ETHUSDT)
Parameter: PnL +300%, ~400 transaksi, ~45% waktu aktif, MaxDD ~17%.
| Simbol | Tier | PnL | MaxDD | N trades | Win rate |
|---|---|---|---|---|---|
| ETHUSDT* | 1 | +301,2% | -17,1% | 418 | 53,8% |
| BTCUSDT | 1 | +42,7% | -28,4% | 395 | 48,6% |
| SOLUSDT | 2 | -18,3% | -41,2% | 456 | 44,1% |
| BNBUSDT | 2 | +12,1% | -33,7% | 387 | 46,8% |
| AVAXUSDT | 2 | -31,4% | -52,8% | 471 | 42,3% |
| ADAUSDT | 2 | -44,7% | -58,1% | 412 | 40,5% |
| DOGEUSDT | 3 | -67,2% | -74,3% | 528 | 38,1% |
| PEPEUSDT | 3 | -72,1% | -81,6% | 574 | 37,4% |
Kesimpulan: Strategi C adalah overfitting klasik. +301% pada ETHUSDT, tetapi kerugian besar pada sebagian besar pasangan lainnya. MaxDD pada Tier 3 melebihi 70% — ini adalah kehancuran modal. Strategi tersebut menangkap pola unik ETH, bukan inefisiensi pasar. Tolak.
Mengapa Strategi Gagal pada Simbol Lain

1. Ketidakcocokan Volatilitas
Alasan paling umum. Parameter strategi disetel ke level volatilitas tertentu. Jika strategi menggunakan threshold masuk 2% — untuk ETH dengan volatilitas harian 3%, ini adalah filter yang wajar. Untuk DOGE dengan volatilitas harian 8% — threshold ini terpicu terlalu sering, menghasilkan banyak sinyal palsu.
Demikian pula, stop loss 1% memadai untuk ETH, tetapi untuk PEPE itu adalah "noise" normal, dan stop terkena puluhan kali sehari.
2. Perbedaan Likuiditas
Strategi mengasumsikan eksekusi pesanan instan pada harga saat ini. Pada BTCUSDT dengan kedalaman buku pesanan 200K — pesanan $10K Anda akan menggerakkan harga, dan eksekusi aktual akan lebih buruk sebesar 0,05-0,2%. Dalam 500 transaksi, itu 25-100% yang hilang karena slippage saja.
3. Mikrostruktur Pasar
Setiap instrumen memiliki mikrostrukturnya sendiri:
- Suku pendanaan: pada BTC, pendanaan konsisten positif dalam bull market (+0,01% setiap 8 jam). Pada meme coin, pendanaan bisa melompat dari -0,3% ke +0,5%. Detail lebih lanjut — di Suku pendanaan membunuh leverage Anda.
- Spread: pada Tier 1 spreadnya 0,01%, pada Tier 4 — 0,5%. Strategi dengan take-profit kecil tidak bisa menguntungkan ketika spread melebihi ukuran take.
- Pola manipulasi: wick, spoofing, wash trading — bermanifestasi secara berbeda di setiap tier.
4. Sensitivitas Rezim
Altcoin berperilaku berbeda dalam fase pasar yang berbeda:
- Dalam tren bull, altcoin mengungguli BTC (beta > 1)
- Dalam tren bear, altcoin jatuh lebih dalam daripada BTC
- Dalam pasar sideways, altcoin dapat berkorelasi dengan BTC atau bergerak berdasarkan narasi mereka sendiri
Strategi yang dioptimalkan dalam satu fase pada satu simbol mungkin disetel secara optimal terhadap lag/lead khusus dari simbol tersebut relatif terhadap BTC — dan lag/lead ini akan berubah ketika rezim berganti.
Penskalaan Parameter Adaptif

Menjalankan strategi dengan parameter identik pada semua simbol adalah salah. Tetapi re-optimasi penuh pada setiap simbol mengalahkan tujuan validasi multi-simbol itu sendiri (parameter menjadi "asli" untuk setiap simbol).
Komprominya adalah normalisasi parameter berdasarkan volatilitas:
import numpy as np
def scale_params_by_volatility(
base_params: dict,
optimization_symbol_vol: float,
target_symbol_vol: float,
vol_sensitive_params: list[str],
) -> dict:
"""
Scale strategy parameters by target symbol volatility.
Args:
base_params: parameters optimized on the original symbol
optimization_symbol_vol: daily volatility of the optimization symbol
target_symbol_vol: daily volatility of the target symbol
vol_sensitive_params: list of volatility-sensitive parameters
"""
vol_ratio = target_symbol_vol / optimization_symbol_vol
adjusted = base_params.copy()
for param in vol_sensitive_params:
if param in adjusted:
adjusted[param] = adjusted[param] * vol_ratio
return adjusted
base_params = {
"entry_threshold": 0.02, # 2% — entry threshold
"stop_loss": 0.01, # 1% — stop loss
"take_profit": 0.03, # 3% — take profit
"trailing_stop": 0.008, # 0.8% — trailing stop
"atr_multiplier": 2.5, # ATR multiplier (not scaled)
"rsi_period": 14, # RSI period (not scaled)
"ma_fast": 10, # fast MA (not scaled)
"ma_slow": 50, # slow MA (not scaled)
}
vol_sensitive = ["entry_threshold", "stop_loss", "take_profit", "trailing_stop"]
eth_vol = 0.032 # 3.2%
doge_vol = 0.081 # 8.1%
doge_params = scale_params_by_volatility(
base_params, eth_vol, doge_vol, vol_sensitive
)
print("ETH params:", {k: f"{v:.4f}" for k, v in base_params.items() if k in vol_sensitive})
print("DOGE params:", {k: f"{v:.4f}" for k, v in doge_params.items() if k in vol_sensitive})
Output:
ETH params: {'entry_threshold': '0.0200', 'stop_loss': '0.0100', 'take_profit': '0.0300', 'trailing_stop': '0.0080'}
DOGE params: {'entry_threshold': '0.0506', 'stop_loss': '0.0253', 'take_profit': '0.0759', 'trailing_stop': '0.0203'}
Stop loss meningkat dari 1% menjadi 2,53% — sesuai untuk volatilitas harian DOGE sebesar 8,1%. Tanpa penskalaan, stop 1% akan terkena "noise" puluhan kali.
Penting: skalakan hanya threshold harga (masuk, stop, take). Periode indikator (RSI, MA) dan pengali (ATR multiplier) biasanya tidak diskalakan — sudah dinormalisasi berdasarkan volatilitas melalui indikator itu sendiri.
Dua Mode Validasi
-
Mode ketat (tanpa penskalaan): jalankan dengan parameter identik. Uji ketangguhan absolut. Jika strategi menguntungkan — edge-nya kuat.
-
Mode adaptif (dengan penskalaan): jalankan dengan parameter yang dinormalisasi. Uji ketangguhan logika strategi, dengan kelonggaran bahwa level volatilitas berbeda.
Kami merekomendasikan menjalankan kedua pengujian. Mode ketat — untuk menilai "kekuatan" edge. Mode adaptif — untuk aplikasi praktis.
Skor Ketangguhan Lintas-Simbol

Untuk penilaian kuantitatif ketangguhan multi-simbol, kami memperkenalkan metrik komposit — Cross-Symbol Robustness Score (CSRS).
Formula
di mana:
- — fraksi simbol yang menguntungkan:
- — rata-rata PnL tertimbang likuiditas yang dinormalisasi:
di mana adalah likuiditas simbol (volume harian rata-rata).
- — bonus untuk konsistensi lintas-tier:
- — penalti untuk varians PnL tinggi antara simbol:
Bobot Default
| Komponen | Bobot | Alasan |
|---|---|---|
| (fraksi menguntungkan) | 0,35 | Paling penting: strategi harus bekerja pada mayoritas |
| (rata-rata PnL) | 0,25 | Imbal hasil absolut |
| (lintas-tier) | 0,25 | Bonus untuk universalitas |
| (penalti varians) | 0,15 | Penalti untuk ketidakstabilan |
Interpretasi CSRS
| CSRS | Interpretasi |
|---|---|
| > 0,7 | Ketangguhan sangat baik. Strategi bekerja pada sebagian besar instrumen. |
| 0,5 — 0,7 | Ketangguhan baik. Strategi bekerja di tiernya dan sebagian di tier lain. |
| 0,3 — 0,5 | Batas. Strategi bekerja pada sekumpulan simbol yang sempit. |
| < 0,3 | Ketangguhan rendah. Curve fitting pada level instrumen kemungkinan terjadi. |
Implementasi Penuh: Pipeline Validasi Multi-Simbol

import numpy as np
import pandas as pd
from dataclasses import dataclass, field
from typing import Callable, Optional
@dataclass
class SymbolResult:
"""Strategy result on a single symbol."""
symbol: str
tier: int
pnl: float
max_dd: float
n_trades: int
win_rate: float
pnl_per_active_day: float
avg_daily_volume: float # liquidity
@dataclass
class TierResult:
"""Aggregated result by tier."""
tier: int
symbols: list[SymbolResult]
n_symbols: int
n_profitable: int
profit_ratio: float
avg_pnl: float
avg_max_dd: float
pnl_std: float
@dataclass
class MultiSymbolResult:
"""Full multi-symbol validation result."""
symbol_results: list[SymbolResult]
tier_results: list[TierResult]
csrs: float
passed: bool
optimization_symbol: str
report: str
SYMBOL_TIERS = {
1: ["BTCUSDT", "ETHUSDT"],
2: ["SOLUSDT", "BNBUSDT", "ADAUSDT", "XRPUSDT", "AVAXUSDT"],
3: ["DOGEUSDT", "SHIBUSDT", "PEPEUSDT", "ARBUSDT", "OPUSDT"],
}
SYMBOL_VOLATILITY = {
"BTCUSDT": 0.028, "ETHUSDT": 0.032,
"SOLUSDT": 0.052, "BNBUSDT": 0.038, "ADAUSDT": 0.048,
"XRPUSDT": 0.045, "AVAXUSDT": 0.055,
"DOGEUSDT": 0.081, "SHIBUSDT": 0.092, "PEPEUSDT": 0.105,
"ARBUSDT": 0.068, "OPUSDT": 0.063,
}
SYMBOL_VOLUME = {
"BTCUSDT": 15e9, "ETHUSDT": 8e9,
"SOLUSDT": 2e9, "BNBUSDT": 1.5e9, "ADAUSDT": 800e6,
"XRPUSDT": 1.2e9, "AVAXUSDT": 500e6,
"DOGEUSDT": 1e9, "SHIBUSDT": 400e6, "PEPEUSDT": 600e6,
"ARBUSDT": 300e6, "OPUSDT": 250e6,
}
def run_multi_symbol_validation(
strategy_fn: Callable,
base_params: dict,
optimization_symbol: str,
data_loader: Callable,
vol_sensitive_params: list[str],
adaptive: bool = True,
csrs_weights: tuple = (0.35, 0.25, 0.25, 0.15),
min_profit_ratio: float = 0.6,
) -> MultiSymbolResult:
"""
Full multi-symbol validation pipeline.
Args:
strategy_fn: strategy function (data, params) -> (pnl, max_dd, n_trades, win_rate, returns)
base_params: parameters optimized on optimization_symbol
optimization_symbol: optimization symbol
data_loader: data loading function (symbol) -> np.ndarray
vol_sensitive_params: parameters to scale by volatility
adaptive: use volatility scaling
csrs_weights: weights (w1, w2, w3, w4) for CSRS
min_profit_ratio: minimum fraction of profitable symbols in a tier
"""
w1, w2, w3, w4 = csrs_weights
opt_vol = SYMBOL_VOLATILITY.get(optimization_symbol, 0.03)
symbol_results = []
for tier, symbols in SYMBOL_TIERS.items():
for symbol in symbols:
data = data_loader(symbol)
if data is None or len(data) < 100:
continue
if adaptive and symbol != optimization_symbol:
sym_vol = SYMBOL_VOLATILITY.get(symbol, 0.05)
params = scale_params_by_volatility(
base_params, opt_vol, sym_vol, vol_sensitive_params
)
else:
params = base_params.copy()
pnl, max_dd, n_trades, win_rate, returns = strategy_fn(data, params)
active_days = max(n_trades * 0.5, 1) # rough estimate
pnl_per_day = pnl / active_days
symbol_results.append(SymbolResult(
symbol=symbol,
tier=tier,
pnl=pnl,
max_dd=max_dd,
n_trades=n_trades,
win_rate=win_rate,
pnl_per_active_day=pnl_per_day,
avg_daily_volume=SYMBOL_VOLUME.get(symbol, 1e6),
))
tier_results = []
tiers_present = sorted(set(r.tier for r in symbol_results))
for tier in tiers_present:
tier_symbols = [r for r in symbol_results if r.tier == tier]
n_profitable = sum(1 for r in tier_symbols if r.pnl > 0)
pnls = [r.pnl for r in tier_symbols]
tier_results.append(TierResult(
tier=tier,
symbols=tier_symbols,
n_symbols=len(tier_symbols),
n_profitable=n_profitable,
profit_ratio=n_profitable / len(tier_symbols) if tier_symbols else 0,
avg_pnl=np.mean(pnls),
avg_max_dd=np.mean([r.max_dd for r in tier_symbols]),
pnl_std=np.std(pnls),
))
all_pnls = [r.pnl for r in symbol_results]
all_volumes = [r.avg_daily_volume for r in symbol_results]
n_total = len(symbol_results)
n_profitable = sum(1 for r in symbol_results if r.pnl > 0)
r_profit = n_profitable / n_total if n_total > 0 else 0
total_vol = sum(all_volumes)
r_pnl_raw = sum(r.pnl * r.avg_daily_volume for r in symbol_results) / total_vol
r_pnl = 1 / (1 + np.exp(-r_pnl_raw * 5))
profitable_tiers = sum(1 for tr in tier_results if tr.avg_pnl > 0)
p_consistency = profitable_tiers / len(tier_results) if tier_results else 0
pnl_std = np.std(all_pnls) if len(all_pnls) > 1 else 0
pnl_mean = np.mean(all_pnls) if all_pnls else 0.01
p_variance = pnl_std / max(abs(pnl_mean), 0.01)
p_variance = min(p_variance, 5.0) # cap the penalty
csrs = w1 * r_profit + w2 * r_pnl + w3 * p_consistency - w4 * (p_variance / 5.0)
csrs = max(0, min(1, csrs)) # clamp to [0, 1]
opt_tier = None
for tier, symbols in SYMBOL_TIERS.items():
if optimization_symbol in symbols:
opt_tier = tier
break
same_tier_result = next((tr for tr in tier_results if tr.tier == opt_tier), None)
passed = (
csrs >= 0.5
and (same_tier_result is None or same_tier_result.profit_ratio >= min_profit_ratio)
and np.mean(all_pnls) > 0
)
report = _generate_report(
symbol_results, tier_results, csrs, passed,
optimization_symbol, adaptive
)
return MultiSymbolResult(
symbol_results=symbol_results,
tier_results=tier_results,
csrs=csrs,
passed=passed,
optimization_symbol=optimization_symbol,
report=report,
)
def _generate_report(
symbol_results, tier_results, csrs, passed,
opt_symbol, adaptive
) -> str:
"""Generate text report."""
lines = []
lines.append("=" * 60)
lines.append("MULTI-SYMBOL VALIDATION REPORT")
lines.append(f"Optimization symbol: {opt_symbol}")
lines.append(f"Mode: {'adaptive' if adaptive else 'strict'}")
lines.append(f"CSRS: {csrs:.3f}")
lines.append(f"Passed: {'YES' if passed else 'NO'}")
lines.append("=" * 60)
for tr in tier_results:
lines.append(f"\n--- Tier {tr.tier} ---")
lines.append(f" Symbols: {tr.n_symbols}, Profitable: {tr.n_profitable} "
f"({tr.profit_ratio:.0%})")
lines.append(f" Avg PnL: {tr.avg_pnl:.2%}, Avg MaxDD: {tr.avg_max_dd:.2%}")
lines.append(f" PnL StdDev: {tr.pnl_std:.2%}")
for sr in tr.symbols:
marker = "*" if sr.symbol == opt_symbol else " "
status = "+" if sr.pnl > 0 else "-"
lines.append(
f" {marker} [{status}] {sr.symbol:12s} "
f"PnL={sr.pnl:+.2%} MaxDD={sr.max_dd:.2%} "
f"Trades={sr.n_trades:4d} WR={sr.win_rate:.1%}"
)
lines.append("\n" + "=" * 60)
return "\n".join(lines)
Contoh Penggunaan Pipeline
def my_strategy(data, params):
"""Your strategy. Returns (pnl, max_dd, n_trades, win_rate, returns)."""
pass
def load_ohlcv(symbol):
"""Load OHLCV data for a symbol."""
pass
base_params = {
"entry_threshold": 0.02,
"stop_loss": 0.01,
"take_profit": 0.03,
"trailing_stop": 0.008,
"atr_multiplier": 2.5,
"rsi_period": 14,
"ma_fast": 10,
"ma_slow": 50,
}
result = run_multi_symbol_validation(
strategy_fn=my_strategy,
base_params=base_params,
optimization_symbol="ETHUSDT",
data_loader=load_ohlcv,
vol_sensitive_params=["entry_threshold", "stop_loss", "take_profit", "trailing_stop"],
adaptive=True,
)
print(result.report)
print(f"\nCSRS: {result.csrs:.3f}")
print(f"Passed: {result.passed}")
Kapan Validasi Simbol Tunggal Dapat Diterima

Tidak setiap strategi harus bekerja di berbagai instrumen. Ada kasus sah di mana simbol tunggal adalah pendekatan yang normal:
Market Making pada Buku Pesanan Tertentu
Strategi market-making (misalnya, menggunakan model Avellaneda-Stoikov) pada dasarnya terikat pada buku pesanan tertentu. Parameter bergantung pada mikrostruktur spesifik: kedalaman, spread, posisi antrian, tingkat pengisian. Pengujian pada simbol lain tidak ada artinya — itu adalah buku pesanan yang berbeda.
Arbitrase Antara Pasangan Tertentu
Arbitrase suku pendanaan atau arbitrase lintas-bursa pada dasarnya terikat pada pasangan instrumen tertentu. Validasi di sini dilakukan pada bursa lain dengan pasangan yang sama, bukan pada simbol yang berbeda.
Strategi yang Secara Eksplisit Menggunakan Properti Unik Aset
Jika strategi didasarkan pada properti spesifik dari satu aset (misalnya, korelasi BTC dengan hashrate atau korelasi ETH dengan biaya gas), validasi multi-simbol tidak berlaku. Tetapi strategi semacam itu jarang.
Dalam semua kasus lainnya — jika strategi didasarkan pada sinyal "generik" (MA crossover, RSI, momentum, mean reversion) — validasi multi-simbol wajib dilakukan. Jika strategi generik hanya bekerja pada satu simbol, itu bukan edge — itu overfitting.
Hubungan dengan Metode Validasi Lainnya

Validasi multi-simbol adalah salah satu dari tiga metode ortogonal pengujian out-of-sample:
| Metode | Sumbu Validasi | Yang Diungkapkan |
|---|---|---|
| Walk-Forward | Waktu | Overfitting pada periode tertentu |
| Multi-simbol | Instrumen | Overfitting pada aset tertentu |
| Bootstrap Monte Carlo | Urutan perdagangan | Ketergantungan pada urutan tertentu |
Setiap metode memeriksa ketangguhan sepanjang sumbunya sendiri. Strategi dapat lulus walk-forward tetapi gagal multi-simbol (curve fitted ke instrumen). Dapat lulus multi-simbol tetapi gagal Monte Carlo (bergantung pada urutan perdagangan yang beruntung).
Perlindungan overfitting maksimum: gunakan ketiga metode.
Pipeline validasi lengkap:
- Optimasi parameter pada satu simbol
- Analisis plateau — pemeriksaan stabilitas optimum
- Walk-forward — validasi sumbu waktu (WFER > 0,5)
- Multi-simbol — validasi sumbu instrumen (CSRS > 0,5)
- Bootstrap Monte Carlo — interval kepercayaan (persentil ke-5 > 0)
- Pertimbangkan suku pendanaan dan asimetri kerugian
Strategi yang lulus keenam pemeriksaan memiliki probabilitas minimal menjadi artefak overfitting.
Ekstensi: Korelasi Simbol dan Strategi Cascade

Validasi multi-simbol mengungkapkan aspek lain: korelasi antara simbol. Jika strategi menguntungkan pada BTC dan ETH tetapi tidak menguntungkan pada semua altcoin — ini adalah informasi bahwa edge terikat pada korelasi tinggi BTC-ETH. Analisis mendalam tentang struktur korelasi — dalam artikel Korelasi sinyal dan pairs trading.
Untuk portofolio strategi, hasil multi-simbol menentukan instrumen mana yang harus dijalankan strategi. Strategi A dari contoh di atas — hanya Tier 1-2. Strategi B — Tier 1-3. Ini adalah data masukan untuk orkestrasi cascade, di mana strategi berbeda dijalankan pada instrumen berbeda tergantung pada profil ketangguhan mereka.
Kesimpulan
Validasi multi-simbol bukan opsional — ini adalah langkah wajib untuk setiap strategi yang mengklaim edge pasar yang tergeneralisasi. Poin-poin utama:
-
Strategi yang hanya bekerja pada satu simbol kemungkinan besar adalah overfit terhadap kekhasan simbol tersebut. Pengecualian: market making, arbitrase, strategi berdasarkan properti unik aset.
-
Pengelompokan tier wajib dilakukan. Anda tidak dapat membandingkan hasil pada BTC (Tier 1) dengan hasil pada PEPE (Tier 3) tanpa memahami perbedaan volatilitas, likuiditas, dan mikrostruktur.
-
Penskalaan parameter adaptif — normalisasi threshold berdasarkan volatilitas — secara signifikan meningkatkan realisme pengujian multi-simbol.
-
CSRS > 0,5 — ambang minimum yang wajar. Strategi harus menguntungkan pada >= 60% simbol di tier yang sama, dan rata-rata PnL di semua simbol harus positif.
-
Walk-forward + Multi-simbol + Monte Carlo — tiga sumbu validasi ortogonal. Setiap metode menangkap apa yang terlewatkan oleh yang lain. Gunakan ketiganya.
Strategi dengan PnL +25% dan CSRS 0,72 lebih andal daripada strategi dengan PnL +300% dan CSRS 0,18. Yang pertama menghasilkan keuntungan dari inefisiensi pasar. Yang terakhir menghasilkan keuntungan dari menghafal satu deret harga.
Tautan Berguna
- Lopez de Prado, M. — Advances in Financial Machine Learning (Wiley)
- Pardo, R. — The Evaluation and Optimization of Trading Strategies (Wiley)
- Bailey, D.H. et al. — The Probability of Backtest Overfitting
- Aronson, D.R. — Evidence-Based Technical Analysis
- Kevin Davey — Building Winning Algorithmic Trading Systems (Wiley)
- Harvey, C.R. & Liu, Y. — Backtesting (2015)
- Chan, E. — Algorithmic Trading: Winning Strategies and Their Rationale (Wiley)
- Binance Research — Cryptocurrency Correlation Analysis
- NumPy — numpy.random.choice
- Pandas — DataFrame
Kutipan
@article{soloviov2026multisymbolvalidation,
author = {Soloviov, Eugen},
title = {Multi-Symbol Validation: Test Your Strategy on All Pairs},
year = {2026},
url = {https://marketmaker.cc/id/blog/post/multi-symbol-validation},
version = {0.1.0},
description = {Mengapa strategi yang dioptimalkan pada ETHUSDT bisa gagal di altcoin. Cara menguji yang benar di seluruh kelompok pasangan (blue chips, large caps, shitcoin) dan berapa skor ketangguhan lintas-simbol yang cukup.}
}
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.