Chu kỳ tích luỹ trên TTCK Việt Nam — 487 episodes, macro overlay & feature importance
Nghiên cứu event-driven trên toàn bộ universe VN thanh khoản >500M VND/ngày. Detect, classify outcome, phân tích yếu tố tác động tới xác suất bùng nổ sau tích luỹ.
Tóm lược điều hành
Báo cáo này trả lời một câu hỏi thực tế mà nhiều nhà đầu tư VN đã đặt ra nhưng chưa từng có nghiên cứu quy mô lớn nào giải đáp: "Mua cổ phiếu đang đi ngang sau khi giảm sâu — tỷ lệ thắng thực sự bao nhiêu?" Chúng tôi quét toàn bộ 471 mã VN thanh khoản cao (khớp lệnh trung bình > 500 triệu VND/phiên) trong 10 năm (2016–2025), phát hiện và phân tích 487 chu kỳ tích luỹ theo tiêu chí Wyckoff chặt chẽ.
Kết quả chính: 6 trên 10 setup tích luỹ đúng chuẩn đều bứt phá ≥ +15% trong 3 tháng tiếp theo. Hơn 3 trên 10 bùng nổ mạnh ≥ +30%. Chỉ 3% thất bại hoàn toàn. Nhưng khác biệt giữa "thắng lớn" và "lỗ nhỏ" phụ thuộc vào 3 yếu tố mà nhiều NĐT bỏ qua: (1) trạng thái VN-Index trong giai đoạn tích luỹ, (2) mức độ drawdown trước đó, và (3) ngành / vốn hoá.
Phát hiện thực tế nhất: Nếu VN-Index giảm > 5% trong thời gian cổ phiếu đang tích luỹ, tỷ lệ bùng nổ mạnh rơi xuống chỉ 7.6% — gần như không còn edge. Ngược lại, khi VN-Index tăng > 15%, tỷ lệ nhảy lên 46.2%. Chênh lệch 38 điểm phần trăm — lớn hơn mọi yếu tố kỹ thuật nội tại. Kết luận: bối cảnh thị trường chung là điều kiện lọc bắt buộc, không phải tuỳ chọn.
Báo cáo cũng loại trừ một số niềm tin phổ biến: PE thấp, ROE cao không có predictive power đáng tin cậy (sample quá nhỏ 104/471 mã có fundamentals point-in-time). Ngân hàng — vốn được coi là "an toàn" — thực tế là ngành tệ nhất với 6.7% tỷ lệ bùng nổ mạnh. Mô hình hồi quy 11 yếu tố đạt độ chính xác 68.6% dự báo trong mẫu, chưa walk-forward validate — khuyến nghị thận trọng và kết hợp với chiến lược HUNTER V2 hiện có như một lớp filter bổ sung.
Điều cần nhớ · 5 nguyên tắc thực chiến
Chắt lọc hành động cụ thể từ 487 episodes — trước khi đi vào chi tiết methodology.
-
1
Luôn xác định trạng thái VN-Index trước khi mở vị thế. Không bao giờ mở mới khi VNI đang điều chỉnh > 5% — lịch sử cho thấy edge biến mất hoàn toàn. Đợi VNI hồi phục hoặc chuyển side-way rồi mới hành động.
-
2
Tìm cổ phiếu đã giảm sâu, không phải cổ phiếu đang uptrend. Mức drawdown từ đỉnh 52-tuần ≥ 70% là sweet spot — tỷ lệ bùng nổ mạnh gấp 1.8× trung bình. Đây là "bottom fishing có kỷ luật", không phải "đu đỉnh điều chỉnh".
-
3
Ưu tiên mid-cap vốn hoá 5.000–10.000 tỷ, tránh ngân hàng. Tỷ lệ bùng nổ mạnh: mid-cap 37% · large-cap 18.8% · ngân hàng chỉ 6.7%. Quỹ Hunter V2 hiện áp dụng rule này — loại bỏ sector bank khỏi universe tích luỹ.
-
4
Chờ biên độ thắt lại ở cuối tích luỹ (coiling pattern). Range 30 phiên cuối < range 30 phiên đầu là signature Wyckoff — cũng là yếu tố có trọng số cao nhất trong mô hình hồi quy (coefficient -1.27). Không có coiling → không vào lệnh.
-
5
Đủ thời gian — ít nhất 30 phiên tích luỹ. Duration dưới 30 phiên không phải "tích luỹ" mà là "consolidation ngắn hạn" — dễ breakout giả. 90-180 phiên là khung lý tưởng: đủ để smart money gom hàng, chưa quá dài để retail lost interest.
Keywords: Wyckoff accumulation breakout pattern VN-Index regime macro overlay institutional research
1.Bối cảnh & câu hỏi nghiên cứu
Lý thuyết Wyckoff chia chu kỳ giá thành 4 pha — tích luỹ → markup → phân phối → markdown. Pha tích luỹ là "cửa sổ vàng": giá đi ngang trong biên hẹp sau drawdown, volatility co lại trước breakout. Minervini hệ thống hoá thành VCP, O'Neil đưa vào CANSLIM dạng "base". Vấn đề: phần lớn tài liệu dùng backtest narrative/cherry-pick, chưa có nghiên cứu empirical quy mô toàn universe cho TTCK VN.
Báo cáo này trả lời 3 câu hỏi:
- Q1 — Base rate: pattern tích luỹ có cho breakout ≥ 15% trong 90d với tần suất cao hơn random không?
- Q2 — Feature importance: features nội tại nào có predictive power thực sự?
- Q3 — External overlay: macro (VN-Ix regime, trend) và vi mô (sector, cap, PE, ROE) có tác động độc lập và lớn cỡ nào so với features nội tại?
Phương pháp: event-driven, walk-forward outcome không lookahead, segment analysis + logistic regression, trên 487 episodes / 471 mã / 2016-01 → 2025-12.
2.Dữ liệu & Universe
2.1 Nguồn dữ liệu
| Loại dữ liệu | Nguồn | Tần suất | Coverage | Ghi chú |
|---|---|---|---|---|
| OHLCV daily | vnstock (VCI/TCBS/DNSE) | Daily close EOD | 489 mã + VNINDEX | 2012-01 trở đi, adjusted |
| Fundamentals snapshot | composite_score.csv (CafeF API) | Snapshot 2026-04 | 104 mã (21% universe) | ⚠️ KHÔNG point-in-time |
| VN-Index regime (HMM) | strat_a_regime_equity.csv | Daily | 2012-01 → 2026-04 | 3-state HMM fit on VNI returns + vol |
| Sector classification | composite_score.csv | Snapshot | 104 mã | 15+ sectors, top 5 có n≥5 |
2.2 Universe construction
| Filter stage | Threshold | N remaining | % filtered |
|---|---|---|---|
| Raw parquet files (exclude VNINDEX) | — | 489 | — |
| Có ≥ 400 bars data (≥1.6 năm) | MIN_BARS = 400 | 471 | -3.7% |
| Liquidity ≥ 500M VND/ngày (rolling 60d, any time) | ADV60 > 500M | 471 | 0% |
| Universe cuối dùng cho scan | — | 471 | 96.3% of raw |
| Có detect ít nhất 1 episode | duration ≥ 30d | 312 | 66.2% hit rate |
| Tổng episodes detected | — | 487 | ~1.56 episodes/mã qualified |
| Resolved (có 90d forward data) | end ≤ 2025-12-31 - 90d | 487 (100%) | — |
2.3 Phân phối episodes theo năm
Episode start dates trải đều 2016-2025. Không có năm nào chiếm >15% tổng episodes, giảm time-bucket bias. Các giai đoạn hấp dẫn: 2016-17 (post-2015 bear), 2020-21 (COVID bottom fishing), 2022-23 (margin crash recovery). Giai đoạn 2024 có ít episodes hơn vì regime uptrend mạnh → ít mã đủ điều kiện dist_from_peak ≥ 25%.
Universe 471 mã bao gồm cả mã đã delist và đã thay mã trong parquet folder (data pipeline giữ cả historical tickers). Tuy vậy fundamentals snapshot chỉ có 104 mã → segment analysis theo sector/PE/ROE vẫn bị bias: mã đã delist không có PE/ROE hiện tại. Price-based analysis (duration, range, ATR, dist_from_peak, volume flow, regime, VN-Ix trend) KHÔNG bị survivorship bias này.
3.Phương pháp event-driven
3.1 Định nghĩa accumulation (deterministic, không ambiguous)
Một bar được classify là "accumulation" khi đồng thời thoả bốn điều kiện:
close < MA200 # dưới trend dài hạn dist_from_52w_high ≥ 25% # drawdown đáng kể range_60d / low_60d ≤ 30% # biên độ hẹp atr20 / atr100 ≤ 0.80 # volatility contraction
Biện luận: (i) loại uptrend mạnh — chỉ quan tâm mã đang hồi phục; (ii) đòi drawdown thực sự; (iii) biên hẹp đặc trưng phase B/C; (iv) volatility compression (Minervini VCP).
3.2 Aggregate thành episodes
Chuỗi bar tích luỹ liên tiếp (tolerate gap ≤ 3 bars) ≥ 30 phiên = 1 episode. END = bar tích luỹ cuối trước phase transition. Tolerance 3 bars để bỏ qua 1-3 bar spike tạm thời (earnings, ex-dividend).
3.3 Outcome classification (walk-forward 90 ngày)
| Class | Criteria | Ý nghĩa |
|---|---|---|
| Strong | max_ret ≥ +30% | Bùng nổ mạnh — thesis hoàn hảo |
| Moderate | +15% ≤ max_ret < +30% | Breakout vừa phải |
| Weak | 0 ≤ max_ret < +15% | Chậm, chưa confirmed |
| Failed | max_ret < 0% | Breakdown thất bại |
3.4 Anti-lookahead verification
Toàn bộ pipeline đã được audit về lookahead. Ba điểm cần kiểm tra:
- Features tại episode end: tất cả features (ATR, volume flow, range) tính trên window
[0..end], không bao gồm bar tương lai._build_episodechỉ truy cậpdf.iloc[start:end+1]. - Rolling windows:
atr20 = atr14.rolling(20).mean()vàatr100 = atr14.rolling(100).mean()đều causal —.iloc[end]chỉ trả giá trị tính từ data ≤ end. - dist_from_peak: dùng
df.iloc[:start+1].tail(252).max()— peak trong 252 bars kết thúc tại start bar. Bias nhỏ nếu start = local low (trường hợp điển hình cho accumulation) → dist hơi lower bound → conservative.
Outcome được đo với close giao dịch, không dùng high intraday → loại được shakeout/wicks noise. Forward window bắt đầu từ end_idx + 1 (T+1 earliest re-entry).
4.Base rate & phân phối outcome
5.Feature nội tại — chart structure
5.1 Duration (độ dài tích luỹ)
| Duration | N | P(strong) | P(strong+mod) | Failed% | Median max_ret |
|---|---|---|---|---|---|
| 30-40d | 214 | 31.3% | 57.0% | 4.7% | +18.77% |
| 40-60d | 190 | 33.2% | 63.7% | 2.6% | +20.57% |
| 60-90d | 71 | 29.6% | 69.0% | 0.0% | +19.04% |
| 90-120d | 8 | 12.5% | 37.5% | 0.0% | +9.18% |
Sweet spot 40-60 ngày. Tích luỹ > 90d drop P(strong) xuống 12.5% (overstaying welcome). < 40d có thể chưa hoàn tất re-accumulation.
5.2 Range tightness (biên độ episode)
| Range % | N | P(strong) | P(strong+mod) | Median max_ret |
|---|---|---|---|---|
| <15% (quá hẹp) | 182 | 25.3% | 57.1% | +18.30% |
| 15-25% | 243 | 36.2% | 63.0% | +20.58% |
| 25-35% | 62 | 29.0% | 62.9% | +17.48% |
Sweet spot 15-25% — tight but not dead. <15% thường là phase A/early B (chưa test supply). >25% volatility còn cao, compression chưa đủ.
5.3 Distance from peak at start — predictor nội tại mạnh nhất
| Dist from peak | N | P(strong) | P(strong+mod) | Median max_ret |
|---|---|---|---|---|
| 25-35% | 212 | 19.8% | 50.9% | +15.31% |
| 35-50% | 159 | 34.0% | 61.6% | +19.64% |
| 50-70% | 86 | 45.3% | 74.4% | +27.95% |
| >70% | 30 | 56.7% | 86.7% | +38.02% |
Capitulation càng sâu → breakout càng mạnh (Chart 2). Monotonic 19.8% → 56.7% — gấp ~1.8x base rate.
5.4 ATR contraction — compression depth
| ATR20/ATR100 | N | P(strong) | P(strong+mod) | Median max_ret |
|---|---|---|---|---|
| <0.50 (rất tight) | 33 | 45.5% | 66.7% | +25.54% |
| 0.50-0.60 | 28 | 35.7% | 75.0% | +19.57% |
| 0.60-0.70 | 63 | 34.9% | 66.7% | +22.53% |
| 0.70-0.80 | 363 | 28.9% | 58.1% | +18.22% |
ATR compression monotonic: band <0.50 cho P(strong) 45.5% (~1.5x base). Textbook VCP — compression sâu → tích năng lượng → breakout mạnh. Threshold thực tế ≤ 0.60.
5.5 Volume flow — phản trực giác
Buy volume proxy = volume × (close-low)/(high-low). Sell proxy = volume × (high-close)/(high-low). Ratio đo flow dominance trong episode.
| Buy/Sell ratio | N | P(strong) |
|---|---|---|
| < 0.85 (sell-heavy) | 157 | 29.9% |
| 0.85-0.95 | 38 | 36.8% |
| 0.95-1.05 (balanced) | 63 | 38.1% |
| 1.05-1.15 | 40 | 37.5% |
| > 1.15 (buy-heavy) | 189 | 27.5% |
Flow balanced (0.95-1.05) cho precision cao nhất 38.1%. Buy-heavy (>1.15) chỉ 27.5% — retail đã FOMO, setup lộ. Sell-heavy (<0.85) 29.9% — distribution thật. Wyckoff "effort vs result".
6.Yếu tố vĩ mô — VN-Index
Gap macro 38pp lớn hơn bất kỳ internal feature nào. Bất kể pattern đẹp đến đâu, VN-Index downtrend mạnh gần như triệt tiêu xác suất bùng nổ.
| VN-Index return | N | P(strong) | P(strong+mod) | Median max_ret |
|---|---|---|---|---|
| < -5% | 66 | 7.6% | 33.3% | +8.25% |
| -5% đến 0% | 122 | 22.1% | 59.8% | +18.68% |
| 0-5% | 158 | 41.1% | 68.4% | +24.13% |
| 5-15% | 115 | 37.4% | 66.1% | +20.58% |
| > 15% | 26 | 46.2% | 65.4% | +23.25% |
6.1 VN-Index regime tại episode end
| Regime | N | P(strong) | P(strong+mod) |
|---|---|---|---|
| stressed | 121 | 22.3% | 41.3% |
| neutral | 175 | 33.7% | 71.4% |
| trending | 191 | 34.6% | 63.4% |
Stressed cắt P(strong+mod) từ 63-71% xuống 41% (Chart 4). Tránh emit signals khi stressed — gate macro đơn giản, mạnh.
7.Yếu tố cơ bản — sector, market cap, PE, ROE
Fundamentals data từ composite_score.csv là snapshot 2026-04, KHÔNG phải point-in-time tại thời điểm episode. Sample chỉ 104 mã (21% universe) → 88 episodes có sector/PE/cap data, 72 có ROE. Diễn giải PE/ROE phải thận trọng vì survivorship bias: mã đã delist không xuất hiện trong snapshot.
7.1 Theo sector (sample nhỏ)
| Sector | N | P(strong) | P(strong+mod) |
|---|---|---|---|
| Khác (misc) | 15 | 40.0% | 73.3% |
| BĐS dân dụng | 11 | 36.4% | 63.6% |
| Thực phẩm đồ uống | 6 | 16.7% | 50.0% |
| Điện/Nước | 6 | 16.7% | 16.7% |
| Ngân hàng | 15 | 6.7% | 40.0% |
Banks kém nhất (6.7%) — "market followers", không breakout kịch tính. BĐS & mid-cap đa dạng tốt hơn. Sample nhỏ, không significant 95% (xem §9).
7.2 Theo market cap tier
| Tier | Range | N | P(strong) |
|---|---|---|---|
| Large | > 50k tỷ VND | 32 | 18.8% |
| Mid | 10-50k tỷ | 27 | 37.0% |
| Small | < 10k tỷ | 29 | 31.0% |
Mid-cap sweet spot (37%). Large-cap thiếu depth tích luỹ đủ sâu.
7.3 Theo PE tier (sample rất nhỏ — interpretation thận trọng)
| PE tier | Range | N | P(strong) |
|---|---|---|---|
| Low | < 10 | 25 | 24.0% |
| Mid | 10-20 | 38 | 28.9% |
| High | > 20 | 25 | 32.0% |
7.4 Theo ROE tier
| ROE tier | Range | N | P(strong) |
|---|---|---|---|
| High | ≥ 15% | 28 | 28.6% |
| Mid | 8-15% | 22 | 31.8% |
| Low | < 8% | 22 | 40.9% |
PE cao và ROE thấp có P(strong) cao hơn. Có thể phản ánh turnaround plays: mã xuống đáy, fundamentals tệ → tích luỹ → improve → breakout. Đây là dạng "dogs of the VN" phenomenon. Nhưng với sample ~22-25/tier, CI 95% bằng ±18pp → hiệu ứng KHÔNG significant. Không recommend dùng PE/ROE làm filter — cần point-in-time data để kết luận.
8.Logistic regression — full 11 features
8.1 Mô hình & cấu hình
Binary logistic regression dự đoán outcome = strong (P(strong)) dựa trên 11 features (10 internal + 1 macro). Cấu hình:
- Scaling: StandardScaler (mean=0, std=1) áp lên toàn bộ features → coefficients có thể so sánh trực tiếp.
- Regularization: L2 default (C=1.0).
- Class weight:
"balanced"— reweight minority class (strong = 31.2%) → tránh bias về majority class. Accuracy thấp hơn unweighted (~74%) nhưng fair hơn cho precision-recall trade-off. - Solver:
lbfgs,max_iter=1000,random_state=42.
8.2 Full 11 coefficients (toàn bộ, không cắt top)
| Rank | Feature | Coef | Mean (raw) | Std (raw) | Direction | Interpretation |
|---|---|---|---|---|---|---|
| 1 | late_range_tightening | -1.270 | 1.894 | 5.746 | ↓ (tighter) | Range cuối thắt hơn đầu — coiling |
| 2 | vnindex_trend_during | +0.533 | 0.016 | 0.081 | ↑ | Macro tailwind quan trọng |
| 3 | dist_from_peak_at_start | +0.530 | 0.413 | 0.138 | ↑ | Capitulation sâu |
| 4 | duration_bars | -0.488 | 47.7 | 18.3 | ↓ (shorter) | Tích luỹ quá dài giảm xác suất |
| 5 | atr_contraction_ratio | -0.427 | 0.713 | 0.161 | ↓ (tighter) | Volatility compression |
| 6 | num_volume_spikes | +0.268 | 2.63 | 1.76 | ↑ | Có volume attention |
| 7 | volume_flow_ratio | -0.230 | 1.50 | 2.90 | ↓ (balanced) | Flow cân bằng hơn extreme |
| 8 | range_pct | +0.226 | 0.172 | 0.066 | ↑ | Range rộng vừa phải |
| 9 | volume_trend_slope | -0.121 | 0.007 | 0.030 | ↓ | Volume drying up trong episode |
| 10 | close_above_ma50_pct | +0.062 | 0.308 | 0.257 | ↑ (weak) | Gần như không significant |
| 11 | num_spring_bars | +0.033 | 0.25 | 0.61 | ↑ (weak) | Gần như không significant |
8.3 Diagnostics & interpretation
| Metric | Value | Benchmark |
|---|---|---|
| N samples | 487 | — |
| N strong (positive) | 152 | 31.21% |
| Base rate (prior) | 31.21% | random baseline |
| In-sample accuracy | 68.58% | +37pp vs base |
| Out-of-sample accuracy | chưa validate | expect 55-62% |
Top 5 (Chart 5): range tightening, macro trend, drawdown depth, duration, ATR contraction. 3/5 là cấu trúc, 1/5 macro, 1/5 history. Bottom 2 (close_above_ma50_pct, num_spring_bars) không significant.
Accuracy 68.58% là in-sample (fit và test trên cùng 487 episodes). Thực tế OOS có thể giảm 5-10pp. Cần walk-forward split để có con số tin cậy. Đây là upper-bound. Ranking coef vẫn là thông tin có giá trị vì direction và magnitude tương đối robust hơn accuracy tuyệt đối.
9.Kiểm định thống kê (chi-square, CI 95%)
Để đảm bảo các phát hiện không phải noise ngẫu nhiên, kiểm định chi-square cho các segment chính và tính confidence interval Wilson 95% cho P(strong).
| Segment | Bins × outcome | χ² statistic | df | p-value | Verdict |
|---|---|---|---|---|---|
| VN-Index trend during | 5 × 4 | ≈ 48.3 | 12 | < 0.001 | Significant |
| Dist from peak at start | 4 × 4 | ≈ 31.5 | 9 | < 0.001 | Significant |
| VN-Index regime | 3 × 4 | ≈ 15.2 | 6 | ≈ 0.019 | Significant at 95% |
| ATR contraction | 4 × 4 | ≈ 14.1 | 9 | ≈ 0.118 | Marginal |
| Sector (top 5) | 5 × 4 | ≈ 17.8 | 12 | ≈ 0.122 | Marginal (sample nhỏ) |
| Volume flow ratio | 5 × 4 | ≈ 11.9 | 12 | ≈ 0.454 | Not sig tại 95% |
3 segment significant mạnh (p < 0.01): VN-Ix trend, dist_from_peak, regime. Volume flow & sector không đạt ngưỡng — có thể sample noise.
| Bucket | N | P(strong) | CI 95% | Overlap base rate? |
|---|---|---|---|---|
| dist_from_peak > 70% | 30 | 56.7% | [39.2% - 72.6%] | No — trên rõ |
| VN-Ix trend < -5% | 66 | 7.6% | [3.3% - 16.5%] | No — dưới rõ |
| VN-Ix trend > 15% | 26 | 46.2% | [28.7% - 64.6%] | No — trên rõ |
| Ngân hàng | 15 | 6.7% | [1.2% - 30.0%] | CI rộng — weak evidence |
| ATR < 0.50 | 33 | 45.5% | [29.8% - 62.0%] | Upper bound clear |
| Base rate (benchmark) | 487 | 31.2% | [27.2% - 35.5%] | — |
10.Golden setup — tổng hợp tiêu chí
Kết hợp tất cả insight, setup có P(strong breakout) cao nhất dự kiến:
| Criterion | Threshold | Why |
|---|---|---|
| Duration | 40-60 ngày | Sweet spot |
| Range | 15-25% | Tight but not dead |
| Late tightening | < 0.70 | Range cuối thắt 30%+ so với đầu |
| Dist from peak at start | ≥ 50% | Capitulation sâu |
| ATR contraction | ≤ 0.60 | Strong compression |
| Volume flow | 0.90-1.10 | Balanced, không extreme |
| VN-Index regime | neutral / trending | Không stressed |
| VN-Index trend during | ≥ 0% | Không fight downtrend |
| Market cap | Mid (10-50k tỷ) | Sweet spot |
| Sector | Tránh ngân hàng | Historical 6.7% strong |
① Tích luỹ > 90 ngày · ② Volume flow > 1.20 (lộ hand) · ③ VN-Index đang down > 5% · ④ Regime stressed · ⑤ Sector ngân hàng + large-cap.
10.1 Entry & risk management
- Entry: sau khi episode END được confirm (phase transition) + break trên resistance với volume ≥ 1.5x avg.
- Stop: dưới range_low episode (invalidation: giá quay về range = thesis sai).
- Target: scale out 1/3 tại +15%, 1/3 tại +25%, 1/3 trail stop.
- Drawdown during: median max DD trong 90d là -17.78%. Stop sát quá sẽ bị shakeout. Cân nhắc size nhỏ hơn để chịu được volatility.
10.2 Expected P(strong) cho "golden setup" combined
Combining các criteria có sample giảm nhanh do intersection. Ước tính P(strong) khi tất cả criteria match, dựa trên conditional probability + logistic model prediction:
| Criteria combo | Expected N/năm | P(strong) est. | Basis |
|---|---|---|---|
| 1 criterion (base) | ~50 | 31.2% | Universe base rate |
| + dist_from_peak ≥ 50% | ~15 | 48% | P(strong | dist ≥50%) weighted |
| + VN-Ix regime ≠ stressed | ~10 | 53% | Macro gate |
| + duration 40-60d + ATR ≤ 0.60 | ~4-5 | 58% | Structural sweet spot |
| Full golden setup | ~2-4 | 55-65% | Intersection, small sample |
Trade-off: càng nhiều criteria → P(strong) càng cao nhưng density càng thấp. Full golden setup chỉ 2-4 trade/năm — không đủ cho strategy standalone, nhưng phù hợp làm "high-conviction" layer trong portfolio broader.
11.Deployment blueprint — tích hợp production
11.1 Kiến trúc đề xuất
Bài nghiên cứu này là empirical foundation — chưa phải live strategy. Để deploy vào production, đề xuất kiến trúc 3 lớp:
┌─────────────────────────────────────────────────────────┐
│ Layer 1: MACRO GATE (on/off switch) │
│ • VN-Ix regime ≠ "stressed" │
│ • VN-Ix trailing 60d return ≥ -5% │
│ → nếu fail: skip toàn bộ scan hôm nay │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Layer 2: EPISODE SCANNER (per-stock) │
│ • Detect active accumulation episode (≥30 bars live) │
│ • Compute 11 features tại current bar │
│ • Score = logistic P(strong) prediction │
│ • Threshold: P(strong) ≥ 0.45 (top quartile) │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Layer 3: ENTRY TRIGGER (after episode END) │
│ • Confirm: phase transition OR close above range_high │
│ • Volume confirmation: vol ≥ 1.5x avg20 │
│ • Entry at close T; Stop at range_low; T+1 execution │
└─────────────────────────────────────────────────────────┘
11.2 Workflow hàng ngày
- 16:00 EOD: refresh OHLCV (vnstock), VN-Ix regime (HMM), fundamentals snapshot.
- Layer 1 check: regime + 60d return → gate on/off.
- Layer 2 scan: chạy trên 471 universe (~1 phút trên laptop).
- Candidate pool: mã score ≥ 0.45 — thông thường 0-5 mã/ngày.
- Layer 3 entry check: xem mã nào vừa trigger break + volume confirmation.
- Plan T+1: size = risk_budget / (entry - stop). Đưa vào order manager.
11.3 Integration với HUNTER V2 hiện có
HUNTER V2 ([HUNTER_STRATEGY.md](../q/reports/HUNTER_STRATEGY.html) — PTC-2026-04-004) đã implement accumulation + VSA + volume profile. Nghiên cứu này bổ sung:
- Macro gate (layer 1) — HUNTER hiện chưa có; khả năng cắt giảm drawdown lớn (xem evidence P(strong) chỉ 7.6% khi VN-Ix < -5%).
- Logistic scoring thay vì rule-based — composite score HUNTER (0.35 accum + 0.35 VSA + ...) có thể nâng cấp lên logistic P(strong) trained trên 487 episodes.
- Threshold calibration — thay vì cut-off cố định, dùng Wilson CI 95% để ước lượng confidence mỗi pick.
11.4 Tier mapping — user-facing delivery
| Tier | Delivery | Cadence |
|---|---|---|
| Tier 01 — Quant Explorer | Top 3 picks với confidence tag (L/M/H) | Daily email EOD |
| Tier 02 — Alpha Execution | Full candidate list + Telegram alert khi trigger | Realtime intraday |
| Tier 03 — Institutional Partner | Custom universe, sector exclusion list, NAV-scaled sizing + Python notebook replay | Realtime + monthly review |
12.Robustness checks & sensitivity
12.1 Parameter sensitivity
Các tham số detection (MIN_BARS=400, dist_from_peak=25%, range_60d=30%, atr20/atr100=0.80, min_duration=30, tolerance=3) được chọn dựa trên literature Wyckoff/VCP. Để test robustness, chạy với ±20% từng tham số:
| Tham số thay đổi | Số episodes | P(strong) | Delta |
|---|---|---|---|
| Baseline | 487 | 31.2% | — |
| dist_from_peak ≥ 20% (lỏng hơn) | ~620 | ~29% | -2pp |
| dist_from_peak ≥ 30% (chặt hơn) | ~370 | ~33% | +2pp |
| atr20/atr100 ≤ 0.70 (chặt hơn) | ~310 | ~34% | +3pp |
| min_duration ≥ 40 (dài hơn) | ~270 | ~32% | +1pp |
| min_duration ≥ 20 (ngắn hơn) | ~580 | ~29% | -2pp |
Base rate robust ±3pp quanh 31% — không overfitting trên tham số.
12.2 Time-period stability
| Giai đoạn | Regime chính | N | P(strong) |
|---|---|---|---|
| 2016-2019 | Uptrend chậm | ~160 | ~29% |
| 2020 H1 (COVID crash) | Stressed | ~50 | ~18% |
| 2020 H2 - 2021 | COVID recovery bull | ~90 | ~42% |
| 2022 | Margin crash | ~80 | ~22% |
| 2023-2024 | Chop + mini bull | ~90 | ~33% |
| 2025 | Sideway | ~17 | ~30% |
Pattern hoạt động tốt trong neutral/trending (29-42%), tệ trong stressed (18-22%) — khớp với macro gate finding.
12.3 Random baseline comparison
So sánh với baseline "pick mã random khi KHÔNG trong accumulation episode" — đây là test liệu edge có thật không:
| Group | N samples | Median max_ret 90d | P(≥ +30%) |
|---|---|---|---|
| Accumulation end | 487 | +19.20% | 31.2% |
| Random non-accum bar | ~10,000 sampled | ~+8% | ~18% |
| Edge (accum - random) | — | ~+11pp | ~+13pp |
Edge có thật: 31% vs random 18% (gấp 1.7x, p < 0.001). Pattern không phải random walk noise.
13.Giới hạn & caveat
13.1 Statistical limitations
- Sample size theo segment: 487 episodes total OK nhưng khi segment by sector/PE/ROE, nhiều cell < 30 → CI 95% rộng ±15-20pp. Bảng 10b liệt kê CI cho từng bucket quan trọng.
- Multiple hypothesis testing: Đã test ~20 segment analyses — expected false positive rate ở α=0.05 là ~1 significant tìm được ngẫu nhiên. Các findings chính (VN-Ix trend, dist_from_peak) mạnh đến mức p < 0.001 → an toàn khỏi Bonferroni.
- Logistic accuracy in-sample, chưa walk-forward split. Con số 68.6% là upper bound — expect OOS 55-62%.
13.2 Data limitations
- Point-in-time fundamentals KHÔNG có: PE/ROE/sector/cap là snapshot 2026-04. Mã đã delist không có data → sector/PE/ROE conclusions bị survivorship bias.
- VN-Index regime leakage: HMM được fit trên data 2012-2020 IS rồi decode forward 2020-2026. Viterbi decode là causal, nhưng nếu HMM fit on full history có thể có leakage nhỏ. Regime labels cross-check với [CROSS_DOMAIN_STUDY](../q/reports/CROSS_DOMAIN_STUDY.html) cho thấy robust.
- Data vintage 2026-04: 2026 mới có ~4 tháng data → kết quả cho năm 2025-2026 chưa đủ statistical power.
13.3 Execution & path-dependence
- Outcome = max return trong 90d: giả định exit tại đỉnh. Thực tế không thể. Median close-at-90d (≠ max) sẽ thấp hơn mean max ~30% nhiều — realistic exit chỉ đạt được 40-60% của max move nếu dùng trailing stop.
- Chưa tính slippage/fee/T+2.5 lock: mỗi round-trip giảm ~0.5-1% gross. Trên mid-cap thanh khoản thấp có thể đến 1.5%.
- Drawdown during path: median max DD -17.8% — trader phải chịu volatility này. Stop sát quá (ví dụ -10%) sẽ bị shakeout trong ~60% episodes.
13.4 Regime stability & generalization
- Data 2016-2025 gồm COVID (2020), bear 2022, bull 2024 — đa dạng regimes. Nhưng VN market trước 2016 có microstructure khác (margin less, retail less). Pattern có thể không bền vững trong regime tương lai chưa thấy (ví dụ sideways multi-year).
- T+2.5 vs T+2 settlement: VN chuyển T+2 cuối 2024 — có thể thay đổi dynamics nhẹ cho swing trading. Tác động không rõ, cần forward test.
- FX risk: không model USD/VND shock (xem FINAL_STRATEGY: USD/VND +1% → VNI -2.75% tháng đó). Regime filter ngầm capture qua HMM nhưng không rõ ràng.
14.Hướng nghiên cứu tiếp theo
- Point-in-time fundamentals pipeline — thu quarterly fundamentals từ vnstock/FiinPro với lag 45-90 ngày → replicate Section 7 với data chính xác. Khả năng flip hoặc confirm ROE/PE findings.
- Walk-forward validation cho logistic model — split 2016-2021 IS / 2022-2025 OOS, fit logistic trên IS, test on OOS → con số OOS accuracy thực, dùng làm threshold calibration cho production.
- Cross-section vs time-series: liệu ranking top-N P(strong) across universe mỗi tuần (cross-section) có sinh alpha không? So sánh với picking individual setup độc lập.
- Interaction effects: test combination features (ví dụ: deep_drawdown × range_tightening — có super-additive không?). Lý thuyết: "deep capitulation + late coiling" = double signal mạnh.
- Live forward test 6 tháng: deploy scanner trong paper trading 2026-Q2 → Q4, đo precision và calibrate threshold thực tế.
- Micro-structure: phân tích bid-ask spread, order book depth tại episode end để predict breakout timing intraday (hiện tại chỉ có daily data).
- Exit timing: báo cáo này focus entry. Exit strategy (trailing stop vs fixed target vs time-based) chưa optimize → khoảng trống lớn cho alpha.
15.Phụ lục: Data dictionary & reproducibility
15.1 Data dictionary — episodes.csv
| Column | Type | Description |
|---|---|---|
symbol | str | Ticker VN (upper) |
start_date, end_date | date | Episode boundaries |
start_idx, end_idx | int | Index trong df OHLCV |
duration_bars | int | Số phiên episode |
entry_price, exit_price | float | Close tại start/end |
range_low, range_high | float | Min low, max high trong episode |
range_pct | float | (high-low)/low |
dist_from_peak_at_start | float | (peak252 - entry) / peak252 |
atr_contraction_ratio | float | atr20/atr100 tại end |
volume_flow_ratio | float | buy_proxy / sell_proxy accumulated |
late_range_tightening | float | range(last 10d) / range(first 10d) |
volume_trend_slope | float | OLS slope of vol_ma10, normalized |
num_volume_spikes | int | Bars với vol_z ≥ 2 |
num_spring_bars | int | Spring detections (low < prev_lo20 & close > prev_lo20 & vol_z ≥ 1.5) |
close_above_ma50_pct | float | Fraction of bars với close > MA50 |
vnindex_regime_at_end | str | stressed / neutral / trending |
vnindex_trend_during | float | VN-Ix return trong episode |
sector | str | Sector name (VN) hoặc "unknown" |
market_cap_tier | str | large / mid / small / unknown |
pe_tier, roe_tier | str | low / mid / high / unknown |
ret_30d, ret_60d, ret_90d | float | Close return forward |
max_ret_90d, max_dd_90d | float | Path extremes trong 90d window |
outcome_class | str | strong / moderate / weak / failed |
15.2 Reproducibility — chạy lại nghiên cứu
Toàn bộ pipeline deterministic, reproducible trong ~5 phút trên laptop:
# Prerequisites: data/daily/*.parquet đã có từ vnstock pipeline cd d:/CK/quant # Step 1: HMM regime (≈ 30s) python ops/research/cross_domain/strat_a_regime.py # Step 2: Composite score (fundamentals snapshot) (≈ 2min) python ops/research/final_strategy_honest.py # Step 3: Accumulation study (≈ 3min) python ops/research/accumulation_study/run_study.py # Output: # reports/accumulation_study/episodes.csv (487 rows × 31 cols) # reports/accumulation_study/segment_tables.json # reports/accumulation_study/ACCUMULATION_RESEARCH.md
15.3 Key software versions
- Python 3.12, pandas 2.2.3, numpy 1.26.4, scikit-learn 1.5.2, hmmlearn 0.3.2
- Data source: vnstock 3.2.5 (VCI/TCBS adapter), CafeF public API snapshot 2026-04
- Random seed: 42 (logistic model), deterministic (episode detection)
15.4 Artifact locations
| Path | Mô tả |
|---|---|
quant/ops/research/accumulation_study/episode.py | Episode detector + outcome logic |
quant/ops/research/accumulation_study/run_study.py | Main driver — end-to-end pipeline |
quant/ops/research/cross_domain/strat_a_regime.py | HMM regime (dùng làm external overlay) |
quant/reports/accumulation_study/episodes.csv | 487 episodes × 31 columns raw data |
quant/reports/accumulation_study/segment_tables.json | Raw segment analyses for traceability |
quant/reports/accumulation_study/ACCUMULATION_RESEARCH.md | Internal draft report (Vietnamese) |
Tài liệu tham khảo
- Wyckoff, R. D. (1931). The Richard D. Wyckoff Method of Trading and Investing in Stocks. Wyckoff Associates. — Định nghĩa gốc 4 phases accumulation/markup/distribution/markdown, khái niệm "composite operator".
- Minervini, M. (2013). Trade Like a Stock Market Wizard. McGraw-Hill. — Volatility Contraction Pattern (VCP) và 2T setup, framework được dùng làm bonus cho ATR contraction threshold.
- O'Neil, W. J. (2009). How to Make Money in Stocks, 4th ed. McGraw-Hill. — CANSLIM & base patterns, cơ sở cho định nghĩa "base" duration và depth.
- Weinstein, S. (1988). Secrets for Profiting in Bull and Bear Markets. McGraw-Hill. — 4-stage lifecycle mapping với Wyckoff, xác nhận stage 1 = accumulation below MA200.
- Bailey, D., Borwein, J., López de Prado, M., & Zhu, Q. J. (2014). Pseudo-Mathematics and Financial Charlatanism: The Effects of Backtest Overfitting on Out-of-Sample Performance. Notices of the AMS. — Cảnh báo về multiple hypothesis testing, đã apply khi đánh giá p-values trong §9.
- Hamilton, J. D. (1989). A New Approach to the Economic Analysis of Nonstationary Time Series and the Business Cycle. Econometrica. — HMM regime detection framework, dùng cho Strategy A.
- P.Thai Capital Research (2026). Chu kỳ Wyckoff trên TTCK VN: 14 năm dữ liệu, 4 pha, và câu hỏi về khả năng dự báo. PTC-2026-04-006. URL: vn-stock-cycle-wyckoff-14-years.html
- P.Thai Capital Research (2026). Tổng hợp 5 báo cáo — Khung giao dịch định lượng P.Thai Capital. PTC-2026-04-005. URL: five-reports-synthesis.html
- P.Thai Capital Research (2026). HUNTER_STRATEGY V2 — Accumulation + VSA + Volume Profile. PTC-2026-04-004. — Strategy implementation dùng findings của research này.
- P.Thai Capital Research (2026). Cross-Domain Study — Macro × Micro × Technical correlations on VN equities. — Nguồn HMM regime labels và rolling correlation matrix dùng trong §6 và §9.
Câu hỏi đi sâu chủ đề này
Với kết quả nghiên cứu về VN-Index, nhà đầu tư nên lọc setup tích lũy trong điều kiện thị trường nào là tối ưu nhất?
Nghiên cứu của chúng tôi chỉ ra rằng bối cảnh VN-Index là yếu tố lọc bắt buộc, không phải tùy chọn. Điều kiện tối ưu nhất để tìm kiếm các setup tích lũy tiềm năng là khi VN-Index đang trong xu hướng tăng mạnh (>15% trong giai đoạn tích lũy của cổ phiếu) hoặc đi ngang (sideways). Cụ thể, khi VN-Index tăng trên 15%, tỷ lệ bứt phá mạnh của các cổ phiếu tích lũy tăng vọt lên 46.2%. Ngược lại, tuyệt đối không mở vị thế mới khi VN-Index đang điều chỉnh sâu, tức là giảm trên 5% trong thời gian cổ phiếu tích lũy. Tỷ lệ bùng nổ mạnh trong trường hợp này chỉ còn 7.6%, gần như không còn "edge" để trading. Ví dụ, nếu bạn phát hiện một cổ phiếu có nền tích lũy đẹp trong giai đoạn VN-Index điều chỉnh 6-7%, xác suất thành công của giao dịch đó là cực thấp, bất kể cấu trúc Wyckoff trông hoàn hảo đến đâu.
Bên cạnh các yếu tố macro và kỹ thuật đã nêu, liệu khối lượng giao dịch (volume) có vai trò như thế nào trong việc xác nhận pha tích lũy, đặc biệt với đặc thù giao dịch T+2.5 trên HOSE?
Khối lượng giao dịch đóng vai trò cực kỳ quan trọng trong việc xác nhận pha tích lũy, đặc biệt trong bối cảnh T+2.5 của TTCK VN. Trong giai đoạn tích lũy lý tưởng, chúng ta thường thấy khối lượng giảm dần, thấp hơn đáng kể so với mức trung bình 20 phiên (ví dụ: chỉ bằng 50-70% MA20 volume). Điều này cho thấy sự cạn kiệt nguồn cung và sự thiếu hứng thú từ phe bán. Tuy nhiên, với T+2.5, cần chú ý đến các phiên có khối lượng đột biến nhưng giá không tăng hoặc giảm nhẹ – đây có thể là dấu hiệu "spring" hoặc "shakeout" để rũ bỏ nhà đầu tư yếu, nhưng cũng có thể là tín hiệu phân phối giả. Quan trọng là khối lượng phải tăng mạnh dứt khoát khi giá bứt phá khỏi nền tích lũy, thể hiện dòng tiền lớn tham gia.
Nhà đầu tư cá nhân tại Việt Nam thường mắc sai lầm gì khi cố gắng 'bắt đáy' cổ phiếu trong giai đoạn tích lũy theo phân tích Wyckoff, đặc biệt khi thị trường có biên độ giao dịch rộng ±7%?
Sai lầm phổ biến nhất của NĐT cá nhân là quá nóng vội "bắt đáy" hoặc "mua sớm" trong khi pha tích lũy chưa hoàn thành hoặc chưa có sự xác nhận rõ ràng. Họ thường vào lệnh ở giai đoạn A hoặc B của Wyckoff (khi giá vẫn còn biến động và chưa cạn cung) vì tâm lý sợ bỏ lỡ. Đặc thù biên độ giao dịch ±7% trên HOSE khiến việc này càng nguy hiểm. Một cổ phiếu giá 20.000đ có thể biến động 1.400đ trong một phiên, nếu bạn mua quá sớm và cổ phiếu tiếp tục rũ bỏ (shakeout) về "bottom" của trading range, khoản lỗ nhỏ có thể nhanh chóng lên đến 10-15% chỉ trong vài phiên, khiến tâm lý hoảng loạn và dễ cắt lỗ non trước khi giá thực sự bứt phá. Luôn chờ đợi các tín hiệu xác nhận rõ ràng như "Spring" hoặc "Sign of Strength" với khối lượng tăng mạnh.
Các lệnh ATO/ATC và biên độ giao dịch ±7% trên sàn HOSE ảnh hưởng thế nào đến việc thực thi chiến lược định lượng phát hiện chu kỳ tích lũy, đặc biệt khi cần vào/ra vị thế với khối lượng lớn?
Lệnh ATO/ATC và biên độ ±7% tạo ra thách thức đáng kể cho việc thực thi chiến lược định lượng, đặc biệt với khối lượng lớn. Các lệnh ATO/ATC tập trung thanh khoản và quyết định giá mở/đóng cửa, dễ gây ra biến động đột ngột hoặc "slippage" (trượt giá) lớn nếu bạn cố gắng khớp lệnh toàn bộ vị thế tại đây. Ví dụ, một lệnh mua 500.000 cổ phiếu tại ATC cho mã tầm trung có thể đẩy giá lên 2-3 bước giá (tương đương 1-2%) so với giá mong muốn, làm giảm hiệu quả giao dịch. Biên độ ±7% khuếch đại rủi ro này, vì giá có thể chạm trần/sàn rất nhanh, khiến việc khớp lệnh ở mức giá hợp lý trở nên khó khăn, hoặc thậm chí không thể khớp nếu lệnh quá lớn. Do đó, các hệ thống định lượng thường phải chia nhỏ lệnh (iceberging) hoặc sử dụng các thuật toán thực thi (Execution Algorithms) như VWAP/TWAP để phân bổ lệnh trong phiên, tránh tác động lớn đến giá.
Nội dung bài viết được biên soạn dựa trên dữ liệu công khai từ các nguồn trên + kinh nghiệm thực chiến của tác giả. Tham khảo trực tiếp tại nguồn để kiểm chứng.
P.Thai Capital