Merge branch 'dev' of https://github.com/vnpy/vnpy into dev
This commit is contained in:
commit
d4aa4f6e4d
@ -7,13 +7,14 @@ from __future__ import division
|
||||
|
||||
from vnpy.event import Event
|
||||
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_CLOSETODAY, OFFSET_CLOSEYESTERDAY)
|
||||
from vnpy.trader.vtObject import VtSubscribeReq, VtOrderReq, VtCancelOrderReq, VtLogData
|
||||
|
||||
from .twapAlgo import TwapAlgo
|
||||
|
||||
from .dmaAlgo import DmaAlgo
|
||||
|
||||
EVENT_ALGO_LOG = 'eAlgoLog' # 算法日志事件
|
||||
EVENT_ALGO_PARAM = 'eAlgoParam' # 算法参数事件
|
||||
@ -147,7 +148,8 @@ class AlgoEngine(object):
|
||||
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)
|
||||
if not contract:
|
||||
@ -157,24 +159,34 @@ class AlgoEngine(object):
|
||||
req.vtSymbol = vtSymbol
|
||||
req.symbol = contract.symbol
|
||||
req.exchange = contract.exchange
|
||||
req.direction = direction
|
||||
req.priceType = PRICETYPE_LIMITPRICE
|
||||
req.direction = direction
|
||||
req.offset = OFFSET_CLOSETODAY
|
||||
req.price = price
|
||||
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)
|
||||
|
||||
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):
|
||||
|
@ -119,14 +119,14 @@ class AlgoTemplate(object):
|
||||
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):
|
||||
|
192
vnpy/trader/app/algoTrading/dmaAlgo.py
Normal file
192
vnpy/trader/app/algoTrading/dmaAlgo.py
Normal 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
|
||||
|
||||
|
@ -152,7 +152,6 @@ class TwapAlgo(AlgoTemplate):
|
||||
d[u'单笔委托'] = self.orderSize
|
||||
d[u'本轮读秒'] = self.timerCount
|
||||
d[u'累计读秒'] = self.timerTotal
|
||||
d['active'] = self.active
|
||||
self.putVarEvent(d)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
@ -10,6 +10,7 @@ from vnpy.trader.uiQt import QtCore, QtWidgets
|
||||
from .algoEngine import (EVENT_ALGO_LOG, EVENT_ALGO_PARAM,
|
||||
EVENT_ALGO_VAR, EVENT_ALGO_SETTING)
|
||||
from .twapAlgo import TwapWidget
|
||||
from .dmaAlgo import DmaWidget
|
||||
|
||||
|
||||
########################################################################
|
||||
@ -386,6 +387,7 @@ class AlgoManager(QtWidgets.QWidget):
|
||||
|
||||
self.initUi()
|
||||
self.addAlgoWidget(TwapWidget)
|
||||
self.addAlgoWidget(DmaWidget)
|
||||
|
||||
self.algoEngine.loadAlgoSetting() # 界面初始化后,再加载算法配置
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user