[Add]新增停止单算法StopAlgo

This commit is contained in:
vn.py 2018-06-11 23:26:53 +08:00
parent 70092a628f
commit 584990a7ed
5 changed files with 224 additions and 13 deletions

View File

@ -15,6 +15,7 @@ from vnpy.trader.vtObject import VtSubscribeReq, VtOrderReq, VtCancelOrderReq, V
from .twapAlgo import TwapAlgo from .twapAlgo import TwapAlgo
from .dmaAlgo import DmaAlgo from .dmaAlgo import DmaAlgo
from .stopAlgo import StopAlgo
EVENT_ALGO_LOG = 'eAlgoLog' # 算法日志事件 EVENT_ALGO_LOG = 'eAlgoLog' # 算法日志事件
EVENT_ALGO_PARAM = 'eAlgoParam' # 算法参数事件 EVENT_ALGO_PARAM = 'eAlgoParam' # 算法参数事件
@ -29,7 +30,9 @@ HISTORY_COLLECTION_NAME = 'AlgoHistory' # 算法历史集合名
ALGO_DICT = { ALGO_DICT = {
TwapAlgo.templateName: TwapAlgo TwapAlgo.templateName: TwapAlgo,
DmaAlgo.templateName: DmaAlgo,
StopAlgo.templateName: StopAlgo
} }
@ -113,8 +116,9 @@ class AlgoEngine(object):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def stopAlgo(self, algoName): def stopAlgo(self, algoName):
"""停止算法""" """停止算法"""
self.algoDict[algoName].stop() if algoName in self.algoDict:
del self.algoDict[algoName] self.algoDict[algoName].stop()
del self.algoDict[algoName]
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def stopAll(self): def stopAll(self):

View File

@ -31,10 +31,10 @@ class DmaAlgo(AlgoTemplate):
# 参数强制类型转换保证从CSV加载的配置正确 # 参数强制类型转换保证从CSV加载的配置正确
self.vtSymbol = str(setting['vtSymbol']) # 合约代码 self.vtSymbol = str(setting['vtSymbol']) # 合约代码
self.direction = unicode(setting['direction']) # 买卖 self.direction = unicode(setting['direction']) # 买卖
self.offset = float(setting['offset']) # 开平 self.offset = unicode(setting['offset']) # 开平
self.priceType = float(setting['priceType']) # 价格类型 self.priceType = unicode(setting['priceType']) # 价格类型
self.price = float(setting['price']) # 价格 self.price = float(setting['price']) # 价格
self.totalVolume = int(setting['totalVolume']) # 数量 self.totalVolume = float(setting['totalVolume']) # 数量
self.vtOrderID = '' # 委托号 self.vtOrderID = '' # 委托号
self.tradedVolume = 0 # 成交数量 self.tradedVolume = 0 # 成交数量
@ -74,7 +74,7 @@ class DmaAlgo(AlgoTemplate):
if self.orderStatus in STATUS_FINISHED: if self.orderStatus in STATUS_FINISHED:
self.stop() self.stop()
self.paramEvent() self.varEvent()
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def onTimer(self): def onTimer(self):
@ -84,12 +84,8 @@ class DmaAlgo(AlgoTemplate):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def onStop(self): def onStop(self):
"""""" """"""
if self.orderStatus not in STATUS_FINISHED: self.writeLog(u'停止算法')
self.cancelAll() self.varEvent()
# 处理这里的逻辑,区分用户停止和到期停止
self.writeLog(u'委托已%s,停止算法' %self.status)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def varEvent(self): def varEvent(self):
@ -99,6 +95,7 @@ class DmaAlgo(AlgoTemplate):
d[u'委托号'] = self.vtOrderID d[u'委托号'] = self.vtOrderID
d[u'成交数量'] = self.tradedVolume d[u'成交数量'] = self.tradedVolume
d[u'委托状态'] = self.orderStatus d[u'委托状态'] = self.orderStatus
d['active'] = self.active
self.putVarEvent(d) self.putVarEvent(d)
#---------------------------------------------------------------------- #----------------------------------------------------------------------

View File

@ -0,0 +1,206 @@
# encoding: UTF-8
from __future__ import division
from collections import OrderedDict
from vnpy.trader.vtConstant import (DIRECTION_LONG, DIRECTION_SHORT,
OFFSET_OPEN, OFFSET_CLOSE)
from vnpy.trader.uiQt import QtWidgets
from .algoTemplate import AlgoTemplate
from .uiAlgoWidget import AlgoWidget, QtWidgets
########################################################################
class StopAlgo(AlgoTemplate):
"""停止单算法,也可以用于止损单"""
templateName = 'STOP'
#----------------------------------------------------------------------
def __init__(self, engine, setting, algoName):
"""Constructor"""
super(StopAlgo, self).__init__(engine, setting, algoName)
# 参数强制类型转换保证从CSV加载的配置正确
self.vtSymbol = str(setting['vtSymbol']) # 合约代码
self.direction = unicode(setting['direction']) # 买卖
self.stopPrice = float(setting['stopPrice']) # 触发价格
self.totalVolume = float(setting['totalVolume']) # 数量
self.offset = unicode(setting['offset']) # 开平
self.priceAdd = float(setting['priceAdd']) # 下单时的超价
self.vtOrderID = '' # 委托号
self.tradedVolume = 0 # 成交数量
self.orderStatus = '' # 委托状态
self.subscribe(self.vtSymbol)
self.paramEvent()
self.varEvent()
#----------------------------------------------------------------------
def onTick(self, tick):
""""""
# 如果已经发出委托,则忽略行情事件
if self.vtOrderID:
return
# 如果到达止损位,才触发委托
if (self.direction == DIRECTION_LONG and
tick.lastPrice >= self.price):
# 计算超价委托价格
price = self.stopPrice + self.priceAdd
# 避免价格超过涨停价
if tick.upperLimit:
price = min(price, tick.upperLimit)
func = self.buy
else:
price = self.stopPrice - self.priceAdd
if tick.lowerLimit:
price = max(price, tick.lowerLimit)
func = self.sell
self.vtOrderID = func(self.vtSymbol, price, self.volume, offset=self.offset)
msg = u'停止单已触发,代码:%s,方向:%s, 价格:%s,数量:%s,开平:%s' %(self.vtSymbol,
self.direction,
self.stopPrice,
self.totalVolume,
self.offset)
self.writeLog(msg)
# 更新变量
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.varEvent()
#----------------------------------------------------------------------
def onTimer(self):
""""""
pass
#----------------------------------------------------------------------
def onStop(self):
""""""
self.writeLog(u'停止算法')
self.varEvent()
#----------------------------------------------------------------------
def varEvent(self):
"""更新变量"""
d = OrderedDict()
d[u'算法状态'] = self.active
d[u'委托号'] = self.vtOrderID
d[u'成交数量'] = self.tradedVolume
d[u'委托状态'] = self.orderStatus
d['active'] = self.active
self.putVarEvent(d)
#----------------------------------------------------------------------
def paramEvent(self):
"""更新参数"""
d = OrderedDict()
d[u'代码'] = self.vtSymbol
d[u'方向'] = self.direction
d[u'触发价格'] = self.stopPrice
d[u'数量'] = self.totalVolume
d[u'开平'] = self.offset
self.putParamEvent(d)
########################################################################
class StopWidget(AlgoWidget):
""""""
#----------------------------------------------------------------------
def __init__(self, algoEngine, parent=None):
"""Constructor"""
super(StopWidget, self).__init__(algoEngine, parent)
self.templateName = StopAlgo.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.comboOffset = QtWidgets.QComboBox()
self.comboOffset.addItems(['', OFFSET_OPEN, OFFSET_CLOSE])
self.comboOffset.setCurrentIndex(0)
self.spinPriceAdd = QtWidgets.QDoubleSpinBox()
self.spinPriceAdd.setMinimum(0)
self.spinPriceAdd.setMaximum(1000000000)
self.spinPriceAdd.setDecimals(8)
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.comboOffset, 4, 1)
grid.addWidget(Label(u'超价'), 5, 0)
grid.addWidget(self.spinPriceAdd, 5, 1)
return grid
#----------------------------------------------------------------------
def getAlgoSetting(self):
""""""
setting = OrderedDict()
setting['templateName'] = StopAlgo.templateName
setting['vtSymbol'] = str(self.lineSymbol.text())
setting['direction'] = unicode(self.comboDirection.currentText())
setting['stopPrice'] = float(self.spinPrice.value())
setting['totalVolume'] = float(self.spinVolume.value())
setting['offset'] = unicode(self.comboOffset.currentText())
setting['priceAdd'] = float(self.spinPriceAdd.value())
return setting

View File

@ -152,6 +152,7 @@ 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

@ -9,8 +9,10 @@ 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 from .dmaAlgo import DmaWidget
from .stopAlgo import StopWidget
######################################################################## ########################################################################
@ -388,6 +390,7 @@ class AlgoManager(QtWidgets.QWidget):
self.initUi() self.initUi()
self.addAlgoWidget(TwapWidget) self.addAlgoWidget(TwapWidget)
self.addAlgoWidget(DmaWidget) self.addAlgoWidget(DmaWidget)
self.addAlgoWidget(StopWidget)
self.algoEngine.loadAlgoSetting() # 界面初始化后,再加载算法配置 self.algoEngine.loadAlgoSetting() # 界面初始化后,再加载算法配置