/// <summary>
        /// Initializes a new instance of the <see cref="CapFloorAssetQuote"/> class.
        /// </summary>
        /// <param name="priceableAsset">The priceable asset.</param>
        /// <param name="baseDate">The base date.</param>
        /// <param name="interpolation">The interpolation.</param>
        /// <param name="extrapolation">if set to <c>true</c> [extrapolation].</param>
        /// <param name="vols">The volatilities.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <param name="discountCurve">The discount rate curve.</param>
        /// <param name="forecastCurve">The forecast rate curve.</param>
        public CapFloorAssetQuote(PriceableCapRateAsset priceableAsset, IRateCurve discountCurve, IRateCurve forecastCurve,
                                  DateTime baseDate, InterpolationMethod interpolation, bool extrapolation, IDictionary <DateTime, Decimal> vols, double tolerance)
        {
            PriceableAsset = priceableAsset;
            PriceableAsset.DiscountCurve = discountCurve;
            PriceableAsset.ForecastCurve = forecastCurve;
            BaseDate            = baseDate;
            Vols                = vols;
            InterpolationMethod = interpolation;
            Extrapolation       = extrapolation;
            Tolerance           = tolerance;
            //This is the flat volatility.
            var premium = PriceableAsset.CalculatePremium();

            if (premium != null)
            {
                Quote = (decimal)premium;
            }
        }
Exemple #2
0
 public static void UpdatePaymentsAmounts(ILogger logger, ICoreCache cache,
                                          String nameSpace, Swap swap,
                                          SwapLegParametersRange_Old leg1Parameters,
                                          SwapLegParametersRange_Old leg2Parameters,
                                          IRateCurve leg1DiscountCurve,
                                          IRateCurve leg2DiscountCurve,
                                          DateTime valuationDate, IBusinessCalendar paymentCalendar)
 {
     foreach (Payment payment in swap.additionalPayment)
     {
         //  choose correct discount curve
         //
         IRateCurve discountCurve;
         if (payment.payerPartyReference.href == leg1Parameters.Payer)
         {
             discountCurve = leg1DiscountCurve;
         }
         else if (payment.payerPartyReference.href == leg2Parameters.Payer)
         {
             discountCurve = leg2DiscountCurve;
         }
         else
         {
             throw new NotImplementedException();
         }
         if (paymentCalendar == null)
         {
             var containsPaymentDateAdjustments = AdjustableOrAdjustedDateHelper.Contains(payment.paymentDate, ItemsChoiceType.dateAdjustments, out var dateAdjustments);
             if (containsPaymentDateAdjustments && dateAdjustments != null)
             {
                 paymentCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, ((BusinessDayAdjustments)dateAdjustments).
                                                                           businessCenters, nameSpace);
             }
         }
         var date = AdjustedDateHelper.GetAdjustedDate(paymentCalendar, payment.paymentDate);
         if (date != null)
         {
             payment.discountFactor          = (decimal)discountCurve.GetDiscountFactor(valuationDate, (DateTime)date);
             payment.discountFactorSpecified = true;
             payment.presentValueAmount      = MoneyHelper.Mul(payment.paymentAmount, payment.discountFactor);
         }
     }
 }
        public NewtonRaphsonSolverFunctions(IPriceableAssetController asset, IPriceableAssetController previousAsset, PricingStructureAlgorithmsHolder algorithmHolder,
                                            IRateCurve baseCurve, DateTime baseDate, SortedDictionary <DateTime, Pair <string, decimal> > items,
                                            double compoundingPeriod, IDictionary <DateTime, double> zeroRateSpreads, IDayCounter dayCounter,
                                            List <DateTime> assetDates)
        {
            _asset           = asset;
            _baseCurve       = baseCurve;
            _zeroRateSpreads = zeroRateSpreads;
            string currency = PropertyHelper.ExtractCurrency(baseCurve.GetPricingStructureId().Properties);

            _algorithm  = algorithmHolder;
            _properties = new NamedValueSet(new Dictionary <string, object>
            {
                { CurveProp.PricingStructureType, "RateCurve" },
                { CurveProp.Market, "DiscountCurveConstruction" },
                { CurveProp.IndexTenor, "0M" },
                { CurveProp.Currency1, currency },
                { "Index", "XXX-XXX" },
                { "Algorithm", "FastLinearZero" },
                { "BaseDate", baseDate },
            });
            _items             = items;
            _compoundingPeriod = compoundingPeriod;
            _dayCounter        = dayCounter;
            _assetDates        = assetDates;
            if (previousAsset != null)
            {
                DateTime previousAssetMaturity = previousAsset.GetRiskMaturityDate();
                DateTime assetMaturity         = asset.GetRiskMaturityDate();
                IEnumerable <KeyValuePair <DateTime, string> > points
                    = from b in baseCurve.GetTermCurve().point
                      where (DateTime)b.term.Items[0] > previousAssetMaturity &&
                      (DateTime)b.term.Items[0] < assetMaturity
                      select new KeyValuePair <DateTime, string>((DateTime)b.term.Items[0], b.id);
                foreach (KeyValuePair <DateTime, string> point in points)
                {
                    _extraPoints.Add(point.Key, point.Value);
                    Pair <string, decimal> pair = new Pair <string, decimal>(point.Value, 0);
                    items.Add(point.Key, pair);
                }
            }
        }
Exemple #4
0
        public static void UpdateFloatingRateDefinition(FloatingRateDefinition floatingRateDefinition,
                                                        FloatingRateCalculation floatingRateCalculation,
                                                        DayCountFraction dayCountFraction,
                                                        CalculationPeriod calculationPeriod,
                                                        IRateCurve forecastCurve)
        {
            var rateObservation = new RateObservation();

            if (floatingRateDefinition.rateObservation != null)
            {
                if (floatingRateDefinition.rateObservation[0].adjustedFixingDateSpecified)
                {
                    rateObservation.adjustedFixingDate          = floatingRateDefinition.rateObservation[0].adjustedFixingDate;
                    rateObservation.adjustedFixingDateSpecified = true;
                }
            }
            floatingRateDefinition.rateObservation = new[] { rateObservation };
            rateObservation.forecastRate           = GetForecastRate(calculationPeriod, forecastCurve, dayCountFraction);
            rateObservation.forecastRateSpecified  = true;
            Decimal finalRate = rateObservation.forecastRate;

            // If spread specified - add it to the final rate.
            //
            if (floatingRateDefinition.spreadSpecified)
            {
                finalRate += floatingRateDefinition.spread;
            }
            // Apply rounding (if it's been specified)
            //
            if (null != floatingRateCalculation.finalRateRounding)
            {
                Rounding finalRateRounding = floatingRateCalculation.finalRateRounding;
                floatingRateDefinition.calculatedRate = RoundingHelper.Round(finalRate, finalRateRounding);
            }
            else
            {
                floatingRateDefinition.calculatedRate = finalRate;
            }
            floatingRateDefinition.calculatedRateSpecified = true;
        }
Exemple #5
0
        private static void UpdateCashflowsWithAmounts(
            ILogger logger,
            ICoreCache cache,
            String nameSpace,
            InterestRateStream stream,
            SwapLegParametersRange legParametersRange,
            ValuationRange valuationRange)
        {
            //  Get a forecast curve
            //
            IRateCurve forecastCurve = null;

            if (!String.IsNullOrEmpty(legParametersRange.ForecastCurve))
            {
                forecastCurve = CurveLoader.LoadInterestRateCurve(logger, cache, nameSpace, legParametersRange.ForecastCurve);
            }
            //  Get a discount curve
            //
            var discountCurve = CurveLoader.LoadInterestRateCurve(logger, cache, nameSpace, legParametersRange.DiscountCurve);

            FixedAndFloatingRateStreamCashflowGenerator.UpdateCashflowsAmounts(stream, forecastCurve, discountCurve, valuationRange.ValuationDate);
        }
Exemple #6
0
        /// <summary>
        /// Bootstraps the specified priceable assets.
        /// </summary>
        /// <param name="priceableAssets">The priceable assets.</param>
        /// <param name="referenceCurve">The reference curve.</param>
        /// <param name="baseDate">The base date.</param>
        /// <param name="termCurve">The term Curve with pre-existing points. This will not work if there are no points.</param>
        /// <param name="tolerance">Solver tolerance to use.</param>
        /// <returns></returns>
        public static TermPoint[] Bootstrap(IList <IPriceableRateSpreadAssetController> priceableAssets,
                                            IRateCurve referenceCurve, DateTime baseDate, TermCurve termCurve,
                                            Double tolerance)
        {
            const double min = 0.000000001;
            const double max = 1;
            Dictionary <DateTime, Pair <string, decimal> > items
                = new Dictionary <DateTime, Pair <string, decimal> > ();
            //  Add the elements (date : discount factor) to the list
            IDictionary <DateTime, double> dfs = new Dictionary <DateTime, double>();

            foreach (var point in termCurve.point)
            {
                dfs.Add((DateTime)point.term.Items[0], (double)point.mid);
                items.Add((DateTime)point.term.Items[0], new Pair <string, decimal>(point.id, point.mid));
            }
            var solver = new Brent();

            foreach (var priceableAsset in priceableAssets)
            {
                var assetMaturityDate = priceableAsset.GetRiskMaturityDate();
                if (dfs.ContainsKey(assetMaturityDate))
                {
                    continue;
                }
                //The first guess, which should be correct for all priceable assets with analytical solutions that have been implemented.
                //So far this is only wrt Depos and Futures...This now should automatically extrapolate the required discount factor on a flat rate basis.
                dfs.Add(assetMaturityDate, (double)priceableAsset.CalculateDiscountFactorAtMaturity(referenceCurve));
                var objectiveFunction = new RateSpreadAssetQuote(priceableAsset, referenceCurve, baseDate,
                                                                 termCurve.extrapolationPermitted, dfs, tolerance);
                // check accuracy so that solver is only called if outside the tolerance.
                if (!objectiveFunction.InitialValue())
                {
                    dfs[assetMaturityDate] = solver.Solve(objectiveFunction, tolerance, dfs[assetMaturityDate], min, max);
                }
                items.Add(assetMaturityDate, new Pair <string, decimal>(priceableAsset.Id, (decimal)dfs[assetMaturityDate]));
            }
            return(TermPointsFactory.Create(items));
        }
    // used in constructor
    private void Ini(string tenor, IRateCurve curve, BilinearInterpolator capletVolMatrix, double nominal)
    {
        stringTenor = tenor;
        rateCurve   = curve;
        volMatrix   = capletVolMatrix;
        N           = nominal;

        // yf of longer cap
        SwapStyle y = (SwapStyle) new BuildingBlockFactory().CreateBuildingBlock(curve.RefDate(), 0, tenor, curve.GetSwapStyle().buildingBlockType);

        yf          = y.scheduleLeg2.GetYFVect(Dc._Act_360);
        capSchedule = y.scheduleLeg2;
        int toRemove = yf.Length - 1;

        yf = yf.Where((val, inx) => inx != toRemove).ToArray();

        // T all tenor needed. They are more than input
        Date        refDate = curve.RefDate();
        List <Date> ToDate  = y.scheduleLeg2.toDates.ToList();

        ToDate.RemoveAt(ToDate.Count - 1);  // remove last element
        T = (from c in ToDate
             select refDate.YF_365(c)).ToArray();
        // df- getting relevant dates
        Date[] dfDate  = y.scheduleLeg2.payDates;
        int    Ncaplet = yf.Length; // number of caplets

        df = new double[Ncaplet];
        // fwd rate
        fwd = new double[Ncaplet];
        Date[] fwdDate = y.scheduleLeg2.fromDates;

        for (int i = 0; i < Ncaplet; i++) // Note the loop start from 1
        {                                 // first discount factor is on first payment date of caplet (first caplet skipped)
            df[i]  = curve.Df(dfDate[i + 1]);
            fwd[i] = curve.Fwd(fwdDate[i + 1]);
        }
    }
Exemple #8
0
        /// <summary>
        /// Set discount from a yield curve ID
        /// </summary>
        /// <param name="rateCurve"></param>
        /// <returns></returns>
        public string SetDiscountFactors(IRateCurve rateCurve)
        {
            const int length = 123;
            string    temp;

            try
            {
                var      discount = new double[length];
                DateTime today    = DateTime.Now;
                for (int i = 0; i < length; i++)
                {
                    discount[i] = rateCurve.GetDiscountFactor(today, today.AddMonths(i * 3));
                }
                _usd.CurDiscount    = discount;
                _usd.DiscountStatus = "User Defined";
                temp = String.Format("Discount factors were set.");
            }
            catch (Exception e)
            {
                temp = e.ToString();
            }
            return(temp);
        }
Exemple #9
0
    public static double FwdBasis(Date StartDate, string SwapTenor, IRateCurve Curve1, IRateCurve Curve2)
    {
        SwapStyle S1 = (SwapStyle) new BuildingBlockFactory().CreateBuildingBlock(StartDate, 0.0, SwapTenor, Curve1.GetSwapStyle().buildingBlockType);
        SwapStyle S2 = (SwapStyle) new BuildingBlockFactory().CreateBuildingBlock(StartDate, 0.0, SwapTenor, Curve2.GetSwapStyle().buildingBlockType);

        double[] yfFloatLeg1 = S1.scheduleLeg2.GetYFVect(S1.swapLeg2.DayCount);

        // using LINQ syntax
        double[] dfFloatLeg1 = (from d in S1.scheduleLeg2.payDates
                                select Curve1.Df(d)).ToArray <double>();
        double[] fwdFloatLeg1 = (from d in S1.scheduleLeg2.fromDates
                                 select Curve1.Fwd(d)).ToArray <double>();

        double[] yfFloatLeg2 = S2.scheduleLeg2.GetYFVect(S2.swapLeg2.DayCount);
        // using LINQ syntax
        double[] dfFloatLeg2 = (from d in S2.scheduleLeg2.payDates
                                select Curve2.Df(d)).ToArray <double>();

        double[] fwdFloatLeg2 = (from d in S2.scheduleLeg2.fromDates
                                 select Curve2.Fwd(d)).ToArray <double>();

        return(SpreadBasisFormula(yfFloatLeg1, dfFloatLeg1, fwdFloatLeg1,
                                  yfFloatLeg2, dfFloatLeg2, fwdFloatLeg2));
    }
Exemple #10
0
        /// <summary>
        /// Calculates the specified model data.
        /// </summary>
        /// <param name="valuationDate">The valuation date.</param>
        /// <param name="discountCurve">The discount curve.</param>
        /// <param name="forecastCurve">The forward curve.</param>
        /// <param name="volCurve">The volatility surface.
        /// and discount curves when called with ForecastRateCurve.</param>
        /// <param name="curveToPerturb">The curve to perturb: the discount curve, the forecast curve or both.</param>
        /// <returns></returns>
        public IDictionary <string, double> CalculateRatePDH(DateTime valuationDate,
                                                             IRateCurve discountCurve, IRateCurve forecastCurve, IVolatilitySurface volCurve, CurvePerturbation curveToPerturb)
        {
            var result = new Dictionary <string, double>();

            AnalyticResults = new RateOptionAssetResults();
            switch (ModelIdentifier)
            {
            case "CapAsset":
                AnalyticsModel = new RateOptionAssetAnalytic();
                break;

            case "DiscountCapAsset":
                AnalyticsModel = new RateOptionAssetAnalytic();
                break;
            }
            ForecastCurveName   = forecastCurve.GetPricingStructureId().UniqueIdentifier;
            DiscountCurveName   = discountCurve.GetPricingStructureId().UniqueIdentifier;
            VolatilityCurveName = volCurve.GetPricingStructureId().UniqueIdentifier;
            var analyticModelParameters = new RateOptionAssetParameters {
                IsPut = !IsCap, Notionals = Notionals
            };

            //and the rest rates
            if (ResetRates != null)
            {
                analyticModelParameters.ForwardRates = ResetRates;
            }
            //2. Get the discount factors
            analyticModelParameters.ForecastDiscountFactors =
                GetDiscountFactors(forecastCurve, AdjustedPeriodDates.ToArray(), valuationDate);
            analyticModelParameters.PaymentDiscountFactors =
                GetDiscountFactors(discountCurve, AdjustedPeriodDates.ToArray(), valuationDate);
            //3. Get the respective year fractions
            analyticModelParameters.YearFractions = YearFractions;
            //4. set the expiry times.
            TimesToExpiry =
                GetTimesToExpiry(ExpiryDates, valuationDate);
            analyticModelParameters.TimesToExpiry = TimesToExpiry;
            //5. Get the vols
            analyticModelParameters.Volatilities =
                GetVolatilties(volCurve, TimesToExpiry, Strikes);
            //8. Get the Strikes
            analyticModelParameters.Strikes = Strikes;
            //9. Set the analytic input parameters and Calculate the respective metrics
            var analyticResults =
                AnalyticsModel.Calculate <IRateOptionAssetResults, RateOptionAssetResults>(analyticModelParameters,
                                                                                           new[] { RateOptionMetrics.NPV });

            AnalyticResults = analyticResults;
            var baseNPV = SumDoubleList(AnalyticResults.NPV, 0);

            //Now loop through the risk curves.
            if (curveToPerturb == CurvePerturbation.DiscountCurve)
            {
                var riskCurves = discountCurve.CreateCurveRiskSet(1);
                foreach (var curve in riskCurves)
                {
                    var perturbedAsset = curve.GetPricingStructureId().Properties.GetValue <string>("PerturbedAsset");
                    analyticResults = RiskCalculationHelper((IRateCurve)curve, analyticModelParameters);
                    result.Add("DiscountCurve:" + perturbedAsset, baseNPV - SumDoubleList(analyticResults.NPV, 0));
                }
            }
            if (curveToPerturb == CurvePerturbation.ForecastCurve)
            {
                var riskCurves = forecastCurve.CreateCurveRiskSet(1);
                foreach (var curve in riskCurves)
                {
                    var perturbedAsset = curve.GetPricingStructureId().Properties.GetValue <string>("PerturbedAsset");
                    analyticResults = ForecastRiskCalculationHelper((IRateCurve)curve, analyticModelParameters);
                    result.Add("ForecastCurve:" + perturbedAsset, baseNPV - SumDoubleList(analyticResults.NPV, 0));
                }
            }
            if (curveToPerturb == CurvePerturbation.Both)
            {
                var riskCurves1 = discountCurve.CreateCurveRiskSet(1);
                foreach (var curve in riskCurves1)
                {
                    var perturbedAsset = curve.GetPricingStructureId().Properties.GetValue <string>("PerturbedAsset");
                    analyticResults = RiskCalculationHelper((IRateCurve)curve, analyticModelParameters);
                    result.Add("DiscountCurve:" + perturbedAsset, baseNPV - SumDoubleList(analyticResults.NPV, 0));
                }
                var riskCurves2 = forecastCurve.CreateCurveRiskSet(1);
                foreach (var curve in riskCurves2)
                {
                    var perturbedAsset = curve.GetPricingStructureId().Properties.GetValue <string>("PerturbedAsset");
                    analyticResults = ForecastRiskCalculationHelper((IRateCurve)curve, analyticModelParameters);
                    result.Add("ForecastCurve:" + perturbedAsset, baseNPV - SumDoubleList(analyticResults.NPV, 0));
                }
            }
            return(result);
        }
Exemple #11
0
        /// <summary>
        /// Calculates the specified model data.
        /// </summary>
        /// <param name="modelData">The model data.</param>
        /// <returns></returns>
        public override BasicAssetValuation Calculate(IAssetControllerData modelData)
        {
            ModelData = modelData;
            switch (ModelIdentifier)
            {
            case "CapAsset":
                AnalyticsModel = new RateOptionAssetAnalytic();
                break;

            case "DiscountCapAsset":
                AnalyticsModel = new RateOptionAssetAnalytic();
                break;
            }
            var metrics                 = MetricsHelper.GetMetricsToEvaluate(Metrics, AnalyticsModel.Metrics);
            var metricsToEvaluate       = metrics.ToArray();
            var analyticModelParameters = new RateOptionAssetParameters();

            AnalyticResults = new RateOptionAssetResults();
            var                marketEnvironment = modelData.MarketEnvironment;
            IRateCurve         rateCurve         = null;
            IRateCurve         discountCurve     = null;
            IVolatilitySurface volCurve          = null;

            //1. instantiate curve
            if (marketEnvironment.GetType() == typeof(SwapLegEnvironment))
            {
                rateCurve           = ((ISwapLegEnvironment)marketEnvironment).GetForecastRateCurve();
                ForecastCurveName   = rateCurve.GetPricingStructureId().UniqueIdentifier;
                discountCurve       = ((ISwapLegEnvironment)marketEnvironment).GetDiscountRateCurve();
                DiscountCurveName   = discountCurve.GetPricingStructureId().UniqueIdentifier;
                volCurve            = ((ISwapLegEnvironment)marketEnvironment).GetVolatilitySurface();
                VolatilityCurveName = volCurve.GetPricingStructureId().UniqueIdentifier;
            }
            //Cap logic.
            analyticModelParameters.IsPut = !IsCap;
            //1. Notionals
            analyticModelParameters.Notionals = Notionals;
            //and the rest rates
            if (ResetRates != null)
            {
                analyticModelParameters.ForwardRates = ResetRates;
            }
            //2. Get the discount factors
            analyticModelParameters.ForecastDiscountFactors =
                GetDiscountFactors(rateCurve, AdjustedPeriodDates.ToArray(), modelData.ValuationDate);
            analyticModelParameters.PaymentDiscountFactors =
                GetDiscountFactors(discountCurve, AdjustedPeriodDates.ToArray(), modelData.ValuationDate);
            //3. Get the respective year fractions
            analyticModelParameters.YearFractions = YearFractions;
            //4. set the expiry times.
            TimesToExpiry =
                GetTimesToExpiry(ExpiryDates, modelData.ValuationDate);
            analyticModelParameters.TimesToExpiry = TimesToExpiry;
            //5. Get the vols
            analyticModelParameters.Volatilities =
                GetVolatilties(volCurve, TimesToExpiry, Strikes);
            //8. Get the Strikes
            analyticModelParameters.Strikes = Strikes;
            ParRate = CalculateImpliedParRate(modelData.ValuationDate);
            analyticModelParameters.Rate = (double)ParRate;
            //9. Set the analytic input parameters and Calculate the respective metrics
            AnalyticResults =
                AnalyticsModel.Calculate <IRateOptionAssetResults, RateOptionAssetResults>(analyticModelParameters,
                                                                                           metricsToEvaluate);
            //TODO change this method and return a table report of all greeks.
            return(GetValue(AnalyticResults));
        }
Exemple #12
0
        /// <summary>
        /// Bootstraps the specified priceable assets.
        /// </summary>
        /// <param name="priceableAssets">The priceable assets.</param>
        /// <param name="baseZeroCurve">The base Zero Curve</param>
        /// <param name="algorithmHolder">The algorithmHolder</param>
        /// <returns></returns>
        public TermPoint[] Bootstrap(List <IPriceableRateAssetController> priceableAssets,
                                     IRateCurve baseZeroCurve, PricingStructureAlgorithmsHolder algorithmHolder)
        {
            var      items    = new SortedDictionary <DateTime, Pair <string, decimal> >();
            DateTime baseDate = baseZeroCurve.GetBaseDate();

            items.Add(baseDate, new Pair <string, decimal>(null, 1m));
            bool         firstTime         = true;
            const double compoundingPeriod = 0.25;
            IPriceableRateAssetController previousAsset = null;
            IEnumerable <TermPoint>       basePillars   = baseZeroCurve.GetTermCurve().point;
            IDayCounter dayCounter = null;

            foreach (IPriceableRateAssetController priceableAsset in priceableAssets)
            {
                List <DateTime> assetDates;
                if (priceableAsset is PriceableSwapRateAsset swap)
                {
                    dayCounter = DayCounterHelper.Parse(swap.DayCountFraction.Value);
                    assetDates = swap.AdjustedPeriodDates;
                }
                else
                {
                    PriceableDeposit deposit = priceableAsset as PriceableDeposit;
                    if (deposit == null)
                    {
                        throw new ArgumentException(
                                  $"PriceableAsset must be a PriceableSwapRateAsset or PriceableDeposit, '{priceableAsset.GetType()}' is not implemented.");
                    }
                    dayCounter = DayCounterHelper.Parse(deposit.Deposit.dayCountFraction.Value);
                    assetDates = new List <DateTime> {
                        deposit.AdjustedStartDate, deposit.GetRiskMaturityDate()
                    };
                }
                DateTime maturityDate = priceableAsset.GetRiskMaturityDate();
                if (items.Keys.Contains(maturityDate))
                {
                    throw new ArgumentException(
                              $"Duplicate priceable asset on '{maturityDate:yyyy-MM-dd}'", nameof(priceableAssets));
                }
                //The min and max values to use with the solver.
                const int xmin     = -1;
                const int xmax     = 1;
                var       accuracy = 10 ^ -12;
                if (firstTime)
                {
                    firstTime = false;
                    // Solve to find the quarterly compounded zero rate spread
                    var solverFunctions
                        = new NewtonRaphsonSolverFunctions(priceableAsset, null, algorithmHolder, baseZeroCurve,
                                                           baseDate, items, compoundingPeriod, ZeroRateSpreads, dayCounter, assetDates);
                    var solver       = new Newton();
                    var initialGuess = (double)priceableAsset.MarketQuote.value;
                    //var solution = new CenteredFiniteDifferenceDerivative();
                    Func <double, double> f           = solverFunctions.ShortEndTargetFunction;
                    var    derivativeOfTargetFunction = new NumericalDerivative().CreateDerivativeFunctionHandle(f, 1);
                    double zeroRateSpread             = solver.Solve(f, derivativeOfTargetFunction, accuracy, initialGuess, xmin, xmax);
                    // add first point
                    DateTime startDate = assetDates.First();
                    decimal  df        = (decimal)GetAdjustedDiscountFactor(baseDate, startDate, dayCounter, zeroRateSpread, baseZeroCurve);
                    if (startDate != baseDate)
                    {
                        items.Add(startDate, new Pair <string, decimal>(null, df));
                    }
                    ZeroRateSpreads.Add(maturityDate, zeroRateSpread);
                    // add extra points
                    IEnumerable <TermPoint> extraPoints = basePillars.Where(b => (DateTime)b.term.Items[0] > startDate && (DateTime)b.term.Items[0] < maturityDate);
                    // Extrapolate the preceding extra points
                    foreach (TermPoint extraPoint in extraPoints)
                    {
                        DateTime date = (DateTime)extraPoint.term.Items[0];
                        df = (decimal)GetAdjustedDiscountFactor(baseDate, date, dayCounter, zeroRateSpread, baseZeroCurve);
                        items.Add(date, new Pair <string, decimal>(extraPoint.id, df));
                    }
                    // add final point
                    df = (decimal)GetAdjustedDiscountFactor(baseDate, maturityDate, dayCounter, zeroRateSpread, baseZeroCurve);
                    items.Add(maturityDate, new Pair <string, decimal>(priceableAsset.Id, df));
                }
                else
                {
                    items.Add(maturityDate, new Pair <string, decimal>(priceableAsset.Id, 0));
                    ZeroRateSpreads.Add(maturityDate, (double)priceableAsset.MarketQuote.value);
                    // Solve to find the quarterly compounded zero rate spread
                    var solverFunctions
                        = new NewtonRaphsonSolverFunctions(priceableAsset, previousAsset, algorithmHolder, baseZeroCurve,
                                                           baseDate, items, compoundingPeriod, ZeroRateSpreads, dayCounter, assetDates);
                    Func <double, double> f           = solverFunctions.LongEndTargetFunction;
                    var    solver                     = new Newton();
                    var    initialGuess               = (double)priceableAsset.MarketQuote.value;
                    var    derivativeOfTargetFunction = new NumericalDerivative().CreateDerivativeFunctionHandle(f, 1);
                    double zeroRateSpread             = solver.Solve(f, derivativeOfTargetFunction, accuracy, initialGuess, xmin, xmax);
                    // Update discount factor value
                    decimal df = (decimal)GetAdjustedDiscountFactor(baseDate, maturityDate, dayCounter, zeroRateSpread, baseZeroCurve);
                    items[maturityDate].Second    = df;
                    ZeroRateSpreads[maturityDate] = zeroRateSpread;
                    solverFunctions.UpdateDiscountFactors(baseDate);
                }
                previousAsset = priceableAsset;
            }
            // Extrapolate the following extra points
            IEnumerable <TermPoint>         finalPoints         = basePillars.Where(b => (DateTime)b.term.Items[0] > items.Last().Key);
            KeyValuePair <DateTime, double> zeroRateSpreadFinal = ZeroRateSpreads.Last();

            foreach (TermPoint extraPoint in finalPoints)
            {
                DateTime date = (DateTime)extraPoint.term.Items[0];
                decimal  df   = (decimal)GetAdjustedDiscountFactor(baseDate, date, dayCounter, zeroRateSpreadFinal.Value, baseZeroCurve);
                items.Add(date, new Pair <string, decimal>(extraPoint.id, df));
            }
            return(TermPointsFactory.Create(items));
        }
Exemple #13
0
        /// <summary>
        /// <remarks>
        /// Always:
        /// pay floating
        /// receive fixed
        /// </remarks>
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="cache"></param>
        /// <param name="nameSpace"></param>
        /// <param name="valueDate"></param>
        /// <param name="effectiveDate"></param>
        /// <param name="terminationDate"></param>
        /// <param name="interpolationMethod"></param>
        /// <param name="margineAboveFloatingRate"></param>
        /// <param name="resetRate"></param>
        /// <param name="directionDateGenerationPayLeg"></param>
        /// <param name="cashFlowFrequencyPayLeg"></param>
        /// <param name="accrualMethodPayLeg"></param>
        /// <param name="holidaysPayLeg"></param>
        /// <param name="discountFactorCurvePayLeg"></param>
        /// <param name="directionDateGenerationRecLeg"></param>
        /// <param name="cashFlowFrequencyRecLeg"></param>
        /// <param name="accrualMethodRecLeg"></param>
        /// <param name="holidaysRecLeg"></param>
        /// <param name="discountFactorCurveRecLeg"></param>
        /// <returns></returns>
        public double GetSwapParRateWithoutCurves
        (
            ILogger logger,
            ICoreCache cache,
            String nameSpace,
            DateTime valueDate,
            DateTime effectiveDate,
            DateTime terminationDate,
            string interpolationMethod,      //1 is linear on forward rates => make sure that the right curve is provided ...
            double margineAboveFloatingRate, // use 0 initially
            double resetRate,
            int directionDateGenerationPayLeg,
            string cashFlowFrequencyPayLeg,
            string accrualMethodPayLeg,
            string holidaysPayLeg,
            IRateCurve discountFactorCurvePayLeg,
            int directionDateGenerationRecLeg,
            string cashFlowFrequencyRecLeg,
            string accrualMethodRecLeg,
            string holidaysRecLeg,
            IRateCurve discountFactorCurveRecLeg
        )
        {
            const decimal dummyNotional = 1000000.0m;
            //  received fixed leg
            //
            var recFixedCashflows = InterestRateSwapPricer.GenerateCashflows(logger, cache, nameSpace, null, valueDate, effectiveDate, terminationDate,
                                                                             interpolationMethod, margineAboveFloatingRate, resetRate,
                                                                             dummyNotional,
                                                                             directionDateGenerationRecLeg,
                                                                             cashFlowFrequencyRecLeg,
                                                                             accrualMethodRecLeg,
                                                                             holidaysRecLeg,
                                                                             discountFactorCurveRecLeg,
                                                                             true);

            recFixedCashflows.PayingFixedRate = false;
            //  pay floating leg
            //
            var payFloatingCashflows = InterestRateSwapPricer.GenerateCashflows(logger, cache, nameSpace, null, valueDate, effectiveDate, terminationDate,
                                                                                interpolationMethod, margineAboveFloatingRate, resetRate,
                                                                                dummyNotional,
                                                                                directionDateGenerationPayLeg,
                                                                                cashFlowFrequencyPayLeg,
                                                                                accrualMethodPayLeg,
                                                                                holidaysPayLeg,
                                                                                discountFactorCurvePayLeg,
                                                                                false);

            payFloatingCashflows.PayingFixedRate = false;
            var objectiveFunction = new InterestRateSwapPricer
            {
                ReceiveLeg = recFixedCashflows,
                PayLeg     = payFloatingCashflows
            };
            var solver = new Brent
            {
                LowerBound = -100.0,
                UpperBound = 100.0
            };

            return(solver.Solve(objectiveFunction, Accuracy, Guess, Step));
        }
 /// <summary>
 /// Gets the discount factors.
 /// </summary>
 /// <param name="discountFactorCurve">The discount factor curve.</param>
 /// <param name="periodDates">The period dates.</param>
 /// <param name="valuationDate">The valuation date.</param>
 /// <returns></returns>
 public List <double> GetDiscountFactors(IRateCurve discountFactorCurve, DateTime[] periodDates,
                                         DateTime valuationDate)
 {
     return(periodDates.Select(periodDate => GetDiscountFactor(discountFactorCurve, periodDate, valuationDate)).ToList());
 }
 /// <summary>
 /// Initiates a new model.
 /// </summary>
 /// <param name="valuationDate">The valuation date.</param>
 /// <param name="startDate">The start date of the coupon.</param>
 /// <param name="endDate">The end date of the coupon.</param>
 /// <param name="paymentDate">The payment date of the cash flow.</param>
 /// <param name="timeToIndex">The timeToIndex. Not necessarily the time to expiry. This is used for surface interpolation..</param>
 /// <param name="capStrike">The cap strike.</param>
 /// <param name="floorStrike">The floor strike.</param>
 /// <param name="reportingCurrencyFxCurve">THe fx curve. It must already be normalised.</param>
 /// <param name="discountCurve">The rate curve to use for discounting.</param>
 /// <param name="forecastCurve">The forecast curve.</param>
 /// <param name="indexVolSurface">The index volatility surface.</param>
 public RateOptionCouponAnalytic(DateTime valuationDate, DateTime startDate, DateTime endDate, DateTime paymentDate,
                                 decimal timeToIndex, decimal capStrike, decimal floorStrike, IFxCurve reportingCurrencyFxCurve, IRateCurve discountCurve, IRateCurve forecastCurve, IVolatilitySurface indexVolSurface)
     : this(valuationDate, startDate, endDate, paymentDate, timeToIndex, capStrike, reportingCurrencyFxCurve, discountCurve, forecastCurve, indexVolSurface)
 {
     IsCollar              = true;
     CollarFloorStrike     = floorStrike;
     CollarFloorVolatility = (decimal)indexVolSurface.GetValue((double)timeToIndex, (double)floorStrike);
 }
        /// <summary>
        /// Calculates the specified model data.
        /// </summary>
        /// <param name="modelData">The model data.</param>//TODO the floating delta?
        /// <returns></returns>
        public override AssetValuation Calculate(IInstrumentControllerData modelData)
        {
            ModelData = modelData;
            AnalyticModelParameters       = null;
            AnalyticsModel                = new FxRateCashflowAnalytic();
            CalculationResults            = null;
            YearFractionToCashFlowPayment = Convert.ToDecimal(CDefaultDayCounter.YearFraction(ModelData.ValuationDate, PaymentDate));
            //Make sure there are some bucket dates even if not set previously.
            if (BucketedDates.Length < 1)
            {
                UpdateBucketingInterval(ModelData.ValuationDate, PeriodHelper.Parse(CDefaultBucketingInterval));
            }
            IsRealised = HasBeenRealised(ModelData.ValuationDate);
            //Add the extra metrics required
            var quotes = ModelData.AssetValuation.quote.ToList();

            if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, FloatingCashflowMetrics.NPV.ToString()) == null)
            {
                var quote = QuotationHelper.Create(0.0m, FloatingCashflowMetrics.LocalCurrencyNPV.ToString(), "DecimalValue", ModelData.ValuationDate);
                quotes.Add(quote);
            }
            if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, FloatingCashflowMetrics.LocalCurrencyNPV.ToString()) == null)
            {
                var quote = QuotationHelper.Create(0.0m, FloatingCashflowMetrics.LocalCurrencyNPV.ToString(), "DecimalValue", ModelData.ValuationDate);
                quotes.Add(quote);
            }
            if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.RiskNPV.ToString()) == null)
            {
                var quote = QuotationHelper.Create(0.0m, InstrumentMetrics.NPV.ToString(), "DecimalValue", ModelData.ValuationDate);
                quotes.Add(quote);
            }
            if (AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, FloatingCashflowMetrics.LocalCurrencyExpectedValue.ToString()) == null)
            {
                var quote = QuotationHelper.Create(0.0m, FloatingCashflowMetrics.LocalCurrencyExpectedValue.ToString(), "DecimalValue", ModelData.ValuationDate);
                quotes.Add(quote);
            }
            //Check if risk calc are required.
            bool delta1PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta1PDH.ToString()) != null ||
                             AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta1PDH.ToString()) != null;
            //Check if risk calc are required.
            bool delta0PDH = AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.LocalCurrencyDelta0PDH.ToString()) != null ||
                             AssetValuationHelper.GetQuotationByMeasureType(ModelData.AssetValuation, InstrumentMetrics.Delta0PDH.ToString()) != null;

            ModelData.AssetValuation.quote = quotes.ToArray();
            var        metrics           = ResolveModelMetrics(AnalyticsModel.Metrics);
            IFxCurve   fxCurve           = null;
            IRateCurve discountCurve     = null;
            IFxCurve   currencyCurve     = null;
            var        reportingCurrency = ModelData.ReportingCurrency == null ? PaymentCurrency.Value : ModelData.ReportingCurrency.Value;
            //Set the basic model.
            var analyticModelParameters = new FxRateCashflowParameters
            {
                Multiplier        = Multiplier,
                ValuationDate     = ModelData.ValuationDate,
                PaymentDate       = PaymentDate,
                Currency          = PaymentCurrency.Value,
                ReportingCurrency = reportingCurrency,
                NotionalAmount    = PaymentAmount.amount,
                StartIndex        = StartIndex,
                IsRealised        = IsRealised,
                CurveYearFraction =
                    YearFractionToCashFlowPayment,
                PeriodAsTimesPerYear = 0.25m,
                BucketingRate        = 0.05m
            };

            if (modelData.MarketEnvironment is ISwapLegEnvironment environment)
            {
                var marketEnvironment = environment;
                //The discount curve.
                discountCurve = marketEnvironment.GetDiscountRateCurve();
                discountCurve.PricingStructureEvolutionType = PricingStructureEvolutionType;
                analyticModelParameters.DiscountCurve       = discountCurve;
                //Check if it is our of currency.
                if (ModelData.ReportingCurrency != null && ModelData.ReportingCurrency.Value != PaymentCurrency.Value)
                {
                    fxCurve = marketEnvironment.GetReportingCurrencyFxCurve();
                    fxCurve.PricingStructureEvolutionType            = PricingStructureEvolutionType;
                    analyticModelParameters.ReportingCurrencyFxCurve = fxCurve;
                }
            }
            else if (modelData.MarketEnvironment.GetType() == typeof(MarketEnvironment))
            {
                var market = (MarketEnvironment)modelData.MarketEnvironment;
                discountCurve = (IRateCurve)market.SearchForPricingStructureType(DiscountCurveName);
                discountCurve.PricingStructureEvolutionType = PricingStructureEvolutionType;
                analyticModelParameters.DiscountCurve       = discountCurve;
                var currencyCurveName = MarketEnvironmentHelper.ResolveFxCurveNames(StartFxRate.quotedCurrencyPair.currency1.Value, StartFxRate.quotedCurrencyPair.currency2.Value);
                currencyCurve = (IFxCurve)market.SearchForPricingStructureType(currencyCurveName);
                currencyCurve.PricingStructureEvolutionType = PricingStructureEvolutionType;
                if (delta1PDH)
                {
                    var riskMarket = market.SearchForPerturbedPricingStructures(DiscountCurveName, "delta1PDH");
                    analyticModelParameters.Delta1PDHCurves       = riskMarket;
                    analyticModelParameters.Delta1PDHPerturbation = 10;
                }
                if (delta0PDH)
                {
                    var riskMarket = market.SearchForPerturbedPricingStructures(DiscountCurveName, "delta0PDH");//TODO The fx deltas
                    analyticModelParameters.Delta1PDHCurves       = riskMarket;
                    analyticModelParameters.Delta1PDHPerturbation = 10;
                }
                if (modelData.ReportingCurrency.Value != PaymentCurrency.Value)
                {
                    string curveName = MarketEnvironmentHelper.ResolveFxCurveNames(PaymentCurrency.Value, modelData.ReportingCurrency.Value);
                    fxCurve = (IFxCurve)market.SearchForPricingStructureType(curveName);
                    fxCurve.PricingStructureEvolutionType            = PricingStructureEvolutionType;
                    analyticModelParameters.ReportingCurrencyFxCurve = fxCurve;
                }
                if (HybridValuation)
                {
                    var currency1RateCurve = (IRateCurve)market.SearchForPricingStructureType(Currency1DiscountCurveName);
                    currency1RateCurve.PricingStructureEvolutionType = PricingStructureEvolutionType;
                    var currency2RateCurve = (IRateCurve)market.SearchForPricingStructureType(Currency2DiscountCurveName);
                    currency2RateCurve.PricingStructureEvolutionType = PricingStructureEvolutionType;
                    AnalyticsModel = new FxRateCashflowAnalytic(ModelData.ValuationDate, PaymentDate, currencyCurve, currency1RateCurve, currency2RateCurve, !InvertFxRate, IsSettlementInCurrency1, fxCurve);
                }
            }
            // store inputs and results from this run
            AnalyticModelParameters = analyticModelParameters;
            if (!HybridValuation)
            {
                AnalyticsModel = new FxRateCashflowAnalytic(ModelData.ValuationDate, PaymentDate,
                                                            fxCurve, currencyCurve, discountCurve);
            } //TODO Fix this with a generic index curve.
            //AnalyticsModel = analyticsModel;
            CalculationResults            = AnalyticsModel.Calculate <IFloatingCashflowResults, FloatingCashflowResults>(AnalyticModelParameters, metrics.ToArray());
            CalculationPerformedIndicator = true;
            PaymentDiscountFactor         = ((FxRateCashflowAnalytic)AnalyticsModel).PaymentDiscountFactor;
            ForecastAmount = MoneyHelper.GetAmount(CalculationResults.LocalCurrencyExpectedValue, PaymentAmount.currency);
            NPV            = MoneyHelper.GetAmount(CalculationResults.LocalCurrencyNPV, PaymentAmount.currency);
            AssetValuation valuation = GetValue(CalculationResults, modelData.ValuationDate);

            valuation.id = Id;
            return(valuation);
        }
        /// <summary>
        /// Creates a stream environment.
        /// </summary>
        /// <param name="baseDate"></param>
        /// <param name="discountCurve"></param>
        /// <param name="forecastCurve"></param>
        /// <param name="fxCurve"></param>
        /// <returns></returns>
        public static ISwapLegEnvironment CreateInterestRateStreamEnvironment(DateTime baseDate, IRateCurve discountCurve, IRateCurve forecastCurve, IFxCurve fxCurve)
        {
            var market = new SwapLegEnvironment();

            market.AddPricingStructure(InterestRateStreamPSTypes.DiscountCurve.ToString(), discountCurve);
            market.AddPricingStructure(InterestRateStreamPSTypes.ForecastCurve.ToString(), forecastCurve);
            market.AddPricingStructure(InterestRateStreamPSTypes.ReportingCurrencyFxCurve.ToString(), fxCurve);
            return(market);
        }
        /// <summary>
        /// Calculates the specified model data.
        /// </summary>
        /// <param name="modelData">The model data.</param>
        /// <returns></returns>
        public override BasicAssetValuation Calculate(IAssetControllerData modelData)
        {
            ModelData      = modelData;
            AnalyticsModel = new InflationAssetAnalytic();
            //DependencyCreator.Resolve<IModelAnalytic<ISimpleDualAssetParameters, RateMetrics>>("InflationAsset");
            var metrics = MetricsHelper.GetMetricsToEvaluate(Metrics, AnalyticsModel.Metrics);
            // Determine if DFAM has been requested - if so thats all we evaluate - every other metric is ignored
            var bEvalDiscountFactorAtMaturity = false;

            if (metrics.Contains(RateMetrics.DiscountFactorAtMaturity))
            {
                bEvalDiscountFactorAtMaturity = true;
                metrics.RemoveAll(
                    metricItem => metricItem != RateMetrics.DiscountFactorAtMaturity);
            }

            ISimpleDualAssetParameters analyticModelParameters = new DualRateAssetParameters
            {
                YearFraction = YearFraction
            };

            AnalyticResults = new RateAssetResults();
            var        metricsToEvaluate = metrics.ToArray();
            var        marketEnvironment = modelData.MarketEnvironment;
            IRateCurve curve             = null;

            //1. instantiate curve
            if (marketEnvironment.GetType() == typeof(SimpleMarketEnvironment))
            {
                curve     = (IRateCurve)((ISimpleMarketEnvironment)marketEnvironment).GetPricingStructure();
                CurveName = curve.GetPricingStructureId().UniqueIdentifier;
            }
            if (marketEnvironment.GetType() == typeof(SimpleRateMarketEnvironment))
            {
                curve     = ((ISimpleRateMarketEnvironment)marketEnvironment).GetRateCurve();
                CurveName = curve.GetPricingStructureId().UniqueIdentifier;
            }
            if (marketEnvironment.GetType() == typeof(SwapLegEnvironment))
            {
                curve     = ((ISwapLegEnvironment)marketEnvironment).GetDiscountRateCurve();
                CurveName = curve.GetPricingStructureId().UniqueIdentifier;
            }
            if (marketEnvironment.GetType() == typeof(MarketEnvironment))
            {
                curve = (IRateCurve)modelData.MarketEnvironment.GetPricingStructure(CurveName);
            }
            //2. get start df = curve.getvalue(this._adjustedStartDate);
            analyticModelParameters.StartDiscountFactor =
                GetDiscountFactor(curve, AdjustedStartDate, modelData.ValuationDate);
            //3. Get the Rate
            analyticModelParameters.Rate = MarketQuoteHelper.NormalisePriceUnits(FixedRate, "DecimalRate").value;
            if (bEvalDiscountFactorAtMaturity)
            {
                //4. Set the anaytic input parameters and Calculate the respective metrics
                AnalyticResults =
                    AnalyticsModel.Calculate <IRateAssetResults, RateAssetResults>(analyticModelParameters,
                                                                                   metricsToEvaluate);
                EndDiscountFactor = DiscountFactorAtMaturity;
            }
            else
            {
                analyticModelParameters.NotionalAmount = Notional;
                //3. Get the end index discount factor
                analyticModelParameters.EndDiscountFactor =
                    GetDiscountFactor(curve, GetRiskMaturityDate(), modelData.ValuationDate);
                //4. Get the payment discount factor
                analyticModelParameters.PaymentDiscountFactor =
                    GetDiscountFactor(curve, GetRiskMaturityDate(), modelData.ValuationDate);
                //5. Set the anaytic input parameters and Calculate the respective metrics
                AnalyticResults =
                    AnalyticsModel.Calculate <IRateAssetResults, RateAssetResults>(analyticModelParameters,
                                                                                   metricsToEvaluate);
            }
            return(GetValue(AnalyticResults));
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="PriceableSimpleOptionAsset"/> class.
        /// </summary>
        /// <param name="cache">The cache.</param>
        /// <param name="logger">The logger.</param>
        /// <param name="nameSpace">The client namespace</param>
        /// <param name="baseDate">The base date.</param>
        /// <param name="expiryTenor">The expiry tenor.</param>
        /// <param name="underlyingAssetIdentifier">The underlying asset.</param>
        /// <param name="strike">The strike.</param>
        /// <param name="volatility">The volatility.</param>
        /// <param name="forecastCurve">The forecast rate curve.</param>
        /// <param name="discountCurve">The discount rate curve. Not used yet, as only the implied rate is caclulated.</param>
        /// <param name="fixingCalendar">The fixingCalendar.</param>
        /// <param name="rollCalendar">The rollCalendar.</param>
        public PriceableSimpleOptionAsset(ILogger logger, ICoreCache cache, string nameSpace, String underlyingAssetIdentifier, DateTime baseDate,
                                          Period expiryTenor, Decimal?strike, Decimal volatility, IRateCurve discountCurve, ICurve forecastCurve, IBusinessCalendar fixingCalendar, IBusinessCalendar rollCalendar)
        {
            UnderlyingAssetRef = underlyingAssetIdentifier;
            var expiryOffset = new Offset
            {
                period           = expiryTenor.period,
                periodMultiplier = expiryTenor.periodMultiplier,
                periodSpecified  = true,
                dayType          = DayTypeEnum.Calendar,
                dayTypeSpecified = true
            };
            var expiryDate      = expiryOffset.Add(baseDate);
            var assetProperties = PriceableAssetFactory.BuildPropertiesForAssets(nameSpace, underlyingAssetIdentifier, expiryDate);
            var instrument      = InstrumentDataHelper.GetInstrumentConfigurationData(cache, nameSpace, underlyingAssetIdentifier);
            var quotation       = BasicQuotationHelper.CreateRate(0.05m);
            var quote           = BasicAssetValuationHelper.Create(quotation);

            UnderlyingPriceableAsset = PriceableAssetFactory.Create(logger, cache, nameSpace, instrument, quote, assetProperties, fixingCalendar, rollCalendar);
            BaseDate     = baseDate;
            ForwardIndex = UnderlyingPriceableAsset.CalculateImpliedQuote(forecastCurve);
            if (strike != null)
            {
                Strike = (Decimal)strike;
            }
            else
            {
                Strike = ForwardIndex;
            }
            DayCounter   = new Actual365();
            ExpiryDate   = expiryDate;
            Volatility   = volatility;
            TimeToExpiry = DayCounter.DayCount(BaseDate, ExpiryDate);
        }
Exemple #20
0
 /// <summary>
 /// Initiates a new model.
 /// </summary>
 /// <param name="valuationDate">The valuation date.</param>
 /// <param name="paymentDate">The payment date of the cash flow.</param>
 /// <param name="reportingCurrencyFxCurve">THe fx curve. It must already be normalised.</param>
 /// <param name="indexCurve">The rate curve to use for calculating the forward index.</param>
 /// <param name="discountCurve">The rate curve to use for discounting.</param>
 public FxRateCashflowAnalytic(DateTime valuationDate, DateTime paymentDate,
                               IFxCurve reportingCurrencyFxCurve, ICurve indexCurve, IRateCurve discountCurve)
 {
     ToReportingCurrencyRate = EvaluateReportingCurrencyFxRate(valuationDate, reportingCurrencyFxCurve);
     if (indexCurve != null)
     {
         FloatingIndex = (decimal)indexCurve.GetValue(new DateTimePoint1D(valuationDate, paymentDate)).Value;
     }
     if (discountCurve != null)
     {
         PaymentDiscountFactor = (decimal)discountCurve.GetDiscountFactor(valuationDate, paymentDate);
     }
 }
 /// <summary>
 /// Initiates a new model.
 /// </summary>
 /// <param name="valuationDate">The valuation date.</param>
 /// <param name="startDate">The start date of the coupon.</param>
 /// <param name="endDate">The end date of the coupon.</param>
 /// <param name="paymentDate">The payment date of the cash flow.</param>
 /// <param name="timeToIndex">The timeToIndex. Not necessarily the time to expiry. This is used for surface interpolation..</param>
 /// <param name="strike">The strike.</param>
 /// <param name="reportingCurrencyFxCurve">THe fx curve. It must already be normalised.</param>
 /// <param name="discountCurve">The rate curve to use for discounting.</param>
 /// <param name="forecastCurve">The forecast curve.</param>
 /// <param name="indexVolSurface">The index volatility surface.</param>
 public RateOptionCouponAnalytic(DateTime valuationDate, DateTime startDate, DateTime endDate, DateTime paymentDate,
                                 decimal timeToIndex, decimal strike, IFxCurve reportingCurrencyFxCurve, IRateCurve discountCurve, IRateCurve forecastCurve, IVolatilitySurface indexVolSurface)
     : base(valuationDate, startDate, endDate, paymentDate, reportingCurrencyFxCurve, discountCurve, forecastCurve)
 {
     Strike      = strike;
     TimeToIndex = timeToIndex;
     Volatility  = (decimal)indexVolSurface.GetValue((double)timeToIndex, (double)strike);
 }
Exemple #22
0
        /// <summary>
        /// This assumes that the rest dates are consistent with the curve.
        /// </summary>
        /// <param name="valuationDate"></param>
        /// <param name="paymentDate">The payment date. The same rest period is assumed as with the spot date.</param>
        /// <param name="indexCurve">The index curve should be already in the correct form for the fx.</param>
        /// <param name="currency2">Normally the foreign rate curve.</param>
        /// <param name="currency2PerCurrency1">The currency2PerCurrency1 flag. </param>
        /// <param name="currency1">Normally the domestic rate curve. </param>
        /// <param name="currency1Settlement">Does settlement occur in currency1. If not, then it must be currency2. </param>
        /// <param name="reportingCurrencyFxCurve">The reporting current fx curve from settlement currency to reporting currency. It must already be normalised.</param>
        public FxRateCashflowAnalytic(DateTime valuationDate, DateTime paymentDate, IFxCurve indexCurve, IRateCurve currency1, IRateCurve currency2,
                                      bool currency2PerCurrency1, bool currency1Settlement, IFxCurve reportingCurrencyFxCurve)
        {
            ToReportingCurrencyRate = EvaluateReportingCurrencyFxRate(valuationDate, reportingCurrencyFxCurve);
            var todayRate = indexCurve.GetForward(valuationDate, valuationDate); //TODO The spot rate may not be the same due to the carry effect, but the evolution works.
            var df1       = currency1.GetDiscountFactor(valuationDate, paymentDate);
            var df2       = currency2.GetDiscountFactor(valuationDate, paymentDate);
            var forward   = df1 / df2;

            if (!currency2PerCurrency1)
            {
                forward = df2 / df1;
            }
            FloatingIndex = (decimal)(todayRate * forward);
            if (currency1Settlement)
            {
                PaymentDiscountFactor = (decimal)currency1.GetDiscountFactor(valuationDate, paymentDate);
            }
            else
            {
                PaymentDiscountFactor = (decimal)currency2.GetDiscountFactor(valuationDate, paymentDate);
            }
        }
 /// <summary>
 /// Gets the discount factors.
 /// </summary>
 /// <param name="discountFactorCurve">The discount factor curve.</param>
 /// <param name="periodDates">The period dates.</param>
 /// <param name="valuationDate">The valuation date.</param>
 /// <returns></returns>
 public Decimal[] GetDiscountFactors(IRateCurve discountFactorCurve, IList <DateTime> periodDates,
                                     DateTime valuationDate)
 {
     return(periodDates.Select(periodDate => GetDiscountFactor(periodDate, valuationDate, discountFactorCurve)).ToArray());
 }
        /// <summary>
        /// This routine finds the average of the index and the volatility between PaymentStart and PaymentEnd.
        /// AveFrequency determines the daily averaging frequency
        /// e.g.AveFrequency =  1 finds average of daily values;
        /// AveFrequency =  7 finds average of weekly values etc.
        /// PaymentEnd is not included in the averaging calculation.
        /// It is assumed that PaymentStart and PaymentEnd have already been adjusted to be business days
        /// Each AverageDate is calculated by adding on the correct number of business days
        /// PaymentRateSet is the sum of the rates that have already been fixed in the period.
        /// This is added onto the sum of the forward rates and the average calculated by dividing
        /// the total sum by the number of averaging points in the period
        /// Holidays:	Index Start is appropriate working day for the Average Date
        ///             Index Set is two working days prior to this Index Start
        ///             Index End is the appropriate working day following addition of the tenor
        /// </summary>
        /// <param name="valueDate"></param>
        /// <param name="discountCurve"></param>
        /// <param name="indexCurve"></param>
        /// <param name="paymentStart"></param>
        /// <param name="paymentEnd"></param>
        /// <param name="indexDaycount"></param>
        /// <param name="indexTenor"></param>
        /// <param name="indexCoupon"></param>
        /// <param name="paymentRateSet"></param>
        /// <param name="indexRateSet"></param>
        /// <param name="averagingFrequency"></param>
        /// <param name="averagePreset"></param>
        /// <param name="indexCity"></param>
        /// <param name="convention"></param>
        /// <param name="volatilityMargin"></param>
        /// <param name="indexVolatility"></param>
        /// <returns></returns>
        public static Double? GetAverageRate(DateTime valueDate, IRateCurve discountCurve,
            IRateCurve indexCurve, DateTime paymentStart, DateTime paymentEnd, int indexDaycount, int indexTenor, int indexCoupon,
            double paymentRateSet, double indexRateSet, int averagingFrequency,
            int averagePreset, long indexCity, int convention, double volatilityMargin,
            IVolatilitySurface indexVolatility)
        {
            long indexSet, indexStart, indexEnd;
            double sumRate = 0.0;
            double sumVol = 0.0;
            double firstVol = 0.0;
            var averageDate = paymentStart;
            int numAvePoints = 0;
            if (indexCurve is null)
                return null;
            //Do simple approximation i.e. divide the sum of the start and end values by two 
            if (averagingFrequency <= 0)
            {

                DateTime Ave_Index_Start, Ave_Index_End;
                //Calculate the fixing date for the start date of the period
                long firstSet = AddWorkDays(PaymentStart, Ave_Preset, Index_City, CHoliday::PRECEEDING);
                //Calculate the fixing date for the end date of the period
                long lastSet = AddWorkDays(PaymentEnd, Ave_Preset, Index_City, CHoliday::PRECEEDING);
                if (valueDate >= lastSet)
                {
                    IndexVolatility = 0.0;
                    return Payment_Rateset / 2.0; //Both the start and the end rates have been fixed
                }

                double firstRate;
                if (valueDate < firstSet)
                {
                    Index_Start = PaymentStart;
                    Date Ave_Index_Start = Index_Start;
                    Date Ave_Index_End = Ave_Index_Start.AddMonths(ConvertToMonths(Index_Tenor));
                    Index_End = GoodDay(Ave_Index_End.GetJulian(), Index_City, Convention);
                    long Index_Tenor_Days = (long) (Index_End - Index_Start);
                    long IndexExpiry = (long) (firstSet - Value_Date);

                    firstRate = _GetIndex(Value_Date, firstSet, Index_Start, Index_End, Index_Tenor,
                        Index_Daycount, Index_Coupon, Index_Coupon, *pIndexCurve, Index_Rateset);
                    // SAJ 25/9/96  Added Volatility margin to volatility to allow for bumping
                    firstVol = GetVolatility(CapsVolName, SwaptVolName, IndexExpiry, Index_Tenor_Days, 0.0) +
                               VolatilityMargin;
                    // SAJ 25/9/96	Added following lines for convexity effect
                    double Weight, AdjForward;
                    GetModifiedForward(Value_Date, PaymentEnd, firstSet, Index_Start, Index_End,
                        Index_Tenor, Index_Coupon, Index_Daycount,
                        *pIndexCurve, firstRate, firstVol, Weight, AdjForward);
                    firstRate = Weight * firstRate + (1 - Weight) * AdjForward;
                    // SAJ 25/9/96 End
                }
                else
                {
                    firstRate = Payment_Rateset;
                    firstVol = 0.0;
                }

                Index_Start = PaymentEnd;
                Ave_Index_Start = Index_Start;
                Ave_Index_End = Ave_Index_Start.AddMonths(ConvertToMonths(Index_Tenor));
                Index_End = GoodDay(Ave_Index_End.GetJulian(), Index_City, Convention);
                long Index_Tenor_Days = (long) (Index_End - Index_Start);
                long IndexExpiry = (long) (lastSet - Value_Date);
                double lastRate = _GetIndex(Value_Date, lastSet, Index_Start, Index_End, Index_Tenor,
                    Index_Daycount, Index_Coupon, Index_Coupon, *pIndexCurve, Index_Rateset);
                // SAJ 25/9/96  Added Volatility margin to volatility to allow for bumping
                double LastVol = GetVolatility(CapsVolName, SwaptVolName, IndexExpiry, Index_Tenor_Days, 0.0) +
                                 VolatilityMargin;
                // SAJ 25/9/96	Added following lines for convexity effect
                double Weight, AdjForward;
                GetModifiedForward(Value_Date, PaymentEnd, lastSet, Index_Start, Index_End,
                    Index_Tenor, Index_Coupon, Index_Daycount,
                    *pIndexCurve, lastRate, LastVol, Weight, AdjForward);
                lastRate = Weight * lastRate + (1 - Weight) * AdjForward;
                // SAJ 25/9/96 End
                IndexVolatility = (firstVol + LastVol) / 2.0 + VolatilityMargin;
                return (firstRate + lastRate) / 2.0;
            }

            //Check if already into the averaging loop or the period is historical
            if (valueDate > PaymentStart)
            {
                sumRate = Payment_Rateset;
                sumVol = 0.0;
            }

            //Begin the averaging loop
            while (averageDate < PaymentEnd)
            {
                //Calculate the index setting date
                Index_Set = AddWorkDays(AverageDate, Ave_Preset, Index_City, CHoliday::PRECEEDING);
                if (Value_Date < Index_Set)
                {
                    Date Ave_Index_Start = AverageDate;
                    Date Ave_Index_End = Ave_Index_Start.AddMonths(ConvertToMonths(Index_Tenor));
                    Index_End = GoodDay(Ave_Index_End.GetJulian(), Index_City, Convention);
                    long Index_Tenor_Days = (long) (Index_End - AverageDate);
                    long IndexExpiry = (long) (Index_Set - Value_Date);
                    double NewRate = _GetIndex(Value_Date, Index_Set, AverageDate, Index_End, Index_Tenor,
                        Index_Daycount, Index_Coupon, Index_Coupon, *pIndexCurve, Index_Rateset);

                    // SAJ 25/9/96  Added Volatility margin to volatility to allow for bumping
                    double newVol = GetVolatility(CapsVolName, SwaptVolName, IndexExpiry, Index_Tenor_Days, 0.0) +
                                    VolatilityMargin;

                    // SAJ 25/9/96	Added following lines for convexity effect
                    double weight, adjForward;
                    GetModifiedForward(Value_Date, PaymentEnd, Index_Set, AverageDate, Index_End,
                        Index_Tenor, Index_Coupon, Index_Daycount,
                        *pIndexCurve, NewRate, newVol, weight, adjForward);
                    NewRate = weight * NewRate + (1 - weight) * adjForward;
                    // SAJ 25/9/96 End
                    sumRate += NewRate;
                    sumVol += (newVol * newVol);
                }

                numAvePoints++;
                // Increment average date by the averaging frequency
                // Here should make the convention Following otherwise will not get out of the end of the month
                // SAJ 25/9/96 Changed the following line to add AveFrequency days and then check good days
                //	    AverageDate = AddWorkDays(AverageDate, AveFrequency, Index_City, CHoliday::FOLLOWING);
                averageDate += AveFrequency;
                averageDate =
                    GoodDay(AverageDate, Index_City, CHoliday::FOLLOWING); // Use following to prevent chattering
                // SAJ 25/9/96 End
            }

            IndexVolatility = Math.Sqrt(sumVol / numAvePoints) + volatilityMargin;
            return sumRate / numAvePoints;
        }
Exemple #25
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="cache"></param>
        /// <param name="nameSpace"></param>
        /// <param name="valueDate"></param>
        /// <param name="effectiveDate"></param>
        /// <param name="terminationDate"></param>
        /// <param name="interpolationMethod"></param>
        /// <param name="margineAboveFloatingRate"></param>
        /// <param name="resetRate"></param>
        /// <param name="notional"></param>
        /// <param name="directionDateGenerationPayLeg"></param>
        /// <param name="cashFlowFrequencyPayLeg"></param>
        /// <param name="accrualMethodPayLeg"></param>
        /// <param name="holidaysPayLeg"></param>
        /// <param name="rateCurvePayLeg"></param>
        /// <param name="directionDateGenerationRecLeg"></param>
        /// <param name="cashFlowFrequencyRecLeg"></param>
        /// <param name="accrualMethodRecLeg"></param>
        /// <param name="holidaysRecLeg"></param>
        /// <param name="rateCurveRecLeg"></param>
        /// <param name="layout">
        /// if 0 - cashflows displayed one under another,
        /// if 1 - cashflows displayed side by side.
        /// </param>
        /// <returns>
        ///  Pay cashflows:
        ///
        ///
        ///
        ///  Rec cashflows:
        ///
        ///
        /// </returns>
        public object[,] GetSwapCashflowsWithoutCurves
        (
            ILogger logger,
            ICoreCache cache,
            String nameSpace,
            DateTime valueDate,
            DateTime effectiveDate,
            DateTime terminationDate,
            string interpolationMethod,      //1 is linear on forward rates => make sure that the right curve is provided ...
            double margineAboveFloatingRate, // use 0 initially
            double resetRate,
            decimal notional,
            int directionDateGenerationPayLeg,
            string cashFlowFrequencyPayLeg,
            string accrualMethodPayLeg,
            string holidaysPayLeg,
            IRateCurve rateCurvePayLeg,
            int directionDateGenerationRecLeg,
            string cashFlowFrequencyRecLeg,
            string accrualMethodRecLeg,
            string holidaysRecLeg,
            IRateCurve rateCurveRecLeg,
            int layout
        )
        {
            //  received fixed leg
            //
            var recFixedCashflows = InterestRateSwapPricer.GenerateCashflows(logger, cache, nameSpace, null, valueDate, effectiveDate, terminationDate,
                                                                             interpolationMethod, margineAboveFloatingRate, resetRate,
                                                                             notional,
                                                                             directionDateGenerationRecLeg,
                                                                             cashFlowFrequencyRecLeg,
                                                                             accrualMethodRecLeg,
                                                                             holidaysRecLeg,
                                                                             rateCurvePayLeg,
                                                                             true);
            //  pay floating leg
            //
            var payFloatingCashflows = InterestRateSwapPricer.GenerateCashflows(logger, cache, nameSpace, null, valueDate, effectiveDate, terminationDate,
                                                                                interpolationMethod, margineAboveFloatingRate, resetRate,
                                                                                notional,
                                                                                directionDateGenerationPayLeg,
                                                                                cashFlowFrequencyPayLeg,
                                                                                accrualMethodPayLeg,
                                                                                holidaysPayLeg,
                                                                                rateCurveRecLeg,
                                                                                false);
            var objectiveFunction = new InterestRateSwapPricer
            {
                ReceiveLeg = recFixedCashflows,
                PayLeg     = payFloatingCashflows
            };
            var solver = new Brent
            {
                LowerBound = -100.0,
                UpperBound = 100.0
            };

            solver.Solve(objectiveFunction, Accuracy, Guess, Step);
            //            bool bothLegsHaveTheSameStructure =
            //                directionDateGenerationPayLeg == directionDateGenerationRecLeg &&
            //                cashFlowFrequencyPayLeg == cashFlowFrequencyRecLeg &&
            //                holidaysPayLeg == holidaysRecLeg;

            // if 0 - cashflows displayed one under another,
            // if 1 - cashflows displayed side by side.

            var result = 1 == layout?Utilities.GetCashflowsSideBySideExcelRange(payFloatingCashflows.Coupons, recFixedCashflows.Coupons) : Utilities.GetCashflowsOneUnderAnotherExcelRange(payFloatingCashflows.Coupons, recFixedCashflows.Coupons);

            return(result);
        }
Exemple #26
0
        /// <summary>
        /// Initiates a new model.
        /// </summary>
        /// <param name="valuationDate">The valuation date.</param>
        /// <param name="paymentDate">The payment date of the cash flow.</param>
        /// <param name="reportingCurrencyFxCurve">The fx curve. It must already be normalised.</param>
        /// <param name="discountCurve">The rate curve to use for discounting.</param>
        public CashflowAnalytic(DateTime valuationDate, DateTime paymentDate, IFxCurve reportingCurrencyFxCurve, IRateCurve discountCurve)
        {
            ToReportingCurrencyRate = EvaluateReportingCurrencyFxRate(valuationDate, reportingCurrencyFxCurve);
            PaymentDiscountFactor   = EvaluateDiscountFactor(valuationDate, paymentDate, discountCurve);
            var paymentDiscountFactor = PaymentDiscountFactor;
            var days = (paymentDate - valuationDate).Days;

            if (days == 0)
            {
                days = 1;
                paymentDiscountFactor = EvaluateDiscountFactor(valuationDate, paymentDate.AddDays(1), discountCurve);
            }
            var time = days / 365.25;

            ContinuousRate = -(Decimal)(Math.Log((double)paymentDiscountFactor) / time);
        }
Exemple #27
0
        internal static double GetAdjustedDiscountFactor(DateTime baseDate, DateTime baseCurveDate,
                                                         IDayCounter dayCounter, double zeroRateSpread, IRateCurve baseCurve)
        {
            const double compoundingPeriod = 0.25;
            // Convert to Zero Rate
            double yearFraction = dayCounter.YearFraction(baseDate, baseCurveDate);
            double df0          = baseCurve.GetDiscountFactor(baseCurveDate);
            double z0           = RateAnalytics.DiscountFactorToZeroRate(df0, yearFraction, compoundingPeriod);
            // Add the spread
            double z = z0 + zeroRateSpread;
            // Change back
            double discountFactor = RateAnalytics.ZeroRateToDiscountFactor(z, yearFraction, compoundingPeriod);

            return(discountFactor);
        }
Exemple #28
0
        /// <summary>
        /// Evaluating the discount factor rate.
        /// </summary>
        /// <returns>The discount factor</returns>
        protected decimal EvaluateDiscountFactor(DateTime valuationDate, DateTime date, IRateCurve discountCurve)
        {
            var result = 1.0m;

            if (discountCurve != null)
            {
                result = (decimal)discountCurve.GetDiscountFactor(valuationDate, date);
            }
            return(result);
        }
Exemple #29
0
 /// <summary>
 /// This assumes that the rest dates are consistent with the curve.
 /// </summary>
 /// <param name="valuationDate">The valuation date.</param>
 /// <param name="paymentDate">The payment date. The same rest period is assumed as with the spot date.</param>
 /// <param name="indexCurve">The index curve should be already in the correct form for the fx.</param>
 /// <param name="currency2">Normaly the foreign rate curve.</param>
 /// <param name="currency2PerCurrency1">The currency2PerCurrency1 flag. </param>
 /// <param name="currency1">Normally the domestic rate curve. </param>
 /// <param name="expiryTime">The expiry time. </param>
 /// <param name="timeToIndex">The time to reset or expiry. </param>
 /// <param name="indexVolSurface">The index volatility surface.</param>
 /// <param name="currency1Settlement">Is the currency1 the settlement currency? </param>
 /// <param name="strike">The strike. </param>
 /// <param name="reportingCurrencyFxCurve">The reporting current fx curve from settlement currency to reporting currency. It must already be normalised.</param>
 /// <param name="fxOptionType">The option type. </param>
 public FxOptionAnalytic(DateTime valuationDate, DateTime paymentDate, IFxCurve indexCurve, IRateCurve currency1, IRateCurve currency2,
                         bool currency2PerCurrency1, bool currency1Settlement, decimal strike, decimal expiryTime, decimal timeToIndex,
                         IVolatilitySurface indexVolSurface, FxOptionType fxOptionType, IFxCurve reportingCurrencyFxCurve)
     : base(valuationDate, paymentDate, indexCurve, currency1, currency2, currency2PerCurrency1, currency1Settlement, reportingCurrencyFxCurve)
 {
     OptionType = fxOptionType;
     Strikes    = new List <decimal> {
         strike
     };
     ExpiryTimes = new List <decimal> {
         expiryTime
     };
     TimeToIndices = new List <decimal> {
         timeToIndex
     };
     Volatilities = new List <decimal> {
         (decimal)indexVolSurface.GetValue((double)timeToIndex, (double)strike)
     };
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="referenceCurve"></param>
 /// <param name="isBaseCurve"></param>
 /// <param name="derivedCurveProperties"></param>
 /// <returns></returns>
 public IRateCurve GenerateRateCurve(IRateCurve referenceCurve, bool isBaseCurve, NamedValueSet derivedCurveProperties)
 {
     throw new NotImplementedException();
 }