From 27cca97c7e4e64a74e3873b2173570f22bec305b Mon Sep 17 00:00:00 2001 From: chenxy123 Date: Sun, 5 Feb 2017 00:18:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0vn.huobi=E7=9A=84=E8=A1=8C?= =?UTF-8?q?=E6=83=85=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vn.huobi/README.md | 2 +- vn.huobi/test.py | 34 +++++++++- vn.huobi/vnhuobi.py | 159 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 186 insertions(+), 9 deletions(-) diff --git a/vn.huobi/README.md b/vn.huobi/README.md index 8ebafe71..1e34903f 100644 --- a/vn.huobi/README.md +++ b/vn.huobi/README.md @@ -2,7 +2,7 @@ ### 简介 -火币的比特币交易接口,基于Rest API(交易)和Websocket API(行情)开发,实现了官方提供API的全部功能。 +火币的比特币交易接口,基于Rest API开发,实现了官方提供API的全部功能。 ### 特点 相比较于[火币官方](http://github.com/huobiapi/API_Docs/)给出的Python API实现,vn.huobi的一些特点: diff --git a/vn.huobi/test.py b/vn.huobi/test.py index c75dc950..7a48fcef 100644 --- a/vn.huobi/test.py +++ b/vn.huobi/test.py @@ -2,8 +2,9 @@ from vnhuobi import * - -if __name__ == '__main__': +#---------------------------------------------------------------------- +def testTrade(): + """测试交易""" accessKey = '' secretKey = '' @@ -35,3 +36,32 @@ if __name__ == '__main__': # 阻塞 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/vn.huobi/vnhuobi.py b/vn.huobi/vnhuobi.py index eddafc68..d81dfa27 100644 --- a/vn.huobi/vnhuobi.py +++ b/vn.huobi/vnhuobi.py @@ -5,10 +5,11 @@ import hashlib import json import requests -from time import time +from time import time, sleep from Queue import Queue, Empty from threading import Thread + # 常量定义 COINTYPE_BTC = 1 COINTYPE_LTC = 2 @@ -24,9 +25,24 @@ LOANTYPE_USD = 4 MARKETTYPE_CNY = 'cny' MARKETTYPE_USD = 'usd' -# API相关定义 -HUOBI_SERVICE_API="https://api.huobi.com/apiv3" +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' @@ -63,7 +79,7 @@ def signature(params): ######################################################################## class TradeApi(object): - """""" + """交易接口""" DEBUG = True #---------------------------------------------------------------------- @@ -103,7 +119,7 @@ class TradeApi(object): # 发送请求 payload = urllib.urlencode(params) - r = requests.post(HUOBI_SERVICE_API, params=payload) + r = requests.post(HUOBI_TRADE_API_API, params=payload) if r.status_code == 200: data = r.json() return data @@ -500,4 +516,135 @@ class TradeApi(object): #---------------------------------------------------------------------- def onGetLoans(self, data, reqID): """查询杠杆列表""" - print data \ No newline at end of file + 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=True): + """初始化""" + self.taskInterval = interval + self.DEBUG = debug + + self.active = True + self.taskThread.start() + + #---------------------------------------------------------------------- + def stop(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