<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Beta on 格物堂</title><link>https://gewutang.cn/tags/beta/</link><description>Recent content in Beta on 格物堂</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Sat, 23 Aug 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://gewutang.cn/tags/beta/index.xml" rel="self" type="application/rss+xml"/><item><title>使用卡尔曼滤波计算个股的动态贝塔</title><link>https://gewutang.cn/2025/08/23/kalman-beta/</link><pubDate>Sat, 23 Aug 2025 00:00:00 +0000</pubDate><guid>https://gewutang.cn/2025/08/23/kalman-beta/</guid><description>&#10;&#10;&#10;&lt;div id="引言" class="section level1"&gt;&#10;&lt;h1&gt;引言&lt;/h1&gt;&#10;&lt;p&gt;在金融领域，贝塔（β）系数是资本资产定价模型（CAPM）中的核心参数，用于衡量单个资产或证券组合相对于整个市场（通常以市场指数代表）的系统性风险或波动性。具体而言，贝塔反映了市场收益率变动一个单位时，个体资产收益率的预期变动幅度。准确估计贝塔对于投资组合管理、风险控制、资产定价以及绩效评估都具有重要意义。例如，投资者可通过贝值判断资产的风险属性，进行合理的资产配置；基金经理也可依据贝塔调整投资组合的市场暴露程度。&lt;/p&gt;&#10;&lt;p&gt;传统的贝塔估计方法主要依赖于最小二乘（OLS）回归。通过在给定时间窗口（如1年、3年或5年）内对资产收益率与市场收益率进行线性回归，所得斜率系数即为贝塔估计值。此外，为降低短期波动带来的误差，也常采用滚动窗口回归或调整贝塔（Adjusted Beta）等方法。&lt;/p&gt;&#10;&lt;p&gt;然而，这些传统方法存在明显不足。首先，它们隐含假设贝塔在估计期间内是固定不变的，但事实上，受公司资本结构、经营策略、行业竞争及宏观经济环境等因素影响，资产的系统性风险可能随时间变化，即贝塔具有时变性。其次，滚动窗口回归中窗口长度的选择缺乏统一标准，较短窗口对噪声敏感，较长窗口则可能无法及时捕捉最新变化。再者，这些方法无法提供实时更新的贝塔估计，难以满足动态风险管理的需求。&lt;/p&gt;&#10;&lt;p&gt;为克服上述不足，本研究引入卡尔曼滤波（Kalman Filter）方法进行时变贝塔的估计。卡尔曼滤波是一种递归状态估计算法，能够从带有噪声的观测数据中最优地估计动态系统的内部状态。其核心优势在于能够实时更新状态估计，并通过建模状态变量的动态演化过程（如随机游走）来捕捉参数的时变特性。将卡尔曼滤波应用于贝塔估计，不仅可以得到随时间平滑变化的贝塔序列，还能通过状态空间模型灵活描述贝塔的动态行为，从而提供更准确、适应性的风险度量。&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div id="卡尔曼滤波原理及其在计算贝塔中的应用" class="section level1"&gt;&#10;&lt;h1&gt;卡尔曼滤波原理及其在计算贝塔中的应用&lt;/h1&gt;&#10;&lt;p&gt;卡尔曼滤波是一种最优递归数据处理算法，用于从一系列存在噪声的观测数据中估计动态系统的内部状态。其基本思想是通过结合系统模型的预测（先验估计）和当前观测值的更新，递归地得到状态的最优估计（后验估计）。该算法主要包含两个步骤：预测（时间更新）和更新（测量更新）。&lt;/p&gt;&#10;&lt;div id="基本原理" class="section level2"&gt;&#10;&lt;h2&gt;基本原理&lt;/h2&gt;&#10;&lt;ol style="list-style-type: decimal"&gt;&#10;&lt;li&gt;&lt;strong&gt;状态空间模型&lt;/strong&gt;&lt;br /&gt;&#10;卡尔曼滤波建立在状态空间模型之上，包括状态方程和观测方程：&#10;&lt;ul&gt;&#10;&lt;li&gt;状态方程（系统模型）：描述状态向量如何随时间演化&lt;br /&gt;&#10;&lt;span class="math display"&gt;\[x_t = F_t x_{t-1} + B_t u_t + w_t\]&lt;/span&gt;&lt;br /&gt;&#10;其中，&lt;span class="math inline"&gt;\(x_t\)&lt;/span&gt;为&lt;span class="math inline"&gt;\(t\)&lt;/span&gt;时刻的状态向量，&lt;span class="math inline"&gt;\(F_t\)&lt;/span&gt;为状态转移矩阵，&lt;span class="math inline"&gt;\(u_t\)&lt;/span&gt;为控制输入向量（可选），&lt;span class="math inline"&gt;\(B_t\)&lt;/span&gt;为控制输入矩阵，&lt;span class="math inline"&gt;\(w_t \sim N(0, Q_t)\)&lt;/span&gt;为过程噪声。&lt;br /&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;观测方程（测量模型）：描述观测值与状态向量的关系&lt;br /&gt;&#10;&lt;span class="math display"&gt;\[z_t = H_t x_t + v_t\]&lt;/span&gt;&lt;br /&gt;&#10;其中，&lt;span class="math inline"&gt;\(z_t\)&lt;/span&gt;为&lt;span class="math inline"&gt;\(t\)&lt;/span&gt;时刻的观测向量，&lt;span class="math inline"&gt;\(H_t\)&lt;/span&gt;为观测矩阵，&lt;span class="math inline"&gt;\(v_t \sim N(0, R_t)\)&lt;/span&gt;为观测噪声。&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;算法步骤&lt;/strong&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;预测步骤&lt;/strong&gt;：&lt;br /&gt;&#10;先验状态估计：&lt;br /&gt;&#10;&lt;span class="math display"&gt;\[\hat{x}_t^{-} = F_t \hat{x}_{t-1} + B_t u_t\]&lt;/span&gt;&lt;br /&gt;&#10;先验误差协方差：&lt;br /&gt;&#10;&lt;span class="math display"&gt;\[P_t^{-} = F_t P_{t-1} F_t^T + Q_t\]&lt;/span&gt;&lt;br /&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;更新步骤&lt;/strong&gt;：&lt;br /&gt;&#10;卡尔曼增益：&lt;br /&gt;&#10;&lt;span class="math display"&gt;\[K_t = P_t^{-} H_t^T (H_t P_t^{-} H_t^T + R_t)^{-1}\]&lt;/span&gt;&lt;br /&gt;&#10;后验状态估计：&lt;br /&gt;&#10;&lt;span class="math display"&gt;\[\hat{x}_t = \hat{x}_t^{-} + K_t (z_t - H_t \hat{x}_t^{-})\]&lt;/span&gt;&lt;br /&gt;&#10;后验误差协方差：&lt;br /&gt;&#10;&lt;span class="math display"&gt;\[P_t = (I - K_t H_t) P_t^{-}\]&lt;/span&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;/div&gt;&#10;&lt;div id="在计算贝塔时的应用" class="section level2"&gt;&#10;&lt;h2&gt;在计算贝塔时的应用&lt;/h2&gt;&#10;&lt;p&gt;在时变贝塔估计中，我们将CAPM模型置于状态空间框架下。假设在时刻&lt;span class="math inline"&gt;\(t\)&lt;/span&gt;，资产超额收益&lt;span class="math inline"&gt;\(r_{a,t}\)&lt;/span&gt;与市场超额收益&lt;span class="math inline"&gt;\(r_{m,t}\)&lt;/span&gt;满足：&lt;br /&gt;&#10;&lt;span class="math display"&gt;\[r_{a,t} = \alpha_t + \beta_t r_{m,t} + \epsilon_t\]&lt;/span&gt;&lt;br /&gt;&#10;其中，&lt;span class="math inline"&gt;\(\alpha_t\)&lt;/span&gt;和&lt;span class="math inline"&gt;\(\beta_t\)&lt;/span&gt;为时变参数，&lt;span class="math inline"&gt;\(\epsilon_t\)&lt;/span&gt;为观测噪声。&lt;/p&gt;&#10;&lt;p&gt;定义状态向量为&lt;span class="math inline"&gt;\(x_t = [\alpha_t, \beta_t]^T\)&lt;/span&gt;，则状态空间模型可表示为：&lt;br /&gt;&#10;- 状态方程（假设参数遵循随机游走）：&lt;br /&gt;&#10;&lt;span class="math display"&gt;\[x_t = x_{t-1} + w_t\]&lt;/span&gt;&lt;br /&gt;&#10;其中，&lt;span class="math inline"&gt;\(w_t\)&lt;/span&gt;为过程噪声，协方差矩阵为&lt;span class="math inline"&gt;\(Q\)&lt;/span&gt;。&lt;br /&gt;&#10;- 观测方程：&lt;br /&gt;&#10;&lt;span class="math display"&gt;\[z_t = H_t x_t + v_t\]&lt;/span&gt;&lt;br /&gt;&#10;其中，&lt;span class="math inline"&gt;\(z_t = r_{a,t}\)&lt;/span&gt;，&lt;span class="math inline"&gt;\(H_t = [1, r_{m,t}]\)&lt;/span&gt;，&lt;span class="math inline"&gt;\(v_t = \epsilon_t\)&lt;/span&gt;为观测噪声，方差为&lt;span class="math inline"&gt;\(R\)&lt;/span&gt;。&lt;/p&gt;&#10;&lt;p&gt;通过卡尔曼滤波递归处理数据，可得到状态向量（即&lt;span class="math inline"&gt;\(\alpha_t\)&lt;/span&gt;和&lt;span class="math inline"&gt;\(\beta_t\)&lt;/span&gt;）的最优估计。滤波结果（Filtered）基于当前及过去信息，适用于实时估计；平滑结果（Smoothed）利用全部样本信息，适用于事后分析。&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div id="r代码实例" class="section level1"&gt;&#10;&lt;h1&gt;R代码实例&lt;/h1&gt;&#10;&lt;pre class="r"&gt;&lt;code&gt;# 安装必要的包（如果尚未安装）&#10;if (!require(&amp;quot;quantmod&amp;quot;)) install.packages(&amp;quot;quantmod&amp;quot;) # 用于获取数据&#10;if (!require(&amp;quot;dlm&amp;quot;)) install.packages(&amp;quot;dlm&amp;quot;) # 用于卡尔曼滤波&#10;if (!require(&amp;quot;ggplot2&amp;quot;)) install.packages(&amp;quot;ggplot2&amp;quot;) # 用于绘图&#10;if (!require(&amp;quot;reshape2&amp;quot;)) install.packages(&amp;quot;reshape2&amp;quot;) # 用于数据重塑&#10;&#10;# 加载包&#10;library(quantmod)&#10;library(dlm)&#10;library(ggplot2)&#10;library(reshape2)&#10;&#10;# 设置时间范围&#10;start_date &amp;lt;- as.Date(&amp;quot;2020-01-01&amp;quot;)&#10;end_date &amp;lt;- Sys.Date() # 使用当前日期&#10;&#10;# 下载AAPL和SPY的日收盘价数据&#10;getSymbols(&amp;quot;AAPL&amp;quot;, src = &amp;quot;yahoo&amp;quot;, from = start_date, to = end_date)&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## [1] &amp;quot;AAPL&amp;quot;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre class="r"&gt;&lt;code&gt;getSymbols(&amp;quot;SPY&amp;quot;, src = &amp;quot;yahoo&amp;quot;, from = start_date, to = end_date)&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## [1] &amp;quot;SPY&amp;quot;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre class="r"&gt;&lt;code&gt;# 提取收盘价并合并数据&#10;aapl_close &amp;lt;- Cl(AAPL)&#10;spy_close &amp;lt;- Cl(SPY)&#10;merged_data &amp;lt;- merge(aapl_close, spy_close)&#10;colnames(merged_data) &amp;lt;- c(&amp;quot;AAPL&amp;quot;, &amp;quot;SPY&amp;quot;)&#10;&#10;# 计算日对数收益率&#10;returns &amp;lt;- na.omit(data.frame(&#10; Date = index(merged_data),&#10; AAPL_Return = as.numeric(ROC(merged_data$AAPL)),&#10; SPY_Return = as.numeric(ROC(merged_data$SPY))&#10;))&#10;&#10;# 使用dlm构建卡尔曼滤波模型&#10;buildCapm &amp;lt;- function(parm) {&#10; dlmMod &amp;lt;- dlm(&#10; FF = matrix(c(1, 0), nrow=1),&#10; V = exp(parm[1]),&#10; GG = diag(2),&#10; W = diag(exp(parm[2:3])),&#10; m0 = c(0, 1),&#10; C0 = diag(2)&#10; )&#10; dlmMod$JFF &amp;lt;- matrix(c(0, 1), nrow=1)&#10; dlmMod$X &amp;lt;- returns$SPY_Return&#10; return(dlmMod)&#10;}&#10;&#10;# 初始参数猜测（取对数后的方差）&#10;init_parm &amp;lt;- c(log(0.01), log(0.0001), log(0.0001))&#10;&#10;# 使用dlmMLE优化参数&#10;mle_result &amp;lt;- dlmMLE(&#10; y = returns$AAPL_Return,&#10; parm = init_parm,&#10; build = buildCapm&#10;)&#10;&#10;# 检查优化是否成功&#10;if (mle_result$convergence != 0) {&#10; warning(&amp;quot;参数优化可能未完全收敛。&amp;quot;)&#10;}&#10;&#10;# 用优化后的参数构建最终的dlm模型&#10;final_model &amp;lt;- buildCapm(mle_result$par)&#10;&#10;# 运行卡尔曼滤波和平滑&#10;filtered_result &amp;lt;- dlmFilter(returns$AAPL_Return, final_model)&#10;smoothed_result &amp;lt;- dlmSmooth(filtered_result)&#10;&#10;# 提取平滑后的状态估计&#10;alpha_smoothed &amp;lt;- smoothed_result$s[-1, 1]&#10;beta_smoothed &amp;lt;- smoothed_result$s[-1, 2]&#10;&#10;# 提取滤波后的状态估计&#10;alpha_filtered &amp;lt;- filtered_result$m[-1, 1]&#10;beta_filtered &amp;lt;- filtered_result$m[-1, 2]&#10;&#10;# 将结果添加到数据框中&#10;returns$Alpha_Smoothed &amp;lt;- alpha_smoothed&#10;returns$Beta_Smoothed &amp;lt;- beta_smoothed&#10;returns$Alpha_Filtered &amp;lt;- alpha_filtered&#10;returns$Beta_Filtered &amp;lt;- beta_filtered&#10;&#10;# 绘制时变贝塔系数&#10;ggplot(returns, aes(x = Date)) +&#10; geom_line(aes(y = Beta_Smoothed, color = &amp;quot;Smoothed β&amp;quot;), linewidth = 0.8) +&#10; geom_line(aes(y = Beta_Filtered, color = &amp;quot;Filtered β&amp;quot;), linewidth = 0.5, linetype = &amp;quot;dashed&amp;quot;, alpha = 0.7) +&#10; geom_hline(yintercept = 1, linetype = &amp;quot;dotted&amp;quot;, color = &amp;quot;black&amp;quot;) +&#10; labs(title = &amp;quot;AAPL vs SPY: Dynamic Beta Coefficient (Kalman Filter)&amp;quot;,&#10; x = &amp;quot;Date&amp;quot;,&#10; y = &amp;quot;Beta Value&amp;quot;,&#10; color = &amp;quot;Estimation Type&amp;quot;) +&#10; theme_bw() +&#10; scale_color_manual(values = c(&amp;quot;Smoothed β&amp;quot; = &amp;quot;darkgreen&amp;quot;, &amp;quot;Filtered β&amp;quot; = &amp;quot;darkred&amp;quot;))&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;&lt;img src="https://gewutang.cn/2025/08/23/kalman-beta/index_files/figure-html/unnamed-chunk-1-1.png" width="672" /&gt;&lt;/p&gt;&#10;&lt;pre class="r"&gt;&lt;code&gt;# 绘制时变阿尔法系数&#10;ggplot(returns, aes(x = Date)) +&#10; geom_line(aes(y = Alpha_Smoothed, color = &amp;quot;Smoothed α&amp;quot;), linewidth = 0.8) +&#10; geom_hline(yintercept = 0, linetype = &amp;quot;dotted&amp;quot;, color = &amp;quot;black&amp;quot;) +&#10; labs(title = &amp;quot;AAPL vs SPY: Dynamic Alpha Coefficient (Kalman Filter)&amp;quot;,&#10; x = &amp;quot;Date&amp;quot;,&#10; y = &amp;quot;Alpha Value&amp;quot;,&#10; color = &amp;quot;Estimation Type&amp;quot;) +&#10; theme_bw() +&#10; scale_color_manual(values = c(&amp;quot;Smoothed α&amp;quot; = &amp;quot;darkgreen&amp;quot;))&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;&lt;img src="https://gewutang.cn/2025/08/23/kalman-beta/index_files/figure-html/unnamed-chunk-1-2.png" width="672" /&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;</description></item></channel></rss>