机器学习实验失败:使用 1.5m 信号训练 XGBoost 分类器
Source: Dev.to

在2022年,我开始用 Python 创建交易策略,尽管知识有限,但仍希望采用强大的基于机器学习的方法。我决定让 AI(Sonnet 4.5)编写代码并通过 Grok Thinking 建议模型参数。
在审阅了大量的市场价格图表后,我假设某些模式可以通过合适的交易策略和仓位优化来利用,从而产生几个百分点的回报。实验在两个 Jupyter Notebook 中设置:一个用于 XGBoost 模型训练,另一个用于策略回测。
数据收集与标注
- 下载了过去5年内顶级30种加密代币的15分钟价格数据,并将其存储为 Parquet 文件。
- 识别出每一个在接下来的十个15分钟区间内出现超过3%跌幅的价格点。
- 提取了该价格点之前的十个价格点以及技术分析指标作为特征。
- 生成了 500 k 条“跌落”信号,并加入 1 M 条随机非跌落样本,得到 1.5 M 条训练实例(其中20% 用作测试)。
为了使不同资产的跌幅具有可比性,我使用 Z 分数方法对其进行归一化:
drop_zscore = drop_pct / volatility # volatility = std deviation of returns
# Threshold: drop_zscore <= -2 (i.e., a drop twice the typical volatility)
特征工程
特征来源于动量、波动率和价差指标。经过预处理后,将数据集输入 XGBoost,使用 Grok 推荐的超参数:
# Recommended hyperparameters
max_depth: 3-7 # prevents memorizing noise
learning_rate: 0.01-0.1 # smaller = better with more trees
n_estimators: 200-500 # use early stopping
subsample: 0.6-0.9
colsample_bytree: 0.6-0.9
scale_pos_weight: 3-10 # handles class imbalance
模型性能
训练集
ROC-AUC Score: 0.6899
Classification Report
----------------------
precision recall f1-score support
No Signal 0.93 0.62 0.74 3,149,036
Signal 0.19 0.66 0.29 426,220
accuracy 0.62 3,575,256
macro avg 0.56 0.64 0.52 3,575,256
weighted avg 0.84 0.62 0.69 3,575,256
Confusion Matrix
[[1,938,267 1,210,769]
[ 144,995 281,225]]
测试集(未见数据)
ROC-AUC Score: 0.6761
Classification Report
...
Train AUC: 0.6899
Test AUC: 0.6761
Difference: 0.0138
✓ 良好的泛化 – 过拟合最小
特征重要性
预测跌幅最具影响力的特征是 基本回报。然而,模型产生了许多误报,这可能对投资组合产生不利影响。

回测
我将训练好的模型加载到回测模拟中,定义了 TP、SL、延迟和冷却等仓位参数。对 900 种参数组合进行网格搜索(在本地机器上约 3 小时)以寻找最佳配置。
结果: 每种情形都以 100 % 的亏损结束。回测过程完全失败。
反思
一步一步使用 Cursor + Sonnet 4.5 进行工作时,代码生成过程非常顺畅;助手在仅进行少量调试后就能生成可运行的 notebook。然而,Jupyter 的集成使用起来相当繁琐——每次修改都需要手动关闭、重新打开并重新运行 notebook。因此,我改用了 Ask Mode,手动粘贴代码块。
实验表明,尽管 AUC 分数尚可,但分类器的误报率以及无法将预测转化为盈利交易,使得该方法在当前形态下效果不佳。后续工作需要解决信号精度、风险管理以及更真实的市场摩擦等问题。