Blotter Question related to addAcctTxn and updateAcct
Alexios, Thanks for the reproducible example. This appears to be a bug, and I've submitted a corresponding bug report to the blotter tracker on R-Forge: https://r-forge.r-project.org/tracker/?func=detail&atid=1269&aid=5983&group_id=316 Best, Josh
On Thu, Nov 6, 2014 at 10:18 AM, alexios ghalanos <alexios at 4dscape.com> wrote:
Hi,
I have a question on the calculations used in updateAcct in relation to the
addAcctTxn function. It would appear to me that the summation of capital
account transactions in updateAcct is wrong, and I provide a reproducible
example below with the code fragment which I believe is related to this.
###############################################################################
# reproducible example:
Sys.setenv(TZ='UTC')
library(blotter)
require(FinancialInstrument)
require(quantmod)
ibm = getSymbols("IBM",auto.assign=FALSE)
index(ibm)<-as.POSIXct(index(ibm))
if(!exists(".instrument")) .instrument <<- new.env()
if(!exists(".blotter")) .blotter <<- new.env()
# Define a currency and a stock
currency("USD")
stock("ibm", currency="USD", multiplier=1)
initPortf('p', symbols="ibm",
currency="USD",initDate=as.POSIXct("2007-01-04"))
initAcct(name="a", portfolios="p", initDate = as.POSIXct("2007-01-04"),
initEq=10000, currency="USD")
# Day 1:
addTxn("p", "ibm", TxnDate=as.POSIXct("2007-01-05"), TxnQty=50,
TxnPrice=97.42, TxnFees = -0.05*50)
# create an account interest charge
addAcctTxn(Account="a", TxnDate=as.POSIXct("2007-01-05"), TxnType =
"Interest", Amount=-10)
# update
updatePortf("p",Dates=as.POSIXct("2007-01-05"))
updateAcct(name="a",Dates=as.POSIXct("2007-01-05"))
updateEndEq(Account="a",Dates=as.POSIXct("2007-01-05"))
getAccount("a")$summary
# 2007-01-05
# Net.Performance = getAccount("a")$summary$Gross.Trading.PL["2007-01-05"] +
getAccount("a")$summary$Txn.Fees["2007-01-05"]+getAccount("a")$summary$Interest["2007-01-05"]
# End.Eq = getAccount("a")$summary$End.Eq["2007-01-04"] +
as.numeric(Net.Performance)
# Equal to 10000-txn.free-interest = 9987.5 (ok)
# Day 2:
# create another interest charge:
addAcctTxn(Account="a", TxnDate=as.POSIXct("2007-01-08"), TxnType =
"Interest", Amount=-10)
updatePortf("p",Dates=as.POSIXct("2007-01-08"))
updateAcct(name="a",Dates=as.POSIXct("2007-01-08"))
updateEndEq(Account="a",Dates=as.POSIXct("2007-01-08"))
getAccount("a")$summary
# Note that the interest is not -10 but -20 (it has been summed over all
previous days)
# 2007-01-08
# Net.Performance = getAccount("a")$summary$Gross.Trading.PL["2007-01-08"] +
getAccount("a")$summary$Txn.Fees["2007-01-08"]+getAccount("a")$summary$Interest["2007-01-08"]
# i.e. 50*(98.90-97.42) - 20
# End.Eq = getAccount("a")$summary$End.Eq["2007-01-05"] +
as.numeric(Net.Performance)
However, interest of -10 was already subtracted from the Ending Equity
already on 2007-01-05.
In the code for updateAcct I notice 3 things (lines 111:139 in the github
repo)
########################################################################
# Code extract
Additions = {
result = if(on=="none")
as.xts(sum(Account$Additions[paste("::",obsDates, sep="")]),
order.by=index(table))
#
# Note 1: The use of '::' means add all transactions upto obsDates...should
it not be just 'paste(obsDates, sep="")'
# since on="none" means that obsLength<=1 (on line 93)
#
else{
if(length(Account$Additions[obsDates])>0) # catch empty sets
period.apply(Account$Additions[obsDates],
endpoints(Account$Additions[obsDates], on=on), sum) # aggregates multiple
account txns
else
xts(rep(0,obsLength),order.by=obsDates)
}
},
Withdrawals = {
result = if(on=="none")
as.xts(sum(Account$Withdrawals[paste("::",obsDates, sep="")]),
order.by=index(table))
else{
if(length(Account$Additions[obsDates])>0) # catch empty sets
#
# Note 2: Should this not be Account$Withdrawals?
#
period.apply(Account$Withdrawals[obsDates],
endpoints(Account$Withdrawals[obsDates], on=periodicity(table)$units), sum)
else
xts(rep(0,obsLength),order.by=obsDates)
}
},
Interest = {
result = if(on=="none")
as.xts(sum(Account$Interest[paste("::",obsDates, sep="")]),,
order.by=index(table))
else{
if(length(Account$Additions[obsDates])>0) # catch empty sets
#
# Note 3: Should this not be Account$Interest?
#
period.apply(Account$Interest[obsDates],
endpoints(Account$Interest[obsDates], on=periodicity(table)$units), sum)
else
xts(rep(0,obsLength),order.by=obsDates)
}
},
###############################################################################
Apologies if I've completely misunderstood the use of some functionality.
Best,
Alexios
sessionInfo()
R version 3.1.1 (2014-07-10) Platform: x86_64-w64-mingw32/x64 (64-bit) locale: LC_COLLATE=English_United Kingdom.1252 LC_CTYPE=English_United Kingdom.1252 LC_MONETARY=English_United Kingdom.1252 LC_NUMERIC=C LC_TIME=English_United Kingdom.1252 attached base packages: stats graphics grDevices utils datasets methods base other attached packages: blotter_0.8.19 devtools_1.5 PerformanceAnalytics_1.1.0 FinancialInstrument_1.1.9 quantmod_0.4-0 TTR_0.22-0 Defaults_1.1-1 xts_0.9-7 zoo_1.7-11 loaded via a namespace (and not attached): digest_0.6.4 evaluate_0.5.5 grid_3.1.1 httr_0.4 lattice_0.20-29 memoise_0.2.1 parallel_3.1.1 RCurl_1.95-4.3 stringr_0.6.2 tools_3.1.1 whisker_0.3-2
_______________________________________________ R-SIG-Finance at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-sig-finance -- Subscriber-posting only. If you want to post, subscribe first. -- Also note that this is not the r-help list where general R questions should go.
Joshua Ulrich | about.me/joshuaulrich FOSS Trading | www.fosstrading.com