siat 3.2.46__py3-none-any.whl → 3.2.51__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- siat/common.py +16 -2
- siat/security_price2.py +3 -2
- siat/security_prices.py +32 -24
- siat/stock.py +181 -114
- {siat-3.2.46.dist-info → siat-3.2.51.dist-info}/METADATA +1 -1
- {siat-3.2.46.dist-info → siat-3.2.51.dist-info}/RECORD +8 -8
- {siat-3.2.46.dist-info → siat-3.2.51.dist-info}/WHEEL +1 -1
- {siat-3.2.46.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
|
|
@@ -3959,9 +3966,13 @@ if __name__=='__main__':
|
|
3959
3966
|
def show_df(data,search_mode=False):
|
3960
3967
|
"""
|
3961
3968
|
功能:在Jupyter中查看dataframe,并可下载成Excel
|
3969
|
+
注意:将改变Jupyter中pandas的显示式样,谨慎使用
|
3962
3970
|
"""
|
3963
3971
|
|
3964
3972
|
import pandas as pd
|
3973
|
+
# 设置列对齐方式为靠左
|
3974
|
+
pd.set_option('display.align', 'left')
|
3975
|
+
|
3965
3976
|
if not isinstance(data,pd.DataFrame):
|
3966
3977
|
print("#Warning: the first parameter must be a dataframe")
|
3967
3978
|
return
|
@@ -3996,6 +4007,9 @@ def show_df(data,search_mode=False):
|
|
3996
4007
|
"criteria":[{"data":firstCol,"condition":"=","value":firstValue}]
|
3997
4008
|
}})
|
3998
4009
|
|
4010
|
+
# 重置为Pandas默认样式, 无效!
|
4011
|
+
pd.reset_option('all')
|
4012
|
+
|
3999
4013
|
return
|
4000
4014
|
|
4001
4015
|
#==============================================================================
|
siat/security_price2.py
CHANGED
@@ -38,7 +38,8 @@ if __name__=='__main__':
|
|
38
38
|
|
39
39
|
ticker='801010.SW' #申万
|
40
40
|
|
41
|
-
|
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
|
|
@@ -1040,6 +1046,8 @@ def get_price_ak_hk(symbol,fromdate,todate,adjust=""):
|
|
1040
1046
|
"""
|
1041
1047
|
抓取单个港股股价,不能处理股指,股指无.HK后缀
|
1042
1048
|
"""
|
1049
|
+
import pandas as pd
|
1050
|
+
|
1043
1051
|
DEBUG=False
|
1044
1052
|
if DEBUG:
|
1045
1053
|
print("Start searching HK stock prices for",symbol,"...")
|
@@ -1292,7 +1300,7 @@ def get_prices_yahoo(ticker,start,end,retry_count=3,pause=1):
|
|
1292
1300
|
|
1293
1301
|
p['ticker']=ticker
|
1294
1302
|
#p['Adj Close']=p['Close']
|
1295
|
-
p['source']='雅虎'
|
1303
|
+
p['source']=text_lang('雅虎','Yahoo')
|
1296
1304
|
|
1297
1305
|
ptname=ticker_name(ticker,'stock')
|
1298
1306
|
if ptname == ticker: ptname=''
|
@@ -1379,7 +1387,7 @@ def get_prices_yf(ticker,start,end,threads=False):
|
|
1379
1387
|
if 'Adj Close' not in list(p):
|
1380
1388
|
p['Adj Close']=p['Close']
|
1381
1389
|
p['ticker']=ticker
|
1382
|
-
p['source']='雅虎'
|
1390
|
+
p['source']=text_lang('雅虎','Yahoo')
|
1383
1391
|
|
1384
1392
|
if len(p) > 0:
|
1385
1393
|
ptname=ticker_name(ticker1,'stock')
|
siat/stock.py
CHANGED
@@ -602,6 +602,17 @@ if __name__ =="__main__":
|
|
602
602
|
|
603
603
|
fromdate='2024-1-1'; todate='2024-5-25'
|
604
604
|
|
605
|
+
# 测试组4
|
606
|
+
ticker='AAPL'
|
607
|
+
indicator='Adj Close'
|
608
|
+
fromdate='2024-5-1'; todate='2024-5-20'
|
609
|
+
adjust=''
|
610
|
+
zeroline=False; average_value=False; datatag=False; power=0; graph=True
|
611
|
+
source='auto'
|
612
|
+
mark_top=True; mark_bottom=True; mark_end=True
|
613
|
+
ticker_type='auto'
|
614
|
+
facecolor='whitesmoke'
|
615
|
+
|
605
616
|
|
606
617
|
df=security_indicator(ticker,indicator,fromdate,todate,ticker_type=ticker_type)
|
607
618
|
|
@@ -621,7 +632,9 @@ def security_indicator(ticker,indicator, \
|
|
621
632
|
print(" #Warning(security_indicator): invalid adjust",adjust)
|
622
633
|
print(" Supported adjust:",adjust_list)
|
623
634
|
adjust='qfq'
|
624
|
-
|
635
|
+
|
636
|
+
if ('Adj' not in indicator):
|
637
|
+
adjust=''
|
625
638
|
if ('Adj' in indicator) and (adjust == ''):
|
626
639
|
adjust='qfq'
|
627
640
|
|
@@ -806,12 +819,27 @@ if __name__ =="__main__":
|
|
806
819
|
ticker='600519.SS'
|
807
820
|
ticker='OR.PA'
|
808
821
|
measures=['Monthly Ret%','Quarterly Ret%','Annual Ret%','XYZ']
|
809
|
-
|
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", \
|
@@ -1411,8 +1446,12 @@ if __name__ =="__main__":
|
|
1411
1446
|
tickers='MSFT'
|
1412
1447
|
measures=['Annual Ret Volatility%','Annual Ret%']
|
1413
1448
|
|
1414
|
-
|
1415
|
-
|
1449
|
+
tickers='NVDA'
|
1450
|
+
tickers='AAPL'
|
1451
|
+
measures=['Close','Adj Close']
|
1452
|
+
|
1453
|
+
fromdate='2024-5-1'
|
1454
|
+
todate='2024-5-30'
|
1416
1455
|
adjust=''
|
1417
1456
|
twinx=False
|
1418
1457
|
loc1='best'
|
@@ -1459,11 +1498,12 @@ def compare_security(tickers,measures,fromdate,todate, \
|
|
1459
1498
|
#如果tickers是一个列表
|
1460
1499
|
if isinstance(tickers,list):
|
1461
1500
|
security_num = len(tickers)
|
1462
|
-
if security_num
|
1501
|
+
if security_num != 0:
|
1502
|
+
if security_num >= 1: ticker1 = tickers[0]
|
1503
|
+
if security_num >= 2: ticker2 = tickers[1]
|
1504
|
+
else:
|
1463
1505
|
print(" #Error(compare_security):security code/codes needed.")
|
1464
1506
|
return None,None
|
1465
|
-
if security_num >= 1: ticker1 = tickers[0]
|
1466
|
-
if security_num >= 2: ticker2 = tickers[1]
|
1467
1507
|
|
1468
1508
|
#判断测度个数
|
1469
1509
|
#如果measures只是一个字符串
|
@@ -1474,43 +1514,67 @@ def compare_security(tickers,measures,fromdate,todate, \
|
|
1474
1514
|
#如果measures是一个列表
|
1475
1515
|
if isinstance(measures,list):
|
1476
1516
|
measure_num = len(measures)
|
1477
|
-
if measure_num
|
1517
|
+
if measure_num != 0:
|
1518
|
+
if measure_num >= 1: measure1 = measures[0]
|
1519
|
+
if measure_num >= 2: measure2 = measures[1]
|
1520
|
+
else:
|
1478
1521
|
print(" #Error(compare_security): a measurement indicator needed.")
|
1479
1522
|
return None,None
|
1480
|
-
if measure_num >= 1: measure1 = measures[0]
|
1481
|
-
if measure_num >= 2: measure2 = measures[1]
|
1482
1523
|
|
1483
1524
|
#解析ticker_type
|
1484
1525
|
if isinstance(ticker_type,str):
|
1485
1526
|
ticker_type1=ticker_type2=ticker_type
|
1486
1527
|
if isinstance(ticker_type,list) and len(ticker_type)==1:
|
1487
1528
|
ticker_type1=ticker_type2=ticker_type[0]
|
1488
|
-
if isinstance(ticker_type,list) and len(ticker_type)
|
1529
|
+
if isinstance(ticker_type,list) and len(ticker_type) >= 2:
|
1489
1530
|
ticker_type1=ticker_type[0]
|
1490
1531
|
ticker_type2=ticker_type[1]
|
1491
1532
|
ticker_type_list=[ticker_type1,ticker_type2]
|
1533
|
+
|
1534
|
+
#屏蔽函数内print信息输出的类
|
1535
|
+
import os, sys
|
1536
|
+
class HiddenPrints:
|
1537
|
+
def __enter__(self):
|
1538
|
+
self._original_stdout = sys.stdout
|
1539
|
+
sys.stdout = open(os.devnull, 'w')
|
1540
|
+
|
1541
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
1542
|
+
sys.stdout.close()
|
1543
|
+
sys.stdout = self._original_stdout
|
1492
1544
|
|
1493
1545
|
#单一证券代码+两个测度指标
|
1494
1546
|
if (security_num == 1) and (measure_num >= 2):
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1547
|
+
|
1548
|
+
print(" Searching",ticker1,"for",measure1,"info ... ...")
|
1549
|
+
#复权价判断1
|
1550
|
+
adjust1=adjust
|
1551
|
+
if ('Adj' in measure1) and (adjust1 ==''):
|
1552
|
+
adjust1='qfq'
|
1498
1553
|
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1554
|
+
with HiddenPrints():
|
1555
|
+
#security_indicator未能做到同时获得Close和Adj Close
|
1556
|
+
df1tmp=security_indicator(ticker=ticker1,indicator=measure1,adjust=adjust1, \
|
1557
|
+
fromdate=fromdate,todate=todate, \
|
1558
|
+
source=source, \
|
1559
|
+
ticker_type=ticker_type, \
|
1560
|
+
graph=False)
|
1561
|
+
pltdf1= df1tmp[[measure1]]
|
1562
|
+
|
1563
|
+
print(" Searching",ticker1,"for",measure2,"info ... ...")
|
1564
|
+
#复权价判断2
|
1565
|
+
adjust2=adjust
|
1566
|
+
if ('Adj' in measure2) and (adjust2 ==''):
|
1567
|
+
adjust2='qfq'
|
1568
|
+
|
1569
|
+
with HiddenPrints():
|
1570
|
+
#security_indicator未能做到同时获得Close和Adj Close
|
1571
|
+
df2tmp=security_indicator(ticker=ticker1,indicator=measure2,adjust=adjust2, \
|
1572
|
+
fromdate=fromdate,todate=todate, \
|
1573
|
+
source=source, \
|
1574
|
+
ticker_type=ticker_type, \
|
1575
|
+
graph=False)
|
1576
|
+
|
1577
|
+
pltdf2= df2tmp[[measure2]]
|
1514
1578
|
|
1515
1579
|
pltdf=pd.merge(pltdf1,pltdf2,left_index=True,right_index=True)
|
1516
1580
|
pltdf['ticker']=ticker1
|
@@ -1522,60 +1586,55 @@ def compare_security(tickers,measures,fromdate,todate, \
|
|
1522
1586
|
ticker_type=ticker_type[0],facecolor=facecolor)
|
1523
1587
|
|
1524
1588
|
try:
|
1525
|
-
result1=
|
1589
|
+
result1=pltdf[['ticker',measure1]]
|
1526
1590
|
except:
|
1527
|
-
|
1591
|
+
result1=None
|
1528
1592
|
try:
|
1529
|
-
result2=
|
1593
|
+
result2=pltdf[['ticker',measure2]]
|
1530
1594
|
except:
|
1531
|
-
|
1532
|
-
|
1533
|
-
return result1,result2
|
1595
|
+
result2=None
|
1596
|
+
return result1,result2
|
1534
1597
|
|
1535
1598
|
elif (security_num >= 2) and (measure_num >= 1):
|
1536
1599
|
#双证券+单个测度指标
|
1537
1600
|
if ('Adj' in measure1) and (adjust ==''):
|
1538
1601
|
adjust='qfq'
|
1539
1602
|
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
pltdf1.rename(columns={list(pltdf1)[0]:measure1},inplace=True)
|
1547
|
-
pltdf1['ticker']=ticker1
|
1603
|
+
df1tmp=security_indicator(ticker=ticker1,indicator=measure1,adjust=adjust, \
|
1604
|
+
fromdate=fromdate,todate=todate, \
|
1605
|
+
source=source, \
|
1606
|
+
ticker_type=ticker_type, \
|
1607
|
+
graph=False)
|
1608
|
+
pltdf1=df1tmp[['ticker',measure1]]
|
1548
1609
|
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
pltdf2.rename(columns={list(pltdf2)[0]:measure1},inplace=True)
|
1556
|
-
pltdf2['ticker']=ticker2
|
1610
|
+
df2tmp=security_indicator(ticker=ticker2,indicator=measure1,adjust=adjust, \
|
1611
|
+
fromdate=fromdate,todate=todate, \
|
1612
|
+
source=source, \
|
1613
|
+
ticker_type=ticker_type, \
|
1614
|
+
graph=False)
|
1615
|
+
pltdf2=df2tmp[['ticker',measure1]]
|
1557
1616
|
|
1558
1617
|
#绘制双证券单指标对比图
|
1559
1618
|
if graph:
|
1560
|
-
|
1561
1619
|
comp_2securities_1measure(pltdf1,pltdf2,measure1,twinx=twinx, \
|
1562
1620
|
loc1=loc1,loc2=loc2,graph=graph, \
|
1563
1621
|
ticker_type=ticker_type_list,facecolor=facecolor)
|
1564
1622
|
|
1565
1623
|
try:
|
1566
1624
|
result1=pltdf1[[measure1]]
|
1625
|
+
except:
|
1626
|
+
print(" #Error(compare_secuirty): measure",measure1,"not found for",ticker1)
|
1627
|
+
result1=None
|
1628
|
+
try:
|
1567
1629
|
result2=pltdf2[[measure1]]
|
1568
1630
|
except:
|
1569
|
-
print(" #Error(compare_secuirty): measure",measure1,"not found")
|
1570
|
-
|
1571
|
-
|
1572
|
-
return result1,result2
|
1631
|
+
print(" #Error(compare_secuirty): measure",measure1,"not found for",ticker2)
|
1632
|
+
result2=None
|
1633
|
+
return result1,result2
|
1573
1634
|
|
1574
1635
|
else:
|
1575
|
-
print(" #
|
1636
|
+
print(" #Warning(compare_secuirty):only support the situations of 1 ticker + 2 measures or 2 tickers + 1 measure.")
|
1576
1637
|
return None,None
|
1577
|
-
|
1578
|
-
return result1,result2
|
1579
1638
|
|
1580
1639
|
|
1581
1640
|
#==============================================================================
|
@@ -2526,16 +2585,23 @@ def stock_dividend(ticker,start,end,facecolor='whitesmoke',fontcolor='black'):
|
|
2526
2585
|
|
2527
2586
|
titletxt=text_lang("股票分红历史","Stock Dividend")+': '+tname
|
2528
2587
|
periodtxt=text_lang("历史期间:","Period:")+' '+fromdatey2md+"-"+todatey2md
|
2529
|
-
sourcetxt=text_lang("数据来源: 雅虎财经,","Data source: Yahoo Finance,")
|
2588
|
+
#sourcetxt=text_lang("数据来源: 雅虎财经,","Data source: Yahoo Finance,")
|
2589
|
+
sourcetxt=text_lang("数据来源: 雅虎财经","Data source: Yahoo Finance")
|
2590
|
+
footnote=periodtxt+'\n'+sourcetxt
|
2530
2591
|
|
2531
2592
|
#修改列命为英文
|
2532
|
-
divprt.columns = [text_lang('序号','No.'),text_lang('日期','Date'),text_lang('星期','Weekday'),text_lang('
|
2593
|
+
divprt.columns = [text_lang('序号','No.'),text_lang('日期','Date'),text_lang('星期','Weekday'),text_lang('每股股息','Dividend/share')]
|
2533
2594
|
|
2534
2595
|
"""
|
2535
2596
|
print(divprt.to_string(index=False))
|
2536
2597
|
"""
|
2537
|
-
print('
|
2598
|
+
#print('') #空一行
|
2538
2599
|
|
2600
|
+
df_display_CSS(divprt,titletxt=titletxt,footnote=footnote,facecolor='papayawhip',decimals=2, \
|
2601
|
+
first_col_align='center',second_col_align='center', \
|
2602
|
+
last_col_align='right',other_col_align='center')
|
2603
|
+
|
2604
|
+
"""
|
2539
2605
|
disph=divprt.style.hide() #不显示索引列
|
2540
2606
|
dispp=disph.format(precision=4) #设置带有小数点的列精度调整为小数点后2位
|
2541
2607
|
#设置标题/列名对齐
|
@@ -2556,6 +2622,7 @@ def stock_dividend(ticker,start,end,facecolor='whitesmoke',fontcolor='black'):
|
|
2556
2622
|
import datetime; todaydt=datetime.date.today(); todayy2md=todaydt.strftime('%y/%m/%d')
|
2557
2623
|
#print('\n*** '+sourcetxt,today)
|
2558
2624
|
print(sourcetxt,todayy2md)
|
2625
|
+
"""
|
2559
2626
|
|
2560
2627
|
return divdf
|
2561
2628
|
|
@@ -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
|
@@ -138,7 +138,7 @@ siat/valuation.py,sha256=NKfeZMdDJOW42oLVHob6eSVBXUqlN1OCnnzwyGAst8c,48855
|
|
138
138
|
siat/valuation_china.py,sha256=EkZQaVkoBjM0c4MCNbaX-bMnlG0e3FXeaWczZDnkptU,67784
|
139
139
|
siat/valuation_market_china_test.py,sha256=gbJ0ioauuo4koTPH6WKUkqcXiQPafnbhU5eKJ6lpdLA,1571
|
140
140
|
siat/var_model_validation.py,sha256=R0caWnuZarrRg9939hxh3vJIIpIyPfvelYmzFNZtPbo,14910
|
141
|
-
siat-3.2.
|
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
|