double _gblackscholes(char dtype,double spot,double strike,double maturity,double sigma,double r) { double d1 = (log(spot/strike) + (r +0.5 * sigma * sigma)*maturity)/(sigma*pow(maturity,0.5)); double d2 = d1 - sigma * pow(maturity,0.5); double price = 0.0; if(dtype == 'C') price = spot * gsl_cdf_ugaussian_P(d1) - strike * exp(-r*maturity)*gsl_cdf_ugaussian_P(d2); else price = -1*spot * gsl_cdf_ugaussian_P(-1*d1) + strike * exp(-r*maturity)*gsl_cdf_ugaussian_P(-1*d2); return price; }
int Pricer::put_quanto(double &prix, double S, double Q, double K, double R, double Rf, double sigma1, double sigma2, double rho, double T) { double sigma4 = sqrt(sigma1*sigma1 - 2 * rho*sigma1*sigma2 + sigma2*sigma2); double a = R - Rf + rho*sigma1*sigma2 - sigma2*sigma2; double x = S / Q; if (S <= 0 || Q <= 0 || K <= 0 || sigma1 <= 0 || sigma2 <= 0 || T<0) { //std::cout << "the asset price, the exchange rate, the maturity, the strike and the volatilities must be positive " << std::endl; return 10; } double d1 = (log(x / K) + (R - a + sigma4*sigma4 / 2)*T) / (sigma4*sqrt(T)); double d2 = (log(x / K) + (R - a - sigma4*sigma4 / 2)*T) / (sigma4*sqrt(T)); prix = -x*exp(-a*T)*gsl_cdf_ugaussian_P(-d1) + exp(-R*T)*K*gsl_cdf_ugaussian_P(-d2); return 0; }
/* * Wrapper for the functions that do the work. */ double gsl_cdf_gamma_P (const double x, const double a, const double b) { double P; double y = x / b; if (x <= 0.0) { return 0.0; } #if 0 /* Not currently working to sufficient accuracy in tails */ if (a > LARGE_A) { /* Use Peizer and Pratt's normal approximation for large A. */ double z = norm_arg (y, a); P = gsl_cdf_ugaussian_P (z); } else #endif { P = gsl_sf_gamma_inc_P (a, y); } return P; }
double gsl_cdf_lognormal_P (const double x, const double zeta, const double sigma) { double u = (log (x) - zeta) / sigma; double P = gsl_cdf_ugaussian_P (u); return P; }
int Pricer::put_vanilla(double &prix, double T, double S0, double K, double sigma, double r, double q) { if (S0 <= 0 || K <= 0 || sigma <= 0 || T <= 0) { //std::cout << "the asset price, the exchange rate, the maturity, the strike and the volatilities must be positive " << std::endl; return 10; } const double sigma2sur2 = sigma*sigma / 2; const double logs0surK = log(S0 / K); const double sigmasqrtT = sigma*sqrt(T); const double d1 = (logs0surK + (r - q + sigma2sur2)*T) / sigmasqrtT; const double d2 = d1 - sigmasqrtT; prix = exp(-r*T)*K*gsl_cdf_ugaussian_P(-d2) - exp(-q*T)*S0*gsl_cdf_ugaussian_P(-d1); return 0; }
int Pricer::option_put_asian(double &ic, double &prix, int nb_samples, double T, double S0, double K, double sigma, double r, double J) { if (S0 <= 0 || K <= 0 || sigma <= 0 || T <= 0 || nb_samples <= 0 || J <= 0) { //std::cout << "the asset price, the exchange rate, the maturity, the strike and the volatilities must be positive " << std::endl; return 10; } struct simulations::Params data; data.M = nb_samples; data.S = S0; data.K = K; data.r = r; data.v = sigma; data.T = T; //data.J = J; double sum = 0; double var = 0; double payoff; gsl_rng *rng = gsl_rng_alloc(gsl_rng_default); gsl_rng_set(rng, (unsigned long int)time(NULL)); gsl_vector* simulations; double temp; int err = 0; double d = sqrt(3.0 / data.T) * (log(data.K / data.S) - (data.r - data.v * data.v / 2.0)* (data.T / 2.0)) / data.v; double esperance_controle2 = exp(-data.r*data.T) * (-data.K * gsl_cdf_ugaussian_P(-d) + data.S*exp((data.r - data.v * data.v / 6)*T / 2.0)*gsl_cdf_ugaussian_P(-d + data.v*sqrt(data.T / 3.0))); for (int i = 0; i < nb_samples; i++) { err = simulate_sj_integral(data, J, rng, &simulations); payoff = payoff_put_asian(simulations, data, J); temp = exp(-r*T) * payoff - calculate_controle(simulations, data, J) + esperance_controle2; sum += temp; var += temp * temp; gsl_vector_free(simulations); } prix = sum / nb_samples; var = var / nb_samples - prix * prix; ic = 1.96 * sqrt(var / nb_samples); gsl_rng_free(rng); return err; }
double gsl_cdf_tdist_P (const double x, const double nu) { double P; double x2 = x * x; if (nu > 30 && x2 < 10 * nu) { double u = cornish_fisher (x, nu); P = gsl_cdf_ugaussian_P (u); return P; } if (x2 < nu) { double u = x2 / nu; double eps = u / (1 + u); if (x >= 0) { P = beta_inc_AXPY (0.5, 0.5, 0.5, nu / 2.0, eps); } else { P = beta_inc_AXPY (-0.5, 0.5, 0.5, nu / 2.0, eps); } } else { double v = nu / (x * x); double eps = v / (1 + v); if (x >= 0) { P = beta_inc_AXPY (-0.5, 1.0, nu / 2.0, 0.5, eps); } else { P = beta_inc_AXPY (0.5, 0.0, nu / 2.0, 0.5, eps); } } return P; }
/* Purpose: calculate z test for proportions, two-tailed for two-sided hypothesis H1 != H0 Parameters: p_sample = proportion of events in sample [0..1] p_population = proportion of events in population [0..1] n = sample size Returns: Probability of making an error when rejecting the NULL hypothesis */ double gstats_test_ZP2 (double p_sample, double p_population, int n) { double z; double result = 0.0; if ((p_sample < 0.0) || (p_sample > 1.0)) { gstats_error ("z-stat: sample proportion must be given as 0.0 - 1.0."); } if ((p_population < 0.0) || (p_population > 1.0)) { gstats_error ("z-stat: population proportion must be given as 0.0 - 1.0."); } if (n < 2) { gstats_error ("z-stat: size of population must be a positive integer > 0."); } z = (p_sample - p_population) / (sqrt ( (p_population * (1-p_population)) / n) ); /* determine direction of numeric integration */ if ( p_sample > p_population ) { /* we use a normal distribution, if n is at least 30, */ /* t-distribution with n - 1 degress of freedom, otherwise */ if (n >= 30) { result = gsl_cdf_ugaussian_Q (z); } else { result = gsl_cdf_tdist_Q (z, (double) n-1); } } if ( p_sample < p_population ) { /* we use a normal distribution, if n is at least 30, */ /* t-distribution with n - 1 degress of freedom, otherwise */ if (n >= 30) { result = gsl_cdf_ugaussian_P (z); } else { result = gsl_cdf_tdist_P (z, (double) n-1); } } if ( p_sample == p_population ) { result = 0.5; } return (result * 2); }
double ProbabilityScaleTransformation::invFunc(double x) const { return 100*gsl_cdf_ugaussian_P(x); }
double gsl_cdf_gaussian_P (const double x, const double sigma) { return gsl_cdf_ugaussian_P (x / sigma); }