protected GeneralizedBlackScholesProcessTolerance GetStochasticProcess(DateTime valuationDate, DateTime expiryDate, double currentSpot, double strikeMoneyness) { // Sous-jacent : Spot Markit // Handle<Quote> underlyingH = new Handle<Quote>(new SimpleQuote(marketData(_valuationDate).impliedSpot)); // Sous-jacent : Spot Bloomberg Handle <Quote> underlyingH = new Handle <Quote>(new SimpleQuote(currentSpot)); // Yield Term Structure Handle <YieldTermStructure> RateTermStructure = marketData(_valuationDate).riskFree_FwdCrv(); // Handle<YieldTermStructure> RateTermStructure = marketData(valuationDate).riskFree_flat(valuationDate); // Handle<YieldTermStructure> RateTermStructure = new Handle<YieldTermStructure>(new FlatForward(valuationDate, 0.00, _dayCounter)); // Dividend Yield var DivTermStructure = marketData(_valuationDate).dividend_FwdCrv(); // var DivTermStructure = new Handle<YieldTermStructure>(new FlatForward(valuationDate, 0.00, _dayCounter)); // Volatility ATM curve // BlackVarianceCurve blackVol = marketData_valuationDate).ATMF_Vol_TS(_valuationDate); // Volatility Single vol point (flat forward) // double volatility = marketData(valuationDate)[expiryDate][strikeMoneyness]; // var blackVol = new Handle<BlackVolTermStructure>(new BlackConstantVol(_valuationDate, _calendar, volatility, _dayCounter)); // Volatility Surface Matrix volMat = marketData(_valuationDate).VolMatrix(); List <Date> dates = marketData(_valuationDate).Dates(); Calendar cal = marketData(_valuationDate).calendar(); List <double> strikes = marketData(_valuationDate).Strikes(currentSpot); // double en argument correspondant au spot de pricing BlackVarianceSurface mySurface = new BlackVarianceSurface(_valuationDate, cal, dates, strikes, volMat, marketData(_valuationDate).dayCounter()); Handle <BlackVolTermStructure> mySurfaceH = new Handle <BlackVolTermStructure>(mySurface); GeneralizedBlackScholesProcessTolerance bsmProcessVolSurface = new GeneralizedBlackScholesProcessTolerance(underlyingH, DivTermStructure, RateTermStructure, mySurfaceH); // Return //return new GeneralizedBlackScholesProcess(underlyingH, DivTermStructure, RateTermStructure, blackVol); return(bsmProcessVolSurface); }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(BlackVarianceSurface obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
static void Main(string[] args) { DateTime timer = DateTime.Now; //////////////// DATES ////////////////////////////////////////////// Calendar calendar = new TARGET(); Date todaysDate = new Date(15, Month.January, 2017); Date settlementDate = new Date(todaysDate); Settings.setEvaluationDate(todaysDate); DayCounter dayCounter = new Actual365Fixed(); //////////////// MARKET ////////////////////////////////////////////// // Spot double underlying = 4468.17; Handle <Quote> underlyingH = new Handle <Quote>(new SimpleQuote(underlying)); // riskfree double riskFreeRate = 0.035; Handle <YieldTermStructure> flatTermStructure = new Handle <YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter)); // dividend double dividendYield = 0.0; double fixedDiv = 5.0; Handle <YieldTermStructure> flatDividendTS = new Handle <YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter)); Handle <YieldTermStructure> FixedDivTermStructure = new Handle <YieldTermStructure>(new FixedForward(settlementDate, fixedDiv, underlying, dayCounter)); // vol surface Date StartDateVol = settlementDate + new Period(1, TimeUnit.Months); List <int> maturityInDays = new InitializedList <int>() { 0, 13, 41, 90, 165, 256, 345, 524, 703 }; List <Date> datesVol = new InitializedList <Date>(); for (int d = 1; d < maturityInDays.Count; d++) { datesVol.Add(calendar.advance(settlementDate, new Period(maturityInDays[d], TimeUnit.Days))); } List <double> strikes = new InitializedList <double>() { 3400, 3600, 3800, 4000, 4200, 4400, 4500, 4600, 4800, 5000, 5200, 5400, 5600 }; Matrix blackVolMatrix = new Matrix(maturityInDays.Count - 1, strikes.Count, 0.2); var vols = new InitializedList <double>() { 0.6625, 0.4875, 0.4204, 0.3667, 0.3431, 0.3267, 0.3121, 0.3121, 0.6007, 0.4543, 0.3967, 0.3511, 0.3279, 0.3154, 0.2984, 0.2921, 0.5084, 0.4221, 0.3718, 0.3327, 0.3155, 0.3027, 0.2919, 0.2889, 0.4541, 0.3869, 0.3492, 0.3149, 0.2963, 0.2926, 0.2819, 0.2800, 0.4060, 0.3607, 0.3330, 0.2999, 0.2887, 0.2811, 0.2751, 0.2775, 0.3726, 0.3396, 0.3108, 0.2781, 0.2788, 0.2722, 0.2661, 0.2686, 0.3550, 0.3277, 0.3012, 0.2781, 0.2781, 0.2661, 0.2661, 0.2681, 0.3428, 0.3209, 0.2958, 0.2740, 0.2688, 0.2627, 0.2580, 0.2620, 0.3302, 0.3062, 0.2799, 0.2631, 0.2573, 0.2533, 0.2504, 0.2544, 0.3343, 0.2959, 0.2705, 0.2540, 0.2504, 0.2464, 0.2448, 0.2462, 0.3460, 0.2845, 0.2624, 0.2463, 0.2425, 0.2385, 0.2373, 0.2422, 0.3857, 0.2860, 0.2578, 0.2399, 0.2357, 0.2327, 0.2312, 0.2351, 0.3976, 0.2860, 0.2607, 0.2356, 0.2297, 0.2268, 0.2241, 0.2320 }; for (int i = 0; i < vols.Count; i++) { int testraw = (int)(i % (datesVol.Count)); int testcol = (int)(i / (datesVol.Count)); blackVolMatrix[testraw, testcol] = vols[i]; } BlackVarianceSurface mySurface = new BlackVarianceSurface(settlementDate, calendar, datesVol, strikes, Matrix.transpose(blackVolMatrix), dayCounter); Handle <BlackVolTermStructure> mySurfaceH = new Handle <BlackVolTermStructure>(mySurface); //////////////// CALIBRATION ////////////////////////////////////////////// Period helperPeriod = new Period(); //helpers List <CalibrationHelper> calibrationHelpers = new List <CalibrationHelper>(); for (int k = 0; k < strikes.Count; k++) { for (int d = 0; d < datesVol.Count; d++) { helperPeriod = new Period(datesVol[d] - settlementDate, TimeUnit.Days); calibrationHelpers.Add(new HestonModelHelper(helperPeriod, calendar, underlying, strikes[k], new Handle <Quote>(new SimpleQuote(blackVolMatrix[d, k])), flatTermStructure, flatDividendTS, CalibrationHelper.CalibrationErrorType.ImpliedVolError)); } } // starting data double v0 = 0.1; double kappa = 1.0; double theta = 0.1; double sigma = 0.5; double rho = -0.5; // model HestonProcess hestonProcess = new HestonProcess(flatTermStructure, flatDividendTS, underlyingH, v0, kappa, theta, sigma, rho); HestonModel hestonmodel = new HestonModel(hestonProcess); AnalyticHestonEngine analyticHestonEngine = new AnalyticHestonEngine(hestonmodel); foreach (HestonModelHelper hmh in calibrationHelpers) { hmh.setPricingEngine(analyticHestonEngine); } // optimization double tolerance = 1.0e-8; LevenbergMarquardt optimizationmethod = new LevenbergMarquardt(tolerance, tolerance, tolerance); hestonmodel.calibrate(calibrationHelpers, optimizationmethod, new EndCriteria(400, 40, tolerance, tolerance, tolerance)); double error = 0.0; List <double> errorList = new InitializedList <double>(); //////////////// CALIBRATION RESULTS ////////////////////////////////////////////// Console.WriteLine("Calbration :"); Console.WriteLine("-----------"); foreach (HestonModelHelper hmh in calibrationHelpers) { error += Math.Abs(hmh.calibrationError()); errorList.Add(Math.Abs(hmh.calibrationError())); } Vector hestonParameters = hestonmodel.parameters(); Console.WriteLine("v0 = {0:0.00%}", hestonParameters[4]); Console.WriteLine("kappa = {0:0.00%}", hestonParameters[1]); Console.WriteLine("theta = {0:0.00%}", hestonParameters[0]); Console.WriteLine("sigma = {0:0.00%}", hestonParameters[2]); Console.WriteLine("rho = {0:0.00%}", hestonParameters[3]); Console.WriteLine(); Console.WriteLine("Total error = {0:0.0000}", error); Console.WriteLine("Mean error = {0:0.0000%}", error / (errorList.Count - 1)); Console.WriteLine(); int StepsPerYear = 52; double absoluteTolerance = 80.0; ulong mcSeed = 42; // MC Heston process HestonProcess calibratedHestonProcess = new HestonProcess(flatTermStructure, flatDividendTS, underlyingH, hestonParameters[4], hestonParameters[1], hestonParameters[0], hestonParameters[2], hestonParameters[3]); // BS process GeneralizedBlackScholesProcessTolerance bsmProcess = new GeneralizedBlackScholesProcessTolerance(underlyingH, FixedDivTermStructure, flatTermStructure, mySurfaceH); //////////////// ENGINES ///////////////////////////////////////////////// IPricingEngine mcHestonEngine = new MakeMCEuropeanHestonEngine <PseudoRandom, Statistics>(calibratedHestonProcess) .withStepsPerYear(StepsPerYear) .withAbsoluteTolerance(absoluteTolerance) .withSeed(mcSeed) .getAsPricingEngine(); double absoluteTolerance2 = 1.0; IPricingEngine mcGenHestonEngineTestbs = new MakeMCGenericScriptInstrument <PseudoRandom>(bsmProcess) .withStepsPerYear(StepsPerYear) .withAbsoluteTolerance(absoluteTolerance2) .withSeed(mcSeed) .value(); IPricingEngine mcGenHestonEngineTestbs2 = new MakeMCGenericScriptInstrument <PseudoRandom>(calibratedHestonProcess) .withStepsPerYear(StepsPerYear) .withAbsoluteTolerance(absoluteTolerance2) .withSeed(mcSeed) .value(); //////////////// PRICING ////////////////////////////////////////////// Console.WriteLine("Pricing Vanilla:"); Console.WriteLine("---------------"); Date maturity = new Date(17, Month.May, 2019); Exercise europeanExercise = new EuropeanExercise(maturity); Option.Type type = Option.Type.Call; double strike = underlying; StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike); VanillaOption europeanOption = new VanillaOption(payoff, europeanExercise); // heston europeanOption.setPricingEngine(analyticHestonEngine); Console.Write("Heston pricing = {0:0.0000}", europeanOption.NPV()); Console.WriteLine(" -> {0:0.0000%}", europeanOption.NPV() / underlying); // Mc heston europeanOption.setPricingEngine(mcHestonEngine); Console.Write("HestMC pricing = {0:0.0000}", europeanOption.NPV()); Console.Write(" -> {0:0.0000%}", europeanOption.NPV() / underlying); Console.WriteLine(" tolerance {0:0.0} / {1:0.00%}", absoluteTolerance, absoluteTolerance / underlying); // analytic bs europeanOption.setPricingEngine(new AnalyticEuropeanEngine(bsmProcess)); Console.Write("BS pricing = {0:0.0000}", europeanOption.NPV()); Console.WriteLine(" -> {0:0.0000%}", europeanOption.NPV() / underlying); Console.WriteLine(); //////////////// AUTOCALL HESTON ////////////////////////////////////////////// List <Date> fixingdates = new InitializedList <Date>(); double coupon = 0.05; double barrierlvl = 0.6; for (int i = 1; i <= 4; i++) { fixingdates.Add(settlementDate + new Period(i, TimeUnit.Years)); } ScriptGenericAutocall myGenericAutocallHTTEst = new ScriptGenericAutocall(fixingdates, coupon, barrierlvl, underlying); myGenericAutocallHTTEst.setPricingEngine(mcGenHestonEngineTestbs); Console.WriteLine("Pricing Autocall BS :"); Console.WriteLine("---------------------"); Console.WriteLine("test = {0:0.0000}", myGenericAutocallHTTEst.NPV()); Console.WriteLine("Err = {0:0.0000%}", myGenericAutocallHTTEst.errorEstimate() / myGenericAutocallHTTEst.NPV()); Console.WriteLine("Samples = {0}", myGenericAutocallHTTEst.samples()); Console.Write("\n"); for (int i = 0; i < 4; i++) { Console.WriteLine("ProbaCall {1} = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaCall " + i), i + 1); } Console.WriteLine("ProbaMid = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaMid")); Console.WriteLine("probaDown = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaDown")); Console.WriteLine("test = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaDown")); Console.WriteLine("AvgDown/Proba = {0:0.0000%}", myGenericAutocallHTTEst.inspout("AvgDown") / myGenericAutocallHTTEst.inspout("ProbaDown")); Console.Write("\n"); myGenericAutocallHTTEst.setPricingEngine(mcGenHestonEngineTestbs2); Console.WriteLine("Pricing Autocall Heston:"); Console.WriteLine("------------------------"); Console.WriteLine("test = {0:0.0000}", myGenericAutocallHTTEst.NPV()); Console.WriteLine("Err = {0:0.0000%}", myGenericAutocallHTTEst.errorEstimate() / myGenericAutocallHTTEst.NPV()); Console.WriteLine("Samples = {0}", myGenericAutocallHTTEst.samples()); Console.Write("\n"); for (int i = 0; i < 4; i++) { Console.WriteLine("ProbaCall {1} = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaCall " + i), i + 1); } Console.WriteLine("ProbaMid = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaMid")); Console.WriteLine("probaDown = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaDown")); Console.WriteLine("test = {0:0.0000%}", myGenericAutocallHTTEst.inspout("ProbaDown")); Console.WriteLine("AvgDown/Proba = {0:0.0000%}", myGenericAutocallHTTEst.inspout("AvgDown") / myGenericAutocallHTTEst.inspout("ProbaDown")); Console.Write("\n"); //////////////// END TEST ////////////////////////////////////////////// Console.WriteLine(); 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(BlackVarianceSurface obj) { return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr; }
static void Main(string[] args) { DateTime timer = DateTime.Now; //////////////// DATES ////////////////////////////////////////////// Calendar calendar = new TARGET(); Date todaysDate = new Date(15, Month.January, 2017); Date settlementDate = new Date(todaysDate); Settings.setEvaluationDate(todaysDate); DayCounter dayCounter = new Actual365Fixed(); //////////////// MARKET ////////////////////////////////////////////// // Spot double underlying = 100; Handle <Quote> underlyingH = new Handle <Quote>(new SimpleQuote(underlying)); // riskfree double riskFreeRate = 0.01; Handle <YieldTermStructure> flatTermStructure = new Handle <YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter)); // dividend double dividendYield = 0.035; double fixedDiv = 5.0; Handle <YieldTermStructure> flatDividendTS = new Handle <YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter)); Handle <YieldTermStructure> FixedDivTermStructure = new Handle <YieldTermStructure>(new FixedForward(settlementDate, fixedDiv, underlying, dayCounter)); // flatvol double volatility = 0.20; Handle <BlackVolTermStructure> flatVolTS = new Handle <BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter)); Console.WriteLine("Underlying price = " + underlying); Console.WriteLine("Risk-free interest rate = {0:0.00%}", riskFreeRate); Console.WriteLine("Dividend yield = {0:0.00%}", dividendYield); Console.WriteLine("Flat Volatility = {0:0.00%}", volatility); Console.Write("\n"); // volSurface List <Date> datesVol = new InitializedList <Date>(); List <double> strikesVol = new InitializedList <double>(); double spotATP = 100; Date StartDateVol = settlementDate + new Period(1, TimeUnit.Months); Matrix blackVolMatrix = new Matrix(5, 5, 0.2); List <double> timesVol = new InitializedList <double>(); for (int i = 0; i < blackVolMatrix.rows(); i++) { timesVol.Add(i + 1); } for (int j = 0; j < blackVolMatrix.columns(); j++) { datesVol.Add(StartDateVol + new Period(j, TimeUnit.Years)); for (int i = 0; i < blackVolMatrix.rows(); i++) { blackVolMatrix[i, j] = 0.2 + Math.Pow(2.5, (i)) / 100; } } for (int j = 0; j < blackVolMatrix.columns(); j++) { strikesVol.Add(spotATP * (1 - (double)((int)(blackVolMatrix.rows() / 2)) / 10) + spotATP * 0.1 * j); } BlackVarianceSurface mySurface = new BlackVarianceSurface(settlementDate, calendar, datesVol, strikesVol, blackVolMatrix, dayCounter); Handle <BlackVolTermStructure> mySurfaceH = new Handle <BlackVolTermStructure>(mySurface); // process GeneralizedBlackScholesProcessTolerance bsmProcessVolSurface = new GeneralizedBlackScholesProcessTolerance(underlyingH, FixedDivTermStructure, flatTermStructure, mySurfaceH); GeneralizedBlackScholesProcessTolerance bsmProcess = new GeneralizedBlackScholesProcessTolerance(underlyingH, flatDividendTS, flatTermStructure, flatVolTS); //////////////// INSTRUMENT ////////////////////////////////////////////// double tolerance = 0.2; List <Date> fixingdates = new InitializedList <Date>(); double coupon = 0.05; double barrierlvl = 0.6; for (int i = 1; i <= 4; i++) { fixingdates.Add(settlementDate + new Period(i, TimeUnit.Years)); } GenericAutocall myGenericAutocall = new GenericAutocall(fixingdates, coupon, barrierlvl, underlying); IPricingEngine mcengine = new MakeMGenericInstrument <PseudoRandom>(bsmProcessVolSurface) .withAbsoluteTolerance(tolerance) .withStepsPerYear(52) .withSeed(50) .value(); myGenericAutocall.setPricingEngine(mcengine); //////////////// Printing Results ////////////////////////////////////////////// Console.WriteLine("NPV Generic Autocall = {0:0.0000}", myGenericAutocall.NPV()); Console.WriteLine("Err = {0:0.0000%}", myGenericAutocall.errorEstimate() / myGenericAutocall.NPV()); Console.WriteLine("Samples = {0}", myGenericAutocall.samples()); Console.Write("\n"); for (int i = 0; i < 4; i++) { Console.WriteLine("ProbaCall {1} = {0:0.0000%}", myGenericAutocall.inspout("ProbaCall " + i), i + 1); } Console.WriteLine("ProbaMid = {0:0.0000%}", myGenericAutocall.inspout("ProbaMid")); Console.WriteLine("probaDown = {0:0.0000%}", myGenericAutocall.inspout("ProbaDown")); Console.WriteLine("AvgDown/Proba = {0:0.0000%}", myGenericAutocall.inspout("AvgDown") / myGenericAutocall.inspout("ProbaDown")); Console.Write("\n"); Console.WriteLine("Test - NoValue = {0:0.0000%}", myGenericAutocall.inspout("NoValue")); // inspout() function Console.Write("\n"); myGenericAutocall.inspout(); Console.Write("\n"); myGenericAutocall.inspout(2, true); // End test Console.WriteLine(" \nRun completed in {0}", DateTime.Now - timer); Console.WriteLine(); Console.Write("Press any key to continue ..."); Console.ReadKey(); }