def _get_calendar(weekmask, holidays, calendar): """ Generate busdaycalendar """ if isinstance(calendar, np.busdaycalendar): if not holidays: holidays = tuple(calendar.holidays) elif not isinstance(holidays, tuple): holidays = tuple(holidays) else: # Trust that calendar.holidays and holidays are # consistent pass # Update weekmask if applicable (added) calendar = np.busdaycalendar(weekmask, holidays) return calendar, holidays if holidays is None: holidays = [] # Handle non list holidays also (added) if isinstance(holidays, pd.DatetimeIndex): holidays = holidays.tolist() try: holidays = holidays + calendar.holidays().tolist() except AttributeError: pass holidays = [_to_dt64D(dt) for dt in holidays] holidays = tuple(sorted(holidays)) kwargs = {"weekmask": weekmask} if holidays: kwargs["holidays"] = holidays busdaycalendar = np.busdaycalendar(**kwargs) return busdaycalendar, holidays
def __init__(self, sql, create=False, start=19251231, end=20401231): """Retrieve or create custom calendar (from F-F_Research_Data_Factors)""" self.sql = sql self.table = sql.Table('busdates', Column('date', Integer, primary_key=True)) if create: # reload the series using pandas reader f = pdr.data.DataReader( name='F-F_ST_Reversal_Factor_daily', data_source='famafrench', # 'F-F_Research_Data_Factors_daily' start=1900, end=2050)[0].index.sort_values().unique() df = DataFrame(str2date(f.astype(str), '%Y-%m-%d', '%Y%m%d'), columns=['date']) self.table.create(checkfirst=True) sql.load_dataframe('busdates', df) else: df = sql.read_dataframe('SELECT * FROM busdates') # 1. Initially, dates = actual FamaFrench busdays dates = pd.DatetimeIndex(sorted(list(df['date'].unique().astype(str)))) last = pd.to_datetime(str(df.iloc[-1]['date'])) # 2. Extend with pandas 5-day calendar from last through to 20221231 dates = dates.append( pd.date_range(last, end=pd.to_datetime('20221231'), freq='B')[1:]) # 3. But remove current list of anticipated NYSE holidays hols = [ '20210101', '20210118', '20210215', '20210402', '20210531', '20210705', '20210906', '20211125', '20211224', '20220117', '20220221', '20220415', '20220530', '20220704', '20220905', '20221124', '20221226' ] self.max_date = max(int(max(hols)[:4]) * 10000 + 1231, max(df['date'])) hols = pd.to_datetime(hols) dates = sorted(list(set(dates).difference( set(hols)))) # actual busdays # 4. Generate a list of all potential busdays from pandas 6-day calendar alldates = set( pd.date_range(dates[0], dates[-1], freq=pd.offsets.CDay( calendar=np.busdaycalendar('1111110'), normalize=True))) # 5. Finalize actual holidays: hols = all dates less actual dates hols = np.array(list(alldates.difference(dates)), dtype='datetime64[D]') hols = sorted(set(hols).union([np.datetime64('1926-01-01')])) # Custom and offset calendar objects is 6-day week less actual holidays self.busdaycalendar_ = np.busdaycalendar(weekmask='1111110', holidays=hols) self.custom_ = pd.offsets.CDay(calendar=self.busdaycalendar_) self.begmo_ = pd.offsets.CBMonthBegin(calendar=self.busdaycalendar_) self.endmo_ = pd.offsets.CBMonthEnd(calendar=self.busdaycalendar_)
def calendar(self, x): x = Holidays.modify_calendar_name(x) # Save calendar self.__cal = x # Update buscore engine h = Holidays.holidays(cdr=x) self.__busc = busdaycalendar(weekmask=self.weekmask, holidays=h)
def create_yearmonth_func(years, holidays): def yearmonth_func(year, month, day_float): max_cnt_busdays = yearmonth__max_cnt_busdays[year, month] target_bday = int( round(day_float * (max_cnt_busdays + 1)) ) # int needed since round(np.float64) yields float first_day_in_month = dt.datetime(year, month, 1) return npdatetime2datetime( np.busday_offset( first_day_in_month, target_bday, "forward", busdaycal=busdaycal ) ) busdaycal = np.busdaycalendar(holidays=holidays) yearmonth__max_cnt_busdays = {} for year in years: for month in range(1, 13): first_day_in_month = dt.datetime(year, month, 1) last_day_in_month = dt.datetime( year, month, calendar.monthrange(year, month)[1] ) max_cnt_busdays = np.busday_count( first_day_in_month, last_day_in_month, busdaycal=busdaycal ) yearmonth__max_cnt_busdays[year, month] = int(max_cnt_busdays) return yearmonth_func
def movedatebymonth(your_date, no_of_month=1, business_day='No Adjustment', holidays=[]): bdc = np.busdaycalendar(weekmask='1111100', holidays=holidays) start_m = dt64(your_date, 'M') day = dt64(your_date, 'D') - dt64(start_m, 'D') end_m = start_m + no_of_month next_m = end_m + 1 days_in_end_m = dt64(next_m, 'D') - dt64(end_m, 'D') if days_in_end_m > day: enddate = dt64(end_m, 'D') + day else: enddate = dt64(end_m, 'D') + days_in_end_m - 1 if business_day == 'No Adjustment' or business_day is None: return enddate elif business_day == 'Following': return np.busday_offset(enddate, 0, roll='forward', busdaycal=bdc) elif business_day == 'Preceeding': return np.busday_offset(enddate, 0, roll='backward', busdaycal=bdc) elif business_day == 'Modified Following': new_date = np.busday_offset(enddate, 0, roll='forward', busdaycal=bdc) if dt64(new_date, 'M') > end_m: return np.busday_offset(enddate, 0, roll='backward', busdaycal=bdc) else: return new_date
def adjustdates(months, dates, business_day, holidays=[]): bdc = np.busdaycalendar(weekmask='1111100', holidays=holidays) datalen = len(dates) newdates = [] for i in range(datalen): month = months[i] dmonth = dt64(dates[i], 'M') if dmonth == month: if business_day == 'Following': dates[i] = np.busday_offset(dates[i], 0, roll='forward', busdaycal=bdc) elif business_day == 'Preceeding': dates[i] = np.busday_offset(dates[i], 0, roll='backward', busdaycal=bdc) elif business_day == 'Modified Following': new_date = np.busday_offset(dates[i], 0, roll='forward', busdaycal=bdc) if dt64(new_date, 'M') > month: dates[i] = np.busday_offset(dates[i], 0, roll='backward', busdaycal=bdc) elif dmonth > month: #print(month,dmonth) nextmonth = month + td64(1, 'M') nextmonthdate = dt64(nextmonth, 'D') days = _datediff(dt64(month, 'D'), nextmonthdate) dates[i] = dt64(month, 'D') + days - 1 if business_day == 'Following': dates[i] = np.busday_offset(dates[i], 0, roll='forward', busdaycal=bdc) elif business_day == 'Preceeding': dates[i] = np.busday_offset(dates[i], 0, roll='backward', busdaycal=bdc) elif business_day == 'Modified Following': new_date = np.busday_offset(dates[i], 0, roll='forward', busdaycal=bdc) if dt64(new_date, 'M') > month: dates[i] = np.busday_offset(dates[i], 0, roll='backward', busdaycal=bdc)
def __init__(self, holidays: np.ndarray) -> None: ''' Do not use this function directly. Use Calendar.get_calendar instead Args: holidays (np.array of datetime64[D]): holidays for this calendar, excluding weekends ''' self.bus_day_cal = np.busdaycalendar(holidays=holidays)
def __init__(self, dc, adj=None, calendar=None, weekmask='Mon Tue Wed Thu Fri', adjoffset=0): """ Day count constructor Parameters ---------- dc : str Valid day count convention, e.g. 'act/360', 'bus/252', 'nl/365'. Currently supported values are listed via static method `dc_domain`. adj : None, 'following', 'preceding', 'modifiedfollowing', 'modifiedpreceding', default None None denotes no adjustment. If specified, it determines how dates that do not fall on valid date are treated. Assuming `adjoffset` set to 0: - 'following' denotes next valid date - 'preceding' denotes previous valid date - 'modifiedfollowing' ('modifiedpreceding') is the next (previous) valid date unless it is across a month boundary, in which case it takes the first valid date earlier (later) in time calendar : None, str If specified, it must be the name of a calendar supported by the Holidays factory class weekmask : str or array)like of bool, default 'Mon Tue Wed Thu Fri' From numpy.busday_offset: A seven-element array indicating which of Monday through Sunday are valid days. May be specified as a length-seven list or array, like [1,1,1,1,1,0,0]; a length-seven string, like ‘1111100’; or a string like “Mon Tue Wed Thu Fri”, made up of 3-character abbreviations for weekdays, optionally separated by white space. Valid abbreviations are: Mon Tue Wed Thu Fri Sat Sun adjoffset : int, default 0 Scalar indicating the offset value that will be used if adjustment rule is not set to None Returns ------- self : DayCounts New instance of object Notes ----- (1) Builds on numpy.datetime64 and pandas.Timestamp. As a rule, inputs of methods are any type/value that can be properly parsed by pandas.to_datetime() without optional inputs. Several methods from these packaged are used. """ self.dc = dc self.adj = adj self.adjoffset = adjoffset h = Holidays.holidays(cdr=calendar) self.__busc = busdaycalendar(weekmask=weekmask, holidays=h) self.calendar = calendar
def get_calendar(ccys, cities=nan): """ Create a calendar which has the holidays and business of the curriences and city inputs. Parameters ---------- cities : array of strings, optional DESCRIPTION. Array of three letter (financial) city codes, The default is None. Returns ------- CustomBusinessDay() object, observing the holiday of the cities """ if pd.isnull(ccys) and pd.isnull(cities): return busdaycalendar() # Muslim/Jewish states have Friday & Sunday as the weekend weekmask = getWeekMask(ccys) holidays = [] if cities is not nan: holidays += [ map_citycode_to_holidays[c] for c in cities if c in map_citycode_to_holidays.keys() ] holidays += [ map_ccy_to_holidays[c] for c in ccys if c in map_ccy_to_holidays.keys() ] # Flattan the list of lists holidays = [h for city_holidays in holidays for h in city_holidays] if holidays == []: return busdaycalendar(weekmask=weekmask) else: cal = HolidayCalendarFactory('Cal', AbstractHolidayCalendar(), holidays) cal_instance = cal() holidays = cal_instance.holidays(datetime(2000, 1, 1), datetime(2100, 1, 1)) return busdaycalendar(holidays=Series(holidays.format()))
def _floatleg_gen_structure(data, holidays=[]): # generate the face value and coupons dates = _dates_gen_structure(data) dates = deque(dates) bdc = np.busdaycalendar(weekmask='1111100', holidays=holidays) for date in dates: offset = -start_basis[data["fixing_basis"]] date["fixing_date"] = np.busday_offset(date["start_date"], offset, roll='backward', busdaycal=bdc) date["face_value"] = data["face_value"] date["margin"] = data["margin"] date["cpn_dcf"] = day_cf(data["day_count"], date["start_date"], date["end_date"], bondmat_date=data["maturity"], next_coupon_date=date["end_date"], business_day=data["business_day"], Frequency=data["frequency"]) # fixing date is a forward date if date["fixing_date"] > data["value_date"]: date["is_fixed"] = False date["accrued"] = 0 # fixing date is for the current coupon period elif (date["fixing_date"] <= data["value_date"] and date["end_date"] > data["value_date"]): date["is_fixed"] = True date["coupon"] = data["current_coupon"] date["coupon_interest"] = (date["cpn_dcf"] * date["coupon"] * date["face_value"] / 100) if data["value_date"] > date["start_date"]: acc_dcf = day_cf(data["day_count"], date["start_date"], data["value_date"], bondmat_date=data["maturity"], next_coupon_date=date["end_date"], business_day=data["business_day"], Frequency=data["frequency"]) date["accrued"] = (acc_dcf / date["cpn_dcf"] * date["coupon_interest"]) else: date["accrued"] = 0 else: date["is_fixed"] = True date["accrued"] = 0 date["fv_flow"] = 0 dates[-1]["fv_flow"] = data["face_value"] return dates
def tenor_to_maturity(start_date, tenors, convention='Actual/365 Fixed', business_day='No Adjustment', holidays=[]): bdc = np.busdaycalendar(weekmask='1111100', holidays=holidays) if isinstance(tenors, list): result = [] for tenor in tenors: mat_date = None if 'w' in tenor or 'W' in tenor: tenor_len = [float(number) for number in re.findall(r'-?\d+\.?\d*', tenor)] if len(tenor_len) == 0: mat_date = None result.append(mat_date) else: number = tenor_len[0] number = np.int32(number) mat_date = np.datetime64(start_date, 'D') + 7 * number mat_date = np.busday_offset(mat_date, 0, roll='forward', busdaycal=bdc) result.append(mat_date) elif 'm' in tenor or 'M' in tenor: mat_date = mat_tenor_by_month(start_date, tenor, convention=convention, business_day=business_day, holidays=holidays) result.append(mat_date) elif 'y' in tenor or 'Y' in tenor: mat_date = mat_tenor_by_month(start_date, tenor, convention=convention, business_day=business_day, holidays=holidays, multiplier=12) result.append(mat_date) elif tenor == 'O/N': mat_date = np.busday_offset(start_date, 1, roll='forward', busdaycal=bdc) result.append(mat_date) return result else: result = tenor_to_maturity(start_date, [tenors], convention=convention, business_day=business_day, holidays=holidays) return result[0]
def create_day_float_map(cnt_daydiff, start_date, holidays): busdaycal = np.busdaycalendar(holidays=holidays) result = {} for daydiff in range(cnt_daydiff): date = start_date + dt.timedelta(daydiff) first_day_in_month = date.replace(day=1) last_day_in_month = date.replace( day=calendar.monthrange(date.year, date.month)[1] ) max_cnt_busdays = np.busday_count( first_day_in_month, last_day_in_month, busdaycal=busdaycal ) cnt_busdays = np.busday_count(first_day_in_month, date, busdaycal=busdaycal) result[date] = ( 12 * date.year + (date.month - 1) + float(cnt_busdays / (max_cnt_busdays + 1)) ) return result
def construct_frn(bond, holidays=[]): bdc = np.busdaycalendar(weekmask='1111100', holidays=holidays) bus_day = None if bond['business_day'] == 'NULL': bus_day = 'No Adjustment' else: bus_day = bond['business_day'] if bond['day_count'] == 'NULL': day_count = 'Actual/365' else: day_count = bond['day_count'] start_date = bond.get('issue_date') if start_date is not None: start_date = dt64(start_date, 'D') value_date = bond.get('value_date') if value_date is not None: value_date = dt64(value_date, 'D') if start_date is not None and value_date is not None: use_date = start_date elif start_date is not None: use_date = start_date elif value_date is not None: use_date = value_date else: raise Exception('Both value_date and issue_date do not have any value') dates = gen_dates(use_date, bond['maturity'], issueDate=start_date, frequency=fre[bond['frequency']], business_day=bus_day, method=bond['date_generation']) #print(dates) # ********************************************************************************* # # CALCULATING THE DATA FOR FULL STRUCTURES # # ********************************************************************************* fs = list(dates) flen = len(fs) for i in range(flen): row = fs[i] row['cf'] = 0 row['time'] = day_cf('Actual/365', use_date, row['date'], bondmat_date=fs[-1]['date'], next_coupon_date=row['date']) if i == 0: row['dcf'] = 0 row['y_dcf'] = 0 row['margin'] = 0 row['fv'] = 0 row['fv_flow'] = 0 row['fixing_date'] = None else: row['dcf'] = day_cf(day_count, fs[i - 1]['date'], row['date'], bondmat_date=fs[-1]['date'], next_coupon_date=row['date'], Frequency=12 / fre[bond['frequency']]) row['y_dcf'] = row['dcf'] row['margin'] = bond['margin'] row['fv'] = bond['face_value'] row['fv_flow'] = 0 if i == flen - 1: row['fv_flow'] = bond['face_value'] row['fixing_date'] = bus_off(fs[i - 1]['date'], -start_basis[bond['fixing_basis']], roll='backward', busdaycal=bdc) bond['full_structures'] = fs # ********************************************************************************* # # CALCULATING THE DATA FOR ACTIVE STRUCTURES # # ********************************************************************************* if value_date is None: bond['active_structures'] = {} elif value_date is not None and start_date is None: bond['active_structures'] = bond['full_structures'] elif value_date < start_date: bond['active_structures'] = bond['full_structures'] else: # print(value_date,start_date) booldate = list(map(lambda x: x['date'] > value_date, fs)) index = booldate.index(True) # exclude paid coupon period/start_date acs = list(fs[index - 1:]) acs[0]['y_dcf'] = 0 acs[1]['y_dcf'] = day_cf(day_count, bond['value_date'], acs[1]['date'], bondmat_date=acs[-1]['date'], next_coupon_date=acs[1]['date'], Frequency=12 / fre[bond['frequency']]) alen = len(acs) for i in range(alen): acs[i]['time'] = day_cf('Actual/365', bond['value_date'], acs[i]['date'], bondmat_date=acs[-1]['date'], next_coupon_date=acs[i]['date']) bond['active_structures'] = acs return bond
def _set_busdaycalendar(self): holidays = np.array(self.holidays, dtype='datetime64[D]') self.busdaycalendar = np.busdaycalendar(holidays=holidays, weekmask=self.weekmask)
def _set_busdaycalendar(self): holidays = np.array(self.holidays, dtype="datetime64[D]") self.busdaycalendar = np.busdaycalendar(holidays=holidays, weekmask=self.weekmask)
def get_cal(start=None, end=None): if this.cal is None: if start is None: start = '1901-01-01' start = pd.Timestamp(start, tz='UTC') if end is None: end = datetime.now().date() end += timedelta(weeks=52) end = pd.Timestamp(end, tz='UTC') print('Initializing calendar between {0:s} and {1:s}'.format( str(start.date()), str(end.date()))) non_trading_rules = [] new_years = rrule.rrule(rrule.MONTHLY, byyearday=1, cache=True, dtstart=start, until=end) non_trading_rules.append(new_years) new_years_sunday = rrule.rrule(rrule.MONTHLY, byyearday=2, byweekday=rrule.MO, cache=True, dtstart=start, until=end) non_trading_rules.append(new_years_sunday) mlk_day = rrule.rrule(rrule.MONTHLY, bymonth=1, byweekday=rrule.MO, bysetpos=3, cache=True, dtstart=datetime(1998, 1, 1, tzinfo=pytz.utc), until=end) non_trading_rules.append(mlk_day) lincoln_birthday = rrule.rrule(rrule.MONTHLY, bymonth=2, bymonthday=12, cache=True, dtstart=start, until=datetime(1954, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(lincoln_birthday) lincoln_birthday_sunday = rrule.rrule(rrule.MONTHLY, bymonth=2, bymonthday=13, byweekday=rrule.MO, cache=True, dtstart=start, until=datetime(1954, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(lincoln_birthday_sunday) lincoln_birthday_saturday = rrule.rrule(rrule.MONTHLY, bymonth=2, bymonthday=11, byweekday=rrule.FR, cache=True, dtstart=start, until=datetime( 1954, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(lincoln_birthday_saturday) washington_birthday = rrule.rrule(rrule.MONTHLY, bymonth=2, bymonthday=22, cache=True, dtstart=start, until=datetime(1971, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(washington_birthday) washington_birthday_sunday = rrule.rrule(rrule.MONTHLY, bymonth=2, bymonthday=23, byweekday=rrule.MO, cache=True, dtstart=start, until=datetime( 1971, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(washington_birthday_sunday) washington_birthday_saturday = rrule.rrule(rrule.MONTHLY, bymonth=2, bymonthday=21, byweekday=rrule.FR, cache=True, dtstart=start, until=datetime( 1971, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(washington_birthday_saturday) presidents_day = rrule.rrule(rrule.MONTHLY, bymonth=2, byweekday=rrule.MO, bysetpos=3, cache=True, dtstart=start, until=end) non_trading_rules.append(presidents_day) national_banking_holiday = rrule.rrule( rrule.DAILY, count=6, byweekday=(rrule.MO, rrule.TU, rrule.WE, rrule.TH, rrule.FR), cache=True, dtstart=datetime(1933, 3, 6, tzinfo=pytz.utc)) non_trading_rules.append(national_banking_holiday) good_friday_0 = rrule.rrule(rrule.DAILY, byeaster=-2, cache=True, dtstart=start, until=datetime(1906, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(good_friday_0) good_friday = rrule.rrule(rrule.DAILY, byeaster=-2, cache=True, dtstart=datetime(1908, 1, 1, tzinfo=pytz.utc), until=end) non_trading_rules.append(good_friday) memorial_day = rrule.rrule(rrule.MONTHLY, bymonth=5, bymonthday=30, cache=True, dtstart=start, until=datetime(1971, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(memorial_day) memorial_day_sunday = rrule.rrule(rrule.MONTHLY, bymonth=5, bymonthday=31, byweekday=rrule.MO, cache=True, dtstart=start, until=datetime(1971, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(memorial_day_sunday) memorial_day_saturday = rrule.rrule(rrule.MONTHLY, bymonth=5, bymonthday=29, byweekday=rrule.FR, cache=True, dtstart=start, until=datetime(1971, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(memorial_day_saturday) memorial_day_new = rrule.rrule(rrule.MONTHLY, bymonth=5, byweekday=rrule.MO, bysetpos=-1, cache=True, dtstart=datetime(1971, 1, 1, tzinfo=pytz.utc), until=end) non_trading_rules.append(memorial_day_new) flag_day = rrule.rrule(rrule.MONTHLY, bymonth=6, bymonthday=14, cache=True, dtstart=datetime(1916, 1, 1, tzinfo=pytz.utc), until=datetime(1954, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(flag_day) flag_day_sunday = rrule.rrule(rrule.MONTHLY, bymonth=6, bymonthday=15, byweekday=rrule.MO, cache=True, dtstart=datetime(1916, 1, 1, tzinfo=pytz.utc), until=datetime(1954, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(flag_day_sunday) flag_day_saturday = rrule.rrule(rrule.MONTHLY, bymonth=6, bymonthday=13, byweekday=rrule.FR, cache=True, dtstart=datetime(1916, 1, 1, tzinfo=pytz.utc), until=datetime(1954, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(flag_day_saturday) july_4th = rrule.rrule(rrule.MONTHLY, bymonth=7, bymonthday=4, cache=True, dtstart=start, until=end) non_trading_rules.append(july_4th) july_4th_sunday = rrule.rrule(rrule.MONTHLY, bymonth=7, bymonthday=5, byweekday=rrule.MO, cache=True, dtstart=start, until=end) non_trading_rules.append(july_4th_sunday) july_4th_saturday = rrule.rrule(rrule.MONTHLY, bymonth=7, bymonthday=3, byweekday=rrule.FR, cache=True, dtstart=start, until=end) non_trading_rules.append(july_4th_saturday) labor_day = rrule.rrule(rrule.MONTHLY, bymonth=9, byweekday=rrule.MO, bysetpos=1, cache=True, dtstart=start, until=end) non_trading_rules.append(labor_day) columbus_day = rrule.rrule(rrule.MONTHLY, bymonth=10, bymonthday=12, cache=True, dtstart=datetime(1909, 1, 1, tzinfo=pytz.utc), until=datetime(1954, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(columbus_day) columbus_day_sunday = rrule.rrule(rrule.MONTHLY, bymonth=10, bymonthday=13, byweekday=rrule.MO, cache=True, dtstart=datetime(1909, 1, 1, tzinfo=pytz.utc), until=datetime(1954, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(columbus_day_sunday) columbus_day_saturday = rrule.rrule(rrule.MONTHLY, bymonth=10, bymonthday=11, byweekday=rrule.FR, cache=True, dtstart=datetime(1909, 1, 1, tzinfo=pytz.utc), until=datetime(1954, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(columbus_day_saturday) election_day = rrule.rrule(rrule.MONTHLY, bymonth=11, bymonthday=(2, 3, 4, 5, 6, 7, 8), byweekday=rrule.TU, cache=True, dtstart=start, until=datetime(1969, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(election_day) pres_election_day = rrule.rrule(rrule.YEARLY, interval=4, bymonth=11, bymonthday=(2, 3, 4, 5, 6, 7, 8), byweekday=rrule.TU, cache=True, dtstart=datetime(1972, 1, 1, tzinfo=pytz.utc), until=datetime(1981, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(pres_election_day) veterans_day = rrule.rrule(rrule.MONTHLY, bymonth=11, bymonthday=11, cache=True, dtstart=datetime(1934, 1, 1, tzinfo=pytz.utc), until=datetime(1954, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(veterans_day) veterans_day_sunday = rrule.rrule(rrule.MONTHLY, bymonth=11, bymonthday=12, byweekday=rrule.MO, cache=True, dtstart=datetime(1934, 1, 1, tzinfo=pytz.utc), until=datetime(1954, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(veterans_day_sunday) veterans_day_saturday = rrule.rrule(rrule.MONTHLY, bymonth=11, bymonthday=10, byweekday=rrule.FR, cache=True, dtstart=datetime(1934, 1, 1, tzinfo=pytz.utc), until=datetime(1954, 1, 1, tzinfo=pytz.utc)) non_trading_rules.append(veterans_day_saturday) thanksgiving = rrule.rrule(rrule.MONTHLY, bymonth=11, byweekday=rrule.TH, bysetpos=4, cache=True, dtstart=start, until=end) non_trading_rules.append(thanksgiving) christmas = rrule.rrule(rrule.MONTHLY, bymonth=12, bymonthday=25, cache=True, dtstart=start, until=end) non_trading_rules.append(christmas) christmas_sunday = rrule.rrule(rrule.MONTHLY, bymonth=12, bymonthday=26, byweekday=rrule.MO, cache=True, dtstart=start, until=end) non_trading_rules.append(christmas_sunday) # If Christmas is a Saturday then 24th, a Friday is observed. christmas_saturday = rrule.rrule(rrule.MONTHLY, bymonth=12, bymonthday=24, byweekday=rrule.FR, cache=True, dtstart=start, until=end) non_trading_rules.append(christmas_saturday) paper_crisis = rrule.rrule(rrule.WEEKLY, count=29, cache=True, dtstart=datetime(1968, 6, 12, tzinfo=pytz.utc)) non_trading_rules.append(paper_crisis) world_war_one = rrule.rrule(rrule.DAILY, count=96, byweekday=(rrule.MO, rrule.TU, rrule.WE, rrule.TH, rrule.FR), cache=True, dtstart=datetime(1914, 7, 31, tzinfo=pytz.utc)) non_trading_rules.append(world_war_one) non_trading_ruleset = rrule.rruleset() for rule in non_trading_rules: non_trading_ruleset.rrule(rule) non_trading_days = non_trading_ruleset.between(start, end, inc=True) hols = [] for non_trading_day in non_trading_days: if non_trading_day.weekday() < 5: hols.append(str(non_trading_day.date())) hols.append('1901-09-19') # PresidentialFuneral-WilliamMcKinley hols.append('1901-07-05') # DayAfterIndependenceDay hols.append('1903-04-22') # NewNYSEBuildingOpened hols.append('1917-06-05') # DraftRegistrationDay hols.append('1918-01-28') # HeatlessDay hols.append('1918-02-04') # HeatlessDay hols.append('1918-02-11') # HeatlessDay hols.append('1918-09-12') # DraftRegistrationDay hols.append('1918-11-11') # VeteransDay hols.append('1919-03-25') # HomecomingOf27thDivision hols.append('1919-05-06') # Parade-77thDivision hols.append('1919-09-10') # ReturnOfGeneralJohnPershing hols.append('1921-11-11') # VeteransDay hols.append('1923-08-03') # PresidentialDeath-WarrenHarding hols.append('1923-08-10') # PresidentialFuneral-WarrenHarding hols.append('1927-06-13') # Parade-CharlesLindbergh hols.append('1929-11-01') # ClericalBacklogRelief hols.append('1945-08-15') # VictoryOverJapanDay hols.append('1945-08-16') # VictoryOverJapanDay hols.append('1945-12-24') # Christmas Eve hols.append('1950-12-12') # Saturdayurday-Before-ChristmasEve hols.append('1956-12-24') # Christmas Eve hols.append('1961-05-29') # DayBeforeDecorationDay hols.append('1963-11-25') # PresidentialFuneral-JohnKennedy hols.append('1968-02-12') # LincolnsBirthday hols.append('1968-04-09') # DayOfMourning-MartinLutherKing hols.append('1968-07-05') # DayAfterIndependenceDay hols.append('1969-02-10') # Weather-Snow hols.append('1969-03-31') # PresidentialFuneral-DwightEisenhower hols.append('1969-07-21') # FirstLunarLanding hols.append('1972-12-28') # PresidentialFuneral-HarryTruman hols.append('1973-01-25') # PresidentialFuneral-LyndonJohnson hols.append('1977-07-14') # NewYorkCityBlackout hols.append('1985-09-27') # Weather-HurricaneGloria hols.append('1994-04-27') # PresidentialFuneral-RichardNixon hols.append('2001-09-11') # September 11, 2001 hols.append('2001-09-12') # September 11, 2001 hols.append('2001-09-13') # September 11, 2001 hols.append('2001-09-14') # September 11, 2001 hols.append('2004-06-11') # Reagan's funeral hols.append('2007-01-02') # Ford's funeral hols.append('2012-10-29') # Frankenstorm hols.append('2012-10-30') # Frankenstorm hols.append('2018-12-05') # George H.W. Bush funeral hols.sort() this.cal = np.busdaycalendar(holidays=hols) return this.cal
import numpy as np # Some important days in July bdd = np.busdaycalendar(holidays=['2011-07-01', '2011-07-04', '2011-07-17']) # Default is Monday to Friday weekdays bdd.weekmask # Any holidays already on the weekend are removed bdd.holidays
def __init__(self, dc, adj=None, calendar=None, weekmask='Mon Tue Wed Thu Fri', adjoffset=0): """ Day count constructor Parameters ---------- dc : str Valid day count convention, e.g. 'act/360', 'bus/252', 'nl/365'. Currently supported values are listed via static method `dc_domain`. adj : None, 'following', 'preceding', 'modifiedfollowing', 'modifiedpreceding', default None None denotes no adjustment. If specified, it determines how dates that do not fall on valid date are treated. Assuming `adjoffset` set to 0: - 'following' denotes next valid date - 'preceding' denotes previous valid date - 'modifiedfollowing' ('modifiedpreceding') is the next (previous) valid date unless it is across a month boundary, in which case it takes the first valid date earlier (later) in time calendar : None, str If specified, it must be the name of a calendar supported by the Holidays factory class weekmask : str or array)like of bool, default 'Mon Tue Wed Thu Fri' From numpy.busday_offset: A seven-element array indicating which of Monday through Sunday are valid days. May be specified as a length-seven list or array, like [1,1,1,1,1,0,0]; a length-seven string, like ‘1111100’; or a string like “Mon Tue Wed Thu Fri”, made up of 3-character abbreviations for weekdays, optionally separated by white space. Valid abbreviations are: Mon Tue Wed Thu Fri Sat Sun adjoffset : int, default 0 Scalar indicating the offset value that will be used if adjustment rule is not set to None Returns ------- self : DayCounts New instance of object Notes ----- (1) THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (2) Builds on numpy.datetime64 and pandas.Timestamp. As a rule, inputs of methods are any type/value that can be properly parsed by pandas.to_datetime() without optional inputs. Several methods from these packaged are used. """ self.dc = dc self.adj = adj self.adjoffset = adjoffset h = Holidays.holidays(cdr=calendar) self.__busc = busdaycalendar(weekmask=weekmask, holidays=h) self.calendar = calendar
def get_seconds(): try: start_time = request.args.get( 'start_time') # expecting times to be in ISO-8601 format end_time = request.args.get('end_time') if start_time == end_time: return str(0) start_date_time_obj = datetime.datetime.strptime( start_time.replace('T', ' '), '%Y-%m-%d %H:%M:%S') end_date_time_obj = datetime.datetime.strptime( end_time.replace('T', ' '), '%Y-%m-%d %H:%M:%S') start_hour = start_date_time_obj.hour start_minute = start_date_time_obj.minute start_second = start_date_time_obj.second end_hour = end_date_time_obj.hour end_minute = end_date_time_obj.minute end_second = end_date_time_obj.second all_p_holidays = [ ] # get holidays of all years between start and end for yr in range(start_date_time_obj.year, end_date_time_obj.year + 1): all_p_holidays.extend([ str(yr) + '-01-01', str(yr) + '-03-21', str(yr) + '-04-10', str(yr) + '-04-13', str(yr) + '-04-27', str(yr) + '-05-01', str(yr) + '-06-16', str(yr) + '-08-09', str(yr) + '-09-10', str(yr) + '-09-24', str(yr) + '-12-16', str(yr) + '-12-25', str(yr) + '-12-26' ]) s = datetime.date(start_date_time_obj.year, start_date_time_obj.month, start_date_time_obj.day) e = datetime.date(end_date_time_obj.year, end_date_time_obj.month, end_date_time_obj.day) bd_cal = numpy.busdaycalendar(holidays=all_p_holidays) all_days = numpy.busday_count(s, e, busdaycal=bd_cal) if start_hour < 8: start_hour = 00 start_minute = 00 start_second = 00 current_day = str(start_date_time_obj.year) + '-' + ( str(start_date_time_obj.month) if start_date_time_obj.month >= 10 else "0" + str(start_date_time_obj.month)) + '-' + ( str(start_date_time_obj.day) if start_date_time_obj.day >= 10 else "0" + str(start_date_time_obj.day)) if current_day in all_p_holidays or start_date_time_obj.weekday == 5 or start_date_time_obj == 6: start_hour = 00 start_minute = 00 start_second = 00 current_day = str(end_date_time_obj.year) + '-' + ( str(end_date_time_obj.month) if end_date_time_obj.month >= 10 else "0" + str(end_date_time_obj.month)) + '-' + ( str(end_date_time_obj.day) if end_date_time_obj.day >= 10 else "0" + str(end_date_time_obj.day)) if current_day in all_p_holidays or end_date_time_obj.weekday == 5 or end_date_time_obj == 6: end_hour = 00 end_minute = 00 end_second = 00 if start_hour >= 17: current_day = str(start_date_time_obj.year) + '-' + ( str(start_date_time_obj.month) if start_date_time_obj.month >= 10 else "0" + str(start_date_time_obj.month)) + '-' + ( str(start_date_time_obj.day) if start_date_time_obj.day >= 10 else "0" + str(start_date_time_obj.day)) if current_day not in all_p_holidays or start_date_time_obj.weekday != 5 or start_date_time_obj != 6: all_days = all_days - 1 start_hour = 00 start_minute = 00 start_second = 00 if start_hour >= 8 and start_hour < 17: all_days = all_days - 1 start_hour = 17 - start_hour if end_hour < 8: end_hour = 00 end_minute = 00 end_second = 00 if end_hour <= 17 and end_hour > 8: end_hour = end_hour - 8 start_time_bussiness = datetime.timedelta(days=0, hours=start_hour, minutes=start_minute, seconds=start_second) end_time_bussiness = datetime.timedelta(days=0, hours=end_hour, minutes=end_minute, seconds=end_second) all_time_bussiness = start_time_bussiness + end_time_bussiness days_to_hours = all_days * 9 hours_to_seconds = days_to_hours * 60 * 60 final_output = int(hours_to_seconds + all_time_bussiness.total_seconds()) return str(final_output) except Exception as e: return (str(e))
def dashboardAttendanceUser(): month = request.args.get('month') year = request.args.get('year') auth_header = request.headers.get('Authorization') if auth_header: auth_token = auth_header.split(" ")[1] else: auth_token = '' response = jsonify({'message': 'Provide a valid auth token.'}), 401 if auth_token: secret_key = os.environ.get('SECRET_KEY', '') user = decode_auth_token(secret_key, auth_token) data = {} if user != 401: today = dt.datetime.today().date() if year is None: year = today.year if month: start = dt.datetime(year=int(year), month=int(month), day=1).date() else: month = today.month start = dt.datetime(year=int(year), month=int(month), day=1).date() end = last_day_of_month(start) dateRange = np.arange(np.datetime64(start), np.datetime64(end + timedelta(days=1)), dtype='datetime64[D]') listBusday = np.busdaycalendar(holidays=dateRange, weekmask=busmask_names) listWeekend = np.busdaycalendar(holidays=dateRange, weekmask=weekmask_names) listHoliday = getListHoliday(mongoClient, np, start.year, start.month) get_data_redis = redis_client.get( keys_redis(user['user_id'], 'attendances')) parse_query_date = dt.datetime.strptime( str(year) + '-' + str(month), '%Y-%m').date() if get_data_redis and parse_query_date < dt.datetime.today( ).replace(day=1).date(): start_date = dt.datetime.strptime( str(start) + ' 00:00:00', '%Y-%m-%d %H:%M:%S') end_date = dt.datetime.strptime( str(end) + ' 23:59:59', '%Y-%m-%d %H:%M:%S') list_presence = [ data for data in json.loads(get_data_redis) if start_date <= parse_datetime(data['startDate']) <= end_date ] else: list_presence = getPresence(mongoClient, user['user_id'], str(start), str(end)) # Delete working days if there are holidays listBusday = np.array( list( filter(lambda x: x not in listHoliday, listBusday.holidays))) latePresence = len([ data for data in list_presence if parse_datetime( data['startDate']).date() not in listWeekend.holidays and max_time_presence < parse_datetime(data['startDate']).time() ]) permit = len([ data for data in list_presence if data['message'] in ['CUTI', 'SAKIT', 'IZIN'] ]) totalWfh = len( [data for data in list_presence if data['location'] == 'WFH']) totalWfo = len( [data for data in list_presence if data['location'] == 'WFO']) totalPerjadin = len([ data for data in list_presence if data['location'] == 'PERJADIN' ]) presence = len([ data for data in list_presence if parse_datetime(data['startDate']).date() in listBusday ]) presenceWeekend = len([ data for data in list_presence if parse_datetime( data['startDate']).date() in listWeekend.holidays ]) busDays = len(listBusday) weekEnd = len(listWeekend.holidays) #check no precene from today if parse_query_date >= dt.datetime.today().replace(day=1).date(): dateRangeFromNow = np.arange(np.datetime64(start), np.datetime64(today + timedelta(days=1)), dtype='datetime64[D]') listBusdayFromNow = np.busdaycalendar( holidays=dateRangeFromNow, weekmask=busmask_names) listBusdayFromNow = np.array( list( filter(lambda x: x not in listHoliday, listBusdayFromNow.holidays))) noPresence = len(listBusdayFromNow) - presence else: noPresence = busDays - presence precentagePresence = round( float(presence - permit) / float(busDays) * 100, 2) precentageLatePresence = round( float(latePresence) / float(busDays) * 100, 2) precentagePermit = round(float(permit) / float(busDays) * 100, 2) precentageNoPresence = round( float(noPresence) / float(busDays) * 100, 2) precentagePresenceWeekend = round( float(presenceWeekend) / float(weekEnd) * 100, 2) precentageWfo = round(float(totalWfo) / float(busDays) * 100, 2) precentageWfh = round(float(totalWfh) / float(busDays) * 100, 2) precentagePerjadin = round( float(totalPerjadin) / float(busDays) * 100, 2) array_presence = arrayPresence(noPresence, precentageNoPresence, presence - permit, precentagePresence, presenceWeekend, precentagePresenceWeekend, latePresence, precentageLatePresence) array_permit = arrayPermit(permit, precentagePermit) array_location_user = arrayLocationUser(totalWfo, precentageWfo, totalWfh, precentageWfh, totalPerjadin, precentagePerjadin) data.update(array_presence) data.update(array_permit) data.update(array_location_user) response = jsonify(message="success", data=data, status=200) return response
def BusinessDays(df): import pandas as pd import numpy as np from datetime import datetime, date, time, timedelta #lista feriados cal_srt = np.busdaycalendar(holidays=[ #feriados 2017 '2017-02-27', '2017-02-28', '2017-03-24', '2017-04-13', '2017-04-14', '2017-05-01', '2017-05-25', '2017-06-20', '2017-06-27', '2017-08-21', '2017-10-16', '2017-11-20', '2017-12-08', '2017-12-25', #feriados 2018 '2018-01-01', '2018-02-12', '2018-02-13', '2018-03-29', '2018-03-30', '2018-04-02', '2018-04-30', '2018-05-01', '2018-05-25', '2018-06-20', '2018-06-27', '2018-07-09', '2018-08-20', '2018-10-15', '2018-11-19', '2018-12-24', '2018-12-25', '2018-12-31', #feriados 2019 '2019-01-01', '2019-03-04', '2019-03-05', '2019-03-31', '2019-04-18', '2019-04-19', '2019-05-01', '2019-06-17', '2019-06-20', '2019-06-27', '2019-07-08', '2019-07-09', '2019-08-19', '2019-10-14', '2019-11-18', '2019-12-25', #feriados 2020 '2020-01-01', '2020-02-24', '2020-02-25', '2020-03-23', '2020-03-24', '2020-03-31', '2020-04-09', '2020-04-10', '2020-04-24', '2020-05-01', '2020-05-25', '2020-06-15', '2020-07-09', '2020-07-10', '2020-08-17', '2020-10-12', '2020-11-23', '2020-12-07', '2020-12-08', '2020-12-25', #cuarentena COVID19 #2020-03 '2020-03-20', '2020-03-25', '2020-03-26', '2020-03-27', '2020-03-30', #2020-04 '2020-04-01', '2020-04-02', '2020-04-03', '2020-04-06', '2020-04-07', '2020-04-08', '2020-04-13', '2020-04-14', '2020-04-15', '2020-04-16', '2020-04-17', '2020-04-20', '2020-04-21', '2020-04-22', '2020-04-23', '2020-04-27', '2020-04-28', '2020-04-29', '2020-04-30', #2020-05 '2020-05-04', '2020-05-05', '2020-05-06', '2020-05-07', '2020-05-08', '2020-05-11', '2020-05-12', '2020-05-13', '2020-05-14', '2020-05-15', '2020-05-18', '2020-05-19', '2020-05-20', '2020-05-21', '2020-05-22', '2020-05-25', '2020-05-26', '2020-05-27', '2020-05-28', '2020-05-29', ]) #plazos a calcular plazos = { 'Plazo BOA': ['Fecha caratulacion', 'kfin EDA'], #aplica Circuito=15 & 3+Motivo=R 'Plazo LOOP': ['kini LOOP', 'kfin LOOP'], #no aplica Circuito=5 'Plazo citacion CMJ': ['kini citacion', 'kfin citacion'], #no aplica Circuito=5 'Plazo dictamen CMJ': ['kfin citacion', 'kfin dictamen'], #no aplica Circuito=5 'Plazo SH': ['Fecha ingreso SH', 'kfin SH'], #aplica Circuito=15 'Plazo BO': ['Plazo BOA', 'Plazo LOOP'], 'Plazo TM': ['Plazo citacion CMJ', 'Plazo dictamen CMJ', 'Plazo SH'], 'Plazo completo': ['Plazo BO', 'Plazo TM'], 'Plazo Ley 27348': ['Plazo TM'], #aplica Circuito=15 'Plazo Loop+Ley 27348': ['Plazo LOOP', 'Plazo Ley 27348'], #aplica Circuito=15 } #conversion a datetime for c in df.columns.drop( ['Expediente Nro', 'Circuito', 'Motivo expediente (grupo)']): df[c] = pd.to_datetime(df[c], format='%Y-%m-%dZ', dayfirst=True, infer_datetime_format=True, exact=True, errors='raise') df[c] = df[c].dt.date #calculo de plazos for i in plazos.keys(): print('-- Ejecutando', i) inicio = datetime.now() if i == 'Plazo BOA': df2 = ( df[df.Circuito.isin(['1', '5']) | (df.Circuito.isin(['3']) & df['Motivo expediente (grupo)'].isin(['R' ]))] #filtra filas [[plazos[i][0], plazos[i][1], 'Fecha actualizacion']] #filtra columnas .rename(columns={ plazos[i][0]: 'date1', plazos[i][1]: 'date2' })) #renombra df2['date2'] = df2['date2'].fillna( df2['Fecha actualizacion']) #completa nulos df[i] = df2.apply(lambda x: np.busday_count( x['date1'], x['date2'], busdaycal=cal_srt), axis=1) #calcula plazo elif i == 'Plazo LOOP': df2 = (df[~df.Circuito.isin(['5']) & df[plazos[i][0]].notnull()][[ plazos[i][0], plazos[i][1], 'Fecha actualizacion' ]].rename(columns={ plazos[i][0]: 'date1', plazos[i][1]: 'date2' })) df2['date2'] = df2['date2'].fillna(df2['Fecha actualizacion']) df[i] = df2.apply(lambda x: np.busday_count( x['date1'], x['date2'], busdaycal=cal_srt), axis=1) elif i == 'Plazo citacion CMJ': df2 = (df[~df.Circuito.isin(['5']) & df[plazos[i][0]].notnull()][[ plazos[i][0], plazos[i][1], 'Fecha actualizacion' ]].rename(columns={ plazos[i][0]: 'date1', plazos[i][1]: 'date2' })) df2['date2'] = df2['date2'].fillna(df2['Fecha actualizacion']) df[i] = df2.apply(lambda x: np.busday_count( x['date1'], x['date2'], busdaycal=cal_srt), axis=1) elif i == 'Plazo dictamen CMJ': df2 = (df[~df.Circuito.isin(['5']) & df[plazos[i][0]].notnull()][[ plazos[i][0], plazos[i][1], 'Fecha actualizacion' ]].rename(columns={ plazos[i][0]: 'date1', plazos[i][1]: 'date2' })) df2['date2'] = df2['date2'].fillna(df2['Fecha actualizacion']) df[i] = df2.apply(lambda x: np.busday_count( x['date1'], x['date2'], busdaycal=cal_srt), axis=1) elif i == 'Plazo SH': df2 = (df[df.Circuito.isin(['1', '5']) & df[plazos[i][0]].notnull()][[ plazos[i][0], plazos[i][1], 'Fecha actualizacion' ]].rename(columns={ plazos[i][0]: 'date1', plazos[i][1]: 'date2' })) df2['date2'] = df2['date2'].fillna(df2['Fecha actualizacion']) df[i] = df2.apply(lambda x: np.busday_count( x['date1'], x['date2'], busdaycal=cal_srt), axis=1) elif i == 'Plazo BO': df2 = (df[df[plazos[i][0]].notnull() | df[plazos[i][1]].notnull()]) df[i] = df2[plazos[i][0]].fillna(0) + df2[plazos[i][1]].fillna(0) elif i == 'Plazo TM': df2 = (df[df[plazos[i][0]].notnull() | df[plazos[i][1]].notnull() | df[plazos[i][2]].notnull()]) df[i] = df2[plazos[i][0]].fillna(0) + df2[plazos[i][1]].fillna( 0) + df2[plazos[i][2]].fillna(0) elif i == 'Plazo completo': df2 = df[[plazos[i][0], plazos[i][1]]] df[i] = (df[plazos[i][0]].fillna(0) + df[plazos[i][1]].fillna(0)) elif i == 'Plazo Ley 27348': df[i] = (df[df.Circuito.isin(['1', '5'])][plazos[i][0]]) elif i == 'Plazo Loop+Ley 27348': df2 = (df[df.Circuito.isin(['1', '5']) & df[plazos[i][1]].notnull()]) df[i] = df2[plazos[i][0]].fillna(0) + df2[plazos[i][1]].fillna(0) fin = datetime.now() time_run = fin - inicio print(i, ': avg:', round(df[i].mean(), 2), ' - Tiempo carga:', round(time_run.total_seconds(), 2), 'segundos', ' - Registros:', len(df2)) df = df[[ 'Expediente Nro', 'Plazo BOA', 'Plazo LOOP', 'Plazo citacion CMJ', 'Plazo dictamen CMJ', 'Plazo SH', 'Plazo BO', 'Plazo TM', 'Plazo completo', 'Plazo Ley 27348', 'Plazo Loop+Ley 27348', ]] return df
def listUserByUnit(): search = request.args.get('search') divisi = request.args.get('divisi') start_date = request.args.get('start_date') end_date = request.args.get('end_date') query = queryAccount(divisi=divisi) if search: query = queryAccount(search='%' + search + '%', divisi=divisi) get_users_redis = redis_client.get('users') if get_users_redis and is_blank(search): users = json.loads(get_users_redis) result = [data for data in users if data['id_divisi'] == divisi] else: users = db.session.execute(query) if users.returns_rows == False: return [] else: result_schema = UserResults() result = result_schema.dump(users, many=True) # close connection database users.close() if start_date and end_date: start_date = datetime.datetime.strptime(start_date + '-0:0:0', '%Y-%m-%d-%H:%M:%S') end_date = datetime.datetime.strptime(end_date + '-23:59:59', '%Y-%m-%d-%H:%M:%S') dateRange = np.arange(np.datetime64(start_date), np.datetime64(end_date + timedelta(days=1)), dtype='datetime64[D]') listBusday = np.busdaycalendar(holidays=dateRange, weekmask=busmask_names) listHoliday = getListHoliday(mongoClient, np, start_date, end_date) # Delete working days if there are holidays listBusday = np.array( list(filter(lambda x: x not in listHoliday, listBusday.holidays))) for user in result: listDayNoLogbook = [] dataFillingLogbook = 0 if start_date and end_date: get_data_logbook_redis = redis_client.get( keys_redis(user['id'], 'logbooks')) get_data_attendance_redis = redis_client.get( keys_redis(user['id'], 'attendances')) # Get list date weekend listWeekend = np.busdaycalendar(holidays=dateRange, weekmask=weekmask_names) # Get list date logbook from redis if get_data_logbook_redis and end_date.date( ) < datetime.datetime.today().replace(day=1).date(): # filter date logbook by query listDateLogbook = np.array([ parse_datetime(data['dateTask']).strftime('%Y-%m-%d') for data in json.loads(get_data_logbook_redis) if start_date <= parse_datetime(data['dateTask']) <= end_date ], dtype='datetime64') else: # Get list date logbook from database listDateLogbook = getListDateLogbook(mongoClient, user['id'], np, start_date, end_date) if get_data_attendance_redis and end_date.date( ) < datetime.datetime.today().replace(day=1).date(): # Get list date permit from redis listPermit = np.array([ parse_datetime(data['startDate']).strftime('%Y-%m-%d') for data in json.loads(get_data_attendance_redis) if start_date <= parse_datetime(data['startDate']) <= end_date and data['message'] in ['CUTI', 'SAKIT', 'IZIN'] ], dtype='datetime64') else: # Get list date permit from database listPermit = getListPermit(mongoClient, user['id'], np, start_date, end_date) # Join array date logbook and array date permit listDateLogbook = np.concatenate((listDateLogbook, listPermit)) # Remove duplicate date logbook listDateLogbook = [ i for j, i in enumerate(listDateLogbook) if i not in listDateLogbook[:j] ] # Delete date logbook if there are weekend and holiday listDateLogbook = list( np.array( list( filter( lambda x: x not in np.concatenate( (listWeekend.holidays, listHoliday)), listDateLogbook)))) # Logbook list empty days listDayNoLogbook = list( np.array( list(filter(lambda x: x not in listDateLogbook, listBusday)))) dataFillingLogbook = round( (len(listDateLogbook) / len(listBusday)) * 100, 2) if len(listDayNoLogbook) > 0: listDayNoLogbook = list( np.datetime_as_string(listDayNoLogbook, unit='D')) totalReport = getCountLogbook(mongoClient, user['id'], start_date, end_date) totalHours = getCountHours(mongoClient, user['id'], start_date, end_date) # add new value on user dictonary user['total_report'] = totalReport user['total_hours'] = totalHours user['precentage_logbook_data_filling'] = dataFillingLogbook user['logbook_list_empty_days'] = listDayNoLogbook return jsonify(result)
def _read_holidays(): csv_path = os.path.join(PACKAGE_PATH, 'FactorLib', 'resource/trade_dates.csv') allTradeDays = pd.to_datetime(pd.read_csv(csv_path, index_col=0, header=None, squeeze=True, dtype='str').tolist(), format='%Y%m%d') holidays = (pd.date_range(min(allTradeDays), max(allTradeDays)).difference(allTradeDays)) return holidays CHN_A_Calendar = np.busdaycalendar(holidays=_read_holidays().to_numpy( dtype='datetime64[D]')) bday_chn_ashare = pd.offsets.CustomBusinessDay(calendar=CHN_A_Calendar) bmonthbegin_chn_ashare = pd.offsets.CustomBusinessMonthBegin( calendar=CHN_A_Calendar) bmonthend_chn_ashare = pd.offsets.CustomBusinessMonthEnd( calendar=CHN_A_Calendar) def _validate_date_range(start, end): if start: start = max(pd.Timestamp(start), _default_min_date) if end: end = min(pd.Timestamp(end), _default_max_date) return start, end
'2020-01-01', # Neujahr '2020-01-06', # Heilige Drei Könige '2020-04-10', # Karfreitag '2020-04-13', # Ostermontag '2020-05-01', # Tag der Arbeit '2020-05-21', # Christi Himmelfahrt '2020-06-01', # Pfingstmontag '2020-06-11', # Fronleichnam '2020-10-03', # Tag der Deutschen Einheit '2020-11-01', # Allerheiligen '2020-12-25', # 1. Weihnachtsfeiertag '2020-12-26', # 2. Weihnachtsfeiertag ] CALENDAR_WEEKMASK_GERMANY = 'Mon Tue Wed Thu Fri' bdd = np.busdaycalendar(weekmask=CALENDAR_WEEKMASK_GERMANY, holidays=HOLIDAYS_GERMANY_BADEN_WUERTTEMBERG) check = ['2017-01-01', '2017-05-01', '2017-08-31', '2017-12-25', '2017-12-26', '2017-12-31', '2019-02-04', '2018-08-31'] for day in check: d= np.datetime64(day) result = np.is_busday(d, busdaycal=bdd) print(day, result) p = { 'busday': {'on': dt.time(19, 0, 0), 'off': dt.time(8, 0, 0)}, 'holiday': {} } check = [dt.datetime.now(), dt.datetime(2017,1,1,8,0,0), dt.datetime(2017,6,24,22,0,0), dt.datetime(2017,6,27,19,0,0), dt.datetime(2017,6,27,18,59,59), dt.datetime(2017,6,27,7,59,59), dt.datetime(2017, 6, 27, 8, 0, 0)]
def business_day_calendar(self, week_mask: str = None) -> np.busdaycalendar: return self.__business_day_calendars.setdefault(week_mask, np.busdaycalendar( weekmask=week_mask or self.DEFAULT_WEEK_MASK, holidays=tuple(self.holidays)))
def weekmask(self, x): h = self.holidays.values.astype('datetime64[D]') self.__busc = busdaycalendar(weekmask=x, holidays=h)
from calendars.calendar import getCalendar from calendars.calendar import getWeekMask import pandas as pd import numpy as np holidays = getCalendar(['NZD']) holidays2=pd.Series(holidays.format()) cal = np.busdaycalendar(holidays=pd.Series(holidays.format())) np.busday_offset('2017-04-17',offsets=0,roll='following',busdaycal=cal) #%% x = np.array(cal.to_pydatetime(), dtype=np.datetime64) cal2 = cal.values.strftime('d-mmm-yyy') np.datetime64(cal2) date = pd.date_range('6-Feb-2020', '6-Feb-2020') date + cal cal.holidays() d1 = datetime.strptime('6Feb2020', '%d%b%Y') d1.date() from datetime import datetime d = np.array([np.datetime64(datetime.strptime('6Feb2020', '%d%b%Y')),np.datetime64(datetime.strptime('7Feb2020', '%d%b%Y'))])
import numpy as np BUSCAL_CHN = np.busdaycalendar(holidays=['2015-01-01', '2015-02-19']) def day_count(begin_dates, end_dates, freq='D', calendar=None): """ Currently, it is just a wrapper on datetime and numpy functions. Setup the interface here to facilitate future update calendar: A busdaycalendar object which specifies the valid days. If this parameter is provided, neither weekmask nor holidays may be provided. """ if freq == 'D': # using timedelta to deal with this return (end_dates - begin_dates).days if freq == 'B': if calendar: return np.busday_count(begin_dates, end_dates, busdaycal=calendar) else: return np.busday_count(begin_dates, end_dates) else: raise NotImplementedError('Other freq type is NOT supported!') if __name__ == '__main__': import datetime as dt print(day_count(dt.date(2014, 1, 1), dt.date(2014, 12, 1))) print(day_count(dt.date(2014, 1, 1), dt.date(2014, 12, 1), freq='B'))