Home > Blockchain >  How Can we Loop Through a Range of Rolling Dates?
How Can we Loop Through a Range of Rolling Dates?

Time:11-27

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)

CodePudding user response:

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

CodePudding user response:

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))

CodePudding user response:

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
  • Related