/// <summary> /// Use the Expiry and Tenor to create a key. /// Expiry or tenor can be null but not both. /// </summary> /// <param name="expiry">Expiry key part</param> /// <param name="strike">Strike key part</param> public ExpiryTenorStrikeKey(string expiry, Double strike) { try { Expiry = expiry != null?PeriodHelper.Parse(expiry) : null; } catch (System.Exception) { Expiry = null; } try { Tenor = null; } catch (System.Exception) { Tenor = null; } try { Strike = Convert.ToDecimal(strike); } catch (System.Exception) { Strike = 0; } }
public void GetForwardRateTest1() { var target = new ForwardRatesMatrix(_assetExpiries, _assetTenors, _assetData, _id); // Check for valid expiry/tenor pair Period expiry = PeriodHelper.Parse("1y"); Period tenor = PeriodHelper.Parse("4y"); const decimal expected = 6.8227m / 100.0m; decimal actual; try { actual = target.GetAssetPrice(expiry, tenor); Assert.AreEqual(expected, actual); } catch (ArgumentException ex) { Assert.AreEqual("Invalid Expiry/Tenor pair supplied.", ex.Message); } // Check for invalid expiry/tenor pair expiry = PeriodHelper.Parse("6y"); tenor = PeriodHelper.Parse("4y"); try { actual = target.GetAssetPrice(expiry, tenor); Assert.AreEqual(expected, actual); } catch (ArgumentException ex) { Assert.AreEqual("Invalid Expiry/Tenor pair supplied.", ex.Message); } }
public void UnadjustedDatesFromTermination() { DateTime effectiveDate = new DateTime(2009, 05, 01); DateTime terminationDate = new DateTime(2010, 11, 27); Period periodInterval = PeriodHelper.Parse("3M"); RollConventionEnum rollDayConvention = RollConventionEnum.Item19; DateTime firstRegularPeriodStartDate = effectiveDate; DateTime lastRegularPeriodEndDate = terminationDate; DateTime[] dates = DateScheduler.GetUnadjustedDatesFromTerminationDate(effectiveDate, terminationDate, periodInterval, rollDayConvention, out firstRegularPeriodStartDate, out lastRegularPeriodEndDate); Assert.AreEqual(dates.Length, 7); Assert.AreEqual(firstRegularPeriodStartDate, new DateTime(2009, 08, 19)); Assert.AreEqual(lastRegularPeriodEndDate, new DateTime(2010, 08, 19)); dates = DateScheduler.GetUnadjustedDatesFromTerminationDate(effectiveDate, terminationDate, periodInterval, rollDayConvention, out firstRegularPeriodStartDate, out lastRegularPeriodEndDate); Assert.AreEqual(dates.Length, 7); Assert.AreEqual(firstRegularPeriodStartDate, new DateTime(2009, 08, 19)); Assert.AreEqual(lastRegularPeriodEndDate, new DateTime(2010, 08, 19)); effectiveDate = new DateTime(2009, 11, 16); terminationDate = new DateTime(2011, 11, 28); rollDayConvention = RollConventionEnum.Item29; dates = DateScheduler.GetUnadjustedDatesFromTerminationDate(effectiveDate, terminationDate, periodInterval, rollDayConvention, out firstRegularPeriodStartDate, out lastRegularPeriodEndDate); Assert.AreEqual(dates.Length, 9); Assert.AreEqual(firstRegularPeriodStartDate, new DateTime(2010, 02, 28)); Assert.AreEqual(lastRegularPeriodEndDate, new DateTime(2011, 08, 29)); }
/// <summary> /// Creates a PricingDataPointCoordinate. /// </summary> /// <param name="expiry"></param> /// <param name="term"></param> /// <param name="strike"></param> /// <param name="generic"></param> /// <returns></returns> public static PricingDataPointCoordinate Create(string expiry, string term, decimal strike, string generic) { var coordinate = new PricingDataPointCoordinate(); var pExpiry = expiry != null?PeriodHelper.Parse(expiry) : null; var pTerm = term != null?PeriodHelper.Parse(term) : null; var pStrike = strike; GenericDimension pGeneric = null; if (generic != null) { pGeneric = new GenericDimension { name = generic, Value = generic }; } coordinate.expiration = new TimeDimension[1]; coordinate.expiration[0] = new TimeDimension { Items = new object[] { pExpiry } }; if (pTerm != null) { coordinate.term = new TimeDimension[1]; coordinate.term[0] = new TimeDimension { Items = new object[] { pTerm } }; } coordinate.strike = new[] { pStrike }; if (pGeneric != null) { coordinate.generic = new[] { pGeneric } } ; return(coordinate); }
/// <summary> /// Use the Expiry and Tenor to create a key. /// Expiry or tenor can be null but not both. /// </summary> /// <param name="expiry">Expiry key part</param> /// <param name="tenor">Tenor key part (can be null)</param> /// <param name="strike">Strike key part</param> public ExpiryTenorStrikeKey(string expiry, string tenor, string strike) { try { Expiry = expiry != null?PeriodHelper.Parse(expiry) : null; } catch (System.Exception) { Expiry = null; } try { Tenor = tenor != null?PeriodHelper.Parse(tenor) : null; } catch (System.Exception) { Tenor = null; } try { Strike = strike != null?Convert.ToDecimal(strike) : 0; } catch (System.Exception) { Strike = 0; } }
/// <summary> /// Parses the string info into an asset. /// </summary> /// <param name="instrumentId"></param> /// <param name="value"></param> /// <returns></returns> public static Pair <Asset, BasicAssetValuation> ParseSurface(string instrumentId, decimal value) { const string rateQuotationType = PriceableCapRateAsset.VolatilityQuotationType; SimpleFra underlyingAsset; var results = instrumentId.Split('-'); var instrument = results[1]; var listBasicQuotations = new List <BasicQuotation>(); var asset = EnumHelper.Parse <AssetTypesEnum>(instrument); switch (asset) { case AssetTypesEnum.BillCaplet: case AssetTypesEnum.BillFloorlet: case AssetTypesEnum.Floorlet: case AssetTypesEnum.Caplet: { var index = results[3]; underlyingAsset = new SimpleFra { id = instrumentId, startTerm = PeriodHelper.Parse(results[2]) }; underlyingAsset.endTerm = underlyingAsset.startTerm.Sum(PeriodHelper.Parse(index)); listBasicQuotations.Add(BasicQuotationHelper.Create(value, rateQuotationType, "DecimalVolatility")); break; } default: throw new NotSupportedException($"Asset type {instrument} is not supported"); } return(new Pair <Asset, BasicAssetValuation>(underlyingAsset, BasicAssetValuationHelper.Create(underlyingAsset.id, listBasicQuotations.ToArray()))); }
///<summary> ///</summary> ///<param name="term"></param> ///<param name="strike"></param> ///<returns></returns> public double GetValueByExpiryTermAndStrike(string term, double strike) { var expiryTerm = PeriodHelper.Parse(term).ToYearFraction(); IPoint point = new Point2D(expiryTerm, strike); return(Interpolator.Value(point)); }
/// <summary> /// Initializes a new instance of the <see cref="PriceableCommodityAverageForward"/> class. /// </summary> /// <param name="notionalAmount">The notional amount</param> /// <param name="baseDate">The base date</param> /// <param name="expiryTerm">The expiry Term.</param> /// <param name="underlyingTenor">The underlying tenor</param> /// <param name="nodeStruct">The nodeStruct.</param> /// <param name="fixingCalendar">The fixingCalendar.</param> /// <param name="paymentCalendar">The paymentCalendar.</param> /// <param name="commodityForward">The forward points.</param> public PriceableCommodityAverageForward(DateTime baseDate, decimal notionalAmount, string expiryTerm, string underlyingTenor, CommodityAverageSwapNodeStruct nodeStruct, IBusinessCalendar fixingCalendar, IBusinessCalendar paymentCalendar, BasicQuotation commodityForward) { PaymentDiscountFactorCcy12 = 1.0m; PaymentDiscountFactorCcy1 = 1.0m; Ccy2CurveName = string.Empty; Ccy1CurveName = string.Empty; ModelIdentifier = "SimpleCommodityAsset"; if (nodeStruct.Commodity != null) { Id = nodeStruct.Commodity.id; } ExpiryTerm = PeriodHelper.Parse(expiryTerm); //Default length is one month //TODO move to config. UnderlyingTenor = PeriodHelper.Parse(underlyingTenor); NotionalAmount = notionalAmount; CommodityAsset = nodeStruct.Commodity; BaseDate = baseDate; SpotDateOffset = nodeStruct.SpotDate; //FixingCalendar = BusinessCenterHelper.ToBusinessCalendar(SpotDateOffset.businessCenters); SpotDate = GetSpotDate(baseDate, fixingCalendar, SpotDateOffset); //TODO Set the start date based on the config data AdjustedStartDate = GetEffectiveDate(SpotDate, paymentCalendar, ExpiryTerm, nodeStruct.SpotDate.businessDayConvention); RiskMaturityDate = GetForwardDate(AdjustedStartDate, paymentCalendar, UnderlyingTenor, SpotDateOffset.businessDayConvention); SetRate(commodityForward); }
public static RateIndex Parse(string id, string instrumentId, string floatingRateIndex, string currency, string dayCountFraction, string paymentFrequency, string term) { var rateIndex = new RateIndex { currency = new IdentifiedCurrency { Value = currency }, dayCountFraction = DayCountFractionHelper.Parse(dayCountFraction), floatingRateIndex = FloatingRateIndexHelper.Parse(floatingRateIndex), id = id, instrumentId = InstrumentIdArrayHelper.Parse(instrumentId) }; Period frequency = null; if (paymentFrequency != null) { frequency = PeriodHelper.Parse(paymentFrequency); } rateIndex.paymentFrequency = frequency; Period period = null; if (term != null) { period = PeriodHelper.Parse(term); } rateIndex.term = period; return(rateIndex); }
/// <summary> /// Generate a day value from a term /// </summary> /// <param name="term">A term to convert to a value</param> /// <param name="dayCountConvention">day count convention to use</param> /// <returns></returns> public static double GenerateDayValue(string term, double dayCountConvention) { var i = PeriodHelper.Parse(term); var numero = Convert.ToDouble(i.periodMultiplier); double yearFraction = 0; switch (i.period) { case PeriodEnum.D: yearFraction = numero / dayCountConvention; break; case PeriodEnum.W: yearFraction = numero / 52.0d; break; case PeriodEnum.M: yearFraction = numero / 12.0d; break; case PeriodEnum.Y: yearFraction = numero; break; } return(yearFraction); }
/// <summary> /// Creates a PricingDataPointCoordinate. /// </summary> /// <param name="expiryDate"></param> /// <param name="expiryTerm"></param> /// <param name="maturityDate"></param> /// <param name="maturityTerm"></param> /// <param name="strike"></param> /// <param name="generic"></param> /// <returns></returns> public static PricingDataPointCoordinate Create(DateTime expiryDate, string expiryTerm, DateTime maturityDate, string maturityTerm, decimal strike, string generic) { var coordinate = new PricingDataPointCoordinate(); var pExpiryTerm = expiryTerm != null?PeriodHelper.Parse(expiryTerm) : null; var pMaturityTerm = maturityTerm != null?PeriodHelper.Parse(maturityTerm) : null; var pStrike = strike; GenericDimension pGeneric = null; if (generic != null) { pGeneric = new GenericDimension { name = generic, Value = generic }; } coordinate.expiration = new TimeDimension[1]; coordinate.expiration[0] = TimeDimensionFactory.Create(expiryDate, pExpiryTerm); coordinate.term = new TimeDimension[1]; coordinate.term[0] = TimeDimensionFactory.Create(maturityDate, pMaturityTerm); coordinate.strike = new[] { pStrike }; if (pGeneric != null) { coordinate.generic = new[] { pGeneric } } ; return(coordinate); }
public void GetVolatilityTest1() { var target = new SwaptionDataMatrix(_volTenors, _volStrikes, _volExpiry, _volData, _id); decimal actual; const decimal expected = 9.83m / 100.0m; Period tenor = PeriodHelper.Parse("2yr"); decimal strike = 50.0m / 10000.0m; try { actual = target.GetVolatility(tenor, strike); Assert.AreEqual(expected, actual); } catch (ArgumentException ex) { Assert.AreEqual("The matrix is malformed. No volatilities are available.", ex.Message); } tenor = PeriodHelper.Parse("32yr"); strike = 50.0m / 10000.0m; try { actual = target.GetVolatility(tenor, strike); Assert.AreEqual(expected, actual); } catch (ArgumentException ex) { Assert.AreEqual("The matrix is malformed. No volatilities are available.", ex.Message); } }
public void GetVolatilityTest5() { var target = new SwaptionDataMatrix(_volTenors, _volStrikes, _volExpiry, _volData, _id); const decimal expected = 10.26m / 100.0m; var actual = new decimal[0]; Period tenor = PeriodHelper.Parse("2yr"); try { actual = target.GetVolatility(tenor); CollectionAssert.Contains(actual, expected); } catch (ArgumentException ex) { Assert.AreEqual("The matrix is malformed. No volatilities are available.", ex.Message); } var expected1 = new decimal[actual.Length]; Array.Copy(actual, expected1, actual.Length); const string tenor1 = "2yr"; try { int i = 0; actual = target.GetVolatility(tenor1); foreach (decimal d in actual) { Assert.AreEqual(expected1[i++], d); } } catch (ArgumentException ex) { Assert.AreEqual("The matrix is malformed. No volatilities are available.", ex.Message); } }
private static UnderlyingAsset CreateSimpleFra(string marketInstrumentId) { var simpleFra = new SimpleFra(); string[] slicedInstrumentId = marketInstrumentId.Split('-'); string instrumentCurrency = slicedInstrumentId[0]; string instrumentTerm = slicedInstrumentId[2]; simpleFra.currency = new IdentifiedCurrency { Value = instrumentCurrency }; string startTerm; string endTerm = slicedInstrumentId[3]; if (endTerm != null) { startTerm = instrumentTerm; Period temp = PeriodHelper.Parse(endTerm); simpleFra.startTerm = PeriodHelper.Parse(startTerm); simpleFra.endTerm = simpleFra.startTerm.Sum(temp); } else { string[] slicedTerm = instrumentTerm.Split("vxVX".ToCharArray());//TODO fix this for index tenors. startTerm = slicedTerm[0]; endTerm = slicedTerm[1]; simpleFra.startTerm = PeriodHelper.Parse(startTerm); simpleFra.endTerm = PeriodHelper.Parse(endTerm); } simpleFra.instrumentId = new[] { new InstrumentId() }; simpleFra.instrumentId[0].Value = marketInstrumentId; return(simpleFra); }
public SABRVolatilitySurface(ILogger logger, ICoreCache cache, String nameSpace, NamedValueSet properties, String[] expiryTenors, Double[] strikes, Double[,] volSurface) : base(logger, cache, nameSpace, properties, expiryTenors, strikes, volSurface) { var assetClass = properties.GetString(CurveProp.AssetClass, true); var type = EnumHelper.Parse <AssetClass>(assetClass); var assetId = properties.GetValue <string>(CurveProp.AssetId, true); var baseDate = properties.GetValue <DateTime>(CurveProp.BaseDate, true); PricingStructureData = new PricingStructureData(CurveType.Parent, type); UnderlyingPriceableAssets = new List <IPriceableAssetController>(); foreach (var tenor in expiryTenors) { var expiryTenor = PeriodHelper.Parse(tenor); var offset = new Offset { period = expiryTenor.period, periodMultiplier = expiryTenor.periodMultiplier, periodSpecified = true, dayType = DayTypeEnum.Calendar, dayTypeSpecified = true }; var expiryDate = offset.Add(baseDate); var assetProperties = PriceableAssetFactory.BuildPropertiesForAssets(nameSpace, assetId, expiryDate); var asset = PriceableAssetFactory.Create(logger, cache, nameSpace, null, assetProperties, null, null); UnderlyingPriceableAssets.Add(asset); } }
public void GetVolatilityTest4() { var target = new SwaptionDataMatrix(_volTenors, _volStrikes, _volExpiry, _volData, _id); const decimal expected = 10.26m / 100.0m; decimal[] actual; Period tenor = PeriodHelper.Parse("2yr"); try { actual = target.GetVolatility(tenor); CollectionAssert.Contains(actual, expected); } catch (ArgumentException ex) { Assert.AreEqual("The matrix is malformed. No volatilities are available.", ex.Message); } tenor = PeriodHelper.Parse("21yr"); try { actual = target.GetVolatility(tenor); CollectionAssert.Contains(actual, expected); } catch (ArgumentException ex) { Assert.AreEqual("The matrix is malformed. No volatilities are available.", ex.Message); } }
public static RelativeDateOffset Create(string period, DayTypeEnum dayType, string businessDayConventionAsString, BusinessCenters businessCenters, string dateRelativeTo) { var result = new RelativeDateOffset(); Period interval = PeriodHelper.Parse(period); result.period = interval.period; result.periodSpecified = true; result.periodMultiplier = interval.periodMultiplier; result.dayType = dayType; result.dayTypeSpecified = true; if (businessDayConventionAsString != null) { result.businessDayConvention = BusinessDayConventionHelper.Parse(businessDayConventionAsString); result.businessDayConventionSpecified = true; } result.businessCenters = businessCenters; if (dateRelativeTo != null) { var dateReference = new DateReference { href = dateRelativeTo }; result.dateRelativeTo = dateReference; } return(result); }
/// <summary> /// The constructor /// </summary> /// <param name="logger">The logger</param> /// <param name="surfaceId">The id to use with this matrix</param> /// <param name="nameSpace">The namespace</param> /// <param name="expiryTenors">An array of expiry definitions</param> /// <paparam name="strike">An array of strike descriptions</paparam> /// <param name="strikes">The strike array.</param> /// <param name="volSurface">A 2d array of volatilities. /// This must be equal to (expiry.Count x (1 <= y <= term.Count) x strike.Count </param> /// <param name="cache">The cache</param> protected ExpiryTermStrikeVolatilitySurface(ILogger logger, ICoreCache cache, String nameSpace, String[] expiryTenors, Double[] strikes, Double[,] volSurface, VolatilitySurfaceIdentifier surfaceId) { Algorithm = surfaceId.Algorithm; PricingStructureIdentifier = surfaceId; 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, strikes, volSurface, surfaceId.StrikeQuoteUnits, surfaceId.UnderlyingAssetReference); PricingStructure = CreateVolatilityRepresentation(surfaceId); PricingStructureValuation = CreateDataPoints(points, surfaceId); 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 VolSurfaceInterpolator(expiries, strikes, new Matrix(volSurface), curveInterpolationMethod, true); }
/// <summary> /// The key constructor to use with Full Calibration Engines /// </summary> /// <param name="expiry"></param> public SABRKey(string expiry)//TODO problem with ATM. { Expiry = expiry; Tenor = DefaultTenor; ExpiryAsDecimal = (decimal)PeriodHelper.Parse(Expiry).ToYearFraction(); TenorAsDecimal = 0.0m; }
///<summary> ///</summary> ///<param name="expiryByStrikeSurface"></param> ///<returns></returns> ///<exception cref="NotImplementedException"></exception> // {null, 0.25, 0.50, 0.75, 1.00},//strike row // {"1y", 0.11, 0.12, 0.13, 0.14},// // {"2y", 0.21, 0.22, 0.23, 0.24},// // {"3y", 0.31, 0.32, 0.33, 0.34},// // {"4y", 0.41, 0.42, 0.43, 0.44},// // {"5y", 0.51, 0.52, 0.53, 0.54},// // {"6y", 0.61, 0.62, 0.63, 0.64},//expiry - 6 // {"7y", 0.71, 0.72, 0.73, 0.74} //expiry - 7 public static List <PricingStructurePoint> ExtractDataPoints(object[,] expiryByStrikeSurface) { var result = new List <PricingStructurePoint>(); // extract // for (int expiryIndex = expiryByStrikeSurface.GetLowerBound(0) + 1; expiryIndex <= expiryByStrikeSurface.GetUpperBound(0); ++expiryIndex) { object expiryAsObject = expiryByStrikeSurface[expiryIndex, 0]; for (int strikeIndex = expiryByStrikeSurface.GetLowerBound(1) + 1; strikeIndex <= expiryByStrikeSurface.GetUpperBound(1); ++strikeIndex) { object strikeAsObject = expiryByStrikeSurface[0, strikeIndex]; object volatilityAsObject = expiryByStrikeSurface[expiryIndex, strikeIndex]; var pricingStructurePoint = new PricingStructurePoint { coordinate = new[] { new PricingDataPointCoordinate() }, valueSpecified = true, value = Convert.ToDecimal(volatilityAsObject) }; // value // // expiry // pricingStructurePoint.coordinate[0].expiration = new[] { new TimeDimension() }; pricingStructurePoint.coordinate[0].expiration[0].Items = new object[] { 1 }; pricingStructurePoint.coordinate[0].expiration[0].Items[0] = PeriodHelper.Parse(expiryAsObject.ToString()); // strike // pricingStructurePoint.coordinate[0].strike = new[] { Convert.ToDecimal(strikeAsObject) }; result.Add(pricingStructurePoint); } } return(result); }
/// <summary> /// /// </summary> /// <param name="expirationTerm"></param> /// <param name="tenor"></param> /// <returns></returns> public double GetValueByExpiryTermAndTenor(string expirationTerm, string tenor) { var expiryTerm = PeriodHelper.Parse(expirationTerm).ToYearFraction(); var underlyingTenor = PeriodHelper.Parse(tenor).ToYearFraction(); IPoint point = new Point2D(expiryTerm, underlyingTenor); return(Interpolator.Value(point)); }
/// <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> /// Create a grid from an array of names and complex array of data /// The data will contain strings and decimals /// </summary> /// <param name="pSettings">The settings object used to generate these SABR parameters</param> /// <param name="fields">The headers used to identify the SABR parameters</param> /// <param name="data">An array of SABR parameters and expiry/tenor pairs</param> /// <param name="valueDate">The valuation date</param> /// <param name="surfaceId">The id for this matrix</param> public SwaptionVolatilityMatrix(object[][] pSettings, string[] fields, object[][] data, DateTime valueDate, string surfaceId) { // Include a QuotedAssetSet to hold the Settings object used to generate this SABR parameters Matrix Settings = AssignSettings(pSettings); // Set the id for this matrix id = surfaceId; // Set the value date for this vol matrix baseDate = new IdentifiedDate { Value = valueDate }; // Set the buildDate for this matrix buildDateTime = DateTime.Now; // Create the dataPoints structure. This will hold the matrix data dataPoints = new MultiDimensionalPricingData(); var columns = fields.Length; var rows = data.Length; dataPoints.point = new PricingStructurePoint[rows * IdentifierFieldCount]; var point = 0; // Loop through the arrays to populate the underlying VolatilityMatrix for (var gRows = 0; gRows < rows; gRows++) { // Extract the expiry/tenor information for creating var expiry = PeriodHelper.Parse(data[gRows][0].ToString()); var tenor = PeriodHelper.Parse(data[gRows][1].ToString()); for (var gCols = columns - IdentifierFieldCount; gCols < columns; gCols++) { dataPoints.point[point] = new PricingStructurePoint { coordinate = new PricingDataPointCoordinate[1] }; // Set up the co-ordinate (Expiry/Term) for each point dataPoints.point[point].coordinate[0] = new PricingDataPointCoordinate { expiration = new TimeDimension[1] }; // Set the Expiry for the co-ordinate point dataPoints.point[point].coordinate[0].expiration[0] = new TimeDimension { Items = new object[] { expiry } }; // Set the Term for the co-ordinate point dataPoints.point[point].coordinate[0].term = new TimeDimension[1]; dataPoints.point[point].coordinate[0].term[0] = new TimeDimension { Items = new object[] { tenor } }; // Add the quotation characteristics for the point // We will only record a value and the measure type dataPoints.point[point].valueSpecified = true; dataPoints.point[point].value = Convert.ToDecimal(data[gRows][gCols]); dataPoints.point[point].measureType = new AssetMeasureType { Value = fields[gCols] }; point++; } } }
/// <summary> /// Parses the specified interval as string. /// </summary> /// <param name="intervalAsString"><example>3M,3m,14d,6Y</example></param> /// <returns></returns> public static ResetFrequency Parse(string intervalAsString) { var result = new ResetFrequency(); Period interval = PeriodHelper.Parse(intervalAsString); result.periodMultiplier = interval.periodMultiplier; result.period = interval.period.ToString(); return(result); }
/// <summary> /// Parses the specified interval as string. /// </summary> /// <param name="intervalAsString"><example>3M,3m,14d,6Y</example></param> /// <param name="rollConventionAsString">The roll convention.</param> /// <returns></returns> public static CalculationPeriodFrequency Parse(string intervalAsString, string rollConventionAsString) { var result = new CalculationPeriodFrequency(); Period interval = PeriodHelper.Parse(intervalAsString); result.periodMultiplier = interval.periodMultiplier; result.period = interval.period.ToString(); result.rollConvention = RollConventionEnumHelper.Parse(rollConventionAsString); return(result); }
/// <summary> /// Calculate a conversion factor for the multiplier. /// The conversion will only check the initial letter of the period string for matching. /// The matches are d(ay), w(eek), m(onth) and y(ear). /// </summary> /// <param name="period"></param> /// <returns></returns> private static decimal ConversionFactor(string period) { if (period == "ATM" || period == "") { return(0.0m); } var mult = (decimal)PeriodHelper.Parse(period).ToYearFraction(); return(mult); }
/// <summary> /// Convert a raw label value to a formatted label /// This will allow inputs such as 3.0 to default to 3yr /// </summary> /// <param name="rawLabel"></param> /// <returns></returns> public static string GenerateTenorLabel(string rawLabel) { var alpha = string.Empty; decimal numero = 0; LabelSplitter(rawLabel, ref alpha, ref numero); var i = PeriodHelper.Parse(rawLabel); return(i.ToString()); }
public static Trade CreateFraTrade(FraInputRange2 fraInputRange) { var trade = new Trade(); var fra = new Fra { adjustedEffectiveDate = DateTypesHelper.ToRequiredIdentifierDate(fraInputRange.AdjustedEffectiveDate), adjustedTerminationDate = fraInputRange.AdjustedTerminationDate, adjustedTerminationDateSpecified = true, paymentDate = DateTypesHelper.ToAdjustableDate(fraInputRange.UnadjustedPaymentDate, fraInputRange.PaymentDateBusinessDayConvention, fraInputRange.PaymentDateBusinessCenters), Items = new object[] { new ProductType { Value = ProductTypeSimpleEnum.FRA.ToString() } }, ItemsElementName = new[] { ItemsChoiceType2.productType } }; if ("resetDate" != fraInputRange.FixingDayOffsetDateRelativeTo) { throw new ArgumentException("The fixing date must be specified as 'resetDate'-relative!", nameof(fraInputRange)); } var fixingDayType = EnumHelper.Parse <DayTypeEnum>(fraInputRange.FixingDayOffsetDayType); fra.fixingDateOffset = RelativeDateOffsetHelper.Create(fraInputRange.FixingDayOffsetPeriod, fixingDayType, fraInputRange.FixingDayOffsetBusinessDayConvention, fraInputRange.FixingDayOffsetBusinessCenters, fraInputRange.FixingDayOffsetDateRelativeTo); fra.dayCountFraction = DayCountFractionHelper.Parse(fraInputRange.DayCountFraction); IDayCounter dayCounter = DayCounterHelper.Parse(fra.dayCountFraction.Value); fra.calculationPeriodNumberOfDays = dayCounter.DayCount(fra.adjustedEffectiveDate.Value, fra.adjustedTerminationDate).ToString(CultureInfo.InvariantCulture); fra.notional = MoneyHelper.GetAmount(fraInputRange.NotionalAmount, fraInputRange.NotionalCurrency); fra.fixedRate = (decimal)fraInputRange.FixedRate; fra.fixedRateSpecified = true; fra.floatingRateIndex = FloatingRateIndexHelper.Parse(fraInputRange.FloatingRateIndex); fra.indexTenor = new[] { PeriodHelper.Parse(fraInputRange.IndexTenor) }; fra.fraDiscounting = fraInputRange.FraDiscounting; fra.fraDiscountingSpecified = true; PartyReference party1 = PartyReferenceFactory.Create("party1"); PartyReference party2 = PartyReferenceFactory.Create("party2"); fra.sellerPartyReference = party1; fra.buyerPartyReference = party2; if (bool.Parse(fraInputRange.IsParty1Buyer)) { fra.sellerPartyReference = party2; fra.buyerPartyReference = party1; } XsdClassesFieldResolver.TradeSetFra(trade, fra); trade.id = fraInputRange.TradeId; return(trade); }
public static FloatingRateCalculation Create(string floatingRateIndex, string indexTenor, decimal spreadInitialValue) { var result = new FloatingRateCalculation { floatingRateIndex = FloatingRateIndexHelper.Parse(floatingRateIndex), indexTenor = PeriodHelper.Parse(indexTenor), spreadSchedule = new[] { SpreadScheduleFactory.Create(spreadInitialValue) } }; return(result); }
/// <summary> /// Process a PPD Grid. The result is a Market structure that camn be published. /// </summary> /// <param name="logger">The logger</param> /// <param name="cache">The cache.</param> /// <param name="swapCurve">The latest rate curve</param> /// <param name="ppdGrid">The raw Points Per Day matrix supplied from the subscriber</param> /// <param name="id">The id to use in publishing the curve</param> /// <param name="nameSpace">The client namespace</param> /// <returns></returns> public static Market ProcessSwaption(ILogger logger, ICoreCache cache, Market swapCurve, SwaptionPPDGrid ppdGrid, string id, string nameSpace) { var mkt = swapCurve; var curve = new SimpleRateCurve(mkt); // List the values so we can build our ATM vols var atmVols = new Dictionary <SimpleKey, decimal>(); // Create a calendar to use to modify the date // default to be Sydney... IBusinessCalendar bc = BusinessCenterHelper.ToBusinessCalendar(cache, new[] { "AUSY" }, nameSpace); //BusinessCalendarHelper("AUSY"); // Use some logic to get the spot date to use // LPM Spot lag is 2 days (modfollowing) DateTime spotDate = curve.GetSpotDate(); // Extract each surface and build an ATM engine therefrom // Build a list of all possible engines foreach (string e in ExpiryKeys) { // Assume frequency = 4 months until 3 years tenor is reached Period expiration = PeriodHelper.Parse(e); double expiryYearFraction = expiration.ToYearFraction(); foreach (string t in TenorKeys) { // Create a Swaprate for each expiry/tenor pair // Assume frequency = 4 months until 3 years tenor is reached double tenorYearFraction = PeriodHelper.Parse(t).ToYearFraction(); int frequency = tenorYearFraction < 4 ? 4 : 2; // Calculation date // Discount factors // Offsets (elapsed days) var rates = new SwapRate(logger, cache, nameSpace, "AUSY", curve.BaseDate, "ACT/365.FIXED", curve.GetDiscountFactors(), curve.GetDiscountFactorOffsets(), frequency, BusinessDayConventionEnum.MODFOLLOWING); // Calculate the volatility given PPD and swap curve DateTime expiry = bc.Roll(expiration.Add(spotDate), BusinessDayConventionEnum.FOLLOWING); decimal vol = CalculateAtmVolatility(rates, expiry, ppdGrid, expiryYearFraction, tenorYearFraction); atmVols.Add(new SimpleKey(e, t), vol); } } var vols = new object[atmVols.Count + 1, 3]; var i = 1; vols[0, 0] = "Expiry"; vols[0, 1] = "Tenor"; vols[0, 2] = "0"; foreach (var key in atmVols.Keys) { vols[i, 0] = key.Expiry; vols[i, 1] = key.Tenor; vols[i, 2] = atmVols[key]; i++; } DateTime buildDateTime = swapCurve.Items1[0].buildDateTime; var volSurface = new VolatilitySurface(vols, new VolatilitySurfaceIdentifier(id), curve.BaseDate, buildDateTime); return(CreateMarketDocument(volSurface.GetFpMLData())); }