FICO
FICO Xpress Optimization Examples Repository
FICO Optimization Community FICO Xpress Optimization Home
Back to examples browserNext example

Dynamic package loading

Description
This example shows how to work with dynamic package loading in order to allow endusers to modify the definition of an optimization problem without disclosing the actual model source:
  1. Compile the package template in usrpkgtempl.mos into usrpkg.bim
  2. Compile the main model in foliomipusrpkg.mos
  3. Share the BIM files and the source of usrpkgtempl.mos with end users
  4. Compile the completed package in usrpkg.mos
  5. Run the compiled model (without recompilation) in foliomipusrpkg.bim with the new version of the package in usrpkg.bim


Source Files

Data Files





foliomipusrpkg.mos

(!******************************************************
   Mosel Example Problems
   ======================

   file foliomipusrpkg.mos
   ```````````````````````
   Modeling a small MIP problem to perform portfolio optimization.
   -- foliomip1.mos extended with an entry point for
      user constraint definition via package 'usrpkg' --
   
   This example shows how to work with dynamic package loading
   in order to allow 3rd party users to modify the definition
   of an optimization problem without disclosing the actual
   model source:

   1- Compile the package template and the main model
      (the package BIM needs to be on the search path for Mosel
      libraries, eg. as specified via the MOSEL_BIM or MOSEL_DSO
      environment variables, or contained in the 'dso' folder of
      the Xpress distribution)
          mosel comp usrpkgtempl.mos -o usrpkg.bim
          mosel comp foliomipusrpkg.mos
   2- Hand out the BIM files and the source of the package
      template to the enduser, the BIM can be run as is:
          mosel run foliomipusrpkg.bim
   3- A modified version of the package can be provided by replacing
      the package BIM file on the search path, without any need to
      recompile the main model:
          mosel comp usrpkg.mos
          mosel run foliomipusrpkg.bim

  (c) 2021 Fair Isaac Corporation
      author: S.Heipcke, Apr. 2021
*******************************************************!)

model "Portfolio optimization with MIP"
 uses "mmxprs", "advmod"
 uses "usrpkg"

 parameters
  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
  MAXNUM = 8                        ! Max. number of different assets
 end-parameters

 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

 initializations from "folio.dat"
  RISK RET NA
 end-initializations

 declarations
  frac: array(SHARES) of mpvar      ! Fraction of capital used per share
  buy: array(SHARES) of mpvar       ! 1 if asset is in portfolio, 0 otherwise
  Return,LimRisk: linctr
  LimNA, AllOne: linctr
 end-declarations

! Objective: total return
 Return:= sum(s in SHARES) RET(s)*frac(s) 

! Limit the percentage of high-risk values
 LimRisk:= sum(s in RISK) frac(s) <= MAXRISK

! Minimum amount of North-American values
 LimNA:= sum(s in NA) frac(s) >= MINAM

! Spend all the capital
 AllOne:= sum(s in SHARES) frac(s) = 1
 
! Upper bounds on the investment per share
 forall(s in SHARES) frac(s) <= MAXVAL

! Limit the total number of assets
 sum(s in SHARES) buy(s) <= MAXNUM

 forall(s in SHARES) do
  buy(s) is_binary                  ! Turn variables into binaries
  frac(s) <= buy(s)                 ! Linking the variables
 end-do

! Entry point for user constraint definition
 userctrdef       

! Uncomment this line to see the Optimizer log
! setparam("XPRS_VERBOSE",true)      ! Enable logging output

! Debugging: Display the solver problem definition
 setparam("XPRS_loadnames", true)
 loadprob(Return)
 writeprob("","l")

! Solve the problem
 maximize(Return)

! Solution printing
 writeln("Total return: ", getobjval)
 forall(s in SHARES)
  writeln(s, ": ", getsol(frac(s))*100, "% (", getsol(buy(s)), ")")
 
end-model 

Back to examples browserNext example