REST API 簡介
火幣為用戶提供了一套全新的API,可以幫用戶快速接入火幣PRO站及HADAX站的交易系統,實現程序化交易。
| 訪問地址 | 適用站點 | 適用功能 | 適用交易對 |
|---|---|---|---|
| https://api.huobipro.com/market | 火幣PRO | 行情 | 所有Pro站交易中的交易對 |
| https://api.huobipro.com/v1 | 火幣PRO | 交易 | 同上 |
| https://api.hadax.com/market | HADAX hadax.com | 行情 | 所有HADAX站交易中的交易對 |
| https://api.hadax.com/v1 | HADAX hadax.com | 交易 | 同上 |
通過API可以實現以下功能:
- 市場行情信息查詢(K線、深度、實時成交、24小時行情)
- 賬戶資產信息查詢
- 下單、撤單操作
- 訂單信息查詢 所有請求基於 HTTPS 協議。
請求說明
- 訪問地址
Pro 站: 行情: https://api.huobipro.com/market 交易: https://api.huobipro.com/v1
HADAX 站: 行情: https://api.hadax.com/market 交易: https://api.hadax.com/v1
- POST請求頭信息中必須聲明 Content-Type:application/json;GET請求頭信息中必須聲明 Content-Type:application/x-www-form-urlencoded。(漢語用戶建議設置 Accept-Language:zh-cn)
- 所有請求參數請按照 API 說明進行參數封裝。
- 將封裝好參數的 API 請求通過 POST 或 GET 的方式提交到服務器。
- 火幣網處理請求,並返回相應的 JSON 格式結果。
- 請使用 https 請求。
- 限制頻率(每個接口,只針對交易api,行情api不限制)為10秒100次。
- 查詢資產詳情方法調用順序:查詢當前用戶的所有賬戶->查詢指定賬戶的余額
- 支持所有Pro站上交易中的交易對,上新幣保持與網站同步。
相關知識點鏈接:
示例代碼:
#!/usr/bin/env python # -*- coding: utf-8 -*- import base64 import datetime import hashlib import hmac import json import urllib import urllib.parse import urllib.request import requests # 此處填寫APIKEY ACCESS_KEY = " " SECRET_KEY = " " # API 請求地址 MARKET_URL = "https://api.huobi.pro" TRADE_URL = "https://api.huobi.pro" # 首次運行可通過get_accounts()獲取acct_id,然后直接賦值,減少重復獲取。 ACCOUNT_ID = None #'Timestamp': '2017-06-02T06:13:49' def http_get_request(url, params, add_to_headers=None): headers = { "Content-type": "application/x-www-form-urlencoded", 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36', } if add_to_headers: headers.update(add_to_headers) postdata = urllib.parse.urlencode(params) response = requests.get(url, postdata, headers=headers, timeout=5) try: if response.status_code == 200: return response.json() else: return except BaseException as e: print("httpGet failed, detail is:%s,%s" %(response.text,e)) return def http_post_request(url, params, add_to_headers=None): headers = { "Accept": "application/json", 'Content-Type': 'application/json' } if add_to_headers: headers.update(add_to_headers) postdata = json.dumps(params) response = requests.post(url, postdata, headers=headers, timeout=10) try: if response.status_code == 200: return response.json() else: return except BaseException as e: print("httpPost failed, detail is:%s,%s" %(response.text,e)) return def api_key_get(params, request_path): method = 'GET' timestamp = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S') params.update({'AccessKeyId': ACCESS_KEY, 'SignatureMethod': 'HmacSHA256', 'SignatureVersion': '2', 'Timestamp': timestamp}) host_url = TRADE_URL host_name = urllib.parse.urlparse(host_url).hostname host_name = host_name.lower() params['Signature'] = createSign(params, method, host_name, request_path, SECRET_KEY) url = host_url + request_path return http_get_request(url, params) def api_key_post(params, request_path): method = 'POST' timestamp = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S') params_to_sign = {'AccessKeyId': ACCESS_KEY, 'SignatureMethod': 'HmacSHA256', 'SignatureVersion': '2', 'Timestamp': timestamp} host_url = TRADE_URL host_name = urllib.parse.urlparse(host_url).hostname host_name = host_name.lower() params_to_sign['Signature'] = createSign(params_to_sign, method, host_name, request_path, SECRET_KEY) url = host_url + request_path + '?' + urllib.parse.urlencode(params_to_sign) return http_post_request(url, params) def createSign(pParams, method, host_url, request_path, secret_key): sorted_params = sorted(pParams.items(), key=lambda d: d[0], reverse=False) encode_params = urllib.parse.urlencode(sorted_params) payload = [method, host_url, request_path, encode_params] payload = '\n'.join(payload) payload = payload.encode(encoding='UTF8') secret_key = secret_key.encode(encoding='UTF8') digest = hmac.new(secret_key, payload, digestmod=hashlib.sha256).digest() signature = base64.b64encode(digest) signature = signature.decode() return signature
#!/usr/bin/env python # -*- coding: utf-8 -*- from Utils import * ''' Market data API ''' # 獲取KLine def get_kline(symbol, period, size=150): """ :param symbol :param period: 可選值:{1min, 5min, 15min, 30min, 60min, 1day, 1mon, 1week, 1year } :param size: 可選值: [1,2000] :return: """ params = {'symbol': symbol, 'period': period, 'size': size} url = MARKET_URL + '/market/history/kline' return http_get_request(url, params) # 獲取marketdepth def get_depth(symbol, type): """ :param symbol :param type: 可選值:{ percent10, step0, step1, step2, step3, step4, step5 } :return: """ params = {'symbol': symbol, 'type': type} url = MARKET_URL + '/market/depth' return http_get_request(url, params) # 獲取tradedetail def get_trade(symbol): """ :param symbol :return: """ params = {'symbol': symbol} url = MARKET_URL + '/market/trade' return http_get_request(url, params) # 獲取merge ticker def get_ticker(symbol): """ :param symbol: :return: """ params = {'symbol': symbol} url = MARKET_URL + '/market/detail/merged' return http_get_request(url, params) # 獲取 Market Detail 24小時成交量數據 def get_detail(symbol): """ :param symbol :return: """ params = {'symbol': symbol} url = MARKET_URL + '/market/detail' return http_get_request(url, params) # 獲取 支持的交易對 def get_symbols(long_polling=None): """ """ params = {} if long_polling: params['long-polling'] = long_polling path = '/v1/common/symbols' return api_key_get(params, path) ''' Trade/Account API ''' def get_accounts(): """ :return: """ path = "/v1/account/accounts" params = {} return api_key_get(params, path) ACCOUNT_ID = 0 # 獲取當前賬戶資產 def get_balance(acct_id=None): """ :param acct_id :return: """ global ACCOUNT_ID if not acct_id: accounts = get_accounts() acct_id = accounts['data'][0]['id']; url = "/v1/account/accounts/{0}/balance".format(acct_id) params = {"account-id": acct_id} return api_key_get(params, url) # 下單 # 創建並執行訂單 def send_order(amount, source, symbol, _type, price=0): """ :param amount: :param source: 如果使用借貸資產交易,請在下單接口,請求參數source中填寫'margin-api' :param symbol: :param _type: 可選值 {buy-market:市價買, sell-market:市價賣, buy-limit:限價買, sell-limit:限價賣} :param price: :return: """ try: accounts = get_accounts() acct_id = accounts['data'][0]['id'] except BaseException as e: print ('get acct_id error.%s' % e) acct_id = ACCOUNT_ID params = {"account-id": acct_id, "amount": amount, "symbol": symbol, "type": _type, "source": source} if price: params["price"] = price url = '/v1/order/orders/place' return api_key_post(params, url) # 撤銷訂單 def cancel_order(order_id): """ :param order_id: :return: """ params = {} url = "/v1/order/orders/{0}/submitcancel".format(order_id) return api_key_post(params, url) # 查詢某個訂單 def order_info(order_id): """ :param order_id: :return: """ params = {} url = "/v1/order/orders/{0}".format(order_id) return api_key_get(params, url) # 查詢某個訂單的成交明細 def order_matchresults(order_id): """ :param order_id: :return: """ params = {} url = "/v1/order/orders/{0}/matchresults".format(order_id) return api_key_get(params, url) # 查詢當前委托、歷史委托 def orders_list(symbol, states, types=None, start_date=None, end_date=None, _from=None, direct=None, size=None): """ :param symbol: :param states: 可選值 {pre-submitted 准備提交, submitted 已提交, partial-filled 部分成交, partial-canceled 部分成交撤銷, filled 完全成交, canceled 已撤銷} :param types: 可選值 {buy-market:市價買, sell-market:市價賣, buy-limit:限價買, sell-limit:限價賣} :param start_date: :param end_date: :param _from: :param direct: 可選值{prev 向前,next 向后} :param size: :return: """ params = {'symbol': symbol, 'states': states} if types: params[types] = types if start_date: params['start-date'] = start_date if end_date: params['end-date'] = end_date if _from: params['from'] = _from if direct: params['direct'] = direct if size: params['size'] = size url = '/v1/order/orders' return api_key_get(params, url) # 查詢當前成交、歷史成交 def orders_matchresults(symbol, types=None, start_date=None, end_date=None, _from=None, direct=None, size=None): """ :param symbol: :param types: 可選值 {buy-market:市價買, sell-market:市價賣, buy-limit:限價買, sell-limit:限價賣} :param start_date: :param end_date: :param _from: :param direct: 可選值{prev 向前,next 向后} :param size: :return: """ params = {'symbol': symbol} if types: params[types] = types if start_date: params['start-date'] = start_date if end_date: params['end-date'] = end_date if _from: params['from'] = _from if direct: params['direct'] = direct if size: params['size'] = size url = '/v1/order/matchresults' return api_key_get(params, url) # 申請提現虛擬幣 def withdraw(address, amount, currency, fee=0, addr_tag=""): """ :param address_id: :param amount: :param currency:btc, ltc, bcc, eth, etc ...(火幣Pro支持的幣種) :param fee: :param addr-tag: :return: { "status": "ok", "data": 700 } """ params = {'address': address, 'amount': amount, "currency": currency, "fee": fee, "addr-tag": addr_tag} url = '/v1/dw/withdraw/api/create' return api_key_post(params, url) # 申請取消提現虛擬幣 def cancel_withdraw(address_id): """ :param address_id: :return: { "status": "ok", "data": 700 } """ params = {} url = '/v1/dw/withdraw-virtual/{0}/cancel'.format(address_id) return api_key_post(params, url) ''' 借貸API ''' # 創建並執行借貸訂單 def send_margin_order(amount, source, symbol, _type, price=0): """ :param amount: :param source: 'margin-api' :param symbol: :param _type: 可選值 {buy-market:市價買, sell-market:市價賣, buy-limit:限價買, sell-limit:限價賣} :param price: :return: """ try: accounts = get_accounts() acct_id = accounts['data'][0]['id'] except BaseException as e: print ('get acct_id error.%s' % e) acct_id = ACCOUNT_ID params = {"account-id": acct_id, "amount": amount, "symbol": symbol, "type": _type, "source": 'margin-api'} if price: params["price"] = price url = '/v1/order/orders/place' return api_key_post(params, url) # 現貨賬戶划入至借貸賬戶 def exchange_to_margin(symbol, currency, amount): """ :param amount: :param currency: :param symbol: :return: """ params = {"symbol": symbol, "currency": currency, "amount": amount} url = "/v1/dw/transfer-in/margin" return api_key_post(params, url) # 借貸賬戶划出至現貨賬戶 def margin_to_exchange(symbol, currency, amount): """ :param amount: :param currency: :param symbol: :return: """ params = {"symbol": symbol, "currency": currency, "amount": amount} url = "/v1/dw/transfer-out/margin" return api_key_post(params, url) # 申請借貸 def get_margin(symbol, currency, amount): """ :param amount: :param currency: :param symbol: :return: """ params = {"symbol": symbol, "currency": currency, "amount": amount} url = "/v1/margin/orders" return api_key_post(params, url) # 歸還借貸 def repay_margin(order_id, amount): """ :param order_id: :param amount: :return: """ params = {"order-id": order_id, "amount": amount} url = "/v1/margin/orders/{0}/repay".format(order_id) return api_key_post(params, url) # 借貸訂單 def loan_orders(symbol, currency, start_date="", end_date="", start="", direct="", size=""): """ :param symbol: :param currency: :param direct: prev 向前,next 向后 :return: """ params = {"symbol": symbol, "currency": currency} if start_date: params["start-date"] = start_date if end_date: params["end-date"] = end_date if start: params["from"] = start if direct and direct in ["prev", "next"]: params["direct"] = direct if size: params["size"] = size url = "/v1/margin/loan-orders" return api_key_get(params, url) # 借貸賬戶詳情,支持查詢單個幣種 def margin_balance(symbol): """ :param symbol: :return: """ params = {} url = "/v1/margin/accounts/balance" if symbol: params['symbol'] = symbol return api_key_get(params, url) if __name__ == '__main__': print (get_symbols())
