import more_itertools as mit
s = """datadate,fyear,tic,ab_ret
31/12/1998,1998,AAPL,0.045
31/12/1999,1999,AAPL,0.012
31/12/1999,2000,AAPL,0.012
31/12/2002,2002,AAPL,-0.031
31/12/2003,2003,AAPL,-0.007
31/12/2005,2005,AAPL,0.001
31/12/2005,2007,AAPL,0.001
31/12/2005,2008,AAPL,0.001
31/12/2005,2009,AAPL,0.001
31/05/2008,2008,TSLA,0.034
31/05/2009,2009,TSLA,0.061
31/05/2010,2010,TSLA,0.003
31/05/2011,2011,TSLA,-0.004
31/05/2014,2014,TSLA,0.009"""
df = pd.read_csv(StringIO(s))
# create a groupby object
g = df.groupby('tic')['fyear']
# list comprehension to find consective groups
data = [{k: [list(gr) for gr in mit.consecutive_groups(v.values)]} for k,v in g]
# now find the group with the most consecutive years
m = [{k: list(filter(lambda x: len(x)>=3, v)) for k,v in x.items()} for x in data]
# iterate through list to create a dict
d = {}
[d.update(di) for di in m]
# create a dataframe from dict
df2 = pd.DataFrame(dict([(k,pd.Series(v)) for k,v in d.items()])).stack().reset_index(level=1).explode(0)
# create a mask and cumsum
mask = ~(df2[0].diff().bfill() == 1)
df2['gr'] = mask.cumsum().where(~mask).bfill().astype(int)
# merge two dataframes together
merge = df.merge(df2, left_on=['tic', 'fyear'], right_on=['level_1', 0])
# rolling
merge['cum_ab'] = merge.groupby(['tic', 'gr'])['ab_ret'].rolling(3).sum().reset_index(level=[0,1], drop=True)
# merge with the original df
final = df.merge(merge[['tic', 'fyear', 'cum_ab']], on=['tic', 'fyear'], how='left')
datadate fyear tic ab_ret cum_ab
0 31/12/1998 1998 AAPL 0.0 nan
1 31/12/1999 1999 AAPL 0.0 nan
2 31/12/1999 2000 AAPL 0.0 0.1
3 31/12/2002 2002 AAPL -0.0 nan
4 31/12/2003 2003 AAPL -0.0 nan
5 31/12/2005 2005 AAPL 0.0 nan
6 31/12/2005 2007 AAPL 0.0 nan
7 31/12/2005 2008 AAPL 0.0 nan
8 31/12/2005 2009 AAPL 0.0 0.0
9 31/05/2008 2008 TSLA 0.0 nan
10 31/05/2009 2009 TSLA 0.1 nan
11 31/05/2010 2010 TSLA 0.0 0.1
12 31/05/2011 2011 TSLA -0.0 0.1
13 31/05/2014 2014 TSLA 0.0 nan