【问题标题】:How to calculate the cumulative product of a rolling window in Pandas?如何计算 Pandas 中滚动窗口的累积乘积?
【发布时间】:2019-07-01 00:48:18
【问题描述】:

我有一个 DataFrame,df,其中包含每日股票收益:

Date         Stock A    Stock B     Stock C
2018-12-26  -0.018207   0.083554   -0.006546
2018-12-27   0.004223   0.000698    0.003806
2018-12-28   0.024847  -0.008717    0.028399
2018-12-31   0.000000   0.010904    0.000000
2019-01-02   0.036554   0.002436    0.035557
2019-01-03   0.043541  -0.028462    0.006065
2019-01-04  -0.036207   0.070025    0.003025
2019-01-07  -0.005367   0.046411   -0.001546
2019-01-08   0.002878   0.014678    0.003631
2019-01-09   0.004663   0.014151    0.017179
2019-01-10   0.009282   0.026047    0.002062
2019-01-11   0.021224  -0.006649   -0.001578
2019-01-14   0.022168  -0.015211    0.008713
2019-01-15  -0.009827   0.020080   -0.004424
2019-01-16   0.021561  -0.016657    0.003583
2019-01-17   0.005025   0.011703    0.010149
2019-01-18   0.013333   0.012785    0.007824
2019-01-21   0.003289   0.000000   -0.000905
2019-01-22  -0.023934  -0.030658   -0.009447
2019-01-23   0.031911  -0.039690    0.015299
2019-01-24   0.030273   0.020665    0.011589
2019-01-25   0.000000   0.040810    0.000000
2019-01-28   0.018325   0.006991   -0.022861
2019-01-29  -0.021098  -0.044974    0.002043
2019-01-30  -0.002536   0.019595    0.014189
2019-01-31   0.000000   0.040298    0.004103
2019-02-01   0.014935  -0.011025    0.004795
2019-02-04   0.010332   0.022597    0.007439
2019-02-05   0.022002   0.012669   -0.002820
2019-02-06  -0.023651  -0.006110   -0.037381

如何计算每只股票在滚动窗口中的累积回报?

例如,如果滚动窗口为 5 天:

  • Stock A 的累积回报系列中的第一个元素应该是 (1 + df.loc["2018-12-26":"2019-01-02", "Stock A"]).cumprod() - 1,计算结果为 (1 + -0.018207)*(1 + 0.004223)*(1 + 0.024847)*(1 + 0.000000)*(1 + 0.036554) - 10.047372
  • 第二个元素应该是(1 + df.loc["2018-12-27":"2019-01-03", "Stock A"]).cumprod() - 1,计算结果为(1 + 0.004223)*(1 + 0.024847)*(1 + 0.000000)*(1 + 0.036554)*(1 + 0.043541) - 10.113245
  • 等等……

Date 索引中的间隔(例如周末)无关紧要,滚动窗口应该只考虑索引中包含的日期。

【问题讨论】:

  • 你如何定义“累积回报”?你想如何处理这些差距? (可能是周末造成的。)它们是否包含在窗口大小中?
  • 感谢@DYZ,我添加了一个示例来说明我想要完成的工作。

标签: python pandas quantitative-finance


【解决方案1】:

由于某种原因 pandas rolling 对象没有 prod 方法,但您可以将 NumPy prod 应用于它们。此外,您需要将1 添加到您的DataFrame,然后再减去它,因此最直接的单行方法是

import numpy as np
...
cumulative_returns_df = (df+1).rolling(5).apply(np.prod)-1

可以说,对数变换、计算滚动和然后反转变换的计算效率更高,数值更稳定:

cumulative_returns_df = np.exp(np.log(df+1).rolling(5).sum())-1

【讨论】:

  • 如何对小于 -1 的返回应用日志转换?
  • 股价回报率不能小于-1:回报率-1表示价格正好为0,回报率低于-1则为负数。通常,您不能记录转换负数,而确保所有值都是正数的常用技术是向它们添加一个常数。
  • 有没有办法使用cumprod() 并将窗口中的最后一个元素除以窗口中的第一个元素?这对我来说比 exp/log 方法更容易理解
【解决方案2】:

您的问题没有明确定义,但假设参考日期是第一行索引2019-01-30,您可以使用df.pct_change(30)

【讨论】:

  • 谢谢,如果 DataFrame 包含股票价格,这将起作用。但是,我的 DataFrame df 包含股票收益。在 this 的情况下我该怎么做?
猜你喜欢
  • 2013-02-24
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 2020-08-07
  • 2018-12-29
  • 2019-08-10
  • 2021-11-08
  • 2021-10-12
相关资源
最近更新 更多