Przeglądaj źródła

另一个方向的逻辑写完了,下午测试。

skyfffire 4 miesięcy temu
rodzic
commit
eeb823736a
4 zmienionych plików z 266 dodań i 274 usunięć
  1. 7 0
      as.py
  2. 19 19
      checker/mexc_to_erc20_checker.py
  3. 237 255
      s_mexc_to_erc20.py
  4. 3 0
      toto.readme

+ 7 - 0
as.py

@@ -10,6 +10,7 @@ import uuid # 用于生成唯一的流程ID
 import time
 import logging
 import s_erc20_to_mexc
+import s_mexc_to_erc20
 import web3_py_client
 import traceback
 import copy
@@ -174,6 +175,12 @@ def strategy_builder(process_item):
         pending_data, pending_lock,
         mexc_data, mexc_lock
         )
+    elif strategy == 'mexc_to_erc20':
+        return s_mexc_to_erc20.ArbitrageProcess(gas_limit_multiplier, gas_price_multiplier, process_item, 
+        core_data, core_lock,
+        pending_data, pending_lock,
+        mexc_data, mexc_lock
+        )
     else:
         process_item_formated = pformat(process_item, indent=2)
         logger.error(f'不存在的策略:{strategy}\n{process_item_formated}')

+ 19 - 19
checker/mexc_to_erc20_checker.py

@@ -52,7 +52,7 @@ proxies = None # {'http': 'http://proxy_url:port', 'https': 'http://proxy_url:po
 
 # 運行模式【trade、view】
 mode = None
-# oo_price_usdt_per_target = None # 这个全局变量似乎没有被有效使用,价格在循环内获取
+# chain_price = None # 这个全局变量似乎没有被有效使用,价格在循环内获取
 
 # 配置請求的日志等級
 app = Flask(__name__)
@@ -149,8 +149,8 @@ def get_mexc_spot_price_target_usdt_ask(human_out_base):
         return {"error": f"MEXC现货({MEXC_TARGET_PAIR_USDT})处理错误: {e}"}, decimal.Decimal('0')
 
 latest_values_for_table = {
-    f"oo_price_usdt_per_target": "N/A",
-    f"mexc_price_target_per_base": "N/A", # MEXC price (converted to USDT/TARGET)
+    f"chain_price": "N/A",
+    f"cex_price": "N/A", # MEXC price (converted to USDT/TARGET)
     f"diff_oo_vs_mexc_percentage": "N/A",
     "profit_value_for_table": "N/A", # 新增:用于表格的利润值
     "oo_error": None, "mexc_error": None,
@@ -172,7 +172,7 @@ def calculate_percentage_diff(sell_price, buy_price):
         return rst
     return None
 
-def send_arb_msg(profit_amount, chain_swap_data, mexc_price_usdt_per_target, human_out_base):
+def send_arb_msg(profit_amount, chain_swap_data, human_out_base, chain_price, cex_price):
     # chain_swap_data 是从 get_chain_price_vs_target_currency 返回的第二个值
     if not (chain_swap_data and chain_swap_data.get('data') and chain_swap_data['data']):
         logger.error(f"套利消息发送失败:链上交易数据不完整 {chain_swap_data}")
@@ -194,7 +194,6 @@ def send_arb_msg(profit_amount, chain_swap_data, mexc_price_usdt_per_target, hum
         "tx": tx, # 预签名交易
         "profit": str(profit_amount.quantize(decimal.Decimal('0.001'))),
         "profitLimit": str(PROFIT_LIMIT.quantize(decimal.Decimal('0.001'))),
-        # "mexcPriceUsdtPerTarget": str(mexc_price_usdt_per_target.quantize(decimal.Decimal('1e-8'))),
         "symbol": MEXC_TARGET_PAIR_USDT,
         "fromToken": IN_TOKEN_ADDRESS,
         "fromTokenAmountHuman": str(human_out_base.quantize(decimal.Decimal(f'1e-{in_dec}'))),
@@ -202,7 +201,8 @@ def send_arb_msg(profit_amount, chain_swap_data, mexc_price_usdt_per_target, hum
         "toToken": OUT_TOKEN_ADDRESS,
         "toTokenAmountHuman": str(human_out_base.quantize(decimal.Decimal(f'1e-{out_dec}'))),
         "toTokenDecimal": str(out_dec),
-        "exchangeOutAmount": str(EXCHANGE_OUT_AMOUNT.quantize(decimal.Decimal(f'1e-{out_dec}'))), # CEX上期望卖出的目标币数量
+        "chainPrice", str(chain_price),
+        "cexPrice", str(cex_price),
         "strategy": STRATEGY,
     }
 
@@ -242,26 +242,26 @@ def update_data_for_plotly_and_table():
             USER_WALLET,
             USER_EXCHANGE_WALLET
         )
-        oo_price_usdt_per_target = oo_data.get("price_base_per_target") # USDT/TARGET
+        chain_price = oo_data.get("price_base_per_target") # USDT/TARGET
         oo_err = oo_data.get("error")
 
         # 2. MEXC: 获取 price_target_per_base (例如 RATO/USDT)
         # trade_value_usdt 是指如果以 EXCHANGE_OUT_AMOUNT 的目标代币在MEXC上砸盘卖出,能获得的USDT估值
         mexc_data, trade_value_usdt = get_mexc_spot_price_target_usdt_ask(human_out_base)
-        mexc_price_target_per_base = mexc_data.get("price_target_per_base") # TARGET/USDT
+        cex_price = mexc_data.get("price_target_per_base") # TARGET/USDT
         mexc_err = mexc_data.get("error")
 
         # 3. 计算百分比差异
         # diff = (链上卖价 - MEXC买价) / MEXC买价
         diff_oo_vs_mexc_pct = calculate_percentage_diff(
-            oo_price_usdt_per_target,                   # 链上卖价 (USDT/TARGET)
-            mexc_price_target_per_base,                 # MEXC买价 (USDT/TARGET)
+            chain_price,                   # 链上卖价 (USDT/TARGET)
+            cex_price,                 # MEXC买价 (USDT/TARGET)
         )
 
         # 4. 计算实际利润额 (以USDT计价)
         # 简化:利润百分比 * 投入的USDT金额
         actual_profit_usdt = None
-        if diff_oo_vs_mexc_pct is not None and oo_price_usdt_per_target is not None and oo_price_usdt_per_target > 0:
+        if diff_oo_vs_mexc_pct is not None and chain_price is not None and chain_price > 0:
             # 基于百分比和投入金额
             actual_profit_usdt = diff_oo_vs_mexc_pct * human_out_base
 
@@ -269,22 +269,22 @@ def update_data_for_plotly_and_table():
         global mode
         if actual_profit_usdt is not None and actual_profit_usdt > PROFIT_LIMIT + 3 and mode == 'trade':
             if chain_swap_full_response: # 确保有完整的链上数据
-                send_arb_msg(actual_profit_usdt, chain_swap_full_response, mexc_price_target_per_base, human_out_base)
+                send_arb_msg(actual_profit_usdt, chain_swap_full_response, human_out_base, chain_price, cex_price)
             else:
                 logger.warning("利润满足但链上数据不完整,无法发送套利消息。")
 
         current_point = {
             "time": fetch_time_chart,
-            "oo_price_usdt_per_target": float(oo_price_usdt_per_target) if oo_price_usdt_per_target else None,
-            "mexc_price_target_per_base": float(mexc_price_target_per_base) if mexc_price_target_per_base else None,
+            "chain_price": float(chain_price) if chain_price else None,
+            "cex_price": float(cex_price) if cex_price else None,
             "diff_oo_vs_mexc": float(diff_oo_vs_mexc_pct) if diff_oo_vs_mexc_pct is not None else None,
             "profit_value": float(actual_profit_usdt) if actual_profit_usdt is not None else None, # 新增:用于图表的实际利润额
         }
 
         with data_lock:
             historical_data_points.append(current_point)
-            latest_values_for_table["oo_price_usdt_per_target"] = f"{oo_price_usdt_per_target:.8f}" if oo_price_usdt_per_target else "N/A"
-            latest_values_for_table["mexc_price_target_per_base"] = f"{mexc_price_target_per_base:.8f}" if mexc_price_target_per_base else "N/A"
+            latest_values_for_table["chain_price"] = f"{chain_price:.8f}" if chain_price else "N/A"
+            latest_values_for_table["cex_price"] = f"{cex_price:.8f}" if cex_price else "N/A"
             latest_values_for_table["diff_oo_vs_mexc_percentage"] = f"{diff_oo_vs_mexc_pct:+.4%}" if diff_oo_vs_mexc_pct is not None else "N/A" # 显示为百分比
             latest_values_for_table["profit_value_for_table"] = f"{actual_profit_usdt:.2f} {BASE_CURRENCY_SYMBOL}" if actual_profit_usdt is not None else "N/A" # 新增
             latest_values_for_table["oo_error"] = oo_err
@@ -292,7 +292,7 @@ def update_data_for_plotly_and_table():
             latest_values_for_table["last_updated"] = fetch_time_full
             latest_values_for_table["in_amount_for_query_display"] = f"{human_out_base:.2f} {BASE_CURRENCY_SYMBOL}" if human_out_base > 0 else "N/A"
 
-        # logger.info(f"{fetch_time_chart} Price Query: Chain Input {human_out_base:.2f} {BASE_CURRENCY_SYMBOL} | OKX Price: {oo_price_usdt_per_target_display} | MEXC Price: {mexc_price_target_per_base_display} | Diff: {diff_display} | Profit: {profit_display}")
+        # logger.info(f"{fetch_time_chart} Price Query: Chain Input {human_out_base:.2f} {BASE_CURRENCY_SYMBOL} | OKX Price: {chain_price_display} | MEXC Price: {cex_price_display} | Diff: {diff_display} | Profit: {profit_display}")
         if oo_err or mexc_err :
              logger.warning(f"{fetch_time_chart} Errors: OO:{oo_err}, MEXC:{mexc_err}")
 
@@ -340,12 +340,12 @@ def get_plotly_chart_data():
 
         # Price Chart
         fig_prices = go.Figure()
-        fig_prices.add_trace(go.Scatter(x=times, y=[p['oo_price_usdt_per_target'] for p in points], mode='lines',
+        fig_prices.add_trace(go.Scatter(x=times, y=[p['chain_price'] for p in points], mode='lines',
                                         name=f'链上({display_base_asset}/{display_target_asset})',
                                         line=dict(color='rgb(75, 192, 192)'),
                                         hovertemplate=f'<b>链上价</b><br>价格: %{{y:.8f}} {display_base_asset}<extra></extra>',
                                         connectgaps=True)) # 处理None值不画线
-        fig_prices.add_trace(go.Scatter(x=times, y=[p['mexc_price_target_per_base'] for p in points], mode='lines',
+        fig_prices.add_trace(go.Scatter(x=times, y=[p['cex_price'] for p in points], mode='lines',
                                         name=f'MEXC价 ({display_base_asset}/{display_target_asset})',
                                         line=dict(color='rgb(255, 99, 132)', dash='dash'),
                                         hovertemplate=f'<b>MEXC价</b><br>价格: %{{y:.8f}} {display_base_asset}<extra></extra>',

+ 237 - 255
s_mexc_to_erc20.py

@@ -10,6 +10,7 @@ from checker.logger_config import get_logger
 from pprint import pformat
 
 web3 = EthClient()
+web3_backup = EthClient(os.getenv("RPC_URL_2"))
 mexc = MexcClient()
 
 # 配置日志
@@ -56,14 +57,16 @@ class ArbitrageProcess:
             self.eth_price = self.core_data['eth_price']
         
         with self.mexc_lock:
-            self.withdraw_info = copy.deepcopy(self.mexc_data['coin_info_map'][self.base_coin][self.NETWORK])
+            self.withdraw_info = copy.deepcopy(self.mexc_data['coin_info_map'][self.coin][self.NETWORK])
             self.WITHDRAW_FEE = Decimal(self.withdraw_info['withdrawFee']) # 提現手續費
+            self.WITHDRAW_ENABLE = self.withdraw_info['withdrawEnable'] # 是否启用提现
 
             withdraw_info_formated = pformat(self.withdraw_info, indent=2)
             logger.info(f'提現信息識別, 手續費:{self.WITHDRAW_FEE}\n{withdraw_info_formated}')
 
         self.tx = tx
         
+        self.mexc_price = Decimal(process_item['cexPrice'])
         self.profit = Decimal(process_item['profit'])               # 這個利潤是實際到手利潤
         self.profit_limit = Decimal(process_item['profitLimit'])    # 這個利潤是實際到手利潤的limit
 
@@ -82,30 +85,28 @@ class ArbitrageProcess:
 
         # 存储当前套利交易的细节信息,例如买入数量、价格等
         self.sell_price = Decimal(0)
+        self.sell_value = Decimal(0)
         self.buy_price = Decimal(0)
-        self.chain_tx_hash = None                                               # 链上买入的tx hash
-        self.chain_usdt_use = Decimal(process_item['fromTokenAmountHuman'])     # 链上usdt减少量(使用量)
-        self.chain_buy_amount = Decimal(0)                                      # 链上币增加量(购入量), todo, 暂用即时余额代替
-        self.exchange_sell_amount = Decimal(process_item['exchangeOutAmount'])  # 交易所卖出量
-        self.exchange_sell_order_id = None                                      # 交易所卖出id
-        self.exchange_withdrawal_id = None                                      # 交易所提现id
-        self.exchange_withdrawal_amount = None                                  # 交易所提现数量
-        self.actual_profit = Decimal(0)                                         # 實際利潤
+        self.buy_value = Decimal(0)
+        self.chain_tx_hash = None                                                   # 链上卖出的tx hash
+
+        self.exchange_buy_amount = Decimal(process_item['fromTokenAmountHuman'])    # 交易所买入量
+        self.exchange_buy_amount = self.exchange_buy_amount + self.WITHDRAW_FEE     # 买入量考虑提现手续费
+
+        self.exchange_buy_order_id = None                                           # 交易所买入id
+        self.exchange_withdrawal_id = None                                          # 交易所提现id
+        self.exchange_withdrawal_amount = None                                      # 交易所提现数量
+        self.actual_profit = Decimal(0)                                             # 實際利潤
 
         # 定义可能的状态
         self.STATES = [
             "CHECK",                        # 检查余额、估算gas等
-            "SELLING_ON_EXCHANGE",          # 正在中心化交易所卖出现货
-            "WAITING_SELL_CONFIRM",         # 等待现货卖出订单确认
-            "BUYING_ON_CHAIN",              # 正在链上买入
+            "BUYING_ON_EXCHANGE",           # 正在中心化交易所买入现货
+            "WAITING_BUY_CONFIRM",          # 等待现货买入订单确认
+            "SELLING_ON_CHAIN",             # 正在链上卖出
             "WAITING_CHAIN_CONFIRM",        # 等待链上交易确认
             "WAITING_EXCHANGE_ROLLBACK",    # 等待交易所回滚
-            # "HEDGING_ON_EXCHANGE",          # 正在中心化交易所套保
-            # "WAITING_HEDGE_CONFIRM",        # 等待套保订单确认
-            # "TRANSFERRING_TO_EXCHANGE",     # 正在向交易所转账
-            # "CLOSING_HEDGE",                # 正在平掉套保单
-            # "WAITING_CLOSE_HEDGE_CONFIRM",  # 等待平掉套保单确认
-            "WAITING_TRANSFER_ARRIVE",      # 等待交易所充值到账
+            # "WAITING_TRANSFER_ARRIVE",      # 等待交易所充值到账
             "TRANSFERRING_TO_CHAIN",        # 正在向链上转账
             "WAITING_WITHDRAWAL_CONFIRM",   # 等待链上提现确认
             "COMPLETED",                    # 套利流程完成
@@ -115,13 +116,11 @@ class ArbitrageProcess:
 
         self.STATE_IDLE = "IDLE"
         self.STATE_CHECK = "CHECK"
-        self.STATE_SELLING_ON_EXCHANGE = "SELLING_ON_EXCHANGE"
-        self.STATE_WAITING_SELL_CONFIRM = "WAITING_SELL_CONFIRM"
-        self.STATE_BUYING_ON_CHAIN = "BUYING_ON_CHAIN"
+        self.STATE_BUYING_ON_EXCHANGE = "BUYING_ON_EXCHANGE"
+        self.STATE_WAITING_BUY_CONFIRM = "WAITING_BUY_CONFIRM"
+        self.STATE_SELLING_ON_CHAIN = "SELLING_ON_CHAIN"
         self.STATE_WAITING_CHAIN_CONFIRM = "WAITING_CHAIN_CONFIRM"
         self.STATE_WAITING_EXCHANGE_ROLLBACK = "WAITING_EXCHANGE_ROLLBACK"
-        # self.STATE_TRANSFERRING_TO_EXCHANGE = "TRANSFERRING_TO_EXCHANGE"
-        self.STATE_WAITING_TRANSFER_ARRIVE = "WAITING_TRANSFER_ARRIVE"
         self.STATE_TRANSFERRING_TO_CHAIN = "TRANSFERRING_TO_CHAIN"
         self.STATE_WAITING_WITHDRAWAL_CONFIRM = "WAITING_WITHDRAWAL_CONFIRM"
         self.STATE_COMPLETED = "COMPLETED"
@@ -150,14 +149,14 @@ class ArbitrageProcess:
         if self.current_state == self.STATE_CHECK:
             self._execute_check()
 
-        elif self.current_state == self.STATE_SELLING_ON_EXCHANGE:
-            self._execute_sell_on_exchange()
+        elif self.current_state == self.STATE_BUYING_ON_EXCHANGE:
+            self._execute_buy_on_exchange()
 
-        elif self.current_state == self.STATE_WAITING_SELL_CONFIRM:
-            self._wait_sell_confirm()
+        elif self.current_state == self.STATE_WAITING_BUY_CONFIRM:
+            self._wait_buy_confirm()
 
-        elif self.current_state == self.STATE_BUYING_ON_CHAIN:
-            self._execute_buy_on_chain()
+        elif self.current_state == self.STATE_SELLING_ON_CHAIN:
+            self._selling_on_chain()
 
         elif self.current_state == self.STATE_WAITING_CHAIN_CONFIRM:
             self._wait_chain_confirm()
@@ -165,9 +164,6 @@ class ArbitrageProcess:
         elif self.current_state == self.STATE_WAITING_EXCHANGE_ROLLBACK:
             self._wait_exchange_rollback()
 
-        # elif self.current_state == "TRANSFERRING_TO_EXCHANGE":
-        #     self._execute_transfer_to_exchange()
-
         elif self.current_state == self.STATE_WAITING_TRANSFER_ARRIVE:
             self._wait_transfer_arrive()
 
@@ -197,28 +193,37 @@ class ArbitrageProcess:
         前置检查,防止低能错误
         """
         try:
-            # step1,檢查交易所的餘額是否夠用
-            # 处理精度
-            pseudo_amount_to_sell = self.exchange_sell_amount.quantize(Decimal('1'), rounding=ROUND_DOWN)
-
-            # 交易所套保余额判断
-            with self.mexc_lock:
-                balances = self.mexc_data['account_info']['balances']
-
-                for balance in balances:
-                    if balance['asset'] == self.coin:
-                        if Decimal(balance['free']) < pseudo_amount_to_sell:
-                            msg = f"交易所剩余{self.coin}: {balance['free']}, 交易所准备卖出:{pseudo_amount_to_sell}, 不能触发套保交易。"
-                            logger.info(msg)
-                            add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
-                            self._set_state(self.STATE_REJECT)
-                            return
-                        else:
-                            msg = f"交易所剩余{self.coin}: {balance['free']}, 交易所准备卖出:{pseudo_amount_to_sell}, 余额校验通过(可以套保)。"
-                            logger.info(msg)
-                            add_state_flow_entry(self.process_item, self.current_state, msg, "success")
-
-                            break
+            # # step1,檢查交易所的餘額是否夠用
+            # # 处理精度
+            # pseudo_amount_to_buy = self.exchange_buy_amount.quantize(Decimal('1'), rounding=ROUND_DOWN)
+            # 
+            # # 交易所套保余额判断
+            # with self.mexc_lock:
+            #     balances = self.mexc_data['account_info']['balances']
+
+            #     for balance in balances:
+            #         if balance['asset'] == self.coin:
+            #             if Decimal(balance['free']) < pseudo_amount_to_buy:
+            #                 msg = f"交易所剩余{self.coin}: {balance['free']}, 交易所准备买入:{pseudo_amount_to_buy}, 不能触发套保交易。"
+            #                 logger.info(msg)
+            #                 add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
+            #                 self._set_state(self.STATE_REJECT)
+            #                 return
+            #             else:
+            #                 msg = f"交易所剩余{self.coin}: {balance['free']}, 交易所准备买入:{pseudo_amount_to_buy}, 余额校验通过(可以套保)。"
+            #                 logger.info(msg)
+            #                 add_state_flow_entry(self.process_item, self.current_state, msg, "success")
+
+            #                 break
+
+            # step1,检查该币对是否有提现权限
+            if not self.WITHDRAW_ENABLE:
+                coin_info_formated = pformat(self.withdraw_info, indent=2)
+                msg = f"{self.coin}不允许提现。\n{coin_info_formated}"
+                logger.info(msg)
+                add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
+                self._set_state(self.STATE_REJECT)
+                return
 
             # step2,估算gas
             logger.info("獲取區塊信息")
@@ -246,7 +251,7 @@ class ArbitrageProcess:
             # step3, 費用與利潤比較
             estimated_eth_value = estimated_eth * self.eth_price
             estimated_eth_value = estimated_eth_value.quantize(Decimal('1e-2'), rounding=ROUND_DOWN)
-            cost = estimated_eth_value + self.WITHDRAW_FEE          # 成本
+            cost = estimated_eth_value + self.WITHDRAW_FEE * self.mexc_price          # 成本
             if self.profit < cost:
                 msg = f"費用判斷不通過! profit: {self.profit}, eth_value:{estimated_eth_value}, eth: {estimated_eth}, eth_price: {self.eth_price}"
                 logger.info(msg)
@@ -257,8 +262,8 @@ class ArbitrageProcess:
             logger.info(msg)
             add_state_flow_entry(self.process_item, self.current_state, msg, "success")
 
-            # step4, 與賬戶eth餘額比對(至少留0.001,不然沒gas了)
-            MARGIN = Decimal(0.001)
+            # step4, 與賬戶eth餘額比對(至少留0.002,不然沒gas了)
+            MARGIN = Decimal(0.002)
             # 暫時鎖住core_data
             with self.core_lock:
                 eth_balance = self.core_data['eth_balance']
@@ -276,7 +281,7 @@ class ArbitrageProcess:
             add_state_flow_entry(self.process_item, self.current_state, msg, "success")
 
             # final, 設定交易狀態,開始交易
-            self._set_state(self.STATE_SELLING_ON_EXCHANGE)
+            self._set_state(self.STATE_BUYING_ON_EXCHANGE)
         except Exception as e:
             exc_traceback = traceback.format_exc()
             msg = f"前置檢查未通過\n{exc_traceback}"
@@ -288,47 +293,47 @@ class ArbitrageProcess:
             # traceback.print_exc()
 
     # 以下是每个状态对应的具体执行函数
-    def _execute_sell_on_exchange(self):
+    def _execute_buy_on_exchange(self):
         """
-        在中心化交易所卖出现货
+        在中心化交易所买入现货
         """
-        msg = "执行:中心化交易所卖出现货..."
+        msg = "执行:中心化交易所买入现货..."
         logger.info(msg)
         add_state_flow_entry(self.process_item, self.current_state, msg, "pending")
         try:
-            # 第一步直接卖出,这个数量用固定数量
-            pseudo_amount_to_sell = self.exchange_sell_amount
+            # 第一步直接买入,这个数量用固定数量
+            pseudo_amount_to_buy = self.exchange_buy_amount
             # 处理精度
-            pseudo_amount_to_sell = pseudo_amount_to_sell.quantize(Decimal('1'), rounding=ROUND_DOWN)
+            pseudo_amount_to_buy = pseudo_amount_to_buy.quantize(Decimal('1'), rounding=ROUND_DOWN)
             
             order_params = {
                 "symbol": self.symbol.replace('_', ''),
-                "side": "SELL",
+                "side": "BUY",
                 "type": "MARKET",
-                "quantity": int(pseudo_amount_to_sell),
+                "quantity": int(pseudo_amount_to_buy),          # 以【幣】的數量進行買入
             }
             order_params_formated = pformat(order_params, indent=2)
             
-            exchange_sell_order = mexc.trade.post_order(order_params)
-            exchange_sell_order_formated = pformat(exchange_sell_order, indent=2)
+            exchange_buy_order = mexc.trade.post_order(order_params)
+            exchange_buy_order_formated = pformat(exchange_buy_order, indent=2)
 
-            msg = f"交易所现货卖出订单已发送 \n params:{order_params_formated} \n rst: {exchange_sell_order_formated}"
-            if 'orderId' not in exchange_sell_order:
+            msg = f"交易所现货买入订单已发送 \n params:{order_params_formated} \n rst: {exchange_buy_order_formated}"
+            if 'orderId' not in exchange_buy_order:
                 logger.error(msg)
                 add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
                 self._set_state(self.STATE_FAILED)
 
                 return
 
-            self.exchange_sell_order_id = exchange_sell_order['orderId']
+            self.exchange_buy_order_id = exchange_buy_order['orderId']
             
             logger.info(msg)
             add_state_flow_entry(self.process_item, self.current_state, msg, "success")
 
-            self._set_state(self.STATE_WAITING_SELL_CONFIRM)
+            self._set_state(self.STATE_WAITING_BUY_CONFIRM)
         except Exception as e:
             exc_traceback = traceback.format_exc()
-            msg = f"交易所现货卖出下单失败\n{exc_traceback}"
+            msg = f"交易所现货买入下单失败\n{exc_traceback}"
             logger.error(msg)
 
             add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
@@ -336,12 +341,12 @@ class ArbitrageProcess:
 
             # traceback.print_exc()
 
-    def _wait_sell_confirm(self):
+    def _wait_buy_confirm(self):
         """
-        等待交易所现货卖出订单确认(完全成交)
+        等待交易所现货买入订单确认(完全成交)
         """
-        exchange_sell_order_id = self.exchange_sell_order_id
-        msg = f"等待交易所现货卖出订单确认:{exchange_sell_order_id}"
+        exchange_buy_order_id = self.exchange_buy_order_id
+        msg = f"等待交易所现货买入订单确认:{exchange_buy_order_id}"
         logger.info(msg)
         add_state_flow_entry(self.process_item, self.current_state, msg, "pending")
 
@@ -352,39 +357,43 @@ class ArbitrageProcess:
             while waiting_times > 0:
                 params = {
                     "symbol": self.symbol.replace('_', ''),
-                    "orderId": exchange_sell_order_id
+                    "orderId": exchange_buy_order_id
                 }
                 order = mexc.trade.get_order(params)
                 last_order = order
 
                 if order['status'] in ["FILLED", "PARTIALLY_CANCELED"]:
+                    # 以实际成交数量为准
+                    self.exchange_buy_amount = Decimal(order['executedQty'])
+
                     money = Decimal(order['cummulativeQuoteQty'])
-                    amount = self.exchange_sell_amount
+                    amount = self.exchange_buy_amount
 
-                    self.sell_price = money / amount
-                    self.sell_price = self.sell_price.quantize(Decimal('1e-16'), rounding=ROUND_DOWN)
+                    self.buy_value = money
+                    self.buy_price = money / amount
+                    self.buy_price = self.buy_price.quantize(Decimal('1e-16'), rounding=ROUND_DOWN)
 
                     order_formated = pformat(order, indent=2)
-                    msg = f"交易所现货卖出订单已完成, 价格:{self.sell_price}, money: {money}\n order: {order_formated}"
+                    msg = f"交易所现货买入订单已完成, 价格:{self.buy_price}, money: {money}\n order: {order_formated}"
                     logger.info(msg)
                     add_state_flow_entry(self.process_item, self.current_state, msg, "success")
 
-                    self.exchange_withdrawal_amount = money
+                    self.exchange_withdrawal_amount = amount
 
-                    self._set_state(self.STATE_BUYING_ON_CHAIN)
+                    self._set_state(self.STATE_SELLING_ON_CHAIN)
                     return
                 else:
                     time.sleep(1)
                     waiting_times = waiting_times - 1
 
             last_order_formated = pformat(last_order, indent=2)
-            msg = f"交易所现货卖出订单失敗, 最後狀態:\n{last_order_formated}。"
+            msg = f"交易所现货买入订单失敗, 最後狀態:\n{last_order_formated}。"
             logger.info(msg)
             add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
             self._set_state(self.STATE_FAILED)
         except Exception as e:
             exc_traceback = traceback.format_exc()
-            msg = f"查询交易所现货卖出订单状态时发生错误\n{exc_traceback}"
+            msg = f"查询交易所现货买入订单状态时发生错误\n{exc_traceback}"
             logger.error(msg)
 
             add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
@@ -392,11 +401,11 @@ class ArbitrageProcess:
 
             # traceback.print_exc()
 
-    def _execute_buy_on_chain(self):
+    def _selling_on_chain(self):
         """
-        在链上执行买入操作
+        在链上执行卖出操作
         """
-        msg = "执行:链上买入操作..."
+        msg = "执行:链上卖出操作..."
         logger.info(msg)
         add_state_flow_entry(self.process_item, self.current_state, msg, "pending")
         try:
@@ -404,13 +413,16 @@ class ArbitrageProcess:
             with self.core_lock:
                 self.tx['nonce'] = self.core_data['nonce']
             
-            # 调用链上客户端执行买入交易
+            # 调用链上客户端执行卖出交易
             signed_tx = web3._sign(self.tx, self.gas_limit_multiplier)
             self.chain_tx_hash = web3.w3.to_hex(signed_tx.hash)
             try:
+                # 主要节点先发交易
                 web3.w3.eth.send_raw_transaction(signed_tx.raw_transaction)
+                # 使用备用节点再发一次交易
+                web3_backup.w3.eth.send_raw_transaction(signed_tx.raw_transaction)
             except Exception as e:
-                msg = f"据反饋說链上买入失败:{e}, 交易哈希:{self.chain_tx_hash}"
+                msg = f"据反饋說链上卖出失败:{e}, 交易哈希:{self.chain_tx_hash}"
                 logger.error(msg)
                 add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
 
@@ -452,8 +464,8 @@ class ArbitrageProcess:
         logger.info(msg)
         add_state_flow_entry(self.process_item, self.current_state, msg, "pending")
         try:
-            # 給300秒時間進行確認
-            waiting_times = 300
+            # 給120秒時間進行確認
+            waiting_times = 120
             while waiting_times > 0:
                 with self.pending_lock:
                     tx_details = copy.deepcopy(self.pending_data[chain_tx_hash]['tx_details'])
@@ -491,87 +503,24 @@ class ArbitrageProcess:
                 from_token_amount = Decimal(from_token_details['amount'])
                 from_token_amount_human = from_token_amount / (Decimal(10) ** self.from_token_decimal)
                 from_token_amount_human = from_token_amount_human.quantize(Decimal('1e-2'), rounding=ROUND_DOWN)
-                self.chain_buy_amount = from_token_amount_human # 存储实际买入数量
 
                 to_token_amount = Decimal(to_token_details['amount'])
                 to_token_amount_human = to_token_amount / (Decimal(10) ** self.to_token_decimal)
 
-                self.buy_price = from_token_amount_human / to_token_amount_human
-                self.buy_price = self.buy_price.quantize(Decimal('1e-16'), rounding=ROUND_DOWN)               
+                self.sell_value = to_token_amount_human
+                self.sell_price = from_token_amount_human / to_token_amount_human
+                self.sell_price = self.sell_price.quantize(Decimal('1e-16'), rounding=ROUND_DOWN)               
 
                 # 交易預估利潤百分比計算
                 rate = self.sell_price / self.buy_price
                 rate = rate.quantize(Decimal('1e-4'), rounding=ROUND_DOWN)
 
-                msg = f"【比率{rate}】。用{from_token_amount_human}买入{to_token_amount_human},价格{self.buy_price}。"
+                msg = f"【比率{rate}】。用{from_token_amount_human}卖出{to_token_amount_human},价格{self.sell_price}。"
                 logger.info(msg)
                 add_state_flow_entry(self.process_item, self.current_state, msg, "success")
 
-                # 判斷快速二賣條件
-                diff = int(to_token_amount_human - self.exchange_sell_amount)
-                value = diff * self.sell_price
-                value = value.quantize(Decimal('1e-4'), rounding=ROUND_DOWN)
-                if value > 2:
-                    msg = f"滿足二賣條件,{diff}*{self.sell_price} = {value}"
-                    logger.info(msg)
-                    add_state_flow_entry(self.process_item, self.current_state, msg, "success")
-
-                    order_params = {
-                        "symbol": self.symbol.replace('_', ''),
-                        "side": "SELL",
-                        "type": "MARKET",
-                        "quantity": int(diff),
-                    }
-                    order_params_formated = pformat(order_params, indent=2)
-                    exchange_sell_order = mexc.trade.post_order(order_params)
-                    exchange_sell_order_formated = pformat(exchange_sell_order, indent=2)
-
-                    if 'orderId' not in exchange_sell_order:
-                        msg = f"交易所现货二卖下单失败 \n params:{order_params_formated} \n rst: {exchange_sell_order_formated}"
-                        logger.error(msg)
-                        add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
-                    else:
-                        oid = exchange_sell_order['orderId']
-
-                        # 查询交易所订单状态
-                        waiting_times_inner = 30
-                        last_order = None
-                        while waiting_times_inner > 0:
-                            params = {
-                                "symbol": self.symbol.replace('_', ''),
-                                "orderId": oid
-                            }
-                            order = mexc.trade.get_order(params)
-                            order_formated = pformat(order, indent=2)
-                            last_order = order
-
-                            if order['status'] in ["FILLED", "PARTIALLY_CANCELED"]:
-                                money = Decimal(order['cummulativeQuoteQty'])
-
-                                msg = f"交易所现货二卖订单已完成, money: {money}。\n order: {order_formated}"
-                                logger.info(msg)
-                                add_state_flow_entry(self.process_item, self.current_state, msg, "success")
-
-                                self.exchange_withdrawal_amount = self.exchange_withdrawal_amount + money
-
-                                break
-                            else:
-                                time.sleep(1)
-                                waiting_times_inner = waiting_times_inner - 1
-
-                        if waiting_times_inner <= 0:
-                            last_order_formated = pformat(last_order, indent=2)
-
-                            msg = f"交易所现货二卖订单失敗, 最後狀態:{last_order_formated}。"
-                            logger.info(msg)
-                            add_state_flow_entry(self.process_item, self.current_state, msg, "fail")     
-                else:
-                    msg = f"不滿足二賣條件,{diff}*{self.sell_price} = {value}"
-                    logger.info(msg)
-                    add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
-
                 # 計算實際利潤
-                actual_profit = value
+                value = self.sell_value - self.buy_value
                 actual_gas_price = Decimal(tx_details['gasPrice'])
                 actual_gas_price_gwei = actual_gas_price / Decimal('1e9')
                 actual_gas_price_gwei = actual_gas_price_gwei.quantize(Decimal('1e-9'), rounding=ROUND_DOWN)
@@ -582,7 +531,7 @@ class ArbitrageProcess:
                 actual_fee_used = actual_eth * self.eth_price
                 actual_fee_used = actual_fee_used.quantize(Decimal('1e-4'), rounding=ROUND_DOWN)
 
-                actual_profit = value - actual_fee_used - self.WITHDRAW_FEE
+                actual_profit = value - actual_fee_used - self.WITHDRAW_FEE * self.mexc_price
 
                 msg = f"【最終利潤】{actual_profit}{self.base_coin}(已扣除所有手續費、滑點)\
                 \n鏈上ETH使用: {actual_eth}({actual_fee_used} USD), gas_price: {actual_gas_price_gwei} GWEI, gas_used: {actual_gas_used}\
@@ -591,11 +540,11 @@ class ArbitrageProcess:
                 logger.info(msg)
                 add_state_flow_entry(self.process_item, self.current_state, msg, "success")
 
-                self._set_state(self.STATE_COMPLETED)
+                self._set_state(self.STATE_TRANSFERRING_TO_CHAIN)
 
                 break
             
-            # 如果300秒都沒確認成功,該交易大概率沒有上鏈
+            # 如果120秒都沒確認成功,該交易大概率沒有上鏈
             if waiting_times <= 0:
                 with self.pending_lock:
                     response = copy.deepcopy(self.pending_data[chain_tx_hash]['response'])
@@ -618,54 +567,54 @@ class ArbitrageProcess:
         """
         市价进行交易所交易回滚
         """
-        msg = "执行:中心化交易所买入现货回滚..."
+        msg = "执行:中心化交易所卖出现货回滚..."
         logger.info(msg)
         add_state_flow_entry(self.process_item, self.current_state, msg, "pending")
         try:
             # 使用预提现数量进行回滚
-            pseudo_amount_to_buy = Decimal(self.exchange_withdrawal_amount)
+            pseudo_amount_to_sell = Decimal(self.exchange_buy_amount)
             # 处理精度
-            pseudo_amount_to_buy = pseudo_amount_to_buy.quantize(Decimal('1'), rounding=ROUND_DOWN)
+            pseudo_amount_to_sell = pseudo_amount_to_sell.quantize(Decimal('1'), rounding=ROUND_DOWN)
 
-            # 交易所U余额判断
+            # 交易所余额判断
             with self.mexc_lock:
                 balances = self.mexc_data['account_info']['balances']
                 for balance in balances:
-                    if balance['asset'] == self.base_coin:
-                        pseudo_amount_to_buy = min(Decimal(balance['free']), pseudo_amount_to_buy)
+                    if balance['asset'] == self.coin:
+                        pseudo_amount_to_sell = min(Decimal(balance['free']), pseudo_amount_to_sell)
 
-                        if pseudo_amount_to_buy < Decimal('10'):
-                            msg = f"交易所剩余{self.base_coin}: {balance['free']}, 小于10, 不能触发回滚交易。"
+                        if pseudo_amount_to_sell * self.mexc_price < Decimal('10'):
+                            msg = f"交易所剩余{self.coin}: {balance['free']}, 小于10, 不能触发回滚交易。"
                             logger.info(msg)
                             add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
                             self._set_state(self.STATE_FAILED)
                             return
                         else:
-                            msg = f"交易所剩余{self.base_coin}: {balance['free']}, 交易所准备使用:{pseudo_amount_to_buy}, 余额校验通过(可以回滚)。"
+                            msg = f"交易所剩余{self.coin}: {balance['free']}, 交易所准备使用:{pseudo_amount_to_sell}, 余额校验通过(可以回滚)。"
                             logger.info(msg)
                             add_state_flow_entry(self.process_item, self.current_state, msg, "success")
                             break
             
             order_params = {
                 "symbol": self.symbol.replace('_', ''),
-                "side": "BUY",
+                "side": "SELL",
                 "type": "MARKET",
-                "quoteOrderQty": int(pseudo_amount_to_buy),
+                "quantity": int(pseudo_amount_to_sell),
             }
             order_params_formated = pformat(order_params, indent=2)
-            exchange_buy_order = mexc.trade.post_order(order_params)
-            exchange_buy_order_formated = pformat(exchange_buy_order, indent=2)
-            if 'orderId' not in exchange_buy_order:
-                msg = f"【回滚】交易所现货买入下单失败\n params:{order_params_formated}\norder: {exchange_buy_order_formated}"
+            exchange_sell_order = mexc.trade.post_order(order_params)
+            exchange_sell_order_formated = pformat(exchange_sell_order, indent=2)
+            if 'orderId' not in exchange_sell_order:
+                msg = f"【回滚】交易所现货卖出下单失败\n params:{order_params_formated}\norder: {exchange_sell_order_formated}"
                 logger.error(msg)
                 add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
                 self._set_state("FAILED")
 
                 return
 
-            exchange_buy_order_id = exchange_buy_order['orderId']
+            exchange_sell_order_id = exchange_sell_order['orderId']
             
-            msg = f"【回滚】交易所现货买入订单已发送, 订单ID: {exchange_buy_order_id}"
+            msg = f"【回滚】交易所现货卖出订单已发送, 订单ID: {exchange_sell_order_id}"
             logger.info(msg)
             add_state_flow_entry(self.process_item, self.current_state, msg, "success")
 
@@ -675,7 +624,7 @@ class ArbitrageProcess:
             while True:
                 params = {
                     "symbol": self.symbol.replace('_', ''),
-                    "orderId": exchange_buy_order_id
+                    "orderId": exchange_sell_order_id
                 }
                 order = mexc.trade.get_order(params)
                 order_formated = pformat(order, indent=2)
@@ -683,11 +632,11 @@ class ArbitrageProcess:
 
                 if order['status'] == "FILLED":
                     money = Decimal(order['cummulativeQuoteQty'])
-                    amount = self.exchange_sell_amount
+                    amount = self.exchange_buy_amount
                     price = money / amount
                     price = price.quantize(Decimal('1e-8'), rounding=ROUND_DOWN)
 
-                    msg = f"【回滚】交易所现货买入订单已完全成交, 价格:{price}。\norder: {order_formated}"
+                    msg = f"【回滚】交易所现货卖出订单已完全成交, 价格:{price}。\norder: {order_formated}"
 
                     logger.info(msg)
                     add_state_flow_entry(self.process_item, self.current_state, msg, "success")
@@ -702,7 +651,7 @@ class ArbitrageProcess:
                 waiting_times = waiting_times - 1
             
             last_query_rst_formated = pformat(last_query_rst, indent=2)
-            msg = f"【回滚】回滚交易订单查询超时, 订单ID: {exchange_buy_order_id}\n最终状态:{last_query_rst_formated}"
+            msg = f"【回滚】回滚交易订单查询超时, 订单ID: {exchange_sell_order_id}\n最终状态:{last_query_rst_formated}"
             logger.info(msg)
             add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
 
@@ -717,73 +666,106 @@ class ArbitrageProcess:
 
             # traceback.print_exc()
 
-# 伪代码示例:如何使用这个类
-if __name__ == "__main__":
-    import ok_chain_client
-    import decimal
-    import pprint
-
-    CHAIN_ID = 1
-    FROM_TOKEN = '0xdAC17F958D2ee523a2206206994597C13D831ec7'
-    FROM_TOKEN_AMOUNT_HUMAM = Decimal('20')
-    FROM_TOKEN_DECIMAL = 6
-    TO_TOKEN = '0xf816507E690f5Aa4E29d164885EB5fa7a5627860'
-    USER_WALLET = ''
-    USER_EXCHANGE_WALLET = '0xc71835a042F4d870B0F4296cc89cAeb921a9f3DA'
-    SYMBOL = "RATO_USDT"
-
-    # 询价,注意!!!这里直接把交易所地址当收款方,省去transfer的流程
-    data = ok_chain_client.swap(CHAIN_ID, 
-                                FROM_TOKEN_AMOUNT_HUMAM * (10 ** FROM_TOKEN_DECIMAL), 
-                                FROM_TOKEN, 
-                                TO_TOKEN, 
-                                1, 
-                                USER_WALLET,
-                                USER_EXCHANGE_WALLET,  # 这里直接把交易所地址当收款方,省去transfer的流程!!!
-                                )
-    if data.get('code') != '0' or not data.get('data'):
-            pprint.pprint(data)
-            pprint.pprint({
-                "error": f"OK API错误({1}) - Code:{data.get('code', 'N/A')}, Msg:{data.get('msg', data.get('message', 'N/A')) if isinstance(data, dict) else '格式错误'}"})
-
-            raise Exception("") 
-    d = data['data'][0]
-    tx = d['tx']
-    router_result = d['routerResult']
-    in_dec, out_dec = int(router_result['fromToken']['decimal']), int(router_result['toToken']['decimal'])
-    atomic_in_base, atomic_out_target = Decimal(router_result['fromTokenAmount']), Decimal(router_result['toTokenAmount'])
-    human_in_base = atomic_in_base / (10 ** in_dec)
-    human_out_target = atomic_out_target / (10 ** out_dec)
-
-    FROM_TOKEN_AMOUNT_HUMAM = human_in_base
-    TO_TOKEN_AMOUNT_HUMAM = human_out_target
-
-    pprint.pprint(tx)
-
-    # 套利流程执行
-    process_item = {
-        "stateFlow": [], # 状态流转记录
-    }
-    ap = ArbitrageProcess(tx, 2, 1.2, 
-                                        FROM_TOKEN, TO_TOKEN, 
-                                        FROM_TOKEN_AMOUNT_HUMAM, TO_TOKEN_AMOUNT_HUMAM,
-                                        USER_EXCHANGE_WALLET, USER_WALLET,
-                                        SYMBOL, process_item)
-
-    # 一般都是从这个流程开始,测试时可以稍作修改、测试后续流程
-    ap._set_state(ap.SELLING_ON_EXCHANGE)
-
-    # 在主循环中周期性调用 run_arbitrage_step
-    while ap.current_state != "COMPLETED" and ap.current_state != "FAILED":
-        ap.run_arbitrage_step()
-
-        if ap.current_state == ap.STATE_WAITING_TRANSFER_ARRIVE or ap.current_state == ap.STATE_WAITING_WITHDRAWAL_CONFIRM:
-            time.sleep(10)
-        # else:
-        #     time.sleep(1)
-
-    logger.info(process_item)
-    if ap.current_state == "COMPLETED":
-        logger.info("套利流程执行成功!")
-    else:
-        logger.info("套利流程执行失败!")
+    def _execute_transfer_to_chain(self):
+        """
+        将交易后获得的计价资产(例如USDT)转账回链上
+        """
+        msg = "执行:交易所计价资产转账回链上..."
+        logger.info(msg)
+        add_state_flow_entry(self.process_item, self.current_state, msg, "pending")
+
+        try:
+            pseudo_withdrawal_amount = str(int(float(self.exchange_buy_amount)))
+
+            withdrawal_params = {
+                'coin': self.coin,
+                'netWork': 'ETH',
+                'address': self.user_wallet,
+                'amount': pseudo_withdrawal_amount
+            }
+            withdrawal_params_formated = pformat(withdrawal_params, indent=2)
+            withdrawal_rst = mexc.wallet.post_withdraw(withdrawal_params)
+            withdrawal_rst_formated = pformat(withdrawal_rst, indent=2)
+            if "id" not in withdrawal_rst:
+                msg = f"交易所提现失败\n參數: {withdrawal_params_formated}\n響應: {withdrawal_rst_formated}"
+                logger.error(msg)
+                add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
+
+                self._set_state(self.STATE_FAILED)
+            else:
+                self.exchange_withdrawal_id = withdrawal_rst["id"]
+                msg = f"交易所提现已发送\n{withdrawal_rst_formated}"
+                logger.info(msg)
+                add_state_flow_entry(self.process_item, self.current_state, msg, "success")
+
+                self._set_state(self.STATE_WAITING_WITHDRAWAL_CONFIRM)
+        except Exception as e:
+            msg = f"转账回链上失败: {e}"
+            logger.error(msg)
+            add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
+
+            self._set_state(self.STATE_FAILED)
+
+            traceback.print_exc()
+
+    def _wait_withdrawal_confirm(self):
+        """
+        等待交易所提现到链上确认
+        """
+        exchange_withdrawal_id = self.exchange_withdrawal_id
+
+        msg = f"等待交易所提现确认:{exchange_withdrawal_id}"
+        logger.info(msg)
+        add_state_flow_entry(self.process_item, self.current_state, msg, "pending")
+        try:
+            is_arrived = False
+
+            # 最多等待30分钟
+            waiting_times = 60
+            last_deposit_state = None
+            last_deposit_state_formated = None
+            while waiting_times > 0:
+                with self.mexc_lock:
+                    withdraw_list = copy.deepcopy(self.mexc_data['withdraw_list'])
+
+                if not isinstance(withdraw_list, list):
+                    msg = f"查询交易所提现状态时发生错误:{withdraw_list}"
+                    logger.error(msg)
+                    add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
+
+                    self._set_state("FAILED")
+                    return
+
+                for withdrawal in withdraw_list:
+                    if withdrawal['id'] != exchange_withdrawal_id:
+                        continue
+
+                    last_deposit_state = withdrawal
+                    last_deposit_state_formated = pformat(last_deposit_state, indent=2)
+
+                    if withdrawal['status'] == 7:
+                        is_arrived = True
+
+                if is_arrived:
+                    msg = f"提现请求已上链:\n{last_deposit_state_formated}"
+                    logger.info(msg)
+                    add_state_flow_entry(self.process_item, self.current_state, msg, "success")
+
+                    self._set_state(self.STATE_COMPLETED)
+                    return
+                
+                time.sleep(30)
+                waiting_times = waiting_times - 1
+
+            msg = f"等待提现到账超时(超过30分钟):\n{last_deposit_state_formated}"
+            logger.error(msg)
+            add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
+
+            self._set_state(self.STATE_FAILED)
+        except Exception as e:
+            msg = f"查询交易所提现状态时发生错误:{e}"
+            logger.error(msg)
+            add_state_flow_entry(self.process_item, self.current_state, msg, "fail")
+            self._set_state(self.STATE_FAILED)
+
+            traceback.print_exc()

+ 3 - 0
toto.readme

@@ -48,8 +48,11 @@
 2025-06-25
 [-] 解决日志文件锁问题
 [-] 备用节点广播
+
+2025-06-26
 [ ] 另一個方向
 
 有時間再做
 [-] zeus昨晚上有一个状态识别bug,导致单边(因为精度问题导致)
 [ ] approve自動
+[ ] 交易所价格、数量精度