按名称分类的累计投资组合表现
Cumulative Portfolio performance by Name
这就是我的 data.frame 的样子。最右边的列(性能)是我想要的列。
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%
')
- 对于第一行,约翰以 10 美元的价格购买了 500 股。所以他花了5000美元,那天他可以卖掉他的仓位5000美元。所以第一行的性能是 0%。
- 对于第二行,John 总共花费了 (10*500)+(20*1000)=25000,他可以出售他的头寸换取 (20 * 1500 股) 或 30000 美元。所以他的累计业绩是(30000-25000)/25000,也就是20%。
- 对于第三行,他总共花了(10*500+20*1000+10*1500)=40000 美元,可以卖到(10*3000 股)或 30000 美元,因此业绩为 -25%。
- 现在第4行,有两个基金(A&B);他仍然可以以 30000 的价格出售他的 A 头寸,因为我假设 A 的价格仍然是每股 10 美元,他以 (30*500)=15000 的价格买入了他的新 B 头寸。所以他可以以 (30000+15000)=45000 的价格卖出 A 和 B 的头寸,但到目前为止他花费了 (40000+15000) 或 55000。所以他在第 4 行的累积表现是 (55000-45000)/55000 或 -18.18%。
我希望这是有道理的。在尝试计算累积业绩时,我很难跟踪这两种基金的价格。感谢您的帮助。
我会扩展数据以涵盖每个人的所有 Date-Fund 组合:
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)))]
然后汇总
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
将性能指标添加到原始交易 table:
dt[res, ret := value/spent - 1, on=c("Name, PurchaseDate")]
假设日期总是每月一次,您可以使用
使 dt_skel
更小
dt_skel = dt[, MaxDate := max(PurchaseDate), by=Name][,
seq(from = PurchaseDate[1L], to =MaxDate[1L], by="month"), by=.(Name, FundName)]
当然,日期格式应为 Date
或 IDate
才能正常工作。
这就是我的 data.frame 的样子。最右边的列(性能)是我想要的列。
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%
')
- 对于第一行,约翰以 10 美元的价格购买了 500 股。所以他花了5000美元,那天他可以卖掉他的仓位5000美元。所以第一行的性能是 0%。
- 对于第二行,John 总共花费了 (10*500)+(20*1000)=25000,他可以出售他的头寸换取 (20 * 1500 股) 或 30000 美元。所以他的累计业绩是(30000-25000)/25000,也就是20%。
- 对于第三行,他总共花了(10*500+20*1000+10*1500)=40000 美元,可以卖到(10*3000 股)或 30000 美元,因此业绩为 -25%。
- 现在第4行,有两个基金(A&B);他仍然可以以 30000 的价格出售他的 A 头寸,因为我假设 A 的价格仍然是每股 10 美元,他以 (30*500)=15000 的价格买入了他的新 B 头寸。所以他可以以 (30000+15000)=45000 的价格卖出 A 和 B 的头寸,但到目前为止他花费了 (40000+15000) 或 55000。所以他在第 4 行的累积表现是 (55000-45000)/55000 或 -18.18%。
我希望这是有道理的。在尝试计算累积业绩时,我很难跟踪这两种基金的价格。感谢您的帮助。
我会扩展数据以涵盖每个人的所有 Date-Fund 组合:
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)))]
然后汇总
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
将性能指标添加到原始交易 table:
dt[res, ret := value/spent - 1, on=c("Name, PurchaseDate")]
假设日期总是每月一次,您可以使用
使dt_skel
更小
dt_skel = dt[, MaxDate := max(PurchaseDate), by=Name][,
seq(from = PurchaseDate[1L], to =MaxDate[1L], by="month"), by=.(Name, FundName)]
当然,日期格式应为 Date
或 IDate
才能正常工作。