[Add]新增波动率管理组件
This commit is contained in:
parent
af31162849
commit
dfb23ab2f4
@ -1 +1 @@
|
|||||||
4kpJoMUXCPNmN66luTh0Lg==
|
1akdYJY+uYtFOYGtWEJkKg==
|
@ -211,8 +211,6 @@ class OmOption(OmInstrument):
|
|||||||
self.r, self.t, self.cp)
|
self.r, self.t, self.cp)
|
||||||
self.midImpv = (self.askImpv + self.bidImpv) / 2
|
self.midImpv = (self.askImpv + self.bidImpv) / 2
|
||||||
|
|
||||||
self.pricingImpv = self.midImpv
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def calculateTheoGreeks(self):
|
def calculateTheoGreeks(self):
|
||||||
"""计算理论希腊值"""
|
"""计算理论希腊值"""
|
||||||
|
@ -124,3 +124,234 @@ class VolatilityChart(pg.GraphicsWindow):
|
|||||||
"""关闭"""
|
"""关闭"""
|
||||||
self.eventEngine.unregister(EVENT_TIMER, self.signal.emit)
|
self.eventEngine.unregister(EVENT_TIMER, self.signal.emit)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class ChainVolatilityMonitor(QtWidgets.QTableWidget):
|
||||||
|
"""期权链波动率监控"""
|
||||||
|
headers = [
|
||||||
|
u'代码',
|
||||||
|
u'买隐波',
|
||||||
|
u'定价',
|
||||||
|
u'卖隐波',
|
||||||
|
u'行权价',
|
||||||
|
u'买隐波',
|
||||||
|
u'定价',
|
||||||
|
u'卖隐波',
|
||||||
|
u'代码'
|
||||||
|
]
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self, chain, parent=None):
|
||||||
|
"""Constructor"""
|
||||||
|
super(ChainVolatilityMonitor, self).__init__(parent)
|
||||||
|
|
||||||
|
self.chain = chain
|
||||||
|
self.cellDict = {} # key: symbol, value: dict of cells
|
||||||
|
|
||||||
|
self.initUi()
|
||||||
|
self.itemChanged.connect(self.pricingImpvChanged)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def initUi(self):
|
||||||
|
"""初始化界面"""
|
||||||
|
chain = self.chain
|
||||||
|
|
||||||
|
# 初始化表格
|
||||||
|
self.setColumnCount(len(self.headers))
|
||||||
|
self.setHorizontalHeaderLabels(self.headers)
|
||||||
|
self.setRowCount(len(chain.callDict))
|
||||||
|
self.verticalHeader().setVisible(False)
|
||||||
|
|
||||||
|
for i in range(self.columnCount()):
|
||||||
|
self.horizontalHeader().setResizeMode(i, QtWidgets.QHeaderView.Stretch)
|
||||||
|
|
||||||
|
# 初始化单元格
|
||||||
|
for row, option in enumerate(chain.callDict.values()):
|
||||||
|
cellSymbol = OmCell(option.symbol, COLOR_SYMBOL, COLOR_BLACK)
|
||||||
|
cellBid = OmCell('%.1f' %(option.bidImpv*100), COLOR_BID, COLOR_BLACK)
|
||||||
|
cellPricing = OmCell('%.1f' %(option.pricingImpv*100), COLOR_POS, COLOR_BLACK)
|
||||||
|
cellAsk = OmCell('%.1f' %(option.askImpv*100), COLOR_ASK, COLOR_BLACK)
|
||||||
|
cellStrike = OmCell(str(option.k), COLOR_STRIKE)
|
||||||
|
|
||||||
|
cellPricing.data = option.symbol
|
||||||
|
|
||||||
|
self.setItem(row, 0, cellSymbol)
|
||||||
|
self.setItem(row, 1, cellBid)
|
||||||
|
self.setItem(row, 2, cellPricing)
|
||||||
|
self.setItem(row, 3, cellAsk)
|
||||||
|
self.setItem(row, 4, cellStrike)
|
||||||
|
|
||||||
|
d = {}
|
||||||
|
d['bid'] = cellBid
|
||||||
|
d['ask'] = cellAsk
|
||||||
|
d['pricing'] = cellPricing
|
||||||
|
self.cellDict[option.symbol] = d
|
||||||
|
|
||||||
|
for row, option in enumerate(chain.putDict.values()):
|
||||||
|
cellSymbol = OmCell(option.symbol, COLOR_SYMBOL, COLOR_BLACK)
|
||||||
|
cellBid = OmCell('%.1f' %(option.bidImpv*100), COLOR_BID, COLOR_BLACK)
|
||||||
|
cellPricing = OmCell('%.1f' %(option.pricingImpv*100), COLOR_POS, COLOR_BLACK)
|
||||||
|
cellAsk = OmCell('%.1f' %(option.askImpv*100), COLOR_ASK, COLOR_BLACK)
|
||||||
|
|
||||||
|
cellPricing.data = option.symbol
|
||||||
|
|
||||||
|
self.setItem(row, 5, cellBid)
|
||||||
|
self.setItem(row, 6, cellPricing)
|
||||||
|
self.setItem(row, 7, cellAsk)
|
||||||
|
self.setItem(row, 8, cellSymbol)
|
||||||
|
|
||||||
|
d = {}
|
||||||
|
d['bid'] = cellBid
|
||||||
|
d['ask'] = cellAsk
|
||||||
|
d['pricing'] = cellPricing
|
||||||
|
self.cellDict[option.symbol] = d
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def refresh(self):
|
||||||
|
"""刷新数据"""
|
||||||
|
for option in self.chain.optionDict.values():
|
||||||
|
d = self.cellDict[option.symbol]
|
||||||
|
d['bid'].setText('%.1f' %(option.bidImpv*100))
|
||||||
|
d['ask'].setText('%.1f' %(option.askImpv*100))
|
||||||
|
d['pricing'].setText('%.1f' %(option.pricingImpv*100))
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def pricingImpvChanged(self, item):
|
||||||
|
"""更细定价波动率"""
|
||||||
|
if not item.data:
|
||||||
|
return
|
||||||
|
|
||||||
|
option = self.chain.optionDict[item.data]
|
||||||
|
newImpv = float(item.text())/100
|
||||||
|
|
||||||
|
if option.pricingImpv != newImpv:
|
||||||
|
option.pricingImpv = newImpv
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class ChainVolatilityManager(QtWidgets.QWidget):
|
||||||
|
"""期权链波动率管理"""
|
||||||
|
IMPV_CHANGE_STEP = 0.001
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self, chain, parent=None):
|
||||||
|
"""Constructor"""
|
||||||
|
super(ChainVolatilityManager, self).__init__(parent)
|
||||||
|
|
||||||
|
self.chain = chain
|
||||||
|
|
||||||
|
self.initUi()
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def initUi(self):
|
||||||
|
"""初始化界面"""
|
||||||
|
self.monitor = ChainVolatilityMonitor(self.chain)
|
||||||
|
|
||||||
|
buttonCallIncrease = QtWidgets.QPushButton(u'看涨+' + ('%.1f%%' %(self.IMPV_CHANGE_STEP*100)))
|
||||||
|
buttonCallDecrease = QtWidgets.QPushButton(u'看涨-' + ('%.1f%%' %(self.IMPV_CHANGE_STEP*100)))
|
||||||
|
buttonPutIncrease = QtWidgets.QPushButton(u'看跌+' + ('%.1f%%' %(self.IMPV_CHANGE_STEP*100)))
|
||||||
|
buttonPutDecrease = QtWidgets.QPushButton(u'看跌-' + ('%.1f%%' %(self.IMPV_CHANGE_STEP*100)))
|
||||||
|
buttonCallReset = QtWidgets.QPushButton(u'看涨重置')
|
||||||
|
buttonPutReset = QtWidgets.QPushButton(u'看跌重置')
|
||||||
|
buttonRefresh = QtWidgets.QPushButton(u'刷新')
|
||||||
|
|
||||||
|
buttonCallIncrease.clicked.connect(self.callIncrease)
|
||||||
|
buttonCallDecrease.clicked.connect(self.callDecrease)
|
||||||
|
buttonPutIncrease.clicked.connect(self.putIncrease)
|
||||||
|
buttonPutDecrease.clicked.connect(self.putDecrease)
|
||||||
|
buttonCallReset.clicked.connect(self.callReset)
|
||||||
|
buttonPutReset.clicked.connect(self.putReset)
|
||||||
|
buttonRefresh.clicked.connect(self.monitor.refresh)
|
||||||
|
|
||||||
|
hbox = QtWidgets.QHBoxLayout()
|
||||||
|
hbox.addStretch()
|
||||||
|
hbox.addWidget(buttonCallIncrease)
|
||||||
|
hbox.addWidget(buttonCallReset)
|
||||||
|
hbox.addWidget(buttonCallDecrease)
|
||||||
|
hbox.addStretch()
|
||||||
|
hbox.addWidget(buttonRefresh)
|
||||||
|
hbox.addStretch()
|
||||||
|
hbox.addWidget(buttonPutIncrease)
|
||||||
|
hbox.addWidget(buttonPutReset)
|
||||||
|
hbox.addWidget(buttonPutDecrease)
|
||||||
|
hbox.addStretch()
|
||||||
|
|
||||||
|
vbox = QtWidgets.QVBoxLayout()
|
||||||
|
vbox.addLayout(hbox)
|
||||||
|
vbox.addWidget(self.monitor)
|
||||||
|
|
||||||
|
self.setLayout(vbox)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def callIncrease(self):
|
||||||
|
"""看涨增加"""
|
||||||
|
for option in self.chain.callDict.values():
|
||||||
|
option.pricingImpv += self.IMPV_CHANGE_STEP
|
||||||
|
self.monitor.refresh()
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def callDecrease(self):
|
||||||
|
"""看涨减少"""
|
||||||
|
for option in self.chain.callDict.values():
|
||||||
|
option.pricingImpv -= self.IMPV_CHANGE_STEP
|
||||||
|
self.monitor.refresh()
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def callReset(self):
|
||||||
|
"""看涨重置为中值"""
|
||||||
|
for option in self.chain.callDict.values():
|
||||||
|
option.pricingImpv = option.midImpv
|
||||||
|
self.monitor.refresh()
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def putIncrease(self):
|
||||||
|
"""看跌增加"""
|
||||||
|
for option in self.chain.putDict.values():
|
||||||
|
option.pricingImpv += self.IMPV_CHANGE_STEP
|
||||||
|
self.monitor.refresh()
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def putDecrease(self):
|
||||||
|
"""看跌减少"""
|
||||||
|
for option in self.chain.putDict.values():
|
||||||
|
option.pricingImpv -= self.IMPV_CHANGE_STEP
|
||||||
|
self.monitor.refresh()
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def putReset(self):
|
||||||
|
"""看跌重置为中值"""
|
||||||
|
for option in self.chain.putDict.values():
|
||||||
|
option.pricingImpv = option.midImpv
|
||||||
|
self.monitor.refresh()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class VolatilityManager(QtWidgets.QWidget):
|
||||||
|
"""波动率管理"""
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self, omEngine, parent=None):
|
||||||
|
"""Constructor"""
|
||||||
|
super(VolatilityManager, self).__init__(parent)
|
||||||
|
|
||||||
|
self.omEngine = omEngine
|
||||||
|
self.portfolio = omEngine.portfolio
|
||||||
|
self.eventEngine = omEngine.eventEngine
|
||||||
|
|
||||||
|
self.initUi()
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def initUi(self):
|
||||||
|
"""初始化界面"""
|
||||||
|
self.setWindowTitle(u'波动率管理')
|
||||||
|
|
||||||
|
tab = QtWidgets.QTabWidget()
|
||||||
|
for chain in self.portfolio.chainDict.values():
|
||||||
|
chainManager = ChainVolatilityManager(chain)
|
||||||
|
tab.addTab(chainManager, chain.symbol)
|
||||||
|
|
||||||
|
vbox = QtWidgets.QVBoxLayout()
|
||||||
|
vbox.addWidget(tab)
|
||||||
|
|
||||||
|
self.setLayout(vbox)
|
@ -11,7 +11,7 @@ from .omBase import EVENT_OM_LOG
|
|||||||
from .uiOmBase import QtWidgets, QtCore
|
from .uiOmBase import QtWidgets, QtCore
|
||||||
from .uiOmManualTrader import ManualTrader
|
from .uiOmManualTrader import ManualTrader
|
||||||
from .uiOmGreeksMonitor import GreeksMonitor
|
from .uiOmGreeksMonitor import GreeksMonitor
|
||||||
from .uiOmVolatilityManager import VolatilityChart
|
from .uiOmVolatilityManager import VolatilityChart, VolatilityManager
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
@ -56,12 +56,19 @@ class OmManager(QtWidgets.QWidget):
|
|||||||
|
|
||||||
self.buttonManualTrader = QtWidgets.QPushButton(u'手动交易')
|
self.buttonManualTrader = QtWidgets.QPushButton(u'手动交易')
|
||||||
self.buttonManualTrader.clicked.connect(self.openManualTrader)
|
self.buttonManualTrader.clicked.connect(self.openManualTrader)
|
||||||
|
self.buttonManualTrader.setDisabled(True)
|
||||||
|
|
||||||
self.buttonGreeksMonitor = QtWidgets.QPushButton(u'希腊值监控')
|
self.buttonGreeksMonitor = QtWidgets.QPushButton(u'希腊值监控')
|
||||||
self.buttonGreeksMonitor.clicked.connect(self.openGreeksMonitor)
|
self.buttonGreeksMonitor.clicked.connect(self.openGreeksMonitor)
|
||||||
|
self.buttonGreeksMonitor.setDisabled(True)
|
||||||
|
|
||||||
self.buttonVolatilityChart = QtWidgets.QPushButton(u'波动率图表')
|
self.buttonVolatilityChart = QtWidgets.QPushButton(u'波动率图表')
|
||||||
self.buttonVolatilityChart.clicked.connect(self.openVolatilityChart)
|
self.buttonVolatilityChart.clicked.connect(self.openVolatilityChart)
|
||||||
|
self.buttonVolatilityChart.setDisabled(True)
|
||||||
|
|
||||||
|
self.buttonVolatilityManager = QtWidgets.QPushButton(u'波动率管理')
|
||||||
|
self.buttonVolatilityManager.clicked.connect(self.openVolatilityManager)
|
||||||
|
self.buttonVolatilityManager.setDisabled(True)
|
||||||
|
|
||||||
self.logMonitor = QtWidgets.QTextEdit()
|
self.logMonitor = QtWidgets.QTextEdit()
|
||||||
self.logMonitor.setReadOnly(True)
|
self.logMonitor.setReadOnly(True)
|
||||||
@ -72,6 +79,7 @@ class OmManager(QtWidgets.QWidget):
|
|||||||
hbox.addWidget(self.buttonManualTrader)
|
hbox.addWidget(self.buttonManualTrader)
|
||||||
hbox.addWidget(self.buttonGreeksMonitor)
|
hbox.addWidget(self.buttonGreeksMonitor)
|
||||||
hbox.addWidget(self.buttonVolatilityChart)
|
hbox.addWidget(self.buttonVolatilityChart)
|
||||||
|
hbox.addWidget(self.buttonVolatilityManager)
|
||||||
hbox.addStretch()
|
hbox.addStretch()
|
||||||
|
|
||||||
hbox2 = QtWidgets.QHBoxLayout()
|
hbox2 = QtWidgets.QHBoxLayout()
|
||||||
@ -94,9 +102,21 @@ class OmManager(QtWidgets.QWidget):
|
|||||||
|
|
||||||
if result:
|
if result:
|
||||||
self.writeLog(u'引擎初始化成功')
|
self.writeLog(u'引擎初始化成功')
|
||||||
|
self.enableButtons()
|
||||||
else:
|
else:
|
||||||
self.writeLog(u'请勿重复初始化引擎')
|
self.writeLog(u'请勿重复初始化引擎')
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def enableButtons(self):
|
||||||
|
"""启用按钮"""
|
||||||
|
self.comboSettingFile.setDisabled(True)
|
||||||
|
self.buttonInit.setDisabled(True)
|
||||||
|
|
||||||
|
self.buttonManualTrader.setEnabled(True)
|
||||||
|
self.buttonGreeksMonitor.setEnabled(True)
|
||||||
|
self.buttonVolatilityChart.setEnabled(True)
|
||||||
|
self.buttonVolatilityManager.setEnabled(True)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def writeLog(self, content, time=''):
|
def writeLog(self, content, time=''):
|
||||||
"""记录日志"""
|
"""记录日志"""
|
||||||
@ -139,6 +159,15 @@ class OmManager(QtWidgets.QWidget):
|
|||||||
self.widgetDict['volatilityChart'] = VolatilityChart(self.omEngine)
|
self.widgetDict['volatilityChart'] = VolatilityChart(self.omEngine)
|
||||||
self.widgetDict['volatilityChart'].showMaximized()
|
self.widgetDict['volatilityChart'].showMaximized()
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def openVolatilityManager(self):
|
||||||
|
"""打开波动率管理组件"""
|
||||||
|
try:
|
||||||
|
self.widgetDict['volatilityManager'].show()
|
||||||
|
except KeyError:
|
||||||
|
self.widgetDict['volatilityManager'] = VolatilityManager(self.omEngine)
|
||||||
|
self.widgetDict['volatilityManager'].show()
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def close(self):
|
def close(self):
|
||||||
"""关闭"""
|
"""关闭"""
|
||||||
|
@ -454,8 +454,8 @@ class MarketMonitor(BasicMonitor):
|
|||||||
# 设置字体
|
# 设置字体
|
||||||
self.setFont(BASIC_FONT)
|
self.setFont(BASIC_FONT)
|
||||||
|
|
||||||
# 设置允许排序
|
# 设置排序
|
||||||
self.setSorting(True)
|
self.setSorting(False)
|
||||||
|
|
||||||
# 初始化表格
|
# 初始化表格
|
||||||
self.initTable()
|
self.initTable()
|
||||||
|
Loading…
Reference in New Issue
Block a user