skfolio.optimization.ConvexOptimization#

class skfolio.optimization.ConvexOptimization(risk_measure=Variance, prior_estimator=None, min_weights=0.0, max_weights=1.0, budget=1.0, min_budget=None, max_budget=None, max_short=None, max_long=None, cardinality=None, group_cardinalities=None, threshold_long=None, threshold_short=None, transaction_costs=0.0, management_fees=0.0, previous_weights=None, groups=None, linear_constraints=None, left_inequality=None, right_inequality=None, l1_coef=0.0, l2_coef=0.0, mu_uncertainty_set_estimator=None, covariance_uncertainty_set_estimator=None, risk_free_rate=0.0, min_acceptable_return=None, cvar_beta=0.95, evar_beta=0.95, cdar_beta=0.95, edar_beta=0.95, solver='CLARABEL', solver_params=None, scale_objective=None, scale_constraints=None, save_problem=False, raise_on_failure=True, add_objective=None, add_constraints=None, overwrite_expected_return=None, portfolio_params=None)[来源]#

skfolio 中所有凸优化估计器的基类。

所有具有凸性公式的风险度量在类方法中定义,命名规范为: _{risk_measure}_risk。该命名规范用于动态查找。

在多个风险度量之间共享的CVX表达式被缓存到一个名为 _cvx_cache 的字典中。这是为了避免CVX表达式的重复并提高性能和收敛性。

Parameters:
risk_measureRiskMeasure, default=RiskMeasure.VARIANCE

RiskMeasure 的优化。 可以是以下任意内容:

  • 方差

  • 半方差

  • 标准差

  • 半偏差

  • 平均绝对偏差

  • 第一低阶部分矩

  • CVAR

  • EVAR

  • 最差实现

  • CDAR

  • 最大回撤

  • 平均回撤

  • EDAR

  • 溃疡指数

  • GINI_MEAN_DIFFERENCE_RATIO

默认值是 RiskMeasure.VARIANCE

prior_estimatorBasePrior, optional

先验估计器. 先验估计器用于估计PriorModel 包含资产预期收益、协方差矩阵、收益和协方差的Cholesky分解的估计。 默认值(None)是使用EmpiricalPrior

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

最小资产权重(权重下限)。 如果提供了浮动值,则应用于每个资产。 None 等价于 -np.Inf (没有下限)。 如果提供了字典,其(键/值)对必须是 (资产名称/资产最小权重),输入 Xfit 方法必须是一个包含资产名称的 DataFrame。 当使用字典时,未提供的资产值将被分配最小权重 0.0。 默认值是 0.0 (不允许做空)。

示例:

  • min_weights = 0 –> 仅限于多头投资组合(不进行卖空)。

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

  • min_weights = -2 –> 每个权重必须高于 -200%。

  • min_weights = {"SX5E": 0, "SPX": -2}

  • min_weights = [0, -2]

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

最大资产权重(权重上限)。
如果提供一个浮点数,它会应用于每个资产。None 相当于 +np.Inf(没有上限)。
如果提供一个字典,它的(键/值)对必须是(资产名称/资产最大权重),而输入 Xfit 方法必须是一个包含资产名称的列的 DataFrame。
当使用字典时,未提供的资产值被分配最小权重 1.0
默认值是 1.0(每个资产低于 100%。)

示例:

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

  • max_weights = None –> 没有上限。

  • max_weights = 2 –> 每个权重必须低于200%。

  • max_weights = {"SX5E": 1, "SPX": 2}

  • max_weights = [1, 2]

budgetfloat | None, default=1.0

投资预算。它是多头和空头头寸的总和(所有权重的总和)。 None 意味着没有预算限制。 默认值是 1.0 (完全投资的投资组合)。

示例:

  • budget = 1 –> 完全投资组合。

  • budget = 0 –> 市场中性投资组合。

  • budget = None –> 对权重之和没有限制。

min_budgetfloat, optional

最低预算。它是多头和空头头寸总和的下限 (所有权重的总和)。如果提供,您必须设置 budget=None。 默认值 (None) 意味着没有最低预算限制。

max_budgetfloat, optional

最大预算。它是多头和空头头寸之和的上限(所有权重之和)。如果提供,您必须设置 budget=None。默认值 (None) 意味着没有最大预算约束。

max_shortfloat, optional

最大空头头寸。空头头寸定义为负权重的总和(按绝对值计算)。 默认值(None)表示没有最大空头头寸。

max_longfloat, optional

最大多头头寸。多头头寸被定义为正权重的总和。 默认值(None)表示没有最大多头头寸。

cardinalityint, optional

指定基数约束以限制投资资产的数量(非零权重)。此功能需要混合整数求解器。对于开源选项,我们建议使用SCIP,通过设置 solver="SCIP" 来实现。要安装它,请使用: pip install cvxpy[SCIP]。对于商业求解器,支持的选项包括MOSEK、GUROBI或CPLEX。

group_cardinalitiesdict[str, int], optional

一个字典,用于指定特定资产组的基数约束。 键代表组名(字符串),值指定每组允许的最大资产数量。您必须使用 groups 参数提供组。这需要一个混合整数求解器(有关详细信息,请参见 cardinality )。

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

指定了资产在投资组合中被视为长仓的最低权重阈值。权重低于该阈值的资产将不被视为投资组合的长仓部分。这个约束可以帮助消除不重要的配置。这需要一个混合整数求解器(有关更多详细信息,请参见 cardinality)。它遵循与 min_weightsmax_weights 相同的格式。

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

指定投资组合中资产被视为短期头寸的最大权重阈值。权重超过该阈值的资产将不被包含在投资组合的短期头寸中。此约束可以帮助控制短期头寸的规模。这需要一个混合整数求解器(有关更多细节,请参见 cardinality)。它遵循与 min_weightsmax_weights 相同的格式。

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

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

l1_coeffloat, default=0.0

L1 正则化系数。 它用于通过 L1 范数惩罚目标函数:

\[l1\_coef \times \Vert w \Vert_{1} = l1\_coef \times \sum_{i=1}^{N} |w_{i}|\]

增加这个系数将减少非零权重的数量(基数)。这倾向于增加鲁棒性(样本外稳定性),但会减少多样化。默认值是 0.0

l2_coeffloat, default=0.0

L2正则化系数。 它用于通过L2范数对目标函数进行惩罚:

\[l2\_coef \times \Vert w \Vert_{2}^{2} = l2\_coef \times \sum_{i=1}^{N} w_{i}^2\]

它倾向于增加稳健性(样本外稳定性)。
默认值是 0.0

mu_uncertainty_set_estimatorBaseMuUncertaintySet, optional

Mu 不确定集估计器。 如果提供,资产的预期收益将使用椭圆形不确定集进行建模。这被称为最坏情况优化,是一种鲁棒优化的类别。它减少了由于预期收益估计错误而产生的不稳定性。最坏情况下投资组合的预期收益为:

\[w^T\hat{\mu} - \kappa_{\mu}\lVert S_{\mu}^\frac{1}{2}w\rVert_{2}\]

通过 \(\kappa\) 表示椭球体的大小(置信区域)和 \(S\) 表示其形状。 默认为 (None),这意味着没有使用不确定性集。

covariance_uncertainty_set_estimatorBaseCovarianceUncertaintySet, optional

协方差不确定性集合估计器。 如果提供,资产协方差矩阵将使用椭球不确定性集合建模。这被称为最坏情况优化,是一种稳健优化的类。它减少了由于协方差矩阵估计误差而导致的不稳定性。 默认值(None)表示不使用不确定性集合。

linear_constraintsarray-like of shape (n_constraints,), optional

线性约束。 线性约束必须符合以下任意模式:

  • “2.5 * ref1 + 0.10 * ref2 + 0.0013 <= 2.5 * ref3”

  • “ref1 >= 2.9 * ref2”

  • “ref1 == ref2”

  • “ref1 >= ref1”

通过“ref1”、“ref2”……在参数 groups 中提供的资产名称或组名称。 如果输入 Xfit 方法是一个具有这些资产名称的列的 DataFrame,则可以不需要 groups 来引用资产名称。

示例:

  • “SPX >= 0.10” –> SPX 权重必须大于 10% (请注意,您也可以使用 min_weights)

  • “SX5E + TLT >= 0.2” –> SX5E和TLT权重的总和必须大于20%

  • “US == 0.7” –> 所有美国权重的总和必须等于70%

  • “股权 == 3 * 债券” –> 所有股权权重的总和必须等于所有债券权重的总和的3倍。

  • “2*SPX + 3*Europe <= Bond + 0.05” –> 混合资产和组约束

groupsdict[str, list[str]] or array-like of shape (n_groups, n_assets), optional

linear_constraints中引用的资产组。如果提供了字典,则其(键/值)对必须是(资产名称/资产组),并且fit方法的输入X必须是一个数据框,其中列包含资产名称。

示例:

  • groups = {“SX5E”: [“股票”, “欧洲”], “SPX”: [“股票”, “美国”], “TLT”: [“债券”, “美国”]}

  • groups = [[“股权”, “股权”, “债券”], [“欧洲”, “美国”, “美国”]]

left_inequalityarray-like of shape (n_constraints, n_assets), optional

线性约束的左侧不等式矩阵 \(A\) \(A \cdot w \leq b\)

right_inequalityarray-like of shape (n_constraints, ), optional

线性约束的右侧不等式向量 \(b\) \(A \cdot w \leq b\)

risk_free_ratefloat, default=0.0

无风险利率。 默认值为 0.0

min_acceptable_returnfloat, optional

用于区分“下行”和“上行”收益以计算下部偏差矩的最低可接受回报:

  • 首个下部分矩

  • 半方差

  • 半偏差

默认值 (None) 是使用平均值。

cvar_betafloat, default=0.95

CVaR(条件风险价值)置信水平。
默认值为 0.95

evar_betafloat, default=0

EVaR(熵值风险)置信水平。
默认值为 0.95

cdar_betafloat, default=0.95

CDaR(条件下跌风险)置信水平。
默认值为 0.95

edar_betafloat, default=0.95

EDaR(风险下跌的熵)置信水平。 默认值是 0.95

add_objectiveCallable[[cp.Variable], cp.Expression], optional

向现有目标表达式添加自定义目标。 它是一个必须以权重 w 作为参数并返回 CVXPY 表达式的函数。

add_constraintsCallable[[cp.Variable], cp.Expression|list[cp.Expression]], optional

向现有约束添加自定义约束或约束列表。 它是一个必须以权重 w 作为参数的函数,并返回一个 CVPXY 表达式或一个 CVPXY 表达式的列表。

overwrite_expected_returnCallable[[cp.Variable], cp.Expression], optional

用自定义表达式覆盖预期的回报 \(\mu \cdot w\)。 它是一个必须以权重 w 作为参数的函数,并返回一个 CVPXY 表达式。

solverstr, default=”CLARABEL”

要使用的求解器。默认是“CLARABEL”,它是用Rust编写的,具有比ECOS和SCS更好的数值稳定性和性能。Cvxpy将在未来版本中将其默认求解器“ECOS”替换为“CLARABEL”。有关可用求解器的更多详细信息,请查阅CVXPY文档:https://www.cvxpy.org/tutorial/advanced/index.html#choosing-a-solver

solver_paramsdict, optional

求解器参数。例如,solver_params=dict(verbose=True)。默认值 (None) 是使用 {"tol_gap_abs": 1e-9, "tol_gap_rel": 1e-9} 对于求解器“CLARABEL”,其他情况下使用CVXPY默认值。有关求解器参数的更多详细信息,请查看 CVXPY 文档:https://www.cvxpy.org/tutorial/solvers

scale_objectivefloat, optional

通过此值缩放每个目标元素。
它可以用于在特定情况下提高优化精度。
默认值(None)根据问题设置。

scale_constraintsfloat, optional

通过此值缩放每个约束元素。 它可以在特定情况下用于提高优化精度。 默认值(None)根据问题设置。

save_problembool, default=False

如果将此设置为 True,CVXPY 问题将保存在 problem_ 中。 默认值为 False

raise_on_failurebool, default=True

如果将此设置为 True,当优化失败时会引发错误,否则会以警告形式通过。

portfolio_paramsdict, optional

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

Attributes:
weights_ndarray of shape (n_assets,) or (n_optimizations, n_assets)

资产的权重。

problem_values_dict[str, float] | list[dict[str, float]] of size n_optimizations

从CVXPY问题中检索的表达式值。

prior_estimator_BasePrior

调整过的 prior_estimator.

mu_uncertainty_set_estimator_BaseMuUncertaintySet

如果提供,拟合 mu_uncertainty_set_estimator

covariance_uncertainty_set_estimator_BaseCovarianceUncertaintySet

如果提供了 covariance_uncertainty_set_estimator

problem_: cvxpy.Problem

用于优化的CVXPY问题。只有当 save_problem 被设置为 True 时。

方法

fit_predict(X)

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

get_metadata_routing()

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

get_params([deep])

获取此估计器的参数。

predict(X)

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

score(X[, y])

预测分数。

set_params(**params)

设置此估计器的参数。

适应

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

估计器实例。