skfolio.optimization.HierarchicalEqualRiskContribution#

class skfolio.optimization.HierarchicalEqualRiskContribution(risk_measure=Variance, prior_estimator=None, distance_estimator=None, hierarchical_clustering_estimator=None, min_weights=0.0, max_weights=1.0, solver='CLARABEL', solver_params=None, transaction_costs=0.0, management_fees=0.0, previous_weights=None, portfolio_params=None)[来源]#

层次等风险贡献估计器。

层级等风险贡献是一种投资组合优化方法,由托马斯·拉芬诺特开发 [2]

该算法使用距离矩阵计算层次聚类,采用层次树聚类算法。然后,对于每个聚类,它计算逆风险分配的总体聚类风险。

最后一步是对树状图进行自顶向下的递归分割,在此过程中,使用简单的风险平价方法在聚类内更新资产权重。

它通过利用树状图形状在自顶向下的递归划分过程中,而不是将其对半切分,从而与层级风险平价有所不同。

注意

默认的链接方法设置为Ward方差最小化算法,它比单链接方法更稳定,具有更好的属性 [4]

此外,初始论文没有提供处理权重约束的算法,目前没有标准解决方案。与HRP(层次风险平价)不同,在每个二分步骤中可以对拆分因子应用权重约束,HERC(层次平等风险贡献)在分配的中间步骤中无法纳入权重约束。因此,在HERC中,权重约束必须在自上而下的分配完成后执行。在skfolio中,我们最小化最终权重与初始权重的相对偏差。这被表述为一个凸优化问题:

\[\begin{split}\begin{cases} \begin{aligned} &\min_{w} & & \Vert \frac{w - w_{init}}{w_{init}} \Vert_{2}^{2} \\ &\text{s.t.} & & \sum_{i=1}^{N} w_{i} = 1 \\ & & & w_{min} \leq w_i \leq w_{max}, \quad \forall i \end{aligned} \end{cases}\end{split}\]

最小化相对偏差(而不是绝对偏差)的原因是我们希望限制对每个资产风险贡献的影响。由于HERC按风险的反比进行分配,基于相对偏差调整权重可以确保资产的风险贡献与初始分配保持比例一致。

Parameters:
risk_measureRiskMeasure or ExtraRiskMeasure, default=RiskMeasure.VARIANCE

RiskMeasureExtraRiskMeasure 的优化。 可以是以下任意一种:

  • 平均绝对偏差

  • 第一低阶部分矩

  • 方差

  • 半方差

  • CVAR

  • EVAR

  • 最差实现

  • CDAR

  • 最大回撤

  • 平均回撤

  • EDAR

  • 溃疡指数

  • GINI_MEAN_DIFFERENCE_RATIO

  • 风险价值

  • 风险下滑

  • 熵风险测量

  • 第四中心矩

  • 第四下部偏度矩

默认值是 RiskMeasure.VARIANCE

prior_estimatorBasePrior, optional

先验估计器. 先验估计器用于估计包含资产预期收益、协方差矩阵和收益估计的PriorModel。 矩时和收益估计用于风险计算,收益估计被距离矩阵估计器使用。 默认值(None)是使用EmpiricalPrior

distance_estimatorBaseDistance, optional

距离估计器。 距离估计器用于估计代码依赖性和计算连接矩阵所需的距离矩阵。 默认 (None) 是使用 PearsonDistance

hierarchical_clustering_estimatorHierarchicalClustering, optional

层次聚类估计器. 层次聚类估计器用于计算联系矩阵 以及基于距离矩阵的资产层次聚类。 默认(None)是使用 HierarchicalClustering

min_weightsfloat | dict[str, float] | array-like of shape (n_assets, ), default=0.0

最小资产权重(权重下限)。不允许负权重。 如果提供的是浮点数,则应用于每个资产。 如果提供的是字典,其(键/值)对必须是 (资产名称/资产最小权重),并且输入 Xfit 方法必须是 一个具有资产名称作为列的 DataFrame。 当使用字典时,未提供的资产值被分配最小权重 0.0。默认值为 0.0(不做空)。

示例:

  • min_weights = 0 –> 只做多的投资组合(不进行卖空)。

  • min_weights = None –> 没有下限(与 -np.Inf 相同)。

  • min_weights = {“SX5E”: 0, “SPX”: 0.1}

  • min_weights = [0, 0.1]

max_weightsfloat | dict[str, float] | array-like of shape (n_assets, ), default=1.0

最大资产权重(权重上限)。权重大于 1.0 的不被允许。如果提供的是一个浮动值,它将应用于每个资产。 如果提供的是一个字典,它的(键/值)对必须是(资产名称/资产最大权重),并且输入 Xfit 方法必须是一个包含资产名称的列的 DataFrame。 当使用字典时,未提供的资产值将被分配最低权重 1.0。 默认值是 1.0(每个资产均低于 100%)。

示例:

  • max_weights = 0 –> 没有多头头寸(仅做空投资组合)。

  • max_weights = 0.5 –> 每个权重必须低于50%。

  • max_weights = {“SX5E”: 1, “SPX”: 0.25}

  • max_weights = [1, 0.25]

transaction_costsfloat | dict[str, float] | array-like of shape (n_assets, ), default=0.0

资产的交易成本。它用于在优化问题中添加线性交易成本:

\[total\_cost = \sum_{i=1}^{N} c_{i} \times |w_{i} - w\_prev_{i}|\]

其中 \(c_{i}\) 是资产 i 的交易成本, \(w_{i}\) 是它的权重, \(w\_prev_{i}\) 是它的前一个权重(在 previous_weights 中定义)。浮动的 \(total\_cost\) 影响投资组合的预期收益,以进行优化:

\[expected\_return = \mu^{T} \cdot w - total\_cost\]

其中 \(\mu\) 是资产预期收益的向量,而 \(w\) 是资产权重的向量。

如果提供了一个浮动值,它将应用于每个资产。 如果提供了一个字典,它的(键/值)对必须是 (资产名称/资产成本),输入 Xfit 方法必须是一个包含资产名称的DataFrame。 默认值为 0.0

警告

根据上述公式,交易成本的周期性需要与\(\mu\)的周期性一致。例如,如果输入X每日收益组成,则transaction_costs需要以每日成本表示。 (请参见交易成本

management_feesfloat | dict[str, float] | array-like of shape (n_assets, ), default=0.0

资产的管理费用。它用于将线性管理费用添加到优化问题中:

\[total\_fee = \sum_{i=1}^{N} f_{i} \times w_{i}\]

其中 \(f_{i}\) 是资产 i 的管理费,\(w_{i}\) 是其权重。 浮动 \(total\_fee\) 正在影响投资组合的预期收益,在优化中:

\[expected\_return = \mu^{T} \cdot w - total\_fee\]

其中 \(\mu\) 是资产预期收益的向量,\(w\) 是资产权重的向量。

如果提供了浮点数,它将应用于每个资产。 如果提供了字典,则其(键/值)对必须是 (资产名称/资产费用),并且输入 Xfit 方法必须是包含资产名称的列的 DataFrame。 默认值为 0.0

警告

根据上述公式,管理费用的周期性需要与\(\mu\)的周期性一致。例如,如果输入的X日常收益组成,则management_fees需要以日常费用的形式表示。

注意

另一种方法是直接对输入 X 影响管理费用,以表示扣除费用后的回报。然而,当使用例如收缩估计量来估计 \(\mu\) 参数时,这种方法会将一个确定值与一个不确定值混合,从而导致管理费用中的不必要偏差。

previous_weightsfloat | dict[str, float] | array-like of shape (n_assets, ), optional

资产的先前权重。先前权重用于计算投资组合的总成本。如果提供一个浮动值,它将应用于每个资产。如果提供一个字典,其(键/值)对必须是(资产名称/资产先前权重),并且 X 的输入 fit 方法必须是一个包含资产名称的 DataFrame 列。默认值 (None) 表示没有先前权重。

portfolio_paramsdict, optional

传递给通过 predictscore 方法评估的投资组合的投资组合参数。如果未提供,nametransaction_costsmanagement_feesprevious_weightsrisk_free_rate 将从优化模型中复制并传递给投资组合。

solverstr, default=”CLARABEL”

用于权重约束优化的求解器。默认值是“CLARABEL”,它是用Rust编写的,具有比ECOS和SCS更好的数值稳定性和性能。有关可用求解器的更多详细信息,请查看CVXPY文档:https://www.cvxpy.org/tutorial/advanced/index.html#choosing-a-solver

solver_paramsdict, optional

求解器参数。例如,solver_params=dict(verbose=True)。 默认值 (None) 是使用CVXPY的默认值。 有关求解器参数的更多详细信息,请查看CVXPY文档: https://www.cvxpy.org/tutorial/advanced/index.html#setting-solver-options

Attributes:
weights_ndarray of shape (n_assets,)

资产的权重。

distance_estimator_BaseDistance

拟合的 distance_estimator

hierarchical_clustering_estimator_HierarchicalClustering

拟合 hierarchical_clustering_estimator

n_features_in_int

fit期间看到的资产数量。

feature_names_in_ndarray of shape (n_features_in_,)

fit期间看到的资产名称。只有当X具有所有为字符串的资产名称时才定义。

参考文献

[1]

“基于层次聚类的资产配置”, 投资组合管理杂志, 托马斯·拉菲诺 (2017).

[2]

“层次化的平等风险贡献投资组合”, 托马斯·拉菲诺(2018年)。

[3]

“应用二阶差分于间隙统计”。 Yue, Wang & Wei (2009).

[4]

“对金融市场中相关性、层级、网络和聚类的二十年回顾”, Gautier Marti, Frank Nielsen, Mikołaj Bińkowski, Philippe Donnat (2020).

方法

fit(X[, y])

拟合层次等风险贡献估计器。

fit_predict(X)

X 执行 fit 操作,并返回基于拟合的 weightsPortfolioPopulation 的预测结果。

get_metadata_routing()

获取此对象的元数据路由。

get_params([deep])

获取此估计器的参数。

predict(X)

根据拟合的权重预测PortfolioPopulationX上的Portfolio

score(X[, y])

预测分数。

set_params(**params)

设置此估计器的参数。

fit(X, y=None, **fit_params)[来源]#

拟合层次等风险贡献估计器。

Parameters:
Xarray-like of shape (n_observations, n_assets)

资产的价格收益。

yIgnored

未使用,按照约定为API一致性而存在。

**fit_paramsdict

传递给基础估计器的参数。只有在 enable_metadata_routing=True 的情况下可用,您可以通过使用 sklearn.set_config(enable_metadata_routing=True) 来设置。详情请参见 元数据路由用户指南

Returns:
selfHierarchicalEqualRiskContribution

拟合的估计器。

fit_predict(X)#

X执行fit并根据拟合的weights返回预测的PortfolioPopulationPortfolioX上的值。对于因子模型,分别使用fit(X, y)然后predict(X)

Parameters:
Xarray-like of shape (n_observations, n_assets)

资产的价格收益。

Returns:
predictionPortfolio | Population

基于拟合的 weights 估计的 PortfolioPopulationPortfolioX 上。

get_metadata_routing()#

获取这个对象的元数据路由。

请查看 用户指南 了解路由机制是如何工作的。

Returns:
routingMetadataRequest

一个 MetadataRequest 封装路由信息。

get_params(deep=True)#

获取此估计器的参数。

Parameters:
deepbool, default=True

如果为真,将返回此估计器及其包含的子对象的参数,这些子对象也是估计器。

Returns:
paramsdict

参数名称映射到它们的值。

predict(X)#

根据拟合的权重预测PortfolioPopulationX上的Portfolio

优化估计器可以返回一个一维或二维数组的 weights。对于一维数组,预测返回一个 Portfolio。对于二维数组,预测返回一个 PopulationPortfolio

如果 name 在投资组合参数中没有提供,我们将使用估计器名称的前 500 个字符。

Parameters:
Xarray-like of shape (n_observations, n_assets)

资产的价格收益。

Returns:
predictionPortfolio | Population

基于拟合的 weights 估计的 PortfolioPopulationPortfolioX 上。

score(X, y=None)#

预测分数。 如果预测是单个 Portfolio,则分数是夏普比率。 如果预测是一组 PopulationPortfolio,则分数是该组中所有投资组合夏普比率的平均值。

Parameters:
Xarray-like of shape (n_observations, n_assets)

资产的价格收益。

yIgnored

未使用,仅为了遵循API一致性而存在。

Returns:
scorefloat

如果预测是单个 Portfolio,则投资组合的夏普比率为;如果预测是 PortfolioPopulation 的所有投资组合夏普比率的平均值。

set_params(**params)#

设置该估计器的参数。

该方法适用于简单估计器以及嵌套对象(如 Pipeline)。后者具有 <component>__<parameter> 形式的参数,因此可以更新嵌套对象的每个组件。

Parameters:
**paramsdict

估计器参数。

Returns:
selfestimator instance

估计器实例。