量化交易|币安合约止损单因强制迁移至 Algo Order API 导致创建失败问题记录(2025-12-16)

量化交易|币安合约止损单因强制迁移至 Algo Order API 导致创建失败问题记录(2025-12-16)

一、问题背景

在使用 Freqtrade + Binance USDT-M Futures(币安合约) 进行量化交易实盘运行时,发现新开仓位在成交后,止损单创建失败,导致仓位在短时间内处于无止损保护状态,存在较大的实盘风险。

该问题并非策略逻辑错误,而是 Binance API 在 2025 年底的一次强制性变更,与 Freqtrade / ccxt 的实现方式产生了不兼容。

file

file

异常信息:

2025-12-16 09:21:44 INFO    freqtrade.worker - Bot heartbeat. PID=1, version='docker-2025.8-dev-87b0a6d3', state='RUNNING'
2025-12-16 09:21:49 WARNING freqtrade.exchange.common - create_stoploss() returned exception: "Could not place stoploss order due to ExchangeError. Message: binance {"code":-4120,"msg":"Order type not supported for this endpoint. Please use the Algo Order API endpoints instead."}". Giving up.
2025-12-16 09:21:49 ERROR   freqtrade.freqtradebot - Unable to place a stoploss order on exchange.
Traceback (most recent call last):
  File "/home/ftuser/.local/lib/python3.13/site-packages/ccxt/base/exchange.py", line 585, in fetch
    response.raise_for_status()
    ~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/ftuser/.local/lib/python3.13/site-packages/requests/models.py", line 1026, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://fapi.binance.com/fapi/v1/order

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/freqtrade/freqtrade/exchange/exchange.py", line 1494, in create_stoploss
    order = self._api.create_order(
        symbol=pair,
    ...<4 lines>...
        params=params,
    )
  File "/home/ftuser/.local/lib/python3.13/site-packages/ccxt/binance.py", line 6080, in create_order
    response = self.fapiPrivatePostOrder(request)
  File "/home/ftuser/.local/lib/python3.13/site-packages/ccxt/base/types.py", line 35, in unbound_method
    return _self.request(self.path, self.api, self.method, params, config=self.config)
           ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ftuser/.local/lib/python3.13/site-packages/ccxt/binance.py", line 11395, in request
    response = self.fetch2(path, api, method, params, headers, body, config)
  File "/home/ftuser/.local/lib/python3.13/site-packages/ccxt/base/exchange.py", line 4564, in fetch2
    raise e
  File "/home/ftuser/.local/lib/python3.13/site-packages/ccxt/base/exchange.py", line 4553, in fetch2
    return self.fetch(request['url'], request['method'], request['headers'], request['body'])
           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ftuser/.local/lib/python3.13/site-packages/ccxt/base/exchange.py", line 601, in fetch
    skip_further_error_handling = self.handle_errors(http_status_code, http_status_text, url, method, headers, http_response, json_response, request_headers, request_body)
  File "/home/ftuser/.local/lib/python3.13/site-packages/ccxt/binance.py", line 11364, in handle_errors
    raise ExchangeError(feedback)
ccxt.base.errors.ExchangeError: binance {"code":-4120,"msg":"Order type not supported for this endpoint. Please use the Algo Order API endpoints instead."}

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/freqtrade/freqtrade/freqtradebot.py", line 1402, in create_stoploss_order
    stoploss_order = self.exchange.create_stoploss(
        pair=trade.pair,
    ...<4 lines>...
        leverage=trade.leverage,
    )
  File "/freqtrade/freqtrade/exchange/common.py", line 187, in wrapper
    raise ex
  File "/freqtrade/freqtrade/exchange/common.py", line 172, in wrapper
    return f(*args, **kwargs)
  File "/freqtrade/freqtrade/exchange/exchange.py", line 1526, in create_stoploss
    raise TemporaryError(
        f"Could not place stoploss order due to {e.__class__.__name__}. Message: {e}"
    ) from e
freqtrade.exceptions.TemporaryError: Could not place stoploss order due to ExchangeError. Message: binance {"code":-4120,"msg":"Order type not supported for this endpoint. Please use the Algo Order API endpoints instead."}
2025-12-16 09:22:09 WARNING freqtrade.exchange.common - create_stoploss() returned exception: "Could not place stoploss order due to ExchangeError. Message: binance {"code":-4120,"msg":"Order type not supported for this endpoint. Please use the Algo Order API endpoints instead."}". Giving up.
2025-12-16 09:22:09 ERROR   freqtrade.freqtradebot - Unable to place a stoploss order on exchange.
Traceback (most recent call last):
  File "/home/ftuser/.local/lib/python3.13/site-packages/ccxt/base/exchange.py", line 585, in fetch
    response.raise_for_status()
    ~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/ftuser/.local/lib/python3.13/site-packages/requests/models.py", line 1026, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://fapi.binance.com/fapi/v1/order

During handling of the above exception, another exception occurred:

二、问题现象

1️⃣ 日志表现

Freqtrade 在尝试创建止损单时直接失败:

create_stoploss() returned exception:
Could not place stoploss order due to ExchangeError.
Message: binance {"code":-4120,
"msg":"Order type not supported for this endpoint. Please use the Algo Order API endpoints instead."}

随后抛出异常:

freqtrade.exceptions.TemporaryError: Unable to place a stoploss order on exchange.

2️⃣ 直接影响

  • ✅ 开仓成功
  • ❌ 止损单未成功创建
  • ⚠️ 仓位在一段时间内无任何风险保护

在实盘环境下,这是一个高风险问题


三、复现条件(Steps to Reproduce)

只要满足以下条件,即 100% 复现

  1. 使用 Binance USDT-M Futures
  2. Freqtrade 配置中启用交易所止损:
"stoploss_on_exchange": true
  1. 使用任何带有止损参数的策略,例如:
stoploss = -0.10
  1. 启动机器人并成功开仓

👉 在 买单成交后、创建止损单时立即失败


四、错误根因分析(GitHub Issue 总结)

1️⃣ Binance API 强制变更

2025-12-09 起,Binance 对 USDT-M Futures API 进行了强制升级:

  • 不再允许 通过旧接口创建条件单

    POST /fapi/v1/order
  • 所有条件单(止损 / 止盈)必须使用新接口

    POST /fapi/v1/algoOrder

涉及的订单类型包括:

  • STOP_MARKET
  • TAKE_PROFIT_MARKET
  • closePosition=true 的止损/止盈单

2️⃣ Freqtrade / ccxt 的行为

在问题版本中:

  • Freqtrade 仍然通过 ccxt 的 create_order()
  • ccxt 内部调用的是:
POST https://fapi.binance.com/fapi/v1/order

该接口 已被 Binance 明确禁止用于条件单,从而直接返回:

{
  "code": -4120,
  "msg": "Order type not supported for this endpoint. Please use the Algo Order API endpoints instead."
}

3️⃣ 官方变更公告

Binance 在官方 Change Log 中已明确说明该变更:

  • 文档位置:Binance Derivatives Change Log
  • 条目时间:2025-11-06
  • 生效时间:2025-12-09

该变更是 强制性的、非向后兼容


五、异常堆栈(关键片段)

ccxt.base.errors.ExchangeError: binance {"code":-4120,
"msg":"Order type not supported for this endpoint. Please use the Algo Order API endpoints instead."}

freqtrade.exceptions.TemporaryError:
Could not place stoploss order due to ExchangeError

从堆栈可以清晰看出:

  • Freqtrade → ccxt → Binance /fapi/v1/order
  • Binance 明确拒绝该请求

六、问题本质总结

这是一次典型的「交易所 API 强制升级 → 量化框架未及时适配」问题

关键点:

  • ❌ 不是策略问题
  • ❌ 不是参数配置错误
  • ❌ 不是用户误操作
  • ✅ 是 Binance API 规则改变
  • ✅ 是 Freqtrade / ccxt 旧实现不兼容

七、解决方式

✅ 官方修复方案(推荐)

Freqtrade 已在 2025.11.1 版本中正式修复该问题:

fix: support binance algo orders

该版本:

  • ✅ 已适配 Binance Futures Algo Order API
  • ✅ 止损 / 止盈条件单将通过正确接口发送
  • ✅ 不再触发 -4120 错误

说明:该版本通过 cherry-pick 的方式合并了针对 Binance Algo Order 的修复。


🔧 升级建议

1️⃣ 升级 Freqtrade

如果你使用的是 Docker:

docker pull freqtradeorg/freqtrade:2025.11.1
docker compose down
docker compose up -d

或确保你的镜像 / 源码版本 ≥ 2025.11.1

file

升级版本后,可以看到创建条件止损单成功了 ^_^:
file

镜像地址:https://hub.docker.com/layers/freqtradeorg/freqtrade/2025.11.1/images/sha256-f196c1023bc9dd631e7ef1e79959fed9d3e6789df30c359dfb5ca1350e77bedf

github地址:https://github.com/freqtrade/freqtrade/releases/tag/2025.11.1


八、实盘经验总结

  • Binance Futures 不再适合使用旧式交易所止损接口
  • 所有条件单相关功能,都必须关注交易所 API 的强制升级公告
  • 实盘运行前,务必关注:

    • 交易所 Change Log
    • Freqtrade Release Notes
    • ccxt 版本兼容性

九、参考链接


记录日期:2025-12-16
关键词:Freqtrade / Binance Futures / Algo Order / Stoploss / ccxt / 实盘踩坑记录

为者常成,行者常至