├── .DS_Store ├── .gitattributes ├── Raw ├── .DS_Store ├── 美元汇率.xlsx ├── GC007利率.xlsx ├── 美债收益率.xlsx ├── 资产换手率.xlsx ├── 资产收盘价.xlsx ├── 中债国债到期收益率(中债)(日).xls ├── 社会融资规模.csv └── M2.csv ├── 大类资产配置研究.pdf ├── RiskParity.py ├── Factors.py ├── StatisticFunc.py ├── AlgoLoop.py ├── RiskParityModel_MultiFactors.ipynb ├── RiskParityModel.ipynb └── RiskParityModel_Summary.ipynb /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhehao97/RiskParityFactorModel/HEAD/.DS_Store -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /Raw/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhehao97/RiskParityFactorModel/HEAD/Raw/.DS_Store -------------------------------------------------------------------------------- /Raw/美元汇率.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhehao97/RiskParityFactorModel/HEAD/Raw/美元汇率.xlsx -------------------------------------------------------------------------------- /大类资产配置研究.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhehao97/RiskParityFactorModel/HEAD/大类资产配置研究.pdf -------------------------------------------------------------------------------- /Raw/GC007利率.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhehao97/RiskParityFactorModel/HEAD/Raw/GC007利率.xlsx -------------------------------------------------------------------------------- /Raw/美债收益率.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhehao97/RiskParityFactorModel/HEAD/Raw/美债收益率.xlsx -------------------------------------------------------------------------------- /Raw/资产换手率.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhehao97/RiskParityFactorModel/HEAD/Raw/资产换手率.xlsx -------------------------------------------------------------------------------- /Raw/资产收盘价.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhehao97/RiskParityFactorModel/HEAD/Raw/资产收盘价.xlsx -------------------------------------------------------------------------------- /Raw/中债国债到期收益率(中债)(日).xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zhehao97/RiskParityFactorModel/HEAD/Raw/中债国债到期收益率(中债)(日).xls -------------------------------------------------------------------------------- /RiskParity.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | from scipy import optimize 4 | 5 | 6 | # 20天滑动平均计算协方差矩阵 7 | def CovrainceMatrix(dataFrame): 8 | return np.cov(dataFrame.values.astype(np.float32), rowvar=False, ddof=1) # covraiance matrix of assets at time t 9 | 10 | 11 | # 优化问题中的目标函数 12 | def TargetFunction(weightVec, covarianceMat): 13 | n = len(weightVec) # scalar type, number of assets 14 | 15 | W = np.array(weightVec) # vector type, weights of assets 16 | V = np.matrix(covarianceMat) # matrix type, covariance matrix of assets 17 | 18 | sigma = W[np.newaxis, :] * V * W[:, np.newaxis] # matrix type 19 | sigma = np.sqrt(sigma[0, 0]) # scalar type, portfolio volatility 20 | 21 | tmp = W - sigma ** 2.0 / n / np.dot(V, W.T) # matrix type 22 | tmp = tmp.A1 # vector type 23 | 24 | return np.sum( tmp * tmp ) 25 | 26 | 27 | # 计算各个资产权重 28 | def ComputeWeight(W0, covarianceMat, cols, thrds={'Equity':0.25, 'FixedIncome':0.45, 'Commodity':0.10}): 29 | 30 | # Boundarys 31 | bnds = [] 32 | 33 | for i in range(len(cols)): 34 | if (cols[i] == '沪深300') or (cols[i] == '中证500') or (cols[i] == '标普500'): 35 | bnds.append((0, thrds['Equity'])) 36 | elif (cols[i] == '10年国债') or (cols[i] == '信用债3-5AAA') or (cols[i] == '10年美债'): 37 | bnds.append((0, thrds['FixedIncome'])) 38 | else: 39 | bnds.append((0, thrds['Commodity'])) 40 | 41 | bnds = tuple(bnds) 42 | 43 | 44 | # Constaints 45 | cons = ({'type': 'eq', 'fun': lambda x:np.sum(x) - 1.0}, 46 | {'type': 'ineq', 'fun': lambda x:x} 47 | ) 48 | 49 | # Optimization results 50 | result = optimize.minimize(TargetFunction, W0, args=(covarianceMat), method='SLSQP', 51 | bounds=bnds, constraints=cons, tol=None, callback=None) 52 | 53 | # Normalization 54 | W = np.around(result.x, decimals=5) 55 | W = W / np.sum(W) # standarlization 56 | 57 | return W 58 | 59 | 60 | -------------------------------------------------------------------------------- /Factors.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | import pandas as pd 4 | 5 | 6 | # 横截面动量因子 7 | def momentumX(cumReturns, col, t, dt): 8 | 9 | m = 2 # 取排名前m的资产重仓 10 | momentX = cumReturns.iloc[t-1, :] / cumReturns.iloc[t-dt, :] # 本周期各资产收益率 11 | momentX = momentX.sort_values(ascending=False) # 各资产按收益率排序 12 | topCol = momentX[:m].index & col # 头部资产名称 13 | 14 | return topCol.to_list() 15 | 16 | 17 | # 时序动量因子 18 | def momentumT(cumReturns, col, t, dt): 19 | 20 | threshold = 0.05 * dt / 250 # 年化收益 5% 21 | momentT = cumReturns.iloc[t-1, :] / cumReturns.iloc[t-dt, :] - 1.0 # 本周期收益率 22 | topCol = momentT.index[momentT > threshold] & col # 绝对收益率大于阈值的资产 23 | 24 | return topCol.to_list() 25 | 26 | 27 | # 横截面反转因子 28 | def reverseX(cumReturns, col, t, dt): 29 | 30 | m = 2 # 取排名前m的资产重仓 31 | reverseX = cumReturns.iloc[t-1, :] / cumReturns.iloc[t-dt, :] # 本周期各资产收益率 32 | reverseX = reverseX.sort_values(ascending=True) # 各资产按收益率排序 33 | bottomCol = reverseX[:m].index & col # 尾部资产名称 34 | 35 | return bottomCol.to_list() 36 | 37 | 38 | # 时序反转因子 39 | def reverseT(cumReturns, col, t, dt): 40 | 41 | threshold = -0.05 * dt / 250 # 年化收益 -5% 42 | reverseT = cumReturns.iloc[t-1, :] / cumReturns.iloc[t-dt, :] - 1.0 # 本周期收益率 43 | bottomCol = reverseT.index[reverseT < threshold] & col # 收益率环比增长>0的资产 44 | 45 | return bottomCol.to_list() 46 | 47 | 48 | # 换手率因子 49 | def turnover(Turnovers, col, t, dt): 50 | 51 | tmpTurnovers = Turnovers.ewm(span=dt, axis=0).mean() 52 | tmp_prev = tmpTurnovers.iloc[t-dt, :] 53 | tmp_now = tmpTurnovers.iloc[t, :] 54 | topCol = tmp_now.index[tmp_now > tmp_prev] & col 55 | 56 | return topCol.to_list() 57 | 58 | 59 | # 铜金价格比因子 60 | def copperGold(Prices, col, t, dt): 61 | 62 | ratioCG = Prices['中信证券COMEX铜期货'] / Prices['中信证券COMEX黄金期货'] 63 | 64 | ratioCG = ratioCG.ewm(span=dt, axis=0).mean() 65 | ratio_prev = ratioCG[t-dt] 66 | ratio_now = ratioCG[t] 67 | topCol = set(['10年国债', '信用债3-5AAA']) & set(col.to_list()) 68 | 69 | if (ratio_now < ratio_prev): 70 | return list(topCol) 71 | 72 | else: 73 | return [] 74 | 75 | 76 | # 铜油价格比因子 77 | def copperGas(Prices, col, t, dt): 78 | 79 | ratioCG = Prices['中信证券COMEX铜期货'] / Prices['中信证券WTI原油期货'] 80 | 81 | ratioCG = ratioCG.ewm(span=dt, axis=0).mean() 82 | ratio_prev = ratioCG[t-dt] 83 | ratio_now = ratioCG[t] 84 | topCol = set(['沪深300', '中证500']) & set(col.to_list()) 85 | 86 | if (ratio_now > ratio_prev): 87 | return list(topCol) 88 | 89 | else: 90 | return [] 91 | 92 | 93 | # 汇率因子 94 | def fxRate(FXs, col, t, dt): 95 | 96 | fxs = FXs.ewm(span=dt, axis=0).mean() 97 | fx_prev = fxs['美元汇率'][t-dt] 98 | fx_now = fxs['美元汇率'][t] 99 | 100 | # 重仓中国国债 101 | if (fx_now > fx_prev): 102 | topCol = set(['10年国债']) & set(col.to_list()) 103 | 104 | # 重仓美国国债 105 | elif (fx_now < fx_prev): 106 | topCol = set(['10年美债']) & set(col.to_list()) 107 | 108 | else: 109 | topCol = [] 110 | 111 | return topCol 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /Raw/社会融资规模.csv: -------------------------------------------------------------------------------- 1 | ,社会融资规模:当月值,,,社会融资规模 2 | ,M5206730,,,M5201607 3 | 日期,EDBclose,,日期,EDBclose 4 | Date,EDBclose,,Date,EDBclose 5 | 2008-01-31,10859,,2008-12-31,69802 6 | 2008-02-29,4731,,2009-12-31,139104 7 | 2008-03-31,6391,,2010-12-31,140191 8 | 2008-04-30,7076,,2011-12-31,128286 9 | 2008-05-31,5678,,2012-12-31,157630.8093 10 | 2008-06-30,5976,,2013-12-31,173169 11 | 2008-07-31,4890,,2014-12-31,164571 12 | 2008-08-31,4575,,2015-12-31,154086 13 | 2008-09-30,5659,,2016-12-31,178022 14 | 2008-10-31,1288,,2017-12-31,261535.84 15 | 2008-11-30,4517,,2018-12-31,224920.2 16 | 2008-12-31,8164,,2019-12-31,255753 17 | 2009-01-31,13990,,, 18 | 2009-02-28,11131,,, 19 | 2009-03-31,22011,,, 20 | 2009-04-30,5452,,, 21 | 2009-05-31,14959,,, 22 | 2009-06-30,21067,,, 23 | 2009-07-31,7388,,, 24 | 2009-08-31,7650,,, 25 | 2009-09-30,11871,,, 26 | 2009-10-31,5985,,, 27 | 2009-11-30,9501,,, 28 | 2009-12-31,8100,,, 29 | 2010-01-31,20550,,, 30 | 2010-02-28,10877,,, 31 | 2010-03-31,13830,,, 32 | 2010-04-30,14919,,, 33 | 2010-05-31,10805,,, 34 | 2010-06-30,10196,,, 35 | 2010-07-31,7202,,, 36 | 2010-08-31,10646,,, 37 | 2010-09-30,11224,,, 38 | 2010-10-31,8608,,, 39 | 2010-11-30,10554,,, 40 | 2010-12-31,10780,,, 41 | 2011-01-31,17560,,, 42 | 2011-02-28,6468,,, 43 | 2011-03-31,18212,,, 44 | 2011-04-30,13673,,, 45 | 2011-05-31,10854,,, 46 | 2011-06-30,10873,,, 47 | 2011-07-31,5393,,, 48 | 2011-08-31,10741,,, 49 | 2011-09-30,4279,,, 50 | 2011-10-31,7908,,, 51 | 2011-11-30,9581,,, 52 | 2011-12-31,12744,,, 53 | 2012-01-31,9754,,, 54 | 2012-02-29,10431,,, 55 | 2012-03-31,18704,,, 56 | 2012-04-30,9637,,, 57 | 2012-05-31,11432,,, 58 | 2012-06-30,17802,,, 59 | 2012-07-31,10522,,, 60 | 2012-08-31,12475,,, 61 | 2012-09-30,16462,,, 62 | 2012-10-31,12906,,, 63 | 2012-11-30,11225,,, 64 | 2012-12-31,16282,,, 65 | 2013-01-31,25446,,, 66 | 2013-02-28,10705,,, 67 | 2013-03-31,25503,,, 68 | 2013-04-30,17629,,, 69 | 2013-05-31,11871,,, 70 | 2013-06-30,10375,,, 71 | 2013-07-31,8191,,, 72 | 2013-08-31,15841,,, 73 | 2013-09-30,14120,,, 74 | 2013-10-31,8645,,, 75 | 2013-11-30,12310,,, 76 | 2013-12-31,12532,,, 77 | 2014-01-31,26004,,, 78 | 2014-02-28,9370,,, 79 | 2014-03-31,20934,,, 80 | 2014-04-30,15259,,, 81 | 2014-05-31,14013,,, 82 | 2014-06-30,19673,,, 83 | 2014-07-31,2737,,, 84 | 2014-08-31,9577,,, 85 | 2014-09-30,11355,,, 86 | 2014-10-31,6807,,, 87 | 2014-11-30,11459,,, 88 | 2014-12-31,16945,,, 89 | 2015-01-31,20516,,, 90 | 2015-02-28,13609,,, 91 | 2015-03-31,12433,,, 92 | 2015-04-30,10582,,, 93 | 2015-05-31,12397,,, 94 | 2015-06-30,18384,,, 95 | 2015-07-31,7511,,, 96 | 2015-08-31,11097,,, 97 | 2015-09-30,13571,,, 98 | 2015-10-31,5593,,, 99 | 2015-11-30,10255,,, 100 | 2015-12-31,18114,,, 101 | 2016-01-31,34758,,, 102 | 2016-02-29,8312,,, 103 | 2016-03-31,23931,,, 104 | 2016-04-30,7809,,, 105 | 2016-05-31,6770,,, 106 | 2016-06-30,16479,,, 107 | 2016-07-31,4791,,, 108 | 2016-08-31,14605,,, 109 | 2016-09-30,17115,,, 110 | 2016-10-31,8865,,, 111 | 2016-11-30,18328,,, 112 | 2016-12-31,16260,,, 113 | 2017-01-31,37720.07698,,, 114 | 2017-02-28,11055.32211,,, 115 | 2017-03-31,25471.63956,,, 116 | 2017-04-30,19558.92377,,, 117 | 2017-05-31,17811.73294,,, 118 | 2017-06-30,25885.91095,,, 119 | 2017-07-31,21188.10657,,, 120 | 2017-08-31,20485.50771,,, 121 | 2017-09-30,25438.60694,,, 122 | 2017-10-31,15861.15144,,, 123 | 2017-11-30,22955.98125,,, 124 | 2017-12-31,18102.88255,,, 125 | 2018-01-31,31417.22055,,, 126 | 2018-02-28,12064.38793,,, 127 | 2018-03-31,17091.4767,,, 128 | 2018-04-30,22242.94055,,, 129 | 2018-05-31,11233.62445,,, 130 | 2018-06-30,20372.96461,,, 131 | 2018-07-31,18381.94196,,, 132 | 2018-08-31,24078.24889,,, 133 | 2018-09-30,23061.25012,,, 134 | 2018-10-31,9537.802987,,, 135 | 2018-11-30,16127.16526,,, 136 | 2018-12-31,19311.17408,,, 137 | 2019-01-31,46791.13927,,, 138 | 2019-02-28,9665.126685,,, 139 | 2019-03-31,29602.33653,,, 140 | 2019-04-30,16709.53817,,, 141 | 2019-05-31,17123.72928,,, 142 | 2019-06-30,26243.30201,,, 143 | 2019-07-31,12872.11027,,, 144 | 2019-08-31,21955.76501,,, 145 | 2019-09-30,25142.21046,,, 146 | 2019-10-31,8680.002122,,, 147 | 2019-11-30,19936.91623,,, 148 | 2019-12-31,21030.28486,,, 149 | 2020-01-31,50518,,, 150 | 2020-02-29,8737,,, 151 | 2020-03-31,51830,,, 152 | 2020-04-30,31042,,, 153 | 2020-05-31,31907,,, -------------------------------------------------------------------------------- /Raw/M2.csv: -------------------------------------------------------------------------------- 1 | 时间,M2,M2:同比 2 | 2008/1/1,"417,846.17",18.94 3 | 2008/2/1,"421,037.84",17.48 4 | 2008/3/1,"423,054.53",16.29 5 | 2008/4/1,"429,313.72",16.94 6 | 2008/5/1,"436,221.60",18.07 7 | 2008/6/1,"443,141.02",17.37 8 | 2008/7/1,"446,362.17",16.35 9 | 2008/8/1,"448,846.68",16 10 | 2008/9/1,"452,898.71",15.29 11 | 2008/10/1,"453,133.32",15.02 12 | 2008/11/1,"458,644.66",14.8 13 | 2008/12/1,"475,166.60",17.82 14 | 2009/1/1,"496,135.31",18.79 15 | 2009/2/1,"506,708.07",20.48 16 | 2009/3/1,"530,626.71",25.51 17 | 2009/4/1,"540,481.21",25.89 18 | 2009/5/1,"548,263.51",25.74 19 | 2009/6/1,"568,916.20",28.46 20 | 2009/7/1,"573,102.85",28.42 21 | 2009/8/1,"576,698.95",28.53 22 | 2009/9/1,"585,405.34",29.31 23 | 2009/10/1,"586,643.29",29.42 24 | 2009/11/1,"594,604.72",29.74 25 | 2009/12/1,"610,224.52",27.68 26 | 2010/1/1,"625,609.29",25.98 27 | 2010/2/1,"636,072.26",25.52 28 | 2010/3/1,"649,947.46",22.5 29 | 2010/4/1,"656,561.22",21.48 30 | 2010/5/1,"663,351.37",21 31 | 2010/6/1,"673,921.72",18.46 32 | 2010/7/1,"674,051.48",17.6 33 | 2010/8/1,"687,506.92",19.2 34 | 2010/9/1,"696,471.50",18.96 35 | 2010/10/1,"699,776.74",19.3 36 | 2010/11/1,"710,339.03",19.5 37 | 2010/12/1,"725,851.79",19.72 38 | 2011/1/1,"733,884.83",17.2 39 | 2011/2/1,"736,130.86",15.7 40 | 2011/3/1,"758,130.88",16.6 41 | 2011/4/1,"757,384.56",15.3 42 | 2011/5/1,"763,409.22",15.1 43 | 2011/6/1,"780,820.85",15.9 44 | 2011/7/1,"772,923.65",14.7 45 | 2011/8/1,"780,852.30",13.5 46 | 2011/9/1,"787,406.20",13 47 | 2011/10/1,"816,829.25",12.9 48 | 2011/11/1,"825,493.94",12.7 49 | 2011/12/1,"851,590.90",13.6 50 | 2012/1/1,"855,898.89",12.4 51 | 2012/2/1,"867,171.42",13 52 | 2012/3/1,"895,565.50",13.4 53 | 2012/4/1,"889,604.04",12.8 54 | 2012/5/1,"900,048.77",13.2 55 | 2012/6/1,"924,991.20",13.6 56 | 2012/7/1,"919,072.40",13.9 57 | 2012/8/1,"924,894.59",13.5 58 | 2012/9/1,"943,688.75",14.8 59 | 2012/10/1,"936,404.28",14.1 60 | 2012/11/1,"944,832.35",13.9 61 | 2012/12/1,"974,148.80",13.8 62 | 2013/1/1,"992,129.25",15.9 63 | 2013/2/1,"998,600.83",15.2 64 | 2013/3/1,"1,035,858.37",15.7 65 | 2013/4/1,"1,032,551.90",16.1 66 | 2013/5/1,"1,042,169.16",15.8 67 | 2013/6/1,"1,054,403.69",14 68 | 2013/7/1,"1,052,212.34",14.5 69 | 2013/8/1,"1,061,256.43",14.7 70 | 2013/9/1,"1,077,379.16",14.2 71 | 2013/10/1,"1,070,242.17",14.3 72 | 2013/11/1,"1,079,257.06",14.2 73 | 2013/12/1,"1,106,524.98",13.6 74 | 2014/1/1,"1,123,521.21",13.2 75 | 2014/2/1,"1,131,760.83",13.3 76 | 2014/3/1,"1,160,687.38",12.1 77 | 2014/4/1,"1,168,812.67",13.2 78 | 2014/5/1,"1,182,293.96",13.4 79 | 2014/6/1,"1,209,587.20",14.7 80 | 2014/7/1,"1,194,249.24",13.5 81 | 2014/8/1,"1,197,499.08",12.8 82 | 2014/9/1,"1,202,051.41",12.9 83 | 2014/10/1,"1,199,236.31",12.6 84 | 2014/11/1,"1,208,605.95",12.3 85 | 2014/12/1,"1,228,374.81",12.2 86 | 2015/1/1,"1,242,709.56",10.8 87 | 2015/2/1,"1,257,384.48",12.5 88 | 2015/3/1,"1,275,332.78",11.6 89 | 2015/4/1,"1,280,779.14",10.1 90 | 2015/5/1,"1,307,357.63",10.8 91 | 2015/6/1,"1,333,375.36",11.8 92 | 2015/7/1,"1,353,210.92",13.3 93 | 2015/8/1,"1,356,907.98",13.3 94 | 2015/9/1,"1,359,824.06",13.1 95 | 2015/10/1,"1,361,020.70",13.5 96 | 2015/11/1,"1,373,956.01",13.7 97 | 2015/12/1,"1,392,278.11",13.3 98 | 2016/1/1,"1,416,319.55",14 99 | 2016/2/1,"1,424,618.68",13.3 100 | 2016/3/1,"1,446,198.03",13.4 101 | 2016/4/1,"1,445,209.59",12.8 102 | 2016/5/1,"1,461,695.11",11.8 103 | 2016/6/1,"1,490,491.83",11.8 104 | 2016/7/1,"1,491,558.72",10.2 105 | 2016/8/1,"1,510,982.91",11.4 106 | 2016/9/1,"1,516,360.50",11.5 107 | 2016/10/1,"1,519,485.40",11.6 108 | 2016/11/1,"1,530,432.06",11.4 109 | 2016/12/1,"1,550,066.67",11.3 110 | 2017/1/1,"1,584,194.56",10.7 111 | 2017/2/1,"1,589,857.00",10.4 112 | 2017/3/1,"1,607,938.98",10.1 113 | 2017/4/1,"1,603,918.84",9.8 114 | 2017/5/1,"1,609,740.77",9.1 115 | 2017/6/1,"1,639,497.05",9.1 116 | 2017/7/1,"1,636,341.11",8.9 117 | 2017/8/1,"1,652,947.30",8.6 118 | 2017/9/1,"1,663,666.05",9 119 | 2017/10/1,"1,662,449.96",8.9 120 | 2017/11/1,"1,679,156.64",9.1 121 | 2017/12/1,"1,690,235.32",8.1 122 | 2018/1/1,"1,720,814.46",8.6 123 | 2018/2/1,"1,729,070.12",8.8 124 | 2018/3/1,"1,739,859.48",8.2 125 | 2018/4/1,"1,737,683.73",8.3 126 | 2018/5/1,"1,743,063.79",8.3 127 | 2018/6/1,"1,770,178.37",8 128 | 2018/7/1,"1,776,196.11",8.5 129 | 2018/8/1,"1,788,670.43",8.2 130 | 2018/9/1,"1,801,665.58",8.3 131 | 2018/10/1,"1,795,561.60",8 132 | 2018/11/1,"1,813,175.07",8 133 | 2018/12/1,"1,826,744.22",8.1 134 | 2019/1/1,"1,865,935.33",8.4 135 | 2019/2/1,"1,867,427.45",8 136 | 2019/3/1,"1,889,412.14",8.6 137 | 2019/4/1,"1,884,670.33",8.5 138 | 2019/5/1,"1,891,153.70",8.5 139 | 2019/6/1,"1,921,360.19",8.5 140 | 2019/7/1,"1,919,410.82",8.1 141 | 2019/8/1,"1,935,492.43",8.2 142 | 2019/9/1,"1,952,250.49",8.4 143 | 2019/10/1,"1,945,600.55",8.4 144 | 2019/11/1,"1,961,429.56",8.2 145 | 2019/12/1,"1,986,488.82",8.7 146 | 2020/1/1,"2,023,066.49",8.4 147 | 2020/2/1,"2,030,830.42",8.8 148 | 2020/3/1,"2,080,923.41",10.1 149 | 2020/4/1,"2,093,533.83",11.1 150 | 2020/5/1,"2,100,183.74",11.1 -------------------------------------------------------------------------------- /StatisticFunc.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | import pandas as pd 4 | import matplotlib.pyplot as plt 5 | 6 | ############################################### 7 | # 基本统计指标 8 | ############################################### 9 | 10 | def DailyReturns(tradeDF): 11 | return tradeDF['投资组合净值'] / tradeDF['投资组合净值'].shift(1, axis=0) - 1.0 12 | 13 | def AnnualReturns(tradeDF): 14 | # 0. 创建备用表 15 | DailyNV = tradeDF['投资组合净值'] 16 | 17 | # 1. 计算年份并创建新表 18 | yearIdx = np.unique(tradeDF.index.year) 19 | AnnualNV = pd.DataFrame(index=yearIdx, columns=['年末净值']) # 创建新的记录表 20 | 21 | # 2. 计算每年末资产净值 22 | for y in yearIdx: 23 | mask = DailyNV.index.year == y 24 | AnnualNV.loc[y, '年末净值'] = DailyNV[mask][-1] 25 | 26 | # 3. 计算年间收益率 27 | initialNV = DailyNV.dropna()[0] # 开仓第一天净值 28 | AnnualReturns = AnnualNV / AnnualNV.shift(1, axis=0).fillna(initialNV) - 1.0 29 | return AnnualReturns 30 | 31 | def AnnualVolatility(tradeDF): 32 | return DailyReturns(tradeDF).groupby(tradeDF.index.year).std() * np.sqrt(250) 33 | 34 | def AnnualMaxDrawdown(tradeDF): 35 | return tradeDF['最大回撤'].groupby(tradeDF.index.year).min() 36 | 37 | 38 | 39 | ######################################## 40 | # 画柱形图 41 | ######################################## 42 | def BarPlot(DF, ttl, Ncol=2): 43 | 44 | N = len(DF.columns) 45 | Nrow = int(np.ceil(N / Ncol)) 46 | flag = 0 47 | 48 | fig, axs = plt.subplots(nrows=Nrow, ncols=Ncol, figsize=(16, 3 * Nrow), constrained_layout=True) 49 | for i in range(Nrow): 50 | for j in range(Ncol): 51 | if (flag >= N): 52 | break 53 | axs[i][j].bar(DF.index, height=DF.iloc[:, flag], label=DF.columns[flag]) 54 | axs[i][j].set_xlabel('时间') 55 | axs[i][j].set_ylabel('贡献度') 56 | axs[i][j].set_ylim(-1.5, 1.5) 57 | axs[i][j].legend(loc='best') 58 | axs[i][j].set_title( str(DF.columns[flag])+'对组合损益的贡献度' ) 59 | flag += 1 60 | plt.savefig('Pics/贡献度_' + str(ttl) + '.png') 61 | 62 | return 63 | 64 | 65 | 66 | ######################################## 67 | # 权重走势 68 | ######################################## 69 | def WeightPlot(tradeDF, weightDF, ttl): 70 | 71 | # 1. Find the data of trading day 72 | tradingDay = tradeDF.index[tradeDF['仓位调整']==1.0] 73 | tmpDF = weightDF.loc[tradingDay, :] 74 | tmpDF = tmpDF.fillna(0) 75 | 76 | # 2. Prepare the data for plotting 77 | labs = tmpDF.columns.to_list() 78 | 79 | x = tmpDF.index.to_list() 80 | y = [] 81 | for col in tmpDF.columns: 82 | y.append( tmpDF[col].values.tolist() ) 83 | 84 | y = np.vstack(y) 85 | 86 | # 2. Plot the figure and save 87 | fig = plt.figure(figsize=(16, 6), dpi=150) 88 | plt.stackplot(x, y, labels=labs) 89 | plt.legend(loc='best') 90 | plt.title(str(ttl) + '资产权重走势') 91 | plt.savefig('Pics/资产权重走势_' + str(ttl) + '.png') 92 | 93 | return 94 | 95 | 96 | ############################################################ 97 | # 贡献度计算 98 | ############################################################ 99 | 100 | def PeriodContribution(tradeDF): 101 | 102 | # 计算调仓日 103 | trading_day = tradeDF.index[tradeDF['仓位调整'] == 1.0] 104 | 105 | # 资产名称列表 106 | cols_name = tradeDF.columns[:-3] 107 | 108 | # 周期初资产净值 109 | valueDF_prev = tradeDF.loc[trading_day, cols_name].shift(1, axis=0) 110 | 111 | # 周期末资产净值 112 | valueDF_now = tradeDF.shift(1, axis=0).loc[trading_day, cols_name] 113 | 114 | # 资产净值变化 115 | valueDF_delta = valueDF_now - valueDF_prev 116 | valueDF_delta = valueDF_delta.fillna(0) # 填充NaN类型 117 | 118 | return valueDF_delta 119 | 120 | 121 | def AnnualContribution(tradeDF): 122 | 123 | # 一个交易周期内各资产的损益 124 | valueDF_delta = PeriodContribution(tradeDF) 125 | 126 | # 一年度内各资产的损益 127 | valueDF_annual = valueDF_delta.groupby(valueDF_delta.index.year).sum() 128 | 129 | # 一年度内各资产对组合贡献度 130 | for col in valueDF_annual.columns: 131 | valueDF_annual[col] /= valueDF_annual['投资组合净值'].apply(abs) 132 | 133 | return valueDF_annual.iloc[:, :-1] # 舍去投资组合净值对应列 134 | 135 | 136 | ############################################################ 137 | # 汇总表现 138 | ############################################################ 139 | 140 | # 各年度表现汇总 141 | def summaryDF(tradeDF): 142 | 143 | years = np.unique(tradeDF.reset_index()['日期'].apply(lambda x:str(x)[:4])) 144 | DF = pd.DataFrame(index=years) 145 | 146 | DF["年收益率"] = AnnualReturns( tradeDF ).values 147 | DF["年波动率"] = AnnualVolatility( tradeDF ).values 148 | DF["信息比"] = DF['年收益率'] / DF['年波动率'] 149 | DF["最大回撤"] = AnnualMaxDrawdown( tradeDF ).values 150 | 151 | return DF 152 | 153 | 154 | def performanceDF(smryDF, tradeDF, name): 155 | DF = pd.DataFrame(index=[str(name)], 156 | columns=['年化收益','年化波动率','最大回撤','最长不创新高时间','信息比','Calmar比率']) 157 | 158 | DF['年化收益'] = smryDF['年收益率'].mean() 159 | DF['年化波动率'] = smryDF['年波动率'].mean() 160 | DF['最大回撤'] = smryDF['最大回撤'].min() 161 | DF['最长不创新高时间'] = tradeDF['最长不创新高时间'].max() 162 | DF['信息比'] = DF['年化收益'] / DF['年化波动率'] 163 | DF['Calmar比率'] = DF['年化收益'] / np.abs( DF['最大回撤'] ) 164 | 165 | return DF 166 | -------------------------------------------------------------------------------- /AlgoLoop.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | import pandas as pd 4 | import RiskParity 5 | import Factors 6 | 7 | # 记录投资权重 8 | def recordWeights(WeightDF, idx, colNames, w): 9 | for i in range(len(colNames)): 10 | WeightDF.loc[idx, colNames[i]] = w[i] 11 | return WeightDF 12 | 13 | 14 | # 记录交易数据 15 | def recordTrades(TradeDF, idx, col, assetsValue, totalValue, maxDrawdown, maxTime, pos=0): 16 | for i in range(len(col)): 17 | TradeDF.loc[idx, col[i]] = assetsValue[i] 18 | TradeDF.loc[idx, '投资组合净值'] = totalValue 19 | TradeDF.loc[idx, '最大回撤'] = maxDrawdown 20 | TradeDF.loc[idx, '最长不创新高时间'] = maxTime 21 | TradeDF.loc[idx, '仓位调整'] = pos 22 | return TradeDF 23 | 24 | 25 | 26 | # 主回测程序 27 | def AlgoTrade(Prices, Returns, cumReturns, Turnovers, FXRates, mode='plain', dt=120, up=0.50, 28 | thresholds={'Equity':0.25, 'FixedIncome':0.45, 'Commodity':0.10}, 29 | factorDict={'momentumX':False, 'momentumT':False, 30 | 'reverseX':False, 'reverseT':False, 31 | 'turnover':False, 'fxRate':False, 32 | 'copperGold':False, 'copperGas':False}): 33 | 34 | # 1.初始化数据变量 35 | alpha = 2 / dt # 指数加权系数 36 | totVal = 10000 # 初始资产 37 | maxVal = 10000 # 历史最大净值 38 | maxDay = dt # 创新高时间 39 | maxDd = 0.0 # 最大回撤 40 | flag = 0.0 # flag = 1 有持仓,flag = 0 无持仓 41 | 42 | # 1.1 创建一个副本 43 | tmpPrices = Prices.copy() 44 | tmpReturns = Returns.copy() 45 | tmpCumReturns = cumReturns.copy() 46 | 47 | 48 | # 2.初始化表格 49 | Weights = pd.DataFrame(columns=tmpReturns.columns, index=tmpReturns.index) # 投资权重 50 | Trades = pd.DataFrame(columns=tmpReturns.columns, index=tmpReturns.index) # 投资组合价值 51 | Trades['投资组合净值'] = np.nan 52 | Trades['最大回撤'] = np.nan 53 | Trades['仓位调整'] = np.nan 54 | 55 | 56 | # 3. 主循环 57 | for t in range(dt, tmpReturns.shape[0]): 58 | 59 | # 3.1 截取时间窗口 60 | idx_prev = tmpReturns.index[t-1] # t-1时刻对应日期 61 | idx = tmpReturns.index[t] # t时刻对应日期 62 | subFrame = tmpReturns.iloc[t-dt:t-1, :].dropna(axis=1, how='any') # 剔除缺失数据的资产 63 | col = subFrame.columns # 资产名称 64 | n = subFrame.shape[1] # 资产数量 65 | 66 | 67 | # 3.2 计算等风险权重 68 | # 初始化 69 | w0 = np.repeat(0.4, n) # 初始化权重 70 | V = RiskParity.CovrainceMatrix(subFrame) # 各资产日收益率协方差矩阵 71 | 72 | 73 | # 优化后的各资产权重 74 | w_prev = Weights.loc[idx_prev, col].values # t-1时刻各资产权重 75 | w = RiskParity.ComputeWeight(w0, V, col, thresholds) # 等风险权重 76 | 77 | # 是否将权重进行指数平均 78 | if mode == 'ema': 79 | if ( np.isnan(w_prev.sum()) ): # 检查权重是否全为空值 80 | pass 81 | else: 82 | w = alpha * w + (1 - alpha) * w_prev # 指数加权平均权重 83 | 84 | # 记录权重数据 85 | Weights = recordWeights(Weights, idx, col, w) 86 | 87 | 88 | # 3.3 调整仓位(每dt个交易日) 89 | if (t % dt == 0) and (flag == 0): # 调仓日 90 | 91 | if factorDict['momentumX']: 92 | 93 | # 动量因子(横向比较) 94 | momentumX_col = Factors.momentumX(tmpCumReturns, col, t, dt) 95 | 96 | # print(t, '横截面动量', momentumX_col) 97 | 98 | # 调整权重 99 | if (len(momentumX_col) > 0): 100 | Weights.loc[idx, momentumX_col] = Weights.loc[idx, momentumX_col] * (1.0 + up) # 上调重仓资产权重 101 | Weights.loc[idx, col] = Weights.loc[idx, col] / Weights.loc[idx, col].sum() # 标准化处理, 无杠杆 102 | 103 | 104 | if factorDict['momentumT']: 105 | 106 | # 动量因子(时序比较) 107 | momentumT_col = Factors.momentumT(tmpCumReturns, col, t, dt) 108 | 109 | # print(t, '时序动量', momentumT_col) 110 | 111 | # 调整权重 112 | if (len(momentumT_col) > 0): 113 | Weights.loc[idx, momentumT_col] = Weights.loc[idx, momentumT_col] * (1.0 + up) # 上调重仓资产权重 114 | Weights.loc[idx, col] = Weights.loc[idx, col] / Weights.loc[idx, col].sum() # 标准化处理, 无杠杆 115 | 116 | 117 | if factorDict['reverseX']: 118 | 119 | # 反转因子(横向比较) 120 | reverseX_col = Factors.reverseX(tmpCumReturns, col, t, dt) 121 | 122 | # print(t, '横截面反转', reverseX_col) 123 | 124 | # 调整权重 125 | if (len(reverseX_col) > 0): 126 | Weights.loc[idx, reverseX_col] = Weights.loc[idx, reverseX_col] * (1.0 + up) # 上调重仓资产权重 127 | Weights.loc[idx, col] = Weights.loc[idx, col] / Weights.loc[idx, col].sum() # 标准化处理, 无杠杆 128 | 129 | 130 | if factorDict['reverseT']: 131 | 132 | # 反转因子(时序比较) 133 | reverseT_col = Factors.reverseT(tmpCumReturns, col, t, dt) 134 | 135 | # print(t, '时序反转', reverseT_col) 136 | 137 | # 调整权重 138 | if (len(reverseT_col) > 0): 139 | Weights.loc[idx, reverseT_col] = Weights.loc[idx, reverseT_col] * (1.0 + up) # 上调重仓资产权重 140 | Weights.loc[idx, col] = Weights.loc[idx, col] / Weights.loc[idx, col].sum() # 标准化处理, 无杠杆 141 | 142 | 143 | 144 | if factorDict['turnover']: 145 | 146 | # 情绪因子(股指换手率) 147 | turnover_col = Factors.turnover(Turnovers, col, t, dt) 148 | 149 | # print(t, '换手率', turnover_col) 150 | 151 | # 调整权重 152 | if (len(turnover_col) > 0): 153 | Weights.loc[idx, turnover_col] = Weights.loc[idx, turnover_col] * (1.0 + up) # 上调重仓资产权重 154 | Weights.loc[idx, col] = Weights.loc[idx, col] / Weights.loc[idx, col].sum() # 标准化处理, 无杠杆 155 | 156 | 157 | 158 | if factorDict['fxRate']: 159 | 160 | # 美元兑人民币汇率因子 161 | fx_col = Factors.fxRate(FXRates, col, t, dt) 162 | 163 | # print(t, '汇率因子', fx_col) 164 | 165 | # 调整权重 166 | if (len(fx_col) > 0): 167 | 168 | tot_col = ['10年国债', '10年美债'] # 针对国债和美债进行标准化处理 169 | tot_weight = Weights.loc[idx, tot_col].sum() # 计算调整前国债和美债总权重 170 | Weights.loc[idx, fx_col] = Weights.loc[idx, fx_col] * (1.0 + up) # 上调重仓资产权重 171 | 172 | # 修正国债和美债权重 173 | Weights.loc[idx, tot_col] = tot_weight * Weights.loc[idx, tot_col] / Weights.loc[idx, tot_col].sum() 174 | 175 | 176 | 177 | if factorDict['copperGold']: 178 | 179 | # 铜金价格比因子 180 | copper_gold = Factors.copperGold(tmpPrices, col, t, dt) 181 | 182 | # print(t, '铜金', copper_gold) 183 | 184 | # 调整权重 185 | if (len(copper_gold) > 0): 186 | Weights.loc[idx, copper_gold] = Weights.loc[idx, copper_gold] * (1.0 + up) # 上调重仓资产权重 187 | Weights.loc[idx, col] = Weights.loc[idx, col] / Weights.loc[idx, col].sum() # 标准化处理, 无杠杆 188 | 189 | 190 | 191 | if factorDict['copperGas']: 192 | 193 | # 铜金价格比因子 194 | copper_gas = Factors.copperGas(tmpPrices, col, t, dt) 195 | 196 | # print(t, '铜油', copper_gas) 197 | 198 | # 调整权重 199 | if (len(copper_gas) > 0): 200 | Weights.loc[idx, copper_gas] = Weights.loc[idx, copper_gas] * (1.0 + up) # 上调重仓资产权重 201 | Weights.loc[idx, col] = Weights.loc[idx, col] / Weights.loc[idx, col].sum() # 标准化处理, 无杠杆 202 | 203 | 204 | 205 | ############################### 206 | # 计算各资产配比 207 | ############################### 208 | assetsVal = 0.999 * totVal * Weights.loc[idx, col] # 各资产净值,千1手续费 209 | flag = 1 210 | 211 | 212 | else: 213 | ############################## 214 | # 逐日盯市 215 | ############################## 216 | assetsVal = Trades.loc[idx_prev, col] * (1.0 + Returns.loc[idx, col]) 217 | flag = 0 218 | 219 | 220 | # 3.4 更新净值,并计算最大回撤和最长不创新高时间 221 | totVal = np.sum(assetsVal) # 更新投资组合净值 222 | 223 | if maxVal < totVal: 224 | maxVal = totVal # 更新历史最大净值 225 | maxDay = t # 更新最大净值时间 226 | 227 | # 计算最大回撤 228 | maxDd = (totVal - maxVal) / maxVal 229 | 230 | # 计算最长不创新高时间 231 | maxTt = t - maxDay 232 | 233 | # 3.5 记录交易数据 234 | Trades = recordTrades(Trades, idx, col, assetsVal, totVal, maxDd, maxTt, pos=flag) 235 | 236 | # Weights.to_csv(str(dt) + mode + '权重.csv', encoding='utf_8_sig') 237 | # Trades.to_csv(str(dt) + mode + '交易.csv', encoding='utf_8_sig') 238 | 239 | return Trades, Weights 240 | 241 | -------------------------------------------------------------------------------- /RiskParityModel_MultiFactors.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "ExecuteTime": { 8 | "end_time": "2020-08-14T04:01:10.806039Z", 9 | "start_time": "2020-08-14T04:01:09.546863Z" 10 | } 11 | }, 12 | "outputs": [], 13 | "source": [ 14 | "import numpy as np\n", 15 | "import pandas as pd\n", 16 | "import matplotlib\n", 17 | "import matplotlib.pyplot as plt\n", 18 | "import AlgoLoop\n", 19 | "import StatisticFunc\n", 20 | "\n", 21 | "plt.style.use('seaborn-deep') # 绘图风格\n", 22 | "matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 字体雅黑\n", 23 | "matplotlib.rcParams['font.family'] = 'sans-serif'\n", 24 | "matplotlib.rcParams['axes.unicode_minus'] = False # 处理负号" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "# 预处理" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": {}, 37 | "source": [ 38 | "## 提取并处理数据" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": {}, 44 | "source": [ 45 | "### 各种利率" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": null, 51 | "metadata": { 52 | "ExecuteTime": { 53 | "end_time": "2020-08-14T04:01:10.969304Z", 54 | "start_time": "2020-08-14T04:01:10.807909Z" 55 | } 56 | }, 57 | "outputs": [], 58 | "source": [ 59 | "# GC007 利率\n", 60 | "GCRates = pd.read_excel(io=\"Raw/GC007利率.xlsx\") # 读取数据\n", 61 | "GCRates = GCRates.drop([0, 1, 2], axis=0) # 删除多余行\n", 62 | "GCRates.columns = ['日期', 'GC007'] # 修改列名\n", 63 | "GCRates[\"日期\"] = pd.DatetimeIndex(GCRates[\"日期\"]) # 类型转换\n", 64 | "GCRates = GCRates.set_index(\"日期\") # 设置索引" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": null, 70 | "metadata": { 71 | "ExecuteTime": { 72 | "end_time": "2020-08-14T04:01:26.922096Z", 73 | "start_time": "2020-08-14T04:01:26.846308Z" 74 | } 75 | }, 76 | "outputs": [], 77 | "source": [ 78 | "# 10年国债收益率\n", 79 | "CNRates = pd.read_excel(io=\"Raw/10年国债到期收益率.xls\") # 读取数据\n", 80 | "CNRates.columns = ['日期', '十年国债收益率'] # 修改列名\n", 81 | "CNRates = CNRates.drop([0, 3870, 3871], axis=0) # 删除多余行\n", 82 | "CNRates[\"日期\"] = pd.DatetimeIndex(CNRates[\"日期\"]) # 类型转换\n", 83 | "CNRates = CNRates.set_index(\"日期\") # 设置索引" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": null, 89 | "metadata": { 90 | "ExecuteTime": { 91 | "end_time": "2020-08-14T04:01:32.625659Z", 92 | "start_time": "2020-08-14T04:01:32.420727Z" 93 | } 94 | }, 95 | "outputs": [], 96 | "source": [ 97 | "# 10年美债收益率\n", 98 | "USRates = pd.read_excel(io=\"Raw/10年美债到期收益率.xlsx\") # 读取数据\n", 99 | "USRates.columns = ['日期', '十年美债收益率'] # 修改列名\n", 100 | "USRates = USRates.drop([0, 6263, 6264], axis=0) # 删除多余行\n", 101 | "USRates[\"日期\"] = pd.DatetimeIndex(USRates[\"日期\"]) # 类型转换\n", 102 | "USRates = USRates.set_index(\"日期\") # 设置索引" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": null, 108 | "metadata": { 109 | "ExecuteTime": { 110 | "end_time": "2020-08-14T04:02:32.036808Z", 111 | "start_time": "2020-08-14T04:02:32.030640Z" 112 | } 113 | }, 114 | "outputs": [], 115 | "source": [ 116 | "# 合并利率\n", 117 | "Rates = GCRates.merge(CNRates, how='left', left_index=True, right_index=True)\n", 118 | "Rates = Rates.merge(USRates, how='left', left_index=True, right_index=True)" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": {}, 124 | "source": [ 125 | "### 权益类资产换手率" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": null, 131 | "metadata": { 132 | "ExecuteTime": { 133 | "end_time": "2020-08-14T04:02:35.368208Z", 134 | "start_time": "2020-08-14T04:02:35.202771Z" 135 | } 136 | }, 137 | "outputs": [], 138 | "source": [ 139 | "Turnovers = pd.read_excel(io=\"Raw/资产换手率.xlsx\") # 读取数据\n", 140 | "Turnovers = Turnovers.drop([0], axis=0) # 删除多余行\n", 141 | "Turnovers[\"日期\"] = pd.DatetimeIndex(Turnovers[\"日期\"]) # 类型转换\n", 142 | "Turnovers = Turnovers.set_index(\"日期\") # 设置索引" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": null, 148 | "metadata": { 149 | "ExecuteTime": { 150 | "end_time": "2020-08-14T04:02:35.637779Z", 151 | "start_time": "2020-08-14T04:02:35.633959Z" 152 | } 153 | }, 154 | "outputs": [], 155 | "source": [ 156 | "# 时间对齐\n", 157 | "Turnovers = Turnovers.loc[Rates.index, :]" 158 | ] 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "metadata": {}, 163 | "source": [ 164 | "### 铁矿石价格指数" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": null, 170 | "metadata": { 171 | "ExecuteTime": { 172 | "end_time": "2020-08-14T04:02:36.592105Z", 173 | "start_time": "2020-08-14T04:02:36.533075Z" 174 | } 175 | }, 176 | "outputs": [], 177 | "source": [ 178 | "IronStone = pd.read_excel(io=\"Raw/铁矿石价格指数.xls\") # 读取数据\n", 179 | "IronStone = IronStone.drop([0, 2642, 2643], axis=0) # 删除多余行\n", 180 | "IronStone.columns=['日期', '铁矿石期货'] # 修改列名\n", 181 | "IronStone[\"日期\"] = pd.DatetimeIndex(IronStone[\"日期\"]) # 类型转换\n", 182 | "IronStone = IronStone.set_index(\"日期\") # 设置索引" 183 | ] 184 | }, 185 | { 186 | "cell_type": "markdown", 187 | "metadata": {}, 188 | "source": [ 189 | "### 各资产收盘价" 190 | ] 191 | }, 192 | { 193 | "cell_type": "code", 194 | "execution_count": null, 195 | "metadata": { 196 | "ExecuteTime": { 197 | "end_time": "2020-08-14T04:02:37.226139Z", 198 | "start_time": "2020-08-14T04:02:36.926112Z" 199 | } 200 | }, 201 | "outputs": [], 202 | "source": [ 203 | "Assets = pd.read_excel(io=\"Raw/资产收盘价.xlsx\") # 读取数据\n", 204 | "Assets = Assets.drop([0], axis=0) # 删除多余行\n", 205 | "Assets[\"日期\"] = pd.DatetimeIndex(Assets[\"日期\"]) # 类型转换\n", 206 | "Assets = Assets.set_index(\"日期\") # 设置索引\n", 207 | "Assets = Assets.loc[Rates.index, :] # 时间对齐" 208 | ] 209 | }, 210 | { 211 | "cell_type": "code", 212 | "execution_count": null, 213 | "metadata": { 214 | "ExecuteTime": { 215 | "end_time": "2020-08-14T04:02:37.250055Z", 216 | "start_time": "2020-08-14T04:02:37.227838Z" 217 | } 218 | }, 219 | "outputs": [], 220 | "source": [ 221 | "# 整合铁矿石数据\n", 222 | "Assets = Assets.drop('中信证券铁矿石', axis=1)\n", 223 | "Assets = Assets.merge(IronStone, how='left', left_index=True, right_index=True)\n", 224 | "\n", 225 | "# 填充铁矿石2011年前缺失数据\n", 226 | "Assets['铁矿石期货'] = Assets['铁矿石期货'].fillna(method='bfill')\n", 227 | "Assets.head()" 228 | ] 229 | }, 230 | { 231 | "cell_type": "markdown", 232 | "metadata": {}, 233 | "source": [ 234 | "### 十年国债&美债价格指数" 235 | ] 236 | }, 237 | { 238 | "cell_type": "code", 239 | "execution_count": null, 240 | "metadata": { 241 | "ExecuteTime": { 242 | "end_time": "2020-08-14T04:02:37.713382Z", 243 | "start_time": "2020-08-14T04:02:37.691688Z" 244 | } 245 | }, 246 | "outputs": [], 247 | "source": [ 248 | "HoldPeriod = (Assets.index - Assets.index[0]).days\n", 249 | "\n", 250 | "# 计算十年国债\n", 251 | "Assets['10年国债'] = 100 - (Rates['十年国债收益率'] - 3.0) * 8.2 + 3.0 * HoldPeriod / 365.0\n", 252 | "Assets['10年国债'] = Assets['10年国债'].fillna(method='ffill')\n", 253 | "\n", 254 | "#计算十年美债\n", 255 | "Assets['10年美债'] = 100 - (Rates['十年美债收益率'] - 3.0) * 8.2 + 3.0 * HoldPeriod / 365.0\n", 256 | "Assets['10年美债'] = Assets['10年美债'].fillna(method='ffill')" 257 | ] 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": null, 262 | "metadata": { 263 | "ExecuteTime": { 264 | "end_time": "2020-08-14T04:02:37.985823Z", 265 | "start_time": "2020-08-14T04:02:37.971311Z" 266 | } 267 | }, 268 | "outputs": [], 269 | "source": [ 270 | "# 替换上证十年国债指数\n", 271 | "Assets = Assets.drop('上证10年国债', axis=1)\n", 272 | "Assets.head()" 273 | ] 274 | }, 275 | { 276 | "cell_type": "markdown", 277 | "metadata": {}, 278 | "source": [ 279 | "### 美元汇率" 280 | ] 281 | }, 282 | { 283 | "cell_type": "code", 284 | "execution_count": null, 285 | "metadata": { 286 | "ExecuteTime": { 287 | "end_time": "2020-08-14T04:02:38.870381Z", 288 | "start_time": "2020-08-14T04:02:38.722693Z" 289 | } 290 | }, 291 | "outputs": [], 292 | "source": [ 293 | "FXRates = pd.read_excel(io=\"Raw/美元汇率.xlsx\")\n", 294 | "FXRates = FXRates.drop([0, 1, 2], axis=0)\n", 295 | "FXRates.columns = ['日期', '美元汇率'] \n", 296 | "FXRates[\"日期\"] = pd.DatetimeIndex(FXRates[\"日期\"])\n", 297 | "FXRates = FXRates.set_index(\"日期\")" 298 | ] 299 | }, 300 | { 301 | "cell_type": "code", 302 | "execution_count": null, 303 | "metadata": { 304 | "ExecuteTime": { 305 | "end_time": "2020-08-14T04:02:39.109598Z", 306 | "start_time": "2020-08-14T04:02:39.107424Z" 307 | } 308 | }, 309 | "outputs": [], 310 | "source": [ 311 | "# # 皮尔逊相关系数\n", 312 | "# np.corrcoef( FXRates.values.flatten().astype(np.float32)[900:-233], \n", 313 | "# (Assets['10年国债'] - Assets['10年美债']).values.astype(np.float32)[900:-220] )" 314 | ] 315 | }, 316 | { 317 | "cell_type": "markdown", 318 | "metadata": {}, 319 | "source": [ 320 | "## 计算各资产收益率" 321 | ] 322 | }, 323 | { 324 | "cell_type": "markdown", 325 | "metadata": {}, 326 | "source": [ 327 | "### 日内损益" 328 | ] 329 | }, 330 | { 331 | "cell_type": "code", 332 | "execution_count": null, 333 | "metadata": { 334 | "ExecuteTime": { 335 | "end_time": "2020-08-14T04:02:39.983444Z", 336 | "start_time": "2020-08-14T04:02:39.970424Z" 337 | } 338 | }, 339 | "outputs": [], 340 | "source": [ 341 | "Returns = Assets.pct_change(axis=0)\n", 342 | "Returns = Returns.dropna(axis=0, how='all') # 删除无数据日" 343 | ] 344 | }, 345 | { 346 | "cell_type": "markdown", 347 | "metadata": {}, 348 | "source": [ 349 | "### 累计损益" 350 | ] 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": null, 355 | "metadata": { 356 | "ExecuteTime": { 357 | "end_time": "2020-08-14T04:02:40.458272Z", 358 | "start_time": "2020-08-14T04:02:40.450143Z" 359 | } 360 | }, 361 | "outputs": [], 362 | "source": [ 363 | "cumReturns = (1.0 + Returns)\n", 364 | "cumReturns = cumReturns.fillna(1.0) # 填充空值\n", 365 | "cumReturns = cumReturns.cumprod() # 计算各资产累计收益率" 366 | ] 367 | }, 368 | { 369 | "cell_type": "markdown", 370 | "metadata": {}, 371 | "source": [ 372 | "### 杠杆调整后的债券净值" 373 | ] 374 | }, 375 | { 376 | "cell_type": "code", 377 | "execution_count": null, 378 | "metadata": { 379 | "ExecuteTime": { 380 | "end_time": "2020-08-14T04:02:40.836960Z", 381 | "start_time": "2020-08-14T04:02:40.833442Z" 382 | } 383 | }, 384 | "outputs": [], 385 | "source": [ 386 | "lever = 2.0 # 杠杆(额外)\n", 387 | "leverReturns = Returns.copy() # 创建副本 \n", 388 | "leverCumReturns = cumReturns.copy() " 389 | ] 390 | }, 391 | { 392 | "cell_type": "code", 393 | "execution_count": null, 394 | "metadata": { 395 | "ExecuteTime": { 396 | "end_time": "2020-08-14T04:02:41.021039Z", 397 | "start_time": "2020-08-14T04:02:41.004172Z" 398 | } 399 | }, 400 | "outputs": [], 401 | "source": [ 402 | "# 更新杠杆调整后的债券净值\n", 403 | "leverReturns['10年国债'] = Returns['10年国债'] * (1.0 + lever) - Rates.loc[Returns.index, 'GC007'] * lever / (365.0 * 100)\n", 404 | "leverReturns['信用债3-5AAA'] = Returns['信用债3-5AAA'] * (1.0 + lever) - Rates.loc[Returns.index, 'GC007'] * lever / (365.0 * 100)\n", 405 | "\n", 406 | "# 更新累计净值\n", 407 | "leverCumReturns = (1.0 + leverReturns)\n", 408 | "leverCumReturns = leverCumReturns.fillna(1.0) # 填充空值\n", 409 | "leverCumReturns = leverCumReturns.cumprod() # 计算各资产累计收益率" 410 | ] 411 | }, 412 | { 413 | "cell_type": "markdown", 414 | "metadata": {}, 415 | "source": [ 416 | "### 剔除美元资产" 417 | ] 418 | }, 419 | { 420 | "cell_type": "code", 421 | "execution_count": null, 422 | "metadata": { 423 | "ExecuteTime": { 424 | "end_time": "2020-08-14T04:02:41.326764Z", 425 | "start_time": "2020-08-14T04:02:41.322344Z" 426 | } 427 | }, 428 | "outputs": [], 429 | "source": [ 430 | "leverReturns_Domestic = leverReturns.drop(['标普500', '10年美债'], axis=1)\n", 431 | "leverCumReturns_Domestic = leverCumReturns.drop(['标普500', '10年美债'], axis=1)" 432 | ] 433 | }, 434 | { 435 | "cell_type": "code", 436 | "execution_count": null, 437 | "metadata": { 438 | "ExecuteTime": { 439 | "end_time": "2020-08-14T04:02:41.788101Z", 440 | "start_time": "2020-08-14T04:02:41.485934Z" 441 | } 442 | }, 443 | "outputs": [], 444 | "source": [ 445 | "leverCumReturns_Domestic.plot(figsize=(16, 6))" 446 | ] 447 | }, 448 | { 449 | "cell_type": "markdown", 450 | "metadata": {}, 451 | "source": [ 452 | "# 风险平价 (杠杆+指数平均)" 453 | ] 454 | }, 455 | { 456 | "cell_type": "markdown", 457 | "metadata": {}, 458 | "source": [ 459 | "## 程序运行" 460 | ] 461 | }, 462 | { 463 | "cell_type": "code", 464 | "execution_count": null, 465 | "metadata": { 466 | "ExecuteTime": { 467 | "end_time": "2020-08-14T04:03:53.225176Z", 468 | "start_time": "2020-08-14T04:02:43.602117Z" 469 | } 470 | }, 471 | "outputs": [], 472 | "source": [ 473 | "tradeDF, weightDF = AlgoLoop.AlgoTrade(Assets, leverReturns_Domestic, leverCumReturns_Domestic, \n", 474 | " Turnovers, FXRates, mode='ema')" 475 | ] 476 | }, 477 | { 478 | "cell_type": "code", 479 | "execution_count": null, 480 | "metadata": { 481 | "ExecuteTime": { 482 | "end_time": "2020-08-14T04:03:53.823461Z", 483 | "start_time": "2020-08-14T04:03:53.227397Z" 484 | } 485 | }, 486 | "outputs": [], 487 | "source": [ 488 | "StatisticFunc.WeightPlot(tradeDF, weightDF, '基准模型')" 489 | ] 490 | }, 491 | { 492 | "cell_type": "markdown", 493 | "metadata": {}, 494 | "source": [ 495 | "## 回测表现汇总" 496 | ] 497 | }, 498 | { 499 | "cell_type": "code", 500 | "execution_count": null, 501 | "metadata": { 502 | "ExecuteTime": { 503 | "end_time": "2020-08-14T04:03:53.862397Z", 504 | "start_time": "2020-08-14T04:03:53.826334Z" 505 | } 506 | }, 507 | "outputs": [], 508 | "source": [ 509 | "smryDF = StatisticFunc.summaryDF(tradeDF)\n", 510 | "pfmcDF = StatisticFunc.performanceDF(smryDF, tradeDF, name='基准模型')" 511 | ] 512 | }, 513 | { 514 | "cell_type": "code", 515 | "execution_count": null, 516 | "metadata": { 517 | "ExecuteTime": { 518 | "end_time": "2020-08-14T04:03:53.873926Z", 519 | "start_time": "2020-08-14T04:03:53.864646Z" 520 | } 521 | }, 522 | "outputs": [], 523 | "source": [ 524 | "smryDF" 525 | ] 526 | }, 527 | { 528 | "cell_type": "code", 529 | "execution_count": null, 530 | "metadata": { 531 | "ExecuteTime": { 532 | "end_time": "2020-08-14T04:03:53.884055Z", 533 | "start_time": "2020-08-14T04:03:53.875720Z" 534 | } 535 | }, 536 | "outputs": [], 537 | "source": [ 538 | "pfmcDF" 539 | ] 540 | }, 541 | { 542 | "cell_type": "markdown", 543 | "metadata": {}, 544 | "source": [ 545 | "## 收益率贡献度" 546 | ] 547 | }, 548 | { 549 | "cell_type": "code", 550 | "execution_count": null, 551 | "metadata": { 552 | "ExecuteTime": { 553 | "end_time": "2020-08-14T04:03:53.908394Z", 554 | "start_time": "2020-08-14T04:03:53.887289Z" 555 | }, 556 | "scrolled": true 557 | }, 558 | "outputs": [], 559 | "source": [ 560 | "annualContrb = StatisticFunc.AnnualContribution(tradeDF)" 561 | ] 562 | }, 563 | { 564 | "cell_type": "code", 565 | "execution_count": null, 566 | "metadata": { 567 | "ExecuteTime": { 568 | "end_time": "2020-08-14T04:03:56.262700Z", 569 | "start_time": "2020-08-14T04:03:53.909877Z" 570 | } 571 | }, 572 | "outputs": [], 573 | "source": [ 574 | "StatisticFunc.BarPlot(annualContrb, '基准模型')" 575 | ] 576 | }, 577 | { 578 | "cell_type": "markdown", 579 | "metadata": {}, 580 | "source": [ 581 | "## 投资组合净值曲线" 582 | ] 583 | }, 584 | { 585 | "cell_type": "code", 586 | "execution_count": null, 587 | "metadata": { 588 | "ExecuteTime": { 589 | "end_time": "2020-08-14T04:03:56.610154Z", 590 | "start_time": "2020-08-14T04:03:56.268403Z" 591 | }, 592 | "scrolled": false 593 | }, 594 | "outputs": [], 595 | "source": [ 596 | "fig = plt.figure(figsize=(16, 6))\n", 597 | "\n", 598 | "plt.plot(tradeDF.index, tradeDF['投资组合净值']/10000, label='基准模型')\n", 599 | " \n", 600 | "plt.plot(cumReturns.index, cumReturns['中证500'], lw=0.8, label='中证500')\n", 601 | "plt.plot(cumReturns.index, cumReturns['标普500'], lw=0.8, label='标普500')\n", 602 | "plt.plot(cumReturns.index, cumReturns['10年国债'], lw=0.8, label='10年国债')\n", 603 | "\n", 604 | "plt.xlabel('时间')\n", 605 | "plt.ylabel('净值')\n", 606 | "plt.ylim(0.0, 3.0)\n", 607 | "plt.legend(loc='upper left')\n", 608 | "plt.title('净值曲线(杠杆,指数平均)')\n", 609 | "plt.savefig('Pics/净值曲线(杠杆,指数平均).png')" 610 | ] 611 | }, 612 | { 613 | "cell_type": "markdown", 614 | "metadata": {}, 615 | "source": [ 616 | "# 风险平价 + 单因子策略(杠杆+指数平均)" 617 | ] 618 | }, 619 | { 620 | "cell_type": "markdown", 621 | "metadata": {}, 622 | "source": [ 623 | "## 换手率" 624 | ] 625 | }, 626 | { 627 | "cell_type": "markdown", 628 | "metadata": {}, 629 | "source": [ 630 | "### 程序运行" 631 | ] 632 | }, 633 | { 634 | "cell_type": "code", 635 | "execution_count": null, 636 | "metadata": { 637 | "ExecuteTime": { 638 | "end_time": "2020-08-14T04:05:16.858998Z", 639 | "start_time": "2020-08-14T04:03:56.614588Z" 640 | } 641 | }, 642 | "outputs": [], 643 | "source": [ 644 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 645 | "factors = {'momentumX':False, 'momentumT':False, \n", 646 | " 'reverseX':False, 'reverseT':False,\n", 647 | " 'turnover':True, 'fxRate':False,\n", 648 | " 'copperGold':False, 'copperGas':False}\n", 649 | "\n", 650 | "tradeDF_1, weightDF_1 = AlgoLoop.AlgoTrade(Assets, leverReturns_Domestic, leverCumReturns_Domestic, \n", 651 | " Turnovers, FXRates, mode='ema', dt=120, up=0.50, \n", 652 | " thresholds=thrds, factorDict=factors)" 653 | ] 654 | }, 655 | { 656 | "cell_type": "code", 657 | "execution_count": null, 658 | "metadata": { 659 | "ExecuteTime": { 660 | "end_time": "2020-08-14T04:05:17.469917Z", 661 | "start_time": "2020-08-14T04:05:16.861646Z" 662 | } 663 | }, 664 | "outputs": [], 665 | "source": [ 666 | "StatisticFunc.WeightPlot(tradeDF_1, weightDF_1, '换手率')" 667 | ] 668 | }, 669 | { 670 | "cell_type": "markdown", 671 | "metadata": {}, 672 | "source": [ 673 | "### 回测表现汇总" 674 | ] 675 | }, 676 | { 677 | "cell_type": "code", 678 | "execution_count": null, 679 | "metadata": { 680 | "ExecuteTime": { 681 | "end_time": "2020-08-14T04:05:17.508922Z", 682 | "start_time": "2020-08-14T04:05:17.471889Z" 683 | } 684 | }, 685 | "outputs": [], 686 | "source": [ 687 | "smryDF_1 = StatisticFunc.summaryDF(tradeDF_1)\n", 688 | "pfmcDF_1 = StatisticFunc.performanceDF(smryDF_1, tradeDF_1, name='换手率')" 689 | ] 690 | }, 691 | { 692 | "cell_type": "code", 693 | "execution_count": null, 694 | "metadata": { 695 | "ExecuteTime": { 696 | "end_time": "2020-08-14T04:05:17.519888Z", 697 | "start_time": "2020-08-14T04:05:17.510994Z" 698 | } 699 | }, 700 | "outputs": [], 701 | "source": [ 702 | "smryDF_1" 703 | ] 704 | }, 705 | { 706 | "cell_type": "code", 707 | "execution_count": null, 708 | "metadata": { 709 | "ExecuteTime": { 710 | "end_time": "2020-08-14T04:05:17.532308Z", 711 | "start_time": "2020-08-14T04:05:17.522195Z" 712 | } 713 | }, 714 | "outputs": [], 715 | "source": [ 716 | "pfmcDF_1" 717 | ] 718 | }, 719 | { 720 | "cell_type": "markdown", 721 | "metadata": {}, 722 | "source": [ 723 | "### 收益率贡献度" 724 | ] 725 | }, 726 | { 727 | "cell_type": "code", 728 | "execution_count": null, 729 | "metadata": { 730 | "ExecuteTime": { 731 | "end_time": "2020-08-14T04:05:17.555744Z", 732 | "start_time": "2020-08-14T04:05:17.534377Z" 733 | }, 734 | "scrolled": true 735 | }, 736 | "outputs": [], 737 | "source": [ 738 | "annualContrb_1 = StatisticFunc.AnnualContribution(tradeDF_1)" 739 | ] 740 | }, 741 | { 742 | "cell_type": "code", 743 | "execution_count": null, 744 | "metadata": { 745 | "ExecuteTime": { 746 | "end_time": "2020-08-14T04:05:19.920851Z", 747 | "start_time": "2020-08-14T04:05:17.557550Z" 748 | } 749 | }, 750 | "outputs": [], 751 | "source": [ 752 | "StatisticFunc.BarPlot(annualContrb_1, '换手率')" 753 | ] 754 | }, 755 | { 756 | "cell_type": "markdown", 757 | "metadata": {}, 758 | "source": [ 759 | "### 投资组合净值曲线" 760 | ] 761 | }, 762 | { 763 | "cell_type": "code", 764 | "execution_count": null, 765 | "metadata": { 766 | "ExecuteTime": { 767 | "end_time": "2020-08-14T04:05:20.218337Z", 768 | "start_time": "2020-08-14T04:05:19.923094Z" 769 | }, 770 | "scrolled": false 771 | }, 772 | "outputs": [], 773 | "source": [ 774 | "fig = plt.figure(figsize=(16, 8))\n", 775 | "\n", 776 | "plt.plot(tradeDF_1.index, tradeDF_1['投资组合净值']/10000, label='换手率')\n", 777 | "\n", 778 | "# 基准参考\n", 779 | "plt.plot(tradeDF.index, tradeDF['投资组合净值']/10000, ls='--', label='基准组合') \n", 780 | "plt.plot(cumReturns.index, cumReturns['中证500'], label='中证500')\n", 781 | "plt.plot(cumReturns.index, cumReturns['10年国债'], label='中国10年国债')\n", 782 | "\n", 783 | "plt.xlabel('时间')\n", 784 | "plt.ylabel('净值')\n", 785 | "plt.ylim(0.0, 5.0)\n", 786 | "plt.legend(loc='upper left')\n", 787 | "plt.title('净值曲线(换手率)')\n", 788 | "plt.savefig('Pics/净值曲线(换手率).png')" 789 | ] 790 | }, 791 | { 792 | "cell_type": "markdown", 793 | "metadata": {}, 794 | "source": [ 795 | "## 横截面动量" 796 | ] 797 | }, 798 | { 799 | "cell_type": "markdown", 800 | "metadata": {}, 801 | "source": [ 802 | "### 程序运行" 803 | ] 804 | }, 805 | { 806 | "cell_type": "code", 807 | "execution_count": null, 808 | "metadata": { 809 | "ExecuteTime": { 810 | "end_time": "2020-08-14T04:06:39.416901Z", 811 | "start_time": "2020-08-14T04:05:20.220602Z" 812 | } 813 | }, 814 | "outputs": [], 815 | "source": [ 816 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 817 | "factors = {'momentumX':True, 'momentumT':False, \n", 818 | " 'reverseX':False, 'reverseT':False,\n", 819 | " 'turnover':False, 'fxRate':False,\n", 820 | " 'copperGold':False, 'copperGas':False}\n", 821 | "\n", 822 | "tradeDF_2, weightDF_2 = AlgoLoop.AlgoTrade(Assets, leverReturns_Domestic, leverCumReturns_Domestic, \n", 823 | " Turnovers, FXRates, mode='ema', dt=120, up=0.50, \n", 824 | " thresholds=thrds, factorDict=factors)" 825 | ] 826 | }, 827 | { 828 | "cell_type": "code", 829 | "execution_count": null, 830 | "metadata": { 831 | "ExecuteTime": { 832 | "end_time": "2020-08-14T04:06:40.025286Z", 833 | "start_time": "2020-08-14T04:06:39.419422Z" 834 | } 835 | }, 836 | "outputs": [], 837 | "source": [ 838 | "StatisticFunc.WeightPlot(tradeDF_2, weightDF_2, '横截面动量')" 839 | ] 840 | }, 841 | { 842 | "cell_type": "markdown", 843 | "metadata": {}, 844 | "source": [ 845 | "### 回测表现汇总" 846 | ] 847 | }, 848 | { 849 | "cell_type": "code", 850 | "execution_count": null, 851 | "metadata": { 852 | "ExecuteTime": { 853 | "end_time": "2020-08-14T04:06:40.063853Z", 854 | "start_time": "2020-08-14T04:06:40.027539Z" 855 | } 856 | }, 857 | "outputs": [], 858 | "source": [ 859 | "smryDF_2 = StatisticFunc.summaryDF(tradeDF_2)\n", 860 | "pfmcDF_2 = StatisticFunc.performanceDF(smryDF_2, tradeDF_2, name='横截面动量')" 861 | ] 862 | }, 863 | { 864 | "cell_type": "code", 865 | "execution_count": null, 866 | "metadata": { 867 | "ExecuteTime": { 868 | "end_time": "2020-08-14T04:06:40.076046Z", 869 | "start_time": "2020-08-14T04:06:40.065806Z" 870 | } 871 | }, 872 | "outputs": [], 873 | "source": [ 874 | "smryDF_2" 875 | ] 876 | }, 877 | { 878 | "cell_type": "code", 879 | "execution_count": null, 880 | "metadata": { 881 | "ExecuteTime": { 882 | "end_time": "2020-08-14T04:06:40.088629Z", 883 | "start_time": "2020-08-14T04:06:40.077782Z" 884 | } 885 | }, 886 | "outputs": [], 887 | "source": [ 888 | "pfmcDF_2" 889 | ] 890 | }, 891 | { 892 | "cell_type": "markdown", 893 | "metadata": {}, 894 | "source": [ 895 | "### 收益率贡献度" 896 | ] 897 | }, 898 | { 899 | "cell_type": "code", 900 | "execution_count": null, 901 | "metadata": { 902 | "ExecuteTime": { 903 | "end_time": "2020-08-14T04:06:40.115397Z", 904 | "start_time": "2020-08-14T04:06:40.090843Z" 905 | }, 906 | "scrolled": true 907 | }, 908 | "outputs": [], 909 | "source": [ 910 | "annualContrb_2 = StatisticFunc.AnnualContribution(tradeDF_2)" 911 | ] 912 | }, 913 | { 914 | "cell_type": "code", 915 | "execution_count": null, 916 | "metadata": { 917 | "ExecuteTime": { 918 | "end_time": "2020-08-14T04:06:42.499970Z", 919 | "start_time": "2020-08-14T04:06:40.124185Z" 920 | } 921 | }, 922 | "outputs": [], 923 | "source": [ 924 | "StatisticFunc.BarPlot(annualContrb_2, '横截面动量')" 925 | ] 926 | }, 927 | { 928 | "cell_type": "markdown", 929 | "metadata": {}, 930 | "source": [ 931 | "### 投资组合净值曲线" 932 | ] 933 | }, 934 | { 935 | "cell_type": "code", 936 | "execution_count": null, 937 | "metadata": { 938 | "ExecuteTime": { 939 | "end_time": "2020-08-14T04:06:42.824788Z", 940 | "start_time": "2020-08-14T04:06:42.505963Z" 941 | }, 942 | "scrolled": false 943 | }, 944 | "outputs": [], 945 | "source": [ 946 | "fig = plt.figure(figsize=(16, 8))\n", 947 | "\n", 948 | "plt.plot(tradeDF_2.index, tradeDF_2['投资组合净值']/10000, label='横截面动量')\n", 949 | " \n", 950 | "# 基准参考\n", 951 | "plt.plot(tradeDF.index, tradeDF['投资组合净值']/10000, ls='--', label='基准组合')\n", 952 | "plt.plot(cumReturns.index, cumReturns['中证500'], lw=0.8, label='中证500')\n", 953 | "plt.plot(cumReturns.index, cumReturns['标普500'], lw=0.8, label='标普500')\n", 954 | "plt.plot(cumReturns.index, cumReturns['10年国债'], lw=0.8, label='10年国债')\n", 955 | "\n", 956 | "plt.xlabel('时间')\n", 957 | "plt.ylabel('净值')\n", 958 | "plt.ylim(0.0, 3.0)\n", 959 | "plt.legend(loc='upper left')\n", 960 | "plt.title('净值曲线(横截面动量)')\n", 961 | "plt.savefig('Pics/净值曲线(横截面动量).png')" 962 | ] 963 | }, 964 | { 965 | "cell_type": "markdown", 966 | "metadata": {}, 967 | "source": [ 968 | "## 时序动量" 969 | ] 970 | }, 971 | { 972 | "cell_type": "markdown", 973 | "metadata": {}, 974 | "source": [ 975 | "### 程序运行" 976 | ] 977 | }, 978 | { 979 | "cell_type": "code", 980 | "execution_count": null, 981 | "metadata": { 982 | "ExecuteTime": { 983 | "end_time": "2020-08-14T04:08:01.678391Z", 984 | "start_time": "2020-08-14T04:06:42.828035Z" 985 | } 986 | }, 987 | "outputs": [], 988 | "source": [ 989 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 990 | "factors = {'momentumX':False, 'momentumT':True, \n", 991 | " 'reverseX':False, 'reverseT':False,\n", 992 | " 'turnover':False, 'fxRate':False,\n", 993 | " 'copperGold':False, 'copperGas':False}\n", 994 | "\n", 995 | "tradeDF_3, weightDF_3 = AlgoLoop.AlgoTrade(Assets, leverReturns_Domestic, leverCumReturns_Domestic, \n", 996 | " Turnovers, FXRates, mode='ema', dt=120, up=0.50, \n", 997 | " thresholds=thrds, factorDict=factors)" 998 | ] 999 | }, 1000 | { 1001 | "cell_type": "code", 1002 | "execution_count": null, 1003 | "metadata": { 1004 | "ExecuteTime": { 1005 | "end_time": "2020-08-14T04:08:02.292394Z", 1006 | "start_time": "2020-08-14T04:08:01.680569Z" 1007 | } 1008 | }, 1009 | "outputs": [], 1010 | "source": [ 1011 | "StatisticFunc.WeightPlot(tradeDF_3, weightDF_3, '时序动量')" 1012 | ] 1013 | }, 1014 | { 1015 | "cell_type": "markdown", 1016 | "metadata": {}, 1017 | "source": [ 1018 | "### 回测表现汇总" 1019 | ] 1020 | }, 1021 | { 1022 | "cell_type": "code", 1023 | "execution_count": null, 1024 | "metadata": { 1025 | "ExecuteTime": { 1026 | "end_time": "2020-08-14T04:08:02.330807Z", 1027 | "start_time": "2020-08-14T04:08:02.294670Z" 1028 | } 1029 | }, 1030 | "outputs": [], 1031 | "source": [ 1032 | "smryDF_3 = StatisticFunc.summaryDF(tradeDF_3)\n", 1033 | "pfmcDF_3 = StatisticFunc.performanceDF(smryDF_3, tradeDF_3, name='时序动量')" 1034 | ] 1035 | }, 1036 | { 1037 | "cell_type": "code", 1038 | "execution_count": null, 1039 | "metadata": { 1040 | "ExecuteTime": { 1041 | "end_time": "2020-08-14T04:08:02.343797Z", 1042 | "start_time": "2020-08-14T04:08:02.332960Z" 1043 | } 1044 | }, 1045 | "outputs": [], 1046 | "source": [ 1047 | "smryDF_3" 1048 | ] 1049 | }, 1050 | { 1051 | "cell_type": "code", 1052 | "execution_count": null, 1053 | "metadata": { 1054 | "ExecuteTime": { 1055 | "end_time": "2020-08-14T04:08:02.355094Z", 1056 | "start_time": "2020-08-14T04:08:02.345825Z" 1057 | } 1058 | }, 1059 | "outputs": [], 1060 | "source": [ 1061 | "pfmcDF_3" 1062 | ] 1063 | }, 1064 | { 1065 | "cell_type": "markdown", 1066 | "metadata": {}, 1067 | "source": [ 1068 | "### 收益率贡献度" 1069 | ] 1070 | }, 1071 | { 1072 | "cell_type": "code", 1073 | "execution_count": null, 1074 | "metadata": { 1075 | "ExecuteTime": { 1076 | "end_time": "2020-08-14T04:08:02.382473Z", 1077 | "start_time": "2020-08-14T04:08:02.357314Z" 1078 | }, 1079 | "scrolled": true 1080 | }, 1081 | "outputs": [], 1082 | "source": [ 1083 | "annualContrb_3 = StatisticFunc.AnnualContribution(tradeDF_3)" 1084 | ] 1085 | }, 1086 | { 1087 | "cell_type": "code", 1088 | "execution_count": null, 1089 | "metadata": { 1090 | "ExecuteTime": { 1091 | "end_time": "2020-08-14T04:08:04.719772Z", 1092 | "start_time": "2020-08-14T04:08:02.384538Z" 1093 | } 1094 | }, 1095 | "outputs": [], 1096 | "source": [ 1097 | "StatisticFunc.BarPlot(annualContrb_3, '时序动量')" 1098 | ] 1099 | }, 1100 | { 1101 | "cell_type": "markdown", 1102 | "metadata": {}, 1103 | "source": [ 1104 | "### 投资组合净值曲线" 1105 | ] 1106 | }, 1107 | { 1108 | "cell_type": "code", 1109 | "execution_count": null, 1110 | "metadata": { 1111 | "ExecuteTime": { 1112 | "end_time": "2020-08-14T04:08:05.045672Z", 1113 | "start_time": "2020-08-14T04:08:04.721913Z" 1114 | }, 1115 | "scrolled": false 1116 | }, 1117 | "outputs": [], 1118 | "source": [ 1119 | "fig = plt.figure(figsize=(16, 8))\n", 1120 | "\n", 1121 | "plt.plot(tradeDF_3.index, tradeDF_3['投资组合净值']/10000, label='时序动量')\n", 1122 | " \n", 1123 | "# 基准参考\n", 1124 | "plt.plot(tradeDF.index, tradeDF['投资组合净值']/10000, ls='--', label='基准组合') \n", 1125 | "plt.plot(cumReturns.index, cumReturns['中证500'], lw=0.8, label='中证500')\n", 1126 | "plt.plot(cumReturns.index, cumReturns['标普500'], lw=0.8, label='标普500')\n", 1127 | "plt.plot(cumReturns.index, cumReturns['10年国债'], lw=0.8, label='10年国债')\n", 1128 | "\n", 1129 | "plt.xlabel('时间')\n", 1130 | "plt.ylabel('净值')\n", 1131 | "plt.ylim(0.0, 3.0)\n", 1132 | "plt.legend(loc='upper left')\n", 1133 | "plt.title('净值曲线(时序动量)')\n", 1134 | "plt.savefig('Pics/净值曲线(时序动量)D.png')" 1135 | ] 1136 | }, 1137 | { 1138 | "cell_type": "markdown", 1139 | "metadata": {}, 1140 | "source": [ 1141 | "## 汇率因子" 1142 | ] 1143 | }, 1144 | { 1145 | "cell_type": "markdown", 1146 | "metadata": {}, 1147 | "source": [ 1148 | "### 程序运行" 1149 | ] 1150 | }, 1151 | { 1152 | "cell_type": "code", 1153 | "execution_count": null, 1154 | "metadata": { 1155 | "ExecuteTime": { 1156 | "end_time": "2020-08-14T04:08:05.050433Z", 1157 | "start_time": "2020-08-14T04:08:05.047693Z" 1158 | } 1159 | }, 1160 | "outputs": [], 1161 | "source": [ 1162 | "# thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 1163 | "# factors = {'momentumX':False, 'momentumT':False, \n", 1164 | "# 'reverseX':False, 'reverseT':False,\n", 1165 | "# 'turnover':False, 'fxRate':True,\n", 1166 | "# 'copperGold':True, 'copperGas':False}\n", 1167 | "\n", 1168 | "# tradeDF_4, weightDF_4 = AlgoLoop.AlgoTrade(Assets, leverReturns, leverCumReturns, \n", 1169 | "# Turnovers, FXRates, mode='ema', dt=120, up=0.50, \n", 1170 | "# thresholds=thrds, factorDict=factors)" 1171 | ] 1172 | }, 1173 | { 1174 | "cell_type": "code", 1175 | "execution_count": null, 1176 | "metadata": { 1177 | "ExecuteTime": { 1178 | "end_time": "2020-08-14T04:08:05.057936Z", 1179 | "start_time": "2020-08-14T04:08:05.052981Z" 1180 | } 1181 | }, 1182 | "outputs": [], 1183 | "source": [ 1184 | "# StatisticFunc.WeightPlot(tradeDF_4, weightDF_4, '汇率因子')" 1185 | ] 1186 | }, 1187 | { 1188 | "cell_type": "markdown", 1189 | "metadata": {}, 1190 | "source": [ 1191 | "### 回测表现汇总" 1192 | ] 1193 | }, 1194 | { 1195 | "cell_type": "code", 1196 | "execution_count": null, 1197 | "metadata": { 1198 | "ExecuteTime": { 1199 | "end_time": "2020-08-14T04:08:05.062466Z", 1200 | "start_time": "2020-08-14T04:08:05.060078Z" 1201 | } 1202 | }, 1203 | "outputs": [], 1204 | "source": [ 1205 | "# smryDF_4 = StatisticFunc.summaryDF(tradeDF_4)\n", 1206 | "# pfmcDF_4 = StatisticFunc.performanceDF(smryDF_4, tradeDF_4, name='汇率因子')" 1207 | ] 1208 | }, 1209 | { 1210 | "cell_type": "code", 1211 | "execution_count": null, 1212 | "metadata": { 1213 | "ExecuteTime": { 1214 | "end_time": "2020-08-14T04:08:05.066386Z", 1215 | "start_time": "2020-08-14T04:08:05.064215Z" 1216 | } 1217 | }, 1218 | "outputs": [], 1219 | "source": [ 1220 | "# smryDF_4" 1221 | ] 1222 | }, 1223 | { 1224 | "cell_type": "code", 1225 | "execution_count": null, 1226 | "metadata": { 1227 | "ExecuteTime": { 1228 | "end_time": "2020-08-14T04:08:05.070136Z", 1229 | "start_time": "2020-08-14T04:08:05.068139Z" 1230 | } 1231 | }, 1232 | "outputs": [], 1233 | "source": [ 1234 | "# pfmcDF_4" 1235 | ] 1236 | }, 1237 | { 1238 | "cell_type": "markdown", 1239 | "metadata": {}, 1240 | "source": [ 1241 | "### 收益率贡献度" 1242 | ] 1243 | }, 1244 | { 1245 | "cell_type": "code", 1246 | "execution_count": null, 1247 | "metadata": { 1248 | "ExecuteTime": { 1249 | "end_time": "2020-08-14T04:08:05.074095Z", 1250 | "start_time": "2020-08-14T04:08:05.071993Z" 1251 | }, 1252 | "scrolled": true 1253 | }, 1254 | "outputs": [], 1255 | "source": [ 1256 | "# annualContrb_4 = StatisticFunc.AnnualContribution(tradeDF_4)" 1257 | ] 1258 | }, 1259 | { 1260 | "cell_type": "code", 1261 | "execution_count": null, 1262 | "metadata": { 1263 | "ExecuteTime": { 1264 | "end_time": "2020-08-14T04:08:05.077826Z", 1265 | "start_time": "2020-08-14T04:08:05.075921Z" 1266 | } 1267 | }, 1268 | "outputs": [], 1269 | "source": [ 1270 | "# StatisticFunc.BarPlot(annualContrb_4, '汇率因子')" 1271 | ] 1272 | }, 1273 | { 1274 | "cell_type": "markdown", 1275 | "metadata": {}, 1276 | "source": [ 1277 | "### 投资组合净值曲线" 1278 | ] 1279 | }, 1280 | { 1281 | "cell_type": "code", 1282 | "execution_count": null, 1283 | "metadata": { 1284 | "ExecuteTime": { 1285 | "end_time": "2020-08-14T04:08:05.081837Z", 1286 | "start_time": "2020-08-14T04:08:05.079674Z" 1287 | }, 1288 | "scrolled": false 1289 | }, 1290 | "outputs": [], 1291 | "source": [ 1292 | "# fig = plt.figure(figsize=(16, 8))\n", 1293 | "\n", 1294 | "# plt.plot(tradeDF_4.index, tradeDF_4['投资组合净值']/10000, label='汇率因子')\n", 1295 | " \n", 1296 | " \n", 1297 | "# # 基准参考\n", 1298 | "# plt.plot(tradeDF.index, tradeDF['投资组合净值']/10000, ls='--', label='基准组合') \n", 1299 | "# plt.plot(cumReturns.index, cumReturns['中证500'], lw=0.8, label='中证500')\n", 1300 | "# plt.plot(cumReturns.index, cumReturns['标普500'], lw=0.8, label='标普500')\n", 1301 | "# plt.plot(cumReturns.index, cumReturns['10年国债'], lw=0.8, label='10年国债')\n", 1302 | "\n", 1303 | "# plt.xlabel('时间')\n", 1304 | "# plt.ylabel('净值')\n", 1305 | "# plt.ylim(0.0, 3.0)\n", 1306 | "# plt.legend(loc='upper left')\n", 1307 | "# plt.title('净值曲线(汇率因子)')\n", 1308 | "# plt.savefig('Pics/净值曲线(汇率因子).png')" 1309 | ] 1310 | }, 1311 | { 1312 | "cell_type": "markdown", 1313 | "metadata": {}, 1314 | "source": [ 1315 | "## 铜金" 1316 | ] 1317 | }, 1318 | { 1319 | "cell_type": "markdown", 1320 | "metadata": {}, 1321 | "source": [ 1322 | "### 程序运行" 1323 | ] 1324 | }, 1325 | { 1326 | "cell_type": "code", 1327 | "execution_count": null, 1328 | "metadata": { 1329 | "ExecuteTime": { 1330 | "end_time": "2020-08-14T04:09:24.187828Z", 1331 | "start_time": "2020-08-14T04:08:05.083718Z" 1332 | } 1333 | }, 1334 | "outputs": [], 1335 | "source": [ 1336 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 1337 | "factors = {'momentumX':False, 'momentumT':False, \n", 1338 | " 'reverseX':False, 'reverseT':False,\n", 1339 | " 'turnover':False, 'fxRate':False,\n", 1340 | " 'copperGold':True, 'copperGas':False}\n", 1341 | "\n", 1342 | "tradeDF_5, weightDF_5 = AlgoLoop.AlgoTrade(Assets, leverReturns_Domestic, leverCumReturns_Domestic, \n", 1343 | " Turnovers, FXRates, mode='ema', dt=120, up=0.50, thresholds=thrds, factorDict=factors)" 1344 | ] 1345 | }, 1346 | { 1347 | "cell_type": "code", 1348 | "execution_count": null, 1349 | "metadata": { 1350 | "ExecuteTime": { 1351 | "end_time": "2020-08-14T04:09:24.797495Z", 1352 | "start_time": "2020-08-14T04:09:24.190150Z" 1353 | } 1354 | }, 1355 | "outputs": [], 1356 | "source": [ 1357 | "StatisticFunc.WeightPlot(tradeDF_5, weightDF_5, '铜金比')" 1358 | ] 1359 | }, 1360 | { 1361 | "cell_type": "markdown", 1362 | "metadata": {}, 1363 | "source": [ 1364 | "### 回测表现汇总" 1365 | ] 1366 | }, 1367 | { 1368 | "cell_type": "code", 1369 | "execution_count": null, 1370 | "metadata": { 1371 | "ExecuteTime": { 1372 | "end_time": "2020-08-14T04:09:24.835597Z", 1373 | "start_time": "2020-08-14T04:09:24.799775Z" 1374 | } 1375 | }, 1376 | "outputs": [], 1377 | "source": [ 1378 | "smryDF_5 = StatisticFunc.summaryDF(tradeDF_5)\n", 1379 | "pfmcDF_5 = StatisticFunc.performanceDF(smryDF_5, tradeDF_5, name='铜金比')" 1380 | ] 1381 | }, 1382 | { 1383 | "cell_type": "code", 1384 | "execution_count": null, 1385 | "metadata": { 1386 | "ExecuteTime": { 1387 | "end_time": "2020-08-14T04:09:24.848386Z", 1388 | "start_time": "2020-08-14T04:09:24.837530Z" 1389 | } 1390 | }, 1391 | "outputs": [], 1392 | "source": [ 1393 | "smryDF_5" 1394 | ] 1395 | }, 1396 | { 1397 | "cell_type": "code", 1398 | "execution_count": null, 1399 | "metadata": { 1400 | "ExecuteTime": { 1401 | "end_time": "2020-08-14T04:09:24.860588Z", 1402 | "start_time": "2020-08-14T04:09:24.850716Z" 1403 | } 1404 | }, 1405 | "outputs": [], 1406 | "source": [ 1407 | "pfmcDF_5" 1408 | ] 1409 | }, 1410 | { 1411 | "cell_type": "markdown", 1412 | "metadata": {}, 1413 | "source": [ 1414 | "### 收益率贡献度" 1415 | ] 1416 | }, 1417 | { 1418 | "cell_type": "code", 1419 | "execution_count": null, 1420 | "metadata": { 1421 | "ExecuteTime": { 1422 | "end_time": "2020-08-14T04:09:24.888706Z", 1423 | "start_time": "2020-08-14T04:09:24.862814Z" 1424 | }, 1425 | "scrolled": true 1426 | }, 1427 | "outputs": [], 1428 | "source": [ 1429 | "annualContrb_5 = StatisticFunc.AnnualContribution(tradeDF_5)" 1430 | ] 1431 | }, 1432 | { 1433 | "cell_type": "code", 1434 | "execution_count": null, 1435 | "metadata": { 1436 | "ExecuteTime": { 1437 | "end_time": "2020-08-14T04:09:27.235585Z", 1438 | "start_time": "2020-08-14T04:09:24.890490Z" 1439 | } 1440 | }, 1441 | "outputs": [], 1442 | "source": [ 1443 | "StatisticFunc.BarPlot(annualContrb_5, '铜金比')" 1444 | ] 1445 | }, 1446 | { 1447 | "cell_type": "markdown", 1448 | "metadata": {}, 1449 | "source": [ 1450 | "### 投资组合净值曲线" 1451 | ] 1452 | }, 1453 | { 1454 | "cell_type": "code", 1455 | "execution_count": null, 1456 | "metadata": { 1457 | "ExecuteTime": { 1458 | "end_time": "2020-08-14T04:09:27.562572Z", 1459 | "start_time": "2020-08-14T04:09:27.238039Z" 1460 | }, 1461 | "scrolled": false 1462 | }, 1463 | "outputs": [], 1464 | "source": [ 1465 | "fig = plt.figure(figsize=(16, 8))\n", 1466 | "\n", 1467 | "plt.plot(tradeDF_5.index, tradeDF_5['投资组合净值']/10000, label='铜金比')\n", 1468 | " \n", 1469 | "# 基准参考\n", 1470 | "plt.plot(tradeDF.index, tradeDF['投资组合净值']/10000, ls='--', label='基准组合') \n", 1471 | "plt.plot(cumReturns.index, cumReturns['中证500'], lw=0.8, label='中证500')\n", 1472 | "plt.plot(cumReturns.index, cumReturns['标普500'], lw=0.8, label='标普500')\n", 1473 | "plt.plot(cumReturns.index, cumReturns['10年国债'], lw=0.8, label='10年国债')\n", 1474 | "\n", 1475 | "plt.xlabel('时间')\n", 1476 | "plt.ylabel('净值')\n", 1477 | "plt.ylim(0.0, 3.0)\n", 1478 | "plt.legend(loc='upper left')\n", 1479 | "plt.title('净值曲线(铜金比)')\n", 1480 | "plt.savefig('Pics/净值曲线(铜金比).png')" 1481 | ] 1482 | }, 1483 | { 1484 | "cell_type": "markdown", 1485 | "metadata": {}, 1486 | "source": [ 1487 | "## 铜油" 1488 | ] 1489 | }, 1490 | { 1491 | "cell_type": "markdown", 1492 | "metadata": {}, 1493 | "source": [ 1494 | "### 程序运行" 1495 | ] 1496 | }, 1497 | { 1498 | "cell_type": "code", 1499 | "execution_count": null, 1500 | "metadata": { 1501 | "ExecuteTime": { 1502 | "end_time": "2020-08-14T04:10:47.171649Z", 1503 | "start_time": "2020-08-14T04:09:27.564811Z" 1504 | } 1505 | }, 1506 | "outputs": [], 1507 | "source": [ 1508 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 1509 | "factors = {'momentumX':False, 'momentumT':False, \n", 1510 | " 'reverseX':False, 'reverseT':False,\n", 1511 | " 'turnover':False, 'fxRate':False,\n", 1512 | " 'copperGold':False, 'copperGas':True}\n", 1513 | "\n", 1514 | "tradeDF_6, weightDF_6 = AlgoLoop.AlgoTrade(Assets, leverReturns_Domestic, leverCumReturns_Domestic, \n", 1515 | " Turnovers, FXRates, mode='ema', dt=120, up=0.50, \n", 1516 | " thresholds=thrds, factorDict=factors)" 1517 | ] 1518 | }, 1519 | { 1520 | "cell_type": "code", 1521 | "execution_count": null, 1522 | "metadata": { 1523 | "ExecuteTime": { 1524 | "end_time": "2020-08-14T04:10:47.780622Z", 1525 | "start_time": "2020-08-14T04:10:47.174148Z" 1526 | } 1527 | }, 1528 | "outputs": [], 1529 | "source": [ 1530 | "StatisticFunc.WeightPlot(tradeDF_6, weightDF_6, '铜油比')" 1531 | ] 1532 | }, 1533 | { 1534 | "cell_type": "markdown", 1535 | "metadata": {}, 1536 | "source": [ 1537 | "### 回测表现汇总" 1538 | ] 1539 | }, 1540 | { 1541 | "cell_type": "code", 1542 | "execution_count": null, 1543 | "metadata": { 1544 | "ExecuteTime": { 1545 | "end_time": "2020-08-14T04:10:47.817977Z", 1546 | "start_time": "2020-08-14T04:10:47.782835Z" 1547 | } 1548 | }, 1549 | "outputs": [], 1550 | "source": [ 1551 | "smryDF_6 = StatisticFunc.summaryDF(tradeDF_6)\n", 1552 | "pfmcDF_6 = StatisticFunc.performanceDF(smryDF_6, tradeDF_6, name='铜油比')" 1553 | ] 1554 | }, 1555 | { 1556 | "cell_type": "code", 1557 | "execution_count": null, 1558 | "metadata": { 1559 | "ExecuteTime": { 1560 | "end_time": "2020-08-14T04:10:47.829652Z", 1561 | "start_time": "2020-08-14T04:10:47.819930Z" 1562 | } 1563 | }, 1564 | "outputs": [], 1565 | "source": [ 1566 | "smryDF_6" 1567 | ] 1568 | }, 1569 | { 1570 | "cell_type": "code", 1571 | "execution_count": null, 1572 | "metadata": { 1573 | "ExecuteTime": { 1574 | "end_time": "2020-08-14T04:10:47.839143Z", 1575 | "start_time": "2020-08-14T04:10:47.831602Z" 1576 | } 1577 | }, 1578 | "outputs": [], 1579 | "source": [ 1580 | "pfmcDF_6" 1581 | ] 1582 | }, 1583 | { 1584 | "cell_type": "markdown", 1585 | "metadata": {}, 1586 | "source": [ 1587 | "### 收益率贡献度" 1588 | ] 1589 | }, 1590 | { 1591 | "cell_type": "code", 1592 | "execution_count": null, 1593 | "metadata": { 1594 | "ExecuteTime": { 1595 | "end_time": "2020-08-14T04:10:47.859357Z", 1596 | "start_time": "2020-08-14T04:10:47.841293Z" 1597 | }, 1598 | "scrolled": true 1599 | }, 1600 | "outputs": [], 1601 | "source": [ 1602 | "annualContrb_6 = StatisticFunc.AnnualContribution(tradeDF_6)" 1603 | ] 1604 | }, 1605 | { 1606 | "cell_type": "code", 1607 | "execution_count": null, 1608 | "metadata": { 1609 | "ExecuteTime": { 1610 | "end_time": "2020-08-14T04:10:50.197549Z", 1611 | "start_time": "2020-08-14T04:10:47.860837Z" 1612 | } 1613 | }, 1614 | "outputs": [], 1615 | "source": [ 1616 | "StatisticFunc.BarPlot(annualContrb_6, '铜油比')" 1617 | ] 1618 | }, 1619 | { 1620 | "cell_type": "markdown", 1621 | "metadata": {}, 1622 | "source": [ 1623 | "### 投资组合净值曲线" 1624 | ] 1625 | }, 1626 | { 1627 | "cell_type": "code", 1628 | "execution_count": null, 1629 | "metadata": { 1630 | "ExecuteTime": { 1631 | "end_time": "2020-08-14T04:10:50.523514Z", 1632 | "start_time": "2020-08-14T04:10:50.200284Z" 1633 | }, 1634 | "scrolled": false 1635 | }, 1636 | "outputs": [], 1637 | "source": [ 1638 | "fig = plt.figure(figsize=(16, 8))\n", 1639 | "\n", 1640 | "plt.plot(tradeDF_6.index, tradeDF_6['投资组合净值']/10000, label='铜油比')\n", 1641 | "\n", 1642 | "# 基准参考\n", 1643 | "plt.plot(tradeDF.index, tradeDF['投资组合净值']/10000, ls='--', label='基准组合') \n", 1644 | "plt.plot(cumReturns.index, cumReturns['中证500'], lw=0.8, label='中证500')\n", 1645 | "plt.plot(cumReturns.index, cumReturns['标普500'], lw=0.8, label='标普500')\n", 1646 | "plt.plot(cumReturns.index, cumReturns['10年国债'], lw=0.8, label='10年国债')\n", 1647 | "\n", 1648 | "plt.xlabel('时间')\n", 1649 | "plt.ylabel('净值')\n", 1650 | "plt.ylim(0.0, 3.0)\n", 1651 | "plt.legend(loc='upper left')\n", 1652 | "plt.title('净值曲线(铜油比)')\n", 1653 | "plt.savefig('Pics/净值曲线(铜油比).png')" 1654 | ] 1655 | }, 1656 | { 1657 | "cell_type": "markdown", 1658 | "metadata": {}, 1659 | "source": [ 1660 | "## 汇总比较" 1661 | ] 1662 | }, 1663 | { 1664 | "cell_type": "code", 1665 | "execution_count": null, 1666 | "metadata": { 1667 | "ExecuteTime": { 1668 | "end_time": "2020-08-14T04:10:50.540326Z", 1669 | "start_time": "2020-08-14T04:10:50.525563Z" 1670 | } 1671 | }, 1672 | "outputs": [], 1673 | "source": [ 1674 | "pd.concat([pfmcDF, pfmcDF_1, pfmcDF_2, pfmcDF_3, pfmcDF_5, pfmcDF_6])" 1675 | ] 1676 | }, 1677 | { 1678 | "cell_type": "code", 1679 | "execution_count": null, 1680 | "metadata": {}, 1681 | "outputs": [], 1682 | "source": [] 1683 | } 1684 | ], 1685 | "metadata": { 1686 | "kernelspec": { 1687 | "display_name": "Python 3", 1688 | "language": "python", 1689 | "name": "python3" 1690 | }, 1691 | "language_info": { 1692 | "codemirror_mode": { 1693 | "name": "ipython", 1694 | "version": 3 1695 | }, 1696 | "file_extension": ".py", 1697 | "mimetype": "text/x-python", 1698 | "name": "python", 1699 | "nbconvert_exporter": "python", 1700 | "pygments_lexer": "ipython3", 1701 | "version": "3.7.7" 1702 | }, 1703 | "latex_envs": { 1704 | "LaTeX_envs_menu_present": true, 1705 | "autoclose": false, 1706 | "autocomplete": true, 1707 | "bibliofile": "biblio.bib", 1708 | "cite_by": "apalike", 1709 | "current_citInitial": 1, 1710 | "eqLabelWithNumbers": true, 1711 | "eqNumInitial": 1, 1712 | "hotkeys": { 1713 | "equation": "Ctrl-E", 1714 | "itemize": "Ctrl-I" 1715 | }, 1716 | "labels_anchors": false, 1717 | "latex_user_defs": false, 1718 | "report_style_numbering": false, 1719 | "user_envs_cfg": false 1720 | }, 1721 | "toc": { 1722 | "base_numbering": 1, 1723 | "nav_menu": {}, 1724 | "number_sections": true, 1725 | "sideBar": true, 1726 | "skip_h1_title": false, 1727 | "title_cell": "Table of Contents", 1728 | "title_sidebar": "Contents", 1729 | "toc_cell": false, 1730 | "toc_position": { 1731 | "height": "calc(100% - 180px)", 1732 | "left": "10px", 1733 | "top": "150px", 1734 | "width": "366px" 1735 | }, 1736 | "toc_section_display": true, 1737 | "toc_window_display": true 1738 | } 1739 | }, 1740 | "nbformat": 4, 1741 | "nbformat_minor": 4 1742 | } 1743 | -------------------------------------------------------------------------------- /RiskParityModel.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "ExecuteTime": { 8 | "end_time": "2020-07-16T03:21:23.803815Z", 9 | "start_time": "2020-07-16T03:21:23.125254Z" 10 | } 11 | }, 12 | "outputs": [], 13 | "source": [ 14 | "import numpy as np\n", 15 | "import pandas as pd\n", 16 | "import matplotlib\n", 17 | "import matplotlib.pyplot as plt\n", 18 | "import AlgoLoop\n", 19 | "import StatisticFunc\n", 20 | "\n", 21 | "plt.style.use('Solarize_Light2') # 绘图风格\n", 22 | "matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 字体雅黑\n", 23 | "matplotlib.rcParams['font.family'] = 'sans-serif'\n", 24 | "matplotlib.rcParams['axes.unicode_minus'] = False # 处理负号" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "# 预处理(不含外国资产,指数权重)" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": {}, 37 | "source": [ 38 | "## 提取并处理数据" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": {}, 44 | "source": [ 45 | "### 各种利率" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": null, 51 | "metadata": { 52 | "ExecuteTime": { 53 | "end_time": "2020-07-16T03:21:24.381059Z", 54 | "start_time": "2020-07-16T03:21:24.230150Z" 55 | } 56 | }, 57 | "outputs": [], 58 | "source": [ 59 | "# GC007 利率\n", 60 | "GCRates = pd.read_excel(io=\"Raw/GC007利率.xlsx\") # 读取数据\n", 61 | "GCRates = GCRates.drop([0, 1, 2], axis=0) # 删除多余行\n", 62 | "GCRates.columns = ['日期', 'GC007'] # 修改列名\n", 63 | "GCRates[\"日期\"] = pd.DatetimeIndex(GCRates[\"日期\"]) # 类型转换\n", 64 | "GCRates = GCRates.set_index(\"日期\") # 设置索引" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": null, 70 | "metadata": { 71 | "ExecuteTime": { 72 | "end_time": "2020-07-16T03:21:24.552641Z", 73 | "start_time": "2020-07-16T03:21:24.480164Z" 74 | } 75 | }, 76 | "outputs": [], 77 | "source": [ 78 | "# 10年国债收益率\n", 79 | "CNRates = pd.read_excel(io=\"Raw/中债国债到期收益率(中债)(日).xls\") # 读取数据\n", 80 | "CNRates.columns = ['日期', '十年国债收益率'] # 修改列名\n", 81 | "CNRates = CNRates.drop([0, 3870, 3871], axis=0) # 删除多余行\n", 82 | "CNRates[\"日期\"] = pd.DatetimeIndex(CNRates[\"日期\"]) # 类型转换\n", 83 | "CNRates = CNRates.set_index(\"日期\") # 设置索引" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": null, 89 | "metadata": { 90 | "ExecuteTime": { 91 | "end_time": "2020-07-16T03:21:24.963418Z", 92 | "start_time": "2020-07-16T03:21:24.764635Z" 93 | } 94 | }, 95 | "outputs": [], 96 | "source": [ 97 | "# 10年美债收益率\n", 98 | "USRates = pd.read_excel(io=\"Raw/美债收益率.xlsx\") # 读取数据\n", 99 | "USRates.columns = ['日期', '十年美债收益率'] # 修改列名\n", 100 | "USRates = USRates.drop([0, 6263, 6264], axis=0) # 删除多余行\n", 101 | "USRates[\"日期\"] = pd.DatetimeIndex(USRates[\"日期\"]) # 类型转换\n", 102 | "USRates = USRates.set_index(\"日期\") # 设置索引" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": null, 108 | "metadata": { 109 | "ExecuteTime": { 110 | "end_time": "2020-07-16T03:21:25.140960Z", 111 | "start_time": "2020-07-16T03:21:25.134314Z" 112 | } 113 | }, 114 | "outputs": [], 115 | "source": [ 116 | "# 合并利率\n", 117 | "Rates = GCRates.merge(CNRates, how='left', left_index=True, right_index=True)\n", 118 | "Rates = Rates.merge(USRates, how='left', left_index=True, right_index=True)" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": null, 124 | "metadata": { 125 | "ExecuteTime": { 126 | "end_time": "2020-07-16T03:21:25.461542Z", 127 | "start_time": "2020-07-16T03:21:25.446923Z" 128 | } 129 | }, 130 | "outputs": [], 131 | "source": [ 132 | "Rates" 133 | ] 134 | }, 135 | { 136 | "cell_type": "markdown", 137 | "metadata": {}, 138 | "source": [ 139 | "### 权益类资产换手率" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": null, 145 | "metadata": { 146 | "ExecuteTime": { 147 | "end_time": "2020-07-16T03:21:26.740174Z", 148 | "start_time": "2020-07-16T03:21:26.612375Z" 149 | } 150 | }, 151 | "outputs": [], 152 | "source": [ 153 | "Turnovers = pd.read_excel(io=\"Raw/资产换手率.xlsx\") # 读取数据\n", 154 | "Turnovers = Turnovers.drop([0], axis=0) # 删除多余行\n", 155 | "Turnovers[\"日期\"] = pd.DatetimeIndex(Turnovers[\"日期\"]) # 类型转换\n", 156 | "Turnovers = Turnovers.set_index(\"日期\") # 设置索引" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": null, 162 | "metadata": { 163 | "ExecuteTime": { 164 | "end_time": "2020-07-16T03:21:26.851031Z", 165 | "start_time": "2020-07-16T03:21:26.847280Z" 166 | } 167 | }, 168 | "outputs": [], 169 | "source": [ 170 | "# 时间对齐\n", 171 | "Turnovers = Turnovers.loc[Rates.index, :]" 172 | ] 173 | }, 174 | { 175 | "cell_type": "markdown", 176 | "metadata": {}, 177 | "source": [ 178 | "### 美元汇率" 179 | ] 180 | }, 181 | { 182 | "cell_type": "code", 183 | "execution_count": null, 184 | "metadata": { 185 | "ExecuteTime": { 186 | "end_time": "2020-07-16T03:21:27.523381Z", 187 | "start_time": "2020-07-16T03:21:27.371607Z" 188 | } 189 | }, 190 | "outputs": [], 191 | "source": [ 192 | "FXRates = pd.read_excel(io=\"Raw/美元汇率.xlsx\")\n", 193 | "FXRates = FXRates.drop([0, 1, 2], axis=0)\n", 194 | "FXRates.columns = ['日期', '美元汇率'] \n", 195 | "FXRates[\"日期\"] = pd.DatetimeIndex(FXRates[\"日期\"])\n", 196 | "FXRates = FXRates.set_index(\"日期\")" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": null, 202 | "metadata": { 203 | "ExecuteTime": { 204 | "end_time": "2020-07-16T03:21:27.744532Z", 205 | "start_time": "2020-07-16T03:21:27.735529Z" 206 | }, 207 | "scrolled": false 208 | }, 209 | "outputs": [], 210 | "source": [ 211 | "FXRates" 212 | ] 213 | }, 214 | { 215 | "cell_type": "markdown", 216 | "metadata": {}, 217 | "source": [ 218 | "### 各资产收盘价" 219 | ] 220 | }, 221 | { 222 | "cell_type": "code", 223 | "execution_count": null, 224 | "metadata": { 225 | "ExecuteTime": { 226 | "end_time": "2020-07-16T03:21:29.466204Z", 227 | "start_time": "2020-07-16T03:21:29.187002Z" 228 | } 229 | }, 230 | "outputs": [], 231 | "source": [ 232 | "Assets = pd.read_excel(io=\"Raw/资产收盘价.xlsx\")\n", 233 | "Assets = Assets.drop([0], axis=0) # 删除多余行\n", 234 | "Assets[\"日期\"] = pd.DatetimeIndex(Assets[\"日期\"]) # 类型转换\n", 235 | "Assets = Assets.set_index(\"日期\") # 设置索引" 236 | ] 237 | }, 238 | { 239 | "cell_type": "code", 240 | "execution_count": null, 241 | "metadata": { 242 | "ExecuteTime": { 243 | "end_time": "2020-07-16T03:21:29.600704Z", 244 | "start_time": "2020-07-16T03:21:29.596951Z" 245 | }, 246 | "scrolled": false 247 | }, 248 | "outputs": [], 249 | "source": [ 250 | "# 时间对齐\n", 251 | "Assets = Assets.loc[Rates.index, :]" 252 | ] 253 | }, 254 | { 255 | "cell_type": "markdown", 256 | "metadata": {}, 257 | "source": [ 258 | "### 十年国债价格指数" 259 | ] 260 | }, 261 | { 262 | "cell_type": "code", 263 | "execution_count": null, 264 | "metadata": { 265 | "ExecuteTime": { 266 | "end_time": "2020-07-16T03:21:30.642773Z", 267 | "start_time": "2020-07-16T03:21:30.623846Z" 268 | } 269 | }, 270 | "outputs": [], 271 | "source": [ 272 | "HoldPeriod = (Assets.index - Assets.index[0]).days\n", 273 | "\n", 274 | "# 计算十年国债\n", 275 | "Assets['10年国债'] = 100 - (Rates['十年国债收益率'] - 3.0) * 8.2 + 3.0 * HoldPeriod / 365.0\n", 276 | "Assets['10年国债'] = Assets['10年国债'].fillna(method='ffill')\n", 277 | "\n", 278 | "#计算十年美债\n", 279 | "Assets['10年美债'] = 100 - (Rates['十年美债收益率'] - 3.0) * 8.2 + 3.0 * HoldPeriod / 365.0\n", 280 | "Assets['10年美债'] = Assets['10年美债'].fillna(method='ffill')" 281 | ] 282 | }, 283 | { 284 | "cell_type": "code", 285 | "execution_count": null, 286 | "metadata": { 287 | "ExecuteTime": { 288 | "end_time": "2020-07-16T03:21:31.660495Z", 289 | "start_time": "2020-07-16T03:21:31.641110Z" 290 | } 291 | }, 292 | "outputs": [], 293 | "source": [ 294 | "# 替换上证十年国债指数\n", 295 | "Assets = Assets.drop('上证10年国债', axis=1)\n", 296 | "Assets" 297 | ] 298 | }, 299 | { 300 | "cell_type": "markdown", 301 | "metadata": {}, 302 | "source": [ 303 | "## 计算各资产收益率" 304 | ] 305 | }, 306 | { 307 | "cell_type": "markdown", 308 | "metadata": {}, 309 | "source": [ 310 | "### 日内损益" 311 | ] 312 | }, 313 | { 314 | "cell_type": "code", 315 | "execution_count": null, 316 | "metadata": { 317 | "ExecuteTime": { 318 | "end_time": "2020-07-16T03:21:41.667064Z", 319 | "start_time": "2020-07-16T03:21:41.653187Z" 320 | } 321 | }, 322 | "outputs": [], 323 | "source": [ 324 | "Returns = Assets.pct_change(axis=0)\n", 325 | "Returns = Returns.dropna(axis=0, how='all') # 删除无数据日" 326 | ] 327 | }, 328 | { 329 | "cell_type": "code", 330 | "execution_count": null, 331 | "metadata": { 332 | "ExecuteTime": { 333 | "end_time": "2020-07-16T03:22:33.076321Z", 334 | "start_time": "2020-07-16T03:22:33.071529Z" 335 | } 336 | }, 337 | "outputs": [], 338 | "source": [ 339 | "# 去除国外资产\n", 340 | "Returns = Returns.drop('标普500', axis=1)\n", 341 | "Returns = Returns.drop('10年美债', axis=1)" 342 | ] 343 | }, 344 | { 345 | "cell_type": "markdown", 346 | "metadata": {}, 347 | "source": [ 348 | "### 累计损益" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "execution_count": null, 354 | "metadata": { 355 | "ExecuteTime": { 356 | "end_time": "2020-07-16T03:22:33.793351Z", 357 | "start_time": "2020-07-16T03:22:33.785947Z" 358 | } 359 | }, 360 | "outputs": [], 361 | "source": [ 362 | "cumReturns = (1.0 + Returns)\n", 363 | "cumReturns = cumReturns.fillna(1.0) # 填充空值\n", 364 | "cumReturns = cumReturns.cumprod() # 计算各资产累计收益率" 365 | ] 366 | }, 367 | { 368 | "cell_type": "code", 369 | "execution_count": null, 370 | "metadata": { 371 | "ExecuteTime": { 372 | "end_time": "2020-07-16T03:22:34.543230Z", 373 | "start_time": "2020-07-16T03:22:34.220527Z" 374 | } 375 | }, 376 | "outputs": [], 377 | "source": [ 378 | "cumReturns.plot(figsize=(16, 6))" 379 | ] 380 | }, 381 | { 382 | "cell_type": "markdown", 383 | "metadata": {}, 384 | "source": [ 385 | "### 杠杆调整后的债券净值" 386 | ] 387 | }, 388 | { 389 | "cell_type": "code", 390 | "execution_count": null, 391 | "metadata": { 392 | "ExecuteTime": { 393 | "end_time": "2020-07-16T03:22:36.256745Z", 394 | "start_time": "2020-07-16T03:22:36.252919Z" 395 | } 396 | }, 397 | "outputs": [], 398 | "source": [ 399 | "lever = 2.0 # 杠杆\n", 400 | "leverReturns = Returns.copy() # 创建副本 \n", 401 | "leverCumReturns = cumReturns.copy() " 402 | ] 403 | }, 404 | { 405 | "cell_type": "code", 406 | "execution_count": null, 407 | "metadata": { 408 | "ExecuteTime": { 409 | "end_time": "2020-07-16T03:22:36.849185Z", 410 | "start_time": "2020-07-16T03:22:36.832543Z" 411 | } 412 | }, 413 | "outputs": [], 414 | "source": [ 415 | "# 更新杠杆调整后的债券净值\n", 416 | "leverReturns['10年国债'] = Returns['10年国债'] * (1.0 + lever) - Rates.loc[Returns.index, 'GC007'] * lever / (365.0 * 100)\n", 417 | "leverReturns['信用债3-5AAA'] = Returns['信用债3-5AAA'] * (1.0 + lever) - Rates.loc[Returns.index, 'GC007'] * lever / (365.0 * 100)\n", 418 | "\n", 419 | "# 更新累计净值\n", 420 | "leverCumReturns = (1.0 + leverReturns)\n", 421 | "leverCumReturns = leverCumReturns.fillna(1.0) # 填充空值\n", 422 | "leverCumReturns = leverCumReturns.cumprod() # 计算各资产累计收益率" 423 | ] 424 | }, 425 | { 426 | "cell_type": "code", 427 | "execution_count": null, 428 | "metadata": { 429 | "ExecuteTime": { 430 | "end_time": "2020-07-16T03:22:37.548224Z", 431 | "start_time": "2020-07-16T03:22:37.271774Z" 432 | }, 433 | "scrolled": false 434 | }, 435 | "outputs": [], 436 | "source": [ 437 | "leverCumReturns.plot(figsize=(16, 6))" 438 | ] 439 | }, 440 | { 441 | "cell_type": "markdown", 442 | "metadata": {}, 443 | "source": [ 444 | "# 风险平价 (指数权重EMA)\n", 445 | "\n", 446 | "**资产明细**\n", 447 | "- 沪深300指数\n", 448 | "- 中证500指数\n", 449 | "- 三年期3A信用债全价指数\n", 450 | "- 十年期国债全价指数(自制)\n", 451 | "- COMEX铜\n", 452 | "- COMEX黄金\n", 453 | "- NYMEX原油\n", 454 | "- 铁矿石期货\n", 455 | "\n", 456 | "回溯时间:2008年初-至今\n", 457 | "\n", 458 | "买卖单笔手续费:千1" 459 | ] 460 | }, 461 | { 462 | "cell_type": "markdown", 463 | "metadata": {}, 464 | "source": [ 465 | "## 程序运行" 466 | ] 467 | }, 468 | { 469 | "cell_type": "code", 470 | "execution_count": null, 471 | "metadata": { 472 | "ExecuteTime": { 473 | "end_time": "2020-07-16T03:28:32.076258Z", 474 | "start_time": "2020-07-16T03:22:39.955349Z" 475 | }, 476 | "scrolled": false 477 | }, 478 | "outputs": [], 479 | "source": [ 480 | "# 运行\n", 481 | "timeWindow = [20, 60, 120, 180, 240] # 调仓周期\n", 482 | "\n", 483 | "NetValueDF_ema = pd.DataFrame(index=Returns.index)\n", 484 | "DailyPnlDF_ema = pd.DataFrame(index=Returns.index) \n", 485 | "DrawDownDF_ema = pd.DataFrame(index=Returns.index)\n", 486 | "\n", 487 | "for dtime in timeWindow:\n", 488 | " tradeDF, weightDF = AlgoLoop.AlgoTrade(Assets, Returns, cumReturns, Turnovers, mode='ema', dt=dtime)\n", 489 | " StatisticFunc.WeightPlot(tradeDF, weightDF, 'EMA'+str(dtime))\n", 490 | " \n", 491 | " NetValueDF_ema[str(dtime)+'组合净值'] = tradeDF['投资组合净值'] / 10000 \n", 492 | " DailyPnlDF_ema[str(dtime)+'组合日收益率'] = tradeDF['投资组合净值'] / tradeDF['投资组合净值'].shift(1) - 1.0\n", 493 | " DrawDownDF_ema[str(dtime)+'最大回撤'] = tradeDF['最大回撤'] " 494 | ] 495 | }, 496 | { 497 | "cell_type": "markdown", 498 | "metadata": {}, 499 | "source": [ 500 | "## 回测表现汇总" 501 | ] 502 | }, 503 | { 504 | "cell_type": "code", 505 | "execution_count": null, 506 | "metadata": { 507 | "ExecuteTime": { 508 | "end_time": "2020-07-16T03:28:32.095224Z", 509 | "start_time": "2020-07-16T03:28:32.078718Z" 510 | } 511 | }, 512 | "outputs": [], 513 | "source": [ 514 | "# 汇总\n", 515 | "summaryDF_ema = pd.DataFrame(index=['每月调仓', '每季度调仓', '每半年调仓', \n", 516 | " '每三季度调仓', '每年调仓'])\n", 517 | "\n", 518 | "summaryDF_ema[\"年平均收益率\"] = DailyPnlDF_ema.mean(axis=0).values * 250\n", 519 | "summaryDF_ema[\"年平均标准差\"] = DailyPnlDF_ema.std(axis=0).values * np.sqrt(250)\n", 520 | "summaryDF_ema[\"无基准夏普比率\"] = summaryDF_ema[\"年平均收益率\"] / summaryDF_ema[\"年平均标准差\"]\n", 521 | "summaryDF_ema[\"最大回撤\"] = DrawDownDF_ema.min(axis=0).values\n", 522 | "summaryDF_ema" 523 | ] 524 | }, 525 | { 526 | "cell_type": "markdown", 527 | "metadata": {}, 528 | "source": [ 529 | "## 各投资组合净值曲线" 530 | ] 531 | }, 532 | { 533 | "cell_type": "code", 534 | "execution_count": null, 535 | "metadata": { 536 | "ExecuteTime": { 537 | "end_time": "2020-07-16T03:31:18.108627Z", 538 | "start_time": "2020-07-16T03:31:17.851224Z" 539 | }, 540 | "scrolled": false 541 | }, 542 | "outputs": [], 543 | "source": [ 544 | "fig = plt.figure(figsize=(16, 8))\n", 545 | "\n", 546 | "for col in NetValueDF_ema.columns:\n", 547 | " plt.plot(NetValueDF_ema.index, NetValueDF_ema[col], lw=0.8, label=col)\n", 548 | " \n", 549 | "plt.plot(cumReturns.index, cumReturns['信用债3-5AAA'], lw=3.0, label='信用债3-5AAA')\n", 550 | "\n", 551 | "plt.xlabel('时间')\n", 552 | "plt.ylabel('净值')\n", 553 | "plt.ylim(0.0, 3.0)\n", 554 | "plt.legend(loc='upper left')\n", 555 | "plt.title('净值曲线(指数平均)')\n", 556 | "plt.show()" 557 | ] 558 | }, 559 | { 560 | "cell_type": "markdown", 561 | "metadata": {}, 562 | "source": [ 563 | "# 风险平价 + 杠杆策略(指数权重EMA)" 564 | ] 565 | }, 566 | { 567 | "cell_type": "markdown", 568 | "metadata": {}, 569 | "source": [ 570 | "## 程序运行" 571 | ] 572 | }, 573 | { 574 | "cell_type": "code", 575 | "execution_count": null, 576 | "metadata": { 577 | "ExecuteTime": { 578 | "end_time": "2020-07-07T02:14:40.047218Z", 579 | "start_time": "2020-07-07T02:09:01.139477Z" 580 | } 581 | }, 582 | "outputs": [], 583 | "source": [ 584 | "# 运行\n", 585 | "timeWindow = [20, 60, 120, 180, 240] # 调仓周期\n", 586 | "\n", 587 | "leverNetValueDF_ema = pd.DataFrame(index=Returns.index)\n", 588 | "leverDailyPnlDF_ema = pd.DataFrame(index=Returns.index) \n", 589 | "leverDrawDownDF_ema = pd.DataFrame(index=Returns.index)\n", 590 | "\n", 591 | "for dtime in timeWindow:\n", 592 | " tradeDF, weightDF = AlgoLoop.AlgoTrade(Assets, leverReturns, leverCumReturns, Turnovers, mode='ema', dt=dtime)\n", 593 | " StatisticFunc.WeightPlot(tradeDF, weightDF, '杠杆EMA'+str(dtime))\n", 594 | " \n", 595 | " leverNetValueDF_ema[str(dtime)+'组合净值'] = tradeDF['投资组合净值'] / 10000 \n", 596 | " leverDailyPnlDF_ema[str(dtime)+'组合日收益率'] = tradeDF['投资组合净值'] / tradeDF['投资组合净值'].shift(1) - 1.0\n", 597 | " leverDrawDownDF_ema[str(dtime)+'最大回撤'] = tradeDF['最大回撤'] " 598 | ] 599 | }, 600 | { 601 | "cell_type": "markdown", 602 | "metadata": {}, 603 | "source": [ 604 | "## 回测表现汇总" 605 | ] 606 | }, 607 | { 608 | "cell_type": "code", 609 | "execution_count": null, 610 | "metadata": { 611 | "ExecuteTime": { 612 | "end_time": "2020-07-07T02:14:40.065962Z", 613 | "start_time": "2020-07-07T02:14:40.049459Z" 614 | } 615 | }, 616 | "outputs": [], 617 | "source": [ 618 | "# 汇总\n", 619 | "leverSummaryDF_ema = pd.DataFrame(index=['每月调仓', '每季度调仓', '每半年调仓', \n", 620 | " '每三季度调仓', '每年调仓'])\n", 621 | "\n", 622 | "leverSummaryDF_ema[\"年平均收益率\"] = leverDailyPnlDF_ema.mean(axis=0).values * 250\n", 623 | "leverSummaryDF_ema[\"年平均标准差\"] = leverDailyPnlDF_ema.std(axis=0).values * np.sqrt(250)\n", 624 | "leverSummaryDF_ema[\"无基准夏普比率\"] = leverSummaryDF_ema[\"年平均收益率\"] / leverSummaryDF_ema[\"年平均标准差\"]\n", 625 | "leverSummaryDF_ema[\"最大回撤\"] = leverDrawDownDF_ema.min(axis=0).values\n", 626 | "leverSummaryDF_ema" 627 | ] 628 | }, 629 | { 630 | "cell_type": "markdown", 631 | "metadata": {}, 632 | "source": [ 633 | "## 各投资组合净值曲线" 634 | ] 635 | }, 636 | { 637 | "cell_type": "code", 638 | "execution_count": null, 639 | "metadata": { 640 | "ExecuteTime": { 641 | "end_time": "2020-07-07T02:14:40.299184Z", 642 | "start_time": "2020-07-07T02:14:40.069191Z" 643 | }, 644 | "scrolled": false 645 | }, 646 | "outputs": [], 647 | "source": [ 648 | "fig = plt.figure(figsize=(16, 8))\n", 649 | "\n", 650 | "for col in leverNetValueDF_ema.columns:\n", 651 | " plt.plot(leverNetValueDF_ema.index, leverNetValueDF_ema[col], lw=0.8, label=col)\n", 652 | " \n", 653 | "# plt.plot(cumReturns.index, cumReturns['中证500'], lw=1.5, label='中证500')\n", 654 | "plt.plot(cumReturns.index, cumReturns['信用债3-5AAA'], lw=3.0, label='信用债3-5AAA')\n", 655 | "\n", 656 | "plt.xlabel('时间')\n", 657 | "plt.ylabel('净值')\n", 658 | "plt.ylim(0.0, 5.0)\n", 659 | "plt.legend(loc='upper left')\n", 660 | "plt.title('净值曲线(杠杆,指数平均)')\n", 661 | "plt.show()" 662 | ] 663 | }, 664 | { 665 | "cell_type": "markdown", 666 | "metadata": {}, 667 | "source": [ 668 | "## 年间收益率分布" 669 | ] 670 | }, 671 | { 672 | "cell_type": "code", 673 | "execution_count": null, 674 | "metadata": { 675 | "ExecuteTime": { 676 | "end_time": "2020-06-20T09:33:11.933158Z", 677 | "start_time": "2020-06-20T09:33:09.412Z" 678 | } 679 | }, 680 | "outputs": [], 681 | "source": [ 682 | "yearReturns_ema = StatisticFunc.annualReturns(NetValueDF_ema)" 683 | ] 684 | }, 685 | { 686 | "cell_type": "code", 687 | "execution_count": null, 688 | "metadata": { 689 | "ExecuteTime": { 690 | "end_time": "2020-06-20T09:33:11.934317Z", 691 | "start_time": "2020-06-20T09:33:09.415Z" 692 | } 693 | }, 694 | "outputs": [], 695 | "source": [ 696 | "StatisticFunc.ReturnDist(yearReturns_ema, 2)" 697 | ] 698 | }, 699 | { 700 | "cell_type": "markdown", 701 | "metadata": {}, 702 | "source": [ 703 | "## 月间收益率分布" 704 | ] 705 | }, 706 | { 707 | "cell_type": "code", 708 | "execution_count": null, 709 | "metadata": { 710 | "ExecuteTime": { 711 | "end_time": "2020-06-20T09:33:11.935398Z", 712 | "start_time": "2020-06-20T09:33:09.453Z" 713 | } 714 | }, 715 | "outputs": [], 716 | "source": [ 717 | "monthlyReturns_ema = StatisticFunc.monthlyReturns(NetValueDF_ema)" 718 | ] 719 | }, 720 | { 721 | "cell_type": "code", 722 | "execution_count": null, 723 | "metadata": { 724 | "ExecuteTime": { 725 | "end_time": "2020-06-20T09:33:11.936561Z", 726 | "start_time": "2020-06-20T09:33:09.456Z" 727 | }, 728 | "scrolled": true 729 | }, 730 | "outputs": [], 731 | "source": [ 732 | "StatisticFunc.ReturnDist(monthlyReturns_ema, 2)" 733 | ] 734 | }, 735 | { 736 | "cell_type": "markdown", 737 | "metadata": {}, 738 | "source": [ 739 | "# 风险平价 + 杠杆 + 因子策略(指数权重EMA)" 740 | ] 741 | }, 742 | { 743 | "cell_type": "markdown", 744 | "metadata": {}, 745 | "source": [ 746 | "## 动量因子(横向比较)" 747 | ] 748 | }, 749 | { 750 | "cell_type": "markdown", 751 | "metadata": {}, 752 | "source": [ 753 | "### 程序运行" 754 | ] 755 | }, 756 | { 757 | "cell_type": "code", 758 | "execution_count": null, 759 | "metadata": { 760 | "ExecuteTime": { 761 | "end_time": "2020-07-07T03:58:11.996273Z", 762 | "start_time": "2020-07-07T03:58:11.971847Z" 763 | } 764 | }, 765 | "outputs": [], 766 | "source": [ 767 | "# 运行\n", 768 | "timeWindow = [20, 60, 120, 180, 240] # 调仓周期\n", 769 | "ups = [0.50, 1.00] # 上调幅度\n", 770 | "\n", 771 | "multiIDX = pd.MultiIndex.from_product([timeWindow, ups], names=['交易周期', '上调幅度'])\n", 772 | "leverNetValueDF_momentumX = pd.DataFrame(index=Returns.index, columns=multiIDX)\n", 773 | "leverDailyPnlDF_momentumX = pd.DataFrame(index=Returns.index, columns=multiIDX) \n", 774 | "leverDrawDownDF_momentumX = pd.DataFrame(index=Returns.index, columns=multiIDX)" 775 | ] 776 | }, 777 | { 778 | "cell_type": "code", 779 | "execution_count": null, 780 | "metadata": { 781 | "ExecuteTime": { 782 | "end_time": "2020-07-07T04:10:33.004037Z", 783 | "start_time": "2020-07-07T03:58:12.537744Z" 784 | } 785 | }, 786 | "outputs": [], 787 | "source": [ 788 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 789 | "factors = {'momentumX':True, 'momentumT':False, \n", 790 | " 'reverseX':False, 'reverseT':False, \n", 791 | " 'turnover':False, \n", 792 | " 'copperGold':False, 'copperGas':False}\n", 793 | "\n", 794 | "for t in timeWindow:\n", 795 | " for u in ups:\n", 796 | " tradeDF, weightDF = AlgoLoop.AlgoTrade(Assets, leverReturns, leverCumReturns, Turnovers, \n", 797 | " mode='ema', dt=t, up=u, thresholds=thrds,\n", 798 | " factorDict=factors)\n", 799 | " StatisticFunc.WeightPlot(tradeDF, weightDF, '杠杆横截面动量(指数权重EMA)'+str(t+u))\n", 800 | "\n", 801 | " leverNetValueDF_momentumX.loc[:, (t, u)] = tradeDF['投资组合净值'] / 10000\n", 802 | " leverDailyPnlDF_momentumX.loc[:, (t, u)] = tradeDF['投资组合净值'] / tradeDF['投资组合净值'].shift(1) - 1.0\n", 803 | " leverDrawDownDF_momentumX.loc[:, (t, u)] = tradeDF['最大回撤'] " 804 | ] 805 | }, 806 | { 807 | "cell_type": "markdown", 808 | "metadata": {}, 809 | "source": [ 810 | "### 回测表现汇总" 811 | ] 812 | }, 813 | { 814 | "cell_type": "code", 815 | "execution_count": null, 816 | "metadata": { 817 | "ExecuteTime": { 818 | "end_time": "2020-07-07T04:10:33.027436Z", 819 | "start_time": "2020-07-07T04:10:33.007166Z" 820 | } 821 | }, 822 | "outputs": [], 823 | "source": [ 824 | "# 汇总\n", 825 | "leverSummaryDF_momentumX = pd.DataFrame(index=multiIDX)\n", 826 | "\n", 827 | "leverSummaryDF_momentumX[\"年平均收益率\"] = leverDailyPnlDF_momentumX.mean(axis=0).values * 250\n", 828 | "leverSummaryDF_momentumX[\"年平均标准差\"] = leverDailyPnlDF_momentumX.std(axis=0).values * np.sqrt(250)\n", 829 | "leverSummaryDF_momentumX[\"无基准夏普比率\"] = leverSummaryDF_momentumX[\"年平均收益率\"] / leverSummaryDF_momentumX[\"年平均标准差\"]\n", 830 | "leverSummaryDF_momentumX[\"最大回撤\"] = leverDrawDownDF_momentumX.min(axis=0).values\n", 831 | "\n", 832 | "leverSummaryDF_momentumX" 833 | ] 834 | }, 835 | { 836 | "cell_type": "markdown", 837 | "metadata": {}, 838 | "source": [ 839 | "### 各投资组合净值曲线" 840 | ] 841 | }, 842 | { 843 | "cell_type": "code", 844 | "execution_count": null, 845 | "metadata": { 846 | "ExecuteTime": { 847 | "end_time": "2020-07-07T04:10:33.758089Z", 848 | "start_time": "2020-07-07T04:10:33.029631Z" 849 | } 850 | }, 851 | "outputs": [], 852 | "source": [ 853 | "fig = plt.figure(figsize=(16, 8), dpi=200)\n", 854 | "\n", 855 | "for col in leverNetValueDF_momentumX.columns:\n", 856 | " plt.plot(leverNetValueDF_momentumX.index, leverNetValueDF_momentumX[col], label=col)\n", 857 | " \n", 858 | "plt.plot(cumReturns.index, cumReturns['信用债3-5AAA'], lw=3.5, label='信用债3-5AAA')\n", 859 | "\n", 860 | "plt.xlabel('时间')\n", 861 | "plt.ylabel('净值')\n", 862 | "plt.ylim(0.0, 5.0)\n", 863 | "plt.legend(loc='upper left')\n", 864 | "plt.title('杠杆横截面动量因子(指数权重EMA)')\n", 865 | "plt.show()" 866 | ] 867 | }, 868 | { 869 | "cell_type": "markdown", 870 | "metadata": {}, 871 | "source": [ 872 | "## 动量因子(时序比较)" 873 | ] 874 | }, 875 | { 876 | "cell_type": "markdown", 877 | "metadata": {}, 878 | "source": [ 879 | "### 程序运行" 880 | ] 881 | }, 882 | { 883 | "cell_type": "code", 884 | "execution_count": null, 885 | "metadata": { 886 | "ExecuteTime": { 887 | "end_time": "2020-07-03T09:18:38.426435Z", 888 | "start_time": "2020-07-03T09:18:38.405398Z" 889 | } 890 | }, 891 | "outputs": [], 892 | "source": [ 893 | "# 运行\n", 894 | "timeWindow = [20, 60, 120, 180, 240] # 调仓周期\n", 895 | "ups = [0.50, 1.00] # 上调幅度\n", 896 | "\n", 897 | "multiIDX = pd.MultiIndex.from_product([timeWindow, ups], names=['交易周期', '上调幅度'])\n", 898 | "leverNetValueDF_momentumT = pd.DataFrame(index=Returns.index, columns=multiIDX)\n", 899 | "leverDailyPnlDF_momentumT = pd.DataFrame(index=Returns.index, columns=multiIDX) \n", 900 | "leverDrawDownDF_momentumT = pd.DataFrame(index=Returns.index, columns=multiIDX)" 901 | ] 902 | }, 903 | { 904 | "cell_type": "code", 905 | "execution_count": null, 906 | "metadata": { 907 | "ExecuteTime": { 908 | "end_time": "2020-07-03T09:32:08.692044Z", 909 | "start_time": "2020-07-03T09:18:38.428597Z" 910 | }, 911 | "scrolled": true 912 | }, 913 | "outputs": [], 914 | "source": [ 915 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 916 | "factors = {'momentumX':False, 'momentumT':True, \n", 917 | " 'reverseX':False, 'reverseT':False, \n", 918 | " 'turnover':False, \n", 919 | " 'copperGold':False, 'copperGas':False}\n", 920 | "\n", 921 | "for t in timeWindow:\n", 922 | " for u in ups:\n", 923 | " tradeDF, weightDF = AlgoLoop.AlgoTrade(Assets, leverReturns, leverCumReturns, Turnovers, \n", 924 | " mode='ema', dt=t, up=u, thresholds=thrds, \n", 925 | " factorDict=factors)\n", 926 | " StatisticFunc.WeightPlot(tradeDF, weightDF, '杠杆时序动量(指数权重EMA)'+str(t+u))\n", 927 | "\n", 928 | " leverNetValueDF_momentumT.loc[:, (t, u)] = tradeDF['投资组合净值'] / 10000 \n", 929 | " leverDailyPnlDF_momentumT.loc[:, (t, u)] = tradeDF['投资组合净值'] / tradeDF['投资组合净值'].shift(1) - 1.0\n", 930 | " leverDrawDownDF_momentumT.loc[:, (t, u)] = tradeDF['最大回撤'] " 931 | ] 932 | }, 933 | { 934 | "cell_type": "markdown", 935 | "metadata": {}, 936 | "source": [ 937 | "### 回测表现汇总" 938 | ] 939 | }, 940 | { 941 | "cell_type": "code", 942 | "execution_count": null, 943 | "metadata": { 944 | "ExecuteTime": { 945 | "end_time": "2020-07-03T09:32:08.713811Z", 946 | "start_time": "2020-07-03T09:32:08.694879Z" 947 | } 948 | }, 949 | "outputs": [], 950 | "source": [ 951 | "# 汇总\n", 952 | "leverSummaryDF_momentumT = pd.DataFrame(index=multiIDX)\n", 953 | "\n", 954 | "leverSummaryDF_momentumT[\"年平均收益率\"] = leverDailyPnlDF_momentumT.mean(axis=0).values * 250\n", 955 | "leverSummaryDF_momentumT[\"年平均标准差\"] = leverDailyPnlDF_momentumT.std(axis=0).values * np.sqrt(250)\n", 956 | "leverSummaryDF_momentumT[\"无基准夏普比率\"] = leverSummaryDF_momentumT[\"年平均收益率\"] / leverSummaryDF_momentumT[\"年平均标准差\"]\n", 957 | "leverSummaryDF_momentumT[\"最大回撤\"] = leverDrawDownDF_momentumT.min(axis=0).values\n", 958 | "\n", 959 | "leverSummaryDF_momentumT" 960 | ] 961 | }, 962 | { 963 | "cell_type": "markdown", 964 | "metadata": {}, 965 | "source": [ 966 | "### 各投资组合净值曲线" 967 | ] 968 | }, 969 | { 970 | "cell_type": "code", 971 | "execution_count": null, 972 | "metadata": { 973 | "ExecuteTime": { 974 | "end_time": "2020-07-03T09:32:09.482258Z", 975 | "start_time": "2020-07-03T09:32:08.715652Z" 976 | } 977 | }, 978 | "outputs": [], 979 | "source": [ 980 | "fig = plt.figure(figsize=(16, 8), dpi=200)\n", 981 | "\n", 982 | "for col in leverNetValueDF_momentumT.columns:\n", 983 | " plt.plot(leverNetValueDF_momentumT.index, leverNetValueDF_momentumT[col], label=col)\n", 984 | "\n", 985 | "plt.plot(cumReturns.index, cumReturns['信用债3-5AAA'], lw=3.0, label='信用债3-5AAA')\n", 986 | " \n", 987 | "plt.xlabel('时间')\n", 988 | "plt.ylabel('净值')\n", 989 | "plt.ylim(0.0, 5.0)\n", 990 | "plt.legend(loc='upper left')\n", 991 | "plt.title('杠杆时间序列动量因子(指数权重EMA)')\n", 992 | "plt.show()" 993 | ] 994 | }, 995 | { 996 | "cell_type": "markdown", 997 | "metadata": {}, 998 | "source": [ 999 | "## 反转因子(横向比较)" 1000 | ] 1001 | }, 1002 | { 1003 | "cell_type": "markdown", 1004 | "metadata": {}, 1005 | "source": [ 1006 | "### 程序运行" 1007 | ] 1008 | }, 1009 | { 1010 | "cell_type": "code", 1011 | "execution_count": null, 1012 | "metadata": { 1013 | "ExecuteTime": { 1014 | "end_time": "2020-07-06T02:42:31.636210Z", 1015 | "start_time": "2020-07-06T02:42:31.610613Z" 1016 | } 1017 | }, 1018 | "outputs": [], 1019 | "source": [ 1020 | "# 运行\n", 1021 | "timeWindow = [20, 60, 120, 180, 240] # 调仓周期\n", 1022 | "ups = [0.50, 1.00] # 上调幅度\n", 1023 | "\n", 1024 | "multiIDX = pd.MultiIndex.from_product([timeWindow, ups], names=['交易周期', '上调幅度'])\n", 1025 | "leverNetValueDF_reverseX = pd.DataFrame(index=Returns.index, columns=multiIDX)\n", 1026 | "leverDailyPnlDF_reverseX = pd.DataFrame(index=Returns.index, columns=multiIDX) \n", 1027 | "leverDrawDownDF_reverseX = pd.DataFrame(index=Returns.index, columns=multiIDX)" 1028 | ] 1029 | }, 1030 | { 1031 | "cell_type": "code", 1032 | "execution_count": null, 1033 | "metadata": { 1034 | "ExecuteTime": { 1035 | "end_time": "2020-07-06T02:56:05.136725Z", 1036 | "start_time": "2020-07-06T02:42:32.043520Z" 1037 | } 1038 | }, 1039 | "outputs": [], 1040 | "source": [ 1041 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 1042 | "factors = {'momentumX':False, 'momentumT':False, \n", 1043 | " 'reverseX':True, 'reverseT':False, \n", 1044 | " 'turnover':False,\n", 1045 | " 'copperGold':False, 'copperGas':False}\n", 1046 | "\n", 1047 | "for t in timeWindow:\n", 1048 | " for u in ups:\n", 1049 | " tradeDF, weightDF = AlgoLoop.AlgoTrade(Assets, leverReturns, leverCumReturns, Turnovers, \n", 1050 | " mode='ema', dt=t, up=u, thresholds=thrds, \n", 1051 | " factorDict=factors)\n", 1052 | " StatisticFunc.WeightPlot(tradeDF, weightDF, '杠杆横截面反转(指数权重EMA)'+str(t+u))\n", 1053 | "\n", 1054 | " leverNetValueDF_reverseX.loc[:, (t, u)] = tradeDF['投资组合净值'] / 10000 \n", 1055 | " leverDailyPnlDF_reverseX.loc[:, (t, u)] = tradeDF['投资组合净值'] / tradeDF['投资组合净值'].shift(1) - 1.0\n", 1056 | " leverDrawDownDF_reverseX.loc[:, (t, u)] = tradeDF['最大回撤'] " 1057 | ] 1058 | }, 1059 | { 1060 | "cell_type": "markdown", 1061 | "metadata": {}, 1062 | "source": [ 1063 | "### 回测表现汇总" 1064 | ] 1065 | }, 1066 | { 1067 | "cell_type": "code", 1068 | "execution_count": null, 1069 | "metadata": { 1070 | "ExecuteTime": { 1071 | "end_time": "2020-07-06T02:56:05.154306Z", 1072 | "start_time": "2020-07-06T02:56:05.138513Z" 1073 | } 1074 | }, 1075 | "outputs": [], 1076 | "source": [ 1077 | "# 汇总\n", 1078 | "leverSummaryDF_reverseX = pd.DataFrame(index=multiIDX)\n", 1079 | "\n", 1080 | "leverSummaryDF_reverseX[\"年平均收益率\"] = leverDailyPnlDF_reverseX.mean(axis=0).values * 250\n", 1081 | "leverSummaryDF_reverseX[\"年平均标准差\"] = leverDailyPnlDF_reverseX.std(axis=0).values * np.sqrt(250)\n", 1082 | "leverSummaryDF_reverseX[\"无基准夏普比率\"] = leverSummaryDF_reverseX[\"年平均收益率\"] / leverSummaryDF_reverseX[\"年平均标准差\"]\n", 1083 | "leverSummaryDF_reverseX[\"最大回撤\"] = leverDrawDownDF_reverseX.min(axis=0).values\n", 1084 | "\n", 1085 | "leverSummaryDF_reverseX" 1086 | ] 1087 | }, 1088 | { 1089 | "cell_type": "markdown", 1090 | "metadata": {}, 1091 | "source": [ 1092 | "### 各投资组合净值曲线" 1093 | ] 1094 | }, 1095 | { 1096 | "cell_type": "code", 1097 | "execution_count": null, 1098 | "metadata": { 1099 | "ExecuteTime": { 1100 | "end_time": "2020-07-06T02:56:05.846752Z", 1101 | "start_time": "2020-07-06T02:56:05.156710Z" 1102 | } 1103 | }, 1104 | "outputs": [], 1105 | "source": [ 1106 | "fig = plt.figure(figsize=(16, 8), dpi=200)\n", 1107 | "\n", 1108 | "for col in leverNetValueDF_reverseX.columns:\n", 1109 | " plt.plot(leverNetValueDF_reverseX.index, leverNetValueDF_reverseX[col], label=col)\n", 1110 | " \n", 1111 | "plt.plot(cumReturns.index, cumReturns['信用债3-5AAA'], lw=3.0, label='信用债3-5AAA')\n", 1112 | "\n", 1113 | "plt.xlabel('时间')\n", 1114 | "plt.ylabel('净值')\n", 1115 | "plt.ylim(0.0, 5.0)\n", 1116 | "plt.legend(loc='upper left')\n", 1117 | "plt.title('杠杆横截面反转因子(指数权重EMA)')\n", 1118 | "plt.show()" 1119 | ] 1120 | }, 1121 | { 1122 | "cell_type": "markdown", 1123 | "metadata": {}, 1124 | "source": [ 1125 | "## 反转因子 (时序比较)" 1126 | ] 1127 | }, 1128 | { 1129 | "cell_type": "markdown", 1130 | "metadata": {}, 1131 | "source": [ 1132 | "### 程序运行" 1133 | ] 1134 | }, 1135 | { 1136 | "cell_type": "code", 1137 | "execution_count": null, 1138 | "metadata": { 1139 | "ExecuteTime": { 1140 | "end_time": "2020-07-04T04:49:11.668030Z", 1141 | "start_time": "2020-07-04T04:49:11.641899Z" 1142 | } 1143 | }, 1144 | "outputs": [], 1145 | "source": [ 1146 | "# 运行\n", 1147 | "timeWindow = [20, 60, 120, 180, 240] # 调仓周期\n", 1148 | "ups = [0.50, 1.00] # 上调幅度\n", 1149 | "\n", 1150 | "multiIDX = pd.MultiIndex.from_product([timeWindow, ups], names=['交易周期', '上调幅度'])\n", 1151 | "leverNetValueDF_reverseT = pd.DataFrame(index=Returns.index, columns=multiIDX)\n", 1152 | "leverDailyPnlDF_reverseT = pd.DataFrame(index=Returns.index, columns=multiIDX) \n", 1153 | "leverDrawDownDF_reverseT = pd.DataFrame(index=Returns.index, columns=multiIDX)" 1154 | ] 1155 | }, 1156 | { 1157 | "cell_type": "code", 1158 | "execution_count": null, 1159 | "metadata": { 1160 | "ExecuteTime": { 1161 | "end_time": "2020-07-04T05:01:22.746742Z", 1162 | "start_time": "2020-07-04T04:49:11.670165Z" 1163 | } 1164 | }, 1165 | "outputs": [], 1166 | "source": [ 1167 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 1168 | "factors = {'momentumX':False, 'momentumT':False, \n", 1169 | " 'reverseX':False, 'reverseT':True, \n", 1170 | " 'turnover':False,\n", 1171 | " 'copperGold':False, 'copperGas':False}\n", 1172 | "\n", 1173 | "for t in timeWindow:\n", 1174 | " for u in ups:\n", 1175 | " tradeDF, weightDF = AlgoLoop.AlgoTrade(Assets, leverReturns, leverCumReturns, Turnovers, \n", 1176 | " mode='ema', dt=t, up=u, thresholds=thrds, \n", 1177 | " factorDict=factors)\n", 1178 | " StatisticFunc.WeightPlot(tradeDF, weightDF, '杠杆时序反转(指数权重EMA)'+str(t+u))\n", 1179 | "\n", 1180 | " leverNetValueDF_reverseT.loc[:, (t, u)] = tradeDF['投资组合净值'] / 10000 \n", 1181 | " leverDailyPnlDF_reverseT.loc[:, (t, u)] = tradeDF['投资组合净值'] / tradeDF['投资组合净值'].shift(1) - 1.0\n", 1182 | " leverDrawDownDF_reverseT.loc[:, (t, u)] = tradeDF['最大回撤'] " 1183 | ] 1184 | }, 1185 | { 1186 | "cell_type": "markdown", 1187 | "metadata": {}, 1188 | "source": [ 1189 | "### 回测表现汇总" 1190 | ] 1191 | }, 1192 | { 1193 | "cell_type": "code", 1194 | "execution_count": null, 1195 | "metadata": { 1196 | "ExecuteTime": { 1197 | "end_time": "2020-07-04T05:01:22.771523Z", 1198 | "start_time": "2020-07-04T05:01:22.749157Z" 1199 | } 1200 | }, 1201 | "outputs": [], 1202 | "source": [ 1203 | "# 汇总\n", 1204 | "leverSummaryDF_reverseT = pd.DataFrame(index=multiIDX)\n", 1205 | "\n", 1206 | "leverSummaryDF_reverseT[\"年平均收益率\"] = leverDailyPnlDF_reverseT.mean(axis=0).values * 250\n", 1207 | "leverSummaryDF_reverseT[\"年平均标准差\"] = leverDailyPnlDF_reverseT.std(axis=0).values * np.sqrt(250)\n", 1208 | "leverSummaryDF_reverseT[\"无基准夏普比率\"] = leverSummaryDF_reverseT[\"年平均收益率\"] / leverSummaryDF_reverseT[\"年平均标准差\"]\n", 1209 | "leverSummaryDF_reverseT[\"最大回撤\"] = leverDrawDownDF_reverseT.min(axis=0).values\n", 1210 | "\n", 1211 | "leverSummaryDF_reverseT" 1212 | ] 1213 | }, 1214 | { 1215 | "cell_type": "markdown", 1216 | "metadata": {}, 1217 | "source": [ 1218 | "### 各投资组合净值曲线" 1219 | ] 1220 | }, 1221 | { 1222 | "cell_type": "code", 1223 | "execution_count": null, 1224 | "metadata": { 1225 | "ExecuteTime": { 1226 | "end_time": "2020-07-04T05:01:23.531426Z", 1227 | "start_time": "2020-07-04T05:01:22.775414Z" 1228 | } 1229 | }, 1230 | "outputs": [], 1231 | "source": [ 1232 | "fig = plt.figure(figsize=(16, 8), dpi=200)\n", 1233 | "\n", 1234 | "for col in leverNetValueDF_reverseT.columns:\n", 1235 | " plt.plot(leverNetValueDF_reverseT.index, leverNetValueDF_reverseT[col], label=col)\n", 1236 | "\n", 1237 | "plt.plot(cumReturns.index, cumReturns['信用债3-5AAA'], lw=3.0, label='信用债3-5AAA')\n", 1238 | " \n", 1239 | "plt.xlabel('时间')\n", 1240 | "plt.ylabel('净值')\n", 1241 | "plt.ylim(0.0, 5.0)\n", 1242 | "plt.legend(loc='upper left')\n", 1243 | "plt.title('杠杆时序反转因子(指数权重EMA)')\n", 1244 | "plt.show()" 1245 | ] 1246 | }, 1247 | { 1248 | "cell_type": "markdown", 1249 | "metadata": {}, 1250 | "source": [ 1251 | "## 情绪因子(股指换手率)" 1252 | ] 1253 | }, 1254 | { 1255 | "cell_type": "markdown", 1256 | "metadata": {}, 1257 | "source": [ 1258 | "### 程序运行" 1259 | ] 1260 | }, 1261 | { 1262 | "cell_type": "code", 1263 | "execution_count": null, 1264 | "metadata": { 1265 | "ExecuteTime": { 1266 | "end_time": "2020-07-04T05:01:23.559601Z", 1267 | "start_time": "2020-07-04T05:01:23.535036Z" 1268 | } 1269 | }, 1270 | "outputs": [], 1271 | "source": [ 1272 | "# 运行\n", 1273 | "timeWindow = [20, 60, 120, 180, 240] # 调仓周期\n", 1274 | "ups = [0.50, 1.00] # 上调幅度\n", 1275 | "\n", 1276 | "multiIDX = pd.MultiIndex.from_product([timeWindow, ups], names=['交易周期', '上调幅度'])\n", 1277 | "leverNetValueDF_turnover = pd.DataFrame(index=Returns.index, columns=multiIDX)\n", 1278 | "leverDailyPnlDF_turnover = pd.DataFrame(index=Returns.index, columns=multiIDX) \n", 1279 | "leverDrawDownDF_turnover = pd.DataFrame(index=Returns.index, columns=multiIDX)" 1280 | ] 1281 | }, 1282 | { 1283 | "cell_type": "code", 1284 | "execution_count": null, 1285 | "metadata": { 1286 | "ExecuteTime": { 1287 | "end_time": "2020-07-04T05:13:35.437572Z", 1288 | "start_time": "2020-07-04T05:01:23.561998Z" 1289 | } 1290 | }, 1291 | "outputs": [], 1292 | "source": [ 1293 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 1294 | "factors = {'momentumX':False, 'momentumT':False, \n", 1295 | " 'reverseX':False, 'reverseT':False, \n", 1296 | " 'turnover':True, \n", 1297 | " 'copperGold':False, 'copperGas':False}\n", 1298 | "\n", 1299 | "for t in timeWindow:\n", 1300 | " for u in ups:\n", 1301 | " tradeDF, weightDF = AlgoLoop.AlgoTrade(Assets, leverReturns, leverCumReturns, Turnovers, \n", 1302 | " mode='plain', dt=t, up=u, thresholds=thrds, \n", 1303 | " factorDict=factors)\n", 1304 | " StatisticFunc.WeightPlot(tradeDF, weightDF, '杠杆换手率(指数权重EMA)'+str(t+u))\n", 1305 | "\n", 1306 | " leverNetValueDF_turnover.loc[:, (t, u)] = tradeDF['投资组合净值'] / 10000 \n", 1307 | " leverDailyPnlDF_turnover.loc[:, (t, u)] = tradeDF['投资组合净值'] / tradeDF['投资组合净值'].shift(1) - 1.0\n", 1308 | " leverDrawDownDF_turnover.loc[:, (t, u)] = tradeDF['最大回撤'] " 1309 | ] 1310 | }, 1311 | { 1312 | "cell_type": "markdown", 1313 | "metadata": {}, 1314 | "source": [ 1315 | "### 回测表现汇总" 1316 | ] 1317 | }, 1318 | { 1319 | "cell_type": "code", 1320 | "execution_count": null, 1321 | "metadata": { 1322 | "ExecuteTime": { 1323 | "end_time": "2020-07-04T05:13:35.457919Z", 1324 | "start_time": "2020-07-04T05:13:35.439560Z" 1325 | }, 1326 | "scrolled": false 1327 | }, 1328 | "outputs": [], 1329 | "source": [ 1330 | "# 汇总\n", 1331 | "leverSummaryDF_turnover = pd.DataFrame(index=multiIDX)\n", 1332 | "\n", 1333 | "leverSummaryDF_turnover[\"年平均收益率\"] = leverDailyPnlDF_turnover.mean(axis=0).values * 250\n", 1334 | "leverSummaryDF_turnover[\"年平均标准差\"] = leverDailyPnlDF_turnover.std(axis=0).values * np.sqrt(250)\n", 1335 | "leverSummaryDF_turnover[\"无基准夏普比率\"] = leverSummaryDF_turnover[\"年平均收益率\"] / leverSummaryDF_turnover[\"年平均标准差\"]\n", 1336 | "leverSummaryDF_turnover[\"最大回撤\"] = leverDrawDownDF_turnover.min(axis=0).values\n", 1337 | "\n", 1338 | "leverSummaryDF_turnover" 1339 | ] 1340 | }, 1341 | { 1342 | "cell_type": "markdown", 1343 | "metadata": {}, 1344 | "source": [ 1345 | "### 各投资组合净值曲线" 1346 | ] 1347 | }, 1348 | { 1349 | "cell_type": "code", 1350 | "execution_count": null, 1351 | "metadata": { 1352 | "ExecuteTime": { 1353 | "end_time": "2020-07-04T05:13:36.133716Z", 1354 | "start_time": "2020-07-04T05:13:35.459539Z" 1355 | }, 1356 | "scrolled": false 1357 | }, 1358 | "outputs": [], 1359 | "source": [ 1360 | "fig = plt.figure(figsize=(16, 8), dpi=200)\n", 1361 | "\n", 1362 | "for col in leverNetValueDF_turnover.columns:\n", 1363 | " plt.plot(leverNetValueDF_turnover.index, leverNetValueDF_turnover[col], label=col)\n", 1364 | " \n", 1365 | "plt.plot(cumReturns.index, cumReturns['信用债3-5AAA'], lw=3.0, label='信用债3-5AAA')\n", 1366 | "\n", 1367 | "plt.xlabel('时间')\n", 1368 | "plt.ylabel('净值')\n", 1369 | "plt.ylim(0.0, 5.0)\n", 1370 | "plt.legend(loc='upper left')\n", 1371 | "plt.title('杠杆股指换手率因子(指数权重EMA)')\n", 1372 | "plt.show()" 1373 | ] 1374 | }, 1375 | { 1376 | "cell_type": "markdown", 1377 | "metadata": {}, 1378 | "source": [ 1379 | "## 铜金价格比因子(十年国债反转)" 1380 | ] 1381 | }, 1382 | { 1383 | "cell_type": "markdown", 1384 | "metadata": {}, 1385 | "source": [ 1386 | "### 程序运行" 1387 | ] 1388 | }, 1389 | { 1390 | "cell_type": "code", 1391 | "execution_count": null, 1392 | "metadata": { 1393 | "ExecuteTime": { 1394 | "end_time": "2020-07-04T05:13:36.158292Z", 1395 | "start_time": "2020-07-04T05:13:36.135661Z" 1396 | } 1397 | }, 1398 | "outputs": [], 1399 | "source": [ 1400 | "# 运行\n", 1401 | "timeWindow = [20, 60, 120, 180, 240] # 调仓周期\n", 1402 | "ups = [0.50, 1.00] # 上调幅度\n", 1403 | "\n", 1404 | "multiIDX = pd.MultiIndex.from_product([timeWindow, ups], names=['交易周期', '上调幅度'])\n", 1405 | "leverNetValueDF_copperGold = pd.DataFrame(index=Returns.index, columns=multiIDX)\n", 1406 | "leverDailyPnlDF_copperGold = pd.DataFrame(index=Returns.index, columns=multiIDX) \n", 1407 | "leverDrawDownDF_copperGold = pd.DataFrame(index=Returns.index, columns=multiIDX)" 1408 | ] 1409 | }, 1410 | { 1411 | "cell_type": "code", 1412 | "execution_count": null, 1413 | "metadata": { 1414 | "ExecuteTime": { 1415 | "end_time": "2020-07-04T05:25:46.847861Z", 1416 | "start_time": "2020-07-04T05:13:36.160532Z" 1417 | } 1418 | }, 1419 | "outputs": [], 1420 | "source": [ 1421 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 1422 | "factors = {'momentumX':False, 'momentumT':False, \n", 1423 | " 'reverseX':False, 'reverseT':False,\n", 1424 | " 'turnover':False, \n", 1425 | " 'copperGold':True, 'copperGas':False}\n", 1426 | "\n", 1427 | "for t in timeWindow:\n", 1428 | " for u in ups:\n", 1429 | " tradeDF, weightDF = AlgoLoop.AlgoTrade(Assets, leverReturns, leverCumReturns, Turnovers, \n", 1430 | " mode='ema', dt=t, up=u, thresholds=thrds, \n", 1431 | " factorDict=factors)\n", 1432 | " StatisticFunc.WeightPlot(tradeDF, weightDF, '杠杆铜金价格比(指数权重EMA)'+str(t+u))\n", 1433 | "\n", 1434 | " leverNetValueDF_copperGold.loc[:, (t, u)] = tradeDF['投资组合净值'] / 10000 \n", 1435 | " leverDailyPnlDF_copperGold.loc[:, (t, u)] = tradeDF['投资组合净值'] / tradeDF['投资组合净值'].shift(1) - 1.0\n", 1436 | " leverDrawDownDF_copperGold.loc[:, (t, u)] = tradeDF['最大回撤'] " 1437 | ] 1438 | }, 1439 | { 1440 | "cell_type": "markdown", 1441 | "metadata": {}, 1442 | "source": [ 1443 | "### 回测表现汇总" 1444 | ] 1445 | }, 1446 | { 1447 | "cell_type": "code", 1448 | "execution_count": null, 1449 | "metadata": { 1450 | "ExecuteTime": { 1451 | "end_time": "2020-07-04T05:25:46.867891Z", 1452 | "start_time": "2020-07-04T05:25:46.850498Z" 1453 | }, 1454 | "scrolled": false 1455 | }, 1456 | "outputs": [], 1457 | "source": [ 1458 | "# 汇总\n", 1459 | "leverSummaryDF_copperGold = pd.DataFrame(index=multiIDX)\n", 1460 | "\n", 1461 | "leverSummaryDF_copperGold[\"年平均收益率\"] = leverDailyPnlDF_copperGold.mean(axis=0).values * 250\n", 1462 | "leverSummaryDF_copperGold[\"年平均标准差\"] = leverDailyPnlDF_copperGold.std(axis=0).values * np.sqrt(250)\n", 1463 | "leverSummaryDF_copperGold[\"无基准夏普比率\"] = leverSummaryDF_copperGold[\"年平均收益率\"] / leverSummaryDF_copperGold[\"年平均标准差\"]\n", 1464 | "leverSummaryDF_copperGold[\"最大回撤\"] = leverDrawDownDF_copperGold.min(axis=0).values\n", 1465 | "\n", 1466 | "leverSummaryDF_copperGold" 1467 | ] 1468 | }, 1469 | { 1470 | "cell_type": "markdown", 1471 | "metadata": {}, 1472 | "source": [ 1473 | "### 各投资组合净值曲线" 1474 | ] 1475 | }, 1476 | { 1477 | "cell_type": "code", 1478 | "execution_count": null, 1479 | "metadata": { 1480 | "ExecuteTime": { 1481 | "end_time": "2020-07-06T01:47:46.795674Z", 1482 | "start_time": "2020-07-06T01:47:46.075857Z" 1483 | }, 1484 | "scrolled": false 1485 | }, 1486 | "outputs": [], 1487 | "source": [ 1488 | "fig = plt.figure(figsize=(16, 8), dpi=200)\n", 1489 | "\n", 1490 | "for col in leverNetValueDF_copperGold.columns:\n", 1491 | " plt.plot(leverNetValueDF_copperGold.index, leverNetValueDF_copperGold[col], label=col)\n", 1492 | " \n", 1493 | "plt.plot(cumReturns.index, cumReturns['信用债3-5AAA'], lw=3.0, label='信用债3-5AAA')\n", 1494 | "\n", 1495 | "plt.xlabel('时间')\n", 1496 | "plt.ylabel('净值')\n", 1497 | "plt.ylim(0.0, 5.0)\n", 1498 | "plt.legend(loc='upper left')\n", 1499 | "plt.title('杠杆铜金价格比因子(指数权重EMA)')\n", 1500 | "plt.show()" 1501 | ] 1502 | }, 1503 | { 1504 | "cell_type": "markdown", 1505 | "metadata": {}, 1506 | "source": [ 1507 | "## 铜油价格比因子(沪深300动量)" 1508 | ] 1509 | }, 1510 | { 1511 | "cell_type": "markdown", 1512 | "metadata": {}, 1513 | "source": [ 1514 | "### 程序运行" 1515 | ] 1516 | }, 1517 | { 1518 | "cell_type": "code", 1519 | "execution_count": null, 1520 | "metadata": { 1521 | "ExecuteTime": { 1522 | "end_time": "2020-07-06T02:06:56.771548Z", 1523 | "start_time": "2020-07-06T02:06:56.746260Z" 1524 | } 1525 | }, 1526 | "outputs": [], 1527 | "source": [ 1528 | "# 运行\n", 1529 | "timeWindow = [20, 60, 120, 180, 240] # 调仓周期\n", 1530 | "ups = [0.50, 1.00] # 上调幅度\n", 1531 | "\n", 1532 | "multiIDX = pd.MultiIndex.from_product([timeWindow, ups], names=['交易周期', '上调幅度'])\n", 1533 | "leverNetValueDF_copperGas = pd.DataFrame(index=Returns.index, columns=multiIDX)\n", 1534 | "leverDailyPnlDF_copperGas = pd.DataFrame(index=Returns.index, columns=multiIDX) \n", 1535 | "leverDrawDownDF_copperGas = pd.DataFrame(index=Returns.index, columns=multiIDX)" 1536 | ] 1537 | }, 1538 | { 1539 | "cell_type": "code", 1540 | "execution_count": null, 1541 | "metadata": { 1542 | "ExecuteTime": { 1543 | "end_time": "2020-07-06T02:20:47.437408Z", 1544 | "start_time": "2020-07-06T02:06:56.773705Z" 1545 | } 1546 | }, 1547 | "outputs": [], 1548 | "source": [ 1549 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 1550 | "factors = {'momentumX':False, 'momentumT':False, \n", 1551 | " 'reverseX':False, 'reverseT':False,\n", 1552 | " 'turnover':False, \n", 1553 | " 'copperGold':False, 'copperGas':True}\n", 1554 | "\n", 1555 | "for t in timeWindow:\n", 1556 | " for u in ups:\n", 1557 | " tradeDF, weightDF = AlgoLoop.AlgoTrade(Assets, leverReturns, leverCumReturns, Turnovers, \n", 1558 | " mode='ema', dt=t, up=u, thresholds=thrds, \n", 1559 | " factorDict=factors)\n", 1560 | " StatisticFunc.WeightPlot(tradeDF, weightDF, '杠杆铜油价格比(指数权重EMA)'+str(t+u))\n", 1561 | "\n", 1562 | " leverNetValueDF_copperGas.loc[:, (t, u)] = tradeDF['投资组合净值'] / 10000 \n", 1563 | " leverDailyPnlDF_copperGas.loc[:, (t, u)] = tradeDF['投资组合净值'] / tradeDF['投资组合净值'].shift(1) - 1.0\n", 1564 | " leverDrawDownDF_copperGas.loc[:, (t, u)] = tradeDF['最大回撤'] " 1565 | ] 1566 | }, 1567 | { 1568 | "cell_type": "markdown", 1569 | "metadata": {}, 1570 | "source": [ 1571 | "### 回测表现汇总" 1572 | ] 1573 | }, 1574 | { 1575 | "cell_type": "code", 1576 | "execution_count": null, 1577 | "metadata": { 1578 | "ExecuteTime": { 1579 | "end_time": "2020-07-06T02:20:47.457150Z", 1580 | "start_time": "2020-07-06T02:20:47.439349Z" 1581 | }, 1582 | "scrolled": false 1583 | }, 1584 | "outputs": [], 1585 | "source": [ 1586 | "# 汇总\n", 1587 | "leverSummaryDF_copperGas = pd.DataFrame(index=multiIDX)\n", 1588 | "\n", 1589 | "leverSummaryDF_copperGas[\"年平均收益率\"] = leverDailyPnlDF_copperGas.mean(axis=0).values * 250\n", 1590 | "leverSummaryDF_copperGas[\"年平均标准差\"] = leverDailyPnlDF_copperGas.std(axis=0).values * np.sqrt(250)\n", 1591 | "leverSummaryDF_copperGas[\"无基准夏普比率\"] = leverSummaryDF_copperGas[\"年平均收益率\"] / leverSummaryDF_copperGas[\"年平均标准差\"]\n", 1592 | "leverSummaryDF_copperGas[\"最大回撤\"] = leverDrawDownDF_copperGas.min(axis=0).values\n", 1593 | "\n", 1594 | "leverSummaryDF_copperGas" 1595 | ] 1596 | }, 1597 | { 1598 | "cell_type": "markdown", 1599 | "metadata": {}, 1600 | "source": [ 1601 | "### 各投资组合净值曲线" 1602 | ] 1603 | }, 1604 | { 1605 | "cell_type": "code", 1606 | "execution_count": null, 1607 | "metadata": { 1608 | "ExecuteTime": { 1609 | "end_time": "2020-07-06T02:20:48.268603Z", 1610 | "start_time": "2020-07-06T02:20:47.458816Z" 1611 | }, 1612 | "scrolled": true 1613 | }, 1614 | "outputs": [], 1615 | "source": [ 1616 | "fig = plt.figure(figsize=(16, 8), dpi=200)\n", 1617 | "\n", 1618 | "for col in leverNetValueDF_copperGas.columns:\n", 1619 | " plt.plot(leverNetValueDF_copperGas.index, leverNetValueDF_copperGas[col], label=col)\n", 1620 | " \n", 1621 | "plt.plot(cumReturns.index, cumReturns['信用债3-5AAA'], lw=3.0, label='信用债3-5AAA')\n", 1622 | "\n", 1623 | "plt.xlabel('时间')\n", 1624 | "plt.ylabel('净值')\n", 1625 | "plt.ylim(0.0, 5.0)\n", 1626 | "plt.legend(loc='upper left')\n", 1627 | "plt.title('杠杆铜油价格比因子(指数权重EMA)')\n", 1628 | "plt.show()" 1629 | ] 1630 | }, 1631 | { 1632 | "cell_type": "markdown", 1633 | "metadata": {}, 1634 | "source": [ 1635 | "# 风险平价+杠杆+多因子策略(指数平均EMA)" 1636 | ] 1637 | }, 1638 | { 1639 | "cell_type": "markdown", 1640 | "metadata": {}, 1641 | "source": [ 1642 | "## 多因子(铜金 + 时序反转)" 1643 | ] 1644 | }, 1645 | { 1646 | "cell_type": "markdown", 1647 | "metadata": {}, 1648 | "source": [ 1649 | "### 程序运行" 1650 | ] 1651 | }, 1652 | { 1653 | "cell_type": "code", 1654 | "execution_count": null, 1655 | "metadata": { 1656 | "ExecuteTime": { 1657 | "end_time": "2020-07-06T13:57:01.501468Z", 1658 | "start_time": "2020-07-06T13:57:01.480414Z" 1659 | } 1660 | }, 1661 | "outputs": [], 1662 | "source": [ 1663 | "# 运行\n", 1664 | "timeWindow = [20, 60, 120, 180, 240] # 调仓周期\n", 1665 | "ups = [0.50, 1.00] # 上调幅度\n", 1666 | "\n", 1667 | "multiIDX = pd.MultiIndex.from_product([timeWindow, ups], names=['交易周期', '上调幅度'])\n", 1668 | "leverNetValueDF_multi = pd.DataFrame(index=Returns.index, columns=multiIDX)\n", 1669 | "leverDailyPnlDF_multi = pd.DataFrame(index=Returns.index, columns=multiIDX) \n", 1670 | "leverDrawDownDF_multi = pd.DataFrame(index=Returns.index, columns=multiIDX)" 1671 | ] 1672 | }, 1673 | { 1674 | "cell_type": "code", 1675 | "execution_count": null, 1676 | "metadata": { 1677 | "ExecuteTime": { 1678 | "end_time": "2020-07-06T14:09:53.812774Z", 1679 | "start_time": "2020-07-06T13:57:01.858610Z" 1680 | } 1681 | }, 1682 | "outputs": [], 1683 | "source": [ 1684 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 1685 | "factors = {'momentumX':False, 'momentumT':False, \n", 1686 | " 'reverseX':False, 'reverseT':True,\n", 1687 | " 'turnover':False, \n", 1688 | " 'copperGold':True, 'copperGas':False}\n", 1689 | "\n", 1690 | "for t in timeWindow:\n", 1691 | " for u in ups:\n", 1692 | " tradeDF, weightDF = AlgoLoop.AlgoTrade(Assets, leverReturns, leverCumReturns, Turnovers, \n", 1693 | " mode='ema', dt=t, up=u, thresholds=thrds, \n", 1694 | " factorDict=factors)\n", 1695 | " StatisticFunc.WeightPlot(tradeDF, weightDF, '杠杆-铜金-时序反转(指数权重EMA)'+str(t+u))\n", 1696 | "\n", 1697 | " leverNetValueDF_multi.loc[:, (t, u)] = tradeDF['投资组合净值'] / 10000 \n", 1698 | " leverDailyPnlDF_multi.loc[:, (t, u)] = tradeDF['投资组合净值'] / tradeDF['投资组合净值'].shift(1) - 1.0\n", 1699 | " leverDrawDownDF_multi.loc[:, (t, u)] = tradeDF['最大回撤'] " 1700 | ] 1701 | }, 1702 | { 1703 | "cell_type": "markdown", 1704 | "metadata": {}, 1705 | "source": [ 1706 | "### 回测表现汇总" 1707 | ] 1708 | }, 1709 | { 1710 | "cell_type": "code", 1711 | "execution_count": null, 1712 | "metadata": { 1713 | "ExecuteTime": { 1714 | "end_time": "2020-07-06T14:09:53.833327Z", 1715 | "start_time": "2020-07-06T14:09:53.814861Z" 1716 | }, 1717 | "scrolled": false 1718 | }, 1719 | "outputs": [], 1720 | "source": [ 1721 | "# 汇总\n", 1722 | "leverSummaryDF_multi = pd.DataFrame(index=multiIDX)\n", 1723 | "\n", 1724 | "leverSummaryDF_multi[\"年平均收益率\"] = leverDailyPnlDF_multi.mean(axis=0).values * 250\n", 1725 | "leverSummaryDF_multi[\"年平均标准差\"] = leverDailyPnlDF_multi.std(axis=0).values * np.sqrt(250)\n", 1726 | "leverSummaryDF_multi[\"无基准夏普比率\"] = leverSummaryDF_multi[\"年平均收益率\"] / leverSummaryDF_multi[\"年平均标准差\"]\n", 1727 | "leverSummaryDF_multi[\"最大回撤\"] = leverDrawDownDF_multi.min(axis=0).values\n", 1728 | "\n", 1729 | "leverSummaryDF_multi" 1730 | ] 1731 | }, 1732 | { 1733 | "cell_type": "markdown", 1734 | "metadata": {}, 1735 | "source": [ 1736 | "### 各投资组合净值曲线" 1737 | ] 1738 | }, 1739 | { 1740 | "cell_type": "code", 1741 | "execution_count": null, 1742 | "metadata": { 1743 | "ExecuteTime": { 1744 | "end_time": "2020-07-06T14:09:54.554721Z", 1745 | "start_time": "2020-07-06T14:09:53.835528Z" 1746 | }, 1747 | "scrolled": false 1748 | }, 1749 | "outputs": [], 1750 | "source": [ 1751 | "fig = plt.figure(figsize=(16, 8), dpi=200)\n", 1752 | "\n", 1753 | "for col in leverNetValueDF_multi.columns:\n", 1754 | " plt.plot(leverNetValueDF_multi.index, leverNetValueDF_multi[col], label=col)\n", 1755 | " \n", 1756 | "plt.plot(cumReturns.index, cumReturns['信用债3-5AAA'], lw=3.0, label='信用债3-5AAA')\n", 1757 | "\n", 1758 | "plt.xlabel('时间')\n", 1759 | "plt.ylabel('净值')\n", 1760 | "plt.ylim(0.0, 5.0)\n", 1761 | "plt.legend(loc='upper left')\n", 1762 | "plt.title('杠杆-铜金-时序反转(指数权重EMA)')\n", 1763 | "plt.show()" 1764 | ] 1765 | }, 1766 | { 1767 | "cell_type": "markdown", 1768 | "metadata": {}, 1769 | "source": [ 1770 | "## 多因子(铜油 + 时序反转)" 1771 | ] 1772 | }, 1773 | { 1774 | "cell_type": "markdown", 1775 | "metadata": {}, 1776 | "source": [ 1777 | "### 程序运行" 1778 | ] 1779 | }, 1780 | { 1781 | "cell_type": "code", 1782 | "execution_count": null, 1783 | "metadata": { 1784 | "ExecuteTime": { 1785 | "end_time": "2020-07-06T14:09:54.582027Z", 1786 | "start_time": "2020-07-06T14:09:54.557197Z" 1787 | } 1788 | }, 1789 | "outputs": [], 1790 | "source": [ 1791 | "# 运行\n", 1792 | "timeWindow = [20, 60, 120, 180, 240] # 调仓周期\n", 1793 | "ups = [0.50, 1.00] # 上调幅度\n", 1794 | "\n", 1795 | "multiIDX = pd.MultiIndex.from_product([timeWindow, ups], names=['交易周期', '上调幅度'])\n", 1796 | "leverNetValueDF_multi2 = pd.DataFrame(index=Returns.index, columns=multiIDX)\n", 1797 | "leverDailyPnlDF_multi2 = pd.DataFrame(index=Returns.index, columns=multiIDX) \n", 1798 | "leverDrawDownDF_multi2 = pd.DataFrame(index=Returns.index, columns=multiIDX)" 1799 | ] 1800 | }, 1801 | { 1802 | "cell_type": "code", 1803 | "execution_count": null, 1804 | "metadata": { 1805 | "ExecuteTime": { 1806 | "end_time": "2020-07-06T14:22:07.546495Z", 1807 | "start_time": "2020-07-06T14:09:54.583797Z" 1808 | }, 1809 | "scrolled": true 1810 | }, 1811 | "outputs": [], 1812 | "source": [ 1813 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 1814 | "factors = {'momentumX':False, 'momentumT':False, \n", 1815 | " 'reverseX':False, 'reverseT':True,\n", 1816 | " 'turnover':False, \n", 1817 | " 'copperGold':False, 'copperGas':True}\n", 1818 | "\n", 1819 | "for t in timeWindow:\n", 1820 | " for u in ups:\n", 1821 | " tradeDF, weightDF = AlgoLoop.AlgoTrade(Assets, leverReturns, leverCumReturns, Turnovers, \n", 1822 | " mode='ema', dt=t, up=u, thresholds=thrds, \n", 1823 | " factorDict=factors)\n", 1824 | " StatisticFunc.WeightPlot(tradeDF, weightDF, '杠杆-铜油-时序反转(指数权重EMA)'+str(t+u))\n", 1825 | "\n", 1826 | " leverNetValueDF_multi2.loc[:, (t, u)] = tradeDF['投资组合净值'] / 10000 \n", 1827 | " leverDailyPnlDF_multi2.loc[:, (t, u)] = tradeDF['投资组合净值'] / tradeDF['投资组合净值'].shift(1) - 1.0\n", 1828 | " leverDrawDownDF_multi2.loc[:, (t, u)] = tradeDF['最大回撤'] " 1829 | ] 1830 | }, 1831 | { 1832 | "cell_type": "markdown", 1833 | "metadata": {}, 1834 | "source": [ 1835 | "### 回测表现汇总" 1836 | ] 1837 | }, 1838 | { 1839 | "cell_type": "code", 1840 | "execution_count": null, 1841 | "metadata": { 1842 | "ExecuteTime": { 1843 | "end_time": "2020-07-06T14:22:07.566384Z", 1844 | "start_time": "2020-07-06T14:22:07.549677Z" 1845 | }, 1846 | "scrolled": false 1847 | }, 1848 | "outputs": [], 1849 | "source": [ 1850 | "# 汇总\n", 1851 | "leverSummaryDF_multi2 = pd.DataFrame(index=multiIDX)\n", 1852 | "\n", 1853 | "leverSummaryDF_multi2[\"年平均收益率\"] = leverDailyPnlDF_multi2.mean(axis=0).values * 250\n", 1854 | "leverSummaryDF_multi2[\"年平均标准差\"] = leverDailyPnlDF_multi2.std(axis=0).values * np.sqrt(250)\n", 1855 | "leverSummaryDF_multi2[\"无基准夏普比率\"] = leverSummaryDF_multi2[\"年平均收益率\"] / leverSummaryDF_multi2[\"年平均标准差\"]\n", 1856 | "leverSummaryDF_multi2[\"最大回撤\"] = leverDrawDownDF_multi2.min(axis=0).values\n", 1857 | "\n", 1858 | "leverSummaryDF_multi2" 1859 | ] 1860 | }, 1861 | { 1862 | "cell_type": "markdown", 1863 | "metadata": {}, 1864 | "source": [ 1865 | "### 各投资组合净值曲线" 1866 | ] 1867 | }, 1868 | { 1869 | "cell_type": "code", 1870 | "execution_count": null, 1871 | "metadata": { 1872 | "ExecuteTime": { 1873 | "end_time": "2020-07-06T14:22:08.256465Z", 1874 | "start_time": "2020-07-06T14:22:07.567954Z" 1875 | }, 1876 | "scrolled": false 1877 | }, 1878 | "outputs": [], 1879 | "source": [ 1880 | "fig = plt.figure(figsize=(16, 8), dpi=200)\n", 1881 | "\n", 1882 | "for col in leverNetValueDF_multi2.columns:\n", 1883 | " plt.plot(leverNetValueDF_multi2.index, leverNetValueDF_multi2[col], label=col)\n", 1884 | " \n", 1885 | "plt.plot(cumReturns.index, cumReturns['信用债3-5AAA'], lw=3.0, label='信用债3-5AAA')\n", 1886 | "\n", 1887 | "plt.xlabel('时间')\n", 1888 | "plt.ylabel('净值')\n", 1889 | "plt.ylim(0.0, 5.0)\n", 1890 | "plt.legend(loc='upper left')\n", 1891 | "plt.title('杠杆-铜油-时序反转(指数权重EMA)')\n", 1892 | "plt.show()" 1893 | ] 1894 | }, 1895 | { 1896 | "cell_type": "markdown", 1897 | "metadata": {}, 1898 | "source": [ 1899 | "# 最佳组合(杠杆+时序动量+铜金)" 1900 | ] 1901 | }, 1902 | { 1903 | "cell_type": "markdown", 1904 | "metadata": {}, 1905 | "source": [ 1906 | "## 程序运行" 1907 | ] 1908 | }, 1909 | { 1910 | "cell_type": "code", 1911 | "execution_count": null, 1912 | "metadata": { 1913 | "ExecuteTime": { 1914 | "end_time": "2020-07-07T05:06:22.345329Z", 1915 | "start_time": "2020-07-07T05:06:22.324517Z" 1916 | } 1917 | }, 1918 | "outputs": [], 1919 | "source": [ 1920 | "# 运行\n", 1921 | "timeWindow = [20, 60, 120, 180, 240] # 调仓周期\n", 1922 | "ups = [0.50, 1.00] # 上调幅度\n", 1923 | "\n", 1924 | "multiIDX = pd.MultiIndex.from_product([timeWindow, ups], names=['交易周期', '上调幅度'])\n", 1925 | "leverNetValueDF_best = pd.DataFrame(index=Returns.index, columns=multiIDX)\n", 1926 | "leverDailyPnlDF_best = pd.DataFrame(index=Returns.index, columns=multiIDX) \n", 1927 | "leverDrawDownDF_best = pd.DataFrame(index=Returns.index, columns=multiIDX)" 1928 | ] 1929 | }, 1930 | { 1931 | "cell_type": "code", 1932 | "execution_count": null, 1933 | "metadata": { 1934 | "ExecuteTime": { 1935 | "end_time": "2020-07-07T05:19:19.888265Z", 1936 | "start_time": "2020-07-07T05:06:22.736596Z" 1937 | } 1938 | }, 1939 | "outputs": [], 1940 | "source": [ 1941 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 1942 | "factors = {'momentumX':True, 'momentumT':True, \n", 1943 | " 'reverseX':False, 'reverseT':False,\n", 1944 | " 'turnover':True, \n", 1945 | " 'copperGold':True, 'copperGas':True}\n", 1946 | "\n", 1947 | "for t in timeWindow:\n", 1948 | " for u in ups:\n", 1949 | " tradeDF, weightDF = AlgoLoop.AlgoTrade(Assets, leverReturns, leverCumReturns, Turnovers, \n", 1950 | " mode='ema', dt=t, up=u, thresholds=thrds, \n", 1951 | " factorDict=factors)\n", 1952 | " StatisticFunc.WeightPlot(tradeDF, weightDF, '杠杆+横截面动量+时序动量+换手率+铜金+铜油(指数权重)'+str(t+u))\n", 1953 | "\n", 1954 | " leverNetValueDF_best.loc[:, (t, u)] = tradeDF['投资组合净值'] / 10000 \n", 1955 | " leverDailyPnlDF_best.loc[:, (t, u)] = tradeDF['投资组合净值'] / tradeDF['投资组合净值'].shift(1) - 1.0\n", 1956 | " leverDrawDownDF_best.loc[:, (t, u)] = tradeDF['最大回撤'] " 1957 | ] 1958 | }, 1959 | { 1960 | "cell_type": "markdown", 1961 | "metadata": {}, 1962 | "source": [ 1963 | "## 回测表现汇总" 1964 | ] 1965 | }, 1966 | { 1967 | "cell_type": "code", 1968 | "execution_count": null, 1969 | "metadata": { 1970 | "ExecuteTime": { 1971 | "end_time": "2020-07-07T05:19:19.913623Z", 1972 | "start_time": "2020-07-07T05:19:19.890719Z" 1973 | }, 1974 | "scrolled": true 1975 | }, 1976 | "outputs": [], 1977 | "source": [ 1978 | "# 汇总\n", 1979 | "leverSummaryDF_best = pd.DataFrame(index=multiIDX)\n", 1980 | "\n", 1981 | "leverSummaryDF_best[\"年平均收益率\"] = leverDailyPnlDF_best.mean(axis=0).values * 250\n", 1982 | "leverSummaryDF_best[\"年平均标准差\"] = leverDailyPnlDF_best.std(axis=0).values * np.sqrt(250)\n", 1983 | "leverSummaryDF_best[\"无基准夏普比率\"] = leverSummaryDF_best[\"年平均收益率\"] / leverSummaryDF_best[\"年平均标准差\"]\n", 1984 | "leverSummaryDF_best[\"最大回撤\"] = leverDrawDownDF_best.min(axis=0).values\n", 1985 | "\n", 1986 | "leverSummaryDF_best" 1987 | ] 1988 | }, 1989 | { 1990 | "cell_type": "markdown", 1991 | "metadata": {}, 1992 | "source": [ 1993 | "## 各投资组合净值曲线" 1994 | ] 1995 | }, 1996 | { 1997 | "cell_type": "code", 1998 | "execution_count": null, 1999 | "metadata": { 2000 | "ExecuteTime": { 2001 | "end_time": "2020-07-07T05:19:20.640052Z", 2002 | "start_time": "2020-07-07T05:19:19.916770Z" 2003 | }, 2004 | "scrolled": false 2005 | }, 2006 | "outputs": [], 2007 | "source": [ 2008 | "fig = plt.figure(figsize=(16, 8), dpi=200)\n", 2009 | "\n", 2010 | "for col in leverNetValueDF_best.columns:\n", 2011 | " plt.plot(leverNetValueDF_best.index, leverNetValueDF_best[col], label=col)\n", 2012 | " \n", 2013 | "plt.plot(cumReturns.index, cumReturns['信用债3-5AAA'], lw=3.0, label='信用债3-5AAA')\n", 2014 | "\n", 2015 | "plt.xlabel('时间')\n", 2016 | "plt.ylabel('净值')\n", 2017 | "plt.ylim(0.0, 5.0)\n", 2018 | "plt.legend(loc='upper left')\n", 2019 | "plt.title('杠杆+横截面动量+时序动量+换手率+铜金+铜油(指数权重)')\n", 2020 | "plt.show()" 2021 | ] 2022 | }, 2023 | { 2024 | "cell_type": "code", 2025 | "execution_count": null, 2026 | "metadata": {}, 2027 | "outputs": [], 2028 | "source": [] 2029 | }, 2030 | { 2031 | "cell_type": "code", 2032 | "execution_count": null, 2033 | "metadata": {}, 2034 | "outputs": [], 2035 | "source": [] 2036 | } 2037 | ], 2038 | "metadata": { 2039 | "kernelspec": { 2040 | "display_name": "Python 3", 2041 | "language": "python", 2042 | "name": "python3" 2043 | }, 2044 | "language_info": { 2045 | "codemirror_mode": { 2046 | "name": "ipython", 2047 | "version": 3 2048 | }, 2049 | "file_extension": ".py", 2050 | "mimetype": "text/x-python", 2051 | "name": "python", 2052 | "nbconvert_exporter": "python", 2053 | "pygments_lexer": "ipython3", 2054 | "version": "3.7.7" 2055 | }, 2056 | "latex_envs": { 2057 | "LaTeX_envs_menu_present": true, 2058 | "autoclose": false, 2059 | "autocomplete": true, 2060 | "bibliofile": "biblio.bib", 2061 | "cite_by": "apalike", 2062 | "current_citInitial": 1, 2063 | "eqLabelWithNumbers": true, 2064 | "eqNumInitial": 1, 2065 | "hotkeys": { 2066 | "equation": "Ctrl-E", 2067 | "itemize": "Ctrl-I" 2068 | }, 2069 | "labels_anchors": false, 2070 | "latex_user_defs": false, 2071 | "report_style_numbering": false, 2072 | "user_envs_cfg": false 2073 | }, 2074 | "toc": { 2075 | "base_numbering": 1, 2076 | "nav_menu": {}, 2077 | "number_sections": true, 2078 | "sideBar": true, 2079 | "skip_h1_title": false, 2080 | "title_cell": "Table of Contents", 2081 | "title_sidebar": "Contents", 2082 | "toc_cell": false, 2083 | "toc_position": { 2084 | "height": "calc(100% - 180px)", 2085 | "left": "10px", 2086 | "top": "150px", 2087 | "width": "301px" 2088 | }, 2089 | "toc_section_display": true, 2090 | "toc_window_display": true 2091 | } 2092 | }, 2093 | "nbformat": 4, 2094 | "nbformat_minor": 4 2095 | } 2096 | -------------------------------------------------------------------------------- /RiskParityModel_Summary.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "ExecuteTime": { 8 | "end_time": "2020-08-31T07:28:37.243958Z", 9 | "start_time": "2020-08-31T07:28:35.539877Z" 10 | } 11 | }, 12 | "outputs": [], 13 | "source": [ 14 | "import numpy as np\n", 15 | "import pandas as pd\n", 16 | "import matplotlib\n", 17 | "import matplotlib.pyplot as plt\n", 18 | "import seaborn as sns\n", 19 | "import AlgoLoop\n", 20 | "import StatisticFunc\n", 21 | "\n", 22 | "plt.style.use('seaborn-deep') # 绘图风格\n", 23 | "matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 字体雅黑\n", 24 | "matplotlib.rcParams['font.family'] = 'sans-serif'\n", 25 | "matplotlib.rcParams['axes.unicode_minus'] = False # 处理负号" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": {}, 31 | "source": [ 32 | "# 预处理" 33 | ] 34 | }, 35 | { 36 | "cell_type": "markdown", 37 | "metadata": {}, 38 | "source": [ 39 | "## 提取并处理数据" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": {}, 45 | "source": [ 46 | "### 各种利率" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": null, 52 | "metadata": { 53 | "ExecuteTime": { 54 | "end_time": "2020-08-31T07:28:37.391604Z", 55 | "start_time": "2020-08-31T07:28:37.247752Z" 56 | } 57 | }, 58 | "outputs": [], 59 | "source": [ 60 | "# GC007 利率\n", 61 | "GCRates = pd.read_excel(io=\"Raw/GC007利率.xlsx\") # 读取数据\n", 62 | "GCRates = GCRates.drop([0, 1, 2], axis=0) # 删除多余行\n", 63 | "GCRates.columns = ['日期', 'GC007'] # 修改列名\n", 64 | "GCRates[\"日期\"] = pd.DatetimeIndex(GCRates[\"日期\"]) # 类型转换\n", 65 | "GCRates = GCRates.set_index(\"日期\") # 设置索引" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": null, 71 | "metadata": { 72 | "ExecuteTime": { 73 | "end_time": "2020-08-31T07:28:37.489320Z", 74 | "start_time": "2020-08-31T07:28:37.395003Z" 75 | } 76 | }, 77 | "outputs": [], 78 | "source": [ 79 | "# 10年国债收益率\n", 80 | "CNRates = pd.read_excel(io=\"Raw/10年国债到期收益率.xls\") # 读取数据\n", 81 | "CNRates.columns = ['日期', '十年国债收益率'] # 修改列名\n", 82 | "CNRates = CNRates.drop([0, 3870, 3871], axis=0) # 删除多余行\n", 83 | "CNRates[\"日期\"] = pd.DatetimeIndex(CNRates[\"日期\"]) # 类型转换\n", 84 | "CNRates = CNRates.set_index(\"日期\") # 设置索引" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": null, 90 | "metadata": { 91 | "ExecuteTime": { 92 | "end_time": "2020-08-31T07:28:37.783592Z", 93 | "start_time": "2020-08-31T07:28:37.492443Z" 94 | } 95 | }, 96 | "outputs": [], 97 | "source": [ 98 | "# 10年美债收益率\n", 99 | "USRates = pd.read_excel(io=\"Raw/10年美债到期收益率.xlsx\") # 读取数据\n", 100 | "USRates.columns = ['日期', '十年美债收益率'] # 修改列名\n", 101 | "USRates = USRates.drop([0, 6263, 6264], axis=0) # 删除多余行\n", 102 | "USRates[\"日期\"] = pd.DatetimeIndex(USRates[\"日期\"]) # 类型转换\n", 103 | "USRates = USRates.set_index(\"日期\") # 设置索引" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": null, 109 | "metadata": { 110 | "ExecuteTime": { 111 | "end_time": "2020-08-31T07:28:37.795641Z", 112 | "start_time": "2020-08-31T07:28:37.786418Z" 113 | } 114 | }, 115 | "outputs": [], 116 | "source": [ 117 | "# 合并利率\n", 118 | "Rates = GCRates.merge(CNRates, how='left', left_index=True, right_index=True)\n", 119 | "Rates = Rates.merge(USRates, how='left', left_index=True, right_index=True)" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "### 权益类资产换手率" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": null, 132 | "metadata": { 133 | "ExecuteTime": { 134 | "end_time": "2020-08-31T07:28:37.964065Z", 135 | "start_time": "2020-08-31T07:28:37.800352Z" 136 | } 137 | }, 138 | "outputs": [], 139 | "source": [ 140 | "Turnovers = pd.read_excel(io=\"Raw/资产换手率.xlsx\") # 读取数据\n", 141 | "Turnovers = Turnovers.drop([0], axis=0) # 删除多余行\n", 142 | "Turnovers[\"日期\"] = pd.DatetimeIndex(Turnovers[\"日期\"]) # 类型转换\n", 143 | "Turnovers = Turnovers.set_index(\"日期\") # 设置索引" 144 | ] 145 | }, 146 | { 147 | "cell_type": "code", 148 | "execution_count": null, 149 | "metadata": { 150 | "ExecuteTime": { 151 | "end_time": "2020-08-31T07:28:37.971255Z", 152 | "start_time": "2020-08-31T07:28:37.966551Z" 153 | } 154 | }, 155 | "outputs": [], 156 | "source": [ 157 | "# 时间对齐\n", 158 | "Turnovers = Turnovers.loc[Rates.index, :]" 159 | ] 160 | }, 161 | { 162 | "cell_type": "markdown", 163 | "metadata": {}, 164 | "source": [ 165 | "### 铁矿石价格指数" 166 | ] 167 | }, 168 | { 169 | "cell_type": "code", 170 | "execution_count": null, 171 | "metadata": { 172 | "ExecuteTime": { 173 | "end_time": "2020-08-31T07:28:38.049025Z", 174 | "start_time": "2020-08-31T07:28:37.975185Z" 175 | } 176 | }, 177 | "outputs": [], 178 | "source": [ 179 | "IronStone = pd.read_excel(io=\"Raw/铁矿石价格指数.xls\") # 读取数据\n", 180 | "IronStone = IronStone.drop([0, 2642, 2643], axis=0) # 删除多余行\n", 181 | "IronStone.columns=['日期', '铁矿石期货'] # 修改列名\n", 182 | "IronStone[\"日期\"] = pd.DatetimeIndex(IronStone[\"日期\"]) # 类型转换\n", 183 | "IronStone = IronStone.set_index(\"日期\") # 设置索引" 184 | ] 185 | }, 186 | { 187 | "cell_type": "markdown", 188 | "metadata": {}, 189 | "source": [ 190 | "### 各资产收盘价" 191 | ] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "execution_count": null, 196 | "metadata": { 197 | "ExecuteTime": { 198 | "end_time": "2020-08-31T07:48:58.643061Z", 199 | "start_time": "2020-08-31T07:48:58.313830Z" 200 | } 201 | }, 202 | "outputs": [], 203 | "source": [ 204 | "Assets = pd.read_excel(io=\"Raw/资产收盘价.xlsx\") # 读取数据\n", 205 | "Assets = Assets.drop([0], axis=0) # 删除多余行\n", 206 | "Assets[\"日期\"] = pd.DatetimeIndex(Assets[\"日期\"]) # 类型转换\n", 207 | "Assets = Assets.set_index(\"日期\") # 设置索引\n", 208 | "Assets = Assets.loc[Rates.index, :] # 时间对齐" 209 | ] 210 | }, 211 | { 212 | "cell_type": "code", 213 | "execution_count": null, 214 | "metadata": { 215 | "ExecuteTime": { 216 | "end_time": "2020-08-31T07:48:58.940736Z", 217 | "start_time": "2020-08-31T07:48:58.932003Z" 218 | } 219 | }, 220 | "outputs": [], 221 | "source": [ 222 | "# 整合铁矿石数据\n", 223 | "Assets = Assets.drop('中信证券铁矿石', axis=1)\n", 224 | "Assets = Assets.merge(IronStone, how='left', left_index=True, right_index=True)\n", 225 | "\n", 226 | "# 填充铁矿石2011年前缺失数据\n", 227 | "Assets['铁矿石期货'] = Assets['铁矿石期货'].fillna(method='bfill')" 228 | ] 229 | }, 230 | { 231 | "cell_type": "markdown", 232 | "metadata": {}, 233 | "source": [ 234 | "### 十年国债&美债价格指数" 235 | ] 236 | }, 237 | { 238 | "cell_type": "code", 239 | "execution_count": null, 240 | "metadata": { 241 | "ExecuteTime": { 242 | "end_time": "2020-08-31T07:48:59.900128Z", 243 | "start_time": "2020-08-31T07:48:59.882919Z" 244 | } 245 | }, 246 | "outputs": [], 247 | "source": [ 248 | "HoldPeriod = (Assets.index - Assets.index[0]).days\n", 249 | "\n", 250 | "# 计算十年国债\n", 251 | "Assets['10年国债'] = 100 - (Rates['十年国债收益率'] - 3.0) * 8.2 + 3.0 * HoldPeriod / 365.0\n", 252 | "Assets['10年国债'] = Assets['10年国债'].fillna(method='ffill')\n", 253 | "\n", 254 | "#计算十年美债\n", 255 | "Assets['10年美债'] = 100 - (Rates['十年美债收益率'] - 3.0) * 8.2 + 3.0 * HoldPeriod / 365.0\n", 256 | "Assets['10年美债'] = Assets['10年美债'].fillna(method='ffill')" 257 | ] 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": null, 262 | "metadata": { 263 | "ExecuteTime": { 264 | "end_time": "2020-08-31T07:49:27.424338Z", 265 | "start_time": "2020-08-31T07:49:27.407874Z" 266 | } 267 | }, 268 | "outputs": [], 269 | "source": [ 270 | "# 替换上证十年国债指数\n", 271 | "Assets = Assets.drop('上证10年国债', axis=1)\n", 272 | "Assets.head()" 273 | ] 274 | }, 275 | { 276 | "cell_type": "markdown", 277 | "metadata": {}, 278 | "source": [ 279 | "### 美元汇率" 280 | ] 281 | }, 282 | { 283 | "cell_type": "code", 284 | "execution_count": null, 285 | "metadata": { 286 | "ExecuteTime": { 287 | "end_time": "2020-08-31T07:28:38.691256Z", 288 | "start_time": "2020-08-31T07:28:38.488189Z" 289 | } 290 | }, 291 | "outputs": [], 292 | "source": [ 293 | "FXRates = pd.read_excel(io=\"Raw/美元汇率.xlsx\")\n", 294 | "FXRates = FXRates.drop([0, 1, 2], axis=0)\n", 295 | "FXRates.columns = ['日期', '美元指数', '美元汇率'] \n", 296 | "FXRates['日期'] = pd.DatetimeIndex(FXRates['日期'])\n", 297 | "FXRates = FXRates.set_index('日期')" 298 | ] 299 | }, 300 | { 301 | "cell_type": "markdown", 302 | "metadata": {}, 303 | "source": [ 304 | "## 计算各资产收益率" 305 | ] 306 | }, 307 | { 308 | "cell_type": "markdown", 309 | "metadata": {}, 310 | "source": [ 311 | "### 日内损益\n", 312 | "\n", 313 | "- 去除WTI原油期货\n", 314 | "- 去除COMEX铜期货\n", 315 | "- 去除铁矿石期货" 316 | ] 317 | }, 318 | { 319 | "cell_type": "code", 320 | "execution_count": null, 321 | "metadata": { 322 | "ExecuteTime": { 323 | "end_time": "2020-08-31T07:28:38.705109Z", 324 | "start_time": "2020-08-31T07:28:38.692938Z" 325 | } 326 | }, 327 | "outputs": [], 328 | "source": [ 329 | "Returns = Assets.pct_change(axis=0)\n", 330 | "Returns = Returns.dropna(axis=0, how='all') # 删除无数据日" 331 | ] 332 | }, 333 | { 334 | "cell_type": "markdown", 335 | "metadata": {}, 336 | "source": [ 337 | "### 累计损益" 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": null, 343 | "metadata": { 344 | "ExecuteTime": { 345 | "end_time": "2020-08-31T07:28:38.715237Z", 346 | "start_time": "2020-08-31T07:28:38.706744Z" 347 | } 348 | }, 349 | "outputs": [], 350 | "source": [ 351 | "cumReturns = (1.0 + Returns)\n", 352 | "cumReturns = cumReturns.fillna(1.0) # 填充空值\n", 353 | "cumReturns = cumReturns.cumprod() # 计算各资产累计收益率" 354 | ] 355 | }, 356 | { 357 | "cell_type": "markdown", 358 | "metadata": {}, 359 | "source": [ 360 | "### 杠杆调整后的债券净值" 361 | ] 362 | }, 363 | { 364 | "cell_type": "code", 365 | "execution_count": null, 366 | "metadata": { 367 | "ExecuteTime": { 368 | "end_time": "2020-08-31T07:28:38.720476Z", 369 | "start_time": "2020-08-31T07:28:38.716961Z" 370 | } 371 | }, 372 | "outputs": [], 373 | "source": [ 374 | "lever = 2.0 # 杠杆(额外)\n", 375 | "leverReturns = Returns.copy() # 创建副本 \n", 376 | "leverCumReturns = cumReturns.copy() " 377 | ] 378 | }, 379 | { 380 | "cell_type": "code", 381 | "execution_count": null, 382 | "metadata": { 383 | "ExecuteTime": { 384 | "end_time": "2020-08-31T07:28:38.737686Z", 385 | "start_time": "2020-08-31T07:28:38.722198Z" 386 | } 387 | }, 388 | "outputs": [], 389 | "source": [ 390 | "# 更新杠杆调整后的债券净值\n", 391 | "leverReturns['10年国债'] = Returns['10年国债'] * (1.0 + lever) - Rates.loc[Returns.index, 'GC007'] * lever / (365.0 * 100)\n", 392 | "leverReturns['信用债3-5AAA'] = Returns['信用债3-5AAA'] * (1.0 + lever) - Rates.loc[Returns.index, 'GC007'] * lever / (365.0 * 100)\n", 393 | "\n", 394 | "# 更新累计净值\n", 395 | "leverCumReturns = (1.0 + leverReturns)\n", 396 | "leverCumReturns = leverCumReturns.fillna(1.0) # 填充空值\n", 397 | "leverCumReturns = leverCumReturns.cumprod() # 计算各资产累计收益率" 398 | ] 399 | }, 400 | { 401 | "cell_type": "code", 402 | "execution_count": null, 403 | "metadata": { 404 | "ExecuteTime": { 405 | "end_time": "2020-08-31T08:07:34.938007Z", 406 | "start_time": "2020-08-31T08:07:34.456144Z" 407 | } 408 | }, 409 | "outputs": [], 410 | "source": [ 411 | "fig, ax1 = plt.subplots(1, 1, figsize=(16,6), dpi=150)\n", 412 | "ax1.plot(cumReturns.index, cumReturns['10年国债'], label='10年国债', lw=1.5)\n", 413 | "ax1.plot(leverCumReturns_A.index, leverCumReturns_A['10年国债'], label='10年国债(杠杆)', lw=1.5)\n", 414 | "ax1.legend()\n", 415 | "\n", 416 | "ax2 = ax1.twinx()\n", 417 | "ax2.plot(GCRates.index, GCRates, label='GC007', color='orange', lw=0.6)\n", 418 | "ax2.legend()\n", 419 | "\n", 420 | "plt.show()\n" 421 | ] 422 | }, 423 | { 424 | "cell_type": "markdown", 425 | "metadata": {}, 426 | "source": [ 427 | "# 指数平均的效果" 428 | ] 429 | }, 430 | { 431 | "cell_type": "markdown", 432 | "metadata": {}, 433 | "source": [ 434 | "## 模型A:国内全资产(无指数平均)" 435 | ] 436 | }, 437 | { 438 | "cell_type": "code", 439 | "execution_count": null, 440 | "metadata": { 441 | "ExecuteTime": { 442 | "end_time": "2020-08-31T07:28:38.744635Z", 443 | "start_time": "2020-08-31T07:28:38.739274Z" 444 | } 445 | }, 446 | "outputs": [], 447 | "source": [ 448 | "leverReturns_A = leverReturns.drop(['标普500', '10年美债'], axis=1)\n", 449 | "leverCumReturns_A = leverCumReturns.drop(['标普500', '10年美债'], axis=1)" 450 | ] 451 | }, 452 | { 453 | "cell_type": "markdown", 454 | "metadata": {}, 455 | "source": [ 456 | "### 程序运行" 457 | ] 458 | }, 459 | { 460 | "cell_type": "code", 461 | "execution_count": null, 462 | "metadata": { 463 | "ExecuteTime": { 464 | "end_time": "2020-08-31T07:30:01.521312Z", 465 | "start_time": "2020-08-31T07:28:38.747184Z" 466 | } 467 | }, 468 | "outputs": [], 469 | "source": [ 470 | "tradeDF_A, weightDF_A = AlgoLoop.AlgoTrade(Assets, leverReturns_A, leverCumReturns_A, Turnovers, FXRates, mode='plain')" 471 | ] 472 | }, 473 | { 474 | "cell_type": "code", 475 | "execution_count": null, 476 | "metadata": { 477 | "ExecuteTime": { 478 | "end_time": "2020-08-31T07:41:30.602649Z", 479 | "start_time": "2020-08-31T07:41:30.541938Z" 480 | } 481 | }, 482 | "outputs": [], 483 | "source": [ 484 | "tradeDF_A.to_csv('模型A_净值.csv', encoding='utf_8_sig')" 485 | ] 486 | }, 487 | { 488 | "cell_type": "code", 489 | "execution_count": null, 490 | "metadata": { 491 | "ExecuteTime": { 492 | "end_time": "2020-08-31T07:30:02.145808Z", 493 | "start_time": "2020-08-31T07:30:01.523907Z" 494 | } 495 | }, 496 | "outputs": [], 497 | "source": [ 498 | "StatisticFunc.WeightPlot(tradeDF_A, weightDF_A, '模型A')" 499 | ] 500 | }, 501 | { 502 | "cell_type": "markdown", 503 | "metadata": {}, 504 | "source": [ 505 | "### 回测表现汇总" 506 | ] 507 | }, 508 | { 509 | "cell_type": "code", 510 | "execution_count": null, 511 | "metadata": { 512 | "ExecuteTime": { 513 | "end_time": "2020-08-31T07:30:02.191804Z", 514 | "start_time": "2020-08-31T07:30:02.148133Z" 515 | } 516 | }, 517 | "outputs": [], 518 | "source": [ 519 | "smryDF_A = StatisticFunc.summaryDF(tradeDF_A)\n", 520 | "pfmcDF_A = StatisticFunc.performanceDF(smryDF_A, tradeDF_A, name='模型A')" 521 | ] 522 | }, 523 | { 524 | "cell_type": "code", 525 | "execution_count": null, 526 | "metadata": { 527 | "ExecuteTime": { 528 | "end_time": "2020-08-31T07:30:02.201059Z", 529 | "start_time": "2020-08-31T07:30:02.193489Z" 530 | } 531 | }, 532 | "outputs": [], 533 | "source": [ 534 | "smryDF_A" 535 | ] 536 | }, 537 | { 538 | "cell_type": "code", 539 | "execution_count": null, 540 | "metadata": { 541 | "ExecuteTime": { 542 | "end_time": "2020-08-31T07:30:02.214737Z", 543 | "start_time": "2020-08-31T07:30:02.207373Z" 544 | } 545 | }, 546 | "outputs": [], 547 | "source": [ 548 | "pfmcDF_A" 549 | ] 550 | }, 551 | { 552 | "cell_type": "markdown", 553 | "metadata": {}, 554 | "source": [ 555 | "### 收益率贡献度" 556 | ] 557 | }, 558 | { 559 | "cell_type": "code", 560 | "execution_count": null, 561 | "metadata": { 562 | "ExecuteTime": { 563 | "end_time": "2020-08-31T07:30:02.236995Z", 564 | "start_time": "2020-08-31T07:30:02.219118Z" 565 | }, 566 | "scrolled": true 567 | }, 568 | "outputs": [], 569 | "source": [ 570 | "annualContrb_A = StatisticFunc.AnnualContribution(tradeDF_A)" 571 | ] 572 | }, 573 | { 574 | "cell_type": "code", 575 | "execution_count": null, 576 | "metadata": { 577 | "ExecuteTime": { 578 | "end_time": "2020-08-31T07:30:04.665883Z", 579 | "start_time": "2020-08-31T07:30:02.239536Z" 580 | } 581 | }, 582 | "outputs": [], 583 | "source": [ 584 | "StatisticFunc.BarPlot(annualContrb_A, '模型A')" 585 | ] 586 | }, 587 | { 588 | "cell_type": "markdown", 589 | "metadata": {}, 590 | "source": [ 591 | "### 投资组合净值曲线" 592 | ] 593 | }, 594 | { 595 | "cell_type": "code", 596 | "execution_count": null, 597 | "metadata": { 598 | "ExecuteTime": { 599 | "end_time": "2020-08-31T07:30:04.950750Z", 600 | "start_time": "2020-08-31T07:30:04.668840Z" 601 | } 602 | }, 603 | "outputs": [], 604 | "source": [ 605 | "fig = plt.figure(figsize=(16, 6))\n", 606 | "\n", 607 | "plt.plot(tradeDF_A.index, tradeDF_A['投资组合净值']/10000, label='模型A')\n", 608 | " \n", 609 | "plt.plot(cumReturns.index, cumReturns['沪深300'], label='沪深300')\n", 610 | "plt.plot(cumReturns.index, cumReturns['10年国债'], label='10年国债')\n", 611 | "\n", 612 | "plt.xlabel('时间')\n", 613 | "plt.ylabel('净值')\n", 614 | "plt.grid(True)\n", 615 | "plt.legend(loc='upper left')\n", 616 | "plt.title('净值曲线--模型A')\n", 617 | "plt.savefig('Pics/净值曲线_模型A.png')" 618 | ] 619 | }, 620 | { 621 | "cell_type": "markdown", 622 | "metadata": {}, 623 | "source": [ 624 | "## 模型B:国内全资产(指数平均)" 625 | ] 626 | }, 627 | { 628 | "cell_type": "code", 629 | "execution_count": null, 630 | "metadata": { 631 | "ExecuteTime": { 632 | "end_time": "2020-08-31T07:30:04.956992Z", 633 | "start_time": "2020-08-31T07:30:04.952565Z" 634 | } 635 | }, 636 | "outputs": [], 637 | "source": [ 638 | "leverReturns_B = leverReturns.drop(['标普500', '10年美债'], axis=1)\n", 639 | "leverCumReturns_B = leverCumReturns.drop(['标普500', '10年美债'], axis=1)" 640 | ] 641 | }, 642 | { 643 | "cell_type": "markdown", 644 | "metadata": {}, 645 | "source": [ 646 | "### 程序运行" 647 | ] 648 | }, 649 | { 650 | "cell_type": "code", 651 | "execution_count": null, 652 | "metadata": { 653 | "ExecuteTime": { 654 | "end_time": "2020-08-31T07:31:12.691437Z", 655 | "start_time": "2020-08-31T07:30:04.958971Z" 656 | } 657 | }, 658 | "outputs": [], 659 | "source": [ 660 | "tradeDF_B, weightDF_B = AlgoLoop.AlgoTrade(Assets, leverReturns_B, leverCumReturns_B, Turnovers, FXRates, mode='ema')" 661 | ] 662 | }, 663 | { 664 | "cell_type": "code", 665 | "execution_count": null, 666 | "metadata": { 667 | "ExecuteTime": { 668 | "end_time": "2020-08-31T07:31:13.220436Z", 669 | "start_time": "2020-08-31T07:31:12.693847Z" 670 | } 671 | }, 672 | "outputs": [], 673 | "source": [ 674 | "StatisticFunc.WeightPlot(tradeDF_B, weightDF_B, '模型B')" 675 | ] 676 | }, 677 | { 678 | "cell_type": "markdown", 679 | "metadata": {}, 680 | "source": [ 681 | "### 回测表现汇总" 682 | ] 683 | }, 684 | { 685 | "cell_type": "code", 686 | "execution_count": null, 687 | "metadata": { 688 | "ExecuteTime": { 689 | "end_time": "2020-08-31T07:31:13.265818Z", 690 | "start_time": "2020-08-31T07:31:13.222237Z" 691 | } 692 | }, 693 | "outputs": [], 694 | "source": [ 695 | "smryDF_B = StatisticFunc.summaryDF(tradeDF_B)\n", 696 | "pfmcDF_B = StatisticFunc.performanceDF(smryDF_B, tradeDF_B, name='国内全资产(指数移动平均)')" 697 | ] 698 | }, 699 | { 700 | "cell_type": "code", 701 | "execution_count": null, 702 | "metadata": { 703 | "ExecuteTime": { 704 | "end_time": "2020-08-31T07:31:13.275123Z", 705 | "start_time": "2020-08-31T07:31:13.267594Z" 706 | } 707 | }, 708 | "outputs": [], 709 | "source": [ 710 | "smryDF_B" 711 | ] 712 | }, 713 | { 714 | "cell_type": "code", 715 | "execution_count": null, 716 | "metadata": { 717 | "ExecuteTime": { 718 | "end_time": "2020-08-31T07:31:13.284221Z", 719 | "start_time": "2020-08-31T07:31:13.276885Z" 720 | } 721 | }, 722 | "outputs": [], 723 | "source": [ 724 | "pfmcDF_B" 725 | ] 726 | }, 727 | { 728 | "cell_type": "markdown", 729 | "metadata": {}, 730 | "source": [ 731 | "### 收益率贡献度" 732 | ] 733 | }, 734 | { 735 | "cell_type": "code", 736 | "execution_count": null, 737 | "metadata": { 738 | "ExecuteTime": { 739 | "end_time": "2020-08-31T07:31:13.303792Z", 740 | "start_time": "2020-08-31T07:31:13.285939Z" 741 | }, 742 | "scrolled": true 743 | }, 744 | "outputs": [], 745 | "source": [ 746 | "annualContrb_B = StatisticFunc.AnnualContribution(tradeDF_B)" 747 | ] 748 | }, 749 | { 750 | "cell_type": "code", 751 | "execution_count": null, 752 | "metadata": { 753 | "ExecuteTime": { 754 | "end_time": "2020-08-31T07:31:15.759866Z", 755 | "start_time": "2020-08-31T07:31:13.305343Z" 756 | } 757 | }, 758 | "outputs": [], 759 | "source": [ 760 | "StatisticFunc.BarPlot(annualContrb_B, '模型B')" 761 | ] 762 | }, 763 | { 764 | "cell_type": "markdown", 765 | "metadata": {}, 766 | "source": [ 767 | "### 投资组合净值曲线" 768 | ] 769 | }, 770 | { 771 | "cell_type": "code", 772 | "execution_count": null, 773 | "metadata": { 774 | "ExecuteTime": { 775 | "end_time": "2020-08-31T07:31:16.068248Z", 776 | "start_time": "2020-08-31T07:31:15.762062Z" 777 | } 778 | }, 779 | "outputs": [], 780 | "source": [ 781 | "fig = plt.figure(figsize=(16, 6))\n", 782 | "\n", 783 | "plt.plot(tradeDF_B.index, tradeDF_B['投资组合净值']/10000, label='模型B(指数平均)')\n", 784 | " \n", 785 | "plt.plot(tradeDF_A.index, tradeDF_A['投资组合净值']/10000, ls='--', label='模型A(基础模型)') \n", 786 | "plt.plot(cumReturns.index, cumReturns['沪深300'], label='沪深300')\n", 787 | "plt.plot(cumReturns.index, cumReturns['10年国债'], label='10年国债')\n", 788 | "\n", 789 | "plt.xlabel('时间')\n", 790 | "plt.ylabel('净值')\n", 791 | "plt.grid(True)\n", 792 | "plt.legend(loc='upper left')\n", 793 | "plt.title('净值曲线--模型B')\n", 794 | "plt.savefig('Pics/净值曲线_模型B.png')" 795 | ] 796 | }, 797 | { 798 | "cell_type": "markdown", 799 | "metadata": {}, 800 | "source": [ 801 | "# 各类资产的特性与选择\n", 802 | "\n", 803 | "- 有商品期货\n", 804 | "- 无商品期货" 805 | ] 806 | }, 807 | { 808 | "cell_type": "markdown", 809 | "metadata": {}, 810 | "source": [ 811 | "## 各资产的年度表现" 812 | ] 813 | }, 814 | { 815 | "cell_type": "markdown", 816 | "metadata": {}, 817 | "source": [ 818 | "### 年化收益" 819 | ] 820 | }, 821 | { 822 | "cell_type": "code", 823 | "execution_count": null, 824 | "metadata": { 825 | "ExecuteTime": { 826 | "end_time": "2020-08-31T07:31:16.072834Z", 827 | "start_time": "2020-08-31T07:31:16.070412Z" 828 | } 829 | }, 830 | "outputs": [], 831 | "source": [ 832 | "# annualR = StatisticFunc.AnnualReturns(cumReturns)\n", 833 | "# annualR" 834 | ] 835 | }, 836 | { 837 | "cell_type": "markdown", 838 | "metadata": {}, 839 | "source": [ 840 | "### 年化波动率" 841 | ] 842 | }, 843 | { 844 | "cell_type": "code", 845 | "execution_count": null, 846 | "metadata": { 847 | "ExecuteTime": { 848 | "end_time": "2020-08-31T07:31:16.079730Z", 849 | "start_time": "2020-08-31T07:31:16.074683Z" 850 | } 851 | }, 852 | "outputs": [], 853 | "source": [ 854 | "# annualV = StatisticFunc.AnnualVolatility(cumReturns)\n", 855 | "# annualV" 856 | ] 857 | }, 858 | { 859 | "cell_type": "markdown", 860 | "metadata": {}, 861 | "source": [ 862 | "### 汇总" 863 | ] 864 | }, 865 | { 866 | "cell_type": "code", 867 | "execution_count": null, 868 | "metadata": { 869 | "ExecuteTime": { 870 | "end_time": "2020-08-31T07:31:16.083377Z", 871 | "start_time": "2020-08-31T07:31:16.081294Z" 872 | } 873 | }, 874 | "outputs": [], 875 | "source": [ 876 | "# annualDF = pd.DataFrame(index=['年化收益', '年化波动率', '信息比'], columns=annualR.columns)\n", 877 | "# annualDF.loc['年化收益', :] = annualR.mean(axis=0)\n", 878 | "# annualDF.loc['年化波动率', :] = annualV.mean(axis=0)\n", 879 | "# annualDF.loc['信息比', :] = annualDF.loc['年化收益', :] / annualDF.loc['年化波动率', :]" 880 | ] 881 | }, 882 | { 883 | "cell_type": "code", 884 | "execution_count": null, 885 | "metadata": { 886 | "ExecuteTime": { 887 | "end_time": "2020-08-31T07:31:16.086931Z", 888 | "start_time": "2020-08-31T07:31:16.084998Z" 889 | } 890 | }, 891 | "outputs": [], 892 | "source": [ 893 | "# annualDF" 894 | ] 895 | }, 896 | { 897 | "cell_type": "markdown", 898 | "metadata": {}, 899 | "source": [ 900 | "## 模型C:剔除部分商品期货" 901 | ] 902 | }, 903 | { 904 | "cell_type": "code", 905 | "execution_count": null, 906 | "metadata": { 907 | "ExecuteTime": { 908 | "end_time": "2020-08-31T07:31:16.098813Z", 909 | "start_time": "2020-08-31T07:31:16.088619Z" 910 | } 911 | }, 912 | "outputs": [], 913 | "source": [ 914 | "# 仅保留黄金期货\n", 915 | "leverReturns_C1 = leverReturns_B.drop(['中信证券COMEX铜期货', '铁矿石期货', '中信证券WTI原油期货'], axis=1)\n", 916 | "leverCumReturns_C1 = leverCumReturns_B.drop(['中信证券COMEX铜期货', '铁矿石期货', '中信证券WTI原油期货'], axis=1)\n", 917 | "\n", 918 | "# 仅保留铁矿石期货\n", 919 | "leverReturns_C2 = leverReturns_B.drop(['中信证券COMEX铜期货', '中信证券COMEX黄金期货', '中信证券WTI原油期货'], axis=1)\n", 920 | "leverCumReturns_C2 = leverCumReturns_B.drop(['中信证券COMEX铜期货', '中信证券COMEX黄金期货', '中信证券WTI原油期货'], axis=1)\n", 921 | "\n", 922 | "# 保留黄金和铁矿石\n", 923 | "leverReturns_C3 = leverReturns_B.drop(['中信证券COMEX黄金期货', '铁矿石期货', '中信证券WTI原油期货'], axis=1)\n", 924 | "leverCumReturns_C3 = leverCumReturns_B.drop(['中信证券COMEX黄金期货', '铁矿石期货', '中信证券WTI原油期货'], axis=1)\n", 925 | "\n", 926 | "# 剔除所有商品期货\n", 927 | "leverReturns_C4 = leverReturns_B.drop(['中信证券COMEX铜期货', '中信证券COMEX黄金期货', '铁矿石期货', '中信证券WTI原油期货'], axis=1)\n", 928 | "leverCumReturns_C4 = leverCumReturns_B.drop(['中信证券COMEX铜期货', '中信证券COMEX黄金期货', '铁矿石期货', '中信证券WTI原油期货'], axis=1)" 929 | ] 930 | }, 931 | { 932 | "cell_type": "markdown", 933 | "metadata": {}, 934 | "source": [ 935 | "### 程序运行" 936 | ] 937 | }, 938 | { 939 | "cell_type": "code", 940 | "execution_count": null, 941 | "metadata": { 942 | "ExecuteTime": { 943 | "end_time": "2020-08-31T07:33:54.562440Z", 944 | "start_time": "2020-08-31T07:31:16.100629Z" 945 | } 946 | }, 947 | "outputs": [], 948 | "source": [ 949 | "tradeDF_C1, weightDF_C1 = AlgoLoop.AlgoTrade(Assets, leverReturns_C1, leverCumReturns_C1, \n", 950 | " Turnovers, FXRates, mode='ema')\n", 951 | "tradeDF_C2, weightDF_C2 = AlgoLoop.AlgoTrade(Assets, leverReturns_C2, leverCumReturns_C2, \n", 952 | " Turnovers, FXRates, mode='ema')\n", 953 | "tradeDF_C3, weightDF_C3 = AlgoLoop.AlgoTrade(Assets, leverReturns_C3, leverCumReturns_C3, \n", 954 | " Turnovers, FXRates, mode='ema')\n", 955 | "tradeDF_C4, weightDF_C4 = AlgoLoop.AlgoTrade(Assets, leverReturns_C4, leverCumReturns_C4, \n", 956 | " Turnovers, FXRates, mode='ema')" 957 | ] 958 | }, 959 | { 960 | "cell_type": "code", 961 | "execution_count": null, 962 | "metadata": { 963 | "ExecuteTime": { 964 | "end_time": "2020-08-31T07:33:56.567634Z", 965 | "start_time": "2020-08-31T07:33:54.565045Z" 966 | }, 967 | "scrolled": false 968 | }, 969 | "outputs": [], 970 | "source": [ 971 | "StatisticFunc.WeightPlot(tradeDF_C1, weightDF_C1, '模型C1(仅保留黄金)')\n", 972 | "StatisticFunc.WeightPlot(tradeDF_C2, weightDF_C2, '模型C2(仅保留铁矿石)')\n", 973 | "StatisticFunc.WeightPlot(tradeDF_C3, weightDF_C3, '模型C3(仅保留铜)')\n", 974 | "StatisticFunc.WeightPlot(tradeDF_C4, weightDF_C4, '模型C4(剔除所有商品)')" 975 | ] 976 | }, 977 | { 978 | "cell_type": "markdown", 979 | "metadata": {}, 980 | "source": [ 981 | "### 回测表现汇总" 982 | ] 983 | }, 984 | { 985 | "cell_type": "code", 986 | "execution_count": null, 987 | "metadata": { 988 | "ExecuteTime": { 989 | "end_time": "2020-08-31T07:33:56.765257Z", 990 | "start_time": "2020-08-31T07:33:56.570101Z" 991 | } 992 | }, 993 | "outputs": [], 994 | "source": [ 995 | "smryDF_C1 = StatisticFunc.summaryDF(tradeDF_C1)\n", 996 | "pfmcDF_C1 = StatisticFunc.performanceDF(smryDF_C1, tradeDF_C1, name='模型C1(仅保留黄金)')\n", 997 | "\n", 998 | "smryDF_C2 = StatisticFunc.summaryDF(tradeDF_C2)\n", 999 | "pfmcDF_C2 = StatisticFunc.performanceDF(smryDF_C2, tradeDF_C2, name='模型C2(仅保留铁矿石)')\n", 1000 | "\n", 1001 | "smryDF_C3 = StatisticFunc.summaryDF(tradeDF_C3)\n", 1002 | "pfmcDF_C3 = StatisticFunc.performanceDF(smryDF_C3, tradeDF_C3, name='模型C3(仅保留铜)')\n", 1003 | "\n", 1004 | "smryDF_C4 = StatisticFunc.summaryDF(tradeDF_C4)\n", 1005 | "pfmcDF_C4 = StatisticFunc.performanceDF(smryDF_C4, tradeDF_C4, name='模型C4(剔除所有商品)')" 1006 | ] 1007 | }, 1008 | { 1009 | "cell_type": "code", 1010 | "execution_count": null, 1011 | "metadata": { 1012 | "ExecuteTime": { 1013 | "end_time": "2020-08-31T07:33:56.779063Z", 1014 | "start_time": "2020-08-31T07:33:56.767332Z" 1015 | } 1016 | }, 1017 | "outputs": [], 1018 | "source": [ 1019 | "# 仅保留黄金\n", 1020 | "smryDF_C1" 1021 | ] 1022 | }, 1023 | { 1024 | "cell_type": "code", 1025 | "execution_count": null, 1026 | "metadata": { 1027 | "ExecuteTime": { 1028 | "end_time": "2020-08-31T07:33:56.794192Z", 1029 | "start_time": "2020-08-31T07:33:56.781381Z" 1030 | } 1031 | }, 1032 | "outputs": [], 1033 | "source": [ 1034 | "# 仅保留铁矿石\n", 1035 | "smryDF_C2" 1036 | ] 1037 | }, 1038 | { 1039 | "cell_type": "code", 1040 | "execution_count": null, 1041 | "metadata": { 1042 | "ExecuteTime": { 1043 | "end_time": "2020-08-31T07:33:56.804663Z", 1044 | "start_time": "2020-08-31T07:33:56.796053Z" 1045 | }, 1046 | "scrolled": false 1047 | }, 1048 | "outputs": [], 1049 | "source": [ 1050 | "# 仅保留铜\n", 1051 | "smryDF_C3" 1052 | ] 1053 | }, 1054 | { 1055 | "cell_type": "code", 1056 | "execution_count": null, 1057 | "metadata": { 1058 | "ExecuteTime": { 1059 | "end_time": "2020-08-31T07:33:56.816873Z", 1060 | "start_time": "2020-08-31T07:33:56.806662Z" 1061 | } 1062 | }, 1063 | "outputs": [], 1064 | "source": [ 1065 | "# 剔除所有商品\n", 1066 | "smryDF_C4" 1067 | ] 1068 | }, 1069 | { 1070 | "cell_type": "code", 1071 | "execution_count": null, 1072 | "metadata": { 1073 | "ExecuteTime": { 1074 | "end_time": "2020-08-31T07:33:56.833004Z", 1075 | "start_time": "2020-08-31T07:33:56.819568Z" 1076 | } 1077 | }, 1078 | "outputs": [], 1079 | "source": [ 1080 | "tmp = pd.concat([pfmcDF_C1, pfmcDF_C2, pfmcDF_C3, pfmcDF_C4])\n", 1081 | "tmp" 1082 | ] 1083 | }, 1084 | { 1085 | "cell_type": "markdown", 1086 | "metadata": {}, 1087 | "source": [ 1088 | "### 收益率贡献度" 1089 | ] 1090 | }, 1091 | { 1092 | "cell_type": "code", 1093 | "execution_count": null, 1094 | "metadata": { 1095 | "ExecuteTime": { 1096 | "end_time": "2020-08-31T07:33:56.888766Z", 1097 | "start_time": "2020-08-31T07:33:56.835141Z" 1098 | }, 1099 | "scrolled": true 1100 | }, 1101 | "outputs": [], 1102 | "source": [ 1103 | "annualContrb_C1 = StatisticFunc.AnnualContribution(tradeDF_C1)\n", 1104 | "\n", 1105 | "annualContrb_C2 = StatisticFunc.AnnualContribution(tradeDF_C2)\n", 1106 | "\n", 1107 | "annualContrb_C3 = StatisticFunc.AnnualContribution(tradeDF_C3)\n", 1108 | "\n", 1109 | "annualContrb_C4 = StatisticFunc.AnnualContribution(tradeDF_C4)" 1110 | ] 1111 | }, 1112 | { 1113 | "cell_type": "code", 1114 | "execution_count": null, 1115 | "metadata": { 1116 | "ExecuteTime": { 1117 | "end_time": "2020-08-31T07:34:03.208271Z", 1118 | "start_time": "2020-08-31T07:33:56.890291Z" 1119 | }, 1120 | "scrolled": true 1121 | }, 1122 | "outputs": [], 1123 | "source": [ 1124 | "StatisticFunc.BarPlot(annualContrb_C1, '模型C1(仅保留黄金)')\n", 1125 | "StatisticFunc.BarPlot(annualContrb_C2, '模型C2(仅保留铁矿石)')\n", 1126 | "StatisticFunc.BarPlot(annualContrb_C3, '模型C3(仅保留铜)')\n", 1127 | "StatisticFunc.BarPlot(annualContrb_C4, '模型C4(剔除所有商品期货)')" 1128 | ] 1129 | }, 1130 | { 1131 | "cell_type": "markdown", 1132 | "metadata": {}, 1133 | "source": [ 1134 | "### 投资组合净值曲线" 1135 | ] 1136 | }, 1137 | { 1138 | "cell_type": "code", 1139 | "execution_count": null, 1140 | "metadata": { 1141 | "ExecuteTime": { 1142 | "end_time": "2020-08-31T07:34:03.581604Z", 1143 | "start_time": "2020-08-31T07:34:03.210948Z" 1144 | }, 1145 | "scrolled": false 1146 | }, 1147 | "outputs": [], 1148 | "source": [ 1149 | "fig = plt.figure(figsize=(16, 6))\n", 1150 | "\n", 1151 | "plt.plot(tradeDF_C1.index, tradeDF_C1['投资组合净值']/10000, label='模型C1(仅保留黄金)')\n", 1152 | "plt.plot(tradeDF_C2.index, tradeDF_C2['投资组合净值']/10000, label='模型C2(仅保留铁矿石)')\n", 1153 | "plt.plot(tradeDF_C3.index, tradeDF_C3['投资组合净值']/10000, label='模型C3(仅保留铜)')\n", 1154 | "plt.plot(tradeDF_C4.index, tradeDF_C4['投资组合净值']/10000, label='模型C4(剔除所有商品期货)')\n", 1155 | " \n", 1156 | "plt.plot(tradeDF_B.index, tradeDF_B['投资组合净值']/10000, ls='--', label='模型B') \n", 1157 | "plt.plot(cumReturns.index, cumReturns['沪深300'], label='沪深300')\n", 1158 | "plt.plot(cumReturns.index, cumReturns['10年国债'], label='10年国债')\n", 1159 | "\n", 1160 | "plt.xlabel('时间')\n", 1161 | "plt.ylabel('净值')\n", 1162 | "plt.grid(True)\n", 1163 | "plt.legend(loc='upper left')\n", 1164 | "plt.title('净值曲线--模型C')\n", 1165 | "plt.savefig('Pics/净值曲线_模型C.png')" 1166 | ] 1167 | }, 1168 | { 1169 | "cell_type": "markdown", 1170 | "metadata": {}, 1171 | "source": [ 1172 | "# 资产分散的效果" 1173 | ] 1174 | }, 1175 | { 1176 | "cell_type": "markdown", 1177 | "metadata": {}, 1178 | "source": [ 1179 | "## 各资产间相关性" 1180 | ] 1181 | }, 1182 | { 1183 | "cell_type": "code", 1184 | "execution_count": null, 1185 | "metadata": { 1186 | "ExecuteTime": { 1187 | "end_time": "2020-08-31T07:34:03.596676Z", 1188 | "start_time": "2020-08-31T07:34:03.583322Z" 1189 | } 1190 | }, 1191 | "outputs": [], 1192 | "source": [ 1193 | "corrDF = cumReturns.corr()\n", 1194 | "corrDF" 1195 | ] 1196 | }, 1197 | { 1198 | "cell_type": "code", 1199 | "execution_count": null, 1200 | "metadata": { 1201 | "ExecuteTime": { 1202 | "end_time": "2020-08-31T07:34:04.572620Z", 1203 | "start_time": "2020-08-31T07:34:03.598396Z" 1204 | } 1205 | }, 1206 | "outputs": [], 1207 | "source": [ 1208 | "fig = plt.figure(figsize=(10, 10), dpi=200)\n", 1209 | "sns.heatmap(corrDF, annot=True, vmax=1, square=True, cmap=\"Blues\")\n", 1210 | "plt.show()" 1211 | ] 1212 | }, 1213 | { 1214 | "cell_type": "markdown", 1215 | "metadata": {}, 1216 | "source": [ 1217 | "## 模型D:引入美元资产\n", 1218 | "\n", 1219 | "- 标普500\n", 1220 | "- 10年期美债" 1221 | ] 1222 | }, 1223 | { 1224 | "cell_type": "code", 1225 | "execution_count": null, 1226 | "metadata": { 1227 | "ExecuteTime": { 1228 | "end_time": "2020-08-31T07:34:04.580253Z", 1229 | "start_time": "2020-08-31T07:34:04.574997Z" 1230 | } 1231 | }, 1232 | "outputs": [], 1233 | "source": [ 1234 | "leverReturns_D = leverReturns.drop(['中信证券COMEX铜期货', '中信证券COMEX黄金期货', '铁矿石期货', '中信证券WTI原油期货'], axis=1)\n", 1235 | "leverCumReturns_D = leverCumReturns.drop(['中信证券COMEX铜期货', '中信证券COMEX黄金期货', '铁矿石期货', '中信证券WTI原油期货'], axis=1)" 1236 | ] 1237 | }, 1238 | { 1239 | "cell_type": "markdown", 1240 | "metadata": {}, 1241 | "source": [ 1242 | "### 程序运行" 1243 | ] 1244 | }, 1245 | { 1246 | "cell_type": "code", 1247 | "execution_count": null, 1248 | "metadata": { 1249 | "ExecuteTime": { 1250 | "end_time": "2020-08-31T07:34:58.298978Z", 1251 | "start_time": "2020-08-31T07:34:04.583329Z" 1252 | } 1253 | }, 1254 | "outputs": [], 1255 | "source": [ 1256 | "tradeDF_D, weightDF_D = AlgoLoop.AlgoTrade(Assets, leverReturns_D, leverCumReturns_D, Turnovers, FXRates, mode='ema')" 1257 | ] 1258 | }, 1259 | { 1260 | "cell_type": "code", 1261 | "execution_count": null, 1262 | "metadata": { 1263 | "ExecuteTime": { 1264 | "end_time": "2020-08-31T07:34:58.791653Z", 1265 | "start_time": "2020-08-31T07:34:58.301283Z" 1266 | } 1267 | }, 1268 | "outputs": [], 1269 | "source": [ 1270 | "StatisticFunc.WeightPlot(tradeDF_D, weightDF_D, '模型D')" 1271 | ] 1272 | }, 1273 | { 1274 | "cell_type": "markdown", 1275 | "metadata": {}, 1276 | "source": [ 1277 | "### 回测表现汇总" 1278 | ] 1279 | }, 1280 | { 1281 | "cell_type": "code", 1282 | "execution_count": null, 1283 | "metadata": { 1284 | "ExecuteTime": { 1285 | "end_time": "2020-08-31T07:34:58.837491Z", 1286 | "start_time": "2020-08-31T07:34:58.793541Z" 1287 | } 1288 | }, 1289 | "outputs": [], 1290 | "source": [ 1291 | "smryDF_D = StatisticFunc.summaryDF(tradeDF_D)\n", 1292 | "pfmcDF_D = StatisticFunc.performanceDF(smryDF_D, tradeDF_D, name='模型D')" 1293 | ] 1294 | }, 1295 | { 1296 | "cell_type": "code", 1297 | "execution_count": null, 1298 | "metadata": { 1299 | "ExecuteTime": { 1300 | "end_time": "2020-08-31T07:34:58.846686Z", 1301 | "start_time": "2020-08-31T07:34:58.838971Z" 1302 | } 1303 | }, 1304 | "outputs": [], 1305 | "source": [ 1306 | "smryDF_D" 1307 | ] 1308 | }, 1309 | { 1310 | "cell_type": "code", 1311 | "execution_count": null, 1312 | "metadata": { 1313 | "ExecuteTime": { 1314 | "end_time": "2020-08-31T07:34:58.855639Z", 1315 | "start_time": "2020-08-31T07:34:58.848430Z" 1316 | } 1317 | }, 1318 | "outputs": [], 1319 | "source": [ 1320 | "pfmcDF_D" 1321 | ] 1322 | }, 1323 | { 1324 | "cell_type": "markdown", 1325 | "metadata": {}, 1326 | "source": [ 1327 | "### 收益率贡献度" 1328 | ] 1329 | }, 1330 | { 1331 | "cell_type": "code", 1332 | "execution_count": null, 1333 | "metadata": { 1334 | "ExecuteTime": { 1335 | "end_time": "2020-08-31T07:34:58.873142Z", 1336 | "start_time": "2020-08-31T07:34:58.857397Z" 1337 | }, 1338 | "scrolled": true 1339 | }, 1340 | "outputs": [], 1341 | "source": [ 1342 | "annualContrb_D = StatisticFunc.AnnualContribution(tradeDF_D)" 1343 | ] 1344 | }, 1345 | { 1346 | "cell_type": "code", 1347 | "execution_count": null, 1348 | "metadata": { 1349 | "ExecuteTime": { 1350 | "end_time": "2020-08-31T07:35:00.752054Z", 1351 | "start_time": "2020-08-31T07:34:58.874916Z" 1352 | } 1353 | }, 1354 | "outputs": [], 1355 | "source": [ 1356 | "StatisticFunc.BarPlot(annualContrb_D, '模型D')" 1357 | ] 1358 | }, 1359 | { 1360 | "cell_type": "markdown", 1361 | "metadata": {}, 1362 | "source": [ 1363 | "### 投资组合净值曲线" 1364 | ] 1365 | }, 1366 | { 1367 | "cell_type": "code", 1368 | "execution_count": null, 1369 | "metadata": { 1370 | "ExecuteTime": { 1371 | "end_time": "2020-08-31T07:35:01.069274Z", 1372 | "start_time": "2020-08-31T07:35:00.754615Z" 1373 | }, 1374 | "scrolled": false 1375 | }, 1376 | "outputs": [], 1377 | "source": [ 1378 | "fig = plt.figure(figsize=(16, 6))\n", 1379 | "\n", 1380 | "plt.plot(tradeDF_D.index, tradeDF_D['投资组合净值']/10000, label='模型D(美元资产)')\n", 1381 | " \n", 1382 | "plt.plot(tradeDF_C4.index, tradeDF_C4['投资组合净值']/10000, ls='--', label='模型C4(去除商品期货)') \n", 1383 | "plt.plot(cumReturns.index, cumReturns['沪深300'], label='沪深300')\n", 1384 | "plt.plot(cumReturns.index, cumReturns['10年国债'], label='10年国债')\n", 1385 | "\n", 1386 | "plt.xlabel('时间')\n", 1387 | "plt.ylabel('净值')\n", 1388 | "plt.grid(True)\n", 1389 | "plt.legend(loc='upper left')\n", 1390 | "plt.title('净值曲线--模型D')\n", 1391 | "plt.savefig('Pics/净值曲线_模型D.png')" 1392 | ] 1393 | }, 1394 | { 1395 | "cell_type": "markdown", 1396 | "metadata": {}, 1397 | "source": [ 1398 | "# 单因子和多因子的作用" 1399 | ] 1400 | }, 1401 | { 1402 | "cell_type": "markdown", 1403 | "metadata": {}, 1404 | "source": [ 1405 | "## 模型E:单因子\n", 1406 | "\n", 1407 | "- 横截面动量" 1408 | ] 1409 | }, 1410 | { 1411 | "cell_type": "markdown", 1412 | "metadata": {}, 1413 | "source": [ 1414 | "### 程序运行" 1415 | ] 1416 | }, 1417 | { 1418 | "cell_type": "code", 1419 | "execution_count": null, 1420 | "metadata": { 1421 | "ExecuteTime": { 1422 | "end_time": "2020-08-31T07:36:00.707598Z", 1423 | "start_time": "2020-08-31T07:35:01.071654Z" 1424 | } 1425 | }, 1426 | "outputs": [], 1427 | "source": [ 1428 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 1429 | "factors = {'momentumX':True, 'momentumT':False, \n", 1430 | " 'reverseX':False, 'reverseT':False,\n", 1431 | " 'turnover':False, 'fxRate':False,\n", 1432 | " 'copperGold':False, 'copperGas':False}\n", 1433 | "\n", 1434 | "tradeDF_single, weightDF_single = AlgoLoop.AlgoTrade(Assets, leverReturns_D, leverCumReturns_D, \n", 1435 | " Turnovers, FXRates, mode='ema', dt=120, up=0.50, \n", 1436 | " thresholds=thrds, factorDict=factors)" 1437 | ] 1438 | }, 1439 | { 1440 | "cell_type": "code", 1441 | "execution_count": null, 1442 | "metadata": { 1443 | "ExecuteTime": { 1444 | "end_time": "2020-08-31T07:36:01.218619Z", 1445 | "start_time": "2020-08-31T07:36:00.709981Z" 1446 | } 1447 | }, 1448 | "outputs": [], 1449 | "source": [ 1450 | "StatisticFunc.WeightPlot(tradeDF_single, weightDF_single, '模型E')" 1451 | ] 1452 | }, 1453 | { 1454 | "cell_type": "markdown", 1455 | "metadata": {}, 1456 | "source": [ 1457 | "### 回测表现汇总" 1458 | ] 1459 | }, 1460 | { 1461 | "cell_type": "code", 1462 | "execution_count": null, 1463 | "metadata": { 1464 | "ExecuteTime": { 1465 | "end_time": "2020-08-31T07:36:01.339774Z", 1466 | "start_time": "2020-08-31T07:36:01.220710Z" 1467 | } 1468 | }, 1469 | "outputs": [], 1470 | "source": [ 1471 | "smryDF_single = StatisticFunc.summaryDF(tradeDF_single)\n", 1472 | "pfmcDF_single = StatisticFunc.performanceDF(smryDF_single, tradeDF_single, name='模型E')" 1473 | ] 1474 | }, 1475 | { 1476 | "cell_type": "code", 1477 | "execution_count": null, 1478 | "metadata": { 1479 | "ExecuteTime": { 1480 | "end_time": "2020-08-31T07:36:01.351298Z", 1481 | "start_time": "2020-08-31T07:36:01.341748Z" 1482 | } 1483 | }, 1484 | "outputs": [], 1485 | "source": [ 1486 | "smryDF_single" 1487 | ] 1488 | }, 1489 | { 1490 | "cell_type": "code", 1491 | "execution_count": null, 1492 | "metadata": { 1493 | "ExecuteTime": { 1494 | "end_time": "2020-08-31T07:36:01.364592Z", 1495 | "start_time": "2020-08-31T07:36:01.353826Z" 1496 | } 1497 | }, 1498 | "outputs": [], 1499 | "source": [ 1500 | "pfmcDF_single" 1501 | ] 1502 | }, 1503 | { 1504 | "cell_type": "markdown", 1505 | "metadata": {}, 1506 | "source": [ 1507 | "### 收益率贡献度" 1508 | ] 1509 | }, 1510 | { 1511 | "cell_type": "code", 1512 | "execution_count": null, 1513 | "metadata": { 1514 | "ExecuteTime": { 1515 | "end_time": "2020-08-31T07:36:01.399780Z", 1516 | "start_time": "2020-08-31T07:36:01.379443Z" 1517 | }, 1518 | "scrolled": true 1519 | }, 1520 | "outputs": [], 1521 | "source": [ 1522 | "annualContrb_single = StatisticFunc.AnnualContribution(tradeDF_single)" 1523 | ] 1524 | }, 1525 | { 1526 | "cell_type": "code", 1527 | "execution_count": null, 1528 | "metadata": { 1529 | "ExecuteTime": { 1530 | "end_time": "2020-08-31T07:36:03.299500Z", 1531 | "start_time": "2020-08-31T07:36:01.403381Z" 1532 | } 1533 | }, 1534 | "outputs": [], 1535 | "source": [ 1536 | "StatisticFunc.BarPlot(annualContrb_single, '模型E')" 1537 | ] 1538 | }, 1539 | { 1540 | "cell_type": "markdown", 1541 | "metadata": {}, 1542 | "source": [ 1543 | "### 投资组合净值曲线" 1544 | ] 1545 | }, 1546 | { 1547 | "cell_type": "code", 1548 | "execution_count": null, 1549 | "metadata": { 1550 | "ExecuteTime": { 1551 | "end_time": "2020-08-31T07:36:03.610988Z", 1552 | "start_time": "2020-08-31T07:36:03.301968Z" 1553 | }, 1554 | "scrolled": false 1555 | }, 1556 | "outputs": [], 1557 | "source": [ 1558 | "fig = plt.figure(figsize=(16, 6))\n", 1559 | "\n", 1560 | "plt.plot(tradeDF_single.index, tradeDF_single['投资组合净值']/10000, label='模型E(单因子)')\n", 1561 | " \n", 1562 | "plt.plot(tradeDF_D.index, tradeDF_D['投资组合净值']/10000, ls='--', label='模型D(美元资产)') \n", 1563 | "plt.plot(cumReturns.index, cumReturns['沪深300'], label='沪深300')\n", 1564 | "plt.plot(cumReturns.index, cumReturns['10年国债'], label='10年国债')\n", 1565 | "\n", 1566 | "plt.xlabel('时间')\n", 1567 | "plt.ylabel('净值')\n", 1568 | "plt.grid(True)\n", 1569 | "plt.legend(loc='upper left')\n", 1570 | "plt.title('净值曲线--模型E')\n", 1571 | "plt.savefig('Pics/净值曲线_模型E.png')" 1572 | ] 1573 | }, 1574 | { 1575 | "cell_type": "markdown", 1576 | "metadata": {}, 1577 | "source": [ 1578 | "## 模型F:多因子\n", 1579 | "\n", 1580 | "- 横截面动量+时序动量+换手率+铜金+铜油+汇率" 1581 | ] 1582 | }, 1583 | { 1584 | "cell_type": "markdown", 1585 | "metadata": {}, 1586 | "source": [ 1587 | "### 程序运行" 1588 | ] 1589 | }, 1590 | { 1591 | "cell_type": "code", 1592 | "execution_count": null, 1593 | "metadata": { 1594 | "ExecuteTime": { 1595 | "end_time": "2020-08-31T07:37:03.691310Z", 1596 | "start_time": "2020-08-31T07:36:03.612726Z" 1597 | } 1598 | }, 1599 | "outputs": [], 1600 | "source": [ 1601 | "thrds = {'Equity':0.50, 'FixedIncome':0.90, 'Commodity':0.30}\n", 1602 | "factors = {'momentumX':True, 'momentumT':False, \n", 1603 | " 'reverseX':False, 'reverseT':False,\n", 1604 | " 'turnover':True, 'fxRate':True,\n", 1605 | " 'copperGold':True, 'copperGas':True}\n", 1606 | "\n", 1607 | "tradeDF_multi, weightDF_multi = AlgoLoop.AlgoTrade(Assets, leverReturns_D, leverCumReturns_D, \n", 1608 | " Turnovers, FXRates, mode='ema', dt=120, up=0.50, \n", 1609 | " thresholds=thrds, factorDict=factors)" 1610 | ] 1611 | }, 1612 | { 1613 | "cell_type": "code", 1614 | "execution_count": null, 1615 | "metadata": { 1616 | "ExecuteTime": { 1617 | "end_time": "2020-08-31T07:37:04.200747Z", 1618 | "start_time": "2020-08-31T07:37:03.694137Z" 1619 | }, 1620 | "scrolled": false 1621 | }, 1622 | "outputs": [], 1623 | "source": [ 1624 | "StatisticFunc.WeightPlot(tradeDF_multi, weightDF_multi, '模型F')" 1625 | ] 1626 | }, 1627 | { 1628 | "cell_type": "markdown", 1629 | "metadata": {}, 1630 | "source": [ 1631 | "### 回测表现汇总" 1632 | ] 1633 | }, 1634 | { 1635 | "cell_type": "code", 1636 | "execution_count": null, 1637 | "metadata": { 1638 | "ExecuteTime": { 1639 | "end_time": "2020-08-31T07:37:04.246990Z", 1640 | "start_time": "2020-08-31T07:37:04.203219Z" 1641 | }, 1642 | "scrolled": false 1643 | }, 1644 | "outputs": [], 1645 | "source": [ 1646 | "smryDF_multi = StatisticFunc.summaryDF(tradeDF_multi)\n", 1647 | "pfmcDF_multi = StatisticFunc.performanceDF(smryDF_multi, tradeDF_multi, name='模型F')" 1648 | ] 1649 | }, 1650 | { 1651 | "cell_type": "code", 1652 | "execution_count": null, 1653 | "metadata": { 1654 | "ExecuteTime": { 1655 | "end_time": "2020-08-31T07:37:04.256398Z", 1656 | "start_time": "2020-08-31T07:37:04.248643Z" 1657 | } 1658 | }, 1659 | "outputs": [], 1660 | "source": [ 1661 | "smryDF_multi" 1662 | ] 1663 | }, 1664 | { 1665 | "cell_type": "code", 1666 | "execution_count": null, 1667 | "metadata": { 1668 | "ExecuteTime": { 1669 | "end_time": "2020-08-31T07:37:04.265279Z", 1670 | "start_time": "2020-08-31T07:37:04.258019Z" 1671 | } 1672 | }, 1673 | "outputs": [], 1674 | "source": [ 1675 | "pfmcDF_multi" 1676 | ] 1677 | }, 1678 | { 1679 | "cell_type": "markdown", 1680 | "metadata": {}, 1681 | "source": [ 1682 | "### 收益率贡献度" 1683 | ] 1684 | }, 1685 | { 1686 | "cell_type": "code", 1687 | "execution_count": null, 1688 | "metadata": { 1689 | "ExecuteTime": { 1690 | "end_time": "2020-08-31T07:37:04.283123Z", 1691 | "start_time": "2020-08-31T07:37:04.267000Z" 1692 | }, 1693 | "scrolled": true 1694 | }, 1695 | "outputs": [], 1696 | "source": [ 1697 | "annualContrb_multi = StatisticFunc.AnnualContribution(tradeDF_multi)" 1698 | ] 1699 | }, 1700 | { 1701 | "cell_type": "code", 1702 | "execution_count": null, 1703 | "metadata": { 1704 | "ExecuteTime": { 1705 | "end_time": "2020-08-31T07:37:06.220717Z", 1706 | "start_time": "2020-08-31T07:37:04.284778Z" 1707 | }, 1708 | "scrolled": false 1709 | }, 1710 | "outputs": [], 1711 | "source": [ 1712 | "StatisticFunc.BarPlot(annualContrb_multi, '模型F')" 1713 | ] 1714 | }, 1715 | { 1716 | "cell_type": "markdown", 1717 | "metadata": {}, 1718 | "source": [ 1719 | "### 投资组合净值曲线" 1720 | ] 1721 | }, 1722 | { 1723 | "cell_type": "code", 1724 | "execution_count": null, 1725 | "metadata": { 1726 | "ExecuteTime": { 1727 | "end_time": "2020-08-31T07:37:06.539546Z", 1728 | "start_time": "2020-08-31T07:37:06.222673Z" 1729 | } 1730 | }, 1731 | "outputs": [], 1732 | "source": [ 1733 | "fig = plt.figure(figsize=(16, 6))\n", 1734 | "\n", 1735 | "plt.plot(tradeDF_multi.index, tradeDF_multi['投资组合净值']/10000, label='模型F(多因子)')\n", 1736 | " \n", 1737 | "plt.plot(tradeDF_D.index, tradeDF_D['投资组合净值']/10000, ls='--', label='模型D(美元资产)') \n", 1738 | "plt.plot(cumReturns.index, cumReturns['沪深300'], label='沪深300')\n", 1739 | "plt.plot(cumReturns.index, cumReturns['10年国债'], label='10年国债')\n", 1740 | "\n", 1741 | "plt.xlabel('时间')\n", 1742 | "plt.ylabel('净值')\n", 1743 | "plt.grid(True)\n", 1744 | "plt.legend(loc='upper left')\n", 1745 | "plt.title('净值曲线--模型F')\n", 1746 | "plt.savefig('Pics/净值曲线_模型F.png')" 1747 | ] 1748 | }, 1749 | { 1750 | "cell_type": "markdown", 1751 | "metadata": {}, 1752 | "source": [ 1753 | "# 模型结果对流动性的依赖" 1754 | ] 1755 | }, 1756 | { 1757 | "cell_type": "code", 1758 | "execution_count": null, 1759 | "metadata": { 1760 | "ExecuteTime": { 1761 | "end_time": "2020-08-31T07:37:06.545643Z", 1762 | "start_time": "2020-08-31T07:37:06.541044Z" 1763 | } 1764 | }, 1765 | "outputs": [], 1766 | "source": [ 1767 | "# 投资组合日收益率\n", 1768 | "PnL = tradeDF_single['投资组合净值'] / tradeDF_single['投资组合净值'].shift(1, axis=0) - 1.0\n", 1769 | "PnL = PnL.dropna()" 1770 | ] 1771 | }, 1772 | { 1773 | "cell_type": "markdown", 1774 | "metadata": {}, 1775 | "source": [ 1776 | "## 二级市场流动性\n", 1777 | "\n", 1778 | "- A股成交量、换手率\n", 1779 | "- 美股成交量、换手率" 1780 | ] 1781 | }, 1782 | { 1783 | "cell_type": "markdown", 1784 | "metadata": {}, 1785 | "source": [ 1786 | "### 流动性数据" 1787 | ] 1788 | }, 1789 | { 1790 | "cell_type": "code", 1791 | "execution_count": null, 1792 | "metadata": { 1793 | "ExecuteTime": { 1794 | "end_time": "2020-08-31T07:37:06.826732Z", 1795 | "start_time": "2020-08-31T07:37:06.547444Z" 1796 | } 1797 | }, 1798 | "outputs": [], 1799 | "source": [ 1800 | "LiqData = pd.read_excel(io=\"Raw/二级市场流动性.xlsx\")\n", 1801 | "LiqData.columns = LiqData.iloc[1, :]" 1802 | ] 1803 | }, 1804 | { 1805 | "cell_type": "code", 1806 | "execution_count": null, 1807 | "metadata": { 1808 | "ExecuteTime": { 1809 | "end_time": "2020-08-31T07:37:06.834359Z", 1810 | "start_time": "2020-08-31T07:37:06.828281Z" 1811 | } 1812 | }, 1813 | "outputs": [], 1814 | "source": [ 1815 | "Volume = LiqData.iloc[:, :4]\n", 1816 | "Volume = Volume.drop(index=[0, 1, 2])\n", 1817 | "Volume = Volume.set_index(['日期'])" 1818 | ] 1819 | }, 1820 | { 1821 | "cell_type": "code", 1822 | "execution_count": null, 1823 | "metadata": { 1824 | "ExecuteTime": { 1825 | "end_time": "2020-08-31T07:37:06.844264Z", 1826 | "start_time": "2020-08-31T07:37:06.835975Z" 1827 | } 1828 | }, 1829 | "outputs": [], 1830 | "source": [ 1831 | "Turnover = LiqData.iloc[:, 5:]\n", 1832 | "Turnover = Turnover.drop(index=[0, 1, 2])\n", 1833 | "Turnover = Turnover.set_index(['日期'])" 1834 | ] 1835 | }, 1836 | { 1837 | "cell_type": "markdown", 1838 | "metadata": {}, 1839 | "source": [ 1840 | "### 相关系数" 1841 | ] 1842 | }, 1843 | { 1844 | "cell_type": "code", 1845 | "execution_count": null, 1846 | "metadata": { 1847 | "ExecuteTime": { 1848 | "end_time": "2020-08-31T07:37:06.862125Z", 1849 | "start_time": "2020-08-31T07:37:06.845931Z" 1850 | } 1851 | }, 1852 | "outputs": [], 1853 | "source": [ 1854 | "# 成交量相关系数\n", 1855 | "data1 = Volume.loc[PnL.index, '沪深300'].ewm(60).mean()\n", 1856 | "data2 = Volume.loc[PnL.index, '中证500'].ewm(60).mean()\n", 1857 | "data3 = PnL.ewm(60).mean()\n", 1858 | "\n", 1859 | "np.corrcoef(data1, data3), np.corrcoef(data2, data3)" 1860 | ] 1861 | }, 1862 | { 1863 | "cell_type": "code", 1864 | "execution_count": null, 1865 | "metadata": { 1866 | "ExecuteTime": { 1867 | "end_time": "2020-08-31T07:37:06.875547Z", 1868 | "start_time": "2020-08-31T07:37:06.864112Z" 1869 | } 1870 | }, 1871 | "outputs": [], 1872 | "source": [ 1873 | "# 换手率相关系数\n", 1874 | "data1 = Turnover.loc[PnL.index, '沪深300'].ewm(60).mean()\n", 1875 | "data2 = Turnover.loc[PnL.index, '中证500'].ewm(60).mean()\n", 1876 | "data3 = PnL.ewm(60).mean()\n", 1877 | "\n", 1878 | "np.corrcoef(data1, data3), np.corrcoef(data2, data3)" 1879 | ] 1880 | }, 1881 | { 1882 | "cell_type": "markdown", 1883 | "metadata": {}, 1884 | "source": [ 1885 | "### 流动性与投资组合表现" 1886 | ] 1887 | }, 1888 | { 1889 | "cell_type": "code", 1890 | "execution_count": null, 1891 | "metadata": { 1892 | "ExecuteTime": { 1893 | "end_time": "2020-08-31T07:37:10.854272Z", 1894 | "start_time": "2020-08-31T07:37:06.877546Z" 1895 | } 1896 | }, 1897 | "outputs": [], 1898 | "source": [ 1899 | "# 成交量\n", 1900 | "fig, ax1 = plt.subplots(1, 1, figsize=(16,6), dpi=150)\n", 1901 | "\n", 1902 | "ax1.plot(Volume.index, Volume['沪深300'].ewm(60).mean(), label='沪深300(60移动平均)', zorder=0)\n", 1903 | "ax1.plot(Volume.index, Volume['中证500'].ewm(60).mean(), label='中证500(60移动平均)', zorder=1)\n", 1904 | "\n", 1905 | "ax1.legend(loc='upper left')\n", 1906 | "ax1.set_xlabel('时间')\n", 1907 | "ax1.set_ylabel('成交量')\n", 1908 | "ax1.grid(True)\n", 1909 | "\n", 1910 | "ax2 = ax1.twinx() \n", 1911 | "ax2.bar(PnL.index, PnL.ewm(60).mean(), label='模型E_日收益率(60移动平均)', color='tab:orange')\n", 1912 | "\n", 1913 | "ax2.legend(loc='upper right')\n", 1914 | "ax2.set_ylabel('投资组合日收益率')\n", 1915 | "\n", 1916 | "plt.title('成交量变化与投资组合收益率的关系')\n", 1917 | "plt.show()" 1918 | ] 1919 | }, 1920 | { 1921 | "cell_type": "code", 1922 | "execution_count": null, 1923 | "metadata": { 1924 | "ExecuteTime": { 1925 | "end_time": "2020-08-31T07:37:14.823971Z", 1926 | "start_time": "2020-08-31T07:37:10.856443Z" 1927 | }, 1928 | "scrolled": false 1929 | }, 1930 | "outputs": [], 1931 | "source": [ 1932 | "# 换手率\n", 1933 | "fig, ax1 = plt.subplots(1, 1, figsize=(16,6), dpi=100)\n", 1934 | "\n", 1935 | "ax1.plot(Turnover.index, Turnover['沪深300'].ewm(60).mean(), label='沪深300(60移动平均)', zorder=1)\n", 1936 | "ax1.plot(Turnover.index, Turnover['中证500'].ewm(60).mean(), label='中证500(60移动平均)', zorder=0)\n", 1937 | "\n", 1938 | "ax1.legend(loc='upper left')\n", 1939 | "ax1.set_xlabel('时间')\n", 1940 | "ax1.set_ylabel('换手率')\n", 1941 | "ax1.grid(True)\n", 1942 | "\n", 1943 | "ax2 = ax1.twinx() \n", 1944 | "ax2.bar(PnL.index, PnL.ewm(60).mean(), label='模型E_日收益率(60移动平均)', color='tab:orange')\n", 1945 | "\n", 1946 | "ax2.legend(loc='upper right')\n", 1947 | "ax2.set_ylabel('投资组合日收益率')\n", 1948 | "\n", 1949 | "plt.title('换手率变化与投资组合收益率的关系')\n", 1950 | "plt.show()" 1951 | ] 1952 | }, 1953 | { 1954 | "cell_type": "markdown", 1955 | "metadata": {}, 1956 | "source": [ 1957 | "## 广义信贷市场流动性\n", 1958 | "\n", 1959 | "- 社会融资规模累计同比 - m2同比\n", 1960 | "- m2同比 - 名义GDP\n" 1961 | ] 1962 | }, 1963 | { 1964 | "cell_type": "markdown", 1965 | "metadata": {}, 1966 | "source": [ 1967 | "### 流动性数据" 1968 | ] 1969 | }, 1970 | { 1971 | "cell_type": "code", 1972 | "execution_count": null, 1973 | "metadata": { 1974 | "ExecuteTime": { 1975 | "end_time": "2020-08-31T07:37:15.059476Z", 1976 | "start_time": "2020-08-31T07:37:14.826212Z" 1977 | } 1978 | }, 1979 | "outputs": [], 1980 | "source": [ 1981 | "# 基本处理\n", 1982 | "CredData = pd.read_excel(io='Raw/广义信贷市场流动性.xls')\n", 1983 | "CredData = CredData.drop([0, 3841, 3842], axis=0)\n", 1984 | "CredData.columns = ['日期', 'M2同比 - GDP同比', '10年美债收益率', 'M2同比', 'M1同比', 'M1同比 - M2同比', '社会融资规模同比 - M2同比']\n", 1985 | "CredData = CredData.set_index('日期')\n", 1986 | "\n", 1987 | "# 用季度数据填充日数据\n", 1988 | "CredData = CredData.fillna(method='bfill', axis=0)" 1989 | ] 1990 | }, 1991 | { 1992 | "cell_type": "markdown", 1993 | "metadata": {}, 1994 | "source": [ 1995 | "### 相关系数" 1996 | ] 1997 | }, 1998 | { 1999 | "cell_type": "code", 2000 | "execution_count": null, 2001 | "metadata": { 2002 | "ExecuteTime": { 2003 | "end_time": "2020-08-31T07:37:15.074750Z", 2004 | "start_time": "2020-08-31T07:37:15.061731Z" 2005 | } 2006 | }, 2007 | "outputs": [], 2008 | "source": [ 2009 | "# M2同比 - GDP同比 相关系数\n", 2010 | "data1 = CredData.loc[PnL.index, 'M2同比 - GDP同比'].ewm(20).mean()\n", 2011 | "data2 = PnL.ewm(20).mean()\n", 2012 | "\n", 2013 | "np.corrcoef(data1, data2)" 2014 | ] 2015 | }, 2016 | { 2017 | "cell_type": "code", 2018 | "execution_count": null, 2019 | "metadata": { 2020 | "ExecuteTime": { 2021 | "end_time": "2020-08-31T07:37:15.085316Z", 2022 | "start_time": "2020-08-31T07:37:15.076665Z" 2023 | } 2024 | }, 2025 | "outputs": [], 2026 | "source": [ 2027 | "# 社融规模 - M2同比 相关系数\n", 2028 | "data1 = CredData.loc[PnL.index, '社会融资规模同比 - M2同比'].ewm(20).mean()\n", 2029 | "data2 = PnL.ewm(20).mean()\n", 2030 | "\n", 2031 | "np.corrcoef(data1, data2)" 2032 | ] 2033 | }, 2034 | { 2035 | "cell_type": "markdown", 2036 | "metadata": {}, 2037 | "source": [ 2038 | "### 流动性与投资组合表现" 2039 | ] 2040 | }, 2041 | { 2042 | "cell_type": "code", 2043 | "execution_count": null, 2044 | "metadata": { 2045 | "ExecuteTime": { 2046 | "end_time": "2020-08-31T07:37:19.131215Z", 2047 | "start_time": "2020-08-31T07:37:15.087192Z" 2048 | } 2049 | }, 2050 | "outputs": [], 2051 | "source": [ 2052 | "# M2同比 - GDP同比\n", 2053 | "fig, ax1 = plt.subplots(1,1,figsize=(16,6), dpi=150)\n", 2054 | "\n", 2055 | "ax1.plot(PnL.index, CredData.loc[PnL.index, 'M2同比 - GDP同比'], \n", 2056 | " label='M2同比 - GDP同比', zorder=0)\n", 2057 | "ax1.plot(PnL.index, CredData.loc[PnL.index, 'M2同比 - GDP同比'].ewm(20).mean(), \n", 2058 | " label='M2同比 - GDP同比(移动平均20)', zorder=1)\n", 2059 | "\n", 2060 | "ax1.legend(loc='upper left')\n", 2061 | "ax1.set_xlabel('时间')\n", 2062 | "ax1.set_ylabel('社会融资规模同比 - M2同比')\n", 2063 | "ax1.grid(True)\n", 2064 | "\n", 2065 | "ax2 = ax1.twinx() \n", 2066 | "ax2.bar(PnL.index, PnL.ewm(20).mean(), label='模型E_日收益率(20移动平均)', color='tab:orange')\n", 2067 | "\n", 2068 | "ax2.legend(loc='upper right')\n", 2069 | "ax2.set_ylabel('投资组合净值')\n", 2070 | "\n", 2071 | "plt.title('广义信贷市场流动性A')\n", 2072 | "plt.show()" 2073 | ] 2074 | }, 2075 | { 2076 | "cell_type": "code", 2077 | "execution_count": null, 2078 | "metadata": { 2079 | "ExecuteTime": { 2080 | "end_time": "2020-08-31T07:37:23.284174Z", 2081 | "start_time": "2020-08-31T07:37:19.133423Z" 2082 | } 2083 | }, 2084 | "outputs": [], 2085 | "source": [ 2086 | "# 社会融资规模同比 - M2同比\n", 2087 | "fig, ax1 = plt.subplots(1,1,figsize=(16,6), dpi=150)\n", 2088 | "\n", 2089 | "ax1.plot(PnL.index, CredData.loc[PnL.index, '社会融资规模同比 - M2同比'], \n", 2090 | " label='社会融资规模同比 - M2同比', zorder=0)\n", 2091 | "ax1.plot(PnL.index, CredData.loc[PnL.index, '社会融资规模同比 - M2同比'].ewm(20).mean(), \n", 2092 | " label='社会融资规模同比 - M2同比(移动平均20)', zorder=1)\n", 2093 | "\n", 2094 | "ax1.legend(loc='upper left')\n", 2095 | "ax1.set_xlabel('时间')\n", 2096 | "ax1.set_ylabel('社会融资规模同比 - M2同比')\n", 2097 | "ax1.grid(True)\n", 2098 | "\n", 2099 | "ax2 = ax1.twinx() \n", 2100 | "ax2.bar(PnL.index, PnL.ewm(20).mean(), label='模型E_日收益率(20移动平均)', color='tab:orange')\n", 2101 | "\n", 2102 | "ax2.legend(loc='upper right')\n", 2103 | "ax2.set_ylabel('投资组合净值')\n", 2104 | "\n", 2105 | "plt.title('广义信贷市场流动性B')\n", 2106 | "plt.show()" 2107 | ] 2108 | }, 2109 | { 2110 | "cell_type": "markdown", 2111 | "metadata": {}, 2112 | "source": [ 2113 | "## 狭义金融市场流动性(利率)\n", 2114 | "\n", 2115 | "- 超储率:超额存款准备金占存款的比例称为超额存款准备金率\n", 2116 | "\n", 2117 | "\n", 2122 | "\n", 2123 | "- 10年国债收益率\n", 2124 | "\n", 2125 | "- 10年美债收益率\n", 2126 | "\n", 2127 | "- 美元指数" 2128 | ] 2129 | }, 2130 | { 2131 | "cell_type": "markdown", 2132 | "metadata": {}, 2133 | "source": [ 2134 | "### 流动性数据" 2135 | ] 2136 | }, 2137 | { 2138 | "cell_type": "code", 2139 | "execution_count": null, 2140 | "metadata": { 2141 | "ExecuteTime": { 2142 | "end_time": "2020-08-31T07:37:23.453288Z", 2143 | "start_time": "2020-08-31T07:37:23.286461Z" 2144 | } 2145 | }, 2146 | "outputs": [], 2147 | "source": [ 2148 | "FinData = pd.read_excel(io='Raw/狭义金融市场流动性.xlsx')\n", 2149 | "\n", 2150 | "# 整理表格\n", 2151 | "FinData.columns = FinData.iloc[1, :]\n", 2152 | "FinData = FinData.drop([0, 1, 2], axis=0)\n", 2153 | "FinData = FinData.set_index('日期')\n", 2154 | "\n", 2155 | "# 填充Backfill \n", 2156 | "FinData = FinData.fillna(method='ffill')" 2157 | ] 2158 | }, 2159 | { 2160 | "cell_type": "markdown", 2161 | "metadata": {}, 2162 | "source": [ 2163 | "### 相关系数" 2164 | ] 2165 | }, 2166 | { 2167 | "cell_type": "code", 2168 | "execution_count": null, 2169 | "metadata": { 2170 | "ExecuteTime": { 2171 | "end_time": "2020-08-31T07:37:23.464372Z", 2172 | "start_time": "2020-08-31T07:37:23.455025Z" 2173 | } 2174 | }, 2175 | "outputs": [], 2176 | "source": [ 2177 | "# 超储率相关系数\n", 2178 | "data1 = FinData.loc[PnL.index, '超额存款准备金率(超储率):金融机构'].ewm(60).mean()\n", 2179 | "data2 = PnL.ewm(60).mean()\n", 2180 | "\n", 2181 | "np.corrcoef(data1, data2)" 2182 | ] 2183 | }, 2184 | { 2185 | "cell_type": "code", 2186 | "execution_count": null, 2187 | "metadata": { 2188 | "ExecuteTime": { 2189 | "end_time": "2020-08-31T07:37:23.476650Z", 2190 | "start_time": "2020-08-31T07:37:23.466692Z" 2191 | } 2192 | }, 2193 | "outputs": [], 2194 | "source": [ 2195 | "# 10年国债收益率\n", 2196 | "data1 = Returns.loc[PnL.index, '10年国债'].ewm(60).mean()\n", 2197 | "data2 = PnL.ewm(60).mean()\n", 2198 | "\n", 2199 | "np.corrcoef(data1, data2)" 2200 | ] 2201 | }, 2202 | { 2203 | "cell_type": "code", 2204 | "execution_count": null, 2205 | "metadata": { 2206 | "ExecuteTime": { 2207 | "end_time": "2020-08-31T07:37:23.488112Z", 2208 | "start_time": "2020-08-31T07:37:23.478813Z" 2209 | } 2210 | }, 2211 | "outputs": [], 2212 | "source": [ 2213 | "# 10年美债收益率\n", 2214 | "data1 = Returns.loc[PnL.index, '10年美债'].ewm(60).mean()\n", 2215 | "data2 = PnL.ewm(60).mean()\n", 2216 | "\n", 2217 | "np.corrcoef(data1, data2)" 2218 | ] 2219 | }, 2220 | { 2221 | "cell_type": "code", 2222 | "execution_count": null, 2223 | "metadata": { 2224 | "ExecuteTime": { 2225 | "end_time": "2020-08-31T07:37:23.498834Z", 2226 | "start_time": "2020-08-31T07:37:23.490137Z" 2227 | } 2228 | }, 2229 | "outputs": [], 2230 | "source": [ 2231 | "# 美元价格指数\n", 2232 | "data1 = FXRates.loc[PnL.index, '美元指数'].ewm(60).mean()\n", 2233 | "data2 = PnL.ewm(60).mean()\n", 2234 | "\n", 2235 | "np.corrcoef(data1, data2)" 2236 | ] 2237 | }, 2238 | { 2239 | "cell_type": "markdown", 2240 | "metadata": {}, 2241 | "source": [ 2242 | "### 流动性与投资组合表现" 2243 | ] 2244 | }, 2245 | { 2246 | "cell_type": "code", 2247 | "execution_count": null, 2248 | "metadata": { 2249 | "ExecuteTime": { 2250 | "end_time": "2020-08-31T07:37:27.736364Z", 2251 | "start_time": "2020-08-31T07:37:23.500784Z" 2252 | } 2253 | }, 2254 | "outputs": [], 2255 | "source": [ 2256 | "# 超储率\n", 2257 | "fig, ax1 = plt.subplots(1,1,figsize=(16,6), dpi=150)\n", 2258 | "\n", 2259 | "data_tmp = FinData.loc[PnL.index, '超额存款准备金率(超储率):金融机构'].ewm(60).mean()\n", 2260 | "\n", 2261 | "ax1.plot(data_tmp.index, data_tmp, label='超储率(60移动平均)', zorder=0)\n", 2262 | "ax1.plot(data_tmp.shift(-120).index, data_tmp.shift(-120), ls='--', label='超储率(60移动平均,120天平移)', zorder=1)\n", 2263 | "\n", 2264 | "ax1.legend(loc='upper left')\n", 2265 | "ax1.set_xlabel('时间')\n", 2266 | "ax1.set_ylabel('比率')\n", 2267 | "ax1.grid(True)\n", 2268 | "\n", 2269 | "ax2 = ax1.twinx() \n", 2270 | "ax2.bar(PnL.index, PnL.ewm(60).mean(), label='模型E_日收益率(60移动平均)', color='tab:orange')\n", 2271 | "\n", 2272 | "ax2.legend(loc='upper right')\n", 2273 | "ax2.set_ylabel('投资组合净值')\n", 2274 | "\n", 2275 | "plt.title('超储率与投资组合日收益率关系')\n", 2276 | "plt.show()" 2277 | ] 2278 | }, 2279 | { 2280 | "cell_type": "code", 2281 | "execution_count": null, 2282 | "metadata": { 2283 | "ExecuteTime": { 2284 | "end_time": "2020-08-31T07:37:31.775332Z", 2285 | "start_time": "2020-08-31T07:37:27.738575Z" 2286 | } 2287 | }, 2288 | "outputs": [], 2289 | "source": [ 2290 | "# 10年国债\n", 2291 | "fig, ax1 = plt.subplots(1,1,figsize=(16,6), dpi=150)\n", 2292 | "\n", 2293 | "ax1.plot(Returns.index, Returns['10年国债'].ewm(60).mean(), label='10年国债_日收益率(60移动平均)', zorder=0)\n", 2294 | "\n", 2295 | "ax1.legend(loc='upper left')\n", 2296 | "ax1.set_xlabel('时间')\n", 2297 | "ax1.set_ylabel('比率')\n", 2298 | "ax1.grid(True)\n", 2299 | "\n", 2300 | "ax2 = ax1.twinx() \n", 2301 | "ax2.bar(PnL.index, PnL.ewm(60).mean(), label='模型E_日收益率(60移动平均)', color='tab:orange')\n", 2302 | "\n", 2303 | "ax2.legend(loc='upper right')\n", 2304 | "ax2.set_ylabel('投资组合净值')\n", 2305 | "\n", 2306 | "plt.title('10年国债日收益率与投资组合日收益率关系')\n", 2307 | "plt.show()" 2308 | ] 2309 | }, 2310 | { 2311 | "cell_type": "code", 2312 | "execution_count": null, 2313 | "metadata": { 2314 | "ExecuteTime": { 2315 | "end_time": "2020-08-31T07:37:36.494961Z", 2316 | "start_time": "2020-08-31T07:37:31.777588Z" 2317 | } 2318 | }, 2319 | "outputs": [], 2320 | "source": [ 2321 | "# 10年美债\n", 2322 | "fig, ax1 = plt.subplots(1,1,figsize=(16,6), dpi=150)\n", 2323 | "\n", 2324 | "ax1.plot(Returns.index, Returns['10年美债'].ewm(60).mean(), label='10年美债_日收益率(60移动平均)', zorder=1)\n", 2325 | "\n", 2326 | "ax1.legend(loc='upper left')\n", 2327 | "ax1.set_xlabel('时间')\n", 2328 | "ax1.set_ylabel('比率')\n", 2329 | "ax1.grid(True)\n", 2330 | "\n", 2331 | "ax2 = ax1.twinx() \n", 2332 | "ax2.bar(PnL.index, PnL.ewm(60).mean(), label='模型E_日收益率(60移动平均)', color='tab:orange')\n", 2333 | "\n", 2334 | "ax2.legend(loc='upper right')\n", 2335 | "ax2.set_ylabel('投资组合净值')\n", 2336 | "\n", 2337 | "plt.title('10年美债日收益率与投资组合日收益率关系')\n", 2338 | "plt.show()" 2339 | ] 2340 | }, 2341 | { 2342 | "cell_type": "code", 2343 | "execution_count": null, 2344 | "metadata": { 2345 | "ExecuteTime": { 2346 | "end_time": "2020-08-31T07:37:41.622095Z", 2347 | "start_time": "2020-08-31T07:37:36.499486Z" 2348 | } 2349 | }, 2350 | "outputs": [], 2351 | "source": [ 2352 | "# 美元指数\n", 2353 | "fig, ax1 = plt.subplots(1,1,figsize=(16,6), dpi=150)\n", 2354 | "\n", 2355 | "ax1.plot(FXRates.index, FXRates['美元指数'].ewm(60).mean(), label='美元指数(60移动平均)', zorder=1)\n", 2356 | "\n", 2357 | "ax1.legend(loc='upper left')\n", 2358 | "ax1.set_xlabel('时间')\n", 2359 | "ax1.set_ylabel('比率')\n", 2360 | "ax1.grid(True)\n", 2361 | "\n", 2362 | "ax2 = ax1.twinx() \n", 2363 | "ax2.bar(PnL.index, PnL.ewm(60).mean(), label='模型E_日收益率(60移动平均)', color='tab:orange')\n", 2364 | "\n", 2365 | "ax2.legend(loc='upper right')\n", 2366 | "ax2.set_ylabel('投资组合净值')\n", 2367 | "\n", 2368 | "plt.title('美元指数与投资组合日收益率关系')\n", 2369 | "plt.show()" 2370 | ] 2371 | }, 2372 | { 2373 | "cell_type": "code", 2374 | "execution_count": null, 2375 | "metadata": {}, 2376 | "outputs": [], 2377 | "source": [] 2378 | } 2379 | ], 2380 | "metadata": { 2381 | "kernelspec": { 2382 | "display_name": "Python 3", 2383 | "language": "python", 2384 | "name": "python3" 2385 | }, 2386 | "language_info": { 2387 | "codemirror_mode": { 2388 | "name": "ipython", 2389 | "version": 3 2390 | }, 2391 | "file_extension": ".py", 2392 | "mimetype": "text/x-python", 2393 | "name": "python", 2394 | "nbconvert_exporter": "python", 2395 | "pygments_lexer": "ipython3", 2396 | "version": "3.7.7" 2397 | }, 2398 | "latex_envs": { 2399 | "LaTeX_envs_menu_present": true, 2400 | "autoclose": false, 2401 | "autocomplete": true, 2402 | "bibliofile": "biblio.bib", 2403 | "cite_by": "apalike", 2404 | "current_citInitial": 1, 2405 | "eqLabelWithNumbers": true, 2406 | "eqNumInitial": 1, 2407 | "hotkeys": { 2408 | "equation": "Ctrl-E", 2409 | "itemize": "Ctrl-I" 2410 | }, 2411 | "labels_anchors": false, 2412 | "latex_user_defs": false, 2413 | "report_style_numbering": false, 2414 | "user_envs_cfg": false 2415 | }, 2416 | "toc": { 2417 | "base_numbering": 1, 2418 | "nav_menu": {}, 2419 | "number_sections": true, 2420 | "sideBar": true, 2421 | "skip_h1_title": false, 2422 | "title_cell": "Table of Contents", 2423 | "title_sidebar": "Contents", 2424 | "toc_cell": false, 2425 | "toc_position": { 2426 | "height": "calc(100% - 180px)", 2427 | "left": "10px", 2428 | "top": "150px", 2429 | "width": "326px" 2430 | }, 2431 | "toc_section_display": true, 2432 | "toc_window_display": true 2433 | } 2434 | }, 2435 | "nbformat": 4, 2436 | "nbformat_minor": 4 2437 | } 2438 | --------------------------------------------------------------------------------