bug fixing

This commit is contained in:
msincenselee 2015-10-18 00:23:24 +08:00
parent 9347691f44
commit 5f3e781996
6 changed files with 259 additions and 98 deletions

View File

@ -575,7 +575,7 @@ class StrategyTemplate(object):
raise NotImplementedError raise NotImplementedError
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def buy(self, price, volume, stopOrder=False): def buy(self, price, volume, orderTime, stopOrder=False):
"""买入开仓""" """买入开仓"""
if self.trading: if self.trading:
if stopOrder: if stopOrder:
@ -584,13 +584,13 @@ class StrategyTemplate(object):
return so return so
else: else:
ref = self.engine.sendOrder(self.symbol, DIRECTION_BUY, ref = self.engine.sendOrder(self.symbol, DIRECTION_BUY,
OFFSET_OPEN, price, volume, self) OFFSET_OPEN, price, volume,orderTime, self)
return ref return ref
else: else:
return None return None
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def cover(self, price, volume, StopOrder=False): def cover(self, price, volume, orderTime, StopOrder=False):
"""买入平仓""" """买入平仓"""
if self.trading: if self.trading:
if stopOrder: if stopOrder:
@ -599,13 +599,13 @@ class StrategyTemplate(object):
return so return so
else: else:
ref = self.engine.sendOrder(self.symbol, DIRECTION_BUY, ref = self.engine.sendOrder(self.symbol, DIRECTION_BUY,
OFFSET_CLOSE, price, volume, self) OFFSET_CLOSE, price, volume,orderTime, self)
return ref return ref
else: else:
return None return None
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def sell(self, price, volume, stopOrder=False): def sell(self, price, volume, orderTime,stopOrder=False):
"""卖出平仓""" """卖出平仓"""
if self.trading: if self.trading:
if stopOrder: if stopOrder:
@ -614,13 +614,13 @@ class StrategyTemplate(object):
return so return so
else: else:
ref = self.engine.sendOrder(self.symbol, DIRECTION_SELL, ref = self.engine.sendOrder(self.symbol, DIRECTION_SELL,
OFFSET_CLOSE, price, volume, self) OFFSET_CLOSE, price, volume,orderTime, self)
return ref return ref
else: else:
return None return None
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def short(self, price, volume, stopOrder=False): def short(self, price, volume, orderTime,stopOrder=False):
"""卖出开仓""" """卖出开仓"""
if self.trading: if self.trading:
if stopOrder: if stopOrder:
@ -629,7 +629,7 @@ class StrategyTemplate(object):
return so return so
else: else:
ref = self.engine.sendOrder(self.symbol, DIRECTION_SELL, ref = self.engine.sendOrder(self.symbol, DIRECTION_SELL,
OFFSET_OPEN, price, volume, self) OFFSET_OPEN, price, volume,orderTime, self)
return ref return ref
else: else:
return None return None

View File

@ -19,14 +19,14 @@ class LimitOrder(object):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def __init__(self, symbol): def __init__(self, symbol):
"""Constructor""" """Constructor"""
self.symbol = symbol self.symbol = symbol # 报单合约
self.price = 0 self.price = 0 # 报单价格
self.volume = 0 self.volume = 0 # 报单合约数量
self.direction = None self.direction = None # 方向
self.offset = None self.offset = None # 开/平
#Modified by Incense Lee #Modified by Incense Lee
self.orderTime = datetime.now() #下单时间 self.orderTime = datetime.now() # 下单时间
######################################################################## ########################################################################
@ -40,10 +40,10 @@ class BacktestingEngine(object):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def __init__(self): def __init__(self):
"""Constructor""" """Constructor"""
self.eventEngine = EventEngine() # 实例化 self.eventEngine = EventEngine() # 实例化
# 策略引擎 # 策略引擎
self.strategyEngine = None # 通过setStrategyEngine进行设置 self.strategyEngine = None # 通过setStrategyEngine进行设置
# TICK历史数据列表由于要使用For循环来实现仿真回放 # TICK历史数据列表由于要使用For循环来实现仿真回放
# 使用list的速度比Numpy和Pandas都要更快 # 使用list的速度比Numpy和Pandas都要更快
@ -254,7 +254,7 @@ class BacktestingEngine(object):
tradeData['OffsetFlag'] = order.offset tradeData['OffsetFlag'] = order.offset
tradeData['Price'] = price tradeData['Price'] = price
tradeData['Volume'] = order.volume tradeData['Volume'] = order.volume
tradeData['TradeTime'] = order.insertTime tradeData['TradeTime'] = order.orderTime
print tradeData print tradeData
@ -271,7 +271,7 @@ class BacktestingEngine(object):
orderData['LimitPrice'] = price orderData['LimitPrice'] = price
orderData['VolumeTotalOriginal'] = order.volume orderData['VolumeTotalOriginal'] = order.volume
orderData['VolumeTraded'] = order.volume orderData['VolumeTraded'] = order.volume
orderData['InsertTime'] = '' orderData['InsertTime'] = order.orderTime
orderData['CancelTime'] = '' orderData['CancelTime'] = ''
orderData['FrontID'] = '' orderData['FrontID'] = ''
orderData['SessionID'] = '' orderData['SessionID'] = ''
@ -322,17 +322,18 @@ class BacktestingEngine(object):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def sendOrder(self, instrumentid, exchangeid, price, pricetype, volume, direction, offset, orderTime=datetime.now()): def sendOrder(self, instrumentid, exchangeid, price, pricetype, volume, direction, offset, orderTime=datetime.now()):
"""回测发单""" """回测发单"""
order = LimitOrder(instrumentid) order = LimitOrder(instrumentid) # 限价报单
order.price = price order.price = price # 报单价格
order.direction = direction order.direction = direction # 买卖方向
order.volume = volume order.volume = volume # 报单数量
order.offset = offset order.offset = offset
order.orderTime = orderTime order.orderTime = orderTime # 报单时间
self.orderRef = self.orderRef + 1 # 报单编号
self.orderRef = self.orderRef + 1
self.dictOrder[str(self.orderRef)] = order self.dictOrder[str(self.orderRef)] = order
return str(self.orderRef) return str(self.orderRef)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
@ -374,15 +375,16 @@ class BacktestingEngine(object):
def saveTradeDataToMysql(self): def saveTradeDataToMysql(self):
"""保存交易记录到mysql,added by Incense Lee""" """保存交易记录到mysql,added by Incense Lee"""
if self.__mysqlConnected: if self.__mysqlConnected:
sql='insert into BackTest.TB_Trade values ' sql='insert into BackTest.TB_Trade (Id,symbol,orderRef,tradeID,direction,offset,price,volume,tradeTime) values '
values = '' values = ''
print u'{0}条交易记录.'.format(len(self.listTrade))
for tradeItem in self.listTrade: for tradeItem in self.listTrade:
if len(values) > 0: if len(values) > 0:
values = values + ',' values = values + ','
values = values + '(\'{0}\',\'{1}\',\'{2}\',\'{3}\',\'{4}\',\'{5}\',{6},{7})'.format( values = values + '(\'{0}\',\'{1}\',{2},{3},{4},{5},{6},{7},\'{8}\')'.format(
self.Id, self.Id,
tradeItem['InstrumentID'], tradeItem['InstrumentID'],
tradeItem['OrderRef'], tradeItem['OrderRef'],
@ -390,7 +392,8 @@ class BacktestingEngine(object):
tradeItem['Direction'], tradeItem['Direction'],
tradeItem['OffsetFlag'], tradeItem['OffsetFlag'],
tradeItem['Price'], tradeItem['Price'],
tradeItem['Volume']) tradeItem['Volume'],
tradeItem['TradeTime'].strftime('%Y-%m-%d %H:%M:%S'))
cur = self.__mysqlConnection.cursor(MySQLdb.cursors.DictCursor) cur = self.__mysqlConnection.cursor(MySQLdb.cursors.DictCursor)

View File

@ -5,32 +5,30 @@ from backtestingEngine import *
from demoStrategy import SimpleEmaStrategy from demoStrategy import SimpleEmaStrategy
import decimal import decimal
def main():
"""回测程序主函数"""
# 回测脚本 # symbol = 'IF1506'
if __name__ == '__main__':
#symbol = 'IF1506'
symbol = 'a' symbol = 'a'
# 创建回测引擎 # 创建回测引擎
be = BacktestingEngine() be = BacktestingEngine()
# 创建策略引擎对象 # 创建策略引擎对象
se = StrategyEngine(be.eventEngine, be, backtesting=True) se = StrategyEngine(be.eventEngine, be, backtesting=True)
be.setStrategyEngine(se) be.setStrategyEngine(se)
# 初始化回测引擎 # 初始化回测引擎
#be.connectMongo() # be.connectMongo()
be.connectMysql() be.connectMysql()
#be.loadMongoDataHistory(symbol, datetime(2015,5,1), datetime.today()) # be.loadMongoDataHistory(symbol, datetime(2015,5,1), datetime.today())
#be.loadMongoDataHistory(symbol, datetime(2012,1,9), datetime(2012,1,14)) # be.loadMongoDataHistory(symbol, datetime(2012,1,9), datetime(2012,1,14))
be.loadMysqlDataHistory(symbol, datetime(2012,1,9), datetime(2012,1,30)) be.loadMysqlDataHistory(symbol, datetime(2012,1,9), datetime(2012,1,14))
# 创建策略对象 # 创建策略对象
setting = {} setting = {}
setting['fastAlpha'] = 0.2 setting['fastAlpha'] = 0.2
setting['slowAlpha'] = 0.05 setting['slowAlpha'] = 0.05
#setting['startDate'] = datetime(year=2015, month=5, day=20) # setting['startDate'] = datetime(year=2015, month=5, day=20)
setting['startDate'] = datetime(year=2012, month=1, day=9) setting['startDate'] = datetime(year=2012, month=1, day=9)
se.createStrategy(u'EMA演示策略', symbol, SimpleEmaStrategy, setting) se.createStrategy(u'EMA演示策略', symbol, SimpleEmaStrategy, setting)
@ -42,3 +40,8 @@ if __name__ == '__main__':
be.startBacktesting() be.startBacktesting()
# 回测脚本
if __name__ == '__main__':
main()

View File

@ -48,12 +48,12 @@ class SimpleEmaStrategy(StrategyTemplate):
self.barTime = None self.barTime = None
# 保存K线数据的列表对象 # 保存K线数据的列表对象
self.listOpen = [] #self.listOpen = []
self.listHigh = [] #self.listHigh = []
self.listLow = [] #self.listLow = []
self.listClose = [] #self.listClose = []
self.listVolume = [] #self.listVolume = []
self.listTime = [] #s#elf.listTime = []
# 持仓 # 持仓
self.pos = 0 self.pos = 0
@ -70,7 +70,16 @@ class SimpleEmaStrategy(StrategyTemplate):
self.initCompleted = False self.initCompleted = False
# 初始化时读取的历史数据的起始日期(可以选择外部设置) # 初始化时读取的历史数据的起始日期(可以选择外部设置)
self.startDate = None self.startDate = None
# Added by Incense Lee
# 属于updateMarketData推送的第一个Tick数据,忽略交易逻辑
self.firstMarketTick = True
self.lineK = [] # K线数据
self.lineEMA = [] # 快速、慢速EMA数据
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def loadSetting(self, setting): def loadSetting(self, setting):
@ -186,7 +195,7 @@ class SimpleEmaStrategy(StrategyTemplate):
self.barTime = ticktime self.barTime = ticktime
else: else:
# 如果是当前一分钟内的数据 # 如果是当前一分钟内的数据
if ticktime.minute == self.barTime.minute: if ticktime.minute == self.barTime.minute and ticktime.hour == self.barTime.hour:
# 汇总TICK生成K线 # 汇总TICK生成K线
self.barHigh = max(self.barHigh, tick.lastPrice) self.barHigh = max(self.barHigh, tick.lastPrice)
self.barLow = min(self.barLow, tick.lastPrice) self.barLow = min(self.barLow, tick.lastPrice)
@ -196,9 +205,9 @@ class SimpleEmaStrategy(StrategyTemplate):
# 如果是新一分钟的数据 # 如果是新一分钟的数据
else: else:
# 首先推送K线数据 # 首先推送K线数据
self.onBar(self.barOpen, self.barHigh, self.barLow, self.barClose, self.onBar(self.barOpen, self.barHigh, self.barLow, self.barClose,
self.barVolume, self.barTime) self.barVolume, self.barTime)
# 初始化新的K线数据 # 初始化新的K线数据
self.barOpen = tick.lastPrice self.barOpen = tick.lastPrice
self.barHigh = tick.lastPrice self.barHigh = tick.lastPrice
@ -216,6 +225,7 @@ class SimpleEmaStrategy(StrategyTemplate):
self.pos = self.pos - trade.volume self.pos = self.pos - trade.volume
log = self.name + u'当前持仓:' + str(self.pos) log = self.name + u'当前持仓:' + str(self.pos)
print log
self.engine.writeLog(log) self.engine.writeLog(log)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
@ -229,16 +239,28 @@ class SimpleEmaStrategy(StrategyTemplate):
pass pass
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def onBar(self, o, h, l, c, volume, time): def onBar(self, o, h, l, c, volume, t):
"""K线数据更新同时进行策略的买入、卖出逻辑计算""" """K线数据更新同时进行策略的买入、卖出逻辑计算"""
# 保存K线序列数据 # 保存K线序列数据
self.listOpen.append(o) #self.listOpen.append(o)
self.listHigh.append(h) #self.listHigh.append(h)
self.listLow.append(l) #self.listLow.append(l)
self.listClose.append(c) #self.listClose.append(c)
self.listVolume.append(volume) #self.listVolume.append(volume)
self.listTime.append(time) #self.listTime.append(t)
# 保存K线数据
k = Bar()
k.open = o
k.high = h
k.low = l
k.close = c
k.volume = volume
k.date = t.date#
k.datetime = t
self.lineK.append(k)
# 计算EMA # 计算EMA
if self.fastEMA: if self.fastEMA:
self.fastEMA = c*self.fastAlpha + self.fastEMA*(1-self.fastAlpha) self.fastEMA = c*self.fastAlpha + self.fastEMA*(1-self.fastAlpha)
@ -246,9 +268,25 @@ class SimpleEmaStrategy(StrategyTemplate):
else: else:
self.fastEMA = c self.fastEMA = c
self.slowEMA = c self.slowEMA = c
emaData = EmaData()
emaData.fastEMA = self.fastEMA
emaData.slowEMA = self.slowEMA
emaData.date = t.date
emaData.time = t.time
emaData.datetime = t
self.lineEMA.append(emaData)
# 交易逻辑 # 交易逻辑
if self.initCompleted: # 首先检查是否是实盘运行还是数据预处理阶段 if self.initCompleted: # 首先检查是否是实盘运行还是数据预处理阶段
# Added by Incense Lee
# 属于updateMarketData推送的第一个Tick数据,忽略交易逻辑
if self.firstMarketTick:
self.firstMarketTick = False
return
# End added
# 快速EMA在慢速EMA上方做多 # 快速EMA在慢速EMA上方做多
if self.fastEMA > self.slowEMA: if self.fastEMA > self.slowEMA:
# 如果当前手头无仓位,则直接做多 # 如果当前手头无仓位,则直接做多
@ -256,29 +294,29 @@ class SimpleEmaStrategy(StrategyTemplate):
# 涨停价买入开仓 # 涨停价买入开仓
# Modified by Incense Lee 回测时Tick数据中没有涨停价只能使用当前价 # Modified by Incense Lee 回测时Tick数据中没有涨停价只能使用当前价
#self.buy(self.currentTick.upperLimit, 1) #self.buy(self.currentTick.upperLimit, 1)
self.buy(self.currentTick.lastPrice, 1) self.buy(self.currentTick.lastPrice, 1, t) # 价格,数量,下单时间
# 手头有空仓,则先平空,再开多 # 手头有空仓,则先平空,再开多
elif self.pos < 0: elif self.pos < 0:
#self.cover(self.currentTick.upperLimit, 1) #self.cover(self.currentTick.upperLimit, 1)
self.cover(self.currentTick.lastPrice, 1) self.cover(self.currentTick.lastPrice, 1, t) # 价格,数量, 下单时间
#self.buy(self.currentTick.upperLimit, 1) #self.buy(self.currentTick.upperLimit, 1)
self.buy(self.currentTick.lastPrice, 1) self.buy(self.currentTick.lastPrice, 1, t)
# 反之,做空 # 反之,做空
elif self.fastEMA < self.slowEMA: elif self.fastEMA < self.slowEMA:
if self.pos == 0: if self.pos == 0:
# Modified by Incense Lee 回测时Tick数据中没有最低价价只能使用当前价 # Modified by Incense Lee 回测时Tick数据中没有最低价价只能使用当前价
#self.short(self.currentTick.lowerLimit, 1) #self.short(self.currentTick.lowerLimit, 1)
self.short(self.currentTick.lastPrice, 1) self.short(self.currentTick.lastPrice, 1, t)
elif self.pos > 0: elif self.pos > 0:
#self.sell(self.currentTick.lowerLimit, 1) #self.sell(self.currentTick.lowerLimit, 1)
self.sell(self.currentTick.lastPrice, 1) self.sell(self.currentTick.lastPrice, 1, t)
#self.short(self.currentTick.lowerLimit, 1) #self.short(self.currentTick.lowerLimit, 1)
self.short(self.currentTick.lastPrice, 1) self.short(self.currentTick.lastPrice, 1, t)
# 记录日志 # 记录日志
log = self.name + u'K线时间' + str(time) + '\n' + \ log = self.name + u'K线时间' + str(t) + '\n' + \
u'快速EMA' + str(self.fastEMA) + u'慢速EMA' + \ u'快速EMA' + str(self.fastEMA) + u'慢速EMA' + \
str(self.slowEMA) str(self.slowEMA)
self.engine.writeLog(log) self.engine.writeLog(log)

View File

@ -12,6 +12,8 @@ print u'demoStrategy.py import pymongo.errors.* success'
from eventEngine import * from eventEngine import *
print u'demoStrategy.py import eventEngine.* success' print u'demoStrategy.py import eventEngine.* success'
from vtConstant import *
import MySQLdb import MySQLdb
@ -24,7 +26,11 @@ DIRECTION_SELL = '1' # 卖出
PRICETYPE_LIMIT = '2' # 限价 PRICETYPE_LIMIT = '2' # 限价
# buy 买入开仓 : DIRECTION_BUY = '0' OFFSET_OPEN = '0'
# sell 卖出平仓 : DIRECTION_SELL = '1' OFFSET_CLOSE = '1'
# short 卖出开仓 : DIRECTION_SELL = '1' OFFSET_OPEN = '0'
# cover 买入平仓 : DIRECTION_BUY = '0' OFFSET_CLOSE = '1'
######################################################################## ########################################################################
class Tick: class Tick:
@ -74,6 +80,47 @@ class Tick:
self.askVolume5 = 0 self.askVolume5 = 0
########################################################################
class Bar(object):
"""K线数据"""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
#self.vtSymbol = EMPTY_STRING # vt系统代码
self.symbol = EMPTY_STRING # 代码
#self.exchange = EMPTY_STRING # 交易所
self.open = EMPTY_FLOAT # OHLC
self.high = EMPTY_FLOAT
self.low = EMPTY_FLOAT
self.close = EMPTY_FLOAT
self.date = EMPTY_STRING # bar开始的时间日期
self.time = EMPTY_STRING # 时间
self.datetime = None # python的datetime时间对象
self.volume = EMPTY_INT # 成交量
self.openInterest = EMPTY_INT # 持仓量
########################################################################
class EmaData(object):
"""数据"""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
self.fastEMA = EMPTY_FLOAT # 快速EMA的数值
self.slowEMA = EMPTY_FLOAT # 慢速EMA的数值
self.date = EMPTY_STRING # EMA开始的时间日期
self.time = EMPTY_STRING # 时间
self.datetime = None # python的datetime时间对象
######################################################################## ########################################################################
class Trade(object): class Trade(object):
"""成交数据对象""" """成交数据对象"""
@ -147,7 +194,7 @@ class StrategyEngine(object):
def __init__(self, eventEngine, mainEngine, backtesting=False): def __init__(self, eventEngine, mainEngine, backtesting=False):
"""Constructor""" """Constructor"""
self.__eventEngine = eventEngine # 引用事件引擎 self.__eventEngine = eventEngine # 引用事件引擎
self.mainEngine = mainEngine # 主引擎在回测中为backtestingEngin,在交易中为demoEngine self.mainEngine = mainEngine # 主引擎在回测中为backtestingEngine,在交易中为MainEngine
self.backtesting = backtesting # 是否在进行回测 self.backtesting = backtesting # 是否在进行回测
# 获取代表今日的datetime # 获取代表今日的datetime
@ -172,7 +219,7 @@ class StrategyEngine(object):
# value为策略对象 # value为策略对象
self.__dictOrderRefStrategy = {} self.__dictOrderRefStrategy = {}
# 保存合约代码和相关停止单的字典 # 保存合约代码和相关停止单(止损单)的字典
# key为合约代码 # key为合约代码
# value为该合约相关的停止单列表 # value为该合约相关的停止单列表
self.__dictStopOrder = {} self.__dictStopOrder = {}
@ -293,13 +340,13 @@ class StrategyEngine(object):
'position_vol as OpenInterest,bid1_price as BidPrice1,bid1_vol as BidVolume1, ' \ 'position_vol as OpenInterest,bid1_price as BidPrice1,bid1_vol as BidVolume1, ' \
'sell1_price as AskPrice1, sell1_vol as AskVolume1 from TB__{0}MI '.format(symbol) 'sell1_price as AskPrice1, sell1_vol as AskVolume1 from TB__{0}MI '.format(symbol)
self.writeLog(sqlstring) print sqlstring
count = cur.execute(sqlstring) count = cur.execute(sqlstring)
cx = cur.fetchall() cx = cur.fetchall()
self.writeLog(u'历史TICK数据载入完成{1}~{2},共{0}'.format(count,startDate,endDate)) print u'历史TICK数据载入完成{1}~{2},共{0}'.format(count,startDate,endDate)
return cx return cx
else: else:
@ -423,7 +470,7 @@ class StrategyEngine(object):
# 如果当前有该合约上的止损单 # 如果当前有该合约上的止损单
if symbol in self.__dictStopOrder: if symbol in self.__dictStopOrder:
print u'strategyEngine.py __processStopOrder() has stop order.' #print u'strategyEngine.py __processStopOrder() has stop order.'
# 获取止损单列表 # 获取止损单列表
listSO = self.__dictStopOrder[symbol] # SO:stop order listSO = self.__dictStopOrder[symbol] # SO:stop order
@ -437,7 +484,7 @@ class StrategyEngine(object):
# 以当日涨停价发出限价单买入 # 以当日涨停价发出限价单买入
print u'sendOrder({0},{1},{2},{3},{4}'.format(symbol,'Direction_Buy',so.offset,upperLimit,so.volume) 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, ref = self.sendOrder(symbol, DIRECTION_BUY, so.offset,
upperLimit, so.volume,tick.time, strategy) upperLimit, so.volume, tick.time, so.strategy)
# 触发策略的止损单发出更新 # 触发策略的止损单发出更新
so.strategy.onStopOrder(ref) so.strategy.onStopOrder(ref)
@ -449,7 +496,7 @@ class StrategyEngine(object):
elif so.direction == DIRECTION_SELL and lastPrice <= so.price: 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) 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, ref = self.sendOrder(symbol, DIRECTION_SELL, so.offset,
lowerLimit, so.volume,tick.time, strategy) lowerLimit, so.volume,tick.time, so.strategy)
so.strategy.onStopOrder(ref) so.strategy.onStopOrder(ref)
@ -515,15 +562,17 @@ class StrategyEngine(object):
if orderRef in self.__dictOrderRefStrategy: if orderRef in self.__dictOrderRefStrategy:
# 创建Trade数据对象 # 创建Trade数据对象
trade = Trade(data['InstrumentID']) trade = Trade(data['InstrumentID']) # 合约代码
trade.orderRef = orderRef trade.orderRef = orderRef # 报单号
trade.tradeID = data['TradeID'] trade.tradeID = data['TradeID'] # 成交编号
trade.direction = data['Direction'] trade.direction = data['Direction'] # 方向
trade.offset = data['OffsetFlag'] trade.offset = data['OffsetFlag'] # 开平
trade.price = data['Price'] trade.price = data['Price'] # 成交价
trade.volume = data['Volume'] trade.volume = data['Volume'] # 成交量
trade.tradeTime = data['TradeTime'] # 成交时间
# 推送给策略 # 推送给策略
strategy = self.__dictOrderRefStrategy[orderRef] strategy = self.__dictOrderRefStrategy[orderRef]
@ -532,7 +581,7 @@ class StrategyEngine(object):
#print u'strategyEngine.py updateTrade() end.' #print u'strategyEngine.py updateTrade() end.'
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def sendOrder(self, symbol, direction, offset, price, volume, orderTime, strategy): def sendOrder(self, symbol, direction, offset, price, volume, ordertime, strategy):
""" """
发单仅允许限价单 发单仅允许限价单
symbol合约代码 symbol合约代码
@ -540,7 +589,7 @@ class StrategyEngine(object):
offset开平OFFSET_OPEN/OFFSET_CLOSE offset开平OFFSET_OPEN/OFFSET_CLOSE
price下单价格 price下单价格
volume下单手数 volume下单手数
orderTime:下单时间回归测试使用 ordertime:下单时间回归测试使用
strategy策略对象 strategy策略对象
""" """
@ -548,7 +597,7 @@ class StrategyEngine(object):
contract = self.mainEngine.selectInstrument(symbol) contract = self.mainEngine.selectInstrument(symbol)
if contract: if contract:
#调用主引擎的发单函数 # 调用主引擎的发单函数
ref = self.mainEngine.sendOrder(symbol, ref = self.mainEngine.sendOrder(symbol,
contract['ExchangeID'], contract['ExchangeID'],
price, price,
@ -556,8 +605,9 @@ class StrategyEngine(object):
volume, volume,
direction, direction,
offset, offset,
orderTime) ordertime)
# 添加报单编号及其映射的策略
self.__dictOrderRefStrategy[ref] = strategy self.__dictOrderRefStrategy[ref] = strategy
#print u'strategyEngine.py sendOrder() end.' #print u'strategyEngine.py sendOrder() end.'
@ -628,7 +678,7 @@ class StrategyEngine(object):
注意这里的price是停止单的触发价 注意这里的price是停止单的触发价
""" """
# 创建止损单对象 # 创建止损单对象
print u'strategyEngine.py placeStopOrder() begin.' print u'strategyEngine.py placeStopOrder() symbol:{0}, direction:{1}, offset:{2}, price:{3}, volume:{4}.'.format(symbol, direction, offset, price, volume)
so = StopOrder(symbol, direction, offset, price, volume, strategy) so = StopOrder(symbol, direction, offset, price, volume, strategy)
@ -642,7 +692,7 @@ class StrategyEngine(object):
# 将该止损单插入列表中 # 将该止损单插入列表中
listSO.append(so) listSO.append(so)
print u'strategyEngine.py placeStopOrder() end.' #print u'strategyEngine.py placeStopOrder() end.'
return so return so
@ -749,16 +799,19 @@ class StrategyTemplate(object):
raise NotImplementedError raise NotImplementedError
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def buy(self, price, volume, stopOrder=False, orderTime=datetime.now()): def buy(self, price, volume, orderTime, stopOrder=False ):
"""买入开仓""" """买入开仓"""
print u'strategyEngine.py StrategyTemplate({3}) buy() begin. symbol:{0}, price:{1},volume:{2}'.format(self.symbol, price, volume, self.name)
print u'strategyEngine.py StrategyTemplate({3}) buy() begin. symbol:{0}, price:{1},volume:{2},time:{4}'.format(self.symbol, price, volume, self.name,orderTime)
if self.trading: if self.trading:
if stopOrder: if stopOrder:
# 止损单
so = self.engine.placeStopOrder(self.symbol, DIRECTION_BUY, so = self.engine.placeStopOrder(self.symbol, DIRECTION_BUY,
OFFSET_OPEN, price, volume, self) OFFSET_OPEN, price, volume, self)
return so return so
else: else:
# 委托单
ref = self.engine.sendOrder(self.symbol, DIRECTION_BUY, ref = self.engine.sendOrder(self.symbol, DIRECTION_BUY,
OFFSET_OPEN, price, volume, orderTime, self) OFFSET_OPEN, price, volume, orderTime, self)
return ref return ref
@ -768,17 +821,20 @@ class StrategyTemplate(object):
#print (u'strategyEngine.py buy() end.') #print (u'strategyEngine.py buy() end.')
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def cover(self, price, volume, stopOrder=False, orderTime=datetime.now()): def cover(self, price, volume,orderTime, stopOrder=False):
"""买入平仓""" """买入平仓"""
print u'strategyEngine.py StrategyTemplate({3}) cover() begin. symbol:{0}, price:{1},volume:{2}'.format(self.symbol, price, volume, self.name) print u'strategyEngine.py StrategyTemplate({3}) cover() begin. symbol:{0}, price:{1},volume:{2},time:{4}'.format(self.symbol, price, volume, self.name, orderTime)
if self.trading: if self.trading:
if stopOrder: if stopOrder:
# 止损单
so = self.engine.placeStopOrder(self.symbol, DIRECTION_BUY, so = self.engine.placeStopOrder(self.symbol, DIRECTION_BUY,
OFFSET_CLOSE, price, volume, self) OFFSET_CLOSE, price, volume, self)
return so return so
else: else:
# 委托单
ref = self.engine.sendOrder(self.symbol, DIRECTION_BUY, ref = self.engine.sendOrder(self.symbol, DIRECTION_BUY,
OFFSET_CLOSE, price, volume, orderTime, self) OFFSET_CLOSE, price, volume, orderTime, self)
return ref return ref
@ -787,17 +843,19 @@ class StrategyTemplate(object):
print (u'strategyEngine.py cover() end.') print (u'strategyEngine.py cover() end.')
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def sell(self, price, volume, stopOrder=False, orderTime=datetime.now()): def sell(self, price, volume, orderTime, stopOrder=False):
"""卖出平仓""" """卖出平仓"""
print u'strategyEngine.py StrategyTemplate({3}) sell() begin. symbol:{0}, price:{1},volume:{2}'.format(self.symbol, price, volume, self.name) print u'strategyEngine.py StrategyTemplate({3}) sell() begin. symbol:{0}, price:{1},volume:{2},time:{4}'.format(self.symbol, price, volume, self.name, orderTime)
if self.trading: if self.trading:
if stopOrder: if stopOrder:
# 止损单
so = self.engine.placeStopOrder(self.symbol, DIRECTION_SELL, so = self.engine.placeStopOrder(self.symbol, DIRECTION_SELL,
OFFSET_CLOSE, price, volume, self) OFFSET_CLOSE, price, volume, self)
return so return so
else: else:
# 委托单
ref = self.engine.sendOrder(self.symbol, DIRECTION_SELL, ref = self.engine.sendOrder(self.symbol, DIRECTION_SELL,
OFFSET_CLOSE, price, volume, orderTime, self) OFFSET_CLOSE, price, volume, orderTime, self)
return ref return ref
@ -806,15 +864,17 @@ class StrategyTemplate(object):
#print u'strategyEngine.py sell() end.' #print u'strategyEngine.py sell() end.'
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def short(self, price, volume, stopOrder=False, orderTime=datetime.now()): def short(self, price, volume, orderTime, stopOrder=False):
"""卖出开仓""" """卖出开仓"""
print u'strategyEngine.py StrategyTemplate({3}) short() begin. symbol:{0}, price:{1},volume:{2}'.format(self.symbol, price, volume, self.name) print u'strategyEngine.py StrategyTemplate({3}) short() begin. symbol:{0}, price:{1},volume:{2},time:{4}'.format(self.symbol, price, volume, self.name, orderTime)
if self.trading: if self.trading:
if stopOrder: if stopOrder:
# 止损单
so = self.engine.placeStopOrder(self.symbol, DIRECTION_SELL, so = self.engine.placeStopOrder(self.symbol, DIRECTION_SELL,
OFFSET_OPEN, price, volume, self) OFFSET_OPEN, price, volume, self)
return so return so
else: else:
# 委托单
ref = self.engine.sendOrder(self.symbol, DIRECTION_SELL, ref = self.engine.sendOrder(self.symbol, DIRECTION_SELL,
OFFSET_OPEN, price, volume, orderTime, self) OFFSET_OPEN, price, volume, orderTime, self)
return ref return ref

View File

@ -0,0 +1,57 @@
# encoding: UTF-8
# 默认空值
EMPTY_STRING = ''
EMPTY_UNICODE = u''
EMPTY_INT = 0
EMPTY_FLOAT = 0.0
# 方向常量
DIRECTION_NONE = u'无方向'
DIRECTION_LONG = u''
DIRECTION_SHORT = u''
DIRECTION_UNKNOWN = u'未知'
DIRECTION_NET = u''
# 开平常量
OFFSET_NONE = u'无开平'
OFFSET_OPEN = u'开仓'
OFFSET_CLOSE = u'平仓'
OFFSET_CLOSETODAY = u'平今'
OFFSET_CLOSESYESTERDAY = u'平昨'
OFFSET_UNKNOWN = u'未知'
# 状态常量
STATUS_NOTTRADED = u'未成交'
STATUS_PARTTRADED = u'部分成交'
STATUS_ALLTRADED = u'全部成交'
STATUS_CANCELLED = u'已撤销'
STATUS_UNKNOWN = u'未知'
# 合约类型常量
PRODUCT_EQUITY = u'股票'
PRODUCT_FUTURES = u'期货'
PRODUCT_OPTION = u'期权'
PRODUCT_INDEX = u'指数'
PRODUCT_COMBINATION = u'组合'
PRODUCT_UNKNOWN = u'未知'
# 价格类型常量
PRICETYPE_LIMITPRICE = u'限价'
PRICETYPE_MARKETPRICE = u'市价'
PRICETYPE_FAK = u'FAK'
PRICETYPE_FOK = u'FOK'
# 期权类型
OPTION_CALL = u'看涨期权'
OPTION_PUT = u'看跌期权'
# 交易所类型
EXCHANGE_SSE = u'SSE' # 上交所
EXCHANGE_SZSE = u'SZSE' # 深交所
EXCHANGE_CFFEX = u'CFFEX' # 中金所
EXCHANGE_SHFE = u'SHFE' # 上期所
EXCHANGE_CZCE = u'CZCE' # 郑商所
EXCHANGE_DCE = u'DCE' # 大商所
EXCHANGE_UNKNOWN = 'UNKNOWN'# 未知交易所
EXCHANGE_NONE = '' # 空交易所