How Can we Loop Through a Range of Rolling Dates?

Question:

I did some Googling and figured out how to generate all Friday dates in a year.

# get all Fridays in a year
from datetime import date, timedelta
def allfridays(year):
   d = date(year, 1, 1)               # January 1st              
   d += timedelta(days = 8 - 2)       # Friday   
   while d.year == year:
      yield d
      d += timedelta(days = 7)

      
for d in allfridays(2022):
   print(d)

Result:

2022-01-07
2022-01-14
2022-01-21
etc.
2022-12-16
2022-12-23
2022-12-30

Now, I’m trying to figure out how to loop through a range of rolling dates, so like 2022-01-07 + 60 days, then 2022-01-14 + 60 days, then 2022-01-21 + 60 days.

step #1:
start = '2022-01-07'
end = '2022-03-08'

step #2:
start = '2022-01-14'
end = '2022-03-15'

Ideally, I want to pass in the start and end date loop, into another loop, which looks like this…

price_data = []
for ticker in tickers:
    try:
        prices = wb.DataReader(ticker, start = start.strftime('%m/%d/%Y'), end = end.strftime('%m/%d/%Y'), data_source='yahoo')[['Adj Close']]
        price_data.append(prices.assign(ticker=ticker)[['ticker', 'Adj Close']])
    except:
        print(ticker)        
df = pd.concat(price_data)
Asked By: ASH

||

Answers:

This could work maybe. You can add the condition, the end of the loop within the lambda function.

from datetime import date, timedelta
    def allfridays(year):
       d = date(year, 1, 1)               # January 1st              
       d += timedelta(days = 8 - 2)       # Friday   
       while d.year == year:
          yield d
          d += timedelta(days = 7) 
    list_dates = []
    for d in allfridays(2022):
    list_dates.append(d)
    

    add_days = map(lambda x: x+timedelta(days = 60),list_dates)
    print(list(add_days))
Answered By: Selknam_CL

Oh my, I totally missed this before. The solution below works just fine.

import pandas as pd
# get all Fridays in a year
from datetime import date, timedelta
def allfridays(year):
   d = date(year, 1, 1)               # January 1st              
   d += timedelta(days = 8 - 2)       # Friday   
   while d.year == year:
      yield d
      d += timedelta(days = 7)

lst=[]
for d in allfridays(2022):
    lst.append(d)
    
df = pd.DataFrame(lst)
print(type(df))
df.columns = ['my_dates']


df['sixty_ahead'] = df['my_dates'] + timedelta(days=60)
df 

Result:
      my_dates sixty_ahead
0   2022-01-07  2022-03-08
1   2022-01-14  2022-03-15
2   2022-01-21  2022-03-22
etc.
49  2022-12-16  2023-02-14
50  2022-12-23  2023-02-21
51  2022-12-30  2023-02-28
Answered By: ASH

First, we have to figure out how to get the first Friday of a given year. Next, we will calculate the start, end days.

import datetime

FRIDAY = 4  # Based on Monday=0
WEEK = datetime.timedelta(days=7)


def first_friday(year):
    """Return the first Friday of the year."""
    the_date = datetime.date(year, 1, 1)
    while the_date.weekday() != FRIDAY:
        the_date = the_date + datetime.timedelta(days=1)
    return the_date


def friday_ranges(year, days_count):
    """
    Generate date ranges that starts on first Friday of `year` and
    lasts for `days_count`.
    """
    DURATION = datetime.timedelta(days=days_count)

    start_date = first_friday(year)
    end_date = start_date + DURATION

    while end_date.year == year:
        yield start_date, end_date
        start_date += WEEK
        end_date = start_date + DURATION


for start_date, end_date in friday_ranges(year=2022, days_count=60):
    # Do what you want with start_date and end_date
    print((start_date, end_date))

Sample output:

(datetime.date(2022, 1, 7), datetime.date(2022, 3, 8))
(datetime.date(2022, 1, 14), datetime.date(2022, 3, 15))
(datetime.date(2022, 1, 21), datetime.date(2022, 3, 22))
...
(datetime.date(2022, 10, 21), datetime.date(2022, 12, 20))
(datetime.date(2022, 10, 28), datetime.date(2022, 12, 27))

Notes

  • The algorithm for first Friday is simple: Start with Jan 1, then keep advancing the day until Friday
  • I made an assumption that the end date must fall into the specified year. If that is not the case, you can adjust the condition in the while loop
Answered By: Hai Vu

as you use pandas then you can try to do it this way:

import pandas as pd

year = 2022
dates = pd.date_range(start=f'{year}-01-01',end=f'{year}-12-31',freq='W-FRI')
df = pd.DataFrame({'my_dates':dates, 'sixty_ahead':dates + pd.Timedelta(days=60)})

print(df.head())
'''
    my_dates sixty_ahead
0 2022-01-07  2022-03-08
1 2022-01-14  2022-03-15
2 2022-01-21  2022-03-22
3 2022-01-28  2022-03-29
4 2022-02-04  2022-04-05
Answered By: SergFSM
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.