Calculate appropriate cumulative return series or asset level using xts attribute information
Source:R/Level.calculate.R
Level.calculate.RdThis function calculates the time varying index level over the entire period
of available data. It works with arithmetic, log, and difference returns,
natively reading the coredata_content attribute of the xts object to
determine the correct calculation logic.
Details
The function relies on the coredata_content attribute, which is automatically
set by Return.calculate. If this attribute is missing, it gracefully
defaults to "discreteReturn".
If the first value in the left-most column is NA, it will be populated with
the seedValue (which defaults to 1). However, if the first value is
not NA, the previous date will be estimated based on the periodicity of the
time series and populated with the seedValue.
This is designed so that information is not lost if levels are converted back to returns
(where the first value results in an NA). Note: the estimated previous date does
not consider weekdays or holidays; it simply calculates the previous calendar day.
If users run Return.calculate() from this package, this will be a non-issue as it
prepends the NA row automatically.
For arithmetic (discreteReturn) returns:
$$(1+r_{1})(1+r_{2})(1+r_{3})\ldots(1+r_{n})=cumprod(1+R)$$
For logReturn returns:
$$exp(r_{1}+r_{2}+r_{3} + \ldots + r_{n})=exp(cumsum(R))$$
For difference returns:
$$r_{1}+r_{2}+r_{3} + \ldots + r_{n}=cumsum(R)$$#'
Examples
# Using a price series
data(prices)
# Calculate discrete returns
ret <- Return.calculate(as.xts(prices), method = "discrete")
# Recover the price level
# The first row of returns is NA, which will be populated with seedValue (1 by default)
prices_recovered <- Level.calculate(ret, seedValue = 100)
head(prices_recovered)
#> AdjClose
#> 1999-01-04 100.0000
#> 1999-01-05 103.6218
#> 1999-01-06 103.1356
#> 1999-01-07 103.9256
#> 1999-01-08 102.4915
#> 1999-01-11 103.4152
# Compare to Return.cumulative
data(managers)
mgr_eq <- managers[, 1:6] # equities only
xtsAttributes(mgr_eq) <- list(coredata_content = "discreteReturn")
mgr_level <- Level.calculate(mgr_eq)
#> Warning: Estimated start date/time based on periodicity of time series
# Here they are equal
Return.cumulative(mgr_eq)
#> HAM1 HAM2 HAM3 HAM4 HAM5 HAM6
#> Cumulative Return 3.126671 4.348599 3.706732 2.52944 0.2650197 0.9858675
tail(mgr_level - 1, 1)
#> HAM1 HAM2 HAM3 HAM4 HAM5 HAM6
#> 2006-12-31 3.126671 4.348599 3.706732 2.52944 0.2650197 0.9858675