siat 2.14.1__py3-none-any.whl → 3.0.0__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/allin.py +1 -0
- siat/assets_liquidity.py +16 -16
- siat/beta_adjustment.py +6 -6
- siat/beta_adjustment_china.py +9 -9
- siat/bond.py +71 -67
- siat/capm_beta.py +11 -11
- siat/capm_beta2.py +49 -23
- siat/common.py +451 -76
- siat/compare_cross.py +15 -82
- siat/exchange_bond_china.pickle +0 -0
- siat/fama_french.py +3 -3
- siat/financials.py +15 -15
- siat/financials2.py +8 -8
- siat/financials_china.py +20 -20
- siat/financials_china2.py +25 -25
- siat/fund_china.pickle +0 -0
- siat/fund_china.py +5 -4
- siat/grafix.py +197 -132
- siat/markowitz.py +6 -5
- siat/option_china.py +1 -1
- siat/option_pricing.py +6 -6
- siat/risk_adjusted_return.py +14 -14
- siat/risk_adjusted_return2.py +64 -42
- siat/risk_evaluation.py +32 -32
- siat/risk_free_rate.py +0 -0
- siat/sector_china.py +3 -195
- siat/security_price2.py +616 -0
- siat/security_prices.py +935 -308
- siat/security_trend2.py +28 -47
- siat/stock.py +225 -437
- siat/stock_china.py +19 -19
- siat/stock_info.pickle +0 -0
- siat/stock_technical.py +547 -144
- siat/transaction.py +3 -3
- siat/translate.py +781 -24
- siat/valuation.py +6 -6
- siat/var_model_validation.py +2 -2
- {siat-2.14.1.dist-info → siat-3.0.0.dist-info}/METADATA +1 -1
- {siat-2.14.1.dist-info → siat-3.0.0.dist-info}/RECORD +41 -40
- {siat-2.14.1.dist-info → siat-3.0.0.dist-info}/WHEEL +0 -0
- {siat-2.14.1.dist-info → siat-3.0.0.dist-info}/top_level.txt +0 -0
siat/stock_technical.py
CHANGED
@@ -62,84 +62,126 @@ plt.rcParams['axes.grid']=False
|
|
62
62
|
#==============================================================================
|
63
63
|
|
64
64
|
if __name__ =="__main__":
|
65
|
-
|
66
|
-
start='2022-12-1'
|
67
|
-
end='2023-1-26'
|
68
|
-
ahead_days=30*2
|
69
|
-
start1=date_adjust(start,adjust=-ahead_days)
|
70
|
-
|
71
|
-
df=get_price(ticker,start1,end)
|
72
|
-
|
73
|
-
RSI_days=14
|
65
|
+
RSI_days=[6,24]
|
74
66
|
|
75
67
|
OBV_days=5
|
76
68
|
|
77
|
-
MA_days=[5,20]
|
78
|
-
|
79
|
-
MACD_fastperiod=12
|
80
|
-
MACD_slowperiod=26
|
81
|
-
MACD_signalperiod=9
|
69
|
+
MA_days=[5,20]; MACD_fastperiod=12; MACD_slowperiod=26; MACD_signalperiod=9
|
82
70
|
|
83
|
-
KDJ_fastk_period=5
|
84
|
-
KDJ_slowk_period=3
|
85
|
-
KDJ_slowk_matype=0
|
86
|
-
KDJ_slowd_period=3
|
71
|
+
KDJ_fastk_period=5; KDJ_slowk_period=3; KDJ_slowk_matype=0; KDJ_slowd_period=3
|
87
72
|
KDJ_slowd_matype=0
|
88
73
|
|
89
|
-
VOL_fastperiod=5
|
90
|
-
VOL_slowperiod=10
|
74
|
+
VOL_fastperiod=5; VOL_slowperiod=10
|
91
75
|
|
92
76
|
PSY_days=12
|
93
77
|
|
94
78
|
ARBR_days=26
|
95
79
|
|
96
|
-
|
97
|
-
CRMA_list=[5,10,20]
|
80
|
+
CR_day=16; CR_madays=[5,10,20]
|
98
81
|
|
99
|
-
|
100
|
-
EMV_madays=9
|
82
|
+
EMV_day=14; EMV_madays=9
|
101
83
|
|
102
|
-
BULL_days=20
|
103
|
-
BULL_nbdevup=2
|
104
|
-
BULL_nbdevdn=2
|
105
|
-
BULL_matype=0
|
84
|
+
BULL_days=20; BULL_nbdevup=2; BULL_nbdevdn=2; BULL_matype=0
|
106
85
|
|
107
|
-
|
108
|
-
TRIX_madays=20
|
86
|
+
TRIX_day=12; TRIX_madays=20
|
109
87
|
|
110
|
-
DMA_fastperiod=10
|
111
|
-
DMA_slowperiod=50
|
112
|
-
DMA_madays=10
|
88
|
+
DMA_fastperiod=10; DMA_slowperiod=50; DMA_madays=10
|
113
89
|
|
114
|
-
|
90
|
+
BIAS_days=[6,12,24]
|
115
91
|
|
116
92
|
CCI_days=14
|
117
93
|
|
118
|
-
|
94
|
+
WR_days=[10,6]
|
95
|
+
|
96
|
+
ROC_day=12; ROC_madays=6
|
97
|
+
|
98
|
+
DMI_DIdays=14; DMI_ADXdays=6
|
99
|
+
|
100
|
+
ticker='AAPL'
|
101
|
+
|
102
|
+
start='2024-3-1'; end='2024-4-12'; ahead_days=30*3
|
103
|
+
start1=date_adjust(start,adjust=-ahead_days)
|
104
|
+
|
105
|
+
df=get_price(ticker,start1,end)
|
106
|
+
ta=calc_technical(df,start,end)
|
107
|
+
|
108
|
+
df1,found=get_price_1ticker_mixed(ticker=ticker,fromdate=start1,todate=end)
|
109
|
+
ta=calc_technical(df1,start,end)
|
110
|
+
|
111
|
+
ta=calc_technical(df,start,end)
|
112
|
+
|
113
|
+
#OBV: 纵轴数量级大(千万),判断是否加零线(有正有负),如加零线则不加均值线,不加零线时判断是否可加均值线
|
114
|
+
df_ta[['obv','obv_ma']].plot(title=ticker_name(ticker)+': '+'能量潮OBV')
|
115
|
+
|
116
|
+
#SAR: 纵轴数量级不大
|
117
|
+
df_ta[['sar']].plot(title=ticker_name(ticker)+': '+'抛物转向SAR')
|
118
|
+
|
119
|
+
#VOL: 纵轴数量级大,无零线,可加均值线
|
120
|
+
df_ta[['vol5','vol10']].plot(title=ticker_name(ticker)+': '+'成交量VOL')
|
121
|
+
|
122
|
+
#ARBR: 纵轴数量级不大,无零线,无均值线
|
123
|
+
df_ta[['ar','br']].plot(title=ticker_name(ticker)+': '+'人气与意愿ARBR')
|
124
|
+
|
125
|
+
#CR: 纵轴数量级不大,无零线
|
126
|
+
df_ta[['cr','crma5','crma10','crma20']].plot(title=ticker_name(ticker)+': '+'能力与意愿CR')
|
127
|
+
df_ta[['cr','crma5','crma20']].plot(title=ticker_name(ticker)+': '+'能力与意愿CR')
|
128
|
+
df_ta[['cr']].plot(title=ticker_name(ticker)+': '+'能力与意愿CR')
|
129
|
+
|
130
|
+
#EMV: 纵轴数量级大
|
131
|
+
df_ta[['em','emv','emva']].plot(title=ticker_name(ticker)+': '+'简易波动EMV')
|
132
|
+
df_ta[['em','emv']].plot(title=ticker_name(ticker)+': '+'简易波动EMV')
|
133
|
+
|
134
|
+
#TRIX: 纵轴数量级不大
|
135
|
+
df_ta[['trix','trma']].plot(title=ticker_name(ticker)+': '+'三重指数平滑TRIX')
|
119
136
|
|
120
|
-
|
121
|
-
|
137
|
+
#DMA: 纵轴数量级不大
|
138
|
+
df_ta[['dma']].plot(title=ticker_name(ticker)+': '+'均线差DMA')
|
139
|
+
|
140
|
+
#BIAS: 纵轴数量级不大
|
141
|
+
df_ta[['bias','bias2','bias3']].plot(title=ticker_name(ticker)+': '+'乖离率BIAS')
|
142
|
+
df_ta[['bias']].plot(title=ticker_name(ticker)+': '+'乖离率BIAS')
|
143
|
+
|
144
|
+
#CCI: 纵轴数量级不大
|
145
|
+
df_ta[['cci']].plot(title=ticker_name(ticker)+': '+'顺势CCI')
|
146
|
+
|
147
|
+
#W%R: 纵轴数量级不大
|
148
|
+
df_ta[['wr6','wr10']].plot(title=ticker_name(ticker)+': '+'威廉W%R')
|
149
|
+
|
150
|
+
#ROC: 纵轴数量级不大
|
151
|
+
df_ta[['roc','rocma']].plot(title=ticker_name(ticker)+': '+'变动速率ROC')
|
152
|
+
|
153
|
+
#DMI: 纵轴数量级不大
|
154
|
+
df_ta[['pdi','mdi','adx','adxr']].plot(title=ticker_name(ticker)+': '+'趋向DMI')
|
155
|
+
df_ta[['pdi','mdi']].plot(title=ticker_name(ticker)+': '+'趋向DMI')
|
156
|
+
df_ta[['adx','adxr']].plot(title=ticker_name(ticker)+': '+'趋向DMI')
|
157
|
+
|
158
|
+
#PSY: 纵轴数量级不大
|
159
|
+
df_ta[['psy']].plot(title=ticker_name(ticker)+': '+'心理线PSY')
|
160
|
+
|
122
161
|
|
123
|
-
DMI_DIdays=14
|
124
|
-
DMI_ADXdays=6
|
125
162
|
|
126
163
|
def calc_technical(df,start,end, \
|
127
164
|
RSI_days=14, \
|
128
165
|
OBV_days=5, \
|
166
|
+
|
129
167
|
MA_days=[5,20], \
|
130
168
|
MACD_fastperiod=12,MACD_slowperiod=26,MACD_signalperiod=9, \
|
169
|
+
|
131
170
|
KDJ_fastk_period=9,KDJ_slowk_period=5,KDJ_slowk_matype=1, \
|
132
171
|
KDJ_slowd_period=5,KDJ_slowd_matype=1, \
|
172
|
+
|
133
173
|
VOL_fastperiod=5,VOL_slowperiod=10, \
|
134
174
|
PSY_days=12, \
|
135
175
|
ARBR_days=26, \
|
136
|
-
|
176
|
+
CR_day=16,CR_madays=[5,10,20], \
|
177
|
+
EMV_day=14,EMV_madays=9, \
|
137
178
|
BULL_days=20,BULL_nbdevup=2,BULL_nbdevdn=2,BULL_matype=0, \
|
138
|
-
|
139
|
-
|
179
|
+
DMA_fastperiod=10,DMA_slowperiod=50,DMA_madays=10, \
|
180
|
+
TRIX_day=12,TRIX_madays=20, \
|
181
|
+
BIAS_days=[6,12,24], \
|
140
182
|
CCI_days=14, \
|
141
|
-
|
142
|
-
|
183
|
+
WR_days=[10,6], \
|
184
|
+
ROC_day=12,ROC_madays=6, \
|
143
185
|
DMI_DIdays=14,DMI_ADXdays=6):
|
144
186
|
"""
|
145
187
|
功能:计算股票的技术分析指标
|
@@ -151,7 +193,12 @@ def calc_technical(df,start,end, \
|
|
151
193
|
"""
|
152
194
|
|
153
195
|
# 导入需要的包
|
154
|
-
|
196
|
+
try:
|
197
|
+
import talib
|
198
|
+
except:
|
199
|
+
print(" #Error(calc_technical): lack of necessary package - talib")
|
200
|
+
talib_install_method()
|
201
|
+
return None
|
155
202
|
|
156
203
|
#=========== RSI,相对强弱指标Relative Strength Index
|
157
204
|
"""
|
@@ -167,10 +214,13 @@ def calc_technical(df,start,end, \
|
|
167
214
|
指标解读:
|
168
215
|
80-100 极强 卖出
|
169
216
|
50-80 强 观望,谨慎卖出
|
170
|
-
|
171
|
-
0-
|
217
|
+
30-50 弱 观望,谨慎买入
|
218
|
+
0-30 极弱 买入
|
172
219
|
"""
|
173
|
-
|
220
|
+
if not isinstance(RSI_days,list):
|
221
|
+
RSI_days=[RSI_days]
|
222
|
+
for d in RSI_days:
|
223
|
+
df['rsi'+str(d)] = talib.RSI(df['Close'], timeperiod=d)
|
174
224
|
|
175
225
|
#=========== OBV:能量潮
|
176
226
|
"""
|
@@ -193,7 +243,7 @@ def calc_technical(df,start,end, \
|
|
193
243
|
6、OBV线最大的用处,在于观察股市盘局整理后,何时会脱离盘局以及突破后的未来走势,OBV线变动方向是重要参考指数,其具体的数值并无实际意义。
|
194
244
|
|
195
245
|
缺点
|
196
|
-
|
246
|
+
OBV指标是建立在国外成熟市场上的经验总结。
|
197
247
|
用在内地股市坐庄的股票上就不灵了,这时股价涨得越高成交量反而越少。
|
198
248
|
这是因为主力控盘较重,股价在上涨过程中没有获利筹码加以兑现,所以此时股票会涨得很“疯”,但成交量并不增加,OBV自然就无法发挥作用。
|
199
249
|
另外,涨跌停板的股票也会导致指标失真。
|
@@ -202,7 +252,13 @@ def calc_technical(df,start,end, \
|
|
202
252
|
|
203
253
|
"""
|
204
254
|
df['obv'] = talib.OBV(df['Close'],df['Volume'])
|
205
|
-
|
255
|
+
|
256
|
+
if not isinstance(OBV_days,list):
|
257
|
+
OBV_days=[OBV_days]
|
258
|
+
for d in OBV_days:
|
259
|
+
df['obv_ma'+str(d)] = talib.MA(df['obv'],timeperiod=d)
|
260
|
+
|
261
|
+
df.drop(columns = ['obv'],inplace=True)
|
206
262
|
|
207
263
|
#=========== MA: 简单、加权移动平均
|
208
264
|
"""
|
@@ -213,9 +269,12 @@ def calc_technical(df,start,end, \
|
|
213
269
|
一般来说,现行价格在平均价之上,意味着市场买力(需求)较大,行情看好;
|
214
270
|
反之,行情价在平均价之下,则意味着供过于求,卖压显然较重,行情看淡。
|
215
271
|
"""
|
216
|
-
|
217
|
-
|
218
|
-
|
272
|
+
if not isinstance(MA_days,list):
|
273
|
+
MA_days=[MA_days]
|
274
|
+
|
275
|
+
for d in MA_days:
|
276
|
+
df['ma'+str(d)] = talib.MA(df['Close'],timeperiod=d)
|
277
|
+
df['ema'+str(d)] = talib.EMA(df['Close'],timeperiod=d)
|
219
278
|
|
220
279
|
#=========== MACD:指数平滑异同平均线
|
221
280
|
"""
|
@@ -234,8 +293,8 @@ def calc_technical(df,start,end, \
|
|
234
293
|
今日DEA = 昨日DEA × 8 ÷ 10 + 今日DIF × 2 ÷ 10
|
235
294
|
|
236
295
|
形态解读:
|
237
|
-
1.
|
238
|
-
2.
|
296
|
+
1.DIF、DEA均为正,DIF向上突破DEA,买入信号。
|
297
|
+
2.DIF、DEA均为负,DIF向下跌破DEA,卖出信号。
|
239
298
|
3.DEA线与K线发生背离,行情反转信号。
|
240
299
|
4.分析MACD柱状线,由红变绿(正变负),卖出信号;由绿变红,买入信号。
|
241
300
|
|
@@ -245,7 +304,7 @@ def calc_technical(df,start,end, \
|
|
245
304
|
3. MACD绿转红:MACD值由负变正,市场由空头转为多头。
|
246
305
|
4. MACD红转绿:MACD值由正变负,市场由多头转为空头。
|
247
306
|
"""
|
248
|
-
df['
|
307
|
+
df['DIF'],df['DEA'],df['MACD']=talib.MACD(df['Close'], \
|
249
308
|
fastperiod=MACD_fastperiod, \
|
250
309
|
slowperiod=MACD_slowperiod, \
|
251
310
|
signalperiod=MACD_signalperiod)
|
@@ -264,7 +323,8 @@ def calc_technical(df,start,end, \
|
|
264
323
|
J = 3D – 2K
|
265
324
|
|
266
325
|
指标解读:
|
267
|
-
|
326
|
+
多头区域,空头区域
|
327
|
+
金叉,死叉
|
268
328
|
"""
|
269
329
|
df['kdj_k'],df['kdj_d'] = talib.STOCH(df['High'],df['Low'],df['Close'], \
|
270
330
|
fastk_period=KDJ_fastk_period,
|
@@ -313,8 +373,12 @@ def calc_technical(df,start,end, \
|
|
313
373
|
df['ext_0'] = df['Close']-df['Close'].shift(1)
|
314
374
|
df['ext_1'] = 0
|
315
375
|
df.loc[df['ext_0']>0,'ext_1'] = 1
|
316
|
-
|
317
|
-
|
376
|
+
|
377
|
+
if not isinstance(PSY_days,list):
|
378
|
+
PSY_days=[PSY_days]
|
379
|
+
for d in PSY_days:
|
380
|
+
df['ext_2'] = df['ext_1'].rolling(window=d).sum()
|
381
|
+
df['psy'+str(d)] = (df['ext_2']/float(d))*100
|
318
382
|
|
319
383
|
df.drop(columns = ['ext_0','ext_1','ext_2'],inplace=True)
|
320
384
|
|
@@ -328,14 +392,21 @@ def calc_technical(df,start,end, \
|
|
328
392
|
"""
|
329
393
|
df['h_o'] = df['High'] - df['Open']
|
330
394
|
df['o_l'] = df['Open'] - df['Low']
|
331
|
-
|
332
|
-
|
333
|
-
|
395
|
+
|
396
|
+
if not isinstance(ARBR_days,list):
|
397
|
+
ARBR_days=[ARBR_days]
|
398
|
+
for d in ARBR_days:
|
399
|
+
df['h_o_sum'] = df['h_o'].rolling(window=d).sum()
|
400
|
+
df['o_l_sum'] = df['o_l'].rolling(window=d).sum()
|
401
|
+
df['ar'+str(d)] = (df['h_o_sum']/df['o_l_sum'])*100
|
402
|
+
|
403
|
+
|
334
404
|
df['h_c'] = df['High'] - df['Close']
|
335
405
|
df['c_l'] = df['Close'] - df['Low']
|
336
|
-
|
337
|
-
|
338
|
-
|
406
|
+
for d in ARBR_days:
|
407
|
+
df['h_c_sum'] = df['h_c'].rolling(window=d).sum()
|
408
|
+
df['c_l_sum'] = df['c_l'].rolling(window=d).sum()
|
409
|
+
df['br'+str(d)] = (df['h_c_sum']/df['c_l_sum'])*100
|
339
410
|
|
340
411
|
df.drop(columns = ['h_o','o_l','h_o_sum','o_l_sum','h_c','c_l','h_c_sum','c_l_sum'],inplace=True)
|
341
412
|
|
@@ -355,14 +426,15 @@ def calc_technical(df,start,end, \
|
|
355
426
|
df['m_price'] = (df['High'] + df['Low'])/2
|
356
427
|
df['h_m'] = df['High']-df['m_price'].shift(1)
|
357
428
|
df['m_l'] = df['m_price'].shift(1)-df['Low']
|
358
|
-
|
359
|
-
df['
|
429
|
+
|
430
|
+
df['h_m_sum'] = df['h_m'].rolling(window=CR_day).sum()
|
431
|
+
df['m_l_sum'] = df['m_l'].rolling(window=CR_day).sum()
|
360
432
|
df['cr'] = (df['h_m_sum']/df['m_l_sum'])*100
|
361
433
|
|
362
|
-
for
|
363
|
-
df['
|
434
|
+
for d in CR_madays:
|
435
|
+
df['cr_ma'+str(d)] = talib.MA(df['cr'],timeperiod=d)
|
364
436
|
|
365
|
-
df.drop(columns = ['m_price','h_m','m_l','h_m_sum','m_l_sum'],inplace=True)
|
437
|
+
df.drop(columns = ['m_price','h_m','m_l','h_m_sum','m_l_sum','cr'],inplace=True)
|
366
438
|
|
367
439
|
#=========== EMV: 简易波动指标
|
368
440
|
"""
|
@@ -381,13 +453,17 @@ def calc_technical(df,start,end, \
|
|
381
453
|
df['a'] = (df['High']+df['Low'])/2
|
382
454
|
df['b'] = (df['High'].shift(1)+df['Low'].shift(1))/2
|
383
455
|
df['c'] = df['High'] - df['Low']
|
384
|
-
|
385
456
|
df['Amount']=df['Close']*df['Volume']
|
386
457
|
df['em'] = (df['a']-df['b'])*df['c']/df['Amount']
|
387
|
-
|
388
|
-
df['
|
458
|
+
|
459
|
+
df['emv'] = df['em'].rolling(window=EMV_day).sum()
|
460
|
+
|
461
|
+
if not isinstance(EMV_madays,list):
|
462
|
+
EMV_madays=[EMV_madays]
|
463
|
+
for d in EMV_madays:
|
464
|
+
df['emv_ma'+str(d)] = talib.MA(df['emv'],timeperiod=d)
|
389
465
|
|
390
|
-
df.drop(columns = ['a','b','c'],inplace=True)
|
466
|
+
df.drop(columns = ['a','b','c','em'],inplace=True)
|
391
467
|
|
392
468
|
#=========== BOLL: 布林线指标
|
393
469
|
"""
|
@@ -423,8 +499,14 @@ def calc_technical(df,start,end, \
|
|
423
499
|
"""
|
424
500
|
|
425
501
|
"""
|
426
|
-
df['trix'] = talib.TRIX(df['Close'],timeperiod=
|
427
|
-
|
502
|
+
df['trix'] = talib.TRIX(df['Close'],timeperiod=TRIX_day)
|
503
|
+
|
504
|
+
if not isinstance(TRIX_madays,list):
|
505
|
+
TRIX_madays=[TRIX_madays]
|
506
|
+
for d in TRIX_madays:
|
507
|
+
df['trix_ma'+str(d)] = talib.MA(df['trix'],timeperiod=d)
|
508
|
+
|
509
|
+
df.drop(columns = ['trix'],inplace=True)
|
428
510
|
|
429
511
|
#=========== DMA: 平均线差
|
430
512
|
"""
|
@@ -441,7 +523,11 @@ def calc_technical(df,start,end, \
|
|
441
523
|
df['ma_shortperiod'] = talib.MA(df['Close'],timeperiod=DMA_fastperiod)
|
442
524
|
df['ma_longperiod'] = talib.MA(df['Close'],timeperiod=DMA_slowperiod)
|
443
525
|
df['ddd'] = df['ma_shortperiod'] - df['ma_longperiod']
|
444
|
-
|
526
|
+
|
527
|
+
if not isinstance(DMA_madays,list):
|
528
|
+
DMA_madays=[DMA_madays]
|
529
|
+
for d in DMA_madays:
|
530
|
+
df['dma'+str(d)] = talib.MA(df['ddd'],timeperiod=d)
|
445
531
|
|
446
532
|
df.drop(columns = ['ma_shortperiod','ma_longperiod','ddd'],inplace=True)
|
447
533
|
|
@@ -454,22 +540,24 @@ def calc_technical(df,start,end, \
|
|
454
540
|
12日BIAS>+6%是卖出时机;<-5.5%,为买入时机。
|
455
541
|
24日BIAS>+9%是卖出时机;<-8%,为买入时机。
|
456
542
|
"""
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
df['bias3'] = ((df['Close']-df['ma24'])/df['ma24'])*100
|
543
|
+
if not isinstance(BIAS_days,list):
|
544
|
+
BIAS_days=[BIAS_days]
|
545
|
+
for d in BIAS_days:
|
546
|
+
df['ma'] = talib.MA(df['Close'],timeperiod=d)
|
547
|
+
df['bias'+str(d)] = ((df['Close']-df['ma'])/df['ma'])*100
|
463
548
|
|
464
|
-
df.drop(columns = ['
|
549
|
+
df.drop(columns = ['ma'],inplace=True)
|
465
550
|
|
466
551
|
#=========== CCI: 顺势指标
|
467
552
|
"""
|
468
553
|
计算过程:
|
469
554
|
CCI(N日) = (TP-MA)÷MD÷0.015
|
470
555
|
说明:TP = (最高价+最低价+收盘价)÷3;MA=最近N日收盘价的累计之和÷N;MD=最近N日(MA-收盘价)的累计之和÷N;0.015为计算系数;N为计算周期,默认为14天
|
471
|
-
"""
|
472
|
-
|
556
|
+
"""
|
557
|
+
if not isinstance(CCI_days,list):
|
558
|
+
CCI_days=[CCI_days]
|
559
|
+
for d in CCI_days:
|
560
|
+
df['cci'+str(d)] = talib.CCI(df['High'],df['Low'],df['Close'],timeperiod=d)
|
473
561
|
|
474
562
|
#=========== W%R: 威廉指标
|
475
563
|
"""
|
@@ -481,21 +569,18 @@ def calc_technical(df,start,end, \
|
|
481
569
|
算法:N日内最高价与当日收盘价的差,除以N日内最高价与最低价的差,结果放大100倍。
|
482
570
|
参数:N 统计天数 一般取14天
|
483
571
|
用法:
|
484
|
-
1.低于
|
572
|
+
1.低于30,超买,即将见顶,应及时卖出
|
485
573
|
2.高于80,超卖,即将见底,应伺机买进
|
486
574
|
3.与RSI、MTM指标配合使用,效果更好
|
487
575
|
"""
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
df['h_6'] = df['High'].rolling(window=n2).max()
|
495
|
-
df['l_6'] = df['Low'].rolling(window=n2).min()
|
496
|
-
df['wr6'] = ((df['h_6'] - df['Close']) / (df['h_6'] - df['l_6'])) * 100
|
576
|
+
if not isinstance(WR_days,list):
|
577
|
+
WR_days=[WR_days]
|
578
|
+
for d in WR_days:
|
579
|
+
df['h_10'] = df['High'].rolling(window=d).max()
|
580
|
+
df['l_10'] = df['Low'].rolling(window=d).min()
|
581
|
+
df['wr'+str(d)] = ((df['h_10']-df['Close'])/(df['h_10']-df['l_10']))*100
|
497
582
|
|
498
|
-
df.drop(columns = ['h_10','l_10'
|
583
|
+
df.drop(columns = ['h_10','l_10'],inplace=True)
|
499
584
|
|
500
585
|
#=========== ROC: 变动速率指标
|
501
586
|
"""
|
@@ -507,20 +592,36 @@ def calc_technical(df,start,end, \
|
|
507
592
|
ROCMA = ROC的M日数值之和÷M
|
508
593
|
说明:M一般取值为6日
|
509
594
|
"""
|
510
|
-
df['roc'] = talib.ROC(df['Close'],timeperiod=
|
511
|
-
df['rocma'] = talib.MA(df['roc'],timeperiod=ROC_madays)
|
595
|
+
df['roc'] = talib.ROC(df['Close'],timeperiod=ROC_day)
|
512
596
|
|
597
|
+
if not isinstance(ROC_madays,list):
|
598
|
+
ROC_madays=[ROC_madays]
|
599
|
+
for d in ROC_madays:
|
600
|
+
df['roc_ma'+str(d)] = talib.MA(df['roc'],timeperiod=d)
|
601
|
+
|
602
|
+
df.drop(columns = ['roc'],inplace=True)
|
513
603
|
#=========== DMI: 趋向指标
|
514
604
|
"""
|
515
605
|
|
516
|
-
"""
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
606
|
+
"""
|
607
|
+
if not isinstance(DMI_DIdays,list):
|
608
|
+
DMI_DIdays=[DMI_DIdays]
|
609
|
+
for d in DMI_DIdays:
|
610
|
+
df['pdi'+str(d)] = talib.PLUS_DI(df['High'],df['Low'],df['Close'],timeperiod=d)
|
611
|
+
df['mdi'+str(d)] = talib.MINUS_DI(df['High'],df['Low'],df['Close'],timeperiod=d)
|
612
|
+
|
613
|
+
if not isinstance(DMI_ADXdays,list):
|
614
|
+
DMI_ADXdays=[DMI_ADXdays]
|
615
|
+
for d in DMI_ADXdays:
|
616
|
+
df['adx'+str(d)] = talib.ADX(df['High'],df['Low'],df['Close'],timeperiod=d)
|
617
|
+
df['adxr'+str(d)] = talib.ADXR(df['High'],df['Low'],df['Close'],timeperiod=d)
|
618
|
+
|
619
|
+
#过滤日期
|
620
|
+
_,startpd,endpd=check_period(start,end)
|
621
|
+
df1=df[(df.index >= startpd) & (df.index <= endpd)]
|
521
622
|
|
522
623
|
|
523
|
-
return
|
624
|
+
return df1
|
524
625
|
|
525
626
|
|
526
627
|
#==============================================================================
|
@@ -555,7 +656,7 @@ def security_MACD(ticker,start='default',end='default', \
|
|
555
656
|
MACD_fastperiod=12,MACD_slowperiod=26,MACD_signalperiod=9, \
|
556
657
|
resample_freq='6H',smooth=True,linewidth=1.5, \
|
557
658
|
loc1='lower left',loc2='lower right', \
|
558
|
-
graph=['ALL'],printout=True):
|
659
|
+
graph=['ALL'],printout=True,ticker_type='auto'):
|
559
660
|
"""
|
560
661
|
套壳函数:可用于股票、交易所债券、交易所基金、部分期货期权(限美股)
|
561
662
|
"""
|
@@ -565,7 +666,7 @@ def security_MACD(ticker,start='default',end='default', \
|
|
565
666
|
MACD_signalperiod=MACD_signalperiod, \
|
566
667
|
resample_freq=resample_freq,smooth=smooth,linewidth=linewidth, \
|
567
668
|
loc1=loc1,loc2=loc2, \
|
568
|
-
graph=graph,printout=printout)
|
669
|
+
graph=graph,printout=printout,ticker_type=ticker_type)
|
569
670
|
return df
|
570
671
|
|
571
672
|
|
@@ -574,7 +675,7 @@ def stock_MACD(ticker,start='default',end='default', \
|
|
574
675
|
MACD_fastperiod=12,MACD_slowperiod=26,MACD_signalperiod=9, \
|
575
676
|
resample_freq='H',smooth=True,linewidth=1.5, \
|
576
677
|
loc1='lower left',loc2='lower right', \
|
577
|
-
graph=['ALL'],printout=True):
|
678
|
+
graph=['ALL'],printout=True,ticker_type='auto'):
|
578
679
|
"""
|
579
680
|
功能:计算股票的技术分析指标MACD
|
580
681
|
输入:df,四种股价Open/Close/High/Low,成交量Volume
|
@@ -618,7 +719,8 @@ def stock_MACD(ticker,start='default',end='default', \
|
|
618
719
|
max_days=max(days_list)
|
619
720
|
start1=date_adjust(start,adjust=-max_days * 3)
|
620
721
|
|
621
|
-
df=get_price(ticker,start1,end)
|
722
|
+
#df=get_price(ticker,start1,end)
|
723
|
+
df,found=get_price_1ticker_mixed(ticker=ticker,fromdate=start1,todate=end,ticker_type=ticker_type)
|
622
724
|
if df is None:
|
623
725
|
print(" #Error(stock_MACD): no info found for",ticker,"from",start,"to",end)
|
624
726
|
return None
|
@@ -659,7 +761,7 @@ def stock_MACD(ticker,start='default',end='default', \
|
|
659
761
|
# 限定日期范围
|
660
762
|
df1=df[(df.index >= startpd) & (df.index <= endpd)]
|
661
763
|
|
662
|
-
y_label="
|
764
|
+
y_label="价格"
|
663
765
|
import datetime as dt; today=dt.date.today()
|
664
766
|
source="数据来源:sina/yahoo/stooq/fred,"+str(today)
|
665
767
|
footnote="MA参数:"+str(MA_days)
|
@@ -672,7 +774,7 @@ def stock_MACD(ticker,start='default',end='default', \
|
|
672
774
|
df2=df1[['Close']+MA_cols]
|
673
775
|
df2.rename(columns={'Close':'收盘价'},inplace=True)
|
674
776
|
|
675
|
-
title_txt="
|
777
|
+
title_txt="证券价格走势分析:"+ticker_name(ticker,ticker_type)+",简单移动均线"
|
676
778
|
|
677
779
|
print(" Rendering graphics ...")
|
678
780
|
draw_lines(df2,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
@@ -718,7 +820,7 @@ def stock_MACD(ticker,start='default',end='default', \
|
|
718
820
|
# 限定日期范围
|
719
821
|
df1=df[(df.index >= startpd) & (df.index <= endpd)]
|
720
822
|
|
721
|
-
y_label="
|
823
|
+
y_label="价格"
|
722
824
|
import datetime as dt; today=dt.date.today()
|
723
825
|
source="数据来源:sina/yahoo/stooq/fred,"+str(today)
|
724
826
|
footnote="EMA参数:"+str(EMA_days)
|
@@ -729,7 +831,7 @@ def stock_MACD(ticker,start='default',end='default', \
|
|
729
831
|
|
730
832
|
df3=df1[['Close']+EMA_cols]
|
731
833
|
df3.rename(columns={'Close':'收盘价'},inplace=True)
|
732
|
-
title_txt="
|
834
|
+
title_txt="证券价格走势分析:"+ticker_name(ticker,ticker_type)+",指数加权均线"
|
733
835
|
draw_lines(df3,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
734
836
|
data_label=False,resample_freq=resample_freq,smooth=smooth,linewidth=linewidth*2)
|
735
837
|
|
@@ -794,7 +896,7 @@ def stock_MACD(ticker,start='default',end='default', \
|
|
794
896
|
# MACD绘图
|
795
897
|
df4=df1[['Close','DIF','DEA','MACD']]
|
796
898
|
df4.rename(columns={'Close':'收盘价','DIF':'快线DIF','DEA':'慢线DEA','MACD':'柱线MACD'},inplace=True)
|
797
|
-
title_txt="
|
899
|
+
title_txt="证券价格走势分析:"+ticker_name(ticker,ticker_type)+",MACD"
|
798
900
|
|
799
901
|
import datetime as dt; today=dt.date.today()
|
800
902
|
source="数据来源:sina/yahoo/stooq/fred,"+str(today)
|
@@ -884,10 +986,12 @@ def talib_install_method():
|
|
884
986
|
print(" Note: method 1 is subject to fail")
|
885
987
|
print(" Installation method 2: conda install -c quantopian ta-lib")
|
886
988
|
print(" Note: method 2 may need scientific internet access")
|
887
|
-
print(" Installation method 3: ")
|
989
|
+
print(" Installation method 3: recommended")
|
888
990
|
print(" Step1. Goto website https://www.lfd.uci.edu/~gohlke/pythonlibs/")
|
889
991
|
print(" Step2. On the web page, search for TA_lib")
|
890
992
|
print(" Step3. Select the file suitable for the Python version and OS 32/64")
|
993
|
+
print(" Your Python version:",check_python_version(),"\b, your operating system:",check_os())
|
994
|
+
|
891
995
|
print(" Step4. Download the file")
|
892
996
|
print(" Step5. pip install <downloaded file name>")
|
893
997
|
print(" Note: method 3 is troublesome, but more likely successful")
|
@@ -923,7 +1027,7 @@ def security_RSI(ticker,start='default',end='default', \
|
|
923
1027
|
RSI_days=[6,12,24],RSI_lines=[20,50,80], \
|
924
1028
|
resample_freq='6H',smooth=True,linewidth=1.5, \
|
925
1029
|
loc1='lower left',loc2='lower right', \
|
926
|
-
graph=['ALL'],printout=True):
|
1030
|
+
graph=['ALL'],printout=True,ticker_type='auto'):
|
927
1031
|
"""
|
928
1032
|
套壳函数,除了股票,还可用于交易所债券和交易所基金(如ETF和REITS)
|
929
1033
|
"""
|
@@ -931,7 +1035,7 @@ def security_RSI(ticker,start='default',end='default', \
|
|
931
1035
|
RSI_days=RSI_days,RSI_lines=RSI_lines, \
|
932
1036
|
resample_freq=resample_freq,smooth=smooth,linewidth=linewidth, \
|
933
1037
|
loc1=loc1,loc2=loc2, \
|
934
|
-
graph=graph,printout=printout)
|
1038
|
+
graph=graph,printout=printout,ticker_type=ticker_type)
|
935
1039
|
return df
|
936
1040
|
|
937
1041
|
|
@@ -939,7 +1043,7 @@ def stock_RSI(ticker,start='default',end='default', \
|
|
939
1043
|
RSI_days=[6,12,24],RSI_lines=[20,50,80], \
|
940
1044
|
resample_freq='H',smooth=True,linewidth=1.5, \
|
941
1045
|
loc1='lower left',loc2='lower right', \
|
942
|
-
graph=['ALL'],printout=True):
|
1046
|
+
graph=['ALL'],printout=True,ticker_type='auto'):
|
943
1047
|
"""
|
944
1048
|
功能:计算股票的技术分析指标RSI
|
945
1049
|
输入:df,四种股价Open/Close/High/Low,成交量Volume
|
@@ -983,7 +1087,8 @@ def stock_RSI(ticker,start='default',end='default', \
|
|
983
1087
|
max_days=max(days_list)
|
984
1088
|
start1=date_adjust(start,adjust=-max_days * 3)
|
985
1089
|
|
986
|
-
df=get_price(ticker,start1,end)
|
1090
|
+
#df=get_price(ticker,start1,end)
|
1091
|
+
df,found=get_price_1ticker_mixed(ticker=ticker,fromdate=start1,todate=end,ticker_type=ticker_type)
|
987
1092
|
if df is None:
|
988
1093
|
print(" #Error(stock_RSI): no info found for",ticker,"from",start,"to",end)
|
989
1094
|
return None
|
@@ -1033,7 +1138,7 @@ def stock_RSI(ticker,start='default',end='default', \
|
|
1033
1138
|
# RSI绘图
|
1034
1139
|
df4=df1[['Close']+RSI_cols]
|
1035
1140
|
df4.rename(columns={'Close':'收盘价'},inplace=True)
|
1036
|
-
title_txt="
|
1141
|
+
title_txt="证券价格走势分析:"+ticker_name(ticker,ticker_type)+",RSI"
|
1037
1142
|
|
1038
1143
|
import datetime as dt; today=dt.date.today()
|
1039
1144
|
source="数据来源:sina/yahoo/stooq/fred,"+str(today)
|
@@ -1163,7 +1268,7 @@ def security_KDJ(ticker,start='default',end='default', \
|
|
1163
1268
|
KDJ_days=[9,3,3],matypes=[0,0],KDJ_lines=[20,50,80], \
|
1164
1269
|
resample_freq='6H',smooth=True,linewidth=1.5, \
|
1165
1270
|
loc1='lower left',loc2='lower right', \
|
1166
|
-
graph=['ALL'],printout=True):
|
1271
|
+
graph=['ALL'],printout=True,ticker_type='auto'):
|
1167
1272
|
"""
|
1168
1273
|
套壳函数
|
1169
1274
|
"""
|
@@ -1171,7 +1276,7 @@ def security_KDJ(ticker,start='default',end='default', \
|
|
1171
1276
|
KDJ_days=KDJ_days,matypes=matypes,KDJ_lines=KDJ_lines, \
|
1172
1277
|
resample_freq=resample_freq,smooth=smooth,linewidth=linewidth, \
|
1173
1278
|
loc1=loc1,loc2=loc2, \
|
1174
|
-
graph=graph,printout=printout)
|
1279
|
+
graph=graph,printout=printout,ticker_type=ticker_type)
|
1175
1280
|
return df
|
1176
1281
|
|
1177
1282
|
|
@@ -1179,7 +1284,7 @@ def stock_KDJ(ticker,start='default',end='default', \
|
|
1179
1284
|
KDJ_days=[9,3,3],matypes=[0,0],KDJ_lines=[20,50,80], \
|
1180
1285
|
resample_freq='H',smooth=True,linewidth=1.5, \
|
1181
1286
|
loc1='lower left',loc2='lower right', \
|
1182
|
-
graph=['ALL'],printout=True):
|
1287
|
+
graph=['ALL'],printout=True,ticker_type='auto'):
|
1183
1288
|
"""
|
1184
1289
|
功能:计算股票的技术分析指标KDJ
|
1185
1290
|
输入:df,四种股价Open/Close/High/Low,成交量Volume
|
@@ -1223,7 +1328,8 @@ def stock_KDJ(ticker,start='default',end='default', \
|
|
1223
1328
|
max_days=max(days_list)
|
1224
1329
|
start1=date_adjust(start,adjust=-max_days * 3)
|
1225
1330
|
|
1226
|
-
df=get_price(ticker,start1,end)
|
1331
|
+
#df=get_price(ticker,start1,end)
|
1332
|
+
df,found=get_price_1ticker_mixed(ticker=ticker,fromdate=start1,todate=end,ticker_type=ticker_type)
|
1227
1333
|
if df is None:
|
1228
1334
|
print(" #Error(stock_RSI): no info found for",ticker,"from",start,"to",end)
|
1229
1335
|
return None
|
@@ -1298,7 +1404,7 @@ def stock_KDJ(ticker,start='default',end='default', \
|
|
1298
1404
|
# 绘图
|
1299
1405
|
df4=df1[['Close']+KDJ_cols]
|
1300
1406
|
df4.rename(columns={'Close':'收盘价'},inplace=True)
|
1301
|
-
title_txt="
|
1407
|
+
title_txt="证券价格走势分析:"+ticker_name(ticker,ticker_type)+",KDJ"
|
1302
1408
|
|
1303
1409
|
import datetime as dt; today=dt.date.today()
|
1304
1410
|
source="数据来源:sina/yahoo/stooq/fred,"+str(today)
|
@@ -1779,7 +1885,7 @@ def print_KDJ_result(checkdf,dfs,KDJ_signals,
|
|
1779
1885
|
注意:KDJ_signals需要提前编辑条件字符串输入,例如"K > 80, D > 80, J > 100且至少持续3个交易日"
|
1780
1886
|
"""
|
1781
1887
|
|
1782
|
-
print("\n*** KDJ
|
1888
|
+
print("\n*** KDJ研判价格趋势:回溯验证,"+ticker_name(ticker))
|
1783
1889
|
print(" "+start+'至'+end+',共计'+str(total_obs)+'个样本')
|
1784
1890
|
|
1785
1891
|
print(" KDJ信号:期间内出现"+str(len(dfs))+'次')
|
@@ -1799,15 +1905,15 @@ def print_KDJ_result(checkdf,dfs,KDJ_signals,
|
|
1799
1905
|
print(" 股价变化过滤门限:"+str(threshhold*100)+'%')
|
1800
1906
|
|
1801
1907
|
print(" 回溯检验结果:")
|
1802
|
-
print("
|
1803
|
-
print("
|
1804
|
-
print("
|
1908
|
+
print(" 之后出现价格上涨趋势的比例:",round(checkdf['future up ratio'].values[0]*100,1),'\b%')
|
1909
|
+
print(" 之后出现价格下跌趋势的比例:",round(checkdf['future down ratio'].values[0]*100,1),'\b%')
|
1910
|
+
print(" 之后出现价格振荡情形的比例:",round(checkdf['future vibrate ratio'].values[0]*100,1),'\b%')
|
1805
1911
|
|
1806
1912
|
"""
|
1807
1913
|
if JKcross =='bottom up':
|
1808
|
-
print(" 出现JD
|
1914
|
+
print(" 出现JD金叉后价格上涨的比例:",round(checkdf['t2+ ratio'].values[0]*100,1),'\b%')
|
1809
1915
|
elif JKcross =='top down':
|
1810
|
-
print(" 出现JK
|
1916
|
+
print(" 出现JK死叉后价格下跌的比例:",round(checkdf['t2- ratio'].values[0]*100,1),'\b%')
|
1811
1917
|
else:
|
1812
1918
|
pass
|
1813
1919
|
"""
|
@@ -1829,19 +1935,21 @@ if __name__ =="__main__":
|
|
1829
1935
|
|
1830
1936
|
def security_Bollinger(ticker,start='default',end='default',boll_days=20, \
|
1831
1937
|
graph=True,smooth=True,loc='best', \
|
1832
|
-
date_range=False,date_freq=False,annotate=False
|
1938
|
+
date_range=False,date_freq=False,annotate=False, \
|
1939
|
+
ticker_type='auto'):
|
1833
1940
|
"""
|
1834
1941
|
套壳函数,为了与security_MACD/RSI/KDJ保持相似
|
1835
1942
|
"""
|
1836
1943
|
df=stock_Bollinger(ticker=ticker,start=start,end=end,boll_days=boll_days, \
|
1837
1944
|
graph=graph,smooth=smooth,loc=loc, \
|
1838
|
-
date_range=date_range,date_freq=date_freq,
|
1945
|
+
date_range=date_range,date_freq=date_freq, \
|
1946
|
+
annotate=annotate,ticker_type=ticker_type)
|
1839
1947
|
return df
|
1840
1948
|
|
1841
1949
|
def stock_Bollinger(ticker,start='default',end='default',boll_days=20, \
|
1842
1950
|
graph=True,smooth=True,loc='best', \
|
1843
1951
|
date_range=False,date_freq=False,annotate=False, \
|
1844
|
-
mark_end=True):
|
1952
|
+
mark_end=True,ticker_type='auto'):
|
1845
1953
|
"""
|
1846
1954
|
套壳函数,为了与stock_MACD/RSI/KDJ保持相似
|
1847
1955
|
"""
|
@@ -1869,14 +1977,14 @@ def stock_Bollinger(ticker,start='default',end='default',boll_days=20, \
|
|
1869
1977
|
df=security_bollinger(ticker=ticker,fromdate=start,todate=end,boll_days=boll_days, \
|
1870
1978
|
graph=graph,smooth=smooth,loc=loc, \
|
1871
1979
|
date_range=date_range,date_freq=date_freq,annotate=annotate, \
|
1872
|
-
mark_end=mark_end)
|
1980
|
+
mark_end=mark_end,ticker_type=ticker_type)
|
1873
1981
|
return df
|
1874
1982
|
|
1875
1983
|
|
1876
1984
|
def security_bollinger(ticker,fromdate,todate,boll_days=20, \
|
1877
1985
|
graph=True,smooth=True,loc='best', \
|
1878
1986
|
date_range=False,date_freq=False,annotate=False, \
|
1879
|
-
mark_end=True):
|
1987
|
+
mark_end=True,ticker_type='auto'):
|
1880
1988
|
"""
|
1881
1989
|
功能:单个证券,绘制布林带
|
1882
1990
|
date_range=False:指定开始结束日期绘图
|
@@ -1893,7 +2001,9 @@ def security_bollinger(ticker,fromdate,todate,boll_days=20, \
|
|
1893
2001
|
fromdate1=date_adjust(fromdate,adjust=-365*1)
|
1894
2002
|
|
1895
2003
|
try:
|
1896
|
-
pricedf=get_price(ticker,fromdate1,todate)
|
2004
|
+
#pricedf=get_price(ticker,fromdate1,todate)
|
2005
|
+
pricedf=get_price_1ticker_mixed(ticker=ticker,fromdate=fromdate1, \
|
2006
|
+
todate=todate,ticker_type=ticker_type)
|
1897
2007
|
except:
|
1898
2008
|
print(" #Error(security_bollinger): price info not found for",ticker)
|
1899
2009
|
return None
|
@@ -1917,7 +2027,7 @@ def security_bollinger(ticker,fromdate,todate,boll_days=20, \
|
|
1917
2027
|
|
1918
2028
|
axhline_value=0
|
1919
2029
|
axhline_label=''
|
1920
|
-
title_txt="
|
2030
|
+
title_txt="证券价格趋势分析:"+ticker_name(ticker,ticker_type)+",布林带"
|
1921
2031
|
|
1922
2032
|
"""
|
1923
2033
|
draw_lines(df1,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
@@ -2012,6 +2122,10 @@ def security_bubble(ticker,fromdate,todate,boll_years=7, \
|
|
2012
2122
|
4、估值在中界线与上线之间波动运行时为多头市场,可持多或加码;估值长时间在中界线与上线间运行后,由上往下跌破中间线为卖出信号。
|
2013
2123
|
5、估值在中界线与下线之间向下波动运行时为空头市场,可持空或加抛。
|
2014
2124
|
"""
|
2125
|
+
if not isinstance(ticker,str):
|
2126
|
+
print(" #Warning(security_bubble): not a valid stock code format for",ticker)
|
2127
|
+
return None
|
2128
|
+
|
2015
2129
|
if indicator.lower()=='mv':
|
2016
2130
|
indicatorname='市值(十亿)'
|
2017
2131
|
elif indicator.lower()=='pe':
|
@@ -2089,7 +2203,7 @@ def security_bubble(ticker,fromdate,todate,boll_years=7, \
|
|
2089
2203
|
|
2090
2204
|
axhline_value=0
|
2091
2205
|
axhline_label=''
|
2092
|
-
title_txt="
|
2206
|
+
title_txt="证券估值趋势布林带:"+ticker_name(ticker)
|
2093
2207
|
|
2094
2208
|
"""
|
2095
2209
|
draw_lines(df1,y_label,x_label,axhline_value,axhline_label,title_txt, \
|
@@ -2134,7 +2248,8 @@ def security_technical(ticker,start='default',end='default', \
|
|
2134
2248
|
loc1='best',loc2='best', \
|
2135
2249
|
graph=['ALL'],printout=False, \
|
2136
2250
|
date_range=False,date_freq=False,annotate=False, \
|
2137
|
-
technical=['MACD'],indicator='Close'
|
2251
|
+
technical=['MACD'],indicator='Close', \
|
2252
|
+
ticker_type='auto'):
|
2138
2253
|
|
2139
2254
|
"""
|
2140
2255
|
套壳函数security_MACD/RSI/KDJ/Bollinger
|
@@ -2185,27 +2300,29 @@ def security_technical(ticker,start='default',end='default', \
|
|
2185
2300
|
MACD_fastperiod=MACD_fastperiod,MACD_slowperiod=MACD_slowperiod,MACD_signalperiod=MACD_signalperiod, \
|
2186
2301
|
resample_freq=resample_freq,smooth=smooth,linewidth=linewidth, \
|
2187
2302
|
loc1=loc1,loc2=loc2, \
|
2188
|
-
graph=graph1,printout=printout)
|
2303
|
+
graph=graph1,printout=printout,ticker_type=ticker_type)
|
2189
2304
|
|
2190
2305
|
if 'RSI' in technical1:
|
2191
2306
|
df=security_RSI(ticker=ticker,start=fromdate,end=todate, \
|
2192
2307
|
RSI_days=RSI_days,RSI_lines=RSI_lines, \
|
2193
2308
|
resample_freq=resample_freq,smooth=smooth,linewidth=linewidth, \
|
2194
2309
|
loc1=loc1,loc2=loc2, \
|
2195
|
-
graph=graph1,printout=printout)
|
2310
|
+
graph=graph1,printout=printout,ticker_type=ticker_type)
|
2196
2311
|
|
2197
2312
|
if 'KDJ' in technical1:
|
2198
2313
|
df=security_KDJ(ticker=ticker,start=fromdate,end=todate, \
|
2199
2314
|
KDJ_days=KDJ_days,matypes=matypes,KDJ_lines=KDJ_lines, \
|
2200
2315
|
resample_freq=resample_freq,smooth=smooth,linewidth=linewidth, \
|
2201
2316
|
loc1=loc1,loc2=loc2, \
|
2202
|
-
graph=graph1,printout=printout)
|
2317
|
+
graph=graph1,printout=printout,ticker_type=ticker_type)
|
2203
2318
|
|
2204
2319
|
if 'Bollinger' in technical1 and 'Close' in indicator1:
|
2205
2320
|
df=security_Bollinger(ticker=ticker,start=fromdate,end=todate,boll_days=boll_days, \
|
2206
2321
|
graph=True,smooth=smooth,loc=loc1, \
|
2207
|
-
date_range=date_range,date_freq=date_freq,annotate=annotate
|
2322
|
+
date_range=date_range,date_freq=date_freq,annotate=annotate, \
|
2323
|
+
ticker_type=ticker_type)
|
2208
2324
|
|
2325
|
+
"""
|
2209
2326
|
if 'Bollinger' in technical1 and 'MV' in indicator1:
|
2210
2327
|
df=security_Bubble(ticker=ticker,start=fromdate,end=todate,boll_years=boll_years, \
|
2211
2328
|
indicator='MV', \
|
@@ -2229,8 +2346,294 @@ def security_technical(ticker,start='default',end='default', \
|
|
2229
2346
|
indicator='ROE', \
|
2230
2347
|
graph=True,smooth=smooth,loc=loc1, \
|
2231
2348
|
date_range=date_range,date_freq=date_freq,annotate=annotate)
|
2349
|
+
"""
|
2350
|
+
|
2351
|
+
if 'Bollinger' in technical1:
|
2352
|
+
vallist=['MV','PE','PB','ROE']
|
2353
|
+
if val in vallist and val in indicator1: #只能处理股票估值,无需ticker_type
|
2354
|
+
df=security_Bubble(ticker=ticker,start=fromdate,end=todate,boll_years=boll_years, \
|
2355
|
+
indicator=val, \
|
2356
|
+
graph=True,smooth=smooth,loc=loc1, \
|
2357
|
+
date_range=date_range,date_freq=date_freq,annotate=annotate)
|
2358
|
+
|
2232
2359
|
return df
|
2233
2360
|
|
2361
|
+
#==============================================================================
|
2362
|
+
if __name__ =="__main__":
|
2363
|
+
RSI_days=[6,24]
|
2364
|
+
|
2365
|
+
OBV_days=5
|
2366
|
+
|
2367
|
+
MA_days=[5,20]; MACD_fastperiod=12; MACD_slowperiod=26; MACD_signalperiod=9
|
2368
|
+
|
2369
|
+
KDJ_fastk_period=5; KDJ_slowk_period=3; KDJ_slowk_matype=0; KDJ_slowd_period=3
|
2370
|
+
KDJ_slowd_matype=0
|
2371
|
+
|
2372
|
+
VOL_fastperiod=5; VOL_slowperiod=10
|
2373
|
+
|
2374
|
+
PSY_days=12
|
2375
|
+
|
2376
|
+
ARBR_days=26
|
2377
|
+
|
2378
|
+
CR_day=16; CR_madays=[5,10,20]
|
2379
|
+
|
2380
|
+
EMV_day=14; EMV_madays=9
|
2381
|
+
|
2382
|
+
BULL_days=20; BULL_nbdevup=2; BULL_nbdevdn=2; BULL_matype=0
|
2383
|
+
|
2384
|
+
TRIX_day=12; TRIX_madays=20
|
2385
|
+
|
2386
|
+
DMA_fastperiod=10; DMA_slowperiod=50; DMA_madays=10
|
2387
|
+
|
2388
|
+
BIAS_days=[6,12,24]
|
2389
|
+
|
2390
|
+
CCI_days=14
|
2391
|
+
|
2392
|
+
WR_days=[10,6]
|
2393
|
+
|
2394
|
+
ROC_day=12; ROC_madays=6
|
2395
|
+
|
2396
|
+
DMI_DIdays=14; DMI_ADXdays=6
|
2397
|
+
|
2398
|
+
ticker='AAPL';ticker_type='auto'
|
2399
|
+
|
2400
|
+
start='2024-3-1'; end='2024-4-12'; ahead_days=30*3
|
2401
|
+
|
2402
|
+
technical='EMV'; indicator='Close'; line='default'
|
2403
|
+
|
2404
|
+
df=security_technical_research(ticker,start,end,technical=technical, \
|
2405
|
+
loc1='lower left',loc2='lower right')
|
2406
|
+
|
2407
|
+
tlist=['RSI','OBV','MACD','KDJ','VOL','PSY','ARBR','CR','EMV','Bollinger', \
|
2408
|
+
'TRIX','DMA','BIAS','CCI','W%R','ROC','DMI']
|
2409
|
+
for t in tlist:
|
2410
|
+
df=security_technical2(ticker,start,end,technical=t,loc1='lower left',loc2='lower right')
|
2411
|
+
|
2412
|
+
def security_technical2(ticker,start='default',end='default', \
|
2413
|
+
RSI_days=[6,24], \
|
2414
|
+
OBV_days=5, \
|
2415
|
+
|
2416
|
+
MA_days=[5,20], \
|
2417
|
+
MACD_fastperiod=12,MACD_slowperiod=26,MACD_signalperiod=9, \
|
2418
|
+
|
2419
|
+
KDJ_fastk_period=9,KDJ_slowk_period=5,KDJ_slowk_matype=1, \
|
2420
|
+
KDJ_slowd_period=5,KDJ_slowd_matype=1, \
|
2421
|
+
|
2422
|
+
VOL_fastperiod=5,VOL_slowperiod=10, \
|
2423
|
+
PSY_days=12, \
|
2424
|
+
ARBR_days=26, \
|
2425
|
+
CR_day=16,CR_madays=[5,20], \
|
2426
|
+
EMV_day=14,EMV_madays=9, \
|
2427
|
+
|
2428
|
+
BULL_days=20,BULL_nbdevup=2,BULL_nbdevdn=2,BULL_matype=0, \
|
2429
|
+
|
2430
|
+
DMA_fastperiod=10,DMA_slowperiod=50,DMA_madays=10, \
|
2431
|
+
|
2432
|
+
TRIX_day=12,TRIX_madays=20, \
|
2433
|
+
BIAS_days=[6,24], \
|
2434
|
+
CCI_days=14, \
|
2435
|
+
WR_days=[10,6], \
|
2436
|
+
ROC_day=12,ROC_madays=6, \
|
2437
|
+
DMI_DIdays=14,DMI_ADXdays=6, \
|
2438
|
+
|
2439
|
+
ahead_days=30*4, \
|
2440
|
+
resample_freq='6H',smooth=True,linewidth=1.5, \
|
2441
|
+
date_range=False,date_freq=False,annotate=False, \
|
2442
|
+
|
2443
|
+
technical=['MACD'],indicator='Close', \
|
2444
|
+
graph=['ALL'],printout=False, \
|
2445
|
+
loc1='best',loc2='best', \
|
2446
|
+
ticker_type='auto'):
|
2447
|
+
"""
|
2448
|
+
功能:计算和绘制证券技术分析指标的简易图,仅供进一步探索使用,仅用于单个证券(股债基)
|
2449
|
+
支持的指标:
|
2450
|
+
RSI、OBV、MACD、KDJ、SAR、VOL、PSY、ARBR、CR、EMV、BOLL、TRIX、DMA、BIAS、CCI、W%R、ROC、DMI
|
2451
|
+
"""
|
2452
|
+
#检查证券代码
|
2453
|
+
if not isinstance(ticker,str):
|
2454
|
+
print(" #Warning(security_technical2): not a security code for",ticker)
|
2455
|
+
return None
|
2456
|
+
|
2457
|
+
#检查indicator
|
2458
|
+
if indicator not in ['Open','Close','High','Low']:
|
2459
|
+
print(" #Warning(security_technical2): not a valid price type for",indicator)
|
2460
|
+
return None
|
2461
|
+
|
2462
|
+
#检查日期:如有错误自动更正
|
2463
|
+
fromdate,todate=start_end_preprocess(start=start,end=end)
|
2464
|
+
|
2465
|
+
#检查指标类别
|
2466
|
+
tech_list={'Bollinger':'布林带','MACD':'指数平滑异同平均', \
|
2467
|
+
'RSI':'相对强弱','KDJ':'随机指标','OBV':'能量潮', \
|
2468
|
+
'SAR':'抛物转向','VOL':'成交量','ARBR':'人气与意愿', \
|
2469
|
+
'CR':'能力线','EMV':'简易波动','TRIX':'三重指数平滑', \
|
2470
|
+
'DMA':'均线差','BIAS':'乖离率','CCI':'顺势线', \
|
2471
|
+
'W%R':'威廉比率','ROC':'变动速率','DMI':'趋向线','PSY':'心理线'}
|
2472
|
+
|
2473
|
+
technical1=technical
|
2474
|
+
if isinstance(technical,list):
|
2475
|
+
technical1=technical[0]
|
2476
|
+
technical1=technical1.upper()
|
2477
|
+
if technical1 == 'BOLLINGER': technical1=technical1.title()
|
2478
|
+
|
2479
|
+
if technical1 not in list(tech_list):
|
2480
|
+
print(" #Warning(security_technical2): unsupported technical pattern",technical)
|
2481
|
+
print(" Supported patterns:",list(tech_list))
|
2482
|
+
return None
|
2483
|
+
|
2484
|
+
#抓取抓取价格数据
|
2485
|
+
fromdate1=date_adjust(fromdate,adjust=-ahead_days)
|
2486
|
+
price,found=get_price_1ticker_mixed(ticker=ticker,fromdate=fromdate1, \
|
2487
|
+
todate=todate,ticker_type=ticker_type,fill=False)
|
2488
|
+
|
2489
|
+
if found not in ['Found']:
|
2490
|
+
print(" #Warning(security_technical2): no prices found for",ticker,'as type',ticker_type)
|
2491
|
+
return None
|
2492
|
+
|
2493
|
+
|
2494
|
+
#计算技术指标
|
2495
|
+
df=calc_technical(price,fromdate,todate, \
|
2496
|
+
RSI_days=RSI_days, \
|
2497
|
+
OBV_days=OBV_days, \
|
2498
|
+
MA_days=MA_days, \
|
2499
|
+
MACD_fastperiod=MACD_fastperiod,MACD_slowperiod=MACD_slowperiod,MACD_signalperiod=MACD_signalperiod, \
|
2500
|
+
KDJ_fastk_period=KDJ_fastk_period,KDJ_slowk_period=KDJ_slowk_period,KDJ_slowk_matype=KDJ_slowk_matype, \
|
2501
|
+
KDJ_slowd_period=KDJ_slowd_period,KDJ_slowd_matype=KDJ_slowd_matype, \
|
2502
|
+
VOL_fastperiod=VOL_fastperiod,VOL_slowperiod=VOL_slowperiod, \
|
2503
|
+
PSY_days=PSY_days, \
|
2504
|
+
ARBR_days=ARBR_days, \
|
2505
|
+
CR_day=CR_day,CR_madays=CR_madays, \
|
2506
|
+
EMV_day=EMV_day,EMV_madays=EMV_madays, \
|
2507
|
+
BULL_days=BULL_days,BULL_nbdevup=BULL_nbdevup,BULL_nbdevdn=BULL_nbdevdn,BULL_matype=BULL_matype, \
|
2508
|
+
DMA_fastperiod=DMA_fastperiod,DMA_slowperiod=DMA_slowperiod,DMA_madays=DMA_madays, \
|
2509
|
+
TRIX_day=TRIX_day,TRIX_madays=TRIX_madays, \
|
2510
|
+
BIAS_days=BIAS_days, \
|
2511
|
+
CCI_days=CCI_days, \
|
2512
|
+
WR_days=WR_days, \
|
2513
|
+
ROC_day=ROC_day,ROC_madays=ROC_madays, \
|
2514
|
+
DMI_DIdays=DMI_DIdays,DMI_ADXdays=DMI_ADXdays)
|
2515
|
+
|
2516
|
+
#技术指标的绘图线
|
2517
|
+
tech_line_default={'RSI':['rsi'],
|
2518
|
+
'OBV':['obv'],
|
2519
|
+
'MACD':['DIF','DEA'],
|
2520
|
+
#'KDJ':['kdj_k','kdj_d','kdj_j'],
|
2521
|
+
'KDJ':['kdj'],
|
2522
|
+
'SAR':['sar'],
|
2523
|
+
'VOL':['vol'],
|
2524
|
+
'PSY':['psy'],
|
2525
|
+
'ARBR':['ar','br'],
|
2526
|
+
'CR':['cr'],
|
2527
|
+
'EMV':['emv'],
|
2528
|
+
'Bollinger':['upper','mid','lower'],
|
2529
|
+
'TRIX':['trix'],
|
2530
|
+
'BIAS':['bias'],
|
2531
|
+
'CCI':['cci'],
|
2532
|
+
'W%R':['wr'],
|
2533
|
+
'ROC':['roc'],
|
2534
|
+
'DMI':['pdi','mdi'],
|
2535
|
+
'DMA':['dma'],}
|
2536
|
+
|
2537
|
+
#数据后处理
|
2538
|
+
magnitude_list={'RSI':[1,''],
|
2539
|
+
'OBV':[1/1000000,'百万'],
|
2540
|
+
'MACD':[1,''],
|
2541
|
+
'KDJ':[1,''],
|
2542
|
+
'SAR':[1,''],
|
2543
|
+
'VOL':[1/1000000,'百万'],
|
2544
|
+
'PSY':[1,''],
|
2545
|
+
'ARBR':[1,''],
|
2546
|
+
'CR':[1,''],
|
2547
|
+
'EMV':[1,''],
|
2548
|
+
'Bollinger':[1,''],
|
2549
|
+
'TRIX':[1,''],
|
2550
|
+
'BIAS':[1,''],
|
2551
|
+
'CCI':[1,''],
|
2552
|
+
'W%R':[1,''],
|
2553
|
+
'ROC':[1,''],
|
2554
|
+
'DMI':[1,''],
|
2555
|
+
'DMA':[1,''],}
|
2556
|
+
|
2557
|
+
mag_times=magnitude_list[technical1][0]
|
2558
|
+
mag_label=magnitude_list[technical1][1]
|
2559
|
+
|
2560
|
+
if 'ALL' in graph or 'all' in graph or 'All' in graph:
|
2561
|
+
tech_line_prefix=tech_line_default[technical1]
|
2562
|
+
else:
|
2563
|
+
if not isinstance(graph,list):
|
2564
|
+
tech_line_prefix=[graph]
|
2565
|
+
else:
|
2566
|
+
tech_line_prefix=graph
|
2567
|
+
|
2568
|
+
tech_line_collist=[]
|
2569
|
+
df_collist=list(df)
|
2570
|
+
for p in tech_line_prefix:
|
2571
|
+
for c in df_collist:
|
2572
|
+
if p in c:
|
2573
|
+
tech_line_collist=tech_line_collist+[c]
|
2574
|
+
#去掉重复项
|
2575
|
+
tech_line_collist=list(set(tech_line_collist))
|
2576
|
+
#去掉误选项
|
2577
|
+
if technical1 == 'ARBR':
|
2578
|
+
remove_cols=[]; remove_item='sar'
|
2579
|
+
for c in tech_line_collist:
|
2580
|
+
if remove_item in c:
|
2581
|
+
tech_line_collist.remove(c)
|
2582
|
+
|
2583
|
+
#改变测度
|
2584
|
+
for c in tech_line_collist:
|
2585
|
+
df[c]=df[c] * mag_times
|
2586
|
+
|
2587
|
+
#字段排序
|
2588
|
+
tech_line_collist.sort()
|
2589
|
+
df1=df[tech_line_collist+[indicator]]
|
2590
|
+
|
2591
|
+
#绘图
|
2592
|
+
import matplotlib.pyplot as plt
|
2593
|
+
fig = plt.figure()
|
2594
|
+
ax = fig.add_subplot(111)
|
2595
|
+
|
2596
|
+
line0=False; line30=False; line50=False; line80=False
|
2597
|
+
for l in tech_line_collist:
|
2598
|
+
lmax=df1[l].max(); lmin=df1[l].min()
|
2599
|
+
if lmax * lmin < 0: line0=True
|
2600
|
+
if 100 >= lmax >= 30 and 0 <= lmin <= 30: line30=True
|
2601
|
+
if 100 >= lmax >= 50 and 0 <= lmin <= 50: line50=True
|
2602
|
+
if 100 >= lmax >= 80 and 0 <= lmin <= 80: line80=True
|
2603
|
+
|
2604
|
+
ax.plot(df1.index,df1[l],label=l)
|
2605
|
+
|
2606
|
+
#绘制0线
|
2607
|
+
if line0:
|
2608
|
+
plt.axhline(y=0,ls=":",c="black",linewidth=2)
|
2609
|
+
#绘制30线
|
2610
|
+
if line30:
|
2611
|
+
plt.axhline(y=30,ls=":",c="green",linewidth=2)
|
2612
|
+
#绘制50线
|
2613
|
+
if line50:
|
2614
|
+
plt.axhline(y=50,ls=":",c="black",linewidth=2)
|
2615
|
+
#绘制50线
|
2616
|
+
if line80:
|
2617
|
+
plt.axhline(y=80,ls=":",c="black",linewidth=2)
|
2618
|
+
|
2619
|
+
ylabeltxt1=technical1+'指标'
|
2620
|
+
if mag_label != '':
|
2621
|
+
ylabeltxt1=ylabeltxt1+'('+mag_label+')'
|
2622
|
+
ax.set_ylabel(ylabeltxt1,fontsize=ylabel_txt_size)
|
2623
|
+
ax.legend(loc=loc1,fontsize=legend_txt_size)
|
2624
|
+
|
2625
|
+
ax2 = ax.twinx()
|
2626
|
+
ylabeltxt2='收盘价'
|
2627
|
+
ax2.set_ylabel(ylabeltxt2,fontsize=ylabel_txt_size)
|
2628
|
+
ax2.plot(df1.index,df1[indicator],label=ylabeltxt2,linestyle='dotted',color='gray')
|
2629
|
+
ax2.legend(loc=loc2,fontsize=legend_txt_size)
|
2630
|
+
|
2631
|
+
titletxt=ticker_name(ticker)+': '+tech_list[technical1]+technical1
|
2632
|
+
plt.title(titletxt,fontweight='bold',fontsize=title_txt_size)
|
2633
|
+
plt.gcf().autofmt_xdate()
|
2634
|
+
plt.show(); plt.close()
|
2635
|
+
|
2636
|
+
return df
|
2234
2637
|
|
2235
2638
|
|
2236
2639
|
#==============================================================================
|