Portfolio optimization with max information ratio. (cvxpy library not giving answer for particular cases)

125 Views Asked by At

In portfolio optimisation with maximizing information ratio, our aim is to create a portfolio such that the information ratio of the portfolio and corresponding benchmark is maximized. Information ratio is defined as the ratio of mean active return of the portfolio to the tracking error (standard deviation) of the active return.

\begin{align*} \text{Information Ratio }(IR) = \frac{E(R_p - R_b)}{\sqrt{\text{var} (R_p - R_b)}} \end{align*}

where $R_p$ is the portfolio return and $R_b$ is the benchmark return.

Suppose, we are having $T$ discrete time steps and $n$ assets. The returns matrix of the assets is of size $T \times n$ and returns of benchmark is of size $T \times 1$. The mean return of portfolio is $\boldsymbol{\overline{\mu}^{T} w}$ and mean benchmark return is $\boldsymbol{\overline{r_b}}$. Hence, maximising the $IR$ is as:

\begin{align*} \max_{\boldsymbol{w}} IR = \max_{\boldsymbol{w}} \,\,\,& \frac{\boldsymbol{\overline{\mu}^T w} - \boldsymbol{\overline{r_b}}}{\sqrt{\sum_t \left[(\boldsymbol{\mu_t^T w} - \boldsymbol{r_{b_t}}) - (\boldsymbol{\overline{\mu}^T w} - \boldsymbol{\overline{r_b}})\right]^2}} \\ \text{such that } & \sum_{i = 1} ^n w_i = 1 \\ & w_i \geq 0 \;\; \forall \, i \end{align*}

The above problem is not a convex optimization problem. Following this, we can convert it to a convex optimization problem as \begin{align*} \max_{\boldsymbol{y}} \,\,\, & \frac{1}{\sqrt{\sum_t \left[(\boldsymbol{\mu_t^T } - \boldsymbol{r_{b_t}}) \boldsymbol{y} - (\boldsymbol{\overline{\mu}^T} - \boldsymbol{\overline{r_b}})\boldsymbol{y} \right]^2}} \\ & \text{such that } (\boldsymbol{\overline{\mu}^T} - \boldsymbol{\overline{r_b}})\boldsymbol{y} = 1 \\ & \sum_{i = 1}^n y_i = k \\ & y_i \geq 0 \,\, \forall i \\ & k \geq 0 \end{align*} which is equivalent as \begin{align*} \min_{\boldsymbol{y}} \,\,\, & \sum_t \left[(\boldsymbol{\mu_t^T } - \boldsymbol{r_{b_t}}) \boldsymbol{y} - (\boldsymbol{\overline{\mu}^T} - \boldsymbol{\overline{r_b}})\boldsymbol{y} \right]^2 \\ & \text{such that } (\boldsymbol{\overline{\mu}^T} - \boldsymbol{\overline{r_b}})\boldsymbol{y} = 1 \\ & \sum_{i = 1}^n y_i = k \\ & y_i \geq 0 \,\, \forall i \\ & k \geq 0 \end{align*} which is a convex quadratic optimization problem. The final weight vector is $\boldsymbol{w} = \frac{\boldsymbol{y}}{k}$

I've tried to code for the above problem statement in python using cvxpy as

def get_weights_IR(lb,ub):
    y = cp.Variable(N)
    k = cp.Variable()


    mean_benchmark_return = benchmark_array.mean()
    mean_active_return = (returns_array.mean(axis=0)-mean_benchmark_return).T@y



    constraints = [mean_active_return == 1,
                   cp.sum(y) == k,
                   y >= 0,
                   k >= 0]

    constraints.append(lb*k <= y)   # Lowerbounds on w
    constraints.append(y <= ub*k)   # Upperbounds on w

    obj = cp.sum(cp.square(((returns_array.T-benchmark_array).T@y)-mean_active_return))


    prob = cp.Problem(cp.Minimize(obj),constraints)
    prob.solve(verbose = True)

    w_opt = y.value/k.value
    
    return w_opt

returns_array = np.array([[-0.03013711,  0.0061953 , -0.02213975,  0.22691861,  0.13615994],
                          [ 0.12480428,  0.15133655,  0.08756408,  0.15077763, -0.01012724],
                          [ 0.51122509,  0.33187607,  0.32826354,  0.414051  , -0.07640095],
                          [-0.16216891,  0.09742404, -0.02647671,  0.15283474, -0.08011946],
                          [ 1.12320715,  0.19202962,  0.38456644,  0.6526214 , -0.09486195],
                          [ 0.75540589, -0.04461505, -0.15299409,  0.38693823, -0.26830538]])

benchmark_array = np.array([ 0.08426975,  0.05885787,  0.33878463, -0.05593472,  0.43057013, 
                            0.44357561])

lb = 0.19
ub = 0.5

In this code, I've kept time steps, $T = 6$ and number of assets, $n = 5$. So the returns matrix of assets is of size $6 \times 5$. This code works when I keep lb = 0.1, it gives the optimal solution, but for lb = 0.19, it says that the problem status is infeasible. I'm unable to figure out any error here. Can anyone help me in understanding about what's going wrong here? Thanks in advance.