не полный проход по списку

Рейтинг: 0Ответов: 1Опубликовано: 19.06.2023

Имеются 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()

Ответы

▲ 3Принят
  1. except: pass - ну правильно, вы так не узнаете о том, что у вас произошла какая-то ошибка и цикл прервался из-за этого. Если ошибка не должна прерывать цикл по cois, то и try/except должен быть внутри цикла по coins. Уже имеющийся try/except в цикл перенести или ещё один добавить - это вы сами смотрите по задаче. try/except могут быть вложенными сколько угодно раз, сообразно постановке задачи.

  2. И except pass в любом случае плохо. Добавьте логирование ошибок, с помощью стандартного модуля logging это делается элементарно. Так вы сможете узнать, что же у вас там происходит. И лучше добавьте логирование не только ошибок в случае выбрасывания исключений, но и в тех местах, где всё работает своим чередом. Так вы будете знать всё о том, как фактически работает ваш код и не будет никаких сюрпризов, почему всё работает так, а не эдак.