[Mod]修改OKEX接口符合vn.py代码风格

This commit is contained in:
vn.py 2017-12-16 15:14:25 +08:00
parent 1dcd2239bd
commit 8652f7fb2e
5 changed files with 223 additions and 267 deletions

14
vnpy/api/okex/README.md Normal file
View File

@ -0,0 +1,14 @@
### 简介
OKEX的比特币交易接口基于Websocket API开发实现了以下功能
1. 发送、撤销委托
2. 查询委托、持仓、资金、成交历史
3. 实时行情、成交、资金更新的推送
### API信息
链接:[https://www.okex.com/ws_getStarted.html](https://www.okex.com/ws_getStarted.html)

View File

@ -1,3 +1,3 @@
# encoding: UTF-8 # encoding: UTF-8
from vnokex import OKEX_Sub_Spot_Api , OKEX_Contract_Api , okex_all_symbol_pairs , okex_all_contract_symbol , okex_all_symbol_type from vnokex import OkexSpotApi , OkexFuturesApi , okex_all_symbol_pairs , CONTRACT_SYMBOL , SPOT_CURRENCY

View File

@ -1,5 +0,0 @@
okex 的平台地址
https://www.okex.com/intro_apiOverview.html
api 文档 https://www.okex.com/ws_request.html

View File

@ -7,9 +7,9 @@ apiKey = '你的accessKey'
secretKey = '你的secretKey' secretKey = '你的secretKey'
# 创建API对象 # 创建API对象
api = OKEX_Sub_Spot_Api() api = OkexSpotApi()
api.connect_Subpot(apiKey, secretKey, True) api.connect(apiKey, secretKey, True)
sleep(3) sleep(3)
@ -25,8 +25,8 @@ api.spotTrade("etc_usdt","sell", "50" , "0.01")
#api.spotUserInfo() #api.spotUserInfo()
#api.spotOrderInfo("etc_btc", 44284731) #api.spotOrderInfo("etc_btc", 44284731)
# api = OKEX_Contract_Api() # api = OkexFuturesApi()
# api.connect_Contract(apiKey, secretKey, True) # api.connect(apiKey, secretKey, True)
# sleep(3) # sleep(3)
#api.subsribeFutureTicker("btc","this_week") #api.subsribeFutureTicker("btc","this_week")

View File

@ -9,34 +9,76 @@ from threading import Thread
import websocket import websocket
# OKEX网站 # OKEX网站
OKEX_USD_SPOT = 'wss://real.okex.com:10441/websocket' # OKEX 现货地址
OKEX_USD_SUB_SPOT = 'wss://real.okex.com:10441/websocket' # OKEX 现货地址
OKEX_USD_CONTRACT = 'wss://real.okex.com:10440/websocket/okexapi' # OKEX 期货地址 OKEX_USD_CONTRACT = 'wss://real.okex.com:10440/websocket/okexapi' # OKEX 期货地址
okex_all_symbol_type = ["usdt","btc","ltc","eth","etc","bch"] SPOT_CURRENCY = ["usdt",
okex_all_symbol_pairs = ["ltc_btc","eth_btc","etc_btc","bch_btc","btc_usdt","eth_usdt",\ "btc",
"ltc_usdt","etc_usdt","bch_usdt","etc_eth","bt1_btc","bt2_btc","btg_btc","qtum_btc",\ "ltc",
"hsr_btc","neo_btc","gas_btc","qtum_usdt","hsr_usdt","neo_usdt","gas_usdt"] "eth",
"etc",
"bch"]
# for test SPOT_SYMBOL = ["ltc_btc",
# okex_all_symbol_pairs = ['etc_usdt'] "eth_btc",
"etc_btc",
"bch_btc",
"btc_usdt",
"eth_usdt",
"ltc_usdt",
"etc_usdt",
"bch_usdt",
"etc_eth",
"bt1_btc",
"bt2_btc",
"btg_btc",
"qtum_btc",
"hsr_btc",
"neo_btc",
"gas_btc",
"qtum_usdt",
"hsr_usdt",
"neo_usdt",
"gas_usdt"]
okex_all_k_line_periods = ["1min","3min","5min","15min","30min","1hour","2hour","4hour","6hour","12hour","day","3day","week"] KLINE_PERIOD = ["1min",
"3min",
"5min",
"15min",
"30min",
"1hour",
"2hour",
"4hour",
"6hour",
"12hour",
"day",
"3day",
"week"]
okex_all_contract_symbol = ["btc","ltc","eth","bch"] CONTRACT_SYMBOL = ["btc",
okex_all_contract_type = ["this_week","next_week","quarter"] "ltc",
"eth",
"etc",
"bch"]
CONTRACT_TYPE = ["this_week",
"next_week",
"quarter"]
########################################################################
class OkexApi(object):
"""交易接口"""
class OKEX_Sub_Spot_Api(object):
"""基于Websocket的API对象"""
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def __init__(self): def __init__(self):
"""Constructor""" """Constructor"""
self.host = '' # 服务器
self.apiKey = '' # 用户名 self.apiKey = '' # 用户名
self.secretKey = '' # 密码 self.secretKey = '' # 密码
self.ws_sub_spot = None # websocket应用对象 现货对象 self.ws = None # websocket应用对象 现货对象
self.thread = None # 初始化线程
self.thread = None # 线程初始化
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def reconnect(self): def reconnect(self):
@ -45,52 +87,43 @@ class OKEX_Sub_Spot_Api(object):
self.close() self.close()
# 再执行重连任务 # 再执行重连任务
self.ws_sub_spot = websocket.WebSocketApp(self.host, self.ws = websocket.WebSocketApp(self.host,
on_message=self.onMessage, on_message=self.onMessage,
on_error=self.onError, on_error=self.onError,
on_close=self.onClose, on_close=self.onClose,
on_open=self.onOpen) on_open=self.onOpen)
self.thread = Thread(target=self.ws_sub_spot.run_forever) self.thread = Thread(target=self.ws.run_forever)
self.thread.start() self.thread.start()
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def connect_Subpot(self, apiKey , secretKey , trace = False): def connect(self, apiKey, secretKey, trace=False):
self.host = OKEX_USD_SUB_SPOT self.host = OKEX_USD_SPOT
self.apiKey = apiKey self.apiKey = apiKey
self.secretKey = secretKey self.secretKey = secretKey
websocket.enableTrace(trace) websocket.enableTrace(trace)
self.ws_sub_spot = websocket.WebSocketApp(self.host, self.ws = websocket.WebSocketApp(self.host,
on_message=self.onMessage, on_message=self.onMessage,
on_error=self.onError, on_error=self.onError,
on_close=self.onClose, on_close=self.onClose,
on_open=self.onOpen) on_open=self.onOpen)
self.thread = Thread(target=self.ws_sub_spot.run_forever) self.thread = Thread(target=self.ws.run_forever)
self.thread.start() self.thread.start()
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def readData(self, evt): def readData(self, evt):
"""解压缩推送收到的数据""" """解码推送收到的数据"""
# # 创建解压器
# decompress = zlib.decompressobj(-zlib.MAX_WBITS)
# # 将原始数据解压成字符串
# inflated = decompress.decompress(evt) + decompress.flush()
# 通过json解析字符串
#data = json.loads(inflated)
data = json.loads(evt) data = json.loads(evt)
return data return data
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def close(self): def close(self):
"""关闭接口""" """关闭接口"""
if self.thread and self.thread.isAlive(): if self.thread and self.thread.isAlive():
self.ws_sub_spot.close() self.ws.close()
self.thread.join() self.thread.join()
#---------------------------------------------------------------------- #----------------------------------------------------------------------
@ -114,34 +147,6 @@ class OKEX_Sub_Spot_Api(object):
"""接口打开""" """接口打开"""
print 'onOpen' print 'onOpen'
#----------------------------------------------------------------------
def subscribeSpotTicker(self, symbol_pair):
# 现货的 ticker
req = "{'event':'addChannel','channel':'ok_sub_spot_%s_ticker'}" % symbol_pair
self.ws_sub_spot.send(req)
#----------------------------------------------------------------------
def subscribeSpotDepth(self, symbol_pair):
# 现货的 市场深度
req = "{'event':'addChannel','channel':'ok_sub_spot_%s_depth'}" % symbol_pair
self.ws_sub_spot.send(req)
#----------------------------------------------------------------------
def subscribeSpotDepth5(self, symbol_pair):
# 现货的 市场深度 5
req = "{'event':'addChannel','channel':'ok_sub_spot_%s_depth_5'}" % symbol_pair
self.ws_sub_spot.send(req)
#----------------------------------------------------------------------
def subscribeSpotDeals(self, symbol_pair):
req = "{'event':'addChannel','channel':'ok_sub_spot_%s_deals'}" % symbol_pair
self.ws_sub_spot.send(req)
#----------------------------------------------------------------------
def subscribeSpotKlines(self, symbol_pair , time_period):
req = "{'event':'addChannel','channel':'ok_sub_spot_%s_kline_%s'}" % ( symbol_pair , time_period)
self.ws_sub_spot.send(req)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def generateSign(self, params): def generateSign(self, params):
"""生成签名""" """生成签名"""
@ -170,15 +175,84 @@ class OKEX_Sub_Spot_Api(object):
# 若触发异常则重连 # 若触发异常则重连
try: try:
self.ws_sub_spot.send(j) self.ws.send(j)
except websocket.WebSocketConnectionClosedException: except websocket.WebSocketConnectionClosedException:
pass pass
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def spotTrade(self, symbol_pair, type_, price, amount): def sendDataRequest(self, channel):
"""发送数据请求"""
d = {}
d['event'] = 'addChannel'
d['channel'] = channel
j = json.dumps(d)
# 若触发异常则重连
try:
self.ws.send(j)
except websocket.WebSocketConnectionClosedException:
pass
#----------------------------------------------------------------------
def login(self):
params = {}
params['api_key'] = self.apiKey
params['sign'] = self.generateSign(params)
# 生成请求
d = {}
d['event'] = 'login'
d['parameters'] = params
# 使用json打包并发送
j = json.dumps(d)
# 若触发异常则重连
try:
self.ws.send(j)
return True
except websocket.WebSocketConnectionClosedException:
return False
########################################################################
class OkexSpotApi(OkexApi):
"""现货交易接口"""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
super(OkexSpotApi, self).__init__()
#----------------------------------------------------------------------
def subscribeSpotTicker(self, symbol):
"""订阅现货的Tick"""
channel = 'ok_sub_spot_%s_ticker' %symbol
self.sendDataRequest(channel)
#----------------------------------------------------------------------
def subscribeSpotDepth(self, symbol, depth=0):
"""订阅现货的深度"""
channel = 'ok_sub_spot_%s_depth' %symbol
if depth:
channel = channel + '_' + str(depth)
self.sendDataRequest(channel)
#----------------------------------------------------------------------
def subscribeSpotDeals(self, symbol):
channel = 'ok_sub_spot_%s_deals' %symbol
self.sendDataRequest(channel)
#----------------------------------------------------------------------
def subscribeSpotKlines(self, symbol, period):
channel = 'ok_sub_spot_%s_kline_%s' %symbol
self.sendDataRequest(channel)
#----------------------------------------------------------------------
def spotTrade(self, symbol, type_, price, amount):
"""现货委托""" """现货委托"""
params = {} params = {}
params['symbol'] = str(symbol_pair) params['symbol'] = str(symbol)
params['type'] = str(type_) params['type'] = str(type_)
params['price'] = str(price) params['price'] = str(price)
params['amount'] = str(amount) params['amount'] = str(amount)
@ -188,10 +262,10 @@ class OKEX_Sub_Spot_Api(object):
self.sendTradingRequest(channel, params) self.sendTradingRequest(channel, params)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def spotCancelOrder(self, symbol_pair, orderid): def spotCancelOrder(self, symbol, orderid):
"""现货撤单""" """现货撤单"""
params = {} params = {}
params['symbol'] = str(symbol_pair) params['symbol'] = str(symbol)
params['order_id'] = str(orderid) params['order_id'] = str(orderid)
channel = 'ok_spot_cancel_order' channel = 'ok_spot_cancel_order'
@ -205,10 +279,10 @@ class OKEX_Sub_Spot_Api(object):
self.sendTradingRequest(channel, {}) self.sendTradingRequest(channel, {})
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def spotOrderInfo(self, symbol_pair, orderid): def spotOrderInfo(self, symbol, orderid):
"""查询现货委托信息""" """查询现货委托信息"""
params = {} params = {}
params['symbol'] = str(symbol_pair) params['symbol'] = str(symbol)
params['order_id'] = str(orderid) params['order_id'] = str(orderid)
channel = 'ok_spot_orderinfo' channel = 'ok_spot_orderinfo'
@ -216,224 +290,99 @@ class OKEX_Sub_Spot_Api(object):
self.sendTradingRequest(channel, params) self.sendTradingRequest(channel, params)
#----------------------------------------------------------------------
# 这个 API 应该已经别废弃了
# def subscribeSpotTrades(self , symbol_pair):
# """订阅现货成交信息"""
# channel = 'ok_sub_spot_%s_trades' % ( symbol_pair)
# self.sendTradingRequest(channel, {}) ########################################################################
class OkexFuturesApi(OkexApi):
"""期货交易接口
#---------------------------------------------------------------------- 交割推送信息
# 这个 API 应该已经别废弃了 [{
# def subscribeSpotUserInfo(self):
# """订阅现货账户信息"""
# channel = 'ok_sub_spot_userinfo'
# self.sendTradingRequest(channel, {})
#----------------------------------------------------------------------
def login(self):
params = {}
params['api_key'] = self.apiKey
params['sign'] = self.generateSign(params)
# 生成请求
d = {}
d['event'] = 'login'
d['parameters'] = params
# 使用json打包并发送
j = json.dumps(d)
# 若触发异常则重连
try:
self.ws_sub_spot.send(j)
except websocket.WebSocketConnectionClosedException:
pass
'''
OKEX 合约接口
[{
"channel": "btc_forecast_price", "channel": "btc_forecast_price",
"timestamp":"1490341322021", "timestamp":"1490341322021",
"data": "998.8" "data": "998.8"
}] }]
data(string): 预估交割价格 data(string): 预估交割价格
timestamp(string): 时间戳 timestamp(string): 时间戳
操作说明
无需订阅交割前一小时自动返回 无需订阅交割前一小时自动返回
"""
这段数据交割前会自动返回
'''
class OKEX_Contract_Api(object):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def __init__(self): def __init__(self):
"""Constructor""" """Constructor"""
self.apiKey = '' # 用户名 super(OkexFuturesApi, self).__init__()
self.secretKey = '' # 密码
self.ws_contract = None # websocket应用对象 期货对象
#-----------------------------------------------------------------------
def connect_Contract(self, apiKey , secretKey , trace = False):
self.host = OKEX_USD_CONTRACT
self.apiKey = apiKey
self.secretKey = secretKey
websocket.enableTrace(trace)
self.ws_contract = websocket.WebSocketApp(self.host,
on_message=self.onMessage,
on_error=self.onError,
on_close=self.onClose,
on_open=self.onOpen)
self.thread = Thread(target=self.ws_contract.run_forever)
self.thread.start()
#-----------------------------------------------------------------------
#----------------------------------------------------------------------
def onMessage(self, ws, evt):
"""信息推送"""
print evt
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def onError(self, ws, evt): def subsribeFuturesTicker(self, symbol, contractType):
"""错误推送""" """订阅期货行情"""
print 'onError' channel ='ok_sub_futureusd_%s_ticker_%s' %(symbol, contractType)
print evt self.sendDataRequest(channel)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def onClose(self, ws): def subscribeFuturesKline(self, symbol, contractType, period):
"""接口断开""" """订阅期货K线"""
print 'onClose' channel = 'ok_sub_futureusd_%s_kline_%s_%s' %(symbol, contractType, period)
self.sendDataRequest(channel)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def onOpen(self, ws): def subscribeFuturesDepth(self, symbol, contractType):
"""接口打开""" """订阅期货深度"""
print 'onOpen' channel = 'ok_sub_future_%s_depth_%s_usd' %(symbol, contractType)
self.sendDataRequest(channel)
def subsribeFutureTicker(self, symbol , contract_type):
req = "{'event':'addChannel','channel':'ok_sub_futureusd_%s_ticker_%s'}" % (symbol , contract_type)
self.ws_contract.send(req)
def subscribeFutureKline(self, symbol , contract_type , time_period):
req = "{'event':'addChannel','channel':'ok_sub_futureusd_%s_kline_%s_%s'}" % (symbol , contract_type , time_period)
self.ws_contract.send(req)
def subscribeFutureDepth(self, symbol , contract_type):
req = "{'event':'addChannel','channel':'ok_sub_future_%s_depth_%s_usd'}" % (symbol , contract_type )
self.ws_contract.send(req)
def subscribeFutureDepth20(self, symbol , contract_type):
req = "{'event':'addChannel','channel':'ok_sub_futureusd_%s_depth_%s_20'}" % (symbol , contract_type)
self.ws_contract.send(req)
def subscribeFutureTrades(self, symbol , contract_type):
req = "{'event':'addChannel','channel':'ok_sub_futureusd_%s_trade_%s'}" % (symbol , contract_type)
self.ws_contract.send(req)
def subscribeFutureIndex(self, symbol ):
req = "{'event':'addChannel','channel':'ok_sub_futureusd_%s_index'}" % (symbol)
self.ws_contract.send(req)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def generateSign(self, params): def subscribeFuturesTrades(self, symbol, contractType):
"""生成签名""" """订阅期货成交"""
l = [] channel = 'ok_sub_futureusd_%s_trade_%s' %(symbol, contractType)
for key in sorted(params.keys()): self.sendDataRequest(channel)
l.append('%s=%s' %(key, params[key]))
l.append('secret_key=%s' %self.secretKey)
sign = '&'.join(l)
return hashlib.md5(sign.encode('utf-8')).hexdigest().upper()
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def sendTradingRequest(self, channel, params): def subscribeFuturesIndex(self, symbol):
"""发送交易请求""" """订阅期货指数"""
# 在参数字典中加上api_key和签名字段 channel = 'ok_sub_futureusd_%s_index' %symbol
params['api_key'] = self.apiKey self.sendDataRequest(channel)
params['sign'] = self.generateSign(params)
# 生成请求
d = {}
d['event'] = 'addChannel'
d['channel'] = channel
d['parameters'] = params
# 使用json打包并发送
j = json.dumps(d)
# 若触发异常则重连
try:
self.ws_contract.send(j)
except websocket.WebSocketConnectionClosedException:
pass
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def login(self): def futuresTrade(self, symbol, contractType, type_, price, amount, matchPrice='0', leverRate='10'):
params = {}
params['api_key'] = self.apiKey
params['sign'] = self.generateSign(params)
# 生成请求
d = {}
d['event'] = 'login'
d['parameters'] = params
# 使用json打包并发送
j = json.dumps(d)
# 若触发异常则重连
try:
self.ws_contract.send(j)
except websocket.WebSocketConnectionClosedException:
pass
#----------------------------------------------------------------------
def futureTrade(self, symbol_pair, contract_type ,type_, price, amount , _match_price = '0' , _lever_rate = '10'):
"""期货委托""" """期货委托"""
params = {} params = {}
params['symbol'] = str(symbol_pair) params['symbol'] = str(symbol)
params['contract_type'] = str(contract_type) params['contract_type'] = str(contractType)
params['price'] = str(price) params['price'] = str(price)
params['amount'] = str(amount) params['amount'] = str(amount)
params['type'] = type_ # 1:开多 2:开空 3:平多 4:平空 params['type'] = type_ # 1:开多 2:开空 3:平多 4:平空
params['match_price'] = _match_price # 是否为对手价: 0:不是 1:是 当取值为1时,price无效 params['match_price'] = matchPrice # 是否为对手价: 0:不是 1:是 当取值为1时,price无效
params['lever_rate'] = _lever_rate params['lever_rate'] = leverRate
channel = 'ok_futureusd_trade' channel = 'ok_futureusd_trade'
self.sendTradingRequest(channel, params) self.sendTradingRequest(channel, params)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def futureCancelOrder(self, symbol_pair, orderid , contract_type): def futuresCancelOrder(self, symbol, orderid, contractType):
"""期货撤单""" """期货撤单"""
params = {} params = {}
params['symbol'] = str(symbol_pair) params['symbol'] = str(symbol)
params['order_id'] = str(orderid) params['order_id'] = str(orderid)
params['contract_type'] = str(contract_type) params['contract_type'] = str(contractType)
channel = 'ok_futureusd_cancel_order' channel = 'ok_futureusd_cancel_order'
self.sendTradingRequest(channel, params) self.sendTradingRequest(channel, params)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def futureUserInfo(self): def futuresUserInfo(self):
"""查询期货账户""" """查询期货账户"""
channel = 'ok_futureusd_userinfo' channel = 'ok_futureusd_userinfo'
self.sendTradingRequest(channel, {}) self.sendTradingRequest(channel, {})
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def futureOrderInfo(self , symbol_pair , order_id , contract_type , status , current_page , page_length = 10): def futuresOrderInfo(self, symbol, orderid, contractType, status, current_page, page_length=10):
"""查询期货委托""" """查询期货委托"""
params = {} params = {}
params['symbol'] = str(symbol_pair) params['symbol'] = str(symbol)
params['order_id'] = str(order_id) params['order_id'] = str(orderid)
params['contract_type'] = str(contract_type) params['contract_type'] = str(contractType)
params['status'] = str(status) params['status'] = str(status)
params['current_page'] = str(current_page) params['current_page'] = str(current_page)
params['page_length'] = str(page_length) params['page_length'] = str(page_length)
@ -443,21 +392,19 @@ class OKEX_Contract_Api(object):
self.sendTradingRequest(channel, params) self.sendTradingRequest(channel, params)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def subscribeFutureTrades( self): def subscribeFuturesTrades( self):
channel = 'ok_sub_futureusd_trades' channel = 'ok_sub_futureusd_trades'
self.sendTradingRequest(channel, {}) self.sendTradingRequest(channel, {})
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def subscribeFutureUserInfo(self): def subscribeFuturesUserInfo(self):
"""订阅期货账户信息""" """订阅期货账户信息"""
channel = 'ok_sub_futureusd_userinfo' channel = 'ok_sub_futureusd_userinfo'
self.sendTradingRequest(channel, {}) self.sendTradingRequest(channel, {})
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def subscribeFuturePositions(self): def subscribeFuturesPositions(self):
"""订阅期货持仓信息""" """订阅期货持仓信息"""
channel = 'ok_sub_futureusd_positions' channel = 'ok_sub_futureusd_positions'
self.sendTradingRequest(channel, {}) self.sendTradingRequest(channel, {})