From 88f283a5db89aaef38ae2b8c9ea7882d5331c22a Mon Sep 17 00:00:00 2001 From: Riskfolio Date: Sat, 6 Jan 2024 12:45:35 -0500 Subject: [PATCH] Update Solvers RLVaR Use CLARABEL as default solver for RLVaR and RLDaR --- ...rial 38 - Mean Kurtosis Optimization.ipynb | 3 +- ...39 - Mean Semi Kurtosis Optimization.ipynb | 4 +- riskfolio/src/HCPortfolio.py | 6 +-- riskfolio/src/OwaWeights.py | 4 +- riskfolio/src/PlotFunctions.py | 26 +++++------ riskfolio/src/Portfolio.py | 13 ++++-- riskfolio/src/Reports.py | 8 ++-- riskfolio/src/RiskFunctions.py | 44 +++++++++---------- 8 files changed, 57 insertions(+), 51 deletions(-) diff --git a/examples/Tutorial 38 - Mean Kurtosis Optimization.ipynb b/examples/Tutorial 38 - Mean Kurtosis Optimization.ipynb index 9822b734..b2301ae3 100644 --- a/examples/Tutorial 38 - Mean Kurtosis Optimization.ipynb +++ b/examples/Tutorial 38 - Mean Kurtosis Optimization.ipynb @@ -434,8 +434,7 @@ " method_kurt=method_kurt,\n", " )\n", "\n", - "port.solvers = ['MOSEK'] # It is recommended to use mosek when optimizing GMD\n", - "port.sol_params = {'MOSEK': {'mosek_params': {'MSK_IPAR_NUM_THREADS': 2}}}\n", + "port.solvers = ['CLARABEL'] # It is recommended to use mosek when optimizing GMD\n", "\n", "# Estimate optimal portfolio:\n", "model ='Classic' # Could be Classic (historical), BL (Black Litterman) or FM (Factor Model)\n", diff --git a/examples/Tutorial 39 - Mean Semi Kurtosis Optimization.ipynb b/examples/Tutorial 39 - Mean Semi Kurtosis Optimization.ipynb index d65c727d..877eaa99 100644 --- a/examples/Tutorial 39 - Mean Semi Kurtosis Optimization.ipynb +++ b/examples/Tutorial 39 - Mean Semi Kurtosis Optimization.ipynb @@ -436,8 +436,8 @@ "\n", "# Estimate optimal portfolio:\n", "\n", - "port.solvers = ['MOSEK'] # It is recommended to use mosek when optimizing GMD\n", - "port.sol_params = {'MOSEK': {'mosek_params': {'MSK_IPAR_NUM_THREADS': 2}}}\n", + "port.solvers = ['CLARABEL'] # It is recommended to use mosek when optimizing GMD\n", + "#port.sol_params = {'MOSEK': {'mosek_params': {'MSK_IPAR_NUM_THREADS': 2}}}\n", "\n", "model ='Classic' # Could be Classic (historical), BL (Black Litterman) or FM (Factor Model)\n", "rm = 'SKT' # Risk measure used, this time will be Tail Gini Range\n", diff --git a/riskfolio/src/HCPortfolio.py b/riskfolio/src/HCPortfolio.py index f3f82115..2f311c13 100644 --- a/riskfolio/src/HCPortfolio.py +++ b/riskfolio/src/HCPortfolio.py @@ -51,7 +51,7 @@ class HCPortfolio(object): The default value is None. solvers: list, optional List of solvers available for CVXPY used for the selected NCO method. - The default value is None. + The default value is ['CLARABEL', 'SCS', 'ECOS']. w_max : pd.Series or float, optional Upper bound constraint for hierarchical risk parity weights :cite:`c-Pfitzinger`. w_min : pd.Series or float, optional @@ -79,8 +79,8 @@ def __init__( beta=None, b_sim=None, kappa=0.30, - solver_rl=None, - solvers=None, + solver_rl='CLARABEL', + solvers=['CLARABEL', 'SCS', 'ECOS'], w_max=None, w_min=None, alpha_tail=0.05, diff --git a/riskfolio/src/OwaWeights.py b/riskfolio/src/OwaWeights.py index 577a772a..066d2dbd 100644 --- a/riskfolio/src/OwaWeights.py +++ b/riskfolio/src/OwaWeights.py @@ -306,7 +306,7 @@ def owa_tgrg(T, alpha=0.05, a_sim=100, beta=None, b_sim=None): return w_ -def owa_l_moment_crm(T, k=4, method="MSD", g=0.5, max_phi=0.5, solver=None): +def owa_l_moment_crm(T, k=4, method="MSD", g=0.5, max_phi=0.5, solver='CLARABEL'): r""" Calculate the OWA weights to calculate a convex risk measure that considers higher linear moments or L-moments as shown in :cite:`d-Cajas6`. @@ -333,7 +333,7 @@ def owa_l_moment_crm(T, k=4, method="MSD", g=0.5, max_phi=0.5, solver=None): The default is 0.5. solver: str, optional Solver available for CVXPY. Used to calculate 'ME', 'MSS' and 'MSD' weights. - The default value is None. + The default value is 'CLARABEL'. Returns ------- diff --git a/riskfolio/src/PlotFunctions.py b/riskfolio/src/PlotFunctions.py index 05f53edb..85c798c1 100644 --- a/riskfolio/src/PlotFunctions.py +++ b/riskfolio/src/PlotFunctions.py @@ -223,7 +223,7 @@ def plot_frontier( beta=None, b_sim=None, kappa=0.30, - solver=None, + solver='CLARABEL', cmap="viridis", w=None, label="Portfolio", @@ -298,7 +298,7 @@ def plot_frontier( Deformation parameter of RLVaR and RLDaR, must be between 0 and 1. The default is 0.30. solver: str, optional Solver available for CVXPY that supports power cone programming. Used to calculate RLVaR and RLDaR. - The default value is None. + The default value is 'CLARABEL'. cmap : cmap, optional Colorscale that represents the risk adjusted return ratio. The default is 'viridis'. @@ -1103,7 +1103,7 @@ def plot_risk_con( beta=None, b_sim=None, kappa=0.30, - solver=None, + solver='CLARABEL', percentage=False, erc_line=True, color="tab:blue", @@ -1168,7 +1168,7 @@ def plot_risk_con( Deformation parameter of RLVaR and RLDaR, must be between 0 and 1. The default is 0.30. solver: str, optional Solver available for CVXPY that supports power cone programming. Used to calculate RLVaR and RLDaR. - The default value is None. + The default value is 'CLARABEL'. percentage : bool, optional If risk contribution per asset is expressed as percentage or as a value. The default is False. erc_line : bool, optional @@ -1331,7 +1331,7 @@ def plot_hist( alpha=0.05, a_sim=100, kappa=0.30, - solver=None, + solver='CLARABEL', bins=50, height=6, width=10, @@ -1354,7 +1354,7 @@ def plot_hist( Deformation parameter of RLVaR and RLDaR, must be between 0 and 1. The default is 0.30. solver: str, optional Solver available for CVXPY that supports power cone programming. Used to calculate RLVaR and RLDaR. - The default value is None. + The default value is 'CLARABEL'. bins : float, optional Number of bins of the histogram. The default is 50. height : float, optional @@ -1490,11 +1490,11 @@ def plot_hist( y, "--", color="orange", - label=r"Normal: \$\mu=" + label=r"Normal: $\mu=" + "{0:.2%}".format(mu) - + "\$%, \$\sigma=" + + "$%, $\sigma=" + "{0:.2%}".format(sigma) - + "\$%", + + "$%", ) factor = (np.max(a) - np.min(a)) / bins @@ -1730,7 +1730,7 @@ def plot_drawdown( w, alpha=0.05, kappa=0.30, - solver=None, + solver='CLARABEL', height=8, width=10, height_ratios=[2, 3], @@ -1751,7 +1751,7 @@ def plot_drawdown( Deformation parameter of RLVaR and RLDaR, must be between 0 and 1. The default is 0.30. solver: str, optional Solver available for CVXPY that supports power cone programming. Used to calculate RLVaR and RLDaR. - The default value is None. + The default value is 'CLARABEL'. height : float, optional Height of the image in inches. The default is 8. width : float, optional @@ -1920,7 +1920,7 @@ def plot_table( alpha=0.05, a_sim=100, kappa=0.30, - solver=None, + solver='CLARABEL', height=9, width=12, t_factor=252, @@ -1955,7 +1955,7 @@ def plot_table( Deformation parameter of RLVaR and RLDaR, must be between 0 and 1. The default is 0.30. solver: str, optional Solver available for CVXPY that supports power cone programming. Used to calculate RLVaR and RLDaR. - The default value is None. + The default value is 'CLARABEL'. height : float, optional Height of the image in inches. The default is 9. width : float, optional diff --git a/riskfolio/src/Portfolio.py b/riskfolio/src/Portfolio.py index 81fdc6b2..63bc03eb 100644 --- a/riskfolio/src/Portfolio.py +++ b/riskfolio/src/Portfolio.py @@ -3967,7 +3967,7 @@ def efficient_frontier( kelly=False, points=20, rf=0, - solver=None, + solver='CLARABEL', hist=True, ): r""" @@ -4019,7 +4019,7 @@ def efficient_frontier( Risk free rate. The default is 0. solver: str, optional Solver available for CVXPY that supports power cone programming. Used to calculate RLVaR and RLDaR. - The default value is None. + The default value is 'CLARABEL'. hist : bool, optional Indicate what kind of returns are used to calculate risk measures that depends on scenarios (All except 'MV' risk measure). @@ -4304,6 +4304,12 @@ def reset_linear_constraints(self): self.ainequality = None self.binequality = None + self.b = None + self.network_sdp = None + self.network_penalty = 0.05 + self.network_ip = None + self.acentrality = None + self.bcentrality = None def reset_inputs(self): r""" @@ -4360,9 +4366,10 @@ def reset_all(self): self.beta = None self.b_sim = None self.kappa = 0.30 + self.n_max_kurt = 50 self.kindbench = True self.benchindex = None - self._benchweights = None + self.benchweights = None self.allowTO = False self.turnover = 0.05 self.allowTE = False diff --git a/riskfolio/src/Reports.py b/riskfolio/src/Reports.py index 9b0a7d66..bf8a433b 100644 --- a/riskfolio/src/Reports.py +++ b/riskfolio/src/Reports.py @@ -41,7 +41,7 @@ def jupyter_report( beta=None, b_sim=None, kappa=0.30, - solver=None, + solver='CLARABEL', percentage=False, erc_line=True, color="tab:blue", @@ -111,7 +111,7 @@ def jupyter_report( Deformation parameter of RLVaR and RLDaR, must be between 0 and 1. The default is 0.30. solver: str, optional Solver available for CVXPY that supports power cone programming. Used to calculate RLVaR and RLDaR. - The default value is None. + The default value is 'CLARABEL'. percentage : bool, optional If risk contribution per asset is expressed as percentage or as a value. The default is False. erc_line : bool, optional @@ -204,8 +204,8 @@ def jupyter_report( MAR=rf, alpha=alpha, a_sim=a_sim, - kappa=0.30, - solver=None, + kappa=kappa, + solver=solver, t_factor=t_factor, ini_days=ini_days, days_per_year=days_per_year, diff --git a/riskfolio/src/RiskFunctions.py b/riskfolio/src/RiskFunctions.py index 89a1f358..5ddf2eca 100644 --- a/riskfolio/src/RiskFunctions.py +++ b/riskfolio/src/RiskFunctions.py @@ -496,7 +496,7 @@ def EVaR_Hist(X, alpha=0.05): return (value, t) -def RLVaR_Hist(X, alpha=0.05, kappa=0.01, solver=None): +def RLVaR_Hist(X, alpha=0.05, kappa=0.3, solver='CLARABEL'): r""" Calculate the Relativistic Value at Risk (RLVaR) of a returns series. I recommend only use this function with MOSEK solver. @@ -523,10 +523,10 @@ def RLVaR_Hist(X, alpha=0.05, kappa=0.01, solver=None): alpha : float, optional Significance level of EVaR. The default is 0.05. kappa : float, optional - Deformation parameter of RLVaR, must be between 0 and 1. The default is 0.01. + Deformation parameter of RLVaR, must be between 0 and 1. The default is 0.3. solver: str, optional Solver available for CVXPY that supports power cone programming. Used to calculate RLVaR and RLDaR. - The default value is None. + The default value is 'CLARABEL'. Raises ------ @@ -858,7 +858,7 @@ def EDaR_Abs(X, alpha=0.05): return (value, t) -def RLDaR_Abs(X, alpha=0.05, kappa=0.01, solver=None): +def RLDaR_Abs(X, alpha=0.05, kappa=0.3, solver='CLARABEL'): r""" Calculate the Relativistic Drawdown at Risk (RLDaR) of a returns series using uncompounded cumulative returns. I recommend only use this function with MOSEK solver. @@ -875,10 +875,10 @@ def RLDaR_Abs(X, alpha=0.05, kappa=0.01, solver=None): alpha : float, optional Significance level of EVaR. The default is 0.05. kappa : float, optional - Deformation parameter of RLDaR, must be between 0 and 1. The default is 0.01. + Deformation parameter of RLDaR, must be between 0 and 1. The default is 0.3. solver: str, optional Solver available for CVXPY that supports power cone programming. Used to calculate RLVaR and RLDaR. - The default value is None. + The default value is 'CLARABEL'. Raises ------ @@ -1239,7 +1239,7 @@ def EDaR_Rel(X, alpha=0.05): return (value, t) -def RLDaR_Rel(X, alpha=0.05, kappa=0.01, solver=None): +def RLDaR_Rel(X, alpha=0.05, kappa=0.3, solver='CLARABEL'): r""" Calculate the Relativistic Drawdown at Risk (RLDaR) of a returns series using compounded cumulative returns. I recommend only use this function with MOSEK solver. @@ -1256,10 +1256,10 @@ def RLDaR_Rel(X, alpha=0.05, kappa=0.01, solver=None): alpha : float, optional Significance level of RLDaR. The default is 0.05. kappa : float, optional - Deformation parameter of RLDaR, must be between 0 and 1. The default is 0.01. + Deformation parameter of RLDaR, must be between 0 and 1. The default is 0.3. solver: str, optional Solver available for CVXPY that supports power cone programming. Used to calculate RLVaR and RLDaR. - The default value is None. + The default value is 'CLARABEL'. Raises ------ @@ -1581,7 +1581,7 @@ def L_Moment(X, k=2): return value -def L_Moment_CRM(X, k=4, method="MSD", g=0.5, max_phi=0.5, solver=None): +def L_Moment_CRM(X, k=4, method="MSD", g=0.5, max_phi=0.5, solver='CLARABEL'): r""" Calculate a custom convex risk measure that is a weighted average of first k-th l-moments. @@ -1662,8 +1662,8 @@ def Sharpe_Risk( a_sim=100, beta=None, b_sim=None, - kappa=0.01, - solver=None, + kappa=0.3, + solver='CLARABEL', ): r""" Calculate the risk measure available on the Sharpe function. @@ -1726,10 +1726,10 @@ def Sharpe_Risk( Number of CVaRs used to approximate Tail Gini of gains. If None it duplicates a_sim value. The default is None. kappa : float, optional - Deformation parameter of RLVaR, must be between 0 and 1. The default is 0.01. + Deformation parameter of RLVaR, must be between 0 and 1. The default is 0.3. solver: str, optional Solver available for CVXPY that supports power cone programming. Used to calculate RLVaR and RLDaR. - The default value is None. + The default value is 'CLARABEL'. Raises ------ @@ -1835,8 +1835,8 @@ def Sharpe( a_sim=100, beta=None, b_sim=None, - kappa=0.01, - solver=None, + kappa=0.3, + solver='CLARABEL', ): r""" Calculate the Risk Adjusted Return Ratio from a portfolio returns series. @@ -1916,7 +1916,7 @@ def Sharpe( Number of CVaRs used to approximate Tail Gini of gains. If None it duplicates a_sim value. The default is None. kappa : float, optional - Deformation parameter of RLVaR, must be between 0 and 1. The default is 0.01. + Deformation parameter of RLVaR, must be between 0 and 1. The default is 0.3. solver: str, optional Solver available for CVXPY that supports power cone programming. Used to calculate RLVaR and RLDaR. The default value is None. @@ -2018,7 +2018,7 @@ def L_Moment(X, k=2): return value -def L_Moment_CRM(X, k=4, method="MSD", g=0.5, max_phi=0.5, solver=None): +def L_Moment_CRM(X, k=4, method="MSD", g=0.5, max_phi=0.5, solver='CLARABEL'): r""" Calculate a custom convex risk measure that is a weighted average of first k-th l-moments. @@ -2045,7 +2045,7 @@ def L_Moment_CRM(X, k=4, method="MSD", g=0.5, max_phi=0.5, solver=None): The default is 0.5. solver: str, optional Solver available for CVXPY. Used to calculate 'ME', 'MSS' and 'MSD' weights. - The default value is None. + The default value is 'CLARABEL'. Raises ------ @@ -2099,8 +2099,8 @@ def Risk_Contribution( a_sim=100, beta=None, b_sim=None, - kappa=0.01, - solver=None, + kappa=0.3, + solver='CLARABEL', ): r""" Calculate the risk contribution for each asset based on the risk measure @@ -2164,7 +2164,7 @@ def Risk_Contribution( Number of CVaRs used to approximate Tail Gini of gains. If None it duplicates a_sim value. The default is None. kappa : float, optional - Deformation parameter of RLVaR, must be between 0 and 1. The default is 0.01. + Deformation parameter of RLVaR, must be between 0 and 1. The default is 0.3. solver: str, optional Solver available for CVXPY that supports power cone programming. Used to calculate RLVaR and RLDaR. The default value is None.