区块键量化交易学习笔记(四)

编程入门 行业动态 更新时间:2024-10-07 08:29:09

<a href=https://www.elefans.com/category/jswz/34/1769401.html style=区块键量化交易学习笔记(四)"/>

区块键量化交易学习笔记(四)

火币官方的HTTP_API:HuobiDMUtil.py   HuobiDMService.py  demo.py

参考说明:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Date    : 20180917
# @Author  : zhaobo
# @github  : import base64
import hmac
import hashlib
import jsonimport urllib
import datetime
import requests
#import urlparse   # urllib.parse in python 3# timeout in 5 seconds:
TIMEOUT = 5#各种请求,获取数据方式
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; rv:53.0) Gecko/20100101 Firefox/53.0'}if add_to_headers:headers.update(add_to_headers)postdata = urllib.parse.urlencode(params)try:response = requests.get(url, postdata, headers=headers, timeout=TIMEOUT)if response.status_code == 200:return response.json()else:return {"status":"fail"}except Exception as e:print("httpGet failed, detail is:%s" %e)return {"status":"fail","msg": "%s"%e}def http_post_request(url, params, add_to_headers=None):headers = {"Accept": "application/json",'Content-Type': 'application/json','User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0'}if add_to_headers:headers.update(add_to_headers)postdata = json.dumps(params)try:response = requests.post(url, postdata, headers=headers, timeout=TIMEOUT)if response.status_code == 200:return response.json()else:return response.json()except Exception as e:print("httpPost failed, detail is:%s" % e)return {"status":"fail","msg": "%s"%e}def api_key_get(url, request_path, params, ACCESS_KEY, SECRET_KEY):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_name = host_url = url#host_name = urlparse.urlparse(host_url).hostnamehost_name = urllib.parse.urlparse(host_url).hostnamehost_name = host_name.lower()params['Signature'] = createSign(params, method, host_name, request_path, SECRET_KEY)url = host_url + request_pathreturn http_get_request(url, params)def api_key_post(url, request_path, params, ACCESS_KEY, SECRET_KEY):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 = url#host_name = urlparse.urlparse(host_url).hostnamehost_name = urllib.parse.urlparse(host_url).hostnamehost_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 -*-
# @Date    : 20180917
# @Author  : zhaobo
# @github  : from HuobiDMUtil import http_get_request, api_key_postclass HuobiDM:def __init__(self,url,access_key,secret_key):self.__url = urlself.__access_key = access_keyself.__secret_key = secret_key'''======================Market data API======================'''# 获取合约信息def get_contract_info(self, symbol='', contract_type='', contract_code=''):"""参数名称         参数类型  必填    描述symbol          string  false   "BTC","ETH"...contract_type   string  false   合约类型: this_week:当周 next_week:下周 quarter:季度contract_code   string  false   BTC181228备注:如果contract_code填了值,那就按照contract_code去查询,如果contract_code 没有填值,则按照symbol+contract_type去查询"""params = {}if symbol:params['symbol'] = symbolif contract_type:params['contract_type'] = contract_typeif contract_code:params['contract_code'] = contract_codeurl = self.__url + '/api/v1/contract_contract_info'return http_get_request(url, params)# 获取合约指数信息def get_contract_index(self, symbol):""":symbol    "BTC","ETH"..."""params = {'symbol': symbol}url = self.__url + '/api/v1/contract_index'return http_get_request(url, params)# 获取合约最高限价和最低限价def get_contract_price_limit(self, symbol='', contract_type='', contract_code=''):""":symbol          "BTC","ETH"...:contract_type   合约类型: this_week:当周 next_week:下周 quarter:季度"contract_code   BTC180928备注:如果contract_code填了值,那就按照contract_code去查询,如果contract_code 没有填值,则按照symbol+contract_type去查询"""params = {}if symbol:params['symbol'] = symbolif contract_type:params['contract_type'] = contract_typeif contract_code:params['contract_code'] = contract_codeurl = self.__url + '/api/v1/contract_price_limit'return http_get_request(url, params)# 获取当前可用合约总持仓量def get_contract_open_interest(self, symbol='', contract_type='', contract_code=''):""":symbol          "BTC","ETH"...:contract_type   合约类型: this_week:当周 next_week:下周 quarter:季度"contract_code   BTC180928备注:如果contract_code填了值,那就按照contract_code去查询,如果contract_code 没有填值,则按照symbol+contract_type去查询"""params = {'symbol': symbol,'contract_type': contract_type,'contract_code': contract_code}url = self.__url + '/api/v1/contract_open_interest'return http_get_request(url, params)   # 获取行情深度def get_contract_depth(self, symbol, type):""":param symbol:   BTC_CW, BTC_NW, BTC_CQ , ...:param type: 可选值:{ step0, step1, step2, step3, step4, step5 (合并深度0-5);step0时,不合并深度 }:return:"""params = {'symbol': symbol,'type': type}url = self.__url + '/market/depth'return http_get_request(url, params)# 获取KLinedef get_contract_kline(self, symbol, period, size=150):""":param symbol  BTC_CW, BTC_NW, BTC_CQ , ...:param period: 可选值:{1min, 5min, 15min, 30min, 60min, 4hour, 1day, 1week, 1mon }:param size: [1,2000]:return:"""params = {'symbol': symbol,'period': period}if size:params['size'] = sizeurl = self.__url + '/market/history/kline'return http_get_request(url, params)# 获取聚合行情def get_contract_market_merged(self, symbol):""":symbol	    "BTC_CW","BTC_NW", "BTC_CQ" ..."""params = {'symbol': symbol}url = self.__url + '/market/detail/merged'return http_get_request(url, params)# 获取市场最近成交记录def get_contract_trade(self, symbol, size=1):""":param symbol: 可选值:{ BTC_CW, BTC_NW, BTC_CQ, etc. }:return:"""params = {'symbol': symbol,'size' : size}url = self.__url + '/market/trade'return http_get_request(url, params)# 批量获取最近的交易记录def get_contract_batch_trade(self, symbol, size=1):""":param symbol: 可选值:{ BTC_CW, BTC_NW, BTC_CQ, etc. }, size: int:return:"""params = {'symbol': symbol,'size' : size}url = self.__url + '/market/history/trade'return http_get_request(url, params)'''======================Trade/Account API======================'''# 获取用户账户信息def get_contract_account_info(self, symbol=''):""":param symbol: "BTC","ETH"...如果缺省,默认返回所有品种:return:"""params = {}if symbol:params["symbol"] = symbolrequest_path = '/api/v1/contract_account_info'return api_key_post(self.__url, request_path, params, self.__access_key, self.__secret_key)# 获取用户持仓信息def get_contract_position_info(self, symbol=''):""":param symbol: "BTC","ETH"...如果缺省,默认返回所有品种:return:"""params = {}if symbol:params["symbol"] = symbolrequest_path = '/api/v1/contract_position_info'return api_key_post(self.__url, request_path, params, self.__access_key, self.__secret_key)# 合约下单def send_contract_order(self, symbol, contract_type, contract_code, client_order_id, price,volume,direction,offset,lever_rate,order_price_type):""":symbol: "BTC","ETH"..:contract_type: "this_week", "next_week", "quarter":contract_code: "BTC181228":client_order_id: 客户自己填写和维护,这次一定要大于上一次:price             必填   价格:volume            必填  委托数量(张):direction         必填  "buy" "sell":offset            必填   "open", "close":lever_rate        必填  杠杆倍数:order_price_type  必填   "limit"限价, "opponent" 对手价备注:如果contract_code填了值,那就按照contract_code去下单,如果contract_code没有填值,则按照symbol+contract_type去下单。:"""params = {"price": price,"volume": volume,"direction": direction,"offset": offset,"lever_rate": lever_rate,"order_price_type": order_price_type}if symbol:params["symbol"] = symbolif contract_type:params['contract_type'] = contract_typeif contract_code:params['contract_code'] = contract_codeif client_order_id:params['client_order_id'] = client_order_idrequest_path = '/api/v1/contract_order'return api_key_post(self.__url, request_path, params, self.__access_key, self.__secret_key)# 合约批量下单def send_contract_batchorder(self, orders_data):"""orders_data: example:orders_data = {'orders_data': [{'symbol': 'BTC', 'contract_type': 'quarter',  'contract_code':'BTC181228',  'client_order_id':'', 'price':1, 'volume':1, 'direction':'buy', 'offset':'open', 'leverRate':20, 'orderPriceType':'limit'},{'symbol': 'BTC','contract_type': 'quarter', 'contract_code':'BTC181228', 'client_order_id':'', 'price':2, 'volume':2, 'direction':'buy', 'offset':'open', 'leverRate':20, 'orderPriceType':'limit'}]}    Parameters of each order: refer to send_contract_order"""params = orders_datarequest_path = '/api/v1/contract_batchorder'return api_key_post(self.__url, request_path, params, self.__access_key, self.__secret_key)# 撤销订单def cancel_contract_order(self, symbol, order_id='', client_order_id=''):"""参数名称          是否必须 类型     描述symbol           true   string  BTC, ETH, ...order_id	         false  string  订单ID( 多个订单ID中间以","分隔,一次最多允许撤消50个订单 )client_order_id  false  string  客户订单ID(多个订单ID中间以","分隔,一次最多允许撤消50个订单)备注: order_id 和 client_order_id都可以用来撤单,同时只可以设置其中一种,如果设置了两种,默认以order_id来撤单。"""params = {"symbol": symbol}if order_id:params["order_id"] = order_idif client_order_id:params["client_order_id"] = client_order_id  request_path = '/api/v1/contract_cancel'return api_key_post(self.__url, request_path, params, self.__access_key, self.__secret_key)# 全部撤单def cancel_all_contract_order(self, symbol):"""symbol: BTC, ETH, ..."""params = {"symbol": symbol}request_path = '/api/v1/contract_cancelall'return api_key_post(self.__url, request_path, params, self.__access_key, self.__secret_key)# 获取合约订单信息def get_contract_order_info(self, symbol, order_id='', client_order_id=''):"""参数名称	        是否必须	类型	    描述symbol          true    string  BTC, ETH, ...order_id	        false	string	订单ID( 多个订单ID中间以","分隔,一次最多允许查询20个订单 )client_order_id	false	string	客户订单ID(多个订单ID中间以","分隔,一次最多允许查询20个订单)备注:order_id和client_order_id都可以用来查询,同时只可以设置其中一种,如果设置了两种,默认以order_id来查询。"""params = {"symbol": symbol}if order_id:params["order_id"] = order_idif client_order_id:params["client_order_id"] = client_order_id  request_path = '/api/v1/contract_order_info'return api_key_post(self.__url, request_path, params, self.__access_key, self.__secret_key)# 获取合约订单明细信息def get_contract_order_detail(self, symbol, order_id, order_type, created_at, page_index=None, page_size=None):"""参数名称     是否必须  类型    描述symbol      true	    string "BTC","ETH"...order_id    true	    long	   订单idorder_type  true    int    订单类型。1:报单, 2:撤单, 3:爆仓, 4:交割created_at  true    number 订单创建时间page_index  false   int    第几页,不填第一页page_size   false   int    不填默认20,不得多于50"""params = {"symbol": symbol,"order_id": order_id,"order_type": order_type,"created_at": created_at}if page_index:params["page_index"] = page_indexif page_size:params["page_size"] = page_size  request_path = '/api/v1/contract_order_detail'return api_key_post(self.__url, request_path, params, self.__access_key, self.__secret_key)# 获取合约当前未成交委托def get_contract_open_orders(self, symbol=None, page_index=None, page_size=None):"""参数名称     是否必须  类型   描述symbol      false   string "BTC","ETH"...page_index  false   int    第几页,不填第一页page_size   false   int    不填默认20,不得多于50"""params = {}if symbol:params["symbol"] = symbolif page_index:params["page_index"] = page_indexif page_size:params["page_size"] = page_size  request_path = '/api/v1/contract_openorders'return api_key_post(self.__url, request_path, params, self.__access_key, self.__secret_key)# 获取合约历史委托def get_contract_history_orders(self, symbol, trade_type, type, status, create_date,page_index=None, page_size=None):"""参数名称     是否必须  类型     描述	    取值范围symbol      true	    string  品种代码  "BTC","ETH"...trade_type  true	    int     交易类型  0:全部,1:买入开多,2: 卖出开空,3: 买入平空,4: 卖出平多,5: 卖出强平,6: 买入强平,7:交割平多,8: 交割平空type        true	    int     类型     1:所有订单、2:结束汏订单status      true	    int     订单状态  0:全部,3:未成交, 4: 部分成交,5: 部分成交已撤单,6: 全部成交,7:已撤单create_date true	    int     日期     7,90(7天或者90天)page_index  false   int     页码,不填默认第1页		page_size   false   int     不填默认20,不得多于50"""params = {"symbol": symbol,"trade_type": trade_type,"type": type,"status": status,"create_date": create_date}if page_index:params["page_index"] = page_indexif page_size:params["page_size"] = page_size  request_path = '/api/v1/contract_hisorders'return api_key_post(self.__url, request_path, params, self.__access_key, self.__secret_key)
from HuobiDMService import HuobiDM
from pprint import pprint#### input huobi dm url
URL = ''####  input your access_key and secret_key below:
ACCESS_KEY = ''
SECRET_KEY = ''dm = HuobiDM(URL, ACCESS_KEY, SECRET_KEY)#### another account:
#dm2 = HuobiDM(URL, "ANOTHER ACCOUNT's ACCESS_KEY", "ANOTHER ACCOUNT's SECRET_KEY")#%%  market data api ===============print (u' 获取合约信息 ')
pprint (dm.get_contract_info(symbol="BTC", contract_type="quarter"))
pprint (dm.get_contract_info(contract_code="BTC181228"))print (u' 获取合约指数信息 ')
pprint (dm.get_contract_index("BTC"))print (u' 获取合约最高限价和最低限价 ')
pprint (dm.get_contract_price_limit(symbol='BTC', contract_type='quarter'))
pprint (dm.get_contract_price_limit(contract_code='BTC181228'))print (u' 获取当前可用合约总持仓量 ')
pprint (dm.get_contract_open_interest(symbol='BTC', contract_type='quarter'))
pprint (dm.get_contract_open_interest(contract_code='BTC181228'))print (u' 获取行情深度数据 ')
pprint (dm.get_contract_depth(symbol='BTC_CW', type='step0'))print (u' 获取K线数据 ')
pprint (dm.get_contract_kline(symbol='BTC_CW', period='60min', size=20))print (u' 获取聚合行情 ')
pprint (dm.get_contract_market_merged('BTC_CW'))print (u' 获取市场最近成交记录 ')
pprint (dm.get_contract_trade('BTC_CW'))print (u' 批量获取最近的交易记录 ')
pprint (dm.get_contract_batch_trade(symbol='BTC_CW', size=3))#%% trade / account api  ===============print (u' 获取用户账户信息 ')
pprint (dm.get_contract_account_info())
pprint (dm.get_contract_account_info("BTC"))print (u' 获取用户持仓信息 ')
pprint (dm.get_contract_position_info())
pprint (dm.get_contract_position_info("BTC"))print (u' 合约下单 ')
pprint(dm.send_contract_order(symbol='', contract_type='', contract_code='BTC181228', client_order_id='', price=10000, volume=1, direction='sell',offset='open', lever_rate=5, order_price_type='limit'))print (u' 合约批量下单 ')
orders_data = {'orders_data': [{'symbol': 'BTC', 'contract_type': 'quarter',  'contract_code':'BTC181228',  'client_order_id':'', 'price':10000, 'volume':1, 'direction':'sell', 'offset':'open', 'leverRate':5, 'orderPriceType':'limit'},{'symbol': 'BTC','contract_type': 'quarter', 'contract_code':'BTC181228', 'client_order_id':'', 'price':20000, 'volume':2, 'direction':'sell', 'offset':'open', 'leverRate':5, 'orderPriceType':'limit'}]}
pprint(dm.send_contract_batchorder(orders_data))print (u' 撤销订单 ')
pprint(dm.cancel_contract_order(symbol='BTC', order_id='42652161'))print (u' 全部撤单 ')
pprint(dm.cancel_all_contract_order(symbol='BTC'))print (u' 获取合约订单信息 ')
pprint(dm.get_contract_order_info(symbol='BTC', order_id='42652161'))print (u' 获取合约订单明细信息 ')
pprint(dm.get_contract_order_detail(symbol='BTC', order_id='42652161', order_type=1, created_at=1542097630215))print (u' 获取合约当前未成交委托 ')
pprint(dm.get_contract_open_orders(symbol='BTC'))print (u' 获取合约历史委托 ')
pprint (dm.get_contract_history_orders(symbol='BTC', trade_type=0, type=1, status=0, create_date=7))

 

WebSocket API(现货)

#!/usr/bin/env pythonimport datetime
import uuid
import urllib
import asyncio
import websockets
import json
import hmac
import base64
import hashlib
import gzip
import tracebackdef generate_signature(host, method, params, request_path, secret_key):"""Generate signature of huobi future.Args:host: api domain url.PS: colo user should set this host as 'api.hbdm',not colo domain.method: request method.params: request params.request_path: "/notification"secret_key: api secret_keyReturns:singature string."""host_url = urllib.parse.urlparse(host).hostname.lower()sorted_params = sorted(params.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 signatureasync def subscribe(url, access_key, secret_key, subs, callback=None, auth=False):""" Huobi Future subscribe websockets.Args:url: the url to be signatured.access_key: API access_key.secret_key: API secret_key.subs: the data list to subscribe.callback: the callback function to handle the ws data received.auth: True: Need to be signatured. False: No need to be signatured."""async with websockets.connect(url) as websocket:if auth:timestamp = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S")data = {"AccessKeyId": access_key,"SignatureMethod": "HmacSHA256","SignatureVersion": "2","Timestamp": timestamp}sign = generate_signature(url, "GET", data, "/ws/v1", secret_key)data["op"] = "auth"data["type"] = "api"data["Signature"] = signmsg_str = json.dumps(data)await websocket.send(msg_str)print(f"send: {msg_str}")for sub in subs:sub_str = json.dumps(sub)await websocket.send(sub_str)print(f"send: {sub_str}")while True:rsp = await websocket.recv()data = json.loads(gzip.decompress(rsp).decode())# print(f"recevie<--: {data}")if "op" in data and data.get("op") == "ping":pong_msg = {"op": "pong", "ts": data.get("ts")}await websocket.send(json.dumps(pong_msg))print(f"send: {pong_msg}")continueif "ping" in data:pong_msg = {"pong": data.get("ping")}await websocket.send(json.dumps(pong_msg))print(f"send: {pong_msg}")continuersp = await callback(data)async def handle_ws_data(*args, **kwargs):""" callback functionArgs:args: valueskwargs: key-values."""print("callback param", *args, **kwargs)if __name__ == "__main__":####  input your access_key and secret_key below:access_key = ""secret_key = ""market_url = 'wss://api.huobi.de/ws'order_url = 'wss://api.huobi.de/ws/v1'market_subs = [{"sub": "market.btcusdt.kline.1min","id": str(uuid.uuid1())},{"sub": "market.btcusdt.depth.step6","id": str(uuid.uuid1())},{"sub": "market.btcusdt.detail","id": str(uuid.uuid1())}]order_subs = [{"op": "sub","cid": str(uuid.uuid1()),"topic": "orders.btcusdt.update"},{"op": "req","cid": str(uuid.uuid1()),"topic": "accounts.list"},{"op": "sub","cid": str(uuid.uuid1()),"topic": "accounts"}]while True:try:# asyncio.get_event_loop().run_until_complete(subscribe(market_url, access_key, secret_key, market_subs, handle_ws_data, auth=False))asyncio.get_event_loop().run_until_complete(subscribe(order_url, access_key,  secret_key, order_subs, handle_ws_data, auth=True))# except (websockets.exceptions.ConnectionClosed):except Exception as e:traceback.print_exc()print('websocket connection error. reconnect rightnow')
# -*- coding: utf-8 -*-from websocket import create_connection
import gzip
import timeif __name__ == '__main__':while(1):try:ws = create_connection("wss://www.hbdm/ws")breakexcept:print('connect ws error,retry...')time.sleep(5)# 订阅 KLine 数据tradeStr_kline="""{"sub": "market.BTC_CQ.kline.1min",  "id": "id1"}"""# 订阅 Market Detail 数据tradeStr_marketDetail="""{"sub": "market.BTC_CQ.detail",  "id": "id6" }"""# 订阅 Trade Detail 数据tradeStr_tradeDetail="""{"sub": "market.BTC_CQ.trade.detail", "id": "id7"}"""# 请求 KLine 数据tradeStr_klinereq="""{"req": "market.BTC_CQ.kline.1min", "id": "id4"}"""# 请求 Trade Detail 数据tradeStr_tradeDetail_req="""{"req": "market.BTC_CQ.trade.detail", "id": "id5"}"""# 订阅 Market Depth 数据tradeStr_marketDepth="""{"sub": "market.BTC_CQ.depth.step0", "id": "id9"}"""ws.send(tradeStr_marketDepth)trade_id = ''while(1):compressData=ws.recv()result=gzip.decompress(compressData).decode('utf-8')if result[:7] == '{"ping"':ts=result[8:21]pong='{"pong":'+ts+'}'ws.send(pong)ws.send(tradeStr_kline)else:try:if trade_id == result['data']['id']:print('重复的id')breakelse:trade_id = result['data']['id']except Exception:passprint(result)

Websocket资产及订单(v2)

v2.1版本签名与v2.0版本签名步骤相似,具体区别如下:

  1. 生成参与签名的字符串时,请求方法固定使用GET,请求地址固定为/ws/v2

  2. 生成参与签名的固定参数名替换为:accessKey,signatureMethod,signatureVersion,timestamp

  3. signatureVersion版本升级为2.1

  4. 参数有变化详细实现代码修改如下(无数据压缩)

    #!/usr/bin/env pythonimport datetime
    import uuid
    import urllib
    import asyncio
    import websockets
    import json
    import hmac
    import base64
    import hashlib
    import tracebackdef generate_signature(host, method, params, request_path, secret_key):"""Generate signature of huobi future.Args:host: api domain url.PS: colo user should set this host as 'api.hbdm',not colo domain.method: request method.params: request params.request_path: "/notification"secret_key: api secret_keyReturns:singature string."""host_url = urllib.parse.urlparse(host).hostname.lower()sorted_params = sorted(params.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 signatureasync def subscribe(url, access_key, secret_key, subs, callback=None, auth=False):""" Huobi Future subscribe websockets.Args:url: the url to be signatured.access_key: API access_key.secret_key: API secret_key.subs: the data list to subscribe.callback: the callback function to handle the ws data received.auth: True: Need to be signatured. False: No need to be signatured."""async with websockets.connect(url) as websocket:if auth:timestamp = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S")data = {"accessKey": access_key,"signatureMethod": "HmacSHA256","signatureVersion": "2.1","timestamp": timestamp}sign = generate_signature(url, "GET", data, "/ws/v2", secret_key)data["authType"] = "api"data["signature"] = signparams = {'action': 'req','ch': 'auth','params': data}msg_str = json.dumps(params)await websocket.send(msg_str)print(f"send: {msg_str}")for sub in subs:sub_str = json.dumps(sub)await websocket.send(sub_str)print(f"send: {sub_str}")while True:rsp = await websocket.recv()# print(f"recevie-->: {rsp}")data = json.loads(rsp)if "action" in data and data.get("action") == "ping":pong_msg = {"action": "pong", "ts": data['data'].get("ts")}await websocket.send(json.dumps(pong_msg))print(f"send: {pong_msg}")continueif "ping" in data:pong_msg = {"pong": data.get("ping")}await websocket.send(json.dumps(pong_msg))print(f"send: {pong_msg}")continuersp = await callback(data)async def handle_ws_data(*args, **kwargs):""" callback functionArgs:args: valueskwargs: key-values."""print("callback param", *args, **kwargs)if __name__ == "__main__":####  input your access_key and secret_key below:access_key = ""secret_key = ""market_url = 'wss://api.huobi.de/ws'order_url = 'wss://api.huobi.de/ws/v2'market_subs = [{"sub": "market.btcusdt.kline.1min","id": str(uuid.uuid1())},{"sub": "market.btcusdt.depth.step6","id": str(uuid.uuid1())},{"sub": "market.btcusdt.detail","id": str(uuid.uuid1())}]order_subs = [{"action": "sub","ch": "trade.clearing#ethusdt"},{"action": "sub","ch": "accounts.update"}]while True:try:# asyncio.get_event_loop().run_until_complete(subscribe(market_url, access_key, secret_key, market_subs, handle_ws_data, auth=False))asyncio.get_event_loop().run_until_complete(subscribe(order_url, access_key,  secret_key, order_subs, handle_ws_data, auth=True))# except (websockets.exceptions.ConnectionClosed):except Exception as e:traceback.print_exc()print('websocket connection error. reconnect rightnow')

    BitMex(签名)

    import time, urllib, hmac, hashlibdef generate_nonce():return int(round(time.time() + 3600))# Generates an API signature.
    # A signature is HMAC_SHA256(secret, verb + path + nonce + data), hex encoded.
    # Verb must be uppercased, url is relative, nonce must be an increasing 64-bit integer
    # and the data, if present, must be JSON without whitespace between keys.
    #
    # For example, in psuedocode (and in real code below):
    #
    # verb=POST
    # url=/api/v1/order
    # nonce=1416993995705
    # data={"symbol":"XBTZ14","quantity":1,"price":395.01}
    # signature = HEX(HMAC_SHA256(secret, 'POST/api/v1/order1416993995705{"symbol":"XBTZ14","quantity":1,"price":395.01}'))
    def generate_signature(secret, verb, url, nonce, data):"""Generate a request signature compatible with BitMEX."""# Parse the url so we can remove the base and extract just the path.parsedURL = urllib.parse.urlparse(url)path = parsedURL.pathif parsedURL.query:path = path + '?' + parsedURL.query# print "Computing HMAC: %s" % verb + path + str(nonce) + datamessage = (verb + path + str(nonce) + data).encode('utf-8')signature = hmac.new(secret.encode('utf-8'), message, digestmod=hashlib.sha256).hexdigest()return signature

    火币(签名)

    import base64
    import hashlib
    import hmac
    import datetime
    from urllib import parse
    import urllib.parse
    import jsondef print_builder(builder):print("params in builder", builder.param_map)print("params in builder build_urls", builder.build_url())class UrlParamsBuilder(object):def __init__(self):self.param_map = dict()self.post_map = dict()def put_url(self, name, value):if value is not None:if isinstance(value, list):self.param_map[name] = valueelse:self.param_map[name] = str(value)def put_post(self, name, value):if value is not None:if isinstance(value, list):self.post_map[name] = valueelse:self.post_map[name] = str(value)def build_url(self):if len(self.param_map) == 0:return ""encoded_param = urllib.parse.urlencode(self.param_map)return "?" + encoded_paramdef build_url_to_json(self):return json.dumps(self.param_map)def create_signature(api_key, secret_key, method, url, builder):ret = {"code" : 0,"message" : ""}if api_key is None or secret_key is None or api_key == "" or secret_key == "":ret["code"] = -1ret["message"] = "API key and secret key are required"return rettimestamp = utc_now()builder.put_url("AccessKeyId", api_key)builder.put_url("SignatureVersion", "2")builder.put_url("SignatureMethod", "HmacSHA256")builder.put_url("Timestamp", timestamp)host = urllib.parse.urlparse(url).hostnamepath = urllib.parse.urlparse(url).path# 对参数进行排序:keys = sorted(builder.param_map.keys())# 加入&qs0 = '&'.join(['%s=%s' % (key, parse.quote(builder.param_map[key], safe='')) for key in keys])# 请求方法,域名,路径,参数 后加入`\n`payload0 = '%s\n%s\n%s\n%s' % (method, host, path, qs0)dig = hmac.new(secret_key.encode('utf-8'), msg=payload0.encode('utf-8'), digestmod=hashlib.sha256).digest()# 进行base64编码s = base64.b64encode(dig).decode()builder.put_url("Signature", s)return retdef utc_now():return datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S')if __name__ == "__main__":api_key_test = "api_key_xxxxxxx"secret_key_test = "secret_key_xxxxxxx"method_test = "GET"url_test = "www.huobi.pro"builder = UrlParamsBuilder()builder.put_url("symbol", "usdtbtc")builder.put_url("types", "market,limit,margin")create_signature(api_key=api_key_test, secret_key=secret_key_test, method=method_test, url=url_test, builder=builder)print_builder(builder)

     

更多推荐

区块键量化交易学习笔记(四)

本文发布于:2024-02-28 15:09:05,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1769670.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:区块   学习笔记

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!