def __init__(self, ctaEngine, setting): """Constructor""" super(DualThrust_IntraDayStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar, onDayBar=self.ondayBar) self.am = ArrayManager() self.barList = []
def __init__(self, ctaEngine, setting): """Constructor""" super(DoubleMaStrategy, self).__init__(ctaEngine, setting) # self.bg = BarGenerator(self.onBar) self.bg = BarGenerator(self.onBar, 5, self.onFiveBar) # 创建K线合成器对象 self.am = ArrayManager(10)
def __init__(self): """Constructor""" super(AtrSignal, self).__init__() self.atrWindow = 30 self.bg = BarGenerator(self.onBar, 15, self.on15Bar) self.am = ArrayManager() self.atrValue = 0.0
def __init__(self, ctaEngine, setting): """Constructor""" super(Turtle01Strategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar,onDayBar = self.ondayBar) self.am = ArrayManager(max(self.longDays,self.shortDays,self.atrDays)+1) self.barList = []
def __init__(self, ctaEngine, setting): """Constructor""" super(tempStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar) self.am = ArrayManager() self.lastzhibiao = zhibiao(0, 0, 0) self.celve0 = zerocelve() # self.celve1 = ceshi() self.tickCelvezu = [self.celve0] self.barCelvezu = [self.celve0] self.tickadd = 1 #断网恢复变量 self.stopcount = None #交易时间和监控联网状态变量 self.yepan = False self.yepanhour = None self.yepanminute = None self.lastbardatetime = None self.tradetime = None #控制开仓和平仓稳定变量 self.tradecount = 0 self.tradingcelve = [self.celve0]
def __init__(self, ctaEngine, setting): """Constructor""" super(DoubleMaStrategyWh, self).__init__(ctaEngine, setting) self.initDays = self.SK_E_LONG + self.SK_E_DAYS_LONG self.bg = BarGenerator(self.onBar) self.am = ArrayManager(self.initDays) self.strategyStartpos = 1891 self.strategyEndpos = 2357 self.all_bar = [] # 注意策略类中的可变对象属性(通常是list和dict等),在策略初始化时需要重新创建, # 否则会出现多个策略实例之间数据共享的情况,有可能导致潜在的策略逻辑错误风险, # 策略类中的这些可变对象属性可以选择不写,全都放在__init__下面,写主要是为了阅读 # 策略时方便(更多是个编程习惯的选择) self.SK_A_ma0 = EMPTY_FLOAT self.SK_A_ma1 = EMPTY_FLOAT self.SK_A_close1 = EMPTY_FLOAT self.BARSLAST_CR_UP_SK_A_LONG = EMPTY_INT_WH self.BARSLAST_CR_DOWN_SK_A_LONG = EMPTY_INT_WH self.BARSLAST_CR_UP_SK_E_LONG = EMPTY_INT_WH self.BARSLAST_CR_DOWN_SK_E_LONG = EMPTY_INT_WH self.BKPRICE = EMPTY_FLOAT_WH self.SKPRICE = EMPTY_FLOAT_WH self.SK_E_ma0 = EMPTY_FLOAT self.SK_E_ma1 = EMPTY_FLOAT self.BP_style = 0000
def __init__(self, ctaEngine, setting): """Constructor""" super(strategy_Volatility_RB, self).__init__(ctaEngine, setting) self.initDays = max(self.BK_BEFORE_DAY, self.SK_BEFORE_DAY) # 初始化数据所用的天数 self.bg = BarGenerator(self.onBar) self.am = ArrayManager(self.initDays) self.strategyStartpos = 1890 self.strategyEndpos = 2358 self.all_bar = [] self.SP_style = 0000 self.BP_style = 0000 self.BKPRICE = EMPTY_FLOAT_WH self.BKDATE = EMPTY_FLOAT_WH self.SKPRICE = EMPTY_FLOAT_WH self.SKDATE = EMPTY_FLOAT_WH self.tradeday = 0 # 注意策略类中的可变对象属性(通常是list和dict等),在策略初始化时需要重新创建, # 否则会出现多个策略实例之间数据共享的情况,有可能导致潜在的策略逻辑错误风险, # 策略类中的这些可变对象属性可以选择不写,全都放在__init__下面,写主要是为了阅读 # 策略时方便(更多是个编程习惯的选择) self.BKWeekProfit = [0, 0, 0, 0, 0, 0, 0] self.SKWeekProfit = [0, 0, 0, 0, 0, 0, 0] self.LongBestday = [0, 1, 2, 3] #[0,1,2] 20190627 self.ShortBestday = [1, 2, 3]
def __init__(self, ctaEngine, setting): """Constructor""" super(Turtle01Strategy1M, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar, xmin=3, onXminBar=self.on3MBar, onDayBar=self.ondayBar) self.am = ArrayManager( max(self.longDays, self.shortDays, self.atrDays) + 1) self.barList = [] if len(Turtle01Strategy1M.cust_Setting) > 0: for cust in Turtle01Strategy1M.cust_Setting: if cust["StrategyGroup"] == "Turtle": capAmtTurtle = float(cust["CaptialAmt"]) minBarTypeTurtle = cust["MinuteBarGen"] break elif cust["StrategyGroup"] == "Default": capAmtDefault = float(cust["CaptialAmt"]) minBarTypeDefault = cust["MinuteBarGen"] if capAmtTurtle > 0: self.capAmount = capAmtTurtle self.minBarType = minBarTypeTurtle self.unitCalcMethod = "custsetting" elif capAmtDefault > 0: self.capAmount = capAmtDefault self.minBarType = minBarTypeDefault self.unitCalcMethod = "custsetting" else: self.unitCalcMethod = "ctasetting"
def __init__(self, ctaEngine, setting): """Constructor""" super(strategyDemo, self).__init__(ctaEngine, setting) self.contractMode = 'Double' #主力合约与次主力合约模式 # self.contractMode='Dominant' #主力合约模式 self.lastOrder = None self.lastTrade = None self.tickList = [] #初始一个tick列表 self.tickListAdd = [] #初始第二个tick列表 self.bType = 0 #买的状态,1表示买开委托状态,0表示非买开委托状态.目的是判断当前委托的状态,不要发生重复发单的事情 self.sType = 0 #买的状态,1表示卖开委托状态,0表示非卖开委托状态 self.orderType = '' self.contractname = '' self.contractnameAdd = '' self.initialFlag = True self.PositionCodeList = [] self.signalGroupList = [] self.rollingDays = 0 #开单条件:远-近 价差大于10,开仓 self.isBuySign = False self.isShortSign = False self.isBuyCoverSign = False self.isShortCoverSign = False #记录价格序列 self.tickListPrice = [] self.tickListAddPrice = [] self.bg = BarGenerator(self.onBar, 5, self.onXminBar) self.am = ArrayManager()
def __init__(self, ctaEngine, setting): """Constructor""" super(DualThrustMultiContractStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar) self.barList = [] #self.syncList = if 'strParams' in setting: params = setting['strParams'] if len(params) >= 3: for p in params: if p[0] == 'unit': self.unitno = p[1] if p[0] == 'p1': self.p1 = p[1] if p[0] == 'p2': self.p2 = p[1] print(self.unitno, self.p1, self.p2) self.pos = 0 self.dayOpen = EMPTY_FLOAT self.dayHigh = EMPTY_FLOAT self.dayLow = EMPTY_FLOAT self.range = EMPTY_FLOAT self.longEntry = EMPTY_FLOAT self.shortEntry = EMPTY_FLOAT self.exitTime = time(hour=14, minute=55) self.longEntered = False self.shortEntered = False
def __init__(self, ctaEngine, setting): # 首先找到策略的父类(就是类CtaTemplate),然后把DoubleMaStrategy的对象转换为类CtaTemplate的对象 super(MultiFrameMaStrategy, self).__init__(ctaEngine, setting) # 生成仓位记录的字典 symbol = self.symbolList[0] self.Longpos = symbol.replace('.','_')+"_LONG" self.Shortpos = symbol.replace('.','_')+"_SHORT" self.bg60 = BarGenerator(self.onBar, 60, self.on60MinBar) self.bg60Dict = { sym: self.bg60 for sym in self.symbolList } self.bg15 = BarGenerator(self.onBar, 15, self.on15MinBar) self.bg15Dict = { sym: self.bg15 for sym in self.symbolList } # 生成Bar数组 self.am60Dict = { sym: ArrayManager(size=self.slowWindow+10) for sym in self.symbolList } self.am15Dict = { sym: ArrayManager(size=self.slowWindow+10) for sym in self.symbolList }
def __init__(self, ctaEngine, setting): """Constructor""" super(ShortTermStrategy, self).__init__(ctaEngine, setting) # 注意策略类中的可变对象属性(通常是list和dict等),在策略初始化时需要重新创建, # 否则会出现多个策略实例之间数据共享的情况,有可能导致潜在的策略逻辑错误风险, # 策略类中的这些可变对象属性可以选择不写,全都放在__init__下面,写主要是为了阅读 # 策略时方便(更多是个编程习惯的选择) self.short_term_list_first = [] self.short_term_list_all = [] self.short_term_last_three_first_index = [] self.short_term_last_two_low_all_index = [] self.short_term_last_two_high_all_index = [] self.short_term_open_last_three_first_index = [] self.short_term_open_last_two_all_index = [] self.all_bar = [] self.BK_style = EMPTY_INT_WH # 2-->所有的低点 21利用低点 22利用高点 self.SK_style = EMPTY_INT_WH # 2-->所有的高点 21利用高点 22利用低点 self.BKPRICE = EMPTY_FLOAT_WH self.SKPRICE = EMPTY_FLOAT_WH self.initDays = self.E_LONG_ALL if self.LongOrShort == True else self.SK_E_LONG_ALL self.MAXCLOSE_AFTER_OPEN = EMPTY_FLOAT_WH #建仓后close的最大值 self.strategyStartpos = 1343 self.strategyEndpos = 1826 self.SP_style = 0000 self.tradeday = 0 self.bg = BarGenerator(self.onBar) self.am = ArrayManager(self.initDays)
def __init__(self, ctaEngine, setting): """Constructor""" super(TripleMAStrategy02, self).__init__(ctaEngine, setting) self.bm = BarGenerator(self.onBar, 5, self.onFiveBar) # 由于maWindow3的长度是120,所以ArrayManager的size要增加至150 self.am = ArrayManager(size=150)
def __init__(self, ctaEngine, setting): """Constructor""" super(BollChannelStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar, 15, self.onXminBar) # 创建K线合成器对象 self.bg30 = BarGenerator(self.onBar, 30, self.on30minBar) self.am = ArrayManager()
def __init__(self, ctaEngine, setting): """Constructor""" super(AtrRsiStrategy, self).__init__(ctaEngine, setting) # 创建K线合成器对象 self.bg = BarGenerator(self.onBar) self.am = ArrayManager()
def __init__(self, ctaEngine, setting): super(MutilEMaStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar) self.am = ArrayManager() self.frequency = mtm.frequency self.pricePosi_top = 0 self.pricePosi_bot = 4 self.status = Status() self.tick = None self.locking = False self.lockActionToken = False self.unlockActionToken = False self.controlRisk = ControlRisk(security=mtm.jqdata_security, ctaEngine=self) self.strategyBase = MutilEMaStrategyBase(security=mtm.jqdata_security, status=self.status, frequency=mtm.frequency, ctaTemplate=self, enableTrade=mtm.enableTrade, enableBuy=mtm.enableBuy, enableShort=mtm.enableShort, controlRisk=self.controlRisk)
def __init__(self, ctaEngine, setting): """Constructor""" super(BollingerBotStrategy01, self).__init__(ctaEngine, setting) self.bm = BarGenerator(self.onBar, 5, self.onFiveBar) self.am = ArrayManager(30) self.orderList = [] self.entryPriceList = []
def __init__(self, ctaEngine, setting): """Constructor""" super(BollChannelStrategy01, self).__init__(ctaEngine, setting) self.bm = BarGenerator(self.onBar, 15, self.on5minBar) # 创建K线合成器对象 self.am = ArrayManager() self.entryPriceList = [] self.orderList = []
def __init__(self, ctaEngine, setting): """Constructor""" super(DoubleMaStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar) self.am = ArrayManager() self.bg15 = BarGenerator(self.onBar, 15, self.on15MinBar) self.am15 = ArrayManager()
def __init__(self, ctaEngine, setting): """Constructor""" super(strategy_AttackDay_RB, self).__init__(ctaEngine, setting) #self.initDays= self.bg = BarGenerator(self.onBar) self.am = ArrayManager(self.initDays)
def __init__(self, ctaEngine, setting): """Constructor""" super(DoubleMaStrategyWh, self).__init__(ctaEngine, setting) #self.initDays= self.bg = BarGenerator(self.onBar) self.am = ArrayManager(self.initDays)
def __init__(self, ctaEngine, setting): super(WfftStrategy, self).__init__(ctaEngine, setting) self.MinPoint = ctaEngine.getPriceTick(self) self.bg = BarGenerator(self.onBar, 5) self.wfft = WFFTStrategyWrapper(int(1)) self.wfft.setWfftSetting(self.N, self.len_, self.q, self.Tq, self.Length, self.Dq, int(self.TrailingStart), int(self.TrailingStop), float(self.MinPoint), int(self.StopLossSet))
def __init__(self, ctaEngine, setting): """Constructor""" super(KeltnerCommonStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar, onDayBar=self.ondayBar, vtSymbol=self.vtSymbol) self.am = ArrayManager() self.barList = [] # Read Parameters from Setting files if 'strParams' in setting: self.params = setting['strParams'] if len(self.params) >= 3: for p in self.params: if p[0] == 'unit': self.fixedSize = p[1] if p[0] == 'p1': self.kUpper = p[1] if p[0] == 'p2': self.kLower = p[1] if p[0] == 'p3': self.maDays = p[1] if p[0] == 'p4': self.atrDays = p[1] if p[0] == 'p5': self.initDays = p[1] if p[0] == 'p6': self.rsilen = p[1] if p[0] == 'p7': self.rsiconfig = p[1] else: # 策略参数 self.fixedSize = 1 self.kUpper = 2 self.kLower = 2 self.maDays = 13 self.atrDays = 20 self.initDays = 55 # original value is 10 self.rsiconfig = 50 self.rsilen = 21 #print(self.fixedSize,self.kUpper,self.kLower,self.maDays,self.initDays) self.atrAvg = 0 self.maHigh = 0 self.maLow = 0 self.longEntry = 0 self.shortEntry = 0 self.longExit = 0 self.shortExit = 0 #exitTime = time(hour=15, minute=20) #will not cover position when day close self.longEntered = False self.shortEntered = False self.loginterval = 15 self.logcountdown = 0
def __init__(self, ctaEngine, setting): """Constructor""" super(DualThrustStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar) self.barList = [] self.am = ArrayManager() self.baselinetime = None
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): """Constructor""" super(BollSignal, self).__init__() self.bollWindow = 18 self.bollDev = 5 # self.bollUp, self.bollDown = 0.0,0.0 self.bg = BarGenerator(self.onBar, 15, self.on15Bar) self.am = ArrayManager()
def __init__(self, ctaEngine, setting): super(WfftStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar, 5) self.am = ArrayManager() self.wfft = WFFT.pythonToCpp() self.wfft.setWfftSetting(self.N, self.len_, self.q, self.Tq, self.Length, self.Dq, int(self.TrailingStart), int(self.TrailingStop), float(self.MinPoint), int(self.StopLossSet))
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, ctaEngine, setting): """Constructor""" super(DoubleMaStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar) self.am = ArrayManager() self.lastzhibiao = zhibiao() self.celve0 = zerocelve() self.tickCelvezu = [celve0] self.barCelvezu = [celve0]
def __init__(self, ctaEngine, setting): """Constructor""" super(DT_IntraDayCommonStrategy, self).__init__(ctaEngine, setting) self.bg = BarGenerator(self.onBar, onDayBar=self.ondayBar, vtSymbol=self.vtSymbol) self.am = ArrayManager() self.barList = [] self.longEntry1 = 0 self.shortEntry1 = 0 # Read Parameters from Setting files if 'strParams' in setting: self.params = setting['strParams'] if len(self.params) >= 3: for p in self.params: if p[0] == 'unit': self.fixedSize = p[1] if p[0] == 'p1': self.k1 = p[1] if p[0] == 'p2': self.k2 = p[1] if p[0] == 'p3': self.rangeDays = p[1] if p[0] == 'p4': self.atrDays = p[1] if p[0] == 'p5': self.initDays = p[1] else: # 策略参数 self.fixedSize = 1 self.k1 = 0.4 self.k2 = 0.4 self.rangeDays = 4 self.atrDays = 20 self.initDays = 55 # original value is 10 #print(self.fixedSize,self.k1,self.k2,self.rangeDays,self.initDays) self.dayOpen = 0 self.rangeHigh = 0 self.rangeLow = 0 self.rangeHighClose = 0 self.rangeLowClose = 0 self.range1 = 0 self.range2 = 0 self.atrValue = 0 self.range = 0 self.longEntry = 0 self.shortEntry = 0 self.exitTime = time( hour=15, minute=20) #will not cover position when day close self.longEntered = False self.shortEntered = False
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 __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()
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 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)
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 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 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 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.bg30 = BarGenerator(self.onBar, 30, self.on30minBar) self.am = ArrayManager() #---------------------------------------------------------------------- def on30minBar(self, bar): """""" #---------------------------------------------------------------------- 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 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
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() # 注意策略类中的可变对象属性(通常是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推送(必须由用户继承实现)""" 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
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)
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