[Add]初步完成OptionMaster核心定价部分的开发
This commit is contained in:
parent
a4394d2baa
commit
64bd2eb6d2
@ -1 +1 @@
|
||||
PurwJxAEvTeQ9X8HMnmMRw==
|
||||
B7/DvEptJ5IBD1LIj9SEFg==
|
@ -19,7 +19,7 @@ from vnpy.trader.uiMainWindow import MainWindow
|
||||
from vnpy.trader.gateway import (secGateway)
|
||||
|
||||
# 加载上层应用
|
||||
from vnpy.trader.app import (riskManager)
|
||||
from vnpy.trader.app import (riskManager, optionMaster)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@ -39,6 +39,7 @@ def main():
|
||||
|
||||
# 添加上层应用
|
||||
me.addApp(riskManager)
|
||||
me.addApp(optionMaster)
|
||||
|
||||
# 创建主窗口
|
||||
mw = MainWindow(me, ee)
|
||||
|
0
vnpy/pricing/__init__.py
Normal file
0
vnpy/pricing/__init__.py
Normal file
@ -23,6 +23,7 @@ theta:当t变动1天时,price的变动(国内交易日每年240天)
|
||||
vega:当v涨跌1个点时,price的变动(如从16%涨到17%)
|
||||
'''
|
||||
|
||||
from __future__ import division
|
||||
|
||||
from scipy import stats
|
||||
from math import (log, pow, sqrt, exp)
|
||||
@ -74,9 +75,15 @@ 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
|
||||
return vega
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def calculateOriginalVega(f, k, r, t, v, cp):
|
||||
"""计算原始vega值"""
|
||||
price1 = calculatePrice(f, k, r, t, v*STEP_UP, cp)
|
||||
price2 = calculatePrice(f, k, r, t, v*STEP_DOWN, cp)
|
||||
vega = (price1 - price2) / (v * STEP_DIFF * 100)
|
||||
vega = (price1 - price2) / (v * STEP_DIFF)
|
||||
return vega
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@ -109,12 +116,13 @@ def calculateImpv(price, f, k, r, t, cp):
|
||||
return 0
|
||||
|
||||
# 采用Newton Raphson方法计算隐含波动率
|
||||
v = 0.2 # 初始波动率猜测
|
||||
v = 0.3 # 初始波动率猜测
|
||||
|
||||
for i in range(50):
|
||||
# 计算当前猜测波动率对应的期权价格和vega值
|
||||
p = calculatePrice(f, k, r, t, v, cp)
|
||||
vega = calculateVega(f, k, r, t, v, cp)
|
||||
#print 'calculating vega', f, k, r, t, v, cp
|
||||
vega = calculateOriginalVega(f, k, r, t, v, cp)
|
||||
|
||||
# 计算误差
|
||||
dx = (price - p) / vega
|
||||
|
@ -1,10 +1,10 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
#from rmEngine import RmEngine
|
||||
#from uiRmWidget import RmEngineManager
|
||||
from .omEngine import OmEngine
|
||||
from .uiOmWidget import OmManager
|
||||
|
||||
appName = 'OptionMaster'
|
||||
appDisplayName = u'OptionMaster'
|
||||
appEngine = None
|
||||
appWidget = None
|
||||
appEngine = OmEngine
|
||||
appWidget = OmManager
|
||||
appIco = 'om.ico'
|
@ -2,19 +2,18 @@
|
||||
"name": "etf_portfolio",
|
||||
"model": "black",
|
||||
"underlying": [
|
||||
"IH1711",
|
||||
"IH1712"
|
||||
"510050"
|
||||
],
|
||||
"chain": [
|
||||
{
|
||||
"underlyingSymbol": "IH1711",
|
||||
"chainSymbol": "m1709",
|
||||
"interestRate": 0.03,
|
||||
"underlyingSymbol": "510050",
|
||||
"chainSymbol": "510050-1712",
|
||||
"r": 0.03
|
||||
},
|
||||
{
|
||||
"underlyingSymbol": "IH1711",
|
||||
"chainSymbol": "m1801",
|
||||
"interestRate": 0.03,
|
||||
"underlyingSymbol": "510050",
|
||||
"chainSymbol": "510050-1801",
|
||||
"r": 0.03
|
||||
}
|
||||
]
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
from __future__ import division
|
||||
|
||||
from copy import copy
|
||||
from collections import OrderedDict
|
||||
|
||||
@ -26,7 +28,10 @@ class OmInstrument(VtTickData):
|
||||
"""Constructor"""
|
||||
super(OmInstrument, self).__init__()
|
||||
|
||||
self.tickInited = False
|
||||
|
||||
# 初始化合约信息
|
||||
self.symbol = contract.symbol
|
||||
self.exchange = contract.exchange
|
||||
self.vtSymbol = contract.vtSymbol
|
||||
|
||||
@ -38,10 +43,15 @@ class OmInstrument(VtTickData):
|
||||
self.midPrice = EMPTY_FLOAT
|
||||
|
||||
# 持仓数据
|
||||
self.longPos = detail.longPos
|
||||
self.shortPos = detail.shortPos
|
||||
self.netPos = self.longPos - self.shortPos
|
||||
self.longPos = 0
|
||||
self.shortPos = 0
|
||||
self.netPos = 0
|
||||
|
||||
if detail:
|
||||
self.longPos = detail.longPos
|
||||
self.shortPos = detail.shortPos
|
||||
self.netPos = self.longPos - self.shortPos
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def newTick(self, tick):
|
||||
"""行情更新"""
|
||||
@ -61,6 +71,7 @@ class OmInstrument(VtTickData):
|
||||
self.askPrice1 = tick.askPrice1
|
||||
self.bidVolume1 = tick.bidVolume1
|
||||
self.askVolume1 = tick.askVolume1
|
||||
self.midPrice = (self.bidPrice1 + self.askPrice1) / 2
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def newTrade(self, trade):
|
||||
@ -98,17 +109,22 @@ class OmUnderlying(OmInstrument):
|
||||
"""标的物"""
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self, contract, chainList):
|
||||
def __init__(self, contract, detail, chainList=None):
|
||||
"""Constructor"""
|
||||
super(OmUnderlying, self).__init__(contract)
|
||||
super(OmUnderlying, self).__init__(contract, detail)
|
||||
|
||||
# 以该合约为标的物的期权链字典
|
||||
self.chainDict = OrderedDict((chain.symbol, chain) for chain in chainList)
|
||||
self.chainDict = OrderedDict()
|
||||
|
||||
# 希腊值
|
||||
self.theoDelta = EMPTY_FLOAT # 理论delta值
|
||||
self.posDelta = EMPTY_FLOAT # 持仓delta值
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def addChain(self, chain):
|
||||
"""添加以该合约为标的的期权链"""
|
||||
self.chainDict[chain.symbol] = chain
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def newTick(self, tick):
|
||||
"""行情更新"""
|
||||
@ -117,7 +133,7 @@ class OmUnderlying(OmInstrument):
|
||||
self.theoDelta = self.size * self.midPrice / 100
|
||||
|
||||
# 遍历推送自己的行情到期权链中
|
||||
for chain in self.chainList:
|
||||
for chain in self.chainDict.values():
|
||||
chain.newUnderlyingTick()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@ -137,12 +153,12 @@ class OmOption(OmInstrument):
|
||||
"""期权"""
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self, contract, underlying, model, r):
|
||||
def __init__(self, contract, detail, underlying, model, r):
|
||||
"""Constructor"""
|
||||
super(OmOption, self).__init__(contract)
|
||||
super(OmOption, self).__init__(contract, detail)
|
||||
|
||||
# 期权属性
|
||||
self.underlying = None # 标的物对象
|
||||
self.underlying = underlying # 标的物对象
|
||||
self.k = contract.strikePrice # 行权价
|
||||
self.r = r # 利率
|
||||
|
||||
@ -183,7 +199,7 @@ class OmOption(OmInstrument):
|
||||
self.chain = None
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def calculateImpv(self):
|
||||
def calculateOptionImpv(self):
|
||||
"""计算隐含波动率"""
|
||||
underlyingPrice = self.underlying.midPrice
|
||||
if not underlyingPrice:
|
||||
@ -222,12 +238,12 @@ class OmOption(OmInstrument):
|
||||
def newTick(self, tick):
|
||||
"""行情更新"""
|
||||
super(OmOption, self).newTick(tick)
|
||||
self.calculateImpv()
|
||||
self.calculateOptionImpv()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def newUnderlyingTick(self):
|
||||
"""标的行情更新"""
|
||||
self.calculateImpv()
|
||||
self.calculateOptionImpv()
|
||||
self.calculateTheoGreeks()
|
||||
self.calculatePosGreeks()
|
||||
|
||||
@ -243,7 +259,6 @@ class OmOption(OmInstrument):
|
||||
self.underlying = underlying
|
||||
|
||||
|
||||
|
||||
########################################################################
|
||||
class OmChain(object):
|
||||
"""期权链"""
|
||||
@ -394,10 +409,10 @@ class OmPortfolio(object):
|
||||
self.posTheta = 0
|
||||
self.posVega = 0
|
||||
|
||||
for underlying in self.underlyingList:
|
||||
for underlying in self.underlyingDict.values():
|
||||
self.posDelta += underlying.posDelta
|
||||
|
||||
for chain in self.chainList:
|
||||
for chain in self.chainDict.values():
|
||||
self.longPos += chain.longPos
|
||||
self.shortPos += chain.shortPos
|
||||
|
||||
|
@ -5,16 +5,26 @@ import json
|
||||
import shelve
|
||||
import os
|
||||
import traceback
|
||||
from collections import OrderedDict
|
||||
|
||||
from vnpy.event import Event
|
||||
from vnpy.trader.vtEvent import EVENT_TICK, EVENT_TRADE, EVENT_CONTRACT
|
||||
from vnpy.trader.vtFunction import getTempPath, getJsonPath
|
||||
from vnpy.trader.vtObject import VtLogData
|
||||
from vnpy.trader.vtObject import VtLogData, VtSubscribeReq
|
||||
from vnpy.trader.vtConstant import PRODUCT_OPTION, OPTION_CALL, OPTION_PUT
|
||||
from vnpy.pricing import black
|
||||
|
||||
from .omBase import (OmOption, OmUnderlying, OmChain, OmPortfolio,
|
||||
EVENT_OM_LOG)
|
||||
|
||||
|
||||
|
||||
# 定价模型字典
|
||||
MODEL_DICT = {}
|
||||
MODEL_DICT['black'] = black
|
||||
|
||||
|
||||
|
||||
########################################################################
|
||||
class OmEngine(object):
|
||||
"""期权主引擎"""
|
||||
@ -28,7 +38,7 @@ class OmEngine(object):
|
||||
self.eventEngine = eventEngine
|
||||
|
||||
self.portfolio = None
|
||||
self.contractDict = {} # symbol:contract
|
||||
self.optionContractDict = {} # symbol:contract
|
||||
|
||||
self.registerEvent()
|
||||
|
||||
@ -53,18 +63,22 @@ class OmEngine(object):
|
||||
def processContractEvent(self, event):
|
||||
"""合约事件"""
|
||||
contract = event.dict_['data']
|
||||
if contract.symbol:
|
||||
self.contractDict[contract.symbol] = contract
|
||||
if contract.symbol and contract.productClass == PRODUCT_OPTION:
|
||||
self.optionContractDict[contract.symbol] = contract
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def subscribeEvent(self, symbol):
|
||||
"""订阅对应合约的事件"""
|
||||
contract = self.contractDict[symbol]
|
||||
contract = self.mainEngine.getContract(symbol)
|
||||
if not contract:
|
||||
self.writeLog(u'行情订阅失败,找不到合约:%s' %symbol)
|
||||
return
|
||||
|
||||
vtSymbol = contract.vtSymbol
|
||||
|
||||
# 订阅行情
|
||||
req = VtSubscribeReq()
|
||||
req.symbol = symbol
|
||||
req.symbol = contract.symbol
|
||||
req.exchange = contract.exchange
|
||||
self.mainEngine.subscribe(req, contract.gatewayName)
|
||||
|
||||
@ -80,67 +94,81 @@ class OmEngine(object):
|
||||
|
||||
f = file(fileName)
|
||||
setting = json.load(f)
|
||||
|
||||
# 读取定价模型
|
||||
model = MODEL_DICT.get(setting['model'], None)
|
||||
if not model:
|
||||
self.writeLog(u'找不到定价模型%s' %setting['model'])
|
||||
return
|
||||
|
||||
# 创建期货和股票标的对象
|
||||
equityDict = OrderedDict([(symbol, OmEquity(symbol)) for symbol in setting['equity']])
|
||||
futuresDict = OrderedDict([(symbol, OmFutures(symbol)) for symbol in setting['futures']])
|
||||
# 创建标的对象
|
||||
underlyingDict = OrderedDict()
|
||||
|
||||
for underlyingSymbol in setting['underlying']:
|
||||
contract = self.mainEngine.getContract(underlyingSymbol)
|
||||
if not contract:
|
||||
self.writeLog(u'找不到标的物合约%s' %underlyingSymbol)
|
||||
continue
|
||||
|
||||
detail = self.mainEngine.getPositionDetail(contract.vtSymbol)
|
||||
|
||||
underlying = OmUnderlying(contract, detail)
|
||||
underlyingDict[underlyingSymbol] = underlying
|
||||
|
||||
# 创建期权链对象并初始化
|
||||
chainDict = OrderedDict()
|
||||
chainList = []
|
||||
|
||||
for d in setting['chain']:
|
||||
interestRate = d['interestRate']
|
||||
chainSymbol = d['chainSymbol']
|
||||
r = d['r']
|
||||
|
||||
# 锁定标的对象,若无则创建
|
||||
if d['underlyingType'] == 'futures':
|
||||
if d['underlyingSymbol'] not in futuresDict:
|
||||
underlying = OmFutures(d['underlyingSymbol'])
|
||||
futuresDict[underlying.symbol] = underlying
|
||||
else:
|
||||
underlying = futuresDict[d['underlyingSymbol']]
|
||||
elif d['underlyingType'] == 'equity':
|
||||
if d['underlyingSymbol'] not in equityDict:
|
||||
underlying = OmEquity(d['underlyingSymbol'])
|
||||
equityDict[underlying.symbol] = underlying
|
||||
else:
|
||||
underlying = equityDict[d['underlyingSymbol']]
|
||||
# 锁定标的对象
|
||||
underlying = underlyingDict.get(d['underlyingSymbol'], None)
|
||||
if not underlying:
|
||||
self.writeLog(u'%s期权链的标的合约%s尚未创建,请检查配置文件' %(chainSymbol, underlyingSymbol))
|
||||
continue
|
||||
|
||||
# 创建期权对象并初始化
|
||||
callList = []
|
||||
putList = []
|
||||
callDict = {}
|
||||
putDict = {}
|
||||
|
||||
for symbol, contract in self.contractDict.items():
|
||||
if contract.optionType and contract.underlyingSymbol == d['chainSymbol']:
|
||||
option = OmOption(symbol)
|
||||
option.init(contract, underlying, interestRate)
|
||||
self.subscribeEvent(option.symbol) # 订阅事件
|
||||
for symbol, contract in self.optionContractDict.items():
|
||||
if contract.underlyingSymbol == d['chainSymbol']:
|
||||
detail = self.mainEngine.getPositionDetail(contract.vtSymbol)
|
||||
option = OmOption(contract, detail, underlying, model, r)
|
||||
|
||||
if contract.optionType is OPTION_CALL:
|
||||
callList.append(option)
|
||||
callDict[option.k] = option
|
||||
else:
|
||||
putList.append(option)
|
||||
putDict[option.k] = option
|
||||
|
||||
# 期权排序
|
||||
strikeList = callDict.keys()
|
||||
strikeList.sort()
|
||||
callList = [callDict[k] for k in strikeList]
|
||||
putList = [putDict[k] for k in strikeList]
|
||||
|
||||
# 创建期权链
|
||||
chain = OmChain(chainSymbol, callList, putList)
|
||||
chainList.append(chain)
|
||||
|
||||
# 添加标的映射关系
|
||||
underlying.addChain(chain)
|
||||
|
||||
chain = OmChain(d['chainSymbol'])
|
||||
chain.init(underlying, callList, putList)
|
||||
chainDict[chain.symbol] = chain
|
||||
|
||||
# 初始化标的对象
|
||||
for underlying in (equityDict.values() + futuresDict.values()):
|
||||
l = []
|
||||
for chain in chainDict.values():
|
||||
if chain.underlying is underlying:
|
||||
l.append(chain)
|
||||
contract = self.contractDict[underlying.symbol]
|
||||
underlying.init(contract, l)
|
||||
self.subscribeEvent(underlying.symbol) # 订阅事件
|
||||
|
||||
# 创建持仓组合对象并初始化
|
||||
self.portfolio = OmPortfolio(setting['name'])
|
||||
self.portfolio.init(futuresDict, equityDict, chainDict)
|
||||
self.portfolio = OmPortfolio(setting['name'], underlyingDict.values(), chainList)
|
||||
|
||||
# 载入波动率配置
|
||||
self.loadImpvSetting()
|
||||
|
||||
# 订阅行情和事件
|
||||
for underlying in underlyingDict.values():
|
||||
self.subscribeEvent(underlying.vtSymbol)
|
||||
|
||||
for chain in chainList:
|
||||
for option in chain.optionDict.values():
|
||||
self.subscribeEvent(option.vtSymbol)
|
||||
|
||||
# 载入成功返回
|
||||
return True
|
||||
|
||||
|
123
vnpy/trader/app/optionMaster/uiOmWidget.py
Normal file
123
vnpy/trader/app/optionMaster/uiOmWidget.py
Normal file
@ -0,0 +1,123 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
from __future__ import division
|
||||
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
from vnpy.event import Event
|
||||
from vnpy.trader.uiQt import QtWidgets, QtCore
|
||||
|
||||
from .omBase import EVENT_OM_LOG
|
||||
|
||||
|
||||
########################################################################
|
||||
class OmManager(QtWidgets.QWidget):
|
||||
"""管理组件"""
|
||||
signal = QtCore.pyqtSignal(type(Event()))
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self, omEngine, eventEngine, parent=None):
|
||||
"""Constructor"""
|
||||
super(OmManager, self).__init__(parent)
|
||||
|
||||
self.omEngine = omEngine
|
||||
self.eventEngine = eventEngine
|
||||
|
||||
self.widgetDict = {}
|
||||
|
||||
self.initUi()
|
||||
self.registerEvent()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def initUi(self):
|
||||
"""初始化界面"""
|
||||
self.setWindowTitle(u'OptionMaster管理')
|
||||
|
||||
# 读取配置文件
|
||||
settingFileList = []
|
||||
|
||||
path = os.path.abspath(os.path.dirname(__file__))
|
||||
for root, subdirs, files in os.walk(path):
|
||||
for name in files:
|
||||
if '_portfolio.json' in name:
|
||||
settingFileList.append(name)
|
||||
|
||||
# 设置界面
|
||||
self.comboSettingFile = QtWidgets.QComboBox()
|
||||
self.comboSettingFile.addItems(settingFileList)
|
||||
self.comboSettingFile.setCurrentIndex(0)
|
||||
|
||||
self.buttonInit = QtWidgets.QPushButton(u'初始化')
|
||||
self.buttonInit.clicked.connect(self.initOmEngine)
|
||||
|
||||
self.logMonitor = QtWidgets.QTextEdit()
|
||||
self.logMonitor.setReadOnly(True)
|
||||
|
||||
hbox = QtWidgets.QHBoxLayout()
|
||||
hbox.addWidget(self.comboSettingFile)
|
||||
hbox.addWidget(self.buttonInit)
|
||||
hbox.addStretch()
|
||||
|
||||
hbox2 = QtWidgets.QHBoxLayout()
|
||||
hbox2.addStretch()
|
||||
|
||||
vbox = QtWidgets.QVBoxLayout()
|
||||
vbox.addLayout(hbox)
|
||||
vbox.addLayout(hbox2)
|
||||
vbox.addWidget(self.logMonitor)
|
||||
|
||||
self.setLayout(vbox)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def initOmEngine(self):
|
||||
"""初始化引擎"""
|
||||
path = os.path.abspath(os.path.dirname(__file__))
|
||||
fileName = unicode(self.comboSettingFile.currentText())
|
||||
fileName = os.path.join(path, fileName)
|
||||
result = self.omEngine.initEngine(fileName)
|
||||
|
||||
if result:
|
||||
self.writeLog(u'引擎初始化成功')
|
||||
else:
|
||||
self.writeLog(u'请勿重复初始化引擎')
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def writeLog(self, content, time=''):
|
||||
"""记录日志"""
|
||||
if not time:
|
||||
time = datetime.now().strftime('%H:%M:%S')
|
||||
content = time + '\t' + content
|
||||
self.logMonitor.append(content)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def processLogEvent(self, event):
|
||||
"""处理日志事件"""
|
||||
log = event.dict_['data']
|
||||
self.writeLog(log.logContent, log.logTime)
|
||||
self.raise_()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def openManualTrader(self):
|
||||
"""打开手动交易"""
|
||||
try:
|
||||
self.widgetDict['manualTrader'].showMaximized()
|
||||
except KeyError:
|
||||
self.widgetDict['manualTrader'] = ManualTrader(self.omEngine)
|
||||
self.widgetDict['manualTrader'].showMaximized()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def close(self):
|
||||
"""关闭"""
|
||||
for widget in self.widgetDict.values():
|
||||
widget.close()
|
||||
|
||||
super(OmManagerWidget, self).close()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def registerEvent(self):
|
||||
"""注册事件监听"""
|
||||
self.signal.connect(self.processLogEvent)
|
||||
|
||||
self.eventEngine.register(EVENT_OM_LOG, self.signal.emit)
|
||||
|
@ -50,8 +50,11 @@ exchangeMapReverse = {v:k for k,v in exchangeMap.items()}
|
||||
#----------------------------------------------------------------------
|
||||
def print_dict(d):
|
||||
""""""
|
||||
for k, v in d.items():
|
||||
print '%s:%s' %(k, v)
|
||||
print '-' * 30
|
||||
l = d.keys()
|
||||
l.sort()
|
||||
for k in l:
|
||||
print '%s:%s' %(k, d[k])
|
||||
|
||||
|
||||
########################################################################
|
||||
@ -893,7 +896,7 @@ class SecTdApi(TdApi):
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def onRspStockQryStockStaticInfo(self, data, error, flag):
|
||||
"""股票合约查询回报"""
|
||||
"""股票合约查询回报"""
|
||||
if not data:
|
||||
return
|
||||
|
||||
@ -1226,8 +1229,8 @@ class SecTdApi(TdApi):
|
||||
|
||||
contract.strikePrice = data['execPrice']
|
||||
|
||||
contract.underlyingSymbol = data['securityID']
|
||||
contract.expiryDate = data['endTradingDay']
|
||||
contract.underlyingSymbol = '-'.join([data['securityID'], str(data['endTradingDay'])[2:-2]])
|
||||
contract.expiryDate = str(data['endTradingDay'])
|
||||
|
||||
# 合约类型
|
||||
contract.productClass = PRODUCT_OPTION
|
||||
|
@ -277,6 +277,11 @@ class MainEngine(object):
|
||||
"""查询委托"""
|
||||
return self.dataEngine.getOrder(vtOrderID)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def getPositionDetail(self, vtSymbol):
|
||||
"""查询持仓细节"""
|
||||
return self.dataEngine.getPositionDetail(vtSymbol)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def getAllWorkingOrders(self):
|
||||
"""查询所有的活跃的委托(返回列表)"""
|
||||
|
Loading…
Reference in New Issue
Block a user