From 163b8303ec6ef7d70ef7d4720c28c0041dc48935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=96=87=E8=96=87=E5=AE=89?= Date: Wed, 25 Feb 2026 09:26:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(spot=5Forder):=20=E5=A2=9E=E5=BC=BA?= =?UTF-8?q?=E7=8E=B0=E8=B4=A7=E4=B8=8B=E5=8D=95API=E7=9A=84=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E5=A4=84=E7=90=86=E4=B8=8E=E6=96=87=E6=A1=A3=E8=AF=B4?= =?UTF-8?q?=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在现货下单API中添加了对下单金额的最小限制(5 USDT),并改进了错误处理机制,针对不同的Binance API异常提供了详细的错误信息。更新了API文档说明,确保用户能够更清晰地理解下单逻辑与要求。此改动提升了系统的健壮性与用户体验。 --- backend/api/routes/account.py | 39 +- docs/bian/现货交易.txt | 1784 ++++++++++++++++++++++++++++++ trading_system/market_scanner.py | 5 +- trading_system/redis_cache.py | 75 +- trading_system/strategy.py | 4 +- 5 files changed, 1855 insertions(+), 52 deletions(-) create mode 100644 docs/bian/现货交易.txt diff --git a/backend/api/routes/account.py b/backend/api/routes/account.py index 5fb0207..e813132 100644 --- a/backend/api/routes/account.py +++ b/backend/api/routes/account.py @@ -1583,12 +1583,21 @@ async def place_spot_order( price: float = Query(None, description="限价单价格(LIMIT 时必填)"), account_id: int = Depends(get_account_id), ): - """现货一键下单(市价单或限价单)。仅支持当前账号 API 密钥对应的现货账户。""" + """ + 现货一键下单。参考文档:POST /api/v3/order(现货)。 + 市价单使用 quoteOrderQty 表示要花费/收到的 USDT 数量;限价单使用 quantity+price。 + """ try: if side not in ("BUY", "SELL"): raise HTTPException(status_code=400, detail="side 必须是 BUY 或 SELL") if quote_order_qty <= 0: raise HTTPException(status_code=400, detail="下单金额必须大于 0") + # 币安现货多数交易对 MIN_NOTIONAL 为 5 USDT + if quote_order_qty < 5: + raise HTTPException( + status_code=400, + detail="现货下单金额不能低于 5 USDT(满足 MIN_NOTIONAL),请调大默认下单金额", + ) if order_type.upper() == "LIMIT" and (price is None or price <= 0): raise HTTPException(status_code=400, detail="限价单必须填写 price") @@ -1598,27 +1607,32 @@ async def place_spot_order( try: from binance_client import BinanceClient + from binance.exceptions import BinanceAPIException except ImportError: trading_system_path = project_root / "trading_system" sys.path.insert(0, str(trading_system_path)) from binance_client import BinanceClient + from binance.exceptions import BinanceAPIException client = BinanceClient(api_key=api_key, api_secret=api_secret, testnet=use_testnet) await client.connect() try: - # 现货使用底层 AsyncClient 的 create_order(spot API) + # 现货接口:POST /api/v3/order(与合约 fapi 不同)。python-binance 中 create_order 为现货。 + # 文档:市价单可用 quoteOrderQty 设置 quote asset 数量,传字符串避免精度问题。 + quote_str = f"{quote_order_qty:.2f}" + if order_type.upper() == "MARKET": order = await client.client.create_order( - symbol=symbol, + symbol=symbol.strip().upper(), side=side, type="MARKET", - quoteOrderQty=quote_order_qty, + quoteOrderQty=quote_str, ) else: - # LIMIT: 需要 quantity,用 quote_order_qty / price 估算 qty = quote_order_qty / price + # 限价单需要 quantity + price,quantity 需符合交易对 LOT_SIZE order = await client.client.create_order( - symbol=symbol, + symbol=symbol.strip().upper(), side=side, type="LIMIT", timeInForce="GTC", @@ -1636,6 +1650,19 @@ async def place_spot_order( await client.disconnect() except HTTPException: raise + except BinanceAPIException as e: + code = getattr(e, "code", getattr(e, "status_code", "")) + msg = str(e).strip() or getattr(e, "message", "") + if code == -2015: + detail = "API Key 无现货交易权限或无效。请在币安 API 管理中勾选「启用现货与杠杆交易」并使用该 Key。" + elif code == -1013: + detail = f"订单不满足交易对规则(如 MIN_NOTIONAL 约 5 USDT): {msg}" + elif code == -1121: + detail = f"交易对格式无效: {msg}" + else: + detail = f"币安现货接口错误 (code={code}): {msg}" + logger.warning("现货下单 BinanceAPIException: %s", detail) + raise HTTPException(status_code=400, detail=detail) except Exception as e: logger.exception("现货下单失败: %s", e) raise HTTPException(status_code=500, detail=f"现货下单失败: {str(e)}") diff --git a/docs/bian/现货交易.txt b/docs/bian/现货交易.txt new file mode 100644 index 0000000..4350c7e --- /dev/null +++ b/docs/bian/现货交易.txt @@ -0,0 +1,1784 @@ +交易接口 +下单 (TRADE) +POST /api/v3/order + +这个请求会把1个订单添加到 EXCHANGE_MAX_ORDERS 过滤器和 MAX_NUM_ORDERS 过滤器中。 + +权重: 1 + +未成交的订单计数: 1 + +参数: + +名称 类型 是否必需 描述 +symbol STRING YES +side ENUM YES 详见枚举定义:订单方向 +type ENUM YES 详见枚举定义:订单类型 +timeInForce ENUM NO 详见枚举定义:生效时间 +quantity DECIMAL NO +quoteOrderQty DECIMAL NO +price DECIMAL NO +newClientOrderId STRING NO 用户自定义的orderid,如空缺系统会自动赋值。 +strategyId LONG NO +strategyType INT NO 不能低于 1000000. +stopPrice DECIMAL NO 仅 STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, TAKE_PROFIT_LIMIT 需要此参数。 +trailingDelta LONG NO 参见 追踪止盈止损(Trailing Stop)订单常见问题。 +icebergQty DECIMAL NO 仅有限价单(包括条件限价单与限价做事单)可以使用该参数,含义为创建冰山订单并指定冰山订单的数量。 +newOrderRespType ENUM NO 指定响应类型 ACK, RESULT, or FULL; MARKET 与 LIMIT 订单默认为FULL, 其他默认为ACK。 +selfTradePreventionMode ENUM NO 允许的 ENUM 取决于交易对的配置。支持的值有:STP 模式。 +pegPriceType ENUM NO PRIMARY_PEG 或 MARKET_PEG。 +参阅 关于挂钩订单参数的注意事项 +pegOffsetValue INT NO 用于挂钩的价格水平(最大值:100)。 +参阅 关于挂钩订单参数的注意事项 +pegOffsetType ENUM NO 仅支持 PRICE_LEVEL。 +参阅 关于挂钩订单参数的注意事项 +recvWindow DECIMAL NO 最大值为 60000 毫秒。 +支持最多三位小数的精度(例如 6000.346),以便可以指定微秒。 +timestamp LONG YES +根据 order type的不同,某些参数 有强制要求,具体如下: + +Type 强制要求的参数 其他信息 +LIMIT timeInForce, quantity, price +MARKET quantity 市价买卖单可用quantity参数来设置base asset数量. +例如:BTCUSDT 市价单,BTC 买卖数量取决于quantity参数. + +市价买卖单可用quoteOrderQty参数来设置quote asset数量. 正确的quantity取决于市场的流动性与quoteOrderQty +例如: 市价 BUY BTCUSDT,单子会基于quoteOrderQty- USDT 的数量,购买 BTC. +市价 SELL BTCUSDT,单子会卖出 BTC 来满足quoteOrderQty- USDT 的数量. +STOP_LOSS quantity, stopPrice, trailingDelta 条件满足后会下MARKET单子. (例如:达到stopPrice或trailingDelta被启动) +STOP_LOSS_LIMIT timeInForce, quantity, price, stopPrice, trailingDelta +TAKE_PROFIT quantity, stopPrice, trailingDelta 条件满足后会下MARKET单子. (例如:达到stopPrice或trailingDelta被启动) +TAKE_PROFIT_LIMIT timeInForce, quantity, price, stopPrice, trailingDelta +LIMIT_MAKER quantity, price 订单大部分情况下与普通的限价单没有区别,但是如果在当前价格会立即吃对手单并成交则下单会被拒绝。因此使用这个订单类型可以保证订单一定是挂单方,不会成为吃单方。 +关于挂钩订单参数的注意事项: + +这些参数仅适用于 LIMIT, LIMIT_MAKER, STOP_LOSS_LIMIT 和 TAKE_PROFIT_LIMIT 订单。 +如果使用了 pegPriceType, 那么 price 字段将是可选的。 否则,price 字段依旧是必须的。 +pegPriceType=PRIMARY_PEG 就是主要挂钩(primary),这是订单簿上与您的订单同一方向的最佳价格。 +pegPriceType=MARKET_PEG 就是市场挂钩(market),这是订单簿上与您的订单相反方向的最佳价格。 +可以通过使用 pegOffsetType 和 pegOffsetValue 来获取最佳价格以外的价格水平。 这两个参数必须一起使用。 +其他: + +任何LIMIT或LIMIT_MAKER只要填icebergQty参数都可以下冰上订单。 +冰山订单的 timeInForce必须设置为GTC。 +STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT_LIMIT 与 TAKE_PROFIT 单子都能同时填上trailingDelta与stopPrice。 +填上quoteOrderQty的市价单不会触犯过滤器的LOT_SIZE限制。订单的quantity会尽量满足quoteOrderQty的数量。 +条件单的触发价格必须: + +比下单时当前市价高: STOP_LOSS BUY, TAKE_PROFIT SELL +比下单时当前市价低: STOP_LOSS SELL, TAKE_PROFIT BUY +关于 newOrderRespType的三种选择 + +数据源: 撮合引擎 + +Response ACK: 返回速度最快,不包含成交信息,信息量最少 + +{ + "symbol": "BTCUSDT", + "orderId": 28, + "orderListId": -1, // 除非此单是订单列表的一部分, 否则此值为 -1 + "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP", + "transactTime": 1507725176595 +} + +Response RESULT: 返回速度居中,返回吃单成交的少量信息 + +{ + "symbol": "BTCUSDT", + "orderId": 28, + "orderListId": -1, // 除非此单是订单列表的一部分, 否则此值为 -1 + "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP", + "transactTime": 1507725176595, + "price": "1.00000000", + "origQty": "10.00000000", + "executedQty": "10.00000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "10.00000000", + "status": "FILLED", + "timeInForce": "GTC", + "type": "MARKET", + "side": "SELL", + "workingTime": 1507725176595, + "selfTradePreventionMode": "NONE" +} + +Response FULL: 返回速度最慢,返回吃单成交的详细信息 + +{ + "symbol": "BTCUSDT", + "orderId": 28, + "orderListId": -1, // 除非此单是订单列表的一部分, 否则此值为 -1 + "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP", + "transactTime": 1507725176595, + "price": "1.00000000", + "origQty": "10.00000000", + "executedQty": "10.00000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "10.00000000", + "status": "FILLED", + "timeInForce": "GTC", + "type": "MARKET", + "side": "SELL", + "workingTime": 1507725176595, + "selfTradePreventionMode": "NONE", + "fills": [ + { + "price": "4000.00000000", + "qty": "1.00000000", + "commission": "4.00000000", + "commissionAsset": "USDT", + "tradeId": 56 + }, + { + "price": "3999.00000000", + "qty": "5.00000000", + "commission": "19.99500000", + "commissionAsset": "USDT", + "tradeId": 57 + }, + { + "price": "3998.00000000", + "qty": "2.00000000", + "commission": "7.99600000", + "commissionAsset": "USDT", + "tradeId": 58 + }, + { + "price": "3997.00000000", + "qty": "1.00000000", + "commission": "3.99700000", + "commissionAsset": "USDT", + "tradeId": 59 + }, + { + "price": "3995.00000000", + "qty": "1.00000000", + "commission": "3.99500000", + "commissionAsset": "USDT", + "tradeId": 60 + } + ] +} + + +订单响应中的特定条件时才会出现的字段 + +订单响应中的有一些字段仅在满足特定条件时才会出现。这些订单响应可以来自下订单,查询订单或取消订单,并且可以包括订单列表类型。 下面列出了这些字段: + +名称 描述 显示的条件 示例 +icebergQty 冰山订单的数量。 只有在请求中发送 icebergQty 参数时才会出现。 "icebergQty": "0.00000000" +preventedMatchId 与 symbol 结合使用时,可用于查询因为 STP 导致订单失效的过期订单。 只有在因为 STP 导致订单失效时可见。 "preventedMatchId": 0 +preventedQuantity 因为 STP 导致订单失效的数量。 只有在因为 STP 导致订单失效时可见。 "preventedQuantity": "1.200000" +stopPrice 用于设置逻辑订单中的触发价。 STOP_LOSS,TAKE_PROFIT,STOP_LOSS_LIMIT 和 TAKE_PROFIT_LIMIT 订单时可见。 "stopPrice": "23500.00000000" +strategyId 策略单ID; 用以关联此订单对应的交易策略。 如果在请求中添加了参数,则会出现。 "strategyId": 37463720 +strategyType 策略单类型; 用以显示此订单对应的交易策略。 如果在请求中添加了参数,则会出现。 "strategyType": 1000000 +trailingDelta 用以定义追踪止盈止损订单被触发的价格差。 出现在追踪止损订单中。 "trailingDelta": 10 +trailingTime 追踪单被激活和跟踪价格变化的时间。 出现在追踪止损订单中。 "trailingTime": -1 +usedSor 用于确定订单是否使用SOR的字段 在使用SOR下单时出现 "usedSor": true | +workingFloor 用以定义订单是通过 SOR 还是由订单提交到的订单薄(order book)成交的。 出现在使用了 SOR 的订单中。 "workingFloor": "SOR" +pegPriceType 挂钩价格类型 仅用于挂钩订单 "pegPriceType": "PRIMARY_PEG" +pegOffsetType 挂钩价格偏移类型 如若需要,仅用于挂钩订单 "pegOffsetType": "PRICE_LEVEL" +pegOffsetValue 挂钩价格偏移值 如若需要,仅用于挂钩订单 "pegOffsetValue": 5 +peggedPrice 订单对应的当前挂钩价格 一旦确定,仅用于挂钩订单 "peggedPrice": "87523.83710000" +测试下单接口 (TRADE) +POST /api/v3/order/test + +用于测试订单请求,但不会提交到撮合引擎 + +权重: + +条件 权重 +没有 computeCommissionRates 1 +有 computeCommissionRates 20 +参数: + +除了 POST /api/v3/order 所有参数, 下面参数也支持: + +参数名 类型 是否必需 描述 +computeCommissionRates BOOLEAN NO 默认值: false +请参阅佣金常见问题解答 了解更多信息。 +数据源: 缓存 + +响应: + +没有 computeCommissionRates + +{} + +有 computeCommissionRates + +{ + "standardCommissionForOrder": { // 订单交易的标准佣金率 + "maker": "0.00000112", + "taker": "0.00000114" + }, + "specialCommissionForOrder": { // 订单交易的特殊佣金率 + "maker": "0.05000000", + "taker": "0.06000000" + }, + "taxCommissionForOrder": { // 订单交易的税率 + "maker": "0.00000112", + "taker": "0.00000114" + }, + "discount": { // 以BNB支付时的标准佣金折扣。 + "enabledForAccount": true, + "enabledForSymbol": true, + "discountAsset": "BNB", + "discount": "0.25000000" // 当用BNB支付佣金时,在标准佣金上按此比率打折 + } +} + +撤销订单 (TRADE) +DELETE /api/v3/order + +权重: 1 + +参数: + +名称 类型 是否必需 描述 +symbol STRING YES +orderId LONG NO +origClientOrderId STRING NO +newClientOrderId STRING NO 用户自定义的本次撤销操作的ID(注意不是被撤销的订单的自定义ID)。如无指定会自动赋值。 +cancelRestrictions ENUM NO 支持的值: +ONLY_NEW - 如果订单状态为 NEW,撤销将成功。 +ONLY_PARTIALLY_FILLED - 如果订单状态为 PARTIALLY_FILLED,撤销将成功。 +recvWindow DECIMAL NO 最大值为 60000 毫秒。 +支持最多三位小数的精度(例如 6000.346),以便可以指定微秒。 +timestamp LONG YES +注意: + +orderId 与 origClientOrderId 必须至少发送一个。 +当同时提供 orderId 和 origClientOrderId 两个参数时,系统首先将会使用 orderId 来搜索订单。然后, 查找结果中的 origClientOrderId 的值将会被用来验证订单。如果两个条件都不满足,则请求将被拒绝。 +数据源: 撮合引擎 + +响应: + +{ + "symbol": "LTCBTC", + "orderId": 28, + "orderListId": -1, // 除非此单是订单列表的一部分, 否则此值为 -1 + "origClientOrderId": "myOrder1", + "clientOrderId": "cancelMyOrder1", + "transactTime": 1507725176595, + "price": "1.00000000", + "origQty": "10.00000000", + "executedQty": "8.00000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "8.00000000", + "status": "CANCELED", + "timeInForce": "GTC", + "type": "LIMIT", + "side": "SELL", + "selfTradePreventionMode": "NONE" +} + +注意: 上面的 payload 没有显示所有可以出现的字段,更多请看 订单响应中的特定条件时才会出现的字段 部分。 + +当仅发送 orderId 时,取消订单的执行(单个 Cancel 或作为 Cancel-Replace 的一部分)总是更快。发送 origClientOrderId 或同时发送 orderId + origClientOrderId 会稍慢。 + +关于 cancelRestrictions + +如果 cancelRestrictions 值不是任何受支持的值,则错误将是: +{ + "code": -1145, + "msg": "Invalid cancelRestrictions" +} + +如果订单没有通过 cancelRestrictions 的条件,错误将是: +{ + "code": -2011, + "msg": "Order was not canceled due to cancel restrictions." +} + +撤销单一交易对的所有挂单 (TRADE) +DELETE /api/v3/openOrders + +撤销单一交易对下所有挂单。这也包括了来自订单列表的挂单。 + +权重: 1 + +参数: + +名称 类型 是否必需 描述 +symbol STRING YES +recvWindow DECIMAL NO 最大值为 60000 毫秒。 +支持最多三位小数的精度(例如 6000.346),以便可以指定微秒。 +timestamp LONG YES +数据源: 撮合引擎 + +响应: + +[ + { + "symbol": "BTCUSDT", + "origClientOrderId": "E6APeyTJvkMvLMYMqu1KQ4", + "orderId": 11, + "orderListId": -1, + "clientOrderId": "pXLV6Hz6mprAcVYpVMTGgx", + "transactTime": 1684804350068, + "price": "0.089853", + "origQty": "0.178622", + "executedQty": "0.000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.000000", + "status": "CANCELED", + "timeInForce": "GTC", + "type": "LIMIT", + "side": "BUY", + "selfTradePreventionMode": "NONE" + }, + { + "symbol": "BTCUSDT", + "origClientOrderId": "A3EF2HCwxgZPFMrfwbgrhv", + "orderId": 13, + "orderListId": -1, + "clientOrderId": "pXLV6Hz6mprAcVYpVMTGgx", + "transactTime": 1684804350068, + "price": "0.090430", + "origQty": "0.178622", + "executedQty": "0.000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.000000", + "status": "CANCELED", + "timeInForce": "GTC", + "type": "LIMIT", + "side": "BUY", + "selfTradePreventionMode": "NONE" + }, + { + "orderListId": 1929, + "contingencyType": "OCO", + "listStatusType": "ALL_DONE", + "listOrderStatus": "ALL_DONE", + "listClientOrderId": "2inzWQdDvZLHbbAmAozX2N", + "transactionTime": 1585230948299, + "symbol": "BTCUSDT", + "orders": [ + { + "symbol": "BTCUSDT", + "orderId": 20, + "clientOrderId": "CwOOIPHSmYywx6jZX77TdL" + }, + { + "symbol": "BTCUSDT", + "orderId": 21, + "clientOrderId": "461cPg51vQjV3zIMOXNz39" + } + ], + "orderReports": [ + { + "symbol": "BTCUSDT", + "origClientOrderId": "CwOOIPHSmYywx6jZX77TdL", + "orderId": 20, + "orderListId": 1929, + "clientOrderId": "pXLV6Hz6mprAcVYpVMTGgx", + "transactTime": 1684804350068, + "price": "0.668611", + "origQty": "0.690354", + "executedQty": "0.000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.000000", + "status": "CANCELED", + "timeInForce": "GTC", + "type": "STOP_LOSS_LIMIT", + "side": "BUY", + "stopPrice": "0.378131", + "icebergQty": "0.017083", + "selfTradePreventionMode": "NONE" + }, + { + "symbol": "BTCUSDT", + "origClientOrderId": "461cPg51vQjV3zIMOXNz39", + "orderId": 21, + "orderListId": 1929, + "clientOrderId": "pXLV6Hz6mprAcVYpVMTGgx", + "transactTime": 1684804350068, + "price": "0.008791", + "origQty": "0.690354", + "executedQty": "0.000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.000000", + "status": "CANCELED", + "timeInForce": "GTC", + "type": "LIMIT_MAKER", + "side": "BUY", + "icebergQty": "0.639962", + "selfTradePreventionMode": "NONE" + } + ] + } +] + +撤消挂单再下单 (TRADE) +POST /api/v3/order/cancelReplace + +撤消挂单并在同个交易对上重新下单。 + +在撤消订单和下单前会判断: 1) 过滤器参数, 以及 2) 目前下单数量。 + +即使请求中没有尝试发送新订单,比如(newOrderResult: NOT_ATTEMPTED),未成交订单的数量仍然会加1。 + +权重: 1 + +未成交的订单计数: 1 + +参数: + +名称 类型 是否必需 描述 +symbol STRING YES +side ENUM YES +type ENUM YES +cancelReplaceMode ENUM YES 指定类型:STOP_ON_FAILURE - 如果撤消订单失败将不会继续重新下单。 +ALLOW_FAILURE - 不管撤消订单是否成功都会继续重新下单。 +timeInForce ENUM NO +quantity DECIMAL NO +quoteOrderQty DECIMAL NO +price DECIMAL NO +cancelNewClientOrderId STRING NO 用户自定义的id,如空缺系统会自动赋值 +cancelOrigClientOrderId STRING NO 必须提供 cancelOrderId 或者 cancelOrigClientOrderId。 + +当同时提供 cancelOrderId 和 cancelOrigClientOrderId 两个参数时,系统首先将会使用 cancelOrderId 来搜索订单。 + +然后, 查找结果中的 cancelOrigClientOrderId 的值将会被用来验证订单。 + +如果两个条件都不满足,则请求将被拒绝。 +cancelOrderId LONG NO 必须提供 cancelOrderId 或者 cancelOrigClientOrderId。 + +当同时提供 cancelOrderId 和 cancelOrigClientOrderId 两个参数时,系统首先将会使用 cancelOrderId 来搜索订单。 + +然后, 查找结果中的 cancelOrigClientOrderId 的值将会被用来验证订单。 + +如果两个条件都不满足,则请求将被拒绝。 +newClientOrderId STRING NO 用于辨识新订单。 +strategyId LONG NO +strategyType INT NO 不能低于 1000000。 +stopPrice DECIMAL NO +trailingDelta LONG NO 参考 追踪止盈止损(Trailing Stop)订单常见问题 +icebergQty DECIMAL NO +newOrderRespType ENUM NO 指定响应类型: +指定响应类型 ACK, RESULT, or FULL; MARKET 与 LIMIT 订单默认为FULL, 其他默认为ACK。 +selfTradePreventionMode ENUM NO 允许的 ENUM 取决于交易对的配置。支持的值有:STP 模式。 +cancelRestrictions ENUM NO 支持的值: +ONLY_NEW - 如果订单状态为 NEW,撤销将成功。 +ONLY_PARTIALLY_FILLED - 如果订单状态为 PARTIALLY_FILLED,撤销将成功。 +orderRateLimitExceededMode ENUM NO 支持的值: + +DO_NOTHING(默认值)- 仅在账户未超过未成交订单频率限制时,会尝试取消订单。 + +CANCEL_ONLY - 将始终取消订单。 +pegPriceType ENUM NO PRIMARY_PEG 或 MARKET_PEG。 +参阅 关于挂钩订单参数的注意事项 +pegOffsetValue INT NO 用于挂钩的价格水平(最大值:100)。 +参阅 关于挂钩订单参数的注意事项 +pegOffsetType ENUM NO 仅支持 PRICE_LEVEL。 +参阅 关于挂钩订单参数的注意事项 +recvWindow DECIMAL NO 最大值为 60000 毫秒。 +支持最多三位小数的精度(例如 6000.346),以便可以指定微秒。 +timestamp LONG YES +如同 POST /api/v3/order,额外的强制参数取决于 type 。 + +响应格式根据消息的处理是成功、部分成功还是失败而有所不同。 + +数据来源: 撮合引擎 + +请求 响应 +cancelReplaceMode orderRateLimitExceededMode 未成交订单数 cancelResult newOrderResult status +STOP_ON_FAILURE DO_NOTHING 在限制范围内 ✅ SUCCESS ✅ SUCCESS 200 +❌ FAILURE ➖ NOT_ATTEMPTED 400 +✅ SUCCESS ❌ FAILURE 409 +超出限制范围 ✅ SUCCESS ✅ SUCCESS N/A +❌ FAILURE ➖ NOT_ATTEMPTED N/A +✅ SUCCESS ❌ FAILURE N/A +CANCEL_ONLY 在限制范围内 ✅ SUCCESS ✅ SUCCESS 200 +❌ FAILURE ➖ NOT_ATTEMPTED 400 +✅ SUCCESS ❌ FAILURE 409 +超出限制范围 ❌ FAILURE ➖ NOT_ATTEMPTED 429 +✅ SUCCESS ❌ FAILURE 429 +ALLOW_FAILURE DO_NOTHING 在限制范围内 ✅ SUCCESS ✅ SUCCESS 200 +❌ FAILURE ❌ FAILURE 400 +❌ FAILURE ✅ SUCCESS 409 +✅ SUCCESS ❌ FAILURE 409 +超出限制范围 ✅ SUCCESS ✅ SUCCESS N/A +❌ FAILURE ❌ FAILURE N/A +❌ FAILURE ✅ SUCCESS N/A +✅ SUCCESS ❌ FAILURE N/A +CANCEL_ONLY 在限制范围内 ✅ SUCCESS ✅ SUCCESS 200 +❌ FAILURE ❌ FAILURE 400 +❌ FAILURE ✅ SUCCESS 409 +✅ SUCCESS ❌ FAILURE 409 +超出限制范围 ✅ SUCCESS ✅ SUCCESS N/A +❌ FAILURE ❌ FAILURE 400 +❌ FAILURE ✅ SUCCESS N/A +✅ SUCCESS ❌ FAILURE 409 +响应:账户没有超出未成交订单计数时的 Response SUCCESS + +// 撤单和下单都成功 +{ + "cancelResult": "SUCCESS", + "newOrderResult": "SUCCESS", + "cancelResponse": { + "symbol": "BTCUSDT", + "origClientOrderId": "DnLo3vTAQcjha43lAZhZ0y", + "orderId": 9, + "orderListId": -1, + "clientOrderId": "osxN3JXAtJvKvCqGeMWMVR", + "transactTime": 1684804350068, + "price": "0.01000000", + "origQty": "0.000100", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.00000000", + "status": "CANCELED", + "timeInForce": "GTC", + "type": "LIMIT", + "side": "SELL" + }, + "newOrderResponse": { + "symbol": "BTCUSDT", + "orderId": 10, + "orderListId": -1, + "clientOrderId": "wOceeeOzNORyLiQfw7jd8S", + "transactTime": 1652928801803, + "price": "0.02000000", + "origQty": "0.040000", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.00000000", + "status": "NEW", + "timeInForce": "GTC", + "type": "LIMIT", + "side": "BUY", + "fills": [] + } +} + +响应:选择了 STOP_ON_FAILURE 而且账户没有超出未成交订单计数时, 撤单出现错误 + +{ + "code": -2022, + "msg": "Order cancel-replace failed.", + "data": { + "cancelResult": "FAILURE", + "newOrderResult": "NOT_ATTEMPTED", + "cancelResponse": { + "code": -2011, + "msg": "Unknown order sent." + }, + "newOrderResponse": null + } +} + +响应:撤单成功而且账户没有超出未成交订单计数时,下单失败 + +{ + "code": -2021, + "msg": "Order cancel-replace partially failed.", + "data": { + "cancelResult": "SUCCESS", + "newOrderResult": "FAILURE", + "cancelResponse": { + "symbol": "BTCUSDT", + "origClientOrderId": "86M8erehfExV8z2RC8Zo8k", + "orderId": 3, + "orderListId": -1, + "clientOrderId": "G1kLo6aDv2KGNTFcjfTSFq", + "transactTime": 1684804350068, + "price": "0.006123", + "origQty": "10000.000000", + "executedQty": "0.000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.000000", + "status": "CANCELED", + "timeInForce": "GTC", + "type": "LIMIT_MAKER", + "side": "SELL" + }, + "newOrderResponse": { + "code": -2010, + "msg": "Order would immediately match and take." + } + } +} + +响应:选择 ALLOW_FAILURE 而且账户没有超出未成交订单计数时, 撤单出现错误 + +{ + "code": -2021, + "msg": "Order cancel-replace partially failed.", + "data": { + "cancelResult": "FAILURE", + "newOrderResult": "SUCCESS", + "cancelResponse": { + "code": -2011, + "msg": "Unknown order sent." + }, + "newOrderResponse": { + "symbol": "BTCUSDT", + "orderId": 11, + "orderListId": -1, + "clientOrderId": "pfojJMg6IMNDKuJqDxvoxN", + "transactTime": 1648540168818 + } + } +} + +响应:选择 cancelReplaceMode=ALLOW_FAILURE 而且账户没有超出未成交订单计数时, 撤单和下单失败 + +{ + "code": -2022, + "msg": "Order cancel-replace failed.", + "data": { + "cancelResult": "FAILURE", + "newOrderResult": "FAILURE", + "cancelResponse": { + "code": -2011, + "msg": "Unknown order sent." + }, + "newOrderResponse": { + "code": -2010, + "msg": "Order would immediately match and take." + } + } +} + +响应:选择 orderRateLimitExceededMode=DO_NOTHING 而且账户超出未成交订单计数时 + +{ + "code": -1015, + "msg": "Too many new orders; current limit is 1 orders per 10 SECOND." +} + +响应:选择 orderRateLimitExceededMode=CANCEL_ONLY 而且账户超出未成交订单计数时 + +{ + "code": -2021, + "msg": "Order cancel-replace partially failed.", + "data": { + "cancelResult": "SUCCESS", + "newOrderResult": "FAILURE", + "cancelResponse": { + "symbol": "LTCBNB", + "origClientOrderId": "GKt5zzfOxRDSQLveDYCTkc", + "orderId": 64, + "orderListId": -1, + "clientOrderId": "loehOJF3FjoreUBDmv739R", + "transactTime": 1715779007228, + "price": "1.00", + "origQty": "10.00000000", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.00", + "status": "CANCELED", + "timeInForce": "GTC", + "type": "LIMIT", + "side": "SELL", + "selfTradePreventionMode": "NONE" + }, + "newOrderResponse": { + "code": -1015, + "msg": "Too many new orders; current limit is 1 orders per 10 SECOND." + } + } +} + +注意: + +上面的 payload 没有显示所有可以出现的字段,更多请看 订单响应中的特定条件时才会出现的字段 部分。 +当仅发送 orderId 时,取消订单的执行(单个 Cancel 或作为 Cancel-Replace 的一部分)总是更快。发送 origClientOrderId 或同时发送 orderId + origClientOrderId 会稍慢。 +修改订单并保留优先级 (TRADE) +PUT /api/v3/order/amend/keepPriority + +由客户发送以减少其现有当前订单的原始数量。 + +这个请求将添加0个订单到 EXCHANGE_MAX_ORDERS 过滤器和 MAX_NUM_ORDERS 过滤器中。 + +请阅读 保留优先权的修改订单常见问题 了解更多信息。 + +权重: 4 + +未成交的订单计数: 0 + +参数: + +名称 类型 是否必需 描述 +symbol STRING YES +orderId LONG NO* 需提供 orderId 或 origClientOrderId。 +origClientOrderId STRING NO* 需提供 orderId 或 origClientOrderId。 +newClientOrderId STRING NO* 订单在被修改后被赋予的新 client order ID。 +如果未发送则自动生成。 +可以将当前 clientOrderId 作为 newClientOrderId 发送来重用当前 clientOrderId 的值。 +newQty DECIMAL YES 交易的新数量。 newQty 必须大于0, 但是必须比订单的原始数量小。 +recvWindow DECIMAL NO 最大值为 60000 毫秒。 +支持最多三位小数的精度(例如 6000.346),以便可以指定微秒。 +timestamp LONG YES +数据源: 撮合引擎 + +来自单个订单的响应: + +{ + "transactTime": 1741926410255, + "executionId": 75, + "amendedOrder": { + "symbol": "BTCUSDT", + "orderId": 33, + "orderListId": -1, + "origClientOrderId": "5xrgbMyg6z36NzBn2pbT8H", + "clientOrderId": "PFaq6hIHxqFENGfdtn4J6Q", + "price": "6.00000000", + "qty": "5.00000000", + "executedQty": "0.00000000", + "preventedQty": "0.00000000", + "quoteOrderQty": "0.00000000", + "cumulativeQuoteQty": "0.00000000", + "status": "NEW", + "timeInForce": "GTC", + "type": "LIMIT", + "side": "SELL", + "workingTime": 1741926410242, + "selfTradePreventionMode": "NONE" + } +} + +来自订单列表中单个订单的响应: + +{ + "transactTime": 1741669661670, + "executionId": 22, + "amendedOrder": { + "symbol": "BTCUSDT", + "orderId": 9, + "orderListId": 1, + "origClientOrderId": "W0fJ9fiLKHOJutovPK3oJp", + "clientOrderId": "UQ1Np3bmQ71jJzsSDW9Vpi", + "price": "0.00000000", + "qty": "4.00000000", + "executedQty": "0.00000000", + "preventedQty": "0.00000000", + "quoteOrderQty": "0.00000000", + "cumulativeQuoteQty": "0.00000000", + "status": "PENDING_NEW", + "timeInForce": "GTC", + "type": "MARKET", + "side": "BUY", + "selfTradePreventionMode": "NONE" + }, + "listStatus": { + "orderListId": 1, + "contingencyType": "OTO", + "listOrderStatus": "EXECUTING", + "listClientOrderId": "AT7FTxZXylVSwRoZs52mt3", + "symbol": "BTCUSDT", + "orders": [ + { + "symbol": "BTCUSDT", + "orderId": 8, + "clientOrderId": "GkwwHZUUbFtZOoH1YsZk9Q" + }, + { + "symbol": "BTCUSDT", + "orderId": 9, + "clientOrderId": "UQ1Np3bmQ71jJzsSDW9Vpi" + } + ] + } +} + +注意: 上面的 payload 没有显示所有可以出现的字段,更多请看 订单响应中的特定条件时才会出现的字段 部分。 + +订单列表(Order lists) +发送新 OCO 订单 - 已弃用 (TRADE) +POST /api/v3/order/oco + +权重: 1 + +未成交的订单计数: 2 + +发送新的 OCO。 + +价格限制: +SELL: Limit price > 最后交易价格 > stop Price +BUY: Limit price < 最后交易价格 < stop Price +数量限制: +两条腿的数量必须相同。 +不过, 冰山 交易的数量不一定相同 +OCO 将2个订单添加到 EXCHANGE_MAX_ORDERS 过滤器和 MAX_NUM_ORDERS 过滤器中。 +参数: + +名称 类型 是否必需 描述 +symbol STRING YES +listClientOrderId STRING NO 整个orderList的唯一ID +side ENUM YES 详见枚举定义:订单方向 +quantity DECIMAL YES +limitClientOrderId STRING NO 限价单的唯一ID +price DECIMAL YES +limitStrategyId LONG NO +limitStrategyType INT NO 不能低于 1000000 +limitIcebergQty DECIMAL NO +trailingDelta LONG NO +stopClientOrderId STRING NO 止损/止损限价单的唯一ID +stopPrice DECIMAL YES +stopStrategyId LONG NO +stopStrategyType INT NO 不能低于 1000000 +stopLimitPrice DECIMAL NO 如果提供,须配合提交stopLimitTimeInForce +stopIcebergQty DECIMAL NO +stopLimitTimeInForce ENUM NO 有效值 GTC/FOK/IOC +newOrderRespType ENUM NO 详见枚举定义:订单返回类型 +selfTradePreventionMode ENUM NO 允许的 ENUM 取决于交易对的配置。支持的值有:STP 模式。 +recvWindow DECIMAL NO 最大值为 60000 毫秒。 +支持最多三位小数的精度(例如 6000.346),以便可以指定微秒。 +timestamp LONG YES +数据源: 撮合引擎 + +响应 + +{ + "orderListId": 0, + "contingencyType": "OCO", + "listStatusType": "EXEC_STARTED", + "listOrderStatus": "EXECUTING", + "listClientOrderId": "JYVpp3F0f5CAG15DhtrqLp", + "transactionTime": 1563417480525, + "symbol": "LTCBTC", + "orders": [ + { + "symbol": "LTCBTC", + "orderId": 2, + "clientOrderId": "Kk7sqHb9J6mJWTMDVW7Vos" + }, + { + "symbol": "LTCBTC", + "orderId": 3, + "clientOrderId": "xTXKaGYd4bluPVp78IVRvl" + } + ], + "orderReports": [ + { + "symbol": "LTCBTC", + "orderId": 2, + "orderListId": 0, + "clientOrderId": "Kk7sqHb9J6mJWTMDVW7Vos", + "transactTime": 1563417480525, + "price": "0.000000", + "origQty": "0.624363", + "executedQty": "0.000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.000000", + "status": "NEW", + "timeInForce": "GTC", + "type": "STOP_LOSS", + "side": "BUY", + "stopPrice": "0.960664", + "workingTime": -1, + "selfTradePreventionMode": "NONE" + }, + { + "symbol": "LTCBTC", + "orderId": 3, + "orderListId": 0, + "clientOrderId": "xTXKaGYd4bluPVp78IVRvl", + "transactTime": 1563417480525, + "price": "0.036435", + "origQty": "0.624363", + "executedQty": "0.000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.000000", + "status": "NEW", + "timeInForce": "GTC", + "type": "LIMIT_MAKER", + "side": "BUY", + "workingTime": 1563417480525, + "selfTradePreventionMode": "NONE" + } + ] +} + +New Order list - OCO (TRADE) +POST /api/v3/orderList/oco + +发送新 one-cancels-the-other (OCO) 订单,激活其中一个订单会立即取消另一个订单。 + +OCO 包含了两个订单,分别被称为 上方订单 和 下方订单。 +其中一个订单必须是 LIMIT_MAKER/TAKE_PROFIT/TAKE_PROFIT_LIMIT 订单,另一个订单必须是 STOP_LOSS 或 STOP_LOSS_LIMIT 订单。 +针对价格限制: +如果 OCO 订单方向是 SELL: +LIMIT_MAKER/TAKE_PROFIT_LIMIT price > 最后交易价格 > STOP_LOSS/STOP_LOSS_LIMIT stopPrice +TAKE_PROFIT stopPrice > 最后交易价格 > STOP_LOSS/STOP_LOSS_LIMIT stopPrice +如果 OCO 订单方向是 BUY: +LIMIT_MAKER/TAKE_PROFIT_LIMIT price < 最后交易价格 < stopPrice +TAKE_PROFIT stopPrice < 最后交易价格 < STOP_LOSS/STOP_LOSS_LIMIT stopPrice +OCO 会添加 2个订单 到 EXCHANGE_MAX_ORDERS 过滤器和 MAX_NUM_ORDERS 过滤器中。 +权重: 1 + +未成交的订单计数: 2 + +参数: + +名称 类型 是否必需 描述 +symbol STRING Yes +listClientOrderId STRING No 整个 OCO order list 的唯一ID。 如果未发送则自动生成。 +仅当前一个订单已填满或完全过期时,才会接受具有相同的listClientOrderId。 +listClientOrderId 与 aboveClientOrderId 和 belowCLientOrderId 不同。 +side ENUM Yes 订单方向:BUY or SELL +quantity DECIMAL Yes 两个订单的数量。 +aboveType ENUM Yes 支持值:STOP_LOSS_LIMIT, STOP_LOSS, LIMIT_MAKER, TAKE_PROFIT, TAKE_PROFIT_LIMIT。 +aboveClientOrderId STRING No 上方订单的唯一ID。 如果未发送则自动生成。 +aboveIcebergQty LONG No 请注意,只有当 aboveTimeInForce 为 GTC 时才能使用。 +abovePrice DECIMAL No 当 aboveType 是 STOP_LOSS_LIMIT, LIMIT_MAKER 或 TAKE_PROFIT_LIMIT 时,可用以指定限价。 +aboveStopPrice DECIMAL No 如果 aboveType 是 STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT 或 TAKE_PROFIT_LIMIT 才能使用。 +必须指定 aboveStopPrice 或 aboveTrailingDelta 或两者。 +aboveTrailingDelta LONG No 请看 追踪止盈止损(Trailing Stop)订单常见问题。 +aboveTimeInForce ENUM No 如果 aboveType 是 STOP_LOSS_LIMIT 或 TAKE_PROFIT_LIMIT,则为必填项。 +aboveStrategyId LONG No 订单策略中上方订单的 ID。 +aboveStrategyType INT No 上方订单策略的任意数值。 +小于 1000000 的值被保留,无法使用。 +abovePegPriceType ENUM NO 参阅 关于挂钩订单参数的注意事项 +abovePegOffsetType ENUM NO +abovePegOffsetValue INT NO +belowType ENUM Yes 支持值:STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT,TAKE_PROFIT_LIMIT。 +belowClientOrderId STRING No +belowIcebergQty LONG No 请注意,只有当 belowTimeInForce 为 GTC 时才能使用。 +belowPrice DECIMAL No 当 belowType 是 STOP_LOSS_LIMIT, LIMIT_MAKER 或 TAKE_PROFIT_LIMIT 时,可用以指定限价。 +belowStopPrice DECIMAL No 如果 belowType 是 STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT 或 TAKE_PROFIT_LIMIT 才能使用。 +必须指定 belowStopPrice 或 belowTrailingDelta 或两者。 +belowTrailingDelta LONG No 请看 追踪止盈止损(Trailing Stop)订单常见问题。 +belowTimeInForce ENUM No 如果belowType 是 STOP_LOSS_LIMIT 或 TAKE_PROFIT_LIMIT,则为必须配合提交的值。 +belowStrategyId LONG No 订单策略中下方订单的 ID。 +belowStrategyType INT No 下方订单策略的任意数值。 +小于 1000000 的值被保留,无法使用。 +belowPegPriceType ENUM NO 参阅 关于挂钩订单参数的注意事项 +belowPegOffsetType ENUM NO +belowPegOffsetValue INT NO +newOrderRespType ENUM No 响应格式可选值: ACK, RESULT, FULL。 +selfTradePreventionMode ENUM No 允许的 ENUM 取决于交易对上的配置。 支持值:STP 模式。 +recvWindow DECIMAL NO 最大值为 60000 毫秒。 +支持最多三位小数的精度(例如 6000.346),以便可以指定微秒。 +timestamp LONG Yes +数据源: 撮合引擎 + +响应: + +使用 newOrderRespType 参数来选择 orderReports 的响应格式。以下示例适用于 RESULT 响应类型。 请参阅 POST /api/v3/order了解更多 orderReports 的响应类型。 + +{ + "orderListId": 1, + "contingencyType": "OCO", + "listStatusType": "EXEC_STARTED", + "listOrderStatus": "EXECUTING", + "listClientOrderId": "lH1YDkuQKWiXVXHPSKYEIp", + "transactionTime": 1710485608839, + "symbol": "LTCBTC", + "orders": [ + { + "symbol": "LTCBTC", + "orderId": 10, + "clientOrderId": "44nZvqpemY7sVYgPYbvPih" + }, + { + "symbol": "LTCBTC", + "orderId": 11, + "clientOrderId": "NuMp0nVYnciDiFmVqfpBqK" + } + ], + "orderReports": [ + { + "symbol": "LTCBTC", + "orderId": 10, + "orderListId": 1, + "clientOrderId": "44nZvqpemY7sVYgPYbvPih", + "transactTime": 1710485608839, + "price": "1.00000000", + "origQty": "5.00000000", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.00000000", + "status": "NEW", + "timeInForce": "GTC", + "type": "STOP_LOSS_LIMIT", + "side": "SELL", + "stopPrice": "1.00000000", + "workingTime": -1, + "icebergQty": "1.00000000", + "selfTradePreventionMode": "NONE" + }, + { + "symbol": "LTCBTC", + "orderId": 11, + "orderListId": 1, + "clientOrderId": "NuMp0nVYnciDiFmVqfpBqK", + "transactTime": 1710485608839, + "price": "3.00000000", + "origQty": "5.00000000", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.00000000", + "status": "NEW", + "timeInForce": "GTC", + "type": "LIMIT_MAKER", + "side": "SELL", + "workingTime": 1710485608839, + "selfTradePreventionMode": "NONE" + } + ] +} + + +New Order List - OTO (TRADE) +POST /api/v3/orderList/oto + +发送一个新的 OTO 订单。 + +一个 OTO 订单(One-Triggers-the-Other)是一个包含了两个订单的订单列表. +第一个订单被称为生效订单,必须为 LIMIT 或 LIMIT_MAKER 类型的订单。最初,订单簿上只有生效订单。 +第二个订单被称为待处理订单。它可以是任何订单类型,但不包括使用参数 quoteOrderQty 的 MARKET 订单。只有当生效订单完全成交时,待处理订单才会被自动下单。 +如果生效订单或者待处理订单中的任意一个被单独取消,订单列表中剩余的那个订单也会被随之取消或过期。 +如果生效订单在下订单列表后立即完全成交,则可能会得到订单响应。其中,生效订单的状态为 FILLED ,但待处理订单的状态为 PENDING_NEW。针对这类情况,如果需要检查当前状态,您可以查询相关的待处理订单。 +OTO 订单将2 个订单添加到 EXCHANGE_MAX_NUM_ORDERS 过滤器和 MAX_NUM_ORDERS 过滤器中。 +权重: 1 + +未成交的订单计数: 2 + +参数: + +名称 类型 是否必需 描述 +symbol STRING YES +listClientOrderId STRING NO 整个订单列表的唯一ID。 如果未发送则自动生成。 +仅当前一个订单列表已填满或完全过期时,才会接受含有相同 listClientOrderId 值的新订单列表。 +listClientOrderId 与 workingClientOrderId 和 pendingClientOrderId 不同。 +newOrderRespType ENUM NO 用于设置JSON响应的格式。 支持的数值: 订单返回类型 +selfTradePreventionMode ENUM NO 允许的数值取决于交易对上的配置。参考 STP 模式 +workingType ENUM YES 支持的数值: LIMIT, LIMIT_MAKER +workingSide ENUM YES 支持的数值: 订单方向 +workingClientOrderId STRING NO 用于标识生效订单的唯一ID。 +如果未发送则自动生成。 +workingPrice DECIMAL YES +workingQuantity DECIMAL YES 用于设置生效订单的数量。 +workingIcebergQty DECIMAL NO 仅当 workingTimeInForce 为 GTC 或 workingType 为 LIMIT_MAKER 时,才能使用此功能。 +workingTimeInForce ENUM NO 支持的数值: 生效时间 +workingStrategyId LONG NO 订单策略中用于标识生效订单的 ID。 +workingStrategyType INT NO 用于标识生效订单策略的任意数值。 +小于 1000000 的值被保留,无法使用。 +pendingType ENUM YES 支持的数值: 订单类型 +请注意,系统不支持使用 quoteOrderQty 的 MARKET 订单。 +workingPegPriceType ENUM NO 参阅 关于挂钩订单参数的注意事项 +workingPegOffsetType ENUM NO +workingPegOffsetValue INT NO +pendingSide ENUM YES 支持的数值: 订单方向 +pendingClientOrderId STRING NO 用于标识待处理订单的唯一ID。 +如果未发送则自动生成。 +pendingPrice DECIMAL NO +pendingStopPrice DECIMAL NO +pendingTrailingDelta DECIMAL NO +pendingQuantity DECIMAL YES 用于设置待处理订单的数量。 +pendingIcebergQty DECIMAL NO 只有当 pendingTimeInForce 为 GTC 或者当 pendingType 为 LIMIT_MAKER 时才能使用。 +pendingTimeInForce ENUM NO 支持的数值: 生效时间 +pendingStrategyId LONG NO 订单策略中用于标识待处理订单的 ID。 +pendingStrategyType INT NO 用于标识待处理订单策略的任意数值。 +小于 1000000 的值被保留,无法使用。 +pendingPegPriceType ENUM NO 参阅 关于挂钩订单参数的注意事项 +pendingPegOffsetType ENUM NO +pendingPegOffsetValue INT NO +recvWindow DECIMAL NO 最大值为 60000 毫秒。 +支持最多三位小数的精度(例如 6000.346),以便可以指定微秒。 +timestamp LONG YES + +根据 pendingType 或者 workingType 的不同值,对于某些参数的强制要求 + +根据 pendingType 或者workingType的不同值,对于某些可选参数有强制要求,具体如下: + +类型 强制要求的参数 其他信息 +workingType = LIMIT workingTimeInForce +pendingType = LIMIT pendingPrice, pendingTimeInForce +pendingType = STOP_LOSS 或 TAKE_PROFIT pendingStopPrice 与/或 pendingTrailingDelta +pendingType = STOP_LOSS_LIMIT 或 TAKE_PROFIT_LIMIT pendingPrice, pendingStopPrice 与/或 pendingTrailingDelta, pendingTimeInForce +数据源: 撮合引擎 + +响应: + +{ + "orderListId": 0, + "contingencyType": "OTO", + "listStatusType": "EXEC_STARTED", + "listOrderStatus": "EXECUTING", + "listClientOrderId": "yl2ERtcar1o25zcWtqVBTC", + "transactionTime": 1712289389158, + "symbol": "LTCBTC", + "orders": [ + { + "symbol": "LTCBTC", + "orderId": 4, + "clientOrderId": "Bq17mn9fP6vyCn75Jw1xya" + }, + { + "symbol": "LTCBTC", + "orderId": 5, + "clientOrderId": "arLFo0zGJVDE69cvGBaU0d" + } + ], + "orderReports": [ + { + "symbol": "LTCBTC", + "orderId": 4, + "orderListId": 0, + "clientOrderId": "Bq17mn9fP6vyCn75Jw1xya", + "transactTime": 1712289389158, + "price": "1.00000000", + "origQty": "1.00000000", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.00000000", + "status": "NEW", + "timeInForce": "GTC", + "type": "LIMIT", + "side": "SELL", + "workingTime": 1712289389158, + "selfTradePreventionMode": "NONE" + }, + { + "symbol": "LTCBTC", + "orderId": 5, + "orderListId": 0, + "clientOrderId": "arLFo0zGJVDE69cvGBaU0d", + "transactTime": 1712289389158, + "price": "0.00000000", + "origQty": "5.00000000", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.00000000", + "status": "PENDING_NEW", + "timeInForce": "GTC", + "type": "MARKET", + "side": "BUY", + "workingTime": -1, + "selfTradePreventionMode": "NONE" + } + ] +} + +注意: 上面的 payload 没有显示所有可以出现的字段,更多请看 订单响应中的特定条件时才会出现的字段 部分。 + + +New Order List - OTOCO (TRADE) +POST /api/v3/orderList/otoco + +发送一个新的 OTOCO 订单。 + +一个 OTOCO 订单(One-Triggers-One-Cancels-the-Other)是一个包含了三个订单的订单列表。 +第一个订单被称为生效订单,必须为 LIMIT 或 LIMIT_MAKER 类型的订单。最初,订单簿上只有生效订单。 +生效订单的行为与此一致 OTO +一个OTOCO订单有两个待处理订单(pending above 和 pending below),它们构成了一个 OCO 订单列表。只有当生效订单完全成交时,待处理订单们才会被自动下单。 +待处理上方(pending above)订单和待处理下方(pending below)订单都遵循与 OCO 订单列表相同的规则 Order List OCO。 +OTOCO 在 EXCHANGE_MAX_NUM_ORDERS 过滤器和 MAX_NUM_ORDERS 过滤器的基础上添加3个订单。 +权重: 1 + +未成交的订单计数: 3 + +参数: + +名称 类型 是否必需 描述 +symbol STRING YES +listClientOrderId STRING NO 整个订单列表的唯一ID。 如果未发送则自动生成。 +仅当前一个订单列表已填满或完全过期时,才会接受含有相同 listClientOrderId 值的新订单列表。 +listClientOrderId 与 workingClientOrderId, pendingAboveClientOrderId 以及 pendingBelowClientOrderId 不同。 +newOrderRespType ENUM NO 用于设置JSON响应的格式。 支持的数值: 订单返回类型 +selfTradePreventionMode ENUM NO 允许的数值取决于交易对上的配置。参考 STP 模式 +workingType ENUM YES 支持的数值: LIMIT, LIMIT_MAKER +workingSide ENUM YES 支持的数值: 订单方向 +workingClientOrderId STRING NO 用于标识生效订单的唯一ID。 +如果未发送则自动生成。 +workingPrice DECIMAL YES +workingQuantity DECIMAL YES +workingIcebergQty DECIMAL NO 仅当 workingTimeInForce 为 GTC 或 workingType 为 LIMIT_MAKER 时,才能使用此功能。 +workingTimeInForce ENUM NO 支持的数值: 生效时间 +workingStrategyId LONG NO 订单策略中用于标识生效订单的 ID。 +workingStrategyType INT NO 用于标识生效订单策略的任意数值。 +小于 1000000 的值被保留,无法使用。 +workingPegPriceType ENUM NO 参阅 关于挂钩订单参数的注意事项 +workingPegOffsetType ENUM NO +workingPegOffsetValue INT NO +pendingSide ENUM YES 支持的数值: 订单方向 +pendingQuantity DECIMAL YES +pendingAboveType ENUM YES 支持的数值: STOP_LOSS_LIMIT, STOP_LOSS, LIMIT_MAKER, TAKE_PROFIT, TAKE_PROFIT_LIMIT +pendingAboveClientOrderId STRING NO 用于标识待处理上方订单的唯一ID。 +如果未发送则自动生成。 +pendingAbovePrice DECIMAL NO 当 pendingAboveType 是 STOP_LOSS_LIMIT, LIMIT_MAKER 或 TAKE_PROFIT_LIMIT 时,可用以指定限价。 +pendingAboveStopPrice DECIMAL NO 如果 pendingAboveType 是 STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, TAKE_PROFIT_LIMIT 才能使用。 +pendingAboveTrailingDelta DECIMAL NO 参见 追踪止盈止损(Trailing Stop)订单常见问题 +pendingAboveIcebergQty DECIMAL NO 只有当 pendingAboveTimeInForce 为 GTC 时才能使用。 +pendingAboveTimeInForce ENUM NO +pendingAboveStrategyId LONG NO 订单策略中用于标识待处理上方订单的 ID。 +pendingAboveStrategyType INT NO 用于标识待处理上方订单策略的任意数值。 +小于 1000000 的值被保留,无法使用。 +pendingAbovePegPriceType ENUM NO 参阅 关于挂钩订单参数的注意事项 +pendingAbovePegOffsetType ENUM NO +pendingAbovePegOffsetValue INT NO +pendingBelowType ENUM NO 支持的数值: STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, TAKE_PROFIT_LIMIT +pendingBelowClientOrderId STRING NO 用于标识待处理下方订单的唯一ID。 +如果未发送则自动生成。 +pendingBelowPrice DECIMAL NO 当 pendingBelowType 是 STOP_LOSS_LIMIT 或 TAKE_PROFIT_LIMIT 时,可用以指定限价。 +pendingBelowStopPrice DECIMAL NO 如果 pendingBelowType 是 STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, TAKE_PROFIT_LIMIT 才能使用。 +必须指定 pendingBelowStopPrice 或 pendingBelowTrailingDelta 或两者。 +pendingBelowTrailingDelta DECIMAL NO +pendingBelowIcebergQty DECIMAL NO 只有当 pendingBelowTimeInForce 为 GTC 时才能使用。 +pendingBelowTimeInForce ENUM NO +pendingBelowStrategyId LONG NO 订单策略中用于标识待处理下方订单的 ID。 +pendingBelowStrategyType INT NO 用于标识待处理下方订单策略的任意数值。 +小于 1000000 的值被保留,无法使用。 +pendingBelowPegPriceType ENUM NO 参阅 关于挂钩订单参数的注意事项 +pendingBelowPegOffsetType ENUM NO +pendingBelowPegOffsetValue INT NO +recvWindow DECIMAL NO 最大值为 60000 毫秒。 +支持最多三位小数的精度(例如 6000.346),以便可以指定微秒。 +timestamp LONG YES + +根据 pendingAboveType, pendingBelowType 或者workingType的不同值,对于某些参数的强制要求 + +根据 pendingAboveType, pendingBelowType 或者workingType的不同值,对于某些可选参数有强制要求,具体如下: + +类型 强制要求的参数 其他信息 +workingType = LIMIT workingTimeInForce +pendingAboveType = LIMIT_MAKER pendingAbovePrice +pendingAboveType = STOP_LOSS/TAKE_PROFIT pendingAboveStopPrice 与/或 pendingAboveTrailingDelta +pendingAboveType = STOP_LOSS_LIMIT/TAKE_PROFIT_LIMIT pendingAbovePrice, pendingAboveStopPrice 与/或 pendingAboveTrailingDelta, pendingAboveTimeInForce +pendingBelowType = LIMIT_MAKER pendingBelowPrice +pendingBelowType = STOP_LOSS/TAKE_PROFIT pendingBelowStopPrice 与/或 pendingBelowTrailingDelta +pendingBelowType = STOP_LOSS_LIMIT/TAKE_PROFIT_LIMIT pendingBelowPrice, pendingBelowStopPrice 与/或 pendingBelowTrailingDelta, pendingBelowTimeInForce +数据源: 撮合引擎 + +响应: + +{ + "orderListId": 1, + "contingencyType": "OTO", + "listStatusType": "EXEC_STARTED", + "listOrderStatus": "EXECUTING", + "listClientOrderId": "RumwQpBaDctlUu5jyG5rs0", + "transactionTime": 1712291372842, + "symbol": "LTCBTC", + "orders": [ + { + "symbol": "LTCBTC", + "orderId": 6, + "clientOrderId": "fM9Y4m23IFJVCQmIrlUmMK" + }, + { + "symbol": "LTCBTC", + "orderId": 7, + "clientOrderId": "6pcQbFIzTXGZQ1e2MkGDq4" + }, + { + "symbol": "LTCBTC", + "orderId": 8, + "clientOrderId": "r4JMv9cwAYYUwwBZfbussx" + } + ], + "orderReports": [ + { + "symbol": "LTCBTC", + "orderId": 6, + "orderListId": 1, + "clientOrderId": "fM9Y4m23IFJVCQmIrlUmMK", + "transactTime": 1712291372842, + "price": "1.00000000", + "origQty": "1.00000000", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.00000000", + "status": "NEW", + "timeInForce": "GTC", + "type": "LIMIT", + "side": "SELL", + "workingTime": 1712291372842, + "selfTradePreventionMode": "NONE" + }, + { + "symbol": "LTCBTC", + "orderId": 7, + "orderListId": 1, + "clientOrderId": "6pcQbFIzTXGZQ1e2MkGDq4", + "transactTime": 1712291372842, + "price": "1.00000000", + "origQty": "5.00000000", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.00000000", + "status": "PENDING_NEW", + "timeInForce": "IOC", + "type": "STOP_LOSS_LIMIT", + "side": "BUY", + "stopPrice": "6.00000000", + "workingTime": -1, + "selfTradePreventionMode": "NONE" + }, + { + "symbol": "LTCBTC", + "orderId": 8, + "orderListId": 1, + "clientOrderId": "r4JMv9cwAYYUwwBZfbussx", + "transactTime": 1712291372842, + "price": "3.00000000", + "origQty": "5.00000000", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.00000000", + "status": "PENDING_NEW", + "timeInForce": "GTC", + "type": "LIMIT_MAKER", + "side": "BUY", + "workingTime": -1, + "selfTradePreventionMode": "NONE" + } + ] +} + +注意: 上面的 payload 没有显示所有可以出现的字段,更多请看 订单响应中的特定条件时才会出现的字段 部分。 + +New Order List - OPO(TRADE) +POST /api/v3/orderList/opo + +发送一个新的 OPO 订单。 + +OPO 会向 EXCHANGE_MAX_NUM_ORDERS 过滤器和 MAX_NUM_ORDERS 过滤器中添加 2 个订单。 +权重: 1 + +未成交订单计数: 2 + +参数: + +名称 类型 必填 描述 +symbol STRING YES +listClientOrderId STRING NO 订单列表中的唯一 ID。如果未发送,则自动生成。只有当之前的同一 listClientOrderId 的订单列表已成交或完全过期后,才接受新的同一 listClientOrderId 的订单列表。listClientOrderId 与 workingClientOrderId 和 pendingClientOrderId 不同。 +newOrderRespType ENUM NO JSON 响应格式。支持的数值:订单返回类型 +selfTradePreventionMode ENUM NO 允许的数值取决于交易对的配置。支持的数值:STP模式 +workingType ENUM YES 支持的数值:LIMIT,LIMIT_MAKER +workingSide ENUM YES 支持的数值:订单方向 +workingClientOrderId STRING NO 生效订单中挂单的任意唯一 ID。如果未发送,则自动生成。 +workingPrice DECIMAL YES 生效订单价格 +workingQuantity DECIMAL YES 设置生效订单的数量 +workingIcebergQty DECIMAL NO 仅当 workingTimeInForce 为 GTC 或 workingType 为 LIMIT_MAKER 时可用 +workingTimeInForce ENUM NO 支持的数值:生效时间 +workingStrategyId LONG NO 用于标识订单策略中生效订单的任意数字值 +workingStrategyType INT NO 用于标识生效订单策略的任意数字值。小于 1000000 的值为保留值,不能使用。 +workingPegPriceType ENUM NO 详见 挂钩订单 +workingPegOffsetType ENUM NO +workingPegOffsetValue INT NO +pendingType ENUM YES 支持的数值:订单类型。注意,不支持使用 quoteOrderQty 的 MARKET 订单。 +pendingSide ENUM YES 支持的数值:订单方向 +pendingClientOrderId STRING NO 待执行订单中挂单的任意唯一 ID。如果未发送,则自动生成。 +pendingPrice DECIMAL NO 待执行订单价格 +pendingStopPrice DECIMAL NO 待执行订单止损价格 +pendingTrailingDelta DECIMAL NO 待执行订单跟踪止损差值 +pendingIcebergQty DECIMAL NO 仅当 pendingTimeInForce 为 GTC 或 pendingType 为 LIMIT_MAKER 时可用 +pendingTimeInForce ENUM NO 支持的数值:生效时间 +pendingStrategyId LONG NO 用于标识订单策略中待执行订单的任意数字值 +pendingStrategyType INT NO 用于标识待执行订单策略的任意数字值。小于 1000000 的值为保留值,不能使用。 +pendingPegPriceType ENUM NO 详见 挂钩订单 +pendingPegOffsetType ENUM NO +pendingPegOffsetValue INT NO +recvWindow DECIMAL NO 该值不能大于 60000。支持最多三位小数精度(例如 6000.346),以便指定微秒。 +timestamp LONG YES 时间戳 +数据来源:撮合引擎 + +响应示例: + +{ + "orderListId": 0, + "contingencyType": "OTO", + "listStatusType": "EXEC_STARTED", + "listOrderStatus": "EXECUTING", + "listClientOrderId": "H94qCqO27P74OEiO4X8HOG", + "transactionTime": 1762998011671, + "symbol": "BTCUSDT", + "orders": [ + { + "symbol": "BTCUSDT", + "orderId": 2, + "clientOrderId": "JX6xfdjo0wysiGumfHNmPu" + }, + { + "symbol": "BTCUSDT", + "orderId": 3, + "clientOrderId": "2ZJCY0IjOhuYIMLGN8kU8S" + } + ], + "orderReports": [ + { + "symbol": "BTCUSDT", + "orderId": 2, + "orderListId": 0, + "clientOrderId": "JX6xfdjo0wysiGumfHNmPu", + "transactTime": 1762998011671, + "price": "102264.00000000", + "origQty": "0.00060000", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.00000000", + "cummulativeQuoteQty": "0.00000000", + "status": "NEW", + "timeInForce": "GTC", + "type": "LIMIT", + "side": "BUY", + "workingTime": 1762998011671, + "selfTradePreventionMode": "NONE" + }, + { + "symbol": "BTCUSDT", + "orderId": 3, + "orderListId": 0, + "clientOrderId": "2ZJCY0IjOhuYIMLGN8kU8S", + "transactTime": 1762998011671, + "price": "0.00000000", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.00000000", + "cummulativeQuoteQty": "0.00000000", + "status": "PENDING_NEW", + "timeInForce": "GTC", + "type": "MARKET", + "side": "SELL", + "workingTime": -1, + "selfTradePreventionMode": "NONE" + } + ] +} + +注意: 上面的 payload 没有显示所有可以出现的字段,更多请看 订单响应中的特定条件时才会出现的字段 部分。 + +New Order List - OPOCO (../TRADE) +POST /api/v3/orderList/opoco + +发送一个 OPOCO 订单。 + +权重: 1 + +未成交订单计数: 3 + +参数: + +名称 类型 必填 描述 +symbol STRING YES 交易对符号 +listClientOrderId STRING NO 订单列表中的任意唯一 ID。如果未发送,则自动生成。只有当之前的同一 listClientOrderId 的订单列表已成交或完全过期时,才接受新的同一 listClientOrderId 的订单列表。listClientOrderId 与 workingClientOrderId、pendingAboveClientOrderId 和 pendingBelowClientOrderId 不同。 +newOrderRespType ENUM NO JSON 响应格式。支持的数值:订单返回类型 +selfTradePreventionMode ENUM NO 允许的值取决于交易对的配置。支持的数值:STP模式 +workingType ENUM YES 支持的数值:LIMIT,LIMIT_MAKER +workingSide ENUM YES 支持的数值:订单方向 +workingClientOrderId STRING NO 生效订单中挂单的任意唯一 ID。如果未发送,则自动生成。 +workingPrice DECIMAL YES 生效订单价格 +workingQuantity DECIMAL YES 生效订单数量 +workingIcebergQty DECIMAL NO 仅当 workingTimeInForce 为 GTC 或 workingType 为 LIMIT_MAKER 时可用 +workingTimeInForce ENUM NO 支持的数值:生效时间 +workingStrategyId LONG NO 用于标识订单策略中生效订单的任意数字值 +workingStrategyType INT NO 用于标识生效订单策略的任意数字值。小于 1000000 的值为保留值,不能使用。 +workingPegPriceType ENUM NO 详见 挂钩订单 +workingPegOffsetType ENUM NO +workingPegOffsetValue INT NO +pendingSide ENUM YES 支持的数值:订单方向 +pendingAboveType ENUM YES 支持的数值:STOP_LOSS_LIMIT,STOP_LOSS,LIMIT_MAKER,TAKE_PROFIT,TAKE_PROFIT_LIMIT +pendingAboveClientOrderId STRING NO 待执行“上方”订单中开放订单的任意唯一 ID。如果未发送,则自动生成。 +pendingAbovePrice DECIMAL NO 当 pendingAboveType 为 STOP_LOSS_LIMIT、LIMIT_MAKER 或 TAKE_PROFIT_LIMIT 时,可用于指定限价。 +pendingAboveStopPrice DECIMAL NO 当 pendingAboveType 为 STOP_LOSS、STOP_LOSS_LIMIT、TAKE_PROFIT、TAKE_PROFIT_LIMIT 时可用。 +pendingAboveTrailingDelta DECIMAL NO 详见 追踪止盈止损常见问题 +pendingAboveIcebergQty DECIMAL NO 仅当 pendingAboveTimeInForce 为 GTC 或 pendingAboveType 为 LIMIT_MAKER 时可用。 +pendingAboveTimeInForce ENUM NO +pendingAboveStrategyId LONG NO 用于标识订单策略中待执行上方订单的任意数字值。 +pendingAboveStrategyType INT NO 用于标识待执行上方订单策略的任意数字值。小于 1000000 的值为保留值,不能使用。 +pendingAbovePegPriceType ENUM NO 详见 挂钩订单 +pendingAbovePegOffsetType ENUM NO +pendingAbovePegOffsetValue INT NO +pendingBelowType ENUM NO 支持的数值:STOP_LOSS,STOP_LOSS_LIMIT,TAKE_PROFIT,TAKE_PROFIT_LIMIT +pendingBelowClientOrderId STRING NO 待执行“下方”订单中开放订单的任意唯一 ID。如果未发送,则自动生成。 +pendingBelowPrice DECIMAL NO 当 pendingBelowType 为 STOP_LOSS_LIMIT 或 TAKE_PROFIT_LIMIT 时,可用于指定限价。 +pendingBelowStopPrice DECIMAL NO 当 pendingBelowType 为 STOP_LOSS、STOP_LOSS_LIMIT、TAKE_PROFIT 或 TAKE_PROFIT_LIMIT 时可用。pendingBelowStopPrice、pendingBelowTrailingDelta 或两者之一必须被指定。 +pendingBelowTrailingDelta DECIMAL NO +pendingBelowIcebergQty DECIMAL NO 仅当 pendingBelowTimeInForce 为 GTC 或 pendingBelowType 为 LIMIT_MAKER 时可用。 +pendingBelowTimeInForce ENUM NO 支持的数值:生效时间 +pendingBelowStrategyId LONG NO 用于标识订单策略中待执行下方订单的任意数字值。 +pendingBelowStrategyType INT NO 用于标识待执行下方订单策略的任意数字值。小于 1000000 为保留值,不能使用。 +pendingBelowPegPriceType ENUM NO 详见 挂钩订单 +pendingBelowPegOffsetType ENUM NO +pendingBelowPegOffsetValue INT NO +recvWindow DECIMAL NO 该值不能大于 60000。支持最多三位小数精度(例如 6000.346),以便指定微秒。 +timestamp LONG YES 时间戳 +响应: + +{ + "orderListId": 2, + "contingencyType": "OTO", + "listStatusType": "EXEC_STARTED", + "listOrderStatus": "EXECUTING", + "listClientOrderId": "bcedxMpQG6nFrZUPQyshoL", + "transactionTime": 1763000506354, + "symbol": "BTCUSDT", + "orders": [ + { + "symbol": "BTCUSDT", + "orderId": 9, + "clientOrderId": "OLSBhMWaIlLSzZ9Zm7fnKB" + }, + { + "symbol": "BTCUSDT", + "orderId": 10, + "clientOrderId": "mfif39yPTHsB3C0FIXznR2" + }, + { + "symbol": "BTCUSDT", + "orderId": 11, + "clientOrderId": "yINkaXSJeoi3bU5vWMY8Z8" + } + ], + "orderReports": [ + { + "symbol": "BTCUSDT", + "orderId": 9, + "orderListId": 2, + "clientOrderId": "OLSBhMWaIlLSzZ9Zm7fnKB", + "transactTime": 1763000506354, + "price": "102496.00000000", + "origQty": "0.00170000", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.00000000", + "cummulativeQuoteQty": "0.00000000", + "status": "NEW", + "timeInForce": "GTC", + "type": "LIMIT", + "side": "BUY", + "workingTime": 1763000506354, + "selfTradePreventionMode": "NONE" + }, + { + "symbol": "BTCUSDT", + "orderId": 10, + "orderListId": 2, + "clientOrderId": "mfif39yPTHsB3C0FIXznR2", + "transactTime": 1763000506354, + "price": "101613.00000000", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.00000000", + "cummulativeQuoteQty": "0.00000000", + "status": "PENDING_NEW", + "timeInForce": "GTC", + "type": "STOP_LOSS_LIMIT", + "side": "SELL", + "stopPrice": "10100.00000000", + "workingTime": -1, + "selfTradePreventionMode": "NONE" + }, + { + "symbol": "BTCUSDT", + "orderId": 11, + "orderListId": 2, + "clientOrderId": "yINkaXSJeoi3bU5vWMY8Z8", + "transactTime": 1763000506354, + "price": "104261.00000000", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.00000000", + "cummulativeQuoteQty": "0.00000000", + "status": "PENDING_NEW", + "timeInForce": "GTC", + "type": "LIMIT_MAKER", + "side": "SELL", + "workingTime": -1, + "selfTradePreventionMode": "NONE" + } + ] +} + +注意: 上面的 payload 没有显示所有可以出现的字段,更多请看 订单响应中的特定条件时才会出现的字段 部分。 + +取消订单列表 (TRADE) +DELETE /api/v3/orderList + +取消整个订单列表。 + +权重: 1 + +参数: + +名称 类型 是否必需 描述 +symbol STRING YES +orderListId LONG NO orderListId 或 listClientOrderId 必须被提供 +listClientOrderId STRING NO orderListId 或 listClientOrderId 必须被提供 +newClientOrderId STRING NO 用户自定义的本次撤销操作的ID(注意不是被撤销的订单的自定义ID)。如无指定会自动赋值。 +recvWindow DECIMAL NO 最大值为 60000 毫秒。 +支持最多三位小数的精度(例如 6000.346),以便可以指定微秒。 +timestamp LONG YES +其他注意点: + +取消订单列表中的单个订单将取消整个订单列表. +当同时提供 orderListId 和 listClientOrderId 两个参数时,系统首先将会使用 orderListId 来搜索订单。然后, 查找结果中的 listClientOrderId 的值将会被用来验证订单。如果两个条件都不满足,则请求将被拒绝。 +数据源: 撮合引擎 + +响应: + +{ + "orderListId": 0, + "contingencyType": "OCO", + "listStatusType": "ALL_DONE", + "listOrderStatus": "ALL_DONE", + "listClientOrderId": "C3wyj4WVEktd7u9aVBRXcN", + "transactionTime": 1574040868128, + "symbol": "LTCBTC", + "orders": [ + { + "symbol": "LTCBTC", + "orderId": 2, + "clientOrderId": "pO9ufTiFGg3nw2fOdgeOXa" + }, + { + "symbol": "LTCBTC", + "orderId": 3, + "clientOrderId": "TXOvglzXuaubXAaENpaRCB" + } + ], + "orderReports": [ + { + "symbol": "LTCBTC", + "origClientOrderId": "pO9ufTiFGg3nw2fOdgeOXa", + "orderId": 2, + "orderListId": 0, + "clientOrderId": "unfWT8ig8i0uj6lPuYLez6", + "transactTime": 1688005070874, + "price": "1.00000000", + "origQty": "10.00000000", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.00000000", + "status": "CANCELED", + "timeInForce": "GTC", + "type": "STOP_LOSS_LIMIT", + "side": "SELL", + "stopPrice": "1.00000000" + }, + { + "symbol": "LTCBTC", + "origClientOrderId": "TXOvglzXuaubXAaENpaRCB", + "orderId": 3, + "orderListId": 0, + "clientOrderId": "unfWT8ig8i0uj6lPuYLez6", + "transactTime": 1688005070874, + "price": "3.00000000", + "origQty": "10.00000000", + "executedQty": "0.00000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "0.00000000", + "status": "CANCELED", + "timeInForce": "GTC", + "type": "LIMIT_MAKER", + "side": "SELL" + } + ] +} + +SOR + +下 SOR 订单 (TRADE) +POST /api/v3/sor/order + +发送使用智能订单路由 (SOR) 的新订单。 + +这个请求会把1个订单添加到 EXCHANGE_MAX_ORDERS 过滤器和 MAX_NUM_ORDERS 过滤器中。 + +参阅 智能指令路由 (SOR) 了解更多详情。 + +权重: 1 + +未成交的订单计数: 1 + +参数: + +名称 类型 是否必需 描述 +symbol STRING YES +side ENUM YES +type ENUM YES +timeInForce ENUM NO +quantity DECIMAL YES +price DECIMAL NO +newClientOrderId STRING NO 用户自定义的orderid,如空缺系统会自动赋值。如果几个订单具有相同的 newClientOrderID 赋值, +那么只有在前一个订单成交后才可以接受下一个订单,否则该订单将被拒绝。 +strategyId LONG NO +strategyType INT NO 赋值不能小于 1000000. +icebergQty DECIMAL NO 仅有限价单可以使用该参数,含义为创建冰山订单并指定冰山订单的数量。 +newOrderRespType ENUM NO 指定响应类型: +指定响应类型 ACK, RESULT 或 FULL; 默认为 FULL。 +selfTradePreventionMode ENUM NO 允许的 ENUM 取决于交易对的配置。支持的值有:STP 模式。 +recvWindow DECIMAL NO 最大值为 60000 毫秒。 +支持最多三位小数的精度(例如 6000.346),以便可以指定微秒。 +timestamp LONG YES +请注意: POST /api/v3/sor/order 只支持 限价 和 市场 单, 并不支持 quoteOrderQty。 + +数据源: 撮合引擎 + +响应: + +{ + "symbol": "BTCUSDT", + "orderId": 2, + "orderListId": -1, + "clientOrderId": "sBI1KM6nNtOfj5tccZSKly", + "transactTime": 1689149087774, + "price": "31000.00000000", + "origQty": "0.50000000", + "executedQty": "0.50000000", + "origQuoteOrderQty": "0.000000", + "cummulativeQuoteQty": "14000.00000000", + "status": "FILLED", + "timeInForce": "GTC", + "type": "LIMIT", + "side": "BUY", + "workingTime": 1689149087774, + "fills": [ + { + "matchType": "ONE_PARTY_TRADE_REPORT", + "price": "28000.00000000", + "qty": "0.50000000", + "commission": "0.00000000", + "commissionAsset": "BTC", + "tradeId": -1, + "allocId": 0 + } + ], + "workingFloor": "SOR", + "selfTradePreventionMode": "NONE", + "usedSor": true +} + +测试 SOR 下单接口 (TRADE) +POST /api/v3/sor/order/test + +用于测试使用智能订单路由 (SOR) 的订单请求,但不会提交到撮合引擎 + +权重: + +条件 请求权重 +没有 computeCommissionRates 1 +有 computeCommissionRates 20 +参数: + +除了 POST /api/v3/sor/order 所有参数, 如下参数也接受: + +参数名 类型 是否必需 描述 +computeCommissionRates BOOLEAN NO 默认值: false +数据源: 缓存 + +响应: + +没有 computeCommissionRates + +{} + +有 computeCommissionRates + +{ + "standardCommissionForOrder": { // 订单交易的标准佣金率。 + "maker": "0.00000112", + "taker": "0.00000114" + }, + "taxCommissionForOrder": { // 订单交易的税率。 + "maker": "0.00000112", + "taker": "0.00000114" + }, + "discount": { // 以BNB支付时的标准佣金折扣。 + "enabledForAccount": true, + "enabledForSymbol": true, + "discountAsset": "BNB", + "discount": "0.25000000" // 当用BNB支付佣金时,在标准佣金上按此比率打折。 + } +} \ No newline at end of file diff --git a/trading_system/market_scanner.py b/trading_system/market_scanner.py index 8b5f356..bfcabf6 100644 --- a/trading_system/market_scanner.py +++ b/trading_system/market_scanner.py @@ -714,7 +714,10 @@ class MarketScanner: logger.debug(f"{symbol} 技术指标计算结果已缓存 (TTL: 30秒)") except Exception as e: logger.debug(f"{symbol} 缓存技术指标计算结果失败: {e}") - + + # 统一:缓存可能返回 None,保证下游始终拿到 'trending'/'ranging'/'unknown' + market_regime = market_regime or 'unknown' + # 计算交易信号得分(用于排序)- 保留用于兼容性 signal_score = 0 diff --git a/trading_system/redis_cache.py b/trading_system/redis_cache.py index 013994a..c13e9b5 100644 --- a/trading_system/redis_cache.py +++ b/trading_system/redis_cache.py @@ -85,7 +85,7 @@ class RedisCache: self._connected = False async def connect(self): - """连接 Redis""" + """连接 Redis。若已连接且 ping 正常则直接返回,避免重复连接和刷屏日志。""" if not REDIS_AVAILABLE: import sys import os @@ -97,96 +97,85 @@ class RedisCache: self.redis = None self._connected = False return - + + # 已连接且连接仍有效时不再重复连接,避免多模块多次 connect 时刷屏 + if self._connected and self.redis: + try: + await self.redis.ping() + return + except Exception: + self._connected = False + self.redis = None + try: # 构建连接参数 connection_kwargs = {} - + # 如果使用 TLS(redis-py的异步客户端使用特定的SSL参数,而不是ssl上下文) if self.use_tls or self.redis_url.startswith('rediss://'): # redis-py的异步客户端不支持直接传递ssl上下文 # 而是使用ssl_cert_reqs、ssl_ca_certs等参数 # 当URL是rediss://时,redis-py会自动启用SSL - - # 设置证书验证要求(字符串格式:'required', 'optional', 'none') connection_kwargs['ssl_cert_reqs'] = self.ssl_cert_reqs - - # 如果提供了 CA 证书路径 if self.ssl_ca_certs: connection_kwargs['ssl_ca_certs'] = self.ssl_ca_certs - - # 设置主机名验证(根据ssl_cert_reqs自动设置,但可以显式指定) if self.ssl_cert_reqs == 'none': connection_kwargs['ssl_check_hostname'] = False elif self.ssl_cert_reqs == 'required': connection_kwargs['ssl_check_hostname'] = True - else: # optional + else: connection_kwargs['ssl_check_hostname'] = False - - logger.info(f"使用 TLS 连接 Redis: {self.redis_url} (ssl_cert_reqs={self.ssl_cert_reqs})") - + logger.debug("使用 TLS 连接 Redis: %s (ssl_cert_reqs=%s)", self.redis_url, self.ssl_cert_reqs) + # 如果 URL 中不包含用户名和密码,且提供了独立的用户名和密码参数,则添加到连接参数中 - # 注意:如果 URL 中已经包含认证信息(如 redis://user:pass@host:port),则优先使用 URL 中的 if self.username and self.password: - # 检查 URL 中是否已包含认证信息(格式:redis://user:pass@host:port) url_parts = self.redis_url.split('://') if len(url_parts) == 2: url_after_scheme = url_parts[1] - # 如果 URL 中不包含 @ 符号,说明没有在 URL 中指定认证信息 if '@' not in url_after_scheme: - # URL 中不包含认证信息,使用独立的用户名和密码参数 connection_kwargs['username'] = self.username connection_kwargs['password'] = self.password - logger.info(f"使用独立的用户名和密码进行认证: {self.username}") + logger.debug("使用独立的用户名和密码进行认证(不记录用户名)") else: - logger.info("URL 中已包含认证信息,优先使用 URL 中的认证信息") + logger.debug("URL 中已包含认证信息,优先使用 URL 中的认证信息") else: - # URL 格式异常,尝试使用独立的用户名和密码 connection_kwargs['username'] = self.username connection_kwargs['password'] = self.password - logger.info(f"URL 格式异常,使用独立的用户名和密码进行认证: {self.username}") - - # 验证URL格式(redis-py要求URL必须有正确的scheme) - if not self.redis_url or not any(self.redis_url.startswith(scheme) for scheme in ['redis://', 'rediss://', 'unix://']): + logger.debug("URL 格式异常,使用独立的用户名和密码进行认证") + + # 验证URL格式 + if not self.redis_url or not any(self.redis_url.startswith(s) for s in ['redis://', 'rediss://', 'unix://']): raise ValueError( f"Redis URL必须指定以下scheme之一 (redis://, rediss://, unix://): {self.redis_url}" ) - - # 创建 Redis 连接 - # 使用 redis.asyncio.from_url(redis-py 4.2+)或 aioredis.from_url(向后兼容) - # redis-py 需要 decode_responses=True,aioredis 2.0 可能不需要 - # 检查是否是 redis.asyncio(通过检查模块名称) + try: module_name = aioredis.__name__ if hasattr(aioredis, '__name__') else '' is_redis_py = 'redis.asyncio' in module_name or 'redis' in module_name - except: + except Exception: is_redis_py = False - + if is_redis_py: - # redis-py 4.2+ 的异步客户端,需要 decode_responses=True connection_kwargs['decode_responses'] = True - # aioredis 2.0 不需要 decode_responses(它默认返回字节) - + self.redis = await aioredis.from_url( self.redis_url, **connection_kwargs ) - - # 测试连接 + await self.redis.ping() self._connected = True - logger.info(f"✓ Redis 连接成功: {self.redis_url}") - + logger.info("✓ Redis 连接成功: %s", self.redis_url) + except Exception as e: - logger.warning(f"Redis 连接失败: {e},将使用内存缓存") - self.redis = None - self._connected = False + logger.warning("Redis 连接失败: %s,将使用内存缓存", e) if self.redis: try: await self.redis.close() - except: + except Exception: pass - self.redis = None + self.redis = None + self._connected = False async def get(self, key: str) -> Optional[Any]: """ diff --git a/trading_system/strategy.py b/trading_system/strategy.py index e88eec0..3221ef7 100644 --- a/trading_system/strategy.py +++ b/trading_system/strategy.py @@ -124,8 +124,8 @@ class TradingStrategy: symbol = symbol_info['symbol'] change_percent = symbol_info['changePercent'] direction = symbol_info['direction'] - market_regime = symbol_info.get('marketRegime', 'unknown') - + market_regime = symbol_info.get('marketRegime') or 'unknown' + # unknown 表示 K 线不足或未判定趋势/震荡,属正常;仅生成推荐,不满足 ONLY_TRENDING 时不自动下单 logger.info( f"处理交易对: {symbol} " f"({direction} {change_percent:.2f}%, 市场状态: {market_regime})"