Making the Minimum Mandatory Changes
The code sample in this section shows the effect of applying the minimal set of changes to the example code.
Within Xpress Workbench, change your
foliodata.mos file so that it now appears as:
01: (! 02: Portfolio optimization app example 03: (c) 2020 Fair Isaac Corporation. 04: !) 05: model "Portfolio Optimization" 06: version 1.0.0 07: 08: options noimplicit 09: 10: uses "mminsight" 11: uses "mmxprs" 12: 13: declarations 14: ! Constant 15: DATAFILE = "shares.csv" 16: end-declarations 17: 18: ! Declaration of the scenario data model for input and results 19: public declarations 20: ! Input entities 21: !@insight.manage input 22: !@insight.alias Maximum investment into high-risk values 23: MaxHighRisk: real 24: 25: !@insight.manage input 26: !@insight.alias Maximum investment per share 27: MaxPerShare: real 28: 29: !@insight.manage input 30: !@insight.alias Minimum investment into North-American values 31: MinNorthAmerica: real 32: 33: !@insight.manage input 34: !@insight.alias Shares 35: ShareIds: set of string 36: 37: ! Input and result entities indexed over ShareIds 38: !@insight.manage input 39: !@insight.alias Expected Return on Investment 40: !@insight.format $ 0.00 41: Shares_Return: array(ShareIds) of real 42: 43: !@insight.manage input 44: !@insight.alias High-risk value 45: Shares_HighRisk: array(ShareIds) of boolean 46: 47: !@insight.manage input 48: !@insight.alias Issued in North America 49: Shares_NorthAmerica: array(ShareIds) of boolean 50: 51: !@insight.manage result 52: !@insight.alias Investment per share 53: !@insight.format 0.0% 54: Shares_fraction: array(ShareIds) of mpvar 55: 56: ! Result entities 57: !@insight.manage result 58: !@insight.alias Total expected return on investment 59: TotalReturn: linctr 60: end-declarations 61: 62: !@doc.descr Handler for the standard LOAD execution mode 63: !@doc.descr Load input data and initialize all input entities. 64: !@insight.execmodes.LOAD 65: public procedure loaddata 66: writeln("Loading data.") 67: MaxHighRisk := 0.33 68: MaxPerShare := 0.25 69: MinNorthAmerica := 0.45 70: 71: initializations from "mmsheet.csv:skiph;" + DATAFILE 72: [Shares_Return, Shares_HighRisk, Shares_NorthAmerica] as '[A:D]' 73: end-initializations 74: 75: writeln("Loading finished.") 76: end-procedure 77: 78: !@doc.descr Handler for the standard RUN execution mode 79: !@doc.descr Create and solve model, then initialize all result entities. 80: !@insight.execmodes.RUN 81: public procedure solvemodel 82: declarations 83: LimitHighRisk, LimitNorthAmerica : linctr 84: end-declarations 85: 86: ! If running in Insight, this call will initialize the input entities with scenario data 87: insightpopulate 88: 89: ! Objective: expected total return 90: TotalReturn := sum(s in ShareIds) Shares_Return(s) * Shares_fraction(s) 91: 92: ! Limit the percentage of high-risk values 93: LimitHighRisk := 94: sum(s in ShareIds | Shares_HighRisk(s)) Shares_fraction(s) <= MaxHighRisk 95: 96: ! Minimum amount of North-American values 97: LimitNorthAmerica := 98: sum(s in ShareIds | Shares_NorthAmerica(s)) Shares_fraction(s) >= MinNorthAmerica 99: 100: ! Spend all the capital 101: sum(s in ShareIds) Shares_fraction(s) = 1 102: 103: ! Upper bounds on the investment per share 104: forall(s in ShareIds) do 105: Shares_fraction(s) <= MaxPerShare 106: end-do 107: 108: writeln('Starting optimization.') 109: 110: ! Solve optimization problem 111: insightmaximize(TotalReturn) 112: 113: writeln('Optimization finished.') 114: end-procedure 115: 116: !@doc.descr Handler for when the model is executed outside of Insight 117: !@insight.execmodes.NONE 118: public procedure standalone 119: loaddata 120: solvemodel 121: end-procedure 122: 123: ! invoke the handler procedure for the current execution mode 124: insightdispatch 125: end-model
Commentary
Line 10 loads the mminsight package.
Line 111 now contains a call to insightmaximize instead of maximize.
Lines 62-114 contain the LOAD and RUN mode code.- If Xpress Insight is loading data, then loaddata is called (line 65.)
- If it is starting a run, then solvemodel is called (line 81.)
- If neither of these is true (i.e. the model is running in non-Xpress Insight mode) then loaddata and solvemodel are called on line 118.