HTTP 5XX返回码用于内部错误;问题在币安的一面.重要的是不要将其视为失败手术;执行状态为UNKNOWN,可能是成功.
HTTP 5XX return codes are used for internal errors; the issue is on
Binance's side. It is important to NOT treat this as a failure
operation; the execution status is UNKNOWN and could have been a
success.
但是我不这样认为,因为我可以毫无问题地运行其他代码的功能 get_account_balance()
.我不确定自己在做什么错,除了发出GET与POST请求外,这两个代码几乎完全相同.
However I don't believe that to be the case because I can run the other code's function get_account_balance()
without issues. I'm not sure what I'm doing wrong, both codes are almost identical except for making GET vs. POST requests.
获得帐户余额的代码-可以正常工作:
Code to get account balance - works fine:
import json
import time
import hmac
import settings
import hashlib
import urllib.parse
import urllib.request
def get_account_balance():
# Setup header with API_KEY
headers = {'X-MBX-APIKEY': settings.API_KEY}
# Params requires timestamp in MS
params = {'timestamp': int(time.time() * 1000)}
# Encode params into url
url = 'https://api.binance.us/api/v3/account?' + urllib.parse.urlencode(params)
# Create a HMAC SHA256 signature
secret = bytes(settings.SECRET_KEY.encode('utf-8'))
signature = hmac.new(secret, urllib.parse.urlencode(params).encode('utf-8'), hashlib.sha256).hexdigest()
# Add signature to url
url += f'&signature={signature}'
# Make a request
req = urllib.request.Request(url, headers=headers)
# Read and decode response
response = urllib.request.urlopen(req).read().decode('utf-8')
# Convert to json
response_json = json.loads(response)
# Print balances for all coins not at 0
for entry in response_json['balances']:
if entry['free'] == '0.00000000':
continue
print(entry)
get_account_balance()
进行交易的代码-不起作用:
Code to place trade - does not work:
import json
import time
import hmac
import settings
import hashlib
import urllib.parse
import urllib.request
def place_trade(symbol, side, order_type, quantity):
# Setup header with API_KEY
headers = {'X-MBX-APIKEY': settings.API_KEY}
# Params require symbol, side, type, quantity and timestamp (for market orders)
params = {
'symbol': symbol,
'side': side,
'type': order_type,
'quantity': quantity,
'timestamp': int(time.time() * 1000)
}
# Encode params into url
url = 'https://api.binance.us/api/v3/order/test?' + urllib.parse.urlencode(params)
# Create a HMAC SHA256 signature
secret = bytes(settings.SECRET_KEY.encode('utf-8'))
signature = hmac.new(secret, urllib.parse.urlencode(params).encode('utf-8'), hashlib.sha256).hexdigest()
# Add signature to url
url += f'&signature={signature}'
# Encode params
data = urllib.parse.urlencode(params).encode('ascii')
# Make a POST request
req = urllib.request.Request(url, data, headers)
# Open request and convert to string and then to json
response = urllib.request.urlopen(req) # <- line with error
response_str = response.read().decode('utf-8')
response_json = json.loads(response_str)
print(response_json)
place_trade(symbol='BTCUSD', side='BUY', order_type='MARKET', quantity=1)
参考
美国Binance主页
美国Binance API Github
API新订单端点
API新订单端点-用于测试*
在示例中使用了该端点,但是两个端点的功能相同并且具有相同的错误
This endpoint is used in the example but both endpoints function the same and have the same error
我还查看了示例库 python-binance
GitHub
文档
编辑
我可以使用 requests
库成功下订单.我浏览了库的源代码,但无法弄清楚如何使用 urllib
I can place a successful order using the requests
library. I went through the library's source code but can't figure out how to properly format a POST request using urllib
使用请求
库进行交易的代码-起作用:
Code to place trade using requests
library - works:
import hmac
import time
import hashlib
import requests
import settings
import urllib.parse
session = requests.session()
session.headers.update({'X-MBX-APIKEY': settings.API_KEY})
url = 'https://api.binance.us/api/v3/order/test'
params = {
'symbol': 'BTCUSD',
'side': 'BUY',
'type': 'MARKET',
'quantity': 1,
'timestamp': int(time.time() * 1000)
}
secret = bytes(settings.SECRET_KEY.encode('utf-8'))
signature = hmac.new(secret, urllib.parse.urlencode(params).encode('utf-8'), hashlib.sha256).hexdigest()
params['signature'] = signature
result = session.post(url, params)
print(result)
print(result.text)
推荐答案
问题出在以下几行:
# Encode params into url
url = 'https://api.binance.us/api/v3/order/test?' + urllib.parse.urlencode(params)
# Add signature to url
url += f'&signature={signature}'
显然,当使用 urllib
时,必须将GET请求有效负载编码到url本身,但是POST请求要求您将它们传递到 data
参数中:>
Apparently, when using urllib
GET request payloads have to be encoded into the url itself, however POST requests require you to pass them into into the data
parameter:
data = urllib.parse.urlencode(params).encode('ascii')
req = urllib.request.Request(url, data=data, headers=headers)
在我的问题中,我正在通过URL和 data
参数传递有效负载.删除URL有效内容可解决此问题.附带说明,供任何绊脚的人使用,在使用 urllib
In my question, I was passing my payload through the url AND the data
parameter. Removing the url payload fixes the issue. Side note for anyone stumbling upon this, putting a question mark ?
after the url is optional for POST requests but not GET requests when using urllib
无需外部库即可发布交易的有效代码:
Working code to post a trade without external libraries:
import json
import time
import hmac
import hashlib
import settings
import urllib.parse
import urllib.request
params = {
'symbol': 'BTCUSD',
'side': 'BUY',
'type': 'MARKET',
'quantity': 1,
'timestamp': int(time.time() * 1000)
}
secret = bytes(settings.SECRET_KEY.encode('utf-8'))
signature = hmac.new(secret, urllib.parse.urlencode(params).encode('utf-8'), hashlib.sha256).hexdigest()
params['signature'] = signature
url = 'https://api.binance.us/api/v3/order/test'
headers = {'X-MBX-APIKEY': settings.API_KEY}
data = urllib.parse.urlencode(params).encode('ascii')
req = urllib.request.Request(url, data=data, headers=headers)
response = urllib.request.urlopen(req)
response_str = response.read().decode('utf-8')
response_json = json.loads(response_str)
print(response_json)
这篇关于使用Python使用Binance API进行交易的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!