⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 calibrator.java

📁 金融资产定价,随机过程,MONTE CARLO 模拟 JAVA 程序和文档资料
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    *    * @param p swap starts at <code>T_p</code>    * @param q swap stops at <code>T_q</code>    * @param kappa strike rate.    */   public double swaptionPrice(int p, int q, double kappa)   {       double S_pq0=S_pq[p][q-p],              // swap rate S_pq(0)              swpnSigma,Nplus,Nminus;                                      swpnSigma=Sigma(p,q);        // aggregate volatility to expiry                             Nplus=FinMath.N(FinMath.d_plus(S_pq0,kappa,swpnSigma));       Nminus=FinMath.N(FinMath.d_minus(S_pq0,kappa,swpnSigma));            return B_pq[p][q-p]*(S_pq0*Nplus-kappa*Nminus);     } // end swaptionPrice          /******************************************************************************* * *                  INTEGRAL OF VOLATILITY FUNCTION g * ******************************************************************************/                    //EXPONENTIAL INTEGRALS:          // integral exp(s/D)ds       double F(double D, double s){ return D*Math.exp(s/D); }            // integral s*exp(s/D)ds      double G(double D, double s){ return D*Math.exp(s/D)*(s-D); }         // integral s^2*exp(s/D)ds       double H(double D, double s){ return D*Math.exp(s/D)*((s-D)*(s-D)+D*D); }           /** <code>integral_0^T g(u)^2du</code>, where <code>g(u)</code> is the      *  function defining the volatilities       *  <code>sigma_j(t)=c_jg(1-t/T_j)</code> in the {@link CS_FactorLoading}.      *  Makes use of the current values of the fields      *  <code>A,D,rho00,alpha,beta</code>.      */      public double integral_g_squared(double T)      {          double R=T;          R+=2*A*(G(-D,T)+D*D);          R+=A*A*(H(-D/2,T)+D*D*D/4);                 return R;      } //end Integral_g_squared        /******************************************************************************* * *                          CALIBRATION * ******************************************************************************/               //<!--Greek characters tau="&#03C4", epsilon="&#949" -->                 /** <p><a name="calibration"><b>Calibration</b></a>       *  of a {@link CS_FactorLoading} to caplet and swaption       *  prices. All caplets are used and missing caplets interpolated.       *  Caplet prices are matched precisely.      *  Only available swaptions are used, missing swaptions are ignored.</p>      *      * <p>The calibration routine is an "exhaustive" search of the parameter      * rectangle along a low discrepancy sequence. The routine repeatedly      * narrows the search space to a smaller rectangle around the current       * optimum.</p>      *      * <p>The calibration routine tries to minimize the mean percent deviation      * of model computed analytic swaption prices from quoted prices and       * returns an <code>LMM_Parameters</code> object which can be handed to a       * constructor to instantiate a <code>LiborProcess.</p>      *      * <p>Intial search region for the <code>CS_FactorLoading</code>      * parameters:<br>      * <code>A &#949;[0,30], D &#949;[0.1,0.9], rho00 &#949;[0.01,0.8],      *       alpha &#949;[0,-6log(rho00)], beta &#949;[0,alpha/n].      * </code><br>      * It is a good idea to modify these settings (in the source code)      * to see how this alters the performance. Experiments show some      * <a href=#main>unexpected phenomena</a>.      * </p>      *      */     public LMM_Parameters calibrate(int nPoints)     {         readCaplets();         readSwaptions();                  // the basic generator for the search points, 5 parameters         LowDiscrepancySequence sbl=new Sobol(5);                  System.out.println("ZOOMING IN ON OPTIMUM, 10 ZOOM LEVELS.");                  //initial search range         double A_min=0, A_max=30,                D_min=0.1, D_max=0.9,                rho_min=0.01, rho_max=0.8,                alpha_min=0, alpha_max=10,                beta_min=0, beta_max=alpha_max/(3*n);                  // zoom depth          int zoom=0;                                                                                    // current optima, minimal error         double A_opt=0, D_opt=0,                rho00_opt=0, alpha_opt=0, beta_opt=0,                // swaption price errors                error_min=1000000,        // minimal mean percent error                percent_error,            // percent deviation, current swaption                sum_percent_error,        // sum of percent error                           mean_percent_error;       // mean of percent errors                                                            // loop over zoom levels         while(zoom<10)         {              System.out.println("\nZOOM DEPTH: "+zoom);              if(zoom>0){                        // search range zooms in on current optimum, reduce number of                   // search points                  double down=(2.0*zoom)/(2.0*zoom+1),                          up=1.0/down;                  A_min=down*A_opt; A_max=up*A_opt;                  D_min=down*D_opt; D_max=up*D_opt;                  rho_min=down*rho00_opt; rho_max=up*rho00_opt;                  alpha_min=down*alpha_opt; alpha_max=up*alpha_opt;                  beta_min=down*beta_opt; beta_max=up*beta_opt;                                    nPoints=3*nPoints/5;                                } //end if                                               System.out.println("Mean swaption price error (%): ");              //random search over x=(A,D,rho00,alpha,beta) along points              // of a Sobol sequence                            LoopStatus loopStatus=new LoopStatus();              long before=System.currentTimeMillis();              // loop progress reported 100 times              int m=nPoints/100;                               sbl.restart();              for(int pt=1;pt<nPoints;pt++)              {                    double[] x=sbl.nextPoint();                  A=A_min+x[0]*(A_max-A_min);                  D=D_min+x[1]*(D_max-D_min);                  rho00=rho_min+x[2]*(rho_max-rho_min);                  rho00=Math.min(rho00,0.8);                  alpha=alpha_min+x[3]*(alpha_max-alpha_min);                  // parameter condition for alpha                  alpha=Math.min(alpha,-6*Math.log(rho00));                  beta=beta_min+x[4]*(beta_max-beta_min);                  // parameter condition for beta                  beta=Math.min(beta,alpha/(3*n));                  beta=Math.min(beta,3*(-Math.log(rho00)-alpha/6));                  //search vector complete                               setParameters(A,D,alpha,beta,rho00);                                    // compute the c[j]=c_j to match the caplet implied vols                  for(int i=1;i<n;i++)                  c[i]=capletSigma[i]/Math.sqrt(Tc[i]*integral_g_squared(1.0));                  // with this set the factor loading                      setFactorLoading                  (new CS_FactorLoading(n,A,D,alpha,beta,rho00,c,Tc));                                    setCholeskyRoots();                     // error with the new parameters                   sum_percent_error=0;                  int nSwpn=0;                     // number of swaptions                  // loop through the swaptions,                  Iterator swapnIterator=swaptions.iterator();                  while(swapnIterator.hasNext())                  {                      double price, modelprice, kappa;                      int p,q;                      // get the next swaption and extract the parameters                      Swpn swpn=(Swpn)swapnIterator.next();                      p=swpn.p;                      q=swpn.q;                      kappa=swpn.kappa;                      price=swpn.price;                                            // compute the analytic LMM-model price for this swaption                      modelprice=swaptionPrice(p,q,kappa);                                            // percent error, current swaption                      percent_error=Math.abs(price-modelprice)/price;                                            // cumulative squared error and percent_error                      sum_percent_error+=percent_error;                      nSwpn++;                  } // end swaption loop                                    // check if we have a new optimum                  mean_percent_error=sum_percent_error/nSwpn;                  if(mean_percent_error<error_min){                                            A_opt=A; D_opt=D;                       rho00_opt=rho00; alpha_opt=alpha; beta_opt=beta;                                            error_min=mean_percent_error;                      // mean swaption price error in percent                      mean_percent_error*=100;                      // cut this down to 4 digits                      String report=new Double(mean_percent_error).toString();                      report=report.substring(0,4);                      System.out.println(report);                  }                                    // progress report on pt-loop                  if((m>1)&&(pt%m==m-1))                  loopStatus.progressReport(pt,nPoints,m,before);                                 } // end for(pt)                                    zoom++;                      } // end while(zoom)          // parameters are set to optimum, return LMM_parameters object                  System.out.println("\nOPTIMAL PARAMETERS:\n");         printParameters();                       return new LMM_Parameters(l,factorLoading);             } // end calibrate                  /******************************************************************************* * *                        TEST PROGRAM * ******************************************************************************/            /** <p><a name="main"><b>Calibration test</b>,</a>       *  calibrates a {@link CS_FactorLoading} to a set of data in dimension       *  <code>n=15</code>.</p>      *      *  <p>The data are synthetic prices generated from a Libor process based      *  on a {@link EP_FactorLoading}. These data are then used to calibrate      *  a {@link CS_FactorLoading}.</p>      *      *  <p>Recall that the calibration routine does not build an initial term       *  structure of forward Libors (from quoted Libors and swap rates) but       *  instead receives the precise initial term strucutre as a parameter.      *  Likewise an <code>EP_FactorLoading</code> is close in spirit to a      *  <code>CS_FactorLoading</code>. Both have humped forward Libor      *  volatilities and a correlation structure of the form      *  <code>rho_ij=b_i/b_j, i&lt=j</code> where <code>b_i</code> is an      *  increasing sequence. Needless to say this makes calibration easier.      *  </p>       *      * <p>Obviously it is extremely important to test this routine and the      * concept of a <code>CS_FactorLoading</code> on market data. Thus this      * class and its methods should mainly be viewed as an infrastructure to      * base your own calibration experiments on and as an example of how      * one might go about doing this.</p>      *      * <p>Even so some interesting phenomena are already evident in this       * rudimentary example. In particular it is observed that the optimal      * parameter values are often highly nonintuitive. For example very      * large volatility bumps (large parameter <code>A</code>) combined with       * very low correlations (much lower than in the data) often match the data       * very closely. Moreover widely different parameter tuples yield very good      * approximations. Of course this could be interpreted as saying that we      * are not close to an optimum yet. On the other hand the model      * swaption prices show a mean percentage error of less than       * <code>0.5%</code>, a very good approximation indeed.</p>      */     public static void main(String[] args)     throws IOException     {          int n=15,              nPoints=5000;                   double delta=0.25;                   double[] l=new double[n],                   c=new double[n],                   Tc=new double[n+1];                    for(int i=0;i<n;i++){ l[i]=0.04; c[i]=0; Tc[i]=i*delta; }          Tc[n]=n*delta;                    System.out.println          ("Writing synthetic swaption and caplet price files.\n"+           "Using EP_FactorLoading.");          new SyntheticData("Caplets","Swaptions").writeData(n);                   System.out.println          ("\nCalibrating CS_FactorLoading to synthetic prices.\n");          new  Calibrator(n,l,c,Tc,"Caplets","Swaptions").calibrate(nPoints);                } // end main                     } // end Calibrator

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -