diff --git a/vn.strategy/strategyEngine.py b/vn.strategy/strategyEngine.py index 1ea38ff7..0e7e4d6c 100644 --- a/vn.strategy/strategyEngine.py +++ b/vn.strategy/strategyEngine.py @@ -429,8 +429,13 @@ class StrategyEngine(object): #---------------------------------------------------------------------- def __registerEvent(self): """注册事件监听""" + #注册订阅行情数据更新事件 self.__eventEngine.register(EVENT_MARKETDATA, self.__updateMarketData) + + #注册订阅订单更新事件 self.__eventEngine.register(EVENT_ORDER, self.__updateOrder) + + #注册订阅交易响应事件 self.__eventEngine.register(EVENT_TRADE ,self.__updateTrade) #---------------------------------------------------------------------- diff --git a/vn.strategy/strategydemo/backtestingEngine.py b/vn.strategy/strategydemo/backtestingEngine.py index 1d484059..c3d82544 100644 --- a/vn.strategy/strategydemo/backtestingEngine.py +++ b/vn.strategy/strategydemo/backtestingEngine.py @@ -11,6 +11,7 @@ from datetime import datetime, timedelta, time from strategyEngine import * + ######################################################################## class LimitOrder(object): """限价单对象""" @@ -252,9 +253,16 @@ class BacktestingEngine(object): #---------------------------------------------------------------------- def startBacktesting(self): """开始回测""" - self.writeLog(u'开始回测') - + + ISOTIMEFORMAT = '%Y-%m-%d %X' + + t1 = datetime.now() + + self.writeLog(u'开始回测,{0}'.format(str(t1 ))) + for data in self.listDataHistory: + + # 记录最新的TICK数据 self.currentData = data @@ -267,8 +275,11 @@ class BacktestingEngine(object): self.strategyEngine.updateMarketData(event) self.saveTradeData() - - self.writeLog(u'回测结束') + + t2 = datetime.now() + self.writeLog(u'回测结束,{0},耗时:{1}秒'.format(str(t2),(t2-t1).seconds)) + + #---------------------------------------------------------------------- def sendOrder(self, instrumentid, exchangeid, price, pricetype, volume, direction, offset): diff --git a/vn.strategy/strategydemo/demoBacktesting.py b/vn.strategy/strategydemo/demoBacktesting.py index d8cbdc4c..a849bed0 100644 --- a/vn.strategy/strategydemo/demoBacktesting.py +++ b/vn.strategy/strategydemo/demoBacktesting.py @@ -24,7 +24,7 @@ if __name__ == '__main__': be.connectMysql() #be.loadMongoDataHistory(symbol, datetime(2015,5,1), datetime.today()) #be.loadMongoDataHistory(symbol, datetime(2012,1,9), datetime(2012,1,14)) - be.loadMysqlDataHistory(symbol, datetime(2012,1,9), datetime(2012,1,20)) + be.loadMysqlDataHistory(symbol, datetime(2012,1,9), datetime(2012,3,30)) # 创建策略对象 setting = {} diff --git a/vn.strategy/strategydemo/demoStrategy.py b/vn.strategy/strategydemo/demoStrategy.py index 5a7269ea..4d8d449b 100644 --- a/vn.strategy/strategydemo/demoStrategy.py +++ b/vn.strategy/strategydemo/demoStrategy.py @@ -126,7 +126,7 @@ class SimpleEmaStrategy(StrategyTemplate): #tick.upperLimit = data['UpperLimitPrice'] #tick.lowerLimit = data['LowerLimitPrice'] - + tick.time = data['UpdateTime'] #tick.ms = data['UpdateMillisec'] #tick.time = UpdateTime @@ -254,19 +254,28 @@ class SimpleEmaStrategy(StrategyTemplate): # 如果当前手头无仓位,则直接做多 if self.pos == 0: # 涨停价买入开仓 - self.buy(self.currentTick.upperLimit, 1) + # Modified by Incense Lee :回测时,Tick数据中没有涨停价,只能使用当前价 + #self.buy(self.currentTick.upperLimit, 1) + self.buy(self.currentTick.lastPrice, 1) # 手头有空仓,则先平空,再开多 elif self.pos < 0: - self.cover(self.currentTick.upperLimit, 1) - self.buy(self.currentTick.upperLimit, 1) + #self.cover(self.currentTick.upperLimit, 1) + self.cover(self.currentTick.lastPrice, 1) + #self.buy(self.currentTick.upperLimit, 1) + self.buy(self.currentTick.lastPrice, 1) # 反之,做空 elif self.fastEMA < self.slowEMA: if self.pos == 0: - self.short(self.currentTick.lowerLimit, 1) + # Modified by Incense Lee :回测时,Tick数据中没有最低价价,只能使用当前价 + #self.short(self.currentTick.lowerLimit, 1) + self.short(self.currentTick.lastPrice, 1) elif self.pos > 0: - self.sell(self.currentTick.lowerLimit, 1) - self.short(self.currentTick.lowerLimit, 1) + #self.sell(self.currentTick.lowerLimit, 1) + self.sell(self.currentTick.lastPrice, 1) + + #self.short(self.currentTick.lowerLimit, 1) + self.short(self.currentTick.lastPrice, 1) # 记录日志 log = self.name + u',K线时间:' + str(time) + '\n' + \ @@ -322,7 +331,8 @@ def main(): setting = {} setting['fastAlpha'] = 0.2 setting['slowAlpha'] = 0.05 - se.createStrategy(u'EMA演示策略', 'IF1506', SimpleEmaStrategy, setting) + #se.createStrategy(u'EMA演示策略', 'IF1506', SimpleEmaStrategy, setting) + se.createStrategy(u'EMA演示策略', 'a', SimpleEmaStrategy, setting) # 启动所有策略 se.startAll() diff --git a/vn.strategy/strategydemo/strategyEngine.py b/vn.strategy/strategydemo/strategyEngine.py index f304d80d..390da8b3 100644 --- a/vn.strategy/strategydemo/strategyEngine.py +++ b/vn.strategy/strategydemo/strategyEngine.py @@ -329,7 +329,7 @@ class StrategyEngine(object): self.writeLog(u'MysqlDB未连接,请检查') except MySQLdb.Error, e: - self.writeLog(u'MysqlDB载入数据失败,请检查.Error {0}: {1}'.format(e.arg[0],e.arg[1])) + self.writeLog(u'MysqlDB载入数据失败,请检查.Error %d: %s'.format(e.arg[0],e.arg[1])) td = timedelta(days=3) @@ -406,6 +406,7 @@ class StrategyEngine(object): if not self.backtesting: #self.__recordTickToMongo(data) self.__recordTickToMysql(data) + #---------------------------------------------------------------------- def __processStopOrder(self, tick): """处理停止单""" @@ -416,6 +417,9 @@ class StrategyEngine(object): # 如果当前有该合约上的止损单 if symbol in self.__dictStopOrder: + + print u'strategyEngine.py __processStopOrder() has stop order.' + # 获取止损单列表 listSO = self.__dictStopOrder[symbol] # SO:stop order @@ -426,6 +430,7 @@ class StrategyEngine(object): # 如果是买入停止单,且最新成交价大于停止触发价 if so.direction == DIRECTION_BUY and lastPrice >= so.price: # 以当日涨停价发出限价单买入 + print u'sendOrder({0},{1},{2},{3},{4}'.format(symbol,'Direction_Buy',so.offset,upperLimit,so.volume) ref = self.sendOrder(symbol, DIRECTION_BUY, so.offset, upperLimit, so.volume, strategy) @@ -437,6 +442,7 @@ class StrategyEngine(object): # 如果是卖出停止单,且最新成交价小于停止触发价 elif so.direction == DIRECTION_SELL and lastPrice <= so.price: + print u'sendOrder({0},{1},{2},{3},{4}'.format(symbol,'Direction_Sell',so.offset,upperLimit,so.volume) ref = self.sendOrder(symbol, DIRECTION_SELL, so.offset, lowerLimit, so.volume, strategy) @@ -452,10 +458,15 @@ class StrategyEngine(object): # 检查停止单列表是否为空,若为空,则从停止单字典中移除该合约代码 if not listSO: del self.__dictStopOrder[symbol] - + + + #---------------------------------------------------------------------- def updateOrder(self, event): - """报单更新""" + """事件响应:报单更新""" + + #print u'strategyEngine.py updateOrder() begin.' + data = event.dict_['data'] orderRef = data['OrderRef'] @@ -485,10 +496,14 @@ class StrategyEngine(object): # 记录该Order的数据 self.__dictOrder[orderRef] = data - + + #print u'strategyEngine.py updateOrder() end.' + #---------------------------------------------------------------------- def updateTrade(self, event): - """成交更新""" + """事件响应:成交更新""" + + #print u'strategyEngine.py updateTrade() begin.' data = event.dict_['data'] orderRef = data['OrderRef'] @@ -507,8 +522,10 @@ class StrategyEngine(object): # 推送给策略 strategy = self.__dictOrderRefStrategy[orderRef] - strategy.onTrade(trade) - + strategy.onTrade(trade) + + #print u'strategyEngine.py updateTrade() end.' + #---------------------------------------------------------------------- def sendOrder(self, symbol, direction, offset, price, volume, strategy): """ @@ -520,9 +537,12 @@ class StrategyEngine(object): volume:下单手数 strategy:策略对象 """ + + #print u'strategyEngine.py sendOrder() begin.' contract = self.mainEngine.selectInstrument(symbol) if contract: + #放入事件引擎 ref = self.mainEngine.sendOrder(symbol, contract['ExchangeID'], price, @@ -532,7 +552,9 @@ class StrategyEngine(object): offset) self.__dictOrderRefStrategy[ref] = strategy - + + #print u'strategyEngine.py sendOrder() end.' + return ref #---------------------------------------------------------------------- @@ -540,6 +562,7 @@ class StrategyEngine(object): """ 撤单 """ + print u'strategyEngine.py cancelOrder() begin.' order = self.__dictOrder[orderRef] symbol = order['InstrumentID'] contract = self.mainEngine.selectInstrument(symbol) @@ -550,12 +573,20 @@ class StrategyEngine(object): orderRef, order['FrontID'], order['SessionID']) - + + print u'strategyEngine.py cancelOrder() end.' + #---------------------------------------------------------------------- def __registerEvent(self): """注册事件监听""" + + #注册订阅行情数据更新事件 self.__eventEngine.register(EVENT_MARKETDATA, self.updateMarketData) + + #注册订阅订单更新事件 self.__eventEngine.register(EVENT_ORDER, self.updateOrder) + + #注册订阅交易响应事件 self.__eventEngine.register(EVENT_TRADE ,self.updateTrade) #---------------------------------------------------------------------- @@ -568,6 +599,7 @@ class StrategyEngine(object): #---------------------------------------------------------------------- def registerStrategy(self, symbol, strategy): """注册策略对合约TICK数据的监听""" + print u'strategyEngine.py registerStrategy() begin.' # 尝试获取监听该合约代码的策略的列表,若无则创建 try: listStrategy = self.__dictSymbolStrategy[symbol] @@ -579,6 +611,8 @@ class StrategyEngine(object): if strategy not in listStrategy: listStrategy.append(strategy) + print u'strategyEngine.py registerStrategy() end.' + #---------------------------------------------------------------------- def placeStopOrder(self, symbol, direction, offset, price, volume, strategy): """ @@ -586,6 +620,8 @@ class StrategyEngine(object): 注意这里的price是停止单的触发价 """ # 创建止损单对象 + print u'strategyEngine.py placeStopOrder() begin.' + so = StopOrder(symbol, direction, offset, price, volume, strategy) # 获取该合约相关的止损单列表 @@ -597,12 +633,17 @@ class StrategyEngine(object): # 将该止损单插入列表中 listSO.append(so) - + + print u'strategyEngine.py placeStopOrder() end.' + return so #---------------------------------------------------------------------- def cancelStopOrder(self, so): """撤销停止单""" + + print u'strategyEngine.py cancelStopOrder() begin.' + symbol = so.symbol try: @@ -615,6 +656,8 @@ class StrategyEngine(object): del self.__dictStopOrder[symbol] except KeyError: pass + + print u'strategyEngine.py cancelStopOrder() end.' #---------------------------------------------------------------------- def startAll(self): @@ -700,6 +743,8 @@ class StrategyTemplate(object): #---------------------------------------------------------------------- def buy(self, price, volume, stopOrder=False): """买入开仓""" + print u'strategyEngine.py StrategyTemplate({3}) buy() begin. symbol:{0}, price:{1},volume:{2}'.format(self.symbol, price, volume, self.name) + if self.trading: if stopOrder: so = self.engine.placeStopOrder(self.symbol, DIRECTION_BUY, @@ -711,10 +756,15 @@ class StrategyTemplate(object): return ref else: return None - + + #print (u'strategyEngine.py buy() end.') + #---------------------------------------------------------------------- def cover(self, price, volume, stopOrder=False): """买入平仓""" + + print u'strategyEngine.py StrategyTemplate({3}) cover() begin. symbol:{0}, price:{1},volume:{2}'.format(self.symbol, price, volume, self.name) + if self.trading: if stopOrder: so = self.engine.placeStopOrder(self.symbol, DIRECTION_BUY, @@ -726,10 +776,14 @@ class StrategyTemplate(object): return ref else: return None - + print (u'strategyEngine.py cover() end.') + #---------------------------------------------------------------------- def sell(self, price, volume, stopOrder=False): """卖出平仓""" + + print u'strategyEngine.py StrategyTemplate({3}) sell() begin. symbol:{0}, price:{1},volume:{2}'.format(self.symbol, price, volume, self.name) + if self.trading: if stopOrder: so = self.engine.placeStopOrder(self.symbol, DIRECTION_SELL, @@ -741,10 +795,12 @@ class StrategyTemplate(object): return ref else: return None - + #print u'strategyEngine.py sell() end.' + #---------------------------------------------------------------------- def short(self, price, volume, stopOrder=False): """卖出开仓""" + print u'strategyEngine.py StrategyTemplate({3}) short() begin. symbol:{0}, price:{1},volume:{2}'.format(self.symbol, price, volume, self.name) if self.trading: if stopOrder: so = self.engine.placeStopOrder(self.symbol, DIRECTION_SELL, @@ -756,7 +812,8 @@ class StrategyTemplate(object): return ref else: return None - + #print u'strategyEngine.py short() end.' + #---------------------------------------------------------------------- def cancelOrder(self, orderRef): """撤单"""