Skip to content

投资分析数据模型(Security / Equity / Fund / Allocations)

retail-api 把每一笔持仓——无论是个股还是基金/ETF——都建模成一行 securities 记录,再挂上对应类型的分类信息(equitiesfunds)。基金还带有自己在多个维度上的百分比拆分(资产类型、行业、市场、类别、股票风格、债券信用等级),数据来自 Morningstar。这样,顾问端的”投资分析”页面就能**穿透(look-through)**基金持仓,并与直接持有的个股合并,算出家庭层面的组合分析指标。

erDiagram
    securities ||--o| equities : "type=equity"
    securities ||--o| funds : "type=fund"
    securities ||--o{ prices : "security_id"
    securities ||--o{ positions : "security_id(实际持仓)"
    securities ||--o{ target_category_mix_allocations : "security_id(可选,针对单个证券的目标配置)"

    equities }o--|| categories : "category_id(14 个类别之一)"
    equities }o--|| sectors : "sector_id"

    funds ||--o| allocations_by_asset_type : "fund_id — 股/债/现金/其他 拆分"
    funds ||--o| allocations_by_market : "fund_id — 发达/新兴市场拆分"
    funds ||--o{ allocations_by_category : "fund_id — 14 个类别各自占比"
    funds ||--o{ allocations_by_sector : "fund_id — 各行业占比"
    funds ||--o| fund_bond_portfolios : "fund_id"
    funds ||--o| fund_equity_portfolios : "fund_id"

    fund_bond_portfolios ||--o| allocations_by_bond_quality : "fund_bond_portfolio_id — AAA...below/unrated 占比"
    fund_equity_portfolios ||--o{ allocations_by_equity_style : "fund_equity_portfolio_id — 市值x估值 占比"
Security 类型分类数据来源权重
equity(个股)equities.category_id / equities.sector_id —— 单一一个类别、单一一个行业100%
fund(基金)allocations_by_categoryallocations_by_sectorallocations_by_asset_typeallocations_by_equity_styleallocations_by_bond_quality百分比拆分,合计 100%
fixed_income(固定收益)非 Morningstar 来源(手动录入的债券/CD)0% 权益类

关系定义在生成的基类里:vendor/rightcapital/core-models/src/Schemas/{Security,Fund,Equity,FundBondPortfolio,FundEquityPortfolio}.php;retail-api 的 App\Models\{Security,Fund,Equity} 继承这些基类,并在此之上补充下面的穿透(look-through)访问器。

App\Models\Security 对外暴露一套统一的访问器接口,不管底层是个股还是基金,调用方都不需要按类型分支处理:

访问器个股(100% 落在一个桶里)基金(百分比拆分)文件位置
getEquityPercentageAttribute()100$this->fund->equity_percentage(由 allocations_by_asset_type 推导)app/Models/Security.php:60-79
getPercentagesByEquityStyleAttribute()来自 equities 行的 {capitalization: {valuation: 100}}$this->fund->percentages_by_equity_style(来自 fund_equity_portfolios.allocations_by_equity_style)app/Models/Security.php:92-117
getPercentagesByEquitySectorIdAttribute(){sector_id: 100}$this->fund->percentages_by_equity_sector_id(来自 allocations_by_sector,过滤出权益类行业)app/Models/Security.php:180-201
getPercentagesByBondSectorIdAttribute()[]$this->fund->percentages_by_bond_sector_idapp/Models/Security.php:130-147
getPercentagesByCategoryIdAttribute(){category_id: 100}$this->fund->percentages_by_category_id(来自 allocations_by_category)app/Models/Security.php:152-175
getPrice()Price::getAdjustedClose($this->id, ...)同上app/Models/Security.php:208-211

Position(app/Models/Position.php:99-139)把上述所有访问器都转发给 getUnderlyingSecurity()——一笔持仓在任意维度拆分中的贡献 = 市值 × equity_percentage × 该维度百分比InvestmentAccount(app/Models/InvestmentAccount.php:335-446)按账户汇总,App\Models\Support\Investment(app/Models/Support/Investment.php:120-178)再跨账户汇总到整个家庭。计算结果按 security 缓存在 Redis 里(ONE_DAY_IN_SECONDS / ONE_WEEK_IN_SECONDS 标签),因为同一只基金的拆分数据会被家庭里持有它的每一笔持仓重复复用。

以下四个页面都在 app/Http/Controllers/Calculate/Advisors/Households/Investment/ 目录下:

页面Controller计算内容
Asset Allocation(资产配置)AllocationController.php:46-189把家庭全部持仓按 category_id(14 个类别)穿透聚合 → 当前配置饼图;与顾问设置的 investment_target_category_mix(目标模型)对比 → 目标配置。输出偏离明细表/图、按金额的再平衡建议,以及双方的预期收益/标准差(用到 资产收益与相关性假设体系 里的假设参数)。
Equity Sector & Style(股票行业与风格)EquitySectorAndStyleController.php:34-90把权益类持仓按 sector_id 和风格箱(市值 × 估值)穿透聚合,再与一个基准证券(默认 VTI,本身也是一只 Morningstar 基金)对比——“你的组合 vs 指数”图。
Concentration(集中度)ConcentrationController.php:33-168security_id 跨账户汇总市值(含公开股票计划持仓),标记单一证券占比过高的集中度风险。
Tax Allocation(税务配置)TaxAllocationController.php按账户的税务属性(应税 / 递延 / 免税)拆分配置,同样叠加上面的类别穿透逻辑。

TargetCategoryMixAllocation(vendor/rightcapital/core-models/src/Schemas/TargetCategoryMixAllocation.php)允许顾问的目标模型既可以指定一个 category_id(粗粒度目标,比如”20% Large Growth”),也可以直接指定一个 security_id(比如给一只集中持有的个股定”10% AAPL”的目标)——两者都会进入同一个 Allocation 页面的对比逻辑。

  • retail-api(web-service/api)仓库 —— app/Models/{Security,Fund,Equity,Position,InvestmentAccount,Category}.phpapp/Models/Support/Investment.phpapp/Http/Controllers/Calculate/Advisors/Households/Investment/*.php,读取于 develop 分支,2026-07。
  • vendor/rightcapital/core-models composer 包 —— src/Schemas/{Security,Fund,Equity,FundBondPortfolio,FundEquityPortfolio,TargetCategoryMixAllocation}.php