NEWS
RiskPortfolios 2.1.8 (2026-08-21)
- optimalPortfolio(type = 'erc'): the equal-risk-contribution weights are now
obtained exactly for the 'none' and 'lo' constraints, by solving
y_i [Sigma y]_i = 1/N (Spinu, 2013), instead of minimising the squared
deviations of the risk contributions with a general-purpose optimizer. The
latter objective is not convex and has local minima on the boundary at which
entire blocks of assets are assigned a zero weight; those were returned
silently whenever the correlation matrix had sizeable negative entries.
- meanEstimation(type = 'bs'): the sample size used in the Bayes-Stein
shrinkage intensity was the number of assets instead of the number of
observations, so the estimator did not depend on the length of the sample
and over-shrunk toward the minimum-variance mean.
- optimalPortfolio(type = 'maxdec', constraint = 'none') solved the problem
with the covariance matrix instead of the correlation matrix, and therefore
returned the minimum-variance portfolio.
- optimalPortfolio(type = 'mv', constraint = 'none') is now the solution of
the mean-variance problem under the summability constraint. The weights used
to be rescaled in a way that cancelled 'gamma' altogether and flipped the
sign of the portfolio when 1'Sigma^-1 mu was negative.
- covEstimation(type = 'ewma') is now normalised: the recursion is started at
zero rather than at the sample covariance matrix, which used to inflate the
covariance by a factor (1 + lambda^T) -- 30% for T = 20.
- covEstimation(type = 'large') is an alias of 'lw'. The two estimators were
numerically identical up to the truncation of the shrinkage intensity to
[0, 1], which 'large' omitted.
- optimalPortfolio(type = 'riskeff') works for portfolios of fewer than ten
assets, and tolerates ties in the semideviations.
- The convergence status returned by slsqp is now inspected instead of being
discarded, and the non-convex problems are solved from several starting
values.
- The default ctr.slsqp gains ftol_rel = 1e-12. The previous default set only
xtol_rel = 1e-18, which is below double precision and can never be met, so
every gross-constrained problem ran to maxeval and reported a non-converged
status irrespective of whether it had converged. With an attainable
criterion the mean-variance problem with a gross constraint on 25 assets
stops after 126 iterations instead of 2000, and the solver's convergence
status becomes informative. It now applies only to the non-convex problems
('erc' under bounds, 'maxdiv' and 'riskeff'), the convex ones having been
moved to an exact quadratic program.
- 'gross.c' is validated (it was not, because the test was made on the wrong
variable), 'lambda' is validated, 'K' required to be a positive
integer, and the dimensions of 'mu' and 'semiDev' are checked against Sigma.
- optimalPortfolio(type = 'invvol') projects its weights onto 'LB'/'UB' when
they bind, with a warning, instead of returning weights that violate them.
- 'LB' and 'UB' are validated whenever they are supplied, not only under the
'user' constraint: they are passed to the optimizer under 'gross' as well,
and bounds incompatible with the summability constraint are now rejected.
- The starting value is projected onto the bounds, so a feasible problem such
as constraint = 'gross' with LB = c(0.9, 0, 0, 0) no longer fails outright
because the equally-weighted default violates them.
- The returned weights are projected onto {LB <= w <= UB, w'1 = 1} rather than
clipped and rescaled, which could push a weight back outside the bounds it
had just been clipped into.
- The default risk aversion is 0.89, as documented (it was 0.8773).
- covEstimation(type = 'const' / 'diag') works for a single asset. The factor
estimator still requires at least three assets, as factanal() does.
- The equal-risk-contribution solver now measures convergence on its defining
condition, y_i [Sigma y]_i = 1/N, relative to that target, and warns if it
is not met. It previously stopped on the size of the last step, normalised
by the largest component of y, and gave up after a thousand sweeps: on
ill-conditioned covariance matrices -- about 1% of ordinary sample
covariance matrices -- it returned risk contributions differing by several
percentage points without any indication, and on the worst cases it was
less accurate than the optimizer it replaced.
- The gross exposure of the returned weights is verified, and the starting
value is required to respect the gross budget. A truncated optimization
could otherwise hand back a portfolio violating gross.c.
- meanEstimation() and semidevEstimation() accept lambda = 1 again, the
no-decay limit that gives equal weights; 2.1.8-dev had wrongly excluded it
for all three estimators, although only the ewma covariance divides by
1 - lambda^T.
- The returns matrix is validated: non-finite entries used to propagate
silently into an all-NA covariance matrix and on into the optimizers.
optimalPortfolio() likewise requires finite Sigma, mu and semiDev, and
invvol requires strictly positive variances instead of returning NaN.
- 'gamma' must be a single positive number, as documented.
- Documentation: the risk-efficient portfolio's stabilizing bounds of
1/(2N) and 2/N are now documented, including the fact that they apply
under every constraint and make gross.c inoperative for that portfolio;
the invertibility of the shrinkage estimators is no longer overstated;
the ewma formula and its prose agree; the plain-text rendering of the
risk-efficient objective divides rather than multiplies; the JOSS
reference is corrected to 2(10), 171.
- Every supplied bound now enters the optimization. 'LB'/'UB' passed together
with constraint = 'lo' or 'none' used to be left out of the quadratic
program and applied afterwards by projecting its solution onto the box,
which restores feasibility but does not minimise the objective: minimum
variance on diag(1, 4, 9) with UB = c(.4, .8, .8) returned variance
1.210779 where the bounded program gives 1.156923.
- The mean-variance, minimum-variance and maximum-decorrelation portfolios
under the 'gross' constraint are now solved exactly as quadratic programs,
by splitting w into positive and negative parts so that the gross budget
becomes linear. They were handed to a nonlinear optimizer that had no
attainable stopping criterion on them, and stopped up to 1e-6 short of the
optimum after exhausting its evaluation budget.
- Sigma is required to be positive semidefinite. An indefinite matrix used to
be accepted, so that 'minimum variance' was reported for a problem whose
objective is unbounded below.
- The maximum-diversification portfolio is refused when Sigma is singular and
nothing bounds the weights: the diversification ratio has no maximum there,
and the optimizer used to return weights of order 1e5 without saying so.
- covEstimation(type = 'lw' / 'large') reports the degenerate case in which
the equally-weighted market factor has zero variance, instead of returning
NaN off-diagonal entries. covEstimation(type = 'const' / 'cor') likewise
reports assets with zero variance rather than returning NA/NaN.
- The Bayes-Stein estimators state their T > N requirement and report a
singular sample covariance matrix in their own terms instead of passing on
a LAPACK message.
- The ewma semideviation weights are computed on the log scale, rebased on
the newest selected observation: lambda^T underflowed to zero on a long
sample and the selected weights then normalised to 0/0.
- 'semiDev' must be non-negative.
- CITATION uses bibentry(); MASS removed from Imports; documentation fixes.
RiskPortfolios 2.1.7 (2021-05-16)
RiskPortfolios 2.1.6
RiskPortfolios 2.1.5 (2021-04-21)
- Update references
- DOI fixed
RiskPortfolios 2.1.4 (2020-04-20)
- Fix description and citation
RiskPortfolios 2.1.3 (2020-04-19)
- Fix description and citation
RiskPortfolios 2.1.2 (2018-08-30)
- References updated
- Gradient added
- Max decorrelation portfolio added
RiskPortfolios 2.1.0
- CRAN release
- documentation updated
- THANKS file added
RiskPortfolios 2.00.11
- Documentation improved and finalized
RiskPortfolios 2.00.10
- LB and UB added properly
- doc modified
RiskPortfolios 2.00.09
- dataset added
- doc RiskPortfolios added
RiskPortfolios 2.00.08
- tests added
- doc fixed
- positivity fixed
RiskPortfolios 2.00.07
- Roxygen documentation
- testthat added
RiskPortfolios 2.00.06
RiskPortfolios 2.00.05
- update informations and references
RiskPortfolios 2.00.04
- serveral error fixes
- new Imports instead of Depends
RiskPortfolios 2.00.03
- erc initialized at 1/sigma normlized
RiskPortfolios 2.00.02
- w0 starting value can now be passed in controls
- references updated
RiskPortfolios 2.00.01
- Renaming of the package with emphasis of risk-based portfolios
- Added inverse volatility portfolio
RiskPortfolios 1.02.02
- DESCRIPTION file adapted to new standard
RiskPortfolios 1.02.01
- major revision of the package
RiskPortfolios 1.01.02
- bug fixd thanks to Samo Pahor
RiskPortfolios 1.01.01
- package's name
- package's version
RiskPortfolios 1-00.01