From 843d3bbfe5d794a4e65617d52ea82a44fe9a2635 Mon Sep 17 00:00:00 2001 From: Zichao Lin Date: Wed, 2 Sep 2026 08:53:23 +0800 Subject: [PATCH] =?UTF-8?q?fix(convert):=20=E4=BF=AE=E6=AD=A3=20OKX=20?= =?UTF-8?q?=E9=97=AA=E5=85=91=E6=96=B9=E5=90=91=E8=A6=86=E7=9B=96=E5=92=8C?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 convert_params 覆盖 ccxt 默认请求方向,baseCcy=base货币,side=bot买卖方向 - 修复 record_data 字段映射:filled=fromAmount(baseCcy数量),cost=toAmount(quoteCcy数量) - 保留 fetchConvertTrade 空壳回退逻辑 - 解决 USDT→OKB 闪兑报 58009 'Crypto pair not exist' 的问题 --- main.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/main.py b/main.py index b884c16..2276523 100644 --- a/main.py +++ b/main.py @@ -275,8 +275,17 @@ class BotSpotTrade: self.logger.info("开始闪兑: %s %s → %s", amount, from_currency, to_currency) + # OKX 闪兑 pair 注册方向为 (baseCcy, quoteCcy) = (base, quote),side 对 baseCcy 描述方向 + # ccxt 默认 baseCcy=fromCode + side=sell,不匹配 OKX 注册方向时会被拒(58009) + # 用 params 覆盖请求方向,使 baseCcy 始终等于交易对的 base 货币 + convert_params = { + 'baseCcy': base_currency, + 'quoteCcy': quote_currency, + 'side': side, + } + try: - quote = self.exchange.fetchConvertQuote(from_currency, to_currency, amount) + quote = self.exchange.fetchConvertQuote(from_currency, to_currency, amount, convert_params) self.logger.info( "获取闪兑报价成功: %s %s → %s %s, 报价ID: %s", from_currency, amount, to_currency, @@ -294,7 +303,7 @@ class BotSpotTrade: try: convert_trade = self.exchange.createConvertTrade( - quote_id, from_currency, to_currency, amount + quote_id, from_currency, to_currency, amount, convert_params ) self.logger.info("创建闪兑交易成功: %s", convert_trade) except Exception as e: @@ -324,11 +333,13 @@ class BotSpotTrade: final_data = trade_detail or convert_trade + # 覆写方向后,OKX 返回的 fromAmount = baseCcy 数量(交易币),toAmount = quoteCcy 数量(计价币) + # 记录格式与现货订单一致:filled = 交易币数量,cost = 计价币数量 record_data = { "symbol": symbol, "id": trade_id, - "filled": final_data.get("toAmount") or 0.0, - "cost": final_data.get("fromAmount") or 0.0, + "filled": final_data.get("fromAmount") or 0.0, + "cost": final_data.get("toAmount") or 0.0, "side": side, "timestamp": final_data.get("timestamp") or int(time.time() * 1000), }