/// <summary> /// Main ctor. /// </summary> /// <param name="discreteSurface">The discrete surface ie 2 dimensional.</param> /// <param name="forwards">The forwards to be used for calibration.</param> /// <param name="xInterpolation">The basic interpolation to be applied to the x axis.</param> /// <param name="yInterpolation">The interpolation type for the y axis</param> /// <param name="allowExtrapolation">Not implemented in EO.</param> protected ExtendedInterpolatedSurface(DiscreteSurface discreteSurface, ParametricAdjustmentPoint[] forwards, IInterpolation xInterpolation, IInterpolation yInterpolation, bool allowExtrapolation) : base(discreteSurface, xInterpolation, yInterpolation, allowExtrapolation) { var values = discreteSurface.GetMatrixOfValues(); var x = discreteSurface.XArray; var width = values.ColumnCount; if (forwards != null) { SpotValue = (double)forwards[0].parameterValue; var length = forwards.Length; var fwds = new double[length - 1]; for (var index = 1; index < length; index++) { fwds[index - 1] = (double)forwards[index].parameterValue; } var fwdcurve = new LinearInterpolation(); fwdcurve.Initialize(x, fwds); ForwardCurve = fwdcurve; } if (yInterpolation.GetType() == typeof(SABRModelInterpolation)) { var y = discreteSurface.YArray; var length = values.RowCount; for (int i = 0; i < length; i++) { //interpolate each maturity first (in strike) with SABR var yinterp = (SABRModelInterpolation)yInterpolation.Clone(); yinterp.ExpiryTime = x[i]; if (Forward != null && Spot != null) { yinterp.AssetPrice = Convert.ToDecimal(Forward); } else { var fwd = ForwardCurve.ValueAt(yinterp.ExpiryTime, true); yinterp.AssetPrice = Convert.ToDecimal(fwd); } yinterp.Initialize(y, values.Row(i).Data); var curve = new DiscreteCurve(y, values.Row(i).Data); var interpolatedCol = new InterpolatedCurve(curve, yinterp, true); _interpolatedColumns.Add(interpolatedCol); } } else //o.w interpolate at each strike point (in time) { for (int i = 0; i < width; i++) { var interp = xInterpolation.Clone(); interp.Initialize(x, values.Column(i).Data); var curve = new DiscreteCurve(x, values.Column(i).Data); var interpolatedCol = new InterpolatedCurve(curve, interp, true); _interpolatedColumns.Add(interpolatedCol); } } }
/// <summary> /// Main ctor. /// </summary> /// <param name="columns">The column values.</param> /// <param name="forwards">An array of forwards to the expiry dates. The length of this array is + 1, as the first element is the spot value.</param> /// <param name="values">The discrete surface ie 2 dimensional.</param> /// <param name="xInterpolation">The basic interpolation to be applied to the x axis.</param> /// <param name="yInterpolation">The basic interpolation to be applied to the y axis.</param> /// <param name="rows">The row values.</param> public ExtendedInterpolatedSurface(double[] rows, double[] columns, double[] forwards, Matrix values, IInterpolation xInterpolation, IInterpolation yInterpolation) : base(new DiscreteSurface(rows, columns, values), xInterpolation, yInterpolation, true) { var width = values.ColumnCount; var discreteSurface = new DiscreteSurface(rows, columns, values); var x = discreteSurface.XArray; if (forwards != null) { SpotValue = forwards[0]; var n = forwards.Length; var fwds = new double[n - 1]; for (var index = 1; index < n; index++) { fwds[index - 1] = forwards[index]; } ForwardCurve = new LinearInterpolation(); ForwardCurve.Initialize(rows, fwds); } if (yInterpolation.GetType() == typeof(SABRModelInterpolation)) { var length = values.RowCount; var y = discreteSurface.YArray; for (int i = 0; i < length; i++) { //interpolate each maturity first (in strike) with SABR var yinterp = (SABRModelInterpolation)yInterpolation.Clone(); yinterp.ExpiryTime = x[i]; if (Forward != null && Spot != null) { yinterp.AssetPrice = Convert.ToDecimal(Forward); } else { var fwd = ForwardCurve.ValueAt(yinterp.ExpiryTime, true); yinterp.AssetPrice = Convert.ToDecimal(fwd); } yinterp.Initialize(y, values.Row(i).Data); var curve = new DiscreteCurve(y, values.Row(i).Data); var interpolatedCol = new InterpolatedCurve(curve, yinterp, true); _interpolatedColumns.Add(interpolatedCol); } } else //o.w interpolate at each strike point (in time) { for (int i = 0; i < width; i++) { var interp = xInterpolation.Clone(); interp.Initialize(x, values.Column(i).Data); var curve = new DiscreteCurve(x, values.Column(i).Data); var interpolatedCol = new InterpolatedCurve(curve, interp, true); _interpolatedColumns.Add(interpolatedCol); } } }
/// <summary> /// Calcs the forward vols. /// </summary> /// <param name="times">The times.</param> /// <param name="vols">The vols.</param> /// <returns></returns> double[] CalcForwardVariance(double[] times, double[] vols) { int n = times.Length; double[] quadvar = new double[n]; List <double> quadvar0 = new List <double>(); List <double> quadt0 = new List <double>(); double[] quadvar1 = new double[n]; double[] fwdvols = new double[n]; for (int idx = 0; idx < n; idx++) { quadvar[idx] = vols[idx] * vols[idx] * times[idx]; } //create List quadvar0 of quadratic variations and associated times, //dropping negative fwd vols int jdx = 1; quadvar0.Add(quadvar[0]); quadt0.Add(times[0]); for (int idx = 1; idx < n; idx++) { if (quadvar[idx] > quadvar[idx - 1]) { quadvar0.Add(quadvar[idx]); quadt0.Add(times[idx]); jdx++; } } //interpolate cut down list to original time vector for (int idx = 0; idx < n; idx++) { double time1 = times[idx]; var li = new LinearInterpolation(); li.Initialize(quadt0.ToArray(), quadvar0.ToArray()); double y = li.ValueAt(time1, false); quadvar1[idx] = y; } //convert back from quadratic variatons to forward vols fwdvols[0] = vols[0] * vols[0]; for (int idx = 0; idx < n - 1; idx++) { double vol0 = quadvar1[idx]; double vol1 = quadvar1[idx + 1]; double fwdvol = Math.Sqrt((vol1 - vol0) / (times[idx + 1] - times[idx])); fwdvols[idx + 1] = fwdvol * fwdvol; } return(fwdvols); }
/// <summary> /// Helper function used to initialise the private fields. /// </summary> /// <param name="volatilityCurve">The Bootstrap engine /// that contains the results of the bootstrap.</param> /// <param name="expiryInterpolationType">Type of the expiry /// interpolation. /// Example: Linear interpolation.</param> private void InitialisePrivateFields (VolatilityCurve volatilityCurve, ExpiryInterpolationType expiryInterpolationType) { // Initialise the Calculation Date. _calculationDate = volatilityCurve.GetBaseDate(); // Set the x and y arrays for the one dimensional interpolation. var results = volatilityCurve.BootstrapResults.Results; IDayCounter dayCountObj = Actual365.Instance; var tempXArray = new List <double>(); var tempYArray = new List <double>(); var count = 1; foreach (var expiry in results.Keys) { var timeToExpiry = dayCountObj.YearFraction (_calculationDate, expiry); tempXArray.Add(timeToExpiry); tempYArray.Add(decimal.ToDouble(results[expiry])); // Record the first and last time to expiry and available // bootstrap Caplet volatility. if (count == 1) { _firstExpiry = (decimal)timeToExpiry; _firstVolatility = results[expiry]; } _lastVolatility = results[expiry]; _lastExpiry = (decimal)timeToExpiry; ++count; } double[] xArray = tempXArray.ToArray(); double[] yArray = tempYArray.ToArray(); // Initialise the one dimensional interpolation object. switch (expiryInterpolationType) { case ExpiryInterpolationType.CubicHermiteSpline: _expiryInterpolationObj = new CubicHermiteSplineInterpolation(); _expiryInterpolationObj.Initialize(xArray, yArray); break; default: // Linear interpolation _expiryInterpolationObj = new LinearInterpolation(); _expiryInterpolationObj.Initialize(xArray, yArray); break; } }
/// <summary> /// Compute a one dimensional (piecewise) Linear interpolation. Extrapolation is flat-line. /// </summary> /// <param name="xValues">One dimensional array of x-values. Array is not required to be in ascending order.</param> /// <param name="yValues">One dimensional array of known y-values. Length of the array must be equal to the length of the XArray parameter.</param> /// <param name="target">Value at which to compute the interpolation.</param> /// <returns></returns> public double LinearInterpolate(Double[] xValues, Double[] yValues, double target) { if (xValues == null) { return(0); } if (yValues == null) { return(0); } var li = new LinearInterpolation(); li.Initialize(xValues, yValues); return(li.ValueAt(target, true)); }
public void TestLinearInterpolation() { Random r = new Random(Environment.TickCount); TearDown(); var interpolation = new LinearInterpolation(); interpolation.Initialize(_times, _rates); for (int i = 0; i < 10; ++i) { double time = (i + r.Next(-10000, 10000) / 10000); double interpRate = interpolation.ValueAt(time, true); Debug.WriteLine($"interpolatedRate : {interpRate} Time: {time}"); } }
/// <summary> /// Helper function used by the master initialisation function to /// initialise the one dimensional interpolation object. /// </summary> /// <param name="discountFactors">The discount factors.</param> /// <param name="offsets">The offsets.</param> private void InitialiseDiscountFactorObject (double[] discountFactors, int[] offsets) { // Convert each offset to a decimal type. var numOffsets = offsets.Length; var xArray = new double[numOffsets]; for (var i = 0; i < numOffsets; ++i) { xArray[i] = offsets[i]; } // Instantiate the object that will provide the one dimensional // interpolation functionality. _discountFactorObj = new LinearInterpolation(); _discountFactorObj.Initialize(xArray, discountFactors); }
public double Value(double trialAdjustment) { // Set the adjustments // Adjust the rates with the answer if (_spreadStartIndex == 0) { for (int i = 0; i <= _spreadEndIndex; i++) { _adjustments[i] = (decimal)trialAdjustment; } } else { int startDays = _days[_spreadStartIndex - 1]; // if there is only one point then don't interpolate if (_spreadDays == startDays) { _adjustments[_spreadStartIndex] = (decimal)trialAdjustment; } else { var x = new double[] { startDays, _spreadDays }; var y = new[] { (double)_adjustments[_spreadStartIndex - 1], trialAdjustment }; var interpolation = new LinearInterpolation(); interpolation.Initialize(x, y); for (int i = _spreadStartIndex; i <= _spreadEndIndex; i++) { int days = _days[i]; _adjustments[i] = (decimal)interpolation.ValueAt(days, false); } } } double valueForAdjustment = RateCurve.CalculateImpliedQuote(_logger, _cache, _nameSpace, _baseDate, _properties, _instruments, _rates, _adjustments, _spreadAssetId, _spreadAssetValuation, _fixingCalendar, _rollCalendar); return(valueForAdjustment - _valueForZeroAdjustment - _spread); }