2024-09-15 09:09:29,137 INFO - Попытка купить на сумму: 4.0
2024-09-15 09:09:29,421 ERROR - Ошибка при покупке: mexc {"code":10007,"msg":"symbol not support api"}  ошибка в этом коде import tkinter as tk
from tkinter import messagebox, OptionMenu, StringVar
import ccxt
import logging
from datetime import datetime
import time
import threading
from queue import Queue, Empty
import pytz

# Настройка логирования
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('trading_bot.log'),
        logging.StreamHandler()
    ]
)

# Конфигурация API
api_key = 'mx0vgl9KtaKYrVqgxi'  # Убедитесь, что указали реальный API-ключ
secret = '067d53047cf245f0b5e6b2f9e987c4c6'  # Убедитесь, что указали реальный секретный ключ

# Глобальные переменные
connected = False
symbols = []
units = []  # Инициализация переменной units
open_positions = []
session_start_time = None
paused = False

# Инициализация биржи
try:
    exchange = ccxt.mexc({
        'apiKey': api_key,
        'secret': secret,
        'enableRateLimit': True,
    })
    exchange.load_markets()
    symbols = list(exchange.symbols)
    logging.info('Биржа MEXC успешно инициализирована.')
    logging.info(f'Доступные символы: {symbols}')
    connected = True
except Exception as e:
    logging.error('Ошибка инициализации биржи MEXC: %s', e)
    connected = False

# Получение и отображение баланса
def get_and_display_balance():
    try:
        balance = exchange.fetch_balance()
        usdt_balance = balance.get('total', {}).get('USDT', 0)
        label_balance.config(text=f'Баланс USDT: {usdt_balance:.2f}')
    except Exception as e:
        logging.error('Ошибка получения баланса: %s', e)

# Получение текущей цены для символа
def get_current_price(symbol):
    try:
        ticker = exchange.fetch_ticker(symbol)
        return ticker['last']
    except Exception as e:
        logging.error('Ошибка получения текущей цены: %s', e)
        return None

# Проверка символа
def validate_symbol(symbol):
    if not symbol:
        messagebox.showerror('Ошибка', 'Символ не выбран.')
        return False
    if symbol not in exchange.markets:
        messagebox.showerror('Ошибка', f'Символ {symbol} не поддерживается.')
        return False
    return True

# Функция покупки
def buy(symbol, cost):
    try:
        if cost <= 0:
            messagebox.showerror('Ошибка', 'Сумма покупки должна быть положительной.')
            return None

        if not validate_symbol(symbol):
            return None

        current_price = get_current_price(symbol)
        if current_price is None:
            messagebox.showerror('Ошибка', 'Не удалось получить текущую цену.')
            return None

        market = exchange.market(symbol)
        min_cost = market['limits']['cost']['min']

        if cost < min_cost:
            messagebox.showerror('Ошибка', f'Минимальная сумма для покупки: {min_cost:.8f}.')
            return None

        logging.info(f'Попытка купить на сумму: {cost}')

        # Создание рыночного ордера с использованием параметра 'quoteOrderQty'
        order = exchange.create_order(
            symbol=symbol,
            type='market',
            side='buy',
            amount=None,  # Для 'quoteOrderQty' устанавливаем amount в None
            params={'quoteOrderQty': cost}
        )
        if order:
            open_positions.append({'symbol': symbol, 'amount': cost, 'price': current_price, 'order_id': order['id']})
            return current_price
    except Exception as e:
        logging.error('Ошибка при покупке: %s', e)
        messagebox.showerror('Ошибка', f'Ошибка при покупке: {e}')
        return None


# Функция продажи
def sell(symbol, amount):
    try:
        if not validate_symbol(symbol):
            return None

        current_price = get_current_price(symbol)
        if current_price is None:
            messagebox.showerror('Ошибка', 'Не удалось получить текущую цену.')
            return None

        market = exchange.market(symbol)
        min_volume = market['limits']['amount']['min']

        if amount < min_volume:
            messagebox.showerror('Ошибка', f"Минимальное количество для продажи: {min_volume}.")
            return None

        precision = market['precision']['amount']
        amount = round(amount, precision)

        logging.info(f'Текущая цена: {current_price}')
        logging.info(f'Продаваемое количество единиц: {amount}')
        logging.info(f'Минимальный объем для {symbol}: {min_volume}')

        # Создание рыночного ордера на продажу
        order = exchange.create_market_sell_order(symbol, amount)
        logging.info('Продажа: %s', order)

        if open_positions:
            last_buy_order = open_positions.pop()
            profit = (current_price - last_buy_order['price']) * amount
            save_trade_state('sell', order, profit)
            logging.info('Торговая история: %s', {'type': 'sell', 'order': order, 'profit': profit})
            return current_price
    except Exception as e:
        logging.error('Ошибка продажи: %s', e)
        messagebox.showerror('Ошибка', f"Не удалось продать: {e}")
        return None

# Сохранение состояния торговли
def save_trade_state(action, order, profit=0):
    with open('trading_bot_state.log', 'a') as f:
        f.write(f"{action},{order['symbol']},{order['amount']},{order['price']},{profit}\n")

# Загрузка состояния торговли из логов
def load_trade_state():
    global open_positions
    try:
        with open('trading_bot_state.log', 'r') as f:
            lines = f.readlines()
            open_positions = []
            for line in lines:
                action, symbol, amount, price, profit = line.strip().split(',')
                if action == 'buy':
                    open_positions.append({'symbol': symbol, 'amount': float(amount), 'price': float(price)})
    except FileNotFoundError:
        logging.info('Лог состояния торговли не найден.')

def continue_previous_session():
    load_trade_state()
    messagebox.showinfo('Продолжение торговой сессии', 'Предыдущая торговая сессия загружена.')
    execute_trade()

# Обновление и отображение открытых позиций
def update_open_positions_display():
    open_orders_text.delete(1.0, tk.END)
    for position in open_positions:
        current_profit = calculate_current_profit(position)
        open_orders_text.insert(tk.END, f"{position['symbol']} {position['amount']} @ {position['price']} текущая прибыль: {current_profit:.2f}\n")

# Расчет текущей прибыли
def calculate_current_profit(position):
    current_price = get_current_price(position['symbol'])
    if current_price is not None:
        profit = (current_price - position['price']) * position['amount']
        return profit
    return 0.0

# Обновление меню символов
def update_symbol_menu(search_query):
    filtered_symbols = [symbol for symbol in symbols if search_query.lower() in symbol.lower()]
    menu = symbol_menu['menu']
    menu.delete(0, 'end')
    for symbol in filtered_symbols:
        menu.add_command(label=symbol, command=lambda s=symbol: on_symbol_select(s))
    if filtered_symbols:
        selected_symbol.set(filtered_symbols[0])
        update_units(filtered_symbols[0])

# Выбор символа
def on_symbol_select(symbol):
    selected_symbol.set(symbol)
    update_units(symbol)

# Обновление единиц
def update_units(symbol):
    global units
    if symbol in exchange.markets:
        market = exchange.markets[symbol]
        base_currency = market['base']
        quote_currency = market['quote']
        units = [base_currency, quote_currency]
    else:
        units = []
    update_unit_menu()

# Обновление меню единиц
def update_unit_menu():
    menu = unit_menu['menu']
    menu.delete(0, 'end')
    for unit in units:
        menu.add_command(label=unit, command=lambda u=unit: selected_unit.set(u))
    if units:
        selected_unit.set(units[0])

# Пауза торговли
def pause_trade():
    global paused
    paused = True
    button_trade.config(text='Торговля на паузе')
    logging.info('Торговля приостановлена пользователем.')

# Синхронизация времени
def synchronize_time():
    global connected
    try:
        server_time = exchange.fetch_time()
        local_time = int(time.time() * 1000)
        time_difference = server_time - local_time
        utc = pytz.utc
        logging.info('Синхронизация времени с биржей.')
        logging.info(f'Серверное время: {datetime.fromtimestamp(server_time / 1000, utc)}')
        logging.info(f'Локальное время: {datetime.fromtimestamp(local_time / 1000, utc)}')
        logging.info(f'Временная разница: {time_difference} мс')
    except Exception as e:
        logging.error('Ошибка синхронизации времени: %s', e)
        connected = False

# Торговая логика
def trade_logic_thread(q):
    try:
        symbol = selected_symbol.get()
        cost = float(entry_amount.get())
        dip_threshold = float(entry_dip.get()) / 100
        rise_threshold = float(entry_rise.get()) / 100

        current_price = get_current_price(symbol)
        if current_price is None:
            raise Exception('Недоступна текущая цена.')

        if not hasattr(execute_trade, "baseline_price") or not open_positions:
            new_buy_price = buy(symbol, cost)
            if new_buy_price:
                execute_trade.baseline_price = new_buy_price
                q.put('Куплено!')

        else:
            if current_price <= execute_trade.baseline_price * (1 - dip_threshold):
                new_buy_price = buy(symbol, cost)
                if new_buy_price:
                    execute_trade.baseline_price = new_buy_price
                    q.put('Куплено на просадке!')

            if current_price >= execute_trade.baseline_price * (1 + rise_threshold):
                for pos in open_positions[:]:
                    sell(pos['symbol'], pos['amount'])
                    open_positions.remove(pos)
                q.put('Продано при росте!')
    except Exception as e:
        q.put(f'Ошибка: {e}')

# Выполнение торговли
def execute_trade():
    global paused
    if paused:
        paused = False
        button_trade.config(text='Торговля активна')
        return

    session_start_time = datetime.now()
    button_trade.config(text='Торговля активна')

    q = Queue()
    trade_thread = threading.Thread(target=trade_logic_thread, args=(q,))
    trade_thread.start()

    check_queue(q)

def check_queue(q):
    try:
        message = q.get_nowait()
    except Empty:
        root.after(100, check_queue, q)
        return

    messagebox.showinfo('Статус', message)

def update_ui():
    if not connected:
        return

    symbol = selected_symbol.get()
    current_price = get_current_price(symbol)
    if current_price:
        label_current_price.config(text=f'Текущая цена: {current_price:.2f}')

    if session_start_time:
        elapsed_time = datetime.now() - session_start_time
        label_session_time.config(text=f'Время сессии: {elapsed_time}')

    connection_status.config(bg='green' if connected else 'red')
    update_open_positions_display()
    root.after(1000, update_ui)

# Интерфейс
root = tk.Tk()
root.title('MEXC Trading Bot')

load_trade_state()
logging.info(f'Местное время компьютера: {datetime.now()}')

label_search = tk.Label(root, text='Поиск символа:')
label_search.pack()

entry_search = tk.Entry(root)
entry_search.pack()
entry_search.bind('<KeyRelease>', lambda event: update_symbol_menu(entry_search.get()))

label_symbol = tk.Label(root, text='Символ:')
label_symbol.pack()

selected_symbol = StringVar(root)
symbol_menu = OptionMenu(root, selected_symbol, *symbols)
symbol_menu.pack()

label_unit = tk.Label(root, text='Торговая единица:')
label_unit.pack()
selected_unit = StringVar(root)
unit_menu = OptionMenu(root, selected_unit, '')
unit_menu.pack()

update_symbol_menu('')

label_balance = tk.Label(root, text="Баланс")
label_balance.pack()

label_amount = tk.Label(root, text='Сумма (в USDT):')
label_amount.pack()
entry_amount = tk.Entry(root)
entry_amount.pack()
entry_amount.insert(tk.END, '10')

label_dip = tk.Label(root, text='Покупка при просадке (%):')
label_dip.pack()
entry_dip = tk.Entry(root)
entry_dip.pack()
entry_dip.insert(tk.END, '0.5')

label_rise = tk.Label(root, text='Продажа при росте (%):')
label_rise.pack()
entry_rise = tk.Entry(root)
entry_rise.pack()
entry_rise.insert(tk.END, '1')

button_trade = tk.Button(root, text='Начать торговлю', command=execute_trade)
button_trade.pack()

button_continue = tk.Button(root, text='Продолжить прошлую сессию', command=continue_previous_session)
button_continue.pack()

button_pause = tk.Button(root, text='Пауза', command=pause_trade)
button_pause.pack()

label_current_price = tk.Label(root, text='Текущая цена:')
label_current_price.pack()

label_positions = tk.Label(root, text='Открытых сделок: 0')
label_positions.pack()

label_profit = tk.Label(root, text='Прибыль сессии: 0.00')
label_profit.pack()

label_session_time = tk.Label(root, text='Время сессии: 00:00:00')
label_session_time.pack()

label_trade_history = tk.Label(root, text='История ордеров:')
label_trade_history.pack()
text_history = tk.Text(root, height=10, width=50)
text_history.pack()

label_open_orders = tk.Label(root, text='Текущие ордера:')
label_open_orders.pack()
open_orders_text = tk.Text(root, height=10, width=50)
open_orders_text.pack()

connection_status = tk.Label(root, text='Статус подключения', width=20, bg='red')
connection_status.pack(anchor='se')

synchronize_time()
get_and_display_balance()
update_ui()

root.mainloop() или напиши какие тебе инструкции по апи нужны чтобы избежать такой ошибки?