【Datawhale AI 夏令营第二期】AI 量化模型预测挑战赛

news2024/11/23 5:13:44

文章目录

  • 赛题分析
    • 赛题背景
    • 赛事任务
    • 赛题数据集
    • 评价指标
  • Baseline实践
    • 导入模块
    • EDA
    • 特征工程
    • 模型训练与验证
    • 结果输出
  • 改进

赛题分析

赛题背景

量化金融在国外已经有数十年的历程,而在国内兴起还不到十年。这是一个极具挑战的领域。量化金融结合了数理统计、金融理论、社会学、心理学等多学科的精华,同时特别注重实践。由于市场博弈参与个体的差异性和群体效应的复杂性,量化金融极具挑战与重大的机遇的特点。 本赛事通过大数据与机器学习的方法和工具,理解市场行为的原理,通过数据分析和模型创建量化策略,采用历史数据,验证量化策略的有效性,并且通过实时数据进行评测。

赛事任务

给定数据集: 给定训练集(含验证集), 包括10只(不公开)股票、79个交易日的L1snapshot数据(前64个交易日为训练数据,用于训练;后15个交易日为测试数据,不能用于训练), 数据已进行规范化和隐藏处理,包括5档量/价,中间价,交易量等数据(具体可参考后续数据说明)。

预测任务:利用过往及当前数据预测未来中间价的移动方向,在数据上进行模型训练与预测

赛题数据集

行情频率:3秒一个数据点(也称为1个tick的snapshot);
每个数据点包括当前最新成交价/五档量价/过去3秒内的成交金额等数据;
训练集中每个数据点包含5个预测标签的标注;允许利用过去不超过100tick(包含当前tick)的数据,预测未来N个tick后的中间价移动方向。
预测时间跨度:5、10、20、40、60个tick,5个预测任务;即在t时刻,分别预测t+5tick,t+10tick,t+20tick,t+40tick,t+60tick以后:最新中间价相较t时刻的中间价:下跌/不变/上涨。

请添加图片描述

股票5档是指买1~买5、卖1~卖5十个价格档位,分别标记五个买盘价格和五个卖盘价格。成交顺序是从1到5,未成交的最高买价是买1,最低卖价是卖1。

评价指标

本模型依据提交的结果文件,采用macro-F1 score进行评价,取label_5, label_10, label_20, label_40, label_60五项中的最高分作为最终得分。

Baseline实践

导入模块

import numpy as np
import pandas as pd
from catboost import CatBoostClassifier
from sklearn.model_selection import StratifiedKFold, KFold, GroupKFold
from sklearn.metrics import accuracy_score, f1_score, roc_auc_score, log_loss, mean_squared_log_error
import tqdm, sys, os, gc, argparse, warnings
import matplotlib.pyplot as plt
warnings.filterwarnings('ignore')

EDA

数据探索性分析,是通过了解数据集,了解变量间的相互关系以及变量与预测值之间的关系,从而帮助我们后期更好地进行特征工程和建立模型,是机器学习中十分重要的一步。

# 读取数据
path = 'AI量化模型预测挑战赛公开数据/'

train_files = os.listdir(path+'train')
train_df = pd.DataFrame()
for filename in tqdm.tqdm(train_files): # 读取每个文件
    tmp = pd.read_csv(path+'train/'+filename)
    tmp['file'] = filename
    train_df = pd.concat([train_df, tmp], axis=0, ignore_index=True) # 连接文件成表

test_files = os.listdir(path+'test')
test_df = pd.DataFrame()
for filename in tqdm.tqdm(test_files):
    tmp = pd.read_csv(path+'test/'+filename)
    tmp['file'] = filename
    test_df = pd.concat([test_df, tmp], axis=0, ignore_index=True)

首先可以对买价卖价进行可视化分析

选择任意一个股票数据进行可视化分析,观察买价和卖价的关系。下面是对买价和卖价的简单介绍:

买价指的是买方愿意为一项股票/资产支付的最高价格。
卖价指的是卖方愿意接受的一项股票/资产的最低价格。
这两个价格之间的差异被称为点差;点差越小,该品种的流动性越高。

cols = ['n_bid1','n_bid2','n_ask1','n_ask2']
tmp_df = train_df[train_df['file']=='snapshot_sym7_date22_pm.csv'].reset_index(drop=True)[-500:]
tmp_df = tmp_df.reset_index(drop=True).reset_index()
for num, col in enumerate(cols):
    plt.figure(figsize=(20,5))
   
    plt.subplot(4,1,num+1)
    plt.plot(tmp_df['index'],tmp_df[col])
    plt.title(col)
plt.show()
plt.figure(figsize=(20,5))

for num, col in enumerate(cols):
    plt.plot(tmp_df['index'],tmp_df[col],label=col)
plt.legend(fontsize=12)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

加上中间价继续可视化,中间价即买价与卖价的均值,数据中有直接给到,我们也可以自己计算。

plt.figure(figsize=(20,5))

for num, col in enumerate(cols):
    
    plt.plot(tmp_df['index'],tmp_df[col],label=col)
    
plt.plot(tmp_df['index'],tmp_df['n_midprice'],label="n_midprice",lw=10)
plt.legend(fontsize=12)

在这里插入图片描述

波动率是给定股票价格变化的重要统计指标,因此要计算价格变化,我们首先需要在固定间隔进行股票估值。我们将使用已提供的数据的加权平均价格(WAP)进行可视化,WAP的变化反映股票波动情况。

train_df['wap1'] = (train_df['n_bid1']*train_df['n_bsize1'] + train_df['n_ask1']*train_df['n_asize1'])/(train_df['n_bsize1'] + train_df['n_asize1'])
test_df['wap1'] = (test_df['n_bid1']*test_df['n_bsize1'] + test_df['n_ask1']*test_df['n_asize1'])/(test_df['n_bsize1'] + test_df['n_asize1'])

tmp_df = train_df[train_df['file']=='snapshot_sym7_date22_pm.csv'].reset_index(drop=True)[-500:]
tmp_df = tmp_df.reset_index(drop=True).reset_index()
plt.figure(figsize=(20,5))
plt.plot(tmp_df['index'], tmp_df['wap1'])

在这里插入图片描述

特征工程

在特征工程阶段,构建基本的时间特征,提取小时、分钟等相关特征,主要是为了刻画不同时间阶段可能存在的差异性信息。需要注意数据是分多个文件存储的,所以需要进行文件合并,然后在进行后续的工作。

# 时间相关特征
train_df['hour'] = train_df['time'].apply(lambda x:int(x.split(':')[0]))
test_df['hour'] = test_df['time'].apply(lambda x:int(x.split(':')[0]))

train_df['minute'] = train_df['time'].apply(lambda x:int(x.split(':')[1]))
test_df['minute'] = test_df['time'].apply(lambda x:int(x.split(':')[1]))

# 入模特征
cols = [f for f in test_df.columns if f not in ['uuid','time','file']]

模型训练与验证

选择使用CatBoost模型,也是通常作为机器学习比赛的基线模型,在不需要过程调参的情况下也能得到比较稳定的分数。这里使用五折交叉验证的方式进行数据切分验证,最终将五个模型结果取平均作为最终提交。

def cv_model(clf, train_x, train_y, test_x, clf_name, seed = 2023):
    folds = 5
    kf = KFold(n_splits=folds, shuffle=True, random_state=seed)
    oof = np.zeros([train_x.shape[0], 3]) # 验证结果,3代表3种类别,会得到3种类别的概率
    test_predict = np.zeros([test_x.shape[0], 3]) # 测试结果
    cv_scores = []
    
    for i, (train_index, valid_index) in enumerate(kf.split(train_x, train_y)):
        print('************************************ {} ************************************'.format(str(i+1)))
        trn_x, trn_y, val_x, val_y = train_x.iloc[train_index], train_y[train_index], train_x.iloc[valid_index], train_y[valid_index]
       
        if clf_name == "cat":
            params = {'learning_rate': 0.2, 'depth': 6, 'bootstrap_type':'Bernoulli','random_seed':2023,
                      'od_type': 'Iter', 'od_wait': 100, 'random_seed': 11, 'allow_writing_files': False,
                      'loss_function': 'MultiClass'}
            
            model = clf(iterations=100, **params)
            model.fit(trn_x, trn_y, eval_set=(val_x, val_y),
                      metric_period=20,
                      use_best_model=True, 
                      cat_features=[],
                      verbose=1)
            
            val_pred  = model.predict_proba(val_x)
            test_pred = model.predict_proba(test_x)
        
        oof[valid_index] = val_pred
        test_predict += test_pred / kf.n_splits
        
        F1_score = f1_score(val_y, np.argmax(val_pred, axis=1), average='macro')
        cv_scores.append(F1_score)
        print(cv_scores)
        
    return oof, test_predict
    
for label in ['label_5','label_10','label_20','label_40','label_60']:
    print(f'=================== {label} ===================')
    cat_oof, cat_test = cv_model(CatBoostClassifier, train_df[cols], train_df[label], test_df[cols], 'cat')
    train_df[label] = np.argmax(cat_oof, axis=1)
    test_df[label] = np.argmax(cat_test, axis=1)

本次比赛采用macro-F1 score进行评价,取label_5, label_10, label_20, label_40, label_60五项中的最高分作为最终得分,所以在初次建模的时候对应五个目标都需要进行建模,确定分数最高的目标,之后进行优化的时候仅需对最优目标进行建模即可,大大节省时间,聚焦单个目标优化。

结果输出

提交结果需要符合提交样例结果,然后将文件夹进行压缩成zip格式提交。

import pandas as pd
import os


# 指定输出文件夹路径
output_dir = './submit'

# 如果文件夹不存在则创建
if not os.path.exists(output_dir):
    os.makedirs(output_dir)

# 首先按照'file'字段对 dataframe 进行分组
grouped = test_df.groupby('file')

# 对于每一个group进行处理
for file_name, group in grouped:
    # 选择你所需要的列
    selected_cols = group[['uuid', 'label_5', 'label_10', 'label_20', 'label_40', 'label_60']]
    
    # 将其保存为csv文件,file_name作为文件名
    selected_cols.to_csv(os.path.join(output_dir, f'{file_name}'), index=False)

改进

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/841992.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DataWhale 机器学习夏令营第二期——AI量化模型预测挑战赛 学习记录

DataWhale 机器学习夏令营第二期 学习记录一 (2023.08.06)1. 问题建模1.1 赛事数据数据集情况数据中缺失值类别和数值特征的基本分布 1.2 评价指标中间价的计算方式价格移动方向说明 1.3 线下验证 DataWhale 机器学习夏令营第二期 ——AI量化模型预测挑战赛 已跑通baseline&…

排查吞吐量和 SNR 方面的 Wi-Fi 问题

服务交付对于客户在选择品牌时要考虑很重要,组织依靠其网络向全球客户无缝提供服务,强大的网络连接对于更好的最终用户体验至关重要,而高质量访问的关键是两个关键指标: 吞吐量信噪比 (SNR) 为了获得更好…

解决word打字卡顿问题的方法

❤ 2023.8.5 ❤ 最近整理论文,本来我是wps死忠粉,奈何wps不支持latex公式。。。 无奈用起了word,但是谁想字数稍微多了一点,word就卡得欲仙欲死,打个字过去2s才显示出来,删除的时候都不知道自己删了几个字…

基于STM32CUBEMX驱动低压步进器电机驱动器STSPIN220(1)----套件概述

基于STM32CUBEMX驱动低压步进器电机驱动器STSPIN220----1.套件概述 套件概述样品申请特征系统控制和生态系统访问功能示意图系统框图跳线设置开发板原理图 套件概述 STM32C011F4Px_STSPIN220 是一款基于 STM32C011F4Px 的低压步进电机驱动套件。其中,STSPIN220 是一…

离散化的两种实现方式【sort或者map】

离散化 定义 把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。 适用范围:数组中元素值域很大,但个数不是很多。 比如将…

Navicat远程连接Linux的MySQL

打开Linux终端,进入root权限,用vim打开MySQL的配置文件 vim /etc/mysql/mysql.conf.d/mysqld.cnf将bind-address的值改为0.0.0.0 进入MySQL mysql -u root -p 将root用户改为允许远程登录 update user set host % where user root; 创建用户 CRE…

码出高效_第二章 | 面向对象_上

目录 一. OOP理念1. 概念辨析2. 四大特性1. 抽象2. 封装3. 继承4. 多态 二. 初识Java1. JDKJDK 5-11的重要类、特性及重大改变 2. JRE关于JVM 三. 类1. 概述2. 接口和抽象类1. 概念及相同点2. 不同点3. 总结 3. 内部类4. 访问权限控制1. 由来2. public/private/无/private3. 推…

无涯教程-Perl - endgrent函数

描述 此功能告诉系统您不再希望使用getgrent从groups文件中读取条目。 语法 以下是此函数的简单语法- endgrent返回值 此函数不返回任何值。 Perl 中的 endgrent函数 - 无涯教程网无涯教程网提供描述此功能告诉系统您不再希望使用getgrent从groups文件中读取条目。 语法以…

开源项目-私人牙医管理系统

哈喽,大家好,今天给大家带来一个开源项目-私人牙医管理系统,项目使用springboot+mysql技术实现 私人牙医管理系统的主要功能包括客户管理,医生管理,药品管理,文章管理模块 登录 客户管理 客户管理主要有客户数据,客户列表,添加客户功能 客户数据 客户列表 添加…

VIOOVI的精益生产探析:深入了解精益生产的本质

精益生产它是利用杜绝浪费和稳定、连续生产的作业流程,是通过系统性的结构管理、生产人员组织以及市场端的供求现状等方面的因素做对应的调整、变革。具备有一定战斗力的生产管理体系,可以很快的根据市场端需求做出对应的调整,而且实现生产过…

黑马大数据学习笔记5-案例

目录 需求分析背景介绍目标需求数据内容DBeaver连接到Hive建库建表加载数据 ETL数据清洗数据问题需求实现查看结果扩展 指标计算需求需求指标统计 可视化展示BIFineBI的介绍及安装FineBI配置数据源及数据准备 可视化展示 P73~77 https://www.bilibili.com/video/BV1WY4y197g7?…

如何使用win10专业版系统自带远程桌面公司内网电脑,从而实现居家办公?

使用win10专业版自带远程桌面公司内网电脑 文章目录 使用win10专业版自带远程桌面公司内网电脑 在现代社会中,各类电子硬件已经遍布我们身边,除了应用在个人娱乐场景的消费类电子产品外,各项工作也离不开电脑的帮助,特别是涉及到数…

router和route的区别

简单理解为,route是用来获取路由信息的,router是用来操作路由的。 一、router router是VueRouter的实例,通过Vue.use(VueRouter)和VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所…

vue结合three.js加载3D模型报404错误

使用vue结合three.js加载3D模型时报404的错误,加载字体库也会报404错误,同样的方法。 vue项目虽然使用npm install three安装了three,但是有些静态资源时读取不到的,当出现异常的404错误时,比如加载3D模型资源时&…

第5章 运算符、表达式和语句

本章介绍以下内容: 关键字:while、typedef 运算符:、-、*、/、%、、--、(类型名) C语言的各种运算符,包括用于普通数学运算的运算符 运算符优先级以及语句、表达式的含义 while循环 复合语句、自动类型转换和强制类型转换 如何编写…

虚拟机不能使用 console 的问题

原理:arm 系统默认走ttyAMA0,x86 默认走ttyS0,而tty0 是走的GPU 串行端口终端(/dev/ttySn) 串行端口终端(Serial Port Terminal)是使用计算机串行端口连接的终端设备。 计算机把每个串行端口都看作是一个字符设备。有段时间这些串行端口设备…

6.6.tensorRT高级(1)-mmdetection框架下yolox模型导出并推理

目录 前言1. yolox导出2. yolox推理3. 补充知识3.1 知识点3.2 mmdetection 总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程,之前有看过一遍,但是没有做笔记,很多东西也忘了。这次重新撸一遍,顺便记记笔记。 本次课程学习…

Spring Boot介绍--快速入门--约定优于配置

文章目录 SpringBoot 基本介绍官方文档Spring Boot 是什么?SpringBoot 快速入门需求/图解说明完成步骤快速入门小结 Spring SpringMVC SpringBoot 的关系总结梳理关系如何理解-约定优于配置 SpringBoot 基本介绍 官方文档 官网: https://spring.io/projects/spring-boot 学习…

JUC之线程中断与LockSupport

什么是中断 首先一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止。其次在Java中没有办法立即停止一条线程,然而停止线程却显得尤为重要,如取消一个耗时操作。因此,Java提供了一种用于停止线程的机制——中…

goanno的简单配置-goland配置

手动敲注释太LOW,使用插件一步搞定 goanno 打开goanno的配置 点击之后弹窗如下 配置method /** Title ${function_name} * Description ${todo} * Author zhangguofu ${date} * Param ${params} * Return ${return_types} */相关效果如下 同理配置interface // ${interface…