关于 signal-classification
用于训练监督式分类器,预测资产在未来周期内的价格方向。内容涵盖标签生成、按时间顺序验证、模型解释和面向交易的阈值选择。
主要功能
- 01二分类与多分类标签
- 02Walk-forward 验证
- 03XGBoost 和 LightGBM 训练
- 04SHAP 特征分析
- 05按盈利因子优化阈值
适用场景
- 01避免随机打乱数据造成泄漏,检验方向信号
- 02分析哪些特征影响预测
- 03为交易信号选择概率阈值
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ agiprolabs/ claude-trading-skills --skill signal-classification安装后在 Claude Code 中输入/signal-classification确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/model_guide.mdvalidation_methods.mdscripts/train_classifier.pywalk_forward_backtest.py详细介绍
信号分类
使用有监督机器学习分类器,预测资产价格在未来一段时间内将上涨还是下跌。本技能涵盖完整流程:标签创建、模型训练、走步验证、特征重要性分析,以及针对交易应用的阈值优化。
基于树的模型为何在交易机器学习中占主导地位
XGBoost 和 LightGBM 是量化交易机器学习的主力模型,原因如下:
- 非线性关系:金融特征之间会以复杂的非线性方式相互作用,树模型能够自然地捕捉这些关系
- 不受特征尺度影响:无需对输入进行归一化或标准化——树按排序进行分割
- 内置特征重要性:无需单独分析,即可了解哪些特征驱动了预测
- 训练和推理速度快:数秒内即可使用数千个样本进行训练,微秒内即可完成预测
- 处理缺失值:原生支持 NaN,无需采用填补技巧
- 内置正则化:max_depth、min_child_weight、subsample 均可防止过拟合
线性模型和深度学习也各有用武之地,但对于样本少于 100k 的表格型交易特征,梯度提升树始终优于其他方法。
分类类型
二元分类
最简单、最常见的设置。预测未来收益是否超过某个阈值:
- 上涨信号:未来收益 > +1%
- 下跌信号:未来收益 < -1%
- 中性(排除):-1% 至 +1%——从训练数据中剔除这些样本,以生成更清晰的标签
import numpy as np
def create_binary_labels(
prices: np.ndarray, horizon: int = 24, threshold: float = 0.01
) -> np.ndarray:
"""Create binary labels from forward returns.
Args:
prices: Array of prices.
horizon: Forward return lookback in bars.
threshold: Minimum return magnitude for a label.
Returns:
Array of labels: 1 (up), 0 (down), NaN (neutral).
"""
fwd_returns = np.roll(prices, -horizon) / prices - 1
fwd_returns[-horizon:] = np.nan
labels = np.where(fwd_returns > threshold, 1,
np.where(fwd_returns < -threshold, 0, np.nan))
return labels
多分类
使用三个类别,实现更精细的信号粒度:
| 类别 | 条件 | 典型阈值 |
|---|---|---|
| 强势上涨 | fwd_return > +2% | 高置信度做多 |
| 温和上涨 | +0.5% 至 +2% | 中等置信度 |
| 下跌 | fwd_return < -0.5% | 回避/做空 |
多分类会减少每个类别的样本数量。仅在数据集足够大(每个类别 1000+ 个样本)时使用。
概率校准
XGBoost/LightGBM 输出的原始模型概率校准效果不佳。预测概率为 0.7,并不意味着有 70% 的正确概率。使用校准来改善这一点:
from sklearn.calibration import CalibratedClassifierCV
calibrated = CalibratedClassifierCV(base_model, cv=5, method="isotonic")
calibrated.fit(X_train, y_train)
probs = calibrated.predict_proba(X_test)[:, 1]
对于树模型,等距回归校准的效果优于 Platt 缩放。
走步验证
这是交易机器学习中最重要的概念。 标准交叉验证会随机打乱数据,从而造成前视偏差。走步验证则遵循时间顺序。
工作原理
Window 1: [===TRAIN===][GAP][=TEST=]
Window 2: [===TRAIN===][GAP][=TEST=]
Window 3: [===TRAIN===][GAP][=TEST=]
Window 4: [===TRAIN===][GAP][=TEST=]
每个窗口:
- 使用过去 N 根 K 线进行训练
- 跳过一段间隔(禁运期),其长度等于未来收益的时间跨度
- 对接下来的 M 根 K 线进行预测
- 记录样本外预测结果
- 向前滑动并重复
典型参数
| 参数 | 值 | 原因 |
|---|---|---|
| 训练窗口 | 30 天(720 根小时 K 线) | 数据量足以学习,且足够新,仍具参考价值 |
| 测试窗口 | 7 天(168 根小时 K 线) | 预测数量足以满足统计显著性要求 |
| 步长 | 1 天(24 根 K 线) | 重叠测试窗口以获取更多数据点 |
| 间隔(禁运期) | 与未来收益的时间跨度相同 | 防止标签泄漏 |
走步验证实现
from typing import Iterator
def walk_forward_splits(
n_samples: int,
train_size: int = 720,
test_size: int = 168,
step_size: int = 24,
gap: int = 24,
) -> Iterator[tuple[np.ndarray, np.ndarray]]:
"""Generate walk-forward train/test index splits.
Args:
n_samples: Total number of samples.
train_size: Number of training samples per window.
test_size: Number of test samples per window.
step_size: Step between successive windows.
gap: Gap between train end and test start.
Yields:
Tuples of (train_indices, test_indices).
"""
start = 0
while start + train_size + gap + test_size <= n_samples:
train_idx = np.arange(start, start + train_size)
test_start = start + train_size + gap
test_idx = np.arange(test_start, test_start + test_size)
yield train_idx, test_idx
start += step_size
参见 references/validation_methods.md,了解净化交叉验证(purged CV)、CPCV 和评估指标。
模型训练流程
完整流程概览
- 特征工程——计算技术指标、链上指标和成交量特征(参见
feature-engineering技能) - 标签创建——根据阈值计算未来收益,并剔除中性区间
- 走步划分——按时间顺序划分训练/测试窗口并设置间隔
- 训练模型——在每个训练窗口上使用 XGBoost 或 LightGBM
- 在测试集上预测——生成样本外概率预测
- 汇总预测结果——拼接所有样本外结果
- 评估——准确率、精确率、召回率、F1、AUC、利润因子
快速训练示例
from xgboost import XGBClassifier
model = XGBClassifier(
n_estimators=200,
max_depth=4,
learning_rate=0.05,
subsample=0.8,
colsample_bytree=0.8,
eval_metric="logloss",
use_label_encoder=False,
random_state=42,
)
model.fit(
X_train, y_train,
eval_set=[(X_val, y_val)],
verbose=False,
)
probabilities = model.predict_proba(X_test)[:, 1]
参见 references/model_guide.md,了解参数建议和调优方法。
SHAP 特征重要性
SHAP(SHapley Additive exPlanations)为理解模型预测提供了黄金标准。
全局特征重要性
哪些特征对所有预测最重要:
import shap
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X_test)
# Summary plot (top 15 features)
shap.summary_plot(shap_values, X_test, max_display=15)
局部解释
为什么会做出某个特定预测:
# Explain a single prediction
shap.force_plot(explainer.expected_value, shap_values[0], X_test.iloc[0])
时间特征重要性
跟踪特征重要性在滚动前向窗口中的变化。如果某个特征的重要性显著下降,市场状态可能已经发生变化。
阈值优化
默认的 0.5 概率阈值几乎从来都不是交易的最佳选择。
为什么不用 0.5?
- 类别不平衡:如果 60% 的标签为“上涨”,0.5 的阈值就过于激进
- 交易成本:边际信号(概率为 0.51)很少能覆盖交易成本
- 收益不对称:交易中精确率比召回率更重要
针对盈利因子进行优化
def optimize_threshold(
probabilities: np.ndarray,
returns: np.ndarray,
thresholds: np.ndarray | None = None,
) -> tuple[float, float]:
"""Find threshold that maximizes profit factor.
Args:
probabilities: Model predicted probabilities.
returns: Actual forward returns.
thresholds: Thresholds to search over.
Returns:
Tuple of (best_threshold, best_profit_factor).
"""
if thresholds is None:
thresholds = np.arange(0.50, 0.85, 0.01)
best_threshold, best_pf = 0.5, 0.0
for t in thresholds:
signals = probabilities >= t
if signals.sum() < 10:
continue
signal_returns = returns[signals]
wins = signal_returns[signal_returns > 0].sum()
losses = abs(signal_returns[signal_returns < 0].sum())
pf = wins / losses if losses > 0 else 0.0
if pf > best_pf:
best_pf = pf
best_threshold = t
return best_threshold, best_pf
典型发现:加密货币交易信号的最佳阈值为 0.60-0.75。
加密货币特定注意事项
较短的训练窗口
加密货币市场状态变化迅速。使用 6 个月数据训练的模型,表现可能不如使用 30 天数据训练的模型。应使用较短的训练窗口并频繁重新训练。
类别不平衡
大多数时间段都处于“横盘”状态(收益在中性区间内)。以下是应对策略:
- 舍弃中性区间:仅使用明确的上涨/下跌标签进行训练
- 对多数类欠采样:在 XGBoost 中使用
scale_pos_weight - SMOTE:合成少数类过采样(谨慎使用——可能引入前视偏差)
- 调整阈值:提高概率阈值以进行补偿
交易成本
准确率为 55% 的模型听起来不错,但扣除 0.5% 的往返交易成本(滑点 + 费用)后,许多信号都会变得无利可图。始终评估扣除成本后的信号:
net_return = gross_return - 0.005 # 50 bps round-trip
特征衰减
随着更多参与者发现并据此交易,特征会逐渐失去预测能力。监控滚动表现,并在指标退化时重新训练。
与其他技能集成
| 技能 | 集成方式 |
|---|---|
feature-engineering | 计算分类器的输入特征 |
vectorbt | 根据 ML 信号回测交易策略 |
regime-detection | 为每种市场状态分别训练模型,或将市场状态作为特征 |
position-sizing | 根据分类器的置信度确定仓位规模 |
risk-management | 对 ML 生成的信号应用投资组合级风险限制 |
文件
参考资料
references/model_guide.md— XGBoost 和 LightGBM 参数指南、调优和集成references/validation_methods.md— 滚动前向验证、净化交叉验证、CPCV 和评估指标
脚本
scripts/train_classifier.py— 使用滚动前向验证和特征重要性训练信号分类器scripts/walk_forward_backtest.py— 使用滚动前向验证,对比回测 ML 信号与买入并持有策略
依赖项
# Core (required)
uv pip install pandas numpy scikit-learn
# Optional (recommended)
uv pip install xgboost lightgbm shap
要点总结
- 滚动前向验证不可或缺——随机交叉验证会严重夸大结果
- 针对盈利因子而非准确率优化阈值——高精确率、低召回率的模型优于高准确率模型
- 加密货币应使用较短的训练窗口——在大多数市场状态下,30 天优于 6 个月
- 监控特征衰减——滚动指标低于基准时重新训练
- 始终评估扣除成本后的表现——准确率为 55% 的模型扣除费用后可能无利可图
- 优先使用 SHAP,而非原始特征重要性——SHAP 提供一致且有理论依据的解释