from datetime import datetime import logging.config from sqlalchemy.sql.sqltypes import DateTime from sqlalchemy import BigInteger, Boolean, Integer, String, ForeignKey from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column from sqlalchemy.ext.asyncio import AsyncAttrs, async_sessionmaker, create_async_engine from logger_helper.logger_helper import LOGGING_CONFIG from sqlalchemy import select, insert logging.config.dictConfig(LOGGING_CONFIG) logger = logging.getLogger("models") engine = create_async_engine(url='sqlite+aiosqlite:///db.sqlite3') async_session = async_sessionmaker(engine) class Base(AsyncAttrs, DeclarativeBase): """Базовый класс для declarative моделей SQLAlchemy с поддержкой async.""" pass class User_Telegram_Id(Base): """ Модель таблицы user_telegram_id. Хранит идентификаторы Telegram пользователей. Атрибуты: id (int): Внутренний первичный ключ записи. tg_id (int): Уникальный идентификатор пользователя Telegram. """ __tablename__ = 'user_telegram_id' id: Mapped[int] = mapped_column(primary_key=True) tg_id = mapped_column(BigInteger) class User_Bybit_API(Base): """ Модель таблицы user_bybit_api. Хранит API ключи и секреты Bybit для каждого Telegram пользователя. Атрибуты: id (int): Внутренний первичный ключ записи. tg_id (int): Внешний ключ на Telegram пользователя (user_telegram_id.tg_id). api_key (str): API ключ Bybit (уникальный для пользователя). secret_key (str): Секретный ключ Bybit (уникальный для пользователя). """ __tablename__ = 'user_bybit_api' id: Mapped[int] = mapped_column(primary_key=True) tg_id = mapped_column(ForeignKey("user_telegram_id.tg_id")) api_key = mapped_column(String(18), default='None') secret_key = mapped_column(String(36), default='None') class User_Symbol(Base): """ Модель таблицы user_main_settings. Хранит основные настройки торговли для пользователя. Атрибуты: id (int): Внутренний первичный ключ записи. tg_id (int): Внешний ключ на Telegram пользователя. trading_mode (str): Режим торговли (ForeignKey на trading_modes.mode). margin_type (str): Тип маржи (ForeignKey на margin_types.type). size_leverage (int): Кредитное плечо. starting_quantity (int): Начальный объём позиции. martingale_factor (int): Коэффициент мартингейла. martingale_step (int): Текущий шаг мартингейла. maximal_quantity (int): Максимальное количество шагов мартингейла. entry_order_type (str): Тип входа (Market или Limit). limit_order_price (str, optional): Цена лимитного ордера, если используется. """ __tablename__ = 'user_symbols' id: Mapped[int] = mapped_column(primary_key=True) tg_id = mapped_column(ForeignKey("user_telegram_id.tg_id")) symbol = mapped_column(String(18), default='PENGUUSDT') class Trading_Mode(Base): """ Справочник доступных режимов торговли. Атрибуты: id (int): Первичный ключ. mode (str): Уникальный режим (например, 'Long', 'Short'). """ __tablename__ = 'trading_modes' id: Mapped[int] = mapped_column(primary_key=True) mode = mapped_column(String(10), unique=True) class Margin_type(Base): """ Справочник типов маржинальной торговли. Атрибуты: id (int): Первичный ключ. type (str): Тип маржи (например, 'Isolated', 'Cross'). """ __tablename__ = 'margin_types' id: Mapped[int] = mapped_column(primary_key=True) type = mapped_column(String(15), unique=True) class Trigger(Base): """ Справочник видов триггеров для сделок. Атрибуты: id (int): Первичный ключ. trigger (str): Название триггера (например, 'Ручной', 'Автоматический'). """ __tablename__ = 'triggers' id: Mapped[int] = mapped_column(primary_key=True) trigger = mapped_column(String(15), unique=True) class User_Main_Settings(Base): """ Основные настройки пользователя для торговли. Атрибуты: id (int): Первичный ключ. tg_id (int): Внешний ключ на Telegram пользователя. trading_mode (str): Режим торговли, FK на trading_modes.mode. margin_type (str): Тип маржи, FK на margin_types.type. size_leverage (int): Кредитное плечо. starting_quantity (int): Начальный объем позиции. martingale_factor (int): Коэффициент мартингейла. martingale_step (int): Текущий шаг мартингейла. maximal_quantity (int): Максимальное число шагов мартингейла. entry_order_type (str): Тип ордера входа (Market/Limit). limit_order_price (Optional[str]): Цена лимитного ордера, если есть. """ __tablename__ = 'user_main_settings' id: Mapped[int] = mapped_column(primary_key=True) tg_id = mapped_column(ForeignKey("user_telegram_id.tg_id")) trading_mode = mapped_column(ForeignKey("trading_modes.mode")) margin_type = mapped_column(ForeignKey("margin_types.type")) size_leverage = mapped_column(Integer(), default=1) starting_quantity = mapped_column(Integer(), default=1) martingale_factor = mapped_column(Integer(), default=1) martingale_step = mapped_column(Integer(), default=1) maximal_quantity = mapped_column(Integer(), default=10) entry_order_type = mapped_column(String(10), default='Market') limit_order_price = mapped_column(String(20), nullable=True) class User_Risk_Management_Settings(Base): """ Настройки управления рисками пользователя. Атрибуты: id (int): Первичный ключ. tg_id (int): Внешний ключ на Telegram пользователя. price_profit (int): Процент прибыли для трейда. price_loss (int): Процент убытка для трейда. max_risk_deal (int): Максимально допустимый риск по сделке в процентах. commission_fee (str): Учитывать ли комиссию в расчетах ("Да"/"Нет"). """ __tablename__ = 'user_risk_management_settings' id: Mapped[int] = mapped_column(primary_key=True) tg_id = mapped_column(ForeignKey("user_telegram_id.tg_id")) price_profit = mapped_column(Integer(), default=1) price_loss = mapped_column(Integer(), default=1) max_risk_deal = mapped_column(Integer(), default=100) commission_fee = mapped_column(String(), default="Да") class User_Condition_Settings(Base): """ Дополнительные пользовательские условия для торговли. Атрибуты: id (int): Первичный ключ. tg_id (int): Внешний ключ на Telegram пользователя. trigger (str): Тип триггера, FK на triggers.trigger. filter_time (str): Временной фильтр. filter_volatility (bool): Фильтр по волатильности. external_cues (bool): Внешние сигналы. tradingview_cues (bool): Сигналы TradingView. webhook (str): URL webhook. ai_analytics (bool): Использование AI для аналитики. """ __tablename__ = 'user_condition_settings' id: Mapped[int] = mapped_column(primary_key=True) tg_id = mapped_column(ForeignKey("user_telegram_id.tg_id")) trigger = mapped_column(ForeignKey("triggers.trigger")) filter_time = mapped_column(String(25), default='???') filter_volatility = mapped_column(Boolean, default=False) external_cues = mapped_column(Boolean, default=False) tradingview_cues = mapped_column(Boolean, default=False) webhook = mapped_column(String(40), default='') ai_analytics = mapped_column(Boolean, default=False) class User_Additional_Settings(Base): """ Прочие дополнительные настройки пользователя. Атрибуты: id (int): Первичный ключ. tg_id (int): Внешний ключ на Telegram пользователя. pattern_save (bool): Сохранять ли шаблоны. autostart (bool): Автоматический запуск. notifications (bool): Получение уведомлений. """ __tablename__ = 'user_additional_settings' id: Mapped[int] = mapped_column(primary_key=True) tg_id = mapped_column(ForeignKey("user_telegram_id.tg_id")) pattern_save = mapped_column(Boolean, default=False) autostart = mapped_column(Boolean, default=False) notifications = mapped_column(Boolean, default=False) class USER_DEALS(Base): """ Таблица сделок пользователя. Атрибуты: id (int): Первичный ключ. tg_id (int): Внешний ключ на Telegram пользователя. symbol (str): Торговая пара. side (str): Направление сделки (Buy/Sell). open_price (int): Цена открытия. positive_percent (int): Процент доходности. """ __tablename__ = 'user_deals' id: Mapped[int] = mapped_column(primary_key=True) tg_id = mapped_column(ForeignKey("user_telegram_id.tg_id")) symbol = mapped_column(String(18), default='PENGUUSDT') side = mapped_column(String(10), nullable=False) open_price = mapped_column(Integer(), nullable=False) positive_percent = mapped_column(Integer(), nullable=False) class UserTimer(Base): """ Таймер пользователя для отсроченного запуска сделок. Атрибуты: id (int): Первичный ключ. tg_id (int): Внешний ключ на Telegram пользователя. timer_minutes (int): Количество минут таймера. timer_start (datetime): Время начала таймера. timer_end (Optional[datetime]): Время окончания таймера (если установлено). """ __tablename__ = 'user_timers' id: Mapped[int] = mapped_column(primary_key=True) tg_id = mapped_column(ForeignKey("user_telegram_id.tg_id")) timer_minutes = mapped_column(Integer, nullable=False, default=0) timer_start = mapped_column(DateTime, default=datetime.utcnow) timer_end = mapped_column(DateTime, nullable=True) async def async_main(): """ Асинхронное создание всех таблиц и заполнение справочников начальными данными. """ async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) # Заполнение таблиц modes = ['Long', 'Short', 'Switch', 'Smart'] for mode in modes: result = await conn.execute(select(Trading_Mode).where(Trading_Mode.mode == mode)) if not result.first(): logger.info("Заполение таблицы режима торговли") await conn.execute(Trading_Mode.__table__.insert().values(mode=mode)) types = ['Isolated', 'Cross'] for type in types: result = await conn.execute(select(Margin_type).where(Margin_type.type == type)) if not result.first(): logger.info("Заполение таблицы типов маржи") await conn.execute(Margin_type.__table__.insert().values(type=type)) triggers = ['Ручной', 'Автоматический', 'TradingView'] for trigger in triggers: result = await conn.execute(select(Trigger).where(Trigger.trigger == trigger)) if not result.first(): logger.info("Заполение таблицы триггеров") await conn.execute(Trigger.__table__.insert().values(trigger=trigger))