Formulating the Model
 
 This section offers one approach to formulating the initial real-world problem as a Mosel model. Even if you are not a Mosel expert, this model is simple enough for you to be able to glean its intent if you have some programming experience.  
 
|   | 
      Note The following code fragment contains line numbers, so that they can be referenced in the subsequent commentary. 
      Code Samples contains a listing of the same model without line numbers, should you wish to cut and paste the code into your own editor. This file is also available as 
      foliodata.mos from 
      https://examples.xpress.fico.com/example.pl?id=mosel_model_10. 
      | 
01: model "Portfolio optimization with LP"
02:  uses "mmxprs"             ! Use Xpress-Optimizer
03: 
04:  parameters
05:   DATAFILE= "folio.dat"    ! File with problem data
06:   OUTFILE= "result.dat"    ! Output file
07:   MAXRISK = 1/3            ! Max. investment into high-risk values
08:   MAXVAL = 0.3             ! Max. investment per share
09:   MINAM = 0.5              ! Min. investment into N.-American values
10:  end-parameters
11: 
12:  declarations
13:   SHARES: set of string        ! Set of shares
14:   RISK: set of string          ! Set of high-risk values among shares
15:   NA: set of string            ! Set of shares issued in N.-America
16:   RET: array(SHARES) of real   ! Estimated return in investment
17:  end-declarations
18: 
19:  initializations from DATAFILE
20:   RISK RET NA
21:  end-initializations
22: 
23:  declarations
24:   frac: array(SHARES) of mpvar ! Fraction of capital used per share
25:  end-declarations
26: 
27: ! Objective: total return
28:  Return:= sum(s in SHARES) RET(s)*frac(s) 
29: 
30: ! Limit the percentage of high-risk values
31:  sum(s in RISK) frac(s) <= MAXRISK
32: 
33: ! Minimum amount of North-American values
34:  sum(s in NA) frac(s) >= MINAM
35: 
36: ! Spend all the capital
37:  sum(s in SHARES) frac(s) = 1
38:  
39: ! Upper bounds on the investment per share
40:  forall(s in SHARES) frac(s) <= MAXVAL
41: 
42: ! Solve the problem
43:  maximize(Return)
44: 
45: ! Solution printing to a file
46:  fopen(OUTFILE, F_OUTPUT)
47:  writeln("Total return: ", getobjval)
48:  forall(s in SHARES) 
49:   writeln(strfmt(s,-12), ": \t", strfmt(getsol(frac(s))*100,5,2), "%")
50:  fclose(F_OUTPUT) 
51:  
52: end-model 
Commentary
Lines 4-10 establish the model's runtime parameters. The specified default values can be changed for every model execution without any need to edit the model source.
Lines 12-17 and 23-25 contain the entity declarations.
  Lines 
  19-21 initialize the entities with values from a data file in text format called 
  folio.dat which as provided contains the following data: 
  
 
 ! Data file for ‘foliodata.mos’
RET: [("treasury") 5 ("hardware") 17 ("theater") 26 ("telecom") 12     
      ("brewery") 8 ("highways") 9 ("cars") 7 ("bank") 6
      ("software") 31 ("electronics") 21 ]
RISK: ["hardware" "theater" "telecom" "software" "electronics"]
NA: ["treasury" "hardware" "theater" "telecom"] Note that this file is available as 
  folio.dat from 
  https://examples.xpress.fico.com/example.pl?id=mosel_model_10 (... if you download the file, it contains a few more entities that are not used in this guide). 
 Line 28 contains an expression whose value is assigned to an entity called Return - the goal of the problem is ultimately to maximize this expression.
Lines 30-40 establish the constraints of the problem, while line 43 starts the optimization solver to maximize the value of Return.
Finally, lines 45-50 display the results of the optimization run, the output is redirected into a text file called result.dat
 
