mirror of
https://github.com/robertmartin8/PyPortfolioOpt.git
synced 2022-11-27 18:02:41 +03:00
misc refactors
This commit is contained in:
@@ -6,7 +6,8 @@ from .black_litterman import (
|
|||||||
from .cla import CLA
|
from .cla import CLA
|
||||||
from .discrete_allocation import get_latest_prices, DiscreteAllocation
|
from .discrete_allocation import get_latest_prices, DiscreteAllocation
|
||||||
from .efficient_frontier import EfficientFrontier
|
from .efficient_frontier import EfficientFrontier
|
||||||
from .hierarchical_risk_parity import HRPOpt
|
from .hierarchical_portfolios import HRPOpt
|
||||||
|
from .risk_models import CovarianceShrinkage
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"market_implied_prior_returns",
|
"market_implied_prior_returns",
|
||||||
@@ -17,4 +18,5 @@ __all__ = [
|
|||||||
"DiscreteAllocation",
|
"DiscreteAllocation",
|
||||||
"EfficientFrontier",
|
"EfficientFrontier",
|
||||||
"HRPOpt",
|
"HRPOpt",
|
||||||
|
"CovarianceShrinkage",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"""
|
"""
|
||||||
The ``base_optimizer`` module houses the parent classes ``BaseOptimizer`` from which all
|
The ``base_optimizer`` module houses the parent classes ``BaseOptimizer`` from which all
|
||||||
optimisers will inherit. ``BaseConvexOptimizer`` is thebase class for all ``cvxpy`` (and ``scipy``)
|
optimisers will inherit. ``BaseConvexOptimizer`` is the base class for all ``cvxpy`` (and ``scipy``)
|
||||||
optimisation.
|
optimisation.
|
||||||
|
|
||||||
Additionally, we define a general utility function ``portfolio_performance`` to
|
Additionally, we define a general utility function ``portfolio_performance`` to
|
||||||
@@ -205,12 +205,12 @@ class BaseConvexOptimizer(BaseOptimizer):
|
|||||||
Add a new term into the objective function. This term must be convex,
|
Add a new term into the objective function. This term must be convex,
|
||||||
and built from cvxpy atomic functions.
|
and built from cvxpy atomic functions.
|
||||||
|
|
||||||
Example:
|
Example::
|
||||||
|
|
||||||
def L1_norm(w, k=1):
|
def L1_norm(w, k=1):
|
||||||
return k * cp.norm(w, 1)
|
return k * cp.norm(w, 1)
|
||||||
|
|
||||||
ef.add_objective(L1_norm, k=2)
|
ef.add_objective(L1_norm, k=2)
|
||||||
|
|
||||||
:param new_objective: the objective to be added
|
:param new_objective: the objective to be added
|
||||||
:type new_objective: cp.Expression (i.e function of cp.Variable)
|
:type new_objective: cp.Expression (i.e function of cp.Variable)
|
||||||
@@ -222,11 +222,11 @@ class BaseConvexOptimizer(BaseOptimizer):
|
|||||||
Add a new constraint to the optimisation problem. This constraint must be linear and
|
Add a new constraint to the optimisation problem. This constraint must be linear and
|
||||||
must be either an equality or simple inequality.
|
must be either an equality or simple inequality.
|
||||||
|
|
||||||
Examples:
|
Examples::
|
||||||
|
|
||||||
ef.add_constraint(lambda x : x[0] == 0.02)
|
ef.add_constraint(lambda x : x[0] == 0.02)
|
||||||
ef.add_constraint(lambda x : x >= 0.01)
|
ef.add_constraint(lambda x : x >= 0.01)
|
||||||
ef.add_constraint(lambda x: x <= np.array([0.01, 0.08, ..., 0.5]))
|
ef.add_constraint(lambda x: x <= np.array([0.01, 0.08, ..., 0.5]))
|
||||||
|
|
||||||
:param new_constraint: the constraint to be added
|
:param new_constraint: the constraint to be added
|
||||||
:type constraintfunc: lambda function
|
:type constraintfunc: lambda function
|
||||||
@@ -242,14 +242,14 @@ class BaseConvexOptimizer(BaseOptimizer):
|
|||||||
def convex_objective(self, custom_objective, weights_sum_to_one=True, **kwargs):
|
def convex_objective(self, custom_objective, weights_sum_to_one=True, **kwargs):
|
||||||
"""
|
"""
|
||||||
Optimise a custom convex objective function. Constraints should be added with
|
Optimise a custom convex objective function. Constraints should be added with
|
||||||
``ef.add_constraint()``. Optimiser arguments *must* be passed as keyword-args. Example:
|
``ef.add_constraint()``. Optimiser arguments *must* be passed as keyword-args. Example::
|
||||||
|
|
||||||
# Could define as a lambda function instead
|
# Could define as a lambda function instead
|
||||||
def logarithmic_barrier(w, cov_matrix, k=0.1):
|
def logarithmic_barrier(w, cov_matrix, k=0.1):
|
||||||
# 60 Years of Portfolio Optimisation, Kolm et al (2014)
|
# 60 Years of Portfolio Optimisation, Kolm et al (2014)
|
||||||
return cp.quad_form(w, cov_matrix) - k * cp.sum(cp.log(w))
|
return cp.quad_form(w, cov_matrix) - k * cp.sum(cp.log(w))
|
||||||
|
|
||||||
w = ef.convex_objective(logarithmic_barrier, cov_matrix=ef.cov_matrix)
|
w = ef.convex_objective(logarithmic_barrier, cov_matrix=ef.cov_matrix)
|
||||||
|
|
||||||
:param custom_objective: an objective function to be MINIMISED. This should be written using
|
:param custom_objective: an objective function to be MINIMISED. This should be written using
|
||||||
cvxpy atoms Should map (w, **kwargs) -> float.
|
cvxpy atoms Should map (w, **kwargs) -> float.
|
||||||
@@ -283,22 +283,22 @@ class BaseConvexOptimizer(BaseOptimizer):
|
|||||||
"""
|
"""
|
||||||
Optimise some objective function using the scipy backend. This can
|
Optimise some objective function using the scipy backend. This can
|
||||||
support nonconvex objectives and nonlinear constraints, but often gets stuck
|
support nonconvex objectives and nonlinear constraints, but often gets stuck
|
||||||
at local minima. This method is not recommended – caveat emptor. Example:
|
at local minima. This method is not recommended – caveat emptor. Example::
|
||||||
|
|
||||||
# Market-neutral efficient risk
|
# Market-neutral efficient risk
|
||||||
constraints = [
|
constraints = [
|
||||||
{"type": "eq", "fun": lambda w: np.sum(w)}, # weights sum to zero
|
{"type": "eq", "fun": lambda w: np.sum(w)}, # weights sum to zero
|
||||||
{
|
{
|
||||||
"type": "eq",
|
"type": "eq",
|
||||||
"fun": lambda w: target_risk ** 2 - np.dot(w.T, np.dot(ef.cov_matrix, w)),
|
"fun": lambda w: target_risk ** 2 - np.dot(w.T, np.dot(ef.cov_matrix, w)),
|
||||||
}, # risk = target_risk
|
}, # risk = target_risk
|
||||||
]
|
]
|
||||||
ef.nonconvex_objective(
|
ef.nonconvex_objective(
|
||||||
lambda w, mu: -w.T.dot(mu), # min negative return (i.e maximise return)
|
lambda w, mu: -w.T.dot(mu), # min negative return (i.e maximise return)
|
||||||
objective_args=(ef.expected_returns,),
|
objective_args=(ef.expected_returns,),
|
||||||
weights_sum_to_one=False,
|
weights_sum_to_one=False,
|
||||||
constraints=constraints,
|
constraints=constraints,
|
||||||
)
|
)
|
||||||
|
|
||||||
:param objective_function: an objective function to be MINIMISED. This function
|
:param objective_function: an objective function to be MINIMISED. This function
|
||||||
should map (weight, args) -> cost
|
should map (weight, args) -> cost
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class BlackLittermanModel(base_optimizer.BaseOptimizer):
|
|||||||
|
|
||||||
- Inputs:
|
- Inputs:
|
||||||
|
|
||||||
- ``cov_matrix`` - pd.DataFrame
|
- ``cov_matrix`` - np.ndarray
|
||||||
- ``n_assets`` - int
|
- ``n_assets`` - int
|
||||||
- ``tickers`` - str list
|
- ``tickers`` - str list
|
||||||
- ``Q`` - np.ndarray
|
- ``Q`` - np.ndarray
|
||||||
@@ -341,9 +341,9 @@ class BlackLittermanModel(base_optimizer.BaseOptimizer):
|
|||||||
if self.posterior_cov is None:
|
if self.posterior_cov is None:
|
||||||
self.posterior_cov = self.bl_cov()
|
self.posterior_cov = self.bl_cov()
|
||||||
return base_optimizer.portfolio_performance(
|
return base_optimizer.portfolio_performance(
|
||||||
|
self.weights,
|
||||||
self.posterior_rets,
|
self.posterior_rets,
|
||||||
self.posterior_cov,
|
self.posterior_cov,
|
||||||
self.weights,
|
|
||||||
verbose,
|
verbose,
|
||||||
risk_free_rate,
|
risk_free_rate,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ class CLA(base_optimizer.BaseOptimizer):
|
|||||||
- ``n_assets`` - int
|
- ``n_assets`` - int
|
||||||
- ``tickers`` - str list
|
- ``tickers`` - str list
|
||||||
- ``mean`` - np.ndarray
|
- ``mean`` - np.ndarray
|
||||||
- ``cov_matrix`` - pd.DataFrame
|
- ``cov_matrix`` - np.ndarray
|
||||||
- ``expected_returns`` - pd.Series
|
- ``expected_returns`` - np.ndarray
|
||||||
- ``lb`` - np.ndarray
|
- ``lb`` - np.ndarray
|
||||||
- ``ub`` - np.ndarray
|
- ``ub`` - np.ndarray
|
||||||
|
|
||||||
@@ -447,9 +447,9 @@ class CLA(base_optimizer.BaseOptimizer):
|
|||||||
:rtype: (float, float, float)
|
:rtype: (float, float, float)
|
||||||
"""
|
"""
|
||||||
return base_optimizer.portfolio_performance(
|
return base_optimizer.portfolio_performance(
|
||||||
|
self.weights,
|
||||||
self.expected_returns,
|
self.expected_returns,
|
||||||
self.cov_matrix,
|
self.cov_matrix,
|
||||||
self.weights,
|
|
||||||
verbose,
|
verbose,
|
||||||
risk_free_rate,
|
risk_free_rate,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user