You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何更高效优雅地计算含现金流的投资账户余额?

带现金流的投资账户滚动余额高效计算方法

我有一个投资账户的收益序列,账户有初始资金,期间可能存在存入和取出操作,需要生成账户的滚动余额。当无中间现金流时,使用cumprod可以轻松实现,但存在中间现金流时只能使用for()循环,感觉这种方法速度较慢,是否有更高效的实现方式?

set.seed(100)
return <- c(0,rnorm(5,.05,.02))
cash_flow <- c(100,0,0,-5,0,0)

account <- data.frame(cash_flow,return)
# 无中间现金流时的简单实现(忽略现金流列)
balance <- account$cash_flow[1] * cumprod(1+account$return)
cbind(account,balance)
#>   cash_flow     return  balance
#> 1       100 0.00000000 100.0000
#> 2         0 0.03995615 103.9956
#> 3         0 0.05263062 109.4690
#> 4        -5 0.04842166 114.7696
#> 5         0 0.06773570 122.5436
#> 6         0 0.05233943 128.9575

# 持有期间有取现操作时的循环实现
balance[1] <- account$cash_flow[1]
for (n in 2:6){
   balance[n] <- (balance[n-1] * (1+account$return[n]) + account$cash_flow[n])
}

cbind(account,balance)
#>   cash_flow     return  balance
#> 1       100 0.00000000 100.0000
#> 2         0 0.03995615 103.9956
#> 3         0 0.05263062 109.4690
#> 4        -5 0.04842166 109.7696
#> 5         0 0.06773570 117.2050
#> 6         0 0.05233943 123.3394

不同实现方案的速度对比

测试了三种实现方式:原生R循环、Reduce()函数、C语言扩展,结果显示C语言实现比原生R循环快34%,Reduce()方法反而更慢。

实现代码:

CB_R <- function(returns,cash_flow,num_rows){
   balance <- cash_flow[1]
   for (n in 2:num_rows){
      balance[n] <- (balance[n-1] * (1+returns[n]) + cash_flow[n])
   }
   return(balance)
}

CB_R2 <- function(returns,cash_flow,num_rows){
   return(
    Reduce(
   f = \(x, i) x * (1 + returns[i]) + cash_flow[i], 
   x = 2:num_rows, 
   init = cash_flow[1],
   acc = TRUE)
   )
}

cppFunction('
NumericVector  CB_C(NumericVector Returns, NumericVector cashFlow,
                              int num_rows) {
  NumericVector balance(num_rows);
  balance[0] = cashFlow[0];
  
  for(int i = 1; i < num_rows; i++){
     balance[i] = (balance[i-1] * (1+Returns[i]) + cashFlow[i]);
  } 
  return balance;  
}')

bench::mark(
   CB_R(account$return,account$cash_flow,nrow(account)),
   CB_R2(account$return,account$cash_flow,nrow(account)),
   CB_C(account$return,account$cash_flow,nrow(account))
)
#> # A tibble: 3 × 6
#>   expression                             min median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr>                          <bch:> <bch:>     <dbl> <bch:byt>    <dbl>
#> 1 CB_R(account$return, account$cash_…  5.8µs  6.4µs   144957.   85.87KB     29.0
#> 2 CB_R2(account$return, account$cash… 13.1µs 14.7µs    64339.        0B     25.7
#> 3 CB_C(account$return, account$cash_…  3.7µs  4.2µs   196991.    2.49KB     39.4

内容的提问来源于stack exchange,提问作者Art

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 16:24:54