KenKem Journal

Làm Sao Kiểm Chứng Một Backtest Khi Chính Bạn Viết Ra Cỗ Máy Backtest Đó?

· #backtesting #research-method #tick-data #software-engineering #systematic-trading

Bạn dựng một cách hiện thực thứ hai, và không tin cái nào cho tới khi hai bên tái tạo được kết quả của nhau. Đó là câu trả lời ngắn. Một backtest do một người viết rồi cũng chính người đó kiểm tra là một con số không có nhân chứng độc lập, và người muốn tin nó nhất chính là người đã viết ra nó.

Mình là kỹ sư phần mềm trước khi là trader, và đây là phần của giao dịch định lượng mà không ai đưa vào ảnh chụp màn hình. Dưới đây là bộ máy kiểm chứng mình thực sự vận hành, bao gồm cả lần nó bắt được lỗi của chính mình.

Cận cảnh đồng hồ so Mitutoyo trên bàn xưởng, đọc tới đơn vị phần trăm milimet
Một thiết bị đo không ai hiệu chuẩn là một nguồn cung cấp số liệu sai đầy tự tin. Ảnh: Adinath Gilande / Pexels.

Vì sao bạn không nên tin một backtest do chính mình viết?

Vì bạn cũng là người viết ra các phép kiểm tra, nên theo đúng cấu trúc, bạn chia sẻ mọi điểm mù với chúng. Một lỗi làm đẹp kết quả sẽ không tự thông báo. Nó xuất hiện dưới dạng một đường cong vốn đẹp, đúng thứ bạn đang mong đợi, nên không có phần nào trong bạn muốn nhìn kỹ hơn.

Trong một công việc kỹ thuật bình thường luôn có người review, có bộ phận kiểm thử, có sự cố khiến bạn ngượng trước đồng nghiệp. Một người nghiên cứu đơn độc thì không có gì trong số đó. Mọi áp lực phản biện đều phải được dựng vào quy trình một cách chủ ý, từ trước, ở thời điểm bạn chưa có kết quả nào và vì vậy chưa có lợi ích gắn với câu trả lời.

Điều đó định nghĩa lại công việc. Phần lớn thời gian của mình không dành để tìm edge. Nó dành để xây dựng lý do nhằm nghi ngờ những edge mình tìm được.

Chạy hai engine độc lập thì bắt được điều gì?

Bắt được lỗi thật trong chính code của mình, và đó là lý do duy nhất khiến quy tắc này tồn tại được dù nó rất phiền.

Mọi chiến lược đều đi qua hai phần mềm hoàn toàn tách biệt. Cái thứ nhất là một phòng thí nghiệm viết bằng C++, xây cho độ rộng, đủ nhanh để mô phỏng hàng nghìn cấu hình trên dữ liệu tick thật. Điều đó quan trọng, vì lựa chọn thay thế là chỉ kiểm tra ba ý tưởng chợt nảy ra vào một ngày thứ Ba rồi gọi đó là một cuộc tìm kiếm. Để phát hành được ba hệ thống, engine đó đã mô phỏng 7.718 cấu hình khác nhau, tức khoảng hai nghìn rưỡi cấu hình cho mỗi hệ thống sống sót.

Cái thứ hai là MetaTrader 5, cũng chạy trên tick thật, và đó là tòa án. Nó mô phỏng sàn, quá trình khớp lệnh, mức giá thực nhận, toàn bộ phần hiện thực không hào nhoáng vốn quyết định một lợi thế lý thuyết có sống sót khi chạm vào tài khoản thật hay không. Khi hai bên mâu thuẫn, MetaTrader thắng và engine của mình là thứ phải sửa. Phía sau ba hệ thống đã phát hành là 178 lần chạy đối chứng độc lập trên MetaTrader, mỗi lần đều được cấu hình và chạy bằng tay.

Hai thiết bị phát tín hiệu phòng thí nghiệm giống hệt nhau đặt cạnh nhau trên bàn tối màu
Hai thiết bị cùng đo một thứ chỉ có ích chừng nào chúng còn được phép bất đồng với nhau. Ảnh: Ludovic Delot / Pexels.

Quy tắc quan trọng đến trước cả hai: chúng phải tái tạo được kết quả của nhau trên cùng một cửa sổ thời gian trước đã. Ngưỡng chấp nhận là một phần trăm về lãi lỗ ròng, không được có lệnh nào không khớp ở cả hai phía, không sai lệch chiều lệnh và không sai lệch lý do thoát lệnh. Một lần không đạt được xem là lỗi engine, chứ không phải một khác biệt quan điểm thú vị. Kể cả một lần đối chiếu tốt cũng chỉ là gần khớp chứ không phải bằng chứng, nên engine nhanh chỉ được phép xếp hạng các cấu hình, không bao giờ được phép chứng nhận một cấu hình nào.

Phép kiểm tra đó đã bắt được mình một lần đúng nghĩa. Trong một lần chạy tham chiếu, engine của chính mình thổi phồng kết quả khoảng 48 phần trăm, do ba lỗi chồng lên nhau. Bộ nạp cấu hình âm thầm bỏ rơi một khóa, khiến engine vào những lệnh mà bộ quy tắc chạy thật không bao giờ vào. Một giá trị biến động được lấy từ sai cây nến, nến đã đóng thay vì nến đang hình thành, khiến mọi mức dừng lỗ bị giới hạn đều rộng hơn vài phần trăm so với đúng. Khoảng chênh còn lại thu về khoảng một phần trăm theo hướng thận trọng, tức là đạt. Mọi kết luận mình rút ra trong khoảng thời gian đó đều sai. Mình không phát hiện ra nhờ cẩn thận, mình phát hiện ra vì hai cách hiện thực nhất quyết không chịu đồng ý với nhau và mình không thể làm cho khoảng chênh đó biến mất chỉ bằng cách mong nó biến mất. Cách sửa có giá trị lâu dài không phải bản vá, mà là bắt cả hai bộ nạp báo lỗi thật to khi gặp một khóa chúng không nhận ra, thay vì lặng lẽ bỏ qua.

Bản năng đó cũng áp dụng khi dữ liệu mới cuối cùng cũng tới. Hai tháng dữ liệu được giữ lại đã được nhập vào và phát lại đúng một lần, không tinh chỉnh gì. Trước khi đọc bất kỳ con số mới nào, đường ống phát lại được chứng minh là đúng bằng cách chạy lại tháng trước đó qua nó và xác nhận nó tái tạo các bản ghi cũ từng lệnh một, 119 trên 119 ở một hệ thống và 39 trên 39 ở hệ thống còn lại. Chỉ sau đó kết quả mới mới được đọc. Chứng minh thiết bị đo trước, rồi mới đo, và phải theo đúng thứ tự đó, vì sau khi đọc kết quả rồi bạn sẽ không còn phân biệt được mình đang làm việc nào nữa.

Vì sao cái nhãn dán trên một tệp tick không có ý nghĩa gì?

Vì một tệp có thể được bán dưới tên dữ liệu tick trong khi thực chất là tick do phần mềm tự sinh, bị làm mỏng, hoặc đầy lỗ hổng, và mọi thứ được kiểm tra trên đó sẽ âm thầm đẹp hơn mức đáng có.

Trước hết hãy nói vì sao cần tick. Một cây nến một phút cho bạn biết giá mở ở đâu, đóng ở đâu, và chạm tới các mức cực trị nào. Nó không cho bạn biết các mức cực trị đó xảy ra theo thứ tự nào. Bên trong cây nến đó, giá có thể đã chạy tới mục tiêu trước rồi mới tới stop, hoặc tới stop trước rồi mới tới mục tiêu, và cây nến trông y hệt nhau trong cả hai trường hợp. Với thứ gì đó giữ lệnh vài phút thay vì vài ngày, đó không phải chi tiết nhỏ. Đó chính là kết quả của lệnh.

Một backtest dựng trên nến buộc phải đoán đường đi của giá, và mọi quy ước đoán mà mình biết đều hào phóng với chiến lược trong tình huống này và tàn nhẫn trong tình huống khác. Kết quả vì vậy mang một hệ số bù mà bạn không nhìn thấy và không đo được. Dữ liệu tick loại bỏ việc phải đoán, vì đường đi của giá chính là dữ liệu chứ không phải thứ được dựng lại sau đó.

Bài học thứ hai thì mình mất nhiều thời gian hơn, và nó đo được. Mình xác minh lịch sử tick bằng mật độ trước khi cho bất kỳ phần nào của nó tiến gần tới một kết luận. Một trình kiểm thử tự sinh tick sẽ cho ra bốn tick mỗi phút hoặc ít hơn. Một tệp xuất thật từ sàn cho cùng thị trường đó chạy trong khoảng 55 tới 660 tick mỗi phút. Khoảng cách này không hề tinh vi khi bạn chịu đếm, và việc đếm là thứ duy nhất phân biệt được hai tệp. Mật độ cũng thay đổi theo tuổi dữ liệu trên cùng một nguồn. Các sàn làm mỏng phần lịch sử cũ, nên cùng một nguồn cho khoảng 66 tick mỗi phút vào đầu năm 2024 và khoảng 470 vào cuối năm 2025, tức là một backtest trên đoạn cũ đang làm việc với ít thông tin hơn hẳn so với đoạn gần đây. Một năm dữ liệu vàng trong kho của mình vào khoảng 40 triệu tick trải trên 312 ngày giao dịch. Một tệp tự nhận là cùng loại nhưng chỉ có một phần nhỏ con số đó đang nói cho bạn biết điều gì đó.

Gần như mọi backtest scalping mình từng thấy trình bày công khai đều chạy trên nến, và gần như không ai nhắc tới điều đó. Thường thì không phải do thiếu trung thực. Phần lớn mọi người không biết là đường đi của giá đã bị mất.

Thế nào là một mô hình chi phí trung thực?

Là tính khoản phí ngay bên trong mô phỏng, trên từng lệnh, thay vì trừ một con số ước lượng ở phút cuối.

Mỗi lệnh đều phải trả commission, phần spread bạn vượt qua, và slippage giữa mức giá bạn muốn với mức giá bạn thật sự nhận được. Một chiến lược giao dịch càng nhiều thì những khoản đó càng chồng lên nhau, và một hệ thống trông rất đẹp trên giấy hoàn toàn có thể lật thành thua khi bạn áp chi phí thực tế. Một backtest bỏ qua chi phí không phải là phiên bản hơi lạc quan của chiến lược của bạn. Nó là một chiến lược khác, thứ bạn không thể giao dịch được ngoài đời. Điều kiện kiểm thử của mình tính spread, slippage, commission, phí qua đêm và độ trễ khớp lệnh 15 mili giây trên từng lệnh, chạy trên tick vàng thật, và những con số mình công bố là thứ đi ra ở đầu bên kia.

Trừ chi phí sau khi chạy xong còn tệ hơn nghe tưởng, vì chi phí thay đổi cả việc lệnh nào được mở. Một vị thế mà engine sẽ không bao giờ mở dưới điều kiện ma sát thật vẫn nằm trong bản ghi không chi phí, kéo theo cả kết quả của nó. Mô hình hóa khoản phí ngay từ đầu là lý do duy nhất giúp mình chẩn đoán được giai đoạn tệ nhất của mình: trong năm 2024, spread trên vàng ngốn khoảng 8,6 phần trăm ATR, so với khoảng 3 đến 4 phần trăm ở các giai đoạn xung quanh. Điều đó nhìn thấy được trong một mô phỏng có tính chi phí và vô hình trong một mô phỏng không tính.

Làm cho đúng cũng không tự động, và kiểu hỏng ở đây đáng được gọi tên. Một trong các sàn mình dùng tính toàn bộ commission khứ hồi ngay trên lệnh vào, còn tệp xuất theo từng lệnh của mình lại bỏ sót khoản đó, nên một tập số liệu đã lưu nằm trên nền chi phí bị tính thiếu cho tới khi lỗi được phát hiện và sửa vào tháng 8 năm 2026. Chi phí đã được tính đúng bên trong mô phỏng, chỉ có tệp xuất đếm sai, và các con số bị ảnh hưởng lạc quan hơn thực tế khoảng 11,5 phần trăm cho tới khi được đính chính. Đó đúng là kiểu lỗi chỉ lộ ra khi bạn so sánh hai đường dẫn khác nhau tới cùng một con số.

Sự hoài nghi tương tự áp dụng cho chính dữ liệu. Những bộ dữ liệu lịch sử âm thầm loại bỏ những gì đã chết, các trường hợp phá sản và hủy niêm yết, đang mô tả một quá khứ mà không ai thực sự trải qua. Mình giao dịch hai sản phẩm là vàng và bitcoin, nên survivorship bias không phải rủi ro sắc nhất của mình, nhưng câu hỏi nền tảng vẫn hữu ích: các khoản lỗ đã đi đâu, và mình có nhận ra không nếu dữ liệu của mình đã xóa chúng từ trước?

Vì sao thêm núm vặn lại khiến chiến lược tệ đi?

Vì với đủ nhiều núm vặn, bạn có thể fit hoàn hảo bất kỳ quá khứ nào mà không dự đoán được gì, và trong suốt quá trình đó việc fit mang lại cảm giác của sự tiến bộ.

Cho một model đủ nhiều threshold được chỉnh tay, nó sẽ mô tả rất chi tiết những tai nạn ngẫu nhiên của một đoạn lịch sử cụ thể. Những tai nạn đó sẽ không lặp lại. Overfitting cũng không cần tới một trăm tham số mới xuất hiện. Nó đến với chỉ hai, rồi cộng dồn theo mỗi rule bạn thêm vào để cứu rule trước đó.

Vì vậy số lần bạn đã thử quan trọng ngang với chất lượng của thứ bạn tìm được. Sinh ra đủ nhiều ứng viên thì một kết quả trông xuất sắc sẽ xuất hiện thuần túy do ngẫu nhiên. Nên các thí nghiệm đều được đăng ký kèm tiêu chí đạt và không đạt viết ra trước khi biết kết quả. Trong lần thống kê mình công bố vào tháng 8 năm 2026, sổ đăng ký lưu 137 thí nghiệm, và 122 trong số đó chưa bao giờ trở thành sản phẩm: 45 bị bác bỏ hoàn toàn, 5 dừng giữa chừng, 72 giữ lại ở mức nghiên cứu. Chúng vẫn tra cứu được, nằm ngay cạnh những cái sống sót, để không ai phải tin lời mình về tỷ lệ giữa hai bên. Khi đã nhìn thấy kết quả, bạn luôn có thể dựng ra một lý do để nó được tính, và đó chính xác là lý do quy tắc phải được tuyên bố từ trước.

Sự trung thực với dữ liệu ngoài mẫu cũng vận hành theo cách đó, và ở đây rất dễ nói quá. Mình có thể nói rằng một cửa sổ hai tháng đã được giữ lại và chỉ đọc một lần, vì đó là điều đã xảy ra và ngày tháng nằm trong hồ sơ. Mình không thể nói như vậy về một giai đoạn xác nhận cũ hơn vốn đã hiện diện khi một ngưỡng được chọn, dù quy tắc lựa chọn chỉ nhìn vào cửa sổ gần đây. Câu nói bảo vệ được thì hẹp hơn câu nói ấn tượng, nên câu hẹp hơn mới là câu được công bố.

Vì sao tài khoản thật của mình vẫn chạy bản build của tháng trước?

Trên laptop của mình có một phiên bản hệ thống tốt hơn phiên bản đang giao dịch bằng tiền thật, và nó sẽ ở yên trên laptop, vì đúng lý do khiến một backtest có ý nghĩa gì đó.

Một backtest là tuyên bố về một cấu hình cụ thể, đã đóng băng. Ngay khoảnh khắc mình thay đổi thứ gì đó, toàn bộ kết quả mình tích lũy được trở thành mô tả về một hệ thống không còn tồn tại. Cứ phát hành từng cải tiến ngay khi tìm ra, thì thứ đang xử lý tiền của bạn sẽ không bao giờ xây được lịch sử hoạt động. Nó chỉ có một chuỗi các bản ghi ngắn, đứt quãng, thuộc về một chuỗi các hệ thống hơi khác nhau, và không bản ghi nào đủ dài để nói lên điều gì.

Nên các thay đổi phải chờ, và một bản phát hành phải tự kiếm lấy đường ra. Quy tắc là một bản build mới phải tái tạo được đúng bài kiểm tra mà nó được duyệt dựa trên đó, trước khi được phép chạm vào tài khoản thật. Khi cơ chế sàn biến động được phát hành vào tháng 8 năm 2026, bản binary phát hành tái tạo lần chạy tham chiếu của nó một cách giống hệt tới từng byte, 1.034 lệnh khớp chính xác, và đó là cách chứng minh rằng thay đổi bạn vừa làm là thay đổi duy nhất đã xảy ra. Các cải tiến vượt ra ngoài đó sẽ đi vào một bài kiểm tra tiến về phía trước trên tài khoản demo chạy thật, trong điều kiện thật trên thị trường hiện tại, nơi mình không thể nhìn trộm đáp án rồi tự thuyết phục bản thân phát hành sớm. Bài kiểm tra đó hiện vẫn là một hạng mục còn nợ chứ chưa hoàn tất, và việc nói ra điều đó cũng thuộc về cùng một kỷ luật.

Hai thói quen nhỏ hơn cũng ra đời từ cùng lập luận, cả hai đều là vết sẹo. Tên tệp của bản phát hành giờ mang theo số phiên bản, vì một lần triển khai âm thầm ghi đè lên binary đang chạy thật sẽ khiến bạn không còn nói được thứ gì đang chạy. Và mỗi tệp cấu hình được phát hành đều ghim đủ cả 62 tham số điều chỉnh được, thay vì để hàng chục tham số phụ thuộc vào những gì hộp thoại tình cờ còn nhớ. Cái thứ hai là vết sẹo vì đã có lần một bản build chạy thật bỏ qua mười thiết lập quan trọng suốt nhiều tuần và chạy một cấu hình không tồn tại trong bất kỳ tệp nào và bất kỳ bài kiểm tra nào. Không có gì sập cả. Nó chỉ đơn giản không phải hệ thống mà mình tưởng mình đang chạy, và đó là kiểu hỏng tệ hơn cả sập, vì sập thì ít ra nó còn báo cho bạn biết.

Phần khó chịu thì mình nói thẳng: mình đang cố ý chạy một thứ chưa tối ưu, và đôi khi mình ngồi nhìn bản mới chạy tốt hơn trong lúc bản cũ đang giao dịch. Đó là cái giá để có thể nói rằng lịch sử hoạt động thuộc về đúng cái đã tạo ra nó.

Nếu mọi edge đều suy giảm, thứ gì đáng giữ lại?

Khả năng phân biệt thứ gì là thật, vì nó sống lâu hơn bất kỳ thứ cụ thể nào bạn xây bằng khả năng đó.

Một backtest mười năm rực rỡ hoàn toàn có thể được nâng lên bởi một market regime giờ đã không còn tồn tại. Thị trường đi qua nhiều pha khác nhau, yên ắng và biến động mạnh, mean-reverting và trending, và cạnh tranh thì ăn mòn. Một chiến lược đóng băng tham số vĩnh viễn thực chất đang âm thầm cược rằng thế giới không bao giờ thay đổi, mà thế giới thì luôn thay đổi. Tên gọi lịch sự của chuyện đó là alpha decay.

Điều này có vẻ mâu thuẫn với việc đóng băng một bản build, và cách hóa giải đáng được nói rõ. Đóng băng là thứ khiến một bản ghi có ý nghĩa trong một cửa sổ thời gian xác định. Rà soát lại là thứ ngăn bản ghi đó biến thành di vật. Một cấu hình giữ nguyên trong suốt thời gian nó đang được thử thách, và mọi thay đổi với nó phải được kiếm về qua đúng chuỗi bằng chứng như mọi thứ khác, chứ không phải vì một ý tưởng mới nghe hay hơn. Câu hỏi không bao giờ chỉ là nó từng hoạt động không. Câu hỏi là nó còn hoạt động không, và mình sẽ nhận ra lúc nó dừng bằng cách nào.

Tự động hóa làm quy trình trung thực hơn ra sao, chứ không chỉ nhanh hơn?

Vì một lịch chạy thì không biết mệt, không bỏ một ngày vì thị trường nhạt, và không âm thầm hạ tiêu chuẩn vào tuần thứ chín.

Gần như mọi công việc lặp lại ở đây giờ đều chạy không cần người trông. Biểu đồ được chụp, phân tích phiên được viết và gửi đi. Nội dung được kết xuất, được đối chiếu với chính bộ quy tắc tuân thủ của nó, rồi được đăng ra các kênh. Không có phần nào trong đó là miễn phí. Mỗi công việc như vậy lấy của mình một buổi tối, vài cái lấy vài buổi, vì các kiểu hỏng thú vị chỉ tồn tại khi chạy thật: một trình lên lịch chạy tay thì ổn nhưng chết trong môi trường tối giản, một bước đăng bài đánh dấu đã gửi trong khi chỉ một phần số kênh chấp nhận, một cơ chế dọn dẹp đúng về kỹ thuật nhưng phá hoại về vận hành.

Điểm quan trọng không phải là số giờ tiết kiệm được. Điểm quan trọng là công việc tiếp tục theo cùng một cách mỗi lần, bao gồm cả những phần của quy trình mà nhiệm vụ duy nhất là làm kết quả của chính mình xấu đi. Tính nhất quán không phải phẩm chất mình sẵn có. Đó là kết quả mình dựng ra bằng kỹ thuật, vì mình quá biết sự nhất quán của mình trông ra sao khi nó phụ thuộc vào việc mình có nhớ hay không.

Thực ra đó là toàn bộ lập luận. Cấu hình được quản lý phiên bản, nên một kết quả luôn truy ngược được về đúng bộ thiết lập đã tạo ra nó. Các thất bại vẫn tra cứu được, nằm cạnh các thành công. Chi phí được tính ngay bên trong mô phỏng. Hai cách hiện thực phải đồng thuận trong sai số một phần trăm trước khi bên nào được tin. Quy tắc quyết định được viết ra trước khi nhìn thấy kết quả. Dữ liệu giữ lại chỉ được đọc một lần. Không điều nào trong số đó làm chiến lược tốt lên dù chỉ một điểm cơ bản. Mọi mục đều khiến kết quả mình công bố xấu đi, và đó chính là mục đích, vì mỗi mục đóng lại một con đường cụ thể mà qua đó mình có thể tự lừa mình mà không hay biết.

Mình không đề nghị ai tin vào kết quả của mình. Mình đang cố công bố đủ nhiều về cách chúng được tạo ra, để không ai cần phải tin.

Câu hỏi thường gặp

Làm sao kiểm chứng một engine backtest do chính bạn xây? Bằng cách bắt một cách hiện thực thứ hai, độc lập, tái tạo lại nó trước khi tin bên nào. Engine nghiên cứu viết bằng C++ của mình và MetaTrader 5 phải thống nhất về cùng một tập lệnh trên cùng một cửa sổ thời gian với dữ liệu tick thật, trong sai số một phần trăm về lãi lỗ ròng và không được có lệnh nào không khớp ở cả hai phía. Khi hai bên bất đồng, nền tảng giao dịch thắng và engine là thứ phải sửa. Quy tắc này tồn tại vì nó có tác dụng thật: engine của chính mình từng thổi phồng một lần chạy tham chiếu khoảng 48 phần trăm, do ba lỗi chồng lên nhau, trong đó có một khóa cấu hình mà bộ nạp âm thầm bỏ rơi.

Vì sao dùng hai engine backtest thay vì một engine tốt? Vì chúng trả lời hai câu hỏi khác nhau và không cái nào tự nó là đủ. Engine C++ được xây cho độ rộng, đủ nhanh để khám phá hàng nghìn cấu hình thay vì vài cái bạn tình cờ nghĩ ra, và đã có 7.718 cấu hình được chạy để phát hành ba hệ thống. MetaTrader 5 được xây cho tính hiện thực, mô phỏng sàn và quá trình khớp lệnh, với 178 lần chạy đối chứng được cấu hình bằng tay. Engine nhanh chỉ được tin để xếp hạng các cấu hình, không bao giờ để chứng nhận một cấu hình.

Backtest một chiến lược scalping có thực sự cần dữ liệu tick không? Có, và lý do rất cụ thể chứ không phải chuyện khẩu vị. Một cây nến một phút không ghi lại việc giá chạm mục tiêu hay chạm stop trước, và với một lệnh sống bên trong cây nến đó, thứ tự chính là toàn bộ kết quả. Các engine chạy trên nến buộc phải đoán đường đi của giá, và mọi quy ước đoán đều làm đẹp chiến lược trong điều kiện này và trừng phạt nó trong điều kiện khác.

Làm sao biết một tệp dữ liệu tick là thật? Bằng cách kiểm tra mật độ thay vì tin vào cái nhãn. Một trình kiểm thử tự sinh tick cho ra bốn tick mỗi phút hoặc ít hơn, còn một tệp xuất thật từ sàn cho cùng thị trường đó chạy khoảng 55 tới 660 tick mỗi phút. Các sàn cũng làm mỏng phần lịch sử cũ, nên cùng một nguồn cho khoảng 66 tick mỗi phút vào đầu năm 2024 và khoảng 470 vào cuối năm 2025, nên một backtest trên giai đoạn cũ đang làm việc với ít thông tin hơn hẳn so với giai đoạn gần đây.

Nên trừ chi phí giao dịch sau khi backtest hay mô hình hóa nó bên trong? Bên trong, trên từng lệnh, vì chi phí thay đổi cả việc lệnh nào được mở. Trừ một con số ước lượng ở phút cuối sẽ để lại trong bản ghi những vị thế mà ma sát thật đã ngăn không cho xảy ra. Các bài kiểm tra của mình tính spread, slippage, commission, phí qua đêm và độ trễ khớp lệnh 15 mili giây. Mô hình hóa khoản phí ngay từ đầu là lý do duy nhất giúp mình chẩn đoán được giai đoạn tệ nhất: trong năm 2024 spread trên vàng ngốn khoảng 8,6 phần trăm ATR so với khoảng 3 đến 4 phần trăm ở giai đoạn lân cận, đó là phép tính số học chứ không phải chiến lược hỏng.

Đã có bao nhiêu thí nghiệm thất bại? 122 trên 137, theo lần thống kê công bố vào tháng 8 năm 2026. Mỗi thí nghiệm đều được đăng ký kèm tiêu chí đạt và không đạt viết ra trước khi biết kết quả: 45 bị bác bỏ hoàn toàn, 5 dừng giữa chừng, 72 giữ lại ở mức nghiên cứu. Chúng vẫn tra cứu được, nằm cạnh các thành công, để không ai phải tin lời mình về tỷ lệ giữa hai bên.

Vì sao không cập nhật hệ thống giao dịch thật ngay khi cải tiến được nó? Vì một backtest là tuyên bố về một cấu hình đã đóng băng, và thay đổi nó sẽ vô hiệu hóa mọi kết quả bạn đã thu thập. Cập nhật liên tục thì hệ thống đang xử lý tiền của bạn không bao giờ tích lũy được một bản ghi đủ dài để có ý nghĩa. Ở đây một bản phát hành phải tái tạo được đúng bài kiểm tra mà nó được duyệt dựa trên đó trước khi tiến gần tài khoản thật, và các cải tiến tiếp theo phải chờ trong một bài kiểm tra tiến về phía trước trên demo, tức là mình đang cố ý chạy một thứ chưa tối ưu.

Đối chiếu hai engine có ý nghĩa gì nếu chúng không bao giờ giống hệt nhau? Ý nghĩa nằm ở độ lớn và nguyên nhân của khác biệt, không phải ở sự hoàn hảo. Một biên độ một phần trăm về lãi lỗ ròng mà không có lệnh nào không khớp là đủ gần để coi phần còn lại là nhiễu thời điểm của tick, còn bất kỳ khác biệt nào lớn hơn đều là một lỗi có nguyên nhân cụ thể đang chờ được tìm ra. Những sai lệch đáng lo là sai lệch về cấu trúc: một lệnh mà engine này vào còn engine kia thì không, một sai lệch chiều, một lý do thoát lệnh khác nhau.

Đây có phải kết quả giao dịch thật không? Không. Mọi con số ở đây là kết quả nghiên cứu: các lần chạy backtest, đối chiếu và kiểm định trên dữ liệu tick thật của sàn, cùng với số liệu đếm từ sổ đăng ký thí nghiệm. Cỡ mẫu trong chương trình này vẫn nằm dưới độ dài lịch sử tối thiểu mà mình muốn có trước khi coi bất cứ điều gì là đã ngã ngũ, và mình thà công bố điều đó còn hơn làm tròn nó đi. Mình có chạy một bài kiểm tra thật và có theo dõi nó, và mình sẽ công bố những gì nó cho thấy, nhưng trích dẫn kết quả nghiên cứu như thể đó là hiệu suất thật thì không trung thực.

Sản phẩm nào của KenKem làm việc gì? Indicator Master Volume Profiler chạy trên TradingView và trên MetaTrader 5, nó hiển thị cách đọc thị trường và để việc đặt lệnh lại cho bạn. Master Volume Sniper trên chợ MQL5 là phần Expert Advisor, và nó chỉ thực thi đúng những quy tắc cùng thiết lập rủi ro mà người dùng tự cấu hình cho mình. Cả hai đều không phải dịch vụ tín hiệu, và cả hai đều không loại bỏ việc bạn phải tự suy nghĩ.


Người viết: KenKem, một kỹ sư phần mềm và nhà sáng lập với hai mươi năm kinh nghiệm, đang học giao dịch định lượng một cách công khai và ghi lại toàn bộ quá trình, bao gồm cả những giả thuyết bị bác bỏ.

Bài viết này được tổng hợp từ loạt bài về phương pháp nghiên cứu và bên trong engine trong nhật ký xây dựng của KenKem. Chỉ nhằm mục đích giáo dục. Không phải lời khuyên đầu tư. Các con số được trích dẫn là kết quả rà soát, backtest và kiểm định trên dữ liệu tick thật, không phải lịch sử giao dịch thật. Hiệu suất trong quá khứ không đảm bảo kết quả trong tương lai.

← All journal articles

Chat