AutoML cho Quy trình Giao dịch Có hệ thống
Blog này đã dành nhiều thời gian về cách tìm kiếm: sử dụng bộ lấy mẫu nào và khi nào (sự giao nhau là chi phí eval), cách định giá tìm kiếm bạn đã thực hiện (Tỷ lệ Sharpe giảm phát), cách tự chấm điểm cho quy trình lựa chọn (PBO) và nơi toàn bộ bộ máy đó hạ cánh một cách trung thực ([không có lợi thế mạnh mẽ](/en/blog/post/honest- Negative-no-robust-edge)).
Những gì nó chưa bao giờ đề cập đến là những gì bạn tìm kiếm trên. Tất cả các bài viết đó đều lấy bộ tính năng và nhóm chiến lược như đã cho và tối ưu hóa các tham số bên trong nó. AutoML tấn công lớp trên - nó tự động hóa việc xây dựng các ứng viên. Ba phần trong số đó không xuất hiện ở bất kỳ nơi nào khác trên blog này:
- Trích xuất tính năng tự động — tsfresh biến một chuỗi giá thành ~794 tính năng được đặc trưng theo thống kê và các công cụ tính năng tổng hợp các tính năng trên các bảng thị trường liên quan thông qua Tổng hợp tính năng sâu.
- AutoML nhận biết ngân sách — Tối ưu hóa tiết kiệm chi phí của FLAML, tìm ra mô hình tốt nhất trong ngân sách điện toán thay vì bất kể chi phí.
- Nhà máy alpha công thức — 101 Alpha công thức của WorldQuant dưới dạng ngữ pháp toán tử tổng hợp mà máy có thể liệt kê.
Mọi thứ khác - hàm mục tiêu, sơ đồ xác nhận, hiệu chỉnh nhiều lần kiểm tra - đã được đo lường ở nơi khác ở đây, vì vậy bài viết này liên kết thay vì dạy lại. Điều đó quan trọng hơn bình thường, bởi vì AutoML làm cho số lượng thử nghiệm bùng nổ và số lượng thử nghiệm chính xác là nội dung còn lại của vòng cung.

AutoML tự động hóa những gì
AutoML không phải là một thuật toán đơn lẻ. Đó là một nhóm các kỹ thuật tự động hóa các giai đoạn khác nhau của quy trình:
| Sân khấu | Cách tiếp cận thủ công | Phương pháp tiếp cận AutoML |
|---|---|---|
| Kỹ thuật tính năng | Chỉ số thủ công chuyên gia tên miền | Trích xuất tự động (tsfresh, Featuretools) |
| Lựa chọn tính năng | Phân tích tương quan, trực giác | Kiểm tra giả thuyết thống kê, SHAP |
| Lựa chọn mô hình | Hãy thử 2-3 mẫu | Tìm kiếm trên hàng chục người học |
| Điều chỉnh siêu tham số | Tìm kiếm dạng lưới, tinh chỉnh thủ công | Tìm kiếm Bayesian / tiết kiệm chi phí (Optuna, FLAML) |
| Thiết kế kiến trúc | Cấu trúc liên kết mạng thần kinh cố định | Tìm kiếm Kiến trúc Thần kinh (NAS) |
| Xây dựng quần thể | Xếp chồng thủ công | Lựa chọn nhóm tự động |
Tiền đề là trong giao dịch có hệ thống, không gian ứng viên là rất lớn - một chuỗi OHLCV duy nhất tạo ra hàng trăm tính năng kỹ thuật và nhiều tài sản, dữ liệu sổ đặt hàng và các nguồn thay thế làm cho nó trở thành tổ hợp. Tiền đề cũng là mối nguy hiểm: mỗi ứng cử viên là một thử nghiệm, và thử nghiệm là thứ tạo ra những khám phá sai lầm.
Một điểm cụ thể của AutoML về mục tiêu: số liệu mà tìm kiếm tối đa hóa phải là số liệu tài chính, vì tìm kiếm sẽ tối ưu hóa chính xác những gì bạn đã viết ra chứ không phải ý bạn. Bạn chọn vô hướng nào sẽ âm thầm chọn chiến lược của bạn — xem Thiết kế chức năng mục tiêu, trong đó Sharpe ngây thơ trên mỗi giao dịch giành được giải xổ số có tỷ lệ tiếp xúc dưới 5% với 56% trong số 600 hạt giống và đăng Sharpe trong mẫu là 21 giảm xuống còn 0,13 trên mẫu. Đưa số liệu tài chính vào công cụ ghi điểm AutoML ngay từ đầu; không tối ưu hóa roc_auc và hy vọng nó chuyển giao.
Kỹ thuật tính năng tự động
Kỹ thuật tính năng là nơi hầu hết các alpha sinh sống. Dữ liệu giá thô là như nhau cho tất cả mọi người. Việc chuyển đổi dữ liệu đó thành tín hiệu dự đoán là điều giúp phân biệt các chiến lược sinh lời với nhiễu.

tsfresh: Từ dòng giá một giá đến hơn 800 tính năng
tsfresh (Trích xuất tính năng chuỗi thời gian dựa trên các thử nghiệm giả thuyết có thể mở rộng) được xây dựng có mục đích để trích xuất tính năng chuỗi thời gian. Nó tính toán 63 phương pháp mô tả đặc tính mở rộng thành ~794 tính năng theo mặc định, bao gồm:
- Những khoảnh khắc thống kê (trung bình, phương sai, độ lệch, độ nhọn)
- Tự tương quan ở nhiều độ trễ
- Hệ số Fourier và năng lượng quang phổ
- Các biện pháp phức tạp (entropy gần đúng, entropy mẫu)
- Đặc trưng phi tuyến (hệ số Friedrich, điểm cố định Langevin max)
- Thay đổi lượng tử và số lượng phạm vi
Đối với dữ liệu tài chính, điều này có nghĩa là một chuỗi giá duy nhất sẽ tạo ra hàng trăm tính năng ứng cử viên — nhiều động lực nắm bắt mà kỹ thuật tính năng thủ công sẽ bỏ lỡ. Đây là một cách tiếp cận khác biệt đáng kể so với các bộ tính năng được tạo thủ công, có nguồn gốc từ miền được sử dụng trong [mô hình trải rộng](/en/blog/post/ Spread-modeling-machine-learning) và DeepLOB: ở đó con người quyết định rằng sự mất cân bằng trong sổ đặt hàng là quan trọng; ở đây một thư viện liệt kê mọi thứ và để việc kiểm tra giả thuyết quyết định.
import pandas as pd
import numpy as np
from tsfresh import extract_features, select_features
from tsfresh.utilities.dataframe_functions import impute
def prepare_rolling_windows(df: pd.DataFrame, window_size: int = 20) -> pd.DataFrame:
"""Convert OHLCV DataFrame into rolling windows for tsfresh."""
records = []
for i in range(window_size, len(df)):
window = df.iloc[i - window_size:i].copy()
window["id"] = i # window identifier
window["time"] = range(window_size)
records.append(window[["id", "time", "close", "volume", "high", "low"]])
return pd.concat(records, ignore_index=True)
df_ohlcv = pd.read_csv("btc_1h.csv", parse_dates=["timestamp"])
df_rolled = prepare_rolling_windows(df_ohlcv, window_size=24)
features = extract_features(
df_rolled,
column_id="id",
column_sort="time",
n_jobs=8, # parallel extraction
disable_progressbar=False,
)
impute(features)
y = df_ohlcv["close"].pct_change(4).shift(-4).iloc[24:].reset_index(drop=True)
y_binary = (y > 0).astype(int)
features_selected = select_features(features, y_binary, fdr_level=0.05)
print(f"Selected {features_selected.shape[1]} features from {features.shape[1]}")
các select_features áp dụng quy trình Stewamini-Yekutieli để kiểm soát tỷ lệ phát hiện sai trên toàn bộ pin tính năng — đó là bản năng đúng đắn và bản năng tương tự mà Bài viết Deflat Sharpe áp dụng cho tìm kiếm chiến lược. Lưu ý những gì nó không làm: Kiểm soát FDR ở bước lựa chọn tính năng không nói gì về chi phí dùng thử của việc tìm kiếm mô hình theo sau nó. Đó là hai bội số riêng biệt và cả hai đều phải được trả.
Công cụ tính năng: Tổng hợp tính năng sâu
Trong khi tsfresh tập trung vào mô tả đặc điểm chuỗi thời gian, Featuretools vượt trội về kỹ thuật tính năng quan hệ - xây dựng các tính năng bằng cách kết hợp các hoạt động nguyên thủy trên các bảng có liên quan.
Đối với giao dịch, điều này rất hữu ích khi bạn có dữ liệu nhiều bảng: lịch sử giao dịch, ảnh chụp nhanh sổ lệnh, tỷ lệ cấp vốn và số liệu trên chuỗi. Featuretools áp dụng Tổng hợp tính năng sâu (DFS), ngăn xếp các nguyên hàm chuyển đổi và tổng hợp:
import featuretools as ft
es = ft.EntitySet(id="crypto_trading")
es = es.add_dataframe(
dataframe_name="candles",
dataframe=df_candles,
index="candle_id",
time_index="timestamp",
)
es = es.add_dataframe(
dataframe_name="orderbook",
dataframe=df_orderbook,
index="snapshot_id",
time_index="timestamp",
)
es = es.add_dataframe(
dataframe_name="funding",
dataframe=df_funding,
index="funding_id",
time_index="timestamp",
)
feature_matrix, feature_defs = ft.dfs(
entityset=es,
target_dataframe_name="candles",
agg_primitives=["mean", "std", "max", "min", "skew", "trend"],
trans_primitives=["percentile", "diff", "cum_mean"],
max_depth=2, # compose up to 2 primitives deep
features_only=False,
)
print(f"Generated {len(feature_defs)} features via DFS")
các time_index khai báo có khả năng chịu tải: đó là điều cho phép Featuretools tính toán các tập hợp chỉ sử dụng các hàng tồn tại ở điểm giới hạn. Nếu hiểu sai và DFS sẽ vui vẻ xây dựng một tính năng trong tương lai — phiên bản dữ liệu quan hệ của các rò rỉ được liệt kê trong phân loại thiên vị nhìn về phía trước.
Sự kết hợp giữa tsfresh (mô tả chuỗi thời gian) và Featuretools (tổng hợp quan hệ) mang đến cho bạn một nhà máy tính năng tạo ra hàng nghìn tín hiệu ứng cử viên từ dữ liệu thị trường thô mà không cần mã hóa chỉ báo thủ công.
AutoML nhận biết ngân sách: FLAML
Chúng tôi giả sử Công cụ ước tính Parzen có cấu trúc cây và Optuna làm nền — đạo hàm, so sánh mẫu và điểm chuẩn nằm trong Tối ưu hóa tọa độ gốc so với tối ưu hóa Bayesian. Về công cụ lấy mẫu mà cần hướng tới, phép đo riêng của blog này là tài liệu tham khảo chứ không phải là câu trả lời dân gian: sự giao thoa bị chi phối bởi chi phí đánh giá, chứ không phải sự thông minh của thuật toán - khi backtest gần như miễn phí, Sobol được xáo trộn sẽ giành chiến thắng về thông lượng (~2.830 cfg/s so với ~154 đối với TPE) và chỉ những đánh giá đắt tiền mới khiến hiệu suất mẫu phải trả giá (Ngẫu nhiên so với Thông minh) Tìm kiếm).

Việc đóng khung đó là điều làm cho FLAML trở thành một trục khác chứ không phải là một công cụ lấy mẫu cạnh tranh. Optuna hỏi mẫu tiếp theo ở đâu; FLAML (Fast Lightweight AutoML) hỏi tôi có thể đủ khả năng lấy mẫu những gì. Nó tối ưu hóa để có mô hình tốt nhất trong một khoảng thời gian hoặc tính toán ngân sách bằng cách sử dụng CFO (Tối ưu hóa chi phí-tiết kiệm), ưu tiên sớm các cấu hình giá rẻ để đánh giá và chỉ tăng cấp khi lợi nhuận cận biên ước tính phù hợp với mức chi tiêu.
from flaml import AutoML
from sklearn.metrics import make_scorer
import numpy as np
def sharpe_score(y_true, y_pred):
"""Custom scorer: Sharpe ratio of predicted signals."""
signal = np.sign(y_pred - 0.5)
returns = signal * y_true # y_true contains forward returns
if returns.std() == 0:
return 0.0
return np.sqrt(252) * returns.mean() / returns.std()
sharpe_scorer = make_scorer(sharpe_score, greater_is_better=True)
automl = AutoML()
automl_settings = {
"time_budget": 300, # 5 minutes
"metric": sharpe_scorer, # optimize the financial objective, not accuracy
"task": "classification",
"estimator_list": [
"lgbm", "xgboost", "rf", "extra_tree", "catboost",
],
"eval_method": "cv",
"split_type": "time", # time series split (no future leakage)
"n_splits": 5,
"log_file_name": "flaml_trading.log",
"seed": 42,
}
automl.fit(
X_train=X_train,
y_train=y_train,
**automl_settings,
)
print(f"Best model: {automl.best_estimator}")
print(f"Best config: {automl.best_config}")
from flaml.data import get_output_from_log
time_history, best_valid_loss_history, valid_loss_history, config_history, metric_history = \
get_output_from_log(filename="flaml_trading.log", time_budget=300)
Lợi thế của FLAML đối với giao dịch là tính toán phân bổ trên các loại mô hình không đồng nhất. Nếu cấu hình LightGBM đánh giá nhanh hơn 10 lần so với CatBoost, thì FLAML sẽ sớm khám phá nhiều LightGBM hơn và chỉ chuyển đổi khi ước tính mức cải thiện cận biên phù hợp với chi phí. Đó là cái nhìn sâu sắc về chế độ giá rẻ từ bài báo chéo, được khái quát hóa: thông lượng là thuật ngữ hạng nhất trong ngân sách tìm kiếm, không phải là chi tiết triển khai.
Nhật ký quỹ đạo là phần đáng được lưu giữ. get_output_from_log cung cấp cho bạn lịch sử cấu hình đầy đủ, đó là số lần dùng thử của bạn — và số lần dùng thử là thông tin đầu vào cho mọi lần giảm phát mà bạn sắp nợ.
Kiến trúc thần kinh Tìm kiếm mô hình giao dịch
Tìm kiếm kiến trúc thần kinh tự động hóa việc thiết kế các cấu trúc liên kết mạng thay vì điều chỉnh một cấu trúc cố định. Sự lựa chọn kiến trúc cho chuỗi tài chính thực sự không rõ ràng — không cố định, tín hiệu trên tạp âm thấp, tần số hỗn hợp và sự phụ thuộc kéo dài hàng phút đến hàng tháng, tất cả đều kéo theo các hướng khác nhau — nhưng động lực đó đã được tranh luận cụ thể ở nơi khác: xem Temporal Fusion Transformer khi TFT đánh bại LSTM đánh bại vanilla Transformer và DeepLOB trên Sự cân bằng giữa CNN+Inception+LSTM, với những gì mà kiến trúc cố định được thiết kế thủ công cẩn thận đã đạt được. NAS là lập luận cho rằng sự lựa chọn này nên được tìm kiếm.
Nghiên cứu về NAS tiến hóa thần kinh để dự đoán lợi nhuận chứng khoán báo cáo rằng RNN được phát triển thông qua EXAMM (Evolutionary eXploration of Augmenting Memory Models) vượt trội so với DJI và S&P 500 ở cả thị trường gấu (2022) và bull (2023) bằng cách sử dụng các chiến lược dài hạn đơn giản. Hãy coi đó là tuyên bố của bên thứ ba, không phải là kết quả được sao chép ở đây - đây là số liệu được tìm kiếm tốt nhất và không có báo cáo giảm phát.
Không gian tìm kiếm NAS để giao dịch
Không gian tìm kiếm NAS thực tế cho các mô hình giao dịch bao gồm:
Search Space:
- Cell types: {LSTM, GRU, Temporal Conv, Transformer block, Linear}
- Number of layers: [1, 8]
- Hidden dimensions: {32, 64, 128, 256}
- Attention heads (if Transformer): {2, 4, 8}
- Dropout rate: [0.0, 0.5]
- Skip connections: {True, False}
- Normalization: {BatchNorm, LayerNorm, None}
- Activation: {ReLU, GELU, SiLU, Mish}
- Lookback window: {20, 60, 120, 252}
Với NNI (Neural Network Intelligence) của Microsoft, bạn có thể xác định và tìm kiếm không gian này:
import nni
from nni.nas.nn.pytorch import LayerChoice, InputChoice
import torch
import torch.nn as nn
class TradingNASModel(nn.Module):
"""NAS-searchable model for financial time series."""
def __init__(self, input_dim: int, seq_len: int):
super().__init__()
self.input_proj = nn.Linear(input_dim, 128)
self.temporal_block = LayerChoice([
nn.LSTM(128, 128, num_layers=2, batch_first=True, dropout=0.1),
nn.GRU(128, 128, num_layers=2, batch_first=True, dropout=0.1),
nn.TransformerEncoder(
nn.TransformerEncoderLayer(d_model=128, nhead=4, batch_first=True),
num_layers=2,
),
], label="temporal_cell")
self.head = LayerChoice([
nn.Sequential(nn.Linear(128, 64), nn.ReLU(), nn.Linear(64, 1)),
nn.Sequential(nn.Linear(128, 32), nn.GELU(), nn.Linear(32, 1)),
nn.Linear(128, 1),
], label="prediction_head")
self.skip = InputChoice(n_candidates=2, n_chosen=1, label="skip_conn")
self.skip_proj = nn.Linear(input_dim, 128)
def forward(self, x: torch.Tensor) -> torch.Tensor:
h = self.input_proj(x)
out = self.temporal_block(h)
if isinstance(out, tuple):
out = out[0]
last = out[:, -1, :]
skip_val = self.skip_proj(x[:, -1, :])
last = self.skip([last, last + skip_val])
return self.head(last).squeeze(-1)
Thuật toán tìm kiếm (ENAS, DARTS hoặc tiến hóa) đánh giá các kiến trúc ứng viên trên một bộ xác thực bằng cách sử dụng mục tiêu tài chính, sau đó thu hẹp dần về các cấu trúc liên kết hiệu suất cao. Lưu ý sự bất cân xứng về chi phí so với mọi thứ khác trong bài viết này: NAS nằm ở vị trí đắt đỏ nhất của trục đánh giá-chi phí, đây là chế độ duy nhất mà các công cụ lấy mẫu hiệu quả mẫu và việc cắt tỉa đa độ trung thực thực sự tự chi trả.
Phương pháp tiếp cận nhà máy WorldQuant Alpha
Cách tiếp cận khám phá alpha của WorldQuant là triển khai các nguyên tắc AutoML ở quy mô công nghiệp nhất trong tài chính. Được thành lập bởi Igor Tulchinsky, WorldQuant vận hành cái mà họ gọi là "nhà máy alpha" — một quy trình có hệ thống để tạo, thử nghiệm và kết hợp hàng triệu tín hiệu dự đoán.
Triết học: Thế hệ Alpha theo hàm mũ và sự điều chỉnh của nó
WorldQuant đặt mục tiêu vào năm 2010 là đạt được một triệu alpha, vào thời điểm mà họ chỉ sản xuất được vài nghìn alpha mỗi năm. Họ đã đạt được mục tiêu đó vào năm 2016. Triết lý dựa trên quy luật cơ bản của quản lý tích cực:
Ở đâu là tỷ lệ thông tin, hệ số thông tin và chiều rộng - số lượng cược độc lập. Mỗi cá nhân là một yếu tố dự báo yếu; khẳng định là việc kết hợp đủ những cái có mối tương quan yếu sẽ kết hợp các IC nhỏ thành một khoản lợi nhuận được điều chỉnh theo rủi ro có ý nghĩa.
Sự điều chỉnh tạo ra hoặc phá vỡ điều này và cách đọc công thức ngây thơ ẩn giấu: bề rộng không phải là số lần thử. việc đếm các lần đặt cược độc lập và các bảng chữ cái được tạo ra không độc lập — chúng được tạo thành từ cùng một toán tử trên cùng các trường giá và khối lượng, vì vậy chúng kế thừa cấu trúc tương quan của nhau. Blog này đã đo lường hiệu ứng trực tiếp trong Tương quan tín hiệu: độ rộng hiệu quả là và với hệ số tương quan mật mã điển hình , mười tín hiệu có giá trị khoảng 3,3 tín hiệu độc lập. các thuật ngữ không tăng theo số lượng bảng chữ cái bạn đã tạo; nó phát triển tùy theo số lượng không tương quan còn sống sót. Một triệu bảng chữ cái tương quan mua cho bạn ít hơn nhiều so với công thức quảng cáo.
Đây là lý do tại sao bước 3 bên dưới — loại bỏ tương quan với thư viện hiện có — không phải là bước vệ sinh trong nhà máy alpha. Đây là bước tạo ra chiều rộng ngay từ đầu.
101 bảng chữ cái công thức
Bài báo "101 bảng chữ cái công thức" của Kakushadze (liên kết với nghiên cứu WorldQuant) đã xuất bản một tập hợp các biểu thức alpha công thức - biểu thức toán học về giá, khối lượng và dữ liệu cơ bản:
Alpha#1: (rank(Ts_ArgMax(SignedPower(((returns < 0) ? stddev(returns, 20)
: close), 2.), 5)) - 0.5)
Alpha#7: ((adv20 < volume) ? ((-1 * ts_rank(abs(delta(close, 7)), 60))
* sign(delta(close, 7))) : (-1 * 1))
Alpha#42: (rank(vwap - close) / rank(vwap + close))
Điều khiến AutoML trở nên thú vị vì nó là một ngữ pháp. Các chữ cái là thành phần của một tập toán tử nhỏ (rank, delta, ts_rank, stddev, correlation, signedpower) trên một tập trường nhỏ (close, volume, vwap, returns, adv20). Ngữ pháp là vô số, có nghĩa là không gian tìm kiếm có thể được tạo bằng máy theo cách "nghĩ ra một tính năng hay" thì không. Một hệ thống AutoML có thể:
- Tạo biểu thức ứng viên bằng cách kết hợp các toán tử trên các trường dữ liệu
- Đánh giá IC, doanh thu và mức giảm của từng biểu thức
- Bộ lọc cho các biểu thức vượt qua thử nghiệm thống kê và không tương quan đủ với thư viện hiện có
- Kết hợp những người sống sót vào một danh mục đầu tư
Lưu ý rằng bước 1 và 2 là những bước dễ dàng và bước 3 là giá trị - xem phần điều chỉnh độ rộng ở trên.
Khám phá Alpha nâng cao LLM
WorldQuant đã bắt đầu tích hợp các mô hình ngôn ngữ lớn vào nhà máy alpha. Như đã đưa tin trên báo chí tài chính, công ty đang khám phá cách LLM có thể "chuyển đổi và khám phá các bảng chữ cái trên các lĩnh vực khác nhau" - tạo ra các cách diễn đạt mới, dịch các tài liệu nghiên cứu thành các giả thuyết có thể kiểm chứng và khắc phục các mối quan hệ giữa các miền mà tìm kiếm liệt kê thuần túy sẽ bỏ lỡ. Đây là một cơ chế khác với việc trích xuất tín hiệu từ văn bản mà blog này đề cập đến trong LLM Alpha Mining on Earnings Calls; ở đây LLM viết công thức, không phải tính năng.
Xây dựng nhà máy Alpha Mini của riêng bạn
Đây là một nhà máy alpha nhỏ gọn nhưng đầy đủ chức năng về ngữ pháp toán tử:
import itertools
from dataclasses import dataclass
from typing import Callable, List
import pandas as pd
import numpy as np
from scipy.stats import spearmanr
@dataclass
class Alpha:
name: str
expression: Callable[[pd.DataFrame], pd.Series]
ic: float = 0.0
turnover: float = 0.0
sharpe: float = 0.0
def ts_rank(series: pd.Series, window: int) -> pd.Series:
return series.rolling(window).apply(lambda x: pd.Series(x).rank().iloc[-1] / len(x))
def ts_delta(series: pd.Series, period: int) -> pd.Series:
return series.diff(period)
def ts_std(series: pd.Series, window: int) -> pd.Series:
return series.rolling(window).std()
def cs_rank(series: pd.Series) -> pd.Series:
return series.rank(pct=True)
def ts_mean(series: pd.Series, window: int) -> pd.Series:
return series.rolling(window).mean()
ALPHA_TEMPLATES = [
("momentum_{w}",
lambda df, w: cs_rank(ts_delta(df["close"], w))),
("mean_reversion_{w}",
lambda df, w: -cs_rank(df["close"] / ts_mean(df["close"], w) - 1)),
("vol_surprise_{w}",
lambda df, w: cs_rank(df["volume"] / ts_mean(df["volume"], w))),
("price_vol_divergence_{w}",
lambda df, w: cs_rank(ts_delta(df["close"], w)) * -cs_rank(ts_delta(df["volume"], w))),
("volatility_rank_{w}",
lambda df, w: -cs_rank(ts_std(df["close"].pct_change(), w))),
("high_low_range_{w}",
lambda df, w: cs_rank(ts_mean(df["high"] - df["low"], w) / df["close"])),
]
WINDOWS = [5, 10, 20, 60, 120]
def generate_alphas(df: pd.DataFrame, forward_returns: pd.Series) -> List[Alpha]:
"""Generate and evaluate all alpha candidates."""
alphas = []
for (name_tpl, expr_fn), window in itertools.product(ALPHA_TEMPLATES, WINDOWS):
name = name_tpl.format(w=window)
try:
signal = expr_fn(df, window)
signal = signal.replace([np.inf, -np.inf], np.nan)
valid = signal.notna() & forward_returns.notna()
if valid.sum() < 100:
continue
ic, _ = spearmanr(signal[valid], forward_returns[valid])
turnover = signal.diff().abs().mean()
ret = (signal * forward_returns).dropna()
sharpe = np.sqrt(252) * ret.mean() / (ret.std() + 1e-9)
alphas.append(Alpha(
name=name,
expression=lambda df, fn=expr_fn, w=window: fn(df, w),
ic=ic,
turnover=turnover,
sharpe=sharpe,
))
except Exception:
continue
alphas.sort(key=lambda a: abs(a.ic), reverse=True)
return alphas
Sáu mẫu trên năm cửa sổ là một lần quét 30 cấu hình. Báo cáo mà nó tạo ra có dạng sơ đồ — các trường là những gì nhà máy phát ra và không có con số nào được điền vào vì không có con số nào được đo ở đây:
SCHEMATIC — illustrative format only, not a measurement
Generated <N> alphas from <N> candidate configurations
Top by |IC|:
<alpha_name> IC=<±0.0xxx> Sharpe=<±x.xxx> Turnover=<0.0xxx>
...
Sharpe thô của alpha hàng đầu trong quá trình quét 30 cấu hình không phải là kết quả — đó là tối đa 30 lần rút và trên 1.000 chiến lược không cạnh, Sharpe hàng năm tốt nhất đạt trung bình 1,63 trong khi thử nghiệm ngây thơ tuyên bố một khám phá 100% thời gian (Tỷ lệ Sharpe bị lệch). Do đó, sản phẩm trung thực mà nhà máy có thể phân phối không phải là "chúng tôi đã tìm thấy bản alpha" mà là có bao nhiêu bản alpha sống sót sau tình trạng giảm phát: phân phối IC, số lần dùng thử, DSR của người chiến thắng so với số đó và PBO của lựa chọn. Đó là phép đo mà phần này vẫn còn nợ.
Lan can: Những gì bạn đã nợ
AutoML khuếch đại khả năng phát hiện và trang bị quá mức ở mức độ ngang nhau và nó làm được điều đó ở số lần thử khi sự khác biệt không còn nhỏ nữa. Mỗi vấn đề này đều được đề cập sâu ở phần khác; vấn đề ở đây là AutoML khiến tất cả chúng trở thành bắt buộc thay vì khuyến khích.
Hãy định giá tìm kiếm, đừng chỉ sửa nó. Quét siêu thông số mô hình tính năng là số lần thử và số lần thử sẽ di chuyển thanh — xem Tỷ lệ sắc nét giảm phát.
Xác thực tạm thời, bằng cách thanh lọc và cấm vận. Xem Tối ưu hóa chuyển tiếp và Phân loại xu hướng nhìn về phía trước để biết các rò rỉ vẫn tồn tại sau sự phân chia thời gian đơn giản.
Cho điểm quy trình, không chỉ người chiến thắng. Xem Xác suất của Backtest Overfitting và thực hiện hiệu chỉnh khả năng chịu tải của nó: giá trị rỗng của PBO là 0,5, không phải 1 — một nửa không phải là "một nửa trang bị quá mức", nó hoàn toàn quá phù hợp, lật đồng xu.
Theo dõi các đỉnh không có ở đó. Tìm kiếm một bề mặt có nhiều tiếng ồn một cách hiệu quả chỉ giúp tìm ra các ảo ảnh sắc nét hơn nhanh hơn (Plateau Analysis); điều này tác động mạnh nhất đến các tham số chiến lược và ít nhất là các siêu tham số ML, đó là trường hợp FLAML và Optuna thực sự được xây dựng cho trường hợp này.
Hạn chế không gian tìm kiếm. Mẫu lá tối thiểu, độ sâu giới hạn và số lượng ước tính, ngân sách tính năng, hình phạt doanh thu — việc thường xuyên tìm kiếm sẽ rẻ hơn so với việc giảm bớt tìm kiếm sau đó.
Kết luận
AutoML nâng mức độ tự động hóa lên một cấp độ: từ việc điều chỉnh các tham số bên trong một ứng viên cố định đến việc tự tạo ra các ứng viên. Ba thành phần đáng để nỗ lực — tsfresh và Featuretools để tạo tính năng, tìm kiếm tiết kiệm chi phí của FLAML để lựa chọn mô hình nhận biết ngân sách và ngữ pháp toán tử công thức để xây dựng alpha có thể đếm được. NAS chỉ có giá trị tính toán khi tỷ lệ tín hiệu trên nhiễu của bạn phù hợp với nó và nó nằm ở điểm cuối đắt đỏ của trục chi phí đánh giá nơi hiệu quả mẫu cuối cùng cũng được đền đáp.
Đối số độ rộng của WorldQuant chỉ tồn tại khi tiếp xúc với các phép đo của chính blog này ở dạng đã sửa: Ở đâu tính các cược độc lập và sản lượng của nhà máy gần như không độc lập. Tạo ra một triệu bảng chữ cái là một nửa dễ dàng. Việc xác định rằng chúng không đủ tương quan để được tính là chiều rộng là một nửa quyết định liệu công thức có ý nghĩa gì hay không.
Và lời cảnh báo trung thực không phải là đạo đức, nó là kết quả được đo lường. Blog này đã chạy phần tìm kiếm và trang bị bổ sung để đưa ra kết luận trong [The Honest Negative](/en/blog/post/honest- Negative-no-robust-edge): hàng chục nghìn thử nghiệm ngược trên 5 chuyên ngành, DSR = 0,00 tại ~37.000 thử nghiệm, PBO 0,264 và 0,327 và không có lợi thế mạnh mẽ. AutoML tăng số lượng bản dùng thử theo mức độ lớn. Bất kể nó tìm thấy gì, nó sẽ có mức giảm phát lớn hơn tương ứng - và sản lượng hữu ích của một nhà máy alpha là tỷ lệ sống sót sau đợt giảm phát đó, chứ không phải kết quả kinh doanh trước đó.
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.