FICO
FICO Xpress Optimization Examples Repository
FICO Optimization Community FICO Xpress Optimization Home
Back to examples browserPrevious exampleNext example

Folio - Advanced modelling and solving tasks

Description
Advanced modelling and solving tasks for a portfolio optimization problem:
  • Automated solver tuning (foliolptune.mos)
  • Defining an integer solution callback (foliocb.mos, callback specification by name: foliocbm.mos; using an 'mpsol' object: foliocb_sol.mos)
  • Using the solution enumerator for multiple MIP solutions (folioenumsol.mos)
  • Handling infeasibility
    • handling infeasibility through deviation variables (folioinfeas.mos)
    • retrieving infeasible row/column from presolve (folioinfcause.mos)
    • retrieving IIS - LP, MIP, NLP infeasible (folioiis.mos, foliomiis.mos, folionliis.mos)
    • using the built-in infeasibility repair functionality (foliorep.mos)
    • same as foliorep, using an 'mpsol' object (foliorep_sol.mos)
  • Data transfer in memory
    • running foliomemio.mos with data transfer in memory (runfolio.mos)
    • same running foliomemio2.mos, grouping tables with identical index sets in "initializations" blocks (runfolio2.mos)
    • main model running several model instances in parallel (runfoliopar.mos)
  • Remote models on a distributed architecture
    • running foliomemio.mos on a remote instance of Mosel (runfoliodistr.mos)
    • main model running several model instances in parallel, each on a different (remote) instance of Mosel (runfoliopardistr.mos)
  • Remote execution via XPRD
    • See examples in the Mosel Whitepapers directory moselpar/XPRD
  • XML and JSON data formats
    • reading data from an XML file, solution output in XML format on screen and to a new file (folioxml.mos, folioxmlqp.mos)
    • generate HTML output file as an XML document (runfolioxml.mos)
    • using JSON-format data files, reading data from a JSON file, solution output in JSON format on screen and to a new file (foliojson.mos)
  • HTTP
    • starting an HTTP server managing requests from HTTP clients (foliohttpsrv.mos)
    • HTTP client exchanging XML data files with an HTTP server (foliohttpclient.mos)


Source Files

Data Files





runfolioxml.mos

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

   file runfolioxml.mos
   ````````````````````
   Main model running portfolio optimization model as submodel.

   Runs model foliomemio.mos.
   -- Data input/output in memory --
   -- Using XML module for writing HTML output --
      
  (c) 2010 Fair Isaac Corporation
      author: S.Heipcke, Sep. 2010, rev. Sep. 2012
*******************************************************!)

model "Run portfolio optimization model"
 uses "mmjobs"                       ! Use multiple model handling
 uses "mmsystem", "mmxprs"
 uses "mmxml"

 parameters
  MODELFILE = "foliomemio.mos"       ! Optimization model
  INPUTFILE = "folio10.dat"          ! File with problem data
 
  MAXRISK = 1/3                      ! Max. investment into high-risk values
  MINREG = 0.2                       ! Min. investment per geogr. region
  MAXREG = 0.5                       ! Max. investment per geogr. region
  MAXSEC = 0.25                      ! Max. investment per ind. sector
  MAXVAL = 0.2                       ! Max. investment per share
  MINVAL = 0.1                       ! Min. investment per share
  MAXNUM = 15                        ! Max. number of different assets
 end-parameters
 
 forward procedure write_html_results

 declarations
  SHARES: set of string              ! Set of shares
  RISK: set of string                ! Set of high-risk values among shares
  REGIONS: set of string             ! Geographical regions
  TYPES: set of string               ! Share types (ind. sectors)
  LOCTAB: dynamic array(REGIONS,SHARES) of boolean ! Shares per geogr. region
  RET: array(SHARES) of real         ! Estimated return in investment
  SECTAB: dynamic array(TYPES,SHARES) of boolean ! Shares per industry sector

  returnsol: real                    ! Solution values
  numsharessol,status: integer
  fracsol: array(SHARES) of real     ! Fraction of capital used per share
  buysol: array(SHARES) of real      ! 1 if asset is in portfolio, 0 otherwise

  foliomod: Model
 end-declarations

! Compile and load the optimization model
 if compile("", MODELFILE, "shmem:bim") <> 0 then
  writeln("Error during model compilation")
  exit(1)
 end-if
 load(foliomod, "shmem:bim")
 fdelete("shmem:bim")

! Read in data from file
 initializations from INPUTFILE
  RISK RET LOCTAB SECTAB
 end-initializations

! Save data to memory
 initializations to "raw:"
  RISK as 'shmem:RISK'
  RET as 'shmem:RET'
  LOCTAB as 'shmem:LOCTAB'
  SECTAB as 'shmem:SECTAB'
 end-initializations

 run(foliomod, "MAXRISK=" + MAXRISK + ",MINREG=" + MINREG + 
  ",MAXREG=" + MAXREG + ",MAXSEC=" + MAXSEC +
  ",MAXVAL=" + MAXVAL + ",MINVAL=" + MINVAL +
  ",MAXNUM=" + MAXNUM + ",DATAFILE='raw:',OUTPUTFILE='raw:'," +
  "RISKDATA='shmem:RISK',RETDATA='shmem:RET',LOCDATA='shmem:LOCTAB'," +
  "SECDATA='shmem:SECTAB',FRACSOL='shmem:FRAC',BUYSOL='shmem:BUY'," +
  "NUMSHARES='shmem:NUMSHARES',RETSOL='shmem:RETSOL'," +
  "SOLSTATUS='shmem:SOLSTATUS'")
  wait                              ! Wait for model termination
  dropnextevent                     ! Ignore termination event message

 initializations from  "raw:"
  returnsol as 'shmem:RETSOL'
  numsharessol as 'shmem:NUMSHARES'
  fracsol as 'shmem:FRAC'
  buysol as 'shmem:BUY'
  status as 'shmem:SOLSTATUS'
 end-initializations

 case status of
  XPRS_OPT: writeln("Problem solved to optimality")
  XPRS_UNF: writeln("Problem solving unfinished")
  XPRS_INF: writeln("Problem is infeasible")
  XPRS_UNB,XPRS_OTH:  writeln("No solution available")
 end-case 

 ! Solution printing
 writeln("Total return: ", returnsol)
 writeln("Number of shares: ", numsharessol)
 forall(s in SHARES | fracsol(s)>0)
  writeln(s, ": ", fracsol(s)*100, "% (", buysol(s), ")")
 
 write_html_results

! *********** Writing an HTML result file ***********
 procedure write_html_results
  declarations
   OutputData: xmldoc
   Root, Head, Body, Style, Title, Table, Row, Cell: integer
  end-declarations

  setparam("datetimefmt", "%0d-%N-%y, %0H:%0M:%0S")

  Root:= addnode(OutputData, 0, XML_ELT, "html")
  Head:= addnode(OutputData, Root, XML_ELT, "head")
  Style:= addnode(OutputData, Head, XML_ELT, "style",
    "body {font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; color: 000055 }\n" +
    "table td {background-color: ffffaa; text-align: left }\n" +
    "table th {background-color: 053055; color: ffcc88}")
  setattr(OutputData, Style, "type", "text/css")
 
  Body:= addnode(OutputData, Root, XML_LASTCHILD, XML_ELT, "body")
  TitleCenter:= addnode(OutputData, Body, XML_ELT, "center")
  Title:= addnode(OutputData, TitleCenter, XML_ELT, "h2", 
              "Portfolio Optimization Results")

  Table:= addnode(OutputData, Body, XML_ELT, "table")
    setattr(OutputData, Table, "width", '100%')
    setattr(OutputData, Table, "cellpadding", '5')
    setattr(OutputData, Table, "cellspacing", '0')
    setattr(OutputData, Table, "border", 0)
  Row:= addnode(OutputData, Table, XML_ELT, "tr")
  Cell:= addnode(OutputData, Row, XML_ELT, "td", "Total return: " + returnsol)
    setattr(OutputData, Cell, "width", '55%')
    setattr(OutputData, Cell, "style", 'color: #8B4513; font-weight: bold;')
  Cell:= addnode(OutputData, Row, XML_LASTCHILD, XML_ELT, "td",
              "Problem instance: " + INPUTFILE)
    setattr(OutputData, Cell, "style", 'color: #8B4513; font-weight: bold;')
  Row:= addnode(OutputData, Table, XML_LASTCHILD, XML_ELT, "tr")
  Cell:= addnode(OutputData, Row, XML_ELT, "td",
                     "Number of shares: " + numsharessol)
    setattr(OutputData, Cell, "style", 'color: #000055; font-weight: bold;')
  Cell:= addnode(OutputData, Row, XML_LASTCHILD, XML_ELT, "td",
              "Date: " + datetime(SYS_NOW))
    setattr(OutputData, Cell, "style", 'color: #8B4513; font-weight: bold;')
  Row:= addnode(OutputData, Table, XML_LASTCHILD, XML_ELT, "tr")
  Cell:= addnode(OutputData, Row, XML_ELT, "td")
    setattr(OutputData, Cell, "colspan", 2)
  CellEmpty:= addnode(OutputData, Cell, XML_ELT, "br")

  Table:= addnode(OutputData, Body, XML_LASTCHILD, XML_ELT, "table")
    setattr(OutputData, Table, "width", '100%')
    setattr(OutputData, Table, "cellpadding", '2')
    setattr(OutputData, Table, "cellspacing", '1')
  Row:= addnode(OutputData, Table, XML_ELT, "tr")
  Cell:= addnode(OutputData, Row, XML_ELT, "th", "Value")
  Cell:= addnode(OutputData, Row, XML_LASTCHILD, XML_ELT, "th", "Percentage")
  forall(s in SHARES | fracsol(s)>0) do
    Row:= addnode(OutputData, Table, XML_LASTCHILD, XML_ELT, "tr")
    Cell:= addnode(OutputData, Row, XML_ELT, "td", s)
    Cell:= addnode(OutputData, Row, XML_LASTCHILD, XML_ELT, "td", 
             textfmt(fracsol(s)*100,4,2) + "%")
  end-do

  HTMLFILE:= INPUTFILE + "_sol.html"
  save(OutputData, HTMLFILE)           ! Write the XML file

 end-procedure

end-model

Back to examples browserPrevious exampleNext example