Browse Source

結構整理。

skyfffire 5 months ago
parent
commit
d66aa784e4
4 changed files with 69 additions and 79 deletions
  1. 15 18
      as.py
  2. 48 57
      erc20_to_mexc_first_sell.py
  3. 5 3
      signal/price_checker.py
  4. 1 1
      web3_py_client.py

+ 15 - 18
as.py

@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 
-import decimal
+from decimal import Decimal
 import threading
 import uuid # 用于生成唯一的流程ID
 import time
@@ -26,7 +26,7 @@ USER_EXCHANGE_WALLET = wallet["user_exchange_wallet"]
 
 # 该代币最后一次执行套利的区块信息 (如果需要防止过于频繁的同类套利,不然变成砸盘、拉盘的了)
 last_process_info = {} # 示例: {"RATO_USDT": 0}
-MIN_BLOCKS_BETWEEN_ARB = decimal.Decimal(5) # 在重试相同交易对之前等待几个区块
+MIN_BLOCKS_BETWEEN_ARB = Decimal(5) # 在重试相同交易对之前等待几个区块
 
 # --- 全局状态和锁 ---
 processing_list = [] # 正在处理的任务列表
@@ -106,7 +106,8 @@ def arbitrage_process_flow(process_item):
     TO_TOKEN = process_item['toToken']
     FROM_TOKEN_AMOUNT_HUMAM = process_item['fromTokenAmountHuman']
     TO_TOKEN_AMOUNT_HUMAM = process_item['toTokenAmountHuman']
-    profit = float(process_item['profit'])
+    profit = Decimal(process_item['profit'])
+    profitLimit = Decimal(process_item['profitLimit'])
     USER_EXCHANGE_WALLET = process_item['userExchangeWallet']
     USER_WALLET = process_item['userWallet']
     SYMBOL = process_item['symbol']
@@ -114,19 +115,15 @@ def arbitrage_process_flow(process_item):
 
 
     gas_price_multiplier = 1
-    if profit > 2:
-        gas_price_multiplier = 1.1
-    elif profit > 5:
+    if profit > Decimal(2) * profitLimit:
+        gas_price_multiplier = 1.2
+    elif profit > Decimal(5) * profitLimit:
         gas_price_multiplier = 1.5
-    elif profit > 10:
+    elif profit > Decimal(10) * profitLimit:
         gas_price_multiplier = 2
     gas_limit_multiplier = 1.2
 
-    ap = erc20_to_mexc_first_sell.ArbitrageProcess(tx, gas_limit_multiplier, gas_price_multiplier, 
-                                                           FROM_TOKEN, TO_TOKEN, 
-                                                           FROM_TOKEN_AMOUNT_HUMAM, EXCHANGE_OUT_AMOUNT,
-                                                           USER_EXCHANGE_WALLET, USER_WALLET,
-                                                           SYMBOL, process_item)
+    ap = erc20_to_mexc_first_sell.ArbitrageProcess(tx, gas_limit_multiplier, gas_price_multiplier, process_item)
 
     # 一般都是从这个流程开始,测试时可以稍作修改、测试后续流程
     ap._set_state(ap.STATE_CHECK)
@@ -155,12 +152,12 @@ def handle_submit_process():
             return jsonify({"error": f"缺少字段: {field}"}), 400
 
     try:
-        profit = decimal.Decimal(str(data['profit']))                                   # 利润
-        profit_limit = decimal.Decimal(str(data['profitLimit']))                        # 利润阈值
-        from_token_amount_human = decimal.Decimal(str(data['fromTokenAmountHuman']))    # fromToken 的人类可读数量
-        from_token_decimal = decimal.Decimal(str(data['fromTokenDecimal']))             # fromToken 的小数位数
-        to_token_amount_human = decimal.Decimal(str(data['toTokenAmountHuman']))        # toToken 的人类可读数量
-        exchange_out_amount = decimal.Decimal(str(data['exchangeOutAmount']))           # 交易所需要卖出的数量
+        profit = Decimal(str(data['profit']))                                   # 利润
+        profit_limit = Decimal(str(data['profitLimit']))                        # 利润阈值
+        from_token_amount_human = Decimal(str(data['fromTokenAmountHuman']))    # fromToken 的人类可读数量
+        from_token_decimal = Decimal(str(data['fromTokenDecimal']))             # fromToken 的小数位数
+        to_token_amount_human = Decimal(str(data['toTokenAmountHuman']))        # toToken 的人类可读数量
+        exchange_out_amount = Decimal(str(data['exchangeOutAmount']))           # 交易所需要卖出的数量
     except (decimal.InvalidOperation, ValueError) as e:
         return jsonify({"error": f"请求体中包含无效的小数/整数值: {e}"}), 400
 

+ 48 - 57
erc20_to_mexc_first_sell.py

@@ -12,11 +12,7 @@ mexc = MexcClient()
 logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
 
 class ArbitrageProcess:
-    def __init__(self, tx, gas_limit_multiplier, gas_price_multiplier, 
-                 from_token, to_token, 
-                 from_token_amount_human, exchange_out_amount,
-                 user_exchange_wallet, user_wallet,
-                 symbol, process_item):
+    def __init__(self, tx, gas_limit_multiplier, gas_price_multiplier, process_item):
         """
         初始化套利流程
 
@@ -35,32 +31,30 @@ class ArbitrageProcess:
 
         self.gas_limit_multiplier = gas_limit_multiplier
         self.gas_price_multiplier = gas_price_multiplier
-        self.from_token_addr = from_token
-        self.to_token_addr = to_token
-        self.user_exchange_wallet = user_exchange_wallet
-        self.user_wallet = user_wallet
-        self.symbol = symbol
+
+        self.from_token_addr = process_item['fromToken']
+        self.to_token_addr = process_item['toToken']
+        self.user_exchange_wallet = process_item['userExchangeWallet']
+        self.user_wallet = process_item['userWallet']
+        self.symbol = process_item['symbol']
+
         self.coin = symbol.split('_')[0]
         self.base_coin = symbol.split('_')[1]
         self.process_item = process_item
 
-        self.sell_price = Decimal(0)
-        self.buy_price = Decimal(0)
 
         # 存储当前套利交易的细节信息,例如买入数量、价格等
-        self.arbitrage_details = {
-            "chain_buy_tx_hash": None,                                          # 链上买入的tx hash
-            "chain_usdt_use":  Decimal(from_token_amount_human),                # 链上usdt减少量(使用量), todo, 暂用固定值代替
-            "chain_amount_before_trade": 0,
-            "chain_amount_after_trade": 0,
-            "chain_buy_amount": Decimal('0'),                                   # 链上币增加量(购入量), todo, 暂用即时余额代替
-            "chain_buy_price": None,                                            # 链上购入价, todo
-            "chain_withdrawal_tx_hash": None,                                   # 链上转入交易所的tx
-            "exchange_out_amount": Decimal(exchange_out_amount),                # 交易所卖出量
-            "exchange_sell_order_id": None,                                     # 交易所卖出id
-            "exchange_withdraw_id": None,                                       # 交易所提现id
-            "exchange_withdraw_amount": None,                                   # 交易所提现数量
-        } 
+        self.sell_price = Decimal(0)
+        self.buy_price = Decimal(0)
+        self.chain_buy_tx_hash = None                                           # 链上买入的tx hash
+        self.chain_usdt_use = Decimal(process_item['fromTokenAmountHuman'])     # 链上usdt减少量(使用量)
+        self.chain_amount_before_trade = Decimal(0)
+        self.chain_amount_after_trade = Decimal(0)
+        self.chain_buy_amount = Decimal(0)                                      # 链上币增加量(购入量), todo, 暂用即时余额代替
+        self.exchange_sell_amount = Decimal(process_item['exchangeOutAmount']), # 交易所卖出量
+        self.exchange_sell_order_id = None                                      # 交易所卖出id
+        self.exchange_withdraw_id = None                                        # 交易所提现id
+        self.exchange_withdraw_amount = None                                    # 交易所提现数量
 
         # 定义可能的状态
         self.STATES = [
@@ -145,7 +139,7 @@ class ArbitrageProcess:
              self._execute_transfer_to_chain()
 
         elif self.current_state == self.STATE_WAITING_WITHDRAWAL_CONFIRM:
-             self._wait_withdrawal_confirm()
+             self._wait_withdraw_confirm()
 
         elif self.current_state == self.STATE_COMPLETED:
             msg = "套利流程成功完成!"
@@ -168,7 +162,7 @@ class ArbitrageProcess:
         """
         try:
             # step1,檢查交易所的餘額是否夠用
-            pseudo_amount_to_sell = self.arbitrage_details["exchange_out_amount"]
+            pseudo_amount_to_sell = self.exchange_sell_amount
             # 处理精度
             pseudo_amount_to_sell = pseudo_amount_to_sell.quantize(Decimal('1'), rounding=ROUND_DOWN)
 
@@ -246,7 +240,7 @@ class ArbitrageProcess:
         add_state_flow_entry(self.process_item, self.current_state, msg, "pending")
         try:
             # 第一步直接卖出,这个数量用固定数量
-            pseudo_amount_to_sell = self.arbitrage_details["exchange_out_amount"]
+            pseudo_amount_to_sell = self.exchange_sell_amount
             # 处理精度
             pseudo_amount_to_sell = pseudo_amount_to_sell.quantize(Decimal('1'), rounding=ROUND_DOWN)
             
@@ -266,13 +260,12 @@ class ArbitrageProcess:
 
                 return
 
-            exchange_sell_order_id = exchange_sell_order['orderId']
+            self.exchange_sell_order_id = exchange_sell_order['orderId']
             
-            msg = f"交易所现货卖出订单已发送, 订单ID: {exchange_sell_order_id}"
+            msg = f"交易所现货卖出订单已发送, 订单ID: {self.exchange_sell_order_id}"
             logging.info(msg)
             add_state_flow_entry(self.process_item, self.current_state, msg, "success")
 
-            self.arbitrage_details["exchange_sell_order_id"] = exchange_sell_order_id
             self._set_state(self.STATE_WAITING_SELL_CONFIRM)
         except Exception as e:
             msg = f"交易所现货卖出下单失败:{e}"
@@ -284,7 +277,7 @@ class ArbitrageProcess:
         """
         等待交易所现货卖出订单确认(完全成交)
         """
-        exchange_sell_order_id = self.arbitrage_details["exchange_sell_order_id"]
+        exchange_sell_order_id = self.exchange_sell_order_id
         msg = f"等待交易所现货卖出订单确认:{exchange_sell_order_id}"
         logging.info(msg)
         add_state_flow_entry(self.process_item, self.current_state, msg, "pending")
@@ -303,7 +296,7 @@ class ArbitrageProcess:
 
                 if order['status'] in ["FILLED", "PARTIALLY_CANCELED"]:
                     money = Decimal(order['cummulativeQuoteQty'])
-                    amount = self.arbitrage_details["exchange_out_amount"]
+                    amount = self.exchange_sell_amount
 
                     self.sell_price = money / amount
                     self.sell_price = self.sell_price.quantize(Decimal('1e-8'), rounding=ROUND_DOWN)
@@ -312,7 +305,7 @@ class ArbitrageProcess:
                     logging.info(msg)
                     add_state_flow_entry(self.process_item, self.current_state, msg, "success")
 
-                    self.arbitrage_details["exchange_withdraw_amount"] = order['cummulativeQuoteQty']
+                    self.exchange_withdraw_amount = order['cummulativeQuoteQty']
 
                     self._set_state(self.STATE_BUYING_ON_CHAIN)
                     return
@@ -338,18 +331,17 @@ class ArbitrageProcess:
         logging.info(msg)
         add_state_flow_entry(self.process_item, self.current_state, msg, "pending")
         try:                
-            self.arbitrage_details["chain_amount_before_trade"] = web3.get_erc20_balance(self.to_token_addr, self.user_exchange_wallet)
+            self.chain_amount_before_trade = web3.get_erc20_balance(self.to_token_addr, self.user_exchange_wallet)
             # 调用链上客户端执行买入交易
-            chain_buy_tx_hash = web3._sign_and_send_transaction(
+            self.chain_buy_tx_hash = web3._sign_and_send_transaction(
                 self.tx,
                 self.gas_limit_multiplier
             )
 
             # 交易成功
-            msg = f"链上买入交易已发送,交易哈希:{chain_buy_tx_hash}"
+            msg = f"链上买入交易已发送,交易哈希:{self.chain_buy_tx_hash}"
             logging.info(msg)
             add_state_flow_entry(self.process_item, self.current_state, msg, "success")
-            self.arbitrage_details["chain_buy_tx_hash"] = chain_buy_tx_hash
             self._set_state(self.STATE_WAITING_CHAIN_CONFIRM)
 
         except Exception as e:
@@ -363,7 +355,7 @@ class ArbitrageProcess:
         等待链上交易确认
         """
 
-        hash = self.arbitrage_details["chain_buy_tx_hash"]
+        hash = self.chain_buy_tx_hash
         msg = f"等待链上交易确认:{hash}"
         logging.info(msg)
         add_state_flow_entry(self.process_item, self.current_state, msg, "pending")
@@ -377,17 +369,17 @@ class ArbitrageProcess:
                 # TODO 卡這裏了 這個方案不太好啊,要不直接獲取交易所充值信息得了
                 actual_buy_amount = Decimal(0)
                 while True:
-                    self.arbitrage_details["chain_amount_after_trade"] = web3.get_erc20_balance(self.to_token_addr, self.user_exchange_wallet)
+                    self.chain_amount_after_trade = web3.get_erc20_balance(self.to_token_addr, self.user_exchange_wallet)
                     
-                    actual_buy_amount = self.arbitrage_details["chain_amount_after_trade"] - self.arbitrage_details["chain_amount_before_trade"]
+                    actual_buy_amount = self.chain_amount_after_trade - self.chain_amount_before_trade
                     if actual_buy_amount > Decimal(0):
                         break
                     
                     time.sleep(1)
 
                 buy_amount_human = actual_buy_amount.quantize(Decimal('1e-2'), rounding=ROUND_DOWN)
-                sell_amount_human = self.arbitrage_details["chain_usdt_use"]
-                self.arbitrage_details["chain_buy_amount"] = buy_amount_human # 存储实际买入数量
+                sell_amount_human = self.chain_usdt_use
+                self.chain_buy_amount = buy_amount_human # 存储实际买入数量
 
                 self.buy_price = sell_amount_human / buy_amount_human
                 self.buy_price = self.buy_price.quantize(Decimal('1e-8'), rounding=ROUND_DOWN)
@@ -420,7 +412,7 @@ class ArbitrageProcess:
         add_state_flow_entry(self.process_item, self.current_state, msg, "pending")
         try:
             # 使用预提现数量进行回滚
-            pseudo_amount_to_buy = Decimal(self.arbitrage_details["exchange_withdraw_amount"])
+            pseudo_amount_to_buy = Decimal(self.exchange_withdraw_amount)
             # 处理精度
             pseudo_amount_to_buy = pseudo_amount_to_buy.quantize(Decimal('1'), rounding=ROUND_DOWN)
 
@@ -477,7 +469,7 @@ class ArbitrageProcess:
 
                 if order['status'] == "FILLED":
                     money = Decimal(order['cummulativeQuoteQty'])
-                    amount = self.arbitrage_details["exchange_out_amount"]
+                    amount = self.exchange_sell_amount
                     price = money / amount
                     price = price.quantize(Decimal('1e-8'), rounding=ROUND_DOWN)
 
@@ -538,7 +530,7 @@ class ArbitrageProcess:
                         pending_amount = pending_amount + Decimal(deposit['amount'])
 
                     # 檢查到沒到列表中
-                    if deposit['transHash'] != self.arbitrage_details['chain_buy_tx_hash']:
+                    if deposit['transHash'] != self.chain_buy_tx_hash:
                         continue
                     last_deposit_state = deposit
                     is_list = True
@@ -553,10 +545,10 @@ class ArbitrageProcess:
                             asset_balance = Decimal(balance['free'])
 
                     # 交易所賣出餘額
-                    exchange_out_amount = self.arbitrage_details["exchange_out_amount"]
+                    exchange_sell_amount = self.exchange_sell_amount
                     
                     # 最終判斷
-                    if exchange_out_amount + asset_balance > pending_amount:
+                    if exchange_sell_amount + asset_balance > pending_amount:
                         msg = f"【flash】资产可以進行快速提現。{last_deposit_state}"
                         logging.info(msg)
                         add_state_flow_entry(self.process_item, self.current_state, msg, "success")
@@ -573,7 +565,7 @@ class ArbitrageProcess:
             while waiting_times > 0:
                 deposit_list = mexc.wallet.get_deposit_list()
                 for deposit in deposit_list:
-                    if deposit['transHash'] != self.arbitrage_details['chain_buy_tx_hash']:
+                    if deposit['transHash'] != self.chain_buy_tx_hash:
                         continue
 
                     last_deposit_state = deposit
@@ -619,7 +611,7 @@ class ArbitrageProcess:
                 # balances = mexc.trade.get_account_info()['balances']
                 # for balance in balances:
                 #     if balance['asset'] == 'USDT':
-            pseudo_withdraw_amount = str(int(float(self.arbitrage_details["exchange_withdraw_amount"])))
+            pseudo_withdraw_amount = str(int(float(self.exchange_withdraw_amount)))
 
             withdraw_params = {
                 'coin': 'USDT',
@@ -633,13 +625,12 @@ class ArbitrageProcess:
                 logging.error(withdraw_params)
                 logging.error(withdraw_rst)
 
-            exchange_withdrawal_id = withdraw_rst["id"]
+            self.exchange_withdraw_id = withdraw_rst["id"]
 
-            msg = f"交易所提现已发送, 提现ID: {exchange_withdrawal_id}"
+            msg = f"交易所提现已发送, 提现ID: {self.exchange_withdraw_id}"
             logging.info(msg)
             add_state_flow_entry(self.process_item, self.current_state, msg, "success")
 
-            self.arbitrage_details["exchange_withdrawl_id"] = withdraw_rst["id"]
             self._set_state(self.STATE_WAITING_WITHDRAWAL_CONFIRM)
 
         except Exception as e:
@@ -649,13 +640,13 @@ class ArbitrageProcess:
 
             self._set_state("FAILED")
 
-    def _wait_withdrawal_confirm(self):
+    def _wait_withdraw_confirm(self):
         """
         等待交易所提现到链上确认
         """
-        exchange_withdrawl_id = self.arbitrage_details['exchange_withdrawl_id']
+        exchange_withdraw_id = self.exchange_withdraw_id
 
-        msg = f"等待交易所提现确认:{exchange_withdrawl_id}"
+        msg = f"等待交易所提现确认:{exchange_withdraw_id}"
         logging.info(msg)
         add_state_flow_entry(self.process_item, self.current_state, msg, "pending")
         try:
@@ -676,7 +667,7 @@ class ArbitrageProcess:
                     return
 
                 for withdraw in withdraw_list:
-                    if withdraw['id'] != exchange_withdrawl_id:
+                    if withdraw['id'] != exchange_withdraw_id:
                         continue
 
                     last_deposit_state = withdraw

+ 5 - 3
signal/price_checker.py

@@ -232,7 +232,7 @@ def update_data_for_plotly_and_table():
              mexc_err = mexc_err or "MEXC价格为0或无效"
 
         # 2. 计算链上价格,用交易所的大致卖出价值购入
-        IN_AMOUNT_TO_QUERY = trade_value * decimal.Decimal(1 - PROFIT_LIMIT)
+        IN_AMOUNT_TO_QUERY = trade_value
         IN_AMOUNT_TO_QUERY = IN_AMOUNT_TO_QUERY.quantize(decimal.Decimal('1'), rounding=decimal.ROUND_DOWN)
         
         oo_data, data = get_chain_price_vs_target_currency(
@@ -257,10 +257,12 @@ def update_data_for_plotly_and_table():
             oo_price_usdt_per_target
         )
 
+        profit = diff_oo_vs_mexc_bid1_pct * IN_AMOUNT_TO_QUERY
+
         # 4. 满足利润条件就发送套利消息
         global mode
-        if diff_oo_vs_mexc_bid1_pct is not None and diff_oo_vs_mexc_bid1_pct > PROFIT_LIMIT and mode == 'trade':
-            send_arb_msg(diff_oo_vs_mexc_bid1_pct, data)
+        if profit is not None and profit > PROFIT_LIMIT and mode == 'trade':
+            send_arb_msg(profit, data)
 
         current_point = {
             "time": fetch_time_chart,

+ 1 - 1
web3_py_client.py

@@ -362,7 +362,7 @@ if __name__ == "__main__":
     # IN_TOKEN_ADDRESS = '0xdAC17F958D2ee523a2206206994597C13D831ec7'     # USDT on Ethereum
     # IN_TOKEN_DECIMALS = decimal.Decimal(6)
     # OUT_TOKEN_ADDRESS = '0xf816507E690f5Aa4E29d164885EB5fa7a5627860'    # RATO on Ethereum
-    USER_WALLET = '0xb1f33026Db86a86372493a3B124d7123e9045Bb4'
+    USER_WALLET = ''
     # SLIPPAGE = 1
     # USER_EXCHANGE_WALLET = '0xc71835a042F4d870B0F4296cc89cAeb921a9f3DA'