Convention.java

  1. package org.drip.analytics.daycount;

  2. /*
  3.  * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  4.  */

  5. /*!
  6.  * Copyright (C) 2020 Lakshmi Krishnamurthy
  7.  * Copyright (C) 2019 Lakshmi Krishnamurthy
  8.  * Copyright (C) 2018 Lakshmi Krishnamurthy
  9.  * Copyright (C) 2017 Lakshmi Krishnamurthy
  10.  * Copyright (C) 2016 Lakshmi Krishnamurthy
  11.  * Copyright (C) 2015 Lakshmi Krishnamurthy
  12.  * Copyright (C) 2014 Lakshmi Krishnamurthy
  13.  * Copyright (C) 2013 Lakshmi Krishnamurthy
  14.  * Copyright (C) 2012 Lakshmi Krishnamurthy
  15.  * Copyright (C) 2011 Lakshmi Krishnamurthy
  16.  *
  17.  *  This file is part of DROP, an open-source library targeting analytics/risk, transaction cost analytics,
  18.  *      asset liability management analytics, capital, exposure, and margin analytics, valuation adjustment
  19.  *      analytics, and portfolio construction analytics within and across fixed income, credit, commodity,
  20.  *      equity, FX, and structured products. It also includes auxiliary libraries for algorithm support,
  21.  *      numerical analysis, numerical optimization, spline builder, model validation, statistical learning,
  22.  *      and computational support.
  23.  *  
  24.  *      https://lakshmidrip.github.io/DROP/
  25.  *  
  26.  *  DROP is composed of three modules:
  27.  *  
  28.  *  - DROP Product Core - https://lakshmidrip.github.io/DROP-Product-Core/
  29.  *  - DROP Portfolio Core - https://lakshmidrip.github.io/DROP-Portfolio-Core/
  30.  *  - DROP Computational Core - https://lakshmidrip.github.io/DROP-Computational-Core/
  31.  *
  32.  *  DROP Product Core implements libraries for the following:
  33.  *  - Fixed Income Analytics
  34.  *  - Loan Analytics
  35.  *  - Transaction Cost Analytics
  36.  *
  37.  *  DROP Portfolio Core implements libraries for the following:
  38.  *  - Asset Allocation Analytics
  39.  *  - Asset Liability Management Analytics
  40.  *  - Capital Estimation Analytics
  41.  *  - Exposure Analytics
  42.  *  - Margin Analytics
  43.  *  - XVA Analytics
  44.  *
  45.  *  DROP Computational Core implements libraries for the following:
  46.  *  - Algorithm Support
  47.  *  - Computation Support
  48.  *  - Function Analysis
  49.  *  - Model Validation
  50.  *  - Numerical Analysis
  51.  *  - Numerical Optimizer
  52.  *  - Spline Builder
  53.  *  - Statistical Learning
  54.  *
  55.  *  Documentation for DROP is Spread Over:
  56.  *
  57.  *  - Main                     => https://lakshmidrip.github.io/DROP/
  58.  *  - Wiki                     => https://github.com/lakshmiDRIP/DROP/wiki
  59.  *  - GitHub                   => https://github.com/lakshmiDRIP/DROP
  60.  *  - Repo Layout Taxonomy     => https://github.com/lakshmiDRIP/DROP/blob/master/Taxonomy.md
  61.  *  - Javadoc                  => https://lakshmidrip.github.io/DROP/Javadoc/index.html
  62.  *  - Technical Specifications => https://github.com/lakshmiDRIP/DROP/tree/master/Docs/Internal
  63.  *  - Release Versions         => https://lakshmidrip.github.io/DROP/version.html
  64.  *  - Community Credits        => https://lakshmidrip.github.io/DROP/credits.html
  65.  *  - Issues Catalog           => https://github.com/lakshmiDRIP/DROP/issues
  66.  *  - JUnit                    => https://lakshmidrip.github.io/DROP/junit/index.html
  67.  *  - Jacoco                   => https://lakshmidrip.github.io/DROP/jacoco/index.html
  68.  *
  69.  *  Licensed under the Apache License, Version 2.0 (the "License");
  70.  *      you may not use this file except in compliance with the License.
  71.  *  
  72.  *  You may obtain a copy of the License at
  73.  *      http://www.apache.org/licenses/LICENSE-2.0
  74.  *  
  75.  *  Unless required by applicable law or agreed to in writing, software
  76.  *      distributed under the License is distributed on an "AS IS" BASIS,
  77.  *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  78.  *  
  79.  *  See the License for the specific language governing permissions and
  80.  *      limitations under the License.
  81.  */

  82. /**
  83.  * <i>Convention</i> contains flags that indicate where the holidays are loaded from, as well as the holiday
  84.  * types and load rules. It exports the following date related functionality:
  85.  *
  86.  *  <br><br>
  87.  *  <ul>
  88.  *      <li>
  89.  *          Add business days according to the specified calendar
  90.  *      </li>
  91.  *      <li>
  92.  *          The Year Fraction between any 2 days given the day count type and the holiday calendar
  93.  *      </li>
  94.  *      <li>
  95.  *          Adjust/roll to the next working day according to the adjustment rule
  96.  *      </li>
  97.  *      <li>
  98.  *          Holiday Functions; is the given day a holiday/business day, the number and the set of
  99.  *              holidays/business days between 2 days.
  100.  *      </li>
  101.  *      <li>
  102.  *          Calendars and Day counts; Available set of day count conventions and calendars, and the weekend
  103.  *              days corresponding to a given calendar.
  104.  *      </li>
  105.  *  </ul>
  106.  *
  107.  *  <br><br>
  108.  *  <ul>
  109.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ProductCore.md">Product Core Module</a></li>
  110.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics</a></li>
  111.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/analytics/README.md">Date, Cash Flow, and Cash Flow Period Measure Generation Utilities</a></li>
  112.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/analytics/daycount/README.md">Day Count Year Fraction Utilities</a></li>
  113.  *  </ul>
  114.  *
  115.  * @author Lakshmi Krishnamurthy
  116.  */

  117. public class Convention {

  118.     /**
  119.      * Date Roll Actual
  120.      */

  121.     public static final int DATE_ROLL_ACTUAL = 0;

  122.     /**
  123.      * Date Roll Following
  124.      */

  125.     public static final int DATE_ROLL_FOLLOWING = 1;

  126.     /**
  127.      * Date Roll Modified Following
  128.      */

  129.     public static final int DATE_ROLL_MODIFIED_FOLLOWING = 2;

  130.     /**
  131.      * Date Roll Modified Following Bi-monthly
  132.      */

  133.     public static final int DATE_ROLL_MODIFIED_FOLLOWING_BIMONTHLY = 4;

  134.     /**
  135.      * Date Roll Previous
  136.      */

  137.     public static final int DATE_ROLL_PREVIOUS = 8;

  138.     /**
  139.      * Date Roll Modified Previous
  140.      */

  141.     public static final int DATE_ROLL_MODIFIED_PREVIOUS = 16;

  142.     /**
  143.      * Week Day Holiday
  144.      */

  145.     public static final int WEEKDAY_HOLS = 1;

  146.     /**
  147.      * Week End Holiday
  148.      */

  149.     public static final int WEEKEND_HOLS = 2;

  150.     private static final int INIT_FROM_HOLS_DB = 1;
  151.     private static final int INIT_FROM_HOLS_XML = 2;
  152.     private static final int INIT_FROM_HOLS_SOURCE = 4;

  153.     private static int s_iInitHols = INIT_FROM_HOLS_SOURCE;
  154.     private static org.drip.analytics.support.CaseInsensitiveTreeMap<org.drip.analytics.eventday.Locale>
  155.         s_mapLocHols = null;

  156.     private static
  157.         org.drip.analytics.support.CaseInsensitiveTreeMap<org.drip.analytics.daycount.DCFCalculator>
  158.             s_mapDCCalc = new
  159.                 org.drip.analytics.support.CaseInsensitiveTreeMap<org.drip.analytics.daycount.DCFCalculator>();

  160.     private static final boolean UpdateDCCalcMap (
  161.         final org.drip.analytics.daycount.DCFCalculator dcfCalc)
  162.     {
  163.         for (java.lang.String strDC : dcfCalc.alternateNames())
  164.             s_mapDCCalc.put (strDC, dcfCalc);

  165.         return true;
  166.     }

  167.     private static final boolean SetDCCalc()
  168.     {
  169.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DC1_1())) return false;

  170.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DC28_360())) return false;

  171.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DC30_360())) return false;

  172.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DC30_365())) return false;

  173.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DC30_Act())) return false;

  174.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DC30E_360())) return false;

  175.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DC30E_360_ISDA())) return false;

  176.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DC30EPLUS_360_ISDA())) return false;

  177.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DCAct_360())) return false;

  178.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DCAct_364())) return false;

  179.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DCAct_365())) return false;

  180.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DCAct_365L())) return false;

  181.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DCAct_Act())) return false;

  182.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DCAct_Act_ISDA())) return false;

  183.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DCAct_Act_UST())) return false;

  184.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DCNL_360())) return false;

  185.         if (!UpdateDCCalcMap (new org.drip.analytics.daycount.DCNL_365())) return false;

  186.         return UpdateDCCalcMap (new org.drip.analytics.daycount.DCNL_Act());
  187.     }

  188.     private static final boolean AddLH (
  189.         final org.drip.analytics.holset.LocationHoliday lh,
  190.         final org.drip.analytics.support.CaseInsensitiveTreeMap<org.drip.analytics.eventday.Locale> mapHols)
  191.     {
  192.         if (null == lh || null == mapHols) return false;

  193.         java.lang.String strLocation = lh.getHolidayLoc();

  194.         org.drip.analytics.eventday.Locale locHols = lh.getHolidaySet();

  195.         if (null == locHols || null == strLocation || strLocation.isEmpty()) return false;

  196.         mapHols.put (strLocation, locHols);

  197.         return true;
  198.     }

  199.     private static final org.drip.analytics.support.CaseInsensitiveTreeMap<org.drip.analytics.eventday.Locale>
  200.         SetHolsFromSource()
  201.     {
  202.         org.drip.analytics.support.CaseInsensitiveTreeMap<org.drip.analytics.eventday.Locale> mapHols = new
  203.             org.drip.analytics.support.CaseInsensitiveTreeMap<org.drip.analytics.eventday.Locale>();

  204.         AddLH (new org.drip.analytics.holset.AEDHoliday(), mapHols);

  205.         AddLH (new org.drip.analytics.holset.ANGHoliday(), mapHols);

  206.         AddLH (new org.drip.analytics.holset.ARAHoliday(), mapHols);

  207.         AddLH (new org.drip.analytics.holset.ARFHoliday(), mapHols);

  208.         AddLH (new org.drip.analytics.holset.ARNHoliday(), mapHols);

  209.         AddLH (new org.drip.analytics.holset.ARPHoliday(), mapHols);

  210.         AddLH (new org.drip.analytics.holset.ARSHoliday(), mapHols);

  211.         AddLH (new org.drip.analytics.holset.ATSHoliday(), mapHols);

  212.         AddLH (new org.drip.analytics.holset.AUDHoliday(), mapHols);

  213.         AddLH (new org.drip.analytics.holset.AZMHoliday(), mapHols);

  214.         AddLH (new org.drip.analytics.holset.BAKHoliday(), mapHols);

  215.         AddLH (new org.drip.analytics.holset.BBDHoliday(), mapHols);

  216.         AddLH (new org.drip.analytics.holset.BEFHoliday(), mapHols);

  217.         AddLH (new org.drip.analytics.holset.BGLHoliday(), mapHols);

  218.         AddLH (new org.drip.analytics.holset.BHDHoliday(), mapHols);

  219.         AddLH (new org.drip.analytics.holset.BMDHoliday(), mapHols);

  220.         AddLH (new org.drip.analytics.holset.BRCHoliday(), mapHols);

  221.         AddLH (new org.drip.analytics.holset.BRLHoliday(), mapHols);

  222.         AddLH (new org.drip.analytics.holset.BSDHoliday(), mapHols);

  223.         AddLH (new org.drip.analytics.holset.CADHoliday(), mapHols);

  224.         AddLH (new org.drip.analytics.holset.CAEHoliday(), mapHols);

  225.         AddLH (new org.drip.analytics.holset.CERHoliday(), mapHols);

  226.         AddLH (new org.drip.analytics.holset.CFFHoliday(), mapHols);

  227.         AddLH (new org.drip.analytics.holset.CHFHoliday(), mapHols);

  228.         AddLH (new org.drip.analytics.holset.CLFHoliday(), mapHols);

  229.         AddLH (new org.drip.analytics.holset.CLUHoliday(), mapHols);

  230.         AddLH (new org.drip.analytics.holset.CNYHoliday(), mapHols);

  231.         AddLH (new org.drip.analytics.holset.COFHoliday(), mapHols);

  232.         AddLH (new org.drip.analytics.holset.CONHoliday(), mapHols);

  233.         AddLH (new org.drip.analytics.holset.COPHoliday(), mapHols);

  234.         AddLH (new org.drip.analytics.holset.CRCHoliday(), mapHols);

  235.         AddLH (new org.drip.analytics.holset.CYPHoliday(), mapHols);

  236.         AddLH (new org.drip.analytics.holset.CZKHoliday(), mapHols);

  237.         AddLH (new org.drip.analytics.holset.DEMHoliday(), mapHols);

  238.         AddLH (new org.drip.analytics.holset.DKKHoliday(), mapHols);

  239.         AddLH (new org.drip.analytics.holset.DOPHoliday(), mapHols);

  240.         AddLH (new org.drip.analytics.holset.DTFHoliday(), mapHols);

  241.         AddLH (new org.drip.analytics.holset.ECSHoliday(), mapHols);

  242.         AddLH (new org.drip.analytics.holset.EEKHoliday(), mapHols);

  243.         AddLH (new org.drip.analytics.holset.EGPHoliday(), mapHols);

  244.         AddLH (new org.drip.analytics.holset.ESBHoliday(), mapHols);

  245.         AddLH (new org.drip.analytics.holset.ESPHoliday(), mapHols);

  246.         AddLH (new org.drip.analytics.holset.ESTHoliday(), mapHols);

  247.         AddLH (new org.drip.analytics.holset.EUBHoliday(), mapHols);

  248.         AddLH (new org.drip.analytics.holset.EURHoliday(), mapHols);

  249.         AddLH (new org.drip.analytics.holset.GBPHoliday(), mapHols);

  250.         AddLH (new org.drip.analytics.holset.GELHoliday(), mapHols);

  251.         AddLH (new org.drip.analytics.holset.GFRHoliday(), mapHols);

  252.         AddLH (new org.drip.analytics.holset.GRDHoliday(), mapHols);

  253.         AddLH (new org.drip.analytics.holset.HKDHoliday(), mapHols);

  254.         AddLH (new org.drip.analytics.holset.HRKHoliday(), mapHols);

  255.         AddLH (new org.drip.analytics.holset.HUFHoliday(), mapHols);

  256.         AddLH (new org.drip.analytics.holset.IBRHoliday(), mapHols);

  257.         AddLH (new org.drip.analytics.holset.IDRHoliday(), mapHols);

  258.         AddLH (new org.drip.analytics.holset.IEPHoliday(), mapHols);

  259.         AddLH (new org.drip.analytics.holset.IGPHoliday(), mapHols);

  260.         AddLH (new org.drip.analytics.holset.ILSHoliday(), mapHols);

  261.         AddLH (new org.drip.analytics.holset.INRHoliday(), mapHols);

  262.         AddLH (new org.drip.analytics.holset.IPCHoliday(), mapHols);

  263.         AddLH (new org.drip.analytics.holset.ITLHoliday(), mapHols);

  264.         AddLH (new org.drip.analytics.holset.JMDHoliday(), mapHols);

  265.         AddLH (new org.drip.analytics.holset.JPYHoliday(), mapHols);

  266.         AddLH (new org.drip.analytics.holset.KPWHoliday(), mapHols);

  267.         AddLH (new org.drip.analytics.holset.KRWHoliday(), mapHols);

  268.         AddLH (new org.drip.analytics.holset.KWDHoliday(), mapHols);

  269.         AddLH (new org.drip.analytics.holset.KYDHoliday(), mapHols);

  270.         AddLH (new org.drip.analytics.holset.KZTHoliday(), mapHols);

  271.         AddLH (new org.drip.analytics.holset.LKRHoliday(), mapHols);

  272.         AddLH (new org.drip.analytics.holset.LTLHoliday(), mapHols);

  273.         AddLH (new org.drip.analytics.holset.LUFHoliday(), mapHols);

  274.         AddLH (new org.drip.analytics.holset.LUXHoliday(), mapHols);

  275.         AddLH (new org.drip.analytics.holset.LVLHoliday(), mapHols);

  276.         AddLH (new org.drip.analytics.holset.MDLHoliday(), mapHols);

  277.         AddLH (new org.drip.analytics.holset.MIXHoliday(), mapHols);

  278.         AddLH (new org.drip.analytics.holset.MKDHoliday(), mapHols);

  279.         AddLH (new org.drip.analytics.holset.MXCHoliday(), mapHols);

  280.         AddLH (new org.drip.analytics.holset.MXNHoliday(), mapHols);

  281.         AddLH (new org.drip.analytics.holset.MXPHoliday(), mapHols);

  282.         AddLH (new org.drip.analytics.holset.MXVHoliday(), mapHols);

  283.         AddLH (new org.drip.analytics.holset.MYRHoliday(), mapHols);

  284.         AddLH (new org.drip.analytics.holset.NLGHoliday(), mapHols);

  285.         AddLH (new org.drip.analytics.holset.NOKHoliday(), mapHols);

  286.         AddLH (new org.drip.analytics.holset.NZDHoliday(), mapHols);

  287.         AddLH (new org.drip.analytics.holset.PABHoliday(), mapHols);

  288.         AddLH (new org.drip.analytics.holset.PEFHoliday(), mapHols);

  289.         AddLH (new org.drip.analytics.holset.PENHoliday(), mapHols);

  290.         AddLH (new org.drip.analytics.holset.PESHoliday(), mapHols);

  291.         AddLH (new org.drip.analytics.holset.PHPHoliday(), mapHols);

  292.         AddLH (new org.drip.analytics.holset.PLNHoliday(), mapHols);

  293.         AddLH (new org.drip.analytics.holset.PLZHoliday(), mapHols);

  294.         AddLH (new org.drip.analytics.holset.PTEHoliday(), mapHols);

  295.         AddLH (new org.drip.analytics.holset.QEFHoliday(), mapHols);

  296.         AddLH (new org.drip.analytics.holset.RUBHoliday(), mapHols);

  297.         AddLH (new org.drip.analytics.holset.RURHoliday(), mapHols);

  298.         AddLH (new org.drip.analytics.holset.SARHoliday(), mapHols);

  299.         AddLH (new org.drip.analytics.holset.SEKHoliday(), mapHols);

  300.         AddLH (new org.drip.analytics.holset.SGDHoliday(), mapHols);

  301.         AddLH (new org.drip.analytics.holset.SITHoliday(), mapHols);

  302.         AddLH (new org.drip.analytics.holset.SKKHoliday(), mapHols);

  303.         AddLH (new org.drip.analytics.holset.SVCHoliday(), mapHols);

  304.         AddLH (new org.drip.analytics.holset.TABHoliday(), mapHols);

  305.         AddLH (new org.drip.analytics.holset.TGTHoliday(), mapHols);

  306.         AddLH (new org.drip.analytics.holset.THBHoliday(), mapHols);

  307.         AddLH (new org.drip.analytics.holset.TRLHoliday(), mapHols);

  308.         AddLH (new org.drip.analytics.holset.TRYHoliday(), mapHols);

  309.         AddLH (new org.drip.analytics.holset.TWDHoliday(), mapHols);

  310.         AddLH (new org.drip.analytics.holset.UAHHoliday(), mapHols);

  311.         AddLH (new org.drip.analytics.holset.USDHoliday(), mapHols);

  312.         AddLH (new org.drip.analytics.holset.USVHoliday(), mapHols);

  313.         AddLH (new org.drip.analytics.holset.UVRHoliday(), mapHols);

  314.         AddLH (new org.drip.analytics.holset.UYUHoliday(), mapHols);

  315.         AddLH (new org.drip.analytics.holset.UYUHoliday(), mapHols);

  316.         AddLH (new org.drip.analytics.holset.VACHoliday(), mapHols);

  317.         AddLH (new org.drip.analytics.holset.VEBHoliday(), mapHols);

  318.         AddLH (new org.drip.analytics.holset.VEFHoliday(), mapHols);

  319.         AddLH (new org.drip.analytics.holset.VNDHoliday(), mapHols);

  320.         AddLH (new org.drip.analytics.holset.XDRHoliday(), mapHols);

  321.         AddLH (new org.drip.analytics.holset.XEUHoliday(), mapHols);

  322.         AddLH (new org.drip.analytics.holset.ZALHoliday(), mapHols);

  323.         AddLH (new org.drip.analytics.holset.ZARHoliday(), mapHols);

  324.         AddLH (new org.drip.analytics.holset.ZUSHoliday(), mapHols);

  325.         AddLH (new org.drip.analytics.holset.ZWDHoliday(), mapHols);

  326.         return mapHols;
  327.     }

  328.     private static final boolean LocationHoliday (
  329.         final java.lang.String strCalendarSet,
  330.         final int iDate,
  331.         final int iHolType)
  332.     {
  333.         if (null == strCalendarSet || strCalendarSet.isEmpty() || 0 >= iDate) return false;

  334.         java.lang.String[] astrCalendars = strCalendarSet.split (",");

  335.         for (java.lang.String strCalendar : astrCalendars) {
  336.             if (null != strCalendar && null != s_mapLocHols.get (strCalendar)) {
  337.                 org.drip.analytics.eventday.Locale lh = s_mapLocHols.get (strCalendar);

  338.                 if (null == lh) continue;

  339.                 if (0 != (WEEKEND_HOLS & iHolType) && null != lh.weekendDays() && lh.weekendDays().isWeekend
  340.                     (iDate))
  341.                     return true;

  342.                 if (null == lh.holidays() || 0 == (WEEKDAY_HOLS & iHolType)) continue;

  343.                 for (org.drip.analytics.eventday.Base hol : lh.holidays()) {
  344.                     try {
  345.                         if (null != hol && iDate == hol.dateInYear (org.drip.analytics.date.DateUtil.Year
  346.                             (iDate), true))
  347.                             return true;
  348.                     } catch (java.lang.Exception e) {
  349.                         e.printStackTrace();
  350.                     }
  351.                 }
  352.             }
  353.         }

  354.         return false;
  355.     }

  356.     /**
  357.      * Initialize the day count basis object from the calendar set
  358.      *
  359.      * @param strCalendarSetLoc The calendar set
  360.      *
  361.      * @return Success (true) Failure (false)
  362.      */

  363.     public static final boolean Init (
  364.         final java.lang.String strCalendarSetLoc)
  365.     {
  366.         if (null != s_mapLocHols) return true;

  367.         if (!SetDCCalc()) return false;

  368.         if (INIT_FROM_HOLS_SOURCE == s_iInitHols) {
  369.             if (null == (s_mapLocHols = SetHolsFromSource())) return false;

  370.             return true;
  371.         }

  372.         try {
  373.             if (INIT_FROM_HOLS_XML == s_iInitHols)
  374.                 s_mapLocHols = org.drip.param.config.ConfigLoader.LoadHolidayCalendars (strCalendarSetLoc);
  375.             else if (INIT_FROM_HOLS_DB == s_iInitHols)
  376.                 s_mapLocHols = org.drip.param.config.ConfigLoader.LoadHolidayCalendarsFromDB
  377.                     (strCalendarSetLoc);

  378.             return true;
  379.         } catch (java.lang.Exception e) {
  380.             e.printStackTrace();
  381.         }

  382.         if (null == s_mapLocHols && null == (s_mapLocHols = SetHolsFromSource()))  return false;

  383.         return false;
  384.     }

  385.     /**
  386.      * Retrieve the set of holiday locations
  387.      *
  388.      * @return Set of holiday locations
  389.      */

  390.     public static final java.util.Set<java.lang.String> HolidayLocations()
  391.     {
  392.         return s_mapLocHols.keySet();
  393.     }

  394.     /**
  395.      * Get the week end days for the given holiday calendar set
  396.      *
  397.      * @param strCalendarSet Holiday calendar set
  398.      *
  399.      * @return Array of days indicating the week day union
  400.      */

  401.     public static final int[] WeekendDays (
  402.         final java.lang.String strCalendarSet)
  403.     {
  404.         if (null == strCalendarSet || strCalendarSet.isEmpty()) return null;

  405.         java.lang.String[] astrCalendars = strCalendarSet.split (",");

  406.         java.util.Set<java.lang.Integer> si = new java.util.HashSet<java.lang.Integer>();

  407.         for (java.lang.String strCalendar : astrCalendars) {
  408.             if (null != strCalendar && null != s_mapLocHols.get (strCalendar)) {
  409.                 org.drip.analytics.eventday.Locale lh = s_mapLocHols.get (strCalendar);

  410.                 if (null == lh || null == lh.weekendDays() || null == lh.weekendDays().days()) continue;

  411.                 for (int i : lh.weekendDays().days())
  412.                     si.add (i);
  413.             }
  414.         }

  415.         int j = 0;

  416.         int[] aiWkend = new int[si.size()];

  417.         for (int iHol : si)
  418.             aiWkend[j++] = iHol;

  419.         return aiWkend;
  420.     }

  421.     /**
  422.      * Get all available DRIP day count conventions
  423.      *
  424.      * @return Available DRIP day count conventions
  425.      */

  426.     public static final java.lang.String AvailableDC()
  427.     {
  428.         java.lang.StringBuffer sbDCSet = new java.lang.StringBuffer();

  429.         for (java.lang.String strDC : s_mapDCCalc.keySet())
  430.             sbDCSet.append (strDC + " | ");

  431.         return sbDCSet.toString();
  432.     }

  433.     /**
  434.      * Calculate the Accrual Fraction in Years between 2 given Dates for the given Day Count Convention and
  435.      *  the other Parameters
  436.      *
  437.      * @param iStartDate Start Date
  438.      * @param iEndDate End Date
  439.      * @param strDayCount Day Count Convention
  440.      * @param bApplyEOMAdj Apply End-of-Month Adjustment (TRUE)
  441.      * @param actactParams ActActParams
  442.      * @param strCalendar Holiday Calendar
  443.      *
  444.      * @return Accrual Fraction in Years
  445.      *
  446.      * @throws java.lang.Exception Thrown if the Accrual Fraction cannot be calculated
  447.      */

  448.     public static final double YearFraction (
  449.         final int iStartDate,
  450.         final int iEndDate,
  451.         final java.lang.String strDayCount,
  452.         final boolean bApplyEOMAdj,
  453.         final ActActDCParams actactParams,
  454.         final java.lang.String strCalendar)
  455.         throws java.lang.Exception
  456.     {
  457.         if ("BUS252".equalsIgnoreCase (strDayCount) || "BUS DAYS252".equalsIgnoreCase (strDayCount) ||
  458.             "BUS/252".equalsIgnoreCase (strDayCount))
  459.             return BusinessDays (iStartDate, iEndDate, strCalendar) / 252.;

  460.         org.drip.analytics.daycount.DCFCalculator dcfCalc = s_mapDCCalc.get (strDayCount);

  461.         if (null != dcfCalc)
  462.             return dcfCalc.yearFraction (iStartDate, iEndDate, bApplyEOMAdj, actactParams, strCalendar);

  463.         System.out.println ("Convention::YearFraction => Unknown DC: " + strDayCount +
  464.             "; defaulting to Actual/365.25");

  465.         return 1. * (iEndDate - iStartDate) / 365.25;
  466.     }

  467.     /**
  468.      * Calculate the Days Accrued between 2 given Dates for the given Day Count Convention and the other
  469.      *  Parameters
  470.      *
  471.      * @param iStartDate Start Date
  472.      * @param iEndDate End Date
  473.      * @param strDayCount Day Count Convention
  474.      * @param bApplyEOMAdj Apply End-of-Month Adjustment (TRUE)
  475.      * @param actactParams ActActParams
  476.      * @param strCalendar Holiday Calendar
  477.      *
  478.      * @return Number of Days Accrued
  479.      *
  480.      * @throws java.lang.Exception Thrown if the Accrual Days cannot be calculated
  481.      */

  482.     public static final int DaysAccrued (
  483.         final int iStartDate,
  484.         final int iEndDate,
  485.         final java.lang.String strDayCount,
  486.         final boolean bApplyEOMAdj,
  487.         final ActActDCParams actactParams,
  488.         final java.lang.String strCalendar)
  489.         throws java.lang.Exception
  490.     {
  491.         if ("BUS252".equalsIgnoreCase (strDayCount) || "BUS DAYS252".equalsIgnoreCase (strDayCount) ||
  492.             "BUS/252".equalsIgnoreCase (strDayCount))
  493.             return BusinessDays (iStartDate, iEndDate, strCalendar);

  494.         org.drip.analytics.daycount.DCFCalculator dcfCalc = s_mapDCCalc.get (strDayCount);

  495.         if (null != dcfCalc)
  496.             return dcfCalc.daysAccrued (iStartDate, iEndDate, bApplyEOMAdj, actactParams, strCalendar);

  497.         return iEndDate - iStartDate;
  498.     }

  499.     /**
  500.      * Roll the given Date in accordance with the Roll Mode and the Calendar Set
  501.      *
  502.      * @param iDate Date to be Rolled
  503.      * @param iRollMode Roll Mode (one of DR_ACT, DR_FOLL, DR_MOD_FOLL, DR_PREV, or DR_MOD_PREV)
  504.      * @param strCalendarSet Calendar Set to calculate the Holidays by
  505.      * @param iNumDaysToRoll The Number of Days to Roll
  506.      *
  507.      * @return The Rolled Date
  508.      *
  509.      * @throws java.lang.Exception Thrown if the date cannot be rolled
  510.      */

  511.     public static final int RollDate (
  512.         final int iDate,
  513.         final int iRollMode,
  514.         final java.lang.String strCalendarSet,
  515.         int iNumDaysToRoll)
  516.         throws java.lang.Exception
  517.     {
  518.         if (0 > iNumDaysToRoll) throw new java.lang.Exception ("Convention::RollDate => Invalid Inputs");

  519.         if (null == strCalendarSet || strCalendarSet.isEmpty() || DATE_ROLL_ACTUAL == iRollMode)
  520.             return iDate + iNumDaysToRoll;

  521.         int iRolledDate = iDate;

  522.         if (0 == iNumDaysToRoll) {
  523.             if (DATE_ROLL_FOLLOWING == iRollMode || DATE_ROLL_MODIFIED_FOLLOWING == iRollMode ||
  524.                 DATE_ROLL_MODIFIED_FOLLOWING_BIMONTHLY == iRollMode) {
  525.                 while (IsHoliday (iRolledDate, strCalendarSet))
  526.                     ++iRolledDate;
  527.             } else if (DATE_ROLL_PREVIOUS == iRollMode || DATE_ROLL_MODIFIED_PREVIOUS == iRollMode) {
  528.                 while (IsHoliday (iRolledDate, strCalendarSet))
  529.                     --iRolledDate;
  530.             }
  531.         } else {
  532.             while (0 != iNumDaysToRoll) {
  533.                 if (DATE_ROLL_FOLLOWING == iRollMode || DATE_ROLL_MODIFIED_FOLLOWING == iRollMode ||
  534.                     DATE_ROLL_MODIFIED_FOLLOWING_BIMONTHLY == iRollMode) {
  535.                     while (IsHoliday (iRolledDate, strCalendarSet))
  536.                         ++iRolledDate;
  537.                 } else if (DATE_ROLL_PREVIOUS == iRollMode || DATE_ROLL_MODIFIED_PREVIOUS == iRollMode) {
  538.                     while (IsHoliday (iRolledDate, strCalendarSet))
  539.                         --iRolledDate;
  540.                 }

  541.                 --iNumDaysToRoll;
  542.             }
  543.         }

  544.         if (DATE_ROLL_MODIFIED_FOLLOWING == iRollMode) {
  545.             if (org.drip.analytics.date.DateUtil.Month (iDate) != org.drip.analytics.date.DateUtil.Month
  546.                 (iRolledDate)) {
  547.                 while (IsHoliday (iRolledDate, strCalendarSet))
  548.                     --iRolledDate;
  549.             }
  550.         }

  551.         if (DATE_ROLL_MODIFIED_FOLLOWING_BIMONTHLY == iRollMode) {
  552.             int iOriginalDay = org.drip.analytics.date.DateUtil.Date (iDate);

  553.             int iRolledDay = org.drip.analytics.date.DateUtil.Date (iRolledDate);

  554.             if ((15 < iOriginalDay && 15 > iRolledDay) || (15 > iOriginalDay && 15 < iRolledDay)) {
  555.                 while (IsHoliday (iRolledDate, strCalendarSet))
  556.                     --iRolledDate;
  557.             }
  558.         }

  559.         if (DATE_ROLL_MODIFIED_PREVIOUS == iRollMode) {
  560.             if (org.drip.analytics.date.DateUtil.Month (iDate) != org.drip.analytics.date.DateUtil.Month
  561.                 (iRolledDate)) {
  562.                 while (IsHoliday (iRolledDate, strCalendarSet))
  563.                     ++iRolledDate;
  564.             }
  565.         }

  566.         return iRolledDate;
  567.     }

  568.     /**
  569.      * Indicate whether the given Date is a Holiday in the specified Location(s)
  570.      *
  571.      * @param iDate Date
  572.      * @param strCalendar Location Calendar Set
  573.      * @param iHolType WEEKDAY_HOLS or WEEKEND_HOLS
  574.      *
  575.      * @return TRUE - it is a Holiday
  576.      */

  577.     public static final boolean IsHoliday (
  578.         final int iDate,
  579.         final java.lang.String strCalendar,
  580.         final int iHolType)
  581.     {
  582.         return LocationHoliday ((null == strCalendar || strCalendar.isEmpty() || "".equalsIgnoreCase
  583.             (strCalendar)) ? "USD" : strCalendar, iDate, iHolType);
  584.     }

  585.     /**
  586.      * Indicates whether the given Date is a Holiday in the specified Location(s)
  587.      *
  588.      * @param iDate Date
  589.      * @param strCalendar Location Calendar Set
  590.      *
  591.      * @return TRUE - it is a Holiday
  592.      */

  593.     public static final boolean IsHoliday (
  594.         final int iDate,
  595.         final java.lang.String strCalendar)
  596.     {
  597.         return IsHoliday (iDate, strCalendar, WEEKDAY_HOLS | WEEKEND_HOLS);
  598.     }

  599.     /**
  600.      * Calculate the Number of Business Days between the Start and the End Dates
  601.      *
  602.      * @param iStartDate Start Date
  603.      * @param iEndDate End Date
  604.      * @param strCalendar Holiday Calendar Set
  605.      *
  606.      * @return The Number of Business Days
  607.      *
  608.      * @throws java.lang.Exception Thrown if it cannot be evaluated
  609.      */

  610.     public static final int BusinessDays (
  611.         final int iStartDate,
  612.         final int iEndDate,
  613.         final java.lang.String strCalendar)
  614.         throws java.lang.Exception
  615.     {
  616.         if (iStartDate > iEndDate)
  617.             throw new java.lang.Exception ("Convention::BusinessDays => Invalid Inputs");

  618.         if (iStartDate == iEndDate) return 0;

  619.         int iNumBusDays = 0;
  620.         int iDate = iStartDate + 1;

  621.         while (iDate <= iEndDate) {
  622.             if (!IsHoliday (iDate, strCalendar)) ++iNumBusDays;

  623.             ++iDate;
  624.         }

  625.         return iNumBusDays;
  626.     }

  627.     /**
  628.      * Calculate the Set of Holidays between the Start and the End Dates
  629.      *
  630.      * @param iStartDate Start Date
  631.      * @param iEndDate End Date
  632.      * @param strCalendar Holiday Calendar Set
  633.      *
  634.      * @return The Set of Holidays
  635.      */

  636.     public static final java.util.List<java.lang.Integer> HolidaySet (
  637.         final int iStartDate,
  638.         final int iEndDate,
  639.         final java.lang.String strCalendar)
  640.     {
  641.         java.util.List<java.lang.Integer> lsHolidays = new java.util.ArrayList<java.lang.Integer>();

  642.         int iLastDate = iEndDate;
  643.         int iFirstDate = iStartDate;

  644.         if (iFirstDate > iLastDate) {
  645.             iLastDate = iStartDate;
  646.             iFirstDate = iEndDate;
  647.         }

  648.         while (iFirstDate != iLastDate) {
  649.             try {
  650.                 if (IsHoliday (iFirstDate, strCalendar)) lsHolidays.add (iFirstDate);

  651.                 ++iFirstDate;
  652.             } catch (java.lang.Exception e) {
  653.                 e.printStackTrace();
  654.             }
  655.         }

  656.         return lsHolidays;
  657.     }

  658.     /**
  659.      * Calculate the Number of Holidays between the Start and the End Dates
  660.      *
  661.      * @param iStartDate Start Date
  662.      * @param iEndDate End Date
  663.      * @param strCalendar Holiday Calendar Set
  664.      *
  665.      * @return The Number of Holidays
  666.      */

  667.     public static final int Holidays (
  668.         final int iStartDate,
  669.         final int iEndDate,
  670.         final java.lang.String strCalendar)
  671.     {
  672.         int iNumHolidays = 0;
  673.         int iLastDate = iEndDate;
  674.         int iFirstDate = iStartDate;

  675.         if (iFirstDate > iLastDate) {
  676.             iLastDate = iStartDate;
  677.             iFirstDate = iEndDate;
  678.         }

  679.         while (iFirstDate != iLastDate) {
  680.             if (IsHoliday (iFirstDate++, strCalendar)) ++iNumHolidays;
  681.         }

  682.         return iStartDate > iEndDate ? -1 * iNumHolidays : iNumHolidays;
  683.     }

  684.     /**
  685.      * Adjust the given Date in Accordance with the Adjustment Mode and the Calendar Set
  686.      *
  687.      * @param iDate Date to be Adjusted
  688.      * @param strCalendar Calendar Set to calculate the Holidays by
  689.      * @param iAdjustMode Adjustment Mode (one of DR_ACT, DR_FOLL, DR_MOD_FOLL, DR_PREV, or DR_MOD_PREV
  690.      *
  691.      * @return The Adjusted Date
  692.      */

  693.     public static final int Adjust (
  694.         final int iDate,
  695.         final java.lang.String strCalendar,
  696.         final int iAdjustMode)
  697.     {
  698.         int iDateAdjusted = iDate;

  699.         while (IsHoliday (iDateAdjusted, strCalendar)) ++iDateAdjusted;

  700.         return iDateAdjusted;
  701.     }

  702.     /**
  703.      * Add the specified Number of Business Days and Adjust According to the Calendar Set
  704.      *
  705.      * @param iDate Date to be Adjusted
  706.      * @param iNumDays Number of Days to Add
  707.      * @param strCalendar Calendar Set to calculate the Holidays by
  708.      *
  709.      * @return The Adjusted Date
  710.      */

  711.     public static final int AddBusinessDays (
  712.         final int iDate,
  713.         final int iNumDays,
  714.         final java.lang.String strCalendar)
  715.     {
  716.         int iAdjustedDate = iDate;
  717.         int iNumDaysIncremented = 0;

  718.         while (iNumDaysIncremented < iNumDays) {
  719.             iAdjustedDate = Adjust (iAdjustedDate + 1, strCalendar, DATE_ROLL_FOLLOWING);

  720.             iNumDaysIncremented += 1;
  721.         }

  722.         return iAdjustedDate;
  723.     }
  724. }