Search code examples
pythondatetimeforexrrule

RRule set for days and hours in day


I'm using python's rrule to work out trading hours. It's easy for days, i'm using a slightly modified example I found on this very site:

def get_rset(start_date):    
    # Create a rule to recur every weekday starting today
    r = rrule.rrule(rrule.DAILY,
                    byweekday=[rrule.MO, rrule.TU, rrule.WE, rrule.TH, rrule.FR],
                    dtstart=start_date)
    # Create a rruleset
    rs = rrule.rruleset()
    # Attach our rrule to it
    rs.rrule(r)
    # Add holidays as exclusion days
    for exdate in holidays:
        rs.exdate(exdate)
    return rs

The problem is while this works great for shares, I need to calculate forex dates differently. I need to work on an hourly basis, add in public holidays etc.

In UTC I believe the markets are open from 10pm Sunday to 10pm the following Friday.

To make this into a rrule I now need 6 different days with Sunday and Friday needing special hours and the remaining weekdays to be considered all hours. I'm pretty sure I need to mix rrule byday and byhour, but I can't any good examples on doing this.

Any help very welcome!


Solution

  • I've figured out a simpler way, following some time alone with Google, the code and class docs. It uses a slight (but appropriate) cheat. Please see example solution below.

    from dateutil import rrule
    from datetime import  timedelta , datetime
    holidays = [] # This is just a list of dates to exclude
    
    def datetime_in_x_trading_hours(start_dt,future_hours):
        # First we add two hours. This is because its simpler to view the timeset
        # as 24hrs MON - FRI. (This also helps align the dates for the holidays)
        print start_dt
        start_dt += timedelta(hours=2)
        rs = get_fx_rset(start_dt)
        # Now using the set get the desired time and put the the missing hours
        future_time = rs[future_hours]
        future_time -= timedelta(hours=2)
        return future_time
    
    def get_fx_rset(start_date_time):
    
        # Create a rule to recur every weekday starting today
        r = rrule.rrule(rrule.HOURLY,
                        byweekday=[rrule.MO, rrule.TU, rrule.WE, rrule.TH, rrule.FR],
                        byhour=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23],
                        byminute=[0],
                        bysecond=[0],
                        dtstart=start_date_time)
    
        # Create a rruleset
        rs = rrule.rruleset()
        # Attach our rrule to it
        rs.rrule(r)
        # Add holidays as exclusion days
        for exdate in holidays:
            rs.exdate(exdate)
    
        return rs
    
    today = datetime.now() - timedelta(days=2)
    print datetime_in_x_trading_hours(today, 7)