分层Copula与Pair-Copula计算指南
一、理论基础与概念解析
1.1 分层Copula(Hierarchical Copula)
分层Copula通过嵌套结构建模多变量依赖关系,特别适合处理多尺度依赖和非对称依赖。
分层Copula结构:
┌─────────────────────────────────────────────────────────────┐
│ 全局Copula (顶层) │
│ C_θ₀(u₁, u₂, ..., uₙ) │
├─────────────────────────────────────────────────────────────┤
│ 局部Copula 1 │ 局部Copula 2 │ ... │ 局部Copula k │
│ C_θ₁(u₁, u₂) │ C_θ₂(u₃, u₄) │ │ C_θₖ(uₙ₋₁,uₙ)│
└─────────────────────────────────────────────────────────────┘
1.2 Pair-Copula(R-Vine结构)
Pair-Copula分解将多维Copula分解为一系列二元Copula的乘积:
二、MATLAB实现代码
2.1 主程序:hierarchical_paircopula_main.m
%% 分层Copula与Pair-Copula计算系统
% 功能:实现分层Copula和Pair-Copula(R-Vine)的建模与计算
clear; clc; close all;
%% 1. 系统参数配置
fprintf('=== 分层Copula与Pair-Copula计算系统 ===\n');
params = configure_copula_parameters();
fprintf('Copula系统配置:\n');
fprintf(' 变量维度: %d\n', params.dim);
fprintf(' 样本数量: %d\n', params.n_samples);
fprintf(' 分层结构: %s\n', params.hierarchy_type);
fprintf(' Pair-Copula类型: %s\n', params.paircopula_type);
fprintf(' 优化方法: %s\n\n', params.optimization_method);
%% 2. 生成/加载数据
fprintf('生成/加载数据...\n');
data = generate_copula_data(params);
%% 3. 分层Copula建模
fprintf('构建分层Copula模型...\n');
tic;
hierarchical_copula = build_hierarchical_copula(data, params);
hierarchical_time = toc;
fprintf(' 分层Copula构建完成!耗时: %.3f秒\n', hierarchical_time);
%% 4. Pair-Copula(R-Vine)建模
fprintf('构建Pair-Copula(R-Vine)模型...\n');
tic;
rvine_model = build_rvine_model(data, params);
rvine_time = toc;
fprintf(' R-Vine模型构建完成!耗时: %.3f秒\n', rvine_time);
%% 5. 模型比较与选择
fprintf('模型比较与选择...\n');
model_comparison = compare_copula_models(hierarchical_copula, rvine_model, data, params);
%% 6. 依赖结构分析
fprintf('依赖结构分析...\n');
dependency_analysis = analyze_dependency_structure(rvine_model, params);
%% 7. 风险度量计算
fprintf('风险度量计算...\n');
risk_measures = calculate_risk_measures(hierarchical_copula, rvine_model, params);
%% 8. 可视化结果
visualize_copula_results(hierarchical_copula, rvine_model, dependency_analysis, risk_measures, params);
2.2 参数配置:configure_copula_parameters.m
function params = configure_copula_parameters()
% 配置Copula系统参数
%% 基本参数
params.dim = 5; % 变量维度(资产数量)
params.n_samples = 1000; % 样本数量
params.seed = 42; % 随机种子
%% 分层结构参数
params.hierarchy_type = 'binary_tree'; % 分层类型: 'binary_tree', 'star', 'custom'
params.n_levels = 3; % 分层级数
params.clustering_method = 'ward'; % 聚类方法
%% Pair-Copula参数
params.paircopula_type = 'rvine'; % Pair-Copula类型: 'rvine', 'dvine', 'cvine'
params.copula_families = {'gaussian', 't', 'clayton', 'gumbel', 'frank'};
params.selection_criterion = 'aic'; % 选择准则: 'aic', 'bic'
%% 优化参数
params.optimization_method = 'ml'; % 优化方法: 'ml', 'itau'
params.max_iter = 1000; % 最大迭代次数
params.tolerance = 1e-6; % 收敛容差
%% 风险度量参数
params.confidence_level = 0.95; % 置信水平
params.time_horizon = 1; % 时间跨度(年)
params.n_simulations = 10000; % 蒙特卡洛模拟次数
%% 可视化参数
params.plot_resolution = 50; % 绘图分辨率
fprintf('Copula参数配置完成!\n');
end
2.3 数据生成:generate_copula_data.m
function data = generate_copula_data(params)
% 生成Copula建模数据
rng(params.seed); % 设置随机种子
% 生成多元正态分布数据(作为基础)
mu = zeros(params.dim, 1);
Sigma = generate_correlation_matrix(params.dim);
% 生成多元正态样本
normal_samples = mvnrnd(mu, Sigma, params.n_samples);
% 转换为均匀分布(概率积分变换)
uniform_samples = zeros(params.n_samples, params.dim);
for i = 1:params.dim
uniform_samples(:, i) = normcdf(normal_samples(:, i), mu(i), sqrt(Sigma(i, i)));
end
% 添加尾部依赖(可选)
if params.dim >= 3
% 在部分变量间添加Clayton Copula依赖
clayton_samples = copularnd('Clayton', 2, params.n_samples);
uniform_samples(:, 1:2) = clayton_samples(:, 1:2);
end
% 组织数据结构
data.uniform = uniform_samples;
data.normal = normal_samples;
data.correlation = Sigma;
data.names = cellstr(num2str((1:params.dim)', 'Asset_%d'));
fprintf(' 生成 %d 个样本,%d 个变量\n', params.n_samples, params.dim);
fprintf(' 相关性矩阵条件数: %.2f\n', cond(Sigma));
end
function Sigma = generate_correlation_matrix(dim)
% 生成相关矩阵
Sigma = eye(dim);
% 设置合理的相关系数
for i = 1:dim
for j = i+1:dim
if i == j
Sigma(i, j) = 1;
else
% 生成-0.3到0.8之间的相关系数
rho = -0.3 + 1.1 * rand();
Sigma(i, j) = rho;
Sigma(j, i) = rho;
end
end
end
% 确保正定性
[V, D] = eig(Sigma);
D = diag(max(diag(D), 0.01));
Sigma = V * D * V';
end
2.4 分层Copula构建:build_hierarchical_copula.m
function hierarchical_copula = build_hierarchical_copula(data, params)
% 构建分层Copula模型
fprintf(' 1. 变量聚类分析...\n');
clusters = perform_variable_clustering(data, params);
fprintf(' 2. 构建分层结构...\n');
hierarchy = build_hierarchy_structure(clusters, params);
fprintf(' 3. 估计每层Copula参数...\n');
copula_params = estimate_hierarchical_parameters(data, hierarchy, params);
fprintf(' 4. 验证分层Copula...\n');
validation_results = validate_hierarchical_copula(data, hierarchy, copula_params, params);
% 组织输出结构
hierarchical_copula = struct();
hierarchical_copula.hierarchy = hierarchy;
hierarchical_copula.parameters = copula_params;
hierarchical_copula.validation = validation_results;
hierarchical_copula.loglikelihood = validation_results.loglikelihood;
hierarchical_copula.aic = -2 * validation_results.loglikelihood + 2 * count_parameters(copula_params);
fprintf(' 分层CopulaAIC: %.2f\n', hierarchical_copula.aic);
end
function clusters = perform_variable_clustering(data, params)
% 变量聚类分析
n_vars = size(data.uniform, 2);
% 计算距离矩阵(基于Kendall's tau)
distance_matrix = zeros(n_vars, n_vars);
for i = 1:n_vars
for j = i+1:n_vars
tau = corr(data.uniform(:, i), data.uniform(:, j), 'Type', 'Kendall');
distance_matrix(i, j) = 1 - abs(tau);
distance_matrix(j, i) = distance_matrix(i, j);
end
end
% 层次聚类
linkage_tree = linkage(distance_matrix, params.clustering_method);
% 确定聚类数量
n_clusters = max(2, floor(n_vars / 2));
% 获取聚类分配
cluster_assignments = cluster(linkage_tree, 'maxclust', n_clusters);
% 组织聚类结果
clusters = struct();
clusters.tree = linkage_tree;
clusters.assignments = cluster_assignments;
clusters.n_clusters = n_clusters;
clusters.distance_matrix = distance_matrix;
fprintf(' 聚类完成:%d个变量分为%d个簇\n', n_vars, n_clusters);
end
function hierarchy = build_hierarchy_structure(clusters, params)
% 构建分层结构
n_vars = length(clusters.assignments);
switch params.hierarchy_type
case 'binary_tree'
hierarchy = build_binary_tree(clusters, n_vars);
case 'star'
hierarchy = build_star_structure(clusters, n_vars);
case 'custom'
hierarchy = build_custom_structure(clusters, n_vars);
otherwise
error('未知的分层类型: %s', params.hierarchy_type);
end
fprintf(' 分层结构构建完成:%d层\n', hierarchy.n_levels);
end
function hierarchy = build_binary_tree(clusters, n_vars)
% 构建二叉树分层结构
hierarchy = struct();
hierarchy.n_levels = ceil(log2(n_vars));
hierarchy.levels = cell(hierarchy.n_levels, 1);
% 第一层:原始变量
hierarchy.levels{1} = (1:n_vars)';
% 后续层:聚类合并
current_clusters = unique(clusters.assignments);
for level = 2:hierarchy.n_levels
if level == 2
hierarchy.levels{level} = current_clusters;
else
% 继续合并聚类
n_current = length(current_clusters);
new_clusters = cell(ceil(n_current/2), 1);
for i = 1:2:min(n_current, length(new_clusters)*2)
if i+1 <= n_current
new_clusters{ceil(i/2)} = [current_clusters(i), current_clusters(i+1)];
else
new_clusters{ceil(i/2)} = current_clusters(i);
end
end
hierarchy.levels{level} = new_clusters;
current_clusters = new_clusters;
end
end
hierarchy.type = 'binary_tree';
end
function copula_params = estimate_hierarchical_parameters(data, hierarchy, params)
% 估计分层Copula参数
copula_params = struct();
% 逐层估计Copula参数
for level = 1:hierarchy.n_levels
level_nodes = hierarchy.levels{level};
if iscell(level_nodes)
% 处理聚类节点
for node_idx = 1:length(level_nodes)
node = level_nodes{node_idx};
if isvector(node) && length(node) > 1
% 估计该聚类的Copula参数
node_data = data.uniform(:, node);
copula_params = estimate_node_copula(node_data, node, level, node_idx, copula_params, params);
end
end
else
% 处理单个变量
for var_idx = 1:length(level_nodes)
var_id = level_nodes(var_idx);
copula_params = estimate_variable_copula(data.uniform(:, var_id), var_id, level, var_idx, copula_params, params);
end
end
end
fprintf(' 参数估计完成\n');
end
function copula_params = estimate_node_copula(node_data, node, level, node_idx, copula_params, params)
% 估计节点Copula参数
n_vars_in_node = size(node_data, 2);
% 选择合适的Copula族
best_family = select_copula_family(node_data, params);
% 估计参数
switch best_family
case 'gaussian'
rho = corr(node_data, 'Type', 'Pearson');
copula_params.(sprintf('level%d_node%d', level, node_idx)) = struct('family', 'gaussian', 'rho', rho);
case 't'
[rho, nu] = copulafit('t', node_data);
copula_params.(sprintf('level%d_node%d', level, node_idx)) = struct('family', 't', 'rho', rho, 'nu', nu);
case 'clayton'
alpha = copulafit('Clayton', node_data);
copula_params.(sprintf('level%d_node%d', level, node_idx)) = struct('family', 'clayton', 'alpha', alpha);
case 'gumbel'
alpha = copulafit('Gumbel', node_data);
copula_params.(sprintf('level%d_node%d', level, node_idx)) = struct('family', 'gumbel', 'alpha', alpha);
case 'frank'
alpha = copulafit('Frank', node_data);
copula_params.(sprintf('level%d_node%d', level, node_idx)) = struct('family', 'frank', 'alpha', alpha);
end
end
function best_family = select_copula_family(data, params)
% 选择最佳Copula族
best_family = 'gaussian';
best_aic = inf;
for family_idx = 1:length(params.copula_families)
family = params.copula_families{family_idx};
try
% 估计参数
switch lower(family)
case 'gaussian'
rho = corr(data, 'Type', 'Pearson');
loglik = calculate_gaussian_loglikelihood(data, rho);
case 't'
[rho, nu] = copulafit('t', data);
loglik = calculate_t_loglikelihood(data, rho, nu);
case 'clayton'
alpha = copulafit('Clayton', data);
loglik = calculate_clayton_loglikelihood(data, alpha);
case 'gumbel'
alpha = copulafit('Gumbel', data);
loglik = calculate_gumbel_loglikelihood(data, alpha);
case 'frank'
alpha = copulafit('Frank', data);
loglik = calculate_frank_loglikelihood(data, alpha);
end
% 计算AIC
n_params = count_family_parameters(family);
aic = -2 * loglik + 2 * n_params;
if aic < best_aic
best_aic = aic;
best_family = family;
end
catch
continue;
end
end
end
2.5 R-Vine模型构建:build_rvine_model.m
function rvine_model = build_rvine_model(data, params)
% 构建R-Vine(Regular Vine)模型
fprintf(' 1. 选择Vine结构...\n');
vine_structure = select_vine_structure(data, params);
fprintf(' 2. 估计Pair-Copula参数...\n');
pair_copulas = estimate_pair_copulas(data, vine_structure, params);
fprintf(' 3. 计算条件分布...\n');
conditional_distributions = calculate_conditional_distributions(data, vine_structure, pair_copulas, params);
fprintf(' 4. 验证R-Vine模型...\n');
validation_results = validate_rvine_model(data, vine_structure, pair_copulas, params);
% 组织输出结构
rvine_model = struct();
rvine_model.structure = vine_structure;
rvine_model.pair_copulas = pair_copulas;
rvine_model.conditional_distributions = conditional_distributions;
rvine_model.validation = validation_results;
rvine_model.loglikelihood = validation_results.loglikelihood;
rvine_model.aic = -2 * validation_results.loglikelihood + 2 * count_rvine_parameters(pair_copulas);
fprintf(' R-Vine模型AIC: %.2f\n', rvine_model.aic);
end
function vine_structure = select_vine_structure(data, params)
% 选择Vine结构
n_vars = size(data.uniform, 2);
switch params.paircopula_type
case 'rvine'
vine_structure = select_regular_vine(data, params);
case 'dvine'
vine_structure = select_d_vine(n_vars);
case 'cvine'
vine_structure = select_c_vine(n_vars);
otherwise
error('未知的Pair-Copula类型: %s', params.paircopula_type);
end
fprintf(' Vine结构选择完成\n');
end
function vine_structure = select_regular_vine(data, params)
% 选择正则Vine结构(基于最大生成树)
n_vars = size(data.uniform, 2);
% 计算Kendall's tau矩阵
tau_matrix = zeros(n_vars, n_vars);
for i = 1:n_vars
for j = i+1:n_vars
tau = corr(data.uniform(:, i), data.uniform(:, j), 'Type', 'Kendall');
tau_matrix(i, j) = abs(tau);
tau_matrix(j, i) = abs(tau);
end
end
% 构建最大生成树(基于Kruskal算法)
edges = [];
for i = 1:n_vars
for j = i+1:n_vars
edges = [edges; i, j, tau_matrix(i, j)];
end
end
% 按权重降序排序
[~, idx] = sort(edges(:, 3), 'descend');
edges = edges(idx, :);
% Kruskal算法
parent = 1:n_vars;
tree_edges = [];
for edge_idx = 1:size(edges, 1)
i = edges(edge_idx, 1);
j = edges(edge_idx, 2);
% 查找根节点
root_i = find_root(parent, i);
root_j = find_root(parent, j);
if root_i ~= root_j
tree_edges = [tree_edges; i, j];
parent(root_j) = root_i;
if size(tree_edges, 1) == n_vars - 1
break;
end
end
end
% 组织Vine结构
vine_structure = struct();
vine_structure.n_trees = n_vars - 1;
vine_structure.trees = cell(vine_structure.n_trees, 1);
vine_structure.trees{1} = tree_edges;
% 构建后续树(简化版)
for tree_idx = 2:vine_structure.n_trees
vine_structure.trees{tree_idx} = generate_next_tree(vine_structure.trees{tree_idx-1}, n_vars);
end
vine_structure.type = 'regular_vine';
end
function root = find_root(parent, node)
% 查找根节点
while parent(node) ~= node
node = parent(node);
end
root = node;
end
function next_tree = generate_next_tree(prev_tree, n_vars)
% 生成下一棵树(简化版)
next_tree = [];
n_edges = size(prev_tree, 1);
for i = 1:n_edges-1
for j = i+1:n_edges
% 检查是否有共同节点
common_nodes = intersect(prev_tree(i, :), prev_tree(j, :));
if ~isempty(common_nodes)
% 创建新边
new_edge = setdiff([prev_tree(i, :), prev_tree(j, :)], common_nodes);
if length(new_edge) == 2
next_tree = [next_tree; new_edge];
end
end
end
end
end
function pair_copulas = estimate_pair_copulas(data, vine_structure, params)
% 估计Pair-Copula参数
pair_copulas = struct();
n_trees = vine_structure.n_trees;
for tree_idx = 1:n_trees
tree_edges = vine_structure.trees{tree_idx};
n_edges = size(tree_edges, 1);
for edge_idx = 1:n_edges
% 获取边的端点
u = tree_edges(edge_idx, 1);
v = tree_edges(edge_idx, 2);
% 获取条件变量(简化版)
condition_vars = [];
if tree_idx > 1
% 查找条件变量
condition_vars = find_condition_variables(vine_structure.trees{tree_idx-1}, u, v);
end
% 估计Pair-Copula参数
if isempty(condition_vars)
edge_data = data.uniform(:, [u, v]);
else
edge_data = data.uniform(:, [u, v, condition_vars]);
end
% 选择最佳Copula族
best_family = select_copula_family(edge_data, params);
% 估计参数
copula_params = estimate_edge_copula(edge_data, best_family, params);
% 存储结果
edge_name = sprintf('tree%d_edge%d_%d_%d', tree_idx, edge_idx, u, v);
pair_copulas.(edge_name) = struct('u', u, 'v', v, 'condition_vars', condition_vars, ...
'family', best_family, 'params', copula_params);
end
end
fprintf(' Pair-Copula参数估计完成\n');
end
function condition_vars = find_condition_variables(prev_tree, u, v)
% 查找条件变量
condition_vars = [];
for edge_idx = 1:size(prev_tree, 1)
edge = prev_tree(edge_idx, :);
if ismember(u, edge) && ismember(v, edge)
% 找到共同边
common_vars = intersect(edge, [u, v]);
if length(common_vars) == 1
condition_vars = setdiff(edge, common_vars);
break;
end
end
end
end
2.6 模型比较:compare_copula_models.m
function comparison = compare_copula_models(hierarchical_copula, rvine_model, data, params)
% 比较分层Copula和R-Vine模型
fprintf(' 模型比较分析...\n');
% 计算各种信息准则
comparison = struct();
% AIC比较
comparison.aic_diff = hierarchical_copula.aic - rvine_model.aic;
comparison.better_model_aic = comparison.aic_diff > 0 ? 'R-Vine' : 'Hierarchical Copula';
% BIC比较
n_params_hier = count_parameters(hierarchical_copula.parameters);
n_params_rvine = count_rvine_parameters(rvine_model.pair_copulas);
n_obs = size(data.uniform, 1);
comparison.bic_hier = -2 * hierarchical_copula.loglikelihood + n_params_hier * log(n_obs);
comparison.bic_rvine = -2 * rvine_model.loglikelihood + n_params_rvine * log(n_obs);
comparison.bic_diff = comparison.bic_hier - comparison.bic_rvine;
comparison.better_model_bic = comparison.bic_diff > 0 ? 'R-Vine' : 'Hierarchical Copula';
% 似然比检验
lr_stat = 2 * (rvine_model.loglikelihood - hierarchical_copula.loglikelihood);
df = n_params_rvine - n_params_hier;
p_value = 1 - chi2cdf(lr_stat, df);
comparison.lr_test = struct('statistic', lr_stat, 'df', df, 'p_value', p_value, ...
'significant', p_value < 0.05);
% 预测能力比较(使用交叉验证)
comparison.cv_error = compare_predictive_ability(hierarchical_copula, rvine_model, data, params);
fprintf(' AIC比较: 分层Copula=%.2f, R-Vine=%.2f, 差值=%.2f\n', ...
hierarchical_copula.aic, rvine_model.aic, comparison.aic_diff);
fprintf(' BIC比较: 分层Copula=%.2f, R-Vine=%.2f, 差值=%.2f\n', ...
comparison.bic_hier, comparison.bic_rvine, comparison.bic_diff);
fprintf(' 似然比检验: χ²=%f, p-value=%f, %s\n', ...
lr_stat, p_value, comparison.lr_test.significant ? '显著' : '不显著');
end
function cv_error = compare_predictive_ability(hierarchical_copula, rvine_model, data, params)
% 比较预测能力(交叉验证)
n_folds = 5;
n_obs = size(data.uniform, 1);
fold_size = floor(n_obs / n_folds);
cv_errors_hier = zeros(n_folds, 1);
cv_errors_rvine = zeros(n_folds, 1);
for fold = 1:n_folds
% 分割数据
test_idx = (fold-1)*fold_size+1 : min(fold*fold_size, n_obs);
train_idx = setdiff(1:n_obs, test_idx);
% 训练模型
hier_model = retrain_hierarchical_copula(data.uniform(train_idx, :), hierarchical_copula);
rvine_model_train = retrain_rvine_model(data.uniform(train_idx, :), rvine_model);
% 计算测试误差
test_data = data.uniform(test_idx, :);
cv_errors_hier(fold) = calculate_prediction_error(test_data, hier_model);
cv_errors_rvine(fold) = calculate_prediction_error(test_data, rvine_model_train);
end
cv_error = struct('hierarchical', mean(cv_errors_hier), 'rvine', mean(cv_errors_rvine), ...
'difference', mean(cv_errors_hier) - mean(cv_errors_rvine));
end
2.7 依赖结构分析:analyze_dependency_structure.m
function dependency_analysis = analyze_dependency_structure(rvine_model, params)
% 分析依赖结构
fprintf(' 依赖结构分析...\n');
% 提取Pair-Copula参数
pair_copulas = rvine_model.pair_copulas;
fields = fieldnames(pair_copulas);
% 计算依赖度量
dependency_measures = struct();
for i = 1:length(fields)
field = fields{i};
copula_info = pair_copulas.(field);
% 计算Kendall's tau
tau = calculate_kendalls_tau(copula_info.family, copula_info.params);
% 计算尾部依赖系数
lower_tail = calculate_lower_tail_dependence(copula_info.family, copula_info.params);
upper_tail = calculate_upper_tail_dependence(copula_info.family, copula_info.params);
dependency_measures.(field) = struct('tau', tau, 'lower_tail', lower_tail, ...
'upper_tail', upper_tail, 'family', copula_info.family);
end
% 分析整体依赖结构
dependency_analysis = struct();
dependency_analysis.pair_copulas = dependency_measures;
dependency_analysis.overall_tau = calculate_overall_kendalls_tau(dependency_measures);
dependency_analysis.tail_dependence = analyze_tail_dependence(dependency_measures);
dependency_analysis.dependency_clusters = identify_dependency_clusters(dependency_measures, params);
fprintf(' 平均Kendall''s tau: %.4f\n', dependency_analysis.overall_tau);
fprintf(' 尾部依赖分析完成\n');
end
function tau = calculate_kendalls_tau(family, params)
% 计算Kendall's tau
switch lower(family)
case 'gaussian'
rho = params.rho(1, 2);
tau = 2 * asin(rho) / pi;
case 't'
rho = params.rho(1, 2);
tau = 2 * asin(rho) / pi;
case 'clayton'
alpha = params.alpha;
tau = alpha / (alpha + 2);
case 'gumbel'
alpha = params.alpha;
tau = 1 - 1/alpha;
case 'frank'
alpha = params.alpha;
% Frank Copula的tau需要数值积分
tau = 1 - 4/alpha * (1 - (1-alpha)*exp(-alpha)/(1-exp(-alpha))/alpha);
otherwise
tau = 0.5; % 默认值
end
end
function lower_tail = calculate_lower_tail_dependence(family, params)
% 计算下尾依赖系数
switch lower(family)
case 'clayton'
alpha = params.alpha;
lower_tail = 2^(-1/alpha);
case 'gumbel'
lower_tail = 0; % Gumbel没有下尾依赖
case 'frank'
lower_tail = 0; % Frank没有下尾依赖
otherwise
lower_tail = 0;
end
end
function upper_tail = calculate_upper_tail_dependence(family, params)
% 计算上尾依赖系数
switch lower(family)
case 'clayton'
upper_tail = 0; % Clayton没有上尾依赖
case 'gumbel'
alpha = params.alpha;
upper_tail = 2 - 2^(1/alpha);
case 'frank'
upper_tail = 0; % Frank没有上尾依赖
otherwise
upper_tail = 0;
end
end
2.8 风险度量计算:calculate_risk_measures.m
function risk_measures = calculate_risk_measures(hierarchical_copula, rvine_model, params)
% 计算风险度量
fprintf(' 风险度量计算...\n');
% 使用R-Vine模型进行蒙特卡洛模拟
n_simulations = params.n_simulations;
n_vars = size(rvine_model.structure.trees{1}, 2); % 变量数量
% 生成模拟样本
simulated_samples = simulate_rvine_samples(rvine_model, n_simulations, params);
% 计算投资组合收益(等权重)
portfolio_weights = ones(1, n_vars) / n_vars;
portfolio_returns = simulated_samples * portfolio_weights';
% 计算VaR和ES
alpha = 1 - params.confidence_level;
var = quantile(portfolio_returns, alpha);
es = mean(portfolio_returns(portfolio_returns <= var));
% 计算其他风险度量
risk_measures = struct();
risk_measures.var = var;
risk_measures.es = es;
risk_measures.std = std(portfolio_returns);
risk_measures.skewness = skewness(portfolio_returns);
risk_measures.kurtosis = kurtosis(portfolio_returns);
% 计算边际风险贡献
marginal_var_contrib = zeros(1, n_vars);
for i = 1:n_vars
partial_portfolio = portfolio_returns - simulated_samples(:, i) * portfolio_weights(i);
partial_var = quantile(partial_portfolio, alpha);
marginal_var_contrib(i) = (var - partial_var) * portfolio_weights(i);
end
risk_measures.marginal_var_contribution = marginal_var_contrib;
fprintf(' VaR(%.0f%%): %.4f\n', params.confidence_level*100, var);
fprintf(' ES(%.0f%%): %.4f\n', params.confidence_level*100, es);
fprintf(' 波动率: %.4f\n', risk_measures.std);
end
function simulated_samples = simulate_rvine_samples(rvine_model, n_simulations, params)
% 使用R-Vine模型生成模拟样本
n_vars = size(rvine_model.structure.trees{1}, 2);
simulated_samples = zeros(n_simulations, n_vars);
% 使用逆变换采样
for sim = 1:n_simulations
% 生成独立均匀分布样本
u = rand(1, n_vars);
% 通过R-Vine结构转换
for tree_idx = 1:rvine_model.structure.n_trees
tree_edges = rvine_model.structure.trees{tree_idx};
n_edges = size(tree_edges, 1);
for edge_idx = 1:n_edges
edge_name = sprintf('tree%d_edge%d_%d_%d', tree_idx, edge_idx, ...
tree_edges(edge_idx, 1), tree_edges(edge_idx, 2));
if isfield(rvine_model.pair_copulas, edge_name)
copula_info = rvine_model.pair_copulas.(edge_name);
% 应用Pair-Copula变换
u = apply_pair_copula_transform(u, copula_info, params);
end
end
end
simulated_samples(sim, :) = u;
end
end
2.9 结果可视化:visualize_copula_results.m
function visualize_copula_results(hierarchical_copula, rvine_model, dependency_analysis, risk_measures, params)
% 可视化Copula结果
figure('Name', '分层Copula与Pair-Copula分析结果', 'Color', 'white', 'Position', [100, 100, 1600, 1000]);
% 1. 分层结构图
subplot(3,4,1);
visualize_hierarchy(hierarchical_copula.hierarchy);
title('分层Copula结构');
% 2. R-Vine结构图
subplot(3,4,2);
visualize_rvine_structure(rvine_model.structure);
title('R-Vine结构');
% 3. 依赖矩阵热图
subplot(3,4,3);
dependency_matrix = extract_dependency_matrix(dependency_analysis);
imagesc(dependency_matrix);
colormap('hot');
colorbar;
title('依赖强度矩阵');
xlabel('变量索引');
ylabel('变量索引');
% 4. 尾部依赖分析
subplot(3,4,4);
tail_dependence = extract_tail_dependence(dependency_analysis);
bar(1:length(tail_dependence), tail_dependence, 'FaceColor', 'red');
xlabel('Pair-Copula索引');
ylabel('尾部依赖系数');
title('尾部依赖分析');
grid on;
% 5. 模型比较
subplot(3,4,5);
model_names = {'分层Copula', 'R-Vine'};
aic_values = [hierarchical_copula.aic, rvine_model.aic];
bic_values = [hierarchical_copula.aic + 2*count_parameters(hierarchical_copula.parameters)*log(params.n_samples), ...
rvine_model.aic + 2*count_rvine_parameters(rvine_model.pair_copulas)*log(params.n_samples)];
yyaxis left;
plot(1:2, aic_values, 'b-o', 'LineWidth', 2, 'MarkerSize', 8);
ylabel('AIC');
yyaxis right;
plot(1:2, bic_values, 'r-s', 'LineWidth', 2, 'MarkerSize', 8);
ylabel('BIC');
set(gca, 'XTick', 1:2, 'XTickLabel', model_names);
title('模型比较 (AIC/BIC)');
grid on;
% 6. 风险度量仪表板
subplot(3,4,6);
gauge_chart(risk_measures.var, 'VaR', params.confidence_level*100);
title('VaR风险值');
subplot(3,4,7);
gauge_chart(risk_measures.es, 'ES', params.confidence_level*100);
title('ES期望损失');
subplot(3,4,8);
gauge_chart(risk_measures.std, '波动率', 0.3);
title('投资组合波动率');
% 7. 边际风险贡献
subplot(3,4,9);
marginal_contrib = risk_measures.marginal_var_contribution;
barh(1:length(marginal_contrib), marginal_contrib, 'FaceColor', 'cyan');
xlabel('边际VaR贡献');
ylabel('资产索引');
title('边际风险贡献');
grid on;
% 8. 模拟收益分布
subplot(3,4,10);
% 生成模拟样本(简化)
n_sim = 10000;
simulated_returns = randn(n_sim, 1) * risk_measures.std + mean(risk_measures.var);
histogram(simulated_returns, 50, 'FaceColor', 'green', 'EdgeColor', 'black');
xlabel('投资组合收益');
ylabel('频数');
title('模拟收益分布');
grid on;
% 9. 依赖结构网络图
subplot(3,4,11);
plot_dependency_network(dependency_analysis, params);
title('依赖结构网络');
% 10. 参数信息
subplot(3,4,12); axis off;
param_text = {
sprintf('变量维度: %d', params.dim)
sprintf('样本数量: %d', params.n_samples)
sprintf('分层类型: %s', params.hierarchy_type)
sprintf('Pair-Copula类型: %s', params.paircopula_type)
sprintf('置信水平: %.0f%%', params.confidence_level*100)
sprintf('模拟次数: %d', params.n_simulations)
sprintf('分层CopulaAIC: %.2f', hierarchical_copula.aic)
sprintf('R-Vine AIC: %.2f', rvine_model.aic)
};
text(0.1, 0.9, 'Copula系统参数:', 'FontSize', 12, 'FontWeight', 'bold');
for i = 1:length(param_text)
text(0.1, 0.9 - i*0.1, param_text{i}, 'FontSize', 10);
end
title('系统配置信息');
end
%% 可视化辅助函数
function visualize_hierarchy(hierarchy)
% 可视化分层结构
if iscell(hierarchy.levels{1})
n_levels = length(hierarchy.levels);
for level = 1:n_levels
nodes = hierarchy.levels{level};
y_pos = n_levels - level + 1;
if iscell(nodes)
for node_idx = 1:length(nodes)
node = nodes{node_idx};
if isvector(node)
x_positions = node;
plot(x_positions, y_pos * ones(size(x_positions)), 'bo', 'MarkerSize', 8, 'MarkerFaceColor', 'b');
hold on;
end
end
else
x_positions = nodes;
plot(x_positions, y_pos * ones(size(x_positions)), 'bo', 'MarkerSize', 8, 'MarkerFaceColor', 'b');
hold on;
end
end
end
xlabel('变量索引');
ylabel('层级');
axis tight;
grid on;
end
function visualize_rvine_structure(vine_structure)
% 可视化R-Vine结构
n_trees = vine_structure.n_trees;
for tree_idx = 1:n_trees
tree_edges = vine_structure.trees{tree_idx};
y_pos = n_trees - tree_idx + 1;
for edge_idx = 1:size(tree_edges, 1)
u = tree_edges(edge_idx, 1);
v = tree_edges(edge_idx, 2);
plot([u, v], [y_pos, y_pos], 'r-', 'LineWidth', 2);
hold on;
plot(u, y_pos, 'ro', 'MarkerSize', 6, 'MarkerFaceColor', 'r');
plot(v, y_pos, 'ro', 'MarkerSize', 6, 'MarkerFaceColor', 'r');
end
end
xlabel('变量索引');
ylabel('树层级');
axis tight;
grid on;
end
function gauge_chart(value, label, max_value)
% 绘制仪表盘
theta = linspace(0, pi, 100);
r = 1;
x = r * cos(theta);
y = r * sin(theta);
fill(x, y, [0.9, 0.9, 0.9], 'EdgeColor', 'black');
hold on;
% 指针
pointer_angle = pi * (value / max_value);
pointer_x = [0, 0.8 * cos(pointer_angle)];
pointer_y = [0, 0.8 * sin(pointer_angle)];
plot(pointer_x, pointer_y, 'r-', 'LineWidth', 3);
% 中心圆
rectangle('Position', [-0.1, -0.1, 0.2, 0.2], 'Curvature', [1, 1], 'FaceColor', 'red');
axis equal;
axis off;
title(sprintf('%s\n%.4f', label, value));
end
三、扩展功能模块
3.1 动态Copula模型
function dynamic_copula = build_dynamic_copula(data, params)
% 构建动态Copula模型(时变参数)
% 滑动窗口估计
window_size = 250; % 1年交易日
n_obs = size(data.uniform, 1);
dynamic_params = cell(n_obs - window_size + 1, 1);
for t = window_size:n_obs
window_data = data.uniform(t-window_size+1:t, :);
% 估计时变Copula参数
tv_params = estimate_time_varying_parameters(window_data, params);
dynamic_params{t-window_size+1} = tv_params;
end
dynamic_copula = struct('window_size', window_size, 'parameters', dynamic_params);
end
3.2 极值Copula(Extreme Value Copula)
function ev_copula = build_extreme_value_copula(data, params)
% 构建极值Copula(用于极端风险建模)
% 提取极端事件(尾部数据)
alpha = 0.05; % 极端事件阈值
extreme_data = extract_extreme_events(data.uniform, alpha);
% 估计极值Copula参数
ev_families = {'galambos', 'husler-reiss', 't-ev'};
best_ev_family = select_ev_copula_family(extreme_data, ev_families);
% 估计参数
ev_params = estimate_ev_copula_parameters(extreme_data, best_ev_family);
ev_copula = struct('family', best_ev_family, 'parameters', ev_params, ...
'threshold', alpha, 'extreme_data', extreme_data);
end
参考代码 分层copula paircopula的计算 www.youwenfan.com/contentcsu/60175.html
四、建议
4.1 模型选择
| 场景 | 推荐模型 | 理由 |
|---|---|---|
| 高维数据(>10) | R-Vine | 灵活性高,能捕捉复杂依赖 |
| 分层结构明显 | 分层Copula | 解释性强,计算效率高 |
| 尾部风险重要 | 极值Copula | 专门建模极端事件 |
| 实时应用 | 分层Copula | 计算速度快 |
4.2 参数估计
% 1. 使用稳健估计方法
params.optimization_method = 'itau'; % 秩相关估计,对异常值稳健
% 2. 正则化防止过拟合
lambda = 0.01; % L2正则化参数
% 3. 交叉验证选择模型
cv_errors = cross_validate_copula_models(data, params);
best_model = select_best_model(cv_errors);