I would like to compute weekly returns but starting from the end date backwards. This is my initial attempt to implement it using pandas:
import pandas as pd
import numpy as np
from pandas.tseries.offsets import BDay
index = pd.date_range(start='2020-09-13', end='2020-10-13', freq=BDay())
index_len = len(index)
dfw = pd.DataFrame(data=np.arange(start=1, stop=1+(index_len-1)*0.002, step=0.002),
index=index,
columns=['col1'])
def weekly_ret(x):
if x.size > 0:
print(f"range is {x.index[0]} - {x.index[-1]}")
return (x.iloc[-1] - x.iloc[0]) / x.iloc[0]
else:
return np.nan
dfw = dfw.resample(rule='5B').apply(weekly_ret)
print(dfw)
then I get the following output but this is not what I want:
range is 2020-09-14 00:00:00 - 2020-09-18 00:00:00
range is 2020-09-21 00:00:00 - 2020-09-25 00:00:00
range is 2020-09-28 00:00:00 - 2020-10-02 00:00:00
range is 2020-10-05 00:00:00 - 2020-10-09 00:00:00
range is 2020-10-12 00:00:00 - 2020-10-13 00:00:00
col1
2020-09-14 0.008000
2020-09-21 0.007921
2020-09-28 0.007843
2020-10-05 0.007767
2020-10-12 0.001923
I would like it to start from 2020-10-13
backwards so that the last range would be:
range is 2020-10-07 00:00:00 - 2020-10-13 00:00:00
instead of:
range is 2020-10-12 00:00:00 - 2020-10-13 00:00:00
What I have tried so far:
- Inverting the dataframe with
dfw = dfw.reindex(index=dfw.index[::-1])
- The step #1 above plus having the rule to be
-5B
, this results in an error. - Using the origin parameter for the resample function but this has no effect on the order of the computation i.e.
origin=dfw.index[-1]
- The step #1 above plus computing per number of rows on the inverted dataframe
dfw = dfw.rolling(5).apply(weekly_ret)[::5]
but here I get a NaN for the first (last) interval and this solution is somewhat also wasteful.
UPDATE: this would be the wanted output; notice the last return considers the week starting from the last day in the index backwards:
range is 2020-09-16 00:00:00 - 2020-09-22 00:00:00 = 0.007968127490039847
range is 2020-09-23 00:00:00 - 2020-09-29 00:00:00 = 0.00788954635108482
range is 2020-09-30 00:00:00 - 2020-10-06 00:00:00 = 0.007812500000000007
range is 2020-10-07 00:00:00 - 2020-10-13 00:00:00 = 0.00773694390715668
col1
2020-09-22 0.007968
2020-09-29 0.007890
2020-10-06 0.007813
2020-10-13 0.007737 i.e. (1.042 - 1.034)/1.034