private Complex Phi(HestonProcess process, Complex a, double nu_0, double nu_t, double dt) { double theta = process.theta(); double kappa = process.kappa(); double sigma = process.sigma(); double sigma2 = sigma * sigma; Complex ga = Complex.Sqrt(kappa * kappa - 2 * sigma2 * a * new Complex(0.0, 1.0)); double d = 4 * theta * kappa / sigma2; double nu = 0.5 * d - 1; Complex z = ga * Complex.Exp(-0.5 * ga * dt) / (1.0 - Complex.Exp(-ga * dt)); Complex log_z = -0.5 * ga * dt + Complex.Log(ga / (1.0 - Complex.Exp(-ga * dt))); Complex alpha = 4.0 * ga * Complex.Exp(-0.5 * ga * dt) / (sigma2 * (1.0 - Complex.Exp(-ga * dt))); Complex beta = 4.0 * kappa * Complex.Exp(-0.5 * kappa * dt) / (sigma2 * (1.0 - Complex.Exp(-kappa * dt))); return(ga * Complex.Exp(-0.5 * (ga - kappa) * dt) * (1 - Complex.Exp(-kappa * dt)) / (kappa * (1.0 - Complex.Exp(-ga * dt))) * Complex.Exp((nu_0 + nu_t) / sigma2 * ( kappa * (1.0 + Complex.Exp(-kappa * dt)) / (1.0 - Complex.Exp(-kappa * dt)) - ga * (1.0 + Complex.Exp(-ga * dt)) / (1.0 - Complex.Exp(-ga * dt)))) * Complex.Exp(nu * log_z) / Complex.Pow(z, nu) * ((nu_t > 1e-8) ? Utils.modifiedBesselFunction_i(nu, Complex.Sqrt(nu_0 * nu_t) * alpha) / Utils.modifiedBesselFunction_i(nu, Complex.Sqrt(nu_0 * nu_t) * beta) : Complex.Pow(alpha / beta, nu) )); }
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); }