From 7ece16c9146467493af7fcd2544951fd197218d3 Mon Sep 17 00:00:00 2001 From: nanoric Date: Tue, 30 Oct 2018 23:44:27 -0400 Subject: [PATCH] =?UTF-8?q?[Fix]=20bitmexGateway:=20=E5=BD=93=E4=B8=8B?= =?UTF-8?q?=E5=8D=95=E3=80=81=E6=92=A4=E5=8D=95=E8=A7=A6=E5=8F=91=E5=B7=B2?= =?UTF-8?q?=E7=9F=A5=E9=94=99=E8=AF=AF=E7=9A=84=E6=97=B6=E5=80=99=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E5=93=8D=E5=BA=94=E9=BB=98=E8=AE=A4onError=E6=88=96?= =?UTF-8?q?=E8=80=85onFailed=20[Mod]=20BitmexRestApi.onError:=E9=99=A4?= =?UTF-8?q?=E4=BA=86=E6=8E=A8=E9=80=81=E9=94=99=E8=AF=AF=E5=88=B0=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E5=BC=95=E6=93=8E=E4=B9=8B=E5=A4=96=EF=BC=8C=E8=BF=98?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=96=B0=E7=9A=84exceptionDetail=E5=9C=A8?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=8F=B0=E6=89=93=E5=8D=B0=E8=AF=A6=E7=BB=86?= =?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=E6=B6=88=E6=81=AF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 目前已知的错误只有网络错误。若下单时发生网络错误,该订单状态会被设置为rejected. --- .../gateway/bitmexGateway/bitmexGateway.py | 78 ++++++++++++++++--- 1 file changed, 67 insertions(+), 11 deletions(-) diff --git a/vnpy/trader/gateway/bitmexGateway/bitmexGateway.py b/vnpy/trader/gateway/bitmexGateway/bitmexGateway.py index 0df8d238..95745adb 100644 --- a/vnpy/trader/gateway/bitmexGateway/bitmexGateway.py +++ b/vnpy/trader/gateway/bitmexGateway/bitmexGateway.py @@ -10,6 +10,7 @@ import os import json import hashlib import hmac +import sys import time import traceback from datetime import datetime, timedelta @@ -17,7 +18,9 @@ from copy import copy from math import pow from urllib import urlencode -from vnpy.api.rest import RestClient +from requests import ConnectionError + +from vnpy.api.rest import RestClient, Request from vnpy.api.websocket import WebsocketClient from vnpy.trader.vtGateway import * from vnpy.trader.vtFunction import getJsonPath, getTempPath @@ -67,6 +70,8 @@ class BitmexGateway(VtGateway): self.fileName = self.gatewayName + '_connect.json' self.filePath = getJsonPath(self.fileName, __file__) + + self.exchange = constant.EXCHANGE_BITMEX #---------------------------------------------------------------------- def connect(self): @@ -172,7 +177,7 @@ class BitmexRestApi(RestClient): """Constructor""" super(BitmexRestApi, self).__init__() - self.gateway = gateway # gateway对象 + self.gateway = gateway # type: BitmexGateway # gateway对象 self.gatewayName = gateway.gatewayName # gateway对象名称 self.apiKey = '' @@ -240,11 +245,11 @@ class BitmexRestApi(RestClient): self.gateway.onLog(log) #---------------------------------------------------------------------- - def sendOrder(self, orderReq): + def sendOrder(self, orderReq):# type: (VtOrderReq)->str """""" self.orderId += 1 - orderId = self.loginTime + self.orderId - vtOrderID = '.'.join([self.gatewayName, str(orderId)]) + orderId = str(self.loginTime + self.orderId) + vtOrderID = '.'.join([self.gatewayName, orderId]) data = { 'symbol': orderReq.symbol, @@ -258,8 +263,22 @@ class BitmexRestApi(RestClient): # 只有限价单才有price字段 if orderReq.priceType == PRICETYPE_LIMITPRICE: data['price'] = orderReq.price + + vtOrder = VtOrderData.createFromGateway( + self.gateway, + orderId=orderId, + symbol=orderReq.symbol, + exchange=self.gateway.exchange, + price=orderReq.price, + volume=orderReq.volume, + direction=orderReq.direction, + offset=orderReq.offset, + ) - self.addRequest('POST', '/order', self.onSendOrder, data=data) + self.addRequest('POST', '/order', callback=self.onSendOrder, data=data, extra=vtOrder, + onFailed=self.onSendOrderFailed, + onError=self.onSendOrderError, + ) return vtOrderID #---------------------------------------------------------------------- @@ -272,12 +291,46 @@ class BitmexRestApi(RestClient): else: params = {'orderID': orderID} - self.addRequest('DELETE', '/order', self.onCancelOrder, params=params) - + self.addRequest('DELETE', '/order', callback=self.onCancelOrder, params=params, + onError=self.onCancelOrderError, + ) + + #---------------------------------------------------------------------- + def onSendOrderFailed(self, _, request): + """ + 下单失败回调:服务器明确告知下单失败 + """ + vtOrder = request.extra # type: VtOrderData + vtOrder.status = constant.STATUS_REJECTED + self.gateway.onOrder(vtOrder) + pass + + #---------------------------------------------------------------------- + def onSendOrderError(self, exceptionType, exceptionValue, tb, request): + """ + 下单失败回调:连接错误 + """ + vtOrder = request.extra # type: VtOrderData + vtOrder.status = constant.STATUS_REJECTED + self.gateway.onOrder(vtOrder) + + # 意料之中的错误只有ConnectionError,若还有其他错误,最好还是记录一下,用原来的onError记录即可 + if not issubclass(exceptionType, ConnectionError): + self.onError(exceptionType, exceptionValue, tb, request) + #---------------------------------------------------------------------- def onSendOrder(self, data, request): """""" pass + + #---------------------------------------------------------------------- + def onCancelOrderError(self, exceptionType, exceptionValue, tb, request): + """ + 撤单失败回调:连接错误 + """ + # 意料之中的错误只有ConnectionError,若还有其他错误,最好还是记录一下,用原来的onError记录即可 + if not issubclass(exceptionType, ConnectionError): + self.onError(exceptionType, exceptionValue, tb, request) #---------------------------------------------------------------------- def onCancelOrder(self, data, request): @@ -307,8 +360,8 @@ class BitmexRestApi(RestClient): e.errorID = exceptionType e.errorMsg = exceptionValue self.gateway.onError(e) - - traceback.print_exc() + + sys.stderr.write(self.exceptionDetail(exceptionType, exceptionValue, tb, request)) ######################################################################## @@ -517,10 +570,13 @@ class BitmexWebsocketApi(WebsocketClient): trade.orderID = orderID trade.vtOrderID = '.'.join([trade.gatewayName, trade.orderID]) - trade.tradeID = tradeID trade.vtTradeID = '.'.join([trade.gatewayName, trade.tradeID]) + if 'side' not in d: + print('no side : \n', d) + return + trade.direction = directionMapReverse[d['side']] trade.price = d['lastPx'] trade.volume = d['lastQty']