/******************************************************************************* * Copyright (c) 2013 Luigi Sgro. All rights reserved. This * program and the accompanying materials are made available under the terms of * the Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Luigi Sgro - initial API and implementation ******************************************************************************/ package com.quantcomponents.core.calendar; import java.util.Calendar; import java.util.Date; import java.util.Map; import java.util.Set; import com.quantcomponents.core.model.BareDate; /** * Base class for periodic trading calendars. * Implementors must specify a set of: * <ul> * <li>closing days</li> * <li>special opening days</li> * <li>normal week days</li> * </li> * that will be used to calculate the trading periods * for any date. */ public abstract class AbstractPeriodicTradingCalendar implements ITradingCalendar { private static final ITradingDay BANK_HOLIDAY = new BankHoliday(); private final ThreadLocal<Calendar> calendars = new ThreadLocal<Calendar>() { @Override protected Calendar initialValue() { return Calendar.getInstance(); } }; @Override public ITradingDay tradingDay(Date date) { if (date.before(getStartDate()) || !date.before(getEndDate())) { throw new IllegalArgumentException(); } Calendar calendar = calendars.get(); calendar.setTimeZone(getTimeZone()); calendar.setTime(date); calendar.set(Calendar.MILLISECOND, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.HOUR_OF_DAY, 0); BareDate bareDate = new BareDate(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE)); ITradingDay specialDay = getSpecialTradingDays().get(bareDate.getDateRepr()); if (specialDay != null) { return specialDay; } if (getClosingDays().contains(bareDate)) { return BANK_HOLIDAY; } ITradingDay tradingDay = getWeekTradingDays().get(calendar.get(Calendar.DAY_OF_WEEK)); if (tradingDay == null) { tradingDay = BANK_HOLIDAY; } return tradingDay; } protected abstract Set<BareDate> getClosingDays(); protected abstract Map<String, ? extends ITradingDay> getSpecialTradingDays(); protected abstract Map<Integer, ? extends ITradingDay> getWeekTradingDays(); }