← Kembali ke artikel
March 14, 2026
5 menit baca

Korelasi Sinyal: Berapa Banyak Pasangan yang Perlu Dipantau

Korelasi Sinyal: Berapa Banyak Pasangan yang Perlu Dipantau
#algotrading
#korelasi
#diversifikasi
#portofolio
#orkestrasi
#kripto

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 10.9510=40%1 - 0.95^{10} = 40\% 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

Ilusi diversifikasi di pasar mata uang 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

10 pasangan yang berkorelasi menciut menjadi 3 pasangan efektif

Pernyataan Formal

Misalkan sebuah strategi pada masing-masing dari NN pasangan aktif selama pp fraksi waktu. Jika sinyal sepenuhnya independen, probabilitas setidaknya satu pasangan aktif:

P(1 aktif)=1(1p)NP(\geq 1\ \text{aktif}) = 1 - (1 - p)^N

Untuk Strategi B (p=0.05p = 0.05, N=10N = 10):

P(1)=10.9510=10.598740.1%P(\geq 1) = 1 - 0.95^{10} = 1 - 0.5987 \approx 40.1\%

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:

Neff=NCfN_{eff} = \frac{N}{C_f}

di mana CfC_f adalah faktor korelasi (correlation factor), yang mencerminkan rata-rata korelasi sinyal berpasangan. Ketika Cf=1C_f = 1 pasangan sepenuhnya independen; ketika Cf=NC_f = N mereka identik.

Untuk pasangan kripto, Cf3C_f \approx 3 yang khas. Maka:

Neff=1033.3N_{eff} = \frac{10}{3} \approx 3.3

P(1)=10.953.310.844=15.6%P(\geq 1) = 1 - 0.95^{3.3} \approx 1 - 0.844 = 15.6\%

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

Heatmap matriks korelasi sinyal 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

Rezim korelasi temporal: pasar 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 CfC_f NeffN_{eff}
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

Effective N: reduksi dimensi dari pasangan yang berkorelasi

Formula dan Penurunan

Ide effective_N dipinjam dari statistik, di mana ukuran sampel efektif memperhitungkan autokorelasi pengamatan. Untuk keperluan kita:

Neff=N1+(N1)ρˉN_{eff} = \frac{N}{1 + (N - 1) \cdot \bar{\rho}}

di mana ρˉ\bar{\rho} adalah rata-rata korelasi sinyal berpasangan. Notasi yang disederhanakan:

Neff=NCf,Cf=1+(N1)ρˉN_{eff} = \frac{N}{C_f}, \quad C_f = 1 + (N - 1) \cdot \bar{\rho}

Properti:

  • Ketika ρˉ=0\bar{\rho} = 0: Cf=1C_f = 1, Neff=NN_{eff} = N — independensi penuh
  • Ketika ρˉ=1\bar{\rho} = 1: Cf=NC_f = N, Neff=1N_{eff} = 1 — semua pasangan identik
  • Ketika ρˉ=0.25\bar{\rho} = 0.25 dan N=10N = 10: Cf=3.25C_f = 3.25, Neff=3.08N_{eff} = 3.08

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 CfC_f menggunakan rumus di atas.

2. Dari PCA imbal hasil harga (perkiraan).

Jika sinyal sangat bergantung pada dinamika harga (momentum, mean-reversion), Anda dapat memperkirakan NeffN_{eff} sebagai jumlah komponen PCA yang menjelaskan 90% varians.

3. Dari heuristik kelas aset (kasar).

Kelas Aset CfC_f 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 Cf3C_f \approx 3.

Pemodelan Utilisasi Slot

Dashboard utilisasi slot orkestrator

Formula untuk P(1 aktif)P(\geq 1\ \text{aktif})

Formula dasar yang memperhitungkan korelasi:

P(1 aktif)=1(1p)NeffP(\geq 1\ \text{aktif}) = 1 - (1 - p)^{N_{eff}}

Tabel untuk berbagai strategi dan jumlah pasangan (Cf=3C_f = 3):

Strategi pp (waktu trading) 5 pasangan (Neff=1.7N_{eff}=1.7) 10 pasangan (Neff=3.3N_{eff}=3.3) 20 pasangan (Neff=6.7N_{eff}=6.7) 50 pasangan (Neff=16.7N_{eff}=16.7)
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:

utilisasi=min(E[aktif],max_slots)max_slots\text{utilisasi} = \frac{\min(E[\text{aktif}], \text{max\_slots})}{\text{max\_slots}}

E[aktif]=NeffpE[\text{aktif}] = N_{eff} \cdot p

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

Effective N dan kurva imbal hasil yang semakin berkurang

Pertanyaan kuncinya: pada NN 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 (p=0.05p = 0.05, Cf=3C_f = 3):

NN pasangan NeffN_{eff} P(1)P(\geq 1) 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 (p=0.15p = 0.15, Cf=3C_f = 3):

NN pasangan NeffN_{eff} P(1)P(\geq 1) 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 (p=0.45p = 0.45, Cf=3C_f = 3):

NN pasangan NeffN_{eff} P(1)P(\geq 1)
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

Degradasi edge di berbagai pasangan trading

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

Jumlah pasangan optimal: persimpangan efisiensi pengisian vs. rata-rata edge

Kita menggabungkan fill_efficiency dan penurunan edge menjadi satu metrik — expected portfolio PnL per hari:

PnL Portofolio/hari=avg_edge(N)×fill_efficiency(N)×365\text{PnL Portofolio/hari} = \text{avg\_edge}(N) \times \text{fill\_efficiency}(N) \times 365

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

Jaringan diversifikasi lintas strategi

Jika Anda tidak dapat meningkatkan jumlah pasangan tanpa batas, Anda dapat mengurangi CfC_f — 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 ρˉ\bar{\rho} dari 0,35 menjadi 0,20-0,25:

Cf=1+9×0.20=2.8(vs. 3.25 pada ρˉ=0.25)C_f = 1 + 9 \times 0.20 = 2.8 \quad \text{(vs. 3.25 pada } \bar{\rho} = 0.25\text{)}

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

ρˉlintas-strategi<0    Cf<1    Neff>N\bar{\rho}_{\text{lintas-strategi}} < 0 \implies C_f < 1 \implies N_{eff} > N

Ini adalah satu-satunya cara untuk mendapatkan Neff>NN_{eff} > N — 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 CfC_f 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
  • CfC_f untuk kripto: 2.5-3.5
  • Pemantauan: rolling CfC_f 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
  • CfC_f 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
  • CfC_f 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%)
NN yang Direkomendasikan 10-15 6-10 4-6
NeffN_{eff} pada Cf=3C_f=3 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 CfC_f portofolio. Sinyalnya lemah berkorelasi dengan strategi momentum dan mean-reversion.

  • Strategi combo (artikel berikutnya): cara merakit portofolio strategi dengan pp dan CfC_f 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:

  1. Hitung effective_N, bukan N. Untuk pasangan kripto Cf3C_f \approx 3. Sepuluh pasangan adalah ~3,3 pasangan efektif. Rencanakan fill_efficiency berdasarkan NeffN_{eff}, bukan NN.

  2. Ukur korelasi sinyal, bukan korelasi harga. Korelasi harga adalah proksi, bukan pengganti. Jalankan strategi pada semua pasangan dan hitung matriks korelasi sinyal biner.

  3. 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.

  4. Kurangi CfC_f, jangan tingkatkan NN. Menggabungkan strategi berbeda pada pasangan yang sama lebih efektif daripada satu strategi pada lebih banyak pasangan. Diversifikasi lintas strategi dapat menghasilkan Neff>NN_{eff} > N.

Faktor korelasi adalah variabel tersembunyi yang menentukan seberapa realistis proyeksi utilisasi dan imbal hasil Anda. Mengabaikannya berarti membangun portofolio di atas ilusi.


Tautan Berguna

  1. Markowitz, H. — Portfolio Selection (1952)
  2. López de Prado — Advances in Financial Machine Learning: Denoising and Detoning
  3. Ledoit, O. & Wolf, M. — Honey, I Shrunk the Sample Covariance Matrix (2004)
  4. Laloux, L. et al. — Noise Dressing of Financial Correlation Matrices (1999)
  5. Cont, R. — Empirical Properties of Asset Returns: Stylized Facts and Statistical Issues
  6. Ernest Chan — Algorithmic Trading: Portfolio Construction and Risk Management
  7. 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\%.}
}
Penafian: Informasi yang disediakan dalam artikel ini hanya untuk tujuan edukasi dan informasi serta tidak merupakan nasihat keuangan, investasi, atau trading. Trading mata uang kripto mengandung risiko kerugian yang signifikan.

Penulis

Eugen Soloviov
Eugen Soloviov

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.

Newsletter

Selangkah Lebih Maju dari Pasar

Berlangganan newsletter kami untuk wawasan AI trading eksklusif, analisis pasar, dan pembaruan platform.

Kami menghormati privasi Anda. Berhenti berlangganan kapan saja.