develop #3
@@ -1,31 +1,55 @@
|
|||||||
import logging
|
from datetime import datetime
|
||||||
from datetime import datetime
|
import logging.config
|
||||||
|
|
||||||
from sqlalchemy.sql.sqltypes import DateTime
|
from sqlalchemy.sql.sqltypes import DateTime
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
from sqlalchemy import BigInteger, Boolean, Integer, String, ForeignKey
|
from sqlalchemy import BigInteger, Boolean, Integer, String, ForeignKey
|
||||||
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
|
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
|
||||||
from sqlalchemy.ext.asyncio import AsyncAttrs, async_sessionmaker, create_async_engine
|
from sqlalchemy.ext.asyncio import AsyncAttrs, async_sessionmaker, create_async_engine
|
||||||
|
from logger_helper.logger_helper import LOGGING_CONFIG
|
||||||
from sqlalchemy import select, insert
|
from sqlalchemy import select, insert
|
||||||
|
|
||||||
|
logging.config.dictConfig(LOGGING_CONFIG)
|
||||||
|
logger = logging.getLogger("models")
|
||||||
|
|
||||||
engine = create_async_engine(url='sqlite+aiosqlite:///db.sqlite3')
|
engine = create_async_engine(url='sqlite+aiosqlite:///db.sqlite3')
|
||||||
|
|
||||||
async_session = async_sessionmaker(engine)
|
async_session = async_sessionmaker(engine)
|
||||||
|
|
||||||
|
|
||||||
class Base(AsyncAttrs, DeclarativeBase):
|
class Base(AsyncAttrs, DeclarativeBase):
|
||||||
|
"""Базовый класс для declarative моделей SQLAlchemy с поддержкой async."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class User_Telegram_Id(Base):
|
class User_Telegram_Id(Base):
|
||||||
|
"""
|
||||||
|
Модель таблицы user_telegram_id.
|
||||||
|
|
||||||
|
Хранит идентификаторы Telegram пользователей.
|
||||||
|
|
||||||
|
Атрибуты:
|
||||||
|
id (int): Внутренний первичный ключ записи.
|
||||||
|
tg_id (int): Уникальный идентификатор пользователя Telegram.
|
||||||
|
"""
|
||||||
__tablename__ = 'user_telegram_id'
|
__tablename__ = 'user_telegram_id'
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
|
|
||||||
tg_id = mapped_column(BigInteger)
|
tg_id = mapped_column(BigInteger)
|
||||||
|
|
||||||
|
|
||||||
class User_Bybit_API(Base):
|
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'
|
__tablename__ = 'user_bybit_api'
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
@@ -35,7 +59,26 @@ class User_Bybit_API(Base):
|
|||||||
api_key = mapped_column(String(18), default='None')
|
api_key = mapped_column(String(18), default='None')
|
||||||
secret_key = mapped_column(String(36), default='None')
|
secret_key = mapped_column(String(36), default='None')
|
||||||
|
|
||||||
|
|
||||||
class User_Symbol(Base):
|
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'
|
__tablename__ = 'user_symbols'
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
@@ -44,28 +87,69 @@ class User_Symbol(Base):
|
|||||||
|
|
||||||
symbol = mapped_column(String(18), default='PENGUUSDT')
|
symbol = mapped_column(String(18), default='PENGUUSDT')
|
||||||
|
|
||||||
|
|
||||||
class Trading_Mode(Base):
|
class Trading_Mode(Base):
|
||||||
|
"""
|
||||||
|
Справочник доступных режимов торговли.
|
||||||
|
|
||||||
|
Атрибуты:
|
||||||
|
id (int): Первичный ключ.
|
||||||
|
mode (str): Уникальный режим (например, 'Long', 'Short').
|
||||||
|
"""
|
||||||
__tablename__ = 'trading_modes'
|
__tablename__ = 'trading_modes'
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
|
|
||||||
mode = mapped_column(String(10), unique=True)
|
mode = mapped_column(String(10), unique=True)
|
||||||
|
|
||||||
|
|
||||||
class Margin_type(Base):
|
class Margin_type(Base):
|
||||||
|
"""
|
||||||
|
Справочник типов маржинальной торговли.
|
||||||
|
|
||||||
|
Атрибуты:
|
||||||
|
id (int): Первичный ключ.
|
||||||
|
type (str): Тип маржи (например, 'Isolated', 'Cross').
|
||||||
|
"""
|
||||||
__tablename__ = 'margin_types'
|
__tablename__ = 'margin_types'
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
|
|
||||||
type = mapped_column(String(15), unique=True)
|
type = mapped_column(String(15), unique=True)
|
||||||
|
|
||||||
|
|
||||||
class Trigger(Base):
|
class Trigger(Base):
|
||||||
|
"""
|
||||||
|
Справочник видов триггеров для сделок.
|
||||||
|
|
||||||
|
Атрибуты:
|
||||||
|
id (int): Первичный ключ.
|
||||||
|
trigger (str): Название триггера (например, 'Ручной', 'Автоматический').
|
||||||
|
"""
|
||||||
__tablename__ = 'triggers'
|
__tablename__ = 'triggers'
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
|
|
||||||
trigger = mapped_column(String(15), unique=True)
|
trigger = mapped_column(String(15), unique=True)
|
||||||
|
|
||||||
|
|
||||||
class User_Main_Settings(Base):
|
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'
|
__tablename__ = 'user_main_settings'
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
@@ -84,6 +168,17 @@ class User_Main_Settings(Base):
|
|||||||
|
|
||||||
|
|
||||||
class User_Risk_Management_Settings(Base):
|
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'
|
__tablename__ = 'user_risk_management_settings'
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
@@ -93,9 +188,24 @@ class User_Risk_Management_Settings(Base):
|
|||||||
price_profit = mapped_column(Integer(), default=1)
|
price_profit = mapped_column(Integer(), default=1)
|
||||||
price_loss = mapped_column(Integer(), default=1)
|
price_loss = mapped_column(Integer(), default=1)
|
||||||
max_risk_deal = mapped_column(Integer(), default=100)
|
max_risk_deal = mapped_column(Integer(), default=100)
|
||||||
commission_fee = mapped_column(Integer(), default=0)
|
commission_fee = mapped_column(String(), default="Да")
|
||||||
|
|
||||||
|
|
||||||
class User_Condition_Settings(Base):
|
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'
|
__tablename__ = 'user_condition_settings'
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
@@ -110,7 +220,18 @@ class User_Condition_Settings(Base):
|
|||||||
webhook = mapped_column(String(40), default='')
|
webhook = mapped_column(String(40), default='')
|
||||||
ai_analytics = mapped_column(Boolean, default=False)
|
ai_analytics = mapped_column(Boolean, default=False)
|
||||||
|
|
||||||
|
|
||||||
class User_Additional_Settings(Base):
|
class User_Additional_Settings(Base):
|
||||||
|
"""
|
||||||
|
Прочие дополнительные настройки пользователя.
|
||||||
|
|
||||||
|
Атрибуты:
|
||||||
|
id (int): Первичный ключ.
|
||||||
|
tg_id (int): Внешний ключ на Telegram пользователя.
|
||||||
|
pattern_save (bool): Сохранять ли шаблоны.
|
||||||
|
autostart (bool): Автоматический запуск.
|
||||||
|
notifications (bool): Получение уведомлений.
|
||||||
|
"""
|
||||||
__tablename__ = 'user_additional_settings'
|
__tablename__ = 'user_additional_settings'
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
@@ -121,34 +242,19 @@ class User_Additional_Settings(Base):
|
|||||||
autostart = mapped_column(Boolean, default=False)
|
autostart = mapped_column(Boolean, default=False)
|
||||||
notifications = mapped_column(Boolean, default=False)
|
notifications = mapped_column(Boolean, default=False)
|
||||||
|
|
||||||
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))
|
|
||||||
|
|
||||||
|
|
||||||
class USER_DEALS(Base):
|
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'
|
__tablename__ = 'user_deals'
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
@@ -162,10 +268,50 @@ class USER_DEALS(Base):
|
|||||||
|
|
||||||
|
|
||||||
class UserTimer(Base):
|
class UserTimer(Base):
|
||||||
|
"""
|
||||||
|
Таймер пользователя для отсроченного запуска сделок.
|
||||||
|
|
||||||
|
Атрибуты:
|
||||||
|
id (int): Первичный ключ.
|
||||||
|
tg_id (int): Внешний ключ на Telegram пользователя.
|
||||||
|
timer_minutes (int): Количество минут таймера.
|
||||||
|
timer_start (datetime): Время начала таймера.
|
||||||
|
timer_end (Optional[datetime]): Время окончания таймера (если установлено).
|
||||||
|
"""
|
||||||
__tablename__ = 'user_timers'
|
__tablename__ = 'user_timers'
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
tg_id = mapped_column(ForeignKey("user_telegram_id.tg_id"))
|
tg_id = mapped_column(ForeignKey("user_telegram_id.tg_id"))
|
||||||
timer_minutes = mapped_column(Integer, nullable=False, default=0)
|
timer_minutes = mapped_column(Integer, nullable=False, default=0)
|
||||||
timer_start = mapped_column(DateTime, default=datetime.utcnow)
|
timer_start = mapped_column(DateTime, default=datetime.utcnow)
|
||||||
timer_end = mapped_column(DateTime, nullable=True)
|
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))
|
||||||
|
@@ -85,5 +85,10 @@ LOGGING_CONFIG = {
|
|||||||
"level": "DEBUG",
|
"level": "DEBUG",
|
||||||
"propagate": False,
|
"propagate": False,
|
||||||
},
|
},
|
||||||
|
"models": {
|
||||||
|
"handlers": ["console", "timed_rotating_file"],
|
||||||
|
"level": "DEBUG",
|
||||||
|
"propagate": False,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user