之前写了bollchannel布林线轨道策略,感觉自己也有收获,趁热打铁,分析下另一个时间周期策略。
其实原理很简单,就是15分钟周期分析现在多头还是空头市场,再结合rsi指标,在5分钟线K线级别下单。非常简单,也很有效。
class MultiTimeframeStrategy(CtaTemplate):
"""跨时间周期交易策略"""
className = 'MultiTimeframeStrategy'
author = u'用Python的交易员'
# 策略参数
rsiSignal = 20 # RSI信号阈值
rsiWindow = 14 # RSI窗口
fastWindow = 5 # 快速均线窗口
slowWindow = 20 # 慢速均线窗口
#这里RSI指标, Relative Strength Index的缩写, 一般r认为50是平衡市场,大于50倾向多头,小于50空头倾向;这里20是一个阈#值,实际就是50+20 = 70 确立多头,50-20 = 30 确认空头。
#rsiWondow 是计算rsiValue的周期参数。
#fastWindow 和slowWindow都是计算均线的周期参数,其中fastWindow是计算5日,slowWindow是20日,如果fast 均价大于slow,一般认为向上趋势,反之向下。
initDays = 10 # 初始化数据所用的天数
fixedSize = 1 # 每次交易的数量
#参考bollchannel文章
# 策略变量
rsiValue = 0 # RSI指标的数值
rsiLong = 0 # RSI买开阈值
rsiShort = 0 # RSI卖开阈值
fastMa = 0 # 5分钟快速均线
slowMa = 0 # 5分钟慢速均线
maTrend = 0 # 均线趋势,多头1,空头-1
#参考bollchannel文章
# 参数列表,保存了参数的名称
paramList = ['name',
'className',
'author',
'vtSymbol',
'rsiSignal',
'rsiWindow',
'fastWindow',
'slowWindow']
#参考bollchannel文章
# 变量列表,保存了变量的名称
varList = ['inited',
'trading',
'pos',
'rsiValue',
'rsiLong',
'rsiShort',
'fastMa',
'slowMa',
'maTrend']
#参考bollchannel文章,其中maTrend是根据快慢均值的高低,如果fastMa > slowMa 为向上,maTrend > 0; 反之向下。
# 同步列表,保存了需要保存到数据库的变量名称
syncList = ['pos']
#参考bollchannel文章,这里只同步仓位。
#----------------------------------------------------------------------
def __init__(self, ctaEngine, setting):
"""Constructor"""
super(MultiTimeframeStrategy, self).__init__(ctaEngine, setting)
self.rsiLong = 50 + self.rsiSignal
self.rsiShort = 50 - self.rsiSignal
#如上文,rsi 大于70为多头,rsi小于30为空头。
# 创建K线合成器对象
self.bg5 = BarGenerator(self.onBar, 5, self.on5MinBar)
self.am5 = ArrayManager()
self.bg15 = BarGenerator(self.onBar, 15, self.on15MinBar)
self.am15 = ArrayManager()
#实现两个K线合成器和AM,来合成并计算5分钟和15分钟K线和对应指标。
#----------------------------------------------------------------------
def onInit(self):
"""初始化策略(必须由用户继承实现)"""
self.writeCtaLog(u'%s策略初始化' %self.name)
# 载入历史数据,并采用回放计算的方式初始化策略数值
initData = self.loadBar(self.initDays)
for bar in initData:
self.onBar(bar)
self.putEvent()
#参考bollchannel文章
#----------------------------------------------------------------------
def onStart(self):
"""启动策略(必须由用户继承实现)"""
self.writeCtaLog(u'%s策略启动' %self.name)
self.putEvent()
#----------------------------------------------------------------------
def onStop(self):
"""停止策略(必须由用户继承实现)"""
self.writeCtaLog(u'%s策略停止' %self.name)
self.putEvent()
#参考bollchannel文章
#----------------------------------------------------------------------
def onTick(self, tick):
"""收到行情TICK推送(必须由用户继承实现)"""
# 只需要要在一个BarGenerator中合成1分钟K线
self.bg5.updateTick(tick)
#参考bollchannel文章, 根据tick交易行情,合成1分钟K线,并更新bg5中onBar。一般这个是针对实盘;通常历史数据下载来都是不到tick级别,而且一分钟k线;可能券商本身会有。这里感觉应该吧bg15放在一起更合适吧。。。
#----------------------------------------------------------------------
def onBar(self, bar):
"""收到Bar推送(必须由用户继承实现)"""
# 基于15分钟判断趋势过滤,因此先更新
self.bg15.updateBar(bar)
# 基于5分钟判断
self.bg5.updateBar(bar)
#参考bollchannel文章,当一分钟K线到达后,凑够时间,合成对应时间K线,包括15分钟和5分钟
#----------------------------------------------------------------------
def on5MinBar(self, bar):
"""5分钟K线"""
self.cancelAll()
#参考bollchannel文章,清空未成交。
# 保存K线数据
self.am5.updateBar(bar)
if not self.am5.inited:
return
#参考bollchannel文章,取得AM指标计算是否有100个bar的数据来计算。
# 如果15分钟数据尚未初始化完毕,则直接返回
if not self.maTrend:
return
#15分钟K线,计算快慢线 fastMa,slowM a 和maTrend; 如果maTrend没有值,说明15分钟K线还没有到100,所以推出函数。
# 计算指标数值
self.rsiValue = self.am5.rsi(self.rsiWindow)
#根据risWindos计算出5分钟rsi现在值。
# 判断是否要进行交易
# 当前无仓位
if self.pos == 0:
if self.maTrend > 0 and self.rsiValue >= self.rsiLong:
self.buy(bar.close+5, self.fixedSize)
elif self.maTrend < 0 and self.rsiValue <= self.rsiShort:
self.short(bar.close-5, self.fixedSize)
#如果空,maTrend 和rsiValue都是多头,下多单,这个是市价单,其实价格没有什么意思,都会按照涨停发出。同理相反,如果都是空头,下空单。
# 持有多头仓位
elif self.pos > 0:
if self.maTrend < 0 or self.rsiValue < 50:
self.sell(bar.close-5, abs(self.pos))
# 持有空头仓位
elif self.pos < 0:
if self.maTrend > 0 or self.rsiValue > 50:
self.cover(bar.close+5, abs(self.pos))
#如果有多头仓位,但是空头趋势,平仓,反之持有空头也是一样。
# 发出状态更新事件
self.putEvent()
#----------------------------------------------------------------------
def on15MinBar(self, bar):
"""15分钟K线推送"""
self.am15.updateBar(bar)
if not self.am15.inited:
return
# 计算均线并判断趋势
self.fastMa = self.am15.sma(self.fastWindow)
self.slowMa = self.am15.sma(self.slowWindow)
if self.fastMa > self.slowMa:
self.maTrend = 1
else:
self.maTrend = -1
#这个不说了,计算快慢均线价格,和对应趋势。
#----------------------------------------------------------------------
def onOrder(self, order):
"""收到委托变化推送(必须由用户继承实现)"""
pass
#----------------------------------------------------------------------
def onTrade(self, trade):
# 发出状态更新事件
self.putEvent()
#----------------------------------------------------------------------
def onStopOrder(self, so):
"""停止单推送"""
pass
其实原理很简单,就是15分钟周期分析现在多头还是空头市场,再结合rsi指标,在5分钟线K线级别下单。非常简单,也很有效。
class MultiTimeframeStrategy(CtaTemplate):
"""跨时间周期交易策略"""
className = 'MultiTimeframeStrategy'
author = u'用Python的交易员'
# 策略参数
rsiSignal = 20 # RSI信号阈值
rsiWindow = 14 # RSI窗口
fastWindow = 5 # 快速均线窗口
slowWindow = 20 # 慢速均线窗口
#这里RSI指标, Relative Strength Index的缩写, 一般r认为50是平衡市场,大于50倾向多头,小于50空头倾向;这里20是一个阈#值,实际就是50+20 = 70 确立多头,50-20 = 30 确认空头。
#rsiWondow 是计算rsiValue的周期参数。
#fastWindow 和slowWindow都是计算均线的周期参数,其中fastWindow是计算5日,slowWindow是20日,如果fast 均价大于slow,一般认为向上趋势,反之向下。
initDays = 10 # 初始化数据所用的天数
fixedSize = 1 # 每次交易的数量
#参考bollchannel文章
# 策略变量
rsiValue = 0 # RSI指标的数值
rsiLong = 0 # RSI买开阈值
rsiShort = 0 # RSI卖开阈值
fastMa = 0 # 5分钟快速均线
slowMa = 0 # 5分钟慢速均线
maTrend = 0 # 均线趋势,多头1,空头-1
#参考bollchannel文章
# 参数列表,保存了参数的名称
paramList = ['name',
'className',
'author',
'vtSymbol',
'rsiSignal',
'rsiWindow',
'fastWindow',
'slowWindow']
#参考bollchannel文章
# 变量列表,保存了变量的名称
varList = ['inited',
'trading',
'pos',
'rsiValue',
'rsiLong',
'rsiShort',
'fastMa',
'slowMa',
'maTrend']
#参考bollchannel文章,其中maTrend是根据快慢均值的高低,如果fastMa > slowMa 为向上,maTrend > 0; 反之向下。
# 同步列表,保存了需要保存到数据库的变量名称
syncList = ['pos']
#参考bollchannel文章,这里只同步仓位。
#----------------------------------------------------------------------
def __init__(self, ctaEngine, setting):
"""Constructor"""
super(MultiTimeframeStrategy, self).__init__(ctaEngine, setting)
self.rsiLong = 50 + self.rsiSignal
self.rsiShort = 50 - self.rsiSignal
#如上文,rsi 大于70为多头,rsi小于30为空头。
# 创建K线合成器对象
self.bg5 = BarGenerator(self.onBar, 5, self.on5MinBar)
self.am5 = ArrayManager()
self.bg15 = BarGenerator(self.onBar, 15, self.on15MinBar)
self.am15 = ArrayManager()
#实现两个K线合成器和AM,来合成并计算5分钟和15分钟K线和对应指标。
#----------------------------------------------------------------------
def onInit(self):
"""初始化策略(必须由用户继承实现)"""
self.writeCtaLog(u'%s策略初始化' %self.name)
# 载入历史数据,并采用回放计算的方式初始化策略数值
initData = self.loadBar(self.initDays)
for bar in initData:
self.onBar(bar)
self.putEvent()
#参考bollchannel文章
#----------------------------------------------------------------------
def onStart(self):
"""启动策略(必须由用户继承实现)"""
self.writeCtaLog(u'%s策略启动' %self.name)
self.putEvent()
#----------------------------------------------------------------------
def onStop(self):
"""停止策略(必须由用户继承实现)"""
self.writeCtaLog(u'%s策略停止' %self.name)
self.putEvent()
#参考bollchannel文章
#----------------------------------------------------------------------
def onTick(self, tick):
"""收到行情TICK推送(必须由用户继承实现)"""
# 只需要要在一个BarGenerator中合成1分钟K线
self.bg5.updateTick(tick)
#参考bollchannel文章, 根据tick交易行情,合成1分钟K线,并更新bg5中onBar。一般这个是针对实盘;通常历史数据下载来都是不到tick级别,而且一分钟k线;可能券商本身会有。这里感觉应该吧bg15放在一起更合适吧。。。
#----------------------------------------------------------------------
def onBar(self, bar):
"""收到Bar推送(必须由用户继承实现)"""
# 基于15分钟判断趋势过滤,因此先更新
self.bg15.updateBar(bar)
# 基于5分钟判断
self.bg5.updateBar(bar)
#参考bollchannel文章,当一分钟K线到达后,凑够时间,合成对应时间K线,包括15分钟和5分钟
#----------------------------------------------------------------------
def on5MinBar(self, bar):
"""5分钟K线"""
self.cancelAll()
#参考bollchannel文章,清空未成交。
# 保存K线数据
self.am5.updateBar(bar)
if not self.am5.inited:
return
#参考bollchannel文章,取得AM指标计算是否有100个bar的数据来计算。
# 如果15分钟数据尚未初始化完毕,则直接返回
if not self.maTrend:
return
#15分钟K线,计算快慢线 fastMa,slowM a 和maTrend; 如果maTrend没有值,说明15分钟K线还没有到100,所以推出函数。
# 计算指标数值
self.rsiValue = self.am5.rsi(self.rsiWindow)
#根据risWindos计算出5分钟rsi现在值。
# 判断是否要进行交易
# 当前无仓位
if self.pos == 0:
if self.maTrend > 0 and self.rsiValue >= self.rsiLong:
self.buy(bar.close+5, self.fixedSize)
elif self.maTrend < 0 and self.rsiValue <= self.rsiShort:
self.short(bar.close-5, self.fixedSize)
#如果空,maTrend 和rsiValue都是多头,下多单,这个是市价单,其实价格没有什么意思,都会按照涨停发出。同理相反,如果都是空头,下空单。
# 持有多头仓位
elif self.pos > 0:
if self.maTrend < 0 or self.rsiValue < 50:
self.sell(bar.close-5, abs(self.pos))
# 持有空头仓位
elif self.pos < 0:
if self.maTrend > 0 or self.rsiValue > 50:
self.cover(bar.close+5, abs(self.pos))
#如果有多头仓位,但是空头趋势,平仓,反之持有空头也是一样。
# 发出状态更新事件
self.putEvent()
#----------------------------------------------------------------------
def on15MinBar(self, bar):
"""15分钟K线推送"""
self.am15.updateBar(bar)
if not self.am15.inited:
return
# 计算均线并判断趋势
self.fastMa = self.am15.sma(self.fastWindow)
self.slowMa = self.am15.sma(self.slowWindow)
if self.fastMa > self.slowMa:
self.maTrend = 1
else:
self.maTrend = -1
#这个不说了,计算快慢均线价格,和对应趋势。
#----------------------------------------------------------------------
def onOrder(self, order):
"""收到委托变化推送(必须由用户继承实现)"""
pass
#----------------------------------------------------------------------
def onTrade(self, trade):
# 发出状态更新事件
self.putEvent()
#----------------------------------------------------------------------
def onStopOrder(self, so):
"""停止单推送"""
pass
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22259926/viewspace-2156080/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/22259926/viewspace-2156080/