Folio - performing simple statistics with R
|
|
Type: | Portfolio optimization |
Rating: | 2 (easy-medium) |
Description: | Using R to calculate the covariance matrix that serves as input to a quadratic optimization problem minimizing the variance of an investment portfolio. Model version 'folioqpgraphr.mos' uses R graph drawing functionality to plot the deviation and display a correlation heatmap. |
File(s): | folioqpr.mos, folioqpgraphr.mos |
Data file(s): | folioqphist.dat, folioqp.dat, folioqpgraph.dat |
|
folioqpr.mos |
(!****************************************************** Mosel Example Problems ====================== file folioqpr.mos ````````````````` Modeling a small QP problem to perform portfolio optimization. -- 1. QP: minimize variance 2. MIQP: limited number of assets -- -- Using R to calculate covariance matrix -- !!! This example requires an installation of R, see the !!! chapter 'R' of the 'Mosel Language Reference' for !!! compatible versions and setup instructions (c) 2015 Fair Isaac Corporation author: S.Lannez, Jul. 2015, rev. Sep. 2017 *******************************************************!) model "Portfolio optimization with QP/MIQP" uses "mmxprs", "mmnl" uses "r" ! Use R 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 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 DATES: set of string ! Historical dates RET: array(SHARES) of real ! Estimated return in investment VAR: array(SHARES,SHARES) of real ! Variance/covariance matrix of ! estimated returns OPEN: array(SHARES,DATES) of real ! Historical share value at market opening CLOSE: array(SHARES,DATES) of real ! Historical share value at market closing end-declarations initializations from "folioqp.dat" RISK RET NA end-initializations ! Load historical values to compute the covariance initializations from "folioqphist.dat" OPEN CLOSE end-initializations ! **** Perform some statistics using R **** ! Copy array to R environments Rset('open',OPEN) Rset('close',CLOSE) ! Print covariance of share value at market openings writeln("Covariances at market openings:") Rprint('cov(t(open))') ! Calculate and retrieve covariance of mean value Rgetarr('cov(t((open+close)/2))',VAR) 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, "%") ! **** 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, "%") ! Round integer values and resolve fixglobal(true) minimize(Variance) writeln("With all binary variables rounded to the nearest integer:") forall(s in SHARES) writeln(s, ": ", getsol(frac(s))*100, "%") end-model |
folioqpgraphr.mos |
(!****************************************************** Mosel R Example Problems ======================== file folioqpgraphr.mos `````````````````````` Modeling a small QP problem to perform portfolio optimization. Minimize variance subject to different target return. -- Using R to calculate covariance matrix -- -- Graphical output via R -- !!! This example requires an installation of R, see the !!! chapter 'R' of the 'Mosel Language Reference' for !!! compatible versions and setup instructions (c) 2015 Fair Isaac Corporation author: S.Lannez, Jul. 2015, rev. Sep. 2017 *******************************************************!) model "Portfolio optimization with QP, graphical output" uses "mmxprs", "mmnl" uses "mmsystem" uses "r" ! Use R functions parameters MAXVAL = 0.3 ! Max. investment per share MINAM = 0.5 ! Min. investment into N.-American values GRDEVICE = "png" ! Set to 'png' or 'pdf' to change the type of document. 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 DATES: set of string ! Historical dates RET: array(SHARES) of real ! Estimated return in investment VAR: array(SHARES,SHARES) of real ! Variance/covariance matrix of ! estimated returns OPEN: array(SHARES,DATES) of real ! Historical share value at market opening CLOSE: array(SHARES,DATES) of real ! Historical share value at market closing SOLRET: array(range) of real ! Solution values (total return) SOLDEV: array(range) of real ! Solution values (average deviation) end-declarations initializations from "folioqp.dat" RISK RET NA end-initializations ! Load historical values to compute the covariance initializations from "folioqphist.dat" OPEN CLOSE end-initializations ! **** Perfom some statistics using R **** ! Copy array to R environments Rset('open',OPEN) Rset('close',CLOSE) ! Print covariance of share value at market openings writeln("Covariances at market openings:") Rprint('cov(t(open))') ! Calculate and retrieve covariance of mean value Rgetarr('cov(t((open+close)/2))',VAR) ! **** Mathematical model **** 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 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 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 writeln("Solution for target ", target, "%") else writeln("No solution for target return >= ", target, "%") break end-if target += 1 end-do ! **** Drawing graphs to represent results and data **** declarations DEV: array(SHARES) of real ! Standard deviation NAMES: array(SHARES) of string ! Names of shares t: text end-declarations initializations from "folioqpgraph.dat" NAMES ! DEV end-initializations ! Compute the standard deviation forall(s in SHARES) DEV(s) := sqrt(VAR(s,s)) ! Setting up the R environment Reval('require(graphics)') ! plot() and heatmap() functions Reval('require(grDevices)') ! heatmap dependency if (GRDEVICE.size>0) then Reval(GRDEVICE+'("folioqpgraphr%03d.'+GRDEVICE+'")') ! Open graphical file end-if ! **** Drawing the efficient frontier **** ! Copy arrays to R Rset('solval',SOLRET) Rset('soldev',SOLDEV) ! Plot the graphs Reval('plot(solval,soldev,color="black",type="l",'+ 'main="Portfolio Return",'+ 'xlab="Solution Value",ylab="Solution Variance")') Reval('points(solval,soldev,pch=21,cex=1,col="dark red")') if (GRDEVICE.size=0) then ! Wait for user entry Reval('dev.flush()') ! Print plots writeln("Press enter to continue...") dummy := readtextline(t) end-if ! Clean up arrays Reval('rm(solval)') Reval('rm(soldev)') ! **** Drawing the shares characteristics **** ! Copy arrays to R Rset('ret',RET) Rset('dev',DEV) Rset('names',NAMES) Rset('risk',RISK) Rset('shares',SHARES) ! Create the color vectors Reval('h <- c()') Reval('h[shares] <- "green"') Reval('h[risk] <- "red"') ! Plot the graphs Reval('plot(ret,dev,col=h,bg=h,type="p",pch=21,'+ 'main="Shares",'+ 'xlab="Share Value",ylab="Share Deviation",'+ 'xlim=c(-5,max(ret)+5),ylim=c(min(dev)-5,max(dev)+5))') Reval('legend("topleft",c("high risk","low risk"),'+ 'col=c("red","green"),pch=21)') Reval('text(ret,dev,names,pos=3)') if (GRDEVICE.size=0) then ! Wait for user entry Reval('dev.flush()') ! Print plots writeln("Press enter to continue...") dummy := readtextline(t) end-if ! Clean up arrays forall(ar in {"ret","dev","risk","shares"}) Reval('rm('+ar+')') ! **** Drawing the correlation heat map **** Reval('z <- cor(t(open+close)/2)') ! Compute the correlation matrix Reval('rownames(z) <- names') ! Set the name of the rows Reval('colnames(z) <- names') ! Set the name of the columns Rprint('symnum(z)') ! Textual representation of the correlation Reval('heatmap(z,Rowv=NA,Colv=NA,symm=TRUE,main="Share Value Correlation")') if (GRDEVICE.size=0) then ! Wait for user entry Reval('dev.flush()') ! Print plots writeln("Press enter to continue...") dummy := readtextline(t) end-if Reval('dev.off()') ! Close current document end-model |
© 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.