static int Free_AndersenStruct(AndersenStruct *andersen_struct)
{
  pnl_mat_free(&(andersen_struct->DiscountedPayoff));
  pnl_mat_free(&(andersen_struct->NumeraireValue));
  pnl_vect_free(&(andersen_struct->AndersenParams));
  pnl_vect_int_free(&(andersen_struct->AndersenIndices));

  return OK;
}
Beispiel #2
0
/*Moments of normal distribution*/
static int moments_normal(PnlVect *c, int m, double mu, double gamma2)
{
/* Input: PnlVect *c  is of dimension m, 
          mu=mean of normal distribution, 
          gamma2=variance of normal distribution.  
   The moments of the normal distribution with mean mu and variance gamma2 up to
   degree m are calculated and stored in c.
*/
  int i,j,n,index1;
  PnlMat *a;

  index1=(int)(m/2+1.);
  LET(c,0)=mu;
  
  a=pnl_mat_create_from_double(m,index1,0.);
  
  for(j=0;j<m;j++)
  {
    MLET(a,j,0)=1;
  }
  
  for(i=2;i<m+1;i++)
    {
   index1=(int)(i/2+1.); 
    for (n=2;n<=index1;n++)
    {
      MLET(a,i-1,n-1)=MGET(a,i-2,n-2)*(i-1-2*(n-1)+2)+MGET(a,i-2,n-1);
      LET(c,i-1)=GET(c,i-1)+MGET(a,i-1,n-1)*pow(mu, (double) i-2.*(double) n+2.)*pow(sqrt(gamma2), 2*(double)n-2.);
    }
    LET(c,i-1)=GET(c,i-1)+ pow (mu,(double)i);
  }  
  pnl_mat_free (&a);

  return 1.;
}
Beispiel #3
0
static void derive_approx_fonction(PnlBasis *B, PnlVect *D, PnlVect *alpha, double t, double x)
{
  double sum0, sum1, sum2, sum3;
  double arg[2];
  PnlMat *Hes = pnl_mat_new();
  PnlVect *grad = pnl_vect_new();
  arg[0] = t; arg[1] = x;
  sum0=0.0;//calcule la valeur de la fonction
  sum1=0.0;//calcule la valeur de sa derivee en x
  sum2=0.0;//calcule la valeur de sa derivee seconde en x
  sum3=0.0;//calcule la valeur de sa derivee en t

  /* sum0 = pnl_basis_eval (B, alpha, arg);
   * sum1 = pnl_basis_eval_D (B, alpha, arg, 1);
   * sum2 = pnl_basis_eval_D2 (B, alpha, arg, 1, 1);
   * sum3 = pnl_basis_eval_D (B, alpha, arg, 0);
   *
   * LET(D,0)=sum0;
   * LET(D,1)=sum1;
   * LET(D,2)=sum2;
   * LET(D,3)=sum3; */

  pnl_basis_eval_derivs (B, alpha, arg, &sum0, grad, Hes);
  LET(D,3) = GET(grad,0);
  LET(D,1) = GET(grad,1);
  LET(D,0) = sum0;
  LET(D,2) = PNL_MGET(Hes, 1, 1);
  LET(D,4) = PNL_MGET(Hes, 0, 1);

  pnl_mat_free (&Hes);
  pnl_vect_free (&grad);

}
Beispiel #4
0
static void triadiag_scalar_prod_test ()
{
  PnlVect *y, *x;
  PnlTridiagMat *M;
  PnlMat *full;
  int n = 5;
  int gen = PNL_RNG_MERSENNE_RANDOM_SEED;


  pnl_rand_init (gen, 1, 1);
  x = pnl_vect_create (n);
  y = pnl_vect_create (n);
  pnl_vect_rand_normal (x, n, gen);
  pnl_vect_rand_normal (y, n, gen);
  M = create_random_tridiag (n, gen);
  full = pnl_tridiag_mat_to_mat (M);
  pnl_test_eq_abs ( pnl_tridiag_mat_scalar_prod (M, x, y), 
                    pnl_mat_scalar_prod (full, x, y),
                    1E-12, "tridiag_mat_scalar_prod", "");

  
  pnl_vect_free (&x);
  pnl_vect_free (&y);
  pnl_tridiag_mat_free (&M);
  pnl_mat_free (&full); 
}
Beispiel #5
0
static void tridiag_lAxpby_test ()
{
  PnlVect *y, *x, *Fy;
  PnlTridiagMat *M;
  PnlMat *FM;
  int n = 5;
  int gen = PNL_RNG_MERSENNE_RANDOM_SEED;

  pnl_rand_init (gen, 1, 1);
  x = pnl_vect_create (n);
  y = pnl_vect_create (n);
  pnl_vect_rand_normal (x, n, gen);
  pnl_vect_rand_normal (y, n, gen);
  Fy = pnl_vect_copy (y);
  M = create_random_tridiag (n, gen);
  FM = pnl_tridiag_mat_to_mat (M);

  pnl_tridiag_mat_lAxpby (1.5, M, x, 3., y);
  pnl_mat_lAxpby (1.5, FM, x, 3., Fy);
  pnl_test_vect_eq_abs (y, Fy, 1E-12, "tridiag_mat_lAxpby", "");

  pnl_vect_free (&x);
  pnl_vect_free (&y);
  pnl_vect_free (&Fy);
  pnl_mat_free (&FM);
  pnl_tridiag_mat_free (&M);
}
Beispiel #6
0
static void tridiag_mv_test ()
{
  PnlVect *y, *x, *Fy;
  PnlMat *FM;
  PnlTridiagMat *M;
  int n = 5;
  int gen = PNL_RNG_MERSENNE_RANDOM_SEED;

  pnl_rand_init (gen, 1, 1);
  x = pnl_vect_create (n);
  y = pnl_vect_create (n);
  pnl_vect_rand_normal (x, n, gen);
  M = create_random_tridiag (n, gen);
  FM = pnl_tridiag_mat_to_mat (M);

  pnl_tridiag_mat_mult_vect_inplace (y, M, x);
  Fy = pnl_mat_mult_vect (FM, x);
  pnl_test_vect_eq_abs (y, Fy, 1E-18, "tridiag_mat_mutl_vect", "");

  pnl_vect_free (&x);
  pnl_vect_free (&y);
  pnl_vect_free (&Fy);
  pnl_mat_free (&FM);
  pnl_tridiag_mat_free (&M);
}
Beispiel #7
0
/*
 * example of how to use  pnl_basis_fit_ls to regress on a basis.
 * regression of the exponential function on the grid [0:0.05:5]
 */
static void exp_regression2()
{
  int n, basis_name, basis_dim, space_dim;
  int i;
  double a, b, h, err;
  PnlMat *t;
  PnlVect *y;
  PnlVect *alpha;

  PnlBasis *basis;


  alpha = pnl_vect_create (0);

  /* creating the grid */
  a=0.0; b=5.0;
  n = 100;
  h = (b-a)/n;
  t = pnl_mat_create_from_double (n+1, 1, h);
  pnl_mat_set (t, 0, 0, 0.0);
  pnl_mat_cumsum (t, 'r');

  /* creating the values of exp on the grid */
  y = pnl_vect_create (n+1);
  for ( i=0 ; i<n+1 ; i++ )
    {
      pnl_vect_set (y, i, function(pnl_mat_get(t, i, 0)));
    }


  basis_name = PNL_BASIS_HERMITIAN; /* PNL_BASIS_TCHEBYCHEV; */
  space_dim = 1; /* real valued basis */
  basis_dim = 5; /* number of elements in the basis */

  basis = pnl_basis_create (basis_name, basis_dim, space_dim);

  pnl_basis_fit_ls (basis, alpha, t, y);
  if ( verbose )
    {
      printf("coefficients of the decomposition : ");
      pnl_vect_print (alpha);
    }
  /* computing the infinity norm of the error */
  err = 0.;
  for (i=0; i<t->m; i++)
    {
      double tmp = function(pnl_mat_get(t, i, 0)) -
        pnl_basis_eval (basis,alpha, pnl_mat_lget(t, i, 0));
      if (fabs(tmp) > err) err = fabs(tmp);
    }

  pnl_test_eq_abs (err, 1.812972, 1E-5, "pnl_basis_eval", "exponential function on [0:0.05:5]");

  pnl_basis_free (&basis);
  pnl_mat_free (&t);
  pnl_vect_free (&y);
  pnl_vect_free (&alpha);
}
static double prix_highly_path_dependent_protection(int M, int N, int N_trading, double spot, double T, int gen, int bindex, int m, param *P)
{
  PnlMat *asset;
  PnlBasis *basis;
  double sol;
  basis=pnl_basis_create(bindex, m, 1);
  asset=pnl_mat_new();
  simul_asset(asset,M,N,spot,T,P,gen);
  prix_en_0_ls(&sol,asset,M,N,N_trading,spot,T,P,basis);
  pnl_basis_free(&basis);
  pnl_mat_free(&asset);
  return sol;
}
TEST (OptionAsian2, Payoff) {
  
  double strike=3.0;
  double T=10.0;
  int TimeSteps=5;
  int size=10;
  PnlMat *mat=  pnl_mat_create_from_list(6,1,1.0,1.0,1.0,1.0,1.0,1.0);
  OptionAsian O=OptionAsian(T,TimeSteps,size,strike);
  double payoff = O.payoff(mat);
  pnl_mat_free(&mat);
  

  ASSERT_EQ(payoff,0.0);
}
Beispiel #10
0
/* Approximation of the call/put function by a polynomial*/
static int pol_approx(NumFunc_1  *p,PnlVect *coeff, double S0, double K, int Nb_Degree_Pol)
  {
  /* Input: NumFunc_1 *p  specifies the payoff function (Call or Put),
            PnlVect *coeff  is of dimension Nb_Degree_Pol+1, 
            S0 initial value to determine the interval where the approximation 
            is done,
            K strike, 
            Nb_Degree_Pol corresponds to the degree of the approximating 
            polynomial.
      The coefficients of the polynomial approximating the Call/Put payoff 
      function are calculated and stored in coeff in increasing order starting 
      with the coefficient corresponding to degree 0.    
   */
  PnlMat *x;
  PnlVect *y;
  PnlBasis *f;
  int dim;
  int j;
  
  dim=(int)((log(S0*10)-log(S0/10))/0.01+0.5);  /* [log(S0/10), log(S0*10)] is  
                                                   the interval of approximation*/
                                                  
  x=pnl_mat_create_from_double(dim,1,0.);     
  y=pnl_vect_create_from_double(dim,0.);

  MLET(x,0,0)=log(S0/10);
  LET(y,0)=(p->Compute)(p->Par,S0/10.);
  
 for(j=1;j<dim;j++)
  {
    MLET(x,j,0)=MGET(x,j-1,0)+0.01;                    /* grid of equally spaced points 
                                                          with distance 0.01 in interval
                                                          [log(S0/10), log(S0*10)]  */
    LET(y,j)=(p->Compute)(p->Par,exp(MGET(x,j,0)));   /*  evaluation of the payoff 
                                                          function at x */
  }
 
  f=pnl_basis_create(PNL_BASIS_CANONICAL,Nb_Degree_Pol+1,1);
  pnl_basis_fit_ls(f,coeff,x,y);
  
  pnl_basis_free (&f);
  pnl_mat_free(&x);
  pnl_vect_free(&y);

  return 1.;
  }
Beispiel #11
0
static void load_rng_array (PnlMat *orig)
{
  int i, j;
  PnlRng **rngtab;
  PnlMat *res;
  rngtab = pnl_rng_create_from_file (binfile, NB_GEN);
  res = pnl_mat_create (NB_GEN, NB_INT);
  for ( i=0 ; i<NB_GEN ; i++ )
    {
      for ( j=0 ; j<NB_INT ; j++ )
        MLET(res, i, j) = pnl_rng_uni (rngtab[i]);
      pnl_rng_free (&(rngtab[i]));
    }
  pnl_test_mat_eq_abs (res, orig, 1E-10, "Save / Load (rng array)", "");
  pnl_mat_free (&res);
  free(rngtab);
  unlink(binfile);
}
Beispiel #12
0
static int load_rng (PnlMat *orig)
{

  PnlRng *rng1, *rng2;
  PnlList *L;
  PnlMat *res;
  FILE *stream;
  int i;

  res = pnl_mat_create (2, NB_INT);
  stream = fopen (binfile, "rb");
  rng1 = PNL_RNG_OBJECT(pnl_object_load (stream)); 
  rng2 = PNL_RNG_OBJECT(pnl_object_load (stream)); 
  fclose (stream);

  for ( i=0 ; i<NB_INT ; i++ )
    MLET(res, 0, i) = pnl_rng_uni (rng1);
  pnl_rng_free (&rng1);


  for ( i=0 ; i<NB_INT ; i++ )
    MLET(res, 1, i) = pnl_rng_uni (rng2);
  pnl_rng_free (&rng2);
  pnl_test_mat_eq_abs (res, orig, 1E-10, "Save / Load (object)", "");

  stream = fopen (binfile, "rb");
  L = pnl_object_load_into_list (stream); 
  fclose (stream);

  rng1 = PNL_RNG_OBJECT(pnl_list_get (L, 0));
  rng2 = PNL_RNG_OBJECT(pnl_list_get (L, 1));

  for ( i=0 ; i<NB_INT ; i++ )
    MLET(res, 0, i) = pnl_rng_uni (rng1);

  for ( i=0 ; i<NB_INT ; i++ )
    MLET(res, 1, i) = pnl_rng_uni (rng2);

  pnl_test_mat_eq_abs (res, orig, 1E-10, "Save / Load (into list)", "");
  pnl_mat_free (&res);
  pnl_list_free (&L);
  unlink(binfile);
  return MPI_SUCCESS;
}
Beispiel #13
0
int main (int argc, char **argv)
{
  PnlRngType t;
  PnlMat *orig;
  pnl_test_init (argc, argv);
  orig = pnl_mat_new();
  MPI_Init (&argc, &argv);
  t = PNL_RNG_MERSENNE;

  save_rng(t, orig);
  load_rng(orig);
  
  save_rng_array(orig);
  load_rng_array(orig);

  MPI_Finalize();
  pnl_mat_free (&orig);
  exit (pnl_test_finalize("Save/Load interface"));
}
Beispiel #14
0
/**
 * Inverse Laplace transform
 * Optimal linear combination for the Gaver Stehfest's method.
 * Unlike the Euler method, the inversion is here performed on the real line
 *
 * @param fhat the real valued Laplace transform of f
 * @param t the point at which f is to be recovered
 * @param n the number of iterations of the method
 * @return f(t)
 */
double pnl_ilap_gs (PnlFunc *fhat, double t, int n)
{
  int k;
  double f, Cnk;
  PnlMat *work;
  PnlMatInt *iwork;

  f = 0.;
  Cnk = 1. / pnl_fact (n-1);
  work = pnl_mat_create (2 * n, n+1); 
  iwork = pnl_mat_int_create_from_int (2 * n, n+1, 0);
  for ( k=1 ; k<n+1 ; k++ )
    {
      f += ALTERNATE(n-k) * pow(k, n) * Cnk * f_tilde (fhat, work, iwork, k, t, k);
      Cnk = (Cnk * (n - k)) / (k + 1);
    }
  pnl_mat_free (&work);
  pnl_mat_int_free (&iwork);
  return f;
}
//simulation par schéma d'euler de la matrice des
//trajectoires. On obtient une matrice de taille (N+1)*M
//(la fonction marche)
static void simul_asset(PnlMat *asset, int M, int N, double spot, double T, param *P, int type_generator)
{
  double h=T/N;
  int i,j;
  PnlMat *G;
  double Si_1;
  G=pnl_mat_create(0,0);
  pnl_mat_resize(asset,N+1,M);
  pnl_mat_rand_normal(G,N,M,type_generator);
  for(j=0;j<M;j++) {pnl_mat_set(asset,0,j,spot);}
  for(i=1;i<N+1;i++)
    {
      for(j=0;j<M;j++)
        {
          Si_1=pnl_mat_get(asset,i-1,j);
          pnl_mat_set(asset,i,j,Si_1*(1+b((i-1)*h,Si_1,spot,P)*h+vol((i-1)*h,Si_1,P)*sqrt(h)*pnl_mat_get(G,i-1,j)));
        }
    }
  pnl_mat_free(&G);
}
// Exercice dates are : T(0), T(1), ..., T(NbrExerciseDates-1).
// with T(0)=0 and T(NbrExerciseDates-1)=Maturity.
static int MC_Am_Alfonsi_LoSc_Bates(NumFunc_1 *p, double S0, double Maturity, double r, double divid, double V0, double k, double theta, double sigma, double rho, double mu_jump,double gamma2,double lambda, long NbrMCsimulation, int NbrExerciseDates, int NbrStepPerPeriod, int generator,  int basis_name, int DimApprox, double confidence, int flag_cir, double *ptPriceAm, double *ptPriceAmError, double *ptInfPriceAm, double *ptSupPriceAm)
{
  int j, m, nbr_var_explicatives, init_mc;
  int flag_SpotPaths, flag_VarPaths, flag_AveragePaths;
  double continuation_value, discounted_payoff, european_price, european_delta, S_t, V_t, discount_step, discount, step, exercise_date, z_alpha, mean_price, var_price;
  double *VariablesExplicatives;

  PnlMat *SpotPaths, *VarPaths, *AveragePaths, *ExplicativeVariables;
  PnlVect *DiscountedOptimalPayoff, *RegressionCoeffVect;
  PnlBasis *basis;

  /* Value to construct the confidence interval */
  z_alpha= pnl_inv_cdfnor((1.+ confidence)/2.);

  step = Maturity / (double)(NbrExerciseDates-1);
  discount_step = exp(-r*step);
  discount = exp(-r*Maturity);

  /* We store Spot and Variance*/
  flag_SpotPaths = 1;
  flag_VarPaths  = 1;
  flag_AveragePaths = 0;

  european_price = 0.;
  european_delta = 0.;

  nbr_var_explicatives = 2;

  basis = pnl_basis_create(basis_name, DimApprox, nbr_var_explicatives);

  VariablesExplicatives = malloc(nbr_var_explicatives*sizeof(double));

  ExplicativeVariables = pnl_mat_create(NbrMCsimulation, nbr_var_explicatives);
  DiscountedOptimalPayoff = pnl_vect_create(NbrMCsimulation); // Continuation Value

  RegressionCoeffVect = pnl_vect_create(0);
  SpotPaths = pnl_mat_create(0, 0); // Matrix of the whole trajectories of the spot
  VarPaths = pnl_mat_create(0, 0); // Matrix of the whole trajectories of the variance
  AveragePaths = pnl_mat_create(0, 0);

  init_mc=pnl_rand_init(generator, NbrExerciseDates*NbrStepPerPeriod, NbrMCsimulation);
  if (init_mc != OK) return init_mc;

  // Simulation of the whole paths
  BatesSimulation_Alfonsi (flag_SpotPaths, SpotPaths, flag_VarPaths, VarPaths, flag_AveragePaths, AveragePaths, S0, Maturity, r, divid, V0, k, theta, sigma, rho, mu_jump, gamma2, lambda, NbrMCsimulation, NbrExerciseDates, NbrStepPerPeriod, generator, flag_cir);

  // At maturity, the price of the option = discounted_payoff
  exercise_date = Maturity;
  for (m=0; m<NbrMCsimulation; m++)
    {
      S_t = MGET(SpotPaths, NbrExerciseDates-1, m); // Simulated Value of the spot at the maturity T
      LET(DiscountedOptimalPayoff, m) = discount * (p->Compute)(p->Par, S_t); // Discounted payoff
    }

  for (j=NbrExerciseDates-2; j>=1; j--)
    {
      /** Least square fitting **/
      exercise_date -= step;
      discount /= discount_step;

      for (m=0; m<NbrMCsimulation; m++)
        {
          V_t = MGET(VarPaths, j, m); // Simulated value of the variance
          S_t = MGET(SpotPaths, j, m); // Simulated value of the spot
          ApAlosHeston(S_t, p, Maturity-exercise_date, r, divid, V_t, k, theta, sigma,rho, &european_price, &european_delta);

          MLET(ExplicativeVariables, m, 0) = discount*european_price/S0;
          MLET(ExplicativeVariables, m, 1) = discount*european_delta*S_t*sqrt(V_t)/S0;
        }

      pnl_basis_fit_ls(basis,RegressionCoeffVect, ExplicativeVariables, DiscountedOptimalPayoff);

      /** Dynamical programming equation **/
      for (m=0; m<NbrMCsimulation; m++)
        {
          V_t = MGET(VarPaths, j, m); // Simulated value of the variance
          S_t = MGET(SpotPaths, j, m); // Simulated value of the spot
          discounted_payoff = discount * (p->Compute)(p->Par, S_t); // Discounted payoff

          if (discounted_payoff>0.) // If the payoff is null, the OptimalPayoff doesnt change.
            {
              ApAlosHeston(S_t, p, Maturity-exercise_date, r, divid, V_t, k, theta, sigma,rho, &european_price, &european_delta);

              VariablesExplicatives[0] = discount*european_price/S0;
              VariablesExplicatives[1] = discount*european_delta*S_t*sqrt(V_t)/S0;

              continuation_value = pnl_basis_eval(basis,RegressionCoeffVect, VariablesExplicatives);

              if (discounted_payoff > continuation_value)
                {
                  LET(DiscountedOptimalPayoff, m) = discounted_payoff;
                }
            }
        }

    }
  discount /= discount_step;

  // At initial date, no need for regression, continuation value is just a plain expectation estimated with empirical mean.
  continuation_value = pnl_vect_sum(DiscountedOptimalPayoff)/(double)NbrMCsimulation;
  discounted_payoff = discount*(p->Compute)(p->Par, S0);

  /* Price */
  mean_price = MAX(discounted_payoff, continuation_value);

  /* Sum of squares */
  var_price = SQR(pnl_vect_norm_two(DiscountedOptimalPayoff))/(double)NbrMCsimulation;
  var_price = MAX(var_price, SQR(discounted_payoff)) - SQR(mean_price);

  /* Price estimator */
  *ptPriceAm = mean_price;
  *ptPriceAmError = sqrt(var_price/((double)NbrMCsimulation-1));

  /* Price Confidence Interval */
  *ptInfPriceAm= *ptPriceAm - z_alpha*(*ptPriceAmError);
  *ptSupPriceAm= *ptPriceAm + z_alpha*(*ptPriceAmError);

  free(VariablesExplicatives);
  pnl_basis_free (&basis);
  pnl_mat_free(&SpotPaths);
  pnl_mat_free(&VarPaths);
  pnl_mat_free(&AveragePaths);
  pnl_mat_free(&ExplicativeVariables);

  pnl_vect_free(&DiscountedOptimalPayoff);
  pnl_vect_free(&RegressionCoeffVect);

  return OK;
}
Beispiel #17
0
/// Price of an option on a ZC using a trinomial tree.
static double tr_hw2d_zcoption(TreeHW2D* Meth, ModelHW2D* ModelParam, ZCMarketData* ZCMarket, double T, double S, int NumberOfTimeStep, NumFunc_1 *p, double r, double u, int Eur_Or_Am)
{
    double a ,sigma1, b, sigma2, rho, sigma3;
    double delta_t1, current_rate, current_u, OptionPrice, delta_y1, delta_u1, A_tT, B_tT, C_tT, ZCPrice;
    int i, h, l, jmin, jmax, kmin, kmax;

    PnlMat* OptionPriceMat1; // Matrix of prices of the option at i
    PnlMat* OptionPriceMat2; // Matrix of prices of the option at i+1
    OptionPriceMat1 = pnl_mat_create(1,1);
    OptionPriceMat2 = pnl_mat_create(1,1);

    A_tT=0;
    B_tT=0;
    C_tT=0;
    ///*******************Parameters of the processes r, u and y *********************////
    a = (ModelParam->rMeanReversion);
    sigma1 = (ModelParam->rVolatility);

    b = (ModelParam->uMeanReversion);
    sigma2 = (ModelParam->uVolatility);

    rho = (ModelParam->correlation);

    sigma3 = sqrt(sigma1*sigma1 + sigma2*sigma2/((b-a)*(b-a)) + 2*rho*sigma1*sigma2 / (b-a) );

    ///****************** Computation of the vector of payoff at the maturity of the option *******************///
    ZCOption_InitialPayoff(Meth, ModelParam, ZCMarket,OptionPriceMat2, p, S);

    ///****************** Backward computation of the option price until time 0 *******************///
    for (i = Meth->Ngrid-1; i>=0; i--)
    {
        BackwardIterationHW2D(Meth, ModelParam, ZCMarket, OptionPriceMat1, OptionPriceMat2, i+1, i);

        if (Eur_Or_Am != 0)
        {
            jmin = pnl_vect_int_get(Meth->yIndexMin, i);  // jmin(i)
            jmax = pnl_vect_int_get(Meth->yIndexMax, i);  // jmax(i)
            kmin = pnl_vect_int_get(Meth->uIndexMin, i);  // kmin(i)
            kmax = pnl_vect_int_get(Meth->uIndexMax, i);  // kmax(i)

            delta_t1 = GET(Meth->t, i) - GET(Meth->t,MAX(i-1,0)); // time step. if i=0, then delta=0 in order to have delta_x=0.
            delta_y1 = delta_xHW2D(delta_t1, a, sigma3); // space step 1
            delta_u1 = delta_xHW2D(delta_t1, b, sigma2); // space step 2

            ZCPrice_Coefficient(ZCMarket, a, sigma1, b, sigma2, rho, GET(Meth->t, i), S, &A_tT , &B_tT, &C_tT);

            for (h= jmin ; h <=jmax ; h++)
            {
                for (l= kmin ; l <=kmax ; l++)
                {
                    current_u = l*delta_u1;
                    current_rate = GET(Meth->alpha, i) + h*delta_y1 - current_u/(b-a);

                    ZCPrice = ZCPrice_Using_Coefficient(current_rate, current_u, A_tT, B_tT, C_tT);

                    // Decide whether to exercise the option or not
                    if ( MGET(OptionPriceMat2, h-jmin, l-kmin) < (p->Compute)(p->Par, ZCPrice))
                    {
                        MLET(OptionPriceMat2, h-jmin, l-kmin) = (p->Compute)(p->Par, ZCPrice);
                    }
                }
            }
        }
    }

    OptionPrice = MGET(OptionPriceMat2, 0, 0);

    pnl_mat_free(& OptionPriceMat1);
    pnl_mat_free(& OptionPriceMat2);

    return OptionPrice;

}// FIN de la fonction ZCOption
Beispiel #18
0
static void pnl_basis_eval_test ()
{
  PnlMat    *X;
  PnlVect   *V, *x, *t, *D, *alpha, *lower, *upper;
  PnlRng    *rng;
  PnlBasis  *basis;
  int        j, deg, n;
  double     t0, x0, tol;

  tol = 1E-8;
  deg=5; //total degree
  n=50;
  D=pnl_vect_create(5);
  x=pnl_vect_create(n);
  t=pnl_vect_create(n);
  t0=0.5;
  x0=2.5;
  rng = pnl_rng_create (PNL_RNG_MERSENNE);
  pnl_rng_sseed (rng, 0);
  
  /*
   * Random points where the function will be evaluted
   */
  pnl_vect_rng_uni(x,n,-5,4,rng);
  pnl_vect_rng_uni(t,n,0,1,rng);
  basis = pnl_basis_create_from_degree (PNL_BASIS_HERMITIAN, deg, 2);
  alpha = pnl_vect_create (basis->nb_func);
  X = pnl_mat_create (n, 2);
  for(j=0;j<n;j++)
    {
      MLET (X, j, 0) = GET(t,j);
      MLET (X, j, 1) = GET(x,j);
    }
  V=pnl_vect_create(n);
  /*
   * Vector of values for the function to recover
   */
  for(j=0;j<n;j++)
    {
      LET(V,j)=fonction_a_retrouver(GET(t,j),GET(x,j));
    }
  pnl_basis_fit_ls (basis, alpha, X, V);
  /*
   * compute approximations of the derivatives (first order in time and
   * second order in space )
   */
  derive_approx_fonction(basis, D, alpha,t0,x0);
  pnl_test_eq_abs (pnl_vect_get(D,0), fonction_a_retrouver(t0,x0), tol,
                   "deriv_approx_fonction", "derivative 0");
  pnl_test_eq_abs (derive_x_approx_fonction(basis, alpha, t0, x0), 
                   derive_x_fonction_a_retrouver(t0,x0), tol, 
                   "deriv_approx_fonction", "derivative %% x");
  pnl_test_eq_abs (pnl_vect_get(D,2), derive_xx_fonction_a_retrouver(t0,x0), 
                   tol, "deriv_approx_fonction", "derivative %% xx");
  pnl_test_eq_abs (pnl_vect_get(D,3), derive_t_fonction_a_retrouver(t0,x0),
                   tol, "deriv_approx_fonction", "derivative %% t");
  pnl_test_eq_abs (pnl_vect_get(D,4), derive_xt_fonction_a_retrouver(t0,x0),
                   tol, "deriv_approx_fonction", "derivative %% tx");

  pnl_basis_free (&basis);

  /* reduced basis */
  basis = pnl_basis_create_from_degree (PNL_BASIS_HERMITIAN, deg, 2);
  lower = pnl_vect_create_from_list (2, 0., -5.);
  upper = pnl_vect_create_from_list (2, 1., 4.);
  pnl_basis_set_domain (basis, lower, upper);
  pnl_basis_fit_ls (basis, alpha, X, V);

  derive_approx_fonction(basis, D, alpha,t0,x0);
  pnl_test_eq_abs (pnl_vect_get(D,0), fonction_a_retrouver(t0,x0), tol,
                   "deriv_approx_fonction (reduced)", "derivative 0");
  pnl_test_eq_abs (derive_x_approx_fonction(basis, alpha, t0, x0), 
                   derive_x_fonction_a_retrouver(t0,x0), tol, 
                   "deriv_approx_fonction (reduced)", "derivative %% x");
  pnl_test_eq_abs (pnl_vect_get(D,2), derive_xx_fonction_a_retrouver(t0,x0), 
                   tol, "deriv_approx_fonction (reduced)",  "derivative %% xx");
  pnl_test_eq_abs (pnl_vect_get(D,3), derive_t_fonction_a_retrouver(t0,x0),
                   tol, "deriv_approx_fonction (reduced)", "derivative %% t");
  pnl_test_eq_abs (pnl_vect_get(D,4), derive_xt_fonction_a_retrouver(t0,x0),
                   tol, "deriv_approx_fonction (reduced)",  "derivative %% tx");

  pnl_basis_free (&basis);
  pnl_rng_free (&rng);
  pnl_vect_free(&alpha);
  pnl_vect_free(&x);
  pnl_vect_free(&t);
  pnl_vect_free(&V);
  pnl_vect_free(&D);
  pnl_vect_free(&lower);
  pnl_vect_free(&upper);
  pnl_mat_free(&X);
}
static void prix_en_0_ls(double *res_prix, PnlMat *asset, int M, int N, int N_trading, double spot, double T, param *P, PnlBasis *basis)
{
  PnlMat *V, *res_beta, *res_no_call;
  PnlMatInt *H, *mod_H;
  PnlVectInt *res_zeta, *res_tau,*res_theta;
  PnlVect *tmp_prix;
  int j, i, zeta_j, tau_j, theta_j;
  double sprix,s;
  double h=T/N;
  //initialisation 
  V=pnl_mat_new();
  res_no_call=pnl_mat_new();
  res_beta=pnl_mat_new();
  res_zeta=pnl_vect_int_new();
  res_theta=pnl_vect_int_new();
  res_tau=pnl_vect_int_new();
  tmp_prix=pnl_vect_create(M);
  H=pnl_mat_int_new();
  mod_H=pnl_mat_int_new();

  //calcul du vecteur H
  calcul_H(H,asset,M,N,N_trading,spot,P);
  calcul_mod_H(mod_H,H,M,N,N_trading,P);
  //calcul du vecteur theta
  theta(res_theta,mod_H,M,N,N_trading,P);

  //calcul du prix_no_call protection
  prix_no_call(res_no_call,M,N,asset,spot,T,P,basis);

  //calcul du prix standard protection
  prix(V,res_no_call,M,N,asset,res_theta,spot,T,P,basis);
  //calcul de tau, zeta et beta
  tau(res_tau,M,N,V,asset,res_theta,P);
  zeta(res_zeta,res_tau,res_theta);
  beta(res_beta,spot,asset,T,N,P);
  //calcul de la somme Monte Carlo
  for(j=0;j<M;j++)
    {
      s=0;
      tau_j=pnl_vect_int_get(res_tau,j);
      theta_j=pnl_vect_int_get(res_theta,j);
      zeta_j=pnl_vect_int_get(res_zeta,j);
      if(tau_j<theta_j)
        {
          pnl_vect_set(tmp_prix,j,pnl_mat_get(res_beta,zeta_j,j)*low(pnl_mat_get(asset,tau_j,j),P));
        }
      else
        {
          pnl_vect_set(tmp_prix,j,pnl_mat_get(res_beta,zeta_j,j)*pnl_mat_get(res_no_call,theta_j,j));
        }
      
      for(i=1;i<=zeta_j;i++) s=s+h*pnl_mat_get(res_beta,i,j)*c(pnl_mat_get(asset,i,j),spot,P);
      pnl_vect_set(tmp_prix,j,pnl_vect_get(tmp_prix,j)+s);    
    }
  sprix=pnl_vect_sum(tmp_prix);
  
  pnl_mat_free(&V);
  pnl_mat_free(&res_beta);
  pnl_mat_int_free(&H);
  pnl_mat_int_free(&mod_H);
  pnl_vect_int_free(&res_zeta);
  pnl_vect_int_free(&res_tau);
  pnl_vect_int_free(&res_theta);
  pnl_vect_free(&tmp_prix);
  *res_prix=sprix/M;
}
Beispiel #20
0
static void regression_multid()
{
  int n, basis_name, nb_func, nb_variates, degree;
  int i, j;
  double a, b, h, err;
  PnlMat *t;
  PnlVect *y;
  PnlVect *alpha;

  PnlBasis *basis;
  alpha = pnl_vect_create (0);

  /* creating the grid */
  a=-2.0; b=2.0;
  n = 100;
  h = (b-a)/n;
  t = pnl_mat_create ((n+1)*(n+1), 2);

  /* creating the values of exp on the grid */
  y = pnl_vect_create ((n+1)*(n+1));
  for (i=0; i<n+1; i++)
    {
      for (j=0; j<n+1; j++)
        {
          pnl_mat_set (t, i*(n+1)+j, 0, a + i * h);
          pnl_mat_set (t, i*(n+1)+j, 1, a + j * h);
          pnl_vect_set (y, i*(n+1)+j, function2d(pnl_mat_lget(t, i*(n+1)+j, 0)));
        }
    }

  basis_name = PNL_BASIS_HERMITIAN;
  nb_variates = 2; /* functions with values in R^2 */
  nb_func = 15; /* number of elements in the basis */

  basis = pnl_basis_create (basis_name, nb_func, nb_variates);

  pnl_basis_fit_ls (basis, alpha, t, y);
  if ( verbose )
    {
      printf("coefficients of the decomposition : ");
      pnl_vect_print (alpha);
    }

  /* computing the infinity norm of the error */
  err = 0.;
  for (i=0; i<t->m; i++)
    {
      double tmp = function2d(pnl_mat_lget(t, i, 0)) -
        pnl_basis_eval (basis,alpha, pnl_mat_lget(t, i, 0));
      if (fabs(tmp) > err) err = fabs(tmp);
    }

  pnl_test_eq_abs (err, 0.263175, 1E-5, "pnl_basis_eval", "log (1+x[0]*x[0] + x[1]*x[1]) on [-2,2]^2");
  pnl_basis_free (&basis);

  degree = 4; /* total sum degree */
  basis = pnl_basis_create_from_degree (basis_name, degree, nb_variates);

  pnl_basis_fit_ls (basis, alpha, t, y);
  if ( verbose )
    {
      printf("coefficients of the decomposition : ");
      pnl_vect_print (alpha);
    }

  /* computing the infinity norm of the error */
  err = 0.;
  for (i=0; i<t->m; i++)
    {
      double tmp = function2d(pnl_mat_lget(t, i, 0)) -
        pnl_basis_eval (basis,alpha, pnl_mat_lget(t, i, 0));
      if (fabs(tmp) > err) err = fabs(tmp);
    }

  pnl_test_eq_abs (err, 0.263175, 1E-5, "pnl_basis_eval (sum degree)", "log (1+x[0]*x[0] + x[1]*x[1]) on [-2,2]^2");
  pnl_basis_free (&basis);

  degree = 4; /* total product degree */
  basis = pnl_basis_create_from_prod_degree (basis_name, degree, nb_variates);

  pnl_basis_fit_ls (basis, alpha, t, y);
  if ( verbose )
    {
      printf("coefficients of the decomposition : ");
      pnl_vect_print (alpha);
    }

  /* computing the infinity norm of the error */
  err = 0.;
  for (i=0; i<t->m; i++)
    {
      double tmp = function2d(pnl_mat_lget(t, i, 0)) -
        pnl_basis_eval (basis,alpha, pnl_mat_lget(t, i, 0));
      if (fabs(tmp) > err) err = fabs(tmp);
    }

  pnl_test_eq_abs (err, 0.263175, 1E-5, "pnl_basis_eval (prod degree)", "log (1+x[0]*x[0] + x[1]*x[1]) on [-2,2]^2");
  pnl_basis_free (&basis);


  pnl_mat_free (&t);
  pnl_vect_free (&y);
  pnl_vect_free (&alpha);
}
Beispiel #21
0
/*/////////////////////////////////////////////////////*/
  static int wh_rstemperedstable_amerput(int ifCall, double Spot,
    double T, double h, double Strike1,
    double er, long int step, int n_state,
    double *ptprice, double *ptdelta)
{
	PnlVect *divi, *rr, *num, *nup, *lambdap, *lambdam, *cm, *cp, *strike,  *mu, *qu;
	PnlVect *prices, *deltas;
	double  eps; 
	PnlMat *lam;
	int res, i, nstates;
	double tomega, omegas, lpnu, lmnu;

	eps= 1.0e-7; // accuracy of iterations

	res=readparamstsl_rs(&nstates, &rr, &divi, &num, &nup, &lambdam, &lambdap, &cm, &cp, &lam, infilename);

	if(!res)
	{
		printf("An error occured while reading file!\n");
		*ptprice=0.;
		*ptdelta=0.;
		return OK;
	}

	mu= pnl_vect_create(nstates+1);
	qu= pnl_vect_create(nstates+1);
	strike= pnl_vect_create(nstates+1);
	prices= pnl_vect_create(nstates+1);
	deltas= pnl_vect_create(nstates+1);
	
	for(i=0;i<nstates; i++) LET(strike,i)=Strike1;

	if(ifCall==0) {omegas=2.0; }
	else {omegas=-1.0; }

	for(i=0;i<nstates;i++)
	{
		LET(rr,i)=log(1.+GET(rr,i)/100.);
		LET(divi,i)=log(1.+GET(divi,i)/100.);
		
		if(ifCall==0) 
 		{
			tomega = GET(lambdam,i)<-2. ? 2. : (-GET(lambdam,i)+1.)/2.;
			omegas = omegas>tomega ? tomega :omegas;
		}
 		else 
 		{
			tomega=GET(lambdap,i)>1. ? -1. : -GET(lambdap,i)/2.;
			omegas = omegas<tomega ? tomega :omegas;
		}

		LET(cp,i) = GET(cp,i) * pnl_tgamma(-GET(nup,i));
		LET(cm,i) = GET(cm,i) * pnl_tgamma(-GET(num,i));
		lpnu=exp(GET(nup,i)*log(GET(lambdap,i)));
		lmnu=exp(GET(num,i)*log(-GET(lambdam,i)));
		
		LET(mu,i)= GET(rr,i) - GET(divi,i) + GET(cp,i)*(lpnu-exp(GET(nup,i)*log(GET(lambdap,i)+1.0))) + GET(cm,i)*(lmnu-exp(GET(num,i)*log(-GET(lambdam,i)-1.0)));
		
		LET(qu,i) = GET(rr,i) + (pow(GET(lambdap,i),GET(nup,i)) - pow(GET(lambdap,i)+omegas,GET(nup,i)))*GET(cp,i) + (pow(-GET(lambdam,i),GET(num,i))-pow(-GET(lambdam,i)-omegas,GET(num,i)))*GET(cm,i);
	}

	res = fastwienerhopfamerican_rs(1, nstates, mu, qu, omegas, 
    ifCall, Spot, lambdam, lambdap, num, nup, cm, cp, rr, divi, lam,
    T, h, strike, er, step, eps, prices, deltas);

	//Price
  *ptprice =GET(prices,n_state-1);
  //Delta
  *ptdelta =GET(deltas,n_state-1);

  // Memory desallocation
 	pnl_vect_free(&mu);
	pnl_vect_free(&qu);
	pnl_vect_free(&prices);
	pnl_vect_free(&deltas);
	pnl_vect_free(&rr);
	pnl_vect_free(&divi);
	pnl_vect_free(&lambdap);
	pnl_vect_free(&lambdam);
	pnl_vect_free(&cp);
	pnl_vect_free(&cm);
	pnl_vect_free(&num);
	pnl_vect_free(&nup);
	pnl_vect_free(&strike);
	
	pnl_mat_free(&lam);
 
  
return OK;
}
Beispiel #22
0
 /* European Call/Put price with Bates model */ 
int MCCuchieroKellerResselTeichmann(double S0, NumFunc_1  *p, double t, double r, double divid, double V0,double kappa,double theta,double sigmav,double rho,double mu,double gamma2,double lambda, long N, int M,int Nb_Degree_Pol,int generator, double confidence,double *ptprice, double *ptdelta, double *pterror_price, double *pterror_delta , double *inf_price, double *sup_price, double *inf_delta, double *sup_delta)
{
  /* Inputs: NumFunc_1 *p  specifies the payoff function (Call or Put),
		         S_0, K, t:  option inputs   
             other inputs: model parameters
             N: number of iterations in the Monte Carlo simulation
             M: number of discretization steps
             Nb_Degree_Pol: degree of approximating polynomial for variance 
                            reduction, between 0 and 8.
      Calculates the price of a European Call/Put option using Monte Carlo 
      with variance reduction. Variance reduction is achieved by approximating 
      the payoff function with a polynomial whose expectation can be calculated 
      analytically and which therefore serves as control variate.       
  */
             
  double mean_price,var_price,mean_delta,mean_delta_novar,var_delta,polyprice, polydelta,mean_price_novar;
  double poly_sample,price_sample_novar,delta_sample,delta_poly_sample,delta_sample_novar;
  int init_mc,i,j,k,n,m1,m2;
  int simulation_dim= 1;
  double alpha, z_alpha;
  double g,g2,h,Xt,Vt;
  double dt,sqrt_dt;
  int nj;
  double poisson_jump=0,mm=0,Eu;
  int matrix_dim, line;
  double K;
  double rhoc;
  PnlMat *A, *eA;
  PnlVect *coeff;
  PnlVect *deltacoeff;
  PnlVect *matcoeff;
  PnlVect *deltamatcoeff;
  PnlVect *b;
  PnlVect *deltab;
  PnlVect *veczero;
  PnlVect *vecX;
  
  rhoc=sqrt(1.-SQR(rho)); 
  Eu= exp(mu+0.5*gamma2)-1.;
  dt=t/(double)M;
  sqrt_dt=sqrt(dt);
  
  K=p->Par[0].Val.V_DOUBLE;
  
  /* Initialisation of vectors and matrices */
  coeff=pnl_vect_create_from_double(Nb_Degree_Pol+1,0.);                                                         
  deltacoeff=pnl_vect_create_from_double(Nb_Degree_Pol+1,0.);
  vecX=pnl_vect_create_from_double(Nb_Degree_Pol+1,0.); 
  
  matrix_dim = (Nb_Degree_Pol+1)*(Nb_Degree_Pol+2)/2;
  matcoeff=pnl_vect_create_from_double(matrix_dim,0.);
  deltamatcoeff=pnl_vect_create_from_double(matrix_dim,0.);
  veczero=pnl_vect_create_from_double(matrix_dim,0.); 
  A=pnl_mat_create_from_double(matrix_dim,matrix_dim,0.);
  eA= pnl_mat_create_from_double(matrix_dim,matrix_dim,0.);
  
  /* Approximation of payoff function */
  pol_approx(p,coeff,S0,K,Nb_Degree_Pol);
  
  /* Calculation of the coefficients of the derivative of the approximating 
     polynomial */
  for (n=0;n<Nb_Degree_Pol;n++)
    LET(deltacoeff,n)=GET(coeff,n+1)*(double)n;
  
  /* Reordering of coefficients, to fit the size of the generator matrix */
  for(n=0;n<Nb_Degree_Pol+1;n++)
  {
    LET(matcoeff,n*(n+1)/2)=GET(coeff,n);
    LET(deltamatcoeff,n*(n+1)/2)=GET(deltacoeff,n);
  }
  
  /* Calculation of the matrix corresponding to the generator of the Bates model */
  matrix_computation(A,Nb_Degree_Pol, r, divid, kappa, theta, lambda, mu, gamma2, sigmav, rho);
  pnl_mat_mult_double(A,t);
  
  /* Matrix exponentiation */
  pnl_mat_exp (eA,A);

  pnl_mat_sq_transpose (eA);
  b=pnl_mat_mult_vect(eA, matcoeff);
  deltab=pnl_mat_mult_vect(eA, deltamatcoeff);

  /* Calculation log(S0)^m1 V0^m2, m1+m2 <=Nb_Degree_Pol */
  for(m1=0;m1<Nb_Degree_Pol+1;m1++)
      for(m2=0;m2<Nb_Degree_Pol+1-m1;m2++)
        {
      line=(m1+m2)*(m1+m2+1)/2+m2;
      LET(veczero,line)=pow(log(S0),(double) m1)*pow(V0, (double) m2);
    }
   
   /* Expectation of approximating polynomial */
  polyprice=pnl_vect_scalar_prod(b,veczero);
  /* Expectation of derivative of approximating polynomial */
  polydelta=pnl_vect_scalar_prod(deltab,veczero);
  
  
  /* Value to construct the confidence interval */
  alpha= (1.- confidence)/2.;
  z_alpha= pnl_inv_cdfnor(1.- alpha);
  
  /*Initialisation*/
  mean_price= 0.0;
  var_price= 0.0;
  mean_delta= 0.0;
  mean_delta_novar= 0.0;
  var_delta= 0.0;
  mean_price_novar=0.;
  
  /*MC sampling*/
  init_mc= pnl_rand_init(generator,simulation_dim,N);

  /* Test after initialization for the generator */
  if(init_mc ==OK)
  {
    /* Begin N iterations */
    for(i=0;i<N;i++)
    {
      Xt=log(S0);
      Vt=V0;
      for(j=0;j<M;j++)
      {
        mm = r-divid-0.5*Vt-lambda*Eu;
         
       /* Generation of standard normal random variables  */
        g= pnl_rand_normal(generator);
        g2= pnl_rand_normal(generator);
       
        
       /* Generation of Poisson random variable */ 
        if(pnl_rand_uni(generator)<lambda*dt)
          nj=1;
        else nj=0;
        
        /* Normally distributed jump size */
        h = pnl_rand_normal(generator);
        poisson_jump=mu*nj+sqrt(gamma2*nj)*h;
       
       /* Euler scheme for log price and variance */
        Xt+=mm*dt+sqrt(MAX(0.,Vt))*sqrt_dt*g+poisson_jump;
        Vt+=kappa*(theta-Vt)*dt+sigmav*sqrt(MAX(0.,Vt))*sqrt_dt*
        (rho*g+rhoc*g2);
      }
      price_sample_novar=(p->Compute)(p->Par,exp(Xt));
      
      /* Creation of vector containing Xt^k, k<=Nb_Degree_Pol */
      for(k=0;k<Nb_Degree_Pol+1;k++)
        {
          LET(vecX,k)=pow(Xt, (double) k);
        }
     
     /* Approximating polynomial evaluated at Xt */
      poly_sample=pnl_vect_scalar_prod(coeff,vecX);
     /* Derivative of approximating polynomial evaluated at Xt */
      delta_poly_sample=pnl_vect_scalar_prod(deltacoeff,vecX);
      
      /*Sum for prices*/
      mean_price_novar+=price_sample_novar;   /* without control variate */
      mean_price+=price_sample_novar-(poly_sample-polyprice);  /* with control variate*/
      
      /* Delta sampling */
     if (price_sample_novar>0.)
        {
          delta_sample_novar=exp(Xt)/S0;//Call Case
          delta_sample= (exp(Xt)-(delta_poly_sample-polydelta))/S0; /* Delta sampling with control variate*/
          if((p->Compute) ==  &Put)
            delta_sample=(-exp(Xt)-(delta_poly_sample-polydelta))/S0;  /* Delta sampling with control variate */
        }
     
     else{
        delta_sample_novar=0;
        delta_sample=0.-(delta_poly_sample-polydelta)/S0;   /* Delta sampling with control variate */
     }
     
     /*Sum for delta*/
      mean_delta_novar+=delta_sample_novar;     /* without control variate */
      mean_delta+=delta_sample;                /* with control variate*/

      /*Sum of squares*/
      var_price+=SQR(price_sample_novar-(poly_sample-polyprice));
      var_delta+=SQR(delta_sample);
    }

    /*Price */
    *ptprice=exp(-r*t)*(mean_price/(double) N);

    /*Error*/
    *pterror_price= sqrt(exp(-2.0*r*t)*var_price/(double)N - SQR(*ptprice))/sqrt(N-1);
     
     /* Price Confidence Interval */
     *inf_price= *ptprice - z_alpha*(*pterror_price);
     *sup_price= *ptprice + z_alpha*(*pterror_price);

     /*Delta*/
      *ptdelta=exp(-r*t)*mean_delta/(double) N;
      *pterror_delta= sqrt(exp(-2.0*r*t)*(var_delta/(double)N-SQR(*ptdelta)))/sqrt((double)N-1);
      
      /* Delta Confidence Interval */
      *inf_delta= *ptdelta - z_alpha*(*pterror_delta);
      *sup_delta= *ptdelta + z_alpha*(*pterror_delta);
    
  }
  
  //Memory desallocation
  pnl_mat_free (&eA);
  pnl_mat_free (&A);
  pnl_vect_free(&coeff);
  pnl_vect_free(&b);
  pnl_vect_free(&matcoeff);
  pnl_vect_free(&veczero);
  pnl_vect_free(&vecX);
  pnl_vect_free(&deltacoeff);
  pnl_vect_free(&deltamatcoeff);
  pnl_vect_free(&deltab);

  return init_mc;
}
Beispiel #23
0
/**
 * Computes garch price for GARCH model
 * @param[in] today_price taday price
 * @param[in] alpha_zero garch parameter
 * @param[in] alpha_one garch parameter
 * @param[in] lambda the constant unit risk premium
 * @param[in] beta_one garch parameter
 * @param[in] interest the annulized interest
 * @param[in] K exercise price
 * @param[in] frequency frequency
 * @param[in] T time to mutrity
 * @param[in] choice emscorrection(ems_on or ems_off)
 * @param[in] type_generator the type of generator for random number
 * @param[out] garch option price
 *             garch->call obtains call option price
 *             garch->put  obtains put option price
 * @return OK if ok otherwise return FAIL
 */
static int garch_price(NumFunc_1  *p,double today_price,double alpha_zero,double alpha_one,double beta_one,double lambda,double interest,int frequency,double K,int T,int N,int choice,int type_generator,double *price,double *delta)
{
  double   sum_callorput;
  double   sum_delta;
  double   s_T;
  double   garch_delta;
  int      i;
  PnlMat  *path_ems, *path, *path1D;
  PnlVect *h;
  path=pnl_mat_create(T,N);
  h=pnl_vect_create (1);

  sum_callorput=0;
  sum_delta=0;

  pnl_vect_set(h,0,today_price);

  if (calculate_path(h,path,interest,frequency,N,T,alpha_zero,alpha_one,lambda,beta_one,type_generator)==FAIL)
    {
      pnl_vect_free(&h);
      pnl_mat_free(&path);
      return FAIL;
    }
  //if we choose ems option
  switch (choice)
    {
    case 1:
      pnl_vect_free(&h);
      pnl_rand_init(type_generator,N,T);
      path_ems=pnl_mat_create(T,N);
      if(ems(path,interest,frequency,path_ems)==FAIL)
        {
          pnl_mat_free(&path);
          pnl_mat_free(&path_ems);
          return FAIL;
        }
      pnl_mat_clone(path, path_ems);
      for(i=0;i<N;i++)
        {
          s_T=pnl_mat_get(path,T-1,i);
          sum_callorput=sum_callorput+(p->Compute)(p->Par,pnl_mat_get(path,T-1,i));
          if(s_T>K) garch_delta=1.;

          sum_delta=sum_delta+(s_T/today_price)*garch_delta;
        }
      pnl_mat_free(&path_ems);
      break;
    case 2:
      path1D=pnl_mat_create(T,1);
      pnl_rand_init(type_generator,1,T);
      for(i=0;i<N;i++)
        {
          calculate_path(h,path1D,interest,frequency,1,T,alpha_zero,alpha_one,lambda,beta_one,type_generator);
          s_T=pnl_mat_get(path1D,T-1,0);
          sum_callorput=sum_callorput+(p->Compute)(p->Par,pnl_mat_get(path,T-1,i));
          if(s_T>K) garch_delta=1.;
          sum_delta=sum_delta+(s_T/today_price)*garch_delta;
      }
      pnl_vect_free(&h);
      pnl_mat_free(&path1D);
      break;
    default:
      printf ("Wrong value for parameter EMS\n");
      return FAIL;
    }

  interest=(interest*frequency)/252.;

  //Price
  *price=sum_callorput/(N*pow(M_E,(interest*T)));
  *delta=sum_delta/(N*pow(M_E,(T*interest)));
  if ((p->Compute)==&Put) *delta=*delta-1;

  pnl_mat_free(&path);
  return OK ;
}
Beispiel #24
0
static int wh_rskou_bar(int am, int upordown, int ifCall, double Spot,
			      double T, double h, double Strike1,
			      double bar,double rebate,
			      double er, long int step,int n_state,
			      double *ptprice, double *ptdelta)
{
	PnlVect *divi, *rr, *lambda, *pp, *lambdap, *lambdam, *cm, *cp, *strike, *sigmas, *rebates, *mu, *qu;
	PnlVect *prices, *deltas;
	double  eps; 
	PnlMat *lam;
	int res, i, nstates;
	double tomega, omegas, sig2;

	eps= 1.0e-7; // accuracy of iterations

	res=readparamskou_rs(&nstates, &rr, &divi, &sigmas, &lambdam, &lambdap, &lambda, &pp, &lam, infilename);

	if(!res)
	{
		printf("An error occured while reading file!\n");
		*ptprice=0.;
		*ptdelta=0.;
		return OK;
	}

	mu= pnl_vect_create(nstates+1);
	qu= pnl_vect_create(nstates+1);
	cp= pnl_vect_create(nstates+1);
	cm= pnl_vect_create(nstates+1);
	strike= pnl_vect_create(nstates+1);
	rebates= pnl_vect_create(nstates+1);
	prices= pnl_vect_create(nstates+1);
	deltas= pnl_vect_create(nstates+1);
	
	for(i=0;i<nstates; i++) LET(strike,i)=Strike1;

	if(upordown==0) {omegas=2.0; }
	else {omegas=-1.0;}

	for(i=0;i<nstates;i++)
	{
		LET(rr,i)=log(1.+GET(rr,i)/100.);
		LET(divi,i)=log(1.+GET(divi,i)/100.);
		LET(rebates,i)= rebate;
		
		if(upordown==0) 
 		{
			tomega = GET(lambdam,i)<-2. ? 2. : (-GET(lambdam,i)+1.)/2.;
			omegas = omegas>tomega ? tomega :omegas;
		}
 		else 
 		{
			tomega=GET(lambdap,i)>1. ? -1. : -GET(lambdap,i)/2.;
			omegas = omegas<tomega ? tomega :omegas;
		}

		LET(cp,i)=(1-GET(pp,i))*GET(lambda,i);
		LET(cm,i)=GET(pp,i)*GET(lambda,i);
		sig2=GET(sigmas,i)*GET(sigmas,i);

		LET(mu,i)= GET(rr,i)- GET(divi,i)+GET(cp,i)/(GET(lambdap,i)+1.0)+GET(cm,i)/(GET(lambdam,i)+1.0)-sig2/2.0;

		LET(qu,i)=GET(rr,i)-GET(mu,i)*omegas-sig2*omegas*omegas/2.0+GET(cp,i)+GET(cm,i)-GET(cp,i)*GET(lambdap,i)/(GET(lambdap,i)+omegas)-GET(cm,i)*GET(lambdam,i)/(GET(lambdam,i)+omegas);
	}

	res= fastwienerhopf_rs(4, nstates, mu, qu, omegas, 1, upordown, ifCall, Spot, lambdam, lambdap,sigmas, sigmas, cm, cp, rr, divi, lam, 
    T, h, strike, bar, rebates, er, step, eps, prices, deltas);

	//Price
  *ptprice =GET(prices,n_state-1);
  //Delta
  *ptdelta =GET(deltas,n_state-1);

  // Memory desallocation
  pnl_vect_free(&mu);
	pnl_vect_free(&qu);
	pnl_vect_free(&prices);
	pnl_vect_free(&deltas);
	pnl_vect_free(&rr);
	pnl_vect_free(&divi);
	pnl_vect_free(&sigmas);
	pnl_vect_free(&lambdap);
	pnl_vect_free(&lambdam);
	pnl_vect_free(&cp);
	pnl_vect_free(&cm);
	pnl_vect_free(&lambda);
	pnl_vect_free(&pp);
	pnl_vect_free(&strike);
	pnl_vect_free(&rebates);
	
	pnl_mat_free(&lam);
  
  return OK;
}
Beispiel #25
0
/**
 * compute the paths from vector which contains historical price and stock the result in a matrix with dimensions (T+1)*N for GARCH model
 * @param[in] h vector which contain all values history of price
 * @param[out] path matrix stock all path after compute
 * @param[in] T Exercise time
 * @param[in] alpha_zero  garch parameter
 * @param[in] alpha_one  garch parameter
 * @param[in] interest interest rate
 * @param[in] lambda the constant unit risk premium
 * @param[in] beta_one parameter garch
 * @param[in] type_generator the type of generator for random number
 * @return OK if ok otherwise return FAIL
 */
static int calculate_path(const PnlVect* h,PnlMat* path,double interest,int frequency,int N,int T,double alpha_zero,double alpha_one,double lambda,double beta_one,int type_generator)
{

  double sigma,s,sigma_t;
  int size;//size of vector
  double s_t;//price at time t
  double s_0;//price init
  double presigma=alpha_zero/(1-beta_one-alpha_one*(1+pow(lambda,2)));
  double preepsilon=0;
  PnlMat* eps;//matrix contains all variables epsilon with value random
  PnlMat* array_sigma;
  int dimension=N;//colum of matrix
  int samples;//row of matrix
  int i,j;


  interest=(frequency*interest)/252.;
  size=h->size;
  s_0=pnl_vect_get(h,0);
  eps=pnl_mat_create(T-size+1,N);//matrix contains all variables epsilon with value random
  array_sigma=pnl_mat_create(T-size+1,N);
  samples=T-size+1;
  pnl_rand_init(type_generator,dimension,samples);
  pnl_mat_rand_normal(eps,samples,dimension,type_generator);


  if(size==1)
    {
      s_t=s_0;
    }
  else
    {
      s_t=pnl_vect_get(h,size-1);
    }
  if(size>1)
    {
      for(i=0;i<size-1;i++)
        {
          presigma=sqrt(alpha_zero+alpha_one*pow((presigma*preepsilon-lambda*presigma),2)+beta_one*pow(presigma,2));
          preepsilon=(1/presigma)*(log(pnl_vect_get(h,i+1)/pnl_vect_get(h,i))-interest+0.5*pow(presigma,2));
        }
    }

  for(i=0;i<dimension;i++)
    {
      for(j=0;j<samples;j++)
        {
          if(j==0)
            {
              sigma=presigma;
              pnl_mat_set(array_sigma,0,i,sigma);
              if(size>1)
                {
                  s=s_t*pow(M_E,(interest-0.5*pow(pnl_mat_get(array_sigma,0,i),2)+pnl_mat_get(array_sigma,0,i)*preepsilon));
                }
              else
                {
                  s=s_0*pow(M_E,(interest-0.5*pow(pnl_mat_get(array_sigma,0,i),2)+pnl_mat_get(array_sigma,0,i)*pnl_mat_get(eps,0,i)));
                }
              pnl_mat_set(path,0,i,s);
            }
          else
            {
              sigma_t=pnl_mat_get(array_sigma,j-1,i);

              sigma=sqrt(alpha_zero+alpha_one*pow((sigma_t*pnl_mat_get(eps,j-1,i)-lambda*sigma_t),2)+beta_one*pow(sigma_t,2));

              pnl_mat_set(array_sigma,j,i,sigma);
              s=pnl_mat_get(path,j-1,i)*pow(M_E,(interest-0.5*pow(sigma,2)+sigma*pnl_mat_get(eps,j,i)));
              pnl_mat_set(path,j,i,s);
            }
        }
    }

  pnl_mat_free(&eps);
  pnl_mat_free(&array_sigma);
  return OK;
}
// Initialization of AndersenStruct. We fill the matrices DiscountedPayoff and NumeraireValue using simulated paths.
// We also fill AndersenIndices with "q" kink-points.
static int Init_AndersenStruct(AndersenStruct *andersen_struct, Libor *ptLib, Swaption *ptBermSwpt, Volatility *ptVol, NumFunc_1 *p, int NbrMCsimulation, int NbrStepPerTenor, int generator, int flag_numeraire, double Nominal, int q)
{
  int alpha, beta, start_index, end_index, save_brownian, save_all_paths;
  int i, m, j, NbrExerciseDates, step;
  double tenor, param_max, discounted_payoff_j, numeraire_j;

  Libor *ptL_current;
  Swaption *ptSwpt;

  PnlMat *LiborPathsMatrix;
  LiborPathsMatrix = pnl_mat_create(0, 0);

  tenor = ptBermSwpt->tenor;
  alpha = pnl_iround(ptBermSwpt->swaptionMaturity/tenor); // T(alpha) is the swaption maturity
  beta  = pnl_iround(ptBermSwpt->swapMaturity/tenor); // T(beta) is the swap maturity
  NbrExerciseDates = beta-alpha;
  start_index = 0;
  end_index = beta-1;

  param_max = 0;
  save_brownian = 0;
  save_all_paths = 1;

  // SImulation of "NbrMCsimulation" Libor paths under "flag_numeraire" measure.
  Sim_Libor_Glasserman(start_index, end_index, ptLib, ptVol, generator, NbrMCsimulation, NbrStepPerTenor, save_all_paths, LiborPathsMatrix, save_brownian, LiborPathsMatrix, flag_numeraire);

  step = (NbrExerciseDates-1)/q;

  mallocLibor(&ptL_current, LiborPathsMatrix->n, tenor, 0.);
  mallocSwaption(&ptSwpt, ptBermSwpt->swaptionMaturity, ptBermSwpt->swapMaturity, 0.0, ptBermSwpt->strike, tenor);

  andersen_struct->NbrExerciseDates = NbrExerciseDates;
  andersen_struct->NbrMCsimulation = NbrMCsimulation;
  andersen_struct->j_start = 0;
  andersen_struct->q = q;

  pnl_mat_resize(andersen_struct->DiscountedPayoff, NbrExerciseDates, NbrMCsimulation);
  pnl_mat_resize(andersen_struct->NumeraireValue, NbrExerciseDates, NbrMCsimulation);
  pnl_vect_resize(andersen_struct->AndersenParams, NbrExerciseDates);
  pnl_vect_int_resize(andersen_struct->AndersenIndices, q+1);

  // Set the indices of kink-points, where parmeters will be estimated
  pnl_vect_int_set(andersen_struct->AndersenIndices, q, NbrExerciseDates-1);
  pnl_vect_int_set(andersen_struct->AndersenIndices, 0, 0);
  for (i=1; i<q; i++)
    {
      pnl_vect_int_set(andersen_struct->AndersenIndices, q-i, (NbrExerciseDates-1)-i*step);
    }

  // Fill the structure andersen_struct with discounted payoff and numeraire values.
  for (j=alpha; j<beta; j++)
    {
      for (m=0; m<NbrMCsimulation; m++)
        {
          pnl_mat_get_row(ptL_current->libor, LiborPathsMatrix, j + m*end_index);

          discounted_payoff_j = Nominal*Swaption_Payoff_Discounted(ptL_current, ptSwpt, p, flag_numeraire);
          numeraire_j = Numeraire(j, ptL_current, flag_numeraire);

          MLET(andersen_struct->DiscountedPayoff, j-alpha, m) = discounted_payoff_j;
          MLET(andersen_struct->NumeraireValue, j-alpha, m) = numeraire_j;

          param_max = MAX(param_max, numeraire_j*discounted_payoff_j);
        }

      ptSwpt->swaptionMaturity += tenor;
    }

  andersen_struct->H_max = param_max;

  pnl_mat_free(&LiborPathsMatrix);
  freeSwaption(&ptSwpt);
  freeLibor(&ptL_current);

  return OK;
}
// Returning the price and the deltas  of a basket option using its lower bound approximation :
static void lower_basket(int put_or_call,int dim, PnlVect *vol, PnlVect *poids,  PnlVect *val_init, PnlVect *div, double cor, double tx_int, double strike, double echeance,  double *prix, PnlVect* deltas)
{
  int i,j;
  // Initializing parameters
  PnlVect *sigma = pnl_vect_create (dim+1);
  PnlVect *x = pnl_vect_create (dim+1);
  PnlVect *eps = pnl_vect_create (dim+1);
  PnlMat *rac_C = pnl_mat_create (dim+1, dim+1);

  pnl_vect_set (sigma,  0,  0);
  for(i=1; i<dim+1;i++){
    pnl_vect_set (sigma, i, pnl_vect_get (vol,  i-1));
  }

  pnl_vect_set (x, 0, strike*exp(-tx_int*echeance));
  for (i=1; i<dim+1; i++){
    pnl_vect_set (x, i, fabs(pnl_vect_get (poids,  i-1)) *
                     pnl_vect_get (val_init,  i-1)*
                     exp(-pnl_vect_get (div,  i-1)*echeance));
  }
  
  pnl_vect_set (eps,  0,  -1);
  for (i=1; i<dim+1; i++){
    if(pnl_vect_get (poids,  i-1)<0) pnl_vect_set (eps,  i,  -1);
    else pnl_vect_set (eps,  i,  1);
  }
  if(put_or_call==1)
    { 
      pnl_vect_mult_double (eps, -1.0);
    }
    
  if(cor != 1){
    PnlMat *C = pnl_mat_create (dim, dim);
    //    double *C=new double[dim*dim]; // Correlation matrix
    for(i=0; i<dim; i++){
      for(j=0; j<dim; j++){
        if(i==j) pnl_mat_set (C,  i,  j,  1);
        else pnl_mat_set (C,  i,  j,  cor);
      }
    }
    pnl_mat_chol (C);
    
    for(i=0; i<dim+1; i++){
      pnl_mat_set (rac_C,  i,  0,  0);
      pnl_mat_set (rac_C,  0,  i, 0);
    }
    for(i=1; i<dim+1; i++){
      for(j=1; j<=i;j++){
        pnl_mat_set (rac_C, i, j, pnl_mat_get (C,  i-1,  j-1));
      }
      for(j=i+1;j<dim+1;j++){
        pnl_mat_set (rac_C,  i,  j ,  0);
      }
    }
    
    /* Correlation was useful only to compute a square root of it */
    pnl_mat_free (&C);
    
  } else {
    for(i=0; i<dim+1;i++){
      pnl_mat_set (rac_C,  i,  0,  0);
      pnl_mat_set (rac_C, i, 1, 1);
      for(j=2; j<dim+1;j++){
        pnl_mat_set (rac_C,  i,  j,  0);
      }
    }
    pnl_mat_set (rac_C,  0,  1,  0);
  }

  lowlinearprice(dim,eps,x,rac_C,sigma,echeance,prix,deltas); // Uses the general formula

  /* In deltas are stored the derivatives along x[i], which differ from those
     along val_init[i] */
  for(i=0;i<dim;i++){
    double d = pnl_vect_get (deltas,  i);
    pnl_vect_set (deltas, i, d * pnl_vect_get (x,  i+1) / pnl_vect_get (val_init,  i)); 
  }

  pnl_vect_free (&eps);
  pnl_vect_free (&x);
  pnl_vect_free (&sigma);
  pnl_mat_free (&rac_C);
  
}