소스 검색

Selenium OddsPortal runner done

Axel Nordh 3 년 전
부모
커밋
172e790f7e
41개의 변경된 파일3880개의 추가작업 그리고 2243개의 파일을 삭제
  1. 2 1
      Odds/.gitignore
  2. 81 0
      Odds/BWin.csv
  3. 66 0
      Odds/BetHard.csv
  4. 28 0
      Odds/BetSafe.csv
  5. 71 33
      Odds/Expekt.csv
  6. 127 42
      Odds/NordicBet.csv
  7. BIN
      Odds/chromedriver.exe
  8. 20 19
      Odds/src/Main.java
  9. 99 48
      Odds/src/main/ArbChecker.java
  10. 261 193
      Odds/src/mysql/Mysql.java
  11. 72 17
      Odds/src/object/ArbResults.java
  12. 24 0
      Odds/src/object/Odds.java
  13. 119 50
      Odds/src/object/ResultDTO.java
  14. 101 0
      Odds/src/parser/BWinParser.java
  15. 136 0
      Odds/src/parser/BetHard.java
  16. 59 24
      Odds/src/parser/BetSafeParser.java
  17. 45 3
      Odds/src/parser/ExpektParser.java
  18. 46 21
      Odds/src/parser/NordicBetParser.java
  19. 268 158
      Odds/src/parser/OddsPortal.java
  20. 27 1
      Odds/src/parser/ParserBase.java
  21. 8 0
      Odds/src/parser/Todo/BetssonParser.java
  22. 9 0
      Odds/src/parser/Todo/ComeOnParser.java
  23. 8 0
      Odds/src/parser/Todo/MrGreenParser.java
  24. 8 0
      Odds/src/parser/Todo/SnabbareParser.java
  25. 1 0
      Odds/src/parser/Todo/SpeedyBetParser_KanskeBesvärlig.java
  26. 7 0
      Odds/src/parser/Todo/UnibetParser.java
  27. 191 162
      OddsJavaFx/src/controllers/AnalysisTestController.java
  28. 150 139
      OddsJavaFx/src/controllers/TestsController.java
  29. 731 684
      OddsJavaFx/src/data/GuiMysql.java
  30. 1 1
      OddsJavaFx/src/fxml/AnalysisTesting.fxml
  31. 1 0
      OddsJavaFx/src/fxml/Testing.fxml
  32. 88 47
      OddsJavaFx/src/objects/League.java
  33. 99 80
      OddsJavaFx/src/objects/bets/Bet.java
  34. 302 304
      OddsJavaFx/src/parser/OddsPortal.java
  35. 294 0
      OddsJavaFx/src/tests/AnalysisBettDrawTester.java
  36. 2 2
      OddsJavaFx/src/tests/AnalysisBettTester.java
  37. 29 27
      OddsJavaFx/src/tests/HomeDrawAwayTest.java
  38. 112 98
      OddsJavaFx/src/tests/LeagueTablePositionTest.java
  39. 27 33
      OddsJavaFx/src/tests/PrioCountriesAll.java
  40. 158 54
      OddsJavaFx/src/tests/RelevanceTest.java
  41. 2 2
      OddsJavaFx/src/tests/TestClass.java

+ 2 - 1
Odds/.gitignore

@@ -1,4 +1,5 @@
 /bin/
 /bin/
 /target/
 /target/
 /.settings/
 /.settings/
-.classpath
+.classpath
+/.apt_generated/

+ 81 - 0
Odds/BWin.csv

@@ -0,0 +1,81 @@
+Gillingham FC,Dagenham & Redbridge FC,2.4,3.2,2.85,2.05,1.68
+CD Feirense,CD Santa Clara,2.85,3.0,2.55,2.3,1.55
+GD Chaves,FC Porto,7.5,4.75,1.39,1.63,2.1
+Burgos CF,SD Eibar,3.0,2.7,2.5,0.0,0.0
+CD Lugo,Sporting Gijon,3.0,2.87,2.37,2.4,1.49
+UD Ibiza,Racing Santander,2.4,2.8,3.0,0.0,0.0
+Levante UD,SD Ponferradina,1.36,4.4,7.75,1.78,1.9
+Malaga CF,Granada CF,3.6,2.95,2.1,2.37,1.51
+Parma Calcio,Benevento Calcio,1.85,3.4,4.2,2.05,1.66
+Cittadella,SSC Bari,2.45,2.85,3.2,2.4,1.49
+Cosenza,Brescia Calcio,3.25,3.1,2.2,2.15,1.62
+Perugia Calcio,SPAL,2.0,3.2,3.75,2.15,1.62
+Reggina 1914,Frosinone Calcio,2.5,3.0,2.95,2.1,1.63
+Modena FC,Venezia FC,2.3,3.2,3.1,1.9,1.77
+Genoa CFC,FC Sudtirol,1.46,4.2,6.75,1.93,1.75
+SC Pisa,Ascoli Calcio 1898 FC,1.98,3.25,3.8,2.15,1.62
+US Palermo,Como 1907,2.3,3.25,3.0,1.95,1.73
+NK Olimpija Ljubljana,NS Mura,1.83,3.6,3.6,1.65,2.1
+AD Ceuta,San Sebastian Reyes,3.2,2.9,2.15,0.0,0.0
+CD Atletico Baleares,SD Logrones,1.88,2.95,4.0,0.0,0.0
+UD Cornella,Real Murcia CF,3.6,2.85,2.0,0.0,0.0
+CD Alcoyano,Athletic Bilbao B,1.8,3.0,4.2,2.4,1.5
+CE Sabadell FC,Real Union de Irun,1.78,3.0,4.33,0.0,0.0
+CA Osasuna B,Gimnastic de Tarragona,2.0,2.95,3.5,2.35,1.52
+Enppi Club,Haras El Hodood,1.98,2.75,3.9,0.0,0.0
+Smouha SC,Aswan FC,1.93,2.85,3.9,0.0,0.0
+Future FC,Al-Ittihad Al-Sakandary,1.73,3.2,4.4,2.1,1.65
+Ceramica Cleopatra,Ismaily SC,2.25,2.8,3.1,0.0,0.0
+ATK Mohun Bagan,Jamshedpur,1.68,3.7,4.4,1.71,2.0
+VfL WolfsburgD,AS RomaD,1.34,4.6,6.75,1.6,2.2
+Real MadridD,ChelseaD,3.7,3.2,1.85,1.88,1.8
+SKN St. PöltenD,Slavia PragD,2.1,3.3,2.85,1.72,1.98
+Red Bull Bragantino SPWomen,SC Corinthians SPWomen,7.25,4.2,1.37,1.55,2.25
+Al ShababOMA,Salalah SC,1.35,4.5,7.0,1.93,1.77
+Falkirk FC,Dundee FC,3.8,3.5,1.73,1.68,2.05
+Attard FC,St Andrews FC,3.1,3.4,1.98,1.63,2.1
+Fgura United FC,Vittoriosa Stars,1.31,4.5,8.0,0.0,0.0
+Naxxar Lions FC,Melita FC,1.6,3.75,4.4,1.63,2.1
+Lija Athletic,San Gwann FC,2.2,3.3,2.7,1.6,2.2
+Al-Salmiya,Al SahelKUW,1.49,4.1,5.0,1.58,2.2
+Al-ArabiKUW,Al-Qadisiya,2.35,3.25,2.55,1.8,1.88
+ADO Den HaagWomen,FeyenoordD,1.62,3.8,4.2,1.62,2.15
+FC Gagra,FC Spaeri,2.1,3.25,2.9,1.87,1.82
+Aizawl FC,Neroca FC,1.78,3.4,3.8,1.95,1.75
+Trau FC,Punjab FC,2.9,3.2,2.1,1.93,1.75
+FC Ashdod,Maccabi Bnei Reina,1.77,3.3,3.9,1.95,1.73
+Hapoel Be`er Sheva FC,Hapoel Tel Aviv FC,1.6,3.6,4.6,1.82,1.87
+Maccabi Haifa FC,Bnei Sakhnin FC,1.25,5.0,9.25,1.63,2.1
+PSS Sleman,Madura United,3.4,3.1,1.93,2.1,1.62
+Kroatien,Brasilien,8.25,5.0,1.36,1.73,2.0
+Nederländerna,Argentina,3.4,3.1,2.25,2.35,1.53
+FC Famalicao,CD Tondela,1.82,3.4,4.33,2.05,1.68
+Cangzhou Mighty Lions,Wuhan FC,2.25,3.4,2.75,1.8,1.88
+Shanghai Shenhua FC,Dalian Professional FC,2.55,3.4,2.45,1.83,1.85
+Shenzhen FC,Changchun Yatai FC,4.1,3.8,1.7,1.71,2.0
+Wuhan Three Towns FC,Shandong Taishan FC,1.87,3.6,3.5,1.8,1.88
+Brisbane Roar FC,Adelaide United FC,2.5,3.4,2.65,1.65,2.1
+Sepsi OSK,FC Voluntari,1.53,3.8,5.75,2.05,1.66
+Crawley Town,Hartlepool United FC,2.0,3.5,3.5,1.88,1.8
+FC Villefranche-Beaujolais,LB Chateauroux,2.37,3.0,2.75,2.05,1.66
+US Avranches,AS Nancy,3.2,3.1,2.05,2.0,1.7
+Le Puy Foot 43 Auvergne,USL Dunkerque,3.0,3.1,2.1,2.05,1.66
+Stade Briochin,Le Mans FC,3.0,3.2,2.1,1.95,1.73
+Sedan Ardennes,Stade Olympique Choletais,1.98,3.1,3.4,2.0,1.68
+Red Star FC,FC de Versailles 78,1.87,3.25,3.6,1.95,1.75
+Paris 13 Atletico,FC Bastia Borgo,1.95,3.25,3.3,2.1,1.65
+Hyderabad FC,SC East Bengal,1.5,4.1,5.5,1.71,2.0
+Samsunspor,Yeni Malatyaspor,1.38,4.6,6.75,1.63,2.1
+K.V. R.S. Waasland Beveren,RSC Anderlecht Futures,1.52,4.1,4.75,0.0,0.0
+Jong KRC Genk,Club NXTU23,2.1,3.6,2.7,0.0,0.0
+SC Weiche Flensburg 08,Hannover 96 II,2.05,3.7,2.7,0.0,0.0
+Eintracht Norderstedt,SV DROCHTERSEN / ASSEL,2.0,3.5,2.9,1.58,2.2
+Chemnitzer FC,Hertha BSC II,1.52,4.0,4.75,1.65,2.1
+VSG Altglienicke,VfB Germania Halberstadt,1.29,5.25,7.0,0.0,0.0
+FC-Astoria Walldorf,TSG 1899 Hoffenheim IIU23,3.25,3.4,1.9,1.62,2.1
+Arbroath FC,Dunfermline Athletic FC,2.1,3.3,2.9,1.78,1.9
+Alloa Athletic FC,Queen of The South FC,2.1,3.4,2.87,1.66,2.05
+RANS Nusantara FC,Tira-Persikabo,2.7,3.25,2.2,1.65,2.1
+PSIS Semarang,Borneo FC Samarinda,2.95,3.3,2.05,1.83,1.85
+CSD Municipal,Antigua GFC,1.58,3.4,5.25,2.2,1.6
+CD Walter Ferretti,Diriangen FC Diriamba,3.25,3.3,1.95,1.82,1.85

+ 66 - 0
Odds/BetHard.csv

@@ -0,0 +1,66 @@
+Rio Ave,Sporting Lisbon,7.25,5.25,1.35,0.0,0.0
+Managua,Real Esteli,2.7,2.85,2.4,0.0,0.0
+Gillingham,Dagenham & Redbridge,2.5,3.25,2.95,0.0,0.0
+Parma,Benevento,1.83,3.45,4.15,0.0,0.0
+Cittadella AS,Bari,2.4,2.9,3.2,0.0,0.0
+Nuova Cosenza,Brescia,3.4,3.1,2.2,0.0,0.0
+Genoa,Sudtirol Alto Adige,1.5,3.95,6.5,0.0,0.0
+Modena,Venezia,2.35,3.05,3.15,0.0,0.0
+Perugia,Spal,2.05,3.15,3.8,0.0,0.0
+Reggina,Frosinone,2.5,2.95,3.0,0.0,0.0
+Pisa,Ascoli,2.1,3.2,3.65,0.0,0.0
+Palermo,Como,2.2,3.2,3.3,0.0,0.0
+Burgos CF,Eibar,3.1,2.8,2.55,0.0,0.0
+CD Lugo,Sporting Gijon,3.2,2.95,2.4,0.0,0.0
+Ibiza Eivissa,Racing Santander,2.4,2.9,3.25,0.0,0.0
+Levante,Ponferradina,1.41,4.55,6.75,0.0,0.0
+Malaga,Granada CF,3.1,3.0,2.4,0.0,0.0
+Feirense,CD Santa Clara,2.9,3.1,2.5,0.0,0.0
+Chaves,Porto,7.5,4.85,1.35,0.0,0.0
+Smouha SC,Aswan,1.95,2.8,4.35,0.0,0.0
+Future FC,Al-Ittihad Al-Sakandary,1.8,3.0,4.75,0.0,0.0
+Ceramica Cleopatra,El Ismaily,2.45,2.8,3.0,0.0,0.0
+Deportivo Pereira,Indepen Medellin,2.2,3.0,3.15,0.0,0.0
+Olimpija Ljubljana,NS Mura,1.9,3.25,3.6,0.0,0.0
+Wolfsburg [W],AS Roma [W],1.28,4.8,7.5,0.0,0.0
+Real Madrid [W],Chelsea [W],3.3,3.05,2.05,0.0,0.0
+St Polten [W],Slavia Prague [W],2.05,3.35,3.05,0.0,0.0
+Al Manama,Bahrain SC,1.58,3.35,5.25,0.0,0.0
+East Riffa,Al Ahli [BRN],2.75,3.2,2.25,0.0,0.0
+CS Mioveni,Uta Arad,3.9,3.0,1.9,0.0,0.0
+Otelul Galati,FC Buzau,2.4,2.95,2.8,0.0,0.0
+Botosani,FCSB,1.95,3.4,3.3,0.0,0.0
+Shanghai Jiading Huilong,Nantong Zhiyun,1.5,4.6,4.3,0.0,0.0
+Zibo Cuju,Kunshan FC,10.25,6.0,1.17,0.0,0.0
+Sichuan Jiuniu,Suzhou Dongwu,1.95,3.25,3.35,0.0,0.0
+Aizawl FC,NEROCA,1.66,3.55,4.25,0.0,0.0
+Trau FC,RoundGlass Punjab,2.9,3.25,2.15,0.0,0.0
+PSS Sleman,Madura United,3.0,3.15,2.15,0.0,0.0
+PSM Makassar,Persita Tangerang,2.0,3.2,3.25,0.0,0.0
+Bali United Pusam FC,Bhayangkara FC,1.86,3.2,3.7,0.0,0.0
+Falkirk,Dundee FC,3.75,3.5,1.76,0.0,0.0
+ATK Mohun Bagan,Jamshedpur FC,1.71,3.35,4.05,0.0,0.0
+FC Ashdod,Maccabi Bnei Raina,1.8,3.2,3.75,0.0,0.0
+Hapoel Beer Sheva,Hapoel Tel Aviv,1.55,3.65,4.6,0.0,0.0
+Maccabi Haifa,Bnei Sakhnin,1.21,5.5,8.5,0.0,0.0
+Hapoel Nir Ramat HaSharon,Maccabi Kabilio Jaffa FC,2.6,2.95,2.45,0.0,0.0
+Hapoel Petah Tikva,Hapoel Afula,2.15,2.8,3.25,0.0,0.0
+Hapoel Nof Hagalil,Bnei Yehuda,2.65,2.95,2.45,0.0,0.0
+Racing Club Abidjan,Sporting Gagnoa,2.4,2.65,3.0,0.0,0.0
+Den Haag [W],Feyenoord [W],1.51,4.3,4.15,0.0,0.0
+Sur Club,Al Ittihad [OMA],2.05,2.8,3.55,0.0,0.0
+Al-Msnaa,AL Nahda [OMA],6.0,2.95,1.58,0.0,0.0
+Bani Yas,Masfut,1.17,6.0,8.5,0.0,0.0
+Al Ain [UAE],Dibba Al Fujairah,1.16,6.0,9.5,0.0,0.0
+Al-Arabi [UAE],Ajman,6.0,4.2,1.35,0.0,0.0
+Al Urooba [UAE],Khorfakkan FC,5.75,4.4,1.36,0.0,0.0
+Shirak Gjumri,FC Noah,1.9,3.35,3.2,0.0,0.0
+Ararat Yerevan,BKMA Yerevan,1.57,3.3,4.75,0.0,0.0
+Ethiopia Bunna,Hadia Hosaina,3.1,3.0,2.1,0.0,0.0
+Wolkite Ketema,Ethiopian Medhin,2.8,2.9,2.25,0.0,0.0
+CSD Comunicaciones,Coban Imperial,1.34,3.65,7.0,0.0,0.0
+Fgura United,Vittoriosa Stars,1.29,4.6,6.75,0.0,0.0
+Attard FC,St. Andrews,3.1,3.35,1.9,0.0,0.0
+Naxxar Lions,Melita,1.54,3.75,4.4,0.0,0.0
+Lija Athletic,San Gwann,2.15,3.45,2.55,0.0,0.0
+AS Kigali,APR FC,2.7,2.6,2.6,0.0,0.0

+ 28 - 0
Odds/BetSafe.csv

@@ -0,0 +1,28 @@
+Atletico Baleares,Logroñés,1.95,3.0,4.33,-1.0,-1.0
+Ceuta,SS de los Reyes,3.3,3.0,2.25,-1.0,-1.0
+Parma,Benevento,1.87,3.4,4.2,2.1,1.7
+Burgos,Eibar,3.0,2.8,2.65,-1.0,-1.0
+Cittadella,Bari,2.5,2.9,3.1,-1.0,-1.0
+Nuova Cosenza,Brescia,3.2,3.1,2.3,2.15,1.65
+Genoa,Sudtirol,1.45,4.2,7.0,1.95,1.8
+Modena,Venezia,2.4,3.1,3.0,2.0,1.75
+Perugia,Spal,2.05,3.2,3.75,2.15,1.65
+Reggina,Frosinone,2.5,3.0,2.95,2.1,1.68
+UD Cornella,UCAM Murcia,3.75,3.0,2.1,-1.0,-1.0
+Lugo,Sporting de Gijón,3.1,2.95,2.45,-1.0,-1.0
+Alcoyano,Athletic B,1.83,3.2,4.5,-1.0,-1.0
+Pisa,Ascoli,2.05,3.2,3.75,2.2,1.62
+Levante,Ponferradina,1.36,4.75,8.0,1.8,1.95
+UD Ibiza-Eivissa,Racing B,2.45,2.95,3.1,-1.0,-1.0
+KS Vllaznia,PSG,29.0,13.0,-1.0,-1.0,-1.0
+VfL Wolfsburg,AS Roma W,1.33,4.75,7.5,1.6,2.2
+Sabadell,Real Union,1.85,3.2,4.5,-1.0,-1.0
+Osasuna B,Gimnàstic,2.05,3.1,3.75,2.4,1.53
+Kroatien,Brasilien,9.6,5.1,1.36,1.8,2.09
+Nederländerna,Argentina,3.6,3.15,2.28,2.48,1.57
+Crawley Town,Hartlepool,2.05,3.5,3.5,1.95,1.85
+Gillingham,Dag & Redbridge,2.55,3.2,2.8,2.1,1.72
+Palermo,Como,2.4,3.2,2.95,2.0,1.75
+Malaga,Granada,3.75,3.1,2.1,2.4,1.53
+Real Madrid,Chelsea LFC,3.75,3.4,1.83,1.9,1.8
+St. Polten,SK Slavia Praha,2.1,3.5,2.95,1.68,2.05

+ 71 - 33
Odds/Expekt.csv

@@ -1,33 +1,71 @@
-FC Oleksandriya,Rukh Vynnyky,1.04,9.5,46.0
-Johor Darul Takzim,Borussia Dortmund,801.0,301.0,-1.0
-Sydkorea,Ghana,2.7,3.15,2.95
-Brasilien,Schweiz,1.47,4.5,8.0
-Portugal,Uruguay,2.08,3.35,4.3
-Châteauroux,Le Mans,2.15,3.4,2.85
-UD Ibiza,FC Andorra,3.05,2.9,2.48
-Qarabağ,Zira IK,1.11,6.4,12.5
-Aris Limassol,Pafos FC,2.55,3.0,2.48
-Olympiakos Nicosia,Nea Salamis Famagusta,2.63,2.95,2.48
-Punjab,Aizawl FC,1.68,3.7,4.1
-Csikszereda Miercurea Ciuc,CSC Șelimbăr,1.34,4.1,8.0
-Ayr United,Pollok,1.18,6.5,12.0
-Altinordu,Manisa Büyükşehir Belediyespor,3.15,3.15,2.1
-Wakiso Giants FC,Express FC,1.85,3.0,4.2
-Ecuador,Senegal,2.45,3.25,3.25
-Nederländerna,Qatar,1.21,7.0,17.0
-Iran,USA,4.1,3.55,2.0
-Wales,England,8.5,4.75,1.43
-ASO Chlef,MC EL Bayadh,1.98,2.9,4.1
-Belouizdad,CS Constantine,1.55,3.6,5.8
-MC Alger,Paradou Ac,1.5,3.5,7.5
-NC Magra,USM Alger,4.1,2.85,2.02
-RC Arbaâ,USM Khenchela,2.18,2.65,3.85
-US Biskra,JS Kabylie,2.38,2.6,3.5
-ES Sétif,MC Oran,1.5,3.65,6.5
-JS Saoura,AB Chelghoum Laid,1.11,6.75,20.0
-Kenkre,Neroca FC,3.65,3.05,1.95
-Chindia Târgovişte,Universitatea Craiova,4.1,3.15,1.95
-ND Gorica,Tabor Sezana,2.08,3.2,3.0
-Maribor,NK Bravo,1.7,3.4,4.0
-SV Türkgücü-Ataspor München,SV Heimstetten,1.47,4.25,5.1
-BSG Chemie Leipzig,BFC Dynamo,2.05,3.5,3.0
+PSM Makassar,Persita Tangerang,1.5,3.7,5.5,-1.0,-1.0
+Gillingham,Dag & Red,2.5,3.25,2.85,2.05,1.73
+Burgos,Eibar,3.05,2.7,2.6,-1.0,-1.0
+Lugo,Sporting Gijón,3.1,2.9,2.4,-1.0,-1.0
+Levante,Ponferradina,1.36,4.5,8.0,1.79,1.94
+UD Ibiza,Racing Santander,2.5,2.85,3.05,-1.0,-1.0
+Málaga,Granada,3.85,3.0,2.04,2.48,1.49
+Parma,Benevento,1.85,3.4,4.2,2.07,1.72
+Cittadella,Bari,2.5,2.85,3.1,2.43,1.53
+Cosenza,Brescia,3.5,3.0,2.2,2.2,1.63
+Genoa,Südtirol,1.42,4.1,7.5,1.95,1.81
+Modena,Venezia,2.35,3.0,3.1,1.98,1.78
+Perugia,Spal,2.05,3.1,3.8,2.25,1.61
+Reggina,Frosinone,2.5,2.95,3.0,2.2,1.63
+Pisa,Ascoli,2.05,3.15,3.75,2.18,1.64
+Palermo,Como,2.4,3.0,3.1,1.98,1.78
+KS Vllaznia (d),Paris SG (d),35.0,17.0,1.01,-1.0,-1.0
+VfL Wolfsburg (d),Roma (d),1.3,5.1,8.5,1.53,2.4
+Real Madrid (d),Chelsea (d),3.75,3.4,1.93,1.83,1.93
+St.Pölten-Spratzern (d),Slavia Praha (d),2.05,3.65,3.15,1.79,1.94
+ENPPI Club,Haras El Hodood,1.9,2.9,4.0,-1.0,-1.0
+Smouha SC,Aswan FC,1.93,2.8,4.5,-1.0,-1.0
+Future FC,Al-Ittihad Alexandria,1.73,3.05,5.2,2.1,1.65
+Ceramica Cleopatra,Ismaily,2.3,2.8,3.3,-1.0,-1.0
+TRAU FC,Punjab,3.25,3.05,2.1,1.97,1.78
+Mohun Bagan,Jamshedpur FC,1.75,3.7,4.3,1.7,2.1
+Bali United,Bhayangkara,1.6,3.3,4.7,2.02,1.72
+Hapoel Nof HaGalil F.C.,Bnei Yehuda Tel Aviv,2.8,3.15,2.3,2.2,1.63
+ADO Den Haag (d),Feyenoord (d),1.75,4.35,3.8,1.64,2.12
+Feirense,Santa Clara,3.0,3.0,2.45,2.43,1.53
+Chaves,Porto,6.85,4.7,1.4,1.66,2.15
+FC Botoşani,FCSB,1.8,3.8,3.8,1.65,2.25
+Mioveni,AFC UTA Arad,4.3,3.15,1.9,2.55,1.52
+Oţelul Galaţi,FC Buzău,2.45,3.1,2.9,2.4,1.54
+Falkirk,Dundee FC,4.0,3.5,1.75,1.67,2.14
+Olimpija Ljubljana,NŠ Mura,1.82,3.65,3.3,1.65,2.15
+Aston Villa,Brighton,2.8,3.35,2.4,1.72,2.06
+Reims,Sochaux,1.9,3.6,3.2,1.72,2.02
+Arsenal,Lyon,2.23,3.65,2.8,1.64,2.18
+Getafe,Chivas Guadalajara,2.0,3.9,3.15,1.73,2.02
+Elche,Leeds,2.9,4.1,2.06,1.87,1.87
+Kroatien,Brasilien,10.0,5.1,1.37,1.8,2.04
+Nederländerna,Argentina,3.65,3.15,2.32,2.38,1.6
+Crawley Town,Hartlepool United,2.0,3.6,3.4,1.91,1.81
+Avranches,Nancy,3.0,3.35,2.08,1.95,1.84
+Bourg-Péronnas,Orleans,1.85,3.5,3.55,1.95,1.84
+Le Puy Football 43 Auvergne,Dunkerque,3.15,3.25,2.04,2.1,1.73
+Red Star FC,Versailles 78,1.76,3.6,3.8,1.89,1.9
+Sedan,Cholet,1.92,3.45,3.3,1.9,1.89
+Stade Briochin,Le Mans,2.85,3.5,2.12,1.84,1.96
+Villefranche,Châteauroux,2.16,3.35,2.88,1.98,1.82
+Gobelins,Bastia-Borgo,2.0,3.25,3.3,2.15,1.7
+Brisbane Roar,Adelaide United,2.43,3.75,2.6,1.67,2.2
+Doxa Katokopias,AEK Larnaca,4.9,3.45,1.57,1.84,1.81
+Pafos FC,Apoel Nicosia,2.35,2.65,3.1,2.33,1.49
+Hyderabad FC,Quess East Bengal Club,1.5,4.25,6.0,1.71,2.07
+RANS Nusantara FC,PS Tira,2.7,3.3,2.2,1.65,2.14
+PSIS Semarang,Pusamania Borneo,2.95,3.4,2.05,1.86,1.86
+Coleraine,Crusaders Belfast,2.75,3.35,2.2,1.75,2.02
+Famalicão,CD de Tondela,1.78,3.35,4.7,2.28,1.58
+ACS Sepsi OSK Sfântul Gheorghe,SC FC Voluntari SA,1.53,3.85,6.0,2.04,1.75
+Alloa Athletic,Queen of the South,2.1,3.4,3.0,1.67,2.14
+Arbroath,Dunfermline Athletic,2.15,3.25,3.1,1.81,1.94
+Samsunspor,Yeni Malatyaspor,1.4,4.0,6.1,1.64,2.14
+1. FFC Frankfurt (d),1. FFC Turbine Potsdam (d),1.17,6.4,8.0,-1.0,-1.0
+ETSV Weiche Flensburg,Hannover 96 II,2.1,3.35,3.0,-1.0,-1.0
+Eintracht Norderstedt,SV Drochtersen/Assel,2.05,3.15,3.25,1.65,2.16
+Chemnitzer FC,Hertha Berlin II,1.58,3.8,4.7,1.63,2.2
+VSG Altglienicke,Germania Halberstadt,1.28,5.5,6.75,-1.0,-1.0
+Astoria Walldorf,Hoffenheim II,3.05,3.6,1.95,1.57,2.33
+KCCA,Express FC,1.6,3.6,4.75,1.91,1.81

+ 127 - 42
Odds/NordicBet.csv

@@ -1,42 +1,127 @@
-Johor Darul Ta zim,Borussia Dortmund,51.0,51.0,-1.0
-PAOK,FC Ashdod,1.85,4.0,4.33
-Real Betis (Perapanamera),Lazio (Rodja),1.01,20.0,25.0
-West Ham (Taz),Real Sociedad (Jekos),8.55,3.63,1.45
-Sydkorea,Ghana,2.7,3.15,2.85
-Ierapetra,Proodeftiki,1.7,4.0,4.2
-Kifisia,Kallithea,2.35,2.9,3.2
-Brasilien,Schweiz,1.48,4.4,7.3
-Altinordu,Manisa FK,3.25,3.4,2.2
-Portugal,Uruguay,2.0,3.3,4.2
-ArzignanoChiampo,L.R. Vicenza Virtus,3.4,3.2,2.1
-Ayr United,Pollok,1.15,7.0,15.0
-Hitchin Town,Redditch Utd,2.75,3.4,2.25
-Kings Langley,Nuneaton,2.95,3.3,2.2
-Shandong Luneng,Cangzhou Mighty Lions,1.22,6.5,10.0
-Tianjin Teda,Guangzhou R F,1.6,4.0,5.0
-Hebei China Fortune Football Club,Dalian Aerbin FC,67.0,13.0,1.02
-Shanghai SIPG,Henan Construction,1.75,3.6,4.5
-Wuhan Three Towns,Changchun Yatai,1.28,5.5,9.0
-Zhejiang Professional,Beijing Guoan,2.55,3.5,2.55
-Shenzhen XiangXue,Wuhan Zall,1.68,4.0,4.5
-Pordenone,Pro Patria,1.8,3.3,4.5
-Foggia,Messina,1.7,3.5,4.75
-Tunisien,Frankrike,6.8,4.1,1.55
-Australien,Danmark,7.0,4.2,1.52
-Catanzaro,Giugliano,1.38,4.5,7.5
-Feralpisalo,Juventus-U23,2.2,3.1,3.3
-Lecco,Renate,2.25,3.2,3.1
-Mantova,Albinoleffe,2.4,2.95,3.1
-Pergolettese,Novara,2.7,3.1,2.6
-Piacenza,Triestina,2.7,3.1,2.6
-Virtus Verona,Pro Sesto,2.55,3.0,2.8
-Latina,Monopoli,2.35,3.0,3.1
-Taranto,Crotone,4.2,3.5,1.8
-Polen,Argentina,7.7,4.35,1.47
-Saudiarabien,Mexiko,4.95,4.05,1.68
-Sangiuliano City,Padova,2.55,3.0,2.8
-Avellino,Juve Stabia,2.2,3.1,3.3
-Potenza,Audace Cerignola,2.6,3.0,2.75
-Turris,Fidelis Andria,2.15,3.2,3.3
-Francavilla,Pescara,3.75,3.5,1.87
-Sporting CP,Farense,1.15,7.0,17.0
+Manchester City (ECF_slezaintima),Tottenham Hotspur (ECF_white_boy1927),27.0,15.0,1.01,-1.0,-1.0
+Chelsea (ECF_Upcake22),Manchester United (ECF_Rus_1995_LAN),7.65,1.15,12.0,-1.0,-1.0
+Girona FC,Standard de Liege,2.0,3.75,3.3,1.57,2.35
+Adana Demirspor,FK Liepaja,1.18,6.4,12.0,-1.0,-1.0
+Atletico Baleares,Logroñés,1.95,3.0,4.33,-1.0,-1.0
+Ceuta,SS de los Reyes,3.3,3.0,2.25,-1.0,-1.0
+Viveiro CF,Alondras CF,2.6,3.0,2.65,2.35,1.53
+RC Celta de Vigo III (Gran Pena FC),Club Rapido de Bouzas,2.35,3.0,2.95,2.25,1.57
+Racing Club Villalbes,CD Barco,1.95,3.3,3.6,1.95,1.78
+CD Rota,Coria CF,3.2,2.95,2.25,2.35,1.52
+AD Cartaya,CD Gerena,4.33,3.2,1.8,2.2,1.6
+Conil CF,Córdoba B,3.5,3.2,2.0,2.1,1.66
+UD Ciudad de Torredonjimeno,Atletico Porcuna CF,1.9,3.25,3.75,2.05,1.68
+UD Almeria B,CF Motril,1.57,3.75,5.0,1.72,2.0
+Silva SD,CSD Arzúa,2.05,3.25,3.3,2.1,1.66
+Parma,Benevento,1.87,3.4,4.2,2.1,1.7
+Sivaspor,Saarbrucken,1.65,3.7,4.75,1.52,2.4
+1. FC Tatran Presov,MFK Dukla Banska Bystrica,4.2,4.0,1.68,1.57,2.3
+Burgos,Eibar,3.0,2.8,2.65,-1.0,-1.0
+Fortuna Sittard,Livingston,1.8,4.0,3.75,-1.0,-1.0
+Aston Villa FC,Brighton and Hove Albion FC,2.8,3.5,2.4,1.72,2.1
+Cremonese,Salsomaggiore,1.05,10.0,34.0,-1.0,-1.0
+ATK Mohun Bagan,Jamshedpur FC,1.7,3.75,4.5,1.75,2.0
+Cittadella,Bari,2.5,2.9,3.1,-1.0,-1.0
+Nuova Cosenza,Brescia,3.2,3.1,2.3,2.15,1.65
+Genoa,Sudtirol,1.45,4.2,7.0,1.95,1.8
+Modena,Venezia,2.4,3.1,3.0,2.0,1.75
+Perugia,Spal,2.05,3.2,3.75,2.15,1.65
+Reggina,Frosinone,2.5,3.0,2.95,2.1,1.68
+AS Lamia,NFC Volos,2.7,3.5,2.35,2.05,1.72
+UD Cornella,UCAM Murcia,3.75,3.0,2.1,-1.0,-1.0
+Stade de Reims,FC Sochaux Montbeliard,2.05,3.6,3.3,1.75,2.05
+Casalarreina CF,SD Oyonesa,3.5,3.3,1.95,1.95,1.78
+Lugo,Sporting de Gijón,3.1,2.95,2.45,-1.0,-1.0
+Arsenal,Olympique Lyonnais,2.45,3.6,2.7,1.7,2.15
+CD Choco,Arosa SC,3.5,3.1,2.05,2.05,1.68
+UD Somozas,UD Paiosaco,1.53,3.75,5.5,1.9,1.8
+UD Ourense,Deportivo La Coruna II,2.6,3.2,2.5,1.95,1.78
+Atletico Arteixo,Estradense,2.65,3.25,2.4,2.2,1.6
+NK Olimpija Ljubljana,NÅ  Mura,1.9,3.6,3.6,1.68,2.1
+Feirense,Santa Clara,2.85,3.0,2.6,2.4,1.53
+Alcoyano,Athletic B,1.83,3.2,4.5,-1.0,-1.0
+Pisa,Ascoli,2.05,3.2,3.75,2.2,1.62
+Levante,Ponferradina,1.36,4.75,8.0,1.8,1.95
+UD Ibiza-Eivissa,Racing B,2.45,2.95,3.1,-1.0,-1.0
+Sabadell,Real Union,1.85,3.2,4.5,-1.0,-1.0
+Osasuna B,Gimnàstic,2.05,3.1,3.75,2.4,1.53
+Chaves,Porto,7.0,4.75,1.4,1.63,2.2
+Gillingham,Dag & Redbridge,2.55,3.2,2.8,2.1,1.72
+Elche CF,Leeds United,3.0,3.75,2.15,1.87,1.87
+Palermo,Como,2.4,3.2,2.95,2.0,1.75
+Malaga,Granada,3.75,3.1,2.1,2.45,1.52
+Keciörengücü,Adanaspor,1.78,3.75,4.33,1.75,2.1
+Tuzlaspor,Çaykur Rizespor,3.5,3.5,2.05,1.9,1.9
+Guangzhou,Guangzhou R F,2.6,3.5,2.5,2.0,1.75
+Zhejiang Professional,Meizhou Hakka,1.68,3.75,4.75,1.8,1.95
+Chengdu Rongcheng,Shanghai SIPG,2.95,3.4,2.3,1.95,1.8
+Kifisia,Ierapetra,1.28,4.85,10.0,1.9,1.82
+Blackburn,Preston,2.18,3.25,3.45,2.25,1.65
+AŠK Bravo,NK Koper,2.85,3.2,2.4,2.05,1.72
+FC Goa,Odisha FC,2.1,3.6,3.1,1.62,2.2
+Granada B,UCAM Murcia,3.3,3.1,2.2,2.15,1.65
+Rotherham,Bristol City,2.92,3.3,2.4,2.01,1.8
+Ipswich,Peterborough,1.55,4.2,5.5,1.87,1.9
+Shrewsbury,Bolton,3.1,3.3,2.3,2.15,1.7
+Irodotos,Kallithea,8.5,4.35,1.35,1.86,1.86
+Carlisle,Barrow,2.35,3.2,3.1,2.2,1.66
+Crewe,Leyton Orient,3.75,3.4,2.0,2.3,1.6
+Harrogate Town,Northampton,3.0,3.3,2.35,2.1,1.72
+Denizlispor,Altay,3.1,3.4,2.25,2.0,1.8
+Alessandria,Montevarchi,2.4,3.0,3.0,2.45,1.52
+Reggiana,Olbia,1.44,4.33,6.5,1.8,1.95
+San Donato Tavarnelle,Imolese,2.2,3.0,3.4,2.45,1.52
+Vis Pesaro,Cesena,4.0,3.2,1.95,2.4,1.53
+Reading,Coventry,2.5,3.25,2.85,2.14,1.71
+Burton Albion,Derby,3.1,3.4,2.25,1.95,1.83
+Forest Green,Cheltenham,2.45,3.3,2.9,2.05,1.75
+Rochdale,Stockport,4.0,3.5,1.9,2.1,1.72
+NorthEast United,Chennaiyin FC,3.6,3.5,1.95,1.83,1.9
+Banbury United,Curzon Ashton,1.95,3.6,3.5,1.8,1.95
+Buxton,Peterborough Sports,2.4,3.3,2.75,2.0,1.75
+Chester,Alfreton Town,1.83,3.6,4.0,1.95,1.8
+Chorley,Telford,1.7,3.75,4.5,1.75,2.0
+Farsley Celtic,Leamington,2.0,3.4,3.5,2.0,1.75
+Gloucester City,Darlington,2.65,3.6,2.35,1.8,1.95
+Kettering,AFC Fylde,3.6,3.6,1.9,1.83,1.9
+Kidderminster,Blyth Spartans,1.6,4.0,5.0,1.85,1.9
+Kings Lynn,Bradford PA,1.33,4.75,8.5,1.8,1.95
+Scarborough Athletic,Brackley,3.5,3.4,2.0,2.0,1.75
+Southport,Boston Utd,2.4,3.5,2.65,1.8,1.95
+Spennymoor Town FC,Hereford,2.25,3.3,3.0,1.87,1.87
+Blackpool,Birmingham,2.75,3.3,2.55,2.04,1.77
+Middlesbrough,Luton,1.8,3.65,4.4,2.03,1.78
+Millwall,Wigan,1.88,3.45,4.25,2.22,1.66
+Sheffield Utd,Huddersfield,1.48,4.4,6.4,1.76,2.07
+Stoke,Cardiff,2.08,3.45,3.55,2.07,1.76
+Swansea,Norwich,2.4,3.45,2.85,1.9,1.9
+Accrington,Portsmouth,3.25,3.5,2.15,1.9,1.9
+Bristol Rovers,Port Vale,2.5,3.3,2.8,1.95,1.83
+Cambridge,Plymouth,3.2,3.5,2.15,1.83,1.95
+Exeter,Sheffield Wed,3.75,3.6,1.95,2.0,1.83
+Lincoln,Wycombe,2.9,3.3,2.45,2.05,1.75
+Milton Keynes,Fleetwood,2.2,3.3,3.3,2.1,1.72
+Morecambe,Charlton,3.75,3.6,1.95,2.0,1.83
+Oxford Utd,Barnsley,2.3,3.4,3.0,2.0,1.8
+Grimsby,Tranmere,2.3,3.2,3.2,2.3,1.62
+Newport County,Doncaster,2.05,3.4,3.6,2.15,1.7
+Salford City FC,Walsall,2.45,3.25,2.9,2.25,1.63
+Stevenage,Mansfield,2.05,3.4,3.6,2.05,1.75
+Sutton United,Colchester,1.95,3.4,4.0,2.15,1.7
+Swindon,AFC Wimbledon,1.95,3.6,3.75,1.95,1.85
+Marocko,Portugal,5.35,3.8,1.7,2.18,1.69
+Cádiz CF B,Betis B,2.35,2.95,3.2,-1.0,-1.0
+Burgos Promesas,Palencia,3.4,3.25,2.1,2.15,1.65
+UD Mutilvera,Alfaro,2.1,3.1,3.6,2.2,1.62
+Racing Rioja,Tudelano,2.7,3.0,2.65,-1.0,-1.0
+Real Sociedad B,CF La Nucía,2.05,3.1,3.75,2.4,1.53
+Göztepe,Manisa FK,2.3,3.4,3.0,1.87,1.9
+Celta B,Cultural Leonesa,2.1,3.1,3.6,2.1,1.68
+AD San Juan,Logrones Promesas,2.15,3.2,3.3,2.2,1.62
+Lucchese,Carrarese,2.3,3.0,3.2,-1.0,-1.0
+Pontedera,Fermana,1.95,3.2,4.0,-1.0,-1.0
+Rimini,Ancona,2.5,3.0,2.9,-1.0,-1.0
+Siena,Fiorenzuola,2.1,3.1,3.6,-1.0,-1.0
+Sassari Torres,Gubbio,3.4,3.1,2.15,2.45,1.52
+Guijuelo,Bergantinos,1.95,3.3,3.75,2.15,1.65
+CD Eldense,Amorebieta,1.75,3.5,4.5,2.35,1.55

BIN
Odds/chromedriver.exe


+ 20 - 19
Odds/src/Main.java

@@ -10,30 +10,13 @@ public class Main {
     public static void main(String[] args) {
     public static void main(String[] args) {
 
 
         // testExpektParser();
         // testExpektParser();
-//        updateFromOddsportal();
+        updateFromOddsportal();
 
 
-        testArbMatches();
+//        testArbMatches();
 //        op.getHistoricMatches("soccer", "japan", "j2-league", "2020");
 //        op.getHistoricMatches("soccer", "japan", "j2-league", "2020");
         // callingRScript();
         // callingRScript();
     }
     }
 
 
-    private static void testArbMatches() {
-        new ArbChecker();
-    }
-
-    private static void updateFromOddsportal() {
-        final OddsPortal op = new OddsPortal();
-        System.out.println("Getting Yesterdays matches");
-        op.getYesterdaysMatches();
-        System.out.println("Getting Todays Matches");
-        op.getTodaysMatches();
-        System.out.println("Getting tomorrows matches");
-        op.getTomorrowsMatches();
-
-        System.out.println("Getting next matches");
-        op.getNextDaysMatches();
-    }
-
     private static void callingRScript() throws IOException {
     private static void callingRScript() throws IOException {
         System.out.println(System.getProperty("user.dir"));
         System.out.println(System.getProperty("user.dir"));
         final String rPath = System.getProperty("user.dir") + "\\src\\RScript\\scorePrediction.R";
         final String rPath = System.getProperty("user.dir") + "\\src\\RScript\\scorePrediction.R";
@@ -57,4 +40,22 @@ public class Main {
         }
         }
     }
     }
 
 
+    private static void testArbMatches() {
+        new ArbChecker();
+    }
+
+    private static void updateFromOddsportal() {
+        final OddsPortal op = new OddsPortal();
+        System.out.println("Getting Yesterdays matches");
+        op.getYesterdaysMatches();
+        System.out.println("Getting Todays Matches");
+        op.getTodaysMatches();
+        System.out.println("Getting tomorrows matches");
+        op.getTomorrowsMatches();
+
+        System.out.println("Getting next matches");
+        op.getNextDaysMatches();
+
+    }
+
 }
 }

+ 99 - 48
Odds/src/main/ArbChecker.java

@@ -12,6 +12,8 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.List;
 
 
 import object.ArbResults;
 import object.ArbResults;
+import parser.BWinParser;
+import parser.BetHard;
 import parser.BetSafeParser;
 import parser.BetSafeParser;
 import parser.ExpektParser;
 import parser.ExpektParser;
 import parser.NordicBetParser;
 import parser.NordicBetParser;
@@ -21,84 +23,133 @@ public class ArbChecker {
     private List<ArbResults> nordicBetMatches = new ArrayList<>();
     private List<ArbResults> nordicBetMatches = new ArrayList<>();
     private List<ArbResults> expektResults = new ArrayList<>();
     private List<ArbResults> expektResults = new ArrayList<>();
     private List<ArbResults> betSafeResults = new ArrayList<>();
     private List<ArbResults> betSafeResults = new ArrayList<>();
+    private List<ArbResults> betHardResults = new ArrayList<>();
+    private List<ArbResults> bWinResults = new ArrayList<>();
 
 
     public ArbChecker() {
     public ArbChecker() {
-    //    NordicBetParser nbp = new NordicBetParser();
-    //    nordicBetMatches.addAll(nbp.parseSoccerMatches().stream().map(m -> new ArbResults(m, "NordicBet")).toList());
-    //    printResultsToArrayFile(nordicBetMatches, "NordicBet.csv");
+        NordicBetParser nbp = new NordicBetParser();
+        nordicBetMatches.addAll(nbp.parseSoccerMatches().stream().map(m -> new ArbResults(m, "NordicBet")).toList());
+        printResultsToArrayFile(nordicBetMatches, "NordicBet.csv");
 
 
-    //    ExpektParser ep = new ExpektParser();
-    //    expektResults.addAll(ep.seleniumParseSoccerMatches().stream().map(m -> new ArbResults(m, "Expekt")).toList());
-    //    printResultsToArrayFile(expektResults, "Expekt.csv");
+        ExpektParser ep = new ExpektParser();
+        expektResults.addAll(ep.seleniumParseSoccerMatches().stream().map(m -> new ArbResults(m, "Expekt")).toList());
+        printResultsToArrayFile(expektResults, "Expekt.csv");
 
 
-    // BetSafeParser bsp = new BetSafeParser();
-    // betSafeResults.addAll(bsp.seleniumPaseSoccerMatches().stream().map(m -> new ArbResults(m, "BetSafe")).toList());
-    // printResultsToArrayFile(betSafeResults, "BetSafe.csv");
+        BetSafeParser bsp = new BetSafeParser();
+        betSafeResults.addAll(bsp.seleniumPaseSoccerMatches().stream().map(m -> new ArbResults(m, "BetSafe")).toList());
+        printResultsToArrayFile(betSafeResults, "BetSafe.csv");
+
+        BetHard bh = new BetHard();
+        betHardResults.addAll(bh.seleniumParseMatches().stream().map(m -> new ArbResults(m, "BetHard")).toList());
+        printResultsToArrayFile(betHardResults, "BetHard.csv");
+
+        BWinParser bwin = new BWinParser();
+        bWinResults
+                .addAll(bwin.parseSoccerMatches().stream().map(m -> new ArbResults(m, BWinParser.BOOKIE)).toList());
+        printResultsToArrayFile(bWinResults, BWinParser.BOOKIE + ".csv");
 
 
         getResultsFromFile("NordicBet.csv", nordicBetMatches, "NordicBet");
         getResultsFromFile("NordicBet.csv", nordicBetMatches, "NordicBet");
         getResultsFromFile("Expekt.csv", expektResults, "Expekt");
         getResultsFromFile("Expekt.csv", expektResults, "Expekt");
-        getResultsFromFile("BetSafe.csv", expektResults, "BetSafe");
+        getResultsFromFile("BetSafe.csv", betSafeResults, "BetSafe");
+        getResultsFromFile("BetHard.csv", betHardResults, "BetHard");
+        getResultsFromFile(BWinParser.BOOKIE + ".csv", bWinResults, BWinParser.BOOKIE);
 
 
         List<SimpleEntry<String, List<ArbResults>>> resultLists = new ArrayList<>();
         List<SimpleEntry<String, List<ArbResults>>> resultLists = new ArrayList<>();
         SimpleEntry<String, List<ArbResults>> entryNordicBet = new SimpleEntry<>("NordicBet", this.nordicBetMatches);
         SimpleEntry<String, List<ArbResults>> entryNordicBet = new SimpleEntry<>("NordicBet", this.nordicBetMatches);
         SimpleEntry<String, List<ArbResults>> betSafe = new SimpleEntry<>("BetSafe", this.betSafeResults);
         SimpleEntry<String, List<ArbResults>> betSafe = new SimpleEntry<>("BetSafe", this.betSafeResults);
+        SimpleEntry<String, List<ArbResults>> betHard = new SimpleEntry<>("BetHard", this.betHardResults);
+        SimpleEntry<String, List<ArbResults>> expekt = new SimpleEntry<>("Expekt", this.expektResults);
+        SimpleEntry<String, List<ArbResults>> bwinEntries = new SimpleEntry<>(BWinParser.BOOKIE, this.bWinResults);
 
 
+        resultLists.add(expekt);
         resultLists.add(entryNordicBet);
         resultLists.add(entryNordicBet);
         resultLists.add(betSafe);
         resultLists.add(betSafe);
-        checkForArbs(new SimpleEntry<>("Expekt", expektResults), resultLists);
+        resultLists.add(betHard);
+        resultLists.add(bwinEntries);
+        checkForArbs(resultLists);
+
     }
     }
 
 
-    private void checkForArbs(SimpleEntry<String, List<ArbResults>> mainList,
-            List<SimpleEntry<String, List<ArbResults>>> resultLists) {
-        for (ArbResults match : mainList.getValue()) {
-            String replaceParentecesRegEx = "\\(.*\\)| [A-Za-z]{2} |Club|club";
-            List<String> homeTeamParts = Arrays
-                    .asList(match.getHomeTeam().replaceAll(replaceParentecesRegEx, "").trim().split(" "));
-            List<String> awayTeamParts = Arrays
-                    .asList(match.getAwayTeam().replaceAll(replaceParentecesRegEx, "").trim().split(" "));
-
-            for (SimpleEntry<String, List<ArbResults>> list : resultLists) {
-                List<ArbResults> homeTeamFound = list.getValue().stream()
-                        .filter(p -> Arrays.asList(p.getHomeTeam().replaceAll(replaceParentecesRegEx, "")
-                                .trim().split(" ")).stream().anyMatch(homeTeamParts::contains))
+    private void checkForArbs(List<SimpleEntry<String, List<ArbResults>>> resultLists) {
+        ArrayList<ArbResults> addedMatches = new ArrayList<>();
+
+        String replaceParentecesRegEx = "\\(.*\\)| [A-Za-z]{2} |Club|club|II|FC|NK|AL|Al";
+
+        for (SimpleEntry<String, List<ArbResults>> list : resultLists) {
+            for (ArbResults match : list.getValue()) {
+
+                List<String> homeTeamParts = Arrays
+                        .asList(match.getHomeTeam().replaceAll(replaceParentecesRegEx, "").trim().split(" "));
+                List<String> awayTeamParts = Arrays
+                        .asList(match.getAwayTeam().replaceAll(replaceParentecesRegEx, "").trim().split(" "));
+
+                List<ArbResults> homeTeamFound = addedMatches.stream()
+                        .filter(p -> p.getHomeTeam().replaceAll(replaceParentecesRegEx, "")
+                                .trim().equals(match.getHomeTeam().replaceAll(replaceParentecesRegEx, "")
+                                        .trim()))
                         .toList();
                         .toList();
 
 
-                List<ArbResults> awayTeamFound = list.getValue().stream()
-                        .filter(p -> Arrays.asList(p.getAwayTeam().replaceAll(replaceParentecesRegEx, "")
-                                .trim().split(" ")).stream().anyMatch(awayTeamParts::contains))
+                List<ArbResults> awayTeamFound = addedMatches.stream()
+                        .filter(p -> p.getAwayTeam().replaceAll(replaceParentecesRegEx, "")
+                                .trim().equals(match.getAwayTeam().replaceAll(replaceParentecesRegEx, "")
+                                        .trim()))
                         .toList();
                         .toList();
 
 
                 if (homeTeamFound.isEmpty() || awayTeamFound.isEmpty()) {
                 if (homeTeamFound.isEmpty() || awayTeamFound.isEmpty()) {
-//                    System.out.println(match.getHomeTeam() + "-" + match.getAwayTeam() + " Not found in list");
-                    continue;
+                    addedMatches.add(new ArbResults(match.getHomeTeam(), match.getAwayTeam(), match.getOdds1(),
+                            match.getOddsX(), match.getOdds2(), list.getKey()));
+                } else if (homeTeamFound.size() == 1) {
+                    homeTeamFound.get(0).addOdds1(list.getKey(), match.getOdds1());
+                    homeTeamFound.get(0).addOddsX(list.getKey(), match.getOddsX());
+                    homeTeamFound.get(0).addOdds2(list.getKey(), match.getOdds2());
+
+                    homeTeamFound.get(0).addOver25Odds(list.getKey(), match.getOver25());
+                    homeTeamFound.get(0).addUnder25Odds(list.getKey(), match.getUnder25());
+                } else if (awayTeamFound.size() == 1) {
+                    awayTeamFound.get(0).addOdds1(list.getKey(), match.getOdds1());
+                    awayTeamFound.get(0).addOddsX(list.getKey(), match.getOddsX());
+                    awayTeamFound.get(0).addOdds2(list.getKey(), match.getOdds2());
+
+                    awayTeamFound.get(0).addOver25Odds(list.getKey(), match.getOver25());
+                    awayTeamFound.get(0).addUnder25Odds(list.getKey(), match.getUnder25());
+                } else if (homeTeamFound.size() > 1) {
+                    for (ArbResults htf : homeTeamFound) {
+                        System.out.println("Multiple found home " + htf);
+                    }
+                } else if (awayTeamFound.size() > 1) {
+                    for (ArbResults atf : awayTeamFound) {
+                        System.out.println("Multiple found away " + atf);
+                    }
                 }
                 }
+            }
+        }
 
 
-                if (homeTeamFound.size() == 1) {
-                    match.addOdds1(list.getKey(), homeTeamFound.get(0).getOdds1());
-                    match.addOddsX(list.getKey(), homeTeamFound.get(0).getOddsX());
-                    match.addOdds2(list.getKey(), homeTeamFound.get(0).getOdds2());
-                    System.out.println(
-                            "Found match mainlist " + match.toStringWithExtra() + " arb value "
-                                    + calculateArbValue3Part(match));
-                } else if (awayTeamFound.size() == 1) {
-                    match.addOdds1(list.getKey(), awayTeamFound.get(0).getOdds1());
-                    match.addOddsX(list.getKey(), awayTeamFound.get(0).getOddsX());
-                    match.addOdds2(list.getKey(), awayTeamFound.get(0).getOdds2());
-                    System.out.println(
-                            "Found match mainlist " + match.toStringWithExtra() + " arb value "
-                                    + calculateArbValue3Part(match));
+        List<ArbResults> GOGOList = new ArrayList<>();
+        for (ArbResults match : addedMatches) {
+            if (match.multipleOddsExist()) {
+                if (calculateArbValue3Part(match) < 1.0f
+                        || match.getArbValueOverUnder() > 0f && match.getArbValueOverUnder() < 1.0f) {
+                    GOGOList.add(match);
+                } else {
+                    System.out.println("Result " + match.toStringWithExtra() + " arb value "
+                            + calculateArbValue3Part(match) + " OverUnderVal " + match.getArbValueOverUnder());
                 }
                 }
             }
             }
         }
         }
+        for (ArbResults match : GOGOList) {
+            System.out.println("GOGOGOGOGOGO Result " + match.toStringWithExtra() + " arb value "
+                    + calculateArbValue3Part(match) + " Over Under arb value" + match.getArbValueOverUnder());
+        }
     }
     }
 
 
     private float calculateArbValue3Part(ArbResults res) {
     private float calculateArbValue3Part(ArbResults res) {
-        return (1 / res.getMaxOdds1().getOdds()) + (1 / res.getMaxOddsX().getOdds()) + (1 / res.getMaxOdds2().getOdds());
+        return (1 / res.getMaxOdds1().getOdds()) + (1 / res.getMaxOddsX().getOdds())
+                + (1 / res.getMaxOdds2().getOdds());
     }
     }
 
 
     private void printResultsToArrayFile(List<ArbResults> results, String fileName) {
     private void printResultsToArrayFile(List<ArbResults> results, String fileName) {
         try (BufferedWriter bw = new BufferedWriter(
         try (BufferedWriter bw = new BufferedWriter(
-            new FileWriter(System.getProperty("user.dir") + File.separator + fileName))) {
+                new FileWriter(System.getProperty("user.dir") + File.separator + fileName))) {
             StringBuilder sb = new StringBuilder();
             StringBuilder sb = new StringBuilder();
 
 
             for (ArbResults r : results) {
             for (ArbResults r : results) {
@@ -108,7 +159,6 @@ public class ArbChecker {
 
 
             bw.write(sb.toString());
             bw.write(sb.toString());
         } catch (IOException e) {
         } catch (IOException e) {
-            // TODO Auto-generated catch block
             e.printStackTrace();
             e.printStackTrace();
         }
         }
     }
     }
@@ -122,10 +172,11 @@ public class ArbChecker {
                 String[] values = line.split(",");
                 String[] values = line.split(",");
                 resultsList.add(new ArbResults(values[0], values[1], Float.parseFloat(values[2]),
                 resultsList.add(new ArbResults(values[0], values[1], Float.parseFloat(values[2]),
                         Float.parseFloat(values[3]),
                         Float.parseFloat(values[3]),
-                        Float.parseFloat(values[4]), bookie));
+                        Float.parseFloat(values[4]),
+                        Float.parseFloat(values[5]),
+                        Float.parseFloat(values[6]), bookie));
             }
             }
         } catch (IOException e) {
         } catch (IOException e) {
-            // TODO Auto-generated catch block
             e.printStackTrace();
             e.printStackTrace();
         }
         }
     }
     }

+ 261 - 193
Odds/src/mysql/Mysql.java

@@ -9,6 +9,7 @@ import java.sql.Statement;
 import java.time.LocalDate;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatter;
+import java.util.List;
 
 
 import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.log.Log;
 
 
@@ -37,65 +38,154 @@ public class Mysql {
         return instance;
         return instance;
     }
     }
 
 
-    protected Connection getConnection() {
-        if (conn == null) {
-            try {
-                conn = DriverManager.getConnection(URL + DATABASE + TIMEZONE_FIX, USERNAME, PASSWORD);
-            } catch (final SQLException e) {
-                throw new RuntimeException(e.getMessage(), e);
-            }
+    public int addCountry(String name) throws SQLException {
+        name = name.replace(" ", "-");
+        name = name.replace("\\.", "");
+        final String sql = "INSERT INTO Country (name) VALUES (?) ON DUPLICATE KEY UPDATE name = ?";
+        try (PreparedStatement stat = conn.prepareStatement(sql)) {
+            stat.setString(1, name);
+            stat.setString(2, name);
+            stat.executeUpdate();
         }
         }
-        return conn;
+
+        return getId("Country", name, -1, -1);
     }
     }
 
 
-    public CurrentParsing getCurrentParsing() {
-        final CurrentParsing returnValue = new CurrentParsing();
-        final String sql = "SELECT * FROM parsing";
-        try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            final ResultSet rs = stat.executeQuery();
-            while (rs.next()) {
-                returnValue.setDone(rs.getBoolean("done"));
-                returnValue.setCurrentYear(rs.getInt("year"));
-                returnValue.setCurrentDate(rs.getDate("gameDate"));
-                returnValue.setLeague(rs.getString("league"));
-                returnValue.setPage(rs.getInt("page"));
+    public int addLeague(String leagueName, String country, String sport) {
+        int countryId = -1;
+        try {
+            leagueName = leagueName.trim();
+            leagueName = leagueName.replace(" ", "-");
+            leagueName = leagueName.replace("\\.", "");
+            final int sportId = addSport(sport);
+            countryId = addCountry(country);
+            final String sql = "INSERT INTO League (name, sportId, countryId) VALUES (?, ?, ?) "
+                    + "ON DUPLICATE KEY UPDATE name = ?";
+            try (PreparedStatement stat = conn.prepareStatement(sql)) {
+                stat.setString(1, leagueName);
+                stat.setInt(2, sportId);
+                stat.setInt(3, countryId);
+                stat.setString(4, leagueName);
+
+                stat.executeUpdate();
             }
             }
-        } catch (final SQLException e) {
+        } catch (SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-        return returnValue;
+        return getId("League", leagueName, countryId, -1);
     }
     }
 
 
-    public int addLeague(String leagueName, String country, String sport) throws SQLException {
-        leagueName = leagueName.trim();
-        leagueName = leagueName.replace(" ", "-");
-        leagueName = leagueName.replace("\\.", "");
-        final int sportId = addSport(sport);
-        final int countryId = addCountry(country);
-        final String sql = "INSERT INTO League (name, sportId, countryId) VALUES (?, ?, ?) "
-                + "ON DUPLICATE KEY UPDATE name = ?";
-        try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setString(1, leagueName);
-            stat.setInt(2, sportId);
-            stat.setInt(3, countryId);
-            stat.setString(4, leagueName);
+    public void addResult(ResultDTO result) {
+        if (result.getCountryId() < 0 || result.getLeagueId() < 0) {
+            System.out.println(String.format("Must supply countryId %s and leagueId %s", result.getCountryId(),
+                    result.getLeagueId()));
+            return;
+        }
+        try {
+            int homeTeamId = getOrInsertTeam(result.getHomeTeam(), result.getCountryId(), result.getLeagueId(),
+                    result.getSportId());
+
+            final int awayTeamId = getOrInsertTeam(result.getAwayTeam(), result.getCountryId(), result.getLeagueId(),
+                    result.getSportId());
+
+            final String selectSql = "SELECT id FROM SoccerResults WHERE homeTeamId = ? AND awayTeamId = ? AND DATE(gameDate) = DATE(?)";
+            final ResultSet rs;
+            int gameId = -1;
+            final String date = result.getGameDate().format(DateTimeFormatter.ISO_DATE);
+            try (PreparedStatement stat = conn.prepareStatement(selectSql)) {
+                stat.setInt(1, homeTeamId);
+                stat.setInt(2, awayTeamId);
+                stat.setString(3, date);
 
 
-            stat.executeUpdate();
+                rs = stat.executeQuery();
+                while (rs.next()) {
+                    gameId = rs.getInt("id");
+                }
+            }
+
+            if (gameId != -1) {
+                final String sql = "UPDATE " + result.getTableName()
+                        + " SET homeScore = ?, awayScore = ?, overtime = ?, odds1 = ?, oddsX = ?, odds2 = ? "
+                        + "WHERE homeTeamId = ? AND awayTeamId = ? AND DATE(gameDate) = ?";
+
+                try (PreparedStatement stat = conn.prepareStatement(sql)) {
+                    stat.setInt(1, result.getHomeScore());
+                    stat.setInt(2, result.getAwayScore());
+                    stat.setBoolean(3, result.isOvertime());
+                    stat.setFloat(4, result.getOdds1());
+                    stat.setFloat(5, result.getOddsX());
+                    stat.setFloat(6, result.getOdds2());
+                    stat.setInt(7, homeTeamId);
+                    stat.setInt(8, awayTeamId);
+                    stat.setString(9, date);
+
+                    stat.executeUpdate();
+                }
+
+            } else {
+                final String sql = "INSERT INTO " + result.getTableName()
+                        + " (homeTeamId, awayTeamId, homeScore, awayScore, overtime, odds1, oddsX, odds2, countryId, gameDate, season, leagueId) "
+                        + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE homeScore = ?, awayScore = ?, odds1 = ?, oddsX = ?, odds2 = ?";
+                try (PreparedStatement stat = conn.prepareStatement(sql)) {
+                    stat.setInt(1, homeTeamId);
+                    stat.setInt(2, awayTeamId);
+                    stat.setInt(3, result.getHomeScore());
+                    stat.setInt(4, result.getAwayScore());
+                    stat.setBoolean(5, result.isOvertime());
+                    stat.setFloat(6, result.getOdds1());
+                    stat.setFloat(7, result.getOddsX());
+                    stat.setFloat(8, result.getOdds2());
+                    stat.setInt(9, result.getCountryId());
+                    stat.setString(10, result.getGameDate().toString());
+                    stat.setString(11, result.getSeason());
+                    stat.setInt(12, result.getLeagueId());
+                    stat.setInt(13, result.getHomeScore());
+                    stat.setInt(14, result.getAwayScore());
+                    stat.setFloat(15, result.getOdds1());
+                    stat.setFloat(16, result.getOddsX());
+                    stat.setFloat(17, result.getOdds2());
+
+                    stat.execute();
+                }
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
         }
         }
-        return getId("League", leagueName, countryId, -1);
     }
     }
 
 
-    public int addCountry(String name) throws SQLException {
-        name = name.replace(" ", "-");
-        name = name.replace("\\.", "");
-        final String sql = "INSERT INTO Country (name) VALUES (?) ON DUPLICATE KEY UPDATE name = ?";
+    public void addResults(List<ResultDTO> resultsToInsert) {
+
+        final String sql = "INSERT INTO SoccerResults (homeTeamId, awayTeamId, homeScore, awayScore, overtime, odds1, oddsX, odds2, countryId, gameDate, season, leagueId) "
+                + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE homeScore = ?, awayScore = ?, odds1 = ?, oddsX = ?, odds2 = ?";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setString(1, name);
-            stat.setString(2, name);
-            stat.executeUpdate();
-        }
 
 
-        return getId("Country", name, -1, -1);
+            for (ResultDTO resultDTO : resultsToInsert) {
+
+                stat.setInt(1, resultDTO.getHomeTeamId());
+                stat.setInt(2, resultDTO.getAwayTeamId());
+                stat.setInt(3, resultDTO.getHomeScore());
+                stat.setInt(4, resultDTO.getAwayScore());
+                stat.setBoolean(5, resultDTO.isOvertime());
+                stat.setFloat(6, resultDTO.getOdds1());
+                stat.setFloat(7, resultDTO.getOddsX());
+                stat.setFloat(8, resultDTO.getOdds2());
+                stat.setInt(9, resultDTO.getCountryId());
+                stat.setString(10, resultDTO.getGameDate().toString());
+                stat.setString(11, resultDTO.getSeason());
+                stat.setInt(12, resultDTO.getLeagueId());
+                stat.setInt(13, resultDTO.getHomeScore());
+                stat.setInt(14, resultDTO.getAwayScore());
+                stat.setFloat(15, resultDTO.getOdds1());
+                stat.setFloat(16, resultDTO.getOddsX());
+                stat.setFloat(17, resultDTO.getOdds2());
+
+                stat.addBatch();
+            }
+
+            stat.executeBatch();
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
     }
     }
 
 
     public int addSport(String sport) throws SQLException {
     public int addSport(String sport) throws SQLException {
@@ -110,43 +200,13 @@ public class Mysql {
         return getId("Sport", sport, -1, -1);
         return getId("Sport", sport, -1, -1);
     }
     }
 
 
-    private int getId(String table, String name, int countryId, int leagueId) throws SQLException {
-        String sql = "SELECT id FROM " + table + " WHERE name = ?";
-        int id = -1;
-        if (countryId > -1) {
-            sql += " AND countryId = ?";
-        }
-        if (leagueId > -1) {
-            sql += " AND leagueId = ?";
-        }
-        try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setString(1, name.trim());
-            if (countryId > -1 && leagueId > -1) {
-                stat.setInt(2, countryId);
-                stat.setInt(3, leagueId);
-            } else if (countryId > -1) {
-                stat.setInt(2, countryId);
-            } else if (leagueId > -1) {
-                stat.setInt(2, leagueId);
-            }
-            final ResultSet insertRs = stat.executeQuery();
-            if (insertRs.next()) {
-                id = insertRs.getInt("id");
-            }
-        }
-        return id;
-    }
-
-    public int getLeagueId(int sportId, int countryId, String leagueName) {
-        final String sql = "SELECT id FROM League WHERE name = ? AND countryId = ? AND sportId = ?";
+    public int getCountryId(String country) {
+        final String sql = "SELECT id from Country WHERE name = ?";
         int id = -1;
         int id = -1;
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setString(1, leagueName.trim());
-            stat.setInt(2, countryId);
-            stat.setInt(3, sportId);
+            stat.setString(1, country.trim());
 
 
             final ResultSet rs = stat.executeQuery();
             final ResultSet rs = stat.executeQuery();
-
             while (rs.next()) {
             while (rs.next()) {
                 id = rs.getInt("id");
                 id = rs.getInt("id");
             }
             }
@@ -156,114 +216,113 @@ public class Mysql {
         return id;
         return id;
     }
     }
 
 
-    public int getSportId(String sportName) {
-        final String sql = "SELECT id from Sport WHERE name = ?";
-        int id = 0;
+    public CurrentParsing getCurrentParsing() {
+        final CurrentParsing returnValue = new CurrentParsing();
+        final String sql = "SELECT * FROM parsing";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setString(1, sportName.trim());
-
             final ResultSet rs = stat.executeQuery();
             final ResultSet rs = stat.executeQuery();
             while (rs.next()) {
             while (rs.next()) {
-                id = rs.getInt("id");
+                returnValue.setDone(rs.getBoolean("done"));
+                returnValue.setCurrentYear(rs.getInt("year"));
+                returnValue.setCurrentDate(rs.getDate("gameDate"));
+                returnValue.setLeague(rs.getString("league"));
+                returnValue.setPage(rs.getInt("page"));
             }
             }
         } catch (final SQLException e) {
         } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-        return id;
+        return returnValue;
     }
     }
 
 
-    public int getCountryId(String country) throws SQLException {
-        final String sql = "SELECT id from Country WHERE name = ?";
-        int id = -1;
+    public Connection getDbConnection() {
+        if (conn == null) {
+            conn = getConnection();
+        }
+        return conn;
+    }
+
+    public String getLastParsedYear(String leagueName, int countryId) {
+        String returnValue = "";
+
+        final String sql = "SELECT parsedYear FROM League WHERE name = ? AND countryId = ?";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setString(1, country.trim());
+            stat.setString(1, leagueName);
+            stat.setInt(2, countryId);
 
 
             final ResultSet rs = stat.executeQuery();
             final ResultSet rs = stat.executeQuery();
+
             while (rs.next()) {
             while (rs.next()) {
-                id = rs.getInt("id");
+                returnValue = rs.getString("parsedYear");
             }
             }
+        } catch (final SQLException e) {
+            e.printStackTrace();
         }
         }
-        return id;
+
+        return returnValue;
     }
     }
 
 
-    public void addResult(ResultDTO result) throws SQLException {
-//		String tableName, LocalDateTime gameDate, String homeTeam, String awayTeam, int homeScore,
-//			int awayScore, boolean overtime, float odds1, float oddsX, float odds2, int countryId, String season,
-//			int leagueId, int sportId) throws SQLException {
+    public String getLastSeason(int leagueId, int countryId) {
+        String result = "";
+        String sql = "SELECT season FROM SoccerResults WHERE leagueId = ? AND countryId = ? ORDER BY gameDate DESC limit 1";
+
+        try (PreparedStatement stat = getConnection().prepareStatement(sql)) {
+            stat.setInt(1, leagueId);
+            stat.setInt(2, countryId);
+
+            ResultSet rs = stat.executeQuery();
 
 
-        if (result.getCountryId() < 0 || result.getLeagueId() < 0) {
-            System.out.println(String.format("Must supply countryId %s and leagueId %s", result.getCountryId(),
-                    result.getLeagueId()));
-            return;
-        }
-        final int homeTeamId = getOrInsertTeam(result.getHomeTeam(), result.getCountryId(), result.getLeagueId(),
-                result.getSportId());
-        final int awayTeamId = getOrInsertTeam(result.getAwayTeam(), result.getCountryId(), result.getLeagueId(),
-                result.getSportId());
-
-        final String selectSql = "SELECT id FROM SoccerResults WHERE homeTeamId = ? AND awayTeamId = ? AND DATE(gameDate) = DATE(?)";
-        final ResultSet rs;
-        int gameId = -1;
-        final String date = result.getGameDate().format(DateTimeFormatter.ISO_DATE);
-        try (PreparedStatement stat = conn.prepareStatement(selectSql)) {
-            stat.setInt(1, homeTeamId);
-            stat.setInt(2, awayTeamId);
-            stat.setString(3, date);
-
-            rs = stat.executeQuery();
             while (rs.next()) {
             while (rs.next()) {
-                gameId = rs.getInt("id");
+                result = rs.getString("season");
             }
             }
+        } catch (SQLException e) {
+            e.printStackTrace();
         }
         }
 
 
-        if (gameId != -1) {
-            final String sql = "UPDATE " + result.getTableName()
-                    + " SET homeScore = ?, awayScore = ?, overtime = ?, odds1 = ?, oddsX = ?, odds2 = ? "
-                    + "WHERE homeTeamId = ? AND awayTeamId = ? AND DATE(gameDate) = ?";
+        return result;
+    }
 
 
-            try (PreparedStatement stat = conn.prepareStatement(sql)) {
-                stat.setInt(1, result.getHomeScore());
-                stat.setInt(2, result.getAwayScore());
-                stat.setBoolean(3, result.isOvertime());
-                stat.setFloat(4, result.getOdds1());
-                stat.setFloat(5, result.getOddsX());
-                stat.setFloat(6, result.getOdds2());
-                stat.setInt(7, homeTeamId);
-                stat.setInt(8, awayTeamId);
-                stat.setString(9, date);
+    public String getLastSeason(String leagueName, int countryId) {
+        String sql = "SELECT season FROM SoccerResults WHERE leagueId = (SELECT id FROM League WHERE name = ? AND countryId = ?) ORDER BY gameDate DESC limit 1";
+        String result = null;
+        try (PreparedStatement stat = conn.prepareStatement(sql)) {
+            stat.setString(1, leagueName);
+            stat.setInt(2, countryId);
 
 
-                stat.executeUpdate();
+            ResultSet rs = stat.executeQuery();
+
+            while (rs.next()) {
+                result = rs.getString("season");
             }
             }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
 
 
-        } else {
-            final String sql = "INSERT INTO " + result.getTableName()
-                    + " (homeTeamId, awayTeamId, homeScore, awayScore, overtime, odds1, oddsX, odds2, countryId, gameDate, season, leagueId) "
-                    + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE homeScore = ?, awayScore = ?, odds1 = ?, oddsX = ?, odds2 = ?";
-            try (PreparedStatement stat = conn.prepareStatement(sql)) {
-                stat.setInt(1, homeTeamId);
-                stat.setInt(2, awayTeamId);
-                stat.setInt(3, result.getHomeScore());
-                stat.setInt(4, result.getAwayScore());
-                stat.setBoolean(5, result.isOvertime());
-                stat.setFloat(6, result.getOdds1());
-                stat.setFloat(7, result.getOddsX());
-                stat.setFloat(8, result.getOdds2());
-                stat.setInt(9, result.getCountryId());
-                stat.setString(10, result.getGameDate().toString());
-                stat.setString(11, result.getSeason());
-                stat.setInt(12, result.getLeagueId());
-                stat.setInt(13, result.getHomeScore());
-                stat.setInt(14, result.getAwayScore());
-                stat.setFloat(15, result.getOdds1());
-                stat.setFloat(16, result.getOddsX());
-                stat.setFloat(17, result.getOdds2());
-
-                stat.execute();
+        if (Strings.isNullOrEmpty(result)) {
+            result = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy"));
+        }
+        return result;
+    }
+
+    public int getLeagueId(int sportId, int countryId, String leagueName) {
+        final String sql = "SELECT id FROM League WHERE name = ? AND countryId = ? AND sportId = ?";
+        int id = -1;
+        try (PreparedStatement stat = conn.prepareStatement(sql)) {
+            stat.setString(1, leagueName.trim());
+            stat.setInt(2, countryId);
+            stat.setInt(3, sportId);
+
+            final ResultSet rs = stat.executeQuery();
+
+            while (rs.next()) {
+                id = rs.getInt("id");
             }
             }
+        } catch (SQLException e) {
+            e.printStackTrace();
         }
         }
+        return id;
     }
     }
 
 
-    private int getOrInsertTeam(String teamName, int countryId, int leagueId, int sportId) throws SQLException {
+    public int getOrInsertTeam(String teamName, int countryId, int leagueId, int sportId) {
         teamName = teamName.replace('\u00A0', ' ').trim();
         teamName = teamName.replace('\u00A0', ' ').trim();
         int teamId;
         int teamId;
         if (leagueId > 0) {
         if (leagueId > 0) {
@@ -281,6 +340,8 @@ public class Mysql {
                     final ResultSet generatedKeys = stat.getGeneratedKeys();
                     final ResultSet generatedKeys = stat.getGeneratedKeys();
                     generatedKeys.next();
                     generatedKeys.next();
                     teamId = generatedKeys.getInt(1);
                     teamId = generatedKeys.getInt(1);
+                } catch (SQLException e) {
+                    e.printStackTrace();
                 }
                 }
             }
             }
         } else {
         } else {
@@ -291,6 +352,22 @@ public class Mysql {
         return teamId;
         return teamId;
     }
     }
 
 
+    public int getSportId(String sportName) {
+        final String sql = "SELECT id from Sport WHERE name = ?";
+        int id = 0;
+        try (PreparedStatement stat = conn.prepareStatement(sql)) {
+            stat.setString(1, sportName.trim());
+
+            final ResultSet rs = stat.executeQuery();
+            while (rs.next()) {
+                id = rs.getInt("id");
+            }
+        } catch (final SQLException e) {
+            e.printStackTrace();
+        }
+        return id;
+    }
+
     public void setParsingForLeague(int leagueId, int sportId, int countryId, LocalDateTime gameDate,
     public void setParsingForLeague(int leagueId, int sportId, int countryId, LocalDateTime gameDate,
             int currentParsePage, String parsedYear) {
             int currentParsePage, String parsedYear) {
         final String sql = "UPDATE League SET parsedYear = ?, parsedPage = ?, lastParsedGameDate = ? WHERE sportId = ? AND countryId = ? AND id = ?";
         final String sql = "UPDATE League SET parsedYear = ?, parsedPage = ?, lastParsedGameDate = ? WHERE sportId = ? AND countryId = ? AND id = ?";
@@ -311,52 +388,43 @@ public class Mysql {
         }
         }
     }
     }
 
 
-    public String getLastParsedYear(String leagueName, int countryId) {
-        String returnValue = "";
-
-        final String sql = "SELECT parsedYear FROM League WHERE name = ? AND countryId = ?";
-        try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setString(1, leagueName);
-            stat.setInt(2, countryId);
-
-            final ResultSet rs = stat.executeQuery();
-
-            while (rs.next()) {
-                returnValue = rs.getString("parsedYear");
-            }
-        } catch (final SQLException e) {
-            e.printStackTrace();
-        }
-
-        return returnValue;
-    }
-
-    public Connection getDbConnection() {
+    protected Connection getConnection() {
         if (conn == null) {
         if (conn == null) {
-            conn = getConnection();
+            try {
+                conn = DriverManager.getConnection(URL + DATABASE + TIMEZONE_FIX, USERNAME, PASSWORD);
+            } catch (final SQLException e) {
+                throw new RuntimeException(e.getMessage(), e);
+            }
         }
         }
         return conn;
         return conn;
     }
     }
 
 
-    public String getLastSeason(String leagueName, int countryId) {
-        String sql = "SELECT season FROM SoccerResults WHERE leagueId = (SELECT id FROM League WHERE name = ? AND countryId = ?) ORDER BY gameDate DESC limit 1";
-        String result = null;
+    private int getId(String table, String name, int countryId, int leagueId) {
+        String sql = "SELECT id FROM " + table + " WHERE name = ?";
+        int id = -1;
+        if (countryId > -1) {
+            sql += " AND countryId = ?";
+        }
+        if (leagueId > -1) {
+            sql += " AND leagueId = ?";
+        }
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setString(1, leagueName);
-            stat.setInt(2, countryId);
-
-            ResultSet rs = stat.executeQuery();
-
-            while (rs.next()) {
-                result = rs.getString("season");
+            stat.setString(1, name.trim());
+            if (countryId > -1 && leagueId > -1) {
+                stat.setInt(2, countryId);
+                stat.setInt(3, leagueId);
+            } else if (countryId > -1) {
+                stat.setInt(2, countryId);
+            } else if (leagueId > -1) {
+                stat.setInt(2, leagueId);
+            }
+            final ResultSet insertRs = stat.executeQuery();
+            if (insertRs.next()) {
+                id = insertRs.getInt("id");
             }
             }
         } catch (SQLException e) {
         } catch (SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-
-        if (Strings.isNullOrEmpty(result)) {
-            result = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy"));
-        }
-        return result;
+        return id;
     }
     }
 }
 }

+ 72 - 17
Odds/src/object/ArbResults.java

@@ -11,6 +11,12 @@ public class ArbResults extends ResultDTO {
     List<Odds> oddsXList = new ArrayList<>();
     List<Odds> oddsXList = new ArrayList<>();
     List<Odds> odds2List = new ArrayList<>();
     List<Odds> odds2List = new ArrayList<>();
 
 
+    List<Odds> over25List = new ArrayList<>();
+    List<Odds> under25List = new ArrayList<>();
+
+    Odds over25;
+    Odds under25;
+
     String bookie;
     String bookie;
 
 
     public ArbResults(String homeTeamName, String awayTeamName, float odds1, float oddsX, float odds2, String bookie) {
     public ArbResults(String homeTeamName, String awayTeamName, float odds1, float oddsX, float odds2, String bookie) {
@@ -23,7 +29,22 @@ public class ArbResults extends ResultDTO {
     }
     }
 
 
     public ArbResults(ResultDTO m, String bookie) {
     public ArbResults(ResultDTO m, String bookie) {
-        this(m.homeTeam, m.awayTeam, m.odds1, m.oddsX, m.odds2, bookie);
+        this(m.homeTeam, m.awayTeam, m.odds1, m.oddsX, m.odds2, m.getOddsOver25goals(), m.getOddsUnder25goals(),
+                bookie);
+    }
+
+    public ArbResults(String homeTeamName, String awayTeamName, float odds1, float oddsX, float odds2,
+            float over25, float under25, String bookie) {
+        this(homeTeamName, awayTeamName, odds1, oddsX, odds2, bookie);
+        this.over25 = new Odds(bookie, over25);
+        this.under25 = new Odds(bookie, under25);
+
+        over25List.add(this.over25);
+        under25List.add(this.under25);
+
+        this.oddsOver25goals = over25;
+        this.oddsUnder25goals = under25;
+
     }
     }
 
 
     public void addOdds1(String bookie, float value) {
     public void addOdds1(String bookie, float value) {
@@ -42,21 +63,27 @@ public class ArbResults extends ResultDTO {
         Float val = Collections.max(odds1List.stream().map(m -> m.odds).toList());
         Float val = Collections.max(odds1List.stream().map(m -> m.odds).toList());
         Optional<Odds> o = odds1List.stream().filter(p -> p.odds == val).findFirst();
         Optional<Odds> o = odds1List.stream().filter(p -> p.odds == val).findFirst();
 
 
-        return o.isPresent()?o.get():null;
+        return o.isPresent() ? o.get() : null;
     }
     }
 
 
     public Odds getMaxOddsX() {
     public Odds getMaxOddsX() {
         Float val = Collections.max(oddsXList.stream().map(m -> m.odds).toList());
         Float val = Collections.max(oddsXList.stream().map(m -> m.odds).toList());
         Optional<Odds> o = oddsXList.stream().filter(p -> p.odds == val).findFirst();
         Optional<Odds> o = oddsXList.stream().filter(p -> p.odds == val).findFirst();
 
 
-        return o.isPresent()?o.get():null;
+        return o.isPresent() ? o.get() : null;
     }
     }
 
 
     public Odds getMaxOdds2() {
     public Odds getMaxOdds2() {
         Float val = Collections.max(odds2List.stream().map(m -> m.odds).toList());
         Float val = Collections.max(odds2List.stream().map(m -> m.odds).toList());
         Optional<Odds> o = odds2List.stream().filter(p -> p.odds == val).findFirst();
         Optional<Odds> o = odds2List.stream().filter(p -> p.odds == val).findFirst();
 
 
-        return o.isPresent()?o.get():null;
+        return o.isPresent() ? o.get() : null;
+    }
+
+    public boolean multipleOddsExist() {
+        return ((odds1List.size() > 1 || oddsXList.size() > 1 || odds2List.size() > 1)
+                && (!getMaxOdds1().bookie.equals(getMaxOdds2().bookie)
+                        || !getMaxOdds1().bookie.equals(getMaxOddsX().bookie)));
     }
     }
 
 
     public String toStringWithExtra() {
     public String toStringWithExtra() {
@@ -65,22 +92,50 @@ public class ArbResults extends ResultDTO {
         return string;
         return string;
     }
     }
 
 
-    public class Odds {
-        String bookie;
-        float odds;
+    public float getOver25() {
+        return this.oddsOver25goals;
+    }
+
+    public float getUnder25() {
+        return this.oddsUnder25goals;
+    }
+
+    public void setOver25(Odds over25) {
+        this.over25 = over25;
+    }
 
 
-        public Odds(String bookie, float odds) {
-            this.bookie = bookie;
-            this.odds = odds;
-        }
+    public void setUnder25(Odds under25) {
+        this.under25 = under25;
+    }
 
 
-        public float getOdds() {return odds;}
+    public void addOver25Odds(String bookie, float odds) {
+        this.over25List.add(new Odds(bookie, odds));
+    }
 
 
-        public String getBookie() {return bookie;}
+    public void addUnder25Odds(String bookie, float odds) {
+        this.under25List.add(new Odds(bookie, odds));
+    }
 
 
-        @Override
-        public String toString() {
-            return "(" + bookie + ") " + odds;
-        }
+    public Odds getMaxOver25() {
+        Float val = Collections.max(over25List.stream().map(m -> m.odds).toList());
+        Optional<Odds> o = over25List.stream().filter(p -> p.odds == val).findFirst();
+
+        return o.isPresent() ? o.get() : null;
     }
     }
+
+    public Odds getMaxUnder25() {
+        Float val = Collections.max(under25List.stream().map(m -> m.odds).toList());
+        Optional<Odds> o = under25List.stream().filter(p -> p.odds == val).findFirst();
+
+        return o.isPresent() ? o.get() : null;
+    }
+
+    public float getArbValueOverUnder() {
+
+        Odds maxOver25 = getMaxOver25();
+        Odds maxUnder25 = getMaxUnder25();
+
+        return (1 / maxOver25.odds) + (1 / maxUnder25.odds);
+    }
+
 }
 }

+ 24 - 0
Odds/src/object/Odds.java

@@ -0,0 +1,24 @@
+package object;
+
+public class Odds {
+    String bookie;
+    float odds;
+
+    public Odds(String bookie, float odds) {
+        this.bookie = bookie;
+        this.odds = odds;
+    }
+
+    public float getOdds() {
+        return odds;
+    }
+
+    public String getBookie() {
+        return bookie;
+    }
+
+    @Override
+    public String toString() {
+        return "(" + bookie + ") " + odds;
+    }
+}

+ 119 - 50
Odds/src/object/ResultDTO.java

@@ -14,13 +14,42 @@ public class ResultDTO {
     float odds1;
     float odds1;
     float oddsX;
     float oddsX;
     float odds2;
     float odds2;
+    float oddsOver25goals;
+    float oddsUnder25goals;
     int countryId;
     int countryId;
     String season;
     String season;
     int leagueId;
     int leagueId;
     int sportId;
     int sportId;
+    private int homeTeamId;
+    private int awayTeamId;
 
 
     public ResultDTO() {
     public ResultDTO() {
-    };
+    }
+
+    public ResultDTO(String tableName) {
+        super();
+        this.tableName = tableName;
+    }
+
+    public ResultDTO(String tableName, LocalDateTime gameDate, int homeTeamId, int awayTeamId, int homeScore,
+            int awayScore, boolean overtime, float odds1, float oddsX, float odds2, int countryId, String season,
+            int leagueId, int sportId) {
+        super();
+        this.tableName = tableName;
+        this.gameDate = gameDate;
+        this.homeTeamId = homeTeamId;
+        this.awayTeamId = awayTeamId;
+        this.homeScore = homeScore;
+        this.awayScore = awayScore;
+        this.overtime = overtime;
+        this.odds1 = odds1;
+        this.oddsX = oddsX;
+        this.odds2 = odds2;
+        this.countryId = countryId;
+        this.season = season;
+        this.leagueId = leagueId;
+        this.sportId = sportId;
+    }
 
 
     public ResultDTO(String tableName, LocalDateTime gameDate, String homeTeam, String awayTeam, int homeScore,
     public ResultDTO(String tableName, LocalDateTime gameDate, String homeTeam, String awayTeam, int homeScore,
             int awayScore, boolean overtime, float odds1, float oddsX, float odds2, int countryId, String season,
             int awayScore, boolean overtime, float odds1, float oddsX, float odds2, int countryId, String season,
@@ -50,120 +79,160 @@ public class ResultDTO {
         this.odds2 = odds2;
         this.odds2 = odds2;
     }
     }
 
 
-    public String getTableName() {
-        return tableName;
+    public ResultDTO(String homeTeamName, String awayTeamName, float odds1, float oddsX, float odds2,
+            float oddsOver25, float oddsUnder25) {
+        this(homeTeamName, awayTeamName, odds1, oddsX, odds2);
+        this.oddsOver25goals = oddsOver25;
+        this.oddsUnder25goals = oddsUnder25;
     }
     }
 
 
-    public void setTableName(String tableName) {
-        this.tableName = tableName;
+    public int getAwayScore() {
+        return awayScore;
+    }
+
+    public String getAwayTeam() {
+        return awayTeam;
+    }
+
+    public int getAwayTeamId() {
+        return awayTeamId;
+    }
+
+    public int getCountryId() {
+        return countryId;
     }
     }
 
 
     public LocalDateTime getGameDate() {
     public LocalDateTime getGameDate() {
         return gameDate;
         return gameDate;
     }
     }
 
 
-    public void setGameDate(LocalDateTime gameDate) {
-        this.gameDate = gameDate;
+    public int getHomeScore() {
+        return homeScore;
     }
     }
 
 
     public String getHomeTeam() {
     public String getHomeTeam() {
         return homeTeam;
         return homeTeam;
     }
     }
 
 
-    public void setHomeTeam(String homeTeam) {
-        this.homeTeam = homeTeam;
+    public int getHomeTeamId() {
+        return homeTeamId;
     }
     }
 
 
-    public String getAwayTeam() {
-        return awayTeam;
+    public int getLeagueId() {
+        return leagueId;
     }
     }
 
 
-    public void setAwayTeam(String awayTeam) {
-        this.awayTeam = awayTeam;
+    public float getOdds1() {
+        return odds1;
     }
     }
 
 
-    public int getHomeScore() {
-        return homeScore;
+    public float getOdds2() {
+        return odds2;
     }
     }
 
 
-    public void setHomeScore(int homeScore) {
-        this.homeScore = homeScore;
+    public float getOddsOver25goals() {
+        return oddsOver25goals;
     }
     }
 
 
-    public int getAwayScore() {
-        return awayScore;
+    public float getOddsUnder25goals() {
+        return oddsUnder25goals;
     }
     }
 
 
-    public void setAwayScore(int awayScore) {
-        this.awayScore = awayScore;
+    public float getOddsX() {
+        return oddsX;
+    }
+
+    public String getSeason() {
+        return season;
+    }
+
+    public int getSportId() {
+        return sportId;
+    }
+
+    public String getTableName() {
+        return tableName;
     }
     }
 
 
     public boolean isOvertime() {
     public boolean isOvertime() {
         return overtime;
         return overtime;
     }
     }
 
 
-    public void setOvertime(boolean overtime) {
-        this.overtime = overtime;
+    public void setAwayScore(int awayScore) {
+        this.awayScore = awayScore;
     }
     }
 
 
-    public float getOdds1() {
-        return odds1;
+    public void setAwayTeam(String awayTeam) {
+        this.awayTeam = awayTeam;
     }
     }
 
 
-    public void setOdds1(float odds1) {
-        this.odds1 = odds1;
+    public void setAwayTeamId(int awayTeamId) {
+        this.awayTeamId = awayTeamId;
     }
     }
 
 
-    public float getOddsX() {
-        return oddsX;
+    public void setCountryId(int countryId) {
+        this.countryId = countryId;
     }
     }
 
 
-    public void setOddsX(float oddsX) {
-        this.oddsX = oddsX;
+    public void setGameDate(LocalDateTime gameDate) {
+        this.gameDate = gameDate;
     }
     }
 
 
-    public float getOdds2() {
-        return odds2;
+    public void setHomeScore(int homeScore) {
+        this.homeScore = homeScore;
     }
     }
 
 
-    public void setOdds2(float odds2) {
-        this.odds2 = odds2;
+    public void setHomeTeam(String homeTeam) {
+        this.homeTeam = homeTeam;
     }
     }
 
 
-    public int getCountryId() {
-        return countryId;
+    public void setHomeTeamId(int homeTeamId) {
+        this.homeTeamId = homeTeamId;
     }
     }
 
 
-    public void setCountryId(int countryId) {
-        this.countryId = countryId;
+    public void setLeagueId(int leagueId) {
+        this.leagueId = leagueId;
     }
     }
 
 
-    public String getSeason() {
-        return season;
+    public void setOdds1(float odds1) {
+        this.odds1 = odds1;
     }
     }
 
 
-    public void setSeason(String season) {
-        this.season = season;
+    public void setOdds2(float odds2) {
+        this.odds2 = odds2;
     }
     }
 
 
-    public int getLeagueId() {
-        return leagueId;
+    public void setOddsOver25goals(float oddsOver25goals) {
+        this.oddsOver25goals = oddsOver25goals;
     }
     }
 
 
-    public void setLeagueId(int leagueId) {
-        this.leagueId = leagueId;
+    public void setOddsUnder25goals(float oddsUnder25goals) {
+        this.oddsUnder25goals = oddsUnder25goals;
     }
     }
 
 
-    public int getSportId() {
-        return sportId;
+    public void setOddsX(float oddsX) {
+        this.oddsX = oddsX;
+    }
+
+    public void setOvertime(boolean overtime) {
+        this.overtime = overtime;
+    }
+
+    public void setSeason(String season) {
+        this.season = season;
     }
     }
 
 
     public void setSportId(int sportId) {
     public void setSportId(int sportId) {
         this.sportId = sportId;
         this.sportId = sportId;
     }
     }
 
 
+    public void setTableName(String tableName) {
+        this.tableName = tableName;
+    }
+
     @Override
     @Override
     public String toString() {
     public String toString() {
-        return homeTeam + "," + awayTeam + "," + odds1 + "," + oddsX + "," + odds2;
+        return homeTeam + "," + awayTeam + "," + odds1 + "," + oddsX + "," + odds2 + "," + oddsOver25goals + ","
+                + oddsUnder25goals;
     }
     }
 }
 }

+ 101 - 0
Odds/src/parser/BWinParser.java

@@ -0,0 +1,101 @@
+package parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.chrome.ChromeDriver;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.openqa.selenium.support.ui.WebDriverWait;
+
+import object.ArbResults;
+import object.Odds;
+import object.ResultDTO;
+
+public class BWinParser extends ParserBase {
+
+    public static final String BOOKIE = "BWin";
+    String url = "https://sports.bwin.se/sv/sports/fotboll-4/idag";
+    String url2 = "https://sports.bwin.se/sv/sports/fotboll-4/imorgon";
+
+    public List<ResultDTO> parseSoccerMatches() {
+        List<ResultDTO> result = new ArrayList<>();
+
+        ChromeDriver driver = getSeleniumDriver();
+        WebDriverWait wait = getWaitDriver(driver);
+
+        parsePage(result, driver, wait, url);
+        parsePage(result, driver, wait, url2);
+
+        driver.close();
+        return result;
+    }
+
+    private void parsePage(List<ResultDTO> result, ChromeDriver driver, WebDriverWait wait, String url) {
+        driver.get(url);
+        wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath("//div[@class='calendar-event-info']"), 0));
+
+        List<WebElement> matchDivs = driver.findElements(By.xpath("//div[@class='calendar-event-info']"));
+
+        for (WebElement matchDiv : matchDivs) {
+            List<WebElement> participants = matchDiv.findElements(By.xpath(".//div[@class='participant']"));
+            if (participants.size() != 2) {
+                System.out.println("Not correct number of participants " + participants.size()
+                        + (participants.size() > 0 ? " first is " + participants.get(0).getText() : ""));
+                continue;
+            }
+            String homeTeam = participants.get(0).getText();
+            String awayTeam = participants.get(1).getText();
+
+            List<Odds> matchOdds = getMatchOdds(matchDiv);
+            List<Odds> overUnderOdds = getOverUnderOdds(matchDiv);
+
+            if (matchOdds.size() == 3 && overUnderOdds.size() == 2) {
+                result.add(new ArbResults(homeTeam, awayTeam, matchOdds.get(0).getOdds(), matchOdds.get(1).getOdds(),
+                        matchOdds.get(2).getOdds(),
+                        overUnderOdds.get(0).getOdds(), overUnderOdds.get(1).getOdds(), BOOKIE));
+                System.out.println("Added " + result.get(result.size() - 1) + " with 2.5 over under");
+            } else if (matchOdds.size() == 3 && overUnderOdds.size() != 2) {
+                result.add(new ArbResults(homeTeam, awayTeam, matchOdds.get(0).getOdds(), matchOdds.get(1).getOdds(),
+                        matchOdds.get(2).getOdds(), BOOKIE));
+                System.out.println("Added " + result.get(result.size() - 1) + " WITHOUT 2.5 over under");
+            } else {
+                System.out.println("Results not added for matchDiv " + matchDiv.toString());
+            }
+        }
+    }
+
+    private List<Odds> getMatchOdds(WebElement matchDiv) {
+        List<Odds> result = new ArrayList<>();
+        if (checkIfElementExists(matchDiv, ".//ms-option-group[1]")) {
+            WebElement oddsContainer = matchDiv.findElement(By.xpath(".//ms-option-group[1]"));
+
+            List<WebElement> odds = oddsContainer.findElements(By.xpath(".//ms-font-resizer"));
+
+            if (odds.size() == 3) {
+                result.add(new Odds(BOOKIE, formatFloat(odds.get(0).getText())));
+                result.add(new Odds(BOOKIE, formatFloat(odds.get(1).getText())));
+                result.add(new Odds(BOOKIE, formatFloat(odds.get(2).getText())));
+            }
+        }
+        return result;
+    }
+
+    private List<Odds> getOverUnderOdds(WebElement matchDiv) {
+        List<Odds> result = new ArrayList<>();
+        if (checkIfElementExists(matchDiv, ".//ms-option-group[2]")) {
+            WebElement oddsContainer = matchDiv.findElement(By.xpath(".//ms-option-group[2]"));
+
+            List<WebElement> odds = oddsContainer.findElements(By.xpath(".//ms-font-resizer"));
+
+            if (odds.size() == 3) {
+                if (formatFloat(odds.get(0).getText().replace(",", ".")) == 2.5f) {
+                    result.add(new Odds(BOOKIE, formatFloat(odds.get(1).getText())));
+                    result.add(new Odds(BOOKIE, formatFloat(odds.get(2).getText())));
+                }
+            }
+        }
+        return result;
+    }
+}

+ 136 - 0
Odds/src/parser/BetHard.java

@@ -0,0 +1,136 @@
+package parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.chrome.ChromeDriver;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.openqa.selenium.support.ui.WebDriverWait;
+
+import object.ResultDTO;
+
+public class BetHard extends ParserBase {
+
+    private boolean tomorrowParsed;
+
+    public BetHard() {
+    }
+
+    public List<ResultDTO> seleniumParseMatches() {
+        List<ResultDTO> result = new ArrayList<>();
+
+        String url = "https://se-sports.bethard.com/sports/?langid=722&stoken=logout";
+        ChromeDriver driver = getSeleniumDriver();
+
+        WebDriverWait wait = getWaitDriver(driver);
+
+        driver.get(url);
+
+        wait.until(
+                ExpectedConditions.numberOfElementsToBeMoreThan(
+                        By.xpath("//div[contains(@class,'sports-list-item-text')]"),
+                        0));
+
+        WebElement fotballSideMenu = driver
+                .findElement(By.xpath("//div[@data-uat='sports-list-item-text-name' and text()='Fotboll']/.."));
+
+        wait.until(ExpectedConditions.elementToBeClickable(
+                By.xpath("//div[@data-uat='sports-list-item-text-name' and text()='Fotboll']/..")));
+
+        fotballSideMenu.click();
+
+        wait.until(ExpectedConditions.elementToBeClickable(
+                By.xpath("//span[@data-uat='tab-switch-btn-text' and text()='Daglig matchlista']/../..")));
+        WebElement dagligLista = driver
+                .findElement(By.xpath("//span[@data-uat='tab-switch-btn-text' and text()='Daglig matchlista']/../.."));
+
+        dagligLista.click();
+
+        wait.until(
+                ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath("//div[@class='rj-instant-collapsible']"), 0));
+
+        parseMatches(driver, wait, result);
+
+        driver.close();
+        return result;
+    }
+
+    private void parseMatches(ChromeDriver driver, WebDriverWait wait, List<ResultDTO> result) {
+        List<WebElement> expandableDivs = driver
+                .findElements(By.xpath("//div[@class='rj-instant-collapsible']"));
+
+        List<WebElement> handledDiv = new ArrayList<>();
+        while (true) {
+            WebElement webElement = expandableDivs.get(0);
+            scrollElementIntoViewCenter(driver, webElement);
+            if (webElement.getAttribute("data-collapsed").equals(Boolean.TRUE.toString())) {
+                int matchDivsBefore = driver.findElements(By.xpath("//div[@class='rj-ev-list__ev-card__inner']"))
+                        .size();
+                webElement.click();
+                wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(
+                        By.xpath("//div[@class='rj-ev-list__ev-card__inner']"), matchDivsBefore - 1));
+            }
+            List<WebElement> matchDiv = webElement
+                    .findElements(By.xpath(".//div[@class='rj-ev-list__ev-card__inner']"));
+            for (WebElement match : matchDiv) {
+                parseMatch(match, result);
+            }
+
+            handledDiv.add(webElement);
+            expandableDivs.remove(webElement);
+            expandableDivs = driver
+                    .findElements(By.xpath("//div[@class='rj-instant-collapsible']"));
+
+            expandableDivs.removeAll(handledDiv);
+
+            if (expandableDivs.size() <= 0) {
+                break;
+            }
+        }
+        if (!tomorrowParsed) {
+            tomorrowParsed = true;
+            try {
+                scrollToTopOfPage(driver);
+                Thread.sleep(200);
+                WebElement tomorrowHeader = driver.findElement(By.xpath("//div[text()='Imorgon']//../.."));
+
+                tomorrowHeader.click();
+                wait.until(
+                        ExpectedConditions.numberOfElementsToBeMoreThan(
+                                By.xpath("//div[@class='rj-instant-collapsible']"),
+                                0));
+                Thread.sleep(200);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+            parseMatches(driver, wait, result);
+        }
+    }
+
+    private void parseMatch(WebElement match, List<ResultDTO> result) {
+        WebElement participants = match.findElement(By.xpath(".//a/div[contains(@class,'name')]"));
+
+        WebElement homeTeamSpan = participants.findElement(By.xpath(".//div[1]/span"));
+        WebElement awayTeamSpan = participants.findElement(By.xpath(".//div[2]/span"));
+
+        String homeTeamName = homeTeamSpan.getText();
+        String awayTeamName = awayTeamSpan.getText();
+
+        if (!checkIfElementExists(match, ".//button[1]//div[2]/span") || // no odds for this game
+                !checkIfElementExists(match, ".//button[2]//div[2]/span") ||
+                !checkIfElementExists(match, ".//button[3]//div[2]/span")) {
+            return;
+        }
+        WebElement odds1Span = match.findElement(By.xpath(".//button[1]//div[2]/span"));
+        WebElement oddsXSpan = match.findElement(By.xpath(".//button[2]//div[2]/span"));
+        WebElement odds2Span = match.findElement(By.xpath(".//button[3]//div[2]/span"));
+
+        float odds1 = formatFloat(odds1Span.getText());
+        float oddsX = formatFloat(oddsXSpan.getText());
+        float odds2 = formatFloat(odds2Span.getText());
+
+        result.add(new ResultDTO(homeTeamName, awayTeamName, odds1, oddsX, odds2));
+    }
+}

+ 59 - 24
Odds/src/parser/BetSafeParser.java

@@ -21,7 +21,8 @@ public class BetSafeParser extends ParserBase {
 
 
     List<ResultDTO> result = new ArrayList<>();
     List<ResultDTO> result = new ArrayList<>();
 
 
-    public BetSafeParser() {}
+    public BetSafeParser() {
+    }
 
 
     public List<ResultDTO> seleniumPaseSoccerMatches() {
     public List<ResultDTO> seleniumPaseSoccerMatches() {
         String url = "https://www.betsafe.com/sv/odds/fotboll";
         String url = "https://www.betsafe.com/sv/odds/fotboll";
@@ -46,6 +47,8 @@ public class BetSafeParser extends ParserBase {
         // Behöver också kolla om det finns mer att ladda obg-show-more-less-button
         // Behöver också kolla om det finns mer att ladda obg-show-more-less-button
         // ng-star-inserted
         // ng-star-inserted
         // Kontrollera att det inte står "Show less" då den minimerar igen
         // Kontrollera att det inte står "Show less" då den minimerar igen
+
+        List<WebElement> handledDivs = new ArrayList<>();
         for (WebElement element : expandableDivs) {
         for (WebElement element : expandableDivs) {
             try {
             try {
                 String xpath = ".//span[text()='Live']";
                 String xpath = ".//span[text()='Live']";
@@ -60,6 +63,7 @@ public class BetSafeParser extends ParserBase {
 
 
                 xpath = ".//span[text()='Kommande idag']";
                 xpath = ".//span[text()='Kommande idag']";
                 if (checkIfElementExists(element, xpath)) {
                 if (checkIfElementExists(element, xpath)) {
+                    scrollElementIntoViewCenter(driver, element);
                     element.click();
                     element.click();
                     wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath(
                     wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath(
                             "//div[contains(@class,'obg-event-row-event-container')]"), matchDivs.size()));
                             "//div[contains(@class,'obg-event-row-event-container')]"), matchDivs.size()));
@@ -71,7 +75,9 @@ public class BetSafeParser extends ParserBase {
                 }
                 }
 
 
                 xpath = ".//span[text()='Imorgon']";
                 xpath = ".//span[text()='Imorgon']";
+                Thread.sleep(200);
                 if (checkIfElementExists(element, xpath)) {
                 if (checkIfElementExists(element, xpath)) {
+                    scrollElementIntoViewCenter(driver, element);
                     element.click();
                     element.click();
                     wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath(
                     wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath(
                             "//div[contains(@class,'obg-event-row-event-container')]"), matchDivs.size()));
                             "//div[contains(@class,'obg-event-row-event-container')]"), matchDivs.size()));
@@ -81,9 +87,16 @@ public class BetSafeParser extends ParserBase {
                     scrollElementIntoView(driver, element);
                     scrollElementIntoView(driver, element);
                 }
                 }
 
 
-            } catch (ElementNotFoundException e) {
+            } catch (ElementNotFoundException | InterruptedException e) {
                 // Empty by design, no more matches today
                 // Empty by design, no more matches today
             }
             }
+
+            List<WebElement> newDivs = matchDivs.stream().filter(p -> !handledDivs.contains(p)).toList();
+
+            for (WebElement match : newDivs) {
+                parseMatch(driver, match);
+                handledDivs.add(match);
+            }
         }
         }
 
 
         expandAllMatches(driver, wait, matchDivs);
         expandAllMatches(driver, wait, matchDivs);
@@ -92,10 +105,13 @@ public class BetSafeParser extends ParserBase {
                 .findElements(By.xpath("//div[contains(@class,'obg-event-row-event-container')]"));
                 .findElements(By.xpath("//div[contains(@class,'obg-event-row-event-container')]"));
 
 
         js.executeScript("window.stop;");
         js.executeScript("window.stop;");
-        for (WebElement match : matchDivs) {
+        List<WebElement> newDivs = matchDivs.stream().filter(p -> !handledDivs.contains(p)).toList();
+
+        for (WebElement match : newDivs) {
+            scrollElementIntoViewCenter(driver, match);
             parseMatch(driver, match);
             parseMatch(driver, match);
         }
         }
-        System.out.println("found " + matchDivs.size() + " matches");
+        System.out.println("found " + matchDivs.size() + " matches handled " + handledDivs.size());
 
 
         driver.close();
         driver.close();
         return result;
         return result;
@@ -103,20 +119,25 @@ public class BetSafeParser extends ParserBase {
 
 
     private void expandAllMatches(ChromeDriver driver, WebDriverWait wait, List<WebElement> matchDivs) {
     private void expandAllMatches(ChromeDriver driver, WebDriverWait wait, List<WebElement> matchDivs) {
         List<WebElement> buttons = driver
         List<WebElement> buttons = driver
-        .findElements(By.xpath("//button[contains(@class,'obg-show-more-less-button')]"));
-        scrollElementIntoViewCenter(driver, buttons.get(0));
+                .findElements(By.xpath("//button[contains(@class,'obg-show-more-less-button')]"));
 
 
         for (WebElement button : buttons) {
         for (WebElement button : buttons) {
             WebElement findElement = button.findElement(By.xpath(".//span"));
             WebElement findElement = button.findElement(By.xpath(".//span"));
             while (!findElement.getText().contains("färre")) {
             while (!findElement.getText().contains("färre")) {
-                scrollElementIntoViewCenter(driver, buttons.get(0));
+                scrollElementIntoView(driver, findElement);
+                try {
+                    Thread.sleep(200);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+                scrollElementIntoViewCenter(driver, findElement);
                 button.click();
                 button.click();
                 findElement = button.findElement(By.xpath(".//span"));
                 findElement = button.findElement(By.xpath(".//span"));
+                scrollElementIntoViewCenter(driver, findElement);
             }
             }
-
         }
         }
 
 
-        if (buttons.size() > 0) {
+        if (!buttons.isEmpty()) {
             wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath(
             wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath(
                     "//div[contains(@class,'obg-event-row-event-container')]"), matchDivs.size()));
                     "//div[contains(@class,'obg-event-row-event-container')]"), matchDivs.size()));
         }
         }
@@ -152,23 +173,37 @@ public class BetSafeParser extends ParserBase {
                 }
                 }
 
 
             }
             }
-            result.add(new ResultDTO(homeTeamName, awayTeamName, odds1, oddsX, odds2));
+
+            float oddsOver25 = -1f;
+            float oddsUnder25 = -1f;
+
+            Optional<WebElement> numberOfGoalsContainer = oddsContainers.stream()
+                    .filter(p -> checkIfElementExists(p, ".//header/div/span")
+                            ? p.findElement(By.xpath(".//header/div/span"))
+                                    .getText().toLowerCase().trim().contains("antal mål")
+                            : Boolean.FALSE)
+                    .findFirst();
+
+            if (numberOfGoalsContainer.isPresent()) {
+                List<WebElement> overUnderElements = numberOfGoalsContainer.get()
+                        .findElements(By.xpath(".//section//span[contains(@class, 'obg-selection-content-label')]"));
+
+                for (WebElement element : overUnderElements) {
+                    WebElement oddsElement = element.findElement(By.xpath(".//..//..//span[@test-id='odds']"));
+                    if (element.getText().trim().equals("över 2.5")) {
+                        oddsOver25 = formatFloat(oddsElement.getText());
+                    } else if (element.getText().trim().equals("under 2.5")) {
+                        oddsUnder25 = formatFloat(oddsElement.getText());
+                    }
+                }
+            }
+
+            result.add(new ResultDTO(homeTeamName, awayTeamName, odds1, oddsX, odds2, oddsOver25, oddsUnder25));
             System.out.println(homeTeamName + "-" + awayTeamName + " odds (" + odds1 + "," + oddsX + "," + odds2 + ")");
             System.out.println(homeTeamName + "-" + awayTeamName + " odds (" + odds1 + "," + oddsX + "," + odds2 + ")");
         } catch (StaleElementReferenceException e) {
         } catch (StaleElementReferenceException e) {
-            System.out.println("Stale element, refreshing");
-            driver.navigate().refresh();
-            parseMatch(driver, match);
+//            System.out.println("Stale element, refreshing");
+//            driver.navigate().refresh();
+//            parseMatch(driver, match);
         }
         }
     }
     }
-
-    private float formatFloat(String string) {
-        float result = -1f;
-        try {
-            result = Float.parseFloat(string);
-        } catch (NumberFormatException e) {
-            // Empty by design
-        }
-
-        return result;
-    }
 }
 }

+ 45 - 3
Odds/src/parser/ExpektParser.java

@@ -71,8 +71,8 @@ public class ExpektParser extends ParserBase {
         scrollElementIntoViewCenter(driver, expandableDivs.get(0));
         scrollElementIntoViewCenter(driver, expandableDivs.get(0));
         for (WebElement element : expandableDivs) {
         for (WebElement element : expandableDivs) {
             if (!checkIfElementExists(element, ".//following-sibling::ul")) {
             if (!checkIfElementExists(element, ".//following-sibling::ul")) {
+                scrollElementIntoViewCenter(driver, element);
                 element.click();
                 element.click();
-                scrollElementIntoView(driver, element);
             }
             }
         }
         }
 
 
@@ -121,7 +121,50 @@ public class ExpektParser extends ParserBase {
                 od++;
                 od++;
             }
             }
 
 
-            result.add(new ResultDTO(homeTeamName, awayTeamName, odds1, oddsX, odds2));
+            float oddsOver25 = -1f;
+            float oddsUnder25 = -1f;
+
+            if (checkIfElementExists(element,
+                    ".//div[@class='KambiBC-list-view__column KambiBC-bet-offers-list__column KambiBC-bet-offers-list__column--num-2']")) {
+                WebElement overUnderContainer = element.findElement(By.xpath(
+                        ".//div[@class='KambiBC-list-view__column KambiBC-bet-offers-list__column KambiBC-bet-offers-list__column--num-2']"));
+
+                if (checkIfElementExists(overUnderContainer, ".//div//div//button[1]//div//div[1]//div[1]")) {
+
+                    WebElement overUnderText1 = overUnderContainer
+                            .findElement(By.xpath(".//div//div//button[1]//div//div[1]//div[1]")); // Över Under text
+                    WebElement overUnderText2 = overUnderContainer
+                            .findElement(By.xpath(".//div//div//button[2]//div//div[1]//div[1]")); // Över Under text
+
+                    WebElement overUnderSiffra1 = overUnderContainer
+                            .findElement(By.xpath(".//div//div//button[1]//div//div[1]//div[2]"));
+                    WebElement overUnderSiffra2 = overUnderContainer
+                            .findElement(By.xpath(".//div//div//button[2]//div//div[1]//div[2]"));
+
+                    WebElement overUnderOdds1 = overUnderContainer
+                            .findElement(By.xpath(".//div//div//button[1]//div//div[2]//div[2]"));
+                    WebElement overUnderOdds2 = overUnderContainer
+                            .findElement(By.xpath(".//div//div//button[2]//div//div[2]//div[2]"));
+
+                    if (overUnderText1.getText().toLowerCase().equals("över")
+                            && formatFloat(overUnderSiffra1.getText()) == 2.5) {
+                        oddsOver25 = formatFloat(overUnderOdds1.getText());
+                    } else if (overUnderText1.getText().toLowerCase().equals("under")
+                            && formatFloat(overUnderSiffra1.getText()) == 2.5) {
+                        oddsUnder25 = formatFloat(overUnderOdds1.getText());
+                    }
+
+                    if (overUnderText2.getText().toLowerCase().equals("över")
+                            && formatFloat(overUnderSiffra2.getText()) == 2.5) {
+                        oddsOver25 = formatFloat(overUnderOdds2.getText());
+                    } else if (overUnderText2.getText().toLowerCase().equals("under")
+                            && formatFloat(overUnderSiffra2.getText()) == 2.5) {
+                        oddsUnder25 = formatFloat(overUnderOdds2.getText());
+                    }
+                }
+            }
+
+            result.add(new ResultDTO(homeTeamName, awayTeamName, odds1, oddsX, odds2, oddsOver25, oddsUnder25));
             System.out.println(homeTeamName + "-" + awayTeamName + " (" + odds1 + "," + oddsX + "," + odds2 + ")");
             System.out.println(homeTeamName + "-" + awayTeamName + " (" + odds1 + "," + oddsX + "," + odds2 + ")");
         }
         }
 
 
@@ -185,7 +228,6 @@ public class ExpektParser extends ParserBase {
 
 
             // System.out.println(webResponse.getContentAsString());
             // System.out.println(webResponse.getContentAsString());
         } catch (FailingHttpStatusCodeException | IOException e) {
         } catch (FailingHttpStatusCodeException | IOException e) {
-            // TODO Auto-generated catch block
             e.printStackTrace();
             e.printStackTrace();
         }
         }
     }
     }

+ 46 - 21
Odds/src/parser/NordicBetParser.java

@@ -50,6 +50,7 @@ public class NordicBetParser extends ParserBase {
                     element.click();
                     element.click();
                     wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath(
                     wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath(
                             "//div[contains(@class,'obg-event-row-event-container')]"), matchDivs.size()));
                             "//div[contains(@class,'obg-event-row-event-container')]"), matchDivs.size()));
+                    Thread.sleep(200);
                     matchDivs = driver
                     matchDivs = driver
                             .findElements(By.xpath("//div[contains(@class,'obg-event-row-event-container')]"));
                             .findElements(By.xpath("//div[contains(@class,'obg-event-row-event-container')]"));
                     scrollElementIntoView(driver, element);
                     scrollElementIntoView(driver, element);
@@ -60,7 +61,7 @@ public class NordicBetParser extends ParserBase {
                     element.click();
                     element.click();
                     wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath(
                     wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath(
                             "//div[contains(@class,'obg-event-row-event-container')]"), matchDivs.size()));
                             "//div[contains(@class,'obg-event-row-event-container')]"), matchDivs.size()));
-
+                    Thread.sleep(200);
                     matchDivs = driver
                     matchDivs = driver
                             .findElements(By.xpath("//div[contains(@class,'obg-event-row-event-container')]"));
                             .findElements(By.xpath("//div[contains(@class,'obg-event-row-event-container')]"));
                     scrollElementIntoView(driver, element);
                     scrollElementIntoView(driver, element);
@@ -72,13 +73,13 @@ public class NordicBetParser extends ParserBase {
                     element.click();
                     element.click();
                     wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath(
                     wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath(
                             "//div[contains(@class,'obg-event-row-event-container')]"), matchDivs.size()));
                             "//div[contains(@class,'obg-event-row-event-container')]"), matchDivs.size()));
-
+                    Thread.sleep(200);
                     matchDivs = driver
                     matchDivs = driver
                             .findElements(By.xpath("//div[contains(@class,'obg-event-row-event-container')]"));
                             .findElements(By.xpath("//div[contains(@class,'obg-event-row-event-container')]"));
                     scrollElementIntoView(driver, element);
                     scrollElementIntoView(driver, element);
                 }
                 }
 
 
-            } catch (ElementNotFoundException e) {
+            } catch (ElementNotFoundException | InterruptedException e) {
                 // Empty by design, no more matches today
                 // Empty by design, no more matches today
             }
             }
         }
         }
@@ -90,6 +91,7 @@ public class NordicBetParser extends ParserBase {
 
 
         js.executeScript("window.stop;");
         js.executeScript("window.stop;");
         for (WebElement match : matchDivs) {
         for (WebElement match : matchDivs) {
+            scrollElementIntoViewCenter(driver, match);
             parseMatch(driver, match);
             parseMatch(driver, match);
         }
         }
         System.out.println("found " + matchDivs.size() + " matches");
         System.out.println("found " + matchDivs.size() + " matches");
@@ -106,6 +108,11 @@ public class NordicBetParser extends ParserBase {
             WebElement findElement = button.findElement(By.xpath(".//span"));
             WebElement findElement = button.findElement(By.xpath(".//span"));
             while (!findElement.getText().contains("less")) {
             while (!findElement.getText().contains("less")) {
                 button.click();
                 button.click();
+                try {
+                    Thread.sleep(200);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
                 findElement = button.findElement(By.xpath(".//span"));
                 findElement = button.findElement(By.xpath(".//span"));
             }
             }
 
 
@@ -130,9 +137,12 @@ public class NordicBetParser extends ParserBase {
             List<WebElement> oddsContainers = match.findElements(By.xpath(".//obg-event-row-market-container"));
             List<WebElement> oddsContainers = match.findElements(By.xpath(".//obg-event-row-market-container"));
 
 
             Optional<WebElement> matchOddsContainer = oddsContainers.stream()
             Optional<WebElement> matchOddsContainer = oddsContainers.stream()
-                    .filter(p -> p.findElement(By.xpath("//header/div/span"))
-                            .getText().equals("Matchresultat"))
+                    .filter(p -> checkIfElementExists(p, ".//header//div//span")
+                            ? p.findElement(By.xpath(".//header/div/span"))
+                                    .getText().equals("Matchresultat")
+                            : Boolean.FALSE)
                     .findFirst();
                     .findFirst();
+
             float odds1 = -1f;
             float odds1 = -1f;
             float oddsX = -1f;
             float oddsX = -1f;
             float odds2 = -1f;
             float odds2 = -1f;
@@ -147,23 +157,38 @@ public class NordicBetParser extends ParserBase {
                 }
                 }
 
 
             }
             }
-            parsedMatches.add(new ResultDTO(homeTeamName, awayTeamName, odds1, oddsX, odds2));
-            System.out.println(homeTeamName + "-" + awayTeamName + " odds (" + odds1 + "," + oddsX + "," + odds2 + ")");
-        } catch (StaleElementReferenceException e) {
-            System.out.println("Stale element, refreshing");
-            driver.navigate().refresh();
-            parseMatch(driver, match);
-        }
-    }
 
 
-    private float formatFloat(String string) {
-        float result = -1f;
-        try {
-            result = Float.parseFloat(string);
-        } catch (NumberFormatException e) {
-            // Empty by design
-        }
+            float oddsOver25 = -1f;
+            float oddsUnder25 = -1f;
+
+            Optional<WebElement> numberOfGoalsContainer = oddsContainers.stream()
+                    .filter(p -> checkIfElementExists(p, ".//header/div/span")
+                            ? p.findElement(By.xpath(".//header/div/span"))
+                                    .getText().toLowerCase().trim().contains("antal mål")
+                            : Boolean.FALSE)
+                    .findFirst();
+
+            if (numberOfGoalsContainer.isPresent()) {
+                List<WebElement> overUnderElements = numberOfGoalsContainer.get()
+                        .findElements(By.xpath(".//section//span[contains(@class, 'obg-selection-content-label')]"));
+
+                for (WebElement element : overUnderElements) {
+                    WebElement oddsElement = element.findElement(By.xpath(".//..//..//span[@test-id='odds']"));
+                    if (element.getText().trim().equals("över 2.5")) {
+                        oddsOver25 = formatFloat(oddsElement.getText());
+                    } else if (element.getText().trim().equals("under 2.5")) {
+                        oddsUnder25 = formatFloat(oddsElement.getText());
+                    }
+                }
+            }
 
 
-        return result;
+            parsedMatches.add(new ResultDTO(homeTeamName, awayTeamName, odds1, oddsX, odds2, oddsOver25, oddsUnder25));
+            System.out.println(homeTeamName + "-" + awayTeamName + " odds (" + odds1 + "," + oddsX + "," + odds2 + ")"
+                    + " overUnder: " + oddsOver25 + "/" + oddsUnder25);
+        } catch (StaleElementReferenceException e) {
+//            System.out.println("Stale element, refreshing");
+//            driver.navigate().refresh();
+//            parseMatch(driver, match);
+        }
     }
     }
 }
 }

+ 268 - 158
Odds/src/parser/OddsPortal.java

@@ -1,17 +1,19 @@
 package parser;
 package parser;
 
 
 import java.io.IOException;
 import java.io.IOException;
-import java.sql.SQLException;
 import java.time.LocalDate;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatter;
-import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
 import java.util.Locale;
 import java.util.Locale;
 import java.util.logging.Level;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.logging.Logger;
 
 
 import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.log.Log;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.chrome.ChromeDriver;
 
 
 import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
 import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
 import com.gargoylesoftware.htmlunit.WebClient;
 import com.gargoylesoftware.htmlunit.WebClient;
@@ -27,8 +29,10 @@ import com.google.common.base.Strings;
 import mysql.Mysql;
 import mysql.Mysql;
 import object.ResultDTO;
 import object.ResultDTO;
 
 
-public class OddsPortal implements ParserJoinedFunctions {
+public class OddsPortal extends ParserBase implements ParserJoinedFunctions {
 
 
+    private static final String DIV_CONTAINS_CLASS_TABS_DIV_NOT_CLASS_DIV_1_DIV = "//div[contains(@class,'tabs')]/div[not(@class)]/div[1]/div";
+    private static final String SOCCER_RESULTS_TABLE_NAME = "SoccerResults";
     private static final String CLASS = "class";
     private static final String CLASS = "class";
     private static final String DATE_PATTERN = "yyyyMMdd";
     private static final String DATE_PATTERN = "yyyyMMdd";
     private LocalDateTime baseDate;
     private LocalDateTime baseDate;
@@ -37,158 +41,11 @@ public class OddsPortal implements ParserJoinedFunctions {
     private int leagueId;
     private int leagueId;
     private LocalDateTime gameDate;
     private LocalDateTime gameDate;
 
 
-    public void getYesterdaysMatches() {
-        baseDate = LocalDateTime.now().plusDays(-1);
-        final String date = LocalDate.now().plusDays(-1).format(DateTimeFormatter.ofPattern(DATE_PATTERN));
-        getMatchesByDate(date);
-    }
-
-    public void getTodaysMatches() {
-        baseDate = LocalDateTime.now();
-        final String date = LocalDate.now().format(DateTimeFormatter.ofPattern(DATE_PATTERN));
-        getMatchesByDate(date);
-    }
-
-    public void getTomorrowsMatches() {
-        baseDate = LocalDateTime.now().plusDays(1);
-        final String dateTomorrow = LocalDate.now().plusDays(1).format(DateTimeFormatter.ofPattern(DATE_PATTERN));
-        getMatchesByDate(dateTomorrow);
-    }
-
-    public void getNextDaysMatches() {
-        baseDate = LocalDateTime.now().plusDays(2);
-        final String dateTomorrow = LocalDate.now().plusDays(2).format(DateTimeFormatter.ofPattern(DATE_PATTERN));
-        getMatchesByDate(dateTomorrow);
-    }
-
-    // https://stackoverflow.com/questions/14439991/skip-particular-javascript-execution-in-html-unit
-    // Skip url
-    private void getMatchesByDate(String date) {
-        final String soccerUrl = "https://oddsportal.com/matches/soccer/" + date;
-        // final String hockeyUrl = "https://oddsportal.com/matches/hockey/" + date;
-
-        try (final WebClient webClient = new WebClient()) {
-            webClient.getOptions().setUseInsecureSSL(true);
-            webClient.getOptions().setCssEnabled(false);
-            webClient.getOptions().setJavaScriptEnabled(true);
-            webClient.getOptions().setThrowExceptionOnScriptError(false);
-            webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
-            Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF);
-
-            webClient.waitForBackgroundJavaScript(3000);
-            parseSoccerMatches(soccerUrl, webClient, date);
-
-        } catch (Exception e) {
-            System.out.println("Webclient failed " + e.getMessage());
-            e.printStackTrace();
-        }
-    }
-
-    private void parseSoccerMatches(final String soccerUrl, final WebClient webClient, String date) {
-        try {
-            final HtmlPage soccerMatches = webClient.getPage(soccerUrl);
-            final HtmlTable matchesTable = soccerMatches.getFirstByXPath("//table[contains(@class, table-main)]");
-            final List<HtmlTableRow> rows = matchesTable.getRows();
-            String countryName = "";
-            String leagueName = "";
-            int i = 1;
-            for (final HtmlTableRow tr : rows) {
-                if (tr.getAttribute(CLASS).equals("dark center")) {
-                    final List<HtmlAnchor> countryLeague = tr.getByXPath(".//a");
-                    countryName = countryLeague.get(0).asNormalizedText().toLowerCase().trim();
-                    leagueName = countryLeague.get(1).asNormalizedText().toLowerCase().trim();
-                    leagueName = leagueName.replace(" ", "-");
-                    leagueName = leagueName.replace("\\.", "");
-                    countryName = countryName.replace(" ", "-");
-                    countryName = countryName.replace("\\.", "");
-                } else {
-                    final List<HtmlTableCell> cells = tr.getCells();
-                    final String[] time = cells.get(0).asNormalizedText().split(":");
-                    final String[] teams = cells.get(1).asNormalizedText().split(" - ");
-                    float odds1 = 0F;
-                    float oddsX = 0F;
-                    float odds2 = 0F;
-                    int homeScore = -1;
-                    int awayScore = -1;
-                    boolean overtime = false;
-
-                    boolean abandon = false;
-
-                    try {
-                        for (final HtmlTableCell tc : cells) {
-                            if (tc.getAttribute(CLASS).contains("live-score")) {
-                                abandon = true;
-                                break;
-                            }
-                            // Score
-                            if (tc.getAttribute(CLASS).contains("table-score")) {
-                                final String[] scoreValue = tc.asNormalizedText().split(":");
-                                homeScore = Integer.valueOf(scoreValue[0]);
-                                if (scoreValue[1].matches("\\D+")) {
-                                    overtime = true;
-                                }
-                                awayScore = Integer.valueOf(scoreValue[1].replaceAll("\\D+", ""));
-                            }
-                            if (tc.getAttribute(CLASS).contains("odds-nowrp")) {
-                                if (tc.asNormalizedText().matches("[+-][0-9][0-9][0-9]")) {
-                                    if (odds1 == 0F) {
-                                        odds1 = convertAmericanOddsToDecimal(Integer.valueOf(tc.asNormalizedText()));
-                                    } else if (oddsX == 0F) {
-                                        oddsX = convertAmericanOddsToDecimal(Integer.valueOf(tc.asNormalizedText()));
-                                    } else if (odds2 == 0F) {
-                                        odds2 = convertAmericanOddsToDecimal(Integer.valueOf(tc.asNormalizedText()));
-                                    }
-                                } else if (tc.asNormalizedText().matches("[0-9].[0-9]+")) {
-                                    if (odds1 == 0F) {
-                                        odds1 = Float.valueOf(tc.asNormalizedText());
-                                    } else if (oddsX == 0F) {
-                                        oddsX = Float.valueOf(tc.asNormalizedText());
-                                    } else if (odds2 == 0F) {
-                                        odds2 = Float.valueOf(tc.asNormalizedText());
-                                    }
-                                }
-                            }
-
-                        }
-                    } catch (final NumberFormatException e) {
-                        Log.getLog().info(String.format(
-                                "Failed to get the match between %s and %s at %s odds1 %s oddsX %s odds2 %s homeScore %s awayScore %s overtime %s",
-                                teams[0].trim(), teams[1].trim(),
-                                baseDate.withHour(Integer.valueOf(time[0])).withMinute(Integer.valueOf(time[1])),
-                                odds1, oddsX, odds2, homeScore, awayScore, (overtime ? "true" : "false")));
-                        continue;
-                    }
-
-                    if (abandon) {
-                        continue;
-                    }
-                    final Mysql mysql = Mysql.getInstance();
-                    final int leaguesId = mysql.addLeague(leagueName, countryName, "soccer");
-                    final int countrysId = mysql.getCountryId(countryName);
-                    final int sportsId = mysql.getSportId("soccer");
-
-                    String season = mysql.getLastSeason(leagueName, countryId); // TODO This don't work
-//					String season = String.valueOf(LocalDate.parse(date, DateTimeFormatter.ofPattern(DATE_PATTERN)).getYear());
-                    if (Strings.isNullOrEmpty(season)) {
-                        season = String.valueOf(LocalDateTime.now().getYear());
-                    }
-
-                    final LocalDateTime dt = baseDate.withHour(Integer.valueOf(time[0]))
-                            .withMinute(Integer.valueOf(time[1])).withSecond(0)
-                            .withNano(0);
-                    if (teams.length != 2) {
-                        System.out.println("Something wrong with teams " + Arrays.toString(teams));
-                    } else {
-                        mysql.addResult(new ResultDTO("SoccerResults", dt, teams[0].trim(), teams[1].trim(), homeScore,
-                                awayScore, overtime, odds1,
-                                oddsX, odds2, countrysId, season, leaguesId, sportsId));
-                    }
-                }
-            }
-        } catch (FailingHttpStatusCodeException | IOException | SQLException e) {
-            e.printStackTrace();
-        }
-    }
+    final int sportsId = Mysql.getInstance().getSportId("soccer");
+    private int currentLeagueId;
+    private int currentCountryId;
+    private List<ResultDTO> resultsToInsert = new ArrayList<>();
+    private String currentSeason;
 
 
     public void getHistoricMatches(String sport, String country, String league, String year) {
     public void getHistoricMatches(String sport, String country, String league, String year) {
         final String url = "https://www.oddsportal.com/";
         final String url = "https://www.oddsportal.com/";
@@ -256,7 +113,7 @@ public class OddsPortal implements ParserJoinedFunctions {
                 }
                 }
                 // process new tournament table content
                 // process new tournament table content
             }
             }
-        } catch (FailingHttpStatusCodeException | IOException | SQLException e) {
+        } catch (FailingHttpStatusCodeException | IOException e) {
             e.printStackTrace();
             e.printStackTrace();
         } catch (final ClassCastException cce) {
         } catch (final ClassCastException cce) {
             Log.getLog().info("Class cast exception message: " + cce.getMessage() + " \ncause: " + cce.getCause());
             Log.getLog().info("Class cast exception message: " + cce.getMessage() + " \ncause: " + cce.getCause());
@@ -267,9 +124,154 @@ public class OddsPortal implements ParserJoinedFunctions {
         Log.getLog().info("DONE with " + country + " (" + countryId + ") league " + league + "(" + leagueId + ")");
         Log.getLog().info("DONE with " + country + " (" + countryId + ") league " + league + "(" + leagueId + ")");
     }
     }
 
 
+    public void getNextDaysMatches() {
+        baseDate = LocalDateTime.now().plusDays(2);
+        final String dateTomorrow = LocalDate.now().plusDays(2).format(DateTimeFormatter.ofPattern(DATE_PATTERN));
+        getMatchesByDateSelenium(dateTomorrow);
+    }
+
+    public void getTodaysMatches() {
+        baseDate = LocalDateTime.now();
+        final String date = LocalDate.now().format(DateTimeFormatter.ofPattern(DATE_PATTERN));
+        getMatchesByDateSelenium(date);
+    }
+
+    // https://stackoverflow.com/questions/14439991/skip-particular-javascript-execution-in-html-unit
+    // Skip url
+    public void getTomorrowsMatches() {
+        baseDate = LocalDateTime.now().plusDays(1);
+        final String dateTomorrow = LocalDate.now().plusDays(1).format(DateTimeFormatter.ofPattern(DATE_PATTERN));
+        getMatchesByDateSelenium(dateTomorrow);
+    }
+
+    public void getYesterdaysMatches() {
+        baseDate = LocalDateTime.now().plusDays(-1);
+        final String date = LocalDate.now().plusDays(-1).format(DateTimeFormatter.ofPattern(DATE_PATTERN));
+        getMatchesByDateSelenium(date);
+    }
+
+    private int getCountryId(List<WebElement> links) {
+        String country;
+        country = links.get(1).getText().trim();
+        country = country.replace(" ", "-");
+        country = country.replace("\\.", "");
+        return Mysql.getInstance().getCountryId(country);
+    }
+
+    private String getLastSeason(int leagueId, int countryId) {
+        String result = "";
+
+        if (!Strings.isNullOrEmpty(currentSeason) && currentLeagueId == leagueId && currentCountryId == countryId) {
+            return currentSeason;
+        } else {
+            result = Mysql.getInstance().getLastSeason(leagueId, countryId);
+        }
+
+        if (Strings.isNullOrEmpty(result)) {
+            result = String.valueOf(LocalDate.now().getYear());
+        }
+        return result;
+    }
+
+    private int getLeagueId(List<WebElement> links) {
+        String league;
+        league = links.get(2).getText().trim();
+        league = league.replace(" ", "-");
+        league = league.replace("\\.", "");
+        return Mysql.getInstance().getLeagueId(sportId, countryId, league);
+    }
+
+    private void getMatchesByDateSelenium(String date) {
+        final String soccerUrl = "https://oddsportal.com/matches/soccer/" + date;
+        parseSoccerMatchesSelenium(soccerUrl);
+    }
+
+    private void parseSoccerMatchesSelenium(final String soccerUrl) {
+        ChromeDriver driver = getSeleniumDriver();
+        sportId = Mysql.getInstance().getSportId("soccer");
+        driver.get(soccerUrl);
+
+        try {
+            Thread.sleep(400);
+
+            List<WebElement> divs = driver
+                    .findElements(By.xpath(DIV_CONTAINS_CLASS_TABS_DIV_NOT_CLASS_DIV_1_DIV));
+
+            int divsCount = divs.size();
+
+            divs = scrollAndGetAllMatchDivs(driver, divs, divsCount);
+
+            for (WebElement element : divs) {
+                ResultDTO result = new ResultDTO(SOCCER_RESULTS_TABLE_NAME);
+
+                boolean somethingWrong = false;
+                List<WebElement> subDivs = element.findElements(By.xpath("./div"));
+                if (subDivs.size() == 3) {
+                    WebElement competitionsDiv = subDivs.get(0);
+                    List<WebElement> links = competitionsDiv.findElements(By.xpath(".//a"));
+
+                    countryId = getCountryId(links);
+                    leagueId = getLeagueId(links);
+                    result.setLeagueId(leagueId);
+                    result.setCountryId(countryId);
+
+                    WebElement firstResultsDiv = subDivs.get(2);
+
+                    setGameDate(result, firstResultsDiv);
+
+                    setTeamsInfo(result, firstResultsDiv);
+
+                    setOdds(result, firstResultsDiv);
+
+                } else if (subDivs.size() == 1) {
+
+                    result.setLeagueId(leagueId);
+                    result.setCountryId(countryId);
+                    WebElement firstResultsDiv = subDivs.get(0);
+
+                    setGameDate(result, firstResultsDiv);
+                    setTeamsInfo(result, firstResultsDiv);
+
+                    setOdds(result, firstResultsDiv);
+                } else {
+                    somethingWrong = true;
+                    String message = "Subdiv size = " + subDivs.size();
+                    Logger.getGlobal().log(Level.WARNING, message);
+                }
+
+                if (!somethingWrong) {
+                    final Mysql mysql = Mysql.getInstance();
+
+                    result.setCountryId(countryId);
+                    result.setLeagueId(leagueId);
+                    result.setSeason(getLastSeason(leagueId, countryId));
+
+                    resultsToInsert.add(result);
+
+                    if (resultsToInsert.size() > 100) {
+                        Logger.getGlobal().log(Level.INFO, "INSERTING 100 results");
+                        mysql.addResults(resultsToInsert);
+                        resultsToInsert.clear();
+                    }
+
+                }
+
+            }
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+            Thread.currentThread().interrupt();
+        }
+
+        String message = "INSERTING LAST " + resultsToInsert.size() + " results";
+        Logger.getGlobal().log(Level.INFO, message);
+        Mysql.getInstance().addResults(resultsToInsert);
+        resultsToInsert.clear();
+        driver.close();
+    }
+
     private void parseTournamentTable(int sportId, int countryId, int leagueId, String season,
     private void parseTournamentTable(int sportId, int countryId, int leagueId, String season,
             HtmlTable tournamentTable, LocalDateTime gameDate,
             HtmlTable tournamentTable, LocalDateTime gameDate,
-            DateTimeFormatter dateFormatter) throws SQLException {
+            DateTimeFormatter dateFormatter) {
         for (final HtmlTableRow tr : tournamentTable.getRows()) {
         for (final HtmlTableRow tr : tournamentTable.getRows()) {
             if (tr.getAttribute(CLASS).contains("deactivate")) {
             if (tr.getAttribute(CLASS).contains("deactivate")) {
                 String homeTeam;
                 String homeTeam;
@@ -335,7 +337,7 @@ public class OddsPortal implements ParserJoinedFunctions {
                 if (gameDate != null && homeTeam != null && awayTeam != null && odds1 != 0 && oddsX != 0 && odds2 != 0
                 if (gameDate != null && homeTeam != null && awayTeam != null && odds1 != 0 && oddsX != 0 && odds2 != 0
                         && !Strings.isNullOrEmpty(season)) { // All set.. update sql result table
                         && !Strings.isNullOrEmpty(season)) { // All set.. update sql result table
                     Mysql.getInstance()
                     Mysql.getInstance()
-                            .addResult(new ResultDTO("SoccerResults", gameDate, homeTeam, awayTeam, homeScore,
+                            .addResult(new ResultDTO(SOCCER_RESULTS_TABLE_NAME, gameDate, homeTeam, awayTeam, homeScore,
                                     awayScore, overtime, odds1,
                                     awayScore, overtime, odds1,
                                     oddsX, odds2, countryId, season, leagueId, sportId));
                                     oddsX, odds2, countryId, season, leagueId, sportId));
                 } else {
                 } else {
@@ -358,4 +360,112 @@ public class OddsPortal implements ParserJoinedFunctions {
             }
             }
         }
         }
     }
     }
+
+    private List<WebElement> scrollAndGetAllMatchDivs(ChromeDriver driver, List<WebElement> divs, int divsCount)
+            throws InterruptedException {
+        if (divsCount > 0) {
+            scrollElementIntoViewCenter(driver, divs.get(divsCount - 1));
+            Thread.sleep(1000);
+            divs = driver
+                    .findElements(By.xpath(DIV_CONTAINS_CLASS_TABS_DIV_NOT_CLASS_DIV_1_DIV));
+        }
+
+        while (divsCount < divs.size()) {
+            if (divsCount > 0) {
+                divsCount = divs.size();
+                scrollElementIntoViewCenter(driver, divs.get(divsCount - 1));
+                Thread.sleep(1000);
+                divs = driver
+                        .findElements(By.xpath(DIV_CONTAINS_CLASS_TABS_DIV_NOT_CLASS_DIV_1_DIV));
+            }
+        }
+        return divs;
+    }
+
+    private void setGameDate(ResultDTO result, WebElement firstResultsDiv) {
+        final List<Integer> time = new ArrayList<>();
+        if (checkIfElementExists(firstResultsDiv, "./div/a/div[1]/div/p")) {
+            String timeText = firstResultsDiv.findElement(By.xpath("./div/a/div[1]/div/p")).getText();
+            String[] timeSplit = timeText.split(":");
+            if (timeSplit.length == 2) {
+                time.add(Integer.parseInt(timeSplit[0]));
+                time.add(Integer.parseInt(timeSplit[1]));
+            } else {
+                time.add(0);
+                time.add(0);
+            }
+        } else {
+            time.add(0);
+            time.add(0);
+        }
+        final LocalDateTime dt = baseDate.withHour(time.get(0))
+                .withMinute(time.get(1)).withSecond(0)
+                .withNano(0);
+
+        result.setGameDate(dt);
+    }
+
+    private void setOdds(ResultDTO result, WebElement firstResultsDiv) {
+        final int addToOddsDivPosition;
+        if (checkIfElementExists(firstResultsDiv, "./div/div[1]/div")) {
+            String resultsText = firstResultsDiv.findElement(By.xpath("./div/div[1]/div")).getText();
+
+            String[] results = resultsText.split(":");
+
+            if (results.length == 2) {
+                result.setHomeScore(Integer.parseInt(results[0]));
+                if (!results[1].matches("[0-9]*")) {
+                    result.setOvertime(true);
+                    result.setAwayScore(Integer.parseInt(results[1].replaceAll("[^0-9]", "")));
+                } else {
+                    result.setAwayScore(Integer.parseInt(results[1]));
+                }
+                addToOddsDivPosition = 1;
+            } else {
+                addToOddsDivPosition = 0;
+            }
+        } else {
+            addToOddsDivPosition = 0;
+        }
+
+        String divStartString = "./div/div[";
+        String divEndString = "]/div/span/p";
+        if (checkIfElementExists(firstResultsDiv,
+                divStartString + (1 + addToOddsDivPosition) + divEndString)) {
+            result.setOdds1(formatFloat(
+                    firstResultsDiv
+                            .findElement(
+                                    By.xpath(divStartString + (1 + addToOddsDivPosition) + divEndString))
+                            .getText().trim()));
+        }
+        if (checkIfElementExists(firstResultsDiv,
+                divStartString + (2 + addToOddsDivPosition) + divEndString)) {
+            result.setOddsX(formatFloat(
+                    firstResultsDiv
+                            .findElement(
+                                    By.xpath(divStartString + (2 + addToOddsDivPosition) + divEndString))
+                            .getText().trim()));
+        }
+        if (checkIfElementExists(firstResultsDiv,
+                divStartString + (3 + addToOddsDivPosition) + divEndString)) {
+            result.setOdds2(formatFloat(
+                    firstResultsDiv
+                            .findElement(
+                                    By.xpath(divStartString + (3 + addToOddsDivPosition) + divEndString))
+                            .getText().trim()));
+        }
+    }
+
+    private void setTeamsInfo(ResultDTO result, WebElement firstResultsDiv) {
+        List<WebElement> teams = firstResultsDiv.findElements(By.xpath(".//div//a//div[2]//a"));
+        String homeTeamName = teams.get(0).getText().trim();
+        String awayTeamName = teams.get(1).getText().trim();
+        result.setHomeTeam(homeTeamName);
+        result.setAwayTeam(awayTeamName);
+
+        result.setHomeTeamId(
+                Mysql.getInstance().getOrInsertTeam(homeTeamName, countryId, leagueId, sportId));
+        result.setAwayTeamId(
+                Mysql.getInstance().getOrInsertTeam(awayTeamName, countryId, leagueId, sportId));
+    }
 }
 }

+ 27 - 1
Odds/src/parser/ParserBase.java

@@ -1,5 +1,6 @@
 package parser;
 package parser;
 
 
+import java.time.Duration;
 import java.util.Collections;
 import java.util.Collections;
 
 
 import org.openqa.selenium.By;
 import org.openqa.selenium.By;
@@ -7,6 +8,7 @@ import org.openqa.selenium.JavascriptExecutor;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.WebElement;
 import org.openqa.selenium.chrome.ChromeDriver;
 import org.openqa.selenium.chrome.ChromeDriver;
 import org.openqa.selenium.chrome.ChromeOptions;
 import org.openqa.selenium.chrome.ChromeOptions;
+import org.openqa.selenium.support.ui.WebDriverWait;
 
 
 public class ParserBase {
 public class ParserBase {
 
 
@@ -14,7 +16,7 @@ public class ParserBase {
         ChromeOptions options = new ChromeOptions();
         ChromeOptions options = new ChromeOptions();
 
 
         System.setProperty("webdriver.chrome.driver",
         System.setProperty("webdriver.chrome.driver",
-                System.getProperty("user.dir") + "/odds/Odds/chromedriver.exe");
+                System.getProperty("user.dir") + "/chromedriver.exe");
         System.setProperty("webdriver.chrome.silentOutput", "true");
         System.setProperty("webdriver.chrome.silentOutput", "true");
         // Fixing 255 Error crashes
         // Fixing 255 Error crashes
         options.addArguments("--no-sandbox");
         options.addArguments("--no-sandbox");
@@ -39,10 +41,23 @@ public class ParserBase {
         return driver;
         return driver;
     }
     }
 
 
+    protected WebDriverWait getWaitDriver(ChromeDriver driver) {
+        return new WebDriverWait(driver, Duration.ofSeconds(30));
+    }
+
+    protected JavascriptExecutor getJsExecutor(ChromeDriver driver) {
+        return driver;
+    }
+
     protected boolean checkIfElementExists(WebElement element, String xpath) {
     protected boolean checkIfElementExists(WebElement element, String xpath) {
         return !element.findElements(By.xpath(xpath)).isEmpty();
         return !element.findElements(By.xpath(xpath)).isEmpty();
     }
     }
 
 
+    protected void scrollToTopOfPage(ChromeDriver driver) {
+        ((JavascriptExecutor) driver)
+                .executeScript("document.body.scrollTop = document.documentElement.scrollTop = 0;");
+    }
+
     protected void scrollElementIntoView(ChromeDriver driver, WebElement element) {
     protected void scrollElementIntoView(ChromeDriver driver, WebElement element) {
         ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView();", element);
         ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView();", element);
     }
     }
@@ -50,4 +65,15 @@ public class ParserBase {
     protected void scrollElementIntoViewCenter(ChromeDriver driver, WebElement element) {
     protected void scrollElementIntoViewCenter(ChromeDriver driver, WebElement element) {
         ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView({ block: 'center' });", element);
         ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView({ block: 'center' });", element);
     }
     }
+
+    protected float formatFloat(String string) {
+        float result = -1f;
+        try {
+            result = Float.parseFloat(string);
+        } catch (NumberFormatException e) {
+            // Empty by design
+        }
+
+        return result;
+    }
 }
 }

+ 8 - 0
Odds/src/parser/Todo/BetssonParser.java

@@ -0,0 +1,8 @@
+package parser.Todo;
+
+import parser.ParserBase;
+
+public class BetssonParser extends ParserBase {
+
+    String url = "https://www.snabbare.com/sv/sportsbook";
+}

+ 9 - 0
Odds/src/parser/Todo/ComeOnParser.java

@@ -0,0 +1,9 @@
+package parser.Todo;
+
+import parser.ParserBase;
+
+public class ComeOnParser extends ParserBase {
+
+    String url = "https://www.comeon.com/sv/sportsbook/sports/1-fotboll/upcoming/0";
+    String url2 = "https://www.comeon.com/sv/sportsbook/sports/1-fotboll/upcoming/1";
+}

+ 8 - 0
Odds/src/parser/Todo/MrGreenParser.java

@@ -0,0 +1,8 @@
+package parser.Todo;
+
+import parser.ParserBase;
+
+public class MrGreenParser extends ParserBase {
+
+    String url = "https://sport.mrgreen.com/sv-SE/filter/football";
+}

+ 8 - 0
Odds/src/parser/Todo/SnabbareParser.java

@@ -0,0 +1,8 @@
+package parser.Todo;
+
+import parser.ParserBase;
+
+public class SnabbareParser extends ParserBase {
+
+    String url = "https://www.betsson.com/sv/odds/fotboll";
+}

+ 1 - 0
Odds/src/parser/Todo/SpeedyBetParser_KanskeBesvärlig.java

@@ -0,0 +1 @@
+package parser.Todo;

+ 7 - 0
Odds/src/parser/Todo/UnibetParser.java

@@ -0,0 +1,7 @@
+package parser.Todo;
+
+import parser.ParserBase;
+
+public class UnibetParser extends ParserBase {
+    String url = "https://www.unibet.se/betting/sports/filter/football/all/matches";
+}

+ 191 - 162
OddsJavaFx/src/controllers/AnalysisTestController.java

@@ -25,15 +25,21 @@ import javafx.scene.control.TableView;
 import javafx.scene.control.TextField;
 import javafx.scene.control.TextField;
 import javafx.scene.control.cell.MapValueFactory;
 import javafx.scene.control.cell.MapValueFactory;
 import javafx.scene.control.cell.PropertyValueFactory;
 import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.control.cell.TextFieldTableCell;
 import javafx.util.Callback;
 import javafx.util.Callback;
+import javafx.util.converter.FloatStringConverter;
 import objects.League;
 import objects.League;
 import objects.SoccerMatch;
 import objects.SoccerMatch;
 import objects.SoccerMatchAnalysis;
 import objects.SoccerMatchAnalysis;
 import objects.bets.Bet;
 import objects.bets.Bet;
 import objects.bets.Bet.Status;
 import objects.bets.Bet.Status;
 
 
+@SuppressWarnings("rawtypes")
 public class AnalysisTestController implements Initializable {
 public class AnalysisTestController implements Initializable {
 
 
+    private static final float MIN_COVER_ODDS = 1.25f;
+    private static final float MAX_COVER_ODDS = 2.25f;
+    private static final DecimalFormat FLOAT_FORMATTER = new DecimalFormat("0.00");
     @FXML
     @FXML
     TableView<SoccerMatch> gameViewTable;
     TableView<SoccerMatch> gameViewTable;
     TableColumn<SoccerMatch, String> homeTeamNameColumn = new TableColumn<>("Home Team");
     TableColumn<SoccerMatch, String> homeTeamNameColumn = new TableColumn<>("Home Team");
@@ -42,23 +48,25 @@ public class AnalysisTestController implements Initializable {
     TableColumn<SoccerMatch, Float> oddsXColumn = new TableColumn<>("X");
     TableColumn<SoccerMatch, Float> oddsXColumn = new TableColumn<>("X");
     TableColumn<SoccerMatch, Float> odds2Column = new TableColumn<>("2");
     TableColumn<SoccerMatch, Float> odds2Column = new TableColumn<>("2");
     TableColumn<SoccerMatch, String> leagueNameColumn = new TableColumn<>("Country");
     TableColumn<SoccerMatch, String> leagueNameColumn = new TableColumn<>("Country");
+
     TableColumn<SoccerMatch, String> countryNameColumn = new TableColumn<>("League");
     TableColumn<SoccerMatch, String> countryNameColumn = new TableColumn<>("League");
+
     TableColumn<SoccerMatch, String> analyzeValueColumn = new TableColumn<>("Value");
     TableColumn<SoccerMatch, String> analyzeValueColumn = new TableColumn<>("Value");
     TableColumn<SoccerMatch, Float> matchBetAmountColumn = new TableColumn<>("Bet Amount");
     TableColumn<SoccerMatch, Float> matchBetAmountColumn = new TableColumn<>("Bet Amount");
-
     TableColumn<SoccerMatch, Void> addBetColumn = new TableColumn<>("Add Bet");
     TableColumn<SoccerMatch, Void> addBetColumn = new TableColumn<>("Add Bet");
-
     @FXML
     @FXML
     TableView<Bet> activeBetsTable;
     TableView<Bet> activeBetsTable;
     TableColumn<Bet, String> matchupColumn = new TableColumn<>("Matchup");
     TableColumn<Bet, String> matchupColumn = new TableColumn<>("Matchup");
     TableColumn<Bet, Float> oddsColumn = new TableColumn<>("Odds");
     TableColumn<Bet, Float> oddsColumn = new TableColumn<>("Odds");
     TableColumn<Bet, Float> betAmountColumn = new TableColumn<>("BetAmount");
     TableColumn<Bet, Float> betAmountColumn = new TableColumn<>("BetAmount");
     TableColumn<Bet, Bet.Status> statusColumn = new TableColumn<>("Status");
     TableColumn<Bet, Bet.Status> statusColumn = new TableColumn<>("Status");
+
     TableColumn<Bet, Integer> homeScoreColumn = new TableColumn<>("Home Score");
     TableColumn<Bet, Integer> homeScoreColumn = new TableColumn<>("Home Score");
     TableColumn<Bet, Integer> awayScoreColumn = new TableColumn<>("Away Score");
     TableColumn<Bet, Integer> awayScoreColumn = new TableColumn<>("Away Score");
-
+    TableColumn<Bet, Integer> betCoveredNumberColumn = new TableColumn<>("Bet Covered Number");
     @FXML
     @FXML
-    TableView<Map<String, Object>> LeagueBetStatsTable;
+    TableView<Map<String, Object>> leagueBetStatsTable;
+
     @FXML
     @FXML
     TableColumn<Map, String> statsLeagueNameColumn = new TableColumn<>("League");
     TableColumn<Map, String> statsLeagueNameColumn = new TableColumn<>("League");
     @FXML
     @FXML
@@ -69,29 +77,26 @@ public class AnalysisTestController implements Initializable {
     TableColumn<Map, Float> statsHomePercentColumn = new TableColumn<>("Home Percent");
     TableColumn<Map, Float> statsHomePercentColumn = new TableColumn<>("Home Percent");
     @FXML
     @FXML
     TableColumn<Map, Integer> statsAwayWinColumn = new TableColumn<>("Away Win");
     TableColumn<Map, Integer> statsAwayWinColumn = new TableColumn<>("Away Win");
+
     @FXML
     @FXML
     TableColumn<Map, Integer> statsAwayLossColumn = new TableColumn<>("Away Loss");
     TableColumn<Map, Integer> statsAwayLossColumn = new TableColumn<>("Away Loss");
     @FXML
     @FXML
     TableColumn<Map, Float> statsAwayPercentColumn = new TableColumn<>("Away Percent");
     TableColumn<Map, Float> statsAwayPercentColumn = new TableColumn<>("Away Percent");
     @FXML
     @FXML
     TableColumn<Map, Float> statsTotalPercentColumn = new TableColumn<>("Total Percent");
     TableColumn<Map, Float> statsTotalPercentColumn = new TableColumn<>("Total Percent");
-
     @FXML
     @FXML
     Button checkBetsButton;
     Button checkBetsButton;
     @FXML
     @FXML
     Button getMatchesButton;
     Button getMatchesButton;
     @FXML
     @FXML
     DatePicker date;
     DatePicker date;
+
     @FXML
     @FXML
     TextField bankTextField;
     TextField bankTextField;
     @FXML
     @FXML
     TextField bettingPercentTextField;
     TextField bettingPercentTextField;
-    private float currentBetAmount = 10f;
 
 
-    private static final float MIN_COVER_ODDS = 1.25f;
-    private static final float MAX_COVER_ODDS = 2.25f;
-
-    private static final DecimalFormat FLOAT_FORMATTER = new DecimalFormat("0.00");
+    private float currentBetAmount = 10f;
 
 
     @Override
     @Override
     public void initialize(URL location, ResourceBundle resources) {
     public void initialize(URL location, ResourceBundle resources) {
@@ -116,10 +121,6 @@ public class AnalysisTestController implements Initializable {
         gameViewTable.getSelectionModel().selectedItemProperty().addListener((obj, oldValue, newValue) -> {
         gameViewTable.getSelectionModel().selectedItemProperty().addListener((obj, oldValue, newValue) -> {
             if (oldValue != null) {
             if (oldValue != null) {
                 oldValue.setBetAmount(currentBetAmount);
                 oldValue.setBetAmount(currentBetAmount);
-                Bet previousBet = oldValue.getPreviousBet();
-//                if (previousBet != null && previousBet.getStatus() != Status.COVERED) {
-//                    oldValue.setPreviousBet(null);
-//                }
             }
             }
 
 
             if (newValue != null) {
             if (newValue != null) {
@@ -135,6 +136,7 @@ public class AnalysisTestController implements Initializable {
         odds1Column.setCellValueFactory(new PropertyValueFactory<>("odds1"));
         odds1Column.setCellValueFactory(new PropertyValueFactory<>("odds1"));
         oddsXColumn.setCellValueFactory(new PropertyValueFactory<>("oddsX"));
         oddsXColumn.setCellValueFactory(new PropertyValueFactory<>("oddsX"));
         odds2Column.setCellValueFactory(new PropertyValueFactory<>("odds2"));
         odds2Column.setCellValueFactory(new PropertyValueFactory<>("odds2"));
+
         leagueNameColumn.setCellValueFactory(new PropertyValueFactory<>("leagueName"));
         leagueNameColumn.setCellValueFactory(new PropertyValueFactory<>("leagueName"));
         countryNameColumn.setCellValueFactory(new PropertyValueFactory<>("countryName"));
         countryNameColumn.setCellValueFactory(new PropertyValueFactory<>("countryName"));
         analyzeValueColumn.setCellValueFactory(new PropertyValueFactory<>("analysisValue"));
         analyzeValueColumn.setCellValueFactory(new PropertyValueFactory<>("analysisValue"));
@@ -152,8 +154,6 @@ public class AnalysisTestController implements Initializable {
                             SoccerMatch data = getTableView().getItems().get(getIndex());
                             SoccerMatch data = getTableView().getItems().get(getIndex());
 
 
                             addToBets(data);
                             addToBets(data);
-
-//                            btn.setDisable(true);
                         });
                         });
                     }
                     }
 
 
@@ -175,7 +175,18 @@ public class AnalysisTestController implements Initializable {
 
 
         gameViewTable.getColumns().addAll(homeTeamNameColumn, awayTeamNameColumn, odds1Column, oddsXColumn, odds2Column,
         gameViewTable.getColumns().addAll(homeTeamNameColumn, awayTeamNameColumn, odds1Column, oddsXColumn, odds2Column,
                 countryNameColumn, leagueNameColumn, analyzeValueColumn, matchBetAmountColumn, addBetColumn);
                 countryNameColumn, leagueNameColumn, analyzeValueColumn, matchBetAmountColumn, addBetColumn);
-        gameViewTable.setEditable(false);
+        gameViewTable.setEditable(true);
+
+        odds1Column.setCellFactory(TextFieldTableCell.<SoccerMatch, Float>forTableColumn(new FloatStringConverter()));
+        odds1Column.setOnEditCommit(
+                e -> e.getTableView().getItems().get(e.getTablePosition().getRow()).setOdds1(e.getNewValue()));
+
+        oddsXColumn.setCellFactory(TextFieldTableCell.<SoccerMatch, Float>forTableColumn(new FloatStringConverter()));
+        oddsXColumn.setOnEditCommit(
+                e -> e.getTableView().getItems().get(e.getTablePosition().getRow()).setOddsX(e.getNewValue()));
+        odds2Column.setCellFactory(TextFieldTableCell.<SoccerMatch, Float>forTableColumn(new FloatStringConverter()));
+        odds2Column.setOnEditCommit(
+                e -> e.getTableView().getItems().get(e.getTablePosition().getRow()).setOdds2(e.getNewValue()));
 
 
         matchupColumn.setCellValueFactory(new PropertyValueFactory<>("matchup"));
         matchupColumn.setCellValueFactory(new PropertyValueFactory<>("matchup"));
         matchupColumn.setMinWidth(100d);
         matchupColumn.setMinWidth(100d);
@@ -184,11 +195,12 @@ public class AnalysisTestController implements Initializable {
         betAmountColumn.setCellValueFactory(new PropertyValueFactory<>("betAmount"));
         betAmountColumn.setCellValueFactory(new PropertyValueFactory<>("betAmount"));
         homeScoreColumn.setCellValueFactory(new PropertyValueFactory<>("homeScore"));
         homeScoreColumn.setCellValueFactory(new PropertyValueFactory<>("homeScore"));
         awayScoreColumn.setCellValueFactory(new PropertyValueFactory<>("awayScore"));
         awayScoreColumn.setCellValueFactory(new PropertyValueFactory<>("awayScore"));
+        betCoveredNumberColumn.setCellValueFactory(new PropertyValueFactory<>("betCoveredNumber"));
 
 
         statusColumn.setCellValueFactory(new PropertyValueFactory<>("status"));
         statusColumn.setCellValueFactory(new PropertyValueFactory<>("status"));
 
 
         activeBetsTable.getColumns().addAll(matchupColumn, oddsColumn, betAmountColumn, statusColumn, homeScoreColumn,
         activeBetsTable.getColumns().addAll(matchupColumn, oddsColumn, betAmountColumn, statusColumn, homeScoreColumn,
-                awayScoreColumn);
+                awayScoreColumn, betCoveredNumberColumn);
 
 
         getActiveBets();
         getActiveBets();
 
 
@@ -202,6 +214,78 @@ public class AnalysisTestController implements Initializable {
         statsAwayPercentColumn.setCellValueFactory(new MapValueFactory<>("statsAwayPercent"));
         statsAwayPercentColumn.setCellValueFactory(new MapValueFactory<>("statsAwayPercent"));
         statsTotalPercentColumn.setCellValueFactory(new MapValueFactory<>("statsTotalPercent"));
         statsTotalPercentColumn.setCellValueFactory(new MapValueFactory<>("statsTotalPercent"));
 
 
+        initializeStatsPanel();
+    }
+
+    private void addMatchesToTable(List<SoccerMatch> matches) {
+        ObservableList<SoccerMatch> currentMatches = FXCollections.<SoccerMatch>observableArrayList();
+
+        for (SoccerMatch soccerMatch : matches) {
+
+            int analyzeValue = getAnalyzeValue(soccerMatch);
+            soccerMatch.setAnalysisValue(analyzeValue);
+            if (currentBetAmount > 0) {
+                soccerMatch.setBetAmount(currentBetAmount);
+            }
+
+            currentMatches.add(soccerMatch);
+        }
+
+        gameViewTable.getItems().addAll(currentMatches);
+    }
+
+    private void addToBets(SoccerMatch data) {
+        if (data.getAnalysisValueInt() > 0) {
+            setNewBet(data, true);
+        } else if (data.getAnalysisValueInt() < 0f) {
+            setNewBet(data, false);
+        } else {
+            System.out.println("Can't add bets with analysts value " + data.getAnalysisValueInt());
+        }
+    }
+
+    private void checkBet(Bet b) {
+        if (b.getHomeScore() >= 0 && b.getAwayScore() >= 0
+                && (b.getBet().equals("1") && b.getHomeScore() > b.getAwayScore())
+                || (b.getBet().equals("2") && b.getHomeScore() < b.getAwayScore())) { // Win
+            b.setStatus(Bet.Status.DONE);
+            Float win = (b.getBetOdds() * b.getBetAmount());
+            updateBank(win);
+
+        } else if (b.getHomeScore() >= 0 && b.getAwayScore() >= 0) { // Loss
+            b.setStatus(Bet.Status.LOST);
+        }
+
+        GuiMysql.getInstance().updateBetStatus(b.getId(), b.getStatus());
+        updateStatsPanel(b);
+    }
+
+    @FXML
+    private void CheckBetsAction() {
+
+        activeBetsTable.getItems().stream().filter(p -> p.getStatus() == Bet.Status.OPEN).forEach(this::checkBet);
+
+        activeBetsTable.refresh();
+
+        updateBetAmount();
+
+    }
+
+    private void checkValidBetAmount() {
+        try {
+            float bankValue = Float.parseFloat(bankTextField.getText());
+            float betPercent = Float.parseFloat(bettingPercentTextField.getText());
+
+            final float betAmount = Float.parseFloat(FLOAT_FORMATTER.format(bankValue * (betPercent / 100f)));
+            currentBetAmount = betAmount;
+            gameViewTable.getItems().forEach(i -> {
+                i.setBetAmount(betAmount);
+            });
+            gameViewTable.refresh();
+
+        } catch (NumberFormatException e) {
+// Ignore
+        }
     }
     }
 
 
     private void getActiveBets() {
     private void getActiveBets() {
@@ -211,6 +295,56 @@ public class AnalysisTestController implements Initializable {
         activeBetsTable.refresh();
         activeBetsTable.refresh();
     }
     }
 
 
+    private Integer getAnalyzeValue(SoccerMatch soccerMatch) {
+        int result = 0;
+
+        SoccerMatchAnalysis analysis = new SoccerMatchAnalysis(soccerMatch);
+        League leagueInfo = GuiMysql.getInstance().getLeagueInfo(soccerMatch.getHomeTeam().getTeamLeagueId());
+        if (leagueInfo != null) {
+            int homeWinsCount = analysis.winLossRatio(leagueInfo.getWinLossRatio(), true);
+            int awayWinsCount = analysis.winLossRatio(leagueInfo.getWinLossRatio(), false);
+
+            int homeWinLossRatioCount = analysis.winLossRationHomeAndAway(true,
+                    leagueInfo.getWinLossRatioHomeAndAway());
+            int awayWinLossRatioCount = analysis.winLossRationHomeAndAway(false,
+                    leagueInfo.getWinLossRatioHomeAndAway());
+
+            int homeScoringTotal = analysis.scoringTotal(leagueInfo.getScoringTotal(), true);
+            int awayScoringTotal = analysis.scoringTotal(leagueInfo.getScoringTotal(), false);
+
+            int scoringDiffLastGames = analysis.getScoringDiffLastGames(leagueInfo.getScoringDiffLastGame());
+            int winsCountDiff = homeWinsCount - awayWinsCount;
+            int winLossRatioDiff = homeWinLossRatioCount - awayWinLossRatioCount;
+            int scoringTotalDiff = homeScoringTotal - awayScoringTotal;
+
+            if (scoringDiffLastGames < 0 && winsCountDiff < 0 && winLossRatioDiff < 0 && scoringTotalDiff < 0) {
+                result = (scoringDiffLastGames + winsCountDiff + winLossRatioDiff + scoringTotalDiff) / 4;
+            } else if (scoringDiffLastGames > 0 && winsCountDiff > 0 && winLossRatioDiff > 0
+                    && scoringTotalDiff > 0) {
+                result = (scoringDiffLastGames + winsCountDiff + winLossRatioDiff + scoringTotalDiff) / 4;
+            }
+        }
+        return result;
+    }
+
+    private float getBank() {
+        float bank = 0;
+        try {
+            bank = Float.parseFloat(bankTextField.getText());
+        } catch (NumberFormatException e) {
+
+        }
+
+        return bank;
+    }
+
+    @FXML
+    private void GetMatchesAction() {
+        List<SoccerMatch> matches = GuiMysql.getInstance().getMatches(1, date.getValue().toString(), "ASC", true);
+
+        addMatchesToTable(matches);
+    }
+
     private Float getNewBetValue(SoccerMatch newValue) {
     private Float getNewBetValue(SoccerMatch newValue) {
         float odds = 0f;
         float odds = 0f;
         float currentDebt = 0f;
         float currentDebt = 0f;
@@ -225,9 +359,17 @@ public class AnalysisTestController implements Initializable {
                     .get();
                     .get();
 
 
             Bet tempBet = bet;
             Bet tempBet = bet;
+            int betCoverNumber = 0;
             while (tempBet.getCoveredBetId() > 0) {
             while (tempBet.getCoveredBetId() > 0) {
                 tempBet = GuiMysql.getInstance().getAnalysisBet(tempBet.getCoveredBetId());
                 tempBet = GuiMysql.getInstance().getAnalysisBet(tempBet.getCoveredBetId());
                 currentDebt += tempBet.getBetAmount();
                 currentDebt += tempBet.getBetAmount();
+                betCoverNumber++;
+            }
+
+            bet.setBetCoveredNumber(betCoverNumber);
+
+            if (betCoverNumber > 3 && newValue.getAnalysisValueInt() < 10 && newValue.getAnalysisValueInt() > -10) {
+                return Float.parseFloat(FLOAT_FORMATTER.format(result));
             }
             }
 
 
             currentDebt += bet.getBetAmount();
             currentDebt += bet.getBetAmount();
@@ -248,31 +390,30 @@ public class AnalysisTestController implements Initializable {
         return Float.parseFloat(FLOAT_FORMATTER.format(result));
         return Float.parseFloat(FLOAT_FORMATTER.format(result));
     }
     }
 
 
-    private void checkValidBetAmount() {
-        try {
-            float bankValue = Float.parseFloat(bankTextField.getText());
-            float betPercent = Float.parseFloat(bettingPercentTextField.getText());
-
-            final float betAmount = Float.parseFloat(FLOAT_FORMATTER.format(bankValue * (betPercent / 100f)));
-            currentBetAmount = betAmount;
-            gameViewTable.getItems().forEach(i -> {
-                i.setBetAmount(betAmount);
-            });
-            gameViewTable.refresh();
-
-        } catch (NumberFormatException e) {
-// Ignore
+    private void initializeStatsPanel() {
+        List<Bet> bets = GuiMysql.getInstance().getAnalysisBetStatistics();
+        for (Bet bet : bets) {
+            updateStatsPanel(bet);
         }
         }
     }
     }
 
 
-    private void addToBets(SoccerMatch data) {
-        if (data.getAnalysisValueInt() > 0) {
-            setNewBet(data, true);
-        } else if (data.getAnalysisValueInt() < 0f) {
-            setNewBet(data, false);
-        } else {
-            System.out.println("Can't add bets with analysts value " + data.getAnalysisValueInt());
+    @FXML
+    private void RemoveDoneBetsAction() {
+        List<Bet> doneBets = activeBetsTable.getItems().stream()
+                .filter(p -> p.getStatus() == Status.DONE || p.getStatus() == Status.COVERED)
+                .toList();
+
+        for (Bet bet : doneBets) {
+            if (bet.getStatus().equals(Status.COVERED)) {
+                GuiMysql.getInstance().updateBetStatus(bet.getId(), Status.DONE);
+            }
+            activeBetsTable.getItems().remove(bet);
         }
         }
+
+        activeBetsTable.getItems().sort((b1, b2) -> Float.compare(b2.getBetAmount(), b1.getBetAmount()));
+
+        activeBetsTable.refresh();
+
     }
     }
 
 
     private void setNewBet(SoccerMatch data, boolean isHomeBet) {
     private void setNewBet(SoccerMatch data, boolean isHomeBet) {
@@ -300,71 +441,16 @@ public class AnalysisTestController implements Initializable {
         updateBank(-bet.getBetAmount());
         updateBank(-bet.getBetAmount());
     }
     }
 
 
-    @FXML
-    private void GetMatchesAction() {
-        List<SoccerMatch> matches = GuiMysql.getInstance().getMatches(1, date.getValue().toString(), "ASC", true);
-
-        addMatchesToTable(matches);
-    }
-
-    private void addMatchesToTable(List<SoccerMatch> matches) {
-        ObservableList<SoccerMatch> currentMatches = FXCollections.<SoccerMatch>observableArrayList();
-
-        for (SoccerMatch soccerMatch : matches) {
-
-            int analyzeValue = getAnalyzeValue(soccerMatch);
-            soccerMatch.setAnalysisValue(analyzeValue);
-            if (currentBetAmount > 0) {
-                soccerMatch.setBetAmount(currentBetAmount);
-            }
-
-            currentMatches.add(soccerMatch);
-        }
-
-        gameViewTable.getItems().addAll(currentMatches);
-    }
-
-    private Integer getAnalyzeValue(SoccerMatch soccerMatch) {
-        int result = 0;
-
-        SoccerMatchAnalysis analysis = new SoccerMatchAnalysis(soccerMatch);
-        League leagueInfo = GuiMysql.getInstance().getLeagueInfo(soccerMatch.getHomeTeam().getTeamLeagueId());
-        if (leagueInfo != null) {
-            int homeWinsCount = analysis.winLossRatio(leagueInfo.getWinLossRatio(), true);
-            int awayWindCount = analysis.winLossRatio(leagueInfo.getWinLossRatio(), false);
-
-            int homeWinLossRatioCount = analysis.winLossRationHomeAndAway(true,
-                    leagueInfo.getWinLossRatioHomeAndAway());
-            int awayWinLossRatioCount = analysis.winLossRationHomeAndAway(false,
-                    leagueInfo.getWinLossRatioHomeAndAway());
-
-            int homeScoringTotal = analysis.scoringTotal(leagueInfo.getScoringTotal(), true);
-            int awayScoringTotal = analysis.scoringTotal(leagueInfo.getScoringTotal(), false);
+    private void updateBank(float value) {
+        float bank;
+        try {
+            bank = Float.parseFloat(bankTextField.getText());
+            bank += value;
 
 
-            int scoringDiffLastGames = analysis.getScoringDiffLastGames(leagueInfo.getScoringDiffLastGame());
-            int winsCountDiff = homeWinsCount - awayWindCount;
-            int winLossRatioDiff = homeWinLossRatioCount - awayWinLossRatioCount;
-            int scoringTotalDiff = homeScoringTotal - awayScoringTotal;
+            bankTextField.setText(String.valueOf(bank));
+        } catch (NumberFormatException e) {
 
 
-            if (scoringDiffLastGames < 0 && winsCountDiff < 0 && winLossRatioDiff < 0 && scoringTotalDiff < 0) {
-                result = (scoringDiffLastGames + winsCountDiff + winLossRatioDiff + scoringTotalDiff) / 4;
-            } else if (scoringDiffLastGames > 0 && winsCountDiff > 0 && winLossRatioDiff > 0
-                    && scoringTotalDiff > 0) {
-                result = (scoringDiffLastGames + winsCountDiff + winLossRatioDiff + scoringTotalDiff) / 4;
-            }
         }
         }
-        return result;
-    }
-
-    @FXML
-    private void CheckBetsAction() {
-
-        activeBetsTable.getItems().stream().filter(p -> p.getStatus() == Bet.Status.OPEN).forEach(this::checkBet);
-
-        activeBetsTable.refresh();
-
-        updateBetAmount();
-
     }
     }
 
 
     private void updateBetAmount() {
     private void updateBetAmount() {
@@ -377,25 +463,10 @@ public class AnalysisTestController implements Initializable {
         }
         }
     }
     }
 
 
-    private void checkBet(Bet b) {
-        if ((b.getBet().equals("1") && b.getHomeScore() > b.getAwayScore())
-                || (b.getBet().equals("2") && b.getHomeScore() < b.getAwayScore())) { // Win
-            b.setStatus(Bet.Status.DONE);
-            Float win = (b.getBetOdds() * b.getBetAmount());
-            updateBank(win);
-
-        } else { // Loss
-            b.setStatus(Bet.Status.LOST);
-        }
-
-        GuiMysql.getInstance().updateBetStatus(b.getId(), b.getStatus());
-        updateStatsPanel(b);
-    }
-
     private void updateStatsPanel(Bet b) {
     private void updateStatsPanel(Bet b) {
         String leagueName = b.getMatch().getLeagueName();
         String leagueName = b.getMatch().getLeagueName();
 
 
-        Optional<Map<String, Object>> leagueStatsRow = LeagueBetStatsTable.getItems().stream()
+        Optional<Map<String, Object>> leagueStatsRow = leagueBetStatsTable.getItems().stream()
                 .filter(p -> p.get("statsLeagueName") != null && leagueName.equals(p.get("statsLeagueName")))
                 .filter(p -> p.get("statsLeagueName") != null && leagueName.equals(p.get("statsLeagueName")))
                 .findFirst();
                 .findFirst();
 
 
@@ -428,7 +499,7 @@ public class AnalysisTestController implements Initializable {
                         ((statsHomeWin + statsAwayWin)
                         ((statsHomeWin + statsAwayWin)
                                 / (float) (statsHomeWin + statsHomeLoss + statsAwayWin + statsAwayLoss)) * 100);
                                 / (float) (statsHomeWin + statsHomeLoss + statsAwayWin + statsAwayLoss)) * 100);
             }
             }
-            ObservableList<Map<String, Object>> items = LeagueBetStatsTable.getItems();
+            ObservableList<Map<String, Object>> items = leagueBetStatsTable.getItems();
 
 
             items.add(newItem);
             items.add(newItem);
         } else {
         } else {
@@ -461,51 +532,9 @@ public class AnalysisTestController implements Initializable {
                                 / (float) (statsHomeWin + statsHomeLoss + statsAwayWin + statsAwayLoss)) * 100);
                                 / (float) (statsHomeWin + statsHomeLoss + statsAwayWin + statsAwayLoss)) * 100);
             }
             }
 
 
-            LeagueBetStatsTable.getItems().set(LeagueBetStatsTable.getItems().indexOf(map), map);
+            leagueBetStatsTable.getItems().set(leagueBetStatsTable.getItems().indexOf(map), map);
         }
         }
-        LeagueBetStatsTable.refresh();
-    }
-
-    private void updateBank(float value) {
-        float bank;
-        try {
-            bank = Float.parseFloat(bankTextField.getText());
-            bank += value;
-
-            bankTextField.setText(String.valueOf(bank));
-        } catch (NumberFormatException e) {
-
-        }
-    }
-
-    private float getBank() {
-        float bank = 0;
-        try {
-            bank = Float.parseFloat(bankTextField.getText());
-        } catch (NumberFormatException e) {
-
-        }
-
-        return bank;
-    }
-
-    @FXML
-    private void RemoveDoneBetsAction() {
-        List<Bet> doneBets = activeBetsTable.getItems().stream()
-                .filter(p -> p.getStatus() == Status.DONE || p.getStatus() == Status.COVERED)
-                .toList();
-
-        for (Bet bet : doneBets) {
-            if (bet.getStatus().equals(Status.COVERED)) {
-                GuiMysql.getInstance().updateBetStatus(bet.getId(), Status.DONE);
-            }
-            activeBetsTable.getItems().remove(bet);
-        }
-
-        activeBetsTable.getItems().sort((b1, b2) -> Float.compare(b2.getBetAmount(), b1.getBetAmount()));
-
-        activeBetsTable.refresh();
-
+        leagueBetStatsTable.refresh();
     }
     }
 
 
 }
 }

+ 150 - 139
OddsJavaFx/src/controllers/TestsController.java

@@ -29,6 +29,7 @@ import javafx.scene.layout.Priority;
 import javafx.scene.layout.VBox;
 import javafx.scene.layout.VBox;
 import parser.OddsPortal;
 import parser.OddsPortal;
 import tests.AddedScoringTest;
 import tests.AddedScoringTest;
+import tests.AnalysisBettDrawTester;
 import tests.AnalysisBettTester;
 import tests.AnalysisBettTester;
 import tests.AwayTeamWinTest;
 import tests.AwayTeamWinTest;
 import tests.AwayTests2;
 import tests.AwayTests2;
@@ -125,97 +126,117 @@ public class TestsController implements Initializable {
     }
     }
 
 
     @FXML
     @FXML
-    private void getResults() {
-        countriesList.clear();
-        leaguesList.clear();
-        initCountries();
+    void getLeagueInfo() {
+        final String country = countrySelector.getValue().trim();
+        final String league = leagueSelector.getValue().trim();
+        final OddsPortal op = new OddsPortal();
+        op.getHistoricMatches("soccer", country, league, String.valueOf(LocalDate.now().getYear()));
     }
     }
 
 
     @FXML
     @FXML
-    private void countrySelected(ActionEvent event) {
-        if (countrySelector.getValue() != null && !countrySelector.getValue().equals("Country")) {
-            leagueSelector.setDisable(false);
-            final int countryId = getCountryIdFromSelector();
-            final int sportId = getSoccerId();
+    private void addedScoreTestAction() {
+        final AddedScoringTest test = new AddedScoringTest();
 
 
-            leaguesList = GuiMysql.getInstance().getLeaguesByDate(sportId, countryId, date.getValue().toString());
+        test.setup("", Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), Float.valueOf(getBetMargin()),
+                Integer.valueOf(getLookback()),
+                1, getCountryIdFromSelector(), getLeagueIdFromSelector());
 
 
-            leagues.clear();
-            leagues.add("League");
-            leaguesList.forEach(l -> leagues.add(l.getValue()));
-        }
+        test.runTest();
     }
     }
 
 
-    private Integer getCountryIdFromSelector() {
-        Optional<SimpleEntry<Integer, String>> o = countriesList.stream()
-                .filter(p -> p.getValue().equals(countrySelector.getValue())).findFirst();
-        return o.isPresent() ? o.get().getKey() : null;
+    @FXML
+    private void analysisDrawTests() {
+        final TestClass test = new AnalysisBettDrawTester();
+        test.setup(date.getValue().toString(), Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), -1.0f,
+                -1, GuiMysql.getInstance().getSportId("soccer"),
+                getCountryIdFromSelector(), getLeagueIdFromSelector());
+
+        test.runTest();
     }
     }
 
 
-    private Integer getLeagueIdFromSelector() {
-        Optional<SimpleEntry<Integer, String>> o = leaguesList.stream()
-                .filter(p -> p.getValue().equals(leagueSelector.getValue())).findFirst();
-        return o.isPresent() ? o.get().getKey() : null;
+    @FXML
+    private void analysisTets() {
+        final TestClass test = new AnalysisBettTester();
+
+        test.setup(date.getValue().toString(), Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), -1.0f,
+                -1, GuiMysql.getInstance().getSportId("soccer"),
+                getCountryIdFromSelector(), getLeagueIdFromSelector());
+
+        test.runTest();
     }
     }
 
 
-    private void initCountries() {
-        countrySelector.setDisable(false);
-        final int sportId = getSoccerId();
+    @FXML
+    private void awayTeamTestAction() {
+        final AwayTeamWinTest test = new AwayTeamWinTest();
 
 
-        countriesList.clear();
-        countriesList.addAll(GuiMysql.getInstance().getCountriesBySport(sportId, date.getValue().toString()));
+        test.setup("", Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), Float.valueOf(getBetMargin()),
+                Integer.valueOf(getLookback()),
+                1, getCountryIdFromSelector(), getLeagueIdFromSelector());
 
 
-        countriesList.forEach(c -> countries.add(c.getValue()));
+        test.runTest();
     }
     }
 
 
-    private int getSoccerId() {
-        if (mSportId <= 0) {
-            mSportId = GuiMysql.getInstance().getSportId(MainController.SPORT);
-        }
+    @FXML
+    private void awayTestAction() {
+        final AwayTests2 test = new AwayTests2();
 
 
-        return mSportId;
+        test.setup("", Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), Float.valueOf(getBetMargin()),
+                Integer.valueOf(getLookback()),
+                1, getCountryIdFromSelector(), getLeagueIdFromSelector());
+
+        test.runTest();
     }
     }
 
 
     @FXML
     @FXML
-    private void leagueSelected(ActionEvent event) {
+    private void calcBestResultsAction() {
+        final LastResultsTest test = new LastResultsTest();
 
 
-        if (GuiMysql.getInstance().getParsingStarted(getCountryIdFromSelector(), getLeagueIdFromSelector())) {
-            getLeagueInfoButton.setDisable(true);
-            getMoreLeagueInfoButton.setDisable(false);
-        } else {
-            getLeagueInfoButton.setDisable(false);
-            getMoreLeagueInfoButton.setDisable(true);
+        calcBestValues.setDisable(true);
+        final String buttonText = calcBestValues.getText();
+        Platform.runLater(() -> {
+            calcBestValues.setText("RUNNING...");
+            test.calcBestResults(mSportId, getCountryIdFromSelector(), getLeagueIdFromSelector());
+            calcBestValues.setDisable(false);
+
+            calcBestValues.setText(buttonText);
+        });
+    }
+
+    @FXML
+    private void countrySelected(ActionEvent event) {
+        if (countrySelector.getValue() != null && !countrySelector.getValue().equals("Country")) {
+            leagueSelector.setDisable(false);
+            final int countryId = getCountryIdFromSelector();
+            final int sportId = getSoccerId();
+
+            leaguesList = GuiMysql.getInstance().getLeaguesByDate(sportId, countryId, date.getValue().toString());
+
+            leagues.clear();
+            leagues.add("League");
+            leaguesList.forEach(l -> leagues.add(l.getValue()));
         }
         }
-        testSettingsPanel.setVisible(true);
     }
     }
 
 
     @FXML
     @FXML
-    private void runTestAction() {
+    private void drawTestAction() {
+        final DrawTests2 test = new DrawTests2();
 
 
-        final String betLevel = getBetLevel();
-        final String betM = getBetMargin();
-        final String startBank = getStartingBank();
-        final String lookBackVal = getLookback();
+        test.setup("", Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), Float.valueOf(getBetMargin()),
+                Integer.valueOf(getLookback()),
+                1, getCountryIdFromSelector(), getLeagueIdFromSelector());
 
 
-        final TestClass test = new LastResultsTest();
-        test.setup(date.getValue().toString(), Float.valueOf(startBank), Float.valueOf(betLevel), Float.valueOf(betM),
-                Integer.valueOf(lookBackVal),
-                mSportId, getCountryIdFromSelector(), getLeagueIdFromSelector());
         test.runTest();
         test.runTest();
     }
     }
 
 
-    private String getLookback() {
-        return Strings.isNullOrEmpty(lookBack.getText()) ? lookBack.getPromptText() : lookBack.getText();
-    }
+    @FXML
+    private void fibonacciDrawTestAction() {
+        final TestClass test = new FibonacciDrawTest();
 
 
-    private String getStartingBank() {
-        return Strings.isNullOrEmpty(startingBank.getText()) ? startingBank.getPromptText() : startingBank.getText();
-    }
+        test.setup(date.getValue().toString(), Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), -1.0f,
+                -1, GuiMysql.getInstance().getSportId("soccer"),
+                getCountryIdFromSelector(), getLeagueIdFromSelector());
 
 
-    private String getBetMargin() {
-        String betM = Strings.isNullOrEmpty(betMargin.getText()) ? betMargin.getPromptText() : betMargin.getText();
-        betM = betM.replace("%", "").trim();
-        return betM;
+        test.runTest();
     }
     }
 
 
     private String getBetLevel() {
     private String getBetLevel() {
@@ -225,27 +246,26 @@ public class TestsController implements Initializable {
         return betLevel;
         return betLevel;
     }
     }
 
 
-    @FXML
-    private void calcBestResultsAction() {
-        final LastResultsTest test = new LastResultsTest();
+    private String getBetMargin() {
+        String betM = Strings.isNullOrEmpty(betMargin.getText()) ? betMargin.getPromptText() : betMargin.getText();
+        betM = betM.replace("%", "").trim();
+        return betM;
+    }
 
 
-        calcBestValues.setDisable(true);
-        final String buttonText = calcBestValues.getText();
-        Platform.runLater(() -> {
-            calcBestValues.setText("RUNNING...");
-            test.calcBestResults(mSportId, getCountryIdFromSelector(), getLeagueIdFromSelector());
-            calcBestValues.setDisable(false);
+    private Integer getCountryIdFromSelector() {
+        Optional<SimpleEntry<Integer, String>> o = countriesList.stream()
+                .filter(p -> p.getValue().equals(countrySelector.getValue())).findFirst();
+        return o.isPresent() ? o.get().getKey() : null;
+    }
 
 
-            calcBestValues.setText(buttonText);
-        });
+    private Integer getLeagueIdFromSelector() {
+        Optional<SimpleEntry<Integer, String>> o = leaguesList.stream()
+                .filter(p -> p.getValue().equals(leagueSelector.getValue())).findFirst();
+        return o.isPresent() ? o.get().getKey() : null;
     }
     }
 
 
-    @FXML
-    void getLeagueInfo() {
-        final String country = countrySelector.getValue().trim();
-        final String league = leagueSelector.getValue().trim();
-        final OddsPortal op = new OddsPortal();
-        op.getHistoricMatches("soccer", country, league, String.valueOf(LocalDate.now().getYear()));
+    private String getLookback() {
+        return Strings.isNullOrEmpty(lookBack.getText()) ? lookBack.getPromptText() : lookBack.getText();
     }
     }
 
 
     @FXML
     @FXML
@@ -277,40 +297,31 @@ public class TestsController implements Initializable {
     }
     }
 
 
     @FXML
     @FXML
-    private void topLeaguesTestAction() {
-        final PrioCountriesAll prioCountriesAll = new PrioCountriesAll();
-        prioCountriesAll.runTest();
+    private void getResults() {
+        countriesList.clear();
+        leaguesList.clear();
+        initCountries();
     }
     }
 
 
-    @FXML
-    private void homeTestAction() {
-        final HomeTests2 test = new HomeTests2();
-
-        test.setup("", Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), Float.valueOf(getBetMargin()),
-                Integer.valueOf(getLookback()),
-                1, getCountryIdFromSelector(), getLeagueIdFromSelector());
+    private int getSoccerId() {
+        if (mSportId <= 0) {
+            mSportId = GuiMysql.getInstance().getSportId(MainController.SPORT);
+        }
 
 
-        test.runTest();
+        return mSportId;
     }
     }
 
 
-    @FXML
-    private void drawTestAction() {
-        final DrawTests2 test = new DrawTests2();
-
-        test.setup("", Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), Float.valueOf(getBetMargin()),
-                Integer.valueOf(getLookback()),
-                1, getCountryIdFromSelector(), getLeagueIdFromSelector());
-
-        test.runTest();
+    private String getStartingBank() {
+        return Strings.isNullOrEmpty(startingBank.getText()) ? startingBank.getPromptText() : startingBank.getText();
     }
     }
 
 
     @FXML
     @FXML
-    private void awayTestAction() {
-        final AwayTests2 test = new AwayTests2();
+    private void goalDiffTest() {
+        final TestClass test = new BetOnDifference();
 
 
-        test.setup("", Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), Float.valueOf(getBetMargin()),
-                Integer.valueOf(getLookback()),
-                1, getCountryIdFromSelector(), getLeagueIdFromSelector());
+        test.setup(date.getValue().toString(), Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), -1.0f,
+                -1, GuiMysql.getInstance().getSportId("soccer"),
+                getCountryIdFromSelector(), getLeagueIdFromSelector());
 
 
         test.runTest();
         test.runTest();
     }
     }
@@ -338,8 +349,8 @@ public class TestsController implements Initializable {
     }
     }
 
 
     @FXML
     @FXML
-    private void awayTeamTestAction() {
-        final AwayTeamWinTest test = new AwayTeamWinTest();
+    private void homeTestAction() {
+        final HomeTests2 test = new HomeTests2();
 
 
         test.setup("", Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), Float.valueOf(getBetMargin()),
         test.setup("", Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), Float.valueOf(getBetMargin()),
                 Integer.valueOf(getLookback()),
                 Integer.valueOf(getLookback()),
@@ -348,15 +359,27 @@ public class TestsController implements Initializable {
         test.runTest();
         test.runTest();
     }
     }
 
 
-    @FXML
-    private void addedScoreTestAction() {
-        final AddedScoringTest test = new AddedScoringTest();
+    private void initCountries() {
+        countrySelector.setDisable(false);
+        final int sportId = getSoccerId();
 
 
-        test.setup("", Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), Float.valueOf(getBetMargin()),
-                Integer.valueOf(getLookback()),
-                1, getCountryIdFromSelector(), getLeagueIdFromSelector());
+        countriesList.clear();
+        countriesList.addAll(GuiMysql.getInstance().getCountriesBySport(sportId, date.getValue().toString()));
 
 
-        test.runTest();
+        countriesList.forEach(c -> countries.add(c.getValue()));
+    }
+
+    @FXML
+    private void leagueSelected(ActionEvent event) {
+
+        if (GuiMysql.getInstance().getParsingStarted(getCountryIdFromSelector(), getLeagueIdFromSelector())) {
+            getLeagueInfoButton.setDisable(true);
+            getMoreLeagueInfoButton.setDisable(false);
+        } else {
+            getLeagueInfoButton.setDisable(false);
+            getMoreLeagueInfoButton.setDisable(true);
+        }
+        testSettingsPanel.setVisible(true);
     }
     }
 
 
     @FXML
     @FXML
@@ -371,15 +394,8 @@ public class TestsController implements Initializable {
     }
     }
 
 
     @FXML
     @FXML
-    private void standingsTest() {
-        final TestClass test = new LeagueTablePositionTest();
-
-        test.runTest();
-    }
-
-    @FXML
-    private void fibonacciDrawTestAction() {
-        final TestClass test = new FibonacciDrawTest();
+    private void relevanceTest() {
+        final TestClass test = new RelevanceTest();
 
 
         test.setup(date.getValue().toString(), Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), -1.0f,
         test.setup(date.getValue().toString(), Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), -1.0f,
                 -1, GuiMysql.getInstance().getSportId("soccer"),
                 -1, GuiMysql.getInstance().getSportId("soccer"),
@@ -389,35 +405,30 @@ public class TestsController implements Initializable {
     }
     }
 
 
     @FXML
     @FXML
-    private void goalDiffTest() {
-        final TestClass test = new BetOnDifference();
+    private void runTestAction() {
 
 
-        test.setup(date.getValue().toString(), Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), -1.0f,
-                -1, GuiMysql.getInstance().getSportId("soccer"),
-                getCountryIdFromSelector(), getLeagueIdFromSelector());
+        final String betLevel = getBetLevel();
+        final String betM = getBetMargin();
+        final String startBank = getStartingBank();
+        final String lookBackVal = getLookback();
 
 
+        final TestClass test = new LastResultsTest();
+        test.setup(date.getValue().toString(), Float.valueOf(startBank), Float.valueOf(betLevel), Float.valueOf(betM),
+                Integer.valueOf(lookBackVal),
+                mSportId, getCountryIdFromSelector(), getLeagueIdFromSelector());
         test.runTest();
         test.runTest();
     }
     }
 
 
     @FXML
     @FXML
-    private void relevanceTest() {
-        final TestClass test = new RelevanceTest();
-
-        test.setup(date.getValue().toString(), Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), -1.0f,
-                -1, GuiMysql.getInstance().getSportId("soccer"),
-                getCountryIdFromSelector(), getLeagueIdFromSelector());
+    private void standingsTest() {
+        final TestClass test = new LeagueTablePositionTest();
 
 
         test.runTest();
         test.runTest();
     }
     }
 
 
     @FXML
     @FXML
-    private void analysisTets() {
-        final TestClass test = new AnalysisBettTester();
-
-        test.setup(date.getValue().toString(), Float.valueOf(getStartingBank()), Float.valueOf(getBetLevel()), -1.0f,
-                -1, GuiMysql.getInstance().getSportId("soccer"),
-                getCountryIdFromSelector(), getLeagueIdFromSelector());
-
-        test.runTest();
+    private void topLeaguesTestAction() {
+        final PrioCountriesAll prioCountriesAll = new PrioCountriesAll();
+        prioCountriesAll.runTest();
     }
     }
 }
 }

+ 731 - 684
OddsJavaFx/src/data/GuiMysql.java

@@ -37,6 +37,15 @@ import objects.bets.Bet.Status;
 
 
 public class GuiMysql extends Mysql {
 public class GuiMysql extends Mysql {
 
 
+    private static final String SEASON = "season";
+    private static final String AWAY_SCORE = "awayScore";
+    private static final String HOME_SCORE = "homeScore";
+    private static final String COUNTRY_NAME = "countryName";
+    private static final String DRAWS = "draws";
+    private static final String DATE_FORMAT = "yyyy-MM-dd";
+    private static final String AWAY_TEAM_ID = "awayTeamId";
+    private static final String HOME_TEAM_ID = "homeTeamId";
+    private static final String LEAGUE_NAME = "leagueName";
     private static final BigDecimal INCREMENT = BigDecimal.valueOf(0.2);
     private static final BigDecimal INCREMENT = BigDecimal.valueOf(0.2);
     private static final GuiMysql instance = new GuiMysql();
     private static final GuiMysql instance = new GuiMysql();
     private final Connection conn;
     private final Connection conn;
@@ -50,127 +59,151 @@ public class GuiMysql extends Mysql {
         return instance;
         return instance;
     }
     }
 
 
-    public List<SimpleEntry<Integer, String>> getSports() {
+    public int addAnalysisBet(Bet bet) {
+        int newId = -1;
+        String sql = "INSERT INTO AnalysisBetTable (matchId, bet, betAmount, betOdds, status) VALUES (?,?,?,?,?)";
 
 
-        final ArrayList<AbstractMap.SimpleEntry<Integer, String>> sports = Lists.newArrayList();
-        final String sql = "SELECT id, name FROM Sport";
-        try (PreparedStatement stat = conn.prepareStatement(sql)) {
+        try (PreparedStatement stat = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
+            stat.setInt(1, bet.getMatch().getMatchId());
+            stat.setString(2, bet.getBet());
+            stat.setFloat(3, bet.getBetAmount());
+            stat.setFloat(4, bet.getBetOdds());
+            stat.setString(5, bet.getStatus().name());
 
 
-            final ResultSet rs = stat.executeQuery();
+            stat.execute();
 
 
-            while (rs.next()) {
-                final SimpleEntry<Integer, String> entry = new SimpleEntry<>(rs.getInt(Constants.ID),
-                        rs.getString("name"));
-                sports.add(entry);
+            ResultSet generatedKeys = stat.getGeneratedKeys();
+
+            while (generatedKeys.next()) {
+                newId = generatedKeys.getInt(1);
             }
             }
-        } catch (final SQLException e) {
+
+        } catch (SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
 
 
-        return sports;
+        return newId;
     }
     }
 
 
-    public List<SimpleEntry<Integer, String>> getCountries() {
+    public void addBetSeries(BetDTO bet) {
+        String sql = "INSERT INTO ActiveBets (series, gameId, betType, bet, odds, done) VALUES (?, ?, ?, ?, ?, ?)";
 
 
-        final ArrayList<AbstractMap.SimpleEntry<Integer, String>> countries = Lists.newArrayList();
-        final String sql = "SELECT id, name FROM Country";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
+            stat.setInt(1, bet.getBetSeries());
+            stat.setInt(2, getGameId(bet.getHomeTeam(), bet.getAwayTeam(), bet.getGameDate(), bet.getCountryId(),
+                    bet.getLeagueId()));
+            stat.setString(3, bet.getBetType());
+            stat.setFloat(4, bet.getBet());
+            stat.setFloat(5, bet.getOdds());
+            stat.setBoolean(6, false);
 
 
-            final ResultSet rs = stat.executeQuery();
-
-            while (rs.next()) {
-                final SimpleEntry<Integer, String> entry = new SimpleEntry<>(rs.getInt(Constants.ID),
-                        rs.getString("name"));
-                countries.add(entry);
-            }
-        } catch (final SQLException e) {
+            stat.execute();
+        } catch (SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-        return countries;
     }
     }
 
 
-    public List<SimpleEntry<Integer, String>> getLeagues(int sportId, int countryId) {
+    public Bet getAnalysisBet(int betId) {
+        Bet result = null;
+        String sql = "SELECT * FROM AnalysisBetTable abt "
+                + "INNER JOIN SoccerResults sr ON abt.matchId = sr.id "
+                + "WHERE abt.id = ?";
 
 
-        final ArrayList<AbstractMap.SimpleEntry<Integer, String>> leagues = Lists.newArrayList();
-        final String sql = "SELECT id, name FROM League WHERE sportId = ? AND countryId = ? ORDER BY name ASC";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setInt(1, sportId);
-            stat.setInt(2, countryId);
+            stat.setInt(1, betId);
 
 
-            final ResultSet rs = stat.executeQuery();
+            ResultSet rs = stat.executeQuery();
 
 
             while (rs.next()) {
             while (rs.next()) {
-                final SimpleEntry<Integer, String> entry = new SimpleEntry<>(rs.getInt(Constants.ID),
-                        rs.getString("name"));
-                leagues.add(entry);
+                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));
+
+                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"));
             }
             }
-        } catch (final SQLException e) {
+
+        } catch (SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-        return leagues;
-    }
 
 
-    public List<SoccerMatch> getUpcomingMatches(String sportResultTable) {
-        final ArrayList<SoccerMatch> matches = Lists.newArrayList();
-        final String dateSql;
-        dateSql = " AND DATE(gameDate) >= DATE(now())";
+        return result;
+    }
 
 
-        final String sql = "SELECT res.id, homeTeamId, awayTeamId, homeScore, awayScore, overtime, odds1, oddsX, odds2, gameDate, season, res.leagueId, res.countryId, "
-                + "hTeam.name as homeTeamName, aTeam.name as awayTeamName, " + "league.name as leagueName, "
-                + "country.name as countryName, "
-                + "country.prio as prio " + "FROM " + sportResultTable + " as res "
-                + "Join Team as hTeam ON res.homeTeamId = hTeam.id "
-                + "Join Team as aTeam ON res.awayTeamId = aTeam.id "
-                + "Join League as league ON res.leagueId = league.id "
-                + "Join Country as country ON res.countryId = country.id " + "WHERE homeScore = -1 " + dateSql
-                + "AND league.name NOT LIKE '%cup%' AND league.name NOT LIKE '%group%' AND league.prio = 1 "
-                + "ORDER BY country.prio DESC, country.name ASC";
+    public List<Bet> getAnalysisBets() {
+        List<Bet> result = new ArrayList<>();
+        String sql = "SELECT * FROM AnalysisBetTable abt "
+                + "INNER JOIN SoccerResults sr ON abt.matchId = sr.id "
+                + "WHERE status IN ('LOST', 'OPEN', 'COVERED')";
 
 
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
+            ResultSet rs = stat.executeQuery();
 
 
-            final ResultSet rs = stat.executeQuery();
             while (rs.next()) {
             while (rs.next()) {
-                final SoccerMatch sm = new SoccerMatch();
-                final Team homeTeam = new Team();
-                final Team awayTeam = new Team();
 
 
-                homeTeam.setTeamId(rs.getInt(Constants.HOME_TEAM_ID));
-                awayTeam.setTeamId(rs.getInt(Constants.AWAY_TEAM_ID));
-                homeTeam.setTeamName(rs.getString(Constants.HOME_TEAM_NAME));
-                awayTeam.setTeamName(rs.getString(Constants.AWAY_TEAM_NAME));
-                homeTeam.setTeamLeagueId(rs.getInt(Constants.LEAGUE_ID));
-                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.setCountryName(rs.getString(Constants.COUNTRY_NAME));
-                awayTeam.setCountryName(rs.getString(Constants.COUNTRY_NAME));
+                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));
 
 
-                sm.setAwayScore(rs.getInt(Constants.AWAY_SCORE));
-                sm.setHomeScore(rs.getInt(Constants.HOME_SCORE));
-                sm.setHomeTeam(homeTeam);
-                sm.setAwayTeam(awayTeam);
-                sm.setMatchId(rs.getInt(Constants.ID));
-                sm.setOdds1(rs.getFloat(Constants.ODDS_1));
-                sm.setOddsX(rs.getFloat(Constants.ODDS_X));
-                sm.setOdds2(rs.getFloat(Constants.ODDS_2));
-                sm.setGameDate(LocalDateTime.parse(rs.getString(Constants.GAME_DATE)));
-                sm.setCountryPrio(rs.getBoolean("prio"));
+                match.setLeagueName(homeTeam.getTeamLeague());
+                match.setCountryName(homeTeam.getCountryName());
 
 
-                matches.add(sm);
+                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")));
             }
             }
 
 
-        } catch (final SQLException e) {
+        } catch (SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
+        return result;
+    }
 
 
-        return matches;
+    public List<Bet> getAnalysisBetStatistics() {
+        List<Bet> result = new ArrayList<>();
+
+        String sql = "SELECT sr.id as soccerMatchId, ht.id as homeTeamId, awt.id as awayTeamId, sr.odds1, sr.oddsX, sr.odds2, "
+                + "sr.homeScore, sr.awayScore, sr.gameDate, sr.season, l.name as leagueName, abt.id as betId, abt.bet, abt.betAmount, abt.betOdds "
+                + "FROM AnalysisBetTable abt "
+                + "INNER JOIN SoccerResults sr ON abt.matchId = sr.id "
+                + "INNER JOIN Team ht ON ht.id = sr.homeTeamId "
+                + "INNER JOIN Team awt ON awt.id = sr.awayTeamId "
+                + "INNER JOIN League l ON l.id = sr.leagueId "
+                + "WHERE abt.status != 'OPEN'";
+
+        try (PreparedStatement stat = getConnection().prepareStatement(sql)) {
+            ResultSet rs = stat.executeQuery();
+
+            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("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));
+                match.setLeagueName(rs.getString(LEAGUE_NAME));
+
+                Bet bet = new Bet(rs.getInt("betId"), match, rs.getString("bet"), rs.getFloat("betAmount"),
+                        rs.getFloat("betOdds"));
+
+                result.add(bet);
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+        return result;
     }
     }
 
 
-    public List<Float> getAvgHomeScore(int teamId) {
+    public List<Float> getAvgAwayScore(int teamId) {
         final ArrayList<Float> returnValue = Lists.newArrayList();
         final ArrayList<Float> returnValue = Lists.newArrayList();
-        final String sql = "SELECT AVG(homeScore) as avgScored, AVG(awayScore) as avgConceded FROM SoccerResults WHERE homeScore != -1 AND homeTeamId = ?";
+        final String sql = "SELECT AVG(homeScore) as avgConceded, AVG(awayScore) as avgScored FROM SoccerResults WHERE awayScore != -1 AND awayTeamId = ?";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
             stat.setInt(1, teamId);
             stat.setInt(1, teamId);
 
 
@@ -188,16 +221,15 @@ public class GuiMysql extends Mysql {
         return returnValue;
         return returnValue;
     }
     }
 
 
-    public List<Float> getAvgHomeScoreThisSeason(int teamId, int countryId, int leagueId) {
-        return getAvgHomeScoreThisSeason(teamId, countryId, leagueId, "");
+    public List<Float> getAvgAwayScoreThisSeason(int teamId, int countryId, int leagueId) {
+        return getAvgAwayScoreThisSeason(teamId, countryId, leagueId, "");
     }
     }
 
 
-    public List<Float> getAvgHomeScoreThisSeason(int teamId, int countryId, int leagueId, String gameDate) {
+    public List<Float> getAvgAwayScoreThisSeason(int teamId, int countryId, int leagueId, String gameDate) {
         final ArrayList<Float> returnValue = Lists.newArrayList();
         final ArrayList<Float> returnValue = Lists.newArrayList();
-        final String sql = "SELECT AVG(homeScore) as avgScoredSeason, AVG(awayScore) as avgConcededSeason FROM SoccerResults WHERE homeScore != -1 AND homeTeamId = ? AND season = ? AND DATE(gameDate) < ? ORDER BY gameDate ASC";
+        final String sql = "SELECT AVG(homeScore) as avgConcededSeason, AVG(awayScore) as avgScoredSeason FROM SoccerResults WHERE awayScore != -1 AND awayTeamId = ? AND season = ? AND DATE(gameDate) < ? ORDER BY gameDate ASC";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
             stat.setInt(1, teamId);
             stat.setInt(1, teamId);
-
             if (Strings.isNullOrEmpty(gameDate)
             if (Strings.isNullOrEmpty(gameDate)
                     || getSeasonFromDate(countryId, leagueId, gameDate).equals(getLastSeason(countryId, leagueId))) {
                     || getSeasonFromDate(countryId, leagueId, gameDate).equals(getLastSeason(countryId, leagueId))) {
                 stat.setString(2, getLastSeason(countryId, leagueId));
                 stat.setString(2, getLastSeason(countryId, leagueId));
@@ -206,7 +238,7 @@ public class GuiMysql extends Mysql {
                 stat.setString(2, seasonFromDate);
                 stat.setString(2, seasonFromDate);
             }
             }
             if (Strings.isNullOrEmpty(gameDate)) {
             if (Strings.isNullOrEmpty(gameDate)) {
-                stat.setString(3, new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
+                stat.setString(3, new SimpleDateFormat(DATE_FORMAT).format(new Date()));
             } else {
             } else {
                 stat.setString(3, gameDate);
                 stat.setString(3, gameDate);
             }
             }
@@ -225,31 +257,9 @@ public class GuiMysql extends Mysql {
         return returnValue;
         return returnValue;
     }
     }
 
 
-    public String getSeasonFromDate(int countryId, int leagueId, String gameDate) {
-        String sql = "SELECT season FROM SoccerResults WHERE DATE(gameDate) = ? AND countryId = ? AND leagueId = ? LIMIT 1";
-        String returnValue = "";
-        try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            if (Strings.isNullOrEmpty(gameDate)) {
-                stat.setString(1, new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
-            } else {
-                stat.setString(1, gameDate);
-            }
-            stat.setInt(2, countryId);
-            stat.setInt(3, leagueId);
-
-            ResultSet rs = stat.executeQuery();
-            while (rs.next()) {
-                returnValue = rs.getString("season");
-            }
-        } catch (SQLException e) {
-            e.printStackTrace();
-        }
-        return returnValue;
-    }
-
-    public List<Float> getAvgAwayScore(int teamId) {
+    public List<Float> getAvgHomeScore(int teamId) {
         final ArrayList<Float> returnValue = Lists.newArrayList();
         final ArrayList<Float> returnValue = Lists.newArrayList();
-        final String sql = "SELECT AVG(homeScore) as avgConceded, AVG(awayScore) as avgScored FROM SoccerResults WHERE awayScore != -1 AND awayTeamId = ?";
+        final String sql = "SELECT AVG(homeScore) as avgScored, AVG(awayScore) as avgConceded FROM SoccerResults WHERE homeScore != -1 AND homeTeamId = ?";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
             stat.setInt(1, teamId);
             stat.setInt(1, teamId);
 
 
@@ -267,15 +277,16 @@ public class GuiMysql extends Mysql {
         return returnValue;
         return returnValue;
     }
     }
 
 
-    public List<Float> getAvgAwayScoreThisSeason(int teamId, int countryId, int leagueId) {
-        return getAvgAwayScoreThisSeason(teamId, countryId, leagueId, "");
+    public List<Float> getAvgHomeScoreThisSeason(int teamId, int countryId, int leagueId) {
+        return getAvgHomeScoreThisSeason(teamId, countryId, leagueId, "");
     }
     }
 
 
-    public List<Float> getAvgAwayScoreThisSeason(int teamId, int countryId, int leagueId, String gameDate) {
+    public List<Float> getAvgHomeScoreThisSeason(int teamId, int countryId, int leagueId, String gameDate) {
         final ArrayList<Float> returnValue = Lists.newArrayList();
         final ArrayList<Float> returnValue = Lists.newArrayList();
-        final String sql = "SELECT AVG(homeScore) as avgConcededSeason, AVG(awayScore) as avgScoredSeason FROM SoccerResults WHERE awayScore != -1 AND awayTeamId = ? AND season = ? AND DATE(gameDate) < ? ORDER BY gameDate ASC";
+        final String sql = "SELECT AVG(homeScore) as avgScoredSeason, AVG(awayScore) as avgConcededSeason FROM SoccerResults WHERE homeScore != -1 AND homeTeamId = ? AND season = ? AND DATE(gameDate) < ? ORDER BY gameDate ASC";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
             stat.setInt(1, teamId);
             stat.setInt(1, teamId);
+
             if (Strings.isNullOrEmpty(gameDate)
             if (Strings.isNullOrEmpty(gameDate)
                     || getSeasonFromDate(countryId, leagueId, gameDate).equals(getLastSeason(countryId, leagueId))) {
                     || getSeasonFromDate(countryId, leagueId, gameDate).equals(getLastSeason(countryId, leagueId))) {
                 stat.setString(2, getLastSeason(countryId, leagueId));
                 stat.setString(2, getLastSeason(countryId, leagueId));
@@ -284,7 +295,7 @@ public class GuiMysql extends Mysql {
                 stat.setString(2, seasonFromDate);
                 stat.setString(2, seasonFromDate);
             }
             }
             if (Strings.isNullOrEmpty(gameDate)) {
             if (Strings.isNullOrEmpty(gameDate)) {
-                stat.setString(3, new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
+                stat.setString(3, new SimpleDateFormat(DATE_FORMAT).format(new Date()));
             } else {
             } else {
                 stat.setString(3, gameDate);
                 stat.setString(3, gameDate);
             }
             }
@@ -303,257 +314,171 @@ public class GuiMysql extends Mysql {
         return returnValue;
         return returnValue;
     }
     }
 
 
-    public List<Float> getLeagueAvarages(int leagueId, int countryId, String gameDate) {
-        final ArrayList<Float> returnValue = Lists.newArrayList();
-        final String sql = "SELECT AVG(homeScore) avgHomeScore, AVG(awayScore) as avgAwayScore"
-                + " FROM SoccerResults WHERE leagueId = ? AND countryId = ? AND DATE(gameDate) < DATE(?)";
+    public String getBetBaseAmount() {
+        String sql = "SELECT value FROM Settings WHERE name = ?";
+        String result = "";
+        try (PreparedStatement stat = conn.prepareStatement(sql)) {
+            stat.setString(1, "BetBaseAmount");
 
 
-        try (PreparedStatement stat = conn.prepareStatement(sql);) {
-            stat.setInt(1, leagueId);
-            stat.setInt(2, countryId);
-            stat.setString(3, gameDate);
+            ResultSet rs = stat.executeQuery();
 
 
-            final ResultSet rs = stat.executeQuery();
             while (rs.next()) {
             while (rs.next()) {
-                returnValue.add(rs.getFloat("avgHomeScore"));
-                returnValue.add(rs.getFloat("avgAwayScore"));
+                result = rs.getString("value");
             }
             }
-
-        } catch (final SQLException e) {
+        } catch (SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
 
 
-        return returnValue;
+        return result;
     }
     }
 
 
-    public Map<Integer, Integer> getGoalAvgThisSeason(int leagueId, int countryId) {
-        Map<Integer, Integer> returnValue = new HashMap<>();
-        final String goalsSql = "SELECT (homeScore + awayScore) as totalGoals, count(*) as count FROM SoccerResults  WHERE leagueId = ? AND countryId = ? AND season = ? GROUP BY totalGoals ORDER BY totalGoals asc";
-        try (PreparedStatement goalStmt = conn.prepareStatement(goalsSql)) {
-            goalStmt.setInt(1, leagueId);
-            goalStmt.setInt(2, countryId);
-            goalStmt.setString(3, getLastSeason(countryId, leagueId));
-
-            final ResultSet goalRs = goalStmt.executeQuery();
+    public List<BetDTO> getBetSeries(boolean includeInactive) {
+        List<BetDTO> result = new ArrayList<>();
+        String sql = "SELECT ab.*, sr.gameDate as gameDate, sr.id as gameId, sr.homeScore as homeScore, sr.awayScore as awayScore, "
+                + "ht.name as homeTeam, aw.name as awayTeam " + "FROM ActiveBets ab "
+                + "INNER JOIN SoccerResults sr ON ab.gameId = sr.id "
+                + "INNER JOIN Team ht ON sr.homeTeamId = ht.id " + "INNER JOIN Team aw ON sr.awayTeamId = aw.id "
+                + "WHERE done = ? ORDER BY series ASC, sr.gameDate DESC";
 
 
-            while (goalRs.next()) {
-                int tg = goalRs.getInt("totalGoals");
-                if (tg < 0) {
-                    continue;
-                }
-                int numGoals = goalRs.getInt("count");
+        try (PreparedStatement stat = conn.prepareStatement(sql)) {
+            stat.setBoolean(1, includeInactive);
 
 
-                returnValue.put(tg, numGoals);
-            }
-        } catch (SQLException e) {
-            e.printStackTrace();
-        }
-        return returnValue;
-    }
+            ResultSet rs = stat.executeQuery();
 
 
-    public List<OverUnder> getStatsOverUnder(int leagueId) {
-        return getStatsOverUnder(leagueId, "");
+            while (rs.next()) {
+                BetDTO dto = new BetDTO();
+                dto.setHomeTeam(rs.getString("homeTeam"));
+                dto.setAwayTeam(rs.getString("awayTeam"));
+                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"));
+                result.add(dto);
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+
+        return result;
     }
     }
 
 
-    private List<String> getAllSeasons(int leagueId) {
-        List<String> returnValue = new ArrayList<String>();
-        String sql = "SELECT distinct(season) FROM SoccerResults WHERE leagueId = ?";
+    public int getBetSeriesEndNumber() {
+        int result = -1;
+        String sql = "SELECT MAX(series) FROM ActiveBets";
 
 
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setInt(1, leagueId);
-
             ResultSet rs = stat.executeQuery();
             ResultSet rs = stat.executeQuery();
 
 
             while (rs.next()) {
             while (rs.next()) {
-                returnValue.add(rs.getString("season"));
+                result = rs.getInt(1);
             }
             }
         } catch (SQLException e) {
         } catch (SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-        return returnValue;
-    }
 
 
-    public List<OverUnder> getStatsOverUnderWithDrawStats(int leagueId, String gameDate) {
-        final DecimalFormat df = new DecimalFormat("##.##");
-        df.setRoundingMode(RoundingMode.HALF_DOWN);
-        final ArrayList<OverUnder> result = Lists.newArrayList();
+        return result;
+    }
 
 
-        final String sql = "SELECT (homeScore + awayScore) as numGoals, count(case when homeScore = awayScore then 1 end) draws, ROUND((sHome.avgScored * sAway.avgConceded) + (sAway.avgScored * sHome.avgConceded),1) roundedDiff, count(*) as numGames "
-                + "FROM SoccerResults "
-                + "INNER JOIN (SELECT homeTeamId, AVG(homeScore) as avgScored, AVG(awayScore) as avgConceded FROM SoccerResults WHERE homeScore != -1 AND homeTeamId = SoccerResults.homeTeamId AND DATE(gameDate) < ? AND leagueId = ? GROUP BY homeTeamId) as sHome ON SoccerResults.homeTeamId = sHome.homeTeamId "
-                + "INNER JOIN (SELECT awayTeamId, AVG(homeScore) as avgConceded, AVG(awayScore) as avgScored FROM SoccerResults WHERE awayScore != -1 AND awayTeamId = SoccerResults.awayTeamId AND DATE(gameDate) < ? AND leagueId = ? GROUP BY awayTeamId) as sAway ON SoccerResults.awayTeamId = sAway.awayTeamId "
-                + "WHERE homeScore != -1 AND awayScore != -1 AND leagueId = ? AND DATE(gameDate) < ? GROUP BY roundedDiff;";
+    public List<SimpleEntry<Integer, String>> getCountries() {
 
 
-        List<String> allSeasons = getAllSeasons(leagueId);
+        final ArrayList<AbstractMap.SimpleEntry<Integer, String>> countries = Lists.newArrayList();
+        final String sql = "SELECT id, name FROM Country";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            final String dateString;
-            if (Strings.isNullOrEmpty(gameDate)) {
-                dateString = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
-            } else {
-                dateString = gameDate;
-            }
-            for (String season : allSeasons) {
-                stat.setString(1, dateString);
-                stat.setInt(2, leagueId);
-                stat.setString(3, dateString);
-                stat.setInt(4, leagueId);
-
-                stat.setInt(5, leagueId);
-                stat.setString(6, dateString);
-
-                final ResultSet rs = stat.executeQuery();
 
 
-                while (rs.next()) {
-                    final float diff = rs.getFloat("roundedDiff");
-                    final int numGoals = rs.getInt("numGoals");
+            final ResultSet rs = stat.executeQuery();
 
 
-                    final OverUnder entry = result.stream().filter(ou -> ou.getKey().compareTo(diff) == 0)
-                            .findFirst()
-                            .orElse(new OverUnder(diff));
-                    entry.addGoalStat(numGoals);
-                    entry.setDraws(rs.getInt("draws"));
-                    entry.setTotalGames(rs.getInt("numGames"));
-                    result.add(entry);
-                }
+            while (rs.next()) {
+                final SimpleEntry<Integer, String> entry = new SimpleEntry<>(rs.getInt(Constants.ID),
+                        rs.getString("name"));
+                countries.add(entry);
             }
             }
         } catch (final SQLException e) {
         } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-        return result;
+        return countries;
     }
     }
 
 
-    public List<OverUnder> getStatsOverUnder(int leagueId, String gameDate) {
-
-        final DecimalFormat df = new DecimalFormat("##.##");
-        df.setRoundingMode(RoundingMode.HALF_DOWN);
-        final ArrayList<OverUnder> result = Lists.newArrayList();
-
-        final String sql = "SELECT ((sHome.avgScored * sAway.avgConceded) + (sAway.avgScored * sHome.avgConceded)) as diff, (homeScore + awayScore) as numGoals "
-                + "FROM SoccerResults "
-                + "INNER JOIN (SELECT homeTeamId, AVG(homeScore) as avgScored, AVG(awayScore) as avgConceded FROM SoccerResults WHERE homeScore != -1 AND homeTeamId = SoccerResults.homeTeamId AND DATE(gameDate) < ? AND season = ? AND leagueId = ? GROUP BY homeTeamId) as sHome ON SoccerResults.homeTeamId = sHome.homeTeamId "
-                + "INNER JOIN (SELECT awayTeamId, AVG(homeScore) as avgConceded, AVG(awayScore) as avgScored FROM SoccerResults WHERE awayScore != -1 AND awayTeamId = SoccerResults.awayTeamId AND DATE(gameDate) < ? AND season = ? AND leagueId = ? GROUP BY awayTeamId) as sAway ON SoccerResults.awayTeamId = sAway.awayTeamId "
-                + "WHERE homeScore != -1 AND awayScore != -1 AND leagueId = ? AND DATE(gameDate) < ? AND season = ? "
-                + "ORDER BY diff ASC";
-        List<String> allSeasons = getAllSeasons(leagueId);
-
+    public List<SimpleEntry<Integer, String>> getCountriesBySport(int sportId, String date) {
+        final String sql = "SELECT * FROM Country WHERE id IN (SELECT DISTINCT(countryId) FROM SoccerResults WHERE DATE(gameDate) = ?) ORDER BY prio DESC, name ASC";
+        final ArrayList<SimpleEntry<Integer, String>> result = new ArrayList<>();
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            final String dateString;
-            if (Strings.isNullOrEmpty(gameDate)) {
-                dateString = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
+            if (date.equals("")) {
+                stat.setString(1, new SimpleDateFormat(DATE_FORMAT).format(new Date()));
             } else {
             } else {
-                dateString = gameDate;
+                stat.setString(1, date);
             }
             }
-            for (String season : allSeasons) {
-                stat.setString(1, dateString);
-                stat.setString(2, season);
-                stat.setInt(3, leagueId);
-                stat.setString(4, dateString);
-                stat.setString(5, season);
-                stat.setInt(6, leagueId);
-
-                stat.setInt(7, leagueId);
-                stat.setString(8, dateString);
-                stat.setString(9, season);
-
-                final ResultSet rs = stat.executeQuery();
 
 
-                while (rs.next()) {
-                    final float diff = rs.getFloat("diff");
-                    final int numGoals = rs.getInt("numGoals");
-                    final Float formatted = round(BigDecimal.valueOf(diff), INCREMENT, RoundingMode.HALF_UP)
-                            .floatValue();
+            final ResultSet rs = stat.executeQuery();
 
 
-                    final OverUnder entry = result.stream().filter(ou -> ou.getKey().compareTo(formatted) == 0)
-                            .findFirst()
-                            .orElse(new OverUnder(formatted));
-                    entry.addGoalStat(numGoals);
-                    result.add(entry);
-                }
+            while (rs.next()) {
+                result.add(new SimpleEntry<>(rs.getInt(Constants.ID), rs.getString("name")));
             }
             }
         } catch (final SQLException e) {
         } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-        return result;
-    }
-
-    public BigDecimal round(BigDecimal value, BigDecimal increment, RoundingMode roundingMode) {
-        if (increment.signum() == 0) {
-            // 0 increment does not make much sense, but prevent division by 0
-            return value;
-        } else {
-            final BigDecimal divided = value.divide(increment, 0, roundingMode);
-            final BigDecimal result = divided.multiply(increment);
-            return result.setScale(2, RoundingMode.HALF_UP);
-        }
-    }
 
 
-    public BigDecimal getIncrement() {
-        return INCREMENT;
+        return result;
     }
     }
 
 
-    public List<TeamStanding> getLeagueTable(int leagueId, String season, int countryId, String date) {
-        final ArrayList<TeamStanding> result = Lists.newArrayList();
-
-        final String sql = "SELECT teamName.name as teamName, count(*) played, "
-                + "count(case when homeScore > awayScore then 1 end) wins, "
-                + "count(case when awayScore> homeScore then 1 end) lost, "
-                + "count(case when homeScore = awayScore then 1 end) draws, "
-                + "sum(homeScore) homeScore, " + "sum(awayScore) awayScore, "
-                + "sum(homeScore) - sum(awayScore) goal_diff, " + "sum("
-                + "case when homeScore > awayScore then 3 else 0 end + case "
-                + "WHEN homeScore = awayScore then 1 else 0 end) score, "
-                + "season FROM "
-                + "(select hometeamId team, homeScore, awayScore, season, gameDate, leagueId as league, countryId as country FROM SoccerResults "
-                + "union all SELECT awayteamId, awayScore, homeScore, season, gameDate, leagueId as league, countryId as country FROM SoccerResults) a "
-                + "INNER JOIN Team teamName ON team = teamName.id " + "WHERE season = ? " + "AND league = ? "
-                + "AND country = ? "
-                + "AND homeScore != -1 " + "AND awayScore != -1 AND DATE(gameDate) < DATE(?) group by team "
-                + "order by score desc, goal_diff desc";
+    public int getGameId(String homeTeam, String awayTeam, String gameDate, int countryId, int leagueId) {
+        int result = -1;
+        String sql = "SELECT id FROM SoccerResults WHERE homeTeamId = (SELECT id FROM Team WHERE name = ? AND countryId = ? AND leagueId = ?) AND awayTeamId = (SELECT id FROM Team WHERE name = ? AND countryId = ? AND leagueId = ?) AND DATE(gameDate) = DATE(?)";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
+            stat.setString(1, homeTeam);
+            stat.setInt(2, countryId);
+            stat.setInt(3, leagueId);
+            stat.setString(4, awayTeam);
+            stat.setInt(5, countryId);
+            stat.setInt(6, leagueId);
+            stat.setString(7, gameDate);
 
 
-            stat.setString(1, season);
-            stat.setInt(2, leagueId);
-            stat.setInt(3, countryId);
-            stat.setString(4, date);
+            ResultSet rs = stat.executeQuery();
 
 
-            final ResultSet rs = stat.executeQuery();
             while (rs.next()) {
             while (rs.next()) {
-                final TeamStanding ts = new TeamStanding(rs.getString("teamName"), rs.getInt("wins"), rs.getInt("lost"),
-                        rs.getInt("draws"),
-                        rs.getInt("score"), rs.getFloat(Constants.HOME_SCORE), rs.getFloat(Constants.AWAY_SCORE),
-                        rs.getFloat("goal_diff"));
-                result.add(ts);
+                result = rs.getInt("id");
             }
             }
 
 
-        } catch (final SQLException e) {
-            Log.getLog().info("Sql vid fel: %s", sql);
+        } catch (SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
 
 
         return result;
         return result;
     }
     }
 
 
-    public boolean getParsingStarted(int countryId, int leagueId) {
-        boolean returnValue = false;
-        final String sql = "SELECT parsedYear FROM League WHERE id = ? AND countryId = ?";
-        try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setInt(1, leagueId);
-            stat.setInt(2, countryId);
+    public Map<Integer, Integer> getGoalAvgThisSeason(int leagueId, int countryId) {
+        Map<Integer, Integer> returnValue = new HashMap<>();
+        final String goalsSql = "SELECT (homeScore + awayScore) as totalGoals, count(*) as count FROM SoccerResults  WHERE leagueId = ? AND countryId = ? AND season = ? GROUP BY totalGoals ORDER BY totalGoals asc";
+        try (PreparedStatement goalStmt = conn.prepareStatement(goalsSql)) {
+            goalStmt.setInt(1, leagueId);
+            goalStmt.setInt(2, countryId);
+            goalStmt.setString(3, getLastSeason(countryId, leagueId));
 
 
-            final ResultSet rs = stat.executeQuery();
-            while (rs.next()) {
-                final String parsedYear = rs.getString("parsedYear");
-                if (!Strings.isNullOrEmpty(parsedYear)) {
-                    returnValue = true;
+            final ResultSet goalRs = goalStmt.executeQuery();
+
+            while (goalRs.next()) {
+                int tg = goalRs.getInt("totalGoals");
+                if (tg < 0) {
+                    continue;
                 }
                 }
+                int numGoals = goalRs.getInt("count");
+
+                returnValue.put(tg, numGoals);
             }
             }
-        } catch (final SQLException e) {
+        } catch (SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-
         return returnValue;
         return returnValue;
     }
     }
 
 
+    public BigDecimal getIncrement() {
+        return INCREMENT;
+    }
+
     public String getLastSeason(Integer countryId, Integer leagueId) {
     public String getLastSeason(Integer countryId, Integer leagueId) {
         String season = "";
         String season = "";
         final String sql = "SELECT season FROM SoccerResults WHERE leagueId = ? AND countryId = ? ORDER BY season DESC limit 1";
         final String sql = "SELECT season FROM SoccerResults WHERE leagueId = ? AND countryId = ? ORDER BY season DESC limit 1";
@@ -572,104 +497,90 @@ public class GuiMysql extends Mysql {
         return season;
         return season;
     }
     }
 
 
-    public TeamResults getTeamResults(int teamId, int numResults, boolean isHomeTeam) {
-        final String sql;
-        final TeamResults tr = new TeamResults();
-        if (isHomeTeam) {
-            sql = "SELECT count(case when homeScore > awayScore then 1 end) wins, "
-                    + "count(case when awayScore > homeScore then 1 end) lost, "
-                    + "count(case when homeScore = awayScore then 1 end) draws "
-                    + "FROM (SELECT * FROM SoccerResults WHERE homeTeamId = ? AND "
-                    + "HomeScore >= 0 AND awayScore >= 0 AND DATE(gameDate) < DATE(NOW()) ORDER BY gameDate DESC LIMIT ?) as t";
-        } else {
-            sql = "SELECT count(case when homeScore < awayScore then 1 end) wins, "
-                    + "count(case when awayScore < homeScore then 1 end) lost, "
-                    + "count(case when homeScore = awayScore then 1 end) draws "
-                    + "FROM (SELECT * FROM SoccerResults WHERE awayTeamId = ? AND "
-                    + "HomeScore >= 0 AND awayScore >= 0 AND DATE(gameDate) < DATE(NOW()) ORDER BY gameDate DESC LIMIT ?) as t";
-        }
+    public List<Float> getLeagueAvarages(int leagueId, int countryId, String gameDate) {
+        final ArrayList<Float> returnValue = Lists.newArrayList();
+        final String sql = "SELECT AVG(homeScore) avgHomeScore, AVG(awayScore) as avgAwayScore"
+                + " FROM SoccerResults WHERE leagueId = ? AND countryId = ? AND DATE(gameDate) < DATE(?)";
 
 
-        try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setInt(1, teamId);
-            stat.setInt(2, numResults);
-            final ResultSet rs = stat.executeQuery();
+        try (PreparedStatement stat = conn.prepareStatement(sql);) {
+            stat.setInt(1, leagueId);
+            stat.setInt(2, countryId);
+            stat.setString(3, gameDate);
 
 
+            final ResultSet rs = stat.executeQuery();
             while (rs.next()) {
             while (rs.next()) {
-                final int draws = rs.getInt("draws");
-                final int wins = rs.getInt("wins");
-                final int lost = rs.getInt("lost");
-                tr.setDraws(draws);
-                tr.setWins(wins);
-                tr.setLosses(lost);
-                tr.setCount(wins + draws + lost);
+                returnValue.add(rs.getFloat("avgHomeScore"));
+                returnValue.add(rs.getFloat("avgAwayScore"));
             }
             }
+
         } catch (final SQLException e) {
         } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
 
 
-        return tr;
+        return returnValue;
     }
     }
 
 
-    public TeamResults getTeamResultsTest(int teamId, int numResults, boolean isHomeTeam, String date) {
-        final String sql;
-        final TeamResults tr = new TeamResults();
-        if (isHomeTeam) {
-            sql = "SELECT count(case when homeScore > awayScore then 1 end) wins, "
-                    + "count(case when awayScore > homeScore then 1 end) lost, "
-                    + "count(case when homeScore = awayScore then 1 end) draws "
-                    + "FROM (SELECT * FROM SoccerResults WHERE homeTeamId = ? AND "
-                    + "HomeScore >= 0 AND awayScore >= 0 AND DATE(gameDate) < ? ORDER BY gameDate DESC LIMIT ?) as t";
-        } else {
-            sql = "SELECT count(case when homeScore < awayScore then 1 end) wins, "
-                    + "count(case when awayScore < homeScore then 1 end) lost, "
-                    + "count(case when homeScore = awayScore then 1 end) draws "
-                    + "FROM (SELECT * FROM SoccerResults WHERE awayTeamId = ? AND "
-                    + "HomeScore >= 0 AND awayScore >= 0 AND DATE(gameDate) < ? ORDER BY gameDate DESC LIMIT ?) as t";
+    public League getLeagueInfo(int leagueId) {
+        final String sql = "SELECT * FROM League WHERE id = ?";
+        League result = null;
+        try (PreparedStatement stat = conn.prepareStatement(sql)) {
+            stat.setInt(1, leagueId);
+            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"));
+            }
+        } catch (final SQLException e) {
+            e.printStackTrace();
         }
         }
 
 
+        return result;
+    }
+
+    public League getLeagueInfo(String teamLeague) {
+        final String sql = "SELECT * FROM League WHERE name = ?";
+        League result = null;
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setInt(1, teamId);
-            stat.setString(2, date);
-            stat.setInt(3, numResults);
+            stat.setString(1, teamLeague);
             final ResultSet rs = stat.executeQuery();
             final ResultSet rs = stat.executeQuery();
 
 
             while (rs.next()) {
             while (rs.next()) {
-                final int draws = rs.getInt("draws");
-                final int wins = rs.getInt("wins");
-                final int lost = rs.getInt("lost");
-                tr.setDraws(draws);
-                tr.setWins(wins);
-                tr.setLosses(lost);
-                tr.setCount(wins + draws + lost);
+                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("drawWinngingFormHomeAway"));
             }
             }
-
         } catch (final SQLException e) {
         } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
 
 
-        return tr;
+        return result;
     }
     }
 
 
-    public List<SimpleEntry<Integer, String>> getCountriesBySport(int sportId, String date) {
-        final String sql = "SELECT * FROM Country WHERE id IN (SELECT DISTINCT(countryId) FROM SoccerResults WHERE DATE(gameDate) = ?) ORDER BY prio DESC, name ASC";
-        final ArrayList<SimpleEntry<Integer, String>> result = new ArrayList<>();
+    public List<SimpleEntry<Integer, String>> getLeagues(int sportId, int countryId) {
+
+        final ArrayList<AbstractMap.SimpleEntry<Integer, String>> leagues = Lists.newArrayList();
+        final String sql = "SELECT id, name FROM League WHERE sportId = ? AND countryId = ? ORDER BY name ASC";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            if (date.equals("")) {
-                stat.setString(1, new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
-            } else {
-                stat.setString(1, date);
-            }
+            stat.setInt(1, sportId);
+            stat.setInt(2, countryId);
 
 
             final ResultSet rs = stat.executeQuery();
             final ResultSet rs = stat.executeQuery();
 
 
             while (rs.next()) {
             while (rs.next()) {
-                result.add(new SimpleEntry<>(rs.getInt(Constants.ID), rs.getString("name")));
+                final SimpleEntry<Integer, String> entry = new SimpleEntry<>(rs.getInt(Constants.ID),
+                        rs.getString("name"));
+                leagues.add(entry);
             }
             }
         } catch (final SQLException e) {
         } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-
-        return result;
+        return leagues;
     }
     }
 
 
     public List<SimpleEntry<Integer, String>> getLeaguesByDate(int sportId, int countryId, String date) {
     public List<SimpleEntry<Integer, String>> getLeaguesByDate(int sportId, int countryId, String date) {
@@ -692,6 +603,48 @@ public class GuiMysql extends Mysql {
         return leagues;
         return leagues;
     }
     }
 
 
+    public List<TeamStanding> getLeagueTable(int leagueId, String season, int countryId, String date) {
+        final ArrayList<TeamStanding> result = Lists.newArrayList();
+
+        final String sql = "SELECT teamName.name as teamName, count(*) played, "
+                + "count(case when homeScore > awayScore then 1 end) wins, "
+                + "count(case when awayScore> homeScore then 1 end) lost, "
+                + "count(case when homeScore = awayScore then 1 end) draws, "
+                + "sum(homeScore) homeScore, " + "sum(awayScore) awayScore, "
+                + "sum(homeScore) - sum(awayScore) goal_diff, " + "sum("
+                + "case when homeScore > awayScore then 3 else 0 end + case "
+                + "WHEN homeScore = awayScore then 1 else 0 end) score, "
+                + "season FROM "
+                + "(select hometeamId team, homeScore, awayScore, season, gameDate, leagueId as league, countryId as country FROM SoccerResults "
+                + "union all SELECT awayteamId, awayScore, homeScore, season, gameDate, leagueId as league, countryId as country FROM SoccerResults) a "
+                + "INNER JOIN Team teamName ON team = teamName.id " + "WHERE season = ? " + "AND league = ? "
+                + "AND country = ? "
+                + "AND homeScore != -1 " + "AND awayScore != -1 AND DATE(gameDate) < DATE(?) group by team "
+                + "order by score desc, goal_diff desc";
+        try (PreparedStatement stat = conn.prepareStatement(sql)) {
+
+            stat.setString(1, season);
+            stat.setInt(2, leagueId);
+            stat.setInt(3, countryId);
+            stat.setString(4, date);
+
+            final ResultSet rs = stat.executeQuery();
+            while (rs.next()) {
+                final TeamStanding ts = new TeamStanding(rs.getString("teamName"), rs.getInt("wins"), rs.getInt("lost"),
+                        rs.getInt(DRAWS),
+                        rs.getInt("score"), rs.getFloat(Constants.HOME_SCORE), rs.getFloat(Constants.AWAY_SCORE),
+                        rs.getFloat("goal_diff"));
+                result.add(ts);
+            }
+
+        } catch (final SQLException e) {
+            Log.getLog().info("Sql vid fel: %s", sql);
+            e.printStackTrace();
+        }
+
+        return result;
+    }
+
     public List<SoccerMatch> getMatches(int sportId, Integer countryId, Integer leagueId, String date, String order,
     public List<SoccerMatch> getMatches(int sportId, Integer countryId, Integer leagueId, String date, String order,
             boolean exactDate,
             boolean exactDate,
             boolean onlyPrio) {
             boolean onlyPrio) {
@@ -757,15 +710,15 @@ public class GuiMysql extends Mysql {
                 awayTeam.setTeamName(rs.getString(Constants.AWAY_TEAM_NAME));
                 awayTeam.setTeamName(rs.getString(Constants.AWAY_TEAM_NAME));
                 homeTeam.setTeamLeagueId(rs.getInt(Constants.LEAGUE_ID));
                 homeTeam.setTeamLeagueId(rs.getInt(Constants.LEAGUE_ID));
                 awayTeam.setTeamLeagueId(rs.getInt(Constants.LEAGUE_ID));
                 awayTeam.setTeamLeagueId(rs.getInt(Constants.LEAGUE_ID));
-                homeTeam.setTeamLeague(rs.getString("leagueName"));
-                awayTeam.setTeamLeague(rs.getString("leagueName"));
+                homeTeam.setTeamLeague(rs.getString(LEAGUE_NAME));
+                awayTeam.setTeamLeague(rs.getString(LEAGUE_NAME));
                 homeTeam.setCountryId(rs.getInt(Constants.COUNTRY_ID));
                 homeTeam.setCountryId(rs.getInt(Constants.COUNTRY_ID));
                 awayTeam.setCountryId(rs.getInt(Constants.COUNTRY_ID));
                 awayTeam.setCountryId(rs.getInt(Constants.COUNTRY_ID));
-                homeTeam.setCountryName(rs.getString("countryName"));
-                awayTeam.setCountryName(rs.getString("countryName"));
+                homeTeam.setCountryName(rs.getString(COUNTRY_NAME));
+                awayTeam.setCountryName(rs.getString(COUNTRY_NAME));
 
 
-                sm.setLeagueName(rs.getString("leagueName"));
-                sm.setCountryName(rs.getString("countryName"));
+                sm.setLeagueName(rs.getString(LEAGUE_NAME));
+                sm.setCountryName(rs.getString(COUNTRY_NAME));
                 sm.setAwayScore(rs.getInt(Constants.AWAY_SCORE));
                 sm.setAwayScore(rs.getInt(Constants.AWAY_SCORE));
                 sm.setHomeScore(rs.getInt(Constants.HOME_SCORE));
                 sm.setHomeScore(rs.getInt(Constants.HOME_SCORE));
                 sm.setHomeTeam(homeTeam);
                 sm.setHomeTeam(homeTeam);
@@ -790,480 +743,574 @@ public class GuiMysql extends Mysql {
         return matches;
         return matches;
     }
     }
 
 
-    public League getLeagueInfo(String teamLeague) {
-        final String sql = "SELECT * FROM League WHERE name = ?";
-        League result = null;
+    public List<SoccerMatch> getMatches(int sportId, String dateString, String sortOrder, boolean exactDate) {
+        return getMatches(sportId, null, null, dateString, sortOrder, exactDate, true);
+    }
+
+    public boolean getParsingStarted(int countryId, int leagueId) {
+        boolean returnValue = false;
+        final String sql = "SELECT parsedYear FROM League WHERE id = ? AND countryId = ?";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setString(1, teamLeague);
-            final ResultSet rs = stat.executeQuery();
+            stat.setInt(1, leagueId);
+            stat.setInt(2, countryId);
 
 
+            final ResultSet rs = stat.executeQuery();
             while (rs.next()) {
             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"));
+                final String parsedYear = rs.getString("parsedYear");
+                if (!Strings.isNullOrEmpty(parsedYear)) {
+                    returnValue = true;
+                }
             }
             }
         } catch (final SQLException e) {
         } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
 
 
-        return result;
+        return returnValue;
     }
     }
 
 
-    public League getLeagueInfo(int leagueId) {
-        final String sql = "SELECT * FROM League WHERE id = ?";
-        League result = null;
-        try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setInt(1, leagueId);
-            final ResultSet rs = stat.executeQuery();
+    public Map<String, String> getPreviousMatches(int numberOfMatches, String homeTeamName, String awayTeamName,
+            String date, int countryId,
+            int leagueId) {
+        Map<String, String> result = new HashMap<>();
 
 
-            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"));
+        String homeTeamSql = "SELECT * FROM SoccerResults sr INNER JOIN Team t ON sr.homeTeamId = t.id WHERE t.name = ? AND sr.leagueId = ? AND DATE(gameDate) < ? ORDER BY gameDate DESC limit ?";
+        String awayTeamSql = "SELECT * FROM SoccerResults sr INNER JOIN Team t ON sr.awayTeamId = t.id WHERE t.name = ? AND sr.leagueId = ? AND DATE(gameDate) < ? ORDER BY gameDate DESC limit ?";
+        String combinedSql = "SELECT * FROM SoccerResults sr INNER JOIN Team homeTeam ON homeTeamId = homeTeam.id INNER JOIN Team awayTeam ON sr.awayTeamId = awayTeam.id WHERE homeTeam.name = ? AND awayTeam.name = ? AND sr.leagueId = ? AND DATE(gameDate) < ? ORDER BY gameDate DESC LIMIT ?";
+        String combinedReverseSql = "SELECT * FROM SoccerResults sr INNER JOIN Team homeTeam ON homeTeamId = homeTeam.id INNER JOIN Team awayTeam ON sr.awayTeamId = awayTeam.id WHERE homeTeam.name = ? AND awayTeam.name = ? AND sr.leagueId = ? AND DATE(gameDate) < ? ORDER BY gameDate DESC LIMIT ?";
+        try (PreparedStatement homeTeamStat = conn.prepareStatement(homeTeamSql);
+                PreparedStatement awayTeamStat = conn.prepareStatement(awayTeamSql);
+                PreparedStatement combinedStat = conn.prepareStatement(combinedSql);
+                PreparedStatement combinedReversedStat = conn.prepareStatement(combinedReverseSql);) {
+
+            homeTeamStat.setString(1, homeTeamName);
+            homeTeamStat.setInt(2, leagueId);
+            homeTeamStat.setString(3, date);
+            homeTeamStat.setInt(4, numberOfMatches);
+
+            awayTeamStat.setString(1, awayTeamName);
+            awayTeamStat.setInt(2, leagueId);
+            awayTeamStat.setString(3, date);
+            awayTeamStat.setInt(4, numberOfMatches);
+
+            combinedStat.setString(1, homeTeamName);
+            combinedStat.setString(2, awayTeamName);
+            combinedStat.setInt(3, leagueId);
+            combinedStat.setString(4, date);
+            combinedStat.setInt(5, numberOfMatches);
+
+            combinedReversedStat.setString(1, awayTeamName);
+            combinedReversedStat.setString(2, homeTeamName);
+            combinedReversedStat.setInt(3, leagueId);
+            combinedReversedStat.setString(4, date);
+            combinedReversedStat.setInt(5, numberOfMatches);
+
+            ResultSet homeTeamRs = homeTeamStat.executeQuery();
+            ResultSet awayTeamRs = awayTeamStat.executeQuery();
+            ResultSet combinedTeamRs = combinedStat.executeQuery();
+            ResultSet combinedReversedTeamRs = combinedReversedStat.executeQuery();
+
+            String homeTeamMeets = "";
+            while (homeTeamRs.next()) {
+                homeTeamMeets += homeTeamRs.getInt(HOME_SCORE) + "-" + homeTeamRs.getInt(AWAY_SCORE) + ", ";
             }
             }
-        } catch (final SQLException e) {
+            String awayTeamMeets = "";
+            while (awayTeamRs.next()) {
+                awayTeamMeets += awayTeamRs.getInt(HOME_SCORE) + "-" + awayTeamRs.getInt(AWAY_SCORE) + ", ";
+            }
+            String combinedMeets = "";
+            while (combinedTeamRs.next()) {
+                combinedMeets += combinedTeamRs.getInt(HOME_SCORE) + "-" + combinedTeamRs.getInt(AWAY_SCORE) + ", ";
+            }
+            String combinedReversedMeets = "";
+            while (combinedReversedTeamRs.next()) {
+                combinedReversedMeets += combinedReversedTeamRs.getInt(HOME_SCORE) + "-"
+                        + combinedReversedTeamRs.getInt(AWAY_SCORE) + ", ";
+            }
+            if (homeTeamMeets.length() > 2) {
+                result.put("PrevHomeTeam", homeTeamMeets.substring(0, homeTeamMeets.length() - 2));
+            } else {
+                result.put("PrevHomeTeam", homeTeamMeets);
+            }
+            if (awayTeamMeets.length() > 2) {
+                result.put("PrevAwayTeam", awayTeamMeets.substring(0, awayTeamMeets.length() - 2));
+            } else {
+                result.put("PrevAwayTeam", awayTeamMeets);
+            }
+            if (combinedMeets.length() > 2) {
+                result.put("PrevCombined", combinedMeets.substring(0, combinedMeets.length() - 2));
+            } else {
+                result.put("PrevCombined", combinedMeets);
+            }
+
+            if (combinedReversedMeets.length() > 2) {
+                result.put("PrevReversedCombined",
+                        combinedReversedMeets.substring(0, combinedReversedMeets.length() - 2));
+            } else {
+                result.put("PrevReversedCombined", combinedReversedMeets);
+            }
+
+        } catch (SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
 
 
         return result;
         return result;
     }
     }
 
 
-    public void setTeamMarginHome(int teamId, int marginHome) {
-        final String sql = "UPDATE Team SET marginHome = ? WHERE id = ?";
-
+    public String getSeasonFromDate(int countryId, int leagueId, String gameDate) {
+        String sql = "SELECT season FROM SoccerResults WHERE DATE(gameDate) = ? AND countryId = ? AND leagueId = ? LIMIT 1";
+        String returnValue = "";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setInt(1, marginHome);
-            stat.setInt(2, teamId);
-
-            stat.executeUpdate();
+            if (Strings.isNullOrEmpty(gameDate)) {
+                stat.setString(1, new SimpleDateFormat(DATE_FORMAT).format(new Date()));
+            } else {
+                stat.setString(1, gameDate);
+            }
+            stat.setInt(2, countryId);
+            stat.setInt(3, leagueId);
 
 
-        } catch (final SQLException e) {
+            ResultSet rs = stat.executeQuery();
+            while (rs.next()) {
+                returnValue = rs.getString(SEASON);
+            }
+        } catch (SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
+        return returnValue;
     }
     }
 
 
-    public void setTeamMarginDraw(int teamId, int marginDraw) {
-        final String sql = "UPDATE Team SET marginDraw = ? WHERE id = ?";
+    public List<SimpleEntry<Integer, String>> getSports() {
 
 
+        final ArrayList<AbstractMap.SimpleEntry<Integer, String>> sports = Lists.newArrayList();
+        final String sql = "SELECT id, name FROM Sport";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setInt(1, marginDraw);
-            stat.setInt(2, teamId);
 
 
-            stat.executeUpdate();
+            final ResultSet rs = stat.executeQuery();
 
 
+            while (rs.next()) {
+                final SimpleEntry<Integer, String> entry = new SimpleEntry<>(rs.getInt(Constants.ID),
+                        rs.getString("name"));
+                sports.add(entry);
+            }
         } catch (final SQLException e) {
         } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-    }
 
 
-    public void setTeamMarginAway(int teamId, int marginAway) {
-        final String sql = "UPDATE Team SET marginAway = ? WHERE id = ?";
-
-        try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setInt(1, marginAway);
-            stat.setInt(2, teamId);
-
-            stat.executeUpdate();
+        return sports;
+    }
 
 
-        } catch (final SQLException e) {
-            e.printStackTrace();
-        }
+    public List<OverUnder> getStatsOverUnder(int leagueId) {
+        return getStatsOverUnder(leagueId, "");
     }
     }
 
 
-    public void setTeamLookbackHome(int teamId, int lookbackHome) {
-        final String sql = "UPDATE Team SET lookbackHome = ? WHERE id = ?";
+    public List<OverUnder> getStatsOverUnder(int leagueId, String gameDate) {
 
 
-        try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setInt(1, lookbackHome);
-            stat.setInt(2, teamId);
+        final DecimalFormat df = new DecimalFormat("##.##");
+        df.setRoundingMode(RoundingMode.HALF_DOWN);
+        final ArrayList<OverUnder> result = Lists.newArrayList();
 
 
-            stat.executeUpdate();
+        final String sql = "SELECT ((sHome.avgScored * sAway.avgConceded) + (sAway.avgScored * sHome.avgConceded)) as diff, (homeScore + awayScore) as numGoals "
+                + "FROM SoccerResults "
+                + "INNER JOIN (SELECT homeTeamId, AVG(homeScore) as avgScored, AVG(awayScore) as avgConceded FROM SoccerResults WHERE homeScore != -1 AND homeTeamId = SoccerResults.homeTeamId AND DATE(gameDate) < ? AND season = ? AND leagueId = ? GROUP BY homeTeamId) as sHome ON SoccerResults.homeTeamId = sHome.homeTeamId "
+                + "INNER JOIN (SELECT awayTeamId, AVG(homeScore) as avgConceded, AVG(awayScore) as avgScored FROM SoccerResults WHERE awayScore != -1 AND awayTeamId = SoccerResults.awayTeamId AND DATE(gameDate) < ? AND season = ? AND leagueId = ? GROUP BY awayTeamId) as sAway ON SoccerResults.awayTeamId = sAway.awayTeamId "
+                + "WHERE homeScore != -1 AND awayScore != -1 AND leagueId = ? AND DATE(gameDate) < ? AND season = ? "
+                + "ORDER BY diff ASC";
+        List<String> allSeasons = getAllSeasons(leagueId);
 
 
-        } catch (final SQLException e) {
-            e.printStackTrace();
-        }
-    }
+        try (PreparedStatement stat = conn.prepareStatement(sql)) {
+            final String dateString;
+            if (Strings.isNullOrEmpty(gameDate)) {
+                dateString = new SimpleDateFormat(DATE_FORMAT).format(new Date());
+            } else {
+                dateString = gameDate;
+            }
+            for (String season : allSeasons) {
+                stat.setString(1, dateString);
+                stat.setString(2, season);
+                stat.setInt(3, leagueId);
+                stat.setString(4, dateString);
+                stat.setString(5, season);
+                stat.setInt(6, leagueId);
 
 
-    public void setTeamLookbackDraw(int teamId, int lookbackDraw) {
-        final String sql = "UPDATE Team SET lookbackDraw = ? WHERE id = ?";
+                stat.setInt(7, leagueId);
+                stat.setString(8, dateString);
+                stat.setString(9, season);
 
 
-        try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setInt(1, lookbackDraw);
-            stat.setInt(2, teamId);
+                final ResultSet rs = stat.executeQuery();
 
 
-            stat.executeUpdate();
+                while (rs.next()) {
+                    final float diff = rs.getFloat("diff");
+                    final int numGoals = rs.getInt("numGoals");
+                    final Float formatted = round(BigDecimal.valueOf(diff), INCREMENT, RoundingMode.HALF_UP)
+                            .floatValue();
 
 
+                    final OverUnder entry = result.stream().filter(ou -> ou.getKey().compareTo(formatted) == 0)
+                            .findFirst()
+                            .orElse(new OverUnder(formatted));
+                    entry.addGoalStat(numGoals);
+                    result.add(entry);
+                }
+            }
         } catch (final SQLException e) {
         } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
+        return result;
     }
     }
 
 
-    public void setTeamLookbackAway(int teamId, int lookbackAway) {
-        final String sql = "UPDATE Team SET lookbackAway = ? WHERE id = ?";
+    public List<OverUnder> getStatsOverUnderWithDrawStats(int leagueId, String gameDate) {
+        final DecimalFormat df = new DecimalFormat("##.##");
+        df.setRoundingMode(RoundingMode.HALF_DOWN);
+        final ArrayList<OverUnder> result = Lists.newArrayList();
+
+        final String sql = "SELECT (homeScore + awayScore) as numGoals, count(case when homeScore = awayScore then 1 end) draws, ROUND((sHome.avgScored * sAway.avgConceded) + (sAway.avgScored * sHome.avgConceded),1) roundedDiff, count(*) as numGames "
+                + "FROM SoccerResults "
+                + "INNER JOIN (SELECT homeTeamId, AVG(homeScore) as avgScored, AVG(awayScore) as avgConceded FROM SoccerResults WHERE homeScore != -1 AND homeTeamId = SoccerResults.homeTeamId AND DATE(gameDate) < ? AND leagueId = ? GROUP BY homeTeamId) as sHome ON SoccerResults.homeTeamId = sHome.homeTeamId "
+                + "INNER JOIN (SELECT awayTeamId, AVG(homeScore) as avgConceded, AVG(awayScore) as avgScored FROM SoccerResults WHERE awayScore != -1 AND awayTeamId = SoccerResults.awayTeamId AND DATE(gameDate) < ? AND leagueId = ? GROUP BY awayTeamId) as sAway ON SoccerResults.awayTeamId = sAway.awayTeamId "
+                + "WHERE homeScore != -1 AND awayScore != -1 AND leagueId = ? AND DATE(gameDate) < ? GROUP BY roundedDiff;";
 
 
+        List<String> allSeasons = getAllSeasons(leagueId);
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setInt(1, lookbackAway);
-            stat.setInt(2, teamId);
+            final String dateString;
+            if (Strings.isNullOrEmpty(gameDate)) {
+                dateString = new SimpleDateFormat(DATE_FORMAT).format(new Date());
+            } else {
+                dateString = gameDate;
+            }
+            for (String season : allSeasons) {
+                stat.setString(1, dateString);
+                stat.setInt(2, leagueId);
+                stat.setString(3, dateString);
+                stat.setInt(4, leagueId);
 
 
-            stat.executeUpdate();
+                stat.setInt(5, leagueId);
+                stat.setString(6, dateString);
 
 
+                final ResultSet rs = stat.executeQuery();
+
+                while (rs.next()) {
+                    final float diff = rs.getFloat("roundedDiff");
+                    final int numGoals = rs.getInt("numGoals");
+
+                    final OverUnder entry = result.stream().filter(ou -> ou.getKey().compareTo(diff) == 0)
+                            .findFirst()
+                            .orElse(new OverUnder(diff));
+                    entry.addGoalStat(numGoals);
+                    entry.setDraws(rs.getInt(DRAWS));
+                    entry.setTotalGames(rs.getInt("numGames"));
+                    result.add(entry);
+                }
+            }
         } catch (final SQLException e) {
         } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
+        return result;
     }
     }
 
 
-    public List<BetDTO> getBetSeries(boolean includeInactive) {
-        List<BetDTO> result = new ArrayList<>();
-        String sql = "SELECT ab.*, sr.gameDate as gameDate, sr.id as gameId, sr.homeScore as homeScore, sr.awayScore as awayScore, "
-                + "ht.name as homeTeam, aw.name as awayTeam " + "FROM ActiveBets ab "
-                + "INNER JOIN SoccerResults sr ON ab.gameId = sr.id "
-                + "INNER JOIN Team ht ON sr.homeTeamId = ht.id " + "INNER JOIN Team aw ON sr.awayTeamId = aw.id "
-                + "WHERE done = ? ORDER BY series ASC, sr.gameDate DESC";
-
+    public Team getTeam(int teamId) {
+        Team result = null;
+        String sql = "SELECT t.*, c.name as countryName, l.name AS leagueName FROM Team t "
+                + "INNER JOIN Country c ON t.countryId = c.id "
+                + "INNER JOIN League l ON t.leagueId = l.id "
+                + "WHERE t.id = ? ";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setBoolean(1, includeInactive);
+            stat.setInt(1, teamId);
 
 
             ResultSet rs = stat.executeQuery();
             ResultSet rs = stat.executeQuery();
 
 
             while (rs.next()) {
             while (rs.next()) {
-                BetDTO dto = new BetDTO();
-                dto.setHomeTeam(rs.getString("homeTeam"));
-                dto.setAwayTeam(rs.getString("awayTeam"));
-                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("homeScore"), rs.getInt("AwayScore"));
-                dto.setGameDate(rs.getString("gameDate"));
-                dto.setWinAmount(rs.getFloat("odds") * rs.getFloat("bet"));
-                result.add(dto);
+                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) {
         } catch (SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-
         return result;
         return result;
     }
     }
 
 
-    public void addBetSeries(BetDTO bet) {
-        String sql = "INSERT INTO ActiveBets (series, gameId, betType, bet, odds, done) VALUES (?, ?, ?, ?, ?, ?)";
-
-        try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setInt(1, bet.getBetSeries());
-            stat.setInt(2, getGameId(bet.getHomeTeam(), bet.getAwayTeam(), bet.getGameDate(), bet.getCountryId(),
-                    bet.getLeagueId()));
-            stat.setString(3, bet.getBetType());
-            stat.setFloat(4, bet.getBet());
-            stat.setFloat(5, bet.getOdds());
-            stat.setBoolean(6, false);
-
-            stat.execute();
-        } catch (SQLException e) {
-            e.printStackTrace();
+    public TeamResults getTeamResults(int teamId, int numResults, boolean isHomeTeam) {
+        final String sql;
+        final TeamResults tr = new TeamResults();
+        if (isHomeTeam) {
+            sql = "SELECT count(case when homeScore > awayScore then 1 end) wins, "
+                    + "count(case when awayScore > homeScore then 1 end) lost, "
+                    + "count(case when homeScore = awayScore then 1 end) draws "
+                    + "FROM (SELECT * FROM SoccerResults WHERE homeTeamId = ? AND "
+                    + "HomeScore >= 0 AND awayScore >= 0 AND DATE(gameDate) < DATE(NOW()) ORDER BY gameDate DESC LIMIT ?) as t";
+        } else {
+            sql = "SELECT count(case when homeScore < awayScore then 1 end) wins, "
+                    + "count(case when awayScore < homeScore then 1 end) lost, "
+                    + "count(case when homeScore = awayScore then 1 end) draws "
+                    + "FROM (SELECT * FROM SoccerResults WHERE awayTeamId = ? AND "
+                    + "HomeScore >= 0 AND awayScore >= 0 AND DATE(gameDate) < DATE(NOW()) ORDER BY gameDate DESC LIMIT ?) as t";
         }
         }
-    }
 
 
-    public int getGameId(String homeTeam, String awayTeam, String gameDate, int countryId, int leagueId) {
-        int result = -1;
-        String sql = "SELECT id FROM SoccerResults WHERE homeTeamId = (SELECT id FROM Team WHERE name = ? AND countryId = ? AND leagueId = ?) AND awayTeamId = (SELECT id FROM Team WHERE name = ? AND countryId = ? AND leagueId = ?) AND DATE(gameDate) = DATE(?)";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setString(1, homeTeam);
-            stat.setInt(2, countryId);
-            stat.setInt(3, leagueId);
-            stat.setString(4, awayTeam);
-            stat.setInt(5, countryId);
-            stat.setInt(6, leagueId);
-            stat.setString(7, gameDate);
-
-            ResultSet rs = stat.executeQuery();
+            stat.setInt(1, teamId);
+            stat.setInt(2, numResults);
+            final ResultSet rs = stat.executeQuery();
 
 
             while (rs.next()) {
             while (rs.next()) {
-                result = rs.getInt("id");
+                final int draws = rs.getInt(DRAWS);
+                final int wins = rs.getInt("wins");
+                final int lost = rs.getInt("lost");
+                tr.setDraws(draws);
+                tr.setWins(wins);
+                tr.setLosses(lost);
+                tr.setCount(wins + draws + lost);
             }
             }
-
-        } catch (SQLException e) {
+        } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
 
 
-        return result;
+        return tr;
     }
     }
 
 
-    public Map<String, String> getPreviousMatches(int numberOfMatches, String homeTeamName, String awayTeamName,
-            String date, int countryId,
-            int leagueId) {
-        Map<String, String> result = new HashMap<>();
-
-        String homeTeamSql = "SELECT * FROM SoccerResults sr INNER JOIN Team t ON sr.homeTeamId = t.id WHERE t.name = ? AND sr.leagueId = ? AND DATE(gameDate) < ? ORDER BY gameDate DESC limit ?";
-        String awayTeamSql = "SELECT * FROM SoccerResults sr INNER JOIN Team t ON sr.awayTeamId = t.id WHERE t.name = ? AND sr.leagueId = ? AND DATE(gameDate) < ? ORDER BY gameDate DESC limit ?";
-        String combinedSql = "SELECT * FROM SoccerResults sr INNER JOIN Team homeTeam ON homeTeamId = homeTeam.id INNER JOIN Team awayTeam ON sr.awayTeamId = awayTeam.id WHERE homeTeam.name = ? AND awayTeam.name = ? AND sr.leagueId = ? AND DATE(gameDate) < ? ORDER BY gameDate DESC LIMIT ?";
-        String combinedReverseSql = "SELECT * FROM SoccerResults sr INNER JOIN Team homeTeam ON homeTeamId = homeTeam.id INNER JOIN Team awayTeam ON sr.awayTeamId = awayTeam.id WHERE homeTeam.name = ? AND awayTeam.name = ? AND sr.leagueId = ? AND DATE(gameDate) < ? ORDER BY gameDate DESC LIMIT ?";
-        try (PreparedStatement homeTeamStat = conn.prepareStatement(homeTeamSql);
-                PreparedStatement awayTeamStat = conn.prepareStatement(awayTeamSql);
-                PreparedStatement combinedStat = conn.prepareStatement(combinedSql);
-                PreparedStatement combinedReversedStat = conn.prepareStatement(combinedReverseSql);) {
-
-            homeTeamStat.setString(1, homeTeamName);
-            homeTeamStat.setInt(2, leagueId);
-            homeTeamStat.setString(3, date);
-            homeTeamStat.setInt(4, numberOfMatches);
-
-            awayTeamStat.setString(1, awayTeamName);
-            awayTeamStat.setInt(2, leagueId);
-            awayTeamStat.setString(3, date);
-            awayTeamStat.setInt(4, numberOfMatches);
-
-            combinedStat.setString(1, homeTeamName);
-            combinedStat.setString(2, awayTeamName);
-            combinedStat.setInt(3, leagueId);
-            combinedStat.setString(4, date);
-            combinedStat.setInt(5, numberOfMatches);
-
-            combinedReversedStat.setString(1, awayTeamName);
-            combinedReversedStat.setString(2, homeTeamName);
-            combinedReversedStat.setInt(3, leagueId);
-            combinedReversedStat.setString(4, date);
-            combinedReversedStat.setInt(5, numberOfMatches);
-
-            ResultSet homeTeamRs = homeTeamStat.executeQuery();
-            ResultSet awayTeamRs = awayTeamStat.executeQuery();
-            ResultSet combinedTeamRs = combinedStat.executeQuery();
-            ResultSet combinedReversedTeamRs = combinedReversedStat.executeQuery();
-
-            String homeTeamMeets = "";
-            while (homeTeamRs.next()) {
-                homeTeamMeets += homeTeamRs.getInt("homeScore") + "-" + homeTeamRs.getInt("awayScore") + ", ";
-            }
-            String awayTeamMeets = "";
-            while (awayTeamRs.next()) {
-                awayTeamMeets += awayTeamRs.getInt("homeScore") + "-" + awayTeamRs.getInt("awayScore") + ", ";
-            }
-            String combinedMeets = "";
-            while (combinedTeamRs.next()) {
-                combinedMeets += combinedTeamRs.getInt("homeScore") + "-" + combinedTeamRs.getInt("awayScore") + ", ";
-            }
-            String combinedReversedMeets = "";
-            while (combinedReversedTeamRs.next()) {
-                combinedReversedMeets += combinedReversedTeamRs.getInt("homeScore") + "-"
-                        + combinedReversedTeamRs.getInt("awayScore") + ", ";
-            }
-            if (homeTeamMeets.length() > 2) {
-                result.put("PrevHomeTeam", homeTeamMeets.substring(0, homeTeamMeets.length() - 2));
-            } else {
-                result.put("PrevHomeTeam", homeTeamMeets);
-            }
-            if (awayTeamMeets.length() > 2) {
-                result.put("PrevAwayTeam", awayTeamMeets.substring(0, awayTeamMeets.length() - 2));
-            } else {
-                result.put("PrevAwayTeam", awayTeamMeets);
-            }
-            if (combinedMeets.length() > 2) {
-                result.put("PrevCombined", combinedMeets.substring(0, combinedMeets.length() - 2));
-            } else {
-                result.put("PrevCombined", combinedMeets);
-            }
+    public TeamResults getTeamResultsTest(int teamId, int numResults, boolean isHomeTeam, String date) {
+        final String sql;
+        final TeamResults tr = new TeamResults();
+        if (isHomeTeam) {
+            sql = "SELECT count(case when homeScore > awayScore then 1 end) wins, "
+                    + "count(case when awayScore > homeScore then 1 end) lost, "
+                    + "count(case when homeScore = awayScore then 1 end) draws "
+                    + "FROM (SELECT * FROM SoccerResults WHERE homeTeamId = ? AND "
+                    + "HomeScore >= 0 AND awayScore >= 0 AND DATE(gameDate) < ? ORDER BY gameDate DESC LIMIT ?) as t";
+        } else {
+            sql = "SELECT count(case when homeScore < awayScore then 1 end) wins, "
+                    + "count(case when awayScore < homeScore then 1 end) lost, "
+                    + "count(case when homeScore = awayScore then 1 end) draws "
+                    + "FROM (SELECT * FROM SoccerResults WHERE awayTeamId = ? AND "
+                    + "HomeScore >= 0 AND awayScore >= 0 AND DATE(gameDate) < ? ORDER BY gameDate DESC LIMIT ?) as t";
+        }
 
 
-            if (combinedReversedMeets.length() > 2) {
-                result.put("PrevReversedCombined",
-                        combinedReversedMeets.substring(0, combinedReversedMeets.length() - 2));
-            } else {
-                result.put("PrevReversedCombined", combinedReversedMeets);
+        try (PreparedStatement stat = conn.prepareStatement(sql)) {
+            stat.setInt(1, teamId);
+            stat.setString(2, date);
+            stat.setInt(3, numResults);
+            final ResultSet rs = stat.executeQuery();
+
+            while (rs.next()) {
+                final int draws = rs.getInt(DRAWS);
+                final int wins = rs.getInt("wins");
+                final int lost = rs.getInt("lost");
+                tr.setDraws(draws);
+                tr.setWins(wins);
+                tr.setLosses(lost);
+                tr.setCount(wins + draws + lost);
             }
             }
 
 
-        } catch (SQLException e) {
+        } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
 
 
-        return result;
+        return tr;
     }
     }
 
 
-    public int getBetSeriesEndNumber() {
-        int result = -1;
-        String sql = "SELECT MAX(series) FROM ActiveBets";
+    public List<SoccerMatch> getUpcomingMatches(String sportResultTable) {
+        final ArrayList<SoccerMatch> matches = Lists.newArrayList();
+        final String dateSql;
+        dateSql = " AND DATE(gameDate) >= DATE(now())";
+
+        final String sql = "SELECT res.id, homeTeamId, awayTeamId, homeScore, awayScore, overtime, odds1, oddsX, odds2, gameDate, season, res.leagueId, res.countryId, "
+                + "hTeam.name as homeTeamName, aTeam.name as awayTeamName, " + "league.name as leagueName, "
+                + "country.name as countryName, "
+                + "country.prio as prio " + "FROM " + sportResultTable + " as res "
+                + "Join Team as hTeam ON res.homeTeamId = hTeam.id "
+                + "Join Team as aTeam ON res.awayTeamId = aTeam.id "
+                + "Join League as league ON res.leagueId = league.id "
+                + "Join Country as country ON res.countryId = country.id " + "WHERE homeScore = -1 " + dateSql
+                + "AND league.name NOT LIKE '%cup%' AND league.name NOT LIKE '%group%' AND league.prio = 1 "
+                + "ORDER BY country.prio DESC, country.name ASC";
 
 
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            ResultSet rs = stat.executeQuery();
 
 
+            final ResultSet rs = stat.executeQuery();
             while (rs.next()) {
             while (rs.next()) {
-                result = rs.getInt(1);
+                final SoccerMatch sm = new SoccerMatch();
+                final Team homeTeam = new Team();
+                final Team awayTeam = new Team();
+
+                homeTeam.setTeamId(rs.getInt(Constants.HOME_TEAM_ID));
+                awayTeam.setTeamId(rs.getInt(Constants.AWAY_TEAM_ID));
+                homeTeam.setTeamName(rs.getString(Constants.HOME_TEAM_NAME));
+                awayTeam.setTeamName(rs.getString(Constants.AWAY_TEAM_NAME));
+                homeTeam.setTeamLeagueId(rs.getInt(Constants.LEAGUE_ID));
+                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.setCountryName(rs.getString(Constants.COUNTRY_NAME));
+                awayTeam.setCountryName(rs.getString(Constants.COUNTRY_NAME));
+
+                sm.setAwayScore(rs.getInt(Constants.AWAY_SCORE));
+                sm.setHomeScore(rs.getInt(Constants.HOME_SCORE));
+                sm.setHomeTeam(homeTeam);
+                sm.setAwayTeam(awayTeam);
+                sm.setMatchId(rs.getInt(Constants.ID));
+                sm.setOdds1(rs.getFloat(Constants.ODDS_1));
+                sm.setOddsX(rs.getFloat(Constants.ODDS_X));
+                sm.setOdds2(rs.getFloat(Constants.ODDS_2));
+                sm.setGameDate(LocalDateTime.parse(rs.getString(Constants.GAME_DATE)));
+                sm.setCountryPrio(rs.getBoolean("prio"));
+
+                matches.add(sm);
             }
             }
-        } catch (SQLException e) {
+
+        } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
 
 
-        return result;
+        return matches;
     }
     }
 
 
-    public List<SoccerMatch> getMatches(int sportId, String dateString, String sortOrder, boolean exactDate) {
-        return getMatches(sportId, null, null, dateString, sortOrder, exactDate, true);
+    public BigDecimal round(BigDecimal value, BigDecimal increment, RoundingMode roundingMode) {
+        if (increment.signum() == 0) {
+            // 0 increment does not make much sense, but prevent division by 0
+            return value;
+        } else {
+            final BigDecimal divided = value.divide(increment, 0, roundingMode);
+            final BigDecimal result = divided.multiply(increment);
+            return result.setScale(2, RoundingMode.HALF_UP);
+        }
     }
     }
 
 
-    public void updateBetBaseAmount(String value) {
-        String sql = "INSERT INTO Settings (name, value) VALUES (?, ?) ON DUPLICATE KEY UPDATE value = ?";
-
+    public void setBetCovered(int id, int coveredBetId) {
+        String sql = "UPDATE AnalysisBetTable SET coveredBetId = ? WHERE id = ?";
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setString(1, "BetBaseAmount");
-            stat.setString(2, value);
-            stat.setString(3, value);
+            stat.setInt(1, coveredBetId);
+            stat.setInt(2, id);
 
 
-            stat.execute();
+            stat.executeUpdate();
         } catch (SQLException e) {
         } catch (SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
     }
     }
 
 
-    public String getBetBaseAmount() {
-        String sql = "SELECT value FROM Settings WHERE name = ?";
-        String result = "";
+    public void setTeamLookbackAway(int teamId, int lookbackAway) {
+        final String sql = "UPDATE Team SET lookbackAway = ? WHERE id = ?";
+
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setString(1, "BetBaseAmount");
+            stat.setInt(1, lookbackAway);
+            stat.setInt(2, teamId);
 
 
-            ResultSet rs = stat.executeQuery();
+            stat.executeUpdate();
 
 
-            while (rs.next()) {
-                result = rs.getString("value");
-            }
-        } catch (SQLException e) {
+        } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-
-        return result;
     }
     }
 
 
-    public void updateBetStatus(int betId, Status newStatus) {
-        String sql = "UPDATE AnalysisBetTable SET status = ? WHERE id = ?";
+    public void setTeamLookbackDraw(int teamId, int lookbackDraw) {
+        final String sql = "UPDATE Team SET lookbackDraw = ? WHERE id = ?";
 
 
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setString(1, newStatus.name());
-            stat.setInt(2, betId);
+            stat.setInt(1, lookbackDraw);
+            stat.setInt(2, teamId);
 
 
             stat.executeUpdate();
             stat.executeUpdate();
-        } catch (SQLException e) {
+
+        } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
     }
     }
 
 
-    public Team getTeam(int teamId) {
-        Team result = null;
-        String sql = "SELECT t.*, c.name as countryName, l.name AS leagueName FROM Team t "
-                + "INNER JOIN Country c ON t.countryId = c.id "
-                + "INNER JOIN League l ON t.leagueId = l.id "
-                + "WHERE t.id = ? ";
+    public void setTeamLookbackHome(int teamId, int lookbackHome) {
+        final String sql = "UPDATE Team SET lookbackHome = ? WHERE id = ?";
+
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setInt(1, teamId);
+            stat.setInt(1, lookbackHome);
+            stat.setInt(2, teamId);
 
 
-            ResultSet rs = stat.executeQuery();
+            stat.executeUpdate();
 
 
-            while (rs.next()) {
-                result = new Team(rs.getInt("id"), rs.getString("name"), rs.getInt("countryId"),
-                        rs.getString("countryName"), rs.getInt("leagueId"), rs.getString("leagueName"));
-            }
-        } catch (SQLException e) {
+        } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-        return result;
     }
     }
 
 
-    public List<Bet> getAnalysisBets() {
-        List<Bet> result = new ArrayList<>();
-        String sql = "SELECT * FROM AnalysisBetTable abt "
-                + "INNER JOIN SoccerResults sr ON abt.matchId = sr.id "
-                + "WHERE status IN ('LOST', 'OPEN', 'COVERED')";
+    public void setTeamMarginAway(int teamId, int marginAway) {
+        final String sql = "UPDATE Team SET marginAway = ? WHERE id = ?";
 
 
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            ResultSet rs = stat.executeQuery();
+            stat.setInt(1, marginAway);
+            stat.setInt(2, teamId);
 
 
-            while (rs.next()) {
+            stat.executeUpdate();
 
 
-                Team homeTeam = getTeam(rs.getInt("homeTeamId"));
-                Team awayTeam = getTeam(rs.getInt("awayTeamId"));
-                SoccerMatch match = new SoccerMatch(rs.getInt("matchId"), homeTeam, awayTeam, rs.getFloat("odds1"),
-                        rs.getFloat("oddsX"), rs.getFloat("odds2"), rs.getInt("homeScore"), rs.getInt("awayScore"),
-                        LocalDateTime.parse(rs.getString("gameDate")), rs.getString("season"));
+        } catch (final SQLException e) {
+            e.printStackTrace();
+        }
+    }
 
 
-                match.setLeagueName(homeTeam.getTeamLeague());
-                match.setCountryName(homeTeam.getCountryName());
+    public void setTeamMarginDraw(int teamId, int marginDraw) {
+        final String sql = "UPDATE Team SET marginDraw = ? WHERE id = ?";
 
 
-                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")));
-            }
+        try (PreparedStatement stat = conn.prepareStatement(sql)) {
+            stat.setInt(1, marginDraw);
+            stat.setInt(2, teamId);
 
 
-        } catch (SQLException e) {
+            stat.executeUpdate();
+
+        } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-        return result;
     }
     }
 
 
-    public int addAnalysisBet(Bet bet) {
-        int newId = -1;
-        String sql = "INSERT INTO AnalysisBetTable (matchId, bet, betAmount, betOdds, status) VALUES (?,?,?,?,?)";
-
-        try (PreparedStatement stat = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
-            stat.setInt(1, bet.getMatch().getMatchId());
-            stat.setString(2, bet.getBet());
-            stat.setFloat(3, bet.getBetAmount());
-            stat.setFloat(4, bet.getBetOdds());
-            stat.setString(5, bet.getStatus().name());
-
-            stat.execute();
+    public void setTeamMarginHome(int teamId, int marginHome) {
+        final String sql = "UPDATE Team SET marginHome = ? WHERE id = ?";
 
 
-            ResultSet generatedKeys = stat.getGeneratedKeys();
+        try (PreparedStatement stat = conn.prepareStatement(sql)) {
+            stat.setInt(1, marginHome);
+            stat.setInt(2, teamId);
 
 
-            while (generatedKeys.next()) {
-                newId = generatedKeys.getInt(1);
-            }
+            stat.executeUpdate();
 
 
-        } catch (SQLException e) {
+        } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-
-        return newId;
     }
     }
 
 
-    public Bet getAnalysisBet(int betId) {
-        Bet result = null;
-        String sql = "SELECT * FROM AnalysisBetTable abt "
-                + "INNER JOIN SoccerResults sr ON abt.matchId = sr.id "
-                + "WHERE abt.id = ?";
+    public void updateBetBaseAmount(String value) {
+        String sql = "INSERT INTO Settings (name, value) VALUES (?, ?) ON DUPLICATE KEY UPDATE value = ?";
 
 
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setInt(1, betId);
-
-            ResultSet rs = stat.executeQuery();
+            stat.setString(1, "BetBaseAmount");
+            stat.setString(2, value);
+            stat.setString(3, value);
 
 
-            while (rs.next()) {
-                Team homeTeam = getTeam(rs.getInt("homeTeamId"));
-                Team awayTeam = getTeam(rs.getInt("awayTeamId"));
-                SoccerMatch match = new SoccerMatch(rs.getInt("matchId"), homeTeam, awayTeam, rs.getFloat("odds1"),
-                        rs.getFloat("oddsX"), rs.getFloat("odds2"), rs.getInt("homeScore"), rs.getInt("awayScore"),
-                        LocalDateTime.parse(rs.getString("gameDate")), rs.getString("season"));
+            stat.execute();
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+    }
 
 
-                match.setLeagueName(homeTeam.getTeamLeague());
-                match.setCountryName(homeTeam.getCountryName());
+    public void updateBetStatus(int betId, Status newStatus) {
+        String sql = "UPDATE AnalysisBetTable SET status = ? WHERE id = ?";
 
 
-                result = new Bet(rs.getInt("id"), match, rs.getString("bet"), rs.getFloat("betAmount"),
-                        rs.getFloat("betOdds"),
-                        Status.valueOf(rs.getString("status")), rs.getInt("coveredBetId"));
-            }
+        try (PreparedStatement stat = conn.prepareStatement(sql)) {
+            stat.setString(1, newStatus.name());
+            stat.setInt(2, betId);
 
 
+            stat.executeUpdate();
         } catch (SQLException e) {
         } catch (SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-
-        return result;
     }
     }
 
 
-    public void setBetCovered(int id, int coveredBetId) {
-        String sql = "UPDATE AnalysisBetTable SET coveredBetId = ? WHERE id = ?";
+    private List<String> getAllSeasons(int leagueId) {
+        List<String> returnValue = new ArrayList<>();
+        String sql = "SELECT distinct(season) FROM SoccerResults WHERE leagueId = ?";
+
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
         try (PreparedStatement stat = conn.prepareStatement(sql)) {
-            stat.setInt(1, coveredBetId);
-            stat.setInt(2, id);
+            stat.setInt(1, leagueId);
 
 
-            stat.executeUpdate();
+            ResultSet rs = stat.executeQuery();
+
+            while (rs.next()) {
+                returnValue.add(rs.getString(SEASON));
+            }
         } catch (SQLException e) {
         } catch (SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
+        return returnValue;
     }
     }
 }
 }

+ 1 - 1
OddsJavaFx/src/fxml/AnalysisTesting.fxml

@@ -53,7 +53,7 @@
                                        <children>
                                        <children>
                                           <Button fx:id="checkBetsButton" mnemonicParsing="false" onAction="#CheckBetsAction" text="Check bets" />
                                           <Button fx:id="checkBetsButton" mnemonicParsing="false" onAction="#CheckBetsAction" text="Check bets" />
                                           <Button mnemonicParsing="false" onAction="#RemoveDoneBetsAction" text="Remove Done bets" />
                                           <Button mnemonicParsing="false" onAction="#RemoveDoneBetsAction" text="Remove Done bets" />
-                                          <TableView fx:id="LeagueBetStatsTable" prefHeight="200.0" prefWidth="200.0">
+                                          <TableView fx:id="leagueBetStatsTable" prefHeight="200.0" prefWidth="200.0">
                                             <columns>
                                             <columns>
                                               <TableColumn fx:id="statsLeagueNameColumn" prefWidth="75.0" text="League" />
                                               <TableColumn fx:id="statsLeagueNameColumn" prefWidth="75.0" text="League" />
                                               <TableColumn fx:id="statsHomeWinColumn" prefWidth="75.0" text="Home Wins" />
                                               <TableColumn fx:id="statsHomeWinColumn" prefWidth="75.0" text="Home Wins" />

+ 1 - 0
OddsJavaFx/src/fxml/Testing.fxml

@@ -67,6 +67,7 @@
                                     <Button onAction="#goalDiffTest" text="GoalDiff" />
                                     <Button onAction="#goalDiffTest" text="GoalDiff" />
                                     <Button onAction="#relevanceTest" text="Test for Relevance" />
                                     <Button onAction="#relevanceTest" text="Test for Relevance" />
                                     <Button onAction="#analysisTets" text="Analysis Test" />
                                     <Button onAction="#analysisTets" text="Analysis Test" />
+                                    <Button onAction="#analysisDrawTests" text="Analysis DRAW Test" />
                                     
                                     
                                  </children>
                                  </children>
                               </VBox>
                               </VBox>

+ 88 - 47
OddsJavaFx/src/objects/League.java

@@ -19,15 +19,56 @@ public class League {
     int scoringTotal;
     int scoringTotal;
     int winLossRatioHomeAndAway;
     int winLossRatioHomeAndAway;
     int winLossRatio;
     int winLossRatio;
+    private int drawDiffHomeAway;
+    private int drawTotalGoals;
+    private int drawWinningForm;
+    private int drawWinningFormHomeAway;
 
 
     public League(int leagueId, String leagueName, int scoringDiffLastGame,
     public League(int leagueId, String leagueName, int scoringDiffLastGame,
-            int scoringTotal, int winLossRatioHomeAndAway, int winLossRatio) {
+            int scoringTotal, int winLossRatioHomeAndAway, int winLossRatio, int drawDiffHomeAway, int drawTotalGoals,
+            int drawWinningForm, int drawWinningFormHomeAway) {
         this.leagueId = leagueId;
         this.leagueId = leagueId;
         this.leagueName = leagueName;
         this.leagueName = leagueName;
         this.scoringDiffLastGame = scoringDiffLastGame;
         this.scoringDiffLastGame = scoringDiffLastGame;
         this.scoringTotal = scoringTotal;
         this.scoringTotal = scoringTotal;
         this.winLossRatioHomeAndAway = winLossRatioHomeAndAway;
         this.winLossRatioHomeAndAway = winLossRatioHomeAndAway;
         this.winLossRatio = winLossRatio;
         this.winLossRatio = winLossRatio;
+        this.drawDiffHomeAway = drawDiffHomeAway;
+        this.drawTotalGoals = drawTotalGoals;
+        this.drawWinningForm = drawWinningForm;
+        this.drawWinningFormHomeAway = drawWinningFormHomeAway;
+    }
+
+    public int getBetMargin() {
+        return betMargin;
+    }
+
+    public int getBetMarginAway() {
+        return betMarginAway;
+    }
+
+    public int getBetMarginDraw() {
+        return betMarginDraw;
+    }
+
+    public int getBetMarginHome() {
+        return betMarginHome;
+    }
+
+    public int getDrawDiffHomeAway() {
+        return drawDiffHomeAway;
+    }
+
+    public int getDrawTotalGoals() {
+        return drawTotalGoals;
+    }
+
+    public int getDrawWinningForm() {
+        return drawWinningForm;
+    }
+
+    public int getDrawWinningFormHomeAway() {
+        return drawWinningFormHomeAway;
     }
     }
 
 
     public int getLeagueId() {
     public int getLeagueId() {
@@ -42,88 +83,88 @@ public class League {
         return lookback;
         return lookback;
     }
     }
 
 
-    public int getBetMargin() {
-        return betMargin;
+    public int getLookbackAway() {
+        return lookbackAway;
     }
     }
 
 
-    public void setLeagueId(int leagueId) {
-        this.leagueId = leagueId;
+    public int getLookbackDraw() {
+        return lookbackDraw;
     }
     }
 
 
-    public void setLeagueName(String leagueName) {
-        this.leagueName = leagueName;
+    public int getLookbackHome() {
+        return lookbackHome;
     }
     }
 
 
-    public void setLookback(int lookback) {
-        this.lookback = lookback;
+    public int getScoringDiffLastGame() {
+        return scoringDiffLastGame;
     }
     }
 
 
-    public void setBetMargin(int betMargin) {
-        this.betMargin = betMargin;
+    public int getScoringTotal() {
+        return scoringTotal;
     }
     }
 
 
-    public int getLookbackHome() {
-        return lookbackHome;
+    public int getWinLossRatio() {
+        return winLossRatio;
     }
     }
 
 
-    public int getLookbackDraw() {
-        return lookbackDraw;
+    public int getWinLossRatioHomeAndAway() {
+        return winLossRatioHomeAndAway;
     }
     }
 
 
-    public int getLookbackAway() {
-        return lookbackAway;
+    public void setBetMargin(int betMargin) {
+        this.betMargin = betMargin;
     }
     }
 
 
-    public int getBetMarginHome() {
-        return betMarginHome;
+    public void setBetMarginAway(int betMarginAway) {
+        this.betMarginAway = betMarginAway;
     }
     }
 
 
-    public int getBetMarginDraw() {
-        return betMarginDraw;
+    public void setBetMarginDraw(int betMarginDraw) {
+        this.betMarginDraw = betMarginDraw;
     }
     }
 
 
-    public int getBetMarginAway() {
-        return betMarginAway;
+    public void setBetMarginHome(int betMarginHome) {
+        this.betMarginHome = betMarginHome;
     }
     }
 
 
-    public void setLookbackHome(int lookbackHome) {
-        this.lookbackHome = lookbackHome;
+    public void setDrawDiffHomeAway(int drawDiffHomeAway) {
+        this.drawDiffHomeAway = drawDiffHomeAway;
     }
     }
 
 
-    public void setLookbackDraw(int lookbackDraw) {
-        this.lookbackDraw = lookbackDraw;
+    public void setDrawTotalGoals(int drawTotalGoals) {
+        this.drawTotalGoals = drawTotalGoals;
     }
     }
 
 
-    public void setLookbackAway(int lookbackAway) {
-        this.lookbackAway = lookbackAway;
+    public void setDrawWinningForm(int drawWinningForm) {
+        this.drawWinningForm = drawWinningForm;
     }
     }
 
 
-    public void setBetMarginHome(int betMarginHome) {
-        this.betMarginHome = betMarginHome;
+    public void setDrawWinningFormHomeAway(int drawWinningFormHomeAway) {
+        this.drawWinningFormHomeAway = drawWinningFormHomeAway;
     }
     }
 
 
-    public void setBetMarginDraw(int betMarginDraw) {
-        this.betMarginDraw = betMarginDraw;
+    public void setLeagueId(int leagueId) {
+        this.leagueId = leagueId;
     }
     }
 
 
-    public void setBetMarginAway(int betMarginAway) {
-        this.betMarginAway = betMarginAway;
+    public void setLeagueName(String leagueName) {
+        this.leagueName = leagueName;
     }
     }
 
 
-    public int getScoringDiffLastGame() {
-        return scoringDiffLastGame;
+    public void setLookback(int lookback) {
+        this.lookback = lookback;
     }
     }
 
 
-    public int getScoringTotal() {
-        return scoringTotal;
+    public void setLookbackAway(int lookbackAway) {
+        this.lookbackAway = lookbackAway;
     }
     }
 
 
-    public int getWinLossRatioHomeAndAway() {
-        return winLossRatioHomeAndAway;
+    public void setLookbackDraw(int lookbackDraw) {
+        this.lookbackDraw = lookbackDraw;
     }
     }
 
 
-    public int getWinLossRatio() {
-        return winLossRatio;
+    public void setLookbackHome(int lookbackHome) {
+        this.lookbackHome = lookbackHome;
     }
     }
 
 
     public void setScoringDiffLastGame(int scoringDiffLastGame) {
     public void setScoringDiffLastGame(int scoringDiffLastGame) {
@@ -134,12 +175,12 @@ public class League {
         this.scoringTotal = scoringTotal;
         this.scoringTotal = scoringTotal;
     }
     }
 
 
-    public void setWinLossRatioHomeAndAway(int winLossRatioHomeAndAway) {
-        this.winLossRatioHomeAndAway = winLossRatioHomeAndAway;
-    }
-
     public void setWinLossRatio(int winLossRatio) {
     public void setWinLossRatio(int winLossRatio) {
         this.winLossRatio = winLossRatio;
         this.winLossRatio = winLossRatio;
     }
     }
 
 
+    public void setWinLossRatioHomeAndAway(int winLossRatioHomeAndAway) {
+        this.winLossRatioHomeAndAway = winLossRatioHomeAndAway;
+    }
+
 }
 }

+ 99 - 80
OddsJavaFx/src/objects/bets/Bet.java

@@ -4,10 +4,18 @@ import objects.SoccerMatch;
 
 
 public class Bet {
 public class Bet {
 
 
+    public static enum Status {
+        DONE,
+        OPEN,
+        LOST,
+        COVERED,
+        SPLIT
+    }
+
     SoccerMatch match;
     SoccerMatch match;
     float betAmount;
     float betAmount;
-    float betOdds;
 
 
+    float betOdds;
     int id;
     int id;
     String homeTeamName;
     String homeTeamName;
     String awayTeamName;
     String awayTeamName;
@@ -17,15 +25,10 @@ public class Bet {
     int coveredBetId;
     int coveredBetId;
     String bet;
     String bet;
 
 
+    int betCoveredNumber;
     Status status;
     Status status;
 
 
-    public static enum Status {
-        DONE,
-        OPEN,
-        LOST,
-        COVERED,
-        SPLIT
-    }
+    public boolean resolved = false;
 
 
     public Bet(int id, SoccerMatch match, String bet, float betAmount, float betOdds) {
     public Bet(int id, SoccerMatch match, String bet, float betAmount, float betOdds) {
         this(id, match, bet, betAmount, betOdds, Status.OPEN, -1);
         this(id, match, bet, betAmount, betOdds, Status.OPEN, -1);
@@ -48,60 +51,66 @@ public class Bet {
         this.coveredBetId = coveredBetId;
         this.coveredBetId = coveredBetId;
     }
     }
 
 
-    public int getId() {
-        return id;
-    }
-
-    public void setId(int id) {
-        this.id = id;
+    public boolean correctBet() {
+        boolean result = false;
+        if (isBetOnHomeTeam() && match.getHomeScore() > match.getAwayScore()) {
+            result = true;
+        }
+        if (isBetOnDraw() && match.getHomeScore() == match.getAwayScore()) {
+            result = true;
+        }
+        if (isBetOnAwayTeam() && match.getHomeScore() < match.getAwayScore()) {
+            result = true;
+        }
+        return result;
     }
     }
 
 
-    public SoccerMatch getMatch() {
-        return match;
+    public int getAwayScore() {
+        return awayScore;
     }
     }
 
 
-    public float getBetAmount() {
-        return betAmount;
+    public String getAwayTeamName() {
+        return awayTeamName;
     }
     }
 
 
-    public float getBetOdds() {
-        return betOdds;
+    public String getBet() {
+        return bet;
     }
     }
 
 
-    public boolean isBetOnHomeTeam() {
-        return bet.equals("1");
+    public float getBetAmount() {
+        return betAmount;
     }
     }
 
 
-    public boolean isBetOnDraw() {
-        return bet.equals("X");
+    public int getBetCoveredNumber() {
+        return betCoveredNumber;
     }
     }
 
 
-    public boolean isBetOnAwayTeam() {
-        return bet.equals("2");
+    public float getBetOdds() {
+        return betOdds;
     }
     }
 
 
-    public void setMatch(SoccerMatch match) {
-        this.match = match;
+    public int getCoveredBetId() {
+        return coveredBetId;
     }
     }
 
 
-    public void setBetAmount(float betAmount) {
-        this.betAmount = betAmount;
+    public int getHomeScore() {
+        return homeScore;
     }
     }
 
 
-    public void setBetOdds(float betOdds) {
-        this.betOdds = betOdds;
+    public String getHomeTeamName() {
+        return homeTeamName;
     }
     }
 
 
-    public void setBetOnHomeTeam() {
-        this.bet = "1";
+    public int getId() {
+        return id;
     }
     }
 
 
-    public void setBetOnDraw() {
-        this.bet = "X";
+    public SoccerMatch getMatch() {
+        return match;
     }
     }
 
 
-    public void setBetOnAwayTeam() {
-        this.bet = "2";
+    public String getMatchup() {
+        return matchup;
     }
     }
 
 
     public float getResult() {
     public float getResult() {
@@ -117,86 +126,96 @@ public class Bet {
         return result;
         return result;
     }
     }
 
 
-    public boolean correctBet() {
-        boolean result = false;
-        if (isBetOnHomeTeam() && match.getHomeScore() > match.getAwayScore()) {
-            result = true;
-        }
-        if (isBetOnDraw() && match.getHomeScore() == match.getAwayScore()) {
-            result = true;
-        }
-        if (isBetOnAwayTeam() && match.getHomeScore() < match.getAwayScore()) {
-            result = true;
-        }
-        return result;
+    public Status getStatus() {
+        return status;
     }
     }
 
 
-    protected boolean isDrawResult() {
-        return match.getHomeScore() == match.getAwayScore();
+    public boolean isBetOnAwayTeam() {
+        return bet.equals("2");
     }
     }
 
 
-    public String getHomeTeamName() {
-        return homeTeamName;
+    public boolean isBetOnDraw() {
+        return bet.equals("X");
     }
     }
 
 
-    public String getAwayTeamName() {
-        return awayTeamName;
+    public boolean isBetOnHomeTeam() {
+        return bet.equals("1");
     }
     }
 
 
-    public String getMatchup() {
-        return matchup;
+    public boolean isResolved() {
+        return resolved;
     }
     }
 
 
-    public void setHomeTeamName(String homeTeamName) {
-        this.homeTeamName = homeTeamName;
+    public void setAwayScore(int awayScore) {
+        this.awayScore = awayScore;
     }
     }
 
 
     public void setAwayTeamName(String awayTeamName) {
     public void setAwayTeamName(String awayTeamName) {
         this.awayTeamName = awayTeamName;
         this.awayTeamName = awayTeamName;
     }
     }
 
 
-    public void setMatchup() {
-        this.matchup = homeTeamName + " - " + awayTeamName;
+    public void setBet(String bet) {
+        this.bet = bet;
     }
     }
 
 
-    public int getHomeScore() {
-        return homeScore;
+    public void setBetAmount(float betAmount) {
+        this.betAmount = betAmount;
     }
     }
 
 
-    public int getAwayScore() {
-        return awayScore;
+    public void setBetCoveredNumber(int betCoverNumber) {
+        this.betCoveredNumber = betCoverNumber;
+    }
+
+    public void setBetOdds(float betOdds) {
+        this.betOdds = betOdds;
+    }
+
+    public void setBetOnAwayTeam() {
+        this.bet = "2";
+    }
+
+    public void setBetOnDraw() {
+        this.bet = "X";
+    }
+
+    public void setBetOnHomeTeam() {
+        this.bet = "1";
+    }
+
+    public void setCoveredBetId(int coveredBetId) {
+        this.coveredBetId = coveredBetId;
     }
     }
 
 
     public void setHomeScore(int homeScore) {
     public void setHomeScore(int homeScore) {
         this.homeScore = homeScore;
         this.homeScore = homeScore;
     }
     }
 
 
-    public void setAwayScore(int awayScore) {
-        this.awayScore = awayScore;
+    public void setHomeTeamName(String homeTeamName) {
+        this.homeTeamName = homeTeamName;
     }
     }
 
 
-    public Status getStatus() {
-        return status;
+    public void setId(int id) {
+        this.id = id;
     }
     }
 
 
-    public void setStatus(Status status) {
-        this.status = status;
+    public void setMatch(SoccerMatch match) {
+        this.match = match;
     }
     }
 
 
-    public int getCoveredBetId() {
-        return coveredBetId;
+    public void setMatchup() {
+        this.matchup = homeTeamName + " - " + awayTeamName;
     }
     }
 
 
-    public void setCoveredBetId(int coveredBetId) {
-        this.coveredBetId = coveredBetId;
+    public void setResolved(boolean resolved) {
+        this.resolved = resolved;
     }
     }
 
 
-    public String getBet() {
-        return bet;
+    public void setStatus(Status status) {
+        this.status = status;
     }
     }
 
 
-    public void setBet(String bet) {
-        this.bet = bet;
+    protected boolean isDrawResult() {
+        return match.getHomeScore() == match.getAwayScore();
     }
     }
 
 
 }
 }

+ 302 - 304
OddsJavaFx/src/parser/OddsPortal.java

@@ -26,308 +26,306 @@ import object.ResultDTO;
 
 
 public class OddsPortal implements ParserJoinedFunctions {
 public class OddsPortal implements ParserJoinedFunctions {
 
 
-	private LocalDateTime baseDate;
-	private int currentParsePage;
-	private int sportId;
-	private int countryId;
-	private int leagueId;
-	private LocalDateTime gameDate;
-
-	// https://stackoverflow.com/questions/14439991/skip-particular-javascript-execution-in-html-unit
-	// Skip url
-	public void getMatchesByDate(String date) {
-		final String soccerUrl = "https://oddsportal.com/matches/soccer/" + date;
-		// final String hockeyUrl = "https://oddsportal.com/matches/hockey/" + date;
-
-		final WebClient webClient = new WebClient();
-		webClient.getOptions().setUseInsecureSSL(true);
-		webClient.getOptions().setCssEnabled(false);
-		webClient.getOptions().setJavaScriptEnabled(true);
-		webClient.getOptions().setThrowExceptionOnScriptError(false);
-		Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF);
-
-		webClient.waitForBackgroundJavaScript(3000);
-		parseSoccerMatches(soccerUrl, webClient);
-
-		webClient.close();
-	}
-
-	private void parseSoccerMatches(final String soccerUrl, final WebClient webClient) {
-		try {
-			System.out.println("Getting Webpage");
-			final HtmlPage soccerMatches = webClient.getPage(soccerUrl);
-			final HtmlTable matchesTable = soccerMatches.getFirstByXPath("//table[contains(@class, table-main)]");
-			final List<HtmlTableRow> rows = matchesTable.getRows();
-			String countryName = "";
-			String leagueName = "";
-			int i = 1;
-			final int size = rows.size();
-			for (final HtmlTableRow tr : rows) {
-				System.out.println("Processing " + i++ + " of " + size);
-				if (tr.getAttribute("class").equals("dark center")) {
-					final List<HtmlAnchor> countryLeague = tr.getByXPath(".//a");
-					countryName = countryLeague.get(0).getTextContent().toLowerCase().trim();
-					leagueName = countryLeague.get(1).getTextContent().toLowerCase().trim();
-					leagueName = leagueName.replaceAll(" ", "-");
-					leagueName = leagueName.replaceAll("\\.", "");
-					countryName = countryName.replaceAll(" ", "-");
-					countryName = countryName.replaceAll("\\.", "");
-				} else {
-					final List<HtmlTableCell> cells = tr.getCells();
-					final String[] time = cells.get(0).getTextContent().split(":");
-					final String[] teams = cells.get(1).getTextContent().split(" - ");
-					float odds1 = 0F;
-					float oddsX = 0F;
-					float odds2 = 0F;
-					int homeScore = -1;
-					int awayScore = -1;
-					boolean overtime = false;
-
-					boolean abandon = false;
-
-					try {
-						for (final HtmlTableCell tc : cells) {
-							if (tc.getAttribute("class").contains("live-score")) {
-								abandon = true;
-								break;
-							}
-							// Score
-							if (tc.getAttribute("class").contains("table-score")) {
-								final String[] scoreValue = tc.getTextContent().split(":");
-								homeScore = Integer.valueOf(scoreValue[0]);
-								if (scoreValue[1].matches("\\D+")) {
-									overtime = true;
-								}
-								awayScore = Integer.valueOf(scoreValue[1].replaceAll("\\D+", ""));
-							}
-							if (tc.getAttribute("class").contains("odds-nowrp")) {
-								if (tc.getTextContent().matches("[+-][0-9][0-9][0-9]")) {
-									if (odds1 == 0F) {
-										odds1 = convertAmericanOddsToDecimal(Integer.valueOf(tc.getTextContent()));
-									} else if (oddsX == 0F) {
-										oddsX = convertAmericanOddsToDecimal(Integer.valueOf(tc.getTextContent()));
-									} else if (odds2 == 0F) {
-										odds2 = convertAmericanOddsToDecimal(Integer.valueOf(tc.getTextContent()));
-									}
-								} else if (tc.getTextContent().matches("[0-9].[0-9]+")) {
-									if (odds1 == 0F) {
-										odds1 = Float.valueOf(tc.getTextContent());
-									} else if (oddsX == 0F) {
-										oddsX = Float.valueOf(tc.getTextContent());
-									} else if (odds2 == 0F) {
-										odds2 = Float.valueOf(tc.getTextContent());
-									}
-								}
-							}
-
-						}
-					} catch (final NumberFormatException e) {
-						System.out
-								.println("Failed to get the match between " + teams[0].trim() + " and "
-										+ teams[1].trim() + " at "
-										+ baseDate.withHour(Integer.valueOf(time[0]))
-												.withMinute(Integer.valueOf(time[1]))
-										+ " odds1: " + odds1 + " oddsX: " + oddsX + " odds2: " + odds2 + " homeScore "
-										+ homeScore + " awayScore " + awayScore + " overtime: "
-										+ (overtime ? "true" : "false"));
-						continue;
-					}
-
-					if (abandon) {
-						continue;
-					}
-					final Mysql mysql = Mysql.getInstance();
-					final int leagueId = mysql.addLeague(leagueName, countryName, "soccer");
-					final int countryId = mysql.getCountryId(countryName);
-					final int sportId = mysql.getSportId("soccer");
-
-					String season = mysql.getLastParsedYear(leagueName, countryId);
-
-					if (Strings.isNullOrEmpty(season)) {
-						season = String.valueOf(LocalDateTime.now().getYear());
-					}
-
-					final LocalDateTime dt = baseDate.withHour(Integer.valueOf(time[0]))
-							.withMinute(Integer.valueOf(time[1])).withSecond(0).withNano(0);
-					mysql.addResult(new ResultDTO("SoccerResults", dt, teams[0].trim(), teams[1].trim(), homeScore,
-							awayScore, overtime, odds1, oddsX, odds2, countryId, season, leagueId, sportId));
-				}
-			}
-		} catch (FailingHttpStatusCodeException | IOException e) {
-			e.printStackTrace();
-		} catch (final SQLException e) {
-			e.printStackTrace();
-		}
-	}
-
-	public void getHistoricMatches(String sport, String country, String league, String year) {
-		final String url = "https://www.oddsportal.com/";
-		final String resultsPage = "/results";
-		final WebClient webClient = new WebClient();
-		webClient.getOptions().setUseInsecureSSL(true);
-		webClient.getOptions().setCssEnabled(false);
-		webClient.getOptions().setJavaScriptEnabled(true);
-		webClient.getOptions().setThrowExceptionOnScriptError(false);
-		Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF);
-
-		league = league.replaceAll(" ", "-");
-		league = league.replaceAll("\\.", "");
-		country = country.replaceAll(" ", "-");
-		league = league.replaceAll("\\.", "");
-		final Mysql mysql = Mysql.getInstance();
-
-		currentParsePage = 1;
-
-		final String urlYearPart;
-		if (year.equals(String.valueOf(LocalDate.now().getYear()))) {
-			urlYearPart = "";
-		} else {
-			urlYearPart = "-" + year;
-		}
-
-		try {
-			sportId = mysql.getSportId(sport);
-			countryId = mysql.getCountryId(country);
-			leagueId = mysql.getLeagueId(sportId, countryId, league);
-			String season = "";
-
-			final HtmlPage leaguePage = webClient
-					.getPage(url + "/" + sport + "/" + country + "/" + league + urlYearPart + resultsPage);
-			final List<HtmlAnchor> yearFilter = leaguePage.getByXPath("//ul[contains(@class,'main-filter')]//a");
-			for (final HtmlAnchor a : yearFilter) {
-				System.out.println("Year filter: " + a.getHrefAttribute());
-				final String active = ((HtmlSpan) a.getParentNode().getParentNode()).getAttribute("class");
-				if (active.contains("active") && !active.contains("inactive")) {
-					season = a.getTextContent();
-					year = season.replace('/', '-');
-				}
-			}
-
-			HtmlDivision tournamentTableDiv = leaguePage.getHtmlElementById("tournamentTable");
-			HtmlTable tournamentTable = (HtmlTable) tournamentTableDiv.getFirstChild();
-
-			gameDate = LocalDateTime.now();
-			final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd MMM yyyy", Locale.ENGLISH);
-			parseTournamentTable(sportId, countryId, leagueId, season, tournamentTable, gameDate, dateFormatter);
-			final HtmlDivision paginationLinksDiv = (HtmlDivision) tournamentTableDiv.getLastChild();
-			final List<HtmlAnchor> pagiantionLinks = paginationLinksDiv
-					.getByXPath(".//a[contains(@href, 'page') and not(.//span[contains(@class, 'arrow')])]");
-			for (final HtmlAnchor a : pagiantionLinks) {
-				System.out.println("Continuing with Pagination: " + a.getHrefAttribute());
-				// When done with start page click pagiantion
-				final int parsePage = Integer.valueOf(a.getTextContent());
-				if (parsePage > currentParsePage) {
-					a.click();
-					webClient.waitForBackgroundJavaScript(1000);
-
-					tournamentTableDiv = leaguePage.getHtmlElementById("tournamentTable");
-					tournamentTable = (HtmlTable) tournamentTableDiv.getFirstChild();
-					parseTournamentTable(sportId, countryId, leagueId, season, tournamentTable, gameDate,
-							dateFormatter);
-					currentParsePage = parsePage;
-				}
-				// process new tournament table content
-			}
-		} catch (FailingHttpStatusCodeException | IOException e) {
-			e.printStackTrace();
-		} catch (final SQLException sqle) {
-			sqle.printStackTrace();
-		} catch (final ClassCastException cce) {
-			System.out.println("No pagination table");
-			// cce.printStackTrace();
-		} finally {
-			Mysql.getInstance().setParsingForLeague(leagueId, sportId, countryId, gameDate, currentParsePage, year);
-		}
-		webClient.close();
-		System.out.println("DONE with " + country + " (" + countryId + ") league " + league + "(" + leagueId + ")");
-	}
-
-	private void parseTournamentTable(int sportId, int countryId, int leagueId, String season,
-			HtmlTable tournamentTable, LocalDateTime gameDate, DateTimeFormatter dateFormatter) throws SQLException {
-		for (final HtmlTableRow tr : tournamentTable.getRows()) {
-			if (tr.getAttribute("class").contains("deactivate")) {
-				String homeTeam;
-				String awayTeam;
-				int homeScore = -1;
-				int awayScore = -1;
-				float odds1 = 0f;
-				float oddsX = 0f;
-				float odds2 = 0f;
-				boolean overtime = false;
-
-				final HtmlTableCell timeCell = tr.getCell(0);
-				final HtmlTableCell participantsCell = tr.getCell(1);
-
-				// Game Time
-				final String[] timeValue = timeCell.getTextContent().split(":");
-				gameDate = gameDate.withHour(Integer.valueOf(timeValue[0]));
-				gameDate = gameDate.withMinute(Integer.valueOf(timeValue[1]));
-
-				// Teams
-				final String[] participantsValue = participantsCell.getTextContent().split(" - ");
-				homeTeam = participantsValue[0].trim();
-				awayTeam = participantsValue[1].trim();
-
-				final List<HtmlTableCell> cells = tr.getCells();
-				for (final HtmlTableCell tc : cells) {
-					// Score
-					if (tc.getAttribute("class").contains("table-score")) {
-						final String[] scoreValue = tc.getTextContent().split(":");
-						if (scoreValue[0].matches("\\D+")) {
-							continue;
-						}
-						homeScore = Integer.valueOf(scoreValue[0]);
-						if (scoreValue[1].matches("\\D+")) {
-							overtime = true;
-						}
-						awayScore = Integer.valueOf(scoreValue[1].replaceAll("\\D+", ""));
-					}
-
-					if (tc.getAttribute("class").contains("odds-nowrp")) {
-						if (tc.getTextContent().matches("[+-][0-9][0-9][0-9]")) {
-							if (odds1 == 0F) {
-								odds1 = convertAmericanOddsToDecimal(Integer.valueOf(tc.getTextContent()));
-							} else if (oddsX == 0F) {
-								oddsX = convertAmericanOddsToDecimal(Integer.valueOf(tc.getTextContent()));
-							} else if (odds2 == 0F) {
-								odds2 = convertAmericanOddsToDecimal(Integer.valueOf(tc.getTextContent()));
-							}
-						} else if (tc.getTextContent().matches("[0-9].[0-9]+")) {
-							if (odds1 == 0F) {
-								odds1 = Float.valueOf(tc.getTextContent());
-							} else if (oddsX == 0F) {
-								oddsX = Float.valueOf(tc.getTextContent());
-							} else if (odds2 == 0F) {
-								odds2 = Float.valueOf(tc.getTextContent());
-							}
-						}
-					}
-				}
-
-				if (gameDate != null && homeTeam != null && awayTeam != null && odds1 != 0 && oddsX != 0 && odds2 != 0
-						&& !Strings.isNullOrEmpty(season)) { // All set.. update sql result table
-					System.out.println("Adding game between " + homeTeam + " and " + awayTeam + " with score "
-							+ homeScore + "-" + awayScore);
-					Mysql.getInstance().addResult(new ResultDTO("SoccerResults", gameDate, homeTeam, awayTeam,
-							homeScore, awayScore, overtime, odds1, oddsX, odds2, countryId, season, leagueId, sportId));
-				} else {
-					System.out.println(String.format(
-							"Not adding, missing somethind.. gameDate: %s, homeTeam %s, awayTeam %s, odds1 %s, oddsX %s, odds2 %s, "
-									+ "season %s",
-							gameDate, homeTeam, awayTeam, odds1, oddsX, odds2, season));
-				}
-
-			} else if (tr.getAttribute("class").contains("center nob-border")) { // Datum rader
-				final List<HtmlSpan> dateSpan = tr.getByXPath(".//span[contains(@class, 'datet')]");
-				final String dateString = dateSpan.get(0).getTextContent();
-				if (dateString.toLowerCase().contains("yesterday")) {
-					gameDate = LocalDateTime.now().minusDays(1);
-				} else if (dateString.toLowerCase().contains("today")) {
-					gameDate = LocalDateTime.now();
-				} else {
-					gameDate = LocalDate.parse(dateString, dateFormatter).atStartOfDay();
-				}
-			}
-		}
-	}
+    private LocalDateTime baseDate;
+    private int currentParsePage;
+    private int sportId;
+    private int countryId;
+    private int leagueId;
+    private LocalDateTime gameDate;
+
+    public void getHistoricMatches(String sport, String country, String league, String year) {
+        final String url = "https://www.oddsportal.com/";
+        final String resultsPage = "/results";
+        final WebClient webClient = new WebClient();
+        webClient.getOptions().setUseInsecureSSL(true);
+        webClient.getOptions().setCssEnabled(false);
+        webClient.getOptions().setJavaScriptEnabled(true);
+        webClient.getOptions().setThrowExceptionOnScriptError(false);
+        Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF);
+
+        league = league.replaceAll(" ", "-");
+        league = league.replaceAll("\\.", "");
+        country = country.replaceAll(" ", "-");
+        league = league.replaceAll("\\.", "");
+        final Mysql mysql = Mysql.getInstance();
+
+        currentParsePage = 1;
+
+        final String urlYearPart;
+        if (year.equals(String.valueOf(LocalDate.now().getYear()))) {
+            urlYearPart = "";
+        } else {
+            urlYearPart = "-" + year;
+        }
+
+        try {
+            sportId = mysql.getSportId(sport);
+            countryId = mysql.getCountryId(country);
+            leagueId = mysql.getLeagueId(sportId, countryId, league);
+            String season = "";
+
+            final HtmlPage leaguePage = webClient
+                    .getPage(url + "/" + sport + "/" + country + "/" + league + urlYearPart + resultsPage);
+            final List<HtmlAnchor> yearFilter = leaguePage.getByXPath("//ul[contains(@class,'main-filter')]//a");
+            for (final HtmlAnchor a : yearFilter) {
+                System.out.println("Year filter: " + a.getHrefAttribute());
+                final String active = ((HtmlSpan) a.getParentNode().getParentNode()).getAttribute("class");
+                if (active.contains("active") && !active.contains("inactive")) {
+                    season = a.getTextContent();
+                    year = season.replace('/', '-');
+                }
+            }
+
+            HtmlDivision tournamentTableDiv = leaguePage.getHtmlElementById("tournamentTable");
+            HtmlTable tournamentTable = (HtmlTable) tournamentTableDiv.getFirstChild();
+
+            gameDate = LocalDateTime.now();
+            final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd MMM yyyy", Locale.ENGLISH);
+            parseTournamentTable(sportId, countryId, leagueId, season, tournamentTable, gameDate, dateFormatter);
+            final HtmlDivision paginationLinksDiv = (HtmlDivision) tournamentTableDiv.getLastChild();
+            final List<HtmlAnchor> pagiantionLinks = paginationLinksDiv
+                    .getByXPath(".//a[contains(@href, 'page') and not(.//span[contains(@class, 'arrow')])]");
+            for (final HtmlAnchor a : pagiantionLinks) {
+                System.out.println("Continuing with Pagination: " + a.getHrefAttribute());
+                // When done with start page click pagiantion
+                final int parsePage = Integer.valueOf(a.getTextContent());
+                if (parsePage > currentParsePage) {
+                    a.click();
+                    webClient.waitForBackgroundJavaScript(1000);
+
+                    tournamentTableDiv = leaguePage.getHtmlElementById("tournamentTable");
+                    tournamentTable = (HtmlTable) tournamentTableDiv.getFirstChild();
+                    parseTournamentTable(sportId, countryId, leagueId, season, tournamentTable, gameDate,
+                            dateFormatter);
+                    currentParsePage = parsePage;
+                }
+                // process new tournament table content
+            }
+        } catch (FailingHttpStatusCodeException | IOException e) {
+            e.printStackTrace();
+        } catch (final SQLException sqle) {
+            sqle.printStackTrace();
+        } catch (final ClassCastException cce) {
+            System.out.println("No pagination table");
+            // cce.printStackTrace();
+        } finally {
+            Mysql.getInstance().setParsingForLeague(leagueId, sportId, countryId, gameDate, currentParsePage, year);
+        }
+        webClient.close();
+        System.out.println("DONE with " + country + " (" + countryId + ") league " + league + "(" + leagueId + ")");
+    }
+
+    // https://stackoverflow.com/questions/14439991/skip-particular-javascript-execution-in-html-unit
+    // Skip url
+    public void getMatchesByDate(String date) {
+        final String soccerUrl = "https://oddsportal.com/matches/soccer/" + date;
+        // final String hockeyUrl = "https://oddsportal.com/matches/hockey/" + date;
+
+        final WebClient webClient = new WebClient();
+        webClient.getOptions().setUseInsecureSSL(true);
+        webClient.getOptions().setCssEnabled(false);
+        webClient.getOptions().setJavaScriptEnabled(true);
+        webClient.getOptions().setThrowExceptionOnScriptError(false);
+        Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF);
+
+        webClient.waitForBackgroundJavaScript(3000);
+        parseSoccerMatches(soccerUrl, webClient);
+
+        webClient.close();
+    }
+
+    private void parseSoccerMatches(final String soccerUrl, final WebClient webClient) {
+        try {
+            System.out.println("Getting Webpage");
+            final HtmlPage soccerMatches = webClient.getPage(soccerUrl);
+            final HtmlTable matchesTable = soccerMatches.getFirstByXPath("//table[contains(@class, table-main)]");
+            final List<HtmlTableRow> rows = matchesTable.getRows();
+            String countryName = "";
+            String leagueName = "";
+            int i = 1;
+            final int size = rows.size();
+            for (final HtmlTableRow tr : rows) {
+                System.out.println("Processing " + i++ + " of " + size);
+                if (tr.getAttribute("class").equals("dark center")) {
+                    final List<HtmlAnchor> countryLeague = tr.getByXPath(".//a");
+                    countryName = countryLeague.get(0).getTextContent().toLowerCase().trim();
+                    leagueName = countryLeague.get(1).getTextContent().toLowerCase().trim();
+                    leagueName = leagueName.replaceAll(" ", "-");
+                    leagueName = leagueName.replaceAll("\\.", "");
+                    countryName = countryName.replaceAll(" ", "-");
+                    countryName = countryName.replaceAll("\\.", "");
+                } else {
+                    final List<HtmlTableCell> cells = tr.getCells();
+                    final String[] time = cells.get(0).getTextContent().split(":");
+                    final String[] teams = cells.get(1).getTextContent().split(" - ");
+                    float odds1 = 0F;
+                    float oddsX = 0F;
+                    float odds2 = 0F;
+                    int homeScore = -1;
+                    int awayScore = -1;
+                    boolean overtime = false;
+
+                    boolean abandon = false;
+
+                    try {
+                        for (final HtmlTableCell tc : cells) {
+                            if (tc.getAttribute("class").contains("live-score")) {
+                                abandon = true;
+                                break;
+                            }
+                            // Score
+                            if (tc.getAttribute("class").contains("table-score")) {
+                                final String[] scoreValue = tc.getTextContent().split(":");
+                                homeScore = Integer.valueOf(scoreValue[0]);
+                                if (scoreValue[1].matches("\\D+")) {
+                                    overtime = true;
+                                }
+                                awayScore = Integer.valueOf(scoreValue[1].replaceAll("\\D+", ""));
+                            }
+                            if (tc.getAttribute("class").contains("odds-nowrp")) {
+                                if (tc.getTextContent().matches("[+-][0-9][0-9][0-9]")) {
+                                    if (odds1 == 0F) {
+                                        odds1 = convertAmericanOddsToDecimal(Integer.valueOf(tc.getTextContent()));
+                                    } else if (oddsX == 0F) {
+                                        oddsX = convertAmericanOddsToDecimal(Integer.valueOf(tc.getTextContent()));
+                                    } else if (odds2 == 0F) {
+                                        odds2 = convertAmericanOddsToDecimal(Integer.valueOf(tc.getTextContent()));
+                                    }
+                                } else if (tc.getTextContent().matches("[0-9].[0-9]+")) {
+                                    if (odds1 == 0F) {
+                                        odds1 = Float.valueOf(tc.getTextContent());
+                                    } else if (oddsX == 0F) {
+                                        oddsX = Float.valueOf(tc.getTextContent());
+                                    } else if (odds2 == 0F) {
+                                        odds2 = Float.valueOf(tc.getTextContent());
+                                    }
+                                }
+                            }
+
+                        }
+                    } catch (final NumberFormatException e) {
+                        System.out
+                                .println("Failed to get the match between " + teams[0].trim() + " and "
+                                        + teams[1].trim() + " at "
+                                        + baseDate.withHour(Integer.valueOf(time[0]))
+                                                .withMinute(Integer.valueOf(time[1]))
+                                        + " odds1: " + odds1 + " oddsX: " + oddsX + " odds2: " + odds2 + " homeScore "
+                                        + homeScore + " awayScore " + awayScore + " overtime: "
+                                        + (overtime ? "true" : "false"));
+                        continue;
+                    }
+
+                    if (abandon) {
+                        continue;
+                    }
+                    final Mysql mysql = Mysql.getInstance();
+                    final int leagueId = mysql.addLeague(leagueName, countryName, "soccer");
+                    final int countryId = mysql.getCountryId(countryName);
+                    final int sportId = mysql.getSportId("soccer");
+
+                    String season = mysql.getLastParsedYear(leagueName, countryId);
+
+                    if (Strings.isNullOrEmpty(season)) {
+                        season = String.valueOf(LocalDateTime.now().getYear());
+                    }
+
+                    final LocalDateTime dt = baseDate.withHour(Integer.valueOf(time[0]))
+                            .withMinute(Integer.valueOf(time[1])).withSecond(0).withNano(0);
+                    mysql.addResult(new ResultDTO("SoccerResults", dt, teams[0].trim(), teams[1].trim(), homeScore,
+                            awayScore, overtime, odds1, oddsX, odds2, countryId, season, leagueId, sportId));
+                }
+            }
+        } catch (FailingHttpStatusCodeException | IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void parseTournamentTable(int sportId, int countryId, int leagueId, String season,
+            HtmlTable tournamentTable, LocalDateTime gameDate, DateTimeFormatter dateFormatter) throws SQLException {
+        for (final HtmlTableRow tr : tournamentTable.getRows()) {
+            if (tr.getAttribute("class").contains("deactivate")) {
+                String homeTeam;
+                String awayTeam;
+                int homeScore = -1;
+                int awayScore = -1;
+                float odds1 = 0f;
+                float oddsX = 0f;
+                float odds2 = 0f;
+                boolean overtime = false;
+
+                final HtmlTableCell timeCell = tr.getCell(0);
+                final HtmlTableCell participantsCell = tr.getCell(1);
+
+                // Game Time
+                final String[] timeValue = timeCell.getTextContent().split(":");
+                gameDate = gameDate.withHour(Integer.valueOf(timeValue[0]));
+                gameDate = gameDate.withMinute(Integer.valueOf(timeValue[1]));
+
+                // Teams
+                final String[] participantsValue = participantsCell.getTextContent().split(" - ");
+                homeTeam = participantsValue[0].trim();
+                awayTeam = participantsValue[1].trim();
+
+                final List<HtmlTableCell> cells = tr.getCells();
+                for (final HtmlTableCell tc : cells) {
+                    // Score
+                    if (tc.getAttribute("class").contains("table-score")) {
+                        final String[] scoreValue = tc.getTextContent().split(":");
+                        if (scoreValue[0].matches("\\D+")) {
+                            continue;
+                        }
+                        homeScore = Integer.valueOf(scoreValue[0]);
+                        if (scoreValue[1].matches("\\D+")) {
+                            overtime = true;
+                        }
+                        awayScore = Integer.valueOf(scoreValue[1].replaceAll("\\D+", ""));
+                    }
+
+                    if (tc.getAttribute("class").contains("odds-nowrp")) {
+                        if (tc.getTextContent().matches("[+-][0-9][0-9][0-9]")) {
+                            if (odds1 == 0F) {
+                                odds1 = convertAmericanOddsToDecimal(Integer.valueOf(tc.getTextContent()));
+                            } else if (oddsX == 0F) {
+                                oddsX = convertAmericanOddsToDecimal(Integer.valueOf(tc.getTextContent()));
+                            } else if (odds2 == 0F) {
+                                odds2 = convertAmericanOddsToDecimal(Integer.valueOf(tc.getTextContent()));
+                            }
+                        } else if (tc.getTextContent().matches("[0-9].[0-9]+")) {
+                            if (odds1 == 0F) {
+                                odds1 = Float.valueOf(tc.getTextContent());
+                            } else if (oddsX == 0F) {
+                                oddsX = Float.valueOf(tc.getTextContent());
+                            } else if (odds2 == 0F) {
+                                odds2 = Float.valueOf(tc.getTextContent());
+                            }
+                        }
+                    }
+                }
+
+                if (gameDate != null && homeTeam != null && awayTeam != null && odds1 != 0 && oddsX != 0 && odds2 != 0
+                        && !Strings.isNullOrEmpty(season)) { // All set.. update sql result table
+                    System.out.println("Adding game between " + homeTeam + " and " + awayTeam + " with score "
+                            + homeScore + "-" + awayScore);
+                    Mysql.getInstance().addResult(new ResultDTO("SoccerResults", gameDate, homeTeam, awayTeam,
+                            homeScore, awayScore, overtime, odds1, oddsX, odds2, countryId, season, leagueId, sportId));
+                } else {
+                    System.out.println(String.format(
+                            "Not adding, missing somethind.. gameDate: %s, homeTeam %s, awayTeam %s, odds1 %s, oddsX %s, odds2 %s, "
+                                    + "season %s",
+                            gameDate, homeTeam, awayTeam, odds1, oddsX, odds2, season));
+                }
+
+            } else if (tr.getAttribute("class").contains("center nob-border")) { // Datum rader
+                final List<HtmlSpan> dateSpan = tr.getByXPath(".//span[contains(@class, 'datet')]");
+                final String dateString = dateSpan.get(0).getTextContent();
+                if (dateString.toLowerCase().contains("yesterday")) {
+                    gameDate = LocalDateTime.now().minusDays(1);
+                } else if (dateString.toLowerCase().contains("today")) {
+                    gameDate = LocalDateTime.now();
+                } else {
+                    gameDate = LocalDate.parse(dateString, dateFormatter).atStartOfDay();
+                }
+            }
+        }
+    }
 }
 }

+ 294 - 0
OddsJavaFx/src/tests/AnalysisBettDrawTester.java

@@ -0,0 +1,294 @@
+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<String, List<Bet>> placedBets = new HashMap<>();
+    TestDatabase database;
+
+    List<LocalSoccerMatch> betsToPlace = new ArrayList<>();
+    float betAmount;
+
+    List<Bet> bets = new ArrayList<>();
+    int wins = 0;
+    int losses = 0;
+
+    float bank;
+
+    private List<Bet> 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<String, List<SoccerMatch>> matches = getMatchesOrderedBySeason(leagueDTO);
+        this.betAmount = startingBank * (bettingLevel / 100.0f);
+
+        boolean skipFirst = false;
+        for (Entry<String, List<SoccerMatch>> 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<SoccerMatch> 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<Bet> 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<DifferenceBetDTO> 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<Bet> 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<Bet> 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());
+
+        });
+    }
+}

+ 2 - 2
OddsJavaFx/src/tests/AnalysisBettTester.java

@@ -74,7 +74,7 @@ public class AnalysisBettTester extends TestClass {
             SoccerMatchAnalysis analysis = new SoccerMatchAnalysis(match);
             SoccerMatchAnalysis analysis = new SoccerMatchAnalysis(match);
 
 
             int homeWinsCount = analysis.winLossRatio(leagueInfo.getWinLossRatio(), true);
             int homeWinsCount = analysis.winLossRatio(leagueInfo.getWinLossRatio(), true);
-            int awayWindCount = analysis.winLossRatio(leagueInfo.getWinLossRatio(), false);
+            int awayWinsCount = analysis.winLossRatio(leagueInfo.getWinLossRatio(), false);
 
 
             int homeWinLossRatioCount = analysis.winLossRationHomeAndAway(true,
             int homeWinLossRatioCount = analysis.winLossRationHomeAndAway(true,
                     leagueInfo.getWinLossRatioHomeAndAway());
                     leagueInfo.getWinLossRatioHomeAndAway());
@@ -85,7 +85,7 @@ public class AnalysisBettTester extends TestClass {
             int awayScoringTotal = analysis.scoringTotal(leagueInfo.getScoringTotal(), false);
             int awayScoringTotal = analysis.scoringTotal(leagueInfo.getScoringTotal(), false);
 
 
             int scoringDiffLastGames = analysis.getScoringDiffLastGames(leagueInfo.getScoringDiffLastGame());
             int scoringDiffLastGames = analysis.getScoringDiffLastGames(leagueInfo.getScoringDiffLastGame());
-            int winsCountDiff = homeWinsCount - awayWindCount;
+            int winsCountDiff = homeWinsCount - awayWinsCount;
             int winLossRatioDiff = homeWinLossRatioCount - awayWinLossRatioCount;
             int winLossRatioDiff = homeWinLossRatioCount - awayWinLossRatioCount;
             int scoringTotalDiff = homeScoringTotal - awayScoringTotal;
             int scoringTotalDiff = homeScoringTotal - awayScoringTotal;
 
 

+ 29 - 27
OddsJavaFx/src/tests/HomeDrawAwayTest.java

@@ -22,6 +22,32 @@ public class HomeDrawAwayTest extends TestClass {
     private float activeOddsX;
     private float activeOddsX;
     private float activeOdds2;
     private float activeOdds2;
 
 
+    public ArrayList<SoccerMatch> getMatches() {
+        final ArrayList<SoccerMatch> matches = new ArrayList<>();
+        prioLeagues = getPrioLeagues();
+
+        final ArrayList<String> leagueIds = Lists.newArrayList();
+        prioLeagues.forEach(p -> leagueIds.add(String.valueOf(p.getLeagueId())));
+
+        final String sql = "SELECT res.*, " + "hTeam.name as homeTeamName, aTeam.name as awayTeamName "
+                + "FROM SoccerResults as res "
+                + "Join Team as hTeam ON res.homeTeam = hTeam.id " + "Join Team as aTeam ON res.awayTeam = aTeam.id "
+                + "WHERE "
+                + "DATE(gameDate) > '2021-07-01' AND " + "homeScore >= 0 AND " + "awayScore >= 0 AND "
+                + "res.leagueId IN ("
+                + String.join(",", leagueIds) + ") " + "ORDER BY gameDate ASC";
+
+        PreparedStatement stmt;
+        try {
+            stmt = getConnection().prepareStatement(sql);
+            matches.addAll(super.getMatches(stmt));
+        } catch (final SQLException e) {
+            e.printStackTrace();
+        }
+
+        return matches;
+    }
+
     @Override
     @Override
     public void runTest() {
     public void runTest() {
         float betAmount;
         float betAmount;
@@ -183,32 +209,6 @@ public class HomeDrawAwayTest extends TestClass {
         return result;
         return result;
     }
     }
 
 
-    public ArrayList<SoccerMatch> getMatches() {
-        final ArrayList<SoccerMatch> matches = new ArrayList<>();
-        prioLeagues = getPrioLeagues();
-
-        final ArrayList<String> leagueIds = Lists.newArrayList();
-        prioLeagues.forEach(p -> leagueIds.add(String.valueOf(p.getLeagueId())));
-
-        final String sql = "SELECT res.*, " + "hTeam.name as homeTeamName, aTeam.name as awayTeamName "
-                + "FROM SoccerResults as res "
-                + "Join Team as hTeam ON res.homeTeam = hTeam.id " + "Join Team as aTeam ON res.awayTeam = aTeam.id "
-                + "WHERE "
-                + "DATE(gameDate) > '2021-07-01' AND " + "homeScore >= 0 AND " + "awayScore >= 0 AND "
-                + "res.leagueId IN ("
-                + String.join(",", leagueIds) + ") " + "ORDER BY gameDate ASC";
-
-        PreparedStatement stmt;
-        try {
-            stmt = getConnection().prepareStatement(sql);
-            matches.addAll(super.getMatches(stmt));
-        } catch (final SQLException e) {
-            e.printStackTrace();
-        }
-
-        return matches;
-    }
-
     private ArrayList<League> getPrioLeagues() {
     private ArrayList<League> getPrioLeagues() {
         final String sql = "SELECT * FROM League WHERE prio = 1";
         final String sql = "SELECT * FROM League WHERE prio = 1";
         final ArrayList<League> result = Lists.newArrayList();
         final ArrayList<League> result = Lists.newArrayList();
@@ -219,7 +219,9 @@ public class HomeDrawAwayTest extends TestClass {
             while (rs.next()) {
             while (rs.next()) {
                 result.add(new League(rs.getInt("id"), rs.getString("name"), rs.getInt("scoringDiffLastGame"),
                 result.add(new League(rs.getInt("id"), rs.getString("name"), rs.getInt("scoringDiffLastGame"),
                         rs.getInt("scoringTotal"),
                         rs.getInt("scoringTotal"),
-                        rs.getInt("winLossRatioHomeAndAway"), rs.getInt("winLossRatio")));
+                        rs.getInt("winLossRatioHomeAndAway"), rs.getInt("winLossRatio"), rs.getInt("drawDiffHomeAway"),
+                        rs.getInt("drawDiffTotalGoals"), rs.getInt("drawWinningForm"),
+                        rs.getInt("drawWinngingFormHomeAway")));
             }
             }
         } catch (final SQLException e) {
         } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();

+ 112 - 98
OddsJavaFx/src/tests/LeagueTablePositionTest.java

@@ -14,121 +14,135 @@ import tests.objects.Standing;
 
 
 public class LeagueTablePositionTest extends TestClass {
 public class LeagueTablePositionTest extends TestClass {
 
 
-	@Override public void runTest() {
-		List<LeagueDTO> prioLeagues = TestDatabase.getInstance().getPrioLeagues();
+    @Override
+    public void runTest() {
+        List<LeagueDTO> prioLeagues = TestDatabase.getInstance().getPrioLeagues();
 
 
-		for (LeagueDTO league : prioLeagues) {
-			if (league.getName().equals("championship")) {
-				runLeagueTest(league);
-			}
-		}
+        for (LeagueDTO league : prioLeagues) {
+            if (league.getName().equals("championship")) {
+                runLeagueTest(league);
+            }
+        }
 
 
-	}
+    }
 
 
-	private void runLeagueTest(LeagueDTO league) {
-		getMatches(league);
-	}
+    private void runLeagueTest(LeagueDTO league) {
+        getMatches(league);
+    }
 
 
-	private void getMatches(LeagueDTO league) {
+    private void getMatches(LeagueDTO league) {
 
 
-		List<SoccerMatch> matches = TestDatabase.getInstance().getMatches(league);
-		List<String> seasons = matches.stream().map(SoccerMatch::getSeason).distinct().sorted().toList();
+        List<SoccerMatch> matches = TestDatabase.getInstance().getMatches(league);
+        List<String> seasons = matches.stream().map(SoccerMatch::getSeason).distinct().sorted().toList();
 
 
-		for (String season : seasons.subList(1, seasons.size())) {
-			List<SoccerMatch> seasonMatches = matches.stream().filter(p -> p.getSeason().equals(season)).toList();
-			Map<String, Integer> intervals = getIntervals(seasonMatches);
-			int skipFirstXMatches = 10;
-			int currentMatch = 0;
+        for (String season : seasons.subList(1, seasons.size())) {
+            List<SoccerMatch> seasonMatches = matches.stream().filter(p -> p.getSeason().equals(season)).toList();
+            Map<String, Integer> intervals = getIntervals(seasonMatches);
+            int skipFirstXMatches = 10;
+            int currentMatch = 0;
 
 
-			int testValue = 0;
+            int testValue = 0;
 
 
-			seasonMatches = seasonMatches.stream().sorted((m1, m2) -> m1.getGameDate().compareTo(m2.getGameDate())).toList();
+            seasonMatches = seasonMatches.stream().sorted((m1, m2) -> m1.getGameDate().compareTo(m2.getGameDate()))
+                    .toList();
 
 
-			for (SoccerMatch match : seasonMatches) {
-				List<Standing> standings = getStandings(seasonMatches.stream().filter(p -> p.getGameDate().isBefore(match.getGameDate())).toList());
+            for (SoccerMatch match : seasonMatches) {
+                List<Standing> standings = getStandings(
+                        seasonMatches.stream().filter(p -> p.getGameDate().isBefore(match.getGameDate())).toList());
 
 
-				standings = standings.stream().sorted((s1, s2) -> Integer.compare(s2.getPoints(), s1.getPoints())).toList();
+                standings = standings.stream().sorted((s1, s2) -> Integer.compare(s2.getPoints(), s1.getPoints()))
+                        .toList();
 
 
-				Optional<Standing> homeTeamStanding = standings.stream().filter(p -> p.getTeamName().equals(match.getHomeTeam().getTeamName()))
-						.findFirst();
-				Optional<Standing> awayTeamStanding = standings.stream().filter(p -> p.getTeamName().equals(match.getAwayTeam().getTeamName()))
-						.findFirst();
-				if (homeTeamStanding.isPresent() && awayTeamStanding.isPresent() && homeTeamStanding.get().getGamesPlayed() >= skipFirstXMatches) {
-					Standing hts = homeTeamStanding.get();
-					Standing ats = awayTeamStanding.get();
+                Optional<Standing> homeTeamStanding = standings.stream()
+                        .filter(p -> p.getTeamName().equals(match.getHomeTeam().getTeamName()))
+                        .findFirst();
+                Optional<Standing> awayTeamStanding = standings.stream()
+                        .filter(p -> p.getTeamName().equals(match.getAwayTeam().getTeamName()))
+                        .findFirst();
+                if (homeTeamStanding.isPresent() && awayTeamStanding.isPresent()
+                        && homeTeamStanding.get().getGamesPlayed() >= skipFirstXMatches) {
+                    Standing hts = homeTeamStanding.get();
+                    Standing ats = awayTeamStanding.get();
 
 
-					int homeTeamPosition = standings.indexOf(hts);
-					int awayTeamPosition = standings.indexOf(ats);
+                    int homeTeamPosition = standings.indexOf(hts);
+                    int awayTeamPosition = standings.indexOf(ats);
 
 
 //					System.out.println(String.format("%s Hometeam %s position %s Awayteam %s position %s Diff %s", season, hts.getTeamName(),
 //					System.out.println(String.format("%s Hometeam %s position %s Awayteam %s position %s Diff %s", season, hts.getTeamName(),
 //							homeTeamPosition, ats.getTeamName(), awayTeamPosition, homeTeamPosition - awayTeamPosition));
 //							homeTeamPosition, ats.getTeamName(), awayTeamPosition, homeTeamPosition - awayTeamPosition));
 //					standings.forEach(s -> System.out.println(String.format("%s \t\t wins %s \t draws %s \t losses %s \t points %s \t gamesPlayed %s",
 //					standings.forEach(s -> System.out.println(String.format("%s \t\t wins %s \t draws %s \t losses %s \t points %s \t gamesPlayed %s",
 //							s.getTeamName(), s.getWins(), s.getDraws(), s.getLosses(), s.getPoints(), s.getGamesPlayed())));
 //							s.getTeamName(), s.getWins(), s.getDraws(), s.getLosses(), s.getPoints(), s.getGamesPlayed())));
 
 
-					List<SoccerMatch> matchesBefore = matches.stream().filter(p -> p.getGameDate().isBefore(match.getGameDate())).toList();
-					matchesBefore = matchesBefore.stream().sorted((m1, m2) -> m1.getGameDate().compareTo(m2.getGameDate())).toList();
-					float avgGoals = getAvgGoalsWithSameDiff(matchesBefore, Math.abs(homeTeamPosition - awayTeamPosition));
-					List<Float> leagueAvarages = TestDatabase.getInstance().getLeagueAvarages(match.getHomeTeam().getTeamLeagueId(),
-							match.getHomeTeam().getCountryId(), match.getGameDate().format(DateTimeFormatter.BASIC_ISO_DATE));
-					if (Math.abs(avgGoals - (leagueAvarages.get(0) + leagueAvarages.get(1))) > 0.5) {
-						System.out.println(String.format(
-								"%s homeTeam: %s (%s) - awayTeam: %s (%s) Avg goals with diff %s is %s and leagueAvg is %s makes diff %s intervals is low %s mid %s high %s",
-								match.getGameDate(), match.getHomeTeam().getTeamName(), homeTeamPosition, match.getAwayTeam().getTeamName(),
-								awayTeamPosition, Math.abs(homeTeamPosition - awayTeamPosition), avgGoals,
-								leagueAvarages.get(0) + leagueAvarages.get(1), avgGoals - (leagueAvarages.get(0) + leagueAvarages.get(1)),
-								intervals.get("Low"), intervals.get("Low") + intervals.get("Mid"),
-								intervals.get("Low") + intervals.get("Mid") + intervals.get("High")));
-					}
-//					if (testValue++ > 100) {
-//						break; // TODO Testing
-//					}
-				}
-
-			}
-//			break; // TODO Testing
-		}
-	}
-
-	private float getAvgGoalsWithSameDiff(List<SoccerMatch> matchesBefore, int placementDiff) {
-		List<Standing> tempStanding = new ArrayList<>();
-		float result = 0.0f;
-		int matchedMatches = 0;
-		for (SoccerMatch match : matchesBefore) {
-			Optional<Standing> homeTeamStanding = tempStanding.stream().filter(ts -> ts.getTeamName().equals(match.getHomeTeam().getTeamName()))
-					.findFirst();
-			Optional<Standing> awayTeamStanding = tempStanding.stream().filter(ts -> ts.getTeamName().equals(match.getAwayTeam().getTeamName()))
-					.findFirst();
-
-			if (homeTeamStanding.isPresent() && awayTeamStanding.isPresent()) {
-				int homeTeamPosition = tempStanding.indexOf(homeTeamStanding.get());
-				int awayTeamPosition = tempStanding.indexOf(awayTeamStanding.get());
-
-				int diff = Math.abs(homeTeamPosition - awayTeamPosition);
-
-				if (diff == placementDiff) {
-					matchedMatches++;
-					result += match.getHomeScore() + match.getAwayScore();
-				}
-			}
-			updateStanding(tempStanding, match,
-					tempStanding.stream().filter(p -> p.getTeamName().equals(match.getHomeTeam().getTeamName())).findFirst(),
-					tempStanding.stream().filter(p -> p.getTeamName().equals(match.getAwayTeam().getTeamName())).findFirst());
-
-			tempStanding.sort((s1, s2) -> Integer.compare(s2.getPoints(), s1.getPoints()));
-		}
-
-		return matchedMatches > 0 ? result / matchedMatches : 0f;
-	}
-
-	private Map<String, Integer> getIntervals(List<SoccerMatch> seasonMatches) {
-		Map<String, Integer> result = new HashMap<>();
-
-		List<String> teams = seasonMatches.stream().map(m -> m.getHomeTeam().getTeamName()).distinct().toList();
-		result.put("Low", (int) Math.floor(teams.size() / 3.0));
-		result.put("Mid", (int) Math.ceil(teams.size() / 3.0));
-		result.put("High", (int) Math.floor(teams.size() / 3.0));
-
-		return result;
-	}
+                    List<SoccerMatch> matchesBefore = matches.stream()
+                            .filter(p -> p.getGameDate().isBefore(match.getGameDate())).toList();
+                    matchesBefore = matchesBefore.stream()
+                            .sorted((m1, m2) -> m1.getGameDate().compareTo(m2.getGameDate())).toList();
+                    float avgGoals = getAvgGoalsWithSameDiff(matchesBefore,
+                            Math.abs(homeTeamPosition - awayTeamPosition));
+                    List<Float> leagueAvarages = TestDatabase.getInstance().getLeagueAvarages(
+                            match.getHomeTeam().getTeamLeagueId(),
+                            match.getHomeTeam().getCountryId(),
+                            match.getGameDate().format(DateTimeFormatter.BASIC_ISO_DATE));
+                    if (Math.abs(avgGoals - (leagueAvarages.get(0) + leagueAvarages.get(1))) > 0.5) {
+                        System.out.println(String.format(
+                                "%s homeTeam: %s (%s) - awayTeam: %s (%s) Avg goals with diff %s is %s and leagueAvg is %s makes diff %s intervals is low %s mid %s high %s",
+                                match.getGameDate(), match.getHomeTeam().getTeamName(), homeTeamPosition,
+                                match.getAwayTeam().getTeamName(),
+                                awayTeamPosition, Math.abs(homeTeamPosition - awayTeamPosition), avgGoals,
+                                leagueAvarages.get(0) + leagueAvarages.get(1),
+                                avgGoals - (leagueAvarages.get(0) + leagueAvarages.get(1)),
+                                intervals.get("Low"), intervals.get("Low") + intervals.get("Mid"),
+                                intervals.get("Low") + intervals.get("Mid") + intervals.get("High")));
+                    }
+                }
+
+            }
+        }
+    }
+
+    private float getAvgGoalsWithSameDiff(List<SoccerMatch> matchesBefore, int placementDiff) {
+        List<Standing> tempStanding = new ArrayList<>();
+        float result = 0.0f;
+        int matchedMatches = 0;
+        for (SoccerMatch match : matchesBefore) {
+            Optional<Standing> homeTeamStanding = tempStanding.stream()
+                    .filter(ts -> ts.getTeamName().equals(match.getHomeTeam().getTeamName()))
+                    .findFirst();
+            Optional<Standing> awayTeamStanding = tempStanding.stream()
+                    .filter(ts -> ts.getTeamName().equals(match.getAwayTeam().getTeamName()))
+                    .findFirst();
+
+            if (homeTeamStanding.isPresent() && awayTeamStanding.isPresent()) {
+                int homeTeamPosition = tempStanding.indexOf(homeTeamStanding.get());
+                int awayTeamPosition = tempStanding.indexOf(awayTeamStanding.get());
+
+                int diff = Math.abs(homeTeamPosition - awayTeamPosition);
+
+                if (diff == placementDiff) {
+                    matchedMatches++;
+                    result += match.getHomeScore() + match.getAwayScore();
+                }
+            }
+            updateStanding(tempStanding, match,
+                    tempStanding.stream().filter(p -> p.getTeamName().equals(match.getHomeTeam().getTeamName()))
+                            .findFirst(),
+                    tempStanding.stream().filter(p -> p.getTeamName().equals(match.getAwayTeam().getTeamName()))
+                            .findFirst());
+
+            tempStanding.sort((s1, s2) -> Integer.compare(s2.getPoints(), s1.getPoints()));
+        }
+
+        return matchedMatches > 0 ? result / matchedMatches : 0f;
+    }
+
+    private Map<String, Integer> getIntervals(List<SoccerMatch> seasonMatches) {
+        Map<String, Integer> result = new HashMap<>();
+
+        List<String> teams = seasonMatches.stream().map(m -> m.getHomeTeam().getTeamName()).distinct().toList();
+        result.put("Low", (int) Math.floor(teams.size() / 3.0));
+        result.put("Mid", (int) Math.ceil(teams.size() / 3.0));
+        result.put("High", (int) Math.floor(teams.size() / 3.0));
+
+        return result;
+    }
 
 
 }
 }

+ 27 - 33
OddsJavaFx/src/tests/PrioCountriesAll.java

@@ -19,6 +19,30 @@ public class PrioCountriesAll extends TestClass {
 
 
     private ArrayList<League> prioLeagues;
     private ArrayList<League> prioLeagues;
 
 
+    public ArrayList<SoccerMatch> getMatches() {
+        final ArrayList<SoccerMatch> matches = new ArrayList<>();
+        prioLeagues = getPrioLeagues();
+
+        final ArrayList<String> leagueIds = Lists.newArrayList();
+        prioLeagues.forEach(p -> leagueIds.add(String.valueOf(p.getLeagueId())));
+
+        final String sql = "SELECT res.*, " + "hTeam.name as homeTeamName, aTeam.name as awayTeamName "
+                + "FROM SoccerResults as res "
+                + "Join Team as hTeam ON res.homeTeam = hTeam.id " + "Join Team as aTeam ON res.awayTeam = aTeam.id "
+                + "WHERE " + "res.leagueId IN ("
+                + String.join(",", leagueIds) + ") " + "ORDER BY gameDate ASC";
+
+        PreparedStatement stmt;
+        try {
+            stmt = getConnection().prepareStatement(sql);
+            matches.addAll(super.getMatches(stmt));
+        } catch (final SQLException e) {
+            e.printStackTrace();
+        }
+
+        return matches;
+    }
+
     @Override
     @Override
     public void runTest() {
     public void runTest() {
         float bank = 1000;
         float bank = 1000;
@@ -116,30 +140,6 @@ public class PrioCountriesAll extends TestClass {
         return returnValue;
         return returnValue;
     }
     }
 
 
-    public ArrayList<SoccerMatch> getMatches() {
-        final ArrayList<SoccerMatch> matches = new ArrayList<>();
-        prioLeagues = getPrioLeagues();
-
-        final ArrayList<String> leagueIds = Lists.newArrayList();
-        prioLeagues.forEach(p -> leagueIds.add(String.valueOf(p.getLeagueId())));
-
-        final String sql = "SELECT res.*, " + "hTeam.name as homeTeamName, aTeam.name as awayTeamName "
-                + "FROM SoccerResults as res "
-                + "Join Team as hTeam ON res.homeTeam = hTeam.id " + "Join Team as aTeam ON res.awayTeam = aTeam.id "
-                + "WHERE " + "res.leagueId IN ("
-                + String.join(",", leagueIds) + ") " + "ORDER BY gameDate ASC";
-
-        PreparedStatement stmt;
-        try {
-            stmt = getConnection().prepareStatement(sql);
-            matches.addAll(super.getMatches(stmt));
-        } catch (final SQLException e) {
-            e.printStackTrace();
-        }
-
-        return matches;
-    }
-
     private ArrayList<League> getPrioLeagues() {
     private ArrayList<League> getPrioLeagues() {
         final String sql = "SELECT * FROM League WHERE prio = 1";
         final String sql = "SELECT * FROM League WHERE prio = 1";
         final ArrayList<League> result = Lists.newArrayList();
         final ArrayList<League> result = Lists.newArrayList();
@@ -150,7 +150,9 @@ public class PrioCountriesAll extends TestClass {
             while (rs.next()) {
             while (rs.next()) {
                 result.add(new League(rs.getInt("id"), rs.getString("name"), rs.getInt("scoringDiffLastGame"),
                 result.add(new League(rs.getInt("id"), rs.getString("name"), rs.getInt("scoringDiffLastGame"),
                         rs.getInt("scoringTotal"),
                         rs.getInt("scoringTotal"),
-                        rs.getInt("winLossRatioHomeAndAway"), rs.getInt("winLossRatio")));
+                        rs.getInt("winLossRatioHomeAndAway"), rs.getInt("winLossRatio"), rs.getInt("drawDiffHomeAway"),
+                        rs.getInt("drawDiffTotalGoals"), rs.getInt("drawWinningForm"),
+                        rs.getInt("drawWinngingFormHomeAway")));
             }
             }
         } catch (final SQLException e) {
         } catch (final SQLException e) {
             e.printStackTrace();
             e.printStackTrace();
@@ -159,12 +161,4 @@ public class PrioCountriesAll extends TestClass {
         return result;
         return result;
     }
     }
 
 
-    @Override
-    public void setup(String date, float startingBank, float bettingLevel, Float betMargin, int lookBack, int sportId,
-            Integer countryId,
-            Integer leagueId) {
-        // TODO Auto-generated method stub
-
-    }
-
 }
 }

+ 158 - 54
OddsJavaFx/src/tests/RelevanceTest.java

@@ -1,11 +1,12 @@
 package tests;
 package tests;
 
 
-import java.util.Collections;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Map.Entry;
+import java.util.Optional;
 import java.util.TreeMap;
 import java.util.TreeMap;
 
 
 import data.TestDatabase;
 import data.TestDatabase;
@@ -13,6 +14,7 @@ import objects.SoccerMatch;
 import objects.SoccerMatchAnalysis;
 import objects.SoccerMatchAnalysis;
 import tests.objects.LeagueDTO;
 import tests.objects.LeagueDTO;
 
 
+@java.lang.SuppressWarnings("squid:S106")
 public class RelevanceTest extends TestClass {
 public class RelevanceTest extends TestClass {
 
 
     // Premiere League Siffror
     // Premiere League Siffror
@@ -45,12 +47,10 @@ public class RelevanceTest extends TestClass {
     // best lookback 7 winLossRationHomeAndAway
     // best lookback 7 winLossRationHomeAndAway
     // best lookback 15 winLossRatio
     // best lookback 15 winLossRatio
 
 
-    private TestDatabase database;
-
     int scoringDiffLastGames = 8;
     int scoringDiffLastGames = 8;
     int scoringTotal = 4;
     int scoringTotal = 4;
     int winLossRationHomeAndAway = 12;
     int winLossRationHomeAndAway = 12;
-    int WinLossRatio = 2;
+    int winLossRatio = 2;
 
 
     Map<Float, Integer> winsOnDiff = new HashMap<>();
     Map<Float, Integer> winsOnDiff = new HashMap<>();
     Map<Float, Integer> lossesOnDiff = new HashMap<>();
     Map<Float, Integer> lossesOnDiff = new HashMap<>();
@@ -64,67 +64,104 @@ public class RelevanceTest extends TestClass {
     float bestPercent = 0;
     float bestPercent = 0;
     int bestLookback = 0;
     int bestLookback = 0;
 
 
-    Map<Integer, Float> resultsDiffTotalGoals = new HashMap<>();
-    Map<Integer, Float> resultsDiffHomeAway = new HashMap<>();
-    Map<Integer, Float> resultsWinningForm = new HashMap<>();
-    Map<Integer, Float> resultsWinnignFormHomeVsAway = new HashMap<>();
-    Map<Integer, Float> results = new HashMap<>();
+    List<Res> resultsDiffTotalGoals = new ArrayList<>();
+    List<Res> resultsDiffHomeAway = new ArrayList<>();
+    List<Res> resultsWinningForm = new ArrayList<>();
+    List<Res> resultsWinnignFormHomeVsAway = new ArrayList<>();
+
+    List<Res> results = new ArrayList<>();
     Map<String, Float> resultsCombined = new HashMap<>();
     Map<String, Float> resultsCombined = new HashMap<>();
 
 
     String season;
     String season;
 
 
+    private float bestDrawPercent;
+
     @Override
     @Override
     public void runTest() {
     public void runTest() {
-        database = TestDatabase.getInstance();
+        TestDatabase database = TestDatabase.getInstance();
         LeagueDTO leagueDTO = database.getLeagueDTO(leagueId);
         LeagueDTO leagueDTO = database.getLeagueDTO(leagueId);
         LinkedHashMap<String, List<SoccerMatch>> matches = getMatchesOrderedBySeason(leagueDTO);
         LinkedHashMap<String, List<SoccerMatch>> matches = getMatchesOrderedBySeason(leagueDTO);
 
 
-        boolean skipFirst = true;
+        boolean skipFirst = false;
         for (Entry<String, List<SoccerMatch>> seasonMatches : matches.entrySet()) {
         for (Entry<String, List<SoccerMatch>> seasonMatches : matches.entrySet()) {
             if (skipFirst) {
             if (skipFirst) {
                 skipFirst = false;
                 skipFirst = false;
                 continue;
                 continue;
             }
             }
-//            for (int i = 1; i < 20; i++) {
-//                gamesLookback = i;
-            season = seasonMatches.getKey();
-//            analyzeDiffHomeAway(seasonMatches.getValue(), resultsDiffHomeAway);
-//            analyzeDiffTotalGoals(seasonMatches.getValue(), resultsDiffTotalGoals);
-//            analyzeWinnigForm(seasonMatches.getValue(), resultsWinningForm);
-//            analyzeWinnigFormHomeVsAway(seasonMatches.getValue(), resultsWinnignFormHomeVsAway);
-            System.out.println("Season " + seasonMatches.getKey());
-            analyzeCombination(seasonMatches.getValue());
+            for (int i = 1; i < 20; i++) {
+                gamesLookback = i;
+                season = seasonMatches.getKey();
+                analyzeDiffHomeAway(seasonMatches.getValue(), resultsDiffHomeAway);
+                analyzeDiffTotalGoals(seasonMatches.getValue(), resultsDiffTotalGoals);
+                analyzeWinnigForm(seasonMatches.getValue(), resultsWinningForm);
+                analyzeWinnigFormHomeVsAway(seasonMatches.getValue(), resultsWinnignFormHomeVsAway);
+//            System.out.println("Season " + seasonMatches.getKey());
+//            analyzeCombination(seasonMatches.getValue());
 //            break;
 //            break;
-//            }
+            }
         }
         }
 
 
         resultsCombined.forEach((k, v) -> System.out.println(k + " result " + v));
         resultsCombined.forEach((k, v) -> System.out.println(k + " result " + v));
 
 
-//        resultsDiffHomeAway.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
-//                .limit(5)
-//                .forEach(e -> System.out
-//                        .println("resultsDiffHomeAway Lookback " + e.getKey() + " value " + e.getValue()));
-//        resultsDiffTotalGoals.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
-//                .limit(5)
-//                .forEach(e -> System.out
-//                        .println("resultsDiffTotalGoals Lookback " + e.getKey() + " value " + e.getValue()));
-//        resultsWinningForm.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
-//                .limit(5)
-//                .forEach(e -> System.out
-//                        .println("resultsWinningForm Lookback " + e.getKey() + " value " + e.getValue()));
-//        resultsWinnignFormHomeVsAway.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
-//                .limit(5)
-//                .forEach(e -> System.out
-//                        .println("resultsWinnignFormHomeVsAway Lookback " + e.getKey() + " value " + e.getValue()));
-
-        results.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
+        resultsDiffHomeAway.stream().sorted((r1, r2) -> Float.compare(r2.getResult(), r1.getResult()))
+                .limit(5)
+                .forEach(e -> System.out
+                        .println("resultsDiffHomeAway Lookback " + e.getLookback() + " value " + e.getResult()));
+        resultsDiffTotalGoals.stream().sorted((r1, r2) -> Float.compare(r2.getResult(), r1.getResult()))
+                .limit(5)
+                .forEach(e -> System.out
+                        .println("resultsDiffTotalGoals Lookback " + e.getLookback() + " value " + e.getResult()));
+
+        resultsWinningForm.stream().sorted((r1, r2) -> Float.compare(r2.getResult(), r1.getResult()))
+                .limit(5)
+                .forEach(e -> System.out
+                        .println("resultsWinningForm Lookback " + e.getLookback() + " value " + e.getResult()));
+
+        resultsWinnignFormHomeVsAway.stream().sorted((r1, r2) -> Float.compare(r2.getResult(), r1.getResult()))
                 .limit(5)
                 .limit(5)
-                .forEach(e -> System.out.println("Lookback " + e.getKey() + " value " + e.getValue()));
+                .forEach(e -> System.out
+                        .println("resultsWinnignFormHomeVsAway Lookback " + e.getLookback() + " value "
+                                + e.getResult()));
+
+        resultsDiffHomeAway.stream()
+                .sorted((r1, r2) -> Float
+                        .compare(r2.getDrawPercent(), r1.getDrawPercent()))
+                .limit(5)
+                .forEach(e -> System.out
+                        .println("resultsDiffHomeAway Draws correct " + e.getDrawPercent()
+                                + " played "
+                                + e.getDrawsPlayed() + " lookback " + e.getLookback()));
+
+        resultsDiffTotalGoals.stream()
+                .sorted((r1, r2) -> Float.compare(r2.getDrawPercent(), r1.getDrawPercent()))
+                .limit(5)
+                .forEach(e -> System.out
+                        .println("resultsDiffTotalGoals Draws correct " + e.getDrawPercent()
+                                + " played "
+                                + e.getDrawsPlayed() + " lookback " + e.getLookback()));
+
+        resultsWinningForm.stream()
+                .sorted((r1, r2) -> Float
+                        .compare(r2.getDrawPercent(), r1.getDrawPercent()))
+                .limit(5)
+                .forEach(e -> System.out
+                        .println("resultsWinningForm Draws correct " + e.getDrawPercent()
+                                + " played "
+                                + e.getDrawsPlayed() + " lookback " + e.getLookback()));
+
+        resultsWinnignFormHomeVsAway.stream()
+                .sorted((r1, r2) -> Float.compare(r2.getDrawPercent(), r1.getDrawPercent()))
+                .limit(5)
+                .forEach(e -> System.out
+                        .println("resultsWinnignFormHomeVsAway Draws correct " + e.getDrawPercent()
+                                + " played "
+                                + e.getDrawsPlayed() + " lookback " + e.getLookback()));
+
         System.out.println("Best percent " + bestPercent + " best lookback " + bestLookback);
         System.out.println("Best percent " + bestPercent + " best lookback " + bestLookback);
 
 
     }
     }
 
 
-    private void analyzeDiffHomeAway(List<SoccerMatch> matches, Map<Integer, Float> resultsDiffHomeAway) {
+    private void analyzeDiffHomeAway(List<SoccerMatch> matches, List<Res> resultsDiffHomeAway) {
         System.out.println("Analysis Diff Home Away");
         System.out.println("Analysis Diff Home Away");
         winsOnDiff = new HashMap<>();
         winsOnDiff = new HashMap<>();
         lossesOnDiff = new HashMap<>();
         lossesOnDiff = new HashMap<>();
@@ -135,9 +172,7 @@ public class RelevanceTest extends TestClass {
 
 
         for (SoccerMatch soccerMatch : matches) {
         for (SoccerMatch soccerMatch : matches) {
             SoccerMatchAnalysis soccerMatchAnalysis = new SoccerMatchAnalysis(soccerMatch);
             SoccerMatchAnalysis soccerMatchAnalysis = new SoccerMatchAnalysis(soccerMatch);
-            float scoringDiffLastGames = soccerMatchAnalysis.getScoringDiffLastGames(gamesLookback);
-
-            checkBetResults(soccerMatch, scoringDiffLastGames);
+            checkBetResults(soccerMatch, soccerMatchAnalysis.getScoringDiffLastGames(gamesLookback));
         }
         }
 
 
         TreeMap<Float, Integer> lossesSorted = sortMap(lossesOnDiff);
         TreeMap<Float, Integer> lossesSorted = sortMap(lossesOnDiff);
@@ -152,7 +187,7 @@ public class RelevanceTest extends TestClass {
         return winsSorted;
         return winsSorted;
     }
     }
 
 
-    private void analyzeDiffTotalGoals(List<SoccerMatch> matches, Map<Integer, Float> resultsDiffTotalGoals) {
+    private void analyzeDiffTotalGoals(List<SoccerMatch> matches, List<Res> resultsDiffTotalGoals) {
         System.out.println("Analysis Diff total goals");
         System.out.println("Analysis Diff total goals");
         winsOnDiff = new HashMap<>();
         winsOnDiff = new HashMap<>();
         lossesOnDiff = new HashMap<>();
         lossesOnDiff = new HashMap<>();
@@ -177,7 +212,7 @@ public class RelevanceTest extends TestClass {
         printResults(winsSorted, lossesSorted, true, resultsDiffTotalGoals);
         printResults(winsSorted, lossesSorted, true, resultsDiffTotalGoals);
     }
     }
 
 
-    private void analyzeWinnigForm(List<SoccerMatch> matches, Map<Integer, Float> resultsWinningForm) {
+    private void analyzeWinnigForm(List<SoccerMatch> matches, List<Res> resultsWinningForm) {
         System.out.println("annalysis Winning form homeAndAway!");
         System.out.println("annalysis Winning form homeAndAway!");
         winsOnDiff = new HashMap<>();
         winsOnDiff = new HashMap<>();
         lossesOnDiff = new HashMap<>();
         lossesOnDiff = new HashMap<>();
@@ -203,7 +238,7 @@ public class RelevanceTest extends TestClass {
     }
     }
 
 
     private void analyzeWinnigFormHomeVsAway(List<SoccerMatch> matches,
     private void analyzeWinnigFormHomeVsAway(List<SoccerMatch> matches,
-            Map<Integer, Float> resultsWinnignFormHomeVsAway) {
+            List<Res> resultsWinnignFormHomeVsAway) {
         System.out.println("annalysis Winning form homeVsAway!");
         System.out.println("annalysis Winning form homeVsAway!");
         winsOnDiff = new HashMap<>();
         winsOnDiff = new HashMap<>();
         lossesOnDiff = new HashMap<>();
         lossesOnDiff = new HashMap<>();
@@ -244,8 +279,8 @@ public class RelevanceTest extends TestClass {
 
 
         for (SoccerMatch soccerMatch : matches) {
         for (SoccerMatch soccerMatch : matches) {
             SoccerMatchAnalysis analysis = new SoccerMatchAnalysis(soccerMatch);
             SoccerMatchAnalysis analysis = new SoccerMatchAnalysis(soccerMatch);
-            int homeWinsCount = analysis.winLossRatio(WinLossRatio, true);
-            int awayWindCount = analysis.winLossRatio(WinLossRatio, false);
+            int homeWinsCount = analysis.winLossRatio(winLossRatio, true);
+            int awayWindCount = analysis.winLossRatio(winLossRatio, false);
 
 
             int homeWinLossRatioCount = analysis.winLossRationHomeAndAway(true, winLossRationHomeAndAway);
             int homeWinLossRatioCount = analysis.winLossRationHomeAndAway(true, winLossRationHomeAndAway);
             int awayWinLossRatioCount = analysis.winLossRationHomeAndAway(false, winLossRationHomeAndAway);
             int awayWinLossRatioCount = analysis.winLossRationHomeAndAway(false, winLossRationHomeAndAway);
@@ -311,7 +346,7 @@ public class RelevanceTest extends TestClass {
     }
     }
 
 
     private void printResults(TreeMap<Float, Integer> winsSorted, TreeMap<Float, Integer> lossesSorted,
     private void printResults(TreeMap<Float, Integer> winsSorted, TreeMap<Float, Integer> lossesSorted,
-            boolean onlyPercentages, Map<Integer, Float> resultsArray) {
+            boolean onlyPercentages, List<Res> resultsArray) {
         StringBuilder winsBuilder = new StringBuilder();
         StringBuilder winsBuilder = new StringBuilder();
         winsSorted.forEach((k, v) -> winsBuilder.append(k + " wins " + v + "\n"));
         winsSorted.forEach((k, v) -> winsBuilder.append(k + " wins " + v + "\n"));
         StringBuilder lossesBuilder = new StringBuilder();
         StringBuilder lossesBuilder = new StringBuilder();
@@ -326,18 +361,87 @@ public class RelevanceTest extends TestClass {
         }
         }
 
 
         float winValue = totalWins / (float) (totalWins + totalLosses);
         float winValue = totalWins / (float) (totalWins + totalLosses);
-        Float res = results.getOrDefault(gamesLookback, 0f);
-
-        resultsArray.put(gamesLookback, res + winValue);
+        Optional<Res> optional = resultsArray.stream().filter(p -> p.getLookback() == gamesLookback).findFirst();
+        Res result;
+        if (optional.isPresent()) {
+            result = optional.get();
+            result.setResult(result.getResult() + winValue);
+            result.setDrawsPlayed(result.getDrawsPlayed() + draws);
+            result.setDrawCorrect(result.getDrawCorrect() + drawsCorrect);
+            resultsArray.set(gamesLookback, result);
+        } else {
+            result = new Res(gamesLookback, winValue, drawsCorrect, draws);
+            resultsArray.add(result);
+        }
 
 
         if (winValue > bestPercent) {
         if (winValue > bestPercent) {
             bestPercent = winValue;
             bestPercent = winValue;
             bestLookback = gamesLookback;
             bestLookback = gamesLookback;
         }
         }
 
 
-        System.out.println("Totals");
+        float drawValue = drawsCorrect / (float) draws;
+        if (drawValue > bestDrawPercent) {
+            bestDrawPercent = drawValue;
+            bestDrawLookback = gamesLookback;
+        }
+
+        System.out.println("Totals " + gamesLookback);
         System.out.println(winValue + " % total " + (totalWins + totalLosses));
         System.out.println(winValue + " % total " + (totalWins + totalLosses));
         System.out.println("Draws " + drawsCorrect / (float) draws + " % total " + draws);
         System.out.println("Draws " + drawsCorrect / (float) draws + " % total " + draws);
     }
     }
 
 
+    class Res {
+
+        int lookback = 0;
+        float result = 0;
+        float drawCorrect = 0;
+        int drawsPlayed = 0;
+
+        public Res() {
+        }
+
+        public Res(int lookback, float result, float drawCorrect, int drawsPlayed) {
+            super();
+            this.lookback = lookback;
+            this.result = result;
+            this.drawCorrect = drawCorrect;
+            this.drawsPlayed = drawsPlayed;
+        }
+
+        public int getLookback() {
+            return lookback;
+        }
+
+        public float getResult() {
+            return result;
+        }
+
+        public float getDrawCorrect() {
+            return drawCorrect;
+        }
+
+        public int getDrawsPlayed() {
+            return drawsPlayed;
+        }
+
+        public void setLookback(int lookback) {
+            this.lookback = lookback;
+        }
+
+        public void setResult(float result) {
+            this.result = result;
+        }
+
+        public void setDrawCorrect(float drawResult) {
+            this.drawCorrect = drawResult;
+        }
+
+        public void setDrawsPlayed(int drawsPlayed) {
+            this.drawsPlayed = drawsPlayed;
+        }
+
+        public float getDrawPercent() {
+            return drawCorrect / drawsPlayed;
+        }
+    }
 }
 }

+ 2 - 2
OddsJavaFx/src/tests/TestClass.java

@@ -137,8 +137,8 @@ public abstract class TestClass {
                 this.bestDrawBank = startingBank;
                 this.bestDrawBank = startingBank;
                 this.bestAwayBank = startingBank;
                 this.bestAwayBank = startingBank;
 
 
-                // TODO Fixa s� att man kontrollerar 1 �r bak�t i tiden som Filtered Matches,
-                // plocka bort om possitive results �r f�rre �n 50%
+                // TODO Fixa s� att man kontrollerar 1 år bakåt i tiden som Filtered Matches,
+                // plocka bort om possitive results är färreän 50%
                 recalcHome(matches);
                 recalcHome(matches);
                 recalcDraw(matches);
                 recalcDraw(matches);
                 recalcAway(matches);
                 recalcAway(matches);