📄 bermudanswaption.java
字号:
* @param exercise exercise policy. */ public RandomVariable ForwardPayoff(final Trigger exercise) { RandomVariable payoff=new RandomVariable(){ public double getValue(int t) { return currentForwardPayoff(t,exercise); } }; // end forward_payoff return payoff; } //end ForwardPayoff /******************************************************************************* NAIVE EXERCISE POLICY *******************************************************************************/ // the continuation value CV(t) will be approximated as g(Q(t)), where // g(x)>x. Here are some functions g(x) we play around with /** <p>Function applied to {@link #Q} to approximate the true * continuation value <code>CV(t)</code>.</p> * * @param x positive real * @param alpha parameter * @param beta parameter * @param t current time * @param n number of Libors */ public double g(double x, double alpha, double beta, int t, int n) { // a linearly from alpha to 1 // b linearly from beta to b/1.5 double a,b,u; b=(n-t)*beta/n; if(x>b)u=x;else{ // u=max{q,b*(q/b)^a} a=((n-t)*alpha+t)/n; u=Math.log(x/b); u*=a; u=Math.exp(u); u*=b; } return u; }// end g /** <p>The approximation * <code>Q(t)=max{ E_t(h_{t+1}), E_t(h_{t+2}),..., E_t(h_T) }</code> * for the continuation value <code>CV(t)</code> computed from the current * Libor path. Note that all the conditional expectations are European * swaption prices.</p> * * @param t current time */ public double Q(int t) { double max=0; for(int j=t+1;j<n;j++){ double Ethj=swaptionAnalyticForwardPrice(t,j); if(Ethj>max)max=Ethj; } return max; } // end Q /** <p>Triggers as soon as <code>h_t> Q(t)</p>.</p> */ public Trigger pureTrigger() { return new Trigger(n) { 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); return(currentForwardPayoff(s)>Q(s)); } }; // return new } // end naiveExercise /** <p>The pure exercise trigger which exercises as soon as * <code>h(t)>g(t,Q(t))</code>, where * <code>g(t,x)=beta(x/beta)^alpha</code> with <code>alpha,beta</code> * depending on <code>t</code> and increasing to one, respectively * decreasing to zero as the end of the swap approaches. * * @param alpha smaller than 1, try 0.75 at t=20 years from expiry, * 1 at expiry and linear in between. * @param beta try 10 times the most expensive European swaption. */ public Trigger convexTrigger( final double alpha, final double beta) { return new Trigger(n) { 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 q=g(Q(s),alpha,beta,s,n); return(currentForwardPayoff(s)>q); } }; // return new } // end naiveExercise /** <p>Triggers as soon as <code>h_t> Q(t)+alpha(t)</p> where * <code>alpha(t)</code> decreases linearly from <code>alpha</code> to zero * as the end of the swaption approaches.</p> * * @param alpha parameter, should be chosen >0 very small. */ public Trigger shiftTrigger( final double alpha) { return new Trigger(n) { 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=(n-t-2)*alpha/(n-2); return(currentForwardPayoff(s)>Q(s)+alpha); } }; // return new } // end naiveExercise /******************************************************************************* MONTE CARLO PRICE *******************************************************************************/ /** <p>Monte Carlo price at time t dependent on a given exercise policy * computed as a conditional expectation * conditioned on <a href=#information>information</a> available at time t * and computed from a sample of nPath (branches of) the price path of the * underlying.</p> * * @param t current time (determines information to condition on). * @param nPath number of path branches used to compute the option price. * @param exercise exercise policy */ public double monteCarloForwardPrice (int t, int nPath, final Trigger exercise) { return ForwardPayoff(exercise).conditionalExpectation(t,nPath); } //end discMonteCarloPrice /** <p>Monte Carlo option price at time t=0.</p> * * @param nPath number of asset price paths used to compute the option price. */ public double monteCarloForwardPrice(int nPath, final Trigger exercise) { return monteCarloForwardPrice(0,nPath,exercise); } /******************************************************************************* * * 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 final int n=40, p=4; final double kappa=0.04; // strike rate boolean verbose=true; // Libor parameter sample final LMM_Parameters lmmParams=new LMM_Parameters(n,LMM_Parameters.JR); final LiborProcess LP=new LiborProcess(lmmParams); final BermudanSwaption bswpn=new BermudanSwaption(LP,p,kappa); final int nPaths=50000; double cvxPrice=0, pjPrice=0; double before=System.currentTimeMillis(), after, time; final Trigger cvx=new CvxTrigger(bswpn,nPaths/2,verbose); final Trigger pj=new PjTrigger(bswpn,nPaths/2,verbose); cvxPrice=bswpn.monteCarloForwardPrice(nPaths,cvx)*LP.B0(n); pjPrice=bswpn.monteCarloForwardPrice(nPaths,pj)*LP.B0(n); after=System.currentTimeMillis(); time=(after-before)*0.001; String report=LP.toString()+ "\n\nBermudan payer swaption: "+ "semi annual, "+n/2+" non call "+p/2+", Strike: "+kappa+ "\ncvxPrice: "+cvxPrice+ "\npjPrice: "+pjPrice+ "\nPaths: "+nPaths+ "\ntime: "+time+" sec."; System.out.println(report); } // end main } // end BermudanSwaption
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -