From 4c12b4d276cfb52632589065f1856fa6aea83861 Mon Sep 17 00:00:00 2001 From: anmol0705 Date: Sun, 21 Jun 2026 15:28:33 +0530 Subject: [PATCH] Fix CLA max_sharpe with equal expected returns --- pypfopt/cla.py | 4 ++-- tests/test_cla.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/pypfopt/cla.py b/pypfopt/cla.py index bde53b19..b21aff6d 100644 --- a/pypfopt/cla.py +++ b/pypfopt/cla.py @@ -364,8 +364,8 @@ def _solve(self): self.w[-1][i], ) if ( - self.ls[-1] is None or lam < self.ls[-1] - ) and lam > CLA._infnone(l_out): + self.ls[-1] is None or CLA._infnone(lam) < self.ls[-1] + ) and CLA._infnone(lam) > CLA._infnone(l_out): l_out, i_out = lam, i if (l_in is None or l_in < 0) and (l_out is None or l_out < 0): # 3) compute minimum variance solution diff --git a/tests/test_cla.py b/tests/test_cla.py index c5f69e23..7a198c8e 100644 --- a/tests/test_cla.py +++ b/tests/test_cla.py @@ -52,6 +52,19 @@ def test_cla_max_sharpe_short(): assert sharpe > long_only_sharpe +def test_cla_max_sharpe_equal_returns_matches_min_volatility(): + mu = np.array([0.1, 0.1]) + S = np.array([[0.01, 0.01], [0.01, 0.02]]) + + cla = CLA(mu, S) + w = cla.max_sharpe() + + min_vol_cla = CLA(mu, S) + min_vol_w = min_vol_cla.min_volatility() + assert w == min_vol_w + np.testing.assert_allclose(cla.weights, min_vol_cla.weights) + + def test_cla_custom_bounds(): bounds = [(0.01, 0.13), (0.02, 0.11)] * 10 cla = setup_cla(weight_bounds=bounds)