def __init__(self, ctaEngine, setting): """Constructor""" super(AtrRsiStrategy, self).__init__(ctaEngine, setting) # 创建K线合成器对象 self.bg = BarGenerator(self.onBar) self.am = ArrayManager()
def __init__(self): """Constructor""" super(MaSignal, self).__init__() self.fastWindow = 5 self.slowWindow = 20 self.bg = BarGenerator(self.onBar, 5, self.onFiveBar) self.am = ArrayManager()
def __init__(self, ctaEngine, setting): """Constructor""" super(KkStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar, 5, self.onFiveBar) # 创建K线合成器对象 self.am = ArrayManager() self.buyOrderIDList = [] self.shortOrderIDList = [] self.orderList = []
def __init__(self): """Constructor""" super(CciSignal, self).__init__() self.cciWindow = 30 self.cciLevel = 10 self.cciLong = self.cciLevel self.cciShort = -self.cciLevel self.bg = BarGenerator(self.onBar) self.am = ArrayManager()
def __init__(self): """Constructor""" super(RsiSignal, self).__init__() self.rsiWindow = 14 self.rsiLevel = 20 self.rsiLong = 50 + self.rsiLevel self.rsiShort = 50 - self.rsiLevel self.bg = BarGenerator(self.onBar) self.am = ArrayManager()
def __init__(self, ctaEngine, setting): """Constructor""" super(MultiTimeframeStrategy, self).__init__(ctaEngine, setting) self.rsiLong = 50 + self.rsiSignal self.rsiShort = 50 - self.rsiSignal # 创建K线合成器对象 self.bg5 = BarGenerator(self.onBar, 5, self.on5MinBar) self.am5 = ArrayManager() self.bg15 = BarGenerator(self.onBar, 15, self.on15MinBar) self.am15 = ArrayManager()
class MaSignal(CtaSignal): """双均线信号""" #---------------------------------------------------------------------- def __init__(self): """Constructor""" super(MaSignal, self).__init__() self.fastWindow = 5 self.slowWindow = 20 self.bg = BarGenerator(self.onBar, 5, self.onFiveBar) self.am = ArrayManager() #---------------------------------------------------------------------- def onTick(self, tick): """Tick更新""" self.bg.updateTick(tick) #---------------------------------------------------------------------- def onBar(self, bar): """K线更新""" self.bg.updateBar(bar) #---------------------------------------------------------------------- def onFiveBar(self, bar): """5分钟K线更新""" self.am.updateBar(bar) if not self.am.inited: self.setSignalPos(0) fastMa = self.am.sma(self.fastWindow) slowMa = self.am.sma(self.slowWindow) if fastMa > slowMa: self.setSignalPos(1) elif fastMa < slowMa: self.setSignalPos(-1) else: self.setSignalPos(0)
class RsiSignal(CtaSignal): """RSI信号""" #---------------------------------------------------------------------- def __init__(self): """Constructor""" super(RsiSignal, self).__init__() self.rsiWindow = 14 self.rsiLevel = 20 self.rsiLong = 50 + self.rsiLevel self.rsiShort = 50 - self.rsiLevel self.bg = BarGenerator(self.onBar) self.am = ArrayManager() #---------------------------------------------------------------------- def onTick(self, tick): """Tick更新""" self.bg.updateTick(tick) #---------------------------------------------------------------------- def onBar(self, bar): """K线更新""" self.am.updateBar(bar) if not self.am.inited: self.setSignalPos(0) rsiValue = self.am.rsi(self.rsiWindow) if rsiValue >= self.rsiLong: self.setSignalPos(1) elif rsiValue <= self.rsiShort: self.setSignalPos(-1) else: self.setSignalPos(0)
class CciSignal(CtaSignal): """CCI信号""" #---------------------------------------------------------------------- def __init__(self): """Constructor""" super(CciSignal, self).__init__() self.cciWindow = 30 self.cciLevel = 10 self.cciLong = self.cciLevel self.cciShort = -self.cciLevel self.bg = BarGenerator(self.onBar) self.am = ArrayManager() #---------------------------------------------------------------------- def onTick(self, tick): """Tick更新""" self.bg.updateTick(tick) #---------------------------------------------------------------------- def onBar(self, bar): """K线更新""" self.am.updateBar(bar) if not self.am.inited: self.setSignalPos(0) cciValue = self.am.cci(self.cciWindow) if cciValue >= self.cciLong: self.setSignalPos(1) elif cciValue<= self.cciShort: self.setSignalPos(-1) else: self.setSignalPos(0)
def __init__(self, ctaEngine, setting): """Constructor""" super(TurtleTradingStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar) self.am = ArrayManager()
class TurtleTradingStrategy(CtaTemplate): """海龟交易策略""" className = 'TurtleTradingStrategy' author = u'用Python的交易员' # 策略参数 entryWindow = 55 # 入场通道窗口 exitWindow = 20 # 出场通道窗口 atrWindow = 20 # 计算ATR波动率的窗口 initDays = 10 # 初始化数据所用的天数 fixedSize = 1 # 每次交易的数量 # 策略变量 entryUp = 0 # 入场通道上轨 entryDown = 0 # 入场通道下轨 exitUp = 0 # 出场通道上轨 exitDown = 0 # 出场通道下轨 atrVolatility = 0 # ATR波动率 longEntry = 0 # 多头入场价格 shortEntry = 0 # 空头入场价格 longStop = 0 # 多头止损价格 shortStop = 0 # 空头止损价格 # 参数列表,保存了参数的名称 paramList = ['name', 'className', 'author', 'vtSymbol', 'entryWindow', 'exitWindow', 'atrWindow', 'initDays', 'fixedSize'] # 变量列表,保存了变量的名称 varList = ['inited', 'trading', 'pos', 'entryUp', 'entryDown', 'exitUp', 'exitDown', 'longEntry', 'shortEntry', 'longStop', 'shortStop'] # 同步列表,保存了需要保存到数据库的变量名称 syncList = ['pos'] #---------------------------------------------------------------------- def __init__(self, ctaEngine, setting): """Constructor""" super(TurtleTradingStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar) 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.bg.updateTick(tick) #---------------------------------------------------------------------- def onBar(self, bar): """收到Bar推送(必须由用户继承实现)""" self.cancelAll() # 保存K线数据 self.am.updateBar(bar) if not self.am.inited: return # 计算指标数值 self.entryUp, self.entryDown = self.am.donchian(self.entryWindow) self.exitUp, self.exitDown = self.am.donchian(self.exitWindow) if not self.pos: self.atrVolatility = self.am.atr(self.atrWindow) # 判断是否要进行交易 if self.pos == 0: self.longEntry = 0 self.shortEntry = 0 self.longStop = 0 self.shortStop = 0 self.sendBuyOrders(self.entryUp) self.sendShortOrders(self.entryDown) elif self.pos > 0: # 加仓逻辑 self.sendBuyOrders(self.longEntry) # 止损逻辑 sellPrice = max(self.longStop, self.exitDown) self.sell(sellPrice, abs(self.pos), True) elif self.pos < 0: # 加仓逻辑 self.sendShortOrders(self.shortEntry) # 止损逻辑 coverPrice = min(self.shortStop, self.exitUp) self.cover(coverPrice, abs(self.pos), True) # 同步数据到数据库 self.saveSyncData() # 发出状态更新事件 self.putEvent() #---------------------------------------------------------------------- def onOrder(self, order): """收到委托变化推送(必须由用户继承实现)""" pass #---------------------------------------------------------------------- def onTrade(self, trade): """成交推送""" if trade.direction == DIRECTION_LONG: self.longEntry = trade.price self.longStop = self.longEntry - self.atrVolatility * 2 else: self.shortEntry = trade.price self.shortStop = self.shortEntry + self.atrVolatility * 2 # 发出状态更新事件 self.putEvent() #---------------------------------------------------------------------- def onStopOrder(self, so): """停止单推送""" pass #---------------------------------------------------------------------- def sendBuyOrders(self, price): """发出一系列的买入停止单""" t = self.pos / self.fixedSize if t < 1: self.buy(price, self.fixedSize, True) if t < 2: self.buy(price + self.atrVolatility*0.5, self.fixedSize, True) if t < 3: self.buy(price + self.atrVolatility, self.fixedSize, True) if t < 4: self.buy(price + self.atrVolatility*1.5, self.fixedSize, True) #---------------------------------------------------------------------- def sendShortOrders(self, price): """""" t = self.pos / self.fixedSize if t > -1: self.short(price, self.fixedSize, True) if t > -2: self.short(price - self.atrVolatility*0.5, self.fixedSize, True) if t > -3: self.short(price - self.atrVolatility, self.fixedSize, True) if t > -4: self.short(price - self.atrVolatility*1.5, self.fixedSize, True)
def __init__(self, ctaEngine, setting): """Constructor""" super(BollChannelStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar, 15, self.onXminBar) # 创建K线合成器对象 self.am = 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' ] # 同步列表,保存了需要保存到数据库的变量名称 syncList = ['pos', 'intraTradeHigh', 'intraTradeLow'] #---------------------------------------------------------------------- def __init__(self, ctaEngine, setting): """Constructor""" super(BollChannelStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(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.bg.updateTick(tick) #---------------------------------------------------------------------- def onBar(self, bar): """收到Bar推送(必须由用户继承实现)""" self.bg.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.saveSyncData() # 发出状态更新事件 self.putEvent() #---------------------------------------------------------------------- def onOrder(self, order): """收到委托变化推送(必须由用户继承实现)""" pass #---------------------------------------------------------------------- def onTrade(self, trade): """成交推送""" # 发出状态更新事件 self.putEvent() #---------------------------------------------------------------------- def onStopOrder(self, so): """停止单推送""" pass
class DoubleMaStrategy(CtaTemplate): """双指数均线策略Demo""" className = 'DoubleMaStrategy' author = u'用Python的交易员' # 策略参数 fastWindow = 10 # 快速均线参数 slowWindow = 60 # 慢速均线参数 initDays = 10 # 初始化数据所用的天数 # 策略变量 fastMa0 = EMPTY_FLOAT # 当前最新的快速EMA fastMa1 = EMPTY_FLOAT # 上一根的快速EMA slowMa0 = EMPTY_FLOAT slowMa1 = EMPTY_FLOAT # 参数列表,保存了参数的名称 paramList = [ 'name', 'className', 'author', 'vtSymbol', 'fastWindow', 'slowWindow' ] # 变量列表,保存了变量的名称 varList = [ 'inited', 'trading', 'pos', 'fastMa0', 'fastMa1', 'slowMa0', 'slowMa1' ] # 同步列表,保存了需要保存到数据库的变量名称 syncList = ['pos'] #---------------------------------------------------------------------- def __init__(self, ctaEngine, setting): """Constructor""" super(DoubleMaStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar) self.am = ArrayManager() # self.bot = Bot(cache_path=True) # self.friend = self.bot.groups().search(u'信息通知群')[0] # 注意策略类中的可变对象属性(通常是list和dict等),在策略初始化时需要重新创建, # 否则会出现多个策略实例之间数据共享的情况,有可能导致潜在的策略逻辑错误风险, # 策略类中的这些可变对象属性可以选择不写,全都放在__init__下面,写主要是为了阅读 # 策略时方便(更多是个编程习惯的选择) #---------------------------------------------------------------------- def onInit(self): """初始化策略(必须由用户继承实现)""" self.writeCtaLog(u'双EMA演示策略初始化') initData = self.loadBar(self.initDays) for bar in initData: self.onBar(bar) self.putEvent() #---------------------------------------------------------------------- def onStart(self): """启动策略(必须由用户继承实现)""" self.writeCtaLog(u'双EMA演示策略启动') self.putEvent() #---------------------------------------------------------------------- def onStop(self): """停止策略(必须由用户继承实现)""" self.writeCtaLog(u'双EMA演示策略停止') self.putEvent() #---------------------------------------------------------------------- def onTick(self, tick): """收到行情TICK推送(必须由用户继承实现)""" self.bg.updateTick(tick) #---------------------------------------------------------------------- def onBar(self, bar): """收到Bar推送(必须由用户继承实现)""" print('double ma receive: ' + bar.time + ' :' + "{0:.2f}".format(bar.close)) # self.friend.send('double ma receive: ' + bar.time + ' : ' + bar.vtSymbol + " {0:.2f}".format(bar.close)) am = self.am am.updateBar(bar) if not am.inited: return # 计算快慢均线 fastMa = am.sma(self.fastWindow, array=True) self.fastMa0 = fastMa[-1] self.fastMa1 = fastMa[-2] slowMa = am.sma(self.slowWindow, array=True) self.slowMa0 = slowMa[-1] self.slowMa1 = slowMa[-2] # 判断买卖 crossOver = self.fastMa0 > self.slowMa0 and self.fastMa1 < self.slowMa1 # 金叉上穿 crossBelow = self.fastMa0 < self.slowMa0 and self.fastMa1 > self.slowMa1 # 死叉下穿 # 金叉和死叉的条件是互斥 # 所有的委托均以K线收盘价委托(这里有一个实盘中无法成交的风险,考虑添加对模拟市价单类型的支持) if crossOver: # 如果金叉时手头没有持仓,则直接做多 if self.pos == 0: self.buy(bar.close, 1) # 如果有空头持仓,则先平空,再做多 elif self.pos < 0: self.cover(bar.close, 1) self.buy(bar.close, 1) # 死叉和金叉相反 elif crossBelow: if self.pos == 0: self.short(bar.close, 1) elif self.pos > 0: self.sell(bar.close, 1) self.short(bar.close, 1) # 发出状态更新事件 self.putEvent() #---------------------------------------------------------------------- def onOrder(self, order): """收到委托变化推送(必须由用户继承实现)""" # 对于无需做细粒度委托控制的策略,可以忽略onOrder pass #---------------------------------------------------------------------- def onTrade(self, trade): """收到成交推送(必须由用户继承实现)""" # 对于无需做细粒度委托控制的策略,可以忽略onOrder pass #---------------------------------------------------------------------- def onStopOrder(self, so): """停止单推送""" pass
class AtrRsiStrategy(CtaTemplate): """结合ATR和RSI指标的一个分钟线交易策略""" className = 'AtrRsiStrategy' author = u'用Python的交易员' # 策略参数 atrLength = 22 # 计算ATR指标的窗口数 atrMaLength = 10 # 计算ATR均线的窗口数 rsiLength = 5 # 计算RSI的窗口数 rsiEntry = 16 # RSI的开仓信号 trailingPercent = 0.8 # 百分比移动止损 initDays = 10 # 初始化数据所用的天数 fixedSize = 1 # 每次交易的数量 # 策略变量 atrValue = 0 # 最新的ATR指标数值 atrMa = 0 # ATR移动平均的数值 rsiValue = 0 # RSI指标的数值 rsiBuy = 0 # RSI买开阈值 rsiSell = 0 # RSI卖开阈值 intraTradeHigh = 0 # 移动止损用的持仓期内最高价 intraTradeLow = 0 # 移动止损用的持仓期内最低价 # 参数列表,保存了参数的名称 paramList = ['name', 'className', 'author', 'vtSymbol', 'atrLength', 'atrMaLength', 'rsiLength', 'rsiEntry', 'trailingPercent'] # 变量列表,保存了变量的名称 varList = ['inited', 'trading', 'pos', 'atrValue', 'atrMa', 'rsiValue', 'rsiBuy', 'rsiSell'] # 同步列表,保存了需要保存到数据库的变量名称 syncList = ['pos', 'intraTradeHigh', 'intraTradeLow'] #---------------------------------------------------------------------- def __init__(self, ctaEngine, setting): """Constructor""" super(AtrRsiStrategy, self).__init__(ctaEngine, setting) # 创建K线合成器对象 self.bg = BarGenerator(self.onBar) self.am = ArrayManager() # 注意策略类中的可变对象属性(通常是list和dict等),在策略初始化时需要重新创建, # 否则会出现多个策略实例之间数据共享的情况,有可能导致潜在的策略逻辑错误风险, # 策略类中的这些可变对象属性可以选择不写,全都放在__init__下面,写主要是为了阅读 # 策略时方便(更多是个编程习惯的选择) #---------------------------------------------------------------------- def onInit(self): """初始化策略(必须由用户继承实现)""" self.writeCtaLog(u'%s策略初始化' %self.name) # 初始化RSI入场阈值 self.rsiBuy = 50 + self.rsiEntry self.rsiSell = 50 - self.rsiEntry # 载入历史数据,并采用回放计算的方式初始化策略数值 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.bg.updateTick(tick) #---------------------------------------------------------------------- def onBar(self, bar): """收到Bar推送(必须由用户继承实现)""" self.cancelAll() # 保存K线数据 am = self.am am.updateBar(bar) if not am.inited: return # 计算指标数值 atrArray = am.atr(self.atrLength, array=True) self.atrValue = atrArray[-1] self.atrMa = atrArray[-self.atrMaLength:].mean() self.rsiValue = am.rsi(self.rsiLength) # 判断是否要进行交易 # 当前无仓位 if self.pos == 0: self.intraTradeHigh = bar.high self.intraTradeLow = bar.low # ATR数值上穿其移动平均线,说明行情短期内波动加大 # 即处于趋势的概率较大,适合CTA开仓 if self.atrValue > self.atrMa: # 使用RSI指标的趋势行情时,会在超买超卖区钝化特征,作为开仓信号 if self.rsiValue > self.rsiBuy: # 这里为了保证成交,选择超价5个整指数点下单 self.buy(bar.close+5, self.fixedSize) elif self.rsiValue < self.rsiSell: self.short(bar.close-5, self.fixedSize) # 持有多头仓位 elif self.pos > 0: # 计算多头持有期内的最高价,以及重置最低价 self.intraTradeHigh = max(self.intraTradeHigh, bar.high) self.intraTradeLow = bar.low # 计算多头移动止损 longStop = self.intraTradeHigh * (1-self.trailingPercent/100) # 发出本地止损委托 self.sell(longStop, abs(self.pos), stop=True) # 持有空头仓位 elif self.pos < 0: self.intraTradeLow = min(self.intraTradeLow, bar.low) self.intraTradeHigh = bar.high shortStop = self.intraTradeLow * (1+self.trailingPercent/100) self.cover(shortStop, abs(self.pos), stop=True) # 同步数据到数据库 self.saveSyncData() # 发出状态更新事件 self.putEvent() #---------------------------------------------------------------------- def onOrder(self, order): """收到委托变化推送(必须由用户继承实现)""" pass #---------------------------------------------------------------------- def onTrade(self, trade): # 发出状态更新事件 self.putEvent() #---------------------------------------------------------------------- def onStopOrder(self, so): """停止单推送""" pass
class MultiTimeframeStrategy(CtaTemplate): """跨时间周期交易策略""" className = 'MultiTimeframeStrategy' author = u'用Python的交易员' # 策略参数 rsiSignal = 20 # RSI信号阈值 rsiWindow = 14 # RSI窗口 fastWindow = 5 # 快速均线窗口 slowWindow = 20 # 慢速均线窗口 initDays = 10 # 初始化数据所用的天数 fixedSize = 1 # 每次交易的数量 # 策略变量 rsiValue = 0 # RSI指标的数值 rsiLong = 0 # RSI买开阈值 rsiShort = 0 # RSI卖开阈值 fastMa = 0 # 5分钟快速均线 slowMa = 0 # 5分钟慢速均线 maTrend = 0 # 均线趋势,多头1,空头-1 # 参数列表,保存了参数的名称 paramList = [ 'name', 'className', 'author', 'vtSymbol', 'rsiSignal', 'rsiWindow', 'fastWindow', 'slowWindow' ] # 变量列表,保存了变量的名称 varList = [ 'inited', 'trading', 'pos', 'rsiValue', 'rsiLong', 'rsiShort', 'fastMa', 'slowMa', 'maTrend' ] # 同步列表,保存了需要保存到数据库的变量名称 syncList = ['pos'] #---------------------------------------------------------------------- def __init__(self, ctaEngine, setting): """Constructor""" super(MultiTimeframeStrategy, self).__init__(ctaEngine, setting) self.rsiLong = 50 + self.rsiSignal self.rsiShort = 50 - self.rsiSignal # 创建K线合成器对象 self.bg5 = BarGenerator(self.onBar, 5, self.on5MinBar) self.am5 = ArrayManager() self.bg15 = BarGenerator(self.onBar, 15, self.on15MinBar) self.am15 = 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推送(必须由用户继承实现)""" # 只需要要在一个BarGenerator中合成1分钟K线 self.bg5.updateTick(tick) #---------------------------------------------------------------------- def onBar(self, bar): """收到Bar推送(必须由用户继承实现)""" # 基于15分钟判断趋势过滤,因此先更新 self.bg15.updateBar(bar) # 基于5分钟判断 self.bg5.updateBar(bar) #---------------------------------------------------------------------- def on5MinBar(self, bar): """5分钟K线""" self.cancelAll() # 保存K线数据 self.am5.updateBar(bar) if not self.am5.inited: return # 如果15分钟数据尚未初始化完毕,则直接返回 if not self.maTrend: return # 计算指标数值 self.rsiValue = self.am5.rsi(self.rsiWindow) # 判断是否要进行交易 # 当前无仓位 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) # 持有多头仓位 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
class DualThrustStrategy(CtaTemplate): """DualThrust交易策略""" className = 'DualThrustStrategy' author = u'用Python的交易员' # 策略参数 fixedSize = 100 k1 = 0.4 k2 = 0.6 initDays = 10 # 策略变量 barList = [] # K线对象的列表 dayOpen = 0 dayHigh = 0 dayLow = 0 range = 0 longEntry = 0 shortEntry = 0 exitTime = time(hour=14, minute=55) longEntered = False shortEntered = False # 参数列表,保存了参数的名称 paramList = ['name', 'className', 'author', 'vtSymbol', 'k1', 'k2'] # 变量列表,保存了变量的名称 varList = ['inited', 'trading', 'pos', 'range', 'longEntry', 'shortEntry', 'exitTime'] # 同步列表,保存了需要保存到数据库的变量名称 syncList = ['pos'] #---------------------------------------------------------------------- def __init__(self, ctaEngine, setting): """Constructor""" super(DualThrustStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar) self.barList = [] #---------------------------------------------------------------------- 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.bg.updateTick(tick) #---------------------------------------------------------------------- def onBar(self, bar): """收到Bar推送(必须由用户继承实现)""" # 撤销之前发出的尚未成交的委托(包括限价单和停止单) self.cancelAll() # 计算指标数值 self.barList.append(bar) if len(self.barList) <= 2: return else: self.barList.pop(0) lastBar = self.barList[-2] # 新的一天 if lastBar.datetime.date() != bar.datetime.date(): # 如果已经初始化 if self.dayHigh: self.range = self.dayHigh - self.dayLow self.longEntry = bar.open + self.k1 * self.range self.shortEntry = bar.open - self.k2 * self.range self.dayOpen = bar.open self.dayHigh = bar.high self.dayLow = bar.low self.longEntered = False self.shortEntered = False else: self.dayHigh = max(self.dayHigh, bar.high) self.dayLow = min(self.dayLow, bar.low) # 尚未到收盘 if not self.range: return if bar.datetime.time() < self.exitTime: if self.pos == 0: if bar.close > self.dayOpen: if not self.longEntered: self.buy(self.longEntry, self.fixedSize, stop=True) else: if not self.shortEntered: self.short(self.shortEntry, self.fixedSize, stop=True) # 持有多头仓位 elif self.pos > 0: self.longEntered = True # 多头止损单 self.sell(self.shortEntry, self.fixedSize, stop=True) # 空头开仓单 if not self.shortEntered: self.short(self.shortEntry, self.fixedSize, stop=True) # 持有空头仓位 elif self.pos < 0: self.shortEntered = True # 空头止损单 self.cover(self.longEntry, self.fixedSize, stop=True) # 多头开仓单 if not self.longEntered: self.buy(self.longEntry, self.fixedSize, stop=True) # 收盘平仓 else: if self.pos > 0: self.sell(bar.close * 0.99, abs(self.pos)) elif self.pos < 0: self.cover(bar.close * 1.01, abs(self.pos)) # 发出状态更新事件 self.putEvent() #---------------------------------------------------------------------- def onOrder(self, order): """收到委托变化推送(必须由用户继承实现)""" pass #---------------------------------------------------------------------- def onTrade(self, trade): # 发出状态更新事件 self.putEvent() #---------------------------------------------------------------------- def onStopOrder(self, so): """停止单推送""" pass
def __init__(self, ctaEngine, setting): """Constructor""" super(DualThrustStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar) self.barList = []
class KkStrategy(CtaTemplate): """基于King Keltner通道的交易策略""" className = 'KkStrategy' author = u'用Python的交易员' # 策略参数 kkLength = 11 # 计算通道中值的窗口数 kkDev = 1.6 # 计算通道宽度的偏差 trailingPrcnt = 0.8 # 移动止损 initDays = 10 # 初始化数据所用的天数 fixedSize = 1 # 每次交易的数量 # 策略变量 kkUp = 0 # KK通道上轨 kkDown = 0 # KK通道下轨 intraTradeHigh = 0 # 持仓期内的最高点 intraTradeLow = 0 # 持仓期内的最低点 buyOrderIDList = [] # OCO委托买入开仓的委托号 shortOrderIDList = [] # OCO委托卖出开仓的委托号 orderList = [] # 保存委托代码的列表 # 参数列表,保存了参数的名称 paramList = [ 'name', 'className', 'author', 'vtSymbol', 'kkLength', 'kkDev' ] # 变量列表,保存了变量的名称 varList = ['inited', 'trading', 'pos', 'kkUp', 'kkDown'] # 同步列表,保存了需要保存到数据库的变量名称 syncList = ['pos', 'intraTradeHigh', 'intraTradeLow'] #---------------------------------------------------------------------- def __init__(self, ctaEngine, setting): """Constructor""" super(KkStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar, 5, self.onFiveBar) # 创建K线合成器对象 self.am = ArrayManager() self.buyOrderIDList = [] self.shortOrderIDList = [] self.orderList = [] #---------------------------------------------------------------------- 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.bg.updateTick(tick) #---------------------------------------------------------------------- def onBar(self, bar): """收到Bar推送(必须由用户继承实现)""" self.bg.updateBar(bar) #---------------------------------------------------------------------- def onFiveBar(self, bar): """收到5分钟K线""" # 撤销之前发出的尚未成交的委托(包括限价单和停止单) for orderID in self.orderList: self.cancelOrder(orderID) self.orderList = [] # 保存K线数据 am = self.am am.updateBar(bar) if not am.inited: return # 计算指标数值 self.kkUp, self.kkDown = am.keltner(self.kkLength, self.kkDev) # 判断是否要进行交易 # 当前无仓位,发送OCO开仓委托 if self.pos == 0: self.intraTradeHigh = bar.high self.intraTradeLow = bar.low self.sendOcoOrder(self.kkUp, self.kkDown, self.fixedSize) # 持有多头仓位 elif self.pos > 0: self.intraTradeHigh = max(self.intraTradeHigh, bar.high) self.intraTradeLow = bar.low l = self.sell(self.intraTradeHigh * (1 - self.trailingPrcnt / 100), abs(self.pos), True) self.orderList.extend(l) # 持有空头仓位 elif self.pos < 0: self.intraTradeHigh = bar.high self.intraTradeLow = min(self.intraTradeLow, bar.low) l = self.cover(self.intraTradeLow * (1 + self.trailingPrcnt / 100), abs(self.pos), True) self.orderList.extend(l) # 同步数据到数据库 self.saveSyncData() # 发出状态更新事件 self.putEvent() #---------------------------------------------------------------------- def onOrder(self, order): """收到委托变化推送(必须由用户继承实现)""" pass #---------------------------------------------------------------------- def onTrade(self, trade): if self.pos != 0: # 多头开仓成交后,撤消空头委托 if self.pos > 0: for shortOrderID in self.shortOrderIDList: self.cancelOrder(shortOrderID) # 反之同样 elif self.pos < 0: for buyOrderID in self.buyOrderIDList: self.cancelOrder(buyOrderID) # 移除委托号 for orderID in (self.buyOrderIDList + self.shortOrderIDList): if orderID in self.orderList: self.orderList.remove(orderID) # 发出状态更新事件 self.putEvent() #---------------------------------------------------------------------- def sendOcoOrder(self, buyPrice, shortPrice, volume): """ 发送OCO委托 OCO(One Cancel Other)委托: 1. 主要用于实现区间突破入场 2. 包含两个方向相反的停止单 3. 一个方向的停止单成交后会立即撤消另一个方向的 """ # 发送双边的停止单委托,并记录委托号 self.buyOrderIDList = self.buy(buyPrice, volume, True) self.shortOrderIDList = self.short(shortPrice, volume, True) # 将委托号记录到列表中 self.orderList.extend(self.buyOrderIDList) self.orderList.extend(self.shortOrderIDList) #---------------------------------------------------------------------- def onStopOrder(self, so): """停止单推送""" pass