01
Brinson 模型介绍

1.1 归因方式
1.1.1 BF 超额收益分解方案
在1985年,Brinson 和 Fachler 提出了一个收益分解方案,简称为 “BF 方案”。与 BHB 方案不同,BF 方案没有包含交互收益,而是将其并入了选择收益当中。因此,BF 方案仅有两个部分:
配置收益(Allocation Return, AR):配置收益的定义与 BHB 方案相同,但 BF 方案引入了基准组合的收益率,衡量基金经理在资产配置上的能力。
选择收益(Selection Return, SR):在 BF 方案中,选择收益不仅衡量基金经理在具体标的选择上的能力,还包括了交互效应。因此,选择收益反映了基金经理在标的选择和资产配置共同作用下的综合超额收益。
1.1.2 BHB 超额收益分解方案
1986 年,Brinson、Hood 和 Beebower 提出了另一种基于 Brinson 模型的超额收益拆分方案,简称为 “BHB 方案”。这一方案在业界应用广泛。BHB 方案通过构建两个虚拟组合——资产配置组合和标的选择组合,将基金组合的超额收益分解为三个部分:
配置收益(Allocation Return, AR):配置收益衡量基金经理在不同资产类别或行业之间进行资产配置的能力。它反映了基金经理通过选择不同资产类别或行业的权重来超越基准的能力。
选择收益(Selection Return, SR):选择收益衡量基金经理在具体标的选择上的能力。它反映了基金经理选择的个股或债券在相对于基准组合的超额收益。
交互收益(Interaction Return, IR):交互收益反映了资产配置和标的选择之间的交互效应。它表示由于资产配置和标的选择共同作用而产生的超额收益。
我们可以用图形来更直观地展示 BF 和 BHB 方案的收益分解方式。下图白色部分代表了基准组合的收益,彩色部分代表了基金组合相对于基准的超额收益。

1.2 多期 Brinson 模型


1.3 行业维度的 Brinson 模型
1.4 结果解释
02
函数介绍
2.1 函数语法
brinson(dailyPosition, benchmarkPosition, marketData, dateList, [method = 'BHB'], [multiPeriod = false], [industryBrinson = NULL], [showAll = false], [multiPeriodMethod = 'grap'])
2.2 输入
2.2.1 输入规范
Brinson 模型基于每期数据进行归因分析,因此 dailyPosition、benchmarkPosition 和 marketData 表格中使用的都是每期数据。模型的逻辑如下:
构建日期向量:根据 dateList 参数构建一个包含每期日期的日期向量。例如,想要对 2024 年 1 月 1 号到 2024 年 1 月 5 号做每天的归因,那 dateList = 2024.01.01..2024.01.05。如果想要根据交易日历的有效日期做归因,也可以使用 getMarketCalendar 函数获取日期范围内的有效日期。
日期匹配:用这些日期与 dailyPosition、benchmarkPosition 和 marketData 表中的 date 列进行 asof join,即寻找日期匹配或最近的数据来代表每期数据。
2.2.2 参数
dailyPosition 每期持仓明细。Table,包含每期组合的持仓信息,提供每个标的的基本信息,包括占组合的权重,用于计算组合的各项收益指标。此表必须包含的列如下:

benchmarkPosition 每期基准明细。Table,包含每期基准组合的信息,提供基准组合内所包含的基准名称和权重,用于计算基准组合的各项收益指标。此表必须包含的列如下:

marketData 每期行情数据。Table,包含所有组合和基准内包含的标的数据。需要包含每期日期每个标的所对应的行情数据。每一条数据需要包含以下信息:

dateList 归因日期。date[],表示需要归因的日期向量。 method 选择用哪种方式计算归因。string,可取值为 ‘BHB’, ‘BF’,代表两种不同的 Brinson 归因方式。默认值为 ‘BHB’。 multiPeriod 是否需要多期归因。Boolean,决定是否需要进行多期 Brison 模型归因(使用GRAP 算法)。默认值为 false。 industryBrinson 是否需要在大类资产中进行行业归因。NULL 或者 string[],代表是否要对某个或某些大类资产进行行业维度的 Brinson 归因,例如 industryBrinson = ['股票']。默认值为 NULL。 showAll 是否要展示每期的归因结果。Boolean,如果为 true,会展示每期归因的结果。如果选择行业维度的归因,则会分别展示每期的大类资产归因结果和每期的行业维度归因结果。默认值为 false。 multiPeriodMethod 多期计算的方法。为 ‘grap’ 或者 ‘sum’,分别代表用 grap 算法计算修正收益,或者直接将收益相加。默认值为 ‘grap’。
2.3 输出
返回一个字典,一定会包含区间收益、基础信息和大类资产归因三个字典。如果 industryBrinson 不为空,则包含基础信息、大类资产归因、行业归因产生的多个字典。
参数设定不同会导致返回结果的结构有稍许的不同,以下是几种常用的归因方式以及相对应的参数设定:
1. 使用 BHB 方法计算单期 Brinson 归因:brinson(dailyPosition, benchmarkPosition, marketData, 2024.01.31, method = 'BHB', multiPeriod = false, industryBrinson = NULL, showAll = false) 。返回结果如下图所示:


03
使用方法
本文会基于已有持仓数据、行情数据、基准数据进行归因计算。若要使用 brinson 模块,请将 dolphinBrinson.dos 放在 [home]/modules 目录下。[home] 目录由系统配置参数 home 决定,可以通过 getHomeDir 函数查看。以下示例中展示的都是模拟数据。具体流程如下:
3.1 数据预处理
1. 持仓表:对于持仓表,需要整理成包含日期、标的、每日持仓权重的表格。因为 Brinson 支持多期归因,表格中需要包含多期持仓的具体组合和权重。

2. 每期基准表:对于基准表,与持仓表相同,需要每期的基准组合。

3. 行情数据表:行情数据表中需要包含所有基准中的成分及其收益率和权重。除此之外,也需要包含所有持仓中标的的行情数据表。例如下表中,包含了持仓及基准持仓中所有标的的行情数据。

3.2 参数设置
对于单期 Brinson 归因,代表对 dateList 所包含的日期区间持仓进行归因。因为 Brinson 支持多期计算,也就是将期限内的持仓变动考虑在归因过程中,所以可以通过设置参数中的 dateList 来设置变动周期。例如,如果每天变动一次具体的持仓,可以将 rule 设置为 ‘D’。如若 dateList = 2024.02.01..2024.03.01,模型则会计算从 2024.02.01 至 2024.03.01 根据每天持仓产生的归因结果。
3.3 模型调用
use dolphinBrinsondateList = 2024.01.31brinson(dailyPosition, benchmarkPosition, marketData, dateList, method = 'BF', multiPeriod = true,industryBrinson = NULL, showAll = true)
2. 使用 BHB 方法和 grap 修正计算多期 Brinson 归因,并对股票大类资产下进行行业归因,并且展示所有结果
use dolphinBrinsondateList = 2024.01.31 2024.02.29 2024.03.31brinson(dailyPosition, benchmarkPosition, marketData, dateList, method = 'BHB', multiPeriod = true,industryBrinson = `股票, showAll = true, multiPeriodMethod = 'grap')
04
函数计算性能
本章节将展示 DolphinDB 实现的 dolphinBrinson 模块的计算性能。通过对函数在不同持仓规模、时间频率以及多期和单期归因设置下的性能测试,能够帮助用户更好地理解函数的计算复杂度以及在实际应用中的表现。
4.1 测试方法
持仓数据 (dailyPosition):模拟了 5 年期间每日包含 10, 100, 1000 只标的的持仓信息,包含股票、债券、现金。
基准持仓数据 (benchmarkPosition):模拟了 10 年期间每日的基准持仓信息。
行情数据 (marketData):模拟了 10 年期间 10000 只股票,股票、债券、现金资产的行情数据。
归因分析配置:
设置 method 为默认值 BHB。
通过改变 dateList 参数来调整运行频率,分别设置为每季度、每月和每日。
通过改变 multiPeriod 来设置是否进行多期归因
通过设置 industryBrinson = ['股票'] 对股票资产进行归因
设置 showAll 为 false,不展示所有结果
4.2 测试结果

从上述结果来看,
时间频率对运行时间的影响:随着时间频率的增加,运行时间增加。这是因为频率越高,数据量越大,计算复杂度也随之增加。虽然是多期,但 GARP 算法只是根据每期的收益率进行一次累积,10 年每月就是多了 120 次乘积计算,因此对计算量来说并没有太大的区别;但如果是每天归因,则增加了 3650 次乘积计算,因此时间会比季度或者月度频率要明显增多。
持仓的影响:如果是每季度或者每月对不同持仓的组合进行一次多期分析,时间相差不大;如果每天进行归因分析,持仓多的组合的运行时间比持仓少的组合分析稍长。
05
总结
06
参考文献
Brinson, Gary P., and Nimrod Fachler. 1985. “Measuring Non-US Equity Portfolio Performance.” Journal of Portfolio Management 11 (3): 73–76.
Brinson, Gary P., L. Randolph Hood, Jr., and Gilbert L. Beebower. 1986.“Determinants of Portfolio Performance.” Financial Analysts Journal 42 (4):39–44. 林晓明,黄晓彬,张泽。Brinson绩效归因模型原理与实践[R].中国:华泰证券,2021.
点击阅读原文,获取完整脚本




