public HybridHestonHullWhiteProcess(HestonProcess hestonProcess,
                                            HullWhiteForwardProcess hullWhiteProcess,
                                            double corrEquityShortRate,
                                            Discretization discretization = Discretization.BSMHullWhite)
        {
            hestonProcess_    = hestonProcess;
            hullWhiteProcess_ = hullWhiteProcess;
            hullWhiteModel_   = new HullWhite(hestonProcess.riskFreeRate(),
                                              hullWhiteProcess.a(),
                                              hullWhiteProcess.sigma());
            corrEquityShortRate_ = corrEquityShortRate;
            disc_   = discretization;
            maxRho_ = Math.Sqrt(1 - hestonProcess.rho() * hestonProcess.rho())
                      - Math.Sqrt(Const.QL_EPSILON) /* reserve for rounding errors */;

            T_           = hullWhiteProcess.getForwardMeasureTime();
            endDiscount_ = hestonProcess.riskFreeRate().link.discount(T_);

            Utils.QL_REQUIRE(corrEquityShortRate * corrEquityShortRate
                             + hestonProcess.rho() * hestonProcess.rho() <= 1.0, () =>
                             "correlation matrix is not positive definite");

            Utils.QL_REQUIRE(hullWhiteProcess.sigma() > 0.0, () =>
                             "positive vol of Hull White process is required");
        }
예제 #2
0
        protected override double blackVolImpl(double t, double strike)
        {
            HestonProcess process = hestonModel_.link.process();

            double df        = process.riskFreeRate().link.discount(t, true);
            double div       = process.dividendYield().link.discount(t, true);
            double spotPrice = process.s0().link.value();

            double fwd = spotPrice
                         * process.dividendYield().link.discount(t, true)
                         / process.riskFreeRate().link.discount(t, true);

            var payoff = new PlainVanillaPayoff(fwd > strike ? Option.Type.Put : Option.Type.Call, strike);

            double kappa = hestonModel_.link.kappa();
            double theta = hestonModel_.link.theta();
            double rho   = hestonModel_.link.rho();
            double sigma = hestonModel_.link.sigma();
            double v0    = hestonModel_.link.v0();

            AnalyticHestonEngine.ComplexLogFormula cpxLogFormula = AnalyticHestonEngine.ComplexLogFormula.Gatheral;

            AnalyticHestonEngine hestonEnginePtr = null;

            double?npv         = null;
            int    evaluations = 0;

            AnalyticHestonEngine.doCalculation(
                df, div, spotPrice, strike, t,
                kappa, theta, sigma, v0, rho,
                payoff, integration_, cpxLogFormula,
                hestonEnginePtr, ref npv, ref evaluations);

            if (npv <= 0.0)
            {
                return(Math.Sqrt(theta));
            }

            Brent solver = new Brent();

            solver.setMaxEvaluations(10000);
            double guess    = Math.Sqrt(theta);
            double accuracy = Const.QL_EPSILON;

            var f = new ImpliedVolHelper(payoff.optionType(), strike, fwd, t, df, npv.Value);

            return(solver.solve(f, accuracy, guess, 0.01));
        }
예제 #3
0
파일: HestonModel.cs 프로젝트: igitur/qlnet
        public HestonModel(HestonProcess process)
            : base(5)
        {
            process_ = process;

            arguments_[0] = new ConstantParameter(process.theta(), new PositiveConstraint());
            arguments_[1] = new ConstantParameter(process.kappa(), new PositiveConstraint());
            arguments_[2] = new ConstantParameter(process.sigma(), new PositiveConstraint());
            arguments_[3] = new ConstantParameter(process.rho(), new BoundaryConstraint(-1.0, 1.0));
            arguments_[4] = new ConstantParameter(process.v0(), new PositiveConstraint());
            generateArguments();

            process_.riskFreeRate().registerWith(update);
            process_.dividendYield().registerWith(update);
            process_.s0().registerWith(update);
        }
예제 #4
0
        protected override IPricingEngine controlPricingEngine()
        {
            HybridHestonHullWhiteProcess process = process_ as HybridHestonHullWhiteProcess;

            Utils.QL_REQUIRE(process != null, () => "invalid process");

            HestonProcess hestonProcess = process.hestonProcess();

            HullWhiteForwardProcess hullWhiteProcess = process.hullWhiteProcess();

            HestonModel hestonModel = new HestonModel(hestonProcess);

            HullWhite hwModel = new HullWhite(hestonProcess.riskFreeRate(),
                                              hullWhiteProcess.a(),
                                              hullWhiteProcess.sigma());

            return(new AnalyticHestonHullWhiteEngine(hestonModel, hwModel, 144));
        }
예제 #5
0
        public override void calculate()
        {
            // this is a european option pricer
            Utils.QL_REQUIRE(arguments_.exercise.type() == Exercise.Type.European, () => "not an European option");

            // plain vanilla
            PlainVanillaPayoff payoff = arguments_.payoff as PlainVanillaPayoff;

            Utils.QL_REQUIRE(payoff != null, () => "non plain vanilla payoff given");

            HestonProcess process = model_.link.process();

            double riskFreeDiscount = process.riskFreeRate().link.discount(arguments_.exercise.lastDate());
            double dividendDiscount = process.dividendYield().link.discount(arguments_.exercise.lastDate());

            double spotPrice = process.s0().link.value();

            Utils.QL_REQUIRE(spotPrice > 0.0, () => "negative or null underlying given");

            double strikePrice = payoff.strike();
            double term        = process.time(arguments_.exercise.lastDate());

            double?resultsValue = null;

            doCalculation(riskFreeDiscount,
                          dividendDiscount,
                          spotPrice,
                          strikePrice,
                          term,
                          model_.link.kappa(),
                          model_.link.theta(),
                          model_.link.sigma(),
                          model_.link.v0(),
                          model_.link.rho(),
                          payoff,
                          integration_,
                          cpxLog_,
                          this,
                          ref resultsValue,
                          ref evaluations_);
            results_.value = resultsValue;
        }