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)
edit: on second thought I think you might want a rolling
product, see the second part
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)
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