[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 .dmaAlgo import DmaAlgo
|
||||
from .stopAlgo import StopAlgo
|
||||
|
||||
EVENT_ALGO_LOG = 'eAlgoLog' # 算法日志事件
|
||||
EVENT_ALGO_PARAM = 'eAlgoParam' # 算法参数事件
|
||||
@ -29,7 +30,9 @@ HISTORY_COLLECTION_NAME = 'AlgoHistory' # 算法历史集合名
|
||||
|
||||
|
||||
ALGO_DICT = {
|
||||
TwapAlgo.templateName: TwapAlgo
|
||||
TwapAlgo.templateName: TwapAlgo,
|
||||
DmaAlgo.templateName: DmaAlgo,
|
||||
StopAlgo.templateName: StopAlgo
|
||||
}
|
||||
|
||||
|
||||
@ -113,6 +116,7 @@ class AlgoEngine(object):
|
||||
#----------------------------------------------------------------------
|
||||
def stopAlgo(self, algoName):
|
||||
"""停止算法"""
|
||||
if algoName in self.algoDict:
|
||||
self.algoDict[algoName].stop()
|
||||
del self.algoDict[algoName]
|
||||
|
||||
|
@ -31,10 +31,10 @@ class DmaAlgo(AlgoTemplate):
|
||||
# 参数,强制类型转换,保证从CSV加载的配置正确
|
||||
self.vtSymbol = str(setting['vtSymbol']) # 合约代码
|
||||
self.direction = unicode(setting['direction']) # 买卖
|
||||
self.offset = float(setting['offset']) # 开平
|
||||
self.priceType = float(setting['priceType']) # 价格类型
|
||||
self.offset = unicode(setting['offset']) # 开平
|
||||
self.priceType = unicode(setting['priceType']) # 价格类型
|
||||
self.price = float(setting['price']) # 价格
|
||||
self.totalVolume = int(setting['totalVolume']) # 数量
|
||||
self.totalVolume = float(setting['totalVolume']) # 数量
|
||||
|
||||
self.vtOrderID = '' # 委托号
|
||||
self.tradedVolume = 0 # 成交数量
|
||||
@ -74,7 +74,7 @@ class DmaAlgo(AlgoTemplate):
|
||||
if self.orderStatus in STATUS_FINISHED:
|
||||
self.stop()
|
||||
|
||||
self.paramEvent()
|
||||
self.varEvent()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def onTimer(self):
|
||||
@ -84,12 +84,8 @@ class DmaAlgo(AlgoTemplate):
|
||||
#----------------------------------------------------------------------
|
||||
def onStop(self):
|
||||
""""""
|
||||
if self.orderStatus not in STATUS_FINISHED:
|
||||
self.cancelAll()
|
||||
|
||||
# 处理这里的逻辑,区分用户停止和到期停止
|
||||
|
||||
self.writeLog(u'委托已%s,停止算法' %self.status)
|
||||
self.writeLog(u'停止算法')
|
||||
self.varEvent()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def varEvent(self):
|
||||
@ -99,6 +95,7 @@ class DmaAlgo(AlgoTemplate):
|
||||
d[u'委托号'] = self.vtOrderID
|
||||
d[u'成交数量'] = self.tradedVolume
|
||||
d[u'委托状态'] = self.orderStatus
|
||||
d['active'] = self.active
|
||||
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.timerCount
|
||||
d[u'累计读秒'] = self.timerTotal
|
||||
d['active'] = self.active
|
||||
self.putVarEvent(d)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
@ -9,8 +9,10 @@ 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
|
||||
from .stopAlgo import StopWidget
|
||||
|
||||
|
||||
########################################################################
|
||||
@ -388,6 +390,7 @@ class AlgoManager(QtWidgets.QWidget):
|
||||
self.initUi()
|
||||
self.addAlgoWidget(TwapWidget)
|
||||
self.addAlgoWidget(DmaWidget)
|
||||
self.addAlgoWidget(StopWidget)
|
||||
|
||||
self.algoEngine.loadAlgoSetting() # 界面初始化后,再加载算法配置
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user