pythonpandasquantitative-finance

Convert daily returns to 2 day or 5 day returns


This question was asked for prices but not for returns to my knowledge (not in Python at least). I would like to convert my given daily returns to other frequencies, like 2 day or 5 day returns.

This is what I have:

data = {'date': ['1/1/2022','1/1/2022', '1/2/2022','1/2/2022'], 'ticker': ['A', 'B','A', 'B'], '1dReturn': [0.11, 0.21,0.31, 0.41]}
df = pd.DataFrame(data)

This is what I would like to get for any given n-day return, below for 2 days:

data = {'date': ['1/1/2022','1/1/2022', '1/2/2022','1/2/2022'], 'ticker': ['A', 'B','A', 'B'], '1dReturn': [0.11, 0.21,0.31, 0.41], '2dReturn': [np.NaN, np.NaN,(1+0.11)*(1+0.31)-1, (1+0.21)*(1+0.41)-1]}
df = pd.DataFrame(data)

Solution

  • edit: on second thought I think you might want a rolling product, see the second part

    first interpretation

    You can use a cumprod after adding 1, then subtract 1:

    df['2dReturn'] = (df.groupby('ticker')['1dReturn']
                        .transform(lambda g: g.add(1).cumprod().sub(1).tail(1-2))
                     )
    

    Output:

            date ticker  1dReturn  2dReturn
    0 2022-01-01      A      0.11       NaN
    1 2022-01-01      B      0.21       NaN
    2 2022-01-02      A      0.31    0.4541
    3 2022-01-02      B      0.41    0.7061
    

    If you don't care about the NaNs, then use:

    df['2dReturn'] = df['1dReturn'].add(1).groupby(df['ticker']).cumprod().sub(1)
    
    second interpretation

    Here we only consider the n previous days using rolling and numpy.prod.

    n = 2
    df[f'{n}dReturn'] = (df.groupby('ticker')['1dReturn']
                           .transform(lambda g: g.add(1).rolling(n)
                                                 .apply(np.prod, raw=True)
                                                 .sub(1)
                                     )
                         )
    

    Output (larger example):

            date ticker  1dReturn  2dReturn  3dReturn  4dReturn  5dReturn
    0   1/1/2022      A      0.11       NaN       NaN       NaN       NaN
    1   1/1/2022      B      0.21       NaN       NaN       NaN       NaN
    2   1/2/2022      A      0.31    0.4541       NaN       NaN       NaN
    3   1/2/2022      B      0.41    0.7061       NaN       NaN       NaN
    4   1/3/2022      A      0.12    0.4672  0.628592       NaN       NaN
    5   1/3/2022      B      0.22    0.7202  1.081442       NaN       NaN
    6   1/4/2022      A      0.32    0.4784  0.936704  1.149741       NaN
    7   1/4/2022      B      0.42    0.7324  1.442684  1.955648       NaN
    8   1/5/2022      A      0.13    0.4916  0.670592  1.188476  1.429208
    9   1/5/2022      B      0.23    0.7466  1.130852  2.004501  2.635447
    10  1/6/2022      A      0.33    0.5029  0.983828  1.221887  1.910672
    11  1/6/2022      B      0.43    0.7589  1.497638  2.047118  3.296437