NaturalLanguageInvestmentStrategy implements InvestmentStrategy { @Override public Stream<RecommendedLoan> recommend(final Collection<LoanDescriptor> available, final PortfolioOverview portfolio, final SessionInfo sessionInfo) { if (!Util.isAcceptable(strategy, portfolio)) { return Stream.empty(); } var preferences = Preferences.get(strategy, portfolio); var withoutUndesirable = available.parallelStream() .peek(d -> LOGGER.trace("Evaluating {}.", d.item())) .filter(d -> { boolean isAcceptable = preferences.getDesirableRatings() .contains(d.item() .getRating()); if (!isAcceptable) { LOGGER.debug("Loan #{} skipped due to an undesirable rating.", d.item() .getId()); } return isAcceptable; }); return strategy.getApplicableLoans(withoutUndesirable, portfolio) .sorted(preferences.getPrimaryMarketplaceComparator()) .flatMap(d -> { final Money recommendedAmount = recommender.apply(d.item(), sessionInfo); if (recommendedAmount.compareTo(recommendedAmount.getZero()) > 0) { return d.recommend(recommendedAmount) .stream(); } else { return Stream.empty(); } }); } NaturalLanguageInvestmentStrategy(final ParsedStrategy p); @Override Stream<RecommendedLoan> recommend(final Collection<LoanDescriptor> available,
            final PortfolioOverview portfolio, final SessionInfo sessionInfo);  }
@Test void unacceptablePortfolioDueToOverInvestment() { final DefaultValues v = new DefaultValues(DefaultPortfolio.EMPTY); v.setTargetPortfolioSize(1000); final ParsedStrategy p = new ParsedStrategy(v, Collections.emptyList(), Collections.emptyMap(), Collections.emptyMap()); final InvestmentStrategy s = new NaturalLanguageInvestmentStrategy(p); final PortfolioOverview portfolio = mock(PortfolioOverview.class); when(portfolio.getInvested()).thenReturn(p.getMaximumInvestmentSize()); final Stream<RecommendedLoan> result = s.recommend(Collections.singletonList(new LoanDescriptor(mockLoan(2))), portfolio, mockSessionInfo()); assertThat(result).isEmpty(); }
@Test void noLoansApplicable() { final MarketplaceFilter filter = MarketplaceFilter.of(MarketplaceFilterCondition.alwaysAccepting()); final ParsedStrategy p = new ParsedStrategy(DefaultPortfolio.PROGRESSIVE, Collections.singleton(filter)); final InvestmentStrategy s = new NaturalLanguageInvestmentStrategy(p); final PortfolioOverview portfolio = mock(PortfolioOverview.class); when(portfolio.getShareOnInvestment(any())).thenReturn(Ratio.ZERO); when(portfolio.getInvested()).thenReturn(p.getMaximumInvestmentSize() .subtract(1)); final Stream<RecommendedLoan> result = s.recommend(Collections.singletonList(new LoanDescriptor(mockLoan(2))), portfolio, mockSessionInfo()); assertThat(result).isEmpty(); }
@Test void nothingRecommendedDueToRatingOverinvested() { final ParsedStrategy p = new ParsedStrategy(DefaultPortfolio.PROGRESSIVE, Collections.emptySet()); final InvestmentStrategy s = new NaturalLanguageInvestmentStrategy(p); final PortfolioOverview portfolio = mock(PortfolioOverview.class); when(portfolio.getShareOnInvestment(any())).thenReturn(Ratio.ZERO); when(portfolio.getInvested()).thenReturn(p.getMaximumInvestmentSize() .subtract(1)); final LoanImpl l = mockLoan(1000); final Rating r = l.getRating(); when(portfolio.getShareOnInvestment(eq(r))).thenReturn(Ratio.fromPercentage("100")); final Stream<RecommendedLoan> result = s.recommend(Collections.singletonList(new LoanDescriptor(l)), portfolio, mockSessionInfo()); assertThat(result).isEmpty(); }
@Test void recommendationIsMade() { final ParsedStrategy p = new ParsedStrategy(DefaultPortfolio.PROGRESSIVE, Collections.emptySet()); final InvestmentStrategy s = new NaturalLanguageInvestmentStrategy(p); final PortfolioOverview portfolio = mock(PortfolioOverview.class); when(portfolio.getInvested()).thenReturn(p.getMaximumInvestmentSize() .subtract(1)); when(portfolio.getShareOnInvestment(any())).thenReturn(Ratio.ZERO); final LoanImpl l = mockLoan(100_000); final LoanImpl l2 = mockLoan(100); final LoanDescriptor ld = new LoanDescriptor(l); final List<RecommendedLoan> result = s .recommend(Arrays.asList(new LoanDescriptor(l2), ld), portfolio, mockSessionInfo()) .collect(Collectors.toList()); assertThat(result).hasSize(1); final RecommendedLoan r = result.get(0); assertSoftly(softly -> { softly.assertThat(r.descriptor()) .isEqualTo(ld); softly.assertThat(r.amount()) .isEqualTo(Money.from(20_000)); }); }