/// <summary> /// Replaces a QuotedAssetSet with this. Note that the referential integrity between the assets /// and valuations is checked and maintained. /// </summary> /// <param name="additional">The additional QuotedAssetSet.</param> /// <returns></returns> public void Replace(QuotedAssetSet additional) { var qas = XmlSerializerHelper.Clone(additional); instrumentSet = qas.instrumentSet; assetQuote = qas.assetQuote; }
//Adds a spread to an asset. The spread value is added to each asset in the original curve. //The array of spread values must be the same length as the array of assets. // The curve is renamed with the id provided. // /// <summary> /// /// </summary> /// <param name="spreadValues"></param> /// <param name="commodityCurve"></param> /// <param name="curveId"></param> /// <returns></returns> protected static Pair <PricingStructure, PricingStructureValuation> AdjustMarketQuotes(Decimal[] spreadValues, Pair <PricingStructure, PricingStructureValuation> commodityCurve, string curveId) { var ycCurveCloned = XmlSerializerHelper.Clone(commodityCurve.First); var ycvCurveCloned = XmlSerializerHelper.Clone(commodityCurve.Second); var yc = (FpML.V5r10.Reporting.FxCurve)ycCurveCloned; yc.id = curveId; var ycv = (FxCurveValuation)ycvCurveCloned; ycv.fxForwardCurve.point = null; ycv.fxForwardPointsCurve = null; ycv.fxForwardCurve = null; //This strips out the basis swaps. // ycv.spotRate = AssetHelper.RemoveAssetsFromQuotedAssetSet(AssetTypesEnum.BasisSwap, ycv.spotRate); if (spreadValues.Length == ycv.spotRate.instrumentSet.Items.Length) { var index = 0; foreach (var bav in ycv.spotRate.assetQuote) { bav.quote = MarketQuoteHelper.AddAndReplaceQuotationByMeasureType("MarketQuote", new List <BasicQuotation>(bav.quote), spreadValues[index]); index++; } } return(new Pair <PricingStructure, PricingStructureValuation>(yc, ycv)); }
//Adds a spread to an asset. The spread value is added to each asset in the original curve. // The curve is renamed with the id provided. // /// <summary> /// /// </summary> /// <param name="spreadValue"></param> /// <param name="commodityCurve"></param> /// <param name="curveId"></param> /// <returns></returns> protected static Pair <PricingStructure, PricingStructureValuation> AdjustMarketQuotes(Decimal spreadValue, Pair <PricingStructure, PricingStructureValuation> commodityCurve, string curveId) { var ycCurveCloned = XmlSerializerHelper.Clone(commodityCurve.First); var ycvCurveCloned = XmlSerializerHelper.Clone(commodityCurve.Second); // assign id to the cloned YieldCurve // var yc = (FpML.V5r10.Reporting.FxCurve)ycCurveCloned; yc.id = curveId; // nullify the discount factor curve to make sure that bootstrapping will happen) // var ycv = (FxCurveValuation)ycvCurveCloned; ycv.fxForwardCurve.point = null; ycv.fxForwardPointsCurve = null; ycv.fxForwardCurve = null; foreach (var bav in ycv.spotRate.assetQuote) { bav.quote = MarketQuoteHelper.AddAndReplaceQuotationByMeasureType("MarketQuote", new List <BasicQuotation>(bav.quote), spreadValue); } return(new Pair <PricingStructure, PricingStructureValuation>(yc, ycv)); }
private void Initialize(ILogger logger, ICoreCache cache, string nameSpace, NamedValueSet properties, IRateCurve baseCurve, IRateCurve quoteCurve, string[] instruments, decimal[] values, FxCurve fxCurve, IBusinessCalendar fixingCalendar, IBusinessCalendar rollCalendar) { var curveId = (RateCurveIdentifier)PricingStructureIdentifier; BaseCurve = baseCurve; QuoteCurve = quoteCurve; //Holder = new PricingStructureAlgorithmsHolder(logger, cache, curveId.PricingStructureType, curveId.Algorithm); Initialize(properties, Holder); var currency = properties.GetValue <string>(CurveProp.Currency1); if (fxCurve != null && baseCurve == null) { var holder = new GenericRateCurveAlgorithmHolder(logger, cache, nameSpace); // Create discount factors, without any input points RateCurve basisAdjustedDiscountCurve = CreateBasisAdjustedDiscountCurve(fxCurve, quoteCurve, currency, curveId.BaseDate, holder); TermCurve discountCurve = ((YieldCurveValuation)basisAdjustedDiscountCurve.PricingStructureValuation).discountFactorCurve; CreateYieldCurve(); GetYieldCurveValuation().discountFactorCurve = discountCurve; SetInterpolator(discountCurve, curveId.Algorithm, PricingStructureTypeEnum.RateSpreadCurve); // Put FX curve into inputs var assetQuotes = new List <BasicAssetValuation>(); BasicAssetValuation[] fxAssetQuotes = ((FxCurveValuation)fxCurve.GetFpMLData().Second).spotRate.assetQuote; foreach (BasicAssetValuation assetQuote in fxAssetQuotes) { BasicAssetValuation clonedAssetQuote = XmlSerializerHelper.Clone(assetQuote); clonedAssetQuote.definitionRef = FxCurveName; assetQuotes.Add(clonedAssetQuote); } AddQuoteCurveInputs(assetQuotes); ((YieldCurveValuation)PricingStructureValuation).inputs = new QuotedAssetSet { assetQuote = assetQuotes.ToArray() }; } else { List <IPriceableRateAssetController> swaps = PriceableAssetFactory.CreatePriceableRateAssets(logger, cache, nameSpace, curveId.BaseDate, instruments, values, null, fixingCalendar, rollCalendar); if (fxCurve == null) { // only use the input swaps PriceableRateAssets = swaps; } else { var holder = new GenericRateCurveAlgorithmHolder(logger, cache, nameSpace); // Add synthetic input points RateCurve basisAdjustedDiscountCurve = CreateBasisAdjustedDiscountCurve(fxCurve, quoteCurve, currency, curveId.BaseDate, holder); //TODO Add some extra short end point: 1D and 1W string[] syntheticSwapPoints = { "1M", "2M", "3M", "6M", "9M" }; PriceableRateAssets = CreateSyntheticSwaps(logger, cache, nameSpace, BaseCurve, basisAdjustedDiscountCurve, currency, curveId.BaseDate, syntheticSwapPoints, fixingCalendar, rollCalendar); PriceableRateAssets.AddRange(swaps); } // bootstrap to create the discount factors PriceableRateAssets = PriceableRateAssets.OrderBy(a => a.GetRiskMaturityDate()).ToList(); Bootstrap((YieldCurveValuation)GetFpMLData().Second); } }
private void AddBaseCurveInputs(List <BasicAssetValuation> assetQuotes) { QuotedAssetSet baseCurveInputs = ((YieldCurveValuation)BaseCurve?.GetFpMLData().Second)?.inputs; if (baseCurveInputs?.assetQuote != null) { foreach (BasicAssetValuation assetQuote in baseCurveInputs.assetQuote) { BasicAssetValuation clonedAssetQuote = XmlSerializerHelper.Clone(assetQuote); clonedAssetQuote.definitionRef = BaseCurveName; assetQuotes.Add(clonedAssetQuote); } } }
/// <summary> /// /// </summary> /// <param name="commodityCurve"></param> /// <param name="curveId"></param> /// <returns></returns> public static Pair <PricingStructure, PricingStructureValuation> CloneCurve(Pair <PricingStructure, PricingStructureValuation> commodityCurve, string curveId) { PricingStructure ycCurveCloned = XmlSerializerHelper.Clone(commodityCurve.First); PricingStructureValuation ycvCurveCloned = XmlSerializerHelper.Clone(commodityCurve.Second); // assign id to the cloned YieldCurve // var yc = (FpML.V5r10.Reporting.FxCurve)ycCurveCloned; yc.id = curveId; // nullify the discount factor curve to make sure that bootstrapping will happen) // var ycv = (FxCurveValuation)ycvCurveCloned; return(new Pair <PricingStructure, PricingStructureValuation>(yc, ycv)); }
public static ValuationReport Merge(ValuationReport valuation1, ValuationReport valuation2) { ValuationReport result = XmlSerializerHelper.Clone(valuation1); ValuationReport copyOfValuation2 = XmlSerializerHelper.Clone(valuation2); // generate new id from a valuation report // string valuationIdForCombinedValuationReport = Guid.NewGuid().ToString(); result.header.messageId.Value = valuationIdForCombinedValuationReport; // copy tradeValuationItems from valuation2 to result. // var listOfTradeValuations = new List <TradeValuationItem>(); listOfTradeValuations.AddRange(result.tradeValuationItem); listOfTradeValuations.AddRange(copyOfValuation2.tradeValuationItem); result.tradeValuationItem = listOfTradeValuations.ToArray(); return(result); }
/// <summary> /// Builds this instance and retruns the underlying instrument associated with the controller /// </summary> /// <returns></returns> public BondTransaction Build() { var bond = BondTypeInfo.Bond; var buyerPartyReference = PartyReferenceHelper.Parse(BuyerReference); var sellerPartyReference = PartyReferenceHelper.Parse(SellerReference); var productType = new object[] { ProductTypeHelper.Create("BondTransaction") }; var itemName = new[] { ItemsChoiceType2.productType }; //TODO extend this var bondTransaction = new BondTransaction { notionalAmount = NotionalAmount, bond = bond, price = XmlSerializerHelper.Clone(BondPrice), buyerPartyReference = buyerPartyReference, sellerPartyReference = sellerPartyReference, id = Id, Items = productType, ItemsElementName = itemName }; return(bondTransaction); }
/// <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); } }
/// <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); } }