Logo Search packages:      
Sourcecode: quantlib version File versions

period.cpp

/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
 Copyright (C) 2004, 2005, 2006 Ferdinando Ametrano
 Copyright (C) 2006 Katiuscia Manzoni
 Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl
 Copyright (C) 2003, 2004, 2005, 2006 StatPro Italia srl

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 <quantlib-dev@lists.sf.net>. The license is also available online at
 <http://quantlib.org/reference/license.html>.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
*/

#include <ql/period.hpp>

namespace QuantLib {

    Period::Period(Frequency f) {
        switch (f) {
          case Once:
          case NoFrequency:
            // same as Period()
            units_ = Days;
            length_ = 0;
            break;
          case Annual:
            units_ = Years;
            length_ = 1;
            break;
          case Semiannual:
          case EveryFourthMonth:
          case Quarterly:
          case Bimonthly:
          case Monthly:
            units_ = Months;
            length_ = 12/f;
            break;
          case Biweekly:
          case Weekly:
            units_ = Weeks;
            length_ = 52/f;
            break;
          case Daily:
            units_ = Days;
            length_ = 1;
            break;
          default:
            QL_FAIL("unknown frequency (" << Integer(f));
        }
    }

    Frequency Period::frequency() const {
        // unsigned version
        Size length = std::abs(length_);

        if (length==0) return NoFrequency;

        switch (units_) {
          case Years:
            QL_REQUIRE(length==1,
                       "cannot instantiate a Frequency from " << *this);
            return Annual;
          case Months:
            QL_REQUIRE((12%length)==0 && length<=12,
                       "cannot instantiate a Frequency from " << *this);
            return Frequency(12/length);
          case Weeks:
            if (length==1)
                return Weekly;
            else if (length==2)
                return Biweekly;
            else
                QL_FAIL("cannot instantiate a Frequency from " << *this);
          case Days:
            QL_REQUIRE(length==1,
                       "cannot instantiate a Frequency from " << *this);
            return Daily;
          default:
            QL_FAIL("unknown time unit (" << Integer(units_));
        }
    }

00092     bool operator<(const Period& p1, const Period& p2) {
        switch (p1.units()) {
          case Days:
            switch (p2.units()) {
              case Days:
                return (p1.length() < p2.length());
              case Weeks:
                return (p1.length() < p2.length() * 7);
              case Months:
                if (p1.length() < p2.length() * 28)
                    return true;
                else
                    QL_FAIL("undecidable comparison between "
                             << p1 << " and " << p2);
              case Years:
                return (p1.length() < p2.length() * 365);
              default:
                QL_FAIL("unknown units");
            }
          case Weeks:
            switch (p2.units()) {
              case Days:
                return (p1.length() * 7 < p2.length());
              case Weeks:
                return (p1.length() < p2.length());
              case Months:
                if (p1.length() * 7 < p2.length() * 28)
                    return true;
                else
                    QL_FAIL("undecidable comparison between "
                             << p1 << " and " << p2);
              case Years:
                if (p1.length() * 7 < p2.length() * 365)
                    return true;
                else
                    QL_FAIL("undecidable comparison between "
                             << p1 << " and " << p2);
              default:
                QL_FAIL("unknown units");
            }
          case Months:
            switch (p2.units()) {
              case Days:
                // Sup[days in p1.length() months] < days in p2
                if (p1.length() * 31 < p2.length())
                    return true;
                // almost 28 days in p1 and less than 28 days in p2
                else if ((p1.length()!=0) && p2.length()< 28)
                    return false;
                else
                    QL_FAIL("undecidable comparison between "
                             << p1 << " and " << p2);
              case Weeks:
                if (p1.length()* 31 < p2.length()  * 7)
                    return true;
                else
                    QL_FAIL("undecidable comparison between "
                             << p1 << " and " << p2);
              case Months:
                return (p1.length() < p2.length());
              case Years:
                return (p1.length() < p2.length() * 12);
              default:
                QL_FAIL("unknown units");
            }
          case Years:
            switch (p2.units()) {
              case Days:
                if (p1.length() * 366 < p2.length())
                    return true;
                // almost 365 days in p1 and less than 365 days in p2
                else if ((p1.length()!=0) && p2.length()< 365)
                    return false;
                else
                    QL_FAIL("undecidable comparison between "
                             << p1 << " and " << p2);
              case Weeks:
                if (p1.length() * 366 < p2.length() * 7)
                    return true;
                else
                    QL_FAIL("undecidable comparison between "
                             << p1 << " and " << p2);
              case Months:
                return (p1.length() * 12 < p2.length());
              case Years:
                return (p1.length() < p2.length());
              default:
                QL_FAIL("unknown units");
            }
          default:
            QL_FAIL("unknown units");
        }
    }

    // period formatting

00188     std::ostream& operator<<(std::ostream& out, const Period& p) {
        return out << io::short_period(p);
    }

    namespace detail {

        std::ostream& operator<<(std::ostream& out,
                                 const long_period_holder& holder) {
            Integer n = holder.p.length();
            out << n << " ";
            switch (holder.p.units()) {
              case Days:
                return out << (n == 1 ? "day" : "days");
              case Weeks:
                return out << (n == 1 ? "week" : "weeks");
              case Months:
                return out << (n == 1 ? "month" : "months");
              case Years:
                return out << (n == 1 ? "year" : "years");
              default:
                QL_FAIL("unknown time unit");
            }
        }

        std::ostream& operator<<(std::ostream& out,
                                 const short_period_holder& holder) {
            Integer n = holder.p.length();
            out << n;
            switch (holder.p.units()) {
              case Days:
                return out << "D";
              case Weeks:
                return out << "W";
              case Months:
                return out << "M";
              case Years:
                return out << "Y";
              default:
                QL_FAIL("unknown time unit");
            }
        }

    }

    namespace io {

00234         detail::long_period_holder long_period(const Period& p) {
            return detail::long_period_holder(p);
        }

00238         detail::short_period_holder short_period(const Period& p) {
            return detail::short_period_holder(p);
        }

    }


   // frequency formatting

    std::ostream& operator<<(std::ostream& out, Frequency f) {
        switch (f) {
          case NoFrequency:
            return out << "no-frequency";
          case Once:
            return out << "once";
          case Annual:
            return out << "annual";
          case Semiannual:
            return out << "semiannual";
          case EveryFourthMonth:
            return out << "every-fourth-month";
          case Quarterly:
            return out << "quarterly";
          case Bimonthly:
            return out << "bimonthly";
          case Monthly:
            return out << "monthly";
          case Biweekly:
            return out << "biweekly";
          case Weekly:
            return out << "weekly";
          case Daily:
            return out << "daily";
          default:
            QL_FAIL("unknown frequency (" << Integer(f) << ")");
        }
    }

}

Generated by  Doxygen 1.6.0   Back to index