siat 3.9.22__py3-none-any.whl → 3.10.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- siat/__init__.py +2 -2
- siat/common.py +74 -1
- siat/financial_statements.py +14 -12
- siat/financials.py +1 -1
- siat/financials2.py +186 -21
- siat/other_indexes.py +11 -4
- siat/security_price2.py +7 -2
- siat/security_prices.py +68 -0
- {siat-3.9.22.dist-info → siat-3.10.1.dist-info}/METADATA +1 -1
- {siat-3.9.22.dist-info → siat-3.10.1.dist-info}/RECORD +13 -13
- {siat-3.9.22.dist-info → siat-3.10.1.dist-info}/LICENSE +0 -0
- {siat-3.9.22.dist-info → siat-3.10.1.dist-info}/WHEEL +0 -0
- {siat-3.9.22.dist-info → siat-3.10.1.dist-info}/top_level.txt +0 -0
siat/__init__.py
CHANGED
@@ -40,7 +40,7 @@ if os == 'windows':
|
|
40
40
|
srcfile=srcpath1+'/'+tagfile
|
41
41
|
else:
|
42
42
|
srcpath1=srcpath
|
43
|
-
srcfile=srcpath1+'/'+
|
43
|
+
srcfile=srcpath1+'/'+tagfile
|
44
44
|
|
45
45
|
try:
|
46
46
|
with open(srcfile,'rb') as file:
|
@@ -70,6 +70,6 @@ if not restart:
|
|
70
70
|
else:
|
71
71
|
with HiddenPrints():
|
72
72
|
fix_package()
|
73
|
-
print(" Please RESTART Python kernel and run this command again")
|
73
|
+
print(" Please RESTART Python kernel and then run this command again")
|
74
74
|
|
75
75
|
#==============================================================================
|
siat/common.py
CHANGED
@@ -3501,7 +3501,7 @@ if __name__=='__main__':
|
|
3501
3501
|
|
3502
3502
|
test_website(url)
|
3503
3503
|
|
3504
|
-
def test_website(url):
|
3504
|
+
def test_website(url="https://finance.yahoo.com"):
|
3505
3505
|
"""
|
3506
3506
|
功能:测试一个网址是否可访问
|
3507
3507
|
"""
|
@@ -5000,6 +5000,79 @@ def shift_column_position(df,col_name,position=1):
|
|
5000
5000
|
|
5001
5001
|
return df
|
5002
5002
|
#==============================================================================
|
5003
|
+
if __name__ == '__main__':
|
5004
|
+
text='accountsReceivable'
|
5005
|
+
text='periodType'
|
5006
|
+
text='reportDate'
|
5007
|
+
text='currencyCode'
|
5008
|
+
text='BasicEPS'
|
5009
|
+
text='EBITDA'
|
5010
|
+
text='CashAndCashEquivalents'
|
5011
|
+
text='Debt to Asset'
|
5012
|
+
|
5013
|
+
text_separate(text)
|
5014
|
+
|
5015
|
+
def text_separate(text):
|
5016
|
+
"""
|
5017
|
+
功能:将连写在一起的专业术语拆分成为正常的形式
|
5018
|
+
参数:
|
5019
|
+
text:待拆分短语,例如accountsReceivable
|
5020
|
+
输出:拆分后短语,例如Accounts Receivable
|
5021
|
+
"""
|
5022
|
+
DEBUG=False
|
5023
|
+
|
5024
|
+
if not text:
|
5025
|
+
return ""
|
5026
|
+
|
5027
|
+
articles={"and","from","in","on","the","of","to","for","not","non","as","per"}
|
5028
|
+
|
5029
|
+
words = []
|
5030
|
+
current_word = [text[0].upper()] # 首字母默认大写
|
5031
|
+
for i in range(1, len(text)):
|
5032
|
+
prev_char, curr_char = text[i-1], text[i]
|
5033
|
+
|
5034
|
+
# 分割条件:当前大写且前一个字符为小写,或当前大写后跟小写(保留连续大写)
|
5035
|
+
if (curr_char.isupper() and prev_char.islower()) or \
|
5036
|
+
(curr_char.isupper() and prev_char.isupper() and i < len(text)-1 and text[i+1].islower()):
|
5037
|
+
words.append(''.join(current_word))
|
5038
|
+
current_word = [curr_char]
|
5039
|
+
else:
|
5040
|
+
current_word.append(curr_char)
|
5041
|
+
words.append(''.join(current_word))
|
5042
|
+
|
5043
|
+
# 处理虚词:除首单词外,虚词首字母小写
|
5044
|
+
formatted_words = [words[0]]
|
5045
|
+
for word in words[1:]:
|
5046
|
+
lower_word = word.lower()
|
5047
|
+
formatted_words.append(lower_word if lower_word in articles else word)
|
5048
|
+
|
5049
|
+
words2=' '.join(formatted_words)
|
5050
|
+
|
5051
|
+
if DEBUG:
|
5052
|
+
print(f"BEFORE: {text}, AFTER: {words2}")
|
5053
|
+
|
5054
|
+
return words2
|
5055
|
+
|
5056
|
+
#==============================================================================
|
5057
|
+
if __name__ == '__main__':
|
5058
|
+
alist=['a','b','c']
|
5059
|
+
element='b'
|
5060
|
+
element='c'
|
5061
|
+
|
5062
|
+
last_in_list(element,alist)
|
5063
|
+
|
5064
|
+
def last_in_list(element,alist):
|
5065
|
+
"""
|
5066
|
+
功能:测试element是否alist的最后一个元素
|
5067
|
+
参数:
|
5068
|
+
element:alist的元素,用于循环
|
5069
|
+
alist:列表,用于循环
|
5070
|
+
"""
|
5071
|
+
result=False
|
5072
|
+
if alist.index(element) == len(alist)-1:
|
5073
|
+
result=True
|
5074
|
+
|
5075
|
+
return result
|
5003
5076
|
#==============================================================================
|
5004
5077
|
#==============================================================================
|
5005
5078
|
#==============================================================================
|
siat/financial_statements.py
CHANGED
@@ -53,7 +53,8 @@ def get_balance_sheet(symbol):
|
|
53
53
|
stmta=stock.balance_sheet() # Defaults to Annual
|
54
54
|
except:
|
55
55
|
print(" Searching for annual report failed, recovering......")
|
56
|
-
|
56
|
+
sleep_random(max_sleep=60)
|
57
|
+
|
57
58
|
try:
|
58
59
|
stmta=stock.balance_sheet()
|
59
60
|
except:
|
@@ -76,7 +77,8 @@ def get_balance_sheet(symbol):
|
|
76
77
|
stmtq=stock.balance_sheet(frequency="q")
|
77
78
|
except:
|
78
79
|
print(" Searching for quarterly report failed, recovering......")
|
79
|
-
|
80
|
+
sleep_random(max_sleep=60)
|
81
|
+
|
80
82
|
try:
|
81
83
|
stmtq=stock.balance_sheet(frequency="q")
|
82
84
|
except:
|
@@ -195,7 +197,7 @@ def get_income_statements(symbol):
|
|
195
197
|
stmta=stock.income_statement() # Defaults to Annual
|
196
198
|
except:
|
197
199
|
print(" Searching for annual report failed, recovering......")
|
198
|
-
|
200
|
+
sleep_random(max_sleep=60)
|
199
201
|
try:
|
200
202
|
stmta=stock.income_statement()
|
201
203
|
except:
|
@@ -218,7 +220,7 @@ def get_income_statements(symbol):
|
|
218
220
|
stmtq=stock.income_statement(frequency="q")
|
219
221
|
except:
|
220
222
|
print(" Searching for quarterly report failed, recovering......")
|
221
|
-
|
223
|
+
sleep_random(max_sleep=60)
|
222
224
|
try:
|
223
225
|
stmtq=stock.income_statement(frequency="q")
|
224
226
|
except:
|
@@ -310,7 +312,7 @@ def get_cashflow_statements(symbol):
|
|
310
312
|
stmta=stock.cash_flow() # Defaults to Annual
|
311
313
|
except:
|
312
314
|
print(" Searching for annual report failed, recovering......")
|
313
|
-
|
315
|
+
sleep_random(max_sleep=60)
|
314
316
|
try:
|
315
317
|
stmta=stock.cash_flow()
|
316
318
|
except:
|
@@ -333,7 +335,7 @@ def get_cashflow_statements(symbol):
|
|
333
335
|
stmtq=stock.cash_flow(frequency="q")
|
334
336
|
except:
|
335
337
|
print(" Searching for quarterly report failed, recovering......")
|
336
|
-
|
338
|
+
sleep_random(max_sleep=60)
|
337
339
|
try:
|
338
340
|
stmtq=stock.cash_flow(frequency="q")
|
339
341
|
except:
|
@@ -407,11 +409,11 @@ def get_financial_statements(ticker):
|
|
407
409
|
fbs = get_balance_sheet(ticker)
|
408
410
|
except:
|
409
411
|
print(" Retrieving fin info failed, trying to recover...")
|
410
|
-
|
412
|
+
sleep_random(max_sleep=60)
|
411
413
|
try:
|
412
414
|
fbs = get_balance_sheet(ticker)
|
413
415
|
except:
|
414
|
-
|
416
|
+
sleep_random(max_sleep=60)
|
415
417
|
try:
|
416
418
|
fbs = get_balance_sheet(ticker)
|
417
419
|
except:
|
@@ -426,11 +428,11 @@ def get_financial_statements(ticker):
|
|
426
428
|
fis = get_income_statements(ticker)
|
427
429
|
except:
|
428
430
|
print(" Failed, recovering...")
|
429
|
-
|
431
|
+
sleep_random(max_sleep=60)
|
430
432
|
try:
|
431
433
|
fis = get_income_statements(ticker)
|
432
434
|
except:
|
433
|
-
|
435
|
+
sleep_random(max_sleep=60)
|
434
436
|
try:
|
435
437
|
fis = get_income_statements(ticker)
|
436
438
|
except:
|
@@ -445,11 +447,11 @@ def get_financial_statements(ticker):
|
|
445
447
|
fcf = get_cashflow_statements(ticker)
|
446
448
|
except:
|
447
449
|
print(" Failed, recovering...")
|
448
|
-
|
450
|
+
sleep_random(max_sleep=60)
|
449
451
|
try:
|
450
452
|
fcf = get_cashflow_statements(ticker)
|
451
453
|
except:
|
452
|
-
|
454
|
+
sleep_random(max_sleep=60)
|
453
455
|
try:
|
454
456
|
fcf = get_cashflow_statements(ticker)
|
455
457
|
except:
|
siat/financials.py
CHANGED
@@ -1186,7 +1186,7 @@ def get_financial_rates(ticker):
|
|
1186
1186
|
fsdf=get_financial_statements(ticker)
|
1187
1187
|
except:
|
1188
1188
|
print(" Failed to get financial statements of",ticker,"\b, recovering")
|
1189
|
-
|
1189
|
+
sleep_random(max_sleep=60)
|
1190
1190
|
try:
|
1191
1191
|
fsdf=get_financial_statements(ticker)
|
1192
1192
|
except:
|
siat/financials2.py
CHANGED
@@ -103,6 +103,7 @@ if __name__=='__main__':
|
|
103
103
|
|
104
104
|
def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
105
105
|
category='profile',business_period='annual', \
|
106
|
+
items_included='all', \
|
106
107
|
scale1=10,scale2=10,dupont_sort='PM',
|
107
108
|
printout=True, \
|
108
109
|
#entry_sort=False, \
|
@@ -125,6 +126,7 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
125
126
|
财务状况('financial')、一般风险('risk')、ESG风险('esg')
|
126
127
|
|
127
128
|
business_period:业务期间类型,可为季报'quarterly',默认年报'annual'、最近的6次报告'recent', 所有'all'
|
129
|
+
items_included:默认输出所有报表项目,可以列表形式选择其中一部分。
|
128
130
|
scale1:仅用于杜邦分析,放大倍数(以便缩小与EM之间的数量级差异),用于Profit Margin,默认10
|
129
131
|
scale2:仅用于杜邦分析,放大倍数,用于Total Asset Turnover,默认10
|
130
132
|
dupont_sort:仅用于杜邦分析,用于排序指标,默认净利润率'PM',还可为总资产周转率'TAT'或权益乘数'EM'
|
@@ -179,7 +181,10 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
179
181
|
注意4:不同经济体上市公司年报季报日期不同,需要列示报表日期和类型(年报或季报)
|
180
182
|
|
181
183
|
"""
|
184
|
+
DEBUG=False
|
185
|
+
|
182
186
|
import numpy as np
|
187
|
+
import pandas as pd
|
183
188
|
|
184
189
|
#屏蔽函数内print信息输出的类
|
185
190
|
import os, sys
|
@@ -265,8 +270,11 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
265
270
|
# 分析资产负债表
|
266
271
|
fsdf=get_balance_sheet(symbol=tickers)
|
267
272
|
if fsdf is None:
|
268
|
-
|
269
|
-
|
273
|
+
print(f" #Warning(fs_analysis): failed to access financial info for {tickers}")
|
274
|
+
if test_yahoo_access():
|
275
|
+
print(f" Solution: if {tickers} are correct, then try again later")
|
276
|
+
else:
|
277
|
+
print(" Problem: no internet connection to Yahoo for retrieveing data")
|
270
278
|
return None
|
271
279
|
|
272
280
|
fsdf['reportDate']=fsdf['asOfDate'].apply(lambda x: x.strftime('%y-%m-%d'))
|
@@ -350,7 +358,22 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
350
358
|
footnote2="Data source: Yahoo Finance, "+str(todaydt)
|
351
359
|
footnote='Note:\n'+footnote1+'\n'+footnote2
|
352
360
|
#print('\n',footnote1,'\n',footnote2)
|
353
|
-
|
361
|
+
|
362
|
+
# 将Item科目名称拆分加空格和转大写
|
363
|
+
fsdf6['Item']=fsdf6['Item'].apply(lambda x: text_separate(x))
|
364
|
+
|
365
|
+
# 判断是否仅输出部分科目
|
366
|
+
if 'all' in items_included:
|
367
|
+
fsdf7=fsdf6
|
368
|
+
else:
|
369
|
+
mask=fsdf6['Item'].isin(items_included)
|
370
|
+
fsdf7=fsdf6[mask]
|
371
|
+
# 将Item列转为分类类型,指定顺序
|
372
|
+
fsdf7['Item'] = pd.Categorical(fsdf7['Item'], categories=items_included, ordered=True)
|
373
|
+
# 按分类顺序排序
|
374
|
+
fsdf7=fsdf7.sort_values(by='Item')
|
375
|
+
|
376
|
+
df_display_CSS(fsdf7,titletxt=titletxt,footnote=footnote,facecolor=facecolor, \
|
354
377
|
titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
|
355
378
|
data_font_size=data_font_size)
|
356
379
|
|
@@ -371,6 +394,11 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
371
394
|
fsdf=get_income_statements(symbol=tickers)
|
372
395
|
if fsdf is None:
|
373
396
|
print(" #Warning(fs_analysis): financial info unaccessible for",tickers)
|
397
|
+
if test_yahoo_access():
|
398
|
+
print(f" Solution: if {tickers} are correct, then try again later")
|
399
|
+
else:
|
400
|
+
print(" Problem: no internet connection to Yahoo for retrieveing data")
|
401
|
+
|
374
402
|
return None
|
375
403
|
|
376
404
|
fsdf['reportDate']=fsdf['asOfDate'].apply(lambda x: x.strftime('%y-%m-%d'))
|
@@ -431,7 +459,22 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
431
459
|
footnote2="Data source: Yahoo Finance, "+str(todaydt)
|
432
460
|
footnote='Note:\n'+footnote1+'\n'+footnote2
|
433
461
|
#print('\n',footnote1,'\n',footnote2)
|
434
|
-
|
462
|
+
|
463
|
+
# 将Item科目名称拆分加空格和转大写
|
464
|
+
fsdf6['Item']=fsdf6['Item'].apply(lambda x: text_separate(x))
|
465
|
+
|
466
|
+
# 判断是否仅输出部分科目
|
467
|
+
if 'all' in items_included:
|
468
|
+
fsdf7=fsdf6
|
469
|
+
else:
|
470
|
+
mask=fsdf6['Item'].isin(items_included)
|
471
|
+
fsdf7=fsdf6[mask]
|
472
|
+
# 将Item列转为分类类型,指定顺序
|
473
|
+
fsdf7['Item'] = pd.Categorical(fsdf7['Item'], categories=items_included, ordered=True)
|
474
|
+
# 按分类顺序排序
|
475
|
+
fsdf7=fsdf7.sort_values(by='Item')
|
476
|
+
|
477
|
+
df_display_CSS(fsdf7,titletxt=titletxt,footnote=footnote,facecolor=facecolor, \
|
435
478
|
titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
|
436
479
|
data_font_size=data_font_size)
|
437
480
|
|
@@ -451,6 +494,11 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
451
494
|
fsdf=get_cashflow_statements(symbol=tickers)
|
452
495
|
if fsdf is None:
|
453
496
|
print(" #Warning(fs_analysis): financial info unaccessible for",tickers)
|
497
|
+
if test_yahoo_access():
|
498
|
+
print(f" Solution: if {tickers} are correct, then try again later")
|
499
|
+
else:
|
500
|
+
print(" Problem: no internet connection to Yahoo for retrieveing data")
|
501
|
+
|
454
502
|
return None
|
455
503
|
|
456
504
|
fsdf['reportDate']=fsdf['asOfDate'].apply(lambda x: x.strftime('%y-%m-%d'))
|
@@ -511,7 +559,22 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
511
559
|
footnote2="Data source: Yahoo Finance, "+str(todaydt)
|
512
560
|
footnote='Note:\n'+footnote1+'\n'+footnote2
|
513
561
|
#print('\n',footnote1,'\n',footnote2)
|
514
|
-
|
562
|
+
|
563
|
+
# 将Item科目名称拆分加空格和转大写
|
564
|
+
fsdf6['Item']=fsdf6['Item'].apply(lambda x: text_separate(x))
|
565
|
+
|
566
|
+
# 判断是否仅输出部分科目
|
567
|
+
if 'all' in items_included:
|
568
|
+
fsdf7=fsdf6
|
569
|
+
else:
|
570
|
+
mask=fsdf6['Item'].isin(items_included)
|
571
|
+
fsdf7=fsdf6[mask]
|
572
|
+
# 将Item列转为分类类型,指定顺序
|
573
|
+
fsdf7['Item'] = pd.Categorical(fsdf7['Item'], categories=items_included, ordered=True)
|
574
|
+
# 按分类顺序排序
|
575
|
+
fsdf7=fsdf7.sort_values(by='Item')
|
576
|
+
|
577
|
+
df_display_CSS(fsdf7,titletxt=titletxt,footnote=footnote,facecolor=facecolor, \
|
515
578
|
titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
|
516
579
|
data_font_size=data_font_size)
|
517
580
|
return fsdf6
|
@@ -544,11 +607,16 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
544
607
|
|
545
608
|
# 股票可为单只股票(单只股票深度分析)
|
546
609
|
if isinstance(tickers,str):
|
547
|
-
print(" Getting financial rates for financial summary of",tickers,"
|
610
|
+
print(" Getting financial rates for financial summary of",tickers,"...")
|
548
611
|
with HiddenPrints():
|
549
612
|
fsdf=get_financial_rates(tickers)
|
550
613
|
if fsdf is None:
|
551
614
|
print(" #Warning(fs_analysis): financial info unaccessible for",tickers)
|
615
|
+
if test_yahoo_access():
|
616
|
+
print(f" Solution: if {tickers} are correct, then try again later")
|
617
|
+
else:
|
618
|
+
print(" Problem: no internet connection to Yahoo for retrieveing data")
|
619
|
+
|
552
620
|
return None
|
553
621
|
|
554
622
|
fsdf['reportDate']=fsdf['asOfDate'].apply(lambda x: x.strftime('%y-%m-%d'))
|
@@ -623,7 +691,22 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
623
691
|
footnote3="Data source: Yahoo Finance, "+todaydt
|
624
692
|
footnote='Note:\n'+footnote1+'\n'+footnote2+'\n'+footnote3
|
625
693
|
#print('\n',footnote1,'\n',footnote2,'\n',footnote3)
|
626
|
-
|
694
|
+
|
695
|
+
# 将Item科目名称拆分加空格和转大写
|
696
|
+
fsdf6['Item']=fsdf6['Item'].apply(lambda x: text_separate(x))
|
697
|
+
|
698
|
+
# 判断是否仅输出部分科目
|
699
|
+
if 'all' in items_included:
|
700
|
+
fsdf7=fsdf6
|
701
|
+
else:
|
702
|
+
mask=fsdf6['Item'].isin(items_included)
|
703
|
+
fsdf7=fsdf6[mask]
|
704
|
+
# 将Item列转为分类类型,指定顺序
|
705
|
+
fsdf7['Item'] = pd.Categorical(fsdf7['Item'], categories=items_included, ordered=True)
|
706
|
+
# 按分类顺序排序
|
707
|
+
fsdf7=fsdf7.sort_values(by='Item')
|
708
|
+
|
709
|
+
df_display_CSS(fsdf7,titletxt=titletxt,footnote=footnote,facecolor=facecolor, \
|
627
710
|
titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
|
628
711
|
data_font_size=data_font_size)
|
629
712
|
return fsdf6
|
@@ -636,14 +719,20 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
636
719
|
business_period=business_period.lower()
|
637
720
|
fsdf=pd.DataFrame()
|
638
721
|
for t in tickers:
|
639
|
-
print(" Getting financial rates for financial summary of",t,"
|
722
|
+
print(" Getting financial rates for financial summary of",t,"...")
|
640
723
|
with HiddenPrints():
|
641
724
|
dftmp=get_financial_rates(t)
|
642
725
|
if dftmp is None:
|
643
726
|
print(" #Warning(fs_analysis): financial info unaccessible for",t)
|
644
|
-
|
727
|
+
if test_yahoo_access():
|
728
|
+
print(f" Solution: if {t} are correct, then try again later")
|
729
|
+
else:
|
730
|
+
print(" Problem: no internet connection to Yahoo for retrieveing data")
|
645
731
|
return None
|
646
732
|
|
733
|
+
if not last_in_list(t,tickers):
|
734
|
+
sleep_random(max_sleep=60)
|
735
|
+
|
647
736
|
if business_period=='recent':
|
648
737
|
dftmp2=dftmp.tail(1)
|
649
738
|
elif business_period=='annual':
|
@@ -725,8 +814,23 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
725
814
|
footnote2="ROx/EM/turnover rates are based on periodic mean, others on end-term"
|
726
815
|
footnote3="Data source: Yahoo Finance, "+str(todaydt)
|
727
816
|
footnote='Note:\n'+footnote1+'\n'+footnote2+'\n'+footnote3
|
728
|
-
#print('\n',footnote1,'\n',footnote2,'\n',footnote3)
|
729
|
-
|
817
|
+
#print('\n',footnote1,'\n',footnote2,'\n',footnote3)
|
818
|
+
|
819
|
+
# 将Item科目名称拆分加空格和转大写
|
820
|
+
fsdf6['Item']=fsdf6['Item'].apply(lambda x: text_separate(x))
|
821
|
+
|
822
|
+
# 判断是否仅输出部分科目
|
823
|
+
if 'all' in items_included:
|
824
|
+
fsdf7=fsdf6
|
825
|
+
else:
|
826
|
+
mask=fsdf6['Item'].isin(items_included)
|
827
|
+
fsdf7=fsdf6[mask]
|
828
|
+
# 将Item列转为分类类型,指定顺序
|
829
|
+
fsdf7['Item'] = pd.Categorical(fsdf7['Item'], categories=items_included, ordered=True)
|
830
|
+
# 按分类顺序排序
|
831
|
+
fsdf7=fsdf7.sort_values(by='Item')
|
832
|
+
|
833
|
+
df_display_CSS(fsdf7,titletxt=titletxt,footnote=footnote,facecolor=facecolor, \
|
730
834
|
titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
|
731
835
|
data_font_size=data_font_size)
|
732
836
|
return fsdf6
|
@@ -760,11 +864,16 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
760
864
|
|
761
865
|
# 股票可为单只股票(单只股票深度分析)
|
762
866
|
if isinstance(tickers,str):
|
763
|
-
print(" Getting financial rates for financial indicators of",tickers,"
|
867
|
+
print(" Getting financial rates for financial indicators of",tickers,"...")
|
764
868
|
with HiddenPrints():
|
765
869
|
fsdf=get_financial_rates(tickers)
|
766
870
|
if fsdf is None:
|
767
871
|
print(" #Warning(fs_analysis): financial info unaccessible for",tickers)
|
872
|
+
if test_yahoo_access():
|
873
|
+
print(f" Solution: if {tickers} are correct, then try again later")
|
874
|
+
else:
|
875
|
+
print(" Problem: no internet connection to Yahoo for retrieveing data")
|
876
|
+
|
768
877
|
return None
|
769
878
|
|
770
879
|
fsdf['reportDate']=fsdf['asOfDate'].apply(lambda x: x.strftime('%y-%m-%d'))
|
@@ -835,8 +944,23 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
835
944
|
footnote2="ROx/EM/turnover rates are based on periodic mean, others on end-term"
|
836
945
|
footnote3="Data source: Yahoo Finance, "+str(todaydt)
|
837
946
|
footnote='Note:\n'+footnote1+'\n'+footnote2+'\n'+footnote3
|
838
|
-
#print('\n',footnote1,'\n',footnote2,'\n',footnote3)
|
839
|
-
|
947
|
+
#print('\n',footnote1,'\n',footnote2,'\n',footnote3)
|
948
|
+
|
949
|
+
# 将Item科目名称拆分加空格和转大写
|
950
|
+
fsdf6['Item']=fsdf6['Item'].apply(lambda x: text_separate(x))
|
951
|
+
|
952
|
+
# 判断是否仅输出部分科目
|
953
|
+
if 'all' in items_included:
|
954
|
+
fsdf7=fsdf6
|
955
|
+
else:
|
956
|
+
mask=fsdf6['Item'].isin(items_included)
|
957
|
+
fsdf7=fsdf6[mask]
|
958
|
+
# 将Item列转为分类类型,指定顺序
|
959
|
+
fsdf7['Item'] = pd.Categorical(fsdf7['Item'], categories=items_included, ordered=True)
|
960
|
+
# 按分类顺序排序
|
961
|
+
fsdf7=fsdf7.sort_values(by='Item')
|
962
|
+
|
963
|
+
df_display_CSS(fsdf7,titletxt=titletxt,footnote=footnote,facecolor=facecolor, \
|
840
964
|
titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
|
841
965
|
data_font_size=data_font_size)
|
842
966
|
return fsdf6
|
@@ -848,18 +972,28 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
848
972
|
|
849
973
|
business_period=business_period.lower()
|
850
974
|
fsdf=pd.DataFrame()
|
975
|
+
print(" Working on financial rates, it may take long time ...")
|
976
|
+
|
851
977
|
for t in tickers:
|
852
|
-
print(" Getting financial rates for financial indicators of",t,"
|
978
|
+
print(" Getting financial rates for financial indicators of",t,"...")
|
853
979
|
with HiddenPrints():
|
854
980
|
dftmp=get_financial_rates(t)
|
855
981
|
if dftmp is None:
|
856
982
|
print(" #Warning(fs_analysis): financial info unaccessible for",t)
|
983
|
+
if test_yahoo_access():
|
984
|
+
print(f" Solution: if {t} are correct, then try again later")
|
985
|
+
else:
|
986
|
+
print(" Problem: no internet connection to Yahoo for retrieveing data")
|
987
|
+
|
857
988
|
return None
|
858
989
|
|
859
|
-
if dftmp
|
860
|
-
print(" #Warning(fs_analysis):
|
990
|
+
if len(dftmp) == 0:
|
991
|
+
print(" #Warning(fs_analysis): zero financial indicators found for stock",t)
|
861
992
|
continue
|
862
993
|
|
994
|
+
if not last_in_list(t,tickers):
|
995
|
+
sleep_random(max_sleep=60)
|
996
|
+
|
863
997
|
if business_period=='recent':
|
864
998
|
dftmp2=dftmp.tail(1)
|
865
999
|
elif business_period=='annual':
|
@@ -938,8 +1072,26 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
938
1072
|
footnote2="ROx/EM/turnover rates are based on periodic mean, others on end-term"
|
939
1073
|
footnote3="Data source: Yahoo Finance, "+str(todaydt)
|
940
1074
|
footnote='Note:\n'+footnote1+'\n'+footnote2+'\n'+footnote3
|
941
|
-
#print('\n',footnote1,'\n',footnote2,'\n',footnote3)
|
942
|
-
|
1075
|
+
#print('\n',footnote1,'\n',footnote2,'\n',footnote3)
|
1076
|
+
|
1077
|
+
# 将Item科目名称拆分加空格和转大写
|
1078
|
+
fsdf6['Item']=fsdf6['Item'].apply(lambda x: text_separate(x))
|
1079
|
+
|
1080
|
+
# 将Item科目名称拆分加空格和转大写
|
1081
|
+
fsdf6['Item']=fsdf6['Item'].apply(lambda x: text_separate(x))
|
1082
|
+
|
1083
|
+
# 判断是否仅输出部分科目
|
1084
|
+
if 'all' in items_included:
|
1085
|
+
fsdf7=fsdf6
|
1086
|
+
else:
|
1087
|
+
mask=fsdf6['Item'].isin(items_included)
|
1088
|
+
fsdf7=fsdf6[mask]
|
1089
|
+
# 将Item列转为分类类型,指定顺序
|
1090
|
+
fsdf7['Item'] = pd.Categorical(fsdf7['Item'], categories=items_included, ordered=True)
|
1091
|
+
# 按分类顺序排序
|
1092
|
+
fsdf7=fsdf7.sort_values(by='Item')
|
1093
|
+
|
1094
|
+
df_display_CSS(fsdf7,titletxt=titletxt,footnote=footnote,facecolor=facecolor, \
|
943
1095
|
titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
|
944
1096
|
data_font_size=data_font_size)
|
945
1097
|
return fsdf6
|
@@ -955,14 +1107,23 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
955
1107
|
|
956
1108
|
business_period=business_period.lower()
|
957
1109
|
fsdf=pd.DataFrame()
|
1110
|
+
print(" Working on dupont identity, it may take long time ...")
|
958
1111
|
for t in tickers:
|
959
|
-
print(" Getting financial rates for dupont identity of",t,"
|
1112
|
+
print(" Getting financial rates for dupont identity of",t,"...")
|
960
1113
|
with HiddenPrints():
|
961
1114
|
dftmp=get_financial_rates(t)
|
962
1115
|
if dftmp is None:
|
963
1116
|
print(" #Warning(fs_analysis): financial info unaccessible for",t)
|
1117
|
+
if test_yahoo_access():
|
1118
|
+
print(f" Solution: if {t} are correct, then try again later")
|
1119
|
+
else:
|
1120
|
+
print(" Problem: no internet connection to Yahoo for retrieveing data")
|
1121
|
+
|
964
1122
|
return None
|
965
1123
|
|
1124
|
+
if not last_in_list(t,tickers):
|
1125
|
+
sleep_random(max_sleep=60)
|
1126
|
+
|
966
1127
|
if business_period=='recent':
|
967
1128
|
dftmp2=dftmp.tail(1)
|
968
1129
|
elif business_period=='annual':
|
@@ -1070,7 +1231,11 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
|
|
1070
1231
|
footnote1="Based on exchange's local accounting standards, EM/TAT are on periodic mean"
|
1071
1232
|
footnote2="Data source: Yahoo Finance, "+str(todaydt)
|
1072
1233
|
footnote='Note:\n'+footnote1+'\n'+footnote2
|
1073
|
-
#print('\n',footnote1,'\b.',footnote2)
|
1234
|
+
#print('\n',footnote1,'\b.',footnote2)
|
1235
|
+
|
1236
|
+
# 将Item科目名称拆分加空格和转大写
|
1237
|
+
df['Item']=df['Item'].apply(lambda x: text_separate(x))
|
1238
|
+
|
1074
1239
|
df_display_CSS(df,titletxt=titletxt,footnote=footnote,facecolor=facecolor,decimals=4, \
|
1075
1240
|
titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
|
1076
1241
|
data_font_size=data_font_size)
|
siat/other_indexes.py
CHANGED
@@ -291,6 +291,7 @@ if __name__=='__main__':
|
|
291
291
|
api_key='VTRR3TA7L9O2DIX6'
|
292
292
|
keyword='AAPL'
|
293
293
|
keyword='Apple'
|
294
|
+
keyword='^TYX'
|
294
295
|
|
295
296
|
search_av("microsoft")
|
296
297
|
search_av("Apple")
|
@@ -308,13 +309,19 @@ def search_av(keyword,api_key='VTRR3TA7L9O2DIX6'):
|
|
308
309
|
|
309
310
|
data = response.json()
|
310
311
|
if "bestMatches" in data:
|
311
|
-
|
312
|
-
|
312
|
+
try:
|
313
|
+
firstcode=data["bestMatches"][0]['1. symbol']
|
314
|
+
firstname=data["bestMatches"][0]['2. name']
|
315
|
+
except:
|
316
|
+
print(f" #Warning(search_av): no contents found for {keyword} in Alpha Vantage")
|
317
|
+
#未找到可匹配的股票代码
|
318
|
+
return None,None,None
|
319
|
+
|
313
320
|
else:
|
314
321
|
if "Information" in data:
|
315
|
-
print(f" Warning(search_av): exceeded
|
322
|
+
print(f" #Warning(search_av): exceeded limit of requests per day in Alpha Vantage")
|
316
323
|
else:
|
317
|
-
print(f" Warning(search_av): keyword {keyword} not found in Alpha Vantage")
|
324
|
+
print(f" #Warning(search_av): keyword {keyword} not found in Alpha Vantage")
|
318
325
|
#未找到可匹配的股票代码
|
319
326
|
return None,None,None
|
320
327
|
|
siat/security_price2.py
CHANGED
@@ -171,9 +171,14 @@ def get_price_1ticker(ticker,fromdate,todate, \
|
|
171
171
|
if source in ['auto','yahoo'] and found not in ['Found','Empty']:
|
172
172
|
dft=None
|
173
173
|
if test_yahoo_finance():
|
174
|
-
#数据源情形
|
175
|
-
dft=
|
174
|
+
#数据源情形3a:yahoo, yahooquery, 需要访问yahoo
|
175
|
+
dft=get_price_yq(ticker1,fromdate,todate)
|
176
176
|
found=df_have_data(dft)
|
177
|
+
|
178
|
+
#数据源情形3b:yahoo, yfinance, 需要访问yahoo,直接为复权价
|
179
|
+
if found not in ['Found','Empty']:
|
180
|
+
dft=get_price_yf(ticker1,fromdate,todate)
|
181
|
+
found=df_have_data(dft)
|
177
182
|
|
178
183
|
#数据源情形4:yahoo, pandas_datareader,需要访问yahoo,似乎不工作了!
|
179
184
|
if found not in ['Found','Empty']:
|
siat/security_prices.py
CHANGED
@@ -1449,6 +1449,74 @@ if __name__=='__main__':
|
|
1449
1449
|
df4=get_prices_yf(['0700.HK','600519.SS'],'2020-12-1','2021-1-31')
|
1450
1450
|
df5=get_prices_yf(['AAPL','MSFT','0700.HK','600519.SS'],'2020-12-1','2021-1-31')
|
1451
1451
|
df6=get_prices_yf(['ABCD','EFGH','0700.HK','600519.SS'],'2020-12-1','2021-1-31')
|
1452
|
+
|
1453
|
+
#==============================================================================
|
1454
|
+
if __name__=='__main__':
|
1455
|
+
ticker='^TYX'
|
1456
|
+
start='2024-12-1'
|
1457
|
+
end='2025-1-31'
|
1458
|
+
|
1459
|
+
get_price_yq(ticker,start,end)
|
1460
|
+
|
1461
|
+
def get_price_yq(ticker,start,end):
|
1462
|
+
"""
|
1463
|
+
功能:从雅虎财经抓取股价,使用yahooquery(注意插件版本问题)
|
1464
|
+
输入:股票代码或股票代码列表,开始日期,结束日期
|
1465
|
+
ticker: 股票代码或股票代码列表。大陆股票代码加上后缀.SZ或.SS或.BJ,港股代码去掉前导0加后缀.HK
|
1466
|
+
start: 样本开始日期,尽量远的日期,以便取得足够多的原始样本,yyyy-mm-dd
|
1467
|
+
end: 样本结束日期,既可以是今天日期,也可以是一个历史日期
|
1468
|
+
|
1469
|
+
输出:指定收盘价格序列,最新日期的股价排列在前
|
1470
|
+
"""
|
1471
|
+
p=None
|
1472
|
+
|
1473
|
+
#支持多个证券
|
1474
|
+
import yahooquery as yq
|
1475
|
+
ticker1,islist=cvt_yftickerlist(ticker)
|
1476
|
+
if not islist:
|
1477
|
+
#下载单一股票的股价
|
1478
|
+
stock=yq.Ticker(ticker1, asynchronous=True)
|
1479
|
+
try:
|
1480
|
+
p=stock.history(start=start,end=end)
|
1481
|
+
#仅针对雅虎情况
|
1482
|
+
if p is not None:
|
1483
|
+
if len(p)==0: p=None
|
1484
|
+
except:
|
1485
|
+
p=None
|
1486
|
+
else:
|
1487
|
+
#下载股票列表的股价,与但股票情况相同,但需注意MultiInex结构
|
1488
|
+
stock=yq.Ticker(ticker1, asynchronous=True)
|
1489
|
+
try:
|
1490
|
+
p=stock.history(start=start,end=end)
|
1491
|
+
#仅针对雅虎情况
|
1492
|
+
if p is not None:
|
1493
|
+
if len(p)==0: p=None
|
1494
|
+
except:
|
1495
|
+
p=None
|
1496
|
+
|
1497
|
+
found=df_have_data(p)
|
1498
|
+
if found in ['Found','Empty']:
|
1499
|
+
p.rename(columns={'open':'Open','high':'High','low':'Low','close':'Close', \
|
1500
|
+
'adjclose':'Adj Close','volume':'Volume'},inplace=True)
|
1501
|
+
|
1502
|
+
if 'Adj Close' not in list(p):
|
1503
|
+
p['Adj Close']=p['Close']
|
1504
|
+
p['ticker']=ticker
|
1505
|
+
p['source']=text_lang('雅虎','Yahoo')
|
1506
|
+
|
1507
|
+
# 去掉一级Index
|
1508
|
+
p=p.droplevel('symbol')
|
1509
|
+
p['date']=p.index
|
1510
|
+
if len(p) > 0:
|
1511
|
+
print(" Successfully retrieved",len(p),"records for",ticker1)
|
1512
|
+
|
1513
|
+
#去掉时区
|
1514
|
+
p=df_index_timezone_remove(p)
|
1515
|
+
else:
|
1516
|
+
pass
|
1517
|
+
#print(" #Error(get_prices_yf):",ticker1,"not found or no prices in the period or inaccessible to yahoo")
|
1518
|
+
|
1519
|
+
return p
|
1452
1520
|
|
1453
1521
|
#==============================================================================
|
1454
1522
|
if __name__=='__main__':
|
@@ -1,5 +1,5 @@
|
|
1
1
|
siat/__init__ -20240701.py,sha256=gP5uajXnJesnH5SL0ZPwq_Qhv59AG1bs4qwZv26Fo2Y,2894
|
2
|
-
siat/__init__.py,sha256=
|
2
|
+
siat/__init__.py,sha256=LZKNrzk9Ibuzpox_Fy4zzxvAZLvtgVFeKMEY5go6ns0,2235
|
3
3
|
siat/__init__.py.backup_20250214.py,sha256=pIo4CV3lNPKIhitmhIh_6aAfZrmzQWGNDcEnvZ7GXoc,3216
|
4
4
|
siat/allin.py,sha256=--32Bt2Mfg7l38w7X9cLJCdWtYRB3tTtVHnS9WnqKDI,3035
|
5
5
|
siat/alpha_vantage_test.py,sha256=tKr-vmuFH3CZAqwmISz6jzjPHzV1JJl3sPfZdz8aTfM,747
|
@@ -19,7 +19,7 @@ siat/capm_beta.py,sha256=cxXdRVBQBllhbfz1LeTJAIWvyRYhW54nhtNUXv4HwS0,29063
|
|
19
19
|
siat/capm_beta2.py,sha256=wGF_HmK_AiGWjpSAx79XHIxDghtI_ueYozvh06-2JEQ,33707
|
20
20
|
siat/capm_beta_test.py,sha256=ImR0c5mc4hIl714XmHztdl7qg8v1E2lycKyiqnFj6qs,1745
|
21
21
|
siat/cmat_commons.py,sha256=Nj9Kf0alywaztVoMVeVVL_EZk5jRERJy8R8kBw88_Tg,38116
|
22
|
-
siat/common.py,sha256=
|
22
|
+
siat/common.py,sha256=J0qSvKtPS1gAfb2_GJNKxFkWJJaNbkQzg4fzaBvKwjM,183440
|
23
23
|
siat/compare_cross.py,sha256=3iP9TH2h3w27F2ARZc7FjKcErYCzWRc-TPiymOyoVtw,24171
|
24
24
|
siat/compare_cross_test.py,sha256=xra5XYmQGEtfIZL2h-GssdH2hLdFIhG3eoCrkDrL3gY,3473
|
25
25
|
siat/concepts_iwencai.py,sha256=m1YEDtECRT6FqtzlKm91pt2I9d3Z_XoP59BtWdRdu8I,3061
|
@@ -40,11 +40,11 @@ siat/fama_french.py,sha256=aUTC-67t_CEPbLk4u79woW_zfZ7OCP6Fo4z5EdWCSkQ,48051
|
|
40
40
|
siat/fama_french_test.py,sha256=M4O23lBKsJxhWHRluwCb3l7HSEn3OFTjzGMpehcevRg,4678
|
41
41
|
siat/fin_stmt2_yahoo.py,sha256=LGmspk0nKyz4X87MtcovZXUfMQkAvrWINuxR4HQ8PI8,41178
|
42
42
|
siat/financial_base.py,sha256=A1rV7XQOVFpCXCV-T6Ge0QeF897hINiu0olN1XWeaFk,41287
|
43
|
-
siat/financial_statements.py,sha256=
|
43
|
+
siat/financial_statements.py,sha256=7cv0z3djnfWsbnvW04ScrWSjCLEyUFrbGgQ6NtclyD0,25512
|
44
44
|
siat/financial_statements_test.py,sha256=FLhx8JD-tVVWSBGux6AMz1jioXX4U4bp9DmgFHYXb_w,716
|
45
|
-
siat/financials.py,sha256=
|
45
|
+
siat/financials.py,sha256=jIkK8nhjQa5Z1SLeJ2rSQsSBswMgredvX2lZ6-1-Y7E,86267
|
46
46
|
siat/financials2 - 副本.py,sha256=dKlNjIfKeoSy055fQ6E6TUj9HEoO5Ney9grD84J5kfk,14389
|
47
|
-
siat/financials2.py,sha256=
|
47
|
+
siat/financials2.py,sha256=xCxqubwCNdfS7WyIb5IXTFonMZfw8FM9F8TCIkAruhk,58795
|
48
48
|
siat/financials_china.py,sha256=iHF3lEESTK9DLWLBHFpyxn3S_dO2sNBE89xqaVYpNCw,192459
|
49
49
|
siat/financials_china2.py,sha256=VvkzkjZeH84zwypR7ReldgJeZ7jnNw0qkzebvWMPm10,94956
|
50
50
|
siat/financials_china2_test.py,sha256=Erz5k4LyOplBBvYls2MypuqHpVNJ3daiLdyeJezNPu0,2722
|
@@ -89,7 +89,7 @@ siat/option_china_test.py,sha256=UQ-YUHUjoGBQyanLcM-yzqeEIUQP_gCQIeT0W6rnUnA,163
|
|
89
89
|
siat/option_pricing.py,sha256=vyQNgBsjcJi70Pa-fJTVVIGK_3jWh80tkd1ESnn3sE4,74069
|
90
90
|
siat/option_pricing_test.py,sha256=eeorV5Ja5vjlRXnP6fWJHetGU5Vb8SnLopkC6RV3GfA,2203
|
91
91
|
siat/option_sina_api_test.py,sha256=dn-k_wrQnAaNKHoROvWJEc7lqlU0bwiV2Aa4usWAFGM,5908
|
92
|
-
siat/other_indexes.py,sha256=
|
92
|
+
siat/other_indexes.py,sha256=zIUOcaytf0e2NnGU9Bkyiu3z_GaR_-T8nVGCZ4s4Bws,13615
|
93
93
|
siat/proxy_test.py,sha256=erQJrmGs2X46z8Gb1h-7GYQ0rTUcaR8dxHExWoBz2eM,2610
|
94
94
|
siat/quandl_test.py,sha256=EcPoXnLuqzPl5dKyVEZi3j3PJZFpsnU_iNPhLWC9p-A,1552
|
95
95
|
siat/risk_adjusted_return.py,sha256=6F8CpKm-HKO4wfnndri0ew-D3lDAH1fs5O9K5cphoLg,55096
|
@@ -102,8 +102,8 @@ siat/risk_free_rate_test.py,sha256=CpmhUf8aEAEZeNu4gvWP2Mz2dLoIgBX5bI41vfUBEr8,4
|
|
102
102
|
siat/sector_china.py,sha256=9zjdORWx5ia_gUezidhOKWmCnVDwWcnnjjugHudelaQ,157411
|
103
103
|
siat/sector_china_test.py,sha256=1wq7ef8Bb_L8F0h0W6FvyBrIcBTEbrTV7hljtpj49U4,5843
|
104
104
|
siat/security_price.py,sha256=2oHskgiw41KMGfqtnA0i2YjNNV6cYgtlUK0j3YeuXWs,29185
|
105
|
-
siat/security_price2.py,sha256=
|
106
|
-
siat/security_prices.py,sha256=
|
105
|
+
siat/security_price2.py,sha256=uC-wA6w3IlA9ZOJYINqIB7LexCbrnnqTkHTPuCSCwpo,27697
|
106
|
+
siat/security_prices.py,sha256=MD1pANBD4E_dppLHxgoc7QoceGmKO3huOr2IQpU_eiQ,111570
|
107
107
|
siat/security_prices_test.py,sha256=OEphoJ87NPKoNow1QA8EU_5MUYrJF-qKoWKNapVfZNI,10779
|
108
108
|
siat/security_trend.py,sha256=o0vpWdrJkmODCP94X-Bvn-w7efHhj9HpUYBHtLl55D0,17240
|
109
109
|
siat/security_trend2-20240620.py,sha256=QVnEcb7AyVbO77jVqfFsJffGXrX8pgJ9xCfoAKmWBPk,24854
|
@@ -145,8 +145,8 @@ siat/valuation_china.py,sha256=eSKIDckyjG8QkENlW_OKkqbQHno8pzDcomBO9iGNJVM,83079
|
|
145
145
|
siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
|
146
146
|
siat/var_model_validation.py,sha256=R0caWnuZarrRg9939hxh3vJIIpIyPfvelYmzFNZtPbo,14910
|
147
147
|
siat/yf_name.py,sha256=laNKMTZ9hdenGX3IZ7G0a2RLBKEWtUQJFY9CWuk_fp8,24058
|
148
|
-
siat-3.
|
149
|
-
siat-3.
|
150
|
-
siat-3.
|
151
|
-
siat-3.
|
152
|
-
siat-3.
|
148
|
+
siat-3.10.1.dist-info/LICENSE,sha256=NTEMMROY9_4U1szoKC3N2BLHcDd_o5uTgqdVH8tbApw,1071
|
149
|
+
siat-3.10.1.dist-info/METADATA,sha256=45hmgtcQRU3Qq-7X7UlCGRDQrV-_c-VNt8Oec76xNBQ,8396
|
150
|
+
siat-3.10.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
151
|
+
siat-3.10.1.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
|
152
|
+
siat-3.10.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|