Binance API买入函数正常但卖出函数报错(精度/价格过滤问题)
Binance API 卖出BTC时精度报错问题
问题背景
我用Binance API开发交易功能,putOrderBuy_at_price函数已实现指定价格买入BTC且运行正常,但调用putOrderSell_at_price函数按指定价格卖出BTC时持续报错。
报错信息
Binance API: APIError(code=-1111): Precision is over the maximum defined for this asset.
或
Binance API returns with: APIError(code=-1013): Filter failure: PRICE_FILTER
测试时打印的卖出价格为23131.845,数量为20,尝试通过循环调整精度但无效。
正常运行的买入函数代码
def putOrderBuy_at_price(self, symbol, amount, price): monney_price = self.client.get_symbol_ticker(symbol=symbol) # Calculate how much ETH $200 can buy print(monney_price['price']) i = 15 while i != 0: try: buy_quantity = round(amount / float(price), i) print("-----------", buy_quantity) #ETHUSDT buy_order = self.client.create_order( symbol = symbol, price = price, quantity = buy_quantity, side = self.client.SIDE_BUY, type = self.client.ORDER_TYPE_LIMIT, timeInForce = self.client.TIME_IN_FORCE_GTC) return(buy_order) except Exception: print(i) i -= 1 print(buy_quantity) # buy_order = self.client.create_order( # symbol = symbol, # price = price, # quantity = buy_quantity, # side = self.client.SIDE_BUY, # type = self.client.ORDER_TYPE_LIMIT, # timeInForce = self.client.TIME_IN_FORCE_GTC)
报错的卖出函数代码
def putOrderSell_at_price(self, symbol, amount, price): monney_price = self.client.get_symbol_ticker(symbol=symbol) i = 10 print("ahsaiaa", price, amount) while i != 0: try: buy_quantity = round(amount / float(price), i) #ETHUSDT buy_order = self.client.create_order( symbol = symbol, price = price, quantity = buy_quantity, side = self.client.SIDE_SELL, type = self.client.ORDER_TYPE_LIMIT, timeInForce = self.client.TIME_IN_FORCE_GTC) return(buy_order) except Exception: print(i) i -= 1 print("vente faite")
函数调用方式
buy = self.putOrderBuy_at_price(symbol, self.qty_eur, price_actual) #le principal sell = self.putOrderSell_at_price(symbol, self.qty_eur, float(price_actual)*1.1) #l ordre de vente
解决方案
问题根源
- 价格/数量精度不符合平台规则:Binance对每个交易对的价格小数位数、数量小数位数有严格限制,
-1013和-1111报错都是因为传入的参数超出了对应交易对的允许范围。 - 卖出函数逻辑错误:卖出时沿用了买入的数量计算方式
amount / float(price),但卖出的amount应该是持有的BTC数量,而非法币金额(比如代码里的self.qty_eur)。买入是用法币换币,计算可买数量;卖出是卖手里的币,需传入实际持仓量。 - 盲目循环调精度无效:靠递减小数位数试错的方式,没有贴合Binance的官方规则,容易遗漏关键限制。
修复步骤
- 获取交易对的官方精度规则:通过
get_symbol_info接口获取目标交易对的精度要求,包括价格最小变动单位、数量最小变动单位等:symbol_info = self.client.get_symbol_info("BTCUSDT") # 提取价格精度 price_filter = next(f for f in symbol_info['filters'] if f['filterType'] == 'PRICE_FILTER') tick_size = float(price_filter['tickSize']) price_precision = len(str(tick_size).split('.')[1]) if '.' in str(tick_size) else 0 # 提取数量精度 lot_size_filter = next(f for f in symbol_info['filters'] if f['filterType'] == 'LOT_SIZE') step_size = float(lot_size_filter['stepSize']) quantity_precision = len(str(step_size).split('.')[1]) if '.' in str(step_size) else 0 - 修正卖出函数的数量逻辑:卖出时传入实际持有的BTC数量,若业务需要对应固定法币金额的卖出,应从买入订单中提取实际成交的币数,而非重新计算。
- 按规则格式化参数:根据获取到的精度格式化价格和数量,且转成字符串传入(避免浮点数精度丢失):
def putOrderSell_at_price(self, symbol, quantity, price): symbol_info = self.client.get_symbol_info(symbol) # 获取价格精度 price_filter = next(f for f in symbol_info['filters'] if f['filterType'] == 'PRICE_FILTER') tick_size = float(price_filter['tickSize']) price_precision = len(str(tick_size).split('.')[1]) if '.' in str(tick_size) else 0 # 获取数量精度 lot_size_filter = next(f for f in symbol_info['filters'] if f['filterType'] == 'LOT_SIZE') step_size = float(lot_size_filter['stepSize']) quantity_precision = len(str(step_size).split('.')[1]) if '.' in str(step_size) else 0 # 格式化价格和数量 formatted_price = round(float(price), price_precision) formatted_quantity = round(float(quantity), quantity_precision) try: sell_order = self.client.create_order( symbol=symbol, price=str(formatted_price), quantity=str(formatted_quantity), side=self.client.SIDE_SELL, type=self.client.ORDER_TYPE_LIMIT, timeInForce=self.client.TIME_IN_FORCE_GTC) return sell_order except Exception as e: print(f"卖出失败: {e}") return None - 修正函数调用逻辑:从买入订单中提取实际买到的数量作为卖出参数:
buy = self.putOrderBuy_at_price(symbol, self.qty_eur, price_actual) # 提取实际成交的BTC数量 actual_bought_quantity = float(buy['executedQty']) sell = self.putOrderSell_at_price(symbol, actual_bought_quantity, float(price_actual)*1.1)
关键注意点
- Binance API要求价格和数量参数必须为字符串类型,避免浮点数精度丢失导致的规则校验失败。
- 不同交易对的精度规则不同,必须动态获取,不能用固定小数位数硬编码。
内容的提问来源于stack exchange,提问作者guiguilecodeur
相关产品推荐
相关产品推荐

