** mvport package v2 * ovport command * Author: Alberto Dorantes, July, 2016 * cdorante@itesm.mx capture program drop ovport program ovport, rclass version 11.0 syntax varlist(min=2 numeric ts) [if] [in][, rfrate(real 0)] [NOShort] [NPort(real 100)] [MINweight(real -1)] [MAXweight(real -1)] [CASEwise] [RMINweights(numlist)] [RMAXweights(numlist)] [COVMatrix(string)] [MRets(string)] marksample touse tempname peso i vecweights meanrets covmat srmin srmax rmin rmax vecmaxweights sumw local nvar : word count `varlist' if "`casewise'"=="" { marksample touse, novarlist } if "`mrets'"!="" { capture matrix `meanrets' = `mrets' if (_rc!=0) { display as error "The matrix for Expected Returns does not exist; define a Stata Matrix (Vertical Vector of N rows and 1 column)" exit } else if (rowsof(`meanrets')!=`nvar') { display as error "The length of the vertical mean vector specified in the mrets option is not equal to the number of variables " exit } else { mata: MR=st_matrix("`mrets'") mata: st_numscalar("srmin",min(MR)) mata: st_numscalar("srmax",max(MR)) local rmax=srmax local rmin=srmin * matrix `meanrets' = J(1,1,0) } } else { quietly meanrets `varlist' `if' `in', `casewise' scalar srmax=r(maxret) scalar srmin=r(minret) local rmax=srmax local rmin=srmin matrix `meanrets'=r(meanrets) } if "`covmatrix'"!="" { capture matrix `covmat' = `covmatrix' if (_rc!=0) { display as error "The Variance-Covariance Matrix does not exist; define a Stata Matrix with that name or change to the right matrix name" exit } else if (rowsof(`covmat')!=`nvar' | colsof(`covmat')!=`nvar') { display as error "The number of columns or rows of the variance-covariance matrix specified in the covm option is not equal to the number of variables " exit } } else { matrix `covmat' = J(1,1,0) } local i=0 local sumw=0 matrix `vecmaxweights'=J(`nvar',1,100) matrix `vecweights'=J(`nvar',1,-100) if "`rmaxweights'"!="" { foreach peso in `rmaxweights' { if `i'<`nvar' { local i=`i'+1 matrix `vecmaxweights'[`i',1] = `peso' local sumw=`sumw'+`peso' } } if `sumw'<=1 { display as error "The sum of each weight specified for the returns is too small; it is not possible to assign 100% in the weights." exit } } else { if `maxweight'!=-1 { if `maxweight'*`nvar'<=1 { display as error "The maximum weight specified for all returns is too small; it is not possible to assign 100% in the weights." exit } matrix `vecmaxweights'=J(`nvar',1,`maxweight') } } if ("`rmaxweights'"!="" | `maxweight'!=-1) { mata: maxr=m_getmaxr(st_matrix("`meanrets'"),st_matrix("`vecmaxweights'")) mata: st_numscalar("srmax",maxr) local rmax=srmax } local i=0 local sumw=0 if "`rminweights'"!="" { local noshort "noshort" matrix `vecweights'=J(`nvar',1,0) foreach peso in `rminweights' { if `i'<`nvar' { local i=`i'+1 matrix `vecweights'[`i',1] = `peso' local sumw=`sumw'+`peso' } } if `sumw'>=1 { display as error "The minimum weights specified for each returns exceed 1 (100%); you have to change them so that the sum of all minimum weights is less than 1" exit } } * else { if `minweight'!=-1 { if `minweight'*`nvar'>=1 { display as error "The minimum weight specified for all returns is not valid; they exceed 1 (100%) considering all returns" exit } matrix `vecweights'=J(`nvar',1,`minweight') local noshort "noshort" } else if "`noshort'"!="" { local minweight 0 matrix `vecweights'=J(`nvar',1,0) } } tempname rcov retp sdp vsharpe vsharpe_order sharpe wop rop sdop N exprets i wef vsdef vref nnoshort mcr cr pcr betas matrix `wop'=J(`nvar',1,.) local nnoshort=("`noshort'"!="") if "`noshort'"=="" { qui gmvport `varlist' `if' `in', `casewise' maxweight(`maxweight') rmaxweight(`rmaxweight') covmatrix(`covmatrix') mrets(`mrets') if (`rfrate'>=r(retport)) { display as error "The risk-free rate is smaller than the global minimum variance portfolio return, which is equal to " r(retport) display as error "The risk-free rate was assigned to " r(retport) local rfrate=r(retport) } mata: `wop'=m_ovport("`varlist'",st_matrix("`vecweights'"),`nport',`rfrate',"`touse'", "`casewise'", st_matrix("`covmat'"), st_matrix("`meanrets'"),st_matrix("`vecmaxweights'"), `nnoshort') } else { cmline `varlist' `if' `in', noshort nport(`nport') rfrate(`rfrate') `casewise' minweight(`minweight') maxweight(`maxweight') rminweights(`rminweights') rmaxweights(`rmaxweights') covmatrix(`covmatrix') mrets(`mrets') nograph } matrix `exprets'=r(exprets) local N=rowsof(`exprets') matrix `wop'=r(wop) matrix `rcov'=r(cov) matrix `mcr' = r(mcr) matrix `cr' = r(cr) matrix `pcr' =r(pcr) matrix `betas' =r(betas) foreach v of varlist `varlist' { local nomvar "`nomvar' `v'" } matrix colnames `wop' = "Weights" matrix rownames `wop' = `nomvar' matrix rownames `rcov' = `nomvar' matrix colnames `rcov' = `nomvar' matrix rownames `mcr' = `nomvar' matrix colnames `mcr' = "Marginal Contribution to Risk" matrix rownames `cr' = `nomvar' matrix colnames `cr' = "Contribution to Risk" matrix rownames `pcr' = `nomvar' matrix colnames `pcr' = "Percent Contribution to Risk" matrix rownames `betas' = `nomvar' matrix colnames `betas' ="Asset betas" matrix `vsharpe'=r(vsharpe) scalar `sharpe'=r(sharpe) scalar `rop'=r(rop) scalar `sdop'=r(sdop) display "Number of observations used to calculate expected returns and var-cov matrix : " r(N) if "`noshort'"=="" { display "The weight vector of the Tangent Portfolio with a risk-free rate of `rfrate' (Allowing Short Sales) is:" } else { display "The weight vector of the Tangent Portfolio with a risk-free rate of `rfrate' (NOT Allow Short Sales) is:" } matrix list `wop', noh noblank display "The return of the Tangent Portfolio is: " r(rop) display "The standard deviation (risk) of the Tangent Portfolio is: " r(sdop) display "The marginal contributions to risk of the assets in the Tangent Portfolio are:" matlist `mcr' return matrix weights=`wop' return matrix cov=`rcov' return matrix exprets=`exprets' return matrix mcr=`mcr' return matrix cr=`cr' return matrix pcr=`pcr' return matrix betas=`betas' return scalar sharper= r(sharper) return scalar rop=r(rop) return scalar sdop=r(sdop) return scalar varop=r(varop) return scalar rfrate=`rfrate' end