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 +26 -4
- siat/security_price2.py +3 -2
- siat/security_prices.py +39 -31
- siat/stock.py +349 -106
- siat/translate.py +70 -61
- {siat-3.2.45.dist-info → siat-3.2.51.dist-info}/METADATA +2 -1
- {siat-3.2.45.dist-info → siat-3.2.51.dist-info}/RECORD +9 -9
- {siat-3.2.45.dist-info → siat-3.2.51.dist-info}/WHEEL +0 -0
- {siat-3.2.45.dist-info → siat-3.2.51.dist-info}/top_level.txt +0 -0
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
|
-
|
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']='
|
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='
|
954
|
-
todate='
|
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
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
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
|
-
|
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
|
-
|
810
|
-
|
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=
|
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)
|
867
|
+
if len(ticker) >= 1:
|
839
868
|
ticker=ticker[0]
|
840
869
|
else:
|
841
|
-
print(" #Error(security_mindicators): need
|
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
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
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
|
-
|
862
|
-
|
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
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
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
|
-
|
902
|
-
"""
|
903
|
-
|
904
|
-
|
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
|
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):
|
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,
|
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,
|
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,
|
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,
|
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 >=
|
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,
|
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,
|
1771
|
+
df1b=price_volatility2(df1a,ticker1,fromdate1,todate,graph=False,ticker_type=ticker_type1)
|
1538
1772
|
#加入收益率波动指标
|
1539
|
-
df1c=ret_volatility2(df1b,ticker1,
|
1773
|
+
df1c=ret_volatility2(df1b,ticker1,fromdate1,todate,graph=False,ticker_type=ticker_type1)
|
1540
1774
|
#加入收益率下偏标准差指标
|
1541
|
-
df1d=ret_lpsd2(df1c,ticker1,
|
1775
|
+
df1d=ret_lpsd2(df1c,ticker1,fromdate1,todate,graph=False,ticker_type=ticker_type1)
|
1542
1776
|
#去掉开始日期以前的数据
|
1543
|
-
pltdf1=df1d[df1d.index >=
|
1777
|
+
pltdf1=df1d[df1d.index >= fromdate1]
|
1544
1778
|
|
1545
1779
|
#证券ticker2:
|
1546
|
-
df2a=stock_ret(ticker2,
|
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,
|
1549
|
-
df2c=ret_volatility2(df2b,ticker2,
|
1550
|
-
df2d=ret_lpsd2(df2c,ticker2,
|
1551
|
-
pltdf2=df2d[df2d.index >=
|
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
|
1658
|
-
|
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
|
-
|
2347
|
-
|
2348
|
-
|
2349
|
-
|
2350
|
-
|
2351
|
-
|
2352
|
-
|
2353
|
-
|
2354
|
-
|
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
|
-
|
2499
|
-
|
2500
|
-
|
2501
|
-
|
2502
|
-
|
2503
|
-
|
2504
|
-
|
2505
|
-
|
2506
|
-
|
2507
|
-
|
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%','
|
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
|
357
|
-
['Exp Ret%','Holding
|
358
|
-
['Exp Adj Ret%','Holding
|
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
|
388
|
-
['Exp Ret Volatility%','Holding
|
389
|
-
['Exp Adj Ret Volatility','Holding
|
390
|
-
['Exp Adj Ret Volatility%','Holding
|
391
|
-
|
392
|
-
['Weekly Ret LPSD','Weekly
|
393
|
-
['Weekly Ret LPSD%','Weekly
|
394
|
-
['Weekly Adj Ret LPSD','Weekly Adjusted
|
395
|
-
['Weekly Adj Ret LPSD%','Weekly Adjusted
|
396
|
-
['Monthly Ret LPSD','Monthly
|
397
|
-
['Monthly Ret LPSD%','Monthly
|
398
|
-
['Monthly Adj Ret LPSD','Monthly Adjusted
|
399
|
-
['Monthly Adj Ret LPSD%','Monthly Adjusted
|
400
|
-
['Quarterly Ret LPSD','Quarterly
|
401
|
-
['Quarterly Ret LPSD%','Quarterly
|
402
|
-
['Quarterly Adj Ret LPSD','Quarterly Adjusted
|
403
|
-
['Quarterly Adj Ret LPSD%','Quarterly Adjusted
|
404
|
-
['Annual Ret LPSD','Annual
|
405
|
-
['Annual Ret LPSD%','Annual
|
406
|
-
['Annual Adj Ret LPSD','Annual Adjusted
|
407
|
-
['Annual Adj Ret LPSD%','Annual Adjusted
|
408
|
-
['Exp Ret LPSD','Holding
|
409
|
-
['Exp Ret LPSD%','Holding
|
410
|
-
['Exp Adj Ret LPSD','Holding
|
411
|
-
['Exp Adj Ret LPSD%','Holding
|
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','
|
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
|
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.
|
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
|
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=
|
101
|
-
siat/security_prices.py,sha256=
|
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=
|
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=
|
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.
|
142
|
-
siat-3.2.
|
143
|
-
siat-3.2.
|
144
|
-
siat-3.2.
|
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
|
File without changes
|