增加风控功能,资金净值低于设定的止损线,强制全仓止损。
This commit is contained in:
parent
c7f6e1e9a5
commit
23f8d1c6f3
@ -97,9 +97,14 @@ class CtaEngine(object):
|
|||||||
req.price = price # 价格
|
req.price = price # 价格
|
||||||
req.volume = volume # 数量
|
req.volume = volume # 数量
|
||||||
|
|
||||||
req.productClass = strategy.productClass
|
if strategy:
|
||||||
req.currency = strategy.currency
|
req.productClass = strategy.productClass
|
||||||
|
req.currency = strategy.currency
|
||||||
|
else:
|
||||||
|
req.productClass = ''
|
||||||
|
req.currency = ''
|
||||||
|
|
||||||
|
|
||||||
# 设计为CTA引擎发出的委托只允许使用限价单
|
# 设计为CTA引擎发出的委托只允许使用限价单
|
||||||
req.priceType = PRICETYPE_LIMITPRICE # 价格类型
|
req.priceType = PRICETYPE_LIMITPRICE # 价格类型
|
||||||
|
|
||||||
@ -165,11 +170,14 @@ class CtaEngine(object):
|
|||||||
|
|
||||||
vtOrderID = self.mainEngine.sendOrder(req, contract.gatewayName) # 发单
|
vtOrderID = self.mainEngine.sendOrder(req, contract.gatewayName) # 发单
|
||||||
|
|
||||||
self.orderStrategyDict[vtOrderID] = strategy # 保存vtOrderID和策略的映射关系
|
if strategy:
|
||||||
|
self.orderStrategyDict[vtOrderID] = strategy # 保存vtOrderID和策略的映射关系
|
||||||
|
|
||||||
self.writeCtaLog(u'策略%s发送委托,%s, %s,%s,%s@%s'
|
self.writeCtaLog(u'策略%s发送委托,%s, %s,%s,%s@%s'
|
||||||
%(strategy.name, vtSymbol, req.offset, req.direction, volume, price))
|
%(strategy.name, vtSymbol, req.offset, req.direction, volume, price))
|
||||||
|
else:
|
||||||
|
self.writeCtaLog(u'%s发送委托,%s, %s,%s,%s@%s'
|
||||||
|
% ('CtaEngine', vtSymbol, req.offset, req.direction, volume, price))
|
||||||
return vtOrderID
|
return vtOrderID
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
@ -413,13 +421,14 @@ class CtaEngine(object):
|
|||||||
pos = event.dict_['data']
|
pos = event.dict_['data']
|
||||||
|
|
||||||
# 更新持仓缓存数据
|
# 更新持仓缓存数据
|
||||||
if pos.vtSymbol in self.tickStrategyDict:
|
#if pos.vtSymbol in self.tickStrategyDict:
|
||||||
posBuffer = self.posBufferDict.get(pos.vtSymbol, None)
|
|
||||||
if not posBuffer:
|
posBuffer = self.posBufferDict.get(pos.vtSymbol, None)
|
||||||
posBuffer = PositionBuffer()
|
if not posBuffer:
|
||||||
posBuffer.vtSymbol = pos.vtSymbol
|
posBuffer = PositionBuffer()
|
||||||
self.posBufferDict[pos.vtSymbol] = posBuffer
|
posBuffer.vtSymbol = pos.vtSymbol
|
||||||
posBuffer.updatePositionData(pos)
|
self.posBufferDict[pos.vtSymbol] = posBuffer
|
||||||
|
posBuffer.updatePositionData(pos)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def registerEvent(self):
|
def registerEvent(self):
|
||||||
@ -440,6 +449,60 @@ class CtaEngine(object):
|
|||||||
# 注册定时器事件
|
# 注册定时器事件
|
||||||
self.eventEngine.register(EVENT_TIMER, self.processTimerEvent)
|
self.eventEngine.register(EVENT_TIMER, self.processTimerEvent)
|
||||||
|
|
||||||
|
# 注册强制止损事件
|
||||||
|
self.eventEngine.register(EVENT_ACCOUNT_LOSS, self.processAccoutLossEvent)
|
||||||
|
|
||||||
|
def processAccoutLossEvent(self,event):
|
||||||
|
"""处理止损时间"""
|
||||||
|
balance = event.dict_['data']
|
||||||
|
self.writeCtaLog(u'净值{0}低于止损线,执行强制止损'.format(balance))
|
||||||
|
self.mainEngine.writeLog(u'净值{0}低于止损线,执行强制止损'.format(balance))
|
||||||
|
|
||||||
|
self.cancelOrders(symbol=EMPTY_STRING)
|
||||||
|
|
||||||
|
for posBuffer in self.posBufferDict.values():
|
||||||
|
|
||||||
|
if posBuffer.shortYd > 0:
|
||||||
|
self.writeCtaLog(u'{0}合约持有昨空单{1}手,强平'.format(posBuffer.vtSymbol,posBuffer.shortYd))
|
||||||
|
tick = self.tickDict.get(posBuffer.vtSymbol, None)
|
||||||
|
|
||||||
|
if not tick:
|
||||||
|
self.writeCtaLog(u'找不对{0}的最新Tick数据'.format(posBuffer.vtSymbol))
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.sendOrder(posBuffer.vtSymbol, orderType=CTAORDER_COVER, price=tick.upperLimit, volume=posBuffer.shortYd,strategy=None)
|
||||||
|
|
||||||
|
if posBuffer.shortToday > 0:
|
||||||
|
self.writeCtaLog(u'{0}合约持有今空单{1}手,强平'.format(posBuffer.vtSymbol,posBuffer.shortToday))
|
||||||
|
tick = self.tickDict.get(posBuffer.vtSymbol, None)
|
||||||
|
|
||||||
|
if not tick:
|
||||||
|
self.writeCtaLog(u'找不对{0}的最新Tick数据'.format(posBuffer.vtSymbol))
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.sendOrder(posBuffer.vtSymbol, orderType=CTAORDER_COVER, price=tick.upperLimit, volume=posBuffer.shortToday,strategy=None)
|
||||||
|
|
||||||
|
if posBuffer.longYd > 0:
|
||||||
|
self.writeCtaLog(u'{0}合约持有昨多单{1}手,强平'.format(posBuffer.vtSymbol,posBuffer.longYd))
|
||||||
|
tick = self.tickDict.get(posBuffer.vtSymbol, None)
|
||||||
|
|
||||||
|
if not tick:
|
||||||
|
self.writeCtaLog(u'找不对{0}的最新Tick数据'.format(posBuffer.vtSymbol))
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.sendOrder(posBuffer.vtSymbol, orderType=CTAORDER_SELL, price=tick.lowerLimit, volume=posBuffer.longYd,strategy=None)
|
||||||
|
|
||||||
|
if posBuffer.longToday > 0:
|
||||||
|
self.writeCtaLog(u'{0}合约持有今多单{1}手,强平'.format(posBuffer.vtSymbol,posBuffer.longToday))
|
||||||
|
tick = self.tickDict.get(posBuffer.vtSymbol, None)
|
||||||
|
|
||||||
|
if not tick:
|
||||||
|
self.writeCtaLog(u'找不对{0}的最新Tick数据'.format(posBuffer.vtSymbol))
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.sendOrder(posBuffer.vtSymbol, orderType=CTAORDER_SELL, price=tick.lowerLimit, volume=posBuffer.longToday,strategy=None)
|
||||||
|
|
||||||
|
|
||||||
def processTimerEvent(self, event):
|
def processTimerEvent(self, event):
|
||||||
"""定时器事件"""
|
"""定时器事件"""
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ class RmEngineManager(QtGui.QWidget):
|
|||||||
self.spinPercentLimit = RmSpinBox(self.rmEngine.percentLimit)
|
self.spinPercentLimit = RmSpinBox(self.rmEngine.percentLimit)
|
||||||
|
|
||||||
# 最大净值止损比例,满足后强制止损
|
# 最大净值止损比例,满足后强制止损
|
||||||
self.spinLossPercentLimit = RmSpinBox(self.rmEngine.lossPercentLimit)
|
self.spinLossLimit = RmSpinBox(self.rmEngine.lossLimit)
|
||||||
|
|
||||||
buttonClearOrderFlowCount = QtGui.QPushButton(u'清空流控计数')
|
buttonClearOrderFlowCount = QtGui.QPushButton(u'清空流控计数')
|
||||||
buttonClearTradeCount = QtGui.QPushButton(u'清空总成交计数')
|
buttonClearTradeCount = QtGui.QPushButton(u'清空总成交计数')
|
||||||
@ -96,8 +96,8 @@ class RmEngineManager(QtGui.QWidget):
|
|||||||
grid.addWidget(RmLine(), 10, 0, 1, 2)
|
grid.addWidget(RmLine(), 10, 0, 1, 2)
|
||||||
grid.addWidget(Label(u'仓位上限(1~100)'), 11, 0)
|
grid.addWidget(Label(u'仓位上限(1~100)'), 11, 0)
|
||||||
grid.addWidget(self.spinPercentLimit, 11, 1)
|
grid.addWidget(self.spinPercentLimit, 11, 1)
|
||||||
grid.addWidget(Label(u'强制止损比例'), 12, 0)
|
grid.addWidget(Label(u'强制止损净值'), 12, 0)
|
||||||
grid.addWidget(self.spinLossPercentLimit, 12, 1)
|
grid.addWidget(self.spinLossLimit, 12, 1)
|
||||||
|
|
||||||
hbox = QtGui.QHBoxLayout()
|
hbox = QtGui.QHBoxLayout()
|
||||||
hbox.addWidget(buttonClearOrderFlowCount)
|
hbox.addWidget(buttonClearOrderFlowCount)
|
||||||
@ -117,7 +117,7 @@ class RmEngineManager(QtGui.QWidget):
|
|||||||
self.spinTradeLimit.valueChanged.connect(self.rmEngine.setTradeLimit)
|
self.spinTradeLimit.valueChanged.connect(self.rmEngine.setTradeLimit)
|
||||||
self.spinWorkingOrderLimit.valueChanged.connect(self.rmEngine.setWorkingOrderLimit)
|
self.spinWorkingOrderLimit.valueChanged.connect(self.rmEngine.setWorkingOrderLimit)
|
||||||
self.spinPercentLimit.valueChanged.connect(self.rmEngine.setAccountPercentLimit)
|
self.spinPercentLimit.valueChanged.connect(self.rmEngine.setAccountPercentLimit)
|
||||||
self.spinLossPercentLimit.valueChanged.connect(self.rmEngine.setLossPercentLimit)
|
self.spinLossLimit.valueChanged.connect(self.rmEngine.setLossLimit)
|
||||||
|
|
||||||
self.buttonSwitchEngineStatus.clicked.connect(self.switchEngineSatus)
|
self.buttonSwitchEngineStatus.clicked.connect(self.switchEngineSatus)
|
||||||
buttonClearOrderFlowCount.clicked.connect(self.rmEngine.clearOrderFlowCount)
|
buttonClearOrderFlowCount.clicked.connect(self.rmEngine.clearOrderFlowCount)
|
||||||
|
@ -417,9 +417,14 @@ class DataEngine(object):
|
|||||||
# 目的:1、
|
# 目的:1、
|
||||||
|
|
||||||
position = event.dict_['data']
|
position = event.dict_['data']
|
||||||
|
|
||||||
symbol = position.symbol
|
symbol = position.symbol
|
||||||
|
|
||||||
|
if symbol is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
if len(symbol) == 0:
|
||||||
|
return
|
||||||
|
|
||||||
# 已存在,不做更新
|
# 已存在,不做更新
|
||||||
if symbol in self.subscribedSymbols:
|
if symbol in self.subscribedSymbols:
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user