Backtest là gì và đọc kết quả thế nào
Hai cấu hình trên cùng một mã cho lợi nhuận tổng chênh 3.13 điểm phần trăm nhưng sụt giảm tối đa chênh 31.78. Lợi nhuận tổng là chỉ tiêu tệ nhất.
FinLens44 phút đọc
Một người chạy backtest cho hai cấu hình trên cùng một cổ phiếu, cùng một cửa sổ 10 năm, cùng một mức phí và cùng một mức trượt giá. Bảng kết quả trả về hai con số lợi nhuận tổng: +49.53% và +46.40%. Chênh nhau 3.13 điểm phần trăm. Nhìn vào đó thì hai cấu hình gần như tương đương, và ai cũng sẽ chọn cái đầu.
Nhưng nếu người đó đọc thêm một dòng nữa trong chính bảng ấy, mức sụt giảm sâu nhất của đường vốn, con số là −68.71% và −36.93%. Chênh nhau 31.78 điểm phần trăm. Cấu hình được chọn vì lợi nhuận nhỉnh hơn 3.13 điểm là cấu hình từng có lúc mất gần bảy phần mười số vốn giả định.
Đó là toàn bộ nội dung của bài này, phát biểu bằng một câu: lợi nhuận tổng là chỉ tiêu tệ nhất trong số các chỉ tiêu mà một backtest trả về, vì nó đọc đúng hai con số ở hai đầu kỳ và ném đi toàn bộ đường đi ở giữa, mà đường đi ở giữa mới là thứ người cầm cổ phiếu thật sự phải sống cùng.
Bài này làm bốn việc. Thứ nhất, nói rõ backtest là gì và nó tính cái gì. Thứ hai, liệt kê đầy đủ những chỉ tiêu mà một bảng kết quả trả về, mỗi cái đo gì và mỗi cái mù cái gì. Thứ ba, mổ cặp số ở trên tới tận cùng, kể cả những chỗ khiến chính cặp số ấy không được phép suy rộng. Thứ tư, phần dài nhất, nói về các giả định mà một công cụ backtest đặt ra mà thường không khai, và những chỗ đặc thù của thị trường Việt Nam làm các giả định đó gãy.
Bài không đưa ra tín hiệu mua bán, không dự báo giá của bất kỳ mã nào, và không giới thiệu bộ tham số nào để dùng. Mọi kết quả backtest xuất hiện dưới đây có mặt để chứng minh một cách hỏng, không để nêu ưu điểm của một chiến lược.
Hai đường vốn xuất phát từ cùng một điểm và kết thúc ở gần cùng một độ cao, nhưng một đường đi qua một hố sâu còn đường kia chỉ có những chỗ lõm nông
Backtest là gì, và nó thật sự tính cái gì
Backtest là phép chạy lại một bộ quy tắc mua bán trên dữ liệu giá của quá khứ, rồi ghi lại kết quả giả định.
Câu đó nghe đơn giản tới mức dễ bỏ qua chỗ khó. Chỗ khó nằm ở chữ "bộ quy tắc": để một cỗ máy chạy lại được, quy tắc phải khai đủ tới mức không còn chỗ nào cho phán đoán của người. Một bộ quy tắc chạy được cần ít nhất sáu thành phần.
| Thành phần | Câu hỏi phải trả lời | Bỏ trống thì sao |
|---|---|---|
| Tập mã | Chạy trên những mã nào, và danh sách đó lấy ở thời điểm nào | Danh sách lấy ở hôm nay áp cho quá khứ là một sai lệch có tên riêng |
| Cửa sổ thời gian | Từ ngày nào tới ngày nào | Kết quả đổi theo cửa sổ, và cửa sổ thường được chọn sau khi đã nhìn dữ liệu |
| Điều kiện vào lệnh | Đúng phiên nào, dựa trên dữ liệu tính tới lúc nào | Dùng dữ liệu chưa có tại thời điểm ra quyết định là một lỗi cả lớp |
| Điều kiện thoát lệnh | Thoát khi nào, và có điều kiện dừng lỗ không | Không khai thì máy tự chọn một quy ước mà người chạy không biết |
| Quy mô vị thế | Mỗi lệnh dùng bao nhiêu phần trăm vốn | Đổi quy mô là đổi cả sụt giảm lẫn lợi nhuận tổng |
| Phí và trượt giá | Trừ bao nhiêu mỗi chiều | Bỏ qua là biến một kết quả âm thành dương |
Sáu dòng này quan trọng vì mỗi dòng là một lựa chọn của người chạy chứ không phải một thuộc tính của thị trường. Đổi một dòng là ra một kết quả khác, và không có dòng nào có đáp án chuẩn. Chuyện này giống hệt chuyện cửa sổ nhận diện đỉnh đáy trong xu hướng và cấu trúc giá: công cụ trông như một phép đo khách quan, nhưng bên trong nó có những tham số do người đặt.
Vì vậy một câu cần nói ngay, và bài này sẽ nhắc lại vài lần: backtest không phải một phép kiểm chứng. Nó là một phép mô phỏng có giả định. Kết quả của nó là câu trả lời cho câu hỏi "nếu quy tắc này đã được chạy trong quá khứ, với đúng những giả định tôi vừa khai, thì số dư giả định đã biến động ra sao". Nó không trả lời câu hỏi "quy tắc này có hiệu quả không", và cũng không thể.
Ba việc backtest làm được thật
Nói cho công bằng, backtest không vô dụng. Nó làm được ba việc mà không cách nào khác làm thay được.
Việc thứ nhất là bắt buộc người ta khai rõ quy tắc. Một ý tưởng mua bán phát biểu bằng lời thường mơ hồ tới mức không sai được. Viết nó ra dưới dạng máy chạy được là ép nó phải có điều kiện để sai. Riêng bước này đã loại được phần lớn ý tưởng, vì nhiều ý tưởng không sống nổi qua bước phải nói rõ.
Việc thứ hai là loại trừ. Một bộ quy tắc cho kết quả rất tệ trên nhiều cửa sổ và nhiều mã thì gần như chắc chắn không nên dùng. Suy luận theo chiều loại trừ này an toàn hơn hẳn suy luận theo chiều khẳng định, vì nó không đòi kết quả quá khứ phải lặp lại, nó chỉ đòi kết quả quá khứ đủ tệ.
Việc thứ ba là đo chi phí. Đây là chỗ backtest cho câu trả lời gần với sự thật nhất, vì phí và thuế là những khoản chắc chắn xảy ra và tính được. Nội dung đó là bài riêng trong chuỗi này, chi phí giao dịch ăn mòn lợi nhuận thế nào.
Cái backtest không làm được là thứ người ta hay dùng nó nhất: khẳng định một bộ quy tắc sẽ tiếp tục cho kết quả tương tự.
Câu chốt: backtest ép một ý tưởng phải khai rõ điều kiện để nó sai, và đó là giá trị lớn nhất của nó; phần còn lại đều phải đọc rất dè.
Một bảng kết quả trả về những gì
Đây là phần liệt kê. Mục đích là để khi mở một bảng kết quả ra, người đọc biết mình đang nhìn cái gì và biết chỗ nào còn thiếu.
Các chỉ tiêu chia được thành bốn nhóm theo câu hỏi mà chúng trả lời. Cách chia này quan trọng hơn danh sách, vì nó cho thấy ngay chỗ hổng: phần lớn người đọc chỉ nhìn nhóm thứ nhất.
Nhóm 1: đo điểm cuối
| Chỉ tiêu | Đo cái gì | Nó mù cái gì |
|---|---|---|
| Lợi nhuận tổng | Tỷ lệ thay đổi của số dư giả định từ đầu kỳ tới cuối kỳ | Toàn bộ đường đi ở giữa, và độ dài của kỳ |
| Lợi nhuận quy về năm | Chính con số trên, quy về một năm để so được hai kỳ dài ngắn khác nhau | Cùng thứ như trên, chỉ đổi thang đo |
Hai chỉ tiêu này đọc đúng hai con số: số dư đầu kỳ và số dư cuối kỳ. Mọi thứ xảy ra giữa hai mốc ấy đều không đi vào phép tính. Đó không phải khiếm khuyết của công thức, đó là định nghĩa của nó.
Nhóm 2: đo đường đi
| Chỉ tiêu | Đo cái gì | Nó mù cái gì |
|---|---|---|
| Sụt giảm tối đa | Mức rơi sâu nhất từ một đỉnh của đường vốn xuống đáy kế tiếp, tính bằng phần trăm | Chuyện đó xảy ra khi nào, và xảy ra bao nhiêu lần |
| Thời gian dưới đỉnh cũ | Bao lâu đường vốn nằm dưới mức đỉnh cũ trước khi vượt lại | Độ sâu trong quãng đó |
| Chỉ số Sharpe hoặc các biến thể | Lợi nhuận trên một đơn vị biến động của lợi nhuận | Cách tính cụ thể, vốn khác nhau giữa các công cụ |
| Tỷ lệ thời gian ở trong thị trường | Bao nhiêu phần trăm số phiên chiến lược đang nắm giữ | Rủi ro trong những phiên đứng ngoài, vốn bằng không |
Nhóm này là nhóm trả lời câu hỏi "đi tới đích bằng con đường nào". Sụt giảm tối đa là chỉ tiêu đơn giản nhất trong nhóm và cũng là chỉ tiêu bị bỏ qua nhiều nhất. Bản chất, cách đo và những chỗ nó gây hiểu nhầm nằm trong sụt giảm tối đa và thời gian hồi phục.
Đừng chép lại một con số Sharpe mà không hỏi nó tính thế nào
Bài này cố ý không in công thức của chỉ số Sharpe, vì cách một công cụ cụ thể tính ra nó phụ thuộc vào ít nhất bốn lựa chọn mà công cụ thường không khai: lợi suất lấy theo phiên hay theo từng lệnh, lãi suất phi rủi ro dùng mức nào, hệ số quy về năm bằng bao nhiêu, và những phiên đứng ngoài thị trường có được tính vào mẫu số hay không. Hai công cụ khai bốn thứ đó khác nhau sẽ cho hai con số Sharpe khác nhau trên cùng một chuỗi lệnh, và không con số nào sai. Chép một con số Sharpe từ bảng này sang bảng khác để so sánh là việc không làm được nếu chưa kiểm bốn lựa chọn trên.
Nhóm 3: đo độ tin cậy của chính phép đo
| Chỉ tiêu | Đo cái gì | Nó mù cái gì |
|---|---|---|
| Số lệnh | Số lần vào và thoát trọn vẹn trong kỳ | Không mù gì, nhưng nó là mẫu số của mọi tỷ lệ bên dưới |
| Tỷ lệ thắng | Số lệnh có lãi chia cho số lệnh | Độ lớn của lãi và của lỗ |
| Lãi trung bình một lệnh thắng | Độ lớn trung bình của phần lãi | Phân bố, nhất là phần đuôi |
| Lỗ trung bình một lệnh thua | Độ lớn trung bình của phần lỗ | Cùng thứ như trên |
| Tỷ lệ lãi trên lỗ | Lãi trung bình chia lỗ trung bình | Số lệnh mà nó được tính trên đó |
| Profit factor | Tổng phần lãi chia cho tổng phần lỗ tính theo giá trị tuyệt đối | Một lệnh rất lớn có thể một mình kéo cả tỷ số |
| Số lệnh còn mở ở ngày cuối kỳ | Có vị thế nào chưa đóng khi kỳ kết thúc không | Kết quả cuối cùng của chính vị thế đó |
Nhóm này trả lời câu hỏi "kết quả trên có đứng trên bao nhiêu quan sát". Nó là nhóm quyết định xem ba nhóm còn lại có nghĩa hay không, và đây là chỗ bài này sẽ quay lại kỹ ở mục về số lệnh.
Riêng profit factor có một chỗ tinh vi cần nói trước: đại lượng mà một công cụ gọi là profit factor không nhất thiết được tính trên cùng một thứ với tổng phần trăm lãi lỗ của từng lệnh, và việc thay nhầm hai đại lượng đó vào nhau tạo ra một sai số đo được. Chuyện đó là nội dung của kỳ vọng toán học của một hệ thống, bài cuối chuỗi này.
Nhóm 4: đo so với cái gì
| Chỉ tiêu | Đo cái gì | Vì sao bắt buộc |
|---|---|---|
| Lợi nhuận của phép mua và giữ cùng kỳ | Kết quả nếu chỉ mua ở đầu kỳ rồi giữ tới cuối kỳ, cùng mã cùng cửa sổ | Đây là phương án thay thế rẻ nhất và đơn giản nhất |
| Vượt mua và giữ | Hiệu số giữa lợi nhuận của chiến lược và của phép mua giữ | Không có nó thì không biết công sức bỏ ra đổi lấy gì |
Nhóm này chỉ có hai dòng nhưng là nhóm dễ bị bỏ nhất, và bỏ nó thì cả bảng mất nghĩa. Một chiến lược cho +50% trong 10 năm nghe như một kết quả. Cùng kỳ đó phép mua và giữ cho +385% thì con số +50% không còn là một kết quả nữa, nó là một khoản mất mát so với việc không làm gì.
Vì vậy, một quy tắc trình bày mà bài này tự áp và sẽ giữ tới cuối: mọi bảng kết quả backtest trong bài đều có cột vượt mua và giữ, cho mọi dòng, ngay trong chính bảng đó. Không đẩy xuống một mục khác, không in cho vài dòng tiện rồi bỏ những dòng còn lại.
Sơ đồ bốn khối xếp thành hàng ngang, mỗi khối ghi tên một nhóm chỉ tiêu backtest và liệt kê các chỉ tiêu thuộc nhóm đó, khối thứ nhất được đánh dấu là khối duy nhất phần lớn người đọc nhìn tới
Câu chốt: một bảng kết quả chỉ có nhóm thứ nhất là một bảng chưa đọc được, vì nó chưa nói đường đi thế nào, đứng trên bao nhiêu quan sát, và so với cái gì.
Cặp số trung tâm: cùng một mã, gần cùng lợi nhuận, khác gấp đôi độ sâu
Bây giờ tới phần đo được.
Hai cấu hình dưới đây chạy trên cùng một mã, HPG, một cổ phiếu ngành thép niêm yết trên HOSE, trong cùng một cửa sổ 10 năm, với cùng một mức phí và cùng một mức trượt giá 0.23% một vòng. Con số 0.23% không phải một tham số mặc định: nó là sàn vật lý suy ra từ lưới bước giá của chính mã đó tại phiên 04/09/2026, tức một bước giá 50 đ chia cho thị giá 21,700 đ. Vì sao phải dùng sàn của chính mã thay vì một con số dùng chung, mục về giả định ở dưới sẽ nói.
Mã cụ thể ở đây chỉ là một điểm dữ liệu. Nó được nêu tên vì cặp kết quả này đo trên một chuỗi giá có thật và người đọc cần biết chuỗi nào, không phải vì có nhận định nào về doanh nghiệp. Không có dòng nào trong bài là khuyến nghị mua hay bán mã này.
| Cấu hình A | Cấu hình B | |
|---|---|---|
| Lợi nhuận tổng | +49.53% | +46.40% |
| Sụt giảm tối đa | −68.71% | −36.93% |
| Số lệnh trong 10 năm | 5 | 45 |
| Tỷ lệ thắng | 60.00% | 44.44% |
| Profit factor | 2.60 | 1.23 |
| Chỉ số Sharpe | thấp hơn B | cao hơn A |
| Lệnh còn mở ở ngày cuối kỳ | 1 | 0 |
| Vượt mua và giữ | thua hơn 335 điểm phần trăm | thua hơn 335 điểm phần trăm |
Số liệu chốt 04/09/2026, nguồn HOSE và FinLens tổng hợp. Bảng có đúng hai dòng cấu hình và cả hai dòng đều có cột vượt mua và giữ.
Ba điều đọc ra từ bảng này, theo thứ tự tăng dần độ khó chịu.
Điều thứ nhất, cái ai cũng thấy. Lợi nhuận tổng chênh 3.13 điểm phần trăm, sụt giảm tối đa chênh 31.78 điểm phần trăm. Tỷ số giữa hai khoảng chênh ấy là hơn mười lần. Nếu chỉ đọc dòng đầu, hai cấu hình gần như không phân biệt được; nếu đọc dòng thứ hai, chúng thuộc hai thế giới khác nhau.
Điều thứ hai, cái khó chịu hơn. Cấu hình A không chỉ hơn về lợi nhuận tổng. Nó hơn cả về tỷ lệ thắng (60.00% so với 44.44%) và hơn cả về profit factor (2.60 so với 1.23). Ba chỉ tiêu mà người ta hay dùng để đánh giá một chiến lược đều chỉ về phía A. Và A chính là cấu hình có sụt giảm sâu gần gấp đôi cùng chỉ số Sharpe thấp hơn.
Nghĩa là mệnh đề "lợi nhuận tổng gây hiểu nhầm" còn chưa đủ mạnh. Mệnh đề đúng là: tỷ lệ thắng và profit factor cũng có thể chỉ ngược hướng với rủi ro mà người cầm cổ phiếu thực sự phải chịu. Không có một chỉ tiêu nào trong nhóm 1 và nhóm 3 thay được cho một chỉ tiêu của nhóm 2.
Điều thứ ba, cái quan trọng nhất. Cả hai cấu hình đều thua phép mua và giữ hơn 335 điểm phần trăm trong cùng cửa sổ đó. Bảng này không có dòng nào đọc được thành lời khen cho cấu hình nào. Nó là bảng của hai kết quả cùng kém so với việc không làm gì, và điều duy nhất nó chứng minh là hai kết quả cùng kém ấy vẫn có thể khác nhau rất xa ở chỗ mà lợi nhuận tổng không nhìn thấy.
| Mốc | Lợi nhuận tổng (%) | Độ sâu sụt giảm tối đa (%) |
|---|---|---|
| Cấu hình A, 5 lệnh | 49.53 | 68.71 |
| Cấu hình B, 45 lệnh | 46.4 | 36.93 |
Chốt số liệu 04/09/2026. Cùng một mã thép trên HOSE, cùng cửa sổ, cùng phí, cùng trượt giá 0.23% một vòng. Cột thứ hai là ĐỘ SÂU của khoản sụt giảm, tức một khoản lỗ, vẽ theo trị tuyệt đối để cùng thang với cột thứ nhất. Cả hai cấu hình đều thua phép mua và giữ hơn 335 điểm phần trăm trong cùng kỳ. Nguồn: HOSE, FinLens tổng hợp.
Hai cặp cột này là toàn bộ luận điểm của bài, vẽ ra thành hình. Cột trái của hai nhóm gần bằng nhau. Cột phải thì không.
Câu chốt: khi lợi nhuận tổng, tỷ lệ thắng và profit factor cùng chỉ về một cấu hình, đó vẫn chưa phải lý do để chọn nó, vì cả ba đều không đo đường đi.
Sáu điều phải nói kèm bảng trên
Một bảng như trên rất dễ bị trích ra khỏi bối cảnh. Sáu điều dưới đây không phải phần chú thích cho đủ lệ bộ, chúng là phần làm cho bảng trên trung thực.
Một: "60% thắng" thực ra là 3 lệnh trên 5
Cấu hình A có đúng 5 lệnh trong 10 năm, và một trong số đó còn đang mở tại ngày cuối kỳ. Tỷ lệ thắng 60.00% của nó là 3 lệnh lãi trên 5 lệnh.
Đây là lý do vì sao cột số lệnh nằm ngay trong bảng chính chứ không nằm trong một ghi chú cuối mục. Một tỷ lệ tính trên 5 quan sát và một tỷ lệ tính trên 45 quan sát trông giống hệt nhau khi in ra dưới dạng phần trăm, và chúng không phải hai con số cùng loại.
Hai: toàn bộ khoảng cách sụt giảm sinh ra từ đúng một lệnh
Khoảng chênh 31.78 điểm phần trăm giữa hai mức sụt giảm không đến từ một đặc tính chung nào của cấu hình A. Nó đến từ đúng một lệnh:
| Thông số của lệnh đó | Giá trị |
|---|---|
| Ngày vào | 25/01/2022 |
| Ngày thoát | 12/07/2023 |
| Số ngày nắm giữ | 533 |
| Mức lỗ tạm thời sâu nhất trong lúc đang giữ | −64.03% |
Một lệnh, giữ 533 ngày, và trong quãng đó số dư giả định có lúc mất 64.03% so với mức trước khi vào lệnh.
Chi tiết này phải nói ra, vì nếu không nói thì người đọc mặc định con số −68.71% là một đặc tính bền của cấu hình A, kiểu như "cấu hình này thường sụt sâu". Không phải. Nó là hậu quả của một sự kiện đơn lẻ. Điều đó không làm con số nhẹ đi chút nào, ngược lại: một chỉ tiêu quyết định bởi một quan sát duy nhất thì càng không có cơ sở để tin nó sẽ lặp lại theo cùng độ lớn, theo bất kỳ chiều nào.
Nó cũng nối thẳng vào một chuyện đã bàn ở kế hoạch thoát lệnh: trong 533 ngày ấy, quy tắc không có điều kiện thoát nào được kích hoạt. Backtest ghi lại một lệnh; người thật cầm vị thế ấy sẽ trải qua gần một năm rưỡi.
Ba: đây là một mã, trong một pha chu kỳ hàng hoá rất mạnh
Kết quả trên đo trên một cổ phiếu ngành thép, trong một cửa sổ 10 năm chứa một pha chu kỳ hàng hoá rất mạnh. Không có cơ sở nào để suy rộng cặp số này sang mã khác, ngành khác, hay cửa sổ khác.
Đây không phải câu rào đón. Nó là một giới hạn cụ thể: cùng một bộ quy tắc chạy trên một mã ngành khác, trong một cửa sổ khác, sẽ cho một cặp số khác, và không có gì bảo đảm khoảng chênh giữa lợi nhuận tổng và sụt giảm vẫn giữ được cùng chiều. Cặp số này chứng minh rằng hiện tượng đó xảy ra được, không chứng minh nó thường xảy ra.
Bốn: sụt giảm của chiến lược và sụt giảm của phép mua giữ chưa so được với nhau
Con số −68.71% và −36.93% đo trên đường vốn của chiến lược, tức số dư giả định của tài khoản, bao gồm cả những quãng chiến lược đang đứng ngoài thị trường và số dư không đổi.
Bài này chưa đo mức sụt giảm tối đa của phép mua và giữ trên cùng mã cùng kỳ. Vì vậy không có câu nào trong bài so hai con số đó với nhau, và người đọc cũng không nên tự làm phép so ấy trong đầu. Cột vượt mua và giữ trong bảng chính so về lợi nhuận, không so về sụt giảm.
Năm: đây là mô phỏng, không phải kết quả giao dịch
Toàn bộ con số trong bảng là kết quả của một phép mô phỏng chạy trên dữ liệu giá quá khứ, với phí và trượt giá do người chạy đặt vào. Không có lệnh nào trong số đó từng được đặt vào một sổ lệnh thật. Kết quả quá khứ, kể cả kết quả quá khứ có thật, cũng không bảo đảm cho kết quả tương lai; một kết quả mô phỏng thì còn cách xa hơn một bước nữa.
Sáu: cặp số này tìm được sau khi quét 30 cấu hình
Điều cuối cùng là điều thẳng thắn nhất, và nó tự nói về chính bài này.
Cặp cấu hình A và B ở trên không phải hai cấu hình đầu tiên được thử. Chúng là kết quả của việc quét 30 cấu hình rồi tìm trong đó một cặp có lợi nhuận tổng gần bằng nhau mà sụt giảm khác xa nhau.
Nói cách khác: người đi tìm biết trước mình muốn thấy hình dạng gì, và đã quét đủ nhiều để tìm ra một cặp có hình dạng ấy.
Điều đó có làm cặp số mất giá trị không? Không, nhưng nó giới hạn rất chặt cái mà cặp số được phép chứng minh. Cặp số này chứng minh hiện tượng này tồn tại, tức có những cặp cấu hình mà lợi nhuận tổng và sụt giảm nói hai chuyện khác nhau. Nó không chứng minh hiện tượng này phổ biến, và càng không chứng minh cấu hình nào tốt hơn cấu hình nào.
Và có một tầng nữa. Việc phải quét 30 lần mới ra cặp số mong muốn chính là một minh hoạ sống cho thứ mà chuỗi bài này đang cảnh báo: khi quét đủ nhiều cấu hình trên một tập dữ liệu, gần như luôn tìm được một cấu hình có hình dạng mình muốn. Cơ chế đó và cách nó biến kết quả trong mẫu thành ảo ảnh là nội dung của vì sao tối ưu tham số hay dẫn tới overfit.
Một bảng kết quả không kèm câu "bảng này là cái thứ mấy trong bao nhiêu cái đã thử" là một bảng thiếu thông tin quan trọng nhất về nó.
Sơ đồ trục thời gian ngang với một đoạn dài được tô đậm kéo từ tháng 01/2022 tới tháng 07/2023, bên dưới là một đường vốn lõm xuống rất sâu đúng trong đoạn đó rồi hồi lên, các đoạn còn lại của trục gần như phẳng
Câu chốt: sáu điều trên không làm bảng kết quả yếu đi, chúng làm bảng kết quả đúng với cái nó thật sự đo được.
Số lệnh quyết định mọi tỷ lệ khác
Mục này tách riêng vì nó là chỗ hay bị bỏ nhất và cũng là chỗ dễ kiểm nhất.
Mọi tỷ lệ trong nhóm 3, gồm tỷ lệ thắng, lãi trung bình, lỗ trung bình, tỷ lệ lãi trên lỗ và profit factor, đều có cùng một mẫu số: số lệnh. Khi mẫu số nhỏ, cả bốn con số ấy đều lung lay theo cùng một cách.
Phép đo độ lung lay, tính thẳng ra được
Không cần lý thuyết thống kê nào để thấy vấn đề. Chỉ cần hỏi: nếu một lệnh trong chuỗi đổi kết quả, tỷ lệ thắng đổi bao nhiêu?
| Cấu hình | Số lệnh | Tỷ lệ thắng hiện tại | Nếu một lệnh thắng thành thua | Mức đổi |
|---|---|---|---|---|
| A | 5 | 60.00% (3 trên 5) | 40.00% (2 trên 5) | 20.00 điểm phần trăm |
| B | 45 | 44.44% (20 trên 45) | 42.22% (19 trên 45) | 2.22 điểm phần trăm |
Cùng một sự kiện, một lệnh duy nhất đổi kết quả, và hậu quả lên chỉ tiêu chênh nhau khoảng chín lần. Với cấu hình A, một phiên khớp lệnh khác đi vài bước giá cũng đủ để tỷ lệ thắng đổi 20 điểm phần trăm. Con số 60.00% ấy không mô tả một đặc tính của chiến lược, nó mô tả kết cục của 5 sự kiện.
Có ngưỡng số lệnh tối thiểu không
Câu trả lời trung thực: bài này không nêu một con số ngưỡng, vì không tìm được căn cứ công khai và kiểm chứng lại được cho thị trường Việt Nam. Các con số ngưỡng thường được nhắc trong tài liệu giao dịch đều là quy ước truyền miệng, không kèm dữ liệu và không kèm điều kiện áp dụng, nên chép lại một con số như vậy vào đây sẽ là dựng một cái mốc giả có vẻ chắc chắn.
Cái làm được, và làm được ngay, là phép tính vừa rồi: lấy chuỗi lệnh của mình, giả sử một lệnh đổi kết quả, rồi xem chỉ tiêu đổi bao nhiêu. Nếu một lệnh làm đổi hai chữ số điểm phần trăm thì con số đang xem không mang thông tin về chiến lược, nó mang thông tin về một vài phiên cụ thể.
Còn một điều nữa cần nói kèm, và nó đi ngược trực giác. Số lệnh nhiều hơn không phải là tốt hơn. Nó chỉ làm các tỷ lệ đứng vững hơn về mặt số học. Đổi lại, mỗi lệnh là một lần trả phí và một lần chịu trượt giá, nên tần suất cao là một khoản chắc chắn mất để đổi lấy một chỉ tiêu đáng tin hơn. Đây là một đánh đổi thật, không phải một lời khuyên chọn tần suất, và độ lớn của nó là nội dung của bài chi phí trong chuỗi này. Cùng cơ chế ấy đã xuất hiện ở khung thời gian và tính nhất quán dưới dạng khung càng ngắn thì chi phí ăn càng sâu.
Câu chốt: trước khi đọc bất kỳ tỷ lệ nào trong một bảng backtest, tìm mẫu số của nó; nếu bảng không in mẫu số, đó đã là một câu trả lời.
Công cụ backtest giả định gì, và vì sao phải hỏi
Đây là phần mà một bảng kết quả gần như không bao giờ in ra, trong khi nó quyết định con số ở mọi dòng.
Một cỗ máy backtest phải trả lời ba câu hỏi trước khi tính được lệnh đầu tiên. Nếu công cụ không cho người dùng thấy câu trả lời của nó, thì mọi con số nó in ra đều đang đứng trên những giả định mà người đọc không biết.
Giả định thứ nhất: lệnh khớp ở đâu
Câu hỏi là: khi quy tắc phát tín hiệu, lệnh được coi là khớp ở mức giá nào và ở phiên nào.
Ba câu trả lời phổ biến, với hậu quả rất khác nhau:
| Quy ước khớp lệnh | Nó giả định gì | Vấn đề |
|---|---|---|
| Khớp tại giá đóng cửa của chính phiên ra tín hiệu | Người ra quyết định biết giá đóng cửa trước khi phiên đóng | Dùng một con số chưa tồn tại tại thời điểm quyết định |
| Khớp tại giá mở cửa của phiên kế tiếp | Có người bán ngay tại giá mở cửa với đủ khối lượng | Hợp lý hơn, nhưng vẫn giả định khớp trọn vẹn tại một mức |
| Khớp tại giá đóng cửa của phiên kế tiếp | Chờ hết phiên rồi mới vào | Bỏ mất phần biến động trong phiên đó |
Quy ước thứ nhất là quy ước tiện nhất để lập trình và cũng là quy ước sai một cách kín đáo nhất. Nó thuộc một lớp lỗi rộng hơn, gọi chung là dùng dữ liệu chưa có tại thời điểm ra quyết định, và lớp lỗi ấy có bài riêng trong chuỗi này: sai lệch sống sót và sai lệch nhìn trước.
Có một chi tiết Việt Nam làm câu hỏi này gai góc hơn. Giá đóng cửa trên HOSE và HNX không phải một giao dịch khớp lệnh liên tục mà là kết quả của một phiên khớp lệnh định kỳ; trên UPCoM thì lại là một giao dịch khớp lệnh liên tục cụ thể. Ba nơi giao dịch, ba bản chất khác nhau cho cùng một chữ "giá đóng cửa", chuyện đã bàn ở đọc một cây nến. Một backtest khớp lệnh tại giá đóng cửa vì thế đang giả định người tham gia đặt được lệnh vào một phiên định kỳ và khớp đúng ở mức giá mà chính phiên đó xác định ra sau.
Giả định thứ hai: phí tính thế nào
Phần lớn công cụ nhận một tham số phí dưới dạng tỷ lệ phẳng cho mỗi chiều. Điều đó bỏ qua ít nhất ba thứ có thật:
- Cấu trúc phí thực tế không phải một con số duy nhất, và có những khoản chỉ phát sinh ở một chiều.
- Thuế thu nhập cá nhân đối với chuyển nhượng chứng khoán tính theo giá trị bán, tức chỉ ở chiều bán.
- Một số khoản có mức tối thiểu, nên với lệnh nhỏ thì tỷ lệ thực tế cao hơn tỷ lệ danh nghĩa.
Bài này không dựng lại bảng phí, vì nó đã có đầy đủ ở chi phí thật của một giao dịch. Điều cần làm khi đọc một backtest là kiểm xem tham số phí trong đó có phản ánh đủ cấu trúc thật hay không, và nếu công cụ chỉ nhận một con số phẳng thì phải biết con số đó đang thiếu gì.
Giả định thứ ba: trượt giá bằng bao nhiêu
Đây là giả định sai nhiều nhất, vì nó thường được để nguyên ở giá trị mặc định.
Trượt giá là phần chênh giữa mức giá mà backtest ghi nhận và mức giá thật sự khớp được. Nó có ít nhất hai thành phần: chênh lệch giữa giá chờ mua tốt nhất và giá chờ bán tốt nhất, và phần giá bị đẩy đi khi lệnh lớn hơn khối lượng đang chờ ở mức đó. Cơ chế của thành phần thứ hai nằm ở khối lượng giao dịch nói lên điều gì.
Ở thị trường Việt Nam có một điều rất cụ thể: thành phần thứ nhất không thể nhỏ hơn một bước giá, vì giá chỉ nhận các bội số của bước giá. Lưới bước giá đặt một cái sàn cho mọi khoảng cách giá, và cơ chế đó đã được dựng trong hỗ trợ và kháng cự thực chất là gì.
Áp vào chính mã dùng ở bảng trên: bước giá 50 đ trên thị giá 21,700 đ tại phiên 04/09/2026 cho một cái sàn 0.2304% cho một vòng mua bán, tức khoảng 0.1152% mỗi chiều. Đó là lý do bảng ở trên chạy với 0.23% chứ không phải một con số tròn nào khác.
Vì sao chuyện này quan trọng: nhiều công cụ đặt mặc định 0.10% một vòng, và con số đó thấp hơn sàn vật lý của rất nhiều mã. Nó không sai đều cho mọi mã, nó sai theo một chiều biết trước, và mức sai khác nhau tuỳ mã, tuỳ vùng giá, tuỳ nơi giao dịch. Bảng đầy đủ của cái sàn ấy trên nhiều mã và ở cả hai lưới giá là trục của bài chi phí giao dịch ăn mòn lợi nhuận thế nào; bài này chỉ dùng đúng con số của mã đang xét.
Trượt giá không đo trực tiếp được từ dữ liệu giá
Con số 0.2304% ở trên là một cái sàn suy ra từ lưới bước giá, không phải mức trượt giá đo được. Dữ liệu giá lịch sử công khai không chứa sổ lệnh, nên không có cách nào lấy ra chênh lệch giữa giá chờ mua và giá chờ bán tại từng thời điểm trong quá khứ, cũng không có cách nào đo phần giá bị đẩy đi theo quy mô lệnh. Nghĩa là mọi con số trượt giá trong mọi backtest đều là một tham số do người chạy đặt vào, không phải một đại lượng đo được. Điều duy nhất biết chắc là nó không thể nhỏ hơn một bước giá. Vì lý do đó, bài này không in bảng ngưỡng hoà vốn tới nhiều chữ số thập phân trên một tham số chưa đo được.
Kết luận của mục này
Nếu một công cụ backtest không nói nó khớp lệnh ở giá nào, tính phí ra sao và đặt trượt giá bằng bao nhiêu, thì con số nó in ra không đọc được. Đó không phải một lời chê công cụ, đó là một hệ quả logic: cùng một bộ quy tắc trên cùng một chuỗi giá cho ra những kết quả khác nhau tuỳ ba giả định ấy, nên biết kết quả mà không biết giả định thì không biết mình đang cầm cái gì.
Sơ đồ ba hộp xếp dọc ghi ba giả định của một backtest là khớp lệnh, phí và trượt giá, mỗi hộp có một mũi tên chỉ sang cột bên phải ghi điều kiện thực tế tương ứng ở sổ lệnh
Câu chốt: ba giả định về khớp lệnh, phí và trượt giá không phải chi tiết kỹ thuật, chúng là những thứ quyết định con số ở mọi dòng của bảng kết quả.
Bốn chỗ thị trường Việt Nam làm một backtest lệch đi
Phần này ngắn hơn các mục trước vì mỗi chỗ đều đã có một bài riêng dựng kỹ. Việc của mục này là nối chúng vào đúng chỗ trong một backtest.
Biên độ dao động: có phiên lệnh không khớp được
Mỗi phiên, giá bị chặn trên bởi giá trần và chặn dưới bởi giá sàn. Hệ quả lên cây nến, gồm cả chuyện nến bị cắt cụt ở hai đầu, nằm trong đọc một cây nến.
Hệ quả riêng cho backtest thì khác và cụ thể hơn: một backtest thấy trong dữ liệu rằng phiên đó có giao dịch ở một mức giá, nên nó cho lệnh khớp ở mức giá đó. Nhưng ở một phiên mà giá nằm ở sàn và bên mua gần như vắng mặt, một lệnh bán thật có thể xếp hàng cả phiên mà không khớp. Backtest không mô phỏng hàng đợi trong sổ lệnh, nó chỉ đọc bốn con số giá của phiên. Nghĩa là những phiên mà việc thoát lệnh khó nhất lại đúng là những phiên mà backtest tự tin nhất.
Chiều ngược lại cũng vậy với lệnh mua ở một phiên trần.
Lưới bước giá: mọi ngưỡng phần trăm đều có một cái sàn
Đã nói ở mục trượt giá, và còn một hệ quả thứ hai. Một quy tắc dạng "thoát khi giá giảm 2% so với giá vào" nghe như một quy tắc dùng chung được cho mọi mã. Nhưng độ mịn nhỏ nhất mà chuỗi giá ghi lại được khác nhau theo mã và theo vùng giá, nên cùng một ngưỡng 2% không có cùng độ chặt trên hai mã khác nhau. Cơ chế đầy đủ ở hỗ trợ và kháng cự thực chất là gì.
Giao dịch thoả thuận: một phần khối lượng không đi qua sổ lệnh
Nếu một quy tắc dùng khối lượng làm điều kiện, chẳng hạn "chỉ vào lệnh khi khối lượng vượt trung bình 20 phiên", thì con số khối lượng ấy phải là khối lượng khớp lệnh trong sổ lệnh, không phải tổng có kèm giao dịch thoả thuận. Hai bên của một giao dịch thoả thuận tự thống nhất giá và khối lượng rồi báo cáo qua hệ thống, nên phần khối lượng đó không phải thứ mà một lệnh thường có thể khớp vào. Chuyện này đã dựng đầy đủ ở khối lượng giao dịch nói lên điều gì.
Hệ quả cho backtest rất trực tiếp: một điều kiện khối lượng chạy trên cột tổng có thể phát tín hiệu ở đúng những phiên mà thanh khoản trong sổ lệnh không hề tăng.
Khoảng trống giá giả và chuỗi gãy vì luật
Đây là chỗ nguy hiểm nhất vì nó không báo lỗi.
Trên chuỗi giá chưa điều chỉnh quyền, ngày giao dịch không hưởng quyền tạo ra một bước nhảy hành chính trông giống hệt một khoảng trống giá do thị trường tạo ra. Một lệnh mua trước ngày đó và bán sau ngày đó được tính lãi lỗ trên hai con số không cùng gốc toạ độ, nên phần trăm lãi lỗ của lệnh ấy sai theo đúng mức điều chỉnh. Cơ chế ở xu hướng và cấu trúc giá, còn bản chất của ngày đó ở ngày giao dịch không hưởng quyền.
Cùng loại là chuyện chuỗi bị gãy vì luật: mã vào diện hạn chế giao dịch làm chuỗi thủng hoặc bị phần mềm lấp bằng những cây nến phẳng chưa từng tồn tại, và mã đổi sàn thì đổi luôn cả biên độ lẫn lưới bước giá giữa chừng cửa sổ mô phỏng. Chi tiết ở diện cảnh báo, kiểm soát và hạn chế giao dịch.
Một backtest chạy qua những đoạn ấy không hề dừng lại. Nó tính, và nó in ra một con số.
Thêm một chỗ ít ai để ý: kỳ nghỉ Tết
Mọi cửa sổ tham số trong phân tích kỹ thuật đếm phiên, không đếm thời gian. Một cửa sổ 20 phiên bình thường trải trên khoảng bốn tuần lịch. Một cửa sổ 20 phiên vắt qua kỳ nghỉ Tết trải trên một khoảng dài hơn hẳn, vì thị trường đóng cửa nhiều ngày liên tiếp.
Hệ quả kép cho một backtest. Thứ nhất, tham số của chỉ báo không còn tương ứng với cùng một khoảng thời gian thật ở mọi chỗ trong chuỗi. Thứ hai, một lệnh mở trước kỳ nghỉ chịu rủi ro của cả quãng thị trường đóng cửa mà backtest không ghi nhận thêm phiên nào cho nó. Chuyện đếm nến không phải đếm thời gian đã được dựng ở khung thời gian và tính nhất quán.
Còn một ràng buộc nữa, thuộc loại cứng: chu kỳ thanh toán ở thị trường cơ sở Việt Nam là T+2 và chưa có giao dịch trong ngày, nên một quy tắc đòi quay vòng nhanh hơn thế không thực hiện được, dù backtest vẫn chạy và vẫn in ra kết quả. Đường đi của một lệnh và các mốc thời gian của nó nằm ở một lệnh mua đi qua những khâu nào.
Câu chốt: một backtest không bao giờ báo lỗi khi dữ liệu bên dưới nó không đồng nhất; nó chỉ in ra một con số, và con số ấy trông giống hệt một con số đúng.
Backtest mất tác dụng khi nào
Đây là mục quan trọng nhất của bài. Backtest là một phép mô phỏng, và như mọi phép mô phỏng, có những đầu vào mà kết quả của nó không mang thông tin.
| Tình huống | Vì sao kết quả không đọc được |
|---|---|
| Tập mã không gồm những mã đã rời sàn trong kỳ | Chỉ những mã sống sót tới hôm nay được đưa vào, nên kết quả lệch lên theo một chiều biết trước |
| Quy tắc ra quyết định bằng giá đóng cửa rồi khớp ngay tại chính giá đó | Dùng một con số chưa tồn tại tại thời điểm ra quyết định |
| Chuỗi giá chưa điều chỉnh quyền | Lệnh vắt qua ngày không hưởng quyền tính lãi lỗ trên hai gốc toạ độ khác nhau |
| Cửa sổ mô phỏng chứa mốc đổi sàn của mã | Biên độ và lưới bước giá đổi giữa chừng, hai đoạn chuỗi thuộc hai chế độ |
| Cửa sổ chứa quãng mã ở diện hạn chế hoặc đình chỉ | Chuỗi thủng, hoặc được lấp bằng những cây nến phẳng chưa từng tồn tại |
| Tín hiệu bán rơi vào phiên giá sàn | Backtest cho khớp trọn vẹn, sổ lệnh thật có thể không có bên mua |
| Tín hiệu mua rơi vào phiên giá trần | Cùng cơ chế, ở chiều ngược lại |
| Số lệnh quá ít | Mọi tỷ lệ trong nhóm 3 mô tả vài sự kiện chứ không mô tả chiến lược |
| Quy mô vốn giả định lớn so với thanh khoản của mã | Trượt giá thật vượt xa tham số, và phần vượt không đo được từ dữ liệu giá |
| Trượt giá đặt dưới sàn vật lý của chính mã đó | Kết quả tốt lên theo một chiều biết trước, mức tốt lên khác nhau tuỳ mã |
| Điều kiện khối lượng chạy trên cột tổng có kèm giao dịch thoả thuận | Tín hiệu xuất hiện ở những phiên mà thanh khoản trong sổ lệnh không tăng |
| Quy tắc đòi quay vòng nhanh hơn T+2 | Không thực hiện được ở thị trường cơ sở, backtest vẫn in ra kết quả |
| Cửa sổ chỉ trải một pha của một chu kỳ | Kết quả mô tả pha đó, không mô tả quy tắc |
| Kết quả đến từ một hoặc hai lệnh chiếm phần lớn tổng lãi | Chỉ tiêu mô tả vài sự kiện đơn lẻ, không mô tả một đặc tính lặp lại |
| Cấu hình được chọn sau khi quét nhiều cấu hình, không có kỳ ngoài mẫu | Kết quả phản ánh công sức đi tìm nhiều hơn phản ánh quy tắc |
Ba dòng cuối đáng nhấn, vì chúng là ba dòng mà bài này tự dính vào ít nhất một: cặp số trung tâm ở trên tìm được sau khi quét 30 cấu hình, và khoảng cách sụt giảm của nó sinh ra từ đúng một lệnh. Bài đã nói ra cả hai, và đó là lý do nó chỉ được phép kết luận rằng hiện tượng ấy tồn tại chứ không được kết luận gì hơn.
Câu chốt: một backtest chỉ có nghĩa khi biết nó đã bỏ qua cái gì, và danh sách trên là danh sách những cái nó bỏ qua mà không báo.
Những chỗ bài này cố ý không khẳng định
Mục này liệt kê những chỗ mà một bài viết dễ dãi sẽ khẳng định, và bài này không.
Không khẳng định cấu hình nào tốt hơn cấu hình nào. Cả hai đều thua phép mua và giữ hơn 335 điểm phần trăm trong cùng kỳ. Bảng ở trên chứng minh hai chỉ tiêu nói hai chuyện khác nhau, không chọn ra người thắng.
Không khẳng định hiện tượng lợi nhuận tổng che mất sụt giảm là phổ biến. Cặp số duy nhất đo được ở đây tìm ra sau 30 lần quét. Nó chứng minh sự tồn tại, không chứng minh tần suất. Muốn nói về tần suất thì phải chạy trên một tập cấu hình khai trước và báo cáo toàn bộ phân bố, việc mà bài này không làm.
Không nêu một ngưỡng số lệnh tối thiểu. Không có căn cứ công khai kiểm chứng lại được cho thị trường Việt Nam, nên bài đưa một phép đo độ nhạy thay cho một con số ngưỡng.
Không so mức sụt giảm của chiến lược với mức sụt giảm của phép mua và giữ. Con số thứ hai chưa được đo trong cùng phép chạy, nên phép so ấy không có cơ sở.
Không nêu một con số trượt giá "đúng". Chỉ nêu cái sàn suy từ lưới bước giá, và nói rõ phần vượt lên trên cái sàn ấy không đo được từ dữ liệu giá công khai.
Không in công thức của chỉ số Sharpe. Cách các công cụ tính khác nhau ở ít nhất bốn lựa chọn, và bài không kiểm được công cụ nào chọn cách nào.
Không suy rộng từ một mã ngành thép sang mã khác hay ngành khác. Cửa sổ 10 năm đó chứa một pha chu kỳ hàng hoá rất mạnh, và điều đó đủ để chặn mọi phép suy rộng.
Không xếp hạng chỉ báo hay chiến lược. Chỉ báo nào nhanh hơn chỉ báo nào là câu hỏi mà thứ hạng đo được thay đổi giữa các mã, nên mọi bảng xếp hạng loại ấy đều tự mâu thuẫn. Chuyện đó là nội dung của chỉ báo trễ và chỉ báo dẫn.
Câu chốt: một bài viết về backtest mà không có mục này thì chính nó cũng đang mắc lỗi mà nó đi cảnh báo.
Bảy câu hỏi trước khi tin một bảng kết quả backtest
Gộp toàn bộ bài lại thành một danh sách dùng được ngay khi mở một bảng kết quả ra, dù bảng đó do mình chạy hay do người khác đưa.
- Sụt giảm tối đa bằng bao nhiêu? Nếu bảng không có dòng này, bảng chưa đọc được, vì lợi nhuận tổng không đo đường đi.
- Số lệnh bằng bao nhiêu? Đây là mẫu số của tỷ lệ thắng, profit factor và mọi con số trung bình. Thử cho một lệnh đổi kết quả rồi xem chỉ tiêu đổi bao nhiêu.
- Lợi nhuận của phép mua và giữ cùng kỳ bằng bao nhiêu, và hiệu số là bao nhiêu? Không có cột này thì không biết công sức bỏ ra đổi lấy gì.
- Kết quả có phụ thuộc vào một hoặc hai lệnh không? Bỏ lệnh lớn nhất ra rồi tính lại, xem kết quả còn lại bao nhiêu.
- Bảng này là cái thứ mấy trong bao nhiêu cấu hình đã thử, và có kỳ ngoài mẫu không? Câu hỏi này thường không được trả lời, và im lặng ở đây là một câu trả lời.
- Công cụ khớp lệnh ở giá nào, tính phí ra sao, đặt trượt giá bằng bao nhiêu? Riêng trượt giá, so với sàn suy từ bước giá của chính mã đó ở vùng giá tương ứng.
- Chuỗi giá đã điều chỉnh quyền chưa, và trong cửa sổ có mốc đổi sàn, quãng bị hạn chế giao dịch, hay kỳ nghỉ dài nào không?
Bảy câu này không giúp tìm ra một chiến lược tốt. Chúng chỉ giúp loại bỏ những bảng kết quả không mang thông tin, và ở lĩnh vực này thì đó đã là phần việc lớn hơn.
Đọc tiếp gì
Bài này mở chuỗi "Kiểm chứng một phương pháp". Ba bài còn lại đi thẳng từ chỗ bài này dừng: sai lệch sống sót và sai lệch nhìn trước xử lý các cách dữ liệu tự làm đẹp kết quả trước khi phép tính bắt đầu; chi phí giao dịch ăn mòn lợi nhuận thế nào đo cụ thể cái sàn trượt giá trên nhiều mã và hai lưới giá; kỳ vọng toán học của một hệ thống ghép tỷ lệ thắng với tỷ lệ lãi trên lỗ thành một con số duy nhất, và chỉ ra một phép suy thường dùng sai.
Nếu bảng kết quả đang xem là bảng của một cấu hình được chọn sau khi quét nhiều bộ tham số, vì sao tối ưu tham số hay dẫn tới overfit là bài đọc kèm bắt buộc.
Năm bài nền của chuỗi "Nền tảng đồ thị" đứng dưới mọi thứ trong bài này: đọc một cây nến, khối lượng giao dịch nói lên điều gì, xu hướng và cấu trúc giá, hỗ trợ và kháng cự thực chất là gì và khung thời gian và tính nhất quán.
Về phía rủi ro, sụt giảm tối đa và thời gian hồi phục là bài giải thích kỹ chỉ tiêu quan trọng nhất trong bảng kết quả, còn quy mô vị thế cho thấy vì sao cùng một chuỗi lệnh với hai quy mô khác nhau cho hai đường vốn khác hẳn nhau.
Nội dung trong bài mang tính chia sẻ kiến thức, không phải khuyến nghị mua bán chứng khoán và không phải tư vấn đầu tư. Mã cổ phiếu được nêu chỉ để chỉ rõ chuỗi giá mà phép mô phỏng chạy trên đó, không hàm ý bất kỳ nhận định nào về doanh nghiệp. Toàn bộ kết quả backtest trong bài là mô phỏng trên dữ liệu quá khứ với phí và trượt giá do người chạy giả định, không phải kết quả giao dịch thật; số liệu chốt ngày 04/09/2026, do FinLens tổng hợp từ dữ liệu giao dịch của HOSE. Kết quả quá khứ không bảo đảm cho kết quả tương lai.
Câu hỏi thường gặp
Backtest là gì?
Backtest là phép chạy lại một bộ quy tắc mua bán đã khai rõ trên dữ liệu giá của quá khứ, rồi ghi lại xem bộ quy tắc đó sinh ra những lệnh nào và số dư tài khoản giả định biến động ra sao. Nó không phải một phép kiểm chứng theo nghĩa khoa học, vì kết quả phụ thuộc vào một loạt giả định do người chạy tự đặt: cửa sổ thời gian, tập mã, giá dùng để khớp lệnh, phí và trượt giá. Đổi bất kỳ giả định nào trong số đó là đổi kết quả.
Vì sao lợi nhuận tổng là chỉ tiêu tệ nhất để đánh giá một backtest?
Vì nó chỉ đọc hai con số ở hai đầu kỳ và bỏ đi toàn bộ đường đi ở giữa. Trên cùng một mã và cùng một cửa sổ 10 năm, đo được hai cấu hình có lợi nhuận tổng +49.53% và +46.40%, tức chênh nhau 3.13 điểm phần trăm, trong khi mức sụt giảm sâu nhất của đường vốn lần lượt là −68.71% và −36.93%, tức chênh nhau 31.78 điểm phần trăm. Con số ở đầu ra gần như giống nhau còn trải nghiệm trên đường đi thì khác hẳn nhau.
Tỷ lệ thắng cao có nghĩa là chiến lược tốt hơn không?
Không nhất thiết, và có ca đo được chỉ ngược lại. Trong cặp cấu hình nêu ở trên, cấu hình có tỷ lệ thắng 60.00% và profit factor 2.60 lại chính là cấu hình có sụt giảm tối đa sâu gần gấp đôi cấu hình có tỷ lệ thắng 44.44% và profit factor 1.23. Ngoài ra tỷ lệ 60.00% ở đây được tính trên đúng 5 lệnh trong 10 năm, tức 3 lệnh lãi trên 5 lệnh, nên nó không mang ý nghĩa thống kê nào.
Số lệnh trong một backtest bao nhiêu thì đủ để tin?
Không có ngưỡng nào có căn cứ công khai, kiểm chứng lại được, cho thị trường Việt Nam, nên bài này không nêu một con số ngưỡng. Nhưng độ nhạy thì tính thẳng ra được: với 5 lệnh, chỉ cần một lệnh đổi kết quả là tỷ lệ thắng nhảy từ 60.00% xuống 40.00%, tức 20.00 điểm phần trăm; với 45 lệnh, một lệnh đổi kết quả chỉ làm tỷ lệ thắng đổi từ 44.44% xuống 42.22%, tức 2.22 điểm phần trăm. Cùng một sự kiện, hai mức độ lung lay khác hẳn nhau.
Backtest của một công cụ giả định gì về khớp lệnh và chi phí?
Thường là ba điều, và công cụ hay không nói ra: lệnh khớp trọn vẹn tại một mức giá đã có sẵn trong dữ liệu, phí là một tỷ lệ phẳng không phụ thuộc quy mô, và trượt giá là một tham số cố định không tăng theo khối lượng lệnh. Cả ba đều là những điều không đúng với sổ lệnh thật. Riêng tham số trượt giá còn có một cái sàn vật lý do lưới bước giá đặt ra và nó khác nhau theo từng mã, nên một tham số dùng chung cho mọi mã là sai theo một chiều biết trước.
Cập nhật lần cuối:
Đọc tiếp
Nội dung trong bài mang tính chia sẻ kiến thức, không phải khuyến nghị mua bán. Mọi quyết định đầu tư và rủi ro đi kèm thuộc về người đọc.