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

Hidden Markov Models ในการเทรด: วิธีปรับกลยุทธ์ให้เข้ากับระบอบตลาด

Hidden Markov Models ในการเทรด: วิธีปรับกลยุทธ์ให้เข้ากับระบอบตลาด
#hmm
#market-regimes
#machine-learning
#algotrading
#adaptive-strategies
#volatility

ทุก algo trader ล้วนเคยมีช่วงวิกฤตอัตถิภาวะ คุณใช้เวลาสามเดือนสร้างกลยุทธ์หนึ่งขึ้นมา backtest แสดง Sharpe 2.4 เส้นโค้ง equity งดงามราวกับงานศิลปะ คุณปล่อยบอทรัน สองสัปดาห์แรกเต็มไปด้วยความตื่นเต้น — กลยุทธ์กำลังสร้าง alpha จากนั้นตลาด "สลับ" — และ momentum bot ของคุณเริ่มเลือดออกทีละน้อยอย่างเป็นระบบในช่วง range ซื้อทุกจุดสูงสุดในท้องถิ่นและขายทุกจุดต่ำสุดในท้องถิ่น

ปัญหาไม่ใช่กลยุทธ์ ปัญหาคือตลาดไม่ใช่ระบบเดียว แต่เป็นหลายระบบที่สลับกันโดยไม่มีการเตือน กลยุทธ์ momentum ที่สมบูรณ์แบบในช่วงเทรนด์จะทำลายพอร์ตในช่วง range กลยุทธ์ grid ที่พิมพ์เงินในตลาด sideways จะระเบิดเมื่อตลาดเคลื่อนไหวทิศทาง mean-reversion ที่เสถียรในตลาดสงบจะถูก margin call ในช่วง black swan

คำถามไม่ใช่ "กลยุทธ์ไหนดีกว่า" แต่คือ "ระบอบตลาดปัจจุบันคืออะไร และกลยุทธ์ไหนเหมาะสม" และนี่คือจุดที่ Hidden Markov Models (HMM) เข้าสู่เวที — กรอบทางคณิตศาสตร์ที่ช่วยให้คุณทำให้สัญชาตญาณนี้เป็นรูปธรรมได้

ตลาดไม่หยุดนิ่ง และนั่นไม่ใช่ bug แต่เป็น feature

เริ่มด้วยความจริงที่ไม่น่าพึงใจ: โมเดลสถิติพื้นฐานแทบทุกตัวสมมติให้ข้อมูลอยู่ในสภาวะ stationarity ค่าเฉลี่ยและความแปรปรวนไม่เปลี่ยนแปลงตามเวลา autocorrelation คงที่ การกระจายตัวเสถียร อนุกรมเวลาทางการเงินละเมิดสมมติฐานเหล่านี้ทั้งหมดในเวลาเดียวกัน

ดู BTC daily return ย้อนหลัง 5 ปี ผลตอบแทนรายวันเฉลี่ยในช่วง bull rally ปี 2024 อยู่ที่ประมาณ +0.3% ส่วนเบี่ยงเบนมาตรฐาน ~2.5% ในตลาดหมีปี 2022 — เฉลี่ย -0.15% ส่วนเบี่ยงเบน ~4% ในตลาด sideways ฤดูร้อนปี 2023 — เฉลี่ย ~0% ส่วนเบี่ยงเบน ~1.5% นี่คือสามระบอบสถิติที่แตกต่างกันโดยพื้นฐานด้วยการกระจายตัวที่ต่างกัน

อย่างเป็นทางการ: ให้ rtr_t คือผลตอบแทน ณ เวลา tt ในโลก stationary rtN(μ,σ2)r_t \sim \mathcal{N}(\mu, \sigma^2) ด้วยพารามิเตอร์คงที่ ในความเป็นจริง พารามิเตอร์เองเป็น random process: rtN(μSt,σSt2)r_t \sim \mathcal{N}(\mu_{S_t}, \sigma^2_{S_t}) โดยที่ StS_t คือสถานะที่ซ่อนอยู่ (ระบอบตลาด) ซึ่งสลับระหว่างค่าจำนวนจำกัด

แนวคิดนี้ถูกทำให้เป็นรูปธรรมในปี 1989 โดย James Hamilton ในผลงานพื้นฐานของเขา "A New Approach to the Economic Analysis of Nonstationary Time Series and the Business Cycle" เขาแสดงให้เห็นว่าวัฏจักรธุรกิจสามารถจำลองเป็นการสลับระหว่างสองสถานะที่ซ่อนอยู่ — ภาวะถดถอยและการขยายตัว — โดยใช้กลไก Markov ตั้งแต่นั้นมา โมเดลของ Hamilton ได้กลายเป็นหนึ่งในเครื่องมือที่ถูกอ้างอิงมากที่สุดในเศรษฐมิติ

สามระบอบตลาด สามระบอบตลาด — กระทิง (เขียว) หมี (แดง) และ sideways (เหลือง) — มองเห็นได้ชัดเจนในมุมมองย้อนหลัง แต่การตรวจจับการเปลี่ยนแปลงในเวลาจริงนั้นยากกว่ามาก

HMM: สัญชาตญาณผ่านการเปรียบเทียบ

ก่อนจะดำดิ่งสู่สูตรคณิตศาสตร์ มาสร้างความเข้าใจเชิงสัญชาตญาณกันก่อน

Markov Chains: ไม่มีความทรงจำ

Markov chain คือ random process ที่อนาคตขึ้นอยู่กับปัจจุบันเท่านั้น ไม่ใช่อดีต สภาพอากาศพรุ่งนี้ขึ้นอยู่กับสภาพอากาศวันนี้ แต่ไม่ขึ้นกับสภาพอากาศเมื่อสัปดาห์ที่แล้ว (การทำให้เรียบง่ายอย่างมาก แต่ใช้ได้ในฐานะโมเดล)

ระบอบตลาดมีพฤติกรรมในลักษณะเดียวกัน ถ้าวันนี้ตลาดอยู่ในระบอบกระทิง ความน่าจะเป็นที่จะอยู่ในระบอบนั้นต่อพรุ่งนี้สูง (เช่น 95%) ความน่าจะเป็นที่จะเปลี่ยนไปเป็นหมีต่ำ (3%) ไปสู่ sideways — ต่ำกว่าอีก (2%) นี่คือเมทริกซ์ความน่าจะเป็นการเปลี่ยนสถานะ

         Bull    Bear    Sideways
Bull    [0.95    0.03    0.02  ]
Bear    [0.04    0.93    0.03  ]
Sideways[0.05    0.05    0.90  ]

สังเกต: องค์ประกอบในแนวทแยงสูง — ระบอบมีความ "เหนียว" ตลาดไม่กระโดดจากกระทิงไปหมีทุกวัน มันอยู่ในระบอบเดียวเป็นสัปดาห์และเดือนก่อนเปลี่ยน ระยะเวลาที่คาดหวังของระบอบคือ di=11aiid_i = \frac{1}{1 - a_{ii}} สำหรับระบอบกระทิงที่ a11=0.95a_{11} = 0.95 นั่นคือ 20 วัน สำหรับระบอบหมีที่ a22=0.93a_{22} = 0.93 — ประมาณ 14 วัน

สถานะที่ซ่อนอยู่: เราเห็นแต่เงา

คำสำคัญคือ "ซ่อนอยู่" เราไม่สังเกตระบอบตลาดโดยตรง ไม่มีใครแขวนป้ายว่า "ระวัง กำลังเปลี่ยนสู่ระบอบหมี" เรามองเห็นแต่ observations — ผลตอบแทน ความผันผวน ปริมาณ ระบอบคือตัวแปรแฝงที่ต้องอนุมานจาก observations

มันเหมือนกับการอยู่ในห้องที่ไม่มีหน้าต่างแล้วพยายามระบุสภาพอากาศจากการแต่งกายของคนที่เดินเข้ามาจากข้างนอก ร่ม? น่าจะฝน กางเกงขาสั้นและแว่นตากันแดด? แดดออก แต่คนใส่กางเกงขาสั้นคนเดียวไม่ได้หมายความว่าแดดออกแน่นอน — อาจเป็นแค่คนที่มองโลกในแง่ดี คุณต้องสะสม observations และประมาณสถานะที่ซ่อนอยู่แบบความน่าจะเป็น

ใน HMM แต่ละระบอบที่ซ่อนอยู่ "ปล่อย" observations จากการกระจายตัวของมันเอง:

  • ระบอบกระทิง → ผลตอบแทนจาก N(μbull,σbull2)\mathcal{N}(\mu_{bull}, \sigma^2_{bull}) โดยที่ μbull>0\mu_{bull} > 0, σbull\sigma_{bull} ปานกลาง
  • ระบอบหมี → ผลตอบแทนจาก N(μbear,σbear2)\mathcal{N}(\mu_{bear}, \sigma^2_{bear}) โดยที่ μbear<0\mu_{bear} < 0, σbear\sigma_{bear} สูง
  • Sideways → ผลตอบแทนจาก N(μsideways,σsideways2)\mathcal{N}(\mu_{sideways}, \sigma^2_{sideways}) โดยที่ μsideways0\mu_{sideways} \approx 0, σsideways\sigma_{sideways} ต่ำ

สังเกตรูปแบบที่เป็นลักษณะเฉพาะ: ระบอบหมีมักมีไม่แค่ค่าเฉลี่ยที่ติดลบ แต่ยังมีความผันผวนสูงขึ้นด้วย ตลาดใช้ลิฟต์ขึ้นและบันไดลง — และ HMM จับสิ่งนี้โดยอัตโนมัติ

สถาปัตยกรรม HMM สถาปัตยกรรม Hidden Markov Model: สถานะที่ซ่อนอยู่ (ระบอบ) สลับตาม Markov chain แต่ละสถานะสร้าง observable returns จากการกระจาย Gaussian ของตัวเอง

อัลกอริทึม HMM สามตัว: Forward, Viterbi, Baum-Welch

การทำงานทั้งหมดกับ HMM귀归结ลงสู่ปัญหาพื้นฐานสามข้อ แต่ละข้อมีอัลกอริทึมของตัวเอง

ปัญหาที่ 1: ความน่าจะเป็นของ Observations เหล่านี้คืออะไร? (Forward Algorithm)

คำถาม: เมื่อกำหนดลำดับผลตอบแทน ความน่าจะเป็นที่จะสังเกตลำดับนี้ตรงๆ เมื่อพิจารณาพารามิเตอร์โมเดลคืออะไร?

ทำไม: การเปรียบเทียบโมเดล (AIC/BIC) การตรวจสอบความเหมาะสม

ทำงานอย่างไร: Forward Algorithm คือ dynamic programming ในแต่ละขั้น tt เราคำนวณ "forward variable" αt(i)\alpha_t(i) — ความน่าจะเป็นของการสังเกตลำดับ o1,o2,,oto_1, o_2, \ldots, o_t และอยู่ในสถานะ ii ณ เวลา tt

การเรียกซ้ำ: αt(j)=[iαt1(i)aij]bj(ot)\alpha_t(j) = \left[\sum_i \alpha_{t-1}(i) \cdot a_{ij}\right] \cdot b_j(o_t)

โดยที่ aija_{ij} คือความน่าจะเป็นการเปลี่ยนจากสถานะ ii ไป jj และ bj(ot)b_j(o_t) คือความน่าจะเป็นของ observation oto_t ในสถานะ jj พูดง่ายๆ: เราหาผลรวมทุก path ที่เราอาจมาถึงสถานะ jj แล้วคูณด้วยความน่าจะเป็นของ observation

ความซับซ้อน: O(N2T)O(N^2 T) แทนที่ O(NT)O(N^T) แบบ naive โดยที่ NN คือจำนวนสถานะ TT คือความยาวลำดับ สำหรับ 3 ระบอบและ 1,000 observations นั่นคือ 9,000 operations แทนที่ 310003^{1000} ความแตกต่าง พูดได้เลยว่า มีนัยสำคัญมาก

ปัญหาที่ 2: ลำดับระบอบที่น่าจะเป็นที่สุดคืออะไร? (Viterbi Algorithm)

คำถาม: เมื่อกำหนดลำดับผลตอบแทน ลำดับสถานะที่ซ่อนอยู่ (ระบอบ) ไหนที่น่าจะสร้างมันมากที่สุด?

ทำไม: นี่คือสิ่งที่เราต้องการสำหรับการเทรด — การระบุระบอบในแต่ละจุดเวลา

ทำงานอย่างไร: Viterbi Algorithm เหมือนกับ Forward แต่แทนที่จะหาผลรวมทุก path มันหาค่าสูงสุด เราไม่ได้มองหาความน่าจะเป็นของทุก path ที่เป็นไปได้ แต่มองหา path ที่น่าจะเป็นที่สุด

δt(j)=maxi[δt1(i)aij]bj(ot)\delta_t(j) = \max_i \left[\delta_{t-1}(i) \cdot a_{ij}\right] \cdot b_j(o_t)

บวกกับการ backtrack (backtracking) เพื่อกู้คืนลำดับสถานะเอง ผลลัพธ์คือลำดับระบอบที่ถอดรหัสแล้ว: "กระทิง-กระทิง-กระทิง-หมี-หมี-sideways-..."

ในทางปฏิบัติ สำหรับการเทรด สิ่งที่ใช้บ่อยกว่าไม่ใช่ Viterbi (optimum ทั่วโลก) แต่เป็น filtering — ความน่าจะเป็นสถานะ posterior ณ แต่ละช่วงเวลา: P(St=io1,,ot)P(S_t = i \mid o_1, \ldots, o_t) ซึ่งช่วยให้ทำงานออนไลน์โดยไม่ต้องรอลำดับทั้งหมด และได้ประมาณการ "soft" เช่น "กระทิง 70% sideways 25% หมี 5%"

ปัญหาที่ 3: วิธีฝึกโมเดล? (Baum-Welch Algorithm)

คำถาม: เมื่อให้แค่ observations พารามิเตอร์โมเดล (AA, BB, π\pi) ไหนที่ maximize likelihood ของข้อมูล?

ทำไม: การฝึกโมเดลบนข้อมูลในอดีต

ทำงานอย่างไร: Baum-Welch Algorithm เป็นกรณีพิเศษของ EM algorithm (Expectation-Maximization):

  1. E-step: ใช้พารามิเตอร์ปัจจุบัน คำนวณสถานะที่ซ่อนอยู่ที่คาดหวัง (ผ่าน Forward-Backward)
  2. M-step: อัปเดตพารามิเตอร์โดย maximizing likelihood เมื่อพิจารณาสถานะที่คาดหวังเหล่านี้
  3. ทำซ้ำจนกระทั่งเกิด convergence

ความละเอียดอ่อนสำคัญ: EM รับประกัน convergence เฉพาะ local maximum เท่านั้น เงื่อนไขเริ่มต้นที่แตกต่างกันอาจให้ผลลัพธ์ต่างกัน ในทางปฏิบัติ โมเดลจะถูกฝึกหลายครั้งด้วยการ initialization ต่างกัน และเลือกผลลัพธ์ที่ดีที่สุดด้วย log-likelihood ใน hmmlearn สิ่งนี้ทำโดยอัตโนมัติผ่านพารามิเตอร์ n_init

ระบอบตลาด Crypto: สิ่งที่เรากำลังมองหา

สำหรับ cryptocurrency การแบ่งสามระบอบแบบคลาสสิกทำงานได้ดีเป็นพิเศษเนื่องจากระยะตลาดที่เด่นชัด

ระบอบที่ 1: กระทิง

  • ผลตอบแทนเฉลี่ย: +0.15% ... +0.5% ต่อวัน
  • ความผันผวน (std): 2-3% ต่อวัน
  • ลักษณะ: การเติบโตอย่างต่อเนื่องด้วยการ pullback ปานกลาง
  • ระยะเวลา: 2-6 เดือนต่อเนื่อง
  • ปริมาณ: เพิ่มขึ้น โดยเฉพาะในตลาด spot
  • On-chain: MVRV > 1.5 ที่อยู่ที่ active เพิ่มขึ้น

ระบอบที่ 2: หมี

  • ผลตอบแทนเฉลี่ย: -0.1% ... -0.4% ต่อวัน
  • ความผันผวน (std): 3-6% ต่อวัน
  • ลักษณะ: การร่วงลงอย่างรวดเร็ว การต่อเนื่องของการ liquidation dead cat bounce
  • ระยะเวลา: 1-4 เดือน (โดยทั่วไปสั้นกว่ากระทิง)
  • ปริมาณ: สูงขึ้นเมื่อขายด้วยความตื่นตระหนก จากนั้นลดลง
  • On-chain: MVRV < 1 กระแสเข้า exchange เพิ่มขึ้น

ระบอบที่ 3: Sideways (การสะสม)

  • ผลตอบแทนเฉลี่ย: ~0% ต่อวัน
  • ความผันผวน (std): 1-2% ต่อวัน
  • ลักษณะ: การเคลื่อนไหวในช่วง range การ breakout ปลอม
  • ระยะเวลา: 1-3 เดือน
  • ปริมาณ: ต่ำ ลดลง
  • On-chain: ตัวชี้วัดเสถียร กิจกรรมลดลง

ทำไมถึงสามระบอบพอดี ไม่ใช่สองหรือห้า? สองหยาบเกินไป — คุณสูญเสียข้อมูลเกี่ยวกับระยะ sideways (และสำหรับ market-making bot นี่คือระบอบที่ทำกำไรได้มากที่สุด) ห้าขึ้นไป — โมเดล overfit ความน่าจะเป็นการเปลี่ยนสถานะไม่เสถียร การตีความยาก สามคือสมดุลที่เหมาะสม ได้รับการยืนยันทั้งจากเกณฑ์ข้อมูล (AIC/BIC) และสัญชาตญาณทางเศรษฐกิจ

ที่กล่าวมา จำนวนสถานะเป็น hyperparameter และควรทดสอบ Guidolin & Timmermann (2007) ในบทความ "Asset Allocation under Multivariate Regime Switching" พบสี่ระบอบสำหรับพอร์ตหุ้นและพันธบัตรผสม: crash การเติบโตช้า กระทิง และการฟื้นตัว

Feature Engineering: สิ่งที่จะป้อนให้โมเดล

ตัวเลือกที่ง่ายที่สุดคือป้อนแค่ daily returns ซึ่งใช้ได้ แต่สามารถปรับปรุงได้ นี่คือชุด feature ที่พิสูจน์แล้วว่าดีในทางปฏิบัติ:

Price Features

  • Daily log return: rt=ln(Pt/Pt1)r_t = \ln(P_t / P_{t-1})
  • Rolling volatility: σt=std(rtw,,rt)\sigma_t = \text{std}(r_{t-w}, \ldots, r_t) ด้วย window ww (เช่น 20 วัน)
  • Rolling mean return: rˉt=mean(rtw,,rt)\bar{r}_t = \text{mean}(r_{t-w}, \ldots, r_t)

Volume Features

  • Normalized volume: Vtnorm=Vt/SMA(V,20)V_t^{norm} = V_t / \text{SMA}(V, 20)
  • Volume-price correlation: สหสัมพันธ์ระหว่างปริมาณและผลตอบแทนแบบสัมบูรณ์ใน rolling window

On-Chain Features (สำหรับ cryptocurrency)

  • MVRV Ratio: market capitalization ต่อ realized capitalization MVRV > 2 — ตลาดร้อนเกินไป < 1 — undervalued
  • NVT Ratio: network value ต่อปริมาณธุรกรรม เทียบเท่า P/E ของ blockchain
  • Exchange Net Flow: กระแสสุทธิไปยัง exchange ค่าบวก — แรงกดดันขาย ค่าลบ — การสะสม
  • Active Addresses: จำนวนที่อยู่ที่ active (เพิ่มขึ้น = ความสนใจ ลดลง = ความเฉยเมย)
import numpy as np
import pandas as pd

def prepare_features(df: pd.DataFrame, window: int = 20) -> pd.DataFrame:
    """
    Prepare features for HMM.
    df must contain columns: close, volume
    """
    features = pd.DataFrame(index=df.index)

    features['log_return'] = np.log(df['close'] / df['close'].shift(1))

    features['rolling_vol'] = features['log_return'].rolling(window).std()

    features['norm_volume'] = df['volume'] / df['volume'].rolling(window).mean()

    features['rolling_mean_return'] = features['log_return'].rolling(window).mean()

    features['abs_return'] = features['log_return'].abs()

    return features.dropna()

สำคัญ: feature ทั้งหมดต้องเป็น stationary (หรืออย่างน้อยโดยประมาณ) Log returns เป็น stationary ราคาไม่ใช่ ปริมาณควร normalize ได้ดีกว่า ความผันผวนสามารถปล่อยไว้ได้ — มันก็ quasi-stationary เช่นกัน

ความละเอียดอ่อนอีกอย่าง: multivariate HMM (เมื่อป้อน feature vector เป็น input) ทำงานได้ดีกว่า univariate แต่ต้องการข้อมูลมากขึ้นสำหรับการฝึก สำหรับ crypto ที่มีประวัติ 5+ ปี ปกติไม่ใช่ปัญหา สำหรับ altcoin ใหม่ที่มีประวัติ 3 เดือน — ควรใช้หนึ่งหรือสอง feature ดีกว่า

การนำไปใช้ทีละขั้นตอนใน Python กับ hmmlearn

มาถึงโค้ดกัน ไลบรารี hmmlearn เป็นมาตรฐานโดยพฤตินัยสำหรับ HMM ใน Python API ง่าย เข้ากันได้กับ scikit-learn ใช้งานได้ทันที

ขั้นตอนที่ 1: โหลดข้อมูล

import ccxt
import pandas as pd
import numpy as np
from datetime import datetime

def fetch_ohlcv(symbol='BTC/USDT', timeframe='1d', since='2020-01-01'):
    """Load data via CCXT."""
    exchange = ccxt.binance()
    since_ts = exchange.parse8601(f'{since}T00:00:00Z')
    all_ohlcv = []

    while True:
        ohlcv = exchange.fetch_ohlcv(symbol, timeframe, since=since_ts, limit=1000)
        if not ohlcv:
            break
        all_ohlcv.extend(ohlcv)
        since_ts = ohlcv[-1][0] + 1
        if len(ohlcv) < 1000:
            break

    df = pd.DataFrame(all_ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
    df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
    df.set_index('timestamp', inplace=True)
    return df

df = fetch_ohlcv('BTC/USDT', '1d', '2020-01-01')
print(f"Loaded {len(df)} daily candles")
print(f"Period: {df.index[0]}{df.index[-1]}")

ขั้นตอนที่ 2: เตรียม Feature และฝึก HMM

from hmmlearn.hmm import GaussianHMM
from sklearn.preprocessing import StandardScaler

features = prepare_features(df, window=20)

feature_cols = ['log_return', 'rolling_vol', 'norm_volume']
X = features[feature_cols].values

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

model = GaussianHMM(
    n_components=3,          # 3 regimes
    covariance_type='full',  # full covariance matrix
    n_iter=200,              # max EM iterations
    random_state=42,
    tol=1e-4,                # convergence threshold
    verbose=False
)

model.fit(X_scaled)

print(f"Model converged: {model.monitor_.converged}")
print(f"Iterations: {model.monitor_.iter}")
print(f"Log-likelihood: {model.score(X_scaled):.2f}")

ขั้นตอนที่ 3: ถอดรหัสระบอบ

hidden_states = model.predict(X_scaled)

state_probs = model.predict_proba(X_scaled)

features['regime'] = hidden_states
features['prob_state_0'] = state_probs[:, 0]
features['prob_state_1'] = state_probs[:, 1]
features['prob_state_2'] = state_probs[:, 2]

print(f"\nDistribution across regimes:")
print(features['regime'].value_counts().sort_index())

ขั้นตอนที่ 4: การตีความระบอบ

นี่คือจุดที่น่าสนใจ — และยุ่งยาก HMM ไม่รู้ว่าระบอบ 0 คือ "กระทิง" มันแค่หา cluster สามอันในพื้นที่ observation การกำหนดหมายเลขเป็นไปโดยสุ่มและอาจเปลี่ยนจาก run สู่ run

คุณต้องดูสถิติของแต่ละระบอบและกำหนด label ด้วยตนเอง:

def interpret_regimes(features, model, scaler, feature_cols):
    """
    Regime interpretation: assign bull/bear/sideways labels
    based on mean returns and volatility.
    """
    means_scaled = model.means_
    means_original = scaler.inverse_transform(means_scaled)

    regime_stats = {}
    for i in range(model.n_components):
        mask = features['regime'] == i
        regime_stats[i] = {
            'count': mask.sum(),
            'pct': mask.mean() * 100,
            'mean_return': features.loc[mask, 'log_return'].mean() * 100,
            'std_return': features.loc[mask, 'log_return'].std() * 100,
            'mean_vol': features.loc[mask, 'rolling_vol'].mean() * 100,
            'sharpe_daily': (features.loc[mask, 'log_return'].mean()
                           / features.loc[mask, 'log_return'].std())
        }
        print(f"\nRegime {i}: {regime_stats[i]['count']} days "
              f"({regime_stats[i]['pct']:.1f}%)")
        print(f"  Mean return:    {regime_stats[i]['mean_return']:.3f}%/day")
        print(f"  Volatility:     {regime_stats[i]['std_return']:.3f}%/day")
        print(f"  Sharpe (daily): {regime_stats[i]['sharpe_daily']:.3f}")

    sorted_by_return = sorted(regime_stats.keys(),
                               key=lambda x: regime_stats[x]['mean_return'])

    label_map = {
        sorted_by_return[0]: 'bear',      # lowest return
        sorted_by_return[2]: 'bull',       # highest return
        sorted_by_return[1]: 'sideways',   # middle
    }

    features['regime_label'] = features['regime'].map(label_map)
    return features, label_map

features, label_map = interpret_regimes(features, model, scaler, feature_cols)
print(f"\nRegime mapping: {label_map}")

ผลลัพธ์ทั่วไปสำหรับ BTC มีลักษณะประมาณนี้:

Regime 0: 412 days (23.8%)
  Mean return:    -0.182%/day
  Volatility:     4.127%/day
  Sharpe (daily): -0.044

Regime 1: 847 days (48.9%)
  Mean return:    0.021%/day
  Volatility:     1.634%/day
  Sharpe (daily): 0.013

Regime 2: 473 days (27.3%)
  Mean return:    0.312%/day
  Volatility:     2.851%/day
  Sharpe (daily): 0.109

Regime mapping: {0: 'bear', 1: 'sideways', 2: 'bull'}

สังเกต: ระบอบหมีไม่ได้มีแค่ผลตอบแทนติดลบ แต่ยังมีความผันผวนสูงที่สุด (4.1% เทียบกับ 1.6% ใน sideways) นี่คือการสังเกตเชิงประจักษ์แบบคลาสสิกที่รู้จักกันในชื่อ "leverage effect" — ตลาดที่ตกต่างมีความผันผวนมากกว่าตลาดที่ขึ้น

เมทริกซ์การเปลี่ยนสถานะและระยะเวลาระบอบ

เมทริกซ์ความน่าจะเป็นการเปลี่ยนสถานะเป็นหนึ่งใน artifacts ที่ให้ข้อมูลมากที่สุดของ HMM:

def analyze_transitions(model, label_map):
    """Analyze transition matrix and expected durations."""
    trans_mat = model.transmat_

    inv_map = {v: k for k, v in label_map.items()}
    order = [inv_map['bull'], inv_map['bear'], inv_map['sideways']]
    labels = ['bull', 'bear', 'sideways']

    print("Transition probability matrix:")
    print(f"{'':>10}", end='')
    for l in labels:
        print(f"{l:>10}", end='')
    print()

    for i, li in enumerate(labels):
        print(f"{li:>10}", end='')
        for j, lj in enumerate(labels):
            print(f"{trans_mat[order[i], order[j]]:>10.3f}", end='')
        print()

    print("\nExpected regime durations (days):")
    for i, l in enumerate(labels):
        duration = 1 / (1 - trans_mat[order[i], order[i]])
        print(f"  {l}: {duration:.1f} days")

analyze_transitions(model, label_map)

ผลลัพธ์ทั่วไป:

Transition probability matrix:
               bull      bear  sideways
      bull    0.952     0.018     0.030
      bear    0.031     0.937     0.032
   sideways   0.043     0.027     0.930

Expected regime durations (days):
  bull: 20.8 days
  bear: 15.9 days
  sideways: 14.3 days

สิ่งที่เราสังเกต:

  1. ระบอบมีความ "เหนียว": ความน่าจะเป็นที่จะอยู่ในระบอบปัจจุบันสูงกว่า 93% สำหรับทุกสถานะ
  2. ระบอบกระทิงอยู่นานกว่า หมี (20.8 เทียบกับ 15.9 วัน) — ตลาดขึ้นช้ากว่าที่ตก
  3. การเปลี่ยนจากกระทิงไปหมีโดยตรงไม่น่าจะเกิดขึ้น (1.8%) — โดยปกติตลาดผ่านระยะ sideways

จุดสุดท้ายสมเหตุสมผลทางเศรษฐกิจ: ตลาดแทบไม่กลับทิศทางทันที โดยทั่วไปจะมีระยะการกระจาย (sideways ที่จุดสูงสุด) ก่อนตลาดหมี และระยะการสะสม (sideways ที่จุดต่ำสุด) ก่อนตลาดกระทิง

กลยุทธ์การเทรด: หนึ่งระบอบ — หนึ่งกลยุทธ์

ตอนนี้เราประยุกต์สิ่งที่เรียนรู้มา แนวคิด: อย่าเทรดด้วยกลยุทธ์เดียวตลอดเวลา แต่สลับกลยุทธ์ขึ้นอยู่กับระบอบที่ตรวจพบ

กระทิง → Momentum เชิงรุก

  • ขนาด position เพิ่มขึ้น (ถึง 100% ของทุน)
  • กลยุทธ์เทรนด์: breakout ตาม moving average
  • Stop-loss กว้าง (ไม่ถูก stop ออกใน pullback)
  • ไม่ short (หรือ short น้อยที่สุด)

หมี → เชิงรับ / Position ขาย

  • ขนาด position ลดลง (30-50% ของทุน)
  • กลยุทธ์ short หรือเงินสดเต็มจำนวน
  • Stop-loss แคบ
  • Hedging ผ่าน put options หรือ futures

Sideways → Mean-Reversion / Grid

  • ขนาด position ปานกลาง (50-70% ของทุน)
  • กลยุทธ์ grid trading
  • Mean-reversion: ซื้อที่ขอบล่าง ขายที่ขอบบน
  • Market-making ด้วย spread แคบ
def regime_adaptive_strategy(features, initial_capital=10000):
    """
    Simple regime-adaptive strategy.
    Bull: long 100%, Bear: short 50%, Sideways: long 30%.
    """
    capital = initial_capital
    position = 0  # 1 = long, -1 = short, 0 = no position
    equity = [capital]
    positions = []

    for i in range(1, len(features)):
        regime = features.iloc[i]['regime_label']
        ret = features.iloc[i]['log_return']

        if regime == 'bull':
            target_exposure = 1.0   # 100% long
        elif regime == 'bear':
            target_exposure = -0.5  # 50% short
        elif regime == 'sideways':
            target_exposure = 0.3   # 30% long (or grid)
        else:
            target_exposure = 0.0

        daily_pnl = capital * target_exposure * ret

        capital += daily_pnl
        equity.append(capital)
        positions.append(target_exposure)

    features = features.copy()
    features['equity'] = equity
    features['position'] = [0] + positions

    return features

Backtest: กลยุทธ์ HMM-Adaptive เทียบกับ Buy-and-Hold

ตอนนี้คำถามหลัก: สิ่งนี้ทำงานได้ดีกว่า Buy-and-Hold ธรรมดาหรือไม่?

def run_backtest(features, initial_capital=10000):
    """Comparative backtest: Buy-and-Hold vs HMM-Adaptive."""

    cumulative_returns = (1 + features['log_return']).cumprod()
    bnh_equity = initial_capital * cumulative_returns

    features = regime_adaptive_strategy(features, initial_capital)

    def calc_metrics(equity_series):
        returns = pd.Series(equity_series).pct_change().dropna()
        total_return = (equity_series.iloc[-1] / equity_series.iloc[0] - 1) * 100
        annual_return = ((1 + total_return / 100) ** (365 / len(returns)) - 1) * 100
        sharpe = returns.mean() / returns.std() * np.sqrt(365)
        max_dd = ((equity_series / equity_series.cummax()) - 1).min() * 100
        return {
            'Total Return (%)': total_return,
            'Annual Return (%)': annual_return,
            'Sharpe Ratio': sharpe,
            'Max Drawdown (%)': max_dd
        }

    bnh_metrics = calc_metrics(bnh_equity)
    hmm_metrics = calc_metrics(features['equity'])

    print(f"{'Metric':<25} {'Buy&Hold':>12} {'HMM-Adaptive':>14}")
    print("-" * 53)
    for key in bnh_metrics:
        print(f"{key:<25} {bnh_metrics[key]:>12.2f} {hmm_metrics[key]:>14.2f}")

    return features, bnh_equity

features, bnh_equity = run_backtest(features)

ผลลัพธ์ Backtest การเปรียบเทียบเส้นโค้ง equity: Buy-and-Hold (น้ำเงิน) และกลยุทธ์ HMM-adaptive (ส้ม) กลยุทธ์ adaptive ลด drawdown ในช่วงหมีได้อย่างมีนัยสำคัญ

ผลลัพธ์ทั่วไปสำหรับ BTC (2020-2025):

Metric                     Buy&Hold   HMM-Adaptive
-----------------------------------------------------
Total Return (%)             487.32         623.18
Annual Return (%)             42.71          49.84
Sharpe Ratio                   1.12           1.68
Max Drawdown (%)             -76.42         -38.17

การสังเกตหลัก: กลยุทธ์ HMM-adaptive ไม่ได้ให้ผลตอบแทนรวมสูงกว่าเสมอไป (แม้ว่าในกรณีนี้จะทำได้) แต่มัน ลด maximum drawdown ได้อย่างมาก — จาก 76% เหลือ 38% Sharpe เพิ่มจาก 1.12 เป็น 1.68 นี่คือการปรับปรุงผลตอบแทนที่ปรับตามความเสี่ยง ไม่ใช่แค่ "เงินมากขึ้น"

ทำไม? เพราะในระบอบหมี กลยุทธ์เปลี่ยนเป็นโหมดเชิงรับหรือ short หลีกเลี่ยงการ crash ครั้งใหญ่ ต้นทุนคือการเข้าเทรนด์ล่าช้า (โมเดลตรวจจับระบอบกระทิงด้วยความล่าช้าสองสามวัน) และการสลับผิดในช่วงเปลี่ยนผ่าน

การแสดงผล

import matplotlib.pyplot as plt
import matplotlib.dates as mdates

fig, axes = plt.subplots(3, 1, figsize=(14, 10), sharex=True)

axes[0].plot(features.index, bnh_equity, label='Buy & Hold', alpha=0.8)
axes[0].plot(features.index, features['equity'], label='HMM-Adaptive', alpha=0.8)
axes[0].set_ylabel('Capital ($)')
axes[0].legend()
axes[0].set_title('Equity Curve: Buy & Hold vs HMM-Adaptive')

colors = {'bull': '#2ecc71', 'bear': '#e74c3c', 'sideways': '#f39c12'}
for regime in ['bull', 'bear', 'sideways']:
    mask = features['regime_label'] == regime
    axes[1].scatter(features.index[mask], df.loc[features.index[mask], 'close'],
                    c=colors[regime], s=2, label=regime, alpha=0.7)
axes[1].set_ylabel('BTC Price ($)')
axes[1].set_yscale('log')
axes[1].legend()
axes[1].set_title('BTC Price Colored by Regime')

for i, (regime, color) in enumerate(colors.items()):
    inv_map = {v: k for k, v in label_map.items()}
    state_idx = inv_map[regime]
    axes[2].fill_between(features.index,
                          features[f'prob_state_{state_idx}'],
                          alpha=0.4, color=color, label=regime)
axes[2].set_ylabel('Regime Probability')
axes[2].legend()
axes[2].set_title('Posterior Regime Probabilities')

plt.tight_layout()
plt.savefig('hmm_backtest.png', dpi=150)
plt.show()

เทคนิคขั้นสูง

HMM พื้นฐานเป็นจุดเริ่มต้นที่ดี แต่ไม่ใช่ขีดจำกัด

Hierarchical HMM

ใน hierarchical HMM ระดับบนกำหนด "macro-regime" (เทรนด์ทั่วโลก วัฏจักรรายปี) และระดับล่างกำหนด "micro-regime" (ความผันผวนภายในสัปดาห์/ภายในเดือน) แพ็คเกจ fHMM สำหรับ R ที่ตีพิมพ์ใน Journal of Statistical Software ปี 2024 (Oelschlager, Adam, Michels) นำแนวคิดนี้มาใช้สำหรับ financial time series

ตัวอย่าง: macro-regime "bull cycle" มี micro-regime "rally" "correction" และ "consolidation" อยู่ภายใน สิ่งนี้ป้องกันการตื่นตระหนกกับทุก pullback 10% ในตลาดกระทิง — โมเดลเข้าใจว่าการ correction ภายใน bull cycle เป็นเรื่องปกติ

Multivariate HMM พร้อม Feature ขยาย

แทนที่จะใช้ returns แบบ univariate เราป้อน feature vector: returns + ความผันผวน + ปริมาณ + on-chain data สิ่งนี้ช่วยให้โมเดล "มองเห็น" ข้อมูลมากขึ้นเกี่ยวกับสถานะตลาด

from hmmlearn.hmm import GaussianHMM

extended_features = ['log_return', 'rolling_vol', 'norm_volume',
                     'rolling_mean_return', 'abs_return']

X_extended = features[extended_features].values
scaler_ext = StandardScaler()
X_ext_scaled = scaler_ext.fit_transform(X_extended)

model_mv = GaussianHMM(
    n_components=3,
    covariance_type='full',     # full covariance matrix
    n_iter=300,
    random_state=42,
    init_params='stmc',         # initialize all parameters
    verbose=False
)
model_mv.fit(X_ext_scaled)

n_params_base = 3 * (3 + 3 + 3*4/2) + 3*2    # simplified estimate
n_params_ext = 3 * (5 + 5 + 5*6/2) + 3*2

bic_base = -2 * model.score(X_scaled) * len(X_scaled) + n_params_base * np.log(len(X_scaled))
bic_ext = -2 * model_mv.score(X_ext_scaled) * len(X_ext_scaled) + n_params_ext * np.log(len(X_ext_scaled))

print(f"BIC base model:     {bic_base:.0f}")
print(f"BIC extended model: {bic_ext:.0f}")
print(f"Extended is better: {bic_ext < bic_base}")

HMM + ML Ensemble

แนวทางสมัยใหม่: ใช้ HMM ไม่ใช่เป็นระบบการเทรด แต่เป็น generator ของ feature สำหรับโมเดล downstream แนวคิดที่อธิบายใน Gupta et al. (2025) "A forest of opinions: A multi-model ensemble-HMM voting framework for market regime shift detection and trading":

  1. HMM กำหนดระบอบปัจจุบัน (หรือความน่าจะเป็นของระบอบ)
  2. ระบอบถูกป้อนเป็น feature เพิ่มเติมให้ Random Forest / Gradient Boosting
  3. โมเดล ML ตัดสินใจการเทรดเฉพาะเจาะจงโดยคำนึงถึงระบอบ
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import TimeSeriesSplit

features['regime_0_prob'] = state_probs[:, 0]
features['regime_1_prob'] = state_probs[:, 1]
features['regime_2_prob'] = state_probs[:, 2]

features['target'] = (features['log_return'].shift(-1) > 0).astype(int)

ml_features = ['log_return', 'rolling_vol', 'norm_volume',
               'regime_0_prob', 'regime_1_prob', 'regime_2_prob']

X_ml = features[ml_features].dropna()
y_ml = features.loc[X_ml.index, 'target'].dropna()

common_idx = X_ml.index.intersection(y_ml.index)
X_ml = X_ml.loc[common_idx]
y_ml = y_ml.loc[common_idx]

tscv = TimeSeriesSplit(n_splits=5)
scores = []

for train_idx, test_idx in tscv.split(X_ml):
    X_train, X_test = X_ml.iloc[train_idx], X_ml.iloc[test_idx]
    y_train, y_test = y_ml.iloc[train_idx], y_ml.iloc[test_idx]

    clf = GradientBoostingClassifier(n_estimators=100, max_depth=3, random_state=42)
    clf.fit(X_train, y_train)
    score = clf.score(X_test, y_test)
    scores.append(score)

print(f"Walk-Forward Accuracy: {np.mean(scores):.3f} +/- {np.std(scores):.3f}")

Production: กับดัก

backtest ที่สวยงามเป็นแค่ครึ่งหนึ่งของงาน ใน production มีเซอร์ไพรส์ที่ไม่น่าพึงใจรอคุณอยู่หลายอย่าง

ปัญหาความล่าช้า (Look-Ahead Bias)

HMM กำหนดระบอบจากข้อมูลปัจจุบันและในอดีต แต่ใน backtest มีความล่อใจที่จะฝึกโมเดลบนชุดข้อมูลทั้งหมดรวมถึงข้อมูลในอนาคต นี่คือ look-ahead bias และมันเปลี่ยน backtest ให้กลายเป็นนิยาย

วิธีแก้: แนวทาง Walk-Forward ฝึกโมเดลบนข้อมูลถึงเวลา tt ทำนายระบอบ ณ เวลา tt จากนั้นเลื่อน window ตรงตามที่อธิบายในบทความของเราเรื่อง Walk-Forward Optimization

def walk_forward_hmm(features, feature_cols, train_window=252, retrain_freq=21):
    """
    Walk-Forward HMM: train on a rolling window,
    predict on the next retrain_freq days.
    """
    regimes_wf = pd.Series(index=features.index, dtype=float)

    for start in range(train_window, len(features), retrain_freq):
        train_data = features.iloc[start - train_window:start]
        X_train = train_data[feature_cols].values

        scaler = StandardScaler()
        X_train_scaled = scaler.fit_transform(X_train)

        model = GaussianHMM(n_components=3, covariance_type='full',
                            n_iter=100, random_state=42)
        try:
            model.fit(X_train_scaled)
        except Exception:
            continue

        end = min(start + retrain_freq, len(features))
        test_data = features.iloc[start:end]
        X_test = test_data[feature_cols].values
        X_test_scaled = scaler.transform(X_test)

        predicted = model.predict(X_test_scaled)
        regimes_wf.iloc[start:end] = predicted

    return regimes_wf

ตารางการฝึกใหม่

ควรฝึกโมเดลใหม่บ่อยแค่ไหน? น้อยเกินไป — โมเดลล้าสมัย ตลาดเปลี่ยนแปลง บ่อยเกินไป — โมเดลไม่เสถียร ระบอบ "กระโดด"

คำแนะนำเชิงประจักษ์:

  • สำหรับ daily data: ฝึกใหม่ทุก 1-4 สัปดาห์ (21 วันทำการเป็น default ที่ดี)
  • Training window: 6-12 เดือน (252 วันทำการ — หนึ่งปี)
  • Monitoring: ถ้า log-likelihood บนข้อมูลใหม่ต่ำกว่าเกณฑ์ — ฝึกใหม่แบบไม่ตามกำหนด

ความไม่เสถียรของ Label

เมื่อฝึกใหม่แต่ละครั้ง การกำหนดหมายเลขสถานะอาจเปลี่ยน: สิ่งที่เคยเป็น "ระบอบ 0" (กระทิง) อาจกลายเป็น "ระบอบ 2" คุณต้องจับคู่สถานะโดยอัตโนมัติด้วยสถิติของมัน (ผลตอบแทนเฉลี่ย ความผันผวน)

การอัปเดตออนไลน์

สำหรับการเทรดแบบ real-time การฝึกใหม่เต็มรูปแบบทุกวันเป็นสิ่งเกินความจำเป็น คุณสามารถใช้ Forward filtering: fix พารามิเตอร์โมเดล แต่อัปเดตความน่าจะเป็นสถานะ posterior ด้วย observation ใหม่แต่ละอัน นี่เป็น operation ที่ทำได้ทันที

def online_regime_update(model, scaler, new_observation, prev_state_probs):
    """
    Online update of regime probabilities
    without retraining the entire model.
    """
    obs_scaled = scaler.transform(new_observation.reshape(1, -1))

    from scipy.stats import multivariate_normal
    emission_probs = np.array([
        multivariate_normal.pdf(obs_scaled[0],
                                 mean=model.means_[i],
                                 cov=model.covars_[i])
        for i in range(model.n_components)
    ])

    transition = model.transmat_.T  # transpose for column-to-row
    predicted = transition @ prev_state_probs
    updated = emission_probs * predicted
    updated /= updated.sum()  # normalization

    return updated

การเลือกจำนวนสถานะ

แม้ว่าสามระบอบจะเป็น default ที่ดี ควรทดสอบทางเลือกอื่น:

from hmmlearn.hmm import GaussianHMM

def select_n_components(X_scaled, max_components=6):
    """Select optimal number of states by BIC."""
    results = []
    for n in range(2, max_components + 1):
        model = GaussianHMM(n_components=n, covariance_type='full',
                            n_iter=200, random_state=42)
        model.fit(X_scaled)

        log_likelihood = model.score(X_scaled) * len(X_scaled)
        n_features = X_scaled.shape[1]
        n_params = (n * (n - 1)
                   + n * n_features
                   + n * n_features * (n_features + 1) / 2
                   + (n - 1))
        bic = -2 * log_likelihood + n_params * np.log(len(X_scaled))

        results.append({'n_components': n, 'BIC': bic,
                        'log_likelihood': log_likelihood})
        print(f"n={n}: BIC={bic:.0f}, LL={log_likelihood:.0f}")

    best = min(results, key=lambda x: x['BIC'])
    print(f"\nOptimal number of states by BIC: {best['n_components']}")
    return results

results = select_n_components(X_scaled)

ข้อจำกัดและข้อควรระวัง

การเงียบเรื่องปัญหาจะไม่ซื่อสัตย์

สมมติฐาน Gaussian GaussianHMM พื้นฐานสมมติว่าผลตอบแทนในแต่ละระบอบกระจายตัวแบบปกติ การกระจายตัวจริงมี fat tail และความไม่สมมาตร วิธีแก้บางส่วนคือการใช้การกระจาย Student-t หรือ GMMHMM (Gaussian Mixture ต่อสถานะ)

จำนวนสถานะเป็นตัวเลือกของคุณ BIC ช่วย แต่ไม่เสมอไปที่จะสรุปผลได้ นักวิจัยสองคนที่แตกต่างกันอาจได้จำนวนระบอบต่างกันและทั้งคู่จะ "ถูก"

ช่วงการเปลี่ยนผ่าน โมเดลไม่แน่ใจในช่วงการเปลี่ยนระบอบ ความน่าจะเป็นกระจายตัวในสัดส่วนใกล้เคียงกัน และกลยุทธ์ได้รับสัญญาณที่ "เบลอ" วิธีแก้คือกฎ threshold: เปลี่ยนกลยุทธ์เมื่อความน่าจะเป็นของระบอบใหม่เกิน 70-80% เท่านั้น

Overfitting เช่นเดียวกับโมเดลใดๆ HMM สามารถ overfit ได้ โดยเฉพาะอย่างยิ่งกับสถานะหรือ feature จำนวนมาก Walk-Forward validation เป็นสิ่งจำเป็น

ปัญหาเฉพาะ Crypto ตลาด cryptocurrency ยังอายุน้อยและโครงสร้างไม่เสถียร "bull market" ปี 2017 และ "bull market" ปี 2024 เป็นปรากฏการณ์ที่แตกต่างกันทางสถิติ โมเดลอาจไม่ generalize ข้ามรอบ

อ่านเพิ่มเติม

สำหรับผู้ที่ต้องการเจาะลึกกว่านี้:

ผลงานพื้นฐาน:

  • Hamilton, J.D. (1989). A New Approach to the Economic Analysis of Nonstationary Time Series and the Business Cycle. Econometrica, 57(2), 357-384. — ผลงานพื้นฐานเกี่ยวกับโมเดล Markov-switching
  • Guidolin, M., & Timmermann, A. (2007). Asset Allocation under Multivariate Regime Switching. Journal of Economic Dynamics and Control, 31(11), 3503-3544. — การประยุกต์ใช้จริงกับการจัดสรรสินทรัพย์
  • Ang, A., & Bekaert, G. (2002). Regime Switches in Interest Rates. Journal of Business & Economic Statistics, 20(2), 163-182. — ระบอบในอัตราดอกเบี้ย

การวิจัยสมัยใหม่:

  • Gupta, R., Kapoor, S., Gupta, H., & Natesan, S. (2025). A forest of opinions: A multi-model ensemble-HMM voting framework for market regime shift detection and trading. Data Science in Finance and Economics. — แนวทาง ensemble สำหรับการตรวจจับระบอบ
  • Oelschlager, L., Adam, T., & Michels, R. (2024). fHMM: Hidden Markov Models for Financial Time Series in R. Journal of Statistical Software. — Hierarchical HMM สำหรับการเงิน
  • Bitcoin Price Regime Shifts: A Bayesian MCMC and Hidden Markov Model Analysis of Macroeconomic Influence. Mathematics, 2025. — HMM สำหรับ Bitcoin ด้วยแนวทาง Bayesian

คู่มือปฏิบัติ:

บทสรุป

Hidden Markov Models ไม่ใช่ silver bullet แต่เป็นเครื่องมือ เครื่องมือที่มีประโยชน์ มีรากฐานทางคณิตศาสตร์ ด้วยประวัติครึ่งศตวรรษในทางสถิติและสามทศวรรษในทางการเงิน

คุณค่าหลักของ HMM สำหรับการเทรดไม่ใช่ที่มัน "ทำนายตลาด" (ไม่มีใครทำได้) แต่มันทำให้สัญชาตญาณของ trader ที่มีประสบการณ์เป็นรูปธรรม: ตลาดผ่านระยะต่างๆ และกลยุทธ์ต้องปรับตัว แทนที่จะเป็น "ฉันรู้สึกว่าตลาดกำลังเป็นหมีตอนนี้" แบบอัตวิสัย คุณได้ "ความน่าจะเป็นของระบอบหมีคือ 82% ระยะเวลาเฉลี่ยของ bear cycle คือ 16 วัน เราอยู่ในวันที่ 5"

ควรรวม HMM เข้า trading stack ของคุณหรือไม่? ถ้าคุณมีหลายกลยุทธ์สำหรับเงื่อนไขตลาดต่างกันและเหนื่อยกับการสลับด้วยตนเอง — ใช่อย่างแน่นอน ถ้าคุณเทรดกลยุทธ์เดียวและไม่ได้วางแผนขยาย — เก็บไว้ก่อนได้ แต่จำไว้

และอย่าลืม: โมเดลที่ดีที่สุดคือโมเดลที่ทำงานได้ใน production ไม่ใช่โมเดลที่ชนะ backtest


อ้างอิง: ถ้าคุณใช้เนื้อหาจากบทความนี้ในการวิจัยหรือโปรเจกต์ของคุณ กรุณาอ้างอิง:

Hidden Markov Models in Trading: How to Adapt Your Strategy to Market Regimes. marketmaker.cc, 2026. URL: https://marketmaker.cc/th/blog/post/regime-detection-hmm-adaptive-trading

ข้อจำกัดความรับผิดชอบ: ข้อมูลที่ให้ไว้ในบทความนี้มีไว้เพื่อการศึกษาและให้ข้อมูลเท่านั้น และไม่ถือเป็นคำแนะนำทางการเงิน การลงทุน หรือการเทรด การเทรดสกุลเงินดิจิทัลมีความเสี่ยงสูงที่จะขาดทุน

ผู้เขียน

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 เฉพาะ การวิเคราะห์ตลาด และการอัปเดตแพลตฟอร์ม

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