Repository navigation
Add max diversification - #15
Merged
Merged
Conversation
thinkjrs
commented
Oct 27, 2026
thinkjrs
commented
Oct 27, 2026
thinkjrs
commented
Oct 27, 2026
thinkjrs
commented
Oct 27, 2026
thinkjrs
commented
Oct 27, 2026
thinkjrs
commented
Oct 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds max diversification, the last of the 0.2.5 methods built on the active-set QP solver from #11.
max_diversification_allocation()andmax_diversification_allocation_with_config(&CovarianceConfig)The method maximizes the diversification ratio
σᵀw / √(wᵀΣw)subject to1ᵀw = 1andw ≥ 0, whereσholds the asset volatilities from the adjusted covariance. It uses only the covariance, so its API matches long-only min variance. It has nolong_only_prefix because the method is long-only by definition.The ratio has the same form as the Sharpe ratio, with
σin place ofμ − r_f, so the same change of variables applies. Rescaling one asset doesn't change the ratio, so it's solved on the correlation matrixCrather thanΣ:Solving on
Σin raw units gave wrong weights, with no error, when volatilities were about eight orders of magnitude apart.long_only_max_ratio(cov, a, best), which both methods call. It returnsNonewhen the optimum is in the null space, so each caller names its own error. Long-only max Sharpe still solves onΣ.SingularCovariance, as risk parity does. The cutoff now runs onC, so it doesn't depend on units.Unboundeddescribes expected returns growing without limit, which doesn't fit a covariance-only method. Shrinkage or regularization gives weights.Tests
w ∝ C⁻¹1 / σon three assets with unequal correlations.SingularCovarianceon the rank-one covariance and weights once shrinkage is added. It returns weights on the collinear pair, whose zero-variance hedge needs a short.σ·wᵀΣw − σᵀw·Σw, is zero on held assets and no higher on the others.long_only_methodslist now feeds all three "best long-only" properties, so max diversification is also checked against long-only min variance and long-only max Sharpe.k ∈ [1e-6, 1e6]divides its weight byk, then the weights are rescaled.PROPTEST_CASES=50000pass.long_only_max_ratio(cov, a). Max diversification calls it on the correlation matrix. The long-only max Sharpe fixtures are unchanged.scales4has four correlated assets with volatilities from about 1e-2 to 1e-10. Min variance and risk parity skip it, since they solve in raw units, where its covariance is numerically singular.scales4, the singular datasets with shrinkage, regularization onnear_singular4, andrank_deficient6without shrinkage, which expectsSingularCovariance.SingularCovariance(2,979 and 1,021) and no other errors. Every set of weights was nonnegative and summed to 1.Docs
reference/README.mddescribes the correlation-matrix reference andscales4.compareexample adds a row.