[Add]新增OptionMaster模块的策略交易引擎
This commit is contained in:
parent
b0902d2c65
commit
5cd3411895
@ -15,6 +15,8 @@ from .omDate import getTimeToMaturity
|
|||||||
CALL = 1
|
CALL = 1
|
||||||
PUT = -1
|
PUT = -1
|
||||||
|
|
||||||
|
OM_DB_NAME = 'VnTrader_OptionMaster_Db'
|
||||||
|
|
||||||
# 事件定义
|
# 事件定义
|
||||||
EVENT_OM_LOG = 'eOmLog'
|
EVENT_OM_LOG = 'eOmLog'
|
||||||
|
|
||||||
|
@ -8,20 +8,29 @@ import traceback
|
|||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from vnpy.event import Event
|
from vnpy.event import Event
|
||||||
from vnpy.trader.vtEvent import EVENT_TICK, EVENT_TRADE, EVENT_CONTRACT
|
from vnpy.trader.vtEvent import (EVENT_TICK, EVENT_TRADE, EVENT_CONTRACT,
|
||||||
|
EVENT_ORDER)
|
||||||
from vnpy.trader.vtFunction import getTempPath, getJsonPath
|
from vnpy.trader.vtFunction import getTempPath, getJsonPath
|
||||||
from vnpy.trader.vtObject import VtLogData, VtSubscribeReq
|
from vnpy.trader.vtObject import (VtLogData, VtSubscribeReq,
|
||||||
from vnpy.trader.vtConstant import PRODUCT_OPTION, OPTION_CALL, OPTION_PUT
|
VtOrderReq, VtCancelOrderReq)
|
||||||
from vnpy.pricing import black
|
from vnpy.trader.vtConstant import (PRODUCT_OPTION, OPTION_CALL, OPTION_PUT,
|
||||||
|
DIRECTION_LONG, DIRECTION_SHORT,
|
||||||
|
OFFSET_OPEN, OFFSET_CLOSE,
|
||||||
|
PRICETYPE_LIMITPRICE)
|
||||||
|
from vnpy.pricing import black, bs, crr
|
||||||
|
|
||||||
from .omBase import (OmOption, OmUnderlying, OmChain, OmPortfolio,
|
from .omBase import (OmOption, OmUnderlying, OmChain, OmPortfolio,
|
||||||
EVENT_OM_LOG)
|
EVENT_OM_LOG,
|
||||||
|
OM_DB_NAME)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 定价模型字典
|
# 定价模型字典
|
||||||
MODEL_DICT = {}
|
MODEL_DICT = {}
|
||||||
MODEL_DICT['black'] = black
|
MODEL_DICT['black'] = black
|
||||||
|
MODEL_DICT['bs'] = bs
|
||||||
|
MODEL_DICT['crr'] = crr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -210,4 +219,187 @@ class OmEngine(object):
|
|||||||
|
|
||||||
event = Event(EVENT_OM_LOG)
|
event = Event(EVENT_OM_LOG)
|
||||||
event.dict_['data'] = log
|
event.dict_['data'] = log
|
||||||
self.eventEngine.put(event)
|
self.eventEngine.put(event)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class OmStrategyEngine(object):
|
||||||
|
"""策略引擎"""
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self, omEngine, eventEngine):
|
||||||
|
"""Constructor"""
|
||||||
|
self.omEngine = omEngine
|
||||||
|
self.mainEngine = omEngine.mainEngine
|
||||||
|
self.eventEngine = eventEngine
|
||||||
|
|
||||||
|
self.portfolio = None
|
||||||
|
|
||||||
|
self.strategyDict = {} # name: strategy
|
||||||
|
self.symbolStrategyDict = {} # vtSymbol:strategy list
|
||||||
|
self.orderStrategyDict= {} # vtOrderID: strategy
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def registerEvent(self):
|
||||||
|
"""注册事件监听"""
|
||||||
|
self.eventEngine.register(EVENT_TICK, self.processTickEvent)
|
||||||
|
self.eventEngine.register(EVENT_TRADE, self.processTradeEvent)
|
||||||
|
self.eventEngine.register(EVENT_ORDER, self.processOrdervent)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def writeLog(self, content):
|
||||||
|
"""快速发出日志事件"""
|
||||||
|
self.omEngine.writeLog(content)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def callStrategyFunc(self, strategy, func, params=None):
|
||||||
|
"""调用策略的函数,若触发异常则捕捉"""
|
||||||
|
try:
|
||||||
|
if params:
|
||||||
|
func(params)
|
||||||
|
else:
|
||||||
|
func()
|
||||||
|
except Exception:
|
||||||
|
# 停止策略,修改状态为未初始化
|
||||||
|
strategy.trading = False
|
||||||
|
strategy.inited = False
|
||||||
|
|
||||||
|
# 发出日志
|
||||||
|
content = '\n'.join([u'策略%s触发异常已停止' %strategy.name,
|
||||||
|
traceback.format_exc()])
|
||||||
|
self.writeLog(content)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def processTickEvent(self, event):
|
||||||
|
"""处理行情事件"""
|
||||||
|
tick = event.dict_['data']
|
||||||
|
l = self.symbolStrategyDict.get(tick.vtSymbol, None)
|
||||||
|
if l:
|
||||||
|
for strategy in l:
|
||||||
|
self.callStrategyFunc(strategy, strategy.onTick, tick)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def processTradeEvent(self, event):
|
||||||
|
"""处理成交事件"""
|
||||||
|
trade = event.dict_['data']
|
||||||
|
strategy = self.orderStrategyDict.get(trade.vtOrderID, None)
|
||||||
|
if strategy:
|
||||||
|
self.callStrategyFunc(strategy, strategy.onTrade, trade)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def processOrderEvent(self, event):
|
||||||
|
"""处理委托事件"""
|
||||||
|
order = event.dict_['data']
|
||||||
|
strategy = self.orderStrategyDict.get(order.vtOrderID, None)
|
||||||
|
if strategy:
|
||||||
|
self.callStrategyFunc(strategy, strategy.onOrder, order)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def loadSetting(self):
|
||||||
|
"""加载配置"""
|
||||||
|
self.portfolio = self.omEngine.portfolio
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def initStrategy(self, name):
|
||||||
|
"""初始化策略"""
|
||||||
|
strategy = self.strategyDict[name]
|
||||||
|
self.callStrategyFunc(strategy, strategy.onInit)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def startStrategy(self, name):
|
||||||
|
"""启动策略"""
|
||||||
|
strategy = self.strategyDict[name]
|
||||||
|
self.callStrategyFunc(strategy, strategy.onStart)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def stopStrategy(self, name):
|
||||||
|
"""停止策略"""
|
||||||
|
strategy = self.strategyDict[name]
|
||||||
|
self.callStrategyFunc(strategy, strategy.onStop)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def sendOrder(self, vtSymbol, direction, offset, price, volume):
|
||||||
|
"""发单"""
|
||||||
|
contract = self.mainEngine.getContract(vtSymbol)
|
||||||
|
if not contract:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
req = VtOrderReq()
|
||||||
|
req.symbol = contract.symbol
|
||||||
|
req.exchange = contract.exchange
|
||||||
|
req.vtSymbol = vtSymbol
|
||||||
|
req.price = price
|
||||||
|
req.volume = volume
|
||||||
|
req.direction = direction
|
||||||
|
req.offset = offset
|
||||||
|
req.priceType = PRICETYPE_LIMITPRICE
|
||||||
|
|
||||||
|
return self.mainEngine.sendOrder(req, contract.gatewayName)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def cancelorder(self, vtOrderID):
|
||||||
|
"""撤单"""
|
||||||
|
order = self.mainEngine.getOrder(vtOrderID)
|
||||||
|
if not order:
|
||||||
|
return
|
||||||
|
|
||||||
|
req = VtCancelOrderReq()
|
||||||
|
req.symbol = order.symbol
|
||||||
|
req.exchange = order.exchange
|
||||||
|
req.orderID = order.orderID
|
||||||
|
req.symbol = order.symbol
|
||||||
|
req.vtSymbol = order.vtSymbo
|
||||||
|
|
||||||
|
self.mainEngine.cancelOrder(req, order.gatewayName)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def buy(self, vtSymbol, price, volume):
|
||||||
|
"""开多"""
|
||||||
|
return self.sendOrder(vtSymbol, DIRECTION_LONG, OFFSET_OPEN, price, volume)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def short(self, vtSymbol, price, volume):
|
||||||
|
"""开空"""
|
||||||
|
return self.sendOrder(vtSymbol, DIRECTION_SHORT, OFFSET_OPEN, price, volume)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def sell(self, vtSymbol, price, volume):
|
||||||
|
"""平多"""
|
||||||
|
return self.sendOrder(vtSymbol, DIRECTION_SHORT, OFFSET_CLOSE, price, volume)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def cover(self, vtSymbol, price, volume):
|
||||||
|
"""平空"""
|
||||||
|
return self.sendOrder(vtSymbol, DIRECTION_LONG, OFFSET_CLOSE, price, volume)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def dbQuery(self, collectionName, flt):
|
||||||
|
"""查询数据"""
|
||||||
|
return self.mainEngine.dbQuery(OM_DB_NAME, collectionName, flt)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def dbUpdate(self, collectionName, d, flt):
|
||||||
|
"""更新数据"""
|
||||||
|
self.mainEngine.dbUpdate(OM_DB_NAME, collectionName, d, flt, True)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def getOption(self, vtSymbol):
|
||||||
|
"""获取期权信息"""
|
||||||
|
return self.portfolio.optionDict.get(vtSymbol, None)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def getUnderlying(self, vtSymbol):
|
||||||
|
"""获取标的信息"""
|
||||||
|
return self.portfolio.underlyingDict.get(vtSymbol, None)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def getChain(self, symbol):
|
||||||
|
"""获取期权链信息"""
|
||||||
|
return self.portfolio.chainDict.get(symbol, None)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def getPortfolio(self):
|
||||||
|
"""获取持仓组合信息"""
|
||||||
|
return self.portfolio
|
||||||
|
|
||||||
|
|
||||||
|
106
vnpy/trader/app/optionMaster/omStrategy.py
Normal file
106
vnpy/trader/app/optionMaster/omStrategy.py
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
|
|
||||||
|
from vnpy.trader.vtConstant import (DIRECTION_LONG, DIRECTION_SHORT,
|
||||||
|
OFFSET_OPEN, OFFSET_CLOSE)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class OmStrategyTemplate(object):
|
||||||
|
"""策略模板"""
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self, engine):
|
||||||
|
"""Constructor"""
|
||||||
|
self.engine = engine
|
||||||
|
|
||||||
|
self.name = ''
|
||||||
|
|
||||||
|
self.inited = False
|
||||||
|
self.trading = False
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def onInit(self):
|
||||||
|
"""初始化"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def onStart(self):
|
||||||
|
"""启动"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def onStop(self):
|
||||||
|
"""停止"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def onTick(self, tick):
|
||||||
|
"""行情推送"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def onTrade(self, trade):
|
||||||
|
"""成交推送"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def onOrder(self, order):
|
||||||
|
"""委托推送"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def cancelOrder(self, vtOrderID):
|
||||||
|
"""撤单"""
|
||||||
|
self.engine.cancelOrder(vtOrderID)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def buy(self, vtSymbol, price, volume):
|
||||||
|
"""开多"""
|
||||||
|
return self.engine.buy(vtSymbol, price, volume)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def short(self, vtSymbol, price, volume):
|
||||||
|
"""开空"""
|
||||||
|
return self.engine.short(vtSymbol, price, volume)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def sell(self, vtSymbol, price, volume):
|
||||||
|
"""平多"""
|
||||||
|
return self.engine.sell(vtSymbol, price, volume)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def cover(self, vtSymbol, price, volume):
|
||||||
|
"""平空"""
|
||||||
|
return self.engine.cover(vtSymbol, price, volume)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def dbQuery(self, flt):
|
||||||
|
"""查询数据"""
|
||||||
|
return self.engine.dbQuery(self.name, flt)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def dbUpdate(self, d, flt):
|
||||||
|
"""更新数据"""
|
||||||
|
return self.engine.dbUpdate(self.name, d, flt)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def getOption(self, vtSymbol):
|
||||||
|
"""查询期权数据"""
|
||||||
|
return self.engine.getOption(vtSymbol)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def getUnderlying(self, vtSymbol):
|
||||||
|
"""获取标的信息"""
|
||||||
|
return self.engine.getUnderlying(vtSymbol)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def getChain(self, symbol):
|
||||||
|
"""获取期权链信息"""
|
||||||
|
return self.engine.getChain(symbol)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def getPortfolio(self):
|
||||||
|
"""获取持仓组合信息"""
|
||||||
|
return self.engine.getPortfolio()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user