public Optional<RecommendedLoan> recommend(final int toInvest) { return recommend(toInvest, false); }
public Optional<RecommendedLoan> recommend(final int toInvest) { return recommend(toInvest, false); }
@Override public Optional<RecommendedLoan> recommend(final BigDecimal toInvest) { return recommend(toInvest.intValue()); } }
@Override public Optional<RecommendedLoan> recommend(final BigDecimal toInvest) { return recommend(toInvest.intValue()); } }
private static RecommendedLoan getRecommendation(final Remote confirmation, final Captcha captcha) { final LoanDescriptor ld = InvestorTest.mockLoanDescriptor(captcha == InvestorTest.Captcha.PROTECTED); return ld.recommend(InvestorTest.CONFIRMED_AMOUNT, confirmation == InvestorTest.Remote.CONFIRMED).get(); }
private static InvestmentStrategy mockStrategy(final int loanToRecommend, final int recommend) { return (l, p, r) -> l.stream() .filter(i -> i.item().getId() == loanToRecommend) .flatMap(i -> i.recommend(BigDecimal.valueOf(recommend)).map(Stream::of).orElse(Stream.empty())); }
@Override public Stream<RecommendedLoan> recommend(final Collection<LoanDescriptor> loans, final PortfolioOverview portfolio, final Restrictions restrictions) { if (!Util.isAcceptable(strategy, portfolio)) { return Stream.empty(); } // split available marketplace into buckets per rating final Map<Rating, List<LoanDescriptor>> splitByRating = Util.sortByRating(strategy.getApplicableLoans(loans), d -> d.item().getRating()); // and now return recommendations in the order in which investment should be attempted final BigDecimal balance = portfolio.getCzkAvailable(); final InvestmentSizeRecommender recommender = new InvestmentSizeRecommender(strategy, restrictions); return Util.rankRatingsByDemand(strategy, splitByRating.keySet(), portfolio) .peek(rating -> Decisions.report(logger -> logger.trace("Processing rating {}.", rating))) .flatMap(rating -> splitByRating.get(rating).stream().sorted(COMPARATOR)) .peek(d -> Decisions.report(logger -> logger.trace("Evaluating {}.", d.item()))) .flatMap(d -> { // recommend amount to invest per strategy final int recommendedAmount = recommender.apply(d.item(), balance.intValue()); if (recommendedAmount > 0) { return d.recommend(recommendedAmount, needsConfirmation(d)) .map(Stream::of) .orElse(Stream.empty()); } else { return Stream.empty(); } }); } }
@Override public Stream<RecommendedLoan> recommend(final Collection<LoanDescriptor> loans, final PortfolioOverview portfolio, final Restrictions restrictions) { if (!Util.isAcceptable(strategy, portfolio)) { return Stream.empty(); } // split available marketplace into buckets per rating final Map<Rating, List<LoanDescriptor>> splitByRating = Util.sortByRating(strategy.getApplicableLoans(loans), d -> d.item().getRating()); // and now return recommendations in the order in which investment should be attempted final BigDecimal balance = portfolio.getCzkAvailable(); final InvestmentSizeRecommender recommender = new InvestmentSizeRecommender(strategy, restrictions); return Util.rankRatingsByDemand(strategy, splitByRating.keySet(), portfolio) .peek(rating -> Decisions.report(logger -> logger.trace("Processing rating {}.", rating))) .flatMap(rating -> splitByRating.get(rating).stream().sorted(COMPARATOR)) .peek(d -> Decisions.report(logger -> logger.trace("Evaluating {}.", d.item()))) .flatMap(d -> { // recommend amount to invest per strategy final int recommendedAmount = recommender.apply(d.item(), balance.intValue()); if (recommendedAmount > 0) { return d.recommend(recommendedAmount, needsConfirmation(d)) .map(Stream::of) .orElse(Stream.empty()); } else { return Stream.empty(); } }); } }
@Test void investmentFromAmountlessConfirmation() { final LoanDescriptor ld = mockLoanDescriptor(); final int recommended = 200; final Investment i = Investor.convertToInvestment(ld.recommend(recommended).get()); assertThat(i.getOriginalPrincipal().intValue()).isEqualTo(recommended); } }
private static RecommendedLoan recommendedLoan() { final Loan loan = Loan.custom().setNonReservedRemainingInvestment(2000).build(); return new LoanDescriptor(loan).recommend(200).orElse(null); }
@Test void underBalance() { // setup APIs final Zonky z = harmlessZonky(199); final PowerTenant auth = mockTenant(z); // run test final InvestingSession it = new InvestingSession(Collections.emptySet(), getInvestor(auth), auth); final Optional<RecommendedLoan> recommendation = mockLoanDescriptor() .recommend(BigDecimal.valueOf(200)); final boolean result = it.invest(recommendation.get()); // verify result assertThat(result).isFalse(); final List<Event> newEvents = getEventsRequested(); assertThat(newEvents).isEmpty(); }
@Test void recommendWrongAmount() { final Loan mockedLoan = LoanDescriptorTest.mockLoan(); final LoanDescriptor ld = new LoanDescriptor(mockedLoan); final Optional<RecommendedLoan> r = ld.recommend(BigDecimal.valueOf(mockedLoan.getNonReservedRemainingInvestment() + 1)); assertThat(r).isEmpty(); } }
@Test void underAmount() { final Zonky z = harmlessZonky(0); final PowerTenant auth = mockTenant(z); final RecommendedLoan recommendation = mockLoanDescriptor().recommend(200).get(); final InvestingSession t = new InvestingSession(Collections.singleton(recommendation.descriptor()), getInvestor(auth), auth); final boolean result = t.invest(recommendation); // verify result assertThat(result).isFalse(); final List<Event> newEvents = getEventsRequested(); assertThat(newEvents).isEmpty(); }
@Test void recommendAmount() { final Loan mockedLoan = LoanDescriptorTest.mockLoan(); final LoanDescriptor ld = new LoanDescriptor(mockedLoan); final Optional<RecommendedLoan> r = ld.recommend(200); assertThat(r).isPresent(); final RecommendedLoan recommendation = r.get(); assertSoftly(softly -> { softly.assertThat(recommendation.descriptor()).isSameAs(ld); softly.assertThat(recommendation.amount()).isEqualTo(BigDecimal.valueOf(200)); softly.assertThat(recommendation.isConfirmationRequired()).isFalse(); }); }