摘要及声明
1:本文主要介绍Treynor-Mauzy(TM)模型,将TM模型所衡量的择时能力延伸到业绩非线性特征上;
2:本文主要为理念的讲解,模型也是笔者自建,文中假设与观点是基于笔者对模型及数据的一孔之见,若有不同见解欢迎随时留言交流;
3:笔者原则是只做干货的分享,后续将更新更多内容,但工作学习之余的闲暇时间有限,更新速度慢还请谅解;
4:模型实现基于python3.8;
目录
1. 从捕获比到TM模型
1.1 二次项的意义
1.2 收益归因的局限性
2. 择时能力与二次项
2.1 价投不择时的传言
2.2 模型失效分析
3. 总结
4. 代码实现
5. 引用
6. 往期精选
1. 从捕获比到TM模型
笔者在之前一篇文章曾经介绍过捕获比,捕获比是一种用来衡量组合在市场上行和下行时期收益获取能力的指标(业绩的非线性特征——捕获指标的改进及国内基金行业的证据)。比起本周要介绍的TM模型,捕获比有很明显的优势,简单直观,计算量小,且具有很强的可解释性。图一展示了三个组合收益R(B)和市场收益R(m)的散点分布,以及上行及下行条件下的线性拟合结果。组合A的捕获比大于1的,具备涨多跌少的特性;组合B捕获比等于1的,无论上行还是下行市场中均呈现相似的斜率;而组合C的捕获比是小于1的。由此我们可以得出一个结论:组合A大概率是股神的,组合B大概率是跟踪指数产品,而组合C大概率是散户的操作结果。
图一:三种不同表现组合的收益分布及拟合结果
但是捕获比的缺陷也很明显,捕获比简单的将市场分为上涨和下跌两种情况,导致其函数虽然是非线性的,但却是个分段函数。其次,组合表现与市场反向涨跌时捕获比是完全失效的,为此笔者上期还对捕获比的函数进行了映射以弥补这一缺陷。
本期所要介绍的TM模型却通过回归拟合的手段一举解决上述两大缺陷,可以说是两种不同的思路,但他们都是为了描述业绩的非线性特征。关于TM的介绍网上已经有很多了,笔者并不打算重复无意义的篇幅,直接上公式:
其中,:组合回报,:市场回报,:无风险收益
其实就是个CAPM模型加上个市场溢价的二次项然后回归,这个二次项主要用于表达业绩的非线性特征,而目前能看到所有文献都将之称为“择时能力”。
1.1 二次项的意义
在解释择时能力之前需要深入剖析这个二次项,在数学上这个二次项无非表达的就是一个抛物线,非常简单:
其中,a控制着抛物线的开口,如图二:
图二:公式[2]的抛物线函数
这个抛物线乍一看和组合业绩毫无联系,但其实组合收益率某些特征可以被抛物线函数右侧的部分曲线拟合进而表达出组合涨跌和市场涨跌之间的二阶非线性关系。即涨多跌少,如a=0.5:y随x增大边际递增(业绩涨多),y随x减小边际递减(业绩跌少)。
为什么是右侧那部分?看看图一中红色散点就知道了,图一中红色散点就可以通过抛物线拟合出来。但它只是抛物线偏右侧的部分图像,要现实图二整条橙色抛物线那样的收益散点分布是极难做到的(市场涨组合涨,市场跌组合涨,市场暴跌组合还暴涨)。
再结合之前捕获比那期的内容来看,其实捕获比和TM模型的二次项都是用来衡量业绩的非线性特征,只是捕获比用了取平均求期望值的方式,而TM模型则是通过回归的方式拟合得到。因此,只要满足回归条件,TM模型不存在取值问题导致模型失效的情况。
1.2 收益归因的局限性
业绩归因从方式上可以分为:基于收益的归因(RBSA,Return based style analysis)、基于持仓的归因(HBSA,Holding based style analysis)。前者是自上而下的通过等方式,已知收益倒推持仓;后者是已知持仓情况,直接通过持仓情况进行业绩分析。当然还有一种归因方式是管理人的自我披露,这里就不展开讲了。
基于持仓的归因方式是最准确的,但绝大多数情况下都很难直接拿到实时的持仓变化,即使是公募基金也只有在季报披露时能更新持仓,更不用说透明度较低的私募了。因此退而求其次,实务中广泛使用的还是基于收益的归因,由于组合收益披露是较高频的数据,于是就可以通过回归等数学工具,例如多因子模型对组合的业绩进行归因分析。然而统计上的相关不代表完全具备实质的经济意义,一些无意义的因子依然有可能被模型识别为显著而被保留在模型中。尤其是对头寸方向和底层资产构成较为复杂的另类策略私募基金而言,有可能基金组合的敞口虽然统计上和沪深300有较大相关性,但这一敞口可能是用各种衍生品合成出来,并不代表组合真正持有了沪深300指数。除了收益特征统计上看着像沪深300的收益,实际上组合还可能暴露于潜在的数个未知风险敞口上。
尽管这种方式在精确性上有所妥协,但对于急需了解管理人业绩黑盒的投资者而言,这无异于在沙漠中寻得一瓶矿泉水。虽然这一瓶水或许无法与绿洲的泉水相提并论,但总比一滴水都没有来的好。
2. 择时能力与二次项
所谓择时能力用大白话来说就是对市场牛熊的判断能力,比如在14年市场底部重仓,15年市场高位走人,那么就可以说有管理人在这轮牛熊中很强的择时收益。择时能力高的组合特点往往是:涨的时候比市场涨得多,跌的时候比市场跌得少;或是涨的时候和市场差不多,跌的时候比市场跌得少,等等方式。其实有很多种情况都可以,说得专业一点:择时能力高的捕获比会显著大于1;择时能力高的TM模型二次项系数会显著大于1。
但是这一关系如果反过来则是不一定成立的,正如第三节提到的收益归因的局限性,它们之间虽然存在因果关系,但却是多因一果(Multiple Causes for a Single Effect),而管理人具备择时能力只是二次项系数会显著大于1的其中一个结果变量(Outcome variables)。如图三所示,其它可能的变量除了前文提到的衍生品合成头寸,风控止损措施也可能导致本来管理人没有择时能力,只是被动止损后造成比基准跌得少的效果。另外,需要注意的是,择时能力也只是个泛泛而谈,择时能力只能被看作是一个中介变量(Mediator Variable),而不是最底层的因果关系。有很多情况,比如个股交易时机的选择、行业的轮动、大类资产的轮动和仓位的管理,甚至不错的运气都有可能导致管理人的具备涨多跌少的特点(运气≠能力,因此笔者并不打算将运气放在择时能力中),辨别是真择时能力还是猴子抛硬币的随机也是需要进一步验证的。
图三:对组合涨多跌少因果关系的梳理
综上就可以得到本文的核心结论:择时能力只是TM模型所衡量的其中一个方面,TM模型二次项所表达的真正含义是组合业绩的非线性特征。反过来说,导致这种非线性特征的因素可以有很多,择时能力只是其中一个可能。
2.1 价投不择时的传言
比较著名的价值投资者,貌似一般都是反对择时,或者否认自己择时的。举例来说,巴菲特的老师格雷厄姆,在《聪明的投资者》中写道: “我从来不择时”。巴菲特本人的投资也几乎都是以十年甚至更长时间为跨度,并且鼓励普通投资者长期配置被动的指数型基金。笔者使用TM模型对巴菲特业绩进行了拆解,所使用的巴菲特业绩来源于Berkshire年报中巴菲特所披露的自1965年至2023年年度业绩(Berkshire Hathway, 2024),比较基准是S&P500指数。无风险收益数据来自Wind,选取了十年期美国国债,通过取年度均值得到。
得到拟合图像及模型参数如图四所示,可以看到的模型参数均是显著的。首先我们假设TM二次项完全代表择时收益,从回归系数来看,巴菲特业绩具备很高的Alpha收益,但择时方面TM模型二次项系数为-3.14,图像呈现负凸的特点:
图四:Berkshire业绩TM模型拟合结果及ANOVA分析
换句话说,从上述模型结果来看巴菲特并没有择时收益,甚至择时上是负收益。这似乎与价值投资者“我从来不择时”以及巴菲特长期持有的理念呼应上了。但仔细想想TM模型二次项系数为-3.14,这意味着其它参数不变的情况下,市场风险溢价上升1%,巴菲特择时带来的业绩贡献下滑-3.14%;市场风险溢价下降1%,巴菲特择时带来的业绩贡献还是下滑-3.14%。这实际上与我们所认知的巴菲特业绩特征是相矛盾的。
图五:Berkshire业绩净值走势
笔者开始怀疑这一现象是模型局限性导致的,巴菲特很强,导致他的Alpha收益很高。Alpha收益很高也就是截距项数值较大,从而抬升了整个散点在Y轴方向上的分布,最小二乘法不得不将拟合曲线的两端向下弯曲以保证拟合更多的散点,进而形成的负凸度。
为了消除截距项的影响,在原有模型的基础上对数据分布进行去中心化,再次进行拟合得到图六结果:
图六:Berkshire业绩TM模型拟合结果及ANOVA分析
经过去中心化后再进行拟合图像就显示出凸性,但TM模型二次项系数在统计上看并不显著,参考价值并不大。
2.2 模型失效分析
仔细看回归分析结果里,协方差显示不稳健,进一步分析下去,看模型是否满足回归条件。简单拉出残差分布图看一下,肉眼都能看出异方差性,残差的方差随市场溢价的增大也不断上升,因此不满足回归条件:
图七:TM模型拟合后的残差分布图
笔者认为业绩披露的频率过低也是造成模型失效的原因之一,即使Berkshire完整的业绩年度已经有59年,但以年为单位的数据点依然非常少,并且从年度收益率的分布图上看,无论是巴菲特还是S&P 500都是有偏的。有偏的分布加上很少的数据点,导致模型拟合效果很差。最后,异方差性也一定程度上是数据分布有偏和数据量较少导致的,从Berkshire业绩TM模型拟合的散点图(图四和图六)来看,散点分布呈现从左向右的喇叭口扩散状态,这直接导致残差的分布也是扩散状态的。
图八:Berkshire和S&P 500年度业绩分布图
综上所述,TM模型无法很好的解释巴菲特的业绩,使用捕获比或许更能简单和直观的衡量巴菲特业绩的非线性特征。
至于加投不择时的传言,仁者见仁智者见智,不是本期重点,笔者不打算展开分析了。
3. 总结
本文在TM模型对择时能力衡量的基础上进一步拓展,认为TM模型中的二次项更多反映了组合业绩的非线性特质,并且明确指出其二次项系数所体现的多因一果的关键特性,这为理解组合业绩提供了更为丰富和全面的视角。本文构建了一个TM模型对Berkshire的业绩进行了分析,由于违反回归假设,TM模型无法很好的应用于这一组合业绩案例,但通过模型的失效分析,进一步理解了TM模型的局限性。
4. 代码实现
本期的代码也是相对简单的可视化操作,笔者编写了一个函数,只要将符合要求的业绩表格放入模块,即可自动计算和展示出本文的拟合图。
首先导入需要的库:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import statsmodels.formula.api as smfplt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
本文所使用的巴菲特业绩来源于Berkshire年报中巴菲特所披露的业绩,比较基准是S&P 500指数。有需要数据的可以私信笔者,下面直接读取并导入业绩数据:
fund = pd.read_excel("C:/Users/nynka/Desktop/工作文件/巴菲特业绩分析.xlsx", sheet_name = "巴菲特年度业绩")
fund["年度"] = fund["年度"].astype("str")
fund.set_index("年度", inplace=True)fund年度 国债收益 Berkshire SP500 超额
1965 0.042837 0.495 0.100 0.395
1966 0.049250 -0.034 -0.117 0.083
1967 0.050727 0.133 0.309 -0.176
1968 0.056444 0.778 0.110 0.668
1969 0.066727 0.194 -0.084 0.278
... ... ... ... ...
2019 0.021414 0.110 0.315 -0.205
2020 0.008892 0.024 0.184 -0.160
2021 0.014469 0.296 0.287 0.009
2022 0.029506 0.040 -0.181 0.221
2023 0.039590 0.158 0.263 -0.105
接下来编写函数,需要注意的是,放进函数里的数据表需要固定格式,第一列无风险收益,第二列组合业绩,第三列为比较基准:
def visual_mod(fund):rf_name = fund.columns[0] ## 获取列名,无风险收益fund_name = fund.columns[1] ## 获取列名,基金名称index_name = fund.columns[2] ## 获取列名,基准fund_pct_chg = fund[fund_name]# ————————数据计算————————## 无风险利率:十年期国债年度均值rf = fund[[rf_name]]## 市场数据market_pct_chg = fund[[index_name]]## 市场溢价MRP = pd.concat([market_pct_chg[index_name], rf[rf_name]], axis = 1, join="inner")MRP = MRP[index_name] - MRP[rf_name]## 基金溢价ERP = pd.concat([fund_pct_chg, rf[rf_name]], axis = 1, join="inner")ERP.columns = ["fund_pct", "rf_pct"]ERP = ERP["fund_pct"] - ERP["rf_pct"]## 整合数据data = pd.concat([ERP, MRP], axis = 1, join = "inner")data.columns = ["erp", "mrp"]data["mrp_sqr"] = data["mrp"] ** 2 ## TM模型二次项# ————————回归建模————————model = smf.gls(data = data, formula = "erp~mrp+mrp_sqr")result = model.fit()# ————————图像输出————————params = result.paramsplt.figure(figsize = (8,5))ax = plt.subplot(1, 1, 1) # plt没有直接居中显示坐标轴的方法,这里用实例化一个subplot后面再用.spines()设置居中ax.plot(data["mrp"].sort_values(ascending=True).values, result.fittedvalues.sort_values(ascending=True).values, color = "orange", label = "拟合结果")ax.plot(data["mrp"].sort_values(ascending=True).values, data["mrp"].sort_values(ascending=True).values, color = "gray", label = "β=1", linewidth = 1, linestyle = "--")ax.scatter(data["mrp"].values, data["erp"].values, color = "orange", marker = "+", s = 8, label = "基金-市场回报分布")## 设置坐标轴居中显示ax.spines['top'].set_visible(False)ax.spines['right'].set_visible(False)ax.spines['bottom'].set_position(('data',0))ax.xaxis.set_ticks_position('bottom')ax.spines['bottom'].set_position(('data', 0))ax.yaxis.set_ticks_position('left')ax.spines['left'].set_position(('data', 0))plt.title("T-M 回归结果")## 设置轴标签居中显示xlim = ax.get_xlim() ## 轴标签没有直接居中显示的方法通过.text设置坐标显示ylim = ax.get_ylim() plt.text(xlim[1] + 0.05 * (xlim[1] - xlim[0]), ylim[0] + 0.35 * (ylim[1] - ylim[0]), index_name, ha='left', va='center', rotation='vertical', fontsize='large') ax.text(0, ylim[0] - 0.02 * (ylim[1] - ylim[0]), fund_name, ha='center', va='center', rotation='horizontal', fontsize='large') plt.legend()plt.show()# ————————回归结果输出————————print("————————ANOVA ANALYSIS————————")print(result.summary())visual_mod(fund)
当然,生成分布图后可以得到前文的图七:
import seaborn as sns
sns.distplot(fund["SP500"], label="S&P 500")
sns.distplot(fund["Berkshire"], label="Berkshire")
plt.legend()
plt.xlabel("收益率")
plt.show()
5. 引用
Berkshire Hathway. 2024. "2023 annual report". https://berkshirehathaway.com/2023ar/2023ar.pdf
6. 往期精选
往期精选 | ||
系列 | 文章传送门 | 实现方式 |
金融杂谈 | 多目标最优化的资产配置 | Python |
基于均值方差最优化资产配置的模型特性 | Python | |
业绩的非线性特征——捕获指标的改进及国内基金行业的证据 | Python | |
基金市场的冷热传递什么信号? | Python | |
券商金股哪家强——信息比率 | Python | |
从指数构建原理看待A股的三千点魔咒 | Python | |
决策树学习基金持仓并识别公司风格类型 | R | |
垃圾公司对回报率计算的影响几何 | Python | |
市场预测美联储加息的有效性几何 | Python | |
市场风险分析 | Python |