Chúng tôi chạy lại một backtest đã lưu và nhận được đường cong vốn khác. Cùng mã chiến lược, cùng khoảng thời gian, cùng mã giao dịch. Số dư cuối kỳ lệch 1.8%, và 3 giao dịch đã dịch chuyển 1 nến.
Như vậy đã đủ khiến kết quả nghiên cứu khó tin cậy. Nếu đồng đội, chính bạn trong tương lai hoặc dịch vụ giao dịch giấy không thể tái tạo lần chạy, bạn sẽ không biết thay đổi đó cải thiện chiến lược hay chỉ làm thay đổi thử nghiệm. Đây là trình tự chúng tôi đã làm theo để tìm ra sai lệch.
Ngày 1: Chúng tôi xác định rõ “cùng một lần chạy” nghĩa là gì
Sai lầm đầu tiên của chúng tôi là xem tệp chiến lược như toàn bộ thử nghiệm. Thực tế không phải vậy. Lần chạy còn phụ thuộc vào dữ liệu đầu vào, phiên bản engine, lịch, siêu dữ liệu công cụ và thiết lập thực thi. Mã chỉ mô tả một phần của phép tính.
Chúng tôi lập bản kê lần chạy trước khi thay đổi bất cứ thứ gì. Bản kê ghi lại commit của chiến lược, mã định danh ảnh chụp dữ liệu, khoảng thời gian, sàn giao dịch, biểu phí, nguồn funding, mô hình khớp lệnh và phiên bản phần mềm. Chúng tôi cũng lưu các lệnh và khớp lệnh thu được, vì riêng đường cong vốn không thể cho biết hai lần chạy bắt đầu khác nhau ở đâu.
| Thành phần | Thông tin cần ghi lại | Lý do quan trọng |
|---|---|---|
| Dữ liệu thị trường | Mã ảnh chụp, phiên bản lược đồ, các điều chỉnh | Nhà cung cấp sửa lại dữ liệu lịch sử và cập nhật các hành động doanh nghiệp |
| Thực thi | Bậc phí, chuỗi funding, thiết lập khớp lệnh và tác động giá | Giá trị mặc định và giả định về tài khoản làm thay đổi kết quả |
| Môi trường chạy | Commit mã, phiên bản engine và thư viện phụ thuộc | Thư viện có thể làm thay đổi thứ tự, cách làm tròn hoặc chỉ báo |
| Đầu ra | Lệnh, khớp lệnh, vị thế và chỉ số | Cho thấy các lần chạy bắt đầu bất đồng ở đâu |
Ngày 2: Chúng tôi so sánh các giao dịch, không phải Sharpe
Các chỉ số tổng hợp khiến chúng tôi phân tâm. Hai lần chạy có Sharpe gần như giống nhau, nhưng nhật ký khớp lệnh cho thấy điểm bất đồng đầu tiên nằm ở một lần quyết toán funding. Một lần chạy tính mức funding cho vị thế đang mở tại thời điểm quyết toán; lần còn lại dùng vị thế sau khi tái cân bằng ở thời điểm đó.
Mã chiến lược không thay đổi. Thứ tự sự kiện của engine đã thay đổi. Một bản cập nhật phiên bản nhỏ đã làm rõ trình tự vốn trước đây phụ thuộc vào cách hai sự kiện tình cờ được sắp xếp.
Chúng tôi cập nhật quy ước chạy để ghi rõ thứ tự: áp dụng funding cho vị thế được giữ đến thời điểm quyết toán, rồi mới xử lý các quyết định của chiến lược tại thời điểm đó. Quy ước cụ thể có thể khác nhau tùy sàn và engine. Để nó ở trạng thái ngầm định mới là lỗi.
Ngày 3: Tệp dữ liệu tưởng như “giống hệt” hóa ra lại khác
Sau khi cố định thứ tự sự kiện, những điểm không khớp còn lại tập trung ở một vài giao dịch cổ phiếu. Nhà cung cấp đã sửa lại điều chỉnh chia tách trong dữ liệu lịch sử. Tệp của chúng tôi vẫn có cùng tên và số dòng như trước, khiến chúng tôi tưởng rằng nó không thay đổi.
Giờ đây, chúng tôi tạo dấu vân tay cho từng ảnh chụp dữ liệu bất biến và lưu chính sách điều chỉnh cùng với nó. Mã băm cho biết dữ liệu có thay đổi hay không, nhưng không giải thích được lý do. Vì vậy, bản kê còn ghi nguồn, thời điểm truy xuất và phiên bản chuyển đổi. Với dữ liệu có thể được sửa đổi, những thông tin này là một phần của kết quả.
Một backtest có thể tái lập cần trả lời được câu hỏi “nó đã dùng phiên bản nào của dữ liệu quá khứ?”
Ngày 4: Chúng tôi tìm ra một thiết lập mặc định âm thầm
Khác biệt cuối cùng là phí maker được đặt bằng 0 vì cấu hình của chiến lược bỏ qua trường này. Một engine mới hơn đã áp dụng phí mặc định của tài khoản. Riêng thiết lập mặc định đó đã làm thay đổi các giao dịch sát ngưỡng, đủ để giải thích phần lớn chênh lệch số dư cuối kỳ.
Chúng tôi ghi rõ các thiết lập có ý nghĩa về mặt kinh tế và yêu cầu engine in cấu hình đã được áp dụng vào hồ sơ lần chạy. Giá trị mặc định rất tiện khi thử nghiệm. Nhưng chúng không phải bằng chứng đáng tin khi so sánh kết quả ở những thời điểm khác nhau.
Những việc lần sau chúng tôi sẽ bỏ qua
Chúng tôi đã mất nửa ngày so sánh các chỉ số tổng hợp trước khi xem khớp lệnh đầu tiên bị lệch. Đừng bắt đầu từ đó. Hãy sắp xếp cả hai nhật ký sự kiện theo dấu thời gian rồi so sánh điểm bất đồng đầu tiên; những khác biệt xuất hiện sau đó thường bắt nguồn từ nguyên nhân đầu tiên ấy.
Chúng tôi cũng sẽ bỏ qua ý tưởng cho rằng chỉ cần ảnh container là đủ để làm cho lần chạy có thể tái lập. Ảnh đó cố định phần lớn môi trường phần mềm, nhưng không cố định tệp dữ liệu bên ngoài, biểu phí được tải lúc chạy hay dữ liệu lịch sử đã được nhà cung cấp sửa đổi.
Khi backtest thay đổi, hãy giữ lại cả hai bản kê và nhật ký lần chạy, rồi xử lý từng nguồn sai lệch một. Kết quả hữu ích không chỉ là một đường cong có thể chạy lại. Đó còn là hồ sơ giải thích dữ liệu và giả định nào đã tạo ra kết quả, cũng như vì sao lần chạy tiếp theo có thể khác.
← Tất cả bài viết


