From 1dcd2239bd0e1b4b536570bc6cc086f95a8f1727 Mon Sep 17 00:00:00 2001 From: "vn.py" Date: Sat, 16 Dec 2017 09:15:39 +0800 Subject: [PATCH] =?UTF-8?q?[Del]=E7=A7=BB=E9=99=A4OkCoin=E5=92=8C=E7=81=AB?= =?UTF-8?q?=E5=B8=81=E7=9A=84=E8=80=81=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vnpy/api/huobi/README.md | 18 - vnpy/api/huobi/__init__.py | 3 - vnpy/api/huobi/test.py | 67 -- vnpy/api/huobi/vnhuobi.py | 652 ---------------- vnpy/api/okcoin/README.md | 36 - vnpy/api/okcoin/__init__.py | 3 - vnpy/api/okcoin/test.py | 47 -- vnpy/api/okcoin/vnokcoin.py | 417 ---------- .../gateway/huobiGateway/HUOBI_connect.json | 7 - vnpy/trader/gateway/huobiGateway/__init__.py | 11 - .../gateway/huobiGateway/huobiGateway.py | 667 ---------------- .../gateway/lbankGateway/lbankGateway.py | 23 +- .../gateway/okcoinGateway/OKCOIN_connect.json | 7 - vnpy/trader/gateway/okcoinGateway/__init__.py | 11 - .../gateway/okcoinGateway/okcoinGateway.py | 734 ------------------ vnpy/trader/language/chinese/constant.py | 16 +- vnpy/trader/language/english/constant.py | 16 +- 17 files changed, 27 insertions(+), 2708 deletions(-) delete mode 100644 vnpy/api/huobi/README.md delete mode 100644 vnpy/api/huobi/__init__.py delete mode 100644 vnpy/api/huobi/test.py delete mode 100644 vnpy/api/huobi/vnhuobi.py delete mode 100644 vnpy/api/okcoin/README.md delete mode 100644 vnpy/api/okcoin/__init__.py delete mode 100644 vnpy/api/okcoin/test.py delete mode 100644 vnpy/api/okcoin/vnokcoin.py delete mode 100644 vnpy/trader/gateway/huobiGateway/HUOBI_connect.json delete mode 100644 vnpy/trader/gateway/huobiGateway/__init__.py delete mode 100644 vnpy/trader/gateway/huobiGateway/huobiGateway.py delete mode 100644 vnpy/trader/gateway/okcoinGateway/OKCOIN_connect.json delete mode 100644 vnpy/trader/gateway/okcoinGateway/__init__.py delete mode 100644 vnpy/trader/gateway/okcoinGateway/okcoinGateway.py diff --git a/vnpy/api/huobi/README.md b/vnpy/api/huobi/README.md deleted file mode 100644 index 1e34903f..00000000 --- a/vnpy/api/huobi/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# vn.huobi - -### 简介 - -火币的比特币交易接口,基于Rest API开发,实现了官方提供API的全部功能。 - -### 特点 -相比较于[火币官方](http://github.com/huobiapi/API_Docs/)给出的Python API实现,vn.huobi的一些特点: - -1. 面向对象的API设计,接近CTP API的结构,对于国内用户而言更容易上手 - -2. 参考CTP API的设计,主动函数调用的结果通过异步(回调函数)的方式推送到程序中,适用于开发稳定可靠的实盘交易程序 - -### API版本 -日期:2015-12-02 - -链接:[http://github.com/huobiapi/API_Docs/wiki](http://github.com/huobiapi/API_Docs/wiki) - diff --git a/vnpy/api/huobi/__init__.py b/vnpy/api/huobi/__init__.py deleted file mode 100644 index 66fc387d..00000000 --- a/vnpy/api/huobi/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# encoding: UTF-8 - -from vnhuobi import TradeApi, DataApi \ No newline at end of file diff --git a/vnpy/api/huobi/test.py b/vnpy/api/huobi/test.py deleted file mode 100644 index 7a48fcef..00000000 --- a/vnpy/api/huobi/test.py +++ /dev/null @@ -1,67 +0,0 @@ -# encoding: utf-8 - -from vnhuobi import * - -#---------------------------------------------------------------------- -def testTrade(): - """测试交易""" - accessKey = '' - secretKey = '' - - # 创建API对象并初始化 - api = TradeApi() - api.DEBUG = True - api.init(accessKey, secretKey) - - # 查询账户,测试通过 - api.getAccountInfo() - - # 查询委托,测试通过 - #api.getOrders() - - # 买入,测试通过 - #api.buy(7100, 0.0095) - - # 卖出,测试通过 - #api.sell(7120, 0.0095) - - # 撤单,测试通过 - #api.cancelOrder(3915047376L) - - # 查询杠杆额度,测试通过 - #api.getLoanAvailable() - - # 查询杠杆列表,测试通过 - #api.getLoans() - - # 阻塞 - input() - - -#---------------------------------------------------------------------- -def testData(): - """测试行情接口""" - api = DataApi() - - api.init(0.5) - - # 订阅成交推送,测试通过 - #api.subscribeTick(SYMBOL_BTCCNY) - - # 订阅报价推送,测试通过 - #api.subscribeQuote(SYMBOL_BTCCNY) - - # 订阅深度推送,测试通过 - #api.subscribeDepth(SYMBOL_BTCCNY, 1) - - # 查询K线数据,测试通过 - data = api.getKline(SYMBOL_BTCCNY, PERIOD_1MIN, 100) - print data - - input() - - -if __name__ == '__main__': - #testTrade() - - testData() \ No newline at end of file diff --git a/vnpy/api/huobi/vnhuobi.py b/vnpy/api/huobi/vnhuobi.py deleted file mode 100644 index 92ac65ba..00000000 --- a/vnpy/api/huobi/vnhuobi.py +++ /dev/null @@ -1,652 +0,0 @@ -# encoding: utf-8 - -import urllib -import hashlib - -import json -import requests -from time import time, sleep -from Queue import Queue, Empty -from threading import Thread - - -# 常量定义 -COINTYPE_BTC = 1 -COINTYPE_LTC = 2 - -ACCOUNTTYPE_CNY = 1 -ACCOUNTTYPE_USD = 2 - -LOANTYPE_CNY = 1 -LOANTYPE_BTC = 2 -LOANTYPE_LTC = 3 -LOANTYPE_USD = 4 - -MARKETTYPE_CNY = 'cny' -MARKETTYPE_USD = 'usd' - -SYMBOL_BTCCNY = 'BTC_CNY' -SYMBOL_LTCCNY = 'LTC_CNY' -SYMBOL_BTCUSD = 'BTC_USD' - -PERIOD_1MIN = '001' -PERIOD_5MIN = '005' -PERIOD_15MIN = '015' -PERIOD_30MIN = '030' -PERIOD_60MIN = '060' -PERIOD_DAILY = '100' -PERIOD_WEEKLY = '200' -PERIOD_MONTHLY = '300' -PERIOD_ANNUALLY = '400' - -# API相关定义 -HUOBI_TRADE_API = 'https://api.huobi.com/apiv3' - -# 功能代码 -FUNCTIONCODE_GETACCOUNTINFO = 'get_account_info' -FUNCTIONCODE_GETORDERS = 'get_orders' -FUNCTIONCODE_ORDERINFO = 'order_info' -FUNCTIONCODE_BUY = 'buy' -FUNCTIONCODE_SELL = 'sell' -FUNCTIONCODE_BUYMARKET = 'buy_market' -FUNCTIONCODE_SELLMARKET = 'sell_market' -FUNCTIONCODE_CANCELORDER = 'cancel_order' -FUNCTIONCODE_GETNEWDEALORDERS = 'get_new_deal_orders' -FUNCTIONCODE_GETORDERIDBYTRADEID = 'get_order_id_by_trade_id' -FUNCTIONCODE_WITHDRAWCOIN = 'withdraw_coin' -FUNCTIONCODE_CANCELWITHDRAWCOIN = 'cancel_withdraw_coin' -FUNCTIONCODE_GETWITHDRAWCOINRESULT = 'get_withdraw_coin_result' -FUNCTIONCODE_TRANSFER = 'transfer' -FUNCTIONCODE_LOAN = 'loan' -FUNCTIONCODE_REPAYMENT = 'repayment' -FUNCTIONCODE_GETLOANAVAILABLE = 'get_loan_available' -FUNCTIONCODE_GETLOANS = 'get_loans' - - -#---------------------------------------------------------------------- -def signature(params): - """生成签名""" - params = sorted(params.iteritems(), key=lambda d:d[0], reverse=False) - message = urllib.urlencode(params) - - m = hashlib.md5() - m.update(message) - m.digest() - - sig=m.hexdigest() - return sig - - -######################################################################## -class TradeApi(object): - """交易接口""" - DEBUG = True - - #---------------------------------------------------------------------- - def __init__(self): - """Constructor""" - self.accessKey = '' - self.secretKey = '' - - self.active = False # API工作状态 - self.reqID = 0 # 请求编号 - self.reqQueue = Queue() # 请求队列 - self.reqThread = Thread(target=self.processQueue) # 请求处理线程 - - #---------------------------------------------------------------------- - def processRequest(self, req): - """处理请求""" - # 读取方法和参数 - method = req['method'] - params = req['params'] - optional = req['optional'] - - # 在参数中增加必须的字段 - params['created'] = long(time()) - params['access_key'] = self.accessKey - params['secret_key'] = self.secretKey - params['method'] = method - - # 添加签名 - sign = signature(params) - params['sign'] = sign - del params['secret_key'] - - # 添加选填参数 - if optional: - params.update(optional) - - # 发送请求 - payload = urllib.urlencode(params) - - r = requests.post(HUOBI_TRADE_API, params=payload) - if r.status_code == 200: - data = r.json() - return data - else: - return None - - #---------------------------------------------------------------------- - def processQueue(self): - """处理请求队列中的请求""" - while self.active: - try: - req = self.reqQueue.get(block=True, timeout=1) # 获取请求的阻塞为一秒 - callback = req['callback'] - reqID = req['reqID'] - - data = self.processRequest(req) - - # 请求失败 - if 'code' in data and 'message' in data: - error = u'错误信息:%s' %data['message'] - self.onError(error, req, reqID) - # 请求成功 - else: - if self.DEBUG: - print callback.__name__ - callback(data, req, reqID) - - except Empty: - pass - - #---------------------------------------------------------------------- - def sendRequest(self, method, params, callback, optional=None): - """发送请求""" - # 请求编号加1 - self.reqID += 1 - - # 生成请求字典并放入队列中 - req = {} - req['method'] = method - req['params'] = params - req['callback'] = callback - req['optional'] = optional - req['reqID'] = self.reqID - self.reqQueue.put(req) - - # 返回请求编号 - return self.reqID - - #################################################### - ## 主动函数 - #################################################### - - #---------------------------------------------------------------------- - def init(self, accessKey, secretKey): - """初始化""" - self.accessKey = accessKey - self.secretKey = secretKey - - self.active = True - self.reqThread.start() - - #---------------------------------------------------------------------- - def exit(self): - """退出""" - self.active = False - - if self.reqThread.isAlive(): - self.reqThread.join() - - #---------------------------------------------------------------------- - def getAccountInfo(self, market='cny'): - """查询账户""" - method = FUNCTIONCODE_GETACCOUNTINFO - params = {} - callback = self.onGetAccountInfo - optional = {'market': market} - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def getOrders(self, coinType=COINTYPE_BTC, market='cny'): - """查询委托""" - method = FUNCTIONCODE_GETORDERS - params = {'coin_type': coinType} - callback = self.onGetOrders - optional = {'market': market} - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def orderInfo(self, id_, coinType=COINTYPE_BTC, market='cny'): - """获取委托详情""" - method = FUNCTIONCODE_ORDERINFO - params = { - 'coin_type': coinType, - 'id': id_ - } - callback = self.onOrderInfo - optional = {'market': market} - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def buy(self, price, amount, coinType=COINTYPE_BTC, - tradePassword='', tradeId = '', market='cny'): - """委托买入""" - method = FUNCTIONCODE_BUY - params = { - 'coin_type': coinType, - 'price': price, - 'amount': amount - } - callback = self.onBuy - optional = { - 'trade_password': tradePassword, - 'trade_id': tradeId, - 'market': market - } - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def sell(self, price, amount, coinType=COINTYPE_BTC, - tradePassword='', tradeId = '', market='cny'): - """委托卖出""" - method = FUNCTIONCODE_SELL - params = { - 'coin_type': coinType, - 'price': price, - 'amount': amount - } - callback = self.onSell - optional = { - 'trade_password': tradePassword, - 'trade_id': tradeId, - 'market': market - } - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def buyMarket(self, amount, coinType=COINTYPE_BTC, - tradePassword='', tradeId = '', market='cny'): - """市价买入""" - method = FUNCTIONCODE_BUYMARKET - params = { - 'coin_type': coinType, - 'amount': amount - } - callback = self.onBuyMarket - optional = { - 'trade_password': tradePassword, - 'trade_id': tradeId, - 'market': market - } - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def sellMarket(self, amount, coinType=COINTYPE_BTC, - tradePassword='', tradeId = '', market='cny'): - """市价卖出""" - method = FUNCTIONCODE_SELLMARKET - params = { - 'coin_type': coinType, - 'amount': amount - } - callback = self.onSellMarket - optional = { - 'trade_password': tradePassword, - 'trade_id': tradeId, - 'market': market - } - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def cancelOrder(self, id_, coinType=COINTYPE_BTC, market='cny'): - """撤销委托""" - method = FUNCTIONCODE_CANCELORDER - params = { - 'coin_type': coinType, - 'id': id_ - } - callback = self.onCancelOrder - optional = {'market': market} - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def getNewDealOrders(self, market='cny'): - """查询最新10条成交""" - method = FUNCTIONCODE_GETNEWDEALORDERS - params = {} - callback = self.onGetNewDealOrders - optional = {'market': market} - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def getOrderIdByTradeId(self, tradeId, coinType=COINTYPE_BTC, - market='cny'): - """通过成交编号查询委托编号""" - method = FUNCTIONCODE_GETORDERIDBYTRADEID - params = { - 'coin_type': coinType, - 'trade_id': tradeId - } - callback = self.onGetOrderIdByTradeId - optional = {'market': market} - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def withdrawCoin(self, withdrawAddress, withdrawAmount, - coinType=COINTYPE_BTC, tradePassword='', - market='cny', withdrawFee=0.0001): - """提币""" - method = FUNCTIONCODE_WITHDRAWCOIN - params = { - 'coin_type': coinType, - 'withdraw_address': withdrawAddress, - 'withdraw_amount': withdrawAmount - } - callback = self.onWithdrawCoin - optional = { - 'market': market, - 'withdraw_fee': withdrawFee - } - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def cancelWithdrawCoin(self, id_, market='cny'): - """取消提币""" - method = FUNCTIONCODE_CANCELWITHDRAWCOIN - params = {'withdraw_coin_id': id_} - callback = self.onCancelWithdrawCoin - optional = {'market': market} - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def onGetWithdrawCoinResult(self, id_, market='cny'): - """查询提币结果""" - method = FUNCTIONCODE_GETWITHDRAWCOINRESULT - params = {'withdraw_coin_id': id_} - callback = self.onGetWithdrawCoinResult - optional = {'market': market} - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def transfer(self, amountFrom, amountTo, amount, - coinType=COINTYPE_BTC ): - """账户内转账""" - method = FUNCTIONCODE_TRANSFER - params = { - 'amount_from': amountFrom, - 'amount_to': amountTo, - 'amount': amount, - 'coin_type': coinType - } - callback = self.onTransfer - optional = {} - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def loan(self, amount, loan_type=LOANTYPE_CNY, - market=MARKETTYPE_CNY): - """申请杠杆""" - method = FUNCTIONCODE_LOAN - params = { - 'amount': amount, - 'loan_type': loan_type - } - callback = self.onLoan - optional = {'market': market} - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def repayment(self, id_, amount, repayAll=0, - market=MARKETTYPE_CNY): - """归还杠杆""" - method = FUNCTIONCODE_REPAYMENT - params = { - 'loan_id': id_, - 'amount': amount - } - callback = self.onRepayment - optional = { - 'repay_all': repayAll, - 'market': market - } - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def getLoanAvailable(self, market='cny'): - """查询杠杆额度""" - method = FUNCTIONCODE_GETLOANAVAILABLE - params = {} - callback = self.onLoanAvailable - optional = {'market': market} - return self.sendRequest(method, params, callback, optional) - - #---------------------------------------------------------------------- - def getLoans(self, market='cny'): - """查询杠杆列表""" - method = FUNCTIONCODE_GETLOANS - params = {} - callback = self.onGetLoans - optional = {'market': market} - return self.sendRequest(method, params, callback, optional) - - #################################################### - ## 回调函数 - #################################################### - - #---------------------------------------------------------------------- - def onError(self, error, req, reqID): - """错误推送""" - print error, reqID - - #---------------------------------------------------------------------- - def onGetAccountInfo(self, data, req, reqID): - """查询账户回调""" - print data - - #---------------------------------------------------------------------- - def onGetOrders(self, data, req, reqID, fuck): - """查询委托回调""" - print data - - #---------------------------------------------------------------------- - def onOrderInfo(self, data, req, reqID): - """委托详情回调""" - print data - - #---------------------------------------------------------------------- - def onBuy(self, data, req, reqID): - """买入回调""" - print data - - #---------------------------------------------------------------------- - def onSell(self, data, req, reqID): - """卖出回调""" - print data - - #---------------------------------------------------------------------- - def onBuyMarket(self, data, req, reqID): - """市价买入回调""" - print data - - #---------------------------------------------------------------------- - def onSellMarket(self, data, req, reqID): - """市价卖出回调""" - print data - - #---------------------------------------------------------------------- - def onCancelOrder(self, data, req, reqID): - """撤单回调""" - print data - - #---------------------------------------------------------------------- - def onGetNewDealOrders(self, data, req, reqID): - """查询最新成交回调""" - print data - - #---------------------------------------------------------------------- - def onGetOrderIdByTradeId(self, data, req, reqID): - """通过成交编号查询委托编号回调""" - print data - - #---------------------------------------------------------------------- - def onWithdrawCoin(self, data, req, reqID): - """提币回调""" - print data - - #---------------------------------------------------------------------- - def onCancelWithdrawCoin(self, data, req, reqID): - """取消提币回调""" - print data - - #---------------------------------------------------------------------- - def onGetWithdrawCoinResult(self, data, req, reqID): - """查询提币结果回调""" - print data - - #---------------------------------------------------------------------- - def onTransfer(self, data, req, reqID): - """转账回调""" - print data - - #---------------------------------------------------------------------- - def onLoan(self, data, req, reqID): - """申请杠杆回调""" - print data - - #---------------------------------------------------------------------- - def onRepayment(self, data, req, reqID): - """归还杠杆回调""" - print data - - #---------------------------------------------------------------------- - def onLoanAvailable(self, data, req, reqID): - """查询杠杆额度回调""" - print data - - #---------------------------------------------------------------------- - def onGetLoans(self, data, req, reqID): - """查询杠杆列表""" - print data - - -######################################################################## -class DataApi(object): - """行情接口""" - TICK_SYMBOL_URL = { - SYMBOL_BTCCNY: 'http://api.huobi.com/staticmarket/detail_btc_json.js', - SYMBOL_LTCCNY: 'http://api.huobi.com/staticmarket/detail_ltc_json.js', - SYMBOL_BTCUSD: 'http://api.huobi.com/usdmarket/detail_btc_json.js' - } - - QUOTE_SYMBOL_URL = { - SYMBOL_BTCCNY: 'http://api.huobi.com/staticmarket/ticker_btc_json.js', - SYMBOL_LTCCNY: 'http://api.huobi.com/staticmarket/ticker_ltc_json.js', - SYMBOL_BTCUSD: 'http://api.huobi.com/usdmarket/ticker_btc_json.js' - } - - DEPTH_SYMBOL_URL = { - SYMBOL_BTCCNY: 'http://api.huobi.com/staticmarket/depth_btc_json.js', - SYMBOL_LTCCNY: 'http://api.huobi.com/staticmarket/depth_ltc_json.js', - SYMBOL_BTCUSD: 'http://api.huobi.com/usdmarket/depth_btc_json.js' - } - - KLINE_SYMBOL_URL = { - SYMBOL_BTCCNY: 'http://api.huobi.com/staticmarket/btc_kline_[period]_json.js', - SYMBOL_LTCCNY: 'http://api.huobi.com/staticmarket/btc_kline_[period]_json.js', - SYMBOL_BTCUSD: 'http://api.huobi.com/usdmarket/btc_kline_[period]_json.js' - } - - DEBUG = True - - #---------------------------------------------------------------------- - def __init__(self): - """Constructor""" - self.active = False - - self.taskInterval = 0 # 每轮请求延时 - self.taskList = [] # 订阅的任务列表 - self.taskThread = Thread(target=self.run) # 处理任务的线程 - - #---------------------------------------------------------------------- - def init(self, interval, debug): - """初始化""" - self.taskInterval = interval - self.DEBUG = debug - - self.active = True - self.taskThread.start() - - #---------------------------------------------------------------------- - def exit(self): - """退出""" - self.active = False - - if self.taskThread.isAlive(): - self.taskThread.join() - - #---------------------------------------------------------------------- - def run(self): - """连续运行""" - while self.active: - for url, callback in self.taskList: - try: - r = requests.get(url) - if r.status_code == 200: - data = r.json() - if self.DEBUG: - print callback.__name__ - callback(data) - except Exception, e: - print e - - sleep(self.taskInterval) - - #---------------------------------------------------------------------- - def subscribeTick(self, symbol): - """订阅实时成交数据""" - url = self.TICK_SYMBOL_URL[symbol] - task = (url, self.onTick) - self.taskList.append(task) - - #---------------------------------------------------------------------- - def subscribeQuote(self, symbol): - """订阅实时报价数据""" - url = self.QUOTE_SYMBOL_URL[symbol] - task = (url, self.onQuote) - self.taskList.append(task) - - #---------------------------------------------------------------------- - def subscribeDepth(self, symbol, level=0): - """订阅深度数据""" - url = self.DEPTH_SYMBOL_URL[symbol] - - if level: - url = url.replace('json', str(level)) - - task = (url, self.onDepth) - self.taskList.append(task) - - #---------------------------------------------------------------------- - def onTick(self, data): - """实时成交推送""" - print data - - #---------------------------------------------------------------------- - def onQuote(self, data): - """实时报价推送""" - print data - - #---------------------------------------------------------------------- - def onDepth(self, data): - """实时深度推送""" - print data - - #---------------------------------------------------------------------- - def getKline(self, symbol, period, length=0): - """查询K线数据""" - url = self.KLINE_SYMBOL_URL[symbol] - url = url.replace('[period]', period) - - if length: - url = url + '?length=' + str(length) - - try: - r = requests.get(url) - if r.status_code == 200: - data = r.json() - return data - except Exception, e: - print e - return None \ No newline at end of file diff --git a/vnpy/api/okcoin/README.md b/vnpy/api/okcoin/README.md deleted file mode 100644 index cd8a1ee5..00000000 --- a/vnpy/api/okcoin/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# vn.okcoin - -贡献者:量衍投资 - -### 简介 -OkCoin的比特币交易接口,基于Websocket API开发,实现了以下功能: - -1. 发送、撤销委托 - -2. 查询委托、持仓、资金、成交历史 - -3. 实时行情、成交、资金更新的推送 - -### 特点 -相比较于[OkCoin官方](http://github.com/OKCoin/websocket/tree/master/python)给出的Python API实现,vn.okcoin的一些特点: - -1. 同时支持OkCoin的中国站和国际站交易,根据用户连接的站点会在内部自动切换结算货币(CNY、USD) - -2. 采用面向对象的接口设计模式,接近国内CTP接口的风格,并对主动函数的调用参数做了大幅简化 - -3. 数据解包和签名生成两个热点函数使用了更加高效的实现方式 - -### 参数命名 -函数的参数命名针对金融领域用户的习惯做了一些修改,具体对应如下: - -* expiry:原生命名的contract_type -* order: 原生命名的match_price -* leverage:原生命名的lever_rate -* page:原生命名的current_page -* length:原生命名的page_length - -### API版本 -日期:2016-06-29 - -链接:[http://www.okcoin.com/about/ws_getStarted.do](http://www.okcoin.com/about/ws_getStarted.do) - diff --git a/vnpy/api/okcoin/__init__.py b/vnpy/api/okcoin/__init__.py deleted file mode 100644 index 69e8247d..00000000 --- a/vnpy/api/okcoin/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# encoding: UTF-8 - -from vnokcoin import OkCoinApi \ No newline at end of file diff --git a/vnpy/api/okcoin/test.py b/vnpy/api/okcoin/test.py deleted file mode 100644 index 41863684..00000000 --- a/vnpy/api/okcoin/test.py +++ /dev/null @@ -1,47 +0,0 @@ -# encoding: UTF-8 - -from vnokcoin import * - -# 在OkCoin网站申请这两个Key,分别对应用户名和密码 -apiKey = '' -secretKey = '' - -# 创建API对象 -api = OkCoinApi() - -# 连接服务器,并等待1秒 -api.connect(OKCOIN_USD, apiKey, secretKey, True) - -sleep(1) - -# 测试现货行情API -#api.subscribeSpotTicker(SYMBOL_BTC) -#api.subscribeSpotTradeData(SYMBOL_BTC) -api.subscribeSpotDepth(SYMBOL_BTC, DEPTH_20) -#api.subscribeSpotKline(SYMBOL_BTC, INTERVAL_1M) - -# 测试现货交易API -#api.subscribeSpotTrades() -#api.subscribeSpotUserInfo() -#api.spotUserInfo() -#api.spotTrade(symbol, type_, price, amount) -#api.spotCancelOrder(symbol, orderid) -#api.spotOrderInfo(symbol, orderid) - -# 测试期货行情API -#api.subscribeFutureTicker(SYMBOL_BTC, FUTURE_EXPIRY_THIS_WEEK) -#api.subscribeFutureTradeData(SYMBOL_BTC, FUTURE_EXPIRY_THIS_WEEK) -#api.subscribeFutureDepth(SYMBOL_BTC, FUTURE_EXPIRY_THIS_WEEK, DEPTH_20) -#api.subscribeFutureKline(SYMBOL_BTC, FUTURE_EXPIRY_THIS_WEEK, INTERVAL_1M) -#api.subscribeFutureIndex(SYMBOL_BTC) - -# 测试期货交易API -#api.subscribeFutureTrades() -#api.subscribeFutureUserInfo() -#api.subscribeFuturePositions() -#api.futureUserInfo() -#api.futureTrade(symbol, expiry, type_, price, amount, order, leverage) -#api.futureCancelOrder(symbol, expiry, orderid) -#api.futureOrderInfo(symbol, expiry, orderid, status, page, length) - -raw_input() \ No newline at end of file diff --git a/vnpy/api/okcoin/vnokcoin.py b/vnpy/api/okcoin/vnokcoin.py deleted file mode 100644 index 75c09c05..00000000 --- a/vnpy/api/okcoin/vnokcoin.py +++ /dev/null @@ -1,417 +0,0 @@ -# encoding: UTF-8 - -import hashlib -import zlib -import json -from time import sleep -from threading import Thread - -import websocket - - -# OKCOIN网站 -OKCOIN_CNY = 'wss://real.okcoin.cn:10440/websocket/okcoinapi' -OKCOIN_USD = 'wss://real.okcoin.com:10440/websocket/okcoinapi' - -# 账户货币代码 -CURRENCY_CNY = 'cny' -CURRENCY_USD = 'usd' - -# 电子货币代码 -SYMBOL_BTC = 'btc' -SYMBOL_LTC = 'ltc' -SYMBOL_ETH = 'eth' - -# 行情深度 -DEPTH_20 = 20 -DEPTH_60 = 60 - -# K线时间区间 -INTERVAL_1M = '1min' -INTERVAL_3M = '3min' -INTERVAL_5M = '5min' -INTERVAL_15M = '15min' -INTERVAL_30M = '30min' -INTERVAL_1H = '1hour' -INTERVAL_2H = '2hour' -INTERVAL_4H = '4hour' -INTERVAL_6H = '6hour' -INTERVAL_1D = 'day' -INTERVAL_3D = '3day' -INTERVAL_1W = 'week' - -# 交易代码,需要后缀货币名才能完整 -TRADING_SYMBOL_BTC = 'btc_' -TRADING_SYMBOL_LTC = 'ltc_' -TRADING_SYMBOL_ETH = 'eth_' - -# 委托类型 -TYPE_BUY = 'buy' -TYPE_SELL = 'sell' -TYPE_BUY_MARKET = 'buy_market' -TYPE_SELL_MARKET = 'sell_market' - -# 期货合约到期类型 -FUTURE_EXPIRY_THIS_WEEK = 'this_week' -FUTURE_EXPIRY_NEXT_WEEK = 'next_week' -FUTURE_EXPIRY_QUARTER = 'quarter' - -# 期货委托类型 -FUTURE_TYPE_LONG = 1 -FUTURE_TYPE_SHORT = 2 -FUTURE_TYPE_SELL = 3 -FUTURE_TYPE_COVER = 4 - -# 期货是否用现价 -FUTURE_ORDER_MARKET = 1 -FUTURE_ORDER_LIMIT = 0 - -# 期货杠杆 -FUTURE_LEVERAGE_10 = 10 -FUTURE_LEVERAGE_20 = 20 - -# 委托状态 -ORDER_STATUS_NOTTRADED = 0 -ORDER_STATUS_PARTTRADED = 1 -ORDER_STATUS_ALLTRADED = 2 -ORDER_STATUS_CANCELLED = -1 -ORDER_STATUS_CANCELLING = 4 - - -######################################################################## -class OkCoinApi(object): - """基于Websocket的API对象""" - - #---------------------------------------------------------------------- - def __init__(self): - """Constructor""" - self.apiKey = '' # 用户名 - self.secretKey = '' # 密码 - self.host = '' # 服务器地址 - - self.currency = '' # 货币类型(usd或者cny) - - self.ws = None # websocket应用对象 - self.thread = None # 工作线程 - - ####################### - ## 通用函数 - ####################### - - #---------------------------------------------------------------------- - def readData(self, evt): - """解压缩推送收到的数据""" - # 创建解压器 - decompress = zlib.decompressobj(-zlib.MAX_WBITS) - - # 将原始数据解压成字符串 - inflated = decompress.decompress(evt) + decompress.flush() - - # 通过json解析字符串 - data = json.loads(inflated) - - return data - - #---------------------------------------------------------------------- - 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 onMessage(self, ws, evt): - """信息推送""" - print 'onMessage' - data = self.readData(evt) - print data - - #---------------------------------------------------------------------- - def onError(self, ws, evt): - """错误推送""" - print 'onError' - print evt - - #---------------------------------------------------------------------- - def onClose(self, ws): - """接口断开""" - print 'onClose' - - #---------------------------------------------------------------------- - def onOpen(self, ws): - """接口打开""" - print 'onOpen' - - #---------------------------------------------------------------------- - def connect(self, host, apiKey, secretKey, trace=False): - """连接服务器""" - self.host = host - self.apiKey = apiKey - self.secretKey = secretKey - - if self.host == OKCOIN_CNY: - self.currency = CURRENCY_CNY - else: - self.currency = CURRENCY_USD - - websocket.enableTrace(trace) - - self.ws = websocket.WebSocketApp(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 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 close(self): - """关闭接口""" - if self.thread and self.thread.isAlive(): - self.ws.close() - self.thread.join() - - #---------------------------------------------------------------------- - def sendMarketDataRequest(self, channel): - """发送行情请求""" - # 生成请求 - d = {} - d['event'] = 'addChannel' - d['binary'] = True - d['channel'] = channel - - # 使用json打包并发送 - j = json.dumps(d) - - # 若触发异常则重连 - try: - self.ws.send(j) - except websocket.WebSocketConnectionClosedException: - pass - - #---------------------------------------------------------------------- - def sendTradingRequest(self, channel, params): - """发送交易请求""" - # 在参数字典中加上api_key和签名字段 - params['api_key'] = self.apiKey - params['sign'] = self.generateSign(params) - - # 生成请求 - d = {} - d['event'] = 'addChannel' - d['binary'] = True - d['channel'] = channel - d['parameters'] = params - - # 使用json打包并发送 - j = json.dumps(d) - - # 若触发异常则重连 - try: - self.ws.send(j) - except websocket.WebSocketConnectionClosedException: - pass - - ####################### - ## 现货相关 - ####################### - - #---------------------------------------------------------------------- - def subscribeSpotTicker(self, symbol): - """订阅现货普通报价""" - self.sendMarketDataRequest('ok_sub_spot%s_%s_ticker' %(self.currency, symbol)) - - #---------------------------------------------------------------------- - def subscribeSpotDepth(self, symbol, depth): - """订阅现货深度报价""" - self.sendMarketDataRequest('ok_sub_spot%s_%s_depth_%s' %(self.currency, symbol, depth)) - - #---------------------------------------------------------------------- - def subscribeSpotTradeData(self, symbol): - """订阅现货成交记录""" - self.sendMarketDataRequest('ok_sub_spot%s_%s_trades' %(self.currency, symbol)) - - #---------------------------------------------------------------------- - def subscribeSpotKline(self, symbol, interval): - """订阅现货K线""" - self.sendMarketDataRequest('ok_sub_spot%s_%s_kline_%s' %(self.currency, symbol, interval)) - - #---------------------------------------------------------------------- - def spotTrade(self, symbol, type_, price, amount): - """现货委托""" - params = {} - params['symbol'] = str(symbol+self.currency) - params['type'] = str(type_) - params['price'] = str(price) - params['amount'] = str(amount) - - channel = 'ok_spot%s_trade' %(self.currency) - - self.sendTradingRequest(channel, params) - - #---------------------------------------------------------------------- - def spotCancelOrder(self, symbol, orderid): - """现货撤单""" - params = {} - params['symbol'] = str(symbol+self.currency) - params['order_id'] = str(orderid) - - channel = 'ok_spot%s_cancel_order' %(self.currency) - - self.sendTradingRequest(channel, params) - - #---------------------------------------------------------------------- - def spotUserInfo(self): - """查询现货账户""" - channel = 'ok_spot%s_userinfo' %(self.currency) - - self.sendTradingRequest(channel, {}) - - #---------------------------------------------------------------------- - def spotOrderInfo(self, symbol, orderid): - """查询现货委托信息""" - params = {} - params['symbol'] = str(symbol+self.currency) - params['order_id'] = str(orderid) - - channel = 'ok_spot%s_orderinfo' %(self.currency) - - self.sendTradingRequest(channel, params) - - #---------------------------------------------------------------------- - def subscribeSpotTrades(self): - """订阅现货成交信息""" - channel = 'ok_sub_spot%s_trades' %(self.currency) - - self.sendTradingRequest(channel, {}) - - #---------------------------------------------------------------------- - def subscribeSpotUserInfo(self): - """订阅现货账户信息""" - channel = 'ok_sub_spot%s_userinfo' %(self.currency) - - self.sendTradingRequest(channel, {}) - - ####################### - ## 期货相关 - ####################### - - #---------------------------------------------------------------------- - def subscribeFutureTicker(self, symbol, expiry): - """订阅期货普通报价""" - self.sendMarketDataRequest('ok_sub_future%s_%s_ticker_%s' %(self.currency, symbol, expiry)) - - #---------------------------------------------------------------------- - def subscribeFutureDepth(self, symbol, expiry, depth): - """订阅期货深度报价""" - self.sendMarketDataRequest('ok_sub_future%s_%s_depth_%s_%s' %(self.currency, symbol, - expiry, depth)) - - #---------------------------------------------------------------------- - def subscribeFutureTradeData(self, symbol, expiry): - """订阅期货成交记录""" - self.sendMarketDataRequest('ok_sub_future%s_%s_trade_%s' %(self.currency, symbol, expiry)) - - #---------------------------------------------------------------------- - def subscribeFutureKline(self, symbol, expiry, interval): - """订阅期货K线""" - self.sendMarketDataRequest('ok_sub_future%s_%s_kline_%s_%s' %(self.currency, symbol, - expiry, interval)) - - #---------------------------------------------------------------------- - def subscribeFutureIndex(self, symbol): - """订阅期货指数""" - self.sendMarketDataRequest('ok_sub_future%s_%s_index' %(self.currency, symbol)) - - #---------------------------------------------------------------------- - def futureTrade(self, symbol, expiry, type_, price, amount, order, leverage): - """期货委托""" - params = {} - params['symbol'] = str(symbol+self.currency) - params['type'] = str(type_) - params['price'] = str(price) - params['amount'] = str(amount) - params['contract_type'] = str(expiry) - params['match_price'] = str(order) - params['lever_rate'] = str(leverage) - - channel = 'ok_future%s_trade' %(self.currency) - - self.sendTradingRequest(channel, params) - - #---------------------------------------------------------------------- - def futureCancelOrder(self, symbol, expiry, orderid): - """期货撤单""" - params = {} - params['symbol'] = str(symbol+self.currency) - params['order_id'] = str(orderid) - params['contract_type'] = str(expiry) - - channel = 'ok_future%s_cancel_order' %(self.currency) - - self.sendTradingRequest(channel, params) - - #---------------------------------------------------------------------- - def futureUserInfo(self): - """查询期货账户""" - channel = 'ok_future%s_userinfo' %(self.currency) - - self.sendTradingRequest(channel, {}) - - #---------------------------------------------------------------------- - def futureOrderInfo(self, symbol, expiry, orderid, status, page, length): - """查询期货委托信息""" - params = {} - params['symbol'] = str(symbol+self.currency) - params['order_id'] = str(orderid) - params['contract_type'] = expiry - params['status'] = status - params['current_page'] = page - params['page_length'] = length - - channel = 'ok_future%s_orderinfo' %(self.currency) - - self.sendTradingRequest(channel, params) - - #---------------------------------------------------------------------- - def subscribeFutureTrades(self): - """订阅期货成交信息""" - channel = 'ok_sub_future%s_trades' %(self.currency) - - self.sendTradingRequest(channel, {}) - - #---------------------------------------------------------------------- - def subscribeFutureUserInfo(self): - """订阅期货账户信息""" - channel = 'ok_sub_future%s_userinfo' %(self.currency) - - self.sendTradingRequest(channel, {}) - - #---------------------------------------------------------------------- - def subscribeFuturePositions(self): - """订阅期货持仓信息""" - channel = 'ok_sub_future%s_positions' %(self.currency) - - self.sendTradingRequest(channel, {}) - - diff --git a/vnpy/trader/gateway/huobiGateway/HUOBI_connect.json b/vnpy/trader/gateway/huobiGateway/HUOBI_connect.json deleted file mode 100644 index 3c427281..00000000 --- a/vnpy/trader/gateway/huobiGateway/HUOBI_connect.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "accessKey": "火币网站申请", - "secretKey": "火币网站申请", - "interval": 0.5, - "market": "cny", - "debug": false -} \ No newline at end of file diff --git a/vnpy/trader/gateway/huobiGateway/__init__.py b/vnpy/trader/gateway/huobiGateway/__init__.py deleted file mode 100644 index 46f21798..00000000 --- a/vnpy/trader/gateway/huobiGateway/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -# encoding: UTF-8 - -from vnpy.trader import vtConstant -from huobiGateway import HuobiGateway - -gatewayClass = HuobiGateway -gatewayName = 'HUOBI' -gatewayDisplayName = u'火币' -gatewayType = vtConstant.GATEWAYTYPE_BTC -gatewayQryEnabled = True - diff --git a/vnpy/trader/gateway/huobiGateway/huobiGateway.py b/vnpy/trader/gateway/huobiGateway/huobiGateway.py deleted file mode 100644 index cb36f3c2..00000000 --- a/vnpy/trader/gateway/huobiGateway/huobiGateway.py +++ /dev/null @@ -1,667 +0,0 @@ -# encoding: UTF-8 - -''' -vn.huobi的gateway接入 -''' - - -import os -import json -from datetime import datetime -from copy import copy -from threading import Condition -from Queue import Queue -from threading import Thread - -from vnpy.api.huobi import vnhuobi -from vnpy.trader.vtGateway import * -from vnpy.trader.vtFunction import getJsonPath - -SYMBOL_BTCCNY = 'BTCCNY' -SYMBOL_LTCCNY = 'LTCCNY' -SYMBOL_BTCUSD = 'BTCUSD' - -SYMBOL_MAP = {} -SYMBOL_MAP[(vnhuobi.COINTYPE_BTC, 'cny')] = SYMBOL_BTCCNY -SYMBOL_MAP[(vnhuobi.COINTYPE_LTC, 'cny')] = SYMBOL_LTCCNY -SYMBOL_MAP[(vnhuobi.COINTYPE_BTC, 'usd')] = SYMBOL_BTCUSD -SYMBOL_MAP_REVERSE = {v: k for k, v in SYMBOL_MAP.items()} - -MDSYMBOL_MAP = {} -MDSYMBOL_MAP['btccny'] = SYMBOL_BTCCNY -MDSYMBOL_MAP['ltccny'] = SYMBOL_LTCCNY -MDSYMBOL_MAP['btcusd'] = SYMBOL_BTCUSD - -DIRECTION_MAP = {} -DIRECTION_MAP[1] = DIRECTION_LONG -DIRECTION_MAP[2] = DIRECTION_SHORT - -STATUS_MAP = {} -STATUS_MAP[0] = STATUS_NOTTRADED -STATUS_MAP[1] = STATUS_PARTTRADED -STATUS_MAP[2] = STATUS_ALLTRADED -STATUS_MAP[3] = STATUS_CANCELLED -STATUS_MAP[5] = STATUS_UNKNOWN -STATUS_MAP[7] = STATUS_UNKNOWN - - - -######################################################################## -class HuobiGateway(VtGateway): - """火币接口""" - - #---------------------------------------------------------------------- - def __init__(self, eventEngine, gatewayName='HUOBI'): - """Constructor""" - super(HuobiGateway, self).__init__(eventEngine, gatewayName) - - self.market = 'cny' - - self.tradeApi = HuobiTradeApi(self) - self.dataApi = HuobiDataApi(self) - - 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: - accessKey = str(setting['accessKey']) - secretKey = str(setting['secretKey']) - interval = setting['interval'] - market = setting['market'] - debug = setting['debug'] - except KeyError: - log = VtLogData() - log.gatewayName = self.gatewayName - log.logContent = u'连接配置缺少字段,请检查' - self.onLog(log) - return - - # 初始化接口 - self.tradeApi.connect(accessKey, secretKey, market, debug) - self.writeLog(u'交易接口初始化成功') - - self.dataApi.connect(interval, market, debug) - self.writeLog(u'行情接口初始化成功') - - # 启动查询 - self.initQuery() - self.startQuery() - - #---------------------------------------------------------------------- - def writeLog(self, content): - """发出日志""" - log = VtLogData() - log.gatewayName = self.gatewayName - log.logContent = content - self.onLog(log) - - #---------------------------------------------------------------------- - def subscribe(self, subscribeReq): - """订阅行情,自动订阅全部行情,无需实现""" - pass - - #---------------------------------------------------------------------- - def sendOrder(self, orderReq): - """发单""" - self.tradeApi.sendOrder(orderReq) - - #---------------------------------------------------------------------- - def cancelOrder(self, cancelOrderReq): - """撤单""" - self.tradeApi.cancel(cancelOrderReq) - - #---------------------------------------------------------------------- - def qryAccount(self): - """查询账户资金""" - pass - - #---------------------------------------------------------------------- - def qryPosition(self): - """查询持仓""" - pass - - #---------------------------------------------------------------------- - def close(self): - """关闭""" - self.tradeApi.exit() - self.dataApi.exit() - - #---------------------------------------------------------------------- - def initQuery(self): - """初始化连续查询""" - if self.qryEnabled: - self.qryFunctionList = [self.tradeApi.queryWorkingOrders, self.tradeApi.queryAccount] - self.startQuery() - - #---------------------------------------------------------------------- - def query(self, event): - """注册到事件处理引擎上的查询函数""" - for function in self.qryFunctionList: - function() - - #---------------------------------------------------------------------- - def startQuery(self): - """启动连续查询""" - self.eventEngine.register(EVENT_TIMER, self.query) - - #---------------------------------------------------------------------- - def setQryEnabled(self, qryEnabled): - """设置是否要启动循环查询""" - self.qryEnabled = qryEnabled - - -######################################################################## -class HuobiTradeApi(vnhuobi.TradeApi): - """交易接口""" - - #---------------------------------------------------------------------- - def __init__(self, gateway): - """Constructor""" - super(HuobiTradeApi, self).__init__() - - self.gateway = gateway - self.gatewayName = gateway.gatewayName - - self.localID = 0 # 本地委托号 - self.localSystemDict = {} # key:localID, value:systemID - self.systemLocalDict = {} # key:systemID, value:localID - self.workingOrderDict = {} # key:localID, value:order - self.reqLocalDict = {} # key:reqID, value:localID - self.cancelDict = {} # key:localID, value:cancelOrderReq - - self.tradeID = 0 # 本地成交号 - - #---------------------------------------------------------------------- - def onError(self, error, req, reqID): - """错误推送""" - err = VtErrorData() - err.gatewayName = self.gatewayName - err.errorMsg = str(error) - err.errorTime = datetime.now().strftime('%H:%M:%S') - self.gateway.onError(err) - - #---------------------------------------------------------------------- - def onGetAccountInfo(self, data, req, reqID): - """查询账户回调""" - # 推送账户数据 - account = VtAccountData() - account.gatewayName = self.gatewayName - account.accountID = 'HUOBI' - account.vtAccountID = '.'.join([account.accountID, self.gatewayName]) - account.balance = data['net_asset'] - self.gateway.onAccount(account) - - # 推送持仓数据 - if self.market == 'cny': - posCny = VtPositionData() - posCny.gatewayName = self.gatewayName - posCny.symbol = 'CNY' - posCny.exchange = EXCHANGE_HUOBI - posCny.vtSymbol = '.'.join([posCny.symbol, posCny.exchange]) - posCny.vtPositionName = posCny.vtSymbol - posCny.position = data['available_cny_display'] - posCny.frozen = data['frozen_cny_display'] - self.gateway.onPosition(posCny) - - posLtc = VtPositionData() - posLtc.gatewayName = self.gatewayName - posLtc.symbol = 'LTC' - posLtc.exchange = EXCHANGE_HUOBI - posLtc.vtSymbol = '.'.join([posLtc.symbol, posLtc.exchange]) - posLtc.vtPositionName = posLtc.vtSymbol - posLtc.position = data['available_ltc_display'] - posLtc.frozen = data['frozen_ltc_display'] - self.gateway.onPosition(posLtc) - else: - posUsd = VtPositionData() - posUsd.gatewayName = self.gatewayName - posUsd.symbol = 'USD' - posUsd.exchange = EXCHANGE_HUOBI - posUsd.vtSymbol = '.'.join([posUsd.symbol, posUsd.exchange]) - posUsd.vtPositionName = posUsd.vtSymbol - posUsd.position = data['available_usd_display'] - posUsd.frozen = data['frozen_usd_display'] - self.gateway.onPosition(posUsd) - - posBtc = VtPositionData() - posBtc.gatewayName = self.gatewayName - posBtc.symbol = 'BTC' - posBtc.exchange = EXCHANGE_HUOBI - posBtc.vtSymbol = '.'.join([posBtc.symbol, posBtc.exchange]) - posBtc.vtPositionName = posBtc.vtSymbol - posBtc.position = data['available_btc_display'] - posBtc.frozen = data['frozen_btc_display'] - self.gateway.onPosition(posBtc) - - #---------------------------------------------------------------------- - def onGetOrders(self, data, req, reqID): - """查询委托回调""" - for d in data: - order = VtOrderData() - order.gatewayName = self.gatewayName - - # 合约代码 - params = req['params'] - coin = params['coin_type'] - order.symbol = SYMBOL_MAP[(coin, self.market)] - order.exchange = EXCHANGE_HUOBI - order.vtSymbol = '.'.join([order.symbol, order.exchange]) - - # 委托号 - systemID = d['id'] - self.localID += 1 - localID = str(self.localID) - self.systemLocalDict[systemID] = localID - self.localSystemDict[localID] = systemID - order.orderID = localID - order.vtOrderID = '.'.join([order.orderID, order.gatewayName]) - - # 其他信息 - order.direction = DIRECTION_MAP[d['type']] - order.offset = OFFSET_NONE - order.price = float(d['order_price']) - order.totalVolume = float(d['order_amount']) - order.tradedVolume = float(d['processed_amount']) - order.orderTime = d['order_time'] - - # 委托状态 - if order.tradedVolume == 0: - order.status = STATUS_NOTTRADED - else: - order.status = STATUS_PARTTRADED - - # 缓存病推送 - self.workingOrderDict[localID] = order - self.gateway.onOrder(order) - - #---------------------------------------------------------------------- - def onOrderInfo(self, data, req, reqID): - """委托详情回调""" - systemID = data['id'] - localID = self.systemLocalDict[systemID] - order = self.workingOrderDict.get(localID, None) - if not order: - return - - # 记录最新成交的金额 - newTradeVolume = float(data['processed_amount']) - order.tradedVolume - if newTradeVolume: - trade = VtTradeData() - trade.gatewayName = self.gatewayName - trade.symbol = order.symbol - trade.vtSymbol = order.vtSymbol - - self.tradeID += 1 - trade.tradeID = str(self.tradeID) - trade.vtTradeID = '.'.join([trade.tradeID, trade.gatewayName]) - - trade.volume = newTradeVolume - trade.price = data['processed_price'] - trade.direction = order.direction - trade.offset = order.offset - trade.exchange = order.exchange - trade.tradeTime = datetime.now().strftime('%H:%M:%S') - - self.gateway.onTrade(trade) - - # 更新委托状态 - order.tradedVolume = float(data['processed_amount']) - order.status = STATUS_MAP.get(data['status'], STATUS_UNKNOWN) - - if newTradeVolume: - self.gateway.onOrder(order) - - if order.status == STATUS_ALLTRADED or order.status == STATUS_CANCELLED: - del self.workingOrderDict[order.orderID] - - #---------------------------------------------------------------------- - def onBuy(self, data, req, reqID): - """买入回调""" - localID = self.reqLocalDict[reqID] - systemID = data['id'] - self.localSystemDict[localID] = systemID - self.systemLocalDict[systemID] = localID - - # 撤单 - if localID in self.cancelDict: - req = self.cancelDict[localID] - self.cancel(req) - del self.cancelDict[localID] - - # 推送委托信息 - order = self.workingOrderDict[localID] - if data['result'] == 'success': - order.status = STATUS_NOTTRADED - self.gateway.onOrder(order) - - #---------------------------------------------------------------------- - def onSell(self, data, req, reqID): - """卖出回调""" - localID = self.reqLocalDict[reqID] - systemID = data['id'] - self.localSystemDict[localID] = systemID - self.systemLocalDict[systemID] = localID - - # 撤单 - if localID in self.cancelDict: - req = self.cancelDict[localID] - self.cancel(req) - del self.cancelDict[localID] - - # 推送委托信息 - order = self.workingOrderDict[localID] - if data['result'] == 'success': - order.status = STATUS_NOTTRADED - self.gateway.onOrder(order) - - #---------------------------------------------------------------------- - def onBuyMarket(self, data, req, reqID): - """市价买入回调""" - print data - - #---------------------------------------------------------------------- - def onSellMarket(self, data, req, reqID): - """市价卖出回调""" - print data - - #---------------------------------------------------------------------- - def onCancelOrder(self, data, req, reqID): - """撤单回调""" - if data['result'] == 'success': - systemID = req['params']['id'] - localID = self.systemLocalDict[systemID] - - order = self.workingOrderDict[localID] - order.status = STATUS_CANCELLED - - del self.workingOrderDict[localID] - self.gateway.onOrder(order) - - #---------------------------------------------------------------------- - def onGetNewDealOrders(self, data, req, reqID): - """查询最新成交回调""" - print data - - #---------------------------------------------------------------------- - def onGetOrderIdByTradeId(self, data, req, reqID): - """通过成交编号查询委托编号回调""" - print data - - #---------------------------------------------------------------------- - def onWithdrawCoin(self, data, req, reqID): - """提币回调""" - print data - - #---------------------------------------------------------------------- - def onCancelWithdrawCoin(self, data, req, reqID): - """取消提币回调""" - print data - - #---------------------------------------------------------------------- - def onGetWithdrawCoinResult(self, data, req, reqID): - """查询提币结果回调""" - print data - - #---------------------------------------------------------------------- - def onTransfer(self, data, req, reqID): - """转账回调""" - print data - - #---------------------------------------------------------------------- - def onLoan(self, data, req, reqID): - """申请杠杆回调""" - print data - - #---------------------------------------------------------------------- - def onRepayment(self, data, req, reqID): - """归还杠杆回调""" - print data - - #---------------------------------------------------------------------- - def onLoanAvailable(self, data, req, reqID): - """查询杠杆额度回调""" - print data - - #---------------------------------------------------------------------- - def onGetLoans(self, data, req, reqID): - """查询杠杆列表""" - print data - - #---------------------------------------------------------------------- - def connect(self, accessKey, secretKey, market, debug=False): - """连接服务器""" - self.market = market - self.DEBUG = debug - - self.init(accessKey, secretKey) - - # 查询未成交委托 - self.getOrders(vnhuobi.COINTYPE_BTC, self.market) - - if self.market == vnhuobi.MARKETTYPE_CNY: - # 只有人民币市场才有莱特币 - self.getOrders(vnhuobi.COINTYPE_LTC, self.market) - - # ---------------------------------------------------------------------- - def queryWorkingOrders(self): - """查询活动委托状态""" - for order in self.workingOrderDict.values(): - # 如果尚未返回委托号,则无法查询 - if order.orderID in self.localSystemDict: - systemID = self.localSystemDict[order.orderID] - coin, market = SYMBOL_MAP_REVERSE[order.symbol] - self.orderInfo(systemID, coin, market) - - # ---------------------------------------------------------------------- - def queryAccount(self): - """查询活动委托状态""" - self.getAccountInfo(self.market) - - # ---------------------------------------------------------------------- - def sendOrder(self, req): - """发送委托""" - # 检查是否填入了价格,禁止市价委托 - if req.priceType != PRICETYPE_LIMITPRICE: - err = VtErrorData() - err.gatewayName = self.gatewayName - err.errorMsg = u'火币接口仅支持限价单' - err.errorTime = datetime.now().strftime('%H:%M:%S') - self.gateway.onError(err) - return None - - # 发送限价委托 - coin, market = SYMBOL_MAP_REVERSE[req.symbol] - - if req.direction == DIRECTION_LONG: - reqID = self.buy(req.price, req.volume, coinType=coin, market=self.market) - else: - reqID = self.sell(req.price, req.volume, coinType=coin, market=self.market) - - self.localID += 1 - localID = str(self.localID) - self.reqLocalDict[reqID] = localID - - # 推送委托信息 - order = VtOrderData() - order.gatewayName = self.gatewayName - - order.symbol = req.symbol - order.exchange = EXCHANGE_HUOBI - order.vtSymbol = '.'.join([order.symbol, order.exchange]) - - order.orderID = localID - order.vtOrderID = '.'.join([order.orderID, order.gatewayName]) - - order.direction = req.direction - order.offset = OFFSET_UNKNOWN - order.price = req.price - order.volume = req.volume - order.orderTime = datetime.now().strftime('%H:%M:%S') - order.status = STATUS_UNKNOWN - - self.workingOrderDict[localID] = order - self.gateway.onOrder(order) - - # 返回委托号 - return order.vtOrderID - - # ---------------------------------------------------------------------- - def cancel(self, req): - """撤单""" - localID = req.orderID - if localID in self.localSystemDict: - systemID = self.localSystemDict[localID] - coin, market = SYMBOL_MAP_REVERSE[req.symbol] - self.cancelOrder(systemID, coin, self.market) - else: - self.cancelDict[localID] = req - - -######################################################################## -class HuobiDataApi(vnhuobi.DataApi): - """行情接口""" - - #---------------------------------------------------------------------- - def __init__(self, gateway): - """Constructor""" - super(HuobiDataApi, self).__init__() - - self.market = 'cny' - - self.gateway = gateway - self.gatewayName = gateway.gatewayName - - self.tickDict = {} # key:symbol, value:tick - - - #---------------------------------------------------------------------- - def onTick(self, data): - """实时成交推送""" - print data - - #---------------------------------------------------------------------- - def onQuote(self, data): - """实时报价推送""" - ticker = data['ticker'] - symbol = MDSYMBOL_MAP[ticker['symbol']] - - if symbol not in self.tickDict: - tick = VtTickData() - tick.gatewayName = self.gatewayName - - tick.symbol = symbol - tick.exchange = EXCHANGE_HUOBI - tick.vtSymbol = '.'.join([tick.symbol, tick.exchange]) - self.tickDict[symbol] = tick - else: - tick = self.tickDict[symbol] - - tick.highPrice = ticker['high'] - tick.lowPrice = ticker['low'] - tick.lastPrice = ticker['last'] - tick.volume = ticker['vol'] - - #---------------------------------------------------------------------- - def onDepth(self, data): - """实时深度推送""" - symbol = MDSYMBOL_MAP[data['symbol']] - if symbol not in self.tickDict: - tick = VtTickData() - tick.gatewayName = self.gatewayName - - tick.symbol = symbol - tick.exchange = EXCHANGE_HUOBI - tick.vtSymbol = '.'.join([tick.symbol, tick.exchange]) - self.tickDict[symbol] = tick - else: - tick = self.tickDict[symbol] - - tick.bidPrice1, tick.bidVolume1 = data['bids'][0] - tick.bidPrice2, tick.bidVolume2 = data['bids'][1] - tick.bidPrice3, tick.bidVolume3 = data['bids'][2] - tick.bidPrice4, tick.bidVolume4 = data['bids'][3] - tick.bidPrice5, tick.bidVolume5 = data['bids'][4] - - tick.askPrice1, tick.askVolume1 = data['asks'][0] - tick.askPrice2, tick.askVolume2 = data['asks'][1] - tick.askPrice3, tick.askVolume3 = data['asks'][2] - tick.askPrice4, tick.askVolume4 = data['asks'][3] - tick.askPrice5, tick.askVolume5 = data['asks'][4] - - now = datetime.now() - tick.time = now.strftime('%H:%M:%S') - tick.date = now.strftime('%Y%m%d') - - self.gateway.onTick(tick) - - #---------------------------------------------------------------------- - def connect(self, interval, market, debug=False): - """连接服务器""" - self.market = market - - self.init(interval, debug) - - # 订阅行情并推送合约信息 - if self.market == vnhuobi.MARKETTYPE_CNY: - self.subscribeQuote(vnhuobi.SYMBOL_BTCCNY) - self.subscribeQuote(vnhuobi.SYMBOL_LTCCNY) - - self.subscribeDepth(vnhuobi.SYMBOL_BTCCNY, 5) - self.subscribeDepth(vnhuobi.SYMBOL_LTCCNY, 5) - - contract = VtContractData() - contract.gatewayName = self.gatewayName - contract.symbol = SYMBOL_BTCCNY - contract.exchange = EXCHANGE_HUOBI - contract.vtSymbol = '.'.join([contract.symbol, contract.exchange]) - contract.name = u'人民币现货BTC' - contract.size = 1 - contract.priceTick = 0.01 - contract.productClass = PRODUCT_SPOT - self.gateway.onContract(contract) - - contract = VtContractData() - contract.gatewayName = self.gatewayName - contract.symbol = SYMBOL_LTCCNY - contract.exchange = EXCHANGE_HUOBI - contract.vtSymbol = '.'.join([contract.symbol, contract.exchange]) - contract.name = u'人民币现货LTC' - contract.size = 1 - contract.priceTick = 0.01 - contract.productClass = PRODUCT_SPOT - self.gateway.onContract(contract) - else: - self.subscribeQuote(vnhuobi.SYMBOL_BTCUSD) - - self.subscribeDepth(vnhuobi.SYMBOL_BTCUSD) - - contract = VtContractData() - contract.gatewayName = self.gatewayName - contract.symbol = SYMBOL_BTCUSD - contract.exchange = EXCHANGE_HUOBI - contract.vtSymbol = '.'.join([contract.symbol, contract.exchange]) - contract.name = u'美元现货BTC' - contract.size = 1 - contract.priceTick = 0.01 - contract.productClass = PRODUCT_SPOT - self.gateway.onContract(contract) - - - - - diff --git a/vnpy/trader/gateway/lbankGateway/lbankGateway.py b/vnpy/trader/gateway/lbankGateway/lbankGateway.py index 8028e6b0..85f82ae3 100644 --- a/vnpy/trader/gateway/lbankGateway/lbankGateway.py +++ b/vnpy/trader/gateway/lbankGateway/lbankGateway.py @@ -38,7 +38,7 @@ STATUS_MAP[-1] = STATUS_CANCELLED ######################################################################## class LbankGateway(VtGateway): - """链行接口""" + """LBANK接口""" #---------------------------------------------------------------------- def __init__(self, eventEngine, gatewayName='LBANK'): @@ -195,7 +195,7 @@ class LbankApi(LbankApi): tick.gatewayName = self.gatewayName tick.symbol = symbol - tick.exchange = EXCHANGE_LHANG + tick.exchange = EXCHANGE_LBANK tick.vtSymbol = '.'.join([tick.symbol, tick.exchange]) self.tickDict[symbol] = tick else: @@ -217,7 +217,7 @@ class LbankApi(LbankApi): tick.gatewayName = self.gatewayName tick.symbol = symbol - tick.exchange = EXCHANGE_LHANG + tick.exchange = EXCHANGE_LBANK tick.vtSymbol = '.'.join([tick.symbol, tick.exchange]) self.tickDict[symbol] = tick else: @@ -265,7 +265,7 @@ class LbankApi(LbankApi): posCny = VtPositionData() posCny.gatewayName = self.gatewayName posCny.symbol = 'CNY' - posCny.exchange = EXCHANGE_LHANG + posCny.exchange = EXCHANGE_LBANK posCny.vtSymbol = '.'.join([posCny.symbol, posCny.exchange]) posCny.vtPositionName = posCny.vtSymbol posCny.frozen = d['freeze']['cny'] @@ -275,7 +275,7 @@ class LbankApi(LbankApi): posBtc = VtPositionData() posBtc.gatewayName = self.gatewayName posBtc.symbol = 'BTC' - posBtc.exchange = EXCHANGE_LHANG + posBtc.exchange = EXCHANGE_LBANK posBtc.vtSymbol = '.'.join([posBtc.symbol, posBtc.exchange]) posBtc.vtPositionName = posBtc.vtSymbol posBtc.frozen = d['freeze']['btc'] @@ -285,7 +285,7 @@ class LbankApi(LbankApi): posZec = VtPositionData() posZec.gatewayName = self.gatewayName posZec.symbol = 'ZEC' - posZec.exchange = EXCHANGE_LHANG + posZec.exchange = EXCHANGE_LBANK posZec.vtSymbol = '.'.join([posZec.symbol, posZec.exchange]) posZec.vtPositionName = posZec.vtSymbol posZec.frozen = d['freeze']['zec'] @@ -379,7 +379,7 @@ class LbankApi(LbankApi): order.gatewayName = self.gatewayName order.symbol = SYMBOL_MAP[data['symbol']] - order.exchange = EXCHANGE_LHANG + order.exchange = EXCHANGE_LBANK order.vtSymbol = '.'.join([order.symbol, order.exchange]) systemID = d['order_id'] @@ -419,7 +419,7 @@ class LbankApi(LbankApi): contract = VtContractData() contract.gatewayName = self.gatewayName contract.symbol = SYMBOL_BTCCNY - contract.exchange = EXCHANGE_LHANG + contract.exchange = EXCHANGE_LBANK contract.vtSymbol = '.'.join([contract.symbol, contract.exchange]) contract.name = u'人民币现货BTC' contract.size = 1 @@ -430,7 +430,7 @@ class LbankApi(LbankApi): contract = VtContractData() contract.gatewayName = self.gatewayName contract.symbol = SYMBOL_ZECCNY - contract.exchange = EXCHANGE_LHANG + contract.exchange = EXCHANGE_LBANK contract.vtSymbol = '.'.join([contract.symbol, contract.exchange]) contract.name = u'人民币现货ZEC' contract.size = 1 @@ -441,12 +441,11 @@ class LbankApi(LbankApi): #---------------------------------------------------------------------- def sendOrder(self, req): """发单""" - """发送委托""" # 检查是否填入了价格,禁止市价委托 if req.priceType != PRICETYPE_LIMITPRICE: err = VtErrorData() err.gatewayName = self.gatewayName - err.errorMsg = u'链行接口仅支持限价单' + err.errorMsg = u'LBANK接口仅支持限价单' err.errorTime = datetime.now().strftime('%H:%M:%S.%f')[:-3] self.gateway.onError(err) return None @@ -470,7 +469,7 @@ class LbankApi(LbankApi): order.gatewayName = self.gatewayName order.symbol = req.symbol - order.exchange = EXCHANGE_LHANG + order.exchange = EXCHANGE_LBANK order.vtSymbol = '.'.join([order.symbol, order.exchange]) order.orderID = localID diff --git a/vnpy/trader/gateway/okcoinGateway/OKCOIN_connect.json b/vnpy/trader/gateway/okcoinGateway/OKCOIN_connect.json deleted file mode 100644 index 8240e55e..00000000 --- a/vnpy/trader/gateway/okcoinGateway/OKCOIN_connect.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "host": "CNY", - "apiKey": "OKCOIN网站申请", - "secretKey": "OKCOIN网站申请", - "trace": false, - "leverage": 20 -} \ No newline at end of file diff --git a/vnpy/trader/gateway/okcoinGateway/__init__.py b/vnpy/trader/gateway/okcoinGateway/__init__.py deleted file mode 100644 index b41a3ecf..00000000 --- a/vnpy/trader/gateway/okcoinGateway/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -# encoding: UTF-8 - -from vnpy.trader import vtConstant -from okcoinGateway import OkcoinGateway - -gatewayClass = OkcoinGateway -gatewayName = 'OKCOIN' -gatewayDisplayName = u'币行' -gatewayType = vtConstant.GATEWAYTYPE_BTC -gatewayQryEnabled = True - diff --git a/vnpy/trader/gateway/okcoinGateway/okcoinGateway.py b/vnpy/trader/gateway/okcoinGateway/okcoinGateway.py deleted file mode 100644 index fb540012..00000000 --- a/vnpy/trader/gateway/okcoinGateway/okcoinGateway.py +++ /dev/null @@ -1,734 +0,0 @@ -# encoding: UTF-8 - -''' -vn.okcoin的gateway接入 - -注意: -1. 前仅支持USD和CNY的现货交易,USD的期货合约交易暂不支持 -''' - - -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.okcoin import vnokcoin -from vnpy.trader.vtGateway import * -from vnpy.trader.vtFunction import getJsonPath - -# 价格类型映射 -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()} - -# 方向类型映射 -directionMap = {} -directionMapReverse = {v: k for k, v in directionMap.items()} - -# 委托状态印射 -statusMap = {} -statusMap[-1] = STATUS_CANCELLED -statusMap[0] = STATUS_NOTTRADED -statusMap[1] = STATUS_PARTTRADED -statusMap[2] = STATUS_ALLTRADED -statusMap[4] = STATUS_UNKNOWN - -############################################ -## 交易合约代码 -############################################ - -# USD -BTC_USD_SPOT = 'BTC_USD_SPOT' -BTC_USD_THISWEEK = 'BTC_USD_THISWEEK' -BTC_USD_NEXTWEEK = 'BTC_USD_NEXTWEEK' -BTC_USD_QUARTER = 'BTC_USD_QUARTER' - -LTC_USD_SPOT = 'LTC_USD_SPOT' -LTC_USD_THISWEEK = 'LTC_USD_THISWEEK' -LTC_USD_NEXTWEEK = 'LTC_USD_NEXTWEEK' -LTC_USD_QUARTER = 'LTC_USD_QUARTER' - -ETH_USD_SPOT = 'ETH_USD_SPOT' -ETH_USD_THISWEEK = 'ETH_USD_THISWEEK' -ETH_USD_NEXTWEEK = 'ETH_USD_NEXTWEEK' -ETH_USD_QUARTER = 'ETH_USD_QUARTER' - -# CNY -BTC_CNY_SPOT = 'BTC_CNY_SPOT' -LTC_CNY_SPOT = 'LTC_CNY_SPOT' -ETH_CNY_SPOT = 'ETH_CNY_SPOT' - -# 印射字典 -spotSymbolMap = {} -spotSymbolMap['ltc_usd'] = LTC_USD_SPOT -spotSymbolMap['btc_usd'] = BTC_USD_SPOT -spotSymbolMap['ETH_usd'] = ETH_USD_SPOT -spotSymbolMap['ltc_cny'] = LTC_CNY_SPOT -spotSymbolMap['btc_cny'] = BTC_CNY_SPOT -spotSymbolMap['eth_cny'] = ETH_CNY_SPOT -spotSymbolMapReverse = {v: k for k, v in spotSymbolMap.items()} - - -############################################ -## Channel和Symbol的印射 -############################################ -channelSymbolMap = {} - -# USD -channelSymbolMap['ok_sub_spotusd_btc_ticker'] = BTC_USD_SPOT -channelSymbolMap['ok_sub_spotusd_ltc_ticker'] = LTC_USD_SPOT -channelSymbolMap['ok_sub_spotusd_eth_ticker'] = ETH_USD_SPOT - -channelSymbolMap['ok_sub_spotusd_btc_depth_20'] = BTC_USD_SPOT -channelSymbolMap['ok_sub_spotusd_ltc_depth_20'] = LTC_USD_SPOT -channelSymbolMap['ok_sub_spotusd_eth_depth_20'] = ETH_USD_SPOT - -# CNY -channelSymbolMap['ok_sub_spotcny_btc_ticker'] = BTC_CNY_SPOT -channelSymbolMap['ok_sub_spotcny_ltc_ticker'] = LTC_CNY_SPOT -channelSymbolMap['ok_sub_spotcny_eth_ticker'] = ETH_CNY_SPOT - -channelSymbolMap['ok_sub_spotcny_btc_depth_20'] = BTC_CNY_SPOT -channelSymbolMap['ok_sub_spotcny_ltc_depth_20'] = LTC_CNY_SPOT -channelSymbolMap['ok_sub_spotcny_eth_depth_20'] = ETH_CNY_SPOT - - - - -######################################################################## -class OkcoinGateway(VtGateway): - """OkCoin接口""" - - #---------------------------------------------------------------------- - def __init__(self, eventEngine, gatewayName='OKCOIN'): - """Constructor""" - super(OkcoinGateway, self).__init__(eventEngine, gatewayName) - - self.api = Api(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: - host = str(setting['host']) - 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 - - if host == 'CNY': - host = vnokcoin.OKCOIN_CNY - else: - host = vnokcoin.OKCOIN_USD - - self.api.active = True - self.api.connect(host, apiKey, secretKey, trace) - - log = VtLogData() - log.gatewayName = self.gatewayName - log.logContent = u'接口初始化成功' - self.onLog(log) - - # 启动查询 - self.initQuery() - self.startQuery() - - #---------------------------------------------------------------------- - def subscribe(self, subscribeReq): - """订阅行情""" - pass - - #---------------------------------------------------------------------- - def sendOrder(self, orderReq): - """发单""" - return self.api.spotSendOrder(orderReq) - - #---------------------------------------------------------------------- - def cancelOrder(self, cancelOrderReq): - """撤单""" - self.api.spotCancel(cancelOrderReq) - - #---------------------------------------------------------------------- - def qryAccount(self): - """查询账户资金""" - self.api.spotUserInfo() - - #---------------------------------------------------------------------- - def qryPosition(self): - """查询持仓""" - pass - - #---------------------------------------------------------------------- - def close(self): - """关闭""" - self.api.active = False - self.api.close() - - #---------------------------------------------------------------------- - def initQuery(self): - """初始化连续查询""" - if self.qryEnabled: - # 需要循环的查询函数列表 - self.qryFunctionList = [self.qryAccount] - - 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 Api(vnokcoin.OkCoinApi): - """OkCoin的API实现""" - - #---------------------------------------------------------------------- - def __init__(self, gateway): - """Constructor""" - super(Api, self).__init__() - - self.gateway = gateway # gateway对象 - self.gatewayName = gateway.gatewayName # gateway对象名称 - - self.active = False # 若为True则会在断线后自动重连 - - self.cbDict = {} - self.tickDict = {} - self.orderDict = {} - - self.localNo = 0 # 本地委托号 - self.localNoQueue = Queue() # 未收到系统委托号的本地委托号队列 - self.localNoDict = {} # key为本地委托号,value为系统委托号 - self.orderIdDict = {} # key为系统委托号,value为本地委托号 - self.cancelDict = {} # key为本地委托号,value为撤单请求 - - self.initCallback() - - #---------------------------------------------------------------------- - def onMessage(self, ws, evt): - """信息推送""" - data = self.readData(evt)[0] - channel = data['channel'] - callback = self.cbDict[channel] - callback(data) - - #---------------------------------------------------------------------- - def onError(self, ws, evt): - """错误推送""" - error = VtErrorData() - error.gatewayName = self.gatewayName - error.errorMsg = str(evt) - 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 onOpen(self, ws): - """连接成功""" - self.gateway.connected = True - self.writeLog(u'服务器连接成功') - - # 连接后查询账户和委托数据 - self.spotUserInfo() - - self.spotOrderInfo(vnokcoin.TRADING_SYMBOL_LTC, '-1') - self.spotOrderInfo(vnokcoin.TRADING_SYMBOL_BTC, '-1') - self.spotOrderInfo(vnokcoin.TRADING_SYMBOL_ETH, '-1') - - # 连接后订阅现货的成交和账户数据 - self.subscribeSpotTrades() - self.subscribeSpotUserInfo() - - self.subscribeSpotTicker(vnokcoin.SYMBOL_BTC) - self.subscribeSpotTicker(vnokcoin.SYMBOL_LTC) - self.subscribeSpotTicker(vnokcoin.SYMBOL_ETH) - - self.subscribeSpotDepth(vnokcoin.SYMBOL_BTC, vnokcoin.DEPTH_20) - self.subscribeSpotDepth(vnokcoin.SYMBOL_LTC, vnokcoin.DEPTH_20) - self.subscribeSpotDepth(vnokcoin.SYMBOL_ETH, vnokcoin.DEPTH_20) - - # 如果连接的是USD网站则订阅期货相关回报数据 - if self.currency == vnokcoin.CURRENCY_USD: - self.subscribeFutureTrades() - self.subscribeFutureUserInfo() - self.subscribeFuturePositions() - - # 返回合约信息 - if self.currency == vnokcoin.CURRENCY_CNY: - l = self.generateCnyContract() - else: - l = self.generateUsdContract() - - for contract in l: - contract.gatewayName = self.gatewayName - self.gateway.onContract(contract) - - #---------------------------------------------------------------------- - def writeLog(self, content): - """快速记录日志""" - log = VtLogData() - log.gatewayName = self.gatewayName - log.logContent = content - self.gateway.onLog(log) - - #---------------------------------------------------------------------- - def initCallback(self): - """初始化回调函数""" - # USD_SPOT - self.cbDict['ok_sub_spotusd_btc_ticker'] = self.onTicker - self.cbDict['ok_sub_spotusd_ltc_ticker'] = self.onTicker - self.cbDict['ok_sub_spotusd_eth_ticker'] = self.onTicker - - self.cbDict['ok_sub_spotusd_btc_depth_20'] = self.onDepth - self.cbDict['ok_sub_spotusd_ltc_depth_20'] = self.onDepth - self.cbDict['ok_sub_spotusd_eth_depth_20'] = self.onDepth - - self.cbDict['ok_spotusd_userinfo'] = self.onSpotUserInfo - self.cbDict['ok_spotusd_orderinfo'] = self.onSpotOrderInfo - - self.cbDict['ok_sub_spotusd_userinfo'] = self.onSpotSubUserInfo - self.cbDict['ok_sub_spotusd_trades'] = self.onSpotSubTrades - - self.cbDict['ok_spotusd_trade'] = self.onSpotTrade - self.cbDict['ok_spotusd_cancel_order'] = self.onSpotCancelOrder - - # CNY_SPOT - self.cbDict['ok_sub_spotcny_btc_ticker'] = self.onTicker - self.cbDict['ok_sub_spotcny_ltc_ticker'] = self.onTicker - self.cbDict['ok_sub_spotcny_eth_ticker'] = self.onTicker - - self.cbDict['ok_sub_spotcny_btc_depth_20'] = self.onDepth - self.cbDict['ok_sub_spotcny_ltc_depth_20'] = self.onDepth - self.cbDict['ok_sub_spotcny_eth_depth_20'] = self.onDepth - - self.cbDict['ok_spotcny_userinfo'] = self.onSpotUserInfo - self.cbDict['ok_spotcny_orderinfo'] = self.onSpotOrderInfo - - self.cbDict['ok_sub_spotcny_userinfo'] = self.onSpotSubUserInfo - self.cbDict['ok_sub_spotcny_trades'] = self.onSpotSubTrades - - self.cbDict['ok_spotcny_trade'] = self.onSpotTrade - self.cbDict['ok_spotcny_cancel_order'] = self.onSpotCancelOrder - - # USD_FUTURES - - #---------------------------------------------------------------------- - def onTicker(self, data): - """""" - if 'data' not in data: - return - - channel = data['channel'] - symbol = channelSymbolMap[channel] - - 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] - - rawData = data['data'] - tick.highPrice = float(rawData['high']) - tick.lowPrice = float(rawData['low']) - tick.lastPrice = float(rawData['last']) - tick.volume = float(rawData['vol']) - #tick.date, tick.time = generateDateTime(rawData['timestamp']) - - newtick = copy(tick) - self.gateway.onTick(newtick) - - #---------------------------------------------------------------------- - def onDepth(self, data): - """""" - if 'data' not in data: - return - - channel = data['channel'] - symbol = channelSymbolMap[channel] - - 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 = generateDateTime(rawData['timestamp']) - - newtick = copy(tick) - self.gateway.onTick(newtick) - - #---------------------------------------------------------------------- - def onSpotUserInfo(self, data): - """现货账户资金推送""" - rawData = data['data'] - info = rawData['info'] - funds = rawData['info']['funds'] - - # 持仓信息 - for symbol in ['btc', 'ltc','eth', self.currency]: - if symbol in funds['free']: - pos = VtPositionData() - pos.gatewayName = self.gatewayName - - pos.symbol = symbol - pos.vtSymbol = symbol - 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 = float(funds['asset']['net']) - self.gateway.onAccount(account) - - #---------------------------------------------------------------------- - def onSpotSubUserInfo(self, data): - """现货账户资金推送""" - if 'data' not in data: - return - - rawData = data['data'] - info = rawData['info'] - - # 持仓信息 - for symbol in ['btc', 'ltc','eth', self.currency]: - if symbol in info['free']: - pos = VtPositionData() - pos.gatewayName = self.gatewayName - - pos.symbol = symbol - pos.vtSymbol = symbol - 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) - - #---------------------------------------------------------------------- - def onSpotSubTrades(self, data): - """成交和委托推送""" - if 'data' not in data: - return - rawData = data['data'] - - # 本地和系统委托号 - orderId = str(rawData['orderId']) - localNo = self.orderIdDict[orderId] - - # 委托信息 - if orderId not in self.orderDict: - order = VtOrderData() - order.gatewayName = self.gatewayName - - 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)) - - # 成交信息 - 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) - - #---------------------------------------------------------------------- - def onSpotOrderInfo(self, data): - """委托信息查询回调""" - 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.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)) - - #---------------------------------------------------------------------- - def generateSpecificContract(self, contract, symbol): - """生成合约""" - new = copy(contract) - new.symbol = symbol - new.vtSymbol = symbol - new.name = symbol - return new - - #---------------------------------------------------------------------- - def generateCnyContract(self): - """生成CNY合约信息""" - contractList = [] - - contract = VtContractData() - contract.exchange = EXCHANGE_OKCOIN - contract.productClass = PRODUCT_SPOT - contract.size = 1 - contract.priceTick = 0.01 - - contractList.append(self.generateSpecificContract(contract, BTC_CNY_SPOT)) - contractList.append(self.generateSpecificContract(contract, LTC_CNY_SPOT)) - contractList.append(self.generateSpecificContract(contract, ETH_CNY_SPOT)) - - return contractList - - #---------------------------------------------------------------------- - def generateUsdContract(self): - """生成USD合约信息""" - contractList = [] - - # 现货 - contract = VtContractData() - contract.exchange = EXCHANGE_OKCOIN - contract.productClass = PRODUCT_SPOT - contract.size = 1 - contract.priceTick = 0.01 - - contractList.append(self.generateSpecificContract(contract, BTC_USD_SPOT)) - contractList.append(self.generateSpecificContract(contract, LTC_USD_SPOT)) - contractList.append(self.generateSpecificContract(contract, ETH_USD_SPOT)) - - # 期货 - contract.productClass = PRODUCT_FUTURES - - contractList.append(self.generateSpecificContract(contract, BTC_USD_THISWEEK)) - contractList.append(self.generateSpecificContract(contract, BTC_USD_NEXTWEEK)) - contractList.append(self.generateSpecificContract(contract, BTC_USD_QUARTER)) - contractList.append(self.generateSpecificContract(contract, LTC_USD_THISWEEK)) - contractList.append(self.generateSpecificContract(contract, LTC_USD_NEXTWEEK)) - contractList.append(self.generateSpecificContract(contract, LTC_USD_QUARTER)) - contractList.append(self.generateSpecificContract(contract, ETH_USD_THISWEEK)) - contractList.append(self.generateSpecificContract(contract, ETH_USD_NEXTWEEK)) - contractList.append(self.generateSpecificContract(contract, ETH_USD_QUARTER)) - - return contractList - - #---------------------------------------------------------------------- - def onSpotTrade(self, data): - """委托回报""" - rawData = data['data'] - orderId = rawData['order_id'] - - # 尽管websocket接口的委托号返回是异步的,但经过测试是 - # 符合先发现回的规律,因此这里通过queue获取之前发送的 - # 本地委托号,并把它和推送的系统委托号进行映射 - localNo = self.localNoQueue.get_nowait() - - self.localNoDict[localNo] = orderId - self.orderIdDict[orderId] = localNo - - # 检查是否有系统委托号返回前就发出的撤单请求,若有则进 - # 行撤单操作 - if localNo in self.cancelDict: - req = self.cancelDict[localNo] - self.spotCancel(req) - del self.cancelDict[localNo] - - #---------------------------------------------------------------------- - def onSpotCancelOrder(self, data): - """撤单回报""" - pass - - #---------------------------------------------------------------------- - def spotSendOrder(self, req): - """发单""" - symbol = spotSymbolMapReverse[req.symbol][:4] - 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] - localNo = req.orderID - - if localNo in self.localNoDict: - orderID = self.localNoDict[localNo] - self.spotCancelOrder(symbol, orderID) - else: - # 如果在系统委托号返回前客户就发送了撤单请求,则保存 - # 在cancelDict字典中,等待返回后执行撤单任务 - self.cancelDict[localNo] = req - -#---------------------------------------------------------------------- -def generateDateTime(s): - """生成时间""" - dt = datetime.fromtimestamp(float(s)/1e3) - time = dt.strftime("%H:%M:%S.%f") - date = dt.strftime("%Y%m%d") - return date, time \ No newline at end of file diff --git a/vnpy/trader/language/chinese/constant.py b/vnpy/trader/language/chinese/constant.py index 06f7e342..b4788d46 100644 --- a/vnpy/trader/language/chinese/constant.py +++ b/vnpy/trader/language/chinese/constant.py @@ -81,15 +81,15 @@ EXCHANGE_ICE = 'ICE' # ICE交易所 EXCHANGE_LME = 'LME' # LME交易所 EXCHANGE_OANDA = 'OANDA' # OANDA外汇做市商 -EXCHANGE_OKCOIN = 'OKCOIN' # OKCOIN比特币交易所 -EXCHANGE_HUOBI = 'HUOBI' # 火币比特币交易所 -EXCHANGE_LHANG = 'LHANG' # 链行比特币交易所 -EXCHANGE_KORBIT = 'KORBIT' # KORBIT 韩国交易所 -EXCHANGE_ZB = 'ZB' # ZB 中国比特币交易所 (比特币中国) -EXCHANGE_OKEX = 'OKEX' # OKEX 中国比特币交易所 (okcoin) -EXCHANGE_ZAIF = "ZAIF" # ZAIF 日本比特币交易所 -EXCHANGE_COINCHECK = "COINCHECK" # COINCHECK 日本比特币交易所 +EXCHANGE_OKCOIN = 'OKCOIN' # OKCOIN比特币交易所 +EXCHANGE_HUOBI = 'HUOBI' # 火币比特币交易所 +EXCHANGE_LBANK = 'LBANK' # LBANK比特币交易所 +EXCHANGE_KORBIT = 'KORBIT' # KORBIT韩国交易所 +EXCHANGE_ZB = 'ZB' # 比特币中国比特币交易所 +EXCHANGE_OKEX = 'OKEX' # OKEX比特币交易所 +EXCHANGE_ZAIF = "ZAIF" # ZAIF日本比特币交易所 +EXCHANGE_COINCHECK = "COINCHECK" # COINCHECK日本比特币交易所 # 货币类型 CURRENCY_USD = 'USD' # 美元 diff --git a/vnpy/trader/language/english/constant.py b/vnpy/trader/language/english/constant.py index bd8be331..96d9131a 100644 --- a/vnpy/trader/language/english/constant.py +++ b/vnpy/trader/language/english/constant.py @@ -77,15 +77,15 @@ EXCHANGE_ICE = 'ICE' # ICE交易所 EXCHANGE_LME = 'LME' # LME交易所 EXCHANGE_OANDA = 'OANDA' # OANDA外汇做市商 -EXCHANGE_OKCOIN = 'OKCOIN' # OKCOIN比特币交易所 -EXCHANGE_HUOBI = 'HUOBI' # 火币比特币交易所 -EXCHANGE_LHANG = 'LHANG' # 链行比特币交易所 -EXCHANGE_KORBIT = 'KORBIT' # KORBIT 韩国交易所 -EXCHANGE_ZB = 'ZB' # ZB 中国比特币交易所 (比特币中国) -EXCHANGE_OKEX = 'OKEX' # OKEX 中国比特币交易所 (okcoin) -EXCHANGE_ZAIF = "ZAIF" # ZAIF 日本比特币交易所 尚未实现 -EXCHANGE_COINCHECK = "COINCHECK" # COINCHECK 日本比特币交易所 +EXCHANGE_OKCOIN = 'OKCOIN' # OKCOIN比特币交易所 +EXCHANGE_HUOBI = 'HUOBI' # 火币比特币交易所 +EXCHANGE_LBANK = 'LBANK' # LBANK比特币交易所 +EXCHANGE_KORBIT = 'KORBIT' # KORBIT韩国交易所 +EXCHANGE_ZB = 'ZB' # 比特币中国比特币交易所 +EXCHANGE_OKEX = 'OKEX' # OKEX比特币交易所 +EXCHANGE_ZAIF = "ZAIF" # ZAIF日本比特币交易所 +EXCHANGE_COINCHECK = "COINCHECK" # COINCHECK日本比特币交易所 # 货币类型 CURRENCY_USD = 'USD' # 美元