Home > Mobile >  Calculation of rolling weights with initial weight at the first day
Calculation of rolling weights with initial weight at the first day

Time:12-16

I have a DataFrame for weights and returns and I want to adjust the weights based on the returns one day before, except for the initial weights. The basic idea is that the weights are changing based on the returns.

I created an example with the weights, returns and the preferred rolling weights:

weights:
            01K W   02K W   03K W   04K W
Dates               
2021-01-01  0.0     0.2     0.3     0.5
2021-01-02  0.0     0.2     0.3     0.5
2021-01-03  0.5     0.2     0.3     0.0
2021-01-04  0.5     0.2     0.3     0.0
2021-01-05  0.5     0.0     0.2     0.3
2021-01-06  0.5     0.0     0.2     0.3

returns:
            01K W   02K W   03K W   04K W
Dates               
2021-01-01  0.01    0.01    -0.03   0.05
2021-01-02  0.02    0.02    0.04    -0.02
2021-01-03  0.03    -0.03   0.01    -0.02
2021-01-04  -0.03   0.01    0.02    0.03
2021-01-05  0.02    0.02    0.01    0.01
2021-01-06  0.01    -0.01   0.03    0.02

With these weights and returns, I try to calculate the rolling weights for 01K W as follows:

  • 2021-01-03: 0.5 (initial weight) (ignore return on previous day)
  • 2021-01-04: 0.515 = 0.5 * (1 0.03) (0.03=return on 2021-01-03)
  • 2021-01-05: 0.4996 = 0.5 * (1 0.03) * (1-0.03)(-0.03=return on 2021-01-04)
  • 2021-01-06: 0.5095 = 0.5 * (1 0.03) * (1-0.03) * (1 0.02)(0.02=return on 2021-01-05)
rolling_weights:
            01K W   02K W   03K W   04K W
Dates               
2021-01-01  0.0000  0.20000 0.30000 0.500
2021-01-02  0.0000  0.20200 0.29100 0.525
2021-01-03  0.5000  0.20604 0.30264 0.000
2021-01-04  0.5150  0.19986 0.30567 0.000
2021-01-05  0.4996  0.00000 0.20785 0.300
2021-01-06  0.5095  0.00000 0.20993 0.303

For reproducibility:

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.02, 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.03, 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')

Thank you very much for your suggestions.

CodePudding user response:

Multiply weights by partial (i.e. resets every time weights are zero) cumprod of returns that are zeroed at positions where weights are zero, and then shifted 1 position down:

weights_new = pd.DataFrame([weights[col]*(returns.where(weights!=0,0).shift(1).fillna(0) 1)[col].groupby(((returns.where(weights!=0,0).shift(1).fillna(0) 1)[col] == 1).cumsum()).cumprod() for col in weights.columns]).T
  • Related