📄 cvxtrigger.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 using convex * deformation of the pure continuation region (see AmericanOptions.tex).</p> * * @author Michael J. Meyer */public class CvxTrigger extends Trigger { LiborProcess LP; BermudanSwaption bswpn; double kappa; // swaption strike double bScale; // scaling factor for variable beta int nPath, // number of training paths p, // swaption exercise begins T_p n; // swap ends T_n (dimension of Libor process) boolean verbose; // messages as the trigger optimizes itself double[] alpha, // alpha[t-p] ... exponent of Q(t) beta; // beta[t-p] ... sacaling factor of Q(t) CvxTriggerBase cvxBase; // object with the training paths and stored // precomputed exercise information LocalOptimizer bfgs; // optimizer to compute alpha,beta coefficients /******************************************************************************* * * AUXILLIARY FUNCTIONS * ******************************************************************************/ // forward payoff from exercise for s>=t under parameters v public double forwardExercisePayoff(int t, double[] v) { double sum=0.0; for(int i=0;i<nPath;i++){ double[][] path=cvxBase.getPath(i); // exercise time along this path, note t<=n-2 int s; if(cvxBase.exercise(i,t,v)) s=t; // exercise now else s=(int)path[t-p+1][2]; // exercise starting from t+1 // payoff is in path[i][s-p][0]; s=n - never exercised. if(s<n) sum+=path[s-p][0]; } // end i return -sum/nPath; } // end f /******************************************************************************* * * PARAMETER OPTIMIZATION * ******************************************************************************/ private class LocalOptimizer extends BFGS { int t, nPath; CvxTriggerBase cvxb; /** 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 (CvxTriggerBase cvxb, 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.cvxb=cvxb; // 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 from 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=cvxb.getPath(i); // exercise time along this path, note t<=n-2 int s; if(cvxb.exercise(i,t,v)) s=t; // exercise now else s=(int)path[t-p+1][2]; // exercise starting from t+1 // payoff is in path[i][s-p][0]; s=n - never exercised. if(s<n) sum+=path[s-p][0]; } // end i return -sum/nPath; } // end f } // end LocalOptimizer /******************************************************************************* * * ACCESSORS * ******************************************************************************/ public double[] getAlpha(){ return alpha; } public double[] getBeta(){ return beta; } /******************************************************************************* * * CONSTRUCTOR * ******************************************************************************/ /** * @param bswpn the Bermudan swaption we want to exercise * @param nPath number of training paths * @param verbose messages as the trigger optimizes itself */ public CvxTrigger(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(); cvxBase=new CvxTriggerBase(bswpn,nPath); bScale=cvxBase.getbScale(); // Q(t) exponents and scaling factors alpha=new double[n-p-1]; beta=new double[n-p-1]; computeCoefficients(); // cvxBase object exists already } // end constructor /******************************************************************************* * * p-PARAMETER COMPUTATION * ******************************************************************************/ /** The pj-coefficients computed by the local optimizer inner class * object. This method must be called before the trigger can be used. * It is not possible to do this in the constructor. */ public void computeCoefficients() { // common to all optimizers int nVals=500; // function evaluations // initial search point and step size // will be dynamically adjusted double alpha0=0.85, beta0=5*bswpn.Q(p)/bScale, stepmax=alpha0/5; double[] z={alpha0,beta0}, h={alpha0/15,beta0/6}; // 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(cvxBase,t,nPath,z,nVals,stepmax,h,verbose); double[] w=bfgs.search(); alpha[t-p]=w[0]; beta[t-p]=w[1]; // for each path set the flag indicating wether the coefficients // trigger at time t for(int i=0;i<nPath;i++){ double[][]path=cvxBase.getPath(i); if(cvxBase.exercise(i,t,w))path[t-p][2]=t; else path[t-p][2]=path[t+1-p][2]; } // set next starting point to last optimum z[0]=Math.min(0.85,w[0]); z[1]=w[1]; h[0]=z[0]/15; h[1]=z[1]/6; stepmax=Math.abs(z[0]/4); }// end t } // end computeCoefficients /******************************************************************************* * * THE TRIGGER CONDITION * ******************************************************************************/ 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 a=alpha[s-p], // optimal alpha for time t b=Math.abs(bScale*beta[s-p]), // optimal beta for time t h=bswpn.currentForwardPayoff(s), // h_t q=bswpn.Q(s); // Q(t) q=Math.log(q/b); q*=a; q=Math.exp(q); q*=b; // q=b*(Q(t)/b)^a return (h>q); } /******************************************************************************* * * 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=16, p=2, nPath=50000; 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; CvxTrigger cvx=new CvxTrigger(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."+ "\nalphas: "+new ColtVector(cvx.getAlpha()).toString()+ "\nbetas: "+new ColtVector(cvx.getBeta()).toString(); System.out.println(report); } // end main } // end pjTrigger
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -