本文基于tushare数据构造有效前沿曲线(个人的tushareID:498867)
有效前沿是在给定投资范围,return-risk约束条件下同等风险情况下收益最大的的资产配置集合。
# Provides ways to work with large multidimensional arrays
import numpy as np
# Allows for further data manipulation and analysis
import pandas as pd
from pandas_datareader import data as web # Reads stock data
import matplotlib.pyplot as plt # Plotting
import matplotlib.dates as mdates # Styling dates
%matplotlib inline
import datetime as dt # For defining dates
import mplfinance as mpf # Matplotlib finance
import time
# Used to get data from a directory
import os
from os import listdir
from os.path import isfile, join
#Statsmodels is a great library we can use to run regressions.
import statsmodels.api as sm
# Seaborn extends the capabilities of Matplotlib
import seaborn as sns
# Used for calculating regressions
from statsmodels.tsa.ar_model import AutoReg, ar_select_order
name=['600418.SH', '603355.SH', '002429.SZ', '002945.SZ', '002423.SZ',
'300376.SZ', '000656.SZ', '600985.SH', '600392.SH', '002085.SZ',
'601106.SH', '600188.SH', '002958.SZ', '601611.SH', '688321.SH',
'300724.SZ', '603267.SH', '002152.SZ', '603056.SH', '600968.SH']
# 导入tushare
import tushare as ts
import pandas as pd
dff=pd.DataFrame()
# 初始化pro接口
pro = ts.pro_api('你的token')
for i in name:
# 导入tushare
# 拉取数据
try:
df = pro.daily(**{
"ts_code": i,
"trade_date": "",
"start_date": "20200101",
"end_date": "20220101",
"offset": "",
"limit": ""
}, fields=[
"ts_code",
"trade_date",
"open",
"high",
"low",
"close",
"pre_close",
"change",
"pct_chg",
"vol",
"amount"
])
dff[i]=df['pct_chg'].values
except:
pass
dff['trade_date']=df['trade_date'].values
dff=dff.sort_values('trade_date')
dff=dff.set_index('trade_date')
port_list = list(dff.columns)
mean_ret = dff.mean() * 252 # 252 average trading days per year
dff.cov() * 252
weights = np.random.random(len(port_list))
weights /= np.sum(weights)
print('Weights :', weights)
print('Total Weight :', np.sum(weights))
np.sum(weights * mean_ret)
np.sqrt(np.dot(weights.T, np.dot(dff.cov() * 252, weights)))
p_ret = [] # Returns list
p_vol = [] # Volatility list
p_SR = [] # Sharpe Ratio list
p_wt = [] # Stock weights list
risk_free_rate = 0.0125
n=len(port_list)
for x in range(40000):
# Generate random weights
p_weights = np.random.random(n)
p_weights /= np.sum(p_weights)
# Add return using those weights to list
ret_1 = np.sum(p_weights * mean_ret) * 252
p_ret.append(ret_1)
# Add volatility or standard deviation to list
vol_1 = np.sqrt(np.dot(p_weights.T, np.dot(dff.cov() * 252, p_weights)))
p_vol.append(vol_1)
# Get Sharpe ratio
SR_1 = (ret_1 - risk_free_rate) / vol_1
p_SR.append(SR_1)
# Store the weights for each portfolio
p_wt.append(p_weights)
# Convert to Numpy arrays
p_ret = np.array(p_ret)
p_vol = np.array(p_vol)
p_SR = np.array(p_SR)
p_wt = np.array(p_wt)
p_ret, p_vol, p_SR, p_wt
# Create a dataframe with returns and volatility
ports = pd.DataFrame({'Return': p_ret, 'Volatility': p_vol})
ports.plot(x='Volatility', y='Return', kind='scatter', figsize=(16, 9))
最后得到如下图: