Tôi giết chiến lược của mình bằng MinTRL: cần 30 năm mới biết nó đúng
2026-09-25 · H&V Company
Mở: +27,96% bị giết thành +1,46%
Tôi từng công bố cấu hình v39 với lợi nhuận +27,96 %. Ngày 22/09/2026 tôi chạy lại chính mã nguồn đó và ra +1,46 %.
Chuyện gì đã xảy ra.
v39 đo trên cửa sổ trượt now() − 59 ngày. Ba chữ "now()" là toàn bộ vấn đề: kỳ đo dịch đi theo đúng cái ngày tôi bấm nút, nên "chạy lại" không bao giờ là chạy lại cùng một phép đo. Baseline thì lấy lần chạy may nhất trong 12 lần. Và nó chưa từng được kiểm ngoài mẫu. Ba thứ đó cộng lại không tạo ra bằng chứng — chúng tạo ra một con số tự khen mình.
Tôi cần một thứ ngược hẳn lại: kỳ đo đóng băng, dữ liệu ghim bằng hash, và một cơ chế tự phạt khi tôi dò quá nhiều cấu hình.
Tôi cần một cách để đo lường sự khác biệt này một cách không thể phủ nhận được. Không dùng cửa sổ trượt. Không tìm hay. Không baseline linh hoạt. Cần một công cụ đặt dấu chỉ trích vào những điều tôi sợ nhất.
Và tôi tìm thấy nó: MinTRL + DSR.
Phép đo tái lập được — hay tại sao "chạy lại ra số khác" là dấu hiệu chết người
Để bài này có giá trị, mỗi con số phải truy được về mã gốc + dữ liệu ghim bằng hash. Tôi sử dụng:
- Data:
data_1m_30mo.pkl → SHA-256 cdbdfa28803400a2… - Mã chiến lược:
run_live.py → SHA-256 cd8851850a54e30a… - Luật thoát:
liquidity.py → SHA-256 01aae4c7366972ac…
Kỳ khảo sát: 2024-03-01 → 2026-08-18 (CỐ ĐỊNH, không trượt).
Kết quả: 517 lệnh. Đối chiếu với file live_trades.pkl: khớp 100% cả timestamp lẫn PnL ròng.
Nếu bạn lấy dữ liệu v39 (cửa sổ trượt) và chạy lại, mỗi ngày bạn sẽ ra một bộ 517 lệnh khác nhau. Những con số không tái lập được = những con số không có ý nghĩa thống kê.
Bài này chỉ dùng con số tái lập được.
Tách mã: vì sao đọc số gộp là tự lừa mình
517 lệnh gồm hai mã khác nhau: ES (E-mini S&P 500) và NQ (E-mini Nasdaq). Chúng hoạt động với quy tắc thoát khác nhau, khủng hoảng lỏng khác nhau, lịch sử hiệu suất khác nhau.
Khi tôi gộp chúng lại, tôi được expR +0,171, t-stat +2,74 — con số trông rất đẹp.
Khi tôi tách ra:
| Mã | n lệnh | expR (lãi mỗi lệnh) | t-stat | trimR (cắt 5% đuôi) | Win rate |
|---|
| ES toàn kỳ | 242 | +0,040 | +0,46 | −0,053 | 40% |
| NQ toàn kỳ | 275 | +0,285 | +3,25 | +0,203 | 48% |
| Gộp (tham khảo) | 517 | +0,171 | +2,74 | +0,086 | 44% |
Dòng ES nói rõ ràng: con số đẹp của gộp là do NQ kéo lên. ES một mình không có edge dương.
Còn trimR là gì? Nó là lãi trung bình sau khi cắt bỏ 5% lệnh có lãi cao nhất. Nếu một hệ thống chỉ kiếm tiền từ vài lệnh "quả lợi" ở đuôi phải — đó là cấu trúc vé số, không phải chiến lược. ES trimR −0,053 = toàn bộ lãi +0,040 của ES nằm ở vài lệnh ngoại lệ; bỏ đi chúng thì hệ "lỗ" ngay.
Số gộp che giấu lỗi này.
trimR: toàn bộ lãi nằm ở đuôi
Con số ES trimR −0,053 là lý do tôi không tin vào ES. Nếu một hệ thống chỉ kiếm tiền nhờ vài lệnh may mắn (outlier), thì nó không phải là một hệ thống — nó là một cược.
Ngược lại, NQ trimR +0,203 = ngay cả khi cắt bỏ 5% lệnh tốt nhất, nó vẫn lãi +0,203 trung bình/lệnh. Đó là dấu hiệu của một quy luật thực sự.
DSR: phép đo mà gần như không ai dám dùng
Deflated Sharpe Ratio (DSR) là thứ được thiết kế để trừng phạt sự dò tìm tham số (parameter searching).
Tôi chạy 250 cấu hình khác nhau trên cùng dữ liệu (thay đổi disp_atr, vfilter, erm). Cả 27 biến thể đều dương (từ +0,126 đến +0,215) — đó là một "cao nguyên", không phải một đỉnh. Điều này nghi ngờ.
DSR sẽ áp một "phạt" vào Sharpe ratio cao nhất của 250 cấu hình này để trả lời câu hỏi: "Nếu tôi lặp lại thí nghiệm này một triệu lần với dữ liệu ngẫu nhiên, tôi sẽ thấy con số cao như vậy bao nhiêu lần?"
Kết quả:
- ES: DSR = 0,296 → FAIL (ngưỡng pass là ≥ 0,5)
- NQ: DSR = 0,991 → PASS
NQ còn pass ngay cả khi tôi tăng số cấu hình lên 500 (DSR 0,990).
ES không bao giờ pass ở bất kỳ mức nào.
MinTRL: cần bao nhiêu lệnh nữa thì tôi mới biết mình đúng
DSR nói "ES không có edge thống kê". Nhưng câu hỏi thực tế hơn là: "Nếu tôi tiếp tục chạy ES, bao lâu thì tôi sẽ biết nó đúng hay sai?"
MinTRL (Minimum Track Record Length) trả lời: 2.992 lệnh.
Cách tính:
- ES chạy được 242 lệnh trong 30 tháng
- Tỷ lệ: 242 / 30 = 8,07 lệnh/tháng
- Để xác nhận 2.992 lệnh: 2.992 / 8,07 ≈ 371 tháng ≈ 30,9 năm
Tức là, nếu edge của ES là thật (expR +0,040), tôi sẽ phải chạy nó liên tục trong 30 năm mới có đủ mẫu để xác nhận điều đó với độ tin cậy thống kê.
Trong đời thật, đó tương đương với "không bao giờ".
NQ khác hoàn toàn: MinTRL chỉ 65 lệnh (tôi đã thu được 275). Với tỷ lệ 9,17 lệnh NQ/tháng, 65 lệnh = 7 tháng. Sau 7 tháng chạy thật, tôi sẽ biết NQ có edge thực không.
Baseline entry ngẫu nhiên: 0/50 lần
Một phép kiểm chứng khác: nếu tôi vào lệnh ngẫu nhiên (thời điểm + hướng random) nhưng giữ nguyên quy tắc thoát, tôi sẽ kiếm bao nhiêu?
Tôi chạy 50 lần. Mỗi lần ~500 lệnh, entry random nhưng thoát theo quy tắc (stop loss swing, target thanh khoản, fallback R/R, phí, breaker).
Kết quả:
| Hệ thật | Null (entry random) | p(null ≥ thật) |
|---|
| GỘP toàn kỳ | +0,171 | −0,207 (max −0,012) | 0/50 < 0,02 |
| ES toàn kỳ | +0,040 | −0,212 (max +0,008) | 0/50 |
| NQ toàn kỳ | +0,285 | −0,205 (max +0,062) | 0/50 |
Cả 50 lần chạy null, không một lần nào vượt lên gây hại như hệ thật. Điều này nói rằng hệ thật có thứ gì đó (bất kỳ thứ gì), NQ ít nhất là cấu trúc entry có logic.
Lưu ý kỹ thuật: z-score thô (2,09) vô dụng ở đây vì đuôi trái của null rất dày (entry random rơi gần vào swing level = risk gần 0 = phí/risk phiên sinh vổng lớn). Phải đọc p thực nghiệm.
Trường hợp NQ khoá (chỉ 81 lệnh): p = 0,08 (vừa đủ sát ngưỡng 0,05 để cảnh báo). Đó là lý do DSR phải cao — để chống lại tình huống này.
Lưới 27 cấu hình: cao nguyên tham số
Khi tôi tìm kiếm, tôi thay đổi ba thông số:
disp_atr ∈ {0,7 · 0,8 · 0,9}vfilter ∈ {1,15 · 1,3 · 1,45}erm ∈ {0,50 · 0,55 · 0,60}
Tổng: 3 × 3 × 3 = 27 cấu hình.
Kết quả: cả 27 đều dương (từ +0,126 đến +0,215). Cấu hình live (v40) hiện tại đứng thứ 14/27 = chính giữa cao nguyên (không phải đỉnh như v39 = #1/12 lần chạy cũ).
Nhưng Optimization Bias (PBO):
| Gộp | ES | NQ |
|---|
| PBO | 0,225 ✅ | 0,618 | 0,583 |
PBO nói: "Trong từng mã, xếp hạng tốt nhất trên mẫu huấn luyện KHÔNG lặp lại ngoài mẫu." ES và NQ có PBO rất cao (>0,5) = vi-chỉnh tham số là vô nghĩa. Chênh lệch giữa ô #1 và ô #27 trong lưới 27 chỉ là nhiễu, không phải signal.
Cấu hình live #14 có thể thua ô #3 ngoài mẫu, hoặc thắng ô #25. Bất kỳ quyết định "di chuyển sang ô tốt hơn" đều rủi ro.
Dải P5: bao lâu mới biết sai, bao lâu mới biết đúng
Tôi so sánh đường vốn live với dải P5 (phân vị 5%) của backtest:
| Thời gian | P5 dải | Ý nghĩa |
|---|
| Sau 20 lệnh (~5 tuần) | −0,338 | Lệch rõ rệt |
| Sau 40 lệnh (~2,3 tháng) | −0,188 | Cảnh báo |
| Sau 60 lệnh (~3,5 tháng) | −0,126 | Gần bác bỏ |
| Sau 100 lệnh (~6 tháng) | −0,055 | Chậm phai |
| Sau 150 lệnh (~9 tháng) | −0,017 | Gần giới hạn |
(Quy đổi: 17,5 lệnh/tháng cho toàn hệ)
Phát hiện hỏng: 2–3,5 tháng. Xác nhận edge (t ≥ 2 nếu edge thật = +0,125): ~433 lệnh ≈ 25 tháng.
Bất đối xứng này là chìa khóa: người ta rất nhanh phát hiện lỗi, nhưng chậm xác nhận thành công. Bất kỳ ai bảo bạn "chỉ cần 6 tháng sẽ rõ" đều nói dối — có thể bạn sẽ biết nó hỏng sau 6 tháng, nhưng để biết nó đúng, bạn cần 25 tháng.
Phán quyết
Hệ hiện tại chạy live là một cược NQ (có bằng chứng thực: DSR 0,99, trimR +0,203, thắng random 0/50) cộng một chân ES không có bằng chứng và sẽ không bao giờ có (MinTRL 30 năm, trimR âm), đứng giữa một cao nguyên tham số mà vi-chỉnh là vô nghĩa.
Tôi không bỏ ES vì tôi e sợ thua lỗ. Tôi nêu rằng bằng chứng cho ES = 0 và sẽ không bao giờ đủ n.
Đó là điều hiếm khi ai dám nói thẳng trong ngành trading. Con số không phải tín hiệu — trong ngành này, những tín hiệu dư mứa. Cái khan hiếm là người dám đặt một công cụ lên chính chiến lược của mình, nhìn vào kết quả, và nói "không".
Tự kiểm chứng
Mã nguồn đặt tại:
~/Documents/trading/ES-NQ/
Chạy phép đo:
cd ~/Documents/trading/ES-NQ && python3 kiem_tai_lap.py
Output sẽ hiển thị các con số từng mã + tổng, kèm hash dữ liệu để bạn đối chiếu.
Cảnh báo rủi ro
Nội dung bài viết là giáo dục kỹ thuật về phương pháp đo lường trong trading. Nó không phải lời khuyên đầu tư, không phải tín hiệu giao dịch, không phải lời mời tham gia chiến lược này.
Hiệu suất quá khứ (kể cả trong sample lẫn out-of-sample) không bảo đảm hiệu suất tương lai. Các kỳ thị trường, thanh khoản, cấu trúc phí khác nhau có thể làm chiến lược này không hoạt động.
Trading chứa chấp rủi ro mất toàn bộ vốn. Chỉ sử dụng tiền mà bạn có khả năng mất.