503 lines
17 KiB
Python
503 lines
17 KiB
Python
|
# encoding: utf-8
|
||
|
|
||
|
import urllib
|
||
|
import hashlib
|
||
|
|
||
|
import json
|
||
|
import requests
|
||
|
from time import time
|
||
|
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'
|
||
|
|
||
|
# API相关定义
|
||
|
HUOBI_SERVICE_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_SERVICE_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, reqID)
|
||
|
# 请求成功
|
||
|
else:
|
||
|
if self.DEBUG:
|
||
|
print callback.__name__
|
||
|
callback(data, 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
|
||
|
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, reqID):
|
||
|
"""错误推送"""
|
||
|
print error, reqID
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onGetAccountInfo(self, data, reqID):
|
||
|
"""查询账户回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onGetOrders(self, data, reqID):
|
||
|
"""查询委托回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onOrderInfo(self, data, reqID):
|
||
|
"""委托详情回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onBuy(self, data, reqID):
|
||
|
"""买入回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onSell(self, data, reqID):
|
||
|
"""卖出回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onBuyMarket(self, data, reqID):
|
||
|
"""市价买入回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onSellMarket(self, data, reqID):
|
||
|
"""市价卖出回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onCancelOrder(self, data, reqID):
|
||
|
"""撤单回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onGetNewDealOrders(self, data, reqID):
|
||
|
"""查询最新成交回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onGetOrderIdByTradeId(self, data, reqID):
|
||
|
"""通过成交编号查询委托编号回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onWithdrawCoin(self, data, reqID):
|
||
|
"""提币回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onCancelWithdrawCoin(self, data, reqID):
|
||
|
"""取消提币回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onGetWithdrawCoinResult(self, data, reqID):
|
||
|
"""查询提币结果回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onTransfer(self, data, reqID):
|
||
|
"""转账回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onLoan(self, data, reqID):
|
||
|
"""申请杠杆回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onRepayment(self, data, reqID):
|
||
|
"""归还杠杆回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onLoanAvailable(self, data, reqID):
|
||
|
"""查询杠杆额度回调"""
|
||
|
print data
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onGetLoans(self, data, reqID):
|
||
|
"""查询杠杆列表"""
|
||
|
print data
|