/// <summary> /// Get an indicative PPD for a given expiry/tenor pair /// If the pair is not in the grid use interpolation to derive the result /// </summary> /// <param name="expiryYF">The expiry as a Year Fraction</param> /// <param name="tenorYF">The tenor as a Year Fraction</param> /// <returns></returns> public decimal GetPPD(double expiryYF, double tenorYF)//TODO convert to newer version. { if (_interp == null) { if (ExtractTerms(out var expiry, out var tenor, out var values)) { _interp = new BilinearInterpolation(ref tenor, ref expiry, ref values); } } return((decimal)_interp.Interpolate(tenorYF, expiryYF)); }
///<summary> ///</summary> ///<param name="points"></param> ///<param name="expirationAsYearFraction"></param> ///<param name="strike"></param> ///<returns></returns> public static double GetValue(IEnumerable <PricingStructurePoint> points, double expirationAsYearFraction, double strike) { var pricingStructurePoints = points as PricingStructurePoint[] ?? points.ToArray(); var volatilityMatrix = GetExpirationByStikeVolatilityMatrix(pricingStructurePoints); var expirationVector = GetDimension1Vector(pricingStructurePoints, CubeDimension.Expiration); var expiryDoubleArray = ConvertArrayOfTimeDimensionsToDouble((TimeDimension[])expirationVector); var strikesVector = GetDimension1Vector(pricingStructurePoints, CubeDimension.Strike); var strikesDoubleArray = ConvertArrayOfDecimalsToDouble((decimal[])strikesVector); var doubleMatrix = ToDoubleMatrix(volatilityMatrix); var bilinearInterpolation = new BilinearInterpolation(ref strikesDoubleArray, ref expiryDoubleArray, ref doubleMatrix); var interpolatedValue = bilinearInterpolation.Interpolate(expirationAsYearFraction, strike); return(interpolatedValue); }
/// <summary> /// Compute a Bilinear interpolation at the ordered pair (ColumnTarget, RowTarget). /// Extrapolation is flat-line in both the Column and Row dimensions. /// </summary> /// <param name="columnLabels">One dimensional array arranged in strict ascending order that governs HORIZONTAL interpolation.</param> /// <param name="rowLabels">One dimensional array arranged in strict ascending order that governs VERTICAL interpolation.</param> /// <param name="dataTable">Two dimensional array of known values with size equal to RowLabels x ColumnLabels.</param> /// <param name="columnTarget">Column (horizontal) target of the interpolation.</param> /// <param name="rowTarget">Row (vertical) target of the interpolation.</param> /// <returns></returns> public double BilinearInterpolate(double[] columnLabels, double[] rowLabels, double[,] dataTable, double columnTarget, double rowTarget) { if (columnLabels == null) { return(0); } if (rowLabels == null) { return(0); } if (dataTable == null) { return(0); } var bil = new BilinearInterpolation(ref columnLabels, ref rowLabels, ref dataTable); return(bil.Interpolate(columnTarget, rowTarget)); }
public void TestInterpolate() { BilinearInterpolation interpObj = new BilinearInterpolation(ref _columnLabels, ref _rowLabels, ref _dataTable); Assert.IsNotNull(interpObj); // Test that the node points are recovered by the interpolation. _rowTarget = 38969; _columnTarget = 85 / 100.0; _expectedValue = 41.5 / 100.0; _actualValue = interpObj.Interpolate(_columnTarget, _rowTarget); Assert.AreEqual(_expectedValue, _actualValue); _rowTarget = 38969; _columnTarget = 90 / 100.0; _expectedValue = 30 / 100.0; _actualValue = interpObj.Interpolate(_columnTarget, _rowTarget); Assert.AreEqual(_expectedValue, _actualValue); _rowTarget = 38969; _columnTarget = 100 / 100.0; _expectedValue = 42.5 / 100.0; _actualValue = interpObj.Interpolate(_columnTarget, _rowTarget); Assert.AreEqual(_expectedValue, _actualValue); _rowTarget = 39524; _columnTarget = 85 / 100.0; _expectedValue = 20.25 / 100.0; _actualValue = interpObj.Interpolate(_columnTarget, _rowTarget); Assert.AreEqual(_expectedValue, _actualValue); _rowTarget = 39524; _columnTarget = 90 / 100.0; _expectedValue = 21.35 / 100.0; _actualValue = interpObj.Interpolate(_columnTarget, _rowTarget); Assert.AreEqual(_expectedValue, _actualValue); _rowTarget = 39524; _columnTarget = 100 / 100.0; _expectedValue = 22.8 / 100.0; _actualValue = interpObj.Interpolate(_columnTarget, _rowTarget); Assert.AreEqual(_expectedValue, _actualValue); // Test interpolation at points that do not coincide with // the node points. _rowTarget = 38969; _columnTarget = 70 / 100.0; _expectedValue = 41.5 / 100.0; _actualValue = interpObj.Interpolate(_columnTarget, _rowTarget); Assert.AreEqual(_expectedValue, _actualValue); _rowTarget = 38969; _columnTarget = 140 / 100.0; _expectedValue = 42.5 / 100.0; _actualValue = interpObj.Interpolate(_columnTarget, _rowTarget); Assert.AreEqual(_expectedValue, _actualValue); _rowTarget = 38735; _columnTarget = 90 / 100.0; _expectedValue = 30 / 100.0; _actualValue = interpObj.Interpolate(_columnTarget, _rowTarget); Assert.AreEqual(_expectedValue, _actualValue); _rowTarget = 39889; _columnTarget = 90 / 100.0; _expectedValue = 21.35 / 100.0; _actualValue = interpObj.Interpolate(_columnTarget, _rowTarget); Assert.AreEqual(_expectedValue, _actualValue); _rowTarget = 38969; _columnTarget = 87.5 / 100.0; _expectedValue = 35.75 / 100.0; _actualValue = interpObj.Interpolate(_columnTarget, _rowTarget); Assert.AreEqual(_expectedValue, _actualValue); _rowTarget = 39334; _columnTarget = 85.1 / 100.0; _expectedValue = 27.46 / 100.0; _actualValue = interpObj.Interpolate(_columnTarget, _rowTarget); const double tolerance = 1.0E-5; Assert.AreEqual(_expectedValue, _actualValue, tolerance); }