📄 caplet.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*//* * Caplet.java * * Created on September 7, 2002, 4:33 PM */package Libor.LiborDerivatives;import Libor.LiborProcess.*;import Statistics.*;import Exceptions.*;/** Caplet <code>cplt([T_i,T_{i+1}],k)</code> pays off * <code>h=delta_i*(L_i(T_i)-k)^+</code>, where <code>k</code> is the * strike rate. No log-normal {@link LiborVector} implemented * for fast valuation of this caplet (there is an exact analytic formula * for the price). * * @author Michael J. Meyer */public class Caplet extends LiborDerivative { int i; // accrual interval [T_i,T_{i+1}] double kappa; //strike rate /******************************************************************************* * * CONSTRUCTOR * ******************************************************************************/ /** Libors <code>L_j</code> needed for <code>j>=i</code> and until time * <code>min(T_{i+1},T_{n-1})</code> (for forward transporting the payoff * from time <code>T_{i+1}</code>). * * @param LP underlying Libor process. * @param i caps Libor on <code>[T_i,T_{i+1}]</code>. * @param kappa strike rate. */ public Caplet(LiborProcess LP, int i, double kappa) { super(LP,i,Math.min(i+1,LP.dimension()-1)); this.i=i; this.kappa=kappa; hasControlVariate=true; controlVariateNeedsX0=false; controlVariateNeedsX1=false; } /******************************************************************************* * * AGGREGATE VOLATILITY TO EXPIRATION * ******************************************************************************/ /** <p>The square root of the quadratic variation<br> * <code><log(L_i)>_{T_t}^{T_i}= * int_{T_t}^{T_i}sigma_i^2(s)ds.</code><br> * Think of this as the aggregate volatility of Libor <code>L_i</code> * until caplet expiration <code>T_i</code>. This quantity is used in * the Black caplet formula.</p> * * @param t current discrete time. */ public double Sigma(int t) { double sgmsqr= LP.factorLoading().integral_sgi_sgj_rhoij(i,i,Tc[t],Tc[i]); return Math.sqrt(sgmsqr); } /******************************************************************************* * * FORWARD TRANSPORTED PAYOFF * ******************************************************************************/ /** Payoff from current Libor path transported forward from time * <code>T_{i+1}</code> to time <code>T_n</code>. */ public double currentForwardPayoff() { // payoff at time T_{i+1} double h=Math.max(LP.X(i,i)-delta[i]*kappa,0); // move this from time T_{i+1} to time T_n return h*LP.forwardTransport(i+1); } /** Mean of the control variate conditioned on the state of the * Libor path at time <code>t</code>. This is * <code>L_i(t)*B_{i+1}(t)/B_n(t)</code> * (a <code>P_n</code>-martingale), see <i>LiborProcess.ps</i>. * * @param t current discrete time (continuous time <code>T_t</code>). */ public double controlVariateMean(int t) { return LP.X(i,t)*LP.B(i+1,t)/LP.B(n,t); } /** Control variate is forward transported Libor * <code>L_i(T_i)*B_{i+1}(T_i)/B_n(T_i)</code>. * See <i>LiborProcess.ps</i> */ public double[] currentControlledForwardPayoff() { double h=currentForwardPayoff(), cv=LP.X(i,i)*LP.B(i+1,i)/LP.B(n,i); return new double[] {h,cv}; } // WARNING: switching the control variate to cv=LP.L(i,i)*LP.B(i+1,i)/LP.B(n,i)// ie. Libors instead of X-Libors and adjusting the control variate mean// accordingly should have no effect. In fact controlled Monte Carlo then no// longer works. Find out why. /******************************************************************************* * * ANALYTIC PRICE * ******************************************************************************/ /** Black caplet price (this is the martingale price in the LMM). * * @param t current discrete time. */ public double analyticForwardPrice(int t) { double L_it=LP.L(i,t), // L_i(t) cSigma,Nplus,Nminus; // at time t=T_i it's the forward transported payoff if(t==i)return currentForwardPayoff(); // if t<T_i cSigma=Sigma(t); // aggregate volatility to expiry Nplus=FinMath.N(FinMath.d_plus(L_it,kappa,cSigma)); Nminus=FinMath.N(FinMath.d_minus(L_it,kappa,cSigma)); // factor B_{i+1}(t)/B_n(t) is LP.forwardTransport(t,i+1) return delta[i]*(L_it*Nplus-kappa*Nminus)*LP.forwardTransport(t,i+1); } //end LMM_Price() /******************************************************************************* * * TEST PROGRAM * ******************************************************************************/ /** <p>Test program. Allocates a Libor process of dimension * <code>n=15</code> and prices the (at the money) caplet * <code>cplt([T_12,T_13],0.04)</code>. * * <p>The Monte Carlo forward price of this caplet * at time <code>T_n</code> is compared to the analytic price. The * correlation of the payoff with the control variate is also computed. * The forward transporting and discounting involves all Libors * <code>L_j, j>=13</code>.</p> */ public static void main(String[] args) { // Libor process setup int n=20, // dimension of Libor process i=19; // caps Libor on [T_i,T_{i+1}] double kappa=0.05; // strike rate // Libor parameter sample final LMM_Parameters lmmParams=new LMM_Parameters(n,LMM_Parameters.CS); final LiborProcess LP=new LiborProcess(lmmParams); final LiborDerivative cplt=new Caplet(LP,i,kappa); // all prices forward prices at time T_n double aprice, // analytic price mcprice, // Monte carlo price cvmcprice; // Monte carlo price with control variate int nPath=50000; // number of Libor paths System.out.print ("\nCAPLET: \n"+ "Correlation of payoff with control variate, "+nPath/4+" paths: "); double cvcorr=cplt.controlledForwardPayoff(). correlationWithControlVariate(0,nPath/4); cvcorr=FinMath.round(cvcorr,4); System.out.print(cvcorr+"\n\nPrice, "+nPath+" paths:\n\n"); aprice=cplt.analyticForwardPrice(0); mcprice=cplt.monteCarloForwardPrice(0,nPath); cvmcprice=cplt.controlledMonteCarloForwardPrice(0,nPath); aprice=FinMath.round(aprice,8); mcprice=FinMath.round(mcprice,8); cvmcprice=FinMath.round(cvmcprice,8); String report= "analytic: "+aprice+"\n"+ "Monte Carlo: "+mcprice+"\n"+ "Monte Carlo with control variate: "+cvmcprice; System.out.println(report); } // end main } // end Caplet
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -