/// <summary> /// This call returns an IValue structure for an exact match with a given point. /// If the point does not exist this method will return null. /// </summary> /// <param name="pt">The point in the surface/cube to get the value of</param> /// <returns>An IValue object representing the value/coordinates of the point</returns> public override IValue GetValue(IPoint pt) { IValue val = null; string tenor = null; string strike; var expiry = ((Period)pt.Coords[0]).ToString(); if (pt.Coords.Count > 2) { tenor = ((Period)pt.Coords[1]).ToString(); strike = pt.Coords[2].ToString(); } else { strike = pt.Coords[1].ToString(); } var key = new ExpiryTenorStrikeKey(expiry, tenor, strike); if (_matrixIndexHelper.ContainsKey(key)) { var idx = _matrixIndexHelper[key]; var volatility = GetVolatilityMatrix().dataPoints.point[idx].value; var id = GetVolatilityMatrix().dataPoints.point[idx].id; val = new VolatilityValue(id, volatility, pt); } return(val); }
/// <summary> /// Convert a VolatilityValue into a <see cref="Point2D"/> /// that represents the year fraction expiry and a Point2D strike /// </summary> /// <param name="val"></param> /// <returns></returns> private static Point2D ToDoublePoint2D(VolatilityValue val) { var expiry = (Period)val.PricePoint.coordinate[0].expiration[0].Items[0]; var strike = val.PricePoint.coordinate[0].strike[0]; var value = Convert.ToDouble(val.Value); return(new Point2D((double)strike, expiry.ToYearFraction(), value)); }
/// <summary> /// Generate an array of PricingStructurePoint from a set of input arrays /// The array can then be added to the Matrix /// </summary> /// <param name="expiry">Expiry values to use</param> /// <param name="term">Tenor values to use</param> /// <param name="strike">Strike values to use</param> /// <param name="volatility">An array of volatility values</param> /// <returns></returns> private PricingStructurePoint[] ProcessRawSurface(string[] expiry, string[] term, string[] strike, double[,] volatility) { var expiryLength = expiry.Length; var termLength = term?.Length ?? 1; var strikeLength = strike.Length; var pointIndex = 0; var points = new PricingStructurePoint[expiryLength * termLength * strikeLength]; // Offset row counter var row = 0; for (var expiryIndex = 0; expiryIndex < expiryLength; expiryIndex++) { // extract the current expiry var expiryKeyPart = expiry[expiryIndex]; for (var termIndex = 0; termIndex < termLength; termIndex++) { // extract the current tenor (term) of null if there are no tenors var tenorKeyPart = term?[termIndex]; // Offset column counter var column = 0; for (var strikeIndex = 0; strikeIndex < strikeLength; strikeIndex++) { // Extract the strike to use in the helper key var strikeKeyPart = strike[strikeIndex]; // Extract the row,column indexed volatility var vol = (decimal)volatility[row, column++]; // Build the index offset list helper var key = new ExpiryTenorStrikeKey(expiryKeyPart, tenorKeyPart, strikeKeyPart); _matrixIndexHelper.Add(key, pointIndex); // Add the value to the points array (dataPoints entry in the matrix) var val = new VolatilityValue(null, vol, new Coordinate(expiryKeyPart, tenorKeyPart, strike[strikeIndex])); points[pointIndex++] = val.PricePoint; } row++; } } return(points); }