예제 #1
0
static double cf_lrs1d_zcb(ZCMarketData* ZCMarket, double t, double r0, double phi0, double kappa, double sigma, double rho, double lambda, double T)
{
    if(t==0)
    {
        return BondPrice(T, ZCMarket);
    }
    else
    {
        double price;
        double P0_t, P0_T, P0_t_plus, P0_t_minus, f0_t, CapitalLambda;
        double dt;

        CapitalLambda = (1 - exp(-kappa*(T-t))) / kappa;

        dt = INC * t;

        P0_t = BondPrice(t, ZCMarket);

        P0_T = BondPrice(T, ZCMarket);

        P0_t_plus  = BondPrice(t + dt, ZCMarket);

        P0_t_minus = BondPrice(t - dt, ZCMarket);

        f0_t = -(log(P0_t_plus) - log(P0_t_minus))/ (2 * dt);

        //Price of Zero Coupon Bond
        price = (P0_T/P0_t) * exp(-SQR(CapitalLambda)*phi0/2 + CapitalLambda*(f0_t-r0));

        return price;
    }

}
예제 #2
0
double ATMSwaptionStrike(double T_start, double T_end, double period, ZCMarketData* ZCMarket)
{
    int i, n=pnl_iround((T_end-T_start)/period);
    double sum=0., T_i=T_start;

    for(i=0; i<n; i++)
    {
        T_i += period;
        sum += BondPrice(T_i, ZCMarket);
    }
    sum *= period;


    return (BondPrice(T_start, ZCMarket)-BondPrice(T_end, ZCMarket))/sum;
}
예제 #3
0
// Compute the initial rate r_0 and corresponding value x_0
void initial_short_rate(ZCMarketData* ZCMarket, double *r0, double *x0)
{
    if(ZCMarket->FlatOrMarket == 0) *r0 = ZCMarket->Rate;

    else *r0 = -log(BondPrice(INC, ZCMarket))/INC;

    *x0 = sqrt(2.* (*r0));
}
예제 #4
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);

        }
    }

}
예제 #5
0
/*Call Option on Zero Coupon Bond*/
static double zbput(double a, double b,double sigma, double rcc,double t, double T, double S, double K, ZCMarketData* ZCMarket)
{
    double PtS,PtT,ATS,BTS;
    double f0_t;
    double p1,p2,p3,k1,k2,k3,psi,phi,rb;
    double h;

    /*Computation of Forward rate*/
    h=sqrt(SQR(a)+2.*SQR(sigma));

    if(t-0.5*INC>0){f0_t = (log( BondPrice(t-0.5*INC, ZCMarket))-log( BondPrice(t+0.5*INC, ZCMarket)))/INC;}
    else {f0_t = -log( BondPrice(INC, ZCMarket))/INC; }

    PtT=zcbond(rcc,a,b,sigma,t,T, ZCMarket);
    PtS=zcbond(rcc,a,b,sigma,t,S, ZCMarket);

    BTS=B(S-T,a,b,sigma);
    ATS=A(S-T,a,b,sigma);

    /*X^2 parameters*/
    rb=(log(ATS/K)+log(A(T,a,b,sigma)*BondPrice(S, ZCMarket))-log(A(S,a,b,sigma)*BondPrice(T, ZCMarket)))/BTS;
    phi=2.*h/(SQR(sigma)*(exp(h*(T-t))-1.));
    psi=(a+h)/SQR(sigma);

    p1=2.*rb*(phi+psi+BTS);
    p2=4.*a*b/SQR(sigma);
    p3=2.*SQR(phi)*( rcc - shift(a,b,sigma,f0_t,t) )*exp(h*(T-t))/(phi+psi+BTS);

    k1=2.*rb*(phi+psi);
    k2=p2;
    k3=2.*SQR(phi)*( rcc - shift(a,b,sigma,f0_t,t) )*exp(h*(T-t))/(phi+psi);

    /*Price of Put by Parity*/

    return PtS*pnl_cdfchi2n(p1,p2,p3)-K*PtT*pnl_cdfchi2n(k1,k2,k3) -PtS+K*PtT;;
}
예제 #6
0
static double zcbond(double rcc,double a,double b,double sigma,double t,double T, ZCMarketData* ZCMarket)
{
    if(t==0)
    {
        return BondPrice(T, ZCMarket);
    }
    else
    {
        double h, A, B, At, AT, shift, c;
        double f0_t, P0_t, P0_T, P0_t_plus, P0_t_minus;

        P0_t = BondPrice(t, ZCMarket);
        P0_T = BondPrice(T, ZCMarket);

        /*Computation of Forward rate*/
        P0_t_plus = BondPrice(t*(1.+INC),ZCMarket);
        P0_t_minus = BondPrice(t*(1.-INC),ZCMarket);
        f0_t = -(log(P0_t_plus)-log(P0_t_minus))/(2.*t*INC);

        /*A,B coefficient*/
        h=sqrt(SQR(a)+2.*SQR(sigma));
        B=2.*(exp(h*(T-t))-1.)/(2.*h+(a+h)*(exp(h*(T-t))-1.));
        A=pow(h*exp(0.5*(a+h)*(T-t))/(h+0.5*(a+h)*(exp(h*(T-t))-1.)), 2.*a*b/SQR(sigma));
        At=pow(h*exp(0.5*(a+h)*(t))/(h+0.5*(a+h)*(exp(h*(t))-1.)), 2.*a*b/SQR(sigma));
        AT=pow(h*exp(0.5*(a+h)*(T))/(h+0.5*(a+h)*(exp(h*(T))-1.)), 2.*a*b/SQR(sigma));

        c=sqrt(a*a+2*sigma*sigma);

        shift = (f0_t - 2*a*b*(exp(t*c)-1)/(2*c+(a+c)*(exp(t*c)-1)));

        A=A*(P0_T*At)/(AT*P0_t)*exp(B*shift);

        /*Price*/
        return A*exp(-B*rcc);
    }
}
예제 #7
0
/*Call Option*/
static int zcb_quad1d(double flat_flag, double beta, double sigma, double r0, char *curve, double T, double *price)
{
    double x0;
    Data data;

    ZCMarketData ZCMarket;

    /* Flag to decide to read or not ZC bond datas in "initialyields.dat" */
    /* If P(0,T) not read then P(0,T)=exp(-r0*T) */
    if(flat_flag==0)
    {
        ZCMarket.FlatOrMarket = 0;
        ZCMarket.Rate = r0;
    }

    else
    {
        ZCMarket.FlatOrMarket = 1;
        ZCMarket.filename = curve;
        ReadMarketData(&ZCMarket);

        r0 = -log(BondPrice(INC, &ZCMarket))/INC;

        if(T > GET(ZCMarket.tm,ZCMarket.Nvalue-1))
        {
            printf("\nError : time bigger than the last time value entered in initialyield.dat\n");
            exit(EXIT_FAILURE);
        }
    }

    x0 = sqrt(2.*r0);
    /* coefficients of P(0,T) */
    bond_coeffs(&ZCMarket, &data, T, beta, sigma, x0);

    /*Price*/
    *price = exp(-(r0 * data.B + data.b*x0 + data.c));

    DeleteZCMarketData(&ZCMarket);

    return OK;
}
예제 #8
0
// Compute f(0, T) the forward rate, known at 0, maturing at T.
double ForwardRate(double T, ZCMarketData* ZCMarket)
{
    return -(log(BondPrice(T + INC,ZCMarket))-log(BondPrice(T,ZCMarket)))/(INC);
}
예제 #9
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);

}
예제 #10
0
static double tr_lrs1d_capfloor(TreeLRS1D* Meth, ModelLRS1D* ModelParam, ZCMarketData* ZCMarket, int NumberOfTimeStep, NumFunc_1 *p, double s, double r, double periodicity,double first_reset_date,double contract_maturity, double CapFloorFixedRate)
{
    double lambda;

    double delta_y; // delta_x1 = space step of the process x at time i ; delta_x2 same at time i+1.
    double delta_t, sqrt_delta_t; // time step

    double OptionPrice, OptionPrice1, OptionPrice2;
    int i, i_s, h_r;
    double theta;
    double y_r, y_ih, y_00, r_00;

    double Ti2, Ti1;
    int i_Ti2, i_Ti1, n;

    PnlVect* proba_from_ih;
    PnlVect* OptionPriceVect1; // Matrix of prices of the option at i
    PnlVect* OptionPriceVect2; // Matrix of prices of the option at i+1

    proba_from_ih = pnl_vect_create(3);
    OptionPriceVect1 = pnl_vect_create(1);
    OptionPriceVect2 = pnl_vect_create(1);

    ///********* Model parameters *********///
    lambda = (ModelParam->Lambda);

    ///**************** PAYOFF at the MATURITY of the OPTION : T(n-1)****************///
    Ti2 = contract_maturity;
    Ti1 = Ti2 - periodicity;

    CapFloor_InitialPayoffLRS1D(Meth, ModelParam, ZCMarket, OptionPriceVect2, p, Ti1, Ti2, CapFloorFixedRate);


    ///**************** Backward computation of the option price ****************///
    n = (int) ((contract_maturity-first_reset_date)/periodicity + 0.1);

    if(n>1)
    {
        for(i = n-2; i>=0; i--)
        {
            Ti1 = first_reset_date + i * periodicity;
            Ti2 = Ti1 + periodicity;
            i_Ti2 = indiceTimeLRS1D(Meth, Ti2);
            i_Ti1 = indiceTimeLRS1D(Meth, Ti1);

            CapFloor_BackwardIterationLRS1D(Meth, ModelParam, ZCMarket, OptionPriceVect1, OptionPriceVect2, i_Ti2, i_Ti1);

            CapFloor_InitialPayoffLRS1D(Meth, ModelParam, ZCMarket, OptionPriceVect1, p, Ti1, Ti2, CapFloorFixedRate);

            pnl_vect_plus_vect(OptionPriceVect2, OptionPriceVect1);
        }
    }

    ///****************** Price of the option at initial time s *******************///
    i_s = indiceTimeLRS1D(Meth, s); // Localisation of s on the tree

    delta_t = GET(Meth->t, 1) - GET(Meth->t,0);
    sqrt_delta_t = sqrt(delta_t);

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

    Ti1 = first_reset_date;
    i_Ti1 = indiceTimeLRS1D(Meth, Ti1);

    if(i_s==0) // If s=0
    {
        CapFloor_BackwardIterationLRS1D(Meth, ModelParam, ZCMarket, OptionPriceVect1, OptionPriceVect2, i_Ti1, 1);

        probabilities(GET(Meth->t,0), y_00, 0, lambda, sqrt_delta_t, ModelParam, ZCMarket, proba_from_ih);

        OptionPrice = exp(-r_00*delta_t) * ( GET(proba_from_ih,0) * GET(OptionPriceVect1, 0) + GET(proba_from_ih,1) * GET(OptionPriceVect1,1) + GET(proba_from_ih,2) * GET(OptionPriceVect1, 2));
    }

    else
    {   // We compute the price of the option as a linear interpolation of the prices at the nodes r(i_s,j_r) and r(i_s,j_r+1)

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

        y_r = r_to_y(ModelParam, r);

        h_r = (int) floor(i_s - (y_r-y_00)/delta_y); // y_r between y(h_r) et y(h_r+1) : y(h_r+1) < y_r <= y(h_r)

        y_ih = y_00 + (i_s-h_r) * delta_y;

        if(h_r < 0 || h_r > 2*i_s)
        {
          printf("WARNING : Instantaneous futur spot rate is out of tree\n");
          exit(EXIT_FAILURE);
        }

        CapFloor_BackwardIterationLRS1D(Meth, ModelParam, ZCMarket, OptionPriceVect1, OptionPriceVect2, i_Ti1, i_s);

        theta = (y_ih - y_r)/delta_y;

        OptionPrice1 = MeanPrice(Meth, i_s, h_r, OptionPriceVect2); //Interpolation(Meth, i_s, h_r  , OptionPriceVect2, phi0);

        OptionPrice2 = MeanPrice(Meth, i_s, h_r+1, OptionPriceVect2); // Interpolation(Meth, i_s, h_r+1  , OptionPriceVect2, phi0);

        OptionPrice = (1-theta) * OptionPrice1 + theta * OptionPrice2 ;
    }

    pnl_vect_free(& OptionPriceVect1);
    pnl_vect_free(& OptionPriceVect2);
    pnl_vect_free(&proba_from_ih);

    return OptionPrice;

}
//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;
}
///* Payer Swaption price as a combination of ZC Put option prices
static int cf_ps1d(int flat_flag, double r_t, char *curve, double Nominal, double periodicity,
                   double option_maturity, double contract_maturity,
                   double SwaptionFixedRate, double a, double sigma,double *price)
{
    int i, nb_payement;
    double ci, sum ,ti;

    double x0, critical_r, Strike_i, PutOptionPrice;
    Data data1, data2;
    Omega om;
    ZCMarketData ZCMarket;

    PutOptionPrice = 0.; /* to avoid warning */
    /* Flag to decide to read or not ZC bond datas in "initialyields.dat" */
    /* If P(0,T) not read then P(0,T)=exp(-r0*T) */
    if(flat_flag==0)
    {
        ZCMarket.FlatOrMarket = 0;
        ZCMarket.Rate = r_t;
    }

    else
    {
        ZCMarket.FlatOrMarket = 1;
        ZCMarket.filename = curve;
        ReadMarketData(&ZCMarket);
        r_t = -log(BondPrice(INC, &ZCMarket))/INC;

        if(contract_maturity > GET(ZCMarket.tm,ZCMarket.Nvalue-1))
        {
            printf("\nError : time bigger than the last time value entered in initialyield.dat\n");
            exit(EXIT_FAILURE);
        }
    }

    x0 = sqrt(2* r_t);

    bond_coeffs(&ZCMarket, &data1, option_maturity, a, sigma, x0);

    ti = option_maturity;
    ci = periodicity * SwaptionFixedRate;

    nb_payement = (int)((contract_maturity-option_maturity)/periodicity);

    critical_r = Critical_Rate(&ZCMarket, r_t, periodicity, option_maturity, contract_maturity, SwaptionFixedRate, a, sigma);

    sum=0.;

    for(i=1; i<=nb_payement; i++)
    {
        ti += periodicity;

        /* coefficients of P(0,S) */
        bond_coeffs(&ZCMarket, &data2, ti, a, sigma, x0);

        /* omega distribution of P(T,S) */
        transport(&om, data1, data2, a, sigma, x0);

        Strike_i = exp(-(om.B*critical_r + om.b*sqrt(2*critical_r) + om.c));

        PutOptionPrice = zb_call_quad1d(&ZCMarket, a, sigma, option_maturity, ti, Strike_i);

        sum += ci * PutOptionPrice;
    }

  sum += PutOptionPrice;

  *price = Nominal * sum;

  DeleteZCMarketData(&ZCMarket);

  return OK;
}
예제 #13
0
파일: HJM.cpp 프로젝트: humeaua/Seminaire
 double HeathJarrowMorton::Libor(double dt, double dStart, double dEnd, double dX, const CurveName & eCurveName) const
 {
     //  Must change coverage to take into account real basis
     return 1.0 / (dEnd - dStart) * (BondPrice(dt, dStart, dX, eCurveName) / BondPrice(dt, dEnd, dX, eCurveName) - 1.0);
 }