Files
group_fqcd_jr/app/model/advisor.py
T

80 lines
4.4 KiB
Python
Raw Normal View History

2026-09-11 09:47:40 +08:00
"""Persistence models for the advisory investment-goal workflow."""
from datetime import date, datetime
from decimal import Decimal
from typing import Any
from sqlalchemy import JSON, BigInteger, Date, DateTime, Integer, Numeric, String, Text
from sqlalchemy.orm import Mapped, mapped_column
from app.model.base import Base
class ClientFacingContent(Base):
"""Existing baseline content-review resource used for goal-book drafts."""
__tablename__ = "client_facing_content"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
customer_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
content_type: Mapped[str] = mapped_column(String(32), nullable=False)
draft_content: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
generated_by_portal: Mapped[str] = mapped_column(String(32), nullable=False)
review_status: Mapped[str] = mapped_column(String(16), nullable=False)
reviewer_user_id: Mapped[int | None] = mapped_column(BigInteger)
reviewed_at: Mapped[datetime | None] = mapped_column(DateTime)
published_at: Mapped[datetime | None] = mapped_column(DateTime)
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
class AdvisorInvestmentGoal(Base):
"""An immutable collected goal version; confirmation activates it for later planning."""
__tablename__ = "advisor_investment_goal"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
goal_no: Mapped[str] = mapped_column(String(36), unique=True, nullable=False)
customer_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
status: Mapped[str] = mapped_column(String(24), nullable=False)
annualized_return_lower_pct: Mapped[Decimal] = mapped_column(Numeric(7, 4), nullable=False)
annualized_return_upper_pct: Mapped[Decimal] = mapped_column(Numeric(7, 4), nullable=False)
max_drawdown_pct: Mapped[Decimal] = mapped_column(Numeric(7, 4), nullable=False)
liquidity_requirement: Mapped[str] = mapped_column(String(32), nullable=False)
investment_horizon_months: Mapped[int] = mapped_column(Integer, nullable=False)
benchmark_name: Mapped[str] = mapped_column(String(128), nullable=False)
notes: Mapped[str | None] = mapped_column(Text)
source: Mapped[str] = mapped_column(String(16), nullable=False)
goal_book_content_id: Mapped[int] = mapped_column(BigInteger, nullable=False, unique=True)
created_by: Mapped[int] = mapped_column(BigInteger, nullable=False)
confirmed_by: Mapped[int | None] = mapped_column(BigInteger)
confirmed_at: Mapped[datetime | None] = mapped_column(DateTime)
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
class AllocationBacktestRun(Base):
"""Stored, analysis-only evidence for a dynamic allocation strategy run."""
__tablename__ = "advisor_allocation_backtest_run"
id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
backtest_no: Mapped[str] = mapped_column(String(36), unique=True, nullable=False)
started_on: Mapped[date] = mapped_column(Date, nullable=False)
ended_on: Mapped[date] = mapped_column(Date, nullable=False)
profile_risk_level: Mapped[str] = mapped_column(String(8), nullable=False)
return_target_lower_pct: Mapped[Decimal] = mapped_column(Numeric(7, 4), nullable=False)
max_drawdown_pct: Mapped[Decimal] = mapped_column(Numeric(7, 4), nullable=False)
liquidity_requirement: Mapped[str] = mapped_column(String(32), nullable=False)
status: Mapped[str] = mapped_column(String(32), nullable=False)
observation_count: Mapped[int] = mapped_column(BigInteger, nullable=False)
static_total_return_pct: Mapped[Decimal | None] = mapped_column(Numeric(12, 4))
dynamic_total_return_pct: Mapped[Decimal | None] = mapped_column(Numeric(12, 4))
static_max_drawdown_pct: Mapped[Decimal | None] = mapped_column(Numeric(12, 4))
dynamic_max_drawdown_pct: Mapped[Decimal | None] = mapped_column(Numeric(12, 4))
dynamic_rebalance_count: Mapped[int] = mapped_column(BigInteger, nullable=False)
liquidity_history_coverage_pct: Mapped[Decimal] = mapped_column(Numeric(7, 4), nullable=False)
limitations: Mapped[list[str]] = mapped_column(JSON, nullable=False)
strategy_version: Mapped[str] = mapped_column(String(32), nullable=False)
created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)