55 lines
1.8 KiB
Python
55 lines
1.8 KiB
Python
from __future__ import annotations
|
||
|
||
from datetime import date
|
||
from decimal import Decimal
|
||
|
||
from sqlalchemy import (
|
||
BigInteger,
|
||
CheckConstraint,
|
||
Date,
|
||
ForeignKey,
|
||
String,
|
||
UniqueConstraint,
|
||
)
|
||
from sqlalchemy.orm import Mapped, mapped_column
|
||
|
||
from app.core.config import settings
|
||
from app.db.base import Base
|
||
from app.db.types import AuditMixin, IdMixin, Price, qualified
|
||
|
||
|
||
class NominalSource:
|
||
MOEX = "moex" # FACEVALUE из истории торгов
|
||
MANUAL = "manual"
|
||
|
||
|
||
class SecurityNominalHistory(IdMixin, AuditMixin, Base):
|
||
"""Номинал бумаги, действующий с даты valid_from (D11).
|
||
|
||
moex пишется при загрузке котировок, только когда FACEVALUE изменился;
|
||
manual — ручная правка с причиной. На одну дату может быть по строке
|
||
каждого источника, ручная в приоритете.
|
||
"""
|
||
|
||
__tablename__ = "security_nominal_history"
|
||
__table_args__ = (
|
||
UniqueConstraint(
|
||
"security_id",
|
||
"valid_from",
|
||
"source",
|
||
name="uq_security_nominal_history_date_source",
|
||
),
|
||
CheckConstraint(
|
||
"source IN ('moex', 'manual')", name="ck_security_nominal_history_source"
|
||
),
|
||
{"schema": settings.DATABASE_SCHEMA} if settings.DATABASE_SCHEMA else {},
|
||
)
|
||
|
||
security_id: Mapped[int] = mapped_column(
|
||
BigInteger, ForeignKey(qualified("security.id")), nullable=False
|
||
)
|
||
valid_from: Mapped[date] = mapped_column(Date, nullable=False)
|
||
face_value: Mapped[Decimal] = mapped_column(Price, nullable=False)
|
||
source: Mapped[str] = mapped_column(String(10), nullable=False)
|
||
reason: Mapped[str | None] = mapped_column(String(500))
|