internal static global::System.Runtime.InteropServices.HandleRef getCPtr(Euribor3M obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
public void testCurveConsistency <T, I, B>(CommonVars vars, I interpolator, double tolerance) where T : ITraits <YieldTermStructure>, new() where I : IInterpolationFactory, new() where B : IBootStrap <PiecewiseYieldCurve>, new() { vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.instruments, new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator); RelinkableHandle <YieldTermStructure> curveHandle = new RelinkableHandle <YieldTermStructure>(); curveHandle.linkTo(vars.termStructure); // check deposits for (int i = 0; i < vars.deposits; i++) { Euribor index = new Euribor(new Period(vars.depositData[i].n, vars.depositData[i].units), curveHandle); double expectedRate = vars.depositData[i].rate / 100, estimatedRate = index.fixing(vars.today); QAssert.IsTrue(Math.Abs(expectedRate - estimatedRate) < tolerance, vars.depositData[i].n + " " + (vars.depositData[i].units == TimeUnit.Weeks ? "week(s)" : "month(s)") + " deposit:" + "\n estimated rate: " + estimatedRate + "\n expected rate: " + expectedRate); } // check swaps IborIndex euribor6m = new Euribor6M(curveHandle); for (int i = 0; i < vars.swaps; i++) { Period tenor = new Period(vars.swapData[i].n, vars.swapData[i].units); VanillaSwap swap = new MakeVanillaSwap(tenor, euribor6m, 0.0) .withEffectiveDate(vars.settlement) .withFixedLegDayCount(vars.fixedLegDayCounter) .withFixedLegTenor(new Period(vars.fixedLegFrequency)) .withFixedLegConvention(vars.fixedLegConvention) .withFixedLegTerminationDateConvention(vars.fixedLegConvention); double expectedRate = vars.swapData[i].rate / 100, estimatedRate = swap.fairRate(); double error = Math.Abs(expectedRate - estimatedRate); QAssert.IsTrue(error < tolerance, vars.swapData[i].n + " year(s) swap:\n" + "\n estimated rate: " + estimatedRate + "\n expected rate: " + expectedRate + "\n error: " + error + "\n tolerance: " + tolerance); } // check bonds vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.bondHelpers, new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator); curveHandle.linkTo(vars.termStructure); for (int i = 0; i < vars.bonds; i++) { Date maturity = vars.calendar.advance(vars.today, vars.bondData[i].n, vars.bondData[i].units); Date issue = vars.calendar.advance(maturity, -vars.bondData[i].length, TimeUnit.Years); List <double> coupons = new List <double>() { vars.bondData[i].coupon / 100.0 }; FixedRateBond bond = new FixedRateBond(vars.bondSettlementDays, 100.0, vars.schedules[i], coupons, vars.bondDayCounter, vars.bondConvention, vars.bondRedemption, issue); IPricingEngine bondEngine = new DiscountingBondEngine(curveHandle); bond.setPricingEngine(bondEngine); double expectedPrice = vars.bondData[i].price, estimatedPrice = bond.cleanPrice(); QAssert.IsTrue(Math.Abs(expectedPrice - estimatedPrice) < tolerance, i + 1 + " bond failure:" + "\n estimated price: " + estimatedPrice + "\n expected price: " + expectedPrice); } // check FRA vars.termStructure = new PiecewiseYieldCurve <T, I, B>(vars.settlement, vars.fraHelpers, new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator); curveHandle.linkTo(vars.termStructure); IborIndex euribor3m = new Euribor3M(curveHandle); for (int i = 0; i < vars.fras; i++) { Date start = vars.calendar.advance(vars.settlement, vars.fraData[i].n, vars.fraData[i].units, euribor3m.businessDayConvention(), euribor3m.endOfMonth()); Date end = vars.calendar.advance(start, 3, TimeUnit.Months, euribor3m.businessDayConvention(), euribor3m.endOfMonth()); ForwardRateAgreement fra = new ForwardRateAgreement(start, end, Position.Type.Long, vars.fraData[i].rate / 100, 100.0, euribor3m, curveHandle); double expectedRate = vars.fraData[i].rate / 100, estimatedRate = fra.forwardRate().rate(); QAssert.IsTrue(Math.Abs(expectedRate - estimatedRate) < tolerance, i + 1 + " FRA failure:" + "\n estimated rate: " + estimatedRate + "\n expected rate: " + expectedRate); } }
public void testBootstrap() { // Testing Eonia-swap curve building... CommonVars vars = new CommonVars(); List <RateHelper> eoniaHelpers = new List <RateHelper>(); List <RateHelper> swap3mHelpers = new List <RateHelper>(); IborIndex euribor3m = new Euribor3M(); Eonia eonia = new Eonia(); for (int i = 0; i < depositData.Length; i++) { double rate = 0.01 * depositData[i].rate; SimpleQuote simple = new SimpleQuote(rate); Handle <Quote> quote = new Handle <Quote>(simple); Period term = new Period(depositData[i].n, depositData[i].unit); RateHelper helper = new DepositRateHelper(quote, term, depositData[i].settlementDays, euribor3m.fixingCalendar(), euribor3m.businessDayConvention(), euribor3m.endOfMonth(), euribor3m.dayCounter()); if (term <= new Period(2, TimeUnit.Days)) { eoniaHelpers.Add(helper); } if (term <= new Period(3, TimeUnit.Months)) { swap3mHelpers.Add(helper); } } for (int i = 0; i < fraData.Length; i++) { double rate = 0.01 * fraData[i].rate; SimpleQuote simple = new SimpleQuote(rate); Handle <Quote> quote = new Handle <Quote>(simple); RateHelper helper = new FraRateHelper(quote, fraData[i].nExpiry, fraData[i].nMaturity, fraData[i].settlementDays, euribor3m.fixingCalendar(), euribor3m.businessDayConvention(), euribor3m.endOfMonth(), euribor3m.dayCounter()); swap3mHelpers.Add(helper); } for (int i = 0; i < eoniaSwapData.Length; i++) { double rate = 0.01 * eoniaSwapData[i].rate; SimpleQuote simple = new SimpleQuote(rate); Handle <Quote> quote = new Handle <Quote>(simple); Period term = new Period(eoniaSwapData[i].n, eoniaSwapData[i].unit); RateHelper helper = new OISRateHelper(eoniaSwapData[i].settlementDays, term, quote, eonia); eoniaHelpers.Add(helper); } for (int i = 0; i < swapData.Length; i++) { double rate = 0.01 * swapData[i].rate; SimpleQuote simple = new SimpleQuote(rate); Handle <Quote> quote = new Handle <Quote>(simple); Period tenor = new Period(swapData[i].nIndexUnits, swapData[i].indexUnit); Period term = new Period(swapData[i].nTermUnits, swapData[i].termUnit); RateHelper helper = new SwapRateHelper(quote, term, vars.calendar, vars.fixedSwapFrequency, vars.fixedSwapConvention, vars.fixedSwapDayCount, euribor3m); if (tenor == new Period(3, TimeUnit.Months)) { swap3mHelpers.Add(helper); } } PiecewiseYieldCurve <Discount, LogLinear> eoniaTS = new PiecewiseYieldCurve <Discount, LogLinear>(vars.today, eoniaHelpers, new Actual365Fixed()); PiecewiseYieldCurve <Discount, LogLinear> swapTS = new PiecewiseYieldCurve <Discount, LogLinear>(vars.today, swap3mHelpers, new Actual365Fixed()); vars.eoniaTermStructure.linkTo(eoniaTS); // test curve consistency double tolerance = 1.0e-10; for (int i = 0; i < eoniaSwapData.Length; i++) { double expected = eoniaSwapData[i].rate; Period term = new Period(eoniaSwapData[i].n, eoniaSwapData[i].unit); OvernightIndexedSwap swap = vars.makeSwap(term, 0.0, 0.0); double?calculated = 100.0 * swap.fairRate(); if (Math.Abs(expected - calculated.Value) > tolerance) { QAssert.Fail("curve inconsistency:\n" + " swap length: " + term + "\n" + " quoted rate: " + expected + "\n" + " calculated rate: " + calculated); } } }
// setup public CommonVars() { // data calendar = new TARGET(); settlementDays = 2; today = calendar.adjust(Date.Today); Settings.setEvaluationDate(today); settlement = calendar.advance(today, settlementDays, TimeUnit.Days); fixedLegConvention = BusinessDayConvention.Unadjusted; fixedLegFrequency = Frequency.Annual; fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.European); bondSettlementDays = 3; bondDayCounter = new ActualActual(); bondConvention = BusinessDayConvention.Following; bondRedemption = 100.0; bmaFrequency = Frequency.Quarterly; bmaConvention = BusinessDayConvention.Following; bmaDayCounter = new ActualActual(); deposits = depositData.Length; fras = fraData.Length; swaps = swapData.Length; bonds = bondData.Length; bmas = bmaData.Length; // market elements rates = new List <SimpleQuote>(deposits + swaps); fraRates = new List <SimpleQuote>(fras); prices = new List <SimpleQuote>(bonds); fractions = new List <SimpleQuote>(bmas); for (int i = 0; i < deposits; i++) { rates.Add(new SimpleQuote(depositData[i].rate / 100)); } for (int i = 0; i < swaps; i++) { rates.Add(new SimpleQuote(swapData[i].rate / 100)); } for (int i = 0; i < fras; i++) { fraRates.Add(new SimpleQuote(fraData[i].rate / 100)); } for (int i = 0; i < bonds; i++) { prices.Add(new SimpleQuote(bondData[i].price)); } for (int i = 0; i < bmas; i++) { fractions.Add(new SimpleQuote(bmaData[i].rate / 100)); } // rate helpers instruments = new List <RateHelper>(deposits + swaps); fraHelpers = new List <RateHelper>(fras); bondHelpers = new List <RateHelper>(bonds); schedules = new List <Schedule>(bonds); bmaHelpers = new List <RateHelper>(bmas); IborIndex euribor6m = new Euribor6M(); for (int i = 0; i < deposits; i++) { Handle <Quote> r = new Handle <Quote>(rates[i]); instruments.Add(new DepositRateHelper(r, new Period(depositData[i].n, depositData[i].units), euribor6m.fixingDays(), calendar, euribor6m.businessDayConvention(), euribor6m.endOfMonth(), euribor6m.dayCounter())); } for (int i = 0; i < swaps; i++) { Handle <Quote> r = new Handle <Quote>(rates[i + deposits]); instruments.Add(new SwapRateHelper(r, new Period(swapData[i].n, swapData[i].units), calendar, fixedLegFrequency, fixedLegConvention, fixedLegDayCounter, euribor6m)); } Euribor3M euribor3m = new Euribor3M(); for (int i = 0; i < fras; i++) { Handle <Quote> r = new Handle <Quote>(fraRates[i]); fraHelpers.Add(new FraRateHelper(r, fraData[i].n, fraData[i].n + 3, euribor3m.fixingDays(), euribor3m.fixingCalendar(), euribor3m.businessDayConvention(), euribor3m.endOfMonth(), euribor3m.dayCounter())); } for (int i = 0; i < bonds; i++) { Handle <Quote> p = new Handle <Quote>(prices[i]); Date maturity = calendar.advance(today, bondData[i].n, bondData[i].units); Date issue = calendar.advance(maturity, -bondData[i].length, TimeUnit.Years); List <double> coupons = new List <double>() { bondData[i].coupon / 100.0 }; schedules.Add(new Schedule(issue, maturity, new Period(bondData[i].frequency), calendar, bondConvention, bondConvention, DateGeneration.Rule.Backward, false)); bondHelpers.Add(new FixedRateBondHelper(p, bondSettlementDays, bondRedemption, schedules[i], coupons, bondDayCounter, bondConvention, bondRedemption, issue)); } }
static void Main(string[] args) { try { DateTime timer = DateTime.Now; Calendar calendar = new TARGET(); Date todaysDate = new Date(10, Month.March, 2004); // must be a business day todaysDate = calendar.adjust(todaysDate); Settings.setEvaluationDate(todaysDate); IborIndex yieldIndx = new Euribor3M(); int[] tenorsSwapMkt = { 5, 10, 15, 20, 25, 30 }; // rates ignoring counterparty risk: double[] ratesSwapmkt = { .03249, .04074, .04463, .04675, .04775, .04811 }; List <RateHelper> swapHelpers = new List <RateHelper>(); for (int i = 0; i < tenorsSwapMkt.Length; i++) { swapHelpers.Add(new SwapRateHelper(new Handle <Quote>(new SimpleQuote(ratesSwapmkt[i])), new Period(tenorsSwapMkt[i], TimeUnit.Years), new TARGET(), Frequency.Quarterly, BusinessDayConvention.ModifiedFollowing, new ActualActual(ActualActual.Convention.ISDA), yieldIndx)); } YieldTermStructure swapTS = new PiecewiseYieldCurve <Discount, LogLinear>(2, new TARGET(), swapHelpers, new ActualActual(ActualActual.Convention.ISDA)); swapTS.enableExtrapolation(); IPricingEngine riskFreeEngine = new DiscountingSwapEngine(new Handle <YieldTermStructure>(swapTS)); List <Handle <DefaultProbabilityTermStructure> > defaultIntensityTS = new List <Handle <DefaultProbabilityTermStructure> >(); int[] defaultTenors = { 0, 12, 36, 60, 84, 120, 180, 240, 300, 360 }; // months // Three risk levels: double[] intensitiesLow = { 0.0036, 0.0036, 0.0065, 0.0099, 0.0111, 0.0177, 0.0177, 0.0177, 0.0177, 0.0177, 0.0177 }; double[] intensitiesMedium = { 0.0202, 0.0202, 0.0231, 0.0266, 0.0278, 0.0349, 0.0349, 0.0349, 0.0349, 0.0349, 0.0349 }; double[] intensitiesHigh = { 0.0534, 0.0534, 0.0564, 0.06, 0.0614, 0.0696, 0.0696, 0.0696, 0.0696, 0.0696, 0.0696 }; // Recovery rates: double ctptyRRLow = 0.4, ctptyRRMedium = 0.35, ctptyRRHigh = 0.3; List <Date> defaultTSDates = new List <Date>(); List <double> intesitiesVLow = new List <double>(), intesitiesVMedium = new List <double>(), intesitiesVHigh = new List <double>(); for (int i = 0; i < defaultTenors.Length; i++) { defaultTSDates.Add(new TARGET().advance(todaysDate, new Period(defaultTenors[i], TimeUnit.Months))); intesitiesVLow.Add(intensitiesLow[i]); intesitiesVMedium.Add(intensitiesMedium[i]); intesitiesVHigh.Add(intensitiesHigh[i]); } defaultIntensityTS.Add(new Handle <DefaultProbabilityTermStructure>( new InterpolatedHazardRateCurve <BackwardFlat>( defaultTSDates, intesitiesVLow, new Actual360(), new TARGET()))); defaultIntensityTS.Add(new Handle <DefaultProbabilityTermStructure>( new InterpolatedHazardRateCurve <BackwardFlat>( defaultTSDates, intesitiesVMedium, new Actual360(), new TARGET()))); defaultIntensityTS.Add(new Handle <DefaultProbabilityTermStructure>( new InterpolatedHazardRateCurve <BackwardFlat>( defaultTSDates, intesitiesVHigh, new Actual360(), new TARGET()))); double blackVol = 0.15; IPricingEngine ctptySwapCvaLow = new CounterpartyAdjSwapEngine(new Handle <YieldTermStructure>(swapTS), blackVol, defaultIntensityTS[0], ctptyRRLow); IPricingEngine ctptySwapCvaMedium = new CounterpartyAdjSwapEngine(new Handle <YieldTermStructure>(swapTS), blackVol, defaultIntensityTS[1], ctptyRRMedium); IPricingEngine ctptySwapCvaHigh = new CounterpartyAdjSwapEngine(new Handle <YieldTermStructure>(swapTS), blackVol, defaultIntensityTS[2], ctptyRRHigh); defaultIntensityTS[0].link.enableExtrapolation(); defaultIntensityTS[1].link.enableExtrapolation(); defaultIntensityTS[2].link.enableExtrapolation(); // SWAP RISKY REPRICE---------------------------------------------- // fixed leg Frequency fixedLegFrequency = Frequency.Quarterly; BusinessDayConvention fixedLegConvention = BusinessDayConvention.ModifiedFollowing; DayCounter fixedLegDayCounter = new ActualActual(ActualActual.Convention.ISDA); DayCounter floatingLegDayCounter = new ActualActual(ActualActual.Convention.ISDA); VanillaSwap.Type swapType = //VanillaSwap::Receiver ; VanillaSwap.Type.Payer; IborIndex yieldIndxS = new Euribor3M(new Handle <YieldTermStructure>(swapTS)); List <VanillaSwap> riskySwaps = new List <VanillaSwap>(); for (int i = 0; i < tenorsSwapMkt.Length; i++) { riskySwaps.Add(new MakeVanillaSwap(new Period(tenorsSwapMkt[i], TimeUnit.Years), yieldIndxS, ratesSwapmkt[i], new Period(0, TimeUnit.Days)) .withSettlementDays(2) .withFixedLegDayCount(fixedLegDayCounter) .withFixedLegTenor(new Period(fixedLegFrequency)) .withFixedLegConvention(fixedLegConvention) .withFixedLegTerminationDateConvention(fixedLegConvention) .withFixedLegCalendar(calendar) .withFloatingLegCalendar(calendar) .withNominal(100.0) .withType(swapType).value()); } Console.WriteLine("-- Correction in the contract fix rate in bp --"); /* The paper plots correction to be substracted, here is printed * with its sign */ for (int i = 0; i < riskySwaps.Count; i++) { riskySwaps[i].setPricingEngine(riskFreeEngine); // should recover the input here: double nonRiskyFair = riskySwaps[i].fairRate(); Console.Write((tenorsSwapMkt[i]).ToString("0").PadLeft(6)); Console.Write(" | " + nonRiskyFair.ToString("P3").PadLeft(6)); // Low Risk: riskySwaps[i].setPricingEngine(ctptySwapCvaLow); Console.Write(" | " + (10000.0 * (riskySwaps[i].fairRate() - nonRiskyFair)).ToString("#0.00").PadLeft(6)); //cout << " | " << setw(6) << riskySwaps[i].NPV() ; // Medium Risk: riskySwaps[i].setPricingEngine(ctptySwapCvaMedium); Console.Write(" | " + (10000.0 * (riskySwaps[i].fairRate() - nonRiskyFair)).ToString("#0.00").PadLeft(6)); //cout << " | " << setw(6) << riskySwaps[i].NPV() ; riskySwaps[i].setPricingEngine(ctptySwapCvaHigh); Console.Write(" | " + (10000.0 * (riskySwaps[i].fairRate() - nonRiskyFair)).ToString("#0.00").PadLeft(6)); //cout << " | " << setw(6) << riskySwaps[i].NPV() ; Console.WriteLine(); } Console.WriteLine(); Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); Console.WriteLine(); Console.Write("Press any key to continue ..."); Console.ReadKey(); } catch (Exception e) { Console.Write(e.Message); Console.Write("Press any key to continue ..."); Console.ReadKey(); } }
static void Main() { DateTime timer = DateTime.Now; /********************* *** MARKET DATA *** *********************/ RelinkableHandle <YieldTermStructure> euriborTermStructure = new RelinkableHandle <YieldTermStructure>(); IborIndex euribor3m = new Euribor3M(euriborTermStructure); Date todaysDate = new Date(23, Month.May, 2006); Settings.setEvaluationDate(todaysDate); Calendar calendar = euribor3m.fixingCalendar(); int fixingDays = euribor3m.fixingDays(); Date settlementDate = calendar.advance(todaysDate, fixingDays, TimeUnit.Days); Console.WriteLine("Today: " + todaysDate.DayOfWeek + ", " + todaysDate); Console.WriteLine("Settlement date: " + settlementDate.DayOfWeek + ", " + settlementDate); // 3 month term FRA quotes (index refers to monthsToStart) double[] threeMonthFraQuote = new double[10]; threeMonthFraQuote[1] = 0.030; threeMonthFraQuote[2] = 0.031; threeMonthFraQuote[3] = 0.032; threeMonthFraQuote[6] = 0.033; threeMonthFraQuote[9] = 0.034; /******************** *** QUOTES *** ********************/ // SimpleQuote stores a value which can be manually changed; // other Quote subclasses could read the value from a database // or some kind of data feed. // FRAs SimpleQuote fra1x4Rate = new SimpleQuote(threeMonthFraQuote[1]); SimpleQuote fra2x5Rate = new SimpleQuote(threeMonthFraQuote[2]); SimpleQuote fra3x6Rate = new SimpleQuote(threeMonthFraQuote[3]); SimpleQuote fra6x9Rate = new SimpleQuote(threeMonthFraQuote[6]); SimpleQuote fra9x12Rate = new SimpleQuote(threeMonthFraQuote[9]); RelinkableHandle <Quote> h1x4 = new RelinkableHandle <Quote>(); h1x4.linkTo(fra1x4Rate); RelinkableHandle <Quote> h2x5 = new RelinkableHandle <Quote>(); h2x5.linkTo(fra2x5Rate); RelinkableHandle <Quote> h3x6 = new RelinkableHandle <Quote>(); h3x6.linkTo(fra3x6Rate); RelinkableHandle <Quote> h6x9 = new RelinkableHandle <Quote>(); h6x9.linkTo(fra6x9Rate); RelinkableHandle <Quote> h9x12 = new RelinkableHandle <Quote>(); h9x12.linkTo(fra9x12Rate); /********************* *** RATE HELPERS *** *********************/ // RateHelpers are built from the above quotes together with // other instrument dependant infos. Quotes are passed in // relinkable handles which could be relinked to some other // data source later. DayCounter fraDayCounter = euribor3m.dayCounter(); BusinessDayConvention convention = euribor3m.businessDayConvention(); bool endOfMonth = euribor3m.endOfMonth(); RateHelper fra1x4 = new FraRateHelper(h1x4, 1, 4, fixingDays, calendar, convention, endOfMonth, fraDayCounter); RateHelper fra2x5 = new FraRateHelper(h2x5, 2, 5, fixingDays, calendar, convention, endOfMonth, fraDayCounter); RateHelper fra3x6 = new FraRateHelper(h3x6, 3, 6, fixingDays, calendar, convention, endOfMonth, fraDayCounter); RateHelper fra6x9 = new FraRateHelper(h6x9, 6, 9, fixingDays, calendar, convention, endOfMonth, fraDayCounter); RateHelper fra9x12 = new FraRateHelper(h9x12, 9, 12, fixingDays, calendar, convention, endOfMonth, fraDayCounter); /********************* ** CURVE BUILDING ** *********************/ // Any DayCounter would be fine. // ActualActual::ISDA ensures that 30 years is 30.0 DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA); double tolerance = 1.0e-15; // A FRA curve List <RateHelper> fraInstruments = new List <RateHelper>(); fraInstruments.Add(fra1x4); fraInstruments.Add(fra2x5); fraInstruments.Add(fra3x6); fraInstruments.Add(fra6x9); fraInstruments.Add(fra9x12); YieldTermStructure fraTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>( settlementDate, fraInstruments, termStructureDayCounter, new List <Handle <Quote> >(), new List <Date>(), tolerance); // Term structures used for pricing/discounting RelinkableHandle <YieldTermStructure> discountingTermStructure = new RelinkableHandle <YieldTermStructure>(); discountingTermStructure.linkTo(fraTermStructure); /*********************** *** construct FRA's *** ***********************/ Calendar fraCalendar = euribor3m.fixingCalendar(); BusinessDayConvention fraBusinessDayConvention = euribor3m.businessDayConvention(); Position.Type fraFwdType = Position.Type.Long; double fraNotional = 100.0; const int FraTermMonths = 3; int[] monthsToStart = new [] { 1, 2, 3, 6, 9 }; euriborTermStructure.linkTo(fraTermStructure); Console.WriteLine("\nTest FRA construction, NPV calculation, and FRA purchase\n"); int i; for (i = 0; i < monthsToStart.Length; i++) { Date fraValueDate = fraCalendar.advance( settlementDate, monthsToStart[i], TimeUnit.Months, fraBusinessDayConvention); Date fraMaturityDate = fraCalendar.advance( fraValueDate, FraTermMonths, TimeUnit.Months, fraBusinessDayConvention); double fraStrikeRate = threeMonthFraQuote[monthsToStart[i]]; ForwardRateAgreement myFRA = new ForwardRateAgreement(fraValueDate, fraMaturityDate, fraFwdType, fraStrikeRate, fraNotional, euribor3m, discountingTermStructure); Console.WriteLine("3m Term FRA, Months to Start: " + monthsToStart[i]); Console.WriteLine("strike FRA rate: {0:0.00%}", fraStrikeRate); Console.WriteLine("FRA 3m forward rate: {0:0.00%}", myFRA.forwardRate()); Console.WriteLine("FRA market quote: {0:0.00%}", threeMonthFraQuote[monthsToStart[i]]); Console.WriteLine("FRA spot value: " + myFRA.spotValue()); Console.WriteLine("FRA forward value: " + myFRA.forwardValue()); Console.WriteLine("FRA implied Yield: {0:0.00%}", myFRA.impliedYield(myFRA.spotValue(), myFRA.forwardValue(), settlementDate, Compounding.Simple, fraDayCounter)); Console.WriteLine("market Zero Rate: {0:0.00%}", discountingTermStructure.link.zeroRate(fraMaturityDate, fraDayCounter, Compounding.Simple)); Console.WriteLine("FRA NPV [should be zero]: {0}\n", myFRA.NPV()); } Console.WriteLine("\n"); Console.WriteLine("Now take a 100 basis-point upward shift in FRA quotes and examine NPV\n"); const double BpsShift = 0.01; threeMonthFraQuote[1] = 0.030 + BpsShift; threeMonthFraQuote[2] = 0.031 + BpsShift; threeMonthFraQuote[3] = 0.032 + BpsShift; threeMonthFraQuote[6] = 0.033 + BpsShift; threeMonthFraQuote[9] = 0.034 + BpsShift; fra1x4Rate.setValue(threeMonthFraQuote[1]); fra2x5Rate.setValue(threeMonthFraQuote[2]); fra3x6Rate.setValue(threeMonthFraQuote[3]); fra6x9Rate.setValue(threeMonthFraQuote[6]); fra9x12Rate.setValue(threeMonthFraQuote[9]); for (i = 0; i < monthsToStart.Length; i++) { Date fraValueDate = fraCalendar.advance( settlementDate, monthsToStart[i], TimeUnit.Months, fraBusinessDayConvention); Date fraMaturityDate = fraCalendar.advance( fraValueDate, FraTermMonths, TimeUnit.Months, fraBusinessDayConvention); double fraStrikeRate = threeMonthFraQuote[monthsToStart[i]] - BpsShift; ForwardRateAgreement myFRA = new ForwardRateAgreement(fraValueDate, fraMaturityDate, fraFwdType, fraStrikeRate, fraNotional, euribor3m, discountingTermStructure); Console.WriteLine("3m Term FRA, 100 notional, Months to Start: " + monthsToStart[i]); Console.WriteLine("strike FRA rate: {0:0.00%}", fraStrikeRate); Console.WriteLine("FRA 3m forward rate: {0:0.00%}", myFRA.forwardRate()); Console.WriteLine("FRA market quote: {0:0.00%}", threeMonthFraQuote[monthsToStart[i]]); Console.WriteLine("FRA spot value: " + myFRA.spotValue()); Console.WriteLine("FRA forward value: " + myFRA.forwardValue()); Console.WriteLine("FRA implied Yield: {0:0.00%}", myFRA.impliedYield(myFRA.spotValue(), myFRA.forwardValue(), settlementDate, Compounding.Simple, fraDayCounter)); Console.WriteLine("market Zero Rate: {0:0.00%}", discountingTermStructure.link.zeroRate(fraMaturityDate, fraDayCounter, Compounding.Simple)); Console.WriteLine("FRA NPV [should be positive]: {0}\n", myFRA.NPV()); } Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); Console.WriteLine(); Console.Write("Press any key to continue ..."); Console.ReadKey(); }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(Euribor3M obj) { return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr; }
static void Main(string[] args) { double nominal = 575000000; Date _marketDate; Date _settlementDate; Dictionary <string, double> _depositRates; Dictionary <string, double> _swapRates; List <RateHelper> _rateHelpers; Calendar _calendar = new TARGET(); int _fixingDays = 2; _marketDate = new Date(new DateTime(2015, 12, 17)); Settings.setEvaluationDate(_marketDate); _depositRates = new Dictionary <string, double>(); _depositRates.Add("1M", 0.0045); _depositRates.Add("3M", 0.0070); _depositRates.Add("6M", 0.0090); _swapRates = new Dictionary <string, double>(); _swapRates.Add("1Y", 0.0080); _swapRates.Add("2Y", 0.0109); _swapRates.Add("3Y", 0.0134); _swapRates.Add("4Y", 0.0153); _swapRates.Add("5Y", 0.0169); _swapRates.Add("7Y", 0.0193); _swapRates.Add("10Y", 0.0218); _swapRates.Add("30Y", 0.0262); _rateHelpers = new List <RateHelper>(); foreach (var v in _depositRates) { SimpleQuote sq = new SimpleQuote(v.Value); _rateHelpers.Add(new DepositRateHelper(new Handle <Quote>(sq), new Period(v.Key), _fixingDays, _calendar, BusinessDayConvention.ModifiedFollowing, true, new Actual360())); } foreach (var v in _swapRates) { SimpleQuote sq = new SimpleQuote(v.Value); _rateHelpers.Add(new SwapRateHelper(new Handle <Quote>(sq), new Period(v.Key), _calendar, Frequency.Semiannual, BusinessDayConvention.Unadjusted, new Thirty360(Thirty360.Thirty360Convention.USA), new Euribor3M())); } _marketDate = _calendar.adjust(_marketDate); _settlementDate = _calendar.advance(_marketDate, _fixingDays, TimeUnit.Days); YieldTermStructure yieldTermStructure = new PiecewiseYieldCurve <Discount, LogLinear>( _settlementDate, _rateHelpers, new ActualActual(ActualActual.Convention.ISDA)); RelinkableHandle <YieldTermStructure> yieldTermStructureHandle = new RelinkableHandle <YieldTermStructure>(); Frequency fixedLegFrequency = Frequency.Semiannual; BusinessDayConvention fixedLegConvention = BusinessDayConvention.ModifiedFollowing; DayCounter fixedLegDayCounter = new Thirty360(Thirty360.Thirty360Convention.USA); double fixedRate = 0.0144; Frequency floatLegFrequency = Frequency.Quarterly; BusinessDayConvention floatLegConvention = BusinessDayConvention.ModifiedFollowing; DayCounter floatLegDayCounter = new Actual360(); IborIndex iborIndex = new Euribor3M(yieldTermStructureHandle); iborIndex.addFixing(new Date(18, Month.Aug, 2015), 0.0033285); iborIndex.addFixing(new Date(18, Month.Nov, 2015), 0.0036960); double floatSpread = 0.0; VanillaSwap.Type swapType = VanillaSwap.Type.Receiver; Date maturity = new Date(20, Month.Nov, 2018); Date effective = new Date(20, Month.Nov, 2013); Schedule fixedSchedule = new Schedule(effective, maturity, new Period(fixedLegFrequency), _calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Rule.Forward, false); Schedule floatSchedule = new Schedule(effective, maturity, new Period(floatLegFrequency), _calendar, floatLegConvention, floatLegConvention, DateGeneration.Rule.Forward, false); VanillaSwap vanillaSwap = new VanillaSwap(swapType, nominal, fixedSchedule, fixedRate, fixedLegDayCounter, floatSchedule, iborIndex, floatSpread, floatLegDayCounter); InterestRate interestRate = new InterestRate(fixedRate, fixedLegDayCounter, Compounding.Simple, fixedLegFrequency); List <InterestRate> coupons = new List <InterestRate>(); for (int i = 0; i < fixedSchedule.Count; i++) { coupons.Add(interestRate); } FixedRateBond fixedBond = new FixedRateBond(_fixingDays, nominal, fixedSchedule, coupons, BusinessDayConvention.ModifiedFollowing); FloatingRateBond floatBond = new FloatingRateBond(_fixingDays, nominal, floatSchedule, iborIndex, floatLegDayCounter); IPricingEngine bondPricingEngine = new DiscountingBondEngine(yieldTermStructureHandle); fixedBond.setPricingEngine(bondPricingEngine); floatBond.setPricingEngine(bondPricingEngine); IPricingEngine swapPricingEngine = new DiscountingSwapEngine(yieldTermStructureHandle); vanillaSwap.setPricingEngine(swapPricingEngine); yieldTermStructureHandle.linkTo(yieldTermStructure); double swapNPV = vanillaSwap.NPV(); double swapFixedNPV = vanillaSwap.fixedLegNPV(); double swapFloatNPV = vanillaSwap.floatingLegNPV(); double bondFixedNPV = fixedBond.NPV(); double bondFloatNPV = floatBond.NPV(); int w = (swapType == VanillaSwap.Type.Receiver ? 1 : -1); double asBondsMarketValue = w * (bondFixedNPV - bondFloatNPV); double asBondsMarketValueNoAcc = w * (fixedBond.cleanPrice() - floatBond.cleanPrice()) / 100.0 * nominal; double asBondsAccruedInterest = asBondsMarketValue - asBondsMarketValueNoAcc; Console.WriteLine("Vanilla Swap Maket Value : {0:N}", swapNPV); Console.WriteLine("As Bonds Market Value : {0:N}", asBondsMarketValue); Console.WriteLine("As Bonds Market Value (no acc): {0:N}", asBondsMarketValueNoAcc); Console.WriteLine("As Bonds Accrued Interest : {0:N}", asBondsAccruedInterest); Date rollDate = new Date(1, Month.Nov, 2015); double bondFixedCash = 0; foreach (CashFlow cf in fixedBond.cashflows()) { if (cf.date() > rollDate & cf.date() <= _marketDate) { bondFixedCash += cf.amount(); } } double bondFloatCash = 0; foreach (CashFlow cf in floatBond.cashflows()) { if (cf.date() > rollDate & cf.date() <= _marketDate) { bondFloatCash += cf.amount(); } } double asBondsCash = w * (bondFixedCash - bondFloatCash); Console.WriteLine("As Bonds Settled Cash : {0:N}", asBondsCash); }