siat 3.2.45__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
 
@@ -3790,7 +3797,7 @@ if __name__=='__main__':
3790
3797
 
3791
3798
  def upgrade_siat(module_list=['siat','akshare','pandas','pandas_datareader', \
3792
3799
  'yfinance','yahooquery','urllib3','tabulate','twine', \
3793
- 'mplfinance','openpyxl','pip'], \
3800
+ 'mplfinance','openpyxl','pip','bottleneck'], \
3794
3801
  pipcmd="pip install --upgrade",alternative=""):
3795
3802
  """
3796
3803
  功能:一次性升级siat及其相关插件
@@ -3952,17 +3959,29 @@ if __name__=='__main__':
3952
3959
 
3953
3960
  show_df(data,search_mode=False)
3954
3961
  show_df(data,search_mode=True)
3962
+
3963
+ x=5
3964
+ show_df(x)
3955
3965
 
3956
3966
  def show_df(data,search_mode=False):
3957
3967
  """
3958
3968
  功能:在Jupyter中查看dataframe,并可下载成Excel
3969
+ 注意:将改变Jupyter中pandas的显示式样,谨慎使用
3959
3970
  """
3960
- df=data.copy()
3961
3971
 
3962
3972
  import pandas as pd
3973
+ # 设置列对齐方式为靠左
3974
+ pd.set_option('display.align', 'left')
3975
+
3976
+ if not isinstance(data,pd.DataFrame):
3977
+ print("#Warning: the first parameter must be a dataframe")
3978
+ return
3979
+
3963
3980
  import datetime
3964
3981
  from itables import init_notebook_mode, show
3965
3982
  init_notebook_mode(all_interactive=True)
3983
+
3984
+ df=data.copy()
3966
3985
 
3967
3986
  if not search_mode:
3968
3987
  show(df, buttons=["copyHtml5", "csvHtml5", "excelHtml5"])
@@ -3988,6 +4007,9 @@ def show_df(data,search_mode=False):
3988
4007
  "criteria":[{"data":firstCol,"condition":"=","value":firstValue}]
3989
4008
  }})
3990
4009
 
4010
+ # 重置为Pandas默认样式, 无效!
4011
+ pd.reset_option('all')
4012
+
3991
4013
  return
3992
4014
 
3993
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
 
@@ -1011,7 +1017,7 @@ def get_price_ak_us(symbol, fromdate, todate, adjust=""):
1011
1017
  df2['ticker']=symbol
1012
1018
  if 'Adj Close' not in list(df2):
1013
1019
  df2['Adj Close']=df2['Close']
1014
- df2['source']='新浪'
1020
+ df2['source']=text_lang('新浪','Sina')
1015
1021
  df2['footnote']=adjust
1016
1022
 
1017
1023
  ptname=ticker_name(symbol,'stock')
@@ -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,"...")
@@ -1097,7 +1105,7 @@ def get_price_ak_hk(symbol,fromdate,todate,adjust=""):
1097
1105
  df2['ticker']=symbol
1098
1106
  if 'Adj Close' not in list(df2):
1099
1107
  df2['Adj Close']=df2['Close']
1100
- df2['source']='新浪'
1108
+ df2['source']=text_lang('新浪','Sina')
1101
1109
 
1102
1110
  ptname=ticker_name(symbol,'stock')
1103
1111
  if ptname == symbol: ptname=''
@@ -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')
@@ -2343,15 +2351,15 @@ def recent_stock_split(ticker):
2343
2351
 
2344
2352
  divprt=divdf[['Seq','Split Date','Weekday','Splits']]
2345
2353
 
2346
- print("\n=== 近期股票分拆历史 ===")
2347
- print("股票:",ticker,'\b,',ticker)
2348
- print("期间:",fromdate,"to",today)
2349
- divprt.columns=['序号','日期','星期','分拆比例']
2354
+ print(text_lang("\n=== 近期股票分拆历史 ===","\n=== Recent Stock Split ==="))
2355
+ print(text_lang("股票:","Stock:"),ticker,'\b,',ticker)
2356
+ print(text_lang("期间:","Period:"),fromdate,"to",today)
2357
+ divprt.columns=[text_lang('序号','No.'),text_lang('日期','Date'),text_lang('星期','Weekday'),text_lang('分拆比例','Split Ratio')]
2350
2358
  print(divprt.to_string(index=False))
2351
2359
 
2352
2360
  import datetime
2353
2361
  today = datetime.date.today()
2354
- print("数据来源: 综合新浪/yahoo,",today)
2362
+ print(text_lang("数据来源: 综合新浪/yahoo,","Data source: Yahoo Finance,"),today)
2355
2363
 
2356
2364
  return divdf
2357
2365
 
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", \
@@ -1350,7 +1385,7 @@ def comp_2securities_1measure(df1,df2,measure,twinx=False,loc1='upper left', \
1350
1385
  #for c in nouselist: dfcols.remove(c)
1351
1386
 
1352
1387
  if not (measure in dfcols):
1353
- print(" #Error(comp_2securities_1measure): only support measurement types of",dfcols)
1388
+ print(" #Error(comp_2securities_1measure):only support measurement types of",dfcols)
1354
1389
  return
1355
1390
 
1356
1391
  #判断是否绘制水平0线
@@ -1404,13 +1439,37 @@ if __name__ =="__main__":
1404
1439
  df2=stock_ret(ticker2,fromdate,todate,graph=False)
1405
1440
  comp_2securities_1measure(df1,df2,measure)
1406
1441
  #==============================================================================
1442
+ if __name__ =="__main__":
1443
+ tickers=['MSFT','AAPL']
1444
+ measures='Annual Ret Volatility%'
1445
+
1446
+ tickers='MSFT'
1447
+ measures=['Annual Ret Volatility%','Annual Ret%']
1448
+
1449
+ tickers='NVDA'
1450
+ tickers='AAPL'
1451
+ measures=['Close','Adj Close']
1452
+
1453
+ fromdate='2024-5-1'
1454
+ todate='2024-5-30'
1455
+ adjust=''
1456
+ twinx=False
1457
+ loc1='best'
1458
+ loc2='lower left'
1459
+ graph=True
1460
+ source='auto'
1461
+ ticker_type='auto'
1462
+ facecolor='whitesmoke'
1463
+
1407
1464
  def compare_security(tickers,measures,fromdate,todate, \
1408
1465
  adjust='', \
1409
1466
  twinx=False, \
1410
1467
  loc1='best',loc2='lower left',graph=True,source='auto', \
1411
1468
  ticker_type='auto',facecolor='whitesmoke'):
1412
1469
  """
1413
- 功能:函数克隆compare_stock
1470
+ 功能:函数克隆compare_stock,只能处理两个ticker一个measure,或一个ticker两个measure
1471
+ 可以处理twinx=True
1472
+ """
1414
1473
  """
1415
1474
  # 应对导入失灵的函数
1416
1475
  from siat.security_prices import upper_ticker
@@ -1421,9 +1480,179 @@ def compare_security(tickers,measures,fromdate,todate, \
1421
1480
  twinx=twinx, \
1422
1481
  loc1=loc1,loc2=loc2,graph=graph,source=source, \
1423
1482
  ticker_type=ticker_type,facecolor=facecolor)
1483
+
1424
1484
  return result
1485
+ """
1486
+ #调试开关
1487
+ DEBUG=False
1488
+ # 应对导入失灵的函数
1489
+ from siat.common import upper_ticker
1490
+ tickers=upper_ticker(tickers)
1491
+
1492
+ #判断证券代码个数
1493
+ #如果tickers只是一个字符串
1494
+ security_num = 0
1495
+ if isinstance(tickers,str):
1496
+ security_num = 1
1497
+ ticker1 = tickers
1498
+ #如果tickers是一个列表
1499
+ if isinstance(tickers,list):
1500
+ security_num = len(tickers)
1501
+ if security_num != 0:
1502
+ if security_num >= 1: ticker1 = tickers[0]
1503
+ if security_num >= 2: ticker2 = tickers[1]
1504
+ else:
1505
+ print(" #Error(compare_security):security code/codes needed.")
1506
+ return None,None
1507
+
1508
+ #判断测度个数
1509
+ #如果measures只是一个字符串
1510
+ measure_num = 0
1511
+ if isinstance(measures,str):
1512
+ measure_num = 1
1513
+ measure1 = measures
1514
+ #如果measures是一个列表
1515
+ if isinstance(measures,list):
1516
+ measure_num = len(measures)
1517
+ if measure_num != 0:
1518
+ if measure_num >= 1: measure1 = measures[0]
1519
+ if measure_num >= 2: measure2 = measures[1]
1520
+ else:
1521
+ print(" #Error(compare_security): a measurement indicator needed.")
1522
+ return None,None
1523
+
1524
+ #解析ticker_type
1525
+ if isinstance(ticker_type,str):
1526
+ ticker_type1=ticker_type2=ticker_type
1527
+ if isinstance(ticker_type,list) and len(ticker_type)==1:
1528
+ ticker_type1=ticker_type2=ticker_type[0]
1529
+ if isinstance(ticker_type,list) and len(ticker_type) >= 2:
1530
+ ticker_type1=ticker_type[0]
1531
+ ticker_type2=ticker_type[1]
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
1544
+
1545
+ #单一证券代码+两个测度指标
1546
+ if (security_num == 1) and (measure_num >= 2):
1547
+
1548
+ print(" Searching",ticker1,"for",measure1,"info ... ...")
1549
+ #复权价判断1
1550
+ adjust1=adjust
1551
+ if ('Adj' in measure1) and (adjust1 ==''):
1552
+ adjust1='qfq'
1425
1553
 
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]]
1578
+
1579
+ pltdf=pd.merge(pltdf1,pltdf2,left_index=True,right_index=True)
1580
+ pltdf['ticker']=ticker1
1581
+
1582
+ #绘制单个证券的双指标对比图
1583
+ if graph:
1584
+ comp_1security_2measures(pltdf,measure1,measure2,twinx=twinx, \
1585
+ loc1=loc1,loc2=loc2,graph=graph, \
1586
+ ticker_type=ticker_type[0],facecolor=facecolor)
1587
+
1588
+ try:
1589
+ result1=pltdf[['ticker',measure1]]
1590
+ except:
1591
+ result1=None
1592
+ try:
1593
+ result2=pltdf[['ticker',measure2]]
1594
+ except:
1595
+ result2=None
1596
+ return result1,result2
1597
+
1598
+ elif (security_num >= 2) and (measure_num >= 1):
1599
+ #双证券+单个测度指标
1600
+ if ('Adj' in measure1) and (adjust ==''):
1601
+ adjust='qfq'
1602
+
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]]
1609
+
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]]
1616
+
1617
+ #绘制双证券单指标对比图
1618
+ if graph:
1619
+ comp_2securities_1measure(pltdf1,pltdf2,measure1,twinx=twinx, \
1620
+ loc1=loc1,loc2=loc2,graph=graph, \
1621
+ ticker_type=ticker_type_list,facecolor=facecolor)
1622
+
1623
+ try:
1624
+ result1=pltdf1[[measure1]]
1625
+ except:
1626
+ print(" #Error(compare_secuirty): measure",measure1,"not found for",ticker1)
1627
+ result1=None
1628
+ try:
1629
+ result2=pltdf2[[measure1]]
1630
+ except:
1631
+ print(" #Error(compare_secuirty): measure",measure1,"not found for",ticker2)
1632
+ result2=None
1633
+ return result1,result2
1634
+
1635
+ else:
1636
+ print(" #Warning(compare_secuirty):only support the situations of 1 ticker + 2 measures or 2 tickers + 1 measure.")
1637
+ return None,None
1638
+
1639
+
1426
1640
  #==============================================================================
1641
+ if __name__ =="__main__":
1642
+ tickers=['MSFT','AAPL']
1643
+ measures='Annual Ret Volatility%'
1644
+ fromdate='2023-1-1'
1645
+ todate='2023-12-31'
1646
+ adjust=''
1647
+ twinx=False
1648
+ loc1='best'
1649
+ loc2='lower left'
1650
+ graph=True
1651
+ source='auto'
1652
+ ticker_type='auto'
1653
+ facecolor='whitesmoke'
1654
+
1655
+
1427
1656
  def compare_stock(tickers,measures,fromdate,todate, \
1428
1657
  adjust='', \
1429
1658
  twinx=False, \
@@ -1442,6 +1671,8 @@ def compare_stock(tickers,measures,fromdate,todate, \
1442
1671
  开始日期fromdate,结束日期todate。
1443
1672
  输出:绘制证券价格折线图,手动指定是否使用单轴或双轴坐标。
1444
1673
  返回:无
1674
+
1675
+ 打算废弃?
1445
1676
  """
1446
1677
  #调试开关
1447
1678
  DEBUG=False
@@ -1479,27 +1710,30 @@ def compare_stock(tickers,measures,fromdate,todate, \
1479
1710
  if measure_num >= 1: measure1 = measures[0]
1480
1711
  if measure_num >= 2: measure2 = measures[1]
1481
1712
 
1713
+ #延伸开始日期
1714
+ fromdate1=date_adjust(fromdate,adjust=-365)
1715
+
1482
1716
  #单一证券代码+两个测度指标
1483
1717
  if (security_num == 1) and (measure_num >= 2):
1484
1718
  if (('Adj' in measure1) or ('Adj' in measure2)) and (adjust ==''):
1485
1719
  adjust='qfq'
1486
1720
 
1487
1721
  #证券ticker1:抓取行情,并计算其各种期间的收益率
1488
- df1a=stock_ret(ticker1,fromdate,todate,adjust=adjust,graph=False,source=source,ticker_type=ticker_type)
1722
+ df1a=stock_ret(ticker1,fromdate1,todate,adjust=adjust,graph=False,source=source,ticker_type=ticker_type)
1489
1723
  if df1a is None: return None,None
1490
1724
  if DEBUG: print("compare|df1a first date:",df1a.index[0])
1491
1725
  #加入价格波动指标
1492
- df1b=price_volatility2(df1a,ticker1,fromdate,todate,graph=False,ticker_type=ticker_type)
1726
+ df1b=price_volatility2(df1a,ticker1,fromdate1,todate,graph=False,ticker_type=ticker_type)
1493
1727
  if DEBUG: print("compare|df1b first date:",df1b.index[0])
1494
1728
  #加入收益率波动指标
1495
- df1c=ret_volatility2(df1b,ticker1,fromdate,todate,graph=False,ticker_type=ticker_type)
1729
+ df1c=ret_volatility2(df1b,ticker1,fromdate1,todate,graph=False,ticker_type=ticker_type)
1496
1730
  if DEBUG: print("compare|df1c first date:",df1c.index[0])
1497
1731
  #加入收益率下偏标准差指标
1498
- df1d=ret_lpsd2(df1c,ticker1,fromdate,todate,graph=False,ticker_type=ticker_type)
1732
+ df1d=ret_lpsd2(df1c,ticker1,fromdate1,todate,graph=False,ticker_type=ticker_type)
1499
1733
  if DEBUG: print("compare|df1d first date:",df1d.index[0])
1500
1734
 
1501
1735
  #去掉开始日期以前的数据
1502
- pltdf1=df1d[df1d.index >= fromdate]
1736
+ pltdf1=df1d[df1d.index >= fromdate1]
1503
1737
  #绘制单个证券的双指标对比图
1504
1738
  if graph:
1505
1739
  comp_1security_2measures(pltdf1,measure1,measure2,twinx=twinx, \
@@ -1531,24 +1765,24 @@ def compare_stock(tickers,measures,fromdate,todate, \
1531
1765
  ticker_type_list=[ticker_type1,ticker_type2]
1532
1766
 
1533
1767
  #证券ticker1:抓取行情,并计算其各种期间的收益率
1534
- df1a=stock_ret(ticker1,fromdate,todate,adjust=adjust,graph=False,source=source,ticker_type=ticker_type1)
1768
+ df1a=stock_ret(ticker1,fromdate1,todate,adjust=adjust,graph=False,source=source,ticker_type=ticker_type1)
1535
1769
  if df1a is None: return None,None
1536
1770
  #加入价格波动指标
1537
- df1b=price_volatility2(df1a,ticker1,fromdate,todate,graph=False,ticker_type=ticker_type1)
1771
+ df1b=price_volatility2(df1a,ticker1,fromdate1,todate,graph=False,ticker_type=ticker_type1)
1538
1772
  #加入收益率波动指标
1539
- df1c=ret_volatility2(df1b,ticker1,fromdate,todate,graph=False,ticker_type=ticker_type1)
1773
+ df1c=ret_volatility2(df1b,ticker1,fromdate1,todate,graph=False,ticker_type=ticker_type1)
1540
1774
  #加入收益率下偏标准差指标
1541
- df1d=ret_lpsd2(df1c,ticker1,fromdate,todate,graph=False,ticker_type=ticker_type1)
1775
+ df1d=ret_lpsd2(df1c,ticker1,fromdate1,todate,graph=False,ticker_type=ticker_type1)
1542
1776
  #去掉开始日期以前的数据
1543
- pltdf1=df1d[df1d.index >= fromdate]
1777
+ pltdf1=df1d[df1d.index >= fromdate1]
1544
1778
 
1545
1779
  #证券ticker2:
1546
- df2a=stock_ret(ticker2,fromdate,todate,adjust=adjust,graph=False,source=source,ticker_type=ticker_type2)
1780
+ df2a=stock_ret(ticker2,fromdate1,todate,adjust=adjust,graph=False,source=source,ticker_type=ticker_type2)
1547
1781
  if df2a is None: return None,None
1548
- df2b=price_volatility2(df2a,ticker2,fromdate,todate,graph=False,ticker_type=ticker_type2)
1549
- df2c=ret_volatility2(df2b,ticker2,fromdate,todate,graph=False,ticker_type=ticker_type2)
1550
- df2d=ret_lpsd2(df2c,ticker2,fromdate,todate,graph=False,ticker_type=ticker_type2)
1551
- pltdf2=df2d[df2d.index >= fromdate]
1782
+ df2b=price_volatility2(df2a,ticker2,fromdate1,todate,graph=False,ticker_type=ticker_type2)
1783
+ df2c=ret_volatility2(df2b,ticker2,fromdate1,todate,graph=False,ticker_type=ticker_type2)
1784
+ df2d=ret_lpsd2(df2c,ticker2,fromdate1,todate,graph=False,ticker_type=ticker_type2)
1785
+ pltdf2=df2d[df2d.index >= fromdate1]
1552
1786
 
1553
1787
  #绘制双证券单指标对比图
1554
1788
  if graph:
@@ -1647,16 +1881,19 @@ def compare_msecurity(tickers,measure,start,end, \
1647
1881
  # 应对导入失灵的函数
1648
1882
  from siat.common import upper_ticker
1649
1883
  tickers=upper_ticker(tickers)
1884
+ if not isinstance(tickers,list):
1885
+ tickers=[tickers]
1886
+
1650
1887
  # 去掉重复代码:有必要,重复代码将导致后续处理出错KeyError: 0!
1651
1888
  tickers=list(set(tickers))
1889
+ """
1652
1890
  num=len(tickers)
1653
1891
  if num <2:
1654
1892
  print(" #Error(compare_msecurity): need more tickers")
1655
1893
  return None
1656
-
1657
- if not isinstance(measure,str):
1658
- print(" #Error(compare_msecurity): support only one measure")
1659
- return None
1894
+ """
1895
+ if isinstance(measure,list):
1896
+ measure=measure[0]
1660
1897
 
1661
1898
  print(" Searching for multiple security for",measure,"...")
1662
1899
  #屏蔽函数内print信息输出的类
@@ -2329,7 +2566,10 @@ def stock_dividend(ticker,start,end,facecolor='whitesmoke',fontcolor='black'):
2329
2566
  divdf['Weekdayiso']= divdf['Index Date'].apply(weekdayfmt)
2330
2567
  #wdlist=['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
2331
2568
  #wdlist=['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday']
2332
- wdlist=['星期一','星期二','星期三','星期四','星期五','星期六','星期日']
2569
+ #wdlist=['星期一','星期二','星期三','星期四','星期五','星期六','星期日']
2570
+ wdlist=[text_lang('星期一','Mon'),text_lang('星期二','Tue'),text_lang('星期三','Wed'), \
2571
+ text_lang('星期四','Thu'),text_lang('星期五','Fri'),text_lang('星期六','Sat'),text_lang('星期日','Sun')]
2572
+
2333
2573
  wdfmt=lambda x : wdlist[x-1]
2334
2574
  divdf['Weekday']= divdf['Weekdayiso'].apply(wdfmt)
2335
2575
 
@@ -2343,25 +2583,25 @@ def stock_dividend(ticker,start,end,facecolor='whitesmoke',fontcolor='black'):
2343
2583
  fromdatey2md=startdt.strftime('%y/%m/%d')
2344
2584
  todatey2md=enddt.strftime('%y/%m/%d')
2345
2585
 
2346
- if lang == 'English':
2347
- titletxt=texttranslate("股票分红历史")+': '+tname
2348
- periodtxt=texttranslate("历史期间:")+' '+fromdatey2md+"-"+todatey2md
2349
- sourcetxt=texttranslate("数据来源: 雅虎财经,")
2350
-
2351
- #修改列命为英文
2352
- divprt.columns = [texttranslate('序号'),texttranslate('日期'),texttranslate('星期'),texttranslate('股息')]
2353
- else:
2354
- titletxt="股票分红历史:"+tname
2355
- periodtxt="期间: "+fromdatey2md+"-"+todatey2md
2356
- sourcetxt="数据来源: 雅虎,"
2357
-
2358
- #修改列命为中文
2359
- divprt.columns = ['序号','日期','星期','每股派息']
2586
+ titletxt=text_lang("股票分红历史","Stock Dividend")+': '+tname
2587
+ periodtxt=text_lang("历史期间:","Period:")+' '+fromdatey2md+"-"+todatey2md
2588
+ #sourcetxt=text_lang("数据来源: 雅虎财经,","Data source: Yahoo Finance,")
2589
+ sourcetxt=text_lang("数据来源: 雅虎财经","Data source: Yahoo Finance")
2590
+ footnote=periodtxt+'\n'+sourcetxt
2591
+
2592
+ #修改列命为英文
2593
+ divprt.columns = [text_lang('序号','No.'),text_lang('日期','Date'),text_lang('星期','Weekday'),text_lang('每股股息','Dividend/share')]
2594
+
2360
2595
  """
2361
2596
  print(divprt.to_string(index=False))
2362
2597
  """
2363
- print(' ') #空一行
2598
+ #print('') #空一行
2364
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
+ """
2365
2605
  disph=divprt.style.hide() #不显示索引列
2366
2606
  dispp=disph.format(precision=4) #设置带有小数点的列精度调整为小数点后2位
2367
2607
  #设置标题/列名对齐
@@ -2382,6 +2622,7 @@ def stock_dividend(ticker,start,end,facecolor='whitesmoke',fontcolor='black'):
2382
2622
  import datetime; todaydt=datetime.date.today(); todayy2md=todaydt.strftime('%y/%m/%d')
2383
2623
  #print('\n*** '+sourcetxt,today)
2384
2624
  print(sourcetxt,todayy2md)
2625
+ """
2385
2626
 
2386
2627
  return divdf
2387
2628
 
@@ -2454,7 +2695,8 @@ def stock_split(ticker,start,end,facecolor='whitesmoke',fontcolor='black'):
2454
2695
  weekdayfmt=lambda x : x.isoweekday()
2455
2696
  divdf['Weekdayiso']= divdf['Index Date'].apply(weekdayfmt)
2456
2697
  #wdlist=['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
2457
- wdlist=['星期一','星期二','星期三','星期四','星期五','星期六','星期日']
2698
+ wdlist=[text_lang('星期一','Mon'),text_lang('星期二','Tue'),text_lang('星期三','Wed'), \
2699
+ text_lang('星期四','Thu'),text_lang('星期五','Fri'),text_lang('星期六','Sat'),text_lang('星期日','Sun')]
2458
2700
  wdfmt=lambda x : wdlist[x-1]
2459
2701
  divdf['Weekday']= divdf['Weekdayiso'].apply(wdfmt)
2460
2702
 
@@ -2495,25 +2737,25 @@ def stock_split(ticker,start,end,facecolor='whitesmoke',fontcolor='black'):
2495
2737
  fromdatey2md=startdt.strftime('%y/%m/%d')
2496
2738
  todatey2md=enddt.strftime('%y/%m/%d')
2497
2739
 
2498
- if lang == 'English':
2499
- titletxt=texttranslate("股票分拆历史")+': '+tname
2500
- periodtxt=texttranslate("历史期间:")+' '+fromdatey2md+"-"+todatey2md
2501
- sourcetxt=texttranslate("数据来源: 雅虎财经,")
2502
-
2503
- #修改列命为英文
2504
- divprt.columns = [texttranslate('序号'),texttranslate('日期'),texttranslate('星期'),texttranslate('股息')]
2505
- else:
2506
- titletxt="股票分拆历史:"+tname
2507
- periodtxt="期间: "+fromdatey2md+"-"+todatey2md
2508
- sourcetxt="数据来源: 雅虎,"
2509
-
2510
- #修改列命为中文
2511
- divprt.columns = ['序号','日期','星期','分拆比例']
2740
+ titletxt=text_lang("股票分拆历史","Stock Split")+': '+tname
2741
+ periodtxt=text_lang("历史期间:","Period:")+' '+fromdatey2md+"-"+todatey2md
2742
+
2743
+ import datetime; todaydt=datetime.date.today(); todayy2md=str(todaydt.strftime('%y/%m/%d'))
2744
+ #sourcetxt=text_lang("数据来源: 雅虎财经, ","Data source: Yahoo Finance, ")+todayy2md
2745
+ sourcetxt=text_lang("数据来源: 雅虎财经","Data source: Yahoo Finance")
2746
+ footnote=periodtxt+'\n'+ sourcetxt
2747
+
2748
+ #修改列命为英文
2749
+ divprt.columns = [text_lang('序号','No.'),text_lang('日期','Date'),text_lang('星期','Weekday'),text_lang('分拆比例','Split Ratio')]
2512
2750
  """
2513
2751
  print(divprt.to_string(index=False))
2514
2752
  """
2515
2753
  print(' ') #空一行
2516
2754
 
2755
+ df_display_CSS(divprt,titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=2, \
2756
+ first_col_align='center',second_col_align='center', \
2757
+ last_col_align='right',other_col_align='center')
2758
+ """
2517
2759
  disph=divprt.style.hide() #不显示索引列
2518
2760
  dispp=disph.format(precision=4) #设置带有小数点的列精度调整为小数点后2位
2519
2761
  #设置标题/列名
@@ -2534,6 +2776,7 @@ def stock_split(ticker,start,end,facecolor='whitesmoke',fontcolor='black'):
2534
2776
  import datetime; todaydt=datetime.date.today(); todayy2md=todaydt.strftime('%y/%m/%d')
2535
2777
  #print('\n*** '+sourcetxt,today)
2536
2778
  print(sourcetxt,todayy2md)
2779
+ """
2537
2780
 
2538
2781
  return divdf
2539
2782
 
siat/translate.py CHANGED
@@ -58,9 +58,9 @@ def ectranslate_c(eword):
58
58
  ['Quarterly Ret%','季度收益率%'],['Quarterly Adj Ret','季度调整收益率'],
59
59
  ['Quarterly Adj Ret%','季度调整收益率%'],['Annual Ret','年收益率'],
60
60
  ['Annual Ret%','年收益率%'],['Annual Adj Ret','年调整收益率'],
61
- ['Annual Adj Ret%','年调整收益率%'],['Exp Ret','投资收益率'],
62
- ['Exp Ret%','投资收益率%'],['Exp Adj Ret','持有调整收益率'],
63
- ['Exp Adj Ret%','持有调整收益率%'],
61
+ ['Annual Adj Ret%','年调整收益率%'],['Exp Ret','持有期资本利得率'],
62
+ ['Exp Ret%','持有期资本利得%'],['Exp Adj Ret','持有期收益率'],
63
+ ['Exp Adj Ret%','持有期收益率%'],
64
64
 
65
65
  ['Weekly Price Volatility','周股价波动风险'],
66
66
  ['Weekly Adj Price Volatility','周调整股价波动风险'],
@@ -70,8 +70,8 @@ def ectranslate_c(eword):
70
70
  ['Quarterly Adj Price Volatility','季调整股价波动风险'],
71
71
  ['Annual Price Volatility','年股价波动风险'],
72
72
  ['Annual Adj Price Volatility','年调整股价波动风险'],
73
- ['Exp Price Volatility','持有股价波动风险'],
74
- ['Exp Adj Price Volatility','持有调整股价波动风险'],
73
+ ['Exp Price Volatility','持有期股价波动风险'],
74
+ ['Exp Adj Price Volatility','持有期复权价波动风险'],
75
75
 
76
76
  ['Weekly Ret Volatility','周收益率波动风险'],
77
77
  ['Weekly Ret Volatility%','周收益率波动风险%'],
@@ -89,31 +89,31 @@ def ectranslate_c(eword):
89
89
  ['Annual Ret Volatility%','年收益率波动风险%'],
90
90
  ['Annual Adj Ret Volatility','年调整收益率波动风险'],
91
91
  ['Annual Adj Ret Volatility%','年调整收益率波动风险%'],
92
- ['Exp Ret Volatility','投资收益率波动风险'],
93
- ['Exp Ret Volatility%','投资收益率波动风险%'],
94
- ['Exp Adj Ret Volatility','调整投资收益率波动风险'],
95
- ['Exp Adj Ret Volatility%','调整投资收益率波动风险%'],
96
-
97
- ['Weekly Ret LPSD','周收益率波动损失风险'],
98
- ['Weekly Ret LPSD%','周收益率波动损失风险%'],
99
- ['Weekly Adj Ret LPSD','周调整收益率波动损失风险'],
100
- ['Weekly Adj Ret LPSD%','周调整收益率波动损失风险%'],
101
- ['Monthly Ret LPSD','月收益率波动损失风险'],
102
- ['Monthly Ret LPSD%','月收益率波动损失风险%'],
103
- ['Monthly Adj Ret LPSD','月调整收益波动损失风险'],
104
- ['Monthly Adj Ret LPSD%','月调整收益波动损失风险%'],
105
- ['Quarterly Ret LPSD','季收益率波动损失风险'],
106
- ['Quarterly Ret LPSD%','季收益率波动损失风险%'],
107
- ['Quarterly Adj Ret LPSD','季调整收益率波动损失风险'],
108
- ['Quarterly Adj Ret LPSD%','季调整收益率波动损失风险%'],
109
- ['Annual Ret LPSD','年收益率波动损失风险'],
110
- ['Annual Ret LPSD%','年收益率波动损失风险%'],
111
- ['Annual Adj Ret LPSD','年调整收益率波动损失风险'],
112
- ['Annual Adj Ret LPSD%','年调整收益率波动损失风险%'],
113
- ['Exp Ret LPSD','投资损失风险'],
114
- ['Exp Ret LPSD%','投资损失风险%'],
115
- ['Exp Adj Ret LPSD','调整投资损失风险'],
116
- ['Exp Adj Ret LPSD%','调整投资损失风险%'],
92
+ ['Exp Ret Volatility','持有期资本利得风险'],
93
+ ['Exp Ret Volatility%','持有期资本利得风险%'],
94
+ ['Exp Adj Ret Volatility','持有期收益率风险'],
95
+ ['Exp Adj Ret Volatility%','持有期收益率风险%'],
96
+
97
+ ['Weekly Ret LPSD','周收益损失风险'],
98
+ ['Weekly Ret LPSD%','周收益损失风险%'],
99
+ ['Weekly Adj Ret LPSD','周复权收益损失风险'],
100
+ ['Weekly Adj Ret LPSD%','周复权收益损失风险%'],
101
+ ['Monthly Ret LPSD','月收益损失风险'],
102
+ ['Monthly Ret LPSD%','月收益损失风险%'],
103
+ ['Monthly Adj Ret LPSD','月复权收益损失风险'],
104
+ ['Monthly Adj Ret LPSD%','月复权收益损失风险%'],
105
+ ['Quarterly Ret LPSD','季收益损失风险'],
106
+ ['Quarterly Ret LPSD%','季收益损失风险%'],
107
+ ['Quarterly Adj Ret LPSD','季复权收益损失风险'],
108
+ ['Quarterly Adj Ret LPSD%','季复权收益损失风险%'],
109
+ ['Annual Ret LPSD','年收益损失风险'],
110
+ ['Annual Ret LPSD%','年收益损失风险%'],
111
+ ['Annual Adj Ret LPSD','年复权收益损失风险'],
112
+ ['Annual Adj Ret LPSD%','年复权收益损失风险%'],
113
+ ['Exp Ret LPSD','持有期资本损失风险'],
114
+ ['Exp Ret LPSD%','持有期资本损失风险%'],
115
+ ['Exp Adj Ret LPSD','持有期收益损失风险'],
116
+ ['Exp Adj Ret LPSD%','持有期收益损失风险%'],
117
117
 
118
118
  ['roll_spread','罗尔价差比率'],['amihud_illiquidity','阿米胡德非流动性'],
119
119
  ['ps_liquidity','P-S流动性'],
@@ -353,9 +353,9 @@ def ectranslate_e(eword):
353
353
  ['Quarterly Ret%','Quarterly Return%'],['Quarterly Adj Ret','Quarterly Adjusted Return'],
354
354
  ['Quarterly Adj Ret%','Quarterly Adjusted Return%'],['Annual Ret','Annual Return'],
355
355
  ['Annual Ret%','Annual Return%'],['Annual Adj Ret','Annual Adjusted Return'],
356
- ['Annual Adj Ret%','Annual Adjusted Return%'],['Exp Ret','Holding Return'],
357
- ['Exp Ret%','Holding Return%'],['Exp Adj Ret','Holding Adjusted Return'],
358
- ['Exp Adj Ret%','Holding Adjusted Return%'],
356
+ ['Annual Adj Ret%','Annual Adjusted Return%'],['Exp Ret','Holding Period Capital Gain Rate'],
357
+ ['Exp Ret%','Holding Period Capital Gain%'],['Exp Adj Ret','Holding Period Return'],
358
+ ['Exp Adj Ret%','Holding Period Return%'],
359
359
 
360
360
  ['Weekly Price Volatility','Weekly Price Volatility'],
361
361
  ['Weekly Adj Price Volatility','Weekly Adjusted Price Volatility'],
@@ -384,31 +384,31 @@ def ectranslate_e(eword):
384
384
  ['Annual Ret Volatility%','Annual Return Volatility%'],
385
385
  ['Annual Adj Ret Volatility','Annual Adjusted Return Volatility'],
386
386
  ['Annual Adj Ret Volatility%','Annual Adjusted Return Volatility%'],
387
- ['Exp Ret Volatility','Holding Return Volatility'],
388
- ['Exp Ret Volatility%','Holding Return Volatility%'],
389
- ['Exp Adj Ret Volatility','Holding Adjusted Return Volatility'],
390
- ['Exp Adj Ret Volatility%','Holding Adjusted Return Volatility%'],
391
-
392
- ['Weekly Ret LPSD','Weekly Return LPSD'],
393
- ['Weekly Ret LPSD%','Weekly Return LPSD%'],
394
- ['Weekly Adj Ret LPSD','Weekly Adjusted Return LPSD'],
395
- ['Weekly Adj Ret LPSD%','Weekly Adjusted Return LPSD%'],
396
- ['Monthly Ret LPSD','Monthly Return LPSD'],
397
- ['Monthly Ret LPSD%','Monthly Return LPSD%'],
398
- ['Monthly Adj Ret LPSD','Monthly Adjusted Return LPSD'],
399
- ['Monthly Adj Ret LPSD%','Monthly Adjusted Return LPSD%'],
400
- ['Quarterly Ret LPSD','Quarterly Return LPSD'],
401
- ['Quarterly Ret LPSD%','Quarterly Return LPSD%'],
402
- ['Quarterly Adj Ret LPSD','Quarterly Adjusted Return LPSD'],
403
- ['Quarterly Adj Ret LPSD%','Quarterly Adjusted Return LPSD%'],
404
- ['Annual Ret LPSD','Annual Return LPSD'],
405
- ['Annual Ret LPSD%','Annual Return LPSD%'],
406
- ['Annual Adj Ret LPSD','Annual Adjusted Return LPSD'],
407
- ['Annual Adj Ret LPSD%','Annual Adjusted Return LPSD%'],
408
- ['Exp Ret LPSD','Holding Return LPSD'],
409
- ['Exp Ret LPSD%','Holding Return LPSD%'],
410
- ['Exp Adj Ret LPSD','Holding Adjusted Return LPSD'],
411
- ['Exp Adj Ret LPSD%','Holding Adjusted Return LPSD%'],
387
+ ['Exp Ret Volatility','Holding Period Capital Gain Volatility'],
388
+ ['Exp Ret Volatility%','Holding Period Capital Gain Volatility%'],
389
+ ['Exp Adj Ret Volatility','Holding Period Return Volatility'],
390
+ ['Exp Adj Ret Volatility%','Holding Period Return Volatility%'],
391
+
392
+ ['Weekly Ret LPSD','Weekly Loss Risk'],
393
+ ['Weekly Ret LPSD%','Weekly Loss Risk%'],
394
+ ['Weekly Adj Ret LPSD','Weekly Adjusted Loss Risk'],
395
+ ['Weekly Adj Ret LPSD%','Weekly Adjusted Loss Risk%'],
396
+ ['Monthly Ret LPSD','Monthly Loss Risk'],
397
+ ['Monthly Ret LPSD%','Monthly Loss Risk%'],
398
+ ['Monthly Adj Ret LPSD','Monthly Adjusted Loss Risk'],
399
+ ['Monthly Adj Ret LPSD%','Monthly Adjusted Loss Risk%'],
400
+ ['Quarterly Ret LPSD','Quarterly Loss Risk'],
401
+ ['Quarterly Ret LPSD%','Quarterly Loss Risk%'],
402
+ ['Quarterly Adj Ret LPSD','Quarterly Adjusted Loss Risk'],
403
+ ['Quarterly Adj Ret LPSD%','Quarterly Adjusted Loss Risk%'],
404
+ ['Annual Ret LPSD','Annual Loss Risk'],
405
+ ['Annual Ret LPSD%','Annual Loss Risk%'],
406
+ ['Annual Adj Ret LPSD','Annual Adjusted Loss Risk'],
407
+ ['Annual Adj Ret LPSD%','Annual Adjusted Loss Risk%'],
408
+ ['Exp Ret LPSD','Holding Period Capital Loss Risk'],
409
+ ['Exp Ret LPSD%','Holding Period Capital Loss Risk%'],
410
+ ['Exp Adj Ret LPSD','Holding Period Loss Risk'],
411
+ ['Exp Adj Ret LPSD%','Holding Period Loss Risk%'],
412
412
 
413
413
  ['roll_spread','Roll Spread'],['amihud_illiquidity','Amihud Illiquidity'],
414
414
  ['ps_liquidity','P-S Liquidity'],
@@ -607,8 +607,12 @@ def codetranslate(codelist):
607
607
  #==============================================================================
608
608
  if __name__=='__main__':
609
609
  codelist=['601398.SS','01398.HK']
610
+ codelist='PDD'
611
+
610
612
  code='601398.SS'
611
613
  code='01398.HK'
614
+
615
+ codetranslate_e(codelist)
612
616
 
613
617
  #在common中定义
614
618
  #SUFFIX_LIST_CN=['SS','SZ','BJ','NQ']
@@ -1813,7 +1817,7 @@ def codetranslate1(code):
1813
1817
  ['EBAY','eBay'],['eBay','eBay'],['META','META'],['ZM','ZOOM'],
1814
1818
  ['GOOG','Google'],['TWTR','Twitter'],
1815
1819
  ['VIPS','Vipshop'],['Vipshop','Vipshop'],
1816
- ['PDD','Pinduoduo'],['Pinduoduo','Pinduoduo'],
1820
+ ['PDD','PDD(US)'],['Pinduoduo','Pinduoduo'],
1817
1821
  ['BABA','Alibaba(US)'],['Alibaba','Alibaba'],
1818
1822
  ['JD','JD(US)'],
1819
1823
  ['SINA','Sina'],['BIDU','Baidu'],['NTES','Netease'],
@@ -1967,9 +1971,10 @@ def codetranslate1(code):
1967
1971
  ['000022.SS','SSE Corpbond Index'],['000061.SS','SSE Entbond30 Index'],
1968
1972
  ['000116.SS','SSE Creditbond100 Index'],['000101.SS','SSE 5-year Creditbond Index'],
1969
1973
 
1970
- ['002594.SZ','BYD Auto (A)'],['01211.HK','BYD Auto (HK)'],['81211.HK','BYD Auto (HK RMB)'],
1974
+ ['002594.SZ','BYD Auto(A)'],['01211.HK','BYD Auto(HK)'],['81211.HK','BYD Auto(HK RMB)'],
1971
1975
  ['600941.SS','China Mobile'],['00941.HK','China Mobile (HK)'],['80941.HK','China Mobile (HK RMB)'],
1972
1976
  ['ULVR.UK','Unilever (UK)'],['605011.SS','Hangzou Power'],['000723.SZ','Meijin Energy'],
1977
+ ['EL','Estee Lauder'],['LOR.DE','L\'Oreal(DE)'],
1973
1978
 
1974
1979
  ['^GSPC','S&P500 Index'],['^DJI','Dow Jones Index'],
1975
1980
  ['WISGP.SI','FTSE Singapore Index'], ['^STI','Straits Times Index'],
@@ -1977,6 +1982,7 @@ def codetranslate1(code):
1977
1982
  ['^N100','Euronext 100 Index'],['^FMIB','FTSE Italy Index'],
1978
1983
  ['^TSX','Toronto Composite Index'],['^MXX','Mexico IPC Index'],
1979
1984
  ['^SNX','India SENSEX 30 Index'],['^FTM','UK FTSE 250 Index'],
1985
+ ['^KLCI','Kuala Lumpur Composite Index'],['^KLSE','Kuala Lumpur Composite Index'],
1980
1986
 
1981
1987
  ['FVTT.FGI','FTSE Viernam Index'],['^RUT','Russell 2000 Index'],
1982
1988
  ['^HSI','Hang Seng Index'],['^N225','Nikkei 225 Index'],
@@ -2218,6 +2224,8 @@ def get_names(symbol):
2218
2224
  if __name__=='__main__':
2219
2225
  symbol='00700.HK'
2220
2226
  symbol='001979.SZ'
2227
+ symbol='PDD'
2228
+
2221
2229
  get_names0(symbol)
2222
2230
 
2223
2231
  def get_names0(symbol):
@@ -2755,7 +2763,7 @@ def texttranslate(code):
2755
2763
  ['数据来源: 新浪/stooq,','Source: sina/stooq,'],['数据来源: 雅虎财经,','Source: Yahoo Finance,'],
2756
2764
  ["证券快照:","证券快照:"],
2757
2765
  ["证券价格走势图:","证券价格走势图:"],
2758
- ["证券收益率波动损失风险走势图:","证券收益率波动损失风险走势图:"],
2766
+ ["证券收益率损失风险走势图:","证券收益率损失风险走势图:"],
2759
2767
  ["证券指标走势对比图:","证券指标走势对比图:"],
2760
2768
  ["证券价格走势蜡烛图演示:","证券价格走势蜡烛图演示:"],
2761
2769
  ["股票分红历史","Stock Dividend History"],
@@ -3213,6 +3221,7 @@ if __name__=='__main__':
3213
3221
  ticker='010107.SS' #债券/基金重码
3214
3222
  ticker='sh010303' #国债/基金重码
3215
3223
  ticker='sh018001' #金融债
3224
+ ticker='PDD'
3216
3225
 
3217
3226
  ticker_type='auto'
3218
3227
  ticker_type='bond'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: siat
3
- Version: 3.2.45
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
@@ -33,6 +33,7 @@ Requires-Dist: luddite
33
33
  Requires-Dist: pendulum
34
34
  Requires-Dist: itables
35
35
  Requires-Dist: py-trans
36
+ Requires-Dist: bottleneck
36
37
 
37
38
  # Welcome to the Magic World of siat
38
39
 
@@ -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=_PkuAzT9fNJazC1p3NIQDqLduzfBFcLsV3KPteo377I,149963
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=ChiVcubRiPzUvYm8a5X5qjxWtawRQdYHFQXLIevGFC4,105328
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=lk3Cvbm2ieFk-ISoy2nX0rEoqnnAGuX3lNiT6iskTjg,143914
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
@@ -131,14 +131,14 @@ siat/transaction_test.py,sha256=Z8g1LJCN4-mnUByXMUMoFmN0t105cbmsz2QmvSuIkbU,1858
131
131
  siat/translate-20230125.py,sha256=NPPSXhT38s5t9fzMvl_fvi4ckSB73ThLmZetVI-xGdU,117953
132
132
  siat/translate-20230206.py,sha256=-vtI125WyaJhmPotOpDAmclt_XnYVaWU9ByLWZ6FyYE,118133
133
133
  siat/translate-20230215.py,sha256=TJgtPE3n8IjljmZ4Pefy8dmHoNdFF-1zpML6BhA9FKE,121657
134
- siat/translate.py,sha256=YoC7OzzGUxT-7EEIU-GYWz0A9CBQ4aIQjlparfVJYSQ,216156
134
+ siat/translate.py,sha256=5o7hSMeNOdyenqiyB5oZwFvIpFvt3yGgp25KZNbqy9o,216309
135
135
  siat/translate_20240606.py,sha256=63IyHWEU3Uz9mjwyuAX3fqY4nUMdwh0ICQAgmgPXP7Y,215121
136
136
  siat/universal_test.py,sha256=CDAOffW1Rvs-TcNN5giWVvHMlch1w4dp-w5SIV9jXL0,3936
137
137
  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.45.dist-info/METADATA,sha256=a1zRvc3eoGiRhfDYBCgHd6iE9YgNmlj83jV1Alrq7Cc,7283
142
- siat-3.2.45.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
143
- siat-3.2.45.dist-info/top_level.txt,sha256=r1cVyL7AIKqeAmEJjNR8FMT20OmEzufDstC2gv3NvEY,5
144
- siat-3.2.45.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,,
File without changes