siat 3.4.37__py3-none-any.whl → 3.5.2__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 +230 -0
- siat/fund_china.py +5 -2
- siat/grafix.py +15 -2
- siat/risk_adjusted_return2.py +50 -40
- siat/sector_china.py +351 -114
- siat/security_price2.py +1 -0
- siat/security_prices.py +44 -11
- siat/security_trend2.py +17 -8
- siat/stock.py +88 -36
- siat/stock_technical.py +6 -6
- siat/translate.py +411 -161
- siat/translate_241003_keep.py +4300 -0
- siat/valuation.py +21 -7
- siat/valuation_china.py +54 -18
- {siat-3.4.37.dist-info → siat-3.5.2.dist-info}/METADATA +1 -1
- {siat-3.4.37.dist-info → siat-3.5.2.dist-info}/RECORD +19 -18
- {siat-3.4.37.dist-info → siat-3.5.2.dist-info}/WHEEL +1 -1
- {siat-3.4.37.dist-info → siat-3.5.2.dist-info}/LICENSE +0 -0
- {siat-3.4.37.dist-info → siat-3.5.2.dist-info}/top_level.txt +0 -0
siat/security_price2.py
CHANGED
siat/security_prices.py
CHANGED
@@ -717,6 +717,8 @@ if __name__=='__main__':
|
|
717
717
|
ticker_type='bond'
|
718
718
|
|
719
719
|
ticker='801002.SW'
|
720
|
+
ticker='807110.SW'
|
721
|
+
|
720
722
|
ticker='sz100303'
|
721
723
|
ticker='100303.SZ'
|
722
724
|
ticker_type='auto'
|
@@ -1833,13 +1835,13 @@ def calc_rolling_return(drdf, period="Weekly"):
|
|
1833
1835
|
retname1=period+" Ret"
|
1834
1836
|
retname2=period+" Ret%"
|
1835
1837
|
import numpy as np
|
1836
|
-
drdf[retname1]=np.exp(drdf["log(Daily Ret)"].rolling(rollingnum).sum())-1.0
|
1838
|
+
drdf[retname1]=np.exp(drdf["log(Daily Ret)"].rolling(rollingnum,min_periods=1).sum())-1.0
|
1837
1839
|
drdf[retname2]=drdf[retname1]*100.0
|
1838
1840
|
|
1839
1841
|
#计算滚动收益率:基于调整收盘价
|
1840
1842
|
retname3=period+" Adj Ret"
|
1841
1843
|
retname4=period+" Adj Ret%"
|
1842
|
-
drdf[retname3]=np.exp(drdf["log(Daily Adj Ret)"].rolling(rollingnum).sum())-1.0
|
1844
|
+
drdf[retname3]=np.exp(drdf["log(Daily Adj Ret)"].rolling(rollingnum,min_periods=1).sum())-1.0
|
1843
1845
|
drdf[retname4]=drdf[retname3]*100.0
|
1844
1846
|
|
1845
1847
|
return drdf
|
@@ -1932,12 +1934,12 @@ def rolling_price_volatility(df, period="Weekly"):
|
|
1932
1934
|
retname1=period+" Price Volatility"
|
1933
1935
|
import numpy as np
|
1934
1936
|
#df[retname1]=df["Close"].rolling(rollingnum).apply(lambda x: np.std(x,ddof=1)/np.mean(x)*np.sqrt(len(x)))
|
1935
|
-
df[retname1]=df["Close"].rolling(rollingnum).apply(lambda x: np.std(x,ddof=1)/np.mean(x))
|
1937
|
+
df[retname1]=df["Close"].rolling(rollingnum,min_periods=1).apply(lambda x: np.std(x,ddof=1)/np.mean(x))
|
1936
1938
|
|
1937
1939
|
#计算滚动期间的调整标准差价格风险:基于调整收盘价
|
1938
1940
|
retname3=period+" Adj Price Volatility"
|
1939
1941
|
#df[retname3]=df["Adj Close"].rolling(rollingnum).apply(lambda x: np.std(x,ddof=1)/np.mean(x)*np.sqrt(len(x)))
|
1940
|
-
df[retname3]=df["Adj Close"].rolling(rollingnum).apply(lambda x: np.std(x,ddof=1)/np.mean(x))
|
1942
|
+
df[retname3]=df["Adj Close"].rolling(rollingnum,min_periods=1).apply(lambda x: np.std(x,ddof=1)/np.mean(x))
|
1941
1943
|
|
1942
1944
|
return df
|
1943
1945
|
|
@@ -1979,6 +1981,16 @@ if __name__ =="__main__":
|
|
1979
1981
|
|
1980
1982
|
|
1981
1983
|
#==============================================================================
|
1984
|
+
if __name__ =="__main__":
|
1985
|
+
ticker='301161.SZ';
|
1986
|
+
ticker='600519.SS';
|
1987
|
+
start='2022-1-1'; end='2024-9-30'
|
1988
|
+
pricedf,found=get_price_1ticker_mixed(ticker=ticker,fromdate=start,todate=end)
|
1989
|
+
rardf1=calc_daily_return(pricedf)
|
1990
|
+
rardf2=calc_rolling_return(rardf1,period=ret_period)
|
1991
|
+
df=rardf2
|
1992
|
+
period="Annual"
|
1993
|
+
|
1982
1994
|
def rolling_ret_volatility(df, period="Weekly"):
|
1983
1995
|
"""
|
1984
1996
|
功能:基于单个证券的期间收益率, 计算其滚动收益率波动风险
|
@@ -1990,7 +2002,7 @@ def rolling_ret_volatility(df, period="Weekly"):
|
|
1990
2002
|
#检查period类型
|
1991
2003
|
periodlist = ["Weekly","Monthly","Quarterly","Annual"]
|
1992
2004
|
if not (period in periodlist):
|
1993
|
-
print("
|
2005
|
+
print(" #Warning(rolling_ret_volatility), only support",periodlist)
|
1994
2006
|
return None
|
1995
2007
|
|
1996
2008
|
#换算期间对应的实际交易天数
|
@@ -2002,14 +2014,18 @@ def rolling_ret_volatility(df, period="Weekly"):
|
|
2002
2014
|
retname1=period+" Ret Volatility"
|
2003
2015
|
retname2=retname1+'%'
|
2004
2016
|
import numpy as np
|
2005
|
-
|
2017
|
+
#min_periods=1: 一些股票上市期间短,可能出现数据量不足,进而导致年度波动率全为空
|
2018
|
+
df[retname1]=df[periodret].rolling(window=rollingnum,min_periods=1).apply(lambda x: np.std(x,ddof=1))
|
2019
|
+
if df[retname1].isnull().all():
|
2020
|
+
print(" #Warning(rolling_ret_volatility): "+retname1+" is all nan becos of insufficient data for period "+period)
|
2021
|
+
|
2006
2022
|
df[retname2]=df[retname1]*100.0
|
2007
2023
|
|
2008
2024
|
#计算滚动标准差:基于调整收益率
|
2009
2025
|
periodadjret=period+" Adj Ret"
|
2010
2026
|
retname3=period+" Adj Ret Volatility"
|
2011
2027
|
retname4=retname3+'%'
|
2012
|
-
df[retname3]=df[periodadjret].rolling(rollingnum).apply(lambda x: np.std(x,ddof=1))
|
2028
|
+
df[retname3]=df[periodadjret].rolling(window=rollingnum,min_periods=1).apply(lambda x: np.std(x,ddof=1))
|
2013
2029
|
df[retname4]=df[retname3]*100.0
|
2014
2030
|
|
2015
2031
|
return df
|
@@ -2120,14 +2136,14 @@ def rolling_ret_lpsd(df, period="Weekly"):
|
|
2120
2136
|
retname1=period+" Ret LPSD"
|
2121
2137
|
retname2=retname1+'%'
|
2122
2138
|
#import numpy as np
|
2123
|
-
df[retname1]=df[periodret].rolling(rollingnum).apply(lambda x: lpsd(x))
|
2139
|
+
df[retname1]=df[periodret].rolling(rollingnum,min_periods=1).apply(lambda x: lpsd(x))
|
2124
2140
|
df[retname2]=df[retname1]*100.0
|
2125
2141
|
|
2126
2142
|
#计算滚动下偏标准差:基于调整收益率
|
2127
2143
|
periodadjret=period+" Adj Ret"
|
2128
2144
|
retname3=period+" Adj Ret LPSD"
|
2129
2145
|
retname4=retname3+'%'
|
2130
|
-
df[retname3]=df[periodadjret].rolling(rollingnum).apply(lambda x: lpsd(x))
|
2146
|
+
df[retname3]=df[periodadjret].rolling(rollingnum,min_periods=1).apply(lambda x: lpsd(x))
|
2131
2147
|
df[retname4]=df[retname3]*100.0
|
2132
2148
|
|
2133
2149
|
return df
|
@@ -2839,14 +2855,31 @@ def fetch_price_swindex(ticker,start,end,info_types=['Close','Volume'],adjust=-2
|
|
2839
2855
|
ticker6=ticker[:6]
|
2840
2856
|
try:
|
2841
2857
|
prices= ak.index_hist_sw(symbol=ticker6,period="day")
|
2842
|
-
except:
|
2858
|
+
except:
|
2859
|
+
try:
|
2860
|
+
dft = ak.index_hist_fund_sw(symbol=ticker6,period="day")
|
2861
|
+
dft['代码']=ticker6
|
2862
|
+
dft['收盘']=dft['收盘指数']
|
2863
|
+
dft['开盘']=dft['收盘指数']
|
2864
|
+
dft['最高']=dft['收盘指数']
|
2865
|
+
dft['最低']=dft['收盘指数']
|
2866
|
+
dft['成交量']=0; dft['成交额']=0
|
2867
|
+
|
2868
|
+
prices=dft
|
2869
|
+
except:
|
2870
|
+
print(" #Error(fetch_price_swindex): failed to fetch prices for",ticker)
|
2871
|
+
return None
|
2843
2872
|
|
2844
2873
|
found=df_have_data(prices)
|
2845
2874
|
if found not in ['Found','Empty']:
|
2846
2875
|
pass
|
2847
2876
|
return df
|
2848
2877
|
|
2849
|
-
|
2878
|
+
#强制修改列名
|
2879
|
+
#prices.columns=['Code','Date','Close','Open','High','Low','Volume','Amount']
|
2880
|
+
prices.rename(columns={'代码':'Code','日期':'Date','收盘':'Close','开盘':'Open', \
|
2881
|
+
'最高':'High','最低':'Low','成交量':'Volume','成交额':'Amount'}, inplace=True)
|
2882
|
+
|
2850
2883
|
million=1000000
|
2851
2884
|
prices['Volume']=prices['Volume']*million
|
2852
2885
|
prices['Amount']=prices['Amount']*million
|
siat/security_trend2.py
CHANGED
@@ -88,11 +88,20 @@ if __name__=='__main__':
|
|
88
88
|
|
89
89
|
#测试组6
|
90
90
|
ticker="851242.SW"
|
91
|
-
|
91
|
+
ticker='807110.SW'
|
92
|
+
indicator='Close'; adjust=''
|
92
93
|
start="2024-1-1"
|
93
|
-
end="2024-
|
94
|
+
end="2024-9-30"
|
94
95
|
ticker_type='auto'
|
95
96
|
|
97
|
+
#测试组6
|
98
|
+
ticker='301161.SZ'
|
99
|
+
indicator='sharpe'; adjust=''
|
100
|
+
start="2024-1-1"
|
101
|
+
end="2024-9-30"
|
102
|
+
ticker_type='auto'
|
103
|
+
|
104
|
+
|
96
105
|
attention_value=''; average_value=False
|
97
106
|
kline=False; kline_demo=False; mav=[5,10,20]
|
98
107
|
dividend=False; split=False
|
@@ -104,8 +113,8 @@ if __name__=='__main__':
|
|
104
113
|
smooth=True; date_range=False; date_freq=False
|
105
114
|
preprocess='none'; scaling_option='change%'
|
106
115
|
annotate=False; annotate_value=False
|
107
|
-
mark_top=
|
108
|
-
printout=
|
116
|
+
mark_top=True; mark_bottom=True; mark_end=True
|
117
|
+
printout=True; source='auto'
|
109
118
|
ticker_type='auto'
|
110
119
|
facecolor='papayawhip'
|
111
120
|
|
@@ -226,7 +235,7 @@ def security_trend(ticker,indicator='Close',adjust='', \
|
|
226
235
|
#print(" #Warning(security_trend): only RAR and CAPM beta indicators support portfolio")
|
227
236
|
#print(" All other indicators do not support portfolio")
|
228
237
|
else:
|
229
|
-
print(" #
|
238
|
+
print(" #Warning(security_trend): unrecognizable security codes",ticker)
|
230
239
|
return None
|
231
240
|
|
232
241
|
# 检查日期:如有错误自动更正
|
@@ -292,7 +301,7 @@ def security_trend(ticker,indicator='Close',adjust='', \
|
|
292
301
|
measures=indicator
|
293
302
|
indicator_num=len(indicator)
|
294
303
|
else:
|
295
|
-
print(" #
|
304
|
+
print(" #Warning(security_trend): unrecognizeable indicator(s) for",indicator)
|
296
305
|
return None
|
297
306
|
|
298
307
|
# 检查趋势指标
|
@@ -462,7 +471,7 @@ def security_trend(ticker,indicator='Close',adjust='', \
|
|
462
471
|
return df
|
463
472
|
|
464
473
|
# 情形6:单个或多个证券,单个或多个RAR指标,支持投资组合=======================
|
465
|
-
#
|
474
|
+
# 注意:收益率类型支持滚动收益率和扩展收益率,但不建议混合使用,因为难以解释结果
|
466
475
|
# 复权价:使用ret_type为xx Adj Ret%即可
|
467
476
|
if indicator_group2:
|
468
477
|
df=compare_rar_security(ticker=tickers,start=fromdate,end=todate,rar=measures, \
|
@@ -491,7 +500,7 @@ def security_trend(ticker,indicator='Close',adjust='', \
|
|
491
500
|
return df
|
492
501
|
|
493
502
|
|
494
|
-
# 情形8:估值指标PE/PB/MV/ROE
|
503
|
+
# 情形8:估值指标PE/PB/MV/ROE,仅针对股票/行业指数代码,无需ticker_type========
|
495
504
|
if indicator_group3:
|
496
505
|
df=security_valuation(tickers=tickers,indicators=measures,start=fromdate,end=todate, \
|
497
506
|
preprocess=preprocess,scaling_option=scaling_option, \
|
siat/stock.py
CHANGED
@@ -474,10 +474,10 @@ def stock_price(ticker,fromdate,todate,adj=False, \
|
|
474
474
|
lang=check_language()
|
475
475
|
if lang == 'English':
|
476
476
|
titletxt=texttranslate("Security Price Trend:")+tickername
|
477
|
-
footnote=texttranslate("Data source: Sina/Stooq/Yahoo/
|
477
|
+
footnote=texttranslate("Data source: Sina/EM/Stooq/Yahoo/SWHY, ")+str(today)
|
478
478
|
else:
|
479
479
|
titletxt=texttranslate("证券价格走势图:")+tickername
|
480
|
-
footnote=texttranslate("数据来源:Sina/EM/Stooq/Yahoo,")+str(today)
|
480
|
+
footnote=texttranslate("数据来源:Sina/EM/Stooq/Yahoo/SWHY,")+str(today)
|
481
481
|
|
482
482
|
pricetype='Close'
|
483
483
|
import pandas as pd
|
@@ -615,6 +615,7 @@ if __name__ =="__main__":
|
|
615
615
|
|
616
616
|
# 测试组5
|
617
617
|
ticker='851242.SW'
|
618
|
+
ticker='807110.SW'
|
618
619
|
indicator='Close'
|
619
620
|
fromdate='2024-5-1'; todate='2024-5-20'
|
620
621
|
adjust=''
|
@@ -716,7 +717,7 @@ def security_indicator(ticker,indicator, \
|
|
716
717
|
titletxt1=text_lang("证券趋势分析:","Security Trend: ")
|
717
718
|
titletxt=titletxt1+ticker_name(ticker,ticker_type=ticker_type)
|
718
719
|
import datetime; todaydt = datetime.date.today()
|
719
|
-
sourcetxt=text_lang("数据来源:Sina/EM/Stooq/Yahoo,","Data source: Sina/EM/Stooq/Yahoo, ")
|
720
|
+
sourcetxt=text_lang("数据来源:Sina/EM/Stooq/Yahoo/SWHY,","Data source: Sina/EM/Stooq/Yahoo/SWHY, ")
|
720
721
|
footnote=sourcetxt+str(todaydt)
|
721
722
|
collabel=ectranslate(indicator)
|
722
723
|
|
@@ -727,8 +728,10 @@ def security_indicator(ticker,indicator, \
|
|
727
728
|
if tickersplit[1].upper() in ['M','B']:
|
728
729
|
ylabeltxt="stooq_MB" #特殊标志,告知绘图函数不显示某些标记
|
729
730
|
except: pass
|
730
|
-
|
731
|
-
|
731
|
+
|
732
|
+
ind_max=erdf3[indicator].max(); ind_min=erdf3[indicator].min()
|
733
|
+
if ind_max * ind_min <0:
|
734
|
+
#if 'Ret%' in indicator:
|
732
735
|
zeroline=True
|
733
736
|
|
734
737
|
plot_line(erdf3,indicator,collabel,ylabeltxt,titletxt,footnote,datatag=datatag, \
|
@@ -798,7 +801,7 @@ def stock_ret(ticker,fromdate,todate, \
|
|
798
801
|
return
|
799
802
|
|
800
803
|
import datetime; todaydt = datetime.date.today()
|
801
|
-
footnote=text_lang("数据来源:Sina/EM/Stooq/Yahoo,","Data source: Sina/EM/Stooq/Yahoo, ")+str(todaydt)
|
804
|
+
footnote=text_lang("数据来源:Sina/EM/Stooq/Yahoo/SWHY,","Data source: Sina/EM/Stooq/Yahoo/SWHY, ")+str(todaydt)
|
802
805
|
collabel=ectranslate(rtype)
|
803
806
|
ylabeltxt=ectranslate(rtype)
|
804
807
|
titletxt=text_lang("证券趋势分析:","Security Trend: ")+ticker_name(ticker,ticker_type=ticker_type)+text_lang(",收益率",", Rate of Return")
|
@@ -869,6 +872,8 @@ def security_mindicators(ticker,measures,
|
|
869
872
|
annotate:这里仅为预留,暂时未作处理
|
870
873
|
smooth:样本数目超过一定数量就默认忽略
|
871
874
|
"""
|
875
|
+
DEBUG=False
|
876
|
+
|
872
877
|
# 提前开始日期
|
873
878
|
#fromdate1=date_adjust(fromdate,adjust=-365*3)
|
874
879
|
|
@@ -937,15 +942,23 @@ def security_mindicators(ticker,measures,
|
|
937
942
|
|
938
943
|
y_label=text_lang('证券指标',"Indicator")
|
939
944
|
import datetime; todaydt = datetime.date.today()
|
940
|
-
x_label=text_lang("数据来源:Sina/EM/Stooq/Yahoo,","Data source: Sina/EM/Stooq/Yahoo, ")+str(todaydt)
|
945
|
+
x_label=text_lang("数据来源:Sina/EM/Stooq/Yahoo/SWHY,","Data source: Sina/EM/Stooq/Yahoo/SWHY, ")+str(todaydt)
|
941
946
|
|
942
|
-
axhline_value=0
|
943
|
-
|
944
|
-
for c in
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
947
|
+
axhline_value=0; axhline_label=''
|
948
|
+
above_zero=0; below_zero=0
|
949
|
+
for c in list(df):
|
950
|
+
c_max=df[c].max(); c_min=df[c].min()
|
951
|
+
try:
|
952
|
+
if c_max>0 or c_min>0: above_zero+=1
|
953
|
+
if c_max<0 or c_min<0: below_zero+=1
|
954
|
+
except: continue
|
955
|
+
|
956
|
+
if above_zero>0 and below_zero>0: #有正有负
|
957
|
+
if DEBUG:
|
958
|
+
print("DEBUG: draw axhline=0")
|
959
|
+
#if 'Ret%' in c:
|
960
|
+
axhline_value=0
|
961
|
+
axhline_label='零线'
|
949
962
|
|
950
963
|
titletxt=text_lang("证券趋势分析:","Security Trend: ")+ticker_name(ticker,ticker_type=ticker_type)
|
951
964
|
|
@@ -1005,7 +1018,7 @@ def stock_price_volatility(ticker,fromdate,todate,type="Weekly Price Volatility"
|
|
1005
1018
|
|
1006
1019
|
titletxt=texttranslate("证券价格波动风险走势图:")+ticker_name(ticker)
|
1007
1020
|
import datetime; today = datetime.date.today()
|
1008
|
-
footnote=texttranslate("数据来源:Sina/EM/Stooq/Yahoo,")+str(today)
|
1021
|
+
footnote=texttranslate("数据来源:Sina/EM/Stooq/Yahoo/SWHY,")+str(today)
|
1009
1022
|
collabel=ectranslate(type)
|
1010
1023
|
ylabeltxt=ectranslate(type)
|
1011
1024
|
pltdf=erdf[erdf.index >= fromdate]
|
@@ -1062,7 +1075,7 @@ def price_volatility2(pricedf,ticker,fromdate,todate, \
|
|
1062
1075
|
|
1063
1076
|
titletxt=text_lang("证券趋势分析:","Security Trend: ")+ticker_name(ticker,ticker_type=ticker_type)+text_lang(",价格波动风险",", Price Volatility Risk")
|
1064
1077
|
import datetime; todaydt = datetime.date.today()
|
1065
|
-
footnote=texttranslate("数据来源:Sina/EM/Stooq/Yahoo,")+str(todaydt)
|
1078
|
+
footnote=texttranslate("数据来源:Sina/EM/Stooq/Yahoo/SWHY,")+str(todaydt)
|
1066
1079
|
collabel=ectranslate(type)
|
1067
1080
|
ylabeltxt=ectranslate(type)
|
1068
1081
|
pltdf=erdf[erdf.index >= fromdate]
|
@@ -1121,7 +1134,7 @@ def stock_ret_volatility(ticker,fromdate,todate,type="Weekly Ret Volatility%",da
|
|
1121
1134
|
|
1122
1135
|
titletxt=texttranslate("证券收益率波动风险走势图:")+ticker_name(ticker)
|
1123
1136
|
import datetime; today = datetime.date.today()
|
1124
|
-
footnote=texttranslate("数据来源:Sina/EM/Stooq/Yahoo,")+str(today)
|
1137
|
+
footnote=texttranslate("数据来源:Sina/EM/Stooq/Yahoo/SWHY,")+str(today)
|
1125
1138
|
collabel=ectranslate(type)
|
1126
1139
|
ylabeltxt=ectranslate(type)
|
1127
1140
|
pltdf=erdf[erdf.index >= fromdate]
|
@@ -1181,7 +1194,7 @@ def ret_volatility2(retdf,ticker,fromdate,todate, \
|
|
1181
1194
|
|
1182
1195
|
titletxt=text_lang("证券趋势分析:","Security Trend: ")+ticker_name(ticker,ticker_type=ticker_type)+text_lang(",收益率波动风险",", Return Volatility Risk")
|
1183
1196
|
import datetime; todaydt = datetime.date.today()
|
1184
|
-
footnote=text_lang("数据来源:Sina/EM/Stooq/Yahoo,","Data source: Sina/EM/Stooq/Yahoo, ")+str(todaydt)
|
1197
|
+
footnote=text_lang("数据来源:Sina/EM/Stooq/Yahoo/SWHY,","Data source: Sina/EM/Stooq/Yahoo/SWHY, ")+str(todaydt)
|
1185
1198
|
collabel=ectranslate(type)
|
1186
1199
|
ylabeltxt=ectranslate(type)
|
1187
1200
|
pltdf=erdf[erdf.index >= fromdate]
|
@@ -1240,7 +1253,7 @@ def ret_lpsd(ticker,fromdate,todate,type="Weekly Ret Volatility%",datatag=False,
|
|
1240
1253
|
|
1241
1254
|
titletxt=texttranslate("证券收益率波动损失风险走势图:")+ticker_name(ticker)
|
1242
1255
|
import datetime; today = datetime.date.today()
|
1243
|
-
footnote=texttranslate("数据来源:Sina/EM/Stooq/Yahoo,")+str(today)
|
1256
|
+
footnote=texttranslate("数据来源:Sina/EM/Stooq/Yahoo/SWHY,")+str(today)
|
1244
1257
|
collabel=ectranslate(type)
|
1245
1258
|
ylabeltxt=ectranslate(type)
|
1246
1259
|
pltdf=erdf[erdf.index >= fromdate]
|
@@ -1298,7 +1311,7 @@ def ret_lpsd2(retdf,ticker,fromdate,todate, \
|
|
1298
1311
|
|
1299
1312
|
titletxt=text_lang("证券趋势分析:","Security Trend: ")+ticker_name(ticker,ticker_type=ticker_type)+text_lang("波动损失风险","Volatility Loss Risk")
|
1300
1313
|
import datetime; todaydt = datetime.date.today()
|
1301
|
-
footnote=text_lang("数据来源:Sina/EM/Stooq/Yahoo,","Data source: Sina/EM/Stooq/Yahoo, ")+str(todaydt)
|
1314
|
+
footnote=text_lang("数据来源:Sina/EM/Stooq/Yahoo/SWHY,","Data source: Sina/EM/Stooq/Yahoo/SWHY, ")+str(todaydt)
|
1302
1315
|
collabel=ectranslate(rtype)
|
1303
1316
|
ylabeltxt=ectranslate(rtype)
|
1304
1317
|
pltdf=erdf[erdf.index >= fromdate]
|
@@ -1361,7 +1374,7 @@ def comp_1security_2measures(df,measure1,measure2,twinx=False, \
|
|
1361
1374
|
titletxt=text_lang("证券趋势分析:","Security Trend: ")+tname
|
1362
1375
|
|
1363
1376
|
import datetime; todaydt = datetime.date.today()
|
1364
|
-
footnote1=text_lang("数据来源:Sina/EM/Stooq/Yahoo,","Source: Sina/EM/Stooq/Yahoo, ")
|
1377
|
+
footnote1=text_lang("数据来源:Sina/EM/Stooq/Yahoo/SWHY,","Source: Sina/EM/Stooq/Yahoo/SWHY, ")
|
1365
1378
|
footnote=footnote1+str(todaydt)
|
1366
1379
|
|
1367
1380
|
#绘图
|
@@ -1380,8 +1393,8 @@ if __name__ =="__main__":
|
|
1380
1393
|
df=stock_ret(ticker,fromdate,todate,graph=False)
|
1381
1394
|
comp_1security_2measures(df,measure1,measure2)
|
1382
1395
|
#==============================================================================
|
1383
|
-
def comp_2securities_1measure(df1,df2,measure,twinx=False,
|
1384
|
-
loc2='
|
1396
|
+
def comp_2securities_1measure(df1,df2,measure,twinx=False, \
|
1397
|
+
loc1='best',loc2='best',graph=True, \
|
1385
1398
|
ticker_type=['auto','auto'],facecolor='whitesmoke'):
|
1386
1399
|
"""
|
1387
1400
|
功能:对比绘制两只证券的相同指标折线图。
|
@@ -1402,7 +1415,13 @@ def comp_2securities_1measure(df1,df2,measure,twinx=False,loc1='upper left', \
|
|
1402
1415
|
#判断是否绘制水平0线
|
1403
1416
|
pricelist=['High','Low','Open','Close','Volume','Adj Close']
|
1404
1417
|
if measure in pricelist: zeroline=False
|
1405
|
-
else:
|
1418
|
+
else:
|
1419
|
+
df_max=max([df1[measure].max(),df2[measure].max()])
|
1420
|
+
df_min=min([df1[measure].min(),df2[measure].min()])
|
1421
|
+
if df_max * df_min >0: #同正同负
|
1422
|
+
zeroline=False
|
1423
|
+
else:
|
1424
|
+
zeroline=True
|
1406
1425
|
|
1407
1426
|
#提取信息
|
1408
1427
|
try:
|
@@ -1431,7 +1450,7 @@ def comp_2securities_1measure(df1,df2,measure,twinx=False,loc1='upper left', \
|
|
1431
1450
|
titletxt=titletxt1+tname1+" vs "+tname2
|
1432
1451
|
|
1433
1452
|
import datetime; todaydt = datetime.date.today()
|
1434
|
-
footnote1=text_lang("数据来源:Sina/EM/Stooq/Yahoo,","Data source: Sina/EM/Stooq/Yahoo, ")
|
1453
|
+
footnote1=text_lang("数据来源:Sina/EM/Stooq/Yahoo/SWHY,","Data source: Sina/EM/Stooq/Yahoo/SWHY, ")
|
1435
1454
|
footnote=footnote1+str(todaydt)+text_lang("统计","")
|
1436
1455
|
|
1437
1456
|
plot_line2(df1,ticker1,measure,label,df2,ticker2,measure,label, \
|
@@ -1569,7 +1588,11 @@ def compare_security(tickers,measures,fromdate,todate, \
|
|
1569
1588
|
source=source, \
|
1570
1589
|
ticker_type=ticker_type, \
|
1571
1590
|
graph=False)
|
1572
|
-
|
1591
|
+
if df_have_data(df1tmp)=="Found":
|
1592
|
+
pltdf1= df1tmp[[measure1]]
|
1593
|
+
else:
|
1594
|
+
print(" #Error(compare_security):no info found for",ticker1,"on",measure1)
|
1595
|
+
return None,None
|
1573
1596
|
|
1574
1597
|
print(" Searching",ticker1,"for",measure2,"info ... ...")
|
1575
1598
|
#复权价判断2
|
@@ -1585,7 +1608,11 @@ def compare_security(tickers,measures,fromdate,todate, \
|
|
1585
1608
|
ticker_type=ticker_type, \
|
1586
1609
|
graph=False)
|
1587
1610
|
|
1588
|
-
|
1611
|
+
if df_have_data(df2tmp)=="Found":
|
1612
|
+
pltdf2= df2tmp[[measure2]]
|
1613
|
+
else:
|
1614
|
+
print(" #Error(compare_security):no info found for",ticker1,"on",measure2)
|
1615
|
+
return None,None
|
1589
1616
|
|
1590
1617
|
pltdf=pd.merge(pltdf1,pltdf2,left_index=True,right_index=True)
|
1591
1618
|
pltdf['ticker']=ticker1
|
@@ -1616,14 +1643,22 @@ def compare_security(tickers,measures,fromdate,todate, \
|
|
1616
1643
|
source=source, \
|
1617
1644
|
ticker_type=ticker_type, \
|
1618
1645
|
graph=False)
|
1619
|
-
|
1646
|
+
if df_have_data(df1tmp)=="Found":
|
1647
|
+
pltdf1=df1tmp[['ticker',measure1]]
|
1648
|
+
else:
|
1649
|
+
print(" #Error(compare_security):no info found for",ticker1,"on",measure1)
|
1650
|
+
return None,None
|
1620
1651
|
|
1621
1652
|
df2tmp=security_indicator(ticker=ticker2,indicator=measure1,adjust=adjust, \
|
1622
1653
|
fromdate=fromdate,todate=todate, \
|
1623
1654
|
source=source, \
|
1624
1655
|
ticker_type=ticker_type, \
|
1625
1656
|
graph=False)
|
1626
|
-
|
1657
|
+
if df_have_data(df2tmp)=="Found":
|
1658
|
+
pltdf2=df2tmp[['ticker',measure1]]
|
1659
|
+
else:
|
1660
|
+
print(" #Error(compare_security):no info found for",ticker2,"on",measure1)
|
1661
|
+
return None,None
|
1627
1662
|
|
1628
1663
|
#绘制双证券单指标对比图
|
1629
1664
|
if graph:
|
@@ -1889,6 +1924,8 @@ def compare_msecurity(tickers,measure,start,end, \
|
|
1889
1924
|
start方式的图形更接近于持有收益率(Exp Ret%),设为默认的缩放方式。
|
1890
1925
|
|
1891
1926
|
"""
|
1927
|
+
DEBUG=False
|
1928
|
+
|
1892
1929
|
# 应对导入失灵的函数
|
1893
1930
|
from siat.common import upper_ticker
|
1894
1931
|
tickers=upper_ticker(tickers)
|
@@ -1906,7 +1943,7 @@ def compare_msecurity(tickers,measure,start,end, \
|
|
1906
1943
|
if isinstance(measure,list):
|
1907
1944
|
measure=measure[0]
|
1908
1945
|
|
1909
|
-
print(" Searching for multiple
|
1946
|
+
print(" Searching for multiple securities for",measure,"...")
|
1910
1947
|
#屏蔽函数内print信息输出的类
|
1911
1948
|
import os, sys
|
1912
1949
|
class HiddenPrints:
|
@@ -1973,8 +2010,8 @@ def compare_msecurity(tickers,measure,start,end, \
|
|
1973
2010
|
#y_label='指标'
|
1974
2011
|
y_label='指标对比'
|
1975
2012
|
|
1976
|
-
x_label1cn="数据来源: Sina/EM/Stooq/Yahoo,"
|
1977
|
-
x_label1en="Source: Sina/EM/Stooq/Yahoo, "
|
2013
|
+
x_label1cn="数据来源: Sina/EM/Stooq/Yahoo/SWHY,"
|
2014
|
+
x_label1en="Source: Sina/EM/Stooq/Yahoo/SWHY, "
|
1978
2015
|
x_label1=text_lang(x_label1cn,x_label1en)
|
1979
2016
|
import datetime; todaydt = datetime.date.today()
|
1980
2017
|
x_label=x_label1+str(todaydt)
|
@@ -2009,10 +2046,25 @@ def compare_msecurity(tickers,measure,start,end, \
|
|
2009
2046
|
dfs2.fillna(axis=0,method='ffill',inplace=True)
|
2010
2047
|
#dfs2.fillna(axis=0,method='bfill',inplace=True)
|
2011
2048
|
|
2012
|
-
if
|
2049
|
+
if DEBUG:
|
2050
|
+
print("DEBUG: dfs2=",list(dfs2))
|
2051
|
+
|
2052
|
+
above_zero=0; below_zero=0
|
2053
|
+
for c in list(dfs2):
|
2054
|
+
c_max=dfs2[c].max(); c_min=dfs2[c].min()
|
2055
|
+
try:
|
2056
|
+
if c_max>0 or c_min>0: above_zero+=1
|
2057
|
+
if c_max<0 or c_min<0: below_zero+=1
|
2058
|
+
except: continue
|
2059
|
+
|
2060
|
+
if DEBUG:
|
2061
|
+
print("DEBUG: above_zero=",above_zero,'below_zero=',below_zero)
|
2062
|
+
|
2063
|
+
if above_zero>0 and below_zero>0: #有正有负
|
2064
|
+
#if 'Ret%' in measure:
|
2013
2065
|
if axhline_label=='':
|
2014
2066
|
axhline_label='零线'
|
2015
|
-
|
2067
|
+
|
2016
2068
|
#持有类指标的首行置为零
|
2017
2069
|
colList=list(dfs2)
|
2018
2070
|
index1=dfs2.head(1).index.values[0]
|
@@ -2490,7 +2542,7 @@ def candlestick_demo(stkcd,fromdate,todate, \
|
|
2490
2542
|
titletxt0=text_lang("K线图/蜡烛图演示:","Candlestick Chart Demo: ")
|
2491
2543
|
titletxt=titletxt0 + ticker_name(str(stkcd),ticker_type=ticker_type)
|
2492
2544
|
price_txt=text_lang('价格','Price')
|
2493
|
-
source_txt=text_lang("数据来源: Sina/EM/Stooq/Yahoo","Data source: Sina/Stooq/Yahoo")
|
2545
|
+
source_txt=text_lang("数据来源: Sina/EM/Stooq/Yahoo/SWHY","Data source: Sina/Stooq/Yahoo")
|
2494
2546
|
|
2495
2547
|
plt.title(titletxt,fontsize=title_txt_size,fontweight='bold')
|
2496
2548
|
plt.ylabel(price_txt,fontsize=ylabel_txt_size)
|
@@ -3989,7 +4041,7 @@ def compare_mmeasure(ticker,measures,fromdate,todate, \
|
|
3989
4041
|
y_label=''
|
3990
4042
|
import datetime; today = datetime.date.today()
|
3991
4043
|
|
3992
|
-
x_label=text_lang("数据来源: Sina/EM/Stooq/Yahoo,","Data source: Sina/Yahoo/Stooq/EM, ")+str(today)
|
4044
|
+
x_label=text_lang("数据来源: Sina/EM/Stooq/Yahoo/SWHY,","Data source: Sina/Yahoo/Stooq/EM, ")+str(today)
|
3993
4045
|
title_txt=text_lang("证券趋势分析:","Security Trend: ")+ticker_name(ticker)
|
3994
4046
|
|
3995
4047
|
draw_lines(df3,y_label=y_label,x_label=x_label, \
|
siat/stock_technical.py
CHANGED
@@ -987,7 +987,7 @@ def stock_MACD(ticker,start='default',end='default', \
|
|
987
987
|
df2=df1[['Close']+MA_cols]
|
988
988
|
df2.rename(columns={'Close':text_lang('收盘价','Close')},inplace=True)
|
989
989
|
|
990
|
-
title_txt=text_lang("
|
990
|
+
title_txt=text_lang("证券技术分析:","Technical Analysis: ")+ticker_name(ticker,ticker_type)+text_lang(",简单移动均线",", Simple MA Line")
|
991
991
|
|
992
992
|
print(" Rendering graphics ...")
|
993
993
|
draw_lines(df2,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
@@ -1044,7 +1044,7 @@ def stock_MACD(ticker,start='default',end='default', \
|
|
1044
1044
|
|
1045
1045
|
df3=df1[['Close']+EMA_cols]
|
1046
1046
|
df3.rename(columns={'Close':text_lang('收盘价','Close')},inplace=True)
|
1047
|
-
title_txt=text_lang("
|
1047
|
+
title_txt=text_lang("证券技术分析:","Technical Analysis: ")+ticker_name(ticker,ticker_type)+text_lang(",指数移动平均线","Exponential MA Line")
|
1048
1048
|
draw_lines(df3,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
1049
1049
|
data_label=False,resample_freq=resample_freq,smooth=smooth,linewidth=linewidth*2,facecolor=facecolor)
|
1050
1050
|
|
@@ -1111,7 +1111,7 @@ def stock_MACD(ticker,start='default',end='default', \
|
|
1111
1111
|
|
1112
1112
|
df4=df1[['Close','DIF','DEA','MACD']]
|
1113
1113
|
df4.rename(columns={'Close':'收盘价','DIF':'快线DIF','DEA':'慢线DEA','MACD':'柱线MACD'},inplace=True)
|
1114
|
-
title_txt=text_lang("
|
1114
|
+
title_txt=text_lang("证券技术分析:","Technical Analysis: ")+ticker_name(ticker,ticker_type)+",MACD"
|
1115
1115
|
|
1116
1116
|
import datetime as dt; today=dt.date.today()
|
1117
1117
|
source=text_lang("数据来源:Sina/Yahoo/Stooq,","Data source: Sina/Yahoo/Stooq, ")+str(today)
|
@@ -1370,7 +1370,7 @@ def stock_RSI(ticker,start='default',end='default', \
|
|
1370
1370
|
# RSI绘图
|
1371
1371
|
df4=df1[['Close']+RSI_cols]
|
1372
1372
|
df4.rename(columns={'Close':'收盘价'},inplace=True)
|
1373
|
-
title_txt=text_lang("
|
1373
|
+
title_txt=text_lang("证券技术分析:","Technical Analysis: ")+ticker_name(ticker,ticker_type)+text_lang(",RSI",", RSI")
|
1374
1374
|
|
1375
1375
|
import datetime as dt; today=dt.date.today()
|
1376
1376
|
source=text_lang("数据来源:Sina/Yahoo/Stooq,","Data source: Sina/Yahoo/Stooq, ")+str(today)
|
@@ -1640,7 +1640,7 @@ def stock_KDJ(ticker,start='default',end='default', \
|
|
1640
1640
|
# 绘图
|
1641
1641
|
df4=df1[['Close']+KDJ_cols]
|
1642
1642
|
df4.rename(columns={'Close':'收盘价'},inplace=True)
|
1643
|
-
title_txt=text_lang("
|
1643
|
+
title_txt=text_lang("证券技术分析:","Technical Analysis: ")+ticker_name(ticker,ticker_type)+text_lang(",KDJ",", KDJ")
|
1644
1644
|
|
1645
1645
|
import datetime as dt; today=dt.date.today()
|
1646
1646
|
source=text_lang("数据来源:Sina/Yahoo/Stooq,","Data source: Sina/Yahoo/Stooq, ")+str(today)
|
@@ -2271,7 +2271,7 @@ def security_bollinger(ticker,fromdate,todate,boll_days=20, \
|
|
2271
2271
|
|
2272
2272
|
axhline_value=0
|
2273
2273
|
axhline_label=''
|
2274
|
-
title_txt=text_lang("
|
2274
|
+
title_txt=text_lang("证券技术分析:","Technical Analysis: ")+ticker_name(ticker,ticker_type)+text_lang(",布林带",", Bollinger Band")
|
2275
2275
|
|
2276
2276
|
"""
|
2277
2277
|
draw_lines(df1,y_label,x_label,axhline_value,axhline_label,title_txt, \
|