siat 3.7.11__py3-none-any.whl → 3.7.20__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 CHANGED
@@ -2,7 +2,7 @@
2
2
  """
3
3
  功能:一次性引入SIAT的所有模块
4
4
  作者:王德宏,北京外国语大学国际商学院
5
- 版权:2021-2024(C) 仅限教学使用,商业使用需要授权
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
- 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
13
+ from siat.allin import *
32
14
 
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
-
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
+ #==============================================================================
@@ -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
- page = requests.get(url)
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
- page = requests.get(url)
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
- 最新修订日期:2020328
7
+ 最新修订日期:2025215
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
- response = requests.get(url)
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
- response = requests.get(url)
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])+'变化趋势:'+ectranslate(scope)
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
- return requests.get(url)
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='%.2f' if abs(y) >= 100 else '%.2f' if abs(y) >= 10 else '%.4f'
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)
@@ -365,7 +367,9 @@ def plot_line(df0,colname,collabel,ylabeltxt,titletxt,footnote,datatag=False, \
365
367
  plt.xlabel(footnote,fontsize=xlabel_txt_size,ha='center')
366
368
  plt.title(titletxt,fontweight='bold',fontsize=title_txt_size)
367
369
 
368
- plt.legend(loc=loc,fontsize=legend_txt_size)
370
+ if haveLegend:
371
+ plt.legend(loc=loc,fontsize=legend_txt_size)
372
+
369
373
  plt.show()
370
374
  plt.close()
371
375
 
@@ -773,7 +777,9 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
773
777
  返回值:无
774
778
  注意:需要日期类型作为df索引
775
779
  """
776
-
780
+ import pandas as pd
781
+ DEBUG=False
782
+
777
783
  #插值平滑
778
784
  try:
779
785
  df01x=df01[[colname1]].astype('float')
@@ -801,6 +807,8 @@ def plot_line2_coaxial2(df01,ticker1,colname1,label1, \
801
807
  ax=plt.gca()
802
808
  date_start=df1.index[0]
803
809
  date_end=df1.index[-1]
810
+ import pandas as pd
811
+
804
812
  if date_range and not date_freq:
805
813
  ax.xaxis.set_major_formatter(mdate.DateFormatter(date_fmt))
806
814
  plt.xticks(pd.date_range(date_start,date_end))
@@ -1237,6 +1245,7 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
1237
1245
  返回值:无
1238
1246
  注意:需要日期类型作为df索引
1239
1247
  """
1248
+ import pandas as pd
1240
1249
  #plt.rcParams['axes.grid']=False
1241
1250
 
1242
1251
  #插值平滑
@@ -1637,7 +1646,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1637
1646
  #y1=round(y+high_low*0.01,2)
1638
1647
  y1=y+high_low*0.01
1639
1648
  #s='%.0f' if y >= 100 else '%.2f'
1640
- s='%.2f' if abs(y) >= 100 else '%.2f' if abs(y) >= 10 else '%.4f'
1649
+ s='%.1f' if abs(y) >= 100 else '%.2f' if abs(y) >= 1 else '%.4f'
1641
1650
  #plt.text(x,y1,s % y,ha='center',va='bottom',color='red')
1642
1651
  plt.text(x,y1,s % y,ha='right',va='bottom',color=last_line_color)
1643
1652
  plt.scatter(x,y, color='red',marker='8',s=70)
@@ -1648,7 +1657,7 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1648
1657
  #y1=round(y-high_low*0.055,2) #标记位置对应y1的底部
1649
1658
  y1=y-high_low*0.050 #标记位置对应y1的底部
1650
1659
  #s='%.0f' if y >= 100 else '%.2f'
1651
- s='%.2f' if abs(y) >= 100 else '%.2f' if abs(y) >= 10 else '%.4f'
1660
+ s='%.1f' if abs(y) >= 100 else '%.2f' if abs(y) >= 1 else '%.4f'
1652
1661
  #plt.text(x,y1,s % y,ha='center',va='bottom',color='seagreen')
1653
1662
  plt.text(x,y1,s % y,ha='right',va='bottom',color=last_line_color)
1654
1663
  plt.scatter(x,y, color='seagreen',marker='8',s=70)
@@ -1847,6 +1856,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1847
1856
 
1848
1857
  band_area='':默认为空,否则为列表,第1个值为带状区域上边沿字段,第2个值为带状区域下边沿字段
1849
1858
  """
1859
+ import pandas as pd
1850
1860
  DEBUG=False
1851
1861
 
1852
1862
  #空值判断
@@ -1952,7 +1962,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1952
1962
  #y1=round(y+high_low*0.01,2)
1953
1963
  y1=y+high_low*0.01
1954
1964
  #s='%.0f' if y >= 100 else '%.2f'
1955
- s='%.2f' if abs(y) >= 100 else '%.2f' if abs(y) >= 10 else '%.4f'
1965
+ s='%.1f' if abs(y) >= 100 else '%.2f' if abs(y) >= 1 else '%.4f'
1956
1966
  #plt.text(x,y1,s % y,ha='center',va='bottom',color='red')
1957
1967
  plt.text(x,y1,s % y,ha='right',va='bottom',color=last_line_color)
1958
1968
  plt.scatter(x,y, color='red',marker='8',s=70)
@@ -1963,7 +1973,7 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1963
1973
  #y1=round(y-high_low*0.055,2) #标记位置对应y1的底部
1964
1974
  y1=y-high_low*0.050 #标记位置对应y1的底部
1965
1975
  #s='%.0f' if y >= 100 else '%.2f'
1966
- s='%.2f' if abs(y) >= 100 else '%.2f' if abs(y) >= 10 else '%.4f'
1976
+ s='%.1f' if abs(y) >= 100 else '%.2f' if abs(y) >= 1 else '%.4f'
1967
1977
  #plt.text(x,y1,s % y,ha='center',va='bottom',color='seagreen')
1968
1978
  plt.text(x,y1,s % y,ha='right',va='bottom',color=last_line_color)
1969
1979
  plt.scatter(x,y, color='seagreen',marker='8',s=70)
@@ -2272,6 +2282,8 @@ def plot_2lines(df01,colname1,label1, \
2272
2282
 
2273
2283
  返回值:无
2274
2284
  """
2285
+ import pandas as pd
2286
+
2275
2287
  #空值判断
2276
2288
  if len(df01) ==0:
2277
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 tentatively unavailable for",indicator)
55
- print(" Possible reason: data source is self-updating.")
56
- print(" Solution: have a breath of fresh air and try later.")
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
- response = requests.get(url)
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="006257"
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='2020-12-1'
1362
- end='2021-1-31'
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/stock_technical.py CHANGED
@@ -4,7 +4,7 @@
4
4
  所属工具包:证券投资分析工具SIAT
5
5
  SIAT:Security Investment Analysis Tool
6
6
  创建日期:2023年1月27日
7
- 最新修订日期:2023年1月27
7
+ 最新修订日期:2025年1月31
8
8
  作者:王德宏 (WANG Dehong, Peter)
9
9
  作者单位:北京外国语大学国际商学院
10
10
  作者邮件:wdehong2000@163.com
@@ -2483,22 +2483,23 @@ if __name__ =="__main__":
2483
2483
  technical='Bollinger'
2484
2484
  indicator='PE'
2485
2485
 
2486
- def security_technical(ticker,start='default',end='default', \
2487
- MA_days=[5,20],EMA_days=[5,20], \
2488
- MACD_fastperiod=12,MACD_slowperiod=26,MACD_signalperiod=9, \
2489
-
2490
- #RSI参数个数必须为3个,否则出错
2491
- RSI_days=[6,12,24],RSI_lines=[20,50,80], \
2492
- KDJ_days=[9,3,3],matypes=[0,0],KDJ_lines=[20,50,80], \
2493
- boll_days=20,boll_years=7, \
2494
- resample_freq='6H',smooth=True,linewidth=1.5, \
2495
- loc1='best',loc2='best', \
2496
- graph=['ALL'],printout=False, \
2497
- date_range=False,date_freq=False,annotate=False, \
2498
- technical=['MACD'],indicator='Close', \
2499
- ticker_type='auto',source='auto', \
2500
- price_line_color='red', \
2501
- facecolor='k'):
2486
+ def security_technical(ticker,technical=['MACD'],indicator='Close', \
2487
+ start='default',end='default', \
2488
+ MA_days=[5,20],EMA_days=[5,20], \
2489
+ MACD_fastperiod=12,MACD_slowperiod=26,MACD_signalperiod=9, \
2490
+
2491
+ #RSI参数个数必须为3个,否则出错
2492
+ RSI_days=[6,12,24],RSI_lines=[20,50,80], \
2493
+ KDJ_days=[9,3,3],matypes=[0,0],KDJ_lines=[20,50,80], \
2494
+ boll_days=20,boll_years=7, \
2495
+
2496
+ resample_freq='6H',smooth=True,linewidth=1.5, \
2497
+ loc1='best',loc2='best', \
2498
+ graph=['ALL'],printout=False, \
2499
+ date_range=False,date_freq=False,annotate=False, \
2500
+ ticker_type='auto',source='auto', \
2501
+ price_line_color='red', \
2502
+ facecolor='k'):
2502
2503
 
2503
2504
  """
2504
2505
  功能:技术分析中的MACD/RSI/KDJ/布林带,支持教学演示,支持参数调节。
@@ -2529,6 +2530,7 @@ def security_technical(ticker,start='default',end='default', \
2529
2530
  if t not in technical_list:
2530
2531
  print(" Warning(security_technical): unsupported technical pattern",t)
2531
2532
  print(" Supported patterns:",technical_list)
2533
+ return None
2532
2534
 
2533
2535
  #检查布林带的指标
2534
2536
  if isinstance(indicator,str):
@@ -2544,6 +2546,7 @@ def security_technical(ticker,start='default',end='default', \
2544
2546
  if t not in indicator_list1:
2545
2547
  print(" Warning(security_technical): unsupported Bollinger indicator",t)
2546
2548
  print(" Supported Bollinger indicator:",indicator_list1)
2549
+ return None
2547
2550
 
2548
2551
  # 检查绘图种类
2549
2552
  if isinstance(graph,str):
siat/stooq.py CHANGED
@@ -37,7 +37,8 @@ class StooqDailyReader(_DailyBaseReader):
37
37
  @property
38
38
  def url(self):
39
39
  """API URL"""
40
- return "https://stooq.com/q/d/l/"
40
+ #return "https://stooq.com/q/d/l/"
41
+ return "https://stooq.com/q/d/?"
41
42
 
42
43
  def _get_params(self, symbol, country="US"):
43
44
  symbol_parts = symbol.split(".")
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(同比)'],['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(季度环比)'],
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(get_industry_valuation_sw_zz): failed to retrieve info for industry",ticker)
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
1
  Metadata-Version: 2.1
2
2
  Name: siat
3
- Version: 3.7.11
3
+ Version: 3.7.20
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
@@ -37,6 +37,8 @@ Requires-Dist: py-trans
37
37
  Requires-Dist: bottleneck
38
38
  Requires-Dist: translate
39
39
  Requires-Dist: translators
40
+ Requires-Dist: nbconvert
41
+ Requires-Dist: playwright
40
42
 
41
43
 
42
44
  # What is siat?
@@ -1,10 +1,11 @@
1
1
  siat/__init__ -20240701.py,sha256=gP5uajXnJesnH5SL0ZPwq_Qhv59AG1bs4qwZv26Fo2Y,2894
2
- siat/__init__.py,sha256=pIo4CV3lNPKIhitmhIh_6aAfZrmzQWGNDcEnvZ7GXoc,3216
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=jSRVPxyYylcgG3fAsuqE-9WH3sDfJ3CdZUcU8VBVdoU,10110
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=crRasPR7t5G1t95hm9JWmIob9d-iYASA4GEW5bKVhWw,173203
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=IjQTzqTkdp19aS0PrD15nU3-tfCJHyzt0oBd5nWvwk8,27449
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=ijMAVA5ydghbQDgNDDdz8fz9NPd2eq90RzpJSRGWz5c,78638
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=5u298_1OSlgLnDmhXxqvo4WgMM0JKSa_4jBYF-Ilx38,41097
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=WH_-a-R-zyKhT4t4NM24gYZWKyvIexN9LfXVQf-1zxA,110166
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=Mxx5Zd5qvhLdwutedwoPRoXlAopTsPww4rRhOgpRmb8,150762
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=FkX-EeqS5Gqm2kIKnDqrqSk_nvG3BbL3Eu4eEmw1OEY,26379
103
- siat/security_prices.py,sha256=cIplEWi6TJEIDI6xANaVf0YrOb1CPqvxULGIShoGa2s,108859
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=AO_ntNoinjXpzzs4eA1iMlsqGFoN1KvgHV6Z_ECVy-M,158658
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
@@ -119,9 +120,9 @@ siat/stock_prices_kneighbors.py,sha256=WfZvo5EyeBsm-T37zDj7Sl9dPSRq5Bx4JxIJ9IUum
119
120
  siat/stock_prices_linear.py,sha256=-OUKRr27L2aStQgJSlJOrJ4gay_G7P-m-7t7cU2Yoqk,13991
120
121
  siat/stock_profile.py,sha256=B3eIwzEmiCqiCaxIlhfdEPsQBoW1PFOe1hkiY3mVF6Y,26038
121
122
  siat/stock_technical-20240620.py,sha256=A4x18mZgYSA8SSiDz4u_O3gd5oVRgbI6JIiBfFY0tVw,116013
122
- siat/stock_technical.py,sha256=urnbFubwsYcl8dEPLM6DfdBmsia4xQ1rvM-71VZTM88,136050
123
+ siat/stock_technical.py,sha256=VX6qSBotTOzXaX1XHyDz3KBYEHlaxcPdBIOacB8T9no,136309
123
124
  siat/stock_test.py,sha256=E9YJAvOw1VEGJSDI4IZuEjl0tGoisOIlN-g9UqA_IZE,19475
124
- siat/stooq.py,sha256=SiRnSUu92pfzIZQ8N4Yo-9VOVSwUSqQE0wqXhF-4y9g,2493
125
+ siat/stooq.py,sha256=R6tHMIpPzWqemvo2PMQGdwDZuVyJ0dE2WoduvWYMEC4,2535
125
126
  siat/temp.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
126
127
  siat/test2_graphviz.py,sha256=05w2YJuIBH0LsJjdA60EFn7rL0vCo-CA6EVJEQOXNE4,16648
127
128
  siat/test_graphviz.py,sha256=CETKpDL8PnysS-PD3fHkeAgagUxjaUl0CsXPiadQySg,16999
@@ -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=TJKbh9vU-ifEN1V9DnyojJ00qcT_fioooTAa8wrml_s,250970
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=XdfTivpr652hRnI6yaB9mpA0JlXFJphJsTqcw2_FnMM,50827
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=r0Q67cSMMlfebEkI9h9pdGlJCooEq7hw_3M5IUs4cSI,20081
145
- siat-3.7.11.dist-info/LICENSE,sha256=NTEMMROY9_4U1szoKC3N2BLHcDd_o5uTgqdVH8tbApw,1071
146
- siat-3.7.11.dist-info/METADATA,sha256=Ji1tVpOKlNrvvumMqw93iIak8lQ5CWZI_V9FZ1Fy94E,8064
147
- siat-3.7.11.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
148
- siat-3.7.11.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
149
- siat-3.7.11.dist-info/RECORD,,
145
+ siat/yf_name.py,sha256=ueaMUifnQ3cE3jc1s84mPDLjT9EOuyx8lnY7AFe_YHQ,21165
146
+ siat-3.7.20.dist-info/LICENSE,sha256=NTEMMROY9_4U1szoKC3N2BLHcDd_o5uTgqdVH8tbApw,1071
147
+ siat-3.7.20.dist-info/METADATA,sha256=wryMCRCTnDgsyFAJt1psDoKeHgipoPKOBtjnPqotZUg,8117
148
+ siat-3.7.20.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
149
+ siat-3.7.20.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
150
+ siat-3.7.20.dist-info/RECORD,,
File without changes
File without changes