Пример #1
0
        /// <summary>
        /// Use Direct SQL commands feature implementation based on EntityFramework Core
        /// </summary>
        /// <param name="conf">Channel configuration</param>
        /// <param name="context">Lazy disposable wrapper around DbContext</param>
        public static void UseEfCoreDirectSqlCommand(this ChannelConfiguration <CommandChannel <Tecture.Features.SqlStroke.Command> > conf, ILazyDisposable <DbContext> context, InterpolatorFactory fac = null)
        {
            if (fac == null)
            {
                fac = new InterpolatorFactory();
            }
            var fe = new EFCore_DirectSql_CommandFeature(context, conf.Channel, fac);

            conf.ForCommand(fe, new EFCore_DirectSql_Saver(fe));
        }
Пример #2
0
 /// <summary>
 /// Use Direct SQL aspect implementation based on EntityFramework Core
 /// </summary>
 /// <param name="conf">Channel configuration</param>
 /// <param name="context">Lazy disposable wrapper around DbContext</param>
 public static void UseEfCoreDirectSql(this ChannelBinding <CommandQueryChannel <Tecture.Aspects.DirectSql.DirectSql.Command, Tecture.Aspects.DirectSql.DirectSql.Query> > conf,
                                       ILazyDisposable <DbContext> context, InterpolatorFactory fac = null)
 {
     if (fac == null)
     {
         fac = new InterpolatorFactory();
     }
     conf.UseEfCoreDirectSqlCommand(context, fac);
     conf.UseEfCoreDirectSqlQuery(context, fac);
 }
Пример #3
0
        /// <summary>
        /// Use Direct SQL commands aspect implementation based on EntityFramework Core
        /// </summary>
        /// <param name="conf">Channel configuration</param>
        /// <param name="context">Lazy disposable wrapper around DbContext</param>
        public static void UseEfCoreDirectSqlCommand(this ChannelBinding <CommandChannel <Tecture.Aspects.DirectSql.DirectSql.Command> > conf, ILazyDisposable <DbContext> context, InterpolatorFactory fac = null)
        {
            if (fac == null)
            {
                fac = new InterpolatorFactory();
            }
            var fe = new EFCore_DirectSql_CommandAspect(context, conf.Channel, fac);

            conf.ForCommand(fe);
        }
Пример #4
0
 public void Build(DateTime originDate, double[] strikes, DateTime[] expiries, double[][] vols)
 {
     OriginDate     = originDate;
     Strikes        = strikes;
     Expiries       = expiries;
     Volatilities   = vols;
     ExpiriesDouble = Expiries.Select(t => TimeBasis.CalculateYearFraction(originDate, t)).ToArray();
     _interpolators = vols.Select((v, ix) =>
                                  InterpolatorFactory.GetInterpolator(Strikes, v, StrikeInterpolatorType)).ToArray();
 }
Пример #5
0
 public CorrelationTimeVector(string labelX, string[] labelsY, double[][] correlations, double[] times, Interpolator1DType interpKind = Interpolator1DType.LinearFlatExtrap)
     : this()
 {
     LabelsX      = new[] { labelX };
     LabelsY      = labelsY;
     Correlations = correlations;
     _times       = times;
     _interpType  = interpKind;
     _interps     = correlations.Select(c => InterpolatorFactory.GetInterpolator(times, c, interpKind)).ToArray();
 }
Пример #6
0
        public void Build(DateTime originDate, double[][] strikes, DateTime[] expiries, double[][] vols, Func <double, double> forwardCurve)
        {
            OriginDate     = originDate;
            Expiries       = expiries;
            ExpiriesDouble = Expiries.Select(t => TimeBasis.CalculateYearFraction(originDate, t)).ToArray();

            if (Expiries.Length != strikes.Length)
            {
                throw new InvalidOperationException("Expiries and first dimension of Strikes must of same length");
            }
            if (Expiries.Length != vols.Length)
            {
                throw new InvalidOperationException("Expiries and first dimension of Vols must of same length");
            }

            Alphas = new double[Expiries.Length];
            Betas  = new double[Expiries.Length];
            Nus    = new double[Expiries.Length];
            Rhos   = new double[Expiries.Length];


            for (var i = 0; i < expiries.Length; i++)
            {
                var vs  = vols[i];
                var ks  = strikes[i];
                var t   = ExpiriesDouble[i];
                var fwd = forwardCurve(t);
                Betas[i] = 1.0;
                Func <double[], double[]> errorFunc = (x =>
                {
                    var err = ks.Select((k, ix) => vs[ix] - SABR.CalcImpVol_Beta1(fwd, k, t, x[0], x[1], x[2]));
                    return(err.ToArray());
                });

                var n2Sol = new Math.Solvers.GaussNewton
                {
                    ObjectiveFunction = errorFunc,
                    InitialGuess      = new double[] { vs.Average(), 0.1, 0.1 },
                    Tollerance        = 1e-8,
                    JacobianBump      = 0.0000001
                };

                var paramArr = n2Sol.Solve();

                Alphas[i] = paramArr[0];
                Rhos[i]   = paramArr[1];
                Nus[i]    = paramArr[2];
            }

            _alphaInterp = InterpolatorFactory.GetInterpolator(ExpiriesDouble, Alphas, TimeInterpolatorType);
            _betaInterp  = InterpolatorFactory.GetInterpolator(ExpiriesDouble, Betas, TimeInterpolatorType);
            _rhoInterp   = InterpolatorFactory.GetInterpolator(ExpiriesDouble, Rhos, TimeInterpolatorType);
            _nuInterp    = InterpolatorFactory.GetInterpolator(ExpiriesDouble, Nus, TimeInterpolatorType);
        }
Пример #7
0
        public void CanInterpolateFact()
        {
            var xs     = new double[] { 0.1, 0.25, 0.5, 0.75, 0.9 };
            var ys     = new double[] { 0.32, 0.32, 0.34, 0.36, 0.38 };
            var interp = InterpolatorFactory.GetInterpolator(xs, ys, Interpolator1DType.GaussianKernel);

            //test pillar values are returned
            for (var i = 0; i < xs.Length; i++)
            {
                Assert.Equal(ys[i], interp.Interpolate(xs[i]), 10);
            }
        }
Пример #8
0
        public static IInterpolator1D GenerateCDF(this IVolSurface surface, int numSamples, DateTime expiry, double fwd, bool returnInverse = false)
        {
            var deltaKLow  = 0.0000001;
            var deltaKHi   = 0.9999999;
            var kStepD     = (deltaKHi - deltaKLow) / (numSamples + 3);
            var deltaKBump = deltaKLow / 10;

            var t = surface.OriginDate.CalculateYearFraction(expiry, DayCountBasis.Act365F);

            var x = new double[numSamples + 2];
            var y = new double[numSamples + 2];


            for (var i = 0; i < x.Length; i++)
            {
                var deltaKNew = deltaKLow + i * kStepD;
                var mStrike   = deltaKNew - deltaKBump / 2;
                var pStrike   = deltaKNew + deltaKBump / 2;

                var mStrikeVol = surface.GetVolForDeltaStrike(mStrike, t, fwd);
                var mk         = BlackFunctions.AbsoluteStrikefromDeltaKAnalytic(fwd, -mStrike, 0, t, mStrikeVol);
                var pStrikeVol = surface.GetVolForDeltaStrike(pStrike, t, fwd);
                var pk         = BlackFunctions.AbsoluteStrikefromDeltaKAnalytic(fwd, -pStrike, 0, t, pStrikeVol);

                if (i == 0)
                {
                    x[0] = mk / 2.0;
                    y[0] = 0;
                    continue;
                }
                if (i == x.Length - 1)
                {
                    x[i] = pk * 2;
                    y[i] = 1;
                    continue;
                }

                var dkAbs = (pk - mk);

                var pPut = BlackFunctions.BlackPV(fwd, pk, 0, t, pStrikeVol, OptionType.P);
                var mPut = BlackFunctions.BlackPV(fwd, mk, 0, t, mStrikeVol, OptionType.P);


                var digital = (pPut - mPut) / dkAbs;
                y[i] = digital;
                x[i] = (mk + pk) / 2.0;
            }

            return(returnInverse ?
                   InterpolatorFactory.GetInterpolator(y, x, Interpolator1DType.LinearFlatExtrap) :
                   InterpolatorFactory.GetInterpolator(x, y, Interpolator1DType.LinearFlatExtrap));
        }
Пример #9
0
        public static IInterpolator1D GeneratePDF(this IVolSurface surface, int numSamples, DateTime expiry, double fwd)
        {
            var deltaK = fwd * 0.0001;

            var t            = surface.OriginDate.CalculateYearFraction(expiry, DayCountBasis.Act365F);
            var lowStrikeVol = surface.GetVolForDeltaStrike(0.0001, t, fwd);
            var lowStrike    = BlackFunctions.AbsoluteStrikefromDeltaKAnalytic(fwd, -0.0001, 0, t, lowStrikeVol);
            var hiStrikeVol  = surface.GetVolForDeltaStrike(0.9999, t, fwd);
            var hiStrike     = BlackFunctions.AbsoluteStrikefromDeltaKAnalytic(fwd, -0.9999, 0, t, hiStrikeVol);

            var x = new double[numSamples + 2];
            var y = new double[numSamples + 2];

            var k = lowStrike;

            var kStep = (hiStrike - lowStrike) / numSamples;

            for (var i = 0; i < x.Length; i++)
            {
                if (i == 0)
                {
                    x[0] = lowStrike / 2.0;
                    y[0] = 0;
                    continue;
                }
                if (i == x.Length - 1)
                {
                    x[i] = k * 2;
                    y[i] = 0;
                    continue;
                }

                var volLow    = surface.GetVolForAbsoluteStrike(k - deltaK, t, fwd);
                var callLow   = BlackFunctions.BlackPV(fwd, k - deltaK, 0, t, volLow, OptionType.C);
                var volMid    = surface.GetVolForAbsoluteStrike(k, t, fwd);
                var callMid   = BlackFunctions.BlackPV(fwd, k, 0, t, volMid, OptionType.C);
                var volHi     = surface.GetVolForAbsoluteStrike(k + deltaK, t, fwd);
                var callHi    = BlackFunctions.BlackPV(fwd, k + deltaK, 0, t, volHi, OptionType.C);
                var digitalLo = (callLow - callMid) / deltaK;
                var digitalHi = (callMid - callHi) / deltaK;
                y[i] = (digitalLo - digitalHi) / deltaK;
                x[i] = k;
                k   += kStep;
            }

            var firstPass = InterpolatorFactory.GetInterpolator(x, y, Interpolator1DType.LinearFlatExtrap);
            var totalY    = ((IIntegrableInterpolator)firstPass).DefiniteIntegral(x.First(), x.Last());

            y = y.Select(v => v / totalY).ToArray();
            return(InterpolatorFactory.GetInterpolator(x, y, Interpolator1DType.LinearFlatExtrap));
        }
Пример #10
0
        private double GetAbsStrikeForDelta(double fwd, double deltaStrike, double maturity)
        {
            var cp = deltaStrike < 0 ? OptionType.Put : OptionType.Call;
            Func <double, double> testFunc = (absK =>
            {
                var interpForStrike = InterpolatorFactory.GetInterpolator(ExpiriesDouble, ExpiriesDouble.Select(e => GetVolForAbsoluteStrike(absK, e, fwd)).ToArray(), TimeInterpolatorType);
                var vol2 = interpForStrike.Interpolate(maturity);
                var deltaK = BlackFunctions.BlackDelta(fwd, absK, 0, maturity, vol2, cp);
                return(deltaK - deltaStrike);
            });

            var solvedStrike = Math.Solvers.Brent.BrentsMethodSolve(testFunc, 0.000000001, 50 * fwd, 1e-8);

            return(solvedStrike);
        }
Пример #11
0
        public double GetVolForDeltaStrike(double deltaStrike, double maturity, double forward)
        {
            if (deltaStrike > 1.0 || deltaStrike < -1.0)
            {
                throw new ArgumentOutOfRangeException($"Delta strike must be in range -1.0 < x < 1.0 - value was {deltaStrike}");
            }

            var key = $"{deltaStrike:f6}~{maturity:f3}~{forward:f6}";

            if (_allowCaching && _deltaVolCache.TryGetValue(key, out var vol))
            {
                return(vol);
            }

            if (StrikeType == StrikeType.ForwardDelta)
            {
                var interpForStrike = InterpolatorFactory.GetInterpolator(ExpiriesDouble,
                                                                          _interpolators.Select(x => x.Interpolate(deltaStrike)).ToArray(),
                                                                          TimeInterpolatorType);
                vol = interpForStrike.Interpolate(maturity);
            }
            else
            {
                var fwd = forward;
                var cp  = deltaStrike < 0 ? OptionType.Put : OptionType.Call;
                Func <double, double> testFunc = (absK =>
                {
                    var interpForStrike = InterpolatorFactory.GetInterpolator(ExpiriesDouble,
                                                                              _interpolators.Select(x => x.Interpolate(absK)).ToArray(),
                                                                              TimeInterpolatorType);
                    var vol2 = interpForStrike.Interpolate(maturity);
                    var deltaK = BlackFunctions.BlackDelta(fwd, absK, 0, maturity, vol2, cp);
                    return(deltaK - Abs(deltaStrike));
                });

                var solvedStrike          = Math.Solvers.Brent.BrentsMethodSolve(testFunc, 0.000000001, 10 * fwd, 1e-8);
                var interpForSolvedStrike = InterpolatorFactory.GetInterpolator(ExpiriesDouble,
                                                                                _interpolators.Select(x => x.Interpolate(solvedStrike)).ToArray(),
                                                                                TimeInterpolatorType);
                vol = interpForSolvedStrike.Interpolate(maturity);
            }

            if (_allowCaching)
            {
                _deltaVolCache[key] = vol;
            }
            return(vol);
        }
Пример #12
0
        private void Initialize()
        {
            var pillarsAsDoubles = _pillarDates.Select(x => x.ToOADate()).ToArray();

            switch (_curveType)
            {
            case SparsePriceCurveType.Coal:
                _interpA = InterpolatorFactory.GetInterpolator(pillarsAsDoubles, _prices, Interpolator1DType.LinearFlatExtrap);
                var allDates       = _pillarDates.First().CalendarDaysInPeriod(_pillarDates.Last());
                var monthlyDates   = allDates.Select(x => x.NthLastSpecificWeekDay(DayOfWeek.Friday, 1)).Distinct();
                var monthlyPillars = monthlyDates.Select(x => x.ToOADate()).ToArray();
                var monthlyPrices  = _interpA.Many(monthlyPillars).ToArray();
                _interpB = InterpolatorFactory.GetInterpolator(monthlyPillars, monthlyPrices, Interpolator1DType.NextValue);
                break;
            }
        }
Пример #13
0
        public void CanInterpolateFact()
        {
            var xs     = new double[] { 0.1, 0.25, 0.5, 0.75, 0.9 };
            var ys     = new double[] { 0.32, 0.32, 0.34, 0.36, 0.38 };
            var interp = InterpolatorFactory.GetInterpolator(xs, ys, Interpolator1DType.GaussianKernel);

            //test pillar values are returned
            for (var i = 0; i < xs.Length; i++)
            {
                Assert.Equal(ys[i], interp.Interpolate(xs[i]), 10);
            }

            var gk = new GaussianKernelInterpolator();

            Assert.Throws <NotImplementedException>(() => interp.Bump(0, 0));
            Assert.Throws <NotImplementedException>(() => interp.UpdateY(0, 0));
            Assert.Throws <NotImplementedException>(() => interp.Sensitivity(0));
        }
Пример #14
0
        public void Finish(FeatureCollection collection)
        {
            if (!_timesteps.IsComplete)
            {
                return;
            }

            //drifts and vols...
            _drifts    = new double[_timesteps.TimeStepCount];
            _lvInterps = new IInterpolator1D[_timesteps.TimeStepCount - 1];

            var strikes = new double[_timesteps.TimeStepCount][];

            for (var t = 0; t < strikes.Length; t++)
            {
                strikes[t] = new double[98];
                var fwd    = _forwardCurve(_timesteps.Times[t]);
                var atmVol = _surface.GetVolForDeltaStrike(fwd, _timesteps.Times[t], fwd);
                for (var k = 0; k < strikes[t].Length; k++)
                {
                    var deltaK = -(0.01 + 0.01 * k);
                    strikes[t][k] = Options.BlackFunctions.AbsoluteStrikefromDeltaKAnalytic(fwd, deltaK, 0, _timesteps.Times[t], atmVol);
                }
            }

            var lvSurface = Options.LocalVol.ComputeLocalVarianceOnGrid(_surface, strikes, _timesteps.Times, _forwardCurve);

            for (var t = 0; t < _lvInterps.Length; t++)
            {
                _lvInterps[t] = InterpolatorFactory.GetInterpolator(strikes[t], lvSurface[t], t == 0 ? Interpolator1DType.DummyPoint : Interpolator1DType.LinearFlatExtrap);
            }

            var prevSpot = _forwardCurve(0);

            for (var t = 1; t < _drifts.Length; t++)
            {
                var spot = _forwardCurve(_timesteps.Times[t]);
                _drifts[t] = System.Math.Log(spot / prevSpot) / _timesteps.TimeSteps[t];

                prevSpot = spot;
            }
            _isComplete = true;
        }
Пример #15
0
        public IrCurve(DateTime[] pillars, double[] rates, DateTime buildDate, string name, Interpolator1DType interpKind)
        {
            _interpKind = interpKind;
            _pillars    = new DateTime[pillars.Length];
            pillars.CopyTo(_pillars, 0);
            _rates = new double[_pillars.Length];

            var pillarsD = new double[_pillars.Length];

            _buildDate = buildDate;

            for (var i = 0; i < pillars.Length; i++)
            {
                pillarsD[i] = buildDate.CalculateYearFraction(pillars[i], _basis);
                _rates[i]   = rates[i];
            }

            _interpolator = InterpolatorFactory.GetInterpolator(pillarsD.ToArray(), _rates.ToArray(), interpKind, isSorted: true, noCopy: true);
            _name         = name;
        }
Пример #16
0
        public static IInterpolator1D GenerateCDF(this IInterpolator1D smile, int numSamples, double t, double fwd)
        {
            var deltaK = fwd * 0.0001;

            var atmVol    = smile.Interpolate(fwd);
            var lowStrike = BlackFunctions.AbsoluteStrikefromDeltaKAnalytic(fwd, -0.0001, 0, t, atmVol);
            var hiStrike  = BlackFunctions.AbsoluteStrikefromDeltaKAnalytic(fwd, -0.9999, 0, t, atmVol);

            var x = new double[numSamples + 2];
            var y = new double[numSamples + 2];

            var k = lowStrike;

            var kStep = (hiStrike - lowStrike) / numSamples;

            for (var i = 0; i < x.Length; i++)
            {
                if (i == 0)
                {
                    x[0] = k / 2.0;
                    y[0] = 0;
                    continue;
                }
                if (i == x.Length - 1)
                {
                    x[i] = k * 2;
                    y[i] = 1;
                    continue;
                }
                var volLow  = smile.Interpolate(k - deltaK / 2.0);
                var putLow  = BlackFunctions.BlackPV(fwd, k - deltaK / 2.0, 0, t, volLow, OptionType.P);
                var volHi   = smile.Interpolate(k + deltaK / 2.0);
                var putHi   = BlackFunctions.BlackPV(fwd, k + deltaK / 2.0, 0, t, volHi, OptionType.P);
                var digital = (putHi - putLow) / deltaK;
                y[i] = digital;
                x[i] = k;
                k   += kStep;
            }

            return(InterpolatorFactory.GetInterpolator(x, y, Interpolator1DType.Linear));
        }
Пример #17
0
        public static object Create1dInterpolatorSafe(
            [ExcelArgument(Description = "Object name")] string ObjectName,
            [ExcelArgument(Description = "Array of X values")] object[] X,
            [ExcelArgument(Description = "Array of Y values")] object[] Y,
            [ExcelArgument(Description = "Type of interpolator, e.g. Linear")] string InterpolatorType)
        {
            return(ExcelHelper.Execute(_logger, () =>
            {
                var interpType = InterpolatorType.OptionalExcel <string>("Linear");
                if (!Enum.TryParse(interpType, out Interpolator1DType iType))
                {
                    return $"Could not parse 1d interpolator type - {interpType}";
                }

                if (X.Length != Y.Length)
                {
                    throw new Exception("Input vectors must be same length");
                }

                var xList = new List <double>();
                var yList = new List <double>();

                for (var i = 0; i < X.Length; i++)
                {
                    if (X[i] is double && Y[i] is double)
                    {
                        xList.Add((double)X[i]);
                        yList.Add((double)Y[i]);
                    }
                }

                var iObj = InterpolatorFactory.GetInterpolator(xList.ToArray(), yList.ToArray(), iType);
                var cache = ContainerStores.GetObjectCache <IInterpolator1D>();
                cache.PutObject(ObjectName, new SessionItem <IInterpolator1D> {
                    Name = ObjectName, Value = iObj
                });
                return ObjectName + '¬' + cache.GetObject(ObjectName).Version;
            }));
        }
Пример #18
0
        public static object Create1dInterpolator(
            [ExcelArgument(Description = "Object name")] string ObjectName,
            [ExcelArgument(Description = "Array of X values")] double[] X,
            [ExcelArgument(Description = "Array of Y values")] double[] Y,
            [ExcelArgument(Description = "Type of interpolator, e.g. Linear")] string InterpolatorType)
        {
            return(ExcelHelper.Execute(_logger, () =>
            {
                var interpType = InterpolatorType.OptionalExcel <string>("Linear");
                if (!Enum.TryParse(interpType, out Interpolator1DType iType))
                {
                    return $"Could not parse 1d interpolator type - {interpType}";
                }

                var iObj = InterpolatorFactory.GetInterpolator(X, Y, iType);
                var cache = ContainerStores.GetObjectCache <IInterpolator1D>();
                cache.PutObject(ObjectName, new SessionItem <IInterpolator1D> {
                    Name = ObjectName, Value = iObj
                });
                return ObjectName + '¬' + cache.GetObject(ObjectName).Version;
            }));
        }
Пример #19
0
        public double Dvdk(double strike, DateTime expiry, double fwd)
        {
            if (StrikeType == StrikeType.ForwardDelta)
            {
                var t = TimeBasis.CalculateYearFraction(OriginDate, expiry);

                var pillarIx          = Array.BinarySearch(Expiries, expiry);
                var interpForMaturity = pillarIx > 0 ?
                                        _interpolators[pillarIx] :
                                        InterpolatorFactory.GetInterpolator(Strikes, Strikes.Select(k => GetVolForDeltaStrike(k, expiry, fwd)).ToArray(), StrikeInterpolatorType);

                var deltaK = GetDeltaStrikeForAbs(fwd, strike, t);
                var vol    = GetVolForAbsoluteStrike(strike, expiry, fwd);
                var gamma  = BlackFunctions.BlackGamma(fwd, strike, 0.0, t, vol);
                return(interpForMaturity.FirstDerivative(deltaK) * gamma);
            }
            else
            {
                var interpForMaturity = InterpolatorFactory.GetInterpolator(Strikes,
                                                                            Strikes.Select(k => GetVolForAbsoluteStrike(k, expiry, fwd)).ToArray(),
                                                                            StrikeInterpolatorType);
                return(interpForMaturity.FirstDerivative(strike));
            }
        }
Пример #20
0
        public static IInterpolator1D GeneratePremiumInterpolator(this IVolSurface surface, int numSamples, double t, double fwd, OptionType cp)
        {
            var lowStrikeVol = surface.GetVolForDeltaStrike(0.001, t, fwd);
            var lowStrike    = BlackFunctions.AbsoluteStrikefromDeltaKAnalytic(fwd, -0.001, 0, t, lowStrikeVol);
            var hiStrikeVol  = surface.GetVolForDeltaStrike(0.999, t, fwd);
            var hiStrike     = BlackFunctions.AbsoluteStrikefromDeltaKAnalytic(fwd, -0.999, 0, t, hiStrikeVol);

            var x = new double[numSamples + 2];
            var y = new double[numSamples + 2];

            var k = lowStrike;

            var kStep = (hiStrike - lowStrike) / (numSamples + 1.0);

            var vol  = surface.GetVolForAbsoluteStrike(k / 10, t, fwd);
            var call = BlackFunctions.BlackPV(fwd, k / 10, 0, t, vol, cp);

            y[0] = call;
            x[0] = k / 10;

            for (var i = 0; i < x.Length - 1; i++)
            {
                vol      = surface.GetVolForAbsoluteStrike(k, t, fwd);
                call     = BlackFunctions.BlackPV(fwd, k, 0, t, vol, cp);
                y[i + 1] = call;
                x[i + 1] = k;
                k       += kStep;
            }

            vol             = surface.GetVolForAbsoluteStrike(k * 10, t, fwd);
            call            = BlackFunctions.BlackPV(fwd, k * 10, 0, t, vol, cp);
            y[x.Length - 1] = call;
            x[x.Length - 1] = k * 10;

            return(InterpolatorFactory.GetInterpolator(x, y, Interpolator1DType.MonotoneCubicSpline));
        }
Пример #21
0
        public IrCurve(DateTime[] pillars, double[] rates, DateTime buildDate, string name, Interpolator1DType interpKind, Currency ccy, string collateralSpec = null, RateType rateStorageType = RateType.Exponential)
        {
            _interpKind      = interpKind;
            _rateStorageType = rateStorageType;
            _pillars         = new DateTime[pillars.Length];
            pillars.CopyTo(_pillars, 0);
            _rates = new double[_pillars.Length];

            var pillarsD = new double[_pillars.Length];

            _buildDate = buildDate;

            for (var i = 0; i < pillars.Length; i++)
            {
                pillarsD[i] = buildDate.CalculateYearFraction(pillars[i], _basis);
                _rates[i]   = rates[i];
            }

            _interpolator  = InterpolatorFactory.GetInterpolator(pillarsD.ToArray(), _rates.ToArray(), interpKind, isSorted: true, noCopy: true);
            _name          = name;
            Currency       = ccy;
            CollateralSpec = collateralSpec ?? (string.IsNullOrWhiteSpace(_name) ? null :
                                                (_name.Contains("[")) ? _name.Split('[').Last().Trim("[]".ToCharArray()) : _name.Split('.').Last());
        }
Пример #22
0
        public static IInterpolator1D GenerateCompositeSmileB(this IVolSurface surface, IVolSurface fxSurface, int numSamples, DateTime expiry, double fwdAsset, double fwdFx, double correlation, bool strikesInDeltaSpace = false)
        {
            var t     = surface.OriginDate.CalculateYearFraction(expiry, DayCountBasis.Act365F);
            var fxInv = new InverseFxSurface("fxInv", fxSurface as IATMVolSurface, null);

            var atmFx = fxSurface.GetVolForDeltaStrike(0.5, t, fwdFx);
            var atmA  = surface.GetVolForDeltaStrike(0.5, t, fwdAsset);

            var compoFwd = fwdAsset * fwdFx;
            var atmCompo = Sqrt(atmFx * atmFx + atmA * atmA + 2.0 * correlation * atmA * atmFx);
            var lowK     = BlackFunctions.AbsoluteStrikefromDeltaKAnalytic(compoFwd, -0.01, 0, t, atmCompo);
            var hiK      = BlackFunctions.AbsoluteStrikefromDeltaKAnalytic(compoFwd, -0.99, 0, t, atmCompo);

            //var cdfInvFx = fxSurface.GenerateCDF2(numSamples * 10, expiry, fwdFx, true);
            //var cdfInvAsset = surface.GenerateCDF2(numSamples * 10, expiry, fwdAsset, true);
            //var yFx = new Func<double, double>(z => cdfInvFx.Interpolate(Statistics.NormSDist(z)));
            //var yAsset = new Func<double, double>(z => cdfInvAsset.Interpolate(Statistics.NormSDist(z)));

            var fxCDFCache    = new Dictionary <double, double>();
            var assetCDFCache = new Dictionary <double, double>();
            var yFx           = new Func <double, double>(z =>
            {
                if (fxCDFCache.TryGetValue(z, out var K))
                {
                    return(K);
                }
                K = fxInv.InverseCDF(expiry, 1.0 / fwdFx, Statistics.NormSDist(z));
                fxCDFCache.Add(z, K);
                return(K);
            });
            var yAsset = new Func <double, double>(z =>
            {
                if (assetCDFCache.TryGetValue(z, out var K))
                {
                    return(K);
                }
                K = surface.InverseCDF(expiry, fwdAsset, Statistics.NormSDist(z));
                assetCDFCache.Add(z, K);
                return(K);
            });

            //var fxCDFCache = new Dictionary<double, double>();
            //var assetCDFCache = new Dictionary<double, double>();
            //var putFx = fxInv.GeneratePremiumInterpolator(numSamples * 10, expiry, 1.0/fwdFx, OptionType.P);
            //var putAsset = surface.GeneratePremiumInterpolator(numSamples * 10, expiry, fwdAsset, OptionType.P);
            //var yFx = new Func<double, double>(z =>
            //{
            //    if (fxCDFCache.TryGetValue(z, out var K)) return K;
            //    K = InverseCDF(putFx, t, 1.0/fwdFx, Statistics.NormSDist(z));
            //    fxCDFCache.Add(z, K);
            //    return K;
            //});
            //var yAsset = new Func<double, double>(z =>
            //{
            //    if (assetCDFCache.TryGetValue(z, out var K)) return K;
            //    K = InverseCDF(putAsset, t, fwdAsset, Statistics.NormSDist(z));
            //    var kl = assetCDFCache.Keys.ToList();
            //    var closerIx = kl.BinarySearch(z);
            //    var keyIx = ~closerIx;
            //    if (closerIx < 0 && z < 0 && kl.Count > keyIx)
            //    {
            //        if (assetCDFCache[kl[keyIx]] < K)
            //            K = assetCDFCache[kl[keyIx]];
            //    }
            //    assetCDFCache.Add(z, K);
            //    return K;
            //});

            var payoff    = new Func <double, double, double, double>((z1, z2, kQ) => Max(kQ * yFx(z2) - yAsset(z1), 0));
            var integrand = new Func <double, double, double, double>((z1, z2, kQ) => payoff(z1, z2, kQ) * BivariateNormal.PDF(z1, z2, -correlation));

            var kStep    = (hiK - lowK) / numSamples;
            var ks       = Enumerable.Range(0, numSamples).Select(kk => lowK + kk * kStep).ToArray();
            var premiums = new double[ks.Length];
            var vols     = new double[ks.Length];

            for (var i = 0; i < ks.Length; i++)
            {
                var ik = new Func <double, double, double>((z1, z2) => integrand(z1, z2, ks[i]));
                var pk = Integration.TwoDimensionalGaussLegendre(ik, -5, 5, -5, 5, 16);
                //var pk = Integration.TwoDimensionalSimpsons(ik, -5, 5, -5, 5, 100);
                pk *= fwdFx;
                var volK = BlackFunctions.BlackImpliedVol(compoFwd, ks[i], 0.0, t, pk, OptionType.P);
                vols[i]     = volK;
                premiums[i] = pk;
            }


            if (strikesInDeltaSpace)
            {
                ks = ks.Select((ak, ix) => - BlackFunctions.BlackDelta(compoFwd, ak, 0.0, t, vols[ix], OptionType.P)).ToArray();
            }

            return(InterpolatorFactory.GetInterpolator(ks, vols, Interpolator1DType.CubicSpline));
        }
Пример #23
0
 private void UpdateInterpolator() => _interp = InterpolatorFactory.GetInterpolator(_strikes, _currentGuess, _interpType);
Пример #24
0
 /// <summary>
 /// Use Direct SQL query aspect implementation based on EntityFramework Core
 /// </summary>
 /// <param name="conf">Channel configuration</param>
 /// <param name="context">Lazy disposable wrapper around DbContext</param>
 public static void UseEfCoreDirectSqlQuery(this ChannelBinding <QueryChannel <Tecture.Aspects.DirectSql.DirectSql.Query> > conf, ILazyDisposable <DbContext> context, InterpolatorFactory fac = null)
 {
     if (fac == null)
     {
         fac = new InterpolatorFactory();
     }
     conf.ForQuery(new EFCore_DirectSql_QueryAspect(context, conf.Channel, fac));
 }
Пример #25
0
        public static Dictionary <DateTime, IInterpolator1D> ToDeltaSmiles(this List <ListedOptionSettlementRecord> optionSettlements, Dictionary <string, double> futuresPrices, SmileOrderOfPrecedence orderOfP = SmileOrderOfPrecedence.UseOTM)
        {
            var output = new Dictionary <DateTime, IInterpolator1D>();

            var byExpiry = optionSettlements.GroupBy(r => r.ExpiryDate).OrderBy(o => o.Key);

            foreach (var expGroup in byExpiry)
            {
                var expiry = expGroup.Key;
                if (expGroup.Select(x => x.UnderlyingFuturesCode).Distinct().Count() != 1)
                {
                    throw new Exception($"Inconsistent underlying contracts for expiry {expiry}");
                }

                if (expGroup.Select(x => x.ValDate).Distinct().Count() != 1)
                {
                    throw new Exception($"Inconsistent value dates for expiry {expiry}");
                }

                var t = expGroup.First().ValDate.CalculateYearFraction(expiry, DayCountBasis.ACT365F);


                var futCode = expGroup.First().UnderlyingFuturesCode;
                if (!futuresPrices.TryGetValue(futCode, out var fut))
                {
                    throw new Exception($"No future price found for contract {futCode}");
                }

                var filtered = new List <SmilePoint>();
                var byStrike = expGroup.GroupBy(e => e.Strike).OrderBy(o => o.Key);
                foreach (var strikeGrp in byStrike)
                {
                    var k = strikeGrp.Key;
                    if (strikeGrp.Count() > 2)
                    {
                        throw new Exception($"Did not expect more than two options at strike {k}");
                    }
                    switch (orderOfP)
                    {
                    case SmileOrderOfPrecedence.Average:
                    {
                        var v = strikeGrp.Average(s => s.ImpliedVol);
                        filtered.Add(
                            new SmilePoint
                            {
                                Strike     = -BlackFunctions.BlackDelta(fut, k, 0.0, t, v, OptionType.P),
                                ImpliedVol = v
                            });
                        break;
                    }

                    case SmileOrderOfPrecedence.UseOTM:
                    {
                        ListedOptionSettlementRecord r;
                        if (fut > k)
                        {
                            r = strikeGrp.Where(sg => sg.CallPut == OptionType.P).SingleOrDefault();
                        }
                        else
                        {
                            r = strikeGrp.Where(sg => sg.CallPut == OptionType.C).SingleOrDefault();
                        }

                        if (r != null && r.ImpliedVol > 1e-8)
                        {
                            filtered.Add(
                                new SmilePoint
                                {
                                    Strike     = -BlackFunctions.BlackDelta(fut, k, 0.0, t, r.ImpliedVol, OptionType.P),
                                    ImpliedVol = r.ImpliedVol
                                });
                        }
                        break;
                    }
                    }
                }

                //now we have filtered to a single vol per-strike...
                if (filtered.Any())
                {
                    output[expiry] = InterpolatorFactory.GetInterpolator(filtered.Select(f => f.Strike).ToArray(), filtered.Select(f => f.ImpliedVol).ToArray(), Interpolator1DType.CubicSpline);
                }
            }
            return(output);
        }
Пример #26
0
        public SVIVolSurface(DateTime originDate, double[] ATMVols, DateTime[] expiries, double[] wingDeltas,
                             double[][] riskies, double[][] flies, double[] fwds, WingQuoteType wingQuoteType, AtmVolType atmVolType,
                             Interpolator1DType timeInterpType, SviType sviType = SviType.Raw, string[] pillarLabels = null) : base()
        {
            if (pillarLabels == null)
            {
                PillarLabels = expiries.Select(x => x.ToString("yyyy-MM-dd")).ToArray();
            }
            else
            {
                PillarLabels = pillarLabels;
            }

            if (ATMVols.Length != expiries.Length || expiries.Length != riskies.Length || riskies.Length != flies.Length)
            {
                throw new Exception("Inputs do not have consistent time dimensions");
            }

            if (wingDeltas.Length != riskies[0].Length || riskies[0].Length != flies[0].Length)
            {
                throw new Exception("Inputs do not have consistent strike dimensions");
            }

            var atmConstraints = ATMVols.Select(a => new ATMStraddleConstraint
            {
                ATMVolType = atmVolType,
                MarketVol  = a
            }).ToArray();

            var needsFlip = wingDeltas.First() > wingDeltas.Last();
            var strikes   = new double[2 * wingDeltas.Length + 1];

            if (needsFlip)
            {
                for (var s = 0; s < wingDeltas.Length; s++)
                {
                    strikes[s] = wingDeltas[wingDeltas.Length - 1 - s];
                    strikes[strikes.Length - 1 - s] = 1.0 - wingDeltas[wingDeltas.Length - 1 - s];
                }
            }
            else
            {
                for (var s = 0; s < wingDeltas.Length; s++)
                {
                    strikes[s] = wingDeltas[s];
                    strikes[strikes.Length - 1 - s] = 1.0 - wingDeltas[s];
                }
            }
            strikes[wingDeltas.Length] = 0.5;

            var wingConstraints = new RRBFConstraint[expiries.Length][];

            RawParams = new SviRawParameters[expiries.Length];
            var f = new AssetSmileSolver();

            if (needsFlip)
            {
                for (var i = 0; i < wingConstraints.Length; i++)
                {
                    var offset = wingDeltas.Length - 1;
                    wingConstraints[i] = new RRBFConstraint[wingDeltas.Length];
                    for (var j = 0; j < wingConstraints[i].Length; j++)
                    {
                        wingConstraints[i][j] = new RRBFConstraint
                        {
                            Delta         = wingDeltas[offset - j],
                            FlyVol        = flies[i][offset - j],
                            RisykVol      = riskies[i][offset - j],
                            WingQuoteType = wingQuoteType,
                        };
                    }
                    RawParams[i] = f.SolveSviRaw(atmConstraints[i], wingConstraints[i], originDate, expiries[i], fwds[i], true);
                }
            }
            else
            {
                for (var i = 0; i < wingConstraints.Length; i++)
                {
                    wingConstraints[i] = new RRBFConstraint[wingDeltas.Length];
                    for (var j = 0; j < wingConstraints[i].Length; j++)
                    {
                        wingConstraints[i][j] = new RRBFConstraint
                        {
                            Delta         = wingDeltas[j],
                            FlyVol        = flies[i][j],
                            RisykVol      = riskies[i][j],
                            WingQuoteType = wingQuoteType,
                        };
                    }
                    RawParams[i] = f.SolveSviRaw(atmConstraints[i], wingConstraints[i], originDate, expiries[i], fwds[i], true);
                }
            }

            OriginDate           = originDate;
            TimeInterpolatorType = timeInterpType;
            Expiries             = expiries;
            ExpiriesDouble       = expiries.Select(x => originDate.CalculateYearFraction(x, TimeBasis)).ToArray();

            _interps    = new IInterpolator1D[5];
            _interps[0] = InterpolatorFactory.GetInterpolator(ExpiriesDouble, RawParams.Select(x => x.A).ToArray(), TimeInterpolatorType);
            _interps[1] = InterpolatorFactory.GetInterpolator(ExpiriesDouble, RawParams.Select(x => x.B).ToArray(), TimeInterpolatorType);
            _interps[2] = InterpolatorFactory.GetInterpolator(ExpiriesDouble, RawParams.Select(x => x.M).ToArray(), TimeInterpolatorType);
            _interps[3] = InterpolatorFactory.GetInterpolator(ExpiriesDouble, RawParams.Select(x => x.Rho).ToArray(), TimeInterpolatorType);
            _interps[4] = InterpolatorFactory.GetInterpolator(ExpiriesDouble, RawParams.Select(x => x.Sigma).ToArray(), TimeInterpolatorType);
            _fwdsInterp = InterpolatorFactory.GetInterpolator(ExpiriesDouble, fwds, Interpolator1DType.Linear);
        }
Пример #27
0
        private void Initialize()
        {
            var pillarsAsDoubles = PillarDates.Select(x => x.ToOADate()).ToArray();

            _interp = InterpolatorFactory.GetInterpolator(pillarsAsDoubles, Contangos, Interpolator1DType.Linear);
        }
Пример #28
0
 public EFCore_DirectSql_CommandAspect(ILazyDisposable <DbContext> context, Type channel, InterpolatorFactory fac)
     : base(new EfCoreStokeRuntime(context, channel, fac))
 {
     Context = context;
 }
Пример #29
0
 public HazzardCurve(TO_HazzardCurve transportObject) : this(transportObject.OriginDate, transportObject.Basis, InterpolatorFactory.GetInterpolator(transportObject.HazzardCurve))
 {
     if (transportObject.ConstantPD.HasValue)
     {
         ConstantPD = transportObject.ConstantPD.Value;
     }
 }
Пример #30
0
 public EFCore_DirectSql_QueryFeature(ILazyDisposable <DbContext> context, Type channel, InterpolatorFactory fac) : base(new EfCoreStokeRuntime(context, channel, fac))
 {
     _dbContext = context;
 }