根据权重和returnDataFrame计算浮动权重

Calculation of floating weights based on weight and return DataFrame

我有两个DataFramesreturnsweights 我尝试将它们组合成 floating_weights DataFrame。这背后的想法是,我想动态调整t期间的权重和t-1期间的return。因此,如果 return 为正,则权重会增加,反之亦然。

这里我创建了一个简单的例子:

weights:
    Dates       01K W   02K W   03K W   04K W
0   2021-01-01  0.0     0.2     0.3     0.5
1   2021-01-02  0.0     0.2     0.3     0.5
2   2021-01-03  0.5     0.2     0.3     0.0
3   2021-01-04  0.5     0.2     0.3     0.0
4   2021-01-05  0.5     0.0     0.2     0.3
5   2021-01-06  0.5     0.0     0.2     0.3


returns:
Dates           01K W   02K W   03K W   04K W
0   2021-01-01  0.01    0.01    -0.03   0.05
1   2021-01-02  -0.02   0.02    0.04    -0.02
2   2021-01-03  0.03    -0.03   0.01    -0.02
3   2021-01-04  -0.03   0.01    0.02    0.01
4   2021-01-05  0.02    0.02    0.01    0.01
5   2021-01-06  0.01    -0.01   0.03    0.02

floating_weightsDataFrame是在上一期return调整正常权重的基础上:

floating_weights (2021-01-01, 02K W): 0.2 (从正常重量开始)

floating_weights (2021-01-02, 02K W): 0.202 = 0.2 * (1+0.01)

floating_weights (2021-01-03, 02K W): 0.206 = 0.2 * (1+0.01) * (1+0.02)

floating_weights (2021-01-04, 02K W): 0.19986 = 0.2 * (1+0.01) * (1+0.02) * (1-0.03)

floating_weights 看起来像这样。

    Dates       01K W   02K W   03K W   04K W
0   2021-01-01  0.0000  0.20000 0.30000 0.500
1   2021-01-02  0.0000  0.20200 0.29100 0.525
2   2021-01-03  0.5000  0.20604 0.30264 0.000
3   2021-01-04  0.5150  0.19986 0.30567 0.000
4   2021-01-05  0.4995  0.00000 0.20785 0.300
5   2021-01-06  0.5095  0.00000 0.20993 0.303

为了可重复性:

import pandas as pd
returns = pd.DataFrame({
    'Dates':['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', '2021-01-05', '2021-01-06'],
    '01K W':[0.01, -0.2, 0.03, -0.03, 0.02, 0.01], 
    '02K W':[0.01, 0.02, -0.03, 0.01, 0.02, -0.01], 
    '03K W':[-0.03, 0.04, 0.01, 0.02, 0.01, 0.03], 
    '04K W':[0.05, -0.02, -0.02, 0.01, 0.01, 0.02]}) 
returns = returns.set_index('Dates')

weights = pd.DataFrame({
    'Dates':['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', '2021-01-05', '2021-01-06'],
    '01K W':[0, 0, 0.5, 0.5, 0.5, 0.5], 
    '02K W':[0.2, 0.2, 0.2, 0.2, 0, 0], 
    '03K W':[0.3, 0.3, 0.3, 0.3, 0.2, 0.2], 
    '04K W':[0.5, 0.5, 0, 0, 0.3, 0.3]}) 
weights = weights.set_index('Dates')

非常感谢您的帮助!

我们可以使用 cumprod to calculate the cumulative returns, then shift and multiply 累积 returns 和 weights 数据框来获得所需的结果

r = returns.add(1).cumprod().shift()
floating_weights = weights.mul(r, fill_value=1)

如果你想在每次权重被分配为零时重置cumprod,在这种情况下我们必须单独考虑每一列

floating_weights = weights.copy()

for col in weights:
    g = weights[col].eq(0).cumsum()
    r = returns[col].add(1).groupby(g).cumprod()
    floating_weights[col] = weights[col].mul(r.shift(1), fill_value=1)

>>> floating_weights

               01K W     02K W     03K W  04K W
Dates                                          
2021-01-01  0.000000  0.200000  0.300000  0.500
2021-01-02  0.000000  0.202000  0.291000  0.525
2021-01-03  0.500000  0.206040  0.302640  0.000
2021-01-04  0.515000  0.199859  0.305666  0.000
2021-01-05  0.499550  0.000000  0.207853  0.300
2021-01-06  0.509541  0.000000  0.209932  0.303