📄 liborderivative.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*//* * LiborDerivative.java * * Created on September 6, 2002, 2:45 PM */package Libor.LiborDerivatives;import Libor.LiborProcess.*;import Statistics.*;/** <p>A derivative whose payoff is a functional of the path of a Libor * process. Since our implementation of the Libor process computes forward * Libors <code>L_i</code> only at the reset times <code>T_j</code> the * payoff <code>H</code> must be a deterministic function * <code>H=H(L_j(T_k); k<=j)</code>. This case covers caps, swaps, swaptions * trigger swaps, Bermudian swaptions and others but does not cover more * exotic derivatives which must evaluate Libors more frequently.</p> * * @author Michael J. Meyer */public abstract class LiborDerivative { int n, // number of Libors including L_0 k, // Libors needed to compute payoff: L_j, j>=k Tmax; // above Libors needed until time Tmax double[] Tc, // the tenor structure Tc[i]=T_i (continuous time) delta; // delta[j]=T_{j+1}-T_j /* A control variate is either implemented or not. * If it is implemented then it may only use the array LP.X of true * Libors or it may need the array LP.X0 or the array LP.X1 * (control variates computed from lognormal approximations). * We need to know which so only the necessary paths of the underlying * Libor process are computed forward (speed). */ boolean hasControlVariate, // set these from the concrete controlVariateNeedsX0, // subclasses controlVariateNeedsX1; LiborProcess LP; // underlying Libor process LiborVector LV; // approximate log normal Libor vector for fast // valuation /******************************************************************************* * * CONSTRUCTOR * ******************************************************************************/ /** <p>Optimized, only the Libors which are needed computed only as far * as needed (speed), allocates log-normal Libor vector for fast * valuation.</p> * * <p>"Payoff" means payoff transported forward to the horizon * <code>T=T_n</code>. The parameters <code>k,Tmax</code> allow us to * avoid the costly computation of full Libor paths.</p> * * @param LP underlying Libor process. * @param k Libors needed to compute payoff: <code>L_j; j>=k</code>. * @param Tmax computation of payoff needs Libors until time * <code>Tmax</code>. * @param LV log-normal approximate Libor vector for fast valuation */ public LiborDerivative (LiborProcess LP, int k, int Tmax, LiborVector LV) { n=LP.dimension(); this.k=k; this.Tmax=Tmax; Tc=LP.tenorStructure(); delta=LP.delta(); this.LP=LP; this.LV=LV; } /** Optimized, only the Libors which are needed computed only as far * as needed (speed). * "Payoff" means payoff transported forward to the horizon * <code>T=T_n</code>. The parameters <code>k,Tmax</code> allow us to * avoid the costly computation of full Libor paths. * * @param LP underlying Libor process. * @param k Libors needed to compute payoff: <code>L_j; j>=k</code>. * @param Tmax computation of payoff needs Libors until time * <code>Tmax</code>. */ public LiborDerivative (LiborProcess LP, int k, int Tmax) { n=LP.dimension(); this.k=k; this.Tmax=Tmax; Tc=LP.tenorStructure(); delta=LP.delta(); this.LP=LP; this.LV=LV; } /** <p>Payoff computed from full Libor paths, no control variate or lognormal * Libor vector.</p> * * @param LP underlying Libor process. */ public LiborDerivative(LiborProcess LP) { this.LP=LP; n=LP.dimension(); k=0; Tmax=n-1; Tc=LP.tenorStructure(); } /******************************************************************************* * * PAYOFF * ******************************************************************************/ /** <p>Forward transported payoff computed from the current Libor path * using the array <code>LP.X</code> of true Libors only. * Here <code>LP</code> is the underlying Libor process.</p> * * <p>If the option has payoffs at several points along the path these * must all be transported forward and aggregated at the horizon * <code>T_n</code>.</p> * * <p>Why the forward transporting? Recall that we are simulating the * Libor dynamics under the forward martingale measure <code>P_n</code>. * Consequently a Monte Carlo simulation computes expectations * <code>E^{P_n}</code> in this probability and we compute the forward * price <code>c_t(H)</code> of an option <code>H</code> at time * <code>t</code> as the conditional expectation <code>E^{P_n}_t(h)</code>. * This formula is correct only if <code>h</code> is the value of the * option payoff(s) at time <code>T_n</code>.</p> */ public abstract double currentForwardPayoff(); /** The forward transported payoff as a random variable. */ public RandomVariable forwardPayoff() { return new RandomVariable(){ public double getValue(int t) { LP.newPathSegment(t,Tmax,k); return currentForwardPayoff(); } }; } // end forwardPayoff /******************************************************************************* * * PAYOFF WITH CONTROL VARIATE * ******************************************************************************/ /** Mean of the control variate conditioned on the state of the * Libor path at time <code>t</code>. * This is a default implementation (error message and program abort) * intended to be overidden in concrete subclasses which do implement * a control variate. */ public double controlVariateMean(int t) { String warning= "LiborDerivative.currentControlledForwardPayoff():\n"+ "no control variate implemented, aborting."; System.out.println(warning); System.exit(0); return 0; // keeps the compiler happy } /** <p>Payoff-Controlvariate pair computed from current Libor path. * Can make use of the array <code>LP.X</code> of true Libors or * of one or both of the log-normal approximations * <code>LP.X0, LP.X1</code>. Make sure the boolean flags * <code>controlVariateNeedsX0, controlVariateNeedsX1</code> * are set from the implementing concrete subclass to ensure that * the underlying Libor process computes the corresponding paths * forward.</p> * * <p>This is a default implementation (error message and program abort) * intended to be overidden in concrete subclasses which do implement * a control variate.</p> */ public double[] currentControlledForwardPayoff() { String warning= "LiborDerivative.currentControlledForwardPayoff():\n"+ "no control variate implemented, aborting."; System.out.println(warning); System.exit(0); return new double[] {0,0}; // keeps the compiler happy } /** The controlled forward transported payoff as a random variable. */ public ControlledRandomVariable controlledForwardPayoff() { return new ControlledRandomVariable(){ public double[] getControlledValue(int t) { LP.newPathSegment (t,Tmax,k,true,controlVariateNeedsX0,controlVariateNeedsX1); return currentControlledForwardPayoff(); } public double getControlVariateMean(int t) { return controlVariateMean(t); } }; // end return new } // end forwardPayoff /******************************************************************************* * * PAYOFF BASED ON LOGNORMAL LIBOR APPROXIMATION * ******************************************************************************/ /** <p>The forward transported payoff seen from time <code>t=0</code> and * computed from a new sample of the Libor vector <code>this.LV</code> * instead of true Libors derived from paths of the underlying * <code>LiborProcess</code>. * * <p>This is a default implementation (error message and program abort) * intended to be overidden in concrete subclasses.</p> * * <p>The idea is to replace the simulation of Libor paths with the much * faster direct simulation of the log-normal Libor approximations. One * hopes that the distribution of the approximation is sufficiently close * to the distribution of true Libor. In our implementations we rely on * the <code>X0</code> approximation. Run the program * <code>Examples.LiborPaths.java</code> to see how closely the * <code>X0-paths</code> track true Libor.</p> * * <p>Note that this applies only to prices computed at time * <code>t=0</code>.</p> * */ public double lognormalForwardPayoffSample() { String warning= "LiborDerivative.lognormalForwardTransportedPayoff():\n"+ "not implemented, aborting."; System.out.println(warning); System.exit(0); return 0; // keeps the compiler happy } /** The {@link #lognormalForwardPayoff} as a random variable based * on the log-normal Libor vector <code>this.LV</code> as a proxy for * the vector of true Libors. */ public RandomVariable lognormalForwardPayoff() { return new RandomVariable(){ public double getValue(int t) { return lognormalForwardPayoffSample(); } }; // end return new } // end lognormalForwardPayoff /******************************************************************************* * * PRICING * ******************************************************************************/ /** The value of the time <code>T_n</code>-forward price at * discrete time <code>t</code> (continuous time <code>T_t</code>). * This is a default implementation (error message and program abort) * intended to be overidden in concrete subclasses.</p> * * @param t current disrete time. */ public double analyticForwardPrice(int t) { String warning= "LiborDerivative.analyticForwardPrice():\n"+ "no analytic price implemented, aborting."; System.out.println(warning); System.exit(0); return 0; // keeps the compiler happy } /** The value of the time <code>T_n</code>-forward price at * discrete time <code>t</code> (continuous time <code>T_t</code>). * * @param t current disrete time. * @param nPath number of Libor paths simulated. */ public double monteCarloForwardPrice(int t, int nPath) { return forwardPayoff().conditionalExpectation(t,nPath); } /** The value of the time <code>T_n</code>-forward price at time * discrete <code>t</code> (continuous time <code>T_t</code>). * * @param t current disrete time. * @param nPath number of Libor paths simulated. */ public double controlledMonteCarloForwardPrice(int t, int nPath) { return controlledForwardPayoff(). conditionalExpectation(t,nPath); } /** <p>The value of the time <code>T_n</code>-forward price at time * discrete <code>t=0</code> (continuous time <code>T_t</code>) * computed by direct simulation of the approximating log-normal * Libor vector <code>this.LV</code> instead of true Libor paths * (speed).</p> * * @param nPath number of Libor vector samples. */ public double lognormalMonteCarloForwardPrice(int nPath) { return lognormalForwardPayoff().expectation(nPath); } } // end LiborDerivative
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -