siat 3.8.41__py3-none-any.whl → 3.8.42__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/financials.py +122 -42
- siat/stock.py +8 -6
- siat/translate.py +5 -3
- {siat-3.8.41.dist-info → siat-3.8.42.dist-info}/METADATA +1 -1
- {siat-3.8.41.dist-info → siat-3.8.42.dist-info}/RECORD +9 -9
- {siat-3.8.41.dist-info → siat-3.8.42.dist-info}/LICENSE +0 -0
- {siat-3.8.41.dist-info → siat-3.8.42.dist-info}/WHEEL +0 -0
- {siat-3.8.41.dist-info → siat-3.8.42.dist-info}/top_level.txt +0 -0
siat/__init__.py
CHANGED
@@ -66,10 +66,10 @@ class HiddenPrints:
|
|
66
66
|
sys.stdout = self._original_stdout
|
67
67
|
|
68
68
|
if not restart:
|
69
|
-
print("Successfully enabled siat v{}".format(current_version))
|
69
|
+
print(" Successfully enabled siat v{}".format(current_version))
|
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 run this command again")
|
74
74
|
|
75
75
|
#==============================================================================
|
siat/financials.py
CHANGED
@@ -90,7 +90,7 @@ def compare_history(tickers,items, \
|
|
90
90
|
ticker2=tickers[1]
|
91
91
|
ticker_num=2
|
92
92
|
if len(tickers) == 0:
|
93
|
-
print(" #Error(): no stock code found",tickers)
|
93
|
+
print(" #Error(compare_history): no stock code found",tickers)
|
94
94
|
return None,None
|
95
95
|
else:
|
96
96
|
ticker1=tickers
|
@@ -103,7 +103,7 @@ def compare_history(tickers,items, \
|
|
103
103
|
item2=items[1]
|
104
104
|
item_num=2
|
105
105
|
if len(items) == 0:
|
106
|
-
print(" #Error(): no analytical item found",items)
|
106
|
+
print(" #Error(compare_history): no analytical item found",items)
|
107
107
|
return None,None
|
108
108
|
else:
|
109
109
|
item1=items
|
@@ -260,21 +260,21 @@ if __name__ == '__main__':
|
|
260
260
|
|
261
261
|
#==============================================================================
|
262
262
|
if __name__ == '__main__':
|
263
|
-
|
263
|
+
ticker=['AAPL','MSFT','WMT']
|
264
264
|
itemk='Current Ratio'
|
265
265
|
itemk='Employees'
|
266
|
+
indicator=itemk='PEG'
|
266
267
|
|
267
268
|
multicolor=False
|
268
269
|
|
269
270
|
tickers=['AMZN','EBAY']
|
270
271
|
itemk='IGR'
|
272
|
+
|
271
273
|
datatag=True
|
272
274
|
tag_offset=0.01
|
273
275
|
graph=True
|
274
276
|
axisamp=1.3
|
275
277
|
|
276
|
-
|
277
|
-
itemk='IGR'
|
278
278
|
|
279
279
|
def compare_snapshot(ticker,indicator, \
|
280
280
|
facecolor='lightblue',
|
@@ -340,13 +340,18 @@ def compare_snapshot(ticker,indicator, \
|
|
340
340
|
'TTM Price to Sales':'priceToSalesTrailing12Months', \
|
341
341
|
'beta':'beta','52-Week Change':'52WeekChange', \
|
342
342
|
'Trailing PE':'trailingPE','Forward PE':'forwardPE', \
|
343
|
-
'PEG':'pegRatio'
|
344
|
-
#'IGR':'IGR','SGR':'SGR'
|
343
|
+
#'PEG':'pegRatio',#经常取不到数据
|
344
|
+
#'IGR':'IGR','SGR':'SGR',#另起其他命令处理
|
345
345
|
}
|
346
|
+
|
346
347
|
itemlist=list(itemdict.keys())
|
347
348
|
if itemk not in itemlist:
|
348
349
|
print(" #Error(compare_snapshot): unsupported indicator",itemk)
|
349
|
-
print(" Supported
|
350
|
+
#print(" Supported indicators:\n",itemlist)
|
351
|
+
print(" Supported indicators:")
|
352
|
+
#printInLine(itemlist,numberPerLine=5,leadingBlanks=2)
|
353
|
+
printInLine_md(itemlist,numberPerLine=5,colalign='left',font_size='16px')
|
354
|
+
|
350
355
|
return None
|
351
356
|
|
352
357
|
item=itemdict[itemk]
|
@@ -357,7 +362,7 @@ def compare_snapshot(ticker,indicator, \
|
|
357
362
|
|
358
363
|
notfoundlist=[]
|
359
364
|
total0=len(tickers)
|
360
|
-
print("Searching
|
365
|
+
print(" Searching",itemk,"for specified stocks ...")
|
361
366
|
for t in tickers:
|
362
367
|
|
363
368
|
current=tickers.index(t)
|
@@ -394,9 +399,9 @@ def compare_snapshot(ticker,indicator, \
|
|
394
399
|
except:
|
395
400
|
df=df._append(row,ignore_index=True)
|
396
401
|
|
397
|
-
# 尝试恢复失败的股票信息
|
402
|
+
# 尝试恢复失败的股票信息 1
|
398
403
|
if len(notfoundlist) > 0:
|
399
|
-
print("Recovering info of",itemk,"for",notfoundlist,"...")
|
404
|
+
print("\n Recovering info of",itemk,"for",notfoundlist,"...")
|
400
405
|
total0=len(notfoundlist)
|
401
406
|
tickers2=notfoundlist.copy(); notfoundlist=[]
|
402
407
|
for t in tickers2:
|
@@ -430,11 +435,49 @@ def compare_snapshot(ticker,indicator, \
|
|
430
435
|
df=df.append(row,ignore_index=True)
|
431
436
|
except:
|
432
437
|
df=df._append(row,ignore_index=True)
|
438
|
+
|
439
|
+
|
440
|
+
# 尝试恢复失败的股票信息 2
|
441
|
+
if len(notfoundlist) > 0:
|
442
|
+
print("\n Recovering info of",itemk,"for",notfoundlist,"...")
|
443
|
+
total0=len(notfoundlist)
|
444
|
+
tickers3=notfoundlist.copy(); notfoundlist=[]
|
445
|
+
for t in tickers3:
|
446
|
+
|
447
|
+
current=tickers3.index(t)
|
448
|
+
total=total0 - len(notfoundlist)
|
449
|
+
print_progress_percent(current,total,steps=10,leading_blanks=2)
|
450
|
+
|
451
|
+
try:
|
452
|
+
info=stock_info(t)
|
453
|
+
except:
|
454
|
+
notfoundlist=notfoundlist+[t]
|
455
|
+
continue
|
456
|
+
if (info is None) or (len(info)==0):
|
457
|
+
notfoundlist=notfoundlist+[t]
|
458
|
+
continue
|
459
|
+
try:
|
460
|
+
value=info[info.index == item]['Value'][0]
|
461
|
+
except:
|
462
|
+
try:
|
463
|
+
itemp=proxydict[item]
|
464
|
+
value=info[info.index == itemp]['Value'][0]
|
465
|
+
notfoundlist=notfoundlist+[t]
|
466
|
+
except:
|
467
|
+
notfoundlist=notfoundlist+[t]
|
468
|
+
continue
|
469
|
+
|
470
|
+
name=ticker_name(t)
|
471
|
+
row=pd.Series({'ticker':t,'item':item,'value':value,'name':name})
|
472
|
+
try:
|
473
|
+
df=df.append(row,ignore_index=True)
|
474
|
+
except:
|
475
|
+
df=df._append(row,ignore_index=True)
|
433
476
|
|
434
477
|
# 未找到任何股票信息
|
435
478
|
if len(df) == 0:
|
436
|
-
print("\n #Warning(compare_snapshot): no stock info
|
437
|
-
print(" Possible reasons:
|
479
|
+
print("\n #Warning(compare_snapshot): no stock info found for specified stocks")
|
480
|
+
print(" Possible reasons: failed to access to or fetch info from Yahoo Finance")
|
438
481
|
return None
|
439
482
|
|
440
483
|
#处理小数点
|
@@ -448,12 +491,12 @@ def compare_snapshot(ticker,indicator, \
|
|
448
491
|
|
449
492
|
#绘图
|
450
493
|
if graph:
|
451
|
-
print(" Calculating and
|
494
|
+
print(" Calculating and rendering graph, please wait ...")
|
452
495
|
colname='value'
|
453
496
|
|
454
497
|
lang=check_language()
|
455
498
|
if lang == 'Chinese':
|
456
|
-
titletxt="
|
499
|
+
titletxt="企业对比: 指标快照"
|
457
500
|
notestxt="注:财务指标为TTM数值"
|
458
501
|
else:
|
459
502
|
titletxt="Company Snapshot Comparison"
|
@@ -475,7 +518,7 @@ def compare_snapshot(ticker,indicator, \
|
|
475
518
|
plot_barh(df,colname,titletxt,footnote,datatag=datatag,tag_offset=tag_offset,axisamp=axisamp)
|
476
519
|
else:
|
477
520
|
#在Spyder中可能无法显示
|
478
|
-
titletxt="
|
521
|
+
titletxt="企业快照:"+ectranslate(itemk)
|
479
522
|
footnote=notestxt+','+footnote1+str(today)
|
480
523
|
plot_barh2(df,colname,titletxt,footnote,facecolor=facecolor)
|
481
524
|
|
@@ -506,11 +549,15 @@ if __name__ == '__main__':
|
|
506
549
|
df=compare_snapshot(tickers,itemk)
|
507
550
|
|
508
551
|
#==============================================================================
|
509
|
-
def compare_snapshot2(
|
552
|
+
def compare_snapshot2(ticker,indicator,graph=True):
|
510
553
|
"""
|
511
554
|
功能:比较多个股票的快照数据,绘制水平柱状图
|
512
555
|
itemk需要通过对照表转换为内部的item
|
556
|
+
|
557
|
+
特点:与compare_snapshot相比如何?
|
513
558
|
"""
|
559
|
+
tickers=ticker; itemk=indicator
|
560
|
+
|
514
561
|
#检查股票代码列表
|
515
562
|
if not isinstance(tickers,list):
|
516
563
|
print(" #Error(compare_snapshot2): need more stock codes in",tickers)
|
@@ -553,10 +600,11 @@ def compare_snapshot2(tickers,itemk,graph=True):
|
|
553
600
|
'EV to Revenue':'enterpriseToRevenue','EV to EBITDA':'enterpriseToEbitda', \
|
554
601
|
#市场看法
|
555
602
|
'Current Price':'currentPrice','Price to Book':'priceToBook', \
|
556
|
-
'TTM Price to Sales':'priceToSalesTrailing12Months', \
|
603
|
+
#'TTM Price to Sales':'priceToSalesTrailing12Months', \
|
604
|
+
'Price to Sales':'priceToSalesTrailing12Months', \
|
557
605
|
'beta':'beta','52-Week Change':'52WeekChange', \
|
558
606
|
'Trailing PE':'trailingPE','Forward PE':'forwardPE', \
|
559
|
-
'PEG':'pegRatio',
|
607
|
+
#'PEG':'pegRatio',
|
560
608
|
#'IGR':'IGR','SGR':'SGR'
|
561
609
|
}
|
562
610
|
itemlist=list(itemdict.keys())
|
@@ -569,7 +617,10 @@ def compare_snapshot2(tickers,itemk,graph=True):
|
|
569
617
|
import pandas as pd
|
570
618
|
#import siat.stock_base as sb
|
571
619
|
df=pd.DataFrame(columns=('ticker','item','value','name'))
|
620
|
+
print(f" Working on {indicator} for specified stocks ...")
|
572
621
|
for t in tickers:
|
622
|
+
print_progress_percent2(t,tickers,steps=5,leading_blanks=4)
|
623
|
+
|
573
624
|
try:
|
574
625
|
info=stock_info(t)
|
575
626
|
except:
|
@@ -611,14 +662,14 @@ def compare_snapshot2(tickers,itemk,graph=True):
|
|
611
662
|
|
612
663
|
#绘图
|
613
664
|
if graph:
|
614
|
-
print("
|
665
|
+
print(" Calculating and rendering graph, please wait ...")
|
615
666
|
|
616
667
|
df.rename(columns={'value':itemk},inplace=True)
|
617
668
|
colname=itemk
|
618
669
|
#titletxt="企业横向对比: "+ectranslate(itemk)+"(TTM)"
|
619
|
-
titletxt="
|
670
|
+
titletxt=text_lang("企业对比: ","Comparing Company: ")+ectranslate(itemk)
|
620
671
|
import datetime; today=datetime.date.today()
|
621
|
-
footnote="注:财务比率为TTM,数据来源: 雅虎财经, "+str(today)
|
672
|
+
footnote=text_lang("注:财务比率为TTM,数据来源: 雅虎财经, ","Note: TTM data, source: Yahoo Finance, ")+str(today)
|
622
673
|
plot_barh2(df,colname,titletxt,footnote)
|
623
674
|
|
624
675
|
return df
|
@@ -632,10 +683,12 @@ if __name__ == '__main__':
|
|
632
683
|
tickers=["0883.HK","0857.HK","0386.HK",'XOM','2222.SR','OXY','BP','RDSA.AS']
|
633
684
|
graph=True
|
634
685
|
|
635
|
-
def compare_tax(
|
686
|
+
def compare_tax(ticker,graph=True,axisamp=1.3,px=True):
|
636
687
|
"""
|
637
688
|
功能:比较公司最新的实际所得税率
|
638
689
|
"""
|
690
|
+
tickers=ticker
|
691
|
+
|
639
692
|
#检查股票代码列表
|
640
693
|
if not isinstance(tickers,list):
|
641
694
|
print(" #Error(compare_tax): need more stock codes in",tickers)
|
@@ -647,7 +700,10 @@ def compare_tax(tickers,graph=True,axisamp=1.3,px=True):
|
|
647
700
|
import siat.beta_adjustment as badj
|
648
701
|
import pandas as pd
|
649
702
|
df=pd.DataFrame(columns=('ticker','name','date','tax rate'))
|
703
|
+
print(" Working on tax info for specified stocks ...")
|
650
704
|
for t in tickers:
|
705
|
+
print_progress_percent2(t,tickers,steps=5,leading_blanks=4)
|
706
|
+
|
651
707
|
try:
|
652
708
|
df0=badj.prepare_hamada_yahoo(t)
|
653
709
|
except:
|
@@ -668,15 +724,15 @@ def compare_tax(tickers,graph=True,axisamp=1.3,px=True):
|
|
668
724
|
df.set_index('key',inplace=True)
|
669
725
|
#绘图
|
670
726
|
if graph:
|
671
|
-
print("
|
727
|
+
print(" Calculating and rendering graph, please wait ...")
|
672
728
|
lang=check_language()
|
673
729
|
colname='tax rate'
|
674
730
|
if lang == 'Chinese':
|
675
|
-
titletxt="
|
731
|
+
titletxt="企业对比: 实际所得税率"
|
676
732
|
itemk="实际所得税率"
|
677
733
|
source_txt="数据来源: 雅虎财经,"
|
678
734
|
else:
|
679
|
-
titletxt=texttranslate("
|
735
|
+
titletxt=texttranslate("企业对比: 实际税率")
|
680
736
|
itemk=texttranslate("实际所得税率")
|
681
737
|
source_txt=texttranslate("数据来源: 雅虎财经,")
|
682
738
|
|
@@ -697,7 +753,7 @@ def calc_igr_sgr(ticker):
|
|
697
753
|
|
698
754
|
|
699
755
|
import siat.stock as stk
|
700
|
-
sub_info=stk.get_stock_profile(ticker,info_type='fin_rates',
|
756
|
+
sub_info=stk.get_stock_profile(ticker,info_type='fin_rates',printout=False)
|
701
757
|
"""
|
702
758
|
#应对各种出错情形:执行出错,返回NoneType,返回空值
|
703
759
|
try:
|
@@ -733,10 +789,12 @@ def calc_igr_sgr(ticker):
|
|
733
789
|
|
734
790
|
return igr,sgr
|
735
791
|
|
736
|
-
def compare_igr_sgr(
|
792
|
+
def compare_igr_sgr(ticker,graph=True,axisamp=1.0,px=True):
|
737
793
|
"""
|
738
794
|
功能:比较公司TTM的IGR和SGR
|
739
795
|
"""
|
796
|
+
tickers=ticker
|
797
|
+
|
740
798
|
#检查股票代码列表
|
741
799
|
if not isinstance(tickers,list):
|
742
800
|
print(" #Error(compare_igr_sgr): need more stock codes in",tickers)
|
@@ -747,7 +805,10 @@ def compare_igr_sgr(tickers,graph=True,axisamp=1.0,px=True):
|
|
747
805
|
|
748
806
|
import pandas as pd
|
749
807
|
df=pd.DataFrame(columns=('ticker','name','date','IGR','SGR'))
|
808
|
+
print(" Working on IGR & SGR for specified stocks ...")
|
750
809
|
for t in tickers:
|
810
|
+
print_progress_percent2(t,tickers,steps=5,leading_blanks=4)
|
811
|
+
|
751
812
|
try:
|
752
813
|
igr,sgr=calc_igr_sgr(t)
|
753
814
|
except:
|
@@ -770,11 +831,11 @@ def compare_igr_sgr(tickers,graph=True,axisamp=1.0,px=True):
|
|
770
831
|
#绘图
|
771
832
|
lang=check_language()
|
772
833
|
if graph:
|
773
|
-
print("\n
|
834
|
+
print("\n Calculating and rendering graph, please wait ...")
|
774
835
|
|
775
836
|
colname='IGR'
|
776
837
|
if lang == "Chinese":
|
777
|
-
titletxt="
|
838
|
+
titletxt="企业对比: 内部增长率IGR"
|
778
839
|
itemk="内部增长率(IGR)"
|
779
840
|
source_txt="数据来源: 雅虎财经,"
|
780
841
|
else:
|
@@ -798,7 +859,7 @@ def compare_igr_sgr(tickers,graph=True,axisamp=1.0,px=True):
|
|
798
859
|
if graph:
|
799
860
|
colname='SGR'
|
800
861
|
if lang == 'Chinese':
|
801
|
-
titletxt="
|
862
|
+
titletxt="企业对比: 可持续增长率SGR"
|
802
863
|
itemk="可持续增长率(SGR)"
|
803
864
|
else:
|
804
865
|
titletxt="Company Sustainable Growth Rate (SGR TTM)"
|
@@ -837,11 +898,11 @@ def get_PE(fsdf):
|
|
837
898
|
import siat.security_prices as ssp
|
838
899
|
prices=ssp.get_price(ticker, fromdate, todate)
|
839
900
|
if prices is None:
|
840
|
-
print("#Error(get_PE): retrieving stock price failed for",ticker,fromdate,todate,"\b, recovering...")
|
901
|
+
print(" #Error(get_PE): retrieving stock price failed for",ticker,fromdate,todate,"\b, recovering...")
|
841
902
|
import time; time.sleep(5)
|
842
903
|
prices=ssp.get_price(ticker, fromdate, todate)
|
843
904
|
if prices is None:
|
844
|
-
print("#Error(get_PE): failed retrieving stock price, retrying stopped")
|
905
|
+
print(" #Error(get_PE): failed retrieving stock price, retrying stopped")
|
845
906
|
import numpy as np
|
846
907
|
fsdf['BasicPE']=np.nan
|
847
908
|
fsdf['DilutedPE']=np.nan
|
@@ -916,13 +977,13 @@ def calc_DebtToAsset(fsdf):
|
|
916
977
|
try:
|
917
978
|
fsdf1['Debt to Asset']=round(fsdf1['TotalLiabilities']/fsdf1['TotalAssets'],4)
|
918
979
|
except:
|
919
|
-
print("#Error(get_DebtToAsset): failed in calculating DebtToAsset")
|
980
|
+
print(" #Error(get_DebtToAsset): failed in calculating DebtToAsset")
|
920
981
|
|
921
982
|
#计算Debt to Equity
|
922
983
|
try:
|
923
984
|
fsdf1['Debt to Equity']=round(fsdf1['TotalLiabilities']/fsdf1['TotalEquities'],4)
|
924
985
|
except:
|
925
|
-
print("#Error(get_DebtToAsset): failed in calculating DebtToEquity")
|
986
|
+
print(" #Error(get_DebtToAsset): failed in calculating DebtToEquity")
|
926
987
|
|
927
988
|
return fsdf1
|
928
989
|
|
@@ -1123,13 +1184,13 @@ def get_financial_rates(ticker):
|
|
1123
1184
|
try:
|
1124
1185
|
fsdf=get_financial_statements(ticker)
|
1125
1186
|
except:
|
1126
|
-
print("
|
1187
|
+
print(" Failed to get financial statements of",ticker,"\b, recovering")
|
1127
1188
|
import time; time.sleep(5)
|
1128
1189
|
try:
|
1129
1190
|
fsdf=get_financial_statements(ticker)
|
1130
1191
|
except:
|
1131
|
-
print("
|
1132
|
-
print("
|
1192
|
+
print(" Failed to get financial statements of",ticker,"\b!")
|
1193
|
+
print(" If the stock code",ticker,"\b is correct, please try a few minutes later.")
|
1133
1194
|
return None
|
1134
1195
|
|
1135
1196
|
#抓取股票的稀释后EPS,计算财务比率
|
@@ -1933,13 +1994,25 @@ def compare_dupont(tickerlist,fsdate='latest', \
|
|
1933
1994
|
name4 = '净资产收益率'
|
1934
1995
|
name5 = '财报日期'
|
1935
1996
|
name6 = '财报类型'
|
1997
|
+
|
1998
|
+
import os, sys
|
1999
|
+
class HiddenPrints:
|
2000
|
+
def __enter__(self):
|
2001
|
+
self._original_stdout = sys.stdout
|
2002
|
+
sys.stdout = open(os.devnull, 'w')
|
2003
|
+
|
2004
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
2005
|
+
sys.stdout.close()
|
2006
|
+
sys.stdout = self._original_stdout
|
1936
2007
|
|
1937
2008
|
dpidflist,dpilist,fsdatelist,fstypelist=[],[],[],[]
|
1938
2009
|
name1list,name2list,name3list,name4list,name5list,name6list=[],[],[],[],[],[]
|
1939
2010
|
newtickerlist=[]
|
2011
|
+
print("Working on DuPont factsheet for specified stocks ...")
|
1940
2012
|
for t in tickerlist:
|
1941
2013
|
try:
|
1942
|
-
|
2014
|
+
with HiddenPrints():
|
2015
|
+
dpidf=calc_dupont(t)
|
1943
2016
|
except:
|
1944
2017
|
print(" #Warning(compare_dupont): lack of some accounting items for",t)
|
1945
2018
|
continue
|
@@ -1966,6 +2039,9 @@ def compare_dupont(tickerlist,fsdate='latest', \
|
|
1966
2039
|
name4list=name4list+[dpi['ROE'][0]]
|
1967
2040
|
name5list=name5list+[dpi['endDate'][0]]
|
1968
2041
|
name6list=name6list+[dpi['periodType'][0]]
|
2042
|
+
|
2043
|
+
#显示进度
|
2044
|
+
print_progress_percent2(t,tickerlist,steps=5,leading_blanks=4)
|
1969
2045
|
|
1970
2046
|
tickerlist=newtickerlist
|
1971
2047
|
raw_data = {ticker:tickerlist,
|
@@ -1985,14 +2061,18 @@ def compare_dupont(tickerlist,fsdate='latest', \
|
|
1985
2061
|
# 排序
|
1986
2062
|
if sort=='PM':
|
1987
2063
|
df.sort_values(name1,ascending=False,inplace=True)
|
2064
|
+
sorttxt=text_lang(":按照"+name1+"降序排列",": By Descending"+name1)
|
1988
2065
|
elif sort=='TAT':
|
1989
2066
|
df.sort_values(name2,ascending=False,inplace=True)
|
2067
|
+
sorttxt=text_lang(":按照"+name2+"降序排列",": By Descending"+name2)
|
1990
2068
|
elif sort=='EM':
|
1991
2069
|
df.sort_values(name3,ascending=False,inplace=True)
|
2070
|
+
sorttxt=text_lang(":按照"+name3+"降序排列",": By Descending"+name3)
|
1992
2071
|
else:
|
1993
2072
|
df.sort_values(name1,ascending=False,inplace=True)
|
2073
|
+
sorttxt=text_lang(":按照"+name1+"降序排列",": By Descending"+name1)
|
1994
2074
|
|
1995
|
-
|
2075
|
+
# 绘图
|
1996
2076
|
#f,ax1 = plt.subplots(1,figsize=(10,5))
|
1997
2077
|
f,ax1 = plt.subplots(1,figsize=(12.8,6.4))
|
1998
2078
|
w = 0.75
|
@@ -2053,9 +2133,9 @@ def compare_dupont(tickerlist,fsdate='latest', \
|
|
2053
2133
|
|
2054
2134
|
plt.legend(loc='best',fontsize=legend_txt_size)
|
2055
2135
|
if lang == 'Chinese':
|
2056
|
-
plt.title("杜邦分析对比图",fontsize=title_txt_size,fontweight='bold')
|
2136
|
+
plt.title("杜邦分析对比图"+sorttxt,fontsize=title_txt_size,fontweight='bold')
|
2057
2137
|
else:
|
2058
|
-
plt.title(texttranslate("杜邦分析对比图"),fontsize=title_txt_size,fontweight='bold')
|
2138
|
+
plt.title(texttranslate("杜邦分析对比图")+sorttxt,fontsize=title_txt_size,fontweight='bold')
|
2059
2139
|
plt.xlim([min(tick_pos)-w,max(tick_pos)+w])
|
2060
2140
|
|
2061
2141
|
plt.gca().set_facecolor('whitesmoke')
|
siat/stock.py
CHANGED
@@ -125,8 +125,8 @@ def get_profile(ticker):
|
|
125
125
|
tp=yf.Ticker(ticker1)
|
126
126
|
try:
|
127
127
|
dic=tp.info
|
128
|
-
except:
|
129
|
-
print(" #Error(get_profile):
|
128
|
+
except ValueError as e:
|
129
|
+
print(" #Error(get_profile): {e} when processing",ticker)
|
130
130
|
return None
|
131
131
|
|
132
132
|
#将字典转换为数据框
|
@@ -346,7 +346,7 @@ def stock_profile(ticker,option='basic',verbose=False):
|
|
346
346
|
返回:证券快照信息数据表。
|
347
347
|
注意:放弃
|
348
348
|
"""
|
349
|
-
print("
|
349
|
+
print(" Searching for security snapshot information, please wait ...")
|
350
350
|
#抓取证券静态信息
|
351
351
|
try:
|
352
352
|
df=get_profile(ticker)
|
@@ -2973,7 +2973,9 @@ def stock_info(symbol):
|
|
2973
2973
|
if result & (suffix=='HK'):
|
2974
2974
|
symbol=prefix[-4:]+'.'+suffix
|
2975
2975
|
|
2976
|
-
from yahooquery import Ticker
|
2976
|
+
from yahooquery import Ticker
|
2977
|
+
#如果出现类似于{'AAPL': 'Invalid Cookie'}错误,则需要升级yahooquery
|
2978
|
+
#如果出现crump相关的错误,则需要更换lxml的版本以便与当前的yahooquery版本匹配
|
2977
2979
|
stock = Ticker(symbol)
|
2978
2980
|
|
2979
2981
|
"""
|
@@ -2996,7 +2998,7 @@ def stock_info(symbol):
|
|
2996
2998
|
return None
|
2997
2999
|
|
2998
3000
|
if adict[symbol] == 'Invalid Cookie':
|
2999
|
-
print(" #Error(stock_info): failed in retrieving info of",symbol,"\b. Try upgrade yahooquery and
|
3001
|
+
print(" #Error(stock_info): failed in retrieving info of",symbol,"\b. Try upgrade yahooquery and run again")
|
3000
3002
|
return None
|
3001
3003
|
|
3002
3004
|
keylist=list(adict[symbol].keys())
|
@@ -3524,7 +3526,7 @@ def get_stock_profile(ticker,info_type='basic',printout=True):
|
|
3524
3526
|
try:
|
3525
3527
|
info=stock_info(ticker)
|
3526
3528
|
except:
|
3527
|
-
print(" #Warning(get_stock_profile):
|
3529
|
+
print(" #Warning(get_stock_profile): recovering info for",ticker,"...")
|
3528
3530
|
import time; time.sleep(5)
|
3529
3531
|
try:
|
3530
3532
|
info=stock_info(ticker)
|
siat/translate.py
CHANGED
@@ -156,7 +156,7 @@ def ectranslate_c(eword):
|
|
156
156
|
['exchangeTimezoneShortName','交易所时区简称'],['quoteType','证券类别'],
|
157
157
|
['symbol','证券代码'],['messageBoardId','证券留言板编号'],
|
158
158
|
['market','证券市场'],['annualHoldingsTurnover','一年內转手率'],
|
159
|
-
['enterpriseToRevenue','市售率(EV/Revenue)'],['EV to Revenue','
|
159
|
+
['enterpriseToRevenue','市售率(EV/Revenue)'],['EV to Revenue','企业价值收入比'],
|
160
160
|
['Price to Book','市净率'],['beta3Year','3年贝塔系数'],
|
161
161
|
['profitMargins','净利润率'],['enterpriseToEbitda','企业价值/EBITDA'],
|
162
162
|
['EV to EBITDA','企业价值倍数(EV/EBITDA)'],
|
@@ -212,7 +212,8 @@ def ectranslate_c(eword):
|
|
212
212
|
['BasicEPS','基本每股收益'],['Cashflow per Share','每股现金流量'],
|
213
213
|
['Profit Margin','净利润率'],['Gross Margin','毛利润率'],
|
214
214
|
['EBITDA Margin','EBITDA利润率'],['Operating Margin','营业利润率'],
|
215
|
-
['Trailing EPS','每股收益TTM'],['
|
215
|
+
['Trailing EPS','每股收益TTM'],['Forward EPS','预期每股收益'],
|
216
|
+
['Trailing PE','市盈率TTM'],['Forward PE','预期市盈率'],
|
216
217
|
['Revenue Growth','销售收入增长率'],['Earnings Growth','年度盈余增长率'],
|
217
218
|
['Earnings Quarterly Growth','季度盈余增长率'],
|
218
219
|
['IGR','内部增长率(IGR)'],['SGR','可持续增长率(SGR)'],
|
@@ -507,7 +508,8 @@ def ectranslate_e(eword):
|
|
507
508
|
['BasicEPS','Basic EPS'],['Cashflow per Share','Cashflow per share'],
|
508
509
|
['Profit Margin','Profit margins'],['Gross Margin','Gross margins'],
|
509
510
|
['EBITDA Margin','EBITDA margins'],['Operating Margin','Operating margins'],
|
510
|
-
['Trailing EPS','EPS TTM'],['
|
511
|
+
['Trailing EPS','EPS TTM'],['Forward EPS','Forward EPS'],
|
512
|
+
['Trailing PE','PE TTM'],['Forward PE','Forward PE'],
|
511
513
|
['Revenue Growth','Revenue growth'],['Earnings Growth','Earnings growth(annual)'],
|
512
514
|
['Earnings Quarterly Growth','Earnings growth(quarterly)'],
|
513
515
|
['IGR','Internal growth rate'],['SGR','Sustainable growth rate'],
|
@@ -1,5 +1,5 @@
|
|
1
1
|
siat/__init__ -20240701.py,sha256=gP5uajXnJesnH5SL0ZPwq_Qhv59AG1bs4qwZv26Fo2Y,2894
|
2
|
-
siat/__init__.py,sha256=
|
2
|
+
siat/__init__.py,sha256=tpSBf8BYpWOzBDF2iNQ4tlVxjx7bmkVQ3kPUu9X3iog,2227
|
3
3
|
siat/__init__.py.backup_20250214.py,sha256=pIo4CV3lNPKIhitmhIh_6aAfZrmzQWGNDcEnvZ7GXoc,3216
|
4
4
|
siat/allin.py,sha256=9xwa97S6KPHXGuqDtyN9b6Y4lCSM1VdBqpFBrlRvV8I,3001
|
5
5
|
siat/alpha_vantage_test.py,sha256=tKr-vmuFH3CZAqwmISz6jzjPHzV1JJl3sPfZdz8aTfM,747
|
@@ -42,7 +42,7 @@ siat/fin_stmt2_yahoo.py,sha256=LGmspk0nKyz4X87MtcovZXUfMQkAvrWINuxR4HQ8PI8,41178
|
|
42
42
|
siat/financial_base.py,sha256=A1rV7XQOVFpCXCV-T6Ge0QeF897hINiu0olN1XWeaFk,41287
|
43
43
|
siat/financial_statements.py,sha256=xx0SMpFqAMKm6cj8uYeG2RpJE6G-RoJ3NWa33UyaVMk,25414
|
44
44
|
siat/financial_statements_test.py,sha256=FLhx8JD-tVVWSBGux6AMz1jioXX4U4bp9DmgFHYXb_w,716
|
45
|
-
siat/financials.py,sha256=
|
45
|
+
siat/financials.py,sha256=fYnMF66xkO0DKSzDoXRb3acYQUYkepXaM5SG6e8gEeY,86168
|
46
46
|
siat/financials2 - 副本.py,sha256=dKlNjIfKeoSy055fQ6E6TUj9HEoO5Ney9grD84J5kfk,14389
|
47
47
|
siat/financials2.py,sha256=YF-A-5iSTzLXTFI0sDGju4_6T87wWC9IlFd4fSXbJXw,50805
|
48
48
|
siat/financials_china.py,sha256=Hu85JOKnCmcTHgblIvHhsV-6c-Y15HFGNR_ZaaJt8nM,191974
|
@@ -109,7 +109,7 @@ siat/security_trend2-20240620.py,sha256=QVnEcb7AyVbO77jVqfFsJffGXrX8pgJ9xCfoAKmW
|
|
109
109
|
siat/security_trend2.py,sha256=8-Z-PWaX8fjnyAyfxEp3qXdVllgDpRISOASKEn7Zeoc,30706
|
110
110
|
siat/setup.py,sha256=up65rQGLmTBkhtaMLowjoQXYmIsnycnm4g1SYmeQS6o,1335
|
111
111
|
siat/shenwan index history test.py,sha256=JCVAzOSEldHalhSFa3pqD8JI_8_djPMQOxpkuYU-Esg,1418
|
112
|
-
siat/stock.py,sha256=
|
112
|
+
siat/stock.py,sha256=bXG1FIwNTNvzHGNDH3ZNWFmXCMyD5dy-CTsHI2OKGWM,159614
|
113
113
|
siat/stock_advice_linear.py,sha256=-twT7IGP-NEplkL1WPSACcNJjggRB2j4mlAQCkzOAuo,31655
|
114
114
|
siat/stock_base.py,sha256=uISvbRyOGy8p9QREA96CVydgflBkn5L3OXOGKl8oanc,1312
|
115
115
|
siat/stock_china.py,sha256=85Ggb21E2mrCYMdSSTTrkoyyLGXMK2V-BtlweHomSRg,93460
|
@@ -135,7 +135,7 @@ siat/transaction_test.py,sha256=Z8g1LJCN4-mnUByXMUMoFmN0t105cbmsz2QmvSuIkbU,1858
|
|
135
135
|
siat/translate-20230125.py,sha256=NPPSXhT38s5t9fzMvl_fvi4ckSB73ThLmZetVI-xGdU,117953
|
136
136
|
siat/translate-20230206.py,sha256=-vtI125WyaJhmPotOpDAmclt_XnYVaWU9ByLWZ6FyYE,118133
|
137
137
|
siat/translate-20230215.py,sha256=TJgtPE3n8IjljmZ4Pefy8dmHoNdFF-1zpML6BhA9FKE,121657
|
138
|
-
siat/translate.py,sha256=
|
138
|
+
siat/translate.py,sha256=6kIzzzdh04J2BkR2XSnKkl4rTZWSHarW-4AdarTZJvI,262334
|
139
139
|
siat/translate_20240606.py,sha256=63IyHWEU3Uz9mjwyuAX3fqY4nUMdwh0ICQAgmgPXP7Y,215121
|
140
140
|
siat/translate_241003_keep.py,sha256=un7Fqe1v35MXsja5exZgjmLzrZtt66NARZIGlyFuGGU,218747
|
141
141
|
siat/universal_test.py,sha256=CDAOffW1Rvs-TcNN5giWVvHMlch1w4dp-w5SIV9jXL0,3936
|
@@ -144,8 +144,8 @@ siat/valuation_china.py,sha256=eSKIDckyjG8QkENlW_OKkqbQHno8pzDcomBO9iGNJVM,83079
|
|
144
144
|
siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
|
145
145
|
siat/var_model_validation.py,sha256=R0caWnuZarrRg9939hxh3vJIIpIyPfvelYmzFNZtPbo,14910
|
146
146
|
siat/yf_name.py,sha256=laNKMTZ9hdenGX3IZ7G0a2RLBKEWtUQJFY9CWuk_fp8,24058
|
147
|
-
siat-3.8.
|
148
|
-
siat-3.8.
|
149
|
-
siat-3.8.
|
150
|
-
siat-3.8.
|
151
|
-
siat-3.8.
|
147
|
+
siat-3.8.42.dist-info/LICENSE,sha256=NTEMMROY9_4U1szoKC3N2BLHcDd_o5uTgqdVH8tbApw,1071
|
148
|
+
siat-3.8.42.dist-info/METADATA,sha256=fXxjQCNXJFoLw_cm0qw_P46eOWOqLHrXZsvxJ-F5-6g,8321
|
149
|
+
siat-3.8.42.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
150
|
+
siat-3.8.42.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
|
151
|
+
siat-3.8.42.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|