[Add]新增委托全撤函数

This commit is contained in:
vn.py 2017-10-08 22:32:07 +08:00
parent 7f18309430
commit 8cb236f823
7 changed files with 147 additions and 58 deletions

File diff suppressed because one or more lines are too long

View File

@ -551,7 +551,17 @@ class BacktestingEngine(object):
"""记录日志""" """记录日志"""
log = str(self.dt) + ' ' + content log = str(self.dt) + ' ' + content
self.logList.append(log) self.logList.append(log)
#----------------------------------------------------------------------
def cancelAll(self, name):
"""全部撤单"""
# 撤销限价单
for orderID in self.workingLimitOrderDict.keys():
self.cancelOrder(orderID)
# 撤销停止单
for stopOrderID in self.workingStopOrderDict.keys():
self.cancelStopOrder(stopOrderID)
#------------------------------------------------ #------------------------------------------------
# 结果计算相关 # 结果计算相关
@ -1042,7 +1052,7 @@ class BacktestingEngine(object):
df['netPnl'].hist(bins=50) df['netPnl'].hist(bins=50)
plt.show() plt.show()
######################################################################## ########################################################################
class TradingResult(object): class TradingResult(object):

View File

@ -41,7 +41,9 @@ from .strategy import STRATEGY_CLASS
class CtaEngine(object): class CtaEngine(object):
"""CTA策略引擎""" """CTA策略引擎"""
settingFileName = 'CTA_setting.json' settingFileName = 'CTA_setting.json'
settingfilePath = getJsonPath(settingFileName, __file__) settingfilePath = getJsonPath(settingFileName, __file__)
STATUS_FINISHED = set([STATUS_REJECTED, STATUS_CANCELLED, STATUS_ALLTRADED])
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def __init__(self, mainEngine, eventEngine): def __init__(self, mainEngine, eventEngine):
@ -74,6 +76,10 @@ class CtaEngine(object):
self.stopOrderDict = {} # 停止单撤销后不会从本字典中删除 self.stopOrderDict = {} # 停止单撤销后不会从本字典中删除
self.workingStopOrderDict = {} # 停止单撤销后会从本字典中删除 self.workingStopOrderDict = {} # 停止单撤销后会从本字典中删除
# 保存策略名称和委托号列表的字典
# key为namevalue为保存orderID限价+本地停止)的集合
self.strategyOrderDict = {}
# 成交号集合,用来过滤已经收到过的成交推送 # 成交号集合,用来过滤已经收到过的成交推送
self.tradeSet = set() self.tradeSet = set()
@ -131,6 +137,7 @@ class CtaEngine(object):
for convertedReq in reqList: for convertedReq in reqList:
vtOrderID = self.mainEngine.sendOrder(convertedReq, contract.gatewayName) # 发单 vtOrderID = self.mainEngine.sendOrder(convertedReq, contract.gatewayName) # 发单
self.orderStrategyDict[vtOrderID] = strategy # 保存vtOrderID和策略的映射关系 self.orderStrategyDict[vtOrderID] = strategy # 保存vtOrderID和策略的映射关系
self.strategyOrderDict[strategy.name].add(vtOrderID) # 添加到策略委托号集合中
vtOrderIDList.append(vtOrderID) vtOrderIDList.append(vtOrderID)
self.writeCtaLog(u'策略%s发送委托,%s%s%s@%s' self.writeCtaLog(u'策略%s发送委托,%s%s%s@%s'
@ -189,6 +196,9 @@ class CtaEngine(object):
self.stopOrderDict[stopOrderID] = so self.stopOrderDict[stopOrderID] = so
self.workingStopOrderDict[stopOrderID] = so self.workingStopOrderDict[stopOrderID] = so
# 保存stopOrderID到策略委托号集合中
self.strategyOrderDict[strategy.name].add(stopOrderID)
# 推送停止单状态 # 推送停止单状态
strategy.onStopOrder(so) strategy.onStopOrder(so)
@ -200,9 +210,19 @@ class CtaEngine(object):
# 检查停止单是否存在 # 检查停止单是否存在
if stopOrderID in self.workingStopOrderDict: if stopOrderID in self.workingStopOrderDict:
so = self.workingStopOrderDict[stopOrderID] so = self.workingStopOrderDict[stopOrderID]
strategy = so.strategy
# 更改停止单状态为已撤销
so.status = STOPORDER_CANCELLED so.status = STOPORDER_CANCELLED
# 从活动停止单字典中移除
del self.workingStopOrderDict[stopOrderID] del self.workingStopOrderDict[stopOrderID]
so.strategy.onStopOrder(so)
# 从策略委托号集合中移除
self.strategyOrderDict[strategy.name].remove(stopOrderID)
# 通知策略
strategy.onStopOrder(so)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def processStopOrder(self, tick): def processStopOrder(self, tick):
@ -230,6 +250,9 @@ class CtaEngine(object):
# 从活动停止单字典中移除该停止单 # 从活动停止单字典中移除该停止单
del self.workingStopOrderDict[so.stopOrderID] del self.workingStopOrderDict[so.stopOrderID]
# 从策略委托号集合中移除
self.strategyOrderDict[so.strategy.name].remove(so.stopOrderID)
# 更新停止单状态,并通知策略 # 更新停止单状态,并通知策略
so.status = STOPORDER_TRIGGERED so.status = STOPORDER_TRIGGERED
so.strategy.onStopOrder(so) so.strategy.onStopOrder(so)
@ -264,6 +287,11 @@ class CtaEngine(object):
if order.vtOrderID in self.orderStrategyDict: if order.vtOrderID in self.orderStrategyDict:
strategy = self.orderStrategyDict[order.vtOrderID] strategy = self.orderStrategyDict[order.vtOrderID]
# 如果委托已经完成(拒单、撤销、全成),则从活动委托集合中移除
if order.status in self.STATUS_FINISHED:
self.strategyOrderDict[strategy.name].remove(order.vtOrderID)
self.callStrategyFunc(strategy, strategy.onOrder, order) self.callStrategyFunc(strategy, strategy.onOrder, order)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
@ -367,6 +395,9 @@ class CtaEngine(object):
strategy = strategyClass(self, setting) strategy = strategyClass(self, setting)
self.strategyDict[name] = strategy self.strategyDict[name] = strategy
# 创建委托号列表
self.strategyOrderDict[name] = set()
# 保存Tick映射关系 # 保存Tick映射关系
if strategy.vtSymbol in self.tickStrategyDict: if strategy.vtSymbol in self.tickStrategyDict:
l = self.tickStrategyDict[strategy.vtSymbol] l = self.tickStrategyDict[strategy.vtSymbol]
@ -576,4 +607,16 @@ class CtaEngine(object):
def stop(self): def stop(self):
"""停止""" """停止"""
pass pass
#----------------------------------------------------------------------
def cancelAll(self, name):
"""全部撤单"""
s = self.strategyOrderDict[name]
# 遍历集合,全部撤单
for orderID in s:
if STOPORDERPREFIX in orderID:
self.cancelStopOrder(orderID)
else:
self.cancelOrder(orderID)

View File

@ -144,6 +144,11 @@ class CtaTemplate(object):
self.ctaEngine.cancelStopOrder(vtOrderID) self.ctaEngine.cancelStopOrder(vtOrderID)
else: else:
self.ctaEngine.cancelOrder(vtOrderID) self.ctaEngine.cancelOrder(vtOrderID)
#----------------------------------------------------------------------
def cancelAll(self):
"""全部撤单"""
self.ctaEngine.cancelAll(self.name)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def insertTick(self, tick): def insertTick(self, tick):

View File

@ -41,8 +41,6 @@ class AtrRsiStrategy(CtaTemplate):
intraTradeHigh = 0 # 移动止损用的持仓期内最高价 intraTradeHigh = 0 # 移动止损用的持仓期内最高价
intraTradeLow = 0 # 移动止损用的持仓期内最低价 intraTradeLow = 0 # 移动止损用的持仓期内最低价
orderList = [] # 保存委托代码的列表
# 参数列表,保存了参数的名称 # 参数列表,保存了参数的名称
paramList = ['name', paramList = ['name',
'className', 'className',
@ -114,10 +112,7 @@ class AtrRsiStrategy(CtaTemplate):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def onBar(self, bar): def onBar(self, bar):
"""收到Bar推送必须由用户继承实现""" """收到Bar推送必须由用户继承实现"""
# 撤销之前发出的尚未成交的委托(包括限价单和停止单) self.cancelAll()
for orderID in self.orderList:
self.cancelOrder(orderID)
self.orderList = []
# 保存K线数据 # 保存K线数据
am = self.am am = self.am
@ -155,20 +150,20 @@ class AtrRsiStrategy(CtaTemplate):
# 计算多头持有期内的最高价,以及重置最低价 # 计算多头持有期内的最高价,以及重置最低价
self.intraTradeHigh = max(self.intraTradeHigh, bar.high) self.intraTradeHigh = max(self.intraTradeHigh, bar.high)
self.intraTradeLow = bar.low self.intraTradeLow = bar.low
# 计算多头移动止损 # 计算多头移动止损
longStop = self.intraTradeHigh * (1-self.trailingPercent/100) longStop = self.intraTradeHigh * (1-self.trailingPercent/100)
# 发出本地止损委托,并且把委托号记录下来,用于后续撤单
l = self.sell(longStop, abs(self.pos), stop=True)
self.orderList.extend(l)
# 发出本地止损委托,并且把委托号记录下来,用于后续撤单
self.sell(longStop, abs(self.pos), stop=True)
# 持有空头仓位 # 持有空头仓位
elif self.pos < 0: elif self.pos < 0:
self.intraTradeLow = min(self.intraTradeLow, bar.low) self.intraTradeLow = min(self.intraTradeLow, bar.low)
self.intraTradeHigh = bar.high self.intraTradeHigh = bar.high
shortStop = self.intraTradeLow * (1+self.trailingPercent/100) shortStop = self.intraTradeLow * (1+self.trailingPercent/100)
l = self.cover(shortStop, abs(self.pos), stop=True) self.cover(shortStop, abs(self.pos), stop=True)
self.orderList.extend(l)
# 发出状态更新事件 # 发出状态更新事件
self.putEvent() self.putEvent()

View File

@ -51,8 +51,6 @@ class BollChannelStrategy(CtaTemplate):
longStop = 0 # 多头止损 longStop = 0 # 多头止损
shortStop = 0 # 空头止损 shortStop = 0 # 空头止损
orderList = [] # 保存委托代码的列表
# 参数列表,保存了参数的名称 # 参数列表,保存了参数的名称
paramList = ['name', paramList = ['name',
'className', 'className',
@ -124,10 +122,8 @@ class BollChannelStrategy(CtaTemplate):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def onXminBar(self, bar): def onXminBar(self, bar):
"""收到X分钟K线""" """收到X分钟K线"""
# 撤销之前发出的尚未成交的委托(包括限价单和停止单) # 全撤之前发出的委托
for orderID in self.orderList: self.cancelAll()
self.cancelOrder(orderID)
self.orderList = []
# 保存K线数据 # 保存K线数据
am = self.am am = self.am
@ -150,11 +146,10 @@ class BollChannelStrategy(CtaTemplate):
self.intraTradeLow = bar.low self.intraTradeLow = bar.low
if self.cciValue > 0: if self.cciValue > 0:
l = self.buy(self.bollUp, self.fixedSize, True) self.buy(self.bollUp, self.fixedSize, True)
self.orderList.extend(l)
elif self.cciValue < 0: elif self.cciValue < 0:
l = self.short(self.bollDown, self.fixedSize, True) self.short(self.bollDown, self.fixedSize, True)
self.orderList.extend(l)
# 持有多头仓位 # 持有多头仓位
elif self.pos > 0: elif self.pos > 0:
@ -162,8 +157,7 @@ class BollChannelStrategy(CtaTemplate):
self.intraTradeLow = bar.low self.intraTradeLow = bar.low
self.longStop = self.intraTradeHigh - self.atrValue * self.slMultiplier self.longStop = self.intraTradeHigh - self.atrValue * self.slMultiplier
l = self.sell(self.longStop, abs(self.pos), True) self.sell(self.longStop, abs(self.pos), True)
self.orderList.extend(l)
# 持有空头仓位 # 持有空头仓位
elif self.pos < 0: elif self.pos < 0:
@ -171,8 +165,7 @@ class BollChannelStrategy(CtaTemplate):
self.intraTradeLow = min(self.intraTradeLow, bar.low) self.intraTradeLow = min(self.intraTradeLow, bar.low)
self.shortStop = self.intraTradeLow + self.atrValue * self.slMultiplier self.shortStop = self.intraTradeLow + self.atrValue * self.slMultiplier
l = self.cover(self.shortStop, abs(self.pos), True) self.cover(self.shortStop, abs(self.pos), True)
self.orderList.extend(l)
# 发出状态更新事件 # 发出状态更新事件
self.putEvent() self.putEvent()

View File

@ -39,8 +39,6 @@ class DualThrustStrategy(CtaTemplate):
longEntered = False longEntered = False
shortEntered = False shortEntered = False
orderList = [] # 保存委托代码的列表
# 参数列表,保存了参数的名称 # 参数列表,保存了参数的名称
paramList = ['name', paramList = ['name',
'className', 'className',
@ -99,9 +97,7 @@ class DualThrustStrategy(CtaTemplate):
def onBar(self, bar): def onBar(self, bar):
"""收到Bar推送必须由用户继承实现""" """收到Bar推送必须由用户继承实现"""
# 撤销之前发出的尚未成交的委托(包括限价单和停止单) # 撤销之前发出的尚未成交的委托(包括限价单和停止单)
for orderID in self.orderList: self.cancelAll()
self.cancelOrder(orderID)
self.orderList = []
# 计算指标数值 # 计算指标数值
self.barList.append(bar) self.barList.append(bar)
@ -138,47 +134,39 @@ class DualThrustStrategy(CtaTemplate):
if self.pos == 0: if self.pos == 0:
if bar.close > self.dayOpen: if bar.close > self.dayOpen:
if not self.longEntered: if not self.longEntered:
l = self.buy(self.longEntry, self.fixedSize, stop=True) self.buy(self.longEntry, self.fixedSize, stop=True)
self.orderList.extend(l)
else: else:
if not self.shortEntered: if not self.shortEntered:
l = self.short(self.shortEntry, self.fixedSize, stop=True) self.short(self.shortEntry, self.fixedSize, stop=True)
self.orderList.extend(l)
# 持有多头仓位 # 持有多头仓位
elif self.pos > 0: elif self.pos > 0:
self.longEntered = True self.longEntered = True
# 多头止损单 # 多头止损单
l = self.sell(self.shortEntry, self.fixedSize, stop=True) self.sell(self.shortEntry, self.fixedSize, stop=True)
self.orderList.extend(l)
# 空头开仓单 # 空头开仓单
if not self.shortEntered: if not self.shortEntered:
l = self.short(self.shortEntry, self.fixedSize, stop=True) self.short(self.shortEntry, self.fixedSize, stop=True)
self.orderList.extend(l)
# 持有空头仓位 # 持有空头仓位
elif self.pos < 0: elif self.pos < 0:
self.shortEntered = True self.shortEntered = True
# 空头止损单 # 空头止损单
l = self.cover(self.longEntry, self.fixedSize, stop=True) self.cover(self.longEntry, self.fixedSize, stop=True)
self.orderList.extend(l)
# 多头开仓单 # 多头开仓单
if not self.longEntered: if not self.longEntered:
l = self.buy(self.longEntry, self.fixedSize, stop=True) self.buy(self.longEntry, self.fixedSize, stop=True)
self.orderList.extend(l)
# 收盘平仓 # 收盘平仓
else: else:
if self.pos > 0: if self.pos > 0:
l = self.sell(bar.close * 0.99, abs(self.pos)) self.sell(bar.close * 0.99, abs(self.pos))
self.orderList.extend(l)
elif self.pos < 0: elif self.pos < 0:
l = self.cover(bar.close * 1.01, abs(self.pos)) self.cover(bar.close * 1.01, abs(self.pos))
self.orderList.extend(l)
# 发出状态更新事件 # 发出状态更新事件
self.putEvent() self.putEvent()