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_vett...@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.ps...@gmail.com> wrote: > > From: Joshua Wiley <jwiley.ps...@gmail.com> > Subject: Re: [R] Calculating Portfolio Standard deviation > To: "Amelia Vettori" <amelia_vett...@yahoo.co.nz> > Cc: "r-help@r-project.org" <r-help@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_vett...@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@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/ ______________________________________________ R-help@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.