Initializing help system before first use

Dynamic package loading


Type: Portfolio optimization
Rating: 3 (intermediate)
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
File(s): foliomipusrpkg.mos, usrpkg.mos (library, compile separately), usrpkgtempl.mos (library, compile separately)
Data file(s): folio.dat


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 

usrpkg.mos
(!******************************************************
   Mosel Example Problems
   ======================

   file usrpkg.mos
   ```````````````
   Entry point template populated with user constraint definitions,  
   including addition of new variables

   Compile to file 'usrpkg.bim'   
   
  (c) 2021 Fair Isaac Corporation
      author: S.Heipcke, Apr. 2021
*******************************************************!)
package usrpkg
  uses "advmod"
    ! Any libraries loaded here also need to be loaded by the main model

 ! Entities from main model available to this package
 ! (this results in an implicit 'public' declaration of these entities)
  requirements
    Return,LimRisk: linctr
    SHARES: set of string
    frac: array(SHARES) of mpvar 
  end-requirements

  declarations
    newv: array(set of string) of mpvar
    ! It is not possible to work in the declarations with a set name stated
    ! in the 'requirements', so here we simply keep the index set unnamed
  end-declarations

  public procedure userctrdef
    ! Change a constraint definition
    settype(LimRisk, CT_GEQ)
    setcoeff(LimRisk, -0.1)

    ! Add a new set of variables and constraints
    forall(s in SHARES) create(newv(s))
    forall(s in SHARES) newv(s) is_binary
    forall(s in SHARES) indicator(1, newv(s), frac(s)>=0.1)
    sum(s in SHARES) newv(s)>=5

    ! Add new variables to the objective
    Return+=sum(s in SHARES) newv(s)
  end-procedure
end-package

usrpkgtempl.mos
(!******************************************************
   Mosel Example Problems
   ======================

   file usrpkgtempl.mos
   ````````````````````
   Entry point template for user constraint definition  
   -- Defining entry points (subroutine called by main model)
      and usable entities from the main model (requirements) --

   Compile to file 'usrpkg.bim'   
   
  (c) 2021 Fair Isaac Corporation
      author: S.Heipcke, Apr. 2021
*******************************************************!)
package usrpkg
  uses "advmod"
    ! Any libraries loaded here also need to be loaded by the main model

 ! Entities from main model available to this package 
 ! (this results in an implicit 'public' declaration of these entities)
  requirements
    Return,LimRisk: linctr
    SHARES: set of string
    frac: array(SHARES) of mpvar 
  end-requirements

  public procedure userctrdef
    writeln("Add user constraint definitions here")
  end-procedure
end-package

© 2001-2024 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.