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);
        }
 public InitiateOnlineOfferCommandHandler(IMediator mediator,
                                          IApplicationRepository applicationRepository,
                                          IEventBus eventBus,
                                          ILogger <InitiateOnlineOfferCommand> logger,
                                          OfferPriceCalculation priceCalculator,
                                          IConfigurationService configurationService,
                                          IContentService contentService,
                                          MessageEventFactory messageEventFactory,
                                          IMasterPartyDataService partyDataService,
                                          ApplicationDocumentsResolver applicationDocumentsResolver,
                                          OfferUtility offerUtility,
                                          ArrangementRequestFactory requestFactory,
                                          IAuditClient auditClient
                                          )
 {
     _applicationRepository = applicationRepository;
     _mediator             = mediator ?? throw new ArgumentNullException(nameof(mediator));
     _eventBus             = eventBus ?? throw new ArgumentNullException(nameof(eventBus));
     _logger               = logger ?? throw new ArgumentNullException(nameof(logger));
     _priceCalculator      = priceCalculator;
     _messageEventFactory  = messageEventFactory;
     _configurationService = configurationService ?? throw new ArgumentNullException(nameof(configurationService));
     _contentService       = contentService ?? throw new ArgumentNullException(nameof(contentService));
     _partyDataService     = partyDataService;
     _documentsResolver    = applicationDocumentsResolver ?? throw new ArgumentNullException(nameof(applicationDocumentsResolver));
     _offerUtility         = offerUtility ?? throw new ArgumentNullException(nameof(offerUtility));
     _requestFactory       = requestFactory ?? throw new ArgumentNullException(nameof(requestFactory));
     _auditClient          = auditClient ?? throw new ArgumentNullException(nameof(auditClient));
 }
        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);
        }
Beispiel #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);
        }
        //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);
        }
 public override void CalculateOffer(Application application, OfferPriceCalculation priceCalculator, string conversionMethod)
 {
     //if (!ValidateParameters(this))
     //{
     //    // do something man !!!
     //}
     //
     _ = priceCalculator.CalculatePrice(application, this).Result;
     CalculateInstallmentPlan(conversionMethod);
 }
Beispiel #7
0
 public ArrangementRequestFactory(IConfigurationService configurationService,
                                  IProductService productService,
                                  IArrangementService arrangementService,
                                  ICampaignService campaignService,
                                  ILogger <ArrangementRequestFactory> logger,
                                  OfferPriceCalculation priceCalculator,
                                  CalculatorProvider calculatorProvider,
                                  IProductSnapshotRepository productSnapshotRepository)
 {
     _configurationService = configurationService ?? throw new ArgumentNullException(nameof(configurationService));
     _productService       = productService ?? throw new ArgumentNullException(nameof(productService));
     _arrangementService   = arrangementService ?? throw new ArgumentNullException(nameof(arrangementService));
     _campaignService      = campaignService ?? throw new ArgumentNullException(nameof(campaignService));
     _logger                    = logger ?? throw new ArgumentNullException(nameof(logger));
     _calculatorProvider        = calculatorProvider ?? throw new ArgumentNullException(nameof(calculatorProvider));
     _priceCalculator           = priceCalculator ?? throw new ArgumentNullException(nameof(priceCalculator));
     _productSnapshotRepository = productSnapshotRepository ?? throw new ArgumentNullException(nameof(productSnapshotRepository));
 }
        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);
        }
Beispiel #9
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);
        }
Beispiel #10
0
 public ArrangementRequestRepository(OfferDBContext context, IConfigurationService configurationService,
                                     ApplicationDocumentsResolver documentsResolver, OfferPriceCalculation priceCalculator,
                                     MessageEventFactory messageEventFactory, IEventBus bus, ILogger <ArrangementRequestRepository> logger,
                                     IApplicationRepository applicationRepository,
                                     ArrangementRequestFactory requestFactory,
                                     IProductSnapshotRepository productSnapshotRepository)
 {
     _context = context ?? throw new ArgumentNullException(nameof(context));
     _configurationService = configurationService ?? throw new ArgumentNullException(nameof(configurationService));
     _documentsResolver    = documentsResolver ?? throw new ArgumentNullException(nameof(documentsResolver));
     _priceCalculator      = priceCalculator ?? throw new ArgumentNullException(nameof(priceCalculator));
     _messageEventFactory  = messageEventFactory ?? throw new ArgumentNullException(nameof(messageEventFactory));
     _bus            = bus ?? throw new ArgumentNullException(nameof(bus));
     _logger         = logger ?? throw new ArgumentNullException(nameof(logger));
     _requestFactory = requestFactory ?? throw new ArgumentNullException(nameof(requestFactory));
     //_auditClient = auditClient ?? throw new ArgumentNullException(nameof(auditClient));
     _applicationRepository     = applicationRepository ?? throw new ArgumentNullException(nameof(applicationRepository));
     _productSnapshotRepository = productSnapshotRepository ?? throw new ArgumentNullException(nameof(productSnapshotRepository));
 }
Beispiel #11
0
 public UpdateArrangementRequestCommandHandler(IMediator mediator,
                                               IArrangementRequestRepository arrangementRequestRepository,
                                               IConfigurationService configurationService,
                                               OfferPriceCalculation priceCalculator,
                                               IApplicationRepository applicationRepository,
                                               ILogger <UpdateArrangementRequestCommand> logger,
                                               CalculatorProvider calculatorProvider,
                                               IAuditClient auditClient,
                                               MessageEventFactory messageEventFactory,
                                               IEventBus eventBus)
 {
     this._arrangementRequestRepository = arrangementRequestRepository;
     this._applicationRepository        = applicationRepository;
     _mediator                  = mediator ?? throw new ArgumentNullException(nameof(mediator));
     this.priceCalculator       = priceCalculator;
     this._configurationService = configurationService ?? throw new ArgumentNullException(nameof(configurationService));
     _logger              = logger ?? throw new ArgumentNullException(nameof(logger));
     _calculatorProvider  = calculatorProvider ?? throw new ArgumentNullException(nameof(calculatorProvider));
     _auditClient         = auditClient ?? throw new ArgumentNullException(nameof(auditClient));
     _messageEventFactory = messageEventFactory ?? throw new ArgumentNullException(nameof(messageEventFactory));
     _eventBus            = eventBus ?? throw new ArgumentNullException(nameof(eventBus));
 }
Beispiel #12
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);
        }
 public override void CalculateOffer(PriceCalculationParameters calculationParameters,
                                     OfferPriceCalculation priceCalculator, string conversionMethod)
 {
     _ = priceCalculator.CalculatePrice(this, calculationParameters).Result;
     CalculateInstallmentPlan(conversionMethod);
 }
Beispiel #14
0
 public InitiatePriceCalculationCommandHandler(
     OfferPriceCalculation priceCalculator, IPriceCalculationService priceCalculation)
 {
     this._priceCalculator  = priceCalculator ?? throw new ArgumentNullException(nameof(priceCalculator));
     this._priceCalculation = priceCalculation ?? throw new ArgumentNullException(nameof(priceCalculation));
 }
        //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);
        }
Beispiel #16
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);
        }
Beispiel #17
0
 public virtual void CalculateOffer(PriceCalculationParameters calculationParameters, OfferPriceCalculation priceCalculator, string conversionMethod)
 {
     // To be implemented for each arrangement request subtype
 }
Beispiel #18
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);
        }
        //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);
        }
        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);
        }
        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);
        }
        //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);
        }
        //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);
        }
Beispiel #25
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);
        }