Exemplo n.º 1
0
        public void TestSkewDigitalEuroCallPut()
        {
            DateTime today        = new DateTime(2010, 06, 22);
            DateTime expiry       = new DateTime(2011, 03, 24);
            double   tau          = System.Convert.ToDouble(expiry.Subtract(today).Days) / 365.0;
            double   spot         = 42.00;
            double   upperbarrier = 44.00;
            double   lowerbarrier = 40.00;

            int[]             zerodays  = { 0, 10 };
            double[]          zerorates = { 0.05, 0.05 };
            int[]             divdays   = new int[] { 0, 51, 247 };
            double[]          divAmts   = new double[] { 4, 1.350, 1.420 };
            double            fwd       = EquityAnalytics.GetForwardCCLin365(spot, tau, divdays, divAmts, zerodays, zerorates);
            OrcWingParameters owp       = new OrcWingParameters()
            {
                AtmForward = fwd, CallCurve = 0.1250, CurrentVol = 0.26, DnCutoff = -0.25, Dsr = 0.9, PutCurve = 0.10, RefFwd = fwd, RefVol = 0.26, Scr = 0.0, SlopeRef = -0.1750, Ssr = 100, TimeToMaturity = tau, UpCutoff = 0.20, Usr = 0.50, Vcr = 0.0
            };
            List <OrcWingParameters> owpList = new List <OrcWingParameters>();

            owpList.Add(owp);
            double     skew1 = EquityAnalytics.GetWingSkew(owpList, new LinearInterpolation(), tau, upperbarrier);
            double     vol   = EquityAnalytics.GetWingValue(owpList, new LinearInterpolation(), tau, upperbarrier);
            BinaryEuro op1   = new BinaryEuro(spot, upperbarrier, true, tau, vol, zerodays, zerorates, divdays, divAmts, skew1);
            double     pr1   = op1.GetPrice();

            Assert.AreEqual(0.35784, pr1, 0.005);
            double     skew2 = EquityAnalytics.GetWingSkew(owpList, new LinearInterpolation(), tau, lowerbarrier);
            BinaryEuro op2   = new BinaryEuro(spot, lowerbarrier, false, tau, vol, zerodays, zerorates, divdays, divAmts, skew2);
            double     pr2   = op2.GetPrice();

            Assert.AreEqual(0.43275, pr2, 0.005);
        }
Exemplo n.º 2
0
        ///<summary>
        ///</summary>
        ///<param name="vols"></param>
        ///<param name="days"></param>
        ///<param name="spot"></param>
        ///<param name="ratedays"></param>
        ///<param name="rateamts"></param>
        ///<param name="divdays"></param>
        ///<param name="divamts"></param>
        ///<returns></returns>
        private List <OrcWingParameters> UnpackWing(double[,] vols, double[] days, double spot, int[] ratedays, double[] rateamts, int[] divdays, double[] divamts)
        {
            const double daybasis = 365.0;
            int          rows     = vols.GetLength(0);
            var          opList   = new List <OrcWingParameters>();

            for (int idx = 0; idx < rows; idx++)
            {
                double fwd = EquityAnalytics.GetForwardCCLin365(spot, days[idx] / daybasis, divdays, divamts, ratedays, rateamts);
                var    op  = new OrcWingParameters
                {
                    AtmForward     = fwd,
                    CurrentVol     = vols[idx, 0],
                    SlopeRef       = vols[idx, 1],
                    PutCurve       = vols[idx, 2],
                    CallCurve      = vols[idx, 3],
                    DnCutoff       = vols[idx, 4],
                    UpCutoff       = vols[idx, 5],
                    Vcr            = vols[idx, 6],
                    Scr            = vols[idx, 7],
                    Ssr            = 100 * vols[idx, 8],
                    Dsr            = vols[idx, 9],
                    Usr            = vols[idx, 10],
                    RefVol         = vols[idx, 11],
                    RefFwd         = fwd,
                    TimeToMaturity = days[idx] / daybasis
                };
                opList.Add(op);
            }
            return(opList);
        }
Exemplo n.º 3
0
        public void TestPCEProfile()
        {
            DateTime today      = new DateTime(2010, 10, 22);
            DateTime expiry     = new DateTime(2011, 10, 22);
            double   maturity   = Convert.ToDouble(expiry.Subtract(today).Days) / 365.0;
            double   spot       = 4200.00;
            int      simuls     = 10000;
            double   callstrike = 1.3 * spot;
            double   putstrike  = 1.0 * spot;

            int[]  zerodays   = { 0, 365 };
            double r0         = 0.065;
            double confidence = 0.95;

            double[] zerorates = { r0, r0 };
            int[]    divdays   = { 1, 51, 247 };
            double[] divamts   = { 22.5, 50, 50 };
            double   fwd       = EquityAnalytics.GetForwardCCLin365(spot, maturity, divdays, divamts, zerodays, zerorates);
            double   histvol   = 0.60;
            double   theta     = Math.Log(spot);
            double   kappa     = 0.9;

            double[]          times = { 7.0 / 365.0, 128.0 / 365.0, 250.0 / 365.0, 365.0 / 365.0, 730.0 / 365.0 };
            OrcWingParameters owp   = new OrcWingParameters {
                AtmForward = fwd, CallCurve = 0.1250, CurrentVol = 0.26, DnCutoff = -0.25, Dsr = 0.9, PutCurve = 0.10, RefFwd = fwd, RefVol = 0.26, Scr = 0.0, SlopeRef = -0.1750, Ssr = 100, TimeToMaturity = maturity, UpCutoff = 0.20, Usr = 0.50, Vcr = 0.0
            };
            List <OrcWingParameters> owpList = new List <OrcWingParameters> {
                owp
            };

            double[,] results = EquityPCEAnalytics.GetCollarPCE("CollarPCE",
                                                                zerodays,
                                                                zerorates,
                                                                divdays,
                                                                divamts,
                                                                owpList,
                                                                spot,
                                                                callstrike,
                                                                putstrike,
                                                                maturity,
                                                                kappa,
                                                                theta,
                                                                histvol,
                                                                times,
                                                                confidence,
                                                                0.25 / 365.0,
                                                                simuls,
                                                                3151);
            double lhs1 = PCEProxyCalc(spot, kappa, theta, histvol, times[0], maturity, callstrike, putstrike, zerodays, zerorates, divdays, divamts, owpList);
            double lhs2 = PCEProxyCalc(spot, kappa, theta, histvol, times[1], maturity, callstrike, putstrike, zerodays, zerorates, divdays, divamts, owpList);
            double lhs3 = PCEProxyCalc(spot, kappa, theta, histvol, times[2], maturity, callstrike, putstrike, zerodays, zerorates, divdays, divamts, owpList);

            Assert.AreEqual(results[0, 1], lhs1, Math.Abs(0.10 * results[0, 1]));
            Assert.AreEqual(results[1, 1], lhs2, Math.Abs(0.10 * results[1, 1]));
            Assert.AreEqual(results[2, 1], lhs3, Math.Abs(0.10 * results[2, 1]));
        }
Exemplo n.º 4
0
        public static double Value(double k, OrcWingParameters parameters)
        {
            double vol = 0.0;
            double f   = Math.Pow(parameters.AtmForward, parameters.Ssr / 100.0) * Math.Pow(parameters.RefFwd, 1.0 - parameters.Ssr / 100.0);
            double aux = Math.Log(k / f);
            //var usc = f * Math.Exp(Parameters.UpCutoff);
            //var dsc = f * Math.Exp(Parameters.DnCutoff);
            double sc = (parameters.SlopeRef - parameters.Scr * parameters.Ssr * (parameters.AtmForward - parameters.RefFwd) / parameters.RefFwd);
            double f1 = 1.0;
            double f2 = aux;
            double f3 = 0.0;

            if (aux <= 0.0)
            {
                f3 = aux * aux;
            }
            double f4 = 0.0;

            if (aux > 0.0)
            {
                f4 = aux * aux;
            }
            //Volatility surface calculations;
            if (aux <= (1.0 + parameters.Dsr) * parameters.DnCutoff)
            {
                vol = parameters.CurrentVol + parameters.DnCutoff * (2.0 + parameters.Dsr) * (sc / 2.0) + (1.0 + parameters.Dsr) * parameters.PutCurve * parameters.DnCutoff * parameters.DnCutoff;
            }
            else if (((1.0 + parameters.Dsr) * parameters.DnCutoff < aux) & (aux <= parameters.DnCutoff))
            {
                vol = (-parameters.PutCurve / parameters.Dsr - sc / (2.0 * parameters.DnCutoff * parameters.Dsr)) * aux * aux
                      + (1.0 + parameters.Dsr) / parameters.Dsr * (2 * parameters.PutCurve * parameters.DnCutoff + sc) * aux
                      - parameters.PutCurve * parameters.DnCutoff * parameters.DnCutoff * (1.0 + 1.0 / parameters.Dsr)
                      - sc * parameters.DnCutoff / (2.0 * parameters.Dsr)
                      + parameters.CurrentVol;
            }
            else if ((parameters.UpCutoff < aux) & (aux <= (1.0 + parameters.Usr) * parameters.UpCutoff))
            {
                vol = (-parameters.CallCurve / parameters.Usr - sc / (2.0 * parameters.UpCutoff * parameters.Usr)) * aux * aux
                      + (1.0 + parameters.Usr) / parameters.Usr * (2.0 * parameters.CallCurve * parameters.UpCutoff + sc) * aux
                      - parameters.CallCurve * parameters.UpCutoff * parameters.UpCutoff * (1.0 + 1.0 / parameters.Usr)
                      - sc * parameters.UpCutoff / (2.0 * parameters.Usr)
                      + parameters.CurrentVol;
            }
            else if (aux > (1.0 + parameters.Usr) * parameters.UpCutoff)
            {
                vol = parameters.CurrentVol
                      + parameters.UpCutoff * (2.0 + parameters.Usr) * (sc / 2.0)
                      + (1.0 + parameters.Usr) * parameters.CallCurve * parameters.UpCutoff * parameters.UpCutoff;
            }
            else if ((parameters.Scr == 0.0) && (parameters.Vcr == 0.0))
            {
                vol = parameters.CurrentVol * f1 + sc * f2 + parameters.PutCurve * f3 + parameters.CallCurve * f4;
            }
            return(vol);
        }
Exemplo n.º 5
0
        public void WingCalibration()
        {
            var stock = TestDataHelper.GetStock("AGK");

            Assert.AreEqual("AGK", stock.Name);
            var stockObject = TestHelper.CreateStock(stock);

            stockObject.CalcForwards();
            if (stockObject.VolatilitySurface.Expiries[0].Strikes[0].InterpModel.GetType() == typeof(WingInterp))
            {
                stockObject.VolatilitySurface.Calibrate();
                var exp0    = new List <DateTime>();
                var strike0 = new List <double>();
                exp0.Add(new DateTime(2009, 09, 16));
                strike0.Add(810);
                List <ForwardExpiry> expiry = stockObject.VolatilitySurface.ValueAt(stockObject, exp0, strike0, false);
                OrcWingParameters    wing   = new OrcWingParameters();
                ForwardExpiry        exp    = stockObject.VolatilitySurface.Expiries[0];
                Strike str = exp.Strikes[0];
                wing.AtmForward = str.InterpModel.WingParams.AtmForward;
                wing.CallCurve  = str.InterpModel.WingParams.CallCurve;
                wing.CurrentVol = str.InterpModel.WingParams.CurrentVol;
                double moneyness = Convert.ToDouble(exp.FwdPrice / stockObject.Spot);
                wing.DnCutoff = str.InterpModel.WingParams.DnCutoff;
                wing.Dsr      = str.InterpModel.WingParams.Dsr;
                wing.PutCurve = str.InterpModel.WingParams.PutCurve;
                wing.RefFwd   = str.InterpModel.WingParams.RefFwd;
                wing.RefVol   = str.InterpModel.WingParams.CurrentVol;
                wing.Scr      = str.InterpModel.WingParams.Scr;
                wing.SlopeRef = str.InterpModel.WingParams.SlopeRef;
                wing.Ssr      = str.InterpModel.WingParams.Ssr;
                wing.UpCutoff = str.InterpModel.WingParams.UpCutoff;
                wing.Usr      = str.InterpModel.WingParams.Usr;
                wing.Vcr      = str.InterpModel.WingParams.Vcr;
                var     forwardexpiry = stockObject.VolatilitySurface.ValueAt(stockObject, new DateTime(2009, 09, 16), strike0, wing, false, false);
                decimal calibrateBack = Math.Round(expiry[0].Strikes[0].Volatility.Value, 4);
                decimal ovridePoint   = Math.Round(forwardexpiry.Strikes[0].Volatility.Value, 4);
                // Can we use ValueAt to value back at our calibrated point (x=7/365,y=8.66);
                Assert.AreEqual(0.59500M, calibrateBack);
                // Can we override with fitted model and arrive back at calibrated point (x=7/365,y=8.66);
                Assert.AreEqual(ovridePoint, 0.5950M);
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Values at, overriding calibrated Wing Model with supplied parms
        /// </summary>
        /// <param name="stock"></param>
        /// <param name="expiry">The expiry.</param>
        /// <param name="strikes">The strikes.</param>
        /// <param name="parms">The parms.</param>
        /// <param name="oride"></param>
        /// <param name="cache">if set to <c>true</c> [cache].</param>
        /// <returns></returns>
        public ForwardExpiry ValueAt(Stock stock, DateTime expiry, List <Double> strikes, OrcWingParameters parms, bool oride, bool cache)
        {
            var fwdExpiry = new ForwardExpiry {
                ExpiryDate = expiry
            };
            double forward = stock.GetForward(stock.Date, expiry);

            fwdExpiry.FwdPrice = Convert.ToDecimal(forward);
            foreach (double strike in strikes)
            {
                double           val = OrcWingVol.Value(strike, parms);
                IVolatilityPoint vp  = new VolatilityPoint();
                vp.SetVolatility(Convert.ToDecimal(val), VolatilityState.Default());
                bool   node = VolatilitySurfaceHelper.IsMatch(strike, expiry, NodalExpiries);
                Strike newstrike;
                if (node & oride)
                {
                    newstrike = VolatilitySurfaceHelper.GetStrike(strike, expiry, NodalExpiries);
                    //new data points, derefernce fitting model
                    newstrike.InterpModel = null;
                }
                else
                {
                    //var wingModel = new WingInterp {WingParams = parms};
                    newstrike = new Strike {
                        StrikePrice = strike, InterpModel = null
                    };
                    //newstrike.InterpModel = wingModel;
                    fwdExpiry.AddStrike(newstrike, node);
                }
                newstrike.SetVolatility(vp);
            }
            return(fwdExpiry);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Tests the fitter.
        /// </summary>
        private void CalibrateToFoCurve(double fwd1, double cc1, double vc1, double dc1, double dsr1, double pc1, double scr1, double sr1, double ssr1, double uc1, double usr1, double vcr1,
                                        double fwd2, double cc2, double vc2, double dc2, double dsr2, double pc2, double scr2, double sr2, double ssr2, double uc2, double usr2, double vcr2,
                                        DateTime exp1, DateTime exp2)
        {
            var stock = TestDataHelper.GetStock("AGK");

            Assert.AreEqual("AGK", stock.Name);
            var           stockObject = TestHelper.CreateStock(stock);
            ForwardExpiry expiry1     = new ForwardExpiry(exp1, Convert.ToDecimal(fwd1));
            ForwardExpiry expiry2     = new ForwardExpiry(exp2, Convert.ToDecimal(fwd2));

            double[] sdStrikeMults = { 0.6,
                                       0.7,
                                       0.75,
                                       0.8,
                                       0.85,
                                       0.87,
                                       0.9,
                                       0.92,
                                       0.94,
                                       0.95,
                                       0.96,
                                       0.98,
                                       1,
                                       1.02,
                                       1.04,
                                       1.05,
                                       1.06,
                                       1.08,
                                       1.1,
                                       1.12,
                                       1.15,
                                       1.2,
                                       1.25,
                                       1.3,
                                       1.4,
                                       1.45,
                                       1.5,
                                       1.55,
                                       1.6,
                                       1.65,
                                       1.7,
                                       1.75,
                                       1.8,
                                       1.85,
                                       1.9,
                                       1.95,
                                       2 };

            OrcWingParameters parms1 = new OrcWingParameters
            {
                AtmForward = fwd1,
                CallCurve  = cc1,
                CurrentVol = vc1,
                DnCutoff   = dc1,
                Dsr        = dsr1,
                PutCurve   = pc1,
                RefFwd     = fwd1,
                RefVol     = vc1,
                Scr        = scr1,
                SlopeRef   = sr1,
                Ssr        = ssr1,
                UpCutoff   = uc1,
                Usr        = usr1,
                Vcr        = vcr1
            };
            OrcWingParameters parms2 = new OrcWingParameters
            {
                AtmForward = fwd2,
                CallCurve  = cc2,
                CurrentVol = vc2,
                DnCutoff   = dc2,
                Dsr        = dsr2,
                PutCurve   = pc2,
                RefFwd     = fwd2,
                RefVol     = vc1,
                Scr        = scr2,
                SlopeRef   = sr2,
                Ssr        = ssr2,
                UpCutoff   = uc2,
                Usr        = usr2,
                Vcr        = vcr2
            };
            //Override
            double        spot    = Convert.ToDouble(stockObject.Spot);
            List <double> strikes = new List <double>();

            foreach (double mul in sdStrikeMults)
            {
                Strike str0 = new Strike(mul * spot, null, null, Units.Cents);
                strikes.Add(str0.StrikePrice);
            }
            ForwardExpiry FOexpiry1 = stockObject.VolatilitySurface.ValueAt(stockObject, exp1, strikes, parms1, true, false);
            ForwardExpiry FOexpiry2 = stockObject.VolatilitySurface.ValueAt(stockObject, exp2, strikes, parms2, true, false);

            stockObject.VolatilitySurface.AddExpiry(FOexpiry1);
            stockObject.VolatilitySurface.AddExpiry(FOexpiry2);
            stockObject.VolatilitySurface.Calibrate();
            // Then  ValueAt() on an arbitrary grid now you have calibrated to your FO vols
        }
Exemplo n.º 8
0
        /// <summary>
        /// Before calculating any PCE numbers on the simulation set, first check the simulated asset values
        /// at the time slices and compare to the expected values of the theoretical distribution.
        /// Check we're within 3 standard errors, reason for 3 being that there is a discretisation error introduced
        /// by the time scheme approximation as well as sample error introduced by the simulation sample mean.
        /// </summary>
        /// <param name="kappa"></param>
        /// <param name="vol"></param>
        /// <param name="theta"></param>
        /// <param name="simuls"></param>
        public void TestDistroConvergence(double kappa, double vol, double theta, int simuls)
        {
            DateTime today      = new DateTime(2010, 10, 22);
            DateTime expiry     = new DateTime(2011, 10, 22);
            double   maturity   = Convert.ToDouble(expiry.Subtract(today).Days) / 365.0;
            double   spot       = 4200.00;
            double   callstrike = 1.3 * spot;
            double   putstrike  = 1.0 * spot;
            double   confidence = 0.95;

            int[]    zerodays  = { 0, 365 };
            double[] zerorates = { 0.065, 0.065 };
            int[]    divdays   = { 1, 51, 247 };
            double[] divamts   = { 22.5, 50, 50 };
            double   fwd       = EquityAnalytics.GetForwardCCLin365(spot, maturity, divdays, divamts, zerodays, zerorates);
            double   histvol   = vol;

            double[]          times = { 128.0 / 365.0, 250.0 / 365.0, 365.0 / 365.0 };
            OrcWingParameters owp   = new OrcWingParameters()
            {
                AtmForward = fwd, CallCurve = 0.1250, CurrentVol = 0.26, DnCutoff = -0.25, Dsr = 0.9, PutCurve = 0.10, RefFwd = fwd, RefVol = 0.26, Scr = 0.0, SlopeRef = -0.1750, Ssr = 100, TimeToMaturity = maturity, UpCutoff = 0.20, Usr = 0.50, Vcr = 0.0
            };
            List <OrcWingParameters> owpList = new List <OrcWingParameters> {
                owp
            };

            double[,] results = EquityPCEAnalytics.GetCollarPCE("Asset",
                                                                zerodays,
                                                                zerorates,
                                                                divdays,
                                                                divamts,
                                                                owpList,
                                                                spot,
                                                                callstrike,
                                                                putstrike,
                                                                maturity,
                                                                kappa,
                                                                theta,
                                                                histvol,
                                                                times, confidence, 1.0 / 365.0, simuls, 3151);
            // Check convergence to mean ln(S_t) ~ N(  theta + exp(-kappa*t)*( ln(S_0) - theta , sigma^2/(2*kappa)*(1-exp(-2*kappa*t) )
            // => E(S_t) = exp(theta + 0.5*sigma^2)
            //
            double LNmean1 = EquityPCEAnalytics.OUMean(kappa, theta, spot, times[0]);
            double LNmean2 = EquityPCEAnalytics.OUMean(kappa, theta, spot, times[1]);
            double LNmean3 = EquityPCEAnalytics.OUMean(kappa, theta, spot, times[2]);
            double Var_1   = EquityPCEAnalytics.OUVar(histvol, kappa, times[0]);
            double Var_2   = EquityPCEAnalytics.OUVar(histvol, kappa, times[1]);
            double Var_3   = EquityPCEAnalytics.OUVar(histvol, kappa, times[2]);
            //lognormal moments
            double lhs1 = Math.Exp(LNmean1 + Var_1 / 2.0);
            double lhs2 = Math.Exp(LNmean2 + Var_2 / 2.0);
            double lhs3 = Math.Exp(LNmean3 + Var_3 / 2.0);
            //double deltat = 1.0/365.0;
            double logvar1 = EquityPCEAnalytics.LNOUVar(spot, histvol, kappa, theta, times[0]);
            double logvar2 = EquityPCEAnalytics.LNOUVar(spot, histvol, kappa, theta, times[1]);
            double logvar3 = EquityPCEAnalytics.LNOUVar(spot, histvol, kappa, theta, times[2]);
            double stderr1 = Math.Sqrt(logvar1 / simuls);
            double stderr2 = Math.Sqrt(logvar2 / simuls);
            double stderr3 = Math.Sqrt(logvar3 / simuls);

            //double accuracy = histvol*histvol*(1/(2*kappa) - deltat /(1-Math.Exp(-2*kappa*deltat)))*(1-Math.Exp(-2*kappa*times[0]));
            Assert.AreEqual(lhs1, results[0, 0], 3.0 * stderr1);
            Assert.AreEqual(lhs2, results[1, 0], 3.0 * stderr2);
            Assert.AreEqual(lhs3, results[2, 0], 3.0 * stderr3);
        }
Exemplo n.º 9
0
        /// <summary>
        /// </summary>
        /// <param name="vols"></param>
        /// <param name="strikes"></param>
        /// <param name="forward"></param>
        /// <param name="spot"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static OrcWingParameters FitWing(double[] strikes,
                                                double[] vols,
                                                double forward,
                                                double spot)
        {
            int n = strikes.Length;

            if (n != vols.Length)
            {
                throw new Exception("Unequal length vectors");
            }
            int n1 = 0;

            for (int idx = 0; idx < n & n1 == 0; idx++)
            {
                if (strikes[idx] < strikes[(idx == 0) ? 0 : idx - 1])
                {
                    throw new Exception("Strikes not ordered");
                }
                if (n1 == 0 & strikes[idx] > forward)
                {
                    n1 = idx;
                }
            }
            int n2        = n - n1;
            var lnStrike1 = new double[n1];
            var lnStrike2 = new double[n2];

            for (int idx = 0; idx < n1; idx++)
            {
                lnStrike1[idx] = Math.Log(strikes[idx] / forward);
            }
            for (int idx = 0; idx < n2; idx++)
            {
                lnStrike2[idx] = Math.Log(strikes[n1 + idx] / forward);
            }
            Matrix xz   = CreateXz(lnStrike1, lnStrike2);
            Matrix xzTr = CreateXzdash(lnStrike1, lnStrike2);
            Matrix a    = xzTr * xz;
            //int aCols = a.ColumnCount;
            //int aRows = a.RowCount;
            var y = new Matrix(n1 + n2, 1);

            for (int idx = 0; idx < n1 + n2; idx++)
            {
                y[idx, 0] = vols[idx];
            }
            Matrix b      = xzTr * y;
            Matrix c      = a.Solve(b);
            var    result = new OrcWingParameters
            {
                Vcr        = 0,
                Scr        = 0,
                AtmForward = forward,
                PutCurve   = c[2, 0],
                CallCurve  = c[3, 0],
                CurrentVol = c[0, 0],
                DnCutoff   = -0.50 - Math.Log(forward / spot),
                UpCutoff   = 0.50 - Math.Log(forward / spot),
                RefFwd     = forward,
                RefVol     = c[0, 0],
                Dsr        = 0.20,
                Usr        = 0.20,
                Ssr        = 100.0,
                SlopeRef   = c[1, 0]
            };

            return(result);
        }
Exemplo n.º 10
0
        public void CanGetVolatilityFromWingParameterSurface()
        {
            RateCurve       rateCurve = CreateRateCurve();
            List <Dividend> divCurve  = CreateDividends();
            Stock           stock     = new Stock(new DateTime(2009, 9, 9), 4665, "CBA", "CBA", rateCurve, divCurve);

            //create SD grid vols
            stock.VolatilitySurface = CreateSurface(stock);
            if (stock.VolatilitySurface.Expiries[0].Strikes[0].InterpModel.GetType() == typeof(WingInterp))
            {
                //FO Wing parameters
                var expiryDate1 = new DateTime(2009, 10, 05);
                var atmForward1 = stock.GetForward(new DateTime(2009, 9, 9), expiryDate1);
                var wingParams1 = new OrcWingParameters
                {
                    CurrentVol = 0.25,
                    RefVol     = 0.25,
                    SlopeRef   = -0.375,
                    PutCurve   = 0.6,
                    CallCurve  = 1.125,
                    DnCutoff   = -0.4,
                    UpCutoff   = 0.225,
                    RefFwd     = atmForward1,
                    AtmForward = atmForward1,
                    Vcr        = 0,
                    Scr        = 0,
                    Ssr        = 100,
                    Dsr        = 0.5,
                    Usr        = 0.5,
                };
                var expiryDate2 = new DateTime(2009, 11, 26);
                var atmForward2 = stock.GetForward(new DateTime(2009, 9, 9), expiryDate2);
                var wingParams2 = new OrcWingParameters
                {
                    CurrentVol = 0.275,
                    RefVol     = 0.275,
                    SlopeRef   = -0.275,
                    PutCurve   = 0.325,
                    CallCurve  = 0.9,
                    DnCutoff   = -0.4,
                    UpCutoff   = 0.225,
                    RefFwd     = atmForward2,
                    AtmForward = atmForward2,
                    Vcr        = 0,
                    Scr        = 0,
                    Ssr        = 100,
                    Dsr        = 0.5,
                    Usr        = 0.5,
                };
                List <double> strikes1 = new List <double> {
                    Math.Round(atmForward1 * 0.5, 2), Math.Round(atmForward1 * 0.9, 2), Math.Round(atmForward1, 2), Math.Round(atmForward1 * 1.1, 2), Math.Round(atmForward1 * 1.5, 2)
                };
                var           expiryFo1 = stock.VolatilitySurface.ValueAt(stock, expiryDate1, strikes1, wingParams1, true, true);
                List <double> strikes2  = new List <double> {
                    Math.Round(atmForward2 * 0.5, 2), Math.Round(atmForward2 * 0.9, 2), Math.Round(atmForward2, 2), Math.Round(atmForward2 * 1.1, 2), Math.Round(atmForward2 * 1.5, 2)
                };
                var expiryFo2 = stock.VolatilitySurface.ValueAt(stock, expiryDate2, strikes2, wingParams2, true, true);
                //  stock.VolatilitySurface.AddExpiry(expiryFo1);
                //  stock.VolatilitySurface.AddExpiry(expiryFo2);
                stock.VolatilitySurface.Calibrate();
                List <double> strikes = new List <double> {
                    (double)stock.VolatilitySurface.Expiries[0].FwdPrice
                };
                List <DateTime> dates = new List <DateTime> {
                    new DateTime(2013, 10, 7)
                };
                var     result     = stock.VolatilitySurface.ValueAt(stock, dates, strikes, false);
                decimal volatility = result[0].Strikes[0].Volatility.Value;
                Assert.AreNotEqual(volatility, 0);
            }
        }
Exemplo n.º 11
0
        public void TestPricevsORCExample()
        {
            DateTime[] rtDates = { DateTime.Parse("17-Aug-2010"),
                                   DateTime.Parse("17-Sep-2010"),
                                   DateTime.Parse("18-Oct-2010"),
                                   DateTime.Parse("17-Nov-2010"),
                                   DateTime.Parse("10-Dec-2010") };

            double[]  rates = { 0.045507232,
                                0.046609656,
                                0.047336042,
                                0.047655159,
                                0.047737236 };
            RateCurve rc = new RateCurve("AUD", "Semi-Annual", DateTime.Parse("16-Aug-2010"), rtDates, rates);
            //Dividend d1 = new Dividend(DateTime.Parse("16-8-2010"),  11.745786M);
            Dividend        d2       = new Dividend(DateTime.Parse("17-8-2010"), 0.893295M);
            Dividend        d3       = new Dividend(DateTime.Parse("23-8-2010"), 7.856689M);
            Dividend        d4       = new Dividend(DateTime.Parse("24-8-2010"), 2.898251M);
            Dividend        d5       = new Dividend(DateTime.Parse("25-8-2010"), 3.344721M);
            Dividend        d6       = new Dividend(DateTime.Parse("26-8-2010"), 0.485070M);
            Dividend        d7       = new Dividend(DateTime.Parse("27-8-2010"), 0.835305M);
            Dividend        d8       = new Dividend(DateTime.Parse("30-8-2010"), 3.952976M);
            Dividend        d9       = new Dividend(DateTime.Parse("31-8-2010"), 0.884255M);
            Dividend        d10      = new Dividend(DateTime.Parse("1-9-2010"), 2.013798M);
            Dividend        d11      = new Dividend(DateTime.Parse("2-9-2010"), 1.241407M);
            Dividend        d12      = new Dividend(DateTime.Parse("3-9-2010"), 0.613699M);
            Dividend        d13      = new Dividend(DateTime.Parse("6-9-2010"), 11.712946M);
            Dividend        d14      = new Dividend(DateTime.Parse("7-9-2010"), 3.775104M);
            Dividend        d15      = new Dividend(DateTime.Parse("8-9-2010"), 0.606597M);
            Dividend        d16      = new Dividend(DateTime.Parse("9-9-2010"), 0.268093M);
            Dividend        d17      = new Dividend(DateTime.Parse("10-9-2010"), 0.144851M);
            Dividend        d18      = new Dividend(DateTime.Parse("13-9-2010"), 1.600975M);
            Dividend        d19      = new Dividend(DateTime.Parse("14-9-2010"), 1.499946M);
            Dividend        d20      = new Dividend(DateTime.Parse("15-9-2010"), 0.238824M);
            Dividend        d21      = new Dividend(DateTime.Parse("16-9-2010"), 0.117931M);
            List <Dividend> divCurve = new List <Dividend>()
            {
                d2, d3, d4, d5, d6, d7, d8, d9, d10,
                d11, d12, d13, d14, d15, d16, d17, d18, d19, d20, d21
            };
            DateTime date0 = new DateTime(2010, 08, 16);
            DateTime exp   = new DateTime(2010, 9, 16);
            double   spot  = 4447.62;
            //double future = 4420;
            double strike      = 4200;
            string stockId     = "XJO_Spot";
            Stock  stock       = new Stock(date0, Convert.ToDecimal(spot), stockId, "XJO", rc, divCurve);
            double fwd         = stock.GetForward(date0, exp);
            var    wingParams1 = new OrcWingParameters
            {
                CurrentVol = 0.234828,
                RefVol     = 0.234828,
                SlopeRef   = -0.109109,
                PutCurve   = 1.235556,
                CallCurve  = 0.60895,
                DnCutoff   = -0.493791,
                UpCutoff   = 0.506209,
                RefFwd     = 4420.092383,
                AtmForward = 4420.092383,
                Vcr        = 0,
                Scr        = 0,
                Ssr        = 100,
                Dsr        = 0.2,
                Usr        = 0.2,
            };
            VolatilitySurface vs      = new VolatilitySurface(stockId, Convert.ToDecimal(spot), date0);
            ForwardExpiry     expiry  = new ForwardExpiry(exp, Convert.ToDecimal(fwd));
            OptionPosition    op      = new OptionPosition("XJO_Vanilla_ETO_Sep10_4200.000_Put", 30.237108, PositionType.Put);
            Strike            strike0 = new Strike(strike, null, op);

            expiry.AddStrike(strike0, true);
            List <double> strikes1 = new List <double> {
                4200
            };
            ForwardExpiry forwardexpiry = vs.ValueAt(stock, exp, strikes1, wingParams1, true, false);
            double        vol           = Convert.ToDouble(forwardexpiry.Strikes[0].Volatility.Value);
            var           utils         = new AmOptionAnalytics(date0, exp, spot, strike, vol, "European", "Put", rc, divCurve, 120);
            double        pr            = Math.Round(utils.Price(), 7);
        }