跳转至

量化研究

借助 torchmetricsCompositionalMetric 将越大越好的指标作为损失函数

在量化研究中,我们可以使用诸如 IC 一类的指标来衡量信号的质量。若将 IC 作为损失函数,我们自然是希望其值越大越好。但是,模型的优化过程总是朝着损失函数越小的方向进行的,因此我们需要将 IC 取反后作为损失值,使得模型朝着 IC 越大的方向优化。

本文介绍了一个便捷的方法,借助 torchmetricsCompositionalMetric 将越大越好的指标作为损失函数。

Python
pred = torch.tensor([1, 2, 3, 4]).to(torch.float32)
target = torch.tensor([2, 3, 5, 10]).to(torch.float32)
print("原始相关系数:", np.corrcoef(target, pred)[0, 1])
loss_fn = 0 - PearsonCorrCoef()
print("损失函数:", loss_fn(pred, target))
Text Only
原始相关系数: 0.9431191251430151
损失函数: tensor(-0.9431)

因子半衰期

对于一个时间序列,我们可以构建一个逐渐衰减的时间序列模型来估计其半衰期。本文介绍了两个模型,用于估计一个时间序列的半衰期。

在量化研究中,了解各个因子的衰减情况,可以更有效地动态分配因子权重,以适应市场变化。

image-20240612194448624

计算部分相关系数矩阵

本文使用相关系数的矩阵表达形式,实现了计算部分相关系数矩阵的加速算法,并实证检验了三种计算相关系数矩阵方法的运行速度。

  • 在计算部分相关系数矩阵时,自定义的加速算法 相比 Pandas .corr() 方法提速约 2180 倍,比 Numpy .corrcoef() 方法提速约 115 倍。
  • 在计算全部相关系数矩阵时,Numpy .corrcoef() 方法比自定义的加速算法略快 \(10\%\),比 Pandas .corr() 方法快约 20 倍。

Pandas 根据日期进行分组

问题背景:有一个分钟级别索引的数据框,需要根据日期进行分组聚合计算。

  1. 简单的 .groupby('datetime') 无法实现按日期分组。
  2. .groupby(pd.Grouper(level='datetime', freq='D')) 会为原始数据中不存在的日期填充空值(例如,在股票数据中,周末、节假日等非交易日会被填充为空值)。
    • 如果分组后调用的是 .mean(),则会出现这个问题。
    • 如果分组后调用的是 .transform('mean'),则不存在这个问题。

本文记录了可以正确根据日期进行分组的方法。

image-20231008235016433

Pandas 向前与居中滚动计算

Pandas 中的 rolling 默认是向后(也就是向上)获取滚动窗口,如果需要向前(也就是向下)或者居中(也就是同时向上和向下)获取滚动窗口,则可以分别使用 pd.api.indexers.FixedForwardWindowIndexercenter=True 来实现。

本文还使用了 .shift(-1) 实现向前或者居中获取滚动窗口,并对比了这种方法与上述方法所得结果的差异。

data forward_using_FixedForwardWindowIndexer forward_using_shift center_using_center center_using_shift
0 1.0 3.0 3.0 3.0 3.0
1 2.0 2.0 2.0 3.0 3.0
2 NaN 4.0 4.0 6.0 6.0
3 4.0 9.0 9.0 9.0 9.0
4 5.0 5.0 NaN 9.0 NaN

使用 Web Scraper 爬取私募排排网的基金数据

私募排排网的数据仅针对部分人群开放,因此在获取数据时有诸多不便。例如,网站需要用户登录才能访问、数据 CSS 样式类别名称被加密等,这些障碍使得我们无法通过常规的爬虫手段方便地获取数据。

本文尝试了多种方法爬取私募排排网的数据,包括 selenium、浏览器工作流自动化的 Automa 插件和嵌入在浏览器开发者工具的 Web Scraper 插件。最终可行且易用的方法是使用 Web Scraper 插件,它在制作和使用爬虫程序时都十分简便。

image-20230712014807756

Python 滚动回归

本文实现了多个资产分别在时间序列上进行滚动回归,并返回由最新系数计算得到的残差,最后将多个资产的残差结果重新聚合为多重索引的数据框。

image-20230424173801905

量化投资策略设计与分析 - CTA

本文是 2023 年 3 月 18 日和 3 月 25 日的量化投资策略设计与分析的课程笔记,这两节课介绍了 CTA 策略。

CTA 简介

CTA(Commodity Trading Advisor)策略的历史可以追溯到 1965 年。

传统意义上,CTA 的投资品种仅局限于商品期货。

经过发展,CTA 扩展到了几乎所有期货品种(比如利率期货、股指期货等)。

国内交易标的—期货品种

image-20230318114234096

量化投资策略设计与分析 - 事件驱动策略

本文是 2023 年 3 月 18 日的量化投资策略设计与分析的课程笔记,本节课介绍了常见的事件驱动策略以及实践中的注意事项。

事件驱动策略简介

事件驱动(Event Driven)属于量化投资之中的一个重要类别,涵盖投资机会广泛。广义上说,市场上任何发生的有可能与股票市场相关的新闻、事件、公告均有可能成为事件驱动的投资机会。常见重大事件包括:

image-20230318091012544

基于逐笔委托和逐笔成交数据构造高频因子

量化投资策略设计与分析的第一次作业是基于逐笔数据构造 39 个高频因子。我对高频因子的构造经验比较少,完成这个作业后的一些经验:

  1. 高频因子的数据格式是比较标准化的,但也要注意细节:例如空缺时间的填补等。
  2. 构造因子的过程本质上是数据处理的过程,常用的方法有:groupbyresampleto_datetimereindexrollingapply等。如果是非常大的数据集,应当用 numpy 等更快速的科学计算包,或者用C++

39 个因子表达式

用提供的某支证券为期不超过一周的高频数据复制 Table A2 中 39 种指标。

image-20230314121903928

LightGBM 的用法

LightGBM 是一种基于决策树的梯度提升机(GBM)算法,它是一种快速、准确的机器学习算法,可以用于分类和回归问题。

本文介绍了 LightGBM 的使用方法和代码示例,并记录了自定义损失函数、打印训练过程、迭代次数参数等问题的解决方法。

LightGBM_logo_black_text

每月底买入行业内 PB 较低的股票:一个简单的选股策略回测

本文回顾了量化投资策略设计与分析课程的一次课前练习。本练习给定的数据都比较整洁、规范,选股逻辑也比较简单清晰,是一个很好的实现选股回测的练习机会。

策略描述

策略描述

请把给定的股票数据,根据行业分类(申万一级行业),分别对每一行业的股票按 PB 由低到高分为 5 组,每月第一个交易日买入那些上月 PB 处于所在行业排名最低 20% 分位组(即 PB 由低到高排序的第一组)的股票,持有 1 个月,每月换仓一次,计算该投资组合的持仓年化收益率和夏普比率,并画出累计净值曲线。

舆情因子和 BERT 情感分类模型

本文总结了研报 舆情因子和 BERT 情感分类模型 - 华泰证券 的主要内容。

思路与框架

  1. 基于 Wind 金融新闻数据,提取其中的情感正负面标签,构建日频的新闻舆情因子。
  2. 使用回归法、IC 值分析法和分层测试法,检验新闻舆情因子。
  3. 基于已有情感标注的 Wind 金融新闻数据,测试 BERT 模型在金融情感分类任务的表现。

普通最小二乘估计的假设条件

  1. 因变量\(Y\)与自变量\(X\)之间是 线性 关系。
  2. 自变量之间 不存在多重共线性 ,即\(\left(X^{\prime} X\right)^{-1}\)存在。
  3. 误差项的 条件均值为\(0\) ,即\(E\left[u \mid X\right]=0\)
  4. 误差项之间 同方差且不相关 ,即\(E\left[u u^{\prime} \mid X\right]=\sigma^2 I_T\)
  5. \(\left(Y_t, X_t\right)\) 独立同分布
  6. 误差项是 正态分布 的。

假设 1-4 可推出:普通最小二乘估计是最小方差线性无偏估计(BLUE)。

假设 1-3 与假设 5 可推出:普通最小二乘估计具有一致性

假设 6 并不影响普通最小二乘估计是最小方差线性无偏估计,它是为了便于在有限样本下对回归系数进行统计检验。

普通最小二乘估计的方差与高斯 - 马尔可夫定理

本文计算了普通最小二乘估计的方差,并证明了高斯 - 马尔可夫定理。

普通最小二乘估计的方差:

\[ \begin{aligned} \operatorname{Var}(\underbrace{\beta^{O L S}}_ {(K+1) \times 1} \mid X)&=\sigma^2 \underbrace{\left(X^{\prime} X\right)^{-1}} _ {(K+1) \times (K+1)} \end{aligned} \]

高斯 - 马尔可夫定理(Gauss-Markov Theorem)

在线性回归模型中,如果线性模型满足高斯马尔可夫假定,则回归系数的最佳线性无偏估计(BLUE, Best Linear Unbiased Estimator)就是普通最小二乘法估计。

线性回归的普通最小二乘估计

ols

本文推导了线性回归的普通最小二乘估计量的矩阵形式,并在一元线性回归的情境下给出了求和形式的表达式。 $$ Y=X \widehat{\beta}+e $$

\[ \beta^{O L S}=\left(X^{\prime} X\right)^{-1} X^{\prime} Y \]

在一元线性回归的情境下:

\[ \beta_1^{O L S} =\frac{\overline{X Y}-\overline{X} * \overline{Y}}{\overline{X^2}-\left(\overline{X}\right)^2} \]
\[ \beta_0^{O L S} =\frac{\overline{X^2} * \overline{Y}-\overline{X} * \overline{X Y}}{\overline{X^2}-\left(\overline{X}\right)^2} \]

Python 实现多列滚动计算——以“更优波动率”为例

对单列数据进行滚动计算,可以使用常规的.rolling()

如果需要对多列数据进行滚动计算,可以考虑下面两种方法:

  1. 引入外部包numpy_ext,使用其中的rollling_apply()方法。
  2. .rolling()中加入参数method='table'

本文以方正金工发表的一篇研报中提出的计算“更优波动率”为例,实现了对多列数据进行滚动计算,并对上述两种方法总结如下:

  1. numpy_ext.rollling_apply()需要引入外部包numpy_ext,该方法接受需要进行滚动计算的多个 Series,并返回计算出的一个数组。
  2. .rolling(method='table')是 Pandas 内置的函数(需要升级到较新的版本),指定method='table'后,就可以对数据框中的多列进行滚动计算,并返回一个数据框。若返回的多列结果相同,我们只需要取出其中一列即可。
  3. .rolling(method='table')使用了engine='numba',计算速度更快。

均值方差模型的有效前沿曲线

在无做空限制的情形下推导均值方差模型的有效前沿曲线,本质上是求解一个带有等式约束的最优化问题。

\[ \begin{aligned} & \underset{w}{\text{minimize}} & & \frac{1}{2} w^{\top} \sum w \\\ & \text{subject to} & & w^{\top} e=1 \\\ & & & w^{\top} \mu=\mu_0 \end{aligned} \]

png

有效前沿曲线

检验多因子模型

\[ R_{it}^e =\alpha_i+\beta_i ^\prime \lambda_t+\varepsilon_{it},\quad t=1,2,\dots, T \]

多因子模型可以用时间序列回归、截面回归和 Fama-Macbeth 回归进行检验。它们的适用情景不同,所得到的结果也需要不同的解读。

多因子模型反映的是资产的预期收益率和因子暴露在截面上的关系。它回答了这样的问题:在同一时刻,为什么有的资产收益率高,有的资产收益率低?

多因子模型认为,每个因子有一个预期收益率,资产在某个因子上的暴露让该资产可以获得相应的预期收益。不同资产在各个因子上的暴露程度不同,导致了不同资产有着不同的预期收益。

如果有一个多因子模型,它能很好地解释资产收益横截面差异,那么我们只需关心:

  1. 各个资产在各个因子上的暴露程度(\(N\times K\))。它是一个矩阵,矩阵的每一行记为\(\beta_i^\prime\),其中\(i=1, 2, \dots, N\)
  2. 各个因子的预期收益率(\(K\times 1\)),记为\(\lambda\)。它是一个列向量,第\(k\)个元素是\(\lambda _k\),代表第\(k\)个因子的预期收益率。

下面梳理可以对多因子模型进行检验的三种方法。