This is what my data.frame looks like. The rightmost column(Performance) is my desired column.
library(data.table)
dt <- fread('
Name FundName SharePrice TotalShares PurchaseDate Performance
John A 10 500 2016-01-01 0%
John A 20 1000 2016-02-01 20%
John A 10 1500 2016-03-01 -25%%
John B 30 500 2016-04-01 -18.18%
John B 60 1000 2016-05-01 4.16%
Tom A 10 500 2016-01-01 0%
Tom A 20 1000 2016-02-01 20%
Tom A 10 1500 2016-03-01 -25%%
Tom B 30 500 2016-04-01 -18.18%
Tom B 60 1000 2016-05-01 4.16%
')
I hope it makes sense. I am struggling with tracking the price of both funds when trying to calculate the cumulative performance. Thank you for your help.
I'd expand the data to cover all Date-Fund combos for each person:
dt_skel = dt[, do.call(CJ, c(.SD, unique=TRUE)),
by=Name, .SDcols=c("FundName", "PurchaseDate")]
dt_full = dt[dt_skel, on=names(dt_skel)]
dt_full[ is.na(TotalShares), TotalShares := 0L]
dt_full[ , SharePrice := SharePrice[1L], by=.(Name, FundName, cumsum(!is.na(SharePrice)))]
Then aggregate
res = dt_full[!is.na(SharePrice), .(
PurchaseDate,
spent = cumsum(TotalShares*SharePrice),
value = cumsum(TotalShares)*SharePrice
), by=.(Name, FundName)][, .(
value = sum(value),
spent = sum(spent)
), by=.(Name, PurchaseDate)]
Name PurchaseDate value spent
1: John 2016-01-01 5000 5000
2: John 2016-02-01 30000 25000
3: John 2016-03-01 30000 40000
4: John 2016-04-01 45000 55000
5: John 2016-05-01 120000 115000
6: Tom 2016-01-01 5000 5000
7: Tom 2016-02-01 30000 25000
8: Tom 2016-03-01 30000 40000
9: Tom 2016-04-01 45000 55000
10: Tom 2016-05-01 120000 115000
To add the performance metric to the original transactions table:
dt[res, ret := value/spent - 1, on=c("Name, PurchaseDate")]
Assuming dates are always monthly, you can make dt_skel
smaller with
dt_skel = dt[, MaxDate := max(PurchaseDate), by=Name][,
seq(from = PurchaseDate[1L], to =MaxDate[1L], by="month"), by=.(Name, FundName)]
Of course, dates should be formatted as Date
or IDate
for this to work.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.