import math
import time
from pybit.unified_trading import HTTP
from requests import Session

import key


def get_data_check(name, data_source, expiration, strike_price, option_type, session):
    try:
        if name == "Спот":
            result = session.get_tickers(
                category="spot",
                symbol=f"{data_source}USDC"
            ).get('result', {}).get('list')[0]

        if name == "Бессрочный USDC":
            result = session.get_tickers(
                category="linear",
                symbol=f"{data_source}USDC"
            ).get('result', {}).get('list')[0]

        if name == "Бессрочный USDT":
            result = session.get_tickers(
                category="linear",
                symbol=f"{data_source}USDT"
            ).get('result', {}).get('list')[0]

        if name == "USDC фьючерсы":
            result = session.get_tickers(
                category="linear",
                symbol=f"{data_source}-{expiration}"
            ).get('result', {}).get('list')[0]

        if name == "USDC опционы":
            if option_type == "Put":
                type = "P"
            elif option_type == "Call":
                type = "C"

            result = session.get_tickers(
                category="options",
                symbol=f"{data_source}-{expiration}-{strike_price}-{type}"
            ).get('result', {}).get('list')[0]
    except Exception as e:
        print(e)

    offer_price = float(result['ask1Price'])
    demand_price = float(result['bid1Price'])
    offer_size = float(result['ask1Size'])
    demand_size = float(result['bid1Size'])

    return offer_price, demand_price, offer_size, demand_size

# Функция для округления числа вниз до n знаков после запятой
def round_down(value, decimals):
    factor = 10 ** decimals
    return math.floor(value * factor) / factor

def post_orders(params, display_window):
    # Создаем подключение к API Bybit
    session = HTTP(
        api_key=key.APIK,
        api_secret=key.APISK,
    )
    first_st_qte = {}
    not_repeat = []
    repeat_index = []
    try:
        for index, ticker in enumerate(params):
            # Создаем копию ticker, чтобы не изменять оригинал
            ticker_copy = ticker.copy()
            qte_need = ticker_copy['quantity']
            del ticker_copy['quantity']

            if ticker_copy not in not_repeat:
                not_repeat.append(ticker_copy)
            else:
                match_index = not_repeat.index(ticker_copy)
                repeat_index.append(match_index)
                repeat_index.append(index)
                continue

            if ticker_copy['direction'] == 'Купить':
                qte = ticker_copy['offer_size']
            else:
                qte = ticker_copy['demand_size']

            percent_have = qte / qte_need
            qte_need_for_buy = (qte_need - qte) / 10
            if qte_need_for_buy < 0:
                qte_need_for_buy = 0
                percent_have = 1

            buy_size = qte_need_for_buy
            first_st_qte[index] = [qte_need_for_buy, buy_size, percent_have]
    except Exception as e:
        print(e)

    unique_repeat_index = list(dict.fromkeys(repeat_index))
    keys_to_delete = []

    for _ in first_st_qte.keys():
        if _ in unique_repeat_index:
            keys_to_delete.append(_)

    # Теперь мы можем безопасно удалить ключи
    for _ in keys_to_delete:
        del first_st_qte[_]


    repeat_pos_one_B = {}
    repeat_pos_one_C = {}
    repeat_pos_two_B = {}
    repeat_pos_two_C = {}
    repeat_pos_three_B = {}
    repeat_pos_three_C = {}
    repeat_pos_four_B = {}
    repeat_pos_four_C = {}
    repeat_pos_five_B = {}
    repeat_pos_five_C = {}

    for num in unique_repeat_index:
        if params[num].get('position_name') == 'Бессрочный USDT':
            if params[num].get('direction') == 'Купить':
                repeat_pos_one_B[num] = params[num]
            if params[num].get('direction') == 'Продать':
                repeat_pos_one_C[num] = params[num]
        if params[num].get('position_name') == 'Бессрочный USDC':
            if params[num].get('direction') == 'Купить':
                repeat_pos_two_B[num] = params[num]
            if params[num].get('direction') == 'Продать':
                repeat_pos_two_C[num] = params[num]
        if params[num].get('position_name') == 'USDC фьючерсы':
            if params[num].get('direction') == 'Купить':
                repeat_pos_three_B[num] = params[num]
            if params[num].get('direction') == 'Продать':
                repeat_pos_three_C[num] = params[num]
        if params[num].get('position_name') == 'USDC опционы':
            if params[num].get('direction') == 'Купить':
                repeat_pos_four_B[num] = params[num]
            if params[num].get('direction') == 'Продать':
                repeat_pos_four_C[num] = params[num]
        if params[num].get('position_name') == 'Спот':
            if params[num].get('direction') == 'Купить':
                repeat_pos_five_B[num] = params[num]
            if params[num].get('direction') == 'Продать':
                repeat_pos_five_C[num] = params[num]

    for repeat_pos in [repeat_pos_one_B, repeat_pos_two_B, repeat_pos_three_B, repeat_pos_four_B, repeat_pos_five_B]:
        if repeat_pos:
            qte_need = 0
            for index in repeat_pos:
                qte = repeat_pos[index]['offer_size']
                qte_need += repeat_pos[index]['quantity']

            percent_have = qte / qte_need
            qte_need_for_buy = (qte_need - qte) / 10

            for index in repeat_pos:
                qte_other = repeat_pos[index]['quantity']
                buy_size = (qte_other - qte_other * percent_have) / 10

                if qte_need_for_buy < 0:
                    qte_need_for_buy = 0
                    percent_have = 1
                    buy_size = 0

                first_st_qte[index] = [qte_need_for_buy, buy_size, percent_have]

    for repeat_pos in [repeat_pos_one_C, repeat_pos_two_C, repeat_pos_three_C, repeat_pos_four_C, repeat_pos_five_C]:
        if repeat_pos:
            qte_need = 0
            for index in repeat_pos:
                qte = repeat_pos[index]['demand_size']
                qte_need += repeat_pos[index]['quantity']

            percent_have = qte / qte_need
            qte_need_for_buy = (qte_need - qte) / 10

            for index in repeat_pos:
                qte_other = repeat_pos[index]['quantity']
                buy_size = (qte_other - qte_other * percent_have) / 10

                if qte_need_for_buy < 0:
                    qte_need_for_buy = 0
                    percent_have = 1
                    buy_size = 0

                first_st_qte[index] = [qte_need_for_buy, buy_size, percent_have]

    first_st_qte = {keys: first_st_qte[keys] for keys in sorted(first_st_qte)}

    # Инициализируем переменные для хранения наименьшего третьего значения и соответствующего ключа
    min_percent = float('inf')  # Инициализируем как бесконечность

    # Проходим по словарю
    for _, value in first_st_qte.items():
        third_value = value[2]  # Берем третье значение массива
        if third_value < min_percent:  # Если текущее значение меньше, чем минимальное
            min_percent = third_value  # Обновляем минимальное значение

    second_st_qte = {}
    not_repeat = []
    repeat_index = []
    try:
        for index, ticker in enumerate(params):
            # Создаем копию ticker, чтобы не изменять оригинал
            ticker_copy = ticker.copy()
            qte_need = ticker_copy['quantity']
            del ticker_copy['quantity']

            if ticker_copy not in not_repeat:
                not_repeat.append(ticker_copy)
            else:
                match_index = not_repeat.index(ticker_copy)
                repeat_index.append(match_index)
                repeat_index.append(index)
                continue

            first_buy = qte_need * min_percent
            qte_need_for_buy = (qte_need - first_buy) / 10

            buy_size = qte_need_for_buy
            second_st_qte[index] = [qte_need_for_buy, buy_size, first_buy]
    except Exception as e:
        print(e)

    unique_repeat_index = list(dict.fromkeys(repeat_index))
    keys_to_delete = []

    for _ in second_st_qte.keys():
        if _ in unique_repeat_index:
            keys_to_delete.append(_)

    # Теперь мы можем безопасно удалить ключи
    for _ in keys_to_delete:
        del second_st_qte[_]

    repeat_pos_one_B = {}
    repeat_pos_one_C = {}
    repeat_pos_two_B = {}
    repeat_pos_two_C = {}
    repeat_pos_three_B = {}
    repeat_pos_three_C = {}
    repeat_pos_four_B = {}
    repeat_pos_four_C = {}
    repeat_pos_five_B = {}
    repeat_pos_five_C = {}

    for num in unique_repeat_index:
        if params[num].get('position_name') == 'Бессрочный USDT':
            if params[num].get('direction') == 'Купить':
                repeat_pos_one_B[num] = params[num]
            if params[num].get('direction') == 'Продать':
                repeat_pos_one_C[num] = params[num]
        if params[num].get('position_name') == 'Бессрочный USDC':
            if params[num].get('direction') == 'Купить':
                repeat_pos_two_B[num] = params[num]
            if params[num].get('direction') == 'Продать':
                repeat_pos_two_C[num] = params[num]
        if params[num].get('position_name') == 'USDC фьючерсы':
            if params[num].get('direction') == 'Купить':
                repeat_pos_three_B[num] = params[num]
            if params[num].get('direction') == 'Продать':
                repeat_pos_three_C[num] = params[num]
        if params[num].get('position_name') == 'USDC опционы':
            if params[num].get('direction') == 'Купить':
                repeat_pos_four_B[num] = params[num]
            if params[num].get('direction') == 'Продать':
                repeat_pos_four_C[num] = params[num]
        if params[num].get('position_name') == 'Спот':
            if params[num].get('direction') == 'Купить':
                repeat_pos_five_B[num] = params[num]
            if params[num].get('direction') == 'Продать':
                repeat_pos_five_C[num] = params[num]

    for repeat_pos in [repeat_pos_one_B, repeat_pos_two_B, repeat_pos_three_B, repeat_pos_four_B, repeat_pos_five_B]:
        if repeat_pos:
            qte_first_buy = 0
            qte_all_need = 0
            for index in repeat_pos:
                qte = repeat_pos[index]['quantity']
                qte_all_need += qte
                first_buy = qte * min_percent
                qte_first_buy += first_buy

            qte_need_for_buy = (qte_all_need - qte_first_buy) / 10

            for index in repeat_pos:
                qte = repeat_pos[index]['quantity']
                first_buy = qte * min_percent
                buy_size = (qte - first_buy) / 10

                second_st_qte[index] = [qte_need_for_buy, buy_size, first_buy]

    for repeat_pos in [repeat_pos_one_C, repeat_pos_two_C, repeat_pos_three_C, repeat_pos_four_C, repeat_pos_five_C]:
        if repeat_pos:
            qte_first_buy = 0
            qte_all_need = 0
            for index in repeat_pos:
                qte = repeat_pos[index]['quantity']
                qte_all_need += qte
                first_buy = qte * min_percent
                qte_first_buy += first_buy

            qte_need_for_buy = (qte_all_need - qte_first_buy) / 10

            for index in repeat_pos:
                qte = repeat_pos[index]['quantity']
                first_buy = qte * min_percent
                buy_size = (qte - first_buy) / 10

                second_st_qte[index] = [qte_need_for_buy, buy_size, first_buy]

    second_st_qte = {keys: second_st_qte[keys] for keys in sorted(second_st_qte)}

    for keys, value in second_st_qte.items():
        second_st_qte[keys] = [round_down(v, 3) for v in value]

    data_display = []
    buyAll = False

    approwed = 0
    while approwed != len(second_st_qte):
        approwed = 0
        for _, value in second_st_qte.items():
            check = params[_]

            offer_price, demand_price, offer_size, demand_size\
                = get_data_check(check['position_name'], check['data_source'], check['expiration'], check['strike_price'], check['option_type'], session)

            if check['direction'] == 'Купить':
                if check['order_price'] >= offer_price:
                    approwed += 1
            if check['direction'] == 'Продать':
                if check['order_price'] <= demand_price:
                    approwed += 1


    for keys, values in second_st_qte.items():
        ticker = params[keys]
        qte = values[2]

        if qte == ticker['quantity']:
            buyAll = True

        try:
            if ticker.get("position_name") == "Спот":
                # Параметры ордера
                try:
                    if ticker['option_type'] == 'Call':
                        type = 'C'
                    elif ticker['option_type'] == 'Put':
                        type = 'P'
                    if ticker['direction'] == 'Купить':
                        direction = 'Buy'
                    if ticker['direction'] == 'Продать':
                        direction = 'Sell'

                    order_params = {
                        "category": "spot",
                        "isLeverage": ticker['leverage'],
                        "symbol": f"{ticker['data_source']}USDC",
                        "side": direction,
                        "orderType": "Limit",
                        "qty": qte,
                        "price": ticker['order_price'],
                        "timeInForce": "GTC",
                        "orderLinkId": f"{time.time()}"
                    }

                    print(session.place_order(**order_params))
                except Exception as e:
                    print(e)

            if ticker.get("position_name") == "USDC опционы":
                # Параметры ордера
                try:
                    if ticker['option_type'] == 'Call':
                        type = 'C'
                    elif ticker['option_type'] == 'Put':
                        type = 'P'
                    if ticker['direction'] == 'Купить':
                        direction = 'Buy'
                    if ticker['direction'] == 'Продать':
                        direction = 'Sell'

                    order_params = {
                        "category": "option",
                        "symbol": f"{ticker['data_source']}-{ticker['expiration']}-{ticker['strike_price']}-{type}",
                        "side": direction,
                        "orderType": "Limit",
                        "qty": qte,
                        "price": ticker['order_price'],
                        "timeInForce": "GTC",
                        "orderLinkId": f"{time.time()}"
                    }

                    print(session.place_order(**order_params))
                except Exception as e:
                    print(e)

            if ticker.get("position_name") == "USDC фьючерсы":
                # Параметры ордера
                try:
                    if ticker['direction'] == 'Купить':
                        direction = 'Buy'
                    if ticker['direction'] == 'Продать':
                        direction = 'Sell'

                    order_params = {
                        "category": "linear",
                        "isLeverage": ticker['leverage'],
                        "symbol": f"{ticker['data_source']}-{ticker['expiration']}",
                        "side": direction,
                        "orderType": "Limit",
                        "qty": qte,
                        "price": ticker['order_price'],
                        "timeInForce": "GTC",
                        "orderLinkId": f"{time.time()}"
                    }

                    print(session.place_order(**order_params))
                except Exception as e:
                    print(e)

            if ticker.get("position_name") == "Бессрочный USDC":
                # Параметры ордера
                try:
                    if ticker['direction'] == 'Купить':
                        direction = 'Buy'
                    if ticker['direction'] == 'Продать':
                        direction = 'Sell'

                    order_params = {
                        "category": "linear",
                        "isLeverage": ticker['leverage'],
                        "symbol": f"{ticker['data_source']}PERP",
                        "side": direction,
                        "orderType": "Limit",
                        "qty": qte,
                        "price": ticker['order_price'],
                        "timeInForce": "GTC",
                        "orderLinkId": f"{time.time()}"
                    }

                    print(session.place_order(**order_params))
                except Exception as e:
                    print(e)

            if ticker.get("position_name") == "Бессрочный USDT":
                # Параметры ордера
                try:
                    if ticker['direction'] == 'Купить':
                        direction = 'Buy'
                    if ticker['direction'] == 'Продать':
                        direction = 'Sell'

                    order_params = {
                        "category": "linear",
                        "isLeverage": ticker['leverage'],
                        "symbol": f"{ticker['data_source']}USDT",
                        "side": direction,
                        "orderType": "Limit",
                        "qty": qte,
                        "price": ticker['order_price'],
                        "timeInForce": "GTC",
                        "orderLinkId": f"{time.time()}"
                    }

                    # print(session.place_order(**order_params))
                except Exception as e:
                    print(e)

            data_display.append([
                ticker['position_name'],
                ticker['quantity'],
                qte,
                qte / ticker['quantity'] * 100,
                ])
        except Exception:
            return 0

    display_window.update_data(data_display)

    if buyAll == True:
        return 0

    for i in range(10):
        data_display = []
        approwed = 0
        approwed_qte = 0

        while approwed != len(second_st_qte) and approwed_qte !=len(second_st_qte):
            approwed = 0
            approwed_qte = 0
            for _, value in second_st_qte.items():
                check = params[_]
                offer_price, demand_price, offer_size, demand_size \
                    = get_data_check(check['position_name'], check['data_source'], check['expiration'],
                                     check['strike_price'], check['option_type'], session)

                if check['direction'] == 'Купить':
                    if check['order_price'] >= offer_price:
                        approwed += 1
                if check['direction'] == 'Продать':
                    if check['order_price'] <= demand_price:
                        approwed += 1

                if check['direction'] == 'Купить':
                    if value[0] >= offer_size:
                        approwed_qte += 1
                if check['direction'] == 'Купить':
                    if value[0] >= demand_size:
                        approwed_qte += 1

        for keys, values in second_st_qte.items():
            ticker = params[keys]
            qte = values[1]

            try:
                if ticker.get("position_name") == "Спот":
                    # Параметры ордера
                    try:
                        if ticker['option_type'] == 'Call':
                            type = 'C'
                        elif ticker['option_type'] == 'Put':
                            type = 'P'
                        if ticker['direction'] == 'Купить':
                            direction = 'Buy'
                        if ticker['direction'] == 'Продать':
                            direction = 'Sell'

                        order_params = {
                            "category": "spot",
                            "isLeverage": ticker['leverage'],
                            "symbol": f"{ticker['data_source']}USDC",
                            "side": direction,
                            "orderType": "Limit",
                            "qty": qte,
                            "price": ticker['order_price'],
                            "timeInForce": "GTC",
                            "orderLinkId": f"{time.time()}"
                        }

                        print(session.place_order(**order_params))
                    except Exception as e:
                        print(e)

                if ticker.get("position_name") == "USDC опционы":
                    # Параметры ордера
                    try:
                        if ticker['option_type'] == 'Call':
                            type = 'C'
                        elif ticker['option_type'] == 'Put':
                            type = 'P'
                        if ticker['direction'] == 'Купить':
                            direction = 'Buy'
                        if ticker['direction'] == 'Продать':
                            direction = 'Sell'

                        order_params = {
                            "category": "option",
                            "symbol": f"{ticker['data_source']}-{ticker['expiration']}-{ticker['strike_price']}-{type}",
                            "side": direction,
                            "orderType": "Limit",
                            "qty": qte,
                            "price": ticker['order_price'],
                            "timeInForce": "GTC",
                            "orderLinkId": f"{time.time()}"
                        }

                        print(session.place_order(**order_params))
                    except Exception as e:
                        print(e)

                if ticker.get("position_name") == "USDC фьючерсы":
                    # Параметры ордера
                    try:
                        if ticker['direction'] == 'Купить':
                            direction = 'Buy'
                        if ticker['direction'] == 'Продать':
                            direction = 'Sell'

                        order_params = {
                            "category": "linear",
                            "isLeverage": ticker['leverage'],
                            "symbol": f"{ticker['data_source']}-{ticker['expiration']}",
                            "side": direction,
                            "orderType": "Limit",
                            "qty": qte,
                            "price": ticker['order_price'],
                            "timeInForce": "GTC",
                            "orderLinkId": f"{time.time()}"
                        }

                        print(session.place_order(**order_params))
                    except Exception as e:
                        print(e)

                if ticker.get("position_name") == "Бессрочный USDC":
                    # Параметры ордера
                    try:
                        if ticker['direction'] == 'Купить':
                            direction = 'Buy'
                        if ticker['direction'] == 'Продать':
                            direction = 'Sell'

                        order_params = {
                            "category": "linear",
                            "isLeverage": ticker['leverage'],
                            "symbol": f"{ticker['data_source']}PERP",
                            "side": direction,
                            "orderType": "Limit",
                            "qty": qte,
                            "price": ticker['order_price'],
                            "timeInForce": "GTC",
                            "orderLinkId": f"{time.time()}"
                        }

                        print(session.place_order(**order_params))
                    except Exception as e:
                        print(e)

                if ticker.get("position_name") == "Бессрочный USDT":
                    # Параметры ордера
                    try:
                        if ticker['direction'] == 'Купить':
                            direction = 'Buy'
                        if ticker['direction'] == 'Продать':
                            direction = 'Sell'

                        order_params = {
                            "category": "linear",
                            "isLeverage": ticker['leverage'],
                            "symbol": f"{ticker['data_source']}USDT",
                            "side": direction,
                            "orderType": "Limit",
                            "qty": qte,
                            "price": ticker['order_price'],
                            "timeInForce": "GTC",
                            "orderLinkId": f"{time.time()}"
                        }

                        # print(session.place_order(**order_params))
                    except Exception as e:
                        print(e)

                data_display.append([
                    ticker['position_name'],
                    ticker['quantity'],
                    qte,
                    qte / ticker['quantity'] * 100,
                ])

            except Exception:
                return 0

        display_window.update_data(data_display)

if __name__ == "__main__":
    session = HTTP(
        api_key=key.APIK,
        api_secret=key.APISK,
    )
    check = {'position_name': 'Бессрочный USDT', 'leverage': 10, 'expiration': '1 неделя', 'strike_price': 100, 'option_type': 'Call', 'direction': 'Купить', 'demand_size': 25.586, 'demand_price': 96940.6, 'order_price': 96940.7, 'quantity': 0.1, 'offer_size': 0.757, 'offer_price': 96940.7, 'data_source': 'BTC'}
    offer_price, demand_price, offer_size, demand_size \
        = get_data_check(check['position_name'], check['data_source'], check['expiration'], check['strike_price'],
                         check['option_type'], session)

    print(type(offer_price), type(demand_price), type(offer_size), type(demand_size))

мне нужно сделать эту функцию ассинхронной так как display_window.update_data(data_display) должна исполнятся сразу в файле UIimport sys
from datetime import datetime

from PyQt5.QtWidgets import (
    QApplication, QWidget, QLabel, QPushButton, QVBoxLayout,
    QComboBox, QHBoxLayout, QLineEdit, QDoubleSpinBox, QSpinBox, QTableWidgetItem, QTableWidget
)
from PyQt5.QtCore import QThread, pyqtSignal

import BestDvg_opt
import BestDvg_fut
import DataFromBB_BTC
import DataFromBB_ETH
import POST

class DataUpdater(QThread):
    data_updated = pyqtSignal(tuple)

    def __init__(self, data_source):
        super().__init__()
        self.data_source = data_source  # Добавляем атрибут для источника данных

    def run(self):
        start_time = datetime.now()
        print(f"Программа запущена в: {start_time.strftime('%Y-%m-%d %H:%M:%S')}")

        while True:
            try:
                # Получаем данные в зависимости от источника
                if self.data_source == "BTC":
                    options_data, futures_data, usdt_perp_data, usdc_perp_data, spot = DataFromBB_BTC.process_tickers()
                else:
                    options_data, futures_data, usdt_perp_data, usdc_perp_data, spot = DataFromBB_ETH.process_tickers()

                self.data_updated.emit((options_data, futures_data, usdt_perp_data, usdc_perp_data, spot))
                print(f"Данные обновлены в: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
                self.sleep(3)
            except Exception as e:
                print(f"Ошибка: {e}")
                if "Rate Limit" in str(e):
                    print("Превышен лимит API, ждем перед повторной попыткой...")
                    self.sleep(10)
                else:
                    self.sleep(3)


class DataUpdaterDvg(QThread):
    data_updated_dvg = pyqtSignal(dict)

    def __init__(self, data_source):
        super().__init__()
        self.data_source = data_source  # Добавляем атрибут для источника данных

    def run(self):
        while True:
            try:
                if self.data_source == "BTC":
                    data = BestDvg_opt.get_BTC_dvg()
                    print("BTC")
                else:
                    data = BestDvg_opt.get_ETH_dvg()
                    print("ETH")

                self.data_updated_dvg.emit(data)  # Отправляем данные через сигнал
                self.sleep(3)
            except Exception as e:
                print(f"Ошибка: {e}")
                if "Rate Limit" in str(e):
                    print("Превышен лимит API, ждем перед повторной попыткой...")
                    self.sleep(10)
                else:
                    self.sleep(3)

class DataUpdaterDvgFut(QThread):
    data_updated_dvg_fut = pyqtSignal(dict)

    def __init__(self, data_source):
        super().__init__()
        self.data_source = data_source  # Добавляем атрибут для источника данных

    def run(self):
        while True:
            try:
                if self.data_source == "BTC":
                    data = BestDvg_fut.get_BTC_dvg()
                    print("BTC")
                else:
                    data = BestDvg_fut.get_ETH_dvg()
                    print("ETH")

                self.data_updated_dvg_fut.emit(data)  # Отправляем данные через сигнал
                self.sleep(3)
            except Exception as e:
                print(f"Ошибка: {e}")
                if "Rate Limit" in str(e):
                    print("Превышен лимит API, ждем перед повторной попыткой...")
                    self.sleep(10)
                else:
                    self.sleep(3)

# class SendDataThread(QThread):
#     def __init__(self, positions_data, open_position_display_window):
#         super().__init__()
#         self.positions_data = positions_data
#         self.open_position_display_window = open_position_display_window
#
#     def run(self):
#         print("Отправка данных начата")  # Логирование
#         try:
#             POST.post_orders(self.positions_data, self.open_position_display_window)
#             print("Данные успешно отправлены")  # Логирование
#         except Exception as e:
#             print(f"Ошибка при отправке данных: {e}")


class PositionWidget(QWidget):
    def __init__(self, remove_callback, option_data):
        """
        remove_callback — функция, вызываемая для удаления этой позиции из родительского виджета.
        """
        super().__init__()
        # Инициализация параметров позиции
        self.position_name = "Бессрочный USDT"   # Выбор из списка 4 позиций
        self.leverage = 10                 # Кредитное плечо
        self.expiration = "1 неделя"       # Срок действия
        self.strike_price = 100            # Страйк-цена
        self.option_type = "Call"          # Тип (применяется для позиции 4)
        self.direction = "Купить"          # Направление
        self.demand_size = 100             # Размер спроса
        self.demand_price = 10             # Цена спроса
        self.order_price = 10              # Цена ордера/IV (пересчитывается)
        self.quantity = 0.1                # Количество
        self.offer_size = 150              # Размер предложения
        self.offer_price = 12              # Цена предложения/IV
        self.fee = 1                       # Размер комиссии

        self.remove_callback = remove_callback
        self.option_data = option_data  # Хранит общий option_data
        # Переменная для фиксации цены ордера
        self.is_order_price_fixed = False

        # -------------------------------
        # 1. Наименование позиции
        self.position_name_combo = QComboBox(self)
        self.position_name_combo.addItems(["Бессрочный USDT", "Бессрочный USDC", "USDC фьючерсы", "USDC опционы", "Спот"])
        self.position_name_combo.setCurrentText(self.position_name)
        self.position_name_combo.currentTextChanged.connect(self.update_position_name)
        layout_name = QVBoxLayout()
        layout_name.addWidget(QLabel("Наименование"))
        layout_name.addWidget(self.position_name_combo)

        # -------------------------------
        # 2. Кредитное плечо
        self.leverage_input = QSpinBox(self)
        self.leverage_input.setRange(1, 100)
        self.leverage_input.setValue(self.leverage)
        self.leverage_input.valueChanged.connect(self.update_leverage)
        self.leverage_label = QLabel("——", self)
        self.leverage_label.hide()  # По умолчанию скрыта
        layout_leverage = QVBoxLayout()
        layout_leverage.addWidget(QLabel("Кред. плечо"))
        layout_leverage.addWidget(self.leverage_input)
        layout_leverage.addWidget(self.leverage_label)

        # -------------------------------
        # 3. Срок действия
        self.expiration_combo = QComboBox(self)
        self.expiration_combo.addItems(["1 неделя", "1 месяц", "3 месяца"])
        self.expiration_combo.setCurrentText(self.expiration)
        self.expiration_combo.currentTextChanged.connect(self.update_expiration)
        self.expiration_label = QLabel("——", self)
        self.expiration_label.hide()
        layout_expiration = QVBoxLayout()
        layout_expiration.addWidget(QLabel("Срок действия"))
        layout_expiration.addWidget(self.expiration_combo)
        layout_expiration.addWidget(self.expiration_label)

        # -------------------------------
        # 4. Страйк-цена
        self.strike_price_combo = QComboBox(self)
        self.strike_price_combo.addItems([str(x) for x in range(90, 111, 5)])
        self.strike_price_combo.setCurrentText(str(100))
        self.strike_price_combo.currentTextChanged.connect(self.update_strike_price)
        self.strike_price_display = QLabel("——", self)
        self.strike_price_display.hide()
        layout_strike = QVBoxLayout()
        layout_strike.addWidget(QLabel("Страйк-цена"))
        layout_strike.addWidget(self.strike_price_combo)
        layout_strike.addWidget(self.strike_price_display)

        # -------------------------------
        # 5. Тип
        self.option_type_combo = QComboBox(self)
        self.option_type_combo.addItems(["Call", "Put"])
        self.option_type_combo.setCurrentText(self.option_type)
        self.option_type_combo.currentTextChanged.connect(self.update_option_type)
        self.option_type_label = QLabel("——", self)
        self.option_type_label.hide()
        layout_option_type = QVBoxLayout()
        layout_option_type.addWidget(QLabel("Тип"))
        layout_option_type.addWidget(self.option_type_combo)
        layout_option_type.addWidget(self.option_type_label)

        # -------------------------------
        # 6. Направление
        self.direction_combo = QComboBox(self)
        self.direction_combo.addItems(["Купить", "Продать"])
        self.direction_combo.setCurrentText(self.direction)
        self.direction_combo.currentTextChanged.connect(self.update_direction)
        layout_direction = QVBoxLayout()
        layout_direction.addWidget(QLabel("Направление"))
        layout_direction.addWidget(self.direction_combo)

        # 7. Размер спроса
        self.demand_size_input = QDoubleSpinBox(self)
        self.demand_size_input.setRange(0.001, 1000.0)
        self.demand_size_input.setValue(self.demand_size)
        self.demand_size_input.setDecimals(3)  # Устанавливаем 3 знака после запятой
        self.demand_size_input.valueChanged.connect(self.update_demand_size)
        layout_demand_size = QVBoxLayout()
        layout_demand_size.addWidget(QLabel("Размер спроса"))
        layout_demand_size.addWidget(self.demand_size_input)

        # 8. Цена спроса
        self.demand_price_input = QLineEdit(str(self.demand_price), self)
        self.demand_price_input.textChanged.connect(self.update_demand_price)
        layout_demand_price = QVBoxLayout()
        layout_demand_price.addWidget(QLabel("Цена спроса"))
        layout_demand_price.addWidget(self.demand_price_input)

        # 9. Цена ордера/IV
        self.order_price_input = QLineEdit(str(self.order_price), self)
        self.order_price_input.setReadOnly(not self.is_order_price_fixed)  # Делаем поле редактируемым или нет
        layout_order_price = QVBoxLayout()
        layout_order_price.addWidget(QLabel("Цена ордера"))
        layout_order_price.addWidget(self.order_price_input)

        # 10. Количество
        self.quantity_input = QDoubleSpinBox(self)
        self.quantity_input.setRange(0.001, 1000.0)
        self.quantity_input.setValue(self.quantity)
        self.quantity_input.setDecimals(3)  # Устанавливаем 3 знака после запятой
        self.quantity_input.valueChanged.connect(self.update_quantity)
        layout_quantity = QVBoxLayout()
        layout_quantity.addWidget(QLabel("Количество"))
        layout_quantity.addWidget(self.quantity_input)

        # 11. Размер предложения
        self.offer_size_input = QDoubleSpinBox(self)
        self.offer_size_input.setRange(0.001, 1000.0)
        self.offer_size_input.setValue(self.offer_size)
        self.offer_size_input.setDecimals(3)  # Устанавливаем 3 знака после запятой
        self.offer_size_input.valueChanged.connect(self.update_offer_size)
        layout_offer_size = QVBoxLayout()
        layout_offer_size.addWidget(QLabel("Размер предложения"))
        layout_offer_size.addWidget(self.offer_size_input)

        # 12. Цена предложения/IV
        self.offer_price_input = QLineEdit(str(self.offer_price), self)
        self.offer_price_input.textChanged.connect(self.update_offer_price)
        layout_offer_price = QVBoxLayout()
        layout_offer_price.addWidget(QLabel("Цена предложения"))
        layout_offer_price.addWidget(self.offer_price_input)

        # 13. Кнопка удаления позиции
        self.delete_button = QPushButton("Удалить", self)
        self.delete_button.clicked.connect(lambda: self.remove_callback(self))
        layout_delete = QVBoxLayout()
        layout_delete.addWidget(QLabel("Действие"))
        layout_delete.addWidget(self.delete_button)

        # 14. Кнопка фиксации/разблокировки цены ордера
        self.toggle_price_button = QPushButton("Зафиксировать цену ордера", self)
        self.toggle_price_button.clicked.connect(self.toggle_order_price_fixation)
        layout_toggle_price = QVBoxLayout()
        layout_toggle_price.addWidget(QLabel(""))
        layout_toggle_price.addWidget(self.toggle_price_button)

        # 14. Комиссия
        self.fee_rate = QLineEdit(str(self.fee), self)
        layout_fee_rate = QVBoxLayout()
        layout_fee_rate.addWidget(QLabel("Комиссия"))
        layout_fee_rate.addWidget(self.fee_rate)

        # Основной горизонтальный макет для размещения всех групп
        main_layout = QHBoxLayout()
        main_layout.addLayout(layout_name)
        main_layout.addLayout(layout_leverage)
        main_layout.addLayout(layout_expiration)
        main_layout.addLayout(layout_strike)
        main_layout.addLayout(layout_option_type)
        main_layout.addLayout(layout_direction)
        main_layout.addLayout(layout_demand_size)
        main_layout.addLayout(layout_demand_price)
        main_layout.addLayout(layout_order_price)
        main_layout.addLayout(layout_quantity)
        main_layout.addLayout(layout_offer_size)
        main_layout.addLayout(layout_offer_price)
        main_layout.addLayout(layout_delete)
        main_layout.addLayout(layout_toggle_price)  # Добавьте кнопку фиксации в конец
        main_layout.addLayout(layout_fee_rate)

        # Устанавливаем основной макет для виджета позиции (без заголовка)
        self.setLayout(main_layout)

        # Первоначальное обновление отображения в зависимости от выбранной позиции
        self.update_position_name(self.position_name)
        self.update_order_price()  # Обновляем цену ордера согласно начальным параметрам

        self.option_data, self.futures_data, self.usdt_perp_data, self.usdc_perp_data, self.spot_data = DataFromBB_BTC.process_tickers()

    def toggle_order_price_fixation(self):
        """Переключение состояния фиксации цены ордера."""
        self.is_order_price_fixed = not self.is_order_price_fixed
        if self.is_order_price_fixed:
            self.toggle_price_button.setText("Разблокировать цену ордера")
            self.order_price_input.setReadOnly(False)  # Делаем поле редактируемым
            self.order_price_input.setStyleSheet("font-weight: bold; color: green;")  # Для визуального обозначения
        else:
            self.toggle_price_button.setText("Зафиксировать цену ордера")
            self.order_price_input.setReadOnly(True)  # Делаем поле не редактируемым
            self.order_price_input.setStyleSheet("")  # Сброс стиля

        # Обновляем цену ордера на основе введенного значения
        self.update_order_price()

    def update_option_data(self, options_data, futures_data, usdt_perp_data, usdc_perp_data, spot_data):
        """Получение и обновление данных для позиции."""
        self.option_data = options_data  # Хранит данные
        self.futures_data = futures_data
        self.usdt_perp_data = usdt_perp_data
        self.usdc_perp_data = usdc_perp_data
        self.spot_data = spot_data

        # Вам нужно добавить логику для обновления информации о фьючерсах и других типах данных, если это необходимо
        # Пример обновления данных опций:
        if self.position_name == "USDC опционы":
            self.update_strike_price(self.strike_price)
            self.update_fee_rate(self.option_data.get(self.expiration)[0].get('options')[0].get('fee'))

        if self.position_name == "USDC фьючерсы":
            self.update_expiration(self.expiration)
            self.update_fee_rate(self.futures_data.get(self.expiration)[0].get('fee'))


        elif self.position_name == "Бессрочный USDT":
            try:
                self.demand_size = float(self.usdt_perp_data[0].get('bid1Size'))
                self.demand_price = float(self.usdt_perp_data[0].get('bid1Price'))
                self.offer_size = float(self.usdt_perp_data[0].get('ask1Size'))
                self.offer_price = float(self.usdt_perp_data[0].get('ask1Price'))

                self.demand_size_input.setValue(self.demand_size)
                self.demand_price_input.setText(str(self.demand_price))
                self.offer_size_input.setValue(self.offer_size)
                self.offer_price_input.setText(str(self.offer_price))

                self.update_order_price()

                self.update_fee_rate(self.usdt_perp_data[0].get('fee'))
            except Exception:
                pass

        elif self.position_name == "Бессрочный USDC":
            try:
                self.demand_size = float(self.usdc_perp_data[0].get('bid1Size'))
                self.demand_price = float(self.usdc_perp_data[0].get('bid1Price'))
                self.offer_size = float(self.usdc_perp_data[0].get('ask1Size'))
                self.offer_price = float(self.usdc_perp_data[0].get('ask1Price'))

                self.demand_size_input.setValue(self.demand_size)
                self.demand_price_input.setText(str(self.demand_price))
                self.offer_size_input.setValue(self.offer_size)
                self.offer_price_input.setText(str(self.offer_price))

                self.update_order_price()

                self.update_fee_rate(self.usdc_perp_data[0].get('fee'))
            except Exception:
                pass

        elif self.position_name == "Спот":
            try:
                self.demand_size = float(self.spot_data[0].get('bid1Size'))
                self.demand_price = float(self.spot_data[0].get('bid1Price'))
                self.offer_size = float(self.spot_data[0].get('ask1Size'))
                self.offer_price = float(self.spot_data[0].get('ask1Price'))

                self.demand_size_input.setValue(self.demand_size)
                self.demand_price_input.setText(str(self.demand_price))
                self.offer_size_input.setValue(self.offer_size)
                self.offer_price_input.setText(str(self.offer_price))

                self.update_order_price()

                self.update_fee_rate(self.spot_data[0].get('fee'))
            except Exception:
                pass


    def update_position_name(self, text):
        """Обновление наименования позиции и переключение между интерактивными элементами и метками."""
        self.position_name = text
        if self.position_name == "USDC опционы":
            # Обновляем даты экспирации
            self.expiration_combo.clear()
            self.expiration_combo.addItems(self.option_data.keys())
            # Обновляем Страйк цены
            self.strike_price_combo.show()
            self.strike_price_display.hide()
            # Для позиции 4:
            # Кредитное плечо не применяется
            self.leverage_input.hide()
            self.leverage_label.setText("——")
            self.leverage_label.show()
            # Срок действия применяется
            self.expiration_combo.show()
            self.expiration_label.hide()
            # Страйк-цена и Тип применяются
            self.option_type_combo.show()
            self.option_type_label.hide()
        elif self.position_name in ["Бессрочный USDT", "Бессрочный USDC", "Спот"]:
            # Для позиций 1 и 2:
            # Кредитное плечо применяется
            self.leverage_input.show()
            self.leverage_label.hide()
            # Срок действия не применяется
            self.expiration_combo.hide()
            self.expiration_label.setText("——")
            self.expiration_label.show()
            self.expiration_combo.clear()
            self.expiration_combo.addItems(["1 неделя", "1 месяц", "3 месяца"])
            self.expiration_combo.setCurrentText("1 неделя")
            # Страйк-цена и Тип не применяются
            self.strike_price_combo.hide()
            self.strike_price_display.setText("——")
            self.strike_price_display.show()
            self.strike_price_combo.clear()
            self.strike_price_combo.addItems([str(x) for x in range(90, 111, 5)])
            self.strike_price_combo.setCurrentText(str(100))
            self.option_type_combo.hide()
            self.option_type_label.setText("——")
            self.option_type_label.show()
            self.option_type_combo.clear()
            self.option_type_combo.addItems(["Call", "Put"])
            self.option_type_combo.setCurrentText("Call")
        elif self.position_name == "USDC фьючерсы":
            # Для позиции 3:
            self.expiration_combo.clear()
            self.expiration_combo.addItems(self.futures_data.keys())
            # Кредитное плечо применяется
            self.leverage_input.show()
            self.leverage_label.hide()
            # Срок действия применяется
            self.expiration_combo.show()
            self.expiration_label.hide()
            # Страйк-цена и Тип не применяются
            self.strike_price_combo.hide()
            self.strike_price_display.setText("——")
            self.strike_price_display.show()
            self.strike_price_combo.clear()
            self.strike_price_combo.addItems([str(x) for x in range(90, 111, 5)])
            self.strike_price_combo.setCurrentText(str(100))
            self.option_type_combo.hide()
            self.option_type_label.setText("——")
            self.option_type_label.show()
            self.option_type_combo.clear()
            self.option_type_combo.addItems(["Call", "Put"])
            self.option_type_combo.setCurrentText("Call")

    def update_leverage(self, value):
        self.leverage = value

    def update_expiration(self, text):
        self.expiration = text
        if self.position_name == "USDC опционы":
            try:
                self.strike_price_combo.clear()
                for i in range(len(self.option_data[self.expiration])):
                    self.strike_price_combo.addItems([self.option_data[self.expiration][i]['str_price']])
            except Exception:
                pass

        if self.position_name == "USDC фьючерсы":
            try:
                self.demand_size = float(self.futures_data.get(self.expiration)[0].get('bid1Size'))
                self.demand_price = float(self.futures_data.get(self.expiration)[0].get('bid1Price'))
                self.offer_size = float(self.futures_data.get(self.expiration)[0].get('ask1Size'))
                self.offer_price = float(self.futures_data.get(self.expiration)[0].get('ask1Price'))

                self.demand_size_input.setValue(self.demand_size)
                self.demand_price_input.setText(str(self.demand_price))
                self.offer_size_input.setValue(self.offer_size)
                self.offer_price_input.setText(str(self.offer_price))

                self.update_order_price()
            except Exception:
                pass


    def update_strike_price(self, text):
        try:
            self.strike_price = int(text)
            if self.position_name == "USDC опционы":
                if self.option_data.get(self.expiration)[self.strike_price_combo.currentIndex()].get('options')[0].get('option_type') == 'Call' and self.option_type == 'Call' or self.option_data.get(self.expiration)[self.strike_price_combo.currentIndex()].get('options')[0].get('option_type') == 'Put' and self.option_type == 'Put':
                    # Если тип Call, устанавливаем параметры
                    self.demand_size = float(self.option_data.get(self.expiration)[self.strike_price_combo.currentIndex()].get('options')[0].get('bid1Size'))
                    self.demand_price = float(self.option_data.get(self.expiration)[self.strike_price_combo.currentIndex()].get('options')[0].get('bid1Price'))
                    self.offer_size = float(self.option_data.get(self.expiration)[self.strike_price_combo.currentIndex()].get('options')[0].get('ask1Size'))
                    self.offer_price = float(self.option_data.get(self.expiration)[self.strike_price_combo.currentIndex()].get('options')[0].get('ask1Price'))
                elif self.option_data.get(self.expiration)[self.strike_price_combo.currentIndex()].get('options')[0].get('option_type') == 'Call' and self.option_type == 'Put' or self.option_data.get(self.expiration)[self.strike_price_combo.currentIndex()].get('options')[0].get('option_type') == 'Put' and self.option_type == 'Call':
                    # Если тип Put, устанавливаем параметры
                    self.demand_size = float(self.option_data.get(self.expiration)[self.strike_price_combo.currentIndex()].get('options')[1].get('bid1Size'))
                    self.demand_price = float(self.option_data.get(self.expiration)[self.strike_price_combo.currentIndex()].get('options')[1].get('bid1Price'))
                    self.offer_size = float(self.option_data.get(self.expiration)[self.strike_price_combo.currentIndex()].get('options')[1].get('ask1Size'))
                    self.offer_price = float(self.option_data.get(self.expiration)[self.strike_price_combo.currentIndex()].get('options')[1].get('ask1Price'))

                self.demand_size_input.setValue(self.demand_size)
                self.demand_price_input.setText(str(self.demand_price))
                self.offer_size_input.setValue(self.offer_size)
                self.offer_price_input.setText(str(self.offer_price))


            self.update_order_price()
        except ValueError:
            pass

    def update_option_type(self, text):
        self.option_type = text
        self.update_strike_price(self.strike_price)

    def update_direction(self, text):
        self.direction = text
        self.update_order_price()  # Пересчитываем цену ордера

    def update_demand_size(self, value):
        self.demand_size = value

    def update_demand_price(self, text):
        try:
            self.demand_price = float(text)
        except ValueError:
            pass
        self.update_order_price()  # Пересчитываем цену ордера при изменении цены спроса

    def update_quantity(self, value):
        self.quantity = value

    def update_offer_size(self, value):
        self.offer_size = value

    def update_offer_price(self, text):
        try:
            self.offer_price = float(text)
        except ValueError:
            pass
        self.update_order_price()  # Пересчитываем цену ордера при изменении цены предложения

    def update_fee_rate(self, value):
        self.fee = f"{value * self.quantity * self.order_price:.3f}"
        self.fee_rate.setText(self.fee)

    def update_order_price(self):
        """Пересчет цены ордера в зависимости от направления.
           Если направление 'Купить' – цена ордера равна цене предложения,
           иначе – цена ордера равна цене спроса."""
        if self.is_order_price_fixed:
            try:
                # Если цена зафиксирована, считываем значение из поля ввода
                self.order_price = float(self.order_price_input.text())
            except ValueError:
                pass  # Игнорируем ошибки преобразования
        else:
            if self.direction == "Купить":
                self.order_price = self.offer_price
            else:
                self.order_price = self.demand_price

        self.order_price_input.setText(f"{self.order_price}")  # Обновляем поле ввода с новой ценой


class App(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Конструктор позиций")
        self.setGeometry(100, 100, 1400, 100)

        # Create instances of the display windows
        self.open_position_display_window = OpenPositionDisplayWindow()
        self.data_display_window = DataDisplayWindow()
        self.parameters_display_window = ParametersDisplayWindow()  # New parameters display window

        self.open_position_display_window.show()
        self.data_display_window.show()  # Show the original window on startup
        self.parameters_display_window.show()  # Show the new parameters window on startup

        self.positions = []

        self.data_fetcher_fut = DataUpdaterDvgFut(data_source="BTC")
        self.data_fetcher_fut.data_updated_dvg_fut.connect(self.update_dvg_futures)
        self.data_fetcher_fut.start()

        self.data_fetcher = DataUpdaterDvg(data_source="BTC")
        self.data_fetcher.data_updated_dvg.connect(self.update_dvg)
        self.data_fetcher.start()

        # Создание потока для обновления данных
        self.data_updater = DataUpdater(data_source="BTC")
        self.data_updater.data_updated.connect(self.update_all_positions)  # Подключаем сигнал к методу
        self.data_updater.start()  # Запуск потока

        # Единая плашка для всех позиций
        header_label = QLabel("Параметры позиции:")
        header_label.setStyleSheet("font-size: 16px; font-weight: bold;")

        # Добавление кнопок для выбора BTC и ETH
        self.btc_button = QPushButton("BTC", self)
        self.eth_button = QPushButton("ETH", self)

        # Установка начального состояния (BTC выбран по умолчанию)
        self.btc_button.setStyleSheet("background-color: green; color: white;")  # Подсветка BTC
        self.eth_button.setStyleSheet("background-color: lightgray; color: black;")  # Неактивная ETH

        # Подключение сигналов к методам
        self.btc_button.clicked.connect(self.select_btc)
        self.eth_button.clicked.connect(self.select_eth)

        # Установка начального состояния (BTC выбран по умолчанию)
        self.btc_button.setChecked(True)

        # Горизонтальный макет для кнопок
        button_layout = QHBoxLayout()
        button_layout.addWidget(self.btc_button)
        button_layout.addWidget(self.eth_button)

        # Вертикальный макет для размещения позиций
        self.positions_layout = QVBoxLayout()

        # Основной вертикальный макет с единым заголовком
        self.main_layout = QVBoxLayout()
        self.main_layout.addWidget(header_label)
        self.main_layout.addLayout(button_layout)
        self.main_layout.addLayout(self.positions_layout)

        # Кнопка для добавления новой позиции
        self.add_button = QPushButton("Добавить позицию", self)
        self.add_button.clicked.connect(self.add_position)

        # Новая кнопка для отправки данных
        self.send_button = QPushButton("Отправить в книгу ордеров", self)
        self.send_button.clicked.connect(self.send_positions_data)  # Привязываем сигнал к функции

        add_layout = QHBoxLayout()
        add_layout.addWidget(self.add_button)
        add_layout.addWidget(self.send_button)  # Добавляем новую кнопку в горизонтальный макет

        # Добавляем кнопку в основной макет
        self.main_layout.addLayout(add_layout)
        self.setLayout(self.main_layout)

    def select_btc(self):
        """Выбор BTC как источника данных."""
        self.data_fetcher_fut.data_source = "BTC"
        self.data_updater.data_source = "BTC"  # Устанавливаем источник данных на BTC
        self.data_fetcher.data_source = "BTC"  # Обновляем источник данных для DataUpdaterDvg
        self.btc_button.setStyleSheet("background-color: green; color: white;")  # Подсветка выбранной кнопки
        self.eth_button.setStyleSheet("background-color: lightgray; color: black;")  # Сброс стиля невыбранной кнопки

    def select_eth(self):
        """Выбор ETH как источника данных."""
        self.data_fetcher_fut.data_source = "ETH"
        self.data_updater.data_source = "ETH"  # Устанавливаем источник данных на ETH
        self.data_fetcher.data_source = "ETH"  # Обновляем источник данных для DataUpdaterDvg
        self.eth_button.setStyleSheet("background-color: green; color: white;")  # Подсветка выбранной кнопки
        self.btc_button.setStyleSheet("background-color: lightgray; color: black;")  # Сброс стиля невыбранной кнопки

    def send_positions_data(self):
        """Сбор данных всех открытых позиций и отправка их."""
        positions_data = []

        for position in self.positions:
            position_data = {
                'position_name': position.position_name,
                'leverage': position.leverage,
                'expiration': position.expiration,
                'strike_price': position.strike_price,
                'option_type': position.option_type,
                'direction': position.direction,
                'demand_size': position.demand_size,
                'demand_price': position.demand_price,
                'order_price': position.order_price,
                'quantity': position.quantity,
                'offer_size': position.offer_size,
                'offer_price': position.offer_price,
                'data_source': self.data_updater.data_source
            }
            positions_data.append(position_data)

        POST.post_orders(positions_data, self.open_position_display_window)

        # # Создаем и запускаем поток для отправки данных
        # self.send_data_thread = SendDataThread(positions_data, self.open_position_display_window)
        # self.send_data_thread.start()  # Запуск потока

    def add_position(self):
        """Добавление новой позиции в интерфейс, передавая общий option_data."""
        position = PositionWidget(remove_callback=self.remove_position, option_data={})
        self.positions.append(position)
        self.positions_layout.addWidget(position)

    def update_all_positions(self, data):
        options_data, futures_data, usdt_perp_data, usdc_perp_data, spot = data

        for position in self.positions:
            position.update_option_data(options_data, futures_data, usdt_perp_data, usdc_perp_data, spot)

    def update_dvg_futures(self, dvg_data_fut):
        """Update all positions and refresh the data display window."""
        position_data = []  # Collect data for the display window

        # You might need to adjust the way you access data based on your exact requirements
        for _ in dvg_data_fut.keys():
            position_info = dvg_data_fut[_]
            for entry in position_info:
                # Assuming the structure of entry matches your requirements
                position_data.append([
                    _,
                    entry[0],  # Купить
                    entry[1],  # Продать
                    entry[2],  # Result
                ])

        # Update the data display window with the collected data
        self.parameters_display_window.update_data(position_data)

    def update_dvg(self, dvg_data):
        """Update all positions and refresh the data display window."""
        position_data = []  # Collect data for the display window

        # You might need to adjust the way you access data based on your exact requirements
        for _ in dvg_data.keys():
            position_info = dvg_data[_]
            for entry in position_info:
                # Assuming the structure of entry matches your requirements
                position_data.append([
                    _,
                    entry[0],  # Call (Купить)
                    entry[1],  # Call (Продать)
                    entry[2],  # Put (Купить)
                    entry[3],  # Put (Продать)
                    entry[4],  # Strike Call
                    entry[5],  # Strike Put
                    entry[6]  # Result
                ])

        # Update the data display window with the collected data
        self.data_display_window.update_data(position_data)

    def remove_position(self, position_widget):
        """Удаление позиции из интерфейса и списка."""
        try:
            if position_widget in self.positions:
                self.positions.remove(position_widget)
                self.positions_layout.removeWidget(position_widget)
                position_widget.deleteLater()
        except Exception as e:
            print(e)

class DataDisplayWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Лучшая разница опционы")
        self.setGeometry(50, 500, 850, 500)

        # Create a table widget
        self.table_widget = QTableWidget(self)
        self.table_widget.setColumnCount(8)  # 8 columns
        self.table_widget.setHorizontalHeaderLabels(["Date expiration", "Call (Купить)", "Call (Продать)", "Put (Купить)", "Put (Продать)", "Strike Call", "Strike Put", "Result, %"])

        # Layout for the table
        layout = QVBoxLayout()
        layout.addWidget(self.table_widget)
        self.setLayout(layout)

    def update_data(self, data):
        """Update the table with the provided data."""
        self.table_widget.setRowCount(len(data))
        for row_index, row_data in enumerate(data):
            for column_index, item in enumerate(row_data):
                self.table_widget.setItem(row_index, column_index, QTableWidgetItem(str(item)))

class ParametersDisplayWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Лучшая разница фьючерсы")
        self.setGeometry(900, 500, 450, 500)

        # Create a table widget
        self.table_widget = QTableWidget(self)
        self.table_widget.setColumnCount(4)  # 4 columns
        self.table_widget.setHorizontalHeaderLabels(["Date expiration", "Купить", "Продать", "Result %"])

        # Layout for the table
        layout = QVBoxLayout()
        layout.addWidget(self.table_widget)
        self.setLayout(layout)

    def update_data(self, data):
        """Update the table with the provided parameter's data."""
        self.table_widget.setRowCount(len(data))
        for row_index, row_data in enumerate(data):
            for column_index, item in enumerate(row_data):
                self.table_widget.setItem(row_index, column_index, QTableWidgetItem(str(item)))


class OpenPositionDisplayWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Открытые позиции")
        self.setGeometry(1350, 500, 550, 300)

        # Создаем таблицу
        self.table_widget = QTableWidget(self)
        self.table_widget.setColumnCount(5)  # 5 столбцов
        self.table_widget.setHorizontalHeaderLabels(["Позиция", "Нужно купить", "Куплено", "%", "Остановить"])

        # Макет для таблицы
        layout = QVBoxLayout()
        layout.addWidget(self.table_widget)
        self.setLayout(layout)

        self.current_data = []  # Список для хранения текущих данных

    def update_data(self, new_data):
        """Обновление таблицы с новыми данными."""
        # Объединяем новые данные с текущими
        self.current_data.extend(new_data)

        # Обновляем таблицу
        self.table_widget.setRowCount(len(self.current_data))
        for row_index, row_data in enumerate(self.current_data):
            for column_index, item in enumerate(row_data[:-1]):  # Исключаем последнюю ячейку для кнопки
                self.table_widget.setItem(row_index, column_index, QTableWidgetItem(str(item)))

            # Создаем кнопку для последнего столбца
            stop_button = QPushButton("Остановить")
            stop_button.clicked.connect(lambda checked, row=row_index: self.stop_position(row))
            self.table_widget.setCellWidget(row_index, 4, stop_button)  # Устанавливаем кнопку в последний столбец

    def stop_position(self, row):
        """Обработка действия остановки позиции."""
        print(f"Stopping position at row {row}")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = App()
    window.show()
    sys.exit(app.exec_())