How to: Use Quadratic Programming to Optimize a Stock Portfolio

Solver Foundation 3.0

You can use quadratic programs to solve economics problems such as optimizing a stock portfolio. The following example demonstrates how a portfolio can be optimized for the lowest risk, given a requested rate of return, by calculating the quadratic coefficients of a regression.

To optimize a portfolio

  1. Add the following using statements to the top of the Program code file.

    using Microsoft.SolverFoundation.Common;
    using Microsoft.SolverFoundation.Services;
    using Microsoft.SolverFoundation.Solvers;

    This example is part of the QP sample included with Solver Foundation. For more information about samples, see Samples for Solver Foundation.

  2. Create a variable that counts the number of stocks in the portfolio, and then add a for loop to create an instance of an interior point solver for each iteration.

      int m = stockNames.Length;
      for (int reqIx = 0; reqIx < iterations; reqIx++) {
        InteriorPointSolver solver = new InteriorPointSolver();
        int[] allocations = new int[m];
  3. For each stock in the portfoloio, add a corresponding variable, and set the bounds to indicate the optimized quantity of the stock that should be purchased.

      for (int invest = 0; invest < m; invest++) {
        string name = stockNames[invest];
        solver.AddVariable(name, out allocations[invest]);
        solver.SetBounds(allocations[invest], 0, 1);
      int expectedReturn;
      solver.AddRow("expectedReturn", out expectedReturn);
  4. Set the bounds for the expected return of the stock portfolio. The expected return, which is a weighted linear combination of investments, must be larger than the minimum return. There is no upper limit on the expected return.

      solver.SetBounds(expectedReturn, (double) plan.Rows[reqIx]["minimum"],
  5. In the for loop, add the linear coefficient of each stock investment for each expected return. The linear coefficient is the historical mean for that investment, which is calculated by code that you can find in the full sample. The investments must add up to the value of the unity variable, that is, all the funds must be placed in an investment.

      int unity;
      solver.AddRow("Investments sum to one", out unity);
      solver.SetBounds(unity, 1, 1);
      for (int invest = m; 0 <= --invest; ) {
        solver.SetCoefficient(expectedReturn, allocations[invest], means[invest]);
        solver.SetCoefficient(unity, allocations[invest], 1);
  6. Calculate the variance of the result, which is a quadratic combination of the covariants and the stock allocations. This variance (risk) is the quadratic part of the objective to be minimized.

      int variance;
      solver.AddRow("variance", out variance);
      for (int invest = m; 0 <= --invest; ) {
        for (int jnvest = m; 0 <= --jnvest; ) {
          solver.SetCoefficient(variance, covariants[invest, jnvest], 
          allocations[invest], allocations[jnvest]);
  7. Add a goal to minimize the variance, given the linear lower bound on the requested return.

    solver.AddGoal(variance, 0, true);
  8. Solve the model by using the interior point solver and default parameters.

      InteriorPointSolverParams lpParams = new InteriorPointSolverParams();
      if (solver.Result != LinearResult.Optimal)
        return false;
  9. Show the results of solving the model.

      for (int invest = m; 0 <= --invest; ) {
        plan.Rows[reqIx][stockNames[invest]] = (double) solver.GetValue(allocations[invest]);
      plan.Rows[reqIx]["actual"] = (double) solver.GetValue(expectedReturn);
      plan.Rows[reqIx]["Std.Dev."] = Math.Sqrt((double)solver.Statistics.Primal);
  10. Press F5 to build and run the code.

  11. Click Load Data, and then click Solve.