Kaggle量化比赛复盘: Optiver - Trading at the Close

该博客围绕金融比赛展开,介绍多个开源及半开源获奖方案,包括特征工程、模型选择等内容。还提及比赛技巧,如特征构造、筛选方法等。最后思考量化领域策略,强调zero_sum技术、模型混合学习等重要性,建议时序领域加入滚动训练或在线学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

前言

一、开源方案

1. 6th获奖方案(代码未开源)

1.1. 特征工程(关键代码)

1.2. 方案解析

2. 7th获奖方案(开源)

2.1. 特征工程

2.2. 特征工程

3. 9th获奖方案(半开源)

3.1. 特征构造

3.2. 特征筛选

3.3. 模型

3.4. zero_sum(标签后处理)

4. 14th获奖方案(开源)

4.1. 方案开源链接

4.2. zero_sum(标签后处理)

5. 15th获奖方案(半开源)

5.1. 特征工程

5.2. 模型

5.2. 时序交叉验证/滚动训练

5.3. zero_sum(标签平滑技术)

6. 23th获奖方案(半开源)

6.1. 特征工程

6.2. 模型

6.3. CV交叉验证

6.4. 关于NN取舍、在线学习的思考

7. 25th获奖方案(半开源)

7.1. 特征工程

7.2. 模型

二、比赛Trick/Fancy Idea

三、思考


前言

基于集合竞价开始以来经过 N 秒的行情数据,进行target预测。

比赛链接:https://www.kaggle.com/competitions/optiver-trading-at-the-close(科学上网)


一、开源方案

1. 6th获奖方案(代码未开源)

kaggle:https://www.kaggle.com/competitions/optiver-trading-at-the-close/discussion/486040

overview:少量特征工程(特征工程在本方案中占比不大)+深度学习(3*Transformer+1*GRU)+滚动训练/增量学习+zero_sum后处理。

1.1. 特征工程(关键代码)

# 特征工程
# (1)集合竞价前n秒数据分桶
df['seconds_in_bucket_flag_1'] = df['seconds_in_bucket'] >= 300 - 60
df['seconds_in_bucket_flag_2'] = df['seconds_in_bucket'] >= 300
df['seconds_in_bucket_flag_3'] = df['seconds_in_bucket'] >= 480 - 60
df['seconds_in_bucket_flag_4'] = df['seconds_in_bucket'] >= 480

# (2)常规量化因子
df["volume"] = df['ask_size'] + df['bid_size']
df["mid_price"] = (df['ask_price'] + df['bid_price']) / 2
df["liquidity_imbalance"] = (df['bid_size'] - df['ask_size']) / df["volume"]
df["matched_imbalance"] = (df['imbalance_size'] - df['matched_size']) / (df['imbalance_size'] + df['matched_size'])
df["size_imbalance"] = df['bid_size'] / df['ask_size']
df['harmonic_imbalance'] = 2 / ((1 / df['bid_size']) + (1 / df['ask_size'] ))


# (3)基于数学算子的常规特征
from itertools import combinations
prices = ["reference_price", "far_price", "near_price", "ask_price", "bid_price", "wap"]
for c in combinations(prices, 2):
    df[f"{c[0]}_{c[1]}_imb"] = df.eval(f"({c[0]} - {c[1]})/({c[0]} + {c[1]})")

1.2. 方案解析

(1)数据预处理:用0填充缺失值,特征标准化;
(2)特征工程:模型共35-36个特征,对seconds_in_bucket(集合竞价前N秒数据进行数值分桶),以及1.1部分的其它特征工程(在本方案中,特征工程work占比不大);
(3)建模:3*transformers + 1* GRU。训练过程采用滚动训练/在线增量学习训练模型,并在滚动过程中使用最新的20day数据评估模型。此外,由于评估指标在每次训练后都不稳定,方案使用指数移动平均值来平滑数值并比较模型;
(4)后处理(比赛trick):对pre进行zero_sum处理。除一个模型外,所有模型在训练时都附加了一个约束条件,即模型输出总和为零;
(5)模型融合:平均加权——(3*transformers+1* GRU)/4。

2. 7th获奖方案(开源)

github:https://github.com/nimashahbazi/optiver-trading-close

kaggle:https://www.kaggle.com/competitions/optiver-trading-at-the-close/discussion/486169

overview:特征工程(手工常规特征、偏差特征)+模型融合(LGB+LSTM、ConvNet)+在线学习滚动更新模型参数;

2.1. 特征工程

常规特征: 

订单簿不平衡:利用公开共享的imb1、imb2等。
趋势指标:采用diff()实现时间变化。
基于交易量的累积:汇总一段时间内的交易量。
全球股票统计:计算历史股票数据的平均值、中位数和标准差。
偏差特征:基于树的模型和神经网络模型都受益于代表偏离中位数的原始特征,如下图所示:

偏差特征(横截面特征):

# 偏差特征/横截面特征/中性化处理
# new_fea = df[feature] - grouped_median,计算每个特征值与其在同一天、同一集合竞价时间分组聚合的中位数(grouped_median)的偏差
# 标准化特征值,更好地识别异常值,减少组间偏差,提高模型性能,增强数据解释性,并便于后续的数据分析工作
  def create_deviation_within_seconds(df, num_features):
      groupby_cols = ['date_id', 'seconds_in_bucket']
      new_columns = {}
      for feature in num_features:
          grouped_median = df.groupby(groupby_cols)[feature].transform('median')
          deviation_col_name = f'deviation_from_median_{feature}'
          new_columns[deviation_col_name] = df[feature] - grouped_median
      return pd.concat([df, pd.DataFrame(new_columns)], axis=1)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值