2026-09-10 15:55:54 +08:00
|
|
|
|
"""场内基金模拟交易域(fin_*)只读 ORM 映射。
|
|
|
|
|
|
|
|
|
|
|
|
设计约定(强约束):
|
|
|
|
|
|
|
|
|
|
|
|
1. 本模块只做「列映射」:不提供任何写辅助方法(无 insert/update/delete/save/merge),
|
|
|
|
|
|
底座、Agent 与业务组员都不得借本模块下单、改持仓或改交易数据(项目硬性业务红线)。
|
|
|
|
|
|
2. 列名、类型、可空性严格对齐 MySQL 实际结构(information_schema.COLUMNS 逐列核对),
|
|
|
|
|
|
不允许任何 DDL / Alembic 迁移改动库结构;回归校验由 tools/audit_constraints.py 负责。
|
|
|
|
|
|
3. 不声明 ForeignKey:跨表关系由 app/repository/fund_query_repository.py 的
|
|
|
|
|
|
客户数据范围解析器表达,避免 ORM 引入 flush 期级联写语义。
|
|
|
|
|
|
4. 未映射 MySQL 生成列(GENERATION_EXPRESSION 非空)——本域当前没有生成列。
|
|
|
|
|
|
5. 只读查询统一走 app/repository/fund_query_repository.py,Agent(Service 层)
|
|
|
|
|
|
不得直接访问本模块的 ORM 实体。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
from datetime import date, datetime
|
|
|
|
|
|
from decimal import Decimal
|
|
|
|
|
|
from typing import Any
|
|
|
|
|
|
|
|
|
|
|
|
from sqlalchemy import JSON, Date, Integer, Numeric, String, Text
|
|
|
|
|
|
from sqlalchemy.dialects.mysql import BIGINT, DATETIME, TINYINT
|
|
|
|
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
|
|
|
|
|
|
|
|
from app.model.base import Base
|
|
|
|
|
|
|
|
|
|
|
|
__all__ = [
|
|
|
|
|
|
"FundCapitalFlow",
|
|
|
|
|
|
"FundCashLedger",
|
|
|
|
|
|
"FundCustomerProfile",
|
|
|
|
|
|
"FundFeeRule",
|
|
|
|
|
|
"FundHolding",
|
|
|
|
|
|
"FundMarketPrice",
|
|
|
|
|
|
"FundNavHistory",
|
|
|
|
|
|
"FundProduct",
|
|
|
|
|
|
"FundRiskAlert",
|
|
|
|
|
|
"FundRiskAssessment",
|
|
|
|
|
|
"FundRiskNotification",
|
|
|
|
|
|
"FundSimAccount",
|
|
|
|
|
|
"FundSimOrder",
|
|
|
|
|
|
"FundTransaction",
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FundProduct(Base):
|
|
|
|
|
|
"""场内基金产品主数据(fin_product)。"""
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "fin_product"
|
|
|
|
|
|
|
|
|
|
|
|
id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True)
|
|
|
|
|
|
product_code: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
|
|
|
|
product_name: Mapped[str] = mapped_column(String(128), nullable=False)
|
|
|
|
|
|
exchange_code: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
|
|
|
|
product_category: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
|
|
|
|
risk_level: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
|
|
|
fund_manager: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
|
|
|
|
|
currency: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
|
|
|
lot_size: Mapped[Decimal] = mapped_column(Numeric(18, 4), nullable=False)
|
|
|
|
|
|
price_tick: Mapped[Decimal] = mapped_column(Numeric(18, 6), nullable=False)
|
|
|
|
|
|
current_nav: Mapped[Decimal | None] = mapped_column(Numeric(18, 6), nullable=True)
|
|
|
|
|
|
current_nav_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
min_amount: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
open_start_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
open_end_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
open_period_start: Mapped[date | None] = mapped_column(Date, nullable=True)
|
|
|
|
|
|
open_period_end: Mapped[date | None] = mapped_column(Date, nullable=True)
|
|
|
|
|
|
transaction_fee_rate: Mapped[Decimal | None] = mapped_column(Numeric(10, 6), nullable=True)
|
|
|
|
|
|
single_investor_max_holding_ratio: Mapped[Decimal] = mapped_column(
|
|
|
|
|
|
Numeric(7, 4), nullable=False
|
|
|
|
|
|
)
|
|
|
|
|
|
management_fee_rate: Mapped[Decimal | None] = mapped_column(Numeric(7, 4), nullable=True)
|
|
|
|
|
|
custodian_fee_rate: Mapped[Decimal | None] = mapped_column(Numeric(7, 4), nullable=True)
|
|
|
|
|
|
risk_disclosure_required: Mapped[int] = mapped_column(TINYINT(display_width=1), nullable=False)
|
|
|
|
|
|
second_confirmation_required: Mapped[int] = mapped_column(
|
|
|
|
|
|
TINYINT(display_width=1), nullable=False
|
|
|
|
|
|
)
|
|
|
|
|
|
recording_required: Mapped[int] = mapped_column(TINYINT(display_width=1), nullable=False)
|
|
|
|
|
|
status: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
|
|
|
|
created_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
updated_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FundMarketPrice(Base):
|
|
|
|
|
|
"""场内日行情(fin_market_price),行情为公共数据,无客户归属。"""
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "fin_market_price"
|
|
|
|
|
|
|
|
|
|
|
|
id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True)
|
|
|
|
|
|
product_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
trade_date: Mapped[date] = mapped_column(Date, nullable=False)
|
|
|
|
|
|
open_price: Mapped[Decimal] = mapped_column(Numeric(18, 6), nullable=False)
|
|
|
|
|
|
high_price: Mapped[Decimal] = mapped_column(Numeric(18, 6), nullable=False)
|
|
|
|
|
|
low_price: Mapped[Decimal] = mapped_column(Numeric(18, 6), nullable=False)
|
|
|
|
|
|
close_price: Mapped[Decimal] = mapped_column(Numeric(18, 6), nullable=False)
|
2026-09-14 00:30:06 +08:00
|
|
|
|
#: 当日涨跌幅(%),来自行情源。**可空**:源未提供、或该行由不提供涨跌幅的降级路径
|
|
|
|
|
|
#: (如 `eastmoney_nav_fallback`)写入时为 NULL —— 调用方必须显示"暂无"而不是当成 0。
|
|
|
|
|
|
change_pct: Mapped[Decimal | None] = mapped_column(Numeric(10, 4), nullable=True)
|
2026-09-10 15:55:54 +08:00
|
|
|
|
volume: Mapped[Decimal | None] = mapped_column(Numeric(24, 4), nullable=True)
|
|
|
|
|
|
turnover_amount: Mapped[Decimal | None] = mapped_column(Numeric(24, 2), nullable=True)
|
|
|
|
|
|
total_fund_shares: Mapped[Decimal] = mapped_column(Numeric(24, 4), nullable=False)
|
|
|
|
|
|
source: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
|
|
|
|
source_updated_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
created_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FundNavHistory(Base):
|
|
|
|
|
|
"""基金净值历史(fin_nav_history),公共数据。"""
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "fin_nav_history"
|
|
|
|
|
|
|
|
|
|
|
|
id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True)
|
|
|
|
|
|
product_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
nav_date: Mapped[date] = mapped_column(Date, nullable=False)
|
|
|
|
|
|
nav: Mapped[Decimal] = mapped_column(Numeric(12, 6), nullable=False)
|
|
|
|
|
|
created_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FundSimAccount(Base):
|
|
|
|
|
|
"""模拟资金账户(fin_sim_account)。"""
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "fin_sim_account"
|
|
|
|
|
|
|
|
|
|
|
|
id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True)
|
|
|
|
|
|
account_no: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
|
|
|
|
customer_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
currency: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
|
|
|
cash_balance: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
available_cash: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
frozen_cash: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
initial_balance: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
status: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
|
|
|
|
version: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
created_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
updated_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FundCashLedger(Base):
|
|
|
|
|
|
"""资金流水(fin_cash_ledger)。无 customer_id,客户归属经 account_id 间接解析。"""
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "fin_cash_ledger"
|
|
|
|
|
|
|
|
|
|
|
|
id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True)
|
|
|
|
|
|
ledger_no: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
|
|
|
account_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
transaction_id: Mapped[int | None] = mapped_column(BIGINT(unsigned=True), nullable=True)
|
|
|
|
|
|
entry_type: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
|
|
|
|
amount: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
balance_after: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
available_cash_after: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
frozen_cash_after: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
idempotency_key: Mapped[str] = mapped_column(String(128), nullable=False)
|
|
|
|
|
|
occurred_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
created_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FundCapitalFlow(Base):
|
|
|
|
|
|
"""资金划转/出入金流水(fin_capital_flow)。"""
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "fin_capital_flow"
|
|
|
|
|
|
|
|
|
|
|
|
id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True)
|
|
|
|
|
|
flow_no: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
|
|
|
customer_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
account_id: Mapped[int | None] = mapped_column(BIGINT(unsigned=True), nullable=True)
|
|
|
|
|
|
transaction_id: Mapped[int | None] = mapped_column(BIGINT(unsigned=True), nullable=True)
|
|
|
|
|
|
flow_type: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
|
|
|
|
amount: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
balance_after: Mapped[Decimal | None] = mapped_column(Numeric(18, 2), nullable=True)
|
|
|
|
|
|
status: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
|
|
|
|
settled_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
occurred_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
payer_name: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
|
|
|
|
|
source_type: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
|
|
|
|
related_work_order_id: Mapped[int | None] = mapped_column(BIGINT(unsigned=True), nullable=True)
|
|
|
|
|
|
match_status: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
|
|
|
|
created_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
updated_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FundFeeRule(Base):
|
|
|
|
|
|
"""费率规则(fin_fee_rule),配置型公共数据。"""
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "fin_fee_rule"
|
|
|
|
|
|
|
|
|
|
|
|
id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True)
|
|
|
|
|
|
rule_code: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
|
|
|
product_id: Mapped[int | None] = mapped_column(BIGINT(unsigned=True), nullable=True)
|
|
|
|
|
|
exchange_code: Mapped[str | None] = mapped_column(String(16), nullable=True)
|
|
|
|
|
|
order_side: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
|
|
|
customer_tier: Mapped[str | None] = mapped_column(String(16), nullable=True)
|
|
|
|
|
|
min_trade_amount: Mapped[Decimal | None] = mapped_column(Numeric(18, 2), nullable=True)
|
|
|
|
|
|
max_trade_amount: Mapped[Decimal | None] = mapped_column(Numeric(18, 2), nullable=True)
|
|
|
|
|
|
fee_rate: Mapped[Decimal] = mapped_column(Numeric(10, 6), nullable=False)
|
|
|
|
|
|
minimum_fee: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
fixed_fee: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
priority: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
|
|
|
|
effective_from: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
effective_until: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
status: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
|
|
|
|
created_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
updated_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FundSimOrder(Base):
|
|
|
|
|
|
"""模拟委托单(fin_sim_order)。只读查询,禁止在此写入委托。"""
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "fin_sim_order"
|
|
|
|
|
|
|
|
|
|
|
|
id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True)
|
|
|
|
|
|
order_no: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
|
|
|
customer_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
account_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
product_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
order_side: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
|
|
|
price_type: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
|
|
|
quantity: Mapped[Decimal] = mapped_column(Numeric(18, 4), nullable=False)
|
|
|
|
|
|
limit_price: Mapped[Decimal | None] = mapped_column(Numeric(18, 6), nullable=True)
|
|
|
|
|
|
quote_price: Mapped[Decimal] = mapped_column(Numeric(18, 6), nullable=False)
|
|
|
|
|
|
quote_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
quote_source: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
|
|
|
|
channel: Mapped[str | None] = mapped_column(String(32), nullable=True)
|
|
|
|
|
|
advisor_id: Mapped[int | None] = mapped_column(BIGINT(unsigned=True), nullable=True)
|
|
|
|
|
|
filled_quantity: Mapped[Decimal] = mapped_column(Numeric(18, 4), nullable=False)
|
|
|
|
|
|
average_executed_price: Mapped[Decimal | None] = mapped_column(Numeric(18, 6), nullable=True)
|
|
|
|
|
|
status: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
|
|
|
|
risk_rule_hits: Mapped[Any | None] = mapped_column(JSON, nullable=True)
|
|
|
|
|
|
risk_disclosure_ack_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
second_confirmation_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
recording_reference: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
|
|
|
|
|
ops_handler_id: Mapped[int | None] = mapped_column(BIGINT(unsigned=True), nullable=True)
|
|
|
|
|
|
ops_handled_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
compliance_handler_id: Mapped[int | None] = mapped_column(BIGINT(unsigned=True), nullable=True)
|
|
|
|
|
|
compliance_handled_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
reject_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
|
|
submitted_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
cancelled_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
created_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
updated_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FundTransaction(Base):
|
|
|
|
|
|
"""成交记录(fin_transaction)。只读查询,禁止在此写入成交。"""
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "fin_transaction"
|
|
|
|
|
|
|
|
|
|
|
|
id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True)
|
|
|
|
|
|
transaction_no: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
|
|
|
order_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
work_order_id: Mapped[int | None] = mapped_column(BIGINT(unsigned=True), nullable=True)
|
|
|
|
|
|
customer_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
account_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
product_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
order_side: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
|
|
|
transaction_type: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
|
|
|
|
executed_price: Mapped[Decimal] = mapped_column(Numeric(18, 6), nullable=False)
|
|
|
|
|
|
nav: Mapped[Decimal] = mapped_column(Numeric(12, 6), nullable=False)
|
|
|
|
|
|
executed_quantity: Mapped[Decimal] = mapped_column(Numeric(18, 4), nullable=False)
|
|
|
|
|
|
shares: Mapped[Decimal] = mapped_column(Numeric(18, 4), nullable=False)
|
|
|
|
|
|
gross_amount: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
amount: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
fee_rule_id: Mapped[int | None] = mapped_column(BIGINT(unsigned=True), nullable=True)
|
|
|
|
|
|
fee_rate_snapshot: Mapped[Decimal] = mapped_column(Numeric(10, 6), nullable=False)
|
|
|
|
|
|
fee_amount: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
fee: Mapped[Decimal | None] = mapped_column(Numeric(18, 2), nullable=True)
|
|
|
|
|
|
net_amount: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
quote_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
quote_source: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
|
|
|
|
executed_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
confirmed_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
confirmed_by: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
|
|
|
|
auto_confirmed: Mapped[int] = mapped_column(TINYINT(display_width=1), nullable=False)
|
|
|
|
|
|
created_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FundHolding(Base):
|
|
|
|
|
|
"""持仓(fin_holding)。只读查询,禁止在此修改持仓。"""
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "fin_holding"
|
|
|
|
|
|
|
|
|
|
|
|
id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True)
|
|
|
|
|
|
customer_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
trade_account: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
|
|
|
|
product_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
total_quantity: Mapped[Decimal] = mapped_column(Numeric(18, 4), nullable=False)
|
|
|
|
|
|
shares: Mapped[Decimal] = mapped_column(Numeric(18, 4), nullable=False)
|
|
|
|
|
|
available_quantity: Mapped[Decimal] = mapped_column(Numeric(18, 4), nullable=False)
|
|
|
|
|
|
frozen_quantity: Mapped[Decimal] = mapped_column(Numeric(18, 4), nullable=False)
|
|
|
|
|
|
average_cost: Mapped[Decimal] = mapped_column(Numeric(18, 6), nullable=False)
|
|
|
|
|
|
cost_amount: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
market_value: Mapped[Decimal | None] = mapped_column(Numeric(18, 2), nullable=True)
|
|
|
|
|
|
current_value: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
profit_loss: Mapped[Decimal | None] = mapped_column(Numeric(18, 2), nullable=True)
|
|
|
|
|
|
profit_loss_ratio: Mapped[Decimal | None] = mapped_column(Numeric(10, 4), nullable=True)
|
|
|
|
|
|
status: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
|
|
|
|
first_acquired_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
version: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
updated_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FundCustomerProfile(Base):
|
|
|
|
|
|
"""客户画像(fin_customer_profile),主键为 customer_id。"""
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "fin_customer_profile"
|
|
|
|
|
|
|
|
|
|
|
|
customer_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True)
|
|
|
|
|
|
trade_account: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
|
|
|
|
real_name: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
|
|
|
birth_date: Mapped[date | None] = mapped_column(Date, nullable=True)
|
|
|
|
|
|
occupation: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
|
|
|
|
|
mobile_masked: Mapped[str | None] = mapped_column(String(32), nullable=True)
|
|
|
|
|
|
investor_type: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
|
|
|
investment_horizon: Mapped[str | None] = mapped_column(String(32), nullable=True)
|
|
|
|
|
|
preferred_asset_class: Mapped[Any | None] = mapped_column(JSON, nullable=True)
|
|
|
|
|
|
trading_frequency: Mapped[str | None] = mapped_column(String(32), nullable=True)
|
|
|
|
|
|
last_active_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
total_asset: Mapped[Decimal] = mapped_column(Numeric(18, 2), nullable=False)
|
|
|
|
|
|
behavior_score: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
|
|
|
|
risk_tags: Mapped[Any | None] = mapped_column(JSON, nullable=True)
|
|
|
|
|
|
opened_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
updated_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FundRiskAssessment(Base):
|
|
|
|
|
|
"""风险测评记录(fin_risk_assessment)。"""
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "fin_risk_assessment"
|
|
|
|
|
|
|
|
|
|
|
|
id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True)
|
|
|
|
|
|
customer_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
questionnaire_version: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
|
|
|
|
answers: Mapped[Any] = mapped_column(JSON, nullable=False)
|
|
|
|
|
|
total_score: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
|
|
|
|
investor_type: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
|
|
|
assessed_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
valid_until: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
created_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FundRiskAlert(Base):
|
|
|
|
|
|
"""风险预警事件(fin_risk_alert)。"""
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "fin_risk_alert"
|
|
|
|
|
|
|
|
|
|
|
|
id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True)
|
|
|
|
|
|
alert_no: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
|
|
|
customer_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
related_transaction_id: Mapped[int | None] = mapped_column(
|
|
|
|
|
|
BIGINT(unsigned=True), nullable=True
|
|
|
|
|
|
)
|
|
|
|
|
|
related_order_id: Mapped[int | None] = mapped_column(BIGINT(unsigned=True), nullable=True)
|
|
|
|
|
|
related_work_order_id: Mapped[int | None] = mapped_column(BIGINT(unsigned=True), nullable=True)
|
|
|
|
|
|
primary_risk_work_order_id: Mapped[int | None] = mapped_column(
|
|
|
|
|
|
BIGINT(unsigned=True), nullable=True
|
|
|
|
|
|
)
|
|
|
|
|
|
alert_type: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
|
|
|
alert_level: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
|
|
|
trigger_rule_codes: Mapped[Any] = mapped_column(JSON, nullable=False)
|
|
|
|
|
|
evidence_summary: Mapped[str] = mapped_column(Text, nullable=False)
|
|
|
|
|
|
evidence_snapshot: Mapped[Any] = mapped_column(JSON, nullable=False)
|
|
|
|
|
|
priority_score: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
|
|
|
|
event_status: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
|
|
|
|
status: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
|
|
|
|
ack_status: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
|
|
|
|
ack_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
handler_id: Mapped[int | None] = mapped_column(BIGINT(unsigned=True), nullable=True)
|
|
|
|
|
|
due_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
is_escalated: Mapped[int] = mapped_column(TINYINT(display_width=1), nullable=False)
|
|
|
|
|
|
escalated_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
escalation_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
|
|
handle_result: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
|
|
closed_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
close_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
|
|
ai_analysis: Mapped[Any | None] = mapped_column(JSON, nullable=True)
|
|
|
|
|
|
manual_remark: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
|
|
created_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
updated_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FundRiskNotification(Base):
|
|
|
|
|
|
"""风险通知(fin_risk_notification)。无 customer_id,客户归属经 alert_id 间接解析。"""
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "fin_risk_notification"
|
|
|
|
|
|
|
|
|
|
|
|
id: Mapped[int] = mapped_column(BIGINT(unsigned=True), primary_key=True)
|
|
|
|
|
|
notification_no: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
|
|
|
alert_id: Mapped[int] = mapped_column(BIGINT(unsigned=True), nullable=False)
|
|
|
|
|
|
channel: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
|
|
|
|
receiver_user_id: Mapped[int | None] = mapped_column(BIGINT(unsigned=True), nullable=True)
|
|
|
|
|
|
receiver_email: Mapped[str | None] = mapped_column(String(128), nullable=True)
|
|
|
|
|
|
title: Mapped[str] = mapped_column(String(128), nullable=False)
|
|
|
|
|
|
content: Mapped[str] = mapped_column(Text, nullable=False)
|
|
|
|
|
|
send_status: Mapped[str] = mapped_column(String(16), nullable=False)
|
|
|
|
|
|
sent_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
read_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
acknowledged_at: Mapped[datetime | None] = mapped_column(DATETIME(fsp=0), nullable=True)
|
|
|
|
|
|
fail_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
|
|
|
|
created_at: Mapped[datetime] = mapped_column(DATETIME(fsp=0), nullable=False)
|