1. 入坑前先看清:随机森林在量化交易中解决的到底是什么问题
我在量化交易里认真使用随机森林,是从一次很失败的预测开始的。当时我跟着网上的教程用各种机器学习模型去预测“明天涨还是跌”,回测曲线画出来相当漂亮,实盘却稳定亏损,手续费倒是贡献了不少。复盘了很久,最核心的问题不是模型选错了,而是我把一个本质上属于“市场结构状态识别”的问题,硬做成了“价格方向预测”。后来我换了个思路,让随机森林先去判断市场当前处在什么结构里——是趋势行情、震荡行情,还是波动率正在扩张——再由交易规则决定怎么做,这才真正体会到机器学习在量化里的定位。这篇文章把我用随机森林做市场结构预测的完整流程、代码结构和踩坑记录都整理出来,适合有一定Python基础、被“AI预测股价”忽悠过但还想认真把机器学习用在交易上的读者。
1.1 为什么“预测涨跌”这条路大多走不通
很多刚接触量化交易的人,第一步就是想用机器学习直接预测未来N根K线是上涨还是下跌。这个想法很自然,但金融时序数据有个残酷特点:价格变化里真正可以被提前预测的成分极低,绝大多数波动来自噪音。如果把日线收益率的信噪比量化一下,你会发现大部分品种的日收益中,可解释的方差占比经常只是个位数。也就是说,模型要在一片巨大的随机噪声里去抓那么一点点规律,还要面对市场参与者结构变化、政策冲击、突发事件等因素,很容易把噪声当成信号学进参数里。
所以你在回测时会看到一种典型现象:训练集上准确率轻松做到百分之七八十,一到样本外就掉到五十附近,跟抛硬币差不多。随机森林作为一种有监督模型,并不会天然绕开这个问题。如果任务本身定义得太“紧”——直接预测方向——即使换了更复杂的深度学习结构,结果也差不了太多,只是换一种方式过拟合而已。
1.2 市场结构预测:一套更接地气的任务定义
方向上难预测,不代表市场完全没有结构。趋势跟踪策略能赚钱,本质上就是在赚“市场存在持续性结构”的钱;波动率策略能赚钱,靠的是波动聚集效应。也就是说,价格未来走哪条路难以预测,但市场当前处于什么“运行模式”,有更强的自相关性和可学习性。
我提到的“市场结构预测”,通俗讲就是让模型回答几个问题:当前行情大概率处于趋势状态还是震荡状态?如果是趋势,是上涨趋势还是下跌趋势?未来一段时间波动率会维持在低位还是明显放大?这些问题判断错了,后果没有方向预测那么严重,容忍度更高;判断对了,却能直接改进交易逻辑的入场、过滤和仓位管理。用随机森林处理这类状态识别和区间预测任务,比硬predict涨跌靠谱得多。
1.3 为什么选随机森林而不是神经网络
从机器学习模型选型看,量化场景有几个现实约束:数据量通常有限,单品种日线数据哪怕看十年也就两千多根K线;特征之间往往存在较强的非线性关系;交易逻辑要求模型输出在一定程度上可解释。随机森林在这几个维度上都相对省心。
我并不是说神经网络不能用,而是说在起步阶段,先用随机森林把问题定义、特征工程、验证框架跑通,远比直接上深度网络靠谱。随机森林对数据尺度不敏感,不需要做复杂的归一化;能自动处理特征交互;有袋外误差和特征重要性做辅助诊断;模型输出概率也比较稳定。对刚入门的交易者来说,这些特性都是加分项。等后面你需要处理非结构化数据或者超大规模特征工程时,再引入深度学习也不迟。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 任务定义与数据准备:先解决“预测什么”再谈“怎么预测”
很多人拿到行情数据后第一件事就是写代码,四处找特征、试模型。我的习惯相反。我会先花大量时间把“预测目标”想清楚:模型到底要输出一个什么变量?这个变量怎么定义才算可交易?如果把这一步做错,后面所有代码都是浪费时间。
2.1 把市场结构拆成哪些可计算的状态
市场结构是个很抽象的词,落到编程层面必须变成可计算的类别或数值。我在实际项目中一般拆成两类问题:
一类是方向性结构,标签可能是“上涨趋势、下跌趋势、震荡区间”。这类结果适合直接指导趋势策略开多还是开空,或者决定要不要过滤掉无效信号。
另一类是波动性结构,标签可能是“高波动、低波动、波动放大中”。这类结果不适合告诉你方向,但可以指导仓位管理。因为无论做多还是做空,如果预测未来波动会显著放大,单位头寸的风险都会增加,需要提前调低仓位。
还有一个容易被忽略的状态是“结构切变”,也就是从震荡切换到趋势,或从趋势切换到震荡的临界区域。这类状态样本量少,但价值最大,我会单独构造特征进行监测。
2.2 标签构造:没有人工标注,就用滚动窗口“自动切片”
因为金融数据没有现成的人工标签,不像图像分类有“猫”和“狗”,我们需要自己设计规则去给历史行情标注结构状态。最基本的方法是拿“未来一段时间”的行情表现回推当前状态。
比如我用日线数据做实验时,会设定一个结构判断周期,常见的是20根K线。标签构造的核心思路是:用未来N根K线的涨跌幅和真实波幅来判断这段行情属于趋势还是震荡。
下面我给出一个可行的标签构造逻辑,它不是唯一方案,但你可以在此基础上调整阈值:
python复制import numpy as np
import pandas as pd
def label_market_structure(df, horizon=20, trend_threshold=1.0):
# 未来horizon根K线的收益率
df['fwd_ret'] = df['close'].shift(-horizon) / df['close'] - 1.0
# 用平均真实波幅ATR做标准化,更能适应不同品种的价格尺度
df['atr'] = df['high'].rolling(horizon).max() - df['low'].rolling(horizon).min()
df['fwd_ret_scaled'] = df['fwd_ret'] / df['atr']
def assign_label(x):
# 阈值的设定需要看品种的波动特性,我一般先看分布再定
if np.isnan(x):
return np.nan
if x > trend_threshold:
return 'uptrend'
elif x < -trend_threshold:
return 'downtrend'
else:
return 'range'
df['structure_label'] = df['fwd_ret_scaled'].apply(assign_label)
# 去掉最后horizon行,因为它们没有未来数据,标签为NaN
df.dropna(subset=['structure_label'], inplace=True)
return df
这个逻辑里最大的一个细节是标准化。不同品种的价格绝对水平差异很大,比如股指和农产品价格完全不在一个量级,直接用固定百分比阈值并不科学。我习惯用一段时间的价格运行区间或ATR做分母,把涨跌幅转成“相对波动水平”,这样标签才对不同品种和市场阶段有可比性。
实际使用时,我还会加上几个约束条件防止标签太粗糙。比如把“最大回撤小但涨幅也小”的行情标成震荡;把“累计涨一点但过程剧烈震荡”的行情通过路径判断排除出趋势类。这个需要你根据自己交易的品种慢慢调,不要指望一次到位。
2.3 数据源选择与样本量的现实约束
做这类研究,数据源我建议优先选择自己实际交易的品种和周期。如果只想熟悉流程,先用指数日线数据练手最合适,因为指数数据连续性好、没有主力合约切换的跳空问题。做商品期货时要注意主力合约会换月,价格序列里有不连续的跳空,需要额外处理。
样本量是个很现实的问题。单品种日线数据十几年也就三四千根,标签去掉末尾缺失后能用的可能只有两千多行。随机森林对这种规模的数据是可以训练的,但不能把特征维度搞得太高,否则容易抓到噪声。我自己的经验是,刚开始做研究时设定200到300个特征以内,特征数量宁可少而精,也不要盲目堆砌。如果真想要更多样本,可以切换更小的周期,比如小时线,但随之而来的是噪声增大和计算开销上升,需要权衡。
3. 特征工程:从K线里提炼“结构”的完整配方
任务定义清楚之后,特征工程就是整个项目里最花时间的部分。市场结构不是一个可以直接观察的量,它隐藏在价格走势、成交量、K线形态和时间特征里。随机森林虽然不像线性模型那样依赖手工特征交互,但你喂进去什么特征,它就只能看到什么信息。
3.1 特征池的整体结构画像:四类信息缺一不可
我习惯将特征分为动量类、波动率类、量价类和时间类。这四个维度合在一起,基本覆盖了描述市场结构所需的信息。
动量类特征描述价格在某个周期内的变化方向和力度,比如不同周期的收益率、均线之间的偏离程度。趋势结构的最直接表现就是动量的一致性。如果5日、20日、60日收益方向一致,市场处于趋势概率高;如果方向混轮,震荡概率高。
波动率类特征描述价格震荡的剧烈程度,比如ATR、收益率的滚动标准差、布林带宽度。趋势和震荡常伴随不同的波动水平,低波动收敛之后往往是趋势的起点,高波动往往出现在趋势的中后段。
量价类特征描述成交量和价格之间的关系。量增价涨、量缩价跌等组合能帮助识别趋势的健康程度和突破的有效性。虽然随机森林没有能力理解因果,但量价关系中的统计规律它是能抓到的。
时间类特征用来捕捉周期性结构,比如星期几效应、日内时段规律。日线级别做星期特征会有一定作用,小时级别则需要加入小时特征。
3.2 pandas特征构造示例:从原始数据到特征矩阵
这里给出一段可复用的特征构造代码,我用它处理日线数据的原始OHLCV字段:
python复制def build_features(df, lookbacks=[5, 10, 20, 60]):
df = df.copy()
for lb in lookbacks:
# 动量类:不同周期收益率
df[f'ret_{lb}'] = df['close'].pct_change(lb)
# 波动率类:滚动标准差,再除以价格做归一化
df[f'std_{lb}'] = df['close'].rolling(lb).std() / df['close']
# K线位置:当前收盘价在过去lb根K线区间中的相对位置
roll_high = df['high'].rolling(lb).max()
roll_low = df['low'].rolling(lb).min()
df[f'close_pos_{lb}'] = (df['close'] - roll_low) / (roll_high - roll_low)
# 量价相关:成交量变化率
df[f'volume_change_{lb}'] = df['volume'].pct_change(lb)
# 均线发散程度:用快慢均线差再标准化
df['ma_5_20_ratio'] = df['close'].rolling(5).mean() / df['close'].rolling(20).mean() - 1
df['ma_20_60_ratio'] = df['close'].rolling(20).mean() / df['close'].rolling(60).mean() - 1
# K线实体和影线比例
df['body_ratio'] = (df['close'] - df['open']).abs() / (df['high'] - df['low'])
df['upper_shadow'] = (df['high'] - df[['close', 'open']].max(axis=1)) / (df['high'] - df['low'])
df['lower_shadow'] = (df[['close', 'open']].min(axis=1) - df['low']) / (df['high'] - df['low'])
# 时间特征
df['weekday'] = df.index.dayofweek
return df
需要特别提醒一点:这里的特征都是用截至当前时刻的数据计算的,没有用到未来信息。这是机器学习模型能否在实盘中复制表现的底线。许多看起来很聪明的特征,如果无意间用到了未来均值、未来最大值、未来最低值做归一化,回测会好得离谱,实盘则完全失效。
3.3 特征重要性与特征筛选的实践经验
随机森林训练完成后,可以直接用feature_importances_查看每个特征对模型预测的贡献。这个属性做粗略筛选挺好用,但要小心使用。
我见过很多人根据特征重要性一次性删掉一半特征,然后重新训练,这其实有风险。随机森林的特征重要性有偏好,连续型特征或高基数特征容易被赋予更高重要性,不代表它们真的好用。更稳妥的做法是:先保留所有特征训练一次,主要看类别下排序靠前的特征是否符合业务逻辑。
我在这里用某种品种的日线数据测试,常会发现几个规律:中期动量类特征对趋势/震荡分类贡献最大;波动率类特征对高波动/低波动分类特别重要;K线位置类特征在震荡转趋势的临界点上提供辅助信息。如果某个特征在业务逻辑上说不通,但重要性极高,反而要警惕是不是数据泄露。
3.4 那些让我吃过亏的特征陷阱
第一个坑是使用了全局统计量做归一化。如果对全样本的价格序列计算均值和标准差,再用来归一化前半段的数据,相当于让过去的数据“偷看”了未来的分布。这个问题在数据探索阶段通过可视化看不出来,但换成前向验证时性能会明显下降。正确做法是使用滚动窗口统计量,或者干脆不对特征做全局标准化,因为随机森林本来不需要这一步。
第二个坑是标签和特征高度重叠。如果标签用了未来20根K线的收益,而特征里也包含了一个以20日均线为分母计算出来的变量,它们虽然不会造成严格意义上的未来函数,但会让特征与标签高度相关,训练集上的指标很漂亮,实盘中一到结构切换就会失效。
第三个坑是去掉NaN时没有对齐索引。用pandas做dropna后,如果特征矩阵和标签向量的索引错位,模型学的就不是你想要的那组对应关系。这种错误很隐蔽,回测中几乎发现不了,只有自己仔细检查样本对齐才能避免。
4. 随机森林训练细节:如何避免一套回测很爽、实盘白搭的参数
训练本身并不复杂,复杂的是一不小心就会掉进时间序列训练里最常见的坑。第4节我会把数据划分、超参数、类别不平衡都拆开讲,并且给出可复现的代码框架。
4.1 时间序列的数据划分:不能像普通分类那样随机打散
金融数据最大的特点是时间顺序本身包含信息。用随机打散的K折交叉验证来评估交易模型,是我见过许多初学者犯的最严重的错误。随机打散后,训练集里会出现未来的数据,测试集里会有过去的样本,模型等于“偷看”了未来,评估结果自然虚高。
正确做法是使用时间序列切分,始终保持训练集时间在前、验证集时间在后。Sklearn提供了TimeSeriesSplit,这里我用它来实现前向验证:
python复制from sklearn.model_selection import TimeSeriesSplit
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, confusion_matrix
X = feature_matrix
y = label_encoded
tscv = TimeSeriesSplit(n_splits=5, gap=20)
for fold, (train_idx, val_idx) in enumerate(tscv.split(X)):
X_train, X_val = X.iloc[train_idx], X.iloc[val_idx]
y_train, y_val = y.iloc[train_idx], y.iloc[val_idx]
model = RandomForestClassifier(
n_estimators=500,
max_features='sqrt',
min_samples_leaf=50,
class_weight='balanced_subsample',
n_jobs=-1,
random_state=42
)
model.fit(X_train, y_train)
y_pred = model.predict(X_val)
acc = accuracy_score(y_val, y_pred)
print(f'Fold {fold}: accuracy = {acc:.3f}')
这里的gap参数非常重要。由于标签是用未来20根K线构造的,训练集末尾的样本和验证集开始的样本在时间上存在重叠。如果不设置gap,验证集的标签就包含了训练集末尾时段的信息,从而造成泄漏。我设置gap=20就是让训练集和验证集之间隔开一段空白,避免这种重叠污染。
4.2 随机森林关键超参数:按金融数据的噪声特点去调
随机森林常用参数不多,但每个参数背后都有一个需要理解的逻辑。
n_estimators控制树的数量。并不是越多越好,增加到一定程度后边际收益会递减,还会拖慢推理速度。500棵在日线数据上已经完全够用,如果特征数很多可以增加到1000。
max_features控制每次分裂时随机抽取的特征数量。默认是sqrt,对分类任务通常够用。特征数少时可以放宽到0.3到0.5,让每棵树看到更多信息。
min_samples_leaf是我认为最需要重视的参数,它直接控制叶子节点的最少样本数。金融数据噪声大,如果叶子节点样本太少,树会学得过于细致,几乎每个训练样本都各自为政,泛化能力会很差。我常用的范围是50到200,具体取决于总样本量。这个参数被我视作随机森林在金融数据上最重要的防过拟合旋钮。
max_depth要不要限制?随机森林本身通过样本扰动和特征扰动降低了树之间的相关性,对深度的限制不像单棵决策树那么敏感。我通常不刻意限制,而是通过min_samples_leaf来控制树的复杂度。
class_weight='balanced_subsample'是在每棵树的抽样过程中自动调整权重,对处理类别不平衡比全局class_weight更平滑。这个选项尤其在趋势样本远少于震荡样本时很有用。
4.3 类别不平衡问题:别急着用SMOTE
在结构预测任务里,震荡样本往往远多于趋势样本。比如一个震荡市占六成、趋势市占四成的品种,直接训练出来的模型会对震荡类有天然偏好,预测趋势时的召回率会偏低。
但我不建议一上来就使用SMOTE这类过采样方法。金融时序里相邻样本高度相关,SMOTE会通过插值生成“合成K线上下文”,这些合成样本实际上在原始数据中从未出现过,很容易引入虚假规律。我首选的方法是通过class_weight和调整预测阈值来平衡。如果趋势类实在太少,可以适当增加历史数据的跨度,或者把上涨趋势和下跌趋势合在一起作为“趋势”类,先做二分类,再按方向做二次判断。
4.4 使用预测概率而不是硬分类结果
随机森林的训练目标是分类,但在实盘交易里,我几乎不使用predict()直接输出的标签,而是使用predict_proba()输出的各类别概率。原因很简单:模型输出“有55%概率处于震荡”和输出“有95%概率处于震荡”在交易决策上是完全不同的信号。
对于二分类问题,我不会固定用0.5做阈值,而是统计验证集上模型输出的概率分布,选取能让F1分数或业务收益最优的分位数。比如历史样本中模型预测“趋势概率”超过0.7的情况只占20%,而这段时间里真实趋势的比例确实明显高于低概率区间,那么0.7就是更合适的入场阈值。这种做法本质上是在做概率校准的近似处理,虽然粗糙,但在样本量有限时比复杂的Isotonic回归更稳定。
5. 把模型输出接进策略:三种我实际测试过的用法
模型训练完成后,真正困难的部分才刚开始——怎么把一个机器学习的输出转化为稳定的交易决策。直接拿预测标签当买卖信号通常不可靠,因为模型的分类精度有限,收益结构也不对称。我尝试过几种不同的接入方式,下面这三种最值得参考。
5.1 用法A:作为趋势策略的“结构过滤器”
趋势跟踪策略最大的软肋是震荡行情里反复止损。常规的均线突破或通道突破策略,在震荡市里会产生大量假突破信号,每次突破都开仓,然后价格又回到区间内,止损离场。两三波下来,趋势带来的利润可能被震荡磨损掉一大部分。
随机森林此时可以作为过滤器使用。趋势策略本身只负责生成方向和入场信号,在开仓之前,额外检查随机森林对当前市场结构的预测。如果模型判断当前处于震荡状态的概率超过某个阈值,就跳过趋势信号,不入场。这样能过滤掉大量低质量的震荡行情。
我在实践中测试了一组日线均线突破策略,加入结构过滤后交易次数下降约四成,而单笔平均盈亏比明显提升。原因是过滤掉的交易多数是震荡市里的假突破,这些交易本身期望值为负。模型的预测准确率不需要特别高,只要它能在“是否处于趋势状态”这个问题上比随机猜测有所提升,策略整体表现就能改善。
5.2 用法B:波动结构识别用于仓位管理
市场结构预测不仅可以判断方向状态,也可以预测波动区间。比如构造一个“未来N根K线波动偏高还是偏低”的二分类标签,用随机森林训练后输出波动状态概率。
这个预测结果适合用来做仓位管理。在风险平价框架下,头寸大小通常和目标波动率挂钩。公式大致是:目标头寸 = 风险预算 / (合约乘数 × 价格 × 预期波动率)。如果你对未来的预期波动率估计得越准确,仓位控制就越精确,回撤就越可控。
比如在一段低波动收敛行情中,模型预测未来波动会明显放大,那么即使当前价格看起来很平稳,也应该降低仓位,而不是因为短期波动小就加倍下注。这种“逆直觉”的仓位控制恰恰能帮助躲过很多黑天鹅式的跳空。
5.3 用法C:状态切变预警——多数人忽略的一个场景
前两种用法分别服务方向策略和仓位管理,第三种用法是用概率变化做状态切变预警。
随机森林对某一状态的预测概率不会突然从0.1跳到0.9,它通常有一个渐变过程。如果连续几天模型对“趋势状态”的概率持续上升,说明市场可能正在从震荡收敛转向趋势扩张。在这种时候,即使当前趋势策略尚未出现入场信号,也值得密切关注突破方向。
我把这种概率的上升速度作为另一个因子,叠加到入场判断里。比如当震荡转趋势的预警概率超过0.6,同时价格已经站上20日均线,我会比平时更早地尝试跟随趋势。预警信号本身不构成完整交易逻辑,但它可以帮助交易者从被动等待转为主动观察。
5.4 回测框架中容易被忽略的三处细节
接入策略后,回测框架对机器学习模型的评估有很大影响。第一个细节是信号时间对齐。如果模型使用今天的收盘数据计算特征并预测明天,那么最早也只能在明天开盘后执行交易,不能在今天收盘价成交。很多人在这里忽略了一根K线的延迟,导致回测绩效虚高。
第二个细节是交易成本。结构过滤器虽然减少了交易次数,但每一次触发信号仍然要支付手续费和滑点。我发现许多人做回测时对交易成本估计过于乐观,尤其是期货和加密市场,滑点可能远远大于手续费本身。给自己的回测加上一个保守的滑点假设,可以避免把成本敏感的策略误判为有效。
第三个细节是模型更新频率。市场结构会随宏观环境变化而缓慢漂移,随机森林模型不可能永远有效。我在回测中会模拟每隔一定周期用最新数据重新训练模型,观察策略绩效是否还能维持。如果重新训练后的表现明显下降,说明模型可能没有真正学到稳定的结构,而是记住了历史噪声。
6. 复盘:随机森林市场结构预测的真正边界在哪里
写完主体流程后,我想专门用一节来复盘那些“模型看似有效、实盘却打了折扣”的情况。这些教训是我花了不少真金白银换来的,也应该是你回测完看到漂亮曲线后最需要冷静思考的问题。
6.1 精度高不等于能赚钱:金融预测的三个反直觉现象
金融预测领域有三个反直觉现象,在入行初期很容易被忽略。
第一个现象是预测准确率提升不等于收益提升。假设原策略在震荡市里每次交易期望亏损1%,趋势市里每次交易期望盈利3%。即使模型能把震荡识别准确率从50%提升到60%,如果不结合具体的交易成本和盈亏比计算,你无法判断这10%的提升最终会带来多少净收益。因此不要以分类准确率作为模型选择的唯一标准,而要以策略的收益指标作为最终评估目标。
第二个现象是模型在特定行情下会突然失效。市场结构的定义依赖于历史数据的统计特征。一旦市场本身的运行模式发生变化,比如某品种从低波动高成交变成高波动低成交,模型在旧数据上学习到的特征分布就不再适用。所以模型需要持续监控和重新训练,而不是一次训练后永久使用。
第三个现象是少数极端样本可能主导整体收益。趋势类样本本身占比不高,趋势行情带来的收益又往往集中在一两波大行情里。随机森林在训练时会尽量均衡所有样本,反而可能把那些对收益贡献最大的少数极端行情当作噪声忽略掉。这也是为什么模型回测结果不错,但实际收益曲线却平庸的原因之一。
6.2 隐蔽的未来函数可能藏在四个地方
我在反复复盘中总结出四个隐蔽的未来函数来源,它们大多不会导致明显报错,却会让回测失真。
一是标签构造边界错误。用未来20行数据构造标签时,如果shift写错参数,当前样本的标签就会包含未来行情信息。这类错误很难被直观检查发现,需要人工抽查几条样本的特征和标签对应关系。
二是滚动标准化泄漏。如果对全样本计算滚动均值或标准差时窗口设置不当,或者使用了包含未来数据的中心化均值,特征值本身就会携带未来信息。
三是样本重叠引发的乐观偏差。标签用未来N根K线生成,如果N比较大,相邻样本的标签会高度相似,模型会在验证时表现得异常好。解决方法是设置gap,或者每隔几根K线采样一个样本,减少样本间重叠。
四是复权处理不当。某些数据接口提供的前复权价格会随最新价格变化而整体调整,如果使用前复权全序列做训练,等于把未来除权信息引入了历史数据。我建议要么使用不复权价格,要么在每次更新时严格区分历史价格和实时价格。
6.3 从随机森林出发,我建议继续尝试的方向
随机森林不是这套方法的天花板。当流程跑通之后,我会建议从以下几个方向继续演化。
一个方向是基于树模型的集成扩展,把随机森林换成梯度提升树模型,在同类特征下往往能获得更精细的预测效果。另一个方向是把预测输出作为新的输入特征,与已有的规则因子拼接,让“结构预判”成为更大策略体系中的一环。也可以尝试构建多个不同周期的结构预测子模型,再通过投票或加权方式融合,提升对整个市场状态的判断稳定性。
我自己现在的默认配置是,先用随机森林跑通一个可解释的基线,再用这个基线的预测概率去改进交易逻辑,最后才考虑更复杂的模型。因为你真正要评估的,永远不是模型用了什么算法,而是它生成的信号在扣除成本后,是否真的让策略变得更稳健。这个底层思路,无论未来机器学习工具怎么变化,应该都不会过时。
