[Add]增加OM策略模块的GUI组件

This commit is contained in:
vn.py 2018-01-16 11:37:39 +08:00
parent 32cfd415e3
commit 33a65208e5
6 changed files with 359 additions and 5 deletions

View File

@ -19,6 +19,7 @@ OM_DB_NAME = 'VnTrader_OptionMaster_Db'
# 事件定义
EVENT_OM_LOG = 'eOmLog'
EVENT_OM_STRATEGY = 'eOmStrategy'
########################################################################

View File

@ -20,7 +20,7 @@ from vnpy.trader.vtConstant import (PRODUCT_OPTION, OPTION_CALL, OPTION_PUT,
from vnpy.pricing import black, bs, crr
from .omBase import (OmOption, OmUnderlying, OmChain, OmPortfolio,
EVENT_OM_LOG,
EVENT_OM_LOG, EVENT_OM_STRATEGY,
OM_DB_NAME)
from .strategy import STRATEGY_CLASS
@ -50,6 +50,8 @@ class OmEngine(object):
self.portfolio = None
self.optionContractDict = {} # symbol:contract
self.strategyEngine = OmStrategyEngine(self, eventEngine)
self.registerEvent()
#----------------------------------------------------------------------
@ -226,7 +228,7 @@ class OmEngine(object):
########################################################################
class OmStrategyEngine(object):
"""策略引擎"""
settingFileName = 'OM_setting.json'
settingFileName = 'strategy_setting.json'
settingfilePath = getJsonPath(settingFileName, __file__)
#----------------------------------------------------------------------
@ -249,7 +251,7 @@ class OmStrategyEngine(object):
"""注册事件监听"""
self.eventEngine.register(EVENT_TICK, self.processTickEvent)
self.eventEngine.register(EVENT_TRADE, self.processTradeEvent)
self.eventEngine.register(EVENT_ORDER, self.processOrdervent)
self.eventEngine.register(EVENT_ORDER, self.processOrderEvent)
self.eventEngine.register(EVENT_TIMER, self.processTimerEvent)
#----------------------------------------------------------------------
@ -449,5 +451,57 @@ class OmStrategyEngine(object):
def getPortfolio(self):
"""获取持仓组合信息"""
return self.portfolio
#----------------------------------------------------------------------
def putStrategyEvent(self, name):
"""触发策略状态变化事件通常用于通知GUI更新"""
event = Event(EVENT_OM_STRATEGY+name)
self.eventEngine.put(event)
#----------------------------------------------------------------------
def getStrategyVar(self, name):
"""获取策略当前的变量字典"""
if name in self.strategyDict:
strategy = self.strategyDict[name]
varDict = OrderedDict()
for key in strategy.varList:
varDict[key] = strategy.__getattribute__(key)
return varDict
else:
self.writeLog(u'策略实例不存在:' + name)
return None
#----------------------------------------------------------------------
def getStrategyParam(self, name):
"""获取策略的参数字典"""
if name in self.strategyDict:
strategy = self.strategyDict[name]
paramDict = OrderedDict()
for key in strategy.paramList:
paramDict[key] = strategy.__getattribute__(key)
return paramDict
else:
self.writeLog(u'策略实例不存在:' + name)
return None
#----------------------------------------------------------------------
def initAll(self):
"""全部初始化"""
for name in self.strategyDict.keys():
self.initStrategy(name)
#----------------------------------------------------------------------
def startAll(self):
"""全部启动"""
for name in self.strategyDict.keys():
self.startStrategy(name)
#----------------------------------------------------------------------
def stopAll(self):
"""全部停止"""
for name in self.strategyDict.keys():
self.stopStrategy(name)

View File

@ -127,4 +127,11 @@ class OmStrategyTemplate(object):
"""获取持仓组合信息"""
return self.engine.getPortfolio()
#----------------------------------------------------------------------
def putEvent(self):
"""发出GUI更新通知"""
self.engine.putStrategyEvent(self.name)

View File

@ -0,0 +1,7 @@
[
{
"name": "double ema",
"className": "EmaDemoStrategy",
"vtSymbol": "IF1706"
}
]

View File

@ -0,0 +1,269 @@
# encoding: UTF-8
'''
OM策略引擎的GUI控制组件
'''
from vnpy.event import Event
from vnpy.trader.vtEvent import *
from vnpy.trader.uiBasicWidget import QtGui, QtCore, QtWidgets, BasicCell
from .omBase import EVENT_OM_LOG, EVENT_OM_STRATEGY
########################################################################
class ValueMonitor(QtWidgets.QTableWidget):
"""参数监控"""
#----------------------------------------------------------------------
def __init__(self, parent=None):
"""Constructor"""
super(ValueMonitor, self).__init__(parent)
self.keyCellDict = {}
self.data = None
self.inited = False
self.initUi()
#----------------------------------------------------------------------
def initUi(self):
"""初始化界面"""
self.setRowCount(1)
self.verticalHeader().setVisible(False)
self.setEditTriggers(self.NoEditTriggers)
self.setMaximumHeight(self.sizeHint().height())
#----------------------------------------------------------------------
def updateData(self, data):
"""更新数据"""
if not self.inited:
self.setColumnCount(len(data))
self.setHorizontalHeaderLabels(data.keys())
col = 0
for k, v in data.items():
cell = QtWidgets.QTableWidgetItem(unicode(v))
self.keyCellDict[k] = cell
self.setItem(0, col, cell)
col += 1
self.inited = True
else:
for k, v in data.items():
cell = self.keyCellDict[k]
cell.setText(unicode(v))
########################################################################
class StrategyManager(QtWidgets.QGroupBox):
"""策略管理组件"""
signal = QtCore.Signal(type(Event()))
#----------------------------------------------------------------------
def __init__(self, engine, eventEngine, name, parent=None):
"""Constructor"""
super(StrategyManager, self).__init__(parent)
self.engine = engine
self.eventEngine = eventEngine
self.name = name
self.initUi()
self.updateMonitor()
self.registerEvent()
#----------------------------------------------------------------------
def initUi(self):
"""初始化界面"""
self.setTitle(self.name)
self.paramMonitor = ValueMonitor(self)
self.varMonitor = ValueMonitor(self)
height = 65
self.paramMonitor.setFixedHeight(height)
self.varMonitor.setFixedHeight(height)
buttonInit = QtWidgets.QPushButton(u'初始化')
buttonStart = QtWidgets.QPushButton(u'启动')
buttonStop = QtWidgets.QPushButton(u'停止')
buttonInit.clicked.connect(self.init)
buttonStart.clicked.connect(self.start)
buttonStop.clicked.connect(self.stop)
hbox1 = QtWidgets.QHBoxLayout()
hbox1.addWidget(buttonInit)
hbox1.addWidget(buttonStart)
hbox1.addWidget(buttonStop)
hbox1.addStretch()
hbox2 = QtWidgets.QHBoxLayout()
hbox2.addWidget(self.paramMonitor)
hbox3 = QtWidgets.QHBoxLayout()
hbox3.addWidget(self.varMonitor)
vbox = QtWidgets.QVBoxLayout()
vbox.addLayout(hbox1)
vbox.addLayout(hbox2)
vbox.addLayout(hbox3)
self.setLayout(vbox)
#----------------------------------------------------------------------
def updateMonitor(self, event=None):
"""显示策略最新状态"""
paramDict = self.engine.getStrategyParam(self.name)
if paramDict:
self.paramMonitor.updateData(paramDict)
varDict = self.engine.getStrategyVar(self.name)
if varDict:
self.varMonitor.updateData(varDict)
#----------------------------------------------------------------------
def registerEvent(self):
"""注册事件监听"""
self.signal.connect(self.updateMonitor)
self.eventEngine.register(EVENT_OM_STRATEGY+self.name, self.signal.emit)
#----------------------------------------------------------------------
def init(self):
"""初始化策略"""
self.engine.initStrategy(self.name)
#----------------------------------------------------------------------
def start(self):
"""启动策略"""
self.engine.startStrategy(self.name)
#----------------------------------------------------------------------
def stop(self):
"""停止策略"""
self.engine.stopStrategy(self.name)
########################################################################
class StrategyEngineManager(QtWidgets.QWidget):
"""引擎管理组件"""
signal = QtCore.Signal(type(Event()))
#----------------------------------------------------------------------
def __init__(self, omEngine, parent=None):
"""Constructor"""
super(StrategyEngineManager, self).__init__(parent)
self.engine = omEngine.strategyEngine
self.eventEngine = omEngine.eventEngine
self.strategyLoaded = False
self.initUi()
self.registerEvent()
# 记录日志
self.engine.writeLog(u'期权策略引擎启动')
#----------------------------------------------------------------------
def initUi(self):
"""初始化界面"""
self.setWindowTitle(u'期权策略')
# 按钮
loadButton = QtWidgets.QPushButton(u'加载策略')
initAllButton = QtWidgets.QPushButton(u'全部初始化')
startAllButton = QtWidgets.QPushButton(u'全部启动')
stopAllButton = QtWidgets.QPushButton(u'全部停止')
loadButton.clicked.connect(self.load)
initAllButton.clicked.connect(self.initAll)
startAllButton.clicked.connect(self.startAll)
stopAllButton.clicked.connect(self.stopAll)
# 滚动区域放置所有的StrategyManager
self.scrollArea = QtWidgets.QScrollArea()
self.scrollArea.setWidgetResizable(True)
# 日志监控
self.ctaLogMonitor = QtWidgets.QTextEdit()
self.ctaLogMonitor.setReadOnly(True)
self.ctaLogMonitor.setMaximumHeight(200)
# 设置布局
hbox2 = QtWidgets.QHBoxLayout()
hbox2.addWidget(loadButton)
hbox2.addWidget(initAllButton)
hbox2.addWidget(startAllButton)
hbox2.addWidget(stopAllButton)
hbox2.addStretch()
vbox = QtWidgets.QVBoxLayout()
vbox.addLayout(hbox2)
vbox.addWidget(self.scrollArea)
vbox.addWidget(self.ctaLogMonitor)
self.setLayout(vbox)
#----------------------------------------------------------------------
def initStrategyManager(self):
"""初始化策略管理组件界面"""
w = QtWidgets.QWidget()
vbox = QtWidgets.QVBoxLayout()
for name in self.engine.strategyDict.keys():
strategyManager = StrategyManager(self.engine, self.eventEngine, name)
vbox.addWidget(strategyManager)
vbox.addStretch()
w.setLayout(vbox)
self.scrollArea.setWidget(w)
#----------------------------------------------------------------------
def initAll(self):
"""全部初始化"""
self.engine.initAll()
#----------------------------------------------------------------------
def startAll(self):
"""全部启动"""
self.engine.startAll()
#----------------------------------------------------------------------
def stopAll(self):
"""全部停止"""
self.engine.stopAll()
#----------------------------------------------------------------------
def load(self):
"""加载策略"""
if not self.strategyLoaded:
self.engine.loadSetting()
self.initStrategyManager()
self.strategyLoaded = True
self.engine.writeLog(u'策略加载成功')
#----------------------------------------------------------------------
def updateLog(self, event):
"""更新相关日志"""
log = event.dict_['data']
content = '\t'.join([log.logTime, log.logContent])
self.ctaLogMonitor.append(content)
#----------------------------------------------------------------------
def registerEvent(self):
"""注册事件监听"""
self.signal.connect(self.updateLog)
self.eventEngine.register(EVENT_OM_LOG, self.signal.emit)

View File

@ -13,6 +13,7 @@ from .uiOmManualTrader import ManualTrader
from .uiOmGreeksMonitor import GreeksMonitor
from .uiOmVolatilityManager import VolatilityChart, VolatilityManager
from .uiOmAnalysisManager import AnalysisManager
from .uiOmStrategyManager import StrategyEngineManager
########################################################################
@ -75,6 +76,10 @@ class OmManager(QtWidgets.QWidget):
self.buttonAnalysisManager.clicked.connect(self.openAnalysisManager)
self.buttonAnalysisManager.setDisabled(True)
self.buttonStrategyManager = QtWidgets.QPushButton(u'策略交易')
self.buttonStrategyManager.clicked.connect(self.openStrategyManager)
self.buttonStrategyManager.setDisabled(True)
self.logMonitor = QtWidgets.QTextEdit()
self.logMonitor.setReadOnly(True)
@ -86,6 +91,7 @@ class OmManager(QtWidgets.QWidget):
hbox.addWidget(self.buttonVolatilityChart)
hbox.addWidget(self.buttonVolatilityManager)
hbox.addWidget(self.buttonAnalysisManager)
hbox.addWidget(self.buttonStrategyManager)
hbox.addStretch()
hbox2 = QtWidgets.QHBoxLayout()
@ -123,6 +129,7 @@ class OmManager(QtWidgets.QWidget):
self.buttonVolatilityChart.setEnabled(True)
self.buttonVolatilityManager.setEnabled(True)
self.buttonAnalysisManager.setEnabled(True)
self.buttonStrategyManager.setEnabled(True)
#----------------------------------------------------------------------
def writeLog(self, content, time=''):
@ -182,7 +189,16 @@ class OmManager(QtWidgets.QWidget):
self.widgetDict['analysisManager'].showMaximized()
except KeyError:
self.widgetDict['analysisManager'] = AnalysisManager(self.omEngine)
self.widgetDict['analysisManager'].showMaximized()
self.widgetDict['analysisManager'].showMaximized()
#----------------------------------------------------------------------
def openStrategyManager(self):
"""打开策略交易组件"""
try:
self.widgetDict['strategyManager'].showMaximized()
except KeyError:
self.widgetDict['strategyManager'] = StrategyEngineManager(self.omEngine)
self.widgetDict['strategyManager'].showMaximized()
#----------------------------------------------------------------------
def close(self):