股票-债全-商品轮动策略——基于美林时钟模型

##这部分是先确定周期最优配置资产
选取2006.01.01-2018.01.01的GDP,CPI,沪深300(000300.SH),上债指数(000012.SH),南华商品指数(NHCI.NH)

思路很简单。通过季度的宏观经济变量,统计对应时间段的三种大资产的平均收益,选取最高的收益作为策略待选资产。
先看结果:

经济↑+通货↓时,股票:37.23%,商品:-19.58%,债券:0.68%
经济↑+通货↓时,股票:0.84%,商品:-22.89%,债券:0.51%
经济↑+通货↓时,股票:-1.20%,商品:-8.75%,债券:0.36%
经济↑+通货↓时,股票:-12.41%,商品:-11.36%,债券:0.31%
经济↑+通货↓时,股票:-16.22%,商品:-17.42%,债券:0.31%
经济↑+通货↓时,股票:5.28%,商品:-7.33%,债券:0.30%
经济↑+通货↓时,股票:-7.90%,商品:-10.30%,债券:0.36%
经济↑+通货↓时,股票:-27.52%,商品:-16.86%,债券:0.39%
经济↑+通货↓时,股票:-28.06%,商品:-10.73%,债券:0.35%
经济↑+通货↓时,股票:-27.32%,商品:-17.94%,债券:0.38%
经济↑+通货↓时,股票:-26.81%,商品:-9.58%,债券:0.27%
经济↑+通货↓时,股票:12.52%,商品:17.76%,债券:0.18%
经济↑+通货↓时,股票:0.74%,商品:11.30%,债券:0.22%
经济↑+通货↓时,股票:-168.76%,商品:-45.18%,债券:1.03%
经济↑+通货↓时,股票:-202.40%,商品:-34.00%,债券:0.82%
经济↑+通货↓时,股票:-37.58%,商品:12.90%,债券:0.25%
经济↑+通货↓时,股票:11.56%,商品:4.40%,债券:0.12%
经济↑+通货↓时,股票:55.56%,商品:12.08%,债券:-0.03%
经济↑+通货↓时,股票的平均收益:-24.03%,v,商品的平均收益:-9.64%,债券的平均收益:0.38%
经济↑+通货↑时,股票:9.21%,商品:3.76%,债券:0.23%
经济↑+通货↑时,股票:21.14%,商品:4.24%,债券:0.10%
经济↑+通货↑时,股票:15.71%,商品:14.60%,债券:0.04%
经济↑+通货↑时,股票:12.43%,商品:18.80%,债券:0.17%
经济↑+通货↑时,股票:-39.92%,商品:2.49%,债券:0.83%
经济↑+通货↑时,股票:-11.48%,商品:-16.01%,债券:1.02%
经济↑+通货↑时,股票:30.08%,商品:-15.84%,债券:0.95%
经济↑+通货↑时,股票:45.11%,商品:-20.31%,债券:0.84%
经济↑+通货↑时,股票:50.93%,商品:-14.94%,债券:0.78%
经济↑+通货↑时,股票:-11.60%,商品:12.41%,债券:0.25%
经济↑+通货↑时,股票:0.82%,商品:14.95%,债券:0.30%
经济↑+通货↑时,股票:-30.35%,商品:8.65%,债券:0.38%
经济↑+通货↑时,股票:-39.31%,商品:-24.26%,债券:0.71%
经济↑+通货↑时,股票:74.50%,商品:7.79%,债券:-0.11%
经济↑+通货↑时,股票:65.11%,商品:-3.68%,债券:0.03%
经济↑+通货↑时,股票的平均收益:12.83%,v,商品的平均收益:-0.49%,债券的平均收益:0.44%
经济↓+通货↓时,股票:7.68%,商品:22.46%,债券:0.29%
经济↓+通货↓时,股票:5.09%,商品:37.37%,债券:0.34%
经济↓+通货↓时,股票:-5.14%,商品:24.09%,债券:0.69%
经济↓+通货↓时,股票:-24.29%,商品:15.51%,债券:0.76%
经济↓+通货↓时,股票的平均收益:-4.17%,商品的平均收益:24.86%,债券的平均收益:0.52%
经济↓+通货↑时,股票:-3.88%,商品:-12.40%,债券:0.36%
经济↓+通货↑时,股票:6.96%,商品:1.72%,债券:0.32%
经济↓+通货↑时,股票:-13.97%,商品:-0.30%,债券:0.37%
经济↓+通货↑时,股票:20.51%,商品:20.56%,债券:0.25%
经济↓+通货↑时,股票:42.65%,商品:32.94%,债券:0.10%
经济↓+通货↑时,股票:43.39%,商品:19.00%,债券:0.31%
经济↓+通货↑时,股票:18.15%,商品:-23.46%,债券:0.66%
经济↓+通货↑时,股票:64.90%,商品:2.82%,债券:0.13%
经济↓+通货↑时,股票:58.19%,商品:0.32%,债券:0.15%
经济↓+通货↑时,股票:-24.46%,商品:7.34%,债券:0.44%
经济↓+通货↑时,股票的平均收益:21.24%,商品的平均收益:4.85%,债券的平均收益:0.31%

通过结果可以看出:
1.经济上行(GDP差分大于0)+通货下行(CPI差分小于零),我们再下一期(三个月):配置债券
2.经济上行(GDP差分大于0)+通货上行(CPI差分大于零),我们再下一期(三个月):配置股票
3.经济下行(GDP差分小于0)+通货下行(CPI差分小于零),我们再下一期(三个月):配置商品
4.经济下行(GDP差分大于0)+通货上行(CPI差分小于零),我们再下一期(三个月):配置股票
因为季度数据会有延迟性,所以我们研究的数据需要延后。

然后用2018.01.01-(2020.08.18)今天的带入策略,收益情况如下:
相对于沪深300,可以看出我们的策略基本都是压着它的。图形为什么这么像,因为这两年都趋向于股票。

然后,所有指数整体比较,最后也是胜的。

使用tushare pro 数据库,获取token 码,需要先注册 https://tushare.pro/register?reg=385920
周期最优资产对比代码:

# coding=utf-8
import math
import tushare as ts
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import talib
import pandas as pd
from datetime import datetime, date
matplotlib.rcParams['axes.unicode_minus']=False
plt.rcParams['font.sans-serif']=['SimHei']
ts.set_token('token码')#######需要先注册 https://tushare.pro/register?reg=385920
pro = ts.pro_api()
#读取数据
dc = pro.cn_cpi(start_m='200601', end_m='201812',fields='month,nt_val,nt_yoy')
dc=dc.sort_index()
dc.set_index('month',inplace=True)
dc2=(dc.shift(12)-dc.shift()).dropna()
C=pd.Series(0,index=dc2.nt_yoy.index)
for j in range(len(dc2.nt_yoy)-3):if (3+j)%3==0:if dc2.nt_yoy[j]>0:C[j]=1elif dc2.nt_yoy[j]<0:C[j]=0else:C[j]=C[j-1] else:pass
def CP(x):#打印CPI季度数据return C[3*x]df1 = pro.cn_gdp(start_q='2006Q1', end_q='2018Q4',fields='quarter,gdp_yoy')
df1.set_index('quarter',inplace=True)#设置日期索引
df2=df1-df1.shift(4)
df2=df2.dropna()
G=pd.Series(0,index=df2.gdp_yoy.index)
for i in range(len(df2.gdp_yoy)):if df2.gdp_yoy[i]>0:G[i]=1elif df2.gdp_yoy[i]<0:G[i]=0else:G[i]=G[i-1]G=G.head(47)
"""
#股票收益
ds = pro.index_monthly(ts_code='000300.SH', start_date='20060101', end_date='20190101', fields='ts_code,trade_date,close')
ds=ds.sort_index()
ds.set_index('trade_date',inplace=True)
ds1=ds.drop(['ts_code'],axis=1)
ds2=ds1.shift(12)-ds1
tt1=ds1
ds2=ds2/tt1
ds2=ds2.dropna()
def st(x):#股票季度收益数据return ds2.close[3*x]
"""#商品收益
ds = pro.index_daily(ts_code='000300.SH', start_date='20060101', end_date='20181231',fields='ts_code,trade_date,close')
ds.set_index('trade_date',inplace=True)
ds=ds.drop(['ts_code'],axis=1)
ds.index = pd.to_datetime(ds.index)
ds=ds.groupby([ds.index.year.rename('year'),ds.index.month.rename('month')])['close'].mean()
ds2=ds-ds.shift(12)
tt2=ds
ds2=ds2/tt2
ds2=ds2.dropna()
def st(x):#打印CPI季度数据h2=3*(len(G)-1-x)return ds2[h2]#商品收益
dp = pro.index_daily(ts_code='NHCI.NH', start_date='20060101', end_date='20181231',fields='ts_code,trade_date,close')
dp.set_index('trade_date',inplace=True)
dp=dp.drop(['ts_code'],axis=1)
dp.index = pd.to_datetime(dp.index)
dp=dp.groupby([dp.index.year.rename('year'),dp.index.month.rename('month')])['close'].mean()
dp2=dp-dp.shift(12)
tt=dp
dp2=dp2/tt
dp2=dp2.dropna()
def sp(x):#打印CPI季度数据h=3*(len(G)-1-x)return dp2[h]
#债券
dz=pro.index_daily(ts_code='000012.SH', start_date='20060101', end_date='20181231',fields='ts_code,trade_date,close')
dz.set_index('trade_date',inplace=True)
dz=dz.drop(['ts_code'],axis=1)
dz.index = pd.to_datetime(dz.index)
dz=dz.groupby([dz.index.year.rename('year'),dz.index.month.rename('month')])['close'].mean()
dz2=dz-dz.shift(12)
tt2=dz
dz2=dz2/tt
dz2=dz2.dropna()
def sz(x):#打印CPI季度数据h1=3*(len(G)-1-x)return dz2[h1]
ST1=0
SP1=0
SZ1=0
k1=0
ST2=0
SP2=0
SZ2=0
k2=0
ST3=0
SP3=0
SZ3=0
k3=0
ST4=0
SP4=0
SZ4=0
k4=0
for i in range(len(G)):if G[i]>0 and CP(i)==0:ST1=ST1+st(i+1)SP1=SP1+sp(i+1)SZ1=SZ1+sz(i+1)k1+=1print('经济↑+通货↓时,股票:{:.2f}%,商品:{:.2f}%,债券:{:.2f}%'.format(st(i+1)*100,sp(i+1)*100,sz(i+1) *100   ))
print('经济↑+通货↓时,股票的平均收益:{:.2f}%,v,商品的平均收益:{:.2f}%,债券的平均收益:{:.2f}%'.format(100*ST1/k1,100*SP1/k1,100*SZ1/k1))for i in range(len(G)):          if G[i]>0 and CP(i)>0:ST2=ST2+st(i+1)SP2=SP2+sp(i+1)SZ2=SZ2+sz(i+1)k2+=1print('经济↑+通货↑时,股票:{:.2f}%,商品:{:.2f}%,债券:{:.2f}%'.format(st(i+1)*100,sp(i+1)*100,sz(i+1) *100   ))
print('经济↑+通货↑时,股票的平均收益:{:.2f}%,v,商品的平均收益:{:.2f}%,债券的平均收益:{:.2f}%'.format(100*ST2/k2,100*SP2/k2,100*SZ2/k2))for i in range(len(G)):if G[i]==0 and CP(i)==0:ST3=ST3+st(i+1)SP3=SP3+sp(i+1)SZ3=SZ3+sz(i+1)k3+=1print('经济↓+通货↓时,股票:{:.2f}%,商品:{:.2f}%,债券:{:.2f}%'.format(st(i+1)*100,sp(i+1)*100,sz(i+1) *100   ))
print('经济↓+通货↓时,股票的平均收益:{:.2f}%,商品的平均收益:{:.2f}%,债券的平均收益:{:.2f}%'.format(100*ST3/k3,100*SP3/k3,100*SZ3/k3))for i in range(len(G)): if G[i]==0 and CP(i)>0:ST4=ST4+st(i+1)SP4=SP4+sp(i+1)SZ4=SZ4+sz(i+1)k4+=1print('经济↓+通货↑时,股票:{:.2f}%,商品:{:.2f}%,债券:{:.2f}%'.format(st(i+1)*100,sp(i+1)*100,sz(i+1) *100   ))
print('经济↓+通货↑时,股票的平均收益:{:.2f}%,商品的平均收益:{:.2f}%,债券的平均收益:{:.2f}%'.format(100*ST4/k4,100*SP4/k4,100*SZ4/k4))

策略代码:

# coding=utf-8
import math
import tushare as ts
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import talib
import pandas as pd
from datetime import datetime, date
matplotlib.rcParams['axes.unicode_minus']=False
plt.rcParams['font.sans-serif']=['SimHei']
ts.set_token('这里加入token 码')
pro = ts.pro_api()
#读取数据df1 = pro.cn_gdp(start_q='2016Q4', end_q='2020Q2',fields='quarter,gdp_yoy')
df1.set_index('quarter',inplace=True)#设置日期索引
df2=df1.shift(4)-df1
df2=df2.dropna()
G=pd.Series(0,index=df2.gdp_yoy.index)
for i in range(len(df2.gdp_yoy)):if df2.gdp_yoy[i]>0:G[i]=1elif df2.gdp_yoy[i]<0:G[i]=0else:G[i]=G[i-1]dc = pro.cn_cpi(start_m='201609', end_m='202003',fields='month,nt_val,nt_yoy')
dc=dc.sort_index()
dc.set_index('month',inplace=True)
dc2=(dc.shift(12)-dc.shift()).dropna()
C=pd.Series(0,index=dc2.nt_yoy.index)
for j in range(len(dc2.nt_yoy)-3):if (3+j)%3==0:if dc2.nt_yoy[j]>0:C[j]=1elif dc2.nt_yoy[j]<0:C[j]=0else:C[j]=C[j-1] else:pass
def CP(x):#打印CPI季度数据return C[3*x]#商品收益
ds = pro.index_daily(ts_code='000300.SH', start_date='20060101', end_date='20181231',fields='ts_code,trade_date,close')
ds.set_index('trade_date',inplace=True)
ds=ds.drop(['ts_code'],axis=1)
ds.index = pd.to_datetime(ds.index)
ds=ds.groupby([ds.index.year.rename('year'),ds.index.month.rename('month')])['close'].mean()
ds2=ds-ds.shift(12)
tt2=ds
ds2=ds2/tt2
ds2=ds2.dropna()
def st(x):#打印CPI季度数据h2=3*(len(G)-1-x)return ds2[h2]dsc = pro.index_daily(ts_code='000300.SH', start_date='20171229', end_date='20200818',fields='ts_code,trade_date,close')
dsc=dsc.drop(['ts_code'],axis=1)
dsc=dsc.sort_index()
dsc.index=pd.to_datetime(dsc.trade_date,format='%Y-%m-%d')#设置日期索引
dsc=dsc.drop(['trade_date'],axis=1)
ret_c=(dsc.shift(1)-dsc)/dsc
ret_c=ret_c.dropna()dsb = pro.index_daily(ts_code='000012.SH', start_date='20171229', end_date='20200818',fields='ts_code,trade_date,close')
dsb=dsb.drop(['ts_code'],axis=1)
dsb=dsb.sort_index()
dsb.index=pd.to_datetime(dsb.trade_date,format='%Y-%m-%d')#设置日期索引
dsb=dsb.drop(['trade_date'],axis=1)
dsb=(dsb.shift(1)-dsb)/dsb
ret_b=dsb.dropna()dsp = pro.index_daily(ts_code='NHCI.NH', start_date='20171229', end_date='20200818',fields='ts_code,trade_date,close')
dsp=dsp.drop(['ts_code'],axis=1)
dsp=dsp.sort_index()
dsp.index=pd.to_datetime(dsp.trade_date,format='%Y-%m-%d')#设置日期索引
dsp=dsp.drop(['trade_date'],axis=1)
dsp=(dsp.shift(1)-dsp)/dsp
ret_p=dsp.dropna()
ret_psig_c=pd.Series(0,index=dsc.close.index)
sig_p=pd.Series(0,index=dsc.close.index)
sig_b=pd.Series(0,index=dsc.close.index)
for i in range(len(G)):if  G[i]>0 and CP(i)>0:sig_c[i*64:64*(i+1)]=1elif   G[i]==0 and CP(i)>0:sig_c[i*64:64*(i+1)]=1elif  G[i]>0 and CP(i)==0:sig_b[i*64:(i+1)*64]=1else:sig_p[i*64:(i+1)*64]=1
sig=sig_c+sig_p+sig_b
RET=sig_c*ret_c.close+sig_p*ret_p.close+sig_b*ret_b.close
cum=np.cumprod(1+RET)-1
plt.rcParams['font.sans-serif']=['SimHei']ddf = pro.index_daily( ts_code='000300.SH', start_date='20180101', end_date='20200810')
ddf=ddf.sort_index()
ddf.index=pd.to_datetime(ddf.trade_date,format='%Y-%m-%d')#设置日期索引
close= ddf.close
ret=ddf.change/ddf.close
SmaSignal=pd.Series(0,index=close.index)
SmaTrade=SmaSignal.shift(1).dropna()/100#shift(1)整体下移一行
SmaRet=ret*SmaTrade.dropna()
cumStock=np.cumprod(1+ret[SmaRet.index[0:]])-1
plt.plot(cumStock,label="沪深300",color='k')ddf1= pro.index_daily( ts_code='000012.SH', start_date='20180101', end_date='20200810')
ddf1=ddf1.sort_index()
ddf1.index=pd.to_datetime(ddf1.trade_date,format='%Y-%m-%d')#设置日期索引
close1= ddf1.close
ret1=ddf1.change/ddf1.close
SmaSignal1=pd.Series(0,index=close1.index)
SmaTrade1=SmaSignal1.shift(1).dropna()/100#shift(1)整体下移一行
SmaRet1=ret1*SmaTrade1.dropna()
cumStock1=np.cumprod(1+ret1[SmaRet1.index[0:]])-1
plt.plot(cumStock1,label="上债指数",color='y')ddf11= pro.index_daily( ts_code='NHCI.NH', start_date='20180101', end_date='20200810')
ddf11=ddf11.sort_index()
ddf11.index=pd.to_datetime(ddf11.trade_date,format='%Y-%m-%d')#设置日期索引
close11= ddf11.close
ret11=ddf11.change/ddf11.close
SmaSignal11=pd.Series(0,index=close11.index)
SmaTrade11=SmaSignal11.shift(1).dropna()/100#shift(1)整体下移一行
SmaRet11=ret11*SmaTrade11.dropna()
cumStock11=np.cumprod(1+ret11[SmaRet11.index[0:]])-1
plt.plot(cumStock11,label="南华指数",color='b')plt.plot(cum,label="改美林策略",color='r',linestyle=':')
plt.title("策略收益率")
plt.legend()
f=cum[-2]*250/len(ret_b.close)
f1=100*f
print("年化收益率:{:.2f}%,总收益{:.2f}%".format(f1,f1*len(ret_b.close)/250))

1.python量化——alpha股票-指数期货对冲策略
2.多因子选股策略
3.海龟交易策略
4.移动平均策略——单/双均线策略
5.改进的美林时钟策略(一)
5.改进的美林时钟策略(二)
6.改进的美林时钟策略(三)

python量化策略——改进的美林时钟轮动策略(一)相关推荐

  1. 抱团股会一直涨?无脑执行大小盘轮动策略,轻松跑赢指数5倍【附Python代码】

    引言: 邢不行的系列帖子"量化小讲堂",通过实际案例教初学者使用python进行量化投资,了解行业研究方向,希望能对大家有帮助. 前言: 巴蛇吞象,扬州跨鹤.人性之贪婪,逝者如此, ...

  2. 搭建系统|继承backtrader的本地量化回测平台如何玩转多股轮动策略!

    前言 一个完整的量化交易系统离不开人机交互功能的应用,特别是在回测阶段,我们需要不断更改参数因子.更换交易策略以应对当前的市场.因此创建完整的.功能键全的GUI用户界面至关重要. 市面上也出现了很多相 ...

  3. 使用python量化交易接口有哪些分析指标和策略?

    量化交易有哪些指标可以用于分析呢?主要有技术面和基本面可以用于分析! 来看一下技术面和基本面有什么区别? 技术面更关注具体的价格,比如每天的开盘价.收盘价.以及和开盘价/收盘价/最低价/最高价相关的K ...

  4. [Tushare+Python] AH股轮动策略基础

    [Tushare+Python] AH股轮动策略基础 摘要:为做AH股轮动策略需进行基础数据处理,这里代码主要涉及AH溢价计算及相关数据清洗. 文章目录 [Tushare+Python] AH股轮动策 ...

  5. 量化选股——基于动量因子的行业风格轮动策略(第1部分—因子测算)

    文章目录 动量因子与行业轮动概述 动量因子的理解 投资视角下的行业轮动现象 投资者视角与奈特不确定性 动量因子在行业风格上的效果测算 动量因子效果测算流程概述 1. 行业选择:申万一级行业 2. 动量 ...

  6. 股债轮动策略之行业版

    股债轮动策略之行业版 雪球上的 宜昌白云飞 的原创专栏里有一个系列文章, 现将其摘录如下: 年化20%七年无亏损的简单策略--股债轮动行业版(一) https://xueqiu.com/1884493 ...

  7. html如何设置轮动,手把手教你构建轮动策略

    A股市场具有明显的大小盘风格轮动现象,比如2015年以中证500为代表的中小盘全面跑赢沪深300指数(大盘),但在随后的几年中沪深300指数成为市场的主流,收益也大幅跑赢中证500. 而最近一年,市场 ...

  8. 多因子策略_单因子选股轮动测试

    多因子策略 因子 因子就是在选择一只股票时,能够帮助你做出决定的一个因素 类型 规模因子 1. 总市值 2. 流通市值 3. 自由流通市值 4. 小市值因子(市值越小,其操纵涨跌所需要的资金越少,股票 ...

  9. akshare改写公募基金轮动策略

    群友说,行业指数不行,没办法跟买.这次我换成了etf进行动量策略,选择本周上涨最强的5个etf,平均持仓,一周后移仓.查看回测效果. 不废话,上传代码,但还是有点毛糙.下次加上日期这些数据,做成df格 ...

  10. 量化选股——基于动量因子的行业风格轮动策略(第2部分—策略回测)

    文章目录 1. 交易策略 2. Backtrader回测程序 3. 回测效果 3.1 2020年1月1日 - 2021年1月1日 3.2 2021年1月1日 - 2022年1月1日 3.3 2022年 ...

最新文章

  1. Java虚拟机的内存空间有几种
  2. 扎心!程序员旅行却只能紧紧抱着电脑加班?
  3. hadoop如何学习?
  4. AspectJ切入点语法详解
  5. 一句话评论设计模式六大原则--转
  6. 部署高可用的Lync Server 2013 Part 4 部署高可用的文件共享DFS
  7. docker mysql编辑器_docker官方mysql镜像自定义配置详解
  8. 【Android】7.1 布局控件常用的公共属性
  9. AT2305-[AGC010D]Decrementing【博弈论】
  10. golismero web扫描器
  11. 如何在服务器上使用matlab
  12. Qt5学习笔记之QString的使用
  13. 元素的水平垂直居中解决方法
  14. scratch python的区别ev3_机器人编程和少儿编程,傻傻分不清—乐高EV3入门感想
  15. 常用的Wi-Fi产品调试测试工具
  16. 唱响艾泽拉斯-泰兰德的拥抱专辑
  17. python爬取付费漫画_Python爬虫---爬取腾讯动漫全站漫画
  18. 多进程log4j日志丢失问题分析
  19. 【数据库SQL实战】获取员工其当前的薪水比其manager当前薪水还高的相关信息
  20. 微信公众平台开发案例

热门文章

  1. 虚拟机安装专用游戏多开win7系统教程简单易懂
  2. Action层, Service层 ,modle层 和 Dao层详解
  3. 走楼梯2<每日一题>
  4. linux 加速度传感器数据获取,对加速度传感器的数据进行方向和坐标的转换
  5. 开源:安卓手机app控制arduino,通过esp8266-01
  6. 数据分析报告这样写,才算真正读懂了数据
  7. 软件设计——云原生12要素
  8. Python-Pyecharts画图(饼图,雷达图,词云)[二]
  9. 1072. 开学寄语(20)
  10. echarts地图设置边界线颜色显示不全