package tests; import java.time.LocalDate; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.stream.Collectors; import data.TestDatabase; import objects.League; import objects.SoccerMatch; import objects.SoccerMatchAnalysis; import objects.bets.AsianHandicap; import objects.bets.Bet; import tests.objects.LeagueDTO; public class AnalysisBettDrawTester extends TestClass { public class DifferenceAsianBetDTO extends AsianHandicap { boolean resolved = false; public DifferenceAsianBetDTO(SoccerMatch match, float betAmount, boolean betOnHomeTeam, float handicap) { super(match, betOnHomeTeam ? "1" : "2", betAmount, betOnHomeTeam ? match.getOdds1() : match.getOdds2(), handicap); } @Override public String toString() { return String.format( "%s \t%s - %s \t\tbet amount %s \todds %s \twinner %s \t result %s-%s \tdiff %s with results %s", getMatch().getGameDate().toLocalDate(), getMatch().getHomeTeamName(), getMatch().getAwayTeamName(), getBetAmount(), super.getBetOdds(), super.isBetOnHomeTeam() ? "1" : "2", getMatch().getHomeScore(), getMatch().getAwayScore(), getMatch().getGoalsDiff(), getResult()); } } public class DifferenceBetDTO extends Bet { boolean resolved = false; public DifferenceBetDTO(SoccerMatch match, float betAmount, boolean betOnHomeTeam) { super(0, match, betOnHomeTeam ? "1" : "2", betAmount, betOnHomeTeam ? match.getOdds1() : match.getOdds2()); } @Override public String toString() { return String.format("%s \t%s - %s \t\tbet amount %s \todds %s \twinner %s \t result %s-%s \tdiff %s", getMatch().getGameDate().toLocalDate(), getMatch().getHomeTeamName(), getMatch().getAwayTeamName(), getBetAmount(), super.getBetOdds(), super.isBetOnHomeTeam() ? "1" : "2", getMatch().getHomeScore(), getMatch().getAwayScore(), getMatch().getGoalsDiff()); } } class LocalSoccerMatch extends SoccerMatch { String decider; SoccerMatch match; public LocalSoccerMatch(SoccerMatch match, String decider) { this.decider = decider; this.match = match; } } Map> placedBets = new HashMap<>(); TestDatabase database; List betsToPlace = new ArrayList<>(); float betAmount; List bets = new ArrayList<>(); int wins = 0; int losses = 0; float bank; private List betSeries = new ArrayList<>(); private League leagueInfo; private int betsLost = 0; @Override public void runTest() { bank = startingBank; database = TestDatabase.getInstance(); leagueInfo = database.getLeagueInfo(leagueId); LeagueDTO leagueDTO = database.getLeagueDTO(leagueId); LinkedHashMap> matches = getMatchesOrderedBySeason(leagueDTO); this.betAmount = startingBank * (bettingLevel / 100.0f); boolean skipFirst = false; for (Entry> seasonMatches : matches.entrySet()) { wins = 0; losses = 0; bank = startingBank; placedBets.clear(); if (skipFirst) { skipFirst = false; continue; } analyze(seasonMatches.getValue()); printResults(); System.out .println( String.format(seasonMatches.getKey() + " Wins %s Losses %s %s total bank: %s", wins, losses, wins / (float) (wins + losses) + "%", bank)); // break; } } private void addBet(SoccerMatch match, String deciders) { betsToPlace.add(new LocalSoccerMatch(match, deciders)); } private void analyze(List seasonMatches) { LocalDate currentMatchDate = seasonMatches.get(0).getGameDate().toLocalDate(); for (SoccerMatch match : seasonMatches) { if (currentMatchDate.isBefore(match.getGameDate().toLocalDate())) { placeBets(); checkBetResults(); betAmount = bank * (bettingLevel / 100.0f); } SoccerMatchAnalysis analysis = new SoccerMatchAnalysis(match); int homeTotalGoals = analysis.scoringTotal(leagueInfo.getDrawTotalGoals(), true); int awayTotalGoals = analysis.scoringTotal(leagueInfo.getDrawTotalGoals(), false); int totalGoalsDecider = homeTotalGoals - awayTotalGoals; int homeTotalGoalsHomeAway = analysis.goalsScoredHomeAndAway(true, leagueInfo.getDrawDiffHomeAway()); int awayTotalGoalsHomeAway = analysis.goalsScoredHomeAndAway(false, leagueInfo.getDrawDiffHomeAway()); int totalGoalsHomeAwayDecider = homeTotalGoalsHomeAway - awayTotalGoalsHomeAway; int homeFormHomeAndAway = analysis.winLossRationHomeAndAway(true, leagueInfo.getDrawWinningFormHomeAway()); int awayFormHomeAndAway = analysis.winLossRationHomeAndAway(false, leagueInfo.getDrawWinningFormHomeAway()); int formHomeAwayDecider = homeFormHomeAndAway - awayFormHomeAndAway; int homeWiningForm = analysis.winLossRatio(leagueInfo.getDrawWinningForm(), true); int awayWiningForm = analysis.winLossRatio(leagueInfo.getDrawWinningForm(), false); int winningFormDecider = homeWiningForm - awayWiningForm; // if (totalGoalsDecider == 0 && totalGoalsHomeAwayDecider == 0 && formHomeAwayDecider == 0 // && winningFormDecider == 0) { // addBet(match, "ALL"); // } else if (totalGoalsDecider == 0 && totalGoalsHomeAwayDecider == 0 && formHomeAwayDecider == 0) { // addBet(match, "NOT winningFormDecider"); // } else if (totalGoalsDecider == 0 && totalGoalsHomeAwayDecider == 0 && winningFormDecider == 0) { // addBet(match, "NOT formHomeAwayDecider"); // } else if (totalGoalsDecider == 0 && formHomeAwayDecider == 0 && winningFormDecider == 0) { // addBet(match, "NOT totalGoalsHomeAwayDecider"); // } else if (totalGoalsHomeAwayDecider == 0 && formHomeAwayDecider == 0 && winningFormDecider == 0) { // addBet(match, "NOT totalGoalsDecider"); // } else if (totalGoalsDecider == 0 && totalGoalsHomeAwayDecider == 0) { addBet(match, "totalGoalsDecider, totalGoalsHomeAwayDecider"); } else if (totalGoalsDecider == 0 && formHomeAwayDecider == 0) { addBet(match, "totalGoalsDecider, formHomeAwayDecider"); } else if (totalGoalsDecider == 0 && winningFormDecider == 0) { addBet(match, "totalGoalsDecider, winningFormDecider"); } else if (totalGoalsHomeAwayDecider == 0 && formHomeAwayDecider == 0) { addBet(match, "totalGoalsHomeAwayDecider, formHomeAwayDecider"); } else if (totalGoalsHomeAwayDecider == 0 && winningFormDecider == 0) { addBet(match, "totalGoalsHomeAwayDecider, winningFormDecider"); } else if (formHomeAwayDecider == 0 && winningFormDecider == 0) { addBet(match, "formHomeAwayDecider, winningFormDecider"); // } else if (totalGoalsDecider == 0) { // addBet(match, "totalGoalsDecider"); // } else if (totalGoalsHomeAwayDecider == 0) { // addBet(match, "totalGoalsHomeAwayDecider"); // } else if (formHomeAwayDecider == 0) { // addBet(match, "formHomeAwayDecider"); // } else if (winningFormDecider == 0) { // addBet(match, "winningFormDecider"); } currentMatchDate = match.getGameDate().toLocalDate(); } } private void checkBetResults() { placedBets.forEach((decider, betList) -> { List activeBets = betList.stream().filter(b -> !b.resolved).toList(); for (Bet bet : activeBets) { if (bet.getHomeScore() == bet.getAwayScore()) { bank += bet.getBetAmount() * bet.getBetOdds(); wins++; } else { losses++; betSeries.add(bet); } bet.setResolved(true); } }); /*- OLD checkBetResults left for inspiration List activeBets = bets.stream().filter(p -> !p.resolved).toList(); for (DifferenceBetDTO bet : activeBets) { if (bet.getResult() > 0) { bank += bet.getResult(); // bet.getBetAmount() * bet.getBetOdds(); String winText = bet.correctBet() ? bet.isBetOnHomeTeam() ? "HOME WIN " : "AWAY WIN" : "HALF WIN"; System.out.println(String.format(winText + "\t" + "%s \t\tnew bank %s", bet, bank)); wins++; } else { // LOSS System.out.println(String.format("LOSS\t\t%s \t\t bank: %s", bet, bank)); losses++; betSeries.add(bet); } bet.resolved = true; } if (!betSeries.isEmpty()) { System.out.println("Outstanding bets:"); betSeries.forEach(b -> System.out.println(b)); } */ } private void placeBets() { for (LocalSoccerMatch soccerMatch : betsToPlace) { Bet bet = new Bet(-1, soccerMatch.match, "X", betAmount, soccerMatch.match.getOddsX()); if (!betSeries.isEmpty()) { betSeries.sort((b1, b2) -> Float.compare(b2.getBetAmount(), b1.getBetAmount())); bet.setBetAmount(bet.getBetAmount() + betSeries.get(0).getBetAmount()); betSeries.remove(0); } bank -= bet.getBetAmount(); List betsList = placedBets.get(soccerMatch.decider); if (betsList == null) { betsList = new ArrayList<>(); } betsList.add(bet); placedBets.put(soccerMatch.decider, betsList); // För att täcka upp föregående bets // float currentBetAmount = 0; //// betSeries.sort((b1, b2) -> Float.compare(b2.getBetAmount(), b1.getBetAmount())); // if (!betSeries.isEmpty() && !betsToPlace.isEmpty()) { // currentBetAmount += betSeries.get(0).getBetAmount(); // betSeries.remove(0); // } // if (soccerMatch.getGoalsDiff().floatValue() > 0f) { // if (currentBetAmount > 0) { // currentBetAmount = (float) (currentBetAmount / (soccerMatch.getOdds1() - 1.0)); // } // bets.add(new DifferenceBetDTO(soccerMatch, currentBetAmount + betAmount, true)); // } else if (soccerMatch.getGoalsDiff().floatValue() < 0f) { // if (currentBetAmount > 0) { // currentBetAmount = (float) (currentBetAmount / (soccerMatch.getOdds2() - 1.0)); // } // bets.add(new DifferenceBetDTO(soccerMatch, currentBetAmount + betAmount, false)); // } // // bank -= currentBetAmount + betAmount; } betsToPlace.clear(); } private void printResults() { placedBets.forEach((decider, bets) -> { List correctBets = bets.stream().filter(p -> p.getHomeScore() == p.getAwayScore()).toList(); Double winnings = correctBets.stream() .collect(Collectors.summingDouble(d -> (double) d.getBetAmount() * (double) d.getBetOdds())); Double totalBetAmount = bets.stream().collect(Collectors.summingDouble(Bet::getBetAmount)); System.out.println(decider + " total matches betted " + bets.size() + " correct " + correctBets.size() + " " + (correctBets.size() / (float) bets.size()) * 100 + "% total cost " + totalBetAmount + " totalWinnings " + winnings + " sum " + (winnings - totalBetAmount) + System.lineSeparator()); }); } }