Beispiel #1
0
        /// <summary>
        /// Price of a zcb at t > 0 with maturity TT > t
        /// as a function of the rate R, of the factor u at t
        /// and of the current zr curve (ZR)
        /// using the Hull &amp; White two-factor model
        /// <para>
        /// dr = (theta(t) + u - a * r) * dt + sigma1 * dz1
        /// du = -b * du * dt + sigma2 * dz2
        /// with dz1 * dz2 = rho * dt
        /// </para>
        /// (see Hull-White (1994) Journal of Derivatives).
        /// </summary>
        /// <param name="context">The underlying project context.</param>
        /// <param name="cache">Data structure where pre-calculated values are stored.</param>
        /// <param name="hw2">An HW2Context object to use for the evaluation.</param>
        /// <param name="R">Rate of return from time t to t+dt.</param>
        /// <param name="u">Factor u at t.</param>
        /// <param name="PT">Current price of a zcb maturing at TT.</param>
        /// <param name="P_t">Current price of a zcb maturing at t.</param>
        /// <param name="Pdt">Current price of a zcb maturing at t + dt.</param>
        /// <param name="TT">The bond maturity.</param>
        /// <param name="t">The initial date of the zcb.</param>
        /// <param name="dt">The length of time steps.</param>
        /// <returns>The value of the bond using the HW2 model.</returns>
        private static double BondHW2(Project context, SPCache cache, HW2Context hw2, double R, double u, double PT, double P_t, double Pdt, double TT, double t, double dt)
        {
            double a_a_b = +hw2.alpha1 * (hw2.alpha1 - hw2.alpha2);
            double b_a_b = +hw2.alpha2 * (hw2.alpha1 - hw2.alpha2);
            double ab    = hw2.alpha1 * hw2.alpha2;

            double TT_t = TT - t;

            int t_idx  = context.DiscreteTime(t);
            int TT_idx = context.DiscreteTime(TT);

            double aHat = 0;
            double bHat = 0;
            double cHat = 0;

#if _USE_CACHE_
#if !_SWAPTIONW_
            lock (cache)
#endif
            {
                if (!cache.IsCached_Eta[t_idx])
                {
                    cache.Cached_Eta[t_idx]   = Eta(t, t + dt, a, b, sigma1, sigma2, rho);
                    cache.IsCached_Eta[t_idx] = true;
                }
            }

            int TT_idx_rel = TT_idx - t_idx;
            if (cache.cache.J > TT_idx_rel)
            {
                HWCache2 cached_element = null;
#if !_SWAPTIONW_
                lock (cache.cache)
#endif
                {
                    if (!cache.cache.IsCached(t_idx, TT_idx_rel))
                    {
                        cached_element      = cache.cache.InsertToCache(t_idx, TT_idx_rel);
                        cached_element.Eta2 = Eta(t, TT, a, b, sigma1, sigma2, rho);
                        cached_element.Bhat = BHat(t, TT, dt, a);
                        cached_element.Chat = CHat(t, TT, dt, a, b, cached_element.Bhat);

                        double BtT  = (1 - Math.Exp(-a * (TT_t))) / a;
                        double Btdt = (1 - Math.Exp(-a * (dt))) / a;
                        cached_element.Ahat = PT / P_t * Math.Exp(-BtT / Btdt * Math.Log(Pdt / P_t)
                                                                  - cached_element.Eta2
                                                                  + BtT / Btdt * cache.Cached_Eta[t_idx]);
                    }
                }

                cached_element = cache.cache.Get(t_idx, TT_idx_rel);
                bHat           = cached_element.Bhat;
                cHat           = cached_element.Chat;
                aHat           = cached_element.Ahat;
            }
            else
            {
                double BtT  = (1 - Math.Exp(-a * (TT_t))) / a;
                double Btdt = (1 - Math.Exp(-a * (dt))) / a;

                aHat = PT / P_t * Math.Exp(-BtT / Btdt * Math.Log(Pdt / P_t)
                                           - Eta(t, TT, a, b, sigma1, sigma2, rho)
                                           + BtT / Btdt * cache.Cached_Eta[t_idx]);

                bHat = BHat(t, TT, dt, a);
                cHat = CHat(t, TT, dt, a, b, bHat);
            }
#else
            double BtT  = (1 - Math.Exp(-hw2.alpha1 * (TT_t))) / hw2.alpha1;
            double Btdt = (1 - Math.Exp(-hw2.alpha1 * (dt))) / hw2.alpha1;

            double l_Pdt_Pt = Math.Log(Pdt / P_t);
            double eta_TT   = hw2.Eta(t, TT);
            double eta_dt   = hw2.Eta(t, t + dt);

            double arg = -BtT / Btdt * (l_Pdt_Pt - eta_dt) - eta_TT;

            if (Engine.Log)
            {
                if (SolverContext.SimulationRealization == 0)
                {
                    Log.Write(string.Format("arg {0} eta_TT {1} eta_dt {2}", arg, eta_TT, eta_dt));
                }
            }
            aHat = (PT / P_t) * Math.Exp(arg);

            bHat = hw2.BHat(t, TT, dt);
            cHat = hw2.CHat(t, TT, dt, bHat);
#endif
            double bond = aHat * Math.Exp(-bHat * R - cHat * u);

#if     _CHECK_OWERFLOWS_
            if (Double.IsInfinity(bond))
            {
                bond = Double.MaxValue / 1000000;
            }
#endif
            return(bond);
        }
        /// <summary>
        /// Price of a zcb at t > 0 with maturity TT > t
        /// as a function of the rate R, of the factor u at t
        /// and of the current zr curve (ZR)
        /// using the Hull &amp; White two-factor model
        /// <para>
        /// dr = (theta(t) + u - a * r) * dt + sigma1 * dz1
        /// du = -b * du * dt + sigma2 * dz2
        /// with dz1 * dz2 = rho * dt
        /// </para>
        /// (see Hull-White (1994) Journal of Derivatives).
        /// </summary>
        /// <param name="context">The underlying project context.</param>
        /// <param name="cache">Data structure where pre-calculated values are stored.</param>
        /// <param name="hw2">An HW2Context object to use for the evaluation.</param>
        /// <param name="R">Rate of return from time t to t+dt.</param>
        /// <param name="u">Factor u at t.</param>
        /// <param name="PT">Current price of a zcb maturing at TT.</param>
        /// <param name="P_t">Current price of a zcb maturing at t.</param>
        /// <param name="Pdt">Current price of a zcb maturing at t + dt.</param>
        /// <param name="TT">The bond maturity.</param>
        /// <param name="t">The initial date of the zcb.</param>
        /// <param name="dt">The length of time steps.</param>
        /// <returns>The value of the bond using the HW2 model.</returns>
        private static double BondHW2(Project context, SPCache cache, HW2Context hw2, double R, double u, double PT, double P_t, double Pdt, double TT, double t, double dt)
        {
            double a_a_b = +hw2.alpha1 * (hw2.alpha1 - hw2.alpha2);
            double b_a_b = +hw2.alpha2 * (hw2.alpha1 - hw2.alpha2);
            double ab = hw2.alpha1 * hw2.alpha2;

            double TT_t = TT - t;

            int t_idx = context.DiscreteTime(t);
            int TT_idx = context.DiscreteTime(TT);

            double aHat = 0;
            double bHat = 0;
            double cHat = 0;
            #if _USE_CACHE_

            #if !_SWAPTIONW_
            lock (cache)
            #endif
            {
                if (!cache.IsCached_Eta[t_idx])
                {
                    cache.Cached_Eta[t_idx] = Eta(t, t + dt, a, b, sigma1, sigma2, rho);
                    cache.IsCached_Eta[t_idx] = true;
                }
            }

            int TT_idx_rel= TT_idx-t_idx;
            if(cache.cache.J>TT_idx_rel)
            {
                HWCache2 cached_element = null;
            #if !_SWAPTIONW_
                lock (cache.cache)
            #endif
                {
                    if (!cache.cache.IsCached(t_idx, TT_idx_rel))
                    {

                        cached_element = cache.cache.InsertToCache(t_idx, TT_idx_rel);
                        cached_element.Eta2 = Eta(t, TT, a, b, sigma1, sigma2, rho);
                        cached_element.Bhat = BHat(t, TT, dt, a);
                        cached_element.Chat = CHat(t, TT, dt, a, b, cached_element.Bhat);

                        double BtT = (1 - Math.Exp(-a * (TT_t))) / a;
                        double Btdt = (1 - Math.Exp(-a * (dt))) / a;
                        cached_element.Ahat = PT / P_t * Math.Exp(-BtT / Btdt * Math.Log(Pdt / P_t)
                                              - cached_element.Eta2
                                              + BtT / Btdt * cache.Cached_Eta[t_idx]);

                }
            }

            cached_element=cache.cache.Get(t_idx,TT_idx_rel);
            bHat=cached_element.Bhat;
            cHat=cached_element.Chat;
            aHat=cached_element.Ahat;
            }
            else
            {
            double BtT = (1 - Math.Exp(-a*(TT_t)))/a;
            double Btdt = (1 - Math.Exp(-a*(dt)))/a;

            aHat = PT/P_t *Math.Exp( -BtT/Btdt * Math.Log( Pdt/P_t )
                   - Eta(t,TT,a,b,sigma1,sigma2,rho)
                   + BtT/Btdt * cache.Cached_Eta[t_idx]);

            bHat=BHat(t,TT,dt,a);
            cHat=CHat(t,TT,dt,a,b,bHat);
            }
            #else
            double BtT = (1 - Math.Exp(-hw2.alpha1 * (TT_t))) / hw2.alpha1;
            double Btdt = (1 - Math.Exp(-hw2.alpha1 * (dt))) / hw2.alpha1;

            double l_Pdt_Pt = Math.Log(Pdt / P_t);
            double eta_TT = hw2.Eta(t, TT);
            double eta_dt = hw2.Eta(t, t + dt);

            double arg = -BtT / Btdt * (l_Pdt_Pt - eta_dt) - eta_TT;

            if (Engine.Log)
                if (SolverContext.SimulationRealization == 0)
                    Log.Write(string.Format("arg {0} eta_TT {1} eta_dt {2}", arg, eta_TT, eta_dt));
            aHat = (PT / P_t) * Math.Exp(arg);

            bHat = hw2.BHat(t, TT, dt);
            cHat = hw2.CHat(t, TT, dt, bHat);
            #endif
            double bond = aHat * Math.Exp(-bHat * R - cHat * u);

            #if     _CHECK_OWERFLOWS_
            if(Double.IsInfinity(bond))
            bond= Double.MaxValue/1000000;
            #endif
            return bond;
        }