Making the Minimum, Mandatory Changes
01: model "Portfolio optimization with LP"
02: 
03:  uses "mminsight"          ! Mandatory for Xpress insight
04:  uses "mmxprs"             ! Use Xpress-Optimizer
05: 
06:  parameters
07:   DATAFILE= "folio.dat"    ! File with problem data
08:   OUTFILE= "result.dat"    ! Output file
09:   MAXRISK = 1/3            ! Max. investment into high-risk values
10:   MAXVAL = 0.3             ! Max. investment per share
11:   MINAM = 0.5              ! Min. investment into N.-American values
12:  end-parameters
13: 
14:  declarations
15:   SHARES: set of string        ! Set of shares
16:   RISK: set of string          ! Set of high-risk values among shares
17:   NA: set of string            ! Set of shares issued in N.-America
18:   RET: array(SHARES) of real   ! Estimated return in investment
19:  end-declarations
20: 
21:  forward procedure datainput
22: 
23:  case insightgetmode of
24:   INSIGHT_MODE_LOAD: do
25:    datainput
26:    exit(0)
27:   end-do
28:   INSIGHT_MODE_RUN:
29:    insightpopulate
30:   else
31:    datainput
32:  end-case
33:  
34:  procedure datainput
35:   initializations from DATAFILE
36:    RISK RET NA
37:   end-initializations
38:  end-procedure
39: 
40:  declarations
41:   frac: array(SHARES) of mpvar ! Fraction of capital used per share
42:  end-declarations
43: 
44: ! Objective: total return
45:  Return:= sum(s in SHARES) RET(s)*frac(s) 
46: 
47: ! Limit the percentage of high-risk values
48:  sum(s in RISK) frac(s) <= MAXRISK
49: 
50: ! Minimum amount of North-American values
51:  sum(s in NA) frac(s) >= MINAM
52: 
53: ! Spend all the capital
54:  sum(s in SHARES) frac(s) = 1
55:  
56: ! Upper bounds on the investment per share
57:  forall(s in SHARES) frac(s) <= MAXVAL
58: 
59: ! Solve the problem
60:  insightmaximize(Return)
61: 
62: ! Solution printing to a file
63:  fopen(OUTFILE, F_OUTPUT)
64:  writeln("Total return: ", getobjval)
65:  forall(s in SHARES) 
66:   writeln(strfmt(s,-12), ": \t", strfmt(getsol(frac(s))*100,5,2), "%")
67:  fclose(F_OUTPUT) 
68:  
69: end-model 
Commentary
Line 3 includes the mminsight package.
Line 21 contains a forward declaration of a procedure called datainput, which has been created so that it can be invoked from a later case statement, which takes one of three code paths depending on the value of insightgetmode.
Lines 23-32 contain the LOAD mode code. If Xpress Insight is loading data, then datainput is called (line 25). If it is simply starting a run, then insightpopulate is called (line 29). If neither of these is true (i.e. the model is running in non-Xpress Insight mode) then datainput is called and execution continues with the next statements.
Lines 34-38 wrap the original initializations block as the datainput procedure so it is only run if invoked explicitly.
Line 60 now contains a call to insightmaximize instead of maximize.
A copy of this code without line numbers is available in Code Samples for you to cut and paste into your own editor.
 
