1. 课程导入

欢迎进入《金融时序机器学习择时信号实战》。在正式写第一行特征工程代码之前,我们需要先建立一张清晰的“认知地图”:这门课到底要解决什么问题,机器学习在其中的位置是什么,以及从原始行情数据到最终可执行交易信号,中间要经过哪些关键环节。很多初学者一上来就调模型、调参数,结果模型在训练集上表现优异,实盘却持续亏损,根本原因往往不是算法不够强,而是对“时序预测”与“交易信号”之间的鸿沟缺乏认识。

一、学习目标:三个层次的能力跃迁

本课程的目标不是让你背下某个模型的公式,而是完成三个层次的能力构建。第一层是数据能力:能够正确获取、清洗、对齐金融时序数据,理解复权、停牌、涨跌停、幸存者偏差等细节对结果的影响。第二层是建模能力:掌握适用于时序的机器学习方法,包括特征构造、标签设计、交叉验证、模型选择与过拟合控制。第三层是交易能力:把模型输出转化为仓位、买卖点、止损止盈规则,并用回测与绩效指标评估其真实价值。

学习建议:每学完一个模型,都问自己三个问题——它预测的是什么?预测结果如何变成仓位?这个仓位在真实交易成本下还赚钱吗?

二、核心概念:预测、信号与交易的三层结构

金融时序机器学习择时,本质上是把“未来价格会怎样”转化为“现在该持有什么仓位”。这里必须区分三个容易混淆的概念:预测目标(如未来5日收益率)、模型输出(如上涨概率0.63)、交易信号(如目标仓位60%)。预测准确率高,不代表信号赚钱;信号赚钱,也不代表策略稳健。三者之间隔着阈值设定、仓位映射、交易成本和风险控制。

另一个核心概念是时序依赖性。与图像、文本不同,金融数据存在自相关、非平稳、 regime switching(市场状态切换)等特性。随机打乱样本会严重高估模型能力,因此必须使用滚动窗口、扩展窗口或 purged K-fold 等时序交叉验证方法。

从行情数据到交易信号的三层结构 数据层 OHLCV · 复权 · 对齐 停牌/涨跌停处理 特征:动量、波动、量价 模型层 标签:未来收益/方向 时序交叉验证 树模型 / 线性 / 神经网络 交易层 概率→仓位映射 交易成本 · 滑点 回测 · 绩效归因 关键约束:时序不可打乱 · 标签不可泄露未来 · 信号必须可执行 滚动窗口训练 → 样本外预测 → 逐日生成仓位 评估闭环:收益 · 夏普 · 最大回撤 · 换手率 · 胜率 · 盈亏比 任何指标异常都要回到数据层与模型层排查

三、整体框架与实战路线图

本课程共30章,整体遵循“数据→特征→标签→模型→信号→回测→优化”的实战路线。前几章打基础,中间集中攻克特征工程与模型训练,后段聚焦信号生成、回测评估与实盘注意事项。每一章都会给出可运行的代码片段和参数配置,你可以直接在自己的数据集上复现。

阶段 核心任务 关键产出 常见风险
数据准备 行情获取、清洗、对齐、复权 干净的价格与成交量面板 幸存者偏差、前视偏差
特征与标签 构造动量、波动、量价特征;定义预测目标 特征矩阵与标签向量 标签泄露、特征未来函数
模型训练 时序交叉验证、模型选择、超参调优 样本外预测概率 过拟合、数据窥探
信号生成 概率→仓位映射、阈值设定、风控规则 每日目标仓位序列 信号抖动、换手过高
回测评估 计入成本、滑点、涨跌停限制 净值曲线与绩效指标 忽略交易成本、过度乐观

四、案例场景:一个最小可运行示例

为了让你对“信号”有直观感受,下面给出一个极简示例:用过去20日动量作为特征,预测未来5日涨跌方向,并把预测概率映射为仓位。注意这里只是演示流程,真实策略需要更严谨的验证。

import pandas as pd
import numpy as np

# 假设 df 已包含 close 列,索引为交易日
df['mom20'] = df['close'].pct_change(20)
df['fwd5'] = df['close'].shift(-5) / df['close'] - 1
df['label'] = (df['fwd5'] > 0).astype(int)

# 简单滚动训练:前500天训练,之后逐日预测
train = df.iloc[:500].dropna()
test = df.iloc[500:].dropna()

from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(train[['mom20']], train['label'])

test = test.copy()
test['prob'] = model.predict_proba(test[['mom20']])[:, 1]
test['position'] = np.where(test['prob'] > 0.55, 1, 0)  # 概率大于0.55才持仓

# 策略收益(未计成本)
test['ret'] = test['close'].pct_change().shift(-1)
test['strategy_ret'] = test['position'] * test['ret']
print(test[['prob', 'position', 'strategy_ret']].tail())
上述代码省略了交易成本、滑点和涨跌停约束,直接用于实盘会严重高估收益。后续章节会逐步补齐这些模块。

五、常见误区与复盘要点

  • 误区一:用随机切分做时序验证。随机打乱会让未来信息泄露到训练集,导致样本外表现虚高。必须使用时间顺序切分。
  • 误区二:只看准确率不看盈亏。在类别不平衡的金融数据中,准确率可能被多数类主导,必须结合夏普、最大回撤、换手率综合判断。
  • 误区三:忽略交易成本。高频调仓的策略在扣除手续费和滑点后可能由盈转亏,信号频率必须与成本结构匹配。
  • 误区四:把回测当实盘。回测中的成交假设、流动性限制、涨跌停无法成交等情况,都会让实盘结果偏离回测。