commit
7f2c47f425
@ -4,5 +4,6 @@
|
|||||||
"tradeLimit": 100,
|
"tradeLimit": 100,
|
||||||
"orderSizeLimit": 10,
|
"orderSizeLimit": 10,
|
||||||
"active": true,
|
"active": true,
|
||||||
"orderFlowLimit": 10
|
"orderCountLimit": 400,
|
||||||
|
"orderFlowLimit": 50
|
||||||
}
|
}
|
@ -21,8 +21,8 @@ class RmEngine(object):
|
|||||||
"""风控引擎"""
|
"""风控引擎"""
|
||||||
settingFileName = 'RM_setting.json'
|
settingFileName = 'RM_setting.json'
|
||||||
path = os.path.abspath(os.path.dirname(__file__))
|
path = os.path.abspath(os.path.dirname(__file__))
|
||||||
settingFileName = os.path.join(path, settingFileName)
|
settingFileName = os.path.join(path, settingFileName)
|
||||||
|
|
||||||
name = u'风控模块'
|
name = u'风控模块'
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
@ -30,47 +30,53 @@ class RmEngine(object):
|
|||||||
"""Constructor"""
|
"""Constructor"""
|
||||||
self.mainEngine = mainEngine
|
self.mainEngine = mainEngine
|
||||||
self.eventEngine = eventEngine
|
self.eventEngine = eventEngine
|
||||||
|
|
||||||
# 是否启动风控
|
# 是否启动风控
|
||||||
self.active = False
|
self.active = False
|
||||||
|
|
||||||
# 流控相关
|
# 流控相关
|
||||||
self.orderFlowCount = EMPTY_INT # 单位时间内委托计数
|
self.orderFlowCount = EMPTY_INT # 单位时间内委托计数
|
||||||
self.orderFlowLimit = EMPTY_INT # 委托限制
|
self.orderFlowLimit = EMPTY_INT # 委托限制
|
||||||
self.orderFlowClear = EMPTY_INT # 计数清空时间(秒)
|
self.orderFlowClear = EMPTY_INT # 计数清空时间(秒)
|
||||||
self.orderFlowTimer = EMPTY_INT # 计数清空时间计时
|
self.orderFlowTimer = EMPTY_INT # 计数清空时间计时
|
||||||
|
|
||||||
# 单笔委托相关
|
# 单笔委托相关
|
||||||
self.orderSizeLimit = EMPTY_INT # 单笔委托最大限制
|
self.orderSizeLimit = EMPTY_INT # 单笔委托最大限制
|
||||||
|
|
||||||
# 成交统计相关
|
# 成交统计相关
|
||||||
self.tradeCount = EMPTY_INT # 当日成交合约数量统计
|
self.tradeCount = EMPTY_INT # 当日成交合约数量统计
|
||||||
self.tradeLimit = EMPTY_INT # 当日成交合约数量限制
|
self.tradeLimit = EMPTY_INT # 当日成交合约数量限制
|
||||||
|
|
||||||
|
# 单品种报撤
|
||||||
|
self.orderCountLimit = 450
|
||||||
|
self.orderCount = {}
|
||||||
|
|
||||||
# 活动合约相关
|
# 活动合约相关
|
||||||
self.workingOrderLimit = EMPTY_INT # 活动合约最大限制
|
self.workingOrderLimit = EMPTY_INT # 活动合约最大限制
|
||||||
|
|
||||||
self.loadSetting()
|
self.loadSetting()
|
||||||
self.registerEvent()
|
self.registerEvent()
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def loadSetting(self):
|
def loadSetting(self):
|
||||||
"""读取配置"""
|
"""读取配置"""
|
||||||
with open(self.settingFileName) as f:
|
with open(self.settingFileName) as f:
|
||||||
d = json.load(f)
|
d = json.load(f)
|
||||||
|
|
||||||
# 设置风控参数
|
# 设置风控参数
|
||||||
self.active = d['active']
|
self.active = d['active']
|
||||||
|
|
||||||
self.orderFlowLimit = d['orderFlowLimit']
|
self.orderFlowLimit = d['orderFlowLimit']
|
||||||
self.orderFlowClear = d['orderFlowClear']
|
self.orderFlowClear = d['orderFlowClear']
|
||||||
|
|
||||||
self.orderSizeLimit = d['orderSizeLimit']
|
self.orderSizeLimit = d['orderSizeLimit']
|
||||||
|
|
||||||
self.tradeLimit = d['tradeLimit']
|
self.tradeLimit = d['tradeLimit']
|
||||||
|
|
||||||
self.workingOrderLimit = d['workingOrderLimit']
|
self.workingOrderLimit = d['workingOrderLimit']
|
||||||
|
|
||||||
|
self.orderCountLimit = d['orderCountLimit']
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def saveSetting(self):
|
def saveSetting(self):
|
||||||
"""保存风控参数"""
|
"""保存风控参数"""
|
||||||
@ -79,42 +85,55 @@ class RmEngine(object):
|
|||||||
d = {}
|
d = {}
|
||||||
|
|
||||||
d['active'] = self.active
|
d['active'] = self.active
|
||||||
|
|
||||||
d['orderFlowLimit'] = self.orderFlowLimit
|
d['orderFlowLimit'] = self.orderFlowLimit
|
||||||
d['orderFlowClear'] = self.orderFlowClear
|
d['orderFlowClear'] = self.orderFlowClear
|
||||||
|
|
||||||
d['orderSizeLimit'] = self.orderSizeLimit
|
d['orderSizeLimit'] = self.orderSizeLimit
|
||||||
|
|
||||||
d['tradeLimit'] = self.tradeLimit
|
d['tradeLimit'] = self.tradeLimit
|
||||||
|
|
||||||
d['workingOrderLimit'] = self.workingOrderLimit
|
d['workingOrderLimit'] = self.workingOrderLimit
|
||||||
|
|
||||||
|
d['orderCountLimit'] = self.orderCountLimit
|
||||||
|
|
||||||
# 写入json
|
# 写入json
|
||||||
jsonD = json.dumps(d, indent=4)
|
jsonD = json.dumps(d, indent=4)
|
||||||
f.write(jsonD)
|
f.write(jsonD)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def registerEvent(self):
|
def registerEvent(self):
|
||||||
"""注册事件监听"""
|
"""注册事件监听"""
|
||||||
self.eventEngine.register(EVENT_TRADE, self.updateTrade)
|
self.eventEngine.register(EVENT_TRADE, self.updateTrade)
|
||||||
self.eventEngine.register(EVENT_TIMER, self.updateTimer)
|
self.eventEngine.register(EVENT_TIMER, self.updateTimer)
|
||||||
|
self.eventEngine.register(EVENT_ORDER, self.updateOrder)
|
||||||
|
|
||||||
|
def updateOrder(self, event):
|
||||||
|
"""更新成交数据"""
|
||||||
|
order = event.dict_['data']
|
||||||
|
if not self.orderCount.has_key(order.symbol):
|
||||||
|
self.orderCount[order.symbol] = 0
|
||||||
|
if order.status in [STATUS_NOTTRADED, STATUS_PARTTRADED, STATUS_ALLTRADED, STATUS_UNKNOWN]:
|
||||||
|
self.orderCount[order.symbol] += 1
|
||||||
|
elif order.status == STATUS_CANCELLED:
|
||||||
|
self.orderCount[order.symbol] += 2
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def updateTrade(self, event):
|
def updateTrade(self, event):
|
||||||
"""更新成交数据"""
|
"""更新成交数据"""
|
||||||
trade = event.dict_['data']
|
trade = event.dict_['data']
|
||||||
self.tradeCount += trade.volume
|
self.tradeCount += trade.volume
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def updateTimer(self, event):
|
def updateTimer(self, event):
|
||||||
"""更新定时器"""
|
"""更新定时器"""
|
||||||
self.orderFlowTimer += 1
|
self.orderFlowTimer += 1
|
||||||
|
|
||||||
# 如果计时超过了流控清空的时间间隔,则执行清空
|
# 如果计时超过了流控清空的时间间隔,则执行清空
|
||||||
if self.orderFlowTimer >= self.orderFlowClear:
|
if self.orderFlowTimer >= self.orderFlowClear:
|
||||||
self.orderFlowCount = 0
|
self.orderFlowCount = 0
|
||||||
self.orderFlowTimer = 0
|
self.orderFlowTimer = 0
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def writeRiskLog(self, content):
|
def writeRiskLog(self, content):
|
||||||
"""快速发出日志事件"""
|
"""快速发出日志事件"""
|
||||||
@ -122,95 +141,105 @@ class RmEngine(object):
|
|||||||
|
|
||||||
if platform.uname() == 'Windows':
|
if platform.uname() == 'Windows':
|
||||||
import winsound
|
import winsound
|
||||||
winsound.PlaySound("SystemHand", winsound.SND_ASYNC)
|
winsound.PlaySound("SystemHand", winsound.SND_ASYNC)
|
||||||
|
|
||||||
# 发出日志事件
|
# 发出日志事件
|
||||||
log = VtLogData()
|
log = VtLogData()
|
||||||
log.logContent = content
|
log.logContent = content
|
||||||
log.gatewayName = self.name
|
log.gatewayName = self.name
|
||||||
event = Event(type_=EVENT_LOG)
|
event = Event(type_=EVENT_LOG)
|
||||||
event.dict_['data'] = log
|
event.dict_['data'] = log
|
||||||
self.eventEngine.put(event)
|
self.eventEngine.put(event)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def checkRisk(self, orderReq):
|
def checkRisk(self, orderReq):
|
||||||
"""检查风险"""
|
"""检查风险"""
|
||||||
# 如果没有启动风控检查,则直接返回成功
|
# 如果没有启动风控检查,则直接返回成功
|
||||||
if not self.active:
|
if not self.active:
|
||||||
return True
|
return RISK_OK
|
||||||
|
|
||||||
# 检查委托数量
|
# 检查委托数量
|
||||||
if orderReq.volume > self.orderSizeLimit:
|
if orderReq.volume > self.orderSizeLimit:
|
||||||
self.writeRiskLog(u'单笔委托数量%s,超过限制%s'
|
self.writeRiskLog(u'单笔委托数量%s,超过限制%s'
|
||||||
%(orderReq.volume, self.orderSizeLimit))
|
%(orderReq.volume, self.orderSizeLimit))
|
||||||
return False
|
return RISK_ERROR_ORDER_SIZE
|
||||||
|
|
||||||
# 检查成交合约量
|
# 检查成交合约量
|
||||||
if self.tradeCount >= self.tradeLimit:
|
if self.tradeCount >= self.tradeLimit:
|
||||||
self.writeRiskLog(u'今日总成交合约数量%s,超过限制%s'
|
self.writeRiskLog(u'今日总成交合约数量%s,超过限制%s'
|
||||||
%(self.tradeCount, self.tradeLimit))
|
%(self.tradeCount, self.tradeLimit))
|
||||||
return False
|
return RISK_ERROR_TRADE_COUNT
|
||||||
|
|
||||||
# 检查流控
|
# 检查流控
|
||||||
if self.orderFlowCount >= self.orderFlowLimit:
|
if self.orderFlowCount >= self.orderFlowLimit:
|
||||||
self.writeRiskLog(u'委托流数量%s,超过限制每%s秒%s'
|
self.writeRiskLog(u'委托流数量%s,超过限制每%s秒%s'
|
||||||
%(self.orderFlowCount, self.orderFlowClear, self.orderFlowLimit))
|
%(self.orderFlowCount, self.orderFlowClear, self.orderFlowLimit))
|
||||||
return False
|
return RISK_ERROR_ORDER_FLOW_COUNT
|
||||||
|
|
||||||
# 检查总活动合约
|
# 检查总活动合约
|
||||||
workingOrderCount = len(self.mainEngine.getAllWorkingOrders())
|
workingOrderCount = len(self.mainEngine.getAllWorkingOrders())
|
||||||
if workingOrderCount >= self.workingOrderLimit:
|
if workingOrderCount >= self.workingOrderLimit:
|
||||||
self.writeRiskLog(u'当前活动委托数量%s,超过限制%s'
|
self.writeRiskLog(u'当前活动委托数量%s,超过限制%s'
|
||||||
%(workingOrderCount, self.workingOrderLimit))
|
%(workingOrderCount, self.workingOrderLimit))
|
||||||
return False
|
return RISK_ERROR_WORKING_ORDER
|
||||||
|
|
||||||
|
if self.orderCount.has_key(orderReq.symbol) and self.orderCount[orderReq.symbol] > self.orderCountLimit:
|
||||||
|
self.writeRiskLog(u'%s当日报撤%s,超过限制%s'
|
||||||
|
% (orderReq.symbol, self.orderCount[orderReq.symbol], self.orderCountLimit))
|
||||||
|
return RISK_ERROR_ORDER_SEND
|
||||||
|
|
||||||
# 对于通过风控的委托,增加流控计数
|
# 对于通过风控的委托,增加流控计数
|
||||||
self.orderFlowCount += 1
|
self.orderFlowCount += 1
|
||||||
|
|
||||||
return True
|
return RISK_OK
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def clearOrderFlowCount(self):
|
def clearOrderFlowCount(self):
|
||||||
"""清空流控计数"""
|
"""清空流控计数"""
|
||||||
self.orderFlowCount = 0
|
self.orderFlowCount = 0
|
||||||
self.writeRiskLog(u'清空流控计数')
|
self.writeRiskLog(u'清空流控计数')
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def clearTradeCount(self):
|
def clearTradeCount(self):
|
||||||
"""清空成交数量计数"""
|
"""清空成交数量计数"""
|
||||||
self.tradeCount = 0
|
self.tradeCount = 0
|
||||||
self.writeRiskLog(u'清空总成交计数')
|
self.writeRiskLog(u'清空总成交计数')
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def setOrderFlowLimit(self, n):
|
def setOrderFlowLimit(self, n):
|
||||||
"""设置流控限制"""
|
"""设置流控限制"""
|
||||||
self.orderFlowLimit = n
|
self.orderFlowLimit = n
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def setOrderFlowClear(self, n):
|
def setOrderFlowClear(self, n):
|
||||||
"""设置流控清空时间"""
|
"""设置流控清空时间"""
|
||||||
self.orderFlowClear = n
|
self.orderFlowClear = n
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def setOrderSizeLimit(self, n):
|
def setOrderSizeLimit(self, n):
|
||||||
"""设置委托最大限制"""
|
"""设置委托最大限制"""
|
||||||
self.orderSizeLimit = n
|
self.orderSizeLimit = n
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def setTradeLimit(self, n):
|
def setTradeLimit(self, n):
|
||||||
"""设置成交限制"""
|
"""设置成交限制"""
|
||||||
self.tradeLimit = n
|
self.tradeLimit = n
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def setWorkingOrderLimit(self, n):
|
def setWorkingOrderLimit(self, n):
|
||||||
"""设置活动合约限制"""
|
"""设置活动合约限制"""
|
||||||
self.workingOrderLimit = n
|
self.workingOrderLimit = n
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setOrderCountLimit(self, n):
|
||||||
|
"""设置单品种报撤次数上限"""
|
||||||
|
self.orderCountLimit = n
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def switchEngineStatus(self):
|
def switchEngineStatus(self):
|
||||||
"""开关风控引擎"""
|
"""开关风控引擎"""
|
||||||
self.active = not self.active
|
self.active = not self.active
|
||||||
|
|
||||||
if self.active:
|
if self.active:
|
||||||
self.writeRiskLog(u'风险管理功能启动')
|
self.writeRiskLog(u'风险管理功能启动')
|
||||||
else:
|
else:
|
||||||
|
@ -68,6 +68,7 @@ class RmEngineManager(QtGui.QWidget):
|
|||||||
self.spinOrderSizeLimit = RmSpinBox(self.rmEngine.orderSizeLimit)
|
self.spinOrderSizeLimit = RmSpinBox(self.rmEngine.orderSizeLimit)
|
||||||
self.spinTradeLimit = RmSpinBox(self.rmEngine.tradeLimit)
|
self.spinTradeLimit = RmSpinBox(self.rmEngine.tradeLimit)
|
||||||
self.spinWorkingOrderLimit = RmSpinBox(self.rmEngine.workingOrderLimit)
|
self.spinWorkingOrderLimit = RmSpinBox(self.rmEngine.workingOrderLimit)
|
||||||
|
self.spinOrderCountLimit = RmSpinBox(self.rmEngine.orderCountLimit)
|
||||||
|
|
||||||
buttonClearOrderFlowCount = QtGui.QPushButton(u'清空流控计数')
|
buttonClearOrderFlowCount = QtGui.QPushButton(u'清空流控计数')
|
||||||
buttonClearTradeCount = QtGui.QPushButton(u'清空总成交计数')
|
buttonClearTradeCount = QtGui.QPushButton(u'清空总成交计数')
|
||||||
@ -91,6 +92,8 @@ class RmEngineManager(QtGui.QWidget):
|
|||||||
grid.addWidget(RmLine(), 8, 0, 1, 2)
|
grid.addWidget(RmLine(), 8, 0, 1, 2)
|
||||||
grid.addWidget(Label(u'活动订单上限'), 9, 0)
|
grid.addWidget(Label(u'活动订单上限'), 9, 0)
|
||||||
grid.addWidget(self.spinWorkingOrderLimit, 9, 1)
|
grid.addWidget(self.spinWorkingOrderLimit, 9, 1)
|
||||||
|
grid.addWidget(Label(u'单品种报撤次数上限'), 10, 0)
|
||||||
|
grid.addWidget(self.spinOrderCountLimit, 10, 1)
|
||||||
|
|
||||||
hbox = QtGui.QHBoxLayout()
|
hbox = QtGui.QHBoxLayout()
|
||||||
hbox.addWidget(buttonClearOrderFlowCount)
|
hbox.addWidget(buttonClearOrderFlowCount)
|
||||||
@ -109,7 +112,8 @@ class RmEngineManager(QtGui.QWidget):
|
|||||||
self.spinOrderSizeLimit.valueChanged.connect(self.rmEngine.setOrderSizeLimit)
|
self.spinOrderSizeLimit.valueChanged.connect(self.rmEngine.setOrderSizeLimit)
|
||||||
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.spinOrderCountLimit.valueChanged.connect(self.rmEngine.setOrderCountLimit)
|
||||||
|
|
||||||
self.buttonSwitchEngineStatus.clicked.connect(self.switchEngineSatus)
|
self.buttonSwitchEngineStatus.clicked.connect(self.switchEngineSatus)
|
||||||
buttonClearOrderFlowCount.clicked.connect(self.rmEngine.clearOrderFlowCount)
|
buttonClearOrderFlowCount.clicked.connect(self.rmEngine.clearOrderFlowCount)
|
||||||
buttonClearTradeCount.clicked.connect(self.rmEngine.clearTradeCount)
|
buttonClearTradeCount.clicked.connect(self.rmEngine.clearTradeCount)
|
||||||
|
@ -6,6 +6,18 @@ EMPTY_UNICODE = u''
|
|||||||
EMPTY_INT = 0
|
EMPTY_INT = 0
|
||||||
EMPTY_FLOAT = 0.0
|
EMPTY_FLOAT = 0.0
|
||||||
|
|
||||||
|
# 风控常量
|
||||||
|
RISK_OK = 0 # 风控正常
|
||||||
|
RISK_ERROR_ORDER_SIZE = 1 # 单笔委托数量超限
|
||||||
|
RISK_ERROR_TRADE_COUNT = 2 # 今日总成交合约数量超限
|
||||||
|
RISK_ERROR_ORDER_FLOW_COUNT = 3 # 委托流数量超限
|
||||||
|
RISK_ERROR_WORKING_ORDER = 4 # 当前活动委托数量超限
|
||||||
|
RISK_ERROR_ORDER_SEND = 5 # 当日单品种报撤次数超限
|
||||||
|
|
||||||
|
RISK_MESSAGE = {RISK_ERROR_ORDER_SIZE: u'单笔委托数量超限', RISK_ERROR_TRADE_COUNT: u'今日总成交合约数量超限',
|
||||||
|
RISK_ERROR_ORDER_FLOW_COUNT: u'委托流数量超限', RISK_ERROR_WORKING_ORDER: u'当前活动委托数量超限',
|
||||||
|
RISK_ERROR_ORDER_SEND: u'当日单品种报撤次数超限'}
|
||||||
|
|
||||||
# 方向常量
|
# 方向常量
|
||||||
DIRECTION_NONE = u'无方向'
|
DIRECTION_NONE = u'无方向'
|
||||||
DIRECTION_LONG = u'多'
|
DIRECTION_LONG = u'多'
|
||||||
|
@ -188,9 +188,10 @@ class MainEngine(object):
|
|||||||
def sendOrder(self, orderReq, gatewayName):
|
def sendOrder(self, orderReq, gatewayName):
|
||||||
"""对特定接口发单"""
|
"""对特定接口发单"""
|
||||||
# 如果风控检查失败则不发单
|
# 如果风控检查失败则不发单
|
||||||
if not self.rmEngine.checkRisk(orderReq):
|
riskResult = self.rmEngine.checkRisk(orderReq)
|
||||||
return ''
|
if riskResult != RISK_OK:
|
||||||
|
return riskResult
|
||||||
|
|
||||||
if gatewayName in self.gatewayDict:
|
if gatewayName in self.gatewayDict:
|
||||||
gateway = self.gatewayDict[gatewayName]
|
gateway = self.gatewayDict[gatewayName]
|
||||||
return gateway.sendOrder(orderReq)
|
return gateway.sendOrder(orderReq)
|
||||||
|
Loading…
Reference in New Issue
Block a user