MergedDiscountForwardCurve.java
package org.drip.state.discount;
/*
* -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*/
/*!
* Copyright (C) 2020 Lakshmi Krishnamurthy
* Copyright (C) 2019 Lakshmi Krishnamurthy
* Copyright (C) 2018 Lakshmi Krishnamurthy
* Copyright (C) 2017 Lakshmi Krishnamurthy
* Copyright (C) 2016 Lakshmi Krishnamurthy
* Copyright (C) 2015 Lakshmi Krishnamurthy
* Copyright (C) 2014 Lakshmi Krishnamurthy
* Copyright (C) 2013 Lakshmi Krishnamurthy
*
* This file is part of DROP, an open-source library targeting analytics/risk, transaction cost analytics,
* asset liability management analytics, capital, exposure, and margin analytics, valuation adjustment
* analytics, and portfolio construction analytics within and across fixed income, credit, commodity,
* equity, FX, and structured products. It also includes auxiliary libraries for algorithm support,
* numerical analysis, numerical optimization, spline builder, model validation, statistical learning,
* and computational support.
*
* https://lakshmidrip.github.io/DROP/
*
* DROP is composed of three modules:
*
* - DROP Product Core - https://lakshmidrip.github.io/DROP-Product-Core/
* - DROP Portfolio Core - https://lakshmidrip.github.io/DROP-Portfolio-Core/
* - DROP Computational Core - https://lakshmidrip.github.io/DROP-Computational-Core/
*
* DROP Product Core implements libraries for the following:
* - Fixed Income Analytics
* - Loan Analytics
* - Transaction Cost Analytics
*
* DROP Portfolio Core implements libraries for the following:
* - Asset Allocation Analytics
* - Asset Liability Management Analytics
* - Capital Estimation Analytics
* - Exposure Analytics
* - Margin Analytics
* - XVA Analytics
*
* DROP Computational Core implements libraries for the following:
* - Algorithm Support
* - Computation Support
* - Function Analysis
* - Model Validation
* - Numerical Analysis
* - Numerical Optimizer
* - Spline Builder
* - Statistical Learning
*
* Documentation for DROP is Spread Over:
*
* - Main => https://lakshmidrip.github.io/DROP/
* - Wiki => https://github.com/lakshmiDRIP/DROP/wiki
* - GitHub => https://github.com/lakshmiDRIP/DROP
* - Repo Layout Taxonomy => https://github.com/lakshmiDRIP/DROP/blob/master/Taxonomy.md
* - Javadoc => https://lakshmidrip.github.io/DROP/Javadoc/index.html
* - Technical Specifications => https://github.com/lakshmiDRIP/DROP/tree/master/Docs/Internal
* - Release Versions => https://lakshmidrip.github.io/DROP/version.html
* - Community Credits => https://lakshmidrip.github.io/DROP/credits.html
* - Issues Catalog => https://github.com/lakshmiDRIP/DROP/issues
* - JUnit => https://lakshmidrip.github.io/DROP/junit/index.html
* - Jacoco => https://lakshmidrip.github.io/DROP/jacoco/index.html
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* <i>MergedDiscountForwardCurve</i> is the Stub for the Merged Discount and Forward Curve Functionality. It
* extends the both the Curve and the DiscountFactorEstimator instances by implementing their functions, and
* exposing the following:
*
* <br><br>
* <ul>
* <li>
* Forward Rate to a specific date/tenor, and effective rate between a date interval
* </li>
* <li>
* Discount Factor to a specific date/tenor, and effective discount factor between a date interval
* </li>
* <li>
* Zero Rate to a specific date/tenor
* </li>
* <li>
* Value Jacobian for Forward rate, discount factor, and zero rate
* </li>
* <li>
* Cross Jacobian between each of Forward rate, discount factor, and zero rate
* </li>
* <li>
* Quote Jacobian to Forward rate, discount factor, and zero rate
* </li>
* <li>
* QM (DF/Zero/Forward) to Quote Jacobian
* </li>
* <li>
* Latent State Quantification Metric, and the canonical truthness transformations
* </li>
* <li>
* Implied/embedded ForwardRateEstimator
* </li>
* <li>
* Turns set/unset/adjust
* </li>
* </ul>
*
* <br><br>
* <ul>
* <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ProductCore.md">Product Core Module</a></li>
* <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/FixedIncomeAnalyticsLibrary.md">Fixed Income Analytics</a></li>
* <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/state/README.md">Latent State Inference and Creation Utilities</a></li>
* <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/state/discount/README.md">Discount Curve Spline Latent State</a></li>
* </ul>
* <br><br>
*
* @author Lakshmi Krishnamurthy
*/
public abstract class MergedDiscountForwardCurve extends org.drip.state.discount.DiscountCurve {
private static final int NUM_DF_QUADRATURES = 5;
protected java.lang.String _strCurrency = "";
protected int _iEpochDate = java.lang.Integer.MIN_VALUE;
protected org.drip.state.discount.TurnListDiscountFactor _tldf = null;
protected org.drip.analytics.input.CurveConstructionInputSet _ccis = null;
protected MergedDiscountForwardCurve (
final int iEpochDate,
final java.lang.String strCurrency,
final org.drip.state.discount.TurnListDiscountFactor tldf)
throws java.lang.Exception
{
if (null == (_strCurrency = strCurrency) || _strCurrency.isEmpty() ||
!org.drip.numerical.common.NumberUtil.IsValid (_iEpochDate = iEpochDate))
throw new java.lang.Exception ("MergedDiscountForwardCurve ctr: Invalid Inputs");
_tldf = tldf;
}
@Override public org.drip.state.identifier.LatentStateLabel label()
{
return org.drip.state.identifier.FundingLabel.Standard (_strCurrency);
}
@Override public java.lang.String currency()
{
return _strCurrency;
}
@Override public org.drip.analytics.date.JulianDate epoch()
{
try {
return new org.drip.analytics.date.JulianDate (_iEpochDate);
} catch (java.lang.Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Set the Discount Curve Turns'
*
* @param tldf Turn List Discount Factor
*
* @return TRUE - Valid Turn List Discount Factor Set
*/
public boolean setTurns (
final org.drip.state.discount.TurnListDiscountFactor tldf)
{
return null != (_tldf = tldf);
}
/**
* Apply the Turns' DF Adjustment
*
* @param iStartDate Turn Start Date
* @param iFinishDate Turn Finish Date
*
* @return Turns' DF Adjustment
*
* @throws java.lang.Exception Thrown if the Inputs are invalid
*/
public double turnAdjust (
final int iStartDate,
final int iFinishDate)
throws java.lang.Exception
{
return null == _tldf ? 1. : _tldf.turnAdjust (iStartDate, iFinishDate);
}
/**
* Apply the Turns' DF Adjustment
*
* @param iFinishDate Turn Finish Date
*
* @return Turns' DF Adjustment
*
* @throws java.lang.Exception Thrown if the Inputs are invalid
*/
protected double turnAdjust (
final int iFinishDate)
throws java.lang.Exception
{
return turnAdjust (epoch().julian(), iFinishDate);
}
/**
* Construct the Native Forward Curve for the given Tenor from the Discount Curve
*
* @param strTenor The Tenor
*
* @return The Tenor-Native Forward Curve
*/
public org.drip.state.forward.ForwardCurve nativeForwardCurve (
final java.lang.String strTenor)
{
if (null == strTenor || strTenor.isEmpty()) return null;
try {
org.drip.state.forward.ForwardCurve fcNative = new org.drip.state.forward.ForwardCurve
(epoch().julian(), org.drip.state.identifier.ForwardLabel.Standard (_strCurrency + "-" +
strTenor)) {
@Override public double forward (
final int iDate)
throws java.lang.Exception
{
return forward (new org.drip.analytics.date.JulianDate (iDate));
}
@Override public double forward (
final org.drip.analytics.date.JulianDate dt)
throws java.lang.Exception
{
if (null == dt)
throw new java.lang.Exception
("MergedDiscountForwardCurve::nativeForwardCurve => Invalid Input");
return libor (dt.subtractTenor (strTenor).julian(), strTenor);
}
@Override public double forward (
final java.lang.String strTenor)
throws java.lang.Exception
{
if (null == strTenor || strTenor.isEmpty())
throw new java.lang.Exception
("MergedDiscountForwardCurve::nativeForwardCurve => Invalid Input");
return forward (epoch().addTenor (strTenor));
}
@Override public org.drip.numerical.differentiation.WengertJacobian jackDForwardDManifestMeasure (
final java.lang.String strManifestMeasure,
final int iDate)
{
return null;
}
};
return fcNative;
} catch (java.lang.Exception e) {
e.printStackTrace();
}
return null;
}
@Override public double df (
final org.drip.analytics.date.JulianDate dt)
throws java.lang.Exception
{
if (null == dt) throw new java.lang.Exception ("MergedDiscountForwardCurve::df got null for date");
return df (dt.julian());
}
@Override public double df (
final java.lang.String strTenor)
throws java.lang.Exception
{
if (null == strTenor || strTenor.isEmpty())
throw new java.lang.Exception ("MergedDiscountForwardCurve::df got bad tenor");
return df (epoch().addTenor (strTenor));
}
@Override public double effectiveDF (
final int iDate1,
final int iDate2)
throws java.lang.Exception
{
if (iDate1 == iDate2) return df (iDate1);
int iNumQuadratures = 0;
double dblEffectiveDF = 0.;
int iQuadratureWidth = (iDate2 - iDate1) / NUM_DF_QUADRATURES;
if (0 == iQuadratureWidth) iQuadratureWidth = 1;
for (int iDate = iDate1; iDate <= iDate2; iDate += iQuadratureWidth) {
++iNumQuadratures;
dblEffectiveDF += (df (iDate) + df (iDate + iQuadratureWidth));
}
return dblEffectiveDF / (2. * iNumQuadratures);
}
@Override public double effectiveDF (
final org.drip.analytics.date.JulianDate dt1,
final org.drip.analytics.date.JulianDate dt2)
throws java.lang.Exception
{
if (null == dt1 || null == dt2)
throw new java.lang.Exception ("MergedDiscountForwardCurve::effectiveDF => Got null for date");
return effectiveDF (dt1.julian(), dt2.julian());
}
@Override public double effectiveDF (
final java.lang.String strTenor1,
final java.lang.String strTenor2)
throws java.lang.Exception
{
if (null == strTenor1 || strTenor1.isEmpty() || null == strTenor2 || strTenor2.isEmpty())
throw new java.lang.Exception ("MergedDiscountForwardCurve::effectiveDF => Got bad tenor");
org.drip.analytics.date.JulianDate dtStart = epoch();
return effectiveDF (dtStart.addTenor (strTenor1), dtStart.addTenor (strTenor2));
}
/**
* Compute the Forward Rate between two Dates
*
* @param iDate1 First Date
* @param iDate2 Second Date
*
* @return The Forward Rate
*
* @throws java.lang.Exception Thrown if the Forward Rate cannot be calculated
*/
public abstract double forward (
final int iDate1,
final int iDate2)
throws java.lang.Exception;
/**
* Compute the Forward Rate between two Tenors
*
* @param strTenor1 Tenor Start
* @param strTenor2 Tenor End
*
* @return The Forward Rate
*
* @throws java.lang.Exception Thrown if the Forward Rate cannot be calculated
*/
public double forward (
final java.lang.String strTenor1,
final java.lang.String strTenor2)
throws java.lang.Exception
{
if (null == strTenor1 || strTenor1.isEmpty() || null == strTenor2 || strTenor2.isEmpty())
throw new java.lang.Exception ("MergedDiscountForwardCurve::forward => Invalid Date");
org.drip.analytics.date.JulianDate dtStart = epoch();
return forward (dtStart.addTenor (strTenor1).julian(), dtStart.addTenor (strTenor2).julian());
}
/**
* Calculate the implied rate to the given date
*
* @param iDate Date
*
* @return Implied rate
*
* @throws java.lang.Exception Thrown if the discount factor cannot be calculated
*/
public abstract double zero (
final int iDate)
throws java.lang.Exception;
/**
* Calculate the implied rate to the given tenor
*
* @param strTenor Tenor
*
* @return Implied rate
*
* @throws java.lang.Exception Thrown if the discount factor cannot be calculated
*/
public double zero (
final java.lang.String strTenor)
throws java.lang.Exception
{
if (null == strTenor || strTenor.isEmpty())
throw new java.lang.Exception ("MergedDiscountForwardCurve::zero => Invalid date");
org.drip.analytics.date.JulianDate dtStart = epoch();
return forward (dtStart.julian(), dtStart.addTenor (strTenor).julian());
}
/**
* Compute the LIBOR between 2 dates given the Day Count
*
* @param iDate1 First Date
* @param iDate2 Second Date
* @param dblDCF Day Count Fraction
*
* @return LIBOR
*
* @throws java.lang.Exception Thrown if the discount factor cannot be calculated
*/
public double libor (
final int iDate1,
final int iDate2,
final double dblDCF)
throws java.lang.Exception
{
if (iDate1 == iDate2 || !org.drip.numerical.common.NumberUtil.IsValid (dblDCF) || 0. == dblDCF)
throw new java.lang.Exception ("MergedDiscountForwardCurve::libor => Invalid input dates");
return ((df (iDate1) / df (iDate2)) - 1.) / dblDCF;
}
/**
* Compute the LIBOR between 2 dates
*
* @param iDate1 First Date
* @param iDate2 Second Date
*
* @return LIBOR
*
* @throws java.lang.Exception Thrown if the discount factor cannot be calculated
*/
public double libor (
final int iDate1,
final int iDate2)
throws java.lang.Exception
{
if (iDate1 == iDate2)
throw new java.lang.Exception ("MergedDiscountForwardCurve::libor => Invalid input dates");
return libor (iDate1, iDate2, org.drip.analytics.daycount.Convention.YearFraction (iDate1, iDate2,
"Act/360", false, null, ""));
}
/**
* Calculate the LIBOR to the given tenor at the specified date
*
* @param iStartDate Start Date
* @param strTenor Tenor
*
* @return LIBOR
*
* @throws java.lang.Exception Thrown if LIBOR cannot be calculated
*/
public double libor (
final int iStartDate,
final java.lang.String strTenor)
throws java.lang.Exception
{
if (!org.drip.numerical.common.NumberUtil.IsValid (iStartDate) || null == strTenor || strTenor.isEmpty())
throw new java.lang.Exception ("MergedDiscountForwardCurve::libor => Invalid Inputs");
return libor (iStartDate, new org.drip.analytics.date.JulianDate (iStartDate).addTenor
(strTenor).julian());
}
/**
* Calculate the LIBOR to the given tenor at the specified Julian Date
*
* @param dt Julian Date
* @param strTenor Tenor
*
* @return LIBOR
*
* @throws java.lang.Exception Thrown if LIBOR cannot be calculated
*/
public double libor (
final org.drip.analytics.date.JulianDate dt,
final java.lang.String strTenor)
throws java.lang.Exception
{
if (null == dt)
throw new java.lang.Exception ("MergedDiscountForwardCurve::libor => Invalid Inputs");
return libor (dt.julian(), strTenor);
}
/**
* Calculate the DV01 of the Par Swap that Matures at the given date
*
* @param iDate Date
*
* @return DV01 of the Par Swap that Matures at the given date
*
* @throws java.lang.Exception Thrown if DV01 cannot be calculated
*/
public double parSwapDV01 (
final int iDate)
throws java.lang.Exception
{
java.lang.String strCurrency = currency();
org.drip.analytics.date.JulianDate dtStart = epoch().addDays (2);
org.drip.param.period.UnitCouponAccrualSetting ucasFixed = new
org.drip.param.period.UnitCouponAccrualSetting (2, "Act/360", false, "Act/360", false,
strCurrency, true,
org.drip.analytics.support.CompositePeriodBuilder.ACCRUAL_COMPOUNDING_RULE_GEOMETRIC);
org.drip.param.period.ComposableFixedUnitSetting cfusFixed = new
org.drip.param.period.ComposableFixedUnitSetting ("6M",
org.drip.analytics.support.CompositePeriodBuilder.EDGE_DATE_SEQUENCE_REGULAR, null, 0., 0.,
strCurrency);
org.drip.param.period.CompositePeriodSetting cpsFixed = new
org.drip.param.period.CompositePeriodSetting (2, "6M", strCurrency, null, 1., null, null, null,
null);
java.util.List<java.lang.Integer> lsFixedStreamEdgeDate =
org.drip.analytics.support.CompositePeriodBuilder.BackwardEdgeDates (dtStart, new
org.drip.analytics.date.JulianDate (iDate), "6M", null,
org.drip.analytics.support.CompositePeriodBuilder.SHORT_STUB);
org.drip.product.rates.Stream fixedStream = new org.drip.product.rates.Stream
(org.drip.analytics.support.CompositePeriodBuilder.FixedCompositeUnit (lsFixedStreamEdgeDate,
cpsFixed, ucasFixed, cfusFixed));
org.drip.param.market.CurveSurfaceQuoteContainer csqs =
org.drip.param.creator.MarketParamsBuilder.Create (this, null, null, null, null, null, null,
null);
java.util.Map<java.lang.String, java.lang.Double> mapFixStream = fixedStream.value
(org.drip.param.valuation.ValuationParams.Spot (dtStart, 0, "",
org.drip.analytics.daycount.Convention.DATE_ROLL_ACTUAL), null, csqs, null);
return mapFixStream.get ("DV01");
}
/**
* Estimate the manifest measure value for the given date
*
* @param strManifestMeasure The Manifest Measure to be Estimated
* @param iDate Date
*
* @return The estimated calibrated measure value
*
* @throws java.lang.Exception Thrown if the estimated manifest measure cannot be computed
*/
public double estimateManifestMeasure (
final java.lang.String strManifestMeasure,
final int iDate)
throws java.lang.Exception
{
if (null == strManifestMeasure || strManifestMeasure.isEmpty())
throw new java.lang.Exception
("MergedDiscountForwardCurve::estimateManifestMeasure => Invalid input");
org.drip.product.definition.CalibratableComponent[] aCalibComp = calibComp();
if (null == aCalibComp)
throw new java.lang.Exception
("MergedDiscountForwardCurve::estimateManifestMeasure => Calib Components not available");
int iNumComponent = aCalibComp.length;
if (0 == iNumComponent)
throw new java.lang.Exception
("MergedDiscountForwardCurve::estimateManifestMeasure => Calib Components not available");
java.util.List<java.lang.Integer> lsDate = new java.util.ArrayList<java.lang.Integer>();
java.util.List<java.lang.Double> lsQuote = new java.util.ArrayList<java.lang.Double>();
for (int i = 0; i < iNumComponent; ++i) {
if (null == aCalibComp[i])
throw new java.lang.Exception
("MergedDiscountForwardCurve::estimateManifestMeasure => Cannot locate a component");
org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double> mapManifestMeasure =
manifestMeasure (aCalibComp[i].primaryCode());
if (mapManifestMeasure.containsKey (strManifestMeasure)) {
lsDate.add (aCalibComp[i].maturityDate().julian());
lsQuote.add (mapManifestMeasure.get (strManifestMeasure));
}
}
int iNumEstimationComponent = lsDate.size();
if (0 == iNumEstimationComponent)
throw new java.lang.Exception
("MergedDiscountForwardCurve::estimateManifestMeasure => Estimation Components not available");
int[] aiDate = new int[iNumEstimationComponent];
double[] adblQuote = new double[iNumEstimationComponent];
org.drip.spline.params.SegmentCustomBuilderControl[] aSBP = new
org.drip.spline.params.SegmentCustomBuilderControl[iNumEstimationComponent - 1];
if (1 == iNumEstimationComponent) return lsQuote.get (0);
org.drip.spline.params.SegmentCustomBuilderControl sbp = new
org.drip.spline.params.SegmentCustomBuilderControl
(org.drip.spline.stretch.MultiSegmentSequenceBuilder.BASIS_SPLINE_POLYNOMIAL, new
org.drip.spline.basis.PolynomialFunctionSetParams (4),
org.drip.spline.params.SegmentInelasticDesignControl.Create (2, 2), null, null);
for (int i = 0; i < iNumEstimationComponent; ++i) {
if (0 != i) aSBP[i - 1] = sbp;
aiDate[i] = lsDate.get (i);
adblQuote[i] = lsQuote.get (i);
}
org.drip.spline.stretch.MultiSegmentSequence regime =
org.drip.spline.stretch.MultiSegmentSequenceBuilder.CreateCalibratedStretchEstimator
("DISC_CURVE_REGIME", aiDate, adblQuote, aSBP, null,
org.drip.spline.stretch.BoundarySettings.NaturalStandard(),
org.drip.spline.stretch.MultiSegmentSequence.CALIBRATE);
if (null == regime)
throw new java.lang.Exception
("MergedDiscountForwardCurve::estimateManifestMeasure => Cannot create Spline Stretch");
double dblRegimeLeftExtreme = regime.getLeftPredictorOrdinateEdge();
if (iDate <= dblRegimeLeftExtreme) return regime.responseValue (dblRegimeLeftExtreme);
double dblRegimeRightExtreme = regime.getRightPredictorOrdinateEdge();
if (iDate >= dblRegimeRightExtreme) return regime.responseValue (dblRegimeRightExtreme);
return regime.responseValue (iDate);
}
/**
* Proxy the Manifest Measure Value using the Closest Node for the given Date
*
* @param strManifestMeasure The Manifest Measure to be Proxied
* @param iDate Date
*
* @return The Measure Value Proxy
*
* @throws java.lang.Exception Thrown if the Manifest Measure Proxy cannot be computed
*/
public double proxyManifestMeasure (
final java.lang.String strManifestMeasure,
final int iDate)
throws java.lang.Exception
{
if (null == strManifestMeasure || strManifestMeasure.isEmpty())
throw new java.lang.Exception
("MergedDiscountForwardCurve::proxyManifestMeasure => Invalid input");
org.drip.product.definition.CalibratableComponent[] aCalibComp = calibComp();
if (null == aCalibComp)
throw new java.lang.Exception
("MergedDiscountForwardCurve::proxyManifestMeasure => Calib Components not available");
int iNumComponent = aCalibComp.length;
if (0 == iNumComponent)
throw new java.lang.Exception
("MergedDiscountForwardCurve::proxyManifestMeasure => Calib Components not available");
java.util.List<java.lang.Integer> lsDate = new java.util.ArrayList<java.lang.Integer>();
java.util.List<java.lang.Double> lsQuote = new java.util.ArrayList<java.lang.Double>();
for (int i = 0; i < iNumComponent; ++i) {
if (null == aCalibComp[i])
throw new java.lang.Exception
("MergedDiscountForwardCurve::proxyManifestMeasure => Cannot locate a component");
org.drip.analytics.support.CaseInsensitiveTreeMap<java.lang.Double> mapManifestMeasure =
manifestMeasure (aCalibComp[i].primaryCode());
if (mapManifestMeasure.containsKey (strManifestMeasure)) {
lsDate.add (aCalibComp[i].maturityDate().julian());
lsQuote.add (mapManifestMeasure.get (strManifestMeasure));
}
}
int iNumEstimationComponent = lsDate.size();
if (0 == iNumEstimationComponent)
throw new java.lang.Exception
("MergedDiscountForwardCurve::proxyManifestMeasure => Estimation Components not available");
if (1 == iNumEstimationComponent) return lsQuote.get (0);
int iDatePrev = lsDate.get (0);
if (iDate <= iDatePrev) return lsQuote.get (0);
for (int i = 1; i < iNumEstimationComponent; ++i) {
int iDateCurr = lsDate.get (i);
if (iDatePrev <= iDate && iDate < iDateCurr)
return iDate - iDatePrev > iDateCurr - iDate ? lsQuote.get (i) : lsQuote.get (i - 1);
iDatePrev = iDateCurr;
}
return lsQuote.get (iNumEstimationComponent - 1);
}
@Override public boolean setCCIS (
final org.drip.analytics.input.CurveConstructionInputSet ccis)
{
if (null == ccis) return false;
_ccis = ccis;
return true;
}
/**
* Retrieve the Forward Curve that might be implied by the Latent State of this Discount Curve Instance
* corresponding to the specified Floating Rate Index
*
* @param iDate The Date
* @param fri The Floating Rate Index
*
* @return The Forward Curve Implied by the Discount Curve Latent State
*/
public abstract org.drip.state.forward.ForwardRateEstimator forwardRateEstimator (
final int iDate,
final org.drip.state.identifier.ForwardLabel fri);
/**
* Retrieve the Latent State Quantification Metric
*
* @return The Latent State Quantification Metric
*/
public abstract java.lang.String latentStateQuantificationMetric();
/**
* Retrieve the Manifest Measure Jacobian of the Discount Factor to the given date
*
* @param iDate Date
* @param strManifestMeasure Manifest Measure
*
* @return The Manifest Measure Jacobian of the Discount Factor to the given date
*/
public abstract org.drip.numerical.differentiation.WengertJacobian jackDDFDManifestMeasure (
final int iDate,
final java.lang.String strManifestMeasure);
/**
* Retrieve the Manifest Measure Jacobian of the Discount Factor to the given date
*
* @param dt Date
* @param strManifestMeasure Manifest Measure
*
* @return The Manifest Measure Jacobian of the Discount Factor to the given date
*/
public org.drip.numerical.differentiation.WengertJacobian jackDDFDManifestMeasure (
final org.drip.analytics.date.JulianDate dt,
final java.lang.String strManifestMeasure)
{
if (null == dt) return null;
return jackDDFDManifestMeasure (dt.julian(), strManifestMeasure);
}
/**
* Retrieve the Manifest Measure Jacobian of the Discount Factor to the date implied by the given Tenor
*
* @param strTenor Tenor
* @param strManifestMeasure Manifest Measure
*
* @return The Manifest Measure Jacobian of the Discount Factor to the date implied by the given Tenor
*/
public org.drip.numerical.differentiation.WengertJacobian jackDDFDManifestMeasure (
final java.lang.String strTenor,
final java.lang.String strManifestMeasure)
{
if (null == strTenor || strTenor.isEmpty()) return null;
try {
return jackDDFDManifestMeasure (epoch().addTenor (strTenor), strManifestMeasure);
} catch (java.lang.Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Calculate the Jacobian of PV at the given date to the Manifest Measure of each component in the
* calibration set to the DF
*
* @param iDate Date for which the Jacobian is needed
*
* @return The Jacobian
*/
public org.drip.numerical.differentiation.WengertJacobian compJackDPVDManifestMeasure (
final int iDate)
{
if (!org.drip.numerical.common.NumberUtil.IsValid (iDate)) return null;
org.drip.product.definition.CalibratableComponent[] aCalibComp = calibComp();
if (null == aCalibComp || 0 == aCalibComp.length) return null;
int iNumParameters = 0;
int iNumComponents = aCalibComp.length;
org.drip.numerical.differentiation.WengertJacobian wjCompPVDF = null;
org.drip.param.valuation.ValuationParams valParams = org.drip.param.valuation.ValuationParams.Spot
(iDate);
org.drip.param.market.CurveSurfaceQuoteContainer csqs =
org.drip.param.creator.MarketParamsBuilder.Create (this, null, null, null, null, null,
null, null == _ccis ? null : _ccis.fixing());
for (int i = 0; i < iNumComponents; ++i) {
org.drip.numerical.differentiation.WengertJacobian wjCompDDirtyPVDManifestMeasure =
aCalibComp[i].jackDDirtyPVDManifestMeasure (valParams, null, csqs, null);
if (null == wjCompDDirtyPVDManifestMeasure) return null;
iNumParameters = wjCompDDirtyPVDManifestMeasure.numParameters();
if (null == wjCompPVDF) {
try {
wjCompPVDF = new org.drip.numerical.differentiation.WengertJacobian (iNumComponents,
iNumParameters);
} catch (java.lang.Exception e) {
e.printStackTrace();
return null;
}
}
for (int k = 0; k < iNumParameters; ++k) {
if (!wjCompPVDF.accumulatePartialFirstDerivative (i, k,
wjCompDDirtyPVDManifestMeasure.firstDerivative (0, k)))
return null;
}
}
return wjCompPVDF;
}
/**
* Calculate the Jacobian of PV at the given date to the Manifest Measure of each component in the
* calibration set to the DF
*
* @param dt Date for which the Jacobian is needed
*
* @return The Jacobian
*/
public org.drip.numerical.differentiation.WengertJacobian compJackDPVDManifestMeasure (
final org.drip.analytics.date.JulianDate dt)
{
return null == dt ? null : compJackDPVDManifestMeasure (dt.julian());
}
/**
* Retrieve the Jacobian of the Forward Rate to the Manifest Measure between the given dates
*
* @param iDate1 Date 1
* @param iDate2 Date 2
* @param strManifestMeasure Manifest Measure
* @param dblElapsedYear The Elapsed Year (in the appropriate Day Count) between dates 1 and 2
*
* @return The Jacobian
*/
public org.drip.numerical.differentiation.WengertJacobian jackDForwardDManifestMeasure (
final int iDate1,
final int iDate2,
final java.lang.String strManifestMeasure,
final double dblElapsedYear)
{
if (iDate1 == iDate2) return null;
org.drip.numerical.differentiation.WengertJacobian wjDDFDManifestMeasureDate1 = jackDDFDManifestMeasure
(iDate1, strManifestMeasure);
if (null == wjDDFDManifestMeasureDate1) return null;
int iNumQuote = wjDDFDManifestMeasureDate1.numParameters();
if (0 == iNumQuote) return null;
org.drip.numerical.differentiation.WengertJacobian wjDDFDManifestMeasureDate2 = jackDDFDManifestMeasure
(iDate2, strManifestMeasure);
if (null == wjDDFDManifestMeasureDate2 || iNumQuote != wjDDFDManifestMeasureDate2.numParameters())
return null;
double dblDF1 = java.lang.Double.NaN;
double dblDF2 = java.lang.Double.NaN;
org.drip.numerical.differentiation.WengertJacobian wjDForwardDManifestMeasure = null;
try {
dblDF1 = df (iDate1);
dblDF2 = df (iDate2);
wjDForwardDManifestMeasure = new org.drip.numerical.differentiation.WengertJacobian (1, iNumQuote);
} catch (java.lang.Exception e) {
e.printStackTrace();
return null;
}
double dblDForwardDManifestMeasure1iScale = 1. / dblDF2;
double dblDForwardDManifestMeasure2iScale = dblDF1 / (dblDF2 * dblDF2);
double dblInverseAnnualizedTenorLength = 1. / dblElapsedYear;
for (int i = 0; i < iNumQuote; ++i) {
double dblDForwardDQManifestMeasurei = ((wjDDFDManifestMeasureDate1.firstDerivative (0, i) *
dblDForwardDManifestMeasure1iScale) - (wjDDFDManifestMeasureDate2.firstDerivative (0, i) *
dblDForwardDManifestMeasure2iScale)) * dblInverseAnnualizedTenorLength;
if (!wjDForwardDManifestMeasure.accumulatePartialFirstDerivative (0, i,
dblDForwardDQManifestMeasurei))
return null;
}
return wjDForwardDManifestMeasure;
}
/**
* Retrieve the Jacobian of the Forward Rate to the Manifest Measure between the given dates
*
* @param dt1 Julian Date 1
* @param dt2 Julian Date 2
* @param strManifestMeasure Manifest Measure
* @param dblElapsedYear The Elapsed Year (in the appropriate Day Count) between dates 1 and 2
*
* @return The Jacobian
*/
public org.drip.numerical.differentiation.WengertJacobian jackDForwardDManifestMeasure (
final org.drip.analytics.date.JulianDate dt1,
final org.drip.analytics.date.JulianDate dt2,
final java.lang.String strManifestMeasure,
final double dblElapsedYear)
{
if (null == dt1 || null == dt2) return null;
return jackDForwardDManifestMeasure (dt1.julian(), dt2.julian(), strManifestMeasure, dblElapsedYear);
}
/**
* Retrieve the Jacobian of the Forward Rate to the Manifest Measure at the given date
*
* @param dt Given Julian Date
* @param strTenor Tenor
* @param strManifestMeasure Manifest Measure
* @param dblElapsedYear The Elapsed Year (in the appropriate Day Count) implied by the Tenor
*
* @return The Jacobian
*/
public org.drip.numerical.differentiation.WengertJacobian jackDForwardDManifestMeasure (
final org.drip.analytics.date.JulianDate dt,
final java.lang.String strTenor,
final java.lang.String strManifestMeasure,
final double dblElapsedYear)
{
if (null == dt || null == strTenor || strTenor.isEmpty()) return null;
return jackDForwardDManifestMeasure (dt.julian(), dt.addTenor (strTenor).julian(),
strManifestMeasure, dblElapsedYear);
}
/**
* Retrieve the Jacobian for the Zero Rate to the given date
*
* @param iDate Date
* @param strManifestMeasure Manifest Measure
*
* @return The Jacobian
*/
public org.drip.numerical.differentiation.WengertJacobian zeroRateJack (
final int iDate,
final java.lang.String strManifestMeasure)
{
int iEpochDate = epoch().julian();
return jackDForwardDManifestMeasure (iEpochDate, iDate, strManifestMeasure, 1. * (iDate - iEpochDate) /
365.25);
}
/**
* Retrieve the Jacobian for the Zero Rate to the given date
*
* @param dt Julian Date
* @param strManifestMeasure Manifest Measure
*
* @return The Jacobian
*/
public org.drip.numerical.differentiation.WengertJacobian zeroRateJack (
final org.drip.analytics.date.JulianDate dt,
final java.lang.String strManifestMeasure)
{
return null == dt? null : zeroRateJack (dt.julian(), strManifestMeasure);
}
/**
* Convert the inferred Formulation Constraint into a "Truthness" Entity
*
* @param strLatentStateQuantificationMetric Latent State Quantification Metric
*
* @return Map of the Truthness Entities
*/
public java.util.Map<java.lang.Integer, java.lang.Double> canonicalTruthness (
final java.lang.String strLatentStateQuantificationMetric)
{
if (null == strLatentStateQuantificationMetric ||
(!org.drip.analytics.definition.LatentStateStatic.DISCOUNT_QM_ZERO_RATE.equalsIgnoreCase
(strLatentStateQuantificationMetric) && !
org.drip.analytics.definition.LatentStateStatic.DISCOUNT_QM_DISCOUNT_FACTOR.equalsIgnoreCase
(strLatentStateQuantificationMetric)))
return null;
org.drip.product.definition.CalibratableComponent[] aCC = calibComp();
if (null == aCC) return null;
int iNumComp = aCC.length;
boolean bFirstCashFlow = true;
if (0 == iNumComp) return null;
java.util.Map<java.lang.Integer, java.lang.Double> mapCanonicalTruthness = new
java.util.TreeMap<java.lang.Integer, java.lang.Double>();
if (org.drip.analytics.definition.LatentStateStatic.DISCOUNT_QM_DISCOUNT_FACTOR.equalsIgnoreCase
(strLatentStateQuantificationMetric))
mapCanonicalTruthness.put (_iEpochDate, 1.);
for (org.drip.product.definition.CalibratableComponent cc : aCC) {
if (null == cc) continue;
java.util.List<org.drip.analytics.cashflow.CompositePeriod> lsCouponPeriod = cc.couponPeriods();
if (null == lsCouponPeriod || 0 == lsCouponPeriod.size()) continue;
for (org.drip.analytics.cashflow.CompositePeriod cpnPeriod : lsCouponPeriod) {
if (null == cpnPeriod) continue;
int iPeriodPayDate = cpnPeriod.payDate();
if (iPeriodPayDate >= _iEpochDate) {
try {
if (org.drip.analytics.definition.LatentStateStatic.DISCOUNT_QM_DISCOUNT_FACTOR.equalsIgnoreCase
(strLatentStateQuantificationMetric))
mapCanonicalTruthness.put (iPeriodPayDate, df (iPeriodPayDate));
else if (org.drip.analytics.definition.LatentStateStatic.DISCOUNT_QM_ZERO_RATE.equalsIgnoreCase
(strLatentStateQuantificationMetric)) {
if (bFirstCashFlow) {
bFirstCashFlow = false;
mapCanonicalTruthness.put (_iEpochDate, zero (iPeriodPayDate));
}
mapCanonicalTruthness.put (iPeriodPayDate, zero (iPeriodPayDate));
}
} catch (java.lang.Exception e) {
e.printStackTrace();
return null;
}
}
}
}
return mapCanonicalTruthness;
}
}