量化投资之多因子选股(一):数据准备与单因子检验

您所在的位置:网站首页 股票策略测试 量化投资之多因子选股(一):数据准备与单因子检验

量化投资之多因子选股(一):数据准备与单因子检验

2024-07-10 01:25| 来源: 网络整理| 查看: 265

文章目录 前言系列文章矢量化选股回测概述要点1:数据格式要点2:股票池要点3:剔除ST股、停盘股、涨跌停要点4: 仓位构建要点5:回测 数据准备单因子检测样例

前言

本菜狗现在是哈工大威海校区计算机学院的大四本科生,也是量化投资的初学者。因为本科学校中做量化的前辈喝同伴极少,缺少与业界的交流,在很长一段时间,本菜狗一直认为量化就是MACD等技术指标的或者是用一些炫酷的DL模型来预测(因为国内很多量化书籍都是“Python基础语法+技术指标+机器学习”)。 好在没有放弃尝试,终于在经过相当一段时间的焦虑和摸索中,开始对量化行业有了比较符合客观但并不全面的认识。于是开启量化方法论系列博客的创作,把自己的学习总结、分享出来,以和需要的同伴交流。 因为本人能力和精力有限,所创作的内容难免有瑕疵乃至纰漏,欢迎批评指正。 若您对我所做的工作感兴趣,欢迎联系我:[email protected]

系列文章

本文是量化投资方法论之多因子选股系列文章的第一篇,分享数据准备(基于Tushare)和单因子检验模块。

矢量化选股回测概述

提示:若看不太懂,可结合后面的代码理解

要点1:数据格式

把数据处理成特定的DataFrame格式:(di,ii)格式,即columns为股票代码、index为日期,value为数据(如收盘价、成交量、各种因子等),每一个指标是单独的一个df。 但也不是所有数据都要DataFrame,一些只有一维的数据使用Series即可,如特定指数收益率序列。 如下图,是10年到21年A股复权后的close数据。

在这里插入图片描述

要点2:股票池

股票池一般取常用指数的成分股矩阵(或者其组合,如沪深300+中证500),一般命名为univ_a\univ_data。univ_a的列名只有现在或历史上曾经是该指数成分股的股票代码。 univ_a[stk_code][trade_date]=1即股票stk_code在trade_date这一天是该指数的成分股。否则univ_a[stk_code][trade_date]=NaN 我们一般在计算因子时计算全部的A股数据,在做选股回测时再考虑股票池。方法为: factor_df = factor_df.reindex_like(univ_a)*univ_a 其中factor_df为因子数据。reindex_like把factor_df的行、列与univ_a统一。

沪深300的股票池数据示例

在这里插入图片描述

要点3:剔除ST股、停盘股、涨跌停

构造矩阵ST_valid,ST_valid[stk_code][trade_date]==1即stk_code在trade_date这一天不是ST股,通过了ST股筛选,否则是NaN 构造矩阵suspend_valid、limit_valid,同ST。 forbid_days = suspend_valid*limit_valid 只有股票在当天同时通过三种筛选,其数值才为1

在做剔除操作时,只需要将仓位矩阵*forbid_days,没有通过筛选的股票的数据就成了NaN

要点4: 仓位构建

step1:横截面排序,按照比例筛选股票,再进行仓位权重归一化,得到初始仓位pos_1 step2:若考虑调仓周期,假设是月频率调仓,就是隔20个交易日调仓。 pos_2 = pos_1.reindex(pos_1.index[::20]).fillna(0).reindex(pos_1.index).ffill() 即截取调仓日的仓位,扩充其他日期的仓位先设置为nan,再ffill(). 这里有一个fillna(0),因为如果不在扩展之前fillna,则可能会出现 某一期一只股票被选上,后面这只股票的仓位原本都应该是NaN,但经过ffill之后却都继承了这个仓位、 step3:考虑调仓日不可交易股票(见to_final_position)

这里有一点要强调,即我们的是factor_df转换成仓位pos_df时,需要shift(1).因为factor是当天收盘后;利用了当天和之前的数据计算的,而交易最早发生在后一个交易日。

要点5:回测

处理好的仓位fin_pos.shift(1)*rtn_df再横向求和就是仓位的日收益,其中rtn_df是股票收益矩阵. shift()的原因是:rtn_df是当天收盘价(开盘价)比上前一天的收盘价(开盘价),而我们是当天非前一天下的单,所以我们吃不到下单第一天的rtn。

数据准备

本人尝试基于tushare(需要积分)获取研究所需要的常用数据(如股票行情数据、指数成分股数据、st股、涨跌停等)并处理成前文所示的(di,ii)格式。

与数据下载、存储、读取相关的代码如下。 但tushare的接口对调取频率、单次调取数据量有限制。因精力有限,并没有对代码进行完全的优化,故部分代码比较啰嗦,运行效率低。 另,因为部分方法使用了多进程并行下载,故无法在jupyter notebook等交互式环境下运行,请在pycharm等IDE下执行main()函数。

数据准备部分主要有三个类。 数据下载的DataDownloader,从tushare接口获取数据并整理成特定格式。 数据更新存储的DataWriter,调用DataDownloader将数据下载、更新、存储到本地。 数据读取的DataReader,读取数据。

import tushare as ts import numpy as np import pandas as pd from multiprocessing import Manager, Pool import datetime import os import pickle import warnings warnings.filterwarnings('ignore') ts.set_token('') pro = ts.pro_api(timeout=5) global dataBase curPath = os.path.abspath(os.path.dirname(__file__)) rootPath = curPath[:curPath.find("多因子框架\\")+len("多因子框架\\")] dataBase = rootPath+'\\data\\' def read_pickle(path): with open(path, 'rb') as handle: return pickle.load(handle) def update_pickle(text, path): with open(path, 'wb') as handle: pickle.dump(text, handle) class DataDownloader: def __init__(self,start_date='20100101',end_date = None): self.start_date = start_date self.end_date = end_date self.trade_dates = self.get_trade_dates() self.stk_codes = self.get_stks() #self.template_df = pd.DataFrame(index=self.trade_dates,columns=self.stk_codes) def get_trade_dates(self,start_date = None,end_date = None): if start_date == None: start_date = self.start_date end_date = datetime.datetime.now().strftime('%Y%m%d') if end_date == None else self.end_date df = pro.trade_cal(exchange='SSE', start_date=start_date,end_date=end_date) df[df['is_open']==1]['cal_date'].drop_duplicates() return df[df['is_open']==1]['cal_date'].to_list() def get_stks(self): stk_set = set() for list_status in ['L','D','P']: stk_set |= set(pro.stock_basic(list_status=list_status,fileds='ts_code')['ts_code'].to_list()) return sorted(list(stk_set)) def get_IdxWeight(self,idx_code): ''' 指数成分股 ''' start_date = pd.to_datetime(self.trade_dates[0]) - datetime.timedelta(days=32) start_date = start_date.strftime('%Y%m%d') trade_dates = self.get_trade_dates(start_date) df_ls = [] while start_date


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3