siat 3.2.5__py3-none-any.whl → 3.2.10__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 +25 -0
- siat/security_price2.py +4 -4
- siat/security_prices.py +22 -3
- siat/stock_technical.py +569 -372
- {siat-3.2.5.dist-info → siat-3.2.10.dist-info}/METADATA +1 -1
- {siat-3.2.5.dist-info → siat-3.2.10.dist-info}/RECORD +8 -8
- {siat-3.2.5.dist-info → siat-3.2.10.dist-info}/WHEEL +0 -0
- {siat-3.2.5.dist-info → siat-3.2.10.dist-info}/top_level.txt +0 -0
siat/stock_technical.py
CHANGED
@@ -90,7 +90,7 @@ if __name__ =="__main__":
|
|
90
90
|
|
91
91
|
BIAS_days=[6,12,24]
|
92
92
|
|
93
|
-
|
93
|
+
CCI_day=14; CCI_madays=[5,20]
|
94
94
|
|
95
95
|
WR_days=[10,6]
|
96
96
|
|
@@ -161,32 +161,51 @@ if __name__ =="__main__":
|
|
161
161
|
|
162
162
|
|
163
163
|
|
164
|
-
def calc_technical(df,start,end, \
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
164
|
+
def calc_technical(df,start,end,technical='MACD', \
|
165
|
+
|
166
|
+
RSI_days=[14], \
|
167
|
+
OBV_days=[5], \
|
168
|
+
|
169
|
+
MA_days=[5,20],EMA_days=[5,20], \
|
170
|
+
MACD_fastperiod=12,MACD_slowperiod=26,MACD_signalperiod=9, \
|
171
|
+
|
172
|
+
KDJ_fastk_period=9,KDJ_slowk_period=5,KDJ_slowk_matype=1,KDJ_slowd_period=5,KDJ_slowd_matype=1, \
|
173
|
+
|
174
|
+
VOL_fastperiod=5,VOL_slowperiod=10, \
|
175
|
+
PSY_days=[12], \
|
176
|
+
ARBR_days=[26], \
|
177
|
+
CR_day=16,CR_madays=[5,10,20], \
|
178
|
+
EMV_day=14,EMV_madays=[9], \
|
179
|
+
|
180
|
+
BULL_day=20,BULL_nbdevup=2,BULL_nbdevdn=2,BULL_matype=0, \
|
181
|
+
|
182
|
+
DMA_fastperiod=10,DMA_slowperiod=50,DMA_madays=[10], \
|
183
|
+
|
184
|
+
TRIX_day=12,TRIX_madays=[20], \
|
185
|
+
BIAS_days=[6,12,24], \
|
186
|
+
CCI_day=14,CCI_madays=[5,20], \
|
187
|
+
WR_days=[10,6], \
|
188
|
+
ROC_day=12,ROC_madays=[6], \
|
189
|
+
DMI_DIdays=[14],DMI_ADXdays=[6], \
|
190
|
+
|
191
|
+
MFI_day=14,MFI_madays=[14], \
|
192
|
+
MOM_day=10,MOM_madays=[10], \
|
193
|
+
|
194
|
+
#需要显示SAR
|
195
|
+
SAR_day=4,SAR_madays=[5,20], \
|
196
|
+
|
197
|
+
#需要显示BETA
|
198
|
+
BETA_day=5,BETA_madays=[5,20], \
|
199
|
+
|
200
|
+
#需要显示TSF
|
201
|
+
TSF_day=14,TSF_madays=[5,20], \
|
202
|
+
|
203
|
+
#需要显示AD
|
204
|
+
AD_day=26,AD_madays=[5,20], \
|
205
|
+
|
206
|
+
#不建议使用复权价,因为最高最低价和开盘价没有复权价!
|
207
|
+
indicator='Close', \
|
208
|
+
more_details=False):
|
190
209
|
"""
|
191
210
|
功能:计算股票的技术分析指标
|
192
211
|
输入:df,四种股价Open/Close/High/Low,成交量Volume
|
@@ -211,6 +230,9 @@ def calc_technical(df,start,end, \
|
|
211
230
|
talib_install_method()
|
212
231
|
return None
|
213
232
|
|
233
|
+
#用于对比,检查是否有计算结果的指标加入
|
234
|
+
dfcols_original=list(df)
|
235
|
+
|
214
236
|
#=========== RSI,相对强弱指标Relative Strength Index
|
215
237
|
"""
|
216
238
|
计算公式:RSI有两种计算方法:
|
@@ -228,11 +250,13 @@ def calc_technical(df,start,end, \
|
|
228
250
|
30-50 弱 观望,谨慎买入
|
229
251
|
0-30 极弱 买入
|
230
252
|
"""
|
231
|
-
if
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
253
|
+
if technical=='RSI':
|
254
|
+
|
255
|
+
if not isinstance(RSI_days,list):
|
256
|
+
RSI_days=[RSI_days]
|
257
|
+
for d in RSI_days:
|
258
|
+
df['rsi'+str(d)] = talib.RSI(df[indicator], timeperiod=d)
|
259
|
+
#注意:rsi1没有意义
|
236
260
|
|
237
261
|
#=========== OBV:能量潮
|
238
262
|
"""
|
@@ -263,15 +287,17 @@ def calc_technical(df,start,end, \
|
|
263
287
|
因此,对于那些达到涨跌停板的股票,OBV指标也无法正常发挥作用。
|
264
288
|
|
265
289
|
"""
|
266
|
-
|
267
|
-
|
268
|
-
if not isinstance(OBV_days,list):
|
269
|
-
OBV_days=[OBV_days]
|
270
|
-
for d in OBV_days:
|
271
|
-
df['obv_ma'+str(d)] = talib.MA(df['obv'],timeperiod=d)
|
290
|
+
if technical=='OBV':
|
272
291
|
|
273
|
-
|
274
|
-
|
292
|
+
df['obv'] = talib.OBV(df[indicator],df['Volume'])
|
293
|
+
|
294
|
+
if not isinstance(OBV_days,list):
|
295
|
+
OBV_days=[OBV_days]
|
296
|
+
for d in OBV_days:
|
297
|
+
df['obv_ma'+str(d)] = talib.MA(df['obv'],timeperiod=d)
|
298
|
+
|
299
|
+
if not more_details:
|
300
|
+
df.drop(columns = ['obv'],inplace=True)
|
275
301
|
|
276
302
|
#=========== MA: 简单、加权移动平均
|
277
303
|
"""
|
@@ -282,13 +308,22 @@ def calc_technical(df,start,end, \
|
|
282
308
|
一般来说,现行价格在平均价之上,意味着市场买力(需求)较大,行情看好;
|
283
309
|
反之,行情价在平均价之下,则意味着供过于求,卖压显然较重,行情看淡。
|
284
310
|
"""
|
285
|
-
if
|
286
|
-
MA_days=[MA_days]
|
311
|
+
if technical=='MA':
|
287
312
|
|
288
|
-
|
289
|
-
|
290
|
-
|
313
|
+
if not isinstance(MA_days,list):
|
314
|
+
MA_days=[MA_days]
|
315
|
+
|
316
|
+
for d in MA_days:
|
317
|
+
df['ma'+str(d)] = talib.MA(df[indicator],timeperiod=d)
|
318
|
+
|
319
|
+
if technical=='EMA':
|
291
320
|
|
321
|
+
if not isinstance(EMA_days,list):
|
322
|
+
EMA_days=[EMA_days]
|
323
|
+
|
324
|
+
for d in EMA_days:
|
325
|
+
df['ema'+str(d)] = talib.EMA(df[indicator],timeperiod=d)
|
326
|
+
|
292
327
|
#=========== MACD:指数平滑异同平均线
|
293
328
|
"""
|
294
329
|
计算方法:快速时间窗口设为12日,慢速时间窗口设为26日,DIF参数设为9日
|
@@ -317,10 +352,12 @@ def calc_technical(df,start,end, \
|
|
317
352
|
3. MACD绿转红:MACD值由负变正,市场由空头转为多头。
|
318
353
|
4. MACD红转绿:MACD值由正变负,市场由多头转为空头。
|
319
354
|
"""
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
355
|
+
if technical=='MACD':
|
356
|
+
|
357
|
+
df['DIF'],df['DEA'],df['MACD']=talib.MACD(df[indicator], \
|
358
|
+
fastperiod=MACD_fastperiod, \
|
359
|
+
slowperiod=MACD_slowperiod, \
|
360
|
+
signalperiod=MACD_signalperiod)
|
324
361
|
|
325
362
|
#=========== KDJ: 随机指标
|
326
363
|
"""
|
@@ -339,13 +376,15 @@ def calc_technical(df,start,end, \
|
|
339
376
|
多头区域,空头区域
|
340
377
|
金叉,死叉
|
341
378
|
"""
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
379
|
+
if technical=='KDJ':
|
380
|
+
|
381
|
+
df['kdj_k'],df['kdj_d'] = talib.STOCH(df['High'],df['Low'],df[indicator], \
|
382
|
+
fastk_period=KDJ_fastk_period,
|
383
|
+
slowk_period=KDJ_slowk_period,
|
384
|
+
slowk_matype=KDJ_slowk_matype,
|
385
|
+
slowd_period=KDJ_slowd_period,
|
386
|
+
slowd_matype=KDJ_slowd_matype)
|
387
|
+
df['kdj_j'] = 3*df['kdj_k'] - 2*df['kdj_d']
|
349
388
|
|
350
389
|
#=========== SAR: 抛物转向
|
351
390
|
"""
|
@@ -368,14 +407,29 @@ def calc_technical(df,start,end, \
|
|
368
407
|
7)SAR指标基准周期的参数为2,如2日、2周、2月等,其计算周期的参数变动范围为2~8
|
369
408
|
8)SAR指标在股价分析系统的主图上显示为“O”形点状图。
|
370
409
|
"""
|
371
|
-
|
372
|
-
|
410
|
+
if technical=='SAR':
|
411
|
+
|
412
|
+
df['sar'] = talib.SAR(df['High'],df['Low'])
|
413
|
+
|
414
|
+
if not isinstance(SAR_madays,list):
|
415
|
+
SAR_madays=[SAR_madays]
|
416
|
+
for d in SAR_madays:
|
417
|
+
df['sar_ma'+str(d)] = df['sar'].rolling(window=d).mean()
|
418
|
+
|
419
|
+
#需要显示SAR?
|
420
|
+
"""
|
421
|
+
if not more_details:
|
422
|
+
#不保留指标本身
|
423
|
+
df.drop(columns = ['sar'],inplace=True)
|
424
|
+
"""
|
373
425
|
#=========== VOL: 成交量
|
374
426
|
"""
|
375
427
|
柱状图是成交量,两条曲线是成交量的移动平均
|
376
428
|
"""
|
377
|
-
|
378
|
-
|
429
|
+
if technical=='VOL':
|
430
|
+
|
431
|
+
df['vol'+str(VOL_fastperiod)] = talib.MA(df['Volume'],timeperiod=VOL_fastperiod)
|
432
|
+
df['vol'+str(VOL_slowperiod)] = talib.MA(df['Volume'],timeperiod=VOL_slowperiod)
|
379
433
|
|
380
434
|
#=========== PSY: 心理线
|
381
435
|
"""
|
@@ -383,17 +437,19 @@ def calc_technical(df,start,end, \
|
|
383
437
|
PSY(N) = A/N × 100
|
384
438
|
说明:N为天数,A为在这N天之中股价上涨的天数
|
385
439
|
"""
|
386
|
-
|
387
|
-
df['ext_1'] = 0
|
388
|
-
df.loc[df['ext_0']>0,'ext_1'] = 1
|
389
|
-
|
390
|
-
if not isinstance(PSY_days,list):
|
391
|
-
PSY_days=[PSY_days]
|
392
|
-
for d in PSY_days:
|
393
|
-
df['ext_2'] = df['ext_1'].rolling(window=d).sum()
|
394
|
-
df['psy'+str(d)] = (df['ext_2']/float(d))*100
|
440
|
+
if technical=='PSY':
|
395
441
|
|
396
|
-
|
442
|
+
df['ext_0'] = df[indicator]-df[indicator].shift(1)
|
443
|
+
df['ext_1'] = 0
|
444
|
+
df.loc[df['ext_0']>0,'ext_1'] = 1
|
445
|
+
|
446
|
+
if not isinstance(PSY_days,list):
|
447
|
+
PSY_days=[PSY_days]
|
448
|
+
for d in PSY_days:
|
449
|
+
df['ext_2'] = df['ext_1'].rolling(window=d).sum()
|
450
|
+
df['psy'+str(d)] = (df['ext_2']/float(d))*100
|
451
|
+
|
452
|
+
df.drop(columns = ['ext_0','ext_1','ext_2'],inplace=True)
|
397
453
|
|
398
454
|
#=========== ARBR: 人气和意愿指标, AR为人气指标,BR为买卖意愿指标
|
399
455
|
"""
|
@@ -403,25 +459,27 @@ def calc_technical(df,start,end, \
|
|
403
459
|
BR(N) = N日内(H-CY)之和 ÷ N日内(CY-L)之和 × 100
|
404
460
|
说明:H表示当天最高价;L表示当天最低价;CY表示前一交易日的收盘价,N表示设定的时间参数,一般原始参数缺省值为26日
|
405
461
|
"""
|
406
|
-
|
407
|
-
df['o_l'] = df['Open'] - df['Low']
|
408
|
-
|
409
|
-
if not isinstance(ARBR_days,list):
|
410
|
-
ARBR_days=[ARBR_days]
|
411
|
-
for d in ARBR_days:
|
412
|
-
df['h_o_sum'] = df['h_o'].rolling(window=d).sum()
|
413
|
-
df['o_l_sum'] = df['o_l'].rolling(window=d).sum()
|
414
|
-
df['ar'+str(d)] = (df['h_o_sum']/df['o_l_sum'])*100
|
462
|
+
if technical=='ARBR':
|
415
463
|
|
464
|
+
df['h_o'] = df['High'] - df['Open']
|
465
|
+
df['o_l'] = df['Open'] - df['Low']
|
466
|
+
|
467
|
+
if not isinstance(ARBR_days,list):
|
468
|
+
ARBR_days=[ARBR_days]
|
469
|
+
for d in ARBR_days:
|
470
|
+
df['h_o_sum'] = df['h_o'].rolling(window=d).sum()
|
471
|
+
df['o_l_sum'] = df['o_l'].rolling(window=d).sum()
|
472
|
+
df['ar'+str(d)] = (df['h_o_sum']/df['o_l_sum'])*100
|
473
|
+
|
474
|
+
|
475
|
+
df['h_c'] = df['High'] - df[indicator]
|
476
|
+
df['c_l'] = df[indicator] - df['Low']
|
477
|
+
for d in ARBR_days:
|
478
|
+
df['h_c_sum'] = df['h_c'].rolling(window=d).sum()
|
479
|
+
df['c_l_sum'] = df['c_l'].rolling(window=d).sum()
|
480
|
+
df['br'+str(d)] = (df['h_c_sum']/df['c_l_sum'])*100
|
416
481
|
|
417
|
-
|
418
|
-
df['c_l'] = df['Close'] - df['Low']
|
419
|
-
for d in ARBR_days:
|
420
|
-
df['h_c_sum'] = df['h_c'].rolling(window=d).sum()
|
421
|
-
df['c_l_sum'] = df['c_l'].rolling(window=d).sum()
|
422
|
-
df['br'+str(d)] = (df['h_c_sum']/df['c_l_sum'])*100
|
423
|
-
|
424
|
-
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)
|
482
|
+
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)
|
425
483
|
|
426
484
|
#=========== CR: 带状能力线或中间意愿指标
|
427
485
|
"""
|
@@ -436,22 +494,22 @@ def calc_technical(df,start,end, \
|
|
436
494
|
说明:N为设定的时间周期参数,一般原始参数日设定为26日
|
437
495
|
3)计算CR值在不同时间周期内的移动平均值:这三条移动平均曲线分别为MA1 MA2 MA3,时间周期分别为5日 10日 20日
|
438
496
|
"""
|
439
|
-
|
440
|
-
df['h_m'] = df['High']-df['m_price'].shift(1)
|
441
|
-
df['m_l'] = df['m_price'].shift(1)-df['Low']
|
497
|
+
if technical=='CR':
|
442
498
|
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
df['
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
df.drop(columns = ['m_price','h_m','m_l','h_m_sum','m_l_sum'
|
499
|
+
df['m_price'] = (df['High'] + df['Low'])/2
|
500
|
+
df['h_m'] = df['High']-df['m_price'].shift(1)
|
501
|
+
df['m_l'] = df['m_price'].shift(1)-df['Low']
|
502
|
+
|
503
|
+
df['h_m_sum'] = df['h_m'].rolling(window=CR_day).sum()
|
504
|
+
df['m_l_sum'] = df['m_l'].rolling(window=CR_day).sum()
|
505
|
+
df['cr'] = (df['h_m_sum']/df['m_l_sum'])*100
|
506
|
+
|
507
|
+
for d in CR_madays:
|
508
|
+
df['cr_ma'+str(d)] = talib.MA(df['cr'],timeperiod=d)
|
509
|
+
|
510
|
+
df.drop(columns = ['m_price','h_m','m_l','h_m_sum','m_l_sum'],inplace=True)
|
511
|
+
if not more_details:
|
512
|
+
df.drop(columns = ['cr'],inplace=True)
|
455
513
|
|
456
514
|
#=========== EMV: 简易波动指标
|
457
515
|
"""
|
@@ -467,20 +525,22 @@ def calc_technical(df,start,end, \
|
|
467
525
|
4)求出EMV的移动平均值EMVA
|
468
526
|
EMVA = EMV的M日移动平均值,M一般设置9日
|
469
527
|
"""
|
470
|
-
|
471
|
-
df['b'] = (df['High'].shift(1)+df['Low'].shift(1))/2
|
472
|
-
df['c'] = df['High'] - df['Low']
|
473
|
-
df['Amount']=df['Close']*df['Volume']
|
474
|
-
df['em'] = (df['a']-df['b'])*df['c']/df['Amount']
|
528
|
+
if technical=='EMV':
|
475
529
|
|
476
|
-
|
530
|
+
df['a'] = (df['High']+df['Low'])/2
|
531
|
+
df['b'] = (df['High'].shift(1)+df['Low'].shift(1))/2
|
532
|
+
df['c'] = df['High'] - df['Low']
|
533
|
+
df['Amount']=df[indicator]*df['Volume']
|
534
|
+
df['em'] = (df['a']-df['b'])*df['c']/df['Amount']
|
535
|
+
|
536
|
+
df['emv'] = df['em'].rolling(window=EMV_day).sum()
|
537
|
+
|
538
|
+
if not isinstance(EMV_madays,list):
|
539
|
+
EMV_madays=[EMV_madays]
|
540
|
+
for d in EMV_madays:
|
541
|
+
df['emv_ma'+str(d)] = talib.MA(df['emv'],timeperiod=d)
|
477
542
|
|
478
|
-
|
479
|
-
EMV_madays=[EMV_madays]
|
480
|
-
for d in EMV_madays:
|
481
|
-
df['emv_ma'+str(d)] = talib.MA(df['emv'],timeperiod=d)
|
482
|
-
|
483
|
-
df.drop(columns = ['a','b','c','em'],inplace=True)
|
543
|
+
df.drop(columns = ['a','b','c','em'],inplace=True)
|
484
544
|
|
485
545
|
#=========== BOLL: 布林线指标
|
486
546
|
"""
|
@@ -508,24 +568,28 @@ def calc_technical(df,start,end, \
|
|
508
568
|
这条带状区的宽窄,随着股价波动幅度的大小而变化,股价涨跌幅度加大时,带状区变宽,
|
509
569
|
涨跌幅度狭小盘整时,带状区则变窄。
|
510
570
|
"""
|
511
|
-
|
512
|
-
|
513
|
-
|
571
|
+
if technical=='Bollinger':
|
572
|
+
|
573
|
+
df['upper'],df['mid'],df['lower'] = talib.BBANDS(df[indicator], \
|
574
|
+
timeperiod=BULL_day, \
|
575
|
+
nbdevup=BULL_nbdevup,nbdevdn=BULL_nbdevdn,matype=BULL_matype)
|
514
576
|
|
515
577
|
#=========== TRIX:三重指数平滑移动平均指标
|
516
578
|
"""
|
517
579
|
|
518
580
|
"""
|
519
|
-
|
581
|
+
if technical=='TRIX':
|
520
582
|
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
583
|
+
df['trix'] = talib.TRIX(df[indicator],timeperiod=TRIX_day)
|
584
|
+
|
585
|
+
if not isinstance(TRIX_madays,list):
|
586
|
+
TRIX_madays=[TRIX_madays]
|
587
|
+
for d in TRIX_madays:
|
588
|
+
df['trix_ma'+str(d)] = talib.MA(df['trix'],timeperiod=d)
|
589
|
+
|
590
|
+
if not more_details:
|
591
|
+
#不保留TRIX
|
592
|
+
df.drop(columns = ['trix'],inplace=True)
|
529
593
|
|
530
594
|
#=========== DMA: 平均线差
|
531
595
|
"""
|
@@ -539,17 +603,19 @@ def calc_technical(df,start,end, \
|
|
539
603
|
2)求DDD的10日移动平均数值
|
540
604
|
DMA(10) = DDD(10)÷10
|
541
605
|
"""
|
542
|
-
|
543
|
-
df['ma_longperiod'] = talib.MA(df[indicator],timeperiod=DMA_slowperiod)
|
544
|
-
df['ddd'] = df['ma_shortperiod'] - df['ma_longperiod']
|
606
|
+
if technical=='DMA':
|
545
607
|
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
608
|
+
df['ma_shortperiod'] = talib.MA(df[indicator],timeperiod=DMA_fastperiod)
|
609
|
+
df['ma_longperiod'] = talib.MA(df[indicator],timeperiod=DMA_slowperiod)
|
610
|
+
df['ddd'] = df['ma_shortperiod'] - df['ma_longperiod']
|
611
|
+
|
612
|
+
if not isinstance(DMA_madays,list):
|
613
|
+
DMA_madays=[DMA_madays]
|
614
|
+
for d in DMA_madays:
|
615
|
+
df['dma_ma'+str(d)] = talib.MA(df['ddd'],timeperiod=d)
|
616
|
+
#注意:dma1似乎没有意义
|
617
|
+
|
618
|
+
df.drop(columns = ['ma_shortperiod','ma_longperiod','ddd'],inplace=True)
|
553
619
|
|
554
620
|
#=========== BIAS: 乖离率
|
555
621
|
"""
|
@@ -560,25 +626,35 @@ def calc_technical(df,start,end, \
|
|
560
626
|
12日BIAS>+6%是卖出时机;<-5.5%,为买入时机。
|
561
627
|
24日BIAS>+9%是卖出时机;<-8%,为买入时机。
|
562
628
|
"""
|
563
|
-
if
|
564
|
-
BIAS_days=[BIAS_days]
|
565
|
-
for d in BIAS_days:
|
566
|
-
df['ma'] = talib.MA(df[indicator],timeperiod=d)
|
567
|
-
df['bias'+str(d)] = ((df[indicator]-df['ma'])/df['ma'])*100
|
629
|
+
if technical=='BIAS':
|
568
630
|
|
569
|
-
|
631
|
+
if not isinstance(BIAS_days,list):
|
632
|
+
BIAS_days=[BIAS_days]
|
633
|
+
for d in BIAS_days:
|
634
|
+
df['ma'] = talib.MA(df[indicator],timeperiod=d)
|
635
|
+
df['bias'+str(d)] = ((df[indicator]-df['ma'])/df['ma'])*100
|
636
|
+
|
637
|
+
df.drop(columns = ['ma'],inplace=True)
|
570
638
|
|
571
639
|
#=========== CCI: 顺势指标
|
572
640
|
"""
|
573
641
|
计算过程:
|
574
642
|
CCI(N日) = (TP-MA)÷MD÷0.015
|
575
643
|
说明:TP = (最高价+最低价+收盘价)÷3;MA=最近N日收盘价的累计之和÷N;MD=最近N日(MA-收盘价)的累计之和÷N;0.015为计算系数;N为计算周期,默认为14天
|
576
|
-
"""
|
577
|
-
if
|
578
|
-
|
579
|
-
|
580
|
-
|
644
|
+
"""
|
645
|
+
if technical=='CCI':
|
646
|
+
|
647
|
+
df['cci'] = talib.CCI(df['High'],df['Low'],df[indicator],timeperiod=CCI_day)
|
648
|
+
|
649
|
+
if not isinstance(CCI_madays,list):
|
650
|
+
CCI_madays=[CCI_madays]
|
651
|
+
for d in CCI_madays:
|
652
|
+
df['cci_ma'+str(d)] = df['cci'].rolling(window=d).mean()
|
581
653
|
|
654
|
+
#需要显示CCI?
|
655
|
+
if not more_details:
|
656
|
+
#不保留指标本身
|
657
|
+
df.drop(columns = ['cci'],inplace=True)
|
582
658
|
#=========== W%R: 威廉指标
|
583
659
|
"""
|
584
660
|
N日W%R = [(Hn-Ct)/(Hn-Ln)]*100
|
@@ -593,14 +669,16 @@ def calc_technical(df,start,end, \
|
|
593
669
|
2.高于80,超卖,即将见底,应伺机买进
|
594
670
|
3.与RSI、MTM指标配合使用,效果更好
|
595
671
|
"""
|
596
|
-
if
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
672
|
+
if technical=='W%R':
|
673
|
+
|
674
|
+
if not isinstance(WR_days,list):
|
675
|
+
WR_days=[WR_days]
|
676
|
+
for d in WR_days:
|
677
|
+
df['h_10'] = df['High'].rolling(window=d).max()
|
678
|
+
df['l_10'] = df['Low'].rolling(window=d).min()
|
679
|
+
df['wr'+str(d)] = ((df['h_10']-df[indicator])/(df['h_10']-df['l_10']))*100
|
680
|
+
|
681
|
+
df.drop(columns = ['h_10','l_10'],inplace=True)
|
604
682
|
|
605
683
|
#=========== ROC: 变动速率指标
|
606
684
|
"""
|
@@ -612,39 +690,136 @@ def calc_technical(df,start,end, \
|
|
612
690
|
ROCMA = ROC的M日数值之和÷M
|
613
691
|
说明:M一般取值为6日
|
614
692
|
"""
|
615
|
-
|
616
|
-
|
617
|
-
if not isinstance(ROC_madays,list):
|
618
|
-
ROC_madays=[ROC_madays]
|
619
|
-
for d in ROC_madays:
|
620
|
-
df['roc_ma'+str(d)] = talib.MA(df['roc'],timeperiod=d)
|
693
|
+
if technical=='ROC':
|
621
694
|
|
622
|
-
|
623
|
-
|
624
|
-
|
695
|
+
df['roc'] = talib.ROC(df[indicator],timeperiod=ROC_day)
|
696
|
+
|
697
|
+
if not isinstance(ROC_madays,list):
|
698
|
+
ROC_madays=[ROC_madays]
|
699
|
+
for d in ROC_madays:
|
700
|
+
df['roc_ma'+str(d)] = talib.MA(df['roc'],timeperiod=d)
|
701
|
+
|
702
|
+
if not more_details:
|
703
|
+
#不保留roc
|
704
|
+
df.drop(columns = ['roc'],inplace=True)
|
625
705
|
|
626
706
|
#=========== DMI: 趋向指标
|
627
707
|
"""
|
628
|
-
|
708
|
+
pdi: 正向DI
|
709
|
+
mdi: 负向DI
|
629
710
|
"""
|
630
|
-
if
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
711
|
+
if technical=='DMI':
|
712
|
+
|
713
|
+
if not isinstance(DMI_DIdays,list):
|
714
|
+
DMI_DIdays=[DMI_DIdays]
|
715
|
+
for d in DMI_DIdays:
|
716
|
+
df['pdi'+str(d)] = talib.PLUS_DI(df['High'],df['Low'],df[indicator],timeperiod=d)
|
717
|
+
df['mdi'+str(d)] = talib.MINUS_DI(df['High'],df['Low'],df[indicator],timeperiod=d)
|
718
|
+
|
719
|
+
if not isinstance(DMI_ADXdays,list):
|
720
|
+
DMI_ADXdays=[DMI_ADXdays]
|
721
|
+
for d in DMI_ADXdays:
|
722
|
+
df['adx'+str(d)] = talib.ADX(df['High'],df['Low'],df[indicator],timeperiod=d)
|
723
|
+
df['adxr'+str(d)] = talib.ADXR(df['High'],df['Low'],df[indicator],timeperiod=d)
|
724
|
+
|
725
|
+
#=========== MFI:资金流动指标
|
726
|
+
"""
|
727
|
+
|
728
|
+
"""
|
729
|
+
if technical=='MFI':
|
730
|
+
|
731
|
+
df['mfi'] = talib.MFI(df['High'],df['Low'],df[indicator],df['Volume'],timeperiod=MFI_day)
|
732
|
+
if not isinstance(MFI_madays,list):
|
733
|
+
MFI_madays=[MFI_madays]
|
734
|
+
for d in MFI_madays:
|
735
|
+
df['mfi_ma'+str(d)] = df['mfi'].rolling(window=d).mean()
|
736
|
+
|
737
|
+
if not more_details:
|
738
|
+
#不保留指标本身
|
739
|
+
df.drop(columns = ['mfi'],inplace=True)
|
740
|
+
|
741
|
+
#=========== MOM:动量指标
|
742
|
+
"""
|
743
|
+
|
744
|
+
"""
|
745
|
+
if technical=='MOM':
|
746
|
+
|
747
|
+
df['mom'] = talib.MOM(df[indicator],timeperiod=MOM_day)
|
748
|
+
if not isinstance(MOM_madays,list):
|
749
|
+
MOM_madays=[MOM_madays]
|
750
|
+
for d in MOM_madays:
|
751
|
+
df['mom_ma'+str(d)] = df['mom'].rolling(window=d).mean()
|
752
|
+
|
753
|
+
if not more_details:
|
754
|
+
#不保留指标本身
|
755
|
+
df.drop(columns = ['mom'],inplace=True)
|
756
|
+
|
757
|
+
#=========== BETA:贝塔系数
|
758
|
+
"""
|
759
|
+
动态贝塔系数?
|
760
|
+
"""
|
761
|
+
if technical=='BETA':
|
762
|
+
|
763
|
+
df['beta'] = talib.BETA(df['High'],df['Low'],timeperiod=BETA_day)
|
764
|
+
|
765
|
+
if not isinstance(BETA_madays,list):
|
766
|
+
BETA_madays=[BETA_madays]
|
767
|
+
for d in BETA_madays:
|
768
|
+
df['beta_ma'+str(d)] = df['beta'].rolling(window=d).mean()
|
769
|
+
|
770
|
+
if not more_details:
|
771
|
+
#不保留指标本身
|
772
|
+
df.drop(columns = ['beta'],inplace=True)
|
773
|
+
|
774
|
+
#=========== TSF:时间序列预测
|
775
|
+
"""
|
776
|
+
|
777
|
+
"""
|
778
|
+
if technical=='TSF':
|
779
|
+
|
780
|
+
df['tsf'] = talib.TSF(df[indicator],timeperiod=TSF_day)
|
781
|
+
|
782
|
+
if not isinstance(TSF_madays,list):
|
783
|
+
TSF_madays=[TSF_madays]
|
784
|
+
for d in TSF_madays:
|
785
|
+
df['tsf_ma'+str(d)] = df['tsf'].rolling(window=d).mean()
|
786
|
+
|
787
|
+
if not more_details:
|
788
|
+
#不保留指标本身
|
789
|
+
df.drop(columns = ['tsf'],inplace=True)
|
790
|
+
|
791
|
+
#=========== AD:量价指标
|
792
|
+
"""
|
793
|
+
|
794
|
+
"""
|
795
|
+
if technical=='AD':
|
796
|
+
|
797
|
+
#df['ad'] = talib.AD(df['High'],df['Low'],df[indicator],df['Volume'],timeperiod=AD_day)
|
798
|
+
df['ad'] = talib.AD(df['High'],df['Low'],df[indicator],df['Volume'])
|
799
|
+
|
800
|
+
if not isinstance(AD_madays,list):
|
801
|
+
AD_madays=[AD_madays]
|
802
|
+
for d in AD_madays:
|
803
|
+
df['ad_ma'+str(d)] = df['ad'].rolling(window=d).mean()
|
804
|
+
|
805
|
+
if not more_details:
|
806
|
+
#不保留指标本身
|
807
|
+
df.drop(columns = ['ad'],inplace=True)
|
808
|
+
|
809
|
+
|
810
|
+
|
811
|
+
#过滤日期===================================================================
|
643
812
|
_,startpd,endpd=check_period(start,end)
|
644
813
|
df1=df[(df.index >= startpd) & (df.index <= endpd)]
|
645
814
|
|
815
|
+
#检查是否加入了计算结果的指标
|
816
|
+
dfcols=list(df)
|
817
|
+
if len(dfcols) > len(dfcols_original):
|
818
|
+
calculated=True
|
819
|
+
else:
|
820
|
+
calculated=False
|
646
821
|
|
647
|
-
return df1
|
822
|
+
return df1,calculated
|
648
823
|
|
649
824
|
|
650
825
|
#==============================================================================
|
@@ -2395,52 +2570,42 @@ def security_technical(ticker,start='default',end='default', \
|
|
2395
2570
|
return df
|
2396
2571
|
|
2397
2572
|
#==============================================================================
|
2573
|
+
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
2398
2574
|
if __name__ =="__main__":
|
2399
2575
|
RSI_days=[6,24]
|
2400
|
-
|
2401
|
-
|
2402
|
-
|
2403
|
-
|
2404
|
-
|
2405
|
-
KDJ_fastk_period=5; KDJ_slowk_period=3; KDJ_slowk_matype=0; KDJ_slowd_period=3
|
2406
|
-
KDJ_slowd_matype=0
|
2407
|
-
|
2576
|
+
OBV_days=[5,10]
|
2577
|
+
MA_days=[5,20]; EMA_days=[5,20]
|
2578
|
+
MACD_fastperiod=12; MACD_slowperiod=26; MACD_signalperiod=9
|
2579
|
+
KDJ_fastk_period=5; KDJ_slowk_period=3; KDJ_slowk_matype=0; KDJ_slowd_period=3; KDJ_slowd_matype=0
|
2408
2580
|
VOL_fastperiod=5; VOL_slowperiod=10
|
2409
|
-
|
2410
2581
|
PSY_days=12
|
2411
|
-
|
2412
2582
|
ARBR_days=26
|
2413
|
-
|
2414
2583
|
CR_day=16; CR_madays=[5,10,20]
|
2415
|
-
|
2416
2584
|
EMV_day=14; EMV_madays=9
|
2417
|
-
|
2418
|
-
BULL_days=20; BULL_nbdevup=2; BULL_nbdevdn=2; BULL_matype=0
|
2419
|
-
|
2585
|
+
BULL_day=20; BULL_nbdevup=2; BULL_nbdevdn=2; BULL_matype=0
|
2420
2586
|
TRIX_day=12; TRIX_madays=20
|
2421
|
-
|
2422
2587
|
DMA_fastperiod=10; DMA_slowperiod=50; DMA_madays=10
|
2423
|
-
|
2424
2588
|
BIAS_days=[6,12,24]
|
2425
|
-
|
2426
|
-
CCI_days=14
|
2427
|
-
|
2589
|
+
CCI_day=14; CCI_madays=[5,10]
|
2428
2590
|
WR_days=[10,6]
|
2429
|
-
|
2430
2591
|
ROC_day=12; ROC_madays=6
|
2431
|
-
|
2432
2592
|
DMI_DIdays=14; DMI_ADXdays=6
|
2593
|
+
MFI_day=14; MFI_madays=[3,5]
|
2594
|
+
MOM_day=10; MOM_madays=[5,20]
|
2595
|
+
SAR_day=4; SAR_madays=[5,20]
|
2596
|
+
BETA_day=5; BETA_madays=[5,20]
|
2597
|
+
TSF_day=14; TSF_madays=[5,10]
|
2598
|
+
AD_day=26; AD_madays=[5,20]
|
2433
2599
|
|
2434
|
-
ticker='AAPL';ticker_type='auto'
|
2435
|
-
|
2436
|
-
start='2024-3-1'; end='2024-4-12'; ahead_days=30*3
|
2437
2600
|
|
2438
|
-
|
2601
|
+
ticker='002594.SZ';ticker_type='auto'
|
2602
|
+
start='2024-5-1'; end='2024-6-13'; ahead_days=30*8
|
2603
|
+
technical='OBV'; indicator='Close'
|
2439
2604
|
|
2440
2605
|
attention_values=[0,25,50,75]
|
2441
|
-
more_details=
|
2606
|
+
more_details=True
|
2442
2607
|
ticker_type='auto'; source='auto'
|
2443
|
-
ahead_days=30*
|
2608
|
+
ahead_days=30*8
|
2444
2609
|
resample_freq='6H'; smooth=True;linewidth=1.5
|
2445
2610
|
date_range=False; date_freq=False; annotate=False
|
2446
2611
|
graph=['ALL']; printout=False
|
@@ -2450,63 +2615,104 @@ if __name__ =="__main__":
|
|
2450
2615
|
price_line_style='dotted'; price_line_color='red'; price_line_width=5; price_line_marker='.'
|
2451
2616
|
marker_sizes=[30,120,250]
|
2452
2617
|
|
2453
|
-
df=security_technical2(ticker,start,end
|
2618
|
+
df=security_technical2(ticker='AAPL',start='2024-5-1',end='2024-6-20', \
|
2619
|
+
technical='CR',more_details=True,loc1='upper left',loc2='lower right')
|
2454
2620
|
|
2455
2621
|
tlist=['RSI','OBV','MACD','KDJ','VOL','PSY','ARBR','CR','EMV','Bollinger', \
|
2456
2622
|
'TRIX','DMA','BIAS','CCI','W%R','ROC','DMI']
|
2457
2623
|
for t in tlist:
|
2458
2624
|
df=security_technical2(ticker,start,end,technical=t,loc1='lower left',loc2='lower right')
|
2459
2625
|
|
2460
|
-
def security_technical2(ticker,start='default',end='default', \
|
2461
|
-
technical=['MACD'],indicator='Close', \
|
2462
|
-
more_details=False, \
|
2463
|
-
attention_values=[0,25,50,75,100], \
|
2464
|
-
|
2465
|
-
ticker_type='auto',source='auto', \
|
2466
|
-
|
2467
|
-
#指标的默认参数
|
2468
|
-
RSI_days=[6,24], \
|
2469
|
-
OBV_days=5, \
|
2470
|
-
|
2471
|
-
MA_days=[5,20], \
|
2472
|
-
MACD_fastperiod=12,MACD_slowperiod=26,MACD_signalperiod=9, \
|
2473
|
-
|
2474
|
-
KDJ_fastk_period=9,KDJ_slowk_period=5,KDJ_slowk_matype=1, \
|
2475
|
-
KDJ_slowd_period=5,KDJ_slowd_matype=1, \
|
2476
|
-
|
2477
|
-
VOL_fastperiod=5,VOL_slowperiod=10, \
|
2478
|
-
PSY_days=12, \
|
2479
|
-
ARBR_days=26, \
|
2480
|
-
CR_day=16,CR_madays=[5,20], \
|
2481
|
-
EMV_day=14,EMV_madays=9, \
|
2482
|
-
|
2483
|
-
BULL_days=20,BULL_nbdevup=2,BULL_nbdevdn=2,BULL_matype=0, \
|
2484
|
-
|
2485
|
-
DMA_fastperiod=10,DMA_slowperiod=50,DMA_madays=10, \
|
2486
|
-
|
2487
|
-
TRIX_day=12,TRIX_madays=20, \
|
2488
|
-
BIAS_days=[6,24], \
|
2489
|
-
CCI_days=14, \
|
2490
|
-
WR_days=[10,6], \
|
2491
|
-
ROC_day=12,ROC_madays=6, \
|
2492
|
-
DMI_DIdays=14,DMI_ADXdays=6, \
|
2493
|
-
|
2494
|
-
#数据提前量
|
2495
|
-
ahead_days=30*4, \
|
2626
|
+
def security_technical2(ticker,start='default',end='default',technical='MACD', \
|
2496
2627
|
|
2497
|
-
|
2498
|
-
|
2499
|
-
|
2500
|
-
|
2501
|
-
|
2502
|
-
|
2503
|
-
|
2504
|
-
|
2505
|
-
|
2506
|
-
|
2507
|
-
|
2508
|
-
|
2509
|
-
|
2628
|
+
#不建议使用复权价,因为最高最低价开盘价没有复权价!
|
2629
|
+
indicator='Close', \
|
2630
|
+
|
2631
|
+
#显示指标本身,如果原来未显示的话
|
2632
|
+
more_details=False, \
|
2633
|
+
|
2634
|
+
#显示关注值水平线,每个指标不同,可自定义多个关注值
|
2635
|
+
attention_values=[], \
|
2636
|
+
|
2637
|
+
ticker_type='auto',source='auto', \
|
2638
|
+
|
2639
|
+
#指标的默认参数
|
2640
|
+
RSI_days=[6,14], \
|
2641
|
+
|
2642
|
+
OBV_days=[5,10], \
|
2643
|
+
|
2644
|
+
MA_days=[5,20],EMA_days=[5,20], \
|
2645
|
+
|
2646
|
+
MACD_fastperiod=12,MACD_slowperiod=26,MACD_signalperiod=9, \
|
2647
|
+
|
2648
|
+
KDJ_fastk_period=9,KDJ_slowk_period=5,KDJ_slowk_matype=1,KDJ_slowd_period=5,KDJ_slowd_matype=1, \
|
2649
|
+
|
2650
|
+
VOL_fastperiod=5,VOL_slowperiod=10, \
|
2651
|
+
|
2652
|
+
PSY_days=[6,12], \
|
2653
|
+
|
2654
|
+
ARBR_days=[26], \
|
2655
|
+
|
2656
|
+
CR_day=30,CR_madays=[10,20,40,60], \
|
2657
|
+
|
2658
|
+
EMV_day=14,EMV_madays=[9], \
|
2659
|
+
|
2660
|
+
BULL_day=20,BULL_nbdevup=2,BULL_nbdevdn=2,BULL_matype=0, \
|
2661
|
+
|
2662
|
+
DMA_fastperiod=10,DMA_slowperiod=50,DMA_madays=[10], \
|
2663
|
+
|
2664
|
+
TRIX_day=12,TRIX_madays=[5,10], \
|
2665
|
+
|
2666
|
+
BIAS_days=[6,12,24], \
|
2667
|
+
|
2668
|
+
CCI_day=14,CCI_madays=[5,10], \
|
2669
|
+
|
2670
|
+
WR_days=[13,34,89], \
|
2671
|
+
|
2672
|
+
ROC_day=12,ROC_madays=[65,12,18], \
|
2673
|
+
|
2674
|
+
DMI_DIdays=7,DMI_ADXdays=6, \
|
2675
|
+
|
2676
|
+
#资金流:3日作为信号,5日作为确认信号
|
2677
|
+
MFI_day=14,MFI_madays=[3,5], \
|
2678
|
+
MOM_day=10,MOM_madays=[5,20], \
|
2679
|
+
|
2680
|
+
#需要显示SAR
|
2681
|
+
SAR_day=4,SAR_madays=[5,20], \
|
2682
|
+
|
2683
|
+
#需要显示BETA
|
2684
|
+
BETA_day=5,BETA_madays=[5,20], \
|
2685
|
+
|
2686
|
+
#需要显示TSF
|
2687
|
+
TSF_day=14,TSF_madays=[5,10], \
|
2688
|
+
|
2689
|
+
#需要显示AD
|
2690
|
+
AD_day=26,AD_madays=[5,20], \
|
2691
|
+
|
2692
|
+
#数据提前量,用于前置计算指标的移动平均值
|
2693
|
+
ahead_days=30*8, \
|
2694
|
+
|
2695
|
+
#指标线的绘图参数
|
2696
|
+
resample_freq='2H',smooth=True,linewidth=1.5, \
|
2697
|
+
date_range=False,date_freq=False, \
|
2698
|
+
|
2699
|
+
#未启用
|
2700
|
+
annotate=False, \
|
2701
|
+
|
2702
|
+
#除了MACD外,其他指标均应为ALL
|
2703
|
+
graph=['ALL'], \
|
2704
|
+
printout=False, \
|
2705
|
+
loc1='best',loc2='best', \
|
2706
|
+
|
2707
|
+
#图形上下半区的背景颜色
|
2708
|
+
facecolor=['whitesmoke','papayawhip'], \
|
2709
|
+
|
2710
|
+
#价格线的绘图参数
|
2711
|
+
#price_line_style=(0,(1,1)), \
|
2712
|
+
price_line_style='dotted', \
|
2713
|
+
price_line_color=['red','green'], \
|
2714
|
+
price_line_width=1,price_line_marker='o', \
|
2715
|
+
marker_sizes=[30,120,250], \
|
2510
2716
|
):
|
2511
2717
|
"""
|
2512
2718
|
功能:计算和绘制证券技术分析指标的简易图,仅供进一步探索使用,仅用于单个证券(股债基)
|
@@ -2523,7 +2729,7 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2523
2729
|
try:
|
2524
2730
|
import talib
|
2525
2731
|
except:
|
2526
|
-
print(" #Error(security_technical2): lack of necessary package
|
2732
|
+
print(" #Error(security_technical2): lack of necessary package, talib")
|
2527
2733
|
talib_install_method()
|
2528
2734
|
return None
|
2529
2735
|
|
@@ -2542,11 +2748,13 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2542
2748
|
|
2543
2749
|
#检查指标类别
|
2544
2750
|
tech_list={'Bollinger':'布林带','MACD':'指数平滑异同平均', \
|
2545
|
-
|
2546
|
-
|
2547
|
-
|
2548
|
-
|
2549
|
-
|
2751
|
+
'RSI':'相对强弱','KDJ':'随机指标','OBV':'能量潮', \
|
2752
|
+
'SAR':'抛物转向','VOL':'成交量','ARBR':'人气与意愿', \
|
2753
|
+
'CR':'能力线','EMV':'简易波动','TRIX':'三重指数平滑', \
|
2754
|
+
'DMA':'均线差','BIAS':'乖离率','CCI':'顺势线', \
|
2755
|
+
'W%R':'威廉比率','ROC':'变动速率','DMI':'趋向线','PSY':'心理线', \
|
2756
|
+
'MFI':'资金流','MOM':'动量指标','BETA':'动态贝塔', \
|
2757
|
+
'TSF':'时间序列预测','AD':'量价指标','MA':'移动平均','EMA':'指数移动平均'}
|
2550
2758
|
|
2551
2759
|
technical1=technical
|
2552
2760
|
if isinstance(technical,list):
|
@@ -2561,7 +2769,12 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2561
2769
|
|
2562
2770
|
#抓取抓取价格数据
|
2563
2771
|
fromdate1=date_adjust(fromdate,adjust=-ahead_days)
|
2564
|
-
|
2772
|
+
if 'Adj' in indicator.title():
|
2773
|
+
adjust='Adj_only' #最高最低价开盘收盘价均为复权价
|
2774
|
+
else:
|
2775
|
+
adjust=''
|
2776
|
+
|
2777
|
+
price,found=get_price_1ticker_mixed(ticker=ticker,fromdate=fromdate1,adjust=adjust, \
|
2565
2778
|
todate=todate,ticker_type=ticker_type,fill=False,source=source)
|
2566
2779
|
|
2567
2780
|
if found not in ['Found']:
|
@@ -2574,10 +2787,6 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2574
2787
|
|
2575
2788
|
#分位数
|
2576
2789
|
import numpy as np
|
2577
|
-
"""
|
2578
|
-
max(price['up_down_abs'])
|
2579
|
-
min(price['up_down_abs'])
|
2580
|
-
"""
|
2581
2790
|
q70=np.percentile(price['up_down_abs'],70)
|
2582
2791
|
q30=np.percentile(price['up_down_abs'],30)
|
2583
2792
|
|
@@ -2585,57 +2794,58 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2585
2794
|
price['marker_size']=price['up_down_abs'].apply(lambda x: big_size if x>=q70 else mid_size if x>=q30 else small_size)
|
2586
2795
|
|
2587
2796
|
#计算技术指标
|
2588
|
-
df=calc_technical(price,fromdate,todate, \
|
2589
|
-
|
2590
|
-
|
2591
|
-
|
2592
|
-
|
2593
|
-
|
2594
|
-
|
2595
|
-
|
2596
|
-
|
2597
|
-
|
2598
|
-
|
2599
|
-
|
2600
|
-
|
2601
|
-
|
2602
|
-
|
2603
|
-
|
2604
|
-
|
2605
|
-
|
2606
|
-
|
2607
|
-
|
2608
|
-
|
2609
|
-
|
2610
|
-
|
2611
|
-
|
2612
|
-
|
2613
|
-
|
2614
|
-
|
2615
|
-
|
2616
|
-
|
2617
|
-
|
2618
|
-
|
2619
|
-
|
2620
|
-
|
2621
|
-
|
2622
|
-
|
2623
|
-
|
2624
|
-
|
2625
|
-
|
2626
|
-
|
2627
|
-
|
2628
|
-
|
2629
|
-
|
2630
|
-
|
2631
|
-
|
2632
|
-
|
2797
|
+
df,calculated=calc_technical(price,fromdate,todate,technical=technical, \
|
2798
|
+
|
2799
|
+
RSI_days=RSI_days, \
|
2800
|
+
OBV_days=OBV_days, \
|
2801
|
+
|
2802
|
+
MA_days=MA_days,EMA_days=EMA_days, \
|
2803
|
+
|
2804
|
+
MACD_fastperiod=MACD_fastperiod,MACD_slowperiod=MACD_slowperiod,MACD_signalperiod=MACD_signalperiod, \
|
2805
|
+
|
2806
|
+
KDJ_fastk_period=KDJ_fastk_period,KDJ_slowk_period=KDJ_slowk_period, \
|
2807
|
+
KDJ_slowk_matype=KDJ_slowk_matype,KDJ_slowd_period=KDJ_slowd_period,KDJ_slowd_matype=KDJ_slowd_matype, \
|
2808
|
+
|
2809
|
+
VOL_fastperiod=VOL_fastperiod,VOL_slowperiod=VOL_slowperiod, \
|
2810
|
+
|
2811
|
+
PSY_days=PSY_days, \
|
2812
|
+
ARBR_days=ARBR_days, \
|
2813
|
+
CR_day=CR_day,CR_madays=CR_madays, \
|
2814
|
+
EMV_day=EMV_day,EMV_madays=EMV_madays, \
|
2815
|
+
|
2816
|
+
BULL_day=BULL_day,BULL_nbdevup=BULL_nbdevup,BULL_nbdevdn=BULL_nbdevdn,BULL_matype=BULL_matype, \
|
2817
|
+
|
2818
|
+
DMA_fastperiod=DMA_fastperiod,DMA_slowperiod=DMA_slowperiod,DMA_madays=DMA_madays, \
|
2819
|
+
|
2820
|
+
TRIX_day=TRIX_day,TRIX_madays=TRIX_madays, \
|
2821
|
+
BIAS_days=BIAS_days, \
|
2822
|
+
CCI_day=CCI_day,CCI_madays=CCI_madays, \
|
2823
|
+
WR_days=WR_days, \
|
2824
|
+
ROC_day=ROC_day,ROC_madays=ROC_madays, \
|
2825
|
+
DMI_DIdays=DMI_DIdays,DMI_ADXdays=DMI_ADXdays, \
|
2826
|
+
|
2827
|
+
MFI_day=MFI_day,MFI_madays=MFI_madays, \
|
2828
|
+
MOM_day=MOM_day,MOM_madays=MOM_madays, \
|
2829
|
+
|
2830
|
+
#需要显示SAR
|
2831
|
+
SAR_day=SAR_day,SAR_madays=SAR_madays, \
|
2832
|
+
|
2833
|
+
#需要显示BETA
|
2834
|
+
BETA_day=BETA_day,BETA_madays=BETA_madays, \
|
2835
|
+
|
2836
|
+
#需要显示TSF
|
2837
|
+
TSF_day=TSF_day,TSF_madays=TSF_madays, \
|
2838
|
+
|
2839
|
+
#需要显示AD
|
2840
|
+
AD_day=AD_day,AD_madays=AD_madays, \
|
2841
|
+
|
2842
|
+
indicator=indicator, \
|
2843
|
+
more_details=more_details)
|
2633
2844
|
|
2634
2845
|
#技术指标的绘图线
|
2635
2846
|
tech_line_default={'RSI':['rsi'],
|
2636
2847
|
'OBV':['obv'],
|
2637
2848
|
'MACD':['DIF','DEA'],
|
2638
|
-
#'KDJ':['kdj_k','kdj_d','kdj_j'],
|
2639
2849
|
'KDJ':['kdj'],
|
2640
2850
|
'SAR':['sar'],
|
2641
2851
|
'VOL':['vol'],
|
@@ -2650,9 +2860,23 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2650
2860
|
'W%R':['wr'],
|
2651
2861
|
'ROC':['roc'],
|
2652
2862
|
'DMI':['pdi','mdi'],
|
2653
|
-
'DMA':['dma'],
|
2863
|
+
'DMA':['dma'],
|
2864
|
+
'MFI':['mfi'],
|
2865
|
+
'MOM':['mom'],
|
2866
|
+
'BETA':['beta'],
|
2867
|
+
'TSF':['tsf'],
|
2868
|
+
'AD':['ad'],
|
2869
|
+
'MA':['ma'],'EMA':['ema'],
|
2870
|
+
}
|
2871
|
+
|
2872
|
+
#检查计算结果:有问题?
|
2873
|
+
if not calculated:
|
2874
|
+
print(" #Warning(security_technical2): unsupported technical parameter",technical)
|
2875
|
+
print(" Supported technical parameters:")
|
2876
|
+
printlist(sorted(list(tech_line_default.keys())),numperline=11,beforehand=' ',separator=' ')
|
2877
|
+
return None
|
2654
2878
|
|
2655
|
-
|
2879
|
+
#绘图数值缩放比例,以便使指标数量级与股价更加协调
|
2656
2880
|
magnitude_list={'RSI':[1,''],
|
2657
2881
|
'OBV':[1/1000000,'百万'],
|
2658
2882
|
'MACD':[1,''],
|
@@ -2662,15 +2886,21 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2662
2886
|
'PSY':[1,''],
|
2663
2887
|
'ARBR':[1,''],
|
2664
2888
|
'CR':[1,''],
|
2665
|
-
'EMV':[
|
2889
|
+
'EMV':[100000000,'亿分之一'],
|
2666
2890
|
'Bollinger':[1,''],
|
2667
|
-
'TRIX':[
|
2891
|
+
'TRIX':[100,'百分之一'],
|
2668
2892
|
'BIAS':[1,''],
|
2669
2893
|
'CCI':[1,''],
|
2670
2894
|
'W%R':[1,''],
|
2671
2895
|
'ROC':[1,''],
|
2672
2896
|
'DMI':[1,''],
|
2673
2897
|
'DMA':[1,''],
|
2898
|
+
'MA':[1,''],'EMA':[1,''],
|
2899
|
+
'MFI':[1,''],
|
2900
|
+
'MOM':[1,''],
|
2901
|
+
'BETA':[1,''],
|
2902
|
+
'TSF':[1,''],
|
2903
|
+
'AD':[1/1000000,'百万'],
|
2674
2904
|
'Volume':[1/1000000,'百万']}
|
2675
2905
|
|
2676
2906
|
mag_times=magnitude_list[technical1][0]
|
@@ -2706,7 +2936,7 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2706
2936
|
df['Volume']=df['Volume'] * magnitude_list['Volume'][0]
|
2707
2937
|
|
2708
2938
|
#字段排序
|
2709
|
-
tech_line_collist.sort()
|
2939
|
+
#tech_line_collist.sort()
|
2710
2940
|
if 'marker_size' in tech_line_collist:
|
2711
2941
|
df1=df[tech_line_collist+[indicator,'Volume','up_down']]
|
2712
2942
|
else:
|
@@ -2718,20 +2948,9 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2718
2948
|
import matplotlib.pyplot as plt
|
2719
2949
|
import matplotlib.dates as mdates
|
2720
2950
|
#import matplotlib.gridspec as gridspec
|
2721
|
-
"""
|
2722
|
-
fig = plt.figure()
|
2723
|
-
ax = fig.add_subplot(111)
|
2724
|
-
"""
|
2725
|
-
"""
|
2726
|
-
#图ax在上方,ax3在下方
|
2727
|
-
fig, (ax, ax3) = plt.subplots(2, sharex=True,figsize=(12,9))
|
2728
2951
|
|
2729
|
-
#plt.gca().set_facecolor('whitesmoke')
|
2730
|
-
fig.gca().set_facecolor(facecolor) #放在这里生效,放尾部不生效
|
2731
|
-
"""
|
2732
2952
|
# 创建两行的布局,上半部分高度为4,下半部分高度为1
|
2733
2953
|
fig = plt.figure(figsize=(14,9))
|
2734
|
-
#fig.gca().set_facecolor(facecolor)
|
2735
2954
|
|
2736
2955
|
if isinstance(facecolor,str):
|
2737
2956
|
facecolor1=facecolor2=facecolor
|
@@ -2757,30 +2976,6 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2757
2976
|
except:
|
2758
2977
|
ax3.set_facecolor('papayawhip')
|
2759
2978
|
|
2760
|
-
"""
|
2761
|
-
line0=False; line30=False; line50=False; line80=False
|
2762
|
-
for l in tech_line_collist:
|
2763
|
-
lmax=df1[l].max(); lmin=df1[l].min()
|
2764
|
-
if lmax * lmin < 0: line0=True
|
2765
|
-
if 100 >= lmax >= 30 and 0 <= lmin <= 30: line30=True
|
2766
|
-
if 100 >= lmax >= 50 and 0 <= lmin <= 50: line50=True
|
2767
|
-
if 100 >= lmax >= 80 and 0 <= lmin <= 80: line80=True
|
2768
|
-
|
2769
|
-
ax.plot(df1.index,df1[l],label=l)
|
2770
|
-
|
2771
|
-
#绘制0线
|
2772
|
-
if line0:
|
2773
|
-
plt.axhline(y=0,ls=":",c="black",linewidth=2)
|
2774
|
-
#绘制30线
|
2775
|
-
if line30:
|
2776
|
-
plt.axhline(y=30,ls=":",c="green",linewidth=2)
|
2777
|
-
#绘制50线
|
2778
|
-
if line50:
|
2779
|
-
plt.axhline(y=50,ls=":",c="black",linewidth=2)
|
2780
|
-
#绘制50线
|
2781
|
-
if line80:
|
2782
|
-
plt.axhline(y=80,ls=":",c="black",linewidth=2)
|
2783
|
-
"""
|
2784
2979
|
color_list=['k','g','b','c','m','y','r']
|
2785
2980
|
attention_draws=[False] * len(attention_values)
|
2786
2981
|
|
@@ -2815,7 +3010,22 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2815
3010
|
if mag_label != '':
|
2816
3011
|
ylabeltxt1=ylabeltxt1+'('+mag_label+')'
|
2817
3012
|
ax.set_ylabel(ylabeltxt1,fontsize=ylabel_txt_size)
|
2818
|
-
|
3013
|
+
|
3014
|
+
#对图例项目排序
|
3015
|
+
# 获取图例句柄和标签
|
3016
|
+
handles, labels = ax.get_legend_handles_labels()
|
3017
|
+
|
3018
|
+
# 指定显示顺序
|
3019
|
+
labels_sorted = sort_list_by_len(labels,reverse=False)
|
3020
|
+
handles_sorted = []
|
3021
|
+
for l in labels_sorted:
|
3022
|
+
pos=labels.index(l)
|
3023
|
+
h=handles[pos]
|
3024
|
+
handles_sorted =handles_sorted +[h]
|
3025
|
+
|
3026
|
+
# 在指定位置添加新的图例,并按照指定顺序显示
|
3027
|
+
ax.legend(handles=handles_sorted,labels=labels_sorted,loc=loc1,fontsize=legend_txt_size)
|
3028
|
+
#ax.legend(loc=loc1,fontsize=legend_txt_size)
|
2819
3029
|
|
2820
3030
|
interval=int(len(df1)/10)+1
|
2821
3031
|
ax.xaxis.set_major_locator(mdates.DayLocator(interval=interval)) # 隔interval天一个标记
|
@@ -2857,12 +3067,10 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2857
3067
|
if df1seg['up_down'].values[0] >=0:
|
2858
3068
|
seg_color=price_line_color1
|
2859
3069
|
#labeltxt=ylabeltxt2+'(当日↑)'
|
2860
|
-
#labeltxt=ylabeltxt2+'(当日≥开盘价)'
|
2861
3070
|
labeltxt=ylabeltxt2+'(当日阳线)'
|
2862
3071
|
else:
|
2863
3072
|
seg_color=price_line_color2
|
2864
3073
|
#labeltxt=ylabeltxt2+'(当日↓)'
|
2865
|
-
#labeltxt=ylabeltxt2+'(当日<开盘价)'
|
2866
3074
|
labeltxt=ylabeltxt2+'(当日阴线)'
|
2867
3075
|
|
2868
3076
|
if first_time:
|
@@ -2871,22 +3079,11 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2871
3079
|
second_time=False
|
2872
3080
|
else:
|
2873
3081
|
labeltxt=''
|
2874
|
-
|
2875
|
-
ax2.plot(df1seg.index,df1seg[indicator],label=labeltxt, \
|
2876
|
-
linestyle=':',color=seg_color,lw=price_line_width,marker=price_line_marker)
|
2877
|
-
"""
|
3082
|
+
|
2878
3083
|
ax2.scatter(df1seg.index,df1seg[indicator], \
|
2879
3084
|
s=df1seg['marker_size'], \
|
2880
3085
|
label=labeltxt, \
|
2881
3086
|
linestyle=':',color=seg_color,lw=price_line_width,marker=price_line_marker)
|
2882
|
-
|
2883
|
-
|
2884
|
-
"""
|
2885
|
-
ax2.plot(df1.index,df1[indicator],label=ylabeltxt2, \
|
2886
|
-
linestyle=price_line_style,color=price_line_color1,lw=price_line_width,marker=price_line_marker)
|
2887
|
-
ax2.scatter(df1down.index,df1down[indicator],label=ylabeltxt2, \
|
2888
|
-
linestyle=price_line_style,color=price_line_color2,lw=price_line_width,marker=price_line_marker)
|
2889
|
-
"""
|
2890
3087
|
|
2891
3088
|
ax2.legend(loc=loc2,fontsize=legend_txt_size)
|
2892
3089
|
|
@@ -2896,9 +3093,9 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2896
3093
|
|
2897
3094
|
ax3.set_ylabel("交易量(百万股)",fontsize=ylabel_txt_size -4)
|
2898
3095
|
|
2899
|
-
footnote1="\n
|
2900
|
-
footnote2="
|
2901
|
-
footnote3="
|
3096
|
+
footnote1="\n注:"
|
3097
|
+
footnote2="价格曲线端点大中小对应当日涨跌幅度的高中低情形。"
|
3098
|
+
footnote3="横轴日期上的空白处为非交易日。\n"
|
2902
3099
|
|
2903
3100
|
import datetime; todaydt = str(datetime.date.today())
|
2904
3101
|
footnote4="数据来源:新浪/雅虎/stooq/东方财富等,"+todaydt+"统计"
|