Procházet zdrojové kódy

New statistics calculations

Axel Nordh před 1 rokem
rodič
revize
a1c272b46f

+ 396 - 121
OddsJavaFx/src/controllers/StatisticsTabController.java

@@ -1,15 +1,9 @@
 package controllers;
 
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.ResourceBundle;
-
 import data.GuiMysql;
 import javafx.collections.FXCollections;
 import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
 import javafx.fxml.FXML;
 import javafx.fxml.Initializable;
 import javafx.scene.control.SelectionMode;
@@ -17,120 +11,401 @@ import javafx.scene.control.TableColumn;
 import javafx.scene.control.TableView;
 import javafx.scene.control.TableView.TableViewSelectionModel;
 import javafx.scene.control.cell.MapValueFactory;
+import objects.League;
 import objects.OverUnder;
+import objects.SoccerMatch;
+import objects.SoccerMatchAnalysis;
+
+import java.net.URL;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@SuppressWarnings("rawtypes")
+public class StatisticsTabController implements Initializable {
+
+    @FXML
+    private TableView<Map<String, Object>> statsTable;
+
+    @FXML
+    TableColumn<Map, Float> diffColumn = new TableColumn<>("Diff");
+    @FXML
+    TableColumn<Map, String> u05 = new TableColumn<>("Under 0.5");
+    @FXML
+    TableColumn<Map, String> o05 = new TableColumn<>("Over 0.5");
+    @FXML
+    TableColumn<Map, String> u15 = new TableColumn<>("Under 1.5");
+    @FXML
+    TableColumn<Map, String> o15 = new TableColumn<>("Over 1.5");
+    @FXML
+    TableColumn<Map, String> u25 = new TableColumn<>("Under 2.5");
+    @FXML
+    TableColumn<Map, String> o25 = new TableColumn<>("Over 2.5");
+    @FXML
+    TableColumn<Map, String> u35 = new TableColumn<>("Under 3.5");
+    @FXML
+    TableColumn<Map, String> o35 = new TableColumn<>("Over 3.5");
+    @FXML
+    TableColumn<Map, String> u45 = new TableColumn<>("Under 4.5");
+    @FXML
+    TableColumn<Map, String> o45 = new TableColumn<>("Over 4.5");
+    @FXML
+    TableColumn<Map, String> u55 = new TableColumn<>("Under 5.5");
+    @FXML
+    TableColumn<Map, String> o55 = new TableColumn<>("Over 5.5");
+    @FXML
+    TableColumn<Map, String> u65 = new TableColumn<>("Under 6.5");
+    @FXML
+    TableColumn<Map, String> o65 = new TableColumn<>("Over 6.5");
+
+    private ObservableList<Map<String, Object>> statLines;
+
+    private static StatisticsTabController instance;
+
+    public static StatisticsTabController getInstance() {
+        if (instance == null) {
+            synchronized (StatisticsTabController.class) {
+                if (instance == null) {
+                    instance = new StatisticsTabController();
+                }
+            }
+        }
+        return instance;
+    }
+
+    @Override
+    public void initialize(URL arg0, ResourceBundle arg1) {
+        diffColumn.setCellValueFactory(new MapValueFactory<>("diff"));
+        u05.setCellValueFactory(new MapValueFactory<>("u05"));
+        o05.setCellValueFactory(new MapValueFactory<>("o05"));
+        u15.setCellValueFactory(new MapValueFactory<>("u15"));
+        o15.setCellValueFactory(new MapValueFactory<>("o15"));
+        u25.setCellValueFactory(new MapValueFactory<>("u25"));
+        o25.setCellValueFactory(new MapValueFactory<>("o25"));
+        u35.setCellValueFactory(new MapValueFactory<>("u35"));
+        o35.setCellValueFactory(new MapValueFactory<>("o35"));
+        u45.setCellValueFactory(new MapValueFactory<>("u45"));
+        o45.setCellValueFactory(new MapValueFactory<>("o45"));
+        u55.setCellValueFactory(new MapValueFactory<>("u55"));
+        o55.setCellValueFactory(new MapValueFactory<>("o55"));
+        u65.setCellValueFactory(new MapValueFactory<>("u65"));
+        o65.setCellValueFactory(new MapValueFactory<>("o65"));
+
+        statLines = FXCollections.<Map<String, Object>>observableArrayList();
+        instance = this;
+    }
+
+    public void setOverUnderTable(int leagueId, String gameDate) {
+        final List<OverUnder> statsOverUnder = GuiMysql.getInstance().getStatsOverUnder(leagueId, gameDate);
+
+        statLines.clear();
+        for (final OverUnder ou : statsOverUnder) {
+            final Map<String, Object> line = new HashMap<>();
+            if (statLines.stream().noneMatch(p -> p.get("diff") == ou.getKey())) {
+                line.put("diff", ou.getKey());
+                line.put("u05", ou.getGoals().get(0) + " (" + ou.calcMinOdds(ou.getGoals().get(0)) + ")");
+                line.put("o05", getOverStat(ou, 1) + " (" + ou.calcMinOdds(getOverStat(ou, 1)) + ")");
+                line.put("u15", getUnderStat(ou, 2) + " (" + ou.calcMinOdds(getUnderStat(ou, 2)) + ")");
+                line.put("o15", getOverStat(ou, 2) + " (" + ou.calcMinOdds(getOverStat(ou, 2)) + ")");
+                line.put("u25", getUnderStat(ou, 3) + " (" + ou.calcMinOdds(getUnderStat(ou, 3)) + ")");
+                line.put("o25", getOverStat(ou, 3) + " (" + ou.calcMinOdds(getOverStat(ou, 3)) + ")");
+                line.put("u35", getUnderStat(ou, 4) + " (" + ou.calcMinOdds(getUnderStat(ou, 4)) + ")");
+                line.put("o35", getOverStat(ou, 4) + " (" + ou.calcMinOdds(getOverStat(ou, 4)) + ")");
+                line.put("u45", getUnderStat(ou, 5) + " (" + ou.calcMinOdds(getUnderStat(ou, 5)) + ")");
+                line.put("o45", getOverStat(ou, 5) + " (" + ou.calcMinOdds(getOverStat(ou, 5)) + ")");
+                line.put("u55", getUnderStat(ou, 6) + " (" + ou.calcMinOdds(getUnderStat(ou, 6)) + ")");
+                line.put("o55", getOverStat(ou, 6) + " (" + ou.calcMinOdds(getOverStat(ou, 6)) + ")");
+                line.put("u65", getUnderStat(ou, 7) + " (" + ou.calcMinOdds(getUnderStat(ou, 7)) + ")");
+                line.put("o65", getOverStat(ou, 7) + " (" + ou.calcMinOdds(getOverStat(ou, 7)) + ")");
+
+                statLines.add(line);
+            }
+        }
+        statsTable.getItems().clear();
+        statsTable.getItems().addAll(statLines);
+        diffColumn.setSortable(true);
+    }
+
+    private int getUnderStat(OverUnder ou, float atMostXGoals) {
+        final ArrayList<Integer> goals = ou.getGoals();
+        int sum = 0;
+        for (int i = 0; i < (goals.size() < atMostXGoals ? goals.size() : atMostXGoals); i++) {
+            sum += goals.get(i);
+        }
+        return sum;
+    }
+
+    private int getOverStat(OverUnder ou, int atLeastXGoals) {
+        final ArrayList<Integer> goals = ou.getGoals();
+        int sum = 0;
+        for (int i = atLeastXGoals; i < goals.size(); i++) {
+            sum += goals.get(i);
+        }
+        return sum;
+    }
+
+    public void markValueInTable(float value) {
+        TableViewSelectionModel<Map<String, Object>> selectionModel = statsTable.getSelectionModel();
+        java.util.Optional<Map<String, Object>> optional = statsTable.getItems().stream().filter(p -> (Float) p.get("diff") == value).findFirst();
+        if (optional.isPresent()) {
+            selectionModel.setSelectionMode(SelectionMode.SINGLE);
+            int indexOf = statsTable.getItems().indexOf(optional.get());
+            selectionModel.select(indexOf);
+        }
+    }
+
+    public void updateStatisticsScoringTotalAction(ActionEvent event) {
+        List<League> leagues = GuiMysql.getInstance().getLeaguesWithPrio();
+        int soccerId = GuiMysql.getInstance().getSportId("Soccer");
+        for (League l : leagues) {
+            Map<Integer, Map<Integer, ScoringTotalResult>> scoringTotalResultList = new HashMap<>();
+            List<SoccerMatch> soccerMateches = GuiMysql.getInstance().getMatches(soccerId, l.getCountyId(),
+                    l.getLeagueId(), "2020-01-01", "ASC", false, true);
+            List<SoccerMatchAnalysis> analyses = soccerMateches.stream().map(SoccerMatchAnalysis::new).collect(Collectors.toList());
+
+            System.out.println(new Date() + " Running " + analyses.size() + " matches");
+            int c = 0;
+            for (SoccerMatchAnalysis a : analyses) {
+                for (int i = 1; i < 20; i++) {
+                    int homeScore = a.scoringTotal(i, true);
+                    int awayScore = a.scoringTotal(i, false);
+
+                    int diff = homeScore - awayScore;
+
+                    ScoringTotalResult scoringTotalResult = new ScoringTotalResult(i, diff, a.getHomeScore(), a.getAwayScore());
+                    Map<Integer, ScoringTotalResult> lookBackMap = scoringTotalResultList.getOrDefault(i, new HashMap<>());
+                    addNewResult(lookBackMap, scoringTotalResult);
+                    scoringTotalResultList.put(i, lookBackMap);
+                }
+                if (++c % 100 == 0) {
+                    System.out.println(new Date() + " " + c + "/" + analyses.size() + " (" + ((double) c / analyses.size()) * 100 + "%)");
+                }
+            }
+            System.out.println(new Date() + " Done " + l.getLeagueName());
+            handleScoringTotalResults("updateStatisticsScoringTotalAction", l.getLeagueName(), l.getLeagueId(), scoringTotalResultList, "ScoringTotal");
+        }
+
+    }
+
+    private void addNewResult(Map<Integer, ScoringTotalResult> map, ScoringTotalResult scoringTotalResult) {
+        if (map.isEmpty()) {
+            map.put(scoringTotalResult.diff, scoringTotalResult);
+            return;
+        }
+        Optional<Integer> found = map.keySet().stream().filter(p -> p == scoringTotalResult.getDiff()).findFirst();
+        if (found.isPresent()) {
+            ScoringTotalResult sTR = map.get(found.get());
+            sTR.add(scoringTotalResult);
+        } else {
+            map.put(scoringTotalResult.diff, scoringTotalResult);
+        }
+    }
+
+    private void handleScoringTotalResults(String methodName, String leagueName, int leagueId, Map<Integer, Map<Integer, ScoringTotalResult>> scoringTotalResultList, String tableColumnName) {
+
+        float bestHomeWinPercent = 0f;
+        float bestAwayWinPercent = 0f;
+        float bestDrawPercent = 0f;
+
+        int bestHomeWinLookback = 0;
+        int bestAwayWinLookback = 0;
+        int bestDrawLookback = 0;
+
+        for (Map.Entry<Integer, Map<Integer, ScoringTotalResult>> entry : scoringTotalResultList.entrySet()) {
+            Map<Integer, ScoringTotalResult> scoringTotalResults = entry.getValue();
+            List<ScoringTotalResult> positiveValues = scoringTotalResults.entrySet().stream().filter(e -> e.getKey() > 0).map(Map.Entry::getValue).collect(Collectors.toList());
+            List<ScoringTotalResult> negativeValues = scoringTotalResults.entrySet().stream().filter(e -> e.getKey() < 0).map(Map.Entry::getValue).collect(Collectors.toList());
+            List<ScoringTotalResult> zeroValues = scoringTotalResults.entrySet().stream().filter(e -> e.getKey() == 0).map(Map.Entry::getValue).collect(Collectors.toList());
+
+            int posHomeWins = 0;
+            int posAwayWins = 0;
+            int posDraws = 0;
+            for (ScoringTotalResult sr : positiveValues) {
+                posHomeWins += sr.homeWins;
+                posAwayWins += sr.awayWins;
+                posDraws += sr.draws;
+            }
+            float posWinPercent = posHomeWins / (float) (posHomeWins + posAwayWins + posDraws);
+
+            int negHomeWins = 0;
+            int negAwayWins = 0;
+            int negDraws = 0;
+            for (ScoringTotalResult sr : negativeValues) {
+                negHomeWins += sr.homeWins;
+                negAwayWins += sr.awayWins;
+                negDraws += sr.draws;
+            }
+            float negWinPercent = negAwayWins / (float) (negHomeWins + negAwayWins + negDraws);
+
+            int zeroHomeWins = 0;
+            int zeroAwayWins = 0;
+            int zeroDraws = 0;
+            for (ScoringTotalResult sr : zeroValues) {
+                zeroHomeWins += sr.homeWins;
+                zeroAwayWins += sr.awayWins;
+                zeroDraws += sr.draws;
+            }
+            float zeroDrawPercent = zeroDraws / (float) (zeroHomeWins + zeroAwayWins + zeroDraws);
+
+            if (posWinPercent > bestHomeWinPercent) {
+                bestHomeWinPercent = posWinPercent;
+                bestHomeWinLookback = entry.getKey();
+            }
+            if (negWinPercent > bestAwayWinPercent) {
+                bestAwayWinPercent = negWinPercent;
+                bestAwayWinLookback = entry.getKey();
+            }
+            if (zeroDrawPercent > bestDrawPercent) {
+                bestDrawPercent = zeroDrawPercent;
+                bestDrawLookback = entry.getKey();
+            }
+        }
+
+        GuiMysql.getInstance().updateScoringTotalResults(leagueId, bestHomeWinLookback, bestAwayWinLookback, bestDrawLookback, tableColumnName);
+        System.out.println(methodName + " " + leagueName + " Best home win lookback: " + bestHomeWinLookback + " (" + bestHomeWinPercent + ")");
+        System.out.println(methodName + " " + leagueName + " Best away win lookback: " + bestAwayWinLookback + " (" + bestAwayWinPercent + ")");
+        System.out.println(methodName + " " + leagueName + " Best draw lookback: " + bestDrawLookback + " (" + bestDrawPercent + ")");
+    }
+
+    public void updateStatisticsScoringDiffLastGamesAction(ActionEvent actionEvent) {
+        List<League> leagues = GuiMysql.getInstance().getLeaguesWithPrio();
+        int soccerId = GuiMysql.getInstance().getSportId("Soccer");
+        for (League l : leagues) {
+            Map<Integer, Map<Integer, ScoringTotalResult>> scoringTotalResultList = new HashMap<>();
+            List<SoccerMatch> soccerMateches = GuiMysql.getInstance().getMatches(soccerId, l.getCountyId(),
+                    l.getLeagueId(), "2020-01-01", "ASC", false, true);
+            List<SoccerMatchAnalysis> analyses = soccerMateches.stream().map(SoccerMatchAnalysis::new).collect(Collectors.toList());
+
+            System.out.println(new Date() + " Running " + analyses.size() + " matches");
+            int c = 0;
+            for (SoccerMatchAnalysis a : analyses) {
+                for (int i = 1; i < 20; i++) {
+                    int diff = a.getScoringDiffLastGames(i);
+
+                    ScoringTotalResult scoringTotalResult = new ScoringTotalResult(i, diff, a.getHomeScore(), a.getAwayScore());
+                    Map<Integer, ScoringTotalResult> lookBackMap = scoringTotalResultList.getOrDefault(i, new HashMap<>());
+                    addNewResult(lookBackMap, scoringTotalResult);
+                    scoringTotalResultList.put(i, lookBackMap);
+                }
+                if (++c % 100 == 0) {
+                    System.out.println(new Date() + " " + c + "/" + analyses.size() + " (" + ((double) c / analyses.size()) * 100 + "%)");
+                }
+            }
+            System.out.println(new Date() + " Done updateStatisticsScoringDiffLastGamesAction " + l.getLeagueName());
+            handleScoringTotalResults("updateStatisticsScoringDiffLastGamesAction", l.getLeagueName(), l.getLeagueId(), scoringTotalResultList, "ScoringDiffLastGames");
+        }
+    }
+
+    public void updateStatisticsWinLossRatioHomeAndAwayAction(ActionEvent actionEvent) {
+        List<League> leagues = GuiMysql.getInstance().getLeaguesWithPrio();
+        int soccerId = GuiMysql.getInstance().getSportId("Soccer");
+        for (League l : leagues) {
+            Map<Integer, Map<Integer, ScoringTotalResult>> scoringTotalResultList = new HashMap<>();
+            List<SoccerMatch> soccerMateches = GuiMysql.getInstance().getMatches(soccerId, l.getCountyId(),
+                    l.getLeagueId(), "2020-01-01", "ASC", false, true);
+            List<SoccerMatchAnalysis> analyses = soccerMateches.stream().map(SoccerMatchAnalysis::new).collect(Collectors.toList());
+
+            System.out.println(new Date() + " Running " + analyses.size() + " matches");
+            int c = 0;
+            for (SoccerMatchAnalysis a : analyses) {
+                for (int i = 1; i < 20; i++) {
+                    int winLossHAHome = a.winLossRatioHomeAndAway(i, true);
+                    int winLossHAAway = a.winLossRatioHomeAndAway(i, false);
+
+                    int diff = winLossHAHome - winLossHAAway;
+
+                    ScoringTotalResult scoringTotalResult = new ScoringTotalResult(i, diff, a.getHomeScore(), a.getAwayScore());
+                    Map<Integer, ScoringTotalResult> lookBackMap = scoringTotalResultList.getOrDefault(i, new HashMap<>());
+                    addNewResult(lookBackMap, scoringTotalResult);
+                    scoringTotalResultList.put(i, lookBackMap);
+                }
+                if (++c % 100 == 0) {
+                    System.out.println(new Date() + " " + c + "/" + analyses.size() + " (" + ((double) c / analyses.size()) * 100 + "%)");
+                }
+            }
+            System.out.println(new Date() + " Done updateStatisticsWinLossRatioHomeAndAwayAction " + l.getLeagueName());
+            handleScoringTotalResults("updateStatisticsWinLossRatioHomeAndAwayAction", l.getLeagueName(), l.getLeagueId(), scoringTotalResultList, "WinLossRatioHomeAndAway");
+        }
+    }
+
+    public void updateStatisticsWinLossRatioAction(ActionEvent actionEvent) {
+        List<League> leagues = GuiMysql.getInstance().getLeaguesWithPrio();
+        int soccerId = GuiMysql.getInstance().getSportId("Soccer");
+        for (League l : leagues) {
+            Map<Integer, Map<Integer, ScoringTotalResult>> scoringTotalResultList = new HashMap<>();
+            List<SoccerMatch> soccerMateches = GuiMysql.getInstance().getMatches(soccerId, l.getCountyId(),
+                    l.getLeagueId(), "2020-01-01", "ASC", false, true);
+            List<SoccerMatchAnalysis> analyses = soccerMateches.stream().map(SoccerMatchAnalysis::new).collect(Collectors.toList());
+
+            System.out.println(new Date() + " Running " + analyses.size() + " matches");
+            int c = 0;
+            for (SoccerMatchAnalysis a : analyses) {
+                for (int i = 1; i < 20; i++) {
+                    int winLossHome = a.winLossRatio(i, true);
+                    int winLossAway = a.winLossRatio(i, false);
+
+                    int diff = winLossHome - winLossAway;
+
+                    ScoringTotalResult scoringTotalResult = new ScoringTotalResult(i, diff, a.getHomeScore(), a.getAwayScore());
+                    Map<Integer, ScoringTotalResult> lookBackMap = scoringTotalResultList.getOrDefault(i, new HashMap<>());
+                    addNewResult(lookBackMap, scoringTotalResult);
+                    scoringTotalResultList.put(i, lookBackMap);
+                }
+                if (++c % 100 == 0) {
+                    System.out.println(new Date() + " " + c + "/" + analyses.size() + " (" + ((double) c / analyses.size()) * 100 + "%)");
+                }
+            }
+            System.out.println(new Date() + " Done updateStatisticsWinLossRatioAction " + l.getLeagueName());
+            handleScoringTotalResults("updateStatisticsWinLossRatioAction", l.getLeagueName(), l.getLeagueId(), scoringTotalResultList, "WinLossRatio");
+        }
+    }
+
+    public void refreshStatisticsAction(ActionEvent actionEvent) {
+
+    }
+
+    private class ScoringTotalResult {
+        private int diff;
+        private int lookback;
+        private int homeWins;
+        private int awayWins;
+        private int draws;
+
+        public ScoringTotalResult(int lookback, int diff, int homeScore, int awayScore) {
+            this.lookback = lookback;
+            this.diff = diff;
+            if (homeScore > awayScore) {
+                homeWins++;
+            } else if (homeScore < awayScore) {
+                awayWins++;
+            } else {
+                draws++;
+            }
+        }
+
+        public int getDiff() {
+            return diff;
+        }
+
+        public int getLookback() {
+            return lookback;
+        }
+
+        public int getHomeWins() {
+            return homeWins;
+        }
+
+        public int getAwayWins() {
+            return awayWins;
+        }
+
+        public int getDraws() {
+            return draws;
+        }
 
-@SuppressWarnings("rawtypes") public class StatisticsTabController implements Initializable {
-
-	@FXML private TableView<Map<String, Object>> statsTable;
-
-	@FXML TableColumn<Map, Float> diffColumn = new TableColumn<>("Diff");
-	@FXML TableColumn<Map, String> u05 = new TableColumn<>("Under 0.5");
-	@FXML TableColumn<Map, String> o05 = new TableColumn<>("Over 0.5");
-	@FXML TableColumn<Map, String> u15 = new TableColumn<>("Under 1.5");
-	@FXML TableColumn<Map, String> o15 = new TableColumn<>("Over 1.5");
-	@FXML TableColumn<Map, String> u25 = new TableColumn<>("Under 2.5");
-	@FXML TableColumn<Map, String> o25 = new TableColumn<>("Over 2.5");
-	@FXML TableColumn<Map, String> u35 = new TableColumn<>("Under 3.5");
-	@FXML TableColumn<Map, String> o35 = new TableColumn<>("Over 3.5");
-	@FXML TableColumn<Map, String> u45 = new TableColumn<>("Under 4.5");
-	@FXML TableColumn<Map, String> o45 = new TableColumn<>("Over 4.5");
-	@FXML TableColumn<Map, String> u55 = new TableColumn<>("Under 5.5");
-	@FXML TableColumn<Map, String> o55 = new TableColumn<>("Over 5.5");
-	@FXML TableColumn<Map, String> u65 = new TableColumn<>("Under 6.5");
-	@FXML TableColumn<Map, String> o65 = new TableColumn<>("Over 6.5");
-
-	private ObservableList<Map<String, Object>> statLines;
-
-	private static StatisticsTabController instance;
-
-	public static StatisticsTabController getInstance() {
-		if (instance == null) {
-			synchronized (StatisticsTabController.class) {
-				if (instance == null) {
-					instance = new StatisticsTabController();
-				}
-			}
-		}
-		return instance;
-	}
-
-	@Override public void initialize(URL arg0, ResourceBundle arg1) {
-		diffColumn.setCellValueFactory(new MapValueFactory<>("diff"));
-		u05.setCellValueFactory(new MapValueFactory<>("u05"));
-		o05.setCellValueFactory(new MapValueFactory<>("o05"));
-		u15.setCellValueFactory(new MapValueFactory<>("u15"));
-		o15.setCellValueFactory(new MapValueFactory<>("o15"));
-		u25.setCellValueFactory(new MapValueFactory<>("u25"));
-		o25.setCellValueFactory(new MapValueFactory<>("o25"));
-		u35.setCellValueFactory(new MapValueFactory<>("u35"));
-		o35.setCellValueFactory(new MapValueFactory<>("o35"));
-		u45.setCellValueFactory(new MapValueFactory<>("u45"));
-		o45.setCellValueFactory(new MapValueFactory<>("o45"));
-		u55.setCellValueFactory(new MapValueFactory<>("u55"));
-		o55.setCellValueFactory(new MapValueFactory<>("o55"));
-		u65.setCellValueFactory(new MapValueFactory<>("u65"));
-		o65.setCellValueFactory(new MapValueFactory<>("o65"));
-
-		statLines = FXCollections.<Map<String, Object>>observableArrayList();
-		instance = this;
-	}
-
-	public void setOverUnderTable(int leagueId, String gameDate) {
-		final List<OverUnder> statsOverUnder = GuiMysql.getInstance().getStatsOverUnder(leagueId, gameDate);
-
-		statLines.clear();
-		for (final OverUnder ou : statsOverUnder) {
-			final Map<String, Object> line = new HashMap<>();
-			if (statLines.stream().noneMatch(p -> p.get("diff") == ou.getKey())) {
-				line.put("diff", ou.getKey());
-				line.put("u05", ou.getGoals().get(0) + " (" + ou.calcMinOdds(ou.getGoals().get(0)) + ")");
-				line.put("o05", getOverStat(ou, 1) + " (" + ou.calcMinOdds(getOverStat(ou, 1)) + ")");
-				line.put("u15", getUnderStat(ou, 2) + " (" + ou.calcMinOdds(getUnderStat(ou, 2)) + ")");
-				line.put("o15", getOverStat(ou, 2) + " (" + ou.calcMinOdds(getOverStat(ou, 2)) + ")");
-				line.put("u25", getUnderStat(ou, 3) + " (" + ou.calcMinOdds(getUnderStat(ou, 3)) + ")");
-				line.put("o25", getOverStat(ou, 3) + " (" + ou.calcMinOdds(getOverStat(ou, 3)) + ")");
-				line.put("u35", getUnderStat(ou, 4) + " (" + ou.calcMinOdds(getUnderStat(ou, 4)) + ")");
-				line.put("o35", getOverStat(ou, 4) + " (" + ou.calcMinOdds(getOverStat(ou, 4)) + ")");
-				line.put("u45", getUnderStat(ou, 5) + " (" + ou.calcMinOdds(getUnderStat(ou, 5)) + ")");
-				line.put("o45", getOverStat(ou, 5) + " (" + ou.calcMinOdds(getOverStat(ou, 5)) + ")");
-				line.put("u55", getUnderStat(ou, 6) + " (" + ou.calcMinOdds(getUnderStat(ou, 6)) + ")");
-				line.put("o55", getOverStat(ou, 6) + " (" + ou.calcMinOdds(getOverStat(ou, 6)) + ")");
-				line.put("u65", getUnderStat(ou, 7) + " (" + ou.calcMinOdds(getUnderStat(ou, 7)) + ")");
-				line.put("o65", getOverStat(ou, 7) + " (" + ou.calcMinOdds(getOverStat(ou, 7)) + ")");
-
-				statLines.add(line);
-			}
-		}
-		statsTable.getItems().clear();
-		statsTable.getItems().addAll(statLines);
-		diffColumn.setSortable(true);
-	}
-
-	private int getUnderStat(OverUnder ou, float atMostXGoals) {
-		final ArrayList<Integer> goals = ou.getGoals();
-		int sum = 0;
-		for (int i = 0; i < (goals.size() < atMostXGoals ? goals.size() : atMostXGoals); i++) {
-			sum += goals.get(i);
-		}
-		return sum;
-	}
-
-	private int getOverStat(OverUnder ou, int atLeastXGoals) {
-		final ArrayList<Integer> goals = ou.getGoals();
-		int sum = 0;
-		for (int i = atLeastXGoals; i < goals.size(); i++) {
-			sum += goals.get(i);
-		}
-		return sum;
-	}
-
-	public void markValueInTable(float value) {
-		TableViewSelectionModel<Map<String, Object>> selectionModel = statsTable.getSelectionModel();
-		java.util.Optional<Map<String, Object>> optional = statsTable.getItems().stream().filter(p -> (Float) p.get("diff") == value).findFirst();
-		if (optional.isPresent()) {
-			selectionModel.setSelectionMode(SelectionMode.SINGLE);
-			int indexOf = statsTable.getItems().indexOf(optional.get());
-			selectionModel.select(indexOf);
-		}
-	}
+        public void add(ScoringTotalResult result) {
+            this.homeWins += result.homeWins;
+            this.awayWins += result.awayWins;
+            this.draws += result.draws;
+        }
+    }
 }

+ 4 - 5
OddsJavaFx/src/controllers/StryktipsetController.java

@@ -21,7 +21,6 @@ import java.net.URL;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
 import java.util.*;
 
 @SuppressWarnings("rawtypes")
@@ -132,10 +131,10 @@ public class StryktipsetController implements Initializable {
             int homeScore = match.scoringTotal(leagueInfo.getScoringTotal(), true);
             int awayScore = match.scoringTotal(leagueInfo.getScoringTotal(), false);
 
-            db.getTotalGoalStat(percentages, leagueInfo.getLeagueId(), leagueInfo.getScoringTotal(),
+            db.addTotalGoalStatToPercentage(percentages, leagueInfo.getLeagueId(), leagueInfo.getScoringTotal(),
                     homeScore - awayScore);
 
-            db.getScoringDiffLastGames(percentages, leagueInfo.getLeagueId(), leagueInfo.getScoringDiffLastGame(),
+            db.addScoringDiffLastGamesToPercentage(percentages, leagueInfo.getLeagueId(), leagueInfo.getScoringDiffLastGame(),
                     match.getScoringDiffLastGames(leagueInfo.getScoringDiffLastGame()));
 
             int winLossHAHome = match.winLossRatioHomeAndAway(leagueInfo.getWinLossRatioHomeAndAway(), true);
@@ -208,8 +207,8 @@ public class StryktipsetController implements Initializable {
                     l.getWinLossRatioHomeAndAway());
 
 
-            List<SoccerMatchAnalysis> matches = GuiMysql.getInstance().getSoccerMatchesWithGoalStats(l.getLeagueId(),
-                    LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE), l.getScoringTotal());
+//            List<SoccerMatchAnalysis> matches = GuiMysql.getInstance().getSoccerMatchesWithGoalStats(l.getLeagueId(),
+//                    LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE), l.getScoringTotal());
             System.out.println("Finished " + LocalDateTime.now() + " with " + l.getLeagueName());
 
         }

+ 14 - 9
OddsJavaFx/src/controllers/strategytest/FibonacciStrategy.java

@@ -12,6 +12,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 /**
  * The basic concept of betting according to the Fibonacci sequence is simple: bet on a tie.
@@ -115,9 +116,9 @@ public class FibonacciStrategy extends VBox implements BettingStrategyInterface
             SoccerMatch m = matches.get(i);
             List<SoccerMatch> soccerMatches = filterTodaysMatches(matches, m);
 
-            List<SoccerMatch> sortedMatchList = sortMatchesOnBetPotential(soccerMatches);
+            List<SoccerMatchAnalysis> sortedMatchList = sortMatchesOnBetPotential(soccerMatches);
 
-            for (SoccerMatch match : sortedMatchList) {
+            for (SoccerMatchAnalysis match : sortedMatchList) {
                 boolean removeSequence = false;
                 String shouldBetOn = shouldBetOn(match);
                 FibonacciSequence activeSequence = null;
@@ -180,15 +181,19 @@ public class FibonacciStrategy extends VBox implements BettingStrategyInterface
      * Matchen måste ha ett odds på X på minst 2.618
      */
     @Override
-    public String shouldBetOn(SoccerMatch match) {
-        return match.getOddsX() >= 2.618 ? "X" : "";
+    public <T extends SoccerMatch> String shouldBetOn(T match) {
+        boolean okPercentage = true; //((SoccerMatchAnalysis)match).getCalculatedPercentages().getDrawPercentage() > 0.25f;
+        boolean minOddsLevel = match.getOddsX() >= 2.618;
+        return okPercentage && minOddsLevel ? "X" : "";
     }
 
     @Override
-    public List<SoccerMatch> sortMatchesOnBetPotential(List<SoccerMatch> matches) {
-        matches.sort((m2, m1) -> Float.compare(new SoccerMatchAnalysis(m1).calculateWinPercentages().getDrawPercentage(),
-                new SoccerMatchAnalysis(m2).calculateWinPercentages().getDrawPercentage()));
-        return matches;
+    public List<SoccerMatchAnalysis> sortMatchesOnBetPotential(List<SoccerMatch> matches) {
+        List<SoccerMatchAnalysis> analysisMatches = matches.stream().map(SoccerMatchAnalysis::new).collect(Collectors.toList());
+        analysisMatches.forEach(sm -> sm.calculateWinPercentages());
+
+        analysisMatches.sort((m2,m1) -> Float.compare(m1.getCalculatedPercentages().getDrawPercentage(), m2.getCalculatedPercentages().getDrawPercentage()));
+        return analysisMatches;
     }
 
     public void reset() {
@@ -205,7 +210,7 @@ public class FibonacciStrategy extends VBox implements BettingStrategyInterface
 
     private class FibonacciSequence {
 
-        public static final List<Integer> fibonacciSequence = Arrays.asList(1, 1, 2, 3, 5, 8, 13, 21, 34, 55); //, 89, 144, 233, 377, 610);
+        public static final List<Integer> fibonacciSequence = Arrays.asList(1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144); //, 233, 377, 610);
         List<SoccerMatch> bets = new ArrayList<>();
         float totalBetValue = 0f;
 

+ 3 - 2
OddsJavaFx/src/controllers/strategytest/KellyFormulaStrategy.java

@@ -14,8 +14,9 @@ import java.util.stream.Collectors;
  * <p>There are of course numerous ideas, concepts and formulas that can help you calculate the ideal stake on a bet.
  * One of them is the Kelly formula. </p>
  *
- * <p>Of course, this is no guarantee that you will always bet correctly and the assessment of how likely the outcome of a game is, does still remain up to you.
- But the Kelly formula can help you choose the size of your bet.</p>
+ * <p>Of course, this is no guarantee that you will always bet correctly and the assessment of how likely the outcome of a game is,
+ * does still remain up to you.
+ * But the Kelly formula can help you choose the size of your bet.</p>
  *
  * <p>This is how the Kelly formula works</p>
  *

+ 5 - 0
OddsJavaFx/src/controllers/strategytest/OneXStrategy.java

@@ -107,6 +107,7 @@ public class OneXStrategy extends VBox implements BettingStrategyInterface {
      * It updates the match summary panel, the statistics, and the bank balance accordingly.
      */
     public void runTest() {
+        int i = 0;
         for (SoccerMatch match : matches) {
             final float oneXOdds = calculate1XOdds(match);
             if ( shouldBetOn(match).equals("1X")) {
@@ -121,6 +122,10 @@ public class OneXStrategy extends VBox implements BettingStrategyInterface {
                     wonLossBank.decreaseValue(betAmount.getValue());
                 }
             }
+            i++;
+            if (i % (matches.size() / 10) == 0) {
+                System.out.println("OneXStrategy Matches processed: " + (matches.size() / 10) + "%");
+            }
         }
     }
 

+ 9 - 2
OddsJavaFx/src/data/DTO/FibonacciDTO/FibonacciDTO.java

@@ -6,7 +6,7 @@ import java.util.List;
 
 public class FibonacciDTO implements Serializable {
 
-    private static final List<Integer> fibonacciSequence = Arrays.asList(1,1,2,3,5,8,13,21,34,55);
+    private static final List<Integer> fibonacciSequence = Arrays.asList(1,1,2,3,5,8,13,21,34,55,-1);
 
     private int matchId;
     private float odds;
@@ -83,6 +83,13 @@ public class FibonacciDTO implements Serializable {
     }
 
     public int getNextSequenceNumber(int currentSequenceNumber) {
-        return fibonacciSequence.get(currentSequenceNumber);
+        int res;
+        try {
+            res = fibonacciSequence.get(currentSequenceNumber);
+        } catch (IndexOutOfBoundsException e) {
+            res = -1;
+        }
+
+        return res;
     }
 }

+ 162 - 114
OddsJavaFx/src/data/GuiMysql.java

@@ -6,6 +6,8 @@ import mysql.Mysql;
 import objects.*;
 import objects.bets.Bet;
 import objects.bets.Bet.Status;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -19,8 +21,20 @@ import java.time.LocalDateTime;
 import java.util.*;
 import java.util.AbstractMap.SimpleEntry;
 
+import static objects.Constants.COUNTRY_ID;
+
 public class GuiMysql extends Mysql {
 
+    public static final String MATCH_ID = "matchId";
+    public static final String ID = "id";
+    public static final String BET = "bet";
+    public static final String BET_AMOUNT = "betAmount";
+    public static final String BET_ODDS = "betOdds";
+    public static final String STATUS = "status";
+    public static final String COVERED_BET_ID = "coveredBetId";
+    public static final String SQL_ERROR = "Sql error: ";
+    private Logger LOG = LoggerFactory.getLogger(GuiMysql.class);
+
     private static final String SEASON = "season";
     private static final String AWAY_SCORE = "awayScore";
     private static final String HOME_SCORE = "homeScore";
@@ -36,6 +50,14 @@ public class GuiMysql extends Mysql {
     private static final BigDecimal INCREMENT = BigDecimal.valueOf(0.2);
     private static final GuiMysql instance = new GuiMysql();
     public static final String GAME_DATE = "gameDate";
+    public static final String SCORING_TOTAL = "scoringTotal";
+    public static final String WIN_LOSS_RATIO_HOME_AND_AWAY = "winLossRatioHomeAndAway";
+    public static final String WIN_LOSS_RATIO = "winLossRatio";
+    public static final String SCORING_DIFF_LAST_GAME = "scoringDiffLastGame";
+    public static final String DRAW_DIFF_HOME_AWAY = "drawDiffHomeAway";
+    public static final String DRAW_DIFF_TOTAL_GOALS = "drawDiffTotalGoals";
+    public static final String DRAW_WINNING_FORM = "drawWinningForm";
+    public static final String DRAW_WINNING_FORM_HOME_AWAY = "drawWinningFormHomeAway";
 
 
     protected GuiMysql() {
@@ -66,7 +88,7 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -88,7 +110,7 @@ public class GuiMysql extends Mysql {
 
             stat.execute();
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -107,19 +129,19 @@ public class GuiMysql extends Mysql {
             while (rs.next()) {
                 Team homeTeam = getTeam(rs.getInt(HOME_TEAM_ID));
                 Team awayTeam = getTeam(rs.getInt(AWAY_TEAM_ID));
-                SoccerMatch match = new SoccerMatch(rs.getInt("matchId"), homeTeam, awayTeam, rs.getFloat("odds1"),
-                        rs.getFloat("oddsX"), rs.getFloat("odds2"), rs.getInt(HOME_SCORE), rs.getInt(AWAY_SCORE),
-                        LocalDateTime.parse(rs.getString("gameDate")), rs.getString(SEASON));
+                SoccerMatch match = new SoccerMatch(rs.getInt(MATCH_ID), homeTeam, awayTeam, rs.getFloat(ODDS_1),
+                        rs.getFloat(ODDS_X), rs.getFloat(ODDS_2), rs.getInt(HOME_SCORE), rs.getInt(AWAY_SCORE),
+                        LocalDateTime.parse(rs.getString(GAME_DATE)), rs.getString(SEASON));
 
                 match.setLeagueName(homeTeam.getTeamLeague());
                 match.setCountryName(homeTeam.getCountryName());
 
-                result = new Bet(rs.getInt("id"), match, rs.getString("bet"), rs.getFloat("betAmount"), rs.getFloat(
-                        "betOdds"), Status.valueOf(rs.getString("status")), rs.getInt("coveredBetId"));
+                result = new Bet(rs.getInt(ID), match, rs.getString(BET), rs.getFloat(BET_AMOUNT), rs.getFloat(
+                        BET_ODDS), Status.valueOf(rs.getString(STATUS)), rs.getInt(COVERED_BET_ID));
             }
 
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -139,19 +161,19 @@ public class GuiMysql extends Mysql {
 
                 Team homeTeam = getTeam(rs.getInt(HOME_TEAM_ID));
                 Team awayTeam = getTeam(rs.getInt(AWAY_TEAM_ID));
-                SoccerMatch match = new SoccerMatch(rs.getInt("matchId"), homeTeam, awayTeam, rs.getFloat("odds1"),
-                        rs.getFloat("oddsX"), rs.getFloat("odds2"), rs.getInt(HOME_SCORE), rs.getInt(AWAY_SCORE),
-                        LocalDateTime.parse(rs.getString("gameDate")), rs.getString(SEASON));
+                SoccerMatch match = new SoccerMatch(rs.getInt(MATCH_ID), homeTeam, awayTeam, rs.getFloat(ODDS_1),
+                        rs.getFloat(ODDS_X), rs.getFloat(ODDS_2), rs.getInt(HOME_SCORE), rs.getInt(AWAY_SCORE),
+                        LocalDateTime.parse(rs.getString(GAME_DATE)), rs.getString(SEASON));
 
                 match.setLeagueName(homeTeam.getTeamLeague());
                 match.setCountryName(homeTeam.getCountryName());
 
-                result.add(new Bet(rs.getInt("id"), match, rs.getString("bet"), rs.getFloat("betAmount"),
-                        rs.getFloat("betOdds"), Status.valueOf(rs.getString("status")), rs.getInt("coveredBetId")));
+                result.add(new Bet(rs.getInt(ID), match, rs.getString(BET), rs.getFloat(BET_AMOUNT),
+                        rs.getFloat(BET_ODDS), Status.valueOf(rs.getString(STATUS)), rs.getInt(COVERED_BET_ID)));
             }
 
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -175,17 +197,17 @@ public class GuiMysql extends Mysql {
                 Team homeTeam = getTeam(rs.getInt(HOME_TEAM_ID));
                 Team awayTeam = getTeam(rs.getInt(AWAY_TEAM_ID));
                 SoccerMatch match = new SoccerMatch(rs.getInt("soccerMatchId"), homeTeam, awayTeam, rs.getFloat(
-                        "odds1"), rs.getFloat("oddsX"), rs.getFloat("odds2"), rs.getInt(HOME_SCORE),
-                        rs.getInt(AWAY_SCORE), LocalDateTime.parse(rs.getString("gameDate")), rs.getString(SEASON));
+                        "odds1"), rs.getFloat(ODDS_X), rs.getFloat(ODDS_2), rs.getInt(HOME_SCORE),
+                        rs.getInt(AWAY_SCORE), LocalDateTime.parse(rs.getString(GAME_DATE)), rs.getString(SEASON));
                 match.setLeagueName(rs.getString(LEAGUE_NAME));
 
-                Bet bet = new Bet(rs.getInt("betId"), match, rs.getString("bet"), rs.getFloat("betAmount"),
-                        rs.getFloat("betOdds"));
+                Bet bet = new Bet(rs.getInt("betId"), match, rs.getString(BET), rs.getFloat(BET_AMOUNT),
+                        rs.getFloat(BET_ODDS));
 
                 result.add(bet);
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -207,7 +229,7 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -247,7 +269,7 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -270,7 +292,7 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -311,7 +333,7 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -331,7 +353,7 @@ public class GuiMysql extends Mysql {
                 result = rs.getString("value");
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -355,19 +377,19 @@ public class GuiMysql extends Mysql {
                 BetDTO dto = new BetDTO();
                 dto.setHomeTeam(rs.getString("homeTeam"));
                 dto.setAwayTeam(rs.getString("awayTeam"));
-                dto.setBet(rs.getFloat("bet"));
+                dto.setBet(rs.getFloat(BET));
                 dto.setBetType(rs.getString("betType"));
                 dto.setBetSeries(rs.getInt("series"));
                 dto.setGameId(rs.getInt("gameId"));
                 dto.setMatch(rs.getString("homeTeam"), rs.getString("awayTeam"));
                 dto.setOdds(rs.getFloat("odds"));
                 dto.setResult(rs.getInt(HOME_SCORE), rs.getInt("AwayScore"));
-                dto.setGameDate(rs.getString("gameDate"));
-                dto.setWinAmount(rs.getFloat("odds") * rs.getFloat("bet"));
+                dto.setGameDate(rs.getString(GAME_DATE));
+                dto.setWinAmount(rs.getFloat("odds") * rs.getFloat(BET));
                 result.add(dto);
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -386,7 +408,7 @@ public class GuiMysql extends Mysql {
                 result = rs.getInt(1);
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -408,7 +430,7 @@ public class GuiMysql extends Mysql {
                 countries.add(entry);
             }
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -433,7 +455,7 @@ public class GuiMysql extends Mysql {
                 result.add(new SimpleEntry<>(rs.getInt(Constants.ID), rs.getString("name")));
             }
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -458,11 +480,11 @@ public class GuiMysql extends Mysql {
             ResultSet rs = stat.executeQuery();
 
             while (rs.next()) {
-                result = rs.getInt("id");
+                result = rs.getInt(ID);
             }
 
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -491,7 +513,7 @@ public class GuiMysql extends Mysql {
                 returnValue.put(tg, numGoals);
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -516,7 +538,7 @@ public class GuiMysql extends Mysql {
                 season = rs.getString(Constants.SEASON);
             }
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -541,7 +563,7 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -557,13 +579,13 @@ public class GuiMysql extends Mysql {
             final ResultSet rs = stat.executeQuery();
 
             while (rs.next()) {
-                result = new League(rs.getInt(Constants.ID), rs.getString("name"), rs.getInt("scoringDiffLastGame"),
-                        rs.getInt("scoringTotal"), rs.getInt("winLossRatioHomeAndAway"), rs.getInt("winLossRatio"),
-                        rs.getInt("drawDiffHomeAway"), rs.getInt("drawDiffTotalGoals"), rs.getInt("drawWinningForm"),
-                        rs.getInt("drawWinningFormHomeAway"));
+                result = new League(rs.getInt(Constants.ID), rs.getString("name"), rs.getInt(SCORING_DIFF_LAST_GAME),
+                        rs.getInt(SCORING_TOTAL), rs.getInt(WIN_LOSS_RATIO_HOME_AND_AWAY), rs.getInt(WIN_LOSS_RATIO),
+                        rs.getInt(DRAW_DIFF_HOME_AWAY), rs.getInt(DRAW_DIFF_TOTAL_GOALS), rs.getInt(DRAW_WINNING_FORM),
+                        rs.getInt(DRAW_WINNING_FORM_HOME_AWAY));
             }
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -579,13 +601,13 @@ public class GuiMysql extends Mysql {
             final ResultSet rs = stat.executeQuery();
 
             while (rs.next()) {
-                result = new League(rs.getInt(Constants.ID), rs.getString("name"), rs.getInt("scoringDiffLastGame"),
-                        rs.getInt("scoringTotal"), rs.getInt("winLossRatioHomeAndAway"), rs.getInt("winLossRatio"),
-                        rs.getInt("drawDiffHomeAway"), rs.getInt("drawDiffTotalGoals"), rs.getInt("drawWinningForm"),
+                result = new League(rs.getInt(Constants.ID), rs.getString("name"), rs.getInt(SCORING_DIFF_LAST_GAME),
+                        rs.getInt(SCORING_TOTAL), rs.getInt(WIN_LOSS_RATIO_HOME_AND_AWAY), rs.getInt(WIN_LOSS_RATIO),
+                        rs.getInt(DRAW_DIFF_HOME_AWAY), rs.getInt(DRAW_DIFF_TOTAL_GOALS), rs.getInt(DRAW_WINNING_FORM),
                         rs.getInt("drawWinngingFormHomeAway"));
             }
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -609,7 +631,7 @@ public class GuiMysql extends Mysql {
                 leagues.add(entry);
             }
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -625,11 +647,11 @@ public class GuiMysql extends Mysql {
             ResultSet rs = stat.executeQuery();
 
             while (rs.next()) {
-                League l = new League(rs.getInt("id"), rs.getString("name"), rs.getInt("scoringDiffLastGame"),
-                        rs.getInt("scoringTotal"),
-                        rs.getInt("winLossRatioHomeAndAway"), rs.getInt("winLossRatio"), rs.getInt("drawDiffHomeAway"),
-                        rs.getInt("drawDiffTotalGoals"),
-                        rs.getInt("drawWinningForm"), rs.getInt("drawWinningFormHomeAway"));
+                League l = new League(rs.getInt(ID), rs.getString("name"), rs.getInt(SCORING_DIFF_LAST_GAME),
+                        rs.getInt(SCORING_TOTAL),
+                        rs.getInt(WIN_LOSS_RATIO_HOME_AND_AWAY), rs.getInt(WIN_LOSS_RATIO), rs.getInt(DRAW_DIFF_HOME_AWAY),
+                        rs.getInt(DRAW_DIFF_TOTAL_GOALS),
+                        rs.getInt(DRAW_WINNING_FORM), rs.getInt(DRAW_WINNING_FORM_HOME_AWAY));
                 l.setCountryName(rs.getString("cName"));
                 l.setPrio(rs.getBoolean("prio"));
                 result.add(l);
@@ -637,7 +659,7 @@ public class GuiMysql extends Mysql {
 
         } catch (SQLException e) {
             System.out.println("Someting wrong with sql " + sql);
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -661,7 +683,7 @@ public class GuiMysql extends Mysql {
                 leagues.add(entry);
             }
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -698,7 +720,7 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -769,8 +791,8 @@ public class GuiMysql extends Mysql {
                 awayTeam.setTeamLeagueId(rs.getInt(Constants.LEAGUE_ID));
                 homeTeam.setTeamLeague(rs.getString(LEAGUE_NAME));
                 awayTeam.setTeamLeague(rs.getString(LEAGUE_NAME));
-                homeTeam.setCountryId(rs.getInt(Constants.COUNTRY_ID));
-                awayTeam.setCountryId(rs.getInt(Constants.COUNTRY_ID));
+                homeTeam.setCountryId(rs.getInt(COUNTRY_ID));
+                awayTeam.setCountryId(rs.getInt(COUNTRY_ID));
                 homeTeam.setCountryName(rs.getString(COUNTRY_NAME));
                 awayTeam.setCountryName(rs.getString(COUNTRY_NAME));
 
@@ -794,7 +816,7 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -821,7 +843,7 @@ public class GuiMysql extends Mysql {
                 }
             }
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -917,7 +939,7 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -943,7 +965,7 @@ public class GuiMysql extends Mysql {
                 returnValue = rs.getString(SEASON);
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -964,7 +986,7 @@ public class GuiMysql extends Mysql {
                 sports.add(entry);
             }
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1028,7 +1050,7 @@ public class GuiMysql extends Mysql {
                 }
             }
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1084,7 +1106,7 @@ public class GuiMysql extends Mysql {
                 }
             }
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1101,11 +1123,11 @@ public class GuiMysql extends Mysql {
             ResultSet rs = stat.executeQuery();
 
             while (rs.next()) {
-                result = new Team(rs.getInt("id"), rs.getString("name"), rs.getInt("countryId"),
+                result = new Team(rs.getInt(ID), rs.getString("name"), rs.getInt("countryId"),
                         rs.getString(COUNTRY_NAME), rs.getInt("leagueId"), rs.getString(LEAGUE_NAME));
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             //closeConnection();
         }
@@ -1142,7 +1164,7 @@ public class GuiMysql extends Mysql {
                 tr.setCount(wins + draws + lost);
             }
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1182,7 +1204,7 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1220,8 +1242,8 @@ public class GuiMysql extends Mysql {
                 awayTeam.setTeamLeagueId(rs.getInt(Constants.LEAGUE_ID));
                 homeTeam.setTeamLeague(rs.getString(Constants.LEAGUE_NAME));
                 awayTeam.setTeamLeague(rs.getString(Constants.LEAGUE_NAME));
-                homeTeam.setCountryId(rs.getInt(Constants.COUNTRY_ID));
-                awayTeam.setCountryId(rs.getInt(Constants.COUNTRY_ID));
+                homeTeam.setCountryId(rs.getInt(COUNTRY_ID));
+                awayTeam.setCountryId(rs.getInt(COUNTRY_ID));
                 homeTeam.setCountryName(rs.getString(Constants.COUNTRY_NAME));
                 awayTeam.setCountryName(rs.getString(Constants.COUNTRY_NAME));
 
@@ -1240,7 +1262,7 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1267,7 +1289,7 @@ public class GuiMysql extends Mysql {
 
             stat.executeUpdate();
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1283,7 +1305,7 @@ public class GuiMysql extends Mysql {
             stat.executeUpdate();
 
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1299,7 +1321,7 @@ public class GuiMysql extends Mysql {
             stat.executeUpdate();
 
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1315,7 +1337,7 @@ public class GuiMysql extends Mysql {
             stat.executeUpdate();
 
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1331,7 +1353,7 @@ public class GuiMysql extends Mysql {
             stat.executeUpdate();
 
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1347,7 +1369,7 @@ public class GuiMysql extends Mysql {
             stat.executeUpdate();
 
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1363,7 +1385,7 @@ public class GuiMysql extends Mysql {
             stat.executeUpdate();
 
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1379,7 +1401,7 @@ public class GuiMysql extends Mysql {
 
             stat.execute();
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1394,7 +1416,7 @@ public class GuiMysql extends Mysql {
 
             stat.executeUpdate();
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1413,7 +1435,7 @@ public class GuiMysql extends Mysql {
                 returnValue.add(rs.getString(SEASON));
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1437,14 +1459,14 @@ public class GuiMysql extends Mysql {
 
             ResultSet rs = stat.executeQuery();
             while (rs.next()) {
-                match = new SoccerMatch(rs.getInt("id"), getTeam(rs.getInt(HOME_TEAM_ID)), getTeam(rs.getInt(
+                match = new SoccerMatch(rs.getInt(ID), getTeam(rs.getInt(HOME_TEAM_ID)), getTeam(rs.getInt(
                         AWAY_TEAM_ID)), rs.getFloat(ODDS_1), rs.getFloat(ODDS_X), rs.getFloat(ODDS_2), rs.getInt(
                         HOME_SCORE),
-                        rs.getInt(AWAY_SCORE), LocalDateTime.parse(rs.getString("gameDate")),
+                        rs.getInt(AWAY_SCORE), LocalDateTime.parse(rs.getString(GAME_DATE)),
                         rs.getString(SEASON));
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1462,12 +1484,12 @@ public class GuiMysql extends Mysql {
             while (rs.next()) {
                 Team homeTeam = getTeam(rs.getInt(HOME_TEAM_ID));
                 Team awayTeam = getTeam(rs.getInt(AWAY_TEAM_ID));
-                result.add(new SoccerMatch(rs.getInt("id"), homeTeam, awayTeam, rs.getFloat(ODDS_1),
+                result.add(new SoccerMatch(rs.getInt(ID), homeTeam, awayTeam, rs.getFloat(ODDS_1),
                         rs.getFloat(ODDS_X), rs.getFloat(ODDS_2), rs.getInt(HOME_SCORE), rs.getInt(AWAY_SCORE),
                         LocalDateTime.parse(rs.getString(GAME_DATE)), rs.getString(SEASON)));
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1533,8 +1555,8 @@ public class GuiMysql extends Mysql {
                 awayTeam.setTeamLeagueId(rs.getInt(Constants.LEAGUE_ID));
                 homeTeam.setTeamLeague(rs.getString(LEAGUE_NAME));
                 awayTeam.setTeamLeague(rs.getString(LEAGUE_NAME));
-                homeTeam.setCountryId(rs.getInt(Constants.COUNTRY_ID));
-                awayTeam.setCountryId(rs.getInt(Constants.COUNTRY_ID));
+                homeTeam.setCountryId(rs.getInt(COUNTRY_ID));
+                awayTeam.setCountryId(rs.getInt(COUNTRY_ID));
                 homeTeam.setCountryName(rs.getString(COUNTRY_NAME));
                 awayTeam.setCountryName(rs.getString(COUNTRY_NAME));
 
@@ -1568,7 +1590,7 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (final SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1611,7 +1633,7 @@ public class GuiMysql extends Mysql {
             ResultSet rs = stat.executeQuery();
 
             while (rs.next()) {
-                SoccerMatchAnalysis sma = new SoccerMatchAnalysis(new SoccerMatch(rs.getInt("id"),
+                SoccerMatchAnalysis sma = new SoccerMatchAnalysis(new SoccerMatch(rs.getInt(ID),
                         GuiMysql.getInstance().getTeam(rs.getInt(HOME_TEAM_ID)),
                         GuiMysql.getInstance().getTeam(rs.getInt(AWAY_TEAM_ID)),
                         rs.getFloat(ODDS_1), rs.getFloat(ODDS_X), rs.getFloat(ODDS_2), rs.getInt(HOME_SCORE),
@@ -1621,7 +1643,7 @@ public class GuiMysql extends Mysql {
                 addTotalGoalStat(sma, limit, leagueId, rs.getInt("homeRes") - rs.getInt("awayRes"));
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1657,7 +1679,7 @@ public class GuiMysql extends Mysql {
 
             stat.execute();
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
             throw new RuntimeException(e);
         }
     }
@@ -1705,7 +1727,7 @@ public class GuiMysql extends Mysql {
 
             stat.execute();
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1754,7 +1776,7 @@ public class GuiMysql extends Mysql {
 
             stat.execute();
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1772,12 +1794,12 @@ public class GuiMysql extends Mysql {
                 Team homeTeam = getTeam(rs.getInt(HOME_TEAM_ID));
                 Team awayTeam = getTeam(rs.getInt(AWAY_TEAM_ID));
                 result.add(new SoccerMatchAnalysis(
-                        new SoccerMatch(rs.getInt("id"), homeTeam, awayTeam, rs.getFloat(ODDS_1),
+                        new SoccerMatch(rs.getInt(ID), homeTeam, awayTeam, rs.getFloat(ODDS_1),
                                 rs.getFloat(ODDS_X), rs.getFloat(ODDS_2), rs.getInt(HOME_SCORE), rs.getInt(AWAY_SCORE),
                                 LocalDateTime.parse(rs.getString(GAME_DATE)), rs.getString(SEASON))));
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1796,13 +1818,13 @@ public class GuiMysql extends Mysql {
             while (rs.next()) {
                 Team homeTeam = getTeam(rs.getInt(HOME_TEAM_ID));
                 Team awayTeam = getTeam(rs.getInt(AWAY_TEAM_ID));
-                result.add(new SoccerMatch(rs.getInt("id"), homeTeam, awayTeam, rs.getFloat(ODDS_1),
+                result.add(new SoccerMatch(rs.getInt(ID), homeTeam, awayTeam, rs.getFloat(ODDS_1),
                         rs.getFloat(ODDS_X), rs.getFloat(ODDS_2), rs.getInt(HOME_SCORE), rs.getInt(AWAY_SCORE),
                         LocalDateTime.parse(rs.getString(GAME_DATE)), rs.getString(SEASON)));
             }
 
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1818,14 +1840,17 @@ public class GuiMysql extends Mysql {
             ResultSet rs = stat.executeQuery();
 
             while (rs.next()) {
-                result.add(new League(rs.getInt(Constants.ID), rs.getString("name"), rs.getInt("scoringDiffLastGame"),
-                        rs.getInt("scoringTotal"), rs.getInt("winLossRatioHomeAndAway"), rs.getInt("winLossRatio"),
-                        rs.getInt("drawDiffHomeAway"), rs.getInt("drawDiffTotalGoals"), rs.getInt("drawWinningForm"),
-                        rs.getInt("drawWinningFormHomeAway")));
+                League l = new League(rs.getInt(Constants.ID), rs.getString("name"), rs.getInt(SCORING_DIFF_LAST_GAME),
+                        rs.getInt(SCORING_TOTAL), rs.getInt(WIN_LOSS_RATIO_HOME_AND_AWAY), rs.getInt(WIN_LOSS_RATIO),
+                        rs.getInt(DRAW_DIFF_HOME_AWAY), rs.getInt(DRAW_DIFF_TOTAL_GOALS), rs.getInt(DRAW_WINNING_FORM),
+                        rs.getInt(DRAW_WINNING_FORM_HOME_AWAY));
+                l.setCountyId(rs.getInt(COUNTRY_ID));
+                result.add(l);
+
 
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1874,13 +1899,13 @@ public class GuiMysql extends Mysql {
 
             stat.execute();
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
     }
 
-    public void getScoringDiffLastGames(Percentages percentages, int leagueId, int lookback, int diff) {
+    public void addScoringDiffLastGamesToPercentage(Percentages percentages, int leagueId, int lookback, int diff) {
         String sql = "SELECT homeWins, draws, awayWins FROM ScoringDiffLastGamesStatistics WHERE leagueId = ? AND " +
                 "lookback = ? and diff = ?";
 
@@ -1897,13 +1922,13 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
     }
 
-    public void getTotalGoalStat(Percentages percentages, int leagueId, int lookback, int diff) {
+    public void addTotalGoalStatToPercentage(Percentages percentages, int leagueId, int lookback, int diff) {
         String sql = "SELECT homeWins, draws, awayWins FROM TotalGoalStatistics WHERE leagueId = ? AND " +
                 "lookback = ? and diff = ?";
 
@@ -1920,7 +1945,7 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1943,7 +1968,7 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1966,7 +1991,7 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -1991,10 +2016,11 @@ public class GuiMysql extends Mysql {
                 stat.setInt(1, value);
                 stat.setInt(2, leagueId);
 
+                System.out.println("Updating league setting " + setting + " from " + oldValue + " to " + value);
                 int res = stat.executeUpdate();
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         }finally {
             closeConnection();
         }
@@ -2017,7 +2043,7 @@ public class GuiMysql extends Mysql {
             }
 
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -2040,7 +2066,7 @@ public class GuiMysql extends Mysql {
                 matches.add(new SoccerMatch(rs));
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -2058,7 +2084,7 @@ public class GuiMysql extends Mysql {
                 matches.add(new SoccerMatch(rs));
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
@@ -2079,11 +2105,33 @@ public class GuiMysql extends Mysql {
                 matches.add(new SoccerMatch(rs));
             }
         } catch (SQLException e) {
-            e.printStackTrace();
+            LOG.error(SQL_ERROR,e);
         } finally {
             closeConnection();
         }
         return matches;
     }
 
+    public void updateScoringTotalResults(int leagueId, int bestHomeWinLookback, int bestAwayWinLookback, int bestDrawLookback, String tableColumnName) {
+        String sql = "INSERT INTO LeagueRatings (leagueId, homeValue, awayValue, drawValue, statisticName) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE homeValue = ?, awayValue = ?, drawValue = ?";
+
+        try (PreparedStatement stat = getConnection().prepareStatement(sql)) {
+            stat.setInt(1, leagueId);
+            stat.setInt(2, bestHomeWinLookback);
+            stat.setInt(3, bestAwayWinLookback);
+            stat.setInt(4, bestDrawLookback);
+            stat.setString(5, tableColumnName);
+            stat.setInt(6, bestHomeWinLookback);
+            stat.setInt(7, bestAwayWinLookback);
+            stat.setInt(8, bestDrawLookback);
+
+            stat.executeUpdate();
+
+        } catch (SQLException e) {
+            e.printStackTrace();
+            LOG.error(SQL_ERROR, e);
+        } finally {
+            closeConnection();
+        }
+    }
 }

+ 16 - 6
OddsJavaFx/src/fxml/StatisticsTabBuilder.fxml

@@ -1,11 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
-<?import javafx.scene.control.TableColumn?>
-<?import javafx.scene.control.TableView?>
-<?import javafx.scene.layout.AnchorPane?>
-<?import javafx.scene.layout.BorderPane?>
-
-<AnchorPane prefHeight="411.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controllers.StatisticsTabController">
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+<AnchorPane prefHeight="411.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controllers.StatisticsTabController">
    <children>
       <BorderPane prefHeight="411.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
          <center>
@@ -29,6 +26,19 @@
               </columns>
             </TableView>
          </center>
+          <bottom>
+          </bottom>
+         <bottom>
+            <FlowPane BorderPane.alignment="CENTER">
+               <children>
+                  <Button mnemonicParsing="false" onAction="#updateStatisticsScoringTotalAction" text="Update Statistics Scoring Total" />
+                   <Button mnemonicParsing="false" onAction="#updateStatisticsScoringDiffLastGamesAction" text="Update Statistics Scoring Diff Last Games" />
+                   <Button mnemonicParsing="false" onAction="#updateStatisticsWinLossRatioHomeAndAwayAction" text="Update Statistics Win Loss Ratio Home And Away" />
+                   <Button mnemonicParsing="false" onAction="#updateStatisticsWinLossRatioAction" text="Update Statistics Win Loss Ratio" />
+                   <Button mnemonicParsing="false" onAction="#refreshStatisticsAction" text="Refresh statistics" />
+               </children>
+            </FlowPane>
+         </bottom>
       </BorderPane>
    </children>
 </AnchorPane>

+ 1 - 1
OddsJavaFx/src/interfaces/strategytest/BettingStrategyInterface.java

@@ -15,7 +15,7 @@ public interface BettingStrategyInterface {
     void buildMatchSummaryPanel();
 
     void runTest();
-    String shouldBetOn(SoccerMatch match);
+    <T extends SoccerMatch> String shouldBetOn(T match);
 
     List<?> sortMatchesOnBetPotential(List<SoccerMatch> matches);
 

+ 9 - 3
OddsJavaFx/src/objects/League.java

@@ -1,8 +1,5 @@
 package objects;
 
-import javafx.scene.control.CheckBox;
-import javafx.scene.layout.HBox;
-
 public class League {
 
     int leagueId;
@@ -28,6 +25,7 @@ public class League {
     private int drawWinningFormHomeAway;
     private String countryName;
     private boolean prio;
+    private int countyId;
 
     public League(int leagueId, String leagueName, int scoringDiffLastGame,
             int scoringTotal, int winLossRatioHomeAndAway, int winLossRatio, int drawDiffHomeAway, int drawTotalGoals,
@@ -44,6 +42,14 @@ public class League {
         this.drawWinningFormHomeAway = drawWinningFormHomeAway;
     }
 
+    public void setCountyId(int countyId) {
+        this.countyId = countyId;
+    }
+
+    public int getCountyId() {
+        return countyId;
+    }
+
     public int getBetMargin() {
         return betMargin;
     }

+ 2 - 2
OddsJavaFx/src/objects/SoccerMatchAnalysis.java

@@ -456,10 +456,10 @@ public class SoccerMatchAnalysis extends SoccerMatch  {
         int homeScore = this.scoringTotal(leagueInfo.getScoringTotal(), true);
         int awayScore = this.scoringTotal(leagueInfo.getScoringTotal(), false);
 
-        database.getTotalGoalStat(calculatedPercentages, leagueInfo.getLeagueId(), leagueInfo.getScoringTotal(),
+        database.addTotalGoalStatToPercentage(calculatedPercentages, leagueInfo.getLeagueId(), leagueInfo.getScoringTotal(),
                 homeScore - awayScore);
 
-        database.getScoringDiffLastGames(calculatedPercentages, leagueInfo.getLeagueId(),
+        database.addScoringDiffLastGamesToPercentage(calculatedPercentages, leagueInfo.getLeagueId(),
                 leagueInfo.getScoringDiffLastGame(),
                 this.getScoringDiffLastGames(leagueInfo.getScoringDiffLastGame()));
 

+ 7 - 67
OddsJavaFx/src/tests/RelevanceTest.java

@@ -79,6 +79,7 @@ public class RelevanceTest extends TestClass {
 
         boolean skipFirst = false;
         for (Entry<String, List<SoccerMatch>> seasonMatches : matches.entrySet()) {
+            
             if (skipFirst) {
                 skipFirst = false;
                 continue;
@@ -86,6 +87,7 @@ public class RelevanceTest extends TestClass {
             for (int i = 1; i < 20; i++) {
                 gamesLookback = i;
                 season = seasonMatches.getKey();
+                System.out.println("Starting loop " + i + " season " + season);
                 analyzeDiffHomeAway(seasonMatches.getValue(), resultsDiffHomeAway);
                 analyzeDiffTotalGoals(seasonMatches.getValue(), resultsDiffTotalGoals);
                 analyzeWinnigForm(seasonMatches.getValue(), resultsWinningForm);
@@ -98,104 +100,42 @@ public class RelevanceTest extends TestClass {
 
         resultsCombined.forEach((k, v) -> System.out.println(k + " result " + v));
 
-        // resultsDiffHomeAway.stream().sorted((r1, r2) -> Float.compare(r2.getResult(),
-        // r1.getResult()))
-        // .limit(5)
-        // .forEach(e -> System.out
-        // .println("scoringDiffLastGame Lookback " + e.getLookback() + " value " +
-        // e.getResult()));
-
         GuiMysql.getInstance().updateLegueSetting(leagueId, "scoringDiffLastGame", resultsDiffHomeAway.stream()
                 .sorted((r1, r2) -> Float.compare(r2.getResult(), r1.getResult())).findFirst().get().getLookback());
 
-        // resultsDiffTotalGoals.stream().sorted((r1, r2) ->
-        // Float.compare(r2.getResult(), r1.getResult()))
-        // .limit(5)
-        // .forEach(e -> System.out
-        // .println("scoringTotal Lookback " + e.getLookback() + " value " +
-        // e.getResult()));
-
         GuiMysql.getInstance().updateLegueSetting(leagueId, "scoringTotal", resultsDiffTotalGoals.stream()
                 .sorted((r1, r2) -> Float.compare(r2.getResult(), r1.getResult())).findFirst().get().getLookback());
 
-        // resultsWinningForm.stream().sorted((r1, r2) -> Float.compare(r2.getResult(),
-        // r1.getResult()))
-        // .limit(5)
-        // .forEach(e -> System.out
-        // .println("winLossRatio Lookback " + e.getLookback() + " value " +
-        // e.getResult()));
 
         GuiMysql.getInstance().updateLegueSetting(leagueId, "winLossRatio", resultsWinningForm.stream()
                 .sorted((r1, r2) -> Float.compare(r2.getResult(), r1.getResult())).findFirst().get().getLookback());
 
-        /*
-         * resultsWinnignFormHomeVsAway.stream().sorted((r1, r2) ->
-         * Float.compare(r2.getResult(), r1.getResult()))
-         * .limit(5)
-         * .forEach(e -> System.out
-         * .println("winLossRatioHomeAndAway Lookback " + e.getLookback() + " value "
-         * + e.getResult()));
-         */
+
         GuiMysql.getInstance().updateLegueSetting(leagueId, "winLossRatioHomeAndAway",
                 resultsWinnignFormHomeVsAway.stream()
                         .sorted((r1, r2) -> Float.compare(r2.getResult(), r1.getResult())).findFirst().get()
                         .getLookback());
 
-        /*
-         * resultsDiffHomeAway.stream()
-         * .sorted((r1, r2) -> Float
-         * .compare(r2.getDrawPercent(), r1.getDrawPercent()))
-         * .limit(5)
-         * .forEach(e -> System.out
-         * .println("Draws drawDiffHomeAway correct " + e.getDrawPercent()
-         * + " played "
-         * + e.getDrawsPlayed() + " lookback " + e.getLookback()));
-         */
 
         GuiMysql.getInstance().updateLegueSetting(leagueId, "drawDiffHomeAway",
                 resultsDiffHomeAway.stream()
                         .sorted((r1, r2) -> Float.compare(r2.getDrawPercent(), r1.getDrawPercent())).findFirst().get()
                         .getLookback());
 
-        /*
-         * resultsDiffTotalGoals.stream()
-         * .sorted((r1, r2) -> Float.compare(r2.getDrawPercent(), r1.getDrawPercent()))
-         * .limit(5)
-         * .forEach(e -> System.out
-         * .println("Draws drawDiffTotalGoals correct " + e.getDrawPercent()
-         * + " played "
-         * + e.getDrawsPlayed() + " lookback " + e.getLookback()));
-         */
+
         GuiMysql.getInstance().updateLegueSetting(leagueId, "drawDiffTotalGoals",
                 resultsDiffTotalGoals.stream()
                         .sorted((r1, r2) -> Float.compare(r2.getDrawPercent(), r1.getDrawPercent())).findFirst().get()
                         .getLookback());
 
-        /*
-         * resultsWinningForm.stream()
-         * .sorted((r1, r2) -> Float
-         * .compare(r2.getDrawPercent(), r1.getDrawPercent()))
-         * .limit(5)
-         * .forEach(e -> System.out
-         * .println("Draw drawWinningForm correct " + e.getDrawPercent()
-         * + " played "
-         * + e.getDrawsPlayed() + " lookback " + e.getLookback()));
-         */
+
 
         GuiMysql.getInstance().updateLegueSetting(leagueId, "drawWinningForm",
                 resultsWinningForm.stream()
                         .sorted((r1, r2) -> Float.compare(r2.getDrawPercent(), r1.getDrawPercent())).findFirst().get()
                         .getLookback());
 
-        /*
-         * resultsWinnignFormHomeVsAway.stream()
-         * .sorted((r1, r2) -> Float.compare(r2.getDrawPercent(), r1.getDrawPercent()))
-         * .limit(5)
-         * .forEach(e -> System.out
-         * .println("drawWinningFormHomeAway Draws correct " + e.getDrawPercent()
-         * + " played "
-         * + e.getDrawsPlayed() + " lookback " + e.getLookback()));
-         */
+
         GuiMysql.getInstance().updateLegueSetting(leagueId, "drawWinningFormHomeAway",
                 resultsWinnignFormHomeVsAway.stream()
                         .sorted((r1, r2) -> Float.compare(r2.getDrawPercent(), r1.getDrawPercent())).findFirst().get()
@@ -222,7 +162,7 @@ public class RelevanceTest extends TestClass {
         TreeMap<Float, Integer> lossesSorted = sortMap(lossesOnDiff);
         TreeMap<Float, Integer> winsSorted = sortMap(winsOnDiff);
 
-        // printResults(winsSorted, lossesSorted, true, resultsDiffHomeAway);
+        //printResults(winsSorted, lossesSorted, true, resultsDiffHomeAway);
     }
 
     private TreeMap<Float, Integer> sortMap(Map<Float, Integer> map) {

+ 3 - 0
OddsStrategyWeb/src/main/java/MainApplication.java

@@ -8,6 +8,9 @@ public class MainApplication extends WebApplication {
     @Override
     public void init() {
         super.init();
+//        getRequestCycleSettings().setRenderStrategy(RequestCycleSettings.RenderStrategy.ONE_PASS_RENDER);
+//        getRequestCycleSettings().setGatherExtendedBrowserInfo(false);
+
 
         // needed for the styling used by the quickstart
 

+ 2 - 2
OddsStrategyWeb/src/main/java/MainPage.java

@@ -32,12 +32,12 @@ public class MainPage extends WebPage {
 
         // Current bet sequences
         add(new Label("currentBetSequencesLabel"));
-        add(new BetSequencesTable("currentBetSequences"));
+        BetSequencesTable currentBetSequences = new BetSequencesTable("currentBetSequences");
+        add(currentBetSequences);
 
         // A way to add bets
         add(new Label("newBetLabel", "New bet"));
         add(new NewBetForm("newBetForm"));
     }
 
-
 }

+ 5 - 2
OddsStrategyWeb/src/main/java/components/AjaxButtonPanel.java

@@ -4,12 +4,14 @@ import data.BetStrategyMysql.BetStrategyMysql;
 import data.DTO.FibonacciDTO.FibonacciDTO;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
 
 public class AjaxButtonPanel extends Panel {
-    public AjaxButtonPanel(String id, IModel<FibonacciDTO> rowModel) {
+
+    public AjaxButtonPanel(String id, IModel<FibonacciDTO> rowModel, DataTable<FibonacciDTO, String> dataTable) {
         super(id, rowModel);
         setOutputMarkupId(true);
 
@@ -20,11 +22,12 @@ public class AjaxButtonPanel extends Panel {
                 // Handle the button click here
                 FibonacciDTO rowObject = rowModel.getObject();
 
+                rowObject.setHomeTeamName("UPDATED");
                 // Your button logic for the row here
                 // TODO kanse en bekräfta dialog?
                 BetStrategyMysql.getInstance().closeFibonacciSequence(rowObject.getSequenceNumber());
 
-                target.getPage().renderPage();
+                target.add(dataTable);
             }
 
             @Override

+ 9 - 4
OddsStrategyWeb/src/main/java/components/betsequences/BetSequencesTable.java

@@ -24,10 +24,11 @@ import java.util.stream.Collectors;
 
 public class BetSequencesTable extends Panel {
     List<FibonacciDTO> allOpenFibonacciSequences;
-
+    DataTable<FibonacciDTO, String> dataTable;
     List<IColumn<FibonacciDTO, String>> tableColumns = new ArrayList<>();
     public BetSequencesTable(String id) {
         super(id);
+        setOutputMarkupId(true);
 
         Label label = new Label("betSequencesLabel", "Current bet sequences");
         add(label);
@@ -73,8 +74,8 @@ public class BetSequencesTable extends Panel {
         Form<?> form = new Form<>("form");
         add(form);
 
-        DataTable<FibonacciDTO, String> dataTable = new DataTable<>("betSequencesTable", tableColumns, dataProvider, 10);
-
+        dataTable = new DataTable<>("betSequencesTable", tableColumns, dataProvider, 10);
+        dataTable.setOutputMarkupId(true);
         dataTable.addTopToolbar(new HeadersToolbar<>(dataTable, dataProvider));
         form.add(dataTable);
         add(form);
@@ -97,9 +98,13 @@ public class BetSequencesTable extends Panel {
         tableColumns.add(new LambdaColumn<FibonacciDTO, String>(Model.of("Action"), rowModel -> "action") {
             @Override
             public void populateItem(Item<ICellPopulator<FibonacciDTO>> cellItem, String componentId, IModel<FibonacciDTO> rowModel) {
-                cellItem.add(new AjaxButtonPanel(componentId, rowModel));
+                cellItem.add(new AjaxButtonPanel(componentId, rowModel, dataTable));
             }
         });
 
     }
+
+    public DataTable<FibonacciDTO, String> getBetsTable() {
+        return dataTable;
+    }
 }

+ 1 - 0
OddsStrategyWeb/src/main/java/components/matchtable/MatchTable.java

@@ -74,6 +74,7 @@ public class MatchTable extends Panel {
     }
 
     private void buildMatchesTable() {
+        setOutputMarkupId(true);
         tableColumns.add(new LambdaColumn<>(Model.of("Match"), "toString",  s -> "(" +s.getMatchId() + ") " +  s.toString()));
         tableColumns.add(new PropertyColumn<>(Model.of("Odds 1"), "odds1", "odds1"));
         tableColumns.add(new PropertyColumn<>(Model.of("Odds X"), "oddsX", "oddsX"));

+ 1 - 0
OddsStrategyWeb/src/main/java/components/newBetForm/NewBetForm.java

@@ -27,6 +27,7 @@ public class NewBetForm extends Panel {
 
     public NewBetForm(String id) {
         super(id);
+        setOutputMarkupId(true);
 
         FeedbackPanel feedbackPanel = new FeedbackPanel("feedback");
         add(feedbackPanel);

+ 3 - 1
OddsStrategyWeb/src/main/webapp/WEB-INF/web.xml

@@ -18,5 +18,7 @@
         <filter-name>MainApplication</filter-name>
         <url-pattern>/*</url-pattern>
     </filter-mapping>
-
+    <session-config>
+        <tracking-mode>COOKIE</tracking-mode>
+    </session-config>
 </web-app>