feat: add Nailong Fund advisor capabilities

This commit is contained in:
Windows
2026-09-11 09:47:40 +08:00
parent 5907fcd6d2
commit a4499defee
143 changed files with 12255 additions and 89 deletions
+79
View File
@@ -0,0 +1,79 @@
"""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)