[Add]添加希腊值监控组件
This commit is contained in:
parent
d3d1afd7c7
commit
796adc7673
@ -1 +1 @@
|
||||
HqLpRXdyn/k8CK6bQvjTlg==
|
||||
4kpJoMUXCPNmN66luTh0Lg==
|
@ -79,7 +79,7 @@ def calculateTheta(f, k, r, t, v, cp):
|
||||
#----------------------------------------------------------------------
|
||||
def calculateVega(f, k, r, t, v, cp):
|
||||
"""计算Vega值"""
|
||||
vega = calculateVega(f, k, r, t, v, cp) / 100
|
||||
vega = calculateOriginalVega(f, k, r, t, v, cp) / 100
|
||||
return vega
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
@ -145,7 +145,7 @@ class OmUnderlying(OmInstrument):
|
||||
#----------------------------------------------------------------------
|
||||
def calculatePosGreeks(self):
|
||||
"""计算持仓希腊值"""
|
||||
self.posDelta = self.theoDelta * self.netPos
|
||||
self.posDelta = self.theoDelta * self.netPos * self.size
|
||||
|
||||
|
||||
########################################################################
|
||||
@ -210,6 +210,8 @@ class OmOption(OmInstrument):
|
||||
self.bidImpv = self.calculateImpv(self.bidPrice1, underlyingPrice, self.k,
|
||||
self.r, self.t, self.cp)
|
||||
self.midImpv = (self.askImpv + self.bidImpv) / 2
|
||||
|
||||
self.pricingImpv = self.midImpv
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def calculateTheoGreeks(self):
|
||||
@ -228,11 +230,11 @@ class OmOption(OmInstrument):
|
||||
#----------------------------------------------------------------------
|
||||
def calculatePosGreeks(self):
|
||||
"""计算持仓希腊值"""
|
||||
self.posValue = self.theoPrice * self.netPos
|
||||
self.posDelta = self.theoDelta * self.netPos
|
||||
self.posGamma = self.theoGamma * self.netPos
|
||||
self.posTheta = self.theoTheta * self.netPos
|
||||
self.posVega = self.theoVega * self.netPos
|
||||
self.posValue = self.theoPrice * self.netPos * self.size
|
||||
self.posDelta = self.theoDelta * self.netPos * self.size
|
||||
self.posGamma = self.theoGamma * self.netPos * self.size
|
||||
self.posTheta = self.theoTheta * self.netPos * self.size
|
||||
self.posVega = self.theoVega * self.netPos * self.size
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def newTick(self, tick):
|
||||
|
294
vnpy/trader/app/optionMaster/uiOmGreeksMonitor.py
Normal file
294
vnpy/trader/app/optionMaster/uiOmGreeksMonitor.py
Normal file
@ -0,0 +1,294 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
from vnpy.event import Event
|
||||
from vnpy.trader.vtEvent import EVENT_TIMER
|
||||
|
||||
from .uiOmBase import *
|
||||
|
||||
|
||||
########################################################################
|
||||
class GreeksMonitor(QtWidgets.QTableWidget):
|
||||
"""希腊值监控"""
|
||||
headers = [
|
||||
u'代码',
|
||||
u'多仓',
|
||||
u'空仓',
|
||||
u'净仓',
|
||||
u'Delta',
|
||||
u'Gamma',
|
||||
u'Theta',
|
||||
u'Vega',
|
||||
u'持仓Delta',
|
||||
u'持仓Gamma',
|
||||
u'持仓Theta',
|
||||
u'持仓Vega'
|
||||
]
|
||||
|
||||
signal = QtCore.pyqtSignal(type(Event()))
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self, omEngine, parent=None):
|
||||
"""Constructor"""
|
||||
super(GreeksMonitor, self).__init__()
|
||||
|
||||
self.portfolio = omEngine.portfolio
|
||||
self.eventEngine = omEngine.eventEngine
|
||||
|
||||
self.cellDict = {} # key:symbol, value:cell dict
|
||||
self.updateTrigger = 2
|
||||
self.updateCount = 0
|
||||
|
||||
self.initUi()
|
||||
self.initCells()
|
||||
self.registerEvent()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def initUi(self):
|
||||
"""初始化界面"""
|
||||
portfolio = self.portfolio
|
||||
|
||||
self.setWindowTitle(u'希腊值监控')
|
||||
|
||||
# 计算所需行数
|
||||
totalRow = 1
|
||||
totalRow += len(portfolio.underlyingDict) + 1
|
||||
totalRow += len(portfolio.chainDict) + 1
|
||||
|
||||
for chain in portfolio.chainDict.values():
|
||||
totalRow += len(chain.optionDict) + 1
|
||||
|
||||
# 初始化表格
|
||||
self.setColumnCount(len(self.headers))
|
||||
self.setHorizontalHeaderLabels(self.headers)
|
||||
self.setRowCount(totalRow)
|
||||
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)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def initCells(self):
|
||||
"""初始化单元格"""
|
||||
portfolio = self.portfolio
|
||||
row = 0
|
||||
|
||||
# 组合
|
||||
cellSymbol = OmCell(portfolio.name, COLOR_SYMBOL, COLOR_BLACK)
|
||||
cellLongPos = OmCell(0, COLOR_POS, COLOR_BLACK)
|
||||
cellShortPos = OmCell(0, COLOR_POS, COLOR_BLACK)
|
||||
cellNetPos = OmCell(0, COLOR_POS, COLOR_BLACK)
|
||||
cellPosDelta = OmCell(0, COLOR_STRIKE)
|
||||
cellPosGamma = OmCell(0, COLOR_STRIKE)
|
||||
cellPosTheta = OmCell(0, COLOR_STRIKE)
|
||||
cellPosVega = OmCell(0, COLOR_STRIKE)
|
||||
|
||||
self.setItem(row, 0, cellSymbol)
|
||||
self.setItem(row, 1, cellLongPos)
|
||||
self.setItem(row, 2, cellShortPos)
|
||||
self.setItem(row, 3, cellNetPos)
|
||||
self.setItem(row, 8, cellPosDelta)
|
||||
self.setItem(row, 9, cellPosGamma)
|
||||
self.setItem(row, 10, cellPosTheta)
|
||||
self.setItem(row, 11, cellPosVega)
|
||||
|
||||
d = {}
|
||||
d['longPos'] = cellLongPos
|
||||
d['shortPos'] = cellShortPos
|
||||
d['netPos'] = cellNetPos
|
||||
d['posDelta'] = cellPosDelta
|
||||
d['posGamma'] = cellPosGamma
|
||||
d['posTheta'] = cellPosTheta
|
||||
d['posVega'] = cellPosVega
|
||||
self.cellDict[portfolio.name] = d
|
||||
|
||||
row += 1
|
||||
|
||||
# 标的
|
||||
row += 1 # 空行
|
||||
|
||||
for underlying in portfolio.underlyingDict.values():
|
||||
cellSymbol = OmCell(underlying.symbol, COLOR_SYMBOL, COLOR_BLACK)
|
||||
cellLongPos = OmCell(0, COLOR_POS, COLOR_BLACK)
|
||||
cellShortPos = OmCell(0, COLOR_POS, COLOR_BLACK)
|
||||
cellNetPos = OmCell(0, COLOR_POS, COLOR_BLACK)
|
||||
cellTheoDelta = OmCell('%.3f' %underlying.theoDelta)
|
||||
cellPosDelta = OmCell(0, COLOR_STRIKE)
|
||||
|
||||
self.setItem(row, 0, cellSymbol)
|
||||
self.setItem(row, 1, cellLongPos)
|
||||
self.setItem(row, 2, cellShortPos)
|
||||
self.setItem(row, 3, cellNetPos)
|
||||
self.setItem(row, 4, cellTheoDelta)
|
||||
self.setItem(row, 8, cellPosDelta)
|
||||
|
||||
d = {}
|
||||
d['longPos'] = cellLongPos
|
||||
d['shortPos'] = cellShortPos
|
||||
d['netPos'] = cellNetPos
|
||||
d['theoDelta'] = cellTheoDelta
|
||||
d['posDelta'] = cellPosDelta
|
||||
self.cellDict[underlying.symbol] = d
|
||||
|
||||
row += 1
|
||||
|
||||
# 期权链
|
||||
row += 1
|
||||
|
||||
for chain in portfolio.chainDict.values():
|
||||
cellSymbol = OmCell(chain.symbol, COLOR_SYMBOL, COLOR_BLACK)
|
||||
cellLongPos = OmCell(0, COLOR_POS, COLOR_BLACK)
|
||||
cellShortPos = OmCell(0, COLOR_POS, COLOR_BLACK)
|
||||
cellNetPos = OmCell(0, COLOR_POS, COLOR_BLACK)
|
||||
cellTheoDelta = OmCell(0)
|
||||
cellTheoGamma = OmCell(0)
|
||||
cellTheoTheta = OmCell(0)
|
||||
cellTheoVega = OmCell(0)
|
||||
cellPosDelta = OmCell(0, COLOR_STRIKE)
|
||||
cellPosGamma = OmCell(0, COLOR_STRIKE)
|
||||
cellPosTheta = OmCell(0, COLOR_STRIKE)
|
||||
cellPosVega = OmCell(0, COLOR_STRIKE)
|
||||
|
||||
self.setItem(row, 0, cellSymbol)
|
||||
self.setItem(row, 1, cellLongPos)
|
||||
self.setItem(row, 2, cellShortPos)
|
||||
self.setItem(row, 3, cellNetPos)
|
||||
self.setItem(row, 4, cellTheoDelta)
|
||||
self.setItem(row, 5, cellTheoGamma)
|
||||
self.setItem(row, 6, cellTheoTheta)
|
||||
self.setItem(row, 7, cellTheoVega)
|
||||
self.setItem(row, 8, cellPosDelta)
|
||||
self.setItem(row, 9, cellPosGamma)
|
||||
self.setItem(row, 10, cellPosTheta)
|
||||
self.setItem(row, 11, cellPosVega)
|
||||
|
||||
d = {}
|
||||
d['longPos'] = cellLongPos
|
||||
d['shortPos'] = cellShortPos
|
||||
d['netPos'] = cellNetPos
|
||||
d['theoDelta'] = cellTheoDelta
|
||||
d['theoGamma'] = cellTheoGamma
|
||||
d['theoTheta'] = cellTheoTheta
|
||||
d['theoVega'] = cellTheoVega
|
||||
d['posDelta'] = cellPosDelta
|
||||
d['posGamma'] = cellPosGamma
|
||||
d['posTheta'] = cellPosTheta
|
||||
d['posVega'] = cellPosVega
|
||||
self.cellDict[chain.symbol + '_chain'] = d
|
||||
|
||||
row += 1
|
||||
|
||||
# 期权
|
||||
for chain in portfolio.chainDict.values():
|
||||
row += 1
|
||||
|
||||
for option in chain.optionDict.values():
|
||||
cellSymbol = OmCell(option.symbol, COLOR_SYMBOL, COLOR_BLACK)
|
||||
cellLongPos = OmCell(0, COLOR_POS, COLOR_BLACK)
|
||||
cellShortPos = OmCell(0, COLOR_POS, COLOR_BLACK)
|
||||
cellNetPos = OmCell(0, COLOR_POS, COLOR_BLACK)
|
||||
cellTheoDelta = OmCell(0)
|
||||
cellTheoGamma = OmCell(0)
|
||||
cellTheoTheta = OmCell(0)
|
||||
cellTheoVega = OmCell(0)
|
||||
cellPosDelta = OmCell(0, COLOR_STRIKE)
|
||||
cellPosGamma = OmCell(0, COLOR_STRIKE)
|
||||
cellPosTheta = OmCell(0, COLOR_STRIKE)
|
||||
cellPosVega = OmCell(0, COLOR_STRIKE)
|
||||
|
||||
self.setItem(row, 0, cellSymbol)
|
||||
self.setItem(row, 1, cellLongPos)
|
||||
self.setItem(row, 2, cellShortPos)
|
||||
self.setItem(row, 3, cellNetPos)
|
||||
self.setItem(row, 4, cellTheoDelta)
|
||||
self.setItem(row, 5, cellTheoGamma)
|
||||
self.setItem(row, 6, cellTheoTheta)
|
||||
self.setItem(row, 7, cellTheoVega)
|
||||
self.setItem(row, 8, cellPosDelta)
|
||||
self.setItem(row, 9, cellPosGamma)
|
||||
self.setItem(row, 10, cellPosTheta)
|
||||
self.setItem(row, 11, cellPosVega)
|
||||
|
||||
d = {}
|
||||
d['longPos'] = cellLongPos
|
||||
d['shortPos'] = cellShortPos
|
||||
d['netPos'] = cellNetPos
|
||||
d['theoDelta'] = cellTheoDelta
|
||||
d['theoGamma'] = cellTheoGamma
|
||||
d['theoTheta'] = cellTheoTheta
|
||||
d['theoVega'] = cellTheoVega
|
||||
d['posDelta'] = cellPosDelta
|
||||
d['posGamma'] = cellPosGamma
|
||||
d['posTheta'] = cellPosTheta
|
||||
d['posVega'] = cellPosVega
|
||||
self.cellDict[option.symbol] = d
|
||||
|
||||
row += 1
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def registerEvent(self):
|
||||
"""注册事件监听"""
|
||||
self.signal.connect(self.updateTable)
|
||||
self.eventEngine.register(EVENT_TIMER, self.signal.emit)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def processTimerEvent(self, event):
|
||||
"""处理定时事件"""
|
||||
self.updateCount += 1
|
||||
|
||||
if self.updateCount >= self.updateTrigger:
|
||||
self.updateCount = 0
|
||||
self.updateTable()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def updateTable(self):
|
||||
"""更新表格"""
|
||||
# 更新组合
|
||||
portfolio = self.portfolio
|
||||
|
||||
d = self.cellDict[portfolio.name]
|
||||
d['longPos'].setText(str(portfolio.longPos))
|
||||
d['shortPos'].setText(str(portfolio.shortPos))
|
||||
d['netPos'].setText(str(portfolio.netPos))
|
||||
d['posDelta'].setText('%.1f' %portfolio.posDelta)
|
||||
d['posGamma'].setText('%.1f' %portfolio.posGamma)
|
||||
d['posTheta'].setText('%.1f' %portfolio.posTheta)
|
||||
d['posVega'].setText('%.1f' %portfolio.posVega)
|
||||
|
||||
# 更新标的
|
||||
for underlying in portfolio.underlyingDict.values():
|
||||
d = self.cellDict[underlying.symbol]
|
||||
d['longPos'].setText(str(underlying.longPos))
|
||||
d['shortPos'].setText(str(underlying.shortPos))
|
||||
d['netPos'].setText(str(underlying.netPos))
|
||||
d['posDelta'].setText('%.1f' %underlying.posDelta)
|
||||
|
||||
# 更新期权链
|
||||
for chain in portfolio.chainDict.values():
|
||||
d = self.cellDict[chain.symbol + '_chain']
|
||||
d['longPos'].setText(str(chain.longPos))
|
||||
d['shortPos'].setText(str(chain.shortPos))
|
||||
d['netPos'].setText(str(chain.netPos))
|
||||
d['posDelta'].setText('%.1f' %chain.posDelta)
|
||||
d['posGamma'].setText('%.1f' %chain.posGamma)
|
||||
d['posTheta'].setText('%.1f' %chain.posTheta)
|
||||
d['posVega'].setText('%.1f' %chain.posVega)
|
||||
|
||||
# 更新期权
|
||||
for chain in portfolio.chainDict.values():
|
||||
for option in chain.optionDict.values():
|
||||
d = self.cellDict[option.symbol]
|
||||
d['longPos'].setText(str(option.longPos))
|
||||
d['shortPos'].setText(str(option.shortPos))
|
||||
d['netPos'].setText(str(option.netPos))
|
||||
d['theoDelta'].setText('%.3f' %option.theoDelta)
|
||||
d['theoGamma'].setText('%.3f' %option.theoGamma)
|
||||
d['theoTheta'].setText('%.3f' %option.theoTheta)
|
||||
d['theoVega'].setText('%.3f' %option.theoVega)
|
||||
d['posDelta'].setText('%.1f' %option.posDelta)
|
||||
d['posGamma'].setText('%.1f' %option.posGamma)
|
||||
d['posTheta'].setText('%.1f' %option.posTheta)
|
||||
d['posVega'].setText('%.1f' %option.posVega)
|
||||
|
||||
|
@ -6,10 +6,11 @@ import os
|
||||
from datetime import datetime
|
||||
|
||||
from vnpy.event import Event
|
||||
from vnpy.trader.uiQt import QtWidgets, QtCore
|
||||
|
||||
from .omBase import EVENT_OM_LOG
|
||||
from .uiOmBase import QtWidgets, QtCore
|
||||
from .uiOmManualTrader import ManualTrader
|
||||
from .uiOmGreeksMonitor import GreeksMonitor
|
||||
|
||||
|
||||
########################################################################
|
||||
@ -55,6 +56,9 @@ class OmManager(QtWidgets.QWidget):
|
||||
self.buttonManualTrader = QtWidgets.QPushButton(u'手动交易')
|
||||
self.buttonManualTrader.clicked.connect(self.openManualTrader)
|
||||
|
||||
self.buttonGreeksMonitor = QtWidgets.QPushButton(u'希腊值监控')
|
||||
self.buttonGreeksMonitor.clicked.connect(self.openGreeksMonitor)
|
||||
|
||||
self.logMonitor = QtWidgets.QTextEdit()
|
||||
self.logMonitor.setReadOnly(True)
|
||||
|
||||
@ -62,6 +66,7 @@ class OmManager(QtWidgets.QWidget):
|
||||
hbox.addWidget(self.comboSettingFile)
|
||||
hbox.addWidget(self.buttonInit)
|
||||
hbox.addWidget(self.buttonManualTrader)
|
||||
hbox.addWidget(self.buttonGreeksMonitor)
|
||||
hbox.addStretch()
|
||||
|
||||
hbox2 = QtWidgets.QHBoxLayout()
|
||||
@ -110,6 +115,15 @@ class OmManager(QtWidgets.QWidget):
|
||||
except KeyError:
|
||||
self.widgetDict['manualTrader'] = ManualTrader(self.omEngine)
|
||||
self.widgetDict['manualTrader'].showMaximized()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def openGreeksMonitor(self):
|
||||
"""打开希腊值监控组件"""
|
||||
try:
|
||||
self.widgetDict['greeksMonitor'].showMaximized()
|
||||
except KeyError:
|
||||
self.widgetDict['greeksMonitor'] = GreeksMonitor(self.omEngine)
|
||||
self.widgetDict['greeksMonitor'].showMaximized()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def close(self):
|
||||
|
Loading…
Reference in New Issue
Block a user