Tôi Đã Để Tương Lai Rò Rỉ Vào Quá Khứ
Có một kết quả backtest, từ những ngày đầu, tốt đến mức lẽ ra phải khiến tôi vui mừng. Thay vào đó, sau vài phút nhìn chằm chằm vào nó, nó lại khiến tôi bất an sâu sắc. Lợi nhuận trong mô phỏng thì lớn, mượt mà, và quá sạch sẽ — kiểu hiệu suất không bao giờ xảy ra trong một thị trường thực, đầy nhiễu loạn và thù địch. Và lý do nó không xảy ra trong một thị trường thực là bởi bài kiểm tra của tôi, một cách lặng lẽ và không hề bị tôi nhận ra, đã có thể nhìn thấy tương lai.
Không phải cố ý. Tôi không hề viết nếu mày biết điều gì xảy ra tiếp theo, hãy gian lận. Tương lai đã rò rỉ vào quá khứ qua hàng tá đường nối nhỏ bé, trông vô hại, và mỗi một trong số đó đang tưởng thưởng cho hệ thống của tôi vì một kiểu thấu thị mà nó sẽ không bao giờ, không bao giờ có được khi tiền thật đặt lên bàn cân.
Lỗi quyến rũ nhất trong backtesting
Tên gọi chung cho hiện tượng này là look-ahead bias, hay rò rỉ (leakage). Nó xảy ra bất cứ khi nào một quyết định trong mô phỏng của bạn được phép sử dụng thông tin mà, trong đời thực, lẽ ra chưa tồn tại vào thời điểm quyết định đó được đưa ra.
Điều này đáng để ngẫm nghĩ, bởi nó tinh vi hơn vẻ ngoài của nó. Một backtest được cho là phải tái hiện trung thực lịch sử: tại mỗi khoảnh khắc, hệ thống chỉ được biết những gì thực sự có thể biết tại khoảnh khắc đó, và nó phải hành động chỉ dựa trên những thông tin đó mà thôi. Rò rỉ là bất kỳ vết nứt nào trên bức tường ấy — bất kỳ nơi nào một mảnh thông tin của ngày mai len lỏi vào quyết định của ngày hôm nay. Và ngay khoảnh khắc điều đó xảy ra, backtest của bạn ngừng đo “điều này đã có thể diễn ra thế nào” và bắt đầu đo “điều này sẽ diễn ra thế nào nếu nó được phép nhìn lén”.
Tương lai len lỏi vào bằng cách nào
Tôi muốn cẩn trọng ở đây để không mô tả những chi tiết cụ thể về hệ thống của riêng mình, nên hãy để tôi giữ vấn đề ở mức những hình dạng chung mà các rò rỉ này thường mang, bởi chúng phổ biến đến mức đáng kinh ngạc.
Một dạng kinh điển: sử dụng trong một quyết định một giá trị mà thực ra chỉ được chốt lại sau khoảnh khắc bạn đang giả vờ quyết định. Một dạng khác: chuẩn bị dữ liệu của bạn bằng cách co giãn hoặc chuẩn hóa nó dựa trên các thống kê — một giá trị trung bình, một khoảng giá trị, một kích thước điển hình — được tính trên toàn bộ lịch sử, bao gồm cả phần mà, tại khoảnh khắc mô phỏng của bạn, vẫn chưa xảy ra. Một dạng nữa: lọc hoặc gán nhãn dữ liệu với lợi thế của cái nhìn hồi tưởng, lặng lẽ loại bỏ một số trường hợp theo cách mà bạn chỉ có thể làm được nếu đã biết trước chúng kết thúc ra sao.
Mỗi cái trong số này là một dòng mã đơn lẻ, trông hết sức hợp lý. Không cái nào tạo cảm giác như đang gian lận trong lúc bạn viết nó. Và mỗi cái trong số đó đều trao cho hệ thống của bạn một dòng thông tin nhỏ, đều đặn, đến từ tương lai.
Vì sao nó khó phát hiện đến vậy
Điều tàn nhẫn nhất về rò rỉ là nó không trông giống một lỗi. Mã chạy không báo lỗi. Không có gì sụp đổ. Và kết quả nó tạo ra không phải là một dấu hiệu cảnh báo — nó là một con số tuyệt vời. Những con số tuyệt vời không khơi dậy sự nghi ngờ ở hầu hết mọi người. Chúng khơi dậy sự ăn mừng, một bức chụp màn hình, một cảm giác thầm lặng rằng có lẽ bạn đang nắm được điều gì đó.
Đó chính xác là điều khiến loại lỗi này nguy hiểm đến vậy. Nó ẩn mình bên trong những kết quả trông giống thành công, vốn là nơi tệ nhất để một lỗi ẩn náu, bởi thành công là kết cục mà bạn ít có động lực nhất để chất vấn. Một cú sụp đổ đòi hỏi phải được sửa. Một đường cong equity tuyệt đẹp lại mời bạn ngừng nhìn tới.
Dấu hiệu: kết quả tốt đến mức khó tin
Trong một thời gian dài, hồi chuông báo động đáng tin cậy duy nhất mà tôi có là chính sự hoài nghi của bản thân. Khi một backtest trả về kết quả tốt hơn một cách ngoạn mục so với bất cứ điều gì bạn có thể kỳ vọng một cách hợp lý — mượt hơn, sinh lời hơn, ổn định hơn mức mà thị trường có bất kỳ quyền nào để cho phép — thì giả thuyết đầu tiên đúng đắn không phải là “tôi đã tìm ra điều gì đó tuyệt vời”. Mà là “thông tin đang rò rỉ ở đâu đó, và tôi cần tìm ra nó”.
Đây là một định kiến tiên nghiệm thực sự hữu ích, và tôi đã đi đến chỗ giữ nó một cách mạnh mẽ: trong một backtest, sự xuất sắc thường là triệu chứng của một lỗi nhiều hơn rất nhiều so với bằng chứng về một lợi thế. Thị trường thì khó nhằn. Những kết quả gợi ý rằng nó dễ dàng thì thường đang nói cho bạn biết về mã của bạn, chứ không phải về thị trường.
Truy tìm các rò rỉ
Công việc thực sự để săn lùng rò rỉ thì nhàm chán và hoàn toàn chẳng có gì hào nhoáng, và tôi chưa tìm thấy một lối tắt khôn ngoan nào thay thế được nó. Kỷ luật là thế này: lấy từng giá trị một đi vào một quyết định, rồi truy ngược nó về đúng khoảnh khắc mà nó lẽ ra mới được biết đến trong đời thực. Rồi hỏi, một cách thẳng thắn, “vào đúng khoảnh khắc tôi đang giả vờ hành động, liệu tôi có thực sự đã có được con số này chưa?”
Hầu hết các rò rỉ, khi cuối cùng bạn dồn được chúng vào góc tường, hóa ra chỉ là một dấu thời gian gian lận đáng giá — một giá trị được dùng một khoảnh khắc trước khi nó thực sự tồn tại, một phép tính vươn xa thêm một bước vào dữ liệu hơn mức cho phép. Những đường nối nhỏ. Nhưng một đường nối nhỏ, lặp lại qua hàng nghìn quyết định, là đủ để chế tạo ra cả một gia tài tưởng tượng.
Nguyên lý sâu xa hơn: tôn trọng mũi tên thời gian
Bên dưới tất cả những điều này là một nguyên lý duy nhất mà giờ đây tôi xem là gần như thiêng liêng: tôn trọng mũi tên thời gian. Một backtest, về bản chất, là một lời hứa — một lời hứa rằng bạn chỉ luôn dùng quá khứ để hành động trong hiện tại, không bao giờ dùng tương lai. Mỗi rò rỉ là một lời hứa nhỏ bị phá vỡ, một nơi mà mã của bạn lặng lẽ vươn tới trong thời gian để tự giúp chính mình.
Vậy nên xây dựng một mô phỏng đáng tin cậy hóa ra ít liên quan đến mô hình hóa khôn ngoan, mà liên quan nhiều hơn nhiều đến việc bảo vệ một ranh giới: lằn ranh giữa những gì đã được biết tại một khoảnh khắc và những gì chỉ có thể được biết sau đó. Phần lớn công sức kỹ thuật, cái phần không ai viết những luồng tweet ngợi ca, chỉ đơn giản là canh giữ ranh giới ấy trước xu hướng liên tục, tùy tiện muốn nhìn lén của chính mã bạn.
Vì sao giờ đây tôi ngờ vực những kết quả tốt nhất của mình
Sự thay đổi lâu dài từ tất cả những điều này là mối quan hệ của tôi với tin tốt đã bị đảo ngược. Một backtest đáng thất vọng thì chỉ đơn giản là đáng thất vọng; tôi nhìn nó, nhún vai, rồi đi tiếp. Một backtest ngoạn mục giờ đây khiến tôi lo lắng trước khi khiến tôi vui mừng. Kết quả càng tốt, tôi càng ráo riết đi tìm cái rò rỉ đã tạo ra nó.
Nghe có vẻ chẳng vui vẻ gì, và đôi khi đúng là vậy. Nhưng nó đến từ một sự tôn trọng phải trả giá đắt mới có được, đối với cách mà trò chơi cụ thể này trừng phạt sự tự lừa dối. Những lời nói dối nguy hiểm nhất mà một hệ thống từng nói với bạn không phải là những thất bại xấu xí. Chúng là những thành công lộng lẫy — những thứ trông y hệt cái điều bạn vẫn hằng mong tìm thấy, và chính vì lẽ đó mà chúng là những thứ cuối cùng bạn nghĩ tới việc nghi ngờ.
— Không tín hiệu, không lợi nhuận, không phải lời khuyên đầu tư.