因子构建模块功能介绍

量化投资研究服务平台提供了相应的因子构建模块。因子构建是多因子模型的基石,是否能够准确、快速、方便的构建出因子决定了多因子研究的效率和准确性。

1、因子的定义

因子,可以看做股票的一种特征,这种特征可能预示着股价未来的涨势。 举个简单的小例子,如果想猜测明天的天气如何,我们可以看看云彩的形状,如果万里无云,我们可以大概率认为明天就是晴天,如果现在风非常大,那么接下来的几个小时或者明天非常有可能下雨。

比如一个企业的利润其实也是一种非常强的特征,如果利润非常高,那么我们一般会认为利润高的股票会有更多人来买,那么股票供不应求,价格自然上涨。但是这里存在一个问题,如果一个市值100亿的公司和市值1000亿的公司利润都是10个亿,那么仅仅凭借利润这个绝对值我们很难区分,一般我们会除以他们的市值做个scale。

所以不严谨的总结就是:因子就是股票的特征,这种特征主要用来预测收益,并进行选股。

2、因子构建的数据依赖

理论上所有跟股票相关的数据都可以做成因子。但是常见的主要有:

  • 成交量
  • 行情价格
  • 财务数据
  • 一致预期数据

目前可以通过QuoteFeed这个类获取成交量和行情价格的数据,通过FinancialFeed获取财务数据相关的数据

3、因子构建的方法

因子的构建需要自己创建一个类,改类需要继承平台提供的BaseFactor类。

3.1. 用户自定义的参数说明

  • factor_name: 因子的名字。
  • factor_direction: 因子的方向, 1为升序,即因子值越小,因子排名越靠前。
  • factor_parameters: 因子需要的其他的参数,python dict类型
  • tickers: list类型的股票代码列表,如[‘000001.SZ’, ‘600000.SH’]

用户自己仅仅需要写下面两个函数即可完成因子的定义:

3.2. _prepare_data(self, begin_day, end_day)

这个函数主要用于因子计算前的数据准备,begin_day和end_day为string类型的日期。

Attention:

某些因子需要将begin_day向前扩展。例如:如果计算20170601~20170701这一个月期间的60日价格动量。那么begin_day应该向前移动60天,实际开始时间应该为20170401.

3.3. _generate_factor(self, trading_day):

因子核心的计算逻辑都在这个函数里实现,这个函数默认所有需要的数据都已经准备好了。

传入的参数为某个交易日,返回的是该交易日的因子数据。

返回数据类型是pandas.series,indx为ticker,value为因子值。

3.4. 调用因子类将数据写入数据库

当前面的代码逻辑都已经写好了,那么就可以调用基类BaseFactor中的generate_factor_and_store(from_dt, to_dt)方法来生成因子了。from_dt代表开始日期,to_dt代表结束日期。都是string类型,如“20170101”。

4、构建的代码示例

下面是60日动量的一个简单示例,计算全A股20170501~20170929之间的60日动量。

from smartbeta.factorbase import BaseFactor
from data_provider.datafeed.quote_feed import QuoteFeed
import pandas as pd
from data_provider.nestlib.trading_cal import TradeCal
from data_provider.datafeed.universe import Universe
from datetime import datetime


class Momentum(BaseFactor):
    def __init__(
        self,
        factor_name="Momentum",
        factor_direction=-1,
        factor_parameters={"lagTradeDays": 60},
        tickers=None,
    ):
        super(Momentum, self).__init__(
            factor_name=factor_name,
            factor_direction=factor_direction,
            factor_parameters=factor_parameters,
            tickers=tickers,
        )

    def _prepare_data(self, begin_date, end_date):
        begin_day = TradeCal().shift_date(
            str(begin_date), self._factor_param["lagTradeDays"]
        )  # 多取一些数据做填充
        freq = Frequency.DAY
        qt_feed = QuoteFeed(
            self.tickers, begin_day, end_date, freq, "forward", columns=["close"]
        )
        qt_feed.load_feed()
        quote_panel = qt_feed.getBarPanel()
        self.quote_panel = quote_panel.close.fillna(method="ffill")

    def _generate_factor(self, end_day):
        """
        计算增量因子数据
        :param end_day:因子生产的日期
        这里需要生成一个series类型的结构,indx为ticker,value为因子值
        """
        begin_day = TradeCal().shift_date(
            str(end_day), self._factor_param["lagTradeDays"]
        )  # 需要交易日历相关的函数的支持
        close_df = self.quote_panel[
            (self.quote_panel.index >= str(begin_day))
            & (self.quote_panel.index <= str(end_day))
        ]

        ret = close_df.tail(1).squeeze() / close_df.head(1).squeeze() - 1.0
        return ret


if __name__ == "__main__":
    from_dt = "20170501"
    to_dt = "20170929"

    allAShare = Universe().get_a_share_in_period(from_dt, to_dt)  # 获取该区间段中所有的A股股票列表

    momentum_60M = Momentum(
        factor_name="Momentum_60M",
        factor_direction=1,
        factor_parameters={"lagTradeDays": 60},
        tickers=allAShare,
    )

    momentum_60M.generate_factor_and_store(from_dt, to_dt)

    # momentum_60M.del_factor() # 从数据库中清空因子

5、添加description

当因子创建一段时间后,该因子的相关信息基本会很容易忘记。这里强烈建议调用add_factor_definition对这个因子加入因子定义。

主要包含以下信息:

  • param category: 因子大类
  • param create_by: 创建者
  • param description: 描述
  • param cal_alg: 计算方法
  • param create_time: 创建时间,如果为None值,就填充为当前时间

因为因子定义的时候已经含有名字和因子的方向,所以调用上面这个接口后,也会将因子名和方向加入数据库中。

如果已创建的因子描述信息有误,可以调用del_factor_definition将这个因子的定义删除。

momentum_60M.add_factor_definition(
    category="Momentum",
    create_by="idwzx",
    description="60日动量,测试只用",
    cal_alg="这里是计算方法,忽略",
)

6、获取因子

因子的基类提供了一个load方法,从数据库中读取因子数据:

  • 参数
    • factor_name: 因子的名称
    • begin_day: 开始日期,int类型YYYYMMDD, 也可以是datetime/str
    • end_day: 结束日期,int类型YYYYMMDD, 也可以是datetime/str
    • ticker: 股票代码。如果没有传入ticker的list,默认取出所有股票的因子值
    • use_cache: 是否使用缓存,default False 使用缓存数据将极大加快因子读取速度,但是当因子数值发生改变时,使用缓存会导致数据不一致,建议对于平台提供的因子或是完成开发的因子使用缓存,而对于用户正在开发的因子和可能频繁发生改变的因子,建议不要使用缓存。通过del_factor()可以删除全部因子数据以及相应缓存。
  • return 因子数据,pandas.DataFrame类型
momentum_60M.load(from_dt, to_dt)

7、因子如何使用

在因子写完计算存入数据库后,投研平台提供了几种工具来使用因子

  1. 分析: 详见 请点击->因子分析模块功能介绍
  2. 合成: 详见 请点击->因子合成流程
  3. 回测: 详见 请点击->因子回测帮助文档

微信扫码分享本页