<span><span>def</span> <span>get_boll</span><span>(security, start_date=None, end_date=None, time_count=<span>10</span>)</span>:</span>
    hs_data=get_price(security,start_date=start_date,end_date=end_date,frequency=<span>'daily'</span>,fields=<span>None</span>,skip_paused=<span>False</span>,fq=<span>'pre'</span>)
    stock_data = get_price(securirty, end_date= end_date, frequency= <span>'daily'</span>, fields= <span>'close'</span>, skip_paused= <span>True</span>, fq= <span>'pre'</span>, count= (len(hs_data[<span>'close'</span>])+time_count<span>-1</span>))
    upper, middle, lower = talib.BBANDS(stock_data[<span>'close'</span>].values, timeperiod=time_count,nbdevup=<span>2</span>,nbdevdn=<span>2</span>,matype=<span>0</span>)
    stock_data = pd.DataFrame({<span>'upper'</span>: upper, <span>'middle'</span>: middle, <span>'lower'</span>: lower}, index= stock_data.index)
    stock_data = stock_data.dropna()
    stock_data[<span>'close'</span>] = hs_data[<span>'close'</span>]
    <span>return</span> stock_data

<span><span>def</span> <span>show_boll</span><span>(stock_data)</span>:</span>
    plt.figure(figsize=(<span>20</span>, <span>5</span>))
    plt.grid()
    plt.plot(stock_data[<span>'upper'</span>], <span>'-'</span>, color=<span>'r'</span>)
    plt.plot(stock_data[<span>'lower'</span>], <span>'-'</span>, color=<span>'r'</span>)
    plt.plot(stock_data[<span>'middle'</span>], <span>'-.'</span>, color=<span>'b'</span>)
    plt.show()

Boll指标研究

布林线指标,即BOLL指标,其英文全称是“Bollinger Bands”,布林线(BOLL)由约翰·布林先生创造,其利用统计原理,一般而言,股价的运动总是围绕某一价值中枢(如均线、成本线等)在一定的范围内变动,布林线指标正是在上述条件的基础上,引进了“股价信道”的概念,其认为股价信道的宽窄随着股价波动幅度的大小而变化,而且股价信道又具有变异性,它会随着股价的变化而自动调整,求出股价的标准差及其信赖区间,从而确定股价的波动范围及未来走势,利用波带显示股价的安全高低价位。

原理:

根据统计学中的标准差原理设计,股价的波动利用标准差方式来表达,配合均线做为中位线,从而变成了偏离情况的写照。

公式:

一、日BOLL指标的计算公式:

  • 中轨线=N日的移动平均线
  • 上轨线=中轨线+两倍的N日标准差
  • 下轨线=中轨线-两倍的N日标准差

二、日BOLL指标的计算过程:

(1)、计算MA

MA=N日内的收盘价之和÷N

(2)、计算标准差MD

MD=平方根N日的(C-MA)的两次方之和除以N

(3)、计算MB、UP、DN线、K倍

MB=(N-1)日的MA
UP=MB+K×MD
 DN=MB-K×MD

正常使用方法:

  • 当股价穿越上限压力线时,卖点信号;
  • 当股价穿越下限支撑线时,买点信号;

目的:

  • 寻找最优中轨参数:N
  • 寻找最优搭配参数:K

导入需要模块

<span>"""导入常用模块"""</span>
<span>import</span> numpy <span>as</span> np
<span>import</span> pandas <span>as</span> pd
<span>import</span> matplotlib.pyplot <span>as</span> plt
<span>import</span> datetime
<span>import</span> talib
<span>from</span> jqdata <span>import</span> *
<span>from</span> jqlib.technical_analysis <span>import</span> *
<span>from</span> environment <span>import</span> * <span># 导入大树工作室开发的回测模块</span>

沪深300价量展示Boll

<span>import</span> seaborn <span>as</span> sns
sns.set(font=<span>'serif'</span>)
securirty = <span>'000300.XSHG'</span>
Boll_data = []
HS_data = []
trade_date = get_trade_days(start_date= <span>'2018-9-01'</span>, end_date= <span>'2019-03-01'</span>)
time_count=<span>20</span>
HS_data = get_price(security=<span>'000300.XSHG'</span>, 
                  start_date=<span>'2018-9-01'</span>, 
                  end_date=<span>'2019-03-01'</span>, 
                  frequency=<span>'daily'</span>, 
                  fields=<span>None</span>, 
                  skip_paused=<span>False</span>, 
                  fq=<span>'pre'</span>)

stock_data = get_price(securirty, end_date= <span>'2019-03-01'</span> , frequency= <span>'daily'</span>, fields= <span>'close'</span>, skip_paused= <span>True</span>, fq= <span>'pre'</span>, count= (len(HS_data[<span>'close'</span>])+time_count<span>-1</span>))
upper, middle, lower = talib.BBANDS(stock_data[<span>'close'</span>].values, timeperiod=time_count,nbdevup=<span>2</span>,nbdevdn=<span>2</span>,matype=<span>0</span>)
stock_data = pd.DataFrame({<span>'upper'</span>: upper, <span>'middle'</span>: middle, <span>'lower'</span>: lower}, index= stock_data.index)
stock_data = stock_data.dropna()
stock_data[<span>'close'</span>] = HS_data[<span>'close'</span>]

plt.figure(figsize=(<span>20</span>, <span>5</span>))
plt.grid()
plt.plot(stock_data[<span>'close'</span>], <span>'-'</span>, color=<span>'g'</span>)
plt.plot(stock_data[<span>'upper'</span>], <span>'-'</span>, color=<span>'r'</span>)
plt.plot(stock_data[<span>'lower'</span>], <span>'-'</span>, color=<span>'r'</span>)
plt.plot(stock_data[<span>'middle'</span>], <span>'-.'</span>, color=<span>'b'</span>)
plt.title(<span>'沪深300指数与Boll通道图'</span>)
plt.legend([<span>'指数价格'</span>, <span>'Boll上轨'</span>, <span>'Boll中轨'</span>, <span>'Boll下轨'</span>], loc=<span>2</span>)
plt.show()

Img

上图展示沪深300指数与其Boll通道表现,图例的通道以及价格走势,明显可知,这是一种类价值回归,也与波动性有一定挂钩。对期货不陌生的投资者应该最为了解,因为在CTA部分策略中,最常使用这类的指标。综上所述,我们本次内容,就深入了解Boll指标,做进行布林带探索的[稀饭?哥伦布魏]!

Boll指标择时效应研究

Boll指标用法可谓五花八门,因为三线合一,不同的搭配有不同的口味,而且三线又可各自组合,使得使用起来更加多变。仔细思考,向上突破下轨,向上突破上轨,站于中轨,二次站于中轨等等,只要不脱轨,就很不错了。

本次研究的脉络为:

  • 择时交易择优参-常规择优
  • 择时交易择优参-轨道分化择优
  • 择时交易择优参-轨道综合

择时交易择优参

[稀饭?哥伦布魏]以简单方式带大家分享Boll。择时交易,方式非常容易理解,就是对Boll参数进行筛选,筛选的参数有三类,中轨均线参数,上下轨标准差倍数。

常规择优

展示常规情况下的中轨配置以及上下轨标准差2倍数,本次的稀饭会比较多清汤,但是会加点肉,因为最近猪瘟还是蛮严重的,所以严选最差猪肉!

  • 回测标的:沪深300指数。
  • 回测时间:2010年01月01日到2018年12月31日。
  • 初始资金:100000元。
  • 不考虑对冲成本,尽量投入全部资金。
    代码展示:
<span>"""初始化以下内容"""</span>
context = Context() <span># 账户对象</span>
order = Order(context) <span># 下单对象</span>
trade = Trade(context, order) <span># 回测对旬</span>
context.start_date = <span>'2010-01-01'</span>
context.end_date = <span>'2018-12-31'</span>
context.universe = [<span>'000300.XSHG'</span>]
context.base = <span>'000300.XSHG'</span>

<span>"""策略主体"""</span>
<span><span>def</span> <span>handle</span><span>(context, order)</span>:</span>
    stock = context.universe[<span>0</span>]
    time_count = <span>20</span>
    n = <span>2</span>
    m = <span>2</span>
    HS_da = get_price(security=stock, 
                      end_date= context.current_dt,
                      frequency= <span>'daily'</span>, 
                      fields= <span>None</span>, 
                      skip_paused= <span>False</span>, 
                      fq=<span>'pre'</span>,
                      count= <span>50</span>)
    stock_data = get_price(stock, end_date= context.current_dt , frequency= <span>'daily'</span>, fields= <span>'close'</span>, skip_paused= <span>True</span>, fq= <span>'pre'</span>, count= (len(HS_da[<span>'close'</span>])+time_count<span>-1</span>))
    upper, middle, lower = talib.BBANDS(stock_data[<span>'close'</span>].values, timeperiod=time_count,nbdevup=n,nbdevdn=m,matype=<span>0</span>)
    <span>if</span> lower[<span>-2</span>] &gt; HS_da[<span>'close'</span>][<span>-2</span>] <span>and</span> lower[<span>-1</span>] &lt; HS_da[<span>'close'</span>][<span>-1</span>]:
        <span>if</span> stock <span>in</span> context.position.keys():
            <span>return</span>
        order.buy(stock, HS_da[<span>'close'</span>][<span>-1</span>], context.cash // HS_da[<span>'close'</span>][<span>-1</span>])
    <span>elif</span> lower[<span>-1</span>] &gt; HS_da[<span>'close'</span>][<span>-1</span>] <span>or</span> upper[<span>-1</span>] &lt; HS_da[<span>'close'</span>][<span>-1</span>]:
        <span>if</span> stock <span>not</span> <span>in</span> context.position.keys():
            <span>return</span>
        order.sell(stock, HS_da[<span>'close'</span>][<span>-1</span>], context.position[stock][<span>'count'</span>])

<span>"""执行策略"""</span>
trade.trade(handle)

Img

从正常角度看,整个数据表现得不是很理想,猪肉的质量有点差,猪毛(回撤:0.4754)占面积略大,而且猪肉可食用部位(策略收益:-0.4332)也比较少。咱们还是用多参数来下锅吧。

  • 回测标的:沪深300指数。
  • 回测时间:2010年01月01日到2018年12月31日。
  • 初始资金:100000元。
  • 不考虑对冲成本,尽量投入全部资金。
  • Boll参数:[5, 10, 15, 20, 25, 30, 35, 40]
    代码展示:
trade_list = []
Boll_list = [<span>10</span>, <span>15</span>, <span>20</span>, <span>25</span>, <span>30</span>, <span>35</span>, <span>40</span>, <span>45</span>, <span>50</span>]
<span>for</span> _Boll <span>in</span> Boll_list:
    <span># 策略结构</span>
    context = Context()
    order = Order(context)
    trade = Trade(context, order)
    context.start_date = <span>'2010-01-01'</span>
    context.end_date = <span>'2018-12-31'</span>
    context.universe = [<span>'000300.XSHG'</span>]
    context.base = <span>'000300.XSHG'</span>

    <span>"""策略主体"""</span>
    <span><span>def</span> <span>handle</span><span>(context, order)</span>:</span>
        stock = context.universe[<span>0</span>]
        time_count = _Boll
        n = <span>2</span>
        m = <span>2</span>
        HS_da = get_price(security=stock, 
                          end_date= context.current_dt,
                          frequency= <span>'daily'</span>, 
                          fields= <span>None</span>, 
                          skip_paused= <span>False</span>, 
                          fq=<span>'pre'</span>,
                          count= <span>50</span>)
        stock_data = get_price(stock, end_date= context.current_dt , frequency= <span>'daily'</span>, fields= <span>'close'</span>, skip_paused= <span>True</span>, fq= <span>'pre'</span>, count= (len(HS_da[<span>'close'</span>])+time_count<span>-1</span>))
        upper, middle, lower = talib.BBANDS(stock_data[<span>'close'</span>].values, timeperiod=time_count,nbdevup=n,nbdevdn=m,matype=<span>0</span>)
        <span>if</span> lower[<span>-2</span>] &gt; HS_da[<span>'close'</span>][<span>-2</span>] <span>and</span> lower[<span>-1</span>] &lt; HS_da[<span>'close'</span>][<span>-1</span>]:
            <span>if</span> stock <span>in</span> context.position.keys():
                <span>return</span>
            order.buy(stock, HS_da[<span>'close'</span>][<span>-1</span>], context.cash // HS_da[<span>'close'</span>][<span>-1</span>])
        <span>elif</span> lower[<span>-1</span>] &gt; HS_da[<span>'close'</span>][<span>-1</span>] <span>or</span> upper[<span>-1</span>] &lt; HS_da[<span>'close'</span>][<span>-1</span>]:
            <span>if</span> stock <span>not</span> <span>in</span> context.position.keys():
                <span>return</span>
            order.sell(stock, HS_da[<span>'close'</span>][<span>-1</span>], context.position[stock][<span>'count'</span>])
    trade.trade(handle, <span>False</span>)
    trade_list.append(trade)
<span># 展示</span>
Trade.show_ratio_compare(<span>'Boll'</span>, Boll_list, trade_list, <span>3</span>, <span>3</span>)

Img
Img

虽然是猪肉,但是还是有好位置的,现在数据表出参数10,整个参数中唯一一个整收益的,还是蛮吃惊的,怎么会出现这样情况呢?因为Boll是类于波动率,进出场都和波动息息相关,只有波动和股价恰到好处,才是最合适的刷单或是价差空间,可谓一物降一物的感觉。

轨道分化择优

中轨参数已经得到相对于其他数据比较优秀的参数,接着就是上下轨的设置,烤猪肉要木叉子,基本两根为主,能够固定方向,把控肉质。吃个稀饭,还烤肉,也是不容易啊。

轨道分化择优-上轨

  • 回测标的:沪深300指数。
  • 回测时间:2010年01月01日到2018年12月31日。
  • 初始资金:100000元。
  • 不考虑对冲成本,尽量投入全部资金。
  • Boll参数:[5, 10, 15, 20, 25, 30, 35, 40]
  • n参数:[0.5, 1, 1.5, 2]
    代码展示:
_list = []
trade_list = []
Boll_list = [<span>10</span>, <span>15</span>, <span>20</span>, <span>25</span>, <span>30</span>, <span>35</span>, <span>40</span>, <span>45</span>, <span>50</span>]
Boll_list_n = [<span>0.5</span>, <span>1</span>, <span>1.5</span>, <span>2</span>]
<span>for</span> _Boll <span>in</span> Boll_list:
    <span>for</span> n_Boll <span>in</span> Boll_list_n:
        <span># 策略结构</span>
        context = Context()
        order = Order(context)
        trade = Trade(context, order)
        context.start_date = <span>'2010-01-01'</span>
        context.end_date = <span>'2018-12-31'</span>
        context.universe = [<span>'000300.XSHG'</span>]
        context.base = <span>'000300.XSHG'</span>
        _list.append(str(_Boll)+<span>','</span>+str(n_Boll))

        <span>"""策略主体"""</span>
        <span><span>def</span> <span>handle</span><span>(context, order)</span>:</span>
            stock = context.universe[<span>0</span>]
            time_count = _Boll
            n = n_Boll
            m = <span>2</span>
            HS_da = get_price(security=stock, 
                              end_date= context.current_dt,
                              frequency= <span>'daily'</span>, 
                              fields= <span>None</span>, 
                              skip_paused= <span>False</span>, 
                              fq=<span>'pre'</span>,
                              count= <span>50</span>)
            stock_data = get_price(stock, end_date= context.current_dt , frequency= <span>'daily'</span>, fields= <span>'close'</span>, skip_paused= <span>True</span>, fq= <span>'pre'</span>, count= (len(HS_da[<span>'close'</span>])+time_count<span>-1</span>))
            upper, middle, lower = talib.BBANDS(stock_data[<span>'close'</span>].values, timeperiod=time_count,nbdevup=n,nbdevdn=m,matype=<span>0</span>)
            <span>if</span> lower[<span>-2</span>] &gt; HS_da[<span>'close'</span>][<span>-2</span>] <span>and</span> lower[<span>-1</span>] &lt; HS_da[<span>'close'</span>][<span>-1</span>]:
                <span>if</span> stock <span>in</span> context.position.keys():
                    <span>return</span>
                order.buy(stock, HS_da[<span>'close'</span>][<span>-1</span>], context.cash // HS_da[<span>'close'</span>][<span>-1</span>])
            <span>elif</span> lower[<span>-1</span>] &gt; HS_da[<span>'close'</span>][<span>-1</span>] <span>or</span> upper[<span>-1</span>] &lt; HS_da[<span>'close'</span>][<span>-1</span>]:
                <span>if</span> stock <span>not</span> <span>in</span> context.position.keys():
                    <span>return</span>
                order.sell(stock, HS_da[<span>'close'</span>][<span>-1</span>], context.position[stock][<span>'count'</span>])
        trade.trade(handle, <span>False</span>)
        trade_list.append(trade)
<span># 展示</span>
Trade.show_all_ratio(<span>'Boll'</span>, Boll_list, trade_list)

Img
Img

数据表给予的信息蛮有非巧合性的,最优的Boll参数依旧为10。最优上轨标准差倍数为0.5,该参数的各项数据对比的排名基本为首位,但是回撤问题一直围绕着,得思考思考,就要考虑下轨问题。不过还是让[稀饭?哥伦布魏]有点尴尬而不失礼节的买了该配置的叉子。

轨道分化择优-下轨

  • 回测标的:沪深300指数。
  • 回测时间:2010年01月01日到2018年12月31日。
  • 初始资金:100000元。
  • 不考虑对冲成本,尽量投入全部资金。
  • Boll参数:[5, 10, 15, 20, 25, 30, 35, 40]
  • m参数:[0.5, 1, 1.5, 2]
    代码展示:
_list = []
trade_list = []
Boll_list = [<span>10</span>, <span>15</span>, <span>20</span>, <span>25</span>, <span>30</span>, <span>35</span>, <span>40</span>, <span>45</span>, <span>50</span>]
Boll_list_m = [<span>0.5</span>, <span>1</span>, <span>1.5</span>, <span>2</span>]
<span>for</span> _Boll <span>in</span> Boll_list:
    <span>for</span> m_Boll <span>in</span> Boll_list_m:
        <span># 策略结构</span>
        context = Context()
        order = Order(context)
        trade = Trade(context, order)
        context.start_date = <span>'2010-01-01'</span>
        context.end_date = <span>'2018-12-31'</span>
        context.universe = [<span>'000300.XSHG'</span>]
        context.base = <span>'000300.XSHG'</span>
        _list.append(str(_Boll)+<span>','</span>+str(m_Boll))

        <span>"""策略主体"""</span>
        <span><span>def</span> <span>handle</span><span>(context, order)</span>:</span>
            stock = context.universe[<span>0</span>]
            time_count = _Boll
            n = <span>2</span>
            m = m_Boll
            HS_da = get_price(security=stock, 
                              end_date= context.current_dt,
                              frequency= <span>'daily'</span>, 
                              fields= <span>None</span>, 
                              skip_paused= <span>False</span>, 
                              fq=<span>'pre'</span>,
                              count= <span>50</span>)
            stock_data = get_price(stock, end_date= context.current_dt , frequency= <span>'daily'</span>, fields= <span>'close'</span>, skip_paused= <span>True</span>, fq= <span>'pre'</span>, count= (len(HS_da[<span>'close'</span>])+time_count<span>-1</span>))
            upper, middle, lower = talib.BBANDS(stock_data[<span>'close'</span>].values, timeperiod=time_count,nbdevup=n,nbdevdn=m,matype=<span>0</span>)
            <span>if</span> lower[<span>-2</span>] &gt; HS_da[<span>'close'</span>][<span>-2</span>] <span>and</span> lower[<span>-1</span>] &lt; HS_da[<span>'close'</span>][<span>-1</span>]:
                <span>if</span> stock <span>in</span> context.position.keys():
                    <span>return</span>
                order.buy(stock, HS_da[<span>'close'</span>][<span>-1</span>], context.cash // HS_da[<span>'close'</span>][<span>-1</span>])
            <span>elif</span> lower[<span>-1</span>] &gt; HS_da[<span>'close'</span>][<span>-1</span>] <span>or</span> upper[<span>-1</span>] &lt; HS_da[<span>'close'</span>][<span>-1</span>]:
                <span>if</span> stock <span>not</span> <span>in</span> context.position.keys():
                    <span>return</span>
                order.sell(stock, HS_da[<span>'close'</span>][<span>-1</span>], context.position[stock][<span>'count'</span>])
        trade.trade(handle, <span>False</span>)
        trade_list.append(trade)
<span># 展示</span>
Trade.show_all_ratio(<span>'Boll'</span>, Boll_list, trade_list)

Img
Img

[稀饭?哥伦布魏]尴尬一笑,依旧是如此的场景,单一参数,策略正收益,最优下轨参数为2,差评地方为回撤貌似加大许多。

轨道综合

上节内容,应该明白发生什么事情,猪肉还是要好好买好好烤。这节内容,会比较严肃介绍。因为是风险厌恶择优的分析,以个人的风险厌恶程度来分析,做比较。

  • 回测标的:沪深300指数。
  • 回测时间:2010年01月01日到2018年12月31日。
  • 初始资金:100000元。
  • 不考虑对冲成本,尽量投入全部资金。
  • Boll参数:[5, 10, 15, 20, 25, 30, 35, 40]
  • n参数:[0.5, 1, 1.5, 2]
  • m参数:[0.5, 1, 1.5, 2]
    代码展示:
_list = []
trade_list = []
Boll_list = [<span>10</span>, <span>15</span>, <span>20</span>, <span>25</span>, <span>30</span>, <span>35</span>, <span>40</span>, <span>45</span>, <span>50</span>]
Boll_list_n = [<span>0.5</span>, <span>1</span>, <span>1.5</span>, <span>2</span>]
Boll_list_m = [<span>0.5</span>, <span>1</span>, <span>1.5</span>, <span>2</span>]
<span>for</span> _Boll <span>in</span> Boll_list:
    <span>for</span> m_Boll <span>in</span> Boll_list_m:
        <span>for</span> n_Boll <span>in</span> Boll_list_n:
            <span># 策略结构</span>
            context = Context()
            order = Order(context)
            trade = Trade(context, order)
            context.start_date = <span>'2010-01-01'</span>
            context.end_date = <span>'2018-12-31'</span>
            context.universe = [<span>'000300.XSHG'</span>]
            context.base = <span>'000300.XSHG'</span>
            _list.append(str(_Boll)+<span>','</span>+str([n_Boll,m_Boll]))

            <span>"""策略主体"""</span>
            <span><span>def</span> <span>handle</span><span>(context, order)</span>:</span>
                stock = context.universe[<span>0</span>]
                time_count = _Boll
                n = n_Boll
                m = m_Boll
                HS_da = get_price(security=stock, 
                                  end_date= context.current_dt,
                                  frequency= <span>'daily'</span>, 
                                  fields= <span>None</span>, 
                                  skip_paused= <span>False</span>, 
                                  fq=<span>'pre'</span>,
                                  count= <span>50</span>)
                stock_data = get_price(stock, end_date= context.current_dt , frequency= <span>'daily'</span>, fields= <span>'close'</span>, skip_paused= <span>True</span>, fq= <span>'pre'</span>, count= (len(HS_da[<span>'close'</span>])+time_count<span>-1</span>))
                upper, middle, lower = talib.BBANDS(stock_data[<span>'close'</span>].values, timeperiod=time_count,nbdevup=n,nbdevdn=m,matype=<span>0</span>)
                <span>if</span> lower[<span>-2</span>] &gt; HS_da[<span>'close'</span>][<span>-2</span>] <span>and</span> lower[<span>-1</span>] &lt; HS_da[<span>'close'</span>][<span>-1</span>]:
                    <span>if</span> stock <span>in</span> context.position.keys():
                        <span>return</span>
                    order.buy(stock, HS_da[<span>'close'</span>][<span>-1</span>], context.cash // HS_da[<span>'close'</span>][<span>-1</span>])
                <span>elif</span> lower[<span>-1</span>] &gt; HS_da[<span>'close'</span>][<span>-1</span>] <span>or</span> upper[<span>-1</span>] &lt; HS_da[<span>'close'</span>][<span>-1</span>]:
                    <span>if</span> stock <span>not</span> <span>in</span> context.position.keys():
                        <span>return</span>
                    order.sell(stock, HS_da[<span>'close'</span>][<span>-1</span>], context.position[stock][<span>'count'</span>])
            trade.trade(handle, <span>False</span>)
            trade_list.append(trade)
<span># 展示</span>
Trade.show_all_ratio(<span>'Boll'</span>, Boll_list, trade_list)

Img

Img

排头数据列表给予的信息比较明确,最优Boll参数为10,最优上轨标准差倍数为0.5,最优下轨标准差倍数为[0.5, 2],为何上轨标准差倍数是单个,而最优下轨标准差倍数是两个。从看收益来解释,正常的投资,是想保稳定收益,出场可以说是最简单也是最难的,因为心态和欲望控制、风险厌恶程度,因此上轨选择最稳定,而且小空间上轨等于中轨,有点价值回归的味道。
下轨为何会两个,这就关系到风险程度以及市场情绪变化、质变,下轨0.5与2是四倍的关系,从回撤角度,2的回撤几乎快是0.5的一倍,胜率提高了0.1,但是收益下降了一倍多,这就是进场风险选择的关键,总所周知,对于股价,每个人都希望走得稳定,但是却不能如愿,一旦股价走向极端,恰恰是引起质变效果,市场的情绪变化导致我们的心理变化,一波冲击波的情绪量瞬间扩大动能,然而使股价回归的另一波动能却不一定能使得股价回归,因为承接力以及大盘环境因素、股价自身情况。
Boll的运用,可以从多方面去切入,既然是中位线与价格的标准差,可以尝试使用标准差为重心去思考,如何使得中位线与偏离程度能更合适搭配我们的策略,配合量能去做搭配。总的一句话:波动之间最稳定的是平稳,而且不能急躁,慢工出细活。

总结

Boll是以波动率和价值回归为基础,数据告诉我们,谨慎是最安全的,以敏感的Boll参数10配合稳定小空间上下轨标准差倍数参数0.5,实际运用中,参数0.5的运用可能受限,但是可以在更小的周期里面运用。
市场的变化,是情绪得变化,多重变化,会引起质变,极端市场的行情,在Boll中是一种机会,但是也是一种风险,因为股票的性质会市场对待的情绪改变了。

下面展示本次研究效果最好的参数

  • 回测标的:沪深300指数。
  • 回测时间:2010年01月01日到2018年12月31日。
  • 初始资金:100000元。
  • 不考虑对冲成本,尽量投入全部资金。
    代码展示:
<span>"""初始化以下内容"""</span>
context = Context() <span># 账户对象</span>
order = Order(context) <span># 下单对象</span>
trade = Trade(context, order) <span># 回测对旬</span>
context.start_date = <span>'2010-01-01'</span>
context.end_date = <span>'2018-12-31'</span>
context.universe = [<span>'000300.XSHG'</span>]
context.base = <span>'000300.XSHG'</span>

<span>"""策略主体"""</span>
<span><span>def</span> <span>handle</span><span>(context, order)</span>:</span>
    stock = context.universe[<span>0</span>]
    time_count = <span>10</span>
    n = <span>0.5</span>
    m = <span>0.5</span>
    HS_da = get_price(security=stock, 
                      end_date= context.current_dt,
                      frequency= <span>'daily'</span>, 
                      fields= <span>None</span>, 
                      skip_paused= <span>False</span>, 
                      fq=<span>'pre'</span>,
                      count= <span>50</span>)
    stock_data = get_price(stock, end_date= context.current_dt , frequency= <span>'daily'</span>, fields= <span>'close'</span>, skip_paused= <span>True</span>, fq= <span>'pre'</span>, count= (len(HS_da[<span>'close'</span>])+time_count<span>-1</span>))
    upper, middle, lower = talib.BBANDS(stock_data[<span>'close'</span>].values, timeperiod=time_count,nbdevup=n,nbdevdn=m,matype=<span>0</span>)
    <span>if</span> lower[<span>-2</span>] &gt; HS_da[<span>'close'</span>][<span>-2</span>] <span>and</span> lower[<span>-1</span>] &lt; HS_da[<span>'close'</span>][<span>-1</span>]:
        <span>if</span> stock <span>in</span> context.position.keys():
            <span>return</span>
        order.buy(stock, HS_da[<span>'close'</span>][<span>-1</span>], context.cash // HS_da[<span>'close'</span>][<span>-1</span>])
    <span>elif</span> lower[<span>-1</span>] &gt; HS_da[<span>'close'</span>][<span>-1</span>] <span>or</span> upper[<span>-1</span>] &lt; HS_da[<span>'close'</span>][<span>-1</span>]:
        <span>if</span> stock <span>not</span> <span>in</span> context.position.keys():
            <span>return</span>
        order.sell(stock, HS_da[<span>'close'</span>][<span>-1</span>], context.position[stock][<span>'count'</span>])

<span>"""执行策略"""</span>
trade.trade(handle)

! Img