[Add]增加OM策略模块的GUI组件
This commit is contained in:
parent
32cfd415e3
commit
33a65208e5
@ -19,6 +19,7 @@ OM_DB_NAME = 'VnTrader_OptionMaster_Db'
|
||||
|
||||
# 事件定义
|
||||
EVENT_OM_LOG = 'eOmLog'
|
||||
EVENT_OM_STRATEGY = 'eOmStrategy'
|
||||
|
||||
|
||||
########################################################################
|
||||
|
@ -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)
|
@ -127,4 +127,11 @@ class OmStrategyTemplate(object):
|
||||
"""获取持仓组合信息"""
|
||||
return self.engine.getPortfolio()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def putEvent(self):
|
||||
"""发出GUI更新通知"""
|
||||
self.engine.putStrategyEvent(self.name)
|
||||
|
||||
|
||||
|
||||
|
||||
|
7
vnpy/trader/app/optionMaster/strategy_setting.json
Normal file
7
vnpy/trader/app/optionMaster/strategy_setting.json
Normal file
@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"name": "double ema",
|
||||
"className": "EmaDemoStrategy",
|
||||
"vtSymbol": "IF1706"
|
||||
}
|
||||
]
|
269
vnpy/trader/app/optionMaster/uiOmStrategyManager.py
Normal file
269
vnpy/trader/app/optionMaster/uiOmStrategyManager.py
Normal 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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user