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