vnpy/beta/api/okex/vnokex.py

412 lines
14 KiB
Python

# encoding: UTF-8
import hashlib
import zlib
import json
from time import sleep
from threading import Thread
import websocket
# OKEX网站
OKEX_USD_SPOT = 'wss://real.okex.com:10441/websocket' # OKEX 现货地址
OKEX_USD_CONTRACT = 'wss://real.okex.com:10440/websocket/okexapi' # OKEX 期货地址
SPOT_CURRENCY = ["usdt",
"btc",
"ltc",
"eth",
"etc",
"bch"]
SPOT_SYMBOL = ["ltc_btc",
"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"]
KLINE_PERIOD = ["1min",
"3min",
"5min",
"15min",
"30min",
"1hour",
"2hour",
"4hour",
"6hour",
"12hour",
"day",
"3day",
"week"]
CONTRACT_SYMBOL = ["btc",
"ltc",
"eth",
"etc",
"bch"]
CONTRACT_TYPE = ["this_week",
"next_week",
"quarter"]
########################################################################
class OkexApi(object):
"""交易接口"""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
self.host = '' # 服务器
self.apiKey = '' # 用户名
self.secretKey = '' # 密码
self.ws = None # websocket应用对象 现货对象
self.thread = None # 初始化线程
#----------------------------------------------------------------------
def reconnect(self):
"""重新连接"""
# 首先关闭之前的连接
self.close()
# 再执行重连任务
self.ws = 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.run_forever)
self.thread.start()
#----------------------------------------------------------------------
def connect(self, apiKey, secretKey, trace=False):
self.host = OKEX_USD_SPOT
self.apiKey = apiKey
self.secretKey = secretKey
websocket.enableTrace(trace)
self.ws = 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.run_forever)
self.thread.start()
#----------------------------------------------------------------------
def readData(self, evt):
"""解码推送收到的数据"""
data = json.loads(evt)
return data
#----------------------------------------------------------------------
def close(self):
"""关闭接口"""
if self.thread and self.thread.isAlive():
self.ws.close()
self.thread.join()
#----------------------------------------------------------------------
def onMessage(self, ws, evt):
"""信息推送"""
print evt
#----------------------------------------------------------------------
def onError(self, ws, evt):
"""错误推送"""
print 'onError'
print evt
#----------------------------------------------------------------------
def onClose(self, ws):
"""接口断开"""
print 'onClose'
#----------------------------------------------------------------------
def onOpen(self, ws):
"""接口打开"""
print 'onOpen'
#----------------------------------------------------------------------
def generateSign(self, params):
"""生成签名"""
l = []
for key in sorted(params.keys()):
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):
"""发送交易请求"""
# 在参数字典中加上api_key和签名字段
params['api_key'] = self.apiKey
params['sign'] = self.generateSign(params)
# 生成请求
d = {}
d['event'] = 'addChannel'
d['channel'] = channel
d['parameters'] = params
# 使用json打包并发送
j = json.dumps(d)
# 若触发异常则重连
try:
self.ws.send(j)
except websocket.WebSocketConnectionClosedException:
pass
#----------------------------------------------------------------------
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, period)
self.sendDataRequest(channel)
#----------------------------------------------------------------------
def spotTrade(self, symbol, type_, price, amount):
"""现货委托"""
params = {}
params['symbol'] = str(symbol)
params['type'] = str(type_)
params['price'] = str(price)
params['amount'] = str(amount)
channel = 'ok_spot_order'
self.sendTradingRequest(channel, params)
#----------------------------------------------------------------------
def spotCancelOrder(self, symbol, orderid):
"""现货撤单"""
params = {}
params['symbol'] = str(symbol)
params['order_id'] = str(orderid)
channel = 'ok_spot_cancel_order'
self.sendTradingRequest(channel, params)
#----------------------------------------------------------------------
def spotUserInfo(self):
"""查询现货账户"""
channel = 'ok_spot_userinfo'
self.sendTradingRequest(channel, {})
#----------------------------------------------------------------------
def spotOrderInfo(self, symbol, orderid):
"""查询现货委托信息"""
params = {}
params['symbol'] = str(symbol)
params['order_id'] = str(orderid)
channel = 'ok_spot_orderinfo'
self.sendTradingRequest(channel, params)
########################################################################
class OkexFuturesApi(OkexApi):
"""期货交易接口
交割推送信息:
[{
"channel": "btc_forecast_price",
"timestamp":"1490341322021",
"data": "998.8"
}]
data(string): 预估交割价格
timestamp(string): 时间戳
无需订阅,交割前一小时自动返回
"""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
super(OkexFuturesApi, self).__init__()
#----------------------------------------------------------------------
def subsribeFuturesTicker(self, symbol, contractType):
"""订阅期货行情"""
channel ='ok_sub_futureusd_%s_ticker_%s' %(symbol, contractType)
self.sendDataRequest(channel)
#----------------------------------------------------------------------
def subscribeFuturesKline(self, symbol, contractType, period):
"""订阅期货K线"""
channel = 'ok_sub_futureusd_%s_kline_%s_%s' %(symbol, contractType, period)
self.sendDataRequest(channel)
#----------------------------------------------------------------------
def subscribeFuturesDepth(self, symbol, contractType, depth=0):
"""订阅期货深度"""
channel = 'ok_sub_futureusd_%s_depth_%s' %(symbol, contractType)
if depth:
channel = channel + '_' + str(depth)
self.sendDataRequest(channel)
#----------------------------------------------------------------------
def subscribeFuturesTrades(self, symbol, contractType):
"""订阅期货成交"""
channel = 'ok_sub_futureusd_%s_trade_%s' %(symbol, contractType)
self.sendDataRequest(channel)
#----------------------------------------------------------------------
def subscribeFuturesIndex(self, symbol):
"""订阅期货指数"""
channel = 'ok_sub_futureusd_%s_index' %symbol
self.sendDataRequest(channel)
#----------------------------------------------------------------------
def futuresTrade(self, symbol, contractType, type_, price, amount, matchPrice='0', leverRate='10'):
"""期货委托"""
params = {}
params['symbol'] = str(symbol)
params['contract_type'] = str(contractType)
params['price'] = str(price)
params['amount'] = str(amount)
params['type'] = type_ # 1:开多 2:开空 3:平多 4:平空
params['match_price'] = matchPrice # 是否为对手价: 0:不是 1:是 当取值为1时,price无效
params['lever_rate'] = leverRate
channel = 'ok_futureusd_trade'
self.sendTradingRequest(channel, params)
#----------------------------------------------------------------------
def futuresCancelOrder(self, symbol, orderid, contractType):
"""期货撤单"""
params = {}
params['symbol'] = str(symbol)
params['order_id'] = str(orderid)
params['contract_type'] = str(contractType)
channel = 'ok_futureusd_cancel_order'
self.sendTradingRequest(channel, params)
#----------------------------------------------------------------------
def futuresUserInfo(self):
"""查询期货账户"""
channel = 'ok_futureusd_userinfo'
self.sendTradingRequest(channel, {})
#----------------------------------------------------------------------
def futuresOrderInfo(self, symbol, orderid, contractType, status, current_page, page_length=10):
"""查询期货委托"""
params = {}
params['symbol'] = str(symbol)
params['order_id'] = str(orderid)
params['contract_type'] = str(contractType)
params['status'] = str(status)
params['current_page'] = str(current_page)
params['page_length'] = str(page_length)
channel = 'ok_futureusd_orderinfo'
self.sendTradingRequest(channel, params)
#----------------------------------------------------------------------
def subscribeFuturesTrades( self):
channel = 'ok_sub_futureusd_trades'
self.sendTradingRequest(channel, {})
#----------------------------------------------------------------------
def subscribeFuturesUserInfo(self):
"""订阅期货账户信息"""
channel = 'ok_sub_futureusd_userinfo'
self.sendTradingRequest(channel, {})
#----------------------------------------------------------------------
def subscribeFuturesPositions(self):
"""订阅期货持仓信息"""
channel = 'ok_sub_futureusd_positions'
self.sendTradingRequest(channel, {})