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
