public static Trade CreateFraTrade(string tradeId, RequiredIdentifierDate adjustedEffectiveDate, DateTime adjustedTerminationDate, AdjustableDate paymentDate, RelativeDateOffset fixingDayOffset, DayCountFraction dayCountFraction, decimal notionalAmount, string notionalCurrency, decimal fixedRate, string floatingRateIndex, string indexTenor, FraDiscountingEnum fraDiscounting) { var trade = new Trade(); var fra = new Fra { adjustedEffectiveDate = adjustedEffectiveDate, adjustedTerminationDate = adjustedTerminationDate, adjustedTerminationDateSpecified = true, paymentDate = paymentDate, Items = new object[] { new ProductType { Value = ProductTypeSimpleEnum.FRA.ToString() } }, ItemsElementName = new[] { ItemsChoiceType2.productType } }; if ("resetDate" != fixingDayOffset.dateRelativeTo.href) { throw new ArgumentException("The fixing date must be specified as 'resetDate'-relative!", nameof(fixingDayOffset)); } fra.fixingDateOffset = fixingDayOffset; fra.dayCountFraction = dayCountFraction; IDayCounter dayCounter = DayCounterHelper.Parse(fra.dayCountFraction.Value); fra.calculationPeriodNumberOfDays = dayCounter.DayCount(fra.adjustedEffectiveDate.Value, fra.adjustedTerminationDate).ToString(CultureInfo.InvariantCulture); fra.notional = MoneyHelper.GetAmount(notionalAmount, notionalCurrency); fra.fixedRate = fixedRate; fra.fixedRateSpecified = true; fra.floatingRateIndex = FloatingRateIndexHelper.Parse(floatingRateIndex); fra.indexTenor = new[] { PeriodHelper.Parse(indexTenor) }; fra.fraDiscounting = fraDiscounting; fra.fraDiscountingSpecified = true; PartyReference party1 = PartyReferenceFactory.Create("party1"); PartyReference party2 = PartyReferenceFactory.Create("party2"); fra.sellerPartyReference = party2; fra.buyerPartyReference = party1; XsdClassesFieldResolver.TradeSetFra(trade, fra); trade.id = tradeId; return(trade); }
public void UnadjustedDatesSchedule2() { DateTime effectiveDate = new DateTime(2008, 07, 9); DateTime terminationDate = new DateTime(2011, 07, 11); Period periodInterval = PeriodHelper.Parse("3M"); RollConventionEnum rollDayConvention = RollConventionEnum.Item7; DateTime firstRegularPeriodStartDate = effectiveDate; DateTime lastRegularPeriodEndDate = terminationDate; //Back|Forward are same string expectedDates = "9/07/2008;7/10/2008;7/01/2009;7/04/2009;7/07/2009;7/10/2009;7/01/2010;7/04/2010;7/07/2010;7/10/2010;7/01/2011;7/04/2011;11/07/2011"; DateTime[] bdates = DateScheduler.GetUnadjustedDatesFromTerminationDate(effectiveDate, terminationDate, periodInterval, rollDayConvention, out firstRegularPeriodStartDate, out lastRegularPeriodEndDate); //bdates = AdjustDates(bdates, BusinessDayConventionEnum.MODFOLLOWING, "AUSY"); Validate(expectedDates, bdates); DateTime[] fdates = DateScheduler.GetUnadjustedDatesFromEffectiveDate(effectiveDate, terminationDate, periodInterval, rollDayConvention, out firstRegularPeriodStartDate, out lastRegularPeriodEndDate); //fdates = AdjustDates(fdates, BusinessDayConventionEnum.MODFOLLOWING, "AUSY"); Validate(expectedDates, fdates); }
/// <summary> /// Parses the string info into an asset. /// </summary> /// <param name="bondTypeId">The type of bond.</param> /// <param name="coupon">The coupon rate</param> /// <param name="daycount">The daycount.</param> /// <param name="frequency">The frequency.</param> /// <param name="ytm">The ytm.</param> /// <param name="maturityDate">The maturity date.</param> /// <returns></returns> public static Pair <Asset, BasicAssetValuation> ParseBond(string bondTypeId, DateTime maturityDate, decimal coupon, string daycount, string frequency, decimal ytm) { const string rateQuotationType = "MarketQuote"; var bondId = bondTypeId + '-' + coupon + '-' + maturityDate.ToShortDateString(); var underlyingAsset = new Bond { id = bondId, maturity = maturityDate, maturitySpecified = true, couponRate = coupon, couponRateSpecified = true, dayCountFraction = DayCountFractionHelper.Parse(daycount), paymentFrequency = PeriodHelper.Parse(frequency) }; var listBasicQuotations = new List <BasicQuotation> { BasicQuotationHelper.Create(ytm, rateQuotationType, "DecimalRate") }; return(new Pair <Asset, BasicAssetValuation>(underlyingAsset, BasicAssetValuationHelper.Create(underlyingAsset.id, listBasicQuotations.ToArray()))); }
public static RateIndex Parse(string floatingRateIndex, string currency, string dayCountFraction, string term) { var rateIndex = new RateIndex { currency = new IdentifiedCurrency { Value = currency }, dayCountFraction = DayCountFractionHelper.Parse(dayCountFraction), floatingRateIndex = FloatingRateIndexHelper.Parse(floatingRateIndex), }; Period period = null; if (term != null) { period = PeriodHelper.Parse(term); } rateIndex.term = period; return(rateIndex); }
/// <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 pary</param> public ExpiryTenorStrikeKey(string expiry, string tenor, decimal 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; } _strike = strike; }
public static RateIndex Parse(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 = instrumentId, instrumentId = InstrumentIdArrayHelper.Parse(instrumentId), paymentFrequency = PeriodHelper.Parse(paymentFrequency), term = PeriodHelper.Parse(term) }; return(rateIndex); }
/// <summary> /// Calculates the specified model data. /// </summary> /// <param name="modelData">The model data.</param> /// <returns></returns> public override AssetValuation Calculate(IInstrumentControllerData modelData) { ModelData = modelData; AnalyticModelParameters = null; CalculationResults = null; UpdateBucketingInterval(ModelData.ValuationDate, PeriodHelper.Parse(CDefaultBucketingInterval)); var quotes = ModelData.AssetValuation.quote.ToList(); ModelData.AssetValuation.quote = quotes.ToArray(); // 1. First derive the analytics to be evaluated via the stream controller model // NOTE: These take precendence of the child model metrics if (AnalyticsModel == null) { AnalyticsModel = new FraInstrumentAnalytic(); } FloatingCoupon.PricingStructureEvolutionType = PricingStructureEvolutionType; FloatingCoupon.BucketedDates = BucketedDates; FloatingCoupon.Multiplier = Multiplier; var childControllers = new List <InstrumentControllerBase>(GetChildren()); //The assetValuation list. ChildValuations = new List <AssetValuation>(); // 2. Now evaluate only the child specific metrics (if any) if (modelData.MarketEnvironment.GetType() == typeof(MarketEnvironment)) { foreach (var cashflow in childControllers) { ChildValuations.Add(cashflow.Calculate(modelData)); } } else { ChildValuations = EvaluateChildMetrics(childControllers, modelData, Metrics); } CalculationPerfomedIndicator = true; ChildValuations[0].id = Id; return(ChildValuations[0]);// fraValuation; }
/// <summary> /// Creates a PricingDataPointCoordinate. /// </summary> /// <param name="expiry"></param> /// <param name="term"></param> /// <param name="strike"></param> /// <returns></returns> public static PricingDataPointCoordinate Create(string expiry, string term, decimal strike) { var coordinate = new PricingDataPointCoordinate(); var pExpiry = expiry != null?PeriodHelper.Parse(expiry) : null; var pTerm = term != null?PeriodHelper.Parse(term) : null; var pStrike = strike; 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 }; return(coordinate); }
/// <summary> /// Initializes a new instance of the <see cref="PriceableCommoditySpot"/> class. /// </summary> /// <param name="notionalAmount"></param> /// <param name="baseDate"></param> /// <param name="term">The 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 PriceableCommodityForward(DateTime baseDate, decimal notionalAmount, string term, CommoditySpotNodeStruct 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; } Tenor = PeriodHelper.Parse(term); NotionalAmount = notionalAmount; CommodityAsset = nodeStruct.Commodity; BaseDate = baseDate; SpotDateOffset = nodeStruct.SpotDate; //FixingCalendar = BusinessCenterHelper.ToBusinessCalendar(SpotDateOffset.businessCenters); var spotDate = GetSpotDate(baseDate, fixingCalendar, SpotDateOffset); RiskMaturityDate = GetForwardDate(spotDate, paymentCalendar, Tenor, SpotDateOffset.businessDayConvention); SetRate(commodityForward); }
/// <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, string strike, string generic) { var coordinate = new PricingDataPointCoordinate(); var pExpiry = expiry != null?PeriodHelper.Parse(expiry) : null; var pTerm = term != null?PeriodHelper.Parse(term) : null; 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 } }; } if (strike != null) { coordinate.strike = new[] { decimal.Parse(strike) }; } if (pGeneric != null) { coordinate.generic = new[] { pGeneric } } ; return(coordinate); }
/// <summary> /// Adds the period. /// </summary> /// <param name="startDate">The start date.</param> /// <param name="tenorString">The tenor string.</param> /// <param name="calendar">The calendar.</param> /// <param name="rollConvention">The roll convention.</param> /// <param name="dayType">Type of the day.</param> /// <returns></returns> public static DateTime AddPeriod(DateTime startDate, string tenorString, IBusinessCalendar calendar, string rollConvention, string dayType) { const string defaultRollConvention = "FOLLOWING"; if (calendar == null) { calendar = new Hell(); } if (String.IsNullOrEmpty(rollConvention)) { rollConvention = defaultRollConvention; } Period rollPeriod = PeriodHelper.Parse(tenorString); if (String.IsNullOrEmpty(dayType)) { dayType = DayTypeStringFromRollPeriodInterval(rollPeriod); } var dayTypeEnum = (DayTypeEnum)Enum.Parse(typeof(DayTypeEnum), dayType, true); BusinessDayConventionEnum businessDayConvention = BusinessDayConventionHelper.Parse(rollConvention); DateTime endDate = calendar.Advance(startDate, OffsetHelper.FromInterval(rollPeriod, dayTypeEnum), businessDayConvention); return(endDate); }
/// <summary> /// Initializes a new instance of the <see cref="RateXccySpreadCurve"/> class, /// by applying spreads to an existing RateCurve. Using FX Curve to create synthetic swaps /// for the period under 1Y. /// </summary> /// <param name="logger">The logger.</param> /// <param name="cache">The cache.</param> /// <param name="nameSpace">THe client namespace</param> /// <param name="properties">The properties of the new curve. One of the mandatory properties for this curve type: /// CutOverTerm, is the tenor at which point all Fx Curve points are removed form the RateXccyCurve bootstrap. /// Normally this is 1Y.</param> /// <param name="currency1Curve">The base zero curve.</param> /// <param name="fxCurve">The FX curve, used for constructing synthetic deposits. The fx points map from the base curve to the non-base curve.</param> /// <param name="currency2Curve">The non-Base Curve.</param> /// <param name="spreadInstruments">The spread instruments and their values.</param> /// <param name="fixingCalendar">The fixingCalendar.</param> /// <param name="rollCalendar">The rollCalendar.</param> public RateXccySpreadCurve(ILogger logger, ICoreCache cache, String nameSpace, NamedValueSet properties, RateCurve currency1Curve, IFxCurve fxCurve, RateCurve currency2Curve, QuotedAssetSet spreadInstruments, IBusinessCalendar fixingCalendar, IBusinessCalendar rollCalendar) : base(logger, cache, nameSpace, new RateCurveIdentifier(properties)) { //Set the base curve. BaseCurve = currency1Curve; ReferenceCurveId = BaseCurve.GetPricingStructureId(); //PricingStructureIdentifier = new RateCurveIdentifier(properties); Currency2Curve = currency2Curve; //Get the cut-over date. var cutOverTerm = properties.GetValue <string>("CutOverTerm"); if (cutOverTerm != null) { CutOverTerm = PeriodHelper.Parse(cutOverTerm); } //set the fx curve. ReferenceFxCurve = fxCurve; IsCurrency1RateCurve = properties.GetValue <bool>("Currency1RateCurve"); //Check the pricing structure type. var pricingStructureId = (RateCurveIdentifier)PricingStructureIdentifier; if (pricingStructureId.PricingStructureType != PricingStructureTypeEnum.RateXccyCurve || ReferenceFxCurve == null) { return; } //There must be a valid quoted asset set in order to bootstrap. if (!XsdClassesFieldResolver.QuotedAssetSetIsValid(spreadInstruments)) { return; } PriceableRateSpreadAssets = PriceableAssetFactory.CreatePriceableRateSpreadAssets(logger, cache, nameSpace, pricingStructureId.BaseDate, spreadInstruments, fixingCalendar, rollCalendar); Build(logger, cache, nameSpace, fixingCalendar, rollCalendar); }
public override AssetValuation Calculate(IInstrumentControllerData modelData) { ModelData = modelData; AnalyticModelParameters = null; CalculationResults = null; UpdateBucketingInterval(ModelData.ValuationDate, PeriodHelper.Parse(CDefaultBucketingInterval)); // 1. First derive the analytics to be evaluated via the stream controller model // NOTE: These take precedence of the child model metrics if (AnalyticsModel == null) { AnalyticsModel = new BondStreamAnalytic(); } var streamControllerMetrics = ResolveModelMetrics(AnalyticsModel.Metrics); AssetValuation streamValuation; // 2. Now evaluate only the child specific metrics (if any) foreach (var coupon in Coupons) { coupon.PricingStructureEvolutionType = PricingStructureEvolutionType; coupon.BucketedDates = BucketedDates; coupon.Multiplier = Multiplier; } var childControllers = new List <InstrumentControllerBase>(Coupons.ToArray()); //Now the stream analytics can be completed. var childValuations = EvaluateChildMetrics(childControllers, modelData, Metrics); var couponValuation = AssetValuationHelper.AggregateMetrics(childValuations, new List <string>(Metrics), PaymentCurrencies); var childControllerValuations = new List <AssetValuation> { couponValuation }; // Child metrics have now been calculated so we can now evaluate the stream model metrics if (streamControllerMetrics.Count > 0) { var reportingCurrency = ModelData.ReportingCurrency == null ? Currency : ModelData.ReportingCurrency.Value; var notionals = GetCouponNotionals(); var accrualFactors = GetCouponAccrualFactors(); var discountFactors = GetPaymentDiscountFactors(); var floatingNPV = AggregateMetric(InstrumentMetrics.FloatingNPV, childControllerValuations); var accrualFactor = AggregateMetric(InstrumentMetrics.AccrualFactor, childControllerValuations); //TODO need to set the notional amount and the weighting. Also amortisation?? IBondStreamParameters analyticModelParameters = new BondStreamParameters { Multiplier = Multiplier, CouponNotionals = notionals, Currency = Currency, ReportingCurrency = reportingCurrency, AccrualFactor = accrualFactor, FloatingNPV = floatingNPV, NPV = AggregateMetric(InstrumentMetrics.NPV, childControllerValuations), CouponYearFractions = accrualFactors, PaymentDiscountFactors = discountFactors, TargetNPV = floatingNPV }; CalculationResults = AnalyticsModel.Calculate <IBondStreamInstrumentResults, BondStreamInstrumentResults>(analyticModelParameters, streamControllerMetrics.ToArray()); // Now merge back into the overall stream valuation var streamControllerValuation = GetValue(CalculationResults, modelData.ValuationDate); streamValuation = AssetValuationHelper.UpdateValuation(streamControllerValuation, childControllerValuations, ConvertMetrics(streamControllerMetrics), new List <string>(Metrics), PaymentCurrencies); AnalyticModelParameters = analyticModelParameters; } else { streamValuation = AssetValuationHelper.AggregateMetrics(childControllerValuations, new List <string>(Metrics), PaymentCurrencies); } CalculationPerformedIndicator = true; streamValuation.id = Id; return(streamValuation); }
/// <summary> /// A basic ctor. /// </summary> /// <param name="baseDate"></param> /// <param name="tenor"></param> /// <param name="value"></param> public DateTimePoint1D(DateTime baseDate, string tenor, double value) : this(baseDate, PeriodHelper.Parse(tenor).Add(baseDate), value) { }
/// <summary> /// Calculates the specified model data. /// </summary> /// <param name="modelData">The model data.</param> /// <returns></returns> public override AssetValuation Calculate(IInstrumentControllerData modelData) { ModelData = modelData; AnalyticModelParameters = null; CalculationResults = null; UpdateBucketingInterval(ModelData.ValuationDate, PeriodHelper.Parse(CDefaultBucketingInterval)); // 1. First derive the analytics to be evaluated via the stream controller model // NOTE: These take precendence of the child model metrics if (AnalyticsModel == null) { AnalyticsModel = new SimpleIRSwaptionInstrumentAnalytic(); } var swaptionControllerMetrics = ResolveModelMetrics(AnalyticsModel.Metrics); var quotes = ModelData.AssetValuation.quote.ToList(); if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.BreakEvenRate.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.BreakEvenRate.ToString(), "DecimalValue"); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.NPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.NPV.ToString(), "DecimalValue"); quotes.Add(quote); } ModelData.AssetValuation.quote = quotes.ToArray(); AssetValuation swaptionValuation; //Sets the evolution type for calculations. Swap.PricingStructureEvolutionType = PricingStructureEvolutionType; Swap.BucketedDates = BucketedDates; if (PremiumPayments != null) { foreach (var payment in PremiumPayments) { payment.PricingStructureEvolutionType = PricingStructureEvolutionType; payment.BucketedDates = BucketedDates; } } //The assetValuation list. var childValuations = new List <AssetValuation>(); // 2. Now evaluate only the child specific metrics (if any) if (PremiumPayments != null) { var paymentControllers = new List <InstrumentControllerBase>(PremiumPayments); childValuations.AddRange(paymentControllers.Select(payment => payment.Calculate(modelData))); } var swapMetrics = Swap.Calculate(modelData); //We assume the fixed leg is always the first leg! var fixedLeg = Swap.GetLegs()[0].Calculate(modelData); var breakEvenRate = AssetValuationHelper.GetQuotationByMeasureType(swapMetrics, InstrumentMetrics.BreakEvenRate.ToString()).value; var timeToIndex = (Swap.EffectiveDate - ModelData.ValuationDate).Days / 365.0; //This is European only. var expiryTime = (ExerciseDates[0] - ModelData.ValuationDate).Days / 365.0; IVolatilitySurface indexVolSurface = null; if (modelData.MarketEnvironment is ISwapLegEnvironment streamMarket1) { indexVolSurface = streamMarket1.GetVolatilitySurface(); indexVolSurface.PricingStructureEvolutionType = PricingStructureEvolutionType; VolatilitySurfaceName = indexVolSurface.GetPricingStructureId().UniqueIdentifier; } else { if (!string.IsNullOrEmpty(VolatilitySurfaceName)) { indexVolSurface = (IVolatilitySurface)modelData.MarketEnvironment.GetPricingStructure(VolatilitySurfaceName); } } //Calculate the delta var delta = SimpleIRSwaptionInstrumentAnalytic.CalculateOptionDelta(IsCall, breakEvenRate, StrikeRate, expiryTime, timeToIndex, indexVolSurface); //Set the multiplier using the delta of the option. //Multiplier = delta;? Swap.Multiplier = System.Math.Abs(delta); //New function that converts the metrics by multiplying be the delta. var swapCalculations = Swap.Calculate(modelData); //childValuations.Add(swapCalculations); var childControllerValuations = AssetValuationHelper.AggregateMetrics(childValuations, new List <string>(Metrics), PaymentCurrencies); // modelData.ValuationDate); var streamAccrualFactor = AssetValuationHelper.GetQuotationByMeasureType(fixedLeg, InstrumentMetrics.AccrualFactor.ToString()); //TODO This is not correct! var npv = AssetValuationHelper.GetQuotationByMeasureType(childControllerValuations, InstrumentMetrics.NPV.ToString()); childValuations.Add(swapCalculations); // Child metrics have now been calculated so we can now evaluate the stream model metrics if (swaptionControllerMetrics.Count > 0) { //Get the market data. IFxCurve fxCurve = null; ISwaptionInstrumentParameters analyticModelParameters = new SwaptionInstrumentParameters { IsBought = IsBasePartyBuyer, IsCall = IsCall, SwapAccrualFactor = System.Math.Abs(streamAccrualFactor.value), Strike = StrikeRate, OtherNPV = npv.value, TimeToExpiry = (decimal)expiryTime, SwapBreakEvenRate = breakEvenRate, //OtherNPV = }; // Curve Related if (modelData.MarketEnvironment is ISwapLegEnvironment streamMarket) { analyticModelParameters.VolatilitySurface = indexVolSurface; //Check for currency. if (ModelData.ReportingCurrency != null) { if (ModelData.ReportingCurrency.Value != PaymentCurrencies[0])//This is an interest rate swap and so only has one currency. { fxCurve = streamMarket.GetReportingCurrencyFxCurve(); fxCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; } } } var analyticsModel = new SimpleIRSwaptionInstrumentAnalytic(ModelData.ValuationDate, (decimal)timeToIndex, StrikeRate, fxCurve, indexVolSurface); AnalyticsModel = analyticsModel; Volatility = analyticsModel.Volatility; AnalyticModelParameters = analyticModelParameters; CalculationResults = AnalyticsModel.Calculate <ISwaptionInstrumentResults, SwaptionInstrumentResults>(analyticModelParameters, swaptionControllerMetrics.ToArray()); // Now merge back into the overall stream valuation var swapControllerValuation = GetValue(CalculationResults, modelData.ValuationDate); //childValuations.Add(swapControllerValuation); childControllerValuations = AssetValuationHelper.AggregateMetrics(childValuations, new List <string>(Metrics), PaymentCurrencies);// modelData.ValuationDate); swaptionValuation = AssetValuationHelper.UpdateValuation(swapControllerValuation, childControllerValuations, ConvertMetrics(swaptionControllerMetrics), new List <string>(Metrics)); //swaptionValuation = AssetValuationHelper.AggregateMetrics(childValuations, new List<string>(Metrics), modelData.ValuationDate); } else { swaptionValuation = childControllerValuations; } CalculationPerfomedIndicator = true; swaptionValuation.id = Id; return(swaptionValuation); }
/// <summary> /// Initializes a new instance of the <see cref="PriceableIRCap"/> class. /// </summary> /// <param name="baseDate">The base date.</param> /// <param name="effectiveDate">The effective Date.</param> /// <param name="term">The cap term.</param> /// <param name="strike">The strike for each caplet.</param> /// <param name="lastResets">A list of reset rates. This may be null.</param> /// <param name="includeStubFlag">A flag: include the first stub period or not.</param> /// <param name="paymentFrequency">The caplet frequency.</param> /// <param name="rollBackward">A flag which determines whether to roll /// the dates: Backward or Forward. Currency this is ignored.</param> /// <param name="resetOffset">The relative date offset for all the fixings.</param> /// <param name="paymentBusinessDayAdjustments">The payment business day adjustments.</param> /// <param name="fixingCalendar">The fixing Calendar.</param> /// <param name="paymentCalendar">The payment Calendar.</param> /// <param name="capCalculation">The cap calculation.</param> public PriceableIRCap(DateTime baseDate, DateTime effectiveDate, string term, Double strike, List <double> lastResets, Boolean includeStubFlag, string paymentFrequency, Boolean rollBackward, RelativeDateOffset resetOffset, BusinessDayAdjustments paymentBusinessDayAdjustments, Calculation capCalculation, IBusinessCalendar fixingCalendar, IBusinessCalendar paymentCalendar) : base(baseDate, paymentBusinessDayAdjustments, resetOffset, capCalculation, null) { Id = "Local"; SimpleIRCap = new SimpleIRSwap { dayCountFraction = capCalculation.dayCountFraction }; ResetRates = lastResets; var unadjustedDates = Analytics.Schedulers.DateScheduler.GetUnadjustedDateSchedule(effectiveDate, PeriodHelper.Parse(term), PeriodHelper.Parse(paymentFrequency)); var adjustedPeriodDates = AdjustedDateScheduler.GetAdjustedDateSchedule(unadjustedDates, paymentBusinessDayAdjustments.businessDayConvention, paymentCalendar); RiskMaturityDate = adjustedPeriodDates[adjustedPeriodDates.Count - 1]; IncludeFirstPeriod = includeStubFlag; //if (!includeStubFlag) //{ // adjustedPeriodDates.RemoveAt(0); //} AdjustedStartDate = effectiveDate; AdjustedPeriodDates = adjustedPeriodDates; ExpiryDates = GetResetDates(AdjustedPeriodDates, fixingCalendar, resetOffset, true); OptionsExpiryDate = ExpiryDates[ExpiryDates.Count - 1]; IsCap = true; YearFractions = GetYearFractions(); Strikes = CreateList(strike, YearFractions.Count); Notionals = CreateList((double)InitialNotional, YearFractions.Count); if (DiscountingType != null) { ModelIdentifier = "DiscountCapAsset"; } }
/// <summary> /// Calculates the specified model data. /// </summary> /// <param name="modelData">The model data.</param>//TODO the floating delta? /// <returns></returns> public override AssetValuation Calculate(IInstrumentControllerData modelData) { ModelData = modelData; AnalyticModelParameters = null; AnalyticsModel = new FxRateCashflowAnalytic(); CalculationResults = null; YearFractionToCashFlowPayment = Convert.ToDecimal(CDefaultDayCounter.YearFraction(ModelData.ValuationDate, PaymentDate)); //Make sure there are some bucket dates even if not set previously. if (BucketedDates.Length < 1) { UpdateBucketingInterval(ModelData.ValuationDate, PeriodHelper.Parse(CDefaultBucketingInterval)); } IsRealised = HasBeenRealised(ModelData.ValuationDate); //Add the extra metrics required var quotes = ModelData.AssetValuation.quote.ToList(); if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, FloatingCashflowMetrics.NPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, FloatingCashflowMetrics.LocalCurrencyNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, FloatingCashflowMetrics.LocalCurrencyNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, FloatingCashflowMetrics.LocalCurrencyNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.RiskNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.NPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, FloatingCashflowMetrics.LocalCurrencyExpectedValue.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, FloatingCashflowMetrics.LocalCurrencyExpectedValue.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } //Check if risk calc are required. bool delta1PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta1PDH.ToString()) != null || AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta1PDH.ToString()) != null; //Check if risk calc are required. bool delta0PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta0PDH.ToString()) != null || AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta0PDH.ToString()) != null; ModelData.AssetValuation.quote = quotes.ToArray(); var metrics = ResolveModelMetrics(AnalyticsModel.Metrics); IFxCurve fxCurve = null; IRateCurve discountCurve = null; IFxCurve currencyCurve = null; var reportingCurrency = ModelData.ReportingCurrency == null ? PaymentCurrency.Value : ModelData.ReportingCurrency.Value; //Set the basic model. var analyticModelParameters = new FxRateCashflowParameters { Multiplier = Multiplier, ValuationDate = ModelData.ValuationDate, PaymentDate = PaymentDate, Currency = PaymentCurrency.Value, ReportingCurrency = reportingCurrency, NotionalAmount = PaymentAmount.amount, StartIndex = StartIndex, IsRealised = IsRealised, CurveYearFraction = YearFractionToCashFlowPayment, PeriodAsTimesPerYear = 0.25m, BucketingRate = 0.05m }; if (modelData.MarketEnvironment is ISwapLegEnvironment environment) { var marketEnvironment = environment; //The discount curve. discountCurve = marketEnvironment.GetDiscountRateCurve(); discountCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.DiscountCurve = discountCurve; //Check if it is our of currency. if (ModelData.ReportingCurrency != null && ModelData.ReportingCurrency.Value != PaymentCurrency.Value) { fxCurve = marketEnvironment.GetReportingCurrencyFxCurve(); fxCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.ReportingCurrencyFxCurve = fxCurve; } } else if (modelData.MarketEnvironment.GetType() == typeof(MarketEnvironment)) { var market = (MarketEnvironment)modelData.MarketEnvironment; discountCurve = (IRateCurve)market.SearchForPricingStructureType(DiscountCurveName); discountCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.DiscountCurve = discountCurve; var currencyCurveName = MarketEnvironmentHelper.ResolveFxCurveNames(StartFxRate.quotedCurrencyPair.currency1.Value, StartFxRate.quotedCurrencyPair.currency2.Value); currencyCurve = (IFxCurve)market.SearchForPricingStructureType(currencyCurveName); currencyCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; if (delta1PDH) { var riskMarket = market.SearchForPerturbedPricingStructures(DiscountCurveName, "delta1PDH"); analyticModelParameters.Delta1PDHCurves = riskMarket; analyticModelParameters.Delta1PDHPerturbation = 10; } if (delta0PDH) { var riskMarket = market.SearchForPerturbedPricingStructures(DiscountCurveName, "delta0PDH");//TODO The fx deltas analyticModelParameters.Delta1PDHCurves = riskMarket; analyticModelParameters.Delta1PDHPerturbation = 10; } if (modelData.ReportingCurrency.Value != PaymentCurrency.Value) { string curveName = MarketEnvironmentHelper.ResolveFxCurveNames(PaymentCurrency.Value, modelData.ReportingCurrency.Value); fxCurve = (IFxCurve)market.SearchForPricingStructureType(curveName); fxCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.ReportingCurrencyFxCurve = fxCurve; } if (HybridValuation) { var currency1RateCurve = (IRateCurve)market.SearchForPricingStructureType(Currency1DiscountCurveName); currency1RateCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; var currency2RateCurve = (IRateCurve)market.SearchForPricingStructureType(Currency2DiscountCurveName); currency2RateCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; AnalyticsModel = new FxRateCashflowAnalytic(ModelData.ValuationDate, PaymentDate, currencyCurve, currency1RateCurve, currency2RateCurve, !InvertFxRate, IsSettlementInCurrency1, fxCurve); } } // store inputs and results from this run AnalyticModelParameters = analyticModelParameters; if (!HybridValuation) { AnalyticsModel = new FxRateCashflowAnalytic(ModelData.ValuationDate, PaymentDate, fxCurve, currencyCurve, discountCurve); } //TODO Fix this with a generic index curve. //AnalyticsModel = analyticsModel; CalculationResults = AnalyticsModel.Calculate <IFloatingCashflowResults, FloatingCashflowResults>(AnalyticModelParameters, metrics.ToArray()); CalculationPerformedIndicator = true; PaymentDiscountFactor = ((FxRateCashflowAnalytic)AnalyticsModel).PaymentDiscountFactor; ForecastAmount = MoneyHelper.GetAmount(CalculationResults.LocalCurrencyExpectedValue, PaymentAmount.currency); NPV = MoneyHelper.GetAmount(CalculationResults.LocalCurrencyNPV, PaymentAmount.currency); AssetValuation valuation = GetValue(CalculationResults, modelData.ValuationDate); valuation.id = Id; return(valuation); }
/// <summary> /// Calculates the specified model data. /// </summary> /// <param name="modelData">The model data.</param> /// <returns></returns> public override AssetValuation Calculate(IInstrumentControllerData modelData) { ModelData = modelData; AnalyticModelParameters = null; CalculationResults = null; UpdateBucketingInterval(ModelData.ValuationDate, PeriodHelper.Parse(CDefaultBucketingInterval)); // 1. First derive the analytics to be evaluated via the stream controller model // NOTE: These take precendence of the child model metrics if (AnalyticsModel == null) { AnalyticsModel = new SimpleXccySwapInstrumentAnalytic(); } var swapControllerMetrics = ResolveModelMetrics(AnalyticsModel.Metrics); AssetValuation swapValuation; var quotes = ModelData.AssetValuation.quote.ToList(); if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.AccrualFactor.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.AccrualFactor.ToString(), "DecimalValue"); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.FloatingNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.FloatingNPV.ToString(), "DecimalValue"); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.NPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.NPV.ToString(), "DecimalValue"); quotes.Add(quote); } ModelData.AssetValuation.quote = quotes.ToArray(); //Sets the evolution type for calculations. foreach (var leg in Legs) { leg.PricingStructureEvolutionType = PricingStructureEvolutionType; leg.BucketedDates = BucketedDates; leg.Multiplier = Multiplier; } if (AdditionalPayments != null) { foreach (var payment in AdditionalPayments) { payment.PricingStructureEvolutionType = PricingStructureEvolutionType; payment.BucketedDates = BucketedDates; payment.Multiplier = Multiplier; } } var legControllers = new List <InstrumentControllerBase> { PayLeg, ReceiveLeg }; //The assetValuation list. var childValuations = new List <AssetValuation>(); // 2. Now evaluate only the child specific metrics (if any) if (modelData.MarketEnvironment is ISwapLegEnvironment) { var market = (SwapLegEnvironment)modelData.MarketEnvironment; IRateCurve discountCurve = null; IRateCurve forecastCurve = null; IFxCurve currencyCurve = null; foreach (var leg in legControllers) { var stream = (PriceableInterestRateStream)leg; if (modelData.ReportingCurrency == null) { modelData.ReportingCurrency = stream.Currency; } if (stream.DiscountCurveName != null) { discountCurve = market.GetDiscountRateCurve(); } if (stream.ForecastCurveName != null) { forecastCurve = market.GetForecastRateCurve(); } if (modelData.ReportingCurrency.Value != stream.Currency.Value) { //stream.ReportingCurrencyFxCurveName = // MarketEnvironmentHelper.ResolveFxCurveNames(stream.Currency.Value, modelData.ReportingCurrency.Value); currencyCurve = market.GetReportingCurrencyFxCurve(); } modelData.MarketEnvironment = MarketEnvironmentHelper.CreateInterestRateStreamEnvironment(modelData.ValuationDate, discountCurve, forecastCurve, currencyCurve); childValuations.Add(leg.Calculate(modelData)); } if (GetAdditionalPayments() != null) { var paymentControllers = new List <InstrumentControllerBase>(GetAdditionalPayments()); childValuations.AddRange(paymentControllers.Select(payment => payment.Calculate(modelData))); } } else { childValuations = EvaluateChildMetrics(legControllers, modelData, Metrics); } var childControllerValuations = AssetValuationHelper.AggregateMetrics(childValuations, new List <string>(Metrics), PaymentCurrencies);// modelData.ValuationDate); childControllerValuations.id = Id + ".InterestRateStreams"; // Child metrics have now been calculated so we can now evaluate the stream model metrics if (swapControllerMetrics.Count > 0) { //TODO need to fix this calculation. var payStreamAccrualFactor = AssetValuationHelper.GetQuotationByMeasureType(childValuations[0], InstrumentMetrics.AccrualFactor.ToString()); //AggregateMetric(InstrumentMetrics.AccrualFactor, childValuations); var payStreamNPV = AssetValuationHelper.GetQuotationByMeasureType(childValuations[0], InstrumentMetrics.NPV.ToString()); //AggregateMetric(InstrumentMetrics.NPV, childValuations); var payStreamFloatingNPV = AssetValuationHelper.GetQuotationByMeasureType(childValuations[0], InstrumentMetrics.FloatingNPV.ToString()); //AggregateMetric(InstrumentMetrics.FloatingNPV, childValuations); var receiveStreamAccrualFactor = AssetValuationHelper.GetQuotationByMeasureType(childValuations[1], InstrumentMetrics.AccrualFactor.ToString()); //AggregateMetric(InstrumentMetrics.AccrualFactor, childValuations); var receiveStreamNPV = AssetValuationHelper.GetQuotationByMeasureType(childValuations[1], InstrumentMetrics.NPV.ToString()); //AggregateMetric(InstrumentMetrics.NPV, childValuations); var receiveStreamFloatingNPV = AssetValuationHelper.GetQuotationByMeasureType(childValuations[1], InstrumentMetrics.FloatingNPV.ToString()); IIRSwapInstrumentParameters analyticModelParameters = new SwapInstrumentParameters { IsPayFixedInd = true, PayStreamAccrualFactor = payStreamAccrualFactor.value, PayStreamFloatingNPV = payStreamFloatingNPV.value, PayStreamNPV = payStreamNPV.value, ReceiveStreamFloatingNPV = receiveStreamFloatingNPV.value, ReceiveStreamNPV = receiveStreamNPV.value, ReceiveStreamAccrualFactor = receiveStreamAccrualFactor.value, NPV = payStreamNPV.value + receiveStreamNPV.value }; CalculationResults = AnalyticsModel.Calculate <IIRSwapInstrumentResults, SwapInstrumentResults>(analyticModelParameters, swapControllerMetrics.ToArray()); // Now merge back into the overall stream valuation var swapControllerValuation = GetValue(CalculationResults, modelData.ValuationDate); swapValuation = AssetValuationHelper.UpdateValuation(swapControllerValuation, childControllerValuations, ConvertMetrics(swapControllerMetrics), new List <string>(Metrics)); } else { swapValuation = childControllerValuations; } CalculationPerfomedIndicator = true; swapValuation.id = Id; return(swapValuation); }
/// <summary> /// Converts a sting period to a time interval. /// </summary> /// <param name="interval">The string interval. Valid intervals are: </param> /// <returns>The double interval.</returns> public double TimeFromInterval(string interval) { return(PeriodHelper.Parse(interval).ToYearFraction()); }
private static InterestRateStream GenerateFixedStreamDefinition(SwapLegParametersRange legParametersRange) { var discountingType = legParametersRange.DiscountingType; InterestRateStream stream; Discounting discounting = null; if (discountingType != null && discountingType.ToUpper() != "NONE") { discounting = new Discounting { discountingType = EnumHelper.Parse <DiscountingTypeEnum>(legParametersRange.DiscountingType), discountingTypeSpecified = true }; stream = InterestRateStreamFactory.CreateFixedRateStream(DiscountingTypeToPayRelativeTo(discounting.discountingType)); } else { stream = InterestRateStreamFactory.CreateFixedRateStream(DiscountingTypeToPayRelativeTo(null)); } // Set effective and termination dates of the stream. // SetEffectiveAndTerminationDates(stream, legParametersRange.EffectiveDate, legParametersRange.MaturityDate, legParametersRange.PaymentBusinessDayAdjustments, legParametersRange.PaymentCalendar); //Set the FirstRegularPeriodStartDate SetFirstRegularPeriodStartDate(stream, legParametersRange.FirstRegularPeriodStartDate); //Set the LastRegularPeriodEndDate SetLastRegularPeriodEndDate(stream, legParametersRange.LastRegularPeriodEndDate); // Adjusted or unadjusted swap // var dateAdjustments = AdjustedType.Adjusted != legParametersRange.AdjustedType ? BusinessDayAdjustmentsHelper.Create(BusinessDayConventionEnum.NONE, legParametersRange.PaymentCalendar) : BusinessDayAdjustmentsHelper.Create(legParametersRange.PaymentBusinessDayAdjustments, legParametersRange.PaymentCalendar); stream.calculationPeriodDates.calculationPeriodDatesAdjustments = dateAdjustments; stream.calculationPeriodDates.calculationPeriodFrequency = CalculationPeriodFrequencyHelper.Parse(legParametersRange.PaymentFrequency, legParametersRange.RollConvention); //Set FirstPeriodStartDate i.e. Full or Partial period. if (legParametersRange.FirstCouponType == FirstCouponType.Full) { var firstCouponStartDate = new AdjustableDate { dateAdjustments = dateAdjustments, id = "FullFirstCoupon" }; SetFirstPeriodStartDate(stream, firstCouponStartDate); } // Set payment dates frequency and adjustments // stream.paymentDates.paymentFrequency = PeriodHelper.Parse(legParametersRange.PaymentFrequency).ToFrequency(); stream.paymentDates.paymentDatesAdjustments = BusinessDayAdjustmentsHelper.Create(legParametersRange.PaymentBusinessDayAdjustments, legParametersRange.PaymentCalendar); Calculation calculation = XsdClassesFieldResolver.CalculationPeriodAmountGetCalculation(stream.calculationPeriodAmount); // Set discounting type // calculation.discounting = discounting; // Set notional amount (as the initial value in notional schedule) // SetNotional(calculation, legParametersRange.NotionalAmount, legParametersRange.Currency); // Set fixed rate (as the initial value in fixed-rate schedule) // Schedule fixedRateSchedule = ScheduleHelper.Create(legParametersRange.CouponOrLastResetRate); XsdClassesFieldResolver.CalculationSetFixedRateSchedule(calculation, fixedRateSchedule); // Set the 'day count convention' // calculation.dayCountFraction = DayCountFractionHelper.Parse(legParametersRange.DayCount); // Initial stub // //if (paymentCalendar==null) //{ // paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, stream.paymentDates.paymentDatesAdjustments.businessCenters); //} //ProcessStubs(stream, legParametersRange, paymentCalendar); return(stream); }
/// <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); }
private static InterestRateStream GenerateFloatingStreamDefinition(SwapLegParametersRange legParametersRange) { Discounting discounting = null; InterestRateStream stream; if (legParametersRange.DiscountingType != null && legParametersRange.DiscountingType.ToUpper() != "NONE") { discounting = new Discounting { discountingType = EnumHelper.Parse <DiscountingTypeEnum>(legParametersRange.DiscountingType) }; // Create the stream object stream = InterestRateStreamFactory.CreateFloatingRateStream(DiscountingTypeToPayRelativeTo(discounting.discountingType)); } else { // Create the stream object // stream = InterestRateStreamFactory.CreateFloatingRateStream(DiscountingTypeToPayRelativeTo(null)); } // Set effective and termination dates of the stream. // SetEffectiveAndTerminationDates(stream, legParametersRange.EffectiveDate, legParametersRange.MaturityDate, legParametersRange.PaymentBusinessDayAdjustments, legParametersRange.PaymentCalendar); //Set the FirstRegularPeriodStartDate SetFirstRegularPeriodStartDate(stream, legParametersRange.FirstRegularPeriodStartDate); //Set the LastRegularPeriodEndDate SetLastRegularPeriodEndDate(stream, legParametersRange.LastRegularPeriodEndDate); // Adjusted or unadjusted swap //Set the stub period type var dateAdjustments = AdjustedType.Adjusted != legParametersRange.AdjustedType ? BusinessDayAdjustmentsHelper.Create(BusinessDayConventionEnum.NONE, legParametersRange.PaymentCalendar) : BusinessDayAdjustmentsHelper.Create(legParametersRange.PaymentBusinessDayAdjustments, legParametersRange.PaymentCalendar); stream.calculationPeriodDates.calculationPeriodDatesAdjustments = dateAdjustments; stream.calculationPeriodDates.calculationPeriodFrequency = CalculationPeriodFrequencyHelper.Parse(legParametersRange.PaymentFrequency, legParametersRange.RollConvention); if (legParametersRange.FirstCouponType == FirstCouponType.Full) { var firstCouponStartDate = new AdjustableDate { dateAdjustments = dateAdjustments, id = "FullFirstCoupon" }; SetFirstPeriodStartDate(stream, firstCouponStartDate); } //Set the payment dates stream.paymentDates.paymentFrequency = PeriodHelper.Parse(legParametersRange.PaymentFrequency).ToFrequency(); stream.paymentDates.paymentDatesAdjustments = BusinessDayAdjustmentsHelper.Create(legParametersRange.PaymentBusinessDayAdjustments, legParametersRange.PaymentCalendar); stream.resetDates.fixingDates = RelativeDateOffsetHelper.Create(legParametersRange.PaymentFrequency, DayTypeEnum.Business, BusinessDayConventionEnum.NONE.ToString(), legParametersRange.FixingCalendar, "resetDates");//"NONE" & "resedDates" - hardcoded stream.resetDates.resetFrequency = ResetFrequencyHelper.Parse(legParametersRange.PaymentFrequency); stream.resetDates.resetDatesAdjustments = BusinessDayAdjustmentsHelper.Create(legParametersRange.FixingBusinessDayAdjustments, legParametersRange.FixingCalendar); Calculation calculation = XsdClassesFieldResolver.CalculationPeriodAmountGetCalculation(stream.calculationPeriodAmount); // Set discounting type // calculation.discounting = discounting; // Set notional amount (as the initial value in notional schedule) // SetNotional(calculation, legParametersRange.NotionalAmount, legParametersRange.Currency); // Set floating rate index name // string indexTenor = legParametersRange.PaymentFrequency; //string indexName = legParametersRange.ForecastCurve; string indexName = legParametersRange.ForecastIndexName; FloatingRateCalculation floatingRateCalculation = FloatingRateCalculationFactory.Create(indexName, indexTenor, legParametersRange.FloatingRateSpread); XsdClassesFieldResolver.CalculationSetFloatingRateCalculation(calculation, floatingRateCalculation); // Set day count convention // calculation.dayCountFraction = DayCountFractionHelper.Parse(legParametersRange.DayCount); return(stream); }
private static InterestRateStream GenerateCapFloorStreamDefinition(CapFloorLegParametersRange legParametersRange) { Discounting discounting = null; InterestRateStream stream; if (legParametersRange.DiscountingType != null && legParametersRange.DiscountingType.ToUpper() != "NONE") { discounting = new Discounting { discountingType = EnumHelper.Parse <DiscountingTypeEnum>(legParametersRange.DiscountingType) }; stream = InterestRateStreamFactory.CreateFloatingRateStream(DiscountingTypeToPayRelativeTo(discounting.discountingType)); } // Create the stream object // else { stream = InterestRateStreamFactory.CreateFloatingRateStream(DiscountingTypeToPayRelativeTo(null)); } // Set effective and termination dates of the stream. // SetEffectiveAndTerminationDates(stream, legParametersRange.EffectiveDate, legParametersRange.MaturityDate, legParametersRange.PaymentBusinessDayAdjustments, legParametersRange.PaymentCalendar); // Adjusted or unadjusted swap // stream.calculationPeriodDates.calculationPeriodDatesAdjustments = AdjustedType.Adjusted != legParametersRange.AdjustedType ? BusinessDayAdjustmentsHelper.Create(BusinessDayConventionEnum.NONE, legParametersRange.PaymentCalendar) : BusinessDayAdjustmentsHelper.Create(legParametersRange.PaymentBusinessDayAdjustments, legParametersRange.PaymentCalendar); stream.calculationPeriodDates.calculationPeriodFrequency = CalculationPeriodFrequencyHelper.Parse(legParametersRange.PaymentFrequency, legParametersRange.RollConvention); stream.paymentDates.paymentFrequency = PeriodHelper.Parse(legParametersRange.PaymentFrequency).ToFrequency(); stream.paymentDates.paymentDatesAdjustments = BusinessDayAdjustmentsHelper.Create(legParametersRange.PaymentBusinessDayAdjustments, legParametersRange.PaymentCalendar); stream.resetDates.fixingDates = RelativeDateOffsetHelper.Create(legParametersRange.PaymentFrequency, DayTypeEnum.Business, BusinessDayConventionEnum.NONE.ToString(), legParametersRange.FixingCalendar, "resetDates");//"NONE" & "resedDates" - hardcoded stream.resetDates.resetFrequency = ResetFrequencyHelper.Parse(legParametersRange.PaymentFrequency); stream.resetDates.resetDatesAdjustments = BusinessDayAdjustmentsHelper.Create(legParametersRange.FixingBusinessDayAdjustments, legParametersRange.FixingCalendar); Calculation calculation = XsdClassesFieldResolver.CalculationPeriodAmountGetCalculation(stream.calculationPeriodAmount); // Set discounting type // calculation.discounting = discounting; // Set notional amount (as the initial value in notional schedule) // SetNotional(calculation, legParametersRange.NotionalAmount, legParametersRange.Currency); // Set floating rate index name // string indexTenor = legParametersRange.PaymentFrequency; string indexName = legParametersRange.ForecastIndexName; FloatingRateCalculation floatingRateCalculation = FloatingRateCalculationFactory.Create(indexName, indexTenor, legParametersRange.FloatingRateSpread); XsdClassesFieldResolver.CalculationSetFloatingRateCalculation(calculation, floatingRateCalculation); if (legParametersRange.CapOrFloor == CapFloorType.Cap) { floatingRateCalculation.capRateSchedule = new[] { new StrikeSchedule() }; floatingRateCalculation.capRateSchedule[0].initialValue = legParametersRange.StrikeRate; floatingRateCalculation.capRateSchedule[0].buyer = new IdentifiedPayerReceiver { Value = PayerReceiverEnum.Receiver }; floatingRateCalculation.capRateSchedule[0].seller = new IdentifiedPayerReceiver { Value = PayerReceiverEnum.Payer }; } else { floatingRateCalculation.floorRateSchedule = new[] { new StrikeSchedule() }; floatingRateCalculation.floorRateSchedule[0].initialValue = legParametersRange.StrikeRate; floatingRateCalculation.floorRateSchedule[0].buyer = new IdentifiedPayerReceiver { Value = PayerReceiverEnum.Receiver }; floatingRateCalculation.floorRateSchedule[0].seller = new IdentifiedPayerReceiver { Value = PayerReceiverEnum.Payer }; } // Set day count convention // calculation.dayCountFraction = DayCountFractionHelper.Parse(legParametersRange.DayCount); return(stream); }
/// <summary> /// Calculates the specified model data. /// </summary> /// <param name="modelData">The model data.</param> /// <returns></returns> public override AssetValuation Calculate(IInstrumentControllerData modelData) { ModelData = modelData; AnalyticModelParameters = null; AnalyticsModel = new FloatingRateCouponAnalytic(); RequiresReset = modelData.ValuationDate > ResetDate; IsRealised = HasBeenRealised(ModelData.ValuationDate); //Make sure there are some bucket dates even if not set previously. if (BucketedDates.Length < 1) { UpdateBucketingInterval(ModelData.ValuationDate, PeriodHelper.Parse(CDefaultBucketingInterval)); } //Add the extra metrics required var quotes = ModelData.AssetValuation.quote.ToList(); if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.BreakEvenRate.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.BreakEvenRate.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.AccrualFactor.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.AccrualFactor.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.FloatingNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.FloatingNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.NPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.NPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.RiskNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.RiskNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.LocalCurrencyNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyExpectedValue.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.LocalCurrencyExpectedValue.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } //Check if risk calc are required. bool delta1PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta1PDH.ToString()) != null || AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta1PDH.ToString()) != null; //Check if risk calc are required. bool delta0PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta0PDH.ToString()) != null || AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta0PDH.ToString()) != null; ModelData.AssetValuation.quote = quotes.ToArray(); var metrics = ResolveModelMetrics(AnalyticsModel.Metrics); IFxCurve fxCurve = null; IRateCurve discountCurve = null; IRateCurve forecastCurve = null; //// Determine if DFAM has been requested - if so thats all we evaluate - every other metric is ignored //if (metrics.Contains(InstrumentMetrics.DiscountFactorAtMaturity)) //{ // metrics.RemoveAll(metricItem => metricItem != InstrumentMetrics.DiscountFactorAtMaturity); //} //Set the forrecast rate dates. The ForecastRateInterpolation shhould have been set. ForwardStartDate = AccrualStartDate; ForwardEndDate = ForecastRateInterpolation ? AccrualEndDate : AdjustedDateHelper.ToAdjustedDate(FixingCalendar, ForecastRateIndex.indexTenor.Add(ForwardStartDate), AccrualBusinessDayAdjustments); //var metricsToEvaluate = metrics.ToArray(); if (metrics.Count > 0) { YearFractionToCashFlowPayment = GetPaymentYearFraction(ModelData.ValuationDate, PaymentDate); var reportingCurrency = ModelData.ReportingCurrency == null ? PaymentCurrency.Value : ModelData.ReportingCurrency.Value; var amount = NotionalAmount.amount; IRateCouponParameters analyticModelParameters = new RateCouponParameters { Multiplier = Multiplier, ValuationDate = modelData.ValuationDate, PaymentDate = PaymentDate, Currency = PaymentCurrency.Value, ReportingCurrency = reportingCurrency, DiscountType = DiscountType, IsRealised = IsRealised, HasReset = RequiresReset, NotionalAmount = amount, Spread = Margin, YearFraction = CouponYearFraction, CurveYearFraction = YearFractionToCashFlowPayment }; decimal?discountRate = null; // Curve Related if (modelData.MarketEnvironment is ISwapLegEnvironment environment) { var streamMarket = environment; discountCurve = streamMarket.GetDiscountRateCurve(); discountCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; forecastCurve = streamMarket.GetForecastRateCurve(); forecastCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; DiscountCurveName = discountCurve.GetPricingStructureId().UniqueIdentifier; analyticModelParameters.DiscountCurve = discountCurve; ForecastCurveName = forecastCurve.GetPricingStructureId().UniqueIdentifier; analyticModelParameters.ForecastCurve = forecastCurve; // Bucketed Delta if (BucketedDates.Length > 1) { analyticModelParameters.PeriodAsTimesPerYear = GetPaymentYearFraction(BucketedDates[0], BucketedDates[1]); analyticModelParameters.BucketedDiscountFactors = GetBucketedDiscountFactors(discountCurve, ModelData. ValuationDate, BucketedDates); } //Check for currency. if (ModelData.ReportingCurrency != null) { if (ModelData.ReportingCurrency.Value != PaymentCurrency.Value) { fxCurve = streamMarket.GetReportingCurrencyFxCurve(); fxCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.ReportingCurrencyFxCurve = fxCurve; } } AnalyticModelParameters = analyticModelParameters; } else if (modelData.MarketEnvironment.GetType() == typeof(MarketEnvironment)) { var market = (MarketEnvironment)modelData.MarketEnvironment; discountCurve = (IRateCurve)market.SearchForPricingStructureType(DiscountCurveName); discountCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; forecastCurve = (IRateCurve)market.SearchForPricingStructureType(ForecastCurveName); forecastCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.DiscountCurve = discountCurve; analyticModelParameters.ForecastCurve = forecastCurve; // Bucketed Delta if (BucketedDates.Length > 1) { analyticModelParameters.PeriodAsTimesPerYear = GetPaymentYearFraction(BucketedDates[0], BucketedDates[1]); analyticModelParameters.BucketedDiscountFactors = GetBucketedDiscountFactors(discountCurve, ModelData. ValuationDate, BucketedDates); } if (delta1PDH) { var riskMarket = market.SearchForPerturbedPricingStructures(DiscountCurveName, "delta1PDH"); analyticModelParameters.Delta1PDHCurves = riskMarket; analyticModelParameters.Delta1PDHPerturbation = 10; } if (delta0PDH) { var riskMarket = market.SearchForPerturbedPricingStructures(ForecastCurveName, "delta0PDH"); analyticModelParameters.Delta0PDHCurves = riskMarket; analyticModelParameters.Delta0PDHPerturbation = 10; } //Check for currency. if (ModelData.ReportingCurrency != null) { if (ModelData.ReportingCurrency.Value != PaymentCurrency.Value) { string curveName = MarketEnvironmentHelper.ResolveFxCurveNames(PaymentCurrency.Value, modelData.ReportingCurrency.Value); fxCurve = (IFxCurve)market.SearchForPricingStructureType(curveName); fxCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.ReportingCurrencyFxCurve = fxCurve; } } AnalyticModelParameters = analyticModelParameters; } //Set the base rate. Default is zero if (AnalyticModelParameters != null) { AnalyticModelParameters.BaseRate = BaseRate; } if (UseObservedRate) { AnalyticsModel = new FixedRateCouponAnalytic(ModelData.ValuationDate, AccrualStartDate, AccrualEndDate, PaymentDate, Rate, analyticModelParameters.YearFraction, DiscountType, fxCurve, discountCurve, forecastCurve); if (Rate != null) { analyticModelParameters.Rate = (decimal)Rate; } } else { if (Rate != null) { discountRate = Rate; } if (DiscountRate != null) { discountRate = DiscountRate; } AnalyticsModel = new FloatingRateCouponAnalytic(ModelData.ValuationDate, AccrualStartDate, AccrualEndDate, PaymentDate, discountRate, analyticModelParameters.YearFraction, DiscountType, fxCurve, discountCurve, forecastCurve); } CalculationResults = AnalyticsModel.Calculate <IRateInstrumentResults, RateInstrumentResults>(AnalyticModelParameters, metrics.ToArray()); CalculationPerfomedIndicator = true; PaymentDiscountFactor = ((FixedRateCouponAnalytic)AnalyticsModel).PaymentDiscountFactor; if (!UseObservedRate) { Rate = CalculationResults.BreakEvenRate; } ForecastAmount = MoneyHelper.GetAmount(CalculationResults.LocalCurrencyExpectedValue, PaymentAmount.currency); NPV = MoneyHelper.GetAmount(CalculationResults.LocalCurrencyNPV, PaymentAmount.currency); } AssetValuation valuation = GetValue(CalculationResults, modelData.ValuationDate); valuation.id = Id; return(valuation); }
/// <summary> /// Adjusted dates from effective date. /// </summary> /// <param name="effectiveDate">The effective date.</param> /// <param name="terminationDate">The termination date.</param> /// <param name="periodInterval">The period interval.</param> /// <param name="rollConvention">The roll convention.</param> /// <param name="businessCalender">The business calender.</param> /// <param name="dateAdjustmentConvention">The date adjustment convention.</param> /// <returns></returns> public static DateTime[] AdjustedDatesFromEffectiveDate(DateTime effectiveDate, DateTime terminationDate, string periodInterval, string rollConvention, IBusinessCalendar businessCalender, BusinessDayConventionEnum dateAdjustmentConvention) { DateTime[] dateSchedule = DateScheduler.GetUnadjustedDatesFromEffectiveDate(effectiveDate, terminationDate, PeriodHelper.Parse(periodInterval), RollConventionEnumHelper.Parse(rollConvention), out _, out _); List <DateTime> adjustedDateSchedule = GetAdjustedDateSchedule(dateSchedule, dateAdjustmentConvention, businessCalender); return(adjustedDateSchedule.ToArray()); }
/// <summary> /// Calculates the specified model data. /// </summary> /// <param name="modelData">The model data.</param> /// <returns></returns> public override AssetValuation Calculate(IInstrumentControllerData modelData) { ModelData = modelData; AnalyticModelParameters = null; AnalyticsModel = new FxOptionAnalytic(); CalculationResults = null; YearFractionToCashFlowPayment = Convert.ToDecimal(CDefaultDayCounter.YearFraction(ModelData.ValuationDate, PaymentDate)); //Make sure there are some bucket dates even if not set previously. if (BucketedDates.Length < 1) { UpdateBucketingInterval(ModelData.ValuationDate, PeriodHelper.Parse(CDefaultBucketingInterval)); } IsRealised = HasBeenRealised(ModelData.ValuationDate); //Add the extra metrics required var quotes = ModelData.AssetValuation.quote.ToList(); if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, FloatingCashflowMetrics.NPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, FloatingCashflowMetrics.LocalCurrencyNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, FloatingCashflowMetrics.LocalCurrencyNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, FloatingCashflowMetrics.LocalCurrencyNPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.RiskNPV.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.NPV.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, FloatingCashflowMetrics.LocalCurrencyExpectedValue.ToString()) == null) { var quote = QuotationHelper.Create(0.0m, FloatingCashflowMetrics.LocalCurrencyExpectedValue.ToString(), "DecimalValue", ModelData.ValuationDate); quotes.Add(quote); } //Check if risk calc are required. bool delta1PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta1PDH.ToString()) != null || AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta1PDH.ToString()) != null; //Check if risk calc are required. bool delta0PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta0PDH.ToString()) != null || AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta0PDH.ToString()) != null; ModelData.AssetValuation.quote = quotes.ToArray(); //Set the cash flowdetails. HasReset = modelData.ValuationDate > ResetDate; IsRealised = HasBeenRealised(ModelData.ValuationDate); TimeToExpiry = GetPaymentYearFraction(ModelData.ValuationDate, AdjustedFixingDate); var volatilityCurveNodeTime = GetPaymentYearFraction(ModelData.ValuationDate, PaymentDate); IFxCurve fxCurve = null; IRateCurve discountCurve = null; IFxCurve currencyCurve = null; IVolatilitySurface volSurface = null; var metrics = ResolveModelMetrics(AnalyticsModel.Metrics); //var metricsToEvaluate = metrics.ToArray(); //if (metricsToEvaluate.Length > 0) //{ YearFractionToCashFlowPayment = GetPaymentYearFraction(ModelData.ValuationDate, PaymentDate); var reportingCurrency = ModelData.ReportingCurrency == null ? PaymentCurrency.Value : ModelData.ReportingCurrency.Value; decimal?premium = null; if (Premium != null) { premium = Premium; } IFxRateCashflowParameters analyticModelParameters = new FxRateCashflowParameters { ValuationDate = modelData.ValuationDate, PaymentDate = PaymentDate, Currency = PaymentCurrency.Value, ReportingCurrency = reportingCurrency, IsRealised = IsRealised, IsReset = HasReset, NotionalAmount = NotionalAmount.amount, CurveYearFraction = YearFractionToCashFlowPayment, ExpiryYearFraction = TimeToExpiry, Premium = premium }; // Curve Related if (modelData.MarketEnvironment.GetType() == typeof(MarketEnvironment)) { var market = (MarketEnvironment)modelData.MarketEnvironment; discountCurve = (IRateCurve)market.SearchForPricingStructureType(DiscountCurveName); discountCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; volSurface = (IVolatilitySurface)market.SearchForPricingStructureType(VolatilitySurfaceName); volSurface.PricingStructureEvolutionType = PricingStructureEvolutionType; var currencyCurveName = MarketEnvironmentHelper.ResolveFxCurveNames(StartFxRate.quotedCurrencyPair.currency1.Value, StartFxRate.quotedCurrencyPair.currency2.Value); currencyCurve = (IFxCurve)market.SearchForPricingStructureType(currencyCurveName); currencyCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.DiscountCurve = discountCurve; if (delta1PDH) { var riskMarket = market.SearchForPerturbedPricingStructures(DiscountCurveName, "delta1PDH"); analyticModelParameters.Delta1PDHCurves = riskMarket; analyticModelParameters.Delta1PDHPerturbation = 10; } if (delta0PDH)//TODO Do this for the fxrate { //var riskMarket = market.SearchForPerturbedPricingStructures(DiscountCurveName, "delta0PDH"); // //TODO The fx deltas //analyticModelParameters.Delta1PDHCurves = riskMarket; //analyticModelParameters.Delta1PDHPerturbation = 10; } if (modelData.ReportingCurrency.Value != PaymentCurrency.Value) { string curveName = MarketEnvironmentHelper.ResolveFxCurveNames(PaymentCurrency.Value, modelData.ReportingCurrency.Value); fxCurve = (IFxCurve)market.SearchForPricingStructureType(curveName); fxCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; analyticModelParameters.ReportingCurrencyFxCurve = fxCurve; } if (HybridValuation) { var currency1RateCurve = (IRateCurve)market.SearchForPricingStructureType(Currency1DiscountCurveName); currency1RateCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; var currency2RateCurve = (IRateCurve)market.SearchForPricingStructureType(Currency2DiscountCurveName); currency2RateCurve.PricingStructureEvolutionType = PricingStructureEvolutionType; AnalyticsModel = new FxOptionAnalytic(ModelData.ValuationDate, PaymentDate, currencyCurve, currency1RateCurve, currency2RateCurve, IsSettlementInCurrency1, !InvertFxRate, Strike, TimeToExpiry, volatilityCurveNodeTime, volSurface, FxOptionType, fxCurve); } } // store inputs and results from this run AnalyticModelParameters = analyticModelParameters; if (!HybridValuation) { AnalyticsModel = new FxOptionAnalytic(ModelData.ValuationDate, PaymentDate, Strike, TimeToExpiry, volatilityCurveNodeTime, fxCurve, currencyCurve, discountCurve, volSurface, FxOptionType); } //TODO Fix this with a generic index curve. //AnalyticsModel = analyticsModel; CalculationResults = AnalyticsModel.Calculate <IFloatingCashflowResults, FloatingCashflowResults>( AnalyticModelParameters, metrics.ToArray()); CalculationPerfomedIndicator = true; PaymentDiscountFactor = ((FxRateCashflowAnalytic)AnalyticsModel).PaymentDiscountFactor; ForecastAmount = MoneyHelper.GetAmount(CalculationResults.LocalCurrencyExpectedValue, PaymentAmount.currency); NPV = MoneyHelper.GetAmount(CalculationResults.LocalCurrencyNPV, PaymentAmount.currency); AssetValuation valuation = GetValue(CalculationResults, modelData.ValuationDate); valuation.id = Id; return(valuation); }
/// <summary> /// Initializes a new instance of the <see cref="RateXccySpreadCurve"/> class. /// </summary> /// <param name="logger">The logger.</param> /// <param name="cache">The cache.</param> /// <param name="nameSpace">THe client namespace</param> /// <param name="baseCurveData">The market data. This must contain both the underlying base curve and the spread curve. /// Otherwise the RateBasisInterpolator can not instantiate.</param> /// <param name="referenceFxCurveData">The fxcurve referenced.</param> /// <param name="currency2CurveData">The curve data for the non base curve. This is normally the domestic curve i.e. AUD, /// as FX is quotes as xccy basis swaps adjust on the non-USD leg.</param> /// <param name="spreadCurveData">The spread Curve Data</param> /// <param name="fixingCalendar">The fixingCalendar.</param> /// <param name="rollCalendar">The rollCalendar.</param> public RateXccySpreadCurve(ILogger logger, ICoreCache cache, string nameSpace, Triplet <PricingStructure, PricingStructureValuation, NamedValueSet> baseCurveData, Triplet <PricingStructure, PricingStructureValuation, NamedValueSet> referenceFxCurveData, Triplet <PricingStructure, PricingStructureValuation, NamedValueSet> currency2CurveData, Triplet <PricingStructure, PricingStructureValuation, NamedValueSet> spreadCurveData, IBusinessCalendar fixingCalendar, IBusinessCalendar rollCalendar) : base(logger, cache, nameSpace, spreadCurveData, fixingCalendar, rollCalendar) { //Set the identifier. var nvs = spreadCurveData.Third; var pricingStructureId = new RateCurveIdentifier(nvs); PricingStructureIdentifier = pricingStructureId; var refCurveId = nvs.GetValue <string>(CurveProp.ReferenceCurveUniqueId); ReferenceCurveId = refCurveId != null ? new Identifier(refCurveId) : ReferenceCurveId = null; if (pricingStructureId.PricingStructureType != PricingStructureTypeEnum.RateXccyCurve) { return; } //Set the curve term. var cutOverTerm = spreadCurveData.Third.GetValue <string>("CutOverTerm"); if (cutOverTerm != null) { CutOverTerm = PeriodHelper.Parse(cutOverTerm); } //Set the reference curve var baseCurveFpML = new Pair <PricingStructure, PricingStructureValuation>(baseCurveData.First, baseCurveData.Second); var baseCurveProps = baseCurveData.Third; BaseCurve = (IRateCurve)PricingStructureFactory.Create(logger, cache, nameSpace, fixingCalendar, rollCalendar, baseCurveFpML, baseCurveProps); var fxCurveFpML = new Pair <PricingStructure, PricingStructureValuation>(referenceFxCurveData.First, referenceFxCurveData.Second); var fxCurveProps = referenceFxCurveData.Third; ReferenceFxCurve = (IFxCurve)PricingStructureFactory.Create(logger, cache, nameSpace, fixingCalendar, rollCalendar, fxCurveFpML, fxCurveProps); //Set the reference curve var currency2CurveFpML = new Pair <PricingStructure, PricingStructureValuation>(currency2CurveData.First, currency2CurveData.Second); var currency2CurveProps = currency2CurveData.Third; Currency2Curve = (RateCurve)PricingStructureFactory.Create(logger, cache, nameSpace, fixingCalendar, rollCalendar, currency2CurveFpML, currency2CurveProps); //Get the spread Data var spreadCurveFpML = new Pair <PricingStructure, PricingStructureValuation>(spreadCurveData.First, spreadCurveData.Second); var spreadCurveProps = spreadCurveData.Third; IsCurrency1RateCurve = spreadCurveProps.GetValue <bool>("Currency1RateCurve"); //Override properties. //var optimize = PropertyHelper.ExtractOptimizeBuildFlag(properties);TODO add this later. var bootstrap = PropertyHelper.ExtractBootStrapOverrideFlag(nvs); var tempFpml = (YieldCurveValuation)spreadCurveFpML.Second; var spreadAssets = tempFpml.inputs; //This is to catch it when there are no discount factor points. var discountsAbsent = tempFpml.discountFactorCurve?.point == null || tempFpml.discountFactorCurve.point.Length == 0; if (cache == null) { bootstrap = false; } if (bootstrap || discountsAbsent) { //There must be a valid quoted asset set in order to bootstrap. if (!XsdClassesFieldResolver.QuotedAssetSetIsValid(spreadAssets)) { return; } PriceableRateSpreadAssets = PriceableAssetFactory.CreatePriceableRateSpreadAssets(logger, cache, nameSpace, pricingStructureId.BaseDate, spreadAssets, fixingCalendar, rollCalendar); Build(logger, cache, nameSpace, fixingCalendar, rollCalendar); } else { if (cache != null) { // the discount curve is already built, so don't rebuild PriceableRateSpreadAssets = PriceableAssetFactory.CreatePriceableRateSpreadAssets(logger, cache, nameSpace, pricingStructureId.BaseDate, spreadAssets, fixingCalendar, rollCalendar); CreatePricingStructure(pricingStructureId, tempFpml.discountFactorCurve, PriceableAssetFactory.Parse(PriceableRateSpreadAssets)); SetInterpolator(BaseCurve, pricingStructureId.PricingStructureType); } else { CreatePricingStructure(pricingStructureId, tempFpml.discountFactorCurve, spreadAssets); SetInterpolator(BaseCurve, pricingStructureId.PricingStructureType); } } }
/// <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="nameSpace"></param> /// <param name="expiryTenors"></param> /// <param name="tenors"></param> /// <param name="volSurface"></param> /// <param name="surfaceId"></param> /// <param name="baseDate"></param> /// <param name="algorithm">The algorithm for interpolation.</param> protected ExpiryTermTenorATMVolatilitySurface(ILogger logger, ICoreCache cache, String nameSpace, String[] expiryTenors, String[] tenors, Double[,] volSurface, VolatilitySurfaceIdentifier surfaceId, DateTime baseDate, string algorithm) { Algorithm = 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, 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 }; PricingStructureValuation = new VolatilityMatrix { dataPoints = datapoints , objectReference = new AnyAssetReference { href = surfaceId.Instrument } , baseDate = new IdentifiedDate { Value = 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++; } 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); }
/// <summary> /// Get an indicative PPD for a given expiry/tenor pair /// If the pair is not in the grid use interpolation to derive the result /// </summary> /// <param name="expiry">The expiry term</param> /// <param name="tenor">The tenor term</param> /// <returns>A PPD value for the pair</returns> public decimal GetPPD(string expiry, string tenor) { return(GetPPD(PeriodHelper.Parse(expiry), PeriodHelper.Parse(tenor))); }
/// <summary> /// Gets the adjusted calculation period start dates. /// </summary> /// <param name="effectiveDate">The effective date.</param> /// <param name="terminationDate">The termination date.</param> /// <param name="periodInterval">The period interval.</param> /// <param name="rollConvention">The roll convention.</param> /// <param name="firstRegularPeriodDate">The first regular period date.</param> /// <param name="stubPeriodType">Type of the stub period.</param> /// <param name="businessCalendar">The businessCalendar.</param> /// <param name="businessDayConvention">The business day convention.</param> /// <returns>A vertical range of dates.</returns> public static DateTime[] GetAdjustedCalculationPeriodDates(DateTime effectiveDate, DateTime terminationDate, string periodInterval, string rollConvention, DateTime firstRegularPeriodDate, string stubPeriodType, IBusinessCalendar businessCalendar, string businessDayConvention) { const string dateToReturn = "unadjustedStartDate"; StubPeriodTypeEnum?stubType = null; if (!string.IsNullOrEmpty(stubPeriodType)) { stubType = (StubPeriodTypeEnum)Enum.Parse(typeof(StubPeriodTypeEnum), stubPeriodType, true); } var periods = CalculationPeriodHelper.GenerateUnadjustedCalculationDates(effectiveDate, terminationDate, firstRegularPeriodDate, PeriodHelper.Parse(periodInterval), RollConventionEnumHelper.Parse(rollConvention), stubType); var dates = CalculationPeriodHelper.GetCalculationPeriodsProperty <DateTime>(periods, dateToReturn); var newDates = new DateTime[dates.Count]; var index = 0; foreach (var date in dates) { var newDate = BusinessCalendarHelper.Advance(businessCalendar, date, "Calendar", "0D", businessDayConvention); newDates[index] = newDate; index++; } var result = newDates; return(result); }