使用币安官方的API来编写一键买卖的Python函数

诸神缄默不语-个人CSDN博文目录

2021.5.6更新:我发现我忘把创建时间戳的函数写上了,今天补上。

这个问题是我之前面一个实习的时候让写的编程题。
做题心得1:金融编程在编程方面真的不难,但是在金融方面真的麻烦,有好多奇奇怪怪的黑话。
做题心得2:机构投资者的操作跟个人投资者真的完全不一样啊,作为个人投资者完全没必要搞这些操作来着……可能这就是官方文档真的很难懂的原因吧,毕竟大部分客户不需要接入。
面试心得:小公司是真的坑爹。虽然私企大多坑爹,但是小公司格外坑爹。

我看到币安那边有人写了集成性SDK的,但是我是直接用requests访问的。因为没钱所以好像没有实验成功的样子……但是事是这么个事,这个代码还是拿出来可供参考一下(毕竟我自己不炒币,这代码以后我也用不到,不发白不发了)。
撰写代码的时间在2020年12月左右,相关API等可能失效。

币安官网

币安API官方文档:
github文档
API文档
API常见问题

另外就是我不会websocket……币安API文档里面官方推荐用websocket,访问限制会小一些。但是我不会用就很尴尬。我在网上简单查了一下没看懂。但是直接用requests应该也够用。

虽然说这感觉像是我的计算机网络知识盲点,但是我觉得我学计算机网络的时候没学到这些东西?
计算机网络明明听起来是这么有用的一门学科,我为什么学完还是啥都不会啊?

不过币安官方还对机器学习有限制,具体条件可以看常见问题那个网页。其实我当时实习面的就是量化岗,我本人还是机器学习出身的,所以说当时看到那一条的时候就感觉很微妙_(:ι」∠)_

相比之下requests入门比较快嘛,而且以前爬虫时候用过。
可以参考博文:
Python处理HTTP请求之requests指北
用python如何curl
requests.post() 方法的使用

币安的API必须要科学上网才能连接。
他们的文档有点难看懂(可能是因为我太菜了),但是客服回应挺快的,我问了客服很多问题都得到了耐心的解答,表扬!

说明一下,由于账号中没有真钱,所以用的是Spot Test Network的密钥和链接。按道理讲,应该是可以直接替换成Spot API进行真实交易的。

因为代码使用Jupyter Notebook写的,发文章时候我也懒得改了……就还是照着原格式一个cell一个cell写吧


[1]导入包

import requests
import json
import time
import hmac
import hashlib

[2]key和密钥是币安官方给的。
创建教程:如何创建API - Biance(币安)
因为账户里没钱,所以我写代码时用的是测试账户(加了_test的baseURL),我看逻辑上应该是可以把测试账户直接改成真实账户的,就把密钥和链接修改一下就行。
coin_list是币种,BTC比特币,LTC莱特币,BNB币安币。

#属性配置
apiKey=''
apiSecretKey=''
apiKey_test=''
apiSecretKey_test=''

baseUrl='https://api.binance.com'
baseUrl_test='https://testnet.binance.vision'

coin_list=['BTC','LTC','BNB']

[3]生成时间戳

def createTimeStamp():
    return int(time.time()*1000)

[4]生成签名

官方文档原话:

签名使用HMAC SHA256算法. API-KEY所对应的API-Secret作为 HMAC SHA256 的密钥,其他所有参数作为HMAC SHA256的操作对象,得到的输出即为签名。
签名 大小写不敏感.

咳,不过我是从GitHub上直接抄的代码就是了,我也没研究这具体是啥意思。
param2string函数将参数字典生成为字符串,然后使用hashing函数生成签名。

def param2string(param):
    """本函数用于根据param(一个参数字典)生成后缀字符串"""
    s=''
    for k in param.keys():
        s+=k
        s+='='
        s+=str(param[k])
        s+='&'
    return s[:-1]
    
def hashing(query_string):
    """本函数用于根据后缀生成签名"""
    #代码参考来源:https://github.com/binance-exchange/binance-signature-examples/blob/master/python/signature.py
    return hmac.new(apiSecretKey_test.encode('utf-8'), query_string.encode('utf-8'), hashlib.sha256).hexdigest()

[4]一键买入函数
post方法,/api/v3/order接口。
注意根据订单类型不同,可能需要的参数也不同。这里用的是市价单,用quoteOrderQty来衡量交易量。

币安官方文档原文:

使用 quoteOrderQty 的市价单MARKET 明确的是通过买入(或卖出)想要花费(或获取)的报价资产数量; 此时的正确报单数量将会以市场流动性和quoteOrderQty被计算出来。
以BTCUSDT为例, quoteOrderQty=100:
 下买单的时候, 订单会尽可能的买进价值100USDT的BTC.
 下卖单的时候, 订单会尽可能的卖出价值100USDT的BTC.
使用 quoteOrderQty 的市价单MARKET不会突破LOT_SIZE的限制规则; 报单会按给定的quoteOrderQty尽可能接近地被执行。

(注意币安官方说wapi开头的API就只能用查询字符串了,因为文档里只有curl的例子,我没搞懂这个requests的data参数还能不能用?反正交易类接口都是api开头的,这种的应该可以用)
(如果不能用,应该可以直接将requests的链接后缀加上param2string这个函数的返回值,然后删掉data参数)

def OneClickBuy(coin_list,pay_by_money_category,pay_by_money_amount):
    """
    coin_list是币名列表,pay_by_money_category是用于买币的币种,pay_by_money_amount是用于买币的币种的数值
    本函数用于一键购买列表中的币
    如果在某一币处交易失败将返回失败原因与已成功的交易
    """
    for c in coin_list:
        data_symbol=c+pay_by_money_category
        data_side='BUY'
        data_type='MARKET'
        data_quoteOrderQty=pay_by_money_amount/3
        data_timestamp=createTimeStamp()
        p={
     'symbol':data_symbol,'side':data_side,'type':data_type,'quoteOrderQty':data_quoteOrderQty,'timestamp':data_timestamp}
        p['signature']=hashing(param2string(p))
        response1=requests.post(url=baseUrl_test+'/api/v3/order',headers={
     'X-MBX-APIKEY':apiKey_test},data=p)
        if response1.status_code!=200:
            print(c+'购买失败!失败原因是:'+response1.json()['msg'])
        else:
            print(c+'购买成功!')

[5]一键卖出函数
差不多就是[4]把side参数换掉,这样的变化程度

def OneClickSell(coin_list,get_category,sell_amount):
    """
    coin_list是币名列表,get_category是卖出后得到的币种名,sell_amount是各自卖出的额度
    本函数用于一键出售列表中的币
    如果在某一币处交易失败将返回失败原因与已成功的交易
    """
    for c in coin_list:
        data_symbol=c+get_category
        data_side='SELL'
        data_type='MARKET'
        data_quantity=sell_amount
        data_timestamp=createTimeStamp()
        p={
     'symbol':data_symbol,'side':data_side,'type':data_type,'quoteOrderQty':data_quoteOrderQty,'timestamp':data_timestamp}
        p['signature']=hashing(param2string(p))
        response1=requests.post(url=baseUrl_test+'/api/v3/order',headers={
     'X-MBX-APIKEY':apiKey_test},data=p)
        if response1.status_code!=200:
            print(c+'购买失败!失败原因是:'+response1.json()['msg'])
        else:
            print(c+'购买成功!')

你可能感兴趣的:(编程实践项目,python,接口,api)