(!******************************************************
   Mosel Example Problems
   ======================

   file folioinsight.mos
   `````````````````````
   Modeling a small LP problem 
   to perform portfolio optimization.
   -- Insight deployment version of foliodata.mos --
   
  (c) 2012 Fair Isaac Corporation
      author: S.Heipcke, Oct. 2012, rev. Nov. 2016
*******************************************************!)

model "Portfolio optimization"
 uses "mmxprs"                       ! Use Xpress Optimizer
 uses "mminsight"                    ! Use Xpress Insight

 version 1.0.0

 parameters
  DATAFILE= "folio.dat"              ! File with problem data
  MAXRISK = 1/3                      ! Max. investment into high-risk values
  MAXVAL = 0.3                       ! Max. investment per share
  MINAM = 0.5                        ! Min. investment into N.-American values
 end-parameters

 public declarations
  SHARES: set of string              ! Set of shares
  RISK: set of string                ! Set of high-risk values among shares
  NA: set of string                  ! Set of shares issued in N.-America
  RET: array(SHARES) of real         ! Estimated return in investment
 end-declarations

 procedure readdata
  initializations from DATAFILE
    RISK RET NA
  end-initializations
 end-procedure

 case insightgetmode of
  INSIGHT_MODE_RUN: 
      insightpopulate                ! Inject scenario data
  INSIGHT_MODE_NONE:                 ! Read in data for baseline
      readdata
  INSIGHT_MODE_LOAD: do
      readdata
      exit(0)                        ! Stop here in 'load data' mode
      end-do
  else
      writeln_("Unknown run mode")
      exit(1)
 end-case

 public declarations
  frac: array(SHARES) of mpvar       ! Fraction of capital used per share
  Return, LimitRisk, LimitAM, TotalOne: linctr   ! Constraints
 end-declarations

! Objective: total return
 Return:= sum(s in SHARES) RET(s)*frac(s) 

! Limit the percentage of high-risk values
 LimitRisk:= sum(s in RISK) frac(s) <= MAXRISK

! Minimum amount of North-American values
 LimitAM:= sum(s in NA) frac(s) >= MINAM

! Spend all the capital
 TotalOne:= sum(s in SHARES) frac(s) = 1
 
! Upper bounds on the investment per share
 forall(s in SHARES) frac(s) <= MAXVAL

! Solve the problem through Insight
 insightmaximize(Return)

! Solution printing
 writeln("Total return: ", getobjval)

end-model 
