1. 前言
有点泄气,读者不多,赞同也不多,不过万事开头难。上一篇我分享了因子库的设计,这一篇主要讲实现,加上我的标题叫Python与量化多因子,势必要加点代码在里头,不过旨在抛砖引玉,点到即止,更多的内容需要读者们自己去探索。
对了,读者如果自己动手,基础的Pandas,Numpy的操作还是需要会的,网上也有很多教程,大家也可以去看,如果有需要,后面我也可以写篇文章来介绍。
2. 因子构成
好像现在各家券商的研报后面都会加上他们因子的构成,很多因子也都是差不多的。我把要做的因子简单的归类,大概有如下这些:规模类
估值类
盈利类
成长类
技术类
一致预期类
另类
其实大家用的因子估计都差不多,现在更关键的是对风格的把握,但这显然也更难。
3. 准备工具
上一篇文章,我有说,我们的因子来自于一些底层的数据,但这些数据都存储在一些底层的表当中,我们需要一个中间层,构建一个统一的数据接口,为我们计算因子提供便利。
这个中间层至少需要包含:提供交易日历
提供股票的行情
提供财务数据,一致预期数据
提供行业分类数据
这四个功能,至于每个功能如何实现,具体问题具体对待。
参考网上开源的Tushare,我们也可以设计自己简单的Python数据接口:
import pandas as pd
class ForTheData:
def __init__(self):
self.calendar = pd.read_csv(r'../calendar.csv')
def get_date_list(self, start, end, freq='d'):
"""获取一段时间的交易日列表:param start: 开始时间,str:param end: 结束时间,str:param freq: 频率,'d', 'w', 'm', 'q':return: list of date"""
pass
def get_next_date(self, date, n):
"""用于获得指定n天后的日期的函数,当n>0时往后推,当n小0时往前推:param date: str:param n: int:return: str"""
pass
def get_hist_data(self, start, end, universe, field):
"""用于获取股票的行情:param start: 开始时间,str:param end: 结束时间,str:param universe: 股票池, list of tickers:param field: 获取的字段, list:return:"""
pass
def get_balance_sheet(self, start, end):
"""获取资产负债表:param start: 开始时间,str:param end: 结束时间,str:return: pd.DataFrame"""
pass
def get_industry_classified(self, start, end, universe, classified_type='zx'):
"""获取股票的行业分类数据:param start: 开始时间,str:param end: 结束时间,str:param universe: 股票列表,list of tickers:param classified_type: 行业分类类型:return: pd.DataFrame"""
pass
for_the_data = ForTheData()
我们定义了一个Python类,它可以帮助我们从前面提到的几项数据源提取需要的Python数据。当然,考虑到环境不一致的原因,我没有写具体实现的逻辑,但我算是提供了一个设计文档,可以借助这个文档来完成代码。
4. 以20日市值平均因子为例
市值是规模因子类当中的一种,我们以20日市值平均这个因子为例,提供一个Python的伪代码:
class AvgSize20d:
"""
20日总市值平均
"""
def __init__(self):
pass
def cal_factor(self, size):
"""
计算市值的平均值
:param size: 市值数据,pd.DataFrame,column为股票列表, index为日期
:return: Series
"""
return pd.Series()
def load_data(self, start, end):
"""
下载市值数据
:param start: 开始日期, str
:param end: 结束日期, str
:return:
"""
return pd.DataFrame()
def product(self, date):
"""
每日运行函数
:param date:
:return:
"""
pre_20d = for_the_data.get_next_date(date, -20)
size = self.load_data(pre_20d, date)
factor = self.cal_factor(size)
return factor
结合上一节定义的行情函数,日历函数,轻轻松松,我们便完成了该因子的计算。当然,这个因子的定义确实也比较简单,像基本面因子的计算会比较复杂些,但大体的框架是不变的。
5. 思考我们简单的定义了因子计算的框架,但是如何将因子计算同一调度,并保存到数据库当中,需要读者进行思考
因子计算当中可能会出现哪些异常,又如何处理?
加油!