请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  量化平台 帖子:3365867 新帖:0

当价格触及布林带上轨后,是突破继续涨?还是回落跌回来?

执着技术派发表于:5 月 10 日 07:35回复(1)

布林带指数择时效果探究

  • 当价格触及布林带上轨后,是突破继续涨?还是回落跌回来?
  • 本文将统计沪深300指数历史上价格触及布林带上轨的情况,做出之后价格走势图,对布林带指数择时效果进行探究。同时也统计了相应的价格触及布林带下轨的情况。

详情见研究

布林带指数择时效果探究¶

  • 当价格触及布林带上轨后,是突破继续涨?还是回落跌回来?本文将统计沪深300指数历史上价格触及布林带上轨的情况,做出之后价格走势图,对布林带指数择时效果进行探究。同时也统计了相应的价格触及布林带下轨的情况。

没听过布林带?¶

  • 百度百科对布林带的介绍
  • 个人解释下,经典的布林带含义中包括3条线,中线,上轨(上轨线),下轨(下轨线)。
    • 中线是就是n日移动均线,每日的值相当于过去n天股价的平均值,就是炒股软件中常见的均线。
    • 上轨是中线加k倍标准差,每日的值相当于过去n天股价的平均值加过去n天股价的k倍标准差。
    • 下轨是中线减k倍标准差,每日的值相当于过去n天股价的平均值减过去n天股价的k倍标准差。
    • 本文中n选择为20,k为2

你支持下面关于布林带择时的哪个说法?¶

  • 一者认为,中线是股价中枢,股价应大概率在上轨与下轨之间波动,因此,当价格触及上轨或下轨时,股价应有回归中线的趋势。即按此说法,当价格触及布林带上轨后,应回落跌回来。
  • 一者认为,当价格触及上轨或下轨时,说明股价突破原本的运动通道,股价中枢应视为异变,股价应继续保持原有趋势突破上轨或下轨。即按此说法,当价格触及布林带上轨后,应突破继续涨。

开始尝试用数据探究此问题¶

# 选择起止时间
start='2008-01-01'
end='2018-12-01'

# 选择指数
index=['000300.XSHG']

# 选择统计事件触发后多久的走势
later_days=15

导入库和函数¶

from jqdata import *
import jqdata
import pandas as pd
import datetime 

# 全局变量
# 交易日期列表
all_trade_days=[i.strftime('%Y-%m-%d') for i in list(get_all_trade_days())]
# 作图尺寸
figsize=(16,8)

# 判断是否触及布林线上轨或下轨
def boll_filter(stk_list,date,up_down='down',ix=-20,k_std=2,field='close',fqy='1d'):
    df=get_price(security=stk_list,count=-ix,end_date=date,fields=[field],frequency=fqy)[field,:,:].iloc[1:,:]
    df=pd.DataFrame({'now':df.loc[date],'mean':df.mean(),'std':df.std()})
    df['up']=df['mean']+k_std*df['std']
    df['down']=df['mean']-k_std*df['std']
    if up_down=='down':
        rlt=list(df[df['now']<=df['down']].index)
    elif up_down=='up':
        rlt=list(df[df['now']>=df['up']].index)
    else:
        print('wrong up_down')
    return rlt

# 统计事件触发后股价变化
def after_story(totalLog,start,end,ahead_days=0,later_days=15,baseIndex=''):
    # 选择要统计触发事件后多少天的股价变化情况
    n_limt=later_days


    # 获取起止时间内的交易日
    days=[i.strftime('%Y-%m-%d') for i in list(get_trade_days(start,end))]

    # 选择基准指数
    # 如果选择了基准指数则统计的股票涨跌幅是减去了该指数涨跌幅的相对涨跌幅
    # 如果想看单纯股票涨跌幅,可以赋值为空字符串''
    baseIndex=''

    # 把事件数据赋值给stk
    stk=totalLog
    # 初始化存储统计结果的变量
    totalSum=pd.DataFrame()

    # 循环触发了事件的每一天
    for i in stk.keys():
        if i<start or i>end:
            continue
    #     print(i)
        # 获得当天触发事件的股票
        stk_list=stk[i]
        # 如果选择了基准指数
        if baseIndex!='':
            # 获取当天触发事件后股票相对基准指数的涨跌幅
            t=get_pct_change_accum([baseIndex]+stk_list,n_limt,all_trade_days[all_trade_days.index(i)-ahead_days],fqy='1d')
            t.reset_index(drop=True,inplace=True)
            t=t.sub(t[baseIndex],axis=0)
            del t[baseIndex]
        # 如果没选基准指数
        else:
            # 获取当天触发事件后股票的涨跌幅
            t=get_pct_change_accum(stk_list,n_limt,all_trade_days[all_trade_days.index(i)-ahead_days],fqy='1d')
            t.reset_index(drop=True,inplace=True)
            t.columns=[i]*len(t.columns)
#             t.columns=[i[:4]]*len(t.columns)
        # 记录当天触发事件后股票的涨跌幅,存储在totalSum
        totalSum=pd.concat([totalSum,t],axis=1)
    # 展示统计结果
    # 格式为dataframe,字段为股票代码,索引为事件后第几天,当天为0,值为涨跌幅
    # 设置作图大小
    
    # 生成事件触发后股价平均涨跌幅走势图
    totalSum.T.mean().plot(figsize=figsize).grid()
#     totalSum.T.mean().pct_change().plot(figsize=figsize).grid()
    print(len(totalSum.columns))
    return totalSum

# 获取相对baseday的ix个交易日量价累计涨跌幅
def get_pct_change_accum(scu,ix,date,fqy='1d',field='close'):
    if ix<=0:
        df=get_price(security=scu,count=-ix+2,end_date=date,fields=[field],frequency=fqy)[field,:,:].iloc[1:,:]

    else:
        df=get_price(security=scu,count=ix+2,end_date=all_trade_days[all_trade_days.index(date)+ix],fields=[field],frequency=fqy)[field,:,:].iloc[1:,:]
    if df.index.empty==True:
        df=df.T
        df['0000-00-00']=[]
        df=df.T
        
    return df/df.iloc[0]

找出历史上触及布林线上轨的情况¶

# 初始化存储统计结果的变量
totalLog=dict()
# 获取起止时间内的交易日
days=[i.strftime('%Y-%m-%d') for i in list(get_trade_days(start,end))]


# 循环统计起止时间内的交易日
for baseDay in days:

    stk_list=index
    date=baseDay
    
    
    stk_list=boll_filter(stk_list=stk_list,date=date,up_down='up')

    # 记录触发事件的股票,存在totalLog中
    if stk_list!=[]:
            totalLog[baseDay]=stk_list
# 对于连续的触发只保留第一次
t=totalLog.keys()
t.sort(reverse = True)
for i in t:
    w=all_trade_days[all_trade_days.index(i)-1]
    if w in t:
        del totalLog[i]
totalLog   
{'2008-11-14': ['000300.XSHG'],
 '2008-12-08': ['000300.XSHG'],
 '2009-02-04': ['000300.XSHG'],
 '2009-02-06': ['000300.XSHG'],
 '2009-03-23': ['000300.XSHG'],
 '2009-06-01': ['000300.XSHG'],
 '2009-06-03': ['000300.XSHG'],
 '2009-07-02': ['000300.XSHG'],
 '2009-11-16': ['000300.XSHG'],
 '2010-03-01': ['000300.XSHG'],
 '2010-03-29': ['000300.XSHG'],
 '2010-10-08': ['000300.XSHG'],
 '2010-12-13': ['000300.XSHG'],
 '2011-02-14': ['000300.XSHG'],
 '2011-02-16': ['000300.XSHG'],
 '2011-04-08': ['000300.XSHG'],
 '2011-07-04': ['000300.XSHG'],
 '2012-01-10': ['000300.XSHG'],
 '2012-02-22': ['000300.XSHG'],
 '2012-02-24': ['000300.XSHG'],
 '2012-12-10': ['000300.XSHG'],
 '2012-12-14': ['000300.XSHG'],
 '2013-01-28': ['000300.XSHG'],
 '2013-02-01': ['000300.XSHG'],
 '2013-05-17': ['000300.XSHG'],
 '2013-08-12': ['000300.XSHG'],
 '2013-09-09': ['000300.XSHG'],
 '2014-02-10': ['000300.XSHG'],
 '2014-04-08': ['000300.XSHG'],
 '2014-06-16': ['000300.XSHG'],
 '2014-07-24': ['000300.XSHG'],
 '2014-09-03': ['000300.XSHG'],
 '2014-10-08': ['000300.XSHG'],
 '2014-11-10': ['000300.XSHG'],
 '2014-11-24': ['000300.XSHG'],
 '2015-01-05': ['000300.XSHG'],
 '2015-03-16': ['000300.XSHG'],
 '2015-05-22': ['000300.XSHG'],
 '2015-10-12': ['000300.XSHG'],
 '2015-10-15': ['000300.XSHG'],
 '2015-11-05': ['000300.XSHG'],
 '2015-12-21': ['000300.XSHG'],
 '2016-03-21': ['000300.XSHG'],
 '2016-06-01': ['000300.XSHG'],
 '2016-07-04': ['000300.XSHG'],
 '2016-07-12': ['000300.XSHG'],
 '2016-08-12': ['000300.XSHG'],
 '2016-10-24': ['000300.XSHG'],
 '2016-11-11': ['000300.XSHG'],
 '2016-11-25': ['000300.XSHG'],
 '2016-11-29': ['000300.XSHG'],
 '2017-02-10': ['000300.XSHG'],
 '2017-02-20': ['000300.XSHG'],
 '2017-03-24': ['000300.XSHG'],
 '2017-04-05': ['000300.XSHG'],
 '2017-05-25': ['000300.XSHG'],
 '2017-06-08': ['000300.XSHG'],
 '2017-06-26': ['000300.XSHG'],
 '2017-07-19': ['000300.XSHG'],
 '2017-08-25': ['000300.XSHG'],
 '2017-10-09': ['000300.XSHG'],
 '2017-11-10': ['000300.XSHG'],
 '2017-11-21': ['000300.XSHG'],
 '2018-01-03': ['000300.XSHG'],
 '2018-07-24': ['000300.XSHG']}

触发后历史平均走势图¶

  • 如图可见,历史总体平均来看,价格触及布林线上轨后有上升趋势。
# 统计之后的平均走势
w=after_story(totalLog,start,end,later_days=later_days)
65

分年度,触发后历史平均走势图¶

  • 如图可见,分年度看,并非每年价格触及布林线上轨后都有上升趋势,说明此趋势仅供参考还可以,单独拿来判断后续走势不确定性很大。
# 分年度,统计之后的平均走势
t=w
f=lambda x : x[:4]
t.columns=map(f,t.columns)
t.T.groupby(t.columns).mean()
t.T.groupby(t.columns).mean().T.plot(figsize=figsize).grid()

找出历史上触及布林线下轨的情况¶

# 初始化存储统计结果的变量
totalLog=dict()
# 获取起止时间内的交易日
days=[i.strftime('%Y-%m-%d') for i in list(get_trade_days(start,end))]


# 循环统计起止时间内的交易日
for baseDay in days:
    
    stk_list=index
    date=baseDay
    
    
    stk_list=boll_filter(stk_list=stk_list,date=date,up_down='down')

    # 记录触发事件的股票,存在totalLog中
    if stk_list!=[]:
            totalLog[baseDay]=stk_list
# 对于连续的触发只保留第一次
t=totalLog.keys()
t.sort(reverse = True)
for i in t:
    w=all_trade_days[all_trade_days.index(i)-1]
    if w in t:
        del totalLog[i]
totalLog
{'2008-01-22': ['000300.XSHG'],
 '2008-03-13': ['000300.XSHG'],
 '2008-03-17': ['000300.XSHG'],
 '2008-04-18': ['000300.XSHG'],
 '2008-05-26': ['000300.XSHG'],
 '2008-06-10': ['000300.XSHG'],
 '2008-06-17': ['000300.XSHG'],
 '2008-08-08': ['000300.XSHG'],
 '2008-09-05': ['000300.XSHG'],
 '2008-09-17': ['000300.XSHG'],
 '2009-08-12': ['000300.XSHG'],
 '2009-08-14': ['000300.XSHG'],
 '2009-12-18': ['000300.XSHG'],
 '2009-12-22': ['000300.XSHG'],
 '2010-01-22': ['000300.XSHG'],
 '2010-04-19': ['000300.XSHG'],
 '2010-05-07': ['000300.XSHG'],
 '2010-06-29': ['000300.XSHG'],
 '2010-11-12': ['000300.XSHG'],
 '2010-11-16': ['000300.XSHG'],
 '2010-12-28': ['000300.XSHG'],
 '2011-01-17': ['000300.XSHG'],
 '2011-01-20': ['000300.XSHG'],
 '2011-04-28': ['000300.XSHG'],
 '2011-05-04': ['000300.XSHG'],
 '2011-05-23': ['000300.XSHG'],
 '2011-06-17': ['000300.XSHG'],
 '2011-07-25': ['000300.XSHG'],
 '2011-08-08': ['000300.XSHG'],
 '2011-09-05': ['000300.XSHG'],
 '2011-09-26': ['000300.XSHG'],
 '2011-11-18': ['000300.XSHG'],
 '2011-12-13': ['000300.XSHG'],
 '2012-03-28': ['000300.XSHG'],
 '2012-06-25': ['000300.XSHG'],
 '2012-06-28': ['000300.XSHG'],
 '2012-07-23': ['000300.XSHG'],
 '2012-08-27': ['000300.XSHG'],
 '2012-11-16': ['000300.XSHG'],
 '2013-06-13': ['000300.XSHG'],
 '2013-06-20': ['000300.XSHG'],
 '2013-06-24': ['000300.XSHG'],
 '2013-10-25': ['000300.XSHG'],
 '2013-11-08': ['000300.XSHG'],
 '2013-12-19': ['000300.XSHG'],
 '2014-02-25': ['000300.XSHG'],
 '2014-08-28': ['000300.XSHG'],
 '2014-10-27': ['000300.XSHG'],
 '2015-06-19': ['000300.XSHG'],
 '2015-06-26': ['000300.XSHG'],
 '2015-08-21': ['000300.XSHG'],
 '2015-11-30': ['000300.XSHG'],
 '2016-01-04': ['000300.XSHG'],
 '2016-01-07': ['000300.XSHG'],
 '2016-01-11': ['000300.XSHG'],
 '2016-05-09': ['000300.XSHG'],
 '2016-09-12': ['000300.XSHG'],
 '2016-12-15': ['000300.XSHG'],
 '2017-05-08': ['000300.XSHG'],
 '2017-08-11': ['000300.XSHG'],
 '2018-02-06': ['000300.XSHG'],
 '2018-03-23': ['000300.XSHG'],
 '2018-03-28': ['000300.XSHG'],
 '2018-05-30': ['000300.XSHG'],
 '2018-06-19': ['000300.XSHG'],
 '2018-06-27': ['000300.XSHG'],
 '2018-08-02': ['000300.XSHG']}

触发后历史平均走势图¶

  • 如图可见,历史总体平均来看,价格触及布林线下轨后有下跌趋势。
# 统计之后的平均走势
w=after_story(totalLog,start,end,later_days=later_days)
67

分年度,触发后历史平均走势图¶

  • 如图可见,分年度看,并非每年价格触及布林线下轨后都有下跌趋势,说明此趋势仅供参考还可以,单独拿来判断后续走势不确定性也是很大。
# 分年度,统计之后的平均走势
t=w
f=lambda x : x[:4]
t.columns=map(f,t.columns)
t.T.groupby(t.columns).mean()
t.T.groupby(t.columns).mean().T.plot(figsize=figsize).grid()

总结¶

  • 在本文布林带的定义下,对沪深300指数来说,当价格触及布林带上轨后,历史上平均来看突破继续涨的趋势比回落要显著。当价格触及布林带下轨后则突破继续跌的趋势比回升要显著。
  • 分年度的看,价格触及布林带上轨或下轨后的趋势并非年年相同,有较大不确定性。
  • 初步观察,虽然价格触及布林带上轨或下轨后的趋势并非年年相同,但似乎与当时市场的牛熊情况相关,结合此因素或许能提供判断的准确性。
 

全部回复

0/140

达人推荐

量化课程

    移动端课程