用于因子策略回测效果检查
'''
根据研究结论编写的策略,由于研究中多空组合的收益中,空头贡献了重要的部分(约50%),由于回测中不能做空,所以策略的收益相对研究中较低。
by wunderkindye
'''
'''
根据聚宽高频因子挖掘大赛比赛专用模板修改
初始资金:2000000
建议回测时间范围
每日调仓 一年 回测日期:20180720-20190720
每周调仓 三年 回测日期:20160720-20190720
每月调仓 五年 回测日期:20140720-20190720
股票池:中证500
每日持仓:数量固定为股票池的20只,持仓均为等权重持有
换仓时间:默认14:50
交易成本:不考虑滑点,印花税1‰,佣金2.5‱、最低5元
'''
# 导入函数库
from jqdata import *
import numpy as np
import pandas as pd
import jqfactor
################################################# 以下内容根据研究因子内容定义 ########################################################
# 定义因子
def calc_factor(context):
'''
用户自定义因子,要求返回一个 Series,index为股票code,value为因子值
我们会买入「因子值最小」的20只,如果您想使用买入「因子值最大」的20只股票,只需将您的结果「乘以-1.0」即可,详见函数下方 return 部分
'''
# 获取股票池,g.stock_pool为因子挖掘的对象股票池,用户不可对此股票池进行二次筛选
stocks = g.stock_pool
# 获取当前时间
now = context.current_dt
# 获取数据
close = get_price(stocks,end_date=context.previous_date,count=21,fields=['close'])['close']
money = get_price(stocks,end_date=context.previous_date,count=21,fields=['money'])['money']
cap = get_fundamentals(query(
valuation.circulating_market_cap
).filter(
valuation.code.in_(stocks)
), date=context.previous_date)
far = close.iloc[-1,:]/close.iloc[0,:] - 1
#far = sum(close.iloc[:,:])/(21*close.iloc[-1,:])-1 研报中的优化思路:均线价格代替期末期初价格差,然而实证检验效果不佳
money = (sum(money.iloc[:,:]))
cap = pd.Series(cap['circulating_market_cap'].values, index=far.index)
result = (far.iloc[:]/(money.iloc[:]/(cap.iloc[:]*100000000)))
return result
# 开盘前运行函数
def before_market_open(context):
'''
盘后运行函数,可选实现
'''
pass
## 收盘后运行函数
def after_market_close(context):
'''
盘后运行函数,可选实现
'''
pass
################################################# 以下内容除设置运行周期,其他地方不用修改 ########################################################
# 初始化函数,设定基准等等
def initialize(context):
# 设定500等权作为基准
g.benchmark = '000982.XSHG'
set_benchmark(g.benchmark)
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
### 股票相关设定 ###
# 股票类每笔交易时的手续费
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.00025, close_commission=0.00025, min_commission=5),type='stock')
# 滑点
set_slippage(FixedSlippage(0.0))
# 初始化因子设置
factor_analysis_initialize(context)
# 定义股票池
set_stockpool(context)
# 运行函数(reference_security为运行时间的参考标的;传入的标的只做种类区分,因此传入'000300.XSHG'或'510300.XSHG'是一样的)
run_daily(set_stockpool, time='before_open', reference_security='000300.XSHG')
run_daily(before_market_open, time='before_open', reference_security='000300.XSHG')
#设置策略交易时间间隔
#run_daily(trade, time='14:50', reference_security='000300.XSHG')
run_weekly(trade,1, time='14:50', reference_security='000300.XSHG')
#run_monthly(trade,1, time='14:50', reference_security='000300.XSHG')
run_daily(after_market_close, time='after_close', reference_security='000300.XSHG')
# 定义股票池
def set_stockpool(context):
# 获取股票池
stocks = get_index_stocks(g.benchmark,context.previous_date)
paused_series = get_price(stocks,end_date=context.current_dt,count=1,fields='paused')['paused'].iloc[0]
# g.stock_pool 为因子挖掘的对象股票池,用户不可对此股票池进行二次筛选
g.stock_pool = paused_series[paused_series==False].index.tolist()
# 定义需要用到的全局变量
def factor_analysis_initialize(context):
# g.weight_method 为加权方式, "avg"按平均加权
g.weight_method = "avg"
weight_method_model = {"avg": "平均加权"}
# 持仓股票数量
g.buy_num = 20
# g.sell为卖出股票权重列表
g.sell = pd.Series(dtype=float)
# g.buy为买入股票权重列表
g.buy = pd.Series(dtype=float)
#g.ind为行业分类
g.ind = 'jq_l1'
# g.d 为获取昨天的时间点
g.d = context.previous_date
# 对因子进行分析计算出每日买入或卖出的股票
def fac(context):
# 获取因子值
far = calc_factor(context)
# 买入股票池
try:
buy = far.sort_values(ascending=True).index.tolist()[:g.buy_num]
except:
buy = far.order(ascending=True).index.tolist()[:g.buy_num]
# 买卖股票权重
if g.weight_method == "avg":
buy_weight = pd.Series(1. / len(buy), index=buy)
else:
raise ValueError('invalid weight_method %s', weight_method)
return buy_weight
#股票交易
def trade(context):
# 计算买入卖出的股票和权重
try:
factor_analysis_initialize(context)
g.buy = fac(context)
except ValueError:
if "Bin edges must be unique" in str(e):
log.error("计算因子值过程出错!")
else:
raise
for s in context.portfolio.positions.keys():
if s not in g.buy.index:
order_target_value(s, 0)
long_cash = context.portfolio.total_value
for s in g.buy.index:
order_target_value(s, g.buy.loc[s] * 0.98 * long_cash)
# 买入股票
def buy(context):
# 计算买入卖出的股票和权重
try:
factor_analysis_initialize(context)
g.buy = fac(context)
except ValueError:
if "Bin edges must be unique" in str(e):
log.error("计算因子值过程出错!")
else:
raise
long_cash = context.portfolio.total_value
for s in g.buy.index:
order_target_value(s, g.buy.loc[s] * 0.98 * long_cash)
# 卖出股票
def sell(context):
for s in context.portfolio.positions.keys():
order_target_value(s, 0)
#导入需要的数据库
from jqfactor import *
from jqdata import *
import pandas as pd
import warnings
warnings.filterwarnings('ignore')
#获取日期列表
def get_tradeday_list(start,end,frequency=None,count=None):
if count != None:
df = get_price('000001.XSHG',end_date=end,count=count)
else:
df = get_price('000001.XSHG',start_date=start,end_date=end)
if frequency == None or frequency =='day':
return df.index
else:
df['year-month'] = [str(i)[0:7] for i in df.index]
if frequency == 'month':
return df.drop_duplicates('year-month').index
elif frequency == 'quarter':
df['month'] = [str(i)[5:7] for i in df.index]
df = df[(df['month']=='01') | (df['month']=='04') | (df['month']=='07') | (df['month']=='10') ]
return df.drop_duplicates('year-month').index
elif frequency =='halfyear':
df['month'] = [str(i)[5:7] for i in df.index]
df = df[(df['month']=='01') | (df['month']=='06')]
return df.drop_duplicates('year-month').index
# 设置起止时间
start='2018-07-20'
end='2019-07-20'
# 设置调仓周期
periods=(5,10,20)
# 设置分层数量
quantiles=5
#获取日期列表
date_list = get_tradeday_list(start=start,end=end,count=None)#获取回测日期间的所有交易日
研报中提出,A股市场的反转现象是由于散户比例高,导致市场的非理性与羊群效应,因此股票的价格变化往往存在过度变化的情况,后续会反向调整。
继而,研报中提出的因子优化的思路之一,是通过中性化(提取横截面回归残差),去除动量/反转因子中含有的流动性因子(流动性因子作为散户数量的代理变量,散户越多,该股票被交易的频率越高,从而有较高的流动性。
原来的模板中也在注释中给出了中性化处理的代码,但经检验,中性化处理对因子IC,IR值的改善贡献不大。仔细思考,中性化处理(提取截面回归残差)其实是基于线性回归模型,即假设因变量(21天前后股票价格差)和自变量(流动性/散户交易占比)呈线性关系。但其实这样的假设并不太合理,直觉上,散户参与交易不应固定地使股票21天后的价格比21天前的价格更高或更低,而应是放大21天前后的价格差。本来上涨的股票因为散户的参与涨的更多,本来下跌的股票下跌更多。
对应的,在本研究中替代原来的中性化处理,用“21天前后价格差/21天平均换手率之和”作为改良后的因子。
def factor_cal(pool,date):
close = get_price(pool,end_date=date,count=21,fields=['close'])['close']#获取收盘价
money = get_price(pool,end_date=date,count=21,fields=['money'])['money']#获取交易额
cap = get_fundamentals(query(
valuation.circulating_market_cap
).filter(
valuation.code.in_(pool)
), date=date) #获取股票流通市值,用于计算换手率用
far = close.iloc[-1,:]/close.iloc[0,:] - 1 #21天前后价差
#far = sum(close.iloc[:,:])/(21*close.iloc[-1,:])-1 用于研报中的另一种改良思路,用平均价格代替时间点价格,但检验发现效果不佳
money = (sum(money.iloc[:,:])/21.) #计算平均换手率
cap = pd.Series(cap['circulating_market_cap'].values, index=far.index)
result = (far.iloc[:]/(money.iloc[:]/(cap.iloc[:]*100000000))) #计算因子值:股价差/平均换手率
return result
#定义一个空的dataframe记录因子值
factor_df = pd.DataFrame()
#循环计算给定日期范围的因子值
mark = 1
print (len(date_list))
for d in date_list:
try: #获取流通市值的函数在零星几天会失败,因此这里用try处理
pool = get_index_stocks('000905.XSHG',date=d)
far = factor_cal(pool,d)
if mark == 1:
factor_df = far
mark = 0
else:
factor_df = pd.concat([factor_df,far],axis=1)
except:
date_list=date_list.drop(d)
continue
#将columns更改为可以日期标签
factor_df.columns = date_list
factor_df.head(3)
229
2018-07-20 00:00:00 | 2018-07-23 00:00:00 | 2018-07-24 00:00:00 | 2018-07-25 00:00:00 | 2018-07-26 00:00:00 | 2018-07-27 00:00:00 | 2018-07-30 00:00:00 | 2018-07-31 00:00:00 | 2018-08-01 00:00:00 | 2018-08-02 00:00:00 | 2018-08-03 00:00:00 | 2018-08-06 00:00:00 | 2018-08-07 00:00:00 | 2018-08-08 00:00:00 | 2018-08-09 00:00:00 | 2018-08-10 00:00:00 | 2018-08-13 00:00:00 | 2018-08-14 00:00:00 | 2018-08-15 00:00:00 | 2018-08-16 00:00:00 | 2018-08-17 00:00:00 | 2018-08-20 00:00:00 | 2018-08-21 00:00:00 | 2018-08-22 00:00:00 | 2018-08-23 00:00:00 | 2018-08-24 00:00:00 | 2018-08-27 00:00:00 | 2018-08-28 00:00:00 | 2018-08-29 00:00:00 | 2018-08-30 00:00:00 | 2018-08-31 00:00:00 | 2018-09-03 00:00:00 | 2018-09-04 00:00:00 | 2018-09-05 00:00:00 | 2018-09-06 00:00:00 | 2018-09-07 00:00:00 | 2018-09-10 00:00:00 | 2018-09-11 00:00:00 | 2018-09-12 00:00:00 | 2018-09-13 00:00:00 | ... | 2019-05-23 00:00:00 | 2019-05-24 00:00:00 | 2019-05-27 00:00:00 | 2019-05-28 00:00:00 | 2019-05-29 00:00:00 | 2019-05-30 00:00:00 | 2019-05-31 00:00:00 | 2019-06-03 00:00:00 | 2019-06-04 00:00:00 | 2019-06-05 00:00:00 | 2019-06-06 00:00:00 | 2019-06-10 00:00:00 | 2019-06-11 00:00:00 | 2019-06-12 00:00:00 | 2019-06-13 00:00:00 | 2019-06-14 00:00:00 | 2019-06-18 00:00:00 | 2019-06-19 00:00:00 | 2019-06-20 00:00:00 | 2019-06-21 00:00:00 | 2019-06-24 00:00:00 | 2019-06-25 00:00:00 | 2019-06-26 00:00:00 | 2019-06-27 00:00:00 | 2019-06-28 00:00:00 | 2019-07-01 00:00:00 | 2019-07-02 00:00:00 | 2019-07-03 00:00:00 | 2019-07-04 00:00:00 | 2019-07-05 00:00:00 | 2019-07-08 00:00:00 | 2019-07-09 00:00:00 | 2019-07-10 00:00:00 | 2019-07-11 00:00:00 | 2019-07-12 00:00:00 | 2019-07-15 00:00:00 | 2019-07-16 00:00:00 | 2019-07-17 00:00:00 | 2019-07-18 00:00:00 | 2019-07-19 00:00:00 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
000006.XSHE | -11.612745 | -8.822291 | -2.804284 | 1.039448 | 2.607539 | 4.366568 | 10.592364 | 4.543292 | 1.076872 | 1.956700 | 3.622247 | -0.443105 | 1.122533 | 3.695890 | 2.978716 | 5.902382 | 3.093861 | 4.125538 | 0.824253 | 0.819768 | -2.380844 | -2.780592 | -5.464474 | -7.415165 | -6.221536 | -10.484775 | -7.782507 | -6.184067 | -5.14282 | 0.853220 | -1.999657 | -0.293819 | -2.905727 | -5.116281 | -9.219400 | -14.772072 | -15.371927 | -16.109292 | -13.156837 | -10.643322 | ... | -22.536138 | -20.438054 | -16.099421 | -11.853769 | -12.006430 | -13.915655 | -14.650752 | -2.212839 | -6.991088 | -4.903990 | -4.048379 | -6.514469 | -0.981977 | 0.000000 | -3.607311 | -5.789223 | 2.651802 | 1.074806 | 6.495696 | 13.550430 | 9.456650 | -1.048775 | 1.551917 | 4.205654 | 6.588853 | 11.996389 | 10.980852 | 12.245196 | 14.244738 | 15.079810 | 4.726903 | -1.164855 | -1.989418 | -1.243770 | 0.849276 | -1.249118 | 1.275299 | -0.431189 | -8.170143 | -4.200764 |
000008.XSHE | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | -884.535488 | -535.198174 | -42.729120 | -37.554268 | -34.645050 | -31.211878 | -30.726857 | -30.329145 | -30.318045 | -28.426219 | -26.891679 | -26.122216 | -25.213660 | -21.442916 | -19.349874 | -18.245008 | -17.57392 | -17.011913 | -16.570262 | -11.336435 | -3.525320 | 4.981456 | 7.240363 | 15.275918 | 14.981741 | 12.870928 | 16.353180 | 17.322943 | ... | -17.785247 | -19.157550 | -19.796848 | -15.740444 | -17.928318 | -10.215782 | -14.144714 | -6.180066 | -8.580232 | -6.868011 | -8.704236 | -10.870437 | -6.828312 | -5.710932 | -7.610949 | -9.765632 | -4.221317 | -3.026805 | 0.879575 | 8.069342 | 9.167814 | 3.106551 | 0.000000 | 2.754585 | -2.638563 | 3.741663 | 2.816808 | 4.759953 | 4.332258 | 6.335657 | -2.211424 | -4.707778 | -5.640526 | -7.845485 | -5.341588 | -4.445708 | -2.249854 | -6.465664 | -9.892760 | -6.043667 |
000009.XSHE | 7.304329 | 9.621554 | 10.216285 | 11.478340 | 13.684456 | 6.307995 | 7.353449 | 5.643813 | 6.079397 | 1.680724 | -0.422693 | -8.224606 | -5.504451 | -2.617163 | -3.042096 | -3.116585 | -6.196279 | -13.189073 | -16.236953 | -12.261096 | -19.714641 | -19.424256 | -22.362643 | -23.346523 | -24.970627 | -25.172207 | -15.846900 | -19.024696 | -16.33447 | -8.555411 | -4.973640 | 0.000000 | -4.968825 | -8.245219 | -17.030172 | -16.461075 | -22.367305 | -20.388025 | -13.567214 | -7.795580 | ... | -9.044784 | -9.032605 | -8.920340 | -4.412703 | -3.079215 | 0.781228 | -5.009636 | -3.251170 | -5.016200 | -2.951018 | -2.851141 | -3.493290 | 0.414500 | 1.037941 | -0.817814 | -4.771357 | -0.667633 | -4.075817 | 1.166682 | 0.470331 | 2.596835 | 3.216418 | 0.000000 | -2.641624 | -3.006762 | 1.302794 | 5.348396 | 4.022485 | 3.792998 | 9.430496 | 0.000000 | -3.931449 | -5.412028 | -6.934928 | -3.835362 | -0.613031 | 1.247859 | -1.549943 | -6.791388 | -7.353609 |
#数据清洗、包括去极值、标准化、中性化等,并加入y值
for date in date_list:
#对数据进行处理、标准化、去极值、中性化
#factor_df = winsorize_med(factor_df, scale=3, inclusive=True, inf2nan=True, axis=0) #中位数去极值处理
se = standardlize(factor_df[date], inf2nan=True) #对每列做标准化处理
factor_df[date] = se
#进行转置,调整为分析可用的格式
factor_df = factor_df.T
factor_df.head()
000006.XSHE | 000008.XSHE | 000009.XSHE | 000012.XSHE | 000021.XSHE | 000025.XSHE | 000027.XSHE | 000028.XSHE | 000031.XSHE | 000039.XSHE | 000049.XSHE | 000060.XSHE | 000061.XSHE | 000062.XSHE | 000066.XSHE | 000078.XSHE | 000089.XSHE | 000090.XSHE | 000156.XSHE | 000158.XSHE | 000301.XSHE | 000400.XSHE | 000401.XSHE | 000418.XSHE | 000426.XSHE | 000488.XSHE | 000501.XSHE | 000513.XSHE | 000519.XSHE | 000528.XSHE | 000536.XSHE | 000537.XSHE | 000541.XSHE | 000543.XSHE | 000547.XSHE | 000552.XSHE | 000553.XSHE | 000559.XSHE | 000563.XSHE | 000564.XSHE | ... | 601990.XSHG | 603000.XSHG | 603019.XSHG | 603025.XSHG | 603056.XSHG | 603077.XSHG | 603169.XSHG | 603188.XSHG | 603198.XSHG | 603225.XSHG | 603228.XSHG | 603233.XSHG | 603328.XSHG | 603355.XSHG | 603369.XSHG | 603377.XSHG | 603444.XSHG | 603486.XSHG | 603501.XSHG | 603515.XSHG | 603517.XSHG | 603556.XSHG | 603568.XSHG | 603569.XSHG | 603589.XSHG | 603650.XSHG | 603658.XSHG | 603659.XSHG | 603712.XSHG | 603766.XSHG | 603806.XSHG | 603816.XSHG | 603866.XSHG | 603868.XSHG | 603877.XSHG | 603883.XSHG | 603885.XSHG | 603888.XSHG | 603899.XSHG | 603939.XSHG | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2018-07-20 | -0.870088 | NaN | 0.472244 | -0.470108 | 0.875667 | -0.014138 | 0.411904 | -1.333933 | -1.199218 | -0.798022 | 0.405831 | NaN | -2.210211 | 1.041722 | 0.505837 | -1.121608 | 0.779599 | -1.656187 | -2.885027 | -1.141462 | NaN | 0.555043 | 0.226158 | -2.066377 | NaN | -0.431978 | -0.972066 | 0.111684 | 0.476672 | 0.053055 | -0.285180 | NaN | -0.310197 | 1.440075 | 0.015036 | -0.543669 | -0.091906 | NaN | -0.731492 | NaN | ... | NaN | -0.471730 | 0.722339 | 1.236778 | -0.077640 | 0.629311 | 0.527204 | 1.036853 | -0.584802 | 0.246333 | 0.920087 | NaN | 4.106038 | 3.213797 | -0.746324 | -0.613145 | -0.115925 | NaN | NaN | -0.545252 | NaN | -0.004294 | -1.070643 | 0.198972 | -0.754378 | NaN | -0.313076 | -0.148719 | NaN | 0.522567 | 0.869291 | -0.345579 | NaN | 0.179888 | 0.240653 | 0.442496 | -1.475229 | -0.210908 | -0.568581 | NaN |
2018-07-23 | -0.861006 | NaN | 0.412071 | -0.170145 | 0.886169 | -0.164529 | 0.742954 | -1.634026 | -0.984491 | -0.661180 | 0.222060 | NaN | -1.256626 | 1.348840 | 0.429924 | -1.235356 | 0.376356 | -1.653100 | -2.823700 | -1.302780 | NaN | 0.650629 | 0.332597 | -1.812079 | NaN | -0.378172 | -0.804527 | -0.379619 | 0.269545 | -0.074263 | -0.192971 | NaN | -0.095334 | 1.743807 | 0.108903 | -0.449485 | -0.192226 | NaN | -1.532472 | NaN | ... | NaN | -0.346953 | 0.551535 | 2.405893 | -0.299463 | 0.447682 | 0.434596 | 1.374870 | -1.094550 | 0.196579 | 0.746806 | NaN | 3.008670 | 2.413048 | -1.188156 | -0.680031 | -0.181470 | NaN | NaN | -0.732495 | NaN | -0.481148 | -0.752212 | 0.045561 | -1.179439 | NaN | -0.698048 | -0.346096 | NaN | 0.980939 | 1.481784 | -0.666809 | NaN | 0.129736 | -0.444896 | -0.166735 | -0.542082 | -0.171055 | -1.657876 | NaN |
2018-07-24 | -0.608539 | NaN | 0.271694 | 0.155494 | 0.376217 | -0.312353 | 2.432267 | -1.362854 | -0.233866 | -0.418961 | -0.017016 | NaN | -0.749284 | 0.934951 | -0.004881 | -1.242849 | 0.581258 | -0.390872 | -1.509734 | -1.421760 | NaN | 0.688310 | 0.700782 | -1.487865 | NaN | -0.229100 | -0.929626 | -0.422155 | 0.009714 | -0.286290 | -0.143150 | NaN | 0.268918 | 1.235722 | -0.088122 | -0.130984 | -0.372996 | NaN | -2.000903 | NaN | ... | NaN | -0.141132 | 0.162645 | 2.345000 | -0.471836 | 0.392809 | -0.160415 | 0.904667 | -0.604277 | 0.044091 | 0.404300 | NaN | 2.412934 | 2.706682 | -1.273929 | -0.725280 | -0.323685 | NaN | NaN | -0.561169 | NaN | -0.630317 | -1.060128 | -0.156635 | -0.969306 | NaN | -0.753179 | -0.568804 | NaN | 0.563373 | 2.462729 | -0.625769 | NaN | 0.091430 | -1.124914 | -0.876723 | -0.457707 | -0.295706 | -1.162420 | NaN |
2018-07-25 | -0.445218 | NaN | 0.290948 | 0.419781 | 0.312331 | -0.291990 | 1.959376 | -1.327793 | -0.060950 | -0.433840 | -0.132887 | NaN | -0.930202 | 0.884997 | -0.072762 | -1.290052 | 0.698484 | -0.651253 | -0.911961 | -1.244367 | NaN | 0.740520 | 0.811219 | -1.671038 | NaN | -0.413167 | -0.878480 | -0.067857 | -0.040785 | -0.228683 | -0.074149 | NaN | 0.329078 | 1.372648 | -0.109476 | -0.276359 | -0.494766 | NaN | -1.081837 | NaN | ... | NaN | -0.003308 | 0.071776 | 3.129088 | -0.610164 | 0.437925 | 0.997283 | 1.085465 | -0.351921 | -0.090329 | 0.197536 | NaN | 1.719629 | 3.027563 | -1.101706 | -0.681717 | -0.332002 | NaN | NaN | -0.598471 | NaN | -0.657594 | -0.313263 | -0.339560 | -0.746412 | NaN | -0.665355 | -0.668788 | NaN | 0.413456 | 0.893097 | -0.614248 | NaN | 0.633211 | -1.307281 | -0.854785 | -0.292175 | -0.277199 | -0.976616 | NaN |
2018-07-26 | -0.408908 | NaN | 0.318737 | 0.388727 | 0.124369 | -0.413213 | 1.860660 | -1.263172 | 0.884298 | -0.550724 | -0.289109 | NaN | 0.058308 | 1.132202 | -0.270724 | -1.124162 | 0.554888 | -0.459622 | -0.368961 | -1.114500 | NaN | 0.849258 | 0.625598 | -1.739112 | NaN | -0.591635 | -0.848536 | 0.237046 | -0.115913 | -0.315208 | 0.335211 | NaN | 0.344520 | 1.413403 | -0.032533 | -0.364395 | -0.594669 | NaN | -0.844878 | NaN | ... | NaN | 0.344744 | -0.153229 | 1.780345 | -0.609763 | 0.613902 | 0.557880 | 0.981468 | -0.189435 | -0.339548 | 0.091403 | NaN | 1.186661 | 0.868546 | -1.191273 | -0.599561 | -0.528395 | NaN | NaN | -0.471456 | NaN | -0.888867 | -0.639720 | -0.272861 | -0.763325 | NaN | -0.517306 | -0.656294 | NaN | 0.774216 | -0.414850 | -0.859926 | NaN | 0.244860 | -1.359304 | -1.098743 | -0.466743 | -0.277365 | -0.711164 | NaN |
#使用获取的因子值进行单因子分析
far = analyze_factor(factor=-factor_df, start_date=date_list[0], end_date=date_list[-1], weight_method='avg', industry='jq_l1', quantiles=quantiles, periods=periods,max_loss=0.3)
IC分析
# 打印信息比率(IC)相关表
far.plot_information_table(group_adjust=False, method='rank')
IC 分析
period_5 | period_10 | period_20 | |
---|---|---|---|
IC Mean | 0.059 | 0.075 | 0.061 |
IC Std. | 0.151 | 0.147 | 0.149 |
IR | 0.389 | 0.513 | 0.409 |
t-stat(IC) | 5.889 | 7.764 | 6.184 |
p-value(IC) | 0.000 | 0.000 | 0.000 |
IC Skew | -0.209 | -0.145 | 0.500 |
IC Kurtosis | -0.312 | 0.159 | 0.157 |
分组收益
# 画各分位数平均收益图
far.plot_quantile_returns_bar(by_group=False, demeaned=0, group_adjust=False)
<Figure size 432x288 with 0 Axes>
#调用因子分析方法,进行因子信息全览,主要关注做多最大分位做空最小分位的收益
far.create_full_tear_sheet(demeaned=False, group_adjust=False, by_group=False, turnover_periods=None, avgretplot=(5, 15), std_bar=False)
分位数统计
min | max | mean | std | count | count % | |
---|---|---|---|---|---|---|
factor_quantile | ||||||
1 | -11.202149 | -0.056701 | -1.099604 | 0.969796 | 22694 | 20.045578 |
2 | -0.714156 | 0.121010 | -0.261042 | 0.176513 | 22628 | 19.987281 |
3 | -0.391428 | 0.455564 | 0.039860 | 0.161549 | 22598 | 19.960782 |
4 | -0.071958 | 0.766691 | 0.316832 | 0.211695 | 22625 | 19.984631 |
5 | -0.055103 | 22.282995 | 1.005523 | 1.248903 | 22667 | 20.021729 |
------------------------- 收益分析
period_5 | period_10 | period_20 | |
---|---|---|---|
Ann. alpha | -0.547 | -0.311 | -0.166 |
beta | 0.167 | 0.142 | 0.195 |
Mean Period Wise Return Top Quantile (bps) | 3.773 | 5.751 | 3.757 |
Mean Period Wise Return Bottom Quantile (bps) | -6.920 | -6.021 | -5.089 |
Mean Period Wise Spread (bps) | 10.216 | 11.022 | 7.818 |
<Figure size 432x288 with 0 Axes>
<Figure size 432x288 with 0 Axes>
<Figure size 432x288 with 0 Axes>
<Figure size 432x288 with 0 Axes>
<Figure size 432x288 with 0 Axes>
------------------------- IC 分析
period_5 | period_10 | period_20 | |
---|---|---|---|
IC Mean | 0.059 | 0.075 | 0.061 |
IC Std. | 0.151 | 0.147 | 0.149 |
IR | 0.389 | 0.513 | 0.409 |
t-stat(IC) | 5.889 | 7.764 | 6.184 |
p-value(IC) | 0.000 | 0.000 | 0.000 |
IC Skew | -0.209 | -0.145 | 0.500 |
IC Kurtosis | -0.312 | 0.159 | 0.157 |
<Figure size 432x288 with 0 Axes>
<Figure size 432x288 with 0 Axes>
<Figure size 432x288 with 0 Axes>
------------------------- 换手率分析
period_10 | period_20 | period_5 | |
---|---|---|---|
Quantile 1 Mean Turnover | 0.565 | 0.769 | 0.399 |
Quantile 2 Mean Turnover | 0.728 | 0.797 | 0.630 |
Quantile 3 Mean Turnover | 0.739 | 0.775 | 0.663 |
Quantile 4 Mean Turnover | 0.723 | 0.798 | 0.626 |
Quantile 5 Mean Turnover | 0.590 | 0.795 | 0.421 |
period_5 | period_10 | period_20 | |
---|---|---|---|
Mean Factor Rank Autocorrelation | 0.651 | 0.378 | -0.038 |
<Figure size 432x288 with 0 Axes>
<Figure size 432x288 with 0 Axes>
-------------------------
<Figure size 432x288 with 0 Axes>
IC分析显示,改良后的因子IC值与原因子相近,但标准差有所降低,即信息系数的稳定性得到提升。IR最低值为0.389,表现较稳健。
分组收益显示,在三种持有周期下,收益的组间单调性表现优秀,相比原来的因子有明显提升。
做多最大分位做空最小分位的多空组合显示收益较稳健,持有10天的多空组合年化收益接近15%,回测周期中上半年内的因子效率有待提升。
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程