研究目的:本文参考广发证券《基于日内高频数据的短周期选股因子研究-高频数据因子研究系列一》,对研报内的结果进行分析,基本复制出该研报中上证500相关的结果,本文大量引用了该研报中对结果的叙述。
研究内容:在个股高频数据中,主要包括开盘价、收盘价、最高价、最低价、成交量、成交额等指标以及分笔的盘口相关的数据。本篇专题报告主要是对个股的分钟级别的成交相关的数据进行因子挖掘,希望能从中挖掘出有效的因子指标。
测试时段:2007年1月到2019年3月
调仓方式:在每周结束时,依据高频指标将剔除ST,*ST与停盘股后的2019年3月27日时的中证500成份股划分为5组,分别持有至周末;得分最高的组合为多头组合,得分最低的为空头组合。
具体因子指标构建如下
对于每个个股在交易日$t$,首先计算个股在特定分钟频率下第$i$个的收益率$r_{t,i}$ ,$r_{t,i} = p_{t,i}-p_{t,i-1}$,其中$p_{t,i}$表示在交易日$t$,个股在第$i$个特定分钟频率下的对数价格,$p_{t,i−1}$表示在交易日$t$,个股在第$i-1$个特定分钟频率下的对数价格。
对于每个个股,根据$r_{t,i}$分别计算个股在交易日$t$下的
已实现方差(RealizedVariance),$$RDVar_t=\sum_{i=1,N}r_{t,i}^2$$已实现偏度(Realized Skewness),$$RDSkew_t=\frac{\sqrt{N}\sum_{t=1}^N r_{t,i}^3}{RDVar_t^{3/2}}$$已实现峰度(Realized kurtosis),$$RDKurt_t=\frac{N\sum_{t=1}^N r_{t,i}^4}{RDVar_t^2}$$
$N$表示个股在交易日t中特定频率的分钟级别数据个数,如在5分钟级别下,交易日t下共有的数据个数$N$为$48(60\prod4/5=48)$。
对于每个个股,在交易日t计算,其中:
已实现波动(Realized Volatility),$$RVol_t=\left(\frac{242}{n}\sum_{i=0}^n RDVar_{t-i}\right)^{1/2}$$已实现偏度(Realized Skewness),
$$RSkew_t=\frac{1}{n}\sum_{i=0}^n RDSkew_{t-i}$$已实现峰度(Realized Kurtosis),$$RKurt_t=\frac{1}{n}\sum_{i=0}^n RDKurt_{t-i}$$
数据说明
样本区间:2007年1月1日至2019年3月27日(以下如无特别说明,2019年指的是2019年1月1日至2019年3月27日)
样本范围:全市场个股、中证500历史成分股
数据频率:个股每个交易日5分钟频率的收盘价、成交量、成交额等数据
策略构建
实证区间:2007年1月1日至2019年3月27日
选股范围:全市场、中证500历史成分股,剔除上市不满一年的股票,剔除ST股票、*ST股票,剔除交易日停牌的股票
分档方式:根据当期个股计算的因子值:已实现波动(Realized Volatility) $RVol_t$,已实现偏度(Realized Skewness)$RSkew_t$ 、已实现峰度(Realized Kurtosis)$RKurt_t$,从小到大分为5档
调仓周期:周频换仓,Q1档为因子值最小的,Q5档为因子值最大的。
研究结论:已实现偏度(Realized Skewness)指标能够对个股收益率进行明显的区分,运用该分组方式采用多空策略具有小于6%的回撤率。
研究耗时
数据准备部分:大约需要1个小时
策略构建部分:大约10min
%matplotlib inline
import pandas as pd
import numpy as np
from tqdm import tqdm
import datetime as dt
from collections import defaultdict
import itertools
import pickle
import warnings
warnings.filterwarnings('ignore')
N=48;n=5
base='000905.XSHG'
START_DATE='2007-1-1'
END_DATE='2019-3-27'
由于5分钟高频数据数量巨大,我将逐个股提取后计算$RDVar_{t,i}$等日度指标,将5分钟高频数据数据转变为日度数据保存,此过程同时剔除了ST股票,停盘股以及小于一年(242个交易日)的股票。数据存储于
百度盘链接: https://pan.baidu.com/s/1WcdR6KKDBSSr0A4mwx3hIA
提取码: yh34
# 生成并保存数据
Codes=get_index_stocks(base,date=END_DATE)
sts=get_extras('is_st', Codes, start_date=START_DATE,\
end_date=END_DATE,df=True)# 记录ST股票
Codes=sts.T.index[~sts.any(axis=0)].tolist()
def SolveADay(rlist):# 根据一天计算指标
rlist=np.diff(np.log(rlist))
RDVar=np.sum(rlist**2)
RDSkew=np.sqrt(N)*np.sum(rlist**3)/RDVar**1.5
RDKurt=N*np.sum(rlist**4)/RDVar**2
return pd.Series([RDVar,RDSkew,RDKurt])
basicFactors=[]
for code in tqdm(Codes):# 按股票代码获取数据
codePrice=get_price(code, start_date=START_DATE, end_date=END_DATE,skip_paused=True,# 去除停牌
frequency='5m', fields=['close'])
codePriceResampled=codePrice['close'].resample('D')
if (codePriceResampled.count()>0).sum()<242:# 剔除小于一年的数据
continue
else:
codePrice=codePriceResampled.apply(SolveADay).unstack(level=1).dropna()#去除不存在波动的日子
codePrice.index=pd.MultiIndex.from_product([[code],codePrice.index])
basicFactors.append(codePrice)
basicFactors=pd.concat(basicFactors)
basicFactors.columns=['RDVar','RDSkew','RDKurt']
basicFactors.index.set_names(['code','date'],inplace=True)
basicFactors.to_csv('zz500c.csv')
basicFactors=pd.read_csv('zz500c.csv',index_col=[0,1])
basicFactors.head()
basicFactors.index.set_levels([
basicFactors.index.levels[0],
pd.to_datetime(basicFactors.index.levels[1])
],inplace=True)
gWeek=pd.Grouper(freq='W', level=-1)
# 构建因子指标
RVol=np.sqrt(242/n*basicFactors['RDVar'].groupby(['code',gWeek]).sum())# 计算RVol
RSkew=1/n*basicFactors['RDSkew'].groupby(['code',gWeek]).sum()# 计算RSkew
RKurt=1/n*basicFactors['RDKurt'].groupby(['code',gWeek]).sum()# 计算RKurt
del basicFactors
中证500成分股波动率分布一览
ax=RVol.hist(bins=50,grid=False)
ax.set_ylabel('Frequency')
ax.set_title('ZZ500 Volatility')
Text(0.5, 1.0, 'ZZ500 Volatility')
中证500成分股偏度分布一览
ax=RSkew.hist(bins=50,grid=False)
ax.set_ylabel('Frequency')
ax.set_title('ZZ500 Skewness')
Text(0.5, 1.0, 'ZZ500 Skewness')
中证500成分股峰度百分位走势一览
ax=RKurt.hist(bins=50,grid=False)
ax.set_ylabel('Frequency')
ax.set_title('ZZ500 Kurtosis')
Text(0.5, 1.0, 'ZZ500 Kurtosis')
def CrossSectionalPercentiles(df):
df=df.swaplevel().sort_index()
df=df.groupby('date').apply(lambda x:np.percentile(x,[90,75,50,25,10]))
df=pd.DataFrame.from_items(zip(df.index, df.values))
df.index=[90,75,'median',25,10]
return df.T
中证500成分股波动率百分位走势一览
CrossSectionalPercentiles(RVol).plot(figsize(8,5))
<matplotlib.axes._subplots.AxesSubplot at 0x7fbb98bcd8d0>
中证500成分股偏度百分位走势一览
CrossSectionalPercentiles(RSkew).plot(figsize=(8,5))
<matplotlib.axes._subplots.AxesSubplot at 0x7fbb98a99278>
中证500成分股峰度百分位走势一览
CrossSectionalPercentiles(RKurt).plot(figsize(8,5))
<matplotlib.axes._subplots.AxesSubplot at 0x7fbb98a88d68>
利用中证500指数成分股在分钟级别的数据计算得到的关于个股的波动率、偏度、 峰度的结果,从中可以看出,个股的波动率在不同的时间维度上变化较大,从波动率分布上可以看出,中证500指数成分股波动率分布呈现右偏分布,从时间维度上看,个股的波动率水平往往与市场的趋势较为相关;个股的偏度分布 上看,整体偏度水平保持在零附近,呈现较为明显的厚尾状态,从个股偏度不同百 分位时间序列走势上可以看出,个股偏度水平整体较为稳定;从个股的峰度分布上 看,与全市场个股的峰度分布类似,在分布上呈现右偏状态,且样本内个股的峰度 水平大部分大于3,呈现出厚尾的现象。
# 提取中证500各股周收益率
Codes=list(RVol.index.levels[0])
Price=get_price(Codes, start_date=START_DATE, end_date=END_DATE,
skip_paused=False,frequency='1d', fields=['close'])
Price=Price.to_frame()['close']
Price.index.set_names(['date','code'],inplace=True)
Price=np.log(Price.groupby(['code',pd.Grouper(freq='W', level=0)]).last())
Return=np.exp(Price.groupby('code').diff().groupby('code').shift(-1)).swaplevel().sort_index()
del Price
# 提取各股市值
mktCap=[]
for date in Return.index.levels[0]:
df=get_fundamentals_continuously(
query(valuation.market_cap).filter(valuation.code.in_(Codes)),
end_date=date,count=1).to_frame()['market_cap']
df.index.set_levels([date], level=0,inplace=True)
mktCap.append(df)
mktCap=pd.concat(mktCap)
mktCap.index.set_names(['date','code'],inplace=True)
mktCap.index.set_levels([
pd.to_datetime(mktCap.index.levels[0]),mktCap.index.levels[1]
],inplace=True)
def GetGroup(df):# 依据指标分组
df=df.swaplevel().sort_index()
group=df.groupby('date').apply(lambda x:pd.qcut(x,q=5,precision=10,labels=['Q1','Q2','Q3','Q4','Q5']))
group.name='group'
return group
def GroupTestRet(group,mktCap,ret):# 计算分组后各组周收益率
df=pd.concat([mktCap,group,ret],axis=1)
df.ffill(inplace=True)
df['market_cap*return']=df['close']*df['market_cap']
df=df.groupby(['date','group'])['market_cap*return'].sum()/\
df.groupby(['date','group'])['market_cap'].sum()
return df.unstack(level=1)
因子指标RVol中证500选股分档表现
RVolLevel=GroupTestRet(GetGroup(RVol),mktCap,Return)
RVolLevel.cumprod().plot(figsize=(10,5))
<matplotlib.axes._subplots.AxesSubplot at 0x7fbb723feeb8>
因子指标RSkew中证500选股分档表现
RSkewLevel=GroupTestRet(GetGroup(RSkew),mktCap,Return)
RSkewLevel.cumprod().plot(figsize=(10,5))
<matplotlib.axes._subplots.AxesSubplot at 0x7fbb910dec88>
因子指标RKurt因中证500选股分档表现
RKurtLevel=GroupTestRet(GetGroup(RKurt),mktCap,Return)
RKurtLevel.cumprod().plot(figsize=(10,5))
<matplotlib.axes._subplots.AxesSubplot at 0x7fbb908619e8>
从图中可以看出,在周频调仓频率的结果下,因子指标RVol、RKurt在全市场中的分档不明显,对个股收益率区分度较差,而因子指标RSkew在 全市场中的分档收益表现明显,对个股收益率区分度明显,分档收益在单调性结果上显著。
中证500RSkew因子IC值走势一览
IC_RSkew=pd.concat([RSkew.swaplevel(),Return],axis=1).\
groupby('date').corr('pearson').iloc[0::2,-1].reset_index(level=1, drop=True)
IC_RSkew.name='IC'
ax=IC_RSkew.plot(figsize=(16,4),legend=True)
IC_RSkewRolling=IC_RSkew.rolling(12).mean()
IC_RSkewRolling.name='IC average(12 terms)'
IC_RSkewRolling.plot(ax=ax,color='red',legend=True)
<matplotlib.axes._subplots.AxesSubplot at 0x7fbb6d5419e8>
中证 500 指数内选股-IC 表现
aggOperator={'mean':np.mean,
'std':np.std,
'min':np.min,
'max':np.max,
'negative percentile':lambda x:'%.2f'%(np.sum(x<0)/x.shape[0]*100)+'%'}
IC_RSkewSummary=IC_RSkew.agg(aggOperator)
IC_RSkewSummary=pd.DataFrame(IC_RSkewSummary).T.\
applymap(lambda x:np.round(x,3) if isinstance(x,float) else x)
IC_RSkewSummary
mean | std | min | max | negative percentile | |
---|---|---|---|---|---|
IC | -0.039 | 0.106 | -0.453 | 0.432 | 65.60% |
中证 500 选股-IC 分年度表现一览
IC_RSkewSummary=IC_RSkew.resample('Y').agg(aggOperator).unstack(level=1).T
IC_RSkewSummary.set_index(IC_RSkewSummary.index.year,inplace=True)
IC_RSkewSummary=IC_RSkewSummary[list(aggOperator)].\
applymap(lambda x:np.round(x,3) if isinstance(x,float) else x)
IC_RSkewSummary
mean | std | min | max | negative percentile | |
---|---|---|---|---|---|
date | |||||
2007 | -0.039 | 0.107 | -0.255 | 0.282 | 62.00% |
2008 | -0.043 | 0.126 | -0.299 | 0.254 | 62.75% |
2009 | -0.056 | 0.096 | -0.334 | 0.132 | 68.63% |
2010 | -0.054 | 0.139 | -0.453 | 0.432 | 74.51% |
2011 | -0.046 | 0.082 | -0.248 | 0.085 | 64.71% |
2012 | -0.038 | 0.109 | -0.264 | 0.254 | 68.63% |
2013 | -0.030 | 0.102 | -0.274 | 0.174 | 60.78% |
2014 | -0.014 | 0.086 | -0.200 | 0.224 | 59.62% |
2015 | -0.044 | 0.118 | -0.334 | 0.205 | 63.46% |
2016 | -0.045 | 0.107 | -0.375 | 0.177 | 66.00% |
2017 | -0.008 | 0.086 | -0.164 | 0.354 | 63.46% |
2018 | -0.044 | 0.088 | -0.243 | 0.147 | 74.51% |
2019 | -0.055 | 0.148 | -0.381 | 0.220 | 58.33% |
RSkew因子指标在中证500指数成分股中选股,从2007年开始至今IC均值为-0.039,标准差为0.106,在周频调仓的情况下, 负IC占比为65.60%。在滚动12期IC的均值也基本上处以零以下的位置,分年度统计中,大部分年度IC均值均为负,且在分年度统计中可以看出,大部分年度负IC占比基本上在60%以上。
多空策略的制定可以参考https://medium.com/auquan/long-short-equity-trading-strategy-daa41d00a036
def GroupTestRetLongShortCumprod(group,mktCap,ret):# 多空策略分组累计收益率
df=pd.concat([mktCap,group,ret],axis=1)
df.ffill(inplace=True)
df['market_cap*return']=df['close']*df['market_cap']
df=df.groupby(['date','group'])['market_cap*return'].sum()/\
df.groupby(['date','group'])['market_cap'].sum()
df=df.unstack(level=1)
df.columns=list(df.columns)
df['Q1-Q5']=1/2*(df['Q1']-df['Q5'])+1
df=df['Q1-Q5'].cumprod()
return df
中证500指数成分股RSkew因子选股多-空策略净值走势表现一览
# zz500Ret 周度
zz500Ret=get_price(base,start_date=START_DATE, end_date=END_DATE,fields=['close'])
zz500Ret=zz500Ret.resample('W').last()
zz500Ret=(np.exp(np.log(zz500Ret).diff().shift(-1)))
zz500Ret.ffill(inplace=True)
RSkewLevel.columns=list(RSkewLevel.columns)
RSkewLevel['Q1-Q5_cum']=GroupTestRetLongShortCumprod(GetGroup(RSkew),mktCap,Return)
RSkewLevel['zz500']=zz500Ret
ax=RSkewLevel[['Q1','Q5','zz500']].cumprod().plot(figsize=(10,5))
RSkewLevel['Q1-Q5_cum'].plot(secondary_y=True,ax=ax,label='Q1-Q5',legend=True)
<matplotlib.axes._subplots.AxesSubplot at 0x7fbb69f40d68>
回测准备
def BacktrackInformation(level,ret):#计算回测所需数据
# 累计收益率
accRate=level.resample('Y').last()/\
level.resample('Y').first()-1
# 年化收益率
yldRate=(1+accRate)**(242/5/level.resample('Y').count())-1
yldRate[-1]=(1+accRate[-1])**(60.5/5/level.resample('Y').count()[-1])-1#2019调整
# 年化波动率
sigma=np.sqrt(242/5)*ret.resample('Y').std()
sigma[-1]*=np.sqrt(60.5/5)/np.sqrt(242/5)#2019调整
# 最大回撤
maxDropdown=(-1+np.exp(np.log(level).diff())).resample('Y').max()
# 信息比率
informationRatio=yldRate/sigma
# 整体
accRateTotal=level.loc[level.last_valid_index()]/level.loc[level.first_valid_index()]-1
yldRateTotal=(1+accRateTotal)**(242/5/level.count().sum())-1
sigmaTotal=np.sqrt(242/5)*ret.std()
maxDropdownTotal=max(maxDropdown)
informationRatioTotal=yldRateTotal/sigmaTotal
return accRate,maxDropdown,yldRate,sigma,informationRatio,\
accRateTotal,maxDropdownTotal,yldRateTotal,sigmaTotal,informationRatioTotal
def BacktrackTable(accRate,maxDropdown,yldRate,sigma,informationRatio,\
accRateTotal,maxDropdownTotal,yldRateTotal,sigmaTotal,informationRatioTotal):
#罗列回测信息
cols=['accRate','maxDropdown','yldRate','sigma','informationRatio']
df=pd.DataFrame([accRate,maxDropdown,yldRate,sigma,informationRatio],index=cols).T
years=list(df.index.year)
df=df.append(pd.DataFrame(
[accRateTotal,maxDropdownTotal,yldRateTotal,sigmaTotal,informationRatioTotal],
index=cols).T)
df=df.apply(lambda x:list(map(lambda z:"%.2f"%(z*100)+'%',x[:-1]))+["%.3f"%x[-1:]],axis=1)
df=pd.DataFrame(df.values.tolist(),columns=cols,index=years+['total'])
return df
中证500数成分股RSkew因子选股多-空策略分年度表现
ret=1/2*(RSkewLevel['Q1']-RSkewLevel['Q5'])
level=RSkewLevel['Q1-Q5_cum']
BacktrackTable(*BacktrackInformation(level,ret))
accRate | maxDropdown | yldRate | sigma | informationRatio | |
---|---|---|---|---|---|
2007 | 27.26% | 3.40% | 26.28% | 8.86% | 2.966 |
2008 | 21.69% | 2.75% | 20.48% | 7.44% | 2.752 |
2009 | 28.04% | 3.32% | 26.44% | 6.33% | 4.177 |
2010 | 11.88% | 3.18% | 11.24% | 10.15% | 1.108 |
2011 | 11.44% | 1.29% | 10.83% | 3.92% | 2.763 |
2012 | 5.44% | 1.21% | 5.15% | 4.95% | 1.040 |
2013 | 11.83% | 2.95% | 11.20% | 6.35% | 1.764 |
2014 | 5.43% | 1.07% | 5.05% | 3.72% | 1.356 |
2015 | 16.52% | 4.70% | 15.29% | 7.78% | 1.966 |
2016 | 12.87% | 2.51% | 12.43% | 5.17% | 2.405 |
2017 | 1.77% | 1.19% | 1.65% | 3.35% | 0.492 |
2018 | 7.65% | 1.78% | 7.25% | 4.85% | 1.495 |
2019 | 3.28% | 3.94% | 3.31% | 4.72% | 0.701 |
total | 401.81% | 4.70% | 13.31% | 6.50% | 2.048 |
多空策略整体的年化收益率为13.31%,信息比率为2.048。分年度看,多空策略在历史上大部分年度都取得了正的收益率。
中证500指数成分股RSkew因子选股多-中证500策略净值走势表现一览
ax=RSkewLevel[['Q1','zz500']].cumprod().plot(figsize=(16,5))
RSkewLevel['Q1-zz500']=RSkewLevel['Q1']-RSkewLevel['zz500']
RSkewLevel['Q1-zz500'].plot(ax=ax,secondary_y=True,legend=True)
<matplotlib.axes._subplots.AxesSubplot at 0x7fbb7ac174e0>
中证 500 选股多头策略分年度表现一览
ret=RSkewLevel['Q1']
RSkewLevel['Q1_cum']=RSkewLevel['Q1'].cumprod()
level=RSkewLevel['Q1_cum']
BacktrackTable(*BacktrackInformation(level,ret))
accRate | maxDropdown | yldRate | sigma | informationRatio | |
---|---|---|---|---|---|
2007 | 252.08% | 16.10% | 238.18% | 40.94% | 5.817 |
2008 | -62.73% | 22.67% | -60.80% | 53.87% | -1.129 |
2009 | 141.43% | 13.72% | 130.82% | 34.33% | 3.811 |
2010 | 21.83% | 7.96% | 20.61% | 25.75% | 0.801 |
2011 | -28.85% | 8.92% | -27.60% | 22.87% | -1.207 |
2012 | 2.45% | 7.10% | 2.32% | 23.33% | 0.099 |
2013 | 30.35% | 5.75% | 28.60% | 21.12% | 1.354 |
2014 | 45.82% | 5.50% | 42.06% | 18.14% | 2.319 |
2015 | 71.18% | 14.39% | 64.93% | 46.10% | 1.409 |
2016 | 1.86% | 7.01% | 1.80% | 27.41% | 0.066 |
2017 | -2.25% | 4.23% | -2.10% | 13.48% | -0.156 |
2018 | -31.25% | 6.38% | -29.93% | 25.46% | -1.175 |
2019 | 37.41% | 7.25% | 37.78% | 11.63% | 3.249 |
total | 770.15% | 22.67% | 18.24% | 32.25% | 0.566 |
中证500选股多头-500策略分年度表现一览
ret=1/2*(RSkewLevel['Q1']-RSkewLevel['zz500'])
RSkewLevel['Q1-zz500']=(ret+1).cumprod()
level=RSkewLevel['Q1-zz500']
BacktrackTable(*BacktrackInformation(level,ret))
accRate | maxDropdown | yldRate | sigma | informationRatio | |
---|---|---|---|---|---|
2007 | 0.20% | 4.83% | 0.20% | 12.27% | 0.016 |
2008 | -6.67% | 2.94% | -6.34% | 10.05% | -0.631 |
2009 | 11.36% | 4.55% | 10.75% | 6.49% | 1.657 |
2010 | 6.59% | 2.19% | 6.25% | 4.69% | 1.333 |
2011 | 8.91% | 4.54% | 8.44% | 5.15% | 1.638 |
2012 | -2.00% | 1.02% | -1.90% | 3.17% | -0.599 |
2013 | 3.31% | 1.93% | 3.14% | 5.29% | 0.593 |
2014 | -0.25% | 0.77% | -0.24% | 2.58% | -0.092 |
2015 | 10.47% | 2.27% | 9.71% | 4.85% | 2.002 |
2016 | 5.89% | 1.80% | 5.70% | 3.85% | 1.480 |
2017 | -0.93% | 0.72% | -0.86% | 2.16% | -0.400 |
2018 | -3.25% | 0.91% | -3.09% | 6.40% | -0.482 |
2019 | 8.83% | 5.17% | 8.90% | 6.19% | 1.438 |
total | 56.05% | 5.17% | 3.52% | 6.39% | 0.550 |
中证 500 选股换手率分年度统计一览
选股换手率采用了 https://economictimes.indiatimes.com/wealth/invest/what-does-a-mutual-funds-portfolio-turnover-ratio-indicate/articleshow/63556068.cms?from=mdr 中描述的方法
RSkewGroup=GetGroup(RSkew)
Q1_RSkewGroup=RSkewGroup.unstack(level=1)
Q1_RSkewGroup=((Q1_RSkewGroup=='Q1')==True).astype(int)
Q1_mktCap=(mktCap.unstack()*Q1_RSkewGroup)
aggOperator={'mean':np.mean,'max':np.max,'min':np.min,'std':np.std,'acc':np.sum}
Q1_RSkewChangeBuy=(Q1_RSkewGroup.diff()>0).astype(int) #buy in
Q1_RSkewChangeBuy=(Q1_RSkewChangeBuy*Q1_mktCap).sum(axis=1)/Q1_mktCap.sum(axis=1)
Q1_RSkewChangeBuy=Q1_RSkewChangeBuy.shift(-1).iloc[:-1]
Q1_RSkewChangeSell=(Q1_RSkewGroup.diff()<0).astype(int).shift(-1) #sell out
Q1_RSkewChangeSell=(Q1_RSkewChangeSell*Q1_mktCap).sum(axis=1)/Q1_mktCap.sum(axis=1)
Q1_RSkewChangeSell=Q1_RSkewChangeSell.iloc[:-1]
Q1_RSkewChange=pd.DataFrame([Q1_RSkewChangeBuy,Q1_RSkewChangeSell]).min(axis=0)
Q1_RSkewChange=(Q1_RSkewChange.resample('Y').agg(aggOperator)).unstack(level=1).T
Q1_RSkewChange.index=Q1_RSkewChange.index.year
Q1_RSkewChange[list(aggOperator)]
mean | max | min | std | acc | |
---|---|---|---|---|---|
date | |||||
2007 | 0.783262 | 0.939657 | 0.469278 | 0.093426 | 39.163119 |
2008 | 0.772033 | 0.940693 | 0.562965 | 0.085270 | 39.373659 |
2009 | 0.785656 | 0.946987 | 0.583867 | 0.080654 | 40.068470 |
2010 | 0.793798 | 0.933038 | 0.603333 | 0.078146 | 40.483714 |
2011 | 0.790165 | 0.924330 | 0.646079 | 0.068739 | 40.298409 |
2012 | 0.762767 | 0.901772 | 0.600531 | 0.069200 | 38.901131 |
2013 | 0.783148 | 0.909950 | 0.653015 | 0.061633 | 39.940542 |
2014 | 0.771364 | 0.903494 | 0.674218 | 0.059443 | 40.110903 |
2015 | 0.795688 | 0.898223 | 0.660018 | 0.056804 | 41.375760 |
2016 | 0.789221 | 0.872059 | 0.633282 | 0.052395 | 39.461071 |
2017 | 0.793374 | 0.895994 | 0.709930 | 0.047146 | 41.255435 |
2018 | 0.778910 | 0.926105 | 0.600036 | 0.054443 | 39.724427 |
2019 | 0.763529 | 0.884148 | 0.623627 | 0.080806 | 8.398817 |
在中证500选股回测中,多头中证500指数后,策略整体的年化收益率为3.52%, 信息比率为0.550,换手率均值在78%左右,策略表现并不出色。整体换手率较高,策略最大回撤为策略 的5.17%,分年度看,每一年的最大回撤都不超过6%。
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程