使用pandas数据帧计算累积回报

Dav*_*ock 11 python pandas cumsum

我有这个数据帧

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
Run Code Online (Sandbox Code Playgroud)

我正在尝试在perc_ret中运行total_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
Run Code Online (Sandbox Code Playgroud)

Ale*_*der 21

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

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
Run Code Online (Sandbox Code Playgroud)

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


jez*_*ael 6

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

\n\n
np.cumprod(1 + df[\'Daily_rets\'].values) - 1\n
Run Code Online (Sandbox Code Playgroud)\n\n

时间

\n\n
#7k rows\ndf = pd.concat([df] * 1000, ignore_index=True)\n\nIn [191]: %timeit np.cumprod(1 + df[\'Daily_rets\'].values) - 1\n41 \xc2\xb5s \xc2\xb1 282 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 10000 loops each)\n\nIn [192]: %timeit (1 + df.Daily_rets).cumprod() - 1\n554 \xc2\xb5s \xc2\xb1 3.63 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n

  • 这个答案是不正确的。分数回报不能简单地相加,因为明天的回报需要考虑今天的回报。请参阅下面亚历山大的答案以获得正确答案。 (15认同)

Don*_* Yi 5

你不能简单地使用 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())
Run Code Online (Sandbox Code Playgroud)

  • 是的,正确的公式是: np.exp(np.log1p(df['daily_return']).cumsum()) - 1 (3认同)