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





foliojson.mos

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

   file foliojson.mos
   ``````````````````
   Modeling a small LP problem 
   to perform portfolio optimization.
   -- Reading/writing data in JSON format --
   
  (c) 2014 Fair Isaac Corporation
      author: S.Heipcke, Sep. 2014
*******************************************************!)

model "Portfolio optimization with LP"
 uses "mmxprs"
 uses "mmxml"                        ! XML/JSON interface functions

 parameters
  DATAFILE= "folio.json"             ! File with problem data
  OUTFILE= "result.json"             ! Output file
  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

 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

  AllData, ResData: xmldoc           ! XML document
  Share,Root,Sol: integer            ! XML nodes
  NodeList: list of integer
 end-declarations

! Reading data from a JSON file
 jsonload(AllData, DATAFILE)


 getnodes(AllData, "jsv/share/jsv", NodeList) 
 RISK:= union(l in NodeList | 
              getvalue(AllData,getnode(AllData,l,"risk"))="high") 
         {getstrvalue(AllData,getnode(AllData,l,"name"))} 

 NA:= union(l in NodeList | 
              getvalue(AllData,getnode(AllData,l,"region"))="NA") 
         {getstrvalue(AllData,getnode(AllData,l,"name"))} 

(! Alternatively:
 getnodes(AllData, "jsv/share/jsv/risk[string()='high']/../name", NodeList)
 RISK:=union(r in NodeList) {getstrvalue(AllData,r)}
 getnodes(AllData, "jsv/share/jsv/region[string()='NA']/../name", NodeList)
 NA:=union(r in NodeList) {getstrvalue(AllData,r)}
 getnodes(AllData, "jsv/share/jsv", NodeList) 
!)

 forall(l in NodeList)
   RET(getstrvalue(AllData,getnode(AllData,l,"name"))):= 
     getintvalue(AllData,getnode(AllData,l,"ret")) 


(! Reading alternative data format 'share2':
 getnodes(AllData, "jsv/share2/jsv/jsv[position()=6 and string()='high']/..",
   NodeList)
 RISK:= union(r in NodeList) 
   {getstrvalue(AllData,getnode(AllData,r,"jsv[position()=1]"))}
 getnodes(AllData, "jsv/share2/jsv/jsv[position()=5 and string()='NA']/..",
   NodeList)
 NA:= union(r in NodeList) 
   {getstrvalue(AllData,getnode(AllData,r,"jsv[position()=1]"))}
 getnodes(AllData, "jsv/share2/jsv", NodeList) 
 forall(l in NodeList)
   RET(getstrvalue(AllData,getnode(AllData,l,"jsv[position()=1]"))):= 
     getintvalue(AllData,getnode(AllData,l,"jsv[position()=2]"))  
!)

 declarations
  frac: array(SHARES) of mpvar       ! Fraction of capital used per share
 end-declarations

! 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) <= MAXRISK

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

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

! Solve the problem
 maximize(Return)

! Solution printing
 writeln("Total return: ", getobjval)
 forall(s in SHARES) 
  writeln(strfmt(s,-12), ": \t", strfmt(getsol(frac(s))*100,5,2), "%")


! Create solution representation in JSON format
 Root:=addnode(ResData, 0, XML_ELT, "jsv")         ! Create root node
 Sol:= addnode(ResData, Root, XML_ELT, "solution") ! Add a "solution" node
 n:=addnode(ResData, Sol, "value", getobjval)      ! ... with child "value"
 Share:= addnode(ResData, Sol, XML_ELT, "share")   ! Add a node to "solution"
 forall(s in SHARES)
   n:=addnode(ResData, Share, s,frac(s).sol)       ! Add a node to "share"
 
 jsonsave(ResData, OUTFILE)        ! Save solution to JSON format file
 jsonsave(ResData, Sol, "")        ! Display JSON format solution on screen
 save(ResData, Sol, "")            ! Display XML format solution on screen
end-model 

Back to examples browserPrevious exampleNext example