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.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:
|
||||||
@ -158,23 +160,33 @@ class AlgoEngine(object):
|
|||||||
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):
|
||||||
|
@ -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):
|
||||||
|
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.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)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
@ -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() # 界面初始化后,再加载算法配置
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user