Complete example
The complete model file folioloop_graph.mos with all the features discussed in this chapter looks as follows. Notice that the two modules mmxprs and mmive may be loaded with a single uses statement. The deviation data may either be added to the original data file or, as shown here, read from a second file.
model "Portfolio optimization with LP"
uses "mmxprs", "mmsvg" ! Use Xpress Optimizer with SVG graphing
parameters
DATAFILE= "folio.dat" ! File with problem data
DEVDATA= "foliodev.dat" ! File with deviation data
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
DEV: array(SHARES) of real ! Standard deviation
SOLRET: array(range) of real ! Solution values (total return)
SOLDEV: array(range) of real ! Solution values (average deviation)
end-declarations
initializations from DATAFILE
RISK RET NA
end-initializations
initializations from DEVDATA
DEV
end-initializations
declarations
frac: array(SHARES) of mpvar ! Fraction of capital used per share
Return, Risk: linctr ! Constraint declaration (optional)
end-declarations
! Objective: total return
Return:= sum(s in SHARES) RET(s)*frac(s)
! 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 for different limits on high-risk shares
ct:=0
forall(r in 0..20) do
! Limit the percentage of high-risk values
Risk:= sum(s in RISK) frac(s) <= r/20
maximize(Return) ! Solve the problem
if (getprobstat = XPRS_OPT) then ! Save the optimal solution value
ct+=1
SOLRET(ct):= getobjval
SOLDEV(ct):= getsol(sum(s in SHARES) DEV(s)*frac(s))
else
writeln("No solution for high-risk values <= ", 100*r/20, "%")
end-if
end-do
! Drawing a graph to represent results (`GrS') and data (`GrL' & `GrH')
svgaddgroup("GrS", "Solution values", SVG_GREY)
svgaddgroup("GrL", "Low risk", SVG_GREEN)
svgaddgroup("GrH", "High risk", SVG_RED)
forall(r in 1..ct) svgaddpoint("GrS", SOLRET(r), SOLDEV(r))
svgaddline("GrS", sum(r in 1..ct) [SOLRET(r), SOLDEV(r)])
forall(s in SHARES - RISK) do
svgaddpoint("GrL", RET(s), DEV(s))
svgaddtext("GrL", RET(s)+1, 1.3*(DEV(s)-1), s)
end-do
forall(s in RISK) do
svgaddpoint("GrH", RET(s), DEV(s))
svgaddtext("GrH", RET(s)-2.5, DEV(s)-1, s)
end-do
! Scale the size of the displayed graph
svgsetgraphscale(10)
svgsetgraphpointsize(2)
! Optionally save graphic to file
svgsave("foliograph.svg")
! Display the graph and wait for window to be closed by the user
svgrefresh
svgwaitclose
end-model The problem is not feasible for small limit values on the constraint Risk. Besides the graphs we therefore obtain the following text output:
No solution for high-risk values <= 0% No solution for high-risk values <= 5% No solution for high-risk values <= 10% No solution for high-risk values <= 15%
© 2001-2019 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.
