Random vs Smart Search: Điểm giao thoa nằm ở chi phí đánh giá, không phải thuật toán
Thuộc series "Backtests Without Illusions".
Có một quan niệm phổ biến trong tối ưu hóa siêu tham số: tìm kiếm random là một baseline mà bạn sẽ vượt qua. Kết quả kinh điển của Bergstra & Bengio (2012) đã chứng minh rằng random đánh bại grid; sau đó tối ưu hóa Bayesian, TPE, CMA-ES, và các phương pháp multi-fidelity như Hyperband/ASHA được cho là sẽ lần lượt đánh bại random. Vậy nên khi chúng tôi ngồi xuống để benchmark các phương pháp tìm kiếm tham số cho engine giao dịch của riêng mình, chúng tôi kỳ vọng vào bậc thang quen thuộc: random ở dưới cùng, một sampler thông minh ở trên đỉnh.
Chúng tôi nhận được điều ngược lại — và rồi chúng tôi cũng nhận được câu trả lời sách giáo khoa. Cùng một chiến lược, cùng một không gian tham số, cùng một hàm mục tiêu, cùng một cỗ máy. Điều duy nhất chúng tôi thay đổi là một lần backtest đắt đỏ đến mức nào, và thứ hạng của các phương pháp tìm kiếm đảo ngược. Khi mỗi lượt đánh giá rẻ, một chuỗi Sobol scrambled "ngu" đã nghiền nát mọi sampler "thông minh". Khi chúng tôi làm cho mỗi lượt đánh giá trở nên đắt đỏ, các phương pháp thông minh vượt lên và tìm ra cấu hình duy nhất sống sót ngoài mẫu.
Bài học ở đây không phải là "random bị đánh giá thấp" hay "Bayesian bị đánh giá quá cao." Mà là điểm giao thoa giữa tìm kiếm random và tìm kiếm thông minh được chi phối bởi chi phí đánh giá, không phải bởi độ tinh vi của thuật toán. Hãy chọn bộ tối ưu hóa của bạn dựa trên chi phí của một lần backtest, không phải dựa trên danh tiếng của nó. Bài viết này đo lường chính xác điểm giao thoa nằm ở đâu, tại sao nó nằm ở đó, và một tiền đề — fidelity — quyết định liệu các thủ thuật của chế độ đắt (dừng sớm, cắt tỉa multi-fidelity) có an toàn để sử dụng hay không.
Mọi thứ dưới đây đến từ hai script trong backtester của chúng tôi: bench_search.py (v4, commit ee092f1) cho chế độ rẻ đơn khung thời gian, và bench_search_multitf.py (commit 102853c) cho chế độ đắt đa khung thời gian. Cả hai đều không rò rỉ (leak-free) — quyết định tại lúc đóng nến i, khớp lệnh tại open[i+1] — và cả hai đều chấm điểm mọi phương pháp trên một hàm mục tiêu walk-forward cuộn nhiều fold với một cửa sổ test giữ riêng mà quá trình tìm kiếm không bao giờ thấy.
Câu hỏi: thông lượng hay hiệu suất theo mẫu?

Mọi phương pháp tìm kiếm đều chi ngân sách wall-clock của mình cho hai việc: quyết định lấy mẫu ở đâu tiếp theo (tính toán riêng của sampler) và đánh giá mẫu đó (chạy backtest). Gọi việc đầu tiên là chi phí ask/tell và việc thứ hai là chi phí đánh giá (eval cost). Sức mạnh tìm kiếm hiệu dụng của một phương pháp trong một ngân sách wall-clock cố định, xấp xỉ, là:
và chất lượng cuối cùng của nó là số điểm đó nhân với mức độ "đặt đúng chỗ" của mỗi điểm. Hai biến số kéo ngược nhau:
- Thông lượng (throughput) — số điểm mỗi giây. Các sampler "ngu" (random, Sobol/QMC scrambled) có chi phí ask/tell gần như bằng không: chúng phát ra một điểm có độ lệch thấp (low-discrepancy) rồi tiếp tục. Chúng tối đa hóa số lượng.
- Hiệu suất theo mẫu (sample-efficiency) — chất lượng trên mỗi điểm. Các sampler "thông minh" (TPE, CMA-ES, ASHA) bỏ ra tính toán thực sự để mô hình hóa hàm mục tiêu nhằm đặt mỗi điểm tốt hơn. Chúng tối đa hóa việc đặt điểm, đánh đổi bằng thông lượng.
Biến số nào thắng phụ thuộc hoàn toàn vào mẫu số. Khi chi phí đánh giá nhỏ, chi phí ask/tell chiếm ưu thế trong mẫu số, nên bất cứ thứ gì làm nó phình to — một mô hình surrogate, một ước lượng mật độ kernel, một lần cập nhật ma trận hiệp phương sai — đều trực tiếp làm giảm số điểm bạn khám phá được. Khi chi phí đánh giá lớn, chi phí ask/tell chỉ là sai số làm tròn, nên sự "thông minh" gần như miễn phí và bạn nên tận dụng nó càng nhiều càng tốt.
Đó là toàn bộ luận điểm gói gọn trong một câu: khoản thuế ask/tell là cố định, nhưng tầm quan trọng của nó được quyết định bởi chi phí đánh giá mà bạn dùng để chia nó. Bây giờ hãy xem điều đó diễn ra.
Chế độ rẻ: Sobol "ngu" thắng về thông lượng

Chiến lược đơn khung thời gian (single-timeframe) của chúng tôi là một quy tắc phân tách HMA/HMA3 không rò rỉ (leak-free) trên không gian 7 tham số, được đánh giá bởi một eval_batch numba chạy trong tiến trình (in-process), sử dụng prange trên các cấu hình mà không có chi phí liên tiến trình. Trên engine này, một lần backtest gần như miễn phí — kernel thô đánh giá các cấu hình với tốc độ khoảng 3–4k cfg/s. Đây là chế độ rẻ, và đây cũng là nơi giao dịch khác biệt rõ rệt so với bối cảnh deep learning mà phần lớn kiến thức dân gian về HPO xuất phát từ đó: "hàm mục tiêu" của chúng tôi không phải là một lần huấn luyện GPU kéo dài 6 giờ, mà là một lượt duyệt mảng (array pass) mất 0.3 mili giây.
Chúng tôi cho mỗi phương pháp cùng một ngân sách — 1,500 lượt đánh giá — và ghi lại wall-clock mà mỗi phương pháp cần để tiêu hết số lượt đánh giá đó, cùng với giá trị mục tiêu trên tập test giữ riêng (held-out) mà nó tìm được. Vì ngân sách đánh giá là cố định, cột wall-clock chính là con số đọc trực tiếp overhead của từng sampler:
| Method | Evals | Wall-clock | Throughput | Held-out TEST |
|---|---|---|---|---|
| sobol (QMC) | 1,500 | 0.53 s | ~2,830 cfg/s | −259 |
| random | 1,500 | 0.85 s | ~1,770 cfg/s | −27 |
| sobol→cmaes | 1,500 | 1.38 s | ~1,085 cfg/s | −367 |
| cmaes | 1,500 | 1.76 s | ~850 cfg/s | −85 |
| tpe | 1,500 | 9.76 s | ~154 cfg/s | −161 |
| tpe-mv+sobol | 1,500 | 12.15 s | ~123 cfg/s | −151 |
| asha (folds) | 1,500 | 15.79 s | ~95 cfg/s | −165 |
TEST là hàm mục tiêu walk-forward (PnL hàng năm trên mỗi đơn vị thời gian hoạt động × độ tin cậy theo số lệnh) trên một cửa sổ giữ riêng mà quá trình tìm kiếm chưa từng chạm tới; càng cao càng tốt.
Hai sự thật nổi bật lên. Thứ nhất, hãy nhìn vào cột thông lượng. Sobol scrambled chạy ở ~2,830 cfg/s — gần chạm trần của engine. TPE chạy ở ~154 cfg/s và ASHA ở ~95. Đó là mức chậm đi 18–30x để thực hiện cùng một số lượng đánh giá y hệt. Các sampler thông minh không đánh giá thêm gì cả; chúng chỉ đang tiêu tốn thời gian đó bên trong bộ máy ask/tell của riêng mình.
Thứ hai — và đây là phần giữ cho câu chuyện trung thực — không có phương pháp nào tìm được kết quả dương ngoài mẫu (out-of-sample). Mọi giá trị TEST đều âm. Trong chế độ đơn khung thời gian, chiến lược của chúng tôi đơn giản là không có edge OOS bền vững, nên câu hỏi "phương pháp nào thắng" không phải là câu hỏi về lợi nhuận cuối cùng; đó là câu hỏi về hiệu suất tìm kiếm. Và về hiệu suất tìm kiếm với ngân sách đánh giá cố định, các phương pháp "ngu" thắng tuyệt đối: Sobol và random đạt được các con số held-out bằng hoặc tốt hơn các sampler thông minh trong khi chỉ tốn 1/20 wall-clock.
Bây giờ hãy đảo ngược cách so sánh theo đúng cách mà người thực hành trải nghiệm nó — cố định wall-clock, không cố định số lượt đánh giá. Nếu bạn cho mỗi phương pháp 15.8 giây mà ASHA cần cho 1,500 lượt đánh giá của nó, Sobol sẽ không dừng lại ở 1,500. Nó tiếp tục chạy, đến khoảng 45,000 cấu hình. Trong chế độ rẻ, câu hỏi không bao giờ là "sampler nào đặt 1,500 điểm tốt nhất" — mà là "bạn muốn có 1,500 điểm được đặt khéo léo hay 45,000 điểm rải ngẫu nhiên (scrambled), khi mỗi điểm gần như miễn phí?" Với một lượt đánh giá gần như miễn phí, độ phủ (breadth) thắng. Độ phủ gấp ba mươi lần trên một không gian 7 chiều đánh bại một mô hình tốt hơn về không gian đó.
Khoản thuế ask/tell
Khoản chênh lệch 20x đó đi đâu? Không phải vào backtest — cái đó giống hệt nhau giữa các phương pháp. Nó đi vào việc ghi sổ (bookkeeping) cho từng điểm của sampler, chạy bằng Python, ngay trong vòng lặp:
- TPE khớp một cặp ước lượng mật độ kernel (kernel-density estimate, trial tốt so với trial xấu) ở mỗi lần
ask, và chi phí này tăng theo lịch sử các trial. TPE đa biến (multivariate) khớp chúng đồng thời trên nhiều chiều — nhiều mô hình hóa hơn, nhiều Python hơn. - CMA-ES cập nhật và lấy mẫu từ một ma trận hiệp phương sai ở mỗi thế hệ (generation). Rẻ hơn TPE trong trường hợp này (nó chạy ở ~850 cfg/s), nhưng vẫn có overhead cao hơn một bậc độ lớn so với việc phát ra một điểm Sobol.
- ASHA phải trả chi phí ghi sổ cho việc thăng hạng/rung (promotion/rung) của bộ cắt tỉa (pruner), và trong thiết kế "fold-làm-fidelity" của chúng tôi, còn phải trả chi phí tính trước (precompute) cố định cho các chỉ báo trước khi có thể cắt tỉa bất cứ thứ gì — nên số lượt đánh giá mà nó "tiết kiệm được" thực ra ít hơn so với những gì sổ sách thể hiện.
Không có ý gì chê bai các thuật toán ở đây cả. Đó chính là điểm mấu chốt: chi phí ask/tell là một con số mili giây trên mỗi điểm xấp xỉ cố định, và khi lượt đánh giá mà nó bao quanh cũng chỉ vài mili giây, chi phí cố định đó đột nhiên chiếm tới 90% ngân sách của bạn. Sampler thông minh dành chín phần mười wall-clock của nó để suy nghĩ xem nên nhìn vào đâu, và một phần mười để thực sự nhìn. Một chuỗi Sobol scrambled dành toàn bộ thời gian để nhìn. Khi việc "nhìn" rẻ, việc "nhìn" thắng.
Chúng tôi cố tình không benchmark một bộ tối ưu hóa Bayesian dùng Gaussian process đầy đủ ở đây, và cũng vì cùng một lý do: một surrogate GP có độ phức tạp theo số trial. Đối lập với một lượt đánh giá chỉ tốn vài mili giây, việc khớp surrogate sẽ ngốn hết toàn bộ ngân sách tìm kiếm trước khi nó kịp đánh giá một phần đáng kể của không gian tham số. Trong chế độ rẻ, GP-BO bị loại ngay từ phép tính số học.
Chế độ đắt: điểm giao thoa đảo chiều

Bây giờ chúng ta làm cho một lần backtest trở nên đắt đỏ. Chiến lược đa khung thời gian (multi-timeframe) xếp chồng một khung cao, một khung trung bình và một khung thấp (triple-TF), mỗi khung đóng góp một lượt tính chỉ báo và các ngưỡng riêng của nó, tất cả được chấm điểm trên cùng một walk-forward nhiều fold. Một lượt đánh giá đơn lẻ giờ đây tốn khoảng 0.1–0.5 giây thay vì 0.3 mili giây — một bước nhảy ba bậc độ lớn. Chi phí đánh giá đã chuyển từ số hạng sai số làm tròn trong mẫu số của chúng ta thành số hạng chi phối. Theo luận điểm ở trên, khoản thuế ask/tell lẽ ra sẽ ngừng quan trọng và sự thông minh sẽ bắt đầu được đền đáp. Và đúng là như vậy.
Chúng tôi chạy mỗi phương pháp trong một ngân sách wall-clock cố định ~150 giây trên bài toán triple-TF (không gian 18 tham số), để mỗi phương pháp tiêu ngân sách đó theo cách sampler của nó quyết định, và đánh giá cấu hình tốt nhất duy nhất mà nó trả về trên một cửa sổ test giữ riêng:
| Method (triple-TF, 150 s) | Evals | Held-out TEST | Verdict |
|---|---|---|---|
| sobol (QMC) | 349 | −673 | thua |
| cascade (sobol²×64) | 20,864 | −585 | thua |
| asha (folds) | 292 eff. | −239 | thua |
| tpe-mv+sobol | 455 | −43 | thua |
| sobol→cmaes | 15,239 | +226 | OOS dương duy nhất |
TEST vẫn là hàm mục tiêu walk-forward như trước. Chỉ có một phương pháp vượt qua mốc 0.
Baseline Sobol "ngu" vốn thống trị chế độ rẻ giờ đây đứng chót, ở mức −673. Việc lấy mẫu mù (blind) độ lệch thấp trên một không gian 18 chiều, với chỉ 349 lượt đánh giá để chi tiêu vì mỗi lượt đều đắt đỏ, không bao giờ khoanh vùng được điều gì cả. Phương pháp thông minh, sobol→cmaes — 30% ngân sách dành cho Sobol để gieo mầm (seed) một "lòng chảo" (basin), sau đó tinh chỉnh bằng CMA-ES từ hạt giống tốt nhất — là phương pháp duy nhất tạo ra được một kết quả dương ngoài mẫu. Trên tập holdout cuối cùng chưa từng bị chạm tới, nhà vô địch trả về +2.62% (19 lệnh, ~6.6% mức phơi nhiễm vốn), cộng thêm vào một cửa sổ test đã trả về +16.35% (46 lệnh, ~15.7% mức phơi nhiễm). Nhà vô địch của mọi đối thủ khác đều lỗ tiền ngoài mẫu.
Đó chính là điểm giao thoa, được đo trên cùng một họ chiến lược, cùng một hàm mục tiêu, cùng một cỗ máy: không thay đổi gì ngoài chi phí của một lượt đánh giá, và thứ hạng của các phương pháp tìm kiếm đảo ngược. Trong chế độ rẻ, Sobol thắng và các sampler thông minh là một sự lãng phí 20x; trong chế độ đắt, sampler thông minh là thứ duy nhất hoạt động và Sobol mới là sự lãng phí.
Vì sao "thông minh" thắng ở đây — và không chỉ vì hiệu suất theo mẫu

Phiên bản gọn gàng của câu chuyện này là "các lượt đánh giá đắt đỏ tưởng thưởng cho hiệu suất theo mẫu, nên phương pháp đặt ít điểm hơn nhưng tốt hơn sẽ thắng." Điều đó chỉ đúng một nửa, và dữ liệu buộc ta phải nhìn thẳng vào nửa còn lại trung thực và thú vị hơn.
Hãy nhìn lại số lượt đánh giá. sobol→cmaes không thắng bằng cách đánh giá ít điểm hơn Sobol mù — nó đánh giá 15,239 điểm so với 349 điểm của Sobol, gấp bốn mươi lần nhiều hơn, trong cùng 150 giây. Bằng cách nào? Vì chi phí đánh giá multi-TF của chúng tôi có cấu trúc (structured), chứ không đồng nhất. Có hai trục: một trục đắt đỏ — trục chỉ báo (các chu kỳ khung thời gian và độ dài HMA, tốn 30–500 ms mỗi lần tính vì chúng buộc phải tính lại chỉ báo) và một trục rẻ — trục ngưỡng (các mức phân tách vào/ra lệnh, ~1–2 ms mỗi lần trên các tín hiệu đã cache). Khoảng cách giữa chúng là 30–100x.
Sobol mù bỏ qua cấu trúc này. Mỗi điểm nó rút ra đều làm rung trục chỉ báo đắt đỏ, buộc phải tính lại từ đầu — nên nó phải trả giá đầy đủ trên cả 349 lượt đánh giá. sobol→cmaes, một khi CMA-ES đã khoanh vùng được một khu vực triển vọng, có xu hướng giữ cấu trúc chỉ báo thô tương đối cố định và nhiễu loạn các ngưỡng liên tục, những thứ rơi vào các tín hiệu đã cache và gần như không tốn gì. Phương pháp thông minh biến cùng một wall-clock thành vừa các điểm được đặt tốt hơn vừa nhiều điểm hơn hẳn, bởi vì tính thích ứng ở đây đồng nghĩa với có nhận thức về chi phí (cost-aware): ở lại trên trục rẻ sau khi trục đắt đã được ghim cố định. Chiến thuật khai thác cascade(sobol²×64) tường minh của chúng tôi làm điều này mạnh mẽ nhất — 20,864 lượt đánh giá bằng cách gộp lô (batch) các ngưỡng rẻ trên các tín hiệu đã cache — và mặc dù nó thua trong test triple-TF, ở biến thể hai khung thời gian nó đã thắng tuyệt đối cửa sổ test với +20.2% (trước khi thất bại ở chính holdout của nó — sẽ nói thêm bên dưới).
Vậy nên phát biểu sắc bén hơn về điểm giao thoa là: trong chế độ đắt, khoản thuế ask/tell trở nên không đáng kể, điều này giải phóng bạn để trở nên thông minh — và "thông minh" nghĩa là thích ứng với cấu trúc chi phí của hàm mục tiêu, chứ không chỉ hình dạng của nó. Lấy mẫu mù không thể làm được cả hai điều đó. Đây chính xác là cấu trúc hai trục mà engine drill-down độ phân giải thích ứng của chúng tôi được xây dựng để khai thác, và đó là lý do vì sao các phương pháp multi-fidelity thuộc về chế độ đắt — với điều kiện một tiền đề được thỏa mãn.
Fidelity: tiền đề ẩn giấu của việc cắt tỉa
Các phương pháp multi-fidelity — Hyperband, ASHA, bất kỳ bộ cắt tỉa dừng sớm (early-stopping) nào — đều dựa trên một giả định: rằng một lượt đánh giá rẻ, một phần (partial) sẽ xếp hạng các cấu hình theo cùng một cách như lượt đánh giá đắt đỏ, đầy đủ sẽ làm. Nếu một cấu hình trông tốt trên một fold walk-forward có xu hướng trông tốt trên tất cả các fold, bạn có thể loại bỏ sớm những cấu hình thua và dồn ngân sách của những cấu hình sống sót cho những cấu hình chiến thắng. Nếu fidelity rẻ xếp hạng một cách ngẫu nhiên, việc dừng sớm chỉ đơn giản là vứt bỏ các cấu hình tốt theo kiểu tung đồng xu.
Vì vậy, trước khi tin tưởng bất kỳ bộ cắt tỉa nào, chúng tôi đo trực tiếp giả định đó. Fidelity của chúng tôi là số lượng fold walk-forward (đánh giá trên r fold một cách rẻ tiền, hoặc toàn bộ K fold với chi phí đầy đủ), và cổng kiểm tra fidelity (fidelity gate) tính hệ số tương quan hạng Spearman ρ giữa hàm mục tiêu r-fold rẻ tiền và hàm mục tiêu đầy đủ trên một mẫu các cấu hình ngẫu nhiên. ρ@1 là tương quan khi bạn đánh giá trên một fold duy nhất — fidelity mạnh dạn nhất, rẻ nhất. Đây là những gì cổng đó báo cáo trên cả hai chế độ:
| Fidelity (số fold sử dụng) | Single-TF ρ | Multi-TF ρ |
|---|---|---|
| ρ@1 (1 fold) | ~0.03 | 0.43 |
| ρ@2 | — | 0.67 |
| ρ@3 | — | 0.78 |
| ρ@4 | — | 0.82 |
| ρ@5 | — | 0.91 |
Trong chế độ đơn khung thời gian, một fold xếp hạng các cấu hình với tương quan ~0.03 so với sự thật — không thể phân biệt về mặt thống kê so với ngẫu nhiên. Đây không phải là sự trùng hợp; đó cùng là sự thật với việc "không phương pháp nào tìm được edge OOS." Khi một chiến lược không có tín hiệu bền vững, hiệu suất theo từng fold của nó chủ yếu là may rủi, nên bất kỳ fold đơn lẻ nào cũng là một lượt rút gần như ngẫu nhiên, và việc cắt tỉa fidelity thấp sẽ giết chết các cấu hình tốt và thăng hạng những cấu hình may mắn. Multi-fidelity không an toàn trong chế độ rẻ ở đây — không phải vì phương pháp tồi, mà vì tín hiệu rẻ chỉ là nhiễu. (Cổng của chúng tôi phát hiện điều này và từ chối cắt tỉa mạnh tay.)
Trong chế độ đa khung thời gian, một edge thực sự tồn tại, và bức tranh fidelity thay đổi hoàn toàn: ρ@1 tăng lên 0.43, và đến fold thứ năm ρ leo lên 0.91. Giờ đây một fold mang thông tin xếp hạng thực sự và năm fold mang gần như toàn bộ thông tin đó. Việc dừng sớm trở nên an toàn — một cấu hình thua ở vài fold đầu tiên thực sự có khả năng cao là một cấu hình thua cuộc. Đây là lý do thứ hai vì sao các phương pháp multi-fidelity thuộc về chế độ đắt: không chỉ vì các lượt đánh giá đắt khiến việc cắt tỉa trở nên xứng đáng, mà còn vì chế độ đắt chính là nơi mà fidelity rẻ cuối cùng xếp hạng giống như fidelity đắt.
Quy tắc mà điều này trao cho bạn thẳng thắn và rẻ để thực hiện: đo ρ trước khi cắt tỉa. Tương quan fidelity là một phép tính hai dòng trên vài trăm cấu hình ngẫu nhiên, và nó chính là sự khác biệt giữa việc tìm kiếm multi-fidelity tăng tốc cho bạn và việc tìm kiếm multi-fidelity âm thầm phá hoại bạn.
Thắng cuộc tìm kiếm không có nghĩa là sống sót qua nó
Thêm một ghi chú trung thực nữa, vì series này nói về các backtest nói dối. Nhà vô địch triple-TF của chúng tôi, sobol→cmaes, là phương pháp duy nhất đạt được holdout dương — +2.62%, cộng thêm +16.35% trong cửa sổ test. Đó là tin tốt. Đây là điều cần lưu ý: nó không sống sót qua quá trình giảm phóng đại thống kê (deflation).
Nhà vô địch là cấu hình tốt nhất trong số hàng chục nghìn cấu hình đã thử qua tất cả các phương pháp. Với mức multiple testing lớn như vậy, một holdout +2.62% không tự động là thật. Chúng tôi đã chạy các cổng chống overfitting mà cả series này dựa vào — Deflated Sharpe Ratio với N hiệu dụng (effective-N) được hiệu chỉnh cho tương quan giữa các trial, và PBO thông qua cross-validation đối xứng tổ hợp (combinatorially-symmetric cross-validation). Nhà vô địch đã vượt qua PBO (0.12, thấp hơn thoải mái so với ngưỡng 0.2 — thứ hạng của nó ổn định qua các lần chia CSCV) nhưng Sharpe đã giảm phóng đại của nó sụp xuống 0 (cổng yêu cầu ≥ 0.95). Kết luận: không sống sót.
Hãy đọc kỹ điều này, vì đó là trọng tâm của toàn bộ bài tập. Kết quả về điểm giao thoa là có thật: tìm kiếm thông minh đã thắng cuộc tìm kiếm trong chế độ đắt, một cách dứt khoát, và Sobol đã thua. Nhưng thắng cuộc tìm kiếm là một phát biểu về bộ tối ưu hóa, không phải về chiến lược. Cấu hình tốt nhất mà một bộ tối ưu hóa tốt có thể tìm ra từ một không gian không có edge vẫn là không có edge — deflation chính là thứ cho bạn biết bạn đang cầm cái nào trong tay. Chọn đúng phương pháp tìm kiếm giúp bạn có được câu trả lời tốt nhất hiện có một cách hiệu quả; nó không tạo ra một edge chưa từng tồn tại. Bộ tối ưu hóa và các cổng chống overfitting là những công cụ khác nhau đo lường những thứ khác nhau, và bạn cần cả hai.
Một quy tắc quyết định mà bạn thực sự có thể áp dụng
Bạn không cần chạy lại benchmark của chúng tôi để chọn một bộ tối ưu hóa. Bạn cần một con số: một lần backtest mất bao lâu? Hãy đo thời gian của một lượt đánh giá hàm mục tiêu của bạn — một lượt walk-forward đầy đủ, tất cả các fold — và đọc ra chế độ tương ứng.
- Đánh giá rẻ (≲ ~10 ms/backtest): mua thông lượng. Dùng Sobol/QMC scrambled hoặc random. Khoản thuế ask/tell trên TPE/CMA-ES/ASHA sẽ khiến bạn tốn 10–30x số điểm để đổi lấy việc đặt điểm mà một lượt đánh giá gần như miễn phí không đền đáp. Đừng bận tâm đến cắt tỉa multi-fidelity — và nếu bạn bị cám dỗ, hãy kiểm tra ρ@1 trước; trong một chế độ rẻ có edge thấp, nó rất có thể gần bằng không, nghĩa là cắt tỉa chỉ là tung đồng xu. Hãy dùng thời gian kỹ thuật tiết kiệm được để mở rộng phạm vi tìm kiếm, không phải thu hẹp nó.
- Đánh giá đắt (≳ ~100 ms–vài giây/backtest): mua hiệu suất theo mẫu. Dùng CMA-ES, TPE, hoặc một lai ghép CMA-ES được gieo mầm bằng Sobol; overhead của sampler giờ chỉ là sai số làm tròn so với lượt đánh giá. Nếu chi phí đánh giá của bạn có cấu trúc (một trục chỉ báo chậm và một trục ngưỡng nhanh, như trong multi-TF), hãy ưu tiên các phương pháp khai thác cấu trúc đó — cascade, drill-down, bất cứ thứ gì có nhận thức về chi phí — hơn là các phương pháp coi mọi chiều đều đắt như nhau.
- Ở giữa, hoặc không chắc chắn: một lai ghép được gieo mầm bằng Sobol (sobol→cmaes) là lựa chọn mặc định vững chắc. Nó hành xử như Sobol theo chiều rộng trước (breadth-first) ở giai đoạn đầu (rẻ, không có mô hình để khớp) và như một bộ tinh chỉnh thông minh ở giai đoạn sau, nên nó suy giảm một cách êm ái (gracefully) dù bạn đang ở chế độ nào — đó chính xác là lý do vì sao nó là nhà vô địch chế độ đắt của chúng tôi.
- Trước khi dùng bất kỳ bộ cắt tỉa nào, hãy đo fidelity. Tính ρ Spearman giữa fidelity rẻ và hàm mục tiêu đầy đủ trên vài trăm cấu hình ngẫu nhiên. Nếu ρ@1 thấp, đừng cắt tỉa trên một fold; hãy nâng tài nguyên tối thiểu cho đến khi ρ vượt qua ~0.5. Việc này chỉ tốn hai dòng code và ngăn bộ tăng tốc của bạn âm thầm loại bỏ những cấu hình tốt nhất của bạn.
- Dù phương pháp nào thắng cuộc tìm kiếm, hãy chạy các cổng deflation. Người chiến thắng của bộ tối ưu hóa là đối tượng dễ overfit nhất mà bạn sẽ tạo ra trong cả tuần. DSR và PBO, chứ không phải điểm số của bộ tối ưu hóa, mới là thứ quyết định liệu nó có thể giao dịch được hay không.
Những mối liên kết
Kết quả này nằm ở trung tâm của một vài mạch nội dung mà series này đã và đang khai thác:
- Nó giả định rằng engine bên dưới là trung thực. Toàn bộ lợi thế của chế độ rẻ tồn tại bởi vì engine numba chạy trong tiến trình của chúng tôi đạt hàng nghìn cấu hình mỗi giây mà không có IPC — bậc thang tốc độ chính là thứ đưa bạn vào chế độ "thông lượng thắng" ngay từ đầu. Một engine chậm, bị đánh thuế bởi framework sẽ đặt mọi bài toán vào chế độ đắt theo mặc định, và bạn sẽ không bao giờ thấy được điểm giao thoa.
- Chiến thuật khai thác chế độ đắt chính là cấu trúc chi phí hai trục mà engine drill-down độ phân giải thích ứng của chúng tôi được thiết kế xoay quanh: khoanh vùng trên trục thô, đắt đỏ, rồi khai thác trục mịn, rẻ.
- Mọi phương pháp ở đây chỉ đáng tin cậy vì engine không rò rỉ. Một cuộc tìm kiếm qua hàng chục nghìn trial là cỗ máy hiệu quả nhất có thể có để tìm ra và khai thác một lỗi look-ahead — "người chiến thắng" sẽ là bất kỳ cấu hình nào dựa vào rò rỉ mạnh nhất. Hãy sửa cái đồng hồ trước, rồi mới tìm kiếm.
- Và số phận của nhà vô địch — thắng cuộc tìm kiếm, thất bại ở deflation — chính là toàn bộ lập luận cho việc coi tìm kiếm tham số và kiểm soát overfitting là những giai đoạn riêng biệt với những công cụ riêng biệt.
Bối cảnh học thuật vẫn là bối cảnh mà lĩnh vực này liên tục quay trở lại: Bergstra & Bengio (2012) về lý do vì sao random đánh bại grid; Hyperband của Li và cộng sự (2018) và phần tiếp theo ASHA (2020) về multi-fidelity; và Bailey & López de Prado (2014) về lý do vì sao người chiến thắng của bất kỳ cuộc tìm kiếm lớn nào cũng phải được giảm phóng đại (deflate) trước khi được tin tưởng. Không ai trong số họ quy định một bộ tối ưu hóa tốt nhất duy nhất, vì không có cái nào cả — chỉ có một chế độ, và một chi phí quyết định chế độ đó.
Những điểm rút ra chính
- Điểm giao thoa giữa tìm kiếm random và tìm kiếm thông minh được quyết định bởi chi phí đánh giá, không phải bởi thuật toán. Chúng tôi đã đảo ngược thứ hạng của mọi phương pháp mà không thay đổi gì ngoài việc một lần backtest đắt đỏ đến mức nào.
- Đánh giá rẻ → Sobol "ngu" thắng về thông lượng. Trên engine single-TF của chúng tôi (~3–4k cfg/s), TPE và ASHA chạy chậm hơn 18–30x với cùng số lượt đánh giá — ~95–154 cfg/s so với ~2,830 của Sobol. Ở cùng wall-clock, độ phủ đánh bại một mô hình tốt hơn về không gian tham số khi mỗi điểm gần như miễn phí.
- Đánh giá đắt → các phương pháp thông minh thắng về hiệu suất. Trên bài toán triple-TF, sobol→cmaes là phương pháp duy nhất tìm được kết quả dương ngoài mẫu (+16.35% test, +2.62% holdout); Sobol mù về đích ở vị trí chót.
- Trong chế độ đắt, "thông minh" nghĩa là có nhận thức về chi phí. Người chiến thắng đã khai thác khoảng cách 30–100x giữa trục chỉ báo đắt đỏ và trục ngưỡng rẻ — nó thực hiện nhiều lượt đánh giá hơn và đặt chúng tốt hơn, bằng cách ở lại trên trục rẻ một khi trục đắt đã được ghim cố định.
- Fidelity là tiền đề cho việc cắt tỉa. Tương quan xếp hạng theo một fold tăng từ ρ@1 ≈ 0.03 (single-TF, về cơ bản là ngẫu nhiên) lên 0.43 (multi-TF), đạt 0.91 sau năm fold. Multi-fidelity/ASHA chỉ mang lại hiệu quả một khi fidelity rẻ xếp hạng giống như fidelity đắt — vậy nên hãy đo ρ trước khi cắt tỉa.
- Thắng cuộc tìm kiếm không có nghĩa là sống sót qua nó. Nhà vô địch đã vượt qua PBO nhưng thất bại ở cổng Deflated Sharpe. Hãy chọn bộ tối ưu hóa dựa trên chi phí đánh giá; hãy quyết định khả năng giao dịch được bằng các cổng deflation. Đó là những công cụ khác nhau, và bạn cần cả hai.
Hãy chọn bộ tối ưu hóa của bạn dựa trên chi phí của một lần backtest. Sau đó hãy nhớ rằng câu trả lời tốt nhất mà một bộ tối ưu hóa có thể tìm được trong một không gian không có edge vẫn là không có edge — và hãy để các cổng, chứ không phải cuộc tìm kiếm, cho bạn biết bạn đang cầm cái nào trong tay.
Tác Giả
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.