⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swaption.java

📁 金融资产定价,随机过程,MONTE CARLO 模拟 JAVA 程序和文档资料
💻 JAVA
字号:
/* WARANTY NOTICE AND COPYRIGHTThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.Copyright (C) Michael J. Meyermatmjm@mindspring.comspyqqqdia@yahoo.com*//* * Swaption.java * * Created on September 7, 2002, 4:33 PM */package Libor.LiborDerivatives;import Libor.LiborProcess.*;import Statistics.*;import Exceptions.*;import LinAlg.*;/** <p>Forward start payer swaption <code>swpn(T,[T_p,T_q],k)</code> pays off *  <code>h=B_pq(T)*(S_pq(T)-k)^+</code> at exercise time <code>T=T_tau</code>, *  where <code>k</code> is the strike rate and <code>S_pq(T)</code> is *  the value of the <code>[T_p,T_q]</code>-swap rate at time <code>T</code>. *  </p> *  <p>Here <code>B_pq</code> is the annuity  *  <code>sum_{k=p}^{q-1}delta_kB_{k+1}</code> as usual. The time *  <code>T=T_tau</code> of swaption exercise is assumed to be a point on the  *  Libor tenor structure.</p> *   * @author  Michael J. Meyer */public class Swaption extends LiborDerivative {              int tau,p,q;          // swap along [T_p,T_q], exercisable at time tau         double kappa;         //strike rate                  /******************************************************************************* * *                          CONSTRUCTOR * ******************************************************************************/        /** Libors needed for forward payoff are <code>L_j, j&gt;=tau</code>      *  at time <code>T_tau</code> (forward transporting from time      *  <code>T_tau</code>).     *     * @param LP underlying Libor process.     * @param p swap begins at <code>T_p</code>.     * @param q swap ends at <code>T_q</code>.     * @param tau swaption exercises at time <code>T_tau&lt;=T_p</code>.     * @param kappa strike rate.     */    public Swaption    (LiborProcess LP, int tau, int p, int q, double kappa)     {        super(LP,tau,tau,LP.X0LiborVector(tau));        this.tau=tau;        this.p=p;        this.q=q;        this.kappa=kappa;        hasControlVariate=true;        controlVariateNeedsX0=false;        controlVariateNeedsX1=false;            }    /******************************************************************************* * *       FUNCTIONS NEEDED FOR THE APPROXIMATE ANALYTIC PRICE * ******************************************************************************/     /** <p>The weight <code>w^{p,q}_j(t)</code> in the representation of the       *  swap rate <code>S_pq(t)</code> as a convex combination of Libors.      *  See <i>LiborProcess.ps</i>.      *      * @param j Libor index in <code>[p,q)</code>.      * @param t current discrete time.      */     public double wpq(int j, int t)     {          double delta_j=LP.delta()[j];         return delta_j*LP.B(j+1,t)/LP.B_pq(p,q,t);     }                 /** <p>The vector <code>x_pq(t)</code> used in the computation of the      *  approximation of the swap rate volatility. See       *  <i>LiborProcess.ps</i>.</p>      *      * @param t current discrete time.      */     public ColtVector xpq(int t)     {          ColtVector x=new ColtVector(q-p);         for(int j=p;j<q;j++){                          double x_j=wpq(j,t)*LP.L(j,t);             x.setQuick(j-p,x_j);         }         return x;     } // end xpq            /** <p>Conditionally deterministic approximation      *  to the aggregate volatility (square root of the quadratic variation      *  <code>&lt;log(S_pq)&gt;_t^T</code>) of the swap rate <code>S_pq</code>     *  to expiration conditioned on the state of the Libor process     *  at time <code>t</code>.</p>     *     * <p>This quantity is used in the analytic approximation to the swaption     * price {@link #analyticForwardPrice}. See <i>LiborProcess.ps</i></p>     *       * @param t current discrete time.     */    public double Sigma(int t)    {        // compute the Cholesky root of the covariation matrix on [T_t,T_tau]        // for the relevant Libors L_j, j=p,...,q-1.        ColtMatrix Q=LP.logCovariationCholeskyRoot(p,q,Tc[t],Tc[tau]);        Q.transposeSelf();        double nrm=xpq(t).timesEquals(Q).L2Norm();                return nrm/LP.swapRate(p,q,t);    }        /******************************************************************************* * *                  FORWARD TRANSPORTED PAYOFF * ******************************************************************************/         /** Payoff at time <code>T_tau</code> from current Libor path transported       *  forward from time <code>T_tau</code> to time <code>T_n</code>.      */     public double currentForwardPayoff()     {         double  k=LP.swapRate(p,q,tau), h;         if(k<kappa) return 0;         h=LP.B_pq(p,q,tau)*(k-kappa);         // move this from time T_tau to time T_n         return h*LP.forwardTransport(tau);     }     /** Mean of the control variate conditioned on the state of the      *  Libor path at time <code>t</code>. This is      *  <code>(B_p(t)-B_q(t))/B_n(t)</code>       *  (a <code>P_n</code>-martingale), see <i>LiborProcess.ps</i>.      *      * @param t current discrete time <code>t&lt;=T</code>.      */     public double controlVariateMean(int t)     {          return (LP.B(p,t)-LP.B(q,t))/LP.B(n,t);     }              /** Control variate is <code>(B_p(T)-B_q(T))/B_n(T), T=T_tau</code>.      *  See <i>LiborProcess.ps</i>       */     public double[] currentControlledForwardPayoff()     {         double h=currentForwardPayoff(),                cv=(LP.B(p,tau)-LP.B(q,tau))/LP.B(n,tau);                         return new double[] {h,cv};       }         /** <p>The forward transported payoff (as seen from time <code>t=0</code>)     *  computed from a new sample of the <code>LiborVector</code> object     *  <code>U=(X^0_tau(T_tau),...,X^0_{n-1}(T_tau))</code>, a log-normal     *  approximation to the vector of true Libors     *  <code>U=(X_tau(T_tau),...,X_{n-1}(T_tau))</code>.     *  Recall <code>X_j(t)=delta_jL_j(t)</code>, see document      *  <i>LiborProcess.ps</i>.</p>     */     public double lognormalForwardPayoffSample()     {         LV.nextSample();         double h=LV.B_pqTm(p,q)*Math.max(LV.S_pqTm(p,q)-kappa,0);         // move this from time T_tau to time T_n         return h*LV.forwardTransport();     }/******************************************************************************* * *                            ANALYTIC PRICE * ******************************************************************************/                   /** <p>Analytic approximation to the swaption price. Based on a log-normal    *  distribution of the swap rate conditioned on the state of the Libor path    *  at the time <code>t</code> of pricing.    *    * @param t current discrete time.    */   public double analyticForwardPrice(int t)   {       double S_pqt=LP.swapRate(p,q,t),              // S_pq(t)              swpnSigma,Nplus,Nminus;                                      // at time t=tau it's the forward transported payoff       if(t==tau)return currentForwardPayoff();          // if t<T      swpnSigma=Sigma(t);        // aggregate volatility to expiry                           Nplus=FinMath.N(FinMath.d_plus(S_pqt,kappa,swpnSigma));     Nminus=FinMath.N(FinMath.d_minus(S_pqt,kappa,swpnSigma));          return LP.B_pq(p,q,t)*(S_pqt*Nplus-kappa*Nminus)/LP.B(n,t);     } //end analyticForwardPrice()            /******************************************************************************* * *                        TEST PROGRAM * ******************************************************************************/            /** <p>Test program. Allocates a Libor process of dimension       *  <code>n=15</code> and prices the (at the money) swaption       *  <code>swpn(T_5,[T_5,T_15],0.04)</code>.      *      *  <p>The Monte Carlo forward price of this swaption      *  at time <code>T_n</code> is compared to the analytic price and       *  to the Monte carlo price based on the log-normal Libor approximation       *  <code>X0</code> and the correlation of the payoff with the control       *  variate computed.      *  The forward transporting and discounting involves all Libors       *  <code>L_j, j&gt=5</code>.</p>      */     public static void main(String[] args)     {         // Libor process setup         int n=15,              // dimension of Libor process             tau=3,             // swaption exercisable at time T_tau             p=5, q=15;         // [T_p,T_q]-swaption         double kappa=0.03;     // strike rate                // Libor parameter sample          final LMM_Parameters lmmParams=new LMM_Parameters(n,LMM_Parameters.CS);         final LiborProcess LP=new LiborProcess(lmmParams);                final LiborDerivative swpn=new Swaption(LP,tau,p,q,kappa);                // all prices forward prices at time T_n         double aprice,                // approximate analytic price                mcprice,               // Monte carlo price                cvmcprice,             // Monte carlo price with control variate                lgnprice;              // log-normal price                int nPath=40000;             // number of Libor paths                  System.out.print         ("\nSWAPTION: \n"+          "Correlation of payoff with control variate, "+nPath/4+" paths: ");         double cvcorr=swpn.controlledForwardPayoff().                            correlationWithControlVariate(0,nPath/4);         cvcorr=FinMath.round(cvcorr,4);         System.out.print(cvcorr+"\n\nPrice, "+nPath+" paths:\n\n");                aprice=swpn.analyticForwardPrice(0);         mcprice=swpn.monteCarloForwardPrice(0,nPath);         cvmcprice=swpn.controlledMonteCarloForwardPrice(0,nPath);         lgnprice=swpn.lognormalMonteCarloForwardPrice(nPath);                  aprice=FinMath.round(aprice,8);         mcprice=FinMath.round(mcprice,8);         cvmcprice=FinMath.round(cvmcprice,8);         lgnprice=FinMath.round(lgnprice,8);                String report=         "approximate analytic: "+aprice+"\n"+         "Monte Carlo: "+mcprice+"\n"+         "Monte Carlo with control variate: "+cvmcprice+"\n"+         "log-normal Monte Carlo: "+lgnprice;         System.out.println(report);                   } // end main     } // end Swaption

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -