布林线均值回归(股票)

    • 1. 原理

    • 2. 策略思路

    • 3. 策略代码

    • 4. 回测结果与稳健性分析

布林线均值回归策略

1. 原理

提起布林线均值回归策略,就不得不提布林带这个概念。布林带是利用统计学中的均值和标准差联合计算得出的,分为均线,上轨线和下轨线。布林线均值回归策略认为,标的价格在上轨线和下轨线围成的范围内浮动,即使短期内突破上下轨,但长期内仍然会回归到布林带之中。因此,一旦突破上下轨,即形成买卖信号。

当股价向上突破上界时,为卖出信号,当股价向下突破下界时,为买入信号。

BOLL线的计算公式:

中轨线 = N日移动平均线
上轨线 = 中轨线 + k 标准差
下轨线 = 中轨线 - k
标准差

2. 策略思路

第一步:根据数据计算BOLL线的上下界
第二步:获得持仓信号
第三步:回测分析

回测标的:SHSE.600004
回测期:2009-09-17 13:00:00 到 2020-03-21 15:00:00
回测初始资金:1000元

3. 策略代码

  1. # coding=utf-8

  2. from __future__ import print_function, absolute_import

  3. from gm.api import *

  4. '''

  5. 本策略采用布林线进行均值回归交易。当价格触及布林线上轨的时候进行卖出,当触及下轨的时候,进行买入。

  6. 使用600004在 2009-09-17 13:00:00 到 2020-03-21 15:00:00 进行了回测。

  7. 注意:

  8. 1:实盘中,如果在收盘的那一根bar或tick触发交易信号,需要自行处理,实盘可能不会成交。

  9. '''

  10. # 策略中必须有init方法

  11. def init(context):

  12. # 设置布林线的三个参数

  13. context.maPeriod = 26 # 计算BOLL布林线中轨的参数

  14. context.stdPeriod = 26 # 计算BOLL 标准差的参数

  15. context.stdRange = 1 # 计算BOLL 上下轨和中轨距离的参数

  16. # 设置要进行回测的合约

  17. context.symbol = 'SHSE.600004' # 订阅&交易标的, 此处订阅的是600004

  18. context.period = max(context.maPeriod, context.stdPeriod, context.stdRange) + 1 # 订阅数据滑窗长度

  19. # 订阅行情

  20. subscribe(symbols= context.symbol, frequency='1d', count=context.period)

  21. def on_bar(context, bars):

  22. # 获取数据滑窗,只要在init里面有订阅,在这里就可以取的到,返回值是pandas.DataFrame

  23. data = context.data(symbol=context.symbol, frequency='1d', count=context.period, fields='close')

  24. # 计算boll的上下界

  25. bollUpper = data['close'].rolling(context.maPeriod).mean() \

  26. + context.stdRange * data['close'].rolling(context.stdPeriod).std()

  27. bollBottom = data['close'].rolling(context.maPeriod).mean() \

  28. - context.stdRange * data['close'].rolling(context.stdPeriod).std()

  29. # 获取现有持仓

  30. pos = context.account().position(symbol=context.symbol, side=PositionSide_Long)

  31. # 交易逻辑与下单

  32. # 当有持仓,且股价穿过BOLL上界的时候卖出股票。

  33. if data.close.values[-1] > bollUpper.values[-1] and data.close.values[-2] < bollUpper.values[-2]:

  34. if pos: # 有持仓就市价卖出股票。

  35. order_volume(symbol=context.symbol, volume=100, side=OrderSide_Sell,

  36. order_type=OrderType_Market, position_effect=PositionEffect_Close)

  37. print('以市价单卖出一手')

  38. # 当没有持仓,且股价穿过BOLL下界的时候买出股票。

  39. elif data.close.values[-1] < bollBottom.values[-1] and data.close.values[-2] > bollBottom.values[-2]:

  40. if not pos: # 没有持仓就买入一百股。

  41. order_volume(symbol=context.symbol, volume=100, side=OrderSide_Buy,

  42. order_type=OrderType_Market, position_effect=PositionEffect_Open)

  43. print('以市价单买入一手')

  44. if __name__ == '__main__':

  45. '''

  46. strategy_id策略ID,由系统生成

  47. filename文件名,请与本文件名保持一致

  48. mode实时模式:MODE_LIVE回测模式:MODE_BACKTEST

  49. token绑定计算机的ID,可在系统设置-密钥管理中生成

  50. backtest_start_time回测开始时间

  51. backtest_end_time回测结束时间

  52. backtest_adjust股票复权方式不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST

  53. backtest_initial_cash回测初始资金

  54. backtest_commission_ratio回测佣金比例

  55. backtest_slippage_ratio回测滑点比例

  56. '''

  57. run(strategy_id='strategy_id',

  58. filename='main.py',

  59. mode=MODE_BACKTEST,

  60. token='token_id',

  61. backtest_start_time='2009-09-17 13:00:00',

  62. backtest_end_time='2020-03-21 15:00:00',

  63. backtest_adjust=ADJUST_PREV,

  64. backtest_initial_cash=1000,

  65. backtest_commission_ratio=0.0001,

  66. backtest_slippage_ratio=0.0001)

4. 回测结果与稳健性分析

设定初始资金1000元,手续费率为0.01%,滑点比率为0.01%。回测结果如下图所示。

回测期累计收益率为99.77%,年化收益率为9.49%。沪深300收益率为10.03%,策略整体跑输大盘。最大回撤为32.04%,胜率为73.47%。

为了验证策略的稳定性,改变回测周期,观察收益情况。

标的 回测期 年化收益率 最大回撤
SHSE.600004 2009.09.17-2020.03.21 9.49% 32.04%
SHSE.600004 2009.01.01-2014.12.30 2.64% 17.07%
SHSE.600004 2014.01.01-2020.03.21 20.75% 17.21%
SHSE.600004 2009.01.01-2019.03.21 8.18% 31.95%

调整不同的回测期后,策略的收益情况发生变化。整体收益均为正,但均跑输大盘。

注:此策略只用于学习、交流、演示,不构成任何投资建议。

(0)

相关推荐