public override AssetValuation Calculate(IInstrumentControllerData modelData) { ModelData = modelData; AnalyticModelParameters = null; AnalyticsModel = new BondTransactionAnalytic(); //1. Create the bond UnderlyingBond = new PriceableSimpleBond(modelData.ValuationDate, BondTypeInfo, SettlementCalendar, PaymentCalendar, Quote, QuoteType); if (BondPrice.dirtyPriceSpecified) { UnderlyingBond.PurchasePrice = BondPrice.dirtyPrice / 100; //PriceQuoteUnits } //Setting other relevant information MaturityDate = UnderlyingBond.MaturityDate; var metrics = ResolveModelMetrics(AnalyticsModel.Metrics); var metricsAsString = metrics.Select(metric => metric.ToString()).ToList(); var controllerData = PriceableAssetFactory.CreateAssetControllerData(metricsAsString.ToArray(), modelData.ValuationDate, modelData.MarketEnvironment); UnderlyingBond.Multiplier = Multiplier; UnderlyingBond.Calculate(controllerData); // store inputs and results from this run AnalyticModelParameters = ((PriceableBondAssetController)UnderlyingBond).AnalyticModelParameters; AnalyticsModel = ((PriceableBondAssetController)UnderlyingBond).AnalyticsModel; CalculationResults = ((PriceableBondAssetController)UnderlyingBond).CalculationResults; CalculationPerfomedIndicator = true; return(GetValue(CalculationResults, modelData.ValuationDate)); }
/// <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); } }