Korelasi Sinyal: Berapa Banyak Pasangan yang Perlu Dipantau
Anda meluncurkan strategi pada 10 pasangan kripto: BTC/USDT, ETH/USDT, SOL/USDT, AVAX/USDT, dan enam altcoin lainnya. Logikanya tampak sempurna: jika strategi aktif 5% dari waktu pada satu pasangan, maka di seluruh 10 pasangan setidaknya satu harus aktif dari waktu. Peningkatan utilisasi empat kali lipat.
Dalam praktiknya, utilisasi ternyata hanya 15-16%, bukan 40%. 10 pasangan Anda berperilaku seperti 3. Modal menganggur, fill_efficiency turun, dan imbal hasil portofolio efektif akhirnya tiga kali lebih rendah dari proyeksi.
Penyebabnya adalah korelasi sinyal. Dan dalam kripto, korelasi ini sangat tinggi secara katastrofik.
Ilusi Diversifikasi dalam Kripto

Dalam keuangan tradisional, diversifikasi bekerja karena saham Apple dan ETF minyak bereaksi terhadap faktor yang berbeda. Di pasar mata uang kripto, semuanya berbeda.
BTC adalah faktor dominan. Ketika Bitcoin turun 5%, ETH turun 6-8%, SOL turun 8-12%, altcoin turun 10-20%. Korelasi imbal hasil harian di pasar kripto secara konsisten di atas 0,6, dan saat panik mendekati 1,0.
Namun bagi kita — trader algo — yang penting bukan korelasi harga, melainkan korelasi sinyal. Jika strategi didasarkan pada momentum dan BTC memicu sinyal masuk, ada kemungkinan besar bahwa ETH dan SOL akan memicu sinyal serupa di menit yang sama. Semua pasangan masuk long secara bersamaan, semua keluar secara bersamaan. Sepuluh posisi — tetapi pada dasarnya satu taruhan.
Mengapa 10 Pasangan ≠ Diversifikasi 10x

Pernyataan Formal
Misalkan sebuah strategi pada masing-masing dari pasangan aktif selama fraksi waktu. Jika sinyal sepenuhnya independen, probabilitas setidaknya satu pasangan aktif:
Untuk Strategi B (, ):
Namun sinyal tidak independen. Mata uang kripto bergerak serempak — artinya sinyal muncul dan padam dalam kelompok.
Korelasi Mengubah 10 Pasangan Menjadi 3
Intuisinya adalah ini: jika 10 pasangan berkorelasi, mereka membawa informasi bukan dari 10 sumber independen tetapi, katakanlah, 3-4. Kita memformalkan ini melalui effective_N:
di mana adalah faktor korelasi (correlation factor), yang mencerminkan rata-rata korelasi sinyal berpasangan. Ketika pasangan sepenuhnya independen; ketika mereka identik.
Untuk pasangan kripto, yang khas. Maka:
Bukan 40%, melainkan 15,6%. Selisih 2,5x. Efisiensi pengisian turun sesuai, dan bersamanya imbal hasil efektif seluruh portofolio (lihat PnL per Waktu Aktif).
Korelasi di Pasar Kripto

BTC sebagai Faktor Dominan
Pasar kripto memiliki struktur faktor yang jelas. BTC menjelaskan 60-80% varians imbal hasil harian untuk sebagian besar altcoin. Hal ini terlihat jelas melalui PCA (Principal Component Analysis):
import numpy as np
from sklearn.decomposition import PCA
def analyze_crypto_factor_structure(returns_matrix: np.ndarray, pair_names: list) -> dict:
"""
Analisis PCA dari struktur faktor imbal hasil kripto.
Args:
returns_matrix: matriks imbal hasil [n_hari x n_pasangan]
pair_names: daftar nama pasangan
"""
pca = PCA()
pca.fit(returns_matrix)
explained = pca.explained_variance_ratio_
cumulative = np.cumsum(explained)
print("Struktur faktor:")
for i, (var, cum) in enumerate(zip(explained[:5], cumulative[:5])):
print(f" PC{i+1}: {var:.1%} varians (kumulatif: {cum:.1%})")
loadings = pca.components_[0]
print("\nMuatan PC1 (faktor BTC):")
for name, load in sorted(zip(pair_names, loadings), key=lambda x: -abs(x[1])):
print(f" {name}: {load:.3f}")
return {
"explained_variance": explained,
"n_effective_factors": int(np.searchsorted(cumulative, 0.90)) + 1,
"pc1_loadings": dict(zip(pair_names, loadings)),
}
Hasil tipikal untuk portofolio 10 pasangan kripto:
| Komponen | Varians yang Dijelaskan | Kumulatif |
|---|---|---|
| PC1 (BTC) | 65% | 65% |
| PC2 | 12% | 77% |
| PC3 | 8% | 85% |
| PC4 | 5% | 90% |
| PC5-PC10 | 10% | 100% |
Empat faktor menjelaskan 90% varians. Dari 10 pasangan, tidak lebih dari 4 yang "independen."
Korelasi Sinyal vs. Korelasi Harga
Berikut adalah nuansa penting. Korelasi harga dan korelasi sinyal adalah hal yang berbeda. Harga BTC dan ETH berkorelasi pada 0,85, tetapi sinyal strategi tertentu mungkin berkorelasi pada 0,95 atau pada 0,50 — tergantung pada logika masuk.
Contoh: strategi overbought/oversold RSI. RSI pada BTC melintasi 30 (oversold) — masuk long. ETH pada saat yang sama mungkin juga oversold (korelasi sinyal ~0,90). Atau mungkin tidak, jika ETH turun lebih lambat (korelasi sinyal ~0,40).
Pendekatan yang benar adalah mengukur korelasi sinyal secara khusus, bukan seri harga:
import numpy as np
from itertools import combinations
def signal_correlation_matrix(
signals: dict, # {pasangan: np.array dari 0/1 per menit}
method: str = "pearson",
) -> np.ndarray:
"""
Hitung matriks korelasi sinyal (biner: 0 = flat, 1 = dalam posisi).
Args:
signals: kamus {nama_pasangan: array_sinyal_biner}
method: metode korelasi ("pearson", "jaccard")
"""
pairs = sorted(signals.keys())
n = len(pairs)
corr_matrix = np.ones((n, n))
for i, j in combinations(range(n), 2):
s_i = signals[pairs[i]]
s_j = signals[pairs[j]]
if method == "pearson":
corr = np.corrcoef(s_i, s_j)[0, 1]
elif method == "jaccard":
intersection = np.sum(s_i & s_j)
union = np.sum(s_i | s_j)
corr = intersection / union if union > 0 else 0
else:
raise ValueError(f"Metode tidak dikenal: {method}")
corr_matrix[i, j] = corr
corr_matrix[j, i] = corr
return corr_matrix, pairs
def estimate_correlation_factor(corr_matrix: np.ndarray) -> float:
"""
Estimasi correlation_factor dari matriks korelasi sinyal.
correlation_factor = 1 + (N-1) * mean_pairwise_correlation
Ketika korelasi 0 → C_f = 1 (semua independen).
Ketika korelasi 1 → C_f = N (semua identik).
"""
n = corr_matrix.shape[0]
upper_triangle = corr_matrix[np.triu_indices(n, k=1)]
mean_corr = np.mean(upper_triangle)
correlation_factor = 1 + (n - 1) * mean_corr
return correlation_factor
Korelasi Temporal: Tenang vs. Panik

Korelasi tidak bersifat statis. Selama periode tenang, BTC dan altcoin dapat berdivergensi — ETH naik karena berita Ethereum, SOL karena berita Solana. Dalam krisis, semuanya runtuh menjadi satu faktor: risk-on/risk-off.
def rolling_correlation_factor(
signals: dict,
window_days: int = 30,
step_days: int = 7,
) -> list:
"""
Rolling correlation_factor untuk mendeteksi perubahan rezim.
"""
pairs = sorted(signals.keys())
minutes_per_day = 1440
window = window_days * minutes_per_day
step = step_days * minutes_per_day
total_minutes = len(signals[pairs[0]])
results = []
for start in range(0, total_minutes - window, step):
end = start + window
window_signals = {p: signals[p][start:end] for p in pairs}
corr_matrix, _ = signal_correlation_matrix(window_signals)
cf = estimate_correlation_factor(corr_matrix)
results.append({
"start_minute": start,
"end_minute": end,
"correlation_factor": cf,
"effective_n": len(pairs) / cf,
})
return results
Gambaran tipikal untuk 10 pasangan kripto:
| Rezim Pasar | Rata-rata Korelasi Sinyal | ||
|---|---|---|---|
| Sideways (vol rendah) | 0.15-0.25 | 2.4-3.3 | 3.0-4.2 |
| Uptrend | 0.25-0.40 | 3.3-4.6 | 2.2-3.0 |
| Downtrend | 0.30-0.50 | 3.7-5.5 | 1.8-2.7 |
| Panik (crash) | 0.60-0.90 | 6.4-9.1 | 1.1-1.6 |
Saat panik, 10 pasangan menciut menjadi 1-2 pasangan efektif. Tepat ketika diversifikasi paling dibutuhkan, diversifikasi itu menghilang. Ini adalah analogi kripto dari klasik "korelasi menuju 1 dalam krisis."
effective_N: Konsep Kunci

Formula dan Penurunan
Ide effective_N dipinjam dari statistik, di mana ukuran sampel efektif memperhitungkan autokorelasi pengamatan. Untuk keperluan kita:
di mana adalah rata-rata korelasi sinyal berpasangan. Notasi yang disederhanakan:
Properti:
- Ketika : , — independensi penuh
- Ketika : , — semua pasangan identik
- Ketika dan : ,
Cara Estimasi correlation_factor dari Data
Dalam praktiknya, ada tiga pendekatan:
1. Dari matriks korelasi sinyal (tepat).
Jalankan strategi pada semua pasangan, dapatkan sinyal biner (0/1 untuk setiap menit), bangun matriks korelasi, hitung menggunakan rumus di atas.
2. Dari PCA imbal hasil harga (perkiraan).
Jika sinyal sangat bergantung pada dinamika harga (momentum, mean-reversion), Anda dapat memperkirakan sebagai jumlah komponen PCA yang menjelaskan 90% varians.
3. Dari heuristik kelas aset (kasar).
| Kelas Aset | Tipikal |
|---|---|
| Kripto (top-10) | 2.5-4.0 |
| Kripto (dengan DeFi/memecoin) | 2.0-3.0 |
| Forex (major) | 1.5-2.5 |
| Saham (satu sektor) | 2.0-3.5 |
| Saham (lintas sektor) | 1.2-1.8 |
Untuk portofolio kripto BTC, ETH, SOL, AVAX, MATIC, DOGE, DOT, LINK, UNI, ATOM, estimasi aman adalah .
Pemodelan Utilisasi Slot

Formula untuk
Formula dasar yang memperhitungkan korelasi:
Tabel untuk berbagai strategi dan jumlah pasangan ():
| Strategi | (waktu trading) | 5 pasangan () | 10 pasangan () | 20 pasangan () | 50 pasangan () |
|---|---|---|---|---|---|
| Strategi B | 5% | 8.2% | 15.6% | 29.1% | 58.0% |
| Strategi A | 15% | 23.6% | 41.8% | 65.9% | 92.8% |
| Strategi C | 45% | 67.1% | 89.0% | 98.8% | ~100% |
Untuk Strategi B dengan aktivitas 5%, Anda membutuhkan 50 pasangan hanya agar setidaknya satu posisi aktif setengah dari waktu. Dan itu pun belum memperhitungkan fakta bahwa 50 pasangan kripto lebih berkorelasi kuat dibanding 10.
Orkestrator Multi-Slot
Orkestrator nyata mengelola beberapa slot secara bersamaan. Jika Anda memiliki 5 slot dan 10 pasangan, utilisasi dihitung secara berbeda:
def estimate_fill_efficiency(
trading_time_pct: float,
n_pairs: int,
correlation_factor: float = 3.0,
max_slots: int = 1,
) -> dict:
"""
Estimasi analitik efisiensi pengisian untuk orkestrator multi-slot.
Args:
trading_time_pct: fraksi waktu aktif untuk satu strategi pada satu pasangan
n_pairs: jumlah pasangan trading
correlation_factor: koefisien korelasi sinyal
max_slots: jumlah maksimum posisi simultan
Returns:
dict dengan metrik utilisasi
"""
effective_n = n_pairs / correlation_factor
p_at_least_one = 1 - (1 - trading_time_pct) ** effective_n
expected_active = effective_n * trading_time_pct
utilization = min(expected_active, max_slots) / max_slots
fill_efficiency = min(p_at_least_one, utilization)
return {
"effective_n": effective_n,
"p_at_least_one": p_at_least_one,
"expected_active": expected_active,
"utilization": utilization,
"fill_efficiency": fill_efficiency,
}
configs = [
("Strategi B, 10 pasangan, 1 slot", 0.05, 10, 3.0, 1),
("Strategi B, 10 pasangan, 3 slot", 0.05, 10, 3.0, 3),
("Strategi B, 30 pasangan, 1 slot", 0.05, 30, 3.0, 1),
("Strategi A, 10 pasangan, 1 slot", 0.15, 10, 3.0, 1),
("Strategi C, 10 pasangan, 1 slot", 0.45, 10, 3.0, 1),
("Strategi C, 10 pasangan, 5 slot", 0.45, 10, 3.0, 5),
]
for name, p, n, cf, slots in configs:
result = estimate_fill_efficiency(p, n, cf, slots)
print(f"{name}:")
print(f" N_eff = {result['effective_n']:.1f}")
print(f" P(≥1 aktif) = {result['p_at_least_one']:.1%}")
print(f" E[aktif] = {result['expected_active']:.2f}")
print(f" fill_efficiency = {result['fill_efficiency']:.1%}")
print()
Output yang diharapkan:
Strategi B, 10 pasangan, 1 slot:
N_eff = 3.3
P(≥1 aktif) = 15.6%
E[aktif] = 0.17
fill_efficiency = 15.6%
Strategi B, 10 pasangan, 3 slot:
N_eff = 3.3
P(≥1 aktif) = 15.6%
E[aktif] = 0.17
fill_efficiency = 5.6%
Strategi B, 30 pasangan, 1 slot:
N_eff = 10.0
P(≥1 aktif) = 40.1%
E[aktif] = 0.50
fill_efficiency = 40.1%
Strategi A, 10 pasangan, 1 slot:
N_eff = 3.3
P(≥1 aktif) = 41.8%
E[aktif] = 0.50
fill_efficiency = 41.8%
Strategi C, 10 pasangan, 1 slot:
N_eff = 3.3
P(≥1 aktif) = 89.0%
E[aktif] = 1.50
fill_efficiency = 89.0%
Strategi C, 10 pasangan, 5 slot:
N_eff = 3.3
P(≥1 aktif) = 89.0%
E[aktif] = 1.50
fill_efficiency = 30.0%
Catatan: Strategi B dengan 3 slot dan 10 pasangan menunjukkan fill_efficiency 5,6%. Tiga slot tidak berguna ketika jumlah pasangan aktif yang diharapkan hanya 0,17. Slot harus dialokasikan secara proporsional dengan beban yang diharapkan.
Simulasi dari Data Nyata
Model analitik adalah perkiraan. Untuk estimasi yang akurat, diperlukan simulasi pada sinyal nyata:
import numpy as np
def simulate_fill_efficiency(
all_signals: dict, # {(strategi, pasangan): [(menit_masuk, menit_keluar), ...]}
max_slots: int = 10,
test_period_minutes: int = 750 * 24 * 60, # 750 hari
priority_fn=None, # fungsi prioritas untuk pemilihan posisi
) -> dict:
"""
Simulasi beban slot nyata orkestrator.
Untuk setiap menit: hitung berapa banyak pasangan ingin masuk posisi,
dan berapa banyak slot yang sebenarnya terisi (dengan mempertimbangkan batas).
Args:
all_signals: sinyal berdasarkan pasangan dan strategi
max_slots: jumlah maksimum posisi simultan
test_period_minutes: panjang periode pengujian dalam menit
priority_fn: jika None — FIFO; jika tidak — fungsi peringkat
"""
demand_timeline = np.zeros(test_period_minutes, dtype=np.int32)
capped_timeline = np.zeros(test_period_minutes, dtype=np.int32)
for signals in all_signals.values():
for entry_min, exit_min in signals:
if entry_min < test_period_minutes:
end = min(exit_min, test_period_minutes)
demand_timeline[entry_min:end] += 1
capped_timeline = np.minimum(demand_timeline, max_slots)
total_demand = np.sum(demand_timeline)
total_filled = np.sum(capped_timeline)
time_with_any_active = np.sum(demand_timeline > 0)
fill_efficiency = np.mean(capped_timeline) / max_slots
demand_fill_ratio = total_filled / total_demand if total_demand > 0 else 0
time_utilization = time_with_any_active / test_period_minutes
slot_distribution = {}
for s in range(max_slots + 1):
slot_distribution[s] = np.mean(capped_timeline == s)
return {
"fill_efficiency": fill_efficiency,
"demand_fill_ratio": demand_fill_ratio,
"time_utilization": time_utilization,
"avg_demand": np.mean(demand_timeline),
"avg_filled": np.mean(capped_timeline),
"slot_distribution": slot_distribution,
"overflow_pct": np.mean(demand_timeline > max_slots),
}
Simulasi pada data nyata seringkali menunjukkan utilisasi yang bahkan lebih rendah dari estimasi analitik, karena memperhitungkan pengelompokan temporal sinyal: semua pasangan masuk secara bersamaan dalam sebuah kluster, menciptakan overflow, kemudian semuanya diam, menciptakan kekosongan.
Berapa Banyak Pasangan yang Perlu Dipantau? Analisis Imbal Hasil yang Semakin Berkurang

Pertanyaan kuncinya: pada berapa penambahan satu pasangan lagi berhenti meningkatkan fill_efficiency secara signifikan?
import numpy as np
def diminishing_returns_analysis(
trading_time_pct: float,
correlation_factor: float = 3.0,
max_pairs: int = 100,
target_utilization: float = 0.80,
) -> dict:
"""
Analisis imbal hasil yang semakin berkurang dari penambahan pasangan baru.
"""
results = []
target_n = None
for n in range(1, max_pairs + 1):
n_eff = n / correlation_factor
p_active = 1 - (1 - trading_time_pct) ** n_eff
marginal = 0
if n > 1:
prev_eff = (n - 1) / correlation_factor
prev_p = 1 - (1 - trading_time_pct) ** prev_eff
marginal = p_active - prev_p
results.append({
"n_pairs": n,
"n_effective": n_eff,
"p_at_least_one": p_active,
"marginal_gain": marginal,
})
if target_n is None and p_active >= target_utilization:
target_n = n
return {
"results": results,
"target_n_for_utilization": target_n,
}
analysis_b = diminishing_returns_analysis(0.05, correlation_factor=3.0, target_utilization=0.80)
print(f"Strategi B: butuh {analysis_b['target_n_for_utilization']} pasangan untuk P(≥1) 80%")
for r in analysis_b["results"]:
if r["n_pairs"] in [1, 3, 5, 10, 20, 30, 50, 80]:
print(f" N={r['n_pairs']:3d}: N_eff={r['n_effective']:.1f}, "
f"P(≥1)={r['p_at_least_one']:.1%}, "
f"marginal={r['marginal_gain']:.2%}")
Hasil untuk Strategi B (, ):
| pasangan | Keuntungan marginal | ||
|---|---|---|---|
| 1 | 0.3 | 1.7% | — |
| 3 | 1.0 | 5.0% | +1.7% |
| 5 | 1.7 | 8.2% | +1.6% |
| 10 | 3.3 | 15.6% | +1.4% |
| 20 | 6.7 | 29.1% | +1.1% |
| 30 | 10.0 | 40.1% | +0.9% |
| 50 | 16.7 | 58.0% | +0.6% |
| 80 | 26.7 | 74.5% | +0.4% |
Untuk Strategi B, mencapai utilisasi single-slot 80% tidak mungkin bahkan dengan 100 pasangan (Anda memerlukan ~96 pasangan). Ini adalah batasan mendasar: strategi dengan waktu trading 5% tidak cocok untuk operasi single-slot — ini memerlukan pendekatan portofolio dengan beberapa strategi.
Untuk Strategi A (, ):
| pasangan | Keuntungan marginal | ||
|---|---|---|---|
| 5 | 1.7 | 23.6% | — |
| 10 | 3.3 | 41.8% | +3.3% |
| 20 | 6.7 | 65.9% | +2.1% |
| 30 | 10.0 | 80.3% | +1.2% |
Strategi A mencapai utilisasi 80% pada ~30 pasangan. Keuntungan marginal pada pasangan ke-30 hanya +1,2%.
Untuk Strategi C (, ):
| pasangan | ||
|---|---|---|
| 3 | 1.0 | 45.0% |
| 5 | 1.7 | 67.1% |
| 10 | 3.3 | 89.0% |
| 15 | 5.0 | 95.0% |
Strategi C dengan waktu trading 45% mencapai utilisasi 90% hanya dengan 10 pasangan. Menambahkan lebih banyak tidak ada gunanya.
Degradasi Edge di Berbagai Pasangan

Ada faktor lain yang membatasi jumlah pasangan: degradasi edge. Sebuah strategi yang dikembangkan dan dioptimalkan pada BTC/USDT mungkin berkinerja lebih buruk pada altcoin yang kurang likuid.
Penyebab degradasi:
- Likuiditas: slippage pada DOGE/USDT beberapa kali lebih tinggi dari BTC/USDT
- Spread: pasangan yang kurang likuid memiliki spread bid-ask yang lebih lebar
- Mikrostruktur: pola order book berbeda antar pasangan
- Manipulasi: altcoin berlikuiditas rendah rentan terhadap pump-and-dump
def edge_decay_analysis(
strategy_results: dict, # {pasangan: {"pnl_per_day": float, "n_trades": int}}
min_trades: int = 30,
) -> list:
"""
Peringkat pasangan berdasarkan edge dengan memperhitungkan degradasi.
"""
ranked = []
for pair, metrics in strategy_results.items():
if metrics["n_trades"] < min_trades:
continue
ranked.append({
"pair": pair,
"pnl_per_day": metrics["pnl_per_day"],
"n_trades": metrics["n_trades"],
"sharpe": metrics.get("sharpe", 0),
})
ranked.sort(key=lambda x: x["pnl_per_day"], reverse=True)
cumulative_pnl = []
running_sum = 0
for i, r in enumerate(ranked):
running_sum += r["pnl_per_day"]
avg = running_sum / (i + 1)
cumulative_pnl.append({
"n_pairs": i + 1,
"last_added": r["pair"],
"last_pnl_per_day": r["pnl_per_day"],
"avg_pnl_per_day": avg,
})
return cumulative_pnl
Gambaran tipikal:
| # pasangan | Terakhir Ditambahkan | PnL/hari dari terakhir | Rata-rata PnL/hari |
|---|---|---|---|
| 1 | BTC/USDT | 0.89% | 0.89% |
| 2 | ETH/USDT | 0.82% | 0.86% |
| 3 | SOL/USDT | 0.71% | 0.81% |
| 5 | AVAX/USDT | 0.55% | 0.73% |
| 8 | DOT/USDT | 0.31% | 0.61% |
| 10 | DOGE/USDT | 0.12% | 0.53% |
Menambahkan pasangan ke-10 menurunkan rata-rata PnL/hari portofolio. Pada pasangan ke-8, edge sudah separuh dari yang terbaik. Diperlukan keseimbangan antara fill_efficiency (meningkat dengan jumlah pasangan) dan rata-rata edge (menurun).
Jumlah Pasangan Optimal: Model Terpadu

Kita menggabungkan fill_efficiency dan penurunan edge menjadi satu metrik — expected portfolio PnL per hari:
def optimal_pairs_count(
pair_edges: list, # PnL/hari dalam urutan menurun: [0.89, 0.82, 0.71, ...]
trading_time_pct: float,
correlation_factor: float = 3.0,
max_slots: int = 1,
) -> dict:
"""
Temukan jumlah pasangan optimal yang memaksimalkan PnL portofolio.
"""
best_n = 0
best_score = 0
results = []
for n in range(1, len(pair_edges) + 1):
avg_edge = np.mean(pair_edges[:n])
n_eff = n / correlation_factor
p_active = 1 - (1 - trading_time_pct) ** n_eff
expected_active = n_eff * trading_time_pct
utilization = min(expected_active, max_slots) / max_slots
fill_eff = min(p_active, utilization)
portfolio_score = avg_edge * fill_eff * 365
results.append({
"n_pairs": n,
"avg_edge": avg_edge,
"fill_efficiency": fill_eff,
"portfolio_annualized": portfolio_score,
})
if portfolio_score > best_score:
best_score = portfolio_score
best_n = n
return {
"optimal_n": best_n,
"optimal_score": best_score,
"results": results,
}
edges = [0.89, 0.82, 0.71, 0.65, 0.55, 0.48, 0.40, 0.31, 0.22, 0.12,
0.08, 0.05, 0.02, -0.01, -0.05]
opt = optimal_pairs_count(edges, trading_time_pct=0.15, correlation_factor=3.0)
print(f"Jumlah pasangan optimal: {opt['optimal_n']}")
print(f"Portofolio dianualisasi: {opt['optimal_score']:.1f}%")
for r in opt["results"]:
print(f" N={r['n_pairs']:2d}: avg_edge={r['avg_edge']:.2f}%, "
f"fill_eff={r['fill_efficiency']:.1%}, "
f"portfolio={r['portfolio_annualized']:.1f}%")
Optimum biasanya ditemukan pada titik di mana fill_efficiency marginal dari penambahan pasangan tidak lagi mengkompensasi penurunan rata-rata edge. Untuk portofolio kripto tipikal:
- Strategi B (5% waktu): optimum pada 8-12 pasangan
- Strategi A (15% waktu): optimum pada 6-10 pasangan
- Strategi C (45% waktu): optimum pada 4-6 pasangan
Sebuah paradoks: strategi dengan waktu trading terendah mendapat manfaat dari pasangan terbanyak, namun fill_efficiency tetap rendah. Solusinya bukan lebih banyak pasangan, tetapi kombinasi dengan strategi lain (lihat Strategi Combo).
Diversifikasi Lintas Pasangan: Strategi untuk Mengurangi Korelasi

Jika Anda tidak dapat meningkatkan jumlah pasangan tanpa batas, Anda dapat mengurangi — yaitu, meningkatkan keragaman sinyal.
Strategi 1: Campuran Token Likuid dan DeFi
BTC, ETH, BNB sangat berkorelasi kuat. Tetapi UNI (DEX), AAVE (lending), CRV (stablecoin) mungkin memiliki driver tersendiri. Menambahkan token DeFi mengurangi rata-rata dari 0,35 menjadi 0,20-0,25:
Strategi 2: Strategi Berbeda pada Pasangan yang Sama
Alih-alih 10 pasangan dengan satu strategi — 5 pasangan dengan dua strategi berbeda. Jika strategi didasarkan pada prinsip yang berbeda (momentum vs. mean-reversion), sinyalnya dapat berkorelasi negatif:
- Momentum masuk long ketika harga naik
- Mean-reversion masuk long ketika harga turun
Ini adalah satu-satunya cara untuk mendapatkan — menggunakan strategi dengan korelasi sinyal negatif.
Strategi 3: Spot vs. Futures
Arbitrase tingkat pendanaan dan trading spot memiliki struktur korelasi yang berbeda. Menambahkan strategi arbitrase ke portofolio secara signifikan mengurangi keseluruhan, karena arbitrase menurut definisi mengeksploitasi divergensi, bukan konvergensi.
Rekomendasi Praktis Berdasarkan Jenis Strategi
Strategi Frekuensi Tinggi Waktu Rendah (waktu trading < 10%)
Perwakilan tipikal: Strategi B (5% waktu, 38 trade selama 750 hari).
- Jumlah pasangan: 10-15 (optimum untuk keseimbangan edge/fill)
- Masalah: fill_efficiency rendah bahkan dengan 15 pasangan (~20-25%)
- Solusi: kombinasi wajib dengan strategi lain di orkestrator
- untuk kripto: 2.5-3.5
- Pemantauan: rolling untuk menyesuaikan jumlah pasangan dengan rezim pasar
Strategi Waktu Menengah (waktu trading 10-30%)
Perwakilan tipikal: Strategi A (15% waktu, 418 trade selama 750 hari).
- Jumlah pasangan: 6-10
- Fill_efficiency pada 10 pasangan: ~40%
- Solusi: kombinasi 2-3 strategi seperti ini mengisi 80%+ dari waktu
- untuk kripto: 2.5-3.5
- Fokus: pilih pasangan dengan edge maksimum, jangan mengejar kuantitas
Strategi Waktu Tinggi (waktu trading > 30%)
Perwakilan tipikal: Strategi C (45% waktu).
- Jumlah pasangan: 4-6
- Fill_efficiency pada 6 pasangan: ~80%
- Masalah: overflow — beberapa pasangan aktif secara bersamaan, tetapi slot lebih sedikit
- Solusi: tingkatkan max_slots atau tambahkan prioritisasi pasangan
- untuk kripto: 2.5-4.0 (lebih tinggi karena posisi panjang yang tumpang tindih saat krisis)
Tabel Ringkasan
| Parameter | Strategi B (5%) | Strategi A (15%) | Strategi C (45%) |
|---|---|---|---|
| yang Direkomendasikan | 10-15 | 6-10 | 4-6 |
| pada | 3.3-5.0 | 2.0-3.3 | 1.3-2.0 |
| Efisiensi pengisian (1 slot) | 15-23% | 32-42% | 77-89% |
| Kombinasi diperlukan? | Wajib | Diinginkan | Tidak |
| Bottleneck | Sinyal sedikit | Keseimbangan | Overflow |
Hubungan dengan Metrik Lain dalam Seri
Artikel ini adalah yang kesebelas dalam seri "Backtest Tanpa Ilusi". Korelasi sinyal secara langsung memengaruhi metrik dari artikel sebelumnya:
-
PnL per Waktu Aktif: fill_efficiency adalah pengganda kunci dalam rumus imbal hasil efektif. Jika Anda melebih-estimasi fill_efficiency dengan mengabaikan korelasi, proyeksi PnL portofolio Anda akan terlalu optimis.
-
Tingkat pendanaan: dengan korelasi tinggi, posisi terbuka secara bersamaan — dan biaya pendanaan tumbuh secara linier dengan jumlah slot. Overflow + pendanaan = pembakaran modal yang dipercepat.
-
Arbitrase tingkat pendanaan: strategi arbitrase adalah diversifikator alami yang mengurangi portofolio. Sinyalnya lemah berkorelasi dengan strategi momentum dan mean-reversion.
-
Strategi combo (artikel berikutnya): cara merakit portofolio strategi dengan dan berbeda untuk mencapai utilisasi 90%+. Orkestrasi kaskade memperhitungkan korelasi sinyal saat menetapkan prioritas.
Kesimpulan
Diversifikasi dalam kripto bukan tentang jumlah pasangan. 10 pasangan yang berkorelasi menghasilkan efek 3-4 pasangan independen. Saat panik, bahkan lebih sedikit lagi.
Empat pelajaran:
-
Hitung effective_N, bukan N. Untuk pasangan kripto . Sepuluh pasangan adalah ~3,3 pasangan efektif. Rencanakan fill_efficiency berdasarkan , bukan .
-
Ukur korelasi sinyal, bukan korelasi harga. Korelasi harga adalah proksi, bukan pengganti. Jalankan strategi pada semua pasangan dan hitung matriks korelasi sinyal biner.
-
Perhitungkan degradasi edge. Lebih banyak pasangan berarti rata-rata PnL/hari yang lebih rendah. Optimum berada pada titik di mana fill_efficiency marginal dari pasangan baru masih mengkompensasi penurunan edge.
-
Kurangi , jangan tingkatkan . Menggabungkan strategi berbeda pada pasangan yang sama lebih efektif daripada satu strategi pada lebih banyak pasangan. Diversifikasi lintas strategi dapat menghasilkan .
Faktor korelasi adalah variabel tersembunyi yang menentukan seberapa realistis proyeksi utilisasi dan imbal hasil Anda. Mengabaikannya berarti membangun portofolio di atas ilusi.
Tautan Berguna
- Markowitz, H. — Portfolio Selection (1952)
- López de Prado — Advances in Financial Machine Learning: Denoising and Detoning
- Ledoit, O. & Wolf, M. — Honey, I Shrunk the Sample Covariance Matrix (2004)
- Laloux, L. et al. — Noise Dressing of Financial Correlation Matrices (1999)
- Cont, R. — Empirical Properties of Asset Returns: Stylized Facts and Statistical Issues
- Ernest Chan — Algorithmic Trading: Portfolio Construction and Risk Management
- Rebonato, R. & Jäckel, P. — The Most General Methodology for Creating a Valid Correlation Matrix
Kutipan
@article{soloviov2026signalcorrelation,
author = {Soloviov, Eugen},
title = {Korelasi Sinyal: Berapa Banyak Pasangan yang Perlu Dipantau},
year = {2026},
url = {https://marketmaker.cc/id/blog/post/signal-correlation-pairs},
version = {0.1.0},
description = {Mengapa 10 pasangan kripto tidak memberikan diversifikasi 10x, cara menghitung effective\_N melalui correlation\_factor, dan berapa banyak pasangan yang benar-benar perlu dipantau untuk utilisasi slot orkestrator 80-90\%.}
}
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.