299 lines
9.6 KiB
Python
299 lines
9.6 KiB
Python
|
# encoding: utf-8
|
||
|
|
||
|
import urllib
|
||
|
import hashlib
|
||
|
|
||
|
import requests
|
||
|
from Queue import Queue, Empty
|
||
|
from threading import Thread
|
||
|
|
||
|
|
||
|
LHANG_API_ROOT ="https://api.lhang.com/v1/"
|
||
|
|
||
|
FUNCTION_TICKER = ('ticker.do', 'get')
|
||
|
FUNCTION_DEPTH = ('depth.do', 'get')
|
||
|
FUNCTION_TRADES = ('trades.do', 'get')
|
||
|
FUNCTION_KLINE = ('kline.do', 'get')
|
||
|
|
||
|
FUNCTION_USERINFO = ('user_info.do', 'post')
|
||
|
FUNCTION_CREATEORDER = ('create_order.do', 'post')
|
||
|
FUNCTION_CANCELORDER = ('cancel_order.do', 'post')
|
||
|
FUNCTION_ORDERSINFO = ('orders_info.do', 'post')
|
||
|
FUNCTION_ORDERSINFOHISTORY = ('orders_info_history.do', 'post')
|
||
|
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def signature(params, secretKey):
|
||
|
"""生成签名"""
|
||
|
params = sorted(params.iteritems(), key=lambda d:d[0], reverse=False)
|
||
|
params.append(('secret_key', secretKey))
|
||
|
message = urllib.urlencode(params)
|
||
|
|
||
|
m = hashlib.md5()
|
||
|
m.update(message)
|
||
|
m.digest()
|
||
|
|
||
|
sig=m.hexdigest()
|
||
|
return sig
|
||
|
|
||
|
|
||
|
########################################################################
|
||
|
class LhangApi(object):
|
||
|
""""""
|
||
|
DEBUG = True
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def __init__(self):
|
||
|
"""Constructor"""
|
||
|
self.apiKey = ''
|
||
|
self.secretKey = ''
|
||
|
|
||
|
self.active = False # API工作状态
|
||
|
self.reqID = 0 # 请求编号
|
||
|
self.reqQueue = Queue() # 请求队列
|
||
|
self.reqThread = Thread(target=self.processQueue) # 请求处理线程
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def init(self, apiKey, secretKey):
|
||
|
"""初始化"""
|
||
|
self.apiKey = apiKey
|
||
|
self.secretKey = secretKey
|
||
|
|
||
|
self.active = True
|
||
|
self.reqThread.start()
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def exit(self):
|
||
|
"""退出"""
|
||
|
self.active = False
|
||
|
self.reqThread.join()
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def processRequest(self, req):
|
||
|
"""处理请求"""
|
||
|
# 读取方法和参数
|
||
|
api, method = req['function']
|
||
|
params = req['params']
|
||
|
url = LHANG_API_ROOT + api
|
||
|
|
||
|
# 在参数中增加必须的字段
|
||
|
params['api_key'] = self.apiKey
|
||
|
|
||
|
# 添加签名
|
||
|
sign = signature(params, self.secretKey)
|
||
|
params['sign'] = sign
|
||
|
|
||
|
# 发送请求
|
||
|
payload = urllib.urlencode(params)
|
||
|
|
||
|
r = requests.request(method, url, 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 data is None:
|
||
|
error = u'请求失败'
|
||
|
self.onError(error, reqID)
|
||
|
elif 'error_code' in data:
|
||
|
error = u'请求出错,错误代码:%s' % data['error_code']
|
||
|
self.onError(error, reqID)
|
||
|
# 请求成功
|
||
|
else:
|
||
|
if self.DEBUG:
|
||
|
print callback.__name__
|
||
|
callback(data, reqID)
|
||
|
|
||
|
except Empty:
|
||
|
pass
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def sendRequest(self, function, params, callback):
|
||
|
"""发送请求"""
|
||
|
# 请求编号加1
|
||
|
self.reqID += 1
|
||
|
|
||
|
# 生成请求字典并放入队列中
|
||
|
req = {}
|
||
|
req['function'] = function
|
||
|
req['params'] = params
|
||
|
req['callback'] = callback
|
||
|
req['reqID'] = self.reqID
|
||
|
self.reqQueue.put(req)
|
||
|
|
||
|
# 返回请求编号
|
||
|
return self.reqID
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onError(self, error, reqID):
|
||
|
"""错误推送"""
|
||
|
print error, reqID
|
||
|
|
||
|
###############################################
|
||
|
# 行情接口
|
||
|
###############################################
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def getTicker(self, symbol):
|
||
|
"""查询行情"""
|
||
|
function = FUNCTION_TICKER
|
||
|
params = {'symbol': symbol}
|
||
|
callback = self.onGetTicker
|
||
|
return self.sendRequest(function, params, callback)
|
||
|
|
||
|
# ----------------------------------------------------------------------
|
||
|
def getDepth(self, symbol, size, merge):
|
||
|
"""查询深度"""
|
||
|
function = FUNCTION_DEPTH
|
||
|
params = {
|
||
|
'symbol': symbol,
|
||
|
'size': size,
|
||
|
'mege': merge
|
||
|
}
|
||
|
callback = self.onGetDepth
|
||
|
return self.sendRequest(function, params, callback)
|
||
|
|
||
|
# ----------------------------------------------------------------------
|
||
|
def getTrades(self, symbol, size, time):
|
||
|
"""查询历史成交"""
|
||
|
function = FUNCTION_TRADES
|
||
|
params = {
|
||
|
'symbol': symbol,
|
||
|
'size': size,
|
||
|
'time': time
|
||
|
}
|
||
|
callback = self.onGetTrades
|
||
|
return self.sendRequest(function, params, callback)
|
||
|
|
||
|
# ----------------------------------------------------------------------
|
||
|
def getKline(self, symbol, size, type_, time):
|
||
|
"""查询K线"""
|
||
|
function = FUNCTION_TRADES
|
||
|
params = {
|
||
|
'symbol': symbol,
|
||
|
'size': size,
|
||
|
'type': type_,
|
||
|
'time': time
|
||
|
}
|
||
|
callback = self.onGetKline
|
||
|
return self.sendRequest(function, params, callback)
|
||
|
|
||
|
#----------------------------------------------------------------------
|
||
|
def onGetTicker(self, data, reqID):
|
||
|
"""查询行情回调"""
|
||
|
print data, reqID
|
||
|
|
||
|
# ----------------------------------------------------------------------
|
||
|
def onGetDepth(self, data, reqID):
|
||
|
"""查询深度回调"""
|
||
|
print data, reqID
|
||
|
|
||
|
# ----------------------------------------------------------------------
|
||
|
def onGetTrades(self, data, reqID):
|
||
|
"""查询历史成交"""
|
||
|
print data, reqID
|
||
|
|
||
|
# ----------------------------------------------------------------------
|
||
|
def onGetKline(self, data, reqID):
|
||
|
"""查询K线回报"""
|
||
|
print data, reqID
|
||
|
|
||
|
###############################################
|
||
|
# 交易接口
|
||
|
###############################################
|
||
|
|
||
|
# ----------------------------------------------------------------------
|
||
|
def getUserInfo(self):
|
||
|
"""查询K线"""
|
||
|
function = FUNCTION_USERINFO
|
||
|
params = {}
|
||
|
callback = self.onGetUserInfo
|
||
|
return self.sendRequest(function, params, callback)
|
||
|
|
||
|
# ----------------------------------------------------------------------
|
||
|
def createOrder(self, symbol, type_, price, amount):
|
||
|
"""发送委托"""
|
||
|
function = FUNCTION_CREATEORDER
|
||
|
params = {
|
||
|
'symbol': symbol,
|
||
|
'type': type_,
|
||
|
'price': price,
|
||
|
'amount': amount
|
||
|
}
|
||
|
callback = self.onCreateOrder
|
||
|
return self.sendRequest(function, params, callback)
|
||
|
|
||
|
# ----------------------------------------------------------------------
|
||
|
def cancelOrder(self, symbol, orderId):
|
||
|
"""撤单"""
|
||
|
function = FUNCTION_CANCELORDER
|
||
|
params = {
|
||
|
'symbol': symbol,
|
||
|
'order_id': orderId
|
||
|
}
|
||
|
callback = self.onCancelOrder
|
||
|
return self.sendRequest(function, params, callback)
|
||
|
|
||
|
# ----------------------------------------------------------------------
|
||
|
def getOrdersInfo(self, symbol, orderId):
|
||
|
"""查询委托"""
|
||
|
function = FUNCTION_ORDERSINFO
|
||
|
params = {
|
||
|
'symbol': symbol,
|
||
|
'order_id': orderId
|
||
|
}
|
||
|
callback = self.onGetOrdersInfo
|
||
|
return self.sendRequest(function, params, callback)
|
||
|
|
||
|
# ----------------------------------------------------------------------
|
||
|
def getOrdersInfoHistory(self, symbol, status, currentPage, pageLength):
|
||
|
"""撤单"""
|
||
|
function = FUNCTION_ORDERSINFOHISTORY
|
||
|
params = {
|
||
|
'symbol': symbol,
|
||
|
'status': status,
|
||
|
'current_page': currentPage,
|
||
|
'page_length': pageLength
|
||
|
}
|
||
|
callback = self.onGetOrdersInfoHistory
|
||
|
return self.sendRequest(function, params, callback)
|
||
|
|
||
|
# ----------------------------------------------------------------------
|
||
|
def onGetUserInfo(self, data, reqID):
|
||
|
"""查询K线回报"""
|
||
|
print data, reqID
|
||
|
|
||
|
# ----------------------------------------------------------------------
|
||
|
def onCreateOrder(self, data, reqID):
|
||
|
"""委托回报"""
|
||
|
print data, reqID
|
||
|
|
||
|
# ----------------------------------------------------------------------
|
||
|
def onCancelOrder(self, data, reqID):
|
||
|
"""撤单回报"""
|
||
|
print data, reqID
|
||
|
|
||
|
# ----------------------------------------------------------------------
|
||
|
def onGetOrdersInfo(self, data, reqID):
|
||
|
"""查询委托回报"""
|
||
|
print data, reqID
|
||
|
|
||
|
# ----------------------------------------------------------------------
|
||
|
def onGetOrdersInfoHistory(self, data, reqID):
|
||
|
"""撤单回报"""
|
||
|
print data, reqID
|
||
|
|