Vì sao backtest hay nói dối, và cách một tick engine sửa lại điều đó
· #systematic-trading #backtesting #tick-data #research-method #trading-psychology
Hồi mới bắt đầu, một backtest của tôi trông rất đẹp. Đẹp đến mức tôi không giải thích nổi. Đường vốn mượt mà, tỷ lệ thắng cao, và không có gì trong logic đủ để lý giải điều đó. Tôi là kỹ sư phần mềm trước khi là một trader, nên phản xạ của tôi không phải là ăn mừng. Mà là nghi ngờ chính mã của mình.
Mất một thời gian tôi mới tìm ra vấn đề, và khi tìm ra thì nó không nằm ở chiến lược. Nó nằm ở cái engine dùng để kiểm thử. Bài viết này là phiên bản đời thường của điều tôi phát hiện, vì đó là một trong những thứ hữu ích nhất tôi từng học, mà gần như không ai nhắc tới.
Điều mà hầu hết backtest âm thầm giả định
Phần lớn backtest bán lẻ chạy trên nến. Mỗi lần một cây: mở, cao, thấp, đóng. Chiến lược của bạn nhìn thấy một cây nến đã hoàn tất, ra quyết định, rồi engine khớp lệnh của bạn ở đâu đó trong cây nến kế tiếp.
Chính phần cuối cùng đó là cái bẫy. Một cây nến là một bản tóm tắt. Nó cho bạn bốn mức giá và sự thật rằng giá đã đi qua mọi mức giữa đỉnh và đáy. Điều nó không cho bạn biết là thứ tự các mức giá đó xảy ra.
Giả sử một cây nến năm phút có đáy 100 và đỉnh 102. Dừng lỗ của bạn ở 100.5, còn chốt lời ở 101.5. Cả hai đều nằm trong biên độ nến. Cả hai đều bị chạm tới. Vậy cái nào khớp trước?
Cây nến không trả lời được. Bên trong nó không có thời gian. Thế là engine buộc phải đoán.
Vì sao cú đoán đó tô hồng cho bạn
Đây là chỗ khó chịu. Rất nhiều engine backtest xử lý sự mập mờ đó bằng một mặc định lạc quan, hoặc bằng một giả định mà bạn chưa bao giờ chủ động chọn. Có cái giả định chốt lời khớp trước. Có cái giả định đường đi tốt nhất qua cây nến. Có cái cho bạn tự đặt quy tắc, và đa số người ta không bao giờ đặt.
Mỗi cú đoán như vậy, lặp lại qua hàng nghìn lệnh, đều đẩy kết quả nghiêng về phía có lợi cho bạn. Trên một lệnh riêng lẻ thì không nhiều. Nửa cái thắng ở đây, một lần cứu dừng lỗ ở kia. Cộng dồn qua vài nghìn lệnh, bạn có một backtest trông như một lợi thế nhưng thực ra là một sản phẩm của cách hạch toán.
Điều tệ nhất là nó trông rất đáng tin. Đường vốn mượt chính vì engine cứ âm thầm giải mọi tình huống năm ăn năm thua nghiêng về phía bạn. Bạn không nhìn vào một chiến lược. Bạn đang nhìn vào chính sự lạc quan của mình, được cộng dồn.
Một tick engine làm khác điều gì
Một tick là một lần khớp giá: một giao dịch, ở một mức giá, tại một khoảnh khắc. Dữ liệu tick thực là dòng thô của từng lần như vậy, đúng theo thứ tự chúng đã xảy ra.
Một engine chạy ở cấp tick không tóm tắt cây nến rồi đoán. Nó đi qua từng lần khớp theo trình tự. Khi giá chạm 100.5, dừng lỗ của bạn được xét ngay lúc đó, trước khi giá kịp tới 101.5, vì đó là thứ tự thực sự đã diễn ra. Không còn tình huống năm ăn năm thua nào để giải, vì không còn sự mập mờ nào sót lại. Trình tự chính là dữ liệu.
Nghe thì tưởng là khác biệt nhỏ. Trên thực tế nó thay đổi mọi thứ ở phía sau:
- Lệnh khớp ở nơi lẽ ra chúng có thể khớp, theo đúng thứ tự thực, không phải thứ tự tiện lợi.
- Bài kiểm thử thôi tô hồng cho bạn. Khi bỏ đi sự lạc quan, rất nhiều "lợi thế" lặng lẽ biến mất. Đó không phải engine bi quan. Đó là engine chính xác.
- Backtest và giao dịch thực bắt đầu khớp nhau. Khoảng cách giữa kết quả trên giấy và kết quả thật, cái người ta gọi là parity, thu hẹp lại, vì cả hai phía giờ cùng đánh giá một thực tại.
Điểm cuối là điều tôi quan tâm nhất. Một backtest là lời hứa bạn tự hứa với mình về tương lai. Nếu nó dựng trên một giả định tô hồng, đó là lời hứa bạn không thể giữ.
Vì sao tôi xây lại của mình
Chuyển từ engine cấp nến sang engine cấp tick thuần túy là một trong những bài toán khó nhất trong bộ nghiên cứu của tôi, dquants. Đó là công việc chậm và chẳng hào nhoáng. Dữ liệu tick khổng lồ, nên phải lưu trữ và truy vấn cẩn thận. Mọi phần trong pipeline từng giả định "mỗi lần một cây nến" đều phải xét lại.
Nhưng tôi làm vì một lý do đơn giản: tôi thà có một bài kiểm thử nói thật với mình còn hơn một bài khiến mình thấy dễ chịu được một tuần. Một chiến lược chỉ sống sót nhờ engine cấp nến thì thực ra chưa từng sống sót. Nó đang được cách hạch toán gánh giùm.
Bây giờ khi tôi cho một setup chạy qua tick engine mà nó vẫn đứng vững, sau chi phí thực, ngoài mẫu, đúng trong bối cảnh thị trường mà tôi nói nó hiệu quả, thì kết quả đó có ý nghĩa. Không phải vì nó ấn tượng. Mà vì nó trung thực. Nó thôi được tô hồng.
Điều này có nghĩa gì nếu bạn không đụng tới code
Bạn không cần tự xây một engine để dùng điều này. Bạn cần một câu hỏi, và nên hỏi nó với bất kỳ backtest nào, kể cả của chính bạn:
Khi dừng lỗ và chốt lời của tôi cùng nằm trong một cây nến, engine này giả định cái nào khớp trước?
Nếu câu trả lời là "tôi không biết", hãy nhìn cả kết quả đó một cách thận trọng. Có thể nó thật. Có thể đó là sự lạc quan đang lên tiếng. Bạn chưa thể phân biệt được, và biết rằng mình chưa phân biệt được, tự nó đã là tiến bộ. Chỉ một câu hỏi đó thôi cũng đủ tách một con số bạn có thể tin khỏi một con số đang lặng lẽ gian lận giùm bạn.
Tất cả những điều này không phải là khẳng định về lợi nhuận. Nó là khẳng định về sự trung thực. Một tick engine không làm cho một chiến lược trở nên tốt. Nó làm cho một chiến lược tồi lộ ra trước khi nó khiến bạn mất tiền thật, mà đó gần như là toàn bộ mục đích của một quy trình nghiên cứu. Trong công việc của mình, đây đúng là lý do tôi giữ tiêu chuẩn nghiêm và cách nói khiêm tốn: tôi vẫn đang học, và cách nhanh nhất để tiếp tục học là xây những công cụ từ chối nói dối tôi.
Chỉ nhằm mục đích giáo dục. Đây là mô tả một phương pháp nghiên cứu, không phải lời khuyên đầu tư, và không phải tuyên bố về kết quả. Hiệu suất trong quá khứ không bảo đảm kết quả tương lai.