siat 3.2.58__py3-none-any.whl → 3.3.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/allin.py +3 -0
- siat/common.py +0 -2
- siat/markowitz2.py +5 -5
- siat/security_prices.py +35 -18
- siat/translate.py +28 -16
- siat/yf_name.py +469 -0
- {siat-3.2.58.dist-info → siat-3.3.1.dist-info}/METADATA +1 -1
- {siat-3.2.58.dist-info → siat-3.3.1.dist-info}/RECORD +10 -9
- {siat-3.2.58.dist-info → siat-3.3.1.dist-info}/WHEEL +0 -0
- {siat-3.2.58.dist-info → siat-3.3.1.dist-info}/top_level.txt +0 -0
siat/allin.py
CHANGED
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
@@ -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
|
|
@@ -1233,7 +1233,7 @@ def portfolio_eset(pf_info,simulation=1000,convex_hull=False):
|
|
1233
1233
|
footnote1="年化收益率标准差-->"
|
1234
1234
|
footnote2="\n\n基于给定的成份证券构造"+str(simulation)+"个投资组合"
|
1235
1235
|
footnote3="\n观察期间:"+hstart+"至"+hend
|
1236
|
-
footnote4="\n
|
1236
|
+
footnote4="\n数据来源: Sina/EM/Stooq/Yahoo, "+str(stoday)
|
1237
1237
|
else:
|
1238
1238
|
if pname == '': pname='Investment Portfolio'
|
1239
1239
|
|
@@ -1244,7 +1244,7 @@ def portfolio_eset(pf_info,simulation=1000,convex_hull=False):
|
|
1244
1244
|
footnote1="Annualized Std -->\n\n"
|
1245
1245
|
footnote2="Based on given securities, constructed "+str(simulation)+" portfolios\n"
|
1246
1246
|
footnote3="Period of observation: "+hstart+" to "+hend
|
1247
|
-
footnote4="\
|
1247
|
+
footnote4="\nData source: Sina/EM/Stooq/Yahoo, "+str(stoday)
|
1248
1248
|
|
1249
1249
|
plt.xlabel(footnote1+footnote2+footnote3+footnote4,fontsize=xlabel_txt_size)
|
1250
1250
|
|
@@ -2625,7 +2625,7 @@ def security_correlation(tickers,start,end,info_type='Close'):
|
|
2625
2625
|
|
2626
2626
|
footnote3="\n观察期间: "+start+'至'+end
|
2627
2627
|
import datetime as dt; stoday=dt.date.today()
|
2628
|
-
footnote4="
|
2628
|
+
footnote4=";数据来源:Sina/EM/stooq/Yahoo,"+str(stoday)
|
2629
2629
|
|
2630
2630
|
fontxlabel={'size':6}
|
2631
2631
|
plt.xlabel(footnote1+footnote2+footnote3+footnote4,fontxlabel)
|
siat/security_prices.py
CHANGED
@@ -417,13 +417,16 @@ def get_price_ak_em(ticker,fromdate,todate,adjust='',ticker_type='auto'):
|
|
417
417
|
df1['footnote']=adjust
|
418
418
|
|
419
419
|
num=len(df1)
|
420
|
+
"""
|
420
421
|
ptname=ticker_name(ticker,ticker_type)
|
421
422
|
if ptname == ticker: ptname=''
|
422
|
-
|
423
|
+
"""
|
423
424
|
if num > 0:
|
424
|
-
print(" Successfully retrieved",num,"records for",ticker,ptname)
|
425
|
+
#print(" Successfully retrieved",num,"records for",ticker,ptname)
|
426
|
+
print(" Successfully retrieved",num,"records for",ticker)
|
425
427
|
else:
|
426
|
-
print(" Sorry, no records retrieved for",ticker,ptname)
|
428
|
+
#print(" Sorry, no records retrieved for",ticker,ptname)
|
429
|
+
print(" Sorry, no records retrieved for",ticker)
|
427
430
|
|
428
431
|
return df1
|
429
432
|
|
@@ -610,15 +613,17 @@ def get_price_stooq(ticker,start,end):
|
|
610
613
|
|
611
614
|
_,start1,end1=check_period(start,end)
|
612
615
|
prices2=prices[(prices.index >= start1) & (prices.index <= end1)]
|
616
|
+
|
613
617
|
num=len(prices2)
|
618
|
+
"""
|
614
619
|
ptname=ticker_name(ticker,'stock')
|
615
620
|
if ptname == ticker: ptname=''
|
616
|
-
|
621
|
+
"""
|
617
622
|
if num > 0:
|
618
|
-
print(" Successfully retrieved",num,"records for",ticker
|
623
|
+
print(" Successfully retrieved",num,"records for",ticker)
|
619
624
|
return prices2
|
620
625
|
else:
|
621
|
-
print(" Sorry, no records found from stooq for",ticker,
|
626
|
+
print(" Sorry, no records found from stooq for",ticker,"from",start,'to',end)
|
622
627
|
return None
|
623
628
|
else:
|
624
629
|
return None
|
@@ -930,13 +935,15 @@ def get_price_ak_cn(ticker,fromdate,todate,adjust='',ticker_type='auto'):
|
|
930
935
|
df2['ticker']=str(ticker)
|
931
936
|
if 'Adj Close' not in list(df2):
|
932
937
|
df2['Adj Close']=df2['Close']
|
933
|
-
df2['footnote']=adjust
|
934
|
-
|
938
|
+
df2['footnote']=adjust
|
939
|
+
|
940
|
+
"""
|
935
941
|
ptname=ticker_name(ticker,ticker_type)
|
936
942
|
if ptname == ticker: ptname=''
|
943
|
+
"""
|
937
944
|
|
938
945
|
if len(df2) > 0:
|
939
|
-
print(" Successfully retrieved",len(df2),"records for",ticker
|
946
|
+
print(" Successfully retrieved",len(df2),"records for",ticker)
|
940
947
|
|
941
948
|
return df2
|
942
949
|
|
@@ -1019,10 +1026,12 @@ def get_price_ak_us(symbol, fromdate, todate, adjust=""):
|
|
1019
1026
|
df2['source']=text_lang('新浪','Sina')
|
1020
1027
|
df2['footnote']=adjust
|
1021
1028
|
|
1029
|
+
"""
|
1022
1030
|
ptname=ticker_name(symbol,'stock')
|
1023
1031
|
if ptname == symbol: ptname=''
|
1024
|
-
|
1025
|
-
|
1032
|
+
"""
|
1033
|
+
|
1034
|
+
print(" Successfully retrieved",num,"records for",symbol)
|
1026
1035
|
|
1027
1036
|
return df2
|
1028
1037
|
|
@@ -1106,10 +1115,12 @@ def get_price_ak_hk(symbol,fromdate,todate,adjust=""):
|
|
1106
1115
|
df2['Adj Close']=df2['Close']
|
1107
1116
|
df2['source']=text_lang('新浪','Sina')
|
1108
1117
|
|
1118
|
+
"""
|
1109
1119
|
ptname=ticker_name(symbol,'stock')
|
1110
1120
|
if ptname == symbol: ptname=''
|
1121
|
+
"""
|
1111
1122
|
|
1112
|
-
print(" Successfully retrieved",num,"records for",symbol
|
1123
|
+
print(" Successfully retrieved",num,"records for",symbol)
|
1113
1124
|
|
1114
1125
|
return df2
|
1115
1126
|
|
@@ -1301,10 +1312,12 @@ def get_prices_yahoo(ticker,start,end,retry_count=3,pause=1):
|
|
1301
1312
|
#p['Adj Close']=p['Close']
|
1302
1313
|
p['source']=text_lang('雅虎','Yahoo')
|
1303
1314
|
|
1315
|
+
"""
|
1304
1316
|
ptname=ticker_name(ticker,'stock')
|
1305
1317
|
if ptname == ticker: ptname=''
|
1306
|
-
|
1307
|
-
|
1318
|
+
"""
|
1319
|
+
|
1320
|
+
print(" Successfully retrieved",len(p),"records for",ticker)
|
1308
1321
|
|
1309
1322
|
#去掉时区
|
1310
1323
|
p=df_index_timezone_remove(p)
|
@@ -1389,10 +1402,12 @@ def get_prices_yf(ticker,start,end,threads=False):
|
|
1389
1402
|
p['source']=text_lang('雅虎','Yahoo')
|
1390
1403
|
|
1391
1404
|
if len(p) > 0:
|
1405
|
+
"""
|
1392
1406
|
ptname=ticker_name(ticker1,'stock')
|
1393
1407
|
if ptname == ticker: ptname=''
|
1394
|
-
|
1395
|
-
|
1408
|
+
"""
|
1409
|
+
|
1410
|
+
print(" Successfully retrieved",len(p),"records for",ticker1)
|
1396
1411
|
|
1397
1412
|
#去掉时区
|
1398
1413
|
p=df_index_timezone_remove(p)
|
@@ -1458,10 +1473,12 @@ def get_index_fred(ticker,start,end):
|
|
1458
1473
|
|
1459
1474
|
num=len(df)
|
1460
1475
|
if num > 0:
|
1476
|
+
"""
|
1461
1477
|
ptname=ticker_name(ticker,'stock')
|
1462
1478
|
if ptname == ticker: ptname=''
|
1463
|
-
|
1464
|
-
|
1479
|
+
"""
|
1480
|
+
|
1481
|
+
print(" Successfully retrieved",num,"records for",ticker)
|
1465
1482
|
else:
|
1466
1483
|
print(" Sorry, no records retrieved for",ticker)
|
1467
1484
|
|
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
|
"""
|
@@ -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'],
|
@@ -3263,10 +3267,9 @@ def ticker1_name(ticker,ticker_type='auto'):
|
|
3263
3267
|
return tname
|
3264
3268
|
"""
|
3265
3269
|
tname=codetranslate(ticker)
|
3266
|
-
if tname != ticker:
|
3270
|
+
if tname != ticker: #翻译成功,注意证券代码与其名称相同的情形,例如IBM
|
3267
3271
|
return tname
|
3268
3272
|
|
3269
|
-
|
3270
3273
|
symbol=ticker1_cvt2yahoo(ticker)
|
3271
3274
|
|
3272
3275
|
#申万行业指数
|
@@ -3325,19 +3328,28 @@ def ticker1_name(ticker,ticker_type='auto'):
|
|
3325
3328
|
if '基金' not in tname: tname=tname + '基金'
|
3326
3329
|
break
|
3327
3330
|
|
3331
|
+
#如未查到,尝试stooq和雅虎名称,限英文名称
|
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=get_stock_name1_en(symbol)
|
3336
|
+
if tname==symbol:
|
3337
|
+
return tname
|
3338
|
+
|
3328
3339
|
#加港股标记
|
3329
|
-
if ('.HK' in ticker) and not ("港股" in tname):
|
3330
|
-
tname=tname+"港股"
|
3340
|
+
if ('.HK' in ticker) and not (text_lang("港股","(HK)") in tname):
|
3341
|
+
tname=tname+text_lang("港股","(HK)")
|
3331
3342
|
#加港股人民币柜台标志
|
3332
3343
|
HKcode=ticker.split('.')[0]
|
3333
|
-
if len(HKcode)==5 and HKcode[0]=='8' and not ("人民币" in tname):
|
3334
|
-
tname=tname+"(
|
3344
|
+
if len(HKcode)==5 and HKcode[0]=='8' and not (text_lang("人民币","(RMB)") in tname):
|
3345
|
+
tname=tname+text_lang("人民币","(RMB)")
|
3335
3346
|
|
3336
|
-
|
3347
|
+
#加美股标记:绝大多数中概股在前面已经查完,真正美股没必要标注美股
|
3337
3348
|
"""
|
3338
|
-
if len(ticker.split('.'))==1 and not ("美股" in tname):
|
3339
|
-
tname=tname+"美股"
|
3340
|
-
"""
|
3349
|
+
if len(ticker.split('.'))==1 and not (text_lang("美股","(US)") in tname):
|
3350
|
+
tname=tname+text_lang("美股","(US)")
|
3351
|
+
"""
|
3352
|
+
|
3341
3353
|
return tname
|
3342
3354
|
|
3343
3355
|
#==============================================================================
|
siat/yf_name.py
ADDED
@@ -0,0 +1,469 @@
|
|
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_name1x(ticker,short_name=False,add_suffix=True,maxlen=80):
|
117
|
+
"""
|
118
|
+
功能:从雅虎财经取得全球证券名称,仅限英文。需要去掉常用词,如Corporation
|
119
|
+
优点:对未定义的证券代码也可给出英文名称,即使在中文语言环境中
|
120
|
+
现存问题:需要访问雅虎,且耗时稍长
|
121
|
+
废弃!!!
|
122
|
+
"""
|
123
|
+
#测试雅虎
|
124
|
+
if not test_yahoo_access():
|
125
|
+
return ticker
|
126
|
+
|
127
|
+
#需要去掉的单词,注意顺序不要轻易颠倒!子串包含的,要长文在前!
|
128
|
+
remove_list=['Corporation','Berhad','Bhd','PLC','plc','Plc', \
|
129
|
+
', Inc.','Inc.', \
|
130
|
+
'AG ST','AG','NA O.N.', \
|
131
|
+
'Aktiengesellschaft','(publ)', \
|
132
|
+
', LLC','LLC', \
|
133
|
+
'Co., Ltd.','Co., Ltd','Co.,Ltd.','Co.,Ltd','Co,.Ltd','co.,ltd', \
|
134
|
+
'Co. LTD','CO.,LTD','Co., Limited', \
|
135
|
+
'Ltd.','Ltd', \
|
136
|
+
'Company', \
|
137
|
+
'Incorporated', \
|
138
|
+
'Corp., Ltd.','Corp.','Corp','AB', \
|
139
|
+
'Limited', \
|
140
|
+
|
141
|
+
#强行缩短名称长度,去掉不影响名称的花哨词语
|
142
|
+
'(Group)','Group', \
|
143
|
+
'Science & Technology','High-Tech','High Technology', \
|
144
|
+
|
145
|
+
#扫尾漏网之逗号句点
|
146
|
+
'.',',']
|
147
|
+
|
148
|
+
"""
|
149
|
+
remove_list=['Corporation','Berhad','Bhd','PLC','plc','Limited', \
|
150
|
+
'Inc', \
|
151
|
+
'AG ST','AG','NA O.N.', \
|
152
|
+
'Aktiengesellschaft','(publ)', \
|
153
|
+
'LLC', \
|
154
|
+
'Co., Ltd.','Ltd.','Ltd', \
|
155
|
+
'Company', \
|
156
|
+
'Incorporated','Corp.','AB']
|
157
|
+
"""
|
158
|
+
#去掉ticker中的.US后缀
|
159
|
+
ticker=ticker.upper()
|
160
|
+
ticker1=ticker.replace('.US', "")
|
161
|
+
|
162
|
+
import yfinance as yf
|
163
|
+
ticker_info = yf.Ticker(ticker1)
|
164
|
+
|
165
|
+
try:
|
166
|
+
t_info=ticker_info.info
|
167
|
+
except:
|
168
|
+
pass
|
169
|
+
return ticker
|
170
|
+
|
171
|
+
try:
|
172
|
+
if short_name:
|
173
|
+
t_name0=t_info['shortName']
|
174
|
+
else:
|
175
|
+
t_name0=t_info['longName']
|
176
|
+
if len(t_name0) > maxlen:
|
177
|
+
t_name0=t_info['shortName']
|
178
|
+
except:
|
179
|
+
pass
|
180
|
+
return ticker #未找到ticker
|
181
|
+
|
182
|
+
#过滤逗号句点?过滤也可能带来更多复杂性!
|
183
|
+
#t_name1=filter_string(t_name0)
|
184
|
+
t_name1=t_name0
|
185
|
+
|
186
|
+
for r in remove_list:
|
187
|
+
t_name1=t_name1.replace(r, "")
|
188
|
+
|
189
|
+
#排除前后空格
|
190
|
+
t_name=t_name1.strip()
|
191
|
+
|
192
|
+
#增加交易所后缀
|
193
|
+
if add_suffix:
|
194
|
+
tlist=ticker.split('.')
|
195
|
+
if len(tlist)==2:
|
196
|
+
sid=tlist[1]
|
197
|
+
if sid not in ['SS','SZ','BJ']:
|
198
|
+
t_name=t_name+'('+sid+')'
|
199
|
+
|
200
|
+
return t_name
|
201
|
+
|
202
|
+
#==============================================================================
|
203
|
+
def replace_multiple_spaces(s):
|
204
|
+
import re
|
205
|
+
return re.sub(r'\s+', ' ', s)
|
206
|
+
|
207
|
+
#==============================================================================
|
208
|
+
if __name__=='__main__':
|
209
|
+
ticker='1155.KL'
|
210
|
+
ticker='MSFT'
|
211
|
+
ticker='G13.SI'
|
212
|
+
ticker='S63.SI'
|
213
|
+
ticker='SUS.ST'
|
214
|
+
ticker='600519.SS'
|
215
|
+
ticker='U11.SI'
|
216
|
+
ticker='1295.KL'
|
217
|
+
ticker='BMW.DE'
|
218
|
+
ticker='MBG.DE'
|
219
|
+
ticker='005930.KS'
|
220
|
+
ticker='LI'
|
221
|
+
ticker='600599.SS'
|
222
|
+
ticker='600123.SS'
|
223
|
+
ticker='600123.ss'
|
224
|
+
ticker='600999.ss'
|
225
|
+
ticker='600111.ss'
|
226
|
+
ticker='600333.ss'
|
227
|
+
ticker='600444.ss'
|
228
|
+
ticker='600777.ss'
|
229
|
+
ticker='CPL.WA'
|
230
|
+
|
231
|
+
yahoo_name2(ticker)
|
232
|
+
|
233
|
+
#极端测试
|
234
|
+
inamelist=[]
|
235
|
+
for i in range(0,50+1):
|
236
|
+
icode=str(600000+i)+'.SS'
|
237
|
+
iname=yahoo_name2(icode)
|
238
|
+
print(icode+':',iname)
|
239
|
+
inamelist=inamelist+[iname]
|
240
|
+
|
241
|
+
#发现问题后单独测试
|
242
|
+
ticker='600088.SS'
|
243
|
+
yahoo_name1(ticker)
|
244
|
+
yahoo_name2(ticker)
|
245
|
+
|
246
|
+
yahoo_name2(ticker,short_name=True)
|
247
|
+
|
248
|
+
ticker_name(ticker)
|
249
|
+
|
250
|
+
def yahoo_name1(ticker,short_name=False,add_suffix=True,maxlen=80):
|
251
|
+
"""
|
252
|
+
功能:从雅虎财经取得全球证券名称,仅限英文。需要去掉常用词,如Corporation
|
253
|
+
优点:对未定义的证券代码也可给出英文名称,即使在中文语言环境中
|
254
|
+
现存问题:需要访问雅虎,且耗时稍长
|
255
|
+
"""
|
256
|
+
|
257
|
+
|
258
|
+
#测试雅虎
|
259
|
+
if not test_yahoo_access():
|
260
|
+
return ticker
|
261
|
+
|
262
|
+
#去掉ticker中的.US后缀
|
263
|
+
ticker=ticker.upper()
|
264
|
+
ticker1=ticker.replace('.US', "")
|
265
|
+
|
266
|
+
import yfinance as yf
|
267
|
+
ticker_info = yf.Ticker(ticker1)
|
268
|
+
|
269
|
+
try:
|
270
|
+
t_info=ticker_info.info
|
271
|
+
except:
|
272
|
+
pass
|
273
|
+
return ticker
|
274
|
+
|
275
|
+
try:
|
276
|
+
if short_name:
|
277
|
+
t_name0=t_info['shortName']
|
278
|
+
else:
|
279
|
+
t_name0=t_info['longName']
|
280
|
+
if len(t_name0) > maxlen:
|
281
|
+
t_name0=t_info['shortName']
|
282
|
+
except:
|
283
|
+
pass
|
284
|
+
return ticker #未找到ticker
|
285
|
+
|
286
|
+
#过滤名称中多余的尾部词汇
|
287
|
+
t_name=filter_stock_name(t_name0)
|
288
|
+
|
289
|
+
#增加交易所后缀
|
290
|
+
if add_suffix:
|
291
|
+
tlist=ticker.split('.')
|
292
|
+
if len(tlist)==2:
|
293
|
+
sid=tlist[1]
|
294
|
+
if sid not in ['SS','SZ','BJ']:
|
295
|
+
t_name=t_name+'('+sid+')'
|
296
|
+
|
297
|
+
return t_name
|
298
|
+
#==============================================================================
|
299
|
+
if __name__=='__main__':
|
300
|
+
original_name='Oponeo.pl SA'
|
301
|
+
original_name='Apple Inc'
|
302
|
+
|
303
|
+
filter_stock_name(original_name)
|
304
|
+
|
305
|
+
def filter_stock_name(original_name):
|
306
|
+
"""
|
307
|
+
功能:过滤从网站上抓取到的证券名称,去掉尾部的公司类别词汇,缩短长度,便于显示
|
308
|
+
"""
|
309
|
+
#定义需要去掉的单词,注意顺序不要轻易颠倒!子串包含的,要长文在前!前置留空格的为避免误删
|
310
|
+
remove_list=[' CORPORATION',' BERHAD',' BHD',' PLC',' INC',' AG ST',' NA O N', \
|
311
|
+
' AKTIENGESELLSCHAFT','(PUBL)',' LLC', \
|
312
|
+
' CO LTD',' CO LIMITED',' LTD',' LIMITED',' COMPANY',' INCORPORATED', \
|
313
|
+
' CORP LTD',' CORP',' AB', \
|
314
|
+
' GROUP CO','(GROUP)',' GROUP', \
|
315
|
+
' PL S A',' PL SA',' AG', \
|
316
|
+
' SCIENCE & TECHNOLOGY',' HIGH-TECH',' HIGH TECHNOLOGY']
|
317
|
+
|
318
|
+
#去掉逗号和句点
|
319
|
+
name1=original_name.replace(',',' ')
|
320
|
+
name2=name1.replace('.',' ')
|
321
|
+
|
322
|
+
#将字符串中的多个空格变为单个空格
|
323
|
+
name3=replace_multiple_spaces(name2)
|
324
|
+
|
325
|
+
#将字符串字母全部大写
|
326
|
+
name4=name3.upper()
|
327
|
+
|
328
|
+
name5=name4
|
329
|
+
for ss in remove_list:
|
330
|
+
name5=name5.replace(ss,'')
|
331
|
+
|
332
|
+
name6=name5.strip()
|
333
|
+
|
334
|
+
name7=original_name[:len(name6)]
|
335
|
+
|
336
|
+
shorter_name=name7
|
337
|
+
return shorter_name
|
338
|
+
|
339
|
+
|
340
|
+
#==============================================================================
|
341
|
+
if __name__ == '__main__':
|
342
|
+
stock_code='OPN.PL'
|
343
|
+
stock_code='AAPL'
|
344
|
+
stock_code='600519.SS'
|
345
|
+
stock_code='6758.T'
|
346
|
+
stock_code='6758.JP'
|
347
|
+
stock_code='ULVR.L'
|
348
|
+
stock_code='ULVR.UK'
|
349
|
+
|
350
|
+
stock_code='1155.KL'
|
351
|
+
stock_code='MSFT'
|
352
|
+
|
353
|
+
stooq_name1(stock_code)
|
354
|
+
|
355
|
+
|
356
|
+
def stooq_name1(stock_code,add_suffix=True):
|
357
|
+
|
358
|
+
import requests
|
359
|
+
from bs4 import BeautifulSoup
|
360
|
+
|
361
|
+
stock_code1=stock_code.lower()
|
362
|
+
|
363
|
+
#美股:尾部增加.us
|
364
|
+
stock_code_list=stock_code1.split('.')
|
365
|
+
if len(stock_code_list)==1:
|
366
|
+
stock_code1=stock_code1+'.us'
|
367
|
+
|
368
|
+
#其他国家股票
|
369
|
+
if len(stock_code_list)==2:
|
370
|
+
code=stock_code_list[0]
|
371
|
+
sid=stock_code_list[1]
|
372
|
+
|
373
|
+
#中国股票:尾部变为.cn
|
374
|
+
if sid in ['ss','sz','bj']:
|
375
|
+
stock_code1=code+'.cn'
|
376
|
+
|
377
|
+
#日本股票:尾部变为.jp
|
378
|
+
if sid in ['t']:
|
379
|
+
stock_code1=code+'.jp'
|
380
|
+
|
381
|
+
#英国股票:尾部变为.uk
|
382
|
+
if sid in ['l']:
|
383
|
+
stock_code1=code+'.uk'
|
384
|
+
|
385
|
+
#XX国股票
|
386
|
+
|
387
|
+
#波兰股票:去掉尾部.PL
|
388
|
+
stock_code1=stock_code1.replace('.pl','')
|
389
|
+
|
390
|
+
#抓取证券名称
|
391
|
+
url = f"https://stooq.com/q/?s={stock_code1}"
|
392
|
+
response = requests.get(url)
|
393
|
+
if response.status_code == 200:
|
394
|
+
soup = BeautifulSoup(response.text, 'html.parser')
|
395
|
+
soup_title=soup.title
|
396
|
+
soup_text=soup_title.text
|
397
|
+
soup_text_list=soup_text.split(' - ')
|
398
|
+
|
399
|
+
t_name = soup_text_list[1].strip()
|
400
|
+
else:
|
401
|
+
pass
|
402
|
+
return stock_code
|
403
|
+
|
404
|
+
#未找到证券代码
|
405
|
+
if t_name == 'Stooq':
|
406
|
+
return stock_code
|
407
|
+
|
408
|
+
#过滤名称中多余的尾部词汇
|
409
|
+
t_name=filter_stock_name(t_name)
|
410
|
+
|
411
|
+
#增加交易所后缀
|
412
|
+
if add_suffix:
|
413
|
+
tlist=stock_code1.split('.')
|
414
|
+
if len(tlist)==1: sid='PL'
|
415
|
+
if len(tlist)==2:
|
416
|
+
sid=tlist[1].upper()
|
417
|
+
|
418
|
+
if sid not in ['CN','US']:
|
419
|
+
t_name=t_name+'('+sid+')'
|
420
|
+
|
421
|
+
return t_name
|
422
|
+
|
423
|
+
#==============================================================================
|
424
|
+
if __name__=='__main__':
|
425
|
+
ticker='1155.KL'
|
426
|
+
ticker='MSFT'
|
427
|
+
ticker='G13.SI'
|
428
|
+
ticker='S63.SI'
|
429
|
+
ticker='SUS.ST'
|
430
|
+
ticker='SUN.UK'
|
431
|
+
ticker='IUI1.DE'
|
432
|
+
|
433
|
+
ticker='600519.SS'
|
434
|
+
ticker='U11.SI'
|
435
|
+
ticker='1295.KL'
|
436
|
+
ticker='BMW.DE'
|
437
|
+
ticker='MBG.DE'
|
438
|
+
ticker='005930.KS'
|
439
|
+
ticker='LI'
|
440
|
+
|
441
|
+
get_stock_name1_en(ticker)
|
442
|
+
|
443
|
+
def get_stock_name1_en(ticker,short_name=False,add_suffix=True,maxlen=80):
|
444
|
+
"""
|
445
|
+
功能:分别从stooq和yahoo网站获取证券名称,优先stooq(因为不需要vpn)
|
446
|
+
"""
|
447
|
+
sname=ticker
|
448
|
+
|
449
|
+
try:
|
450
|
+
sname=stooq_name1(ticker,add_suffix=add_suffix)
|
451
|
+
except:
|
452
|
+
pass
|
453
|
+
|
454
|
+
if sname==ticker:
|
455
|
+
try:
|
456
|
+
sname=yahoo_name1(ticker,short_name=short_name,add_suffix=add_suffix,maxlen=maxlen)
|
457
|
+
except:
|
458
|
+
pass
|
459
|
+
|
460
|
+
return sname
|
461
|
+
|
462
|
+
#==============================================================================
|
463
|
+
#==============================================================================
|
464
|
+
#==============================================================================
|
465
|
+
#==============================================================================
|
466
|
+
#==============================================================================
|
467
|
+
#==============================================================================
|
468
|
+
#==============================================================================
|
469
|
+
#==============================================================================
|
@@ -1,6 +1,6 @@
|
|
1
1
|
siat/__init__ -20240701.py,sha256=gP5uajXnJesnH5SL0ZPwq_Qhv59AG1bs4qwZv26Fo2Y,2894
|
2
2
|
siat/__init__.py,sha256=NJn2HSa0cdet21YFoJs5nafHgrM3H3J3wdtFYi1KzfM,2065
|
3
|
-
siat/allin.py,sha256=
|
3
|
+
siat/allin.py,sha256=mGm28SxvGGiNAsg6RleiqgyFQvrpgQZERYqpPkdDzPw,2851
|
4
4
|
siat/alpha_vantage_test.py,sha256=tKr-vmuFH3CZAqwmISz6jzjPHzV1JJl3sPfZdz8aTfM,747
|
5
5
|
siat/assets_liquidity.py,sha256=o_UZdLs693uNWPEQB2OzxDH0mdWimOmq4qe_vx1pue0,28987
|
6
6
|
siat/assets_liquidity_test.py,sha256=UWk6HIUlizU7LQZ890fGx8LwU1jMMrIZswg8cFUJWZ8,1285
|
@@ -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
|
@@ -98,7 +98,7 @@ siat/sector_china.py,sha256=nP6kfYsnaQWZj8dK-zklwSDW8FDS-obZWp_zL0ec2Ig,118603
|
|
98
98
|
siat/sector_china_test.py,sha256=1wq7ef8Bb_L8F0h0W6FvyBrIcBTEbrTV7hljtpj49U4,5843
|
99
99
|
siat/security_price.py,sha256=2oHskgiw41KMGfqtnA0i2YjNNV6cYgtlUK0j3YeuXWs,29185
|
100
100
|
siat/security_price2.py,sha256=4xvc9AzRhLKJMu6AxVzIqcn1-NrHoeCF2Ao2p9nwYjU,25978
|
101
|
-
siat/security_prices.py,sha256=
|
101
|
+
siat/security_prices.py,sha256=9T4RVZNDlxAGursIb4hZqGeekjYgjBgo3uALhzhWWLw,106181
|
102
102
|
siat/security_prices_test.py,sha256=OEphoJ87NPKoNow1QA8EU_5MUYrJF-qKoWKNapVfZNI,10779
|
103
103
|
siat/security_trend.py,sha256=o0vpWdrJkmODCP94X-Bvn-w7efHhj9HpUYBHtLl55D0,17240
|
104
104
|
siat/security_trend2-20240620.py,sha256=QVnEcb7AyVbO77jVqfFsJffGXrX8pgJ9xCfoAKmWBPk,24854
|
@@ -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=GjuJTXsZKpmAEtljUxs1T-TT-aGZ726zWCAqQM03ElU,217888
|
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.
|
143
|
-
siat-3.
|
144
|
-
siat-3.
|
141
|
+
siat/yf_name.py,sha256=H1EM8YYXA8nQHIqsJlso0I3HKPiJLT3QujO4gRVQXWs,13945
|
142
|
+
siat-3.3.1.dist-info/METADATA,sha256=vdhsH9jtHlGhPaJ_YFcUYY7skJN7j4b663c9NWnTQRg,7309
|
143
|
+
siat-3.3.1.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
|
144
|
+
siat-3.3.1.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
|
145
|
+
siat-3.3.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|