2018-10-22 02:41:30 +00:00
|
|
|
|
# encoding: UTF-8
|
|
|
|
|
import base64
|
|
|
|
|
import hashlib
|
|
|
|
|
import hmac
|
|
|
|
|
import json
|
|
|
|
|
import urllib
|
|
|
|
|
|
|
|
|
|
import time
|
|
|
|
|
|
|
|
|
|
from vnpy.api.rest import Request, RestClient
|
2018-10-24 01:31:20 +00:00
|
|
|
|
from vnpy.api.websocket import WebsocketClient
|
2018-10-22 02:41:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
def paramsToDataV1(params):
|
|
|
|
|
return urllib.urlencode(sorted(params.items()))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
def signV1(dataWithApiKey, apiSecret):
|
|
|
|
|
"""
|
|
|
|
|
usage:
|
|
|
|
|
params = { ... , 'api_key': ...}
|
|
|
|
|
data = paramsToData(params)
|
|
|
|
|
signature = sign(data, apiSecret)
|
|
|
|
|
data += "&sign" + signature
|
|
|
|
|
|
|
|
|
|
:param dataWithApiKey: sorted urlencoded args with apiKey
|
|
|
|
|
:return: param 'sign' for okex api
|
|
|
|
|
"""
|
|
|
|
|
dataWithSecret = dataWithApiKey + "&secret_key=" + apiSecret
|
|
|
|
|
return hashlib.md5(dataWithSecret.encode()).hexdigest().upper()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
def signV3(dataToSign, apiSecret):
|
|
|
|
|
return base64.b64encode( hmac.new(apiSecret, dataToSign.encode(), hashlib.sha256).digest())
|
|
|
|
|
|
2018-10-24 01:31:20 +00:00
|
|
|
|
|
2018-10-22 02:41:30 +00:00
|
|
|
|
########################################################################
|
|
|
|
|
class OkexFuturesRestBaseV1(RestClient):
|
|
|
|
|
host = 'https://www.okex.com/api/v1'
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
def __init__(self):
|
|
|
|
|
super(OkexFuturesRestBaseV1, self).__init__()
|
|
|
|
|
self.apiKey = None
|
|
|
|
|
self.apiSecret = None
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
# noinspection PyMethodOverriding
|
|
|
|
|
def init(self, apiKey, apiSecret, apiPassphrase):
|
|
|
|
|
# type: (str, str, str) -> any
|
|
|
|
|
super(OkexFuturesRestBaseV1, self).init(self.host)
|
|
|
|
|
self.apiKey = apiKey
|
|
|
|
|
self.apiSecret = apiSecret
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
def sign(self, request): # type: (Request)->Request
|
|
|
|
|
args = request.params or {}
|
|
|
|
|
args.update(request.data or {})
|
|
|
|
|
if 'sign' in args:
|
|
|
|
|
args.pop('sign')
|
|
|
|
|
if 'apiKey' not in args:
|
|
|
|
|
args['api_key'] = self.apiKey
|
|
|
|
|
data = paramsToDataV1(args)
|
|
|
|
|
signature = signV1(data, self.apiSecret)
|
|
|
|
|
data += "&sign=" + signature
|
|
|
|
|
|
|
|
|
|
request.headers = {'Content-Type': 'application/x-www-form-urlencoded'}
|
|
|
|
|
request.data = data
|
|
|
|
|
return request
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
########################################################################
|
|
|
|
|
class OkexFuturesRestBaseV3(RestClient):
|
|
|
|
|
"""
|
|
|
|
|
Okex Rest API v3基础类
|
|
|
|
|
"""
|
|
|
|
|
host = 'https://www.okex.com'
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
def __init__(self):
|
|
|
|
|
super(OkexFuturesRestBaseV3, self).__init__()
|
|
|
|
|
self.apiKey = None
|
|
|
|
|
self.apiSecret = None
|
|
|
|
|
self.apiPassphrase = None
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
# noinspection PyMethodOverriding
|
|
|
|
|
def init(self, apiKey, apiSecret, apiPassphrase):
|
|
|
|
|
# type: (str, str, str) -> any
|
|
|
|
|
super(OkexFuturesRestBaseV3, self).init(self.host)
|
|
|
|
|
self.apiKey = apiKey
|
|
|
|
|
self.apiSecret = apiSecret
|
|
|
|
|
self.apiPassphrase = apiPassphrase
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
def sign(self, request): # type: (Request)->Request
|
|
|
|
|
timestamp = str(time.time())
|
|
|
|
|
|
|
|
|
|
data = json.dumps(request.data)
|
|
|
|
|
request.data = data
|
|
|
|
|
dataToSign = timestamp + request.method + request.path + data
|
|
|
|
|
|
|
|
|
|
signature = signV3(dataToSign, self.apiSecret)
|
|
|
|
|
|
|
|
|
|
request.headers = {
|
|
|
|
|
'OK-ACCESS-KEY': self.apiKey,
|
|
|
|
|
'OK-ACCESS-SIGN': signature,
|
|
|
|
|
'OK-ACCESS-TIMESTAMP': timestamp,
|
|
|
|
|
'OK-ACCESS-PASSPHRASE': self.apiPassphrase,
|
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
|
}
|
|
|
|
|
return request
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
########################################################################
|
2018-10-24 01:31:20 +00:00
|
|
|
|
class OkexFuturesWebSocketBase(WebsocketClient):
|
2018-10-22 02:41:30 +00:00
|
|
|
|
"""
|
|
|
|
|
Okex期货websocket客户端
|
|
|
|
|
实例化后使用init设置apiKey和secretKey(apiSecret)
|
|
|
|
|
"""
|
2018-10-31 09:07:44 +00:00
|
|
|
|
host = 'wss://real.okex.com:10440/websocket/okexapi?compress=true'
|
2018-10-22 02:41:30 +00:00
|
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
super(OkexFuturesWebSocketBase, self).__init__()
|
|
|
|
|
super(OkexFuturesWebSocketBase, self).init(OkexFuturesWebSocketBase.host)
|
|
|
|
|
self.apiKey = None
|
|
|
|
|
self.apiSecret = None
|
|
|
|
|
self.apiPassphrase = None
|
|
|
|
|
|
|
|
|
|
self.autoLogin = True
|
|
|
|
|
|
|
|
|
|
self.onConnected = self._onConnected
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
# noinspection PyMethodOverriding
|
|
|
|
|
def init(self, apiKey, secretKey, apiPassphrase, autoLogin=True):
|
|
|
|
|
|
|
|
|
|
self.apiKey = apiKey
|
|
|
|
|
self.apiSecret = secretKey
|
|
|
|
|
self.apiPassphrase = apiPassphrase
|
|
|
|
|
self.autoLogin = autoLogin
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
def sendPacket(self, dictObj, authenticate=False):
|
|
|
|
|
if authenticate:
|
|
|
|
|
pass
|
|
|
|
|
return super(OkexFuturesWebSocketBase, self).sendPacket(dictObj)
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
def _login(self, ):
|
|
|
|
|
timestamp = str(time.time())
|
|
|
|
|
|
|
|
|
|
data = timestamp + 'GET' + '/users/self/verify'
|
|
|
|
|
signature = signV3(data, self.apiSecret)
|
|
|
|
|
|
|
|
|
|
self.sendPacket({
|
|
|
|
|
"event": "login",
|
|
|
|
|
"parameters": {
|
|
|
|
|
"api_key": self.apiKey,
|
|
|
|
|
"timestamp": timestamp,
|
|
|
|
|
"passphrase": self.apiPassphrase,
|
|
|
|
|
"sign": signature,
|
|
|
|
|
}
|
|
|
|
|
}, authenticate=False)
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
def _onConnected(self):
|
|
|
|
|
if self.autoLogin:
|
|
|
|
|
self._login()
|