Merge branch 'dev' of https://github.com/vnpy/vnpy into dev

This commit is contained in:
vn.py 2018-06-11 22:18:47 +08:00
commit d4aa4f6e4d
5 changed files with 219 additions and 14 deletions

View File

@ -7,13 +7,14 @@ from __future__ import division
from vnpy.event import Event from vnpy.event import Event
from vnpy.trader.vtEvent import EVENT_TIMER, EVENT_TICK, EVENT_ORDER, EVENT_TRADE from vnpy.trader.vtEvent import EVENT_TIMER, EVENT_TICK, EVENT_ORDER, EVENT_TRADE
from vnpy.trader.vtConstant import (DIRECTION_LONG, DIRECTION_SHORT, PRICETYPE_LIMITPRICE, from vnpy.trader.vtConstant import (DIRECTION_LONG, DIRECTION_SHORT,
PRICETYPE_LIMITPRICE, PRICETYPE_MARKETPRICE,
OFFSET_OPEN, OFFSET_CLOSE, OFFSET_OPEN, OFFSET_CLOSE,
OFFSET_CLOSETODAY, OFFSET_CLOSEYESTERDAY) OFFSET_CLOSETODAY, OFFSET_CLOSEYESTERDAY)
from vnpy.trader.vtObject import VtSubscribeReq, VtOrderReq, VtCancelOrderReq, VtLogData from vnpy.trader.vtObject import VtSubscribeReq, VtOrderReq, VtCancelOrderReq, VtLogData
from .twapAlgo import TwapAlgo from .twapAlgo import TwapAlgo
from .dmaAlgo import DmaAlgo
EVENT_ALGO_LOG = 'eAlgoLog' # 算法日志事件 EVENT_ALGO_LOG = 'eAlgoLog' # 算法日志事件
EVENT_ALGO_PARAM = 'eAlgoParam' # 算法参数事件 EVENT_ALGO_PARAM = 'eAlgoParam' # 算法参数事件
@ -147,7 +148,8 @@ class AlgoEngine(object):
self.mainEngine.subscribe(req, contract.gatewayName) self.mainEngine.subscribe(req, contract.gatewayName)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def sendOrder(self, algo, vtSymbol, direction, price, volume): def sendOrder(self, algo, vtSymbol, direction, price, volume,
priceType=None, offset=None):
"""发单""" """发单"""
contract = self.mainEngine.getContract(vtSymbol) contract = self.mainEngine.getContract(vtSymbol)
if not contract: if not contract:
@ -157,24 +159,34 @@ class AlgoEngine(object):
req.vtSymbol = vtSymbol req.vtSymbol = vtSymbol
req.symbol = contract.symbol req.symbol = contract.symbol
req.exchange = contract.exchange req.exchange = contract.exchange
req.direction = direction req.direction = direction
req.priceType = PRICETYPE_LIMITPRICE
req.offset = OFFSET_CLOSETODAY req.offset = OFFSET_CLOSETODAY
req.price = price req.price = price
req.volume = volume req.volume = volume
if priceType:
req.priceType = priceType
else:
req.priceType = PRICETYPE_LIMITPRICE
if offset:
req.offset = offset
else:
req.offset = OFFSET_OPEN
vtOrderID = self.mainEngine.sendOrder(req, contract.gatewayName) vtOrderID = self.mainEngine.sendOrder(req, contract.gatewayName)
return vtOrderID return vtOrderID
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def buy(self, algo, vtSymbol, price, volume): def buy(self, algo, vtSymbol, price, volume, priceType=None, offset=None):
"""买入""" """买入"""
return self.sendOrder(algo, vtSymbol, DIRECTION_LONG, price, volume) return self.sendOrder(algo, vtSymbol, DIRECTION_LONG, price, volume, priceType, offset)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def sell(self, algo, vtSymbol, price, volume): def sell(self, algo, vtSymbol, price, volume, priceType=None, offset=None):
"""卖出""" """卖出"""
return self.sendOrder(algo, vtSymbol, DIRECTION_SHORT, price, volume) return self.sendOrder(algo, vtSymbol, DIRECTION_SHORT, price, volume, priceType, offset)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def cancelOrder(self, algo, vtOrderID): def cancelOrder(self, algo, vtOrderID):

View File

@ -119,14 +119,14 @@ class AlgoTemplate(object):
self.engine.subscribe(self, vtSymbol) self.engine.subscribe(self, vtSymbol)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def buy(self, vtSymbol, price, volume): def buy(self, vtSymbol, price, volume, priceType=None, offset=None):
"""""" """"""
return self.engine.buy(self, vtSymbol, price, volume) return self.engine.buy(self, vtSymbol, price, volume, priceType, offset)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def sell(self, vtSymbol, price, volume): def sell(self, vtSymbol, price, volume, priceType=None, offset=None):
"""""" """"""
return self.engine.sell(self, vtSymbol, price, volume) return self.engine.sell(self, vtSymbol, price, volume, priceType, offset)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def cancelOrder(self, vtOrderID): def cancelOrder(self, vtOrderID):

View File

@ -0,0 +1,192 @@
# encoding: UTF-8
from __future__ import division
from collections import OrderedDict
from vnpy.trader.vtConstant import (DIRECTION_LONG, DIRECTION_SHORT,
OFFSET_OPEN, OFFSET_CLOSE,
PRICETYPE_LIMITPRICE, PRICETYPE_MARKETPRICE,
STATUS_REJECTED, STATUS_CANCELLED, STATUS_ALLTRADED)
from vnpy.trader.uiQt import QtWidgets
from .algoTemplate import AlgoTemplate
from .uiAlgoWidget import AlgoWidget, QtWidgets
STATUS_FINISHED = set([STATUS_ALLTRADED, STATUS_CANCELLED, STATUS_REJECTED])
########################################################################
class DmaAlgo(AlgoTemplate):
"""DMA算法直接发出限价或者市价委托"""
templateName = 'DMA'
#----------------------------------------------------------------------
def __init__(self, engine, setting, algoName):
"""Constructor"""
super(DmaAlgo, self).__init__(engine, setting, algoName)
# 参数强制类型转换保证从CSV加载的配置正确
self.vtSymbol = str(setting['vtSymbol']) # 合约代码
self.direction = unicode(setting['direction']) # 买卖
self.offset = float(setting['offset']) # 开平
self.priceType = float(setting['priceType']) # 价格类型
self.price = float(setting['price']) # 价格
self.totalVolume = int(setting['totalVolume']) # 数量
self.vtOrderID = '' # 委托号
self.tradedVolume = 0 # 成交数量
self.orderStatus = '' # 委托状态
self.subscribe(self.vtSymbol)
self.paramEvent()
self.varEvent()
#----------------------------------------------------------------------
def onTick(self, tick):
""""""
# 发出委托
if not self.vtOrderID:
if self.direction == DIRECTION_LONG:
func = self.buy
else:
func = self.sell
self.vtOrderID = func(self.vtSymbol, self.price, self.volume,
self.priceType, self.offset)
# 更新变量
self.varEvent()
#----------------------------------------------------------------------
def onTrade(self, trade):
""""""
pass
#----------------------------------------------------------------------
def onOrder(self, order):
""""""
self.tradedVolume = order.tradedVolume
self.orderStatus = order.status
if self.orderStatus in STATUS_FINISHED:
self.stop()
self.paramEvent()
#----------------------------------------------------------------------
def onTimer(self):
""""""
pass
#----------------------------------------------------------------------
def onStop(self):
""""""
if self.orderStatus not in STATUS_FINISHED:
self.cancelAll()
# 处理这里的逻辑,区分用户停止和到期停止
self.writeLog(u'委托已%s,停止算法' %self.status)
#----------------------------------------------------------------------
def varEvent(self):
"""更新变量"""
d = OrderedDict()
d[u'算法状态'] = self.active
d[u'委托号'] = self.vtOrderID
d[u'成交数量'] = self.tradedVolume
d[u'委托状态'] = self.orderStatus
self.putVarEvent(d)
#----------------------------------------------------------------------
def paramEvent(self):
"""更新参数"""
d = OrderedDict()
d[u'代码'] = self.vtSymbol
d[u'方向'] = self.direction
d[u'价格'] = self.price
d[u'数量'] = self.totalVolume
d[u'价格类型'] = self.priceType
d[u'开平'] = self.offset
self.putParamEvent(d)
########################################################################
class DmaWidget(AlgoWidget):
""""""
#----------------------------------------------------------------------
def __init__(self, algoEngine, parent=None):
"""Constructor"""
super(DmaWidget, self).__init__(algoEngine, parent)
self.templateName = DmaAlgo.templateName
#----------------------------------------------------------------------
def initAlgoLayout(self):
""""""
self.lineSymbol = QtWidgets.QLineEdit()
self.comboDirection = QtWidgets.QComboBox()
self.comboDirection.addItem(DIRECTION_LONG)
self.comboDirection.addItem(DIRECTION_SHORT)
self.comboDirection.setCurrentIndex(0)
self.spinPrice = QtWidgets.QDoubleSpinBox()
self.spinPrice.setMinimum(0)
self.spinPrice.setMaximum(1000000000)
self.spinPrice.setDecimals(8)
self.spinVolume = QtWidgets.QDoubleSpinBox()
self.spinVolume.setMinimum(0)
self.spinVolume.setMaximum(1000000000)
self.spinVolume.setDecimals(6)
self.comboPriceType = QtWidgets.QComboBox()
self.comboPriceType.addItems([PRICETYPE_LIMITPRICE, PRICETYPE_MARKETPRICE])
self.comboPriceType.setCurrentIndex(0)
self.comboOffset = QtWidgets.QComboBox()
self.comboOffset.addItems(['', OFFSET_OPEN, OFFSET_CLOSE])
self.comboOffset.setCurrentIndex(0)
buttonStart = QtWidgets.QPushButton(u'启动')
buttonStart.clicked.connect(self.addAlgo)
buttonStart.setMinimumHeight(100)
Label = QtWidgets.QLabel
grid = QtWidgets.QGridLayout()
grid.addWidget(Label(u'代码'), 0, 0)
grid.addWidget(self.lineSymbol, 0, 1)
grid.addWidget(Label(u'方向'), 1, 0)
grid.addWidget(self.comboDirection, 1, 1)
grid.addWidget(Label(u'价格'), 2, 0)
grid.addWidget(self.spinPrice, 2, 1)
grid.addWidget(Label(u'数量'), 3, 0)
grid.addWidget(self.spinVolume, 3, 1)
grid.addWidget(Label(u'类型'), 4, 0)
grid.addWidget(self.comboPriceType, 4, 1)
grid.addWidget(Label(u'开平'), 5, 0)
grid.addWidget(self.comboOffset, 5, 1)
return grid
#----------------------------------------------------------------------
def getAlgoSetting(self):
""""""
setting = OrderedDict()
setting['templateName'] = DmaAlgo.templateName
setting['vtSymbol'] = str(self.lineSymbol.text())
setting['direction'] = unicode(self.comboDirection.currentText())
setting['price'] = float(self.spinPrice.value())
setting['totalVolume'] = float(self.spinVolume.value())
setting['priceType'] = unicode(self.comboPriceType.currentText())
setting['offset'] = unicode(self.comboOffset.currentText())
return setting

View File

@ -152,7 +152,6 @@ class TwapAlgo(AlgoTemplate):
d[u'单笔委托'] = self.orderSize d[u'单笔委托'] = self.orderSize
d[u'本轮读秒'] = self.timerCount d[u'本轮读秒'] = self.timerCount
d[u'累计读秒'] = self.timerTotal d[u'累计读秒'] = self.timerTotal
d['active'] = self.active
self.putVarEvent(d) self.putVarEvent(d)
#---------------------------------------------------------------------- #----------------------------------------------------------------------

View File

@ -10,6 +10,7 @@ from vnpy.trader.uiQt import QtCore, QtWidgets
from .algoEngine import (EVENT_ALGO_LOG, EVENT_ALGO_PARAM, from .algoEngine import (EVENT_ALGO_LOG, EVENT_ALGO_PARAM,
EVENT_ALGO_VAR, EVENT_ALGO_SETTING) EVENT_ALGO_VAR, EVENT_ALGO_SETTING)
from .twapAlgo import TwapWidget from .twapAlgo import TwapWidget
from .dmaAlgo import DmaWidget
######################################################################## ########################################################################
@ -386,6 +387,7 @@ class AlgoManager(QtWidgets.QWidget):
self.initUi() self.initUi()
self.addAlgoWidget(TwapWidget) self.addAlgoWidget(TwapWidget)
self.addAlgoWidget(DmaWidget)
self.algoEngine.loadAlgoSetting() # 界面初始化后,再加载算法配置 self.algoEngine.loadAlgoSetting() # 界面初始化后,再加载算法配置