(!******************************************************
   Mosel Example Problems
   ======================

   file foliolps_graph.mos
   ```````````````````````
   Modeling a small LP problem 
   to perform portfolio optimization.
   -- Using string indices --
   -- Graphical representation of the solution --
   
  (c) 2017 Fair Isaac Corporation
      author: S.Heipcke, June 2017, Sep. 2017
*******************************************************!)

model "Portfolio optimization with LP - graph"
 uses "mmxprs"                       ! Use Xpress Optimizer
 uses "mmsvg"

 declarations
                                     ! Set of shares
  SHARES = {"treasury", "hardware", "theater", "telecom", "brewery", 
            "highways", "cars", "bank", "software", "electronics"}
                                     ! Set of high-risk values among shares
  RISK = {"hardware", "theater", "telecom", "software", "electronics"}
                                     ! Set of shares issued in N.-America
  NA = {"treasury", "hardware", "theater", "telecom"}
  RET: array(SHARES) of real         ! Estimated return in investment

  frac: array(SHARES) of mpvar       ! Fraction of capital used per share
 end-declarations

 RET::(["treasury", "hardware", "theater", "telecom", "brewery", "highways",
       "cars", "bank", "software", "electronics"])[5,17,26,12,8,9,7,6,31,21] 
 
! Objective: total return
 Return:= sum(s in SHARES) RET(s)*frac(s) 

! Limit the percentage of high-risk values
 sum(s in RISK) frac(s) <= 1/3

! Minimum amount of North-American values
 sum(s in NA) frac(s) >= 0.5

! Spend all the capital
 sum(s in SHARES) frac(s) = 1
 
! Upper bounds on the investment per share
 forall(s in SHARES) frac(s) <= 0.3

! Solve the problem
 maximize(Return)

! Solution printing
 writeln("Total return: ", getobjval)
 forall(s in SHARES) writeln(s, ": ", getsol(frac(s))*100, "%")  

! Solution drawing
 forall(s in SHARES) svgaddgroup("gr"+s,s)
 ttl:=0.0
 forall(s in SHARES | frac(s).sol>0) do
   svgaddpie("gr"+s, 200,200, 150, ttl, ttl+frac(s).sol)
   svgsetstyle(svggetlastobj, SVG_STROKE, SVG_GRAY)
   ttl+=frac(s).sol
 end-do

! Optionally save graphic to file
 svgsave("foliolps.svg")
 
! Set graph size 
 svgsetgraphviewbox(0,0,500,500)

! Display the graph and wait for window to be closed by the user  
 svgrefresh
 svgwaitclose("Close browser window to terminate model execution.", 1)

end-model 
