<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>风险度量 on 格物堂</title><link>https://gewutang.cn/tags/%E9%A3%8E%E9%99%A9%E5%BA%A6%E9%87%8F/</link><description>Recent content in 风险度量 on 格物堂</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Fri, 17 Dec 2010 00:00:00 +0000</lastBuildDate><atom:link href="https://gewutang.cn/tags/%E9%A3%8E%E9%99%A9%E5%BA%A6%E9%87%8F/index.xml" rel="self" type="application/rss+xml"/><item><title>VaR和方差协方差方法及R语言</title><link>https://gewutang.cn/2010/12/17/var-caculation-via-variance-covariance-method/</link><pubDate>Fri, 17 Dec 2010 00:00:00 +0000</pubDate><guid>https://gewutang.cn/2010/12/17/var-caculation-via-variance-covariance-method/</guid><description>&lt;h2 id="方差-协方差法"&gt;&lt;a href="#%e6%96%b9%e5%b7%ae-%e5%8d%8f%e6%96%b9%e5%b7%ae%e6%b3%95" class="header-anchor"&gt;&lt;/a&gt;方差-协方差法&#10;&lt;/h2&gt;&lt;p&gt;方差-协方差法是一种基于资产收益率正态性假设的VaR计算方法。其核心思想是通过历史数据估计资产收益率的均值、方差和协方差矩阵，构建投资组合收益率的概率分布，继而计算VaR值。&lt;/p&gt;&#10;&lt;p&gt;具体流程可分为以下三步：&lt;/p&gt;&#10;&lt;p&gt;首先，计算资产收益率的协方差矩阵以衡量风险关联；其次，根据投资组合权重计算组合收益率的期望值和标准差；最后，在给定置信水平下，利用正态分布分位数确定VaR值。例如，在95%置信水平下，单日VaR可表示为组合市值的绝对值乘以其标准差再乘1.645（对应正态分布左尾5%分位数）。该方法计算效率高，但对非线性风险和非正态分布敏感。多日VaR可通过时间平方根法则调整，即单日VaR乘 &lt;code&gt;\(\sqrt{T}\)&lt;/code&gt; 得到。&lt;/p&gt;&#10;&lt;h2 id="r代码实现"&gt;&lt;a href="#r%e4%bb%a3%e7%a0%81%e5%ae%9e%e7%8e%b0" class="header-anchor"&gt;&lt;/a&gt;R代码实现&#10;&lt;/h2&gt;&lt;pre&gt;&lt;code class="language-r"&gt;# 加载必要包&#10;library(quantmod)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 载入需要的程序包：xts&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 载入需要的程序包：zoo&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## &#10;## 载入程序包：'zoo'&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## The following objects are masked from 'package:base':&#10;## &#10;## as.Date, as.Date.numeric&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 载入需要的程序包：TTR&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## Registered S3 method overwritten by 'quantmod':&#10;## method from&#10;## as.zoo.data.frame zoo&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;library(PerformanceAnalytics)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## &#10;## 载入程序包：'PerformanceAnalytics'&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## The following object is masked from 'package:graphics':&#10;## &#10;## legend&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;library(ggplot2)&#10;library(dplyr)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## &#10;## ######################### Warning from 'xts' package ##########################&#10;## # #&#10;## # The dplyr lag() function breaks how base R's lag() function is supposed to #&#10;## # work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or #&#10;## # source() into this session won't work correctly. #&#10;## # #&#10;## # Use stats::lag() to make sure you're not using dplyr::lag(), or you can add #&#10;## # conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop #&#10;## # dplyr from breaking base R's lag() function. #&#10;## # #&#10;## # Code in packages is not affected. It's protected by R's namespace mechanism #&#10;## # Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning. #&#10;## # #&#10;## ###############################################################################&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## &#10;## 载入程序包：'dplyr'&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## The following objects are masked from 'package:xts':&#10;## &#10;## first, last&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## The following objects are masked from 'package:stats':&#10;## &#10;## filter, lag&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## The following objects are masked from 'package:base':&#10;## &#10;## intersect, setdiff, setequal, union&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 1. 下载股票数据（示例使用苹果、微软、亚马逊）&#10;symbols &amp;lt;- c(&amp;quot;AAPL&amp;quot;, &amp;quot;MSFT&amp;quot;, &amp;quot;AMZN&amp;quot;)&#10;getSymbols(symbols, src = &amp;quot;yahoo&amp;quot;, from = &amp;quot;2022-01-01&amp;quot;, to = Sys.Date())&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## [1] &amp;quot;AAPL&amp;quot; &amp;quot;MSFT&amp;quot; &amp;quot;AMZN&amp;quot;&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 2. 提取收盘价并合并&#10;prices &amp;lt;- merge(Cl(AAPL), Cl(MSFT), Cl(AMZN)) %&amp;gt;% na.omit()&#10;colnames(prices) &amp;lt;- symbols&#10;&#10;# 3. 计算对数收益率&#10;returns &amp;lt;- na.omit(Return.calculate(prices, method = &amp;quot;log&amp;quot;))&#10;&#10;# 4. 设定投资组合参数&#10;weights &amp;lt;- c(0.3, 0.4, 0.3) # 组合权重&#10;conf_level &amp;lt;- 0.95 # 置信水平&#10;portfolio_value &amp;lt;- 1e6 # 组合价值（美元）&#10;&#10;# 5. 计算协方差矩阵与组合标准差&#10;cov_matrix &amp;lt;- cov(returns)&#10;port_sd &amp;lt;- sqrt(t(weights) %*% cov_matrix %*% weights)&#10;&#10;# 6. 计算单日VaR&#10;var_1d &amp;lt;- abs(portfolio_value * qnorm(1 - conf_level) * port_sd)&#10;&#10;# 7. 计算5日VaR（时间平方根法则）&#10;var_5d &amp;lt;- var_1d * sqrt(5)&#10;&#10;# 8. 可视化VaR分布&#10;ggplot(data = data.frame(Returns = as.numeric(returns %*% weights)), &#10; aes(x = Returns)) +&#10; geom_histogram(aes(y = ..density..), bins = 50, fill = &amp;quot;steelblue&amp;quot;, alpha = 0.7) +&#10; geom_vline(xintercept = -var_1d/portfolio_value, color = &amp;quot;red&amp;quot;, &#10; linetype = &amp;quot;dashed&amp;quot;, size = 1) +&#10; stat_function(fun = dnorm, args = list(mean = mean(returns %*% weights),&#10; sd = sd(returns %*% weights)), color = &amp;quot;darkgreen&amp;quot;) +&#10; labs(title = &amp;quot;Portfolio Returns Distribution with VaR&amp;quot;,&#10; x = &amp;quot;Daily Returns&amp;quot;, y = &amp;quot;Density&amp;quot;) +&#10; annotate(&amp;quot;text&amp;quot;, x = -var_1d/portfolio_value, y = 15, &#10; label = paste0(&amp;quot;95% 1d VaR: $&amp;quot;, round(var_1d)), color = &amp;quot;red&amp;quot;)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.&#10;## ℹ Please use `linewidth` instead.&#10;## This warning is displayed once every 8 hours.&#10;## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was&#10;## generated.&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.&#10;## ℹ Please use `after_stat(density)` instead.&#10;## This warning is displayed once every 8 hours.&#10;## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was&#10;## generated.&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;img src="https://gewutang.cn/2010/12/17/var-caculation-via-variance-covariance-method/index_files/figure-html/unnamed-chunk-1-1.png" width="672" /&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 输出结果&#10;cat(&amp;quot;单日VaR（95%置信度）:&amp;quot;, round(var_1d), &amp;quot;美元\n&amp;quot;)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 单日VaR（95%置信度）: 28894 美元&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;cat(&amp;quot;5日VaR（95%置信度）:&amp;quot;, round(var_5d), &amp;quot;美元&amp;quot;)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 5日VaR（95%置信度）: 64609 美元&#10;&lt;/code&gt;&lt;/pre&gt;&#10;</description></item><item><title>VaR和蒙特卡洛模拟法</title><link>https://gewutang.cn/2010/12/16/var-calculation-via-montecarlo-simulation/</link><pubDate>Thu, 16 Dec 2010 00:00:00 +0000</pubDate><guid>https://gewutang.cn/2010/12/16/var-calculation-via-montecarlo-simulation/</guid><description>&lt;h2 id="蒙特卡洛模拟法"&gt;&lt;a href="#%e8%92%99%e7%89%b9%e5%8d%a1%e6%b4%9b%e6%a8%a1%e6%8b%9f%e6%b3%95" class="header-anchor"&gt;&lt;/a&gt;蒙特卡洛模拟法&#10;&lt;/h2&gt;&lt;p&gt;蒙特卡洛模拟法是一种基于随机抽样和统计模拟的数值计算方法，其通过生成大量随机样本，利用概率统计理论估计复杂问题的近似解。该方法由数学家冯·诺伊曼和乌拉姆于20世纪40年代在核武器研制项目中首次提出。蒙特卡洛模拟法也可以用来计算投资组合的VaR。&lt;/p&gt;&#10;&lt;p&gt;在应用蒙特卡洛模拟法计算VaR时，首先根据投资组合的历史特征，总结投资组合收益率对应的可能分布并提取该分布对应的核心参数；再以这些核心参数为基础，结合特定分布模拟出一系列符合要求的伪随机数作为假想的未来数据；最后，以这些“假想的未来数据”作为研究对象计算出VaR值。&lt;/p&gt;&#10;&lt;h2 id="蒙特卡洛模拟法计算单资产var"&gt;&lt;a href="#%e8%92%99%e7%89%b9%e5%8d%a1%e6%b4%9b%e6%a8%a1%e6%8b%9f%e6%b3%95%e8%ae%a1%e7%ae%97%e5%8d%95%e8%b5%84%e4%ba%a7var" class="header-anchor"&gt;&lt;/a&gt;蒙特卡洛模拟法计算单资产VaR&#10;&lt;/h2&gt;&lt;p&gt;基于R语言应用蒙特卡洛模拟法计算VaR的代码如下:&lt;/p&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 加载必要包&#10;if (!require(&amp;quot;quantmod&amp;quot;)) install.packages(&amp;quot;quantmod&amp;quot;)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 载入需要的程序包：quantmod&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 载入需要的程序包：xts&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 载入需要的程序包：zoo&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## &#10;## 载入程序包：'zoo'&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## The following objects are masked from 'package:base':&#10;## &#10;## as.Date, as.Date.numeric&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 载入需要的程序包：TTR&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## Registered S3 method overwritten by 'quantmod':&#10;## method from&#10;## as.zoo.data.frame zoo&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;if (!require(&amp;quot;MASS&amp;quot;)) install.packages(&amp;quot;MASS&amp;quot;)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 载入需要的程序包：MASS&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;library(quantmod)&#10;library(MASS)&#10;library(dplyr)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## &#10;## ######################### Warning from 'xts' package ##########################&#10;## # #&#10;## # The dplyr lag() function breaks how base R's lag() function is supposed to #&#10;## # work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or #&#10;## # source() into this session won't work correctly. #&#10;## # #&#10;## # Use stats::lag() to make sure you're not using dplyr::lag(), or you can add #&#10;## # conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop #&#10;## # dplyr from breaking base R's lag() function. #&#10;## # #&#10;## # Code in packages is not affected. It's protected by R's namespace mechanism #&#10;## # Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning. #&#10;## # #&#10;## ###############################################################################&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## &#10;## 载入程序包：'dplyr'&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## The following object is masked from 'package:MASS':&#10;## &#10;## select&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## The following objects are masked from 'package:xts':&#10;## &#10;## first, last&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## The following objects are masked from 'package:stats':&#10;## &#10;## filter, lag&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## The following objects are masked from 'package:base':&#10;## &#10;## intersect, setdiff, setequal, union&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 获取苹果公司股票数据（过去2年）&#10;getSymbols(&amp;quot;AAPL&amp;quot;, src = &amp;quot;yahoo&amp;quot;, from = as.Date(&amp;quot;2023-05-01&amp;quot;), to = as.Date(Sys.Date()))&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## [1] &amp;quot;AAPL&amp;quot;&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 计算对数收益率&#10;returns &amp;lt;- na.omit(ROC(Cl(AAPL))) &#10;colnames(returns) &amp;lt;- &amp;quot;AAPL_Return&amp;quot;&#10;&#10;# 参数设置&#10;set.seed(123)&#10;n_sim &amp;lt;- 10000 # 模拟次数&#10;confidence_level &amp;lt;- 0.95&#10;portfolio_value &amp;lt;- 1e6 # 组合价值100万美元&#10;&#10;# 估计收益率参数&#10;mu &amp;lt;- mean(returns)&#10;sigma &amp;lt;- sd(returns)&#10;&#10;# 蒙特卡洛模拟（正态分布）&#10;sim_normal &amp;lt;- rnorm(n_sim, mean = mu, sd = sigma)&#10;portfolio_loss_normal &amp;lt;- portfolio_value * (1 - exp(sim_normal)) # 对数收益转换为价格变动&#10;&#10;# 蒙特卡洛模拟（t分布）&#10;&#10;# 计算VaR&#10;var_normal &amp;lt;- quantile(portfolio_loss_normal, probs = confidence_level)&#10;&#10;# 格式化输出&#10;cat(&amp;quot;蒙特卡洛模拟VaR（正态分布假设）:&amp;quot;, round(var_normal, 2), &amp;quot;USD\n&amp;quot;)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 蒙特卡洛模拟VaR（正态分布假设）: 27011.97 USD&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 可视化比较&#10;hist(portfolio_loss_normal, breaks = 50, main = &amp;quot;正态分布模拟损失&amp;quot;, &#10; xlab = &amp;quot;损失金额(USD)&amp;quot;, col = &amp;quot;lightblue&amp;quot;)&#10;abline(v = var_normal, col = &amp;quot;red&amp;quot;, lwd = 2)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;img src="https://gewutang.cn/2010/12/16/var-calculation-via-montecarlo-simulation/index_files/figure-html/single-1.png" width="672" /&gt;&#10;&lt;p&gt;也可以将模拟的分布确定为以下分布：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;偏正态分布&lt;/li&gt;&#10;&lt;li&gt;偏t分布&lt;/li&gt;&#10;&lt;li&gt;广义误差分布&lt;/li&gt;&#10;&lt;li&gt;偏广义误差分布&lt;/li&gt;&#10;&lt;li&gt;混合正态分布&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="蒙特卡洛模拟计算多资产投资组合var"&gt;&lt;a href="#%e8%92%99%e7%89%b9%e5%8d%a1%e6%b4%9b%e6%a8%a1%e6%8b%9f%e8%ae%a1%e7%ae%97%e5%a4%9a%e8%b5%84%e4%ba%a7%e6%8a%95%e8%b5%84%e7%bb%84%e5%90%88var" class="header-anchor"&gt;&lt;/a&gt;蒙特卡洛模拟计算多资产投资组合VaR&#10;&lt;/h2&gt;&lt;p&gt;蒙特卡洛模拟通过以下步骤实现多资产VaR计算:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;历史数据获取：通过quantmod获取真实资产价格数据&lt;/li&gt;&#10;&lt;li&gt;参数估计：计算资产收益率的均值向量和协方差矩阵&lt;/li&gt;&#10;&lt;li&gt;路径生成：生成服从多元正态分布的模拟收益率路径&lt;/li&gt;&#10;&lt;li&gt;组合估值：根据权重计算组合价值变化&lt;/li&gt;&#10;&lt;li&gt;损失分布：统计模拟损失的分位数得到VaR&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;## 环境配置与数据获取&#10;# ----------------------&#10;# 加载必要包&#10;# ----------------------&#10;library(ggplot2)&#10;# library(foreach)&#10;# library(doParallel)&#10;library(Matrix)&#10;library(matrixcalc)&#10;&#10;# ----------------------&#10;# 参数设置&#10;# ----------------------&#10;symbols &amp;lt;- c(&amp;quot;AAPL&amp;quot;, &amp;quot;GOOG&amp;quot;, &amp;quot;MSFT&amp;quot;, &amp;quot;AMZN&amp;quot;) # 资产列表&#10;weights &amp;lt;- c(0.3, 0.3, 0.2, 0.2) # 投资权重&#10;V0 &amp;lt;- 1000000 # 初始组合价值（美元）&#10;n_sim &amp;lt;- 100000 # 模拟次数&#10;alpha &amp;lt;- 0.99 # 置信水平&#10;T_days &amp;lt;- 10 # 持有期（天）&#10;start_date &amp;lt;- &amp;quot;2020-01-01&amp;quot;&#10;end_date &amp;lt;- format(Sys.Date(), &amp;quot;%Y-%m-%d&amp;quot;) # 动态获取最新数据&#10;&#10;# ----------------------&#10;# 获取真实历史数据&#10;# ----------------------&#10;getSymbols(symbols, src = &amp;quot;yahoo&amp;quot;, from = start_date, to = end_date)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## [1] &amp;quot;AAPL&amp;quot; &amp;quot;GOOG&amp;quot; &amp;quot;MSFT&amp;quot; &amp;quot;AMZN&amp;quot;&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 提取调整后收盘价并计算日收益率&#10;prices &amp;lt;- do.call(merge, lapply(symbols, function(x) Ad(get(x))))&#10;# 替换原returns计算代码&#10;returns &amp;lt;- ROC(prices, type = &amp;quot;discrete&amp;quot;)&#10;&#10;# 添加数据清洗&#10;returns&amp;lt;- apply(returns, 2, function(x) {&#10; x[is.infinite(x)] &amp;lt;- NA&#10; na.omit(x)&#10;})&#10;&#10;# 验证数据完整性&#10;if (any(is.na(returns)) || any(is.infinite(returns))) {&#10; stop(&amp;quot;数据清洗失败，仍存在缺失值或无穷值&amp;quot;)&#10;}&#10;&#10; &#10;## 参数估计与路径生成（增强）&#10;&#10;# ----------------------&#10;# 计算统计参数（带时间调整）&#10;# ----------------------&#10;mu &amp;lt;- colMeans(returns) * T_days # 持有期收益率均值&#10;sigma &amp;lt;- cov(returns) * T_days&#10;&#10;robust_sigma &amp;lt;- function(sigma, eps=1e-8) {&#10; eig &amp;lt;- eigen(sigma)&#10; ev &amp;lt;- pmax(eig$values, eps) # 特征值下限保护&#10; sigma_robust &amp;lt;- eig$vectors %*% diag(ev) %*% t(eig$vectors)&#10; return(as.matrix(nearPD(sigma_robust, keepDiag=TRUE)$mat))&#10;}&#10;&#10;sigma &amp;lt;- robust_sigma(sigma)&#10;&#10;# 协方差矩阵正定性修正&#10;# 矩阵条件数校验&#10;if (kappa(sigma) &amp;gt; 1e6) warning(&amp;quot;协方差矩阵条件数过高，建议降维处理&amp;quot;)&#10;&#10;# 特征值范围验证&#10;eigen_values &amp;lt;- eigen(sigma)$values&#10;if (min(eigen_values) &amp;lt; 1e-6) stop(&amp;quot;矩阵修正失败&amp;quot;)&#10;&#10;# ----------------------&#10;# 蒙特卡洛模拟&#10;# ----------------------&#10;set.seed(123)&#10;&#10;sim_returns &amp;lt;- MASS::mvrnorm(n_sim, mu, sigma)&#10;portfolio_returns &amp;lt;- sim_returns %*% weights&#10;losses &amp;lt;- -V0 * portfolio_returns&#10;&#10;# ----------------------&#10;# 三维可视化（带ES标注）&#10;# ----------------------&#10;### 风险指标计算与可视化（最终修正版）&#10;&#10;# ----------------------&#10;# 风险指标计算&#10;# ----------------------&#10;VaR &amp;lt;- quantile(losses, probs=alpha,na.rm=TRUE)&#10;ES &amp;lt;- mean(losses[losses &amp;gt;= VaR])&#10;&#10;# ----------------------&#10;# 增强可视化&#10;# ----------------------&#10;&#10;# 生成精确breaks参数&#10;br &amp;lt;- pretty(range(losses), n=100)&#10;if (length(br) &amp;lt; 2) br &amp;lt;- seq(min(losses), max(losses), length.out=100)&#10;&#10;loss_plot &amp;lt;- ggplot(data.frame(Loss=losses), aes(x=Loss)) +&#10; geom_histogram(aes(y=..density..), breaks=br, fill=&amp;quot;#69b3a2&amp;quot;, alpha=0.7) +&#10; geom_vline(xintercept=VaR, color=&amp;quot;red&amp;quot;, linetype=&amp;quot;dashed&amp;quot;, size=1) +&#10; geom_vline(xintercept=ES, color=&amp;quot;blue&amp;quot;, linetype=&amp;quot;dotted&amp;quot;, size=1) +&#10; geom_density(color=&amp;quot;darkblue&amp;quot;, size=0.8, adjust=1.5) + # 调整核密度估计带宽&#10; labs(title=paste(&amp;quot;多资产组合损失分布 (&amp;quot;,T_days,&amp;quot;天持有期)&amp;quot;),&#10; x=&amp;quot;损失金额（美元）&amp;quot;, y=&amp;quot;密度&amp;quot;) +&#10; theme_minimal(base_size=12) +&#10; theme(&#10; plot.title=element_text(hjust=0.5, face=&amp;quot;bold&amp;quot;),&#10; panel.grid.major=element_line(color=&amp;quot;gray90&amp;quot;),&#10; panel.grid.minor=element_blank()&#10; )&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.&#10;## ℹ Please use `linewidth` instead.&#10;## This warning is displayed once every 8 hours.&#10;## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was&#10;## generated.&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 动态计算标注位置&#10;plot_data &amp;lt;- ggplot_build(loss_plot)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.&#10;## ℹ Please use `after_stat(density)` instead.&#10;## This warning is displayed once every 8 hours.&#10;## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was&#10;## generated.&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;max_density &amp;lt;- max(plot_data$data[[1]]$density)&#10;&#10;loss_plot &amp;lt;- loss_plot +&#10; annotate(&amp;quot;segment&amp;quot;, &#10; x=VaR, xend=VaR, &#10; y=0, yend=0.65*max_density,&#10; color=&amp;quot;red&amp;quot;, linetype=&amp;quot;dashed&amp;quot;) +&#10; annotate(&amp;quot;label&amp;quot;, &#10; x=VaR, y=0.7*max_density,&#10; label=paste0(alpha*100, &amp;quot;% VaR\n$&amp;quot;, format(round(VaR), big.mark=&amp;quot;,&amp;quot;)),&#10; color=&amp;quot;red&amp;quot;, fill=&amp;quot;white&amp;quot;, size=4) +&#10; annotate(&amp;quot;segment&amp;quot;,&#10; x=ES, xend=ES,&#10; y=0, yend=0.55*max_density,&#10; color=&amp;quot;blue&amp;quot;, linetype=&amp;quot;dotted&amp;quot;) +&#10; annotate(&amp;quot;label&amp;quot;,&#10; x=ES, y=0.6*max_density,&#10; label=paste0(&amp;quot;Expected Shortfall\n$&amp;quot;, format(round(ES), big.mark=&amp;quot;,&amp;quot;)),&#10; color=&amp;quot;blue&amp;quot;, fill=&amp;quot;white&amp;quot;, size=4)&#10;&#10;print(loss_plot)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;img src="https://gewutang.cn/2010/12/16/var-calculation-via-montecarlo-simulation/index_files/figure-html/trible-1.png" width="672" /&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# ----------------------&#10;# 结果输出&#10;# ----------------------&#10;cat(sprintf(&amp;quot;\n【增强版蒙特卡洛模拟结果】(%d天持有期)\n&amp;quot;, T_days))&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## &#10;## 【增强版蒙特卡洛模拟结果】(10天持有期)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;cat(&amp;quot;----------------------------------------\n&amp;quot;)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## ----------------------------------------&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;cat(sprintf(&amp;quot;▪ 投资组合规模: $%s\n&amp;quot;, format(V0, big.mark=&amp;quot;,&amp;quot;)))&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## ▪ 投资组合规模: $1e+06&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;cat(sprintf(&amp;quot;▪ VaR(%d%%置信水平): $%s\n&amp;quot;, alpha*100, format(round(VaR), big.mark=&amp;quot;,&amp;quot;)))&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## ▪ VaR(99%置信水平): $124,519&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;cat(sprintf(&amp;quot;▪ 预期损失(ES): $%s\n&amp;quot;, format(round(ES), big.mark=&amp;quot;,&amp;quot;)))&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## ▪ 预期损失(ES): $143,313&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;cat(sprintf(&amp;quot;▪ 最大可能损失: $%s\n&amp;quot;, format(round(max(losses)), big.mark=&amp;quot;,&amp;quot;)))&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## ▪ 最大可能损失: $237,724&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h2 id="基于混合多元正态分布优化蒙特卡洛模拟法"&gt;&lt;a href="#%e5%9f%ba%e4%ba%8e%e6%b7%b7%e5%90%88%e5%a4%9a%e5%85%83%e6%ad%a3%e6%80%81%e5%88%86%e5%b8%83%e4%bc%98%e5%8c%96%e8%92%99%e7%89%b9%e5%8d%a1%e6%b4%9b%e6%a8%a1%e6%8b%9f%e6%b3%95" class="header-anchor"&gt;&lt;/a&gt;基于混合多元正态分布优化蒙特卡洛模拟法&#10;&lt;/h2&gt;&lt;p&gt;混合多元正态分布可通过组合多个多元正态分布刻画不同市场状态下资产收益率的动态相关性和厚尾特征，适用于多资产组合的VaR计算。&lt;/p&gt;&#10;&lt;p&gt;在置信水平 &lt;code&gt;\(\alpha\)&lt;/code&gt; 下，多元混合正态模型的分位数 &lt;code&gt;\(Q_{\alpha}\)&lt;/code&gt; 满足以下等式：&lt;/p&gt;&#10;&lt;p&gt;$$&#10;\sum_{i=1}^k \pi_i \cdot \Phi\left(Q_\alpha ,;, \mu_p^{(i)}, \sigma_p^{(i)}\right) = \alpha&lt;br&gt;&#10;$$&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;\(\pi_i\)&lt;/code&gt;: 第 &lt;code&gt;\(i\)&lt;/code&gt; 个混合成分的权重（$\sum_{i=1}^k \pi_i = 1$）；&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;\(\mu_p^{(i)} = \mathbf{w}^\top \boldsymbol{\mu}_i\)&lt;/code&gt;: 第 &lt;code&gt;\(i\)&lt;/code&gt;个成分的线性组合均值（$\mathbf{w}$ 为资产权重向量，$\boldsymbol{\mu}_i$ 为成分均值向量）；&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;\(\sigma_p^{(i)} = \sqrt{\mathbf{w}^\top \boldsymbol{\Sigma}_i \mathbf{w}}\)&lt;/code&gt;: 第 &lt;code&gt;\(i\)&lt;/code&gt; 个成分的线性组合标准差（$\boldsymbol{\Sigma}_i$ 为成分协方差矩阵）；&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;\(\Phi(\cdot)\)&lt;/code&gt;: 标准单变量正态分布的累积分布函数（CDF）&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 加载包&#10;library(quantmod)&#10;library(mclust)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## Package 'mclust' version 6.1.1&#10;## Type 'citation(&amp;quot;mclust&amp;quot;)' for citing this R package in publications.&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;library(MASS)&#10;library(Matrix)&#10;library(matrixcalc)&#10;library(dplyr)&#10;library(showtext)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 载入需要的程序包：sysfonts&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 载入需要的程序包：showtextdb&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;library(ggplot2)&#10;library(DescTools)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## &#10;## 载入程序包：'DescTools'&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## The following object is masked from 'package:mclust':&#10;## &#10;## BrierScore&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 参数设置&#10;symbols &amp;lt;- c(&amp;quot;AAPL&amp;quot;, &amp;quot;GOOG&amp;quot;, &amp;quot;MSFT&amp;quot;)&#10;weights &amp;lt;- c(0.4, 0.3, 0.3)&#10;portfolio_value &amp;lt;- 1e6&#10;confidence_level &amp;lt;- 0.95&#10;&#10;# 数据获取与处理&#10;getSymbols(symbols, from = &amp;quot;2020-01-01&amp;quot;, to = Sys.Date())&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## [1] &amp;quot;AAPL&amp;quot; &amp;quot;GOOG&amp;quot; &amp;quot;MSFT&amp;quot;&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;prices &amp;lt;- do.call(merge, lapply(symbols, function(x) Cl(get(x))))&#10;returns &amp;lt;- ROC(prices,type = &amp;quot;discrete&amp;quot;) %&amp;gt;% na.omit() %&amp;gt;% as.matrix()&#10;&#10;# 混合模型拟合与修正&#10;set.seed(123)&#10;mix_model &amp;lt;- Mclust(returns, G = 2)&#10;&#10;# 提取并修正模型参数&#10;weights_mix &amp;lt;- mix_model$parameters$pro&#10;means_mix &amp;lt;- mix_model$parameters$mean&#10;&#10;# 检查混合模型协方差参数维度&#10;sigma_dim &amp;lt;- dim(mix_model$parameters$variance$sigma)&#10;cat(&amp;quot;Sigma参数维度:&amp;quot;, sigma_dim, &amp;quot;\n&amp;quot;)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## Sigma参数维度: 3 3 2&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 确认模型类型是否兼容&#10;if (mix_model$modelName != &amp;quot;VVV&amp;quot;) {&#10; warning(&amp;quot;当前模型&amp;quot;, mix_model$modelName, &#10; &amp;quot;可能使用共享协方差矩阵结构，需调整修正逻辑&amp;quot;)&#10;}&#10;&#10;&#10;&#10;covs_mix &amp;lt;- lapply(1:mix_model$G, function(g) {&#10; # 提取第g个成分的协方差矩阵&#10; sigma &amp;lt;- mix_model$parameters$variance$sigma[,,g]&#10; &#10; # 验证矩阵维度&#10; if (!matrixcalc::is.square.matrix(sigma)) {&#10; stop(paste(&amp;quot;成分&amp;quot;, g, &amp;quot;协方差矩阵非正方形，维度:&amp;quot;, &#10; paste(dim(sigma), collapse=&amp;quot;x&amp;quot;)))&#10; }&#10; &#10; # 特征值修正&#10; eig &amp;lt;- eigen(sigma)&#10; ev &amp;lt;- pmax(eig$values, 1e-6)&#10; sigma_corrected &amp;lt;- eig$vectors %*% diag(ev) %*% t(eig$vectors)&#10; as.matrix(nearPD(sigma_corrected)$mat)&#10;})&#10;&#10;# 增强型修正函数&#10;robust_cov_fix &amp;lt;- function(sigma) {&#10; if (!is.matrix(sigma) || nrow(sigma) != ncol(sigma)) {&#10; sigma &amp;lt;- matrix(sigma, nrow=sqrt(length(sigma))) # 向量转矩阵&#10; }&#10; &#10; # 添加对称性强制修正&#10; sigma &amp;lt;- 0.5 * (sigma + t(sigma))&#10; &#10; # 执行特征值修正&#10; eig &amp;lt;- eigen(sigma)&#10; ev &amp;lt;- pmax(eig$values, 1e-6)&#10; eig$vectors %*% diag(ev) %*% t(eig$vectors)&#10;}&#10;&#10;# 应用修正函数&#10;covs_mix &amp;lt;- lapply(1:mix_model$G, function(g) {&#10; as.matrix(nearPD(&#10; robust_cov_fix(mix_model$parameters$variance$sigma[,,g])&#10; )$mat)&#10;})&#10;&#10;# 验证所有协方差矩阵性质&#10;sapply(covs_mix, function(x) {&#10; c(dim=dim(x), isSquare=matrixcalc::is.square.matrix(x))&#10;}) # 维度应统一为NxN&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## [,1] [,2]&#10;## dim1 3 3&#10;## dim2 3 3&#10;## isSquare 1 1&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 检查正定性&#10;sapply(covs_mix, matrixcalc::is.positive.definite) # 应全为TRUE&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## [1] TRUE TRUE&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 安全模拟函数&#10;safe_mvrnorm &amp;lt;- function(n, mu, sigma) {&#10; sigma_fixed &amp;lt;- as.matrix(nearPD(sigma)$mat)&#10; MASS::mvrnorm(n, mu, sigma_fixed)&#10;}&#10;&#10;# 蒙特卡洛模拟&#10;n_sim &amp;lt;- 10000&#10;sim_returns &amp;lt;- matrix(0, nrow = n_sim, ncol = 3)&#10;&#10;for (i in 1:n_sim) {&#10; component &amp;lt;- sample(1:length(weights_mix), 1, prob = weights_mix)&#10; sim_returns[i, ] &amp;lt;- safe_mvrnorm(1, &#10; means_mix[, component], &#10; covs_mix[[component]])&#10;}&#10;&#10;# 查看模拟结果摘要&#10;summary(sim_returns) # 不应有NA或极端值&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## V1 V2 V3 &#10;## Min. :-0.1235547 Min. :-0.1244924 Min. :-0.1164468 &#10;## 1st Qu.:-0.0101667 1st Qu.:-0.0104414 1st Qu.:-0.0098317 &#10;## Median : 0.0012049 Median : 0.0009092 Median : 0.0006312 &#10;## Mean : 0.0009236 Mean : 0.0006466 Mean : 0.0007475 &#10;## 3rd Qu.: 0.0126020 3rd Qu.: 0.0120780 3rd Qu.: 0.0113348 &#10;## Max. : 0.1311838 Max. : 0.1262479 Max. : 0.1401261&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 计算VaR&#10;portfolio_returns &amp;lt;- sim_returns %*% weights&#10;&#10;portfolio_returns &amp;lt;- na.omit(portfolio_returns) # 移除缺失值&#10;if (sd(portfolio_returns) &amp;lt; 1e-6) stop(&amp;quot;收益波动率过低，无法生成有效分布&amp;quot;)&#10;&#10;# Winsorize处理极端值&#10;&#10;portfolio_returns &amp;lt;- Winsorize(portfolio_returns)&#10;losses &amp;lt;- -portfolio_value * portfolio_returns&#10;# 计算VaR和ES&#10;VaR &amp;lt;- quantile(losses, 1 - confidence_level)&#10;ES &amp;lt;- mean(losses[losses &amp;lt;= VaR])&#10;&#10;# 生成自适应breaks&#10;br &amp;lt;- pretty(range(portfolio_returns), n = 100)&#10;if (length(br) &amp;lt; 10) br &amp;lt;- seq(min(portfolio_returns), max(portfolio_returns), length.out=100)&#10;&#10;&#10;cat(&amp;quot;95% VaR:&amp;quot;, round(VaR, 2), &amp;quot;元\n&amp;quot;)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 95% VaR: -27728.82 元&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;cat(&amp;quot;95% ES:&amp;quot;,round(ES, 2),&amp;quot;元\n&amp;quot;)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 95% ES: -27729.96 元&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 验证VaR计算合理性&#10;cat(&amp;quot;VaR占组合比例:&amp;quot;, round(VaR/portfolio_value*100, 2), &amp;quot;%\n&amp;quot;) &#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## VaR占组合比例: -2.77 %&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;cat(&amp;quot;ES占组合比例:&amp;quot;, round(ES/portfolio_value*100,2),&amp;quot;%\n&amp;quot;)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## ES占组合比例: -2.77 %&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code class="language-r"&gt;# 正常范围通常在1%-10%之间&#10;&#10;showtext_auto() # 启用中文字体支持&#10;&#10;# 计算VaR和ES的标签文本&#10;var_label &amp;lt;- paste0(confidence_level*100, &amp;quot;% VaR: ¥&amp;quot;, format(round(VaR), big.mark = &amp;quot;,&amp;quot;))&#10;es_label &amp;lt;- paste0(confidence_level*100, &amp;quot;% ES: ¥&amp;quot;, format(round(ES), big.mark = &amp;quot;,&amp;quot;))&#10;&#10;# 生成风险可视化图表&#10;loss_plot &amp;lt;- ggplot(data.frame(losses), aes(x = losses)) +&#10; geom_histogram(aes(y = after_stat(density)), &#10; fill = &amp;quot;#6baed6&amp;quot;, alpha = 0.7, color = &amp;quot;white&amp;quot;) + # 优化填充色并添加边框&#10; geom_vline(aes(xintercept = VaR, color = &amp;quot;VaR&amp;quot;), &#10; linetype = &amp;quot;dashed&amp;quot;, linewidth = 1.2) +&#10; geom_vline(aes(xintercept = ES, color = &amp;quot;ES&amp;quot;), &#10; linetype = &amp;quot;dotdash&amp;quot;, linewidth = 1.2) + # 添加ES线&#10; annotate(&amp;quot;text&amp;quot;, x = VaR, y = Inf, label = var_label, # 使用annotate固定标签位置&#10; color = &amp;quot;#de2d26&amp;quot;, vjust = 2.5, size = 5, family = &amp;quot;sans&amp;quot;) +&#10; annotate(&amp;quot;text&amp;quot;, x = ES, y = Inf, label = es_label,&#10; color = &amp;quot;#3182bd&amp;quot;, vjust = 4.5, size = 5, family = &amp;quot;sans&amp;quot;) +&#10; scale_color_manual(name = &amp;quot;风险指标&amp;quot;,&#10; values = c(&amp;quot;VaR&amp;quot; = &amp;quot;#de2d26&amp;quot;, &amp;quot;ES&amp;quot; = &amp;quot;#3182bd&amp;quot;),&#10; guide = guide_legend(override.aes = list(&#10; linetype = c(&amp;quot;dashed&amp;quot;, &amp;quot;dotdash&amp;quot;)))) +&#10; labs(title = &amp;quot;投资组合风险价值分布可视化&amp;quot;,&#10; subtitle = paste(&amp;quot;基于&amp;quot;, length(symbols), &amp;quot;资产混合正态模型蒙特卡洛模拟&amp;quot;),&#10; x = &amp;quot;潜在损失金额 (元)&amp;quot;, y = &amp;quot;概率密度&amp;quot;) +&#10; theme_minimal(base_size = 14) +&#10; theme(&#10; text = element_text(family = &amp;quot;sans&amp;quot;), # 确保中文字体显示&#10; plot.title = element_text(hjust = 0.5, face = &amp;quot;bold&amp;quot;, size = 18),&#10; plot.subtitle = element_text(hjust = 0.5, color = &amp;quot;gray40&amp;quot;, size = 12),&#10; axis.title = element_text(size = 12),&#10; axis.text = element_text(color = &amp;quot;gray30&amp;quot;),&#10; panel.grid.major = element_line(color = &amp;quot;grey90&amp;quot;, linewidth = 0.3),&#10; panel.grid.minor = element_blank(), # 移除次要网格线&#10; legend.position = &amp;quot;top&amp;quot;,&#10; legend.title = element_text(size = 12),&#10; legend.text = element_text(size = 10),&#10; plot.margin = margin(1, 1, 1, 1, &amp;quot;cm&amp;quot;)&#10; ) +&#10; coord_cartesian(clip = &amp;quot;off&amp;quot;) # 允许标签超出绘图区域&#10;&#10;print(loss_plot)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;img src="https://gewutang.cn/2010/12/16/var-calculation-via-montecarlo-simulation/index_files/figure-html/mixed-1.png" width="672" /&gt;&#10;</description></item><item><title>VaR和历史模拟法及R语言</title><link>https://gewutang.cn/2010/12/15/var-calculation-using-historical-simulation/</link><pubDate>Wed, 15 Dec 2010 00:00:00 +0000</pubDate><guid>https://gewutang.cn/2010/12/15/var-calculation-using-historical-simulation/</guid><description>&#10;&#10;&#10;&lt;pre class="r"&gt;&lt;code&gt;library(showtext)&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## Loading required package: sysfonts&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## Loading required package: showtextdb&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre class="r"&gt;&lt;code&gt;font_add(&amp;quot;SimHei&amp;quot;, &amp;quot;SimHei.ttf&amp;quot;)&#10;showtext_auto()&lt;/code&gt;&lt;/pre&gt;&#10;&lt;div id="引言" class="section level2"&gt;&#10;&lt;h2&gt;引言&lt;/h2&gt;&#10;&lt;p&gt;现代金融领域的计量工作分为两大块，即资产定价和风险度量。而资产定价又是以度量风险并为风险定价为基础，由此可见，风险度量工作实际上是现代金融计量领域的核心。金融领域度量风险的方法有很多，其中应用最多的是方差、最大回撤和 VaR 等。&lt;/p&gt;&#10;&lt;p&gt;在业界，VaR 不仅单纯作为风险管理的工具，在进行投资组合优化时，也会将 VaR 作为重要的过滤指标之一。&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div id="var-的定义" class="section level2"&gt;&#10;&lt;h2&gt;VaR 的定义&lt;/h2&gt;&#10;&lt;p&gt;VaR 是 Value at Risk 的简称，中文译作“在险价值”。它是指在市场正常波动情况下，投资者所持有的投资组合在未来一定时期 &lt;span class="math inline"&gt;\(T\)&lt;/span&gt; 内，在一定置信水平 &lt;span class="math inline"&gt;\(\alpha\)&lt;/span&gt; 下所可能产生的最大可能损失。&lt;/p&gt;&#10;&lt;p&gt;假设投资者持有的投资组合的初始价值为 &lt;span class="math inline"&gt;\(P_{0}\)&lt;/span&gt; ，&lt;span class="math inline"&gt;\(r\)&lt;/span&gt; 为未来一定时期 &lt;span class="math inline"&gt;\(T\)&lt;/span&gt; 对应的收益率。那么，该组合的期末价值为：&lt;/p&gt;&#10;&lt;p&gt;&lt;span class="math display"&gt;\[&#10;P_{T}=P_{0}(1+r_{T})&#10;\]&lt;/span&gt;&#10;&lt;span class="math inline"&gt;\(r\)&lt;/span&gt; 可视作随机变量，若假设在某一置信水平下，该投资组合的最低价值为 &lt;span class="math inline"&gt;\(P^*\)&lt;/span&gt; ，则：&lt;/p&gt;&#10;&lt;p&gt;&lt;span class="math display"&gt;\[&#10;P_{T}^*=P_{0}(1+r_{T}^*)&#10;\]&lt;/span&gt;&#10;显然，根据VaR的定义可知，其等于投资组合的最低价值和初始价值之差：&lt;/p&gt;&#10;&lt;p&gt;&lt;span class="math display"&gt;\[&#10;VaR_{\alpha}=-P_{0}r_{\alpha}^*&#10;\]&lt;/span&gt;&#10;可见，计算 VaR 值等价于计算一定置信水平下的投资组合的最低价值 &lt;span class="math inline"&gt;\(P^*\)&lt;/span&gt; 或最低收益率 &lt;span class="math inline"&gt;\(r^*\)&lt;/span&gt; 。而计算最低价值或最低收益率则需依赖于价格序列或收益率序列的分布或概率密度函数。换句话说，计算金融资产序列的分布函数或概率密度函数正是计算 VaR 值的核心之处。&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div id="var-的算法" class="section level1"&gt;&#10;&lt;h1&gt;VaR 的算法&lt;/h1&gt;&#10;&lt;p&gt;清楚了 VaR 的定义，计算 VaR 的方法也就呼之欲出了。目前，常用的 VaR 算法可以分为参数法即方差-协方差法、蒙特卡洛模拟法以及非参数方法即历史模拟法。在 VaR 的应用过程中，人们也对 VaR 的上述算法进行了扩展。比如，在方差-协方差方法下人们提出了指数级权平均模型计算方差或者结合 Garch 类模型计算方差进而计算 VaR 的方法。&lt;/p&gt;&#10;&lt;div id="历史模拟法" class="section level2"&gt;&#10;&lt;h2&gt;历史模拟法&lt;/h2&gt;&#10;&lt;p&gt;历史模拟法是最简单的计算 VaR 的方法。它假设投资组合未来的波动与投资组合的历史数据完全一致，因此，计算投资组合的未来 VaR 就等同于计算历史数据的既有 VaR 。&lt;/p&gt;&#10;&lt;p&gt;历史模拟法的步骤为：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;搜集历史数据&lt;/li&gt;&#10;&lt;li&gt;计算历史数据的几何收益率&lt;/li&gt;&#10;&lt;li&gt;对收益率进行排序并计算给定置信水平的下分位数&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/div&gt;&#10;&lt;div id="单资产-var-的计算及其r实现" class="section level2"&gt;&#10;&lt;h2&gt;单资产 VaR 的计算及其R实现&lt;/h2&gt;&#10;&lt;p&gt;下面以计算单个资产的VaR为例：&lt;/p&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;library(quantmod)&#10;&#10;# 获取苹果公司股票数据&#10;getSymbols(&amp;quot;AAPL&amp;quot;, src = &amp;quot;yahoo&amp;quot;, from = Sys.Date() - 365, to = Sys.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;# 计算对数收益率&#10;returns &amp;lt;- na.omit(periodReturn(AAPL, period = &amp;#39;daily&amp;#39;, type = &amp;#39;log&amp;#39;))&#10;&#10;# 设置置信水平 (95%)&#10;confidence_level &amp;lt;- 0.95&#10;&#10;# 历史模拟法计算VaR&#10;historical_var &amp;lt;- -quantile(returns, probs = 1 - confidence_level)&#10;&#10;# 打印结果&#10;cat(&amp;quot;历史模拟法计算的每日VaR（95%置信水平）:&amp;quot;, round(historical_var*100, 2), &amp;quot;%\n&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 历史模拟法计算的每日VaR（95%置信水平）: 3.22 %&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre class="r"&gt;&lt;code&gt;# 可视化结果&#10;hist(returns, breaks = 50, main = &amp;quot;日收益率分布与VaR（95%）&amp;quot;,&#10; xlab = &amp;quot;日收益率&amp;quot;, col = &amp;quot;lightblue&amp;quot;, border = &amp;quot;white&amp;quot;)&#10;abline(v = -historical_var, col = &amp;quot;red&amp;quot;, lwd = 2)&#10;text(x = -historical_var, y = par(&amp;quot;usr&amp;quot;)[4]*0.9, &#10; labels = paste(&amp;quot;VaR =&amp;quot;, round(historical_var*100, 2), &amp;quot;%&amp;quot;), &#10; pos = 2, col = &amp;quot;red&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;&lt;img src="https://gewutang.cn/2010/12/15/var-calculation-using-historical-simulation/index_files/figure-html/unnamed-chunk-1-1.png" width="672" /&gt;&lt;/p&gt;&#10;&lt;p&gt;也可以直接用PerformanceAnalytics包中的VaR函数计算历史模拟法下的VaR值：&lt;/p&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;PerformanceAnalytics&amp;quot;)) install.packages(&amp;quot;PerformanceAnalytics&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## Loading required package: PerformanceAnalytics&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## &#10;## Attaching package: &amp;#39;PerformanceAnalytics&amp;#39;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## The following object is masked from &amp;#39;package:graphics&amp;#39;:&#10;## &#10;## legend&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre class="r"&gt;&lt;code&gt;library(quantmod)&#10;library(PerformanceAnalytics)&#10;&#10;# 获取苹果公司股票数据（过去250个交易日）&#10;getSymbols(&amp;quot;AAPL&amp;quot;, src = &amp;quot;yahoo&amp;quot;, from = Sys.Date() - 365, to = Sys.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;# 计算对数收益率&#10;returns &amp;lt;- na.omit(ROC(Cl(AAPL))) # 等效于 log(Cl(AAPL)/lag(Cl(AAPL)))&#10;&#10;# 使用PerformanceAnalytics包计算历史模拟法VaR（95%置信水平）&#10;var_result &amp;lt;- VaR(&#10; R = returns,&#10; p = 0.95,&#10; method = &amp;quot;historical&amp;quot;,&#10; portfolio_method = &amp;quot;single&amp;quot;&#10;)&#10;&#10;# 提取并格式化结果&#10;historical_var &amp;lt;- abs(var_result[1,]) # VaR值通常取正数表示损失&#10;confidence_level &amp;lt;- attr(var_result, &amp;quot;cl&amp;quot;)&#10;&#10;# 输出结果&#10;cat(&amp;quot;PerformanceAnalytics计算的每日VaR（&amp;quot;, confidence_level*100, &amp;quot;%置信水平）:&amp;quot;,&#10; round(historical_var*100, 2), &amp;quot;%\n&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## PerformanceAnalytics计算的每日VaR（ %置信水平）: 3.22 %&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre class="r"&gt;&lt;code&gt;# 可视化收益率分布及VaR&#10;hist(returns, breaks = 50, main = &amp;quot;日收益率分布与VaR（历史模拟法）&amp;quot;,&#10; xlab = &amp;quot;日收益率&amp;quot;, col = &amp;quot;lightblue&amp;quot;, border = &amp;quot;white&amp;quot;)&#10;abline(v = -historical_var, col = &amp;quot;red&amp;quot;, lwd = 2)&#10;text(x = -historical_var, y = par(&amp;quot;usr&amp;quot;)[4]*0.9,&#10; labels = paste(&amp;quot;VaR =&amp;quot;, round(historical_var*100, 2), &amp;quot;%&amp;quot;),&#10; pos = 2, col = &amp;quot;red&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;&lt;img src="https://gewutang.cn/2010/12/15/var-calculation-using-historical-simulation/index_files/figure-html/unnamed-chunk-2-1.png" width="672" /&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div id="多资产投资组合的-var-计算及其-r-实现" class="section level2"&gt;&#10;&lt;h2&gt;多资产投资组合的 VaR 计算及其 R 实现&lt;/h2&gt;&#10;&lt;p&gt;用历史模拟法计算多资产投资组合的 VaR 与单资产思路类似，唯一不同的是要按照当前投资组合中各资产的权重计算投资组合的历史收益率。&lt;/p&gt;&#10;&lt;p&gt;具体R代码如下:&lt;/p&gt;&#10;&lt;pre class="r"&gt;&lt;code&gt;# 加载必要包&#10;library(quantmod) # 金融数据获取&#10;library(dplyr) # 数据处理&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## &#10;## ######################### Warning from &amp;#39;xts&amp;#39; package ##########################&#10;## # #&#10;## # The dplyr lag() function breaks how base R&amp;#39;s lag() function is supposed to #&#10;## # work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or #&#10;## # source() into this session won&amp;#39;t work correctly. #&#10;## # #&#10;## # Use stats::lag() to make sure you&amp;#39;re not using dplyr::lag(), or you can add #&#10;## # conflictRules(&amp;#39;dplyr&amp;#39;, exclude = &amp;#39;lag&amp;#39;) to your .Rprofile to stop #&#10;## # dplyr from breaking base R&amp;#39;s lag() function. #&#10;## # #&#10;## # Code in packages is not affected. It&amp;#39;s protected by R&amp;#39;s namespace mechanism #&#10;## # Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning. #&#10;## # #&#10;## ###############################################################################&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## &#10;## Attaching package: &amp;#39;dplyr&amp;#39;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## The following objects are masked from &amp;#39;package:xts&amp;#39;:&#10;## &#10;## first, last&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## The following objects are masked from &amp;#39;package:stats&amp;#39;:&#10;## &#10;## filter, lag&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## The following objects are masked from &amp;#39;package:base&amp;#39;:&#10;## &#10;## intersect, setdiff, setequal, union&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre class="r"&gt;&lt;code&gt;library(ggplot2) # 可视化&#10;&#10;# ========== 参数设置 ==========&#10;symbols &amp;lt;- c(&amp;quot;AAPL&amp;quot;, &amp;quot;GOOG&amp;quot;, &amp;quot;MSFT&amp;quot;) # 资产代码（苹果、谷歌、微软）&#10;weights &amp;lt;- c(0.5, 0.3, 0.2) # 资产权重（总和为1）&#10;portfolio_value &amp;lt;- 1e7 # 投资组合当前价值（假设1千万元）&#10;confidence_level &amp;lt;- 0.95 # 置信水平&#10;start_date &amp;lt;- &amp;quot;2020-01-01&amp;quot; # 数据开始日期&#10;end_date &amp;lt;- &amp;quot;2023-12-31&amp;quot; # 数据结束日期&#10;&#10;# ========== 1. 获取历史价格数据 ==========&#10;getSymbols(symbols, 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; &amp;quot;GOOG&amp;quot; &amp;quot;MSFT&amp;quot;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre class="r"&gt;&lt;code&gt;# 提取收盘价并合并&#10;prices &amp;lt;- merge(Cl(get(symbols[1])), Cl(get(symbols[2])), Cl(get(symbols[3])))&#10;colnames(prices) &amp;lt;- symbols&#10;&#10;# 清理缺失值（确保日期对齐）&#10;prices_clean &amp;lt;- na.omit(prices)&#10;&#10;# ========== 2. 计算各资产对数收益率 ==========&#10;returns &amp;lt;- data.frame(&#10; AAPL = as.numeric(Delt(prices_clean$AAPL)),&#10; GOOG = as.numeric(Delt(prices_clean$GOOG)),&#10; MSFT = as.numeric(Delt(prices_clean$MSFT))&#10;) %&amp;gt;% na.omit() # 去除首行NA&#10;&#10;# ========== 3. 计算投资组合每日收益率 ==========&#10;# 将收益率转换为矩阵进行加权计算&#10;returns_matrix &amp;lt;- as.matrix(returns)&#10;portfolio_returns &amp;lt;- returns_matrix %*% weights&#10;&#10;# ========== 4. 历史模拟法计算VaR ==========&#10;# 按升序排列组合收益率（损失为负值）&#10;sorted_returns &amp;lt;- sort(portfolio_returns)&#10;&#10;# 确定分位数位置&#10;n &amp;lt;- length(sorted_returns)&#10;var_index &amp;lt;- floor((1 - confidence_level) * n)&#10;var_quantile &amp;lt;- sorted_returns[var_index]&#10;&#10;# 计算VaR绝对值&#10;VaR &amp;lt;- abs(var_quantile) * portfolio_value&#10;&#10;# ========== 5. 输出结果 ==========&#10;cat(&amp;quot;========== 计算结果 ==========\n&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## ========== 计算结果 ==========&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre class="r"&gt;&lt;code&gt;cat(&amp;quot;置信水平:&amp;quot;, confidence_level * 100, &amp;quot;%\n&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 置信水平: 95 %&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre class="r"&gt;&lt;code&gt;cat(&amp;quot;历史数据天数:&amp;quot;, n, &amp;quot;\n&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 历史数据天数: 1005&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre class="r"&gt;&lt;code&gt;cat(&amp;quot;VaR分位数对应收益率:&amp;quot;, round(var_quantile * 100, 2), &amp;quot;%\n&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## VaR分位数对应收益率: -2.94 %&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre class="r"&gt;&lt;code&gt;cat(&amp;quot;组合VaR值:&amp;quot;, round(VaR, 2), &amp;quot;元\n&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre&gt;&lt;code&gt;## 组合VaR值: 294069.7 元&lt;/code&gt;&lt;/pre&gt;&#10;&lt;pre class="r"&gt;&lt;code&gt;# ========== 6. 可视化== ==========&#10;# 绘制组合收益率分布直方图&#10;ggplot(data.frame(Return = portfolio_returns), aes(x = Return)) +&#10; geom_histogram(bins = 50, fill = &amp;quot;lightblue&amp;quot;, color = &amp;quot;black&amp;quot;) +&#10; geom_vline(xintercept = var_quantile, color = &amp;quot;red&amp;quot;, linewidth = 1) +&#10; labs(title = &amp;quot;投资组合历史收益率分布与VaR&amp;quot;,&#10; x = &amp;quot;收益率&amp;quot;, y = &amp;quot;频数&amp;quot;) +&#10; annotate(&amp;quot;text&amp;quot;, x = var_quantile, y = Inf, &#10; label = paste0(confidence_level * 100, &amp;quot;% VaR: &amp;quot;, round(VaR, 2), &amp;quot;元&amp;quot;),&#10; color = &amp;quot;red&amp;quot;, vjust = 1.5, hjust = -0.1) +&#10; theme_minimal()&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;&lt;img src="https://gewutang.cn/2010/12/15/var-calculation-using-historical-simulation/index_files/figure-html/unnamed-chunk-3-1.png" width="672" /&gt;&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;</description></item></channel></rss>