单因子测试框架和单因子回测框架搭建

Posted 黑马程序员官方

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单因子测试框架和单因子回测框架搭建相关的知识,希望对你有一定的参考价值。

学习目标

  • 目标
    • 应用因子IC和因子收益率实现单因子测试和回测框架对因子筛选

一、单因子测试框架

刚才我们在研究平台上所做的因子IC分析和因子收益率分析都属于因子的测试框架,因为我们使用的第三方平台,所以没有办法做一个比较完整的通用的测试系统。但是目的是为了测试选出表现较好的,如果我们建立好了测试结果?因子分析完了接着做什么?

1.1 将所有统计的因子打分排名

统计完结果之后我们需要对上百个因子进行一次筛选,在这里采取打分排名

  • 构建打分依据
    • 因子平均收益 >0.002
    • IC > 0.02
    • IR > 0.3
    • 对于3项标准中的每一项进行打分,每满足一项打分为1,然后每个因子看的多少分
注:打分大小看整体情况,以及选出多少因子排名之后可以选出10多个较好的因子,然后做后续相关性分析和合成

二、单因子回测框架

当筛选出部分因子之后,其实我们还要去观察它在回测过程当中真是的收益率情况。所以要建立每个因子的回测框架,主要对不同分位数上的股票收益进行统计。也就是下面这张图

2.1 代码

# 可以自己import我们平台支持的第三方python模块,比如pandas、numpy等。
# 建立单因子的回测框架
# 回测区间 2017-01-01~2018-01-01
# 调仓频率:一个月,买卖判断
import numpy as np


# 在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递。
def init(context):
    # 在context中保存全局变量
    context.quantile = 5

    scheduler.run_monthly(factor_rollback, tradingday=1)


def factor_rollback(context, bar_dict):
    # 选出因子数据,选出不同组的位置进行回测
    q = query(fundamentals.financial_indicator.earnings_per_share)

    fund = get_fundamentals(q)

    # 进行数据处理
    # 变成行是股票、列是指标的数据
    factor = fund.T

    # 去极值、标准化
    factor['earnings_per_share'] = mad(factor['earnings_per_share'])
    factor['earnings_per_share'] = stand(factor['earnings_per_share'])

    # 求分位数是对于一列数据,dataframe求不了
    data = factor.iloc[:, 0]

    # 按照分位去分成5组,分别进行回测
    # quantie(0.2)
    # [0.2, 0.4, 0.6, 0.8]
    if context.quantile == 1:
        data = data[data <= data.quantile(0.2)]
    elif context.quantile == 2:
        data = data[(data > data.quantile(0.2)) & (data <= data.quantile(0.4))]
    elif context.quantile == 3:
        data = data[(data > data.quantile(0.4)) & (data <= data.quantile(0.6))]
    elif context.quantile == 4:
        data = data[(data > data.quantile(0.6)) & (data <= data.quantile(0.8))]
    elif context.quantile == 5:
        data = data[data > data.quantile(0.8)]

    # 建立回测的股票池
    context.stock_list = data.index

    # 卖
    for stock in context.portfolio.positions.keys():

        # 判断股票仓位是否>0
        if context.portfolio.positions[stock].quantity > 0:

            if stock not in context.stock_list:
                order_target_percent(stock, 0)

    weight = 1.0 / len(context.stock_list)
    # 卖
    for stock in context.stock_list:
        order_target_percent(stock, weight)


# before_trading此函数会在每天策略交易开始前被调用,当天只会被调用一次
def before_trading(context):
    pass


# 你选择的证券的数据更新将会触发此段逻辑,例如日或分钟历史数据切片或者是实时数据切片更新
def handle_bar(context, bar_dict):
    # 开始编写你的主要的算法逻辑
    pass


# after_trading函数会在每天交易结束后被调用,当天只会被调用一次
def after_trading(context):
    pass


def mad(factor):
    """3倍中位数去极值
    """
    # 求出因子值的中位数
    med = np.median(factor)

    # 求出因子值与中位数的差值,进行绝对值
    mad = np.median(np.abs(factor - med))

    # 定义几倍的中位数上下限
    high = med + (3 * 1.4826 * mad)
    low = med - (3 * 1.4826 * mad)

    # 替换上下限以外的值
    factor = np.where(factor > high, high, factor)
    factor = np.where(factor < low, low, factor)
    return factor


def stand(factor):
    """自实现标准化
    """
    mean = factor.mean()
    std = factor.std()
    return (factor - mean) / std

 

以上是关于单因子测试框架和单因子回测框架搭建的主要内容,如果未能解决你的问题,请参考以下文章

多因子策略-回测阶段应用

如何看待量化交易的回测?

单因子有效性分析-因子收益率分析

量化交易单因子有效性分析目的

多因子模型用啥数据

day33 Python与金融量化分析