[Del]移除beta目录下的OKEX接口

This commit is contained in:
vn.py 2018-06-01 12:27:36 +08:00
parent 762a838b3d
commit 230688dea8
8 changed files with 0 additions and 1467 deletions

View File

@ -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)

View File

@ -1,4 +0,0 @@
# encoding: UTF-8
from __future__ import absolute_import
from .vnokex import OkexSpotApi, OkexFuturesApi, CONTRACT_SYMBOL, SPOT_CURRENCY

View File

@ -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()

View File

@ -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, {})

View File

@ -1,6 +0,0 @@
{
"apiKey": "你的apiKey",
"secretKey": "你的secretKey",
"trace": false,
"leverage": 10
}

View File

@ -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

View File

@ -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

View File

@ -322,7 +322,6 @@ class HuobiDataApi(DataApi):
self.gateway.onTick(tick)
########################################################################
class HuobiTradeApi(TradeApi):
"""交易API实现"""