Ejemplo n.º 1
0
        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();
            }
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 4
0
        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");
            }
        }
Ejemplo n.º 5
0
        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!");
            }
        }