📄 pjtrigger.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/* * PjTrigger.java * * Created on November 27, 2002, 11:47 PM */package Libor.LiborDerivatives;import Libor.LiborProcess.*;import Triggers.*;import Optimizers.*;import LinAlg.*;/** <p>Exercise trigger of a Bermudan swaption following * Peter Jaeckel. Akwardly a base object has to be fully constructed * before the trigger can be constructed.</p> * * @author Michael J. Meyer */public class PjTrigger extends Trigger { LiborProcess LP; BermudanSwaption bswpn; double kappa; // swaption strike int nPath, // number of training paths p, // swaption exercise begins T_p n; // swap ends T_n (dimension of Libor process) boolean verbose; // messages during optimization double[] S, // the swap rates at time zero p1,p2,p3; // pj[t-p] pj's p-coefficients PjTriggerBase pjBase; // object with the training paths and stored // precomputed exercise information LocalOptimizer bfgs; /******************************************************************************* * * PARAMETER OPTIMIZATION * ******************************************************************************/ private class LocalOptimizer extends BFGS { int t, nPath; PjTriggerBase pjb; /** This is used to optimize the parameters <code>p0,p1,p2</code> * used to parametrize the exercise boundary. * * @param pjb base object containing the training paths * @param t exercise time * @param nPath number of training paths * @param x starting parameter vector * @param nVals number of function evaluations * @param stepmax maximum stepsize in line search * @param h dricetional increments for gradient computation * @param verbose messages during optimization */ public LocalOptimizer (PjTriggerBase pjb, int t, int nPath, double[] x, int nVals, double stepmax, double[] h, boolean verbose) { // no complete allocation of super since calls to f // need the field nPath super(x,nVals,stepmax,h,verbose,false); this.nPath=nPath; this.t=t; this.pjb=pjb; // now complete the intialization of the super class setInitialConditions(); if(verbose){ System.err.println ("INITIAL POINT: "+new ColtVector(getX()).toString()); System.err.println ("INITIAL DIRECTION: "+new ColtVector(getD()).toString()); } } // end constructor // forward payoff fom exercise for s>=t under parameters v public double f(double[] v) { double sum=0.0; for(int i=0;i<nPath;i++){ double[][] path=pjb.getPath(i); // exercise time along this path, note t<=n-2 int s; if(pjb.exercise(i,t,v)) s=t; else s=(int)path[t-p+1][3]; // s=n never exercised, otherwise payoff is in path[i][s-p][2] if(s<n) sum+=path[s-p][2]; } // end i return -sum; } // end f } // end LocalOptimizer /******************************************************************************* * * ACCESSORS * ******************************************************************************/ public double[] getP1(){ return p1; } public double[] getP2(){ return p2; } public double[] getP3(){ return p3; } /******************************************************************************* * * CONSTRUCTOR * ******************************************************************************/ /** * @param bswpn the Bermudan swaption we want to exercise */ public PjTrigger(BermudanSwaption bswpn, int nPath, boolean verbose) { super(bswpn.getLP().dimension()); this.bswpn=bswpn; this.nPath=nPath; this.verbose=verbose; kappa=bswpn.getKappa(); LP=bswpn.getLP(); p=bswpn.getp(); n=LP.dimension(); pjBase=new PjTriggerBase(bswpn,nPath); S=pjBase.getS(); // Jaeckel's p-coefficients p1=new double[n-p-1]; p2=new double[n-p-1]; p3=new double[n-p-1]; computeCoefficients(); // pjBase object exists already } // end constructor /******************************************************************************* * * p-PARAMETER COMPUTATION * ******************************************************************************/ /** The pj-coefficients computed by the local optimizer inner class * object. */ public void computeCoefficients() { // common to all optimizers int nVals=120; // initial search point, // dynamically adjusted to be the optimum of the last search double[] z={kappa/2,kappa,0.75*kappa}, h={z[0]/4, z[1]/4, z[2]/4}; double stepmax=kappa/3; // backward recursive computation for(int t=n-2;t>=p;t--){ if(verbose) System.out.println("\nExercise point t="+t+"\n"); Optimizer bfgs=new LocalOptimizer(pjBase,t,nPath,z,nVals,stepmax,h,verbose); double[] pj=bfgs.search(); p1[t-p]=pj[0]; p2[t-p]=pj[1]; p3[t-p]=pj[2]; // for each path set the optimal exercise time s>=t starting // at time t for(int i=0;i<nPath;i++){ double[][]path=pjBase.getPath(i); if(pjBase.exercise(i,t,pj)) path[t-p][3]=t; else path[t-p][3]=path[t-p+1][3]; } //reset starting point to last optimum z=pj; h[0]=z[0]/4; h[1]=z[1]/4; h[2]=z[2]/4; stepmax=Math.max(Math.min(z[0],Math.min(z[1],z[2])),0.01)/2; }// end t } // end computeCoefficients /******************************************************************************* * * THE TRIGGER CONDITION * ******************************************************************************/ /** True if exercise is triggered at time <code>t</cod> false otherwise. * * @param t irrelevant * @param s current time */ public boolean isTriggered(int t, int s) { if(s<p)return false; if(s==n)return true; double f=LP.L(s,s); if(s==n-1)return(f>kappa); double sw=LP.swapRate(s+1,n,s), h=bswpn.currentForwardPayoff(s); return ((f-p3[s-p])*(sw-p2[s-p])>p1[s-p]*S[s-p])&&(sw>p2[s-p]) &&(h>0); } /******************************************************************************* * * TEST PROGRAM * ******************************************************************************/ /** <p>Test program. Allocates a Libor process of dimension * <code>n=20</code> and a semiannual 10 non call 2 Bermudan swaption. * Then computes the exercise boundary from the naive exercise strategy * at time <code>t=8</code>.</p> */ public static void main(String[] args) { // Libor process setup int n=20, p=2, nPath=10000; double kappa=0.04; // strike rate boolean verbose=true; // Libor parameter sample LMM_Parameters lmmParams=new LMM_Parameters(n,LMM_Parameters.JR); LiborProcess LP=new LiborProcess(lmmParams); BermudanSwaption bswpn=new BermudanSwaption(LP,p,kappa); double before=System.currentTimeMillis(), after, time; PjTrigger pj=new PjTrigger(bswpn,nPath,verbose); after=System.currentTimeMillis(); time=(after-before)*0.001; String report=LP.toString()+ "\n\nAllocating PjTrigger: "+ "semi annual, "+n/2+" non call "+p/2+", time: "+time+" sec."+ "\np1:"+new ColtVector(pj.getP1()).toString()+ "\np2:"+new ColtVector(pj.getP2()).toString()+ "\np3:"+new ColtVector(pj.getP3()).toString(); System.out.println(report); } // end main } // end PjTrigger
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -