← العودة إلى قائمة المقالات
March 14, 2026
5 دقائق للقراءة

ارتباط الإشارات: كم عدد الأزواج التي يجب مراقبتها

ارتباط الإشارات: كم عدد الأزواج التي يجب مراقبتها
#algotrading
#correlation
#diversification
#portfolio
#orchestration
#crypto

تطلق استراتيجية على 10 أزواج عملات مشفرة: BTC/USDT، ETH/USDT، SOL/USDT، AVAX/USDT وستة عملات بديلة أخرى. المنطق يبدو محكماً: إذا كانت الاستراتيجية نشطة 5% من الوقت على زوج واحد، فعبر 10 أزواج يجب أن يكون واحد على الأقل نشطاً 10.9510=40%1 - 0.95^{10} = 40\% من الوقت. زيادة أربعة أضعاف في الاستخدام.

في الواقع، يتبين أن الاستخدام 15-16%، وليس 40%. أزواجك العشرة تتصرف كثلاثة. رأس المال يبقى خاملاً، وينخفض fill_efficiency، والعائد الفعلي للمحفظة ينتهي بثلاث مرات أقل من المتوقع.

السبب هو ارتباط الإشارات. وفي العملات المشفرة، هذا الارتباط مرتفع بشكل كارثي.

وهم التنويع في العملات المشفرة

وهم التنويع في أسواق العملات المشفرة

في التمويل التقليدي، يعمل التنويع لأن سهم Apple وصندوق ETF للنفط يتفاعلان مع عوامل مختلفة. في سوق العملات المشفرة، كل شيء مختلف.

BTC هو العامل المهيمن. عندما ينخفض البيتكوين 5%، ينخفض ETH بنسبة 6-8%، وينخفض SOL بنسبة 8-12%، وتنخفض العملات البديلة بنسبة 10-20%. ارتباطات العوائد اليومية في سوق العملات المشفرة تتجاوز باستمرار 0.6، وأثناء الذعر تقترب من 1.0.

لكن بالنسبة لنا — متداولي الخوارزميات — ما يهم ليس ارتباط الأسعار، بل ارتباط الإشارات. إذا كانت الاستراتيجية مبنية على الزخم وأطلق BTC إشارة دخول، فهناك احتمال كبير أن ETH وSOL سيطلقان إشارة مماثلة في نفس الدقيقة. جميع الأزواج تدخل لونغ في وقت واحد، وتخرج جميعها في وقت واحد. عشرة مراكز — لكن في جوهرها رهان واحد.

لماذا 10 أزواج ≠ 10 أضعاف التنويع

10 أزواج مترابطة تنهار إلى 3 أزواج فعالة

الصياغة الرسمية

افترض أن الاستراتيجية على كل من NN زوج نشطة لنسبة pp من الوقت. إذا كانت الإشارات مستقلة تماماً، فإن احتمال أن يكون زوج واحد على الأقل نشطاً:

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

للاستراتيجية 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\%

لكن الإشارات ليست مستقلة. العملات المشفرة تتحرك بشكل متزامن — مما يعني أن الإشارات تظهر وتنطفئ في مجموعات.

الارتباط يحول 10 أزواج إلى 3

الحدس هو: إذا كانت 10 أزواج مترابطة، فهي تحمل معلومات من ليس 10 مصادر مستقلة بل، لنقل، 3-4. نصيغ هذا رسمياً عبر effective_N:

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

حيث CfC_f هو correlation factor، الذي يعكس متوسط ارتباط الإشارات بين الأزواج. عندما Cf=1C_f = 1 تكون الأزواج مستقلة تماماً؛ عندما Cf=NC_f = N تكون متطابقة.

لأزواج العملات المشفرة، القيمة النموذجية Cf3C_f \approx 3. عندها:

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\%

ليس 40%، بل 15.6%. فرق 2.5 ضعف. ينخفض fill efficiency وفقاً لذلك، ومعه العائد الفعلي للمحفظة بأكملها (انظر PnL per Active Time).

الارتباط في أسواق العملات المشفرة

خريطة حرارية لمصفوفة ارتباط إشارات العملات المشفرة

BTC كعامل مهيمن

يمتلك سوق العملات المشفرة بنية عاملية واضحة. يفسر BTC نسبة 60-80% من تباين العوائد اليومية لمعظم العملات البديلة. هذا مرئي بوضوح عبر PCA (تحليل المكونات الرئيسية):

import numpy as np
from sklearn.decomposition import PCA

def analyze_crypto_factor_structure(returns_matrix: np.ndarray, pair_names: list) -> dict:
    """
    PCA analysis of the factor structure of crypto returns.

    Args:
        returns_matrix: returns matrix [n_days x n_pairs]
        pair_names: list of pair names
    """
    pca = PCA()
    pca.fit(returns_matrix)

    explained = pca.explained_variance_ratio_
    cumulative = np.cumsum(explained)

    print("Factor structure:")
    for i, (var, cum) in enumerate(zip(explained[:5], cumulative[:5])):
        print(f"  PC{i+1}: {var:.1%} variance (cumulative: {cum:.1%})")

    loadings = pca.components_[0]
    print("\nPC1 loadings (BTC factor):")
    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)),
    }

النتيجة النموذجية لمحفظة من 10 أزواج عملات مشفرة:

المكون التباين المُفسَّر التراكمي
PC1 (BTC) 65% 65%
PC2 12% 77%
PC3 8% 85%
PC4 5% 90%
PC5-PC10 10% 100%

أربعة عوامل تفسر 90% من التباين. من بين 10 أزواج، لا يزيد عدد "المستقلة" عن 4.

ارتباط الإشارات مقابل ارتباط الأسعار

هنا فارق دقيق مهم. ارتباط الأسعار وارتباط الإشارات شيئان مختلفان. ارتباط أسعار BTC وETH يبلغ 0.85، لكن ارتباط إشارات استراتيجية معينة قد يكون 0.95 أو 0.50 — حسب منطق الدخول.

مثال: استراتيجية RSI للتشبع الشرائي/البيعي. RSI على BTC يعبر 30 (تشبع بيعي) — دخول لونغ. ETH في نفس اللحظة قد يكون أيضاً في حالة تشبع بيعي (ارتباط إشارات ~0.90). أو قد لا يكون كذلك، إذا كان ETH ينخفض ببطء أكبر (ارتباط إشارات ~0.40).

النهج الصحيح هو قياس ارتباط الإشارات تحديداً، وليس سلاسل الأسعار:

import numpy as np
from itertools import combinations

def signal_correlation_matrix(
    signals: dict,  # {pair: np.array of 0/1 per minute}
    method: str = "pearson",
) -> np.ndarray:
    """
    Calculate the signal correlation matrix (binary: 0 = flat, 1 = in position).

    Args:
        signals: dictionary {pair_name: binary_signal_array}
        method: correlation method ("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"Unknown method: {method}")

        corr_matrix[i, j] = corr
        corr_matrix[j, i] = corr

    return corr_matrix, pairs


def estimate_correlation_factor(corr_matrix: np.ndarray) -> float:
    """
    Estimate correlation_factor from the signal correlation matrix.

    correlation_factor = 1 + (N-1) * mean_pairwise_correlation

    When correlation is 0 → C_f = 1 (all independent).
    When correlation is 1 → C_f = N (all identical).
    """
    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

الارتباط الزمني: الهدوء مقابل الذعر

أنظمة الارتباط الزمني: السوق الهادئ مقابل الذعر

الارتباط ليس ثابتاً. خلال فترات الهدوء، يمكن أن يتباعد BTC والعملات البديلة — ETH يرتفع بأخبار إيثريوم، SOL بأخبار سولانا. في الأزمة، كل شيء ينهار إلى عامل واحد: المخاطرة/تجنب المخاطرة.

def rolling_correlation_factor(
    signals: dict,
    window_days: int = 30,
    step_days: int = 7,
) -> list:
    """
    Rolling correlation_factor to detect regime changes.
    """
    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

الصورة النموذجية لـ 10 أزواج عملات مشفرة:

نظام السوق متوسط ارتباط الإشارات CfC_f NeffN_{eff}
عرضي (تقلب منخفض) 0.15-0.25 2.4-3.3 3.0-4.2
اتجاه صاعد 0.25-0.40 3.3-4.6 2.2-3.0
اتجاه هابط 0.30-0.50 3.7-5.5 1.8-2.7
ذعر (انهيار) 0.60-0.90 6.4-9.1 1.1-1.6

أثناء الذعر، تنضغط 10 أزواج إلى 1-2 أزواج فعالة. بالتحديد عندما يكون التنويع مطلوباً أكثر، يتلاشى. هذا هو النظير المشفر للمبدأ الكلاسيكي "الارتباطات تتجه إلى 1 في الأزمة."

effective_N: المفهوم الجوهري

Effective N: تقليل الأبعاد من الأزواج المترابطة

الصيغة والاشتقاق

فكرة effective_N مستعارة من الإحصاء، حيث يأخذ حجم العينة الفعال بعين الاعتبار الارتباط الذاتي للملاحظات. لأغراضنا:

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

حيث ρˉ\bar{\rho} هو متوسط ارتباط الإشارات بين الأزواج. الترميز المبسط:

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

الخصائص:

  • عندما ρˉ=0\bar{\rho} = 0: Cf=1C_f = 1، Neff=NN_{eff} = N — استقلال تام
  • عندما ρˉ=1\bar{\rho} = 1: Cf=NC_f = N، Neff=1N_{eff} = 1 — جميع الأزواج متطابقة
  • عندما ρˉ=0.25\bar{\rho} = 0.25 و N=10N = 10: Cf=3.25C_f = 3.25، Neff=3.08N_{eff} = 3.08

كيفية تقدير correlation_factor من البيانات

في الممارسة العملية، هناك ثلاث طرق:

1. من مصفوفة ارتباط الإشارات (دقيق).

شغّل الاستراتيجية على جميع الأزواج، واحصل على إشارات ثنائية (0/1 لكل دقيقة)، وابنِ مصفوفة الارتباط، واحسب CfC_f باستخدام الصيغة أعلاه.

2. من PCA لعوائد الأسعار (تقريبي).

إذا كانت الإشارات تعتمد بشدة على ديناميكيات الأسعار (الزخم، الارتداد للمتوسط)، يمكنك تقدير NeffN_{eff} كعدد مكونات PCA التي تفسر 90% من التباين.

3. من الاستدلالات حسب فئة الأصول (تقريبي).

فئة الأصول CfC_f النموذجي
عملات مشفرة (أعلى 10) 2.5-4.0
عملات مشفرة (مع DeFi/عملات ميم) 2.0-3.0
فوركس (رئيسية) 1.5-2.5
أسهم (قطاع واحد) 2.0-3.5
أسهم (عبر القطاعات) 1.2-1.8

لمحفظة عملات مشفرة من BTC، ETH، SOL، AVAX، MATIC، DOGE، DOT، LINK، UNI، ATOM، التقدير الآمن هو Cf3C_f \approx 3.

نمذجة استخدام الفتحات

لوحة تحكم استخدام فتحات المنسق

صيغة P(1 active)P(\geq 1\ \text{active})

الصيغة الأساسية مع مراعاة الارتباط:

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

جدول لاستراتيجيات وأعداد أزواج مختلفة (Cf=3C_f = 3):

الاستراتيجية pp (وقت التداول) 5 أزواج (Neff=1.7N_{eff}=1.7) 10 أزواج (Neff=3.3N_{eff}=3.3) 20 زوجاً (Neff=6.7N_{eff}=6.7) 50 زوجاً (Neff=16.7N_{eff}=16.7)
استراتيجية B 5% 8.2% 15.6% 29.1% 58.0%
استراتيجية A 15% 23.6% 41.8% 65.9% 92.8%
استراتيجية C 45% 67.1% 89.0% 98.8% ~100%

للاستراتيجية B بنشاط 5%، تحتاج 50 زوجاً فقط لتحظى بمركز نشط واحد على الأقل نصف الوقت. وهذا لا يأخذ في الاعتبار حتى أن 50 زوجاً من العملات المشفرة مترابطة أكثر من 10.

المنسق متعدد الفتحات

المنسق الحقيقي يدير عدة فتحات في وقت واحد. إذا كان لديك 5 فتحات و10 أزواج، يُحسب الاستخدام بشكل مختلف:

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

E[active]=NeffpE[\text{active}] = 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:
    """
    Analytical estimate of fill efficiency for a multi-slot orchestrator.

    Args:
        trading_time_pct: fraction of active time for one strategy on one pair
        n_pairs: number of trading pairs
        correlation_factor: signal correlation coefficient
        max_slots: maximum number of simultaneous positions

    Returns:
        dict with utilization metrics
    """
    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 = [
    ("Strategy B, 10 pairs, 1 slot", 0.05, 10, 3.0, 1),
    ("Strategy B, 10 pairs, 3 slots", 0.05, 10, 3.0, 3),
    ("Strategy B, 30 pairs, 1 slot", 0.05, 30, 3.0, 1),
    ("Strategy A, 10 pairs, 1 slot", 0.15, 10, 3.0, 1),
    ("Strategy C, 10 pairs, 1 slot", 0.45, 10, 3.0, 1),
    ("Strategy C, 10 pairs, 5 slots", 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 active) = {result['p_at_least_one']:.1%}")
    print(f"  E[active] = {result['expected_active']:.2f}")
    print(f"  fill_efficiency = {result['fill_efficiency']:.1%}")
    print()

المخرجات المتوقعة:

Strategy B, 10 pairs, 1 slot:
  N_eff = 3.3
  P(≥1 active) = 15.6%
  E[active] = 0.17
  fill_efficiency = 15.6%

Strategy B, 10 pairs, 3 slots:
  N_eff = 3.3
  P(≥1 active) = 15.6%
  E[active] = 0.17
  fill_efficiency = 5.6%

Strategy B, 30 pairs, 1 slot:
  N_eff = 10.0
  P(≥1 active) = 40.1%
  E[active] = 0.50
  fill_efficiency = 40.1%

Strategy A, 10 pairs, 1 slot:
  N_eff = 3.3
  P(≥1 active) = 41.8%
  E[active] = 0.50
  fill_efficiency = 41.8%

Strategy C, 10 pairs, 1 slot:
  N_eff = 3.3
  P(≥1 active) = 89.0%
  E[active] = 1.50
  fill_efficiency = 89.0%

Strategy C, 10 pairs, 5 slots:
  N_eff = 3.3
  P(≥1 active) = 89.0%
  E[active] = 1.50
  fill_efficiency = 30.0%

ملاحظة: الاستراتيجية B بـ 3 فتحات و10 أزواج تُظهر fill_efficiency بنسبة 5.6%. ثلاث فتحات لا معنى لها عندما يكون العدد المتوقع من الأزواج النشطة 0.17 فقط. يجب تخصيص الفتحات بما يتناسب مع الحمل المتوقع.

المحاكاة من بيانات حقيقية

النموذج التحليلي هو تقريب. للتقدير الدقيق، تحتاج محاكاة على إشارات حقيقية:

import numpy as np

def simulate_fill_efficiency(
    all_signals: dict,       # {(strategy, pair): [(entry_min, exit_min), ...]}
    max_slots: int = 10,
    test_period_minutes: int = 750 * 24 * 60,  # 750 days
    priority_fn=None,        # priority function for position selection
) -> dict:
    """
    Simulate real slot load of the orchestrator.

    For each minute: count how many pairs want to enter a position,
    and how many slots are actually occupied (accounting for the limit).

    Args:
        all_signals: signals by pairs and strategies
        max_slots: maximum number of simultaneous positions
        test_period_minutes: length of the test period in minutes
        priority_fn: if None — FIFO; otherwise — ranking function
    """
    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),
    }

المحاكاة على بيانات حقيقية غالباً تُظهر استخداماً أقل حتى من التقدير التحليلي، لأنها تأخذ بعين الاعتبار التجمع الزمني للإشارات: جميع الأزواج تدخل في وقت واحد في مجموعة، مما يخلق تجاوزاً، ثم تصمت جميعها، مما يخلق فراغاً.

كم عدد الأزواج التي يجب مراقبتها؟ تحليل العوائد المتناقصة

Effective N ومنحنى العوائد المتناقصة

السؤال الرئيسي: عند أي NN يتوقف إضافة زوج آخر عن زيادة fill_efficiency بشكل ملحوظ؟

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:
    """
    Diminishing returns analysis from adding new pairs.
    """
    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"Strategy B: need {analysis_b['target_n_for_utilization']} pairs for 80% P(≥1)")

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%}")

نتائج الاستراتيجية B (p=0.05p = 0.05، Cf=3C_f = 3):

NN أزواج NeffN_{eff} P(1)P(\geq 1) المكسب الهامشي
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%

للاستراتيجية B، الوصول إلى 80% من استخدام فتحة واحدة مستحيل حتى مع 100 زوج (تحتاج ~96 زوجاً). هذا قيد جوهري: استراتيجية بوقت تداول 5% غير مناسبة لتشغيل فتحة واحدة — تحتاج نهج محفظة مع استراتيجيات متعددة.

للاستراتيجية A (p=0.15p = 0.15، Cf=3C_f = 3):

NN أزواج NeffN_{eff} P(1)P(\geq 1) المكسب الهامشي
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%

الاستراتيجية A تصل إلى 80% استخدام عند ~30 زوجاً. المكسب الهامشي عند الزوج الثلاثين هو فقط +1.2%.

للاستراتيجية C (p=0.45p = 0.45، Cf=3C_f = 3):

NN أزواج 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%

الاستراتيجية C بوقت تداول 45% تصل إلى 90% استخدام بـ 10 أزواج فقط. إضافة المزيد لا معنى لها.

تدهور الميزة عبر الأزواج

تدهور الميزة عبر أزواج التداول

هناك عامل آخر يحد من عدد الأزواج: تدهور الميزة. استراتيجية طُورت وحُسّنت على BTC/USDT قد تؤدي بشكل أسوأ على العملات البديلة الأقل سيولة.

أسباب التدهور:

  • السيولة: الانزلاق على DOGE/USDT أعلى بعدة مرات من BTC/USDT
  • السبريد: الأزواج الأقل سيولة لديها فروق سعرية أوسع بين العرض والطلب
  • البنية المجهرية: أنماط دفتر الأوامر تختلف بين الأزواج
  • التلاعب: العملات البديلة منخفضة السيولة عرضة للضخ والتفريغ
def edge_decay_analysis(
    strategy_results: dict,  # {pair: {"pnl_per_day": float, "n_trades": int}}
    min_trades: int = 30,
) -> list:
    """
    Rank pairs by edge accounting for degradation.
    """
    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

الصورة النموذجية:

عدد الأزواج آخر مُضاف PnL/يوم لآخر زوج متوسط PnL/يوم
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%

إضافة الزوج العاشر يخفض متوسط PnL/يوم للمحفظة. بحلول الزوج الثامن، الميزة بالفعل نصف ما هي عليه في الأفضل. التوازن مطلوب بين fill_efficiency (يزداد مع عدد الأزواج) ومتوسط الميزة (ينخفض).

العدد الأمثل من الأزواج: النموذج الموحد

العدد الأمثل من الأزواج: تقاطع fill efficiency ومتوسط الميزة

نجمع fill_efficiency وتدهور الميزة في مقياس واحد — PnL المتوقع للمحفظة يومياً:

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

def optimal_pairs_count(
    pair_edges: list,           # PnL/day in descending order: [0.89, 0.82, 0.71, ...]
    trading_time_pct: float,
    correlation_factor: float = 3.0,
    max_slots: int = 1,
) -> dict:
    """
    Find the optimal number of pairs that maximizes portfolio PnL.
    """
    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"Optimal number of pairs: {opt['optimal_n']}")
print(f"Portfolio annualized: {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}%")

النقطة المثلى توجد عادةً حيث لا يعود fill_efficiency الهامشي من إضافة زوج يعوض انخفاض متوسط الميزة. لمحفظة عملات مشفرة نموذجية:

  • الاستراتيجية B (5% وقت): الأمثل عند 8-12 زوجاً
  • الاستراتيجية A (15% وقت): الأمثل عند 6-10 أزواج
  • الاستراتيجية C (45% وقت): الأمثل عند 4-6 أزواج

المفارقة: الاستراتيجية ذات أقل وقت تداول تستفيد من أكبر عدد من الأزواج، ومع ذلك يبقى fill_efficiency منخفضاً. الحل ليس المزيد من الأزواج، بل الجمع مع استراتيجيات أخرى (انظر استراتيجيات كومبو).

التنويع عبر الأزواج: استراتيجيات تقليل الارتباط

شبكة التنويع عبر الاستراتيجيات

إذا لم تتمكن من زيادة عدد الأزواج بلا حدود، يمكنك تقليل CfC_f — أي زيادة تنوع الإشارات.

الاستراتيجية 1: مزيج من الرموز السائلة ورموز DeFi

BTC، ETH، BNB مترابطة بشدة. لكن UNI (DEX)، AAVE (إقراض)، CRV (عملات مستقرة) قد يكون لها محركاتها الخاصة. إضافة رموز DeFi تقلل متوسط ρˉ\bar{\rho} من 0.35 إلى 0.20-0.25:

Cf=1+9×0.20=2.8(مقابل 3.25 عند ρˉ=0.25)C_f = 1 + 9 \times 0.20 = 2.8 \quad \text{(مقابل 3.25 عند } \bar{\rho} = 0.25\text{)}

الاستراتيجية 2: استراتيجيات مختلفة على نفس الأزواج

بدلاً من 10 أزواج باستراتيجية واحدة — 5 أزواج باستراتيجيتين مختلفتين. إذا كانت الاستراتيجيات مبنية على مبادئ مختلفة (زخم مقابل ارتداد للمتوسط)، فإن إشاراتها يمكن أن تكون مترابطة عكسياً:

  • الزخم يدخل لونغ عندما يرتفع السعر
  • الارتداد للمتوسط يدخل لونغ عندما ينخفض السعر

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

هذه هي الطريقة الوحيدة للحصول على Neff>NN_{eff} > N — استخدام استراتيجيات ذات ارتباط إشارات سلبي.

الاستراتيجية 3: فوري مقابل عقود آجلة

المراجحة على معدل التمويل والتداول الفوري لها بنية ارتباط مختلفة. إضافة استراتيجيات المراجحة إلى المحفظة تقلل CfC_f الإجمالي بشكل كبير، لأن المراجحة بحكم التعريف تستغل التباعد، وليس التقارب.

التوصيات العملية حسب نوع الاستراتيجية

استراتيجيات عالية التردد منخفضة الوقت (وقت التداول < 10%)

الممثل النموذجي: الاستراتيجية B (5% وقت، 38 صفقة خلال 750 يوماً).

  • عدد الأزواج: 10-15 (الأمثل لتوازن الميزة/الاستخدام)
  • المشكلة: fill_efficiency منخفض حتى مع 15 زوجاً (~20-25%)
  • الحل: الجمع الإلزامي مع استراتيجيات أخرى في المنسق
  • CfC_f للعملات المشفرة: 2.5-3.5
  • المراقبة: CfC_f المتداول لتكييف عدد الأزواج مع نظام السوق

استراتيجيات متوسطة الوقت (وقت التداول 10-30%)

الممثل النموذجي: الاستراتيجية A (15% وقت، 418 صفقة خلال 750 يوماً).

  • عدد الأزواج: 6-10
  • Fill_efficiency عند 10 أزواج: ~40%
  • الحل: الجمع بين 2-3 استراتيجيات من هذا النوع يملأ 80%+ من الوقت
  • CfC_f للعملات المشفرة: 2.5-3.5
  • التركيز: اختيار الأزواج ذات أقصى ميزة، لا تطارد الكمية

استراتيجيات عالية الوقت (وقت التداول > 30%)

الممثل النموذجي: الاستراتيجية C (45% وقت).

  • عدد الأزواج: 4-6
  • Fill_efficiency عند 6 أزواج: ~80%
  • المشكلة: تجاوز — عدة أزواج نشطة في وقت واحد، لكن الفتحات أقل
  • الحل: زيادة max_slots أو إضافة تحديد أولويات الأزواج
  • CfC_f للعملات المشفرة: 2.5-4.0 (أعلى بسبب تداخل المراكز الطويلة مع الأزمات)

جدول ملخص

المعامل الاستراتيجية B (5%) الاستراتيجية A (15%) الاستراتيجية C (45%)
NN الموصى به 10-15 6-10 4-6
NeffN_{eff} عند Cf=3C_f=3 3.3-5.0 2.0-3.3 1.3-2.0
Fill eff. (فتحة واحدة) 15-23% 32-42% 77-89%
هل الجمع مطلوب؟ إلزامي مرغوب لا
عنق الزجاجة إشارات قليلة التوازن التجاوز

الارتباط بالمقاييس الأخرى في السلسلة

هذه المقالة هي الحادية عشرة في سلسلة "اختبارات رجعية بلا أوهام". ارتباط الإشارات يؤثر مباشرة على المقاييس من المقالات السابقة:

  • PnL per Active Time: fill_efficiency هو المضاعف الرئيسي في صيغة العائد الفعلي. إذا بالغت في تقدير fill_efficiency بتجاهل الارتباط، ستكون توقعات PnL للمحفظة متفائلة أكثر من اللازم.

  • معدلات التمويل: مع الارتباط العالي، تُفتح المراكز في وقت واحد — وتنمو تكاليف التمويل خطياً مع عدد الفتحات. التجاوز + التمويل = حرق متسارع لرأس المال.

  • مراجحة معدل التمويل: استراتيجيات المراجحة هي منوع طبيعي يقلل CfC_f للمحفظة. إشاراتها مرتبطة بشكل ضعيف مع استراتيجيات الزخم والارتداد للمتوسط.

  • استراتيجيات كومبو (المقالة التالية): كيفية تجميع محفظة استراتيجيات ذات pp وCfC_f مختلفين لتحقيق استخدام 90%+. التنسيق المتتالي يأخذ بعين الاعتبار ارتباط الإشارات عند تعيين الأولويات.

الخلاصة

التنويع في العملات المشفرة ليس عن عدد الأزواج. 10 أزواج مترابطة تعطي تأثير 3-4 أزواج مستقلة. أثناء الذعر، أقل من ذلك.

أربع نقاط رئيسية:

  1. احسب effective_N، وليس N. لأزواج العملات المشفرة Cf3C_f \approx 3. عشرة أزواج هي ~3.3 أزواج فعالة. خطط fill_efficiency بناءً على NeffN_{eff}، وليس NN.

  2. قس ارتباط الإشارات، وليس ارتباط الأسعار. ارتباط الأسعار هو بديل تقريبي، وليس بديلاً كاملاً. شغّل الاستراتيجية على جميع الأزواج واحسب مصفوفة ارتباط الإشارات الثنائية.

  3. احسب حساب تدهور الميزة. المزيد من الأزواج يعني متوسط PnL/يوم أقل. النقطة المثلى هي حيث fill_efficiency الهامشي من زوج جديد لا يزال يعوض انخفاض الميزة.

  4. قلل CfC_f، لا تزد NN. الجمع بين استراتيجيات مختلفة على نفس الأزواج أكثر فعالية من استراتيجية واحدة على أزواج أكثر. التنويع عبر الاستراتيجيات يمكن أن يحقق Neff>NN_{eff} > N.

Correlation factor هو المتغير الخفي الذي يحدد مدى واقعية توقعات الاستخدام والعائد. تجاهله يعني بناء محفظة على أوهام.


روابط مفيدة

  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

Citation

@article{soloviov2026signalcorrelation,
  author = {Soloviov, Eugen},
  title = {Signal Correlation: How Many Pairs to Monitor},
  year = {2026},
  url = {https://marketmaker.cc/ru/blog/post/signal-correlation-pairs},
  version = {0.1.0},
  description = {Why 10 crypto pairs don't provide 10x diversification, how to calculate effective\_N via correlation\_factor, and how many pairs you really need to monitor for 80-90\% orchestrator slot utilization.}
}
blog.disclaimer

MarketMaker.cc Team

البحوث والاستراتيجيات الكمية

ناقش في تلغرام
Newsletter

ابقَ متقدماً على السوق

اشترك في نشرتنا الإخبارية للحصول على رؤى حصرية حول تداول الذكاء الاصطناعي وتحليلات السوق وتحديثات المنصة.

نحترم خصوصيتك. يمكنك إلغاء الاشتراك في أي وقت.