Skip to main content

Simple riskengine for cvxpy

Project description

cvxrisk

PyPI version Apache 2.0 License Downloads

We provide an abstract Model class. The class is designed to be used in conjunction with cvxpy. Using this class, we can formulate a function computing a standard minimum risk portfolio as

import cvxpy as cp

from cvx.risk import Model


def minimum_risk(w: cp.Variable, risk_model: Model, **kwargs) -> cp.Problem:
    """Constructs a minimum variance portfolio.

    Args:
        w: cp.Variable representing the portfolio weights.
        risk_model: A risk model.

    Returns:
        A convex optimization problem.
    """
    return cp.Problem(
        cp.Minimize(risk_model.estimate(w, **kwargs)),
        [cp.sum(w) == 1, w >= 0] + risk_model.constraints(w, **kwargs)
    )

The risk model is injected into the function. The function is not aware of the precise risk model used. All risk models are required to implement the estimate method.

Note that factor risk models work with weights for the assets but also with weights for the factors. To stay flexible we are applying the **kwargs pattern to the function above.

A first example

A first example is a risk model based on the sample covariance matrix. We construct the risk model as follows

import numpy as np
import cvxpy as cp

from cvx.risk.sample import SampleCovariance

riskmodel = SampleCovariance(num=2)
w = cp.Variable(2)
problem = minimum_risk(w, riskmodel)

riskmodel.update(cov=np.array([[1.0, 0.5], [0.5, 2.0]]))
problem.solve()
print(w.value)

The risk model and the actual optimization problem are decoupled. This is good practice and keeps the code clean and maintainable.

In a backtest we don't have to reconstruct the problem in every iteration. We can simply update the risk model with the new data and solve the problem again. The implementation of the risk models is flexible enough to deal with changing dimensions of the underlying weight space.

Risk models

Sample covariance

We offer a SampleCovariance class as seen above.

Factor risk models

Factor risk models use the projection of the weight vector into a lower dimensional subspace, e.g. each asset is the linear combination of $k$ factors.

r_i = \sum_{j=1}^k f_j \beta_{ji} + \epsilon_i

The factor time series are $f_1, \ldots, f_k$. The loadings are the coefficients $\beta_{ji}$. The residual returns $\epsilon_i$ are assumed to be uncorrelated with the f actors.

Any position $w$ in weight space projects to a position $y = \beta^T w$ in factor space. The variance for a position $w$ is the sum of the variance of the systematic returns explained by the factors and the variance of the idiosyncratic returns.

Var(r) = Var(\beta^T w) + Var(\epsilon w)

We assume the residual returns are uncorrelated and hence

Var(r) = y^T \Sigma_f y + \sum_i w_i^2 Var(\epsilon_i)

where $\Sigma_f$ is the covariance matrix of the factors and $Var(\epsilon_i)$ is the variance of the idiosyncratic returns.

Factor risk models are widely used in practice. Usually two scenarios are distinguished. A first route is to rely on estimates for the factor covariance matrix $\Sigma_f$, the loadings $\beta$ and the volatilities of the idiosyncratic returns $\epsilon_i$. Usually those quantities are provided by external parties, e.g. Barra or Axioma.

An alternative would be to start with the estimation of factor time series $f_1, \ldots, f_k$. Usually they are estimated via a principal component analysis (PCA) of the asset returns. It is then a simple linear regression to compute the loadings $\beta$. The volatilities of the idiosyncratic returns $\epsilon_i$ are computed as the standard deviation of the observed residuals. The factor covariance matrix $\Sigma_f$ may even be diagonal in this case as the factors are orthogonal.

We expose a method to compute the first $k$ principal components.

cvar

We currently also support the conditional value at risk (CVaR) as a risk measure.

Poetry

We assume you share already the love for Poetry. Once you have installed poetry you can perform

make install

to replicate the virtual environment we have defined in pyproject.toml and locked in poetry.lock.

Jupyter

We install JupyterLab on fly within the aforementioned virtual environment. Executing

make jupyter

will install and start the jupyter lab.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cvxrisk-1.3.0.tar.gz (1.5 MB view details)

Uploaded Source

Built Distribution

cvxrisk-1.3.0-py3-none-any.whl (19.8 kB view details)

Uploaded Python 3

File details

Details for the file cvxrisk-1.3.0.tar.gz.

File metadata

  • Download URL: cvxrisk-1.3.0.tar.gz
  • Upload date:
  • Size: 1.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.10.12

File hashes

Hashes for cvxrisk-1.3.0.tar.gz
Algorithm Hash digest
SHA256 635daba0b76a41935b52ffa4c2f554a6a6b0e8346b79d85d8312f34314da8a8f
MD5 ff5827a763f2fbf13afaf66fa8935709
BLAKE2b-256 4c9521555adde99f2cf59295abc396a805a82aa558bfc732e3e1be1e3fbb6b14

See more details on using hashes here.

File details

Details for the file cvxrisk-1.3.0-py3-none-any.whl.

File metadata

  • Download URL: cvxrisk-1.3.0-py3-none-any.whl
  • Upload date:
  • Size: 19.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.10.12

File hashes

Hashes for cvxrisk-1.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cee30e3e9a002b680717e9d15aaab372d1e63a8f99f9f8e9fac7a9b2bbd66b19
MD5 f37441862880a4a2af05e380469657d9
BLAKE2b-256 95f4cf687d7d6b98d431925ed0680cb141599a50c189c1960a14f7b2d1d02401

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page