Esempio n. 1
0
static void
findstats(Pos p, Ori o)
{
	/* Recalculate cross assert and score total at 'p'
	 */
	Pos	left, right;
	Word lword, rword;
	Node n;
	Edge e;
	int	s;

	lword.n = rword.n = 0;
	if(EDGE(p))
		return;

	/* find word to the left */
	s = 0;
	for(left=PREV(p,o); HASLETTER(left); left = PREV(left,o))
		;
	left = NEXT(left,o);
	while (HASLETTER(left)) {
		lword.c[lword.n++] = LETTER(left);
		s += SCORE(left);
		left = NEXT(left,o);
	}
	/* find word to the right */
	for(right=NEXT(p,o); HASLETTER(right); right = NEXT(right,o)) {
		rword.c[rword.n++] = LETTER(right);
		s += SCORE(right);
	}
	if(DBG) {
		wordprint(&lword);
		print("X");
		wordprint(&rword);
		print(" [%d] ", s);
	}

	SIDE(p,o) = s;
	ISANCHOR(p) = true;

	/* calculate cross asserts */
	CROSS(p,o) = 0;
	n = traverse(root, &lword, 0);
	assert(n>=0);
	if(n>0)
		do {
			e = dict[n++];
			if ( (rword.n && isword(NODE(e), &rword)) || 
				 (!rword.n && TERM(e)) ) {
				CROSS(p,o) |= 1 << LET(e);
				DPRINT("%c, ", LET(e)+'a');
			}
		} while (!(LAST(e)));
	DPRINT("\n");
}
Esempio n. 2
0
static SCM
expand_let (SCM expr, SCM env)
{
  SCM bindings;

  const SCM cdr_expr = CDR (expr);
  const long length = scm_ilength (cdr_expr);
  ASSERT_SYNTAX (length >= 0, s_bad_expression, expr);
  ASSERT_SYNTAX (length >= 2, s_missing_expression, expr);

  bindings = CAR (cdr_expr);
  if (scm_is_symbol (bindings))
    {
      ASSERT_SYNTAX (length >= 3, s_missing_expression, expr);
      return expand_named_let (expr, env);
    }

  check_bindings (bindings, expr);
  if (scm_is_null (bindings))
    return expand_sequence (CDDR (expr), env);
  else
    {
      SCM var_names, var_syms, inits;
      transform_bindings (bindings, expr, &var_names, &var_syms, &inits);
      return LET (SCM_BOOL_F,
                  var_names, var_syms, expand_exprs (inits, env),
                  expand_sequence (CDDR (expr),
                                   expand_env_extend (env, var_names,
                                                      var_syms)));
    }
}
Esempio n. 3
0
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];
	}
}
// Scalar function to be minimized in order to get optimal parameters.
static double func_to_minimize(double x, void *andersen_struct)
{
  LET(((AndersenStruct*)andersen_struct)->AndersenParams, ((AndersenStruct*)andersen_struct)->j_start) = x;

  return -AmOption_Price_Andersen(andersen_struct);

}
Esempio n. 5
0
// 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);
}
Esempio n. 6
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.;
  }
Esempio n. 7
0
void Levy_fourier_stiffness(PnlVectComplex *Levy_sinus,double hx,int bnd,int Nw,double hw,int kmin,int kmax,PnlVect *row_stiffness)
{
  PnlVectComplex *cos_sin_vect;
  int i,k,m;
  double tmp;
  cos_sin_vect=pnl_vect_complex_create(Nw);
  pnl_vect_resize(row_stiffness,kmax-kmin+1);
  tmp=-bnd*M_PI;
  for (i=0;i<Nw;i++)
    {
      pnl_vect_complex_set(cos_sin_vect,i,CIexp(tmp));
      tmp+=hw;
    }
  for(k=-1;k>=kmin;k--)
    {
      tmp=0;
      m=0;
      for (i=0;i<Nw;i++)
        {
          
          tmp+=GET_REAL(Levy_sinus,i)*GET_REAL(cos_sin_vect,m)+GET_IMAG(Levy_sinus,i)*GET_IMAG(cos_sin_vect,m);
          m-=k;
          m=m%(Nw);
        }
      LET(row_stiffness,k-kmin)=tmp*hw*1/(M_2PI);
    }
  for(k=0;k<=kmax;k++)
    {
      tmp=0;
      m=0;
      for (i=0;i<Nw;i++)
        {
          tmp+=GET_REAL(Levy_sinus,i)*GET_REAL(cos_sin_vect,m)-GET_IMAG(Levy_sinus,i)*GET_IMAG(cos_sin_vect,m);
          m+=k;
          m=m%Nw;
          
        }
      LET(row_stiffness,k-kmin)=tmp*hw*1/(M_2PI);
    }
  if(bnd%2==1)
    for(k=kmin;k<=kmax;k++)
      if(k-kmin%2==0)
        LET(row_stiffness,k-kmin)*=-1;
    
  pnl_vect_complex_free(&cos_sin_vect);
}
Esempio n. 8
0
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];
	}
}
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;
}
/// Computation of the payoff at the final time of the tree (ie the option maturity)
static void BermudianSwaption_InitialPayoffHW1D(int swaption_start, TreeHW1dG* Meth, ModelHW1dG* HW1dG_Parameters, ZCMarketData* ZCMarket, PnlVect* OptionPriceVect2, NumFunc_1 *p, double periodicity,double contract_maturity, double SwaptionFixedRate)
{
    double sigma;

    int jminprev, jmaxprev; // jmin[i], jmax [i]
    int i,j;

    double delta_x1; // delta_x1 = space step of the process x at time i
    double delta_t1; // time step

    double ZCPrice, SumZC;
    double current_rate;

    int NumberOfPayments;
    double Ti;

    ZCPrice = 0.0;

    ///** Calcul du vecteur des payoffs a l'instant de maturite de l'option
    jminprev = pnl_vect_int_get(Meth->Jminimum, swaption_start);   // jmin(swaption_start)
    jmaxprev = pnl_vect_int_get(Meth->Jmaximum, swaption_start);  // jmax(swaption_start)

    pnl_vect_resize(OptionPriceVect2, jmaxprev-jminprev+1);

    delta_t1 = GET(Meth->t, swaption_start) - GET(Meth->t,swaption_start-1);
    sigma = Current_VolatilityHW1dG(HW1dG_Parameters, GET(Meth->t, swaption_start));
    delta_x1 = SpaceStepHW1dG(delta_t1, sigma);//SpaceStepHW1dG(delta_t1, a, sigma);

    NumberOfPayments = (int) floor((contract_maturity-GET(Meth->t, swaption_start) )/periodicity + 0.2);


    p->Par[0].Val.V_DOUBLE = 1.0;

    for( j = jminprev ; j<=jmaxprev ; j++)
    {
        current_rate = j * delta_x1 + GET(Meth->alpha, swaption_start); // rate(Ngrid, j )

        SumZC = 0;
        for(i=1; i<=NumberOfPayments; i++)
        {
            Ti = GET(Meth->t, swaption_start) + i*periodicity;
            ZCPrice = DiscountFactor(ZCMarket, HW1dG_Parameters, GET(Meth->t, swaption_start), Ti, current_rate);

            SumZC += ZCPrice;
        }


        LET(OptionPriceVect2, j-jminprev) = ((p->Compute)(p->Par, periodicity * SwaptionFixedRate * SumZC + ZCPrice));
    }

}
Esempio n. 11
0
/// Computation of the payoff at the final time of the tree (ie the option maturity)
static void CapFloor_InitialPayoffLRS1D(TreeLRS1D* Meth, ModelLRS1D* ModelParam, ZCMarketData* ZCMarket, PnlVect* OptionPriceVect2, NumFunc_1 *p, double T1, double T2, double CapFloorFixedRate)
{
    double sigma, rho, kappa, lambda;

    int j, h;
    double delta_y, delta_t, sqrt_delta_t;
    double y_00, y_ih, r_ih, phi_ihj;

    double ZCPrice;

    int  i_T1;
    double periodicity;

    /// Model Parameters
    kappa = (ModelParam->Kappa);
    sigma = (ModelParam->Sigma);
    rho = (ModelParam->Rho);
    lambda = (ModelParam->Lambda);

    /// Computation of the vector of payoff at the maturity of the option
    periodicity = T2 - T1;
    i_T1 = indiceTimeLRS1D(Meth, T1);

    pnl_vect_resize(OptionPriceVect2, 6*i_T1 - 3);

    delta_t = GET(Meth->t, i_T1+1) - GET(Meth->t,i_T1);
    sqrt_delta_t = sqrt(delta_t);
    delta_y = lambda * sqrt_delta_t;

    y_00 = r_to_y(ModelParam, -log(BondPrice(GET(Meth->t, 1), ZCMarket))/GET(Meth->t, 1));

    p->Par[0].Val.V_DOUBLE = 1.0 ;

    for( h=0; h<=2*i_T1; h++) /// h : numero de la box
    {
        y_ih = y_00 + (i_T1-h) * delta_y;
        r_ih = y_to_r(ModelParam, y_ih);

        for(j=0;j<number_phi_in_box(i_T1, h);j++) /// Boucle sur les  valeurs de phi à (i,h)
        {
            phi_ihj = phi_value(Meth, i_T1, h, j);

            ZCPrice = cf_lrs1d_zcb(ZCMarket, T1, r_ih, phi_ihj, kappa, sigma, rho, lambda, T2);

            LET(OptionPriceVect2, index_tree(i_T1, h, j)) = (p->Compute)(p->Par, (1+periodicity*CapFloorFixedRate)*ZCPrice);

        }
    }

}
Esempio n. 12
0
// Use results on trigonometric function.
void Levy_process_fourier_stiffness_0(Levy_process * mod,double hx,double bnd_fourier,int Nw,int kmin,int kmax,int Dupire,PnlVect *row_stiffness)
{
  double abserr;
  int k,neval;
  RFourierFunc RF;
  PnlFunc Func;
  double A=12.56;
  double epsabs=1e-15;
  double epsrel=1e-15;
  RF.Dupire=Dupire;
  RF.hx=hx;
  RF.Model=mod;
  Func.params=&RF;
  Func.function=&RFourierFuncEvaluation_Void;
  pnl_vect_resize(row_stiffness,kmax-kmin+1);
  for(k=kmin;k<=kmax;k++)
    {
      RF.k=k;
      pnl_integration_GK(&Func,-A,A,epsabs,epsrel,&LET(row_stiffness,k-kmin),&abserr,&neval);
      LET(row_stiffness,k-kmin)/=M_2PI;
    }
  printf("sum of Row stiffness %e \n",pnl_vect_sum(row_stiffness));
  pnl_vect_print(row_stiffness);
}
Esempio n. 13
0
static SCM
expand_cond_clauses (SCM clause, SCM rest, int elp, int alp, SCM env)
{
  SCM test;
  const long length = scm_ilength (clause);
  ASSERT_SYNTAX (length >= 1, s_bad_cond_clause, clause);

  test = CAR (clause);
  if (scm_is_eq (test, scm_sym_else) && elp)
    {
      const int last_clause_p = scm_is_null (rest);
      ASSERT_SYNTAX (length >= 2, s_bad_cond_clause, clause);
      ASSERT_SYNTAX (last_clause_p, s_misplaced_else_clause, clause);
      return expand_sequence (CDR (clause), env);
    }

  if (scm_is_null (rest))
    rest = VOID (SCM_BOOL_F);
  else
    rest = expand_cond_clauses (CAR (rest), CDR (rest), elp, alp, env);

  if (length >= 2
      && scm_is_eq (CADR (clause), scm_sym_arrow)
      && alp)
    {
      SCM tmp = scm_gensym (scm_from_locale_string ("cond "));
      SCM new_env = scm_acons (tmp, tmp, env);
      ASSERT_SYNTAX (length > 2, s_missing_recipient, clause);
      ASSERT_SYNTAX (length == 3, s_extra_expression, clause);
      return LET (SCM_BOOL_F,
                  scm_list_1 (tmp),
                  scm_list_1 (tmp),
                  scm_list_1 (expand (test, env)),
                  CONDITIONAL (SCM_BOOL_F,
                               LEXICAL_REF (SCM_BOOL_F, tmp, tmp),
                               CALL (SCM_BOOL_F,
                                     expand (CADDR (clause), new_env),
                                     scm_list_1 (LEXICAL_REF (SCM_BOOL_F,
                                                              tmp, tmp))),
                               rest));
    }
  /* FIXME length == 1 case */
  else
    return CONDITIONAL (SCM_BOOL_F,
                        expand (test, env),
                        expand_sequence (CDR (clause), env),
                        rest);
}
Esempio n. 14
0
static void fcn_lsq(const PnlVect *x, PnlVect *fvec, void *p)
{
  int i;
  double tmp1, tmp2, tmp3;
  double y[15] = {1.4e-1, 1.8e-1, 2.2e-1, 2.5e-1, 2.9e-1, 3.2e-1, 3.5e-1,
		  3.9e-1, 3.7e-1, 5.8e-1, 7.3e-1, 9.6e-1, 1.34, 2.1, 4.39};

  for (i = 0; i < 15; i++)
    {
      tmp1 = i+1;
      tmp2 = 15 - i;
      tmp3 = tmp1;
      if (i > 7) tmp3 = tmp2;
      LET(fvec,i) = y[i] - (GET(x,0) + tmp1/(GET(x,1)*tmp2 + GET(x,2)*tmp3));
    }
}
Esempio n. 15
0
/// 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);
}
/// Computation of the payoff at the final time of the tree (ie the option maturity)
static void ZCOption_InitialPayoffBK1D(PnlVect* ZCbondPriceVect, PnlVect* OptionPriceVect, NumFunc_1 *p)
{
    int j;

    double ZCPrice;

    pnl_vect_resize(OptionPriceVect, ZCbondPriceVect->size);

    ///** Calcul du vecteur des payoffs a l'instant de maturite de l'option

    for( j = 0 ; j<ZCbondPriceVect->size ; j++)
    {
        ZCPrice = GET(ZCbondPriceVect, j);

        LET(OptionPriceVect, j) = (p->Compute)(p->Par, ZCPrice); // Payoff of the option
    }
}
Esempio n. 17
0
static void fcn_fsolve(const PnlVect *x, PnlVect *fvec, void *p)
{
  /*      subroutine fcn for hybrd example. */

  int k, n;
  double one=1, temp, temp1, temp2, three=3, two=2, zero=0;

  n = x->size;
  pnl_vect_resize (fvec, n);
  for (k=0; k<n; k++)
    {
      
      temp = (three - two*GET(x,k))*GET(x,k);
      temp1 = zero;
      if (k != 0) temp1 = GET(x,k-1);
      temp2 = zero;
      if (k != n-1) temp2 = GET(x,k+1);
      LET(fvec,k) = temp - temp1 - two*temp2 + one;
    }
}
Esempio n. 18
0
static SCM
expand_letstar_clause (SCM bindings, SCM body, SCM env SCM_UNUSED)
{
  if (scm_is_null (bindings))
    return expand_sequence (body, env);
  else
    {
      SCM bind, name, sym, init;

      ASSERT_SYNTAX (scm_is_pair (bindings), s_bad_expression, bindings);
      bind = CAR (bindings);
      ASSERT_SYNTAX (scm_ilength (bind) == 2, s_bad_binding, bind);
      name = CAR (bind);
      sym = scm_gensym (SCM_UNDEFINED);
      init = CADR (bind);
      
      return LET (SCM_BOOL_F, scm_list_1 (name), scm_list_1 (sym),
                  scm_list_1 (expand (init, env)),
                  expand_letstar_clause (CDR (bindings), body,
                                         scm_acons (name, sym, env)));
    }
}
Esempio n. 19
0
static SCM
expand_or (SCM expr, SCM env SCM_UNUSED)
{
  SCM tail = CDR (expr);
  const long length = scm_ilength (tail);

  ASSERT_SYNTAX (length >= 0, s_bad_expression, expr);

  if (scm_is_null (CDR (expr)))
    return CONST (SCM_BOOL_F, SCM_BOOL_F);
  else
    {
      SCM tmp = scm_gensym (SCM_UNDEFINED);
      return LET (SCM_BOOL_F,
                  scm_list_1 (tmp), scm_list_1 (tmp),
                  scm_list_1 (expand (CADR (expr), env)),
                  CONDITIONAL (SCM_BOOL_F,
                               LEXICAL_REF (SCM_BOOL_F, tmp, tmp),
                               LEXICAL_REF (SCM_BOOL_F, tmp, tmp),
                               expand_or (CDR (expr),
                                          scm_acons (tmp, tmp, env))));
    }
}
// We interpolate linearly the parameters of exercise strategy between intermidiate exercise dates.
static int Interpolate_AndersenParams(AndersenStruct *andersen_struct)
{
  int i, j, q, j1, j2;
  double a, b;

  q = andersen_struct->q;

  for (i=0; i<q; i++)
    {
      j1 = pnl_vect_int_get(andersen_struct->AndersenIndices, i);
      j2 = pnl_vect_int_get(andersen_struct->AndersenIndices, i+1);

      for (j=j1; j<=j2; j++)
        {
          a = ((double)(j-j1))/((double)(j2-j1));
          b = ((double)(j2-j))/((double)(j2-j1));

          LET(andersen_struct->AndersenParams, j) = a*GET(andersen_struct->AndersenParams, j2) + b*GET(andersen_struct->AndersenParams, j1);
        }

    }

  return OK;
}
// Compute the price of a bermudan swaption.
static int MC_BermSwpaption_Andersen(NumFunc_1 *p, Libor *ptLib, Swaption *ptBermSwpt, Volatility *ptVol, double Nominal, long NbrMCsimulation_param, long NbrMCsimulation, int NbrStepPerTenor, int generator, int flag_numeraire, int q, double *PriceBermSwp)
{
  int alpha, beta, i, NbrExerciseDates;
  double tenor, numeraire_0;
  double ax, bx,  cx, tol, xmin;

  AndersenStruct andersen_struct;
  PnlFunc FuncToMinimize;

  Create_AndersenStruct(&andersen_struct);

  //Nfac = ptVol->numberOfFactors;
  //N = ptLib->numberOfMaturities;
  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;
  

  numeraire_0 = Numeraire(0, ptLib, flag_numeraire);

  tol = 1e-10;
  q = MIN(q, NbrExerciseDates-1); // The maximum number of kink-points that can be used is NbrExerciseDates-1.
  q = MAX(1, q); // q must be greater than zero.

  FuncToMinimize.function = &func_to_minimize;
  FuncToMinimize.params = &andersen_struct;

  // Initialize the structure andersen_struct using "NbrMCsimulation_param" paths.
  // We will use these paths to estimates the optimal parameters of exercise strategy.
  Init_AndersenStruct(&andersen_struct, ptLib, ptBermSwpt, ptVol, p, NbrMCsimulation_param, NbrStepPerTenor, generator, flag_numeraire, Nominal, q);

  // At maturity, the parameter is null, because we exercise whenever payoff is positif.
  pnl_vect_set_zero(andersen_struct.AndersenParams);

  ax = 0; // lower point for GoldenSearch method
  cx = andersen_struct.H_max; // upper point for GoldenSectionSearch method
  bx = 0.5*(ax+cx); // middle point for GoldenSectionSearch method

  for (i=q-1; i>=0; i--)
    {
      // Index of exercise date where we compute parameter of exercise strategy.
      andersen_struct.j_start = pnl_vect_int_get(andersen_struct.AndersenIndices, i);

      // Find optimal parameter at current exercise date.
      golden(&FuncToMinimize, ax, bx, cx, tol, &xmin);

      // Store this parameter in AndersenParams.
      LET(andersen_struct.AndersenParams, andersen_struct.j_start) = xmin;

      ax = 0.5*xmin;
      bx = 0.5*(ax+cx);
    }

  // We simulate another set of Libor paths, independants of the ones used to estimate the parameters of exercise strategy.
  // In general, choose NbrMCsimulation >> NbrMCsimulation_param.
  Init_AndersenStruct(&andersen_struct, ptLib, ptBermSwpt, ptVol, p, NbrMCsimulation, NbrStepPerTenor, generator, flag_numeraire, Nominal, q);

  // Finaly, we use the found parameters to estimate the price of bermudan swaption following.
  andersen_struct.j_start = 0;
  *PriceBermSwp = numeraire_0*AmOption_Price_Andersen(&andersen_struct);

  // Free memory.
  Free_AndersenStruct(&andersen_struct);

  return OK;
}
Esempio n. 22
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);
}
Esempio n. 23
0
/// Backward computation of the price of a Zero Coupon Bond
static void CapFloor_BackwardIterationLRS1D(TreeLRS1D* Meth, ModelLRS1D* ModelParam, ZCMarketData* ZCMarket, PnlVect* OptionPriceVect1, PnlVect* OptionPriceVect2, int index_last, int index_first)
{
    double sigma, rho, kappa, lambda;

    int i, j, h;
    double delta_y, delta_t, sqrt_delta_t;
    double price_up, price_middle, price_down;
    double y_00, y_ih, r_ih, phi_ihj, phi_next;


    PnlVect* proba_from_ij;

    proba_from_ij = pnl_vect_create(3);


    ///********* Model parameters *********///
    kappa = (ModelParam->Kappa);
    sigma = (ModelParam->Sigma);
    rho = (ModelParam->Rho);
    lambda = (ModelParam->Lambda);

    delta_t = GET(Meth->t, 1) - GET(Meth->t,0);
    y_00 = r_to_y(ModelParam, -log(BondPrice(GET(Meth->t, 1), ZCMarket))/delta_t);

    for(i = index_last-1; i>=index_first; i--)
    {
        pnl_vect_resize(OptionPriceVect1, 6*i-3);  // OptionPriceVect1 := Price of the bond in the tree at time t(i)

        delta_t = GET(Meth->t, i+1) - GET(Meth->t,i);
        sqrt_delta_t = sqrt(delta_t);
        delta_y = lambda * sqrt_delta_t;

        for( h=0; h<=2*i; h++) /// h : numero de la box
        {
            y_ih = y_00 + (i-h) * delta_y;
            r_ih = y_to_r(ModelParam, y_ih);

            for(j=0;j<number_phi_in_box(i, h);j++) /// Boucle sur les  valeurs de phi à (i,h)
            {
                phi_ihj = phi_value(Meth, i, h, j);

                phi_next = phi_ihj * (1-2*kappa*delta_t) + SQR(sigma) * pow(y_to_r(ModelParam, y_ih), (2*rho)) * delta_t;

                price_up     = Interpolation(Meth, i+1, h  , OptionPriceVect2, phi_next);
                price_middle = Interpolation(Meth, i+1, h+1, OptionPriceVect2, phi_next);
                price_down   = Interpolation(Meth, i+1, h+2, OptionPriceVect2, phi_next);

                probabilities(GET(Meth->t,i), y_ih, phi_ihj, lambda, sqrt_delta_t, ModelParam, ZCMarket, proba_from_ij);

                LET(OptionPriceVect1, index_tree(i,h,j)) = exp(-r_ih*delta_t) * (GET(proba_from_ij,0) * price_up + GET(proba_from_ij,1) * price_middle + GET(proba_from_ij,2) * price_down );

            }
        }

        pnl_vect_clone(OptionPriceVect2, OptionPriceVect1); // Copy OptionPriceVect1 in OptionPriceVect2

    } // END of the loop on i (time)

    pnl_vect_free(&proba_from_ij);

}
/// Price of a bermudianswaption using a trinomial tree
static double tr_hw1dg_bermudianswaption(TreeHW1dG* Meth, ModelHW1dG* HW1dG_Parameters, ZCMarketData* ZCMarket,int NumberOfTimeStep, NumFunc_1 *p, double r, double periodicity,double option_maturity,double contract_maturity, double SwaptionFixedRate)
{
    double delta_t1; // time step
    double Pup, Pmiddle, Pdown;
    int i,j;
    double Ti2, Ti1;
    int i_Ti2, i_Ti1;
    double current_rate, NumberOfPayments;
    double OptionPrice;

    PnlVect* PayoffVect;
    PnlVect* OptionPriceVect1; // Vector of prices of the option at i
    PnlVect* OptionPriceVect2; // Vector of prices of the option at i+1
    OptionPriceVect1 = pnl_vect_create(1);
    OptionPriceVect2 = pnl_vect_create(1);
    PayoffVect = pnl_vect_create(1);

    //mean_reversion = (HW1dG_Parameters->MeanReversion);

    ///****************** Computation of the vector of payoff at the maturity of the option *******************///
    Ti1 = contract_maturity-periodicity;
    i_Ti1 = IndexTimeHW1dG(Meth, Ti1);
    BermudianSwaption_InitialPayoffHW1D(i_Ti1, Meth, HW1dG_Parameters, ZCMarket, OptionPriceVect2, p, periodicity, contract_maturity, SwaptionFixedRate);

    ///****************** Backward computation of the option price until initial time s *******************///

    NumberOfPayments = (int) floor((contract_maturity-option_maturity )/periodicity + 0.2);

    for(i=NumberOfPayments-2 ; i>=0 ; i--)
    {
        Ti1 = option_maturity + i * periodicity;
        Ti2 = Ti1 + periodicity;
        i_Ti2 = IndexTimeHW1dG(Meth, Ti2);
        i_Ti1 = IndexTimeHW1dG(Meth, Ti1);

        BackwardIterationHW1dG(Meth, HW1dG_Parameters, OptionPriceVect1, OptionPriceVect2, i_Ti2, i_Ti1);

        BermudianSwaption_InitialPayoffHW1D(i_Ti1, Meth, HW1dG_Parameters, ZCMarket, PayoffVect, p, periodicity, contract_maturity, SwaptionFixedRate);

        for(j=0;j<PayoffVect->size;j++)
        {
            if(GET(PayoffVect,j)>GET(OptionPriceVect2,j))
            {
                LET(OptionPriceVect2,j)=GET(PayoffVect,j);
            }
        }

    }

    BackwardIterationHW1dG(Meth, HW1dG_Parameters, OptionPriceVect1, OptionPriceVect2, i_Ti1, 1);

    Pup = 1.0 / 6.0;
    Pmiddle = 2.0 /3.0 ;
    Pdown = 1.0 / 6.0;

    delta_t1 = GET(Meth->t, 1) - GET(Meth->t,0);
    current_rate = GET(Meth->alpha, 0); // r(0,j)
    OptionPrice = exp(-current_rate*delta_t1) * ( Pup * GET(OptionPriceVect2, 2) + Pmiddle * GET(OptionPriceVect2,1) + Pdown * GET(OptionPriceVect2, 0));

    pnl_vect_free(& OptionPriceVect1);
    pnl_vect_free(& OptionPriceVect2);
    pnl_vect_free(& PayoffVect);

    return OptionPrice;

}
Esempio n. 25
0
int
arch_pdp11_translate_instr(cpu_t *cpu, addr_t pc, BasicBlock *bb) {
	uint16_t opcode = cpu->RAM[pc];

//LOG("%s:%d PC=$%04X\n", __func__, __LINE__, pc);

	switch (get_instr(opcode)) {
		/* flags */
		case INSTR_CLC:	LET1(cpu->ptr_C, FALSE);				break;
		case INSTR_CLD:	LET1(ptr_D, FALSE);				break;
		case INSTR_CLI:	LET1(ptr_I, FALSE);				break;
		case INSTR_CLV:	LET1(cpu->ptr_V, FALSE);				break;
		case INSTR_SEC:	LET1(cpu->ptr_C, TRUE);				break;
		case INSTR_SED:	LET1(ptr_D, TRUE);				break;
		case INSTR_SEI:	LET1(ptr_I, TRUE);				break;

		/* register transfer */
		case INSTR_TAX:	SET_NZ(LET(X,R(A)));			break;
		case INSTR_TAY:	SET_NZ(LET(Y,R(A)));			break;
		case INSTR_TXA:	SET_NZ(LET(A,R(X)));			break;
		case INSTR_TYA:	SET_NZ(LET(A,R(Y)));			break;
		case INSTR_TSX:	SET_NZ(LET(X,R(S)));			break;
		case INSTR_TXS:	SET_NZ(LET(S,R(X)));			break;

		/* load */
		case INSTR_LDA:	SET_NZ(LET(A,OPERAND));			break;
		case INSTR_LDX:	SET_NZ(LET(X,OPERAND));			break;
		case INSTR_LDY:	SET_NZ(LET(Y,OPERAND));			break;

		/* store */
		case INSTR_STA:	STORE(R(A),LOPERAND);			break;
		case INSTR_STX:	STORE(R(X),LOPERAND);			break;
		case INSTR_STY:	STORE(R(Y),LOPERAND);			break;

		/* stack */
		case INSTR_PHA:	PUSH(R(A));						break;
		case INSTR_PHP:	PUSH(arch_flags_encode(cpu, bb));	break;
		case INSTR_PLA:	SET_NZ(LET(A,PULL));			break;
		case INSTR_PLP:	arch_flags_decode(cpu, PULL, bb);	break;

		/* shift */
		case INSTR_ASL:	SET_NZ(SHIFTROTATE(LOPERAND, LOPERAND, true, false));	break;
		case INSTR_LSR:	SET_NZ(SHIFTROTATE(LOPERAND, LOPERAND, false, false));	break;
		case INSTR_ROL:	SET_NZ(SHIFTROTATE(LOPERAND, LOPERAND, true, true));	break;
		case INSTR_ROR:	SET_NZ(SHIFTROTATE(LOPERAND, LOPERAND, false, true));	break;

		/* bit logic */
		case INSTR_AND:	SET_NZ(LET(A,AND(R(A),OPERAND)));			break;
		case INSTR_ORA:	SET_NZ(LET(A,OR(R(A),OPERAND)));			break;
		case INSTR_EOR:	SET_NZ(LET(A,XOR(R(A),OPERAND)));			break;
		case INSTR_BIT:	SET_NZ(OPERAND);							break;

		/* arithmetic */
		case INSTR_ADC:	SET_NZ(ADC(ptr_A, ptr_A, OPERAND, true, false));		break;
		case INSTR_SBC:	SET_NZ(ADC(ptr_A, ptr_A, COM(OPERAND), true, false));	break;
		case INSTR_CMP:	SET_NZ(ADC(NULL, ptr_A, COM(OPERAND), false, true));		break;
		case INSTR_CPX:	SET_NZ(ADC(NULL, ptr_X, COM(OPERAND), false, true));		break;
		case INSTR_CPY:	SET_NZ(ADC(NULL, ptr_Y, COM(OPERAND), false, true));		break;

		/* increment/decrement */
		case INSTR_INX:	SET_NZ(LET(X,INC(R(X))));			break;
		case INSTR_INY:	SET_NZ(LET(Y,INC(R(Y))));			break;
		case INSTR_DEX:	SET_NZ(LET(X,DEC(R(X))));			break;
		case INSTR_DEY:	SET_NZ(LET(Y,DEC(R(Y))));			break;

		case INSTR_INC:	SET_NZ(STORE(INC(OPERAND),LOPERAND));			break;
		case INSTR_DEC:	SET_NZ(STORE(DEC(OPERAND),LOPERAND));			break;
		
		/* control flow */
		case INSTR_JMP:
			if (get_addmode(opcode) == ADDMODE_IND) {
				Value *v = LOAD_RAM16(CONST32(OPERAND_16));
				new StoreInst(v, cpu->ptr_PC, bb);
			}
			break;
		case INSTR_JSR:	PUSH16(pc+2);						break;
		case INSTR_RTS:	STORE(ADD(PULL16, CONST16(1)), cpu->ptr_PC);	break;

		/* branch */
		case INSTR_BEQ:
		case INSTR_BNE:
		case INSTR_BCS:
		case INSTR_BCC:
		case INSTR_BMI:
		case INSTR_BPL:
		case INSTR_BVS:
		case INSTR_BVC:
			break;

		/* other */
		case INSTR_NOP:											break;
		case INSTR_BRK:	arch_6502_trap(cpu, pc, bb);			break;
		case INSTR_RTI:	arch_6502_trap(cpu, pc, bb);			break;
		case INSTR_XXX:	arch_6502_trap(cpu, pc, bb);			break;
	}

	return get_length(get_addmode(opcode));
}
//swaption_payer_receiver=0 : Payer
//swaption_payer_receiver=1 : Receiver
static double cf_swaption_direct(StructLiborAffine *LiborAffine, double swaption_start, double swaption_end, double swaption_period, double swaption_strike, double swaption_nominal, int swaption_payer_receiver)
{
    double x0, lambda, theta, eta, Sqr_eta, Y;
    double P=0., Q=0., x, deg_freedom, n_centrality_param, bound, price, trm_k;
    double Tk, a_Ti, b_Ti, dzeta_k, sigma_k, sum=0.;
    int i, m, k, which=1, status;
    double psi_d;
    dcomplex uk, phi, psi;

    x0     = GET(LiborAffine->ModelParams, 0);
    lambda = GET(LiborAffine->ModelParams, 1);
    theta  = GET(LiborAffine->ModelParams, 2);
    eta    = GET(LiborAffine->ModelParams, 3);
    Sqr_eta = SQR(eta);

    // Static variables
    Ti = swaption_start;
    Tm = swaption_end;
    TN = LET(LiborAffine->TimeDates, (LiborAffine->TimeDates)->size-1);

    i = indiceTimeLiborAffine(LiborAffine, Ti);
    m = indiceTimeLiborAffine(LiborAffine, Tm);

    c_k = pnl_vect_create_from_double(m-i+1, swaption_period*swaption_strike);
    Phi_i_k = pnl_vect_create(m-i+1);
    Psi_i_k = pnl_vect_create(m-i+1);

    LET(c_k, 0) = -1.0;
    LET(c_k, m-i) += 1.;

    for (k=i; k<=m; k++)
    {
        uk = Complex(GET(LiborAffine->MartingaleParams, k), 0.);
        phi_psi_t_v(TN-Ti, uk, LiborAffine, &phi, &psi);

        LET(Phi_i_k, k-i) = Creal(phi);
        LET(Psi_i_k, k-i) = Creal(psi);
    }
    // Zero of the function f
    if (m==i+1) Y = find_Y_caplet(LiborAffine);
    else Y = find_Y_swaption(LiborAffine);

    a_Ti = exp(-lambda*Ti);
    if (lambda == 0.) b_Ti = Ti;
    else b_Ti = (1.-a_Ti)/lambda;

    deg_freedom = lambda*theta/Sqr_eta;

    sum=0.;
    Tk=Ti;
    for (k=i; k<=m; k++)
    {
        psi_d = GET(Psi_i_k, k-i);

        dzeta_k = 1 - 2*Sqr_eta*b_Ti*psi_d;
        sigma_k = Sqr_eta*b_Ti/dzeta_k;

        x = Y/sigma_k;

        n_centrality_param = x0*a_Ti/(Sqr_eta*b_Ti*dzeta_k);

        if (x<0)
        {
            P=0.;
            Q=1.;
        }
        else
        {
            pnl_cdf_chn (&which, &P, &Q, &x, &deg_freedom, &n_centrality_param, &status, &bound);
        }

        if (swaption_payer_receiver==0)
            trm_k = -GET(c_k, k-i)*BondPrice(Tk, LiborAffine->ZCMarket) * Q;
        else
            trm_k = GET(c_k, k-i)*BondPrice(Tk, LiborAffine->ZCMarket) * P;

        sum += trm_k;
        Tk += swaption_period;
    }

    price = swaption_nominal * sum;

    pnl_vect_free(&c_k);
    pnl_vect_free(&Phi_i_k);
    pnl_vect_free(&Psi_i_k);

    return price;
}
Esempio n. 27
0
int CarrMethod_VectStrike(PnlVect *K,
                          PnlVect * Price,
                          double S0,
                          double T,
                          double B,
                          double CallPut,
                          double r,
                          double divid,
                          double sigma,
                          void * Model,
                          dcomplex (*ln_phi)(dcomplex u,double t,void * model))
    
{
  int n;
  dcomplex dzeta,dzetaBS;
  double alpha=0.75;
  int Nlimit = 4*2048;//2048;
  //>> Should be even => use of real_fft
  //number of integral discretization steps
  double mone;//0.010;
  double Kstep=B*2/(Nlimit); // strike domain is (-B,B)
  double h  = M_2PI/(Nlimit*Kstep);
  //double B  = 0.5*(Nlimit)*Kstep; // strike domain is (-B,B)
  double vn = 0;
  dcomplex vn_minus_alpha_plus_uno = Complex(0,-(alpha+1));
  dcomplex i_vn_plus_alpha         = Complex(alpha,0);
  dcomplex uno_plus_alpha_plus_ivn =Complex(1+alpha,vn);
  PnlVectComplex * y = pnl_vect_complex_create(Nlimit);
 
  // Should become output
  pnl_vect_resize(K,Nlimit);
  pnl_vect_resize(Price,Nlimit);
  
  //delta
  mone=1;
  //printf("limit integration %7.4f \n",A); 
  for(n=0; n<Nlimit; n++)
    {
      dzeta   = Cadd(ln_phi(vn_minus_alpha_plus_uno,T,Model),Complex(0,vn*B));
      dzetaBS = Cadd(ln_phi_BS(vn_minus_alpha_plus_uno,T,sigma),Complex(0,vn*B));
      dzeta   = Csub(Cexp(dzeta),Cexp(dzetaBS));
      dzeta   = Cdiv(dzeta,i_vn_plus_alpha);
      dzeta   = Cdiv(dzeta,uno_plus_alpha_plus_ivn);
      //>> With Simson rules
      pnl_vect_complex_set(y,n,RCmul(3+mone-((n==0)?1:0),Conj(dzeta)));
      //>> Update value 
      vn += h;
      vn_minus_alpha_plus_uno.r+=h;
      i_vn_plus_alpha.i+=h;
      uno_plus_alpha_plus_ivn.i+=h;
      mone*=-1;
    }
  pnl_ifft_inplace(y);
  for(n=0;n<Nlimit;n++)
    {
      LET(K,n)=exp(-B+n*Kstep+(r-divid)*T)*(S0);
      pnl_cf_call_bs(S0,GET(K,n),T,r,divid,sigma,&LET(Price,n),&vn);
      LET(Price,n)+=2./3* S0/(Kstep)*exp(alpha*(B-n*Kstep)-divid*T)*GET_REAL(y,n);
    }
  if (CallPut==2)
    for(n=0;n<Nlimit;n++)
      LET(Price,n)-=S0*exp(-divid*T)+GET(K,n)*exp(-r*T);
  /*
  printf("Price K=  %7.4f  P= %7.4f \n",GET(K,Nlimit/2-5),GET(Price,Nlimit/2-5));
  printf("Price K=  %7.4f  P= %7.4f \n",GET(K,Nlimit/2-4),GET(Price,Nlimit/2-4));
  printf("Price K=  %7.4f  P= %7.4f \n",GET(K,Nlimit/2-3),GET(Price,Nlimit/2-3));
  printf("Price K=  %7.4f  P= %7.4f \n",GET(K,Nlimit/2-2),GET(Price,Nlimit/2-2));
  printf("Price K=  %7.4f  P= %7.4f \n",GET(K,Nlimit/2-1),GET(Price,Nlimit/2-1));
  printf("Price K=  %7.4f  P= %7.4f \n",GET(K,Nlimit/2+0),GET(Price,Nlimit/2+0));
  printf("Price K=  %7.4f  P= %7.4f \n",GET(K,Nlimit/2+1),GET(Price,Nlimit/2+1));
  printf("Price K=  %7.4f  P= %7.4f \n",GET(K,Nlimit/2+2),GET(Price,Nlimit/2+2));
  printf("Price K=  %7.4f  P= %7.4f \n",GET(K,Nlimit/2+3),GET(Price,Nlimit/2+3));
  printf("Price K=  %7.4f  P= %7.4f \n",GET(K,Nlimit/2+4),GET(Price,Nlimit/2+4));
  printf("Price K=  %7.4f  P= %7.4f \n",GET(K,Nlimit/2+5),GET(Price,Nlimit/2+5));
  printf("Price K=  %7.4f  P= %7.4f \n",GET(K,Nlimit/2+6),GET(Price,Nlimit/2+6));
  printf("Price K=  %7.4f  P= %7.4f \n",GET(K,Nlimit/2+7),GET(Price,Nlimit/2+7));
  printf("Price K=  %7.4f  P= %7.4f \n",GET(K,Nlimit/2+8),GET(Price,Nlimit/2+8));
  pnl_vect_free(&K);
  pnl_vect_free(&Price);
  */
  return OK;
}
Esempio n. 28
0
int CarrMethod_onStrikeList(PnlVect *K,
                            PnlVect * Price,
                            double S0,
                            double T,
                            double CallPut,
                            double r,
                            double divid,
                            double sigma,
                            Levy_diffusion * Model)
  
{
  PnlVect * StrikeFFT,*PriceFFT;
  int n,error,ancestor,current,next;
  double delta;
  double strike_min = GET(K, 0);
  double strike_max = GET(K,K->size-1);
  //double nbr_strike = K->size;
  double strike_bnd = 2*MAX(log(strike_max/S0),fabs(log(strike_min/S0)));//0.25*log(strike_max/strike_min)/nbr_strike;
  // 2 adjust heuristic parameter, to find four points
  // in fft in which all real strike value from K

  // Stored data for homogen grid in strike
  StrikeFFT=pnl_vect_create(0);
  PriceFFT=pnl_vect_create(0);
  
  error=CarrMethod_VectStrike(StrikeFFT,PriceFFT,
                              S0,T,strike_bnd,CallPut,r,divid,sigma,
                              Model,
                              &Levy_diffusion_ln_characteristic_function_with_cast);
  ancestor=0;
  current=0;
  next=1;
  n=0;
  while(n<K->size)
    {
      if((GET(StrikeFFT,current)<=GET(K,n))&&(GET(StrikeFFT,next)>GET(K,n)))
        {
          quadratic_interpolation(GET(PriceFFT,ancestor),
                                  GET(PriceFFT,current),
                                  GET(PriceFFT,next),
                                  GET(StrikeFFT,ancestor),
                                  GET(StrikeFFT,current),
                                  GET(StrikeFFT,next),
                                  GET(K,n),
                                  &LET(Price,n),
                                  &delta);
          n++;
        }
      else
        {
          ancestor=current;//not ++ for the first step
          current++;
          next++;
          if(next>StrikeFFT->size)
            PNL_ERROR(" Carr method domain size is too small for interpolation after FFT !","carr.c ");
 
        }
    }
  LET(Price,n)=GET(PriceFFT,PriceFFT->size);
  return error;
}
/// Backward computation of the price of an option on a Zero Coupon Bond
void ZCOption_BackwardIterationBK1D(TreeShortRate* Meth, ModelParameters* ModelParam, PnlVect* ZCbondPriceVect1, PnlVect* ZCbondPriceVect2,  PnlVect* OptionPriceVect1, PnlVect* OptionPriceVect2, int index_last, int index_first, NumFunc_1 *p, int Eur_Or_Am)
{
    double a ,sigma;

    int jmin; // jmin[i+1], jmax[i+1]
    int jminprev, jmaxprev; // jmin[i], jmax [i]
    int i, j, k; // i = represents the time index. j, k represents the nodes index

    double eta_over_delta_x;
    double delta_x1, delta_x2; // delta_x1 = space step of the process x at time i ; delta_x2 same at time i+1.
    double delta_t1, delta_t2; // time step
    double beta_x;              // quantity used in the compuation of the probabilities. it depends only on i.
    double ZCPrice; //ZC price

    double current_rate;

    double Pup, Pmiddle, Pdown;

    ///*******************Parameters of the processes r, u and y *********************////
    a = ModelParam->MeanReversion;
    sigma = ModelParam->RateVolatility;

    jminprev = pnl_vect_int_get(Meth->Jminimum, index_last);  // jmin(index_last)
    jmaxprev = pnl_vect_int_get(Meth->Jmaximum, index_last);  // jmax(index_last)

    ///** Backward computation of the option price from "index_last-1" to "index_first", knowing those at "index_last"**///
    for(i = index_last-1; i>=index_first; i--)
    {
        jmin = jminprev; // jmin := jmin(i+1)

        jminprev = pnl_vect_int_get(Meth->Jminimum, i); // jminprev := jmin(i)
        jmaxprev = pnl_vect_int_get(Meth->Jmaximum, i); // jmaxprev := jmax(i)

        pnl_vect_resize(OptionPriceVect1, jmaxprev-jminprev +1);  // OptionPrice1 := Prix a l'instant i,

        if(Eur_Or_Am != 0)
        {
            pnl_vect_resize(ZCbondPriceVect1, jmaxprev-jminprev +1);  // OptionPrice1 := Prix a l'instant i,
        }

        delta_t1 = GET(Meth->t, i) - GET(Meth->t,MAX(i-1,0)); // Pas de temps entre t[i] et t[i-1]
        delta_t2 = GET(Meth->t, i+1) - GET(Meth->t,i); // Pas de temps entre t[i+1] et t[i]

        delta_x1 = SpaceStep(delta_t1, a, sigma);  // SpaceStep (i)
        delta_x2 = SpaceStep(delta_t2, a, sigma);  // SpaceStep (i+1)

        beta_x =  (delta_x1 / delta_x2) * exp(-a*delta_t2);

        // Boucle sur les noeuds
        for(j = jminprev ; j<= jmaxprev ; j++)
        {
            k= pnl_iround(j * beta_x); // index of the middle node emanating from (i,j)
            eta_over_delta_x = j * beta_x - k; // quantity used in the compuation of the probabilities Pup, Pmiddle and Pdown.

            Pup = ProbaUp(eta_over_delta_x); // Probability of an up move from (i,j)
            Pmiddle = ProbaMiddle(eta_over_delta_x); // Probability of a middle move from (i,j)
            Pdown = 1 - Pup - Pmiddle; // Probability of a down move from (i,j)

            current_rate = func_model_bk1d(j * delta_x1 + GET(Meth->alpha, i)); // r(i,j)

            LET(OptionPriceVect1,j-jminprev) = exp(-current_rate*delta_t2) * ( Pup * GET(OptionPriceVect2, k+1-jmin) + Pmiddle * GET(OptionPriceVect2, k-jmin) + Pdown * GET(OptionPriceVect2, k-1-jmin));

            if(Eur_Or_Am != 0)
            {
                LET(ZCbondPriceVect1,j-jminprev) = exp(-current_rate*delta_t2) * ( Pup * GET(ZCbondPriceVect2, k+1-jmin) + Pmiddle * GET(ZCbondPriceVect2, k-jmin) + Pdown * GET(ZCbondPriceVect2, k-1-jmin));

                ZCPrice = GET(ZCbondPriceVect1,j-jminprev); // ZC price P(ti, S, r_ti=current rate)
                // In the case of american option, decide wether to exerice the option or not
                if( GET(OptionPriceVect1, j-jminprev) < (p->Compute)(p->Par, ZCPrice))
                {
                    LET(OptionPriceVect1, j-jminprev) = (p->Compute)(p->Par, ZCPrice);
                }
            }

        }

      // Copy OptionPrice1 in OptionPrice2
      pnl_vect_clone(OptionPriceVect2, OptionPriceVect1);

      if(Eur_Or_Am != 0)
      {
          pnl_vect_clone(ZCbondPriceVect2, ZCbondPriceVect1);
      }

    } // END of the loop on i
}
Esempio n. 30
0
// Use results on trigonometric function.
// Compute int_R sinc(u)^4 psi(u) exp( i u k ) du 
void Levy_fourier_stiffness_gradient(PnlVectComplex *Levy_sinus,
                                     double hx,
                                     int bnd,
                                     int Nw,
                                     int grad_size,
                                     double hw,
                                     int kmin,
                                     int kmax,
                                     PnlVect *row_stiffness)
{
  PnlVectComplex *cos_sin_vect;
  int i,k,m,j;
  double tmp1;
  int bound=kmax-kmin+1;
  cos_sin_vect=pnl_vect_complex_create(Nw);
  pnl_vect_resize(row_stiffness,grad_size*(kmax-kmin+1));
  tmp1=-bnd*M_PI;
  for (i=0;i<Nw;i++)
    {
      pnl_vect_complex_set(cos_sin_vect,i,CIexp(tmp1));
      tmp1+=hw;
    }
  pnl_vect_set_double(row_stiffness,0.0);
  for(k=-1;k>=kmin;k--)
    {
      m=0;
      for (i=0;i<Nw;i++)
        {
          
          for(j=0;j<grad_size;j++)
            {
              //LET(row_stiffness,j+grad_size*(k-kmin))
                LET(row_stiffness,bound*j+(k-kmin))+=GET_REAL(Levy_sinus,j+i*grad_size)*GET_REAL(cos_sin_vect,m)+
                  GET_IMAG(Levy_sinus,j+i*grad_size)*GET_IMAG(cos_sin_vect,m);
            }
          m-=k;
          m=m%(Nw);
        }
      //for(j=0;j<grad_size;j++)
      //  LET(row_stiffness,j+grad_size*(k-kmin))*=hw*1/(M_2PI);
    }
  for(k=0;k<=kmax;k++)
    {
      m=0;
      for (i=0;i<Nw;i++)
        {
          for(j=0;j<grad_size;j++)
            {
              //LET(row_stiffness,j+grad_size*(k-kmin))
              LET(row_stiffness,bound*j+(k-kmin))+=GET_REAL(Levy_sinus,j+i*grad_size)*GET_REAL(cos_sin_vect,m)
                -GET_IMAG(Levy_sinus,j+i*grad_size)*GET_IMAG(cos_sin_vect,m);
            }
          m+=k;
          m=m%Nw;
          
        }
      //for(j=0;j<grad_size;j++)
      //      LET(row_stiffness,j+grad_size*(k-kmin))*=hw*1/(M_2PI);
    }

  if(bnd%2==1)
    for(j=0;j<grad_size;j++)
      for(k=kmin;k<=kmax;k++)
        LET(row_stiffness,bound*j+(k-kmin))*=((k-kmin%2==0)?-1:1)*hw*1/(M_2PI);
  else 
    for(j=0;j<grad_size;j++)
      for(k=kmin;k<=kmax;k++)
        LET(row_stiffness,bound*j+(k-kmin))*=hw*1/(M_2PI);
  /*
    for(k=kmin;k<=kmax;k++)
      if(k-kmin%2==0)
      for(j=0;j<grad_size;j++)
        LET(row_stiffness,j+grad_size*(k-kmin))*=-1;
  */
  pnl_vect_complex_free(&cos_sin_vect);
}