[Add]初步完成OptionMaster手动交易模块
This commit is contained in:
parent
b2aa6c5c2b
commit
e096455b44
@ -1 +1 @@
|
||||
B7/DvEptJ5IBD1LIj9SEFg==
|
||||
HqLpRXdyn/k8CK6bQvjTlg==
|
@ -43,6 +43,10 @@ DX_TARGET = 0.00001
|
||||
#----------------------------------------------------------------------
|
||||
def calculatePrice(f, k, r, t, v, cp):
|
||||
"""计算期权价格"""
|
||||
# 如果波动率为0,则直接返回期权空间价值
|
||||
if v <= 0:
|
||||
return max(0, cp * (f - k))
|
||||
|
||||
d1 = (log(f / k) + (0.5 * pow(v, 2) + r) * t) / (v * sqrt(t))
|
||||
d2 = d1 - v * sqrt(t)
|
||||
price = cp * (f * cdf(cp * d1) - k * cdf(cp * d2) * exp(-r * t))
|
||||
@ -121,9 +125,13 @@ def calculateImpv(price, f, k, r, t, cp):
|
||||
for i in range(50):
|
||||
# 计算当前猜测波动率对应的期权价格和vega值
|
||||
p = calculatePrice(f, k, r, t, v, cp)
|
||||
#print 'calculating vega', f, k, r, t, v, cp
|
||||
|
||||
vega = calculateOriginalVega(f, k, r, t, v, cp)
|
||||
|
||||
# 如果vega过小接近0,则直接返回
|
||||
if not vega:
|
||||
return v
|
||||
|
||||
# 计算误差
|
||||
dx = (price - p) / vega
|
||||
|
||||
|
@ -376,6 +376,7 @@ class OmPortfolio(object):
|
||||
self.underlyingDict = OrderedDict()
|
||||
self.chainDict = OrderedDict()
|
||||
self.optionDict = {}
|
||||
self.instrumentDict = {}
|
||||
|
||||
for underlying in underlyingList:
|
||||
self.underlyingDict[underlying.symbol] = underlying
|
||||
@ -385,6 +386,9 @@ class OmPortfolio(object):
|
||||
self.optionDict.update(chain.callDict)
|
||||
self.optionDict.update(chain.putDict)
|
||||
|
||||
self.instrumentDict.update(self.underlyingDict)
|
||||
self.instrumentDict.update(self.optionDict)
|
||||
|
||||
# 持仓数据
|
||||
self.longPos = EMPTY_INT
|
||||
self.shortPos = EMPTY_INT
|
||||
|
41
vnpy/trader/app/optionMaster/uiOmBase.py
Normal file
41
vnpy/trader/app/optionMaster/uiOmBase.py
Normal file
@ -0,0 +1,41 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
from vnpy.trader.uiQt import QtGui, QtWidgets, QtCore
|
||||
|
||||
COLOR_BID = QtGui.QColor(255,174,201)
|
||||
COLOR_ASK = QtGui.QColor(160,255,160)
|
||||
COLOR_STRIKE = QtGui.QColor(0,0,160)
|
||||
COLOR_POS = QtGui.QColor(225,255,255)
|
||||
COLOR_SYMBOL = QtGui.QColor('white')
|
||||
COLOR_BLACK = QtGui.QColor('black')
|
||||
|
||||
CALL_SUFFIX = '_call'
|
||||
PUT_SUFFIX = '_put'
|
||||
|
||||
STYLESHEET_START = "background-color: rgb(111,255,244); color: black"
|
||||
STYLESHEET_STOP = "background-color: rgb(255,201,111); color: black"
|
||||
|
||||
|
||||
########################################################################
|
||||
class OmCell(QtWidgets.QTableWidgetItem):
|
||||
"""单元格"""
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self, text=None, background=None, foreground=None, data=None):
|
||||
"""Constructor"""
|
||||
super(OmCell, self).__init__()
|
||||
|
||||
self.data = data
|
||||
self.background = None
|
||||
|
||||
if text:
|
||||
self.setText(text)
|
||||
|
||||
if foreground:
|
||||
self.setForeground(foreground)
|
||||
|
||||
if background:
|
||||
self.setBackground(background)
|
||||
self.background = background
|
||||
|
||||
self.setTextAlignment(QtCore.Qt.AlignCenter)
|
411
vnpy/trader/app/optionMaster/uiOmManualTrader.py
Normal file
411
vnpy/trader/app/optionMaster/uiOmManualTrader.py
Normal file
@ -0,0 +1,411 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
from vnpy.event import Event
|
||||
|
||||
from vnpy.trader.vtConstant import DIRECTION_LONG, DIRECTION_SHORT, OFFSET_OPEN, OFFSET_CLOSE, PRICETYPE_LIMITPRICE
|
||||
from vnpy.trader.vtObject import VtOrderReq
|
||||
from vnpy.trader.vtEvent import EVENT_TICK, EVENT_TRADE
|
||||
from vnpy.trader.uiBasicWidget import WorkingOrderMonitor, PositionMonitor
|
||||
|
||||
from uiOmBase import *
|
||||
|
||||
|
||||
|
||||
########################################################################
|
||||
class ChainMonitor(QtWidgets.QTableWidget):
|
||||
"""期权链监控"""
|
||||
headers = [
|
||||
u'代码',
|
||||
u'买价',
|
||||
u'买量',
|
||||
u'买隐波',
|
||||
u'卖价',
|
||||
u'卖量',
|
||||
u'卖隐波',
|
||||
u'净仓',
|
||||
u'行权价',
|
||||
u'净仓',
|
||||
u'买价',
|
||||
u'买量',
|
||||
u'买隐波',
|
||||
u'卖价',
|
||||
u'卖量',
|
||||
u'卖隐波',
|
||||
u'代码'
|
||||
]
|
||||
|
||||
signalTick = QtCore.pyqtSignal(type(Event()))
|
||||
signalPos = QtCore.pyqtSignal(type(Event()))
|
||||
signalTrade = QtCore.pyqtSignal(type(Event()))
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self, omEngine, eventEngine, parent=None):
|
||||
"""Constructor"""
|
||||
super(ChainMonitor, self).__init__(parent)
|
||||
|
||||
self.omEngine = omEngine
|
||||
self.eventEngine = eventEngine
|
||||
|
||||
# 保存代码和持仓的字典
|
||||
self.bidPriceDict = {}
|
||||
self.bidVolumeDict = {}
|
||||
self.bidImpvDict = {}
|
||||
self.askPriceDict = {}
|
||||
self.askVolumeDict = {}
|
||||
self.askImpvDict = {}
|
||||
self.posDict = {}
|
||||
|
||||
# 保存期权对象的字典
|
||||
portfolio = omEngine.portfolio
|
||||
|
||||
self.instrumentDict = {}
|
||||
self.instrumentDict.update(portfolio.optionDict)
|
||||
self.instrumentDict.update(portfolio.underlyingDict)
|
||||
|
||||
# 初始化
|
||||
self.initUi()
|
||||
self.registerEvent()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def initUi(self):
|
||||
"""初始化界面"""
|
||||
portfolio = self.omEngine.portfolio
|
||||
|
||||
# 初始化表格
|
||||
self.setColumnCount(len(self.headers))
|
||||
self.setHorizontalHeaderLabels(self.headers)
|
||||
|
||||
rowCount = 0
|
||||
rowCount += len(portfolio.underlyingDict)
|
||||
rowCount += len(portfolio.chainDict)
|
||||
for chain in portfolio.chainDict.values():
|
||||
rowCount += len(chain.callDict)
|
||||
self.setRowCount(rowCount)
|
||||
|
||||
self.verticalHeader().setVisible(False)
|
||||
self.setEditTriggers(self.NoEditTriggers)
|
||||
|
||||
for i in range(self.columnCount()):
|
||||
self.horizontalHeader().setResizeMode(i, QtWidgets.QHeaderView.Stretch)
|
||||
self.horizontalHeader().setResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
|
||||
self.horizontalHeader().setResizeMode(self.columnCount()-1, QtWidgets.QHeaderView.ResizeToContents)
|
||||
|
||||
# 初始化标的单元格
|
||||
row = 0
|
||||
|
||||
for underlying in portfolio.underlyingDict.values():
|
||||
symbol = underlying.symbol
|
||||
|
||||
cellSymbol = OmCell(symbol, COLOR_SYMBOL, COLOR_BLACK, underlying)
|
||||
cellBidPrice = OmCell(str(underlying.bidPrice1), COLOR_BID, COLOR_BLACK, underlying)
|
||||
cellBidVolume = OmCell(str(underlying.bidVolume1), COLOR_BID, COLOR_BLACK, underlying)
|
||||
cellAskPrice = OmCell(str(underlying.askPrice1), COLOR_ASK, COLOR_BLACK, underlying)
|
||||
cellAskVolume = OmCell(str(underlying.askVolume1), COLOR_ASK, COLOR_BLACK, underlying)
|
||||
cellPos = OmCell(str(underlying.netPos), COLOR_POS, COLOR_BLACK, underlying)
|
||||
|
||||
self.setItem(row, 0, cellSymbol)
|
||||
self.setItem(row, 1, cellBidPrice)
|
||||
self.setItem(row, 2, cellBidVolume)
|
||||
self.setItem(row, 4, cellAskPrice)
|
||||
self.setItem(row, 5, cellAskVolume)
|
||||
self.setItem(row, 7, cellPos)
|
||||
|
||||
self.bidPriceDict[symbol] = cellBidPrice
|
||||
self.bidVolumeDict[symbol] = cellBidVolume
|
||||
self.askPriceDict[symbol] = cellAskPrice
|
||||
self.askVolumeDict[symbol] = cellAskVolume
|
||||
self.posDict[symbol] = cellPos
|
||||
|
||||
row += 1
|
||||
|
||||
row += 1
|
||||
|
||||
# 初始化期权单元格
|
||||
for chain in portfolio.chainDict.values():
|
||||
|
||||
# call
|
||||
callRow = row
|
||||
|
||||
for option in chain.callDict.values():
|
||||
cellSymbol = OmCell(option.symbol, COLOR_SYMBOL, COLOR_BLACK, option)
|
||||
cellBidPrice = OmCell(str(option.bidPrice1), COLOR_BID, COLOR_BLACK, option)
|
||||
cellBidVolume = OmCell(str(option.bidVolume1), COLOR_BID, COLOR_BLACK, option)
|
||||
cellBidImpv = OmCell('%.1f' %(option.bidImpv*100), COLOR_BID, COLOR_BLACK, option)
|
||||
cellAskPrice = OmCell(str(option.askPrice1), COLOR_ASK, COLOR_BLACK, option)
|
||||
cellAskVolume = OmCell(str(option.askVolume1), COLOR_ASK, COLOR_BLACK, option)
|
||||
cellAskImpv = OmCell('%.1f' %(option.askImpv*100), COLOR_ASK, COLOR_BLACK, option)
|
||||
cellPos = OmCell(str(option.netPos), COLOR_POS, COLOR_BLACK, option)
|
||||
cellStrike = OmCell(str(option.k), COLOR_STRIKE)
|
||||
|
||||
self.setItem(callRow, 0, cellSymbol)
|
||||
self.setItem(callRow, 1, cellBidPrice)
|
||||
self.setItem(callRow, 2, cellBidVolume)
|
||||
self.setItem(callRow, 3, cellBidImpv)
|
||||
self.setItem(callRow, 4, cellAskPrice)
|
||||
self.setItem(callRow, 5, cellAskVolume)
|
||||
self.setItem(callRow, 6, cellAskImpv)
|
||||
self.setItem(callRow, 7, cellPos)
|
||||
self.setItem(callRow, 8, cellStrike)
|
||||
|
||||
self.bidPriceDict[option.symbol] = cellBidPrice
|
||||
self.bidVolumeDict[option.symbol] = cellBidVolume
|
||||
self.bidImpvDict[option.symbol] = cellBidImpv
|
||||
self.askPriceDict[option.symbol] = cellAskPrice
|
||||
self.askVolumeDict[option.symbol] = cellAskVolume
|
||||
self.askImpvDict[option.symbol] = cellAskImpv
|
||||
self.posDict[option.symbol] = cellPos
|
||||
|
||||
callRow += 1
|
||||
|
||||
# put
|
||||
putRow = row
|
||||
|
||||
for option in chain.putDict.values():
|
||||
cellSymbol = OmCell(option.symbol, COLOR_SYMBOL, COLOR_BLACK, option)
|
||||
cellBidPrice = OmCell(str(option.bidPrice1), COLOR_BID, COLOR_BLACK, option)
|
||||
cellBidVolume = OmCell(str(option.bidVolume1), COLOR_BID, COLOR_BLACK, option)
|
||||
cellBidImpv = OmCell('%.1f' %(option.bidImpv*100), COLOR_BID, COLOR_BLACK, option)
|
||||
cellAskPrice = OmCell(str(option.askPrice1), COLOR_ASK, COLOR_BLACK, option)
|
||||
cellAskVolume = OmCell(str(option.askVolume1), COLOR_ASK, COLOR_BLACK, option)
|
||||
cellAskImpv = OmCell('%.1f' %(option.askImpv*100), COLOR_ASK, COLOR_BLACK, option)
|
||||
cellPos = OmCell(str(option.netPos), COLOR_POS, COLOR_BLACK, option)
|
||||
|
||||
self.setItem(putRow, 9, cellPos)
|
||||
self.setItem(putRow, 10, cellBidPrice)
|
||||
self.setItem(putRow, 11, cellBidVolume)
|
||||
self.setItem(putRow, 12, cellBidImpv)
|
||||
self.setItem(putRow, 13, cellAskPrice)
|
||||
self.setItem(putRow, 14, cellAskVolume)
|
||||
self.setItem(putRow, 15, cellAskImpv)
|
||||
self.setItem(putRow, 16, cellSymbol)
|
||||
|
||||
self.bidPriceDict[option.symbol] = cellBidPrice
|
||||
self.bidVolumeDict[option.symbol] = cellBidVolume
|
||||
self.bidImpvDict[option.symbol] = cellBidImpv
|
||||
self.askPriceDict[option.symbol] = cellAskPrice
|
||||
self.askVolumeDict[option.symbol] = cellAskVolume
|
||||
self.askImpvDict[option.symbol] = cellAskImpv
|
||||
self.posDict[option.symbol] = cellPos
|
||||
|
||||
putRow += 1
|
||||
|
||||
row = putRow + 1
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def registerEvent(self):
|
||||
"""注册事件监听"""
|
||||
self.signalTick.connect(self.processTickEvent)
|
||||
self.signalTrade.connect(self.processTradeEvent)
|
||||
|
||||
portfolio = self.omEngine.portfolio
|
||||
|
||||
for underlying in portfolio.underlyingDict.values():
|
||||
self.eventEngine.register(EVENT_TICK + underlying.vtSymbol, self.signalTick.emit)
|
||||
self.eventEngine.register(EVENT_TRADE + underlying.vtSymbol, self.signalTick.emit)
|
||||
|
||||
for chain in portfolio.chainDict.values():
|
||||
for option in chain.optionDict.values():
|
||||
self.eventEngine.register(EVENT_TICK + option.vtSymbol, self.signalTick.emit)
|
||||
self.eventEngine.register(EVENT_TRADE + option.vtSymbol, self.signalTrade.emit)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def processTickEvent(self, event):
|
||||
"""行情更新"""
|
||||
tick = event.dict_['data']
|
||||
symbol = tick.symbol
|
||||
|
||||
if symbol in self.bidImpvDict:
|
||||
option = self.instrumentDict[symbol]
|
||||
self.bidImpvDict[symbol].setText('%.1f' %(option.bidImpv*100))
|
||||
self.askImpvDict[symbol].setText('%.1f' %(option.askImpv*100))
|
||||
|
||||
self.bidPriceDict[symbol].setText(str(tick.bidPrice1))
|
||||
self.bidVolumeDict[symbol].setText(str(tick.bidVolume1))
|
||||
self.askPriceDict[symbol].setText(str(tick.askPrice1))
|
||||
self.askVolumeDict[symbol].setText(str(tick.askVolume1))
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def processTradeEvent(self, event):
|
||||
"""成交更新"""
|
||||
trade = event.dict_['data']
|
||||
|
||||
symbol = trade.symbol
|
||||
instrument = self.instrumentDict[symbol]
|
||||
self.posDict[symbol].setText(str(instrument.netPos))
|
||||
|
||||
|
||||
########################################################################
|
||||
class TradingWidget(QtWidgets.QWidget):
|
||||
"""交易组件"""
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self, omEngine, parent=None):
|
||||
"""Constructor"""
|
||||
super(TradingWidget, self).__init__(parent)
|
||||
|
||||
self.omEngine = omEngine
|
||||
self.mainEngine = omEngine.mainEngine
|
||||
self.portfolio = omEngine.portfolio
|
||||
|
||||
self.initUi()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def initUi(self):
|
||||
"""初始化界面"""
|
||||
self.setFixedWidth(200)
|
||||
|
||||
labelTradingWidget = QtWidgets.QLabel(u'期权交易')
|
||||
labelSymbol = QtWidgets.QLabel(u'代码')
|
||||
labelDirection = QtWidgets.QLabel(u'方向')
|
||||
labelPrice = QtWidgets.QLabel(u'价格')
|
||||
labelVolume = QtWidgets.QLabel(u'数量')
|
||||
|
||||
self.lineSymbol = QtWidgets.QLineEdit()
|
||||
self.comboDirection = QtWidgets.QComboBox()
|
||||
self.comboDirection.addItems([DIRECTION_LONG, DIRECTION_SHORT])
|
||||
self.linePrice = QtWidgets.QLineEdit()
|
||||
self.lineVolume = QtWidgets.QLineEdit()
|
||||
self.buttonSendOrder = QtWidgets.QPushButton(u'发单')
|
||||
self.buttonSendOrder.clicked.connect(self.sendOrder)
|
||||
|
||||
grid = QtWidgets.QGridLayout()
|
||||
grid.addWidget(labelTradingWidget, 0, 0, 1, 2)
|
||||
grid.addWidget(labelSymbol, 1, 0)
|
||||
grid.addWidget(labelDirection, 2, 0)
|
||||
grid.addWidget(labelPrice, 3, 0)
|
||||
grid.addWidget(labelVolume, 4, 0)
|
||||
grid.addWidget(self.lineSymbol, 1, 1)
|
||||
grid.addWidget(self.comboDirection, 2, 1)
|
||||
grid.addWidget(self.linePrice, 3, 1)
|
||||
grid.addWidget(self.lineVolume, 4, 1)
|
||||
grid.addWidget(self.buttonSendOrder, 5, 0, 1, 2)
|
||||
self.setLayout(grid)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def sendOrder(self):
|
||||
"""发送委托"""
|
||||
try:
|
||||
symbol = str(self.lineSymbol.text())
|
||||
direction = str(self.comboDirection.currentText())
|
||||
price = float(self.linePrice.text())
|
||||
volume = int(self.lineVolume.text())
|
||||
except:
|
||||
return
|
||||
|
||||
instrument = self.portfolio.instrumentDict.get(symbol, None)
|
||||
if not instrument:
|
||||
return
|
||||
|
||||
# 做多
|
||||
if direction == DIRECTION_LONG:
|
||||
# 如果空头仓位大于等于买入量,则只需平
|
||||
if instrument.shortPos >= volume:
|
||||
self.fastTrade(symbol, DIRECTION_LONG, OFFSET_CLOSE, price, volume)
|
||||
# 否则先平后开
|
||||
else:
|
||||
openVolume = volume - instrument.shortPos
|
||||
if instrument.shortPos:
|
||||
self.fastTrade(symbol, DIRECTION_LONG, OFFSET_CLOSE, price, instrument.shortPos)
|
||||
self.fastTrade(symbol, DIRECTION_LONG, OFFSET_OPEN, price, openVolume)
|
||||
# 做空
|
||||
else:
|
||||
if instrument.longPos >= volume:
|
||||
self.fastTrade(symbol, DIRECTION_SHORT, OFFSET_CLOSE, price, volume)
|
||||
else:
|
||||
openVolume = volume - instrument.longPos
|
||||
if instrument.longPos:
|
||||
self.fastTrade(symbol, DIRECTION_SHORT, OFFSET_CLOSE, price, instrument.longPos)
|
||||
self.fastTrade(symbol ,DIRECTION_SHORT, OFFSET_OPEN, price, openVolume)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def fastTrade(self, symbol, direction, offset, price, volume):
|
||||
"""封装下单函数"""
|
||||
contract = self.mainEngine.getContract(symbol)
|
||||
if not contract:
|
||||
return
|
||||
|
||||
req = VtOrderReq()
|
||||
req.symbol = symbol
|
||||
req.exchange = contract.exchange
|
||||
req.direction = direction
|
||||
req.offset = offset
|
||||
req.price = price
|
||||
req.volume = volume
|
||||
req.priceType = PRICETYPE_LIMITPRICE
|
||||
self.mainEngine.sendOrder(req, contract.gatewayName)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def updateWidget(self, item):
|
||||
"""双击监控组件单元格后自动更新组件"""
|
||||
instrument = item.data
|
||||
if not instrument:
|
||||
return
|
||||
|
||||
self.lineSymbol.setText(instrument.symbol)
|
||||
|
||||
# short
|
||||
if item.background is COLOR_BID:
|
||||
self.comboDirection.setCurrentIndex(1)
|
||||
self.linePrice.setText(str(instrument.bidPrice1))
|
||||
self.lineVolume.setText(str(instrument.bidVolume1))
|
||||
# long
|
||||
elif item.background is COLOR_ASK:
|
||||
self.comboDirection.setCurrentIndex(0)
|
||||
self.linePrice.setText(str(instrument.askPrice1))
|
||||
self.lineVolume.setText(str(instrument.askVolume1))
|
||||
|
||||
|
||||
########################################################################
|
||||
class ManualTrader(QtWidgets.QWidget):
|
||||
"""手动交易组件"""
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self, omEngine, parent=None):
|
||||
"""Constructor"""
|
||||
super(ManualTrader, self).__init__(parent)
|
||||
|
||||
self.omEngine = omEngine
|
||||
self.mainEngine = omEngine.mainEngine
|
||||
self.eventEngine = omEngine.eventEngine
|
||||
|
||||
self.initUi()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def initUi(self):
|
||||
"""初始化界面"""
|
||||
self.setWindowTitle(u'手动交易')
|
||||
|
||||
posMonitor = PositionMonitor(self.mainEngine, self.eventEngine)
|
||||
for i in range(posMonitor.columnCount()):
|
||||
posMonitor.horizontalHeader().setResizeMode(QtWidgets.QHeaderView.Stretch)
|
||||
posMonitor.setSorting(False)
|
||||
|
||||
orderMonitor = WorkingOrderMonitor(self.mainEngine, self.eventEngine)
|
||||
for i in range(orderMonitor.columnCount()):
|
||||
orderMonitor.horizontalHeader().setResizeMode(QtWidgets.QHeaderView.Stretch)
|
||||
orderMonitor.setSorting(False)
|
||||
|
||||
tradingWidget = TradingWidget(self.omEngine)
|
||||
|
||||
chainMonitor = ChainMonitor(self.omEngine, self.eventEngine)
|
||||
chainMonitor.itemDoubleClicked.connect(tradingWidget.updateWidget)
|
||||
|
||||
vbox1 = QtWidgets.QVBoxLayout()
|
||||
vbox1.addWidget(orderMonitor)
|
||||
vbox1.addWidget(posMonitor)
|
||||
|
||||
vbox2 = QtWidgets.QVBoxLayout()
|
||||
vbox2.addWidget(tradingWidget)
|
||||
vbox2.addStretch()
|
||||
|
||||
hbox = QtWidgets.QHBoxLayout()
|
||||
hbox.addLayout(vbox1)
|
||||
hbox.addLayout(vbox2)
|
||||
|
||||
vbox3 = QtWidgets.QVBoxLayout()
|
||||
vbox3.addWidget(chainMonitor)
|
||||
vbox3.addLayout(hbox)
|
||||
|
||||
self.setLayout(vbox3)
|
||||
|
||||
|
@ -9,6 +9,7 @@ from vnpy.event import Event
|
||||
from vnpy.trader.uiQt import QtWidgets, QtCore
|
||||
|
||||
from .omBase import EVENT_OM_LOG
|
||||
from .uiOmManualTrader import ManualTrader
|
||||
|
||||
|
||||
########################################################################
|
||||
@ -51,12 +52,16 @@ class OmManager(QtWidgets.QWidget):
|
||||
self.buttonInit = QtWidgets.QPushButton(u'初始化')
|
||||
self.buttonInit.clicked.connect(self.initOmEngine)
|
||||
|
||||
self.buttonManualTrader = QtWidgets.QPushButton(u'手动交易')
|
||||
self.buttonManualTrader.clicked.connect(self.openManualTrader)
|
||||
|
||||
self.logMonitor = QtWidgets.QTextEdit()
|
||||
self.logMonitor.setReadOnly(True)
|
||||
|
||||
hbox = QtWidgets.QHBoxLayout()
|
||||
hbox.addWidget(self.comboSettingFile)
|
||||
hbox.addWidget(self.buttonInit)
|
||||
hbox.addWidget(self.buttonManualTrader)
|
||||
hbox.addStretch()
|
||||
|
||||
hbox2 = QtWidgets.QHBoxLayout()
|
||||
@ -99,7 +104,7 @@ class OmManager(QtWidgets.QWidget):
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def openManualTrader(self):
|
||||
"""打开手动交易"""
|
||||
"""打开手动交易组件"""
|
||||
try:
|
||||
self.widgetDict['manualTrader'].showMaximized()
|
||||
except KeyError:
|
||||
@ -120,4 +125,3 @@ class OmManager(QtWidgets.QWidget):
|
||||
self.signal.connect(self.processLogEvent)
|
||||
|
||||
self.eventEngine.register(EVENT_OM_LOG, self.signal.emit)
|
||||
|
Loading…
Reference in New Issue
Block a user