Mô phỏng Monte Carlo chiến lược trading — Rủi ro mà một backtest che giấu

Xác minh lần cuối: · Nội dung luôn có giá trị
Cảnh báo rủi ro · YMYL Bài viết này chỉ mang tính giáo dục và không phải là lời khuyên đầu tư. Giao dịch trên thị trường Forex tiềm ẩn rủi ro mất vốn cao — ESMA cho biết từ 74% đến 89% tài khoản nhà đầu tư bán lẻ thua lỗ. Giao dịch ký quỹ ngoại hối dành cho cá nhân không được cấp phép tại Việt Nam; hãy tham khảo ý kiến chuyên gia tài chính được cấp phép trước khi đưa ra bất kỳ quyết định nào.

Có lần một độc giả gửi cho tôi kết quả kiểm thử ngược (backtest) mà anh ấy rất tự hào: tỷ lệ thắng 55%, lệnh thắng trung bình 100 euro, lệnh thua trung bình 80 euro, lợi nhuận kỳ vọng trên giấy khoảng 3.800 euro mỗi năm. Những con số trông khá ổn — nhưng anh ấy mở tài khoản thực, mạo hiểm 5% mỗi lệnh và cháy tài khoản trong vòng sáu tháng. Anh ấy hỏi tôi sai ở đâu. Sai không phải ở chiến lược, mà ở việc xem một lần backtest như một sự thật tuyệt đối, trong khi mô phỏng Monte Carlo sẽ cho thấy rằng với cùng lợi thế và khối lượng lệnh đó, xác suất phá tài khoản vào khoảng 25%. Cuộc trò chuyện ấy là lý do tôi viết bài này.

Mô phỏng Monte Carlo chiến lược trading thực sự là gì

Monte Carlo là một phương pháp xác suất được đặt theo tên sòng bạc ở Monaco. Trong trading, ý tưởng này rất đơn giản: thay vì chỉ nhìn vào một đường vốn duy nhất mà lịch sử tạo ra, bạn tạo ra một nghìn chuỗi mới với cùng các thông số thống kê nhưng theo thứ tự khác nhau. Mỗi chuỗi vẽ ra một bức tranh tài khoản khác nhau, và tổng hợp lại chúng tạo thành đám mây các khả năng mà một lần kiểm thử ngược riêng lẻ không bao giờ có thể tiết lộ.

Một backtest đơn lẻ là một thực hiện của một quá trình ngẫu nhiên. Biến động xung quanh nó có thể rất lớn — đó là cách một trò chơi lặp đi lặp lại với lợi thế hoạt động. Mô phỏng Monte Carlo biến biến động đó thành những con số cụ thể mà bạn có thể hành động dựa trên đó.

Monte Carlo thực sự trả lời những câu hỏi gì

Mô phỏng cho bạn ba thứ mà một backtest đơn lẻ không thể cung cấp. Thứ nhất là mức sụt giảm vốn (drawdown) thực tế ở độ tin cậy 95% — độ sâu mà bạn không vượt qua trong 95 trong số 100 mô phỏng. Thứ hai là xác suất mất đi một phần đáng kể của tài khoản, chẳng hạn vốn giảm xuống dưới một nửa. Thứ ba là dải kết quả hàng năm có thể xảy ra trong khi lợi thế chiến lược vẫn không đổi.

Trong ví dụ minh họa của tôi, một chiến lược có tỷ lệ thắng 55%, lệnh thắng trung bình 100 euro, lệnh thua trung bình 80 euro và 200 lệnh mỗi năm có giá trị kỳ vọng khoảng 19 euro mỗi lệnh — 3.800 euro trên giấy. Mô phỏng một nghìn lần cho kết quả: median gần 3.750 euro; 5% tệ nhất kết thúc ở khoảng 500 euro lợi nhuận; 1% tệ nhất ở mức lỗ 800 euro; còn 5% tốt nhất vươn lên 7.500 euro. Cùng một lợi thế — chênh lệch năm lần.

Cách thực hiện mô phỏng trong Excel

Phiên bản không cần macro cũng đủ để bạn hiểu rõ chiến lược của mình. Trong các ô A1 đến A5, bạn nhập các thông số: tỷ lệ thắng 0,55; lệnh thắng trung bình 100; lệnh thua trung bình -80; số lệnh trong một chuỗi 200; và vốn ban đầu 10.000. Trong ô B1, bạn nhập công thức =IF(RAND()<A1, A2, A3) — hàm RAND của Excel trả về một giá trị từ không đến một, và khi giá trị đó thấp hơn tỷ lệ thắng, bạn nhận được lệnh thắng, ngược lại là lệnh thua.

Trong ô C1, bạn cộng vốn ban đầu vào giá trị ở B1 — đó là điểm đầu tiên của đường vốn. B2 dùng lại công thức tương tự, và C2 cộng giá trị ở C1 vào B2. Kéo cả hai cột xuống đến hàng 200. Vậy là bạn đã tạo ra một chuỗi năm đầy đủ.

Sao chép hai cột đó sang ngang một nghìn lần (B–C, D–E, F–G, v.v.) sẽ cho bạn một nghìn đường vốn độc lập. Từ các giá trị cuối, bạn tính =PERCENTILE.INC(phạm_vi, 0.5) để lấy median, rồi dùng 0,05 và 0,01 để xem 5% và 1% tệ nhất. Mỗi lần nhấn F9 sẽ tính lại toàn bộ các giá trị ngẫu nhiên — một nghìn lần mô phỏng mới chỉ với một thao tác. Thực sự là đủ.

Cách thực hiện tương tự trong Python với bootstrap

Python làm được những gì Excel không thể. Thứ nhất là tốc độ — hàng nghìn lần chạy chỉ mất vài giây. Thứ hai, quan trọng hơn, là kỹ thuật bootstrap: lấy mẫu không phải từ các thông số giả định mà từ danh sách giao dịch thực tế của bạn.

Bạn nhập NumPy, tải 100 hoặc hơn các giá trị P/L thực từ nhật ký giao dịch và viết new_sequence = np.random.choice(history, size=200, replace=True). Hàm np.cumsum biến danh sách P/L thành đường vốn, và một vòng lặp xung quanh nó tạo ra một nghìn lần chạy độc lập. Bạn đọc các phân vị bằng np.percentile và dùng Matplotlib để vẽ biểu đồ spaghetti — một nghìn đường cong chồng lên nhau với median và dải phân vị 5–95 được đánh dấu.

Bootstrap bảo toàn phần đuôi thực của phân phối — các khoản lỗ lớn, các chuỗi biến động, đôi khi là lệnh thắng kỷ lục trong một tuần biến động mạnh. Các giả định tham số học không làm được điều đó, vì chúng không giả định phân phối mà giao dịch của bạn thực sự có.

"Tỷ lệ rủi ro/lợi nhuận gần như không có ý nghĩa gì nếu không đưa quản lý khối lượng lệnh vào phương trình. Thông qua quản lý khối lượng lệnh, bạn có thể đạt được gần như bất kỳ mục tiêu nào bạn muốn." — Van K. Tharp, Trade Your Way to Financial Freedom, McGraw-Hill, 2007

Giới hạn thực tế — những gì Monte Carlo không thể làm

Mô phỏng tham số dựa trên hai giả định: các lệnh giao dịch độc lập với nhau và phân phối kết quả là ổn định. Cả hai đều bị vi phạm trong thị trường thực, đồng thời. Các khoản lỗ có xu hướng tập trung — khi chế độ thị trường thay đổi, nhiều lệnh liên tiếp có thể di chuyển cùng chiều, và mô hình lấy mẫu độc lập không thể tái tạo điều đó. Những đợt sụt giảm vốn nghiêm trọng nhất trong giao dịch thực thường trông tệ hơn phân vị 1% từ Monte Carlo, không phải tốt hơn.

Vấn đề thứ hai là mô phỏng sử dụng chính lịch sử mà bạn cung cấp cho nó. Nếu 100 lệnh của bạn chỉ bao gồm một xu hướng tăng trong EUR/USD, Monte Carlo sẽ không cho bạn biết gì về cách chiến lược hoạt động trong giai đoạn tích lũy kéo dài hay sau một biến động 200 pip do dữ liệu Mỹ. Đó là lý do tại sao nên kết hợp mô phỏng với phân tích walk-forward, giúp kiểm tra chiến lược qua các cửa sổ cuộn và phát hiện sự suy giảm lợi thế.

Những đợt sụt giảm vốn sâu nhất thường vượt qua phân vị 1% từ một lần Monte Carlo sạch. Hãy xem mô phỏng như một mức sàn xác suất, không phải trần nhà, và đọc nó cùng với tài liệu quản lý rủi ro chuyên sâu trên ForexMechanics để có bối cảnh đầy đủ hơn.

Lưu ý về môi trường pháp lý tại Việt Nam: giao dịch ngoại hối/CFD bán lẻ thông qua các broker nước ngoài không được cấp phép cho nhà đầu tư cá nhân theo quy định của Ngân hàng Nhà nước Việt Nam (NHNN). Các nội dung trong bài chỉ mang tính giáo dục về phương pháp quản lý rủi ro; đây không phải lời khuyên đầu tư và không hàm ý bất kỳ sàn giao dịch cụ thể nào được cấp phép hợp pháp tại Việt Nam.

Bước tiếp theo để thực sự áp dụng mô phỏng này

  1. Xuất lịch sử ít nhất 100 lệnh đã đóng từ nhật ký giao dịch hoặc nền tảng của bạn. Với ít hơn 100 lệnh, thống kê quá nhiễu để Monte Carlo có thể nói điều gì có ý nghĩa về phần đuôi phân phối. Nếu bạn chưa đủ dữ liệu, hãy giao dịch thêm sáu đến mười hai tuần nữa và quay lại bài tập này với mẫu đầy đủ hơn — chất lượng đầu vào quyết định chất lượng kết quả mô phỏng.
  2. Mở một bảng Excel trống và xây dựng phiên bản tham số được mô tả ở trên. Nhập tỷ lệ thắng, lệnh thắng trung bình, lệnh thua trung bình và vốn của riêng bạn, sao chép hai cột một nghìn lần, nhấn F9 và quan sát dải giá trị cuối. Một giờ làm việc đó sẽ cho bạn thấy rõ khoảng dao động thực sự rộng đến mức nào đằng sau "năm trung bình" của bạn. Đây là bước nền tảng thuộc phần xây dựng chiến lược của mọi trader nghiêm túc.
  3. Đọc phân vị 5% của drawdown tối đa từ một nghìn lần mô phỏng đó. Nếu nó chỉ ra mức giảm 30% trong khi ngưỡng chịu đựng tâm lý của bạn dừng lại ở khoảng 15%, vấn đề không phải là chiến lược mà là khối lượng lệnh. Giảm một nửa rủi ro mỗi lệnh và chạy lại cho đến khi mức sàn 5% nằm trong ngưỡng chịu đựng của bạn — đây là cốt lõi của quản lý rủi ro có hệ thống.
  4. Sau một năm giao dịch thực, chạy lại mô phỏng với lịch sử mới và so sánh với năm trước. Nếu median giảm xuống và phần đuôi mở rộng ra, lợi thế của bạn đang suy giảm — đó là thời điểm để hỏi liệu chiến lược có còn hoạt động không, chứ không chỉ là tiếp tục dưỡng nó theo quán tính. Đây là kỷ luật mà các trader dài hạn áp dụng để tồn tại qua nhiều chu kỳ thị trường.
Jarosław Wasiński
Giới thiệu tác giả

Jarosław Wasiński

Tổng biên tập MyBank.pl · Nhà phân tích tài chính và thị trường

Nhà phân tích và chuyên gia thực hành độc lập với hơn 20 năm kinh nghiệm trong lĩnh vực tài chính. Người sáng lập và tổng biên tập cổng thông tin MyBank.pl hoạt động từ năm 2004. Phân tích cơ bản thị trường ngoại hối và kinh tế vĩ mô từ năm 2007. Viết từ góc độ thị trường toàn cầu, chú trọng khung pháp lý quốc tế. Nội dung mang tính giáo dục; giao dịch Forex ký quỹ không được cấp phép cho nhà đầu tư cá nhân tại Việt Nam.

Nguồn và tài liệu tham khảo

  1. Bank for International Settlements Minimum capital requirements for market risk (d457) · Bazylejski standard pokazujący, jak instytucje liczą ryzyko rynkowe za pomocą expected shortfall i historycznej symulacji — analog Monte Carlo dla portfela. www.bis.org ↗
  2. Van Tharp Institute About Van K. Tharp · Strona biograficzna potwierdzająca autorstwo książki „Trade Your Way to Financial Freedom" (McGraw-Hill) i jego pracę nad position sizingiem oraz symulacją Monte Carlo dla traderów detalicznych. www.vantharp.com ↗
  3. NumPy Developers numpy.random.choice — Random sampling · Oficjalna dokumentacja funkcji losowania z powtórzeniami; podstawowe narzędzie do bootstrap resampling listy transakcji w Pythonie. numpy.org ↗
  4. Python Software Foundation random — Generate pseudo-random numbers · Oficjalna dokumentacja biblioteki standardowej Pythona z funkcjami random.choices i random.sample, używanymi do prostych symulacji Monte Carlo bez NumPy. docs.python.org ↗

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

Mô phỏng Monte Carlo chiến lược trading là gì?

Monte Carlo là một phương pháp xác suất được đặt theo tên sòng bạc Monaco. Trong trading, bạn lấy danh sách giao dịch lịch sử hoặc các thông số chiến lược — tỷ lệ thắng, lệnh thắng trung bình, lệnh thua trung bình — và thay vì nhìn vào một đường vốn duy nhất mà lịch sử tạo ra, bạn tạo ra một nghìn chuỗi mới theo thứ tự ngẫu nhiên. Mỗi chuỗi có cùng thống kê nhưng thứ tự thắng/thua khác nhau, nên mỗi chuỗi vẽ ra một bức tranh tài khoản khác nhau. Để làm gì: một backtest đơn lẻ là một thực hiện. Biến động xung quanh nó có thể rất lớn. Cùng một chiến lược với giá trị kỳ vọng khoảng 19 euro mỗi lệnh và 200 lệnh mỗi năm có thể cho median Monte Carlo gần 3.750 euro, nhưng phân vị 5% tệ nhất giảm xuống 500 euro và 5% tốt nhất vươn lên 7.500 euro. Khoảng dao động rất rộng dù lợi thế không đổi. Hiểu nhầm phổ biến nhất: "năm ngoái chiến lược kiếm được 5.000 euro, vậy năm nay cũng nên tương tự." Monte Carlo cho thấy dải thực tế khi giữ nguyên lợi thế có thể kéo dài từ 1.000 đến 10.000 euro — và không có gì bất thường ở đó. Đó chỉ đơn giản là biến động thống kê.

Làm thế nào để thực hiện mô phỏng Monte Carlo trong Excel?

Phiên bản đơn giản nhất không cần macro hay VBA. Trong các ô A1 đến A5, bạn nhập các thông số: tỷ lệ thắng (ví dụ 0,55), lệnh thắng trung bình (ví dụ 100), lệnh thua trung bình (ví dụ -80), số lệnh trong một chuỗi (ví dụ 200) và vốn ban đầu (ví dụ 10.000). Trong ô B1, bạn nhập công thức =IF(RAND()<A1, A2, A3) — hàm RAND của Excel trả về một giá trị từ không đến một, nếu giá trị đó thấp hơn tỷ lệ thắng thì bạn nhận được lệnh thắng, ngược lại là lệnh thua. Trong ô C1, cộng vốn ban đầu vào giá trị ở B1. B2 và C2 dùng cùng công thức, nhưng C2 tham chiếu đến C1. Kéo cả hai cột xuống đến hàng 200. Vậy là một chuỗi năm hoàn chỉnh. Sao chép hai cột đó sang ngang một nghìn lần để có một nghìn đường vốn độc lập. Từ các giá trị cuối, tính =PERCENTILE.INC(phạm_vi, 0.5) cho median, và 0,05, 0,01 để xem 5% và 1% tệ nhất. Nhấn F9 tính lại toàn bộ — mỗi lần nhấn là một nghìn mô phỏng mới. Excel xử lý điều này tốt và đủ để hiểu rõ chiến lược của bạn.

Làm thế nào để triển khai Monte Carlo trong Python?

Python thực hiện công việc tương tự nhanh hơn và cho phép bạn bootstrap: lấy mẫu từ danh sách giao dịch thực tế thay vì chỉ từ các thông số giả định. Bạn nhập NumPy, tải 100 hoặc hơn các giá trị P/L thực từ nhật ký giao dịch và viết new_sequence = np.random.choice(history, size=200, replace=True). Hàm np.cumsum biến danh sách P/L thành đường vốn, và một vòng lặp xung quanh nó tạo ra một nghìn lần chạy độc lập. Bạn đọc phân vị bằng np.percentile và dùng Matplotlib để vẽ biểu đồ spaghetti — một nghìn đường cong chồng lên nhau với median và dải phân vị 5–95 được đánh dấu nổi bật. Bootstrap bảo toàn phần đuôi thực của phân phối: những khoản lỗ lớn, các chuỗi biến động tập trung, đôi khi lệnh thắng kỷ lục trong một tuần biến động mạnh. Các giả định tham số học không tái tạo được điều này vì chúng không giả định phân phối mà giao dịch của bạn thực sự có. Một biểu đồ tiết lộ nhiều hơn về rủi ro chiến lược so với mười bảng số liệu.

Giới hạn của Monte Carlo trong trading là gì?

Monte Carlo không phải là tiên tri và cần nói thẳng điều đó. Giả định cơ bản của mô phỏng tham số là các lệnh giao dịch độc lập với nhau và phân phối kết quả ổn định. Trong thị trường thực, cả hai điều kiện này thường bị vi phạm đồng thời. Các khoản lỗ có xu hướng tập trung thành cụm — khi chế độ thị trường thay đổi, nhiều lệnh liên tiếp có thể di chuyển cùng chiều, và một mô hình lấy mẫu độc lập không thể tái tạo điều đó. Đó là lý do tại sao những đợt sụt giảm vốn nghiêm trọng nhất trong giao dịch thực thường trông tệ hơn phân vị 1% từ Monte Carlo, không phải tốt hơn. Vấn đề thứ hai là mô phỏng sử dụng chính lịch sử mà bạn cung cấp. Nếu 100 lệnh của bạn chỉ bao gồm xu hướng tăng trong EUR/USD, Monte Carlo sẽ không cho bạn biết gì về cách chiến lược hoạt động trong giai đoạn tích lũy kéo dài. Hệ quả thực tế: hãy xem kết quả Monte Carlo như một mức sàn xác suất, không phải trần nhà. Nếu kịch bản 5% tệ nhất chỉ ra mức giảm 30%, hãy giả định giao dịch thực có thể đào sâu hơn. Điều chỉnh khối lượng lệnh theo mức sàn đó, không phải theo median — như vậy một thất bại thực tế sẽ không đánh gục bạn.

Tìm hiểu sâu hơn · hướng dẫn đầy đủ