资产收益与相关性假设体系(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 表(id、name、group 列)验证:
category_id | 类别名称 | CategoryGroup(8 大类) | getEngineClassId() |
|---|---|---|---|
| 1–4 | Large Growth, Large Value, Mid Cap, Small Cap | US_EQUITIES | 1 |
| 5 | International Equities | INTERNATIONAL_EQUITIES | 2 |
| 6 | Emerging Markets | EMERGING_MARKETS | 3 |
| 7 | Real Estate | REAL_ESTATE | 4 |
| 8–11 | Government, Municipal, Corporate, High Yield | US_BONDS | 5 |
| 12 | International Bonds | INTERNATIONAL_BONDS | 6 |
| 13 | Cash | CASH | 7 |
| 14 | Other | OTHER | 8 |
category_id 1–14 是内置的”基础类别”(RightCapital\Core\Models\Category::ID_LARGE_GROWTH … ID_OTHER,定义在 vendor/rightcapital/core-models/src/Models/Category.php:21-34);机构/顾问自定义的类别从 ID_CUSTOM_MIN = 101 开始,同样也带一个 group。CategoryGroup 本身定义在 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, 2 | Large Growth, Large Value | 2 + 9.93,vol 15.76 | 2 + 4.7,vol 15.76 |
| 3 | Mid Cap | 2 + 8.48,vol 17.12 | 2 + 5.0,vol 17.12 |
| 4 | Small Cap | 2 + 8.41,vol 19.69 | 2 + 4.9,vol 19.69 |
| 5 | International Equities | 2 + 7.63,vol 16.55 | 2 + 5.8,vol 16.55 |
| 6 | Emerging Markets | 2 + 8.07,vol 21.63 | 2 + 5.8,vol 21.63 |
| 7 | Real Estate | 2 + 6.92,vol 17.24 | 2 + 6.2,vol 17.24 |
| 8 | Government | 3.82 + 0,vol 7.38 | 4.0 + 0,vol 7.38 |
| 9 | Municipal | 4.22 + 0,vol 4.65 | 3.8 + 0,vol 4.65 |
| 10 | Corporate | 4.06 + 0,vol 4.17 | 5.2 + 0,vol 4.17 |
| 11 | High Yield | 6.49 + 0,vol 8.89 | 6.1 + 0,vol 8.89 |
| 12 | International Bonds | 4.06 + 0,vol 4.17 | 4.0 + 0,vol 4.17 |
| 13 | Cash | 1.87 + 0,vol 0.54 | 3.1 + 0,vol 0.54 |
| 14 | Other | 2 + 9.93,vol 15.76 | 2 + 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_returns、forward_looking_jp_morgan、customized。一行 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。举几个例子:
| group1 | group2 | 相关系数 |
|---|---|---|
| US_EQUITIES | INTERNATIONAL_EQUITIES | 0.63 |
| US_EQUITIES | EMERGING_MARKETS | 0.665 |
| US_EQUITIES | REAL_ESTATE | 0.829 |
| US_EQUITIES | US_BONDS | 0.393 |
| US_EQUITIES | INTERNATIONAL_BONDS | 0.192 |
| US_EQUITIES | CASH | −0.12 |
| INTERNATIONAL_EQUITIES | EMERGING_MARKETS | 0.558 |
这个 trait 被混入到假设模型里(AdvisorAssumption、OrganizationAssumption)——effective_correlations 按家庭 → 顾问(可选机构级覆盖)的顺序解析,归属层级与 AssetReturnSet 一致。
相关性特意没有做到 14 个细分类别的粒度:同一大类下的兄弟类别(比如同属 US_EQUITIES 的 Large Growth 和 Small Cap)默认视为高度联动,所以每个类别都直接继承其所属大类的两两相关性——8×8 就足以覆盖全部 14 选 2 的类别组合,不需要手工调 91 个数字。
喂给场景生成器
Section titled “喂给场景生成器”ScenarioGenerator::generateInputContent()(app/Engine/ScenGen/ScenarioGenerator.php:294-360)是两层数据合并、生成 scen_gen 二进制输入文本的地方:
- 遍历 14 个类别(按
category_id排序):把vol转成小数,标注它所属大类的getEngineClassId()({I|Class ID}行),并算出几何预期收益(capital_gain + dividend) / 100 + vol² / 2(+ vol²/2项是把算术平均收益修正为几何平均收益,用于对数正态模拟)。 - 遍历两遍
CategoryGroup::cases(),构造 8×8 相关性网格;对角线 =1,非对角项从Correlations列表里查找(找不到就报错——这份 28 对的表必须保持完整,理论上新增大类时也不会有代码自动帮你补全)。 - 输出
{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/ 下的 GlobalScenarioGenerator、AdvisorScenarioGenerator、HouseholdScenarioGenerator、OrganizationScenarioGenerator)分别实现抽象方法 getAssetReturnSetValues() / getCorrelationsAssumption()(ScenarioGenerator.php:261,266),用于解析当前该用哪一层级的假设参数。
关键文件索引
Section titled “关键文件索引”| 内容 | 文件:行号 |
|---|---|
| 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 |
- 投资分析数据模型 —— 家庭实际持仓如何通过基金穿透映射到这同一套 14 个类别
- Engine Input Construction —— 这份 scenario file 所服务的计算引擎输入流水线
- Morningstar 证券主数据 —— 穿透逻辑读取的
securities/funds/allocations_by_*数据来源
- retail-api(
web-service/api)仓库 ——app/Models/{AssetReturnSet,HouseholdAssumption,Support/HasCorrelations}.php、app/Engine/ScenGen/ScenarioGenerator.php,读取于develop分支,2026-07。 vendor/rightcapital/core-modelscomposer 包 ——src/Models/{Category,AssetReturnSet}.php、src/Enums/Category/CategoryGroup.php、src/Enums/AssetReturnSet/AssetReturnSetType.php。- 本地 PostgreSQL(
rightcapital.categories、rightcapital.asset_return_sets)—— 验证了category_id→group映射及asset_return_sets.type取值。