[Blotter-commits] r1500 - in pkg/blotter: . R man

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Mon Sep 9 21:29:52 CEST 2013


Author: braverock
Date: 2013-09-09 21:29:52 +0200 (Mon, 09 Sep 2013)
New Revision: 1500

Added:
   pkg/blotter/R/AcctReturns.R
   pkg/blotter/man/AcctReturns.Rd
Modified:
   pkg/blotter/DESCRIPTION
Log:
- add AcctReturns function by Andrii Babii (moved  from PortfolioAttribution)


Modified: pkg/blotter/DESCRIPTION
===================================================================
--- pkg/blotter/DESCRIPTION	2013-08-26 09:01:15 UTC (rev 1499)
+++ pkg/blotter/DESCRIPTION	2013-09-09 19:29:52 UTC (rev 1500)
@@ -26,42 +26,5 @@
 Contributors: Dirk Eddelbuettel, Jan Humme, Lance Levenson,
     Ben McCann, Jeff Ryan, Garrett See, Joshua Ulrich, Wolfgang Wu
 URL: https://r-forge.r-project.org/projects/blotter/
-Copyright: (c) 2008-2012
+Copyright: (c) 2008-2013
 ByteCompile: TRUE
-Collate:
-    'PortfReturns.R'
-    'addPortfInstr.R'
-    'addTxn.R'
-    'addAcctTxn.R'
-    'calcPortfWgt.R'
-    'calcPosAvgCost.R'
-    'calcTxnAvgCost.R'
-    'calcTxnValue.R'
-    'chart.ME.R'
-    'chart.Posn.R'
-    'chart.Reconcile.R'
-    'chart.Spread.R'
-    'extractTests.R'
-    'getAccount.R'
-    'getByPortf.R'
-    'getBySymbol.R'
-    'getEndEq.R'
-    'getPortfAcct.R'
-    'getPortfolio.R'
-    'getPos.R'
-    'getPosAvgCost.R'
-    'getPosQty.R'
-    'getTxn.R'
-    'initAcct.R'
-    'initPortf.R'
-    'initPosPL.R'
-    'initSummary.R'
-    'initTxn.R'
-    'perTradeStats.R'
-    'put.portfolio.R'
-    'tradeStats.R'
-    'updateAcct.R'
-    'updateEndEq.R'
-    'updatePortf.R'
-    'updatePosPL.R'
-    'put.account.R'

Added: pkg/blotter/R/AcctReturns.R
===================================================================
--- pkg/blotter/R/AcctReturns.R	                        (rev 0)
+++ pkg/blotter/R/AcctReturns.R	2013-09-09 19:29:52 UTC (rev 1500)
@@ -0,0 +1,129 @@
+#' Calculate account returns
+#' 
+#' Similar to the \code{PortfReturns} function, but gives returns for the 
+#' entire account and takes into account external cashflows. External cashflows
+#' are defined as contributions to or withdrawals from the account. Allows 
+#' selecting between time-weighted returns and linked modified Dietz approach. 
+#' If time-weighted method is selected, returns at time \eqn{t} are computed 
+#' using: \deqn{r_{t}=\frac{V_{t}}{V_{t-1}+C_{t}}-1}
+#' where \eqn{V_{t}} - account value at time \eqn{t}, \eqn{C_{t}} - cashflow at
+#' time \eqn{t}. The implicit assumption made here is that the cash flow is 
+#' available for the portfolio manager to invest from the beginning of the day. 
+#' These returns then can be chain linked with geometric compounding (for 
+#' instance using \code{Return.cumulative} function from the 
+#' \code{PerformanceAnalytics} package) to yield cumulative multi-period 
+#' returns:
+#' \deqn{1+r=\prod_{t=1}^{T}(1+r_{t})=\prod_{t=1}^{T}\frac{V_{t}}{V_{t-1}+C_{t}}}
+#' In the case if there were no cashflows, the result reduces to simple 
+#' one-period returns. Time-weighted returns has also an interpretation in
+#' terms of unit value pricing.
+#' If Modified Dietz method is selected, monthly returns are computed taking
+#' into account cashflows within each month:
+#' \deqn{r = \frac{V_{t}-V_{t-1}-C}{V_{t-1}+\sum_{t}C_{t}\times W_{t}}}
+#' where \eqn{C} - total external cash flows within a month, 
+#' \eqn{C_{t}} - external cashflow at time \eqn{t}, 
+#' \deqn{W_{t}=\frac{TD-D_{t}}{TD}} - weighting ratio to be applied to external 
+#' cashflow on day \eqn{t},
+#' \eqn{TD} - total number of days within the month,
+#' \eqn{D_{t}} - number of days since the beginning of the month including 
+#' weekends and public holidays.
+#' Finally monthly Modified Dietz returns can also be linked geometrically.
+#' 
+#' @aliases AcctReturns
+#' @param Account string name of the account to generate returns for
+#' @param \dots any other passthru parameters (like \code{native} for 
+#' \code{.getBySymbol}
+#' @param Dates xts style ISO 8601 date subset to retrieve, default NULL 
+#' (all dates)
+#' @param Portfolios concatenated string vector for portfolio names to retrieve
+#' returns on, default NULL (all portfolios)
+#' @param method Used to select between time-weighted and linked modified Dietz
+#' returns. May be any of: \itemize{\item timeweighted \item dietz} By default
+#' time-weighted is selected
+#' @return returns xts with account returns
+#' @author Brian Peterson, Andrii Babii
+#' @seealso PortfReturns
+#' @references Christopherson, Jon A., Carino, David R., Ferson, Wayne E. 
+#' \emph{Portfolio Performance Measurement and Benchmarking}. McGraw-Hill. 
+#' 2009. Chapter 5 \cr Bacon, C. \emph{Practical Portfolio Performance 
+#' Measurement and Attribution}. Wiley. 2004. Chapter 2 \cr
+#' @keywords portfolio returns
+#' @note
+#' TODO handle portfolio and account in different currencies (not hard, just not done)
+#' 
+#' TODO explicitly handle portfolio weights
+#' 
+#' TODO support additions and withdrawals to available capital
+#' @export
+AcctReturns <- 
+function(Account, Dates = NULL, Portfolios = NULL, method = c("timeweighted", "dietz"), ...)
+{ # @author Brian Peterson, Andrii Babii
+	aname <- Account
+	if(!grepl("account\\.", aname)){
+	  Account <- try(get(paste("account", aname, sep = '.'), envir = .blotter))
+	}  else{
+    Account <- try(get(aname, envir = .blotter))
+	}
+	if(inherits(Account, "try-error")){
+	  stop(paste("Account ", aname, " not found, use initAcct() to create a new 
+               account"))
+	}
+	if(!inherits(Account, "account")){
+    stop("Account ", aname, " passed is not the name of an account object.")
+	}
+	if(is.null(Portfolios)){
+	  Portfolios = names(Account$portfolios)
+	}
+  
+	# Get xts with net trading P&L for all portfolios associated with account
+	table = NULL
+	for(pname in Portfolios){
+		Portfolio <- getPortfolio(pname)
+		if(is.null(Dates)){
+		  Dates <- paste("::", last(index(Portfolio$summary)), sep = '')
+		}
+		ptable = .getBySymbol(Portfolio = Portfolio, Attribute = "Net.Trading.PL", 
+                          Dates = Dates)
+		if(is.null(table)){
+		  table=ptable
+		}
+		else{
+		  table=cbind(table,ptable)
+		}
+	}
+  if(!is.null(attr(Account, 'initEq'))){
+	  initEq <- as.numeric(attr(Account, 'initEq'))
+		if(initEq == 0){
+      stop("Initial equity of zero would produce div by zero NaN, Inf, -Inf 
+             returns, please fix in initAcct().")
+		}
+    
+	  #TODO check portfolio and account currencies and convert if necessary
+    
+    CF = Account$summary$Additions - Account$summary$Withdrawals # Cashflows
+    V = initEq + reclass(rowSums(table), table)                  # Account values
+    method = method[1]
+    
+    if (method == "timeweighted"){
+      # Time-weighted returns
+      returns = V  / (lag(V) + CF) - 1
+    }
+    
+    if (method == "dietz"){
+      # Linked modified Dietz
+      C = apply.monthly(CF, sum)   # total monthly cashflow
+      V = apply.monthly(V, first)  # monthly account values
+      cfweighted <- function(CF){
+        TD = ndays(CF)             # total number of days within the period
+        # number of days since the beginning of the period
+        D = round(as.vector((index(CF) - index(CF)[1])/3600/24)) 
+        W = (TD - D) / TD          # weights
+        cashfl = sum(CF * W)       # weighted sum of cashflows within the period
+        return(cashfl)
+      }
+      cashfl = apply.monthly(CF, cfweighted)
+      returns = (V - lag(V) - C) / (lag(V) + cashfl) # Modified Dietz
+    }
+	}
+	return(returns)
+}

Added: pkg/blotter/man/AcctReturns.Rd
===================================================================
--- pkg/blotter/man/AcctReturns.Rd	                        (rev 0)
+++ pkg/blotter/man/AcctReturns.Rd	2013-09-09 19:29:52 UTC (rev 1500)
@@ -0,0 +1,88 @@
+\name{AcctReturns}
+\alias{AcctReturns}
+\title{Calculate account returns}
+\usage{
+  AcctReturns(Account, Dates = NULL, Portfolios = NULL,
+    method = c("timeweighted", "dietz"), ...)
+}
+\arguments{
+  \item{Account}{string name of the account to generate
+  returns for}
+
+  \item{\dots}{any other passthru parameters (like
+  \code{native} for \code{.getBySymbol}}
+
+  \item{Dates}{xts style ISO 8601 date subset to retrieve,
+  default NULL (all dates)}
+
+  \item{Portfolios}{concatenated string vector for
+  portfolio names to retrieve returns on, default NULL (all
+  portfolios)}
+
+  \item{method}{Used to select between time-weighted and
+  linked modified Dietz returns. May be any of:
+  \itemize{\item timeweighted \item dietz} By default
+  time-weighted is selected}
+}
+\value{
+  returns xts with account returns
+}
+\description{
+  Similar to the \code{PortfReturns} function, but gives
+  returns for the entire account and takes into account
+  external cashflows. External cashflows are defined as
+  contributions to or withdrawals from the account. Allows
+  selecting between time-weighted returns and linked
+  modified Dietz approach. If time-weighted method is
+  selected, returns at time \eqn{t} are computed using:
+  \deqn{r_{t}=\frac{V_{t}}{V_{t-1}+C_{t}}-1} where
+  \eqn{V_{t}} - account value at time \eqn{t}, \eqn{C_{t}}
+  - cashflow at time \eqn{t}. The implicit assumption made
+  here is that the cash flow is available for the portfolio
+  manager to invest from the beginning of the day. These
+  returns then can be chain linked with geometric
+  compounding (for instance using \code{Return.cumulative}
+  function from the \code{PerformanceAnalytics} package) to
+  yield cumulative multi-period returns:
+  \deqn{1+r=\prod_{t=1}^{T}(1+r_{t})=\prod_{t=1}^{T}\frac{V_{t}}{V_{t-1}+C_{t}}}
+  In the case if there were no cashflows, the result
+  reduces to simple one-period returns. Time-weighted
+  returns has also an interpretation in terms of unit value
+  pricing. If Modified Dietz method is selected, monthly
+  returns are computed taking into account cashflows within
+  each month: \deqn{r =
+  \frac{V_{t}-V_{t-1}-C}{V_{t-1}+\sum_{t}C_{t}\times
+  W_{t}}} where \eqn{C} - total external cash flows within
+  a month, \eqn{C_{t}} - external cashflow at time \eqn{t},
+  \deqn{W_{t}=\frac{TD-D_{t}}{TD}} - weighting ratio to be
+  applied to external cashflow on day \eqn{t}, \eqn{TD} -
+  total number of days within the month, \eqn{D_{t}} -
+  number of days since the beginning of the month including
+  weekends and public holidays. Finally monthly Modified
+  Dietz returns can also be linked geometrically.
+}
+\note{
+  TODO handle portfolio and account in different currencies
+  (not hard, just not done)
+
+  TODO explicitly handle portfolio weights
+
+  TODO support additions and withdrawals to available
+  capital
+}
+\author{
+  Brian Peterson, Andrii Babii
+}
+\references{
+  Christopherson, Jon A., Carino, David R., Ferson, Wayne
+  E. \emph{Portfolio Performance Measurement and
+  Benchmarking}. McGraw-Hill. 2009. Chapter 5 \cr Bacon, C.
+  \emph{Practical Portfolio Performance Measurement and
+  Attribution}. Wiley. 2004. Chapter 2 \cr
+}
+\seealso{
+  PortfReturns
+}
+\keyword{portfolio}
+\keyword{returns}
+



More information about the Blotter-commits mailing list