public void InterestRateListNullInConditions()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);

            ProductConditions conditions = new ProductConditions
            {
                Fees          = new List <FeeCondition> {
                },
                InterestRates = new List <InterestRateCondition> {
                    null
                }
            };
            Application application                = Utility.GetApplication(conditions);
            var         arrangementRequest         = application.ArrangementRequests[0] as TermLoanRequest;
            var         priceCalculationConditions = Utility.GetPriceCalculationParameterFromTermLoanRequest(arrangementRequest);


            var result = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);

            Assert.Equal("RanToCompletion", result.Status.ToString());
            Assert.Empty(result.Result.Conditions.Fees);
        }
        public void RateInInterestRateNull()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var OfferPriceCalculation     = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            InterestRateCondition intRate = new InterestRateCondition
            {
                Kind       = InterestRateKinds.RegularInterest,
                Rate       = null,
                Title      = "regular-interest",
                Currencies = new List <string> {
                    "RSD"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                InterestRates = new List <InterestRateCondition> {
                    intRate
                }
            };
            Application application                = Utility.GetApplication(conditions);
            var         arrangementRequest         = application.ArrangementRequests[0] as TermLoanRequest;
            var         priceCalculationConditions = Utility.GetPriceCalculationParameterFromTermLoanRequest(arrangementRequest);


            var result = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);

            Assert.Equal("RanToCompletion", result.Status.ToString());
            Assert.Single(result.Result.Conditions.InterestRates);
        }
        //Percentage and FixedAmount have two variations that sets them over upper limit and calculated should be equal to upper limit
        public void CalculatedOverUpperLimitMultipleVariations()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var          OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            FeeCondition regularFee            = new FeeCondition
            {
                Percentage  = (decimal)0.1,
                FixedAmount = new Currency {
                    Amount = 20, Code = "EUR"
                },
                LowerLimit = new Currency {
                    Amount = 20, Code = "EUR"
                },
                UpperLimit = new Currency {
                    Amount = 200, Code = "EUR"
                },
                VariationsDefinitionDMN = "product/price-variations/multiple-fee-var-over-range.dmn",
                PercentageLowerLimit    = (decimal)0.05,
                PercentageUpperLimit    = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                }
            };
            Application application                = Utility.GetApplication(conditions);
            var         arrangementRequest         = application.ArrangementRequests[0] as TermLoanRequest;
            var         priceCalculationConditions = Utility.GetPriceCalculationParameterFromTermLoanRequest(arrangementRequest);


            var result     = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);
            var resultFees = result.Result.Conditions.Fees[0];
            var variation  = result.Result.Conditions.Fees[0].Variations;

            Assert.Equal("2", variation.Count.ToString());

            var variationOne = variation[0];
            var variationTwo = variation[1];

            Assert.Equal("RanToCompletion", result.Status.ToString());
            Assert.Equal(1, resultFees.CalculatedPercentage);
            Assert.Equal((decimal)0.4, variationOne.Percentage);
            Assert.Equal((decimal)0.6, variationTwo.Percentage);
            Assert.Equal("product/price-variations/multiple-fee-var-over-range.dmn", resultFees.VariationsDefinitionDMN);
        }
Пример #4
0
        public void IterativeBaseRateInInterestRateNull()
        {
            var OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            InterestRateCondition regularInterestEuribor = new InterestRateCondition
            {
                //market-rates api ima bazne vrednosti za interest rates - odavde uzeti primere
                //Regular interest moze da bude definisan posebno za svaku valutu
                Kind = InterestRateKinds.RegularInterest,
                Rate = new InterestRate
                {
                    BaseRateId      = null,
                    SpreadRateValue = 10
                },
                EffectiveDate = DateTime.Now.AddDays(-1),
                Title         = "regular-interest",
                Currencies    = new List <string> {
                    "RSD"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                InterestRates = new List <InterestRateCondition> {
                    regularInterestEuribor
                }
            };
            var arrangementRequest = Utility.GetArangementRequest(conditions);

            Application application = new Application
            {
                //U DMN-u pogledati podatke kje uticu na skor iz configa
                //Ovo ce promeniti broj Percentage za fee i za interest-rate
                ArrangementNumber = "1",
                CustomerName      = "Tester",
                StatusInformation = new StatusInformation
                {
                    Description = "Works as a tester"
                },
                CustomerSegment = "student",
                CollateralModel = "two-co-debtors",

                RiskScore   = 55,
                ChannelCode = "web",
                RequestDate = DateTime.Now
            };

            var result = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);

            Assert.Equal("RanToCompletion", result.Status.ToString());
            Assert.Single(result.Result.Conditions.InterestRates);
            var interestRate = result.Result.Conditions.InterestRates[0];

            Assert.Null(interestRate.Rate.BaseRateId);
            Assert.Equal(0, interestRate.Rate.BaseRateValue);
            Assert.Equal((decimal)10.0, interestRate.Rate.SpreadRateValue);
        }
Пример #5
0
 public override void CalculateOffer(Application application, OfferPriceCalculation priceCalculator, string conversionMethod)
 {
     //if (!ValidateParameters(this))
     //{
     //    // do something man !!!
     //}
     //
     _ = priceCalculator.CalculatePrice(application, this).Result;
     CalculateInstallmentPlan(conversionMethod);
 }
        public void BaseRateInInterestRateNull()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            InterestRateCondition regularInterestEuribor = new InterestRateCondition
            {
                //market-rates api ima bazne vrednosti za interest rates - odavde uzeti primere
                //Regular interest moze da bude definisan posebno za svaku valutu
                Kind = InterestRateKinds.RegularInterest,
                Rate = new InterestRate
                {
                    BaseRateId      = null,
                    SpreadRateValue = 10
                },
                EffectiveDate = DateTime.Now.AddDays(-1),
                Title         = "regular-interest",
                Currencies    = new List <string> {
                    "RSD"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                InterestRates = new List <InterestRateCondition> {
                    regularInterestEuribor
                }
            };
            Application application                = Utility.GetApplication(conditions);
            var         arrangementRequest         = application.ArrangementRequests[0] as TermLoanRequest;
            var         priceCalculationConditions = Utility.GetPriceCalculationParameterFromTermLoanRequest(arrangementRequest);


            var result = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);

            Assert.Equal("RanToCompletion", result.Status.ToString());
            Assert.Single(result.Result.Conditions.InterestRates);
            var interestRate = result.Result.Conditions.InterestRates[0];

            Assert.Null(interestRate.Rate.BaseRateId);
            Assert.Equal(0, interestRate.Rate.BaseRateValue);
            Assert.Equal((decimal)10.0, interestRate.Rate.SpreadRateValue);
        }
Пример #7
0
        public void IterativeRateInInterestRateNull()
        {
            var OfferPriceCalculation     = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            InterestRateCondition intRate = new InterestRateCondition
            {
                Kind       = InterestRateKinds.RegularInterest,
                Rate       = null,
                Title      = "regular-interest",
                Currencies = new List <string> {
                    "RSD"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                InterestRates = new List <InterestRateCondition> {
                    intRate
                }
            };
            var arrangementRequest = Utility.GetArangementRequest(conditions);

            Application application = new Application
            {
                //U DMN-u pogledati podatke kje uticu na skor iz configa
                //Ovo ce promeniti broj Percentage za fee i za interest-rate
                ArrangementNumber = "1",
                CustomerName      = "Tester",
                StatusInformation = new StatusInformation
                {
                    Description = "Works as a tester"
                },
                CustomerSegment = "student",
                CollateralModel = "two-co-debtors",

                RiskScore   = 55,
                ChannelCode = "web",
                RequestDate = DateTime.Now
            };

            var result = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);

            Assert.Equal("RanToCompletion", result.Status.ToString());
            Assert.Single(result.Result.Conditions.InterestRates);
        }
Пример #8
0
        public async Task <PriceCalculationResponse> Handle(InitiatePriceCalculationCommand message, CancellationToken cancellationToken)
        {
            ProductConditions conditions = await _priceCalculation.ReadVariationDefinitions(new ProductConditions
            {
                Fees          = message.Fees == null ? null : new List <FeeCondition>(message.Fees),
                InterestRates = message.InterestRates == null ? null : new List <InterestRateCondition>(message.InterestRates)
            });

            var calcParams = new PriceCalculationParameters
            {
                InterestRates        = conditions.InterestRates,
                Fees                 = conditions.Fees,
                Amount               = message.Amount,
                Term                 = message.Term,
                Currency             = message.Currency,
                Channel              = message.Channel,
                RiskScore            = message.RiskScore,
                CustomerSegment      = message.CustomerSegment,
                CollateralModel      = message.CollateralModel,
                PartOfBundle         = message.ProductBundling,
                Campaign             = message.Campaign,
                Options              = message.ProductOptions,
                CreditRating         = message.CreditRating,
                CustomerValue        = message.CustomerValue,
                DebtToIncome         = message.DebtToIncome,
                AdditionalProperties = message.BundledComponents
            };

            var calcResult = await _priceCalculator.CalculatePrice(calcParams);

            var result = new PriceCalculationResponse
            {
                Fees          = calcResult.Fees,
                InterestRates = calcResult.InterestRates,
                Napr          = calcResult.Napr
            };

            return(result);
        }
        //Percentage and FixedAmount have a variation that sets them to near lower limit but still above
        public void CalculatedNearLowerLimit()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var          OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            FeeCondition regularFee            = new FeeCondition
            {
                //Samo % se testira za sada jer trenutno nema za fixedAmount
                //Samo varijacije uticu na PercentageKind = FeeConditionKinds.OriginationFee,
                Percentage  = (decimal)0.1,
                FixedAmount = new Currency {
                    Amount = 200, Code = "EUR"
                },
                LowerLimit = new Currency {
                    Amount = 20, Code = "EUR"
                },
                UpperLimit = new Currency {
                    Amount = 200, Code = "EUR"
                },
                VariationsDefinitionDMN = "product/price-variations/fee-in-range-lower.dmn",
                PercentageLowerLimit    = (decimal)0.01,
                PercentageUpperLimit    = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                }
            };

            Application application                = Utility.GetApplication(conditions);
            var         arrangementRequest         = application.ArrangementRequests[0] as TermLoanRequest;
            var         priceCalculationConditions = Utility.GetPriceCalculationParameterFromTermLoanRequest(arrangementRequest);


            var result = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);

            //Basic assertions
            Assert.Equal("RanToCompletion", result.Status.ToString());

            Assert.Single(result.Result.Conditions.Fees);
            var resultFees = result.Result.Conditions.Fees[0];

            Assert.Single(resultFees.Variations);
            var variation = resultFees.Variations[0];


            //Asserting input
            Assert.Equal(200, resultFees.FixedAmount.Amount);
            Assert.Equal((decimal)0.1, resultFees.Percentage);

            //Asserting output
            Assert.Equal("product/price-variations/fee-in-range-lower.dmn", resultFees.VariationsDefinitionDMN);
            Assert.Equal((decimal)0.02, resultFees.CalculatedPercentage);
            Assert.Equal((decimal) - 0.08, variation.Percentage);
            Assert.Equal(21, resultFees.CalculatedFixedAmount);
            Assert.Equal(-179, variation.FixedAmount);
        }
Пример #10
0
        //Arrangement Request is set to EUR
        //There are no defined variations - Application data does not matter
        //There are two fees, both accounted because they're in the same currency
        public void IterativeTwoInterestRatesDiferentKind()
        {
            var          OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            FeeCondition regularFee            = new FeeCondition
            {
                //Samo % se testira za sada jer trenutno nema za fixedAmount
                //Samo varijacije uticu na Percentage
                Kind        = FeeConditionKinds.OriginationFee,
                Percentage  = (decimal)0.2,
                FixedAmount = new Currency {
                    Amount = 200, Code = "EUR"
                },
                LowerLimit = new Currency {
                    Amount = 200, Code = "EUR"
                },
                UpperLimit = new Currency {
                    Amount = 4000, Code = "EUR"
                },
                PercentageLowerLimit = (decimal)0.01,
                PercentageUpperLimit = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            InterestRateCondition regularInterestEuribor = new InterestRateCondition
            {
                Kind = InterestRateKinds.RegularInterest,
                Rate = new InterestRate
                {
                    BaseRateId      = "EURIBOR-3M",
                    SpreadRateValue = 10
                },
                Title      = "regular-interest",
                Currencies = new List <string> {
                    "EUR"
                }
            };

            InterestRateCondition earlyWithdrawalInterest = new InterestRateCondition
            {
                Kind = InterestRateKinds.EarlyWithdrawalInterest,
                Rate = new InterestRate
                {
                    BaseRateId      = "EARLY-EUR",
                    SpreadRateValue = 2
                },
                Title      = "early-withdrawal-interest",
                Currencies = new List <string> {
                    "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                    regularInterestEuribor, earlyWithdrawalInterest
                }
            };
            var arrangementRequest = Utility.GetArangementRequest(conditions);

            Application application = new Application
            {
                ArrangementNumber = "1",
                CustomerName      = "Tester",
                StatusInformation = new StatusInformation
                {
                    Description = "Works as a tester"
                },
                CustomerSegment = "student",
                CollateralModel = "two-co-debtors",

                RiskScore   = 55,
                ChannelCode = "web",
                RequestDate = DateTime.Now
            };

            var result = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);

            Assert.Single(result.Result.Conditions.Fees);
            Assert.Equal("RanToCompletion", result.Status.ToString());

            var resultInterest = result.Result.Conditions.InterestRates[0];
            var resultEarlyWithdrawalInterest = result.Result.Conditions.InterestRates[1];

            Assert.Equal("EURIBOR-3M", resultInterest.Rate.BaseRateId);
            Assert.Equal((decimal)8.5, resultInterest.CalculatedRate);
            Assert.Equal((decimal) - 1.5, resultInterest.Rate.BaseRateValue);
            Assert.Equal((decimal)10.0, resultInterest.Rate.SpreadRateValue);
            //C# won't let this be asserted in any other way
            Assert.Equal("0", resultInterest.Variations.Count.ToString());

            Assert.Equal("EARLY-EUR", resultEarlyWithdrawalInterest.Rate.BaseRateId);
            Assert.Equal((decimal)3.5, resultEarlyWithdrawalInterest.CalculatedRate);
            Assert.Equal((decimal)1.5, resultEarlyWithdrawalInterest.Rate.BaseRateValue);
            Assert.Equal((decimal)2.0, resultEarlyWithdrawalInterest.Rate.SpreadRateValue);

            Assert.Equal(0, resultInterest.CalculatedLowerLimit);
            Assert.Equal(100, resultInterest.CalculatedUpperLimit);
        }
        //Arrangement Request is set to EUR
        //There are no defined variations - Application data does not matter
        //There are two fees, both accounted because they're in the same currency
        public void TwoInterestRatesDiferentKind()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var          OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            FeeCondition regularFee            = new FeeCondition
            {
                //Samo % se testira za sada jer trenutno nema za fixedAmount
                //Samo varijacije uticu na Percentage
                Kind        = FeeConditionKinds.OriginationFee,
                Percentage  = (decimal)0.2,
                FixedAmount = new Currency {
                    Amount = 200, Code = "EUR"
                },
                LowerLimit = new Currency {
                    Amount = 200, Code = "EUR"
                },
                UpperLimit = new Currency {
                    Amount = 4000, Code = "EUR"
                },
                PercentageLowerLimit = (decimal)0.01,
                PercentageUpperLimit = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            InterestRateCondition regularInterestEuribor = new InterestRateCondition
            {
                Kind = InterestRateKinds.RegularInterest,
                Rate = new InterestRate
                {
                    BaseRateId      = "EURIBOR-3M",
                    SpreadRateValue = 10
                },
                Title      = "regular-interest",
                Currencies = new List <string> {
                    "EUR"
                }
            };

            InterestRateCondition earlyWithdrawalInterest = new InterestRateCondition
            {
                Kind = InterestRateKinds.EarlyWithdrawalInterest,
                Rate = new InterestRate
                {
                    BaseRateId      = "EARLY-EUR",
                    SpreadRateValue = 2
                },
                Title      = "early-withdrawal-interest",
                Currencies = new List <string> {
                    "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                    regularInterestEuribor, earlyWithdrawalInterest
                }
            };

            Application application                = Utility.GetApplication(conditions);
            var         arrangementRequest         = application.ArrangementRequests[0] as TermLoanRequest;
            var         priceCalculationConditions = Utility.GetPriceCalculationParameterFromTermLoanRequest(arrangementRequest);


            var result = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);

            Assert.Single(result.Result.Conditions.Fees);
            Assert.Equal("RanToCompletion", result.Status.ToString());

            var resultInterest = result.Result.Conditions.InterestRates[0];
            var resultEarlyWithdrawalInterest = result.Result.Conditions.InterestRates[1];

            Assert.Equal("EURIBOR-3M", resultInterest.Rate.BaseRateId);
            Assert.Equal((decimal)8.5, resultInterest.CalculatedRate);
            Assert.Equal((decimal) - 1.5, resultInterest.Rate.BaseRateValue);
            Assert.Equal((decimal)10.0, resultInterest.Rate.SpreadRateValue);
            //C# won't let this be asserted in any other way
            Assert.Equal("0", resultInterest.Variations.Count.ToString());

            Assert.Equal("EARLY-EUR", resultEarlyWithdrawalInterest.Rate.BaseRateId);
            Assert.Equal((decimal)3.5, resultEarlyWithdrawalInterest.CalculatedRate);
            Assert.Equal((decimal)1.5, resultEarlyWithdrawalInterest.Rate.BaseRateValue);
            Assert.Equal((decimal)2.0, resultEarlyWithdrawalInterest.Rate.SpreadRateValue);

            Assert.Equal(0, resultInterest.CalculatedLowerLimit);
            Assert.Equal(100, resultInterest.CalculatedUpperLimit);
        }
Пример #12
0
        //No variations, calc rates should be as they are set in the request
        //Rate is within limits
        public void NoVariationsBelowLimitWithoutMarketRate()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            InterestRateCondition regularInterestEuribor = new InterestRateCondition
            {
                //This base rate id removes -1.5 from spreadRateValue, making rate under limit
                Kind = InterestRateKinds.RegularInterest,
                Rate = new InterestRate
                {
                    BaseRateId      = "EURIBOR-6M",
                    SpreadRateValue = (decimal)9.9
                },
                UpperLimit = new InterestRate
                {
                    BaseRateId      = "EURIBOR-6M",
                    SpreadRateValue = 18
                },
                LowerLimit = new InterestRate
                {
                    BaseRateId      = "EURIBOR-6M",
                    SpreadRateValue = 10
                },
                Title      = "regular-interest",
                Currencies = new List <string> {
                    "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees          = new List <FeeCondition> {
                },
                InterestRates = new List <InterestRateCondition> {
                    regularInterestEuribor
                }
            };
            Application application                = Utility.GetApplication(conditions);
            var         arrangementRequest         = application.ArrangementRequests[0] as TermLoanRequest;
            var         priceCalculationConditions = Utility.GetPriceCalculationParameterFromTermLoanRequest(arrangementRequest);

            var variationsDefinition = Utility.GetVariationDefinitionParamsFromApplication(application);
            var result         = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);
            var resultInterest = result.Result.Conditions.InterestRates[0];

            //Basic assertions
            Assert.Equal("RanToCompletion", result.Status.ToString());
            Assert.Equal("0", resultInterest.Variations.Count.ToString());

            //Asserting input parameters
            Assert.Equal("EURIBOR-6M", resultInterest.Rate.BaseRateId);
            Assert.Equal(0, resultInterest.Rate.BaseRateValue);
            Assert.Equal((decimal)9.9, resultInterest.Rate.SpreadRateValue);

            Assert.Equal("EURIBOR-6M", resultInterest.UpperLimit.BaseRateId);
            Assert.Equal(0, resultInterest.UpperLimit.BaseRateValue);
            Assert.Equal((decimal)18.0, resultInterest.UpperLimit.SpreadRateValue);

            Assert.Equal("EURIBOR-6M", resultInterest.LowerLimit.BaseRateId);
            Assert.Equal(0, resultInterest.LowerLimit.BaseRateValue);
            Assert.Equal((decimal)10.0, resultInterest.LowerLimit.SpreadRateValue);

            //Asserting Napr and calculation results
            Assert.Equal((decimal)10.0, ((TermLoanRequest)result.Result).Napr);
            Assert.Equal((decimal)10.0, resultInterest.CalculatedRate);
            Assert.Equal((decimal)10.0, resultInterest.CalculatedLowerLimit);
            Assert.Equal((decimal)18.0, resultInterest.CalculatedUpperLimit);
        }
        //Percentage and FixedAmount have a variation that sets them to near lower limit but still above
        public void IterativeCalculatedNearLowerLimit()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var          priceCalculator = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            FeeCondition regularFee      = new FeeCondition
            {
                //Samo % se testira za sada jer trenutno nema za fixedAmount
                //Samo varijacije uticu na PercentageKind = FeeConditionKinds.OriginationFee,
                Percentage  = (decimal)0.1,
                FixedAmount = new Currency {
                    Amount = 200, Code = "EUR"
                },
                LowerLimit = new Currency {
                    Amount = 20, Code = "EUR"
                },
                UpperLimit = new Currency {
                    Amount = 200, Code = "EUR"
                },
                VariationsDefinitionDMN = "product/price-variations/iterative-fee-in-range-lower.dmn",
                PercentageLowerLimit    = (decimal)0.01,
                PercentageUpperLimit    = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                }
            };
            var arrangementRequest = Utility.GetArangementRequest(conditions);

            Application application = new Application
            {
                ArrangementNumber = "1",
                CustomerName      = "Tester",
                StatusInformation = new StatusInformation
                {
                    Description = "Works as a tester"
                },
                CustomerSegment = "student",
                CollateralModel = "two-co-debtors",

                RiskScore   = 55,
                ChannelCode = "web",
                RequestDate = DateTime.Now
            };

            var result = priceCalculator.CalculatePrice(application, arrangementRequest);

            //Basic assertions
            Assert.Equal("RanToCompletion", result.Status.ToString());

            Assert.Single(result.Result.Conditions.Fees);
            var resultFees = result.Result.Conditions.Fees[0];

            Assert.Single(resultFees.Variations);
            var variation = resultFees.Variations[0];


            //Asserting input
            Assert.Equal(200, resultFees.FixedAmount.Amount);
            Assert.Equal((decimal)0.1, resultFees.Percentage);

            //Asserting output
            Assert.Equal("product/price-variations/iterative-fee-in-range-lower.dmn", resultFees.VariationsDefinitionDMN);
            Assert.Equal((decimal)0.03, resultFees.CalculatedPercentage);
            Assert.Equal((decimal) - 0.07, variation.Percentage);
            Assert.Equal(22, resultFees.CalculatedFixedAmount);
            Assert.Equal(-178, variation.FixedAmount);
        }
        //Percentage and FixedAmount have two variations that sets them over upper limit and calculated should be equal to upper limit
        public void IterativeCalculatedOverUpperLimitMultipleVariations()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var          priceCalculator = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            FeeCondition regularFee      = new FeeCondition
            {
                Percentage  = (decimal)0.1,
                FixedAmount = new Currency {
                    Amount = 20, Code = "EUR"
                },
                LowerLimit = new Currency {
                    Amount = 20, Code = "EUR"
                },
                UpperLimit = new Currency {
                    Amount = 200, Code = "EUR"
                },
                VariationsDefinitionDMN = "product/price-variations/iterative-multiple-fee-var-over-range.dmn",
                PercentageLowerLimit    = (decimal)0.05,
                PercentageUpperLimit    = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                }
            };
            var arrangementRequest = Utility.GetArangementRequest(conditions);

            Application application = new Application
            {
                ArrangementNumber = "1",
                CustomerName      = "Tester",
                StatusInformation = new StatusInformation
                {
                    Description = "Works as a tester"
                },
                CustomerSegment = "student",
                CollateralModel = "two-co-debtors",

                RiskScore   = 55,
                ChannelCode = "web",
                RequestDate = DateTime.Now
            };

            var result     = priceCalculator.CalculatePrice(application, arrangementRequest);
            var resultFees = result.Result.Conditions.Fees[0];

            var variation = result.Result.Conditions.Fees[0].Variations;

            Assert.Equal("2", variation.Count.ToString());

            var variationOne = variation[0];
            var variationTwo = variation[1];

            Assert.Equal("RanToCompletion", result.Status.ToString());
            Assert.Equal(1, resultFees.CalculatedPercentage);
            Assert.Equal((decimal)0.5, variationOne.Percentage);
            Assert.Equal((decimal)0.6, variationTwo.Percentage);
            Assert.Equal("product/price-variations/iterative-multiple-fee-var-over-range.dmn", resultFees.VariationsDefinitionDMN);
        }
Пример #15
0
        public void IterativeMultipleOriginationFeesBothCalculated()
        {
            var          OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            FeeCondition regularFee            = new FeeCondition
            {
                Kind               = FeeConditionKinds.OriginationFee,
                ServiceCode        = "",
                ServiceDescription = "",
                Percentage         = (decimal)0.2,
                FixedAmount        = new Currency {
                    Amount = 200, Code = "RSD"
                },
                LowerLimit = new Currency {
                    Amount = 200, Code = "RSD"
                },
                UpperLimit = new Currency {
                    Amount = 4000, Code = "RSD"
                },
                PercentageLowerLimit = (decimal)0.01,
                PercentageUpperLimit = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            FeeCondition regularFee2 = new FeeCondition
            {
                Kind               = FeeConditionKinds.OriginationFee,
                ServiceCode        = "",
                ServiceDescription = "",
                Percentage         = (decimal)0.3,
                FixedAmount        = new Currency {
                    Amount = 300, Code = "RSD"
                },
                LowerLimit = new Currency {
                    Amount = 200, Code = "RSD"
                },
                UpperLimit = new Currency {
                    Amount = 4000, Code = "RSD"
                },
                PercentageLowerLimit = (decimal)0.01,
                PercentageUpperLimit = 1,
                Title         = "Origination-fee2",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                }
            };
            var arrangementRequest = Utility.GetArangementRequest(conditions);

            Application application = new Application
            {
                ArrangementNumber = "1",
                CustomerName      = "Tester",
                StatusInformation = new StatusInformation
                {
                    Description = "Works as a tester"
                },
                CustomerSegment = "student",
                CollateralModel = "two-co-debtors",

                RiskScore   = 55,
                ChannelCode = "web",
                RequestDate = DateTime.Now
            };

            var result = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);

            Assert.Equal("RanToCompletion", result.Status.ToString());
            var resultFees = result.Result.Conditions.Fees;

            //Assert.Equal("2", resultFees.Count.ToString());
            Assert.Equal("1", resultFees.Count.ToString());
            var resultFeeOne = resultFees[0];

            Assert.Empty(resultFeeOne.Variations);
            Assert.Equal((decimal)0.2, resultFeeOne.CalculatedPercentage);
            Assert.Equal(200, resultFeeOne.CalculatedFixedAmount);
            Assert.Null(resultFeeOne.VariationsDefinitionDMN);

            //var resultFeeTwo = resultFees[1];
            //Assert.Empty(resultFeeTwo.Variations);
            //Assert.Equal((decimal)0.3, resultFeeTwo.CalculatedPercentage);
            //Assert.Equal(300, resultFeeTwo.CalculatedFixedAmount);
            //Assert.Null(resultFeeTwo.VariationsDefinitionDMN);
        }
        public void MultipleOriginationFeesBothCalculated()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var          OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            FeeCondition regularFee            = new FeeCondition
            {
                Kind               = FeeConditionKinds.OriginationFee,
                ServiceCode        = "",
                ServiceDescription = "",
                Percentage         = (decimal)0.2,
                FixedAmount        = new Currency {
                    Amount = 200, Code = "RSD"
                },
                LowerLimit = new Currency {
                    Amount = 200, Code = "RSD"
                },
                UpperLimit = new Currency {
                    Amount = 4000, Code = "RSD"
                },
                PercentageLowerLimit = (decimal)0.01,
                PercentageUpperLimit = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            FeeCondition regularFee2 = new FeeCondition
            {
                Kind               = FeeConditionKinds.OriginationFee,
                ServiceCode        = "",
                ServiceDescription = "",
                Percentage         = (decimal)0.3,
                FixedAmount        = new Currency {
                    Amount = 300, Code = "RSD"
                },
                LowerLimit = new Currency {
                    Amount = 200, Code = "RSD"
                },
                UpperLimit = new Currency {
                    Amount = 4000, Code = "RSD"
                },
                PercentageLowerLimit = (decimal)0.01,
                PercentageUpperLimit = 1,
                Title         = "Origination-fee2",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                }
            };
            Application application                = Utility.GetApplication(conditions);
            var         arrangementRequest         = application.ArrangementRequests[0] as TermLoanRequest;
            var         priceCalculationConditions = Utility.GetPriceCalculationParameterFromTermLoanRequest(arrangementRequest);


            var result = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);

            Assert.Equal("RanToCompletion", result.Status.ToString());
            var resultFees = result.Result.Conditions.Fees;

            Assert.Equal("2", resultFees.Count.ToString());
            var resultFeeOne = resultFees[0];

            Assert.Empty(resultFeeOne.Variations);
            Assert.Equal((decimal)0.2, resultFeeOne.CalculatedPercentage);
            Assert.Equal(200, resultFeeOne.CalculatedFixedAmount);
            Assert.Null(resultFeeOne.VariationsDefinitionDMN);

            var resultFeeTwo = resultFees[1];

            Assert.Empty(resultFeeTwo.Variations);
            Assert.Equal((decimal)0.3, resultFeeTwo.CalculatedPercentage);
            Assert.Equal(300, resultFeeTwo.CalculatedFixedAmount);
            Assert.Null(resultFeeTwo.VariationsDefinitionDMN);
        }
Пример #17
0
 public override void CalculateOffer(PriceCalculationParameters calculationParameters,
                                     OfferPriceCalculation priceCalculator, string conversionMethod)
 {
     _ = priceCalculator.CalculatePrice(this, calculationParameters).Result;
     CalculateInstallmentPlan(conversionMethod);
 }
        public void TwoInterestRatesOneUsed()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);

            /*VariationsDefinition (fee.variationsDefinition) utice na fee.percentage (percentage + varijacije)
             * fixedAmount moze da seta u okviru definisanih granica (Upper/LowerLimitAmount ili percentage)
             */
            //moze da postoji samo jedan origination fee
            FeeCondition regularFee = new FeeCondition
            {
                Kind               = FeeConditionKinds.OriginationFee,
                ServiceCode        = "",
                ServiceDescription = "",
                Percentage         = (decimal)0.2,
                FixedAmount        = new Currency {
                    Amount = 200, Code = "RSD"
                },
                LowerLimit = new Currency {
                    Amount = 200, Code = "RSD"
                },
                UpperLimit = new Currency {
                    Amount = 4000, Code = "RSD"
                },
                PercentageLowerLimit = (decimal)0.01,
                PercentageUpperLimit = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };
            //SpreadRateValue + BaseRateValue + SumaVarijacija = interestRate.CalculatedRate
            //Vazi za svaki interest rate
            //Samo jedan RegularInterest moze biti na proizvodu i napr je vezan samo za njegov CalculatedRate
            InterestRateCondition regularInterestEuribor = new InterestRateCondition
            {
                //market-rates api ima bazne vrednosti za interest rates - odavde uzeti primere
                //Regular interest moze da bude definisan posebno za svaku valutu
                Kind = InterestRateKinds.RegularInterest,
                Rate = new InterestRate
                {
                    BaseRateId      = "EURIBOR-3M",
                    SpreadRateValue = 10
                },
                Title      = "regular-interest",
                Currencies = new List <string> {
                    "EUR"
                }
            };

            InterestRateCondition regularInterestBelibor = new InterestRateCondition
            {
                //SpreadRateValue je fiksni deo kamatne stope
                //Base rate id definise prema cemu se gleda promenljivi deo (baseRateBalue) kamatne stope
                //Obuhvati da nema stopu
                //IsFixed
                Kind = InterestRateKinds.RegularInterest,
                Rate = new InterestRate
                {
                    BaseRateId      = "BELIBOR-3M",
                    SpreadRateValue = 12
                },
                Title      = "regular-interest",
                Currencies = new List <string> {
                    "RSD"
                }
            };

            ProductConditions conditions = new ProductConditions {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                    regularInterestEuribor, regularInterestBelibor
                }
            };
            Application application                = Utility.GetApplication(conditions);
            var         arrangementRequest         = application.ArrangementRequests[0] as TermLoanRequest;
            var         priceCalculationConditions = Utility.GetPriceCalculationParameterFromTermLoanRequest(arrangementRequest);


            var result         = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);
            var resultFees     = result.Result.Conditions.Fees[0];
            var resultInterest = result.Result.Conditions.InterestRates[0];

            Assert.Equal("RanToCompletion", result.Status.ToString());
            Assert.Empty(resultFees.Variations);
            Assert.Equal((decimal)0.2, resultFees.CalculatedPercentage);
            Assert.Equal(200, resultFees.CalculatedFixedAmount);
            Assert.Null(resultFees.VariationsDefinitionDMN);

            Assert.Equal("BELIBOR-3M", resultInterest.Rate.BaseRateId);
            Assert.Equal((decimal)9.5, resultInterest.CalculatedRate);
            Assert.Equal((decimal) - 2.5, resultInterest.Rate.BaseRateValue);
            Assert.Equal((decimal)12.0, resultInterest.Rate.SpreadRateValue);
            //C# won't let this be asserted in any other way
            Assert.Equal("0", resultInterest.Variations.Count.ToString());

            Assert.Empty(resultInterest.Variations);
            Assert.Equal(0, resultInterest.CalculatedLowerLimit);
            Assert.Equal(100, resultInterest.CalculatedUpperLimit);
        }
Пример #19
0
        public override void CalculateOffer(PriceCalculationParameters calculationParameters, OfferPriceCalculation priceCalculator, string feeCurrencyConversionMethod)
        {
            var ignore = priceCalculator.CalculatePrice(this, calculationParameters).Result;

            // isCompound i calendarBasis izvuci tokom CalculatePrice da dodatno opisu Napr
            bool isCompound = false;
            CalendarBasisKind calendarBasis = CalendarBasisKind.CalendarActActISDA;
            double            yearlyRate    = Convert.ToDouble(Napr) / 100;

            var ir = Conditions.InterestRates.FirstOrDefault(it => it.Kind == InterestRateKinds.RegularInterest);

            if (ir != null)
            {
                isCompound    = ir.IsCompound;
                calendarBasis = ir.CalendarBasis;
                yearlyRate    = Convert.ToDouble(ir.CalculatedRate);
                Napr          = Convert.ToDecimal(yearlyRate);
            }


            var startDate = calculationParameters.RequestDate ?? DateTime.Today;

            List <InstallmentPlanRow> rows       = new List <InstallmentPlanRow>();
            List <FeeCondition>       rowFeeList = new List <FeeCondition>();
            List <FeeCondition>       fees       = Conditions.Fees;

            fees = FeeCalculation.PrepareFees(fees, Currency, feeCurrencyConversionMethod);

            decimal  runningAmount = Math.Round(Amount, 2);
            DateTime runningDate   = startDate;

            if (CalculationDate > DateTime.Today)
            {
                CalculationDate = runningDate;
            }
            else
            {
                runningDate = CalculationDate ?? DateTime.Today;
            }

            // SLOBA: Fee scheduling, and scheduling in general has to be improved in advanced calculator.
            decimal totalFeeAmount = 0;

            if (fees != null)
            {
                List <FeeCondition> feeList = fees.FindAll(f => f.Frequency == FeeConditionFrequency.EventTriggered && f.EffectiveDate <= DateTime.Today && f.Currencies.Contains(Currency));
                totalFeeAmount = Math.Round(FeeCalculation.CalculateFee(Amount, feeList), 4);
            }
            NumberOfInstallments = 1;

            /* Disbursment */
            InstallmentPlanRow rowDisbursement = new InstallmentPlanRow();

            rowDisbursement.Date               = runningDate;
            rowDisbursement.Ordinal            = 0;
            rowDisbursement.ActivityKind       = ActivityKind.Disbursement;
            rowDisbursement.Description        = "Loan disbursement";
            rowDisbursement.Disbursement       = Amount;
            rowDisbursement.StartingBalance    = 0;
            rowDisbursement.OutstandingBalance = Amount;
            rowDisbursement.PrincipalRepayment = 0;
            rowDisbursement.InterestRepayment  = 0;
            rowDisbursement.NetCashFlow        = Amount - totalFeeAmount;
            rowDisbursement.Fee      = totalFeeAmount;
            rowDisbursement.YearFrac = 0;
            rows.Add(rowDisbursement);
            int i = -1;

            InstallmentPlanRow rowInterest;
            var intrStartDate = startDate;

            runningDate = runningDate.AddMonths(1);
            while (runningDate <= MaturityDate.Value)
            {
                i++;


                var interest = Math.Round(InterestCalculation.CalculateInterest(intrStartDate, runningDate, runningDate, Convert.ToDouble(yearlyRate), 'Y', isCompound, calendarBasis, Convert.ToDouble(runningAmount))
                                          .Sum(it => it.Interest), 2);

                rowInterest = new InstallmentPlanRow();

                rowInterest.Ordinal            = i + 1;
                rowInterest.Date               = runningDate;
                rowInterest.ActivityKind       = ActivityKind.Repayment;
                rowInterest.Description        = "Interest and fee repayment";
                rowInterest.InterestRepayment  = Convert.ToDecimal(interest);
                rowInterest.PrincipalRepayment = 0;
                rowInterest.Annuity            = rowInterest.InterestRepayment;
                rowInterest.StartingBalance    = Math.Round(runningAmount, 2);
                rowInterest.OutstandingBalance = Math.Round(runningAmount, 2);

                #region Fee calculation
                if (fees != null)
                {
                    decimal totalRowFee = 0;
                    rowFeeList = fees.FindAll(f => f.Frequency == FeeConditionFrequency.Monthly && f.EffectiveDate <= DateTime.Today && f.Currencies.Contains(Currency));
                    if (rowFeeList.Count > 0)
                    {
                        totalRowFee += FeeCalculation.CalculateFee(runningAmount, rowFeeList);
                    }
                    if ((i + 1) % 4 == 0)
                    {
                        rowFeeList = fees.FindAll(f => f.Frequency == FeeConditionFrequency.Quarterly && f.EffectiveDate <= DateTime.Today && f.Currencies.Contains(Currency));
                        if (rowFeeList.Count > 0)
                        {
                            totalRowFee += FeeCalculation.CalculateFee(runningAmount, rowFeeList);
                        }
                    }
                    if ((i + 1) % 6 == 0)
                    {
                        rowFeeList = fees.FindAll(f => f.Frequency == FeeConditionFrequency.Semiyearly && f.EffectiveDate <= DateTime.Today && f.Currencies.Contains(Currency));
                        if (rowFeeList.Count > 0)
                        {
                            totalRowFee += FeeCalculation.CalculateFee(runningAmount, rowFeeList);
                        }
                    }
                    if ((i + 1) % 12 == 0)
                    {
                        rowFeeList = fees.FindAll(f => f.Frequency == FeeConditionFrequency.Yearly && f.EffectiveDate <= DateTime.Today && f.Currencies.Contains(Currency));
                        if (rowFeeList.Count > 0)
                        {
                            totalRowFee += FeeCalculation.CalculateFee(runningAmount, rowFeeList);
                        }
                    }
                    rowInterest.Fee = Math.Round(totalRowFee, 4);
                }
                #endregion
                rowInterest.NetCashFlow = rowInterest.Disbursement - rowInterest.PrincipalRepayment - rowInterest.InterestRepayment - rowInterest.Fee - rowInterest.OtherExpenses;
                rowInterest.YearFrac    = Convert.ToDecimal(InterestCalculation.YearFrac(startDate, runningDate)); //, calendarBasis);
                rows.Add(rowInterest);
                intrStartDate = runningDate;
                runningDate   = runningDate.AddMonths(1);
            }

            i++;

            rowInterest = new InstallmentPlanRow();

            rowInterest.Ordinal            = i + 1;
            rowInterest.Date               = runningDate;
            rowInterest.ActivityKind       = ActivityKind.Repayment;
            rowInterest.Description        = "Principal repayment";
            rowInterest.InterestRepayment  = 0;
            rowInterest.PrincipalRepayment = Amount;
            rowInterest.Annuity            = Amount;
            rowInterest.StartingBalance    = Amount;
            rowInterest.OutstandingBalance = 0;

            #region Fee calculation
            rowInterest.Fee = 0;
            #endregion
            rowInterest.NetCashFlow = rowInterest.Disbursement - rowInterest.PrincipalRepayment - rowInterest.InterestRepayment - rowInterest.Fee - rowInterest.OtherExpenses;
            rowInterest.YearFrac    = Convert.ToDecimal(InterestCalculation.YearFrac(startDate, runningDate)); //, calendarBasis);
            rows.Add(rowInterest);
            NumberOfInstallments = 1;

            // arrangementRequest.InstallmentPlan = rows;
            CalculateAPR(rows);
        }
        //No variations, calc rates should be as they are set in the request
        //Rate is within limits
        public void IterativeNoVariationsRateAboveLimitBasedOnMarketRate()
        {
            var OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            InterestRateCondition regularInterestEuribor = new InterestRateCondition
            {
                //This base rate id removes -1.5 from spreadRateValue, making rate under limit
                Kind = InterestRateKinds.RegularInterest,
                Rate = new InterestRate
                {
                    BaseRateId      = "EURIBOR-4M",
                    SpreadRateValue = 17
                },
                UpperLimit = new InterestRate
                {
                    BaseRateId      = "EURIBOR-6M",
                    SpreadRateValue = 18
                },
                LowerLimit = new InterestRate
                {
                    BaseRateId      = "EURIBOR-6M",
                    SpreadRateValue = 10
                },
                Title      = "regular-interest",
                Currencies = new List <string> {
                    "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees          = new List <FeeCondition> {
                },
                InterestRates = new List <InterestRateCondition> {
                    regularInterestEuribor
                }
            };
            var arrangementRequest = Utility.GetArangementRequest(conditions);

            Application application = new Application
            {
                ArrangementNumber = "1",
                CustomerName      = "Tester",
                StatusInformation = new StatusInformation
                {
                    Description = "Works as a tester"
                },
                CustomerSegment = "student",
                CollateralModel = "two-co-debtors",

                RiskScore   = 55,
                ChannelCode = "web",
                RequestDate = DateTime.Now
            };

            var result         = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);
            var resultInterest = result.Result.Conditions.InterestRates[0];

            //Basic assertions
            Assert.Equal("RanToCompletion", result.Status.ToString());
            Assert.Equal("0", resultInterest.Variations.Count.ToString());

            //Asserting input parameters
            Assert.Equal("EURIBOR-4M", resultInterest.Rate.BaseRateId);
            Assert.Equal(2, resultInterest.Rate.BaseRateValue);
            Assert.Equal(17, resultInterest.Rate.SpreadRateValue);

            Assert.Equal("EURIBOR-6M", resultInterest.UpperLimit.BaseRateId);
            Assert.Equal(0, resultInterest.UpperLimit.BaseRateValue);
            Assert.Equal((decimal)18.0, resultInterest.UpperLimit.SpreadRateValue);

            Assert.Equal("EURIBOR-6M", resultInterest.LowerLimit.BaseRateId);
            Assert.Equal(0, resultInterest.LowerLimit.BaseRateValue);
            Assert.Equal((decimal)10.0, resultInterest.LowerLimit.SpreadRateValue);

            //Asserting Napr and calculation results
            Assert.Equal((decimal)18.0, ((TermLoanRequest)result.Result).Napr);
            Assert.Equal((decimal)18.0, resultInterest.CalculatedRate);
            Assert.Equal((decimal)10.0, resultInterest.CalculatedLowerLimit);
            Assert.Equal((decimal)18.0, resultInterest.CalculatedUpperLimit);
        }