目录
上一篇用多因子策略回测后,止损效果不明显,这次用布林带突破。
-
策略逻辑
当价格触及布林线上轨的时候进行卖出,当触及下轨的时候,进行买入。
-
增量代码
# coding=utf-8
from __future__ import print_function, absolute_import, unicode_literals
from gm.api import *
"""
本策略采用布林线进行均值回归交易。当价格触及布林线上轨的时候进行卖出,当触及下轨的时候,进行买入。
使用600004在 2009-09-17 13:00:00 到 2020-03-21 15:00:00 进行了回测。
注意:
1:实盘中,如果在收盘的那一根bar或tick触发交易信号,需要自行处理,实盘可能不会成交。
"""
# 策略中必须有init方法
def init(context):
""" init函数是在策略开始运行时被调用,进行初始化工作的函数"""
# 设置布林线的三个参数
context.maPeriod = 26 # 计算BOLL布林线中轨的参数
context.stdPeriod = 26 # 计算BOLL 标准差的参数
context.stdRange = 1 # 计算BOLL 上下轨和中轨距离的参数
# 设置要进行回测的合约 合约名称写法详见 https://www.myquant.cn/docs/python/python_concept#44e233ec21d880c2
# 或者可以在掘金终端的仿真交易中输入这个代码看是否查询的是需要的标的
# 订阅数据滑窗长度
context.period = max(context.maPeriod, context.stdPeriod, context.stdRange) + 1
# 滑窗指的是每次从最新的行情往回取一定周期的数据, 相当于行情软件中k线图一个屏所容纳的k线
# context.symbols = 'SZSE.300558,SZSE.300457,SZSE.300529,SZSE.300661,SZSE.300676'
context.symbol_list = ['SZSE.300558', 'SZSE.300457', 'SZSE.300529', 'SZSE.300661', 'SZSE.300676'] # 订阅&交易标的,
# 订阅行情 第一个参数是标的, 第二个是时间周期,表示日线,第三个指指定设置count参数,表示需要的滑窗大
# 详见 https://www.myquant.cn/docs/python/python_subscribe#15ad56f8be8519c0
subscribe(symbols= context.symbol_list, frequency='1d', count=context.period)
context.symbol = ''
def on_bar(context, bars):
"""
当init中subscribe订阅过的标的的k线完成的时候,on_bar 会被调用,用来处理计算和交易下单逻辑
详见 https://www.myquant.cn/docs/python/python_data_event#b198d6b609adb1d4
"""
for symbol in context.symbol_list:
context.symbol=symbol
boll(context)
def boll(context):
symbol=context.symbol
# 获取数据滑窗,只要在init里面有订阅,在这里就可以取的到, 返回值是pandas.DataFrame的数据结构
data = context.data(symbol=symbol, frequency='1d', count=context.period, fields='close')
# data = history_n(symbol=symbol, frequency='1d', end_time=context.now, fields='close', count=context.period, df=True)
# 计算boll的上下界
bollUpper = data.close.rolling(context.maPeriod).mean() \
+ context.stdRange * data.close.rolling(context.stdPeriod).std()
bollBottom = data.close.rolling(context.maPeriod).mean() \
- context.stdRange * data.close.rolling(context.stdPeriod).std()
# 获取现有持仓
pos = context.account().position(symbol=symbol, side=PositionSide_Long)
# 交易逻辑与下单
# 当有持仓,且股价穿过BOLL上界的时候卖出股票。
if data.close.values[-1] > bollUpper.values[-1] and data.close.values[-2] < bollUpper.values[-2]:
if pos: # 有持仓就市价卖出股票。
order_target_percent(symbol=symbol, percent=0, order_type=OrderType_Market,
position_side=PositionSide_Long)
print('以市价单卖出:' + symbol)
# 当没有持仓,且股价穿过BOLL下界的时候买入股票。
elif data.close.values[-1] < bollBottom.values[-1] and data.close.values[-2] > bollBottom.values[-2]:
if not pos: # 没有持仓就买入。
order_target_percent(symbol=symbol, percent=1/len(context.symbol_list), order_type=OrderType_Market,
position_side=PositionSide_Long)
print('以市价单买入:'+symbol)
# 查看最终的回测结果
def on_backtest_finished(context, indicator):
print(indicator)
if __name__ == '__main__':
'''
strategy_id策略ID,由系统生成
filename文件名,请与本文件名保持一致
mode实时模式:MODE_LIVE回测模式:MODE_BACKTEST
token绑定计算机的ID,可在系统设置-密钥管理中生成
backtest_start_time回测开始时间
backtest_end_time回测结束时间
backtest_adjust股票复权方式不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
backtest_initial_cash回测初始资金
backtest_commission_ratio回测佣金比例
backtest_slippage_ratio回测滑点比例
'''
run(strategy_id='e8b49858-882c-11ea-b2b5-0a0027000006',
filename='bollings.py',
mode=MODE_BACKTEST,
token='9b06ce1b5a39ac39d7',
backtest_start_time='2020-01-01 13:00:00',
backtest_end_time='2020-08-21 15:00:00',
backtest_adjust=ADJUST_PREV,
backtest_initial_cash=1000000,
backtest_commission_ratio=0.0001,
backtest_slippage_ratio=0.0001)
-
回测结果
多支创业板股票的回测:
扫描二维码关注公众号,回复:
11924435 查看本文章
-
结果分析
貌似回测效果还不错,分析下,有可能是我选择的几支创业板股票表现本身就不错