Initializing help system before first use

Portfolio optimization


Type: Portfolio optimization(QP)
Rating: 3 (intermediate)
Description: An investor is evaluating ten different securities ('shares'). He estimates the return on investment for a period of one year. To spread the risk he wishes to invest at most 30% of the capital into any share. He further wishes to invest at least half of his capital in North-American shares and at most a third in high-risk shares. How should the capital be divided among the shares to minimize the risk whilst obtaining a certain target yield? The investor adopts the Markowitz idea of getting estimates of the variance/covariance matrix of estimated returns on the securities.
File(s): folioqp_graph.mos
Data file(s): folioqpgraph.dat


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

   file folioqpgraph.mos
   `````````````````````
   TYPE:         Portfolio optimization problem (Quadratic Programming problem)
   DIFFICULTY:   3
   FEATURES:     small QP problem, solved repeatedly with modified
                 constraints, graphical representation of the results,
                 use of `min' and `max'
   DESCRIPTION:  An investor is evaluating ten different securities (`shares').
                 He estimates the return on investment for a period of one 
                 year. To spread the risk he wishes to invest at most 
                 30% of the capital into any share. He further wishes to 
                 invest at least half of his capital in North-American 
                 shares and at most a third in high-risk shares. How should 
                 the capital be divided among the shares to  minimize the 
                 risk whilst obtaining a certain target yield? The investor 
                 adopts the Markowitz idea of getting estimates of the 
                 variance/covariance matrix of estimated returns on the 
                 securities.     
   FURTHER INFO: `Getting Started with Xpress', Chapter 7 `Quadratic
                 Programming'.
                 Similar problem:
                 `Applications of optimization with Xpress-MP', 
                 Section 13.7 `Mean variance portfolio selection'
   
   (c) 2008 Fair Isaac Corporation
       author: S. Heipcke, 2003, rev. Sep. 2017
*******************************************************!)

model "Portfolio optimization with QP"
 uses "mmxprs", "mmnl", "mmsvg"      ! Use Xpress Optimizer with QP solver

 parameters
  MAXVAL = 0.3                       ! Max. investment per share
  MINAM = 0.5                        ! Min. investment into N.-American values
 end-parameters

 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
  SOLRET: array(range) of real       ! Solution values (total return)
  SOLDEV: array(range) of real       ! Solution values (average deviation)
 end-declarations

 initializations from "folioqpgraph.dat"
  RISK RET NA VAR
 end-initializations

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

! Objective: mean variance
 Variance:= sum(s,t in SHARES) VAR(s,t)*frac(s)*frac(t) 

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

! Spend all the capital
 SpendAll:= 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 a range of returns: this is the efficient frontier
 target:= min(s in SHARES) RET(s)
 RMAX:= max(s in SHARES) RET(s)

 while(target < RMAX) do
  Return:= sum(s in SHARES) RET(s)*frac(s) >= target    ! Target yield
  minimize(Variance)                ! Solve the problem
   
  if (getprobstat = XPRS_OPT) then  ! Save the optimal solution value
   ct+=1
   SOLDEV(ct):= getobjval
   SOLRET(ct):= target
  else
   writeln("No solution for target return >= ", ct, "%")
   break
  end-if
  target += 1
 end-do

! Drawing a graph to represent results (`GrS') and data (`GrL' & `GrH') 
 declarations
  DEV: array(SHARES) of real         ! Standard deviation
  NAMES: array(SHARES) of string     ! Names of shares
 end-declarations

 initializations from "folioqpgraph.dat"
  DEV NAMES
 end-initializations
	
 svgaddgroup("GrS", "Solution values", SVG_BLACK)
 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), NAMES(s))
 end-do

 forall (s in RISK) do
  svgaddpoint("GrH", RET(s), DEV(s))
  svgaddtext("GrH", RET(s)-2.5, DEV(s)-1, NAMES(s))
 end-do

! Scale the size of the displayed graph
 svgsetgraphscale(10)
 svgsetgraphpointsize(2)
 svgsetgraphlabels("Expected return", "Standard deviation")

 svgsave("folioqpgraph.svg")
 svgrefresh
 svgwaitclose("Close browser window to terminate model execution.", 1)
 
end-model 

© 2001-2026 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.