Return.portfolio(R, weights = NULL, wealth.index = FALSE, contribution = FALSE, geometric = TRUE, rebalance_on = c(NA, "years", "quarters", "months", "weeks", "days"), value = 1, verbose = FALSE, ...)
endpoints
.weights
parameter, or a list that includes intermediate calculations
When asset return and weights are matched by period, contribution is simply the weighted return of the asset. c_i = w_i * R_i Contributions are summable across the portfolio to calculate the total portfolio return.
Contribution cannot be aggregated through time. For example, say we have an equal weighted portfolio of five assets with monthly returns. The geometric return of the portfolio over several months won't match any aggregation of the individual contributions of the assets, particularly if any rebalancing was done during the period.
To aggregate contributions through time such that they are summable to the geometric returns of the portfolio, the calculation must track changes in the notional value of the assets and portfolio. For example, contribution during a quarter will be calculated as the change in value of the position through those three months, divided by the original value of the portfolio. Approaching it this way makes the calculation robust to weight changes as well. c_pi = V_(t-p)i - V_t)/V_ti
If the user does not specify weights, an equal weight portfolio is assumed. Alternatively, a vector or single-row matrix of weights that matches the length of the asset columns may be specified. In either case, if no rebalancing period is specified, the weights will be applied at the beginning of the asset time series and no further rebalancing will take place. If a rebalancing period is specified, the portfolio will be rebalanced to the starting weights at the interval specified.
Return.portfolio
will work only on daily or lower frequencies. If you are
rebalancing intraday, you should be using a trades/prices framework like
the blotter
package, not a weights/returns framework.
Irregular rebalancing can be done by specifying a time series of weights. The function uses the date index of the weights for xts-style subsetting of rebalancing periods.
Weights specified for rebalancing should be thought of as "end-of-period" weights. Rebalancing periods can be thought of as taking effect immediately after the close of the bar. So, a March 31 rebalancing date will actually be in effect for April 1. A December 31 rebalancing date will be in effect on Jan 1, and so forth. This convention was chosen because it fits with common usage, and because it simplifies xts Date subsetting via endpoints.
In verbose mode, the function returns a list of data and intermediary calculations.
returns
: The portfolio returns.
contribution
: The per period contribution to portfolio
return of each asset. Contribution is calculated as BOP weight times the
period's return divided by BOP value. Period contributions are summed
across the individual assets to calculate portfolio return
BOP.Weight
: Beginning of Period (BOP) Weight for each
asset. An asset's BOP weight is calculated using the input weights
(or assumed weights, see below) and rebalancing parameters given. The next
period's BOP weight is either the EOP weights from the prior period or
input weights given on a rebalance period.
EOP.Weight:
End of Period (BOP) Weight for each asset.
An asset's EOP weight is the sum of the asset's BOP weight and
contribution for the period divided by the sum of the contributions and
initial weights for the portfolio.
BOP.Value:
BOP Value for each asset. The BOP value for each
asset is the asset's EOP value from the prior period, unless there is a
rebalance event. If there is a rebalance event, the BOP value of the
asset is the rebalance weight times the EOP value of the portfolio. That
effectively provides a zero-transaction cost change to the position values
as of that date to reflect the rebalance. Note that the sum of the BOP
values of the assets is the same as the prior period's EOP portfolio value.
EOP.Value:
EOP Value for each asset. The EOP value is for
each asset is calculated as (1 + asset return) times the asset's BOP value.
The EOP portfolio value is the sum of EOP value across assets.
To calculate BOP and EOP position value, we create an index for each position. The
sum of that value across assets represents an indexed value of the total portfolio.
Note that BOP and EOP position values are only computed when geometric = TRUE
.
From the value calculations, we can calculate different aggregations through time for the asset contributions. Those are calculated as the EOP asset value less the BOP asset value; that quantity is divided by the BOP portfolio value. Across assets, those will sum to equal the geometric chained returns of the portfolio for that same time period. The function does not do this directly, however.
Return.calculate
endpoints
data(edhec)
Return.portfolio(edhec["1997",1:5], rebalance_on="quarters") # returns time series
Return.portfolio(edhec["1997",1:5], rebalance_on="quarters", verbose=TRUE) # returns list
# with a weights object
data(weights) # rebalance at the beginning of the year to various weights through time
chart.StackedBar(weights)
x <- Return.portfolio(edhec["2000::",1:11], weights=weights,verbose=TRUE)
chart.CumReturns(x$returns)
chart.StackedBar(x$BOP.Weight)
chart.StackedBar(x$BOP.Value)
Run the code above in your browser using DataLab