# [R] Calculating Portfolio Standard deviation

Joshua Wiley jwiley.psych at gmail.com
Mon Jan 10 12:47:45 CET 2011

```Dear Amelia,

I find it hard to believe I'm not reinventing the wheel here, but
here's a little function.  If no weights are specified it uses all 1s.

## Define function
lvar <- function(x, weights, na.rm = TRUE) {
if (missing(weights)) {
weights <- rep(1, ncol(x))
}

covmat <- var(x = x, na.rm = na.rm)
utc <- upper.tri(covmat)
wt.var <- sum(diag(covmat) * weights^2)
wt.cov <- sum(weights[row(covmat)[utc]] *
weights[col(covmat)[utc]] *
covmat[utc])
variance <- wt.var + 2 * wt.cov
return(variance)
}

## example with weights
lvar(x = prices_df, weights = c(0.10, 0.25, 0.20, 0.45))

HTH,

Josh

On Mon, Jan 10, 2011 at 3:14 AM, Amelia Vettori
<amelia_vettori at yahoo.co.nz> wrote:
>
> Dear Patric and Joshua sirs,
>
> Thanks a lot for the great solution. This code works perfectly when we are assigning equal weights, however problem is I do need to use the weights assigned.
>
> And yes I will be calculating the co-variance for the price returns only. Here for an example sake I had taken the prices. I am working on equity, bond and currency portfolio and since the valuations methods differ in each case, I am for the time being dealing separately with these instruments. Once, the portfolio value series is ready, I will be taking the returns and then calculate the covariance matrix etc and proceed on. Just for the sake of simplicity, I am as an example taking prices rather than the return on prices. But sir, thanks a lot for bringing this to notice as others may follow this thread in future.
>
> As regards the R code provided by Joshua sir, there is no problem in assigning the weights to the diagonal elements as I had done below
>
> diag_elements = sum(diag(Vdat)*weights^2). However, the problem does exist for the elemnts appearing in the upper covariance matrix (i.e. Vdat[upper.tri(Vdat)] ). Perhaps one may have to use the loop.
>
> # For Non diagonal elements
>
> weights = c(0.10, 0.25, 0.20, 0.45)
>
> > Vdat
>             ABC        DEF        GHI        JKL
> ABC  11.2111111 -0.7111111  -1.833333 -11.011111
> DEF  -0.7111111 15.6000000   6.222222   4.511111
> GHI  -1.8333333  6.2222222  24.722222 -21.055556
> JKL -11.0111111  4.5111111 -21.055556  87.211111
>
>
> B = NULL
>
> for(i in 1:4)
>     {
>         for (j in 1:4)
>             {
>             if(i!=j)
>                 {
>
>                 B[i] = weights[i]*weights[j]*Vdat[i,j]
>                 }
>             }
>     }
>
> B      # The idea is the sum(B) would give me the weighted non-diagonal elements. This gives me
>
> > B
> [1] -0.4955  0.5075 -1.8950 -1.8950
>
> However, actually I should be getting
>
> -0.017778, -0.036667, -0.4955, 0.31111, 0.5075, -1.8950
>
> That's because when I consider (1,2), (1,3) or(1,4) it stores the value for B[1] only once and likewise.
>
> Kindly guide.
>
>
> regards
>
> Amelia
>
> --- On Mon, 10/1/11, Joshua Wiley <jwiley.psych at gmail.com> wrote:
>
> From: Joshua Wiley <jwiley.psych at gmail.com>
> Subject: Re: [R] Calculating Portfolio Standard deviation
> To: "Amelia Vettori" <amelia_vettori at yahoo.co.nz>
> Cc: "r-help at r-project.org" <r-help at r-project.org>
> Received: Monday, 10 January, 2011, 9:05 AM
>
> Dear Amelia,
>
> If you have the actual data you should be able to use the variance covariance matrix to simplify this
>
> Vdat <- cov(prices_df)
>
> sum(diag(Vdat)) + 2*Vdat[upper.tri(Vdat)]
>
> By using covariances instead of correlations you do not need to multiply by he standard deviations and by using variances there's no need to square. The only trick would be adding your weights back in.  See ?diag and ?upper.tri and ?vcov for relevant documentation.
>
> Cheers,
>
> Josh
>
> On Jan 10, 2011, at 0:26, Amelia Vettori <amelia_vettori at yahoo.co.nz> wrote:
>
> > Dear R helpers
> >
> > I have following data
> >
> > stocks <- c("ABC", "DEF", "GHI", "JKL")
> >
> > prices_df <- data.frame(ABC = c(17,24,15,22,16,22,17,22,15,19),
> >                                          DEF = c(22,28,20,20,28,26,29,18,24,21),
> >                                           GHI = c(32,27,32,36,37,37,34,23,25,32),
> >
> >                                           JKL = c(47,60,60,43,62,38,44,53,61,41))
> >
> > sd_prices <- c(3.3483,3.9497,4.9721,9.3387)   # standard deviations say(sd1, sd2, sd3, sd4)
> >
> > weights <- c(0.10, 0.25, 0.20, 0.45)      # say (w1, w2, w3, w4)
> >
> > I need to calculate the standard deviation of the portfolio. The formula is
> >
> > stdev_portfolio = sqrt((w1*sd1)^2+(w2*sd2)^2+(w3*sd3)^2+(w4*sd4)^2 +
> >                         2*w1*w2*sd1*sd2*correlation(ABC, DEF)+
> >
> >                      2*w1*w3*sd1*sd3*correlation(ABC, GHI)+
> >                         2*w1*w4*sd1*sd4*correlation(ABC, JKL)+
> >                         2*w2*w3*sd2*sd3*correlation(DEF, GHI)+
> >                         2*w2*w4*sd2*sd4*correlation(DEF, JKL)+
> >                         2*w3*w4*sd3*sd4*correlation(GHI, JKL))
> >
> >
> >
> > OR if we define
> >
> > P = sd_prices*weights
> >
> > I need to calculate
> >
> > stdev_portfolio = sqrt((P1)^2+(P2)^2+(P3)^2+(P4)^2 +
> >                         2*P1*P2*correlation(ABC, DEF)+
> >                         2*P1*P3*correlation(ABC, GHI)+
> >                         2*P1*P4*correlation(ABC, JKL)+
> >                         2*P2*P3*correlation(DEF,
> > GHI)+
> >                         2*P2*P4*correlation(DEF, JKL)+
> >                         2*P3*P4*correlation(GHI, JKL))
> >
> > In reality I will be dealing with not 4, but many stocks and hence I can't generalize this as
> >
> > stdev_portfolio = sqrt((P[1])^2+(P[2])^2+(P[3])^2+(P[4)^2 +
> >                         2*P[1]*P[2]*correlation(ABC, DEF)+
> >                         2*P1*P3*correlation(ABC,
> > GHI)+
> >                         2*P1*P4*correlation(ABC, JKL)+
> >                         2*P2*P3*correlation(DEF, GHI)+
> >                         2*P2*P4*correlation(DEF, JKL)+
> >                         2*P3*P4*correlation(GHI, JKL))
> >
> > Kindly advise as to how do I
> > calculate the portfolio standard deviation?
> >
> > Thanking in advance
> >
> > Amelia Vettori
> >
> >
> >
> >    [[alternative HTML version deleted]]
> >
> > ______________________________________________
> > R-help at r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-help
> > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> > and provide commented, minimal, self-contained, reproducible code.
>
>

--
Joshua Wiley
Ph.D. Student, Health Psychology
University of California, Los Angeles
http://www.joshuawiley.com/

```

More information about the R-help mailing list