public FuturesRateHelper(double price, Date iborStartDate, IborIndex i, double convAdj = 0.0, Futures.Type type = Futures.Type.IMM) : base(price) { convAdj_ = new Handle <Quote>(new SimpleQuote(convAdj)); switch (type) { case Futures.Type.IMM: Utils.QL_REQUIRE(IMM.isIMMdate(iborStartDate, false), () => iborStartDate + " is not a valid IMM date"); break; case Futures.Type.ASX: Utils.QL_REQUIRE(ASX.isASXdate(iborStartDate, false), () => iborStartDate + " is not a valid ASX date"); break; default: Utils.QL_FAIL("unknown futures type (" + type + ")"); break; } earliestDate_ = iborStartDate; Calendar cal = i.fixingCalendar(); maturityDate_ = cal.advance(iborStartDate, i.tenor(), i.businessDayConvention()); yearFraction_ = i.dayCounter().yearFraction(earliestDate_, maturityDate_); pillarDate_ = latestDate_ = latestRelevantDate_ = maturityDate_; }
public CommonVars() { settlementDays = 2; nominal = 1000000.0; fixedConvention = BusinessDayConvention.Unadjusted; fixedFrequency = Frequency.Annual; fixedDayCount = new Thirty360(); index = new Euribor6M(termStructure); floatingConvention = index.businessDayConvention(); floatingTenor = index.tenor(); calendar = index.fixingCalendar(); today = calendar.adjust(Date.Today); Settings.setEvaluationDate(today); settlement = calendar.advance(today, settlementDays, TimeUnit.Days); termStructure.linkTo(Utilities.flatRate(settlement, 0.05, new Actual365Fixed())); }
public MakeVanillaSwap(Period swapTenor, IborIndex index, double?fixedRate = null, Period forwardStart = null) { swapTenor_ = swapTenor; iborIndex_ = index; fixedRate_ = fixedRate; forwardStart_ = forwardStart ?? new Period(0, TimeUnit.Days); settlementDays_ = iborIndex_.fixingDays(); fixedCalendar_ = floatCalendar_ = index.fixingCalendar(); type_ = VanillaSwap.Type.Payer; nominal_ = 1.0; floatTenor_ = index.tenor(); fixedConvention_ = fixedTerminationDateConvention_ = BusinessDayConvention.ModifiedFollowing; floatConvention_ = floatTerminationDateConvention_ = index.businessDayConvention(); fixedRule_ = floatRule_ = DateGeneration.Rule.Backward; fixedEndOfMonth_ = floatEndOfMonth_ = false; fixedFirstDate_ = fixedNextToLastDate_ = floatFirstDate_ = floatNextToLastDate_ = null; floatSpread_ = 0.0; floatDayCount_ = index.dayCounter(); }
public MakeBasisSwap(Period swapTenor, IborIndex index1, IborIndex index2, Period forwardStart) { swapTenor_ = swapTenor; iborIndex1_ = index1; iborIndex2_ = index2; forwardStart_ = forwardStart; effectiveDate_ = null; float1Calendar_ = float2Calendar_ = index1.fixingCalendar(); type_ = BasisSwap.Type.Payer; nominal_ = 1.0; float1Tenor_ = index1.tenor(); float2Tenor_ = index2.tenor(); float1Convention_ = float1TerminationDateConvention_ = index1.businessDayConvention(); float2Convention_ = float2TerminationDateConvention_ = index2.businessDayConvention(); float1Rule_ = float2Rule_ = DateGeneration.Rule.Backward; float1EndOfMonth_ = float2EndOfMonth_ = false; float1FirstDate_ = float1NextToLastDate_ = float2FirstDate_ = float2NextToLastDate_ = null; float1Spread_ = float2Spread_ = 0.0; float1DayCount_ = index1.dayCounter(); float2DayCount_ = index2.dayCounter(); engine_ = new DiscountingBasisSwapEngine(index1.forwardingTermStructure(), index2.forwardingTermStructure()); }
public void testSwaptionPricing() { // Testing forward swap and swaption pricing const int size = 10; const int steps = 8 * size; #if QL_USE_INDEXED_COUPON const double tolerance = 1e-6; #else const double tolerance = 1e-12; #endif List <Date> dates = new List <Date>(); List <double> rates = new List <double>(); dates.Add(new Date(4, 9, 2005)); dates.Add(new Date(4, 9, 2011)); rates.Add(0.04); rates.Add(0.08); IborIndex index = makeIndex(dates, rates); LiborForwardModelProcess process = new LiborForwardModelProcess(size, index); LmCorrelationModel corrModel = new LmExponentialCorrelationModel(size, 0.5); LmVolatilityModel volaModel = new LmLinearExponentialVolatilityModel(process.fixingTimes(), 0.291, 1.483, 0.116, 0.00001); // set-up pricing engine process.setCovarParam((LfmCovarianceParameterization) new LfmCovarianceProxy(volaModel, corrModel)); // set-up a small Monte-Carlo simulation to price swations List <double> tmp = process.fixingTimes(); TimeGrid grid = new TimeGrid(tmp, tmp.Count, steps); List <int> location = new List <int>(); for (int i = 0; i < tmp.Count; ++i) { location.Add(grid.index(tmp[i])); } ulong seed = 42; const int nrTrails = 5000; LowDiscrepancy.icInstance = new InverseCumulativeNormal(); IRNG rsg = (InverseCumulativeRsg <RandomSequenceGenerator <MersenneTwisterUniformRng> , InverseCumulativeNormal>) new PseudoRandom().make_sequence_generator(process.factors() * (grid.size() - 1), seed); MultiPathGenerator <IRNG> generator = new MultiPathGenerator <IRNG>(process, grid, rsg, false); LiborForwardModel liborModel = new LiborForwardModel(process, volaModel, corrModel); Calendar calendar = index.fixingCalendar(); DayCounter dayCounter = index.forwardingTermStructure().link.dayCounter(); BusinessDayConvention convention = index.businessDayConvention(); Date settlement = index.forwardingTermStructure().link.referenceDate(); SwaptionVolatilityMatrix m = liborModel.getSwaptionVolatilityMatrix(); for (int i = 1; i < size; ++i) { for (int j = 1; j <= size - i; ++j) { Date fwdStart = settlement + new Period(6 * i, TimeUnit.Months); Date fwdMaturity = fwdStart + new Period(6 * j, TimeUnit.Months); Schedule schedule = new Schedule(fwdStart, fwdMaturity, index.tenor(), calendar, convention, convention, DateGeneration.Rule.Forward, false); double swapRate = 0.0404; VanillaSwap forwardSwap = new VanillaSwap(VanillaSwap.Type.Receiver, 1.0, schedule, swapRate, dayCounter, schedule, index, 0.0, index.dayCounter()); forwardSwap.setPricingEngine(new DiscountingSwapEngine(index.forwardingTermStructure())); // check forward pricing first double expected = forwardSwap.fairRate(); double calculated = liborModel.S_0(i - 1, i + j - 1); if (Math.Abs(expected - calculated) > tolerance) { QAssert.Fail("Failed to reproduce fair forward swap rate" + "\n calculated: " + calculated + "\n expected: " + expected); } swapRate = forwardSwap.fairRate(); forwardSwap = new VanillaSwap(VanillaSwap.Type.Receiver, 1.0, schedule, swapRate, dayCounter, schedule, index, 0.0, index.dayCounter()); forwardSwap.setPricingEngine(new DiscountingSwapEngine(index.forwardingTermStructure())); if (i == j && i <= size / 2) { IPricingEngine engine = new LfmSwaptionEngine(liborModel, index.forwardingTermStructure()); Exercise exercise = new EuropeanExercise(process.fixingDates()[i]); Swaption swaption = new Swaption(forwardSwap, exercise); swaption.setPricingEngine(engine); GeneralStatistics stat = new GeneralStatistics(); for (int n = 0; n < nrTrails; ++n) { Sample <IPath> path = (n % 2 != 0) ? generator.antithetic() : generator.next(); MultiPath value = path.value as MultiPath; Utils.QL_REQUIRE(value != null, () => "Invalid Path"); //Sample<MultiPath> path = generator.next(); List <double> rates_ = new InitializedList <double>(size); for (int k = 0; k < process.size(); ++k) { rates_[k] = value[k][location[i]]; } List <double> dis = process.discountBond(rates_); double npv = 0.0; for (int k = i; k < i + j; ++k) { npv += (swapRate - rates_[k]) * (process.accrualEndTimes()[k] - process.accrualStartTimes()[k]) * dis[k]; } stat.add(Math.Max(npv, 0.0)); } if (Math.Abs(swaption.NPV() - stat.mean()) > stat.errorEstimate() * 2.35) { QAssert.Fail("Failed to reproduce swaption npv" + "\n calculated: " + stat.mean() + "\n expected: " + swaption.NPV()); } } } } }
public void testCalibration() { // Testing calibration of a Libor forward model const int size = 14; const double tolerance = 8e-3; double[] capVols = { 0.145708, 0.158465, 0.166248, 0.168672, 0.169007, 0.167956, 0.166261, 0.164239, 0.162082, 0.159923, 0.157781, 0.155745, 0.153776, 0.151950, 0.150189, 0.148582, 0.147034, 0.145598, 0.144248 }; double[] swaptionVols = { 0.170595, 0.166844, 0.158306, 0.147444, 0.136930, 0.126833, 0.118135, 0.175963, 0.166359, 0.155203, 0.143712, 0.132769, 0.122947, 0.114310, 0.174455, 0.162265, 0.150539, 0.138734, 0.128215, 0.118470, 0.110540, 0.169780, 0.156860, 0.144821, 0.133537, 0.123167, 0.114363, 0.106500, 0.164521, 0.151223, 0.139670, 0.128632, 0.119123, 0.110330, 0.103114, 0.158956, 0.146036, 0.134555, 0.124393, 0.115038, 0.106996, 0.100064 }; IborIndex index = makeIndex(); LiborForwardModelProcess process = new LiborForwardModelProcess(size, index); Handle <YieldTermStructure> termStructure = index.forwardingTermStructure(); // set-up the model LmVolatilityModel volaModel = new LmExtLinearExponentialVolModel(process.fixingTimes(), 0.5, 0.6, 0.1, 0.1); LmCorrelationModel corrModel = new LmLinearExponentialCorrelationModel(size, 0.5, 0.8); LiborForwardModel model = new LiborForwardModel(process, volaModel, corrModel); int swapVolIndex = 0; DayCounter dayCounter = index.forwardingTermStructure().link.dayCounter(); // set-up calibration helper List <CalibrationHelper> calibrationHelper = new List <CalibrationHelper>(); int i; for (i = 2; i < size; ++i) { Period maturity = i * index.tenor(); Handle <Quote> capVol = new Handle <Quote>(new SimpleQuote(capVols[i - 2])); CalibrationHelper caphelper = new CapHelper(maturity, capVol, index, Frequency.Annual, index.dayCounter(), true, termStructure, CalibrationHelper.CalibrationErrorType.ImpliedVolError); caphelper.setPricingEngine(new AnalyticCapFloorEngine(model, termStructure)); calibrationHelper.Add(caphelper); if (i <= size / 2) { // add a few swaptions to test swaption calibration as well for (int j = 1; j <= size / 2; ++j) { Period len = j * index.tenor(); Handle <Quote> swaptionVol = new Handle <Quote>( new SimpleQuote(swaptionVols[swapVolIndex++])); CalibrationHelper swaptionHelper = new SwaptionHelper(maturity, len, swaptionVol, index, index.tenor(), dayCounter, index.dayCounter(), termStructure, CalibrationHelper.CalibrationErrorType.ImpliedVolError); swaptionHelper.setPricingEngine(new LfmSwaptionEngine(model, termStructure)); calibrationHelper.Add(swaptionHelper); } } } LevenbergMarquardt om = new LevenbergMarquardt(1e-6, 1e-6, 1e-6); //ConjugateGradient gc = new ConjugateGradient(); model.calibrate(calibrationHelper, om, new EndCriteria(2000, 100, 1e-6, 1e-6, 1e-6), new Constraint(), new List <double>()); // measure the calibration error double calculated = 0.0; for (i = 0; i < calibrationHelper.Count; ++i) { double diff = calibrationHelper[i].calibrationError(); calculated += diff * diff; } if (Math.Sqrt(calculated) > tolerance) { QAssert.Fail("Failed to calibrate libor forward model" + "\n calculated diff: " + Math.Sqrt(calculated) + "\n expected : smaller than " + tolerance); } }
public static object eqInstIRBasisSwap( [ExcelArgument(Description = "trade id ")] string tradeid, [ExcelArgument(Description = "payer/receiver (1/0) ")] bool ispayer, [ExcelArgument(Description = "notional ")] double notional, [ExcelArgument(Description = "start date ")] DateTime startdate, [ExcelArgument(Description = " (String) forward start month, e.g. 7D, 3M, 7Y ")] string Tenor, [ExcelArgument(Description = "id of base index ")] string baseindexid, [ExcelArgument(Description = "id of basis index ")] string basisindexid, [ExcelArgument(Description = "basis leg spread ")] double spread, [ExcelArgument(Description = "id of discount curve ")] string discountId, [ExcelArgument(Description = "trigger ")] object trigger) { if (ExcelUtil.CallFromWizard()) { return(""); } string callerAddress = ""; callerAddress = ExcelUtil.getActiveCellAddress(); try { Xl.Range rng = ExcelUtil.getActiveCellRange(); // by default // endOfMonth_(1*Months<=swapTenor && swapTenor<=2*Years ? true : false), bool end_of_month = true; EliteQuant.DayCounter fixeddc = new EliteQuant.Actual360(); if (!baseindexid.Contains('@')) { baseindexid = "IDX@" + baseindexid; } IborIndex baseidx = OHRepository.Instance.getObject <IborIndex>(baseindexid); if (!basisindexid.Contains('@')) { basisindexid = "IDX@" + basisindexid; } IborIndex basisidx = OHRepository.Instance.getObject <IborIndex>(basisindexid); if (!discountId.Contains('@')) { discountId = "CRV@" + discountId; } YieldTermStructure discountcurve = OHRepository.Instance.getObject <YieldTermStructure>(discountId); YieldTermStructureHandle dch = new YieldTermStructureHandle(discountcurve); EliteQuant.Period tenor_ = EliteQuant.EQConverter.ConvertObject <EliteQuant.Period>(Tenor); EliteQuant.Date sdate = EliteQuant.EQConverter.ConvertObject <EliteQuant.Date>(startdate); EliteQuant.Date fdate = baseidx.fixingDate(sdate); EliteQuant.Date tdate = baseidx.fixingCalendar().advance(sdate, tenor_); // fixed leg 1 yr. Forward? Schedule basesch = new Schedule(sdate, tdate, baseidx.tenor(), baseidx.fixingCalendar(), baseidx.businessDayConvention(), baseidx.businessDayConvention(), DateGeneration.Rule.Backward, end_of_month); Schedule basissch = new Schedule(sdate, tdate, basisidx.tenor(), basisidx.fixingCalendar(), basisidx.businessDayConvention(), basisidx.businessDayConvention(), DateGeneration.Rule.Backward, end_of_month); //GenericSwap swap = new GenericSwap((ispayer ? _GenericSwap.Type.Payer : _GenericSwap.Type.Receiver), notional, // basesch, baseidx, baseidx.dayCounter(), basissch, basisidx, basisidx.dayCounter(), spread); //DiscountingSwapEngine engine = new DiscountingSwapEngine(dch); //swap.setPricingEngine(engine); //Date refDate = discountcurve.referenceDate(); // Store the futures and return its id //string id = "SWP@" + tradeid; //OHRepository.Instance.storeObject(id, swap, callerAddress); //id += "#" + (String)DateTime.Now.ToString(@"HH:mm:ss"); //return id; return(0); } catch (Exception e) { ExcelUtil.logError(callerAddress, System.Reflection.MethodInfo.GetCurrentMethod().Name.ToString(), e.Message); return("#EQ_ERR!"); } }
public static object eqInstIRVanillaSwap( [ExcelArgument(Description = "trade id ")] string tradeid, [ExcelArgument(Description = "payer/receiver (1/0) ")] bool ispayer, [ExcelArgument(Description = "notional ")] double notional, [ExcelArgument(Description = "fixed rate ")] double fixedRate, [ExcelArgument(Description = "start date ")] DateTime startdate, [ExcelArgument(Description = " (String) forward start month, e.g. 7D, 3M, 7Y ")] string Tenor, [ExcelArgument(Description = "id of libor index ")] string indexid, [ExcelArgument(Description = "floating leg spread ")] double spread, [ExcelArgument(Description = "id of discount curve ")] string discountId, [ExcelArgument(Description = "trigger ")] object trigger) { if (ExcelUtil.CallFromWizard()) { return(""); } string callerAddress = ""; callerAddress = ExcelUtil.getActiveCellAddress(); try { Xl.Range rng = ExcelUtil.getActiveCellRange(); // by default bool end_of_month = true; EliteQuant.DayCounter fixeddc = new EliteQuant.Thirty360(); EliteQuant.Period tenor_ = EliteQuant.EQConverter.ConvertObject <EliteQuant.Period>(Tenor); if (!indexid.Contains('@')) { indexid = "IDX@" + indexid; } IborIndex idx = OHRepository.Instance.getObject <IborIndex>(indexid); if (!discountId.Contains('@')) { discountId = "CRV@" + discountId; } YieldTermStructure discountcurve = OHRepository.Instance.getObject <YieldTermStructure>(discountId); YieldTermStructureHandle dch = new YieldTermStructureHandle(discountcurve); EliteQuant.Date sdate = EliteQuant.EQConverter.ConvertObject <EliteQuant.Date>(startdate); EliteQuant.Date fdate = idx.fixingDate(sdate); EliteQuant.Date tdate = idx.fixingCalendar().advance(sdate, tenor_); Schedule fixedsch = new Schedule(sdate, tdate, new Period(6, TimeUnit.Months), idx.fixingCalendar(), idx.businessDayConvention(), idx.businessDayConvention(), DateGeneration.Rule.Backward, end_of_month); Schedule floatingsch = new Schedule(sdate, tdate, idx.tenor(), idx.fixingCalendar(), idx.businessDayConvention(), idx.businessDayConvention(), DateGeneration.Rule.Backward, end_of_month); VanillaSwap swap = new VanillaSwap(ispayer ? _VanillaSwap.Type.Payer : _VanillaSwap.Type.Receiver, notional, fixedsch, fixedRate, fixeddc, floatingsch, idx, spread, idx.dayCounter()); DiscountingSwapEngine engine = new DiscountingSwapEngine(dch); swap.setPricingEngine(engine); Date refDate = discountcurve.referenceDate(); // Store the futures and return its id string id = "SWP@" + tradeid; OHRepository.Instance.storeObject(id, swap, callerAddress); id += "#" + (String)DateTime.Now.ToString(@"HH:mm:ss"); return(id); } catch (Exception e) { ExcelUtil.logError(callerAddress, System.Reflection.MethodInfo.GetCurrentMethod().Name.ToString(), e.Message); return("#EQ_ERR!"); } }