public void WhenThereIsAGoalByAtMinuteSecondsInThePeriod_Half(string team, int minute, int second, int period, Table table) { ScenarioContext.Current.Get <BasePricingResponse>(Constants.KeyPricingResponse); ScenarioContext.Current.Get <ConnectClient>(Constants.KeyConnectClient); var stateMachine = new SS.GTP.Domain.Sports.Handball.StateMachine { SportType = Sport.Handball, HalvesOrQuarters = Period.Halves, HalfOrQuarterLength = 30, OvertimeLength = 0 }; AddTeam1Point(stateMachine, period, minute, second); var request = new PricingRequest(); request.FixtureState.ActionLog = stateMachine.ActionLog.ToList(); request.FixtureState.Clock.Period = 1; var linkedCeResource = ScenarioContext.Current.Get <FixtureResource>(Constants.KeyLinkedCe); var connectClient = ScenarioContext.Current.Get <ConnectClient>(Constants.KeyConnectClient); connectClient.PriceFixture(linkedCeResource, request); }
public void PricingRequestTest() { var pricingRequest = new PricingRequest { mocean_mcc = "test mcc", mocean_mnc = "test mnc", mocean_delimiter = "test delimiter", mocean_resp_format = "json" }; Assert.IsNotNull(pricingRequest.mocean_mcc); Assert.AreEqual(pricingRequest.mocean_mcc, "test mcc"); Assert.IsNotNull(pricingRequest.mocean_mnc); Assert.AreEqual(pricingRequest.mocean_mnc, "test mnc"); Assert.IsNotNull(pricingRequest.mocean_delimiter); Assert.AreEqual(pricingRequest.mocean_delimiter, "test delimiter"); Assert.IsNotNull(pricingRequest.mocean_resp_format); Assert.AreEqual(pricingRequest.mocean_resp_format, "json"); pricingRequest = new PricingRequest(); Assert.IsNull(pricingRequest.mocean_mcc); Assert.IsNull(pricingRequest.mocean_mnc); Assert.IsNull(pricingRequest.mocean_delimiter); Assert.IsNull(pricingRequest.mocean_resp_format); pricingRequest.mocean_mcc = "test mcc"; Assert.AreEqual(pricingRequest.mocean_mcc, "test mcc"); pricingRequest.mocean_mnc = "test mnc"; Assert.AreEqual(pricingRequest.mocean_mnc, "test mnc"); pricingRequest.mocean_delimiter = "test delimiter"; Assert.AreEqual(pricingRequest.mocean_delimiter, "test delimiter"); pricingRequest.mocean_resp_format = "json"; Assert.AreEqual(pricingRequest.mocean_resp_format, "json"); }
private IPricingResult CalcBond(Bond bond, IMarketCondition market, PricingRequest pricingRequest = PricingRequest.None) { var request = bond.BondTradeingMarket == TradingMarket.ChinaInterBank ? PricingRequest.Ai : PricingRequest.AiEod; var bondResult = _bondEngine.Calculate(bond, market, request | PricingRequest.Cashflow | pricingRequest); return(bondResult); }
public async Task <PricingResponse> GetPriceDetails(PricingRequest request) { request.ServiceConsumer = _settings.Consumer; return(await _proxy.GetPriceDetails.POSTAsync(request).ContinueWith((x) => JsonConvert.DeserializeObject <PricingResponse>(JsonConvert.SerializeObject(x.Result)))); }
public PricingResponse GetPricing(PricingRequest request) { return(new PricingResponse { Description = "Night Rate", TotalPrice = 6.5m }); }
public PricingResponse GetPricing(PricingRequest request) { return(new PricingResponse { Description = "Weekend Rate", TotalPrice = 10 }); }
private void ProcessRequest(PricingRequest request) { Console.WriteLine(@"Finding stock prices for {0}", request.CompanyCode); IActorRef pricingLookUpActorRef = Context.ActorOf(Props.Create <PricingLookupActor>(), "PriceLookup" + Guid.NewGuid()); pricingLookUpActorRef.Tell(request); }
public PricingResponse GetPricing(PricingRequest request) { return(new PricingResponse { Description = "Early Bird", TotalPrice = 13 }); }
public bool IsApplicable(PricingRequest request) { return(request.Entry.DayOfWeek != DayOfWeek.Saturday && request.Entry.DayOfWeek != DayOfWeek.Sunday && request.Entry.IsBetween(18, 24) && request.Exit.IsBetween(18, 6) && ( request.Exit.Day == request.Entry.Day || request.Exit.Day == request.Entry.Day + 1 )); }
public void TestIsApplicable(string description, string entry, string exit, decimal expectedTotalCost) { var request = new PricingRequest { Entry = DateTime.Parse(entry), Exit = DateTime.Parse(exit) }; var pricingResponse = _rate.GetPricing(request); pricingResponse.TotalPrice.Should().Be(expectedTotalCost); }
public PricingResponse GetPricing(PricingRequest request) { var hourlyCost = CalculateRate(request, x => x.TotalHours, HourlyRate); var dailyCost = CalculateRate(request, x => x.TotalDays, DailyRate); return(new PricingResponse { Description = "Standard Rate", TotalPrice = Math.Min(hourlyCost, dailyCost) }); }
public async Task <IActionResult> CalculatePrice(PricingRequest pricingRequest) { var price = await _pricingService.CalculateMonthlyPremiumAsync( new PricingDto { Age = pricingRequest.Age, CoverAmount = pricingRequest.CoverAmount, OccupationId = pricingRequest.OccupationId }); return(Ok(price)); }
public void TestIsApplicable(string description, string entry, string exit, bool expectedIsApplicable) { var request = new PricingRequest { Entry = DateTime.Parse(entry), Exit = DateTime.Parse(exit) }; var isApplicable = _rate.IsApplicable(request); isApplicable.Should().Be(expectedIsApplicable); }
public PricingResponse GetPricing(PricingRequest request) { if (request.Exit < request.Entry) { // AJB: implement fluid validation throw new Exception("Entry must be earlier than Exit"); } return(_rates .Where(x => x.IsApplicable(request)) .Select(x => x.GetPricing(request)) .OrderBy(x => x.TotalPrice) .First()); }
/// <summary> /// main method for handling requests send to this handler /// </summary> /// <param name="context"></param> public void ProcessRequest(HttpContext context) { // get data string xml = new StreamReader(context.Request.InputStream).ReadToEnd(); XDocument doc = XDocument.Load(new StringReader(xml)); XNamespace xns = XNamespace.Get("http://schemas.xmlsoap.org/soap/envelope/"); AuthHeader header = GetSoapHeader(doc.Descendants(xns + "Header").First().FirstNode); PricingRequest body = GetSoapBody(doc.Descendants(xns + "Body").First().FirstNode); // process pricing ProductReturn returnedPrices = new ProductReturn(); IUserProfileLogic profileLogic = _scope.GetService(typeof(IUserProfileLogic)) as IUserProfileLogic; UserProfileReturn profileLogicReturn = profileLogic.GetUserProfile(header.UserName, false); if (profileLogicReturn.UserProfiles.Count > 0) { UserProfile profile = profileLogicReturn.UserProfiles[0]; PagedResults <Customer> customers = profileLogic.CustomerSearch(profile, body.customerNumber, new Core.Models.Paging.PagingModel(), string.Empty, CustomerSearchType.Customer); if (customers.TotalResults > 0) { returnedPrices.Products.AddRange(GetItemPricing(customers.Results[0].CustomerBranch, body.customerNumber, body.products, ConvertEffectiveDate(body.effDate))); } } // return results SoapEnvelope soap = new SoapEnvelope(); soap.Body.Response.Results = GetProductString(returnedPrices); XmlSerializer serializer = new XmlSerializer(soap.GetType()); XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); namespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance"); namespaces.Add("xsd", "http://www.w3.org/2001/XMLSchema"); namespaces.Add("soap", "http://schemas.xmlsoap.org/soap/envelope/"); serializer.Serialize(context.Response.OutputStream, soap, namespaces); context.Response.ContentType = "text/xml"; }
private void LookupPrice(PricingRequest request) { WebClient client = new WebClient(); var address = new Uri(String.Format(api, request.CompanyCode)); client.DownloadStringTaskAsync(address).ContinueWith( httpRequest => { var response = httpRequest.Result; var json = JsonConvert.DeserializeObject <RootObject>(response); decimal price = json.data[0].sellPrice1 == "-" ? Decimal.Zero : Decimal.Parse(json.data[0].sellPrice1); return(new PricingResponse(request.CompanyCode, price, "NSE")); }, TaskContinuationOptions.AttachedToParent & TaskContinuationOptions.ExecuteSynchronously).PipeTo(Self); }
public static PricingRequest[] Split(this PricingRequest request) { var result = new List <PricingRequest>(); const ulong min = 0x1UL; var max = Enum.GetValues(typeof(PricingRequest)).Cast <ulong>().Max(); for (var e = min; e <= max; e = e << 1) { if ((request & (PricingRequest)e) == (PricingRequest)e) { result.Add((PricingRequest)e); } } return(result.ToArray()); }
//希望这个放入tradebaseinfo对应的类 public virtual IPricingResult ValueTrade(QdpMarket market, PricingRequest request) { try { var instrument = GenerateInstrument(); Logger.InfoFormat("Valuing trade of type {0}", instrument.GetType().Name); var marketCondition = GenerateMarketCondition(market); var engine = GenerateEngine(); var result = engine.Calculate(instrument, marketCondition, request); return(result); } catch (Exception ex) { return(new PricingResult(market.ReferenceDate, request) { Succeeded = false, ErrorMessage = ex.Message }); } }
private IPricingResult CalcOptionBond(Bond bond, IMarketCondition market, PricingRequest request, PriceQuoteType?optionRequestType) { var result = new PricingResult(market.ValuationDate, request); var optionFlg = optionRequestType == PriceQuoteType.YtmExecution || optionRequestType == PriceQuoteType.YtmCallExecution || optionRequestType == PriceQuoteType.YtmPutExecution; // Get Call Execution if (optionFlg) { if (bond.OptionToCall != null) { var optionCallResult = CalcOption(bond.OptionToCall, bond, market, request, bond.PaymentFreq); result.CallDate = double.IsNaN(optionCallResult.Item2) ? null : optionCallResult.Item1; result.YieldToCall = optionCallResult.Item2; result.CleanPrice = optionCallResult.Item3; } if (bond.OptionToPut != null) { var optionPutResult = CalcOption(bond.OptionToPut, bond, market, request, bond.PaymentFreq); result.PutDate = double.IsNaN(optionPutResult.Item2) ? null : optionPutResult.Item1; result.YieldToPut = optionPutResult.Item2; result.CleanPrice = double.IsNaN(result.CleanPrice) ? optionPutResult.Item3 : result.CleanPrice; } else if (bond.OptionToAssPut != null) { // Get Put Execution for ass type Frequency frequency; var optionPut = ParseAssPut(bond, out frequency); var optionAssPutResult = CalcOption(optionPut, bond, market, request, frequency); result.PutDate = double.IsNaN(optionAssPutResult.Item2) ? null : optionAssPutResult.Item1; result.YieldToPut = optionAssPutResult.Item2; result.CleanPrice = double.IsNaN(result.CleanPrice) ? optionAssPutResult.Item3 : result.CleanPrice; } } return(result); }
public async Task Test_Pricing_request__Correct_response(object input) { // Prepare PricingRequest request = (PricingRequest)input; // Pre-validate Assert.NotNull(request); // Perform PricingResponse response = await _adapter.GetPriceDetails(request); // Post-validate Assert.NotNull(response); Assert.Equal(request.Header.DistributorId, response.Header.DistributorId); Assert.True(!string.IsNullOrWhiteSpace(response.Header.ExternalOrderNumber)); if (!string.IsNullOrWhiteSpace(request.Header.ExternalOrderNumber)) { Assert.Equal(request.Header.ExternalOrderNumber, response.Header.ExternalOrderNumber); } Assert.Equal(request.Lines.Length, response.Lines.Length); Assert.True(response.Header.TotalDue > 0); Assert.True(response.Header.VolumePoints > 0); }
public override IPricingResult Calculate(CdsProtectionLeg protectionLeg, IMarketCondition market, PricingRequest request) { var result = new PricingResult(market.ValuationDate, request); var start = protectionLeg.StartDate; var maturity = protectionLeg.UnderlyingMaturityDate; var valuationDate = market.ValuationDate; if (market.ValuationDate >= maturity) { result.Pv = 0.0; } else { var tmpStart = valuationDate <= start ? start : valuationDate; var step = (maturity - tmpStart) / NumIntegrationInterval; var term = new Term(step, Period.Day); var pv = 0.0; var df = market.DiscountCurve.Value.GetDf(valuationDate, tmpStart); var prob = market.SurvivalProbabilityCurve.Value.GetSpotRate(tmpStart); for (var i = 0; i < NumIntegrationInterval; ++i) { var tmpDate = term.Next(tmpStart, i + 1); var dfTmp = market.DiscountCurve.Value.GetDf(valuationDate, tmpDate); var probTmp = market.SurvivalProbabilityCurve.Value.GetSpotRate(tmpDate); pv += (df + dfTmp) * (prob - probTmp); df = dfTmp; prob = probTmp; } pv *= 0.5 * (1 - protectionLeg.RecoveryRate); result.Pv = protectionLeg.Notional * pv; } return(result); }
public override IPricingResult Calculate(FxOption fxOption, IMarketCondition market, PricingRequest request) { var newMarket = market.UpdateCondition( new UpdateMktConditionPack <IYieldCurve>(x => x.DividendCurves, market.FgnDiscountCurve.Value), new UpdateMktConditionPack <double>(x => x.SpotPrices.Value.Values.First(), market.GetFxRate(GetSpotDate(market.ValuationDate, fxOption), fxOption.DomCcy, fxOption.FgnCcy)) ); return(new AnalyticalVanillaEuropeanOptionEngine().Calculate(fxOption, newMarket, request)); }
public override IPricingResult Calculate(ConstantLeveragedNote cln, IMarketCondition market, PricingRequest request) { var result = new PricingResult(market.ValuationDate, request); double finalNoteValue; result.Pv = CalcPv(cln, market, out finalNoteValue); var startFxRate = cln.FxRates[cln.StartDate]; var endFxRate = cln.FxRates[market.ValuationDate]; result.Delta = finalNoteValue * cln.TargetLeverage * endFxRate / startFxRate; return(result); }
public override IPricingResult Calculate(HoldingPeriod holdingPeriod, IMarketCondition market, PricingRequest request) { var beginValuation = DateTime.Now; var result = new PricingResult(market.ValuationDate, request); var psDict = new Dictionary <string, Dictionary <string, RateRecord> >(); var bondId = holdingPeriod.Id; var startDate = holdingPeriod.StartDate; var endDate = holdingPeriod.UnderlyingMaturityDate; var bond = holdingPeriod.UnderlyingBond; _roundCleanPrice = holdingPeriod.UnderlyingBond.RoundCleanPrice; var startBondId = bondId + "_Start"; var endBondId = bondId + "_End"; // Create start and end bond market var startMarket = CreateMarketCondition(bondId, startBondId, startDate, market, holdingPeriod.StartFixingRate); var endMarket = CreateMarketCondition(bondId, endBondId, endDate, market, holdingPeriod.EndFixingRate); // Calc Ai var startAiCashflow = CalcBond(bond, startMarket); var endAiCashflow = CalcBond(bond, endMarket); var principalBetweenTemp = startAiCashflow.Cashflows.Where(x => x.CashflowType == CashflowType.Principal && x.AccrualEndDate > startDate && x.AccrualEndDate <= endDate).Sum(cashflow => cashflow.PaymentAmount); var interestBetweenTemp = startAiCashflow.Cashflows.Where(x => x.CashflowType == CashflowType.Coupon && x.AccrualEndDate > startDate && x.AccrualEndDate <= endDate).Sum(cashflow => cashflow.PaymentAmount); var yieldPricer = new HoldingPeriodYieldPricer(holdingPeriod, startAiCashflow.Ai, endAiCashflow.Ai, principalBetweenTemp, interestBetweenTemp); var holdingPeriodResult = new Dictionary <string, double>(); holdingPeriodResult["holdingCost"] = double.IsNaN(holdingPeriod.HoldingCost) ? 0.0 : holdingPeriod.HoldingCost; holdingPeriodResult["startFrontCommission"] = double.IsNaN(holdingPeriod.StartFrontCommission) ? 0.0 : holdingPeriod.StartFrontCommission; holdingPeriodResult["startBackCommission"] = double.IsNaN(holdingPeriod.StartBackCommission) ? 0.0 : holdingPeriod.StartBackCommission; holdingPeriodResult["endFrontCommission"] = double.IsNaN(holdingPeriod.EndFrontCommission) ? 0.0 : holdingPeriod.EndFrontCommission; holdingPeriodResult["endBackCommission"] = double.IsNaN(holdingPeriod.EndBackCommission) ? 0.0 : holdingPeriod.EndBackCommission; // option date holdingPeriodResult["hasStartOption"] = ExecutionOptionDate(startDate, holdingPeriod.UnderlyingBond, startAiCashflow.Cashflows) == null ? 1.0 : 0.0; holdingPeriodResult["hasEndOption"] = ExecutionOptionDate(endDate, holdingPeriod.UnderlyingBond, endAiCashflow.Cashflows) == null ? 1.0 : 0.0; var isCalcStartCleanPrice = false; var isCalcEndCleanPrice = false; string functionType = ""; double inputPar1 = 0.0; double inputPar2 = 0.0; if (result.IsRequested(PricingRequest.NetAnnualizedYield)) { var startResult = CalcStartBond(startMarket, bondId, bond, holdingPeriodResult); var endResult = CalcEndBond(endMarket, bondId, bond, holdingPeriodResult); var startCleanPrice = _roundCleanPrice ? Math.Round(startResult.CleanPrice, 4, MidpointRounding.AwayFromZero) : startResult.CleanPrice; var endCleanPrice = _roundCleanPrice ? Math.Round(endResult.CleanPrice, 4, MidpointRounding.AwayFromZero) : endResult.CleanPrice; // Calc functionType = "AnnualYieldFromCleanPrice"; inputPar1 = startCleanPrice; inputPar2 = endCleanPrice; } else if (result.IsRequested(PricingRequest.CleanPrice) && market.MktQuote.Value[bondId].Item1 == PriceQuoteType.None) { if (market.MktQuote.Value.ContainsKey(startBondId)) { var startResult = CalcStartBond(startMarket, bondId, bond, holdingPeriodResult); var startCleanPrice = _roundCleanPrice ? Math.Round(startResult.CleanPrice, 4, MidpointRounding.AwayFromZero) : startResult.CleanPrice; var annualizedYield = market.MktQuote.Value[bondId].Item2; // Calc functionType = "EndCleanPriceFromAnnual"; inputPar1 = startCleanPrice; inputPar2 = annualizedYield; isCalcEndCleanPrice = true; } else if (market.MktQuote.Value.ContainsKey(endBondId)) { var endResult = CalcEndBond(endMarket, bondId, bond, holdingPeriodResult); var annualizedYield = market.MktQuote.Value[bondId].Item2; var endCleanPrice = _roundCleanPrice ? Math.Round(endResult.CleanPrice, 4, MidpointRounding.AwayFromZero) : endResult.CleanPrice; // Calc functionType = "StartCleanPriceFromAnnual"; inputPar1 = endCleanPrice; inputPar2 = annualizedYield; isCalcStartCleanPrice = true; } } else if (result.IsRequested(PricingRequest.CleanPrice) && market.MktQuote.Value.ContainsKey(bondId) && market.MktQuote.Value[bondId].Item1 == PriceQuoteType.NetPnl) { if (market.MktQuote.Value.ContainsKey(startBondId)) { var startResult = CalcStartBond(startMarket, bondId, bond, holdingPeriodResult); var netPnl = market.MktQuote.Value[bondId].Item2; var startCleanPrice = _roundCleanPrice ? Math.Round(startResult.CleanPrice, 4, MidpointRounding.AwayFromZero) : startResult.CleanPrice; // Calc functionType = "EndCleanPriceFromPnl"; inputPar1 = startCleanPrice; inputPar2 = netPnl; isCalcEndCleanPrice = true; } else if (market.MktQuote.Value.ContainsKey(endBondId)) { var endResult = CalcEndBond(endMarket, bondId, bond, holdingPeriodResult); var netPnl = market.MktQuote.Value[bondId].Item2; var endCleanPrice = _roundCleanPrice ? Math.Round(endResult.CleanPrice, 4, MidpointRounding.AwayFromZero) : endResult.CleanPrice; // Calc functionType = "StartCleanPriceFromPnl"; inputPar1 = endCleanPrice; inputPar2 = netPnl; isCalcStartCleanPrice = true; } } else { CalcStartBond(startMarket, bondId, bond, holdingPeriodResult); CalcEndBond(endMarket, bondId, bond, holdingPeriodResult); } // Calc yieldPricer.CalcAnnualizedYieldCleanPrice(functionType, inputPar1, inputPar2, holdingPeriodResult); if (isCalcStartCleanPrice) { // Calc startDate bond var mktQuote = new Dictionary <string, Tuple <PriceQuoteType, double> > { { bondId, Tuple.Create(PriceQuoteType.Clean, holdingPeriodResult["startCleanPrice"]) } }; var newMarket = startMarket.UpdateCondition(new UpdateMktConditionPack <Dictionary <string, Tuple <PriceQuoteType, double> > >(x => x.MktQuote, mktQuote)); CalcStartBond(newMarket, bondId, bond, holdingPeriodResult); } if (isCalcEndCleanPrice) { // Calc endDate bond var mktQuote = new Dictionary <string, Tuple <PriceQuoteType, double> > { { bondId, Tuple.Create(PriceQuoteType.Clean, holdingPeriodResult["endCleanPrice"]) } }; var newMarket = endMarket.UpdateCondition(new UpdateMktConditionPack <Dictionary <string, Tuple <PriceQuoteType, double> > >(x => x.MktQuote, mktQuote)); CalcEndBond(newMarket, bondId, bond, holdingPeriodResult); } ParseResult(psDict, bondId, holdingPeriodResult); result.ProductSpecific = psDict; var endValuation = DateTime.Now; result.CalcTimeInMilliSecond = (endValuation - beginValuation).TotalMilliseconds; return(result); }
public override IPricingResult Calculate(BinaryOption trade, IMarketCondition market, PricingRequest request) { var result = new PricingResult(market.ValuationDate, request); if (trade.BinaryOptionPayoffType == BinaryOptionPayoffType.CashOrNothing) { var factor = (double)BinaryOptionReplicationStrategy; var lowStrike = trade.Strike + Offset * (factor - 1.0) / 2.0; var highStrike = trade.Strike + Offset * (factor + 1.0) / 2.0; //if call, replicate by call spreads, //if put, replicate by put spreads var lowStrikeOption = new VanillaOption(trade.StartDate, trade.UnderlyingMaturityDate, trade.Exercise, trade.OptionType, lowStrike, trade.UnderlyingProductType, trade.Calendar, trade.DayCount, trade.PayoffCcy, trade.SettlementCcy, trade.ExerciseDates, trade.ObservationDates, trade.Notional); var highStrikeOption = new VanillaOption(trade.StartDate, trade.UnderlyingMaturityDate, trade.Exercise, trade.OptionType, highStrike, trade.UnderlyingProductType, trade.Calendar, trade.DayCount, trade.PayoffCcy, trade.SettlementCcy, trade.ExerciseDates, trade.ObservationDates, trade.Notional); var engine = new AnalyticalVanillaEuropeanOptionEngine(); var lowResult = engine.Calculate(lowStrikeOption, market, request); var highResult = engine.Calculate(highStrikeOption, market, request); var sign = trade.OptionType == OptionType.Call ? 1.0 : -1.0; factor = sign * trade.CashOrNothingAmount / Offset; //calc basic stuff if (result.IsRequested(PricingRequest.Pv)) { result.Pv = (lowResult.Pv - highResult.Pv) * factor; } if (AnalyticalOptionPricerUtil.isBasicPricing(result)) { result.Delta = (lowResult.Delta - highResult.Delta) * factor; result.DeltaCash = result.Delta * market.SpotPrices.Value.Values.First(); result.Gamma = (lowResult.Gamma - highResult.Gamma) * factor; result.GammaCash = result.Gamma * market.SpotPrices.Value.Values.First() * market.SpotPrices.Value.Values.First() / 100; result.Vega = (lowResult.Vega - highResult.Vega) * factor; result.Rho = (lowResult.Rho - highResult.Rho) * factor; result.Theta = (lowResult.Theta - highResult.Theta) * factor; } if (AnalyticalOptionPricerUtil.isHighOrderPricing(result)) { result.DDeltaDvol = (lowResult.DDeltaDvol - highResult.DDeltaDvol) * factor; result.DVegaDvol = (lowResult.DVegaDvol - highResult.DVegaDvol) * factor; result.DVegaDt = (lowResult.DVegaDt - highResult.DVegaDt) * factor; result.DDeltaDt = (lowResult.DDeltaDt - highResult.DDeltaDt) * factor; } } else if (trade.BinaryOptionPayoffType == BinaryOptionPayoffType.AssetOrNothing) { var binaryCfOption = new BinaryOption(trade.StartDate, trade.UnderlyingMaturityDate, trade.Exercise, trade.OptionType, trade.Strike, trade.UnderlyingProductType, BinaryOptionPayoffType.CashOrNothing, 1.0, trade.Calendar, trade.DayCount, trade.PayoffCcy, trade.SettlementCcy, trade.ExerciseDates, trade.ObservationDates); var binaryResult = Calculate(binaryCfOption, market, request); var vanillaOption = new VanillaOption(trade.StartDate, trade.UnderlyingMaturityDate, trade.Exercise, trade.OptionType, trade.Strike, trade.UnderlyingProductType, trade.Calendar, trade.DayCount, trade.PayoffCcy, trade.SettlementCcy, trade.ExerciseDates, trade.ObservationDates, trade.Notional); var engine = new AnalyticalVanillaEuropeanOptionEngine(); var vanillaResult = engine.Calculate(vanillaOption, market, request); var sign = trade.OptionType == OptionType.Call ? 1.0 : -1.0; if (result.IsRequested(PricingRequest.Pv)) { result.Pv = sign * vanillaResult.Pv + trade.Strike * binaryResult.Pv; } if (AnalyticalOptionPricerUtil.isBasicPricing(result)) { result.Delta = sign * vanillaResult.Delta + trade.Strike * binaryResult.Delta; result.DeltaCash = result.Delta * market.SpotPrices.Value.Values.First(); result.Gamma = sign * vanillaResult.Gamma + trade.Strike * binaryResult.Gamma; result.GammaCash = result.Gamma * market.SpotPrices.Value.Values.First() * market.SpotPrices.Value.Values.First() / 100; result.Vega = sign * vanillaResult.Vega + trade.Strike * binaryResult.Vega; result.Rho = sign * vanillaResult.Rho + trade.Strike * binaryResult.Rho; result.Theta = sign * vanillaResult.Theta + trade.Strike * binaryResult.Theta; } if (AnalyticalOptionPricerUtil.isHighOrderPricing(result)) { result.DDeltaDvol = sign * vanillaResult.DDeltaDvol + trade.Strike * binaryResult.DDeltaDvol; result.DVegaDvol = sign * vanillaResult.DVegaDvol + trade.Strike * binaryResult.DVegaDvol; result.DVegaDt = sign * vanillaResult.DVegaDt + trade.Strike * binaryResult.DVegaDt; result.DDeltaDt = sign * vanillaResult.DDeltaDt + trade.Strike * binaryResult.DDeltaDt; } } return(result); }
public override IPricingResult Calculate(BondFutures bondFuture, IMarketCondition market, PricingRequest request) { var beginValuation = DateTime.Now; var pricingRequest = CheckParameterCondition(bondFuture, market, request); //if (result.IsRequested(PricingRequest.Dv01)) //{ // result.Dv01 = CalcDv01(bondFuture, market); //} var result = new PricingResult(market.ValuationDate, pricingRequest); //if (result.IsRequested(PricingRequest.Pv)) //{ // result.Pv = CalcPv(bondFuture, market); //} if (result.IsRequested(PricingRequest.DirtyPrice)) { result.DirtyPrice = market.MktQuote.Value.Where(x => x.Key == bondFuture.Id).Select(x => x.Value.Item2).First() * bondFuture.Notional / 100; } if (result.IsRequested(PricingRequest.ConvertFactors)) { result.ConvertFactors = CalcConvertFactors(bondFuture, market); } if (result.IsRequested(PricingRequest.Irr) || result.IsRequested(PricingRequest.Pv01) || result.IsRequested(PricingRequest.KeyRateDv01) || result.IsRequested(PricingRequest.ZeroSpread) || result.IsRequested(PricingRequest.ZeroSpreadDelta) || result.IsRequested(PricingRequest.UnderlyingPv) || result.IsRequested(PricingRequest.Basis) || result.IsRequested(PricingRequest.Convexity) || result.IsRequested(PricingRequest.Ytm) || result.IsRequested(PricingRequest.CheapestToDeliver) || result.IsRequested(PricingRequest.ModifiedDuration) || result.IsRequested(PricingRequest.MacDuration) ) { //TODO: wierd update logic, why bother? var mktQuote = market.MktQuote.Value.Keys.Where(quoteKey => !quoteKey.Contains(bondFuture.Id + "_")).ToDictionary(quoteKey => quoteKey, quoteKey => market.MktQuote.Value[quoteKey]); var updateMarket = market.UpdateCondition(new UpdateMktConditionPack <Dictionary <string, Tuple <PriceQuoteType, double> > >(x => x.MktQuote, mktQuote)); var yieldPricer = new BondFuturesYieldPricer(bondFuture, updateMarket); //calculate convert factors if (!result.ConvertFactors.Any()) { result.ConvertFactors = CalcConvertFactors(bondFuture, market); } var convertFactors = result.ConvertFactors; //calculate IRR result.ProductSpecific = yieldPricer.CalcEquation("FromFuturesPriceAndBondPrice"); //calculate pv01 var maxIrr = result.ProductSpecific["Irr"].Values.Select(x => x.Rate).Max(); var ctdBondId = result.ProductSpecific["Irr"].First(x => x.Value.Rate == maxIrr).Key; var ctdBond = bondFuture.Deliverables.First(x => x.Id == ctdBondId); var cf = convertFactors[ctdBondId]; var scaling = bondFuture.Notional / (100.0 * cf); var engine = new BondEngineCn(); result.CheapestToDeliver = ctdBondId; //two risks here are CTD risk, not bond futures risk var resultCTD = engine.Calculate(ctdBond, market, PricingRequest.All); result.ZeroSpread = resultCTD.ZeroSpread; result.UnderlyingPv = resultCTD.Pv * scaling; result.Basis = yieldPricer.CalcFutureCtdBasis(ctdBond, cf); result.Ytm = resultCTD.Ytm; result.MacDuration = resultCTD.MacDuration; result.ModifiedDuration = resultCTD.ModifiedDuration; result.Convexity = resultCTD.Convexity; result.DollarConvexity = resultCTD.DollarConvexity * scaling; // 1% price impact result.DollarModifiedDuration = resultCTD.DollarModifiedDuration * scaling; // same order of magnitutude of CTD dollar modifiedDuration, good for pnl attribution //convert to bond futures risk result.Pv01 = resultCTD.Pv01 * scaling; // underlying pv01 is foreach (var kvp in resultCTD.KeyRateDv01) { foreach (var risk in kvp.Value) { risk.Risk *= scaling; } } result.KeyRateDv01 = resultCTD.KeyRateDv01; result.ZeroSpreadDelta = resultCTD.ZeroSpreadDelta * scaling; } if (result.IsRequested(PricingRequest.FairQuote)) { var mktQuote = market.MktQuote.Value.Keys.Where(quoteKey => !quoteKey.Equals(bondFuture.Id)).ToDictionary(quoteKey => quoteKey, quoteKey => market.MktQuote.Value[quoteKey]); var updateMarket = market.UpdateCondition(new UpdateMktConditionPack <Dictionary <string, Tuple <PriceQuoteType, double> > >(x => x.MktQuote, mktQuote)); var yieldPricer = new BondFuturesYieldPricer(bondFuture, updateMarket); result.ProductSpecific = yieldPricer.CalcEquation("FromBondPriceAndIrr"); } if (result.IsRequested(PricingRequest.MktQuote)) { result.ProductSpecific = CalcMktFuturePrice(bondFuture, market); } if (result.IsRequested(PricingRequest.UnderlyingFairQuote)) { var mktQuote = market.MktQuote.Value.Keys.Where(quoteKey => quoteKey.Contains(bondFuture.Id)).ToDictionary(quoteKey => quoteKey, quoteKey => market.MktQuote.Value[quoteKey]); var updateMarket = market.UpdateCondition(new UpdateMktConditionPack <Dictionary <string, Tuple <PriceQuoteType, double> > >(x => x.MktQuote, mktQuote)); var yieldPricer = new BondFuturesYieldPricer(bondFuture, updateMarket); result.ProductSpecific = yieldPricer.CalcEquation("FromFuturesPriceAndIrr"); } var endValuation = DateTime.Now; result.CalcTimeInMilliSecond = (endValuation - beginValuation).TotalMilliseconds; return(result); }
private PricingRequest CheckParameterCondition(BondFutures bondFuture, IMarketCondition market, PricingRequest request) { var pricingRequest = request; var tfId = bondFuture.Id; var bondIds = bondFuture.Deliverables.Select(x => x.Id).ToArray(); var treasuryIds = bondIds.Select(x => tfId + "_" + x).ToArray(); var mktQuotes = market.MktQuote.Value; if (mktQuotes != null && mktQuotes.Count > 0) { var tfHasValue = mktQuotes.ContainsKey(tfId); var bondHasValue = bondIds.Select(x => mktQuotes.ContainsKey(x)).Count(y => y) > 0; var treasuryHasValue = treasuryIds.Select(x => mktQuotes.ContainsKey(x)).Count(y => y) > 0; if (request == PricingRequest.All) { if (tfHasValue && bondHasValue) { pricingRequest = PricingRequest.Irr; } else if (bondHasValue && treasuryHasValue) { pricingRequest = PricingRequest.FairQuote; } else if (tfHasValue && treasuryHasValue) { pricingRequest = PricingRequest.UnderlyingFairQuote; } } } return(pricingRequest); }
public override IPricingResult GetRisks(Forward <Bond> trade, IMarketCondition market, PricingRequest pricingRequest) { var result = new PricingResult(market.ValuationDate, pricingRequest); var bondEngine = new BondEngine(); var bMarket = market.UpdateCondition(new UpdateMktConditionPack <IYieldCurve>(x => x.DiscountCurve, market.UnderlyingDiscountCurve.Value)); if (result.IsRequested(PricingRequest.Dv01)) { var bondZeroSpread = BondPricingFunctions.ZeroSpread(trade.Underlying, bMarket); IMarketCondition bondMktUp; IMarketCondition bondMktDown; if (market.FixingCurve.HasValue) { bondMktUp = bMarket.UpdateCondition( new UpdateMktConditionPack <IYieldCurve>(x => x.FixingCurve, bMarket.FixingCurve.Value.Shift(1)), new UpdateMktConditionPack <IYieldCurve>(x => x.DiscountCurve, bMarket.DiscountCurve.Value.Shift(1).GetSpreadedCurve(new ZeroSpread(bondZeroSpread))) ); bondMktDown = bMarket.UpdateCondition( new UpdateMktConditionPack <IYieldCurve>(x => x.FixingCurve, bMarket.FixingCurve.Value.Shift(-1)), new UpdateMktConditionPack <IYieldCurve>(x => x.DiscountCurve, bMarket.DiscountCurve.Value.Shift(-1).GetSpreadedCurve(new ZeroSpread(bondZeroSpread))) ); } else { bondMktUp = bMarket.UpdateCondition( new UpdateMktConditionPack <IYieldCurve>(x => x.DiscountCurve, bMarket.DiscountCurve.Value.Shift(1).GetSpreadedCurve(new ZeroSpread(bondZeroSpread))) ); bondMktDown = bMarket.UpdateCondition( new UpdateMktConditionPack <IYieldCurve>(x => x.DiscountCurve, bMarket.DiscountCurve.Value.Shift(-1).GetSpreadedCurve(new ZeroSpread(bondZeroSpread))) ); } var fwdMarket = market.UpdateCondition(new UpdateMktConditionPack <ISpread>(x => x.CreditSpread, new ZeroSpread(bondZeroSpread))); var upPv = bondEngine.Calculate(trade.Underlying, bondMktUp, PricingRequest.Pv).Pv; var downPv = bondEngine.Calculate(trade.Underlying, bondMktDown, PricingRequest.Pv).Pv; if (fwdMarket.FixingCurve.HasValue) { var fwdMktUp = fwdMarket.UpdateCondition( new UpdateMktConditionPack <IYieldCurve>(x => x.FixingCurve, bMarket.FixingCurve.Value.Shift(1)), new UpdateMktConditionPack <IYieldCurve>(x => x.DiscountCurve, bMarket.DiscountCurve.Value.Shift(1)), new UpdateMktConditionPack <IYieldCurve>(x => x.UnderlyingDiscountCurve, bMarket.UnderlyingDiscountCurve.Value.Shift(1)), new UpdateMktConditionPack <Dictionary <string, Tuple <PriceQuoteType, double> > >(x => x.MktQuote, bMarket.MktQuote.Value.UpdateKey(trade.Underlying.Id, Tuple.Create(PriceQuoteType.Dirty, upPv))) ); var fwdMktDown = fwdMarket.UpdateCondition( new UpdateMktConditionPack <IYieldCurve>(x => x.FixingCurve, bMarket.FixingCurve.Value.Shift(-1)), new UpdateMktConditionPack <IYieldCurve>(x => x.DiscountCurve, bMarket.DiscountCurve.Value.Shift(-1)), new UpdateMktConditionPack <IYieldCurve>(x => x.UnderlyingDiscountCurve, bMarket.UnderlyingDiscountCurve.Value.Shift(-1)), new UpdateMktConditionPack <Dictionary <string, Tuple <PriceQuoteType, double> > >(x => x.MktQuote, bMarket.MktQuote.Value.UpdateKey(trade.Underlying.Id, Tuple.Create(PriceQuoteType.Dirty, downPv))) ); result.Dv01 = (CalcPv(trade, fwdMktDown) - CalcPv(trade, fwdMktUp)) / 2.0; } else { var fwdMktUp = fwdMarket.UpdateCondition( new UpdateMktConditionPack <IYieldCurve>(x => x.DiscountCurve, bMarket.DiscountCurve.Value.Shift(1)), new UpdateMktConditionPack <IYieldCurve>(x => x.UnderlyingDiscountCurve, bMarket.UnderlyingDiscountCurve.Value.Shift(1)), new UpdateMktConditionPack <Dictionary <string, Tuple <PriceQuoteType, double> > >(x => x.MktQuote, bMarket.MktQuote.Value.UpdateKey(trade.Underlying.Id, Tuple.Create(PriceQuoteType.Dirty, upPv))) ); var fwdMktDown = fwdMarket.UpdateCondition( new UpdateMktConditionPack <IYieldCurve>(x => x.DiscountCurve, bMarket.DiscountCurve.Value.Shift(-1)), new UpdateMktConditionPack <IYieldCurve>(x => x.UnderlyingDiscountCurve, bMarket.UnderlyingDiscountCurve.Value.Shift(-1)), new UpdateMktConditionPack <Dictionary <string, Tuple <PriceQuoteType, double> > >(x => x.MktQuote, bMarket.MktQuote.Value.UpdateKey(trade.Underlying.Id, Tuple.Create(PriceQuoteType.Dirty, downPv))) ); result.Dv01 = (CalcPv(trade, fwdMktDown) - CalcPv(trade, fwdMktUp)) / 2.0; } } if (result.IsRequested(PricingRequest.Dv01Underlying)) { var factor = trade.Notional / trade.Underlying.Notional; result.Dv01Underlying = bondEngine.Calculate(trade.Underlying, bMarket, PricingRequest.Dv01).Dv01 *factor; } return(result); }
public override IPricingResult Calculate(Bond bond, IMarketCondition market, PricingRequest request) { var beginValuation = DateTime.Now; var result = new PricingResult(market.ValuationDate, request); var isCleanPriceRound = bond.RoundCleanPrice; var bondQuote = market.MktQuote.Value.ContainsKey(bond.Id) ? market.MktQuote.Value[bond.Id] : null; var bMktQuote = new Dictionary <string, Tuple <PriceQuoteType, double> >(); IPricingResult resultOptionBond = new PricingResult(market.ValuationDate, request); IPricingResult resultSimpleBond; if (bondQuote != null && (bondQuote.Item1 == PriceQuoteType.YtmExecution || bondQuote.Item1 == PriceQuoteType.YtmCallExecution || bondQuote.Item1 == PriceQuoteType.YtmPutExecution)) { bMktQuote[bond.Id] = Tuple.Create(PriceQuoteType.Ytm, bondQuote.Item2); var ytmMarket = market.UpdateCondition(new UpdateMktConditionPack <Dictionary <string, Tuple <PriceQuoteType, double> > >(x => x.MktQuote, bMktQuote)); // Get Call or Put cleanprice var pricingRequest = PricingRequest.CleanPrice; if (result.IsRequested(PricingRequest.AiEod)) { pricingRequest = pricingRequest | PricingRequest.AiEod; } resultOptionBond = CalcOptionBond(bond, ytmMarket, pricingRequest, bondQuote.Item1); // Parse market var cleanMarket = UpdateCleanPriceMarket(bond.Id, resultOptionBond.CleanPrice, isCleanPriceRound, market); resultSimpleBond = _bondEngine.Calculate(bond, cleanMarket, request); } else { if (isCleanPriceRound && bondQuote != null) { if (bondQuote.Item1 == PriceQuoteType.Clean) { var cleanPriceMarket = UpdateCleanPriceMarket(bond.Id, bondQuote.Item2, isCleanPriceRound, market); resultSimpleBond = _bondEngine.Calculate(bond, cleanPriceMarket, request); } else { resultSimpleBond = _bondEngine.Calculate(bond, market, request); var cleanPriceMarket = UpdateCleanPriceMarket(bond.Id, resultSimpleBond.CleanPrice, isCleanPriceRound, market); resultSimpleBond = _bondEngine.Calculate(bond, cleanPriceMarket, request); } } else { resultSimpleBond = _bondEngine.Calculate(bond, market, request); } // Parse market bMktQuote[bond.Id] = Tuple.Create(PriceQuoteType.Clean, double.IsNaN(resultSimpleBond.CleanPrice) ? 0.0 : resultSimpleBond.CleanPrice); var executionYieldPricingRequest = PricingRequest.Ytm; if (result.IsRequested(PricingRequest.AiEod)) { executionYieldPricingRequest = PricingRequest.Ytm | PricingRequest.AiEod; } var newMarket = market.UpdateCondition(new UpdateMktConditionPack <Dictionary <string, Tuple <PriceQuoteType, double> > >(x => x.MktQuote, bMktQuote)); if (result.IsRequested(PricingRequest.YtmExecution)) { resultOptionBond = CalcOptionBond(bond, newMarket, executionYieldPricingRequest, PriceQuoteType.YtmExecution); } } result = (PricingResult)resultSimpleBond; result.YieldToCall = resultOptionBond.YieldToCall; result.YieldToPut = resultOptionBond.YieldToPut; result.CallDate = resultOptionBond.CallDate; result.PutDate = resultOptionBond.PutDate; var endValuation = DateTime.Now; result.CalcTimeInMilliSecond = (endValuation - beginValuation).TotalMilliseconds; return(result); }
private Tuple <Date, double, double> CalcOption(Dictionary <string, double> optionInfo, Bond bond, IMarketCondition market, PricingRequest request, Frequency frequency = Frequency.None) { var paymentDaycount = bond.BondTradeingMarket == TradingMarket.ChinaInterBank ? (IDayCount) new ActActIsma() : new ModifiedAfb(); if (optionInfo != null && optionInfo.Count > 0) { var execution = optionInfo.Where(x => x.Key.ToDate() > market.ValuationDate).OrderBy(x => x.Key.ToDate()).FirstOrDefault(); var maturityDate = execution.Key.ToDate(); if (maturityDate != null) { var executionBond = new Bond(bond.Id, bond.StartDate, maturityDate, bond.Notional, bond.Currency, bond.Coupon, bond.Calendar, frequency, bond.Stub, bond.AccrualDayCount, paymentDaycount, bond.AccrualBizDayRule, bond.PaymentBizDayRule, bond.SettlmentGap, bond.BondTradeingMarket, bond.StickToEom, bond.Redemption, bond.FirstPaymentDate, bond.IsZeroCouponBond, bond.IssuePrice, bond.IssueRate, AmortizationType.None, bond.AmortizationInDates, bond.AmortizationInIndex, bond.RenormalizeAfterAmoritzation, bond.StepWiseCompensationRate); var executionResult = _bondEngine.Calculate(executionBond, market, request); return(Tuple.Create(maturityDate, executionResult.Ytm, executionResult.CleanPrice)); } } return(Tuple.Create(Date.MaxValue, double.NaN, double.NaN)); }