← กลับไปยังบทความ
March 10, 2026
อ่าน 5 นาที

Multi-Symbol Validation: ทดสอบกลยุทธ์ของคุณกับทุกคู่เทรด

Multi-Symbol Validation: ทดสอบกลยุทธ์ของคุณกับทุกคู่เทรด
#algotrading
#backtest
#validation
#multi-symbol
#diversification
#crypto

บทความจากซีรีส์ "Backtests Without Illusions"

คุณปรับแต่งกลยุทธ์บน ETHUSDT ข้อมูล 25 เดือน พารามิเตอร์ 12+ ตัว ผล backtest แสดง PnL +55%, 500 ไม้, MaxDD -0.9%, เปิดสถานะ 15% ของเวลา เส้น equity curve ขึ้นอย่างราบรื่น พารามิเตอร์ผ่าน plateau analysis — จุดเหมาะสมดูกว้าง Walk-forward ได้ WFER > 0.6 Monte Carlo bootstrap แสดงเปอร์เซ็นต์ไทล์ที่ 5 เป็นบวก

ทุกอย่างสมบูรณ์แบบ ยกเว้นสิ่งเดียว: คุณทดสอบกลยุทธ์บน เครื่องมือเดียว

คุณรันอัลกอริทึมเดิมด้วยพารามิเตอร์เดิมบน BTCUSDT — PnL +8% บน SOLUSDT — PnL -12% บน DOGEUSDT — PnL -34% กลยุทธ์ที่ผ่านการตรวจสอบทั้งหมดบน ETH กลับไม่ทำกำไรบนคู่เทรดอื่นส่วนใหญ่

นี่ไม่ใช่บัก นี่คือ กับดักสัญลักษณ์เดียว (single-symbol trap) — หนึ่งในรูปแบบ overfitting ที่พบบ่อยและอันตรายที่สุดใน algotrading

กับดักเครื่องมือเดียว

Single-symbol trap: เส้น equity curve สวยงามเส้นเดียวล้อมรอบด้วยกลยุทธ์ที่ล้มเหลวบนสินทรัพย์อื่น

การปรับแต่งกลยุทธ์บนสัญลักษณ์เดียวโดยพื้นฐานแล้วคือการ fit กับพลวัตราคาของสินทรัพย์นั้นโดยเฉพาะ แม้คุณจะรัน walk-forward แม้ bootstrap จะแสดง confidence interval กว้าง — การตรวจสอบเหล่านี้ทั้งหมดดำเนินการ ภายใน time series เดียว

Walk-forward ตรวจสอบความทนทานข้าม เวลา: พารามิเตอร์ทำงานกับข้อมูลอนาคตของเครื่องมือเดิมได้ไหม Monte Carlo ตรวจสอบความทนทานข้าม ลำดับไม้: กลยุทธ์ทนต่อลำดับที่ต่างออกไปได้ไหม แต่ไม่มีวิธีใดตรวจสอบความทนทานข้าม เครื่องมือ: กลยุทธ์ทำงานกับสินทรัพย์อื่นที่มีคุณสมบัติต่างกันได้ไหม

ถ้ากลยุทธ์ทำกำไรได้เฉพาะบน ETHUSDT — มันจับได้ไม่ใช่ความไม่มีประสิทธิภาพของตลาด แต่เป็นโครงสร้างเฉพาะของ price series ของ ETH:

  • รูปแบบแท่งเทียนที่เป็นลักษณะเฉพาะของ ETH
  • ระดับความผันผวนเฉพาะที่ threshold ถูก tune ให้
  • ความเจาะจงด้านสภาพคล่องและ microstructure ของคู่เทรดนี้
  • ความสัมพันธ์กับ BTC ที่เป็นลักษณะเฉพาะของช่วงเวลาหนึ่ง

สิ่งเหล่านี้ไม่ใช่ edge นี่คือ curve fitting ในระดับเครื่องมือ

กลุ่มสัญลักษณ์ (Tiers) ในตลาด Crypto

เมทริกซ์คุณสมบัติของแต่ละ tier

ไม่ใช่ว่าสกุลเงินดิจิทัลทุกตัวเท่าเทียมกัน สำหรับ multi-symbol validation ที่มีความหมาย คุณต้องเข้าใจว่าเครื่องมือแบ่งออกเป็นกลุ่มที่มีคุณสมบัติแตกต่างกันโดยพื้นฐาน

Tier 1: Blue Chips (BTC, ETH)

สภาพคล่องสูง ความผันผวนค่อนข้างต่ำ กระแส institutional ความสัมพันธ์กับ macro (S&P 500, DXY, อัตราดอกเบี้ย Fed) Order book ลึก spread แคบ funding rate เสถียร ความผันผวนรายวันทั่วไป: 2-4%

Tier 2: Large Caps (SOL, BNB, ADA, XRP, AVAX)

สภาพคล่องปานกลาง ความผันผวนสูงขึ้น การเคลื่อนไหวมักขับเคลื่อนโดย sector dynamics (L1 vs L2, DeFi vs infra) Funding rate ผันผวนมากขึ้น Spread กว้างขึ้น ความผันผวนรายวันทั่วไป: 4-6%

Tier 3: Mid Caps (DOGE, SHIB, PEPE, ARB, OP)

Meme coin และ narrative token ความผันผวนสูง ความสัมพันธ์กับปัจจัยพื้นฐานต่ำ การเคลื่อนไหวถูกกำหนดโดย social media, listing, narrative Order book บางบน exchange บางแห่ง ความผันผวนรายวันทั่วไป: 6-10%

Tier 4: Low Caps (New Listings)

ความผันผวนสุดขั้ว order book บาง ความเสี่ยงจากการ manipulate ประวัติมักไม่เพียงพอสำหรับ backtest เต็มรูปแบบ ความผันผวนรายวันทั่วไป: 10-20%+

ตารางสรุปคุณสมบัติ

คุณสมบัติ Tier 1 Tier 2 Tier 3 Tier 4
ความผันผวนรายวัน 2-4% 4-6% 6-10% 10-20%+
Spread เฉลี่ย (perps) 0.01-0.02% 0.02-0.05% 0.05-0.15% 0.1-0.5%+
ความลึก order book (top 5 bps) $5-50M $1-10M $100K-2M $10K-200K
Funding rate (ค่าเฉลี่ย abs) 0.005-0.01% 0.01-0.03% 0.02-0.08% 0.05-0.2%+
ความสัมพันธ์กับ BTC 0.85-0.95 0.6-0.85 0.3-0.7 0.1-0.5
ประวัติขั้นต่ำ 5+ ปี 2-5 ปี 6 เดือน - 3 ปี < 6 เดือน

แต่ละ tier คือ "โลก" ที่แยกจากกันด้วย microstructure ของตัวเอง กลยุทธ์ที่ tune สำหรับ Tier 1 เข้าสู่สภาพแวดล้อมแปลกใหม่เมื่อย้ายไป Tier 3

วิธีการ Multi-Symbol Validation

วิธีการ multi-symbol validation: ปรับแต่ง, ทดสอบ tier เดิม, ทดสอบ tier อื่น, วิเคราะห์ผลลัพธ์

ขั้นตอนที่ 1: ปรับแต่งบนสัญลักษณ์เดียว

เลือกสัญลักษณ์สำหรับการปรับแต่ง เช่น ETHUSDT รัน pipeline เต็มรูปแบบ: Optuna optimization, plateau analysis, walk-forward กำหนดพารามิเตอร์ให้คงที่

ขั้นตอนที่ 2: ทดสอบบนสัญลักษณ์จาก Tier เดิม

รันกลยุทธ์ด้วย พารามิเตอร์เดิม บน 5-10 สัญลักษณ์จาก tier เดิม สำหรับ Tier 1 มีจำกัด (BTC + ETH) แต่สำหรับ Tier 2 และ Tier 3 มีสัญลักษณ์เพียงพอ

ขั้นตอนที่ 3: ทดสอบบนสัญลักษณ์จาก Tier อื่น

รันกลยุทธ์บน 3-5 สัญลักษณ์จากแต่ละ tier อื่น นี่คือการทดสอบที่โหดที่สุด: ถ้ากลยุทธ์ทำงานบน ETHUSDT (Tier 1) และบน DOGEUSDT (Tier 3) ความน่าจะเป็นของ curve fitting นั้นน้อยมาก

ขั้นตอนที่ 4: วิเคราะห์ผลลัพธ์ตามกลุ่ม

รวมเมตริกตาม tier และประเมินความทนทานข้ามสัญลักษณ์

เมตริกสำหรับแต่ละสัญลักษณ์

สำหรับแต่ละสัญลักษณ์ บันทึก:

  • PnL — ผลตอบแทนรวม
  • MaxDD — drawdown สูงสุด
  • N trades — จำนวนไม้
  • Win rate — สัดส่วนไม้ที่ทำกำไร
  • PnL/active day — ผลตอบแทนต่อหน่วยเวลาที่ active (รายละเอียดใน PnL by active time)

เกณฑ์การผ่าน

กลยุทธ์ผ่าน multi-symbol validation หาก:

  1. ทำกำไรบน >= 60% ของสัญลักษณ์ใน tier เดิม
  2. PnL เฉลี่ยในกลุ่มเป็นบวก
  3. MaxDD ไม่เพิ่มขึ้นอย่างมาก (ไม่เกิน 2-3 เท่าเทียบกับสัญลักษณ์ที่ใช้ปรับแต่ง)
  4. ถ้ากลยุทธ์ทำกำไรเฉพาะบนสัญลักษณ์ที่ปรับแต่ง — ปฏิเสธ

ตัวอย่าง: สามกลยุทธ์ สามผลลัพธ์

เปรียบเทียบสามกลยุทธ์: A (เขียว, ประสบความสำเร็จบางส่วน), B (ฟ้าอมเขียว, ทนทาน), C (แดง, overfitted)

ลองดูตัวอย่างที่เป็นรูปธรรม สามกลยุทธ์ (Strategy A, Strategy B, Strategy C) ปรับแต่งบน ETHUSDT ทดสอบบน 12 สัญลักษณ์ใน tier สี่ระดับ

Strategy A (ปรับแต่งบน ETHUSDT)

พารามิเตอร์: PnL +55%, ~500 ไม้, ~15% active time, MaxDD ~0.9%

สัญลักษณ์ Tier PnL MaxDD N trades Win rate PnL/active day
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%

* — สัญลักษณ์ที่ใช้ปรับแต่ง

ผลลัพธ์ตาม tier:

Tier สัญลักษณ์ ทำกำไร PnL เฉลี่ย 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%

คำตัดสิน: Strategy A ทำงานได้ใน Tier 1-2 แต่ล้มเหลวโดยสิ้นเชิงใน Tier 3 นี่คือกลยุทธ์ทั่วไปที่ tune สำหรับสภาพแวดล้อมความผันผวนต่ำ สำหรับพอร์ตโฟลิโอของ blue chips และ large caps — ยอมรับได้ สำหรับการใช้งานทั่วไป — ไม่ได้

Strategy B (ปรับแต่งบน ETHUSDT)

พารามิเตอร์: PnL +25%, ~40 ไม้, ~5% active time

สัญลักษณ์ 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%

ผลลัพธ์ตาม tier:

Tier สัญลักษณ์ ทำกำไร PnL เฉลี่ย 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%

คำตัดสิน: Strategy B ทำกำไรบน 9 จาก 11 สัญลักษณ์ (82%) PnL เฉลี่ยเป็นบวกในทุก tier MaxDD เพิ่มขึ้นตามที่คาดไว้ตาม tier นี่คือ กลยุทธ์ที่ทนทาน ด้วย edge ตลาดที่แท้จริง แม้ PnL บนสัญลักษณ์ที่ปรับแต่งจะถ่อมตัวกว่า (+25% เทียบกับ +55%) Strategy B น่าเชื่อถือกว่า Strategy A มากอย่างมีนัยสำคัญ

Strategy C (ปรับแต่งบน ETHUSDT)

พารามิเตอร์: PnL +300%, ~400 ไม้, ~45% active time, MaxDD ~17%

สัญลักษณ์ 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%

คำตัดสิน: Strategy C คือ overfitting แบบคลาสสิก +301% บน ETHUSDT แต่ขาดทุนอย่างหนักบนคู่อื่นส่วนใหญ่ MaxDD บน Tier 3 เกิน 70% — นี่คือการทำลายทุน กลยุทธ์จับรูปแบบเฉพาะของ ETH ไม่ใช่ความไม่มีประสิทธิภาพของตลาด ปฏิเสธ

ทำไมกลยุทธ์ถึงพังบนสัญลักษณ์อื่น

สี่ปัจจัยที่ทำให้กลยุทธ์พัง: ความผันผวน, สภาพคล่อง, microstructure และการเปลี่ยน regime

1. ความไม่ตรงกันของความผันผวน

เหตุผลที่พบบ่อยที่สุด พารามิเตอร์กลยุทธ์ถูก tune ให้กับระดับความผันผวนเฉพาะ ถ้ากลยุทธ์ใช้ threshold เข้า 2% — สำหรับ ETH ที่มีความผันผวนรายวัน 3% นี่คือ filter ที่สมเหตุสมผล สำหรับ DOGE ที่มีความผันผวนรายวัน 8% — threshold นี้ trigger บ่อยเกินไป สร้างสัญญาณเท็จจำนวนมาก

ในทำนองเดียวกัน stop loss 1% เหมาะสำหรับ ETH แต่สำหรับ PEPE มันคือ "noise" ปกติ และ stop จะถูก hit หลายสิบครั้งต่อวัน

2. ความแตกต่างด้านสภาพคล่อง

กลยุทธ์สมมติว่าคำสั่งถูก execute ทันทีที่ราคาปัจจุบัน บน BTCUSDT ด้วยความลึก order book 50Mภายใน5bps—นี่สมจริงบนARBUSDTด้วยความลึก50M ภายใน 5 bps — นี่สมจริง บน ARBUSDT ด้วยความลึก 200K — คำสั่ง $10K ของคุณจะเคลื่อนราคา และการ execute จริงจะแย่กว่า 0.05-0.2% ใน 500 ไม้ นั่นคือ 25-100% ที่หายไปเพียงจาก slippage เท่านั้น

3. Market Microstructure

แต่ละเครื่องมือมี microstructure ของตัวเอง:

  • Funding rates: บน BTC funding เป็นบวกสม่ำเสมอในตลาดขาขึ้น (+0.01% ทุก 8 ชั่วโมง) บน meme coin funding อาจกระโดดจาก -0.3% ถึง +0.5% รายละเอียดเพิ่มเติม — ใน Funding rates kill your leverage
  • Spread: บน Tier 1 spread คือ 0.01% บน Tier 4 — 0.5% กลยุทธ์ที่มี take-profit เล็กไม่สามารถทำกำไรได้เมื่อ spread เกินขนาด take
  • Manipulation patterns: wicks, spoofing, wash trading — แสดงออกต่างกันในแต่ละ tier

4. Regime Sensitivity

Altcoin ประพฤติตัวต่างกันในเฟสตลาดที่ต่างกัน:

  • ในเทรนด์ขาขึ้น altcoin outperform BTC (beta > 1)
  • ในเทรนด์ขาลง altcoin ร่วงหนักกว่า BTC
  • ในตลาด sideways altcoin อาจ correlate กับ BTC หรือเคลื่อนไหวตาม narrative ของตัวเอง

กลยุทธ์ที่ปรับแต่งในเฟสหนึ่งบนสัญลักษณ์หนึ่งอาจถูก tune ให้เหมาะสมกับ lag/lead ของสัญลักษณ์นั้นเทียบกับ BTC โดยเฉพาะ — และ lag/lead นี้จะเปลี่ยนเมื่อ regime เปลี่ยน

การปรับพารามิเตอร์แบบ Adaptive

การปรับพารามิเตอร์แบบ adaptive: gauge อัตราส่วนความผันผวนพร้อม sliders พารามิเตอร์ที่แปลงจาก threshold แคบเป็น threshold กว้าง

การรันกลยุทธ์ด้วยพารามิเตอร์เดิมบนสัญลักษณ์ทั้งหมดนั้นไม่ถูกต้อง แต่การ re-optimize เต็มรูปแบบบนแต่ละสัญลักษณ์ก็ทำลายวัตถุประสงค์ของ multi-symbol validation (พารามิเตอร์กลายเป็น "native" ของแต่ละสัญลักษณ์)

ทางประนีประนอมคือ การ normalize พารามิเตอร์ตามความผันผวน:

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

ผลลัพธ์:

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 เพิ่มจาก 1% เป็น 2.53% — เหมาะสมกับความผันผวนรายวัน 8.1% ของ DOGE โดยไม่มีการ scale stop 1% จะถูก hit โดย "noise" หลายสิบครั้ง

สำคัญ: scale เฉพาะ price thresholds (entries, stops, takes) เท่านั้น Period ของ indicator (RSI, MA) และตัวคูณ (ATR multiplier) มักไม่ถูก scale — พวกมัน normalize ตามความผันผวนผ่าน indicator อยู่แล้ว

สองโหมดการตรวจสอบ

  1. Strict mode (ไม่มี scaling): รันด้วยพารามิเตอร์เดิม ทดสอบความทนทานสัมบูรณ์ ถ้ากลยุทธ์ทำกำไร — edge นั้นแข็งแกร่ง

  2. Adaptive mode (มี scaling): รันด้วยพารามิเตอร์ที่ normalize แล้ว ทดสอบความทนทานของ logic กลยุทธ์ โดยยอมรับว่าระดับความผันผวนต่างกัน

เราแนะนำให้รันทั้งสองการทดสอบ Strict mode — เพื่อประเมิน "ความแข็งแกร่ง" ของ edge Adaptive mode — สำหรับการประยุกต์ใช้จริง

Cross-Symbol Robustness Score

Multi-symbol cross-robustness radar

สำหรับการประเมินเชิงปริมาณของความทนทานข้ามสัญลักษณ์ เราแนะนำ metric ผสม — Cross-Symbol Robustness Score (CSRS)

สูตร

CSRS=w1Rprofit+w2Rpnl+w3Pconsistencyw4Pvariance\text{CSRS} = w_1 \cdot R_{profit} + w_2 \cdot R_{pnl} + w_3 \cdot P_{consistency} - w_4 \cdot P_{variance}

โดยที่:

  • RprofitR_{profit} — สัดส่วนสัญลักษณ์ที่ทำกำไร:

Rprofit=NprofitableNtotalR_{profit} = \frac{N_{profitable}}{N_{total}}

  • RpnlR_{pnl} — PnL เฉลี่ยถ่วงน้ำหนักสภาพคล่องแบบ normalize:

Rpnl=i=1NliPnLii=1NliR_{pnl} = \frac{\sum_{i=1}^{N} l_i \cdot \text{PnL}_i}{\sum_{i=1}^{N} l_i}

โดยที่ lil_i คือสภาพคล่องของสัญลักษณ์ ii (ปริมาณซื้อขายรายวันเฉลี่ย)

  • PconsistencyP_{consistency} — โบนัสสำหรับความสอดคล้องข้าม tier:

Pconsistency=Nprofitable_tiersNtotal_tiersP_{consistency} = \frac{N_{profitable\_tiers}}{N_{total\_tiers}}

  • PvarianceP_{variance} — บทลงโทษสำหรับความแปรปรวนสูงของ PnL ระหว่างสัญลักษณ์:

Pvariance=σ(PnL1,,PnLN)max(PnLˉ,0.01)P_{variance} = \frac{\sigma(\text{PnL}_1, \ldots, \text{PnL}_N)}{\max(|\bar{\text{PnL}}|, 0.01)}

น้ำหนักเริ่มต้น

ส่วนประกอบ น้ำหนัก เหตุผล
w1w_1 (สัดส่วนที่ทำกำไร) 0.35 สำคัญที่สุด: กลยุทธ์ต้องทำงานบนส่วนใหญ่
w2w_2 (PnL เฉลี่ย) 0.25 ผลตอบแทนสัมบูรณ์
w3w_3 (ข้าม tier) 0.25 โบนัสสำหรับความเป็นสากล
w4w_4 (บทลงโทษความแปรปรวน) 0.15 บทลงโทษสำหรับความไม่เสถียร

การตีความ CSRS

CSRS การตีความ
> 0.7 ความทนทานยอดเยี่ยม กลยุทธ์ทำงานบนเครื่องมือส่วนใหญ่
0.5 — 0.7 ความทนทานดี กลยุทธ์ทำงานใน tier ของตัวเองและบางส่วนใน tier อื่น
0.3 — 0.5 เส้นแบ่ง กลยุทธ์ทำงานบนชุดสัญลักษณ์แคบ
< 0.3 ความทนทานต่ำ curve fitting ในระดับเครื่องมือมีแนวโน้มสูง

การ Implement เต็มรูปแบบ: Multi-Symbol Validation Pipeline

Isometric 3D data processing pipeline สำหรับ multi-symbol strategy validation

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)

ตัวอย่างการใช้งาน 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}")

เมื่อการตรวจสอบสัญลักษณ์เดียวเป็นที่ยอมรับได้

ข้อยกเว้น: order book สำหรับ market-making, cross-exchange arbitrage และรูปแบบ correlation เฉพาะสินทรัพย์

ไม่ใช่ทุกกลยุทธ์ที่ต้องทำงานข้ามหลายเครื่องมือ มีกรณีที่ชอบด้วยกฎหมายที่ single-symbol เป็นแนวทางปกติ:

Market Making บน Order Book เฉพาะ

กลยุทธ์ market-making (เช่น ใช้โมเดล Avellaneda-Stoikov) โดยนิยามแล้วผูกกับ order book เฉพาะ พารามิเตอร์ขึ้นอยู่กับ microstructure เฉพาะ: ความลึก, spread, ตำแหน่งในคิว, fill rate การทดสอบบนสัญลักษณ์อื่นไม่มีความหมาย — มันเป็น order book ที่ต่างกัน

Arbitrage ระหว่างคู่เทรดเฉพาะ

Funding rate arbitrage หรือ cross-exchange arbitrage โดยนิยามแล้วผูกกับคู่เครื่องมือเฉพาะ การตรวจสอบที่นี่คือบน exchange อื่นด้วยคู่เดิม ไม่ใช่บนสัญลักษณ์ที่ต่างกัน

กลยุทธ์ที่ใช้คุณสมบัติเฉพาะของสินทรัพย์อย่างชัดเจน

ถ้ากลยุทธ์อิงอยู่กับคุณสมบัติเฉพาะของสินทรัพย์หนึ่ง (เช่น ความสัมพันธ์ของ BTC กับ hashrate หรือความสัมพันธ์ของ ETH กับ gas fees) multi-symbol validation ไม่สามารถใช้ได้ แต่กลยุทธ์เหล่านี้หายาก

ในกรณีอื่นทั้งหมด — ถ้ากลยุทธ์อิงอยู่กับสัญญาณ "ทั่วไป" (MA crossover, RSI, momentum, mean reversion) — multi-symbol validation เป็นสิ่งจำเป็น ถ้ากลยุทธ์ทั่วไปทำงานเฉพาะบนสัญลักษณ์เดียว มันไม่ใช่ edge — มันคือ overfitting

ความสัมพันธ์กับวิธีการตรวจสอบอื่น

สามแกนการตรวจสอบตั้งฉากกัน: เวลา (walk-forward), เครื่องมือ (multi-symbol), ลำดับไม้ (Monte Carlo)

Multi-symbol validation คือ หนึ่งในสามวิธีตั้งฉากกัน ของการทดสอบ out-of-sample:

วิธีการ แกนการตรวจสอบ สิ่งที่เผยให้เห็น
Walk-Forward เวลา Overfitting กับช่วงเวลาเฉพาะ
Multi-symbol เครื่องมือ Overfitting กับสินทรัพย์เฉพาะ
Monte Carlo Bootstrap ลำดับไม้ การพึ่งพาลำดับเฉพาะ

แต่ละวิธีตรวจสอบความทนทานตามแกนของตัวเอง กลยุทธ์สามารถผ่าน walk-forward แต่ล้มเหลวใน multi-symbol (curve fitted กับเครื่องมือ) สามารถผ่าน multi-symbol แต่ล้มเหลวใน Monte Carlo (ขึ้นอยู่กับลำดับไม้ที่โชคดี)

การป้องกัน overfitting สูงสุด: ใช้ทั้งสามวิธี

Full validation pipeline:

  1. Optimization ของพารามิเตอร์บนสัญลักษณ์เดียว
  2. Plateau analysis — ตรวจสอบเสถียรภาพของจุดเหมาะสม
  3. Walk-forward — การตรวจสอบแกนเวลา (WFER > 0.5)
  4. Multi-symbol — การตรวจสอบแกนเครื่องมือ (CSRS > 0.5)
  5. Monte Carlo bootstrap — confidence intervals (เปอร์เซ็นต์ไทล์ที่ 5 > 0)
  6. คำนึงถึง funding rates และ ความไม่สมมาตรของการขาดทุน

กลยุทธ์ที่ผ่านการตรวจสอบทั้งหกมีความน่าจะเป็นน้อยที่สุดที่จะเป็น overfitting artifact

ส่วนขยาย: Correlation ระหว่างสัญลักษณ์และ Cascade Strategies

กราฟเครือข่าย correlation สกุลเงินดิจิทัลพร้อม cascade strategy allocation flows

Multi-symbol validation เผยให้เห็นอีกด้านหนึ่ง: correlations ระหว่างสัญลักษณ์ ถ้ากลยุทธ์ทำกำไรบน BTC และ ETH แต่ไม่ทำกำไรบน altcoin ทั้งหมด — นี่คือข้อมูลที่ว่า edge ผูกกับ correlation สูงระหว่าง BTC-ETH การวิเคราะห์โครงสร้าง correlation โดยละเอียด — ในบทความ Signal correlation and pairs trading

สำหรับพอร์ตโฟลิโอกลยุทธ์ ผลลัพธ์ multi-symbol กำหนดว่าจะ launch กลยุทธ์บนเครื่องมือใด Strategy A จากตัวอย่างข้างต้น — เฉพาะ Tier 1-2 Strategy B — Tier 1-3 นี่คือข้อมูลสำหรับ cascade orchestration ซึ่ง launch กลยุทธ์ต่างกันบนเครื่องมือต่างกันขึ้นอยู่กับ robustness profile ของพวกมัน

บทสรุป

Multi-symbol validation ไม่ใช่ตัวเลือก — มันเป็นขั้นตอนบังคับสำหรับกลยุทธ์ใดๆ ที่อ้างว่ามี market edge ที่เป็นสากล ประเด็นสำคัญ:

  1. กลยุทธ์ที่ทำงานบนสัญลักษณ์เดียวมักจะ overfit กับลักษณะเฉพาะของสัญลักษณ์นั้น ข้อยกเว้น: market making, arbitrage, กลยุทธ์ที่อิงคุณสมบัติเฉพาะของสินทรัพย์

  2. การจัดกลุ่ม Tier เป็นสิ่งจำเป็น คุณไม่สามารถเปรียบเทียบผลลัพธ์บน BTC (Tier 1) กับผลลัพธ์บน PEPE (Tier 3) โดยไม่เข้าใจความแตกต่างด้านความผันผวน สภาพคล่อง และ microstructure

  3. การปรับพารามิเตอร์แบบ Adaptive — การ normalize threshold ตามความผันผวน — ปรับปรุงความสมจริงของการทดสอบ multi-symbol อย่างมีนัยสำคัญ

  4. CSRS > 0.5 — threshold ขั้นต่ำที่สมเหตุสมผล กลยุทธ์ควรทำกำไรบน >= 60% ของสัญลักษณ์ใน tier เดิม และ PnL เฉลี่ยในสัญลักษณ์ทั้งหมดควรเป็นบวก

  5. Walk-forward + Multi-symbol + Monte Carlo — สามแกนการตรวจสอบตั้งฉากกัน แต่ละวิธีจับสิ่งที่วิธีอื่นพลาด ใช้ทั้งสาม

กลยุทธ์ที่มี PnL +25% และ CSRS 0.72 น่าเชื่อถือกว่ากลยุทธ์ที่มี PnL +300% และ CSRS 0.18 กลยุทธ์แรกหาเงินจากความไม่มีประสิทธิภาพของตลาด กลยุทธ์หลังหาเงินจากการจำ price series เดียว


ลิงก์ที่เป็นประโยชน์

  1. Lopez de Prado, M. — Advances in Financial Machine Learning (Wiley)
  2. Pardo, R. — The Evaluation and Optimization of Trading Strategies (Wiley)
  3. Bailey, D.H. et al. — The Probability of Backtest Overfitting
  4. Aronson, D.R. — Evidence-Based Technical Analysis
  5. Kevin Davey — Building Winning Algorithmic Trading Systems (Wiley)
  6. Harvey, C.R. & Liu, Y. — Backtesting (2015)
  7. Chan, E. — Algorithmic Trading: Winning Strategies and Their Rationale (Wiley)
  8. Binance Research — Cryptocurrency Correlation Analysis
  9. NumPy — numpy.random.choice
  10. Pandas — DataFrame

การอ้างอิง

@article{soloviov2026multisymbolvalidation,
  author = {Soloviov, Eugen},
  title = {Multi-Symbol Validation: Test Your Strategy on All Pairs},
  year = {2026},
  url = {https://marketmaker.cc/th/blog/post/multi-symbol-validation},
  version = {0.1.0},
  description = {ทำไมกลยุทธ์ที่ปรับแต่งบน ETHUSDT ถึงอาจล้มเหลวกับ altcoin อื่น วิธีทดสอบอย่างถูกต้องข้ามกลุ่มคู่เทรด (blue chips, large caps, shitcoins) และระดับคะแนนความทนทานข้ามสัญลักษณ์ที่ถือว่าเพียงพอ}
}
ข้อจำกัดความรับผิดชอบ: ข้อมูลที่ให้ไว้ในบทความนี้มีไว้เพื่อการศึกษาและให้ข้อมูลเท่านั้น และไม่ถือเป็นคำแนะนำทางการเงิน การลงทุน หรือการเทรด การเทรดสกุลเงินดิจิทัลมีความเสี่ยงสูงที่จะขาดทุน

ผู้เขียน

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

ก้าวนำหน้าตลาด

สมัครรับจดหมายข่าวของเราเพื่อรับข้อมูลเชิงลึกการเทรดด้วย AI เฉพาะ การวิเคราะห์ตลาด และการอัปเดตแพลตฟอร์ม

เราเคารพความเป็นส่วนตัวของคุณ ยกเลิกการสมัครได้ทุกเมื่อ