не полный проход по списку
Имеются 3 функции запускающие код
Но проблема такая, что я не получаю вывод messages сразу, а код их выплевывает после того, как только в функции get arbitrsge info в итерации по списку coins дойдет до какого-то индекса в списке, происходит будто-бы переполнение и когда он мне сообщения выдал, то начинает итерацию по списку заново, хотя еще и половины не прошел, также когда итерация происходит то по приближению к этому индексу итерация замедляется сильно
def perform_arbitrage():
messages = []
coins = [coin for coin in final_coin_list if coin not in blacklisted_coins]
enabled_exchanges = [exchange_id for exchange_id, enabled in exchange_filter.items() if enabled]
combinations = list(itertools.combinations(enabled_exchanges, 2))
with concurrent.futures.ThreadPoolExecutor() as executor:
results = []
for exchange_id1, exchange_id2 in combinations:
results.append(executor.submit(get_arbitrage_info, exchange_id1, exchange_id2, coins))
for result in concurrent.futures.as_completed(results):
try:
messages.extend(result.result())
except Exception as e:
print(f"Error executing arbitrage for {exchange_id1} and {exchange_id2}: {str(e)}")
return messages
def get_arbitrage_info(exchange_id1, exchange_id2, coins):
messages = []
try:
exchange1 = exchanges[exchange_id1]
exchange2 = exchanges[exchange_id2]
for coin in coins:
print(coin)
order_book1 = exchange1.fetch_order_book(f'{coin}', limit=5)
order_book2 = exchange2.fetch_order_book(f'{coin}', limit=5)
bids1 = order_book1['bids']
asks1 = order_book1['asks']
bids2 = order_book2['bids']
asks2 = order_book2['asks']
best_bid1 = bids1[0][0] if len(bids1) > 0 else None
best_ask1 = asks1[0][0] if len(asks1) > 0 else None
best_bid2 = bids2[0][0] if len(bids2) > 0 else None
best_ask2 = asks2[0][0] if len(asks2) > 0 else None
if best_bid1 is not None and best_ask1 is not None:
lowest_buy_price_exchange1 = bids1[-1][0]
highest_sell_price_exchange1 = asks1[-1][0]
price_range_exchange1 = f'{lowest_buy_price_exchange1} - {highest_sell_price_exchange1}'
else:
price_range_exchange1 = 'N/A'
if best_bid2 is not None and best_ask2 is not None:
lowest_buy_price_exchange2 = bids2[-1][0]
highest_sell_price_exchange2 = asks2[-1][0]
price_range_exchange2 = f'{lowest_buy_price_exchange2} - {highest_sell_price_exchange2}'
else:
price_range_exchange2 = 'N/A'
average_ask_price1, average_bid_price1 = calculate_average_price(bids1, asks1, lowest_buy_price_exchange1,
highest_sell_price_exchange1)
average_ask_price2, average_bid_price2 = calculate_average_price(bids2, asks2, lowest_buy_price_exchange2,
highest_sell_price_exchange2)
if average_bid_price1 is not None:
price1 = average_bid_price1
else:
price1 = None
if average_ask_price2 is not None:
price2 = average_ask_price2
else:
price2 = None
if average_bid_price1 is not None:
price3 = average_bid_price2
else:
price3 = None
if average_ask_price2 is not None:
price4 = average_ask_price1
else:
price4 = None
buy_volume1 = calculate_volume(price1, price2, min_profit)
sell_volume1 = float(buy_volume1[0]) * price2
buy_volume2 = calculate_volume(price3, price4, min_profit)
sell_volume2 = float(buy_volume2[0]) * price4
price_difference1 = (price2 - price1) / price2 * 100
profit1 = sell_volume1 - buy_volume1[1]
price_difference2 = (price4 - price3) / price4 * 100
profit2 = sell_volume2 - buy_volume2[1]
coin1 = coin.split('/')[0].upper()
coin2 = coin.split('/')[1].upper()
exchange1_networks = get_network_info(exchange1, coin1)
exchange2_networks = get_network_info(exchange2, coin1)
common_networks = set(Network(network) for network in exchange1_networks.keys()) & set(
Network(network) for network in exchange2_networks.keys())
if common_networks:
min_fee_network = min(common_networks, key=lambda x: exchange1_networks[x.name])
min_fee = exchange1_networks[min_fee_network.name]
if price_difference1 >= min_spread_percentage and profit1 >= min_profit and buy_volume1[1] < max_volume:
message = f'{exchange_id2} -> {exchange_id1} | {coin1}/{coin2}\n\n\n'
message += '📉 Покупка\n\n'
message += f'Цена покупки: {price1}\n\n'
message += f'Покупка Объем: {buy_volume1[1]} {coin2} -> {buy_volume1[0]} {coin1}\n'
message += f'Цена: {coin2} ({price_range_exchange2}) -> {coin2}\n\n\n'
message += '📈 Продажа\n\n'
message += f'Цена продажи: {price2}\n\n'
message += f'Продажа Объем: {buy_volume1[0]} {coin1} -> {sell_volume1} {coin2}\n'
message += f'Цена: {coin2} ({price_range_exchange1}) -> {coin2}\n\n\n'
message += f'Разница в цене: {price_difference1:.2f}%\n\n'
message += f'Прибыль: {profit1:.2f} USDT\n\n\n'
message += f"Общая сеть: {min_fee_network.name}\nКомиссия: {min_fee} {coin1} = {round(float(min_fee) * price1, 2)}$\n\n\n"
messages.append(message)
if price_difference2 >= min_spread_percentage and profit2 >= min_profit and buy_volume2[1] < max_volume:
message = f'{exchange_id1} -> {exchange_id2} | {coin1}/{coin2}\n\n\n'
message += '📉 Покупка\n\n'
message += f'Цена покупки: {price3}\n\n'
message += f'Покупка Объем: {buy_volume2[1]} {coin2} -> {buy_volume2[0]} {coin1}\n'
message += f'Цена: {coin2} ({price_range_exchange1}) -> {coin2}\n\n\n'
message += '📈 Продажа\n\n'
message += f'Цена продажи: {price4}\n\n'
message += f'Продажа Объем: {buy_volume2[0]} {coin1} -> {sell_volume2} {coin2}\n'
message += f'Цена: {coin2} ({price_range_exchange2}) -> {coin2}\n\n\n'
message += f'Разница в цене: {price_difference2:.2f}%\n\n'
message += f'Прибыль: {profit2:.2f} USDT\n\n\n'
message += f"Общая сеть: {min_fee_network.name}\nКомиссия: {min_fee} {coin1} = {round(float(min_fee) * price3, 2)}$\n\n\n"
messages.append(message)
except:
pass
return messages
# Функция для выполнения арбитража в отдельном потоке
def run_arbitrage(chat_id):
global is_running
while is_running:
messages = perform_arbitrage()
# Отправка новых связок
if messages:
for message in messages:
bot.send_message(chat_id, message)
@bot.message_handler(func=lambda message: message.text == 'Начать Арбитраж')
def start_arbitrage(message):
global is_running
if is_running:
bot.send_message(message.chat.id, "Арбитраж уже запущен")
return
is_running = True
bot.send_message(message.chat.id, "Арбитраж начат")
print(f'Запущен арбитраж, is_running = {is_running}') # Отладочный вывод
# Запускаем арбитражный поток
arbitrage_thread = threading.Thread(target=run_arbitrage, args=(message.chat.id,))
arbitrage_thread.start()