bug fixing
This commit is contained in:
parent
9347691f44
commit
5f3e781996
@ -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
|
||||||
|
@ -19,11 +19,11 @@ 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() # 下单时间
|
||||||
@ -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,15 +322,16 @@ 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)
|
||||||
|
|
||||||
|
@ -5,10 +5,8 @@ from backtestingEngine import *
|
|||||||
from demoStrategy import SimpleEmaStrategy
|
from demoStrategy import SimpleEmaStrategy
|
||||||
import decimal
|
import decimal
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""回测程序主函数"""
|
||||||
# 回测脚本
|
|
||||||
if __name__ == '__main__':
|
|
||||||
# symbol = 'IF1506'
|
# symbol = 'IF1506'
|
||||||
symbol = 'a'
|
symbol = 'a'
|
||||||
|
|
||||||
@ -24,7 +22,7 @@ if __name__ == '__main__':
|
|||||||
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 = {}
|
||||||
@ -42,3 +40,8 @@ if __name__ == '__main__':
|
|||||||
be.startBacktesting()
|
be.startBacktesting()
|
||||||
|
|
||||||
|
|
||||||
|
# 回测脚本
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
@ -72,6 +72,15 @@ class SimpleEmaStrategy(StrategyTemplate):
|
|||||||
# 初始化时读取的历史数据的起始日期(可以选择外部设置)
|
# 初始化时读取的历史数据的起始日期(可以选择外部设置)
|
||||||
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)
|
||||||
@ -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,15 +239,27 @@ 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:
|
||||||
@ -247,8 +269,24 @@ class SimpleEmaStrategy(StrategyTemplate):
|
|||||||
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)
|
||||||
|
@ -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:策略对象
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -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
|
||||||
|
57
vn.strategy/strategydemo/vtConstant.py
Normal file
57
vn.strategy/strategydemo/vtConstant.py
Normal 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 = '' # 空交易所
|
Loading…
Reference in New Issue
Block a user