Python调用Binance API创建订单报-1111精度超限、-2021立即触发错误
问题根因
两个报错分别对应参数配置错误,手动将数值四舍五入保留2位小数的处理方式完全不符合币安API的规则要求:
-1111 精度超限:币安合约每个交易对的下单数量、价格允许的小数位数是单独定义的,没有统一保留2位的规则,硬编码round位数要么超出精度上限,要么不符合交易对的最小下单步长要求。-2021 订单会立即触发:要么是止损/止盈的触发价格不符合持仓方向的规则,挂单时价格已经处于触发区间,提交后会立刻成交;要么是平仓单的交易方向写反,导致订单逻辑异常。你原有代码里开的是SELL方向空单,但止损止盈平仓单的side也写了SELL,属于方向配置错误,平仓单方向必须和开仓方向相反。
解决方案
1. 动态拉取交易对规则,禁止硬编码精度参数
所有精度、最小下单量参数都要通过接口实时拉取,不要自己写死数值:
# 获取合约交易对规则 exchange_info = client.futures_exchange_info() symbol_info = next(item for item in exchange_info['symbols'] if item['symbol'] == symbol) # 读取对应精度 price_precision = symbol_info['pricePrecision'] quantity_precision = symbol_info['quantityPrecision'] # 读取最小下单量限制 lot_size_filter = [f for f in symbol_info['filters'] if f['filterType'] == 'LOT_SIZE'][0] min_qty = float(lot_size_filter['minQty'])
2. 统一处理参数精度
不要直接用内置round处理浮点数,避免二进制浮点数精度误差导致参数不符合要求,写通用精度处理函数:
def format_precision(value, precision): factor = 10 ** precision return round(value * factor) / factor
所有涉及数量、价格的参数(包括限价单价格、止损止盈触发价)都要对应交易对的精度做格式化,下单数量还要校验不小于最小下单量要求。
3. 校验条件单价格方向
提交条件单前必须校验价格位置,避免触发立即成交错误:
- 持有SELL方向空单时:STOP_MARKET止损单的触发价必须高于当前标记价/最新价(价格上涨到阈值时平仓止损),TAKE_PROFIT_MARKET止盈单的触发价必须低于当前标记价/最新价(价格下跌到阈值时平仓止盈)
- 持有BUY方向多单时规则相反:止损价低于当前价,止盈价高于当前价
另外注意平仓单的side必须和开仓方向相反:平空用BUY,平多用SELL,哪怕传了closePosition=true也要传对方向参数。
修正后参考代码
pos = "SELL" # 拉取交易对规则 exchange_info = client.futures_exchange_info() symbol_info = next(item for item in exchange_info['symbols'] if item['symbol'] == symbol) price_precision = symbol_info['pricePrecision'] quantity_precision = symbol_info['quantityPrecision'] lot_size_filter = [f for f in symbol_info['filters'] if f['filterType'] == 'LOT_SIZE'][0] min_qty = float(lot_size_filter['minQty']) # 精度格式化函数 def format_precision(value, precision): factor = 10 ** precision return round(value * factor) / factor # 处理开仓参数 q = tbal / price q = max(q, min_qty) # 保证不小于最小下单量 q = format_precision(q, quantity_precision) open_price = format_precision(price, price_precision) # 设置杠杆 client.futures_change_leverage(symbol=symbol, leverage=info.laverage) # 处理止损止盈价格 stop_loss_price = format_precision(open_price * info.stopshort, price_precision) take_profit_price = format_precision(open_price * info.takeshort, price_precision) # 校验价格方向(调试阶段建议开启) current_mark_price = float(client.futures_mark_price(symbol=symbol)['markPrice']) if pos == "SELL": if stop_loss_price <= current_mark_price: raise ValueError("空单止损价必须高于当前标记价") if take_profit_price >= current_mark_price: raise ValueError("空单止盈价必须低于当前标记价") # 建议先挂止损止盈单,再挂开仓单,避免开仓后未带上止损 stop_order = client.futures_create_order( symbol=symbol, side="BUY", # 平空方向为BUY type="STOP_MARKET", stopPrice=stop_loss_price, closePosition="true" ) take_order = client.futures_create_order( symbol=symbol, side="BUY", # 平空方向为BUY type="TAKE_PROFIT_MARKET", stopPrice=take_profit_price, closePosition="true" ) open_order = client.futures_create_order( symbol=symbol, side=pos, type="LIMIT", quantity=q, price=open_price, timeInForce="GTC" )
内容的提问来源于stack exchange,提问作者Andrey Kanava
相关产品推荐
相关产品推荐

