// Instrument interface public override void calculate() { if (discountCurve_.empty()) { throw new ArgumentException("no discounting term structure set"); } results_.value = results_.cash = 0; results_.errorEstimate = null; results_.legNPV = new InitializedList <double?>(arguments_.legs.Count); results_.legBPS = new InitializedList <double?>(arguments_.legs.Count); List <double?> startDiscounts = new InitializedList <double?>(arguments_.legs.Count); for (int i = 0; i < arguments_.legs.Count; ++i) { results_.legNPV[i] = arguments_.payer[i] * CashFlows.npv(arguments_.legs[i], discountCurve_); results_.legBPS[i] = arguments_.payer[i] * CashFlows.bps(arguments_.legs[i], discountCurve_); results_.value += results_.legNPV[i]; results_.cash += arguments_.payer[i] * CashFlows.cash(arguments_.legs[i]); try { Date d = CashFlows.startDate(arguments_.legs[i]); startDiscounts[i] = discountCurve_.link.discount(d); } catch { startDiscounts[i] = null; } } results_.additionalResults.Add("startDiscounts", startDiscounts); }
public override double value(double x) { InterestRate y = new InterestRate(x, dayCounter_, compounding_, frequency_); double NPV = CashFlows.npv(cashflows_, y, settlementDate_); return(marketPrice_ - NPV); }
public override double value(double y) { InterestRate yield = new InterestRate(y, dayCounter_, compounding_, frequency_); double NPV = CashFlows.npv(leg_, yield, includeSettlementDateFlows_, settlementDate_, npvDate_); return(npv_ - NPV); }
public override double value(double zSpread) { zSpread_.setValue(zSpread); double NPV = CashFlows.npv(leg_, curve_, includeSettlementDateFlows_, settlementDate_, npvDate_); return(npv_ - NPV); }
//! Yield value of a basis point /*! The yield value of a one basis point change in price is * the derivative of the yield with respect to the price * multiplied by 0.01 */ public static double yieldValueBasisPoint(Leg leg, InterestRate yield, bool includeSettlementDateFlows, Date settlementDate = null, Date npvDate = null) { if (leg.empty()) { return(0.0); } if (settlementDate == null) { settlementDate = Settings.evaluationDate(); } if (npvDate == null) { npvDate = settlementDate; } double npv = CashFlows.npv(leg, yield, includeSettlementDateFlows, settlementDate, npvDate); double modifiedDuration = CashFlows.duration(leg, yield, Duration.Type.Modified, includeSettlementDateFlows, settlementDate, npvDate); double shift = 0.01; return((1.0 / (-npv * modifiedDuration)) * shift); }
//! Basis-point value /*! Obtained by setting dy = 0.0001 in the 2nd-order Taylor * series expansion. */ public static double basisPointValue(Leg leg, InterestRate yield, bool includeSettlementDateFlows, Date settlementDate = null, Date npvDate = null) { if (leg.empty()) { return(0.0); } if (settlementDate == null) { settlementDate = Settings.evaluationDate(); } if (npvDate == null) { npvDate = settlementDate; } double npv = CashFlows.npv(leg, yield, includeSettlementDateFlows, settlementDate, npvDate); double modifiedDuration = CashFlows.duration(leg, yield, Duration.Type.Modified, includeSettlementDateFlows, settlementDate, npvDate); double convexity = CashFlows.convexity(leg, yield, includeSettlementDateFlows, settlementDate, npvDate); double delta = -modifiedDuration * npv; double gamma = (convexity / 100.0) * npv; double shift = 0.0001; delta *= shift; gamma *= shift * shift; return(delta + 0.5 * gamma); }
// At-the-money rate of the cash flows. // The result is the fixed rate for which a fixed rate cash flow vector, equivalent to the input vector, has the required NPV according to the given term structure. If the required NPV is // not given, the input cash flow vector's NPV is used instead. public static double atmRate(List <CashFlow> cashflows, YieldTermStructure discountCurve, Date settlementDate = null, Date npvDate = null, int exDividendDays = 0, double?npv = null) { double bps = CashFlows.bps(cashflows, discountCurve, settlementDate, npvDate, exDividendDays); if (npv == null) { npv = CashFlows.npv(cashflows, discountCurve, settlementDate, npvDate, exDividendDays); } return(basisPoint_ * npv.Value / bps); }
//! Yield value of a basis point /*! The yield value of a one basis point change in price is * the derivative of the yield with respect to the price * multiplied by 0.01 */ public static double yieldValueBasisPoint(List <CashFlow> leg, InterestRate y, Date settlementDate) { if (leg.Count == 0) { return(0.0); } double shift = 0.01; double dirtyPrice = CashFlows.npv(leg, y, settlementDate); double modifiedDuration = CashFlows.duration(leg, y, Duration.Type.Modified, settlementDate); return((1.0 / (-dirtyPrice * modifiedDuration)) * shift); }
public override void calculate() { List <CashFlow> cashflows = arguments_.cashflows; Date settlementDate = arguments_.settlementDate; Date valuationDate = discountCurve().link.referenceDate(); if (discountCurve().empty()) { throw new ApplicationException("no discounting term structure set"); } results_.value = CashFlows.npv(cashflows, discountCurve().link, valuationDate, valuationDate); results_.settlementValue = CashFlows.npv(cashflows, discountCurve().link, settlementDate, settlementDate); }
// converts the yield volatility into a forward price volatility private double forwardPriceVolatility() { Date bondMaturity = arguments_.redemptionDate; Date exerciseDate = arguments_.callabilityDates[0]; List <CashFlow> fixedLeg = arguments_.cashflows; // value of bond cash flows at option maturity double fwdNpv = CashFlows.npv(fixedLeg, discountCurve_, exerciseDate); DayCounter dayCounter = arguments_.paymentDayCounter; Frequency frequency = arguments_.frequency; // adjust if zero coupon bond (see also bond.cpp) if (frequency == Frequency.NoFrequency || frequency == Frequency.Once) { frequency = Frequency.Annual; } double fwdYtm = CashFlows.yield(fixedLeg, fwdNpv, dayCounter, Compounding.Compounded, frequency, false, exerciseDate); InterestRate fwdRate = new InterestRate(fwdYtm, dayCounter, Compounding.Compounded, frequency); double fwdDur = CashFlows.duration(fixedLeg, fwdRate, Duration.Type.Modified, exerciseDate); double cashStrike = arguments_.callabilityPrices[0]; dayCounter = volatility_.link.dayCounter(); Date referenceDate = volatility_.link.referenceDate(); double exerciseTime = dayCounter.yearFraction(referenceDate, exerciseDate); double maturityTime = dayCounter.yearFraction(referenceDate, bondMaturity); double yieldVol = volatility_.link.volatility(exerciseTime, maturityTime - exerciseTime, cashStrike); double fwdPriceVol = yieldVol * fwdDur * fwdYtm; return(fwdPriceVol); }
public override void calculate() { // validate args for Black engine Utils.QL_REQUIRE(arguments_.putCallSchedule.Count == 1, "Must have exactly one call/put date to use Black Engine"); Date settle = arguments_.settlementDate; Date exerciseDate = arguments_.callabilityDates[0]; Utils.QL_REQUIRE(exerciseDate >= settle, "must have exercise Date >= settlement Date"); List <CashFlow> fixedLeg = arguments_.cashflows; double value = CashFlows.npv(fixedLeg, discountCurve_, settle); double npv = CashFlows.npv(fixedLeg, discountCurve_, discountCurve_.link.referenceDate()); double fwdCashPrice = (value - spotIncome()) / discountCurve_.link.discount(exerciseDate); double cashStrike = arguments_.callabilityPrices[0]; Option.Type type = (arguments_.putCallSchedule[0].type() == Callability.Type.Call ? Option.Type.Call : Option.Type.Put); double priceVol = forwardPriceVolatility(); double exerciseTime = volatility_.link.dayCounter().yearFraction( volatility_.link.referenceDate(), exerciseDate); double embeddedOptionValue = Utils.blackFormula(type, cashStrike, fwdCashPrice, priceVol * Math.Sqrt(exerciseTime)); if (type == Option.Type.Call) { results_.value = npv - embeddedOptionValue; results_.settlementValue = value - embeddedOptionValue; } else { results_.value = npv + embeddedOptionValue; results_.settlementValue = value + embeddedOptionValue; } }
public static double dirtyPrice(Bond bond, InterestRate yield, Date settlementDate = null) { if (settlementDate == null) { settlementDate = bond.settlementDate(); } Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); double dirtyPrice = CashFlows.npv(bond.cashflows(), yield, false, settlementDate) * 100.0 / bond.notional(settlementDate); return(dirtyPrice); }
public override void calculate() { if (discountCurve_.empty()) { throw new ArgumentException("no discounting term structure set"); } results_.value = results_.cash = 0; results_.errorEstimate = null; results_.legNPV = new InitializedList <double?>(arguments_.legs.Count); for (int i = 0; i < arguments_.legs.Count; ++i) { results_.legNPV[i] = arguments_.payer[i] * CashFlows.npv(arguments_.legs[i], discountCurve_); results_.value += results_.legNPV[i]; results_.cash += arguments_.payer[i] * CashFlows.cash(arguments_.legs[i]); } }
public static double cleanPrice(Bond bond, YieldTermStructure discount, double zSpread, DayCounter dayCounter, Compounding compounding, Frequency frequency, Date settlementDate = null) { if (settlementDate == null) { settlementDate = bond.settlementDate(); } Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => "non tradable at " + settlementDate + " (maturity being " + bond.maturityDate() + ")"); double dirtyPrice = CashFlows.npv(bond.cashflows(), discount, zSpread, dayCounter, compounding, frequency, false, settlementDate) * 100.0 / bond.notional(settlementDate); return(dirtyPrice - bond.accruedAmount(settlementDate)); }
public static double cleanPrice(Bond bond, YieldTermStructure discountCurve, Date settlementDate = null) { if (settlementDate == null) { settlementDate = bond.settlementDate(); } Utils.QL_REQUIRE(BondFunctions.isTradable(bond, settlementDate), () => "non tradable at " + settlementDate + " settlementDate date (maturity being " + bond.maturityDate() + ")"); double dirtyPrice = CashFlows.npv(bond.cashflows(), discountCurve, false, settlementDate) * 100.0 / bond.notional(settlementDate); return(dirtyPrice - bond.accruedAmount(settlementDate)); }
public override void calculate() { if (_discountCurve.IsEmpty) { throw new ArgumentException("no discounting term structure set"); } results_.value = 0; results_.cash = 0; results_.errorEstimate = null; results_.legNPV.Clear(); for (int i = 0; i < arguments_.legs.Count; ++i) { results_.legNPV[i] = arguments_.payer[i] * CashFlows.npv(arguments_.legs[i], _discountCurve); results_.value += results_.legNPV[i]; results_.cash += arguments_.payer[i] * CashFlows.cash(arguments_.legs[i]); } }
//! Basis-point value /*! Obtained by setting dy = 0.0001 in the 2nd-order Taylor * series expansion. */ public static double basisPointValue(List <CashFlow> leg, InterestRate y, Date settlementDate) { if (leg.Count == 0) { return(0.0); } double shift = 0.0001; double dirtyPrice = CashFlows.npv(leg, y, settlementDate); double modifiedDuration = CashFlows.duration(leg, y, Duration.Type.Modified, settlementDate); double convexity = CashFlows.convexity(leg, y, settlementDate); double delta = -modifiedDuration * dirtyPrice; double gamma = (convexity / 100.0) * dirtyPrice; delta *= shift; gamma *= shift * shift; return(delta + 0.5 * gamma); }
public override void calculate() { Utils.QL_REQUIRE(!discountCurve_.empty(), "discounting term structure handle is empty"); results_.valuationDate = discountCurve_.link.referenceDate(); bool includeRefDateFlows = includeSettlementDateFlows_.HasValue ? includeSettlementDateFlows_.Value : Settings.includeReferenceDateEvents; results_.value = CashFlows.npv(arguments_.cashflows, discountCurve_, includeRefDateFlows, results_.valuationDate, results_.valuationDate); results_.cash = CashFlows.cash(arguments_.cashflows, arguments_.settlementDate); // a bond's cashflow on settlement date is never taken into // account, so we might have to play it safe and recalculate if (!includeRefDateFlows && results_.valuationDate == arguments_.settlementDate) { // same parameters as above, we can avoid another call results_.settlementValue = results_.value; } else { // no such luck results_.settlementValue = CashFlows.npv(arguments_.cashflows, discountCurve_, false, arguments_.settlementDate, arguments_.settlementDate); } }