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,4)
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,4)
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,4)
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,4)
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),4)
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,4)
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,4)
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,4)
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),4)
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("年化收益率%","Annual Return%"), \
959
+ "年化收益率%":text_lang("年化收益率%","pa Return%"), \
957
960
  "收益率变化":text_lang("收益率变化","Return%+/-"), \
958
961
  "风险排名":text_lang("风险排名","Risk#"), \
959
- "年化标准差%":text_lang("年化标准差%","Annual Std%"), \
962
+ "年化标准差%":text_lang("年化标准差%","pa Std%"), \
960
963
  "标准差变化":text_lang("标准差变化","Std%+/-"), \
961
964
  "收益率/标准差":text_lang("收益率/标准差","Return/Std")}, \
962
965
  inplace=True)
963
966
 
964
- df_display_CSS(prr2,titletxt=titletxt,footnote='',facecolor='papayawhip',decimals=2, \
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='right',other_col_align='right', \
967
- titile_font_size='16px',heading_font_size='15px', \
968
- data_font_size='15px')
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
- simulation=1000
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
- points_sorted=points
1217
- points_sorted.sort(key=lambda x: x[0])
1218
- points_df=pd.DataFrame(points_sorted,columns=['x','y'])
1219
-
1220
- window=100
1221
- nwindow=int(len(points_df)/window)
1222
- upper_points=[]
1223
- for n in range(nwindow):
1224
- tmp_df=points_df[n*window:n*window+window]
1225
- max_y=max(tmp_df['y'])
1226
- max_x=tmp_df[tmp_df['y']==max_y]['x'].values[0]
1227
-
1228
- upper_points=upper_points+[[max_x,max_y]]
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
- print('')
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='blue',marker='*',s=200,label=name_hiret)
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='red',marker='8',s=150,label=name_lorisk)
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 Std of Risk Premium") #用于横轴名称
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,facecolor=facecolor)
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=False,facecolor='papayawhip'):
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,facecolor=facecolor)
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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: siat
3
- Version: 3.3.12
3
+ Version: 3.4.1
4
4
  Summary: Securities Investment Analysis Tools (siat)
5
5
  Home-page: https://pypi.org/project/siat/
6
6
  Author: Prof. WANG Dehong, International Business School, Beijing Foreign Studies University
@@ -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=y7ShcnKIaxw6LVZlwJj56PlOskiI0DRqU8PXU6f8uyM,114781
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.3.12.dist-info/METADATA,sha256=EtLtE-RtRKITuvSR_Lx-VPuRx_GVICFYFtDe0pjtZHM,7310
143
- siat-3.3.12.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
144
- siat-3.3.12.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
145
- siat-3.3.12.dist-info/RECORD,,
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