Skip to content

资产收益与相关性假设体系(8 大类 / 14 小类)

RightCapital 的资本市场假设分成两层,都落在同一张 categories 表上:14 个细分类别各自有自己的预期收益和波动率假设,但只有它们归属的 8 个更粗的分组才有相关性矩阵。App\Engine\ScenGen\ScenarioGenerator 把这两层数据合并,喂给原生的蒙特卡洛场景生成器二进制程序(scen_gen-*),驱动退休/财务目标的成功概率模拟和压力测试。

flowchart TB
    subgraph L1["14 个细分类别 —— 各自有收益 + 波动率"]
        C1["1-4: Large Growth, Large Value, Mid Cap, Small Cap"]
        C2["5: International Equities"]
        C3["6: Emerging Markets"]
        C4["7: Real Estate"]
        C5["8-11: Government, Municipal, Corporate, High Yield"]
        C6["12: International Bonds"]
        C7["13: Cash"]
        C8["14: Other"]
    end
    subgraph L2["8 个 CategoryGroup 引擎大类 —— 只承载相关性矩阵"]
        G1["US_EQUITIES (1)"]
        G2["INTERNATIONAL_EQUITIES (2)"]
        G3["EMERGING_MARKETS (3)"]
        G4["REAL_ESTATE (4)"]
        G5["US_BONDS (5)"]
        G6["INTERNATIONAL_BONDS (6)"]
        G7["CASH (7)"]
        G8["OTHER (8)"]
    end
    C1-->G1
    C2-->G2
    C3-->G3
    C4-->G4
    C5-->G5
    C6-->G6
    C7-->G7
    C8-->G8

映射关系已用本地 rightcapital.categories 表(idnamegroup 列)验证:

category_id类别名称CategoryGroup(8 大类)getEngineClassId()
1–4Large Growth, Large Value, Mid Cap, Small CapUS_EQUITIES1
5International EquitiesINTERNATIONAL_EQUITIES2
6Emerging MarketsEMERGING_MARKETS3
7Real EstateREAL_ESTATE4
8–11Government, Municipal, Corporate, High YieldUS_BONDS5
12International BondsINTERNATIONAL_BONDS6
13CashCASH7
14OtherOTHER8

category_id 1–14 是内置的”基础类别”(RightCapital\Core\Models\Category::ID_LARGE_GROWTHID_OTHER,定义在 vendor/rightcapital/core-models/src/Models/Category.php:21-34);机构/顾问自定义的类别从 ID_CUSTOM_MIN = 101 开始,同样也带一个 groupCategoryGroup 本身定义在 vendor/rightcapital/core-models/src/Enums/Category/CategoryGroup.php

这也正是 投资分析 里穿透聚合家庭实际持仓时用的同一套类别——所以”当前配置”和”假设参数”永远说的是同一套 14/8 分类语言。

第一层——每个类别的收益与波动率(AssetReturnSet)

Section titled “第一层——每个类别的收益与波动率(AssetReturnSet)”

RightCapital\Core\Models\AssetReturnSet::PREDEFINED_SET_VALUES_BY_TYPE(vendor/rightcapital/core-models/src/Models/AssetReturnSet.php:18-279)硬编码了三套预设,每套是一份 {category_id, dividend, capital_gain, vol} 列表(单位均为 %,capital_gain = 资本增值,dividend = 股息/利息收益,vol = 年化标准差):

category_id类别历史指数收益(Historical Index Returns)
(股息 + 资本增值,波动率)
前瞻预期(J.P. Morgan Forward-Looking)
(股息 + 资本增值,波动率)
1, 2Large Growth, Large Value2 + 9.93,vol 15.762 + 4.7,vol 15.76
3Mid Cap2 + 8.48,vol 17.122 + 5.0,vol 17.12
4Small Cap2 + 8.41,vol 19.692 + 4.9,vol 19.69
5International Equities2 + 7.63,vol 16.552 + 5.8,vol 16.55
6Emerging Markets2 + 8.07,vol 21.632 + 5.8,vol 21.63
7Real Estate2 + 6.92,vol 17.242 + 6.2,vol 17.24
8Government3.82 + 0,vol 7.384.0 + 0,vol 7.38
9Municipal4.22 + 0,vol 4.653.8 + 0,vol 4.65
10Corporate4.06 + 0,vol 4.175.2 + 0,vol 4.17
11High Yield6.49 + 0,vol 8.896.1 + 0,vol 8.89
12International Bonds4.06 + 0,vol 4.174.0 + 0,vol 4.17
13Cash1.87 + 0,vol 0.543.1 + 0,vol 0.54
14Other2 + 9.93,vol 15.762 + 4.7,vol 15.76

两套预设的波动率完全一致,区别只在预期收益:“历史指数收益”反映长期历史平均水平(权益类收益更高),“J.P. Morgan 前瞻预期”反映当下市场环境下的资本市场假设(权益类收益更低、债券收益更高,对应当前利率环境)。同一个文件里还有一套更老的 asset_returns_2022(:19-104),只作为仍在用旧版 scenario file 的家庭的兼容回退。

RightCapital\Core\Enums\AssetReturnSet\AssetReturnSetType(vendor/rightcapital/core-models/src/Enums/AssetReturnSet/AssetReturnSetType.php)有三个取值:historical_index_returnsforward_looking_jp_morgancustomized。一行 AssetReturnSet 记录(asset_return_sets 表)会选定其中一种;App\Models\AssetReturnSet::getValuesAttribute()(app/Models/AssetReturnSet.php:67-73)对前两种直接返回预设表,对第三种则调用 processCustomizedValues()(逐类别的自定义覆盖值,存在 customized_values JSONB 字段里)。

归属层级:asset_return_sets.organization_id / advisor_id / household_id 分别把一套假设绑定到机构、顾问(顾问的全局默认值,AdvisorAssumption::asset_return_set),或单个家庭覆盖(HouseholdAssumption::global_asset_return_set 回退到 household.advisor.advisor_assumption.asset_return_set,app/Models/HouseholdAssumption.php:76-84)。

第二层——跨大类相关性(HasCorrelations)

Section titled “第二层——跨大类相关性(HasCorrelations)”

App\Models\Support\HasCorrelations::DEFAULT_CORRELATIONS(app/Models/Support/HasCorrelations.php:22-163)是一份 {group1, group2, value} 平铺列表——8 个 CategoryGroup 两两组合(28 对),value = 相关系数 × 100。举几个例子:

group1group2相关系数
US_EQUITIESINTERNATIONAL_EQUITIES0.63
US_EQUITIESEMERGING_MARKETS0.665
US_EQUITIESREAL_ESTATE0.829
US_EQUITIESUS_BONDS0.393
US_EQUITIESINTERNATIONAL_BONDS0.192
US_EQUITIESCASH−0.12
INTERNATIONAL_EQUITIESEMERGING_MARKETS0.558

这个 trait 被混入到假设模型里(AdvisorAssumptionOrganizationAssumption)——effective_correlations 按家庭 → 顾问(可选机构级覆盖)的顺序解析,归属层级与 AssetReturnSet 一致。

相关性特意没有做到 14 个细分类别的粒度:同一大类下的兄弟类别(比如同属 US_EQUITIES 的 Large Growth 和 Small Cap)默认视为高度联动,所以每个类别都直接继承其所属大类的两两相关性——8×8 就足以覆盖全部 14 选 2 的类别组合,不需要手工调 91 个数字。

ScenarioGenerator::generateInputContent()(app/Engine/ScenGen/ScenarioGenerator.php:294-360)是两层数据合并、生成 scen_gen 二进制输入文本的地方:

  1. 遍历 14 个类别(按 category_id 排序):把 vol 转成小数,标注它所属大类的 getEngineClassId()({I|Class ID} 行),并算出几何预期收益 (capital_gain + dividend) / 100 + vol² / 2(+ vol²/2 项是把算术平均收益修正为几何平均收益,用于对数正态模拟)。
  2. 遍历两遍 CategoryGroup::cases(),构造 8×8 相关性网格;对角线 = 1,非对角项从 Correlations 列表里查找(找不到就报错——这份 28 对的表必须保持完整,理论上新增大类时也不会有代码自动帮你补全)。
  3. 输出 {N|Expected Returns}{N|Volatilities}{I|Class ID},以及 8 行 {N|Correlations|i},连同文件版本头——这就是 App\Engine\Calc\Support\EngineRunner 传给计算引擎二进制程序的 scenario file(计算引擎输入的另一条并行流水线见 Engine Input Construction;那份文档里的 AssetAllocationReturnAndVolatilityAssumptionsSection 携带的正是家庭”当前配置”在这同一套 14 个类别上的百分比,由 穿透机制 算出)。

ScenarioGenerator 的子类(app/Engine/ScenGen/ 下的 GlobalScenarioGeneratorAdvisorScenarioGeneratorHouseholdScenarioGeneratorOrganizationScenarioGenerator)分别实现抽象方法 getAssetReturnSetValues() / getCorrelationsAssumption()(ScenarioGenerator.php:261,266),用于解析当前该用哪一层级的假设参数。

内容文件:行号
14→8 类别/分组映射(基础类别 ID)vendor/rightcapital/core-models/src/Models/Category.php:21-34
CategoryGroup 枚举(8 大类、引擎 class id、名称)vendor/rightcapital/core-models/src/Enums/Category/CategoryGroup.php
预设收益/波动率表(3 套 × 14 个类别)vendor/rightcapital/core-models/src/Models/AssetReturnSet.php:18-279
AssetReturnSetType 枚举vendor/rightcapital/core-models/src/Enums/AssetReturnSet/AssetReturnSetType.php
AssetReturnSet.values 解析逻辑(预设 vs. 自定义)app/Models/AssetReturnSet.php:67-73
家庭 → 顾问 asset-return-set 回退逻辑app/Models/HouseholdAssumption.php:76-84
默认 8×8 相关性矩阵app/Models/Support/HasCorrelations.php:22-163
场景输入构造(收益 + 相关性 → scen_gen 文本)app/Engine/ScenGen/ScenarioGenerator.php:294-360
各归属层级假设解析的抽象方法app/Engine/ScenGen/ScenarioGenerator.php:261,266
  • retail-api(web-service/api)仓库 —— app/Models/{AssetReturnSet,HouseholdAssumption,Support/HasCorrelations}.phpapp/Engine/ScenGen/ScenarioGenerator.php,读取于 develop 分支,2026-07。
  • vendor/rightcapital/core-models composer 包 —— src/Models/{Category,AssetReturnSet}.phpsrc/Enums/Category/CategoryGroup.phpsrc/Enums/AssetReturnSet/AssetReturnSetType.php
  • 本地 PostgreSQL(rightcapital.categoriesrightcapital.asset_return_sets)—— 验证了 category_idgroup 映射及 asset_return_sets.type 取值。