You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

解决方案

问题根源

  1. 价格/数量精度不符合平台规则:Binance对每个交易对的价格小数位数、数量小数位数有严格限制,-1013和-1111报错都是因为传入的参数超出了对应交易对的允许范围。
  2. 卖出函数逻辑错误:卖出时沿用了买入的数量计算方式amount / float(price),但卖出的amount应该是持有的BTC数量,而非法币金额(比如代码里的self.qty_eur)。买入是用法币换币,计算可买数量;卖出是卖手里的币,需传入实际持仓量。
  3. 盲目循环调精度无效:靠递减小数位数试错的方式,没有贴合Binance的官方规则,容易遗漏关键限制。

修复步骤

  1. 获取交易对的官方精度规则:通过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
    
  2. 修正卖出函数的数量逻辑:卖出时传入实际持有的BTC数量,若业务需要对应固定法币金额的卖出,应从买入订单中提取实际成交的币数,而非重新计算。
  3. 按规则格式化参数:根据获取到的精度格式化价格和数量,且转成字符串传入(避免浮点数精度丢失):
    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
    
  4. 修正函数调用逻辑:从买入订单中提取实际买到的数量作为卖出参数:
    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 06:45:16