1#' calculate simple or compound returns from prices
2#'
3#' calculate simple or compound returns from prices
4#'
5#' Two requirements should be made clear.  First, the function
6#' \code{Return.calculate} assumes regular price data.  In this case, we
7#' downloaded monthly close prices.  Prices can be for any time scale, such as
8#' daily, weekly, monthly or annual, as long as the data consists of regular
9#' observations.  Irregular observations require time period scaling to be
10#' comparable.  Fortunately, \code{\link[xts]{to.period}} in the \code{xts}
11#' package, or the \code{\link[zoo]{aggregate.zoo}} in the \code{zoo} package
12#' supports supports management and conversion of irregular time series.
13#'
14#' Second, if corporate actions, dividends, or other adjustments such as time-
15#' or money-weighting are to be taken into account, those calculations must be
16#' made separately. This is a simple function that assumes fully adjusted close
17#' prices as input.  For the IBM timeseries in the example below, dividends and
18#' corporate actions are not contained in the "close" price series, so we end
19#' up with "price returns" instead of "total returns".  This can lead to
20#' significant underestimation of the return series over longer time periods.
21#' To use adjusted returns, specify \code{quote="AdjClose"} in
22#' \code{\link[tseries]{get.hist.quote}}, which is found in package
23#' \code{tseries}.
24#'
25#' We have changes the default arguments and settings for \code{method}
26#' from \code{compound} and \code{simple} to \code{discrete} and
27#' \code{log} and \code{discrete} to avoid confusing between the return type
28#' and the chaining method.  In most of the rest of \code{PerformanceAnalytics},
29#' compound and simple are used to refer to the \emph{return chaining} method used for the returns.
30#' The default for this function is to use discrete returns, because most other package
31#' functions use compound chaining by default.
32#'
33#' @aliases CalculateReturns Return.calculate
34#' @param prices data object containing ordered price observations
35#' @param method calculate "discrete" or "log" returns, default discrete(simple)
36#' @author Peter Carl
37#' @seealso \code{\link{Return.cumulative}}
38#' @references Bacon, C. \emph{Practical Portfolio Performance Measurement and
39#' Attribution}. Wiley. 2004. Chapter 2 \cr
40###keywords ts multivariate distribution models
41#' @examples
42#'
43#'   \dontrun{
44#'     require(quantmod)
45#'     prices = getSymbols("IBM", from = "1999-01-01", to = "2007-01-01")
46#'   }
47#'   \dontshow{
48#'     data(prices)
49#'   }
50#' R.IBM = Return.calculate(xts(prices), method="discrete")
51#' colnames(R.IBM)="IBM"
52#' chart.CumReturns(R.IBM,legend.loc="topleft", main="Cumulative Daily Returns for IBM")
53#' round(R.IBM,2)
54#' @export
55Return.calculate <-
56function(prices, method = c("discrete","log","difference"))
57{ # @ author Peter Carl
58
59    #  Calculate returns from a price stream
60
61    # Required inputs
62
63    # Prices: data object containing ordered price observations
64    # method: "simple", "compound"
65
66    # FUNCTION:
67
68    method = method[1]
69    pr = checkData(prices, method = "xts")
70
71    if(method=="simple" || method=='discrete' || method=="arithmetic"){
72        #Returns = pr/pr[-nrow(pr), ] - 1
73        Returns = pr/lag.xts(pr) - 1
74        xtsAttributes(Returns) <- list(ret_type="discrete")
75        #EB: I think this should be more abstract, to cover "level" (e.g. Price), "difference", "residuals", etc.
76        xtsAttributes(Returns) <- list(coredata_content = "discreteReturn")
77
78    }
79    if(method=="compound" || method=='log' || method == "continuous") {
80        Returns = diff(log(pr))
81        xtsAttributes(Returns) <- list(ret_type="log")
82        xtsAttributes(Returns) <- list(coredata_content = "logReturn")
83    }
84    if(method=="diff" || method=='difference') {
85      Returns = diff(pr)
86      # xtsAttributes(Returns) <- list(ret_type="diff")
87      xtsAttributes(Returns) <- list(coredata_content = "difference")
88    }
89
90    #maybe set to pr in the body instead of Returns
91    xtsAttributes(pr)$coredata_content <- xtsAttributes(Returns)$coredata_content
92    reclass(Returns,match.to=pr)
93}
94
95#' @rdname Return.calculate
96#' @export
97CalculateReturns <-
98function(prices, method = c("discrete","log"))
99{ # @ author Peter Carl
100    Return.calculate(prices=prices, method=method)
101}
102###############################################################################
103# R (http://r-project.org/) Econometrics for Performance and Risk Analysis
104#
105# Copyright (c) 2004-2020 Peter Carl and Brian G. Peterson
106#
107# This R package is distributed under the terms of the GNU Public License (GPL)
108# for full details see the file COPYING
109#
110# $Id$
111#
112###############################################################################
113