【问题标题】:Cumulative Portfolio performance by Name按名称划分的累积投资组合表现
【发布时间】:2016-04-15 20:00:24
【问题描述】:

这就是我的 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%                    
      ')
  • 对于第一行,John 以 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%。

我希望这是有道理的。在尝试计算累积表现时,我正在努力跟踪这两种基金的价格。感谢您的帮助。

【问题讨论】:

    标签: r data.table dplyr zoo


    【解决方案1】:

    我会扩展数据以涵盖每个人的所有 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
    

    将性能指标添加到原始事务表中:

    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)]
    

    当然,日期的格式应为 DateIDate 才能正常工作。

    【讨论】:

    • 非常感谢弗兰克。日期通常到处都是,不一定是每月一次。
    猜你喜欢
    • 2020-09-27
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 2015-09-11
    • 2019-05-04
    • 1970-01-01
    • 2021-03-05
    • 2022-11-18
    相关资源
    最近更新 更多