[Add]新增停止单算法StopAlgo
This commit is contained in:
parent
70092a628f
commit
584990a7ed
@ -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):
|
||||||
|
@ -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)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
206
vnpy/trader/app/algoTrading/stopAlgo.py
Normal file
206
vnpy/trader/app/algoTrading/stopAlgo.py
Normal 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
|
||||||
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
@ -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() # 界面初始化后,再加载算法配置
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user