siat 3.7.4__py3-none-any.whl → 3.7.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
siat/common.py CHANGED
@@ -3827,7 +3827,8 @@ if __name__=='__main__':
3827
3827
  def upgrade_siat(module_list=['siat','akshare','pandas','pandas_datareader', \
3828
3828
  'yfinance','yahooquery','urllib3','tabulate','twine', \
3829
3829
  'mplfinance','openpyxl','pip','bottleneck','ipywidgets'], \
3830
- pipcmd="python -m pip install --upgrade --user",alternative=""):
3830
+ pipcmd="python -m pip install --upgrade --user", \
3831
+ mirror="aliyun"):
3831
3832
  """
3832
3833
  功能:一次性升级siat及其相关插件
3833
3834
 
@@ -3839,7 +3840,8 @@ def upgrade_siat(module_list=['siat','akshare','pandas','pandas_datareader', \
3839
3840
  DEBUG=False
3840
3841
 
3841
3842
  print("Upgrading siat and related modules, please wait ... ...")
3842
-
3843
+ alternative=mirror
3844
+
3843
3845
  #获取系统目录
3844
3846
  import sys
3845
3847
  syspath=sys.path
@@ -3930,7 +3932,7 @@ def upgrade_siat(module_list=['siat','akshare','pandas','pandas_datareader', \
3930
3932
  if 'pip' in fail_list:
3931
3933
  print("Upgrading for pip, in Anaconda Prompt (Windows) or Terminal (Mac):")
3932
3934
  print(" python -m pip install --upgrade --user pip")
3933
-
3935
+ print("Please RESTART Python kernel to enforce the upgraded modules!")
3934
3936
  return
3935
3937
 
3936
3938
  def df_index_timezone_remove(df):
@@ -4171,14 +4173,58 @@ def firstLetterUpper(text):
4171
4173
 
4172
4174
  #==============================================================================
4173
4175
  if __name__ == '__main__':
4174
- string = "Hello, Welcome to this New World!"
4176
+ string = "HeLLo, Welcome to this New WorLd!"
4175
4177
  words = ["Hello", "World"]
4176
4178
 
4177
4179
  contains_any(string, words)
4178
4180
 
4179
4181
  def contains_any(string, words):
4180
- # 定义一个函数,检查字符串string是否包含列表words中的任何元素
4181
- return any(word in string for word in words)
4182
+ """
4183
+
4184
+ 功能:测试字符串string中是否含有字符串列表words中的任意一个元素
4185
+ 参数:
4186
+ string:字符串,大小写不限
4187
+ words:字符串列表,大小写不限
4188
+ 注意:为避免大小写字母的影响,比较前需要先将两边的字母全部小写化
4189
+ """
4190
+ #将字符串列表中的元素小写,避免大小写差异导致比较失败
4191
+ if not isinstance(words,list):
4192
+ words_list=[words]
4193
+ else:
4194
+ words_list=words
4195
+ new_words=words_list.copy() #不改变原列表的内容
4196
+
4197
+ new_words_list=[]
4198
+ for w in new_words:
4199
+ if isinstance(w,str):
4200
+ new_words_list=new_words_list+[w.lower()]
4201
+ else: continue #过滤列表中非字符串的元素
4202
+
4203
+ if isinstance(string,str):
4204
+ new_string=string.lower()
4205
+ else:
4206
+ return False
4207
+
4208
+ #检查字符串new_string是否包含列表new_words_list中的任何元素
4209
+ return any((word in new_string) for word in new_words_list)
4210
+
4211
+ #==============================================================================
4212
+ if __name__ == '__main__':
4213
+ s = "Hello, 世界! This is a test string with symbols #$%^&*()."
4214
+
4215
+ cleaned_s = remove_symbols(s)
4216
+
4217
+ def remove_symbols(s):
4218
+ """
4219
+
4220
+ 功能:删除字符串中除字母、数字和汉字外的所有符号
4221
+ """
4222
+ import re
4223
+ # 正则表达式匹配字母、数字和汉字
4224
+ pattern = re.compile(r'[^\w\u4e00-\u9fa5]')
4225
+ # 使用sub()函数将所有不匹配的符号替换为空字符
4226
+ return pattern.sub('', s)
4227
+
4182
4228
 
4183
4229
  #==============================================================================
4184
4230
  if __name__ == '__main__':
@@ -22,6 +22,7 @@ import pandas as pd
22
22
  #本模块使用yahooquery插件
23
23
  #==============================================================================
24
24
  if __name__=='__main__':
25
+ symbol='JD'
25
26
  symbol='INTL'
26
27
  symbol='MSFT'
27
28
  symbol='600519.SS'
@@ -36,7 +37,7 @@ def get_balance_sheet(symbol):
36
37
  """
37
38
  功能:获取雅虎财经上一只股票所有的年度和季度资产负债表
38
39
  """
39
- print(" Searching for balance info of",symbol,"\b, please wait...")
40
+ print(" Searching for balance info of {}, please wait...".format(symbol))
40
41
 
41
42
  result,prefix,suffix=split_prefix_suffix(symbol)
42
43
  if result & (suffix=='HK'):
siat/financials.py CHANGED
@@ -77,7 +77,7 @@ def compare_history(tickers,items, \
77
77
  twinx=False:单纵轴
78
78
  """
79
79
  #检查power的范围是否合理
80
- if not (power in range(0,10)):
80
+ if not (power in range(0,80)):
81
81
  print(" #Error(compare_history): invalid parameter, power =",power)
82
82
  return None
83
83
 
@@ -1157,17 +1157,21 @@ def get_financial_rates(ticker):
1157
1157
  #####以上的指标为时间序列;以下的指标为非时间序列,类似于快照信息
1158
1158
  #==============================================================================
1159
1159
  if __name__=='__main__':
1160
+ symbol='JD'
1160
1161
  symbol='AAPL'
1161
1162
  symbol='BABA'
1162
1163
  symbol='2883.HK'
1163
1164
  symbol='EBAY'
1165
+
1166
+ stock_info(symbol)
1164
1167
 
1165
1168
  def stock_info(symbol):
1166
1169
  """
1167
1170
  功能:返回静态信息
1168
1171
  """
1169
1172
  DEBUG=False
1170
- #print("...Searching for information of",symbol,"\b, please wait...")
1173
+ if DEBUG:
1174
+ print(" DEBUG: in stock_info, symbol={}".format(symbol))
1171
1175
 
1172
1176
  from yahooquery import Ticker
1173
1177
  stock = Ticker(symbol)
@@ -1616,6 +1620,7 @@ if __name__=='__main__':
1616
1620
 
1617
1621
  #==============================================================================
1618
1622
  if __name__=='__main__':
1623
+ ticker='01810.HK'
1619
1624
  ticker='AAPL'
1620
1625
  info_type='fin_rates'
1621
1626
 
@@ -1637,6 +1642,10 @@ def get_stock_profile(ticker,info_type='basic',graph=True):
1637
1642
  print(" Supported info_type:\n",typelist)
1638
1643
  return None
1639
1644
 
1645
+ #改变港股代码,去掉前导的0或8
1646
+ if '.HK' in ticker.upper():
1647
+ ticker=ticker[-7:]
1648
+
1640
1649
  info=stock_info(ticker)
1641
1650
  if not graph: return info
1642
1651
 
siat/financials2.py CHANGED
@@ -21,6 +21,7 @@ from siat.common import *
21
21
  from siat.translate import *
22
22
  from siat.financial_statements import *
23
23
  from siat.financials import *
24
+ from siat.stock import *
24
25
  from siat.grafix import *
25
26
  #==============================================================================
26
27
  import matplotlib.pyplot as plt
@@ -61,8 +62,17 @@ if czxt in ['linux']: #website Jupyter
61
62
  plt.rcParams['axes.unicode_minus'] = False
62
63
  #==============================================================================
63
64
  if __name__=='__main__':
65
+ #测试1
66
+ tickers="JD"
67
+ analysis_type='Balance Sheet'
68
+ fsdates='2023-12-31'
69
+
70
+ font_size='16px'
71
+ business_period='annual'
72
+
73
+
64
74
  tickers=["JD","00700.HK",'BABA','09999.HK']
65
- fsdates='2022-12-31'
75
+ fsdates='2023-12-31'
66
76
 
67
77
  analysis_type='Balance Sheet'
68
78
  analysis_type='Income Statement'
@@ -92,8 +102,10 @@ if __name__=='__main__':
92
102
 
93
103
  def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
94
104
  category='profile',business_period='annual', \
95
- scale1=10,scale2=10,sort='PM',
96
- printout=True,facecolor='papayawhip',font_size='16px'
105
+ scale1=10,scale2=10,dupont_sort='PM',
106
+ printout=True, \
107
+ entry_sort=False, \
108
+ facecolor='papayawhip',font_size='16px'
97
109
  ):
98
110
  """
99
111
  功能:tickers为股票列表,fsdates为财报日期,可为单个日期或日期列表
@@ -130,36 +142,54 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
130
142
 
131
143
  #确定表格字体大小
132
144
  titile_font_size=font_size
133
- heading_font_size=data_font_size=str(int(font_size.replace('px',''))-1)+'px'
145
+ heading_font_size=data_font_size=str(int(font_size.replace('px',''))-3)+'px'
134
146
 
135
147
  # 基于analysis_type1的类型分别处理
136
- if ('profile' in analysis_type1):
148
+ #if ('profile' in analysis_type1):
149
+ if contains_any(analysis_type1,['profile']):
137
150
  # 股票需为单只股票,若为列表则仅取第一个
138
151
  if not isinstance(tickers,str):
139
152
  if isinstance(tickers,list): tickers=tickers[0]
140
153
  else:
141
- print(" #Warning(fs_analysis_china): must be one ticker or first ticker in a list for",tickers)
154
+ print(" #Warning(fs_analysis_china): {} must be one ticker or ticker list".format(tickers))
142
155
  return None
143
156
 
144
157
  # 检查category
145
- category_list=['profile','officers','market_rates','dividend','stock_split','fin_rates','risk_general','risk_esg']
146
- if category not in category_list:
147
- print(" Unsupported category:",category,"\b. Supported categories as follows:")
148
- print_list(category_list,leading_blanks=2)
158
+ #category_list=['profile','officers','market_rates','dividend','split','fin_rates','risk_general','risk_esg']
159
+ category_list=['profile','officers','market rates','dividend','split','financial rates','general risk','esg']
149
160
 
150
- if category == 'profile':
151
- info=get_stock_profile(ticker)
152
- elif category == 'dividend':
153
- info=stock_dividend(ticker,fromdate='1990-1-1',todate=todaydt)
154
- elif category == 'stock_split':
155
- info=stock_split(ticker,fromdate='1990-1-1',todate=todaydt)
161
+ #if category == 'profile':
162
+ if contains_any(category,['profile']):
163
+ info=get_stock_profile(tickers)
164
+ #elif category == 'dividend':
165
+ elif contains_any(category,['dividend']):
166
+ #info=stock_dividend(tickers,start='1990-1-1',end=todaydt)
167
+ info=stock_dividend(tickers)
168
+ #elif category == 'stock_split':
169
+ elif contains_any(category,['split']):
170
+ #info=stock_split(tickers,start='1990-1-1',end=todaydt)
171
+ info=stock_split(tickers)
172
+ elif contains_any(category,['market']):
173
+ category='market_rates'
174
+ info=get_stock_profile(tickers,info_type=category)
175
+ elif contains_any(category,['financial']):
176
+ category='fin_rates'
177
+ info=get_stock_profile(tickers,info_type=category)
178
+
179
+ elif contains_any(category,['risk']):
180
+ category='risk_general'
181
+ info=get_stock_profile(tickers,info_type=category)
182
+ elif contains_any(category,['esg']):
183
+ category='risk_esg'
184
+ info=get_stock_profile(tickers,info_type=category)
156
185
  else:
157
- info=get_stock_profile(ticker,info_type=category)
186
+ print(" Unsupported category {}, supported categories:".format(category))
187
+ print_list(category_list,leading_blanks=2)
158
188
 
159
189
  return info
160
-
161
- elif ('balance' in analysis_type1) or ('sheet' in analysis_type1) \
162
- or ('asset' in analysis_type1) or ('liability' in analysis_type1):
190
+ #elif ('balance' in analysis_type1) or ('sheet' in analysis_type1) or ('asset' in analysis_type1) or ('liability' in analysis_type1):
191
+ #elif contains_any(analysis_type1,['balance','sheet','asset','liability']):
192
+ elif contains_any(analysis_type1,['balance','sheet','asset','liability']):
163
193
  # 股票需为单只股票,若为列表则仅取第一个
164
194
  if not isinstance(tickers,str):
165
195
  if isinstance(tickers,list): tickers=tickers[0]
@@ -261,9 +291,8 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
261
291
 
262
292
  else:
263
293
  return fsdf2
264
-
265
- elif ('income' in analysis_type1) or ('cost' in analysis_type1) \
266
- or ('expense' in analysis_type1) or ('earning' in analysis_type1):
294
+ #elif ('income' in analysis_type1) or ('cost' in analysis_type1) or ('expense' in analysis_type1) or ('earnings' in analysis_type1):
295
+ elif contains_any(analysis_type1,['income','revenue','cost','expense','earnings']):
267
296
  # 股票需为单只股票,若为列表则仅取第一个
268
297
  if not isinstance(tickers,str):
269
298
  if isinstance(tickers,list): tickers=tickers[0]
@@ -342,8 +371,8 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
342
371
  return fsdf6
343
372
 
344
373
  return fsdf2
345
-
346
- elif ('cash' in analysis_type1) or ('flow' in analysis_type1):
374
+ #elif ('cash' in analysis_type1) or ('flow' in analysis_type1):
375
+ elif contains_any(analysis_type1,['cash','flow']):
347
376
  # 股票需为单只股票,若为列表则仅取第一个
348
377
  if not isinstance(tickers,str):
349
378
  if isinstance(tickers,list): tickers=tickers[0]
@@ -421,9 +450,8 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
421
450
  return fsdf6
422
451
 
423
452
  return fsdf2
424
-
425
- elif ('summary' in analysis_type1):
426
-
453
+ #elif ('summary' in analysis_type1):
454
+ elif contains_any(analysis_type1,['summary']):
427
455
  itemlist1=[
428
456
  #资产负债表
429
457
  'CashAndCashEquivalents','AccountsReceivable','Inventory', \
@@ -634,9 +662,8 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
634
662
  return fsdf6
635
663
 
636
664
  return fsdf2
637
-
638
- elif ('indicator' in analysis_type1):
639
-
665
+ #elif ('indicator' in analysis_type1):
666
+ elif contains_any(analysis_type1,['indicator']):
640
667
  itemlist=[
641
668
  #短期偿债能力
642
669
  'Current Ratio','Quick Ratio','Cash Ratio','Cash Flow Ratio', \
@@ -847,8 +874,8 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
847
874
 
848
875
  return fsdf2
849
876
 
850
-
851
- elif ('dupont' in analysis_type1) and (('identity' in analysis_type1) or ('analysis' in analysis_type1)):
877
+ #elif ('dupont' in analysis_type1) and (('identity' in analysis_type1) or ('analysis' in analysis_type1)):
878
+ elif contains_any(analysis_type1,['dupont','identity']):
852
879
  # 股票需为股票列表
853
880
  if not isinstance(tickers,list):
854
881
  print(" #Warning(fs_analysis_china): must be a ticker list for",tickers)
@@ -903,11 +930,11 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
903
930
  name4='Return on Equity'
904
931
  name5='endDate'
905
932
 
906
- if sort=='PM':
933
+ if dupont_sort=='PM':
907
934
  df.sort_values(name1,ascending=False,inplace=True)
908
- elif sort=='TAT':
935
+ elif dupont_sort=='TAT':
909
936
  df.sort_values(name2,ascending=False,inplace=True)
910
- elif sort=='EM':
937
+ elif dupont_sort=='EM':
911
938
  df.sort_values(name3,ascending=False,inplace=True)
912
939
  else:
913
940
  df.sort_values(name1,ascending=False,inplace=True)
siat/financials_china.py CHANGED
@@ -3872,6 +3872,9 @@ def get_fin_indicator_1ticker_china(ticker,fsdates):
3872
3872
 
3873
3873
  import pandas as pd
3874
3874
  # 过滤财报日期
3875
+ if isinstance(fsdates,str):
3876
+ fsdates=[fsdates]
3877
+
3875
3878
  fsdates2=[]
3876
3879
  for d in fsdates:
3877
3880
  d1=pd.to_datetime(d)
@@ -3886,6 +3889,8 @@ def get_fin_indicator_1ticker_china(ticker,fsdates):
3886
3889
  _,t1,_=split_prefix_suffix(ticker)
3887
3890
  try:
3888
3891
  dft=ak.stock_financial_analysis_indicator(t1)
3892
+ dft['日期']=dft['日期'].apply(lambda x: x.strftime("%Y-%m-%d"))
3893
+ dft.sort_values(by=['日期'],ascending=False,inplace=True)
3889
3894
  except:
3890
3895
  print(" #Error(get_fin_summary_1ticker_china): no fin stmts found or info source unavailable for",ticker)
3891
3896
  return None
siat/financials_china2.py CHANGED
@@ -1987,7 +1987,7 @@ def fs_analysis_china(tickers,fsdates=[],analysis_type='balance sheet', \
1987
1987
  基本信息(默认):profile
1988
1988
  股东信息:shareholder
1989
1989
  历史分红:dividend
1990
- 主营业务:business
1990
+ 主营业务:business,目前无法获取数据!
1991
1991
  市场估值:valuation
1992
1992
  财务概况:financial
1993
1993
 
siat/sector_china.py CHANGED
@@ -2909,7 +2909,7 @@ def find_peers_china(industry='',top=20,rank=20,sw_level='2'):
2909
2909
  return tickerlist
2910
2910
  else:
2911
2911
  print(" #Warning(find_peers_china): failed in retrieving component stocks for Shenwan industry",industry)
2912
- print(" Possible solution: upgrade akshare. if still fail, reportto the author of siat for help")
2912
+ print(" Possible solution: upgrade akshare. if still fail, report to the author of siat for help")
2913
2913
  return []
2914
2914
 
2915
2915
  #==============================================================================
siat/stock.py CHANGED
@@ -2620,7 +2620,7 @@ if __name__ =="__main__":
2620
2620
  todate="2022-9-26"
2621
2621
 
2622
2622
 
2623
- def security_dividend(ticker,start="L3Y",end="today",facecolor='whitesmoke',fontcolor='black'):
2623
+ def security_dividend(ticker,start="L5Y",end="today",facecolor='whitesmoke',fontcolor='black'):
2624
2624
  """
2625
2625
  功能:套壳函数stock_dividend
2626
2626
  """
siat/stock_china.py CHANGED
@@ -673,7 +673,7 @@ def price_direction_knn(ticker,df,ndays=1,diff=0.01,min_score=0.9,votes=100,max_
673
673
  decision='='
674
674
  decision_text='FLAT'
675
675
 
676
- if not printout: return decision,today_close,today
676
+ if not printout: return decision,today_close,stoday
677
677
 
678
678
  print(" Model voting for stock price after "+str(ndays)+" trading days: Higher("+str(zhang)+'), Lower('+str(die)+')')
679
679
  print(" "+ticker_name(ticker,'stock')+': previously closed '+str(known_close)+' @ '+str(known_day))
@@ -949,7 +949,7 @@ def price_price_knn(ticker,df,ndays=1,max_neighbours=10,max_RS=20,printout=True)
949
949
  import numpy as np
950
950
  if np.isnan(decision): decision='?'
951
951
 
952
- if not printout: return decision,decision_score,today_close,today
952
+ if not printout: return decision,decision_score,today_close,stoday
953
953
 
954
954
  print(" Model poll for stock price after "+str(ndays)+" trading days:",decision)
955
955
  print(" Last close price: "+ticker_name(ticker,'stock')+', closed '+str(known_close)+', '+str(known_day))
@@ -1128,11 +1128,19 @@ def stock_profile_china(ticker,category='profile', \
1128
1128
  DEBUG=False
1129
1129
 
1130
1130
  #检查是否A股
1131
- _,_,suffix=split_prefix_suffix(ticker)
1131
+ _,prefix,suffix=split_prefix_suffix(ticker)
1132
1132
  if not (suffix.upper() in ['SS','SZ','BJ']):
1133
1133
  print(" #Warning(stock_profile_china): not a stock in China for",ticker)
1134
1134
  return
1135
1135
 
1136
+ if suffix.upper() in ['SS','SH']:
1137
+ sx='SH'
1138
+ elif suffix.upper() in ['SZ']:
1139
+ sx='SZ'
1140
+ else:
1141
+ sx='BJ'
1142
+ sxticker=sx+prefix
1143
+
1136
1144
  categorylist=['profile','business','shareholder','financial','dividend','valuation']
1137
1145
  if not (category in categorylist):
1138
1146
  print(" #Error(stock_detail_china): unsupported category",category)
@@ -1144,7 +1152,7 @@ def stock_profile_china(ticker,category='profile', \
1144
1152
  from datetime import datetime
1145
1153
 
1146
1154
  import datetime as dt
1147
- today=dt.date.today()
1155
+ stoday=str(dt.date.today())
1148
1156
 
1149
1157
  yi=100000000.0
1150
1158
  yiyuan_name='(亿元)'
@@ -1156,6 +1164,7 @@ def stock_profile_china(ticker,category='profile', \
1156
1164
  #确定表格字体大小
1157
1165
  titile_font_size=font_size
1158
1166
  heading_font_size=data_font_size=str(int(font_size.replace('px',''))-1)+'px'
1167
+ heading_font_size_small=data_font_size_small=str(int(font_size.replace('px',''))-3)+'px'
1159
1168
 
1160
1169
  import akshare as ak
1161
1170
  # 个股基本信息======================================================================================
@@ -1248,12 +1257,13 @@ def stock_profile_china(ticker,category='profile', \
1248
1257
  print('\n数据来源:巨潮资讯,',str(today))
1249
1258
  """
1250
1259
  titletxt1=titletxt+":基本信息"
1251
- footnote='数据来源:巨潮资讯,'+str(today)
1260
+ footnote='数据来源:巨潮资讯,'+str(stoday)
1252
1261
  df_display_CSS(df=dftmp15,titletxt=titletxt1,footnote=footnote, \
1253
1262
  facecolor=facecolor,decimals=2,last_col_align='left', \
1254
1263
  titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
1255
1264
  data_font_size=data_font_size)
1256
1265
 
1266
+ print(' ')
1257
1267
  print("*****",titletxt+":业务范围")
1258
1268
  longtext=df6.iloc[0]["主营业务"]
1259
1269
  print_sentence(longtext,mid_symbol=[';','。'])
@@ -1268,20 +1278,20 @@ def stock_profile_china(ticker,category='profile', \
1268
1278
 
1269
1279
  # 主营业务信息查询=============================================================================
1270
1280
  # 主营业务仅在年报/中报中公布,一三季报中无此信息
1281
+ import numpy as np
1271
1282
  if category == 'business':
1272
1283
  try:
1273
- df2=ak.stock_zygc_ym(symbol=ticker1)
1284
+ df2=ak.stock_zygc_em(symbol=sxticker)
1274
1285
  except:
1275
- print(" #Warning(stock_profile_china): business info not found for",ticker)
1286
+ print(" #Warning(stock_profile_china): fetching business info failed for",ticker)
1276
1287
  return
1277
1288
 
1278
- df2['分类']=df2['分类'].apply(lambda x: '***合计' if x=='合计' else x)
1279
-
1289
+ df2['分类类型']=df2['分类类型'].apply(lambda x: '按业务分类' if x in [np.nan,None] else x)
1290
+ df2['报告日期']=df2['报告日期'].apply(lambda x: x.strftime("%Y-%m-%d"))
1280
1291
  # 整理信息
1281
- df2['报告年度']=df2['报告期'].apply(lambda x: x[:4])
1282
- df2['报告类别']=df2['报告期'].apply(lambda x: x[-2:])
1283
- df2['报告月日']=df2['报告类别'].apply(lambda x: '12-31' if x=='年度' else '06-30' if x=='中期' else '12-31')
1284
- df2['报告日期']=df2['报告年度']+'-'+df2['报告月日']
1292
+ df2['报告年度']=df2['报告日期'].apply(lambda x: x[:4])
1293
+ df2['报告月日']=df2['报告日期'].apply(lambda x: x[-5:])
1294
+ df2['报告类别']=df2['报告月日'].apply(lambda x: '年度' if x=='12-31' else '中期' if x=='06-30' else '季度')
1285
1295
 
1286
1296
  if business_period in ['annual','recent']:
1287
1297
  if business_period == 'annual': #最近一期年报
@@ -1290,14 +1300,14 @@ def stock_profile_china(ticker,category='profile', \
1290
1300
  if business_period == 'recent': #最近一期年报/中报
1291
1301
  df2a=df2.copy(deep=True)
1292
1302
 
1293
- period=df2a.head(1)['报告期'][0]
1303
+ period=df2a.head(1)['报告日期'][0]
1294
1304
  else: #具体中报或年报日期
1295
1305
  result,business_period1=check_date2(business_period)
1296
1306
  if result:
1297
1307
  df2a=df2[df2['报告日期']==business_period1].copy(deep=True)
1298
1308
  if len(df2a) > 0:
1299
1309
  df2a.reset_index(drop=True,inplace=True)
1300
- period=df2a.head(1)['报告期'][0]
1310
+ period=df2a.head(1)['报告日期'][0]
1301
1311
  else:
1302
1312
  print(" #Warning(stock_profile_china): invalid business period for",business_period)
1303
1313
  print(" Valid business_period: annual, recent, or an valid mid-term/annual report date, eg 2022-12-31 or 2022-6-30")
@@ -1307,13 +1317,23 @@ def stock_profile_china(ticker,category='profile', \
1307
1317
  print(" Valid business_period: annual, recent, or an valid mid-term/annual report date, eg 2022-12-31 or 2022-6-30")
1308
1318
  return
1309
1319
 
1310
- dftmp=df2[df2['报告期']==period]
1311
-
1312
- cols1=['分类方向','分类','营业收入','营业收入-占主营收入比','营业成本','营业成本-占主营成本比','毛利率']
1313
- cols2=['分类方向','分类','营业收入-同比增长','营业成本-同比增长','毛利率','毛利率-同比增长']
1314
-
1315
- dftmp1=dftmp[cols1]
1316
- titletxt1=ticker_name(ticker,'stock')+':主营业务构成,'+period
1320
+ dftmp=df2[df2['报告日期']==period]
1321
+ cols1=['主营构成','主营收入','收入比例','主营成本','成本比例','主营利润','利润比例','毛利率']
1322
+ #cols2=['分类方向','分类','营业收入-同比增长','营业成本-同比增长','毛利率','毛利率-同比增长']
1323
+
1324
+ for c in cols1:
1325
+ if c in ['主营收入','主营成本','主营利润']:
1326
+ dftmp[c]=dftmp[c].apply(lambda x: round(x/yi,2))
1327
+ if c in ['收入比例','成本比例','利润比例','毛利率']:
1328
+ dftmp[c]=dftmp[c].apply(lambda x: round(x*100,2))
1329
+ dftmp.rename(columns={c:c+'%'},inplace=True)
1330
+
1331
+ cols1p=['主营构成','主营收入','收入比例%','主营成本','成本比例%','主营利润','利润比例%','毛利率%']
1332
+ dftmp1a=dftmp[dftmp['分类类型']=='按业务分类'][cols1p]
1333
+ dftmp1b=dftmp[dftmp['分类类型']=='按地区分类'][cols1p]
1334
+
1335
+ titletxt1a=ticker_name(ticker,'stock')+':主营业务构成,按业务分类,单位:亿元,'+period
1336
+ titletxt1b=ticker_name(ticker,'stock')+':主营业务构成,按地区分类,单位:亿元,'+period
1317
1337
  """
1318
1338
  if prettytab:
1319
1339
  pandas2prettytable(dftmp1,titletxt1,firstColSpecial=True,leftColAlign='l',otherColAlign='c',tabborder=tabborder)
@@ -1323,15 +1343,23 @@ def stock_profile_china(ticker,category='profile', \
1323
1343
  print(dftmp1.to_markdown(tablefmt='Simple',index=False,colalign=['left','left','right','right','right','right','right']))
1324
1344
  print('\n数据来源:益盟-F10,',str(today))
1325
1345
  """
1326
- footnote='数据来源:益盟-F10,'+str(today)
1327
- df_display_CSS(df=dftmp1,titletxt=titletxt1,footnote=footnote, \
1328
- first_col_align='left',second_col_align='left', \
1346
+ footnote=''
1347
+ df_display_CSS(df=dftmp1a,titletxt=titletxt1a,footnote=footnote, \
1348
+ first_col_align='left',second_col_align='right', \
1329
1349
  facecolor=facecolor,decimals=2, \
1330
1350
  titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
1331
1351
  data_font_size=data_font_size)
1332
-
1333
- dftmp2=dftmp[cols2]
1334
- titletxt2=ticker_name(ticker,'stock')+':主营业务增长,'+period
1352
+
1353
+ print('')
1354
+ footnote='数据来源:东方财富,'+str(stoday)
1355
+ df_display_CSS(df=dftmp1b,titletxt=titletxt1b,footnote=footnote, \
1356
+ first_col_align='left',second_col_align='right', \
1357
+ facecolor=facecolor,decimals=2, \
1358
+ titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
1359
+ data_font_size=data_font_size)
1360
+
1361
+ #dftmp2=dftmp[cols2]
1362
+ #titletxt2=ticker_name(ticker,'stock')+':主营业务增长,'+period
1335
1363
  """
1336
1364
  if prettytab:
1337
1365
  pandas2prettytable(dftmp2,titletxt2,firstColSpecial=True,leftColAlign='l',otherColAlign='c',tabborder=tabborder)
@@ -1341,12 +1369,13 @@ def stock_profile_china(ticker,category='profile', \
1341
1369
  print(dftmp2.to_markdown(tablefmt='Simple',index=False,colalign=['left','left','right','right','right','right']))
1342
1370
  print('\n数据来源:益盟-F10,',str(today))
1343
1371
  """
1372
+ """
1344
1373
  df_display_CSS(df=dftmp2,titletxt=titletxt2,footnote=footnote, \
1345
1374
  first_col_align='left',second_col_align='left', \
1346
1375
  facecolor=facecolor,decimals=2, \
1347
1376
  titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
1348
1377
  data_font_size=data_font_size)
1349
-
1378
+ """
1350
1379
  # 历史分红信息查询=============================================================================
1351
1380
  """
1352
1381
  if category == 'dividend':
@@ -1427,7 +1456,7 @@ def stock_profile_china(ticker,category='profile', \
1427
1456
  print(dftmp3.to_markdown(tablefmt='Simple',index=False,colalign=alignlist))
1428
1457
  print('【注】送股/转增:股数/10股,派息:元(税前)/10股,数据来源:新浪财经,',str(today))
1429
1458
  """
1430
- footnote='【注】送股/转增:股数/10股,派息:元(税前)/10股,数据来源:新浪财经,'+str(today)
1459
+ footnote='【注】送股/转增:股数/10股,派息:元(税前)/10股,数据来源:新浪财经,'+str(stoday)
1431
1460
  df_display_CSS(df=dftmp3,titletxt=titletxt,footnote=footnote, \
1432
1461
  facecolor=facecolor,decimals=2, \
1433
1462
  titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
@@ -1465,7 +1494,7 @@ def stock_profile_china(ticker,category='profile', \
1465
1494
  print(dftmp3.to_markdown(tablefmt='Simple',index=False,colalign=alignlist))
1466
1495
  print('【注】配股方案:每10股的配股数,配股价格为元。数据来源:新浪财经,',str(today))
1467
1496
  """
1468
- footnote='【注】配股方案:每10股的配股数,配股价格为元。数据来源:新浪财经,'+str(today)
1497
+ footnote='【注】配股方案:每10股的配股数,配股价格为元。数据来源:新浪财经,'+str(stoday)
1469
1498
  df_display_CSS(df=dftmp3,titletxt=titletxt,footnote=footnote, \
1470
1499
  facecolor=facecolor,decimals=2, \
1471
1500
  titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
@@ -1557,7 +1586,7 @@ def stock_profile_china(ticker,category='profile', \
1557
1586
  print(dftmp1.to_markdown(tablefmt='Simple',index=False,colalign=['center','left','left','right']))
1558
1587
  print('\n数据来源:新浪财经,',str(today))
1559
1588
  """
1560
- footnote='数据来源:新浪财经,'+str(today)
1589
+ footnote='数据来源:新浪财经,'+str(stoday)
1561
1590
  df_display_CSS(df=dftmp1,titletxt=titletxt,footnote=footnote, \
1562
1591
  first_col_align='center',second_col_align='left', \
1563
1592
  facecolor=facecolor,decimals=2, \
@@ -1598,7 +1627,7 @@ def stock_profile_china(ticker,category='profile', \
1598
1627
  titletxt=ticker_name(ticker,'stock')+':估值与市值'
1599
1628
  import datetime as dt
1600
1629
  today=dt.date.today()
1601
- footnote3="数据来源:乐咕乐股,"+str(today)
1630
+ footnote3="数据来源:乐咕乐股,"+str(stoday)
1602
1631
 
1603
1632
  # 计算市盈率的均值,中位数、最大最小值
1604
1633
  #va='pe'; va_name="市盈率"
@@ -1715,7 +1744,11 @@ def stock_profile_china(ticker,category='profile', \
1715
1744
  if any(s in category for s in ['financial','healthy']):
1716
1745
 
1717
1746
  try:
1718
- df7=ak.stock_financial_analysis_indicator(symbol=ticker1)
1747
+ df7=ak.stock_financial_analysis_indicator(symbol=ticker1)
1748
+ #其中的日期为datetime.date object类型
1749
+ df7['日期']=df7['日期'].apply(lambda x: x.strftime("%Y-%m-%d"))
1750
+ #降序排列
1751
+ df7.sort_values(by=['日期'],ascending=False,inplace=True)
1719
1752
  except:
1720
1753
  print(" #Warning(stock_detail_china):financial info not found for",ticker)
1721
1754
  return
@@ -1760,11 +1793,11 @@ def stock_profile_china(ticker,category='profile', \
1760
1793
  print(dftmp1.to_markdown(tablefmt='Simple',index=False,colalign=colalignList))
1761
1794
  print('\n数据来源:新浪财经,',str(today))
1762
1795
  """
1763
- footnote='数据来源:新浪财经,'+str(today)
1796
+ footnote='数据来源:新浪财经,'+str(stoday)
1764
1797
  df_display_CSS(df=dftmp1,titletxt=titletxt,footnote=footnote, \
1765
1798
  facecolor=facecolor,decimals=2, \
1766
- titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
1767
- data_font_size=data_font_size)
1799
+ titile_font_size=titile_font_size,heading_font_size=heading_font_size_small, \
1800
+ data_font_size=data_font_size_small)
1768
1801
 
1769
1802
  """
1770
1803
  加权平均每股收益:
@@ -1818,8 +1851,8 @@ def stock_profile_china(ticker,category='profile', \
1818
1851
  """
1819
1852
  df_display_CSS(df=dftmp1,titletxt=titletxt,footnote=footnote, \
1820
1853
  facecolor=facecolor,decimals=2, \
1821
- titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
1822
- data_font_size=data_font_size)
1854
+ titile_font_size=titile_font_size,heading_font_size=heading_font_size_small, \
1855
+ data_font_size=data_font_size_small)
1823
1856
 
1824
1857
 
1825
1858
  """
@@ -1864,8 +1897,8 @@ def stock_profile_china(ticker,category='profile', \
1864
1897
  """
1865
1898
  df_display_CSS(df=dftmp2,titletxt=titletxt,footnote=footnote, \
1866
1899
  facecolor=facecolor,decimals=2, \
1867
- titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
1868
- data_font_size=data_font_size)
1900
+ titile_font_size=titile_font_size,heading_font_size=heading_font_size_small, \
1901
+ data_font_size=data_font_size_small)
1869
1902
 
1870
1903
 
1871
1904
  """
@@ -1905,8 +1938,8 @@ def stock_profile_china(ticker,category='profile', \
1905
1938
  """
1906
1939
  df_display_CSS(df=dftmp1,titletxt=titletxt,footnote=footnote, \
1907
1940
  facecolor=facecolor,decimals=2, \
1908
- titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
1909
- data_font_size=data_font_size)
1941
+ titile_font_size=titile_font_size,heading_font_size=heading_font_size_small, \
1942
+ data_font_size=data_font_size_small)
1910
1943
 
1911
1944
 
1912
1945
  titletxt=ticker_name(ticker,'stock')+":主要财务信息,资产负债分析"
@@ -1948,8 +1981,8 @@ def stock_profile_china(ticker,category='profile', \
1948
1981
  """
1949
1982
  df_display_CSS(df=dftmp1,titletxt=titletxt,footnote=footnote, \
1950
1983
  facecolor=facecolor,decimals=2, \
1951
- titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
1952
- data_font_size=data_font_size)
1984
+ titile_font_size=titile_font_size,heading_font_size=heading_font_size_small, \
1985
+ data_font_size=data_font_size_small)
1953
1986
 
1954
1987
 
1955
1988
  """
@@ -1995,8 +2028,8 @@ def stock_profile_china(ticker,category='profile', \
1995
2028
  """
1996
2029
  df_display_CSS(df=dftmp1,titletxt=titletxt,footnote=footnote, \
1997
2030
  facecolor=facecolor,decimals=2, \
1998
- titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
1999
- data_font_size=data_font_size)
2031
+ titile_font_size=titile_font_size,heading_font_size=heading_font_size_small, \
2032
+ data_font_size=data_font_size_small)
2000
2033
 
2001
2034
  """
2002
2035
  资产的经营现金流量回报率是经营活动产生的现金流量净额/总资产,是体现企业收现能力的指标之一。
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: siat
3
- Version: 3.7.4
3
+ Version: 3.7.6
4
4
  Summary: Securities Investment Analysis Tools (siat)
5
5
  Home-page: https://pypi.org/project/siat/
6
6
  Author: Prof. WANG Dehong, International Business School, Beijing Foreign Studies University
@@ -18,7 +18,7 @@ siat/capm_beta.py,sha256=cxXdRVBQBllhbfz1LeTJAIWvyRYhW54nhtNUXv4HwS0,29063
18
18
  siat/capm_beta2.py,sha256=-ZYYp1HK7SkfTR3vBKZ0QVC4Q_tbST2O4MGbX_V77J0,32031
19
19
  siat/capm_beta_test.py,sha256=ImR0c5mc4hIl714XmHztdl7qg8v1E2lycKyiqnFj6qs,1745
20
20
  siat/cmat_commons.py,sha256=Nj9Kf0alywaztVoMVeVVL_EZk5jRERJy8R8kBw88_Tg,38116
21
- siat/common.py,sha256=2Y51NN6n4FhkNXDRFnV9xPE2Z7XcjqcqaWtZLRaDmgQ,163283
21
+ siat/common.py,sha256=08Gb287rbVIAFdLilHPg3DJHLCCIhM95rJ-zhuZpudc,164861
22
22
  siat/compare_cross.py,sha256=3iP9TH2h3w27F2ARZc7FjKcErYCzWRc-TPiymOyoVtw,24171
23
23
  siat/compare_cross_test.py,sha256=xra5XYmQGEtfIZL2h-GssdH2hLdFIhG3eoCrkDrL3gY,3473
24
24
  siat/concepts_iwencai.py,sha256=m1YEDtECRT6FqtzlKm91pt2I9d3Z_XoP59BtWdRdu8I,3061
@@ -37,13 +37,13 @@ siat/exchange_bond_china.pickle,sha256=zDqdPrFacQ0nqjP_SuF6Yy87EgijIRsFvFroW7FAY
37
37
  siat/fama_french.py,sha256=aUTC-67t_CEPbLk4u79woW_zfZ7OCP6Fo4z5EdWCSkQ,48051
38
38
  siat/fama_french_test.py,sha256=M4O23lBKsJxhWHRluwCb3l7HSEn3OFTjzGMpehcevRg,4678
39
39
  siat/financial_base.py,sha256=5u298_1OSlgLnDmhXxqvo4WgMM0JKSa_4jBYF-Ilx38,41097
40
- siat/financial_statements.py,sha256=Ek18eKHflxZ01evOIwnfH1KZ_M2g8Vr8SxkL1om-K7U,25391
40
+ siat/financial_statements.py,sha256=xx0SMpFqAMKm6cj8uYeG2RpJE6G-RoJ3NWa33UyaVMk,25414
41
41
  siat/financial_statements_test.py,sha256=FLhx8JD-tVVWSBGux6AMz1jioXX4U4bp9DmgFHYXb_w,716
42
- siat/financials.py,sha256=mbEZSNeHMMFcnPUryQWvdmNlWQvpnOG9eItgS7IVw3k,80458
42
+ siat/financials.py,sha256=6WOWYift3MpKkNBnvnBFASXy9nKKC6DzAr8rg2XyNtw,80646
43
43
  siat/financials2 - 副本.py,sha256=dKlNjIfKeoSy055fQ6E6TUj9HEoO5Ney9grD84J5kfk,14389
44
- siat/financials2.py,sha256=7mnsTncKsgwFu8PP4refh5C5iMIO9P0KOMSF87ZyncY,45736
45
- siat/financials_china.py,sha256=Pgi-CTl7ZT_RxHt70N7wBjMQ_UUAqZFClLh6GpcK0MQ,191709
46
- siat/financials_china2.py,sha256=tUvWZhUORrZ0EuCVVkJifbO-8d_hXUyA73OPmOX1CL0,92862
44
+ siat/financials2.py,sha256=A6gjqbdNVgA0hloglhPlDR82mHjb3rSskD-s0T8LKg0,47289
45
+ siat/financials_china.py,sha256=Y9QHyJKDgVbkb5L1f65BAiNxLIDmasRUN9_ju4Yby_c,191925
46
+ siat/financials_china2.py,sha256=NZzpS1eCaxEClOhh8dvfdn88NhIULqeb9E0GUDUiG4U,92892
47
47
  siat/financials_china2_test.py,sha256=Erz5k4LyOplBBvYls2MypuqHpVNJ3daiLdyeJezNPu0,2722
48
48
  siat/financials_china2_test2.py,sha256=C8CuYTMHN4Mhp-sTu-Bmg0zMXRCaYV6ezGDoYartRYQ,3507
49
49
  siat/financials_china2_test3.py,sha256=UXYSA80DNSPRhHpovc2MA9JkpILWMAQaRatbWCHBNPs,3118
@@ -95,7 +95,7 @@ siat/risk_evaluation.py,sha256=I6B3gty-t--AkDCO0tKF-291YfpnF-IkXcFjqNKCt9I,76286
95
95
  siat/risk_evaluation_test.py,sha256=YEXM96gKzTfwN4U61AS4Rr1tV7KgUvn4rRC6f3iMw9s,3731
96
96
  siat/risk_free_rate.py,sha256=ZMr4cHikPvXvywr54gGqiI3Nvb69am6tq3zj2hwzANE,12384
97
97
  siat/risk_free_rate_test.py,sha256=CpmhUf8aEAEZeNu4gvWP2Mz2dLoIgBX5bI41vfUBEr8,4285
98
- siat/sector_china.py,sha256=MX1pzqvHvmWD9qGAe8lnUoCXSWjwnjBK8HhAbijTirI,150761
98
+ siat/sector_china.py,sha256=Mxx5Zd5qvhLdwutedwoPRoXlAopTsPww4rRhOgpRmb8,150762
99
99
  siat/sector_china_test.py,sha256=1wq7ef8Bb_L8F0h0W6FvyBrIcBTEbrTV7hljtpj49U4,5843
100
100
  siat/security_price.py,sha256=2oHskgiw41KMGfqtnA0i2YjNNV6cYgtlUK0j3YeuXWs,29185
101
101
  siat/security_price2.py,sha256=FkX-EeqS5Gqm2kIKnDqrqSk_nvG3BbL3Eu4eEmw1OEY,26379
@@ -106,10 +106,10 @@ siat/security_trend2-20240620.py,sha256=QVnEcb7AyVbO77jVqfFsJffGXrX8pgJ9xCfoAKmW
106
106
  siat/security_trend2.py,sha256=mamJtFAbXC1orGgMEmp0taPk-yUqWm-jdGf64bjhn2Q,29756
107
107
  siat/setup.py,sha256=up65rQGLmTBkhtaMLowjoQXYmIsnycnm4g1SYmeQS6o,1335
108
108
  siat/shenwan index history test.py,sha256=JCVAzOSEldHalhSFa3pqD8JI_8_djPMQOxpkuYU-Esg,1418
109
- siat/stock.py,sha256=sDYEXGE9XYnzRYzxv1AUJqMqAu6ISZx7skiu82L1Z7Y,158613
109
+ siat/stock.py,sha256=Eq8dVs9CxT1vS1BEsFQ4xCff3aXBucbT5OPW-WidNcA,158613
110
110
  siat/stock_advice_linear.py,sha256=-twT7IGP-NEplkL1WPSACcNJjggRB2j4mlAQCkzOAuo,31655
111
111
  siat/stock_base.py,sha256=uISvbRyOGy8p9QREA96CVydgflBkn5L3OXOGKl8oanc,1312
112
- siat/stock_china.py,sha256=zyUyghIrkkkYWlHRRP7Hoblxzfp-jrck60pTJpwMahg,91553
112
+ siat/stock_china.py,sha256=vm_BslG0gJm4R0-O5bNtENkMMfDP-u1TYKCKzLH9Nkk,93460
113
113
  siat/stock_china_test.py,sha256=eO4HWsSvc6qezl0LndjtL24lViEyrBjH_sx2c2Y2Q2M,1294
114
114
  siat/stock_info.pickle,sha256=XqcFwQrXoBXAzZnE6rnfpI7zETXZS2usqzsx2ff7MEg,1319005
115
115
  siat/stock_info_test.py,sha256=gfG3DbhDACbtD8wnv_R6zhj0t11XaC8NX8uLD9Qv3Fo,6122
@@ -141,8 +141,8 @@ siat/valuation_china.py,sha256=CVp1IwIsF3Om0J29RGkyxZLt4n9Ug-ua_RKhLwL9fUQ,69624
141
141
  siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
142
142
  siat/var_model_validation.py,sha256=R0caWnuZarrRg9939hxh3vJIIpIyPfvelYmzFNZtPbo,14910
143
143
  siat/yf_name.py,sha256=r0Q67cSMMlfebEkI9h9pdGlJCooEq7hw_3M5IUs4cSI,20081
144
- siat-3.7.4.dist-info/LICENSE,sha256=NTEMMROY9_4U1szoKC3N2BLHcDd_o5uTgqdVH8tbApw,1071
145
- siat-3.7.4.dist-info/METADATA,sha256=Z5_tRV4Qco5cFw7n0OY1MUd17AVse6nzSrziWnY9PMI,8009
146
- siat-3.7.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
147
- siat-3.7.4.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
148
- siat-3.7.4.dist-info/RECORD,,
144
+ siat-3.7.6.dist-info/LICENSE,sha256=NTEMMROY9_4U1szoKC3N2BLHcDd_o5uTgqdVH8tbApw,1071
145
+ siat-3.7.6.dist-info/METADATA,sha256=VBhwM1YCtzZwZbd51whrNXU_MA7CNw_-4bi2xzjDo5k,8009
146
+ siat-3.7.6.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
147
+ siat-3.7.6.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
148
+ siat-3.7.6.dist-info/RECORD,,
File without changes
File without changes