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 Load input data and initialize all input entities 63: procedure loaddata 64: writeln("Loading data.") 65: MaxHighRisk := 0.33 66: MaxPerShare := 0.25 67: MinNorthAmerica := 0.45 68: 69: initializations from "mmsheet.csv:skiph;" + DATAFILE 70: [Shares_Return, Shares_HighRisk, Shares_NorthAmerica] as '[A:D]' 71: end-initializations 72: 73: writeln("Loading finished.") 74: end-procedure 75: 76: !@doc.descr Create and solve model, then initialize all result entities. 77: procedure solvemodel 78: declarations 79: LimitHighRisk, LimitNorthAmerica : linctr 80: end-declarations 81: 82: ! Objective: expected total return 83: TotalReturn := sum(s in ShareIds) Shares_Return(s) * Shares_fraction(s) 84: 85: ! Limit the percentage of high-risk values 86: LimitHighRisk := 87: sum(s in ShareIds | Shares_HighRisk(s)) Shares_fraction(s) <= MaxHighRisk 88: 89: ! Minimum amount of North-American values 90: LimitNorthAmerica := 91: sum(s in ShareIds | Shares_NorthAmerica(s)) Shares_fraction(s) >= MinNorthAmerica 92: 93: ! Spend all the capital 94: sum(s in ShareIds) Shares_fraction(s) = 1 95: 96: ! Upper bounds on the investment per share 97: forall(s in ShareIds) do 98: Shares_fraction(s) <= MaxPerShare 99: end-do 100: 101: writeln('Starting optimization.') 102: 103: ! Solve optimization problem 104: insightmaximize(TotalReturn) 105: 106: writeln('Optimization finished.') 107: end-procedure 108: 109: !@doc.descr Handler for the standard LOAD execution mode 110: !@doc.descr Define actions to perform in 'load' execution mode 111: !@insight.execmodes.LOAD 112: public procedure doload 113: ! Scenario is being 'loaded' through Xpress Insight 114: ! Initialize input arrays and then terminate 115: loaddata 116: end-procedure 117: 118: !@doc.descr Handler for the standard RUN execution mode 119: !@doc.descr Define actions to perform in 'run' execution mode 120: !@insight.execmodes.RUN 121: public procedure dorun 122: ! Scenario is being 'run' through Xpress Insight 123: ! Populate with Insight scenario data and then solve optimization 124: insightpopulate 125: solvemodel 126: end-procedure 127: 128: !@doc.descr Handler for the standalone (NONE) execution mode 129: !@doc.descr Define actions to perform when model is run standalone (without Xpress Insight) 130: !@insight.execmodes.NONE 131: public procedure doloadandrun 132: ! Model is being run outside of Xpress Insight, e.g. from the Mosel command-line tool 133: ! Initialize input arrays then solve optimization 134: loaddata 135: solvemodel 136: end-procedure 137: 138: ! Automatically call the procedure with annotation matching the current execution mode 139: insightdispatch 140: 141: end-model
Commentary
The following line numbers in the code perform these functions:
- Line 10 loads the mminsight package.
- Line 104 now contains a call to insightmaximize instead of maximize.
- Lines 109-116 contain the LOAD mode code.
- Lines 118-126 contain the RUN mode code.
- Lines 128-136 are executed when the code is executed outside Insight.
- Line 139 calls the procedure that matches the selected execution mode.