|
|
@@ -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
|