/// <summary> /// Takes a range of volatilities, an array of tenor expiries and an /// array of strikes to create a VolatilitySurface /// </summary> /// <param name="nameSpace"></param> /// <param name="expiryTenors"></param> /// <param name="strikes"></param> /// <param name="volSurface"></param> /// <param name="surfaceId"></param> /// <param name="logger"></param> /// <param name="cache">The cache.</param> /// <param name="forwards">The array of forwards. The first element is the spot value. Conseuently, the length of this array is expiryTenors.Length + 1.</param> protected ExtendedExpiryTermStrikeVolatilitySurface(ILogger logger, ICoreCache cache, String nameSpace, String[] expiryTenors, Double[] strikes, Double[] forwards, Double[,] volSurface, VolatilitySurfaceIdentifier surfaceId) { Algorithm = surfaceId.Algorithm; PricingStructureIdentifier = surfaceId; //Build the parameteric adjustment set from th3e forwards. var parametricAdjustment = GenerateForwards(forwards); var holder = new PricingStructureAlgorithmsHolder(logger, cache, nameSpace, surfaceId.PricingStructureType, surfaceId.Algorithm); var xDimensionInterpolationMethod = InterpolationMethodHelper.Parse(holder.GetValue("xDimensionInterpolation")); var yDimensionInterpolationMethod = InterpolationMethodHelper.Parse(holder.GetValue("yDimensionInterpolation")); _matrixIndexHelper = new SortedList <ExpiryTenorStrikeKey, int>(new ExpiryTenorStrikeKey()); var points = ProcessRawSurface(expiryTenors, strikes, volSurface, surfaceId.StrikeQuoteUnits, surfaceId.UnderlyingAssetReference); PricingStructure = new VolatilityRepresentation { name = surfaceId.Name, id = surfaceId.Id, currency = surfaceId.Currency, asset = new AnyAssetReference { href = surfaceId.Instrument }, }; var datapoints = new MultiDimensionalPricingData { point = points }; PricingStructureValuation = new VolatilityMatrix { dataPoints = datapoints , adjustment = parametricAdjustment , objectReference = new AnyAssetReference { href = surfaceId.Instrument } , baseDate = new IdentifiedDate { Value = surfaceId.BaseDate } , buildDateTime = DateTime.Now , buildDateTimeSpecified = true }; var expiries = new double[expiryTenors.Length]; var index = 0; foreach (var term in expiryTenors)//TODO include business day holidays and roll conventions. { expiries[index] = PeriodHelper.Parse(term).ToYearFraction(); index++; } // Record the row/column sizes of the inputs _matrixRowCount = expiryTenors.Length; // Columns includes expiry and term (tenor) if it exists. _matrixColumnCount = strikes.Length + 1; // Generate an interpolator to use Interpolator = new ExtendedVolatilitySurfaceInterpolator(expiries, strikes, forwards, new Matrix(volSurface), xDimensionInterpolationMethod.Value, yDimensionInterpolationMethod.Value); }
/// <summary> /// Takes a range of volatilities, an array of tenor expiries and an /// array of strikes to create a VolatilitySurface /// </summary> /// <param name="logger"></param> /// <param name="cache"></param> /// <param name="nameSpace"></param> /// <param name="expiryTenors"></param> /// <param name="strikes"></param> /// <param name="volSurface"></param> /// <param name="surfaceId"></param> public ExpiryTermTenorStrikeVolatilityCube(ILogger logger, ICoreCache cache, String nameSpace, String[] expiryTenors, Double[] strikes, Double[,] volSurface, VolatilitySurfaceIdentifier surfaceId) { Algorithm = surfaceId.Algorithm; var holder = new PricingStructureAlgorithmsHolder(logger, cache, nameSpace, surfaceId.PricingStructureType, surfaceId.Algorithm); var curveInterpolationMethod = InterpolationMethodHelper.Parse(holder.GetValue("CurveInterpolation")); var points = ProcessRawSurface(expiryTenors, strikes, volSurface); PricingStructure = new VolatilityRepresentation { name = surfaceId.Name, id = surfaceId.Id, asset = new AnyAssetReference { href = "Unknown" }, }; var datapoints = new MultiDimensionalPricingData { point = points }; PricingStructureValuation = new VolatilityMatrix { dataPoints = datapoints , objectReference = new AnyAssetReference { href = PricingStructure.id } , baseDate = new IdentifiedDate { Value = surfaceId.BaseDate } , buildDateTime = DateTime.Now , buildDateTimeSpecified = true }; var expiries = new double[expiryTenors.Length]; var index = 0; foreach (var term in expiryTenors)//TODO include business day holidays and roll conventions. { expiries[index] = PeriodHelper.Parse(term).ToYearFraction(); index++; } // Generate an interpolator to use Interpolator = new VolSurfaceInterpolator(expiries, strikes, new Matrix(volSurface), curveInterpolationMethod, true); }
/// <summary> /// Construct a VolatilityCube from points /// </summary> /// <param name="properties"></param> /// <param name="points"></param> public VolatilityCube(NamedValueSet properties, PricingStructurePoint[] points) { properties.Set(EnvironmentProp.Function, FunctionProp.Market.ToString()); PricingStructureIdentifier = new VolatilitySurfaceIdentifier(properties); var surfaceId = (VolatilitySurfaceIdentifier)PricingStructureIdentifier; PricingStructureData = new PricingStructureData(CurveType.Parent, Constants.AssetClass.Rates);//TODO Need to set for the different underlyers. SetInterpolator(); foreach (PricingStructurePoint point in points) { point.underlyingAssetReference = surfaceId.UnderlyingAssetReference; point.quoteUnits = surfaceId.StrikeQuoteUnits; } PricingStructure = new VolatilityRepresentation { name = surfaceId.Name, id = surfaceId.Id, currency = surfaceId.Currency, asset = new AnyAssetReference { href = surfaceId.Instrument }, }; var datapoints = new MultiDimensionalPricingData { point = points }; PricingStructureValuation = new VolatilityMatrix { dataPoints = datapoints, objectReference = new AnyAssetReference { href = surfaceId.Instrument }, baseDate = new IdentifiedDate { Value = surfaceId.BaseDate }, buildDateTime = DateTime.Now, buildDateTimeSpecified = true }; _matrixIndexHelper = new SortedList <ExpiryTenorStrikeKey, int>(new ExpiryTenorStrikeKey()); ProcessVolatilityRepresentation(); }
/// <summary> /// Unpack a raw surface and create a VolatilitySurface /// The object array is assumed to be zero based when it is passed to the constructor /// (That is any Excel idiosyncrasies have been expunged) /// We'll test and modify if necessary to zero base the array /// </summary> /// <param name="rawSurface"></param> /// <param name="surfaceId"></param> /// <param name="date"></param> /// <param name="buildDateTime"></param> // /// <param name="algorithm">The algorithm for interpolation. Not implemented yet.</param> public VolatilitySurface(object[,] rawSurface, VolatilitySurfaceIdentifier surfaceId, DateTime date, DateTime buildDateTime) { PricingStructureIdentifier = surfaceId; IDayCounter dc = Actual365.Instance; var termPoints = new List <TermPoint> { TermPointFactory.Create(1.0m, new DateTime()), TermPointFactory.Create(0.99m, new DateTime().AddDays(10)), TermPointFactory.Create(0.97m, new DateTime().AddDays(100)) }; var termCurve = TermCurve.Create(new DateTime(), new InterpolationMethod { Value = "LinearInterpolation" }, true, termPoints); Interpolator = new TermCurveInterpolator(termCurve, date, dc);//TODO need to create a surfaceinterpolator. var zeroedRawSurface = rawSurface.GetLowerBound(0) == 1 ? RedimensionRawSurface(rawSurface) : rawSurface; _algorithm = "Linear"; // An ugly trick to find out if this is a cube or a surface bool isCube = !double.TryParse(zeroedRawSurface[1, 1].ToString(), out _); // Extract the strikes/tenors/expiries and build the surface var expiry = ExtractExpiryFromRawSurface(zeroedRawSurface); var term = ExtractTenorFromRawSurface(zeroedRawSurface, isCube); var strike = ExtractStrikeFromRawSurface(zeroedRawSurface, isCube); var volatility = ExtractVolatilitiesFromRawSurface(zeroedRawSurface, isCube); _matrixIndexHelper = new SortedList <ExpiryTenorStrikeKey, int>(new ExpiryTenorStrikeKey()); var points = ProcessRawSurface(expiry, term, strike, volatility); PricingStructure = new VolatilityRepresentation { name = surfaceId.Name, id = surfaceId.Id, asset = new AnyAssetReference { href = "Unknown" }, }; PricingStructureValuation = new VolatilityMatrix { dataPoints = new MultiDimensionalPricingData { point = points }, objectReference = new AnyAssetReference { href = PricingStructure.id }, baseDate = new IdentifiedDate { Value = date }, buildDateTime = buildDateTime, buildDateTimeSpecified = true }; // Record the row/column sizes of the inputs _matrixRowCount = expiry.Length; _matrixRowCount *= term?.Length ?? 1; // Columns includes expiry and term (tenor) if it exists. _matrixColumnCount = strike.Length + 1; _matrixColumnCount += term != null ? 1 : 0; // Generate an interpolator to use if (term == null || term.Length == 0) { _interpolation = new BilinearInterpolator(); } else { _interpolation = new TrilinearInterpolator(); } }
/// <summary> /// The constructor /// </summary> /// <param name="assetRef">The Asset this volatility models</param> /// <param name="name">The id to use with this matrix</param> /// <param name="date">The value date relating to this surface</param> /// <param name="expiry">An array of expiry definitions</param> /// <param name="term">An array of tenors or null if there is no term dimension.</param> /// <paparam name="strike">An array of strike descriptions</paparam> /// <param name="strike">The strike array.</param> /// <param name="volatility">A 2d array of volatilities. /// This must be equal to (expiry.Count x (1 <= y <= term.Count) x strike.Count </param> public VolatilitySurface(string assetRef, string name, DateTime date, string[] expiry, string[] term, string[] strike, double[,] volatility) { IDayCounter dc = Actual365.Instance; var termPoints = new List <TermPoint> { TermPointFactory.Create(1.0m, new DateTime()), TermPointFactory.Create(0.99m, new DateTime().AddDays(10)), TermPointFactory.Create(0.97m, new DateTime().AddDays(100)) }; var termCurve = TermCurve.Create(new DateTime(), new InterpolationMethod { Value = "LinearInterpolation" }, true, termPoints); Interpolator = new TermCurveInterpolator(termCurve, date, dc);//TODO need to create a surfaceinterpolator. _algorithm = "Linear"; _matrixIndexHelper = new SortedList <ExpiryTenorStrikeKey, int>(new ExpiryTenorStrikeKey()); var points = ProcessRawSurface(expiry, term, strike, volatility); PricingStructure = new VolatilityRepresentation { name = name , id = name + date.ToString("yyyyMMdd") , asset = new AnyAssetReference { href = assetRef } }; PricingStructureValuation = new VolatilityMatrix { dataPoints = new MultiDimensionalPricingData { point = points } , objectReference = new AnyAssetReference { href = PricingStructure.id } , baseDate = new IdentifiedDate { Value = date } , buildDateTime = DateTime.Now , buildDateTimeSpecified = true }; // Record the row/column sizes of the inputs _matrixRowCount = expiry.Length; _matrixRowCount *= term?.Length ?? 1; // Columns includes expiry and term (tenor) if it exists. _matrixColumnCount = strike.Length + 1; _matrixColumnCount += term != null ? 1 : 0; //TODO // Generate an interpolator to use if (term == null || term.Length == 0) { _interpolation = new BilinearInterpolator(); } else { _interpolation = new TrilinearInterpolator(); } }
/// <summary> /// Takes a range of volatilities, an array of tenor expiries and an /// array of strikes to create a VolatilitySurface /// </summary> /// <param name="logger">The logger.</param> /// <param name="cache">The cache.</param> /// <param name="expiryTenors">the expiry tenors.</param> /// <param name="tenors">The tenors.</param> /// <param name="volSurface">The vol surface.</param> /// <param name="nameSpace">The namespace</param> /// <param name="properties">The properties.</param> protected ExpiryTermTenorATMVolatilitySurface(ILogger logger, ICoreCache cache, String nameSpace, NamedValueSet properties, String[] expiryTenors, String[] tenors, Double[,] volSurface) { Algorithm = PropertyHelper.ExtractAlgorithm(properties); PricingStructureIdentifier = new VolatilitySurfaceIdentifier(properties); var surfaceId = (VolatilitySurfaceIdentifier)PricingStructureIdentifier; var holder = new PricingStructureAlgorithmsHolder(logger, cache, nameSpace, surfaceId.PricingStructureType, surfaceId.Algorithm); var curveInterpolationMethod = InterpolationMethodHelper.Parse(holder.GetValue("CurveInterpolation")); _matrixIndexHelper = new SortedList <ExpiryTenorStrikeKey, int>(new ExpiryTenorStrikeKey()); var points = ProcessRawSurface(expiryTenors, tenors, volSurface, surfaceId.UnderlyingAssetReference); PricingStructure = new VolatilityRepresentation { name = surfaceId.Name, id = surfaceId.Id, currency = surfaceId.Currency, asset = new AnyAssetReference { href = surfaceId.Instrument }, }; var datapoints = new MultiDimensionalPricingData { point = points, businessCenter = surfaceId.BusinessCenter, timing = surfaceId.QuoteTiming, currency = surfaceId.Currency, cashflowType = surfaceId.CashflowType, informationSource = surfaceId.InformationSources, measureType = surfaceId.MeasureType, quoteUnits = surfaceId.QuoteUnits }; if (surfaceId.ExpiryTime != null) { datapoints.expiryTime = (DateTime)surfaceId.ExpiryTime; datapoints.expiryTimeSpecified = true; } if (surfaceId.ValuationDate != null) { datapoints.valuationDate = (DateTime)surfaceId.ValuationDate; datapoints.valuationDateSpecified = true; } if (surfaceId.Time != null) { datapoints.time = (DateTime)surfaceId.Time; datapoints.timeSpecified = true; } if (surfaceId.QuotationSide != null) { datapoints.side = (QuotationSideEnum)surfaceId.QuotationSide; datapoints.sideSpecified = true; } PricingStructureValuation = new VolatilityMatrix { dataPoints = datapoints, objectReference = new AnyAssetReference { href = surfaceId.Instrument }, baseDate = new IdentifiedDate { Value = surfaceId.BaseDate }, buildDateTime = surfaceId.BuildDateTime, buildDateTimeSpecified = true }; var expiries = new double[expiryTenors.Length]; var index = 0; foreach (var term in expiryTenors)//TODO include business day holidays and roll conventions. { expiries[index] = PeriodHelper.Parse(term).ToYearFraction(); index++; } var tenor = new double[tenors.Length]; index = 0; foreach (var term in tenors)//TODO include business day holidays and roll conventions. { tenor[index] = PeriodHelper.Parse(term).ToYearFraction(); index++; } // Record the row/column sizes of the inputs _matrixRowCount = expiryTenors.Length; _matrixRowCount *= tenors.Length; // Columns includes expiry and term (tenor) if it exists. _matrixColumnCount = 1; // Generate an interpolator to use Interpolator = new VolSurfaceInterpolator(expiries, tenor, new Matrix(volSurface), curveInterpolationMethod, true); }