siat 3.3.12__py3-none-any.whl → 3.4.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
siat/markowitz2.py
CHANGED
@@ -819,10 +819,13 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='papayawhip'):
|
|
819
819
|
#临时保存,避免影响原值
|
820
820
|
pr=portfolio_returns.copy()
|
821
821
|
|
822
|
+
#统一核定小数位数
|
823
|
+
ndecimals=2
|
824
|
+
|
822
825
|
#以pname组合作为基准
|
823
826
|
import numpy as np
|
824
827
|
mean_return_pname=pr[pname].mean(axis=0)
|
825
|
-
annual_return_pname=round(((1 + mean_return_pname)**252 - 1)*100,
|
828
|
+
annual_return_pname=round(((1 + mean_return_pname)**252 - 1)*100,ndecimals)
|
826
829
|
"""
|
827
830
|
if annual_return_pname > 0:
|
828
831
|
pct_style=True #百分比模式
|
@@ -832,7 +835,7 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='papayawhip'):
|
|
832
835
|
pct_style=False
|
833
836
|
|
834
837
|
std_return_pname=pr[pname].std(axis=0)
|
835
|
-
annual_std_pname= round((std_return_pname*np.sqrt(252))*100,
|
838
|
+
annual_std_pname= round((std_return_pname*np.sqrt(252))*100,ndecimals)
|
836
839
|
|
837
840
|
import pandas as pd
|
838
841
|
#prr=pd.DataFrame(columns=["名称","年化收益率","收益率变化","年化标准差","标准差变化","收益/风险"])
|
@@ -843,12 +846,12 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='papayawhip'):
|
|
843
846
|
|
844
847
|
#年化收益率:按列求均值
|
845
848
|
mean_return=pr[c].mean(axis=0)
|
846
|
-
annual_return = round(((1 + mean_return)**252 - 1)*100,
|
849
|
+
annual_return = round(((1 + mean_return)**252 - 1)*100,ndecimals)
|
847
850
|
|
848
851
|
if pct_style:
|
849
|
-
return_chg=round((annual_return - annual_return_pname) / annual_return_pname * 100,
|
852
|
+
return_chg=round((annual_return - annual_return_pname) / annual_return_pname * 100,ndecimals)
|
850
853
|
else:
|
851
|
-
return_chg=round((annual_return - annual_return_pname),
|
854
|
+
return_chg=round((annual_return - annual_return_pname),ndecimals)
|
852
855
|
|
853
856
|
#收益率变化
|
854
857
|
if return_chg==0:
|
@@ -866,15 +869,15 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='papayawhip'):
|
|
866
869
|
|
867
870
|
#年化标准差
|
868
871
|
std_return=pr[c].std(axis=0)
|
869
|
-
annual_std = round((std_return*np.sqrt(252))*100,
|
872
|
+
annual_std = round((std_return*np.sqrt(252))*100,ndecimals)
|
870
873
|
|
871
874
|
#sharpe_ratio=round(annual_return / annual_std,2)
|
872
|
-
sharpe_ratio=round((annual_return) / annual_std,
|
875
|
+
sharpe_ratio=round((annual_return) / annual_std,ndecimals)
|
873
876
|
|
874
877
|
if pct_style:
|
875
|
-
std_chg=round((annual_std - annual_std_pname) / annual_std_pname * 100,
|
878
|
+
std_chg=round((annual_std - annual_std_pname) / annual_std_pname * 100,ndecimals)
|
876
879
|
else:
|
877
|
-
std_chg=round((annual_std - annual_std_pname),
|
880
|
+
std_chg=round((annual_std - annual_std_pname),ndecimals)
|
878
881
|
|
879
882
|
#标准差变化
|
880
883
|
if std_chg==0:
|
@@ -953,19 +956,32 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='papayawhip'):
|
|
953
956
|
|
954
957
|
prr2.rename(columns={"投资组合名称/策略":text_lang("投资组合名称/策略","Strategy"), \
|
955
958
|
"收益排名":text_lang("收益排名","Return#"), \
|
956
|
-
"年化收益率%":text_lang("年化收益率%","
|
959
|
+
"年化收益率%":text_lang("年化收益率%","pa Return%"), \
|
957
960
|
"收益率变化":text_lang("收益率变化","Return%+/-"), \
|
958
961
|
"风险排名":text_lang("风险排名","Risk#"), \
|
959
|
-
"年化标准差%":text_lang("年化标准差%","
|
962
|
+
"年化标准差%":text_lang("年化标准差%","pa Std%"), \
|
960
963
|
"标准差变化":text_lang("标准差变化","Std%+/-"), \
|
961
964
|
"收益率/标准差":text_lang("收益率/标准差","Return/Std")}, \
|
962
965
|
inplace=True)
|
963
966
|
|
964
|
-
|
967
|
+
#重新排名:相同的值赋予相同的序号
|
968
|
+
prr2["pa Return%"]=prr2["pa Return%"].apply(lambda x: round(float(x),ndecimals))
|
969
|
+
prr2["Return#"]=prr2["pa Return%"].rank(ascending=False,method='dense')
|
970
|
+
prr2["Return#"]=prr2["Return#"].apply(lambda x: int(x))
|
971
|
+
|
972
|
+
prr2["pa Std%"]=prr2["pa Std%"].apply(lambda x: round(float(x),ndecimals))
|
973
|
+
prr2["Risk#"]=prr2["pa Std%"].rank(ascending=False,method='dense')
|
974
|
+
prr2["Risk#"]=prr2["Risk#"].apply(lambda x: int(x))
|
975
|
+
|
976
|
+
prr2["Return/Std"]=prr2["Return/Std"].apply(lambda x: round(float(x),ndecimals))
|
977
|
+
prr2["Ret/Std#"]=prr2["Return/Std"].rank(ascending=False,method='dense')
|
978
|
+
prr2["Ret/Std#"]=prr2["Ret/Std#"].apply(lambda x: int(x))
|
979
|
+
|
980
|
+
df_display_CSS(prr2,titletxt=titletxt,footnote='',facecolor='papayawhip',decimals=ndecimals, \
|
965
981
|
first_col_align='left',second_col_align='center', \
|
966
|
-
last_col_align='
|
967
|
-
titile_font_size='
|
968
|
-
data_font_size='
|
982
|
+
last_col_align='center',other_col_align='center', \
|
983
|
+
titile_font_size='15px',heading_font_size='14px', \
|
984
|
+
data_font_size='14px')
|
969
985
|
|
970
986
|
"""
|
971
987
|
print(' ') #空一行
|
@@ -1110,23 +1126,37 @@ def portfolio_ranks_en(portfolio_returns,pname):
|
|
1110
1126
|
|
1111
1127
|
#==============================================================================
|
1112
1128
|
if __name__=='__main__':
|
1113
|
-
|
1129
|
+
#Define market information and name of the portfolio: Banking #1
|
1130
|
+
Market={'Market':('China','000300.SS','Banking #1')}
|
1131
|
+
#First batch of component stocks
|
1132
|
+
Stocks1={'601939.SS':.3,#CCB Bank
|
1133
|
+
'600000.SS':.3, #SPDB Bank
|
1134
|
+
'600036.SS':.2, #CMB Bank
|
1135
|
+
'601166.SS':.2,#Industrial Bank
|
1136
|
+
}
|
1137
|
+
portfolio=dict(Market,**Stocks1)
|
1138
|
+
|
1139
|
+
pf_info=portfolio_build(portfolio,thedate='2024-7-17')
|
1140
|
+
|
1114
1141
|
simulation=50000
|
1142
|
+
convex_hull=True; frontier="both"; facecolor='papayawhip'
|
1115
1143
|
|
1116
1144
|
portfolio_eset(pf_info,simulation=50000)
|
1117
1145
|
|
1118
|
-
def portfolio_feset(pf_info,simulation=50000,convex_hull=True,facecolor='papayawhip'):
|
1146
|
+
def portfolio_feset(pf_info,simulation=50000,convex_hull=True,frontier="both",facecolor='papayawhip'):
|
1119
1147
|
|
1120
|
-
results=portfolio_eset(pf_info,simulation=simulation,convex_hull=convex_hull,facecolor=facecolor)
|
1148
|
+
results=portfolio_eset(pf_info,simulation=simulation,convex_hull=convex_hull,frontier=frontier,facecolor=facecolor)
|
1121
1149
|
|
1122
1150
|
return results
|
1123
1151
|
|
1124
1152
|
|
1125
|
-
def portfolio_eset(pf_info,simulation=50000,convex_hull=False,facecolor='papayawhip'):
|
1153
|
+
def portfolio_eset(pf_info,simulation=50000,convex_hull=False,frontier="both",facecolor='papayawhip'):
|
1126
1154
|
"""
|
1127
1155
|
功能:基于随机数,生成大量可能的投资组合,计算各个投资组合的年均收益率和标准差,绘制投资组合的可行集
|
1128
1156
|
默认绘制散点图凸包:convex_hull=True
|
1129
1157
|
"""
|
1158
|
+
DEBUG=True; MORE_DETAIL=False
|
1159
|
+
|
1130
1160
|
[[portfolio,thedate,stock_return,_,_],_]=pf_info
|
1131
1161
|
pname=portfolio_name(portfolio)
|
1132
1162
|
_,_,tickerlist,_,ticker_type=decompose_portfolio(portfolio)
|
@@ -1176,7 +1206,6 @@ def portfolio_eset(pf_info,simulation=50000,convex_hull=False,facecolor='papayaw
|
|
1176
1206
|
+ ['Returns', 'Volatility']
|
1177
1207
|
|
1178
1208
|
# 绘制散点图
|
1179
|
-
print('')
|
1180
1209
|
"""
|
1181
1210
|
RandomPortfolios.plot('Volatility','Returns',kind='scatter',color='y',edgecolors='k')
|
1182
1211
|
"""
|
@@ -1193,6 +1222,8 @@ def portfolio_eset(pf_info,simulation=50000,convex_hull=False,facecolor='papayaw
|
|
1193
1222
|
|
1194
1223
|
#绘制散点图轮廓线凸包(convex hull)
|
1195
1224
|
if convex_hull:
|
1225
|
+
print(" Calculating convex hull ...")
|
1226
|
+
|
1196
1227
|
from scipy.spatial import ConvexHull
|
1197
1228
|
|
1198
1229
|
#构造散点对的列表
|
@@ -1204,29 +1235,85 @@ def portfolio_eset(pf_info,simulation=50000,convex_hull=False,facecolor='papayaw
|
|
1204
1235
|
y=pf_returns_list[pos]
|
1205
1236
|
points=points+[[x,y]]
|
1206
1237
|
|
1238
|
+
#寻找最左侧的坐标:在x最小的同时,y要最大
|
1239
|
+
points_df = pd.DataFrame(points, columns=['x', 'y'])
|
1240
|
+
points_df.sort_values(by=['x','y'],ascending=[True,False],inplace=True)
|
1241
|
+
x1,y1=points_df.head(1).values[0]
|
1242
|
+
if DEBUG and MORE_DETAIL:
|
1243
|
+
print("\n*** Leftmost point (x1,y1):",x1,y1)
|
1244
|
+
|
1245
|
+
#寻找最高点的坐标:在y最大的同时,x要最小
|
1246
|
+
points_df.sort_values(by=['y','x'],ascending=[False,True],inplace=True)
|
1247
|
+
x2,y2=points_df.head(1).values[0]
|
1248
|
+
if DEBUG and MORE_DETAIL:
|
1249
|
+
print("*** Highest point (x2,y2):",x2,y2)
|
1250
|
+
|
1251
|
+
if DEBUG:
|
1252
|
+
plt.plot([x1,x2],[y1,y2],ls=':',lw=2,alpha=0.5)
|
1253
|
+
|
1254
|
+
#建立最左侧和最高点之间的拟合直线方程y=a+bx
|
1255
|
+
a=(x1*y2-x2*y1)/(x1-x2); b=(y1-y2)/(x1-x2)
|
1256
|
+
def y_bar(x_bar):
|
1257
|
+
return a+b*x_bar
|
1258
|
+
|
1207
1259
|
# 计算散点集的外轮廓
|
1208
|
-
hull = ConvexHull(points)
|
1260
|
+
hull = ConvexHull(points)
|
1261
|
+
|
1209
1262
|
# 绘制外轮廓线
|
1263
|
+
firsttime_efficient=True; firsttime_inefficient=True
|
1210
1264
|
for simplex in hull.simplices:
|
1265
|
+
#p1中是一条线段起点和终点的横坐标
|
1266
|
+
p1=[points[simplex[0]][0], points[simplex[1]][0]]
|
1267
|
+
px1=p1[0];px2=p1[1]
|
1268
|
+
#p2中是一条线段起点和终点的纵坐标
|
1269
|
+
p2=[points[simplex[0]][1], points[simplex[1]][1]]
|
1270
|
+
py1=p2[0]; py2=p2[1]
|
1271
|
+
|
1272
|
+
if DEBUG and MORE_DETAIL:
|
1273
|
+
print("\n*** Hull line start (px1,py1):",px1,py1)
|
1274
|
+
print("*** Hull line end (px2,py2):",px2,py2)
|
1275
|
+
|
1276
|
+
"""
|
1211
1277
|
plt.plot([points[simplex[0]][0], points[simplex[1]][0]],
|
1212
1278
|
[points[simplex[0]][1], points[simplex[1]][1]], 'k-.')
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1279
|
+
"""
|
1280
|
+
|
1281
|
+
#线段起点:px1,py1;线段终点:px2,py2
|
1282
|
+
if DEBUG and MORE_DETAIL:
|
1283
|
+
is_efficient=(py1>=y_bar(px1) or py1==y1) and (py2>=y_bar(px2) or py2==y2)
|
1284
|
+
print("\n*** is_efficient:",is_efficient)
|
1285
|
+
print("py1=",py1,"y_bar1",y_bar(px1),"y1=",y1,"py2=",py2,"ybar2=",y_bar(px2),"y2=",y2)
|
1286
|
+
if px1==x1 and py1==y1:
|
1287
|
+
print("====== This is the least risk point !")
|
1288
|
+
if px2==x2 and py2==y2:
|
1289
|
+
print("====== This is the highest return point !")
|
1290
|
+
|
1291
|
+
#坐标对[px1,py1]既可能作为开始点,也可能作为结束点,[px2,py2]同样
|
1292
|
+
if ((py1>=y_bar(px1) or py1==y1) and (py2>=y_bar(px2) or py2==y2)) or \
|
1293
|
+
((py1>=y_bar(px2) or py1==y2) and (py2>=y_bar(px1) or py2==y1)):
|
1294
|
+
|
1295
|
+
#有效边界
|
1296
|
+
if frontier.lower() in ['both','efficient']:
|
1297
|
+
if firsttime_efficient:
|
1298
|
+
plt.plot(p1,p2, 'r--',label=text_lang("有效边界","Efficient Frontier"),lw=3,alpha=0.5)
|
1299
|
+
firsttime_efficient=False
|
1300
|
+
else:
|
1301
|
+
plt.plot(p1,p2, 'r--',lw=3,alpha=0.5)
|
1302
|
+
else:
|
1303
|
+
pass
|
1304
|
+
else:
|
1305
|
+
#其余边沿
|
1306
|
+
if frontier.lower() in ['both','inefficient']:
|
1307
|
+
if firsttime_inefficient:
|
1308
|
+
plt.plot(p1,p2, 'k-.',label=text_lang("无效边界","Inefficient Frontier"),alpha=0.5)
|
1309
|
+
firsttime_inefficient=False
|
1310
|
+
else:
|
1311
|
+
plt.plot(p1,p2, 'k-.',alpha=0.5)
|
1312
|
+
else:
|
1313
|
+
pass
|
1314
|
+
else:
|
1315
|
+
print('')
|
1316
|
+
|
1230
1317
|
|
1231
1318
|
import datetime as dt; stoday=dt.date.today()
|
1232
1319
|
lang = check_language()
|
@@ -1256,6 +1343,7 @@ def portfolio_eset(pf_info,simulation=50000,convex_hull=False,facecolor='papayaw
|
|
1256
1343
|
plt.xlabel(footnote1+footnote2+footnote3+footnote4,fontsize=xlabel_txt_size)
|
1257
1344
|
|
1258
1345
|
plt.gca().set_facecolor(facecolor)
|
1346
|
+
plt.legend(loc='best')
|
1259
1347
|
plt.show()
|
1260
1348
|
|
1261
1349
|
return [pf_info,RandomPortfolios]
|
@@ -1698,7 +1786,7 @@ if __name__=='__main__':
|
|
1698
1786
|
#==============================================================================
|
1699
1787
|
def RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
|
1700
1788
|
ylabeltxt,x_axis_name,pname,simulation,hstart,hend, \
|
1701
|
-
hiret_point,lorisk_point,convex_hull=True, \
|
1789
|
+
hiret_point,lorisk_point,convex_hull=True,frontier='efficient', \
|
1702
1790
|
facecolor="papayawhip"):
|
1703
1791
|
"""
|
1704
1792
|
功能:将生成的马科维茨可行集RandomPortfolios绘制成彩色散点图
|
@@ -1726,7 +1814,8 @@ def RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
|
|
1726
1814
|
plt.xlabel(footnote1+footnote2+footnote3+footnote4)
|
1727
1815
|
plt.show()
|
1728
1816
|
"""
|
1729
|
-
|
1817
|
+
DEBUG=False
|
1818
|
+
|
1730
1819
|
#RandomPortfolios.plot(col_x,col_y,kind='scatter',color='y',edgecolors='k')
|
1731
1820
|
|
1732
1821
|
pf_ratio = np.array(RandomPortfolios[col_y] / RandomPortfolios[col_x])
|
@@ -1739,6 +1828,7 @@ def RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
|
|
1739
1828
|
|
1740
1829
|
#绘制散点图轮廓线凸包(convex hull)
|
1741
1830
|
if convex_hull:
|
1831
|
+
print(" Calculating convex hull ...")
|
1742
1832
|
from scipy.spatial import ConvexHull
|
1743
1833
|
|
1744
1834
|
#构造散点对的列表
|
@@ -1750,13 +1840,65 @@ def RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
|
|
1750
1840
|
y=pf_returns_list[pos]
|
1751
1841
|
points=points+[[x,y]]
|
1752
1842
|
|
1843
|
+
#寻找最左侧的坐标:在x最小的同时,y要最大
|
1844
|
+
points_df = pd.DataFrame(points, columns=['x', 'y'])
|
1845
|
+
points_df.sort_values(by=['x','y'],ascending=[True,False],inplace=True)
|
1846
|
+
x1,y1=points_df.head(1).values[0]
|
1847
|
+
|
1848
|
+
#寻找最高点的坐标:在y最大的同时,x要最小
|
1849
|
+
points_df.sort_values(by=['y','x'],ascending=[False,True],inplace=True)
|
1850
|
+
x2,y2=points_df.head(1).values[0]
|
1851
|
+
|
1852
|
+
if DEBUG:
|
1853
|
+
plt.plot([x1,x2],[y1,y2],ls=':',lw=2,alpha=0.5)
|
1854
|
+
|
1855
|
+
#建立最左侧和最高点之间的拟合直线方程y=a+bx
|
1856
|
+
a=(x1*y2-x2*y1)/(x1-x2); b=(y1-y2)/(x1-x2)
|
1857
|
+
def y_bar(x_bar):
|
1858
|
+
return a+b*x_bar
|
1859
|
+
|
1753
1860
|
# 计算散点集的外轮廓
|
1754
|
-
hull = ConvexHull(points)
|
1861
|
+
hull = ConvexHull(points)
|
1862
|
+
|
1755
1863
|
# 绘制外轮廓线
|
1864
|
+
firsttime_efficient=True; firsttime_inefficient=True
|
1756
1865
|
for simplex in hull.simplices:
|
1866
|
+
#p1中是一条线段起点和终点的横坐标
|
1867
|
+
p1=[points[simplex[0]][0], points[simplex[1]][0]]
|
1868
|
+
px1=p1[0];px2=p1[1]
|
1869
|
+
#p2中是一条线段起点和终点的纵坐标
|
1870
|
+
p2=[points[simplex[0]][1], points[simplex[1]][1]]
|
1871
|
+
py1=p2[0]; py2=p2[1]
|
1872
|
+
|
1873
|
+
"""
|
1757
1874
|
plt.plot([points[simplex[0]][0], points[simplex[1]][0]],
|
1758
1875
|
[points[simplex[0]][1], points[simplex[1]][1]], 'k-.')
|
1759
|
-
|
1876
|
+
"""
|
1877
|
+
#线段起点:px1,py1;线段终点:px2,py2。但也可能互换起点和终点
|
1878
|
+
if ((py1>=y_bar(px1) or py1==y1) and (py2>=y_bar(px2) or py2==y2)) or \
|
1879
|
+
((py1>=y_bar(px2) or py1==y2) and (py2>=y_bar(px1) or py2==y1)) :
|
1880
|
+
#有效边界
|
1881
|
+
if frontier.lower() in ['both','efficient']:
|
1882
|
+
if firsttime_efficient:
|
1883
|
+
plt.plot(p1,p2, 'r--',label=text_lang("有效边界","Efficient Frontier"),lw=3,alpha=0.5)
|
1884
|
+
firsttime_efficient=False
|
1885
|
+
else:
|
1886
|
+
plt.plot(p1,p2, 'r--',lw=3,alpha=0.5)
|
1887
|
+
else:
|
1888
|
+
pass
|
1889
|
+
else:
|
1890
|
+
#其余边沿
|
1891
|
+
if frontier.lower() in ['both','inefficient']:
|
1892
|
+
if firsttime_inefficient:
|
1893
|
+
plt.plot(p1,p2, 'k-.',label=text_lang("无效边界","Inefficient Frontier"),alpha=0.5)
|
1894
|
+
firsttime_inefficient=False
|
1895
|
+
else:
|
1896
|
+
plt.plot(p1,p2, 'k-.',alpha=0.5)
|
1897
|
+
else:
|
1898
|
+
pass
|
1899
|
+
else:
|
1900
|
+
#无convex hull
|
1901
|
+
print('')
|
1760
1902
|
|
1761
1903
|
lang = check_language()
|
1762
1904
|
if lang == 'Chinese':
|
@@ -1787,11 +1929,11 @@ def RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
|
|
1787
1929
|
#解析最大比率点和最低风险点信息,并绘点
|
1788
1930
|
[hiret_x,hiret_y,name_hiret]=hiret_point
|
1789
1931
|
#plt.scatter(hiret_x, hiret_y, color='red',marker='*',s=150,label=name_hiret)
|
1790
|
-
plt.scatter(hiret_x, hiret_y, color='
|
1932
|
+
plt.scatter(hiret_x, hiret_y, color='red',marker='*',s=300,label=name_hiret,alpha=0.5)
|
1791
1933
|
|
1792
1934
|
[lorisk_x,lorisk_y,name_lorisk]=lorisk_point
|
1793
1935
|
#plt.scatter(lorisk_x, lorisk_y, color='m',marker='8',s=100,label=name_lorisk)
|
1794
|
-
plt.scatter(lorisk_x, lorisk_y, color='
|
1936
|
+
plt.scatter(lorisk_x, lorisk_y, color='blue',marker='8',s=150,label=name_lorisk,alpha=0.5)
|
1795
1937
|
|
1796
1938
|
plt.legend(loc='best')
|
1797
1939
|
|
@@ -1873,7 +2015,7 @@ def cvt_portfolio_name(pname,portfolio_returns):
|
|
1873
2015
|
|
1874
2016
|
#==============================================================================
|
1875
2017
|
|
1876
|
-
def portfolio_optimize_sharpe(es_info,graph=True,convex_hull=False,facecolor='papayawhip'):
|
2018
|
+
def portfolio_optimize_sharpe(es_info,graph=True,convex_hull=False,frontier='efficient',facecolor='papayawhip'):
|
1877
2019
|
"""
|
1878
2020
|
功能:计算投资组合的最高夏普比率组合,并绘图
|
1879
2021
|
MSR: Maximium Sharpe Rate, 最高夏普指数方案
|
@@ -1927,7 +2069,7 @@ def portfolio_optimize_sharpe(es_info,graph=True,convex_hull=False,facecolor='pa
|
|
1927
2069
|
hiret_weights,lorisk_weights,portfolio_returns = \
|
1928
2070
|
portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk, \
|
1929
2071
|
colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=graph, \
|
1930
|
-
convex_hull=convex_hull,facecolor=facecolor)
|
2072
|
+
convex_hull=convex_hull,frontier=frontier,facecolor=facecolor)
|
1931
2073
|
|
1932
2074
|
print(text_lang("【注释】","[Notes]"))
|
1933
2075
|
print("★MSR :Maximized Sharpe Ratio"+text_lang(",最大夏普比率点",''))
|
@@ -1950,7 +2092,7 @@ if __name__=='__main__':
|
|
1950
2092
|
|
1951
2093
|
#==============================================================================
|
1952
2094
|
|
1953
|
-
def portfolio_optimize_sortino(es_info,graph=True,convex_hull=False,facecolor="papayawhip"):
|
2095
|
+
def portfolio_optimize_sortino(es_info,graph=True,convex_hull=False,frontier='efficient',facecolor="papayawhip"):
|
1954
2096
|
"""
|
1955
2097
|
功能:计算投资组合的最高索替诺比率组合,并绘图
|
1956
2098
|
MSO: Maximium Sortino ratio, 最高索替诺比率方案
|
@@ -1968,7 +2110,7 @@ def portfolio_optimize_sortino(es_info,graph=True,convex_hull=False,facecolor="p
|
|
1968
2110
|
title_ext=text_lang("索替诺比率","Sortino Ratio") #用于标题区别
|
1969
2111
|
colorbartxt=text_lang("索替诺比率","Sortino Ratio") #用于彩色棒标签
|
1970
2112
|
ylabeltxt=text_lang("年化风险溢价","Annualized Risk Premium") #用于纵轴名称
|
1971
|
-
x_axis_name=text_lang("年化风险溢价之下偏标准差","Annualized
|
2113
|
+
x_axis_name=text_lang("年化风险溢价之下偏标准差","Annualized Risk Premium LPSD") #用于横轴名称
|
1972
2114
|
|
1973
2115
|
#定制部分结束...............................................................
|
1974
2116
|
|
@@ -1976,7 +2118,7 @@ def portfolio_optimize_sortino(es_info,graph=True,convex_hull=False,facecolor="p
|
|
1976
2118
|
hiret_weights,lorisk_weights,portfolio_returns = \
|
1977
2119
|
portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk, \
|
1978
2120
|
colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=graph, \
|
1979
|
-
convex_hull=convex_hull,facecolor=facecolor)
|
2121
|
+
convex_hull=convex_hull,frontier=frontier,facecolor=facecolor)
|
1980
2122
|
|
1981
2123
|
print(text_lang("【注释】","[Notes]"))
|
1982
2124
|
print("★MSO:Maximum SOrtino ratio"+text_lang(",最大索替诺比率点",''))
|
@@ -2001,7 +2143,7 @@ if __name__=='__main__':
|
|
2001
2143
|
if __name__=='__main__':
|
2002
2144
|
graph=True; convex_hull=False
|
2003
2145
|
|
2004
|
-
def portfolio_optimize_alpha(es_info,graph=True,convex_hull=False,facecolor='papayawhip'):
|
2146
|
+
def portfolio_optimize_alpha(es_info,graph=True,convex_hull=False,frontier='efficient',facecolor='papayawhip'):
|
2005
2147
|
"""
|
2006
2148
|
功能:计算投资组合的最高詹森阿尔法组合,并绘图
|
2007
2149
|
MAR: Maximium Alpha Ratio, 最高阿尔法指数方案
|
@@ -2026,7 +2168,7 @@ def portfolio_optimize_alpha(es_info,graph=True,convex_hull=False,facecolor='pap
|
|
2026
2168
|
hiret_weights,lorisk_weights,portfolio_returns = \
|
2027
2169
|
portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk, \
|
2028
2170
|
colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=graph, \
|
2029
|
-
convex_hull=convex_hull,facecolor=facecolor)
|
2171
|
+
convex_hull=convex_hull,frontier=frontier,facecolor=facecolor)
|
2030
2172
|
|
2031
2173
|
print(text_lang("【注释】","[Notes]"))
|
2032
2174
|
print("★MAR :Maximum Alpha Ratio"+text_lang(",最大阿尔法点",''))
|
@@ -2048,7 +2190,7 @@ if __name__=='__main__':
|
|
2048
2190
|
|
2049
2191
|
#==============================================================================
|
2050
2192
|
|
2051
|
-
def portfolio_optimize_treynor(es_info,graph=True,convex_hull=False,facecolor='papayawhip'):
|
2193
|
+
def portfolio_optimize_treynor(es_info,graph=True,convex_hull=False,frontier='efficient',facecolor='papayawhip'):
|
2052
2194
|
"""
|
2053
2195
|
功能:计算投资组合的最高特雷诺比率组合,并绘图
|
2054
2196
|
MTR: Maximium Treynor Ratio, 最高特雷诺指数方案
|
@@ -2073,7 +2215,7 @@ def portfolio_optimize_treynor(es_info,graph=True,convex_hull=False,facecolor='p
|
|
2073
2215
|
hiret_weights,lorisk_weights,portfolio_returns = \
|
2074
2216
|
portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk, \
|
2075
2217
|
colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=graph, \
|
2076
|
-
convex_hull=convex_hull,facecolor=facecolor)
|
2218
|
+
convex_hull=convex_hull,frontier=frontier,facecolor=facecolor)
|
2077
2219
|
|
2078
2220
|
print(text_lang("【注释】","[Notes]"))
|
2079
2221
|
print("★MTR :Maximum Treynor Ratio"+text_lang(",最大特雷诺比率点",''))
|
@@ -2088,7 +2230,7 @@ if __name__=='__main__':
|
|
2088
2230
|
|
2089
2231
|
def portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk, \
|
2090
2232
|
colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=True, \
|
2091
|
-
convex_hull=False,facecolor='papayawhip'):
|
2233
|
+
convex_hull=False,frontier='efficient',facecolor='papayawhip'):
|
2092
2234
|
"""
|
2093
2235
|
功能:提供rar比率优化的共同处理部分
|
2094
2236
|
基于RandomPortfolios中的随机投资组合,计算相应的指数,寻找最大指数点和风险最小点,并绘图标注两个点
|
@@ -2163,7 +2305,8 @@ def portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk,
|
|
2163
2305
|
if graph:
|
2164
2306
|
RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
|
2165
2307
|
ylabeltxt,x_axis_name,pname,simulation,hstart,hend, \
|
2166
|
-
hiret_point,lorisk_point,convex_hull=convex_hull,
|
2308
|
+
hiret_point,lorisk_point,convex_hull=convex_hull, \
|
2309
|
+
frontier=frontier,facecolor=facecolor)
|
2167
2310
|
|
2168
2311
|
#返回数据,供进一步分析
|
2169
2312
|
portfolio_returns=StockReturns.copy()
|
@@ -2200,7 +2343,7 @@ if __name__=='__main__':
|
|
2200
2343
|
|
2201
2344
|
def portfolio_optimize(pf_info,ratio='sharpe',simulation=50000,RF=0, \
|
2202
2345
|
graph=True,hirar_return=False,lorisk=True, \
|
2203
|
-
convex_hull=
|
2346
|
+
convex_hull=True,frontier='efficient',facecolor='papayawhip'):
|
2204
2347
|
"""
|
2205
2348
|
功能:集成式投资组合优化策略
|
2206
2349
|
注意:实验发现RF较小时对于结果的影响极其微小难以观察,默认设为不使用无风险利率调整收益
|
@@ -2231,7 +2374,8 @@ def portfolio_optimize(pf_info,ratio='sharpe',simulation=50000,RF=0, \
|
|
2231
2374
|
eval(func_optimize)(es_info=es_info,RF=RF,graph=graph)
|
2232
2375
|
"""
|
2233
2376
|
name_hiret,hiret_weights,name_lorisk,lorisk_weights,portfolio_returns= \
|
2234
|
-
eval(func_optimize)(es_info=es_info,graph=graph,convex_hull=convex_hull,
|
2377
|
+
eval(func_optimize)(es_info=es_info,graph=graph,convex_hull=convex_hull, \
|
2378
|
+
frontier=frontier,facecolor=facecolor)
|
2235
2379
|
|
2236
2380
|
|
2237
2381
|
lang = check_language()
|
@@ -2239,12 +2383,12 @@ def portfolio_optimize(pf_info,ratio='sharpe',simulation=50000,RF=0, \
|
|
2239
2383
|
zhuhe_txt='组合'
|
2240
2384
|
mingcheng_txt='投资组合名称/策略'
|
2241
2385
|
titletxt="投资组合策略:业绩比较"
|
2242
|
-
ylabeltxt="
|
2386
|
+
ylabeltxt="持有期收益率"
|
2243
2387
|
else:
|
2244
2388
|
zhuhe_txt=''
|
2245
2389
|
mingcheng_txt='Strategy'
|
2246
2390
|
titletxt="Investment Portfolio Strategy: Performance Comparison"
|
2247
|
-
ylabeltxt="Holding Return"
|
2391
|
+
ylabeltxt="Holding Period Return"
|
2248
2392
|
|
2249
2393
|
#打印投资组合构造和业绩表现
|
2250
2394
|
hi_name=modify_portfolio_name(name_hiret+zhuhe_txt)
|
@@ -69,7 +69,7 @@ siat/luchy_draw.py,sha256=8Ue-NKnvSVqINPY1eXat0NJat5MR-gex_K62aOYFdmA,20486
|
|
69
69
|
siat/market_china.py,sha256=EOO-RvdnzJThTrgNHWW3TlWhx4k4rfdjbooOnQsYdQU,50299
|
70
70
|
siat/markowitz.py,sha256=DsfS6vG9TAfdJP4GgN-CCArujPi84XjD23CWbxaA2o4,97627
|
71
71
|
siat/markowitz2-20240620.py,sha256=irZAPnjaatFsKQmFRMENP-cO6bEUl2narYtkU5NKTWI,108019
|
72
|
-
siat/markowitz2.py,sha256=
|
72
|
+
siat/markowitz2.py,sha256=LK2pDEtE5PUmBtCHmCcRs8FlPqZKmhFXiuLIL4JeQa8,121991
|
73
73
|
siat/markowitz_ccb_test.py,sha256=xBkkoaNHdq9KSUrNuHGgKTdNYUvgi84kNYcf719eoyE,1593
|
74
74
|
siat/markowitz_ef_test.py,sha256=wjNlICkgRIqnonPeSIHo4Mu2GRtb9dr21wDt2kMNEcI,4032
|
75
75
|
siat/markowitz_old.py,sha256=Lf7O_4QWT8RsdkHiUyc_7kKY3eZjKDtFR89Fz3pwYnY,33046
|
@@ -139,7 +139,7 @@ siat/valuation_china.py,sha256=EkZQaVkoBjM0c4MCNbaX-bMnlG0e3FXeaWczZDnkptU,67784
|
|
139
139
|
siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
|
140
140
|
siat/var_model_validation.py,sha256=R0caWnuZarrRg9939hxh3vJIIpIyPfvelYmzFNZtPbo,14910
|
141
141
|
siat/yf_name.py,sha256=H1EM8YYXA8nQHIqsJlso0I3HKPiJLT3QujO4gRVQXWs,13945
|
142
|
-
siat-3.
|
143
|
-
siat-3.
|
144
|
-
siat-3.
|
145
|
-
siat-3.
|
142
|
+
siat-3.4.1.dist-info/METADATA,sha256=0s5TpzHfnUzzwRFnFeoBNXS-3miIuEZglezF2dKX0rs,7309
|
143
|
+
siat-3.4.1.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
|
144
|
+
siat-3.4.1.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
|
145
|
+
siat-3.4.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|