siat 3.1.22__py3-none-any.whl → 3.1.28__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/markowitz2-20240620.py +2614 -0
- siat/markowitz2.py +52 -4
- siat/sector_china.py +17 -9
- siat/security_price2.py +11 -0
- siat/stock_technical.py +84 -50
- siat/valuation_china.py +7 -5
- {siat-3.1.22.dist-info → siat-3.1.28.dist-info}/METADATA +1 -1
- {siat-3.1.22.dist-info → siat-3.1.28.dist-info}/RECORD +10 -9
- {siat-3.1.22.dist-info → siat-3.1.28.dist-info}/WHEEL +0 -0
- {siat-3.1.22.dist-info → siat-3.1.28.dist-info}/top_level.txt +0 -0
siat/markowitz2.py
CHANGED
@@ -252,6 +252,23 @@ if __name__=='__main__':
|
|
252
252
|
printout=True
|
253
253
|
graph=False
|
254
254
|
|
255
|
+
#测试3
|
256
|
+
Market={'Market':('China','000300.SS','锂电池1号')}
|
257
|
+
Stocks={'300750.SZ':0.4,#宁德时代
|
258
|
+
'002594.SZ':0.3,#比亚迪
|
259
|
+
'300014.SZ':0.2,#亿纬锂能
|
260
|
+
'300207.SZ':0.1,#欣旺达
|
261
|
+
}
|
262
|
+
portfolio=dict(Market,**Stocks)
|
263
|
+
|
264
|
+
indicator='Adj Close'
|
265
|
+
adjust='qfq'; source='auto'; ticker_type='bond'
|
266
|
+
thedate='2024-6-19'
|
267
|
+
pastyears=2
|
268
|
+
printout=True
|
269
|
+
graph=False
|
270
|
+
|
271
|
+
|
255
272
|
pf_info=portfolio_build(portfolio,thedate,pastyears,printout,graph)
|
256
273
|
|
257
274
|
"""
|
@@ -260,12 +277,30 @@ def portfolio_cumret(portfolio,thedate,pastyears=1, \
|
|
260
277
|
printout=True,graph=True):
|
261
278
|
"""
|
262
279
|
def portfolio_build(portfolio,thedate='default',pastyears=1, \
|
280
|
+
indicator='Adj Close', \
|
281
|
+
adjust='qfq',source='auto',ticker_type='auto', \
|
263
282
|
printout=True,graph=False):
|
264
283
|
"""
|
265
284
|
功能:收集投资组合成份股数据,绘制收益率趋势图,并与等权和期间内交易额加权策略组合比较
|
266
285
|
注意:此处无需RF,待到优化策略时再指定
|
267
286
|
printout=True控制获取股价时是否逐个显示
|
287
|
+
|
288
|
+
特别注意:若ticker_type='fund'可能导致无法处理股票的复权价!
|
289
|
+
若要指定特定的证券为债券,则需要使用列表逐一指定证券的类型(股票,债券,基金)
|
268
290
|
"""
|
291
|
+
#判断复权标志
|
292
|
+
indicator_list=['Close','Adj Close']
|
293
|
+
if indicator not in indicator_list:
|
294
|
+
print(" Warning(portfolio_build): invalid indicator",indicator)
|
295
|
+
print(" Supported indicator:",indicator_list)
|
296
|
+
indicator='Adj Close'
|
297
|
+
|
298
|
+
adjust_list=['','qfq','hfq']
|
299
|
+
if adjust not in adjust_list:
|
300
|
+
print(" Warning(portfolio_build): invalid indicator",adjust)
|
301
|
+
print(" Supported adjust:",adjust_list)
|
302
|
+
adjust='qfq'
|
303
|
+
|
269
304
|
import datetime
|
270
305
|
stoday = datetime.date.today()
|
271
306
|
if thedate=='default':
|
@@ -329,18 +364,23 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
|
|
329
364
|
|
330
365
|
# 抓取投资组合股价
|
331
366
|
#prices=get_prices(tickerlist,start,thedate)
|
332
|
-
|
367
|
+
#判断是否赚取复权价
|
368
|
+
if indicator == 'Adj Close' and adjust == '':
|
369
|
+
adjust='qfq'
|
370
|
+
if indicator == 'Close' and adjust != '':
|
371
|
+
indicator = 'Adj Close'
|
372
|
+
|
333
373
|
if printout:
|
334
374
|
#prices=get_prices_simple(tickerlist,start,thedate) #有待改造?
|
335
375
|
#债券优先
|
336
376
|
prices,found=get_price_mticker(tickerlist,start,thedate, \
|
337
|
-
adjust=
|
377
|
+
adjust=adjust,source=source,ticker_type=ticker_type,fill=False)
|
338
378
|
else:
|
339
379
|
with HiddenPrints():
|
340
380
|
#prices=get_prices_simple(tickerlist,start,thedate) #有待改造?
|
341
381
|
prices,found=get_price_mticker(tickerlist,start,thedate, \
|
342
|
-
adjust=
|
343
|
-
|
382
|
+
adjust=adjust,source=source,ticker_type=ticker_type,fill=False)
|
383
|
+
|
344
384
|
if found == 'Found':
|
345
385
|
ntickers=len(list(prices['Close']))
|
346
386
|
nrecords=len(prices)
|
@@ -360,6 +400,14 @@ def portfolio_build(portfolio,thedate='default',pastyears=1, \
|
|
360
400
|
print(" #Error(portfolio_build): retrieved empty prices for",pname)
|
361
401
|
return None
|
362
402
|
#..........................................................................
|
403
|
+
#判断是否使用复权价:若是,使用Adj Close直接覆盖Close。方法最简单,且兼容后续处理!
|
404
|
+
if (indicator =='Adj Close') or (adjust !=''):
|
405
|
+
prices_collist=list(prices)
|
406
|
+
for pc in prices_collist:
|
407
|
+
pc1=pc[0]; pc2=pc[1]
|
408
|
+
if pc1=='Close':
|
409
|
+
pc_adj=('Adj Close',pc2)
|
410
|
+
prices[pc]=prices[pc_adj]
|
363
411
|
|
364
412
|
# 取各个成份股的收盘价
|
365
413
|
aclose=prices['Close']
|
siat/sector_china.py
CHANGED
@@ -1161,7 +1161,7 @@ if __name__=='__main__':
|
|
1161
1161
|
period="day"
|
1162
1162
|
industry_list='all'
|
1163
1163
|
|
1164
|
-
def get_industry_sw(itype='1',period="day",industry_list='all'):
|
1164
|
+
def get_industry_sw(itype='1',period="day",industry_list='all',max_sleep=8):
|
1165
1165
|
"""
|
1166
1166
|
功能:遍历某类申万指数,下载数据
|
1167
1167
|
itype: F表征指数,n=1/2/3行业指数,S风格指数,B大类风格,C金创类
|
@@ -1174,7 +1174,7 @@ def get_industry_sw(itype='1',period="day",industry_list='all'):
|
|
1174
1174
|
if not (itype in typelist):
|
1175
1175
|
print(" #Error(get_industry_sw): unsupported industry category",itype)
|
1176
1176
|
print(" Supported industry category",typelist)
|
1177
|
-
print(" F: Featured, n-Level n
|
1177
|
+
print(" F: Featured, n-Level n industry, S-Styled, B- Big Styled, C- Financial Innovation, A-All (more time))")
|
1178
1178
|
return None
|
1179
1179
|
|
1180
1180
|
#获得指数代码
|
@@ -1192,10 +1192,10 @@ def get_industry_sw(itype='1',period="day",industry_list='all'):
|
|
1192
1192
|
#循环获取指标
|
1193
1193
|
import pandas as pd
|
1194
1194
|
import akshare as ak
|
1195
|
-
import datetime
|
1195
|
+
import datetime; import random; import time
|
1196
1196
|
df=pd.DataFrame()
|
1197
1197
|
|
1198
|
-
print("
|
1198
|
+
print(" Start searching industry data, it takes time, please wait ...")
|
1199
1199
|
num=len(ilist)
|
1200
1200
|
if num <= 10:
|
1201
1201
|
steps=5
|
@@ -1205,7 +1205,7 @@ def get_industry_sw(itype='1',period="day",industry_list='all'):
|
|
1205
1205
|
total=len(ilist)
|
1206
1206
|
fail_list=[]
|
1207
1207
|
for i in ilist:
|
1208
|
-
|
1208
|
+
print_progress_percent2(i,ilist,steps=5,leading_blanks=4)
|
1209
1209
|
#print(" Retrieving information for industry",i)
|
1210
1210
|
|
1211
1211
|
#抓取指数价格
|
@@ -1235,7 +1235,11 @@ def get_industry_sw(itype='1',period="day",industry_list='all'):
|
|
1235
1235
|
df=df._append(dft2)
|
1236
1236
|
|
1237
1237
|
current=ilist.index(i)
|
1238
|
-
print_progress_percent(current,total,steps=steps,leading_blanks=2)
|
1238
|
+
#print_progress_percent(current,total,steps=steps,leading_blanks=2)
|
1239
|
+
|
1240
|
+
#生成随机数睡眠,试图防止被反爬虫,不知是否管用!
|
1241
|
+
random_int=random.randint(1,max_sleep)
|
1242
|
+
time.sleep(random_int)
|
1239
1243
|
|
1240
1244
|
#num=list(set(list(df['ticker'])))
|
1241
1245
|
if len(fail_list)==0:
|
@@ -1266,7 +1270,7 @@ if __name__=='__main__':
|
|
1266
1270
|
industry_list=['850831.SW','801785.SW','801737.SW','801194.SW',
|
1267
1271
|
'801784.SW','801783.SW','801782.SW']
|
1268
1272
|
|
1269
|
-
def get_industry_sw2(industry_list,period="day"):
|
1273
|
+
def get_industry_sw2(industry_list,period="day",max_sleep=8):
|
1270
1274
|
"""
|
1271
1275
|
功能:遍历指定的申万指数列表,下载数据
|
1272
1276
|
period="day"; choice of {"day", "week", "month"}
|
@@ -1280,10 +1284,10 @@ def get_industry_sw2(industry_list,period="day"):
|
|
1280
1284
|
#循环获取指标
|
1281
1285
|
import pandas as pd
|
1282
1286
|
import akshare as ak
|
1283
|
-
import datetime
|
1287
|
+
import datetime; import random; import time
|
1284
1288
|
df=pd.DataFrame()
|
1285
1289
|
|
1286
|
-
print("Searching industry information, please wait ...")
|
1290
|
+
print(" Searching industry information, it takes time, please wait ...")
|
1287
1291
|
ilist=industry_list
|
1288
1292
|
num=len(ilist)
|
1289
1293
|
if num <= 10:
|
@@ -1323,6 +1327,10 @@ def get_industry_sw2(industry_list,period="day"):
|
|
1323
1327
|
|
1324
1328
|
current=ilist.index(i)
|
1325
1329
|
print_progress_percent(current,total,steps=steps,leading_blanks=2)
|
1330
|
+
|
1331
|
+
#生成随机数睡眠,试图防止被反爬虫,不知是否管用!
|
1332
|
+
random_int=random.randint(1,max_sleep)
|
1333
|
+
time.sleep(random_int)
|
1326
1334
|
|
1327
1335
|
#num=list(set(list(df['ticker'])))
|
1328
1336
|
if len(fail_list) > 0:
|
siat/security_price2.py
CHANGED
@@ -231,6 +231,17 @@ if __name__=='__main__':
|
|
231
231
|
source='auto'
|
232
232
|
fill=True
|
233
233
|
|
234
|
+
#测试复权价
|
235
|
+
ticker=['300750.SZ','300014.SZ']
|
236
|
+
fromdate="2023-4-20"
|
237
|
+
todate="2023-4-30"
|
238
|
+
ticker_type='fund'
|
239
|
+
|
240
|
+
adjust='qfq'
|
241
|
+
source='auto'
|
242
|
+
fill=False
|
243
|
+
|
244
|
+
|
234
245
|
prices,found=get_price_mticker(ticker,fromdate,todate,adjust,source,ticker_type,fill)
|
235
246
|
|
236
247
|
def get_price_mticker(ticker,fromdate,todate, \
|
siat/stock_technical.py
CHANGED
@@ -183,7 +183,10 @@ def calc_technical(df,start,end, \
|
|
183
183
|
CCI_days=14, \
|
184
184
|
WR_days=[10,6], \
|
185
185
|
ROC_day=12,ROC_madays=6, \
|
186
|
-
DMI_DIdays=14,DMI_ADXdays=6
|
186
|
+
DMI_DIdays=14,DMI_ADXdays=6, \
|
187
|
+
|
188
|
+
indicator='Close', \
|
189
|
+
more_details=False):
|
187
190
|
"""
|
188
191
|
功能:计算股票的技术分析指标
|
189
192
|
输入:df,四种股价Open/Close/High/Low,成交量Volume
|
@@ -191,7 +194,14 @@ def calc_technical(df,start,end, \
|
|
191
194
|
支持的指标:
|
192
195
|
RSI、OBV、MACD、 KDJ、 SAR、 VOL、 PSY、 ARBR、 CR、 EMV、
|
193
196
|
BOLL、 TRIX、 DMA、 BIAS、 CCI、 W%R、 ROC、 DMI
|
197
|
+
|
198
|
+
注意:indicator='Close'为不使用复权价,'Adj Close'为前复权价(需要指定source='yahoo')
|
194
199
|
"""
|
200
|
+
if indicator not in ['Close','Adj Close']:
|
201
|
+
print(" #Error(calc_technical): unsupported indicator",indicator)
|
202
|
+
print(" Supported indicator: Close, Adj Close")
|
203
|
+
|
204
|
+
return None
|
195
205
|
|
196
206
|
# 导入需要的包
|
197
207
|
try:
|
@@ -221,7 +231,8 @@ def calc_technical(df,start,end, \
|
|
221
231
|
if not isinstance(RSI_days,list):
|
222
232
|
RSI_days=[RSI_days]
|
223
233
|
for d in RSI_days:
|
224
|
-
df['rsi'+str(d)] = talib.RSI(df[
|
234
|
+
df['rsi'+str(d)] = talib.RSI(df[indicator], timeperiod=d)
|
235
|
+
#注意:rsi1没有意义
|
225
236
|
|
226
237
|
#=========== OBV:能量潮
|
227
238
|
"""
|
@@ -252,14 +263,15 @@ def calc_technical(df,start,end, \
|
|
252
263
|
因此,对于那些达到涨跌停板的股票,OBV指标也无法正常发挥作用。
|
253
264
|
|
254
265
|
"""
|
255
|
-
df['obv'] = talib.OBV(df[
|
266
|
+
df['obv'] = talib.OBV(df[indicator],df['Volume'])
|
256
267
|
|
257
268
|
if not isinstance(OBV_days,list):
|
258
269
|
OBV_days=[OBV_days]
|
259
270
|
for d in OBV_days:
|
260
271
|
df['obv_ma'+str(d)] = talib.MA(df['obv'],timeperiod=d)
|
261
|
-
|
262
|
-
|
272
|
+
|
273
|
+
if not more_details:
|
274
|
+
df.drop(columns = ['obv'],inplace=True)
|
263
275
|
|
264
276
|
#=========== MA: 简单、加权移动平均
|
265
277
|
"""
|
@@ -274,8 +286,8 @@ def calc_technical(df,start,end, \
|
|
274
286
|
MA_days=[MA_days]
|
275
287
|
|
276
288
|
for d in MA_days:
|
277
|
-
df['ma'+str(d)] = talib.MA(df[
|
278
|
-
df['ema'+str(d)] = talib.EMA(df[
|
289
|
+
df['ma'+str(d)] = talib.MA(df[indicator],timeperiod=d)
|
290
|
+
df['ema'+str(d)] = talib.EMA(df[indicator],timeperiod=d)
|
279
291
|
|
280
292
|
#=========== MACD:指数平滑异同平均线
|
281
293
|
"""
|
@@ -305,7 +317,7 @@ def calc_technical(df,start,end, \
|
|
305
317
|
3. MACD绿转红:MACD值由负变正,市场由空头转为多头。
|
306
318
|
4. MACD红转绿:MACD值由正变负,市场由多头转为空头。
|
307
319
|
"""
|
308
|
-
df['DIF'],df['DEA'],df['MACD']=talib.MACD(df[
|
320
|
+
df['DIF'],df['DEA'],df['MACD']=talib.MACD(df[indicator], \
|
309
321
|
fastperiod=MACD_fastperiod, \
|
310
322
|
slowperiod=MACD_slowperiod, \
|
311
323
|
signalperiod=MACD_signalperiod)
|
@@ -371,7 +383,7 @@ def calc_technical(df,start,end, \
|
|
371
383
|
PSY(N) = A/N × 100
|
372
384
|
说明:N为天数,A为在这N天之中股价上涨的天数
|
373
385
|
"""
|
374
|
-
df['ext_0'] = df[
|
386
|
+
df['ext_0'] = df[indicator]-df[indicator].shift(1)
|
375
387
|
df['ext_1'] = 0
|
376
388
|
df.loc[df['ext_0']>0,'ext_1'] = 1
|
377
389
|
|
@@ -435,7 +447,11 @@ def calc_technical(df,start,end, \
|
|
435
447
|
for d in CR_madays:
|
436
448
|
df['cr_ma'+str(d)] = talib.MA(df['cr'],timeperiod=d)
|
437
449
|
|
438
|
-
|
450
|
+
if more_details:
|
451
|
+
#保留cr
|
452
|
+
df.drop(columns = ['m_price','h_m','m_l','h_m_sum','m_l_sum'],inplace=True)
|
453
|
+
else:
|
454
|
+
df.drop(columns = ['m_price','h_m','m_l','h_m_sum','m_l_sum','cr'],inplace=True)
|
439
455
|
|
440
456
|
#=========== EMV: 简易波动指标
|
441
457
|
"""
|
@@ -492,7 +508,7 @@ def calc_technical(df,start,end, \
|
|
492
508
|
这条带状区的宽窄,随着股价波动幅度的大小而变化,股价涨跌幅度加大时,带状区变宽,
|
493
509
|
涨跌幅度狭小盘整时,带状区则变窄。
|
494
510
|
"""
|
495
|
-
df['upper'],df['mid'],df['lower'] = talib.BBANDS(df[
|
511
|
+
df['upper'],df['mid'],df['lower'] = talib.BBANDS(df[indicator], \
|
496
512
|
timeperiod=BULL_days, \
|
497
513
|
nbdevup=BULL_nbdevup,nbdevdn=BULL_nbdevdn,matype=BULL_matype)
|
498
514
|
|
@@ -500,14 +516,16 @@ def calc_technical(df,start,end, \
|
|
500
516
|
"""
|
501
517
|
|
502
518
|
"""
|
503
|
-
df['trix'] = talib.TRIX(df[
|
519
|
+
df['trix'] = talib.TRIX(df[indicator],timeperiod=TRIX_day)
|
504
520
|
|
505
521
|
if not isinstance(TRIX_madays,list):
|
506
522
|
TRIX_madays=[TRIX_madays]
|
507
523
|
for d in TRIX_madays:
|
508
524
|
df['trix_ma'+str(d)] = talib.MA(df['trix'],timeperiod=d)
|
509
|
-
|
510
|
-
|
525
|
+
|
526
|
+
if not more_details:
|
527
|
+
#不保留TRIX
|
528
|
+
df.drop(columns = ['trix'],inplace=True)
|
511
529
|
|
512
530
|
#=========== DMA: 平均线差
|
513
531
|
"""
|
@@ -521,14 +539,15 @@ def calc_technical(df,start,end, \
|
|
521
539
|
2)求DDD的10日移动平均数值
|
522
540
|
DMA(10) = DDD(10)÷10
|
523
541
|
"""
|
524
|
-
df['ma_shortperiod'] = talib.MA(df[
|
525
|
-
df['ma_longperiod'] = talib.MA(df[
|
542
|
+
df['ma_shortperiod'] = talib.MA(df[indicator],timeperiod=DMA_fastperiod)
|
543
|
+
df['ma_longperiod'] = talib.MA(df[indicator],timeperiod=DMA_slowperiod)
|
526
544
|
df['ddd'] = df['ma_shortperiod'] - df['ma_longperiod']
|
527
545
|
|
528
546
|
if not isinstance(DMA_madays,list):
|
529
547
|
DMA_madays=[DMA_madays]
|
530
548
|
for d in DMA_madays:
|
531
549
|
df['dma'+str(d)] = talib.MA(df['ddd'],timeperiod=d)
|
550
|
+
#注意:dma1似乎没有意义
|
532
551
|
|
533
552
|
df.drop(columns = ['ma_shortperiod','ma_longperiod','ddd'],inplace=True)
|
534
553
|
|
@@ -544,8 +563,8 @@ def calc_technical(df,start,end, \
|
|
544
563
|
if not isinstance(BIAS_days,list):
|
545
564
|
BIAS_days=[BIAS_days]
|
546
565
|
for d in BIAS_days:
|
547
|
-
df['ma'] = talib.MA(df[
|
548
|
-
df['bias'+str(d)] = ((df[
|
566
|
+
df['ma'] = talib.MA(df[indicator],timeperiod=d)
|
567
|
+
df['bias'+str(d)] = ((df[indicator]-df['ma'])/df['ma'])*100
|
549
568
|
|
550
569
|
df.drop(columns = ['ma'],inplace=True)
|
551
570
|
|
@@ -559,7 +578,7 @@ def calc_technical(df,start,end, \
|
|
559
578
|
CCI_days=[CCI_days]
|
560
579
|
for d in CCI_days:
|
561
580
|
df['cci'+str(d)] = talib.CCI(df['High'],df['Low'],df['Close'],timeperiod=d)
|
562
|
-
|
581
|
+
|
563
582
|
#=========== W%R: 威廉指标
|
564
583
|
"""
|
565
584
|
N日W%R = [(Hn-Ct)/(Hn-Ln)]*100
|
@@ -593,14 +612,17 @@ def calc_technical(df,start,end, \
|
|
593
612
|
ROCMA = ROC的M日数值之和÷M
|
594
613
|
说明:M一般取值为6日
|
595
614
|
"""
|
596
|
-
df['roc'] = talib.ROC(df[
|
615
|
+
df['roc'] = talib.ROC(df[indicator],timeperiod=ROC_day)
|
597
616
|
|
598
617
|
if not isinstance(ROC_madays,list):
|
599
618
|
ROC_madays=[ROC_madays]
|
600
619
|
for d in ROC_madays:
|
601
620
|
df['roc_ma'+str(d)] = talib.MA(df['roc'],timeperiod=d)
|
621
|
+
|
622
|
+
if not more_details:
|
623
|
+
#不保留roc
|
624
|
+
df.drop(columns = ['roc'],inplace=True)
|
602
625
|
|
603
|
-
df.drop(columns = ['roc'],inplace=True)
|
604
626
|
#=========== DMI: 趋向指标
|
605
627
|
"""
|
606
628
|
|
@@ -657,7 +679,7 @@ def security_MACD(ticker,start='default',end='default', \
|
|
657
679
|
MACD_fastperiod=12,MACD_slowperiod=26,MACD_signalperiod=9, \
|
658
680
|
resample_freq='6H',smooth=True,linewidth=1.5, \
|
659
681
|
loc1='lower left',loc2='lower right', \
|
660
|
-
graph=['ALL'],printout=True,ticker_type='auto'):
|
682
|
+
graph=['ALL'],printout=True,ticker_type='auto',source='auto'):
|
661
683
|
"""
|
662
684
|
套壳函数:可用于股票、交易所债券、交易所基金、部分期货期权(限美股)
|
663
685
|
"""
|
@@ -667,7 +689,7 @@ def security_MACD(ticker,start='default',end='default', \
|
|
667
689
|
MACD_signalperiod=MACD_signalperiod, \
|
668
690
|
resample_freq=resample_freq,smooth=smooth,linewidth=linewidth, \
|
669
691
|
loc1=loc1,loc2=loc2, \
|
670
|
-
graph=graph,printout=printout,ticker_type=ticker_type)
|
692
|
+
graph=graph,printout=printout,ticker_type=ticker_type,source=source)
|
671
693
|
return df
|
672
694
|
|
673
695
|
|
@@ -676,7 +698,7 @@ def stock_MACD(ticker,start='default',end='default', \
|
|
676
698
|
MACD_fastperiod=12,MACD_slowperiod=26,MACD_signalperiod=9, \
|
677
699
|
resample_freq='H',smooth=True,linewidth=1.5, \
|
678
700
|
loc1='lower left',loc2='lower right', \
|
679
|
-
graph=['ALL'],printout=True,ticker_type='auto'):
|
701
|
+
graph=['ALL'],printout=True,ticker_type='auto',source='auto'):
|
680
702
|
"""
|
681
703
|
功能:计算股票的技术分析指标MACD
|
682
704
|
输入:df,四种股价Open/Close/High/Low,成交量Volume
|
@@ -721,7 +743,7 @@ def stock_MACD(ticker,start='default',end='default', \
|
|
721
743
|
start1=date_adjust(start,adjust=-max_days * 3)
|
722
744
|
|
723
745
|
#df=get_price(ticker,start1,end)
|
724
|
-
df,found=get_price_1ticker_mixed(ticker=ticker,fromdate=start1,todate=end,ticker_type=ticker_type)
|
746
|
+
df,found=get_price_1ticker_mixed(ticker=ticker,fromdate=start1,todate=end,ticker_type=ticker_type,source=source)
|
725
747
|
if df is None:
|
726
748
|
print(" #Error(stock_MACD): no info found for",ticker,"from",start,"to",end)
|
727
749
|
return None
|
@@ -1028,7 +1050,7 @@ def security_RSI(ticker,start='default',end='default', \
|
|
1028
1050
|
RSI_days=[6,12,24],RSI_lines=[20,50,80], \
|
1029
1051
|
resample_freq='6H',smooth=True,linewidth=1.5, \
|
1030
1052
|
loc1='lower left',loc2='lower right', \
|
1031
|
-
graph=['ALL'],printout=True,ticker_type='auto'):
|
1053
|
+
graph=['ALL'],printout=True,ticker_type='auto',source='auto'):
|
1032
1054
|
"""
|
1033
1055
|
套壳函数,除了股票,还可用于交易所债券和交易所基金(如ETF和REITS)
|
1034
1056
|
"""
|
@@ -1036,7 +1058,7 @@ def security_RSI(ticker,start='default',end='default', \
|
|
1036
1058
|
RSI_days=RSI_days,RSI_lines=RSI_lines, \
|
1037
1059
|
resample_freq=resample_freq,smooth=smooth,linewidth=linewidth, \
|
1038
1060
|
loc1=loc1,loc2=loc2, \
|
1039
|
-
graph=graph,printout=printout,ticker_type=ticker_type)
|
1061
|
+
graph=graph,printout=printout,ticker_type=ticker_type,source=source)
|
1040
1062
|
return df
|
1041
1063
|
|
1042
1064
|
|
@@ -1044,7 +1066,7 @@ def stock_RSI(ticker,start='default',end='default', \
|
|
1044
1066
|
RSI_days=[6,12,24],RSI_lines=[20,50,80], \
|
1045
1067
|
resample_freq='H',smooth=True,linewidth=1.5, \
|
1046
1068
|
loc1='lower left',loc2='lower right', \
|
1047
|
-
graph=['ALL'],printout=True,ticker_type='auto'):
|
1069
|
+
graph=['ALL'],printout=True,ticker_type='auto',source='auto'):
|
1048
1070
|
"""
|
1049
1071
|
功能:计算股票的技术分析指标RSI
|
1050
1072
|
输入:df,四种股价Open/Close/High/Low,成交量Volume
|
@@ -1089,7 +1111,7 @@ def stock_RSI(ticker,start='default',end='default', \
|
|
1089
1111
|
start1=date_adjust(start,adjust=-max_days * 3)
|
1090
1112
|
|
1091
1113
|
#df=get_price(ticker,start1,end)
|
1092
|
-
df,found=get_price_1ticker_mixed(ticker=ticker,fromdate=start1,todate=end,ticker_type=ticker_type)
|
1114
|
+
df,found=get_price_1ticker_mixed(ticker=ticker,fromdate=start1,todate=end,ticker_type=ticker_type,source=source)
|
1093
1115
|
if df is None:
|
1094
1116
|
print(" #Error(stock_RSI): no info found for",ticker,"from",start,"to",end)
|
1095
1117
|
return None
|
@@ -1269,7 +1291,7 @@ def security_KDJ(ticker,start='default',end='default', \
|
|
1269
1291
|
KDJ_days=[9,3,3],matypes=[0,0],KDJ_lines=[20,50,80], \
|
1270
1292
|
resample_freq='6H',smooth=True,linewidth=1.5, \
|
1271
1293
|
loc1='lower left',loc2='lower right', \
|
1272
|
-
graph=['ALL'],printout=True,ticker_type='auto'):
|
1294
|
+
graph=['ALL'],printout=True,ticker_type='auto',source='auto'):
|
1273
1295
|
"""
|
1274
1296
|
套壳函数
|
1275
1297
|
"""
|
@@ -1277,7 +1299,7 @@ def security_KDJ(ticker,start='default',end='default', \
|
|
1277
1299
|
KDJ_days=KDJ_days,matypes=matypes,KDJ_lines=KDJ_lines, \
|
1278
1300
|
resample_freq=resample_freq,smooth=smooth,linewidth=linewidth, \
|
1279
1301
|
loc1=loc1,loc2=loc2, \
|
1280
|
-
graph=graph,printout=printout,ticker_type=ticker_type)
|
1302
|
+
graph=graph,printout=printout,ticker_type=ticker_type,source=source)
|
1281
1303
|
return df
|
1282
1304
|
|
1283
1305
|
|
@@ -1285,7 +1307,7 @@ def stock_KDJ(ticker,start='default',end='default', \
|
|
1285
1307
|
KDJ_days=[9,3,3],matypes=[0,0],KDJ_lines=[20,50,80], \
|
1286
1308
|
resample_freq='H',smooth=True,linewidth=1.5, \
|
1287
1309
|
loc1='lower left',loc2='lower right', \
|
1288
|
-
graph=['ALL'],printout=True,ticker_type='auto'):
|
1310
|
+
graph=['ALL'],printout=True,ticker_type='auto',source='auto'):
|
1289
1311
|
"""
|
1290
1312
|
功能:计算股票的技术分析指标KDJ
|
1291
1313
|
输入:df,四种股价Open/Close/High/Low,成交量Volume
|
@@ -1330,7 +1352,7 @@ def stock_KDJ(ticker,start='default',end='default', \
|
|
1330
1352
|
start1=date_adjust(start,adjust=-max_days * 3)
|
1331
1353
|
|
1332
1354
|
#df=get_price(ticker,start1,end)
|
1333
|
-
df,found=get_price_1ticker_mixed(ticker=ticker,fromdate=start1,todate=end,ticker_type=ticker_type)
|
1355
|
+
df,found=get_price_1ticker_mixed(ticker=ticker,fromdate=start1,todate=end,ticker_type=ticker_type,source=source)
|
1334
1356
|
if df is None:
|
1335
1357
|
print(" #Error(stock_RSI): no info found for",ticker,"from",start,"to",end)
|
1336
1358
|
return None
|
@@ -1937,20 +1959,20 @@ if __name__ =="__main__":
|
|
1937
1959
|
def security_Bollinger(ticker,start='default',end='default',boll_days=20, \
|
1938
1960
|
graph=True,smooth=True,loc='best', \
|
1939
1961
|
date_range=False,date_freq=False,annotate=False, \
|
1940
|
-
|
1962
|
+
ticker_type='auto',source='auto'):
|
1941
1963
|
"""
|
1942
1964
|
套壳函数,为了与security_MACD/RSI/KDJ保持相似
|
1943
1965
|
"""
|
1944
1966
|
df=stock_Bollinger(ticker=ticker,start=start,end=end,boll_days=boll_days, \
|
1945
1967
|
graph=graph,smooth=smooth,loc=loc, \
|
1946
1968
|
date_range=date_range,date_freq=date_freq, \
|
1947
|
-
annotate=annotate,ticker_type=ticker_type)
|
1969
|
+
annotate=annotate,ticker_type=ticker_type,source=source)
|
1948
1970
|
return df
|
1949
1971
|
|
1950
1972
|
def stock_Bollinger(ticker,start='default',end='default',boll_days=20, \
|
1951
1973
|
graph=True,smooth=True,loc='best', \
|
1952
1974
|
date_range=False,date_freq=False,annotate=False, \
|
1953
|
-
mark_end=True,ticker_type='auto'):
|
1975
|
+
mark_end=True,ticker_type='auto',source='auto'):
|
1954
1976
|
"""
|
1955
1977
|
套壳函数,为了与stock_MACD/RSI/KDJ保持相似
|
1956
1978
|
"""
|
@@ -1978,14 +2000,14 @@ def stock_Bollinger(ticker,start='default',end='default',boll_days=20, \
|
|
1978
2000
|
df=security_bollinger(ticker=ticker,fromdate=start,todate=end,boll_days=boll_days, \
|
1979
2001
|
graph=graph,smooth=smooth,loc=loc, \
|
1980
2002
|
date_range=date_range,date_freq=date_freq,annotate=annotate, \
|
1981
|
-
mark_end=mark_end,ticker_type=ticker_type)
|
2003
|
+
mark_end=mark_end,ticker_type=ticker_type,source=source)
|
1982
2004
|
return df
|
1983
2005
|
|
1984
2006
|
|
1985
2007
|
def security_bollinger(ticker,fromdate,todate,boll_days=20, \
|
1986
2008
|
graph=True,smooth=True,loc='best', \
|
1987
2009
|
date_range=False,date_freq=False,annotate=False, \
|
1988
|
-
mark_end=True,ticker_type='auto'):
|
2010
|
+
mark_end=True,ticker_type='auto',source='auto'):
|
1989
2011
|
"""
|
1990
2012
|
功能:单个证券,绘制布林带
|
1991
2013
|
date_range=False:指定开始结束日期绘图
|
@@ -2004,7 +2026,7 @@ def security_bollinger(ticker,fromdate,todate,boll_days=20, \
|
|
2004
2026
|
try:
|
2005
2027
|
#pricedf=get_price(ticker,fromdate1,todate)
|
2006
2028
|
pricedf,found=get_price_1ticker_mixed(ticker=ticker,fromdate=fromdate1, \
|
2007
|
-
todate=todate,ticker_type=ticker_type)
|
2029
|
+
todate=todate,ticker_type=ticker_type,source=source)
|
2008
2030
|
except:
|
2009
2031
|
print(" #Error(security_bollinger): price info not found for",ticker)
|
2010
2032
|
return None
|
@@ -2253,10 +2275,18 @@ def security_technical(ticker,start='default',end='default', \
|
|
2253
2275
|
graph=['ALL'],printout=False, \
|
2254
2276
|
date_range=False,date_freq=False,annotate=False, \
|
2255
2277
|
technical=['MACD'],indicator='Close', \
|
2256
|
-
ticker_type='auto'):
|
2278
|
+
ticker_type='auto',source='auto'):
|
2257
2279
|
|
2258
2280
|
"""
|
2259
|
-
|
2281
|
+
功能:技术分析中的MACD/RSI/KDJ/布林带,支持教学演示,支持参数调节。
|
2282
|
+
支持的产品:全球股票,债券(限中国内地的上市债券),基金(支持中国和美国的上市基金)。
|
2283
|
+
ticker:证券代码
|
2284
|
+
start/end:起止日期。支持简洁方式,仅需使用start指定近期的期间长度。
|
2285
|
+
简洁方式:mrw(近1周),l2w(近2周),l3w(近3周),mrm(近1个月),l2m(近2个月),
|
2286
|
+
mrq(近3个月),mrh(近6个月),mry(近1年),l2y(近2年),l3y(近3年),
|
2287
|
+
l5y(近5年),l8y(近8年),l10y(近10年),l20y(近20年),l30y(近30年),ytd(今年以来)
|
2288
|
+
|
2289
|
+
其他说明:套壳函数security_MACD/RSI/KDJ/Bollinger
|
2260
2290
|
"""
|
2261
2291
|
|
2262
2292
|
# 检查日期:如有错误自动更正
|
@@ -2304,27 +2334,27 @@ def security_technical(ticker,start='default',end='default', \
|
|
2304
2334
|
MACD_fastperiod=MACD_fastperiod,MACD_slowperiod=MACD_slowperiod,MACD_signalperiod=MACD_signalperiod, \
|
2305
2335
|
resample_freq=resample_freq,smooth=smooth,linewidth=linewidth, \
|
2306
2336
|
loc1=loc1,loc2=loc2, \
|
2307
|
-
graph=graph1,printout=printout,ticker_type=ticker_type)
|
2337
|
+
graph=graph1,printout=printout,ticker_type=ticker_type,source=source)
|
2308
2338
|
|
2309
2339
|
if 'RSI' in technical1:
|
2310
2340
|
df=security_RSI(ticker=ticker,start=fromdate,end=todate, \
|
2311
2341
|
RSI_days=RSI_days,RSI_lines=RSI_lines, \
|
2312
2342
|
resample_freq=resample_freq,smooth=smooth,linewidth=linewidth, \
|
2313
2343
|
loc1=loc1,loc2=loc2, \
|
2314
|
-
graph=graph1,printout=printout,ticker_type=ticker_type)
|
2344
|
+
graph=graph1,printout=printout,ticker_type=ticker_type,source=source)
|
2315
2345
|
|
2316
2346
|
if 'KDJ' in technical1:
|
2317
2347
|
df=security_KDJ(ticker=ticker,start=fromdate,end=todate, \
|
2318
2348
|
KDJ_days=KDJ_days,matypes=matypes,KDJ_lines=KDJ_lines, \
|
2319
2349
|
resample_freq=resample_freq,smooth=smooth,linewidth=linewidth, \
|
2320
2350
|
loc1=loc1,loc2=loc2, \
|
2321
|
-
graph=graph1,printout=printout,ticker_type=ticker_type)
|
2351
|
+
graph=graph1,printout=printout,ticker_type=ticker_type,source=source)
|
2322
2352
|
|
2323
2353
|
if 'Bollinger' in technical1 and 'Close' in indicator1:
|
2324
2354
|
df=security_Bollinger(ticker=ticker,start=fromdate,end=todate,boll_days=boll_days, \
|
2325
2355
|
graph=True,smooth=smooth,loc=loc1, \
|
2326
2356
|
date_range=date_range,date_freq=date_freq,annotate=annotate, \
|
2327
|
-
ticker_type=ticker_type)
|
2357
|
+
ticker_type=ticker_type,source=source)
|
2328
2358
|
|
2329
2359
|
"""
|
2330
2360
|
if 'Bollinger' in technical1 and 'MV' in indicator1:
|
@@ -2449,12 +2479,13 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2449
2479
|
technical=['MACD'],indicator='Close', \
|
2450
2480
|
graph=['ALL'],printout=False, \
|
2451
2481
|
loc1='best',loc2='best', \
|
2452
|
-
ticker_type='auto', \
|
2482
|
+
ticker_type='auto',source='auto', \
|
2453
2483
|
|
2454
2484
|
attention_values=[0,30,50,80], \
|
2455
|
-
facecolor='papayawhip',price_line_color='red'
|
2485
|
+
facecolor='papayawhip',price_line_color='red', \
|
2486
|
+
|
2487
|
+
more_details=False):
|
2456
2488
|
"""
|
2457
|
-
|
2458
2489
|
功能:计算和绘制证券技术分析指标的简易图,仅供进一步探索使用,仅用于单个证券(股债基)
|
2459
2490
|
|
2460
2491
|
支持的探索指标:仅供探索使用
|
@@ -2500,7 +2531,7 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2500
2531
|
#抓取抓取价格数据
|
2501
2532
|
fromdate1=date_adjust(fromdate,adjust=-ahead_days)
|
2502
2533
|
price,found=get_price_1ticker_mixed(ticker=ticker,fromdate=fromdate1, \
|
2503
|
-
todate=todate,ticker_type=ticker_type,fill=False)
|
2534
|
+
todate=todate,ticker_type=ticker_type,fill=False,source=source)
|
2504
2535
|
|
2505
2536
|
if found not in ['Found']:
|
2506
2537
|
print(" #Warning(security_technical2): no prices found for",ticker,'as type',ticker_type)
|
@@ -2542,7 +2573,10 @@ def security_technical2(ticker,start='default',end='default', \
|
|
2542
2573
|
CCI_days=CCI_days, \
|
2543
2574
|
WR_days=WR_days, \
|
2544
2575
|
ROC_day=ROC_day,ROC_madays=ROC_madays, \
|
2545
|
-
DMI_DIdays=DMI_DIdays,DMI_ADXdays=DMI_ADXdays
|
2576
|
+
DMI_DIdays=DMI_DIdays,DMI_ADXdays=DMI_ADXdays, \
|
2577
|
+
|
2578
|
+
indicator=indicator, \
|
2579
|
+
more_details=more_details)
|
2546
2580
|
|
2547
2581
|
#技术指标的绘图线
|
2548
2582
|
tech_line_default={'RSI':['rsi'],
|