001 /*
002 Copyright (C) 2007 Richard Gomes
003
004 This source code is release under the BSD License.
005
006 This file is part of JQuantLib, a free-software/open-source library
007 for financial quantitative analysts and developers - http://jquantlib.org/
008
009 JQuantLib is free software: you can redistribute it and/or modify it
010 under the terms of the JQuantLib license. You should have received a
011 copy of the license along with this program; if not, please email
012 <jquant-devel@lists.sourceforge.net>. The license is also available online at
013 <http://www.jquantlib.org/index.php/LICENSE.TXT>.
014
015 This program is distributed in the hope that it will be useful, but WITHOUT
016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
017 FOR A PARTICULAR PURPOSE. See the license for more details.
018
019 JQuantLib is based on QuantLib. http://quantlib.org/
020 When applicable, the original copyright notice follows this notice.
021 */
022
023 package org.jquantlib.daycounters;
024
025 import org.jquantlib.lang.annotation.QualityAssurance;
026 import org.jquantlib.lang.annotation.QualityAssurance.Quality;
027 import org.jquantlib.lang.annotation.QualityAssurance.Version;
028 import org.jquantlib.time.Date;
029
030 /**
031 * Simple day counter for reproducing theoretical calculations.
032 * <p>
033 * This day counter tries to ensure that whole-month distances are returned as a
034 * simple fraction, i.e., 1 year = 1.0, 6 months = 0.5, 3 months = 0.25 and so
035 * forth.
036 *
037 * @note This day counter should be used together with NullCalendar, which
038 * ensures that dates at whole-month distances share the same day of
039 * month. It is <b>not</b> guaranteed to work with any other calendar.
040 *
041 * @author Srinivas Hasti
042 * @author Richard Gomes
043 */
044 @QualityAssurance(quality=Quality.Q4_UNIT, version=Version.V097, reviewers="Richard Gomes")
045 public class SimpleDayCounter extends DayCounter {
046
047
048 public SimpleDayCounter() {
049 super.impl = new Impl();
050 }
051
052
053 //
054 // private inner classes
055 //
056
057 final private class Impl extends DayCounter.Impl {
058
059 private final DayCounter fallback = new Thirty360();
060
061 //
062 // implements DayCounter
063 //
064
065 @Override
066 protected final String name() /* @ReadOnly */{
067 return "Simple";
068 }
069
070 @Override
071 protected long dayCount(final Date dateStart, final Date dateEnd) /* @ReadOnly */ {
072 return fallback.dayCount(dateStart, dateEnd);
073 }
074
075 @Override
076 protected /*@Time*/ final double yearFraction(
077 final Date dateStart, final Date dateEnd,
078 final Date refPeriodStart, final Date refPeriodEnd) /* @ReadOnly */{
079 final int dm1 = dateStart.dayOfMonth();
080 final int dm2 = dateEnd.dayOfMonth();
081 final int mm1 = dateStart.month().value();
082 final int mm2 = dateEnd.month().value();
083 final int yy1 = dateStart.year();
084 final int yy2 = dateEnd.year();
085
086 if (dm1 == dm2 ||
087 // e.g., Aug 30 -> Feb 28 ?
088 (dm1 > dm2 && Date.isEndOfMonth(dateEnd)) ||
089 // e.g., Feb 28 -> Aug 30 ?
090 (dm1 < dm2 && Date.isEndOfMonth(dateStart)))
091 return (yy2 - yy1) + (mm2 - mm1) / 12.0;
092 else
093 return fallback.yearFraction(dateStart, dateEnd, refPeriodStart, refPeriodEnd);
094 }
095
096 }
097
098 }