/// <summary> /// Initializes a new instance of the <see cref="PriceableBondCouponRateStream"/> class. /// </summary> /// <param name="logger">The logger.</param> /// <param name="cache">The cache.</param> /// <param name="nameSpace">The client namespace.</param> /// <param name="bondId">The bond Id.</param> /// <param name="paymentConvention">The payment roll conventions</param> /// <param name="forecastRateInterpolation">ForwardEndDate = forecastRateInterpolation ? AccrualEndDate /// : AdjustedDateHelper.ToAdjustedDate(forecastRateIndex.indexTenor.Add(AccrualStartDate), AccrualBusinessDayAdjustments);</param> /// <param name="fixingCalendar">The fixingCalendar.</param> /// <param name="paymentCalendar">The paymentCalendar.</param> /// <param name="tradeDate">The trade date is used to set the base date for future coupon generation.</param> /// <param name="notionalAmount">The notional amount</param> /// <param name="couponType">The coupon type: fixed or floating.</param> /// <param name="bond">THe bond details.</param> public PriceableBondCouponRateStream ( ILogger logger , ICoreCache cache , string nameSpace , string bondId , DateTime tradeDate , decimal notionalAmount , CouponStreamType couponType , Bond bond , BusinessDayAdjustments paymentConvention , bool forecastRateInterpolation , IBusinessCalendar fixingCalendar , IBusinessCalendar paymentCalendar) { BondId = bondId; Multiplier = 1.0m; PaymentCurrencies = new List <string>(); AnalyticsModel = new BondStreamAnalytic(); BondCouponStreamType = couponType; Id = BuildId(bondId, BondCouponStreamType); Currency = bond.currency.Value; ForecastRateInterpolation = forecastRateInterpolation; //Get the currency. if (!PaymentCurrencies.Contains(bond.currency.Value)) { PaymentCurrencies.Add(bond.currency.Value); } //The calendars if (paymentCalendar == null) { paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, paymentConvention.businessCenters, nameSpace); } //Set the default discount curve name. BondCurveName = CurveNameHelpers.GetBondCurveName(Currency, bondId); //Set the forecast curve name.//TODO extend this to the other types. //if (BondCouponStreamType != CouponStreamType.GenericFixedRate) //{ // if (fixingCalendar == null) // { // fixingCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, ResetDates.resetDatesAdjustments.businessCenters, nameSpace); // } // ForecastCurveName = null; // //if (Calculation.Items != null) // //{ // // var floatingRateCalculation = Calculation.Items; // // var floatingRateIndex = (FloatingRateCalculation) floatingRateCalculation[0]; // // ForecastCurveName = CurveNameHelpers.GetForecastCurveName(floatingRateIndex); // //} //} //Build the coupons and principal exchanges. Coupons = PriceableInstrumentsFactory.CreatePriceableBondCoupons(tradeDate, bond, notionalAmount, BondCouponStreamType, paymentConvention, ForecastRateInterpolation, fixingCalendar, paymentCalendar);//TODO add the stub calculation. UpdateCouponDiscountCurveNames(); UpdateCouponIds(); //RiskMaturityDate = ; logger.LogInfo("Bond Coupon Stream built"); }
/// <summary> /// Process a PPD Grid. The result is a Market structure that camn be published. /// </summary> /// <param name="logger">The logger</param> /// <param name="cache">The cache.</param> /// <param name="swapCurve">The latest rate curve</param> /// <param name="ppdGrid">The raw Points Per Day matrix supplied from the subscriber</param> /// <param name="id">The id to use in publishing the curve</param> /// <param name="nameSpace">The client namespace</param> /// <returns></returns> public static Market ProcessSwaption(ILogger logger, ICoreCache cache, Market swapCurve, SwaptionPPDGrid ppdGrid, string id, string nameSpace) { var mkt = swapCurve; var curve = new SimpleRateCurve(mkt); // List the values so we can build our ATM vols var atmVols = new Dictionary <SimpleKey, decimal>(); // Create a calendar to use to modify the date // default to be Sydney... IBusinessCalendar bc = BusinessCenterHelper.ToBusinessCalendar(cache, new[] { "AUSY" }, nameSpace); //BusinessCalendarHelper("AUSY"); // Use some logic to get the spot date to use // LPM Spot lag is 2 days (modfollowing) DateTime spotDate = curve.GetSpotDate(); // Extract each surface and build an ATM engine therefrom // Build a list of all possible engines foreach (string e in ExpiryKeys) { // Assume frequency = 4 months until 3 years tenor is reached Period expiration = PeriodHelper.Parse(e); double expiryYearFraction = expiration.ToYearFraction(); foreach (string t in TenorKeys) { // Create a Swaprate for each expiry/tenor pair // Assume frequency = 4 months until 3 years tenor is reached double tenorYearFraction = PeriodHelper.Parse(t).ToYearFraction(); int frequency = tenorYearFraction < 4 ? 4 : 2; // Calculation date // Discount factors // Offsets (elapsed days) var rates = new SwapRate(logger, cache, nameSpace, "AUSY", curve.BaseDate, "ACT/365.FIXED", curve.GetDiscountFactors(), curve.GetDiscountFactorOffsets(), frequency, BusinessDayConventionEnum.MODFOLLOWING); // Calculate the volatility given PPD and swap curve DateTime expiry = bc.Roll(expiration.Add(spotDate), BusinessDayConventionEnum.FOLLOWING); decimal vol = CalculateAtmVolatility(rates, expiry, ppdGrid, expiryYearFraction, tenorYearFraction); atmVols.Add(new SimpleKey(e, t), vol); } } var vols = new object[atmVols.Count + 1, 3]; var i = 1; vols[0, 0] = "Expiry"; vols[0, 1] = "Tenor"; vols[0, 2] = "0"; foreach (var key in atmVols.Keys) { vols[i, 0] = key.Expiry; vols[i, 1] = key.Tenor; vols[i, 2] = atmVols[key]; i++; } DateTime buildDateTime = swapCurve.Items1[0].buildDateTime; var volSurface = new VolatilitySurface(vols, new VolatilitySurfaceIdentifier(id), curve.BaseDate, buildDateTime); return(CreateMarketDocument(volSurface.GetFpMLData())); }
/// <summary> /// </summary> /// <param name="cache"></param> /// <param name="interestRateStream"></param> /// <param name="listCalculationPeriods"></param> /// <param name="fixingCalendar"></param> /// <param name="nameSpace"></param> /// <returns></returns> /// <exception cref="NotSupportedException"></exception> /// <exception cref="NotImplementedException"></exception> public static List <DateTime> GetAdjustedResetDates(ICoreCache cache, InterestRateStream interestRateStream, List <CalculationPeriod> listCalculationPeriods, IBusinessCalendar fixingCalendar, string nameSpace) { var adjustedResetDates = new List <DateTime>(); ResetDates resetDates = interestRateStream.resetDates; Period resetFrequency = IntervalHelper.FromFrequency(resetDates.resetFrequency); Period calculationPeriodFrequency = IntervalHelper.FromFrequency(interestRateStream.calculationPeriodDates.calculationPeriodFrequency); if (resetFrequency.period != calculationPeriodFrequency.period) { throw new NotSupportedException( $"Reset period type ({resetFrequency.period}) and calculation period type ({calculationPeriodFrequency.period}) are different. This is not supported."); } if (int.Parse(resetFrequency.periodMultiplier) != int.Parse(calculationPeriodFrequency.periodMultiplier)) { throw new NotSupportedException( $"Reset period frequency ({resetFrequency.period}) is not equal to calculation period frequency ({calculationPeriodFrequency.period}). This is not supported."); } BusinessDayAdjustments resetDatesAdjustments = resetDates.resetDatesAdjustments; ResetRelativeToEnum resetRelativeTo = resetDates.resetRelativeTo; if (fixingCalendar == null) { fixingCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, resetDatesAdjustments.businessCenters, nameSpace); } foreach (CalculationPeriod calculationPeriodsInPaymentPeriod in listCalculationPeriods) { switch (resetRelativeTo) { case ResetRelativeToEnum.CalculationPeriodStartDate: { DateTime unadjustedResetDate = calculationPeriodsInPaymentPeriod.unadjustedStartDate; DateTime adjustedResetDate = AdjustedDateHelper.ToAdjustedDate(fixingCalendar, unadjustedResetDate, resetDatesAdjustments); adjustedResetDates.Add(adjustedResetDate); break; } case ResetRelativeToEnum.CalculationPeriodEndDate: { DateTime unadjustedResetDate = calculationPeriodsInPaymentPeriod.unadjustedEndDate; DateTime adjustedResetDate = AdjustedDateHelper.ToAdjustedDate(fixingCalendar, unadjustedResetDate, resetDatesAdjustments); adjustedResetDates.Add(adjustedResetDate); break; } default: { throw new NotImplementedException("resetRelativeTo"); } } } return(adjustedResetDates); }
/// <summary> /// /// </summary> /// <param name="cache"></param> /// <param name="nameSpace"></param> /// <param name="properties"></param> /// <returns></returns> protected IBusinessCalendar ExtractFixingCalendar(ICoreCache cache, string nameSpace, NamedValueSet properties) { string[] fixingCalendars = properties.GetArray <string>("FixingCenters"); IBusinessCalendar fixingCalendar = null; if (fixingCalendars != null) { fixingCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, fixingCalendars, nameSpace); } return(fixingCalendar); }
/// <summary> /// /// </summary> /// <param name="cache"></param> /// <param name="nameSpace"></param> /// <param name="properties"></param> /// <returns></returns> protected IBusinessCalendar ExtractPaymentCalendar(ICoreCache cache, string nameSpace, NamedValueSet properties) { string[] paymentCalendars = properties.GetArray <string>("PaymentCenters"); IBusinessCalendar paymentCalendar = null; if (paymentCalendars != null) { paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, paymentCalendars, nameSpace); } return(paymentCalendar); }
public List <DateTime> BuildDates(ILogger logger, ICoreCache cache, String nameSpace, BillSwapPricerDatesRange billSwapPricerDatesRange, IBusinessCalendar paymentCalendar) { CalculationPeriodFrequency frequency = CalculationPeriodFrequencyHelper.Parse(billSwapPricerDatesRange.RollFrequency, billSwapPricerDatesRange.RollConvention); StubPeriodTypeEnum? initialStub = null; if (!String.IsNullOrEmpty(billSwapPricerDatesRange.InitialStubPeriod)) { initialStub = EnumHelper.Parse <StubPeriodTypeEnum>(billSwapPricerDatesRange.InitialStubPeriod); } StubPeriodTypeEnum?finalStub = null; if (!String.IsNullOrEmpty(billSwapPricerDatesRange.FinalStubPeriod)) { finalStub = EnumHelper.Parse <StubPeriodTypeEnum>(billSwapPricerDatesRange.FinalStubPeriod); } //BusinessDayAdjustments adjustments = BusinessDayAdjustmentsHelper.Create(BusinessDayConventionEnum.NONE, ""); //if (paymentCalendar == null) //{ // paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, adjustments.businessCenters);//Make sure this builds a valid calendar! //} BusinessDayAdjustments calculationPeriodDayAdjustments = BusinessDayAdjustmentsHelper.Create(billSwapPricerDatesRange.BusinessDayConvention, billSwapPricerDatesRange.Calendar); if (paymentCalendar == null) { paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, calculationPeriodDayAdjustments.businessCenters, nameSpace); } CalculationPeriodsPrincipalExchangesAndStubs result = CalculationPeriodGenerator.GenerateAdjustedCalculationPeriods( billSwapPricerDatesRange.StartDate, billSwapPricerDatesRange.EndDate, billSwapPricerDatesRange.FirstRegularPeriodStartDate, frequency, calculationPeriodDayAdjustments, initialStub, finalStub, paymentCalendar ); foreach (CalculationPeriod regularCalculationPeriod in result.GetRegularAndStubPeriods()) { // Adjust both startDate & endDate of period // CalculationPeriodHelper.SetAdjustedDates(regularCalculationPeriod, AdjustedDateHelper.ToAdjustedDate(paymentCalendar, regularCalculationPeriod.unadjustedStartDate, calculationPeriodDayAdjustments), AdjustedDateHelper.ToAdjustedDate(paymentCalendar, regularCalculationPeriod.unadjustedEndDate, calculationPeriodDayAdjustments)); } var listResult = result.GetRegularAndStubPeriods().Select(regularCalculationPeriod => regularCalculationPeriod.adjustedStartDate).ToList(); listResult.Add(result.GetRegularAndStubPeriods()[result.GetRegularAndStubPeriods().Count - 1].adjustedEndDate); return(listResult); }
/// <summary> /// /// </summary> /// <param name="logger"></param> /// <param name="cache"></param> /// <param name="capFloorLeg"></param> /// <param name="nameSpace"></param> /// <param name="fixingCalendar"></param> /// <param name="paymentCalendar"></param> /// <param name="spreadSchedule"></param> /// <param name="capOrFloorSchedule"></param> /// <param name="notionalSchedule"></param> /// <returns></returns> public static CapFloor GenerateDefinitionCashflows(ILogger logger, ICoreCache cache, string nameSpace, IBusinessCalendar fixingCalendar, IBusinessCalendar paymentCalendar, CapFloorLegParametersRange capFloorLeg, Schedule spreadSchedule, Schedule capOrFloorSchedule, NonNegativeAmountSchedule notionalSchedule) { if (paymentCalendar == null) { if (!string.IsNullOrEmpty(capFloorLeg.PaymentCalendar)) { var payCalendar = BusinessCentersHelper.Parse(capFloorLeg.PaymentCalendar); paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, payCalendar, nameSpace); } } if (fixingCalendar == null) { if (!string.IsNullOrEmpty(capFloorLeg.FixingCalendar)) { var fixCalendar = BusinessCentersHelper.Parse(capFloorLeg.FixingCalendar); fixingCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, fixCalendar, nameSpace); } } CapFloor capFloor = GenerateDefiniton(capFloorLeg, spreadSchedule, capOrFloorSchedule, notionalSchedule); if (null != spreadSchedule) { InterestRateStreamParametricDefinitionGenerator.SetSpreadSchedule(capFloor.capFloorStream, spreadSchedule); } if (null != notionalSchedule) { InterestRateStreamParametricDefinitionGenerator.SetNotionalSchedule(capFloor.capFloorStream, notionalSchedule); } if (null != capOrFloorSchedule) { if (capFloorLeg.CapOrFloor == CapFloorType.Cap) { InterestRateStreamParametricDefinitionGenerator.SetCapRateSchedule(capFloor.capFloorStream, capOrFloorSchedule, true); } else { InterestRateStreamParametricDefinitionGenerator.SetFloorRateSchedule(capFloor.capFloorStream, capOrFloorSchedule, true); } } capFloor.capFloorStream.cashflows = FixedAndFloatingRateStreamCashflowGenerator.GetCashflows(capFloor.capFloorStream, fixingCalendar, paymentCalendar); return(capFloor); }
private void AddCashFlows(ILogger logger, ICoreCache cache, IBusinessCalendar fixingCalendar, IBusinessCalendar paymentCalendar, Fra fraFpML, bool isBuyer, String nameSpace) { EffectiveDate = fraFpML.adjustedEffectiveDate.Value; TerminationDate = fraFpML.adjustedTerminationDate; if (paymentCalendar == null) { paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, fraFpML.paymentDate.dateAdjustments.businessCenters, nameSpace); } if (fixingCalendar == null) { fixingCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, fraFpML.fixingDateOffset.businessCenters, nameSpace); } DateTime unadjustedPaymentDate = fraFpML.paymentDate.unadjustedDate.Value; var notional = MoneyHelper.GetAmount(fraFpML.notional.amount, fraFpML.notional.currency); PaymentDate = paymentCalendar.Roll(unadjustedPaymentDate, BusinessDayConventionHelper.Parse(fraFpML.paymentDate.dateAdjustments.businessDayConvention.ToString())); DateTime adjustedFixingDate = GetResetDate(logger, cache, fixingCalendar, fraFpML, nameSpace); var interval = fraFpML.indexTenor[0]; var floatingInterest = new PriceableFloatingRateCoupon(fraFpML.id + "FloatingCoupon_1" , isBuyer , EffectiveDate , TerminationDate , adjustedFixingDate , fraFpML.dayCountFraction , 0.0m , FixedRate , null , isBuyer ? MoneyHelper.Neg(notional) : notional , PaymentDate , new ForecastRateIndex { floatingRateIndex = fraFpML.floatingRateIndex, indexTenor = interval } , null , null , fraFpML.fraDiscounting , paymentCalendar , fixingCalendar) { ForecastRateInterpolation = ForecastRateInterpolation }; // Combine two cashflows into one leg // FloatingCoupon = floatingInterest;//fraFpML.fraDiscounting, }
public static void UpdatePaymentsAmounts(ILogger logger, ICoreCache cache, String nameSpace, Swap swap, SwapLegParametersRange leg1Parameters, SwapLegParametersRange leg2Parameters, IRateCurve leg1DiscountCurve, IRateCurve leg2DiscountCurve, DateTime valuationDate, IBusinessCalendar paymentCalendar) { foreach (Payment payment in swap.additionalPayment) { // choose correct discount curve // IRateCurve discountCurve; if (payment.payerPartyReference.href == leg1Parameters.Payer) { discountCurve = leg1DiscountCurve; } else if (payment.payerPartyReference.href == leg2Parameters.Payer) { discountCurve = leg2DiscountCurve; } else { throw new NotImplementedException(); } if (paymentCalendar == null) { var containsPaymentDateAdjustments = AdjustableOrAdjustedDateHelper.Contains(payment.paymentDate, ItemsChoiceType.dateAdjustments, out var dateAdjustments); if (containsPaymentDateAdjustments && dateAdjustments != null) { paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, ((BusinessDayAdjustments)dateAdjustments). businessCenters, nameSpace); } } var date = AdjustedDateHelper.GetAdjustedDate(paymentCalendar, payment.paymentDate); if (date == null) { continue; } payment.discountFactor = (decimal)discountCurve.GetDiscountFactor(valuationDate, (DateTime)date); payment.discountFactorSpecified = true; payment.presentValueAmount = MoneyHelper.Mul(payment.paymentAmount, payment.discountFactor); } }
/// <summary> /// </summary> /// <param name="cache"></param> /// <param name="interestRateStream"></param> /// <param name="listAdjustedResetDates"></param> /// <param name="businessCalendar"></param> /// <param name="nameSpace"></param> /// <returns></returns> /// <exception cref="NotSupportedException"></exception> public static List <DateTime> GetAdjustedFixingDates(ICoreCache cache, InterestRateStream interestRateStream, List <DateTime> listAdjustedResetDates, IBusinessCalendar businessCalendar, string nameSpace) { var result = new List <DateTime>(); RelativeDateOffset fixingDatesOffset = interestRateStream.resetDates.fixingDates; int numberOfDays = int.Parse(fixingDatesOffset.periodMultiplier); // Only NON-POSITIVE offset expressed in BUSINESS DAYS is supported. // if (!(fixingDatesOffset.dayType == DayTypeEnum.Business & fixingDatesOffset.period == PeriodEnum.D & numberOfDays <= 0)) { string exceptionMessage = $"[{fixingDatesOffset.dayType} {fixingDatesOffset.period} {numberOfDays} days] fixing day offset is not supported."; throw new NotSupportedException(exceptionMessage); } var businessDayAdjustments = new BusinessDayAdjustments { businessCenters = fixingDatesOffset.businessCenters, businessDayConvention = fixingDatesOffset.businessDayConvention }; if (businessCalendar == null) { businessCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, businessDayAdjustments.businessCenters, nameSpace); } foreach (DateTime adjustedResetDate in listAdjustedResetDates) { int offsetInBusinessDays = numberOfDays; DateTime adjustedFixingDate = adjustedResetDate; while (offsetInBusinessDays++ < 0) { // Adjust fixing date for one days back. // do { adjustedFixingDate = adjustedFixingDate.AddDays(-1); } while (!businessCalendar.IsBusinessDay(adjustedFixingDate)); // adjustedFixingDate has been adjusted for 1 BUSINESS DAY } result.Add(adjustedFixingDate); } return(result); }
/// <summary> /// Gets the reset date. /// </summary> /// <param name="logger"> </param> /// <param name="cache"> </param> /// <param name="fixingCalendar"> </param> /// <param name="fraFpML">The fraFpML.</param> /// <param name="nameSpace"></param> /// <returns></returns> private static DateTime GetResetDate(ILogger logger, ICoreCache cache, IBusinessCalendar fixingCalendar, Fra fraFpML, String nameSpace) { var effectiveDateId = fraFpML.adjustedEffectiveDate.id; var fixingdateRef = fraFpML.fixingDateOffset.dateRelativeTo.href; DateTime resetDate = fraFpML.adjustedEffectiveDate.Value; if (fixingCalendar == null) { fixingCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, fraFpML.fixingDateOffset.businessCenters, nameSpace); } if (fixingdateRef == effectiveDateId) { resetDate = AdjustedDateHelper.ToAdjustedDate(fixingCalendar, fraFpML.adjustedEffectiveDate.Value, fraFpML.fixingDateOffset); } logger.LogInfo("Reset date set."); return(resetDate); }
private void SetFraDates(ICoreCache cache, string nameSpace, RateCurve initialCurve, IEnumerable <int> instrumentIndicies) { FraStartDates = new List <DateTime>(); FraEndDates = new List <DateTime>(); foreach (int i in instrumentIndicies) { CheckDepositInstrument(i); var rateAssetController = (PriceableDeposit)initialCurve.PriceableRateAssets[i]; DateTime startDate = CalculateFraStartTime(rateAssetController); FraStartDates.Add(startDate); var deposit = rateAssetController; //BusinessDayConventionEnum adjustment = deposit.BusinessDayAdjustments.businessDayConvention; BusinessCenters bs = deposit.SpotDateOffset.businessCenters; var calendar = BusinessCenterHelper.ToBusinessCalendar(cache, bs, nameSpace); DateTime endDate = CalculateFraEndTime(calendar, rateAssetController); FraEndDates.Add(endDate); } }
/// <summary> /// Master function used by the constructor to initialise all /// private fields. /// </summary> /// <param name="logger">The logger.</param> /// <param name="cache">The cache.</param> /// <param name="nameSpace">The clients namespace</param> /// <param name="businessCalendar">Four letter (uppercase) code for /// the business calendar that will be used to generate all dates in /// the swap schedule. /// Example: AUSY.</param> /// <param name="calculationDate">Base date.</param> /// <param name="dayCount">Three letter (uppercase) code for the day /// count convention that will be used to compute the accrual factors. /// Example: ACT/365.</param> /// <param name="discountFactors">Array of known discount factors. /// </param> /// <param name="offsets">The number of days from the Calculation /// Date to each known discount factor.</param> /// <param name="fixedSideFrequency">Roll frequency (number of /// rolls/payments per year) on the fixed side of the swap. /// Precondition: must be a divisor of 12. /// Example: Quarterly corresponds to a frequency of 4; Monthly /// corresponds to a frequency of 12.</param> /// <param name="rollConvention">Roll convention used to generate /// the swap schedule. /// Example: MODFOLLOWING.</param> private void InitialisePrivateFields (ILogger logger, ICoreCache cache, string nameSpace, string businessCalendar, DateTime calculationDate, string dayCount, double[] discountFactors, int[] offsets, int fixedSideFrequency, BusinessDayConventionEnum rollConvention) { // Initialise all private fields, except for the one dimensional // interpolation object. _businessCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, new[] { businessCalendar }, nameSpace); _calculationDate = calculationDate; _discountFactors = null; _dayCount = dayCount; _fixedSideFrequency = fixedSideFrequency; _rollConvention = rollConvention; _swapSchedule = null; // Initialise the one dimensional interpolation object. InitialiseDiscountFactorObject(discountFactors, offsets); logger.LogDebug("Discount factors initialised."); }
/// <summary> /// Initializes a new instance of the <see cref="PriceableInterestRateStream"/> class. /// </summary> /// <param name="logger">The logger.</param> /// <param name="cache">The cache.</param> /// <param name="nameSpace">The client namespace.</param> /// <param name="swapId">The swap Id.</param> /// <param name="payerPartyReference">The payer party reference.</param> /// <param name="receiverPartyReference">The receiver party reference.</param> /// <param name="payerIsBase">The flag for whether the payer reference is the base party.</param> /// : AdjustedDateHelper.ToAdjustedDate(forecastRateIndex.indexTenor.Add(AccrualStartDate), AccrualBusinessDayAdjustments);</param> /// <param name="paymentCalendar">The paymentCalendar.</param> public PriceableLease ( ILogger logger , ICoreCache cache , String nameSpace , string swapId , string payerPartyReference , string receiverPartyReference , bool payerIsBase , IBusinessCalendar paymentCalendar) { Multiplier = 1.0m; Payer = payerPartyReference; Receiver = receiverPartyReference; PayerIsBaseParty = payerIsBase; PaymentCurrencies = new List <string>(); AnalyticsModel = new StructuredStreamAnalytic(); Id = BuildId(swapId, CouponStreamType); //Get the currency. var currency = XsdClassesFieldResolver.CalculationGetNotionalSchedule(Calculation); Currency = currency.notionalStepSchedule.currency; if (!PaymentCurrencies.Contains(Currency.Value)) { PaymentCurrencies.Add(Currency.Value); } //The calendars if (paymentCalendar == null) { paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, PaymentDates.paymentDatesAdjustments.businessCenters, nameSpace); } //Set the default discount curve name. DiscountCurveName = CurveNameHelpers.GetDiscountCurveName(Currency.Value, true); RiskMaturityDate = LastDate(); logger.LogInfo("Stream built"); }
/// <summary> /// Process a CapFloor ATM parvVols structure. /// The process Bootstraps the parVols using the supplied ratecurve /// </summary> /// <param name="logger">The logger</param> /// <param name="cache">The cache.</param> /// <param name="nameSpace"></param> /// <param name="rateCurve"></param> /// <param name="capFloor"></param> /// <returns></returns> private static Market ProcessCapFloorATM(ILogger logger, ICoreCache cache, string nameSpace, Market rateCurve, CapFloorATMMatrix capFloor) { var id = capFloor.id; var expiry = capFloor.GetExpiries(); var vols = capFloor.GetVolatilities(); var mkt = rateCurve; var curve = new SimpleRateCurve(mkt); var discountFactorDates = curve.GetDiscountFactorDates(); var discountFactors = curve.GetDiscountFactors(); var volType = capFloor.GetVolatilityTypes(); var atmVols = new Dictionary <string, decimal>(); var settings = CreateCapFloorProperties(capFloor.GetVolatilitySettings()); // Create an internal matrix object from the raw data var matrix = new CapFloorVolatilityMatrix(id, expiry, volType, vols, null, discountFactorDates, ArrayUtilities.ArrayToDecimal(discountFactors)); // Create an ATM engine from the matrix var engines = CreateEngines(logger, cache, nameSpace, id, matrix, settings); // Add the default interpolation to use const ExpiryInterpolationType volatilityInterpolation = ExpiryInterpolationType.Linear; if (engines != null) { var vol = new CapletExpiryInterpolatedVolatility(engines[0], volatilityInterpolation); // List the values so we can build our ATM vols var keys = ExpiryKeys.Split(','); // Create a calendar to use to modify the date var businessCalendar = settings.GetValue("BusinessCalendar", "AUSY"); var bc = BusinessCenterHelper.ToBusinessCalendar(cache, new[] { businessCalendar }, nameSpace); // Use some logic to get the spot date to use // LPM Spot lag is 2 days (modfollowing) var spotDate = curve.GetSpotDate(); var rollConvention = settings.GetValue("RollConvention", BusinessDayConventionEnum.FOLLOWING); spotDate = spotDate == curve.GetBaseDate() ? bc.Roll(spotDate.Add(new TimeSpan(2, 0, 0, 0)), rollConvention) : spotDate; //// Extract each surface and build an ATM engine therefrom //// Build a list of all possible engines foreach (var key in keys) { // Calculate the volatility for each target key var tv = PeriodHelper.Parse(key); var target = tv.period == PeriodEnum.D ? bc.Roll(spotDate.AddDays(Convert.ToInt32(tv.periodMultiplier)), rollConvention) : bc.Roll(spotDate.AddMonths(Convert.ToInt32(tv.periodMultiplier)), rollConvention); atmVols.Add(key, vol.ComputeCapletVolatility(target)); } } var outputVols = new object[atmVols.Count + 1, 2]; var i = 1; //Expiry 0 outputVols[0, 0] = "Expiry"; outputVols[0, 1] = "0"; foreach (var key in atmVols.Keys) { outputVols[i, 0] = key; outputVols[i, 1] = atmVols[key]; i++; } DateTime buildDateTime = rateCurve.Items1[0].buildDateTime; var volSurface = new VolatilitySurface(outputVols, new VolatilitySurfaceIdentifier(id), curve.BaseDate, buildDateTime); return(CreateMarketDocument(volSurface.GetFpMLData())); }
/// <summary> /// /// </summary> /// <param name="logger"></param> /// <param name="cache"></param> /// <param name="nameSpace"></param> /// <param name="tradeDate"></param> /// <param name="effectiveDate"></param> /// <param name="referenceEquity"></param> /// <param name="settlementCalendar"></param> /// <param name="equityFpML"></param> /// <param name="basePartyReference"></param> /// <param name="forecastRateInterpolation"></param> public EquityTransactionPricer(ILogger logger, ICoreCache cache, string nameSpace, DateTime tradeDate, DateTime effectiveDate, String referenceEquity, IBusinessCalendar settlementCalendar, EquityTransaction equityFpML, string basePartyReference, Boolean forecastRateInterpolation) { logger.LogInfo("EquityType set. Commence to build a equity transaction."); if (equityFpML == null) { return; } SettlementDate = effectiveDate; TradeDate = tradeDate; Multiplier = 1.0m; BuyerReference = equityFpML.buyerPartyReference.href; PaymentCurrencies = new List <string> { equityFpML.unitPrice.currency.Value }; SellerReference = equityFpML.sellerPartyReference.href; BasePartyBuyer = basePartyReference == equityFpML.buyerPartyReference.href; ForecastRateInterpolation = forecastRateInterpolation; SettlementCalendar = settlementCalendar; ReferenceEquity = referenceEquity; NumberOfShares = Convert.ToInt16(equityFpML.numberOfUnits); PurchasePrice = MoneyHelper.GetAmount(equityFpML.unitPrice.amount, equityFpML.unitPrice.currency.Value); PaymentCurrencies = new List <string> { equityFpML.unitPrice.currency.Value }; var exchangeMIC = equityFpML.equity.exchangeId; var exchangeMICData = InstrumentDataHelper.CreateEquityExchangeKey(nameSpace, exchangeMIC.Value); var exchangeData = cache.LoadItem <ExchangeConfigData>(exchangeMICData); if (exchangeData?.Data is ExchangeConfigData) { var exchange = (ExchangeConfigData)exchangeData.Data; var equityTypeInfo = new EquityNodeStruct { SettlementDate = exchange.SettlementDate }; if (equityFpML.equity != null) { if (SettlementCalendar == null) { SettlementCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, equityTypeInfo.SettlementDate .businessCenters, nameSpace); } if (PaymentCalendar == null) { PaymentCalendar = SettlementCalendar; } var equity = XmlSerializerHelper.Clone(equityFpML.equity); EquityTypeInfo = XmlSerializerHelper.Clone(equityTypeInfo); EquityTypeInfo.Equity = equity;; RiskMaturityDate = SettlementDate; MaturityDate = SettlementDate; if (!PaymentCurrencies.Contains(equityFpML.equity.currency.Value)) { PaymentCurrencies.Add(equityFpML.equity.currency.Value); } logger.LogInfo("Equity transaction has been successfully created."); } } else { logger.LogInfo("Equity type data not available."); } //Add payments like the settlement price if (PurchasePrice == null || !PurchasePrice.amountSpecified) { return; } var amount = PurchasePrice.amount * NumberOfShares; var settlementPayment = PaymentHelper.Create("EquitySettlemetAmount", BuyerReference, SellerReference, amount, SettlementDate); AdditionalPayments = PriceableInstrumentsFactory.CreatePriceablePayments(basePartyReference, new[] { settlementPayment }, PaymentCalendar); if (!PaymentCurrencies.Contains(settlementPayment.paymentAmount.currency.Value)) { PaymentCurrencies.Add(settlementPayment.paymentAmount.currency.Value); } }
public PropertyTransactionPricer(ILogger logger, ICoreCache cache, string nameSpace, DateTime paymentDate, String referenceContract, IBusinessCalendar settlementCalendar, PropertyTransaction propertyFpML, string basePartyReference, Boolean forecastRateInterpolation) { logger.LogInfo("PropertyType set. Commence to build a property transaction."); if (propertyFpML == null) { return; } // //Set the multiplier // Multiplier = 1.0m; // //Set the trade information // BuyerReference = propertyFpML.buyerPartyReference.href; PaymentCurrencies = new List <string> { propertyFpML.purchasePrice.currency.Value }; SellerReference = propertyFpML.sellerPartyReference.href; BasePartyBuyer = basePartyReference == propertyFpML.buyerPartyReference.href; ForecastRateInterpolation = forecastRateInterpolation; SettlementCalendar = settlementCalendar; PaymentDate = paymentDate; // //Set the issuer information // ReferenceContract = referenceContract; // //Set the notional information // PurchasePrice = MoneyHelper.GetAmount(propertyFpML.purchasePrice.amount, propertyFpML.purchasePrice.currency.Value); PaymentCurrencies = new List <string> { propertyFpML.purchasePrice.currency.Value }; // //Get the instrument configuration information. // var propertyTypeInfo = propertyFpML.property; if (propertyFpML.property != null && propertyTypeInfo != null) { if (SettlementCalendar == null) { SettlementCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, propertyTypeInfo.businessDayAdjustments.businessCenters, nameSpace); } //Pre processes the data for the priceable asset. PropertyInfo = XmlSerializerHelper.Clone(propertyTypeInfo); //This is done because the config data is not stored in the correct way. Need to add a price quote units. //TODO Set other relevant property information //PropertyTypeInfo.Property.faceAmount = NotionalAmount.amount; if (!PaymentCurrencies.Contains(propertyFpML.purchasePrice.currency.Value)) { PaymentCurrencies.Add(propertyFpML.purchasePrice.currency.Value); } logger.LogInfo("Property transaction has been successfully created."); } else { logger.LogInfo("Property type data not available."); } }
/// <summary> /// Convert the cap/floor PPD values to an ATM parVols structure /// This method then calls the bootstrapper <see cref="ProcessCapFloorPpd"/> /// to generate the capvol curve /// </summary> /// <param name="logger">The logger</param> /// <param name="cache">The cache.</param> /// <param name="rateCurve"></param> /// <param name="capFloor"></param> /// <param name="nameSpace"></param> /// <returns></returns> private static Market ProcessCapFloorPpd(ILogger logger, ICoreCache cache, string nameSpace, Market rateCurve, CapFloorATMMatrix capFloor) { var expiry = capFloor.GetExpiries(); var vols = capFloor.GetVolatilities(); var mkt = rateCurve; var curve = new SimpleRateCurve(mkt); var rawOffsets = curve.GetDiscountFactorOffsets(); var offsets = Array.ConvertAll(rawOffsets, IntToDouble); var discountFactors = curve.GetDiscountFactors(); var volType = capFloor.GetVolatilityTypes(); var atmVols = new Dictionary <string, decimal>(); var settings = CreateCapFloorProperties(capFloor.GetVolatilitySettings()); var bc = BusinessCenterHelper.ToBusinessCalendar(cache, new[] { "AUSY" }, nameSpace); // Use some logic to get the spot date to use // Step through each vol and convert ppd to ATM vol for (var i = 0; i < expiry.Length; i++) { // Create a Swaprate for each expiry // Assume frequency = 4 months until 4 years tenor is reached Period tv = PeriodHelper.Parse(expiry[i]); //double tvYearFraction = tv.ToYearFraction(); //int frequency = tvYearFraction < 4 ? 4 : 2; const int frequency = 4; var rates = new SwapRate(logger, cache, nameSpace, "AUSY", curve.GetBaseDate(), "ACT/365.FIXED", discountFactors, curve.GetDiscountFactorOffsets(), frequency, BusinessDayConventionEnum.MODFOLLOWING); switch (volType[i]) { case "ETO": { DateTime spotDate = settings.GetValue("Calculation Date", DateTime.MinValue); var rollConvention = settings.GetValue("RollConvention", BusinessDayConventionEnum.MODFOLLOWING); DateTime etoDate = bc.Roll(tv.Add(spotDate), rollConvention); atmVols[expiry[i]] = CalculateATMVolatility(settings, spotDate, etoDate, offsets, discountFactors, vols[i][0]); } break; case "Cap/Floor": { DateTime spotDate = settings.GetValue("Calculation Date", DateTime.MinValue); var rollConvention = settings.GetValue("RollConvention", BusinessDayConventionEnum.MODFOLLOWING); DateTime expiryDate = bc.Roll(tv.Add(spotDate), rollConvention); string tenor = DateToTenor(spotDate, expiryDate); double tenorYearFraction = PeriodHelper.Parse(tenor).ToYearFraction(); // Add the caplet maturity to the expiry and then calculate the vol atmVols[expiry[i]] = CalculateCAPATMVolatility(rates, spotDate, tenorYearFraction, vols[i][0]); } break; } } // Fudge to switch the PPD header to ATM // We've converted so we want the new name var headers = capFloor.GetHeaders(); for (var i = 0; i < headers.Length; i++) { if (!headers[i].Contains("PPD")) { continue; } headers[i] = "ATM"; break; } // Convert our lovely dictionary to a grubby array of arrays var volatilities = new object[atmVols.Keys.Count][]; var row = 0; foreach (var key in atmVols.Keys) { volatilities[row] = new object[3]; volatilities[row][0] = key; volatilities[row][1] = atmVols[key]; volatilities[row][2] = volType[row++]; } var convertedCapFloor = new CapFloorATMMatrix(headers, volatilities, capFloor.GetVolatilitySettings(), capFloor.baseDate.Value, capFloor.id); return(ProcessCapFloorATM(logger, cache, nameSpace, rateCurve, convertedCapFloor)); }
/// <summary> /// Initializes a new instance of the <see cref="PriceableInterestRateStream"/> class. /// </summary> /// <param name="logger">The logger.</param> /// <param name="cache">The cache.</param> /// <param name="nameSpace">The client namesspace.</param> /// <param name="swapId">The swap Id.</param> /// <param name="payerPartyReference">The payer party reference.</param> /// <param name="receiverPartyReference">The receiver party reference.</param> /// <param name="payerIsBase">The flag for whether the payerreference is the base party.</param> /// <param name="calculationPeriodDates">The caluclation period date information.</param> /// <param name="paymentDates">The payment dates of the swap leg.</param> /// <param name="resetDates">The reset dates of the swap leg.</param> /// <param name="principalExchanges">The principal Exchange type.</param> /// <param name="calculationPeriodAmount">The calculation period amount data.</param> /// <param name="stubCalculationPeriodAmount">The stub calculation information.</param> /// <param name="cashflows">The FpML cashflows for that stream.</param> /// <param name="settlementProvision">The settlement provision data.</param> /// <param name="forecastRateInterpolation">ForwardEndDate = forecastRateInterpolation ? AccrualEndDate /// : AdjustedDateHelper.ToAdjustedDate(forecastRateIndex.indexTenor.Add(AccrualStartDate), AccrualBusinessDayAdjustments);</param> /// <param name="fixingCalendar">The fixingCalendar.</param> /// <param name="paymentCalendar">The paymentCalendar.</param> public PriceableInterestRateStream ( ILogger logger , ICoreCache cache , String nameSpace , string swapId , string payerPartyReference , string receiverPartyReference , bool payerIsBase , CalculationPeriodDates calculationPeriodDates , PaymentDates paymentDates , ResetDates resetDates , PrincipalExchanges principalExchanges , CalculationPeriodAmount calculationPeriodAmount , StubCalculationPeriodAmount stubCalculationPeriodAmount , Cashflows cashflows , SettlementProvision settlementProvision , bool forecastRateInterpolation , IBusinessCalendar fixingCalendar , IBusinessCalendar paymentCalendar) { Multiplier = 1.0m; Payer = payerPartyReference; Receiver = receiverPartyReference; PayerIsBaseParty = payerIsBase; CalculationPeriodDates = calculationPeriodDates; PaymentDates = paymentDates; PaymentCurrencies = new List <string>(); ResetDates = resetDates; PrincipalExchanges = principalExchanges; CalculationPeriodAmount = calculationPeriodAmount; AnalyticsModel = new StructuredStreamAnalytic(); Calculation = (Calculation)CalculationPeriodAmount.Item; if (Calculation.Items?[0] is Schedule strikeSchedule) { Strike = strikeSchedule.initialValue;//Only picks up the first fixed rate for the swaption calculation. } StubCalculationPeriodAmount = stubCalculationPeriodAmount; Cashflows = cashflows; CouponStreamType = CouponTypeFromCalculation(Calculation); Id = BuildId(swapId, CouponStreamType); ForecastRateInterpolation = forecastRateInterpolation; var isThereDiscounting = XsdClassesFieldResolver.CalculationHasDiscounting(Calculation); if (isThereDiscounting) { IsDiscounted = true; //TODO need to include rate logic for the correct solved answers. What about reset cashflows?? } //Get the currency. var currency = XsdClassesFieldResolver.CalculationGetNotionalSchedule(Calculation); Currency = currency.notionalStepSchedule.currency; if (!PaymentCurrencies.Contains(Currency.Value)) { PaymentCurrencies.Add(Currency.Value); } //The calendars if (paymentCalendar == null) { paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, PaymentDates.paymentDatesAdjustments.businessCenters, nameSpace); } SettlementProvision = settlementProvision; //Set the default discount curve name. DiscountCurveName = CurveNameHelpers.GetDiscountCurveName(Currency.Value, true); //Set the forecast curve name.//TODO extend this to the other types. if (CouponStreamType != CouponStreamType.GenericFixedRate) { if (fixingCalendar == null) { fixingCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, ResetDates.resetDatesAdjustments.businessCenters, nameSpace); } ForecastCurveName = null; if (Calculation.Items != null) { var floatingRateCalculation = Calculation.Items; var floatingRateIndex = (FloatingRateCalculation)floatingRateCalculation[0]; ForecastCurveName = CurveNameHelpers.GetForecastCurveName(floatingRateIndex); } } //Build the coupons and principal exchanges. if (GetCashflowPaymentCalculationPeriods() != null) { Coupons = PriceableInstrumentsFactory.CreatePriceableCoupons(PayerIsBaseParty, GetCashflowPaymentCalculationPeriods(), Calculation, ForecastRateInterpolation, fixingCalendar, paymentCalendar);//TODO add the stubcalculation. UpdateCouponIds(); } if (GetCashflowPrincipalExchanges() != null) { var exchanges = GetCashflowPrincipalExchanges(); Exchanges = PriceableInstrumentsFactory.CreatePriceablePrincipalExchanges(PayerIsBaseParty, exchanges, Currency.Value, paymentCalendar); UpdateExchangeIds(); } RiskMaturityDate = LastDate(); logger.LogInfo("Stream built"); }
/// <summary> /// /// </summary> /// <param name="logger"></param> /// <param name="cache"></param> /// <param name="paymentCalendar"> </param> /// <param name="capFloorFpML"></param> /// <param name="basePartyReference"></param> /// <param name="forecastRateInterpolation"></param> /// <param name="nameSpace"></param> /// <param name="fixingCalendar"> </param> public CapFloorPricer(ILogger logger, ICoreCache cache, String nameSpace, IBusinessCalendar fixingCalendar, IBusinessCalendar paymentCalendar, CapFloor capFloorFpML, string basePartyReference, Boolean forecastRateInterpolation) { if (capFloorFpML == null) { return; } //AnalyticsModel = new SimpleIRSwapInstrumentAnalytic(); BusinessCentersResolver.ResolveBusinessCenters(capFloorFpML); ForecastRateInterpolation = forecastRateInterpolation; //We make the assumption that the termination date is the same for all legs.. AdjustableDate adjustableTerminationDate = XsdClassesFieldResolver.CalculationPeriodDatesGetTerminationDate(capFloorFpML.capFloorStream.calculationPeriodDates); if (paymentCalendar == null) { paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, adjustableTerminationDate.dateAdjustments.businessCenters, nameSpace); } RiskMaturityDate = AdjustedDateHelper.ToAdjustedDate(paymentCalendar, adjustableTerminationDate); ProductType = ProductTypeSimpleEnum.CapFloor; PaymentCurrencies = new List <string>(); //Resolve the payer if (capFloorFpML.capFloorStream == null) { return; } var calculation = capFloorFpML.capFloorStream.calculationPeriodAmount.Item as Calculation; var floatingRatecalculation = calculation?.Items[0] as FloatingRateCalculation; if (floatingRatecalculation == null) { return; } if (floatingRatecalculation.capRateSchedule != null) { var schedule = floatingRatecalculation.capRateSchedule[0]; var buyerPartyReference = schedule.buyer.Value; if (buyerPartyReference == PayerReceiverEnum.Receiver) { BuyerPartyReference = capFloorFpML.capFloorStream.receiverPartyReference.href; SellerPartyReference = capFloorFpML.capFloorStream.payerPartyReference.href; } else { BuyerPartyReference = capFloorFpML.capFloorStream.payerPartyReference.href; SellerPartyReference = capFloorFpML.capFloorStream.receiverPartyReference.href; } } if (floatingRatecalculation.capRateSchedule == null && floatingRatecalculation.floorRateSchedule != null) { var schedule = floatingRatecalculation.floorRateSchedule[0]; var buyerPartyReference = schedule.buyer.Value; if (buyerPartyReference == PayerReceiverEnum.Receiver) { BuyerPartyReference = capFloorFpML.capFloorStream.receiverPartyReference.href; SellerPartyReference = capFloorFpML.capFloorStream.payerPartyReference.href; } else { BuyerPartyReference = capFloorFpML.capFloorStream.payerPartyReference.href; SellerPartyReference = capFloorFpML.capFloorStream.receiverPartyReference.href; } } BasePartyBuyer = basePartyReference == BuyerPartyReference;//TODO add in the calendar functionality. //Set the id of the first stream. THe generator requires the flag: BasePartyPayer. var capFloorLeg = new PriceableCapFloorStream(logger, cache, nameSpace, !BasePartyBuyer, capFloorFpML.capFloorStream, ForecastRateInterpolation, fixingCalendar, paymentCalendar); Legs.Add(capFloorLeg); //Add the currencies for the trade pricer. if (!PaymentCurrencies.Contains(capFloorLeg.Currency.Value)) { PaymentCurrencies.Add(capFloorLeg.Currency.Value); } if (capFloorFpML.additionalPayment != null) { AdditionalPayments = PriceableInstrumentsFactory.CreatePriceablePayments(basePartyReference, capFloorFpML.additionalPayment, null); foreach (var payment in capFloorFpML.additionalPayment) { if (!PaymentCurrencies.Contains(payment.paymentAmount.currency.Value)) { PaymentCurrencies.Add(payment.paymentAmount.currency.Value); } } } }
/// <summary> /// /// </summary> /// <param name="logger"></param> /// <param name="cache"></param> /// <param name="nameSpace"></param> /// <param name="legCalendars"></param> /// <param name="trade"></param> /// <param name="tradeProps"></param> /// <param name="forecastRateInterpolation"></param> public TradePricer(ILogger logger, ICoreCache cache, String nameSpace, List <Pair <IBusinessCalendar, IBusinessCalendar> > legCalendars, Trade trade, NamedValueSet tradeProps, bool forecastRateInterpolation) { if (tradeProps == null) { tradeProps = new NamedValueSet();//TODO Need to generate properties for the FpML examples. } var tradeIdentifier = new TradeIdentifier(tradeProps); TradeIdentifier = tradeIdentifier; TradeHeader = trade.tradeHeader; //Get the baseParty, which in GWML is the originating party. BaseParty = tradeProps.GetValue <string>(TradeProp.BaseParty, false) ?? TradeProp.Party1; var party1 = tradeProps.GetValue <string>(TradeProp.Party1, true); var party2 = tradeProps.GetValue <string>(TradeProp.Party2, true); Parties = new List <Party> { new Party { partyName = new PartyName { Value = party1 } }, new Party { partyName = new PartyName { Value = party2 } } }; TradeType = trade.ItemElementName; //Determine the product type, so that the appropriate productPricer can be instantiated. //Set the product type var productType = tradeIdentifier.ProductType; //Check whether the business calendars list is null. Pair <IBusinessCalendar, IBusinessCalendar> firstCalendarPair = null; if (legCalendars?.Count > 0) { firstCalendarPair = legCalendars[0]; } //Instantiate the productPricer. if (productType != null && productType != ProductTypeSimpleEnum.Undefined) { ProductType = (ProductTypeSimpleEnum)productType; switch (ProductType) { case ProductTypeSimpleEnum.PropertyTransaction: { IBusinessCalendar settlementCalendar = null; if (firstCalendarPair != null) { settlementCalendar = firstCalendarPair.First; } var property = (PropertyTransaction)trade.Item; var tradeDate = tradeProps.GetValue <DateTime>(TradeProp.TradeDate, false); var referenceProperty = tradeProps.GetValue <String>(PropertyProp.ReferenceProperty, false); //Get the instrument configuration data. //Modify the pricer to include this data. PriceableProduct = new PropertyTransactionPricer(logger, cache, nameSpace, tradeDate, referenceProperty, settlementCalendar, property, BaseParty, forecastRateInterpolation); ProductReporter = new PropertyTransactionReporter(); } break; case ProductTypeSimpleEnum.EquityTransaction: { IBusinessCalendar settlementCalendar = null; if (firstCalendarPair != null) { settlementCalendar = firstCalendarPair.First; } var equity = (EquityTransaction)trade.Item; var tradeDate = tradeProps.GetValue <DateTime>(TradeProp.TradeDate, true); var effectiveDate = tradeProps.GetValue <DateTime>(TradeProp.EffectiveDate, true); var referenceEquity = tradeProps.GetValue <String>(EquityProp.ReferenceEquity, false); //Get the instrument configuration data. //Modify the pricer to include this data. PriceableProduct = new EquityTransactionPricer(logger, cache, nameSpace, tradeDate, effectiveDate, referenceEquity, settlementCalendar, equity, BaseParty, forecastRateInterpolation); ProductReporter = new EquityTransactionReporter(); } break; case ProductTypeSimpleEnum.BondTransaction: { IBusinessCalendar settlementCalendar = null; if (firstCalendarPair != null) { settlementCalendar = firstCalendarPair.First; } var bond = (BondTransaction)trade.Item; var tradeDate = tradeProps.GetValue <DateTime>(TradeProp.TradeDate, true); var effectiveDate = tradeProps.GetValue <DateTime>(TradeProp.EffectiveDate, true); var bondType = tradeProps.GetValue <string>(BondProp.BondType, false); //Get the instrument configuration data. //Modify the pricer to include this data. PriceableProduct = new BondTransactionPricer(logger, cache, nameSpace, tradeDate, effectiveDate, settlementCalendar, settlementCalendar, bond, BaseParty, bondType, forecastRateInterpolation); ProductReporter = new BondTransactionReporter(); } break; case ProductTypeSimpleEnum.FutureTransaction: { IBusinessCalendar settlementCalendar = null; if (firstCalendarPair != null) { settlementCalendar = firstCalendarPair.First; } var future = (FutureTransaction)trade.Item; var tradeDate = tradeProps.GetValue <DateTime>(TradeProp.TradeDate, false); var type = tradeProps.GetValue <String>(FuturesProp.FuturesType, true); var futureType = EnumHelper.Parse <ExchangeContractTypeEnum>(type); //Get the instrument configuration data. //Modify the pricer to include this data. PriceableProduct = new FutureTransactionPricer(logger, cache, nameSpace, tradeDate, futureType, settlementCalendar, future, BaseParty, forecastRateInterpolation); ProductReporter = new FutureTransactionReporter(); } break; case ProductTypeSimpleEnum.InterestRateSwap: { var swap = (Swap)trade.Item; PriceableProduct = new InterestRateSwapPricer(logger, cache, nameSpace, legCalendars, swap, BaseParty, forecastRateInterpolation); ProductReporter = new InterestRateSwapReporter(); } break; case ProductTypeSimpleEnum.AssetSwap: { var swap = (Swap)trade.Item; //TODO set for the payer. This needs to be modified for the base counterparty. PriceableProduct = new AssetSwapPricer(logger, cache, nameSpace, legCalendars, swap, BaseParty, new Bond(), forecastRateInterpolation); ProductReporter = new InterestRateSwapReporter(); } break; case ProductTypeSimpleEnum.CrossCurrencySwap: { var swap = (Swap)trade.Item; //TODO set for the payer. This needs to be modified for the base counterparty. PriceableProduct = new CrossCurrencySwapPricer(logger, cache, nameSpace, legCalendars, swap, BaseParty, forecastRateInterpolation); ProductReporter = new InterestRateSwapReporter(); } break; case ProductTypeSimpleEnum.FRA: // todo { var fra = (Fra)trade.Item; IBusinessCalendar fixingCalendar = null; IBusinessCalendar paymentCalendar = null; if (firstCalendarPair != null) { fixingCalendar = firstCalendarPair.First; paymentCalendar = firstCalendarPair.Second; } PriceableProduct = new FraPricer(logger, cache, fixingCalendar, paymentCalendar, fra, BaseParty, nameSpace) { ForecastRateInterpolation = forecastRateInterpolation }; ProductReporter = new ForwardRateAgreementReporter(); } break; //case ProductTypeSimpleEnum.InflationSwap: // break; //case ProductTypeSimpleEnum.CreditDefaultSwap: // break; //case ProductTypeSimpleEnum.TotalReturnSwap: // break; //case ProductTypeSimpleEnum.VarianceSwap: // break; case ProductTypeSimpleEnum.CapFloor: { var capFloor = (CapFloor)trade.Item; IBusinessCalendar fixingCalendar = null; IBusinessCalendar paymentCalendar = null; if (firstCalendarPair != null) { fixingCalendar = firstCalendarPair.First; paymentCalendar = firstCalendarPair.Second; } PriceableProduct = new CapFloorPricer(logger, cache, nameSpace, fixingCalendar, paymentCalendar, capFloor, BaseParty); ProductReporter = new CapFloorReporter(); } break; case ProductTypeSimpleEnum.FxSpot: { var fxForward = (FxSingleLeg)trade.Item; PriceableProduct = new FxSingleLegPricer(fxForward, BaseParty, ProductTypeSimpleEnum.FxSpot); ProductReporter = new FxSingleLegReporter(); } break; case ProductTypeSimpleEnum.FxForward: { var fxForward = (FxSingleLeg)trade.Item; PriceableProduct = new FxSingleLegPricer(fxForward, BaseParty, ProductTypeSimpleEnum.FxForward); ProductReporter = new FxSingleLegReporter(); } break; case ProductTypeSimpleEnum.BulletPayment: { if (trade.Item is BulletPayment bullet) { IBusinessCalendar paymentCalendar = null; if (firstCalendarPair != null) { paymentCalendar = firstCalendarPair.Second; } //The calendars if (paymentCalendar == null) { if (bullet.payment.paymentDate != null) { var containsPaymentDateAdjustments = AdjustableOrAdjustedDateHelper.Contains(bullet.payment.paymentDate, ItemsChoiceType.dateAdjustments, out object dateAdjustments); if (containsPaymentDateAdjustments && dateAdjustments != null) { paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, ((BusinessDayAdjustments)dateAdjustments). businessCenters, nameSpace); } } } PriceableProduct = new BulletPaymentPricer(bullet, BaseParty, paymentCalendar); ProductReporter = new BulletPaymentReporter(); } } break; case ProductTypeSimpleEnum.FxSwap: { var fxSwap = (FxSwap)trade.Item; PriceableProduct = new FxSwapPricer(fxSwap, BaseParty); ProductReporter = new FxSwapReporter(); } break; //case ProductTypeSimpleEnum.EquityOption: // break; //case ProductTypeSimpleEnum.BondOption: // break; case ProductTypeSimpleEnum.FxOption: { IBusinessCalendar fixingCalendar = null; IBusinessCalendar paymentCalendar = null; if (firstCalendarPair != null) { fixingCalendar = firstCalendarPair.First; paymentCalendar = firstCalendarPair.Second; } var fxOption = (FxOption)trade.Item; PriceableProduct = new VanillaEuropeanFxOptionPricer(logger, cache, nameSpace, fixingCalendar, paymentCalendar, fxOption, BaseParty); ProductReporter = new FxOptionLegReporter(); } break; //case ProductTypeSimpleEnum.FxOptionStrategy: // break; //case ProductTypeSimpleEnum.CreditDefaultIndex: // break; //case ProductTypeSimpleEnum.CreditDefaultIndexTranche: // break; //case ProductTypeSimpleEnum.CreditDefaultBasket: // break; //case ProductTypeSimpleEnum.CreditDefaultBasketTranche: // break; //case ProductTypeSimpleEnum.CreditDefaultOption: // break; //case ProductTypeSimpleEnum.EquityForward: // break; case ProductTypeSimpleEnum.InterestRateSwaption: { var interestRateSwaption = (Swaption)trade.Item; PriceableProduct = new InterestRateSwaptionPricer(logger, cache, nameSpace, interestRateSwaption, BaseParty, forecastRateInterpolation); ProductReporter = new InterestRateSwaptionReporter(); } break; case ProductTypeSimpleEnum.TermDeposit: { //var party1 = tradeProps.GetValue<string>(TradeProp.Party1, true); //var party2 = tradeProps.GetValue<string>(TradeProp.Party2, true); //var reportingParty = baseParty == party1 ? "Party1" : "Party2"; // TODO this is for backward compatability. var deposit = (TermDeposit)trade.Item; PriceableProduct = new TermDepositPricer(logger, cache, deposit, TradeProp.Party1); //The payment date must be correct before calling this! ProductReporter = new TermDepositReporter(); } break; //case ProductTypeSimpleEnum.DividendSwap: // break; //case ProductTypeSimpleEnum.ConvertibleBondOption: // break; //case ProductTypeSimpleEnum.Loan: // break; //case ProductTypeSimpleEnum.Repo: // break; default: throw new NotSupportedException("Unsupported ProductType: " + ProductType); } } else { switch (TradeType) { case ItemChoiceType15.propertyTransaction: { var equity = (PropertyTransaction)trade.Item; IBusinessCalendar settlementCalendar = null; if (firstCalendarPair != null) { settlementCalendar = firstCalendarPair.First; } var tradeDate = tradeProps.GetValue <DateTime>(TradeProp.TradeDate, false); var referenceProperty = tradeProps.GetValue <String>(PropertyProp.ReferenceProperty, false); PriceableProduct = new PropertyTransactionPricer(logger, cache, nameSpace, tradeDate, referenceProperty, settlementCalendar, equity, BaseParty, forecastRateInterpolation); ProductReporter = new PropertyTransactionReporter(); } break; case ItemChoiceType15.equityTransaction: { var equity = (EquityTransaction)trade.Item; IBusinessCalendar settlementCalendar = null; if (firstCalendarPair != null) { settlementCalendar = firstCalendarPair.First; } var tradeDate = tradeProps.GetValue <DateTime>(TradeProp.TradeDate, false); var effectiveDate = tradeProps.GetValue <DateTime>(TradeProp.EffectiveDate, true); var referenceEquity = tradeProps.GetValue <String>(EquityProp.ReferenceEquity, false); PriceableProduct = new EquityTransactionPricer(logger, cache, nameSpace, tradeDate, effectiveDate, referenceEquity, settlementCalendar, equity, BaseParty, forecastRateInterpolation); ProductReporter = new EquityTransactionReporter(); } break; case ItemChoiceType15.bondTransaction: { var bond = (BondTransaction)trade.Item; IBusinessCalendar settlementCalendar = null; IBusinessCalendar paymentCalendar = null; if (firstCalendarPair != null) { settlementCalendar = firstCalendarPair.First; paymentCalendar = firstCalendarPair.Second; } var tradeDate = tradeProps.GetValue <DateTime>(TradeProp.TradeDate, true); var effectiveDate = tradeProps.GetValue <DateTime>(TradeProp.EffectiveDate, true); var bondType = tradeProps.GetValue <string>(BondProp.BondType, false); PriceableProduct = new BondTransactionPricer(logger, cache, nameSpace, tradeDate, effectiveDate, settlementCalendar, paymentCalendar, bond, BaseParty, bondType, forecastRateInterpolation); ProductReporter = new BondTransactionReporter(); } break; case ItemChoiceType15.futureTransaction: { IBusinessCalendar settlementCalendar = null; if (firstCalendarPair != null) { settlementCalendar = firstCalendarPair.First; } var future = (FutureTransaction)trade.Item; var tradeDate = tradeProps.GetValue <DateTime>(TradeProp.TradeDate, false); var type = tradeProps.GetValue <String>(FuturesProp.FuturesType, true); var futureType = EnumHelper.Parse <ExchangeContractTypeEnum>(type); //Get the instrument configuration data. //Modify the pricer to include this data. PriceableProduct = new FutureTransactionPricer(logger, cache, nameSpace, tradeDate, futureType, settlementCalendar, future, BaseParty, forecastRateInterpolation); ProductReporter = new FutureTransactionReporter(); } break; case ItemChoiceType15.swap: { var swap = (Swap)trade.Item; //TODO this needs to be emnhanced ProductType = ProductTypeSimpleEnum.InterestRateSwap; PriceableProduct = new CrossCurrencySwapPricer(logger, cache, nameSpace, legCalendars, swap, BaseParty, forecastRateInterpolation); ProductReporter = new InterestRateSwapReporter(); //var report = } break; case ItemChoiceType15.fra: // todo { var fra = (Fra)trade.Item; IBusinessCalendar fixingCalendar = null; IBusinessCalendar paymentCalendar = null; if (firstCalendarPair != null) { fixingCalendar = firstCalendarPair.First; paymentCalendar = firstCalendarPair.Second; } ProductType = ProductTypeSimpleEnum.FRA; PriceableProduct = new FraPricer(logger, cache, fixingCalendar, paymentCalendar, fra, BaseParty) { ForecastRateInterpolation = forecastRateInterpolation }; ProductReporter = new ForwardRateAgreementReporter(); } break; case ItemChoiceType15.capFloor: { var capFloor = (CapFloor)trade.Item; IBusinessCalendar fixingCalendar = null; IBusinessCalendar paymentCalendar = null; if (firstCalendarPair != null) { fixingCalendar = firstCalendarPair.First; paymentCalendar = firstCalendarPair.Second; } ProductType = ProductTypeSimpleEnum.CapFloor; PriceableProduct = new CapFloorPricer(logger, cache, nameSpace, fixingCalendar, paymentCalendar, capFloor, BaseParty); ProductReporter = new CapFloorReporter(); } break; case ItemChoiceType15.fxSingleLeg: { var fxForward = (FxSingleLeg)trade.Item; ProductType = ProductTypeSimpleEnum.FxSpot; PriceableProduct = new FxSingleLegPricer(fxForward, BaseParty, ProductType); ProductReporter = new FxSingleLegReporter(); } break; case ItemChoiceType15.fxSwap: { var fxSwap = (FxSwap)trade.Item; ProductType = ProductTypeSimpleEnum.FxSwap; PriceableProduct = new FxSwapPricer(fxSwap, BaseParty); ProductReporter = new FxSwapReporter(); } break; case ItemChoiceType15.bulletPayment: { if (trade.Item is BulletPayment bullet) { IBusinessCalendar paymentCalendar = null; if (firstCalendarPair != null) { paymentCalendar = firstCalendarPair.Second; } //The calendars if (paymentCalendar == null) { if (bullet.payment.paymentDate != null) { var containsPaymentDateAdjustments = AdjustableOrAdjustedDateHelper.Contains(bullet.payment.paymentDate, ItemsChoiceType.dateAdjustments, out object dateAdjustments); if (containsPaymentDateAdjustments && dateAdjustments != null) { paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, ((BusinessDayAdjustments)dateAdjustments). businessCenters, nameSpace); } } } ProductType = ProductTypeSimpleEnum.BulletPayment; PriceableProduct = new BulletPaymentPricer(bullet, BaseParty, paymentCalendar); ProductReporter = new BulletPaymentReporter(); } } break; case ItemChoiceType15.termDeposit: { var deposit = (TermDeposit)trade.Item; ProductType = ProductTypeSimpleEnum.TermDeposit; PriceableProduct = new TermDepositPricer(logger, cache, deposit, TradeProp.Party1); //The payment date must be correct before calling this! ProductReporter = new TermDepositReporter(); } break; case ItemChoiceType15.swaption: { var interestRateSwaption = (Swaption)trade.Item; ProductType = ProductTypeSimpleEnum.InterestRateSwaption; PriceableProduct = new InterestRateSwaptionPricer(logger, cache, nameSpace, interestRateSwaption, BaseParty, forecastRateInterpolation); ProductReporter = new InterestRateSwaptionReporter(); } break; case ItemChoiceType15.fxOption: { IBusinessCalendar fixingCalendar = null; IBusinessCalendar paymentCalendar = null; if (firstCalendarPair != null) { fixingCalendar = firstCalendarPair.First; paymentCalendar = firstCalendarPair.Second; } var fxOption = (FxOption)trade.Item; ProductType = ProductTypeSimpleEnum.FxOption; PriceableProduct = new VanillaEuropeanFxOptionPricer(logger, cache, nameSpace, fixingCalendar, paymentCalendar, fxOption, BaseParty); ProductReporter = new FxOptionLegReporter(); } break; default: throw new NotSupportedException("Unsupported TradeType: " + TradeType); } //Adds the extra party info now required. PriceableProduct.OrderedPartyNames.Add(party1); PriceableProduct.OrderedPartyNames.Add(party2); //Check if collateralised if (trade.collateral != null) { PriceableProduct.IsCollateralised = true; } } }
/// <summary> /// /// </summary> /// <param name="logger"></param> /// <param name="cache"></param> /// <param name="nameSpace"></param> /// <param name="tradeDate"></param> /// <param name="settlementDate">The payment settlement date.</param> /// <param name="settlementCalendar"></param> /// <param name="paymentCalendar"></param> /// <param name="bondFpML"></param> /// <param name="basePartyReference"></param> /// <param name="bondType"></param> /// <param name="forecastRateInterpolation"></param> public BondTransactionPricer(ILogger logger, ICoreCache cache, string nameSpace, DateTime tradeDate, DateTime settlementDate, IBusinessCalendar settlementCalendar, IBusinessCalendar paymentCalendar, BondTransaction bondFpML, string basePartyReference, string bondType, Boolean forecastRateInterpolation) { Multiplier = 1.0m; TradeDate = tradeDate; BondType = EnumHelper.Parse <BondTypesEnum>(bondType); logger.LogInfo("BondType set. Commence to build a bond transaction."); if (bondFpML == null) { return; } BuyerReference = bondFpML.buyerPartyReference.href; PaymentCurrencies = new List <string> { bondFpML.notionalAmount.currency.Value }; SellerReference = bondFpML.sellerPartyReference.href; BasePartyBuyer = basePartyReference == bondFpML.buyerPartyReference.href; if (!BasePartyBuyer) { Multiplier = -1.0m; } ForecastRateInterpolation = forecastRateInterpolation; SettlementCalendar = settlementCalendar; PaymentCalendar = paymentCalendar; //Set the bond price information BondPrice = new BondPrice(); if (bondFpML.price.accrualsSpecified) { BondPrice.accrualsSpecified = true; BondPrice.accruals = bondFpML.price.accruals; } if (bondFpML.price.dirtyPriceSpecified) { BondPrice.dirtyPriceSpecified = true; BondPrice.dirtyPrice = bondFpML.price.dirtyPrice; } BondPrice.cleanOfAccruedInterest = bondFpML.price.cleanOfAccruedInterest; BondPrice.cleanPrice = bondFpML.price.cleanPrice; //Set the notional information NotionalAmount = MoneyHelper.GetAmount(bondFpML.notionalAmount.amount, bondFpML.notionalAmount.currency.Value); //Determines the quotation and units QuoteType = BondPriceEnum.YieldToMaturity; //We need to get the ytm in until there is a bond market price/spread. if (BondPrice.dirtyPriceSpecified) { QuoteType = BondPriceEnum.DirtyPrice; Quote = BasicQuotationHelper.Create(BondPrice.dirtyPrice, RateQuotationType); } //Get the insturment configuration information. var assetIdentifier = bondFpML.bond.currency.Value + "-Bond-" + BondType; BondNodeStruct bondTypeInfo = null; var instrument = InstrumentDataHelper.GetInstrumentConfigurationData(cache, nameSpace, assetIdentifier); if (instrument != null) { bondTypeInfo = instrument.InstrumentNodeItem as BondNodeStruct; } if (bondFpML.bond != null && bondTypeInfo != null) { if (SettlementCalendar == null) { SettlementCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, bondTypeInfo.SettlementDate.businessCenters, nameSpace); } if (PaymentCalendar == null) { PaymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, bondTypeInfo.BusinessDayAdjustments.businessCenters, nameSpace); } //Preprocesses the data for the priceableasset. var bond = XmlSerializerHelper.Clone(bondFpML.bond); BondTypeInfo = XmlSerializerHelper.Clone(bondTypeInfo); BondTypeInfo.Bond = bond; //This is done because the config data is not stored in the ciorrect way. Need to add a price quote units. if (bond.couponRateSpecified) { var coupon = bond.couponRate; BondTypeInfo.Bond.couponRate = coupon; } BondTypeInfo.Bond.faceAmount = NotionalAmount.amount; if (BondTypeInfo.Bond.maturitySpecified) { RiskMaturityDate = BondTypeInfo.Bond.maturity; } SettlementDate = settlementDate; if (!PaymentCurrencies.Contains(bondFpML.bond.currency.Value)) { PaymentCurrencies.Add(bondFpML.bond.currency.Value); } logger.LogInfo("Bond transaction has been successfully created."); } else { logger.LogInfo("Bond type data not available."); } //Add payments like the settlement price if (!BondPrice.dirtyPriceSpecified) { return; } var amount = BondPrice.dirtyPrice * NotionalAmount.amount / 100; var settlementPayment = PaymentHelper.Create("BondSettlemetAmount", BuyerReference, SellerReference, amount, SettlementDate); AdditionalPayments = PriceableInstrumentsFactory.CreatePriceablePayments(basePartyReference, new[] { settlementPayment }, SettlementCalendar); if (!PaymentCurrencies.Contains(settlementPayment.paymentAmount.currency.Value)) { PaymentCurrencies.Add(settlementPayment.paymentAmount.currency.Value); } }
protected SwapPricer(ILogger logger, ICoreCache cache, String nameSpace, List <Pair <IBusinessCalendar, IBusinessCalendar> > legCalendars, Swap swapFpML, string basePartyReference, ProductTypeSimpleEnum productType, Boolean forecastRateInterpolation) { Multiplier = 1.0m; if (swapFpML == null) { return; } BusinessCentersResolver.ResolveBusinessCenters(swapFpML); ForecastRateInterpolation = forecastRateInterpolation; //Get the effective date AdjustableDate adjustableEffectiveDate = XsdClassesFieldResolver.CalculationPeriodDatesGetEffectiveDate(swapFpML.swapStream[0].calculationPeriodDates); EffectiveDate = adjustableEffectiveDate.unadjustedDate.Value; //We make the assumption that the termination date is the same for all legs. AdjustableDate adjustableTerminationDate = XsdClassesFieldResolver.CalculationPeriodDatesGetTerminationDate(swapFpML.swapStream[0].calculationPeriodDates); var paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, adjustableTerminationDate.dateAdjustments.businessCenters, nameSpace); TerminationDate = AdjustedDateHelper.ToAdjustedDate(paymentCalendar, adjustableTerminationDate); RiskMaturityDate = TerminationDate; //EffectiveDate is not set; ProductType = productType; PaymentCurrencies = new List <string>(); //Resolve the payer var legs = swapFpML.swapStream.Length; if (legs == 0) { return; } var flag = false; var index = 0; if (legCalendars != null && legCalendars.Count == legs) { flag = true; } foreach (var swapStream in swapFpML.swapStream) { bool payerIsBase = basePartyReference == swapStream.payerPartyReference.href;//TODO add in the calendar functionality. //Set the id of the first stream. PriceableInterestRateStream leg = flag ? new PriceableInterestRateStream(logger, cache, nameSpace, payerIsBase, swapStream, ForecastRateInterpolation, legCalendars[index].First, legCalendars[index].Second) : new PriceableInterestRateStream(logger, cache, nameSpace, payerIsBase, swapStream, ForecastRateInterpolation, null, null); Legs.Add(leg); //Add the currencies for the trade pricer. if (!PaymentCurrencies.Contains(leg.Currency.Value)) { PaymentCurrencies.Add(leg.Currency.Value); } index++; } if (swapFpML.additionalPayment != null) { AdditionalPayments = PriceableInstrumentsFactory.CreatePriceablePayments(basePartyReference, swapFpML.additionalPayment, null); foreach (var payment in swapFpML.additionalPayment) { if (!PaymentCurrencies.Contains(payment.paymentAmount.currency.Value)) { PaymentCurrencies.Add(payment.paymentAmount.currency.Value); } } } }
/// <summary> /// /// </summary> /// <param name="logger"></param> /// <param name="cache"></param> /// <param name="nameSpace"></param> /// <param name="tradeDate"></param> /// <param name="settlementDate">The payment settlement date.</param> /// <param name="settlementCalendar"></param> /// <param name="paymentCalendar"></param> /// <param name="bondFpML"></param> /// <param name="basePartyReference"></param> /// <param name="bondType"></param> /// <param name="forecastRateInterpolation"></param> public BondTransactionPricer(ILogger logger, ICoreCache cache, string nameSpace, DateTime tradeDate, DateTime settlementDate, IBusinessCalendar settlementCalendar, IBusinessCalendar paymentCalendar, BondTransaction bondFpML, string basePartyReference, string bondType, bool forecastRateInterpolation) { Multiplier = 1.0m; TradeDate = tradeDate; BondType = EnumHelper.Parse <BondTypesEnum>(bondType); logger.LogInfo("BondType set. Commence to build a bond transaction."); if (bondFpML == null) { return; } BuyerReference = bondFpML.buyerPartyReference.href; PaymentCurrencies = new List <string> { bondFpML.notionalAmount.currency.Value }; SellerReference = bondFpML.sellerPartyReference.href; BasePartyBuyer = basePartyReference == bondFpML.buyerPartyReference.href; if (!BasePartyBuyer) { Multiplier = -1.0m; } ForecastRateInterpolation = forecastRateInterpolation; SettlementCalendar = settlementCalendar; PaymentCalendar = paymentCalendar; //Set the bond price information BondPrice = new BondPrice(); if (bondFpML.price.accrualsSpecified) { BondPrice.accrualsSpecified = true; BondPrice.accruals = bondFpML.price.accruals; } if (bondFpML.price.dirtyPriceSpecified) { BondPrice.dirtyPriceSpecified = true; BondPrice.dirtyPrice = bondFpML.price.dirtyPrice; } BondPrice.cleanOfAccruedInterest = bondFpML.price.cleanOfAccruedInterest; BondPrice.cleanPrice = bondFpML.price.cleanPrice; //Set the currencies CouponCurrency = bondFpML.notionalAmount.currency; PaymentCurrency = bondFpML.notionalAmount.currency;//This could be another currency! //Set the notional information NotionalAmount = MoneyHelper.GetAmount(bondFpML.notionalAmount.amount, bondFpML.notionalAmount.currency.Value); //Determines the quotation and units QuoteType = BondPriceEnum.YieldToMaturity; //We need to get the ytm in until there is a bond market price/spread. if (BondPrice.dirtyPriceSpecified) { QuoteType = BondPriceEnum.DirtyPrice; Quote = BasicQuotationHelper.Create(BondPrice.dirtyPrice, RateQuotationType); } //Get the instrument configuration information. var assetIdentifier = bondFpML.bond.currency.Value + "-Bond-" + BondType; BondNodeStruct bondTypeInfo = null; //TODO Set the swap curves for asset swap valuation. // //Gets the template bond type var instrument = InstrumentDataHelper.GetInstrumentConfigurationData(cache, nameSpace, assetIdentifier); if (instrument != null) { bondTypeInfo = instrument.InstrumentNodeItem as BondNodeStruct; } if (bondFpML.bond != null && bondTypeInfo != null) { if (SettlementCalendar == null) { SettlementCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, bondTypeInfo.SettlementDate.businessCenters, nameSpace); } if (PaymentCalendar == null) { PaymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, bondTypeInfo.BusinessDayAdjustments.businessCenters, nameSpace); } //Pre-processes the data for the priceable asset. var bond = XmlSerializerHelper.Clone(bondFpML.bond); Bond = bond; bondTypeInfo.Bond = Bond; //Set the curves to use for valuations. BondCurveName = CurveNameHelpers.GetBondCurveName(Bond.currency.Value, Bond.id); //THe discount curve is only for credit calculations. DiscountCurveName = CurveNameHelpers.GetDiscountCurveName(Bond.currency.Value, true); if (bond.maturitySpecified) { MaturityDate = bond.maturity; } SettlementDateConvention = bondTypeInfo.SettlementDate; BusinessDayAdjustments = bondTypeInfo.BusinessDayAdjustments; ExDivDateConvention = bondTypeInfo.ExDivDate; //This is done because the config data is not stored in the correct way. Need to add a price quote units. if (bond.couponRateSpecified) { var coupon = bond.couponRate; Bond.couponRate = coupon; } bondTypeInfo.Bond.faceAmount = NotionalAmount.amount; bondTypeInfo.Bond.faceAmountSpecified = true; Bond.faceAmount = NotionalAmount.amount; if (Bond.maturitySpecified) { RiskMaturityDate = Bond.maturity; } SettlementDate = settlementDate; if (!PaymentCurrencies.Contains(bondFpML.bond.currency.Value)) { PaymentCurrencies.Add(bondFpML.bond.currency.Value); } logger.LogInfo("Bond transaction has been successfully created."); } else { logger.LogInfo("Bond type data not available."); } //Set the underlying bond UnderlyingBond = new PriceableSimpleBond(tradeDate, bondTypeInfo, SettlementCalendar, PaymentCalendar, Quote, QuoteType); BondIssuer = UnderlyingBond.Issuer; if (BondPrice.dirtyPriceSpecified) { UnderlyingBond.PurchasePrice = BondPrice.dirtyPrice / 100; //PriceQuoteUnits } //Set the coupons var bondId = Bond.id;//Could use one of the instrumentIds //bondStream is an interest Rate Stream but needs to be converted to a bond stream. //It automatically contains the coupon currency. Coupons = new PriceableBondCouponRateStream(logger, cache, nameSpace, bondId, tradeDate, bondFpML.notionalAmount.amount, CouponStreamType.GenericFixedRate, Bond, BusinessDayAdjustments, ForecastRateInterpolation, null, PaymentCalendar); //Add payments like the settlement price if (!BondPrice.dirtyPriceSpecified) { return; } var amount = BondPrice.dirtyPrice * NotionalAmount.amount / 100; var settlementPayment = PaymentHelper.Create(BuyerReference, SellerReference, PaymentCurrency.Value, amount, SettlementDate); AdditionalPayments = PriceableInstrumentsFactory.CreatePriceablePayments(basePartyReference, new[] { settlementPayment }, SettlementCalendar); // var finalPayment = PaymentHelper.Create(BondIssuer, BuyerReference, CouponCurrency.Value, NotionalAmount.amount, RiskMaturityDate); FinalRedemption = PriceableInstrumentsFactory.CreatePriceablePayment(basePartyReference, finalPayment, PaymentCalendar); AdditionalPayments.Add(FinalRedemption); if (!PaymentCurrencies.Contains(settlementPayment.paymentAmount.currency.Value)) { PaymentCurrencies.Add(settlementPayment.paymentAmount.currency.Value); } }
public FutureTransactionPricer(ILogger logger, ICoreCache cache, string nameSpace, DateTime tradeDate, ExchangeContractTypeEnum futuresType, IBusinessCalendar settlementCalendar, FutureTransaction futureFpML, string basePartyReference, Boolean forecastRateInterpolation) { logger.LogInfo("FuturesType set. Commence to build a future transaction."); if (futureFpML == null) { return; } Multiplier = 1.0m; BuyerReference = futureFpML.buyerPartyReference.href; PaymentCurrencies = new List <string> { futureFpML.unitPrice.currency.Value }; SellerReference = futureFpML.sellerPartyReference.href; BasePartyBuyer = basePartyReference == futureFpML.buyerPartyReference.href; if (!BasePartyBuyer) { Multiplier = -1.0m; } ForecastRateInterpolation = forecastRateInterpolation; SettlementCalendar = settlementCalendar; FuturesType = futuresType; ReferenceContract = futureFpML.future.id; var futuresCode = ReferenceContract.Split('-')[2]; NumberOfContracts = Convert.ToInt16(futureFpML.numberOfUnits); PurchasePrice = MoneyHelper.GetAmount(futureFpML.unitPrice.amount, futureFpML.unitPrice.currency.Value); var exchangeMIC = futureFpML.future.exchangeId; FuturesCurveName = CurveNameHelpers.GetExchangeTradedCurveName(futureFpML.unitPrice.currency.Value, exchangeMIC.Value, futuresCode); DiscountCurveName = CurveNameHelpers.GetDiscountCurveName(futureFpML.unitPrice.currency, true); FuturesTypeInfo = new FutureNodeStruct(); var exchangeMICData = InstrumentDataHelper.CreateEquityExchangeKey(nameSpace, exchangeMIC.Value); var exchangeData = cache.LoadItem <ExchangeConfigData>(exchangeMICData); if (exchangeData?.Data is ExchangeConfigData) { Exchange = (ExchangeConfigData)exchangeData.Data; FuturesTypeInfo.SpotDate = Exchange.SettlementDate; } if (futureFpML.future != null) { if (SettlementCalendar == null) { SettlementCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, FuturesTypeInfo.SpotDate .businessCenters, nameSpace); } var future = XmlSerializerHelper.Clone(futureFpML.future); FuturesTypeInfo.Future = future; if (FuturesTypeInfo.SpotDate != null) { SettlementDate = GetSettlementDate(tradeDate, SettlementCalendar, FuturesTypeInfo.SpotDate); } //Instantiate the priceable future. NamedValueSet namedValueSet = PriceableAssetFactory.BuildPropertiesForAssets(nameSpace, FuturesTypeInfo.Future.id, tradeDate); var asset = AssetHelper.Parse(FuturesTypeInfo.Future.id, 0.0m, 0.0m); UnderlyingFuture = PriceableAssetFactory.Create(logger, cache, nameSpace, asset.Second, namedValueSet, null, null) as IPriceableFuturesAssetController; if (UnderlyingFuture != null) { RiskMaturityDate = UnderlyingFuture.GetRiskMaturityDate(); MaturityDate = RiskMaturityDate; LastTradeDate = UnderlyingFuture.LastTradeDate; } if (!PaymentCurrencies.Contains(futureFpML.future.currency.Value)) { PaymentCurrencies.Add(futureFpML.future.currency.Value); } logger.LogInfo("Futures transaction has been successfully created."); } else { logger.LogInfo("Futures type data not available."); } //Add payments like the settlement price if (!PurchasePrice.amountSpecified) { return; } var amount = PurchasePrice.amount * NumberOfContracts / 100; var settlementPayment = PaymentHelper.Create("FuturesSettlemetAmount", BuyerReference, SellerReference, amount, SettlementDate); AdditionalPayments = PriceableInstrumentsFactory.CreatePriceablePayments(basePartyReference, new[] { settlementPayment }, SettlementCalendar); if (!PaymentCurrencies.Contains(settlementPayment.paymentAmount.currency.Value)) { PaymentCurrencies.Add(settlementPayment.paymentAmount.currency.Value); } }
/// <summary> /// /// </summary> /// <param name="logger"></param> /// <param name="cache"></param> /// <param name="nameSpace"></param> /// <param name="leg1Parameters"></param> /// <param name="leg1Calendars"></param> /// <param name="leg2Parameters"></param> /// <param name="leg2Calendars"></param> /// <param name="fixedRateSchedule"></param> /// <param name="spreadSchedule"></param> /// <param name="notionalSchedule"></param> /// <returns></returns> public static Swap GenerateDefinitionCashflows(ILogger logger, ICoreCache cache, string nameSpace, SwapLegParametersRange leg1Parameters, Pair <IBusinessCalendar, IBusinessCalendar> leg1Calendars, SwapLegParametersRange leg2Parameters, Pair <IBusinessCalendar, IBusinessCalendar> leg2Calendars, Schedule fixedRateSchedule, Schedule spreadSchedule, NonNegativeAmountSchedule notionalSchedule) { IBusinessCalendar leg1PaymentCalendar = null; IBusinessCalendar leg2PaymentCalendar = null; IBusinessCalendar leg1FixingCalendar = null; IBusinessCalendar leg2FixingCalendar = null; if (leg1Calendars != null) { leg1FixingCalendar = leg1Calendars.First; leg1PaymentCalendar = leg1Calendars.Second; } else { if (!string.IsNullOrEmpty(leg1Parameters.PaymentCalendar)) { var payCalendar = BusinessCentersHelper.Parse(leg1Parameters.PaymentCalendar); leg1PaymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, payCalendar, nameSpace); leg1FixingCalendar = leg1PaymentCalendar; } if (!string.IsNullOrEmpty(leg1Parameters.FixingCalendar)) { var fixingCalendar = BusinessCentersHelper.Parse(leg1Parameters.FixingCalendar); leg1FixingCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, fixingCalendar, nameSpace); } } if (leg2Calendars != null) { leg2FixingCalendar = leg2Calendars.First; leg2PaymentCalendar = leg2Calendars.Second; } else { if (!string.IsNullOrEmpty(leg2Parameters.PaymentCalendar)) { var payCalendar = BusinessCentersHelper.Parse(leg2Parameters.PaymentCalendar); leg2PaymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, payCalendar, nameSpace); leg2FixingCalendar = leg2PaymentCalendar; } if (!string.IsNullOrEmpty(leg2Parameters.FixingCalendar)) { var fixingCalendar = BusinessCentersHelper.Parse(leg2Parameters.FixingCalendar); leg2FixingCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, fixingCalendar, nameSpace); } } var swap = GenerateDefiniton(leg1Parameters, leg2Parameters); InterestRateStream stream1 = swap.swapStream[0]; InterestRateStream stream2 = swap.swapStream[1]; if (null != fixedRateSchedule) { // Set FixedRateSchedule (if this is a fixed leg) // if (leg1Parameters.IsFixedLegType()) { InterestRateStreamParametricDefinitionGenerator.SetFixedRateSchedule(stream1, fixedRateSchedule); } // Set FixedRateSchedule (if this is a fixed leg) // if (leg2Parameters.IsFixedLegType()) { InterestRateStreamParametricDefinitionGenerator.SetFixedRateSchedule(stream2, fixedRateSchedule); } } if (null != spreadSchedule) //for float legs only { if (leg1Parameters.IsFloatingLegType()) { InterestRateStreamParametricDefinitionGenerator.SetSpreadSchedule(stream1, spreadSchedule); } if (leg2Parameters.IsFloatingLegType()) { InterestRateStreamParametricDefinitionGenerator.SetSpreadSchedule(stream2, spreadSchedule); } } if (null != notionalSchedule) { // Set notional schedule // InterestRateStreamParametricDefinitionGenerator.SetNotionalSchedule(stream1, notionalSchedule); InterestRateStreamParametricDefinitionGenerator.SetNotionalSchedule(stream2, notionalSchedule); } stream1.cashflows = FixedAndFloatingRateStreamCashflowGenerator.GetCashflows(stream1, leg1FixingCalendar, leg1PaymentCalendar); stream2.cashflows = FixedAndFloatingRateStreamCashflowGenerator.GetCashflows(stream2, leg2FixingCalendar, leg2PaymentCalendar); return(swap); }