next up previous contents index
Next: Term Structure algorithms. Up: Mean Variance Analysis. Previous: Mean variance portfolios.   Contents   Index

Short sales constraints

In real applications, it is often not possible to sell assets short. In that case we need to add a constraint that all portfolio weights shall be zero or above.

When constraining the short sales, we need to solve a quadratic program.

\begin{displaymath}\min \mathbf{\omega}^\prime \mathbf{V} \mathbf{\omega} \end{displaymath}

subject to

\begin{displaymath}\mathbf{\omega}^\prime\mathbf{1} = 1 \end{displaymath}


\begin{displaymath}\mathbf{\omega}^\prime\mathbf{e} = E[r_p] \end{displaymath}


\begin{displaymath}\omega_i \in [0,1] \ \ \forall \ i \end{displaymath}

To actually put the full code for a quadratic program here is beyond the purpose of these notes. In the following I therefore submit the program to a quadratic solver called cfsqp. At times is it best to trust in the OR department and their codes. The code merely indicates what the typical steps are in submitting this to a general optimization routine. All we have to do is to define an objective function and a set of constraints as C subroutines that can be interfaced with an optimizer.



// file mv_short.cc 
// author: Bernt Arne Oedegaard
// calculate a mean variance portfolio under short sales constraints
#include "mv_calc.h"
#include "cfsqp_op.h"   // optimize using CFSQP
#include "mymatrix.h"  // 

int      MV_SHORT_no_assets;   // global values because they need to be 
double   MV_SHORT_r;           // available in criterion function
Matrix*  MV_SHORT_e;
Matrix*  MV_SHORT_V;

double MV_SHORT_objective(double x[]){
     Matrix X(MV_SHORT_no_assets,1);
     for (int i=0;i<MV_SHORT_no_assets;++i){
 	X.element(i,0)=x[i];
     };
     return mv_calculate_variance(*MV_SHORT_V,X);
 }

 double MV_SHORT_constraints(double x[],int constraint_no){
     Matrix X(MV_SHORT_no_assets,1);
     for (int i=0;i<MV_SHORT_no_assets;++i){
 	X.element(i,0)=x[i];
     };
     if (constraint_no==1) {    // constraint w'1=1
 	Matrix A = (X.t()*ones_matrix(MV_SHORT_no_assets,1));
 	return A.element(0,0)-1.0;
     };
     if (constraint_no==2) {    // constraint w'e=r
 	Matrix A = (X.t()*(*MV_SHORT_e));
 	return A.element(0,0)-MV_SHORT_r;
     };
     return 0;
 };

ReturnMatrix mv_calculate_portfolio_given_mean_no_short_sales( Matrix& e,
 							       Matrix& V,
 							       double r){
     // solve the quadratic program to minimize variance given constraints
     // all weights are in [0,1] 
     // the weights sum to one
     // expected return equals r
  MV_SHORT_no_assets = e.Nrows();
  MV_SHORT_V = &V;
  MV_SHORT_e = &e;
  MV_SHORT_r = r;
  Matrix w = null_matrix(MV_SHORT_no_assets, 1);
  // check whether it is feasible to find optimum. Only if r is between 
  // min and max in e;
  double r_min = e.element(0,0);
  double r_max = e.element(0,0);
  int i_min = 0;
  int i_max = 0;
  int i;
  for (i=1;i<MV_SHORT_no_assets;++i) {
    if (e.element(i,0)<r_min) { 
      r_min = e.element(i,0); 
      i_min = i;
    };
    if (e.element(i,0)>r_max) { 
      r_max = e.element(i,0); 
      i_max = i;
    };
  };
  if ( (r>r_max) || (r<r_min) ) {
    cerr << " can not perform optimization " << endl;
    w.Release(); // returning zeros as weight
    return w;
  };     
  double *x = new double[MV_SHORT_no_assets];
  double *x_min = new double[MV_SHORT_no_assets];
  double *x_max = new double[MV_SHORT_no_assets];
  for (i=0;i<MV_SHORT_no_assets;++i) {
    x[i]      = 0;
    x_min[i]  = 0;
    x_max[i] = 1;
  };
  // now generate feasible portfolio by combining r_max and r_min;
  double lambda = (r-r_max)/(r_min-r_max);
  x[i_min]=lambda;
  x[i_max]=(1-lambda);
  double min_var = CFSQP_optimize_with_constraints_and_bounds(
							      x,
							      MV_SHORT_no_assets, 
							      MV_SHORT_objective,
							      0,0,0,2,                         // 2 linear equality constraints
							      MV_SHORT_constraints, 
							      x_min,
							      x_max);
  for (i=0; i<MV_SHORT_no_assets; ++i) {
    w.element(i,0)=x[i]; 
  };
  delete [] x;
  delete [] x_min;
  delete [] x_max;
  w.Release();
  return w;
};

 



next up previous contents index
Next: Term Structure algorithms. Up: Mean Variance Analysis. Previous: Mean variance portfolios.   Contents   Index
Bernt Arne Odegaard
1999-09-09