From a5e972ce5a3b24f9f990c4c21f3c92b0150551cb Mon Sep 17 00:00:00 2001 From: "vn.py" Date: Mon, 2 Jul 2018 17:52:16 +0800 Subject: [PATCH] =?UTF-8?q?[Add]=E6=96=B0=E5=A2=9E=E5=88=B7=E5=8D=95?= =?UTF-8?q?=E7=AE=97=E6=B3=95StAlgo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/CryptoTrader/BIGONE_connect.json | 5 + examples/CryptoTrader/FCOIN_connect.json | 5 + examples/CryptoTrader/run.py | 7 +- vnpy/trader/app/algoTrading/algoEngine.py | 15 +- vnpy/trader/app/algoTrading/stAlgo.py | 170 +++++++++++++++++++ vnpy/trader/app/algoTrading/uiAlgoManager.py | 2 + vnpy/trader/app/riskManager/RM_setting.json | 2 +- 7 files changed, 202 insertions(+), 4 deletions(-) create mode 100644 examples/CryptoTrader/BIGONE_connect.json create mode 100644 examples/CryptoTrader/FCOIN_connect.json create mode 100644 vnpy/trader/app/algoTrading/stAlgo.py diff --git a/examples/CryptoTrader/BIGONE_connect.json b/examples/CryptoTrader/BIGONE_connect.json new file mode 100644 index 00000000..87aab6bd --- /dev/null +++ b/examples/CryptoTrader/BIGONE_connect.json @@ -0,0 +1,5 @@ +{ + "apiKey": "", + "apiSecret": "", + "symbols": ["BTC-USDT", "ETH-USDT", "EOS-USDT"] +} \ No newline at end of file diff --git a/examples/CryptoTrader/FCOIN_connect.json b/examples/CryptoTrader/FCOIN_connect.json new file mode 100644 index 00000000..00d51e2a --- /dev/null +++ b/examples/CryptoTrader/FCOIN_connect.json @@ -0,0 +1,5 @@ +{ + "apiKey": "", + "apiSecret": "", + "symbols": ["ethusdt"] +} \ No newline at end of file diff --git a/examples/CryptoTrader/run.py b/examples/CryptoTrader/run.py index 9088f66e..80ce604d 100644 --- a/examples/CryptoTrader/run.py +++ b/examples/CryptoTrader/run.py @@ -22,7 +22,8 @@ from vnpy.trader.uiMainWindow import MainWindow # 加载底层接口 from vnpy.trader.gateway import (huobiGateway, okexGateway, binanceGateway, bitfinexGateway, - bitmexGateway) + bitmexGateway, fcoinGateway, + bigoneGateway) # 加载上层应用 from vnpy.trader.app import (riskManager, algoTrading) @@ -41,12 +42,14 @@ def main(): me = MainEngine(ee) # 添加交易接口 + me.addGateway(bigoneGateway) + me.addGateway(fcoinGateway) me.addGateway(bitmexGateway) me.addGateway(huobiGateway) me.addGateway(okexGateway) me.addGateway(binanceGateway) me.addGateway(bitfinexGateway) - + # 添加上层应用 me.addApp(riskManager) me.addApp(algoTrading) diff --git a/vnpy/trader/app/algoTrading/algoEngine.py b/vnpy/trader/app/algoTrading/algoEngine.py index f1da8037..68406569 100644 --- a/vnpy/trader/app/algoTrading/algoEngine.py +++ b/vnpy/trader/app/algoTrading/algoEngine.py @@ -16,6 +16,7 @@ from vnpy.trader.vtObject import VtSubscribeReq, VtOrderReq, VtCancelOrderReq, V from .twapAlgo import TwapAlgo from .dmaAlgo import DmaAlgo from .stopAlgo import StopAlgo +from .stAlgo import StAlgo EVENT_ALGO_LOG = 'eAlgoLog' # 算法日志事件 EVENT_ALGO_PARAM = 'eAlgoParam' # 算法参数事件 @@ -32,7 +33,8 @@ HISTORY_COLLECTION_NAME = 'AlgoHistory' # 算法历史集合名 ALGO_DICT = { TwapAlgo.templateName: TwapAlgo, DmaAlgo.templateName: DmaAlgo, - StopAlgo.templateName: StopAlgo + StopAlgo.templateName: StopAlgo, + StAlgo.templateName: StAlgo } @@ -274,6 +276,17 @@ class AlgoEngine(object): return tick + #---------------------------------------------------------------------- + def getContract(self, algo, vtSymbol): + """查询合约""" + contract = self.mainEngine.getContract(vtSymbol) + if not contract: + self.writeLog(u'%s查询合约失败,找不到报价:%s' %(algo.algoName, vtSymbol)) + return + + return contract + + #---------------------------------------------------------------------- def saveAlgoSetting(self, algoSetting): """保存算法配置""" diff --git a/vnpy/trader/app/algoTrading/stAlgo.py b/vnpy/trader/app/algoTrading/stAlgo.py new file mode 100644 index 00000000..9d0d6893 --- /dev/null +++ b/vnpy/trader/app/algoTrading/stAlgo.py @@ -0,0 +1,170 @@ +# 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 StAlgo(AlgoTemplate): + """自成交算法(self trade),用于刷成交量""" + + templateName = 'ST' + + #---------------------------------------------------------------------- + def __init__(self, engine, setting, algoName): + """Constructor""" + super(StAlgo, self).__init__(engine, setting, algoName) + + # 参数,强制类型转换,保证从CSV加载的配置正确 + self.vtSymbol = str(setting['vtSymbol']) # 合约代码 + self.orderVolume = float(setting['orderVolume']) # 委托数量 + self.interval = int(setting['interval']) # 运行间隔 + self.minTickSpread = int(setting['minTickSpread']) # 最小价差 + + self.count = 0 # 定时计数 + self.tradedVolume = 0 # 总成交数量 + + self.subscribe(self.vtSymbol) + self.paramEvent() + self.varEvent() + + #---------------------------------------------------------------------- + def onTick(self, tick): + """""" + pass + + #---------------------------------------------------------------------- + def onTrade(self, trade): + """""" + self.tradedVolume += trade.volume + self.varEvent() + + #---------------------------------------------------------------------- + def onOrder(self, order): + """""" + pass + + #---------------------------------------------------------------------- + def onTimer(self): + """""" + self.count += 1 + if self.count == self.interval: + self.count = 0 + + # 全撤委托 + self.cancelAll() + + # 获取行情 + tick = self.getTick(self.vtSymbol) + if not tick: + return + + contract = self.getContract(self.vtSymbol) + if not contract: + return + + tickSpread = (tick.askPrice1 - tick.bidPrice1) / contract.priceTick + if tickSpread < self.minTickSpread: + self.writeLog(u'当前价差为%s个Tick,小于算法设置%s,不执行刷单' %(tickSpread, self.minTickSpread)) + return + + midPrice = tick.bidPrice1 + contract.priceTick * int(tickSpread/2) + + self.buy(self.vtSymbol, midPrice, self.orderVolume) + self.sell(self.vtSymbol, midPrice, self.orderVolume) + + self.writeLog(u'发出刷单买卖委托,价格:%s,数量:%s' %(midPrice, self.orderVolume)) + + self.varEvent() + + #---------------------------------------------------------------------- + def onStop(self): + """""" + self.writeLog(u'停止算法') + self.varEvent() + + #---------------------------------------------------------------------- + def varEvent(self): + """更新变量""" + d = OrderedDict() + d[u'算法状态'] = self.active + d[u'成交数量'] = self.tradedVolume + d[u'定时计数'] = self.count + d['active'] = self.active + self.putVarEvent(d) + + #---------------------------------------------------------------------- + def paramEvent(self): + """更新参数""" + d = OrderedDict() + d[u'代码'] = self.vtSymbol + d[u'单次委托数量'] = self.orderVolume + d[u'执行间隔'] = self.interval + d[u'最小价差Tick'] = self.minTickSpread + self.putParamEvent(d) + + +######################################################################## +class StWidget(AlgoWidget): + """""" + + #---------------------------------------------------------------------- + def __init__(self, algoEngine, parent=None): + """Constructor""" + super(StWidget, self).__init__(algoEngine, parent) + + self.templateName = StAlgo.templateName + + #---------------------------------------------------------------------- + def initAlgoLayout(self): + """""" + self.lineSymbol = QtWidgets.QLineEdit() + + self.spinVolume = QtWidgets.QDoubleSpinBox() + self.spinVolume.setMinimum(0) + self.spinVolume.setMaximum(1000000000) + self.spinVolume.setDecimals(6) + + self.spinInterval = QtWidgets.QSpinBox() + self.spinInterval.setMinimum(20) + self.spinInterval.setMaximum(3600) + + self.spinMinTickSpread = QtWidgets.QSpinBox() + self.spinMinTickSpread.setMinimum(0) + self.spinMinTickSpread.setMaximum(1000) + + 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.spinVolume, 1, 1) + grid.addWidget(Label(u'执行间隔'), 2, 0) + grid.addWidget(self.spinInterval, 2, 1) + grid.addWidget(Label(u'最小价差Tick'), 3, 0) + grid.addWidget(self.spinMinTickSpread, 3, 1) + + return grid + + #---------------------------------------------------------------------- + def getAlgoSetting(self): + """""" + setting = OrderedDict() + setting['templateName'] = StAlgo.templateName + setting['vtSymbol'] = str(self.lineSymbol.text()) + setting['orderVolume'] = float(self.spinVolume.value()) + setting['interval'] = int(self.spinInterval.value()) + setting['minTickSpread'] = int(self.spinMinTickSpread.value()) + + return setting + + \ No newline at end of file diff --git a/vnpy/trader/app/algoTrading/uiAlgoManager.py b/vnpy/trader/app/algoTrading/uiAlgoManager.py index 59aec40c..62f656de 100644 --- a/vnpy/trader/app/algoTrading/uiAlgoManager.py +++ b/vnpy/trader/app/algoTrading/uiAlgoManager.py @@ -15,6 +15,7 @@ from .algoEngine import (EVENT_ALGO_LOG, EVENT_ALGO_PARAM, from .twapAlgo import TwapWidget from .dmaAlgo import DmaWidget from .stopAlgo import StopWidget +from .stAlgo import StWidget ######################################################################## @@ -393,6 +394,7 @@ class AlgoManager(QtWidgets.QWidget): self.addAlgoWidget(TwapWidget) self.addAlgoWidget(DmaWidget) self.addAlgoWidget(StopWidget) + self.addAlgoWidget(StWidget) self.algoEngine.loadAlgoSetting() # 界面初始化后,再加载算法配置 diff --git a/vnpy/trader/app/riskManager/RM_setting.json b/vnpy/trader/app/riskManager/RM_setting.json index 6dc35464..d34f89d0 100644 --- a/vnpy/trader/app/riskManager/RM_setting.json +++ b/vnpy/trader/app/riskManager/RM_setting.json @@ -5,6 +5,6 @@ "workingOrderLimit": 20, "tradeLimit": 1000, "orderSizeLimit": 100, - "active": true, + "active": false, "orderFlowLimit": 50 } \ No newline at end of file