I have used quantmod
to download prices for a bunch of assets, and then I've merged the data sets to one time series.
library(quantmod)
# Vector of stocks
stocks <- c('AEIS', 'ABC', 'AMGN', 'BBY', 'HRB', 'BKE', 'CPLA', 'GIB')
# Download data sets
getSymbols(stocks)
# Generate time series of prices
prices.data <- do.call(merge, lapply(stocks, function(x) Cl(get(x))))
colnames(prices.data) <- stocks
head(prices.data)
AEIS ABC AMGN BBY HRB BKE CPLA GIB
2007-01-03 18.75 23.055 68.40 49.06 23.20 23.00123 25.44 6.73
2007-01-04 18.89 23.145 71.33 49.84 23.28 22.73215 25.19 6.78
2007-01-05 18.63 22.865 71.50 50.00 22.95 21.87720 25.00 6.71
2007-01-08 18.88 23.225 70.93 49.42 23.27 21.76003 25.00 6.76
2007-01-09 18.66 23.150 71.27 49.04 23.48 22.54554 24.84 6.79
2007-01-10 18.93 23.260 71.04 49.41 23.97 22.12458 25.02 6.85
I would now like a new time series, returns.data
, containing the monthly returns for each asset. How do I generate this in the smoothest fashion possible?
Smoothest possible fashion ... this one liner?
Just use utilities from quantmod monthlyReturn
:
out <- setNames(do.call(cbind, lapply(prices.data, monthlyReturn)), stocks)
setNames
allows you to update the column names without having to write another replacement function (http://adv-r.had.co.nz/Functions.html#special-calls) on another line, which would typically be something like colnames(out) <- stocks
(I emphasise you don't need to do this).
head(out)
AEIS ABC AMGN BBY HRB BKE CPLA GIB
2007-01-31 -0.075733333 0.135979224 0.02880118 0.02731351 0.06034478 -0.049622659 0.11713832 0.15898960
2007-02-28 0.162146509 0.004200000 -0.08682678 -0.07777781 -0.11300813 0.027695074 0.15095000 0.08461538
2007-03-30 0.044687291 0.002851749 -0.13040773 0.04819279 -0.03574698 0.034482762 0.02537457 0.02364066
2007-04-30 0.164448614 -0.052322237 0.14781671 -0.04248766 0.07461977 -0.002240886 0.04203935 0.03810624
2007-05-31 0.001632694 0.024604920 -0.11989395 0.03515539 0.04776647 0.148231314 0.25207430 0.20244716
2007-06-29 -0.076609655 -0.034166340 -0.02054916 -0.03354738 -0.01350781 -0.036674811 0.05187388 0.03792784