diff --git a/beta/api/okex/README.md b/beta/api/okex/README.md deleted file mode 100644 index f98f155c..00000000 --- a/beta/api/okex/README.md +++ /dev/null @@ -1,14 +0,0 @@ -### 简介 - -OKEX的比特币交易接口,基于Websocket API开发,实现了以下功能: - -1. 发送、撤销委托 - -2. 查询委托、持仓、资金、成交历史 - -3. 实时行情、成交、资金更新的推送 - -### API信息 - -链接:[https://www.okex.com/ws_getStarted.html](https://www.okex.com/ws_getStarted.html) - diff --git a/beta/api/okex/__init__.py b/beta/api/okex/__init__.py deleted file mode 100644 index a0b1b632..00000000 --- a/beta/api/okex/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# encoding: UTF-8 - -from __future__ import absolute_import -from .vnokex import OkexSpotApi, OkexFuturesApi, CONTRACT_SYMBOL, SPOT_CURRENCY \ No newline at end of file diff --git a/beta/api/okex/test.py b/beta/api/okex/test.py deleted file mode 100644 index 2e20cb82..00000000 --- a/beta/api/okex/test.py +++ /dev/null @@ -1,52 +0,0 @@ -# encoding: UTF-8 - -from __future__ import absolute_import -from .vnokex import * - -# 在OkCoin网站申请这两个Key,分别对应用户名和密码 -apiKey = '你的accessKey' -secretKey = '你的secretKey' - -# 创建API对象 -api = OkexSpotApi() - -api.connect(apiKey, secretKey, True) - -sleep(3) - -#api.login() -api.subscribeSpotTicker("bch_btc") -api.subscribeSpotDepth("bch_btc") -api.subscribeSpotDepth("bch_btc", 5) -api.subscribeSpotDeals("bch_btc") -api.subscribeSpotKlines("bch_btc","30min") - -#api.spotTrade("etc_usdt","sell", "50" , "0.01") -#api.spotCancelOrder("etc_btc","44274138") -#api.spotUserInfo() -#api.spotOrderInfo("etc_btc", 44284731) - -# api = OkexFuturesApi() -# api.connect(apiKey, secretKey, True) - -# sleep(3) -#api.subsribeFutureTicker("btc","this_week") -#api.subscribeFutureKline("btc","this_week", "30min") -#api.subscribeFutureDepth("btc","this_week") -#api.subscribeFutureDepth("btc","this_week", 5) -#api.subscribeFutureTrades("btc","this_week") -#api.subscribeFutureIndex("btc") -#api.subscribeFutureForecast_price("btc") - -#api.login() -#api.futureTrade( "etc_usd", "this_week" ,"1" , 20 , 1 , _match_price = '0' , _lever_rate = '10') # 14245727693 -#api.futureCancelOrder("etc_usd","14245727693" , "this_week") -#api.futureUserInfo() -#api.futureOrderInfo("etc_usd" , "14245727693" , "this_week" , '1', '1' , '10') -# api.subscribeFutureTrades() - -''' -合约账户信息、 持仓信息等,在登录后都会自动推送。。。官方文档这样写的,还没实际验证过 -''' - -input() \ No newline at end of file diff --git a/beta/api/okex/vnokex.py b/beta/api/okex/vnokex.py deleted file mode 100644 index 18267b97..00000000 --- a/beta/api/okex/vnokex.py +++ /dev/null @@ -1,413 +0,0 @@ -# encoding: UTF-8 - -from __future__ import print_function -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, {}) - \ No newline at end of file diff --git a/beta/gateway/okexGateway/OKEX_connect.json b/beta/gateway/okexGateway/OKEX_connect.json deleted file mode 100644 index a0224e4c..00000000 --- a/beta/gateway/okexGateway/OKEX_connect.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "apiKey": "你的apiKey", - "secretKey": "你的secretKey", - "trace": false, - "leverage": 10 -} \ No newline at end of file diff --git a/beta/gateway/okexGateway/__init__.py b/beta/gateway/okexGateway/__init__.py deleted file mode 100644 index bafb2366..00000000 --- a/beta/gateway/okexGateway/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# encoding: UTF-8 - -from __future__ import absolute_import -from vnpy.trader import vtConstant -from .okexGateway import okexGateway - -gatewayClass = okexGateway -gatewayName = 'OKEX' -gatewayDisplayName = u'OKEX' -gatewayType = vtConstant.GATEWAYTYPE_BTC -gatewayQryEnabled = True - diff --git a/beta/gateway/okexGateway/okexGateway.py b/beta/gateway/okexGateway/okexGateway.py deleted file mode 100644 index ba8deb48..00000000 --- a/beta/gateway/okexGateway/okexGateway.py +++ /dev/null @@ -1,965 +0,0 @@ -# encoding: UTF-8 - -''' -vnpy.api.okex的gateway接入 - -注意: -1. 目前仅支持USD现货交易 -''' -from __future__ import print_function - -import os -import json -from datetime import datetime -from time import sleep -from copy import copy -from threading import Condition -from Queue import Queue -from threading import Thread -from time import sleep - -from vnpy.api.okex import OkexSpotApi, CONTRACT_SYMBOL, SPOT_CURRENCY -from vnpy.trader.vtGateway import * -from vnpy.trader.vtFunction import getJsonPath - -# 价格类型映射 -# 买卖类型: 限价单(buy/sell) 市价单(buy_market/sell_market) -priceTypeMap = {} -priceTypeMap['buy'] = (DIRECTION_LONG, PRICETYPE_LIMITPRICE) -priceTypeMap['buy_market'] = (DIRECTION_LONG, PRICETYPE_MARKETPRICE) -priceTypeMap['sell'] = (DIRECTION_SHORT, PRICETYPE_LIMITPRICE) -priceTypeMap['sell_market'] = (DIRECTION_SHORT, PRICETYPE_MARKETPRICE) -priceTypeMapReverse = {v: k for k, v in priceTypeMap.items()} - -# 委托状态印射 -statusMap = {} -statusMap[-1] = STATUS_CANCELLED -statusMap[0] = STATUS_NOTTRADED -statusMap[1] = STATUS_PARTTRADED -statusMap[2] = STATUS_ALLTRADED -statusMap[4] = STATUS_UNKNOWN - - -okex_all_symbol_pairs = ['ref_usdt', 'soc_usdt', 'light_usdt', 'avt_usdt', 'of_usdt', 'brd_usdt', 'ast_usdt', 'int_usdt', 'zrx_usdt', 'ctr_usdt', 'dgd_usdt', 'aidoc_usdt', 'wtc_usdt', 'swftc_usdt', 'wrc_usdt', 'sub_usdt', 'dna_usdt', 'knc_usdt', 'kcash_usdt', 'mdt_usdt', 'theta_usdt', 'ppt_usdt', 'utk_usdt', 'qvt_usdt', 'salt_usdt', 'la_usdt', 'itc_usdt', 'fair_usdt', 'yee_usdt', '1st_usdt', 'fun_usdt', 'iost_usdt', 'mkr_usdt', 'tio_usdt', 'req_usdt', 'ubtc_usdt', 'icx_usdt', 'tct_usdt', 'san_usdt', 'lrc_usdt', 'icn_usdt', 'cvc_usdt', 'eth_usdt', 'poe_usdt', 'xlm_usdt', 'iota_usdt', 'eos_usdt', 'nuls_usdt', 'mot_usdt', 'neo_usdt', 'gnx_usdt', 'dgb_usdt', 'evx_usdt', 'ltc_usdt', 'mda_usdt', 'etc_usdt', 'dpy_usdt', 'tnb_usdt', 'nas_usdt', 'btc_usdt', 'smt_usdt', 'ssc_usdt', 'oax_usdt', 'yoyo_usdt', 'snc_usdt', 'sngls_usdt', 'bch_usdt', 'mana_usdt', 'mof_usdt', 'mco_usdt', 'vib_usdt', 'topc_usdt', 'pra_usdt', 'bnt_usdt', 'xmr_usdt', 'edo_usdt', 'snt_usdt', 'eng_usdt', 'stc_usdt', 'qtum_usdt', 'key_usdt', 'ins_usdt', 'rnt_usdt', 'bcd_usdt', 'amm_usdt', 'lend_usdt', 'btm_usdt', 'elf_usdt', 'xuc_usdt', 'cag_usdt', 'snm_usdt', 'act_usdt', 'dash_usdt', 'zec_usdt', 'storj_usdt', 'pay_usdt', 'vee_usdt', 'show_usdt', 'trx_usdt', 'atl_usdt', 'ark_usdt', 'ost_usdt', 'gnt_usdt', 'dat_usdt', 'rcn_usdt', 'qun_usdt', 'mth_usdt', 'rct_usdt', 'read_usdt', 'gas_usdt', 'btg_usdt', 'mtl_usdt', 'cmt_usdt', 'xrp_usdt', 'spf_usdt', 'aac_usdt', 'can_usdt', 'omg_usdt', 'hsr_usdt', 'link_usdt', 'dnt_usdt', 'true_usdt', 'ukg_usdt', 'xem_usdt', 'ngc_usdt', 'lev_usdt', 'rdn_usdt', 'ace_usdt', 'ipc_usdt', 'ugc_usdt', 'viu_usdt', 'mag_usdt', 'hot_usdt', 'pst_usdt', -'ref_btc', 'soc_btc', 'light_btc', 'avt_btc', 'of_btc', 'brd_btc', 'ast_btc', 'int_btc', 'zrx_btc', 'ctr_btc', 'dgd_btc', 'aidoc_btc', 'wtc_btc', 'swftc_btc', 'wrc_btc', 'sub_btc', 'dna_btc', 'knc_btc', 'kcash_btc', 'mdt_btc', 'theta_btc', 'ppt_btc', 'utk_btc', 'qvt_btc', 'salt_btc', 'la_btc', 'itc_btc', 'fair_btc', 'yee_btc', '1st_btc', 'fun_btc', 'iost_btc', 'mkr_btc', 'tio_btc', 'req_btc', 'ubtc_btc', 'icx_btc', 'tct_btc', 'san_btc', 'lrc_btc', 'icn_btc', 'cvc_btc', 'eth_btc', 'poe_btc', 'xlm_btc', 'iota_btc', 'eos_btc', 'nuls_btc', 'mot_btc', 'neo_btc', 'gnx_btc', 'dgb_btc', 'evx_btc', 'ltc_btc', 'mda_btc', 'etc_btc', 'dpy_btc', 'tnb_btc', 'nas_btc', 'btc_btc', 'smt_btc', 'ssc_btc', 'oax_btc', 'yoyo_btc', 'snc_btc', 'sngls_btc', 'bch_btc', 'mana_btc', 'mof_btc', 'mco_btc', 'vib_btc', 'topc_btc', 'pra_btc', 'bnt_btc', 'xmr_btc', 'edo_btc', 'snt_btc', 'eng_btc', 'stc_btc', 'qtum_btc', 'key_btc', 'ins_btc', 'rnt_btc', 'bcd_btc', 'amm_btc', 'lend_btc', 'btm_btc', 'elf_btc', 'xuc_btc', 'cag_btc', 'snm_btc', 'act_btc', 'dash_btc', 'zec_btc', 'storj_btc', 'pay_btc', 'vee_btc', 'show_btc', 'trx_btc', 'atl_btc', 'ark_btc', 'ost_btc', 'gnt_btc', 'dat_btc', 'rcn_btc', 'qun_btc', 'mth_btc', 'rct_btc', 'read_btc', 'gas_btc', 'btg_btc', 'mtl_btc', 'cmt_btc', 'xrp_btc', 'spf_btc', 'aac_btc', 'can_btc', 'omg_btc', 'hsr_btc', 'link_btc', 'dnt_btc', 'true_btc', 'ukg_btc', 'xem_btc', 'ngc_btc', 'lev_btc', 'rdn_btc', 'ace_btc', 'ipc_btc', 'ugc_btc', 'viu_btc', 'mag_btc', 'hot_btc', 'pst_btc'] - - -######################################################################## -class OkexGateway(VtGateway): - """OKEX交易接口""" - - #---------------------------------------------------------------------- - def __init__(self, eventEngine, gatewayName='OKEX'): - """Constructor""" - super(OkexGateway, self).__init__(eventEngine, gatewayName) - - self.api_spot = SpotApi(self) - # self.api_contract = Api_contract(self) - - self.leverage = 0 - self.connected = False - - self.fileName = self.gatewayName + '_connect.json' - self.filePath = getJsonPath(self.fileName, __file__) - - #---------------------------------------------------------------------- - def connect(self): - """连接""" - # 载入json文件 - try: - f = file(self.filePath) - except IOError: - log = VtLogData() - log.gatewayName = self.gatewayName - log.logContent = u'读取连接配置出错,请检查' - self.onLog(log) - return - - # 解析json文件 - setting = json.load(f) - try: - apiKey = str(setting['apiKey']) - secretKey = str(setting['secretKey']) - trace = setting['trace'] - leverage = setting['leverage'] - except KeyError: - log = VtLogData() - log.gatewayName = self.gatewayName - log.logContent = u'连接配置缺少字段,请检查' - self.onLog(log) - return - - # 初始化接口 - self.leverage = leverage - - self.api_spot.active = True - self.api_spot.connect(apiKey, secretKey, trace) - - log = VtLogData() - log.gatewayName = self.gatewayName - log.logContent = u'接口初始化成功' - self.onLog(log) - - # 启动查询 - # self.initQuery() - # self.startQuery() - - #---------------------------------------------------------------------- - def subscribe(self, subscribeReq): - """订阅行情""" - self.api_spot.subscribe(subscribeReq) - - #---------------------------------------------------------------------- - def sendOrder(self, orderReq): - """发单""" - return self.api_spot.spotSendOrder(orderReq) - - #---------------------------------------------------------------------- - def cancelOrder(self, cancelOrderReq): - """撤单""" - self.api_spot.spotCancel(cancelOrderReq) - - #---------------------------------------------------------------------- - def qryAccount(self): - """查询账户资金""" - self.api_spot.spotUserInfo() - - #---------------------------------------------------------------------- - def qryOrderInfo(self): - self.api_spot.spotAllOrders() - - #---------------------------------------------------------------------- - def qryPosition(self): - """查询持仓""" - pass - - #---------------------------------------------------------------------- - def close(self): - """关闭""" - self.api_spot.active = False - self.api_spot.close() - - #---------------------------------------------------------------------- - def initQuery(self): - """初始化连续查询""" - if self.qryEnabled: - # 需要循环的查询函数列表 - #self.qryFunctionList = [self.qryAccount, self.qryOrderInfo] - self.qryFunctionList = [ self.qryOrderInfo] - #self.qryFunctionList = [] - - self.qryCount = 0 # 查询触发倒计时 - self.qryTrigger = 2 # 查询触发点 - self.qryNextFunction = 0 # 上次运行的查询函数索引 - - self.startQuery() - - #---------------------------------------------------------------------- - def query(self, event): - """注册到事件处理引擎上的查询函数""" - self.qryCount += 1 - - if self.qryCount > self.qryTrigger: - # 清空倒计时 - self.qryCount = 0 - - # 执行查询函数 - function = self.qryFunctionList[self.qryNextFunction] - function() - - # 计算下次查询函数的索引,如果超过了列表长度,则重新设为0 - self.qryNextFunction += 1 - if self.qryNextFunction == len(self.qryFunctionList): - self.qryNextFunction = 0 - - #---------------------------------------------------------------------- - def startQuery(self): - """启动连续查询""" - self.eventEngine.register(EVENT_TIMER, self.query) - - #---------------------------------------------------------------------- - def setQryEnabled(self, qryEnabled): - """设置是否要启动循环查询""" - self.qryEnabled = qryEnabled - - -######################################################################## -class SpotApi(OkexSpotApi): - """okex的API实现""" - - #---------------------------------------------------------------------- - def __init__(self, gateway): - """Constructor""" - super(SpotApi, self).__init__() - - self.gateway = gateway # gateway对象 - self.gatewayName = gateway.gatewayName # gateway对象名称 - self.active = False # 若为True则会在断线后自动重连 - - self.cbDict = {} - self.tickDict = {} - self.orderDict = {} - - self.channelSymbolMap = {} - - self.localNo = 0 # 本地委托号 - self.localNoQueue = Queue() # 未收到系统委托号的本地委托号队列 - self.localNoDict = {} # key为本地委托号,value为系统委托号 - self.orderIdDict = {} # key为系统委托号,value为本地委托号 - self.cancelDict = {} # key为本地委托号,value为撤单请求 - - self.recordOrderId_BefVolume = {} # 记录的之前处理的量 - - self.cache_some_order = {} - self.tradeID = 0 - - self.registerSymbolPairArray = set([]) - - self.initCallback() - - ''' - 登录后,每次订单执行撤销后又这样的 推送。。不知道干啥的。先过滤掉了 - {u'binary': 1, u'product': u'spot', u'type': u'order', u'base': u'etc' -, u'quote': u'usdt', u'data': {u'status': -1, u'orderType': 0, u'price': u'25.4050', u'modifyTime': -1512288275000L, u'userId': 6548935, u'createTime': 1512288275000L, u'source': 0, u'quoteSize': u'0.0 -0000000', u'executedValue': u'0.00000000', u'id': 62877909, u'filledSize': u'0.00000000', u'side': 1 -, u'size': u'0.01000000'}} - ''' - #---------------------------------------------------------------------- - def onMessage(self, ws, evt): - """信息推送""" - # print evt - - data = self.readData(evt)[0] - try: - channel = data['channel'] - except Exception as ex: - channel = None - if channel == None: - return - # try: - if channel == "addChannel" and 'data' in data: - channel = data['data']["channel"] - if channel != "addChannel" and 'future' not in channel and channel != 'login': - - # print channel - callback = self.cbDict[channel] - callback(data) - - # if 'depth' not in channel and 'ticker' not in channel and 'deals' not in channel and 'userinfo' not in channel and 'future' not in channel: - # print data - - # except Exception,ex: - # print "Error in callback cbDict ", channel - - #print self.cbDict - - #---------------------------------------------------------------------- - def onError(self, ws, evt): - """错误推送""" - error = VtErrorData() - error.gatewayName = self.gatewayName - error.errorMsg = str(evt) - self.gateway.onError(error) - - #---------------------------------------------------------------------- - def onError(self, data): - error = VtErrorData() - error.gatewayName = self.gatewayName - error.errorMsg = str(data["data"]["error_code"]) - self.gateway.onError(error) - - #---------------------------------------------------------------------- - def onClose(self, ws): - """接口断开""" - # 如果尚未连上,则忽略该次断开提示 - if not self.gateway.connected: - return - - self.gateway.connected = False - self.writeLog(u'服务器连接断开') - - # 重新连接 - if self.active: - def reconnect(): - while not self.gateway.connected: - self.writeLog(u'等待10秒后重新连接') - sleep(10) - if not self.gateway.connected: - self.reconnect() - - t = Thread(target=reconnect) - t.start() - #---------------------------------------------------------------------- - def subscribe(self, subscribeReq): - symbol_pair_gateway = subscribeReq.symbol - arr = symbol_pair_gateway.split('.') - symbol_pair = arr[0] - - if symbol_pair not in self.registerSymbolPairArray: - self.registerSymbolPairArray.add(symbol_pair) - self.subscribeSingleSymbol(symbol_pair) - - self.spotOrderInfo(symbol_pair, '-1') - - #---------------------------------------------------------------------- - def subscribeSingleSymbol(self, symbol): - if symbol in okex_all_symbol_pairs: - self.subscribeSpotTicker(symbol) - self.subscribeSpotDepth5(symbol) - #self.subscribeSpotDeals(symbol) - - #---------------------------------------------------------------------- - def spotAllOrders(self): - print(spotAllOrders) - for symbol in registerSymbolPairArray: - if symbol in okex_all_symbol_pairs: - self.spotOrderInfo(symbol, '-1') - - for orderId in self.orderIdDict.keys(): - order = self.orderDict.get(orderId, None) - if order != None: - symbol_pair = (order.symbol.split('.'))[0] - self.spotOrderInfo(symbol_pair, orderId) - - #---------------------------------------------------------------------- - def onOpen(self, ws): - """连接成功""" - self.gateway.connected = True - self.writeLog(u'服务器连接成功') - - self.login() - # 连接后查询账户和委托数据 - self.spotUserInfo() - - self.subscribeSingleSymbol("etc_usdt") - for symbol in okex_all_symbol_pairs: - # self.subscribeSpotTicker(symbol) - # self.subscribeSpotDepth5(symbol) - # self.subscribeSpotDeals(symbol) - - #Ticker数据 - self.channelSymbolMap["ok_sub_spot_%s_ticker" % symbol] = symbol - #盘口的深度 - self.channelSymbolMap["ok_sub_spot_%s_depth_5" % symbol] = symbol - #所有人的交易数据 - self.channelSymbolMap["ok_sub_spot_%s_deals" % symbol] = symbol - - contract = VtContractData() - contract.gatewayName = self.gatewayName - contract.symbol = symbol - contract.exchange = EXCHANGE_OKEX - contract.vtSymbol = '.'.join([contract.symbol, contract.exchange]) - contract.name = u'OKEX现货%s' % symbol - contract.size = 0.00001 - contract.priceTick = 0.00001 - contract.productClass = PRODUCT_SPOT - self.gateway.onContract(contract) - - ''' - [{ - "channel":"ok_sub_spot_bch_btc_deals", - "data":[["1001","2463.86","0.052","16:34:07","ask"]] - }] - ''' - #---------------------------------------------------------------------- - def onSpotSubDeals(self, data): - if 'data' not in data: - return - rawData = data["data"] - - # print rawData - - - #---------------------------------------------------------------------- - def writeLog(self, content): - """快速记录日志""" - log = VtLogData() - log.gatewayName = self.gatewayName - log.logContent = content - self.gateway.onLog(log) - - #---------------------------------------------------------------------- - def initCallback(self): - """初始化回调函数""" - # USD_SPOT - for symbol_pair in okex_all_symbol_pairs: - self.cbDict["ok_sub_spot_%s_ticker" % symbol_pair] = self.onTicker - self.cbDict["ok_sub_spot_%s_depth_5" % symbol_pair] = self.onDepth - self.cbDict["ok_sub_spot_%s_deals" % symbol_pair] = self.onSpotSubDeals - - self.cbDict["ok_sub_spot_%s_order" % symbol_pair] = self.onSpotSubOrder - self.cbDict["ok_sub_spot_%s_balance" % symbol_pair] = self.onSpotBalance - - self.cbDict['ok_spot_userinfo'] = self.onSpotUserInfo - self.cbDict['ok_spot_orderinfo'] = self.onSpotOrderInfo - - # 下面这两个好像废弃了 - #self.cbDict['ok_sub_spot_userinfo'] = self.onSpotSubUserInfo - #self.cbDict['ok_sub_spot_trades'] = self.onSpotSubTrades - - self.cbDict['ok_spot_order'] = self.onSpotOrder - self.cbDict['ok_spot_cancel_order'] = self.onSpotCancelOrder - - ''' - [ - { - "binary": 0, - "channel": "ok_sub_spot_bch_btc_ticker", - "data": { - "high": "10000", - "vol": "185.03743858", - "last": "111", - "low": "0.00000001", - "buy": "115", - "change": "101", - "sell": "115", - "dayLow": "0.00000001", - "dayHigh": "10000", - "timestamp": 1500444626000 - } - } - ] - ''' - #---------------------------------------------------------------------- - def onTicker(self, data): - """""" - if 'data' not in data: - return - - channel = data['channel'] - if channel == 'addChannel': - return - try: - symbol = self.channelSymbolMap[channel] - - if symbol not in self.tickDict: - tick = VtTickData() - tick.exchange = EXCHANGE_OKEX - tick.symbol = '.'.join([symbol, tick.exchange]) - tick.vtSymbol = '.'.join([symbol, tick.exchange]) - - tick.gatewayName = self.gatewayName - self.tickDict[symbol] = tick - else: - tick = self.tickDict[symbol] - - rawData = data['data'] - tick.highPrice = float(rawData['high']) - tick.lowPrice = float(rawData['low']) - tick.lastPrice = float(rawData['last']) - tick.volume = float(rawData['vol'].replace(',', '')) - # tick.date, tick.time = self.generateDateTime(rawData['timestamp']) - - # print "ticker", tick.date, tick.time - # newtick = copy(tick) - # self.gateway.onTick(newtick) - except Exception as ex: - print("Error in onTicker ", channel) - - #---------------------------------------------------------------------- - def onDepth(self, data): - """""" - if 'data' not in data: - return - try: - channel = data['channel'] - symbol = self.channelSymbolMap[channel] - except Exception as ex: - symbol = None - - if symbol == None: - return - - if symbol not in self.tickDict: - tick = VtTickData() - tick.symbol = symbol - tick.vtSymbol = symbol - tick.gatewayName = self.gatewayName - self.tickDict[symbol] = tick - else: - tick = self.tickDict[symbol] - - if 'data' not in data: - return - rawData = data['data'] - - - tick.bidPrice1, tick.bidVolume1 = rawData['bids'][0] - tick.bidPrice2, tick.bidVolume2 = rawData['bids'][1] - tick.bidPrice3, tick.bidVolume3 = rawData['bids'][2] - tick.bidPrice4, tick.bidVolume4 = rawData['bids'][3] - tick.bidPrice5, tick.bidVolume5 = rawData['bids'][4] - - tick.askPrice1, tick.askVolume1 = rawData['asks'][-1] - tick.askPrice2, tick.askVolume2 = rawData['asks'][-2] - tick.askPrice3, tick.askVolume3 = rawData['asks'][-3] - tick.askPrice4, tick.askVolume4 = rawData['asks'][-4] - tick.askPrice5, tick.askVolume5 = rawData['asks'][-5] - - tick.date, tick.time = self.generateDateTime(rawData['timestamp']) - # print "Depth", tick.date, tick.time - - newtick = copy(tick) - self.gateway.onTick(newtick) - - ''' - [ - { - "base": "bch", - "binary": 0, - "channel": "ok_sub_spot_bch_btc_balance", - "data": { - "info": { - "free": { - "btc": 5814.850605790395 - }, - "freezed": { - "btc": 7341 - } - } - }, - "product": "spot", - "quote": "btc", - "type": "order" - } - ] - ''' - def onSpotBalance(self, data): - """交易发生金额变动之后会触发这个函数""" - # print data - - rawData = data['data'] - info = rawData['info'] - - for symbol in info["freezed"].keys(): - pos = VtPositionData() - pos.gatewayName = self.gatewayName - pos.symbol = symbol + "." + EXCHANGE_OKEX - pos.vtSymbol = symbol + "." + EXCHANGE_OKEX - pos.direction = DIRECTION_NET - pos.frozen = float(info['freezed'][symbol]) - pos.position = pos.frozen + float(info['free'][symbol]) - - self.gateway.onPosition(pos) - - ''' - [{"binary":0,"channel":"ok_spot_userinfo","data":{"result":true,"info":{"funds":{"borrow":{"dgd":"0" -,"bcd":"0","bcc":"0","bch":"0","hsr":"0","xuc":"0","omg":"0","eos":"0","qtum":"0","btc":"0","act":"0 -","bcs":"0","btg":"0","etc":"0","eth":"0","usdt":"0","gas":"0","zec":"0","neo":"0","ltc":"0","bt1":" -0","bt2":"0","iota":"0","pay":"0","storj":"0","gnt":"0","snt":"0","dash":"0"},"free":{"dgd":"0","bcd -":"0","bcc":"0","bch":"0","hsr":"0","xuc":"3","omg":"0","eos":"0","qtum":"0","btc":"0.00266884258369 -","act":"0","bcs":"0","btg":"0","etc":"7.9909635","eth":"0","usdt":"0","gas":"0","zec":"0","neo":"0" -,"ltc":"0","bt1":"0","bt2":"0","iota":"0","pay":"0","storj":"0","gnt":"0","snt":"0","dash":"0"},"fre -ezed":{"dgd":"0","bcd":"0","bcc":"0","bch":"0","hsr":"0","xuc":"0","omg":"0","eos":"0","qtum":"0","b -tc":"0","act":"0","bcs":"0","btg":"0","etc":"0","eth":"0","usdt":"0","gas":"0","zec":"0","neo":"0"," -ltc":"0","bt1":"0","bt2":"0","iota":"0","pay":"0","storj":"0","gnt":"0","snt":"0","dash":"0"}}}}}] -{u'binary': 0, u'data': {u'info': {u'funds': {u'freezed': {u'zec': u'0', u'usdt': u'0', u'btg': u'0' -, u'btc': u'0', u'bt1': u'0', u'neo': u'0', u'pay': u'0', u'storj': u'0', u'iota': u'0', u'omg': u'0 -', u'dgd': u'0', u'bt2': u'0', u'xuc': u'0', u'gas': u'0', u'hsr': u'0', u'snt': u'0', u'dash': u'0' -, u'bch': u'0', u'gnt': u'0', u'bcd': u'0', u'qtum': u'0', u'bcc': u'0', u'eos': u'0', u'etc': u'0', - u'act': u'0', u'eth': u'0', u'ltc': u'0', u'bcs': u'0'}, u'borrow': {u'zec': u'0', u'usdt': u'0', u -'btg': u'0', u'btc': u'0', u'bt1': u'0', u'neo': u'0', u'pay': u'0', u'storj': u'0', u'iota': u'0', -u'omg': u'0', u'dgd': u'0', u'bt2': u'0', u'xuc': u'0', u'gas': u'0', u'hsr': u'0', u'snt': u'0', u' -dash': u'0', u'bch': u'0', u'gnt': u'0', u'bcd': u'0', u'qtum': u'0', u'bcc': u'0', u'eos': u'0', u' -etc': u'0', u'act': u'0', u'eth': u'0', u'ltc': u'0', u'bcs': u'0'}, u'free': {u'zec': u'0', u'usdt' -: u'0', u'btg': u'0', u'btc': u'0.00266884258369', u'bt1': u'0', u'neo': u'0', u'pay': u'0', u'storj -': u'0', u'iota': u'0', u'omg': u'0', u'dgd': u'0', u'bt2': u'0', u'xuc': u'3', u'gas': u'0', u'hsr' -: u'0', u'snt': u'0', u'dash': u'0', u'bch': u'0', u'gnt': u'0', u'bcd': u'0', u'qtum': u'0', u'bcc' -: u'0', u'eos': u'0', u'etc': u'7.9909635', u'act': u'0', u'eth': u'0', u'ltc': u'0', u'bcs': u'0'}} -}, u'result': True}, u'channel': u'ok_spot_userinfo'} - ''' - #---------------------------------------------------------------------- - def onSpotUserInfo(self, data): - """现货账户资金推送""" - rawData = data['data'] - info = rawData['info'] - funds = rawData['info']['funds'] - - # 持仓信息 - for symbol in ['btc', 'ltc','eth', self.currency]: - #for symbol in : - if symbol in funds['free']: - pos = VtPositionData() - pos.gatewayName = self.gatewayName - - pos.symbol = symbol + "." + EXCHANGE_OKEX - pos.vtSymbol = symbol + "." + EXCHANGE_OKEX - pos.vtPositionName = symbol - pos.direction = DIRECTION_NET - - pos.frozen = float(funds['freezed'][symbol]) - pos.position = pos.frozen + float(funds['free'][symbol]) - - self.gateway.onPosition(pos) - - # 账户资金 - account = VtAccountData() - account.gatewayName = self.gatewayName - account.accountID = self.gatewayName - account.vtAccountID = account.accountID - account.balance = 0.0 - #account.balance = float(funds['asset']['net']) - self.gateway.onAccount(account) - - #---------------------------------------------------------------------- - # 这个 API 现在文档没找到。。 好像废弃了 - def onSpotSubUserInfo(self, data): - """现货账户资金推送""" - if 'data' not in data: - return - - rawData = data['data'] - info = rawData['info'] - - # 持仓信息 - #for symbol in ['btc', 'ltc','eth', self.currency]: - for symbol in SPOT_CURRENCY: - if symbol in info['free']: - pos = VtPositionData() - pos.gatewayName = self.gatewayName - - pos.symbol = symbol + "." + EXCHANGE_OKEX - pos.vtSymbol = symbol + "." + EXCHANGE_OKEX - pos.vtPositionName = symbol - pos.direction = DIRECTION_NET - - pos.frozen = float(info['freezed'][symbol]) - pos.position = pos.frozen + float(info['free'][symbol]) - - self.gateway.onPosition(pos) - - ''' - 交易数据 - [ - { - "base": "bch", - "binary": 0, - "channel": "ok_sub_spot_bch_btc_order", - "data": { - "symbol": "bch_btc", - "tradeAmount": "1.00000000", - "createdDate": "1504530228987", - "orderId": 6191, - "completedTradeAmount": "0.00000000", - "averagePrice": "0", - "tradePrice": "0.00000000", - "tradeType": "buy", - "status": 0, - "tradeUnitPrice": "113.00000000" - }, - "product": "spot", - "quote": "btc", - "type": "balance" - } - ] - - {u'binary': 0, u'data': {u'orderId': 62870564, u'status': 0, u'tradeType': u'sell', u'tradeUnitPrice -': u'25.3500', u'symbol': u'etc_usdt', u'tradePrice': u'0.0000', u'createdDate': u'1512287172393', u -'averagePrice': u'0', u'tradeAmount': u'0.01000000', u'completedTradeAmount': u'0.00000000'}, u'chan -nel': u'ok_sub_spot_etc_usdt_order'} - ''' - #---------------------------------------------------------------------- - def onSpotSubOrder(self, data): - """交易数据""" - if 'data' not in data: - return - - rawData = data["data"] - - # 本地和系统委托号 - orderId = str(rawData['orderId']) - - # 这时候出现None, 情况是 已经发出了单子,但是系统这里还没建立 索引 - # 先这样返回试一下 - # 因为 发完单,订单变化是先推送的。。导致不清楚他的localID - # 现在的处理方式是, 先缓存这里的信息,等到出现了 localID,再来处理这一段 - localNo = self.orderIdDict.get(orderId, None) - if localNo == None: - arr = self.cache_some_order.get(orderId, None) - if arr == None: - arr = [] - arr.append(data) - self.cache_some_order[orderId] = arr - else: - arr.append(data) - return - - # 委托信息 - if orderId not in self.orderDict: - order = VtOrderData() - order.gatewayName = self.gatewayName - - order.symbol = '.'.join([rawData['symbol'], EXCHANGE_OKEX]) - #order.symbol = spotSymbolMap[rawData['symbol']] - order.vtSymbol = order.symbol - - order.orderID = localNo - order.vtOrderID = '.'.join([self.gatewayName, order.orderID]) - - order.price = float(rawData['tradeUnitPrice']) - order.totalVolume = float(rawData['tradeAmount']) - order.direction, priceType = priceTypeMap[rawData['tradeType']] - - self.orderDict[orderId] = order - else: - order = self.orderDict[orderId] - - order.tradedVolume = float(rawData['completedTradeAmount']) - order.status = statusMap[rawData['status']] - - self.gateway.onOrder(copy(order)) - - - bef_volume = self.recordOrderId_BefVolume.get(orderId, 0.0 ) - now_volume = float(rawData['completedTradeAmount']) - bef_volume - - if now_volume > 0.000001: - trade = VtTradeData() - trade.gatewayName = self.gatewayName - - trade.symbol = order.symbol - trade.vtSymbol = order.symbol - - self.tradeID += 1 - trade.tradeID = str(self.tradeID) - trade.vtTradeID = '.'.join([self.gatewayName, trade.tradeID]) - - trade.orderID = localNo - trade.vtOrderID = '.'.join([self.gatewayName, trade.orderID]) - - trade.price = float(rawData['tradeUnitPrice']) - trade.volume = float(now_volume) - - trade.direction, priceType = priceTypeMap[rawData['tradeType']] - - trade.tradeTime = datetime.now().strftime('%H:%M:%S') - - self.gateway.onTrade(trade) - - """ - 原来的OK coin方式,不过数据一直没有 所以换一种方式 - # 成交信息 - if 'sigTradeAmount' in rawData and float(rawData['sigTradeAmount'])>0: - trade = VtTradeData() - trade.gatewayName = self.gatewayName - - trade.symbol = spotSymbolMap[rawData['symbol']] - trade.vtSymbol = order.symbol - - trade.tradeID = str(rawData['id']) - trade.vtTradeID = '.'.join([self.gatewayName, trade.tradeID]) - - trade.orderID = localNo - trade.vtOrderID = '.'.join([self.gatewayName, trade.orderID]) - - trade.price = float(rawData['sigTradePrice']) - trade.volume = float(rawData['sigTradeAmount']) - - trade.direction, priceType = priceTypeMap[rawData['tradeType']] - - trade.tradeTime = datetime.now().strftime('%H:%M:%S') - - self.gateway.onTrade(trade) - """ - ''' - [ - { - "binary": 0, - "channel": "ok_spot_orderinfo", - "data": { - "result": true, - "orders": [ - { - "symbol": "bch_btc", - "amount": "0.10000000", - "price": "1.00000000", - "avg_price": 0, - "create_date": 1504529828000, - "type": "buy", - "deal_amount": 0, - "order_id": 6189, - "status": -1 - } - ] - } - } - ] - ''' - #---------------------------------------------------------------------- - def onSpotOrderInfo(self, data): - """委托信息查询回调""" - if "error_code" in data.keys(): - print(data) - return - rawData = data['data'] - for d in rawData['orders']: - self.localNo += 1 - localNo = str(self.localNo) - orderId = str(d['order_id']) - - self.localNoDict[localNo] = orderId - self.orderIdDict[orderId] = localNo - - if orderId not in self.orderDict: - order = VtOrderData() - order.gatewayName = self.gatewayName - - #order.symbol = spotSymbolMap[d['symbol']] - order.symbol = '.'.join([d["symbol"], EXCHANGE_OKEX]) - order.vtSymbol = order.symbol - - order.orderID = localNo - order.vtOrderID = '.'.join([self.gatewayName, order.orderID]) - - order.price = d['price'] - order.totalVolume = d['amount'] - order.direction, priceType = priceTypeMap[d['type']] - - self.orderDict[orderId] = order - else: - order = self.orderDict[orderId] - - order.tradedVolume = d['deal_amount'] - order.status = statusMap[d['status']] - - self.gateway.onOrder(copy(order)) - - ''' - [ - { - "binary": 0, - "channel": "ok_spot_order", - "data": { - "result": true, - "order_id": 6189 - } - } - ] - ''' - def onSpotOrder(self, data): - rawData = data['data'] - if 'error_code' in rawData.keys(): - print(data) - return - - orderId = str(rawData['order_id']) - - # 尽管websocket接口的委托号返回是异步的,但经过测试是 - # 符合先发现回的规律,因此这里通过queue获取之前发送的 - # 本地委托号,并把它和推送的系统委托号进行映射 - - # localNo = self.orderIdDict.get(orderId, None) - # if localNo == None: - - localNo = self.localNoQueue.get_nowait() - - self.localNoDict[localNo] = orderId - self.orderIdDict[orderId] = localNo - - # print orderId, self.cache_some_order - if orderId in self.cache_some_order.keys(): - arr = self.cache_some_order[orderId] - for d in arr: - self.onSpotSubOrder(d) - - # 处理完就删除掉这里 - del self.cache_some_order[orderId] - - # 检查是否有系统委托号返回前就发出的撤单请求,若有则进 - # 行撤单操作 - if localNo in self.cancelDict: - req = self.cancelDict[localNo] - self.spotCancel(req) - del self.cancelDict[localNo] - - - ''' - [ - { - "binary": 0, - "channel": "ok_spot_cancel_order", - "data": { - "result": true, - "order_id": "125433027" - } - } - ] - ''' - #---------------------------------------------------------------------- - def onSpotCancelOrder(self, data): - """撤单回报""" - if 'data' not in data: - return - - if 'error' in data["data"].keys(): - self.onError(data) - return - - rawData = data['data'] - orderId = str(rawData['order_id']) - - localNo = self.orderIdDict[orderId] - - if orderId not in self.orderDict: - order = VtOrderData() - order.gatewayName = self.gatewayName - - order.symbol = '.'.join([rawData['symbol'], EXCHANGE_OKEX]) - order.vtSymbol = order.symbol - - order.orderID = localNo - order.vtOrderID = '.'.join([self.gatewayName, order.orderID]) - - self.orderDict[orderId] = order - else: - order = self.orderDict[orderId] - - order.status = STATUS_CANCELLED - self.gateway.onOrder(order) - - del self.orderDict[orderId] - del self.orderIdDict[orderId] - del self.localNoDict[localNo] - - - if orderId in self.cache_some_order.keys(): - del self.cache_some_order[orderId] - - #---------------------------------------------------------------------- - def spotSendOrder(self, req): - """发单""" - #symbol = spotSymbolMapReverse[req.symbol][:4] - symbol = (req.symbol.split('.'))[0] - type_ = priceTypeMapReverse[(req.direction, req.priceType)] - - self.spotTrade(symbol, type_, str(req.price), str(req.volume)) - - # 本地委托号加1,并将对应字符串保存到队列中,返回基于本地委托号的vtOrderID - self.localNo += 1 - self.localNoQueue.put(str(self.localNo)) - vtOrderID = '.'.join([self.gatewayName, str(self.localNo)]) - return vtOrderID - - #---------------------------------------------------------------------- - def spotCancel(self, req): - """撤单""" - #symbol = spotSymbolMapReverse[req.symbol][:4] - symbol = (req.symbol.split('.'))[0] - localNo = req.orderID - - if localNo in self.localNoDict: - orderID = self.localNoDict[localNo] - self.spotCancelOrder(symbol, orderID) - else: - # 如果在系统委托号返回前客户就发送了撤单请求,则保存 - # 在cancelDict字典中,等待返回后执行撤单任务 - self.cancelDict[localNo] = req - - #---------------------------------------------------------------------- - def generateDateTime(self, s): - """生成时间""" - dt = datetime.fromtimestamp(float(s)/1e3) - time = dt.strftime("%H:%M:%S.%f") - date = dt.strftime("%Y%m%d") - return date, time diff --git a/vnpy/trader/gateway/huobiGateway/huobiGateway.py b/vnpy/trader/gateway/huobiGateway/huobiGateway.py index b3fc31d4..2b84a7ee 100644 --- a/vnpy/trader/gateway/huobiGateway/huobiGateway.py +++ b/vnpy/trader/gateway/huobiGateway/huobiGateway.py @@ -322,7 +322,6 @@ class HuobiDataApi(DataApi): self.gateway.onTick(tick) - ######################################################################## class HuobiTradeApi(TradeApi): """交易API实现"""