#沪深300、中证500的数据
hs300 = get_price('000300.SH','20070301', '20170519', '1d', ['open', 'high', 'low', 'close'])
zz500 = get_price('000905.SH','20070301', '20170519', '1d', ['open', 'high', 'low', 'close'])
本文参考了长江证券研报《基于成分股动量的大小盘轮动策略》
#导入需要使用的包
import pandas as pd
from pandas import DataFrame
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib
matplotlib.rcParams.update({
'font.family': 'serif',
'font.serif': ['Droid Sans Fallback', 'serif'],
})
import matplotlib.pyplot as plt
from pylab import *
import seaborn as sns
#sns.set_style('white')
mpl.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文
mpl.rcParams['axes.unicode_minus']=False #用来正常显示负号
#获得沪深300、中证500的每日价格变动百分比
hs300['300pcr'] = hs300['close'].pct_change().fillna(0)
zz500['500pcr'] = zz500['close'].pct_change().fillna(0)
#新建一个df,存储沪深300、中证500的每日收益率差的累计值、每日表现更优的指数收益率累计值,以及两个指数的收益率累计值
pcr35 = DataFrame()
pcr35['3-5'] = hs300['300pcr'] - zz500['500pcr']
pt= []
for i in range(len(hs300['300pcr'])):
pt.append(max(hs300['300pcr'][i], zz500['500pcr'][i]))
pcr35['perfect_time'] = pt
pcr35['perfect_time'] = pcr35['perfect_time'] + 1
pcr35['perfect_time'] = pcr35['perfect_time'] .cumprod()
pcr35['3-5'] = pcr35['3-5'] + 1.0
pcr35['3-5'] = pcr35['3-5'].cumprod()
pcr35['300pcr'] = hs300['300pcr'] + 1.0
pcr35['300pcr'] = pcr35['300pcr'].cumprod()
pcr35['500pcr'] = zz500['500pcr'] + 1.0
pcr35['500pcr'] = pcr35['500pcr'].cumprod()
pcr35 = pcr35.dropna()
#画出pcr35的收益表现
fig = plt.figure(figsize= (12, 5))
fig.set_tight_layout(True)
ax1 = fig.add_subplot(111)
ax1.grid(True)
ax1.plot(pcr35.index, pcr35[['300pcr']], label = u'沪深300')
ax1.plot(pcr35.index, pcr35[['500pcr']], label = u'中证500')
ax1.plot(pcr35.index, pcr35[['perfect_time']], label = u'择时最大潜力')
ax1.set_ylabel(u'收益率', fontsize = 16)
ax1.set_xlabel(u'时间', fontsize = 16)
#ax1.set_xticks(pcr35.index)
#ax1.set_xticklabels(pcr35.index.tolist())
fig.autofmt_xdate()
ax1.legend(fontsize = 14)
ax1.set_title(u'股指完美择时收益表现',fontsize = 20)
plt.show()
虽然股市涨涨跌跌,但是如果可以做到沪深300、中证500的完美择时,完全不用担心市场的涨跌。 当然完美择时只是理论上的,但是也说明了择时策略巨大潜力。
# 获取指数的年度收益
x = 100 * ( pcr35['300pcr']['2007'][-1]/pcr35['300pcr']['2007'][0] - 1 ) .round(2)
x1 =100 * ( pcr35['500pcr']['2007'][-1]/pcr35['500pcr']['2007'][0] - 1 ) .round(2)
Yhs300 = [x]
Yzz500 = [x1]
for i in range(2008, 2018):
#pcr35['300pcr'][str(i)][-1]
Yhs300.append(100 * ( pcr35['300pcr'][str(i)][-1]/pcr35['300pcr'][str(i-1)][-1] - 1 ) .round(2) )
Yzz500.append(100 * ( pcr35['500pcr'][str(i)][-1]/pcr35['500pcr'][str(i-1)][-1] - 1 ) .round(2) )
YPC = DataFrame(index = ['2007', '2008', '2009', '2010', '2011', '2012','2013', '2014', '2015', '2016', '2017'])
YPC['Yhs300'] = Yhs300
YPC['Yzz500'] = Yzz500
YPC.columns = ['沪深300','中证500']
YPC.T
计算得出的数据与长江证券的结果基本一致,在2007出所差距,可能是对初始值的处理不一样。 从历年数据中可以看出大小盘轮动的特征还是比较明显。2011、2012、2014、2016年沪深300表现更佳、其余数年中证500表现更好。
#比价关系
#sns.set_style('white')
pcr35['pr'] =hs300['close'][1:]/zz500['close'][1:]
fig = plt.figure(figsize= (21, 9))
fig.set_tight_layout(False)
ax1 = fig.add_subplot(111)
ax1.grid(False)
ax2 = ax1.twinx()
ax1.plot(pcr35.index, pcr35[['300pcr']], label = u'沪深300', alpha = 0.3)
ax1.plot(pcr35.index, pcr35[['500pcr']], label = u'中证500', alpha = 0.3)
ax2.plot(pcr35.index, pcr35[['pr']], label = u'大小盘比价', color = 'red', alpha = 0.8)
ax1.legend(loc = 2, fontsize = 12)
ax2.legend(loc = 0, fontsize = 12)
ax1.set_xlabel(u'时间', fontsize = 16)
ax1.set_ylabel(u'增长率', fontsize = 16)
ax2.set_ylabel(u'比价值', fontsize = 16)
ax1.set_title(u'沪深300,中证500比价关系', fontsize = 20)
#plt.xticks(pm.index)
plt.show()
从比价关系走势图来看,大部分情况下沪深300 相对中证500 走弱,证明在A 股市场中大多数区间段,小盘股要强于大盘股。
利用比价关系构建指标,进行择时。 构建指标:为了使数据更加平稳,将比价关系对数化。在利用MA20和均线乖离率进行处理。 择时方法:指标站上20日均线时并且乖离率小于10%,做多沪深300
import math
pcr35['logpr'] =list(map(lambda x: math.log(x), pcr35.pr))
pcr35.head()
import talib
Logpr = DataFrame(index = pcr35.index)
Logpr['logpr'] = pcr35['logpr']
Logpr['ma20'] = talib.MA(np.array(Logpr['logpr']), 20)
Logpr['bias'] = (Logpr['logpr']-Logpr['ma20'])/Logpr['ma20']*100
sns.distplot(pcr35['500pcr'], bins = 100)
hs300 = get_price('000300.SH','20070301', '20170519', '1d', ['open', 'high', 'low', 'close'])
zz500 = get_price('000905.SH','20070301', '20170519', '1d', ['open', 'high', 'low', 'close'])
hs300['300dc'] = hs300['close']/hs300['close'].shift(1)
zz500['500dc'] = zz500['close']/zz500['close'].shift(1)
pr_long = []
for i in range(len(Logpr['logpr'])):
pr_long.append(0)
for i in range(len(Logpr['logpr'])):
if Logpr['logpr'][i] > Logpr['ma20'][i] and Logpr.bias[i]<10:
pr_long[i] = hs300['300dc'][i]
elif Logpr['logpr'][i] < Logpr['ma20'][i] and Logpr.bias[i]>-10:
pr_long[i] = zz500['500dc'][i]
elif Logpr['logpr'][i] > Logpr['ma20'][i] and Logpr['logpr'][i-1] < Logpr['ma20'][i-1] and Logpr.bias[i]<10:
pr_long[i] = 1
elif Logpr['logpr'][i] < Logpr['ma20'][i] and Logpr['logpr'][i-1] > Logpr['ma20'][i-1] and Logpr.bias[i]>-10:
pr_long[i] = 1
else :
pr_long[i] = 1
pr_long_short = []
for i in range(len(Logpr['logpr'])):
pr_long_short.append(0)
for i in range(len(Logpr['logpr'])):
if Logpr['logpr'][i] > Logpr['ma20'][i] and Logpr.bias[i]<10:
pr_long_short[i] = 0.5 * (hs300['300dc'][i] - 1) + 0.5 * ( 1 - zz500['500dc'][i]) + 1
elif Logpr['logpr'][i] < Logpr['ma20'][i] and Logpr.bias[i]>-10:
pr_long_short[i] = 0.5 * (zz500['500dc'][i] - 1) + 0.5 * ( 1 - hs300['300dc'][i]) + 1
elif Logpr['logpr'][i] > Logpr['ma20'][i] and Logpr['logpr'][i-1] < Logpr['ma20'][i-1] and Logpr.bias[i]<10:
pr_long_short[i] = 1
elif Logpr['logpr'][i] < Logpr['ma20'][i] and Logpr['logpr'][i-1] > Logpr['ma20'][i-1] and Logpr.bias[i]>-10:
pr_long_short[i] = 1
else :
pr_long_short[i] = 1
Logpr = DataFrame()
Logpr['pr_long'] = pr_long
Logpr['pr_long_short'] = pr_long_short
Logpr.index = zz500.index
Logpr = Logpr.replace(0.0, 1.0)
Logpr['pr_long'] = Logpr['pr_long'].cumprod()
Logpr['pr_long_short'] = Logpr['pr_long_short'].cumprod()
fig = plt.figure(figsize= (16, 9))
fig.set_tight_layout(True)
ax1 = fig.add_subplot(111)
ax1.grid(True)
ax1.plot(Logpr.index, Logpr[['pr_long']], label = u'纯多头策略' )
ax1.plot(pcr35.index, pcr35[['300pcr']], label = '沪深300')
ax1.plot(pcr35.index, pcr35[['500pcr']], label = '中证500')
ax1.plot(Logpr.index, Logpr[['pr_long_short']], label = u'多空策略')
ax1.legend(fontsize = 12)
ax1.set_xlabel(u'时间', fontsize = 16)
ax1.set_ylabel(u'增长率', fontsize = 16)
ax1.set_title(u'纯多头策略与多空策略对比', fontsize = 20)
plt.show()