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); }
static void tridiag_lu_syslin_test () { PnlVect *b, *x, *Mx; PnlTridiagMat *M; PnlTridiagMatLU *LU; int n = 5; int gen = PNL_RNG_MERSENNE_RANDOM_SEED; pnl_rand_init (gen, 1, 1); x = pnl_vect_create (n); b = pnl_vect_create (n); pnl_vect_rand_normal (b, n, gen); M = create_random_tridiag (n, gen); LU = pnl_tridiag_mat_lu_new (); pnl_tridiag_mat_lu_compute (LU, M); pnl_tridiag_mat_lu_syslin (x, LU, b); Mx = pnl_tridiag_mat_mult_vect (M, x); pnl_test_vect_eq_abs (Mx, b, 1E-12, "tridiag_mat_syslin", ""); pnl_vect_free (&x); pnl_vect_free (&Mx); pnl_vect_free (&b); pnl_tridiag_mat_free (&M); pnl_tridiag_mat_lu_free (&LU); }
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); }
/// Price at time "s" of a ZC bond maturing at "T" using a trinomial tree. static double tr_hw1d_zcbond(TreeShortRate* Meth, ModelParameters* ModelParam, ZCMarketData* ZCMarket, double T) { int index_last, index_first; double OptionPrice; PnlVect* OptionPriceVect1; // Matrix of prices of the option at i PnlVect* OptionPriceVect2; // Matrix of prices of the option at i+1 OptionPriceVect1 = pnl_vect_create(1); OptionPriceVect2 = pnl_vect_create(1); ///****************** Computation of the vector of payoff at the maturity of the option *******************/// ZCBond_InitialPayoffHW1D(Meth, OptionPriceVect2); ///****************** Backward computation of the option price until time 0 *******************/// index_last = Meth->Ngrid; index_first = 0; BackwardIteration(Meth, ModelParam, OptionPriceVect1, OptionPriceVect2, index_last, index_first, &func_model_hw1d); OptionPrice = GET(OptionPriceVect1, 0); pnl_vect_free(& OptionPriceVect1); pnl_vect_free(& OptionPriceVect2); return OptionPrice; }
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); }
static void test_hybrX () { int j, n, maxfev, info, nfev; double xtol, fnorm; PnlVect *x, *fvec, *diag; PnlRnFuncRnDFunc f; n = 9; x = pnl_vect_create (n); fvec = pnl_vect_create (n); diag = pnl_vect_create (n); /* the following starting values provide a rough solution. */ pnl_vect_set_double (x, -1); /* default value for xtol */ xtol = 0; maxfev = 2000; pnl_vect_set_double (diag, 1); /* * Test without Jacobian */ printf ("Test of pnl_root_fsolve without user supplied Jacobian.\n\n"); f.function = fcn_fsolve; f.Dfunction = NULL; f.params = NULL; info = pnl_root_fsolve (&f, x, fvec, xtol, maxfev, &nfev, diag, FALSE); fnorm = pnl_vect_norm_two(fvec); printf(" final l2 norm of the residuals %15.7g\n\n", fnorm); printf(" number of function evaluations %10i\n\n", nfev); printf(" exit parameter %10i\n\n", info); printf(" final approximate solution\n"); for (j=1; j<=n; j++) printf("%s%15.7g", j%3==1?"\n ":"", GET(x,j-1)); printf("\n\n"); /* * Test with Jacobian */ printf ("Test of pnl_root_fsolve without user supplied Jacobian.\n\n"); f.function = fcn_fsolve; f.Dfunction = Dfcn_fsolve; f.params = NULL; info = pnl_root_fsolve (&f, x, fvec, xtol, maxfev, &nfev, diag, FALSE); fnorm = pnl_vect_norm_two(fvec); printf(" final l2 norm of the residuals %15.7g\n\n", fnorm); printf(" number of function evaluations %10i\n\n", nfev); printf(" exit parameter %10i\n\n", info); printf(" final approximate solution\n"); for (j=1; j<=n; j++) printf("%s%15.7g", j%3==1?"\n ":"", GET(x,j-1)); printf("\n\n"); pnl_vect_free (&x); pnl_vect_free (&fvec); pnl_vect_free (&diag); }
/* * 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); }
// Conjugate gradient optimization of function f, given its gradient gradf. // Minimum is stored in min, its location in p. Tolerance is asked : static void optigc(int dim, PnlVect *p, double tol, double *min, double f(PnlVect *), void gradf(PnlVect *, PnlVect *)) { int i, j; /* Scalars used to define directions */ double gg,gam,fp,dgg; PnlVect *g = pnl_vect_create (dim); /* Auxiliary direction : gradient at the minimum */ PnlVect *h = pnl_vect_create (dim); /* Conjugate direction along which to minimize */ PnlVect *grad = pnl_vect_create (dim); /* Gradient */ const int ITMAX = 20000; const double EPS = 1.0e-18; fp=f(p); gradf(p,grad); pnl_vect_clone (h, grad); pnl_vect_clone (g, grad); pnl_vect_mult_double (h ,-1.0); pnl_vect_mult_double (g ,-1.0); pnl_vect_mult_double (grad ,-1.0); for(i=0; i<ITMAX; i++) { min1dir(dim,p,h,min,f); // Minimizing along direction h if(2.0*fabs((*min)-fp) <= tol*(fabs((*min))+fabs(fp)+EPS)) // Done : tolerance reached { pnl_vect_free (&g); pnl_vect_free (&h); pnl_vect_free (&grad); return; } fp=(*min); gradf(p,grad); // Computes gradient at point p, location of minimum dgg=gg=0.0; /* Computes coefficients applied to new direction for h */ gg = pnl_vect_scalar_prod (g, g); /* Denominator */ dgg = pnl_vect_scalar_prod (grad, grad) + pnl_vect_scalar_prod (g, grad); /* Numerator : Polak-Ribiere */ if(gg==0.0) // Gradient equals zero : done { pnl_vect_free (&g); pnl_vect_free (&h); pnl_vect_free (&grad); return; } gam=dgg/gg; for(j=0; j<dim; j++){ // Defining directions for next iteration pnl_vect_set (g, j, - pnl_vect_get (grad, j)); pnl_vect_set (h, j, pnl_vect_get (g, j)+gam * pnl_vect_get (h, j)); } } perror ("Too many iterations in optigc\n"); }
static void test_lmdif () { int m, n, info, nfev, maxfev; double tol, fnorm; PnlVect *x, *fvec; PnlRnFuncRmDFunc f; m = 15; n = 3; x = pnl_vect_create (n); fvec = pnl_vect_create (m); /* the following starting values provide a rough fit. */ pnl_vect_set_double (x, 1.); /* default vlaues */ tol = 0; maxfev = 0; /* * Test without user supplied Jacobian */ printf ("Test of pnl_root_fsolve_lsq without user supplied Jacobian.\n\n"); f.function = fcn_lsq; f.Dfunction = NULL; f.params = NULL; info = pnl_root_fsolve_lsq(&f, x, m, fvec, tol, tol, 0., maxfev, &nfev, NULL, TRUE); fnorm = pnl_vect_norm_two(fvec); printf(" final l2 norm of the residuals%15.7f\n\n",fnorm); printf(" exit parameter %10i\n\n", info); printf(" final approximate solution\n\n %15.7f%15.7f%15.7f\n\n", GET(x,0), GET(x,1), GET(x,2)); /* * Test with user supplied Jacobian */ printf ("Test of pnl_root_fsolve_lsq with user supplied Jacobian.\n\n"); f.function = fcn_lsq; f.Dfunction = Dfcn_lsq; f.params = NULL; info = pnl_root_fsolve_lsq(&f, x, m, fvec, tol, tol, 0., maxfev, &nfev, NULL, TRUE); fnorm = pnl_vect_norm_two(fvec); printf(" final l2 norm of the residuals%15.7f\n\n",fnorm); printf(" exit parameter %10i\n\n", info); printf(" final approximate solution\n\n %15.7f%15.7f%15.7f\n\n", GET(x,0), GET(x,1), GET(x,2)); pnl_vect_free (&x); pnl_vect_free (&fvec); }
Barrier_u::Barrier_u(double strike, double* bu, double T, int timeStep, int size, double r, double* coeff) : Option(T, timeStep, size, r, coeff){ strike_ = strike; Bu_ = pnl_vect_create(size_); for (int i = 0; i < size_; i++){ LET(Bu_, i) = bu[i]; } }
static PnlTridiagMat* create_random_tridiag (n, gen) { PnlVect *dl, *du, *d; PnlTridiagMat *M; d = pnl_vect_create (n); du = pnl_vect_create (n); dl = pnl_vect_create (n); pnl_vect_rand_uni (d, n, 0., 1., gen); pnl_vect_rand_uni (du, n-1, 0., 1., gen); pnl_vect_rand_uni (dl, n-1, 0., 1., gen); M = pnl_tridiag_mat_create_from_ptr (n, dl->array, d->array, du->array); pnl_vect_free (&d); pnl_vect_free (&dl); pnl_vect_free (&du); return M; }
int CALC(AP_CarmonaDurrleman)(void *Opt, void *Mod, PricingMethod *Met) { TYPEOPT* ptOpt=(TYPEOPT*)Opt; TYPEMOD* ptMod=(TYPEMOD*)Mod; double r; int i, res; PnlVect *divid = pnl_vect_create(ptMod->Size.Val.V_PINT); PnlVect *spot, *sig; spot = pnl_vect_compact_to_pnl_vect (ptMod->S0.Val.V_PNLVECTCOMPACT); sig = pnl_vect_compact_to_pnl_vect (ptMod->Sigma.Val.V_PNLVECTCOMPACT); for(i=0; i<ptMod->Size.Val.V_PINT; i++) pnl_vect_set (divid, i, log(1.+ pnl_vect_compact_get (ptMod->Divid.Val.V_PNLVECTCOMPACT, i)/100.)); r= log(1.+ptMod->R.Val.V_DOUBLE/100.); res=ap_carmonadurrleman(spot, ptOpt->PayOff.Val.V_NUMFUNC_ND, ptOpt->Maturity.Val.V_DATE-ptMod->T.Val.V_DATE, r, divid, sig, ptMod->Rho.Val.V_DOUBLE, &(Met->Res[0].Val.V_DOUBLE),Met->Res[1].Val.V_PNLVECT); pnl_vect_free(&divid); pnl_vect_free (&spot); pnl_vect_free (&sig); return res; }
static int Create_AndersenStruct(AndersenStruct *andersen_struct) { andersen_struct->DiscountedPayoff = pnl_mat_create(0,0); andersen_struct->NumeraireValue = pnl_mat_create(0,0); andersen_struct->AndersenParams = pnl_vect_create(0); andersen_struct->AndersenIndices = pnl_vect_int_create(0); return OK; }
Option::Option(double T, int timeStep, int size, double r, double *coeff){ T_ = T; timeStep_ = timeStep; size_ = size; r_ = r; Coeff_ = pnl_vect_create(size_); for (int i = 0; i < size_; i++){ LET(Coeff_, i) = coeff[i]; } }
/** * compute the sum of all element in the row of matrix * * @param[in] mat matrix * @param[in] nb_row the number of row * @return sum of all element in the row of matrix * */ static double sum_row_matrix(const PnlMat* mat,int nb_row) { double result; PnlVect* V=pnl_vect_create(mat->m); pnl_mat_get_row(V,mat,nb_row); result= pnl_vect_sum(V); pnl_vect_free(&V); return result; }
static double f1dim( double x) { int j; double val; PnlVect * xt = pnl_vect_create (_n); for(j=0; j<_n; j++){ pnl_vect_set (xt, j, pnl_vect_get (_p, j) + x * pnl_vect_get (_dir, j)); } val=func(xt); pnl_vect_free (&xt); return val; }
/// Prix at time s of an option, maturing at T, on a ZC, with maturity S, using a trinomial tree. double tr_bk1d_zcoption(TreeShortRate* Meth, ModelParameters* ModelParam, ZCMarketData* ZCMarket, double T, double S, NumFunc_1 *p, double r, int Eur_Or_Am) { int i_T; double OptionPrice; PnlVect* OptionPriceVect1; // Vector of prices of the option at time i PnlVect* OptionPriceVect2; // Vector of prices of the option at time i+1 PnlVect* ZCbondPriceVect1; // Vector of prices of the option at time i PnlVect* ZCbondPriceVect2; // Vector of prices of the option at time i+1 OptionPriceVect1 = pnl_vect_create(1); OptionPriceVect2 = pnl_vect_create(1); ZCbondPriceVect1 = pnl_vect_create(1); ZCbondPriceVect2 = pnl_vect_create(1); ///****************** Computation of the vector of payoff at the maturity of the option *******************/// i_T = IndexTime(Meth, T); // Localisation of s on the tree ZCBond_InitialPayoffBK1D(Meth, ZCbondPriceVect2); ZCOption_BackwardIterationBK1D(Meth, ModelParam, ZCbondPriceVect1, ZCbondPriceVect2, ZCbondPriceVect1, ZCbondPriceVect2, Meth->Ngrid, i_T, p, 0); ZCOption_InitialPayoffBK1D(ZCbondPriceVect2, OptionPriceVect2, p); ///****************** Backward computation of the option price until initial time s *******************/// ZCOption_BackwardIterationBK1D(Meth, ModelParam, ZCbondPriceVect1, ZCbondPriceVect2, OptionPriceVect1, OptionPriceVect2, i_T, 0, p, Eur_Or_Am); OptionPrice = GET(OptionPriceVect1, 0); pnl_vect_free(& OptionPriceVect1); pnl_vect_free(& OptionPriceVect2); pnl_vect_free(& ZCbondPriceVect1); pnl_vect_free(& ZCbondPriceVect2); return OptionPrice; }// FIN de la fonction ZCOption
static void tridiag_syslin_test () { PnlVect *b, *x, *Mx; PnlTridiagMat *M, *Mcopy; int n = 5; int gen = PNL_RNG_MERSENNE_RANDOM_SEED; pnl_rand_init (gen, 1, 1); x = pnl_vect_create (n); b = pnl_vect_create (n); pnl_vect_rand_normal (b, n, gen); M = create_random_tridiag (n, gen); Mcopy = pnl_tridiag_mat_copy (M); pnl_tridiag_mat_syslin (x, M, b); Mx = pnl_tridiag_mat_mult_vect (Mcopy, x); pnl_test_vect_eq_abs (Mx, b, 1E-12, "tridiag_mat_syslin", ""); pnl_vect_free (&x); pnl_vect_free (&Mx); pnl_vect_free (&b); pnl_tridiag_mat_free (&M); pnl_tridiag_mat_free (&Mcopy); }
/// Backward computation of the price of a Zero Coupon Bond static void ZCBond_BackwardIterationCIRpp1D(TreeCIRpp1D* Meth, ModelCIRpp1D* ModelParam, ZCMarketData* ZCMarket, PnlVect* OptionPriceVect1, PnlVect* OptionPriceVect2, int index_last, int index_first) { double a, b, sigma; double delta_t, sqrt_delta_t; double current_rate, current_x, x_middle; int i, h; int NumberNode, index; PnlVect* Probas; Probas = pnl_vect_create(3); ///********* Model parameters *********/// a = (ModelParam->MeanReversion); b = (ModelParam->LongTermMean); sigma = (ModelParam->Volatility); delta_t = GET(Meth->t, 1) - GET(Meth->t,0); // = t[i] - t[i-1] sqrt_delta_t = sqrt(delta_t); for(i = index_last-1; i>=index_first; i--) { NumberNode = (int) ((GET(Meth->Xmax, i) - GET(Meth->Xmin, i)) / (Meth->delta_x) + 0.1); pnl_vect_resize(OptionPriceVect1, NumberNode +1); // OptionPriceVect1 := Price of the bond in the tree at time t(i) // Loop over the node at the time i for(h = 0 ; h<= NumberNode ; h++) { current_x = x_value(i, h, Meth); current_rate = R(current_x, sigma) + GET(Meth->alpha,i); x_middle = MiddleNode(Meth, i, a, b, sigma, current_x, sqrt_delta_t, Probas); index = (int) ((x_middle-GET(Meth->Xmin,i+1))/(Meth->delta_x) + 0.1); LET(OptionPriceVect1,h) = exp(-current_rate*delta_t) * ( GET(Probas,2) * GET(OptionPriceVect2, index+1) + GET(Probas,1) * GET(OptionPriceVect2, index) + GET(Probas,0) * GET(OptionPriceVect2, index-1)); // Backward computation of the bond price } pnl_vect_clone(OptionPriceVect2, OptionPriceVect1); // Copy OptionPriceVect1 in OptionPriceVect2 } // END of the loop on i (time) pnl_vect_free(&Probas); }
// Read the ZC price from the file "initialyield.dat" and put it in the structure "ZCMarket". void ReadMarketData(ZCMarketData* ZCMarket) { FILE* Entrees; /*File variable of the code*/ int i, etat; char ligne[20]; char* pligne; double p, tt; char data[MAX_PATH_LEN]; sprintf(data, "%s", init); Entrees=fopen(data, "r"); if(Entrees==NULL) { printf("Le FICHIER N'A PU ETRE OUVERT. VERIFIER LE CHEMIN\n"); abort(); } i=0; // i represents the number of value read in the file pligne=ligne; ZCMarket->Pm = pnl_vect_create(100); ZCMarket->tm = pnl_vect_create_from_double(100, 0); while(1) { pligne=fgets(ligne, sizeof(ligne), Entrees); if(pligne==NULL) { break; } else { sscanf(ligne, "%lf t=%lf", &p, &tt); /* La ligne lue dans le fichier doit etre de la forme "0.943290 t=0.5" ou 0.943290 est un double pour le prix de B(0,t=0.5)*/ LET(ZCMarket->Pm,i) = p; /*enregistre le prix du zero coupon*/ LET(ZCMarket->tm,i) = tt; /*enreristre le temps correspondant*/ i++; } } etat=fclose(Entrees); ZCMarket->Nvalue = i; pnl_vect_resize(ZCMarket->Pm, i); pnl_vect_resize(ZCMarket->tm, i); }
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; } } }
static void prix(PnlMat *res, PnlMat *res_no_call, int M, int N, PnlMat *asset, PnlVectInt *res_theta, 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; Si=pnl_vect_new(); c_iplus1=pnl_vect_create(M); alpha=pnl_vect_new(); V_iplus1=pnl_vect_new(); pnl_mat_resize(res,N+1,M); prix_no_call(res_no_call,M,N,asset,spot,T,P,basis); for(j=0;j<M;j++) pnl_mat_set(res,N,j,(pnl_mat_get(res_no_call,N,j))); 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); if(i>=pnl_vect_int_get(res_theta,j)) { pnl_mat_set(res,i,j,pnl_mat_get(res_no_call,i,j));} else pnl_mat_set(res,i,j,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=MAX(low(spot,P),exp(-mu(spot,spot,P)*h)*v0); for(j=0;j<M;j++) { if(pnl_vect_int_get(res_theta,j)==0) pnl_mat_set(res,0,j,pnl_mat_get(res_no_call,i,j)); else pnl_mat_set(res,0,j,v0); } pnl_vect_free(&Si); pnl_vect_free(&c_iplus1); pnl_vect_free(&V_iplus1); pnl_vect_free(&alpha); }
static int MET(Init)(PricingMethod *Met,Option *Opt) { TYPEOPT *opt = (TYPEOPT*)(Opt->TypeOpt); if ( Met->init == 0) { Met->init=1; Met->Res[1].Val.V_PNLVECT=NULL; } /* some initialisation */ if(Met->Res[1].Val.V_PNLVECT==NULL) Met->Res[1].Val.V_PNLVECT=pnl_vect_create(opt->Size.Val.V_PINT); else pnl_vect_resize(Met->Res[1].Val.V_PNLVECT,opt->Size.Val.V_PINT); return OK; }
double Barrier_u :: payoff ( double t, const PnlMat* path) const { double sum ; //Vecteur utilisé pour effectuer la somme de chaque actif à maturité 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, timeStep_); sum = pnl_vect_scalar_prod(final, Coeff_) - strike_; //On vérifie que toutes les valeurs des sous-jacents soient en dessous de la barrière //Si on en trouve une alors le prix de l'option est de 0 for (int i=0; i<timeStep_+1; i++){ for (int d=0; d<size_; d++){ if (MGET(path,d,i) > pnl_vect_get(Bu_,d)){ pnl_vect_free(&final); return 0; } } }
double f_by_density(params *p) { int N ; double m_dVarianceCurve; double m_dGamma ; double m_dOmega1 ; double m_dOmega2 ; double m_dCorrel; int path,i ; double sup ; PnlVect *axis; double res ; N = p->n; m_dVarianceCurve= p->VarianceCurve; m_dGamma = p->Gamma; m_dOmega1 = p->Omega1; m_dOmega2 = p->Omega2; m_dCorrel = p->Correl; path = 2000; sup = 12; axis = pnl_vect_create(path); res = 0; for ( i = 0; i < path; i++) pnl_vect_set(axis,i, -sup + 2 * sup * i / (double)path); for ( i = 0; i < path - 1; i++) res += (pnl_vect_get(axis,i + 1) - pnl_vect_get(axis,i)) * sqrt(m_dVarianceCurve * (1 - m_dGamma) * exp(m_dOmega1 * pnl_vect_get(axis,i) - m_dOmega1 * m_dOmega1 / 2.0) + m_dVarianceCurve * m_dGamma * exp(m_dOmega2 * pnl_vect_get(axis,i) - m_dOmega2 * m_dOmega2 / 2.0)) * exp(-pnl_vect_get(axis,i) * pnl_vect_get(axis,i) / 2.0) / sqrt(2.0 *M_PI); return res; }
static int cf_swaption_direct_libaff_cir1d(int InitYieldCurve_flag, double R_flat, char *curve, double x0, double lambda, double theta, double eta, double swaption_start, double swaption_end, double swaption_period, double swaption_strike, double swaption_nominal, int swaption_payer_receiver, double *swaption_price) { StructLiborAffine LiborAffine; ZCMarketData ZCMarket; PnlVect *ModelParams=pnl_vect_create(4); ZCMarket.filename = curve; SetInitYieldCurve(InitYieldCurve_flag, R_flat, &ZCMarket); LET(ModelParams, 0) = x0; LET(ModelParams, 1) = lambda; LET(ModelParams, 2) = theta; LET(ModelParams, 3) = eta; CreateStructLiborAffine(&LiborAffine, &ZCMarket, swaption_start, swaption_end, swaption_period, ModelParams, &phi_psi_cir1d, &MaxMgfArg_cir1d); *swaption_price = cf_swaption_direct(&LiborAffine, swaption_start, swaption_end, swaption_period, swaption_strike, swaption_nominal, swaption_payer_receiver); FreeStructLiborAffine(&LiborAffine); return OK; }
double put_by_density(double k, params *p) { int N ; double m_dVarianceCurve; double m_dGamma ; double m_dOmega1 ; double m_dOmega2 ; double m_dCorrel; int path,i ; double inf ; PnlVect *axis; double strikeMax, res; N = p->n; m_dVarianceCurve= p->VarianceCurve; m_dGamma = p->Gamma; m_dOmega1 = p->Omega1; m_dOmega2 = p->Omega2; m_dCorrel = p->Correl; path = 2000; inf = -12; axis = pnl_vect_create(path); strikeMax = z(k * k,p); res = 0; for (i = 0; i < path; i++) pnl_vect_set(axis,i,inf + (i + 1) * (strikeMax - inf) / (double)path); for (i = 0; i < path - 1; i++) res += (pnl_vect_get(axis,i+1) - pnl_vect_get(axis,i)) * MAX(k - sqrt(g(pnl_vect_get(axis,i),p)), 0.0) * exp(-pnl_vect_get(axis,i) * pnl_vect_get(axis,i) / 2.0) / sqrt(2.0 * M_PI); return res; }
double call_by_density(double k, params *p) { int N ; double m_dVarianceCurve; double m_dGamma ; double m_dOmega1 ; double m_dOmega2 ; double m_dCorrel; int path,i ; double sup ; PnlVect *axis; double strikeMin, res; N = p->n; m_dVarianceCurve= p->VarianceCurve; m_dGamma = p->Gamma; m_dOmega1 = p->Omega1; m_dOmega2 = p->Omega2; m_dCorrel = p->Correl; path = 2000; sup = 12; axis = pnl_vect_create(path); strikeMin = z(k * k,p); res = 0; for (i = 0; i < path; i++) pnl_vect_set(axis,i,strikeMin + sup * i / (double)path); for (i = 0; i < path - 1; i++) res += (pnl_vect_get(axis,i+1) - pnl_vect_get(axis,i)) * MAX(sqrt(g(pnl_vect_get(axis,i),p)) - k, 0.0) * exp(-pnl_vect_get(axis,i) * pnl_vect_get(axis,i) / 2.0) / sqrt(2.0 * M_PI); return res; }
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); }
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); }