📄 calibrator.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*//* * Calibrator.java * * Created on September 18, 2002, 12:50 AM */package Libor.LiborProcess;import Statistics.FinMath;import Statistics.LoopStatus;import LinAlg.*;import Exceptions.*;import com.skylit.io.*;import java.io.*;import java.util.Vector;import java.util.Iterator;import QuasiRandom.*;/** <p>This is a restricted version of a Libor process which has all the methods * needed for calibration (computing the relevant prices at time zero, * solving for implied volatilities etc) but no methods for path computation. * Obviously this implies that Monte Carlo simulation is not used in * calibration. See <i>LiborProcess.ps</i>.</p> * * <p><a href=#calibration>Calibration</a> * is carried out for the {@link CS_FactorLoading} only. * The calibration routine does not build an initial term structure of forward * Libors. This term structure is handed to the constructor as an argument. * In all our experiments this will be the exact intial term structure of the * corresponding Libor process.</p> * * <p>The model parameters <code>A,D,alpha,beta,rho00</code> * for the <code>CS_FactorLoading</code> are * calibrated to caplets <code>cplt([T_i,T_{i+1}],kappa)</code> and swaptions * <code>swpn(T_p, [T_p,T_q],kappa)</code> with arbitrary strikes satisfying * <code>1<=p<=n-2</code>. * Note in particular that no forward start swaptions are used. The * swaption is exercised into a swap starting at the time of exercise.</p> * * <p><b>Warning:</b></p> the calibration routine works with cash prices * (at time zero) <i>not</i> forward prices at the horizon! * The calibration routine tries to minimize the mean percent error over all * available swaption prices.</p> * * @author Michael J. Meyer */public class Calibrator { int n; // number of forward Libors double[] delta, // delta[t]=T_{t+1}-T_t,length of compounding intervals Tc, // tenor structure, Tc[t]=T_t x, // initial X-Libors x[j]=X_j(0)=delta_jL_j(0) l; // initial Libors l[j]=L_j(0) // stored for faster computation of the swap rate weights w^j_{p,q}(0): double[] Bi; // Bi[j]=B_j(0), zero coupon bonds double[][] B_pq, // B_pq[p][q-p]=B_pq(0), annuities // note index shift q->q-p S_pq; // S_pq[p][q-p]=S_pq(0), swap rates // We need to store the array of transposed Cholesky roots of the // covariation matrices CV(p)=(cv_ij(p))_{i,j=p,...,n-1}, where // cv_ij(p)=integral_0^{T_p}sigma_i(s)sigma_j(s)rho(i,j)ds. // Here p=1,...,n-2. // These matrices are used in the computation of analytic swaption prices // and are set in the calibration routine whenever a new parameter tuple // is investigated. ColtMatrix[] tCholeskyRoots; // INFORMATION SPECIFIC TO THE CURRENT FACTOR LOADING: /** CS_FactorLoading parameter */ public double A,D,alpha,beta,rho00; // the array of c_j from sigma_j(t)=c_j*g(1-t/T_j) double[] c; // volatility and correlation structure FactorLoading factorLoading; // file readers for caplet and swaption prices EasyReader capletReader, swaptionReader; /******************************************************************************* * * UTILITIES FOR TESTING * ******************************************************************************/ private void printParameters() { System.out.println ("A="+A+ "\nD="+D+ "\nrho00="+rho00+ "\nalpha="+alpha+ "\nbeta="+beta); } /******************************************************************************* * * CAPLETS AND SWAPTIONS * ******************************************************************************/ /** Structure containing swaption parameters and price. */ public class Swpn{ public int p,q; public double kappa, price; public Swpn(int p, int q, double kappa, double price) { this.p=p; this.q=q; this.kappa=kappa; this.price=price; } } /** Array of caplet implied aggregate volatilities, * <code>capletSigma=sigma_i*sqrt(T_i)</code>, where * <code>sigma_i</code> is the annual caplet price implied volatility * of Libor <code>L_i</code>. Missing caplets will be interpolated * from nearest neighbors. */ public double[] capletSigma; /** list of swaptions */ public static final Vector swaptions=new Vector(); /******************************************************************************* * * SET THE FACTORLOADING AND CORRESPONDING CHOLESKY ROOTS * ******************************************************************************/ /** <p>The Cholesky root of * {@link FactorLoading#logCovariationMatrix(int,int,double,double)}.</p> * * @param p Libors <code>L_j, j=p,...,q-1.</code> * @param q Libors <code>L_j, j=p,...,q-1.</code> * @param t time interval [t,T], continuous time. * @param T time interval [t,T], continuous time. */ public ColtMatrix logCovariationCholeskyRoot(int p,int q, double t, double T) { return factorLoading.logCovariationCholeskyRoot(p,q,t,T); } /** Sets the parameters for the <code>CS_FactorLoading</code>. */ public void setParameters (double A, double D, double alpha, double beta, double rho00) { this.A=A; this.D=D; this.alpha=alpha; this.beta=beta; this.rho00=rho00; } /** Sets the factor loading from the current parameters. */ public void setFactorLoading(CS_FactorLoading fl) { factorLoading=fl; } /** Sets the array of transposed Cholesky roots of the covariation matrices * from the current factor loading. */ public void setCholeskyRoots() { for(int p=1;p<n-1;p++){ tCholeskyRoots[p]=logCovariationCholeskyRoot(p,n,0,Tc[p]); tCholeskyRoots[p].transposeSelf(); } } /******************************************************************************* * * READ CAPLET PRICES * ******************************************************************************/ // READ CAPLETS /** Reads the caplet prices and stores the implied aggregate volatilities in * the array <code>capletSigma</code>. Missing caplets are interpolated. * The file containing the caplets must adhere to the following * <a href=#capletFile>file format</a>. */ private void readCaplets() { // the current caplet and its fields int i; double kappa, price; while(!capletReader.eof()){ i=capletReader.readInt(); kappa=capletReader.readDouble(); price=capletReader.readDouble(); try{ capletSigma[i]=capletImpliedSigma(i,kappa,price); } // ignore this caplet if solving for implied vol fails catch(NoSolutionException e){ capletSigma[i]=0; } } capletReader.close(); // interpolate the missing caplets: for(int j=1;j<n;j++) if(capletSigma[j]==0)interpolateCaplet(j); } // end readCaplets // INTERPOLATION OF MISSING CAPLETS: // smallest index i1>i for which a caplet has been read // returns n if i was the last caplet read. private int i_1(int i) { int j=i+1; while((j<n)&&(capletSigma[j]==0))j++; return j; } // largest index 1<=i0<i for which a caplet has been read // returns 0 if i was the first caplet read. private int i_0(int i) { int j=i-1; while((j>0)&&(capletSigma[j]==0))j--; return j; } // Interpolates this volatlity of caplet i as arithmetic // average of nearest neighbors private void interpolateCaplet(int i) { // nearest neighbor below and above i for which a // caplet has been read. int i0=i_0(i), i1=i_1(i); // annual vols of these double vol0=0, vol1=0; if(i0!=0)vol0=capletSigma[i0]/Math.sqrt(Tc[i0]); if(i1!=n)vol1=capletSigma[i1]/Math.sqrt(Tc[i1]); if((i0==0)&&(i1==n)){ System.out.println("\nNo caplets found. Aborting program."); System.exit(0); } if(i0==0) // use implied annual vol of i0 capletSigma[i]=vol1*Math.sqrt(Tc[i]); else if(i1==n) // use implied annual vol of i1 capletSigma[i]=vol0*Math.sqrt(Tc[i]); else // use arithmetic average of annual vols i0,i1 { double vol=0.5*(vol0+vol1); capletSigma[i]=vol*Math.sqrt(Tc[i]); } } // end interpolateCaplet /*******************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -