siat 3.7.12__py3-none-any.whl → 3.7.21__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/__init__.py +6 -59
- siat/__init__.py.backup_20250214.py +73 -0
- siat/barrons_scraping_test.py +8 -2
- siat/common.py +71 -2
- siat/cryptocurrency.py +13 -4
- siat/economy.py +2 -2
- siat/financial_base.py +4 -1
- siat/grafix.py +17 -7
- siat/sector_china.py +12 -7
- siat/security_price2.py +4 -2
- siat/security_prices.py +6 -2
- siat/stock.py +2 -2
- siat/translate.py +55 -55
- siat/valuation.py +1 -1
- siat/yf_name.py +35 -6
- {siat-3.7.12.dist-info → siat-3.7.21.dist-info}/METADATA +8 -14
- {siat-3.7.12.dist-info → siat-3.7.21.dist-info}/RECORD +20 -19
- {siat-3.7.12.dist-info → siat-3.7.21.dist-info}/WHEEL +1 -1
- {siat-3.7.12.dist-info → siat-3.7.21.dist-info}/LICENSE +0 -0
- {siat-3.7.12.dist-info → siat-3.7.21.dist-info}/top_level.txt +0 -0
siat/__init__.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
"""
|
3
3
|
功能:一次性引入SIAT的所有模块
|
4
4
|
作者:王德宏,北京外国语大学国际商学院
|
5
|
-
版权:2021-
|
5
|
+
版权:2021-2025(C) 仅限教学使用,商业使用需要授权
|
6
6
|
联络:wdehong2000@163.com
|
7
7
|
"""
|
8
8
|
|
@@ -10,64 +10,11 @@
|
|
10
10
|
#屏蔽所有警告性信息
|
11
11
|
import warnings; warnings.filterwarnings('ignore')
|
12
12
|
#==============================================================================
|
13
|
-
|
14
|
-
from siat.allin import *
|
15
|
-
success=True
|
16
|
-
except:
|
17
|
-
print(" #Warning: failed to enable siat!")
|
18
|
-
import sys; version=sys.version
|
19
|
-
version_list=version.split('|')
|
20
|
-
python_version=version_list[0].strip()
|
21
|
-
python_version_list=python_version.split('.')
|
22
|
-
python_version2="{0}.{1}".format(python_version_list[0],python_version_list[1])
|
23
|
-
|
24
|
-
if python_version2 < '3.11':
|
25
|
-
print(" Solution: your Python version is {0}, suggest upgrade to {1} or above".format(python_version2,'3.11'))
|
26
|
-
elif python_version2 < '3.12':
|
27
|
-
print(" Solution: your Python version is {0}, suggest upgrade to {1} or above".format(python_version2,'3.12'))
|
28
|
-
else:
|
29
|
-
print(" Solution: your Python version is {}, suggest upgrade to the newest one".format(python_version2))
|
30
|
-
|
31
|
-
success=False
|
13
|
+
from siat.allin import *
|
32
14
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
InteractiveShell.ast_node_interactivity='all'
|
38
|
-
#==============================================================================
|
39
|
-
# 检查是否存在新版本
|
40
|
-
check_newer_version=False
|
41
|
-
|
42
|
-
try:
|
43
|
-
import pkg_resources
|
44
|
-
current_version=pkg_resources.get_distribution("siat").version
|
45
|
-
current_list=current_version.split('.')
|
46
|
-
print("Successfully enabled siat version",current_version)
|
47
|
-
|
48
|
-
if check_newer_version:
|
49
|
-
import luddite
|
50
|
-
latest_version=luddite.get_version_pypi("siat")
|
51
|
-
latest_list=latest_version.split('.')
|
52
|
-
|
53
|
-
newest=True
|
54
|
-
for i in range(3):
|
55
|
-
#print(i)
|
56
|
-
if int(current_list[i]) < int(latest_list[i]):
|
57
|
-
newest=False
|
58
|
-
|
59
|
-
if not newest:
|
60
|
-
#print("The latest version of siat is",latest_version,'\n')
|
61
|
-
print("There is a newer version of siat",latest_version,'\n')
|
62
|
-
print("*** How to upgrade siat?")
|
63
|
-
print("Upgrade from official website? Command: upgrade_siat()")
|
64
|
-
print("Upgrade from Tsinghua? Command: upgrade_siat(alternative='tsinghua')")
|
65
|
-
print("Upgrade from Alibaba? Command: upgrade_siat(alternative='alibaba')")
|
66
|
-
|
67
|
-
except:
|
68
|
-
print(" #Warning: plugin went unexpected with either {0} or {1}".format("pkg_resources","luddite"))
|
69
|
-
print(" Solution: please re-run. If problem remains, contact the author of siat for help")
|
70
|
-
#pass
|
71
|
-
|
15
|
+
import pkg_resources
|
16
|
+
current_version=pkg_resources.get_distribution("siat").version
|
17
|
+
current_list=current_version.split('.')
|
18
|
+
print("Successfully enabled siat v{}".format(current_version))
|
72
19
|
|
73
20
|
#==============================================================================
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""
|
3
|
+
功能:一次性引入SIAT的所有模块
|
4
|
+
作者:王德宏,北京外国语大学国际商学院
|
5
|
+
版权:2021-2024(C) 仅限教学使用,商业使用需要授权
|
6
|
+
联络:wdehong2000@163.com
|
7
|
+
"""
|
8
|
+
|
9
|
+
#==============================================================================
|
10
|
+
#屏蔽所有警告性信息
|
11
|
+
import warnings; warnings.filterwarnings('ignore')
|
12
|
+
#==============================================================================
|
13
|
+
try:
|
14
|
+
from siat.allin import *
|
15
|
+
success=True
|
16
|
+
except:
|
17
|
+
print(" #Warning: failed to enable siat!")
|
18
|
+
import sys; version=sys.version
|
19
|
+
version_list=version.split('|')
|
20
|
+
python_version=version_list[0].strip()
|
21
|
+
python_version_list=python_version.split('.')
|
22
|
+
python_version2="{0}.{1}".format(python_version_list[0],python_version_list[1])
|
23
|
+
|
24
|
+
if python_version2 < '3.11':
|
25
|
+
print(" Solution: your Python version is {0}, suggest upgrade to {1} or above".format(python_version2,'3.11'))
|
26
|
+
elif python_version2 < '3.12':
|
27
|
+
print(" Solution: your Python version is {0}, suggest upgrade to {1} or above".format(python_version2,'3.12'))
|
28
|
+
else:
|
29
|
+
print(" Solution: your Python version is {}, suggest upgrade to the newest one".format(python_version2))
|
30
|
+
|
31
|
+
success=False
|
32
|
+
|
33
|
+
if success:
|
34
|
+
#==============================================================================
|
35
|
+
#同一命令行多个输出,主要用于Jupyter Notebook
|
36
|
+
from IPython.core.interactiveshell import InteractiveShell
|
37
|
+
InteractiveShell.ast_node_interactivity='all'
|
38
|
+
#==============================================================================
|
39
|
+
# 检查是否存在新版本
|
40
|
+
check_newer_version=False
|
41
|
+
|
42
|
+
try:
|
43
|
+
import pkg_resources
|
44
|
+
current_version=pkg_resources.get_distribution("siat").version
|
45
|
+
current_list=current_version.split('.')
|
46
|
+
print("Successfully enabled siat version",current_version)
|
47
|
+
|
48
|
+
if check_newer_version:
|
49
|
+
import luddite
|
50
|
+
latest_version=luddite.get_version_pypi("siat")
|
51
|
+
latest_list=latest_version.split('.')
|
52
|
+
|
53
|
+
newest=True
|
54
|
+
for i in range(3):
|
55
|
+
#print(i)
|
56
|
+
if int(current_list[i]) < int(latest_list[i]):
|
57
|
+
newest=False
|
58
|
+
|
59
|
+
if not newest:
|
60
|
+
#print("The latest version of siat is",latest_version,'\n')
|
61
|
+
print("There is a newer version of siat",latest_version,'\n')
|
62
|
+
print("*** How to upgrade siat?")
|
63
|
+
print("Upgrade from official website? Command: upgrade_siat()")
|
64
|
+
print("Upgrade from Tsinghua? Command: upgrade_siat(alternative='tsinghua')")
|
65
|
+
print("Upgrade from Alibaba? Command: upgrade_siat(alternative='alibaba')")
|
66
|
+
|
67
|
+
except:
|
68
|
+
print(" #Warning: plugin went unexpected with either {0} or {1}".format("pkg_resources","luddite"))
|
69
|
+
print(" Solution: please re-run. If problem remains, contact the author of siat for help")
|
70
|
+
#pass
|
71
|
+
|
72
|
+
|
73
|
+
#==============================================================================
|
siat/barrons_scraping_test.py
CHANGED
@@ -102,7 +102,10 @@ def query_stock_symbol(self):
|
|
102
102
|
|
103
103
|
# Check for two different Barron's URLs
|
104
104
|
url = 'http://www.barrons.com/quote/stock/us/xnas/%s' % (self.symbol)
|
105
|
-
|
105
|
+
headers = {
|
106
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
107
|
+
}
|
108
|
+
page = requests.get(url,headers=headers)
|
106
109
|
if page.status_code == 404:
|
107
110
|
url = 'http://www.barrons.com/quote/stock/us/xnys/%s?mod=DNH_S' % (self.symbol)
|
108
111
|
|
@@ -159,7 +162,10 @@ def query_stock_symbol(self):
|
|
159
162
|
"""
|
160
163
|
# Check for two different Barron's URLs
|
161
164
|
url = 'http://www.barrons.com/quote/stock/us/xnas/%s' % (self.symbol)
|
162
|
-
|
165
|
+
headers = {
|
166
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
167
|
+
}
|
168
|
+
page = requests.get(url,headers=headers)
|
163
169
|
if page.status_code == 404:
|
164
170
|
url = 'http://www.barrons.com/quote/stock/us/xnys/%s?mod=DNH_S' % (self.symbol)
|
165
171
|
"""
|
siat/common.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
所属工具包:证券投资分析工具SIAT
|
5
5
|
SIAT:Security Investment Analysis Tool
|
6
6
|
创建日期:2019年7月16日
|
7
|
-
最新修订日期:
|
7
|
+
最新修订日期:2025年2月15日
|
8
8
|
作者:王德宏 (WANG Dehong, Peter)
|
9
9
|
作者单位:北京外国语大学国际商学院
|
10
10
|
作者邮件:wdehong2000@163.com
|
@@ -3483,8 +3483,11 @@ def test_website(url):
|
|
3483
3483
|
功能:测试一个网址是否可访问
|
3484
3484
|
"""
|
3485
3485
|
import requests
|
3486
|
+
headers = {
|
3487
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
3488
|
+
}
|
3486
3489
|
try:
|
3487
|
-
response = requests.get(url)
|
3490
|
+
response = requests.get(url,headers=headers)
|
3488
3491
|
if response.status_code == 200:
|
3489
3492
|
#print(f"{url} is accessible.")
|
3490
3493
|
return True
|
@@ -4780,6 +4783,72 @@ def ttest(sample1,sample2):
|
|
4780
4783
|
return round(p_value,4)
|
4781
4784
|
|
4782
4785
|
#==============================================================================
|
4786
|
+
|
4787
|
+
|
4788
|
+
|
4789
|
+
async def convert_jupyter_to_pdf(notebook_path, output_pdf_path, size="A4"):
|
4790
|
+
"""
|
4791
|
+
将 Jupyter Notebook 转换为 PDF 文件
|
4792
|
+
参数:
|
4793
|
+
notebook_path (str): Jupyter Notebook 文件路径(.ipynb 文件)
|
4794
|
+
output_pdf_path (str): 输出的 PDF 文件路径
|
4795
|
+
|
4796
|
+
返回:
|
4797
|
+
None
|
4798
|
+
注意1:pip install playwright之后可能还要执行playwright install
|
4799
|
+
注意2:调用本函数的格式是异步await开头
|
4800
|
+
await convert_notebook_to_pdf(notebook_path, output_pdf_path)
|
4801
|
+
注意3:notebook_path和output_pdf_path中可以带路径
|
4802
|
+
"""
|
4803
|
+
import os
|
4804
|
+
from nbconvert import HTMLExporter
|
4805
|
+
from playwright.async_api import async_playwright
|
4806
|
+
|
4807
|
+
html_file = ""
|
4808
|
+
|
4809
|
+
try:
|
4810
|
+
# 导出 Notebook 为 HTML
|
4811
|
+
html_exporter = HTMLExporter()
|
4812
|
+
try:
|
4813
|
+
html_content, _ = html_exporter.from_filename(notebook_path)
|
4814
|
+
print("Start to convert ipynb file to pdf in {}, ...".format(size))
|
4815
|
+
|
4816
|
+
except:
|
4817
|
+
print("File not found for {}".format(notebook_path))
|
4818
|
+
return
|
4819
|
+
|
4820
|
+
# 创建临时 HTML 文件
|
4821
|
+
html_file = "temp_notebook.html"
|
4822
|
+
with open(html_file, "w", encoding="utf-8") as f:
|
4823
|
+
f.write(html_content)
|
4824
|
+
|
4825
|
+
# 使用 Playwright 打开 HTML 并保存为 PDF
|
4826
|
+
async with async_playwright() as p:
|
4827
|
+
browser = await p.chromium.launch()
|
4828
|
+
page = await browser.new_page()
|
4829
|
+
await page.goto(f"file://{os.path.abspath(html_file)}")
|
4830
|
+
await page.pdf(path=output_pdf_path, format=size)
|
4831
|
+
await browser.close()
|
4832
|
+
|
4833
|
+
print(f"PDF file generated as {output_pdf_path}")
|
4834
|
+
|
4835
|
+
except Exception as e:
|
4836
|
+
print(f"Conversion failed: {e}")
|
4837
|
+
return
|
4838
|
+
|
4839
|
+
finally:
|
4840
|
+
if html_file == "":
|
4841
|
+
return
|
4842
|
+
# 删除临时 HTML 文件
|
4843
|
+
elif os.path.exists(html_file):
|
4844
|
+
os.remove(html_file)
|
4845
|
+
|
4846
|
+
if __name__ == '__main__':
|
4847
|
+
# 定义 Notebook 路径和输出 PDF 路径
|
4848
|
+
notebook_path = r"S:\SIA\机工社版本\脚本测试\证券投资分析-第一章案例Python脚本-检测2.ipynb" # 替换为你的 Notebook 文件路径
|
4849
|
+
output_pdf_path = "E:/output_notebook.pdf" # 替换为你想保存的 PDF 文件路径
|
4850
|
+
#await convert_notebook_to_pdf(notebook_path, output_pdf_path)
|
4851
|
+
|
4783
4852
|
#==============================================================================
|
4784
4853
|
#==============================================================================
|
4785
4854
|
#==============================================================================
|
siat/cryptocurrency.py
CHANGED
@@ -38,8 +38,12 @@ plt.rcParams['axes.unicode_minus'] = False
|
|
38
38
|
#定义爬虫函数:抓取交易所信息
|
39
39
|
def fetchCrypto_Exchange(fsym,tsym,top=5):
|
40
40
|
urlprefix="https://min-api.cryptocompare.com/data/top/exchanges/full?fsym="
|
41
|
-
url = urlprefix + fsym + "&tsym=" + tsym
|
42
|
-
|
41
|
+
url = urlprefix + fsym + "&tsym=" + tsym
|
42
|
+
headers = {
|
43
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
44
|
+
}
|
45
|
+
|
46
|
+
response = requests.get(url,headers=headers)
|
43
47
|
soup = BeautifulSoup(response.content, "html.parser")
|
44
48
|
dic = json.loads(soup.prettify())
|
45
49
|
|
@@ -90,14 +94,19 @@ def fetchCrypto_Price_byExchange(fsym, tsym, exchange):
|
|
90
94
|
|
91
95
|
timestamp_today = datetime.today().timestamp()
|
92
96
|
curr_timestamp = timestamp_today
|
93
|
-
|
97
|
+
|
98
|
+
headers = {
|
99
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
100
|
+
}
|
101
|
+
|
94
102
|
for j in range(2):
|
95
103
|
df = pd.DataFrame(columns=cols)
|
96
104
|
urlprefix="https://min-api.cryptocompare.com/data/histoday?fsym="
|
97
105
|
url = urlprefix + fsym + \
|
98
106
|
"&tsym=" + tsym + "&toTs=" + str(int(curr_timestamp)) + \
|
99
107
|
"&limit=2000" + "&e=" + exchange
|
100
|
-
|
108
|
+
|
109
|
+
response = requests.get(url,headers=headers)
|
101
110
|
soup = BeautifulSoup(response.content, "html.parser")
|
102
111
|
dic = json.loads(soup.prettify())
|
103
112
|
if len(dic['Data']) < 1:
|
siat/economy.py
CHANGED
@@ -216,7 +216,7 @@ def economy_trend(start,end,scope='China',factor='GDP',datatag=False,power=0, \
|
|
216
216
|
|
217
217
|
#绘图
|
218
218
|
ylabeltxt=ectranslate(factor)
|
219
|
-
titletxt=ectranslate(list(ds['name'])[0])+'
|
219
|
+
titletxt=ectranslate(list(ds['name'])[0])+'走势:'+ectranslate(scope)
|
220
220
|
|
221
221
|
import datetime
|
222
222
|
today=datetime.date.today()
|
@@ -453,7 +453,7 @@ def compare_economy(tickers,measures,fromdate,todate,power=0,twinx=False, \
|
|
453
453
|
yline=100 #绘制y=100的水平线
|
454
454
|
|
455
455
|
if lang == 'Chinese':
|
456
|
-
titletxt=ectranslate(list(df1['name'])[0])+'
|
456
|
+
titletxt=ectranslate(list(df1['name'])[0])+'走势对比:'+ \
|
457
457
|
'\n'+ectranslate(ticker1)+' vs '+ectranslate(ticker2)
|
458
458
|
else:
|
459
459
|
titletxt=list(df1['name'])[0]+', Trend Comparison'+ \
|
siat/financial_base.py
CHANGED
@@ -38,7 +38,10 @@ class YahooFin():
|
|
38
38
|
def make_request(self, url):
|
39
39
|
"""Makes a GET request"""
|
40
40
|
import requests
|
41
|
-
|
41
|
+
headers = {
|
42
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
43
|
+
}
|
44
|
+
return requests.get(url,headers=headers)
|
42
45
|
|
43
46
|
def get_data(self):
|
44
47
|
"""Returns a json object from a GET request"""
|
siat/grafix.py
CHANGED
@@ -136,6 +136,7 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
|
|
136
136
|
注意1:需要日期类型作为df索引
|
137
137
|
注意2:date_freq不为False时,必须设置date_range=True,否则无法完成日期设置!
|
138
138
|
"""
|
139
|
+
import pandas as pd
|
139
140
|
|
140
141
|
#空值判断
|
141
142
|
if len(df0) ==0:
|
@@ -214,7 +215,7 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
|
|
214
215
|
#y1=round(y+high_low*0.01,2)
|
215
216
|
y1=y+high_low*0.01
|
216
217
|
#s='%.0f' if y >= 100 else '%.2f'
|
217
|
-
s='%.
|
218
|
+
s='%.1f' if abs(y) >= 100 else '%.2f' if abs(y) >= 1 else '%.4f'
|
218
219
|
plt.text(x,y1,s % y,ha='right',va='bottom',color='red')
|
219
220
|
"""
|
220
221
|
s='%.0f' if y >= 100 else '%.2f'
|
@@ -229,7 +230,8 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
|
|
229
230
|
#y1=round(y-high_low*0.055,2) #标记位置对应y1的底部
|
230
231
|
y1=y-high_low*0.050 #标记位置对应y1的底部
|
231
232
|
#s='%.0f' if y >= 100 else '%.2f'
|
232
|
-
s='%.2f' if abs(y) >= 100 else '%.2f' if abs(y) >= 10 else '%.4f'
|
233
|
+
#s='%.2f' if abs(y) >= 100 else '%.2f' if abs(y) >= 10 else '%.4f'
|
234
|
+
s='%.1f' if abs(y) >= 100 else '%.2f' if abs(y) >= 1 else '%.4f'
|
233
235
|
#plt.text(x,y1,s % y,ha='center',va='bottom',color='seagreen')
|
234
236
|
plt.text(x,y1,s % y,ha='right',va='bottom',color='seagreen')
|
235
237
|
plt.scatter(x,y, color='seagreen',marker='8',s=70)
|
@@ -775,7 +777,9 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
|
|
775
777
|
返回值:无
|
776
778
|
注意:需要日期类型作为df索引
|
777
779
|
"""
|
778
|
-
|
780
|
+
import pandas as pd
|
781
|
+
DEBUG=False
|
782
|
+
|
779
783
|
#插值平滑
|
780
784
|
try:
|
781
785
|
df01x=df01[[colname1]].astype('float')
|
@@ -803,6 +807,8 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
|
|
803
807
|
ax=plt.gca()
|
804
808
|
date_start=df1.index[0]
|
805
809
|
date_end=df1.index[-1]
|
810
|
+
import pandas as pd
|
811
|
+
|
806
812
|
if date_range and not date_freq:
|
807
813
|
ax.xaxis.set_major_formatter(mdate.DateFormatter(date_fmt))
|
808
814
|
plt.xticks(pd.date_range(date_start,date_end))
|
@@ -1239,6 +1245,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
|
|
1239
1245
|
返回值:无
|
1240
1246
|
注意:需要日期类型作为df索引
|
1241
1247
|
"""
|
1248
|
+
import pandas as pd
|
1242
1249
|
#plt.rcParams['axes.grid']=False
|
1243
1250
|
|
1244
1251
|
#插值平滑
|
@@ -1639,7 +1646,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1639
1646
|
#y1=round(y+high_low*0.01,2)
|
1640
1647
|
y1=y+high_low*0.01
|
1641
1648
|
#s='%.0f' if y >= 100 else '%.2f'
|
1642
|
-
s='%.
|
1649
|
+
s='%.1f' if abs(y) >= 100 else '%.2f' if abs(y) >= 1 else '%.4f'
|
1643
1650
|
#plt.text(x,y1,s % y,ha='center',va='bottom',color='red')
|
1644
1651
|
plt.text(x,y1,s % y,ha='right',va='bottom',color=last_line_color)
|
1645
1652
|
plt.scatter(x,y, color='red',marker='8',s=70)
|
@@ -1650,7 +1657,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1650
1657
|
#y1=round(y-high_low*0.055,2) #标记位置对应y1的底部
|
1651
1658
|
y1=y-high_low*0.050 #标记位置对应y1的底部
|
1652
1659
|
#s='%.0f' if y >= 100 else '%.2f'
|
1653
|
-
s='%.
|
1660
|
+
s='%.1f' if abs(y) >= 100 else '%.2f' if abs(y) >= 1 else '%.4f'
|
1654
1661
|
#plt.text(x,y1,s % y,ha='center',va='bottom',color='seagreen')
|
1655
1662
|
plt.text(x,y1,s % y,ha='right',va='bottom',color=last_line_color)
|
1656
1663
|
plt.scatter(x,y, color='seagreen',marker='8',s=70)
|
@@ -1849,6 +1856,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1849
1856
|
|
1850
1857
|
band_area='':默认为空,否则为列表,第1个值为带状区域上边沿字段,第2个值为带状区域下边沿字段
|
1851
1858
|
"""
|
1859
|
+
import pandas as pd
|
1852
1860
|
DEBUG=False
|
1853
1861
|
|
1854
1862
|
#空值判断
|
@@ -1954,7 +1962,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1954
1962
|
#y1=round(y+high_low*0.01,2)
|
1955
1963
|
y1=y+high_low*0.01
|
1956
1964
|
#s='%.0f' if y >= 100 else '%.2f'
|
1957
|
-
s='%.
|
1965
|
+
s='%.1f' if abs(y) >= 100 else '%.2f' if abs(y) >= 1 else '%.4f'
|
1958
1966
|
#plt.text(x,y1,s % y,ha='center',va='bottom',color='red')
|
1959
1967
|
plt.text(x,y1,s % y,ha='right',va='bottom',color=last_line_color)
|
1960
1968
|
plt.scatter(x,y, color='red',marker='8',s=70)
|
@@ -1965,7 +1973,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
|
1965
1973
|
#y1=round(y-high_low*0.055,2) #标记位置对应y1的底部
|
1966
1974
|
y1=y-high_low*0.050 #标记位置对应y1的底部
|
1967
1975
|
#s='%.0f' if y >= 100 else '%.2f'
|
1968
|
-
s='%.
|
1976
|
+
s='%.1f' if abs(y) >= 100 else '%.2f' if abs(y) >= 1 else '%.4f'
|
1969
1977
|
#plt.text(x,y1,s % y,ha='center',va='bottom',color='seagreen')
|
1970
1978
|
plt.text(x,y1,s % y,ha='right',va='bottom',color=last_line_color)
|
1971
1979
|
plt.scatter(x,y, color='seagreen',marker='8',s=70)
|
@@ -2274,6 +2282,8 @@ def plot_2lines(df01,colname1,label1, \
|
|
2274
2282
|
|
2275
2283
|
返回值:无
|
2276
2284
|
"""
|
2285
|
+
import pandas as pd
|
2286
|
+
|
2277
2287
|
#空值判断
|
2278
2288
|
if len(df01) ==0:
|
2279
2289
|
print (" #Warning(plot_2lines): no data to plot df01.")
|
siat/sector_china.py
CHANGED
@@ -38,8 +38,8 @@ def sector_list_china(indicator="新浪行业"):
|
|
38
38
|
#检查选项是否支持
|
39
39
|
indicatorlist=["新浪行业","概念","地域","行业","启明星行业"]
|
40
40
|
if indicator not in indicatorlist:
|
41
|
-
print("#Error(sector_list_china): unsupported sectoring method",indicator)
|
42
|
-
print("Supported sectoring methods:",indicatorlist)
|
41
|
+
print(" #Error(sector_list_china): unsupported sectoring method",indicator)
|
42
|
+
print(" Supported sectoring methods:",indicatorlist)
|
43
43
|
return None
|
44
44
|
|
45
45
|
import akshare as ak
|
@@ -51,9 +51,11 @@ def sector_list_china(indicator="新浪行业"):
|
|
51
51
|
df['label']=df['label'].apply(lambda x: x.strip())
|
52
52
|
|
53
53
|
except:
|
54
|
-
print(" #Error(sector_list_china): data source
|
55
|
-
print(" Possible reason: data source is self-updating.")
|
56
|
-
print("
|
54
|
+
print(" #Error(sector_list_china): data source unavailable for",indicator)
|
55
|
+
print(" Possible reason 1: data source is self-updating now.")
|
56
|
+
print(" Possible reason 2: need to upgrade akshare.")
|
57
|
+
print(" Possible reason 3: data source not reachable under vpn.")
|
58
|
+
|
57
59
|
return None
|
58
60
|
|
59
61
|
sectorlist=list(df['板块'])
|
@@ -592,7 +594,7 @@ def sector_position_sina(ticker,sector="new_dlhy",return_result=False):
|
|
592
594
|
|
593
595
|
def sector_position_china(ticker,sector="new_dlhy"):
|
594
596
|
"""
|
595
|
-
|
597
|
+
功能:查找一只股票在板块内的分位数位置
|
596
598
|
ticker:股票代码
|
597
599
|
sector:板块代码
|
598
600
|
"""
|
@@ -3882,7 +3884,10 @@ def get_stock_industry_sw(ticker):
|
|
3882
3884
|
|
3883
3885
|
ticker6=ticker[:6]
|
3884
3886
|
url=f"https://vip.stock.finance.sina.com.cn/corp/go.php/vCI_CorpOtherInfo/stockid/{ticker6}/menu_num/2.phtml"
|
3885
|
-
|
3887
|
+
headers = {
|
3888
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
3889
|
+
}
|
3890
|
+
response = requests.get(url,headers=headers)
|
3886
3891
|
|
3887
3892
|
if response.status_code == 200:
|
3888
3893
|
soup = BeautifulSoup(response.text, 'html.parser')
|
siat/security_price2.py
CHANGED
@@ -42,8 +42,10 @@ if __name__=='__main__':
|
|
42
42
|
|
43
43
|
ticker='AAPL'
|
44
44
|
|
45
|
-
ticker=
|
45
|
+
ticker='GC=F'
|
46
46
|
|
47
|
+
ticker="006257"
|
48
|
+
ticker_type='auto'
|
47
49
|
|
48
50
|
fromdate='2024-5-1'; todate='2024-5-20'
|
49
51
|
|
@@ -164,7 +166,7 @@ def get_price_1ticker(ticker,fromdate,todate, \
|
|
164
166
|
dft=get_price_yf(ticker1,fromdate,todate)
|
165
167
|
found=df_have_data(dft)
|
166
168
|
|
167
|
-
#数据源情形4:yahoo, pandas_datareader,需要访问yahoo
|
169
|
+
#数据源情形4:yahoo, pandas_datareader,需要访问yahoo,似乎不工作了!
|
168
170
|
if found not in ['Found','Empty']:
|
169
171
|
dft=get_prices_yahoo(ticker1,fromdate,todate)
|
170
172
|
found=df_have_data(dft)
|
siat/security_prices.py
CHANGED
@@ -553,6 +553,8 @@ if __name__=='__main__':
|
|
553
553
|
ticker='TRBNCN.M'
|
554
554
|
ticker='RSAYCN.M'
|
555
555
|
|
556
|
+
ticker='GC.F'
|
557
|
+
|
556
558
|
ticker=['AAPL','MSFT']
|
557
559
|
|
558
560
|
start='2023-1-1'
|
@@ -1358,10 +1360,12 @@ def get_price_yf(ticker,start,end,threads=False):
|
|
1358
1360
|
|
1359
1361
|
|
1360
1362
|
if __name__=='__main__':
|
1361
|
-
start='
|
1362
|
-
end='
|
1363
|
+
start='2024-12-1'
|
1364
|
+
end='2025-1-31'
|
1363
1365
|
|
1364
1366
|
ticker='AAPL'
|
1367
|
+
ticker='GC=F'
|
1368
|
+
|
1365
1369
|
ticker=['AAPL','MSFT']
|
1366
1370
|
ticker=['0700.HK','600519.SS']
|
1367
1371
|
ticker=['AAPL','MSFT','0700.HK','600519.SS']
|
siat/stock.py
CHANGED
@@ -571,8 +571,6 @@ def all_calculate(pricedf,ticker1,fromdate,todate,ticker_type='auto'):
|
|
571
571
|
if __name__ =="__main__":
|
572
572
|
# 测试组1
|
573
573
|
ticker='NVDA'
|
574
|
-
fromdate='2023-5-1'
|
575
|
-
todate='2023-6-16'
|
576
574
|
indicator="Exp Ret%"
|
577
575
|
indicator="Annual Ret Volatility%"
|
578
576
|
|
@@ -588,6 +586,7 @@ if __name__ =="__main__":
|
|
588
586
|
todate='2023-9-17'
|
589
587
|
indicator="Close"
|
590
588
|
|
589
|
+
# 公共参数
|
591
590
|
datatag=False
|
592
591
|
power=0
|
593
592
|
graph=True
|
@@ -595,6 +594,7 @@ if __name__ =="__main__":
|
|
595
594
|
zeroline=False
|
596
595
|
average_value=False
|
597
596
|
|
597
|
+
# 其他测试
|
598
598
|
ticker='600519.SS'; indicator='Exp Ret Volatility%'
|
599
599
|
|
600
600
|
ticker='180202.SZ'
|
siat/translate.py
CHANGED
@@ -1474,61 +1474,61 @@ def codetranslate0(code):
|
|
1474
1474
|
# 打开stooq.py中的函数def _get_params(self, symbol, country="US")
|
1475
1475
|
# 在函数列表中加入一项"m"即可避免自动在ticker加上后缀.us的问题
|
1476
1476
|
# 或者使用fix_package()函数自动修正
|
1477
|
-
['CPIYKR.M','韩国CPI(
|
1478
|
-
['CPIYUK.M','英国CPI(
|
1479
|
-
['CPIYJP.M','日本CPI(
|
1480
|
-
['CPIYUS.M','美国CPI(
|
1481
|
-
['CPIYFR.M','法国CPI(
|
1482
|
-
['CPIYMY.M','马来西亚CPI(
|
1483
|
-
['CPIYAU.M','澳大利亚CPI(
|
1484
|
-
['CPIYCA.M','加拿大CPI(
|
1485
|
-
['CPIYBR.M','巴西CPI(
|
1486
|
-
['CPIYNO.M','挪威CPI(
|
1487
|
-
['CPIYIS.M','冰岛CPI(
|
1488
|
-
['CPIYNL.M','荷兰CPI(
|
1489
|
-
['CPIYGR.M','希腊CPI(
|
1490
|
-
['CPIYIE.M','爱尔兰CPI(
|
1491
|
-
['CPIYCZ.M','捷克CPI(
|
1492
|
-
['CPIYRO.M','罗马尼亚CPI(
|
1493
|
-
|
1494
|
-
|
1495
|
-
['PPIYKR.M','韩国PPI(
|
1496
|
-
['PPIYUK.M','英国PPI(
|
1497
|
-
['PPIYJP.M','日本PPI(
|
1498
|
-
['PPIYUS.M','美国PPI(
|
1499
|
-
|
1500
|
-
['GDPYUS.M','美国GDP(
|
1501
|
-
['GDPYCN.M','中国GDP(
|
1502
|
-
['GDPYSG.M','新加坡GDP(
|
1503
|
-
['GDPYDE.M','德国GDP(
|
1504
|
-
['GDPYAU.M','澳大利亚GDP(
|
1505
|
-
['GDPYJP.M','日本GDP(
|
1506
|
-
['GDPYUK.M','英国GDP(
|
1507
|
-
['GDPYMY.M','马来西亚GDP(
|
1508
|
-
['GDPYKR.M','韩国GDP(
|
1509
|
-
['GDPYTR.M','土耳其GDP(
|
1510
|
-
['GDPYNZ.M','新西兰GDP(
|
1511
|
-
['GDPYIN.M','印度GDP(
|
1512
|
-
['GDPYZA.M','南非GDP(
|
1513
|
-
['GDPYMX.M','墨西哥GDP(
|
1514
|
-
['GDPYBR.M','巴西GDP(
|
1515
|
-
['GDPYIE.M','爱尔兰GDP(
|
1516
|
-
['GDPYBE.M','比利时GDP(
|
1517
|
-
['GDPYNL.M','荷兰GDP(
|
1518
|
-
['GDPYPT.M','葡萄牙GDP(
|
1519
|
-
['GDPYES.M','西班牙GDP(
|
1520
|
-
['GDPYGR.M','希腊GDP(
|
1521
|
-
['GDPYIT.M','意大利GDP(
|
1522
|
-
['GDPYSE.M','瑞典GDP(
|
1523
|
-
['GDPYIS.M','冰岛GDP(
|
1524
|
-
['GDPYDK.M','丹麦GDP(
|
1525
|
-
['GDPYPL.M','波兰GDP(
|
1526
|
-
['GDPYCZ.M','捷克GDP(
|
1527
|
-
['GDPYSK.M','斯洛伐克GDP(
|
1528
|
-
['GDPYHU.M','匈牙利GDP(
|
1529
|
-
['GDPYAT.M','奥地利GDP(
|
1530
|
-
['GDPYCH.M','瑞士GDP(
|
1531
|
-
['GDPQFR.M','法国GDP(
|
1477
|
+
['CPIYKR.M','韩国CPI(同比增速%)'],
|
1478
|
+
['CPIYUK.M','英国CPI(同比增速%)'],['CPIYDE.M','德国CPI(同比增速%)'],
|
1479
|
+
['CPIYJP.M','日本CPI(同比增速%)'],['CPIYCN.M','中国CPI(同比增速%)'],
|
1480
|
+
['CPIYUS.M','美国CPI(同比增速%)'],['CPIYPL.M','波兰CPI(同比增速%)'],
|
1481
|
+
['CPIYFR.M','法国CPI(同比增速%)'],['CPIYPH.M','菲律宾CPI(同比增速%)'],
|
1482
|
+
['CPIYMY.M','马来西亚CPI(同比增速%)'],['CPIYSG.M','新加坡CPI(同比增速%)'],
|
1483
|
+
['CPIYAU.M','澳大利亚CPI(同比增速%)'],['CPIYNZ.M','新西兰CPI(同比增速%)'],
|
1484
|
+
['CPIYCA.M','加拿大CPI(同比增速%)'],['CPIYMX.M','墨西哥CPI(同比增速%)'],
|
1485
|
+
['CPIYBR.M','巴西CPI(同比增速%)'],['CPIYSE.M','瑞典CPI(同比增速%)'],
|
1486
|
+
['CPIYNO.M','挪威CPI(同比增速%)'],['CPIYDK.M','丹麦CPI(同比增速%)'],
|
1487
|
+
['CPIYIS.M','冰岛CPI(同比增速%)'],['CPIYCH.M','瑞士CPI(同比增速%)'],
|
1488
|
+
['CPIYNL.M','荷兰CPI(同比增速%)'],['CPIYIT.M','意大利CPI(同比增速%)'],
|
1489
|
+
['CPIYGR.M','希腊CPI(同比增速%)'],['CPIYES.M','西班牙CPI(同比增速%)'],
|
1490
|
+
['CPIYIE.M','爱尔兰CPI(同比增速%)'],['CPIYAT.M','奥地利CPI(同比增速%)'],
|
1491
|
+
['CPIYCZ.M','捷克CPI(同比增速%)'],['CPIYSK.M','斯洛伐克CPI(同比增速%)'],
|
1492
|
+
['CPIYRO.M','罗马尼亚CPI(同比增速%)'],['CPIYHU.M','匈牙利CPI(同比增速%)'],
|
1493
|
+
|
1494
|
+
|
1495
|
+
['PPIYKR.M','韩国PPI(同比增速%)'],['PPIYSK.M','斯洛伐克PPI(同比增速%)'],
|
1496
|
+
['PPIYUK.M','英国PPI(同比增速%)'],['PPIYDE.M','德国PPI(同比增速%)'],
|
1497
|
+
['PPIYJP.M','日本PPI(同比增速%)'],['PPIYCN.M','中国PPI(同比增速%)'],
|
1498
|
+
['PPIYUS.M','美国PPI(同比增速%)'],['PPIYPL.M','波兰PPI(同比增速%)'],
|
1499
|
+
|
1500
|
+
['GDPYUS.M','美国GDP(同比增速%)'],['GDPQUS.M','美国GDP(季度环比增速%)'],
|
1501
|
+
['GDPYCN.M','中国GDP(同比增速%)'],
|
1502
|
+
['GDPYSG.M','新加坡GDP(同比增速%)'],['GDPQSG.M','新加坡GDP(季度环比增速%)'],
|
1503
|
+
['GDPYDE.M','德国GDP(同比增速%)'],['GDPQDE.M','德国GDP(季度环比增速%)'],
|
1504
|
+
['GDPYAU.M','澳大利亚GDP(同比增速%)'],['GDPQAU.M','澳大利亚GDP(季度环比增速%)'],
|
1505
|
+
['GDPYJP.M','日本GDP(同比增速%)'],['GDPQJP.M','日本GDP(季度环比增速%)'],
|
1506
|
+
['GDPYUK.M','英国GDP(同比增速%)'],['GDPQUK.M','英国GDP(季度环比增速%)'],
|
1507
|
+
['GDPYMY.M','马来西亚GDP(同比增速%)'],['GDPQMY.M','马来西亚GDP(季度环比增速%)'],
|
1508
|
+
['GDPYKR.M','韩国GDP(同比增速%)'],['GDPQKR.M','韩国GDP(季度环比增速%)'],
|
1509
|
+
['GDPYTR.M','土耳其GDP(同比增速%)'],['GDPQTR.M','土耳其GDP(季度环比增速%)'],
|
1510
|
+
['GDPYNZ.M','新西兰GDP(同比增速%)'],
|
1511
|
+
['GDPYIN.M','印度GDP(同比增速%)'],
|
1512
|
+
['GDPYZA.M','南非GDP(同比增速%)'],
|
1513
|
+
['GDPYMX.M','墨西哥GDP(同比增速%)'],
|
1514
|
+
['GDPYBR.M','巴西GDP(同比增速%)'],
|
1515
|
+
['GDPYIE.M','爱尔兰GDP(同比增速%)'],
|
1516
|
+
['GDPYBE.M','比利时GDP(同比增速%)'],
|
1517
|
+
['GDPYNL.M','荷兰GDP(同比增速%)'],
|
1518
|
+
['GDPYPT.M','葡萄牙GDP(同比增速%)'],
|
1519
|
+
['GDPYES.M','西班牙GDP(同比增速%)'],
|
1520
|
+
['GDPYGR.M','希腊GDP(同比增速%)'],
|
1521
|
+
['GDPYIT.M','意大利GDP(同比增速%)'],
|
1522
|
+
['GDPYSE.M','瑞典GDP(同比增速%)'],
|
1523
|
+
['GDPYIS.M','冰岛GDP(同比增速%)'],
|
1524
|
+
['GDPYDK.M','丹麦GDP(同比增速%)'],
|
1525
|
+
['GDPYPL.M','波兰GDP(同比增速%)'],
|
1526
|
+
['GDPYCZ.M','捷克GDP(同比增速%)'],
|
1527
|
+
['GDPYSK.M','斯洛伐克GDP(同比增速%)'],
|
1528
|
+
['GDPYHU.M','匈牙利GDP(同比增速%)'],['GDPYRO.M','罗马尼亚GDP(同比增速%)'],
|
1529
|
+
['GDPYAT.M','奥地利GDP(同比增速%)'],
|
1530
|
+
['GDPYCH.M','瑞士GDP(同比增速%)'],
|
1531
|
+
['GDPQFR.M','法国GDP(季度环比增速%)'],
|
1532
1532
|
|
1533
1533
|
['PMMNDE.M','德国PMI(制造业)'],['PMMNUS.M','美国PMI(制造业)'],
|
1534
1534
|
['PMMNEU.M','欧元区PMI(制造业)'],['PMMNFR.M','法国PMI(制造业)'],
|
siat/valuation.py
CHANGED
@@ -396,7 +396,7 @@ def get_index_valuation_funddb(ticker,indicators,start,end):
|
|
396
396
|
with HiddenPrints():
|
397
397
|
dft=ak.index_value_hist_funddb(symbol=iname,indicator=t)
|
398
398
|
except:
|
399
|
-
print(" #Error(
|
399
|
+
print(" #Error(get_index_valuation_funddb): failed to retrieve info for industry",ticker)
|
400
400
|
industry_list=list(ak.index_value_name_funddb()['指数名称'])
|
401
401
|
industry_sw=[]
|
402
402
|
industry_zz=[]
|
siat/yf_name.py
CHANGED
@@ -24,7 +24,7 @@ def test_yahoo_access():
|
|
24
24
|
"""
|
25
25
|
功能:测试雅虎财经是否可达
|
26
26
|
"""
|
27
|
-
url="https://finance.yahoo.com"
|
27
|
+
url="https://finance.yahoo.com/"
|
28
28
|
result=test_website(url)
|
29
29
|
|
30
30
|
return result
|
@@ -35,8 +35,11 @@ if __name__=='__main__':
|
|
35
35
|
|
36
36
|
def test_website(url):
|
37
37
|
import requests
|
38
|
+
headers = {
|
39
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
40
|
+
}
|
38
41
|
try:
|
39
|
-
response = requests.get(url)
|
42
|
+
response = requests.get(url,headers=headers)
|
40
43
|
if response.status_code == 200:
|
41
44
|
#print(f"Website {url} is accessible")
|
42
45
|
return True
|
@@ -366,6 +369,10 @@ def ticker_info1(ticker,info="all",test_access=True,print_title=True):
|
|
366
369
|
|
367
370
|
return
|
368
371
|
|
372
|
+
|
373
|
+
if __name__=='__main__':
|
374
|
+
ticker="SGC=F"
|
375
|
+
yahoo_name1(ticker)
|
369
376
|
|
370
377
|
def yahoo_name1(ticker,short_name=False,add_suffix=True,maxlen=80):
|
371
378
|
"""
|
@@ -436,6 +443,7 @@ if __name__ == '__main__':
|
|
436
443
|
stock_code='MSFT'
|
437
444
|
|
438
445
|
stock_code='SWMCX'
|
446
|
+
stock_code='SGC=F'
|
439
447
|
|
440
448
|
yahoo_name1_direct(stock_code)
|
441
449
|
|
@@ -450,9 +458,12 @@ def yahoo_name1_direct(stock_code,add_suffix=True):
|
|
450
458
|
stock_code1=stock_code.upper()
|
451
459
|
|
452
460
|
#抓取证券名称
|
461
|
+
headers = {
|
462
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
463
|
+
}
|
453
464
|
# https://finance.yahoo.com/quote/SWMCX/
|
454
465
|
url = f"https://finance.yahoo.com/quote/{stock_code1}/"
|
455
|
-
response = requests.get(url)
|
466
|
+
response = requests.get(url,headers=headers)
|
456
467
|
if response.status_code == 200:
|
457
468
|
soup = BeautifulSoup(response.text, 'html.parser')
|
458
469
|
soup_title=soup.title
|
@@ -476,6 +487,8 @@ if __name__=='__main__':
|
|
476
487
|
original_name='Apple Inc'
|
477
488
|
original_name='Schwab US Mid-Cap Index'
|
478
489
|
|
490
|
+
original_name='Shanghai Gold (CNH) Futures,Apr'
|
491
|
+
|
479
492
|
filter_stock_name(original_name)
|
480
493
|
|
481
494
|
def filter_stock_name(original_name):
|
@@ -493,7 +506,12 @@ def filter_stock_name(original_name):
|
|
493
506
|
' CORP LTD',' CORP',' AB', \
|
494
507
|
' GROUP CO','(GROUP)',' GROUP', \
|
495
508
|
' PL S A',' PL SA',' AG', \
|
496
|
-
' SCIENCE & TECHNOLOGY',' HIGH-TECH',' HIGH TECHNOLOGY'
|
509
|
+
' SCIENCE & TECHNOLOGY',' HIGH-TECH',' HIGH TECHNOLOGY', \
|
510
|
+
|
511
|
+
' APR',
|
512
|
+
|
513
|
+
|
514
|
+
]
|
497
515
|
|
498
516
|
#去掉逗号和句点
|
499
517
|
name1=original_name.replace(',',' ')
|
@@ -510,6 +528,7 @@ def filter_stock_name(original_name):
|
|
510
528
|
name6=name5.strip()
|
511
529
|
|
512
530
|
name7=original_name[:len(name6)+1]
|
531
|
+
name7=name7.replace(',','').replace('.','')
|
513
532
|
|
514
533
|
shorter_name=name7
|
515
534
|
return shorter_name
|
@@ -528,6 +547,8 @@ if __name__ == '__main__':
|
|
528
547
|
stock_code='1155.KL'
|
529
548
|
stock_code='MSFT'
|
530
549
|
|
550
|
+
stock_code='GC.F'
|
551
|
+
|
531
552
|
stooq_name1(stock_code)
|
532
553
|
|
533
554
|
|
@@ -566,8 +587,11 @@ def stooq_name1(stock_code,add_suffix=True):
|
|
566
587
|
stock_code1=stock_code1.replace('.pl','')
|
567
588
|
|
568
589
|
#抓取证券名称
|
590
|
+
headers = {
|
591
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
592
|
+
}
|
569
593
|
url = f"https://stooq.com/q/?s={stock_code1}"
|
570
|
-
response = requests.get(url)
|
594
|
+
response = requests.get(url,headers=headers)
|
571
595
|
if response.status_code == 200:
|
572
596
|
soup = BeautifulSoup(response.text, 'html.parser')
|
573
597
|
soup_title=soup.title
|
@@ -618,6 +642,8 @@ if __name__=='__main__':
|
|
618
642
|
ticker='ULVR.L'
|
619
643
|
ticker='KSL.AX'
|
620
644
|
|
645
|
+
ticker='SGC=F'
|
646
|
+
|
621
647
|
ticker='IBM'
|
622
648
|
|
623
649
|
get_stock_name1_en(ticker)
|
@@ -660,8 +686,11 @@ def get_stock_name_china_sina(ticker):
|
|
660
686
|
from bs4 import BeautifulSoup
|
661
687
|
|
662
688
|
ticker6=ticker[:6]
|
689
|
+
headers = {
|
690
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
691
|
+
}
|
663
692
|
url=f"https://vip.stock.finance.sina.com.cn/corp/go.php/vCI_CorpOtherInfo/stockid/{ticker6}/menu_num/2.phtml"
|
664
|
-
response = requests.get(url)
|
693
|
+
response = requests.get(url,headers=headers)
|
665
694
|
|
666
695
|
if response.status_code == 200:
|
667
696
|
soup = BeautifulSoup(response.text, 'html.parser')
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.1
|
2
2
|
Name: siat
|
3
|
-
Version: 3.7.
|
3
|
+
Version: 3.7.21
|
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
|
@@ -8,15 +8,15 @@ Author-email: wdehong2000@163.com
|
|
8
8
|
License: Copyright (C) WANG Dehong, 2024. For educational purpose only!
|
9
9
|
Description-Content-Type: text/markdown
|
10
10
|
License-File: LICENSE
|
11
|
-
Requires-Dist:
|
11
|
+
Requires-Dist: pandas-datareader
|
12
12
|
Requires-Dist: yfinance
|
13
13
|
Requires-Dist: tqdm
|
14
|
-
Requires-Dist:
|
14
|
+
Requires-Dist: plotly-express
|
15
15
|
Requires-Dist: akshare
|
16
16
|
Requires-Dist: urllib3
|
17
17
|
Requires-Dist: mplfinance
|
18
18
|
Requires-Dist: statsmodels
|
19
|
-
Requires-Dist:
|
19
|
+
Requires-Dist: yahoo-earnings-calendar
|
20
20
|
Requires-Dist: yahooquery
|
21
21
|
Requires-Dist: pypinyin
|
22
22
|
Requires-Dist: seaborn
|
@@ -33,18 +33,12 @@ Requires-Dist: graphviz
|
|
33
33
|
Requires-Dist: luddite
|
34
34
|
Requires-Dist: pendulum
|
35
35
|
Requires-Dist: itables
|
36
|
-
Requires-Dist:
|
36
|
+
Requires-Dist: py-trans
|
37
37
|
Requires-Dist: bottleneck
|
38
38
|
Requires-Dist: translate
|
39
39
|
Requires-Dist: translators
|
40
|
-
|
41
|
-
|
42
|
-
Dynamic: description
|
43
|
-
Dynamic: description-content-type
|
44
|
-
Dynamic: home-page
|
45
|
-
Dynamic: license
|
46
|
-
Dynamic: requires-dist
|
47
|
-
Dynamic: summary
|
40
|
+
Requires-Dist: nbconvert
|
41
|
+
Requires-Dist: playwright
|
48
42
|
|
49
43
|
|
50
44
|
# What is siat?
|
@@ -1,10 +1,11 @@
|
|
1
1
|
siat/__init__ -20240701.py,sha256=gP5uajXnJesnH5SL0ZPwq_Qhv59AG1bs4qwZv26Fo2Y,2894
|
2
|
-
siat/__init__.py,sha256=
|
2
|
+
siat/__init__.py,sha256=GalodR1ABKiirPw_VNH_jX1ZxapuiNkFBMTOQhoFBxw,786
|
3
|
+
siat/__init__.py.backup_20250214.py,sha256=pIo4CV3lNPKIhitmhIh_6aAfZrmzQWGNDcEnvZ7GXoc,3216
|
3
4
|
siat/allin.py,sha256=x1QC29PUBUYiA6IAbQKbRvtxIEUOBx8dy5k7zh1ABT4,2970
|
4
5
|
siat/alpha_vantage_test.py,sha256=tKr-vmuFH3CZAqwmISz6jzjPHzV1JJl3sPfZdz8aTfM,747
|
5
6
|
siat/assets_liquidity.py,sha256=o_UZdLs693uNWPEQB2OzxDH0mdWimOmq4qe_vx1pue0,28987
|
6
7
|
siat/assets_liquidity_test.py,sha256=UWk6HIUlizU7LQZ890fGx8LwU1jMMrIZswg8cFUJWZ8,1285
|
7
|
-
siat/barrons_scraping_test.py,sha256=
|
8
|
+
siat/barrons_scraping_test.py,sha256=v5IioDB7CselbpjOX68fNPQYgm2UH4SKnz_q_MA4qGY,10464
|
8
9
|
siat/beta_adjustment.py,sha256=viJJE9O82SbA_VYuJtrs3HT0OWYhk4yvmoywskrAhaI,37287
|
9
10
|
siat/beta_adjustment_china.py,sha256=QAVhTQxfV7NSakNPMfQtGMeRzEHVBC8JZQTqD5Owp2I,20802
|
10
11
|
siat/beta_adjustment_test.py,sha256=nBhvQQfqxooCHjy5hL0a8V0ZC58BjuCZVFpqpWpHeF0,2467
|
@@ -18,17 +19,17 @@ siat/capm_beta.py,sha256=cxXdRVBQBllhbfz1LeTJAIWvyRYhW54nhtNUXv4HwS0,29063
|
|
18
19
|
siat/capm_beta2.py,sha256=-ZYYp1HK7SkfTR3vBKZ0QVC4Q_tbST2O4MGbX_V77J0,32031
|
19
20
|
siat/capm_beta_test.py,sha256=ImR0c5mc4hIl714XmHztdl7qg8v1E2lycKyiqnFj6qs,1745
|
20
21
|
siat/cmat_commons.py,sha256=Nj9Kf0alywaztVoMVeVVL_EZk5jRERJy8R8kBw88_Tg,38116
|
21
|
-
siat/common.py,sha256=
|
22
|
+
siat/common.py,sha256=Fk794V57LTXPcQfEFc579u56Lq9ffhJhKGaG7ANhcws,175777
|
22
23
|
siat/compare_cross.py,sha256=3iP9TH2h3w27F2ARZc7FjKcErYCzWRc-TPiymOyoVtw,24171
|
23
24
|
siat/compare_cross_test.py,sha256=xra5XYmQGEtfIZL2h-GssdH2hLdFIhG3eoCrkDrL3gY,3473
|
24
25
|
siat/concepts_iwencai.py,sha256=m1YEDtECRT6FqtzlKm91pt2I9d3Z_XoP59BtWdRdu8I,3061
|
25
26
|
siat/concepts_kpl.py,sha256=SJ9UaJp5i79EXKZ3dPa_vBEoG_zgl1Ig5rZAm-ubgM4,4941
|
26
27
|
siat/copyrights.py,sha256=YMLjZb328YpFMR-s_GUu0HBgeGce3pV7DgRut8S3I7w,690
|
27
|
-
siat/cryptocurrency.py,sha256=
|
28
|
+
siat/cryptocurrency.py,sha256=ImkP0Z3QsKNrHrA07mZM46RvGAWb36AD14cNaiv_pCg,27829
|
28
29
|
siat/cryptocurrency_test.py,sha256=3AikTNJ7j-HwLGLIYEfyXZ3bLVuLeru9mwiwHQi2SdA,2669
|
29
30
|
siat/derivative.py,sha256=qV8n09799eqLc26ojR6vN5n_X-xd7rGwdYjgq-wBih8,41483
|
30
31
|
siat/economy-20230125.py,sha256=vxZZlPnLkh7SpGMVEPLwxjt0yYLSVmdZrO-s2NYLyoM,73848
|
31
|
-
siat/economy.py,sha256=
|
32
|
+
siat/economy.py,sha256=8mo6J5c73CD0hF2LmX89LaYeePwTjZgJ1CrNw13AIUA,78632
|
32
33
|
siat/economy_test.py,sha256=6vjNlPz7W125pJb7simCddobSEp3jmLIMvVkLRZ7zW8,13339
|
33
34
|
siat/esg.py,sha256=GMhaonIKtvOK83rhpQUH5aJt2OL3HQBSVfD__Yw-0oo,19040
|
34
35
|
siat/esg_test.py,sha256=Z9m6GUt8O7oHZSEG9aDYpGdvvrv2AiRJdHTiU6jqmZ0,2944
|
@@ -37,7 +38,7 @@ siat/exchange_bond_china.pickle,sha256=zDqdPrFacQ0nqjP_SuF6Yy87EgijIRsFvFroW7FAY
|
|
37
38
|
siat/fama_french.py,sha256=aUTC-67t_CEPbLk4u79woW_zfZ7OCP6Fo4z5EdWCSkQ,48051
|
38
39
|
siat/fama_french_test.py,sha256=M4O23lBKsJxhWHRluwCb3l7HSEn3OFTjzGMpehcevRg,4678
|
39
40
|
siat/fin_stmt2_yahoo.py,sha256=LGmspk0nKyz4X87MtcovZXUfMQkAvrWINuxR4HQ8PI8,41178
|
40
|
-
siat/financial_base.py,sha256=
|
41
|
+
siat/financial_base.py,sha256=A1rV7XQOVFpCXCV-T6Ge0QeF897hINiu0olN1XWeaFk,41287
|
41
42
|
siat/financial_statements.py,sha256=xx0SMpFqAMKm6cj8uYeG2RpJE6G-RoJ3NWa33UyaVMk,25414
|
42
43
|
siat/financial_statements_test.py,sha256=FLhx8JD-tVVWSBGux6AMz1jioXX4U4bp9DmgFHYXb_w,716
|
43
44
|
siat/financials.py,sha256=6WOWYift3MpKkNBnvnBFASXy9nKKC6DzAr8rg2XyNtw,80646
|
@@ -62,7 +63,7 @@ siat/future_china.py,sha256=F-HsIf2Op8Z22RzTjet1g8COzldgnMjFNSXsAkeGyWo,17595
|
|
62
63
|
siat/future_china_test.py,sha256=BrSzmDVaOHki6rntOtosmRn-6dkfOBuLulJNqh7MOpc,1163
|
63
64
|
siat/global_index_test.py,sha256=hnFp3wqqzzL-kAP8mgxDZ54Bd5Ijf6ENi5YJlGBgcXw,2402
|
64
65
|
siat/google_authenticator.py,sha256=ZUbZR8OW0IAKDbcYtlqGqIpZdERpFor9NccFELxg9yI,1637
|
65
|
-
siat/grafix.py,sha256=
|
66
|
+
siat/grafix.py,sha256=OJ7FYYvnd9V3zvycg_BKF65InLnUhGwdVdkJciD_8pk,110461
|
66
67
|
siat/grafix_test.py,sha256=kXvcpLgQNO7wd30g_bWljLj5UH7bIVI0_dUtXbfiKR0,3150
|
67
68
|
siat/holding_risk.py,sha256=G3wpaewAKF9CwEqRpr4khyuDu9SU2EGyQUHdk7cmHOA,30693
|
68
69
|
siat/holding_risk_test.py,sha256=FRlw_9wFG98BYcg_cSj95HX5WZ1TvkGaOUdXD7-V86s,474
|
@@ -96,18 +97,18 @@ siat/risk_evaluation.py,sha256=I6B3gty-t--AkDCO0tKF-291YfpnF-IkXcFjqNKCt9I,76286
|
|
96
97
|
siat/risk_evaluation_test.py,sha256=YEXM96gKzTfwN4U61AS4Rr1tV7KgUvn4rRC6f3iMw9s,3731
|
97
98
|
siat/risk_free_rate.py,sha256=IBuRqA2kppdZsW4D4fapW7vnM5HMEXOn95A5r9Pkwlo,12384
|
98
99
|
siat/risk_free_rate_test.py,sha256=CpmhUf8aEAEZeNu4gvWP2Mz2dLoIgBX5bI41vfUBEr8,4285
|
99
|
-
siat/sector_china.py,sha256=
|
100
|
+
siat/sector_china.py,sha256=QShFSaJMOydLKL-eCbUy_cWFnXnbdZW90lCUAp6B5lU,151007
|
100
101
|
siat/sector_china_test.py,sha256=1wq7ef8Bb_L8F0h0W6FvyBrIcBTEbrTV7hljtpj49U4,5843
|
101
102
|
siat/security_price.py,sha256=2oHskgiw41KMGfqtnA0i2YjNNV6cYgtlUK0j3YeuXWs,29185
|
102
|
-
siat/security_price2.py,sha256=
|
103
|
-
siat/security_prices.py,sha256=
|
103
|
+
siat/security_price2.py,sha256=LYV478O4vizVNbM6WYlQvaQFq9kjh2ftljhuABGsjkU,26425
|
104
|
+
siat/security_prices.py,sha256=ql1-7TC1w36a_2nKxeR45Cw0cKMl5o7yCl2M9QE3jx8,108909
|
104
105
|
siat/security_prices_test.py,sha256=OEphoJ87NPKoNow1QA8EU_5MUYrJF-qKoWKNapVfZNI,10779
|
105
106
|
siat/security_trend.py,sha256=o0vpWdrJkmODCP94X-Bvn-w7efHhj9HpUYBHtLl55D0,17240
|
106
107
|
siat/security_trend2-20240620.py,sha256=QVnEcb7AyVbO77jVqfFsJffGXrX8pgJ9xCfoAKmWBPk,24854
|
107
108
|
siat/security_trend2.py,sha256=mamJtFAbXC1orGgMEmp0taPk-yUqWm-jdGf64bjhn2Q,29756
|
108
109
|
siat/setup.py,sha256=up65rQGLmTBkhtaMLowjoQXYmIsnycnm4g1SYmeQS6o,1335
|
109
110
|
siat/shenwan index history test.py,sha256=JCVAzOSEldHalhSFa3pqD8JI_8_djPMQOxpkuYU-Esg,1418
|
110
|
-
siat/stock.py,sha256=
|
111
|
+
siat/stock.py,sha256=aelzuy_mPBC0eBknjnRuBVYLZAjMw4ykvKWQXY_4K30,158649
|
111
112
|
siat/stock_advice_linear.py,sha256=-twT7IGP-NEplkL1WPSACcNJjggRB2j4mlAQCkzOAuo,31655
|
112
113
|
siat/stock_base.py,sha256=uISvbRyOGy8p9QREA96CVydgflBkn5L3OXOGKl8oanc,1312
|
113
114
|
siat/stock_china.py,sha256=85Ggb21E2mrCYMdSSTTrkoyyLGXMK2V-BtlweHomSRg,93460
|
@@ -133,17 +134,17 @@ siat/transaction_test.py,sha256=Z8g1LJCN4-mnUByXMUMoFmN0t105cbmsz2QmvSuIkbU,1858
|
|
133
134
|
siat/translate-20230125.py,sha256=NPPSXhT38s5t9fzMvl_fvi4ckSB73ThLmZetVI-xGdU,117953
|
134
135
|
siat/translate-20230206.py,sha256=-vtI125WyaJhmPotOpDAmclt_XnYVaWU9ByLWZ6FyYE,118133
|
135
136
|
siat/translate-20230215.py,sha256=TJgtPE3n8IjljmZ4Pefy8dmHoNdFF-1zpML6BhA9FKE,121657
|
136
|
-
siat/translate.py,sha256=
|
137
|
+
siat/translate.py,sha256=ESiwyQX_eGxdoBlGxFdJpgJfOx9NdSvBww4Ck7d9kto,251537
|
137
138
|
siat/translate_20240606.py,sha256=63IyHWEU3Uz9mjwyuAX3fqY4nUMdwh0ICQAgmgPXP7Y,215121
|
138
139
|
siat/translate_241003_keep.py,sha256=un7Fqe1v35MXsja5exZgjmLzrZtt66NARZIGlyFuGGU,218747
|
139
140
|
siat/universal_test.py,sha256=CDAOffW1Rvs-TcNN5giWVvHMlch1w4dp-w5SIV9jXL0,3936
|
140
|
-
siat/valuation.py,sha256=
|
141
|
+
siat/valuation.py,sha256=tSW5jyda3lChqBkdsbBGfdUeh9bCfjo6P93CjLif9eM,50825
|
141
142
|
siat/valuation_china.py,sha256=CVp1IwIsF3Om0J29RGkyxZLt4n9Ug-ua_RKhLwL9fUQ,69624
|
142
143
|
siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
|
143
144
|
siat/var_model_validation.py,sha256=R0caWnuZarrRg9939hxh3vJIIpIyPfvelYmzFNZtPbo,14910
|
144
|
-
siat/yf_name.py,sha256=
|
145
|
-
siat-3.7.
|
146
|
-
siat-3.7.
|
147
|
-
siat-3.7.
|
148
|
-
siat-3.7.
|
149
|
-
siat-3.7.
|
145
|
+
siat/yf_name.py,sha256=ueaMUifnQ3cE3jc1s84mPDLjT9EOuyx8lnY7AFe_YHQ,21165
|
146
|
+
siat-3.7.21.dist-info/LICENSE,sha256=NTEMMROY9_4U1szoKC3N2BLHcDd_o5uTgqdVH8tbApw,1071
|
147
|
+
siat-3.7.21.dist-info/METADATA,sha256=QX6HIgpLmiCwCAl0mTeY5p4rzwUo4gXXRj2eZ2P-AVs,8117
|
148
|
+
siat-3.7.21.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
149
|
+
siat-3.7.21.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
|
150
|
+
siat-3.7.21.dist-info/RECORD,,
|
File without changes
|
File without changes
|