量化交易 实战之单因子回测框架

概述

之前我们在研究平台上所做的因子 IC 分析和因子收益率分析都属于因子的测试框架. 因为我们使用的第三方平台, 所以没有办法做一个比较完整的通用的测试系统. 但是目的是为了测试表现较好的, 所以本节我们来建立一个测试系统.

因子排名

统计完结果之后我们需要对上百个因子进行一次筛选.

构建打分依据:

  • 因子平均收益 > 0.002
  • IC > 0.02
  • IR > 0.3
  • 对于 3 项标准中的每一项进行打分, 每满足一项打分为 1, 然后每个因子看的多少分

单因子回测框架

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

代码实现

代码

# 建立单因子的回测框架
# 回测区间2020-01-01到2021-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)

    # 转置
    fund = fund.T

    # 去极值, 标准化
    fund["earnings_per_share"] = mad(fund["earnings_per_share"])
    fund["earnings_per_share"] = stand(fund["earnings_per_share"])

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

    # 按照分位去分成5组, 分别进行回测
    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():
        # 判断是否还在股票池
        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


def mad(factor):
    """3倍中位数去极值"""
    
    # 求出因子值的中位数
    median = np.median(factor)
    
    # 求出因子值与中位数的差值, 进行绝对值
    mad = np.median(abs(factor - median))
    
    # 定义几倍的中位数上下限
    high = median + (3 * 1.4826 * mad)
    low = median - (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

quantile = 1

在这里插入图片描述

quantile = 2

在这里插入图片描述

quantile = 3

在这里插入图片描述

quantile = 4

在这里插入图片描述

quantile = 5

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_46274168/article/details/115060198