vnpy/examples/VnTrader/ctaStrategy123/strategy/strategyBollChannel.py

188 lines
6.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# encoding: UTF-8
"""
感谢Darwin Quant贡献的策略思路。
知乎专栏原文https://zhuanlan.zhihu.com/p/24448511
策略逻辑:
1. 布林通道(信号)
2. CCI指标过滤
3. ATR指标止损
适合品种:螺纹钢
适合周期15分钟
这里的策略是作者根据原文结合vn.py实现对策略实现上做了一些修改仅供参考。
"""
from __future__ import division
from vnpy.trader.vtObject import VtBarData
from vnpy.trader.vtConstant import EMPTY_STRING
from vnpy.trader.app.ctaStrategy.ctaTemplate import (CtaTemplate,
BarManager,
ArrayManager)
########################################################################
class BollChannelStrategy(CtaTemplate):
"""基于布林通道的交易策略"""
className = 'BollChannelStrategy'
author = u'用Python的交易员'
# 策略参数
bollWindow = 18 # 布林通道窗口数
bollDev = 3.4 # 布林通道的偏差
cciWindow = 10 # CCI窗口数
atrWindow = 30 # ATR窗口数
slMultiplier = 5.2 # 计算止损距离的乘数
initDays = 10 # 初始化数据所用的天数
fixedSize = 1 # 每次交易的数量
# 策略变量
bollUp = 0 # 布林通道上轨
bollDown = 0 # 布林通道下轨
cciValue = 0 # CCI指标数值
atrValue = 0 # ATR指标数值
intraTradeHigh = 0 # 持仓期内的最高点
intraTradeLow = 0 # 持仓期内的最低点
longStop = 0 # 多头止损
shortStop = 0 # 空头止损
# 参数列表,保存了参数的名称
paramList = ['name',
'className',
'author',
'vtSymbol',
'bollWindow',
'bollDev',
'cciWindow',
'atrWindow',
'slMultiplier',
'initDays',
'fixedSize']
# 变量列表,保存了变量的名称
varList = ['inited',
'trading',
'pos',
'bollUp',
'bollDown',
'cciValue',
'atrValue',
'intraTradeHigh',
'intraTradeLow',
'longStop',
'shortStop']
#----------------------------------------------------------------------
def __init__(self, ctaEngine, setting):
"""Constructor"""
super(BollChannelStrategy, self).__init__(ctaEngine, setting)
self.bm = BarManager(self.onBar, 15, self.onXminBar) # 创建K线合成器对象
self.am = ArrayManager()
#----------------------------------------------------------------------
def onInit(self):
"""初始化策略(必须由用户继承实现)"""
self.writeCtaLog(u'%s策略初始化' %self.name)
# 载入历史数据,并采用回放计算的方式初始化策略数值
initData = self.loadBar(self.initDays)
for bar in initData:
self.onBar(bar)
self.putEvent()
#----------------------------------------------------------------------
def onStart(self):
"""启动策略(必须由用户继承实现)"""
self.writeCtaLog(u'%s策略启动' %self.name)
self.putEvent()
#----------------------------------------------------------------------
def onStop(self):
"""停止策略(必须由用户继承实现)"""
self.writeCtaLog(u'%s策略停止' %self.name)
self.putEvent()
#----------------------------------------------------------------------
def onTick(self, tick):
"""收到行情TICK推送必须由用户继承实现"""
self.bm.updateTick(tick)
#----------------------------------------------------------------------
def onBar(self, bar):
"""收到Bar推送必须由用户继承实现"""
self.bm.updateBar(bar)
#----------------------------------------------------------------------
def onXminBar(self, bar):
"""收到X分钟K线"""
# 全撤之前发出的委托
self.cancelAll()
# 保存K线数据
am = self.am
am.updateBar(bar)
if not am.inited:
return
# 计算指标数值
self.bollUp, self.bollDown = am.boll(self.bollWindow, self.bollDev)
self.cciValue = am.cci(self.cciWindow)
self.atrValue = am.atr(self.atrWindow)
# 判断是否要进行交易
# 当前无仓位,发送开仓委托
if self.pos == 0:
self.intraTradeHigh = bar.high
self.intraTradeLow = bar.low
if self.cciValue > 0:
self.buy(self.bollUp, self.fixedSize, True)
elif self.cciValue < 0:
self.short(self.bollDown, self.fixedSize, True)
# 持有多头仓位
elif self.pos > 0:
self.intraTradeHigh = max(self.intraTradeHigh, bar.high)
self.intraTradeLow = bar.low
self.longStop = self.intraTradeHigh - self.atrValue * self.slMultiplier
self.sell(self.longStop, abs(self.pos), True)
# 持有空头仓位
elif self.pos < 0:
self.intraTradeHigh = bar.high
self.intraTradeLow = min(self.intraTradeLow, bar.low)
self.shortStop = self.intraTradeLow + self.atrValue * self.slMultiplier
self.cover(self.shortStop, abs(self.pos), True)
# 发出状态更新事件
self.putEvent()
#----------------------------------------------------------------------
def onOrder(self, order):
"""收到委托变化推送(必须由用户继承实现)"""
pass
#----------------------------------------------------------------------
def onTrade(self, trade):
# 发出状态更新事件
self.putEvent()
#----------------------------------------------------------------------
def onStopOrder(self, so):
"""停止单推送"""
pass