/// <summary> /// Creates the equity curve. /// </summary> /// <param name="logger">The logger.</param> /// <param name="cache">The cache.</param> /// <param name="nameSpace">THe client namespace</param> /// <param name="equityId">THe underlying curve asset.</param> /// <param name="fixingCalendar"></param> /// <param name="rollCalendar"></param> /// <param name="baseDate">The base date.</param> /// <param name="fxRates">The spot rate.</param> /// <param name="curveId">The curve id.</param> /// <param name="termCurve">The bootstrapped term curve.</param> /// <returns></returns> private static FxCurveValuation CreateEquityCurveValuation(ILogger logger, ICoreCache cache, string nameSpace, EquityCurveIdentifier equityId, IBusinessCalendar fixingCalendar, IBusinessCalendar rollCalendar, DateTime baseDate, FxRateSet fxRates, string curveId, TermCurve termCurve) { DateTime settlementDate = GetSettlementDate(logger, cache, nameSpace, equityId, fixingCalendar, rollCalendar, baseDate); var fxCurveValuation = new FxCurveValuation { baseDate = IdentifiedDateHelper.Create(baseDate), buildDateTime = baseDate, buildDateTimeSpecified = true, spotRate = fxRates, id = curveId, fxForwardCurve = termCurve, spotDate = IdentifiedDateHelper.Create("SettlementDate", settlementDate) }; return(fxCurveValuation); }
///// <summary> ///// Returns a list of non-interpolated values found in a immediate vicinity of requested point. ///// <remarks> ///// If a GetValue method returns a exact match - this method should be returning null. ///// </remarks> ///// </summary> ///// <param name="termCurve"></param> ///// <param name="baseDate"></param> ///// <param name="dayCounter"></param> ///// <param name="date"></param> ///// <returns></returns> //public static decimal InterpolateRate2(TermCurve termCurve, DateTime baseDate, IDayCounter dayCounter, DateTime date) //{ // var dates = termCurve.GetListTermDates(); // var values = termCurve.GetListMidValues(); // var index = Array.BinarySearch(dates.ToArray(), date); // if (index >= 0) // { // var result = termCurve.point[index].mid; // return result; // } // var nextIndex = ~index; // var prevIndex = nextIndex - 1; // var baseIndex = prevIndex - 1; // if (prevIndex == 0) // { // return values[prevIndex];//TODO check this. // } // var time1 = dayCounter.YearFraction(baseDate, dates[baseIndex]); // var time2 = dayCounter.YearFraction(baseDate, dates[nextIndex]); // var timei = dayCounter.YearFraction(baseDate, date); // var i1 = (time2 - timei) / (time2 - time1); // var i2 = (timei - time1) / (time2 - time1); // var r1 = (double)values[baseIndex]; // var r2 = (double)values[nextIndex]; // var rate = (i1 * r1 * time1 + i2 * r2 * time2) / timei; // return (decimal)rate; //} private static List <Tuple <DateTime, decimal> > ProcessTermCurve(TermCurve termCurve) { var result = new List <Tuple <DateTime, decimal> >(); var termDates = termCurve.GetListTermDates(); var values = termCurve.GetListMidValues(); int counter = 0; if (termDates.Count == values.Count) { foreach (var date in termDates) { var tuple = new Tuple <DateTime, decimal>(date, values[counter]); result.Add(tuple); counter++; } } return(result); }
private void Bootstrap(YieldCurveValuation yieldCurveValuation) { if (yieldCurveValuation == null || yieldCurveValuation.inputs != null && yieldCurveValuation.discountFactorCurve?.point == null) { CreateYieldCurve(); } var curveId = (RateCurveIdentifier)PricingStructureIdentifier; // Add extra input points for BaseCurve - if they exist List <BasicAssetValuation> assetQuotes = ((YieldCurveValuation)PricingStructureValuation).inputs.assetQuote.ToList(); AddBaseCurveInputs(assetQuotes); // Add extra input points for QuoteCurve - if they exist AddQuoteCurveInputs(assetQuotes); ((YieldCurveValuation)PricingStructureValuation).inputs.assetQuote = assetQuotes.ToArray(); TermCurve discountCurve = ((YieldCurveValuation)PricingStructureValuation).discountFactorCurve; SetInterpolator(discountCurve, curveId.Algorithm, PricingStructureTypeEnum.RateSpreadCurve); }
private void CreateYieldCurve() { var curveId = (RateCurveIdentifier)PricingStructureIdentifier; InterpolationMethod interpolationMethod = InterpolationMethodHelper.Parse(Holder.GetValue("BootstrapperInterpolation")); bool extrapolationPermitted = bool.Parse(Holder.GetValue("ExtrapolationPermitted")); TermPoint[] points = BaseCurve != null ? new RateBootstrapperNewtonRaphson().Bootstrap(PriceableRateAssets, BaseCurve, Holder) : null; //TermPoint[] points = BaseCurve != null ? RateXccySpreadBootstrapper.Bootstrap(PriceableRateAssets, BaseCurve, Holder) : null; var termCurve = new TermCurve { extrapolationPermitted = extrapolationPermitted, extrapolationPermittedSpecified = true, interpolationMethod = interpolationMethod, point = points }; CreatePricingStructure(curveId, termCurve, PriceableRateAssets, null); }
public void LoadInterestRateVolCurveTest() { CreateATMRateVolCurve("AUD", "3M", IrVolInstruments, IrVolValues, IrStrikes); var curve = (CapVolatilityCurve)CurveEngine.LoadVolatilityCurve(Market, "AUD", "3M", null); Assert.IsNotNull(curve); // 3M does exist Assert.AreEqual("3M", curve.GetPricingStructureId().Properties.GetString("IndexTenor", true)); //var baseDate = curve.GetBaseDate(); var expiration = VolatilitySurfaceHelper.GetDimensionValues(curve.GetVolatilityMatrix().dataPoints?.point, CubeDimension.Expiration); var volatilities = VolatilitySurfaceHelper.GetDimensionValues(curve.GetVolatilityMatrix().dataPoints?.point, CubeDimension.Volatility); var valArray = new List <Decimal>(); foreach (var vol in volatilities) { valArray.Add((decimal)vol); } var expiryArray = new List <TimeDimension>(); //var valArray = new List<Decimal>(); //Debug.Print(baseDate.ToString(CultureInfo.InvariantCulture)); foreach (var expiry in expiration) { //Temporary if (expiry is TimeDimension timeDimension) { expiryArray.Add(timeDimension); } //var date = expiry as DateTime? ?? baseDate.AddDays(1); //expiryArray.Add(date); //Debug.Print(expiry.ToString()); } var termPoints = TermPointsFactory.Create(expiryArray, valArray); var termCurve = new TermCurve { point = termPoints }; var output = XmlSerializerHelper.SerializeToString(termCurve); Debug.Print(output); }
private static object[,] TermCurveTo2DArray(TermCurve termCurve) { if (null != termCurve.point) { var result = new object[termCurve.point.Length, 2]; for (int i = 0; i < termCurve.point.Length; ++i) { var termPoint = termCurve.point[i]; result[i, 0] = TermPointHelper.GetDate(termPoint); result[i, 1] = termPoint.mid; } return(result); } // ReSharper disable RedundantIfElseBlock else // ReSharper restore RedundantIfElseBlock { return(null); } }
private static TermCurve Load(TermCurve termCurve, IList <DateTime> centralBankDates, DateTime baseDate, IDayCounter dayCounter) { var points = new List <TermPoint>(termCurve.point); var counter = 0; foreach (var point in termCurve.point) { var date = (DateTime)point.term.Items[0]; if (centralBankDates != null) { //dates are the central bank dates between the term curve node dates specified by the input instruments. //TODO currently the intermediate central bank dates are forgotten. //They need to be spliced into the term curve. //Also, the interpolation routine needs to be set to the appropriate back fill/forward fill logic. var dates = centralBankDates.Where(t => GetPreviousIndex(termCurve, t) == counter).ToList(); foreach (var centralBankdate in dates) { if (date == centralBankdate) { continue; } if (dates.IndexOf(centralBankdate) == 1) { var termPoint = TermPointFactory.Create(InterpolateRate(termCurve, baseDate, dayCounter, dates[0]), dates[0]); points.Insert(GetPreviousIndex(termCurve, date), termPoint); } else { var termPoint = TermPointFactory.Create(InterpolateRate2(termCurve, baseDate, dayCounter, centralBankdate), centralBankdate); points.Insert(GetPreviousIndex(termCurve, date), termPoint); } } } counter++; } //TODO does this fix the problem? //termCurve.point = points.ToArray(); return(termCurve); }
/// <summary> /// Initializes a new instance of the <see cref="FxCurve"/> class. /// </summary> /// <param name="logger">The logger.</param> /// <param name="cache">The cache.</param> /// <param name="nameSpace">THe client namespace</param> /// <param name="fpmlData">The FPML data.</param> /// <param name="properties">The properties.</param> /// <param name="fixingCalendar">The fixingCalendar.</param> /// <param name="rollCalendar">The rollCalendar.</param> public EquityCurve(ILogger logger, ICoreCache cache, string nameSpace, Pair <PricingStructure, PricingStructureValuation> fpmlData, NamedValueSet properties, IBusinessCalendar fixingCalendar, IBusinessCalendar rollCalendar) : base(logger, cache, nameSpace, fpmlData, new EquityCurveIdentifier(properties)) { PricingStructureData = new PricingStructureData(CurveType.Parent, AssetClass.Equity, properties); if (properties == null) { properties = PricingStructurePropertyHelper.FxCurve(fpmlData);//TODO } //Set the spot date; SettlementDate = GetSettlementDate(logger, cache, nameSpace, GetEquityCurveId(), fixingCalendar, rollCalendar, PricingStructureValuation.baseDate.Value); var fxCurveValuation = (FxCurveValuation)fpmlData.Second; // hack - set the base date - todo - is this the right place alex? PricingStructureValuation.baseDate = new IdentifiedDate { Value = PricingStructureIdentifier.BaseDate }; SetFpmlData(fpmlData); TermCurve termCurve = SetConfigurationData(); var bootstrap = PropertyHelper.ExtractBootStrapOverrideFlag(properties); var buildFlag = (fxCurveValuation.spotRate != null) && (fxCurveValuation.fxForwardCurve == null || fxCurveValuation.fxForwardCurve.point == null); // If there's no forward points - do build the curve. // - TODO what happened the central bank dates if ((bootstrap || buildFlag) && cache != null) { // if (BootstrapperName == "FastBootstrapper") //TODO PriceableEquityAssets = PriceableAssetFactory.CreatePriceableEquityAssets(logger, cache, nameSpace, fxCurveValuation.baseDate.Value, fxCurveValuation.spotRate, fixingCalendar, rollCalendar); fxCurveValuation.fxForwardCurve = termCurve; fxCurveValuation.fxForwardCurve.point = EquityBootstrapper.Bootstrap( PriceableEquityAssets, fxCurveValuation.baseDate.Value, fxCurveValuation.fxForwardCurve.extrapolationPermitted, fxCurveValuation.fxForwardCurve.interpolationMethod); } ((FxCurveValuation)PricingStructureValuation).fxForwardCurve = fxCurveValuation.fxForwardCurve; SetInterpolator(PricingStructureValuation.baseDate.Value); }
/// <summary> /// Generate a set of perturbed rate curves by just changing the market quote values of the priceable assets and /// thus not requiring the use of the cache or business calendars. /// </summary> /// <param name="baseDate"></param> /// <param name="value"></param> /// <param name="assetPosition"></param> /// <param name="priceableRateAssets"></param> /// <param name="extrapolationPermitted"></param> /// <param name="interpolationMethod"></param> /// <param name="tolerance"></param> /// <returns></returns> public static TermCurve PerturbSpecificAsset(DateTime baseDate, Decimal value, int assetPosition, List <IPriceableRateAssetController> priceableRateAssets, bool extrapolationPermitted, InterpolationMethod interpolationMethod, double tolerance) { //Set up the new term curve. var termCurve = new TermCurve(); termCurve.extrapolationPermitted = extrapolationPermitted; termCurve.interpolationMethod = interpolationMethod; //Modify the quotes. if (priceableRateAssets != null && assetPosition <= priceableRateAssets.Count) { //Perturb the aset quote. var quote = priceableRateAssets[assetPosition].MarketQuote.value; var pertrubedQuote = priceableRateAssets[assetPosition].MarketQuote.value + value; priceableRateAssets[assetPosition].MarketQuote.value = pertrubedQuote; termCurve.point = RateBootstrapper.Bootstrap(priceableRateAssets, baseDate, extrapolationPermitted, interpolationMethod, tolerance); //Reset the old value. priceableRateAssets[assetPosition].MarketQuote.value = quote; } return(termCurve); }
private void InitialiseInstance(ILogger logger, ICoreCache cache, string nameSpace, NamedValueSet properties, FxRateSet assetSet, IBusinessCalendar fixingCalendar, IBusinessCalendar rollCalendar) { PricingStructureData = new PricingStructureData(CurveType.Parent, AssetClass.Equity, properties); var curveId = new EquityCurveIdentifier(properties); PricingStructureIdentifier = curveId; Holder = new PricingStructureAlgorithmsHolder(logger, cache, nameSpace, curveId.PricingStructureType, curveId.Algorithm); DateTime baseDate = PricingStructureIdentifier.BaseDate; //Set the spot date; SettlementDate = GetSettlementDate(logger, cache, nameSpace, GetEquityCurveId(), fixingCalendar, rollCalendar, baseDate); //TODO //FixingCalendar = null; //RollCalendar = null; // The bootstrapper to use BootstrapperName = Holder.GetValue("Bootstrapper"); Tolerance = double.Parse(Holder.GetValue("Tolerance")); bool extrapolationPermitted = bool.Parse(Holder.GetValue("ExtrapolationPermitted")); InterpolationMethod interpolationMethod = InterpolationMethodHelper.Parse(Holder.GetValue("BootstrapperInterpolation")); var termCurve = new TermCurve { extrapolationPermitted = extrapolationPermitted, extrapolationPermittedSpecified = true, interpolationMethod = interpolationMethod }; PriceableEquityAssets = PriceableAssetFactory.CreatePriceableEquityAssets(logger, cache, nameSpace, baseDate, assetSet, fixingCalendar, rollCalendar); termCurve.point = EquityBootstrapper.Bootstrap(PriceableEquityAssets, baseDate, termCurve.extrapolationPermitted, termCurve.interpolationMethod, Tolerance); // Pull out the fx curve and fx curve valuation Pair <PricingStructure, PricingStructureValuation> fpmlData = CreateFpmlPair(logger, cache, nameSpace, baseDate, (EquityCurveIdentifier)PricingStructureIdentifier, assetSet, termCurve, fixingCalendar, rollCalendar); SetFpmlData(fpmlData); // Interpolate the DiscountFactor curve based on the respective curve interpolation SetInterpolator(baseDate); }
internal static TermCurve ConstructDiscountFactors(ILogger logger, ICoreCache cache, string nameSpace, TermCurve inputCurve, DateTime baseDate, string currency) { List <DateTime> dates = inputCurve.point.Select(a => (DateTime)a.term.Items[0]).ToList(); List <decimal> values = inputCurve.point.Select(a => a.mid).ToList(); var properties = new NamedValueSet(); properties.Set(CurveProp.PricingStructureType, PricingStructureTypeEnum.RateCurve.ToString()); properties.Set(CurveProp.Market, "ConstructDiscountFactors"); properties.Set(CurveProp.IndexTenor, "0M"); properties.Set(CurveProp.Currency1, currency); properties.Set(CurveProp.IndexName, "XXX-XXX"); properties.Set(CurveProp.Algorithm, "FastLinearZero"); properties.Set(CurveProp.BaseDate, baseDate); var curveId = new RateCurveIdentifier(properties); var algorithmHolder = new PricingStructureAlgorithmsHolder(logger, cache, nameSpace, curveId.PricingStructureType, curveId.Algorithm); var curve = new RateCurve(properties, algorithmHolder, dates, values); var termPoints = new List <TermPoint>(); for (DateTime date = dates.First(); date <= dates.Last(); date = date.AddMonths(1)) { var discountFactor = (decimal)curve.GetDiscountFactor(date); var timeDimension = new TimeDimension(); XsdClassesFieldResolver.TimeDimensionSetDate(timeDimension, date); var termPoint = new TermPoint { mid = discountFactor, midSpecified = true, term = timeDimension }; termPoints.Add(termPoint); } var termCurve = new TermCurve { point = termPoints.ToArray() }; return(termCurve); }
/// <summary> /// /// </summary> /// <param name="logger"></param> /// <param name="cache"></param> /// <param name="nameSpace"></param> /// <param name="fixingCalendar"></param> /// <param name="rollCalendar"></param> public sealed override void Build(ILogger logger, ICoreCache cache, string nameSpace, IBusinessCalendar fixingCalendar, IBusinessCalendar rollCalendar)//TODO need to define the cutover point. { var pricingStructureId = (RateCurveIdentifier)PricingStructureIdentifier; //Order the assets. PriceableRateSpreadAssets = PriceableRateSpreadAssets.OrderBy(a => a.GetRiskMaturityDate()).ToList(); //Generate the rate curve from the fx curve. var fxProps = ReferenceFxCurve.GetPricingStructureId().Properties; var quoteBasisEnum = PropertyHelper.ExtractQuoteBasis(fxProps); bool isBaseCurve = IsCurrency1RateCurve && quoteBasisEnum == QuoteBasisEnum.Currency2PerCurrency1; //var fxCurve = ReferenceFxCurve as FxCurve; //priceableAsset is PriceableCapRateAsset asset if (ReferenceFxCurve is FxCurve fxCurve)//fxCurve != null { var rateCurve = fxCurve.GenerateRateCurve(logger, cache, nameSpace, BaseCurve, isBaseCurve, pricingStructureId.GetProperties(), fixingCalendar, rollCalendar); //remove all points after the CutOverTerm. var rateCurvePoints = RemovePoints(rateCurve); //Retrieve the term curve. var termCurve = new TermCurve { extrapolationPermitted = rateCurve.GetTermCurve().extrapolationPermitted, extrapolationPermittedSpecified = rateCurve.GetTermCurve().extrapolationPermittedSpecified, interpolationMethod = rateCurve.GetTermCurve().interpolationMethod, point = rateCurvePoints }; //Get the reference interpolated curve. termCurve.point = RateXccySpreadBootstrapper.Bootstrap(PriceableRateSpreadAssets, Currency2Curve, pricingStructureId.BaseDate, termCurve); CreatePricingStructure(pricingStructureId, termCurve, PriceableAssetFactory.Parse(PriceableRateSpreadAssets)); } SetInterpolator(Currency2Curve, pricingStructureId.PricingStructureType); }
//TODO this is not yet implemented. FIX IT! internal void SetSpreadInterpolator(TermCurve discountFactorCurve, string algorithm, PricingStructureTypeEnum psType) { var curveId = (RateCurveIdentifier)PricingStructureIdentifier; // The underlying curve and associated compounding frequency (compounding frequency required when underlying curve is a ZeroCurve) CompoundingFrequency = EnumHelper.Parse <CompoundingFrequencyEnum>(Holder.GetValue("CompoundingFrequency")); UnderlyingInterpolatedCurve = Holder.GetValue("UnderlyingCurve"); //TODO this redundant. var interpDayCounter = Actual365.Instance; var underlyingCurve = ParseUnderlyingCurve(UnderlyingInterpolatedCurve); // interpolate the DiscountFactor curve based on the respective curve interpolation if (underlyingCurve != UnderlyingCurveTypes.ZeroCurve) { Interpolator = new TermCurveInterpolator(discountFactorCurve, GetBaseDate(), interpDayCounter); } // otherwise interpolate our underlying curve will be a zero curve else { var zeroCurve = new ZeroRateCurve { rateCurve = YieldCurveAnalytics.ToZeroCurve(discountFactorCurve, GetBaseDate(), CompoundingFrequency, DayCounter) }; zeroCurve.rateCurve.interpolationMethod = InterpolationMethodHelper.Parse(Holder.GetValue("CurveInterpolation")); zeroCurve.compoundingFrequency = FpML.V5r3.Reporting.CompoundingFrequency.Create(CompoundingFrequency); GetYieldCurveValuation().zeroCurve = zeroCurve; if (curveId.Algorithm == "SpreadInterpolation") { } else { Interpolator = new TermCurveInterpolator(GetYieldCurveValuation().zeroCurve.rateCurve, GetBaseDate(), interpDayCounter); }//TODO this is where to add the spread stuff. } }
///<summary> ///</summary> ///<param name="discountCurve"></param> ///<param name="baseDate"></param> ///<param name="forwardRateTenor"></param> ///<param name="priceableXibor"></param> ///<returns></returns> public TermCurve ToPriceableXiborForwardCurve(TermCurve discountCurve, DateTime baseDate, Period forwardRateTenor, PriceableXibor priceableXibor) //TODO { //CompoundingFrequency frequency = CompoundingFrequencyHelper.Create("Annual"); var dates = discountCurve.GetListTermDates(); var yearFractions = new List <double>(); foreach (var date in dates) { var yearFraction = (date - baseDate).TotalDays / 365.0;//TODO extend this with a general daycountraction. yearFractions.Add(yearFraction); } var midValues = discountCurve.GetListMidValues(); var discountFactors = new List <double>(Array.ConvertAll(midValues.ToArray(), Convert.ToDouble)); var forwardTermCurve = TermCurve.Create(new List <TermPoint>()); var index = 0; foreach (var startOfPeriodDateTime in dates) { var yearFractionsbeginPeriod = yearFractions[index]; var endOfPeriodDateTime = forwardRateTenor.Add(startOfPeriodDateTime); var yearFractionAtEndOfPeriod = (endOfPeriodDateTime - baseDate).TotalDays / 365.0; //get df corresponding to end of period // IInterpolation interpolation = new LinearRateInterpolation(); interpolation.Initialize(yearFractions.ToArray(), discountFactors.ToArray()); var dfAtEndOfPeriod = interpolation.ValueAt(yearFractionAtEndOfPeriod, true); var dfAtTheBeginingOfPeriod = discountFactors[index]; var forwardRate = (dfAtTheBeginingOfPeriod / dfAtEndOfPeriod - 1) / (yearFractionAtEndOfPeriod - yearFractionsbeginPeriod); var zeroPoint = TermPointFactory.Create(Convert.ToDecimal(forwardRate), startOfPeriodDateTime); forwardTermCurve.Add(zeroPoint); ++index; } return(forwardTermCurve); }
private static Pair <PricingStructure, PricingStructureValuation> CreateFpmlPair(ILogger logger, ICoreCache cache, string nameSpace, DateTime baseDate, EquityCurveIdentifier curveId, FxRateSet assetSet, TermCurve termCurve, IBusinessCalendar fixingCalendar, IBusinessCalendar rollCalendar) { FpML.V5r10.Reporting.FxCurve fxCurve = CreateEquityCurve(curveId.Id, curveId.CurveName, curveId.Currency); FxCurveValuation fxCurveValuation = CreateEquityCurveValuation(logger, cache, nameSpace, curveId, fixingCalendar, rollCalendar, baseDate, assetSet, fxCurve.id, termCurve); return(new Pair <PricingStructure, PricingStructureValuation>(fxCurve, fxCurveValuation)); }
/// <summary> /// Gets the quoted asset set. /// </summary> /// <param name="baseDate"></param> /// <param name="values"></param> /// <param name="priceableRateAssets"></param> /// <param name="extrapolationPermitted"></param> /// <param name="interpolationMethod"></param> /// <param name="tolerance"></param> /// <returns></returns> public static TermCurve PerturbAllAssets(DateTime baseDate, Decimal[] values, List <IPriceableRateAssetController> priceableRateAssets, bool extrapolationPermitted, InterpolationMethod interpolationMethod, double tolerance) { //Set up the new term curve. var termCurve = new TermCurve { extrapolationPermitted = extrapolationPermitted, interpolationMethod = interpolationMethod }; //Modify the quotes. if (priceableRateAssets != null) { var quotes = new List <decimal>(); var numControllers = priceableRateAssets.Count; var valuesArray = new decimal[numControllers]; if (values.Length == numControllers) { valuesArray = values; } if (values.Length < numControllers) { for (var i = 0; i < values.Length; i++) { valuesArray[i] = values[i]; } for (var i = values.Length; i < numControllers; i++) { valuesArray[i] = values[values.Length - 1]; } } else { for (var i = 0; i < numControllers; i++) { valuesArray[i] = values[i]; } } var index = 0; foreach (var rateController in priceableRateAssets) { //Perturb the asset quote. var quote = rateController.MarketQuote.value; quotes.Add(quote); var perturbedQuote = quote + valuesArray[index]; rateController.MarketQuote.value = perturbedQuote; index++; } termCurve.point = RateBootstrapper.Bootstrap(priceableRateAssets, baseDate, extrapolationPermitted, interpolationMethod, tolerance); index = 0; foreach (var rateController in priceableRateAssets) { //Reset the asset quote. rateController.MarketQuote.value = quotes[index]; index++; } } return(termCurve); }
/// <summary> /// Creates the pricing structure with ADDITIONAL /// </summary> /// <param name="baseDate">The base date.</param> /// <param name="curveId">The curve id.</param> /// <param name="assetSet">The FxRateSet.</param> /// <param name="termCurve">The bootstrapped term curve.</param> /// <returns></returns> private static Pair <PricingStructure, PricingStructureValuation> CreateFpMLPair(DateTime baseDate, PricingStructureIdentifier curveId, FxRateSet assetSet, TermCurve termCurve) { var commodityCurve = CreateCommodityCurve(curveId.Id, curveId.CurveName, curveId.Currency); var commodityCurveValuation = CreateCommodityCurveValuation(baseDate, assetSet, commodityCurve.id, termCurve); return(new Pair <PricingStructure, PricingStructureValuation>(commodityCurve, commodityCurveValuation)); }
/// <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(); } }
//TODO add EOM, EOQ and EOY perturbation: this transfers the step to the specific day. //Also needs to add EOM swaps to the asset config file. /// <summary> /// The main ctor. /// </summary> /// <param name="termCurve"></param> /// <param name="baseDate"></param> /// <param name="turnDates"></param> /// <param name="dayCounter"></param> public TurnInterpolator(TermCurve termCurve, DateTime baseDate, DateTime[] turnDates, IDayCounter dayCounter) : base(ConvertTermCurve(termCurve, baseDate, turnDates, dayCounter), baseDate, dayCounter) { TurnDates = turnDates; TermCurve = InterpolateTurnPoints(termCurve, turnDates, baseDate, dayCounter); }
/// <summary> /// Determines whether extrapolation is permitted. /// </summary> /// <param name="termCurve"></param> /// <returns></returns> public static bool IsExtrapolationPermitted(TermCurve termCurve) { bool isExtrapolationPermitted = termCurve.extrapolationPermittedSpecified && termCurve.extrapolationPermitted; return(isExtrapolationPermitted); }
private static TermCurve InterpolateGapStepTermPoints(string centralBankName, TermCurve termCurve, IList <DateTime> centralBankDates, DateTime baseDate, IDayCounter dayCounter) { //Step 1. Insert the extra points. var resultTermCurve = LoadAndSort(centralBankName, termCurve, centralBankDates, baseDate, dayCounter); //Step 2. SortPoints the term curve if necessary. return(resultTermCurve); }
/// <summary> /// The main ctor. /// </summary> /// <param name="termCurve"></param> /// <param name="baseDate"></param> /// <param name="dayCounter"></param> public TermCurveInterpolator(TermCurve termCurve, DateTime baseDate, IDayCounter dayCounter) : base(Converter(termCurve, baseDate, dayCounter), InterpolationHelper(termCurve), IsExtrapolationPermitted(termCurve)) { }
/// <summary> /// Creates the yield curve valuation. /// </summary> /// <param name="curveId"></param> /// <param name="quotedAssetSet">The quoted asset set.</param> /// <param name="commodityurveId">The commodity curve id.</param> /// <param name="forwardCurve">The curve</param> /// <returns></returns> protected static FxCurveValuation CreateCommodiyCurveValuation(PricingStructureIdentifier curveId, FxRateSet quotedAssetSet, string commodityurveId, TermCurve forwardCurve) { var yieldCurveValuation = new FxCurveValuation { baseDate = IdentifiedDateHelper.Create(curveId.BaseDate), buildDateTime = curveId.BuildDateTime, buildDateTimeSpecified = true, spotRate = quotedAssetSet, id = commodityurveId, definitionRef = curveId.PricingStructureType.ToString(), fxForwardCurve = forwardCurve }; return(yieldCurveValuation); }
/// <summary> /// Bootstraps the specified priceable spread rate assets. /// </summary> /// <param name="priceableAssets">The priceable assets.</param> /// <param name="referenceCurve">The reference curve.</param> /// <param name="baseDate">The base date.</param> /// <param name="termCurve">The term Curve with pre-existing points.</param> /// <returns></returns> public static TermPoint[] Bootstrap(IList <IPriceableRateSpreadAssetController> priceableAssets, RateCurve referenceCurve, DateTime baseDate, TermCurve termCurve) { return(Bootstrap(priceableAssets, referenceCurve, baseDate, termCurve, referenceCurve.Tolerance)); }
/// <summary> /// The main ctor. /// </summary> /// <param name="termCurve">a term curve containing the spread values at each provided node.</param> /// <param name="baseDate">The base date.</param> public SpreadInterpolator(TermCurve termCurve, DateTime baseDate) : base(termCurve, baseDate, Actual365.Instance) { }
/// <summary> /// Creates the pricing structure. /// </summary> protected void CreatePricingStructure(EquityCurveIdentifier curveId, TermCurve termCurve, IEnumerable <IPriceableEquityAssetController> priceableEquityAssets) { FxRateSet quotedAssetSet = priceableEquityAssets != null?PriceableAssetFactory.Parse(priceableEquityAssets) : null; CreatePricingStructure(curveId, termCurve, quotedAssetSet); }
/// <summary> /// Creates the discrete curve. /// </summary> /// <param name="termCurve"></param> /// <param name="baseDate"></param> /// <param name="dayCounter"></param> /// <returns></returns> public static DiscreteCurve Converter(TermCurve termCurve, DateTime baseDate, IDayCounter dayCounter) { var curve = new DiscreteCurve(PointCurveHelper(termCurve, baseDate, dayCounter)); return(curve); }
///<summary> ///</summary> ///<param name="termCurve"></param> ///<param name="baseDate"></param> ///<param name="dayCounter"></param> public FxCurveInterpolator(TermCurve termCurve, DateTime baseDate, IDayCounter dayCounter) : base(CurveHelper.Converter(termCurve, baseDate, dayCounter), InterpolationFactory.Create(termCurve), CurveHelper.IsExtrapolationPermitted(termCurve)) { }
/// <summary> /// Bootstraps the specified priceable assets. /// </summary> /// <param name="priceableAssets">The priceable assets.</param> /// <param name="referenceCurve">The reference curve.</param> /// <param name="baseDate">The base date.</param> /// <param name="termCurve">The term Curve with pre-existing points. This will not work if there are no points.</param> /// <param name="tolerance">Solver tolerance to use.</param> /// <returns></returns> public static TermPoint[] Bootstrap(IList <IPriceableRateSpreadAssetController> priceableAssets, IRateCurve referenceCurve, DateTime baseDate, TermCurve termCurve, Double tolerance) { const double min = 0.000000001; const double max = 1; Dictionary <DateTime, Pair <string, decimal> > items = new Dictionary <DateTime, Pair <string, decimal> > (); // Add the elements (date : discount factor) to the list IDictionary <DateTime, double> dfs = new Dictionary <DateTime, double>(); foreach (var point in termCurve.point) { dfs.Add((DateTime)point.term.Items[0], (double)point.mid); items.Add((DateTime)point.term.Items[0], new Pair <string, decimal>(point.id, point.mid)); } var solver = new Brent(); foreach (var priceableAsset in priceableAssets) { var assetMaturityDate = priceableAsset.GetRiskMaturityDate(); if (dfs.ContainsKey(assetMaturityDate)) { continue; } //The first guess, which should be correct for all priceable assets with analytical solutions that have been implemented. //So far this is only wrt Depos and Futures...This now should automatically extrapolate the required discount factor on a flat rate basis. dfs.Add(assetMaturityDate, (double)priceableAsset.CalculateDiscountFactorAtMaturity(referenceCurve)); var objectiveFunction = new RateSpreadAssetQuote(priceableAsset, referenceCurve, baseDate, termCurve.extrapolationPermitted, dfs, tolerance); // check accuracy so that solver is only called if outside the tolerance. if (!objectiveFunction.InitialValue()) { dfs[assetMaturityDate] = solver.Solve(objectiveFunction, tolerance, dfs[assetMaturityDate], min, max); } items.Add(assetMaturityDate, new Pair <string, decimal>(priceableAsset.Id, (decimal)dfs[assetMaturityDate])); } return(TermPointsFactory.Create(items)); }