From 0749007dc7fd1a558029e3b15ae3a1f8977b33da Mon Sep 17 00:00:00 2001 From: nanoric Date: Thu, 11 Oct 2018 06:12:15 -0400 Subject: [PATCH 1/7] =?UTF-8?q?[Add]=20=E4=BF=AE=E6=94=B9=E9=83=A8?= =?UTF-8?q?=E5=88=86=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vnpy/trader/vtObject.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vnpy/trader/vtObject.py b/vnpy/trader/vtObject.py index d7a1d384..9aa62507 100644 --- a/vnpy/trader/vtObject.py +++ b/vnpy/trader/vtObject.py @@ -143,10 +143,10 @@ class VtOrderData(VtBaseData): # 代码编号相关 self.symbol = EMPTY_STRING # 合约代码 self.exchange = EMPTY_STRING # 交易所代码 - self.vtSymbol = EMPTY_STRING # 合约在vt系统中的唯一代码,通常是 合约代码.交易所代码 + self.vtSymbol = EMPTY_STRING # 统一格式:f"{symbol}.{exchange}" - self.orderID = EMPTY_STRING # 订单编号 - self.vtOrderID = EMPTY_STRING # 订单在vt系统中的唯一编号,通常是 Gateway名.订单编号 + self.orderID = EMPTY_STRING # 订单编号 gateway内部自己生成的编号 + self.vtOrderID = EMPTY_STRING # 统一格式:f"{gatewayName}.{orderId}" # 报单相关 self.direction = EMPTY_UNICODE # 报单方向 From d9b5de31f335dada7dcd5733f023aba5fcb70fc1 Mon Sep 17 00:00:00 2001 From: nanoric Date: Thu, 11 Oct 2018 06:13:00 -0400 Subject: [PATCH 2/7] =?UTF-8?q?[Add]=20=E5=87=86=E5=A4=87=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0queryOrders?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vnpy/api/okexfuture/OkexFutureApi.py | 23 +++++++++ .../okexFutureGateway/okexFutureGateway.py | 50 +++++++++++++++---- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/vnpy/api/okexfuture/OkexFutureApi.py b/vnpy/api/okexfuture/OkexFutureApi.py index 78a3a796..5318425e 100644 --- a/vnpy/api/okexfuture/OkexFutureApi.py +++ b/vnpy/api/okexfuture/OkexFutureApi.py @@ -206,6 +206,29 @@ class OkexFutureRestClient(OkexFutureRestBase): callback=self.onOrder, data=data, extra=_OkexFutureCustomExtra(onSuccess, onFailed, extra)) + #---------------------------------------------------------------------- + # todos: complete this + def queryOrders(self, symbol, contractType, orderId, onSuccess, onFailed=None, + extra=None): # type: (str, OkexFutureContractType, str, Callable[[OkexFutureOrder, Any], Any], Callable[[Any], Any], Any)->Request + """ + :param symbol: str + :param contractType: OkexFutureContractType + :param orderId: str + :param onSuccess: (OkexFutureOrder, extra:Any)->Any + :param onFailed: (extra: Any)->Any + :param extra: Any + :return: Request + """ + data = { + 'symbol': symbol, + 'contractType': contractType, + 'order_id': orderId + } + return self.addReq('POST', + '/future_order_info.do', + callback=self.onOrder, + data=data, + extra=_OkexFutureCustomExtra(onSuccess, onFailed, extra)) #---------------------------------------------------------------------- def queryUserInfo(self, onSuccess, onFailed=None, diff --git a/vnpy/trader/gateway/okexFutureGateway/okexFutureGateway.py b/vnpy/trader/gateway/okexFutureGateway/okexFutureGateway.py index b3b1624e..3b5287c3 100644 --- a/vnpy/trader/gateway/okexFutureGateway/okexFutureGateway.py +++ b/vnpy/trader/gateway/okexFutureGateway/okexFutureGateway.py @@ -5,6 +5,8 @@ from __future__ import print_function import json from abc import abstractmethod, abstractproperty +from typing import Dict + from vnpy.api.okexfuture.OkexFutureApi import * from vnpy.trader.vtFunction import getJsonPath from vnpy.trader.vtGateway import * @@ -94,6 +96,7 @@ class _Order(object): self.remoteId = None self.vtOrder = None # type: VtOrderData + ######################################################################## class OkexFutureGateway(VnpyGateway): """OKEX期货交易接口""" @@ -107,8 +110,8 @@ class OkexFutureGateway(VnpyGateway): self.api = OkexFutureRestClient() self.leverRate = 1 self.symbols = [] - - self.orders = + + self._orders = {} # type: Dict[str, _Order] #---------------------------------------------------------------------- @property def gatewayName(self): @@ -148,6 +151,15 @@ class OkexFutureGateway(VnpyGateway): def subscribe(self, subscribeReq): """订阅行情""" pass + + #---------------------------------------------------------------------- + @staticmethod + def _contractTypeFromSymbol(symbol): + return symbolsForUi[symbol] + + #---------------------------------------------------------------------- + def _getOrder(self, localId): + return self._orders[localId] #---------------------------------------------------------------------- def sendOrder(self, vtRequest): # type: (VtOrderReq)->str @@ -167,8 +179,8 @@ class OkexFutureGateway(VnpyGateway): vtOrder.direction = vtRequest.direction myorder.vtOrder = vtOrder - - symbol, contractType = symbolsForUi[vtRequest.symbol] + + symbol, contractType = self._contractTypeFromSymbol(vtRequest.symbol) orderType = orderTypeMap[(vtRequest.priceType, vtRequest.offset)] # 开多、开空、平多、平空 userMarketPrice = False @@ -183,14 +195,26 @@ class OkexFutureGateway(VnpyGateway): useMarketPrice=userMarketPrice, leverRate=self.leverRate, onSuccess=self.onOrderSent, - extra=None) + extra=None, + ) return myorder.localId + + #---------------------------------------------------------------------- + def cancelOrder(self, vtCancel): # type: (VtCancelOrderReq)->None + """撤单""" + myorder = self._getOrder(vtCancel.orderID) + symbol, contractType = self._contractTypeFromSymbol(vtCancel.symbol) + self.api.cancelOrder(symbol=symbol, + contractType=contractType, + orderId=myorder.remoteId, + onSuccess=self.onOrderCanceled, + extra=myorder, + ) + # cancelDict: 不存在的,没有localId就没有remoteId,没有remoteId何来cancel #---------------------------------------------------------------------- - def cancelOrder(self, cancelOrderReq): - """撤单""" - self.api.cancelOrder(cancelOrderReq) + def queryOrder(self): #---------------------------------------------------------------------- def qryAccount(self): @@ -207,8 +231,16 @@ class OkexFutureGateway(VnpyGateway): """关闭""" self.api.close() + #---------------------------------------------------------------------- def onOrderSent(self, remoteId, myorder): #type: (int, _Order)->None myorder.remoteId = remoteId myorder.vtOrder.status = constant.STATUS_NOTTRADED self.onOrder(myorder.vtOrder) - \ No newline at end of file + + #---------------------------------------------------------------------- + @staticmethod + def onOrderCanceled(myorder): #type: (_Order)->None + myorder.vtOrder.status = constant.STATUS_CANCELLED + + + From 0ee13bf862c747566e4721bd8237305c9ae01947 Mon Sep 17 00:00:00 2001 From: nanoric Date: Thu, 11 Oct 2018 22:05:43 -0400 Subject: [PATCH 3/7] =?UTF-8?q?[Add]=20RestClient:=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E4=BA=86Join=E5=87=BD=E6=95=B0=20[Mod]=20=E5=B0=86processReq?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E4=BF=9D=E6=8A=A4=E6=96=B9=E6=B3=95=EF=BC=9A?= =?UTF-8?q?=E6=94=B9=E5=90=8D=E4=B8=BA=5FprocessReq?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vnpy/network/RestClient.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/vnpy/network/RestClient.py b/vnpy/network/RestClient.py index 9905bc44..a1f5c06e 100644 --- a/vnpy/network/RestClient.py +++ b/vnpy/network/RestClient.py @@ -127,6 +127,16 @@ class RestClient(object): :return: """ self._active = False + + #---------------------------------------------------------------------- + def join(self): + """ + 等待所有请求处理结束 + 如果要并确保RestClient的退出,请在调用stop之后紧接着调用join。 + 如果只是要确保所有的请求都处理完,直接调用join即可。 + :return: + """ + self._queue.join() #---------------------------------------------------------------------- def addReq(self, method, path, callback, @@ -160,7 +170,10 @@ class RestClient(object): while self._active: try: req = self._queue.get(timeout=1) - self.processReq(req, session) + try: + self._processReq(req, session) + finally: + self._queue.task_done() except Empty: pass @@ -202,7 +215,7 @@ class RestClient(object): sys.excepthook(exceptionType, exceptionValue, tb) #---------------------------------------------------------------------- - def processReq(self, req, session): # type: (Request, requests.Session)->None + def _processReq(self, req, session): # type: (Request, requests.Session)->None """处理请求""" try: req = self.beforeRequest(req) From a396b55f8e68d968c06cea43732b84f76391c247 Mon Sep 17 00:00:00 2001 From: nanoric Date: Thu, 11 Oct 2018 22:39:10 -0400 Subject: [PATCH 4/7] =?UTF-8?q?[Add]=20=E5=AE=8C=E6=88=90OkexFutureApi.que?= =?UTF-8?q?ryOrders?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vnpy/api/okexfuture/OkexFutureApi.py | 42 +++++++++++++++++++--------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/vnpy/api/okexfuture/OkexFutureApi.py b/vnpy/api/okexfuture/OkexFutureApi.py index 5318425e..b0c9787b 100644 --- a/vnpy/api/okexfuture/OkexFutureApi.py +++ b/vnpy/api/okexfuture/OkexFutureApi.py @@ -6,6 +6,7 @@ from vnpy.api.okexfuture.vnokexFuture import OkexFutureRestBase from vnpy.network.RestClient import Request +######################################################################## class _OkexFutureCustomExtra(object): def __init__(self, onSuccess, onFailed, extra): @@ -14,26 +15,20 @@ class _OkexFutureCustomExtra(object): self.extra = extra +######################################################################## class OkexFuturePriceType(Enum): Buy = 'buy' Sell = 'sell' +######################################################################## class OkexFutureContractType(Enum): ThisWeek = 'this_week' NextWeek = 'next_week' Quarter = 'quarter' -class OkexFutureStatus(Enum): - NoTraded = '0' - PartialTraded = '1' - AllTraded = '2' - Canceled = '-1' - CancelProcessing = '4' - Canceling = '5' - - +######################################################################## class OkexFutureOrderType(Enum): OpenLong = '1' OpenShort = '2' @@ -41,8 +36,16 @@ class OkexFutureOrderType(Enum): CloseShort = '4' +######################################################################## +class OkexFutureOrderStatus(Enum): + NotFinished = '1' + Finished = '2' + + +######################################################################## class OkexFutureOrder(object): + #---------------------------------------------------------------------- def __init__(self): self.volume = None self.contractName = None @@ -59,8 +62,10 @@ class OkexFutureOrder(object): self.unitAmount = None +######################################################################## class OkexFutureUserInfo(object): + #---------------------------------------------------------------------- def __init__(self): self.accountRights = None self.keepDeposit = None @@ -69,15 +74,19 @@ class OkexFutureUserInfo(object): self.riskRate = None +######################################################################## class OkexFuturePosition(object): + #---------------------------------------------------------------------- def __init__(self, ): self.forceLiquidatePrice = None self.holding = [] # type: List[OkexFuturePositionDetail] +######################################################################## class OkexFuturePositionDetail(object): + #---------------------------------------------------------------------- def __init__(self, ): self.buyAmount = None self.buyAvailable = None @@ -206,10 +215,12 @@ class OkexFutureRestClient(OkexFutureRestBase): callback=self.onOrder, data=data, extra=_OkexFutureCustomExtra(onSuccess, onFailed, extra)) + #---------------------------------------------------------------------- - # todos: complete this - def queryOrders(self, symbol, contractType, orderId, onSuccess, onFailed=None, - extra=None): # type: (str, OkexFutureContractType, str, Callable[[OkexFutureOrder, Any], Any], Callable[[Any], Any], Any)->Request + def queryOrders(self, symbol, contractType, status, + onSuccess, onFailed=None, + pageIndex=None, pageLength=50, + extra=None): # type: (str, OkexFutureContractType, OkexFutureOrderStatus, Callable[[OkexFutureOrder, Any], Any], Callable[[Any], Any], int, int, Any)->Request """ :param symbol: str :param contractType: OkexFutureContractType @@ -222,8 +233,13 @@ class OkexFutureRestClient(OkexFutureRestBase): data = { 'symbol': symbol, 'contractType': contractType, - 'order_id': orderId + 'status': status, + 'order_id': '-1', + 'pageLength': 50 } + if pageIndex: + data['page_index'] = pageIndex + return self.addReq('POST', '/future_order_info.do', callback=self.onOrder, From 6e0e1c116bf9858052c9089ab3b19485fd7e11c3 Mon Sep 17 00:00:00 2001 From: nanoric Date: Thu, 11 Oct 2018 22:51:31 -0400 Subject: [PATCH 5/7] =?UTF-8?q?[Mod]=20=E5=B0=86RestClient=E5=92=8CWebClie?= =?UTF-8?q?nt=E7=A7=BB=E5=8A=A8=E5=88=B0api=E6=96=87=E4=BB=B6=E5=A4=B9?= =?UTF-8?q?=E4=B8=AD=EF=BC=8C=E5=B9=B6=E4=BF=AE=E6=94=B9import=E6=96=B9?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/all_test.py | 3 +-- tests/{network => api}/__init__.py | 0 .../base/RestClientTest.py} | 2 +- tests/{network => api/base}/WebSocketClientTest.py | 3 +-- {vnpy/network => tests/api/base}/__init__.py | 0 vnpy/api/okexfuture/OkexFutureApi.py | 2 +- vnpy/api/okexfuture/vnokexFuture.py | 2 +- vnpy/{network => api/rest}/RestClient.py | 0 vnpy/api/rest/__init__.py | 1 + vnpy/{network => api/websocket}/WebSocketClient.py | 10 +++++----- vnpy/api/websocket/__init__.py | 1 + 11 files changed, 12 insertions(+), 12 deletions(-) rename tests/{network => api}/__init__.py (100%) rename tests/{network/RestfulClientTest.py => api/base/RestClientTest.py} (97%) rename tests/{network => api/base}/WebSocketClientTest.py (92%) rename {vnpy/network => tests/api/base}/__init__.py (100%) rename vnpy/{network => api/rest}/RestClient.py (100%) create mode 100644 vnpy/api/rest/__init__.py rename vnpy/{network => api/websocket}/WebSocketClient.py (91%) create mode 100644 vnpy/api/websocket/__init__.py diff --git a/tests/all_test.py b/tests/all_test.py index d8480b5f..44d1f1df 100644 --- a/tests/all_test.py +++ b/tests/all_test.py @@ -1,8 +1,7 @@ import unittest # noinspection PyUnresolvedReferences -from tests.network.RestfulClientTest import * -from tests.network.WebSocketClientTest import * +from api.base import * if __name__ == "__main__": unittest.main() diff --git a/tests/network/__init__.py b/tests/api/__init__.py similarity index 100% rename from tests/network/__init__.py rename to tests/api/__init__.py diff --git a/tests/network/RestfulClientTest.py b/tests/api/base/RestClientTest.py similarity index 97% rename from tests/network/RestfulClientTest.py rename to tests/api/base/RestClientTest.py index 9aa711f4..36da9289 100644 --- a/tests/network/RestfulClientTest.py +++ b/tests/api/base/RestClientTest.py @@ -6,7 +6,7 @@ import unittest from simplejson import JSONDecodeError from Promise import Promise -from vnpy.network.RestClient import RestClient, Request +from vnpy.api.rest.RestClient import RestClient, Request class FailedError(RuntimeError): diff --git a/tests/network/WebSocketClientTest.py b/tests/api/base/WebSocketClientTest.py similarity index 92% rename from tests/network/WebSocketClientTest.py rename to tests/api/base/WebSocketClientTest.py index 4337a3c0..8361f647 100644 --- a/tests/network/WebSocketClientTest.py +++ b/tests/api/base/WebSocketClientTest.py @@ -1,9 +1,8 @@ # encoding: UTF-8 -import json import unittest from Promise import Promise -from vnpy.network.WebSocketClient import WebsocketClient +from vnpy.api.websocket import WebsocketClient class TestWebsocketClient(WebsocketClient): diff --git a/vnpy/network/__init__.py b/tests/api/base/__init__.py similarity index 100% rename from vnpy/network/__init__.py rename to tests/api/base/__init__.py diff --git a/vnpy/api/okexfuture/OkexFutureApi.py b/vnpy/api/okexfuture/OkexFutureApi.py index b0c9787b..54b53ec2 100644 --- a/vnpy/api/okexfuture/OkexFutureApi.py +++ b/vnpy/api/okexfuture/OkexFutureApi.py @@ -3,7 +3,7 @@ from enum import Enum from typing import Any, Callable, List, Union from vnpy.api.okexfuture.vnokexFuture import OkexFutureRestBase -from vnpy.network.RestClient import Request +from vnpy.api.rest import Request ######################################################################## diff --git a/vnpy/api/okexfuture/vnokexFuture.py b/vnpy/api/okexfuture/vnokexFuture.py index 0553827d..535ea7af 100644 --- a/vnpy/api/okexfuture/vnokexFuture.py +++ b/vnpy/api/okexfuture/vnokexFuture.py @@ -4,7 +4,7 @@ import urllib ######################################################################## -from vnpy.network.RestClient import RestClient, Request +from vnpy.api.rest import RestClient, Request ######################################################################## diff --git a/vnpy/network/RestClient.py b/vnpy/api/rest/RestClient.py similarity index 100% rename from vnpy/network/RestClient.py rename to vnpy/api/rest/RestClient.py diff --git a/vnpy/api/rest/__init__.py b/vnpy/api/rest/__init__.py new file mode 100644 index 00000000..f0cbea27 --- /dev/null +++ b/vnpy/api/rest/__init__.py @@ -0,0 +1 @@ +from .RestClient import Request, RequestStatus, RestClient, requestsSessionProvider diff --git a/vnpy/network/WebSocketClient.py b/vnpy/api/websocket/WebSocketClient.py similarity index 91% rename from vnpy/network/WebSocketClient.py rename to vnpy/api/websocket/WebSocketClient.py index f969cfa6..12cbfca5 100644 --- a/vnpy/network/WebSocketClient.py +++ b/vnpy/api/websocket/WebSocketClient.py @@ -9,7 +9,7 @@ import time from abc import abstractmethod from threading import Thread, Lock -import websocket +import vnpy.api.websocket class WebsocketClient(object): @@ -57,12 +57,12 @@ class WebsocketClient(object): #---------------------------------------------------------------------- def sendReq(self, req): # type: (dict)->None """发出请求""" - return self._get_ws().send(json.dumps(req), opcode=websocket.ABNF.OPCODE_TEXT) + return self._get_ws().send(json.dumps(req), opcode=vnpy.api.websocket.ABNF.OPCODE_TEXT) #---------------------------------------------------------------------- def sendText(self, text): # type: (str)->None """发出请求""" - return self._get_ws().send(text, opcode=websocket.ABNF.OPCODE_TEXT) + return self._get_ws().send(text, opcode=vnpy.api.websocket.ABNF.OPCODE_TEXT) #---------------------------------------------------------------------- def sendData(self, data): # type: (bytes)->None @@ -78,7 +78,7 @@ class WebsocketClient(object): #---------------------------------------------------------------------- def _connect(self): """""" - self._ws = websocket.create_connection(self.host, sslopt={'cert_reqs': ssl.CERT_NONE}) + self._ws = vnpy.api.websocket.create_connection(self.host, sslopt={'cert_reqs': ssl.CERT_NONE}) self.onConnect() #---------------------------------------------------------------------- @@ -125,7 +125,7 @@ class WebsocketClient(object): #---------------------------------------------------------------------- def _ping(self): - return self._get_ws().send('ping', websocket.ABNF.OPCODE_PING) + return self._get_ws().send('ping', vnpy.api.websocket.ABNF.OPCODE_PING) #---------------------------------------------------------------------- @abstractmethod diff --git a/vnpy/api/websocket/__init__.py b/vnpy/api/websocket/__init__.py new file mode 100644 index 00000000..3e58eeb4 --- /dev/null +++ b/vnpy/api/websocket/__init__.py @@ -0,0 +1 @@ +from .WebSocketClient import WebsocketClient From 8c971c7d81362fe3483dacecb6e8b6b6d2e88a95 Mon Sep 17 00:00:00 2001 From: nanoric Date: Thu, 11 Oct 2018 23:09:25 -0400 Subject: [PATCH 6/7] =?UTF-8?q?[Add]=20=E5=A2=9E=E5=8A=A0OkexFutureSymbol?= =?UTF-8?q?=E7=B1=BB=E4=BB=A5=E8=A1=A8=E7=A4=BA=E5=8F=AF=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E7=9A=84=E5=90=88=E7=BA=A6=EF=BC=88=E6=97=A0=E6=B3=95=E7=9B=B4?= =?UTF-8?q?=E6=8E=A5=E4=BB=8EAPI=E6=9F=A5=E8=AF=A2=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vnpy/api/okexfuture/OkexFutureApi.py | 9 +++++++++ vnpy/api/okexfuture/__init__.py | 2 ++ 2 files changed, 11 insertions(+) diff --git a/vnpy/api/okexfuture/OkexFutureApi.py b/vnpy/api/okexfuture/OkexFutureApi.py index 54b53ec2..6c351312 100644 --- a/vnpy/api/okexfuture/OkexFutureApi.py +++ b/vnpy/api/okexfuture/OkexFutureApi.py @@ -13,6 +13,15 @@ class _OkexFutureCustomExtra(object): self.onFailed = onFailed self.onSuccess = onSuccess self.extra = extra + + +######################################################################## +class OkexFutureSymbol(Enum): + BTC = 'btc_usd' + LTC = 'ltc_usd' + ETH = 'eth_usd' + ETC = 'etc_usd' + BCH = 'bch_usd' ######################################################################## diff --git a/vnpy/api/okexfuture/__init__.py b/vnpy/api/okexfuture/__init__.py index e69de29b..71802197 100644 --- a/vnpy/api/okexfuture/__init__.py +++ b/vnpy/api/okexfuture/__init__.py @@ -0,0 +1,2 @@ +from .OkexFutureApi import OkexFutureSymbol, OkexFutureContractType, OkexFutureOrder, OkexFutureOrderStatus, OkexFuturePosition, \ + OkexFuturePositionDetail, OkexFuturePriceType, OkexFutureRestClient, OkexFutureUserInfo From 4878b3291bb4e996a73dffb7262d3ae0c1a6fdb1 Mon Sep 17 00:00:00 2001 From: nanoric Date: Thu, 11 Oct 2018 23:37:16 -0400 Subject: [PATCH 7/7] =?UTF-8?q?[Mod]=20=E5=B0=86Enum=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E6=99=AE=E9=80=9A=E7=9A=84object=20[Mod]=20onFailed=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E4=B8=80=E4=B8=AAerrorCode=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vnpy/api/okexfuture/OkexFutureApi.py | 101 ++++++++++++++++++++++----- 1 file changed, 84 insertions(+), 17 deletions(-) diff --git a/vnpy/api/okexfuture/OkexFutureApi.py b/vnpy/api/okexfuture/OkexFutureApi.py index 6c351312..2849c8c9 100644 --- a/vnpy/api/okexfuture/OkexFutureApi.py +++ b/vnpy/api/okexfuture/OkexFutureApi.py @@ -1,5 +1,4 @@ # encoding: UTF-8 -from enum import Enum from typing import Any, Callable, List, Union from vnpy.api.okexfuture.vnokexFuture import OkexFutureRestBase @@ -16,7 +15,7 @@ class _OkexFutureCustomExtra(object): ######################################################################## -class OkexFutureSymbol(Enum): +class OkexFutureSymbol(object): BTC = 'btc_usd' LTC = 'ltc_usd' ETH = 'eth_usd' @@ -25,20 +24,20 @@ class OkexFutureSymbol(Enum): ######################################################################## -class OkexFuturePriceType(Enum): +class OkexFuturePriceType(object): Buy = 'buy' Sell = 'sell' ######################################################################## -class OkexFutureContractType(Enum): +class OkexFutureContractType(object): ThisWeek = 'this_week' NextWeek = 'next_week' Quarter = 'quarter' ######################################################################## -class OkexFutureOrderType(Enum): +class OkexFutureOrderType(object): OpenLong = '1' OpenShort = '2' CloseLong = '3' @@ -46,7 +45,7 @@ class OkexFutureOrderType(Enum): ######################################################################## -class OkexFutureOrderStatus(Enum): +class OkexFutureOrderStatus(object): NotFinished = '1' Finished = '2' @@ -143,7 +142,7 @@ class OkexFutureRestClient(OkexFutureRestBase): def sendOrder(self, symbol, contractType, orderType, volume, onSuccess, onFailed=None, price=None, useMarketPrice=False, leverRate=None, - extra=None): # type:(str, OkexFutureContractType, OkexFutureOrderType, float, Callable[[int, Any], Any], Callable[[Any], Any], float, bool, Union[int, None], Any)->Request + extra=None): # type:(str, OkexFutureContractType, OkexFutureOrderType, float, Callable[[int, Any], Any], Callable[[int, Any], Any], float, bool, Union[int, None], Any)->Request """ :param symbol: str :param contractType: OkexFutureContractType @@ -181,7 +180,7 @@ class OkexFutureRestClient(OkexFutureRestBase): #---------------------------------------------------------------------- def cancelOrder(self, symbol, contractType, orderId, onSuccess, onFailed=None, - extra=None): # type: (str, OkexFutureContractType, str, Callable[[object], Any], Callable[[Any], Any], Any)->Request + extra=None): # type: (str, OkexFutureContractType, str, Callable[[object], Any], Callable[[int, Any], Any], Any)->Request """ :param symbol: str :param contractType: OkexFutureContractType @@ -204,7 +203,7 @@ class OkexFutureRestClient(OkexFutureRestBase): #---------------------------------------------------------------------- def queryOrder(self, symbol, contractType, orderId, onSuccess, onFailed=None, - extra=None): # type: (str, OkexFutureContractType, str, Callable[[OkexFutureOrder, Any], Any], Callable[[Any], Any], Any)->Request + extra=None): # type: (str, OkexFutureContractType, str, Callable[[OkexFutureOrder, Any], Any], Callable[[int, Any], Any], Any)->Request """ :param symbol: str :param contractType: OkexFutureContractType @@ -229,7 +228,7 @@ class OkexFutureRestClient(OkexFutureRestBase): def queryOrders(self, symbol, contractType, status, onSuccess, onFailed=None, pageIndex=None, pageLength=50, - extra=None): # type: (str, OkexFutureContractType, OkexFutureOrderStatus, Callable[[OkexFutureOrder, Any], Any], Callable[[Any], Any], int, int, Any)->Request + extra=None): # type: (str, OkexFutureContractType, OkexFutureOrderStatus, Callable[[OkexFutureOrder, Any], Any], Callable[[int, Any], Any], int, int, Any)->Request """ :param symbol: str :param contractType: OkexFutureContractType @@ -257,7 +256,7 @@ class OkexFutureRestClient(OkexFutureRestBase): #---------------------------------------------------------------------- def queryUserInfo(self, onSuccess, onFailed=None, - extra=None): # type: (Callable[[List[OkexFutureUserInfo], Any], Any], Callable[[Any], Any], Any)->Request + extra=None): # type: (Callable[[List[OkexFutureUserInfo], Any], Any], Callable[[int, Any], Any], Any)->Request """ 查询用户信息 :param onSuccess: (userInfos: List[OkexFutureUserInfo], extra: Any)->Any @@ -273,7 +272,7 @@ class OkexFutureRestClient(OkexFutureRestBase): #---------------------------------------------------------------------- def queryPosition(self, symbol, contractType, onSuccess, onFailed=None, - extra=None): # type: (str, OkexFutureContractType, Callable[[OkexFuturePosition, Any], Any], Callable[[Any], Any], Any)->Request + extra=None): # type: (str, OkexFutureContractType, Callable[[OkexFuturePosition, Any], Any], Callable[[int, Any], Any], Any)->Request data = { 'symbol': symbol, 'contractType': contractType @@ -296,7 +295,10 @@ class OkexFutureRestClient(OkexFutureRestBase): extra.onSuccess(remoteId, extra.extra) else: if extra.onFailed: - extra.onFailed(extra.extra) + code = 0 + if 'error_code' in data: + code = data['error_code'] + extra.onFailed(code, extra.extra) #---------------------------------------------------------------------- @staticmethod @@ -310,7 +312,10 @@ class OkexFutureRestClient(OkexFutureRestBase): extra.onSuccess(extra.extra) else: if extra.onFailed: - extra.onFailed(extra.extra) + code = 0 + if 'error_code' in data: + code = data['error_code'] + extra.onFailed(code, extra.extra) #---------------------------------------------------------------------- @staticmethod @@ -338,7 +343,10 @@ class OkexFutureRestClient(OkexFutureRestBase): extra.onSuccess(okexOrder, extra.extra) else: if extra.onFailed: - extra.onFailed(extra.extra) + code = 0 + if 'error_code' in data: + code = data['error_code'] + extra.onFailed(code, extra.extra) #---------------------------------------------------------------------- @staticmethod @@ -359,7 +367,10 @@ class OkexFutureRestClient(OkexFutureRestBase): extra.onSuccess(uis, extra.extra) else: if extra.onFailed: - extra.onFailed(extra.extra) + code = 0 + if 'error_code' in data: + code = data['error_code'] + extra.onFailed(code, extra.extra) #---------------------------------------------------------------------- @staticmethod @@ -390,4 +401,60 @@ class OkexFutureRestClient(OkexFutureRestBase): extra.onSuccess(pos, extra.extra) else: if extra.onFailed: - extra.onFailed(extra.extra) + code = 0 + if 'error_code' in data: + code = data['error_code'] + extra.onFailed(code, extra.extra) + + #---------------------------------------------------------------------- + @staticmethod + def errorCode2String(code): + assert code in errorCodeMap + return errorCodeMap[code] + + +errorCodeMap = { + 0: '远程服务器并未给出错误代码', + + 20001: '用户不存在', + 20002: '用户被冻结', + 20003: '用户被爆仓冻结', + 20004: '合约账户被冻结', + 20005: '用户合约账户不存在', + 20006: '必填参数为空', + 20007: '参数错误', + 20008: '合约账户余额为空', + 20009: '虚拟合约状态错误', + 20010: '合约风险率信息不存在', + 20011: '10倍/20倍杠杆开BTC前保证金率低于90%/80%,10倍/20倍杠杆开LTC前保证金率低于80%/60%', + 20012: '10倍/20倍杠杆开BTC后保证金率低于90%/80%,10倍/20倍杠杆开LTC后保证金率低于80%/60%', + 20013: '暂无对手价', + 20014: '系统错误', + 20015: '订单信息不存在', + 20016: '平仓数量是否大于同方向可用持仓数量', + 20017: '非本人操作', + 20018: '下单价格高于前一分钟的103%或低于97%', + 20019: '该IP限制不能请求该资源', + 20020: '密钥不存在', + 20021: '指数信息不存在', + 20022: '接口调用错误(全仓模式调用全仓接口,逐仓模式调用逐仓接口)', + 20023: '逐仓用户', + 20024: 'sign签名不匹配', + 20025: '杠杆比率错误', + 20026: 'API鉴权错误', + 20027: '无交易记录', + 20028: '合约不存在', + 20029: '转出金额大于可转金额', + 20030: '账户存在借款', + 20038: '根据相关法律,您所在的国家或地区不能使用该功能。', + 20049: '用户请求接口过于频繁', + 20061: '合约相同方向只支持一个杠杆,若有10倍多单,就不能再下20倍多单', + 21005: '请求接口失败,请您重试', + 21020: '合约交割中,无法下单', + 21021: '合约清算中,无法下单', + 21023: '当前全仓方向仓位已超过最大可开张数', + 21024: '当前逐仓方向仓位已超过最大可开张数', + 21025: '下单后保证金率小于对应档位要求的最低保证金率', + 21026: '您的账户已被限制开仓操作', + 20119: '接口已下线或无法使用', +}