foliomip3.mos |
(!******************************************************
Mosel Example Problems
======================
file foliomip3.mos
``````````````````
Modeling a MIP problem
to perform portfolio optimization.
-- Extending the problem with constraints on
the geographical and sectorial distributions --
-- Working with a larger data set --
*** This model cannot be run with a Community Licence
for the provided data instance ***
(c) 2008 Fair Isaac Corporation
author: S.Heipcke, Dec. 2008
*******************************************************!)
model "Portfolio optimization with MIP"
uses "mmxprs"
parameters
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 = 7 ! Max. number of different assets
! 6,7: difficult, 4: infeas, 5,8+:easy
DATAFILE = "folio250.dat" ! File with problem data
end-parameters
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)
LOC: array(REGIONS) of set of string ! Sets of shares per geogr. region
RET: array(SHARES) of real ! Estimated return in investment
SEC: array(TYPES) of set of string ! Sets of shares per industry sector
end-declarations
initializations from DATAFILE
RISK RET LOC SEC
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
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
! Limits on geographical distribution
forall(r in REGIONS) do
sum(s in LOC(r)) frac(s) >= MINREG
sum(s in LOC(r)) frac(s) <= MAXREG
end-do
! Diversification across industry sectors
forall(t in TYPES) sum(s in SEC(t)) frac(s) <= MAXSEC
! 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
! 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) <= MAXVAL*buy(s) ! Linking the variables
frac(s) >= MINVAL*buy(s) ! Linking the variables
end-do
! Display Optimizer log
setparam("XPRS_verbose", true)
! Solve the problem
maximize(Return)
! Solution printing
writeln("Total return: ", getobjval)
forall(s in SHARES | getsol(frac(s))>0)
writeln(s, ": ", getsol(frac(s))*100, "% (", getsol(buy(s)), ")")
end-model
|
|
foliomemio.mos |
(!******************************************************
Mosel Example Problems
======================
file foliomemio.mos
```````````````````
Modeling a MIP problem
to perform portfolio optimization.
Same model as in foliomip3.mos with
simplified data structures (replaced arrays of structured types).
-- Data input/output in memory --
Run modes for this model:
1. Stand-alone: data I/O to text files
(run this model from Workbench or from Mosel command line)
2. Submodel to another Mosel model: data exchange in memory
(run model 'runfolio.mos' or 'runfoliopar.mos' to execute this model)
3a. C: I/O to C program runfolio.c or runfoliod.c
(compile and run C program 'runfolio.c' or 'runfoliod.c')
3b. Java: I/O to Java program runfolio.java, runfoliob.java, or
runfoliod.java
(compile and run Java program 'runfolio.java', 'runfoliob.java',
or 'runfoliod.java')
3c. (Windows only) C#: I/O to C# program runfolio.cs or runfoliob.cs
(compile and run C# program 'runfolio.cs' or 'runfoliob.cs')
4. Remote execution from another Mosel model:
(run model 'runfoliodistr.mos' or 'runfoliopardistr.mos' to execute
this model)
5a. Remote execution from C: I/O to C program distfolio.c or distfoliopar.c
(compile and run C program 'distfolio.c' or 'distfoliopar.c')
5b. Remote execution from Java: I/O to Java program distfolio.java or
distfoliopar.java
(compile and run Java program 'distfolio.java' or 'distfoliopar.java')
(c) 2009 Fair Isaac Corporation
author: S.Heipcke, Jan. 2009, rev. Sep. 2018
*******************************************************!)
model "Portfolio optimization with MIP"
uses "mmxprs"
parameters
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
DATAFILE = "folio10.dat" ! File with problem data
OUTPUTFILE = "sol10out.dat" ! File for solution output
RISKDATA = "RISK" ! Locations of input data
RETDATA = "RET"
LOCDATA = "LOCTAB"
SECDATA = "SECTAB"
FRACSOL = "FRAC" ! Locations for solution output
BUYSOL = "BUY"
NUMSHARES = "NUMSHARES"
RETSOL = "RETSOL"
SOLSTATUS = "SOLSTATUS"
end-parameters
declarations
SHARES,S: 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
end-declarations
initializations from DATAFILE
RISK as RISKDATA
RET as RETDATA
LOCTAB as LOCDATA
SECTAB as SECDATA
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
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
! Limits on geographical distribution
forall(r in REGIONS) do
sum(s in SHARES | exists(LOCTAB(r,s))) frac(s) >= MINREG
sum(s in SHARES | exists(LOCTAB(r,s))) frac(s) <= MAXREG
end-do
! Diversification across industry sectors
forall(t in TYPES) sum(s in SHARES | exists(SECTAB(t,s))) frac(s) <= MAXSEC
! 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
! 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) <= MAXVAL*buy(s) ! Linking the variables
frac(s) >= MINVAL*buy(s) ! Linking the variables
end-do
! Display Optimizer log
setparam("XPRS_verbose", true)
! Solve the problem
maximize(Return)
! Adapt Mosel comparison tolerance to Optimizer feasibility tolerance
setparam("zerotol", getparam("XPRS_feastol")/10)
! Solution output
function getvalues(v: array(SHARES) of mpvar): dynamic array(S) of real
forall(s in SHARES | v(s).sol<>0) returned(s):= v(s).sol
end-function
initializations to OUTPUTFILE
evaluation of Return.sol as RETSOL
evaluation of sum(s in SHARES | buy(s).sol<>0) 1 as NUMSHARES
evaluation of getvalues(frac) as FRACSOL
evaluation of getvalues(buy) as BUYSOL
evaluation of getprobstat as SOLSTATUS
end-initializations
end-model
|
|
foliomemio2.mos |
(!******************************************************
Mosel Example Problems
======================
file foliomemio2.mos
````````````````````
Modeling a MIP problem
to perform portfolio optimization.
Same model as in foliomip3.mos with
simplified data structures (replaced arrays of structured types).
-- Data input/output in memory --
-- Grouping arrays with identical index sets --
Run modes for this model:
1. Stand-alone: data I/O to text files
(run this model from Workbench or from Mosel command line)
2. Submodel to another Mosel model: data exchange in memory
(run model 'runfolio2.mos' to execute this model)
3a. C: I/O to C program folio2.c
(compile and run C program 'folio2.c')
3b. Java: I/O to Java program folio2.java
(compile and run Java program 'folio2.java')
3c. C# (Windows only): I/O to C# program folio2.cs
(compile and run C# program 'folio2.cs')
(c) 2009 Fair Isaac Corporation
author: S.Heipcke, Feb. 2009, rev. Sep. 2018
*******************************************************!)
model "Portfolio optimization with MIP"
uses "mmxprs"
parameters
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
DATAFILE = "folio10.dat" ! File with problem data
OUTPUTFILE = "sol10out.dat" ! File for solution output
RISKDATA = "RISK" ! Locations of input data
RETDATA = "RET"
LOCDATA = "LOCTAB"
SECDATA = "SECTAB"
FRACBUYSOL = "FRACBUY" ! Locations for solution output
NUMSHARES = "NUMSHARES"
RETSOL = "RETSOL"
SOLSTATUS = "SOLSTATUS"
end-parameters
declarations
SHARES,S: 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
end-declarations
initializations from DATAFILE
RISK as RISKDATA
RET as RETDATA
LOCTAB as LOCDATA
SECTAB as SECDATA
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
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
! Limits on geographical distribution
forall(r in REGIONS) do
sum(s in SHARES | exists(LOCTAB(r,s))) frac(s) >= MINREG
sum(s in SHARES | exists(LOCTAB(r,s))) frac(s) <= MAXREG
end-do
! Diversification across industry sectors
forall(t in TYPES) sum(s in SHARES | exists(SECTAB(t,s))) frac(s) <= MAXSEC
! 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
! 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) <= MAXVAL*buy(s) ! Linking the variables
frac(s) >= MINVAL*buy(s) ! Linking the variables
end-do
! Display Optimizer log
setparam("XPRS_verbose", true)
! Solve the problem
maximize(Return)
! Adapt Mosel comparison tolerance to Optimizer feasibility tolerance
setparam("zerotol", getparam("XPRS_feastol")/10)
! Solution output
function getvalues(v: array(SHARES) of mpvar): dynamic array(S) of real
forall(s in SHARES | v(s).sol<>0) returned(s):= v(s).sol
end-function
initializations to OUTPUTFILE
evaluation of Return.sol as RETSOL
evaluation of sum(s in SHARES | buy(s).sol<>0) 1 as NUMSHARES
[evaluation of getvalues(frac) , evaluation of getvalues(buy)] as FRACBUYSOL
evaluation of getprobstat as SOLSTATUS
end-initializations
end-model
|
|
foliocbio.mos |
(!******************************************************
Mosel Example Problems
======================
file foliocbio.mos
``````````````````
Modeling a MIP problem
to perform portfolio optimization.
Same model as in foliomip3.mos.
-- Defining an integer solution callback
to write out solution information to external program --
*** This model cannot be run with a Community Licence
for the provided data instance ***
(c) 2011 Fair Isaac Corporation
author: S.Heipcke, July 2011, rev. Sep. 2018
*******************************************************!)
model "Portfolio optimization with MIP"
uses "mmxprs"
uses "mmjobs"
parameters
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
DATAFILE = "folio250.dat" ! File with problem data
OUTPUTFILE = "sol10out.dat" ! File for solution output
FRACSOL = "FRAC" ! Locations for solution output
BUYSOL = "BUY"
NUMSHARES = "NUMSHARES"
RETSOL = "RETSOL"
SOLCOUNT = "SOLCOUNT"
end-parameters
forward public procedure printsol
declarations
SHARES,S: 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)
LOC: array(REGIONS) of set of string ! Sets of shares per geogr. region
RET: array(SHARES) of real ! Estimated return in investment
SEC: array(TYPES) of set of string ! Sets of shares per industry sector
end-declarations
initializations from DATAFILE
RISK RET LOC SEC
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
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
! Limits on geographical distribution
forall(r in REGIONS) do
sum(s in LOC(r)) frac(s) >= MINREG
sum(s in LOC(r)) frac(s) <= MAXREG
end-do
! Diversification across industry sectors
forall(t in TYPES) sum(s in SEC(t)) frac(s) <= MAXSEC
! 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
! 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) <= MAXVAL*buy(s) ! Linking the variables
frac(s) >= MINVAL*buy(s) ! Linking the variables
end-do
! Display Optimizer log
setparam("XPRS_verbose", true)
! Adapt Mosel comparison tolerance to Optimizer feasibility tolerance
setparam("zerotol", getparam("XPRS_feastol")/10)
! Set a MIP solution callback
setcallback(XPRS_CB_INTSOL, "printsol")
! Solve the problem
maximize(Return)
if getprobstat <> XPRS_OPT then exit(1); end-if
!******** Solution output********
!**** Auxiliary function creating an array of solution values ****
function getvalues(v: array(SHARES) of mpvar): dynamic array(S) of real
forall(s in SHARES | v(s).sol<>0) returned(s):= v(s).sol
end-function
!**** Definition of the MIP solution callback function ****
public procedure printsol
initializations to OUTPUTFILE
evaluation of getparam("XPRS_MIPSOLS") as SOLCOUNT
evaluation of sum(s in SHARES | buy(s).sol<>0) 1 as NUMSHARES
evaluation of getsol(Return) as RETSOL
evaluation of getvalues(frac) as FRACSOL
evaluation of getvalues(buy) as BUYSOL
end-initializations
end-procedure
end-model
|
|
foliocb.mos |
(!******************************************************
Mosel Example Problems
======================
file foliocb.mos
````````````````
Modeling a MIP problem
to perform portfolio optimization.
Same model as in foliomip3.mos.
-- Defining an integer solution callback --
*** This model cannot be run with a Community Licence
for the provided data instance ***
(c) 2008 Fair Isaac Corporation
author: S.Heipcke, Dec. 2008
*******************************************************!)
model "Portfolio optimization with MIP"
uses "mmxprs"
parameters
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
DATAFILE = "folio250.dat" ! File with problem data
end-parameters
forward public procedure printsol
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)
LOC: array(REGIONS) of set of string ! Sets of shares per geogr. region
RET: array(SHARES) of real ! Estimated return in investment
SEC: array(TYPES) of set of string ! Sets of shares per industry sector
end-declarations
initializations from DATAFILE
RISK RET LOC SEC
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
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
! Limits on geographical distribution
forall(r in REGIONS) do
sum(s in LOC(r)) frac(s) >= MINREG
sum(s in LOC(r)) frac(s) <= MAXREG
end-do
! Diversification across industry sectors
forall(t in TYPES) sum(s in SEC(t)) frac(s) <= MAXSEC
! 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
! 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) <= MAXVAL*buy(s) ! Linking the variables
frac(s) >= MINVAL*buy(s) ! Linking the variables
end-do
! Display Optimizer log
setparam("XPRS_verbose", true)
! Set a MIP solution callback
setcallback(XPRS_CB_INTSOL, "printsol")
! Solve the problem
maximize(Return)
! Solution printing
public procedure printsol
writeln("Solution ", getparam("XPRS_MIPSOLS"))
! Attention: 'getobjval' cannot be used during the optimization run
! writeln("Total return: ", getparam("XPRS_MIPOBJVAL"))
writeln("Total return: ", getsol(Return))
forall(s in SHARES | getsol(frac(s))>0)
writeln(s, ": ", getsol(frac(s))*100, "% (", getsol(buy(s)), ")")
end-procedure
end-model
|
|
folioenumsol.mos |
(!******************************************************
Mosel Example Problems
======================
file folioenumsol.mos
`````````````````````
Modeling a MIP problem
to perform portfolio optimization.
Same model as in foliomip3.mos.
-- Using the solution enumerator --
(c) 2008 Fair Isaac Corporation
author: S.Heipcke, Dec. 2008, rev. Jan. 2013
*******************************************************!)
model "Portfolio optimization with MIP"
uses "mmxprs"
parameters
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 = 7 ! Max. number of different assets
DATAFILE = "folio10.dat" ! File with problem data
end-parameters
forward procedure print_sol
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)
LOC: array(REGIONS) of set of string ! Sets of shares per geogr. region
RET: array(SHARES) of real ! Estimated return in investment
SEC: array(TYPES) of set of string ! Sets of shares per industry sector
end-declarations
initializations from DATAFILE
RISK RET LOC SEC
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
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
! Limits on geographical distribution
forall(r in REGIONS) do
sum(s in LOC(r)) frac(s) >= MINREG
sum(s in LOC(r)) frac(s) <= MAXREG
end-do
! Diversification across industry sectors
forall(t in TYPES) sum(s in SEC(t)) frac(s) <= MAXSEC
! 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
! 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) <= MAXVAL*buy(s) ! Linking the variables
frac(s) >= MINVAL*buy(s) ! Linking the variables
end-do
! Remove doubles from the solution pool, comparing solutions on their
! discrete variables only
setparam("XPRS_ENUMDUPLPOL",3)
! Alternatively: switch off MIP heuristics to avoid generation of doubles
! setparam("XPRS_HEURSTRATEGY", 0)
! Disable presolve operations that attempt to improve the efficiency by
! cutting off MIP solutions from the feasible region
presolveops:= getparam("XPRS_PRESOLVEOPS")
if bittest(presolveops,32)=32 then presolveops-=32; end-if
! Disable duplicate column removal
if bittest(presolveops,8)=8 then presolveops-=8; end-if
! Disable dual reduction operations
setparam("XPRS_PRESOLVEOPS", presolveops)
presolveops:= getparam("XPRS_MIPPRESOLVE")
if bittest(presolveops,16)=16 then presolveops-=16; end-if
! Disable in-tree dual reductions
setparam("XPRS_MIPPRESOLVE", presolveops)
setparam("XPRS_SYMMETRY", 0) ! Disable symmetry detection
! Set the max. number of solutions to store (default: 10)
setparam("XPRS_enummaxsol", 25)
! Display Optimizer log
setparam("XPRS_verbose", true)
! Solve the problem, enabling the solution enumerator
maximize(XPRS_ENUM, Return)
! Print out all solutions saved by the enumerator
forall(i in 1..getparam("XPRS_enumsols")) do
selectsol(i) ! Select a solution from the pool
writeln("Solution ", i)
print_sol
end-do
! Solution printing
procedure print_sol
writeln("Total return: ", getobjval)
forall(s in SHARES | getsol(frac(s))>0)
writeln(s, ": ", getsol(frac(s))*100, "% (", getsol(buy(s)), ")")
end-procedure
end-model
|
|
folioinfeas.mos |
(!******************************************************
Mosel Example Problems
======================
file folioinfeas.mos
````````````````````
Modeling an LP problem
to perform portfolio optimization.
Linear version of the model in foliomip3.mos.
-- Infeasible model parameter values --
-- Handling infeasibility through auxiliary variables --
(c) 2008 Fair Isaac Corporation
author: S.Heipcke, Dec. 2008, rev. Sep. 2018
*******************************************************!)
model "Portfolio optimization with MIP"
uses "mmxprs"
parameters
MAXRISK = 1/3 ! Max. investment into high-risk values
MINREG = 0.3 ! Min. investment per geogr. region
MAXREG = 0.5 ! Max. investment per geogr. region
MAXSEC = 0.1 ! Max. investment per ind. sector
MAXVAL = 0.2 ! Max. investment per share
MINVAL = 0.1 ! Min. investment per share
DATAFILE = "folio250.dat" ! File with problem data
end-parameters
forward procedure print_sol
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)
LOC: array(REGIONS) of set of string ! Sets of shares per geogr. region
RET: array(SHARES) of real ! Estimated return in investment
SEC: array(TYPES) of set of string ! Sets of shares per industry sector
end-declarations
initializations from DATAFILE
RISK RET LOC SEC
end-initializations
public declarations
frac: array(SHARES) of mpvar ! Fraction of capital used per share
Return: linctr ! Total return
LimitRisk: linctr ! Max. percentage of high-risk values
LimitMinReg,LimitMaxReg: array(REGIONS) of linctr ! Min/max perc. per region
LimitSec: array(TYPES) of linctr ! Max. percentage per industry sector
TotalOne: linctr ! Spend all the capital
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
! Limits on geographical distribution
forall(r in REGIONS) do
LimitMinReg(r):= sum(s in LOC(r)) frac(s) >= MINREG
LimitMaxReg(r):= sum(s in LOC(r)) frac(s) <= MAXREG
end-do
! Diversification across industry sectors
forall(t in TYPES) LimitSec(t):= sum(s in SEC(t)) frac(s) <= MAXSEC
! 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
! Display Optimizer log
setparam("XPRS_verbose", true)
! Solve the problem (using primal Simplex to minimize infeasibilities)
maximize(XPRS_PRI,Return)
declarations
mx,mdj: set of mpvar
mslack,mdual: set of linctr
devRisk: mpvar
devMinReg,devMaxReg: array(REGIONS) of mpvar
devSec: array(TYPES) of mpvar
end-declarations
if getprobstat=XPRS_INF then
! Print some details
getinfeas(mx, mslack, mdual, mdj)
writeln("Infeasible variables:")
forall(v in mx) writeln(" ",getname(v))
forall(v in mdj) writeln(" ",getname(v))
writeln("Infeasible constraints:")
forall(c in mslack) writeln(" ",getname(c))
forall(c in mdual) writeln(" ",getname(c))
writeln("#### Original problem infeasible. Adding deviation variables ####")
! Add deviation variables to make problem solvable
LimitRisk -= devRisk
forall(r in REGIONS) do
LimitMinReg(r) += devMinReg(r)
LimitMaxReg(r) -= devMaxReg(r)
devMaxReg(r) <= MAXREG/2 ! Only allow small deviations
end-do
forall(t in TYPES) do
LimitSec(t) -= devSec(t)
devSec(t)<= MAXSEC/2 ! Only allow small deviations
end-do
Penalty:= devRisk + sum(r in REGIONS) (devMinReg(r)+devMaxReg(r)) +
sum(t in TYPES) devSec(t)
! Resolve the problem with penalty terms added to the objective
maximize(Return - 10*Penalty)
if getprobstat=XPRS_INF then
writeln("No solution after relaxation")
exit(1)
end-if
writeln("Constraint violations:")
writeln(" Constraint Activity Deviation Bound(s)")
writeln(" Risk ",
strfmt(getsol(sum(s in RISK) frac(s)),-10),
strfmt(devRisk.sol,-10), " (", MAXRISK, ")")
forall(r in REGIONS)
writeln(" Region ", strfmt(r,-11), " ",
strfmt(getsol(sum(s in LOC(r)) frac(s)),-10),
strfmt(devMaxReg(r).sol-devMinReg(r).sol,-10),
" (", MINREG, "-",MAXREG,")")
forall(t in TYPES)
writeln(" Sector ", strfmt(t,-14), " ",
strfmt(getsol(sum(s in SEC(t)) frac(s)),-10),
strfmt(devSec(t).sol,-10), " (", MAXSEC, ")")
end-if
print_sol
! Solution printing
procedure print_sol
writeln("Solution ", getparam("XPRS_MIPSOLS"))
writeln("Total return: ", getsol(Return))
forall(s in SHARES | getsol(frac(s))>0)
writeln(s, ": ", getsol(frac(s))*100, "%")
end-procedure
end-model
|
|
folioinfcause.mos |
(!******************************************************
Mosel Example Problems
======================
file folioinfcause.mos
``````````````````````
Modeling a MIP problem
to perform portfolio optimization.
Same model as in foliomip3.mos.
-- Infeasible model parameter values --
-- Retrieving infeasible row/column from presolve --
(c) 2012 Fair Isaac Corporation
author: S.Heipcke, Oct. 2012, rev. May 2018
*******************************************************!)
model "Portfolio optimization with MIP"
uses "mmxprs"
parameters
MAXRISK = 1/3 ! Max. investment into high-risk values
MINREG = 0.1 ! Min. investment per geogr. region
MAXREG = 0.2 ! Max. investment per geogr. region
MAXSEC = 0.1 ! Max. investment per ind. sector
MAXVAL = 0.15 ! Max. investment per share
MINVAL = 0.15 ! Min. investment per share
MAXNUM = 4 ! Max. number of different assets
DATAFILE = "folio10.dat" ! File with problem data
end-parameters
forward procedure print_sol
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)
LOC: array(REGIONS) of set of string ! Sets of shares per geogr. region
RET: array(SHARES) of real ! Estimated return in investment
SEC: array(TYPES) of set of string ! Sets of shares per industry sector
end-declarations
initializations from DATAFILE
RISK RET LOC SEC
end-initializations
public 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: linctr ! Total return
LimitRisk: linctr ! Max. percentage of high-risk values
LimitMinReg,LimitMaxReg: array(REGIONS) of linctr ! Min/max perc. per region
LimitSec: array(TYPES) of linctr ! Max. percentage per industry sector
TotalOne: linctr ! Spend all the capital
LimitNum: linctr ! Max. total number of assets
LinkUB,LinkLB: array(SHARES) of linctr ! Linking buy+frac variables
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
! Limits on geographical distribution
forall(r in REGIONS) do
LimitMinReg(r):= sum(s in LOC(r)) frac(s) >= MINREG
LimitMaxReg(r):= sum(s in LOC(r)) frac(s) <= MAXREG
end-do
! Diversification across industry sectors
forall(t in TYPES) LimitSec(t):= sum(s in SEC(t)) frac(s) <= MAXSEC
! 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
! Limit the total number of assets
LimitNum:= sum(s in SHARES) buy(s) <= MAXNUM
forall(s in SHARES) do
buy(s) is_binary ! Turn variables into binaries
LinkUB(s):= frac(s) <= MAXVAL*buy(s) ! Linking the variables
LinkLB(s):= frac(s) >= MINVAL*buy(s) ! Linking the variables
end-do
! Display Optimizer log
setparam("XPRS_verbose", true)
setparam("XPRS_LOADNAMES", true)
setparam("XPRS_TRACE", 1) ! Show detailed presolve log
! Solve the problem
maximize(XPRS_LIN,Return)
declarations
V: set of mpvar
C: set of linctr
end-declarations
probstat:= getprobstat
case probstat of
XPRS_OPT: do
writeln("Problem solved")
print_sol
end-do
XPRS_INF: do
setparam("XPRS_verbose", false) ! Disable Optimizer output
writeln("LP infeasible")
getinfcause(V, C) ! Retrieve inf. var. or constr.
forall(v in V) writeln("Infeasible variable: ", getname(v), " ")
forall(c in C) writeln("Infeasible constraint: ", getname(c), " ")
end-do
XPRS_OTH: writeln("Problem unbounded")
XPRS_UNF: writeln("Optimization unfinished")
else writeln("Unknown problem status")
end-case
! Solution printing
procedure print_sol
writeln("Solution ", getparam("XPRS_MIPSOLS"))
writeln("Total return: ", getsol(Return))
forall(s in SHARES | getsol(frac(s))>0)
writeln(s, ": ", getsol(frac(s))*100, "% (", getsol(buy(s)), ")")
end-procedure
end-model
|
|
folioiis.mos |
(!******************************************************
Mosel Example Problems
======================
file folioiis.mos
`````````````````
Modeling a MIP problem
to perform portfolio optimization.
Same model as in foliomip3.mos.
-- Infeasible model parameter values --
-- Retrieving IIS --
*** This model cannot be run with a Community Licence
for the provided data instance ***
(c) 2008 Fair Isaac Corporation
author: S.Heipcke, Dec. 2008, rev. Sep. 2018
*******************************************************!)
model "Portfolio optimization with MIP"
uses "mmxprs"
parameters
MAXRISK = 1/3 ! Max. investment into high-risk values
MINREG = 0.1 ! Min. investment per geogr. region
MAXREG = 0.2 ! Max. investment per geogr. region
MAXSEC = 0.1 ! Max. investment per ind. sector
MAXVAL = 0.2 ! Max. investment per share
MINVAL = 0.1 ! Min. investment per share
MAXNUM = 5 ! Max. number of different assets
DATAFILE = "folio250.dat" ! File with problem data
end-parameters
forward procedure print_sol
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)
LOC: array(REGIONS) of set of string ! Sets of shares per geogr. region
RET: array(SHARES) of real ! Estimated return in investment
SEC: array(TYPES) of set of string ! Sets of shares per industry sector
end-declarations
initializations from DATAFILE
RISK RET LOC SEC
end-initializations
public 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: linctr ! Total return
LimitRisk: linctr ! Max. percentage of high-risk values
LimitMinReg,LimitMaxReg: array(REGIONS) of linctr ! Min/max perc. per region
LimitSec: array(TYPES) of linctr ! Max. percentage per industry sector
TotalOne: linctr ! Spend all the capital
LimitNum: linctr ! Max. total number of assets
LinkUB,LinkLB: array(SHARES) of linctr ! Linking buy+frac variables
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
! Limits on geographical distribution
forall(r in REGIONS) do
LimitMinReg(r):= sum(s in LOC(r)) frac(s) >= MINREG
LimitMaxReg(r):= sum(s in LOC(r)) frac(s) <= MAXREG
end-do
! Diversification across industry sectors
forall(t in TYPES) LimitSec(t):= sum(s in SEC(t)) frac(s) <= MAXSEC
! 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
! Limit the total number of assets
LimitNum:= sum(s in SHARES) buy(s) <= MAXNUM
forall(s in SHARES) do
buy(s) is_binary ! Turn variables into binaries
LinkUB(s):= frac(s) <= MAXVAL*buy(s) ! Linking the variables
LinkLB(s):= frac(s) >= MINVAL*buy(s) ! Linking the variables
end-do
! Display Optimizer log
setparam("XPRS_verbose", true)
setparam("XPRS_LOADNAMES", true)
! Solve the problem
maximize(XPRS_LIN,Return)
declarations
V: set of mpvar
C: set of linctr
end-declarations
probstat:= getprobstat
case probstat of
XPRS_OPT: do
writeln("Problem solved")
print_sol
end-do
XPRS_INF: do
setparam("XPRS_verbose", false) ! Disable Optimizer output
writeln("LP infeasible")
getiis(0, V, C) ! Retrieve the IIS approximation
writeln("IIS approximation")
write(" variables: "); writeln(getsize(V))
write(" constraints: "); writeln(getsize(C))
getiis({},{}) ! Generate all IIS
numiis:= getparam("XPRS_NUMIIS") ! Retrieve number of IIS
writeln("Total IIS:", numiis)
forall(i in 1..numiis) do
getiis(i, V, C) ! Retrieve the i'th IIS
writeln("IIS ", i)
write(" variables: "); writeln(getsize(V))
forall(v in V) write(getname(v), " "); writeln
write(" constraints: "); writeln(getsize(C))
forall(c in C) write(getname(c), " "); writeln
end-do
end-do
XPRS_OTH: writeln("Problem unbounded")
XPRS_UNF: writeln("Optimization unfinished")
else writeln("Unknown problem status")
end-case
! Solution printing
procedure print_sol
writeln("Solution ", getparam("XPRS_MIPSOLS"))
writeln("Total return: ", getsol(Return))
forall(s in SHARES | getsol(frac(s))>0)
writeln(s, ": ", getsol(frac(s))*100, "% (", getsol(buy(s)), ")")
end-procedure
end-model
|
|
foliomiis.mos |
(!******************************************************
Mosel Example Problems
======================
file foliomiis.mos
``````````````````
Modeling a MIP problem
to perform portfolio optimization.
Same model as in foliomip3.mos.
-- Infeasible model parameter values --
-- Retrieving MIIS --
(c) 2010 Fair Isaac Corporation
author: S.Heipcke, Oct. 2010
*******************************************************!)
model "Portfolio optimization with MIP"
uses "mmxprs"
parameters
MAXRISK = 1/4 ! Max. investment into high-risk values
MINREG = 0.1 ! Min. investment per geogr. region
MAXREG = 0.25 ! Max. investment per geogr. region
MAXSEC = 0.15 ! Max. investment per ind. sector
MAXVAL = 0.225 ! Max. investment per share
MINVAL = 0.1 ! Min. investment per share
MAXNUM = 5 ! Max. number of different assets
DATAFILE = "folio5.dat" ! File with problem data
end-parameters
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)
LOC: array(REGIONS) of set of string ! Sets of shares per geogr. region
RET: array(SHARES) of real ! Estimated return in investment
SEC: array(TYPES) of set of string ! Sets of shares per industry sector
end-declarations
initializations from DATAFILE
RISK RET LOC SEC
end-initializations
public 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: linctr ! Total return
LimitRisk: linctr ! Max. percentage of high-risk values
LimitMinReg,LimitMaxReg: array(REGIONS) of linctr ! Min/max perc. per region
LimitSec: array(TYPES) of linctr ! Max. percentage per industry sector
TotalOne: linctr ! Spend all the capital
LimitNum: linctr ! Max. total number of assets
LinkUB,LinkLB: array(SHARES) of linctr ! Linking buy+frac variables
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
! Limits on geographical distribution
forall(r in REGIONS) do
LimitMinReg(r):= sum(s in LOC(r)) frac(s) >= MINREG
LimitMaxReg(r):= sum(s in LOC(r)) frac(s) <= MAXREG
end-do
! Diversification across industry sectors
forall(t in TYPES) LimitSec(t):= sum(s in SEC(t)) frac(s) <= MAXSEC
! 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
! Limit the total number of assets
LimitNum:= sum(s in SHARES) buy(s) <= MAXNUM
forall(s in SHARES) do
buy(s) is_binary ! Turn variables into binaries
LinkUB(s):= frac(s) <= MAXVAL*buy(s) ! Linking the variables
LinkLB(s):= frac(s) >= MINVAL*buy(s) ! Linking the variables
end-do
! Display Optimizer log
setparam("XPRS_verbose", true)
setparam("XPRS_LOADNAMES", true)
! Uncomment this line to see that the problem is LP-feasible
! maximize(XPRS_LIN,Return)
! Solve the problem
maximize(Return)
declarations
V: set of mpvar
C: set of linctr
end-declarations
probstat:= getprobstat
case probstat of
XPRS_OPT: writeln("Problem solved")
XPRS_INF: do
setparam("XPRS_verbose", false) ! Disable Optimizer output
writeln("MIP infeasible")
getiis({},{}) ! Generate all IIS
numiis:= getparam("XPRS_NUMIIS") ! Retrieve number of IIS
! (at most 1 for MIP)
writeln("Total IIS:", numiis)
forall(i in 1..numiis) do
getiis(i, V, C) ! Retrieve the i'th IIS
writeln("IIS ", i)
write(" variables: "); writeln(getsize(V))
forall(v in V) write(getname(v), " "); writeln
write(" constraints: "); writeln(getsize(C))
forall(c in C) write(getname(c), " "); writeln
end-do
end-do
XPRS_OTH: writeln("Problem unbounded")
XPRS_UNF: writeln("Optimization unfinished")
else writeln("Unknown problem status")
end-case
end-model
|
|
foliolptune.mos |
(!******************************************************
Mosel Example Problems
======================
file foliolptune.mos
````````````````````
Modeling a small LP problem
to perform portfolio optimization.
-- Added Tuner flags --
(c) 2008 Fair Isaac Corporation
author: S.Heipcke, Aug. 2003
*******************************************************!)
model "Portfolio optimization with LP"
uses "mmxprs" ! Use Xpress Optimizer
uses "mmsystem"
public declarations
SHARES = 1..10 ! Set of shares
RISK = {2,3,4,9,10} ! Set of high-risk values among shares
NA = {1,2,3,4} ! Set of shares issued in N.-America
RET: array(SHARES) of real ! Estimated return in investment
frac: array(SHARES) of mpvar ! Fraction of capital used per share
end-declarations
RET:: [5,17,26,12,8,9,7,6,31,21]
! 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) <= 1/3
! Minimum amount of North-American values
sum(s in NA) frac(s) >= 0.5
! Spend all the capital
sum(s in SHARES) frac(s) = 1
! Upper bounds on the investment per share
forall(s in SHARES) frac(s) <= 0.3
(! Problem output from Mosel (to check problem definition, not for tuning):
exportprob(EP_MAX,'foliomos.lp', Return);
exportprob(EP_MPS,'foliomos.mat', Return);
! Problem output from the solver (for tuning):
setparam('XPRS_LOADNAMES',true)
loadprob(Return);
writeprob('folioopt.mat', 'x');
!)
! Display progress log
setparam('XPRS_VERBOSE',true)
! Solve the problem
setparam("XPRS_TUNERMAXTIME", 60)
setparam("XPRS_TUNEROUTPUTPATH", string(expandpath("TuneOut")))
maximize(XPRS_TUNE, Return)
(!
declarations
status:array({XPRS_OPT,XPRS_UNF,XPRS_INF,XPRS_UNB,XPRS_OTH}) of string
end-declarations
status::([XPRS_OPT,XPRS_UNF,XPRS_INF,XPRS_UNB,XPRS_OTH])[
"Optimum found","Unfinished","Infeasible","Unbounded","Failed"]
writeln("Problem status: ", status(getprobstat))
!)
! Solution printing
writeln("Total return: ", getobjval)
forall(s in SHARES) writeln(s, ": ", getsol(frac(s))*100, "%")
end-model
|
|
foliorep.mos |
(!******************************************************
Mosel Example Problems
======================
file foliorep.mos
`````````````````
Modeling a MIP problem
to perform portfolio optimization.
Same model as in foliomip3.mos.
-- Infeasible model parameter values --
-- Repairing infeasibilities --
(c) 2008 Fair Isaac Corporation
author: S.Heipcke, Dec. 2008, rev. Sep. 2018
*******************************************************!)
model "Portfolio optimization with MIP"
uses "mmxprs"
parameters
MAXRISK = 1/3 ! Max. investment into high-risk values
MINREG = 0.3 ! Min. investment per geogr. region
MAXREG = 0.5 ! Max. investment per geogr. region
MAXSEC = 0.15 ! Max. investment per ind. sector
MAXVAL = 0.2 ! Max. investment per share
MINVAL = 0.1 ! Min. investment per share
MAXNUM = 4 ! Max. number of different assets
DATAFILE = "folio10.dat" ! File with problem data
end-parameters
forward procedure print_sol
forward procedure print_violated
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)
LOC: array(REGIONS) of set of string ! Sets of shares per geogr. region
RET: array(SHARES) of real ! Estimated return in investment
SEC: array(TYPES) of set of string ! Sets of shares per industry sector
end-declarations
initializations from DATAFILE
RISK RET LOC SEC
end-initializations
public 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: linctr ! Total return
LimitRisk: linctr ! Max. percentage of high-risk values
LimitMinReg,LimitMaxReg: array(REGIONS) of linctr ! Min/max perc. per region
LimitSec: array(TYPES) of linctr ! Max. percentage per industry sector
LimitNum: linctr ! Max. total number of assets
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
! Limits on geographical distribution
forall(r in REGIONS) do
LimitMinReg(r):= sum(s in LOC(r)) frac(s) >= MINREG
LimitMaxReg(r):= sum(s in LOC(r)) frac(s) <= MAXREG
end-do
! Diversification across industry sectors
forall(t in TYPES) LimitSec(t):= sum(s in SEC(t)) frac(s) <= MAXSEC
! 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
! Limit the total number of assets
LimitNum:= sum(s in SHARES) buy(s) <= MAXNUM
forall(s in SHARES) do
buy(s) is_binary ! Turn variables into binaries
frac(s) <= MAXVAL*buy(s) ! Linking the variables
frac(s) >= MINVAL*buy(s) ! Linking the variables
end-do
! Display Optimizer log
! setparam("XPRS_verbose", true)
! Solve the problem
! maximize(XPRS_LIN,Return)
maximize(Return)
!**** Infeasibility repair + reporting ****
declarations
Alrp,Agrp: array(linctr) of real ! Selectors for LEG / GEQ constraints
Albp,Aubp: array(mpvar) of real ! Selector for lower / upper bounds on vars
rstat: array(range) of string ! Status message text
end-declarations
probstat:= getprobstat
case probstat of
XPRS_OPT: writeln("Problem solved")
XPRS_INF: do
! Must use the detailed infeasibility repair method since
! only some constraints of each type may be relaxed
Alrp(LimitRisk):=1
forall(r in REGIONS) Alrp(LimitMaxReg(r)):=1
forall(t in TYPES) Alrp(LimitSec(t)):=1
Alrp(LimitNum):=1
forall(r in REGIONS) Agrp(LimitMinReg(r)):=1
delta:=0.001
while (delta<10) do
setparam("XPRS_MAXTIME", -10)
! setparam("XPRS_VERBOSE", false)
! Option 'r': repairinfeas reports the relaxed constraints/bounds
repairinfeas(Alrp, Agrp, Albp, Aubp, 'r', delta, "")
repstatus:= getprobstat
write("delta = ", delta, ": ")
case probstat of
XPRS_OPT: writeln("Relaxed problem solved")
XPRS_INF: writeln("Relaxed problem infeasible")
XPRS_OTH: writeln("Relaxed problem unbounded")
XPRS_UNF: writeln("Repairinfeas has been terminated")
else writeln("Unknown problem status")
end-case
! Display the relaxed solution
print_sol
! Programmatic checking of constraint violations
print_violated
delta:= delta*10
end-do
end-do
XPRS_OTH: writeln("Problem unbounded")
XPRS_UNF: writeln("Optimization unfinished")
else writeln("Unknown problem status")
end-case
!**** Solution printing ****
procedure print_sol
writeln(" Total return: ", getsol(Return))
forall(s in SHARES | getsol(frac(s))>0)
writeln(" ", s, ": ", getsol(frac(s))*100, "% (", getsol(buy(s)), ")")
end-procedure
!**** Display violated constraints ****
procedure print_violated
declarations
AllCtr: set of linctr
end-declarations
EPS:=1e-6
writeln(" Violated (relaxed) constraints:")
getloadedlinctrs(AllCtr)
forall(c in AllCtr)
case gettype(c) of
CT_EQ: if abs(getsol(c))>EPS then
writeln(" = constraint ", getname(c), " by ", c.sol)
end-if
CT_GEQ: if getsol(c)<-EPS then
writeln(" >= constraint ", getname(c), " by ", c.sol)
end-if
CT_LEQ: if getsol(c)>EPS then
writeln(" <= constraint ", getname(c), " by ", c.sol)
end-if
end-case
writeln
end-procedure
end-model
|
|
foliorep_sol.mos |
(!******************************************************
Mosel Example Problems
======================
file foliorep_sol.mos
`````````````````````
Modeling a MIP problem
to perform portfolio optimization.
Same model as in foliomip3.mos.
-- Infeasible model parameter values --
-- Repairing infeasibilities --
-- Storing solutions in an mpsol object --
(c) 2014 Fair Isaac Corporation
author: S.Heipcke, Sep. 2014, rev. Sep. 2018
*******************************************************!)
model "Portfolio optimization with MIP"
uses "mmxprs"
parameters
MAXRISK = 1/3 ! Max. investment into high-risk values
MINREG = 0.3 ! Min. investment per geogr. region
MAXREG = 0.5 ! Max. investment per geogr. region
MAXSEC = 0.15 ! Max. investment per ind. sector
MAXVAL = 0.2 ! Max. investment per share
MINVAL = 0.1 ! Min. investment per share
MAXNUM = 4 ! Max. number of different assets
DATAFILE = "folio10.dat" ! File with problem data
end-parameters
forward procedure print_sol
forward procedure print_violated
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)
LOC: array(REGIONS) of set of string ! Sets of shares per geogr. region
RET: array(SHARES) of real ! Estimated return in investment
SEC: array(TYPES) of set of string ! Sets of shares per industry sector
end-declarations
initializations from DATAFILE
RISK RET LOC SEC
end-initializations
public 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: linctr ! Total return
LimitRisk: linctr ! Max. percentage of high-risk values
LimitMinReg,LimitMaxReg: array(REGIONS) of linctr ! Min/max perc. per region
LimitSec: array(TYPES) of linctr ! Max. percentage per industry sector
LimitNum: linctr ! Max. total number of assets
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
! Limits on geographical distribution
forall(r in REGIONS) do
LimitMinReg(r):= sum(s in LOC(r)) frac(s) >= MINREG
LimitMaxReg(r):= sum(s in LOC(r)) frac(s) <= MAXREG
end-do
! Diversification across industry sectors
forall(t in TYPES) LimitSec(t):= sum(s in SEC(t)) frac(s) <= MAXSEC
! 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
! Limit the total number of assets
LimitNum:= sum(s in SHARES) buy(s) <= MAXNUM
forall(s in SHARES) do
buy(s) is_binary ! Turn variables into binaries
frac(s) <= MAXVAL*buy(s) ! Linking the variables
frac(s) >= MINVAL*buy(s) ! Linking the variables
end-do
! Display Optimizer log
! setparam("XPRS_verbose", true)
! Solve the problem
! maximize(XPRS_LIN,Return)
maximize(Return)
!**** Infeasibility repair + reporting ****
declarations
Alrp,Agrp: array(linctr) of real ! Selectors for LEG / GEQ constraints
Albp,Aubp: array(mpvar) of real ! Selector for lower / upper bounds on vars
rstat: array(range) of string ! Status message text
end-declarations
probstat:= getprobstat
case probstat of
XPRS_OPT: writeln("Problem solved")
XPRS_INF: do
! Must use the detailed infeasibility repair method since
! only some constraints of each type may be relaxed
Alrp(LimitRisk):=1
forall(r in REGIONS) Alrp(LimitMaxReg(r)):=1
forall(t in TYPES) Alrp(LimitSec(t)):=1
Alrp(LimitNum):=1
forall(r in REGIONS) Agrp(LimitMinReg(r)):=1
rstat::(0..5)["relaxed optimum found",
"relaxed problem infeasible", "relaxed problem unbounded",
"solution nonoptimal for original objective",
"error", "numerical instability"]
delta:=0.001
while (delta<10) do
setparam("XPRS_MAXTIME", -10)
! setparam("XPRS_VERBOSE", false)
! Option 'r': repairinfeas reports the relaxed constraints/bounds
repairinfeas(Alrp, Agrp, Albp, Aubp, 'r', delta, "")
repstatus:= getprobstat
write("delta = ", delta, ": ")
case probstat of
XPRS_OPT: writeln("Relaxed problem solved")
XPRS_INF: writeln("Relaxed problem infeasible")
XPRS_OTH: writeln("Relaxed problem unbounded")
XPRS_UNF: writeln("Repairinfeas has been terminated")
else writeln("Unknown problem status")
end-case
! Display the relaxed solution
print_sol
! Programmatic checking of constraint violations
print_violated
delta:= delta*10
end-do
end-do
XPRS_OTH: writeln("Problem unbounded")
XPRS_UNF: writeln("Optimization unfinished")
else writeln("Unknown problem status")
end-case
!**** Solution printing ****
procedure print_sol
writeln(" Total return: ", getsol(Return))
forall(s in SHARES | getsol(frac(s))>0)
writeln(" ", s, ": ", getsol(frac(s))*100, "% (", getsol(buy(s)), ")")
end-procedure
!**** Display violated constraints ****
procedure print_violated
declarations
Solution: mpsol
AllCtr: set of linctr
end-declarations
EPS:=1e-6
writeln(" Violated (relaxed) constraints:")
getloadedlinctrs(AllCtr)
savesol(Solution)
forall(c in AllCtr)
case gettype(c) of
CT_EQ: if abs(getsol(Solution,c))>EPS then
writeln(" = constraint ", getname(c), " by ", getsol(Solution,c))
end-if
CT_GEQ: if getsol(Solution,c)<-EPS then
writeln(" >= constraint ", getname(c), " by ", getsol(Solution,c))
end-if
CT_LEQ: if getsol(Solution,c)>EPS then
writeln(" <= constraint ", getname(c), " by ", getsol(Solution,c))
end-if
end-case
writeln
end-procedure
end-model
|
|
runfolio.mos |
(!******************************************************
Mosel Example Problems
======================
file runfolio.mos
`````````````````
Master model running portfolio optimization model.
Runs model foliomemio.mos.
-- Data input/output in memory --
(c) 2009 Fair Isaac Corporation
author: S.Heipcke, Jan. 2009
*******************************************************!)
model "Run portfolio optimization model"
uses "mmjobs" ! Use multiple model handling
uses "mmsystem", "mmxprs"
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
setparam("datetimefmt", "%0d-%N-%y, %0H:%0M:%0S")
HTMLFILE:= INPUTFILE + "_sol.html"
fopen(HTMLFILE, F_OUTPUT)
writeln("<html>")
writeln("<head>")
writeln("<style type='text/css'>")
writeln("body {font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; color: 000055 }")
writeln("table td {background-color: ffffaa; text-align: left }")
writeln("table th {background-color: 053055; color: ffcc88}")
writeln("</style>")
writeln("</head>")
writeln("<body>")
writeln("<center><h2>Portfolio Optimization Results</h2></center>")
writeln("<table width='100%' cellpadding='5' cellspacing='0' border=0>")
writeln("<tr><td width='55%'><font color='#000055'><b>Total return: ",
returnsol, "</b></font></td><td><font color='#885533'><b>Problem instance: ",
INPUTFILE,"</b></font></td></tr>")
writeln("<tr><td><font color='#000055'><b>Number of shares: ", numsharessol, "</b></font></td><td><font color='#885533'><b>Date: ", datetime(SYS_NOW),"</b></font></td></tr>")
writeln("<tr><td colspan='2'> </td></tr>")
writeln("</table>")
writeln("<table cellpadding='2' cellspacing='1' width='100%'>")
writeln("<tr><th>Value</th><th>Percentage</th></tr>")
forall(s in SHARES | fracsol(s)>0)
writeln("<tr><td>", s, "</td><td>", strfmt(fracsol(s)*100,4,2),
"%</td></tr>")
writeln("</table>")
writeln("</body>")
writeln("</html>")
fclose(F_OUTPUT)
end-procedure
end-model
|
|
runfolio2.mos |
(!******************************************************
Mosel Example Problems
======================
file runfolio2.mos
``````````````````
Master model running portfolio optimization model.
Runs model foliomemio2.mos.
-- Data input/output in memory --
-- Grouping arrays with identical index sets --
(c) 2009 Fair Isaac Corporation
author: S.Heipcke, Feb. 2009
*******************************************************!)
model "Run portfolio optimization model"
uses "mmjobs" ! Use multiple model handling
uses "mmsystem", "mmxprs"
parameters
MODELFILE = "foliomemio2.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',FRACBUYSOL='shmem:FRACBUY'," +
"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,buysol] as 'shmem:FRACBUY'
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
setparam("datetimefmt", "%0d-%N-%y, %0H:%0M:%0S")
HTMLFILE:= INPUTFILE + "_sol.html"
fopen(HTMLFILE, F_OUTPUT)
writeln("<html>")
writeln("<head>")
writeln("<style type='text/css'>")
writeln("body {font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; color: 000055 }")
writeln("table td {background-color: ffffaa; text-align: left }")
writeln("table th {background-color: 053055; color: ffcc88}")
writeln("</style>")
writeln("</head>")
writeln("<body>")
writeln("<center><h2>Portfolio Optimization Results</h2></center>")
writeln("<table width='100%' cellpadding='5' cellspacing='0' border=0>")
writeln("<tr><td width='55%'><font color='#000055'><b>Total return: ",
returnsol, "</b></font></td><td><font color='#885533'><b>Problem instance: ",
INPUTFILE,"</b></font></td></tr>")
writeln("<tr><td><font color='#000055'><b>Number of shares: ", numsharessol, "</b></font></td><td><font color='#885533'><b>Date: ", datetime(SYS_NOW),"</b></font></td></tr>")
writeln("<tr><td colspan='2'> </td></tr>")
writeln("</table>")
writeln("<table cellpadding='2' cellspacing='1' width='100%'>")
writeln("<tr><th>Value</th><th>Percentage</th></tr>")
forall(s in SHARES | fracsol(s)>0)
writeln("<tr><td>", s, "</td><td>", strfmt(fracsol(s)*100,4,2),
"%</td></tr>")
writeln("</table>")
writeln("</body>")
writeln("</html>")
fclose(F_OUTPUT)
end-procedure
end-model
|
|
runfoliopar.mos |
(!******************************************************
Mosel Example Problems
======================
file runfoliopar.mos
````````````````````
Master model running several instances of the
portfolio optimization model in parallel.
Runs model foliomemio.mos.
-- Data input/output in memory --
*** ATTENTION: This model will return an error if ***
*** no more than one Xpress licence is available. ***
*** With a single license, use setting NUMPAR=1 ***
(c) 2009 Fair Isaac Corporation
author: S.Heipcke, Feb. 2009, rev. Dec. 2017
*******************************************************!)
model "Run portfolio optimization model (parallel)"
uses "mmjobs" ! Use multiple model handling
uses "mmsystem", "mmxprs"
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 = 9 ! Max. number of different assets
NUMPAR = 5 ! Number of model instances to run
end-parameters
forward procedure write_html_header
forward procedure write_html_line(i:integer)
forward procedure write_html_line(i:integer,msg:string)
forward procedure write_html_footer
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,totalreturn: real ! Solution values
numsharessol,status,totalnum,totalopt: 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: dynamic array(Instances:range) of Model
end-declarations
! Compile the optimization model
if compile("", MODELFILE, "shmem:bim") <> 0 then
writeln("Error during model compilation")
exit(1)
end-if
! Load several instances of the optimization model
forall(i in 1..NUMPAR) do
create(foliomod(i))
load(foliomod(i), "shmem:bim")
end-do
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
! Start all instances in parallel, using unique file location names for output
forall(i in Instances)
run(foliomod(i), "MAXRISK=" + MAXRISK + ",MINREG=" + MINREG +
",MAXREG=" + MAXREG + ",MAXSEC=" + MAXSEC +
",MAXVAL=" + MAXVAL + ",MINVAL=" + MINVAL +
",MAXNUM=" + (MAXNUM-i) + ",DATAFILE='raw:',OUTPUTFILE='raw:'," +
"RISKDATA='shmem:RISK',RETDATA='shmem:RET',LOCDATA='shmem:LOCTAB'," +
"SECDATA='shmem:SECTAB',FRACSOL='shmem:FRAC" + i +"',BUYSOL='shmem:BUY" +
i + "',NUMSHARES='shmem:NUMSHARES" + i + "',RETSOL='shmem:RETSOL" + i +
"',SOLSTATUS='shmem:SOLSTATUS" + i + "'" )
! Wait until all models have finished
! (alternatively: could retrieve results as soon as a run finishes)
forall(i in Instances) do
wait ! Wait for model terminations
dropnextevent ! Ignore termination event message
end-do
! Output: generate an HTML page with all solutions
write_html_header
forall(i in Instances) do
forall(s in SHARES) do
fracsol(s):=0; buysol(s):=0
end-do
initializations from "raw:"
returnsol as 'shmem:RETSOL'+i
numsharessol as 'shmem:NUMSHARES'+i
fracsol as 'shmem:FRAC'+i
buysol as 'shmem:BUY'+i
status as 'shmem:SOLSTATUS'+i
end-initializations
case status of
XPRS_OPT: do
write_html_line(i)
totalreturn+=returnsol
totalnum+=numsharessol
totalopt+=1
end-do
XPRS_UNF: write_html_line(i,"Problem solving unfinished")
XPRS_INF: write_html_line(i,"Problem is infeasible")
XPRS_UNB,XPRS_OTH: write_html_line(i,"No solution available")
end-case
end-do
write_html_footer
! *********** Writing an HTML result file ***********
procedure write_html_header
setparam("datetimefmt", "%0d-%N-%y, %0H:%0M:%0S")
HTMLFILE:= INPUTFILE + "_sol.html"
fopen(HTMLFILE, F_OUTPUT)
writeln("<html>")
writeln("<head>")
writeln("<style type='text/css'>")
writeln("body {font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; color: 000055 }")
writeln("table td {background-color: ffffaa; text-align: left }")
writeln("table th {background-color: 053055; color: ffcc88}")
writeln("</style>")
writeln("</head>")
writeln("<body>")
writeln("<center><h2>Portfolio Optimization Summary Results</h2></center>")
writeln("<table width='100%' cellpadding='5' cellspacing='0' border=0>")
writeln("<tr><td width='55%'><font color='#000055'><b> </b></font></td><td><font color='#885533'><b>Problem data: ",
INPUTFILE,"</b></font></td></tr>")
writeln("<tr><td><font color='#000055'><b> </b></font></td><td><font color='#885533'><b>Date: ", datetime(SYS_NOW),"</b></font></td></tr>")
writeln("<tr><td colspan='2'> </td></tr>")
writeln("</table>")
writeln("<table cellpadding='2' cellspacing='1' width='100%'>")
writeln("<tr><th>Instance</th><th>Return</th><th>No. shares</th><th>Value: Percentage</th></tr>")
end-procedure
procedure write_html_line(i:integer)
write("<tr><td><center>", i, "</center></td><td>", returnsol, "</td><td><center>", numsharessol, "</center></td><td>")
writeln("<table cellpadding='2' cellspacing='0' width='100%'>")
ct:=0
forall(s in SHARES | fracsol(s)>0) do
ct+=1
writeln(if(ct mod 4=1, "<tr>", ""),
"<td><font size='-1'>", s, ": ", strfmt(fracsol(s)*100,4,2), "%,</font></td>",
if(ct mod 4=0, "</tr>", ""))
end-do
writeln(if(ct mod 4<>0, "</tr>", ""), "</table></td></tr>")
end-procedure
procedure write_html_line(i:integer,msg:string)
writeln("<tr><td><center>", i, "</center></td><td align='left' colspan='3'>", msg, "</td></tr>")
end-procedure
procedure write_html_footer
writeln("<tr><th>Average</th><th>", totalreturn/totalopt, "</th><th>", totalnum/totalopt, "</th><th></th></tr>")
writeln("</table>")
writeln("</body>")
writeln("</html>")
fclose(F_OUTPUT)
end-procedure
end-model
|
|
runfoliodistr.mos |
(!******************************************************
Mosel Example Problems
======================
file runfoliodistr.mos
``````````````````````
Master model running portfolio optimization model
on a remote Mosel instance.
Runs model foliomemio.mos.
*** ATTENTION: This model will return an error if ***
*** no more than one Xpress licence is available. ***
(c) 2010 Fair Isaac Corporation
author: S.Heipcke, July 2010
*******************************************************!)
model "Run portfolio optimization model remotely"
uses "mmjobs" ! Use multiple model handling
uses "mmsystem", "mmxprs"
parameters
MODELFILE = "foliomemio" ! Optimization model
INPUTFILE = "folio10.dat" ! File with problem data
OUTPUTFILE = "solout.dat" ! File for solution output
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
returnsol: real ! Solution values
numsharessol,status: integer
fracsol: dynamic array(SHARES) of real ! Fraction of capital used per share
buysol: dynamic array(SHARES) of real ! 1 if asset is in portfolio, 0 otherwise
foliomod: Model ! Mosel model
moselinst: Mosel ! Mosel instance
end-declarations
! Compile the optimization model locally
if compile(MODELFILE+".mos") <> 0 then
writeln("Error during model compilation")
exit(1)
end-if
! Start a remote Mosel instance:
! "" stands for the node running this model; try IP addresses or host names
if connect(moselinst, "")<>0 then exit(2); end-if
! Load the optimization model into the remote instance
load(moselinst, foliomod, "rmt:"+MODELFILE+".bim")
fdelete(MODELFILE+".bim")
run(foliomod, "MAXRISK=" + MAXRISK + ",MINREG=" + MINREG +
",MAXREG=" + MAXREG + ",MAXSEC=" + MAXSEC +
",MAXVAL=" + MAXVAL + ",MINVAL=" + MINVAL +
",MAXNUM=" + MAXNUM + ",DATAFILE='rmt:" + INPUTFILE +
"',OUTPUTFILE='rmt:" + OUTPUTFILE + "'")
wait ! Wait for model termination
dropnextevent ! Ignore termination event message
initializations from OUTPUTFILE
returnsol as 'RETSOL'
numsharessol as 'NUMSHARES'
fracsol as 'FRAC'
buysol as 'BUY'
status as '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
setparam("datetimefmt", "%0d-%N-%y, %0H:%0M:%0S")
HTMLFILE:= INPUTFILE + "_sol.html"
fopen(HTMLFILE, F_OUTPUT)
writeln("<html>")
writeln("<head>")
writeln("<style type='text/css'>")
writeln("body {font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; color: 000055 }")
writeln("table td {background-color: ffffaa; text-align: left }")
writeln("table th {background-color: 053055; color: ffcc88}")
writeln("</style>")
writeln("</head>")
writeln("<body>")
writeln("<center><h2>Portfolio Optimization Results</h2></center>")
writeln("<table width='100%' cellpadding='5' cellspacing='0' border=0>")
writeln("<tr><td width='55%'><font color='#000055'><b>Total return: ",
returnsol, "</b></font></td><td><font color='#885533'><b>Problem instance: ",
INPUTFILE,"</b></font></td></tr>")
writeln("<tr><td><font color='#000055'><b>Number of shares: ", numsharessol, "</b></font></td><td><font color='#885533'><b>Date: ", datetime(SYS_NOW),"</b></font></td></tr>")
writeln("<tr><td colspan='2'> </td></tr>")
writeln("</table>")
writeln("<table cellpadding='2' cellspacing='1' width='100%'>")
writeln("<tr><th>Value</th><th>Percentage</th></tr>")
forall(s in SHARES | fracsol(s)>0)
writeln("<tr><td>", s, "</td><td>", strfmt(fracsol(s)*100,4,2),
"%</td></tr>")
writeln("</table>")
writeln("</body>")
writeln("</html>")
fclose(F_OUTPUT)
end-procedure
end-model
|
|
runfoliopardistr.mos |
(!******************************************************
Mosel Example Problems
======================
file runfoliopardistr.mos
`````````````````````````
Master model running several instances of the
portfolio optimization model in parallel using
several Mosel instances (distribute architecture).
Runs model foliomemio.mos.
*** ATTENTION: This model will return an error if ***
*** no more than one Xpress licence is available. ***
*** With a single license, use setting NUMPAR=1 ***
(c) 2010 Fair Isaac Corporation
author: S.Heipcke, July 2010, rev. Dec. 2017
*******************************************************!)
model "Run portfolio optimization model (distributed parallel)"
uses "mmjobs" ! Use multiple model handling
uses "mmsystem", "mmxprs"
parameters
MODELFILE = "foliomemio" ! 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 = 9 ! Max. number of different assets
NUMPAR = 5 ! Number of model instances to run
end-parameters
forward procedure write_html_header
forward procedure write_html_line(i:integer)
forward procedure write_html_line(i:integer,msg:string)
forward procedure write_html_footer
declarations
SHARES: set of string ! Set of shares
returnsol,totalreturn: real ! Solution values
numsharessol,status,totalnum,totalopt: integer
fracsol: dynamic array(SHARES) of real ! Fraction of capital used per share
buysol: dynamic array(SHARES) of real ! 1 if asset is in portfolio, 0 otherwise
foliomod: dynamic array(Instances:range) of Model ! Mosel models
moselinst: dynamic array(Instances) of Mosel ! Mosel instances
end-declarations
! Compile the optimization model
if compile(MODELFILE+".mos") <> 0 then
writeln("Error during model compilation")
exit(1)
end-if
! Start remote Mosel instances:
! "" stands for the node running this model; try IP addresses or host names
forall(i in 1..NUMPAR) do
create(moselinst(i))
if connect(moselinst(i), "")<>0 then exit(2); end-if
end-do
! Load several instances of the optimization model
forall(i in 1..NUMPAR) do
create(foliomod(i))
load(moselinst(i), foliomod(i), "rmt:"+MODELFILE+".bim")
end-do
fdelete(MODELFILE+".bim")
! Start all instances in parallel, using unique file names for output
forall(i in Instances)
run(foliomod(i), "MAXRISK=" + MAXRISK + ",MINREG=" + MINREG +
",MAXREG=" + MAXREG + ",MAXSEC=" + MAXSEC +
",MAXVAL=" + MAXVAL + ",MINVAL=" + MINVAL +
",MAXNUM=" + (MAXNUM-i) + ",DATAFILE='rmt:" + INPUTFILE +
"',OUTPUTFILE='rmt:solout" + i + ".dat"+ "',FRACSOL='FRAC" + i +
"',BUYSOL='BUY" + i + "',NUMSHARES='NUMSHARES" + i +
"',RETSOL='RETSOL" + i + "',SOLSTATUS='SOLSTATUS" + i + "'" )
! Wait until all models have finished
! (alternatively: could retrieve results as soon as a run finishes)
forall(i in Instances) do
wait ! Wait for model terminations
dropnextevent ! Ignore termination event message
end-do
! Output: generate an HTML page with all solutions
write_html_header
forall(i in Instances) do
forall(s in SHARES) do
fracsol(s):=0; buysol(s):=0
end-do
OFile:="solout"+i+".dat"
initializations from OFile
returnsol as 'RETSOL'+i
numsharessol as 'NUMSHARES'+i
fracsol as 'FRAC'+i
buysol as 'BUY'+i
status as 'SOLSTATUS'+i
end-initializations
fdelete(OFile)
case status of
XPRS_OPT: do
write_html_line(i)
totalreturn+=returnsol
totalnum+=numsharessol
totalopt+=1
end-do
XPRS_UNF: write_html_line(i,"Problem solving unfinished")
XPRS_INF: write_html_line(i,"Problem is infeasible")
XPRS_UNB,XPRS_OTH: write_html_line(i,"No solution available")
end-case
end-do
write_html_footer
! *********** Writing an HTML result file ***********
procedure write_html_header
setparam("datetimefmt", "%0d-%N-%y, %0H:%0M:%0S")
HTMLFILE:= INPUTFILE + "_sol.html"
fopen(HTMLFILE, F_OUTPUT)
writeln("<html>")
writeln("<head>")
writeln("<style type='text/css'>")
writeln("body {font-family: Verdana, Geneva, Helvetica, Arial, sans-serif; color: 000055 }")
writeln("table td {background-color: ffffaa; text-align: left }")
writeln("table th {background-color: 053055; color: ffcc88}")
writeln("</style>")
writeln("</head>")
writeln("<body>")
writeln("<center><h2>Portfolio Optimization Summary Results</h2></center>")
writeln("<table width='100%' cellpadding='5' cellspacing='0' border=0>")
writeln("<tr><td width='55%'><font color='#000055'><b> </b></font></td><td><font color='#885533'><b>Problem data: ",
INPUTFILE,"</b></font></td></tr>")
writeln("<tr><td><font color='#000055'><b> </b></font></td><td><font color='#885533'><b>Date: ", datetime(SYS_NOW),"</b></font></td></tr>")
writeln("<tr><td colspan='2'> </td></tr>")
writeln("</table>")
writeln("<table cellpadding='2' cellspacing='1' width='100%'>")
writeln("<tr><th>Instance</th><th>Return</th><th>No. shares</th><th>Value: Percentage</th></tr>")
end-procedure
procedure write_html_line(i:integer)
write("<tr><td><center>", i, "</center></td><td>", returnsol, "</td><td><center>", numsharessol, "</center></td><td>")
writeln("<table cellpadding='2' cellspacing='0' width='100%'>")
ct:=0
forall(s in SHARES | fracsol(s)>0) do
ct+=1
writeln(if(ct mod 4=1, "<tr>", ""),
"<td><font size='-1'>", s, ": ", strfmt(fracsol(s)*100,4,2), "%,</font></td>",
if(ct mod 4=0, "</tr>", ""))
end-do
writeln(if(ct mod 4<>0, "</tr>", ""), "</table></td></tr>")
end-procedure
procedure write_html_line(i:integer,msg:string)
writeln("<tr><td><center>", i, "</center></td><td align='left' colspan='3'>", msg, "</td></tr>")
end-procedure
procedure write_html_footer
writeln("<tr><th>Average</th><th>", totalreturn/totalopt, "</th><th>", totalnum/totalopt, "</th><th></th></tr>")
writeln("</table>")
writeln("</body>")
writeln("</html>")
fclose(F_OUTPUT)
end-procedure
end-model
|
|
folioxml.mos |
(!******************************************************
Mosel Example Problems
======================
file folioxml.mos
`````````````````
Modeling a small LP problem
to perform portfolio optimization.
-- Reading/writing data in XML format --
(c) 2010 Fair Isaac Corporation
author: S.Heipcke, July 2010, rev. July 2013
*******************************************************!)
model "Portfolio optimization with LP"
uses "mmxprs"
uses "mmxml" ! XML interface functions
parameters
DATAFILE= "folio.xml" ! File with problem data
OUTFILE= "result.xml" ! 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 an XML file
load(AllData, DATAFILE)
getnodes(AllData, "portfolio/share", NodeList)
RISK:= union(l in NodeList | getattr(AllData,l,"risk")="high")
{getstrattr(AllData,l,"name")}
NA:= union(l in NodeList | getattr(AllData,l,"region")="NA")
{getstrattr(AllData,l,"name")}
(! Alternatively:
getnodes(AllData, "portfolio/share[@risk='high']/attribute::name", NodeList)
RISK:=union(r in NodeList) {getstrvalue(AllData,r)}
getnodes(AllData, "portfolio/share[@region='NA']/attribute::name", NodeList)
NA:=union(r in NodeList) {getstrvalue(AllData,r)}
getnodes(AllData, "portfolio/share", NodeList)
!)
forall(l in NodeList)
RET(getstrattr(AllData,l,"name")):= getintattr(AllData, l, "ret")
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 XML format
Root:=addnode(ResData, 0, XML_ELT, "result") ! Create root node "result"
Sol:= addnode(ResData, Root, XML_ELT, "solution") ! Add a "solution" node
setattr(ResData, Sol, "value", getobjval) ! ... with attribute "value"
forall(s in SHARES) do
Share:=addnode(ResData, Sol, XML_ELT,"share") ! Add a node to "solution"
setattr(ResData, Share, "name", s) ! ... with attribute "name"
setvalue(ResData, Share, frac(s).sol) ! ... and solution value
end-do
save(ResData, OUTFILE) ! Save solution to XML format file
save(ResData, Sol, "") ! Display XML format solution on screen
end-model
|
|
folioxmlqp.mos |
(!******************************************************
Mosel Example Problems
======================
file folioxmlqp.mos
```````````````````
Modeling a small QP problem
to perform portfolio optimization.
-- 1. QP: minimize variance
2. MIQP: limited number of assets ---
-- Reading/writing data in XML format --
(c) 2010 Fair Isaac Corporation
author: S.Heipcke, July 2010, rev. Sep. 2017
*******************************************************!)
model "Portfolio optimization with QP/MIQP"
uses "mmxprs", "mmnl"
uses "mmxml" ! XML interface functions
parameters
MAXVAL = 0.3 ! Max. investment per share
MINAM = 0.5 ! Min. investment into N.-American values
MAXNUM = 4 ! Max. number of different assets
TARGET = 9.0 ! Minimum target yield
end-parameters
forward procedure save_solution(num: integer)
declarations
SHARES = 1..10 ! Set of shares
RISK: set of integer ! Set of high-risk values among shares
NA: set of integer ! Set of shares issued in N.-America
RET: array(SHARES) of real ! Estimated return in investment
VAR: array(SHARES,SHARES) of real ! Variance/covariance matrix of
! estimated returns
AllData, Solution: xmldoc ! XML document
Share,Root,Sol: integer ! XML nodes
NodeList: list of integer
end-declarations
! Reading data from an XML file
load(AllData, "folioqp.xml")
getnodes(AllData, "portfolio/share", NodeList)
RISK:= union(l in NodeList | getattr(AllData,l,"risk")="high")
{getintattr(AllData,l,"name")}
NA:= union(l in NodeList | getattr(AllData,l,"region")="NA")
{getintattr(AllData,l,"name")}
forall(l in NodeList)
RET(getintattr(AllData,l,"name")):= getintattr(AllData, l, "ret")
! Read a second XML file
reset(AllData) ! Empty the "xmldoc" object
load(AllData, "folioqpvar.xml")
getnodes(AllData, "variance/var", NodeList)
forall(l in NodeList)
VAR(getintattr(AllData, l, "ind1"),getintattr(AllData, l, "ind2")):=
getrealvalue(AllData,l)
reset(AllData) ! Free up memory
! Prepare XML structure for solution output
Root:=addnode(Solution, 0, XML_ELT, "result") ! Create root node "result"
declarations
frac: array(SHARES) of mpvar ! Fraction of capital used per share
end-declarations
! **** First problem: unlimited number of assets ****
! Objective: mean variance
Variance:= sum(s,t in SHARES) VAR(s,t)*frac(s)*frac(t)
! Minimum amount of North-American values
sum(s in NA) frac(s) >= MINAM
! Spend all the capital
sum(s in SHARES) frac(s) = 1
! Target yield
sum(s in SHARES) RET(s)*frac(s) >= TARGET
! Upper bounds on the investment per share
forall(s in SHARES) frac(s) <= MAXVAL
! Solve the problem
minimize(Variance)
! Solution printing
writeln("With a target of ", TARGET, " minimum variance is ", getobjval)
forall(s in SHARES) writeln(s, ": ", getsol(frac(s))*100, "%")
save_solution(1)
! **** Second problem: limit total number of assets ****
declarations
buy: array(SHARES) of mpvar ! 1 if asset is in portfolio, 0 otherwise
end-declarations
! Limit the total number of assets
sum(s in SHARES) buy(s) <= MAXNUM
forall(s in SHARES) do
buy(s) is_binary
frac(s) <= buy(s)
end-do
! Solve the problem
minimize(Variance)
writeln("With a target of ", TARGET," and at most ", MAXNUM,
" assets,\n minimum variance is ", getobjval)
forall(s in SHARES) writeln(s, ": ", getsol(frac(s))*100, "%")
save_solution(2)
! Write solution to a new XML file
save(Solution, "qpresult.xml")
!*********************************************************************
! Solution printing to a file
procedure save_solution(num: integer)
Sol:= addnode(Solution, Root, XML_LASTCHILD, XML_ELT, "solution")
! Append a "solution" node
setattr(Solution, Sol, "num", num) ! ... with attribute "num"
forall(s in SHARES) do ! Add node containing solution value
Share:= addnode(Solution, Sol, "share", frac(s).sol)
setattr(Solution, Share, "name", s)
end-do
save(Solution, Sol, "") ! Display XML solution on screen
end-procedure
end-model
|
|
runfolioxml.mos |
(!******************************************************
Mosel Example Problems
======================
file runfolioxml.mos
````````````````````
Master model running portfolio optimization model.
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
|
|
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
|
|
foliohttpsrv.mos |
(!******************************************************
Mosel Example Problems
======================
file foliohttpsrv.mos
`````````````````````
HTTP server receiving requests for model runs with
XML-format data and running instances of model
folioxml.mos for every request (on the same Mosel
instance that is running this http server model).
(c) 2013 Fair Isaac Corporation
author: S.Heipcke, July 2013, rev. Apr. 2014
*******************************************************!)
model "HTTP server launching portfolio model"
uses "mmhttp" ! Use HTTP functions
uses "mmjobs" ! Use multiple model handling
parameters
MODELFILE = "folioxml" ! Optimization model
end-parameters
declarations
foliomod = record
m: Model ! Mosel model
id: integer ! Model index
rid: integer ! Request index
tempdir: string ! Name of temporary data directory
end-record
modqueue: list of foliomod ! Active models
DATAFILE, bimfile: string
MAXRISK, MAXVAL, MINAM: real
end-declarations
! Compile the optimization model
bimfile:=getparam("tmpdir")+"/"+MODELFILE+".bim"
if compile("g",MODELFILE+".mos",bimfile) <> 0 then
writeln("Error during model compilation")
exit(1)
end-if
!**** Create a new model instance and start running it ****
function newfoliomod(rid: integer): foliomod
! Load the optimization model
load(returned.m, bimfile)
returned.id:= getid(returned.m)
returned.rid:= rid
! Extract the data file from the tar archive
returned.tempdir:=getparam("tmpdir")+"/tartemp"+rid
makedir(returned.tempdir)
untar("zlib.gzip:"+httpreqfile(rid), returned.tempdir) ! Untar the data
! The configuration data is held in a fixed-name file
initializations from returned.tempdir+"/folioconfig.dat"
MAXRISK
MAXVAL
MINAM
DATAFILE
end-initializations
! Run model, disabling output
setdefstream(returned.m,F_OUTPUT, "null:")
run(returned.m, "MAXRISK=" + MAXRISK + ",MAXVAL=" + MAXVAL +
",MINAM=" + MINAM + ",DATAFILE='" + returned.tempdir+"/"+DATAFILE +
"',OUTFILE="+httpreqfile(rid))
end-function
!**** Locate an entry in the queue of active models ****
function findmodel(mid: integer): integer
ct:=0
returned:=-1
forall(p in modqueue, ct as counter)
if p.id=mid then
returned:= p.rid
! Delete temporary files
removefiles(SYS_RECURS, p.tempdir, "*")
removedir(p.tempdir)
! Delete entries from list
unload(p.m)
break
end-if
if returned<0 then
writeln("Queue entry not found")
elif ct=1 then
cuthead(modqueue,1)
elif ct=modqueue.size then
cuttail(modqueue,1)
elif ct>1 and ct<modqueue.size then
tqueue:=splittail(modqueue,-ct+1)
cuthead(tqueue,1)
modqueue+=tqueue
end-if
end-function
!**** Server: receive optimization requests, start submodel, send back results
! Server configuration
setparam("http_defport",2533) ! Set server port (2533)
setparam("http_maxreq", 4) ! Max. number of simultaneous requests
setparam("http_srvconfig",HTTP_POST) ! Only POST requests
setparam("workdir",getparam("tmpdir")) ! Move to temporary directory
httpstartsrv ! Start the server
! Handle events received by the server
repeat
wait ! Wait for an event
ev:=getnextevent
if ev.class=EVENT_HTTPNEW then ! Request pending
r:=integer(ev.value) ! Get request ID
if httpreqtype(r)=HTTP_POST and ! This is redundant (only POST expected)
httpreqlabel(r)="runmodel" then
!**** Extract data and start model run ****
writeln(time(SYS_NOW), " Request ", r, " received from ", httpreqfrom(r))
if httpreqstat(r)<>2 then ! Whether data file exists
httpreplycode(r,400,"Missing data archive") ! Reply "Bad request"
else
modqueue += [newfoliomod(r)]
end-if
else
httpreplycode(r,400) ! "Bad request"
end-if
elif ev.class=EVENT_END then
!**** Retrieve results file and return it to the client; cleaning up ****
! Retrieve sender model ID
evmodid:= ev.fromid
! Find model in queue and remove it
rid:=findmodel(evmodid)
! fcopy(httpreqfile(rid),"") ! Display file contents
! Reply to client
writeln(time(SYS_NOW), " Reply to request ", rid)
if ev.value=RT_OK then
httpreply(rid,httpreqfile(rid))
elif ev.value=RT_LICERR then
httpreplycode(rid, 500, "No license available to run optimization model")
else
httpreplycode(rid, 500, "Error during model execution")
end-if
end-if
until false
end-model
|
|
foliohttpclient.mos |
(!******************************************************
Mosel Example Problems
======================
file foliohttpclient.mos
````````````````````````
Sending HTTP requests for model runs with
XML-format data to a server, retrieving and
displaying the results.
*** Before running this model, an HTTP server must be
*** launched by running the file foliohttpsrv.mos.
(c) 2013 Fair Isaac Corporation
author: S.Heipcke, July 2013
*******************************************************!)
model "HTTP client launching portfolio model"
uses "mmhttp" ! Use HTTP functions
uses "mmxml" ! Use XML format
parameters
DATAFILE= "folio.xml" ! File with problem data
OUTFILE= "result.xml" ! 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
SERVERNAME = "localhost" ! Configure with the machine name/address
! that is running foliohttpsrv.mos
end-parameters
declarations
ResData: xmldoc ! XML document
SList: list of integer ! XML nodes
end-declarations
! Create a temporary file with the configuration data
TEMPDIR:=getparam("tmpdir")+"/tartemp"
makedir(TEMPDIR)
initializations to TEMPDIR+"/folioconfig.dat"
MAXRISK
MAXVAL
MINAM
DATAFILE
end-initializations
! Create an archive with the configuration data + XML data file
fcopy(DATAFILE, TEMPDIR)
newtar(0, "zlib.gzip:tmp:folio.tgz", TEMPDIR, [DATAFILE, "folioconfig.dat"])
! Delete temporary files
removefiles(SYS_RECURS, TEMPDIR, "*")
removedir(TEMPDIR)
! Post the solving request (synchronous mode => waits for reply from server)
status:=httppost("http://" + SERVERNAME + ":2533/runmodel",
"tmp:folio.tgz", OUTFILE)
! Display the result
if status/100=2 then
load(ResData, OUTFILE) ! Reading data from an XML file
sol:=getnode(ResData, "result/solution")
writeln("Solution with value ", getattr(ResData, sol, "value"), ":")
getnodes(ResData, sol, "share", SList)
forall(s in SList)
writeln(" ", getattr(ResData, s, "name"), ": ", getvalue(ResData, s))
else
writeln("Request failed with code: ", status, " (", httpreason(status), ")")
fcopy(OUTFILE,"") ! Display output file contents (error msg)
end-if
end-model
|
|