← Quay lại danh sách bài viết
July 2, 2026
5 phút đọc

Thiết Kế Hàm Mục Tiêu: Chỉ Số Bạn Tối Ưu Hóa Âm Thầm Chọn Chiến Lược Của Bạn

Thiết Kế Hàm Mục Tiêu: Chỉ Số Bạn Tối Ưu Hóa Âm Thầm Chọn Chiến Lược Của Bạn
#algotrading
#backtest
#overfitting
#objective-function
#optimization
#sharpe
#validation
🎯
Part 1 of 7 · Collection
Backtesting Without Fooling Yourself

Bài viết thuộc series "Backtest Không Ảo Tưởng".

📄 Bài viết này đã phát triển thành một bài báo nghiên cứu. Mọi con số dưới đây đến từ một script tất định duy nhất xây dựng ground truth có kiểm soát — một thị trường tổng hợp với lợi thế đã biết trong một dải tín hiệu vừa phải và nhiễu đuôi béo ở khắp mọi nơi — sau đó chạy một tìm kiếm ngưỡng dưới sáu hàm mục tiêu khác nhau và đo, out of sample, chiến lược nào mỗi hàm mục tiêu thực sự chọn. Đọc bài báo trực tuyến (phiên bản tương tác + PDF) tại objective-design.marketmaker.cc, mã nguồn và dữ liệu tại github.com/suenot/objective-design-degeneracy.

Bạn muốn chiến lược tốt nhất. Vì vậy bạn chạy một tìm kiếm — quét qua một ngưỡng, một lookback, một khoảng cách stop, và giữ lại thiết lập nào đạt điểm cao nhất. Tìm kiếm kết thúc và trao cho bạn một người chiến thắng. Hợp lý. Chuẩn mực. Đó là điều mọi optimizer, grid search, và hyperparameter tuner trên đời đều làm.

Nhưng hãy nhìn vào động từ: đạt điểm cao nhất. Cao nhất về cái gì? Trước khi tìm kiếm có thể tôn vinh bất cứ điều gì, bạn phải trao cho nó một con số duy nhất để tối đa hóa — một hàm mục tiêu. PnL. Sharpe. Sharpe-trên-các-nến-bạn-đã-giao-dịch. Return-trên-max-drawdown. Bạn đã gõ một trong số này, có lẽ không suy nghĩ nhiều, và sau đó tìm kiếm đã dành một triệu lần đánh giá để làm chính xác những gì bạn yêu cầu.

Lựa chọn đó không phải là một thủ tục hình thức. Đó là toàn bộ quyết định. Tìm kiếm không tìm ra "một chiến lược tốt" — không có thứ gì như vậy một cách trừu tượng. Nó tìm ra chiến lược tối đa hóa con số vô hướng bạn đã chọn, và các con số vô hướng khác nhau chỉ vào những chiến lược hoàn toàn khác nhau trên cùng một dữ liệu. Hàm mục tiêu là bàn tay bí mật trên vô lăng, và hầu hết thời gian không ai nhìn vào nó.

Đây là toàn bộ bài viết trong một bảng. Một tìm kiếm ngưỡng, một thị trường tổng hợp với một lợi thế thực, đã biết, sáu hàm mục tiêu — và sáu chiến lược mà chúng chọn, đo trên dữ liệu held-out:

Hàm mục tiêu (thứ mà tìm kiếm tối đa hóa) Mức tiếp xúc thị trường trung bình Sharpe in-sample Sharpe out-of-sample Người chiến thắng thoái hóa
PnL thô 0.859 1.76 1.61 0%
Sharpe toàn dòng thời gian 0.740 1.82 1.71 0%
Sharpe per-trade ("active") 0.286 1.00 0.70 57%
Sàn tiếp xúc (emin=0.20e_{\min}=0.20) 0.740 1.82 1.71 0%
Shrinkage theo số lượng giao dịch (conf_k=40=40) 0.523 1.54 1.31 20.7%
Robust (floor + conf_k) 0.675 1.78 1.70 0.2%

600 seed độc lập, T=2000T = 2000 nến mỗi seed, 80 ngưỡng ứng viên mỗi tìm kiếm, in-sample và out-of-sample được rút mẫu độc lập. Sharpe hàng năm (252 chu kỳ/năm). "Thoái hóa" = người chiến thắng được chọn ở trong thị trường ít hơn 5% thời gian, hoặc đạt một Sharpe out-of-sample không dương. Điểm tối ưu thực sự của thị trường này là một Sharpe hàng năm out-of-sample 1.77.

Hãy đọc hàng thứ ba cho đến khi nó nhức nhối. Sharpe per-trade — một đại diện cho cả họ các chỉ số điều-kiện-theo-hoạt-động (Sharpe per-trade, expectancy, SQN của van Tharp, tỷ lệ thắng), tất cả đều được tính trên chỉ các nến bạn đã giao dịch — chọn một chiến lược mà out of sample tệ hơn hơn một nửa số còn lại, và làm điều đó một cách thoái hóa 57% số lần. Đó không phải là một hàm mục tiêu tệ hơn một cách tinh tế. Trên dữ liệu này nó là một cái bẫy, và tìm kiếm bước vào nó hơn một nửa số lần. Bây giờ hãy đọc hàng ngay phía trên nó: Sharpe toàn dòng thời gian thuần túy không bao giờ thoái hóa và đạt 1.71 out of sample. Đó chính là điểm nút của toàn bộ cách khắc phục, tiết lộ sớm — cách sửa trung thực đơn giản là đo trên toàn bộ dòng thời gian; các bản vá tinh vi hơn ở các hàng dưới cùng, ở mức tốt nhất, chỉ khớp với con số đó, không bao giờ vượt qua nó. Bài viết này là giải phẫu học của cái bẫy đó và cách khắc phục nó, với ground truth được biết trước xuyên suốt để câu hỏi "hàm mục tiêu có chọn đúng chiến lược không?" là một sự thật, không phải một ý kiến.

Màn 1 — Quyết định bí mật: định luật Goodhart chính là tìm kiếm

Một tìm kiếm tham số được vẽ như một cái phễu gồm nhiều đường cong chiến lược ứng viên, với một thấu kính duy nhất được gắn nhãn OBJECTIVE đóng dấu một đường cong là người chiến thắng trong khi các đường cong trông giống hệt nhau bị loại bỏ, minh họa rằng việc lựa chọn chỉ số âm thầm chọn ra chiến lược

Năm 1975, nhà kinh tế học Charles Goodhart đã viết một câu mà đã tồn tại lâu hơn mọi thứ khác ông từng làm:

"Bất kỳ quy luật thống kê nào được quan sát cũng sẽ có xu hướng sụp đổ một khi áp lực được đặt lên nó cho mục đích kiểm soát."

Cách diễn giải phổ biến, thường được gán cho Marilyn Strathern, thì súc tích hơn: khi một thước đo trở thành mục tiêu, nó không còn là một thước đo tốt nữa.

Một tìm kiếm tham số là ví dụ thuần túy nhất có thể có của định luật Goodhart. Hàm mục tiêu là thước đo. Tìm kiếm là áp lực — hàng nghìn, hàng triệu lần thử để đẩy thước đo đó lên cao nhất có thể. Và tìm kiếm không quan tâm chút nào đến việc bạn muốn nói gì qua thước đo đó. Nó chỉ quan tâm đến con số. Nếu có bất kỳ cách nào để làm cho con số lớn lên mà không liên quan gì đến một lợi thế thực, có thể giao dịch được — giao dịch hiếm khi, đứng yên (flat) hầu hết thời gian, bắt được vài giá trị ngoại lai may mắn — tìm kiếm sẽ tìm ra cách đó, bởi vì tìm ra giá trị lớn nhất là điều duy nhất nó được xây dựng để làm.

Đây chính là thất bại mà tài liệu về an toàn AI gọi là reward hacking (khai thác phần thưởng): một tác nhân (agent) tối ưu hóa một proxy (đại diện) cho thứ bạn muốn sẽ khai thác mọi khoảng hở giữa proxy đó và mục tiêu thực. Tìm kiếm của bạn chính là tác nhân đó. "Tỷ lệ Sharpe" chính là proxy đó. "Một chiến lược tôi có thể tin tưởng để giao dịch tiền thật vào quý tới" chính là mục tiêu. Khoảng hở giữa chúng là nơi toàn bộ ngành kỷ luật này tồn tại.

Để quan sát khoảng hở đó mở ra, chúng ta cần một thế giới nơi chúng ta biết sự thật. Vì vậy chúng ta xây dựng một thế giới như thế.

Thị trường. Mỗi kỳ, một biến dự báo sts_t (một tín hiệu chuẩn hóa standard-normal) xuất hiện, theo sau là lợi nhuận rtr_t mà nó dự báo một phần. Lợi thế là có thật nhưng bị giới hạn — nó chỉ tồn tại bên trong một dải tín hiệu vừa phải st1|s_t| \le 1, và biến mất bên ngoài dải đó:

rt=βst1[st1]+εt,β=0.3,εtt4 (unit variance).r_t = \beta\, s_t \cdot \mathbf{1}\big[\,|s_t| \le 1\,\big] + \varepsilon_t, \qquad \beta = 0.3, \qquad \varepsilon_t \sim t_{4}\ (\text{unit variance}).

Có hai lựa chọn thiết kế quan trọng. Thứ nhất, lợi thế nằm trong dải vừa phải: các tín hiệu cực đoan không mang thông tin dự báo nào, vì vậy một chiến lược nên giao dịch ở phần giữa và bỏ qua các đuôi. Thứ hai, nhiễu εt\varepsilon_tđuôi béo (Student-tt với 4 bậc tự do, kiểu đuôi nặng mà lợi nhuận thực tế thực sự có) — nhưng thành phần này ở đây vì tính thực tế, không phải vì cơ chế. Thật hấp dẫn khi nói rằng đuôi béo chính là thứ khiến cái bẫy có thể xảy ra, và chúng tôi đã giả định chính xác điều đó cho đến khi chúng tôi chạy nhóm đối chứng: một phiên bản nhiễu Gaussian của thị trường này (gaussian_control trong kết quả, 300 seed) tái tạo lại cái bẫy về cơ bản không đổi — hàm mục tiêu per-trade vẫn thoái hóa 55.7% số lần dưới nhiễu Gaussian so với 57.0% với đuôi béo, và Sharpe out-of-sample của nó là 0.71 so với 0.70. Vì vậy cái bẫy không liên quan đến đuôi béo. Đó là một hiệu ứng thuần túy mẫu-nhỏ-cộng-lựa-chọn: lấy giá trị lớn nhất, trên khoảng 20 ngưỡng có mức tiếp xúc thấp, của một Sharpe được tính trên một nhúm quan sát, và một góc may mắn nào đó sẽ luôn trông ngoạn mục. Bất kỳ phân phối nhiễu nào cũng làm được điều này; một chiến lược ở trong thị trường chỉ vài nến có thể, chỉ bằng may mắn, trải qua vài chuyển động thuận lợi và đạt một con số in-sample chẳng có ý nghĩa gì. Chúng tôi giữ đuôi béo vì lợi nhuận thực tế có chúng, không phải vì cái bẫy cần chúng.

Chiến lược. Một họ một tham số. Giao dịch theo hướng của tín hiệu bất cứ khi nào độ lớn của nó dưới một ngưỡng θ\theta, nếu không thì đứng yên (flat):

post=sign(st)1[stθ].\text{pos}_t = \operatorname{sign}(s_t)\cdot \mathbf{1}\big[\,|s_t| \le \theta\,\big].

Một θ\theta rất nhỏ chỉ giao dịch trên những tín hiệu nhỏ nhất, tầm thường nhất — một vé số giao-dịch-hiếm, gần như không bao giờ ở trong thị trường. Một θ\theta gần rìa dải bắt được toàn bộ lợi thế thực và có mức tiếp xúc tốt. Một θ\theta khổng lồ giao dịch mọi thứ, bao gồm cả các nến ngoài dải không mang lợi thế nào và chỉ thêm nhiễu.

def gen_dataset(T, rng, beta=0.30, band=1.0, tail_df=4):
    s    = rng.standard_normal(T)
    edge = beta * np.where(np.abs(s) <= band, s, 0.0)          # edge ONLY inside |s| <= 1
    t    = rng.standard_t(tail_df, T) / np.sqrt(tail_df / (tail_df - 2.0))  # fat tails, unit var
    return s, edge + t

def simulate(s, r, theta):
    pos      = np.where(np.abs(s) <= theta, np.sign(s), 0.0)   # trade the band, skip outliers
    strat    = pos * r
    active   = pos != 0.0
    exposure = active.mean()                                   # fraction of bars in a position
    sharpe_full   = strat.mean()         / strat.std(ddof=1)            # on the WHOLE timeline
    sharpe_active = strat[active].mean() / strat[active].std(ddof=1)    # on ONLY the active bars
    return dict(exposure=exposure, n_trades=int(active.sum()),
                sharpe_full=sharpe_full, sharpe_active=sharpe_active, pnl=strat.sum())

Bởi vì chúng tôi đã xây dựng thị trường này, chúng tôi có thể tính toán sự thật trực tiếp — hiệu suất trung bình tại mọi ngưỡng trên toàn bộ 600 seed, out of sample. Điểm tối ưu thực sự nằm ở θ1.04\theta \approx 1.04: ngay tại rìa của dải tín hiệu, ở trong thị trường khoảng 70% thời gian (suy ra: một tín hiệu chuẩn hóa rơi vào bên trong s1.04|s|\le 1.04 với xác suất P(s1.04)=0.70P(|s|\le 1.04)=0.70), đạt Sharpe hàng năm out-of-sample 1.77. Đó là con số mà mọi hàm mục tiêu đang cố gắng tìm ra. Hãy ghi nhớ nó: θ≈1.04, Sharpe OOS 1.77, khoảng 70% dòng thời gian ở trong thị trường. Bất cứ điều gì một hàm mục tiêu chọn mà xa con số này là hàm mục tiêu đang thất bại, không phải vì thị trường khó.

Màn 2 — Cái bẫy: tám giao dịch may mắn, một Sharpe bằng 21, một ảo ảnh

Một máy đánh bạc trả thưởng ở một lượt quay may mắn duy nhất, cho thấy tám vé giao dịch và một Sharpe per-trade in-sample cao vút bằng 21 sụp đổ xuống 0.13 out of sample, kịch tính hóa một người chiến thắng vé-số-giao-dịch-hiếm được chọn bởi một hàm mục tiêu ngây thơ

Bây giờ hãy để một hàm mục tiêu ngây thơ tự do trên một lần rút mẫu cụ thể của thị trường này — seed 6. Công khai đầy đủ về seed này: nó không phải là lần rút mẫu đầu tiên hay ngẫu nhiên. Chúng tôi đã quét qua các seed để tìm một người chiến thắng per-trade thoái hóa rõ rệt và chọn seed này, chính xác là để cơ chế đó không thể bị bỏ lỡ. Kết quả mà nó cho thấy là hoàn toàn điển hình — như Màn 3 sẽ xác nhận, hàm mục tiêu per-trade chọn một vé số có mức tiếp xúc dưới 5% trong 56% tổng số seed — nhưng độ lớn của seed 6 nằm ở đầu cực đoan của phân phối đó. Hãy đọc nó như một ví dụ đặc biệt rõ rệt của một thất bại phổ biến, không phải một ví dụ trung vị. Chúng tôi tối ưu hóa Sharpe per-trade: tỷ lệ Sharpe được tính chỉ trên các nến mà chiến lược thực sự đang giữ vị thế. Đây là một điều cực kỳ tự nhiên để báo cáo. "Khi nó giao dịch, các giao dịch của nó tốt đến đâu?" Nó có cảm giác như cô lập kỹ năng khỏi sự nhàn rỗi. Nó làm điều ngược lại.

Đây là chiến lược mà Sharpe per-trade tôn vinh trên seed 6:

  • Ngưỡng θ=0.005\theta = 0.005 — nó chỉ giao dịch trên những tín hiệu nhỏ nhất.
  • Mức tiếp xúc thị trường 0.4% — nó đứng yên 99.6% thời gian.
  • Tám giao dịch. Tám. Trên 2000 nến.
  • Sharpe per-trade hàng năm in-sample: 21.09.
  • Sharpe toàn dòng thời gian in-sample: 0.82.
  • Sharpe toàn dòng thời gian out-of-sample: 0.13.

Chỉ số per-trade đọc được 21.09 — một con số chưa từng có chiến lược thực nào đạt được, kiểu con số sẽ khiến một quỹ được ra mắt. Và nó là một ảo ảnh hoàn toàn. Tám giao dịch đó tình cờ bắt được vài chuyển động thuận lợi; đo trên chỉ tám nến đó, tỷ lệ giữa trung bình và độ lệch chuẩn là thiên văn. Nhưng trên toàn bộ dòng thời gian — nơi chiến lược đứng yên 99.6% thời gian — "lợi thế" đó đóng góp về cơ bản là không có gì: một Sharpe toàn dòng thời gian 0.82 in sample, sụp đổ xuống 0.13 trên dữ liệu mới. Người chiến thắng mà hàm mục tiêu đã chọn, xét cho mọi mục đích giao dịch, là đứng yên.

Và nó thậm chí không phải là một lợi thế thực ở ngưỡng đó. Hãy nhớ lại thị trường: lợi thế nằm trong dải s1|s|\le 1, và θ=0.005\theta = 0.005 nằm ngay tại trung tâm nơi tín hiệu yếu nhất. Đường cong out-of-sample thực sự tại θ=0.005\theta = 0.005−0.01 — không thể phân biệt được với không (suy ra từ đường cong ground-truth). Tìm kiếm không tìm thấy một lợi thế thực nhỏ. Nó tìm thấy tám lần rút mẫu nhiễu may mắn và báo cáo chúng như một Sharpe bằng 21.

Đây là cái bẫy thu nhỏ: Sharpe per-trade thưởng cho chiến lược vì giao dịch càng hiếm càng tốt, bởi vì càng ít nến bạn đứng trên đó, càng dễ để vài nến trong số chúng may mắn, và chỉ số này không bao giờ một lần hỏi "nhưng bạn có thực sự ở trong thị trường không?" Độ lớn của seed 6 là được chọn lọc kỹ càng — chúng tôi đã đi tìm một cái rõ rệt — nhưng bản chất của nó thì không. Trên toàn bộ 600 seed, Sharpe per-trade chọn một người chiến thắng thoái hóa (một người hầu như không giao dịch, hoặc thua lỗ out of sample) trong 57% số đó, và một vé số có mức tiếp xúc dưới 5% cụ thể trong 56%. Lựa chọn thoái hóa điển hình ôn hòa hơn nhiều so với Sharpe bằng 21 của seed 6: tính trung bình trên toàn bộ 600 seed, người chiến thắng của hàm mục tiêu per-trade có Sharpe per-trade in-sample là 4.58 và mức tiếp xúc trung bình 0.286 — vẫn đứng yên hầu hết thời gian, chỉ là không đứng yên 99.6%. Seed 6 kịch tính hóa cơ chế; con số 56% mới là phần nên khiến bạn lo lắng. Hơn một nửa số lần, chỉ số thông dụng hàng ngày này trao cho bạn một tấm vé số và gọi nó là một chiến lược.

Màn 3 — Sự thật thống kê: sáu hàm mục tiêu, 600 seed

Sáu hàm mục tiêu như những thí sinh trên một bảng xếp hạng, Sharpe per-trade tỏa sáng nhất in sample nhưng bị đóng dấu thoái hóa 57 phần trăm trong khi các hàm mục tiêu nhận-biết-tiếp-xúc giữ vững out of sample, minh họa rằng một con số in-sample tuyệt vời không có nghĩa là một lựa chọn tốt

Một seed không chứng minh được gì cả; nó chỉ minh họa. Để đo lường một hàm mục tiêu, chúng ta phải hỏi nó chọn gì trung bình, trên nhiều thị trường độc lập, và chấm điểm lựa chọn đó trên dữ liệu mà tìm kiếm chưa bao giờ thấy. Vì vậy: 600 seed, mỗi seed là một lần rút mẫu độc lập của thị trường; trên mỗi seed, chạy tìm kiếm 80-ngưỡng dưới mỗi hàm mục tiêu; ghi lại mức tiếp xúc, Sharpe in-sample và out-of-sample của bất cứ thứ gì nó chọn, và liệu lựa chọn đó có thoái hóa hay không.

Hàm mục tiêu Mức tiếp xúc trung bình Sharpe in-sample Sharpe out-of-sample Mức giảm IS→OOS (tuyệt đối) Thoái hóa
PnL thô 0.859 1.76 1.61 0.15 0.0%
Sharpe toàn dòng thời gian 0.740 1.82 1.71 0.11 0.0%
Sharpe per-trade 0.286 1.00 0.70 0.30 57%
Sàn tiếp xúc (emin=0.20e_{\min}=0.20) 0.740 1.82 1.71 0.11 0.0%
Shrinkage conf_k (k=40k=40) 0.523 1.54 1.31 0.23 20.7%
Robust (floor + conf_k) 0.675 1.78 1.70 0.08 0.2%

Cột "Mức giảm IS→OOS" là mức sụt giảm tuyệt đối trong Sharpe hàng năm từ in-sample đến out-of-sample (ví dụ 1.000.701.00\to0.70 là một mức giảm 0.30), không phải phần trăm. Và hãy chú ý hàng "Sàn tiếp xúc" giống hệt từng byte với "Sharpe toàn dòng thời gian": đó không phải là sự trùng hợp, và Màn 5 giải thích lý do tại sao.

Ba sự thật nổi bật lên, và mỗi cái là một bài học.

Sharpe per-trade là hàm mục tiêu ngây thơ duy nhất thoái hóa. Mức tiếp xúc trung bình của nó là 0.286 — nó chọn các chiến lược đứng yên hầu hết thời gian — và Sharpe in-sample 1.00 của nó giảm 0.30 xuống out-of-sample 0.70, tệ nhất trong nhóm. Hãy chú ý dấu hiệu này: con số in-sample của nó (1.00) thậm chí không ấn tượng, nhưng trên bất kỳ một seed đơn lẻ nào nó sẽ vui vẻ báo cáo một con số per-trade là 21. Giá trị trung bình bị triệt tiêu bởi vì các cửa sổ may mắn chỉ theo các hướng ngẫu nhiên; những gì sống sót đến out-of-sample chỉ là 0.70, và 57% các lựa chọn cá nhân hoàn toàn là rác.

Các hàm mục tiêu nhận-biết-tiếp-xúc tự nhiên an toàn. PnL thô và Sharpe toàn dòng thời gian không bao giờ thoái hóa (0.0%). Lý do mang tính cấu trúc: cả hai đều được đo trên toàn bộ dòng thời gian, vì vậy một chiến lược đứng yên 99.6% thời gian kiếm được gần như không có gì dưới chúng. Bạn không thể lợi dụng một chỉ số toàn dòng thời gian bằng cách giao dịch hiếm khi — việc đứng yên bị phạt trực tiếp và tự động, bởi vì các nến đứng yên nằm trong mẫu số. Đây là ý tưởng quan trọng nhất trong toàn bộ bài viết, và chúng ta sẽ quay lại nó ở Màn 6.

PnL thô an toàn nhưng không tối ưu — nó tiếp xúc quá mức. Hãy nhìn kỹ: mức tiếp xúc trung bình của PnL thô là 0.859, cao nhất trong tất cả, và Sharpe out-of-sample của nó (1.61) thấp hơn một chút dưới Sharpe toàn dòng thời gian (1.71) và điểm tối ưu thực sự (1.77). PnL thưởng cho việc ở trong thị trường, vì vậy tìm kiếm đẩy θ\theta quá cao (trên seed 6, PnL thô chọn θ=1.84\theta=1.84 so với mức tối ưu 1.04), kéo theo các nến ngoài dải không mang lợi thế nào và chỉ thêm nhiễu. Nó không nổ tung — nhưng nó trôi qua điểm tối ưu thực theo hướng ngược lại so với cái bẫy per-trade. Hàm mục tiêu khác nhau, thiên lệch khác nhau, cùng một bài học: chỉ số đã chọn chiến lược.

Hai hàng chúng ta chưa thảo luận — sàn tiếp xúc và conf_k — chính là cách khắc phục. Đó là màn tiếp theo.

Màn 4 — Tại sao tám giao dịch không bao giờ có thể được tin tưởng

Một ước lượng điểm Sharpe duy nhất được đánh dấu với một thanh sai số khoảng tin cậy khổng lồ bởi vì nó dựa trên chỉ tám quan sát, bên cạnh một thước đo được gắn nhãn minimum track record length, minh họa rằng một tỷ lệ được đo trên một nhúm giao dịch là vô nghĩa về mặt thống kê

Trước khi khắc phục cái bẫy, đáng để chính xác về tại sao tám giao dịch tạo ra một Sharpe bằng 21 chẳng có ý nghĩa gì — bởi vì cách sửa xuất phát trực tiếp từ lý do đó.

Tỷ lệ Sharpe là một ước lượng, và các ước lượng có thanh sai số. Kết quả năm 2002 của Andrew Lo cho sai số chuẩn của một tỷ lệ Sharpe được ước lượng từ TT quan sát, dưới giả định hào phóng nhất có thể (lợi nhuận IID Gaussian):

SE(SR^)1+SR^2/2T.\operatorname{SE}\big(\widehat{SR}\big) \approx \sqrt{\frac{1 + \widehat{SR}^{\,2}/2}{T}}.

Sai số chỉ thu hẹp theo 1/T1/\sqrt{T}. Hãy đưa cái bẫy vào công thức này. Sharpe per-trade trên seed 6 là 21.0921.09 hàng năm, tương đương 1.331.33 trên mỗi quan sát, được tính trên T=8T = 8 nến. Sai số chuẩn là

SE1+1.332/280.49 per observation = 7.7 annualized\operatorname{SE} \approx \sqrt{\frac{1 + 1.33^2/2}{8}} \approx 0.49 \ \text{per observation} \ = \ \textbf{7.7 annualized}

(suy ra từ công thức của Lo). Ước lượng điểm là 21.0921.09; thanh sai số một-sigma của nó có bậc độ lớn ±7.7\pm 7.7 — hãy đọc điều này như một bậc độ lớn mang tính minh họa, không phải một khoảng tin cậy đã hiệu chuẩn, bởi vì công thức này giả định lợi nhuận IID Gaussian mà nhiễu t4t_4 đuôi béo của chúng ta vi phạm. Dù vậy, thông điệp là rõ ràng không thể nhầm lẫn: "Sharpe bằng 21" là một con số được rút ra từ một phân phối rộng đến mức nó về cơ bản không mang thông tin gì — và đó là phép tính hào phóng, bởi vì phần mở rộng của Mertens cho thấy đuôi béo và độ lệch (skew) chỉ làm phình to sai số chuẩn hơn nữa. Sharpe của một backtest giao-dịch-hiếm kém đáng tin cậy hơn giá trị điểm của nó theo mọi hướng cùng một lúc: quá ít quan sát, và sai phân phối.

Đây chính xác là điều mà Minimum Track Record Length (độ dài track record tối thiểu) hình thức hóa (Bailey & López de Prado, 2012). Nó đảo ngược câu hỏi — tôi cần bao nhiêu quan sát trước khi tôi được phép tin vào một Sharpe có kích thước này ở độ tin cậy pp?

MinTRL=1+[1γ^3SR^+γ^414SR^2](Z1pSR^SR)2,\text{MinTRL} = 1 + \Big[\,1 - \hat\gamma_3\,\widehat{SR} + \tfrac{\hat\gamma_4 - 1}{4}\,\widehat{SR}^{\,2}\,\Big]\left(\frac{Z_{1-p}}{\widehat{SR} - SR^*}\right)^{2},

biến "hãy tin tưởng ít hơn vào các backtest giao-dịch-ít" thành một con số giao dịch rõ ràng, có thể kiểm tra được. Điểm sâu sắc cho việc thiết kế hàm mục tiêu là thế này: một hàm mục tiêu tốt nên áp đặt một track record tối thiểu từ bên trong, thay vì để một con người nhận ra, sau khi sự việc đã xảy ra, rằng người chiến thắng dựa trên tám quan sát. Sharpe per-trade làm điều ngược lại — nó được tối đa hóa bằng cách đẩy số lượng quan sát về mức tối thiểu. Bất kỳ hàm mục tiêu nào có điểm tối ưu nằm ở "càng ít giao dịch càng tốt" thì, theo cấu trúc, là một hàm mục tiêu tìm kiếm chính ước lượng kém tin cậy nhất của nó.

Hai thất bại cộng dồn trong cái bẫy này, và gọi tên cả hai cho chúng ta biết cách sửa nó. Thứ nhất, nhiễu mẫu nhỏ: tám quan sát không thể ghim chặt được bất kỳ tỷ lệ nào. Thứ hai, lựa chọn: tám nến đó không được trao cho chúng ta — tìm kiếm đã chọn ngưỡng rơi vào chúng, một phần bởi vì chúng may mắn. Tìm kiếm là một bộ tối đa hóa; nó sẽ luôn tìm ra góc của không gian nơi nhiễu tình cờ trông giống tín hiệu. Bạn không thể vượt qua điều này bằng một ước lượng điểm khéo léo hơn. Bạn phải thay đổi ý nghĩa của "tốt nhất" để góc may mắn đó không còn là giá trị lớn nhất.

Màn 5 — Cách khắc phục: một sàn tiếp xúc và một shrinkage theo số lượng giao dịch

Một bảng điều khiển với hai núm vặn được gắn nhãn exposure floor và conf_k shrinkage, cả hai đều nâng một bề mặt hiệu suất out-of-sample lên một cao nguyên phẳng cao, trong khi một chỉ báo thoái hóa tắt đi, minh họa hai cách khắc phục độc lập cùng nhau khôi phục lại điểm tối ưu thực sự

Chúng ta có hai căn bệnh đã được gọi tên — giao dịch quá hiếmdựa trên quá ít quan sát — vì vậy chúng ta viết hai phương thuốc, mỗi phương nhắm vào một căn bệnh.

Phương thuốc 1: một sàn tiếp xúc (exposure floor). Cách sửa đơn giản nhất có thể. Từ chối hoàn toàn bất kỳ chiến lược nào không ở trong thị trường ít nhất emine_{\min} thời gian — nếu bạn hầu như không giao dịch, điểm của bạn là -\infty và tìm kiếm không thể chọn bạn. Nhưng có một sự tinh tế trung thực trong cái gì bạn đặt sàn cho, và đó là bài học thầm lặng của toàn bộ bài viết này. Như một hàm mục tiêu độc lập, chúng tôi đặt sàn cho Sharpe toàn dòng thời gian, và trên thị trường này điều đó không thay đổi gì cả: người chiến thắng riêng của Sharpe toàn dòng thời gian đã nằm ở mức ~74% tiếp xúc rồi, vì vậy một sàn 20% không bao giờ bị kích hoạt. Đó chính xác là lý do tại sao các hàng "sàn tiếp xúc" và "Sharpe toàn dòng thời gian" trong các bảng ở trên giống hệt nhau từng byte — gắn một sàn vào một chỉ số vốn đã an toàn và bạn chỉ đơn giản tái tạo lại Sharpe toàn dòng thời gian. Sàn chỉ làm công việc có thể nhìn thấy được khi nó bảo vệ một chỉ số mà nếu không sẽ chạy thẳng vào góc: một chỉ số per-trade, như trong hàm mục tiêu robust dưới đây. Nói cách khác, "yêu cầu tiếp xúc" và "đo trên toàn bộ dòng thời gian" là, trên dữ liệu này, hai cái tên cho cùng một sự can thiệp.

Phương thuốc 2: một shrinkage theo số lượng giao dịch — "conf_k". Dành cho khi bạn bị mắc kẹt với một chỉ số per-trade và muốn một sự điều chỉnh mềm thay vì một ngưỡng cắt cứng: chiết khấu Sharpe một cách liên tục theo số lượng giao dịch mà nó dựa vào. Nhân với n/(n+k)n/(n+k), trong đó nn là số lượng giao dịch và kk là một "hằng số tin cậy" cố định — một sức mạnh tiên nghiệm tương-đương-giao-dịch được chọn trước khi tìm kiếm:

score(θ)=SR^(θ)n(θ)n(θ)+k.\text{score}(\theta) = \widehat{SR}(\theta)\cdot \frac{n(\theta)}{n(\theta) + k}.

Khi n0n \to 0 điểm số bị đè xuống không bất kể Sharpe thô lớn đến đâu; khi nn \to \infty điểm số hội tụ về Sharpe thô. Đây là cùng một logic sửa chữa như MinTRL và sai số chuẩn ở Màn 4 — thu nhỏ một ước lượng mẫu nhỏ về không như một hàm giảm dần theo kích thước mẫu của nó — được gấp trực tiếp vào trong hàm mục tiêu thay vì được áp dụng như một bộ lọc hậu-kỳ. Tiền lệ có tên gần nhất là System Quality Number của van Tharp (SQN=Ntrade/σtrade\text{SQN} = \sqrt{N}\cdot \overline{\text{trade}}/\sigma_{\text{trade}}), thứ tương tự làm cho một chỉ số chất lượng per-trade tỷ lệ theo số lượng giao dịch NN — mặc dù dạng hàm số khác nhau (N\sqrt{N} tăng không giới hạn, trong khi n/(n+k)n/(n+k) bão hòa tại 1). Về hình dạng, phương pháp của chúng tôi là một shrinkage kiểu Bayesian precision-weighted / empirical-Bayes; đó là công trình của chúng tôi cho vấn đề này, không phải một ước lượng có tên được lấy từ tài liệu.

def obj_active_sharpe(m):                  # the trap: Sharpe on only the active bars
    return m["sharpe_active"]

def _shrink(n, conf_k):                     # trade-count shrinkage n / (n + k)
    return n / (n + conf_k) if (n + conf_k) > 0 else 0.0

def obj_confk(m, conf_k=40.0):              # few trades -> little credit
    return m["sharpe_active"] * _shrink(m["n_trades"], conf_k)

def obj_robust(m, e_min=0.20, conf_k=40.0): # both cures at once
    if m["exposure"] < e_min:               # floor: reject strategies that barely trade
        return -np.inf
    return m["sharpe_active"] * _shrink(m["n_trades"], conf_k)

Bây giờ đến phần trung thực: bao nhiêu sàn, bao nhiêu shrinkage? Hãy quét cả hai và đọc toàn bộ bề mặt. Mỗi ô là Sharpe out-of-sample trung bình trên 200 seed (một tập con một-phần-ba của 600, để giữ cho việc quét hai chiều rẻ hơn) với tỷ lệ thoái hóa bên cạnh nó:

emine_{\min} \ conf_k k=0k=0 k=40k=40 k=80k=80
0.00 0.66 (59.5%) 1.26 (22.5%) 1.47 (11.5%)
0.05 1.43 (10.0%) 1.53 (6.0%) 1.60 (4.0%)
0.10 1.64 (1.5%) 1.65 (1.0%) 1.67 (1.0%)
0.20 1.71 (0.0%) 1.71 (0.0%) 1.71 (0.0%)
0.35 1.73 (0.0%) 1.73 (0.0%) 1.73 (0.0%)

Sharpe hàng năm out-of-sample trung bình, với tỷ lệ thoái hóa trong ngoặc đơn. Ô trên-cùng-bên-trái (0,0)(0,0) là Sharpe per-trade thô — không sàn, không shrinkage: OOS 0.66, thoái hóa 59.5%. Đó là cùng một hàm mục tiêu với hàng per-trade của Màn 3, vốn đọc là 0.70 / 57%; khoảng cách nhỏ đó thuần túy là do bộ seed — lần quét này dùng 200 seed, Monte Carlo dùng toàn bộ 600. Cùng chỉ số, mẫu nhỏ hơn.

Bề mặt này kể một câu chuyện rõ ràng qua ba cách đọc.

Mỗi phương thuốc hoạt động độc lập. Di chuyển sang phải dọc theo hàng trên cùng (thêm shrinkage, không sàn): OOS leo từ 0.661.261.470.66 \to 1.26 \to 1.47 và thoái hóa giảm từ 59.5%22.5%11.5%59.5\% \to 22.5\% \to 11.5\%. Di chuyển xuống dưới cột bên trái (thêm sàn, không shrinkage): OOS leo từ 0.661.431.641.710.66 \to 1.43 \to 1.64 \to 1.71 và thoái hóa giảm từ 59.5%10%1.5%0%59.5\% \to 10\% \to 1.5\% \to 0\%. Mỗi núm vặn, khi được vặn riêng lẻ, độc lập nâng hiệu suất out-of-sample và tiêu diệt thoái hóa. Sàn tiếp xúc là đòn bẩy đơn lẻ mạnh hơn ở đây, bởi vì nó tấn công trực diện vào đặc điểm định nghĩa của cái bẫy — mức tiếp xúc gần-bằng-không.

Cùng nhau chúng đạt đến cao nguyên — và cao nguyên đó chính là Sharpe toàn dòng thời gian. Đến emin=0.20e_{\min} = 0.20 hàng này phẳng ở OOS 1.71 với 0% thoái hóa trên mọi mức shrinkage; đẩy đến emin=0.35e_{\min}=0.35 và nó nhích lên 1.73. Nhưng hãy nhìn kỹ vào cái gì con số 1.71 đó thực sự là: đó chính xác là điểm số mà Sharpe toàn dòng thời gian thuần túy đạt được ở Màn 3 mà không có sàn và không có shrinkage nào cả. Ở mức tốt nhất, các bản vá không vượt qua Sharpe toàn dòng thời gian — chúng tái tạo nó. Và hàm mục tiêu robust được sửa hoàn toàn thậm chí còn không đạt đến đó: trên toàn bộ 600 seed nó dừng ở OOS 1.70 với một mức thoái hóa dư 0.17%, thấp hơn một chút so với 1.71 / 0% của Sharpe toàn phần — nó bị lấn át một cách yếu ớt bởi chỉ số đơn giản hơn. Một thiết lập giữa khiêm tốn, emin=0.10e_{\min}=0.10 với k=40k=40, đạt OOS 1.651% thoái hóa — tiện dụng nếu một chỉ số per-trade bị ép buộc lên bạn, nhưng không bao giờ là lý do để ưa thích nó.

Các con số chính xác phụ thuộc vào quy mô — hình dạng mới là kết quả. Các giá trị cụ thể emin=0.20e_{\min}=0.20, k=40k=40 khắc phục hoàn toàn thị trường này được điều chỉnh cho chính quá trình tạo dữ liệu này; trên một thị trường khác với tần suất giao dịch và độ dày đuôi khác nhau, cao nguyên nằm ở nơi khác. Cái tổng quát hóa được không phải là tọa độ mà là bề mặt: một sự nâng đơn điệu theo cả hai hướng, thoái hóa bị đẩy về không, một cao nguyên tại sự thật. Bạn tìm ra tọa độ của riêng mình bằng cách quét, chính xác như ở trên.

Kết hợp cả hai phương thuốc lại — hàm mục tiêu robust, sàn 0.20 cộng conf_k 40 — và quay lại seed 6. Cái bẫy đã tôn vinh θ=0.005\theta = 0.005, tám giao dịch, một Sharpe OOS toàn dòng thời gian là 0.13. Hàm mục tiêu robust thay vào đó chọn θ=0.979\theta = 0.979: mức tiếp xúc thị trường 0.66, 447 giao dịch, Sharpe hàng năm out-of-sample 1.77. θ=0.979\theta = 0.979 đó thấp hơn điểm tối ưu thực θ=1.04\theta = 1.04 đúng một điểm lưới, vì vậy nó khôi phục một ngưỡng gần-tối-ưu, có mức tiếp xúc tốt thay vì đáp trúng hồng tâm — Sharpe out-of-sample của seed đơn lẻ này (1.77) tình cờ trùng khớp với điểm tối ưu của quần thể. Cùng dữ liệu, cùng tìm kiếm, cùng 80 ngưỡng ứng viên. Chỉ có định nghĩa của "tốt nhất" thay đổi, và nó đã chuyển người chiến thắng từ một ảo ảnh tám-giao-dịch đứng yên sang lợi thế thực, có mức tiếp xúc tốt — mà, một cách đáng nói, chính là cùng ngưỡng mà Sharpe toàn dòng thời gian thuần túy chọn trên seed này.

Một lưu ý mà việc quét làm rõ ràng: conf_k một mình là không đủ trên thị trường này. Ở k=40k=40 không sàn, thoái hóa vẫn là 22.5% trên các seed — và cụ thể trên seed 6, conf_k một mình chọn θ=0.015\theta = 0.015, 35 giao dịch, một Sharpe out-of-sample là −0.06. Ba mươi lăm giao dịch sống sót qua một shrinkage 35/(35+40)0.4735/(35+40) \approx 0.47 với đủ điểm số còn lại để thắng. Sàn tiếp xúc là thứ đóng lại khoảng hở cuối cùng đó, bởi vì nó nhắm trực tiếp vào dấu hiệu thực sự của cái bẫy — sự đứng yên — thay vì tin tưởng số lượng giao dịch như một proxy cho nó.

Màn 6 — Bài học sâu sắc hơn: đo trên toàn bộ dòng thời gian

Hai cách chấm điểm cùng một chiến lược được đối chiếu: một đèn chiếu hẹp chỉ chiếu sáng vài nến mà một chiến lược đã giao dịch so với một đèn pha đo toàn bộ dòng thời gian bao gồm cả các đoạn đứng yên, minh họa rằng các hàm mục tiêu nhận-biết-tiếp-xúc không thể bị lợi dụng bởi các giao dịch may mắn hiếm hoi

Hãy lùi lại khỏi cách khắc phục và chú ý điều gì thực sự tách biệt các hàm mục tiêu an toàn khỏi cái bẫy. Đó không phải là sự tinh vi. PnL thô và Sharpe toàn dòng thời gian đơn giản hơn Sharpe per-trade, và chúng không bao giờ thoái hóa — 0% trên toàn bộ 600 seed — không sàn, không shrinkage, không cần điều chỉnh gì cả.

Ranh giới phân chia là một thuộc tính duy nhất: chỉ số đo cửa sổ nào? Sharpe per-trade chỉ đo các nến mà chiến lược chọn để đứng trên đó — một cửa sổ tự-chọn mà tìm kiếm có thể thu nhỏ tùy ý. Sharpe toàn dòng thời gian và tổng PnL đo toàn bộ dòng thời gian, bao gồm cả các nến đứng yên. Và bạn không thể làm cho một chỉ số toàn dòng thời gian lớn lên bằng cách giao dịch hiếm khi, bởi vì mỗi giờ bạn đứng yên là một giờ nằm trong mẫu số không kiếm được gì. Sàn tiếp xúc và conf_k, cuối cùng, chỉ là những cách để vá lại chỉ số per-trade với sự nhận-biết-tiếp-xúc mà các chỉ số toàn dòng thời gian có sẵn miễn phí — và việc quét đã cho chúng ta biết trần của bản vá đó: ở mức tốt nhất nó khớp với Sharpe toàn dòng thời gian (OOS 1.70 so với 1.71), không bao giờ vượt qua nó. Nếu bạn được tự do chọn cửa sổ, hãy chọn toàn bộ dòng thời gian và bỏ qua hoàn toàn bản vá.

Vì vậy nguyên tắc thiết kế, nói thẳng thắn:

Thiết kế hàm mục tiêu sao cho nó không thể bị lợi dụng bởi các giao dịch may mắn hiếm hoi. Bạn có ba công cụ, theo thứ tự ưu tiên tương đối:

  1. Đo trên toàn bộ dòng thời gian. Mặc định mà gần như không bao giờ nên rời bỏ. Sharpe toàn dòng thời gian và tổng lợi nhuận nhận-biết-tiếp-xúc theo cấu trúc — sự nhàn rỗi bị phạt tự động bởi vì các nến đứng yên được tính. Nếu bạn thấy mình đang báo cáo một chỉ số được tính trên "chỉ những nến chúng ta hoạt động," hãy dừng lại và hỏi tìm kiếm sẽ làm gì với sự tự do chọn những nến đó.
  2. Yêu cầu tiếp xúc. Nếu bạn phải sử dụng một chỉ số điều-kiện-theo-hoạt-động, hãy đặt sàn cho mức tiếp xúc để tìm kiếm không thể chọn một chiến lược hầu như không giao dịch. Đây là đòn bẩy đơn lẻ mạnh nhất chống lại cái bẫy cụ thể này.
  3. Thu nhỏ theo số lượng giao dịch. Chiết khấu bất kỳ tỷ lệ nào theo n/(n+k)n/(n+k) để một Sharpe dựa trên một nhúm quan sát chỉ kiếm được một phần nhỏ tín nhiệm so với một Sharpe dựa trên hàng nghìn. Đây là sự áp đặt Minimum Track Record Length ở cấp độ hàm mục tiêu: một con số từ ít quan sát là không đáng tin cậy (Màn 4), vì vậy một hàm mục tiêu trung thực định giá sự không đáng tin cậy đó vào bên trong thay vì tin tưởng một con người sẽ phát hiện ra nó sau này.

Không điều nào trong số này làm cho tìm kiếm thông minh hơn. Nó làm cho mục tiêu trung thực, để khi tìm kiếm làm chính xác những gì nó luôn làm — tìm giá trị lớn nhất — giá trị lớn nhất đó là một chiến lược bạn thực sự muốn.

Ghi Chú Trung Thực

Ba lưu ý, được nói thẳng thắn, bởi vì một nghiên cứu có kiểm soát chỉ giành được kết luận của nó bằng cách gọi tên các giới hạn của nó.

  • Thị trường là tổng hợp, và cố ý như vậy. Một tín hiệu chuẩn hóa, một lợi thế tuyến tính giới hạn trong s1|s|\le 1, nhiễu Student-tt(44) đuôi béo — được chọn vì ground truth có kiểm soát, không phải vì tính thực tế của thị trường. Chúng ta chỉ có thể chứng minh rằng một hàm mục tiêu chọn sai chiến lược bằng cách chạy nó trên dữ liệu nơi chúng ta biết chiến lược nào đúng. Thị trường thực là non-stationary, tự tương quan, và chuyển đổi chế độ. Đuôi béo là một thành phần thực tế mà chúng tôi đã giữ lại, nhưng — trái với một dự đoán ban đầu tự nhiên, và trái với một bản nháp trước đó của chính bài viết này — chúng không phải là thứ vận hành cái bẫy: một nhóm đối chứng nhiễu Gaussian (300 seed) thoái hóa 55.7% số lần so với 57.0% ở đây, với Sharpe out-of-sample 0.71 so với 0.70. Cái bẫy là một hiện tượng mẫu-nhỏ-cộng-lựa-chọn sống sót có hoặc không có đuôi nặng. Điều được giao ở đây là chẩn đoán và mô hình khắc phục, không phải một chiến lược và không phải một hằng số phổ quát.
  • Các giá trị khắc phục phụ thuộc vào quy mô. Sàn cụ thể emin=0.20e_{\min}=0.20 và shrinkage k=40k=40 đóng hoàn toàn cái bẫy được điều chỉnh phù hợp với chính quá trình tạo dữ liệu này — tần suất giao dịch của nó, độ dày đuôi của nó, kích thước lợi thế của nó. Trên dữ liệu khác cao nguyên sẽ dịch chuyển. Cái chuyển giao được là hình dạng của bề mặt quét (nâng đơn điệu ở cả hai núm vặn, thoái hóa về không, một cao nguyên tại sự thật) và phương pháp để tìm ra tọa độ của riêng bạn: quét cả hai và đọc bề mặt, đừng sao chép các con số.
  • conf_k là công trình của chúng tôi, không phải một ước lượng có tên. Shrinkage theo số lượng giao dịch SR^n/(n+k)\widehat{SR}\cdot n/(n+k) là một công cụ kiểu Bayesian precision-weighted / empirical-Bayes mà chúng tôi xây dựng cho vấn đề này; cơ sở lý luận của nó được đặt nền trên kết quả sai số chuẩn Lo/Mertens đã được xác minh và MinTRL của Bailey–López de Prado, và người họ hàng có tên gần nhất của nó là System Quality Number của van Tharp (Ntrade/σtrade\sqrt{N}\cdot \overline{\text{trade}}/\sigma_{\text{trade}}, một dạng hàm khác), nhưng chúng tôi không tuyên bố rằng bản thân n/(n+k)n/(n+k) xuất hiện dưới một cái tên trong tài liệu. Các phương thuốc đồng hành của nó — sàn tiếp xúc, đo toàn dòng thời gian — là thực hành chuẩn mực được phát biểu chính xác. Và hãy chú ý những hàm mục tiêu nào đã an toàn ở đây: PnL thô và Sharpe toàn dòng thời gian không bao giờ cần sửa chữa, bởi vì chúng đã nhận-biết-tiếp-xúc ngay từ đầu — đến mức đặt sàn cho Sharpe toàn dòng thời gian rút gọn lại thành chính Sharpe toàn dòng thời gian, người chiến thắng của nó đã vượt qua bất kỳ sàn hợp lý nào. Cái bẫy cụ thể là Sharpe per-trade / active — và ngay cả hàm mục tiêu per-trade được sửa hoàn toàn cũng chỉ khớp với Sharpe toàn dòng thời gian (OOS 1.70 so với 1.71), không bao giờ vượt qua nó. Bài học chính không phải là cách khắc phục; đó là đo trên toàn bộ dòng thời gian ngay từ đầu.

Điểm Chính

  1. Hàm mục tiêu là quyết định, không phải một thủ tục hình thức. Một tìm kiếm không tìm ra "một chiến lược tốt" — nó tìm ra bộ tối đa hóa của bất kỳ con số vô hướng nào bạn trao cho nó, và các con số vô hướng khác nhau chọn ra những chiến lược hoàn toàn khác nhau trên cùng một dữ liệu. Chọn hàm mục tiêu chính là chọn chiến lược; mọi thứ ở downstream chỉ là sổ sách kế toán. Đó chính là định luật Goodhart: khoảnh khắc chỉ số của bạn trở thành mục tiêu của tìm kiếm, tìm kiếm sẽ khai thác mọi khoảng hở giữa nó và điều bạn thực sự muốn nói.
  2. Sharpe per-trade là một cái bẫy. Được đo chỉ trên các nến mà một chiến lược giao dịch, nó được tối đa hóa bằng cách giao dịch càng hiếm càng tốt — càng ít quan sát, càng dễ để vài chuyển động may mắn làm phình to tỷ lệ (một nhóm đối chứng Gaussian xác nhận đuôi béo không cần thiết; đó là một hiệu ứng mẫu-nhỏ-cộng-lựa-chọn). Trên 600 seed nó chọn một vé số có mức tiếp xúc dưới 5% trong 56% số đó và thoái hóa trong 57%; lựa chọn thoái hóa điển hình có Sharpe per-trade in-sample trung bình là 4.58. Trên một seed cố ý được chọn rõ rệt, nó đã tôn vinh một chiến lược tám-giao-dịch, tiếp xúc 0.4% với Sharpe per-trade in-sample 21.09 sụp đổ xuống Sharpe out-of-sample toàn dòng thời gian 0.13. Một tỷ lệ được xây dựng trên tám quan sát có sai số chuẩn bậc ±7.7 hàng năm (Màn 4) — nó chưa bao giờ là thông tin.
  3. Các hàm mục tiêu nhận-biết-tiếp-xúc tự nhiên an toàn. PnL thô và Sharpe toàn dòng thời gian không bao giờ thoái hóa (0%), bởi vì chúng đo toàn bộ dòng thời gian và sự nhàn rỗi bị phạt tự động. Bạn không thể lợi dụng một chỉ số toàn dòng thời gian bằng cách giao dịch hiếm khi. Khiếm khuyết duy nhất của PnL thô là thiên lệch ngược lại — nó tiếp xúc quá mức (mức tiếp xúc trung bình 0.859, OOS 1.61 so với mức thực 1.77), trôi θ\theta qua điểm tối ưu để ở trong thị trường nhiều hơn.
  4. Các cách khắc phục hoạt động — nhưng chúng chỉ đưa bạn trở lại Sharpe toàn dòng thời gian. Một sàn tiếp xúc và một shrinkage theo số lượng giao dịch (conf_k) mỗi cái độc lập nâng Sharpe out-of-sample và đẩy thoái hóa về không; cùng nhau chúng đạt đến một cao nguyên. Nhưng cao nguyên đó chính là Sharpe toàn dòng thời gian: thoái hóa giảm từ 59.5% tại (emin,k)=(0,0)(e_{\min},k)=(0,0) xuống 0%emin=0.20e_{\min}=0.20 và Sharpe OOS leo từ 0.66 lên 1.71 — con số chính xác mà Sharpe toàn phần thuần túy đạt được không cần trợ giúp, và hàm mục tiêu robust được sửa hoàn toàn thực ra dừng thấp hơn một chút (OOS 1.70, thoái hóa 0.17%: bị lấn át yếu). Trên seed 6 hàm mục tiêu robust khôi phục một ngưỡng gần-tối-ưu, có mức tiếp xúc tốt (θ=0.979\theta = 0.979, thấp hơn mức thực 1.041.04 đúng một điểm lưới; 447 giao dịch; Sharpe OOS 1.77). Hãy coi conf_k như một phương án dự phòng cho khi một chỉ số per-trade bị ép buộc lên bạn, không phải như một nâng cấp so với việc đo toàn bộ dòng thời gian. Tọa độ chính xác phụ thuộc vào quy mô; hình dạng của bề mặt là kết quả có thể chuyển giao.
  5. Thiết kế hàm mục tiêu sao cho nó không thể bị lợi dụng bởi các giao dịch may mắn hiếm hoi. Theo thứ tự ưu tiên: đo trên toàn bộ dòng thời gian (mặc định), yêu cầu tiếp xúc (đòn bẩy đơn lẻ mạnh nhất), thu nhỏ theo số lượng giao dịch (Minimum Track Record Length ở cấp độ hàm mục tiêu). Không điều nào trong số này làm cho tìm kiếm khôn ngoan hơn — chúng làm cho mục tiêu trung thực, để giá trị lớn nhất mà tìm kiếm chắc chắn tìm ra là một chiến lược bạn thực sự sẽ giao dịch.

Một tìm kiếm tham số là một vị thần đèn ngoan ngoãn. Nó ban cho chính xác điều ước bạn diễn đạt, không phải điều bạn thực sự muốn nói — và "tối đa hóa chỉ số này" chính là điều ước đó. Diễn đạt nó như một Sharpe per-trade và nó sẽ triệu hồi tám giao dịch may mắn và gọi chúng là một gia tài. Diễn đạt nó sao cho việc đứng yên bị trừng phạt và một nhúm giao dịch chỉ kiếm được một nhúm tín nhiệm, và cùng vị thần đèn đó, trên cùng dữ liệu, trao cho bạn lợi thế thực. Chiến lược bạn triển khai đã được chọn ngay khoảnh khắc bạn gõ hàm mục tiêu. Hãy chọn nó một cách có chủ đích.

Thí nghiệm đầy đủ — thị trường tổng hợp, sáu hàm mục tiêu, Monte Carlo 600-seed, và bề mặt quét-khắc-phục, mọi con số đều có thể tái tạo được từ một script tất định duy nhất — nằm trong bài báo đồng hành tại objective-design.marketmaker.cc, với mã nguồn và dữ liệu tại github.com/suenot/objective-design-degeneracy.

Đây là một mặt trận trong cùng cuộc chiến mà các nghiên cứu khác của chúng tôi chiến đấu từ những góc độ khác nhau. Deflated Sharpe Ratio định giá người chiến thắng của một tìm kiếm sau multiple testing — trong khi bài viết này hỏi liệu hàm mục tiêu có chọn đúng chiến lược hay không, DSR hỏi liệu chiến lược nó chọn có đánh bại những gì may mắn đơn thuần sẽ tạo ra hay không. Nghiên cứu sắp tới về xác suất backtest overfitting tấn công cùng một thiên lệch lựa chọn từ phía lấy mẫu lại, chấm điểm quy trình thay vì người chiến thắng. Và phân loại look-ahead bias liệt kê nhà sản xuất Sharpe giả vĩ đại khác — một rò rỉ từ tương lai — thứ tạo ra triệu chứng giống hệt (một backtest lộng lẫy chết khi chạy thật) thông qua một cơ chế hoàn toàn khác. Thiết kế hàm mục tiêu, khử lạm phát, xác suất overfitting, look-ahead: bốn cái tên cho một ngành kỷ luật — không bị lừa dối bởi chính backtest của bạn.

Tuyên bố miễn trừ trách nhiệm: Thông tin được cung cấp trong bài viết này chỉ nhằm mục đích giáo dục và thông tin, không cấu thành lời khuyên về tài chính, đầu tư hoặc giao dịch. Giao dịch tiền mã hóa tiềm ẩn rủi ro thua lỗ đáng kể.

Tác Giả

Eugen Soloviov
Eugen Soloviov

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.

Newsletter

Đi Trước Thị Trường

Đăng ký nhận bản tin của chúng tôi để có những thông tin chuyên sâu độc quyền về AI trading, phân tích thị trường và các cập nhật nền tảng.

Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất kỳ lúc nào.