增加风控功能,资金净值低于设定的止损线,强制全仓止损。
This commit is contained in:
parent
c7f6e1e9a5
commit
23f8d1c6f3
@ -97,8 +97,13 @@ class CtaEngine(object):
|
||||
req.price = price # 价格
|
||||
req.volume = volume # 数量
|
||||
|
||||
req.productClass = strategy.productClass
|
||||
req.currency = strategy.currency
|
||||
if strategy:
|
||||
req.productClass = strategy.productClass
|
||||
req.currency = strategy.currency
|
||||
else:
|
||||
req.productClass = ''
|
||||
req.currency = ''
|
||||
|
||||
|
||||
# 设计为CTA引擎发出的委托只允许使用限价单
|
||||
req.priceType = PRICETYPE_LIMITPRICE # 价格类型
|
||||
@ -165,11 +170,14 @@ class CtaEngine(object):
|
||||
|
||||
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))
|
||||
|
||||
else:
|
||||
self.writeCtaLog(u'%s发送委托,%s, %s,%s,%s@%s'
|
||||
% ('CtaEngine', vtSymbol, req.offset, req.direction, volume, price))
|
||||
return vtOrderID
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
@ -413,13 +421,14 @@ class CtaEngine(object):
|
||||
pos = event.dict_['data']
|
||||
|
||||
# 更新持仓缓存数据
|
||||
if pos.vtSymbol in self.tickStrategyDict:
|
||||
posBuffer = self.posBufferDict.get(pos.vtSymbol, None)
|
||||
if not posBuffer:
|
||||
posBuffer = PositionBuffer()
|
||||
posBuffer.vtSymbol = pos.vtSymbol
|
||||
self.posBufferDict[pos.vtSymbol] = posBuffer
|
||||
posBuffer.updatePositionData(pos)
|
||||
#if pos.vtSymbol in self.tickStrategyDict:
|
||||
|
||||
posBuffer = self.posBufferDict.get(pos.vtSymbol, None)
|
||||
if not posBuffer:
|
||||
posBuffer = PositionBuffer()
|
||||
posBuffer.vtSymbol = pos.vtSymbol
|
||||
self.posBufferDict[pos.vtSymbol] = posBuffer
|
||||
posBuffer.updatePositionData(pos)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def registerEvent(self):
|
||||
@ -440,6 +449,60 @@ class CtaEngine(object):
|
||||
# 注册定时器事件
|
||||
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):
|
||||
"""定时器事件"""
|
||||
|
||||
|
@ -68,7 +68,7 @@ class RmEngineManager(QtGui.QWidget):
|
||||
self.spinPercentLimit = RmSpinBox(self.rmEngine.percentLimit)
|
||||
|
||||
# 最大净值止损比例,满足后强制止损
|
||||
self.spinLossPercentLimit = RmSpinBox(self.rmEngine.lossPercentLimit)
|
||||
self.spinLossLimit = RmSpinBox(self.rmEngine.lossLimit)
|
||||
|
||||
buttonClearOrderFlowCount = QtGui.QPushButton(u'清空流控计数')
|
||||
buttonClearTradeCount = QtGui.QPushButton(u'清空总成交计数')
|
||||
@ -96,8 +96,8 @@ class RmEngineManager(QtGui.QWidget):
|
||||
grid.addWidget(RmLine(), 10, 0, 1, 2)
|
||||
grid.addWidget(Label(u'仓位上限(1~100)'), 11, 0)
|
||||
grid.addWidget(self.spinPercentLimit, 11, 1)
|
||||
grid.addWidget(Label(u'强制止损比例'), 12, 0)
|
||||
grid.addWidget(self.spinLossPercentLimit, 12, 1)
|
||||
grid.addWidget(Label(u'强制止损净值'), 12, 0)
|
||||
grid.addWidget(self.spinLossLimit, 12, 1)
|
||||
|
||||
hbox = QtGui.QHBoxLayout()
|
||||
hbox.addWidget(buttonClearOrderFlowCount)
|
||||
@ -117,7 +117,7 @@ class RmEngineManager(QtGui.QWidget):
|
||||
self.spinTradeLimit.valueChanged.connect(self.rmEngine.setTradeLimit)
|
||||
self.spinWorkingOrderLimit.valueChanged.connect(self.rmEngine.setWorkingOrderLimit)
|
||||
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)
|
||||
buttonClearOrderFlowCount.clicked.connect(self.rmEngine.clearOrderFlowCount)
|
||||
|
@ -417,9 +417,14 @@ class DataEngine(object):
|
||||
# 目的:1、
|
||||
|
||||
position = event.dict_['data']
|
||||
|
||||
symbol = position.symbol
|
||||
|
||||
if symbol is None:
|
||||
return
|
||||
|
||||
if len(symbol) == 0:
|
||||
return
|
||||
|
||||
# 已存在,不做更新
|
||||
if symbol in self.subscribedSymbols:
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user