Computing Returns for Multiple Securities with quantmod
Summary
The document addresses calculating daily, weekly, or monthly returns from adjusted closing prices for several securities downloaded with quantmod in R. The central issue is that functions such as weeklyReturn are intended for a univariate series, while the example passes a merged multi-column time series and gets an unexpected result.
One suggested approach applies the return function separately to each column and merges the outputs. Another first aggregates each adjusted-price series to weekly closes, then calculates log differences across those observations. A further answer splits the merged data by series before calculating returns at several frequencies. The examples illustrate practical alternatives, but they do not compare their handling of missing dates, alignment, or period conventions; users should check those details for their own data and chosen return definition.
Key ideas
- Return functions designed for univariate series should be applied separately to each security in a merged price object.
- The per-security return series can be merged afterward for cross-asset analysis.
- Weekly log returns can be computed by aggregating prices to weekly closes and differencing their logarithms.
- Missing observations and date alignment can affect results when securities have different histories.
- Return frequency and aggregation conventions should match the intended analysis.
Tags
Full text
# Calculate return for a set of securities downloaded using quantmod
# Calculate return for a set of securities downloaded using quantmod
I downloaded adjusted closing price using quantmod for a set of securities. I want to calculate daily/weekly/monthly return for all securities. Usual dailyReturn, weeklyReturn etc not working. What do I need to do? Here is my code.
```
tickers <- c('FB','MMM')
data_env <- new.env()
getSymbols(Symbols = tickers, env = data_env)
tempPort <- do.call(merge, eapply(data_env, Ad))
head(tempPort )
MMM.Adjusted FB.Adjusted
2007-01-03 57.00983 NA
2007-01-04 56.78401 NA
2007-01-05 56.39790 NA
2007-01-08 56.52174 NA
2007-01-09 56.58731 NA
2007-01-10 56.71116 NA
head(weeklyReturn(tempPort, type = 'log', leading=TRUE))
weekly.returns
2012-05-18 -0.010791856
2012-05-25 0.015093078
2012-06-01 -0.023027534
2012-06-08 0.037315263
2012-06-15 0.016605617
2012-06-22 -0.007000966
```
It returned garbage. How to handle this?
## Answer by Robert (score 0)
https://quant.stackexchange.com/a/45836
`weeklyReturn`is for univariate series.
Try this
```
tail(do.call("merge",apply(tempPort,2,weeklyReturn,type = 'log', leading=TRUE)))
# weekly.returns weekly.returns.1
# 2019-04-18 0.006692682 -0.00458900
# 2019-04-26 -0.132748543 0.07148027
# 2019-05-03 -0.034230826 0.02057131
# 2019-05-10 -0.051856081 -0.03715810
# 2019-05-17 -0.039257136 -0.01627267
# 2019-05-24 -0.009381505 -0.02314769
```
## Answer by Wilson Freitas (score 0)
https://quant.stackexchange.com/a/68427
Maybe create a weekly series before calculating returns.
```
library(xts)
library(quantmod)
tickers <- c('FB','MMM')
data_env <- new.env()
getSymbols(Symbols = tickers, env = data_env)
tempPort_weekly <- do.call(merge, eapply(data_env, function(x) {
x <- Ad(x)
w <- Cl(to.weekly(x))
colnames(w) <- colnames(x)
w
}))
tail(diff(log(tempPort_weekly)))
#> MMM.Adjusted FB.Adjusted
#> 2021-09-10 -0.051945999 0.006437513
#> 2021-09-17 -0.016719862 -0.037587995
#> 2021-09-24 -0.002482621 -0.032775228
#> 2021-10-01 -0.024377816 -0.028595080
#> 2021-10-08 0.001527043 -0.038515509
#> 2021-10-15 0.027809784 -0.016157643
```
Created on 2021-10-18 by the reprex package (v0.2.1)
## Answer by Jien Weng (score 0)
https://quant.stackexchange.com/a/85495
The `tempPort` object might be causing trouble here, as the `weeklyReturn` function and similar methods generally work best with univariate series.
Try splitting by ticker before applying the functions, then merging results back. Here’s a simplified process to compute daily, weekly, and monthly returns
```
data_env <- new.env()
tickers <- c('FB', 'MMM')
getSymbols(tickers, env = data_env)
tempPort <- do.call(merge, eapply(data_env, Ad))
na_omitted <- na.omit(tempPort) # Remove incomplete data
# Compute returns per series
returns_list <- lapply(split(na_omitted), function(ts) {
data.frame(
daily = dailyReturn(ts),
weekly = weeklyReturn(ts),
monthly = monthlyReturn(ts)
)
})
hope this helps.
```Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.