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/stock_technical.py CHANGED
@@ -62,84 +62,126 @@ plt.rcParams['axes.grid']=False
62
62
  #==============================================================================
63
63
 
64
64
  if __name__ =="__main__":
65
- ticker='AAPL'
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
- CR_days=16
97
- CRMA_list=[5,10,20]
80
+ CR_day=16; CR_madays=[5,10,20]
98
81
 
99
- EMV_days=14
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
- TRIX_days=12
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
- BIAS_list=[6,12,24]
90
+ BIAS_days=[6,12,24]
115
91
 
116
92
  CCI_days=14
117
93
 
118
- WR_list=[10,6]
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
- ROC_days=12
121
- ROC_madays=6
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
- EMV_days=14,EMV_madays=9, \
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
- TRIX_days=12,TRIX_madays=20, \
139
- BIAS_list=[6,12,24], \
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
- WR_list=[10,6], \
142
- ROC_days=12,ROC_madays=6, \
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
- import talib
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
- 20-50 弱 观望,谨慎买入
171
- 0-20 极弱 买入
217
+ 30-50 弱 观望,谨慎买入
218
+ 0-30 极弱 买入
172
219
  """
173
- df['rsi'] = talib.RSI(df['Close'], timeperiod=RSI_days)
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
- 葛兰碧的OBV指标是建立在国外成熟市场上的经验总结。
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
- df['obv_ma'] = talib.MA(df['obv'],timeperiod=OBV_days)
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
- for mad in MA_days:
217
- df['ma'+str(mad)] = talib.MA(df['Close'],timeperiod=mad)
218
- df['ema'+str(mad)] = talib.EMA(df['Close'],timeperiod=mad)
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.DIFF、DEA均为正,DIFF向上突破DEA,买入信号。
238
- 2.DIFF、DEA均为负,DIFF向下跌破DEA,卖出信号。
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['DIFF'],df['DEA'],df['MACD']=talib.MACD(df['Close'], \
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
- df['ext_2'] = df['ext_1'].rolling(window=PSY_days).sum()
317
- df['psy'] = (df['ext_2']/float(PSY_days))*100
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
- df['h_o_sum'] = df['h_o'].rolling(window=ARBR_days).sum()
332
- df['o_l_sum'] = df['o_l'].rolling(window=ARBR_days).sum()
333
- df['ar'] = (df['h_o_sum']/df['o_l_sum'])*100
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
- df['h_c_sum'] = df['h_c'].rolling(window=ARBR_days).sum()
337
- df['c_l_sum'] = df['c_l'].rolling(window=ARBR_days).sum()
338
- df['br'] = (df['h_c_sum']/df['c_l_sum'])*100
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
- df['h_m_sum'] = df['h_m'].rolling(window=CR_days).sum()
359
- df['m_l_sum'] = df['m_l'].rolling(window=CR_days).sum()
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 crmad in CRMA_list:
363
- df['crma'+str(crmad)] = talib.MA(df['cr'],timeperiod=crmad)
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
- df['emv'] = df['em'].rolling(window=EMV_days).sum()
388
- df['emva'] = talib.MA(df['emv'],timeperiod=EMV_madays)
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=TRIX_days)
427
- df['trma'] = talib.MA(df['trix'],timeperiod=TRIX_madays)
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
- df['dma'] = talib.MA(df['ddd'],timeperiod=DMA_madays)
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
- df['ma6'] = talib.MA(df['Close'],timeperiod=BIAS_list[0])
458
- df['ma12'] = talib.MA(df['Close'],timeperiod=BIAS_list[1])
459
- df['ma24'] = talib.MA(df['Close'],timeperiod=BIAS_list[2])
460
- df['bias'] = ((df['Close']-df['ma6'])/df['ma6'])*100
461
- df['bias2'] = ((df['Close']-df['ma12'])/df['ma12'])*100
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 = ['ma6','ma12','ma24'],inplace=True)
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
- df['cci'] = talib.CCI(df['High'],df['Low'],df['Close'],timeperiod=CCI_days)
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.低于20,超买,即将见顶,应及时卖出
572
+ 1.低于30,超买,即将见顶,应及时卖出
485
573
  2.高于80,超卖,即将见底,应伺机买进
486
574
  3.与RSI、MTM指标配合使用,效果更好
487
575
  """
488
- n = WR_list[0]
489
- df['h_10'] = df['High'].rolling(window=n).max()
490
- df['l_10'] = df['Low'].rolling(window=n).min()
491
- df['wr10'] = ((df['h_10']-df['Close'])/(df['h_10']-df['l_10']))*100
492
-
493
- n2 = WR_list[1]
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','h_6','l_6'],inplace=True)
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=ROC_days)
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
- df['pdi'] = talib.PLUS_DI(df['High'],df['Low'],df['Close'],timeperiod=DMI_DIdays)
518
- df['mdi'] = talib.MINUS_DI(df['High'],df['Low'],df['Close'],timeperiod=DMI_DIdays)
519
- df['adx'] = talib.ADX(df['High'],df['Low'],df['Close'],timeperiod=DMI_ADXdays)
520
- df['adxr'] = talib.ADXR(df['High'],df['Low'],df['Close'],timeperiod=DMI_ADXdays)
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 df
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="股票价格走势分析:"+codetranslate(ticker)+",简单移动均线"
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="股票价格走势分析:"+codetranslate(ticker)+",指数加权均线"
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="股票价格走势分析:"+codetranslate(ticker)+",MACD"
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="股票价格走势分析:"+codetranslate(ticker)+",RSI"
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="股票价格走势分析:"+codetranslate(ticker)+",KDJ"
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研判股价趋势:回溯验证,"+codetranslate(ticker))
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(" 之后出现股价上涨趋势的比例:",round(checkdf['future up ratio'].values[0]*100,1),'\b%')
1803
- print(" 之后出现股价下跌趋势的比例:",round(checkdf['future down ratio'].values[0]*100,1),'\b%')
1804
- print(" 之后出现股价振荡情形的比例:",round(checkdf['future vibrate ratio'].values[0]*100,1),'\b%')
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金叉后股价上涨的比例:",round(checkdf['t2+ ratio'].values[0]*100,1),'\b%')
1914
+ print(" 出现JD金叉后价格上涨的比例:",round(checkdf['t2+ ratio'].values[0]*100,1),'\b%')
1809
1915
  elif JKcross =='top down':
1810
- print(" 出现JK死叉后股价下跌的比例:",round(checkdf['t2- ratio'].values[0]*100,1),'\b%')
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,annotate=annotate)
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="证券趋势布林带:"+codetranslate(ticker)
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="证券趋势布林带:"+codetranslate(ticker)
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
  #==============================================================================