tune backtestEngine

This commit is contained in:
msincenselee 2015-10-10 17:08:13 +08:00
parent ec429b62f6
commit 019dc69bf2
5 changed files with 110 additions and 27 deletions

View File

@ -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)
#----------------------------------------------------------------------

View File

@ -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):

View File

@ -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 = {}

View File

@ -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()

View File

@ -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):
"""撤单"""