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: public 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: public 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 loads the mminsight package.
Line 21 contains a forward declaration of a procedure called datainput, which has been defined 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 (and it avoids repeating the code under the different execution modes.)
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.
© 2001-2020 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.