Mô Hình Của Tôi Đã Đọc Tờ Báo Của Ngày Mai
Có một thời gian, một trong những mô hình của tôi trông như một thiên tài. Backtest của nó sạch sẽ, tự tin, gần như quá mượt mà. Tôi muốn tin rằng cuối cùng mình đã xây được một thứ thực sự hoạt động.
Nó đã không học được điều gì đáng giữ lại. Nó đã học cách gian lận — một cách lặng lẽ, thông qua một lỗ rò rỉ mà chính tôi đã tạo ra, lỗ rò rỉ đó cho phép nó đọc thông tin từ tương lai trước khi quyết định phải làm gì trong quá khứ.
Cậu học trò giỏi một cách đáng ngờ
Một mô hình hoạt động tốt hơn bạn mong đợi một chút thì thật thú vị. Một mô hình hoạt động tốt hơn nhiều so với mức nó có quyền đạt được thì nên khiến bạn sợ hãi. Mô hình của tôi thuộc loại thứ hai: mượt mà ở nơi mà thị trường thật vốn gồ ghề, tự tin ở nơi mà lẽ ra nó phải bất định.
Trong một bài viết trước đó, tôi đã viết rằng kết quả nguy hiểm nhất là kết quả tâng bốc bạn. Đây lại là bài học ấy, trong một lớp ngụy trang tinh vi hơn. Lần này những con số không hề vô lý — chúng chỉ quá tốt, và “quá tốt” tự nó là một dạng cờ đỏ, bởi vì lợi thế thực sự trong thị trường thì nhỏ bé, nhiễu loạn, và khó giành được. Một mô hình trông như đã giải được thị trường thì gần như luôn luôn đã tìm thấy một vết nứt trong mô phỏng của bạn thay vào đó.
Tương lai đã lọt vào ở đâu
Vết nứt nằm ở khâu chuẩn hóa — bước không hào nhoáng nơi bạn tái tỷ lệ các đầu vào thô để một mô hình có thể học từ chúng. Để chuẩn hóa, bạn cần các thống kê: một tâm, một độ phân tán. Và tôi đã tính các thống kê đó trên toàn bộ tập dữ liệu cùng một lúc.
Lựa chọn duy nhất đó chính là nơi tương lai lọt vào. Khi bạn tính thống kê trên toàn bộ lịch sử rồi áp dụng chúng cho một điểm trong quá khứ, mỗi giá trị “đã chuẩn hóa” tại thời điểm quá khứ đó lặng lẽ mã hóa thông tin về dữ liệu chưa hề xảy ra. Mô hình, khi nhìn vào bất kỳ khoảnh khắc nào, đang ngầm được cho biết điều gì đó về hình dạng của toàn bộ dòng thời gian — bao gồm cả tương lai của nó. Nó chưa bao giờ trực tiếp nhìn thấy giá của ngày mai. Nó không cần phải vậy. Nó đang hít thở bầu không khí đã pha lẫn ngày mai vào trong đó.
Tại sao look-ahead lại dễ tạo ra đến vậy
Điều khiến look-ahead bias trở nên nguy hiểm không phải là vì nó khó tạo ra. Mà là vì nó len lỏi vào thông qua những bước tiền xử lý vốn rất đỗi bình thường. Cách viết code tự nhiên nhất, dễ đọc nhất — fit bộ scaler trên dữ liệu, rồi biến đổi dữ liệu — đã sai ngay từ đầu đối với chuỗi thời gian, và chẳng có gì lên tiếng phàn nàn. Không có ngoại lệ nào được ném ra. Không có bài kiểm thử nào chuyển sang màu đỏ. Những con số trông hoàn toàn hợp lý. Triệu chứng duy nhất là mô hình của bạn tốt hơn mức lẽ ra nó nên đạt được, mà đó lại chính là triệu chứng bạn ít có động lực điều tra nhất.
Đó là cái bẫy của rò rỉ: nó không trông giống một lỗi. Nó trông giống thành công.
Dấu hiệu: lỗi lạc ở trong này, chết yểu ở ngoài kia
Có một dấu hiệu nhận biết, dù tự nó không phải là bằng chứng. Một mô hình bị làm hỏng bởi look-ahead có xu hướng lỗi lạc trên dữ liệu mà nó được tinh chỉnh để đối chiếu và sụp đổ ngay khoảnh khắc nó gặp dữ liệu mà nó không thể lén nhìn. Một khoảng cách lớn giữa vinh quang trong-mẫu và sự sụp đổ ngoài-mẫu là một dấu hiệu cảnh báo của rò rỉ — dù nó cũng có thể đến từ quá khớp, một sự dịch chuyển trong chế độ thị trường, hoặc các chi phí bạn đã ước lượng thấp. Trong trường hợp của tôi, lỗ rò rỉ chính là thủ phạm.
Vậy nên bài kiểm tra thực sự quan trọng chưa bao giờ là “backtest tốt đến mức nào?” Mà là “nó tệ đi bao nhiêu khi tôi làm cho mô phỏng trở nên trung thực?” Khi tôi bịt lỗ rò rỉ lại, hiệu suất tụt xuống — và sự tụt giảm đó, đau đớn như nó vốn dĩ, lại là con số đáng tin cậy đầu tiên mà hệ thống từng cho tôi thấy.
Cách sửa: không bao giờ dùng bất cứ thứ gì bạn chưa thể biết được
Cách sửa là một nguyên tắc, không phải một dòng code: tại bất kỳ khoảnh khắc nào trong mô phỏng, mô hình chỉ được phép dùng thông tin đã tồn tại tại hoặc trước khoảnh khắc đó. Đối với chuẩn hóa, điều đó nghĩa là rút ra các thống kê từ một cửa sổ trượt của quá khứ — fit trên những gì có sẵn cho đến một thời điểm nhất định, không bao giờ trên toàn bộ dòng thời gian, và không bao giờ trên một điểm đơn lẻ của tương lai.
Nó chậm hơn. Nó rắc rối hơn. Nó tạo ra những backtest trông tệ hơn. Cả ba điều đó đều là tính năng, chứ không phải chi phí, bởi vì mỗi điều một là sự mô phỏng từ chối cho mô hình du hành thời gian. Một pipeline trung thực phải trả một khoản thuế bằng hiệu suất bề ngoài, và khoản thuế đó là cái giá cho những con số mà bạn thực sự có thể tin tưởng.
Rò rỉ là một gia đình, không phải một lỗi đơn lẻ
Phần khó nhất của việc sửa lỗi này không phải là bộ chuẩn hóa. Mà là nhận ra rằng bộ chuẩn hóa chỉ là một cánh cửa, và tương lai có thể bước vào qua nhiều cánh cửa. Cùng một sai lầm ấy ẩn nấp trong cách các nhãn được xây dựng, trong các đặc trưng bí mật tóm tắt cả một chuỗi, trong bất kỳ bước tiền xử lý nào chạm vào quá khứ và tương lai cùng một lúc. Bịt một lỗ rò rỉ và bạn vẫn chưa bịt được rò rỉ; bạn chỉ mới học được nó trông ra sao, để có thể đi tìm những lỗ còn lại.
Tôi ngừng nghĩ về look-ahead như một lỗi cần sửa và bắt đầu xem nó như một thuộc tính cần kiểm toán — một thứ mà giờ đây tôi cố ý săn lùng, dựa trên giả định rằng nếu một kết quả trông quá sạch sẽ, thì tương lai đang lọt vào ở đâu đó mà tôi chưa kiểm tra.
Tại sao backtest lại tưởng thưởng cho việc gian lận
Bên dưới tất cả những điều này là một sự thật khó chịu về backtest: chúng không thể phân biệt kỹ năng với sự nhìn lại quá khứ. Một backtest trả thưởng y hệt nhau cho một mô hình thực sự dự đoán được thị trường và một mô hình đang lặng lẽ đọc đáp án. Cả hai đều tạo ra một đường cong đẹp đẽ. Dữ liệu nghiêm ngặt hướng về phía trước, chưa từng thấy là bài kiểm tra mạnh hơn bắt đầu tách biệt chúng — dù ngay cả điều đó, tự nó, cũng không thể chứng minh một pipeline là không có rò rỉ.
Đó là lý do vì sao “nó làm tốt trong backtest” là điểm khởi đầu của một cuộc điều tra, chứ không phải điểm kết thúc. Một equity curve trông đẹp là một câu hỏi: liệu mô hình này có xứng đáng với kết quả đó, hay tôi đã vô tình để nó gian lận? Toàn bộ kỷ luật của nghiên cứu trung thực chỉ là học cách đặt câu hỏi đó trước khi thị trường đặt nó cho bạn.
Một mô hình đọc tờ báo của ngày mai sẽ luôn trông như một thiên tài. Thiên tài đó là của bạn, không phải của nó — và nó nằm trọn vẹn trong lỗ rò rỉ mà bạn đã quên bịt lại.
— Không tín hiệu, không lợi nhuận, không phải lời khuyên đầu tư.