【问题标题】:Calculating cumulative returns with pandas dataframe使用 pandas 数据框计算累积回报
【发布时间】:2016-05-23 18:38:07
【问题描述】:

我有这个数据框

Poloniex_DOGE_BTC   Poloniex_XMR_BTC    Daily_rets  perc_ret
172 0.006085    -0.000839   0.003309    0
173 0.006229    0.002111    0.005135    0
174 0.000000    -0.001651   0.004203    0
175 0.000000    0.007743    0.005313    0
176 0.000000    -0.001013   -0.003466   0
177 0.000000    -0.000550   0.000772    0
178 0.000000    -0.009864   0.001764    0

我正在尝试计算 perc_ret 中的daily_rets 总数

但是我的代码只是从 daily_rets 复制值

df['perc_ret'] = (  df['Daily_rets'] + df['perc_ret'].shift(1) )


Poloniex_DOGE_BTC   Poloniex_XMR_BTC    Daily_rets  perc_ret
172 0.006085    -0.000839   0.003309    NaN
173 0.006229    0.002111    0.005135    0.005135
174 0.000000    -0.001651   0.004203    0.004203
175 0.000000    0.007743    0.005313    0.005313
176 0.000000    -0.001013   -0.003466   -0.003466
177 0.000000    -0.000550   0.000772    0.000772
178 0.000000    -0.009864   0.001764    0.001764

【问题讨论】:

    标签: python pandas cumsum


    【解决方案1】:

    如果性能很重要,请使用numpy.cumprod

    np.cumprod(1 + df['Daily_rets'].values) - 1
    

    时间安排

    #7k rows
    df = pd.concat([df] * 1000, ignore_index=True)
    
    In [191]: %timeit np.cumprod(1 + df['Daily_rets'].values) - 1
    41 µs ± 282 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
    
    In [192]: %timeit (1 + df.Daily_rets).cumprod() - 1
    554 µs ± 3.63 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    

    【讨论】:

    • 这个答案不正确。分数回报不能简单地加在一起,因为明天的回报需要考虑今天的回报。请参阅下面亚历山大的答案以获得正确答案。
    • @Valdemar - 同意,所以改变了答案。
    • @EndreMoen - 是否可以使用示例数据发布新问题,预期输出?因为我不明白你的意思
    【解决方案2】:

    如果它们是每日简单回报并且您想要累积回报,那么您肯定需要每日复合数吗?

    df['perc_ret'] = (1 + df.Daily_rets).cumprod() - 1  # Or df.Daily_rets.add(1).cumprod().sub(1)
    
    >>> df
         Poloniex_DOGE_BTC  Poloniex_XMR_BTC  Daily_rets  perc_ret
    172           0.006085         -0.000839    0.003309  0.003309
    173           0.006229          0.002111    0.005135  0.008461
    174           0.000000         -0.001651    0.004203  0.012700
    175           0.000000          0.007743    0.005313  0.018080
    176           0.000000         -0.001013   -0.003466  0.014551
    177           0.000000         -0.000550    0.000772  0.015335
    178           0.000000         -0.009864    0.001764  0.017126
    

    如果它们是日志返回,那么您可以使用cumsum

    【讨论】:

      【解决方案3】:

      您不能简单地使用 cumsum 将它们全部添加

      例如,如果你有数组 [1.1, 1.1],你应该有 2.21,而不是 2.2

      import numpy as np
      
      # daily return:
      df['daily_return'] = df['close'].pct_change()
      
      # calculate cumluative return
      df['cumluative_return'] = np.exp(np.log1p(df['daily_return']).cumsum())
      

      【讨论】:

      • np.exp(np.log1p(df['daily_return']).cumsum()) 到底需要 - 1 吗?
      • 是的,正确的公式是:np.exp(np.log1p(df['daily_return']).cumsum()) - 1
      • 或者直接使用 np.expm1 函数。它在数字上更精确
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-02
      • 1970-01-01
      • 2015-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-10
      相关资源
      最近更新 更多