Skip to main content

A calendar wrapper

Project description

doubledate

Managing irregular calendars isn't hard per-se, but it can be painful, especially in the context of trading calendars and backtesting. That is why doubledate exposes a nifty Calendar class to work with custom calendars.

Installation

The best - and easiest - way to install doubledate is by calling:

pip install doubledate 

Usage

import datetime
from doubledate import Calendar, utils

#every day in 2019
#you can load up your own dates from a backend, API, file...
calendar = Calendar([datetime.date(2019,1,1) + datetime.timedelta(i) for i in range(365)])

#weekends
weekends = calendar.weekends()

#week days
weekdays = calendar.weekdays()

#first and last date
weekdays.first(), weekdays.last()

#or index
weekdays[0], weekdays[-1]

#slice the calendar
#like normal lists, the Calendar is 0-based, such that slice(10:20) returns the 11th to 20th dates
weekdays[10:20]

#or with a date-like object
#this will be inclusive of the bounds, if they are in the calendar
s2 = weekdays[datetime.date(2019,7,1):datetime.date(2019,12,31)]

#10th weekday each month
b10 = weekdays.groupby("month").apply(lambda cal: cal[10])

#5th to 10th weekday each month
b5to10 = weekdays.groupby("month").apply(lambda cal: cal[5:10])

#lets retrieve holidays from somewhere (API, file...)
holidays = [
    datetime.date(2019, 1, 1), datetime.date(2019, 1, 21), 
    datetime.date(2019, 2, 18), datetime.date(2019, 5, 27),
    datetime.date(2019, 7, 4), datetime.date(2019, 9, 2), 
    datetime.date(2019, 10, 14), datetime.date(2019, 11, 11), 
    datetime.date(2019, 11, 28), datetime.date(2019, 12, 25)
]

#because the calendar class is a sorted set, you have set methods like union, intersection and difference
#business days
workdays = weekdays.difference(holidays)

#... alternatively
workdays = holidays.inverse(datetime.date(2019, 1, 1), datetime.date(2019, 12, 31)).weekdays()

#non-weekend holidays
offdays = weekdays.union(holidays)

#is my birthday a weekday?
datetime.date(2019, 6, 17) in weekdays
>> True

#slicing is inclusive of the two bounds... summer workdays
summer = workdays[datetime.date(2019,6,21):datetime.date(2019,9,20)]

#index of given date in given frequency
workdays.dayof(datetime.date(2019,8,14), "month")
>> 8

#a few utilities
utils.isleap(2016), utils.isleap(datetime.date(2019,6,17))
>> True, False

#end of month
utils.eom(datetime.date(2016,2,14), 0), utils.eom(datetime.date(2016,2,14), -1)
>> datetime.date(2019, 2, 29), datetime.date(2019, 1, 31)

#... number of work days to new Year's eve
#week end, month end, quarter end, semester end or year end... simply ask for it!
workdays.daysto(to="year end", asof=datetime.date(2019, 11, 15))
>> 45

About doubledate

This package is named after the doubledate calendar, which was itself named after Pope Gregory XIII who introduced it as a correction to the Julian calendar in 1582.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

doubledate-0.0.1.tar.gz (12.2 kB view hashes)

Uploaded Source

Built Distribution

doubledate-0.0.1-py3-none-any.whl (20.5 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page