← กลับไปยังบทความ
July 30, 2026
อ่าน 5 นาที

AutoML สำหรับไปป์ไลน์การซื้อขายเชิงระบบ

AutoML สำหรับไปป์ไลน์การซื้อขายเชิงระบบ
#AutoML
#NAS
#feature-engineering
#automation
#quant

บล็อกนี้ใช้เวลาส่วนใหญ่ใน วิธีการค้นหา: ตัวอย่างใดที่จะใช้และเมื่อใด (ครอสโอเวอร์คือต้นทุนการประเมิน) วิธีกำหนดราคาการค้นหาที่คุณรัน (อัตราส่วนความคมชัดที่ลดลง) วิธีให้คะแนนขั้นตอนการคัดเลือก (PBO) และตำแหน่งที่อุปกรณ์ทั้งหมดลงจอดอย่างตรงไปตรงมา (ไม่มีขอบที่แข็งแกร่ง)

สิ่งที่ไม่เคยครอบคลุมคือสิ่งที่คุณค้นหา มากกว่า บทความเหล่านั้นล้วนใช้ชุดคุณลักษณะและกลุ่มกลยุทธ์ตามที่กำหนดและปรับพารามิเตอร์ภายในให้เหมาะสม AutoML โจมตีเลเยอร์ด้านบน — มันทำให้การสร้างผู้สมัครโดยอัตโนมัติ สามส่วนที่ไม่ปรากฏที่อื่นในบล็อกนี้:

  1. การแยกคุณลักษณะอัตโนมัติ — tsfresh เปลี่ยนชุดราคาหนึ่งชุดให้เป็นคุณลักษณะที่มีคุณลักษณะทางสถิติประมาณ 794 รายการ และ Featuretools จะเขียนคุณลักษณะต่างๆ ในตารางตลาดที่เกี่ยวข้องผ่านการสังเคราะห์คุณลักษณะเชิงลึก
  2. AutoML ที่คำนึงถึงงบประมาณ — การเพิ่มประสิทธิภาพต้นทุนแบบประหยัดของ FLAML ซึ่งค้นหาโมเดลที่ดีที่สุด ภายในงบประมาณการประมวลผล แทนที่จะคำนึงถึงต้นทุน
  3. โรงงานอัลฟ่าสูตร — อัลฟ่าสูตร 101 รายการของ WorldQuant เป็นตัวดำเนินการไวยากรณ์ที่เครื่องสามารถระบุได้

อย่างอื่นทั้งหมด เช่น ฟังก์ชั่นวัตถุประสงค์ รูปแบบการตรวจสอบความถูกต้อง การแก้ไขการทดสอบหลายรายการ ได้รับการวัดแล้วที่อื่นที่นี่ ดังนั้นบทความนี้จึงเชื่อมโยงแทนที่จะสอนซ้ำ นั่นมีความสำคัญมากกว่าปกติ เนื่องจาก AutoML ทำให้จำนวนการทดลองใช้เพิ่มขึ้น และการจำนวนการทดลองก็ตรงกับส่วนที่เหลือของส่วนโค้ง

ไปป์ไลน์การซื้อขายอย่างเป็นระบบ AutoML

AutoML ใดที่ทำงานอัตโนมัติ

AutoML ไม่ใช่อัลกอริธึมเดียว เป็นตระกูลเทคนิคที่ทำให้ขั้นตอนต่างๆ ของไปป์ไลน์เป็นไปโดยอัตโนมัติ:

เวที วิธีการด้วยตนเอง วิธี AutoML
วิศวกรรมคุณสมบัติ ตัวชี้วัดงานฝีมือของผู้เชี่ยวชาญโดเมน การสกัดอัตโนมัติ (tsfresh, Featuretools)
การเลือกคุณสมบัติ การวิเคราะห์สหสัมพันธ์ สัญชาตญาณ การทดสอบสมมติฐานทางสถิติ SHAP
การเลือกรุ่น ลองสัก 2-3 รุ่น ค้นหาผู้เรียนหลายสิบคน
การปรับไฮเปอร์พารามิเตอร์ ค้นหาตาราง ปรับแต่งด้วยตนเอง การค้นหาแบบเบย์ / ประหยัดต้นทุน (Optuna, FLAML)
การออกแบบสถาปัตยกรรม แก้ไขโทโพโลยีโครงข่ายประสาทเทียม การค้นหาสถาปัตยกรรมประสาท (NAS)
การก่อสร้างทั้งมวล การซ้อนด้วยตนเอง การเลือกวงดนตรีอัตโนมัติ

หลักฐานก็คือในการซื้อขายอย่างเป็นระบบ พื้นที่ของผู้สมัครมีขนาดใหญ่มาก — ซีรีส์ OHLCV ชุดเดียวสร้างคุณสมบัติทางเทคนิคหลายร้อยรายการ และสินทรัพย์หลายรายการ ข้อมูลการสั่งซื้อ และแหล่งข้อมูลทางเลือกทำให้สามารถรวมกันได้ หลักฐานก็เป็นอันตรายเช่นกัน ผู้สมัครทุกคนคือการทดลอง และการทดลองคือสิ่งที่ทำให้เกิดการค้นพบที่ผิดพลาด

จุดเฉพาะของ AutoML หนึ่งจุดในวัตถุประสงค์: เมตริกที่การค้นหาเพิ่มสูงสุดจะต้องเป็นเมตริกทางการเงิน เนื่องจากการค้นหาจะปรับให้เหมาะสมตามสิ่งที่คุณจดไว้ทุกประการและไม่ได้หมายถึงอะไร สเกลาร์ที่คุณเลือกจะเป็นการเลือกกลยุทธ์ของคุณ — ดู Objective-Function Design โดยที่ Sharpe ที่ไร้เดียงสาต่อการซื้อขายจะครองลอตเตอรีที่มีความเสี่ยงต่ำกว่า 5% ใน 56% ของ 600 เมล็ด และโพสต์ Sharpe ในตัวอย่างจำนวน 21 รายการที่ลดลงเหลือ 0.13 จากตัวอย่าง เชื่อมโยงตัวชี้วัดทางการเงินเข้ากับตัวบันทึกบัญชี AutoML ตั้งแต่เริ่มต้น ไม่ปรับให้เหมาะสม roc_auc และหวังว่าจะถ่ายโอน

วิศวกรรมคุณสมบัติอัตโนมัติ

วิศวกรรมฟีเจอร์คือจุดที่อัลฟ่าส่วนใหญ่อาศัยอยู่ ข้อมูลราคาดิบจะเหมือนกันสำหรับทุกคน การแปลงข้อมูลดังกล่าวให้เป็นสัญญาณคาดการณ์คือสิ่งที่แยกกลยุทธ์ที่ทำกำไรออกจากสัญญาณรบกวน

โรงงานวิศวกรรมฟีเจอร์อัตโนมัติ

tsfresh: จากซีรีย์ราคาเดียวไปจนถึงฟีเจอร์มากกว่า 800 รายการ

tsfresh (การแยกคุณลักษณะอนุกรมเวลาตามการทดสอบสมมุติฐานที่ปรับขนาดได้) สร้างขึ้นโดยมีจุดประสงค์เพื่อการแยกคุณลักษณะอนุกรมเวลา มันคำนวณวิธีการกำหนดลักษณะ 63 วิธีซึ่งขยายเป็นคุณสมบัติ ~ 794 ตามค่าเริ่มต้น ซึ่งรวมถึง:

  • ช่วงเวลาทางสถิติ (ค่าเฉลี่ย ความแปรปรวน ความเบ้ ความโด่ง)
  • ความสัมพันธ์อัตโนมัติที่ความล่าช้าหลายครั้ง
  • ค่าสัมประสิทธิ์ฟูริเยร์และพลังงานสเปกตรัม
  • มาตรการความซับซ้อน (เอนโทรปีโดยประมาณ, เอนโทรปีตัวอย่าง)
  • คุณสมบัติไม่เชิงเส้น (ค่าสัมประสิทธิ์ฟรีดริช, จุดคงที่ Langevin สูงสุด)
  • เปลี่ยนปริมาณและการนับช่วง

สำหรับข้อมูลทางการเงิน หมายความว่าชุดราคาเดียวจะสร้างคุณสมบัติที่เป็นตัวเลือกได้หลายร้อยรายการ ซึ่งหลายๆ รายการจะบันทึกการเปลี่ยนแปลงที่วิศวกรรมคุณสมบัติแบบแมนนวลอาจพลาดไป นี่เป็นแนวทางที่แตกต่างอย่างมากจากชุดฟีเจอร์ที่มาจากโดเมนซึ่งสร้างขึ้นด้วยมือซึ่งใช้ใน การสร้างแบบจำลองสเปรด และ DeepLOB: มีมนุษย์ตัดสินใจว่าความไม่สมดุลของสมุดคำสั่งซื้อมีความสำคัญ ที่นี่ห้องสมุดจะแจกแจงทุกอย่างและให้การทดสอบสมมติฐานตัดสินใจ

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]}")

ที่ select_features ฟังก์ชั่นใช้ขั้นตอน Benjamini-Yekutieli เพื่อควบคุมอัตราการค้นพบที่ผิดพลาดในแบตเตอรี่ฟีเจอร์ทั้งหมด ซึ่งเป็นสัญชาตญาณที่ถูกต้อง และสัญชาตญาณเดียวกันกับ บทความ Sharpe ที่ยุบตัว นำไปใช้กับการค้นหากลยุทธ์ โปรดทราบว่าสิ่งที่ ไม่ ทำ: การควบคุม FDR ในขั้นตอนการเลือกคุณสมบัติไม่ได้พูดอะไรเกี่ยวกับต้นทุนการทดลองใช้การค้นหาแบบจำลองที่ตามมา สิ่งเหล่านี้เป็นค่าทวีคูณสองค่าที่แยกจากกัน และต้องจ่ายทั้งคู่

Featuretools: การสังเคราะห์คุณสมบัติเชิงลึก

ในขณะที่ tsfresh มุ่งเน้นไปที่การกำหนดลักษณะอนุกรมเวลา Featuretools เป็นเลิศในด้านวิศวกรรมฟีเจอร์เชิงสัมพันธ์ — การสร้างฟีเจอร์โดยการเขียนการดำเนินการดั้งเดิมในตารางที่เกี่ยวข้องกัน

สำหรับการเทรด สิ่งนี้จะมีประสิทธิภาพเมื่อคุณมีข้อมูลหลายตาราง: ประวัติการซื้อขาย, สแนปชอตสมุดคำสั่งซื้อ, อัตราเงินทุน และตัวชี้วัดแบบออนไลน์ Featuretools ใช้การสังเคราะห์คุณสมบัติเชิงลึก (DFS) ซึ่งจะซ้อนการเปลี่ยนแปลงและการรวมกลุ่มแบบดั้งเดิม:

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")

ที่ time_index การประกาศเป็นแบบรับน้ำหนัก: เป็นสิ่งที่ช่วยให้ Featuretools คำนวณการรวมกลุ่มโดยใช้เฉพาะแถวที่มีอยู่ที่จุดตัดเท่านั้น หากทำผิดแล้ว DFS จะสร้างฟีเจอร์ที่มาจากอนาคตอย่างมีความสุข — อินสแตนซ์ข้อมูลเชิงสัมพันธ์ของการรั่วไหลที่จัดอยู่ในรายการ อนุกรมวิธานอคติแบบมองไปข้างหน้า

การรวมกันของ tsfresh (การกำหนดลักษณะอนุกรมเวลา) และ Featuretools (การสังเคราะห์เชิงสัมพันธ์) ช่วยให้คุณมีฟีเจอร์แฟคทอรีที่สร้างสัญญาณที่เป็นตัวเลือกหลายพันรายการจากข้อมูลตลาดดิบ โดยไม่ต้องใช้การเข้ารหัสตัวบ่งชี้ด้วยตนเอง

AutoML ที่คำนึงถึงงบประมาณ: FLAML

เราถือว่า Optuna และ Parzen Estimators ที่มีโครงสร้างแบบต้นไม้เป็นพื้นหลัง — การได้มา การเปรียบเทียบตัวอย่าง และเกณฑ์มาตรฐานอยู่ใน Coordinate Descent เทียบกับ Bayesian Optimization ซึ่ง ตัวอย่างที่จะเข้าถึง การวัดของบล็อกนี้เป็นข้อมูลอ้างอิงและไม่ใช่คำตอบตามคติพื้นบ้าน: ครอสโอเวอร์ถูกควบคุมโดยต้นทุนการประเมิน ไม่ใช่ความฉลาดของอัลกอริทึม — เมื่อการทดสอบย้อนกลับเกือบจะฟรี Sobol ที่มีสัญญาณรบกวนจะชนะตามปริมาณงาน (~2,830 cfg/s เทียบกับ ~154 สำหรับ TPE) และมีเพียงการประเมินราคาแพงเท่านั้นที่ทำให้ต้องเสียประสิทธิภาพของตัวอย่าง (สุ่มเทียบกับอัจฉริยะ ค้นหา)

การค้นหา AutoML ที่คำนึงถึงงบประมาณ

การจัดเฟรมนั้นเป็นสิ่งที่ทำให้ FLAML มีแกนที่แตกต่างออกไป แทนที่จะเป็นตัวเก็บตัวอย่างที่แข่งขันกัน Optuna ถาม ว่าจะเก็บตัวอย่างต่อไปที่ไหน; แฟลม (Fast Lightweight AutoML) ถามว่า ฉันสามารถหาตัวอย่างอะไรได้บ้าง ปรับให้เหมาะสมสำหรับโมเดลที่ดีที่สุดภายในเวลาที่กำหนดหรือคำนวณงบประมาณโดยใช้ CFO (การเพิ่มประสิทธิภาพต้นทุน) ซึ่งจัดลำดับความสำคัญของการกำหนดค่าราคาถูกเพื่อประเมินตั้งแต่เนิ่นๆ และเพิ่มระดับเฉพาะเมื่อกำไรส่วนเพิ่มโดยประมาณที่สมเหตุสมผลในการใช้จ่าย

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)

ข้อได้เปรียบของ FLAML สำหรับการซื้อขายคือการจัดสรรการประมวลผลข้ามประเภทโมเดลที่ต่างกัน หากการกำหนดค่า LightGBM ประเมินได้เร็วกว่า CatBoost ถึง 10 เท่า FLAML จะสำรวจ LightGBM มากขึ้นตั้งแต่เนิ่นๆ และเปลี่ยนเฉพาะเมื่อประเมินว่าการปรับปรุงเล็กน้อยจะช่วยลดต้นทุนได้ นั่นคือข้อมูลเชิงลึกเกี่ยวกับระบบราคาถูกจากบทความแบบครอสโอเวอร์ ซึ่งมีเนื้อหาทั่วไปว่า ปริมาณงานเป็นคำระดับเฟิร์สคลาสในงบประมาณการค้นหา ไม่ใช่รายละเอียดการใช้งาน

บันทึกวิถีเป็นส่วนที่ควรค่าแก่การรักษา get_output_from_log ให้ประวัติการกำหนดค่าทั้งหมดแก่คุณ ซึ่งเป็นจำนวนการทดลองใช้ของคุณ — และจำนวนการทดลองใช้คือข้อมูลอินพุตของภาวะเงินฝืดทุกครั้งที่คุณเป็นหนี้

ค้นหาสถาปัตยกรรมประสาทสำหรับโมเดลการซื้อขาย

การค้นหาสถาปัตยกรรมประสาททำให้การออกแบบโทโพโลยีเครือข่ายเป็นไปโดยอัตโนมัติ แทนที่จะปรับแต่งโทโพโลยีแบบตายตัว ตัวเลือกสถาปัตยกรรมสำหรับซีรีส์ทางการเงินนั้นไม่ชัดเจนอย่างแท้จริง - การไม่คงที่ สัญญาณต่อเสียงรบกวนต่ำ ความถี่ผสม และการพึ่งพาซึ่งครอบคลุมตั้งแต่นาทีถึงเดือน ล้วนดึงไปในทิศทางที่ต่างกัน - แต่แรงจูงใจนั้นถูกโต้แย้งอย่างเป็นรูปธรรมในที่อื่นแล้ว: ดู Temporal Fusion Transformer เมื่อ TFT เต้น LSTM เต้น vanilla Transformer และ DeepLOB เกี่ยวกับข้อดีข้อเสียของ CNN+Inception+LSTM สำหรับสิ่งที่สถาปัตยกรรมคงที่ที่ออกแบบด้วยมืออย่างระมัดระวังบรรลุผลสำเร็จแล้ว NAS เป็นข้อโต้แย้งว่าควรค้นหาตัวเลือกนี้เอง

การวิจัยเกี่ยวกับ Neuroevolution NAS สำหรับการทำนายการคืนสินค้า รายงานว่า RNN ที่พัฒนาผ่าน EXAMM (Evolutionary eXploration of Augmenting Memory Models) มีประสิทธิภาพเหนือกว่า DJI และ S&P 500 ในตลาดหมี (2022) และตลาดกระทิง (2023) โดยใช้กลยุทธ์ระยะสั้นแบบง่ายๆ ให้ถือว่าเป็นการกล่าวอ้างของบุคคลที่สาม ไม่ใช่เป็นผลจากการทำซ้ำที่นี่ เนื่องจากเป็นตัวเลขที่มีการค้นหาดีที่สุด โดยไม่มีการรายงานภาวะเงินฝืด

พื้นที่ค้นหา NAS เพื่อการค้าขาย

พื้นที่ค้นหา NAS ที่ใช้งานได้จริงสำหรับโมเดลการซื้อขายประกอบด้วย:

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}

ด้วย NNI (Neural Network Intelligence) จาก Microsoft คุณสามารถกำหนดและค้นหาพื้นที่นี้:

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)

อัลกอริธึมการค้นหา (ENAS, DARTS หรือวิวัฒนาการ) ประเมินสถาปัตยกรรมของผู้สมัครในชุดการตรวจสอบความถูกต้องโดยใช้วัตถุประสงค์ทางการเงิน จากนั้นค่อยๆ แคบลงไปสู่โทโพโลยีที่มีประสิทธิภาพสูง โปรดสังเกตความไม่สมดุลของต้นทุนเมื่อเทียบกับสิ่งอื่นๆ ในบทความนี้: NAS อยู่ที่ปลายสุดของแกนประเมินต้นทุนที่มีราคาแพงมาก ซึ่งเป็นระบบหนึ่งที่ผู้เก็บตัวอย่างที่มีประสิทธิภาพในการสุ่มตัวอย่างและการตัดหลายความเที่ยงตรงจ่ายเองอย่างแท้จริง

แนวทางโรงงาน WorldQuant Alpha

แนวทางการค้นพบอัลฟ่าของ WorldQuant ถือเป็นการนำหลักการ AutoML ไปใช้ในด้านการเงินในระดับอุตสาหกรรมมากที่สุด WorldQuant ก่อตั้งโดย Igor Tulchinsky ดำเนินธุรกิจที่เรียกว่า "โรงงานอัลฟ่า" ซึ่งเป็นกระบวนการที่เป็นระบบในการสร้าง ทดสอบ และรวมสัญญาณคาดการณ์หลายล้านสัญญาณ

ปรัชญา: การสร้างอัลฟ่าแบบเอ็กซ์โพเนนเชียลและการแก้ไข

WorldQuant ตั้งเป้าหมายในปี 2010 ที่จะเข้าถึงอัลฟ่าหนึ่งล้านตัว โดยในช่วงเวลาหนึ่งที่ผลิตได้เพียงหลายพันตัวต่อปี พวกเขาบรรลุเป้าหมายนั้นในปี 2559 ปรัชญาตั้งอยู่บนกฎพื้นฐานของการจัดการเชิงรุก:

IRICBRIR \approx IC \cdot \sqrt{BR}

ที่ไหน IRIR คืออัตราส่วนข้อมูล ICIC ค่าสัมประสิทธิ์ข้อมูลและ BRBR ความกว้าง — จำนวนการเดิมพัน อิสระ แต่ละคน αi\alpha_i เป็นตัวทำนายที่อ่อนแอ ข้อกล่าวอ้างก็คือการรวมตัวที่มีความสัมพันธ์กันอย่างอ่อนเพียงพอจะรวมไอซีขนาดเล็กเข้ากับผลตอบแทนที่ปรับความเสี่ยงอย่างมีความหมาย

การแก้ไขที่สร้างหรือฝ่าฝืน และการอ่านสูตรแบบไร้เดียงสาซ่อนอยู่: ความกว้างไม่ใช่การนับการทดลอง BRBR นับการเดิมพันแบบอิสระ และอัลฟ่าที่สร้างขึ้นนั้นไม่เป็นอิสระ — พวกมันประกอบด้วยตัวดำเนินการเดียวกันในช่องราคาและปริมาณเดียวกัน ดังนั้นจึงสืบทอดโครงสร้างความสัมพันธ์ของกันและกัน บล็อกนี้วัดผลกระทบโดยตรงใน Signal Correlation: ความกว้างที่มีประสิทธิภาพคือ Neff=N/CfN_{eff} = N / C_fและด้วยปัจจัยความสัมพันธ์ของสกุลเงินดิจิทัลทั่วไป Cf3C_f \approx 3สัญญาณสิบสัญญาณมีค่าประมาณ 3.3 สัญญาณอิสระ ที่ BR\sqrt{BR} คำจะไม่เพิ่มขึ้นตามจำนวนอัลฟ่าที่คุณสร้าง มันเติบโตขึ้นตามจำนวนคนที่ไม่เกี่ยวข้องที่รอดชีวิต อัลฟ่าที่สัมพันธ์กันนับล้านซื้อคุณน้อยกว่าสูตรที่โฆษณาไว้มาก

นี่คือเหตุผลว่าทำไมขั้นตอนที่ 3 ด้านล่าง — ความสัมพันธ์กับห้องสมุดที่มีอยู่ — ไม่ใช่ขั้นตอนด้านสุขอนามัยในโรงงานอัลฟ่า เป็นขั้นตอนที่สร้างความกว้างตั้งแต่แรก

อัลฟ่าสูตร 101 ตัว

บทความ "101 Formulaic Alphas" โดย Kakushadze (ที่เกี่ยวข้องกับการวิจัยของ WorldQuant) ตีพิมพ์ชุดนิพจน์อัลฟ่าที่เป็นสูตร — นิพจน์ทางคณิตศาสตร์เหนือราคา ปริมาณ และข้อมูลพื้นฐาน:

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))

สิ่งที่ทำให้สิ่งนี้น่าสนใจสำหรับ AutoML ก็คือ มันเป็น ไวยากรณ์ อัลฟาเป็นองค์ประกอบของชุดตัวดำเนินการขนาดเล็ก (rank, delta, ts_rank, stddev, correlation, signedpower) บนชุดฟิลด์ขนาดเล็ก (close, volume, vwap, returns, adv20). ไวยากรณ์สามารถนับได้ ซึ่งหมายความว่าพื้นที่การค้นหานั้นสามารถสร้างโดยเครื่องได้ในลักษณะที่ "คิดถึงคุณลักษณะที่ดี" ไม่ใช่ ระบบ AutoML สามารถ:

  1. สร้าง นิพจน์ของผู้สมัครโดยการเขียนตัวดำเนินการบนช่องข้อมูล
  2. ประเมิน IC, มูลค่าการซื้อขาย และ Drawdown ของแต่ละนิพจน์
  3. ตัวกรอง สำหรับนิพจน์ที่รอดจากการทดสอบทางสถิติ และ ไม่มีความสัมพันธ์กับไลบรารีที่มีอยู่อย่างเพียงพอ
  4. รวม ผู้รอดชีวิตไว้ในพอร์ตโฟลิโอ

โปรดทราบว่าขั้นตอนที่ 1 และ 2 เป็นขั้นตอนที่ง่าย และขั้นตอนที่ 3 คือตำแหน่งของค่า — ดูการแก้ไขความกว้างด้านบน

การค้นพบอัลฟ่าที่ปรับปรุงแล้วของ LLM

WorldQuant ได้เริ่มบูรณาการโมเดลภาษาขนาดใหญ่เข้ากับโรงงานอัลฟ่า ตามที่รายงานในสื่อทางการเงิน บริษัทกำลังสำรวจว่า LLM สามารถ "แปลงและค้นพบอัลฟ่าในโดเมนต่างๆ" ได้อย่างไร — สร้างการแสดงออกใหม่ๆ แปลเอกสารการวิจัยเป็นสมมติฐานที่ทดสอบได้ และแสดงความสัมพันธ์ข้ามโดเมนที่การค้นหาแบบนับล้วนๆ จะพลาดไป นี่เป็นกลไกที่แตกต่างจากการแยกสัญญาณออกจากข้อความ ซึ่งบล็อกนี้กล่าวถึงใน LLM Alpha Mining on Earnings Calls; ในที่นี้ LLM จะเขียน สูตร ไม่ใช่ คุณลักษณะ

สร้างโรงงาน Mini Alpha ของคุณเอง

นี่คือโรงงานอัลฟ่าขนาดกะทัดรัดแต่ใช้งานได้ดีเหนือไวยากรณ์ของผู้ปฏิบัติงาน:

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

เทมเพลตหกเทมเพลตบนห้าหน้าต่างเป็นการกวาดล้างการกำหนดค่า 30 รายการ รายงานที่ผลิตมีรูปแบบ แผนผัง — ช่องต่างๆ คือสิ่งที่โรงงานส่งออก และไม่มีการกรอกตัวเลข เนื่องจากไม่มีการวัดที่นี่:

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 แบบดิบของอัลฟ่าระดับบนสุดจากการกำหนดค่า 30 แบบ ไม่ใช่ผลลัพธ์ — มันคือสูงสุดที่ 30 เสมอ และในกลยุทธ์แบบศูนย์ขอบ 1,000 แบบ ค่าเฉลี่ย Sharpe ต่อปีที่ดีที่สุดอยู่ที่ 1.63 ในขณะที่การทดสอบแบบไร้เดียงสาประกาศการค้นพบ 100% ของเวลา (Deflated Sharpe Ratio) การส่งมอบจากโรงงานโดยสุจริตจึงไม่ใช่ "เราพบอัลฟ่า" แต่เป็น จำนวนอัลฟ่าที่รอดจากภาวะเงินฝืด: การกระจาย IC จำนวนการทดลอง DSR ของผู้ชนะเทียบกับจำนวนนั้น และ PBO ของการคัดเลือก นั่นคือการวัดส่วนนี้ยังคงเป็นหนี้อยู่

Guardrails: สิ่งที่คุณเป็นหนี้อยู่แล้ว

AutoML ขยายขอบเขตการค้นพบและการปรับแต่งมากเกินไปในขนาดที่เท่ากัน และจะทำเช่นนั้นในช่วงทดลองใช้โดยที่ความแตกต่างนั้นไม่สำคัญอีกต่อไป แต่ละสิ่งเหล่านี้จะกล่าวถึงในเชิงลึกในที่อื่น ประเด็นก็คือ AutoML ทำให้ทั้งหมดนี้เป็นเรื่องบังคับแทนที่จะแนะนำ

กำหนดราคาการค้นหา อย่าเพิ่งแก้ไขให้ถูกต้อง การกวาดคุณลักษณะโมเดล-ไฮเปอร์พารามิเตอร์เป็นการนับการทดลองใช้ และจำนวนการทดลองใช้ย้ายแถบ — ดู The Deflated Sharpe Ratio

ตรวจสอบความถูกต้องชั่วคราว โดยมีการล้างข้อมูลและคว่ำบาตร ดู Walk-Forward Optimization และ Look-Ahead Bias Taxonomy เพื่อดูการรั่วไหลที่รอดพ้นจากการแยกทางชั่วคราวอย่างไร้เดียงสา

ให้คะแนนขั้นตอน ไม่ใช่เฉพาะผู้ชนะ ดู ความน่าจะเป็นของ Backtest Overfitting และดำเนินการแก้ไขการรับน้ำหนัก: ค่าว่างของ PBO คือ 0.5 ไม่ใช่ 1 — ครึ่งหนึ่งไม่ใช่ "ครึ่งพอดี" แต่เป็นพอดีเกินพอดี พลิกเหรียญ

เฝ้าดูยอดเขาที่ไม่มีอยู่ตรงนั้น การค้นหาพื้นผิวที่มีเสียงรบกวนอย่างมีประสิทธิภาพจะพบภาพลวงตาที่คมชัดยิ่งขึ้นเร็วขึ้น (การวิเคราะห์ที่ราบสูง); สิ่งนี้กัดได้ยากที่สุดกับพารามิเตอร์กลยุทธ์และน้อยที่สุดในไฮเปอร์พารามิเตอร์ของ ML ซึ่งเป็นกรณีที่ FLAML และ Optuna ถูกสร้างขึ้นมาเพื่อจริง ๆ

จำกัดพื้นที่การค้นหา ตัวอย่างลีฟขั้นต่ำ ความลึกที่ต่อยอดและจำนวนตัวประมาณค่า งบประมาณฟีเจอร์ การลงโทษการหมุนเวียน — การทำให้การค้นหาเป็นปกติมีราคาถูกกว่าการทำให้การค้นหาจางลงในภายหลัง

บทสรุป

AutoML ย้ายการทำงานอัตโนมัติขึ้นไปอีกระดับ: ตั้งแต่การปรับพารามิเตอร์ภายในตัวเลือกคงที่ไปจนถึงการสร้างตัวเลือกด้วยตนเอง องค์ประกอบสามอย่างคุ้มค่ากับความพยายาม ได้แก่ tsfresh และ Featuretools สำหรับการสร้างฟีเจอร์ การค้นหาแบบประหยัดต้นทุนของ FLAML สำหรับการเลือกโมเดลที่คำนึงถึงงบประมาณ และไวยากรณ์ตัวดำเนินการตามสูตรสำหรับการสร้างอัลฟ่าที่นับได้ NAS จะคุ้มค่ากับการประมวลผลก็ต่อเมื่ออัตราส่วนสัญญาณต่อสัญญาณรบกวนของคุณเหมาะสมเท่านั้น และจะอยู่ที่ปลายสุดที่มีราคาแพงของแกนประเมินต้นทุน ซึ่งท้ายที่สุดแล้วประสิทธิภาพของตัวอย่างจะต้องจ่าย

อาร์กิวเมนต์ความกว้างของ WorldQuant ยังคงติดต่อกับการวัดของบล็อกนี้ในรูปแบบที่ถูกต้องเท่านั้น: IRICBRIR \approx IC\sqrt{BR} ที่ไหน BRBR นับการเดิมพัน อิสระ และผลผลิตของโรงงานแทบไม่มีความเป็นอิสระเลย การสร้างอัลฟ่าล้านตัวนั้นง่ายเพียงครึ่งเดียว การพิจารณาว่าไม่มีความสัมพันธ์กันมากพอที่จะนับเป็นความกว้างคือครึ่งหนึ่งที่กำหนดว่าสูตรมีความหมายหรือไม่

และคำเตือนที่ซื่อสัตย์ไม่ใช่คุณธรรม แต่เป็นผลที่วัดได้ บล็อกนี้กล่าวถึงส่วนโค้งของการค้นหาและการปรับแต่งจนเสร็จสิ้นใน The Honest Negative: การทดสอบย้อนหลังนับหมื่นครั้งในห้าสาขาหลัก, DSR = 0.00 ที่การทดลอง ~ 37,000 ครั้ง, PBO 0.264 และ 0.327 และไม่มีขอบที่แข็งแกร่ง AutoML เพิ่มจำนวนการทดลองใช้ตามลำดับความสำคัญ ไม่ว่าจะพบอะไรก็ตาม มันจะติดหนี้ภาวะเงินฝืดที่มากขึ้นตามลำดับ และผลลัพธ์ที่เป็นประโยชน์ของโรงงานอัลฟ่าก็คืออัตราการรอดชีวิตหลังจากภาวะเงินฝืดนั้น ไม่ใช่ประเด็นสำคัญก่อนหน้านั้น

ข้อจำกัดความรับผิดชอบ: ข้อมูลที่ให้ไว้ในบทความนี้มีไว้เพื่อการศึกษาและให้ข้อมูลเท่านั้น และไม่ถือเป็นคำแนะนำทางการเงิน การลงทุน หรือการเทรด การเทรดสกุลเงินดิจิทัลมีความเสี่ยงสูงที่จะขาดทุน

ผู้เขียน

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

ก้าวนำหน้าตลาด

สมัครรับจดหมายข่าวของเราเพื่อรับข้อมูลเชิงลึกการเทรดด้วย AI เฉพาะ การวิเคราะห์ตลาด และการอัปเดตแพลตฟอร์ม

เราเคารพความเป็นส่วนตัวของคุณ ยกเลิกการสมัครได้ทุกเมื่อ