// Auxiliary gradient of function Cost, used in routine lowlinearprice : static void Gradcost(PnlVect *ksi, PnlVect *g) { int i,j,k; double normv=0, s; for (i=0; i<Dim+1; i++) { double ksi_i = pnl_vect_get (ksi, i); normv += ksi_i * ksi_i; } normv=sqrt(normv); pnl_vect_set (g, Dim+1, 0); for(j=0; j<Dim+1;j++){ pnl_vect_set (g, j, 0.); for(i=0;i<Dim+1;i++){ double tmp=0; for(k=0; k<Dim+1;k++){ tmp+=pnl_mat_get (Rac_C, i, k) * pnl_vect_get (ksi, k); } s=pnl_normal_density(pnl_vect_get (ksi, Dim+1) + pnl_vect_get (Sigma, i) * tmp*sqrt(Echeance)/normv); s*=pnl_vect_get (Eps, i) * pnl_vect_get (X, i); if(j==Dim) pnl_vect_set (g, Dim+1, pnl_vect_get (g, Dim+1) + s); s*=pnl_vect_get (Sigma, i) * sqrt(Echeance)/normv; s*=pnl_mat_get (Rac_C, i, j) - pnl_vect_get (ksi, j) *tmp/(normv*normv); pnl_vect_set (g, j, pnl_vect_get (g, j) + s); } pnl_vect_set (g , j , -pnl_vect_get (g, j)); } pnl_vect_set (g , Dim+1 , -pnl_vect_get (g, Dim+1)); }
/* * 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 void tau(PnlVectInt *res, int M, int N, PnlMat *V, PnlMat *asset, PnlVectInt *res_theta, param *P) { int i,j; pnl_vect_int_resize(res,M); for(j=0;j<M;j++) { i=0; /* printf("low=%f \n",low(pnl_mat_get(asset,i,j))); * printf("V=%f \n",pnl_mat_get(V,i,j)); */ while(((pnl_mat_get(V,i,j)>low(pnl_mat_get(asset,i,j),P)+eps)||(pnl_mat_get(V,i,j)<low(pnl_mat_get(asset,i,j),P)-eps))&&(i<pnl_vect_int_get(res_theta,j))) i++; if(i>=pnl_vect_int_get(res_theta,j)) pnl_vect_int_set(res,j,N); else pnl_vect_int_set(res,j,i); } }
/** * Create a tridiagonal matrix from a standard matrix by only taking into * account the three main diagonals. * * @param mat a PnlMat * @return a PnlTridiagMat */ PnlTridiagMat* pnl_tridiag_mat_create_from_mat (const PnlMat * mat) { PnlTridiagMat *M; int i; CheckIsSquare (mat); M=pnl_tridiag_mat_create(mat->m); for (i=0; i<mat->m-1; i++) { M->DU[i] = pnl_mat_get (mat, i, i+1); M->D[i] = pnl_mat_get (mat, i, i); M->DL[i] = pnl_mat_get (mat, i+1, i); } M->D[mat->m-1] = pnl_mat_get (mat, mat->m-1, mat->m-1); return M; }
static int ems(const PnlMat* path,double interest,int frequency,PnlMat* ems_path) { int row,colum; int i=0,j; double sum_row,s1=0; double r=interest*frequency/252; row=path->m; colum=path->n; ems_path->m=row; ems_path->n=colum; memcpy(ems_path->array,path->array,row*colum*sizeof(double)); if(row>=1) { s1=pnl_mat_get(ems_path,0,0); } while(i<row) { if(i==0) { for(j=0;j<colum;j++) { pnl_mat_set(ems_path,i,j,s1); } } else { sum_row=sum_row_matrix(path,i)/(colum*pow(M_E,i*r)); for(j=0;j<colum;j++) { pnl_mat_set(ems_path,i,j,s1*pnl_mat_get(ems_path,i,j)/sum_row); } } i++; } return OK; }
//création de la matrice v qui représente le prix. Elle est //de taille (N+1)*M static void prix_no_call(PnlMat *res, int M, int N, PnlMat *asset, double spot, double T, param *P, PnlBasis *basis) { int i,j; double Sij,mu_ij,v0; PnlVect *Si,*V_iplus1,*alpha, *c_iplus1;//(ligne i de la matrice) PnlMat MSi; double h=T/N; pnl_mat_resize(res,N+1,M); Si=pnl_vect_new(); alpha=pnl_vect_new(); c_iplus1=pnl_vect_create(M); V_iplus1=pnl_vect_new(); for(j=0;j<M;j++) pnl_mat_set(res,N,j,g(pnl_mat_get(asset,N,j),P)); for(i=N-1;i>=1;i--) { for(j=0;j<M;j++) pnl_vect_set(c_iplus1,j,c(pnl_mat_get(asset,i+1,j),spot,P)*h); pnl_mat_get_row(Si,asset,i); pnl_vect_mult_double(Si,1.0/spot); pnl_mat_get_row(V_iplus1,res,i+1); pnl_vect_plus_vect(V_iplus1,c_iplus1); MSi = pnl_mat_wrap_vect(Si); pnl_basis_fit_ls(basis,alpha,&MSi,V_iplus1); for(j=0;j<M;j++) { Sij=pnl_mat_get(asset,i,j)/spot; mu_ij=mu(spot,spot*Sij,P); pnl_mat_set(res,i,j,MIN(up(spot*Sij,P),MAX(low(spot*Sij,P),exp(-mu_ij*h)*pnl_basis_eval(basis,alpha,&Sij)))); } } pnl_mat_get_row(V_iplus1,res,1); for(j=0;j<M;j++) pnl_vect_set(c_iplus1,j,c(pnl_mat_get(asset,1,j),spot,P)*h); pnl_vect_plus_vect(V_iplus1,c_iplus1); v0=pnl_vect_sum(V_iplus1)/M; v0=MIN(up(spot,P),MAX(low(spot,P),exp(-mu(spot,spot,P)*h)*v0)); for(j=0;j<M;j++) pnl_mat_set(res,0,j,v0); pnl_vect_free(&Si); pnl_vect_free(&alpha); pnl_vect_free(&c_iplus1); pnl_vect_free(&V_iplus1); }
//stocke dans res 1 ou 0, 1 si le sous-jacent est au dessus //de Sbarre, 0 sinon static void calcul_H(PnlMatInt *res, PnlMat *asset, int M, int N, int N_trading, double spot, param *P) { int i,j; int coef=N/N_trading; pnl_mat_int_resize(res,N_trading+1,M); for(j=0;j<M;j++) { for(i=0;i<N_trading+1;i++) { if(pnl_mat_get(asset,coef*i,j)>=P->Sbarre) pnl_mat_int_set(res,i,j,1); else pnl_mat_int_set(res,i,j,0); } } }
double Barrier_l :: payoff (const PnlMat *path) { double sum ; PnlVect* final = pnl_vect_create(size_); //On met dans final la dernière colonne de Path correspond à la valeur à maturité des sous-jacents. pnl_mat_get_col(final, path, TimeSteps_); sum = pnl_vect_scalar_prod(final, Coeff_) - Strike_; //On vérifie que toutes les valeurs des sous-jacents soient au dessus de la barrière //Si on en trouve une alors le prix de l'option est de 0 for (int i=0; i<TimeSteps_+1; i++){ for (int d=0; d<size_; d++){ if (pnl_mat_get(path,d,i) < pnl_vect_get(Bl_,d)){ pnl_vect_free(&final); return 0; } } }
//definition de beta (voir page 10) matrice de taille //(N+1)*M (elle marche) static void beta(PnlMat *res, double spot, PnlMat *asset, double T, int N, param *P) { int i,j; double h=T/N; int M=asset->n; pnl_mat_resize(res,N+1,M); for(j=0;j<M;j++) pnl_mat_set(res,0,j,0); for(i=1;i<N+1;i++) { for(j=0;j<M;j++) { pnl_mat_set(res,i,j,mu(spot,pnl_mat_get(asset,i-1,j),P)); } } pnl_mat_cumsum(res,'r'); pnl_mat_mult_double(res,-h); pnl_mat_map_inplace(res,exp); }
//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); }
// Computes the price and the deltas of a claim using the lower bound of the // price for an option // that is paying a linear combination of assets : static void lowlinearprice(int _dim, PnlVect *_eps, PnlVect *_x, PnlMat *_rac_C, PnlVect *_sigma, double _echeance, double *prix, PnlVect *deltas) { int i, j; double arg; double normv=0; double tol=1e-15; PnlVect *xopt = pnl_vect_create_from_double ( _dim+2, 1./sqrt(_dim+1.)); // Starting point for optimization : normalized vector pnl_vect_set (xopt, _dim+1, 0.0); // Initializing global variables to parameters of the problem Dim=_dim; Echeance=_echeance; Sigma = _sigma; Rac_C = _rac_C; Eps = _eps; X = _x; optigc(Dim+2,xopt,tol,prix,Cost,Gradcost); *prix = -1.0* (*prix); // Price is the maximum of function for (i=0; i<Dim+1; i++) { double xopt_i = pnl_vect_get (xopt, i); normv += xopt_i * xopt_i; } normv = sqrt (normv); for(i=0; i<Dim; i++){ double tmp=0; for(j=0; j<Dim+1; j++){ tmp+=pnl_mat_get (_rac_C, i+1, j) * pnl_vect_get (xopt, j); } arg=pnl_vect_get (xopt, Dim+1) + pnl_vect_get (Sigma, i+1) * tmp*sqrt(Echeance)/normv; pnl_vect_set (deltas, i, pnl_vect_get (Eps, i+1) * cdf_nor(arg)); // Computing the deltas } pnl_vect_free (&xopt); }
// Auxiliary cost function to minimize used in lowlinearprice : static double Cost(PnlVect *ksi) { int i, j; double p=0,arg=0; double normv=0; for (i=0; i<Dim+1; i++) { double ksi_i = pnl_vect_get (ksi, i); normv += ksi_i * ksi_i; } normv = sqrt (normv); for(i=0; i<Dim+1;i++){ double tmp=0; for(j=0;j<Dim+1;j++){ tmp+=pnl_mat_get (Rac_C, i, j) * pnl_vect_get (ksi, j); } arg=pnl_vect_get (ksi, Dim+1) + pnl_vect_get (Sigma, i) * tmp*sqrt(Echeance)/normv; p+=pnl_vect_get (Eps, i) * pnl_vect_get (X, i) * cdf_nor(arg); } return (-1.0*p); // The function is to be maximized }
// 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); }
/** * 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 ; }
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; }
void calibSkew(double k2, double Put2, params *p) { int i; double gammaMin; double gammaMax; double aux, beta; int N ; double zetaF, zetaP, Error, ErrorMethod ; int Index ; gamma_ast(p, &gammaMin); gammaMax =MIN( p->VIXFuture * p->VIXFuture / p->VarianceCurve,p->Strike*p->Strike/p->VarianceCurve); N = 10; PnlMat *point; PnlMat *skewmarket; point = pnl_mat_create( N,3); skewmarket = pnl_mat_create( N,2); pnl_mat_set(point,0,0,gammaMin); zetaMax (gammaMin,p, &zetaF, &zetaP); pnl_mat_set(point,0,1,zetaF); pnl_mat_set(point,0,2,0.0); for ( i = 1; i < N; i++) { pnl_mat_set(point,i,0,gammaMin + i * (gammaMax - gammaMin) / (double)(N - 1)); pnl_mat_set(skewmarket,i,0,pnl_mat_get(point,i,0)); zeta_ast(pnl_mat_get(point,i,0),&beta, &aux, p); pnl_mat_set(point,i,1, aux ); pnl_mat_set(point,i,2, beta ); } Error = Put2, ErrorMethod = Put2; Index = 0; for( i = 0; i < N; i++) { p->Gamma = pnl_mat_get(point, i, 0); p->Omega1 = pnl_mat_get(point, i, 1); p->Omega2= pnl_mat_get(point, i, 1)*pnl_mat_get(point, i, 2); double putPrice = put_by_density(k2, p); ErrorMethod = ABS(putPrice - Put2); if (ErrorMethod < Error) { Error = ErrorMethod; Index = i; } } p->Gamma = pnl_mat_get(point, Index, 0); p->Omega1 = pnl_mat_get(point, Index, 1); p->Omega2= pnl_mat_get(point, Index, 1)*pnl_mat_get(point, Index, 2); //printf("final Gamma = %f, Omega1 = %f, Omega2 = %f\n",p->Gamma, p->Omega1, p->Omega2); }
void calibToVIXSmiles(double k1, double k2, double Theta , double RhoXY, params *p, FILE* MarketData, FILE* OUTOMEGA) { char chaine[TAILLE_MAX] = ""; int NumberMat,i,j; PnlMat *Data; PnlVect *aux; PnlMat *OMEGA; double varStateProces,T, Delta; if(MarketData != NULL) { if(fgets(chaine, TAILLE_MAX, MarketData) != NULL) i=0; //LiborNumber = (int)atof ( chaine ); if(fgets(chaine, TAILLE_MAX, MarketData) != NULL) NumberMat = (int) atof ( chaine ); Data = pnl_mat_create (NumberMat,7); OMEGA = pnl_mat_create (2*NumberMat,3); aux = pnl_vect_create (7); for(j=0;j<NumberMat;j++) { if(fgets(chaine, TAILLE_MAX, MarketData) != NULL) { RowFromFile(chaine, NumberMat, aux); for(i=0;i<7;i++) { pnl_mat_set(Data,j,i,pnl_vect_get(aux,i)/100.0); } } } fclose(MarketData); } for(i=0;i<NumberMat;i++) { p->VarianceCurve=pnl_mat_get(Data,i,1); p->VIXFuture =pnl_mat_get(Data,i,2); p->Strike =pnl_mat_get(Data,i,3); p->PutVIX =pnl_mat_get(Data,i,4); calibSkew(pnl_mat_get(Data,i,5), pnl_mat_get(Data,i,6), p); if(i<NumberMat-1) { T = pnl_mat_get(Data,i+1,0); Delta = pnl_mat_get(Data,i+1,0) - pnl_mat_get(Data,i,0); } else { Delta = pnl_mat_get(Data,i,0) - pnl_mat_get(Data,i-1,0); T = pnl_mat_get(Data,i,0)+ Delta; } varStateProces = calcul_var(T, Delta, k1, k2, Theta , RhoXY); pnl_mat_set(OMEGA,2*i,0, T-Delta); pnl_mat_set(OMEGA,2*i,1, p->Omega1); pnl_mat_set(OMEGA,2*i,2, p->VarianceCurve); pnl_mat_set(OMEGA,2*i+1,0, T-p->Gamma*Delta); pnl_mat_set(OMEGA,2*i+1,1, p->Omega2); pnl_mat_set(OMEGA,2*i+1,2, p->VarianceCurve); } if (OUTOMEGA != NULL) { fprintf( OUTOMEGA, "%d \n", 2*NumberMat ); // Ecriture du caractère A for(i=0;i<2*NumberMat;i++) fprintf( OUTOMEGA, "%f \t %f \t %f \n", pnl_mat_get(OMEGA,i,0), pnl_mat_get(OMEGA,i,1), pnl_mat_get(OMEGA,i,2)); // Ecriture du caractère A fclose(OUTOMEGA); } //pnl_mat_print(OMEGA); }
/** * 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; }