siat 3.7.7__py3-none-any.whl → 3.7.9__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/financials2.py CHANGED
@@ -104,17 +104,38 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
104
104
  category='profile',business_period='annual', \
105
105
  scale1=10,scale2=10,dupont_sort='PM',
106
106
  printout=True, \
107
- entry_sort=False, \
107
+ #entry_sort=False, \
108
108
  facecolor='papayawhip',font_size='16px'
109
109
  ):
110
110
  """
111
- 功能:tickers为股票列表,fsdates为财报日期,可为单个日期或日期列表
111
+
112
+ 功能:分析境外上市公司财报信息
113
+
114
+ 参数:
115
+ tickers:股票列表,对比分析时需要多个股票,单列财报时仅取第一个股票
116
+ fsdates:财报日期,可为单个日期或日期列表,注意境外上市公司财报日期与中国大陆的不同
117
+
118
+ analysis_type:分析类型,可为企业概况('profile')、资产负债表简表('balance sheet')、
119
+ 利润表简表('income statement')、现金流量表简表('cash flow')、财报概况('financial summary')、
120
+ 财务比率('financial indicator')、杜邦分析('dupont identity')
121
+
122
+ category:企业概况分类,,仅当analysis_type='profile'时有效,
123
+ 可为基本信息'profile'、高管概况('officers')、分红('dividend')、股票分拆('split')、市场表现('market')、
124
+ 财务状况('financial')、一般风险('risk')、ESG风险('esg')
125
+
126
+ business_period:业务期间类型,可为季报'quarterly',年报'annual'、最近的6次报告'recent', 所有'all'
127
+ scale1:仅用于杜邦分析,放大倍数(以便缩小与EM之间的数量级差异),用于Profit Margin,默认10
128
+ scale2:仅用于杜邦分析,放大倍数,用于Total Asset Turnover,默认10
129
+ dupont_sort:仅用于杜邦分析,用于排序指标,默认净利润率'PM',还可为总资产周转率'TAT'或权益乘数'EM'
130
+ printout:是否显示数据表,默认是True
131
+ facecolor:背景颜色,默认小麦黄'papayawhip'
132
+ font_size:标题字体大小,默认'16px'
133
+
112
134
  注意1:仅从雅虎财经获取数据
113
135
  注意2:不同经济体上市公司报表币种可能不同,金额项目仅进行同公司对比,不进行公司间对比
114
- 注意3:公司间仅对比财务比率
136
+ 注意3:公司间仅对比财务比率和杜邦分析
115
137
  注意4:不同经济体上市公司年报季报日期不同,需要列示报表日期和类型(年报或季报)
116
-
117
- business_period:取季报'quarterly',年报'annual',最近的6次报告'recent', 所有'all'
138
+
118
139
  """
119
140
  import numpy as np
120
141
 
@@ -177,9 +198,11 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
177
198
  info=get_stock_profile(tickers,info_type=category)
178
199
 
179
200
  elif contains_any(category,['risk']):
201
+ #这里的是风险指标,数值越大风险越高,数值越小越好
180
202
  category='risk_general'
181
203
  info=get_stock_profile(tickers,info_type=category)
182
204
  elif contains_any(category,['esg']):
205
+ #这里的ESG为风险指标,数值越大风险越高,数值越小越好
183
206
  category='risk_esg'
184
207
  info=get_stock_profile(tickers,info_type=category)
185
208
  else:
@@ -200,7 +223,7 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
200
223
  # 分析资产负债表
201
224
  fsdf=get_balance_sheet(symbol=tickers)
202
225
  if fsdf is None:
203
- print(" #Warning(fs_analysis): financial info unaccessible for",tickers,"\b, which needs connection to Yahoo Finance")
226
+ print(" #Warning(fs_analysis): financial info unaccessible for",tickers,"\b, which needs connection to Yahoo")
204
227
  return None
205
228
 
206
229
  fsdf['reportDate']=fsdf['asOfDate'].apply(lambda x: x.strftime('%y-%m-%d'))
@@ -245,7 +268,7 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
245
268
  fsdf4.replace(0,'---',inplace=True)
246
269
 
247
270
  #titletxt="\n***** "+ticker_name(tickers)+": BALANCE SHEET"+' *****\n'
248
- titletxt=ticker_name(tickers,'stock')+": BALANCE SHEET"
271
+ titletxt=ticker_name(tickers,'stock')+text_lang(":资产负债简表",": BALANCE SHEET")
249
272
  #print(titletxt)
250
273
  """
251
274
  tablefmt_list=["plain","simple","github","grid","simple_grid","rounded_grid", \
@@ -347,7 +370,7 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
347
370
  fsdf4.replace(0,'---',inplace=True)
348
371
 
349
372
  #titletxt="\n***** "+ticker_name(tickers)+": INCOME STATEMENTS"+' *****\n'
350
- titletxt=ticker_name(tickers,'stock')+": INCOME STATEMENTS"
373
+ titletxt=ticker_name(tickers,'stock')+text_lang(":利润简表",": INCOME STATEMENTS")
351
374
  #print(titletxt)
352
375
 
353
376
  collist=list(fsdf4)
@@ -427,7 +450,7 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
427
450
  fsdf4.replace(0,'---',inplace=True)
428
451
 
429
452
  #titletxt="\n***** "+ticker_name(tickers)+": CASHFLOW STATEMENTS"+' *****\n'
430
- titletxt=ticker_name(tickers,'stock')+": CASHFLOW STATEMENTS"
453
+ titletxt=ticker_name(tickers,'stock')+text_lang(":现金流量简表",": CASHFLOW STATEMENTS")
431
454
  #print(titletxt)
432
455
 
433
456
  collist=list(fsdf4)
@@ -536,7 +559,7 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
536
559
  fsdf4.replace(0,'---',inplace=True)
537
560
 
538
561
  #titletxt="\n***** "+ticker_name(tickers)+": FINANCIAL STATEMENT SUMMARY"+' *****\n'
539
- titletxt=ticker_name(tickers,'stock')+": FINANCIAL STATEMENT SUMMARY"
562
+ titletxt=ticker_name(tickers,'stock')+text_lang(":财报摘要",": FINANCIAL STATEMENT SUMMARY")
540
563
  #print(titletxt)
541
564
 
542
565
  collist=list(fsdf4)
@@ -638,7 +661,7 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
638
661
  fsdf4.replace(0,'---',inplace=True)
639
662
 
640
663
  #titletxt="\n***** PEER COMPARISON OF FINANCIAL STATEMENT SUMMARY *****\n"
641
- titletxt="FINANCIAL STATEMENT SUMMARY: PEER COMPARISON"
664
+ titletxt=text_lang("财报摘要对比","FINANCIAL STATEMENT SUMMARY: COMPARISON")
642
665
  #print(titletxt)
643
666
 
644
667
  collist=list(fsdf4)
@@ -746,7 +769,7 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
746
769
  fsdf4.replace(0,'---',inplace=True)
747
770
 
748
771
  #titletxt="\n***** "+ticker_name(tickers)+": FINANCIAL INDICATORS"+' *****\n'
749
- titletxt=ticker_name(tickers,'stock')+": FINANCIAL INDICATORS"
772
+ titletxt=ticker_name(tickers,'stock')+text_lang(":财务比率",": FINANCIAL INDICATORS")
750
773
  #print(titletxt)
751
774
 
752
775
  collist=list(fsdf4)
@@ -849,7 +872,7 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
849
872
  fsdf4.replace(0,'---',inplace=True)
850
873
 
851
874
  #titletxt="\n***** PEER COMPARISON OF FINANCIAL INDICATORS *****\n"
852
- titletxt="FINANCIAL INDICATORS: PEER COMPARISON"
875
+ titletxt=text_lang("财务比率对比","FINANCIAL INDICATORS: COMPARISON")
853
876
  #print(titletxt)
854
877
 
855
878
  collist=list(fsdf4)
@@ -963,21 +986,21 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
963
986
  plt.ylabel("Items (Amplified)")
964
987
 
965
988
  footnote1="[Bar amplifier] "+name1+':x'+str(scale1)+','+name2+':x'+str(scale2)
966
- footnote2='Financial statement period: '+fin_period+'. Bar height does not indicate ROE value.'
989
+ footnote2='Statement period: '+fin_period+'. Bar height does not indicate ROE value.'
967
990
  footnote3="Data source: Yahoo Finance,"+todaydt
968
991
  footnote ='\n'+footnote1+'\n'+footnote2+'\n'+footnote3
969
992
  plt.xlabel(footnote,fontsize=10)
970
993
 
971
994
  plt.legend(loc='best',fontsize=10)
972
- plt.title("Dupont Identity Analysis")
995
+ plt.title(text_lang("杜邦分析对比","Dupont Identity Analysis"))
973
996
  plt.xlim([min(tick_pos)-w,max(tick_pos)+w])
974
997
 
975
- plt.gca().set_facecolor('whitesmoke')
998
+ plt.gca().set_facecolor(facecolor)
976
999
  plt.show()
977
1000
 
978
1001
  if printout:
979
1002
  #title_txt="\n***** Dupont Identity Fact Sheet *****\n"
980
- titletxt="Dupont Identity Fact Sheet"
1003
+ titletxt=text_lang("杜邦分析数据表","Dupont Identity Fact Sheet")
981
1004
  #print(titletxt)
982
1005
 
983
1006
  # 保留四位小数
@@ -998,7 +1021,7 @@ def fs_analysis(tickers,fsdates=[],analysis_type='balance sheet', \
998
1021
  footnote2="Data source: Yahoo Finance, "+str(todaydt)
999
1022
  footnote='Note:\n'+footnote1+'\n'+footnote2
1000
1023
  #print('\n',footnote1,'\b.',footnote2)
1001
- df_display_CSS(df,titletxt=titletxt,footnote=footnote,facecolor=facecolor, \
1024
+ df_display_CSS(df,titletxt=titletxt,footnote=footnote,facecolor=facecolor,decimals=4, \
1002
1025
  titile_font_size=titile_font_size,heading_font_size=heading_font_size, \
1003
1026
  data_font_size=data_font_size)
1004
1027
  return df2
siat/grafix.py CHANGED
@@ -1448,6 +1448,25 @@ def plot_line2_twinx2(df01,ticker1,colname1,label1, \
1448
1448
  return
1449
1449
 
1450
1450
  #==============================================================================
1451
+ if __name__ =="__main__":
1452
+ df0=security_trend(['PDD','JD'],annotate=True,graph=False)
1453
+
1454
+ y_label=''; x_label='Footnote'
1455
+ axhline_value=0; axhline_label=''
1456
+ title_txt='Title'
1457
+ data_label=False
1458
+ resample_freq='H'; smooth=True
1459
+ linewidth=1.5
1460
+ loc='best'
1461
+ annotate=True; annotate_value=True
1462
+ plus_sign=False
1463
+ attention_value=''; attention_value_area=''
1464
+ attention_point=''; attention_point_area=''
1465
+ mark_top=False; mark_bottom=False; mark_end=False
1466
+ ticker_type='auto'
1467
+ facecolor='whitesmoke'
1468
+
1469
+
1451
1470
  def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1452
1471
  data_label=True,resample_freq='H',smooth=True,linewidth=1.5, \
1453
1472
  loc='best',annotate=False,annotate_value=False,plus_sign=False, \
@@ -1758,8 +1777,24 @@ def draw_lines(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
1758
1777
 
1759
1778
  # 若不绘制annotate,则绘制图例
1760
1779
  #if not annotate:
1761
- plt.legend(loc=loc,fontsize=legend_txt_size)
1780
+ #检查是否存在可绘制的标签,若有则绘制
1781
+ if DEBUG:
1782
+ have_label=False
1783
+ for line in plt.gca().lines:
1784
+ print(f" DEBUG: plt.gca().lines, line={line.get_label()}")
1785
+ if line.get_label() != '':
1786
+ have_label=True
1762
1787
 
1788
+ #plt.legend没有图例标签时会提示信息No artists...
1789
+ if not annotate or attention_value !='' or attention_point !='':
1790
+ plt.legend(loc=loc,fontsize=legend_txt_size)
1791
+
1792
+ """
1793
+ if any([line.get_label() != '' for line in plt.gca().lines]):
1794
+ tuli=plt.legend(loc=loc,fontsize=legend_txt_size)
1795
+ if DEBUG:
1796
+ print(f" DEBUG: result of plt.legend is {tuli}")
1797
+ """
1763
1798
  if plus_sign:
1764
1799
  # 尝试改变纵轴刻度格式:给正数添加正号+,以便突出显示增减幅度
1765
1800
  import matplotlib.ticker as ticker
@@ -2072,7 +2107,9 @@ def draw_lines2(df0,y_label,x_label,axhline_value,axhline_label,title_txt, \
2072
2107
  plt.gca().set_facecolor("whitesmoke")
2073
2108
 
2074
2109
  #if not annotate:
2075
- plt.legend(loc=loc,fontsize=legend_txt_size)
2110
+ #plt.legend没有图例标签时会提示信息No artists...
2111
+ if not annotate or attention_value !='' or attention_point !='':
2112
+ plt.legend(loc=loc,fontsize=legend_txt_size)
2076
2113
 
2077
2114
  #设置绘图风格:关闭网格虚线
2078
2115
  plt.rcParams['axes.grid']=False
siat/stock.py CHANGED
@@ -2654,10 +2654,10 @@ def stock_dividend(ticker,start="L3Y",end="today",facecolor='whitesmoke',fontcol
2654
2654
  try:
2655
2655
  div=stock.dividends
2656
2656
  except:
2657
- print(" #Error(stock_dividend): no div info found for",ticker)
2657
+ print(" #Error(stock_dividend): no dividend information found for",ticker)
2658
2658
  return None
2659
2659
  if len(div)==0:
2660
- print(" #Warning(stock_dividend): no div info found for",ticker)
2660
+ print(" #Warning(stock_dividend): no dividend information found for",ticker)
2661
2661
  return None
2662
2662
 
2663
2663
  # 去掉时区信息,避免合并中的日期时区冲突问题
@@ -2795,10 +2795,10 @@ def stock_split(ticker,start="L10Y",end="today",facecolor='whitesmoke',fontcolor
2795
2795
  try:
2796
2796
  div=stock.splits
2797
2797
  except:
2798
- print(" #Error(stock_split): no split info found for",ticker)
2798
+ print(" #Error(stock_split): no split information found for",ticker)
2799
2799
  return None
2800
2800
  if len(div)==0:
2801
- print(" #Warning(stock_split): no split info found for",ticker)
2801
+ print(" #Warning(stock_split): no split information found for",ticker)
2802
2802
  return None
2803
2803
 
2804
2804
  # 去掉时区信息,避免合并中的日期时区冲突问题
@@ -2810,7 +2810,7 @@ def stock_split(ticker,start="L10Y",end="today",facecolor='whitesmoke',fontcolor
2810
2810
  div1=div[div.index >= startdt]
2811
2811
  div2=div1[div1.index <= enddt]
2812
2812
  if len(div2)==0:
2813
- print(" #Warning(stock_split): no split info in period",fromdate,todate)
2813
+ print(" #Warning(stock_split): no split information in period",fromdate,todate)
2814
2814
  return None
2815
2815
 
2816
2816
  #对齐打印
siat/translate.py CHANGED
@@ -4554,6 +4554,306 @@ if __name__=='__main__':
4554
4554
  industry_sw_name(icode)
4555
4555
 
4556
4556
  #==============================================================================
4557
-
4557
+ #实现简单中英文短语互译
4558
+ #==============================================================================
4559
+ if __name__ == '__main__':
4560
+ chntext='市盈率'
4561
+ engtext="PE ratio"
4562
+ engtext="P/E ratio"
4563
+
4564
+ zh2en(chntext)
4565
+
4566
+ en2zh(engtext)
4567
+
4568
+
4569
+ def zh2en(text):
4570
+ '''英文转换成中文'''
4571
+
4572
+ from translate import Translator
4573
+ translator = Translator(from_lang="zh", to_lang="en")
4574
+ translation = translator.translate(text)
4575
+
4576
+ return translation
4577
+
4578
+ def en2zh(text):
4579
+ '''中文转换成英文'''
4580
+
4581
+ from translate import Translator
4582
+ translator = Translator(from_lang="en", to_lang="zh")
4583
+ translation = translator.translate(text)
4584
+
4585
+ return translation
4586
+
4587
+ if __name__ == '__main__':
4588
+ chntext='市盈率'
4589
+ engtext1="PE ratio"
4590
+ engtext2="P/E ratio"
4591
+
4592
+ lang_auto(chntext)
4593
+ lang_auto(engtext1)
4594
+ lang_auto(engtext2)
4595
+
4596
+ lang_auto(text)
4597
+
4598
+
4599
+ def lang_auto(text):
4600
+ '''转换字符串text至当前语言环境,基于translate'''
4601
+
4602
+ #注意:这个翻译模块只能每天提供有限单词翻译服务
4603
+ from translate import Translator
4604
+
4605
+ lang_env=check_language()
4606
+ lang_text=detect_language(text)
4607
+
4608
+ #字符串语言与当前环境语言相同,无需翻译,节省运行时间
4609
+ if lang_env==lang_text:
4610
+ return text
4611
+
4612
+ provider_list=['mymemory']
4613
+
4614
+ if lang_env=='Chinese':
4615
+ #translator = Translator(from_lang="en", to_lang="zh")
4616
+ #translator = Translator(to_lang="zh")
4617
+ translator = Translator(to_lang="zh",provider="mymemory")
4618
+ elif lang_env=='English':
4619
+ translator = Translator(to_lang="en")
4620
+ else:
4621
+ return text
4622
+
4623
+ translation = translator.translate(text)
4624
+
4625
+ return translation
4626
+
4627
+ if __name__ == '__main__':
4628
+ text='市盈率'
4629
+ text='贵州茅台'
4630
+ text='五粮液'
4631
+ text='Dividend Payout Ratio'
4632
+ text='asOfDate'
4633
+ text='Cash And Cash Equivalents'
4634
+ text='AccountsReceivableNetSalesAllowance'
4635
+ text='Accounts Receivable Net of Sales Allowance'
4636
+ text='Accounts Payable'
4637
+
4638
+ language_detect=True
4639
+ language_engine=['google','baidu','bing']
4640
+
4641
+ chntext='市盈率'
4642
+ engtext1="PE ratio"
4643
+ engtext2="P/E ratio"
4644
+
4645
+ lang_auto2(text)
4646
+ lang_auto2(text,language_detect=True)
4647
+
4648
+ lang_auto2(chntext)
4649
+ lang_auto2(engtext1)
4650
+ lang_auto2(engtext2)
4651
+
4652
+
4653
+ def lang_auto2(text,language_detect=True,language_engine=['alibaba','google','bing','sogou']):
4654
+ '''转换字符串text至当前语言环境,基于translators,可指定翻译服务器,准确度更高'''
4655
+
4656
+ import translators as ts
4657
+
4658
+ lang_env=check_language()
4659
+
4660
+ if language_detect:
4661
+ lang_text=detect_language(text)
4662
+
4663
+ #字符串语言与当前环境语言相同,无需翻译,节省运行时间
4664
+ if lang_env==lang_text:
4665
+ return text
4666
+
4667
+ success=False
4668
+ if lang_env=='Chinese':
4669
+ #translator支持baidu/bing/google
4670
+ if isinstance(language_engine,str):
4671
+ language_engine=[language_engine]
4672
+
4673
+ for le in language_engine:
4674
+ try:
4675
+ translation = ts.translate_text(text,from_language='en',to_language='zh', translator=le)
4676
+ success=True
4677
+ break
4678
+ except:
4679
+ continue
4680
+ elif lang_env=='English':
4681
+ for le in language_engine:
4682
+ try:
4683
+ translation = ts.translate_text(text,from_language='zh',to_language='en', translator=le)
4684
+ success=True
4685
+ break
4686
+ except:
4687
+ continue
4688
+ else:
4689
+ return text
4690
+
4691
+ if not success:
4692
+ translation = text
4693
+
4694
+ return translation
4695
+
4696
+
4697
+ if __name__ == '__main__':
4698
+ chntext='市盈率'
4699
+ engtext1="PE ratio"
4700
+
4701
+ detect_language(chntext)
4702
+ detect_language(engtext)
4703
+
4704
+ def detect_language(text):
4705
+ '''判断字符串text是中文还是英文'''
4706
+
4707
+ import re
4708
+ chinese_pattern = re.compile(r'[\u4e00-\u9fa5]')
4709
+ english_pattern = re.compile(r'[a-zA-Z]')
4710
+
4711
+ chinese_count = len(chinese_pattern.findall(text))
4712
+ english_count = len(english_pattern.findall(text))
4713
+ total_count = chinese_count + english_count
4714
+
4715
+ if total_count == 0:
4716
+ result='Unknown'
4717
+
4718
+ if chinese_count > english_count:
4719
+ result='Chinese'
4720
+ elif english_count > chinese_count:
4721
+ result='English'
4722
+ else:
4723
+ result='Both'
4724
+
4725
+ return result
4726
+
4727
+
4728
+ if __name__ == '__main__':
4729
+ text='DividendPayoutRatio'
4730
+ text='CashAndCashEquivalents'
4731
+ text='asOfDate'
4732
+
4733
+ text='GrossPPE'
4734
+
4735
+ text='Cash And Cash Equivalents'
4736
+
4737
+ words_split_yahoo(text)
4738
+
4739
+ def words_split_yahoo(text,split_improve=True):
4740
+ '''将雅虎英文财报术语拆分为带空格的词组'''
4741
+
4742
+
4743
+ #替换基于大写字母无法分词的短语
4744
+ text=text.replace("periodType","PeriodType")
4745
+ text=text.replace("Tradeand","TradeAnd")
4746
+
4747
+ words_list=[]
4748
+ start=0
4749
+
4750
+ for i in range(len(text)):
4751
+ c=text[i]
4752
+
4753
+ if (c>='A' and c<='Z') or c==' ':
4754
+ words_list=words_list+[text[start:i].strip(' ')]
4755
+ start=i
4756
+
4757
+ #添加最后一个单词
4758
+ words_list=words_list+[text[start:i+1]]
4759
+
4760
+ special_words=['and','of','in','at','as','for','non','from']
4761
+ words_list2=[]
4762
+ for w in words_list:
4763
+ if text.index(w) == 0:
4764
+ words_list2=words_list2+[w.title()]
4765
+ elif w.lower() in special_words:
4766
+ words_list2=words_list2+[w.lower()]
4767
+ else:
4768
+ words_list2=words_list2+[w]
4769
+
4770
+ text_new=''
4771
+ for w in words_list2:
4772
+ text_new=text_new+' '+w
4773
+
4774
+ #若出现多个空格则替换为单个空格
4775
+ import re
4776
+ text_new=re.sub(r' +', ' ', text_new)
4777
+
4778
+ #去掉首尾的空格
4779
+ text_new=text_new.strip(' ')
4780
+
4781
+
4782
+ #判断大写字母缩写合并
4783
+ prev_c1=''; prev_c2=''
4784
+ text_new2=''
4785
+ for c in text_new:
4786
+ if c>='A' and c<='Z':
4787
+ if prev_c1==' ' and (prev_c2>='A' and prev_c2<='Z'):
4788
+ text_new2=text_new2.strip(' ')+c
4789
+ else:
4790
+ text_new2=text_new2+c
4791
+ else:
4792
+ text_new2=text_new2+c
4793
+
4794
+ prev_c2=prev_c1; prev_c1=c
4795
+
4796
+ #弥补大写字母合并后继词的逻辑缺陷
4797
+ for upl in ['PPE']:
4798
+ text_new2=text_new2.replace(upl,upl+' ')
4799
+ text_new2=re.sub(r' +', ' ', text_new2)
4800
+ text_new2=text_new2.strip(' ')
4801
+
4802
+
4803
+ #替换缩写/简写/容易翻译出错的词,强行规避翻译错误。
4804
+ #注意:不影响未拆分科目名称,仅为翻译用途
4805
+ if split_improve:
4806
+ text_new3=text_new2.replace("PPE","Plant Property and Equipment")
4807
+
4808
+ text_new3=text_new3.replace("Treasury Shares Number","Treasury Shares")
4809
+ text_new3=text_new3.replace("Ordinary Shares Number","Ordinary Shares")
4810
+ text_new3=text_new3.replace(" Gross "," and ")
4811
+ text_new3=text_new3.replace("non Current","Non-current")
4812
+ text_new3=text_new3.replace("Non Current","Non-current")
4813
+ text_new3=text_new3.replace("Short Term","Short-term")
4814
+ text_new3=text_new3.replace("Long Term","Long-term")
4815
+ text_new3=text_new3.replace("Available for Sale","Available-for-sale")
4816
+
4817
+ text_new3=text_new3.replace(" Com "," Common ")
4818
+ text_new3=text_new3.replace(" Net "," Net of ")
4819
+ text_new3=text_new3.replace("Net Income","Net Profit")
4820
+
4821
+ text_new3=text_new3.replace("EBITDA","XXX")
4822
+ text_new3=text_new3.replace("EBIT","Earnings before Interest and Tax")
4823
+ text_new3=text_new3.replace("XXX","EBITDA")
4824
+
4825
+ text_new3=text_new3.replace("Tax Provision","Tax Accrued")
4826
+ text_new3=text_new3.replace("non Operating","Non-operating")
4827
+
4828
+ text_new3=text_new3.replace("Operating Income","Operating Profit")
4829
+ text_new3=text_new3.replace("Pretax Income","Pretax Profit")
4830
+
4831
+ text_new3=text_new3.replace("Current Provisions","Current Reserve")
4832
+
4833
+ text_new3=text_new3.replace("Duefrom ","Due from ")
4834
+ text_new3=text_new3.replace("Dueto ","Due to ")
4835
+
4836
+ text_new3=text_new3.replace("Investmentin ","Investment in ")
4837
+ text_new3=text_new3.replace("Diluted NIAvailto ","Diluted Net Profit Avail to ")
4838
+ text_new3=text_new3.replace(" Noncontrolling "," Non-controlling ")
4839
+ text_new3=text_new3.replace("Other Gand A","Other General and Administrative Expense")
4840
+ text_new3=text_new3.replace("Otherunder ","Other under ")
4841
+ text_new3=text_new3.replace("Mergern Acquisition","Merger and Acquisition")
4842
+ text_new3=text_new3.replace("Write Off","Write-off")
4843
+
4844
+ text_new3=text_new3.replace("Cash Flow From ","Cash Flow from ")
4845
+ text_new3=text_new3.replace("Cash From ","Cash Flow from ")
4846
+ text_new3=text_new3.replace(" From "," from ")
4847
+ text_new3=text_new3.replace("Provisionand","Provision and")
4848
+ text_new3=text_new3.replace("Write-offof","Write-off of")
4849
+ text_new3=text_new3.replace("non Cash","non-Cash")
4850
+ text_new3=text_new3.replace("Changein","Change in")
4851
+
4852
+ else:
4853
+ text_new3=text_new2
4854
+
4855
+ return text_new3
4856
+
4857
+ #==============================================================================
4558
4858
  #==============================================================================
4559
4859
  #==============================================================================
siat/valuation.py CHANGED
@@ -1177,9 +1177,10 @@ def security_valuation(tickers,indicators,start,end, \
1177
1177
 
1178
1178
  #==============================================================================
1179
1179
  if __name__=='__main__':
1180
- df=security_trend(baijiu_stocks,indicator='PE',start='MRY',graph=False)
1180
+ bank_big=find_peers_china('国有大型银行Ⅱ',top=25)
1181
+ df=security_trend(bank_big,indicator='PE',start='MRY',graph=False)
1181
1182
  indicator='PE'
1182
- base=''
1183
+ base='601398.SS'
1183
1184
 
1184
1185
 
1185
1186
  def print_valuation(df,indicator='PE',base='',facecolor='whitesmoke'):
@@ -1189,14 +1190,15 @@ def print_valuation(df,indicator='PE',base='',facecolor='whitesmoke'):
1189
1190
  try:
1190
1191
  df1=df[indicator]
1191
1192
  except:
1192
- print(" #Warning: current dataframe does not support indicator",indicator)
1193
+ print(f" #Warning(print_valuation): unsupported indicator {indicator} in current dataframe")
1193
1194
  return
1194
1195
 
1195
1196
  collist=list(df1)
1196
1197
  base=base.upper()
1198
+ base=ticker_name(base)
1197
1199
  if not (base in collist):
1198
1200
  """
1199
- print(" #Warning: invalid item",base,"for current dataframe")
1201
+ print(" #Warning(print_valuation): invalid item",base,"for current dataframe")
1200
1202
  print(" Valid items in current dataframe:\n",collist)
1201
1203
  return
1202
1204
  """
@@ -1256,7 +1258,8 @@ def print_valuation(df,indicator='PE',base='',facecolor='whitesmoke'):
1256
1258
  #df4=df3[['序号','证券名称',col_mean,col_mean_rel,'均值对比',col_latest_date,col_latest_rel,'对比@'+col_latest_date]]
1257
1259
  df4=df3[['证券名称',col_mean,'均值排名',col_latest_date,'排名@'+col_latest_date,col_mean_rel,col_latest_rel,'均值对比','对比@'+col_latest_date]]
1258
1260
 
1259
- titletxt="*** 估值对比:"+indicator+",降序排列"
1261
+ #titletxt="估值对比:"+ectranslate(indicator)+",降序排列"
1262
+ titletxt="证券估值对比:{0}({1}),降序排列".format(ectranslate(indicator),indicator)
1260
1263
  """
1261
1264
  print("\n",titletxt,'\n')
1262
1265
  alignlist=['left','right','center','right','center']+['right']*(len(list(df4))-5)
@@ -1273,16 +1276,17 @@ def print_valuation(df,indicator='PE',base='',facecolor='whitesmoke'):
1273
1276
  #设置列数值对齐
1274
1277
  dispf=dispt.set_properties(**{'text-align':'center'})
1275
1278
  #设置前景背景颜色
1276
- dispf2=dispf.set_properties(**{'background-color':facecolor,'color':fontcolor})
1279
+ #dispf2=dispf.set_properties(**{'background-color':facecolor,'color':fontcolor})
1280
+ dispf2=dispf.set_properties(**{'background-color':facecolor})
1277
1281
 
1278
1282
  from IPython.display import display
1279
1283
  display(dispf2)
1280
1284
 
1281
- print(" ")
1285
+ #print(" ")
1282
1286
  if diff > 0:
1283
1287
  print("【注】未列出"+str(diff)+"只估值为非正数的证券:"+str(diff_list))
1284
1288
  import datetime; todaydt = datetime.date.today()
1285
- footnote="*** 期间:"+col_start_date+"至"+col_latest_date+"。数据来源: baidu/stooq/funddb/swhysc,"+str(todaydt)
1289
+ footnote="估值期间:"+col_start_date+"至"+col_latest_date+",数据来源: baidu/stooq/funddb/swhysc,"+str(todaydt)
1286
1290
  print(footnote)
1287
1291
 
1288
1292
  return
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: siat
3
- Version: 3.7.7
3
+ Version: 3.7.9
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
@@ -35,6 +35,8 @@ Requires-Dist: pendulum
35
35
  Requires-Dist: itables
36
36
  Requires-Dist: py-trans
37
37
  Requires-Dist: bottleneck
38
+ Requires-Dist: translate
39
+ Requires-Dist: translators
38
40
 
39
41
 
40
42
  # What is siat?