The OPTQP Procedure

Example 7.3 Portfolio Selection with Transactions

Consider a portfolio selection problem with a slight modification. You are now required to take into account the current position and transaction costs associated with buying and selling assets. The objective is to find the minimum variance portfolio. In order to understand the scenario better, consider the following data.

You are given three assets. The current holding of the three assets is denoted by the vector bold c = [200, 300, 500], the amount of asset bought and sold is denoted by b Subscript i and s Subscript i, respectively, and the net investment in each asset is denoted by x Subscript i and is defined by the following relation:

x Subscript i Baseline minus b Subscript i Baseline plus s Subscript i Baseline equals c Subscript i Baseline comma i equals 1 comma 2 comma 3

Suppose that you pay a transaction fee of 0.01 every time you buy or sell. Let the covariance matrix script upper C be defined as

StartLayout 1st Row 1st Column script upper C 2nd Column equals 3rd Column Start 3 By 3 Matrix 1st Row 1st Column 0.027489 2nd Column negative 0.00874 3rd Column negative 0.00015 2nd Row 1st Column negative 0.00874 2nd Column 0.109449 3rd Column negative 0.00012 3rd Row 1st Column negative 0.00015 2nd Column negative 0.00012 3rd Column 0.000766 EndMatrix EndLayout

Assume that you hope to obtain at least 12% growth. Let bold r = [1.109048, 1.169048, 1.074286] be the vector of expected return on the three assets, and let script upper B=1000 be the available funds. Mathematically, this problem can be written in the following manner:

StartLayout 1st Row 1st Column min 2nd Column 0.027489 x 1 squared minus 0.01748 x 1 x 2 minus 0.0003 x 1 x 3 plus 0.109449 x 2 squared 2nd Row 1st Column Blank 2nd Column minus 0.00024 x 2 x 3 plus 0.000766 x 3 squared EndLayout
StartLayout 1st Row 1st Column normal s normal u normal b normal j normal e normal c normal t normal t normal o 2nd Column Blank 3rd Column Blank 4th Column Blank 5th Column Blank 2nd Row 1st Column left-parenthesis normal r normal e normal t normal u normal r normal n right-parenthesis 2nd Column sigma-summation Underscript i equals 1 Overscript 3 Endscripts r Subscript i Baseline x Subscript i 3rd Column greater-than-or-equal-to 4th Column 1.12 script upper B 5th Column Blank 3rd Row 1st Column left-parenthesis normal b normal u normal d normal g normal e normal t right-parenthesis 2nd Column sigma-summation Underscript i equals 1 Overscript 3 Endscripts x Subscript i plus sigma-summation Underscript i equals 1 Overscript 3 Endscripts 0.01 left-parenthesis b Subscript i Baseline plus s Subscript i Baseline right-parenthesis 3rd Column equals 4th Column script upper B 5th Column Blank 4th Row 1st Column left-parenthesis normal b normal a normal l normal a normal n normal c normal e right-parenthesis 2nd Column x Subscript i Baseline minus b Subscript i plus s Subscript i 3rd Column equals 4th Column c Subscript i Baseline comma 5th Column i equals 1 comma 2 comma 3 5th Row 1st Column Blank 2nd Column x Subscript i Baseline comma b Subscript i Baseline comma s Subscript i Baseline 3rd Column greater-than-or-equal-to 4th Column 0 comma 5th Column i equals 1 comma 2 comma 3 EndLayout

The QPS-format input data set is as follows:

data potrdata;
   input field1 $ field2 $ field3 $ field4 field5 $ field6 @;
datalines;
NAME    .         POTRAN    .            .          .
ROWS    .         .         .            .          .
N       OBJ.FUNC  .         .            .          .
G       RETURN    .         .            .          .
E       BUDGET    .         .            .          .
E       BALANC1   .         .            .          .
E       BALANC2   .         .            .          .
E       BALANC3   .         .            .          .
COLUMNS .         .         .            .          .
.       X1        RETURN    1.109048     BUDGET     1.0
.       X1        BALANC1   1.0          .          .
.       X2        RETURN    1.169048     BUDGET     1.0
.       X2        BALANC2   1.0          .          .
.       X3        RETURN    1.074286     BUDGET     1.0
.       X3        BALANC3   1.0          .          .
.       B1        BUDGET    .01          BALANC1   -1.0
.       B2        BUDGET    .01          BALANC2   -1.0
.       B3        BUDGET    .01          BALANC3   -1.0
.       S1        BUDGET    .01          BALANC1    1.0
.       S2        BUDGET    .01          BALANC2    1.0
.       S3        BUDGET    .01          BALANC3    1.0
RHS     .         .         .            .          .
.       RHS       RETURN    1120         .          .
.       RHS       BUDGET    1000         .          .
.       RHS       BALANC1   200          .          .
.       RHS       BALANC2   300          .          .
.       RHS       BALANC3   500          .          .
RANGES  .         .         .            .          .
BOUNDS  .         .         .            .          .
QUADOBJ .         .         .            .          .
.       X1        X1        0.054978     .          .
.       X1        X2        -.01748      .          .
.       X1        X3        -.0003       .          .
.       X2        X2        0.218898     .          .
.       X2        X3        -.00024      .          .
.       X3        X3        0.001532     .          .
ENDATA  .         .         .            .          .
;

Use the following SAS statements to solve the problem:

data mylib.potrdata;
   set potrdata;
   _id_ = _n_;
run;
proc optqp data = mylib.potrdata
  printlevel = 0
  primalout = mylib.potrpout
  dualout   = mylib.potrdout;
run;

The optimal solution is displayed in Output 7.3.1.

Output 7.3.1: Portfolio Selection with Transactions

The OPTQP Procedure
Primal Solution

ObsObjective Function IDRHS IDVariable
Name
Variable
Type
Linear
Objective
Coefficient
Lower
Bound
Upper BoundVariable ValueVariable
Status
1OBJ.FUNCRHSX1N001.7977E308397.584O
2OBJ.FUNCRHSX2N001.7977E308406.115O
3OBJ.FUNCRHSX3N001.7977E308190.165O
4OBJ.FUNCRHSB1N001.7977E308197.584O
5OBJ.FUNCRHSB2N001.7977E308106.115O
6OBJ.FUNCRHSB3N001.7977E3080.000O
7OBJ.FUNCRHSS1N001.7977E3080.000O
8OBJ.FUNCRHSS2N001.7977E3080.000O
9OBJ.FUNCRHSS3N001.7977E308309.835O


Last updated: September 09, 2026