siat 3.2.46__py3-none-any.whl → 3.2.51__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
@@ -3720,13 +3720,20 @@ def df_display_CSS(df,titletxt='',footnote='',facecolor='papayawhip',decimals=2,
3720
3720
  """
3721
3721
  功能:采样CSS式样显示df,适用于Jupyter环境,整齐紧凑,不挑浏览器
3722
3722
  注意:若facecolor不被支持,则自动改为papayawhip
3723
+
3724
+ 特别注意:运行show_df()后将发生格式错乱(表格位置自动居中,标题从表格上方移到下方,原脚注仍然居左)
3725
+ 因此,不要轻易使用show_df()
3723
3726
  """
3727
+ import pandas as pd
3728
+ import numpy as np
3729
+
3730
+ # 重置为Pandas默认样式, 无效!
3731
+ pd.reset_option('all')
3732
+
3724
3733
  #检查df是否为空
3725
3734
  if len(df)==0: return
3726
3735
 
3727
3736
  #替换nan和inf
3728
- import pandas as pd
3729
- import numpy as np
3730
3737
  df.replace([np.inf, -np.inf],'-', inplace=True)
3731
3738
  df.replace([np.nan],'-', inplace=True)
3732
3739
 
@@ -3959,9 +3966,13 @@ if __name__=='__main__':
3959
3966
  def show_df(data,search_mode=False):
3960
3967
  """
3961
3968
  功能:在Jupyter中查看dataframe,并可下载成Excel
3969
+ 注意:将改变Jupyter中pandas的显示式样,谨慎使用
3962
3970
  """
3963
3971
 
3964
3972
  import pandas as pd
3973
+ # 设置列对齐方式为靠左
3974
+ pd.set_option('display.align', 'left')
3975
+
3965
3976
  if not isinstance(data,pd.DataFrame):
3966
3977
  print("#Warning: the first parameter must be a dataframe")
3967
3978
  return
@@ -3996,6 +4007,9 @@ def show_df(data,search_mode=False):
3996
4007
  "criteria":[{"data":firstCol,"condition":"=","value":firstValue}]
3997
4008
  }})
3998
4009
 
4010
+ # 重置为Pandas默认样式, 无效!
4011
+ pd.reset_option('all')
4012
+
3999
4013
  return
4000
4014
 
4001
4015
  #==============================================================================
siat/security_price2.py CHANGED
@@ -38,7 +38,8 @@ if __name__=='__main__':
38
38
 
39
39
  ticker='801010.SW' #申万
40
40
 
41
- fromdate='2024-1-1'; todate='2024-4-6'
41
+ ticker='AAPL'
42
+ fromdate='2024-5-1'; todate='2024-5-20'
42
43
 
43
44
  ticker_type='auto'
44
45
  ticker_type='bond'
@@ -50,7 +51,7 @@ if __name__=='__main__':
50
51
  source='auto'
51
52
  source='yahoo'
52
53
 
53
- adjust=''
54
+ adjust='qfq'
54
55
  fill=True
55
56
 
56
57
  price,found=get_price_1ticker(ticker=ticker,fromdate=fromdate,todate=todate, \
siat/security_prices.py CHANGED
@@ -411,7 +411,7 @@ def get_price_ak_em(ticker,fromdate,todate,adjust='',ticker_type='auto'):
411
411
  '成交量':'Volume','成交额':'Amount','换手率':'Turnover'},inplace=True)
412
412
  df1=df[['Open','Close','High','Low','Volume','Amount','Turnover']]
413
413
 
414
- df1['source']='东方财富'
414
+ df1['source']=text_lang('东方财富','EM')
415
415
  df1['ticker']=str(ticker)
416
416
  df1['Adj Close']=df1['Close']
417
417
  df1['footnote']=adjust
@@ -601,7 +601,7 @@ def get_price_stooq(ticker,start,end):
601
601
  #prices.dropna(inplace=True)
602
602
 
603
603
  prices['Adj Close']=prices['Close']
604
- prices['source']='stooq'
604
+ prices['source']='Stooq'
605
605
  prices['ticker']=str(ticker)
606
606
  prices['footnote']=''
607
607
 
@@ -950,14 +950,18 @@ if __name__=='__main__':
950
950
  #==============================================================================
951
951
  if __name__=='__main__':
952
952
  symbol='AAPL'
953
- fromdate='2020-12-1'
954
- todate='2021-1-31'
955
- adjust=""
953
+ fromdate='2024-5-1'
954
+ todate='2024-5-20'
955
+ adjust="qfq"
956
+
957
+ get_price_ak_us(symbol, fromdate, todate, adjust)
956
958
 
957
959
  def get_price_ak_us(symbol, fromdate, todate, adjust=""):
958
960
  """
959
961
  抓取单个美股股价,不能处理股指
960
962
  """
963
+ import pandas as pd
964
+ DEBUG=False
961
965
 
962
966
  #检查日期期间
963
967
  result,start,end=check_period(fromdate,todate)
@@ -969,27 +973,29 @@ def get_price_ak_us(symbol, fromdate, todate, adjust=""):
969
973
  #printmsg=str(symbol)+" from "+fromdate+" to "+todate
970
974
 
971
975
  import akshare as ak
972
- #print(" Searching info in Sina for",symbol,"... ...")
973
- try:
974
- if adjust=='':
975
- df=ak.stock_us_daily(symbol=symbol,adjust=adjust)
976
- elif adjust=='Adj_only':
977
- df=ak.stock_us_daily(symbol=symbol,adjust='qfq')
978
- df['Adj Close']=df['close']
979
-
980
- else:
981
- dffqno=ak.stock_us_daily(symbol=symbol,adjust='')
982
- dffq=ak.stock_us_daily(symbol=symbol,adjust='qfq')
983
- dffq.rename(columns={'close':'Adj Close'},inplace=True)
984
-
985
- df=pd.merge(dffqno,dffq[['date','Adj Close']],on=['date'])
976
+ if DEBUG:
977
+ print(" Searching info in Sina for",symbol,"... ...")
978
+ #try:
979
+ if adjust=='':
980
+ df=ak.stock_us_daily(symbol=symbol,adjust=adjust)
981
+ elif adjust=='Adj_only':
982
+ df=ak.stock_us_daily(symbol=symbol,adjust='qfq')
983
+ df['Adj Close']=df['close']
986
984
 
985
+ else:
986
+ #分别获取收盘价和复权价,并合成
987
+ dffqno=ak.stock_us_daily(symbol=symbol,adjust='')
988
+ dffq=ak.stock_us_daily(symbol=symbol,adjust='qfq')
989
+ dffq.rename(columns={'close':'Adj Close'},inplace=True)
990
+
991
+ df=pd.merge(dffqno,dffq[['date','Adj Close']],on=['date'])
992
+ """
987
993
  except:
988
- #print(" #Error(get_price_ak_us): no info found for",symbol)
994
+ if DEBUG:
995
+ print(" #Error(get_price_ak_us): no info found for",symbol)
989
996
  return None
990
-
997
+ """
991
998
  #去掉可能出现的时区信息,必须使用datetime中的tz_localize
992
- import pandas as pd
993
999
  df['date']=pd.to_datetime(df['date'])
994
1000
  #df['date']=df['date'].tz_localize(None)
995
1001
 
@@ -1040,6 +1046,8 @@ def get_price_ak_hk(symbol,fromdate,todate,adjust=""):
1040
1046
  """
1041
1047
  抓取单个港股股价,不能处理股指,股指无.HK后缀
1042
1048
  """
1049
+ import pandas as pd
1050
+
1043
1051
  DEBUG=False
1044
1052
  if DEBUG:
1045
1053
  print("Start searching HK stock prices for",symbol,"...")
@@ -1292,7 +1300,7 @@ def get_prices_yahoo(ticker,start,end,retry_count=3,pause=1):
1292
1300
 
1293
1301
  p['ticker']=ticker
1294
1302
  #p['Adj Close']=p['Close']
1295
- p['source']='雅虎'
1303
+ p['source']=text_lang('雅虎','Yahoo')
1296
1304
 
1297
1305
  ptname=ticker_name(ticker,'stock')
1298
1306
  if ptname == ticker: ptname=''
@@ -1379,7 +1387,7 @@ def get_prices_yf(ticker,start,end,threads=False):
1379
1387
  if 'Adj Close' not in list(p):
1380
1388
  p['Adj Close']=p['Close']
1381
1389
  p['ticker']=ticker
1382
- p['source']='雅虎'
1390
+ p['source']=text_lang('雅虎','Yahoo')
1383
1391
 
1384
1392
  if len(p) > 0:
1385
1393
  ptname=ticker_name(ticker1,'stock')
siat/stock.py CHANGED
@@ -602,6 +602,17 @@ if __name__ =="__main__":
602
602
 
603
603
  fromdate='2024-1-1'; todate='2024-5-25'
604
604
 
605
+ # 测试组4
606
+ ticker='AAPL'
607
+ indicator='Adj Close'
608
+ fromdate='2024-5-1'; todate='2024-5-20'
609
+ adjust=''
610
+ zeroline=False; average_value=False; datatag=False; power=0; graph=True
611
+ source='auto'
612
+ mark_top=True; mark_bottom=True; mark_end=True
613
+ ticker_type='auto'
614
+ facecolor='whitesmoke'
615
+
605
616
 
606
617
  df=security_indicator(ticker,indicator,fromdate,todate,ticker_type=ticker_type)
607
618
 
@@ -621,7 +632,9 @@ def security_indicator(ticker,indicator, \
621
632
  print(" #Warning(security_indicator): invalid adjust",adjust)
622
633
  print(" Supported adjust:",adjust_list)
623
634
  adjust='qfq'
624
-
635
+
636
+ if ('Adj' not in indicator):
637
+ adjust=''
625
638
  if ('Adj' in indicator) and (adjust == ''):
626
639
  adjust='qfq'
627
640
 
@@ -806,12 +819,27 @@ if __name__ =="__main__":
806
819
  ticker='600519.SS'
807
820
  ticker='OR.PA'
808
821
  measures=['Monthly Ret%','Quarterly Ret%','Annual Ret%','XYZ']
809
- fromdate='2023-1-1'
810
- todate='2023-6-25'
822
+
823
+ ticker='NVDA'
824
+ measures=['Close','Adj Close']
825
+
826
+ fromdate='2024-5-20'
827
+ todate='2024-6-20'
828
+ adjust=''
829
+ band_area=''
811
830
  graph=True
812
- smooth=False
831
+ smooth=True
813
832
  loc='best'
833
+ facecolor='whitesmoke'
834
+ date_range=False
835
+ date_freq=False
814
836
  annotate=False
837
+ annotate_value=False
838
+ source='auto'
839
+ mark_top=True; mark_bottom=True; mark_end=True
840
+ ticker_type='auto'
841
+
842
+ df=security_mindicators(ticker,measures,fromdate,todate)
815
843
 
816
844
  def security_mindicators(ticker,measures,
817
845
  fromdate,todate, \
@@ -832,60 +860,69 @@ def security_mindicators(ticker,measures,
832
860
  smooth:样本数目超过一定数量就默认忽略
833
861
  """
834
862
  # 提前开始日期
835
- fromdate1=date_adjust(fromdate,adjust=-365*3)
863
+ #fromdate1=date_adjust(fromdate,adjust=-365*3)
836
864
 
865
+ #处理ticker,允许1个
837
866
  if isinstance(ticker,list):
838
- if len(ticker) == 1:
867
+ if len(ticker) >= 1:
839
868
  ticker=ticker[0]
840
869
  else:
841
- print(" #Error(security_mindicators): need 1 ticker only in",ticker)
870
+ print(" #Error(security_mindicators): need a ticker for proceed")
842
871
  return None
843
872
 
873
+ #处理measures,允许多个
844
874
  if isinstance(measures,str):
845
875
  measures=[measures]
846
876
 
847
- #判断复权价
848
- adjust_list=['','qfq','hfq']
849
- if adjust not in adjust_list:
850
- print(" #Warning(security_mindicators): invalid adjust",adjust)
851
- print(" Supported adjust:",adjust_list)
852
- adjust='qfq'
853
-
854
- if adjust =='':
855
- for m in measures:
856
- if 'Adj' in m:
857
- adjust='qfq'
858
- break
877
+ #屏蔽函数内print信息输出的类
878
+ import os, sys
879
+ class HiddenPrints:
880
+ def __enter__(self):
881
+ self._original_stdout = sys.stdout
882
+ sys.stdout = open(os.devnull, 'w')
859
883
 
860
- #抓取股价
861
- try:
862
- from siat.security_price2 import get_price_1ticker_mixed
863
- #pricedf=get_price(ticker,fromdate1,todate,source=source)
864
- pricedf,found=get_price_1ticker_mixed(ticker=ticker,fromdate=fromdate1,todate=todate, \
865
- adjust=adjust, \
866
- source=source,ticker_type=ticker_type)
867
- except:
868
- print(" #Error(security_mindicators): price info not found for",ticker)
869
- return None
870
- if pricedf is None:
871
- print(" #Error(security_mindicators): none of price info found for",ticker)
872
- return None
873
- if len(pricedf) ==0:
874
- print(" #Warning(security_mindicators): price info unavailable for",ticker)
875
- return None
876
-
877
- df=all_calculate(pricedf,ticker,fromdate,todate,ticker_type=ticker_type)
884
+ def __exit__(self, exc_type, exc_val, exc_tb):
885
+ sys.stdout.close()
886
+ sys.stdout = self._original_stdout
878
887
 
879
- # 检查指标是否存在
880
- colList=list(df)
881
- for c in measures:
882
- if not (c in colList):
883
- print(" #Warning(security_mindicators): unsupported security measure",c)
884
- measures.remove(c)
885
- df1=df[measures]
886
-
887
- for c in list(df1):
888
- df1.rename(columns={c:ectranslate(c)},inplace=True)
888
+ df=pd.DataFrame()
889
+ for m in measures:
890
+ print(" Searching",ticker,"for",m,"info ... ...")
891
+ #复权价判断
892
+ adjustm=adjust
893
+ if ('Adj' in m) and (adjust ==''):
894
+ adjustm='qfq'
895
+
896
+ with HiddenPrints():
897
+ #security_indicator未能做到同时获得Close和Adj Close
898
+ dftmp=security_indicator(ticker=ticker,indicator=m,adjust=adjustm, \
899
+ fromdate=fromdate,todate=todate, \
900
+ source=source, \
901
+ ticker_type=ticker_type, \
902
+ graph=False)
903
+ if dftmp is None:
904
+ print(" #Error(security_mindicators): info not found for",ticker)
905
+ return None
906
+ if len(dftmp) ==0:
907
+ print(" #Error(security_mindicators): empty record found for",ticker)
908
+ return None
909
+
910
+ try:
911
+ dftmp1= dftmp[[m]]
912
+ except:
913
+ print(" #Error(security_mindicators): unsupported measure for",m)
914
+ return None
915
+
916
+ if len(df)==0:
917
+ df=dftmp1
918
+ else:
919
+ df=pd.merge(df,dftmp1,left_index=True,right_index=True)
920
+
921
+ df['ticker']=ticker
922
+
923
+ # 翻译指标名称
924
+ for c in list(df):
925
+ df.rename(columns={c:ectranslate(c)},inplace=True)
889
926
 
890
927
  y_label=text_lang('证券指标',"Indicator")
891
928
  import datetime; todaydt = datetime.date.today()
@@ -898,19 +935,17 @@ def security_mindicators(ticker,measures,
898
935
  axhline_value=0
899
936
  axhline_label='零线'
900
937
  break
901
- title_txt=text_lang("证券趋势分析:","Security Trend: ")+ticker_name(ticker,ticker_type=ticker_type)
902
- """
903
- draw_lines(df1,y_label,x_label,axhline_value,axhline_label,title_txt, \
904
- data_label=False,resample_freq='H',smooth=smooth,loc=loc,annotate=annotate)
905
- """
906
- draw_lines2(df1,y_label,x_label,axhline_value,axhline_label,title_txt, \
938
+
939
+ titletxt=text_lang("证券趋势分析:","Security Trend: ")+ticker_name(ticker,ticker_type=ticker_type)
940
+
941
+ draw_lines2(df,y_label,x_label,axhline_value,axhline_label,titletxt, \
907
942
  data_label=False,resample_freq='6H',smooth=smooth, \
908
943
  date_range=date_range,date_freq=date_freq,date_fmt='%Y-%m-%d', \
909
944
  annotate=annotate,annotate_value=annotate_value, \
910
945
  mark_top=mark_top,mark_bottom=mark_bottom,mark_end=mark_end,facecolor=facecolor, \
911
946
  band_area=band_area,loc=loc)
912
947
 
913
- return df1
948
+ return df
914
949
 
915
950
  #==============================================================================
916
951
  def stock_price_volatility(ticker,fromdate,todate,type="Weekly Price Volatility", \
@@ -1411,8 +1446,12 @@ if __name__ =="__main__":
1411
1446
  tickers='MSFT'
1412
1447
  measures=['Annual Ret Volatility%','Annual Ret%']
1413
1448
 
1414
- fromdate='2023-1-1'
1415
- todate='2023-12-31'
1449
+ tickers='NVDA'
1450
+ tickers='AAPL'
1451
+ measures=['Close','Adj Close']
1452
+
1453
+ fromdate='2024-5-1'
1454
+ todate='2024-5-30'
1416
1455
  adjust=''
1417
1456
  twinx=False
1418
1457
  loc1='best'
@@ -1459,11 +1498,12 @@ def compare_security(tickers,measures,fromdate,todate, \
1459
1498
  #如果tickers是一个列表
1460
1499
  if isinstance(tickers,list):
1461
1500
  security_num = len(tickers)
1462
- if security_num == 0:
1501
+ if security_num != 0:
1502
+ if security_num >= 1: ticker1 = tickers[0]
1503
+ if security_num >= 2: ticker2 = tickers[1]
1504
+ else:
1463
1505
  print(" #Error(compare_security):security code/codes needed.")
1464
1506
  return None,None
1465
- if security_num >= 1: ticker1 = tickers[0]
1466
- if security_num >= 2: ticker2 = tickers[1]
1467
1507
 
1468
1508
  #判断测度个数
1469
1509
  #如果measures只是一个字符串
@@ -1474,43 +1514,67 @@ def compare_security(tickers,measures,fromdate,todate, \
1474
1514
  #如果measures是一个列表
1475
1515
  if isinstance(measures,list):
1476
1516
  measure_num = len(measures)
1477
- if measure_num == 0:
1517
+ if measure_num != 0:
1518
+ if measure_num >= 1: measure1 = measures[0]
1519
+ if measure_num >= 2: measure2 = measures[1]
1520
+ else:
1478
1521
  print(" #Error(compare_security): a measurement indicator needed.")
1479
1522
  return None,None
1480
- if measure_num >= 1: measure1 = measures[0]
1481
- if measure_num >= 2: measure2 = measures[1]
1482
1523
 
1483
1524
  #解析ticker_type
1484
1525
  if isinstance(ticker_type,str):
1485
1526
  ticker_type1=ticker_type2=ticker_type
1486
1527
  if isinstance(ticker_type,list) and len(ticker_type)==1:
1487
1528
  ticker_type1=ticker_type2=ticker_type[0]
1488
- if isinstance(ticker_type,list) and len(ticker_type) > 1:
1529
+ if isinstance(ticker_type,list) and len(ticker_type) >= 2:
1489
1530
  ticker_type1=ticker_type[0]
1490
1531
  ticker_type2=ticker_type[1]
1491
1532
  ticker_type_list=[ticker_type1,ticker_type2]
1533
+
1534
+ #屏蔽函数内print信息输出的类
1535
+ import os, sys
1536
+ class HiddenPrints:
1537
+ def __enter__(self):
1538
+ self._original_stdout = sys.stdout
1539
+ sys.stdout = open(os.devnull, 'w')
1540
+
1541
+ def __exit__(self, exc_type, exc_val, exc_tb):
1542
+ sys.stdout.close()
1543
+ sys.stdout = self._original_stdout
1492
1544
 
1493
1545
  #单一证券代码+两个测度指标
1494
1546
  if (security_num == 1) and (measure_num >= 2):
1495
- #复权价判断
1496
- if (('Adj' in measure1) or ('Adj' in measure2)) and (adjust ==''):
1497
- adjust='qfq'
1547
+
1548
+ print(" Searching",ticker1,"for",measure1,"info ... ...")
1549
+ #复权价判断1
1550
+ adjust1=adjust
1551
+ if ('Adj' in measure1) and (adjust1 ==''):
1552
+ adjust1='qfq'
1498
1553
 
1499
- pltdf1=compare_msecurity(tickers=ticker1,measure=measure1, \
1500
- start=fromdate,end=todate, \
1501
- adjust=adjust, \
1502
- graph=False, \
1503
- source=source, \
1504
- ticker_type=ticker_type_list[0])
1505
- pltdf1.rename(columns={list(pltdf1)[0]:measure1},inplace=True)
1506
-
1507
- pltdf2=compare_msecurity(tickers=ticker1,measure=measure2, \
1508
- start=fromdate,end=todate, \
1509
- adjust=adjust, \
1510
- graph=False, \
1511
- source=source, \
1512
- ticker_type=ticker_type_list[0])
1513
- pltdf2.rename(columns={list(pltdf2)[0]:measure2},inplace=True)
1554
+ with HiddenPrints():
1555
+ #security_indicator未能做到同时获得Close和Adj Close
1556
+ df1tmp=security_indicator(ticker=ticker1,indicator=measure1,adjust=adjust1, \
1557
+ fromdate=fromdate,todate=todate, \
1558
+ source=source, \
1559
+ ticker_type=ticker_type, \
1560
+ graph=False)
1561
+ pltdf1= df1tmp[[measure1]]
1562
+
1563
+ print(" Searching",ticker1,"for",measure2,"info ... ...")
1564
+ #复权价判断2
1565
+ adjust2=adjust
1566
+ if ('Adj' in measure2) and (adjust2 ==''):
1567
+ adjust2='qfq'
1568
+
1569
+ with HiddenPrints():
1570
+ #security_indicator未能做到同时获得Close和Adj Close
1571
+ df2tmp=security_indicator(ticker=ticker1,indicator=measure2,adjust=adjust2, \
1572
+ fromdate=fromdate,todate=todate, \
1573
+ source=source, \
1574
+ ticker_type=ticker_type, \
1575
+ graph=False)
1576
+
1577
+ pltdf2= df2tmp[[measure2]]
1514
1578
 
1515
1579
  pltdf=pd.merge(pltdf1,pltdf2,left_index=True,right_index=True)
1516
1580
  pltdf['ticker']=ticker1
@@ -1522,60 +1586,55 @@ def compare_security(tickers,measures,fromdate,todate, \
1522
1586
  ticker_type=ticker_type[0],facecolor=facecolor)
1523
1587
 
1524
1588
  try:
1525
- result1=pltdf1[[measure1]]
1589
+ result1=pltdf[['ticker',measure1]]
1526
1590
  except:
1527
- return None,None
1591
+ result1=None
1528
1592
  try:
1529
- result2=pltdf1[[measure2]]
1593
+ result2=pltdf[['ticker',measure2]]
1530
1594
  except:
1531
- return result1,None
1532
- else:
1533
- return result1,result2
1595
+ result2=None
1596
+ return result1,result2
1534
1597
 
1535
1598
  elif (security_num >= 2) and (measure_num >= 1):
1536
1599
  #双证券+单个测度指标
1537
1600
  if ('Adj' in measure1) and (adjust ==''):
1538
1601
  adjust='qfq'
1539
1602
 
1540
- pltdf1=compare_msecurity(tickers=ticker1,measure=measure1, \
1541
- start=fromdate,end=todate, \
1542
- adjust=adjust, \
1543
- graph=False, \
1544
- source=source, \
1545
- ticker_type=ticker_type_list[0])
1546
- pltdf1.rename(columns={list(pltdf1)[0]:measure1},inplace=True)
1547
- pltdf1['ticker']=ticker1
1603
+ df1tmp=security_indicator(ticker=ticker1,indicator=measure1,adjust=adjust, \
1604
+ fromdate=fromdate,todate=todate, \
1605
+ source=source, \
1606
+ ticker_type=ticker_type, \
1607
+ graph=False)
1608
+ pltdf1=df1tmp[['ticker',measure1]]
1548
1609
 
1549
- pltdf2=compare_msecurity(tickers=ticker2,measure=measure1, \
1550
- start=fromdate,end=todate, \
1551
- adjust=adjust, \
1552
- graph=False, \
1553
- source=source, \
1554
- ticker_type=ticker_type_list[1])
1555
- pltdf2.rename(columns={list(pltdf2)[0]:measure1},inplace=True)
1556
- pltdf2['ticker']=ticker2
1610
+ df2tmp=security_indicator(ticker=ticker2,indicator=measure1,adjust=adjust, \
1611
+ fromdate=fromdate,todate=todate, \
1612
+ source=source, \
1613
+ ticker_type=ticker_type, \
1614
+ graph=False)
1615
+ pltdf2=df2tmp[['ticker',measure1]]
1557
1616
 
1558
1617
  #绘制双证券单指标对比图
1559
1618
  if graph:
1560
-
1561
1619
  comp_2securities_1measure(pltdf1,pltdf2,measure1,twinx=twinx, \
1562
1620
  loc1=loc1,loc2=loc2,graph=graph, \
1563
1621
  ticker_type=ticker_type_list,facecolor=facecolor)
1564
1622
 
1565
1623
  try:
1566
1624
  result1=pltdf1[[measure1]]
1625
+ except:
1626
+ print(" #Error(compare_secuirty): measure",measure1,"not found for",ticker1)
1627
+ result1=None
1628
+ try:
1567
1629
  result2=pltdf2[[measure1]]
1568
1630
  except:
1569
- print(" #Error(compare_secuirty): measure",measure1,"not found")
1570
- return None,None
1571
- else:
1572
- return result1,result2
1631
+ print(" #Error(compare_secuirty): measure",measure1,"not found for",ticker2)
1632
+ result2=None
1633
+ return result1,result2
1573
1634
 
1574
1635
  else:
1575
- print(" #Error(compare_secuirty):no idea on what to compare.")
1636
+ print(" #Warning(compare_secuirty):only support the situations of 1 ticker + 2 measures or 2 tickers + 1 measure.")
1576
1637
  return None,None
1577
-
1578
- return result1,result2
1579
1638
 
1580
1639
 
1581
1640
  #==============================================================================
@@ -2526,16 +2585,23 @@ def stock_dividend(ticker,start,end,facecolor='whitesmoke',fontcolor='black'):
2526
2585
 
2527
2586
  titletxt=text_lang("股票分红历史","Stock Dividend")+': '+tname
2528
2587
  periodtxt=text_lang("历史期间:","Period:")+' '+fromdatey2md+"-"+todatey2md
2529
- sourcetxt=text_lang("数据来源: 雅虎财经,","Data source: Yahoo Finance,")
2588
+ #sourcetxt=text_lang("数据来源: 雅虎财经,","Data source: Yahoo Finance,")
2589
+ sourcetxt=text_lang("数据来源: 雅虎财经","Data source: Yahoo Finance")
2590
+ footnote=periodtxt+'\n'+sourcetxt
2530
2591
 
2531
2592
  #修改列命为英文
2532
- divprt.columns = [text_lang('序号','No.'),text_lang('日期','Date'),text_lang('星期','Weekday'),text_lang('股息','Dividend')]
2593
+ divprt.columns = [text_lang('序号','No.'),text_lang('日期','Date'),text_lang('星期','Weekday'),text_lang('每股股息','Dividend/share')]
2533
2594
 
2534
2595
  """
2535
2596
  print(divprt.to_string(index=False))
2536
2597
  """
2537
- print(' ') #空一行
2598
+ #print('') #空一行
2538
2599
 
2600
+ df_display_CSS(divprt,titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=2, \
2601
+ first_col_align='center',second_col_align='center', \
2602
+ last_col_align='right',other_col_align='center')
2603
+
2604
+ """
2539
2605
  disph=divprt.style.hide() #不显示索引列
2540
2606
  dispp=disph.format(precision=4) #设置带有小数点的列精度调整为小数点后2位
2541
2607
  #设置标题/列名对齐
@@ -2556,6 +2622,7 @@ def stock_dividend(ticker,start,end,facecolor='whitesmoke',fontcolor='black'):
2556
2622
  import datetime; todaydt=datetime.date.today(); todayy2md=todaydt.strftime('%y/%m/%d')
2557
2623
  #print('\n*** '+sourcetxt,today)
2558
2624
  print(sourcetxt,todayy2md)
2625
+ """
2559
2626
 
2560
2627
  return divdf
2561
2628
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: siat
3
- Version: 3.2.46
3
+ Version: 3.2.51
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=07y3q4nJdkM-anpZepj4gK0gvTKj-BB0ppDDI5-TCcY,26904
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=bag64Mm_b09lxtnlvtQnIMeTtjNFZlzjShRxr5m3OwI,150142
21
+ siat/common.py,sha256=-0zmR2N_t2xaTyYedwztT7HcHKG39DwaoLoX1u5Wm7s,150656
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
@@ -97,15 +97,15 @@ siat/risk_free_rate_test.py,sha256=CpmhUf8aEAEZeNu4gvWP2Mz2dLoIgBX5bI41vfUBEr8,4
97
97
  siat/sector_china.py,sha256=nP6kfYsnaQWZj8dK-zklwSDW8FDS-obZWp_zL0ec2Ig,118603
98
98
  siat/sector_china_test.py,sha256=1wq7ef8Bb_L8F0h0W6FvyBrIcBTEbrTV7hljtpj49U4,5843
99
99
  siat/security_price.py,sha256=2oHskgiw41KMGfqtnA0i2YjNNV6cYgtlUK0j3YeuXWs,29185
100
- siat/security_price2.py,sha256=NKlk5VRA-WeSK8dU960PRfWUOzj4BQ4HbUw3t4j9cv8,25955
101
- siat/security_prices.py,sha256=E4lYVHKtepPS_oymYHUKn2tZj-LyFa-hMMPNgdbvTj0,105569
100
+ siat/security_price2.py,sha256=4xvc9AzRhLKJMu6AxVzIqcn1-NrHoeCF2Ao2p9nwYjU,25978
101
+ siat/security_prices.py,sha256=WXC-UNLnuZ69MtC5oLIXbFKX5UeJ_52wRiqHj4LfJW0,105797
102
102
  siat/security_prices_test.py,sha256=OEphoJ87NPKoNow1QA8EU_5MUYrJF-qKoWKNapVfZNI,10779
103
103
  siat/security_trend.py,sha256=o0vpWdrJkmODCP94X-Bvn-w7efHhj9HpUYBHtLl55D0,17240
104
104
  siat/security_trend2-20240620.py,sha256=QVnEcb7AyVbO77jVqfFsJffGXrX8pgJ9xCfoAKmWBPk,24854
105
105
  siat/security_trend2.py,sha256=WOygSyWSynNmk5gpOA8n1738-nWqfDzuyMjwriB3eP4,25284
106
106
  siat/setup.py,sha256=up65rQGLmTBkhtaMLowjoQXYmIsnycnm4g1SYmeQS6o,1335
107
107
  siat/shenwan index history test.py,sha256=JCVAzOSEldHalhSFa3pqD8JI_8_djPMQOxpkuYU-Esg,1418
108
- siat/stock.py,sha256=klgcv0v54uDN7iEg1NXhM08qDOS1G54wyquTQBJodFM,150367
108
+ siat/stock.py,sha256=cIEVxAZ6vPhpICWk4p4tqpeyidLjxZHO2fF_HClaxHw,152530
109
109
  siat/stock_advice_linear.py,sha256=-twT7IGP-NEplkL1WPSACcNJjggRB2j4mlAQCkzOAuo,31655
110
110
  siat/stock_base.py,sha256=uISvbRyOGy8p9QREA96CVydgflBkn5L3OXOGKl8oanc,1312
111
111
  siat/stock_china.py,sha256=zyUyghIrkkkYWlHRRP7Hoblxzfp-jrck60pTJpwMahg,91553
@@ -138,7 +138,7 @@ siat/valuation.py,sha256=NKfeZMdDJOW42oLVHob6eSVBXUqlN1OCnnzwyGAst8c,48855
138
138
  siat/valuation_china.py,sha256=EkZQaVkoBjM0c4MCNbaX-bMnlG0e3FXeaWczZDnkptU,67784
139
139
  siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
140
140
  siat/var_model_validation.py,sha256=R0caWnuZarrRg9939hxh3vJIIpIyPfvelYmzFNZtPbo,14910
141
- siat-3.2.46.dist-info/METADATA,sha256=gZ8jTNIstNWw0UbcwTQ9S41tm9_aUi65_Pqhiu9pH8M,7310
142
- siat-3.2.46.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
143
- siat-3.2.46.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
144
- siat-3.2.46.dist-info/RECORD,,
141
+ siat-3.2.51.dist-info/METADATA,sha256=3PAMtgmDyOlUvGAb41VpjG5L2_ZVWfKGjN7qau9xKTc,7310
142
+ siat-3.2.51.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
143
+ siat-3.2.51.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
144
+ siat-3.2.51.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.2)
2
+ Generator: bdist_wheel (0.38.4)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5