From 9ab283aecff6ba9523f0538f1e5cae1febb4e851 Mon Sep 17 00:00:00 2001 From: Lakshmi Krishnamurthy Date: Mon, 25 Dec 2023 09:23:55 -0500 Subject: [PATCH] Features: - State Curve Basis Spline Forward Rate - Constructor (1, 2) - State Curve Basis Spline Forward Rate (3, 4, 5) - State Curve Basis Spline Forward Rate - Jack D Manifest Measure (6) - State Curve Basis Spline FX Forward #1 (7, 8) - State Curve Basis Spline FX Forward - Span (9) - State Curve Basis Spline FX Forward - Spot (10, 11) - State Curve Basis Spline FX Forward - Node (12, 13, 14) - State Curve Basis Spline FX Forward - Constructor (15, 16, 17) - State Curve Basis Spline FX Forward #2 (18, 19, 20) - State Curve Basis Spline FX Forward - Zero (21, 22, 23) - State Curve Basis Spline FX Forward - Bootstrap (24, 25, 26) - State Curve Basis Spline FX Forward - Implied Node Rates (27, 28, 29) - State Curve Basis Spline FX Forward - Bootstrap Discount Curve (30, 31, 32) - State Curve Basis Spline FX Forward #3 (33, 34, 35) - State Curve Basis Spline FX Forward - Jack D Manifest Measure (36, 37) - State Curve Basis Spline Govvie Yield (38, 39, 40) - State Curve Basis Spline Govvie Yield - Span (41) - State Curve Basis Spline Govvie Yield - Constructor (42, 43) - State Curve Basis Spline Govvie Yield - Yld (44, 45, 46) - State Curve Basis Spline Govvie Yield - Jack D Forward Manifest Measure (47) - State Curve Basis Spline Govvie Yield - Flat Forward Discount (48) - State Curve Basis Spline Govvie Yield - Flat Forward (49, 50, 51) - State Curve Basis Spline Market Surface (52, 53) - State Curve Basis Spline Market Surface - Wire Stretch (54) - State Curve Basis Spline Market Surface - Constructor (55, 56, 57) - State Curve Basis Spline Market Surface - Node (58) - State Curve Basis Spline Market Surface - x Anchor Term Structure (59, 60) Bug Fixes/Re-organization: Samples: IdeaDRIP: --- ReleaseNotes/03_01_2023.txt | 37 ++ ScheduleSheet.xlsx | Bin 49246 -> 49262 bytes .../state/curve/BasisSplineFXForward.java | 340 +++++++++++------- .../state/curve/BasisSplineForwardRate.java | 41 ++- .../state/curve/BasisSplineGovvieYield.java | 116 +++--- .../state/curve/BasisSplineMarketSurface.java | 83 +++-- 6 files changed, 396 insertions(+), 221 deletions(-) create mode 100644 ReleaseNotes/03_01_2023.txt diff --git a/ReleaseNotes/03_01_2023.txt b/ReleaseNotes/03_01_2023.txt new file mode 100644 index 000000000000..64a8f8466a8b --- /dev/null +++ b/ReleaseNotes/03_01_2023.txt @@ -0,0 +1,37 @@ + +Features: + + - State Curve Basis Spline Forward Rate - Constructor (1, 2) + - State Curve Basis Spline Forward Rate (3, 4, 5) + - State Curve Basis Spline Forward Rate - Jack D Manifest Measure (6) + - State Curve Basis Spline FX Forward #1 (7, 8) + - State Curve Basis Spline FX Forward - Span (9) + - State Curve Basis Spline FX Forward - Spot (10, 11) + - State Curve Basis Spline FX Forward - Node (12, 13, 14) + - State Curve Basis Spline FX Forward - Constructor (15, 16, 17) + - State Curve Basis Spline FX Forward #2 (18, 19, 20) + - State Curve Basis Spline FX Forward - Zero (21, 22, 23) + - State Curve Basis Spline FX Forward - Bootstrap (24, 25, 26) + - State Curve Basis Spline FX Forward - Implied Node Rates (27, 28, 29) + - State Curve Basis Spline FX Forward - Bootstrap Discount Curve (30, 31, 32) + - State Curve Basis Spline FX Forward #3 (33, 34, 35) + - State Curve Basis Spline FX Forward - Jack D Manifest Measure (36, 37) + - State Curve Basis Spline Govvie Yield (38, 39, 40) + - State Curve Basis Spline Govvie Yield - Span (41) + - State Curve Basis Spline Govvie Yield - Constructor (42, 43) + - State Curve Basis Spline Govvie Yield - Yld (44, 45, 46) + - State Curve Basis Spline Govvie Yield - Jack D Forward Manifest Measure (47) + - State Curve Basis Spline Govvie Yield - Flat Forward Discount (48) + - State Curve Basis Spline Govvie Yield - Flat Forward (49, 50, 51) + - State Curve Basis Spline Market Surface (52, 53) + - State Curve Basis Spline Market Surface - Wire Stretch (54) + - State Curve Basis Spline Market Surface - Constructor (55, 56, 57) + - State Curve Basis Spline Market Surface - Node (58) + - State Curve Basis Spline Market Surface - x Anchor Term Structure (59, 60) + + +Bug Fixes/Re-organization: + +Samples: + +IdeaDRIP: diff --git a/ScheduleSheet.xlsx b/ScheduleSheet.xlsx index d53336ea41cdec7991235d4777e3ccda63fbaf19..b7d5b18101516308fc2979d493695a686dcd3c50 100644 GIT binary patch delta 14441 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 bRY#Bi1G!%(gRh7bt>+-VS_6Kr3Ge>_c5wVY delta 14420 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 diff --git a/src/main/java/org/drip/state/curve/BasisSplineFXForward.java b/src/main/java/org/drip/state/curve/BasisSplineFXForward.java index a3705f1b8661..8136752f8a6b 100644 --- a/src/main/java/org/drip/state/curve/BasisSplineFXForward.java +++ b/src/main/java/org/drip/state/curve/BasisSplineFXForward.java @@ -1,11 +1,25 @@ package org.drip.state.curve; +import org.drip.analytics.date.JulianDate; +import org.drip.numerical.differentiation.WengertJacobian; +import org.drip.param.valuation.ValuationParams; +import org.drip.product.fx.FXForwardComponent; +import org.drip.product.params.CurrencyPair; +import org.drip.service.common.StringUtil; +import org.drip.spline.grid.Span; +import org.drip.state.creator.ScenarioDiscountCurveBuilder; +import org.drip.state.discount.MergedDiscountForwardCurve; +import org.drip.state.fx.FXCurve; + /* * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /*! + * Copyright (C) 2025 Lakshmi Krishnamurthy + * Copyright (C) 2024 Lakshmi Krishnamurthy + * Copyright (C) 2023 Lakshmi Krishnamurthy * Copyright (C) 2022 Lakshmi Krishnamurthy * Copyright (C) 2021 Lakshmi Krishnamurthy * Copyright (C) 2020 Lakshmi Krishnamurthy @@ -83,72 +97,96 @@ /** * BasisSplineFXForward manages the Basis Latent State, using the Basis as the State Response - * Representation. + * Representation. It exports the following functionality: * - *

* - *

+ * + *
+ * + * + * + * + * + * + * + *
Module Product Core Module
Library Fixed Income Analytics
Project Latent State Inference and Creation Utilities
Package Basis Spline Based Latent States
* * @author Lakshmi Krishnamurthy */ -public class BasisSplineFXForward extends org.drip.state.fx.FXCurve { - private org.drip.spline.grid.Span _span = null; - private double _dblFXSpot = java.lang.Double.NaN; +public class BasisSplineFXForward extends FXCurve +{ + private Span _span = null; + private double _fxSpot = Double.NaN; private double nodeBasis ( - final int iNodeDate, - final org.drip.param.valuation.ValuationParams valParam, - final org.drip.state.discount.MergedDiscountForwardCurve dcNum, - final org.drip.state.discount.MergedDiscountForwardCurve dcDenom, - final boolean bBasisOnDenom) - throws java.lang.Exception + final int nodeDate, + final ValuationParams valuationParams, + final MergedDiscountForwardCurve numeratorDiscountCurve, + final MergedDiscountForwardCurve denominatorDiscountCurve, + final boolean basisOnDenominator) + throws Exception { - return new org.drip.product.fx.FXForwardComponent ("FXFWD_" + - org.drip.service.common.StringUtil.GUID(), currencyPair(), epoch().julian(), iNodeDate, 1., - null).discountCurveBasis (valParam, dcNum, dcDenom, _dblFXSpot, fx (iNodeDate), - bBasisOnDenom); + return new FXForwardComponent ( + "FXFWD_" + StringUtil.GUID(), + currencyPair(), + epoch().julian(), + nodeDate, + 1., + null + ).discountCurveBasis ( + valuationParams, + numeratorDiscountCurve, + denominatorDiscountCurve, + _fxSpot, + fx (nodeDate), + basisOnDenominator + ); } /** * BasisSplineFXForward constructor * - * @param cp The Currency Pair + * @param currencyPair The Currency Pair * @param span The Span over which the Basis Representation is valid * - * @throws java.lang.Exception Thrown if the Inputs are Invalid + * @throws Exception Thrown if the Inputs are Invalid */ public BasisSplineFXForward ( - final org.drip.product.params.CurrencyPair cp, - final org.drip.spline.grid.Span span) - throws java.lang.Exception + final CurrencyPair currencyPair, + final Span span) + throws Exception { - super ((int) span.left(), cp); + super ((int) span.left(), currencyPair); - _span = span; - - _dblFXSpot = _span.calcResponseValue (_span.left()); + _fxSpot = (_span = span).calcResponseValue (_span.left()); } @Override public double fx ( - final int iDate) - throws java.lang.Exception + final int date) + throws Exception { - double dblSpanLeft = _span.left(); + double spanLeft = _span.left(); - if (iDate <= dblSpanLeft) return _span.calcResponseValue (dblSpanLeft); + if (date <= spanLeft) { + return _span.calcResponseValue (spanLeft); + } - double dblSpanRight = _span.right(); + double spanRight = _span.right(); - if (iDate >= dblSpanRight) return _span.calcResponseValue (dblSpanRight); + if (date >= spanRight) { + return _span.calcResponseValue (spanRight); + } - return _span.calcResponseValue (iDate); + return _span.calcResponseValue (date); } /** @@ -159,130 +197,172 @@ public BasisSplineFXForward ( public double fxSpot() { - return _dblFXSpot; + return _fxSpot; } @Override public double[] zeroBasis ( - final int[] aiDateNode, - final org.drip.param.valuation.ValuationParams valParams, - final org.drip.state.discount.MergedDiscountForwardCurve dcNum, - final org.drip.state.discount.MergedDiscountForwardCurve dcDenom, - final boolean bBasisOnDenom) + final int[] nodeDateArray, + final ValuationParams valuationParams, + final MergedDiscountForwardCurve numeratorDiscountCurve, + final MergedDiscountForwardCurve denominatorDiscountCurve, + final boolean basisOnDenominator) { - if (null == aiDateNode) return null; + if (null == nodeDateArray) { + return null; + } - int iNumBasis = aiDateNode.length; - double[] adblBasis = new double[iNumBasis]; + int nodeCount = nodeDateArray.length; + double[] basisArray = new double[nodeCount]; - if (0 == iNumBasis) return null; + if (0 == nodeCount) { + return null; + } - for (int i = 0; i < iNumBasis; ++i) { + for (int nodeIndex = 0; nodeIndex < nodeCount; ++nodeIndex) { try { - adblBasis[i] = nodeBasis (aiDateNode[i], valParams, dcNum, dcDenom, bBasisOnDenom); - } catch (java.lang.Exception e) { + basisArray[nodeIndex] = nodeBasis ( + nodeDateArray[nodeIndex], + valuationParams, + numeratorDiscountCurve, + denominatorDiscountCurve, + basisOnDenominator + ); + } catch (Exception e) { e.printStackTrace(); return null; } } - return adblBasis; + return basisArray; } @Override public double[] bootstrapBasis ( - final int[] aiDateNode, - final org.drip.param.valuation.ValuationParams valParams, - final org.drip.state.discount.MergedDiscountForwardCurve dcNum, - final org.drip.state.discount.MergedDiscountForwardCurve dcDenom, - final boolean bBasisOnDenom) + final int[] nodeDateArray, + final ValuationParams valuationParams, + final MergedDiscountForwardCurve numeratorDiscountCurve, + final MergedDiscountForwardCurve denominatorDiscountCurve, + final boolean basisOnDenominator) { - if (null == aiDateNode) return null; + if (null == nodeDateArray) { + return null; + } - int iNumBasis = aiDateNode.length; - double[] adblBasis = new double[iNumBasis]; - org.drip.state.discount.MergedDiscountForwardCurve dcBasis = bBasisOnDenom ? dcDenom : dcNum; + int nodeCount = nodeDateArray.length; + double[] basisArray = new double[nodeCount]; + MergedDiscountForwardCurve basisDiscountCurve = basisOnDenominator ? denominatorDiscountCurve : + numeratorDiscountCurve; - if (0 == iNumBasis || null == dcBasis) return null; + if (0 == nodeCount || null == basisDiscountCurve) { + return null; + } - for (int i = 0; i < iNumBasis; ++i) { + for (int nodeIndex = 0; nodeIndex < nodeCount; ++nodeIndex) { try { - if (bBasisOnDenom) - adblBasis[i] = nodeBasis (aiDateNode[i], valParams, dcNum, dcBasis, true); - else - adblBasis[i] = nodeBasis (aiDateNode[i], valParams, dcBasis, dcDenom, false); - } catch (java.lang.Exception e) { + basisArray[nodeIndex] = nodeBasis ( + nodeDateArray[nodeIndex], + valuationParams, + basisOnDenominator ? numeratorDiscountCurve : basisDiscountCurve, + basisOnDenominator ? basisDiscountCurve : denominatorDiscountCurve, + true + ); + } catch (Exception e) { e.printStackTrace(); return null; } } - return adblBasis; + return basisArray; } @Override public double[] impliedNodeRates ( - final int[] aiDateNode, - final org.drip.param.valuation.ValuationParams valParams, - final org.drip.state.discount.MergedDiscountForwardCurve dcNum, - final org.drip.state.discount.MergedDiscountForwardCurve dcDenom, - final boolean bBasisOnDenom) + final int[] nodeDateArray, + final ValuationParams valuationParams, + final MergedDiscountForwardCurve numeratorDiscountCurve, + final MergedDiscountForwardCurve denominatorDiscountCurve, + final boolean basisOnDenominator) { - if (null == aiDateNode) return null; + if (null == nodeDateArray) { + return null; + } - int iNumBasis = aiDateNode.length; - double[] adblImpliedNodeRate = new double[iNumBasis]; + int nodeCount = nodeDateArray.length; + double[] impliedNodeRateArray = new double[nodeCount]; - if (0 == iNumBasis) return null; + if (0 == nodeCount) { + return null; + } - for (int i = 0; i < iNumBasis; ++i) { + for (int nodeIndex = 0; nodeIndex < nodeCount; ++nodeIndex) { try { - double dblBaseImpliedRate = java.lang.Double.NaN; - - if (bBasisOnDenom) - dblBaseImpliedRate = dcNum.zero (aiDateNode[i]); - else - dblBaseImpliedRate = dcDenom.zero (aiDateNode[i]); - - adblImpliedNodeRate[i] = dblBaseImpliedRate + nodeBasis (i, valParams, dcNum, dcDenom, - bBasisOnDenom); - } catch (java.lang.Exception e) { + impliedNodeRateArray[nodeIndex] = ( + basisOnDenominator ? numeratorDiscountCurve.zero (nodeDateArray[nodeIndex]) : + denominatorDiscountCurve.zero (nodeDateArray[nodeIndex]) + ) + nodeBasis ( + nodeIndex, + valuationParams, + numeratorDiscountCurve, + denominatorDiscountCurve, + basisOnDenominator + ); + } catch (Exception e) { e.printStackTrace(); } } - return adblImpliedNodeRate; + return impliedNodeRateArray; } - @Override public org.drip.state.discount.MergedDiscountForwardCurve bootstrapBasisDC ( - final int[] aiDateNode, - final org.drip.param.valuation.ValuationParams valParams, - final org.drip.state.discount.MergedDiscountForwardCurve dcNum, - final org.drip.state.discount.MergedDiscountForwardCurve dcDenom, - final boolean bBasisOnDenom) + @Override public MergedDiscountForwardCurve bootstrapBasisDC ( + final int[] nodeDateArray, + final ValuationParams valuationParams, + final MergedDiscountForwardCurve numeratorDiscountCurve, + final MergedDiscountForwardCurve denominatorDiscountCurve, + final boolean basisOnDenominator) { - double[] adblImpliedRate = impliedNodeRates (aiDateNode, valParams, dcNum, dcDenom, bBasisOnDenom); - - if (null == adblImpliedRate) return null; + double[] impliedRateArray = impliedNodeRates ( + nodeDateArray, + valuationParams, + numeratorDiscountCurve, + denominatorDiscountCurve, + basisOnDenominator + ); + + if (null == impliedRateArray) { + return null; + } - int iNumDF = adblImpliedRate.length; - double[] adblDF = new double[iNumDF]; - org.drip.state.discount.MergedDiscountForwardCurve dc = bBasisOnDenom ? dcDenom : dcNum; + int impliedRateArrayCount = impliedRateArray.length; + double[] discountFactorArray = new double[impliedRateArrayCount]; + MergedDiscountForwardCurve discountCurve = basisOnDenominator ? denominatorDiscountCurve : + numeratorDiscountCurve; - if (0 == iNumDF) return null; + if (0 == impliedRateArrayCount) { + return null; + } - int iSpotDate = valParams.valueDate(); + int spotDate = valuationParams.valueDate(); - java.lang.String strCurrency = dc.currency(); + String currency = discountCurve.currency(); - for (int i = 0; i < iNumDF; ++i) - adblDF[i] = java.lang.Math.exp (-1. * adblImpliedRate[i] * (aiDateNode[i] - iSpotDate) / - 365.25); + for (int impliedRateArrayIndex = 0; impliedRateArrayIndex < impliedRateArrayCount; + ++impliedRateArrayIndex) { + discountFactorArray[impliedRateArrayIndex] = Math.exp ( + -1. * impliedRateArray[impliedRateArrayIndex] * + (nodeDateArray[impliedRateArrayIndex] - spotDate) / 365.25 + ); + } try { - return org.drip.state.creator.ScenarioDiscountCurveBuilder.CubicPolynomialDiscountCurve - (strCurrency + "::BASIS", new org.drip.analytics.date.JulianDate (iSpotDate), strCurrency, - aiDateNode, adblDF); - } catch (java.lang.Exception e) { + return ScenarioDiscountCurveBuilder.CubicPolynomialDiscountCurve ( + currency + "::BASIS", + new JulianDate (spotDate), + currency, + nodeDateArray, + discountFactorArray + ); + } catch (Exception e) { e.printStackTrace(); } @@ -290,27 +370,33 @@ public double fxSpot() } @Override public double rate ( - final int[] aiDateNode, - final org.drip.param.valuation.ValuationParams valParams, - final org.drip.state.discount.MergedDiscountForwardCurve dcNum, - final org.drip.state.discount.MergedDiscountForwardCurve dcDenom, - final int iDate, - final boolean bBasisOnDenom) - throws java.lang.Exception + final int[] nodeDateArray, + final ValuationParams valuationParams, + final MergedDiscountForwardCurve numeratorDiscountCurve, + final MergedDiscountForwardCurve denominatorDiscountCurve, + final int date, + final boolean basisOnDenominator) + throws Exception { - org.drip.state.discount.MergedDiscountForwardCurve dcImplied = bootstrapBasisDC (aiDateNode, valParams, dcNum, - dcDenom, bBasisOnDenom); - - if (null == dcImplied) - throw new java.lang.Exception ("BasisSplineFXForward::rate: Cannot imply basis DC!"); + MergedDiscountForwardCurve impliedDiscountCurve = bootstrapBasisDC ( + nodeDateArray, + valuationParams, + numeratorDiscountCurve, + denominatorDiscountCurve, + basisOnDenominator + ); + + if (null == impliedDiscountCurve) { + throw new Exception ("BasisSplineFXForward::rate: Cannot imply basis DC!"); + } - return dcImplied.zero (iDate); + return impliedDiscountCurve.zero (date); } - @Override public org.drip.numerical.differentiation.WengertJacobian jackDForwardDManifestMeasure ( - final java.lang.String strManifestMeasure, - final int iDate) + @Override public WengertJacobian jackDForwardDManifestMeasure ( + final String manifestMeasure, + final int date) { - return _span.jackDResponseDManifestMeasure (strManifestMeasure, iDate, 1); + return _span.jackDResponseDManifestMeasure (manifestMeasure, date, 1); } } diff --git a/src/main/java/org/drip/state/curve/BasisSplineForwardRate.java b/src/main/java/org/drip/state/curve/BasisSplineForwardRate.java index a0ab97c26680..4c9348e215f7 100644 --- a/src/main/java/org/drip/state/curve/BasisSplineForwardRate.java +++ b/src/main/java/org/drip/state/curve/BasisSplineForwardRate.java @@ -1,8 +1,11 @@ package org.drip.state.curve; +import org.drip.numerical.differentiation.WengertJacobian; +import org.drip.spline.grid.OverlappingStretchSpan; import org.drip.spline.grid.Span; import org.drip.state.forward.ForwardCurve; +import org.drip.state.identifier.ForwardLabel; /* * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- @@ -121,41 +124,45 @@ public class BasisSplineForwardRate extends ForwardCurve { /** * BasisSplineForwardRate constructor * - * @param fri The Floating Rate Index + * @param forwardLabel The Floating Rate Index Forward Label * @param span The Span over which the Forward Rate Representation is valid * - * @throws java.lang.Exception Thrown if the Inputs are Invalid + * @throws Exception Thrown if the Inputs are Invalid */ public BasisSplineForwardRate ( - final org.drip.state.identifier.ForwardLabel fri, - final org.drip.spline.grid.OverlappingStretchSpan span) - throws java.lang.Exception + final ForwardLabel forwardLabel, + final OverlappingStretchSpan span) + throws Exception { - super ((int) span.left(), fri); + super ((int) span.left(), forwardLabel); _span = span; } @Override public double forward ( - final int iDate) - throws java.lang.Exception + final int date) + throws Exception { - double dblSpanLeft = _span.left(); + double spanLeft = _span.left(); - if (iDate <= dblSpanLeft) return _span.calcResponseValue (dblSpanLeft); + if (date <= spanLeft) { + return _span.calcResponseValue (spanLeft); + } - double dblSpanRight = _span.right(); + double spanRight = _span.right(); - if (iDate >= dblSpanRight) return _span.calcResponseValue (dblSpanRight); + if (date >= spanRight) { + return _span.calcResponseValue (spanRight); + } - return _span.calcResponseValue (iDate); + return _span.calcResponseValue (date); } - @Override public org.drip.numerical.differentiation.WengertJacobian jackDForwardDManifestMeasure ( - final java.lang.String strManifestMeasure, - final int iDate) + @Override public WengertJacobian jackDForwardDManifestMeasure ( + final String manifestMeasure, + final int date) { - return _span.jackDResponseDManifestMeasure (strManifestMeasure, iDate, 1); + return _span.jackDResponseDManifestMeasure (manifestMeasure, date, 1); } } diff --git a/src/main/java/org/drip/state/curve/BasisSplineGovvieYield.java b/src/main/java/org/drip/state/curve/BasisSplineGovvieYield.java index 2de84a90f041..afd88f9f9446 100644 --- a/src/main/java/org/drip/state/curve/BasisSplineGovvieYield.java +++ b/src/main/java/org/drip/state/curve/BasisSplineGovvieYield.java @@ -1,11 +1,20 @@ package org.drip.state.curve; +import org.drip.analytics.date.JulianDate; +import org.drip.numerical.differentiation.WengertJacobian; +import org.drip.spline.grid.Span; +import org.drip.state.govvie.GovvieCurve; +import org.drip.state.nonlinear.FlatForwardDiscountCurve; + /* * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /*! + * Copyright (C) 2025 Lakshmi Krishnamurthy + * Copyright (C) 2024 Lakshmi Krishnamurthy + * Copyright (C) 2023 Lakshmi Krishnamurthy * Copyright (C) 2022 Lakshmi Krishnamurthy * Copyright (C) 2021 Lakshmi Krishnamurthy * Copyright (C) 2020 Lakshmi Krishnamurthy @@ -83,108 +92,127 @@ /** * BasisSplineGovvieYield manages the Basis Spline Latent State, using the Basis as the State Response - * Representation, for the Govvie Curve with Yield Quantification Metric. + * Representation, for the Govvie Curve with Yield Quantification Metric. It exports the following + * functionality: * - *

* - *

+ * + *
+ * + * + * + * + * + * + * + *
Module Product Core Module
Library Fixed Income Analytics
Project Latent State Inference and Creation Utilities
Package Basis Spline Based Latent States
* * @author Lakshmi Krishnamurthy */ -public class BasisSplineGovvieYield extends org.drip.state.govvie.GovvieCurve { - private org.drip.spline.grid.Span _span = null; +public class BasisSplineGovvieYield extends GovvieCurve +{ + private Span _span = null; /** - * BasisSplineGovvieYield Constructor + * BasisSplineGovvieYield Constructor * - * @param strTreasuryCode Treasury Code - * @param strCurrency Currency + * @param treasuryCode Treasury Code + * @param currency Currency * @param span Govvie Curve Span * - * @throws java.lang.Exception Thrown if the Inputs are Invalid + * @throws Exception Thrown if the Inputs are Invalid */ public BasisSplineGovvieYield ( - final java.lang.String strTreasuryCode, - final java.lang.String strCurrency, - final org.drip.spline.grid.Span span) - throws java.lang.Exception + final String treasuryCode, + final String currency, + final Span span) + throws Exception { - super ((int) span.left(), strTreasuryCode, strCurrency); + super ((int) span.left(), treasuryCode, currency); _span = span; } @Override public double yld ( - final int iDate) - throws java.lang.Exception + final int date) + throws Exception { - double dblSpanLeft = _span.left(); + double spanLeft = _span.left(); - if (iDate <= dblSpanLeft) return _span.calcResponseValue (dblSpanLeft); + if (date <= spanLeft) { + return _span.calcResponseValue (spanLeft); + } - double dblSpanRight = _span.right(); + double spanRight = _span.right(); - if (iDate >= dblSpanRight) return _span.calcResponseValue (dblSpanRight); + if (date >= spanRight) { + return _span.calcResponseValue (spanRight); + } - return _span.calcResponseValue (iDate); + return _span.calcResponseValue (date); } - @Override public org.drip.numerical.differentiation.WengertJacobian jackDForwardDManifestMeasure ( - final java.lang.String strManifestMeasure, - final int iDate) + @Override public WengertJacobian jackDForwardDManifestMeasure ( + final String manifestMeasure, + final int date) { - return _span.jackDResponseDManifestMeasure (strManifestMeasure, iDate, 1); + return _span.jackDResponseDManifestMeasure (manifestMeasure, date, 1); } /** * Construct a Flat Forward Instance of the Curve at the specified Date Nodes * - * @param aiDate Array of Date Nodes + * @param dateArray Array of Date Nodes * * @return The Flat Forward Instance */ - public org.drip.state.nonlinear.FlatForwardDiscountCurve flatForward ( - final int[] aiDate) + public FlatForwardDiscountCurve flatForward ( + final int[] dateArray) { - return flatForward (dayCount(), freq(), aiDate); + return flatForward (dayCount(), freq(), dateArray); } /** * Construct a Flat Forward Instance of the Curve at the specified Date Node Tenors * - * @param astrTenor Array of Date Node Tenors + * @param tenorArray Array of Date Node Tenors * * @return The Flat Forward Instance */ - public org.drip.state.nonlinear.FlatForwardDiscountCurve flatForward ( - final java.lang.String[] astrTenor) + public FlatForwardDiscountCurve flatForward ( + final String[] tenorArray) { - if (null == astrTenor) return null; + if (null == tenorArray) { + return null; + } - int iNumTenor = astrTenor.length; - int[] aiDate = 0 == iNumTenor ? null : new int[iNumTenor]; + int tenorCount = tenorArray.length; + int[] dateArray = 0 == tenorCount ? null : new int[tenorCount]; - org.drip.analytics.date.JulianDate dtEpoch = epoch(); + JulianDate epochDate = epoch(); - for (int i = 0; i < iNumTenor; ++i) { + for (int tenorIndex = 0; tenorIndex < tenorCount; ++tenorIndex) { try { - aiDate[i] = dtEpoch.addTenor (astrTenor[i]).julian(); - } catch (java.lang.Exception e) { + dateArray[tenorIndex] = epochDate.addTenor (tenorArray[tenorIndex]).julian(); + } catch (Exception e) { e.printStackTrace(); return null; } } - return flatForward (dayCount(), freq(), aiDate); + return flatForward (dayCount(), freq(), dateArray); } } diff --git a/src/main/java/org/drip/state/curve/BasisSplineMarketSurface.java b/src/main/java/org/drip/state/curve/BasisSplineMarketSurface.java index c93079f4f00f..9fccaf0de989 100644 --- a/src/main/java/org/drip/state/curve/BasisSplineMarketSurface.java +++ b/src/main/java/org/drip/state/curve/BasisSplineMarketSurface.java @@ -1,11 +1,19 @@ package org.drip.state.curve; +import org.drip.analytics.definition.MarketSurface; +import org.drip.analytics.definition.NodeStructure; +import org.drip.spline.multidimensional.WireSurfaceStretch; +import org.drip.state.identifier.CustomLabel; + /* * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /*! + * Copyright (C) 2025 Lakshmi Krishnamurthy + * Copyright (C) 2024 Lakshmi Krishnamurthy + * Copyright (C) 2023 Lakshmi Krishnamurthy * Copyright (C) 2022 Lakshmi Krishnamurthy * Copyright (C) 2021 Lakshmi Krishnamurthy * Copyright (C) 2020 Lakshmi Krishnamurthy @@ -85,60 +93,69 @@ * BasisSplineMarketSurface implements the Market surface that holds the latent state Dynamics * parameters. * - *

- * - *

+ *
+ * + * + * + * + * + * + * + *
Module Product Core Module
Library Fixed Income Analytics
Project Latent State Inference and Creation Utilities
Package Basis Spline Based Latent States
* * @author Lakshmi Krishnamurthy */ -public class BasisSplineMarketSurface extends org.drip.analytics.definition.MarketSurface { - private org.drip.spline.multidimensional.WireSurfaceStretch _wss = null; +public class BasisSplineMarketSurface extends MarketSurface +{ + private WireSurfaceStretch _wireSurfaceStretch = null; /** * BasisSplineMarketSurface Constructor * - * @param iEpochDate The Starting Date - * @param label The Spline Market Surface Latent State Label - * @param strCurrency The Currency - * @param wss Wire Surface Stretch Instance + * @param epochDate The Starting Date + * @param customLabel The Spline Market Surface Latent State Label + * @param currency The Currency + * @param wireSurfaceStretch Wire Surface Stretch Instance * - * @throws java.lang.Exception Thrown if the Inputs are Invalid + * @throws Exception Thrown if the Inputs are Invalid */ public BasisSplineMarketSurface ( - final int iEpochDate, - final org.drip.state.identifier.CustomLabel label, - final java.lang.String strCurrency, - final org.drip.spline.multidimensional.WireSurfaceStretch wss) - throws java.lang.Exception + final int epochDate, + final CustomLabel customLabel, + final String currency, + final WireSurfaceStretch wireSurfaceStretch) + throws Exception { - super (iEpochDate, label, strCurrency); + super (epochDate, customLabel, currency); - _wss = wss; + _wireSurfaceStretch = wireSurfaceStretch; } @Override public double node ( - final double dblStrike, - final double dblDate) - throws java.lang.Exception + final double strike, + final double date) + throws Exception { - return _wss.responseValue (dblStrike, dblDate); + return _wireSurfaceStretch.responseValue (strike, date); } - @Override public org.drip.analytics.definition.NodeStructure xAnchorTermStructure ( - final double dblStrikeAnchor) + @Override public NodeStructure xAnchorTermStructure ( + final double strikeAnchor) { try { - return new BasisSplineTermStructure (epoch().julian(), - org.drip.state.identifier.CustomLabel.Standard (label() + "_" + dblStrikeAnchor), - currency(), _wss.wireSpanXAnchor (dblStrikeAnchor)); - } catch (java.lang.Exception e) { + return new BasisSplineTermStructure ( + epoch().julian(), + CustomLabel.Standard (label() + "_" + strikeAnchor), + currency(), + _wireSurfaceStretch.wireSpanXAnchor (strikeAnchor) + ); + } catch (Exception e) { e.printStackTrace(); } @@ -152,7 +169,7 @@ public BasisSplineMarketSurface ( return new BasisSplineTermStructure (epoch().julian(), org.drip.state.identifier.CustomLabel.Standard (label() + "_" + new org.drip.analytics.date.JulianDate ((int) dblMaturityDateAnchor)), currency(), - _wss.wireSpanYAnchor (dblMaturityDateAnchor)); + _wireSurfaceStretch.wireSpanYAnchor (dblMaturityDateAnchor)); } catch (java.lang.Exception e) { e.printStackTrace(); }