投资组合的收益率与风险
不同相关系数下投资组合标准差随投资比例变动的情况
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
%matplotlib inline
设置calc_mean函数为采用的投资组合方式
def calc_mean(frac):
return (0.08* frac+0.15*(1-frac))
0.08* (1/50)+0.15*(1-(1/50))
0.14859999999999998
以x/50为权重(其中x属于0到50)进行投资组合(其实就是0到1中间等距抽权重)
mean=list(map(calc_mean,[x/50 for x in range(51)]))
mean
[0.15,
0.14859999999999998,
0.1472,
0.14579999999999999,
0.1444,
0.14300000000000002,
0.1416,
0.1402,
0.1388,
0.1374,
0.136,
0.1346,
0.13319999999999999,
0.1318,
0.13040000000000002,
0.129,
0.1276,
0.12619999999999998,
0.1248,
0.1234,
0.122,
0.12060000000000001,
0.1192,
0.1178,
0.1164,
0.11499999999999999,
0.1136,
0.1122,
0.1108,
0.1094,
0.108,
0.1066,
0.1052,
0.1038,
0.10239999999999999,
0.101,
0.0996,
0.09820000000000001,
0.0968,
0.0954,
0.094,
0.0926,
0.0912,
0.0898,
0.0884,
0.08700000000000001,
0.0856,
0.08420000000000001,
0.0828,
0.0814,
0.08]
[x/50 for x in range(51)] #0-1之间组合数据
[0.0,
0.02,
0.04,
0.06,
0.08,
0.1,
0.12,
0.14,
0.16,
0.18,
0.2,
0.22,
0.24,
0.26,
0.28,
0.3,
0.32,
0.34,
0.36,
0.38,
0.4,
0.42,
0.44,
0.46,
0.48,
0.5,
0.52,
0.54,
0.56,
0.58,
0.6,
0.62,
0.64,
0.66,
0.68,
0.7,
0.72,
0.74,
0.76,
0.78,
0.8,
0.82,
0.84,
0.86,
0.88,
0.9,
0.92,
0.94,
0.96,
0.98,
1.0]
计算不同相关系数的股票组合对应收益值
公式为(0.12x+0.25(1-x))的完全平方展开式,其中交叉项还乘以了相关系数。0.12和0.25分别为两种股票的收益率,x和(1-x)为标准差(或者权重,这里还没弄懂),最终得值为均值。
import math
sd_mat=np.array([list(map(lambda x :math.sqrt( (x**2)*0.12**2 \
+ ((1-x)**2)*0.25**2\
+ 2*x*(1-x)*(-1.5+i*0.5)*0.12*0.25)
,[x/50 for x in range(51)])) for i in range(1,6)]) #range表示左闭右开区间
sd_mat
array([[0.25 , 0.2426 , 0.2352 , 0.2278 , 0.2204 ,
0.213 , 0.2056 , 0.1982 , 0.1908 , 0.1834 ,
0.176 , 0.1686 , 0.1612 , 0.1538 , 0.1464 ,
0.139 , 0.1316 , 0.1242 , 0.1168 , 0.1094 ,
0.102 , 0.0946 , 0.0872 , 0.0798 , 0.0724 ,
0.065 , 0.0576 , 0.0502 , 0.0428 , 0.0354 ,
0.028 , 0.0206 , 0.0132 , 0.0058 , 0.0016 ,
0.009 , 0.0164 , 0.0238 , 0.0312 , 0.0386 ,
0.046 , 0.0534 , 0.0608 , 0.0682 , 0.0756 ,
0.083 , 0.0904 , 0.0978 , 0.1052 , 0.1126 ,
0.12 ],
[0.25 , 0.24380886, 0.23763636, 0.231484 , 0.22535341,
0.21924644, 0.2131651 , 0.20711166, 0.20108864, 0.19509885,
0.18914545, 0.18323198, 0.17736245, 0.17154137, 0.16577382,
0.16006561, 0.15442331, 0.14885443, 0.1433675 , 0.13797232,
0.13268007, 0.12750357, 0.1224575 , 0.11755867, 0.11282624,
0.10828204, 0.10395076, 0.0998601 , 0.09604082, 0.09252654,
0.08935323, 0.08655842, 0.08417981, 0.08225351, 0.08081188,
0.07988116, 0.07947931, 0.07961432, 0.0802835 , 0.08147368,
0.08316249, 0.08532034, 0.08791268, 0.09090237, 0.09425158,
0.09792344, 0.10188307, 0.10609826, 0.11053977, 0.11518142,
0.12 ],
[0.25 , 0.24501175, 0.240048 , 0.23511027, 0.23020026,
0.22531977, 0.22047077, 0.21565537, 0.21087589, 0.20613481,
0.20143485, 0.19677896, 0.19217034, 0.18761247, 0.18310915,
0.17866449, 0.17428299, 0.16996953, 0.16572942, 0.16156844,
0.15749286, 0.15350948, 0.14962567, 0.14584937, 0.14218917,
0.13865425, 0.13525443, 0.13200015, 0.12890244, 0.12597285,
0.12322337, 0.12066632, 0.11831416, 0.11617934, 0.11427406,
0.11260995, 0.11119784, 0.11004744, 0.10916703, 0.10856316,
0.10824047, 0.10820148, 0.10844648, 0.10897357, 0.10977869,
0.11085576, 0.11219697, 0.11379297, 0.11563321, 0.11770624,
0.12 ],
[0.25 , 0.24620877, 0.24243564, 0.23868146, 0.23494714,
0.23123365, 0.227542 , 0.22387327, 0.22022861, 0.21660923,
0.21301643, 0.20945157, 0.2059161 , 0.20241156, 0.19893959,
0.19550192, 0.19210039, 0.18873696, 0.1854137 , 0.18213281,
0.17889662, 0.1757076 , 0.17256836, 0.16948168, 0.16645047,
0.16347783, 0.160567 , 0.1577214 , 0.15494464, 0.15224047,
0.14961283, 0.14706584, 0.14460373, 0.14223094, 0.13995199,
0.13777155, 0.13569436, 0.13372524, 0.13186903, 0.13013055,
0.12851459, 0.12702582, 0.12566877, 0.12444774, 0.12336677,
0.12242957, 0.12163947, 0.12099934, 0.12051158, 0.12017803,
0.12 ],
[0.25 , 0.2474 , 0.2448 , 0.2422 , 0.2396 ,
0.237 , 0.2344 , 0.2318 , 0.2292 , 0.2266 ,
0.224 , 0.2214 , 0.2188 , 0.2162 , 0.2136 ,
0.211 , 0.2084 , 0.2058 , 0.2032 , 0.2006 ,
0.198 , 0.1954 , 0.1928 , 0.1902 , 0.1876 ,
0.185 , 0.1824 , 0.1798 , 0.1772 , 0.1746 ,
0.172 , 0.1694 , 0.1668 , 0.1642 , 0.1616 ,
0.159 , 0.1564 , 0.1538 , 0.1512 , 0.1486 ,
0.146 , 0.1434 , 0.1408 , 0.1382 , 0.1356 ,
0.133 , 0.1304 , 0.1278 , 0.1252 , 0.1226 ,
0.12 ]])
sd_mat.shape
(5, 51)
不同相关系数均值和标准差关系图
label为相关系数,横轴为标准差,纵轴为均值。
plt.plot(sd_mat[0,:],mean,label="-1")
plt.plot(sd_mat[1,:],mean,label="-0.5")
plt.plot(sd_mat[2,:],mean,label="0")
plt.plot(sd_mat[3,:],mean,label="0.5")
plt.plot(sd_mat[4,:],mean,label="1")
plt.legend(loc="upper left")
<matplotlib.legend.Legend at 0x18896d0b7c0>
Markowitz模型实现
先导入股票,本次实现使用股票为600004、600015、600023、600033、600183,分别对应白云机场、华夏银行、浙能电力、福建高速和生益科技股票。
目前我国000或002开头的就是深证的,600开头的是上证的,300开头的是创业板zhi 200开头的是深圳B股,900开头的是上海B股。
获取各只股票日线行情数据
import tushare as ts
pro = ts.pro_api('4c1fa508ab60e554d221c55a47dfa557a6c7bfd0c239b45657c2262d')
df = pro.daily(ts_code='600004.SH', start_date='20200101', end_date='20201231')
df.head()
ts_code | trade_date | open | high | low | close | pre_close | change | pct_chg | vol | amount | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 600004.SH | 20201231 | 13.80 | 14.30 | 13.70 | 14.13 | 13.63 | 0.50 | 3.6684 | 186855.09 | 261417.827 |
1 | 600004.SH | 20201230 | 13.36 | 13.72 | 13.25 | 13.63 | 13.37 | 0.26 | 1.9447 | 105098.32 | 142205.693 |
2 | 600004.SH | 20201229 | 13.18 | 13.61 | 13.18 | 13.37 | 13.27 | 0.10 | 0.7536 | 97057.08 | 130418.052 |
3 | 600004.SH | 20201228 | 13.43 | 13.45 | 13.17 | 13.27 | 13.48 | -0.21 | -1.5579 | 120737.86 | 160222.485 |
4 | 600004.SH | 20201225 | 13.25 | 13.50 | 13.22 | 13.48 | 13.35 | 0.13 | 0.9738 | 57026.12 | 76510.480 |
byjc = df.set_index(["trade_date"])
byjc.index = pd.to_datetime(byjc.index)
byjc.head(10)
ts_code | open | high | low | close | pre_close | change | pct_chg | vol | amount | |
---|---|---|---|---|---|---|---|---|---|---|
trade_date | ||||||||||
2020-12-31 | 600004.SH | 13.80 | 14.30 | 13.70 | 14.13 | 13.63 | 0.50 | 3.6684 | 186855.09 | 261417.827 |
2020-12-30 | 600004.SH | 13.36 | 13.72 | 13.25 | 13.63 | 13.37 | 0.26 | 1.9447 | 105098.32 | 142205.693 |
2020-12-29 | 600004.SH | 13.18 | 13.61 | 13.18 | 13.37 | 13.27 | 0.10 | 0.7536 | 97057.08 | 130418.052 |
2020-12-28 | 600004.SH | 13.43 | 13.45 | 13.17 | 13.27 | 13.48 | -0.21 | -1.5579 | 120737.86 | 160222.485 |
2020-12-25 | 600004.SH | 13.25 | 13.50 | 13.22 | 13.48 | 13.35 | 0.13 | 0.9738 | 57026.12 | 76510.480 |
2020-12-24 | 600004.SH | 13.35 | 13.41 | 13.18 | 13.35 | 13.35 | 0.00 | 0.0000 | 78080.01 | 104002.222 |
2020-12-23 | 600004.SH | 13.39 | 13.46 | 13.25 | 13.35 | 13.35 | 0.00 | 0.0000 | 122316.53 | 163204.891 |
2020-12-22 | 600004.SH | 13.96 | 13.96 | 13.31 | 13.35 | 14.12 | -0.77 | -5.4533 | 256419.53 | 348439.957 |
2020-12-21 | 600004.SH | 14.05 | 14.15 | 13.63 | 14.12 | 14.21 | -0.09 | -0.6334 | 128751.81 | 179205.692 |
2020-12-18 | 600004.SH | 14.43 | 14.43 | 14.15 | 14.21 | 14.43 | -0.22 | -1.5246 | 82641.45 | 117739.517 |
data = pro.daily(ts_code='600015.SH', start_date='20200101', end_date='20201231')
hxyh = data.set_index(["trade_date"])
hxyh.index=pd.to_datetime(hxyh.index) #时间类型
hxyh.head(10)
ts_code | open | high | low | close | pre_close | change | pct_chg | vol | amount | |
---|---|---|---|---|---|---|---|---|---|---|
trade_date | ||||||||||
2020-12-31 | 600015.SH | 6.17 | 6.28 | 6.17 | 6.25 | 6.19 | 0.06 | 0.9693 | 323628.00 | 202126.611 |
2020-12-30 | 600015.SH | 6.14 | 6.19 | 6.12 | 6.19 | 6.15 | 0.04 | 0.6504 | 171216.96 | 105291.236 |
2020-12-29 | 600015.SH | 6.14 | 6.17 | 6.13 | 6.15 | 6.14 | 0.01 | 0.1629 | 138161.26 | 84991.588 |
2020-12-28 | 600015.SH | 6.16 | 6.18 | 6.12 | 6.14 | 6.17 | -0.03 | -0.4862 | 142068.40 | 87339.651 |
2020-12-25 | 600015.SH | 6.15 | 6.21 | 6.15 | 6.17 | 6.17 | 0.00 | 0.0000 | 166727.73 | 102964.436 |
2020-12-24 | 600015.SH | 6.18 | 6.22 | 6.14 | 6.17 | 6.18 | -0.01 | -0.1618 | 109642.01 | 67734.194 |
2020-12-23 | 600015.SH | 6.18 | 6.19 | 6.13 | 6.18 | 6.18 | 0.00 | 0.0000 | 151969.90 | 93657.059 |
2020-12-22 | 600015.SH | 6.23 | 6.24 | 6.16 | 6.18 | 6.24 | -0.06 | -0.9615 | 175320.62 | 108670.014 |
2020-12-21 | 600015.SH | 6.23 | 6.26 | 6.20 | 6.24 | 6.23 | 0.01 | 0.1605 | 131370.60 | 81852.468 |
2020-12-18 | 600015.SH | 6.23 | 6.27 | 6.21 | 6.23 | 6.24 | -0.01 | -0.1603 | 150797.28 | 94042.457 |
data = pro.daily(ts_code='600023.SH', start_date='20200101', end_date='20201231')
zndl = data.set_index(["trade_date"])
zndl.index=pd.to_datetime(zndl.index) #时间类型
zndl.head(10)