# eda(数据描述)&baseline

  1. target 服从泊松分布(或卡方)
  2. MSE 的分布前提假设数据满足高斯分布
  3. 分类问题的评估函数多用 f1 score

F1 分数是精确率(P,预测结果对了多少)和召回率(R,对实际结果我覆盖了多少)的调和平均数

  1. encoding 技巧:对面板数据,按类别 groupby,然后聚合操作

  2. 按时间聚合时,可以考虑 tsfresh 包

  3. 聚合时,考虑到越新的数据,对未来影响越大,可以考虑从后往前选特定长度

  4. 伪标签思想:用初始学到的模型给无标签数据集打标签,取确信度大的结果加入 train set,用于后续训练(要防止确认偏见

  5. stacking 思想:

    把不同模型看作不同的专家,用一个主席模型缝合到一起。

    在训练主席模型时,为了防止数据泄露,会使用 K-fold 生成临时专家小模型,小专家的输出作为主席训练用的元特征。

这样的好处是整个原始训练集中的每一条数据,都恰好被当过一次 “验证集”,并由一个从未见过它的模型做出了预测

​ 最后在 test dataset 上,再用整个训练集跑出专家模型,输出结果给主席模型缝合。

bagging 思想:有放回抽样 train data,并行训练多个同类型模型,预测时投票 or 均值(随机森林在此基础上会对特征列的随机抽样

boosting 思想:则对上一个弱模型的误差重点关注,最后所有子模型合并

  • 分类问题,训练时缩放权重,预测时对子模型按权重加和投票
  • 拟合问题,训练时拟合残差,预测时加和结果(按学习率,这个训练时就有)
  1. MSE 会优先拟合值较大的结果,它过分关注标签比较大的样本。所以用反比的 weight 中和

# feature 因子工程

# 订单簿基处理(横向扩展)

  1. book_wap1book_wap2
  • 含义:加权平均价格(Weighted Average Price),基于每一档位的买卖盘数据计算

注意:此处量价交叉相乘,为了体现力量趋势

买盘量大,则价格向卖方价前进。反之同理

  1. book_wap_mean

    • 含义:加权平均价格的平均值
  2. book_wap_diff

    • 含义:相邻档加权平均价格的差值
  3. book_price_spread

    • 含义:买卖价差的相对值(归一化处理)

此处分母可以是买一和卖一之和,也即 2 倍中间位均值

  1. book_bid_spread

    • 含义:买盘的价格差
  2. book_ask_spread

    • 含义:卖盘的价格差
  3. book_total_volume

    • 含义:买卖盘的总数量
  4. book_volume_imbalance

  • 含义:买卖盘数量的不平衡程度(总卖减总买)

# agg 特征(纵向聚合)

基于同股票同时间段聚合,得到:

  • 订单簿:求每一列的 对数变动率标准差(平方和的平方根)
  • trade:基于 pricesizeorder_count (成交订单数)、 seconds_in_bucket (10min 时间桶内第几秒成交的 trade) 四列,对每一列求简单聚合( summeanstdmaxmin

# 伪 K 线特征

由于每个 trade 只有一个成交价格数据,太单薄

所以考虑重采样

波动率和成交量关系密切

对每个 10min 时间桶,重采样为 10s 一根 K,构建开高低收,计算:

  1. MACD,KDJ 等基础指标,TA-lib

  2. 量价 corr 等回归指标

  3. AD 指标(Accumulation/Distribution)(价格给成交量权重)

核心思想是:

  • 如果收盘价接近最高价,并且成交量较大,就说明市场有 “资金流入”(吸筹、买入)。
  • 如果收盘价接近最低价,并且成交量较大,就说明市场有 “资金流出”(派发、卖出)。

公式分两步:

  • 计算 CLV(Close Location Value,收盘位置值)

CLV=(closelow)(highclose)highlowCLV=\frac{(close - low) - (high - close)}{high - low}

CLV 取值范围在 -1 到 1 之间,越接近 1 表示收盘越靠近最高,越接近 -1 表示收盘越靠近最低。

  • 计算 AD 值

AD=ADyesterday+CLV×VolumnAD = AD_{yesterday} + CLV \times Volumn

AD 指标的走势可以帮助判断价格走势背后的资金动向。如果股价在涨,但 AD 没有同步上涨,可能暗示上涨缺乏资金支撑,有背离风险。

  1. OBV 能量潮 **(切割)**

简单说就是今日价格上涨,咱累加 vol;下跌,就减。

  1. Klinger 成交量摆动指标 **(切割)**

同 OBV,只是切割指标不用 close 了,用(close+high+low)3\dfrac{(close+high+low)}{3}

  1. ATR**(前面都是量,这里开始是价)**

  2. 乖离率 **(收盘价和均线偏离程度)**

  3. 相对波动率 RVI**(切割)**

核心思想是:把近期的波动 “活跃度” 和整体波动做对比,用来判断市场是平稳还是波动剧烈。

计算步骤大致如下(常见做法):

  • 划分 & 计算
    一般用标准差、TR 或者绝对收益(| 今日收盘 − 昨日收盘 |)作为每日波动指标。

    • UpVol:如果当天价格上涨,用当日波动值;否则为 0

    • DownVol:如果当天价格下跌,用当日波动值;否则为 0

  • 平滑处理
    用 N 日移动平均或者指数加权平均:

UpVolavg=EMA(N,UpVol)DownVolavg=EMA(N,DownVol)\begin{aligned} UpVol_{avg} &= EMA(N, UpVol)\\ DownVol_{avg} &= EMA(N, DownVol) \end{aligned}

  • 计算 RVI

RVI=UpVolavgUpVolavg+DownVolavg×100RVI = \frac{UpVol_{avg}}{UpVol_{avg} + DownVol_{avg}} \times 100

RVI 的值在 0~100 之间:

  • RVI 接近 100 → 上涨波动占主导,波动活跃
  • RVI 接近 0 → 下跌波动占主导
  • 中间区域 → 市场波动平稳

barra 对流动性的定义就是不同周期内的换手率

流动性可以用 买卖不平衡性买卖压力 衡量

  1. 深度差 & 高度差

每档买卖量的相对差

对每档价格求差分,对差分求买卖相对差

  1. 价格加权的买卖量压力

核心思想:离买一卖一的中间价(midprice)越近,权重越大;

  1. Amihud

核心思想:单位成交量带来的价格波动越大,说明流动性越差

分子可以用最短价格路径来改进

# boosting 树模型

# 基础

  1. sigmoid 函数

Sigmoid function - Wikipedia

  1. softmax

要对一个 feature 进行nn 分类,用该 feature 喂进 model 出一个nn 长度的 output,其每个元素为znz_n。然后 softmax,就是算指数比例,将 output 值映射到 pn[0,1]p_n\in[0, 1],且sum(p)=1sum(p)=1

pn=eznj=1neznp_n = \dfrac{e^{z_n}}{\sum_{j=1}^n e^{z_n}}

  1. 逻辑回归

逻辑回归就是一个线性回归 + sigmoid 激活,损失函数取交叉熵,反向传播优化

  • 在逻辑回归和分类问题里: 交叉熵损失 = 负对数似然损失

  • 交叉熵损失:

    多分类,分 k 类时,对一个样本

L=k=1KyklnpkL = - \sum_{k=1}^K y_k \ln p_k

其中:

  • yky_k 是 one-hot 编码(真实类别),如果真实类别是 cc,那么 yc=1y_c=1,其他 yk=0y_k=0
  • pkp_k 是预测概率,来自 Softmax

k=2k=2,代入:

y1=yy0=1y1=1yp1=pp0=1p1=1p\begin{gathered} y_1 = y \\ y_0 = 1 - y_1 = 1 - y \\ p_1 = p \\ p_0 = 1 - p_1 = 1 - p \end{gathered}

得到二分类交叉熵(对每个样本xix_i):

L=[(1y)ln(1p)+ylnp]L = - \big[ (1-y)\ln (1-p) + y\ln p \big]

# cart 树

可分类可回归

用 “基尼指数” 衡量纯度,分裂时选基尼指数最小的特征。

严格的二叉树

# GBDT

  1. 所有树都是 cart 回归树(无论分类任务还是回归任务)

  2. 串行训练,第 1 棵树学完后,第 2 棵树专门修正第 1 棵的伪残差

  3. 残差怎么算,由损失函数反向传播决定。分类常用交叉熵,回归常用 MSE

  4. 每棵树的分裂层数由超参数确定,怎么分裂选取 loss 下降最多(即 gain 最大的方式)。在分裂时,分类任务计算 loss 用泰勒展开近似,用一阶导 g 和二阶导 h 计算,回归(损失函数 MSE)直接算;叶子节点的值,分类任务也是用泰勒近似的,基于一阶导 g 和二阶导 h 计算;回归(MSE)任务取均值

  5. 迭代数量为 mm 时,二分类每次迭代训练 1 棵树,总共有 mm 棵树;多分类(k 类)每次迭代训练kk 棵树,总共有 m×km\times k 棵树;

# XGBoost

GBDT 改进版

  • 加入正则项,防止过拟合
  • 利用二阶导数,优化更快
  • 支持并行、缺失值处理、剪枝等

# LightGBM

XGBoost 高速大容量版

  • 使用直方图加速特征分裂

  • 采用 “叶子优先” 生长策略(而非层优先)

  • 支持大规模数据、类别特征原生处理

更快、更省内存;精度也很高,特别适合海量数据

# 树模型的缺陷

# KNN 最邻近模型

思想:对要分类点 x ,看 x 附近最近的 K 的点,这些点大多属于哪个类,x 就是哪类

要点:交叉验证确定超参 K,还有使用二叉树思想构建训练数据,用于更快查点

# K 近邻与树模型的异同

相同:本质上都是在特征空间内划分成小区间。每个小区间用一个值来表示

区分:

  1. K 近邻在划分时可斜着、曲线切;树模型的划分线只能平行于某个 feature
  2. K 近邻算法在进行特征空间划分时候,其实并没有用到训练数据的标签信息;树模型使用 label 划分

多树模型只是划分区间更细,那这里有一个关键问题:

** 这种模型只适用于区间内预测。 ** 对于区间外的样本标签,它没有办法进行一个良好的预测。

# 解决方法

把直接预测改为相对预测,比如对 label 做差分:

  • 利用过去一段时间的平均值(特定模型)和未来的标签的差生成相对标签。
  • 利用另一个趋势模型的预测值(某个模型)和未来的标签的差生成相对标签。

标准差考虑其非负性,可以相对预测下一时刻与当前的比值。

# 超参数搜索

超参数指模型无法靠机器学习优化的参数,人为设置的。大致方法有:

  1. 网格搜索
  2. 随机搜索
  3. 贝叶斯搜索
  4. 强化学习搜索

前两者的不同参数集之间没有联系;后两者基于历史的搜索路径,指导和启发我们以后的搜索路径

# 高斯过程

在拟合模型时,假设有一个拟合函数库(先验,由均值 & 核函数决定),我们有一系列真实观测数据,那么对于观测到的每组(x, y),就会从函数库里筛函数。最后筛出来的函数们,对于输入x0x_0,就会输出不同的 y,看作模型f(x0)f(x_0) 的概率分布。

高斯过程定义:对任意有限多个输入点(x1,,xn)(x_1,\dots,x_n),对应的函数值向量 (f(x1),,f(xn))(f(x_1),\dots,f(x_n)) 都服从一个多元高斯分布。

写成公式:

f(x)GP(m(x),k(x,x))f(x)\sim \mathcal{GP}(m(x), k(x,x'))

意思是:

  • 均值函数 m (x) m (x) m (x) 给出在每个输入点的期望值;
  • 协方差函数 k (x,x′) k (x,x') k (x,x′) 给出不同输入点之间的相关性。

高斯过程通过规定任意有限点的函数值的联合高斯分布,间接地定义了整个函数库的概率分布,而不必直接给每条函数一个概率。

贝叶斯搜索会假设我们搜索的超参数的点、以及它的验证集的评估指标符合的是一个高斯过程。

搜了一些点 —> 高斯过程拟合 —> 拟合结果告诉你超参数取哪些值评估结果比较好 —> 以这些点采样超参数,循环

# alpha 的寻找

  • 截取片段
  • 聚合
  • 分类(比如 kmeans、按某一 feature 的大小排序)

在每一个股票上,我们这里可以根据 “买卖方向”“成交额大小” 对每一行 feature 进行分类

跨股票维度上,我们可以对近似类别的股票聚合求新 feature

也考虑特殊回归的 feature—— 弹性系数

# 加速

# python 内生加速技巧

  1. del 引用,释放内存
  2. 列表推导式快于 for 循环
  3. 调用局部变量比全局变量快
  4. from import 比 import 快

# 多进程

python 由于 GIL 锁,每个时刻,同一进程下,只有一个线程能在运行代码块(处理 list,dict 等数据结构的缺陷,python 早期就加了这个锁),这导致:

  • IO 操作,python 多线程没问题
  • CPU 密集操作,需要 python 多进程

于是我们使用 multiprocessing 实现多进程

pool 中,先 close 声明:“不给子进程池加新任务了”,然后 join 堵塞等人齐。可用 with 自动管理资源

类型 定义
阻塞 主进程会卡在当前这一行代码,等任务完成后才继续往下执行
非阻塞 主进程不会卡住,调用后立即继续执行下一行代码,任务在后台运行

map 加任务的函数基本返回都是有序结果,除非你特殊 unordered

# numba

可搜索参考:numba 自动并行化

# 多集群

就是用多个计算机,经典的有 mapreduce (分治 + 聚合) 思想

# 量化简述

# 基于 base feature 的深度挖掘

基本就是遗传规划 & 深度学习