diff --git a/vnpy/api/okexfuture/OkexFutureApi.py b/vnpy/api/okexfuture/OkexFutureApi.py index b6d801c9..1fc96cbb 100644 --- a/vnpy/api/okexfuture/OkexFutureApi.py +++ b/vnpy/api/okexfuture/OkexFutureApi.py @@ -1,7 +1,7 @@ # encoding: UTF-8 from typing import Any, Callable, List, Union -from vnpy.api.okexfuture.vnokexFuture import OkexFutureRestBase +from vnpy.api.okexfuture.vnokexFuture import OkexFutureRestBase, OkexFutureWebSocketBase from vnpy.api.rest import Request @@ -424,11 +424,21 @@ class OkexFutureRestClient(OkexFutureRestBase): #--------------------------------------------------------------------- @staticmethod def errorCodeToString(code): - assert code in errorCodeMap - return errorCodeMap[code] + assert code in restErrorCodeMap + return restErrorCodeMap[code] -errorCodeMap = { +#---------------------------------------------------------------------- +class OkexFutureWebSocketApi(OkexFutureWebSocketBase): + + def subscribe(self, packet): + pass + + def onPacket(self, packet): + pass + + +restErrorCodeMap = { 0: '远程服务器并未给出错误代码', 20001: '用户不存在', @@ -473,3 +483,104 @@ errorCodeMap = { 21026: '您的账户已被限制开仓操作', 20119: '接口已下线或无法使用', } + +webSocketErrorCodeMap = { + 10000: '必填参数为空', + 10001: '参数错误', + 10002: '验证失败', + 10003: '该连接已经请求了其他用户的实时交易数据', + 10004: '该连接没有请求此用户的实时交易数据', + 10005: 'api_key或者sign不合法', + 10008: '非法参数', + 10009: '订单不存在', + 10010: '余额不足', + 10011: '卖的数量小于BTC/LTC最小买卖额度', + 10012: '当前网站暂时只支持btc_usd ltc_usd', + 10014: '下单价格不得≤0或≥1000000', + 10015: '暂不支持此channel订阅', + 10016: '币数量不足', + 10017: 'WebSocket鉴权失败', + 10100: '用户被冻结', + 10049: '小额委托(<0.15BTC)的未成交委托数量不得大于50个', + 10216: '非开放API', + 20001: '用户不存在', + 20002: '用户被冻结', + 20003: '用户被爆仓冻结', + 20004: '合约账户被冻结', + 20005: '用户合约账户不存在', + 20006: '必填参数为空', + 20007: '参数错误', + 20008: '合约账户余额为空', + 20009: '虚拟合约状态错误', + 20010: '合约风险率信息不存在', + 20011: '开仓前保证金率超过90%', + 20012: '开仓后保证金率超过90%', + 20013: '暂无对手价', + 20014: '系统错误', + 20015: '订单信息不存在', + 20016: '平仓数量是否大于同方向可用持仓数量', + 20017: '非本人操作', + 20018: '下单价格高于前一分钟的105%或低于95%', + 20019: '该IP限制不能请求该资源', + 20020: '密钥不存在', + 20021: '指数信息不存在', + 20022: '接口调用错误', + 20023: '逐仓用户', + 20024: 'sign签名不匹配', + 20025: '杠杆比率错误', + 20100: '请求超时', + 20101: '数据格式无效', + 20102: '登录无效', + 20103: '数据事件类型无效', + 20104: '数据订阅类型无效', + 20107: 'JSON格式错误', + 20115: 'quote参数未匹配到', + 20116: '参数不匹配', + 1002: '交易金额大于余额', + 1003: '交易金额小于最小交易值', + 1004: '交易金额小于0', + 1007: '没有交易市场信息', + 1008: '没有最新行情信息', + 1009: '没有订单', + 1010: '撤销订单与原订单用户不一致', + 1011: '没有查询到该用户', + 1013: '没有订单类型', + 1014: '没有登录', + 1015: '没有获取到行情深度信息', + 1017: '日期参数错误', + 1018: '下单失败', + 1019: '撤销订单失败', + 1024: '币种不存在', + 1025: '没有K线类型', + 1026: '没有基准币数量', + 1027: '参数不合法可能超出限制', + 1028: '保留小数位失败', + 1029: '正在准备中', + 1030: '有融资融币无法进行交易', + 1031: '转账余额不足', + 1032: '该币种不能转账', + 1035: '密码不合法', + 1036: '谷歌验证码不合法', + 1037: '谷歌验证码不正确', + 1038: '谷歌验证码重复使用', + 1039: '短信验证码输错限制', + 1040: '短信验证码不合法', + 1041: '短信验证码不正确', + 1042: '谷歌验证码输错限制', + 1043: '登陆密码不允许与交易密码一致', + 1044: '原密码错误', + 1045: '未设置二次验证', + 1046: '原密码未输入', + 1048: '用户被冻结', + 1050: '订单已撤销或者撤销中', + 1051: '订单已完成交易', + 1201: '账号零时删除', + 1202: '账号不存在', + 1203: '转账金额大于余额', + 1204: '不同种币种不能转账', + 1205: '账号不存在主从关系', + 1206: '提现用户被冻结', + 1207: '不支持转账', + 1208: '没有该转账用户', + 1209: '当前api不可用', +} diff --git a/vnpy/api/okexfuture/vnokexFuture.py b/vnpy/api/okexfuture/vnokexFuture.py index 0b3a7e2e..eb5f125e 100644 --- a/vnpy/api/okexfuture/vnokexFuture.py +++ b/vnpy/api/okexfuture/vnokexFuture.py @@ -1,8 +1,10 @@ # encoding: UTF-8 import hashlib import urllib +from abc import abstractmethod from vnpy.api.rest import Request, RestClient +from vnpy.api.websocket import WebSocketClient #---------------------------------------------------------------------- @@ -48,3 +50,38 @@ class OkexFutureRestBase(RestClient): req.headers = {'Content-Type': 'application/x-www-form-urlencoded'} req.data = data return req + + +######################################################################## +class OkexFutureWebSocketBase(WebSocketClient): + """ + Okex期货websocket客户端 + 实例化后使用init设置apiKey和secretKey(apiSecret) + """ + host = 'wss://real.okex.com:10440/websocket/okexapi' + + def __init__(self): + super(OkexFutureWebSocketBase, self).__init__() + self.apiKey = None + self.apiSecret = None + + #---------------------------------------------------------------------- + # noinspection PyMethodOverriding + def init(self, apiKey, secretKey): + super(OkexFutureWebSocketBase, self).init(self.host) + + self.apiKey = apiKey + self.apiSecret = secretKey + + #---------------------------------------------------------------------- + def sendPacket(self, dictObj, authenticate=False): + if authenticate: + data = urllib.urlencode(sorted(dictObj.items())) + signature = sign(data, self.apiSecret) + dictObj['sign'] = signature + return super(OkexFutureWebSocketBase, self).sendPacket(dictObj) + + #---------------------------------------------------------------------- + @abstractmethod + def onPacket(self, packet): + pass diff --git a/vnpy/api/websocket/WebSocketClient.py b/vnpy/api/websocket/WebSocketClient.py index 1ae22dae..dd29a738 100644 --- a/vnpy/api/websocket/WebSocketClient.py +++ b/vnpy/api/websocket/WebSocketClient.py @@ -49,6 +49,7 @@ class WebSocketClient(object): def setCreateConnection(self, func): """ for internal usage + :param func: a function like websocket.create_connection """ self.createConnection = func