Binance API Python杠杆交易买卖函数实现与报错排查求助
问题排查与修复方案
核心问题点
- 硬编码精度导致Lot size错误:第一个函数会根据交易对的
stepSize动态计算保留小数位数,但是sell_quantity1、sell_quantity2直接写死了round(order,5),不同交易对的精度规则完全不同,比如DOGEUSDT的stepSize为1,要求下单数量为整数,保留5位小数完全不符合规则,直接触发Lot size failure报错。 - 未覆盖利息导致资金不足错误:平空仓时仅取了
borrowed字段的借币本金,没有计算未支付的借币利息,实际可平仓需要的数量要覆盖本金+利息,仅卖本金数量的话,后续还款会出现资金缺口,触发Insufficient funds报错。 - 未校验最小下单金额规则:Binance要求所有订单的名义价值(数量*当前价格)大于等于10USDT(部分交易对规则不同),两个平仓函数都没有做这个校验,如果计算出来的平仓金额小于阈值就会报错。
- 取值逻辑不符合交易场景:平多仓时取的
free余额可能已经被其他挂单冻结,部分场景下取到的free会小于实际可平数量,或者出现浮点数精度偏差。
修复后的代码示例
首先提取通用工具函数,避免重复逻辑:
import math import pandas as pd def get_symbol_precision(symbol): """动态获取交易对的数量精度""" symbol_info = client.get_symbol_info(symbol) step_size = float([f for f in symbol_info['filters'] if f['filterType'] == 'LOT_SIZE'][0]['stepSize']) return int(round(-math.log(step_size, 10), 0)) def check_min_notional(symbol, quantity): """校验订单是否满足最小名义金额要求""" price = float(client.get_recent_trades(symbol=symbol)[0]['price']) min_notional = float([f for f in client.get_symbol_info(symbol)['filters'] if f['filterType'] == 'MIN_NOTIONAL'][0]['minNotional']) return quantity * price >= min_notional
修复后的平空数量获取函数:
def sell_quantity1(symbol, asset): a = 0 while a < 3: try: margin_assets = pd.DataFrame(client.get_margin_account()['userAssets']) asset_info = margin_assets[margin_assets['asset']==asset].iloc[0] # 总负债=本金+利息 total_debt = float(asset_info['borrowed']) + float(asset_info['interest']) break except Exception as e: print("can't extract borrowed amount..retrying") a+=1 # 动态取精度,不硬编码位数 precision = get_symbol_precision(symbol) quantity = round(total_debt, precision) # 校验最小下单金额 if not check_min_notional(symbol, quantity): raise ValueError(f"平仓金额小于交易对最小要求,无法下单") return quantity
修复后的平多数量获取函数:
def sell_quantity2(symbol, asset): a = 0 while a < 3: try: margin_assets = pd.DataFrame(client.get_margin_account()['userAssets']) asset_info = margin_assets[margin_assets['asset']==asset].iloc[0] free_amount = float(asset_info['free']) break except Exception as e: print("can't extract available amount..retrying") a+=1 precision = get_symbol_precision(symbol) quantity = round(free_amount * 0.9995, precision) # 预留手续费空间 if not check_min_notional(symbol, quantity): raise ValueError(f"平仓金额小于交易对最小要求,无法下单") return quantity
额外优化建议
- 不要硬编码filters的索引取值,比如原第一个函数里用
['filters'][2]取stepSize,Binance的接口返回filter顺序可能调整,最好按filterType过滤取值,避免后续接口变更导致报错。 - 所有下单前可以先调用
client.create_test_order做测试,确认参数没问题再发真实订单,减少报错概率。 - 浮点数计算可以用
decimal模块处理,避免二进制精度丢失导致的数量偏差。
内容的提问来源于stack exchange,提问作者Prakul Jaiswal
相关产品推荐
相关产品推荐

