siat 3.4.32__py3-none-any.whl → 3.5.1__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/security_price2.py CHANGED
@@ -38,6 +38,7 @@ if __name__=='__main__':
38
38
 
39
39
  ticker='801010.SW' #申万
40
40
  ticker='851242.SW' #申万
41
+ ticker='807110.SW'
41
42
 
42
43
  ticker='AAPL'
43
44
 
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("*** 错误#1(rolling_ret_volatility),仅支持期间类型:",periodlist)
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
- df[retname1]=df[periodret].rolling(rollingnum).apply(lambda x: np.std(x,ddof=1))
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: pass
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
- prices.columns=['Code','Date','Close','Open','High','Low','Volume','Amount']
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
- indicator='Close'
91
+ ticker='807110.SW'
92
+ indicator='Close'; adjust=''
92
93
  start="2024-1-1"
93
- end="2024-6-30"
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=False; mark_bottom=False; mark_end=False
108
- printout=False; source='auto'
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(" #Error(security_trend): unrecognizable security codes",ticker)
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(" #Error(security_trend): invalid indicator(s) for",indicator)
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, \
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/EM, ")+str(today)
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
- if 'Ret%' in indicator:
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
- axhline_label=''
944
- for c in measures:
945
- if 'Ret%' in c:
946
- axhline_value=0
947
- axhline_label='零线'
948
- break
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,loc1='upper left', \
1384
- loc2='lower left',graph=True, \
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: zeroline=True
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, \
@@ -1889,6 +1908,8 @@ def compare_msecurity(tickers,measure,start,end, \
1889
1908
  start方式的图形更接近于持有收益率(Exp Ret%),设为默认的缩放方式。
1890
1909
 
1891
1910
  """
1911
+ DEBUG=False
1912
+
1892
1913
  # 应对导入失灵的函数
1893
1914
  from siat.common import upper_ticker
1894
1915
  tickers=upper_ticker(tickers)
@@ -1906,7 +1927,7 @@ def compare_msecurity(tickers,measure,start,end, \
1906
1927
  if isinstance(measure,list):
1907
1928
  measure=measure[0]
1908
1929
 
1909
- print(" Searching for multiple security for",measure,"...")
1930
+ print(" Searching for multiple securities for",measure,"...")
1910
1931
  #屏蔽函数内print信息输出的类
1911
1932
  import os, sys
1912
1933
  class HiddenPrints:
@@ -1973,8 +1994,8 @@ def compare_msecurity(tickers,measure,start,end, \
1973
1994
  #y_label='指标'
1974
1995
  y_label='指标对比'
1975
1996
 
1976
- x_label1cn="数据来源: Sina/EM/Stooq/Yahoo,"
1977
- x_label1en="Source: Sina/EM/Stooq/Yahoo, "
1997
+ x_label1cn="数据来源: Sina/EM/Stooq/Yahoo/SWHY,"
1998
+ x_label1en="Source: Sina/EM/Stooq/Yahoo/SWHY, "
1978
1999
  x_label1=text_lang(x_label1cn,x_label1en)
1979
2000
  import datetime; todaydt = datetime.date.today()
1980
2001
  x_label=x_label1+str(todaydt)
@@ -2009,10 +2030,25 @@ def compare_msecurity(tickers,measure,start,end, \
2009
2030
  dfs2.fillna(axis=0,method='ffill',inplace=True)
2010
2031
  #dfs2.fillna(axis=0,method='bfill',inplace=True)
2011
2032
 
2012
- if 'Ret%' in measure:
2033
+ if DEBUG:
2034
+ print("DEBUG: dfs2=",list(dfs2))
2035
+
2036
+ above_zero=0; below_zero=0
2037
+ for c in list(dfs2):
2038
+ c_max=dfs2[c].max(); c_min=dfs2[c].min()
2039
+ try:
2040
+ if c_max>0 or c_min>0: above_zero+=1
2041
+ if c_max<0 or c_min<0: below_zero+=1
2042
+ except: continue
2043
+
2044
+ if DEBUG:
2045
+ print("DEBUG: above_zero=",above_zero,'below_zero=',below_zero)
2046
+
2047
+ if above_zero>0 and below_zero>0: #有正有负
2048
+ #if 'Ret%' in measure:
2013
2049
  if axhline_label=='':
2014
2050
  axhline_label='零线'
2015
-
2051
+
2016
2052
  #持有类指标的首行置为零
2017
2053
  colList=list(dfs2)
2018
2054
  index1=dfs2.head(1).index.values[0]
@@ -2490,7 +2526,7 @@ def candlestick_demo(stkcd,fromdate,todate, \
2490
2526
  titletxt0=text_lang("K线图/蜡烛图演示:","Candlestick Chart Demo: ")
2491
2527
  titletxt=titletxt0 + ticker_name(str(stkcd),ticker_type=ticker_type)
2492
2528
  price_txt=text_lang('价格','Price')
2493
- source_txt=text_lang("数据来源: Sina/EM/Stooq/Yahoo","Data source: Sina/Stooq/Yahoo")
2529
+ source_txt=text_lang("数据来源: Sina/EM/Stooq/Yahoo/SWHY","Data source: Sina/Stooq/Yahoo")
2494
2530
 
2495
2531
  plt.title(titletxt,fontsize=title_txt_size,fontweight='bold')
2496
2532
  plt.ylabel(price_txt,fontsize=ylabel_txt_size)
@@ -3989,7 +4025,7 @@ def compare_mmeasure(ticker,measures,fromdate,todate, \
3989
4025
  y_label=''
3990
4026
  import datetime; today = datetime.date.today()
3991
4027
 
3992
- x_label=text_lang("数据来源: Sina/EM/Stooq/Yahoo,","Data source: Sina/Yahoo/Stooq/EM, ")+str(today)
4028
+ x_label=text_lang("数据来源: Sina/EM/Stooq/Yahoo/SWHY,","Data source: Sina/Yahoo/Stooq/EM, ")+str(today)
3993
4029
  title_txt=text_lang("证券趋势分析:","Security Trend: ")+ticker_name(ticker)
3994
4030
 
3995
4031
  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("证券价格走势分析:","Security Trend: ")+ticker_name(ticker,ticker_type)+text_lang(",简单移动均线",", Simple MA Line")
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("证券价格走势分析:","Security Trend: ")+ticker_name(ticker,ticker_type)+text_lang(",指数移动平均线","Exponential MA Line")
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("证券价格走势分析:","Security Trend: ")+ticker_name(ticker,ticker_type)+",MACD"
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("证券价格走势分析:","Security Trend: ")+ticker_name(ticker,ticker_type)+text_lang(",RSI",", RSI")
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("证券价格走势分析:","Security Trend: ")+ticker_name(ticker,ticker_type)+text_lang(",KDJ",", KDJ")
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("证券价格趋势分析:","Security Trend: ")+ticker_name(ticker,ticker_type)+text_lang(",布林带",", Bollinger Band")
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, \