siat 3.2.57__py3-none-any.whl → 3.2.59__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/common.py CHANGED
@@ -3985,8 +3985,6 @@ def show_df(data,search_mode=False):
3985
3985
  """
3986
3986
 
3987
3987
  import pandas as pd
3988
- # 设置列对齐方式为靠左
3989
- pd.set_option('display.align', 'left')
3990
3988
 
3991
3989
  if not isinstance(data,pd.DataFrame):
3992
3990
  print("#Warning: the first parameter must be a dataframe")
siat/markowitz2.py CHANGED
@@ -139,7 +139,7 @@ if __name__=='__main__':
139
139
 
140
140
  def cumulative_returns_plot(retgroup,name_list="",titletxt="投资组合策略:业绩比较", \
141
141
  ylabeltxt="持有收益率",xlabeltxt="", \
142
- label_list=[]):
142
+ label_list=[],facecolor='papayawhip'):
143
143
  """
144
144
  功能:基于传入的name_list绘制多条持有收益率曲线,并从label_list中取出曲线标记
145
145
  注意:最多绘制四条曲线,否则在黑白印刷时无法区分曲线,以此标记为实线、点虚线、划虚线和点划虚线四种
@@ -163,10 +163,10 @@ def cumulative_returns_plot(retgroup,name_list="",titletxt="投资组合策略
163
163
  import datetime as dt; stoday=dt.date.today()
164
164
  if lang == 'Chinese':
165
165
  footnote1="观察期间: "+hstart+'至'+hend
166
- footnote2="\n来源:Sina/EM/stooq,"+str(stoday)
166
+ footnote2="\n数据来源:Sina/EM/Stooq/Yahoo,"+str(stoday)
167
167
  else:
168
168
  footnote1="Period of observation: "+hstart+' to '+hend
169
- footnote2="\nSource: sina/eastmoney/stooq, "+str(stoday)
169
+ footnote2="\nData source: Sina/EM/Stooq/Yahoo, "+str(stoday)
170
170
 
171
171
  xlabeltxt=footnote1+footnote2
172
172
 
@@ -193,7 +193,7 @@ def cumulative_returns_plot(retgroup,name_list="",titletxt="投资组合策略
193
193
  plt.legend(loc='best')
194
194
  plt.title(titletxt); plt.ylabel(ylabeltxt); plt.xlabel(xlabeltxt)
195
195
 
196
- plt.gca().set_facecolor('whitesmoke')
196
+ plt.gca().set_facecolor(facecolor)
197
197
  plt.show()
198
198
 
199
199
  return
@@ -290,7 +290,7 @@ def portfolio_cumret(portfolio,thedate,pastyears=1, \
290
290
  def portfolio_build(portfolio,thedate='default',pastyears=1, \
291
291
  indicator='Adj Close', \
292
292
  adjust='qfq',source='auto',ticker_type='auto', \
293
- printout=True,graph=False):
293
+ printout=True,graph=False,facecolor='papayawhip'):
294
294
  """
295
295
  功能:收集投资组合成份股数据,绘制收益率趋势图,并与等权和期间内交易额加权策略组合比较
296
296
  注意:此处无需RF,待到优化策略时再指定
@@ -321,7 +321,7 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
321
321
  print(" #Warning(portfolio_build): invalid date",thedate)
322
322
  return None
323
323
 
324
- print("\n Searching for portfolio info, which may take time ...")
324
+ print(" Searching for portfolio info, which may take time ...")
325
325
  # 解构投资组合
326
326
  scope,_,tickerlist,sharelist0,ticker_type=decompose_portfolio(portfolio)
327
327
  pname=portfolio_name(portfolio)
@@ -451,7 +451,7 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
451
451
 
452
452
  title_txt=text_lang("投资组合: 日收益率的变化趋势","Investment Portfolio: Daily Return")
453
453
  ylabel_txt=text_lang("日收益率","Daily Return")
454
- source_txt=text_lang("来源: 综合新浪/东方财富/stooq/雅虎等, ","Source: sina/eastmoney/stooq, ")
454
+ source_txt=text_lang("来源: 综合新浪/东方财富/Stooq/雅虎等, ","Data source: Sina/EM/Stooq/Yahoo, ")
455
455
 
456
456
  plt.title(title_txt)
457
457
  plt.ylabel(ylabel_txt)
@@ -459,7 +459,7 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
459
459
  stoday = datetime.date.today()
460
460
  plt.xlabel(source_txt+str(stoday))
461
461
 
462
- plt.gca().set_facecolor('whitesmoke')
462
+ plt.gca().set_facecolor(facecolor)
463
463
 
464
464
  plt.legend(); plt.show(); plt.close()
465
465
  #..........................................................................
@@ -469,14 +469,14 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
469
469
  label_list=[pname]
470
470
 
471
471
 
472
- titletxt=text_lang("投资组合: 持有收益率的变化趋势","Investment Portfolio: Holding Return")
473
- ylabeltxt=text_lang("持有收益率","Holding Return")
474
- xlabeltxt1=text_lang("来源: 综合新浪/东方财富/stooq/雅虎等, ","Source: sina/eastmoney/stooq, ")
472
+ titletxt=text_lang("投资组合: 持有收益率的变化趋势","Investment Portfolio: Holding Period Return%")
473
+ ylabeltxt=text_lang("持有收益率","Holding Period Return%")
474
+ xlabeltxt1=text_lang("数据来源: 综合新浪/东方财富/Stooq/雅虎等, ","Data source: Sina/EM/Stooq/Yahoo, ")
475
475
  xlabeltxt=xlabeltxt1+str(stoday)
476
476
 
477
477
  #绘制持有收益率曲线
478
478
  if graph:
479
- cumulative_returns_plot(StockReturns,name_list,titletxt,ylabeltxt,xlabeltxt,label_list)
479
+ cumulative_returns_plot(StockReturns,name_list,titletxt,ylabeltxt,xlabeltxt,label_list,facecolor=facecolor)
480
480
  #..........................................................................
481
481
 
482
482
  # 构造等权重组合Portfolio_EW的持有收益率
@@ -498,10 +498,10 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
498
498
  StockReturns['Portfolio_LW'] = stock_return.mul(portfolio_weights_lw, axis=1).sum(axis=1)
499
499
 
500
500
  #绘制累计收益率对比曲线
501
- title_txt=text_lang("投资组合策略:业绩对比","Portfolio Strategies: Performance Comparison")
502
- Portfolio_EW_txt=text_lang("等权重策略","Equal-weight")
501
+ title_txt=text_lang("投资组合策略:业绩对比","Portfolio Strategies: Performance")
502
+ Portfolio_EW_txt=text_lang("等权重策略","Equal-weighted")
503
503
  if ('bond' not in ticker_type) and ('fund' not in ticker_type):
504
- Portfolio_LW_txt=text_lang("交易额加权策略","Amount-weight")
504
+ Portfolio_LW_txt=text_lang("交易额加权策略","Amount-weighted")
505
505
 
506
506
  name_list=['Portfolio', 'Portfolio_EW', 'Portfolio_LW']
507
507
  label_list=[pname, Portfolio_EW_txt, Portfolio_LW_txt]
@@ -737,7 +737,7 @@ def portfolio_expectation_universal(pname,member_returns,portfolio_weights,membe
737
737
  print(" ***投资组合持仓策略***")
738
738
  print_tickerlist_sharelist(tickerlist,portfolio_weights,leading_blanks=4,ticker_type=ticker_type)
739
739
 
740
- print(" *来源:Sina/EM/stooq,"+str(stoday)+"统计")
740
+ print(" *数据来源:Sina/EM/Stooq/Yahoo,"+str(stoday)+"统计")
741
741
  else:
742
742
  print("\n ======= Investment Portfolio: Return and Risk =======")
743
743
  print(" Investment portfolio:",pname)
@@ -749,7 +749,7 @@ def portfolio_expectation_universal(pname,member_returns,portfolio_weights,membe
749
749
  print(" ***Portfolio Constructing Strategy***")
750
750
  print_tickerlist_sharelist(tickerlist,portfolio_weights,4)
751
751
 
752
- print(" *Source: sina/eastmoney/stooq,"+str(stoday))
752
+ print(" *Data source: Sina/EM/Stooq/Yahoo, "+str(stoday))
753
753
 
754
754
  return
755
755
 
@@ -793,23 +793,28 @@ if __name__=='__main__':
793
793
 
794
794
 
795
795
  #==============================================================================
796
+
797
+
796
798
  def portfolio_ranks(portfolio_returns,pname,facecolor='whitesmoke'):
797
799
  """
798
800
  功能:区分中英文
799
801
  """
802
+ """
800
803
  lang = check_language()
801
804
  if lang == 'Chinese':
802
- df=portfolio_ranks_cn(portfolio_returns=portfolio_returns,pname=pname,facecolor='whitesmoke')
805
+ df=portfolio_ranks_cn(portfolio_returns=portfolio_returns,pname=pname,facecolor=facecolor)
803
806
  else:
804
807
  df=portfolio_ranks_en(portfolio_returns=portfolio_returns,pname=pname)
805
-
808
+ """
809
+ df=portfolio_ranks_cn(portfolio_returns=portfolio_returns,pname=pname,facecolor=facecolor)
810
+
806
811
  return df
807
812
 
808
813
  #==============================================================================
809
814
 
810
815
  def portfolio_ranks_cn(portfolio_returns,pname,facecolor='whitesmoke'):
811
816
  """
812
- 功能:打印现有投资组合的收益率、标准差排名,收益率降序,标准差升序,中文
817
+ 功能:打印现有投资组合的收益率、标准差排名,收益率降序,标准差升序,中文/英文
813
818
  """
814
819
  #临时保存,避免影响原值
815
820
  pr=portfolio_returns.copy()
@@ -847,7 +852,7 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='whitesmoke'):
847
852
 
848
853
  #收益率变化
849
854
  if return_chg==0:
850
- return_chg_str="基准"
855
+ return_chg_str=text_lang("基准","Benchmark")
851
856
  elif return_chg > 0:
852
857
  if pct_style:
853
858
  return_chg_str='+'+str(return_chg)+'%'
@@ -873,7 +878,7 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='whitesmoke'):
873
878
 
874
879
  #标准差变化
875
880
  if std_chg==0:
876
- std_chg_str="基准"
881
+ std_chg_str=text_lang("基准","Benchmark")
877
882
  elif std_chg > 0:
878
883
  if pct_style:
879
884
  std_chg_str='+'+str(std_chg)+'%'
@@ -935,7 +940,7 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='whitesmoke'):
935
940
  prr2[c]=prr2[c].apply(lambda x: str(round(x,4)) if isinstance(x,float) else str(x))
936
941
  except: pass
937
942
 
938
- titletxt='投资组合策略排名:平衡收益与风险'
943
+ titletxt=text_lang('投资组合策略排名:平衡收益与风险','Investment Portfolio Strategies: Performance, Balancing Return and Risk')
939
944
  """
940
945
  dispt=prr2.style.set_caption(titletxt).set_table_styles(
941
946
  [{'selector':'caption',
@@ -946,6 +951,16 @@ def portfolio_ranks_cn(portfolio_returns,pname,facecolor='whitesmoke'):
946
951
  display(dispf)
947
952
  """
948
953
 
954
+ prr2.rename(columns={"投资组合名称/策略":text_lang("投资组合名称/策略","Strategy"), \
955
+ "收益排名":text_lang("收益排名","Return#"), \
956
+ "年化收益率%":text_lang("年化收益率%","Annualized Return%"), \
957
+ "收益率变化":text_lang("收益率变化","Return%+/-"), \
958
+ "风险排名":text_lang("风险排名","Risk#"), \
959
+ "年化标准差%":text_lang("年化标准差%","Annualized Std%"), \
960
+ "标准差变化":text_lang("标准差变化","Std%+/-"), \
961
+ "收益率/标准差":text_lang("收益率/标准差","Return/Std")}, \
962
+ inplace=True)
963
+
949
964
  df_display_CSS(prr2,titletxt=titletxt,footnote='',facecolor='papayawhip',decimals=4, \
950
965
  first_col_align='left',second_col_align='center', \
951
966
  last_col_align='right',other_col_align='right', \
@@ -988,6 +1003,7 @@ if __name__=='__main__':
988
1003
  def portfolio_ranks_en(portfolio_returns,pname):
989
1004
  """
990
1005
  功能:打印现有投资组合的收益率、标准差排名,收益率降序,标准差升序,英文
1006
+ 废弃!!!
991
1007
  """
992
1008
  #临时保存,避免影响原值
993
1009
  pr=portfolio_returns.copy()
@@ -1122,7 +1138,7 @@ def portfolio_eset(pf_info,simulation=1000,convex_hull=False):
1122
1138
  np.random.seed(RANDOM_SEED)
1123
1139
 
1124
1140
  # 循环模拟n次随机的投资组合
1125
- print("\n Calculating portfolio efficient set, please wait ...")
1141
+ print(" Calculating portfolio efficient set, please wait ...")
1126
1142
  for i in range(simulation):
1127
1143
  # 生成numstocks个随机数,并归一化,得到一组随机的权重数据
1128
1144
  random9 = np.random.random(numstocks)
@@ -1153,6 +1169,7 @@ def portfolio_eset(pf_info,simulation=1000,convex_hull=False):
1153
1169
  + ['Returns', 'Volatility']
1154
1170
 
1155
1171
  # 绘制散点图
1172
+ print('')
1156
1173
  """
1157
1174
  RandomPortfolios.plot('Volatility','Returns',kind='scatter',color='y',edgecolors='k')
1158
1175
  """
@@ -1185,7 +1202,7 @@ def portfolio_eset(pf_info,simulation=1000,convex_hull=False):
1185
1202
  # 绘制外轮廓线
1186
1203
  for simplex in hull.simplices:
1187
1204
  plt.plot([points[simplex[0]][0], points[simplex[1]][0]],
1188
- [points[simplex[0]][1], points[simplex[1]][1]], 'k-')
1205
+ [points[simplex[0]][1], points[simplex[1]][1]], 'k-.')
1189
1206
 
1190
1207
  """
1191
1208
  #滚动法寻找上边沿
@@ -1216,18 +1233,18 @@ def portfolio_eset(pf_info,simulation=1000,convex_hull=False):
1216
1233
  footnote1="年化收益率标准差-->"
1217
1234
  footnote2="\n\n基于给定的成份证券构造"+str(simulation)+"个投资组合"
1218
1235
  footnote3="\n观察期间:"+hstart+"至"+hend
1219
- footnote4="\n来源: Sina/EM/stooq, "+str(stoday)
1236
+ footnote4="\n数据来源: Sina/EM/Stooq/Yahoo, "+str(stoday)
1220
1237
  else:
1221
1238
  if pname == '': pname='Investment Portfolio'
1222
1239
 
1223
1240
  plt.colorbar(label='Return/Std')
1224
- plt.title(pname+": Efficient Set",fontsize=title_txt_size)
1241
+ plt.title(pname+": Feasible/Efficient Set",fontsize=title_txt_size)
1225
1242
  plt.ylabel("Annualized Return",fontsize=ylabel_txt_size)
1226
1243
 
1227
1244
  footnote1="Annualized Std -->\n\n"
1228
- footnote2="Based on given component securities, constructed "+str(simulation)+" portfolios\n"
1245
+ footnote2="Based on given securities, constructed "+str(simulation)+" portfolios\n"
1229
1246
  footnote3="Period of observation: "+hstart+" to "+hend
1230
- footnote4="\nSource: sina/eastmoney/stooq, "+str(stoday)
1247
+ footnote4="\nData source: Sina/EM/Stooq/Yahoo, "+str(stoday)
1231
1248
 
1232
1249
  plt.xlabel(footnote1+footnote2+footnote3+footnote4,fontsize=xlabel_txt_size)
1233
1250
 
@@ -1674,7 +1691,8 @@ if __name__=='__main__':
1674
1691
  #==============================================================================
1675
1692
  def RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
1676
1693
  ylabeltxt,x_axis_name,pname,simulation,hstart,hend, \
1677
- hiret_point,lorisk_point,convex_hull=True):
1694
+ hiret_point,lorisk_point,convex_hull=True, \
1695
+ facecolor="whitesmoke"):
1678
1696
  """
1679
1697
  功能:将生成的马科维茨可行集RandomPortfolios绘制成彩色散点图
1680
1698
  """
@@ -1701,7 +1719,7 @@ def RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
1701
1719
  plt.xlabel(footnote1+footnote2+footnote3+footnote4)
1702
1720
  plt.show()
1703
1721
  """
1704
-
1722
+ print('')
1705
1723
  #RandomPortfolios.plot(col_x,col_y,kind='scatter',color='y',edgecolors='k')
1706
1724
 
1707
1725
  pf_ratio = np.array(RandomPortfolios[col_y] / RandomPortfolios[col_x])
@@ -1737,25 +1755,25 @@ def RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
1737
1755
  if lang == 'Chinese':
1738
1756
  if pname == '': pname='投资组合'
1739
1757
 
1740
- plt.title(pname+": 马科维茨有效(可行)集,基于"+title_ext,fontsize=title_txt_size)
1758
+ plt.title(pname+": 马科维茨可行/有效集,基于"+title_ext,fontsize=title_txt_size)
1741
1759
  plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
1742
1760
 
1743
1761
  import datetime as dt; stoday=dt.date.today()
1744
1762
  footnote1=x_axis_name+" -->\n\n"
1745
- footnote2="基于给定的成份证券构造"+str(simulation)+"个投资组合"
1763
+ footnote2="基于给定证券构造"+str(simulation)+"个投资组合"
1746
1764
  footnote3="\n观察期间:"+hstart+"至"+hend
1747
- footnote4="\n来源: Sina/EM/stooq/FRED, "+str(stoday)
1765
+ footnote4="\n数据来源: Sina/EM/Stooq/Yahoo, "+str(stoday)
1748
1766
  else:
1749
1767
  if pname == '': pname='Investment Portfolio'
1750
1768
 
1751
- plt.title(pname+": Efficient Set, Based on "+title_ext,fontsize=title_txt_size)
1769
+ plt.title(pname+": Portfolio Optimization, Based on "+title_ext,fontsize=title_txt_size)
1752
1770
  plt.ylabel(ylabeltxt,fontsize=ylabel_txt_size)
1753
1771
 
1754
1772
  import datetime as dt; stoday=dt.date.today()
1755
1773
  footnote1=x_axis_name+" -->\n\n"
1756
- footnote2="Based on given component securities, constructed "+str(simulation)+" portfolios"
1774
+ footnote2="Based on given securities, constructed "+str(simulation)+" portfolios"
1757
1775
  footnote3="\nPeriod of observation: "+hstart+" to "+hend
1758
- footnote4="\nSource: sina/eastmoney/stooq/FRED, "+str(stoday)
1776
+ footnote4="\nData source: Sina/EM/Stooq/Yahoo, "+str(stoday)
1759
1777
 
1760
1778
  plt.xlabel(footnote1+footnote2+footnote3+footnote4,fontsize=xlabel_txt_size)
1761
1779
 
@@ -1770,7 +1788,7 @@ def RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
1770
1788
 
1771
1789
  plt.legend(loc='best')
1772
1790
 
1773
- plt.gca().set_facecolor('whitesmoke')
1791
+ plt.gca().set_facecolor(facecolor)
1774
1792
  plt.show()
1775
1793
 
1776
1794
  return
@@ -1824,8 +1842,15 @@ def cvt_portfolio_name(pname,portfolio_returns):
1824
1842
  '最佳特雷诺比率组合(MTR)','特雷诺比率最小风险组合(GMBT)']
1825
1843
 
1826
1844
  else:
1827
- pclist=[pname,'Equal-weight','Amount-weight','MSR','GMVS','MSO','GML', \
1845
+ #"""
1846
+ pclist=[pname,'Equal-weighted','Amount-weighted','MSR','GMVS','MSO','GML', \
1828
1847
  'MAR','GMBA', 'MTR','GMBT']
1848
+ """
1849
+ pclist=[pname,'Equal-weighted','Amount-weighted','Max Sharpe Ratio(MSR)', \
1850
+ 'Min Risk in Sharpe Ratio(GMVS)','Max Sortino Ratio(MSO)', \
1851
+ 'Min Risk in Sortino Ratio(GML)','Max Alpha(MAR)','Min Risk in Alpha(GMBA)', \
1852
+ 'Max Treynor Ratio(MTR)','Min Risk in Treynor Ratio(GMBT)']
1853
+ """
1829
1854
 
1830
1855
  pecols=list(portfolio_returns)
1831
1856
  for p in pecols:
@@ -1841,7 +1866,7 @@ def cvt_portfolio_name(pname,portfolio_returns):
1841
1866
 
1842
1867
  #==============================================================================
1843
1868
 
1844
- def portfolio_optimize_sharpe(es_info,graph=True,convex_hull=False):
1869
+ def portfolio_optimize_sharpe(es_info,graph=True,convex_hull=False,facecolor='whitesmoke'):
1845
1870
  """
1846
1871
  功能:计算投资组合的最高夏普比率组合,并绘图
1847
1872
  MSR: Maximium Sharpe Rate, 最高夏普指数方案
@@ -1895,11 +1920,11 @@ def portfolio_optimize_sharpe(es_info,graph=True,convex_hull=False):
1895
1920
  hiret_weights,lorisk_weights,portfolio_returns = \
1896
1921
  portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk, \
1897
1922
  colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=graph, \
1898
- convex_hull=convex_hull)
1923
+ convex_hull=convex_hull,facecolor=facecolor)
1899
1924
 
1900
- print("【注释】")
1901
- print("★MSR : Maximized Sharpe Ratio,最大夏普比率点")
1902
- print("◍GMVS: Global Minimized Volatility by Sharpe,全局最小夏普比率波动点")
1925
+ print(text_lang("【注释】","[Notes]"))
1926
+ print("★MSR :Maximized Sharpe Ratio"+text_lang(",最大夏普比率点",''))
1927
+ print("◍GMVS:Global Minimized Volatility by Sharpe Ratio"+text_lang(",全局最小夏普比率波动点",''))
1903
1928
 
1904
1929
  return name_hiret,hiret_weights,name_lorisk,lorisk_weights,portfolio_returns
1905
1930
 
@@ -1918,7 +1943,7 @@ if __name__=='__main__':
1918
1943
 
1919
1944
  #==============================================================================
1920
1945
 
1921
- def portfolio_optimize_sortino(es_info,graph=True,convex_hull=False):
1946
+ def portfolio_optimize_sortino(es_info,graph=True,convex_hull=False,facecolor="whitesmoke"):
1922
1947
  """
1923
1948
  功能:计算投资组合的最高索替诺比率组合,并绘图
1924
1949
  MSO: Maximium Sortino ratio, 最高索替诺比率方案
@@ -1933,10 +1958,10 @@ def portfolio_optimize_sortino(es_info,graph=True,convex_hull=False):
1933
1958
  name_hiret='MSO' #Maximum SOrtino ratio,指数最高点
1934
1959
  name_lorisk='GML' #Global Minimum LPSD,风险最低点
1935
1960
 
1936
- title_ext="索替诺比率" #用于标题区别
1937
- colorbartxt='索替诺比率' #用于彩色棒标签
1938
- ylabeltxt="年化风险溢价" #用于纵轴名称
1939
- x_axis_name="年化风险溢价之下偏标准差" #用于横轴名称
1961
+ title_ext=text_lang("索替诺比率","Sortino Ratio") #用于标题区别
1962
+ colorbartxt=text_lang("索替诺比率","Sortino Ratio") #用于彩色棒标签
1963
+ ylabeltxt=text_lang("年化风险溢价","Annualized Risk Premium") #用于纵轴名称
1964
+ x_axis_name=text_lang("年化风险溢价之下偏标准差","Annualized Std of Risk Premium") #用于横轴名称
1940
1965
 
1941
1966
  #定制部分结束...............................................................
1942
1967
 
@@ -1944,11 +1969,11 @@ def portfolio_optimize_sortino(es_info,graph=True,convex_hull=False):
1944
1969
  hiret_weights,lorisk_weights,portfolio_returns = \
1945
1970
  portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk, \
1946
1971
  colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=graph, \
1947
- convex_hull=convex_hull)
1972
+ convex_hull=convex_hull,facecolor=facecolor)
1948
1973
 
1949
- print("【注释】")
1950
- print("★MSO Maximum SOrtino ratio,最大索替诺比率点")
1951
- print("◍GML: Global Minimum LPSD,全局最小LPSD点")
1974
+ print(text_lang("【注释】","[Notes]"))
1975
+ print("★MSO:Maximum SOrtino ratio"+text_lang(",最大索替诺比率点",''))
1976
+ print("◍GML:Global Minimum LPSD"+text_lang(",全局最小LPSD点",''))
1952
1977
 
1953
1978
  return name_hiret,hiret_weights,name_lorisk,lorisk_weights,portfolio_returns
1954
1979
 
@@ -1969,7 +1994,7 @@ if __name__=='__main__':
1969
1994
  if __name__=='__main__':
1970
1995
  graph=True; convex_hull=False
1971
1996
 
1972
- def portfolio_optimize_alpha(es_info,graph=True,convex_hull=False):
1997
+ def portfolio_optimize_alpha(es_info,graph=True,convex_hull=False,facecolor='whitesmoke'):
1973
1998
  """
1974
1999
  功能:计算投资组合的最高詹森阿尔法组合,并绘图
1975
2000
  MAR: Maximium Alpha Ratio, 最高阿尔法指数方案
@@ -1984,21 +2009,21 @@ def portfolio_optimize_alpha(es_info,graph=True,convex_hull=False):
1984
2009
  name_hiret='MAR' #Maximum Alpha Ratio,指数最高点
1985
2010
  name_lorisk='GMBA' #Global Minimum Beta by Alpha,风险最低点
1986
2011
 
1987
- title_ext="阿尔法指数" #用于标题区别
1988
- colorbartxt='阿尔法指数' #用于彩色棒标签
1989
- ylabeltxt="阿尔法指数" #用于纵轴名称
1990
- x_axis_name="贝塔系数" #用于横轴名称
2012
+ title_ext=text_lang("阿尔法指数","Jensen Alpha") #用于标题区别
2013
+ colorbartxt=text_lang("阿尔法指数","Jensen Alpha") #用于彩色棒标签
2014
+ ylabeltxt=text_lang("阿尔法指数","Jensen Alpha") #用于纵轴名称
2015
+ x_axis_name=text_lang("贝塔系数","Beta") #用于横轴名称
1991
2016
  #定制部分结束...............................................................
1992
2017
 
1993
2018
  #计算指数,寻找最大指数点和风险最低点,并绘图标注两个点
1994
2019
  hiret_weights,lorisk_weights,portfolio_returns = \
1995
2020
  portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk, \
1996
2021
  colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=graph, \
1997
- convex_hull=convex_hull)
2022
+ convex_hull=convex_hull,facecolor=facecolor)
1998
2023
 
1999
- print("【注释】")
2000
- print("★MAR : Maximum Alpha Ratio,最大阿尔法点")
2001
- print("◍GMBA: Global Minimum Beta by Alpha,全局最小阿尔法-贝塔点")
2024
+ print(text_lang("【注释】","[Notes]"))
2025
+ print("★MAR :Maximum Alpha Ratio"+text_lang(",最大阿尔法点",''))
2026
+ print("◍GMBA:Global Minimum Beta by Alpha"+text_lang(",全局最小阿尔法-贝塔点",''))
2002
2027
 
2003
2028
  return name_hiret,hiret_weights,name_lorisk,lorisk_weights,portfolio_returns
2004
2029
 
@@ -2016,7 +2041,7 @@ if __name__=='__main__':
2016
2041
 
2017
2042
  #==============================================================================
2018
2043
 
2019
- def portfolio_optimize_treynor(es_info,graph=True,convex_hull=False):
2044
+ def portfolio_optimize_treynor(es_info,graph=True,convex_hull=False,facecolor='whitesmoke'):
2020
2045
  """
2021
2046
  功能:计算投资组合的最高特雷诺比率组合,并绘图
2022
2047
  MTR: Maximium Treynor Ratio, 最高特雷诺指数方案
@@ -2031,21 +2056,21 @@ def portfolio_optimize_treynor(es_info,graph=True,convex_hull=False):
2031
2056
  name_hiret='MTR' #Maximum Treynor Ratio,指数最高点
2032
2057
  name_lorisk='GMBT' #Global Minimum Beta in Treynor,风险最低点
2033
2058
 
2034
- title_ext="特雷诺比率" #用于标题区别
2035
- colorbartxt='特雷诺比率' #用于彩色棒标签
2036
- ylabeltxt="年化风险溢价" #用于纵轴名称
2037
- x_axis_name="贝塔系数" #用于横轴名称
2059
+ title_ext=text_lang("特雷诺比率","Treynor Ratio") #用于标题区别
2060
+ colorbartxt=text_lang("特雷诺比率","Treynor Ratio") #用于彩色棒标签
2061
+ ylabeltxt=text_lang("年化风险溢价","Annualized Risk Premium") #用于纵轴名称
2062
+ x_axis_name=text_lang("贝塔系数","Beta") #用于横轴名称
2038
2063
  #定制部分结束...............................................................
2039
2064
 
2040
2065
  #计算指数,寻找最大指数点和风险最低点,并绘图标注两个点
2041
2066
  hiret_weights,lorisk_weights,portfolio_returns = \
2042
2067
  portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk, \
2043
2068
  colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=graph, \
2044
- convex_hull=convex_hull)
2069
+ convex_hull=convex_hull,facecolor=facecolor)
2045
2070
 
2046
- print("【注释】")
2047
- print("★MTR : Maximum Treynor Ratio,最大特雷诺比率点")
2048
- print("◍GMBT: #Global Minimum Beta in Treynor,全局最小特雷诺-贝塔点")
2071
+ print(text_lang("【注释】","[Notes]"))
2072
+ print("★MTR :Maximum Treynor Ratio"+text_lang(",最大特雷诺比率点",''))
2073
+ print("◍GMBT:Global Minimum Beta in Treynor"+text_lang(",全局最小特雷诺-贝塔点",''))
2049
2074
 
2050
2075
  return name_hiret,hiret_weights,name_lorisk,lorisk_weights,portfolio_returns
2051
2076
 
@@ -2056,7 +2081,7 @@ if __name__=='__main__':
2056
2081
 
2057
2082
  def portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk, \
2058
2083
  colorbartxt,title_ext,ylabeltxt,x_axis_name,graph=True, \
2059
- convex_hull=False):
2084
+ convex_hull=False,facecolor='whitesmoke'):
2060
2085
  """
2061
2086
  功能:提供rar比率优化的共同处理部分
2062
2087
  基于RandomPortfolios中的随机投资组合,计算相应的指数,寻找最大指数点和风险最小点,并绘图标注两个点
@@ -2131,7 +2156,7 @@ def portfolio_optimize_rar(es_info,col_ratio,col_y,col_x,name_hiret,name_lorisk,
2131
2156
  if graph:
2132
2157
  RandomPortfolios_plot(RandomPortfolios,col_x,col_y,colorbartxt,title_ext, \
2133
2158
  ylabeltxt,x_axis_name,pname,simulation,hstart,hend, \
2134
- hiret_point,lorisk_point,convex_hull=convex_hull)
2159
+ hiret_point,lorisk_point,convex_hull=convex_hull,facecolor=facecolor)
2135
2160
 
2136
2161
  #返回数据,供进一步分析
2137
2162
  portfolio_returns=StockReturns.copy()
@@ -2167,7 +2192,8 @@ if __name__=='__main__':
2167
2192
  convex_hull=False
2168
2193
 
2169
2194
  def portfolio_optimize(pf_info,ratio='sharpe',simulation=10000,RF=0, \
2170
- graph=True,hirar_return=False,lorisk=True,convex_hull=False):
2195
+ graph=True,hirar_return=False,lorisk=True, \
2196
+ convex_hull=False,facecolor='whitesmoke'):
2171
2197
  """
2172
2198
  功能:集成式投资组合优化策略
2173
2199
  注意:实验发现RF较小时对于结果的影响极其微小难以观察,默认设为不使用无风险利率调整收益
@@ -2198,7 +2224,7 @@ def portfolio_optimize(pf_info,ratio='sharpe',simulation=10000,RF=0, \
2198
2224
  eval(func_optimize)(es_info=es_info,RF=RF,graph=graph)
2199
2225
  """
2200
2226
  name_hiret,hiret_weights,name_lorisk,lorisk_weights,portfolio_returns= \
2201
- eval(func_optimize)(es_info=es_info,graph=graph,convex_hull=convex_hull)
2227
+ eval(func_optimize)(es_info=es_info,graph=graph,convex_hull=convex_hull,facecolor=facecolor)
2202
2228
 
2203
2229
 
2204
2230
  lang = check_language()
@@ -2209,7 +2235,7 @@ def portfolio_optimize(pf_info,ratio='sharpe',simulation=10000,RF=0, \
2209
2235
  ylabeltxt="持有收益率"
2210
2236
  else:
2211
2237
  zhuhe_txt=''
2212
- mingcheng_txt='Portfolio'
2238
+ mingcheng_txt='Strategy'
2213
2239
  titletxt="Investment Portfolio Strategy: Performance Comparison"
2214
2240
  ylabeltxt="Holding Return"
2215
2241
 
@@ -2599,7 +2625,7 @@ def security_correlation(tickers,start,end,info_type='Close'):
2599
2625
 
2600
2626
  footnote3="\n观察期间: "+start+'至'+end
2601
2627
  import datetime as dt; stoday=dt.date.today()
2602
- footnote4=";来源:Sina/EM/stooq/Yahoo,"+str(stoday)
2628
+ footnote4=";数据来源:Sina/EM/stooq/Yahoo,"+str(stoday)
2603
2629
 
2604
2630
  fontxlabel={'size':6}
2605
2631
  plt.xlabel(footnote1+footnote2+footnote3+footnote4,fontxlabel)
siat/translate.py CHANGED
@@ -17,6 +17,7 @@ SIAT:Security Investment Analysis Tool
17
17
  #关闭所有警告
18
18
  import warnings; warnings.filterwarnings('ignore')
19
19
  from siat.common import *
20
+ from siat.yf_name import *
20
21
  #==============================================================================
21
22
  def ectranslate(eword):
22
23
  """
@@ -1762,19 +1763,19 @@ def codetranslate1(code):
1762
1763
  ['000799.SZ','Jiuguijiu'],['603589.SS','Kouzijiao'],['600809.SS','Shanxi Fenjiu'],
1763
1764
 
1764
1765
  #股票:银行
1765
- ['601398.SS','ICBC(A)'],['601939.SS','CCB(A)'],
1766
- ['601288.SS','ABC(A)'],['601988.SS','BOC(A)'],
1767
- ['600000.SS','浦发银行'],['601328.SS','交通银行'],
1768
- ['600036.SS','招商银行'],['000776.SZ','广发银行'],
1769
- ['601166.SS','兴业银行'],['601169.SS','北京银行'],
1770
- ['600015.SS','华夏银行'],['601916.SS','浙商银行'],
1771
- ['600016.SS','民生银行'],['000001.SZ','平安银行'],
1772
- ['601818.SS','光大银行'],['601998.SS','中信银行'],
1773
- ['601229.SS','上海银行'],['601658.SS','邮储银行'],
1766
+ ['601398.SS','ICBC Bank(A)'],['601939.SS','CCB Bank(A)'],
1767
+ ['601288.SS','ABC Bank(A)'],['601988.SS','Bank of China(A)'],
1768
+ ['600000.SS','SPDB Bank'],['601328.SS','Bank of Communications'],
1769
+ ['600036.SS','CMB Bank'],['000776.SZ','GDB Bank'],
1770
+ ['601166.SS','Industrial Bank'],['601169.SS','Bank of Beijing'],
1771
+ ['600015.SS','Huaxia Bank'],['601916.SS','CZBank'],
1772
+ ['600016.SS','Minsheng Bank'],['000001.SZ','Pingan Bank'],
1773
+ ['601818.SS','Everbright Bank'],['601998.SS','Citic Bank'],
1774
+ ['601229.SS','Bank of Shanghai'],['601658.SS','PSBC Bank'],
1774
1775
 
1775
1776
  ['01398.HK','ICBC(HK)'],['00939.HK','CCB(HK)'],
1776
1777
  ['01288.HK','ABC(HK)'],['00857.HK','Petro China(HK)'],
1777
- ['00005.HK','HSBC(HK)'],['HSBA.L','汇丰控股()'],
1778
+ ['00005.HK','HSBC(HK)'],['HSBA.L','HSBC(UK)'],
1778
1779
  ['02888.HK','Standard Chartered(HK)'],
1779
1780
  ['03988.HK','BOC(HK)'],['BANK OF CHINA','中国银行'],
1780
1781
 
@@ -1951,13 +1952,16 @@ def codetranslate1(code):
1951
1952
  ['^NDQ','NASDAQ Composite Index'],['^NDX','NASDAQ 100 Index'],
1952
1953
  ['IBM','IBM Corp'],
1953
1954
 
1954
- ['1155.KL','Maybank'],['5347.KL','Tenaga Nasional Berhad'],
1955
- ['1295.KL','Public Bank Berhad'],['1066.KL','RHB Bank'],
1956
- ['5819.KL','Hong Leong Bank'],['5183.KL','Petronas Chemical'],
1957
- ['7113.KL','Top Glove Bhd'],['3182.KL','Genting Berhad'],
1958
- ['6888.KL','Axiata Berhad'],['1015.KL','AmBank'],
1955
+ ['1155.KL','Maybank(KL)'],['5347.KL','Tenaga Nasional(KL)'],
1956
+ ['1295.KL','Public Bank(KL)'],['1066.KL','RHB Bank(KL)'],
1957
+ ['5819.KL','Hong Leong Bank(KL)'],['5183.KL','Petronas Chemical(KL)'],
1958
+ ['7113.KL','Top Glove(KL)'],['3182.KL','Genting(KL)'],
1959
+ ['6888.KL','Axiata(KL)'],['1015.KL','AmBank(KL)'],
1959
1960
 
1960
- ['D05.SI','DBS Bank(SG)'],['U11.SI','UOB Bank(SG)'],['O39.SI','OCBC Bank(SG)'],
1961
+ ['D05.SI','DBS Bank(SG)'],['DBSDY','DBS Bank(US)'],
1962
+ ['U11.SI','UOB Bank(SG)'],['UOVEY','UOB Bank(US)'],
1963
+ ['O39.SI','OCBC Bank(SG)'],['OVCHY','OCBC Bank(US)'],
1964
+ ['S41.SI','Hong Leong Finance(SG)'],
1961
1965
 
1962
1966
  ['000002.SS','SSE A Index'],['000003.SS','SSE B Index'],
1963
1967
  ['399107.SZ','SZE A Index'],['399108.SZ','SZE B Index'],
@@ -3234,6 +3238,7 @@ if __name__=='__main__':
3234
3238
  ticker='sh018001' #金融债
3235
3239
  ticker='PDD'
3236
3240
  ticker='IBM'
3241
+ ticker='600000.SS'
3237
3242
 
3238
3243
  ticker_type='auto'
3239
3244
  ticker_type='bond'
@@ -3262,10 +3267,9 @@ def ticker1_name(ticker,ticker_type='auto'):
3262
3267
  return tname
3263
3268
  """
3264
3269
  tname=codetranslate(ticker)
3265
- if tname != ticker: #翻译成功
3270
+ if tname != ticker: #翻译成功,注意证券代码与其名称相同的情形,例如IBM
3266
3271
  return tname
3267
3272
 
3268
-
3269
3273
  symbol=ticker1_cvt2yahoo(ticker)
3270
3274
 
3271
3275
  #申万行业指数
@@ -3324,19 +3328,28 @@ def ticker1_name(ticker,ticker_type='auto'):
3324
3328
  if '基金' not in tname: tname=tname + '基金'
3325
3329
  break
3326
3330
 
3331
+ #如未查到,尝试雅虎名称
3332
+ if tname==symbol:
3333
+ #不包括中国大陆和香港证券,这些都应在前面查到?新上市的可能查不到
3334
+ #if ('.SS' not in symbol) and ('.SH' not in symbol) and ('.SZ' not in symbol) and ('.BJ' not in symbol) and ('.HK' not in symbol):
3335
+ tname=yahoo_name2(symbol)
3336
+ if tname==symbol:
3337
+ return tname
3338
+
3327
3339
  #加港股标记
3328
- if ('.HK' in ticker) and not ("港股" in tname):
3329
- tname=tname+"港股"
3340
+ if ('.HK' in ticker) and not (text_lang("港股","(HK)") in tname):
3341
+ tname=tname+text_lang("港股","(HK)")
3330
3342
  #加港股人民币柜台标志
3331
3343
  HKcode=ticker.split('.')[0]
3332
- if len(HKcode)==5 and HKcode[0]=='8' and not ("人民币" in tname):
3333
- tname=tname+"(人民币)"
3344
+ if len(HKcode)==5 and HKcode[0]=='8' and not (text_lang("人民币","(RMB)") in tname):
3345
+ tname=tname+text_lang("人民币","(RMB)")
3334
3346
 
3335
- #加美股标记
3347
+ #加美股标记:绝大多数中概股在前面已经查完,真正美股没必要标注美股
3348
+ """
3349
+ if len(ticker.split('.'))==1 and not (text_lang("美股","(US)") in tname):
3350
+ tname=tname+text_lang("美股","(US)")
3336
3351
  """
3337
- if len(ticker.split('.'))==1 and not ("美股" in tname):
3338
- tname=tname+"美股"
3339
- """
3352
+
3340
3353
  return tname
3341
3354
 
3342
3355
  #==============================================================================
siat/yf_name.py ADDED
@@ -0,0 +1,325 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ 本模块功能:SIAT公共转换函数,获取雅虎证券代码英文名称
4
+ 所属工具包:证券投资分析工具SIAT
5
+ SIAT:Security Investment Analysis Tool
6
+ 创建日期:2024年7月12日
7
+ 最新修订日期:
8
+ 作者:王德宏 (WANG Dehong, Peter)
9
+ 作者单位:北京外国语大学国际商学院
10
+ 作者邮件:wdehong2000@163.com
11
+ 版权所有:王德宏
12
+ 用途限制:仅限研究与教学使用,不可商用!商用需要额外授权。
13
+ 特别声明:作者不对使用本工具进行证券投资导致的任何损益负责!
14
+ """
15
+ #==============================================================================
16
+ #关闭所有警告
17
+ import warnings; warnings.filterwarnings('ignore')
18
+
19
+ #==============================================================================
20
+ if __name__=='__main__':
21
+ test_yahoo_access()
22
+
23
+ def test_yahoo_access():
24
+ """
25
+ 功能:测试雅虎财经是否可达
26
+ """
27
+ url="https://finance.yahoo.com"
28
+ result=test_website(url)
29
+
30
+ return result
31
+
32
+ if __name__=='__main__':
33
+ url="https://finance.yahoo.com"
34
+ test_website(url)
35
+
36
+ def test_website(url):
37
+ import requests
38
+ try:
39
+ response = requests.get(url)
40
+ if response.status_code == 200:
41
+ #print(f"Website {url} is accessible")
42
+ return True
43
+ else:
44
+ #print(f"Website {url} access failed,Code:{response.status_code}")
45
+ return False
46
+ except requests.exceptions.RequestException:
47
+ print(f"Website {url} is inaccessible")
48
+ return False
49
+
50
+ if __name__=='__main__':
51
+ s = "Hello, world. Python is fun!"
52
+ split_string(s)
53
+
54
+ def split_string(s):
55
+ import re
56
+ # 使用正则表达式匹配空格、逗号或句点
57
+ return re.split(r'[ ,.]', s)
58
+
59
+ if __name__=='__main__':
60
+ s = "Hello, world. Python is fun!"
61
+ filter_string(s)
62
+
63
+ def filter_string(s):
64
+ #排除证券名称中的多余空格、逗号和句号
65
+ slist=split_string(s)
66
+ s1=''
67
+ for sl in slist:
68
+ if sl != '':
69
+ if s1=='':
70
+ s1=sl
71
+ else:
72
+ s1=s1+' '+sl
73
+
74
+ return s1
75
+ #==============================================================================
76
+ if __name__=='__main__':
77
+ ticker='1155.KL'
78
+ ticker='MSFT'
79
+ ticker='G13.SI'
80
+ ticker='S63.SI'
81
+ ticker='SUS.ST'
82
+ ticker='600519.SS'
83
+ ticker='U11.SI'
84
+ ticker='1295.KL'
85
+ ticker='BMW.DE'
86
+ ticker='MBG.DE'
87
+ ticker='005930.KS'
88
+ ticker='LI'
89
+ ticker='600599.SS'
90
+ ticker='600123.SS'
91
+ ticker='600123.ss'
92
+ ticker='600999.ss'
93
+ ticker='600111.ss'
94
+ ticker='600333.ss'
95
+ ticker='600444.ss'
96
+ ticker='600777.ss'
97
+
98
+ yahoo_name1(ticker)
99
+
100
+ #极端测试
101
+ inamelist=[]
102
+ for i in range(100,150+1):
103
+ icode=str(600000+i)+'.SS'
104
+ iname=yahoo_name1(icode)
105
+ print(icode+':',iname)
106
+ inamelist=inamelist+[iname]
107
+
108
+ #发现问题后单独测试
109
+ ticker='600087.SS'
110
+ yahoo_name1(ticker)
111
+
112
+ yahoo_name1(ticker,short_name=True)
113
+
114
+ ticker_name(ticker)
115
+
116
+ def yahoo_name1(ticker,short_name=False,add_suffix=True,maxlen=80):
117
+ """
118
+ 功能:从雅虎财经取得全球证券名称,仅限英文。需要去掉常用词,如Corporation
119
+ 优点:对未定义的证券代码也可给出英文名称,即使在中文语言环境中
120
+ 现存问题:需要访问雅虎,且耗时稍长
121
+ """
122
+ #测试雅虎
123
+ if not test_yahoo_access():
124
+ return ticker
125
+
126
+ #需要去掉的单词,注意顺序不要轻易颠倒!子串包含的,要长文在前!
127
+ remove_list=['Corporation','Berhad','Bhd','PLC','plc','Plc', \
128
+ ', Inc.','Inc.', \
129
+ 'AG ST','AG','NA O.N.', \
130
+ 'Aktiengesellschaft','(publ)', \
131
+ ', LLC','LLC', \
132
+ 'Co., Ltd.','Co., Ltd','Co.,Ltd.','Co.,Ltd','Co,.Ltd','co.,ltd', \
133
+ 'Co. LTD','CO.,LTD','Co., Limited', \
134
+ 'Ltd.','Ltd', \
135
+ 'Company', \
136
+ 'Incorporated', \
137
+ 'Corp., Ltd.','Corp.','Corp','AB', \
138
+ 'Limited', \
139
+
140
+ #强行缩短名称长度,去掉不影响名称的花哨词语
141
+ '(Group)','Group', \
142
+ 'Science & Technology','High-Tech','High Technology', \
143
+
144
+ #扫尾漏网之逗号句点
145
+ '.',',']
146
+
147
+ """
148
+ remove_list=['Corporation','Berhad','Bhd','PLC','plc','Limited', \
149
+ 'Inc', \
150
+ 'AG ST','AG','NA O.N.', \
151
+ 'Aktiengesellschaft','(publ)', \
152
+ 'LLC', \
153
+ 'Co., Ltd.','Ltd.','Ltd', \
154
+ 'Company', \
155
+ 'Incorporated','Corp.','AB']
156
+ """
157
+ #去掉ticker中的.US后缀
158
+ ticker=ticker.upper()
159
+ ticker1=ticker.replace('.US', "")
160
+
161
+ import yfinance as yf
162
+ ticker_info = yf.Ticker(ticker1)
163
+
164
+ try:
165
+ t_info=ticker_info.info
166
+ except:
167
+ pass
168
+ return ticker
169
+
170
+ try:
171
+ if short_name:
172
+ t_name0=t_info['shortName']
173
+ else:
174
+ t_name0=t_info['longName']
175
+ if len(t_name0) > maxlen:
176
+ t_name0=t_info['shortName']
177
+ except:
178
+ pass
179
+ return ticker #未找到ticker
180
+
181
+ #过滤逗号句点?过滤也可能带来更多复杂性!
182
+ #t_name1=filter_string(t_name0)
183
+ t_name1=t_name0
184
+
185
+ for r in remove_list:
186
+ t_name1=t_name1.replace(r, "")
187
+
188
+ #排除前后空格
189
+ t_name=t_name1.strip()
190
+
191
+ #增加交易所后缀
192
+ if add_suffix:
193
+ tlist=ticker.split('.')
194
+ if len(tlist)==2:
195
+ sid=tlist[1]
196
+ if sid not in ['SS','SZ','BJ']:
197
+ t_name=t_name+'('+sid+')'
198
+
199
+ return t_name
200
+
201
+ #==============================================================================
202
+ if __name__=='__main__':
203
+ ticker='1155.KL'
204
+ ticker='MSFT'
205
+ ticker='G13.SI'
206
+ ticker='S63.SI'
207
+ ticker='SUS.ST'
208
+ ticker='600519.SS'
209
+ ticker='U11.SI'
210
+ ticker='1295.KL'
211
+ ticker='BMW.DE'
212
+ ticker='MBG.DE'
213
+ ticker='005930.KS'
214
+ ticker='LI'
215
+ ticker='600599.SS'
216
+ ticker='600123.SS'
217
+ ticker='600123.ss'
218
+ ticker='600999.ss'
219
+ ticker='600111.ss'
220
+ ticker='600333.ss'
221
+ ticker='600444.ss'
222
+ ticker='600777.ss'
223
+
224
+ yahoo_name2(ticker)
225
+
226
+ #极端测试
227
+ inamelist=[]
228
+ for i in range(0,50+1):
229
+ icode=str(600000+i)+'.SS'
230
+ iname=yahoo_name2(icode)
231
+ print(icode+':',iname)
232
+ inamelist=inamelist+[iname]
233
+
234
+ #发现问题后单独测试
235
+ ticker='600088.SS'
236
+ yahoo_name1(ticker)
237
+ yahoo_name2(ticker)
238
+
239
+ yahoo_name2(ticker,short_name=True)
240
+
241
+ ticker_name(ticker)
242
+
243
+ def yahoo_name2(ticker,short_name=False,add_suffix=True,maxlen=80):
244
+ """
245
+ 功能:从雅虎财经取得全球证券名称,仅限英文。需要去掉常用词,如Corporation
246
+ 优点:对未定义的证券代码也可给出英文名称,即使在中文语言环境中
247
+ 现存问题:需要访问雅虎,且耗时稍长
248
+ """
249
+ #定义需要去掉的单词,注意顺序不要轻易颠倒!子串包含的,要长文在前!前置留空格的为避免误删
250
+ remove_list=[' CORPORATION',' BERHAD',' BHD',' PLC',' INC',' AG ST',' NA O N', \
251
+ ' AKTIENGESELLSCHAFT','(PUBL)',' LLC', \
252
+ ' CO LTD',' CO LIMITED',' LTD',' LIMITED',' COMPANY',' INCORPORATED', \
253
+ ' CORP LTD',' CORP',' AB', \
254
+ '(GROUP)',' GROUP', \
255
+
256
+ ' SCIENCE & TECHNOLOGY',' HIGH-TECH',' HIGH TECHNOLOGY']
257
+
258
+
259
+ #测试雅虎
260
+ if not test_yahoo_access():
261
+ return ticker
262
+
263
+ #去掉ticker中的.US后缀
264
+ ticker=ticker.upper()
265
+ ticker1=ticker.replace('.US', "")
266
+
267
+ import yfinance as yf
268
+ ticker_info = yf.Ticker(ticker1)
269
+
270
+ try:
271
+ t_info=ticker_info.info
272
+ except:
273
+ pass
274
+ return ticker
275
+
276
+ try:
277
+ if short_name:
278
+ t_name0=t_info['shortName']
279
+ else:
280
+ t_name0=t_info['longName']
281
+ if len(t_name0) > maxlen:
282
+ t_name0=t_info['shortName']
283
+ except:
284
+ pass
285
+ return ticker #未找到ticker
286
+
287
+ #去掉逗号和句点
288
+ name1=t_name0.replace(',',' ')
289
+ name2=name1.replace('.',' ')
290
+
291
+ #将字符串中的多个空格变为单个空格
292
+ name3=replace_multiple_spaces(name2)
293
+
294
+ #将字符串字母全部大写
295
+ name4=name3.upper()
296
+
297
+ name5=name4
298
+ for ss in remove_list:
299
+ name5=name5.replace(ss,'')
300
+
301
+ name6=name5.strip()
302
+
303
+ name7=t_name0[:len(name6)]
304
+
305
+ #增加交易所后缀
306
+ t_name=name7
307
+ if add_suffix:
308
+ tlist=ticker.split('.')
309
+ if len(tlist)==2:
310
+ sid=tlist[1]
311
+ if sid not in ['SS','SZ','BJ']:
312
+ t_name=t_name+'('+sid+')'
313
+
314
+ return t_name
315
+ #==============================================================================
316
+ #==============================================================================
317
+ #==============================================================================
318
+ #==============================================================================
319
+ #==============================================================================
320
+ #==============================================================================
321
+ #==============================================================================
322
+ #==============================================================================
323
+ #==============================================================================
324
+ #==============================================================================
325
+ #==============================================================================
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: siat
3
- Version: 3.2.57
3
+ Version: 3.2.59
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
@@ -18,7 +18,7 @@ siat/capm_beta.py,sha256=cxXdRVBQBllhbfz1LeTJAIWvyRYhW54nhtNUXv4HwS0,29063
18
18
  siat/capm_beta2.py,sha256=d7lZ-VXVVmBkMVGDPlozL-9gAU3cYpHG23X1WSRCOgY,26907
19
19
  siat/capm_beta_test.py,sha256=ImR0c5mc4hIl714XmHztdl7qg8v1E2lycKyiqnFj6qs,1745
20
20
  siat/cmat_commons.py,sha256=Nj9Kf0alywaztVoMVeVVL_EZk5jRERJy8R8kBw88_Tg,38116
21
- siat/common.py,sha256=voALy4D-hTj7VOmibBH-1P0QUJf6PU-aS7hjjbFP7Zo,151717
21
+ siat/common.py,sha256=VU4AhQZGQmTCcw-lbiuG7jSz7Dsy1psOi9ayaAbBDdY,151635
22
22
  siat/compare_cross.py,sha256=3iP9TH2h3w27F2ARZc7FjKcErYCzWRc-TPiymOyoVtw,24171
23
23
  siat/compare_cross_test.py,sha256=xra5XYmQGEtfIZL2h-GssdH2hLdFIhG3eoCrkDrL3gY,3473
24
24
  siat/concepts_iwencai.py,sha256=m1YEDtECRT6FqtzlKm91pt2I9d3Z_XoP59BtWdRdu8I,3061
@@ -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=glHikhabFAF6Hb6df1pYfhkxid2IZXBYAVQng5wd9Wk,97526
71
71
  siat/markowitz2-20240620.py,sha256=irZAPnjaatFsKQmFRMENP-cO6bEUl2narYtkU5NKTWI,108019
72
- siat/markowitz2.py,sha256=csHIjqTbIsHMYQ_LEur9K0Jg8pOm8deEVdQfAGCOG5o,111461
72
+ siat/markowitz2.py,sha256=oStv4V74OiqBk-rnBPo6QJTUSNe1FCyT1Yl6-Fx_mHc,113934
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
@@ -131,14 +131,15 @@ siat/transaction_test.py,sha256=Z8g1LJCN4-mnUByXMUMoFmN0t105cbmsz2QmvSuIkbU,1858
131
131
  siat/translate-20230125.py,sha256=NPPSXhT38s5t9fzMvl_fvi4ckSB73ThLmZetVI-xGdU,117953
132
132
  siat/translate-20230206.py,sha256=-vtI125WyaJhmPotOpDAmclt_XnYVaWU9ByLWZ6FyYE,118133
133
133
  siat/translate-20230215.py,sha256=TJgtPE3n8IjljmZ4Pefy8dmHoNdFF-1zpML6BhA9FKE,121657
134
- siat/translate.py,sha256=VeOmlFEOUGFzLGCvkHs6MLHcwPChxaCtOlH3l4Lycmk,216989
134
+ siat/translate.py,sha256=v4__NZBhC7cVevl_lKxwhcKQa_UFuyVK1pdB6_KEflI,217855
135
135
  siat/translate_20240606.py,sha256=63IyHWEU3Uz9mjwyuAX3fqY4nUMdwh0ICQAgmgPXP7Y,215121
136
136
  siat/universal_test.py,sha256=CDAOffW1Rvs-TcNN5giWVvHMlch1w4dp-w5SIV9jXL0,3936
137
137
  siat/valuation.py,sha256=NKfeZMdDJOW42oLVHob6eSVBXUqlN1OCnnzwyGAst8c,48855
138
138
  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
- siat-3.2.57.dist-info/METADATA,sha256=s71iq16m6Vre5twfLLE1TvjanbaUZQaj43J6v-Sn4t4,7310
142
- siat-3.2.57.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
143
- siat-3.2.57.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
144
- siat-3.2.57.dist-info/RECORD,,
141
+ siat/yf_name.py,sha256=CI3xZJSMGbDCKhmpL8_6DdebH6EDnVUaSfdTSf-FnA8,10199
142
+ siat-3.2.59.dist-info/METADATA,sha256=suq3jI9DoMGKMeRXn-DbMpSlZhVwWtopNKsfiBjgOjw,7310
143
+ siat-3.2.59.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
144
+ siat-3.2.59.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
145
+ siat-3.2.59.dist-info/RECORD,,
File without changes