public void calculate(double[] p, GBMParaViewModel para) { this.xData_ = p; this.yData_ = new double[p.Length]; double sellBuySign = 1.0; if (this.sellBuy_ == "매도") { sellBuySign = -1.0; } else { } // set up dates Calendar calendar = new TARGET(); //Date todaysDate = new Date(DateTime.Now); Date settlementDate = new Date(para.ReferenceDate_); Settings.setEvaluationDate(settlementDate); // our options Option.Type type = this.callPutEnum_; double underlying = para.CurrentPrice_; double strike = this.strike_; double dividendYield = para.Dividend_ / 100; double riskFreeRate = para.Drift_ / 100; if (this.callPutEnum_ == Option.Type.Call) { this.imVol_ = para.Call_Interpolation_.value(this.strike_); } else if (this.callPutEnum_ == Option.Type.Put) { this.imVol_ = para.Put_Interpolation_.value(this.strike_); } double volatility = (this.imVol_) / 100; Date maturity = new Date(this.maturiry_.AddDays(1)); if (this.callPutEnum_ == 0) { this.deltaCal_ = 1.0; this.gammaCal_ = 0.0; this.vegaCal_ = 0.0; this.thetaCal_ = 0.0; this.rhoCal_ = 0.0; this.deltaPosition_ = sellBuySign * this.unit_ * 500000 * underlying; this.deltaRisk_ = this.deltaPosition_ * 0.09; this.gammaRisk_ = 0.0; this.vegaRisk_ = 0.0; this.totalRisk_ = this.deltaRisk_ + this.gammaRisk_ + this.vegaRisk_; this.deepOTM_ = 0.0; //this.remainDays_ = maturity - settlementDate; this.remainDays_ = (this.maturiry_ - para.ReferenceDate_).Days + 1; return; } DayCounter dayCounter = new Actual365Fixed(); Exercise europeanExercise = new EuropeanExercise(maturity); SimpleQuote quote = new SimpleQuote(underlying); Handle <Quote> underlyingH = new Handle <Quote>(quote); // bootstrap the yield/dividend/vol curves var flatTermStructure = new Handle <YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter)); var flatDividendTS = new Handle <YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter)); var flatVolTS = new Handle <BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter)); StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike); var bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS); // options VanillaOption europeanOption = new VanillaOption(payoff, europeanExercise); // Analytic formulas: // Black-Scholes for European europeanOption.setPricingEngine(new AnalyticEuropeanEngine(bsmProcess)); this.npv_ = Math.Round(europeanOption.NPV(), 6); this.deltaCal_ = sellBuySign * Math.Round(europeanOption.delta(), 6); this.gammaCal_ = sellBuySign * Math.Round(europeanOption.gamma(), 6); this.vegaCal_ = sellBuySign * Math.Round(europeanOption.vega() / 100, 6); this.thetaCal_ = sellBuySign * Math.Round(europeanOption.theta() / 365, 6); this.rhoCal_ = sellBuySign * Math.Round(europeanOption.rho() / 100, 6); this.deltaPosition_ = Math.Round(this.deltaCal_ * this.unit_ * 500000 * underlying, 0); this.deltaRisk_ = Math.Round(this.deltaPosition_ * 0.09, 0); this.gammaRisk_ = Math.Round(0.5 * this.gammaCal_ * (underlying * underlying * 0.08 * 0.08) * this.unit_ * 500000, 0); this.vegaRisk_ = Math.Round(this.vegaCal_ * this.imVol_ * 0.25 * this.unit_ * 500000, 0); this.totalRisk_ = this.deltaRisk_ + this.gammaRisk_ + this.vegaRisk_; this.deepOTM_ = 0.0; //this.remainDays_ = maturity - settlementDate; this.remainDays_ = (this.maturiry_ - para.ReferenceDate_).Days + 1; for (int i = 0; i < this.xData_.Length; i++) { quote.setValue(this.xData_[i]); this.yData_[i] = 500000.0 * (double)this.unit_ * europeanOption.NPV(); } }
public void testCashAtHitOrNothingAmericanGreeks() { // Testing American cash-(at-hit)-or-nothing digital option greeks SavedSettings backup = new SavedSettings(); SortedDictionary <string, double> calculated = new SortedDictionary <string, double>(); SortedDictionary <string, double> expected = new SortedDictionary <string, double>(); SortedDictionary <string, double> tolerance = new SortedDictionary <string, double>(); // std::map<std::string,Real> calculated, expected, tolerance; tolerance["delta"] = 5.0e-5; tolerance["gamma"] = 5.0e-5; tolerance["rho"] = 5.0e-5; Option.Type[] types = { QLNet.Option.Type.Call, QLNet.Option.Type.Put }; double[] strikes = { 50.0, 99.5, 100.5, 150.0 }; double cashPayoff = 100.0; double[] underlyings = { 100 }; double[] qRates = { 0.04, 0.05, 0.06 }; double[] rRates = { 0.01, 0.05, 0.15 }; double[] vols = { 0.11, 0.5, 1.2 }; DayCounter dc = new Actual360(); Date today = Date.Today; Settings.setEvaluationDate(today); SimpleQuote spot = new SimpleQuote(0.0); SimpleQuote qRate = new SimpleQuote(0.0); Handle <YieldTermStructure> qTS = new Handle <YieldTermStructure>(Utilities.flatRate(qRate, dc)); SimpleQuote rRate = new SimpleQuote(0.0); Handle <YieldTermStructure> rTS = new Handle <YieldTermStructure>(Utilities.flatRate(rRate, dc)); SimpleQuote vol = new SimpleQuote(0.0); Handle <BlackVolTermStructure> volTS = new Handle <BlackVolTermStructure>(Utilities.flatVol(vol, dc)); // there is no cycling on different residual times Date exDate = today + 360; Exercise exercise = new EuropeanExercise(exDate); Exercise amExercise = new AmericanExercise(today, exDate, false); Exercise[] exercises = { exercise, amExercise }; BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle <Quote>(spot), qTS, rTS, volTS); IPricingEngine euroEngine = new AnalyticEuropeanEngine(stochProcess); IPricingEngine amEngine = new AnalyticDigitalAmericanEngine(stochProcess); IPricingEngine[] engines = { euroEngine, amEngine }; bool knockin = true; for (int j = 0; j < engines.Length; j++) { for (int i1 = 0; i1 < types.Length; i1++) { for (int i6 = 0; i6 < strikes.Length; i6++) { StrikedTypePayoff payoff = new CashOrNothingPayoff(types[i1], strikes[i6], cashPayoff); VanillaOption opt = new VanillaOption(payoff, exercises[j]); opt.setPricingEngine(engines[j]); for (int i2 = 0; i2 < underlyings.Length; i2++) { for (int i4 = 0; i4 < qRates.Length; i4++) { for (int i3 = 0; i3 < rRates.Length; i3++) { for (int i7 = 0; i7 < vols.Length; i7++) { // test data double u = underlyings[i2]; double q = qRates[i4]; double r = rRates[i3]; double v = vols[i7]; spot.setValue(u); qRate.setValue(q); rRate.setValue(r); vol.setValue(v); // theta, dividend rho and vega are not available for // digital option with american exercise. Greeks of // digital options with european payoff are tested // in the europeanoption.cpp test double value = opt.NPV(); calculated["delta"] = opt.delta(); calculated["gamma"] = opt.gamma(); calculated["rho"] = opt.rho(); if (value > 1.0e-6) { // perturb spot and get delta and gamma double du = u * 1.0e-4; spot.setValue(u + du); double value_p = opt.NPV(), delta_p = opt.delta(); spot.setValue(u - du); double value_m = opt.NPV(), delta_m = opt.delta(); spot.setValue(u); expected["delta"] = (value_p - value_m) / (2 * du); expected["gamma"] = (delta_p - delta_m) / (2 * du); // perturb rates and get rho and dividend rho double dr = r * 1.0e-4; rRate.setValue(r + dr); value_p = opt.NPV(); rRate.setValue(r - dr); value_m = opt.NPV(); rRate.setValue(r); expected["rho"] = (value_p - value_m) / (2 * dr); // check //std::map<std::string,Real>::iterator it; foreach (var it in calculated) { string greek = it.Key; double expct = expected [greek], calcl = calculated[greek], tol = tolerance [greek]; double error = Utilities.relativeError(expct, calcl, value); if (error > tol) { REPORT_FAILURE(greek, payoff, exercise, u, q, r, today, v, expct, calcl, error, tol, knockin); } } } } } } } } } } }
public void calculate(GBMParaViewModel para) { // set up dates Calendar calendar = new TARGET(); //Date todaysDate = new Date(DateTime.Now); Date settlementDate = new Date(para.ReferenceDate_); Settings.setEvaluationDate(settlementDate); // our options Option.Type type = this.callPutEnum_; double underlying = para.CurrentPrice_; double strike = this.strike_; double dividendYield = para.Dividend_ / 100; double riskFreeRate = para.Drift_ / 100; double volatility = 0.0; if (this.callPutEnum_ == Option.Type.Call) { try { volatility = para.Call_Interpolation_.value(this.strike_) / 100; this.imVolCal_ = Math.Round(para.Call_Interpolation_.value(this.strike_), 1); } catch (Exception) { volatility = para.Call_Interpolation_.value(this.strike_, true) / 100; this.imVolCal_ = Math.Round(para.Call_Interpolation_.value(this.strike_, true), 1); } } else if (this.callPutEnum_ == Option.Type.Put) { try { volatility = para.Call_Interpolation_.value(this.strike_) / 100; this.imVolCal_ = Math.Round(para.Put_Interpolation_.value(this.strike_), 1); } catch (Exception) { volatility = para.Call_Interpolation_.value(this.strike_, true) / 100; this.imVolCal_ = Math.Round(para.Put_Interpolation_.value(this.strike_, true), 1); } } Date maturity = new Date(this.maturiry_); DayCounter dayCounter = new Actual365Fixed(); //// write column headings //int[] widths = new int[] { 35, 14, 14, 14 }; //Console.Write("{0,-" + widths[0] + "}", "Method"); //Console.Write("{0,-" + widths[1] + "}", "European"); //Console.Write("{0,-" + widths[2] + "}", "Bermudan"); //Console.WriteLine("{0,-" + widths[3] + "}", "American"); //List<Date> exerciseDates = new List<Date>(); ; //for (int i = 1; i <= 4; i++) // exerciseDates.Add(settlementDate + new Period(3 * i, TimeUnit.Months)); Exercise europeanExercise = new EuropeanExercise(maturity); //Exercise bermudanExercise = new BermudanExercise(exerciseDates); //Exercise americanExercise = new AmericanExercise(settlementDate, maturity); Handle <Quote> underlyingH = new Handle <Quote>(new SimpleQuote(underlying)); // bootstrap the yield/dividend/vol curves var flatTermStructure = new Handle <YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter)); var flatDividendTS = new Handle <YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter)); var flatVolTS = new Handle <BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter)); StrikedTypePayoff payoff = new PlainVanillaPayoff(type, strike); var bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS); // options VanillaOption europeanOption = new VanillaOption(payoff, europeanExercise); // Analytic formulas: // Black-Scholes for European europeanOption.setPricingEngine(new AnalyticEuropeanEngine(bsmProcess)); this.npv_ = Math.Round(europeanOption.NPV(), 6); this.deltaCal_ = Math.Round(europeanOption.delta(), 6); this.gammaCal_ = Math.Round(europeanOption.gamma(), 6); this.vegaCal_ = Math.Round(europeanOption.vega() / 100, 6); this.thetaCal_ = Math.Round(europeanOption.theta() / 365, 6); this.rhoCal_ = Math.Round(europeanOption.rho() / 100, 6); }
public void testGreeksInitialization() { // Testing forward option greeks initialization DayCounter dc = new Actual360(); SavedSettings backup = new SavedSettings(); Date today = Date.Today; Settings.setEvaluationDate(today); SimpleQuote spot = new SimpleQuote(100.0); SimpleQuote qRate = new SimpleQuote(0.04); Handle <YieldTermStructure> qTS = new Handle <YieldTermStructure>(Utilities.flatRate(qRate, dc)); SimpleQuote rRate = new SimpleQuote(0.01); Handle <YieldTermStructure> rTS = new Handle <YieldTermStructure>(Utilities.flatRate(rRate, dc)); SimpleQuote vol = new SimpleQuote(0.11); Handle <BlackVolTermStructure> volTS = new Handle <BlackVolTermStructure>(Utilities.flatVol(vol, dc)); BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess(new Handle <Quote>(spot), qTS, rTS, volTS); IPricingEngine engine = new ForwardVanillaEngine(stochProcess, process => new TestBinomialEngine(process)); Date exDate = today + new Period(1, TimeUnit.Years); Exercise exercise = new EuropeanExercise(exDate); Date reset = today + new Period(6, TimeUnit.Months); StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Call, 0.0); ForwardVanillaOption option = new ForwardVanillaOption(0.9, reset, payoff, exercise); option.setPricingEngine(engine); IPricingEngine ctrlengine = new TestBinomialEngine(stochProcess); VanillaOption ctrloption = new VanillaOption(payoff, exercise); ctrloption.setPricingEngine(ctrlengine); double?delta = 0; try { delta = ctrloption.delta(); } catch (Exception) { // if normal option can't calculate delta, // nor should forward try { delta = option.delta(); } catch (Exception) { delta = null; } Utils.QL_REQUIRE(delta == null, () => "Forward delta invalid"); } double?rho = 0; try { rho = ctrloption.rho(); } catch (Exception) { // if normal option can't calculate rho, // nor should forward try { rho = option.rho(); } catch (Exception) { rho = null; } Utils.QL_REQUIRE(rho == null, () => "Forward rho invalid"); } double?divRho = 0; try { divRho = ctrloption.dividendRho(); } catch (Exception) { // if normal option can't calculate divRho, // nor should forward try { divRho = option.dividendRho(); } catch (Exception) { divRho = null; } Utils.QL_REQUIRE(divRho == null, () => "Forward dividendRho invalid"); } double?vega = 0; try { vega = ctrloption.vega(); } catch (Exception) { // if normal option can't calculate vega, // nor should forward try { vega = option.vega(); } catch (Exception) { vega = null; } Utils.QL_REQUIRE(vega == null, () => "Forward vega invalid"); } }
public static object eqInstGetOptionGreeks( [ExcelArgument(Description = "id of option ")] string ObjectId, [ExcelArgument(Description = "Greek type ")] string gtype, [ExcelArgument(Description = "Option type (VANILLA or MULTIASSET)")] string otype, [ExcelArgument(Description = "trigger ")] object trigger) { if (ExcelUtil.CallFromWizard()) { return(""); } string callerAddress = ""; callerAddress = ExcelUtil.getActiveCellAddress(); try { Xl.Range rng = ExcelUtil.getActiveCellRange(); if (ExcelUtil.isNull(gtype)) { gtype = "NPV"; } if (ExcelUtil.isNull(otype)) { otype = "VANILLA"; } if (otype == "VANILLA") { VanillaOption option = OHRepository.Instance.getObject <VanillaOption>(ObjectId); switch (gtype.ToUpper()) { case "NPV": return(option.NPV()); case "DELTA": return(option.delta()); case "GAMMA": return(option.gamma()); case "VEGA": return(option.vega()); case "THETA": return(option.theta()); case "RHO": return(option.rho()); default: return(0); } } else if (otype == "MULTIASSET") { BasketOption option = OHRepository.Instance.getObject <BasketOption>(ObjectId); switch (gtype.ToUpper()) { case "NPV": return(option.NPV()); case "DELTA": return(option.delta()); case "GAMMA": return(option.gamma()); case "VEGA": return(option.vega()); case "THETA": return(option.theta()); case "RHO": return(option.rho()); default: return(0); } } else { return("Unknown option type"); } } catch (Exception e) { ExcelUtil.logError(callerAddress, System.Reflection.MethodInfo.GetCurrentMethod().Name.ToString(), e.Message); return("#EQ_ERR!"); } }