跳转至


课程  因子投资  机器学习  Python  Poetry  ppw  tools  programming  Numpy  Pandas  pandas  算法  hdbscan  聚类  选股  Algo  minimum  numpy  algo  FFT  模式识别  配对交易  GBDT  LightGBM  XGBoost  statistics  CDF  KS-Test  monte-carlo  VaR  回测  过拟合  algorithms  machine learning  strategy  python  sklearn  pdf  概率  数学  面试题  量化交易  策略分类  风险管理  Info  interview  career  xgboost  PCA  wavelet  时序事件归因  SHAP  Figures  Behavioral Economics  graduate  arma  garch  人物  职场  Quantopian  figure  Banz  金融行业  买方  卖方  story  量化传奇  rsi  zigzag  穹顶压力  因子  ESG  因子策略  投资  策略  pe  ORB  Xgboost  Alligator  Indicator  factor  alpha101  alpha  技术指标  wave  quant  algorithm  pearson  spearman  tushare  因子分析  Alphalens  涨停板  herd-behaviour  momentum  因子评估  review  SMC  聪明钱  trade  history  indicators  zscore  波动率  强化学习  顶背离  freshman  resources  others  AI  DeepSeek  network  量子计算  金融交易  IBM  weekly  LLT  backtest  backtrader  研报  papers  UBL  quantlib  jupyter-notebook  scikit-learn  pypinyin  qmt  xtquant  blog  static-site  duckdb  工具  colors  free resources  barra  world quant  Alpha  openbb  数据  risk-management  llm  prompt  CANSLIM  Augment  arsenal  copilot  vscode  code  量化数据存储  hdf5  h5py  cursor  augment  trae  Jupyter  jupysql  pyarrow  parquet  数据源  quantstats  实盘  clickhouse  notebook  redis  remote-agent  AI-tools  Moonshot  回测,研报,tushare 

others »

[0721] QuanTide Weekly


本周要闻回顾

  • 上交所放大招,将发布上证全收益指数!
  • 私募巨头发声,大跌不是我们干的!
  • 交易所加强异常交易监管...

本周 Po 文

  • 基于 XGBoost 的组合策略...
  • 不能求二阶导的 Metrics,不是好的 objective
  • 全球大蓝屏!作为量化人,我的检讨来了
  • 不要去写书 除非是要与你的灵魂对话
  • 问薪无愧!自学量化大纲有这 75 页就够了

本周要闻回顾

  • 上交所放大招,将发布上证全收益指数!为便利投资者观察上海证券市场整体收益情况,上海证券交易所与中证指数有限公司决定自 7 月 29 日起正式发布上证综合全收益指数实时行情,同时将指数代码和简称分别调整为“000888”和“上证收益”。

  • 私募巨头发声,大跌不是我们干的!本周DMA 持股市值大降 2000 亿元,幻方、衍复相继发声,认为量化投资具有长期优势,不应被视为导致市场低迷的主要原因。2023年以来,DMA策略收益颇为优秀,成为私募的主要盈利策略,也因此遭到市场诟病。


  • 交易所持续加强异常交易监管,深交所本周共对 54 起证券异常交易行为采取了自律监管措施,上交所本周对个别波动幅度较大的可转债进行重点监控,对 49 起拉抬打压、虚假申报等证券异常交易行为采取了书面警示等监管措施。 上期所发布《上海期货交易所异常交易行为管理办法(修订版)》将于今年10 月 25 日实施。

  • 比特币盘中突破 67000 美元

  • 半年猛增 50%,中短债基金总体规模已超 8000 亿元。汇金二季度继续增持 ETF,申购金额或者接近 3000 亿元。股票型 ETF 规模年内增长超 4200 亿元,宽基 ETF 成为增长主力。

  • 受Trump和微软蓝屏事件双重打击,特斯拉周五盘中一度大跌近5%,最终收跌4.02%。

下周重要日历

  • 周一,央行将公布 7 月 LPR 报价。市场预期三季度末或四季度可能迎来降准或降息的新窗口,以进一步支持经济稳步增长

  • 周一起,融券保证金比例上调至 100%,私募证券投资基金参与融券的保证金比例由不得低于 100%上调至 120%。值得注意的是,在证监会宣布上述消息后,A 股市场融券规模已开始连续下滑。Wind 数据显示,截至 7 月 18 日,融券余额已减少至约 295 亿元,创出最近 4 年新低。

  • 7 月 24 日起发行超长期特别国债,本期国债为30年期固定利率附息债,竞争性招标面值总额550亿元

  • 本周将有三支新股发行,分别是力聚热能、博实结、龙图光罩。

  • 本周五将迎来成品油调价窗口,按测算,对应的国内汽柴油零售价应下调50元/吨。
信息来源:证券日报等,通过Tushare.pro接口综合汇编。

本周Po文

这周我们共发表5篇文章。《基于 XGBoost 的组合策略...》等两篇详细讲解了机器学习构建组合策略的框架和常见问题。


文章要点与结论:

  1. 通过两阶段式方案实现多因子、多资产的组合策略构建。第一阶段基于XGBoost构建多个多因子单标的模型,第二阶段通过经典的均值方差方案进行组合优化。
  2. 应该基于分类而不是回归来构建机器学习模型。基于时序的价格预测几乎没有意义(价格序列不具有平稳性)。
  3. 分类模型是以多因子为特征,以未来一周期的涨跌幅度digitize化作为标签来训练构建的。
  4. 对XGBoost模型而言,基本上无须考虑因子标准化。因子标准化甚至有可能引入副作用;但另一方面,因子标准化也有利于正则惩罚项。
  5. 损失函数与度量函数的差别在于,损失函数要能计算梯度。MAPE函数的不可导性决定了它不适合作为损失函数。
  6. 在金融领域,相对误差比RMSE更有意义,因此我们介绍了SMAPE -- 这是一个可作为损失函数的函数。

这两篇文章我们也集结后,发在本文末尾。

在这一期的量化工具专栏中,我们发表了获得NASA奖章的男人,带来了这些IPython技巧。IPython是非常轻量的交互式编程工具,尽管它的所有功能都可以在Notebook中找到,但它更轻,但仍然长袖擅舞,颇有飞燕之姿。

不要去写书 除非是要与你的灵魂交流中,我们披露了《Python高效编程实践指南》出版过程中的一些冏事。这本书会对量化人构建稳健的交易系统非常有帮助。


话音刚落,周五就发生了Windows蓝屏事件,正是因为CrowedStrike缺乏完善的CI/CD,才导致这一事件发生。而CI/CD正是本书详细介绍的内容之一。

问薪无愧,最全威的量化自学路线图中,我们介绍了Algos.org编写的这份量化自学大纲。

我们也将在8月底前,推出自己的量化自学路线图。除了更好的本地化之外(英文版中,一些工具、网站和数据源对国内市场不支持),我们还将更清晰地理出从入门到精通、从小白到不同的岗位的学习路径。

在大纲没有出来之前,大家可以暂时参照这份路线图:

75%


基于XGBoost构建多因子策略

如何在投资组合策略中运用上机器学习方法? 最近,我们翻了下之前存过的论文,决定对《A portfolio Strategy Based on XGBoost Regression and Monte Carlo Method》这篇论文进行解读。

这是论文抽象出来的一个基本框架图。

50%

这个框架能解决的什么问题呢?我们知道,在一个投资组合策略中,要重点考虑的第一个问题是,如何从给定的 universe 中,选择一部分股票纳入策略股票池;其次要考虑,这部分股票的持仓如何分配,使之在这个组合上,达到风险收益比最高。


后一部分,最经典的方法就是运用 MPT 理论,寻找有效投资前沿。这里既可以用凸优化求解,也可以使用蒙特卡洛方案。这一部分,我们之前有一个系列文章:投资组合理论与实战,从基本概念到实战细节,都讲得非常清楚,这里就不详述了。

如何从 universe 中选择股票进入股票池? 这在单因子模型中比较容易解决,就是选择因子分层中,表现最佳的那个分层 (tier) 的股票进入股票池。各标的的权重可以按因子载荷来分配,也可以使用 MPT 方法。

但如何在多因子模型中选择股票进入股票池?这一直是一个难题。我们常常提到的 Barra 模型也只是一个风控模型,并不能选择出最佳的股票池出来。


论文的思路是,将股票的纳入选择看成一个回归问题,即,通过多因子的训练,找出最能被模型预测的那些股票进入股票池

作者给出的结果是,在 2021、2020 和 2019 年,龙头股票投资组合的回报率分别为 27.86%, 6.20%和 23.26%。不过,作者并没有给出基准比较,此外,也没有深入分析,如果这些结果有超额收益的话,这些超额是来自于 MPT 呢,还是来自于 XGBoost。

这也是我们要对这篇论文进行解读的地方。希望通过我们的解读,你也可以学习到,究竟应该如何分析他人的论文,从中汲取正确的部分。

错误的回归

论文中使用的是 XGBoost 回归模型。这可能是值得商榷的地方。在资产定价模型中,我们要预测的是股票在截面上的强弱,而不是在时序上的走势

论文作者这里使用的方法是训练一个回归模型,从而使得它能较好地预测次日(或者后面一段时间的走势)。

R50

右图是论文作者得到的结果之一。看起来模型能比较完美地预测次日走势。


显然,由于 XGBoost 回归模型本身没有预测股票强弱的能力,所以,即使通过回归模型找出了完美拟合的股票,也没有任何意义。因为一支下跌中的股票,也可能被完美地拟合出来。所以,论文中提到的收益,即使有超额,很可能也来自于 MPT 理论。

但是,作者仍然给出了一个如何通过 XGBoost 来寻找多因子模型中表现最佳个股的线索。我们只需要把它改造成一个分类模型,然后通过分类模型,筛选出表现最好的股票就可以了

L50

训练集中的 X 部分不用改变,但我们需要重新设定标签,即 y 部分。对给定的因子\(X_i\),对应的\(y_i\)需要能反映是上涨或者下跌。如果有可能,我们可以将标签设置为 5 类,-2 表示大跌,2 表示大涨,中间部分以此类推。

然后构造分类器进行训练。训练完成后,通过模型预测出来属于大涨标签的,我们就放入股票池,此时可以平均分配权重,也可以通过 MPT 理论来进行优化。

端到端训练及新的网络架构

论文作者使用的框架是两阶段式的,即先选择股票进入策略池,再通过 MPT 优化权重。


但即使是在第一阶段,它仍然是两段式的。每次进行训练时,它都只使用了一个标的的多因子数据。因此,如果 universe 中有 1000 支标的,就要训练出 1000 个模型(这是论文中暗示的方法,也可以考虑一个模型,训练 1000 次)。

这么做的原因是技术限制。XGBoost 只支持二维输入。如果我们要使用多个标的的多个因子同时进行训练,就必须使用 panel 格式的数据,或者将多个标的的多个因子进行一维展开。但如果标的数过多,展开后的训练会很困难。

也就是,由于技术限制,要么进行单因子的多标的同时训练,要么进行多因子的单标的训练。

但是,论文作者在这里给出了一个方法,就是你可以分别训练多个标的各自的模型,然后同样分别进行预测,然后再通过 MAPE 进行评估。当我们改成分类模型之后,可以简单地看分类结果,也可以结合分类的 metric 评估(在时序维度上的),选择准确性和分类结果都好的标的,纳入策略股票池。

损失函数与度量函数

接下来,我们要分析 MAPE 这个函数在论文中的使用。以此为契机,适当深入一点机器学习的原理,讲以下两个知识点:

1. 损失函数和度量函数
2. XGBoost模型,因子数据是否要标准化

损失函数与度量函数

在机器学习中,有两类重要的函数,一类是目标函数(objective function),又称损失函数(loss function);一类是度量函数(metrics)

75%

损失函数用于模型训练。在训练过程中,通过梯度下降等方法,使得损失函数的值不断减小,直到无法继续下降为止,模型就训练完成。

训练完成之后的模型,将在test数据集上进行测试,并将预测的结果与真实值进行对比。为了将这个对比过程数值化,我们就引入了度量函数(metrics)

在sklearn中,提供了大量的损失函数和度量函数。下图列举了部分Sklearn提供的损失函数和度量函数:


可以看出,度量函数的个数远多于损失函数,这是为什么呢?

在论文中,论文作者并没有披露他通过xgboost训练的具体过程,只是说直接使用了xgboost的database,这个表述有点奇怪,我们可以理解为在参数上使用了XGBoost的默认值好了。


但是他重点提到了使用MAPE,从过程来看,是在把MAPE当成度量函数进行事后评估。

在XGBoost中,如果没有特别指定目标函数,那么默认会使用带正则惩罚的RMSE(rooted mean square error)函数。RMSE也可以作为度量函数,在论文中,作者没有使用RMSE作为度量函数,而是选择了MAPE(mean absolute percentage error),原因何在?如果MAPE在这个场景下比RMSE更好,又为何不在训练中使用MAPE?

看上去无论目标函数也好,度量函数也好,都要使得预测值与真实值越接近越好。既然都有这个特性,为什么还需要区分这两类函数呢?

要回答这些问题,就要了解XGBoost的训练原理,核心是:它是如何求梯度下降的。

XGBoost:二阶泰勒展开

XGBoost是一种提升(Boosting)算法,它通过多个弱学习器叠加,构成一个强学习器。每次迭代时,新的树会修正现有模型的残差,即预测值与真实值之间的差异。这个差异的大小,就由目标函数来计算。

在XGBoost中,多个弱学习器的叠加采用了加法模型,


即最终的预测是所有弱学习器输出的加权和。这种模型允许我们使用泰勒展开来近似损失函数,从而进行高效的优化。

XGBoost对目标函数的优化是通过泰勒二阶展开,再求二阶导来实现的。使用二阶导数,XGBoost可以实现更快速的收敛,因为它不仅考虑了梯度的方向,还考虑了损失函数的形状。

\[ f(x) \approx f(a) + f'(a)(x-a) + \frac{f''(a)}{2!}(x-a)^2 \]

正是由于XGBoost内部优化原理,决定了我们选择目标函数时,目标函数必须是二阶可导的。

RMSE是二阶可导的,但MAPE不是:MAPE从定义上来看,它的取值可以为零,在这些零值点附近连一阶导都不存在,就更不用说二阶导了。下图是MAPE的公式:

$$

\text{MAPE} = 100\frac{1}{n}\sum_{i=1}^{n}\left|\frac{\text{实际值} - \text{预测值}}{\text{实际值}} \right| $$

当预测值与实际值一致时,MAPE的值就会取零。

如何选择目标函数?

选择MAPE作为度量函数,不仅仅是便于在不同的模型之间进行比较,在金融领域它还有特殊的重要性:


我们更在乎预测值与真实值之间的相对误差,而不是绝对误差。在交易中,百分比才是王者。正因为这个原因,如果在训练时,能够使用MAPE作为目标函数,这样预测出来的准确度,要比我们通过RSME训练出来的准确度,更接近实际应用。

这就是在具体领域,我们改进算法的一个切入点。已经有人发明了被称为SMAPE的损失函数,它的公式是:

$$

\text{SMAPE} = \frac{100}{n} \sum_{t=1}^n \frac{\left|F_t-A_t\right|}{(|A_t|+|F_t|)/2} $$

到目前为止,sklearn还没有提供这个函数,但我们可以自己实现,并通过sklearn的make_scorer方法接入到sklearn系统中:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from sklearn.metrics import make_scorer

def smape(y_true, y_pred):
    return np.mean(2.0 * np.abs(y_pred - y_true) / 
           (np.abs(y_true) + np.abs(y_pred)))

smape_scorer = make_scorer(smape, greater_is_better=False)

# 使用举例:在GridSearchCV中使用
grid_search = GridSearchCV(estimator=model, 
                           param_grid=params, 
                           scoring=smape_scorer)

Question: 既然训练中不能使用MAPE,那么论文在测试中,又为何要使用MAPE呢?

答案其实很简单,是为了便于在多个模型之间进行比较。在论文作者的算法中,每支股票都必须有自己的模型。由于每支股票的绝对价格不一样,因此,它们的RSME是不一样的,而MAPE相当于一个归一化的指标,从而可以在不同的模型之间进行比较,最终选择出误差最小的模型对应的股票,纳入策略股池。

但我们前面也提到过,论文作者的这个模型没有意义,改用分类模型会好一些。如果改用分类模型的话,损失函数也不再是RSME了,度量函数也不能是MAPE了。


标准化

论文中还提到,在训练之前,他将因子数据进行了标准化。

实际上,这也是没有意义的一步。因为XGBoost是决策树模型,它是通过特征值的比较来进行分裂和划分数据的,显然,分裂点的比较,并不依赖数据的量纲,因此,标准化就没有意义,反而可能带来精度损失问题,得不偿失。

Hint

如果因子数据使用单精度浮点数储存,那么如果两个小数只在小数点的第7位数字之后才产生差异,这两个数字在比较时,实际上是一样的。如果我们在进行标准化时,把两个原来有大小差异的数字,缩放到了只在第7位数字之后才出现差异,就产生了精度损失。

当然,事情也不能一概而论。XGBoost使用正则化来控制树的复杂度,包括对叶节点的权重进行L2正则化。如果你在训练XGBoost模型时,损失函数加了正则惩罚,而特征未经过标准化,正则化的效果可能会变差。

另外,论文中的方法是,每支股票一个模型,但如果只用一个模型,但拿1000支股票的数据来训练1000次呢?显然,这个时候,就必须要提前进行标准化了。


否则,收敛会很困难(当然,即使使用了标准化,也不保证就能收敛。能否收敛,要看众多股票是否真的具有同样的特征到标签的映射关系)。这并不是XGBoost的要求,而是根据我们使用XGBoost的方法带来的额外要求。

结论

对多数量化人来说,我们不可能像陈天奇那样自己撸一个机器学习框架出来,因此,要用同样的模型,做出更优的结果,就只能在数据标注、目标函数、评估函数和参数调优等方面下功夫了。这往往既需要有较深的领域知识,也要对具体的模型原理有一定的了解。

版权所有: 量化风云/QuanTide 公众号