internal override global::QuantLib.DefaultProbabilityTermStructure Build()
        {
            var termStructureDayCounter = DayCountBasis.ToQlDayCounter();
            var quoteHandle             = new QlQuoteHandle(new QlQuote(FlatHazardRate));

            return(new FlatHazardRate(TradeDate, quoteHandle, termStructureDayCounter));
        }
예제 #2
0
 public Coupbase(FinancialDay settlement, FinancialDay maturity, int frequency, DayCountBasis basis)
 {
     Settlement = settlement;
     Maturity   = maturity;
     Frequency  = frequency;
     Basis      = basis;
 }
        public HazzardCurve Solve(List <CDS> instruments, double recoveryRate, IIrCurve discountCurve, DateTime buildDate, DayCountBasis basis = DayCountBasis.ACT365F)
        {
            _curveInstruments    = instruments;
            _pillars             = instruments.OrderBy(x => x.FinalSensitivityDate).Select(c => c.FinalSensitivityDate).ToArray();
            _pillarsT            = _pillars.Select(p => buildDate.CalculateYearFraction(p, basis)).ToArray();
            _numberOfInstruments = _curveInstruments.Count;
            _numberOfPillars     = _pillars.Length;
            _discountCurve       = discountCurve;
            _buildDate           = buildDate;
            _basis        = basis;
            _recoveryRate = recoveryRate;

            _currentGuess = instruments.OrderBy(x => x.FinalSensitivityDate).Select((x, ix) => x.Spread / (1.0 - recoveryRate)).ToArray();
            _currentCurve = new LinearHazzardInterpolator(_pillarsT, _currentGuess);
            _currentPVs   = ComputePVs();

            ComputeJacobian();

            for (var i = 0; i < MaxItterations; i++)
            {
                ComputeNextGuess();
                _currentCurve = new LinearHazzardInterpolator(_pillarsT, _currentGuess);

                _currentPVs = ComputePVs();
                if (_currentPVs.Max(x => System.Math.Abs(x)) < Tollerance)
                {
                    UsedItterations = i + 1;
                    break;
                }
                ComputeJacobian();
            }

            return(new HazzardCurve(_buildDate, _basis, _currentCurve));
        }
예제 #4
0
        public SabrVolSurface(DateTime originDate, double[][] strikes, DateTime[] expiries, double[][] vols, Func <double, double> forwardCurve,
                              Interpolator1DType timeInterpType, DayCountBasis timeBasis)
        {
            TimeInterpolatorType = timeInterpType;
            TimeBasis            = timeBasis;

            Build(originDate, strikes, expiries, vols, forwardCurve);
        }
예제 #5
0
 public Coupon(DateTime startDate, DateTime endDate, DayCountBasis dayCount = DayCountBasis.ActualActual)
 {
     StartDate = startDate;
     EndDate   = endDate;
     NbDays    = (EndDate - StartDate).Days;
     DayCount  = dayCount;
     NbYears   = DateUtils.YearFrac(StartDate, EndDate);
 }
예제 #6
0
 public GenericSwapLeg(DateTime startDate, Frequency tenor, Calendar calendars, Currency currency, Frequency resetFrequency, DayCountBasis dayBasis)
 {
     EffectiveDate   = startDate;
     TerminationDate = new TenorDateRelative(tenor);
     ResetFrequency  = resetFrequency;
     Currency        = currency;
     SetAllCalendars(calendars);
     AccrualDCB = dayBasis;
 }
예제 #7
0
 internal QlCds Build()
 {
     if (Schedule == null)
     {
         Schedule = BuildSchedule();
     }
     return(new QlCds(Protection.ToQlSide(), Notional, UpfrontRate, Convert.ToDouble(CouponRate.RealValue), Schedule.QlObj,
                      global::QuantLib.BusinessDayConvention.Following, DayCountBasis.ToQlDayCounter()));
 }
예제 #8
0
        public double GetYearFrac(System.DateTime date1, System.DateTime date2, DayCountBasis basis)
        {
            var func = new Yearfrac();
            var args = new List <FunctionArgument> {
                new FunctionArgument(date1.ToOADate()), new FunctionArgument(date2.ToOADate()), new FunctionArgument((int)basis)
            };
            var result = func.Execute(args, _context);

            return(result.ResultNumeric);
        }
예제 #9
0
        public GridVolSurface(DateTime originDate, double[] strikes, DateTime[] expiries, double[][] vols,
                              StrikeType strikeType, Interpolator1DType strikeInterpType, Interpolator1DType timeInterpType,
                              DayCountBasis timeBasis)
        {
            StrikeType             = strikeType;
            StrikeInterpolatorType = strikeInterpType;
            TimeInterpolatorType   = timeInterpType;
            TimeBasis = timeBasis;

            Build(originDate, strikes, expiries, vols);
        }
예제 #10
0
        public ContangoPriceCurve(DateTime buildDate, double spot, DateTime spotDate, DateTime[] pillarDates, double[] contangos, ICurrencyProvider currencyProvider,
                                  DayCountBasis basis = DayCountBasis.ACT360, string[] pillarLabels = null)
        {
            _currencyProvider = currencyProvider;
            Currency          = currencyProvider["USD"];
            BuildDate         = buildDate;
            PillarDates       = pillarDates;
            Contangos         = contangos;
            Basis             = basis;
            Spot     = spot;
            SpotDate = spotDate;

            PillarLabels = pillarLabels ?? PillarDates.Select(x => x.ToString("yyyy-MM-dd")).ToArray();

            Initialize();
        }
예제 #11
0
        public FixedRateLoanDeposit(DateTime startDate, DateTime endDate, double interestRate, Currency currency, DayCountBasis basis, double notional, string discountCurve) : base()
        {
            StartDate     = startDate;
            EndDate       = endDate;
            InterestRate  = interestRate;
            Basis         = basis;
            Notional      = notional;
            DiscountCurve = discountCurve;
            Currency      = currency;

            LoanDepoSchedule = new CashFlowSchedule {
                Flows = new List <CashFlow>()
            };
            LoanDepoSchedule.Flows.Add(new CashFlow
            {
                Notional   = Notional,
                Currency   = Currency,
                FlowType   = FlowType.FixedAmount,
                SettleDate = StartDate,
            });
            LoanDepoSchedule.Flows.Add(new CashFlow
            {
                Notional   = -Notional,
                Currency   = Currency,
                FlowType   = FlowType.FixedAmount,
                SettleDate = EndDate,
            });
            var dcf = StartDate.CalculateYearFraction(EndDate, Basis);

            LoanDepoSchedule.Flows.Add(new CashFlow
            {
                Notional           = -Notional,
                Currency           = Currency,
                FlowType           = FlowType.FixedRate,
                SettleDate         = EndDate,
                AccrualPeriodStart = StartDate,
                AccrualPeriodEnd   = EndDate,
                FixedRateOrMargin  = InterestRate,
                YearFraction       = dcf,
                Fv = -Notional * dcf * interestRate
            });

            PillarDate = endDate;
            SolveCurve = DiscountCurve;
        }
예제 #12
0
        public GridVolSurface(DateTime originDate, double[] strikes, DateTime[] expiries, double[][] vols,
                              StrikeType strikeType, Interpolator1DType strikeInterpType, Interpolator1DType timeInterpType,
                              DayCountBasis timeBasis, string[] pillarLabels = null) : base()
        {
            StrikeType             = strikeType;
            StrikeInterpolatorType = strikeInterpType;
            TimeInterpolatorType   = timeInterpType;
            TimeBasis = timeBasis;

            if (pillarLabels == null)
            {
                PillarLabels = expiries.Select(x => x.ToString("yyyy-MM-dd")).ToArray();
            }
            else
            {
                PillarLabels = pillarLabels;
            }

            Build(originDate, strikes, expiries, vols);
        }
예제 #13
0
        public static double YearFrac(DateTime startDate, DateTime?endDate, DayCountBasis dayCountBasis = DayCountBasis.UsPsa30_360)
        {
            if (endDate == null)
            {
                return(0);
            }

            if (startDate == endDate)
            {
                return(0);
            }
            if (startDate < endDate)
            {
                return(Financial.YearFrac(startDate, endDate.Value, dayCountBasis));
            }
            else
            {
                return(Financial.YearFrac(endDate.Value, startDate, dayCountBasis));
            }
        }
예제 #14
0
        internal static FinancialDay Create(System.DateTime date, DayCountBasis basis)
        {
            switch (basis)
            {
            case DayCountBasis.US_30_360:
                return(new FinancialDay_Us_30_360(date));

            case DayCountBasis.Actual_Actual:
                return(new FinancialDay_Actual_Actual(date));

            case DayCountBasis.Actual_360:
                return(new FinancialDay_Actual_360(date));

            case DayCountBasis.Actual_365:
                return(new FinancialDay_Actual_365(date));

            case DayCountBasis.European_30_360:
                return(new FinancialDay_European_30_360(date));

            default:
                throw new ArgumentException("basis");
            }
        }
예제 #15
0
        internal static IFinanicalDays Create(DayCountBasis basis)
        {
            switch (basis)
            {
            case DayCountBasis.US_30_360:
                return(new FinancialDaysUs_30_360());

            case DayCountBasis.Actual_Actual:
                return(new FinancialDays_Actual_Actual());

            case DayCountBasis.Actual_360:
                return(new FinancialDays_Actual_360());

            case DayCountBasis.Actual_365:
                return(new FinancialDays_Actual_365());

            case DayCountBasis.European_30_360:
                return(new FinancialDaysEuropean_30_360());

            default:
                throw new ArgumentException("basis");
            }
        }
예제 #16
0
        /// <summary>
        /// Adds a year fraction to a date to return an end date
        /// </summary>
        /// <param name="startDate">Start Date</param>
        /// <param name="yearFraction">Year fraction in format consistent with basis parameter</param>
        /// <param name="basis">DayCountBasis enum</param>
        /// <returns></returns>
        public static DateTime AddYearFraction(this DateTime startDate, double yearFraction, DayCountBasis basis, bool ignoreTimeComponent = true)
        {
            var o = new DateTime();

            switch (basis)
            {
            case DayCountBasis.Act_360:
                o = new DateTime((long)(startDate.Ticks + yearFraction / _ticksFraction360));
                break;

            case DayCountBasis.Act_365F:
                o = new DateTime((long)(startDate.Ticks + yearFraction / _ticksFraction365));
                break;
            }

            if (ignoreTimeComponent)
            {
                o = o.Date;
            }

            return(o);
        }
예제 #17
0
        /// <summary>
        /// Calculates a year fraction from a day count method and two dates
        /// Start date is inclusive, end date exclusive
        /// </summary>
        /// <param name="startDate">Start Date (inclusive)</param>
        /// <param name="endDate">End Date (exclusive)</param>
        /// <param name="basis">DayCountBasis enum</param>
        /// <param name="ignoreTimeComponent">Ignore the time component of the DateTime inputs - defaults to true</param>
        /// <param name="calendar">Optional calendar object, required only for methods involving business days</param>
        /// <returns></returns>
        public static double CalculateYearFraction(this DateTime startDate, DateTime endDate, DayCountBasis basis, bool ignoreTimeComponent = true, Calendar calendar = null)
        {
            if (ignoreTimeComponent)
            {
                startDate = startDate.Date;
                endDate   = endDate.Date;
            }

            switch (basis)
            {
            case DayCountBasis.Act_360:
                return((endDate.Ticks - startDate.Ticks) * _ticksFraction360);

            case DayCountBasis.Act_365F:
                return((endDate.Ticks - startDate.Ticks) * _ticksFraction365);

            case DayCountBasis.Act_Act_ISDA:
            case DayCountBasis.Act_Act:
                if (endDate.Year == startDate.Year)
                {       //simple case
                    var eoY = new DateTime(endDate.Year, 12, 31);
                    return((endDate - startDate).TotalDays / eoY.DayOfYear);
                }
                else
                {
                    double nIntermediateYears = endDate.Year - startDate.Year - 1;

                    var eoYe = new DateTime(endDate.Year, 12, 31);
                    var e    = endDate.DayOfYear / (double)eoYe.DayOfYear;

                    var eoYs = new DateTime(startDate.Year, 12, 31);
                    var s    = (eoYs - startDate).TotalDays / eoYs.DayOfYear;

                    return(s + nIntermediateYears + e);
                }

            case DayCountBasis._30_360:
                double ydiff = endDate.Year - startDate.Year;
                double mdiff = endDate.Month - startDate.Month;
                double ddiff = endDate.Day - startDate.Day;
                return((ydiff * 360 + mdiff * 30 + ddiff) / 360);

            case DayCountBasis.ThirtyE360:
                double d1E    = Math.Min(startDate.Day, 30);
                double d2E    = Math.Min(endDate.Day, 30);
                double ydiffE = endDate.Year - startDate.Year;
                double mdiffE = endDate.Month - startDate.Month;
                var    ddiffE = d2E - d1E;
                return((ydiffE * 360 + mdiffE * 30 + ddiffE) / 360);

            case DayCountBasis.Bus252:
                return(startDate.BusinessDaysInPeriod(endDate.AddDays(-1), calendar).Count / 252.0);

            case DayCountBasis.Unity:
                return(1.0);
            }
            return(-1);
        }
예제 #18
0
 /// <summary>
 /// Calculates a year fraction from a day count method and two dates
 /// Start date is inclusive, end date exclusive
 /// </summary>
 /// <param name="startDate">Start Date (inclusive)</param>
 /// <param name="endDate">End Date (exclusive)</param>
 /// <param name="basis">DayCountBasis enum</param>
 /// <returns></returns>
 public static double CalculateYearFraction(this DayCountBasis basis, DateTime startDate, DateTime endDate) => startDate.CalculateYearFraction(endDate, basis);
예제 #19
0
 public CoupncdImpl(FinancialDay settlement, FinancialDay maturity, int frequency, DayCountBasis basis) : base(settlement, maturity, frequency, basis)
 {
 }
예제 #20
0
 public IrCurve(TO_IrCurve transportObject, ICurrencyProvider currencyProvider)
     : this(transportObject.Pillars, transportObject.Rates, transportObject.BuildDate, transportObject.Name, transportObject.InterpKind,
            currencyProvider.GetCurrency(transportObject.Ccy), transportObject.CollateralSpec, transportObject.RateStorageType)
 {
     _basis = transportObject.Basis;
 }
예제 #21
0
        protected override FinanceCalcResult <double> ExecuteFunction(FinancialDay settlementDate, FinancialDay maturityDate, int frequency, DayCountBasis basis = DayCountBasis.US_30_360)
        {
            var impl = new CoupdaysImpl(settlementDate, maturityDate, frequency, basis);

            return(impl.GetCoupdays());
        }
        double GetDuration(System.DateTime settlement, System.DateTime maturity, double coupon, double yield, int nFreq, DayCountBasis nBase)
        {
            double       fYearfrac   = _yearFracProvider.GetYearFrac(settlement, maturity, nBase);
            double       fNumOfCoups = _couponProvider.GetCoupnum(settlement, maturity, nFreq, nBase);
            double       fDur        = 0.0;
            const double f100        = 100.0;

            coupon *= f100 / (double)nFreq;    // fCoup is used as cash flow
            yield  /= nFreq;
            yield  += 1.0;

            double nDiff = fYearfrac * nFreq - fNumOfCoups;

            double t;

            for (t = 1.0; t < fNumOfCoups; t++)
            {
                fDur += (t + nDiff) * coupon / System.Math.Pow(yield, t + nDiff);
            }

            fDur += (fNumOfCoups + nDiff) * (coupon + f100) / System.Math.Pow(yield, fNumOfCoups + nDiff);

            double p = 0.0;

            for (t = 1.0; t < fNumOfCoups; t++)
            {
                p += coupon / System.Math.Pow(yield, t + nDiff);
            }

            p += (coupon + f100) / System.Math.Pow(yield, fNumOfCoups + nDiff);

            fDur /= p;
            fDur /= (double)nFreq;

            return(fDur);
        }
예제 #23
0
        public static FinanceCalcResult <double> GetPrice(FinancialDay settlement, FinancialDay maturity, double rate, double yield, double redemption, int frequency, DayCountBasis basis = DayCountBasis.US_30_360)
        {
            var coupDaysResult = new CoupdaysImpl(settlement, maturity, frequency, basis).GetCoupdays();

            if (coupDaysResult.HasError)
            {
                return(coupDaysResult);
            }
            var coupdaysNcResult = new CoupdaysncImpl(settlement, maturity, frequency, basis).Coupdaysnc();

            if (coupdaysNcResult.HasError)
            {
                return(coupdaysNcResult);
            }
            var coupnumResult = new CoupnumImpl(settlement, maturity, frequency, basis).GetCoupnum();

            if (coupnumResult.HasError)
            {
                return(new FinanceCalcResult <double>(coupnumResult.ExcelErrorType));
            }
            var coupdaysbsResult = new CoupdaybsImpl(settlement, maturity, frequency, basis).Coupdaybs();

            if (coupdaysbsResult.HasError)
            {
                return(new FinanceCalcResult <double>(coupdaysbsResult.ExcelErrorType));
            }

            var E   = coupDaysResult.Result;
            var DSC = coupdaysNcResult.Result;
            var N   = coupnumResult.Result;
            var A   = coupdaysbsResult.Result;

            var retVal = -1d;

            if (N > 1)
            {
                var part1 = redemption / System.Math.Pow(1d + (yield / frequency), N - 1d + (DSC / E));
                var sum   = 0d;
                for (var k = 1; k <= N; k++)
                {
                    sum += (100 * (rate / frequency)) / System.Math.Pow(1 + yield / frequency, k - 1 + DSC / E);
                }

                retVal = part1 + sum - (100 * (rate / frequency) * (A / E));
            }
            else
            {
                var DSR = E - A;
                var T1  = 100 * (rate / frequency) + redemption;
                var T2  = (yield / frequency) * (DSR / E) + 1;
                var T3  = 100 * (rate / frequency) * (A / E);

                retVal = T1 / T2 - T3;
            }

            return(new FinanceCalcResult <double>(retVal));
        }
예제 #24
0
        public double GetForwardRate(DateTime startDate, DateTime endDate, RateType rateType, DayCountBasis basis)
        {
            var tbas = startDate.CalculateYearFraction(endDate, basis);

            return(GetForwardRate(startDate, endDate, rateType, tbas));
        }
예제 #25
0
 public HazzardCurve(DateTime originDate, DayCountBasis basis, IInterpolator1D hazzardRateInterpolator)
 {
     OriginDate    = originDate;
     Basis         = basis;
     _hazzardCurve = hazzardRateInterpolator;
 }
예제 #26
0
        public static double PV(this CashFlowSchedule schedule, IrCurve discountCurve, IrCurve forecastCurve, bool updateState, bool updateDf, bool updateEstimate, DayCountBasis basisFloat, DateTime?filterDate)
        {
            double totalPv = 0;

            for (var i = 0; i < schedule.Flows.Count; i++)
            {
                var flow = schedule.Flows[i];

                if (filterDate.HasValue && flow.SettleDate < filterDate.Value)
                {
                    continue;
                }

                double fv, pv, df;

                switch (flow.FlowType)
                {
                case FlowType.FixedRate:
                {
                    if (updateState)
                    {
                        var rateLin = flow.FixedRateOrMargin;
                        var yf      = flow.YearFraction;
                        fv = rateLin * yf * flow.Notional;
                    }
                    else
                    {
                        fv = flow.Fv;
                    }

                    if (updateDf)
                    {
                        df = discountCurve.Pv(1, flow.SettleDate);
                    }
                    else
                    {
                        df = flow.Fv == flow.Pv ? 1.0 : flow.Pv / flow.Fv;
                    }

                    pv = fv * df;

                    totalPv += pv;

                    if (updateState)
                    {
                        flow.Fv = fv;
                        flow.Pv = pv;
                    }
                    break;
                }

                case FlowType.FloatRate:
                {
                    if (updateEstimate)
                    {
                        var s       = flow.AccrualPeriodStart;
                        var e       = flow.AccrualPeriodEnd;
                        var rateLin = forecastCurve.GetForwardRate(s, e, RateType.Linear, basisFloat);
                        rateLin += flow.FixedRateOrMargin;
                        var yf = flow.YearFraction;
                        fv = rateLin * yf * flow.Notional;
                    }
                    else
                    {
                        fv = flow.Fv;
                    }

                    if (updateDf)
                    {
                        df = discountCurve.Pv(1, flow.SettleDate);
                    }
                    else
                    {
                        df = flow.Fv == flow.Pv ? 1.0 : flow.Pv / flow.Fv;
                    }

                    pv       = fv * df;
                    totalPv += pv;

                    if (updateState)
                    {
                        flow.Fv = fv;
                        flow.Pv = pv;
                    }
                    break;
                }

                case FlowType.FixedAmount:
                {
                    fv = flow.Notional;

                    if (updateDf)
                    {
                        df = discountCurve.Pv(1, flow.SettleDate);
                    }
                    else
                    {
                        df = flow.Fv == flow.Pv ? 1.0 : flow.Pv / flow.Fv;
                    }

                    pv       = fv * df;
                    totalPv += pv;

                    if (updateState)
                    {
                        flow.Fv = fv;
                        flow.Pv = pv;
                    }

                    break;
                }
                }
            }

            return(totalPv);
        }
예제 #27
0
 public void YearFraction(DateTime startDate, DateTime endDate, DayCountBasis basis, double yf) => Assert.Equal(yf, startDate.CalculateYearFraction(endDate, basis));
예제 #28
0
        public static double PV(this CashFlowSchedule schedule, Currency reportingCCy, IFundingModel model, string forecastCurve, DayCountBasis basisFloat, DateTime?filterDate)
        {
            var totalPv = 0.0;

            for (var i = 0; i < schedule.Flows.Count; i++)
            {
                var flow = schedule.Flows[i];

                if (filterDate.HasValue && flow.SettleDate < filterDate.Value)
                {
                    continue;
                }

                double fv, pv;
                var    df        = model.GetDf(reportingCCy, model.BuildDate, flow.SettleDate);
                var    fwdFxRate = model.GetFxRate(flow.SettleDate, flow.Currency, reportingCCy);

                switch (flow.FlowType)
                {
                case FlowType.FixedRate:
                {
                    var rateLin = flow.FixedRateOrMargin;
                    var yf      = flow.YearFraction;
                    fv       = rateLin * yf * flow.Notional;
                    fv      *= fwdFxRate;
                    pv       = fv * df;
                    totalPv += pv;
                    break;
                }

                case FlowType.FloatRate:
                {
                    var s       = flow.AccrualPeriodStart;
                    var e       = flow.AccrualPeriodEnd;
                    var rateLin = model.GetCurve(forecastCurve).GetForwardRate(s, e, RateType.Linear, basisFloat);
                    rateLin += flow.FixedRateOrMargin;
                    var yf = flow.YearFraction;
                    fv       = rateLin * yf * flow.Notional;
                    fv      *= fwdFxRate;
                    pv       = fv * df;
                    totalPv += pv;
                    break;
                }

                case FlowType.FixedAmount:
                {
                    fv       = flow.Notional;
                    fv      *= fwdFxRate;
                    pv       = fv * df;
                    totalPv += pv;
                    break;
                }
                }
            }

            return(totalPv);
        }
예제 #29
0
 internal static int NumberOfDays(DayCountBasis basis)
 {
     if (basis == DayCountBasis.Actual_360 || basis == DayCountBasis.European_30_360 ||
         basis == DayCountBasis.US_NASD) return 360;
     else return 365;
 }
예제 #30
0
 public double GetPrice(System.DateTime settlement, System.DateTime maturity, double rate, double yield, double redemption, int frequency, DayCountBasis basis = DayCountBasis.US_30_360)
 {
     return(PriceImpl.GetPrice(
                FinancialDayFactory.Create(settlement, basis),
                FinancialDayFactory.Create(maturity, basis),
                rate,
                yield,
                redemption,
                frequency,
                basis).Result);
 }
예제 #31
0
 /// <summary>
 /// Returns the discount rate for a security
 /// </summary>
 /// <param name="settlement">The security's settlement date.</param>
 /// <param name="maturity">The security's maturity date.</param>
 /// <param name="par">The security's price per $100 face value.</param>
 /// <param name="redemption">The security's redemption value per $100 face value.</param>
 /// <param name="basis">The type of day count basis to use.</param>
 /// <returns>The discount rate for a security</returns>
 public static double DISC(DateTime settlement, DateTime maturity, double par, double redemption, DayCountBasis basis = DayCountBasis.US_NASD)
 {
     return (redemption - par) / redemption * (NumberOfDays(basis) / (maturity - settlement).Days);
 }
예제 #32
0
파일: Cashflow.cs 프로젝트: biqueta/qwack
 public static double GetFloatRate(this CashFlow cashFlow, IIrCurve curve, DayCountBasis basis) => curve.GetForwardRate(cashFlow.AccrualPeriodStart, cashFlow.AccrualPeriodEnd, RateType.Linear, basis);
예제 #33
0
        /// <summary>
        /// Returns the accrued interest for a security that pays interest at maturity
        /// </summary>
        /// <param name="issue">The security's issue date.</param>
        /// <param name="settlement">The security's maturity date.</param>
        /// <param name="rate">The security's annual coupon rate.</param>
        /// <param name="par">The security's par value.</param>
        /// <param name="basis">The type of day count basis to use.</param>
        /// <returns>The accrued interest for a security that pays interest at maturity.</returns>
        public static double ACCRINTM(
            DateTime issue,
            DateTime settlement,
            double rate,
            double par,
            DayCountBasis basis = DayCountBasis.US_NASD)
        {
            if (rate <= 0) throw new ArgumentOutOfRangeException(nameof(rate), "'rate' must be greater than 0");
            if (par <= 0) throw new ArgumentOutOfRangeException(nameof(par), "'par' must be greater than 0");

            if (issue >= settlement)
                throw new ArgumentException("The issue date must be before the settlement date.", nameof(issue));


            throw new NotImplementedException();
            //return par * (rate / (double)frequency) * Functions.Sum(i => 0, 1, 2).Real;
        }