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 +0 -2
- siat/markowitz2.py +103 -77
- siat/translate.py +39 -26
- siat/yf_name.py +325 -0
- {siat-3.2.57.dist-info → siat-3.2.59.dist-info}/METADATA +1 -1
- {siat-3.2.57.dist-info → siat-3.2.59.dist-info}/RECORD +8 -7
- {siat-3.2.57.dist-info → siat-3.2.59.dist-info}/WHEEL +0 -0
- {siat-3.2.57.dist-info → siat-3.2.59.dist-info}/top_level.txt +0 -0
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
|
166
|
+
footnote2="\n数据来源:Sina/EM/Stooq/Yahoo,"+str(stoday)
|
167
167
|
else:
|
168
168
|
footnote1="Period of observation: "+hstart+' to '+hend
|
169
|
-
footnote2="\
|
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(
|
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("
|
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("来源: 综合新浪/东方财富/
|
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(
|
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("
|
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
|
502
|
-
Portfolio_EW_txt=text_lang("等权重策略","Equal-
|
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-
|
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("
|
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(" *
|
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=
|
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("
|
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
|
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
|
1245
|
+
footnote2="Based on given securities, constructed "+str(simulation)+" portfolios\n"
|
1229
1246
|
footnote3="Period of observation: "+hstart+" to "+hend
|
1230
|
-
footnote4="\
|
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+":
|
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="
|
1763
|
+
footnote2="基于给定证券构造"+str(simulation)+"个投资组合"
|
1746
1764
|
footnote3="\n观察期间:"+hstart+"至"+hend
|
1747
|
-
footnote4="\n
|
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+":
|
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
|
1774
|
+
footnote2="Based on given securities, constructed "+str(simulation)+" portfolios"
|
1757
1775
|
footnote3="\nPeriod of observation: "+hstart+" to "+hend
|
1758
|
-
footnote4="\
|
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(
|
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
|
-
|
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 :
|
1902
|
-
print("◍GMVS:
|
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
|
1951
|
-
print("◍GML:
|
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 :
|
2001
|
-
print("◍GMBA:
|
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 :
|
2048
|
-
print("◍GMBT:
|
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,
|
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='
|
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="
|
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','
|
1767
|
-
['600000.SS','
|
1768
|
-
['600036.SS','
|
1769
|
-
['601166.SS','
|
1770
|
-
['600015.SS','
|
1771
|
-
['600016.SS','
|
1772
|
-
['601818.SS','
|
1773
|
-
['601229.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
|
1955
|
-
['1295.KL','Public Bank
|
1956
|
-
['5819.KL','Hong Leong Bank'],['5183.KL','Petronas Chemical'],
|
1957
|
-
['7113.KL','Top Glove
|
1958
|
-
['6888.KL','Axiata
|
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)'],['
|
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
|
-
|
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
|
+
#==============================================================================
|
@@ -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=
|
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=
|
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=
|
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
|
142
|
-
siat-3.2.
|
143
|
-
siat-3.2.
|
144
|
-
siat-3.2.
|
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
|
File without changes
|