overtime-live-trading-utils 2.1.43 → 2.1.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/.circleci/config.yml +32 -32
  2. package/.prettierrc +9 -9
  3. package/codecov.yml +20 -20
  4. package/index.ts +26 -26
  5. package/jest.config.ts +16 -16
  6. package/main.js +1 -1
  7. package/package.json +30 -30
  8. package/src/constants/common.ts +7 -7
  9. package/src/constants/errors.ts +6 -6
  10. package/src/constants/sports.ts +78 -78
  11. package/src/enums/sports.ts +109 -109
  12. package/src/tests/mock/MockLeagueMap.ts +170 -170
  13. package/src/tests/mock/MockOpticOddsEvents.ts +662 -662
  14. package/src/tests/mock/MockOpticSoccer.ts +9378 -9378
  15. package/src/tests/mock/MockSoccerRedis.ts +2308 -2308
  16. package/src/tests/unit/bookmakers.test.ts +79 -79
  17. package/src/tests/unit/markets.test.ts +156 -156
  18. package/src/tests/unit/odds.test.ts +92 -92
  19. package/src/tests/unit/resolution.test.ts +1489 -1489
  20. package/src/tests/unit/sports.test.ts +58 -58
  21. package/src/tests/unit/spread.test.ts +131 -131
  22. package/src/types/missing-types.d.ts +2 -2
  23. package/src/types/odds.ts +61 -61
  24. package/src/types/resolution.ts +656 -656
  25. package/src/types/sports.ts +19 -19
  26. package/src/utils/bookmakers.ts +159 -159
  27. package/src/utils/constraints.ts +210 -210
  28. package/src/utils/gameMatching.ts +81 -81
  29. package/src/utils/markets.ts +119 -119
  30. package/src/utils/odds.ts +918 -918
  31. package/src/utils/opticOdds.ts +71 -71
  32. package/src/utils/resolution.ts +319 -319
  33. package/src/utils/sportPeriodMapping.ts +36 -36
  34. package/src/utils/sports.ts +51 -51
  35. package/src/utils/spread.ts +97 -97
  36. package/tsconfig.json +16 -16
  37. package/webpack.config.js +24 -24
  38. package/CLAUDE.md +0 -84
  39. package/resolution_live_markets.md +0 -356
@@ -1,210 +1,210 @@
1
- import { League, Sport, getLeagueSport } from 'overtime-utils';
2
- import { ScoresObject } from '../types/odds';
3
-
4
- export const checkGameContraints = (
5
- opticOddsScoresApiResponse: ScoresObject,
6
- marketLeague: League,
7
- constraintsMap: Map<Sport, number>
8
- ) => {
9
- const marketSport = getLeagueSport(marketLeague);
10
- const homeTeam = opticOddsScoresApiResponse.homeTeam;
11
- const awayTeam = opticOddsScoresApiResponse.awayTeam;
12
-
13
- const currentClock = opticOddsScoresApiResponse.clock;
14
- const currentPeriod = opticOddsScoresApiResponse.period;
15
- const currentGameStatus = opticOddsScoresApiResponse.status;
16
-
17
- if (currentGameStatus.toLowerCase() == 'completed') {
18
- return {
19
- allow: false,
20
- message: `Blocking game ${homeTeam} - ${awayTeam} because it is no longer live.`,
21
- };
22
- }
23
-
24
- if (marketSport === Sport.SOCCER) {
25
- return allowSoccerGame(homeTeam, awayTeam, currentClock, currentPeriod, constraintsMap.get(Sport.SOCCER));
26
- }
27
-
28
- return {
29
- allow: true,
30
- message: `The sport ${marketLeague} does not have constraint`,
31
- };
32
- };
33
-
34
- export const allowGameSportWithPeriodConstraint = (
35
- homeTeam: string,
36
- awayTeam: string,
37
- currentPeriod: number,
38
- periodLimitForLiveTrade: number
39
- ) => {
40
- if (!Number.isNaN(currentPeriod) && currentPeriod >= periodLimitForLiveTrade) {
41
- return {
42
- allow: false,
43
- message: `Blocking game ${homeTeam} - ${awayTeam} due to period: ${currentPeriod}. period`,
44
- };
45
- }
46
- return { allow: true, message: '' };
47
- };
48
-
49
- export const allowSoccerGame = (
50
- homeTeam: string,
51
- awayTeam: string,
52
- currentClock: string,
53
- currentPeriod: string,
54
- soccerMinuteLimitForLiveTrading: number | undefined
55
- ) => {
56
- const currentClockNumber = Number(currentClock);
57
- if (
58
- (!Number.isNaN(currentClockNumber) &&
59
- soccerMinuteLimitForLiveTrading !== undefined &&
60
- currentClockNumber >= soccerMinuteLimitForLiveTrading) ||
61
- (Number.isNaN(currentClockNumber) && currentPeriod.toLowerCase() != 'half')
62
- ) {
63
- return { allow: false, message: `Blocking game ${homeTeam} - ${awayTeam} due to clock: ${currentClock}min` };
64
- }
65
-
66
- return { allow: true, message: '' };
67
- };
68
-
69
- export const allowGameSportWithResultConstraint = (
70
- opticOddsScoresApiResponse: ScoresObject,
71
- homeTeam: string,
72
- awayTeam: string,
73
- currentPeriod: string,
74
- currentScoreHome: number,
75
- currentScoreAway: number,
76
- marketLeague: League,
77
- marketSport: Sport
78
- ) => {
79
- const setInProgress = Number(currentPeriod);
80
- const currentResultInSet = fetchResultInCurrentSet(setInProgress, opticOddsScoresApiResponse);
81
- const atpGrandSlamMatch = opticOddsScoresApiResponse.league.toLowerCase() == 'atp';
82
- const currentSetsScore = { home: currentScoreHome, away: currentScoreAway };
83
-
84
- if (marketSport == Sport.VOLLEYBALL) {
85
- if (setInProgress == 5) {
86
- return checkResultConstraint(
87
- homeTeam,
88
- awayTeam,
89
- currentResultInSet,
90
- currentSetsScore,
91
- VOLLEYBALL_SET_THRESHOLD,
92
- VOLLEYBALL_FIFTH_SET_POINTS_LIMIT
93
- );
94
- } else {
95
- return checkResultConstraint(
96
- homeTeam,
97
- awayTeam,
98
- currentResultInSet,
99
- currentSetsScore,
100
- VOLLEYBALL_SET_THRESHOLD,
101
- VOLLEYBALL_POINTS_LIMIT
102
- );
103
- }
104
- }
105
-
106
- if (marketLeague.toString().startsWith(League.TENNIS_GS.toString()) && atpGrandSlamMatch) {
107
- return checkResultConstraint(
108
- homeTeam,
109
- awayTeam,
110
- currentResultInSet,
111
- currentSetsScore,
112
- TENNIS_ATP_GRAND_SLAM_SET_THRESHOLD,
113
- TENNIS_GEMS_LIMIT
114
- );
115
- }
116
-
117
- if (
118
- (marketLeague.toString().startsWith(League.TENNIS_GS.toString()) && !atpGrandSlamMatch) ||
119
- marketLeague.toString().startsWith(League.TENNIS_MASTERS.toString()) ||
120
- marketLeague.toString().startsWith(League.SUMMER_OLYMPICS_TENNIS.toString()) ||
121
- marketLeague.toString().startsWith(League.TENNIS_WTA.toString()) ||
122
- marketLeague.toString().startsWith(League.TENNIS_ATP_CHALLENGER.toString())
123
- ) {
124
- return checkResultConstraint(
125
- homeTeam,
126
- awayTeam,
127
- currentResultInSet,
128
- currentSetsScore,
129
- TENNIS_MASTERS_SET_THRESHOLD,
130
- TENNIS_GEMS_LIMIT
131
- );
132
- }
133
-
134
- return {
135
- allow: true,
136
- message: `The sport ${marketLeague} does not have result constraint`,
137
- };
138
- };
139
-
140
- export const fetchResultInCurrentSet = (currentSet: number, opticOddsScoresApiResponse: ScoresObject) => {
141
- let currentHomeGameScore = 0;
142
- let currentAwayGameScore = 0;
143
- switch (currentSet) {
144
- case 1:
145
- currentHomeGameScore = Number(opticOddsScoresApiResponse.homePeriod1);
146
- currentAwayGameScore = Number(opticOddsScoresApiResponse.awayPeriod1);
147
- break;
148
- case 2:
149
- currentHomeGameScore = Number(opticOddsScoresApiResponse.homePeriod2);
150
- currentAwayGameScore = Number(opticOddsScoresApiResponse.awayPeriod2);
151
- break;
152
- case 3:
153
- currentHomeGameScore = Number(opticOddsScoresApiResponse.homePeriod3);
154
- currentAwayGameScore = Number(opticOddsScoresApiResponse.awayPeriod3);
155
- break;
156
- case 4:
157
- currentHomeGameScore = Number(opticOddsScoresApiResponse.homePeriod4);
158
- currentAwayGameScore = Number(opticOddsScoresApiResponse.awayPeriod4);
159
- break;
160
- case 5:
161
- currentHomeGameScore = Number(opticOddsScoresApiResponse.homePeriod5);
162
- currentAwayGameScore = Number(opticOddsScoresApiResponse.awayPeriod5);
163
- break;
164
- }
165
- return { home: currentHomeGameScore, away: currentAwayGameScore };
166
- };
167
-
168
- const checkResultConstraint = (
169
- homeTeam: string,
170
- awayTeam: string,
171
- currentResultInSet: { home: number; away: number },
172
- currentSetsWon: { home: number; away: number },
173
- setThreshold: number,
174
- resultLimit: number
175
- ) => {
176
- if (Number(currentSetsWon.home) == setThreshold || Number(currentSetsWon.away) == setThreshold) {
177
- if (Number(currentSetsWon.home) == setThreshold && currentResultInSet.home >= resultLimit) {
178
- return {
179
- allow: false,
180
- message: `Blocking game ${homeTeam} - ${awayTeam} due to current result: ${currentSetsWon.home} - ${currentSetsWon.away} (${currentResultInSet.home} - ${currentResultInSet.away})`,
181
- };
182
- }
183
-
184
- if (Number(currentSetsWon.away) == setThreshold && currentResultInSet.away >= resultLimit) {
185
- return {
186
- allow: false,
187
- message: `Blocking game ${homeTeam} - ${awayTeam} due to current result: ${currentSetsWon.home} - ${currentSetsWon.away} (${currentResultInSet.home} - ${currentResultInSet.away})`,
188
- };
189
- }
190
- return {
191
- allow: true,
192
- message: '',
193
- currentHomeGameScore: currentResultInSet.home,
194
- currentAwayGameScore: currentResultInSet.away,
195
- };
196
- }
197
- return {
198
- allow: true,
199
- message: '',
200
- currentHomeGameScore: currentResultInSet.home,
201
- currentAwayGameScore: currentResultInSet.away,
202
- };
203
- };
204
-
205
- const VOLLEYBALL_SET_THRESHOLD = 2;
206
- const VOLLEYBALL_POINTS_LIMIT = 20;
207
- const VOLLEYBALL_FIFTH_SET_POINTS_LIMIT = 10;
208
- const TENNIS_ATP_GRAND_SLAM_SET_THRESHOLD = 2;
209
- const TENNIS_MASTERS_SET_THRESHOLD = 1;
210
- const TENNIS_GEMS_LIMIT = 5;
1
+ import { League, Sport, getLeagueSport } from 'overtime-utils';
2
+ import { ScoresObject } from '../types/odds';
3
+
4
+ export const checkGameContraints = (
5
+ opticOddsScoresApiResponse: ScoresObject,
6
+ marketLeague: League,
7
+ constraintsMap: Map<Sport, number>
8
+ ) => {
9
+ const marketSport = getLeagueSport(marketLeague);
10
+ const homeTeam = opticOddsScoresApiResponse.homeTeam;
11
+ const awayTeam = opticOddsScoresApiResponse.awayTeam;
12
+
13
+ const currentClock = opticOddsScoresApiResponse.clock;
14
+ const currentPeriod = opticOddsScoresApiResponse.period;
15
+ const currentGameStatus = opticOddsScoresApiResponse.status;
16
+
17
+ if (currentGameStatus.toLowerCase() == 'completed') {
18
+ return {
19
+ allow: false,
20
+ message: `Blocking game ${homeTeam} - ${awayTeam} because it is no longer live.`,
21
+ };
22
+ }
23
+
24
+ if (marketSport === Sport.SOCCER) {
25
+ return allowSoccerGame(homeTeam, awayTeam, currentClock, currentPeriod, constraintsMap.get(Sport.SOCCER));
26
+ }
27
+
28
+ return {
29
+ allow: true,
30
+ message: `The sport ${marketLeague} does not have constraint`,
31
+ };
32
+ };
33
+
34
+ export const allowGameSportWithPeriodConstraint = (
35
+ homeTeam: string,
36
+ awayTeam: string,
37
+ currentPeriod: number,
38
+ periodLimitForLiveTrade: number
39
+ ) => {
40
+ if (!Number.isNaN(currentPeriod) && currentPeriod >= periodLimitForLiveTrade) {
41
+ return {
42
+ allow: false,
43
+ message: `Blocking game ${homeTeam} - ${awayTeam} due to period: ${currentPeriod}. period`,
44
+ };
45
+ }
46
+ return { allow: true, message: '' };
47
+ };
48
+
49
+ export const allowSoccerGame = (
50
+ homeTeam: string,
51
+ awayTeam: string,
52
+ currentClock: string,
53
+ currentPeriod: string,
54
+ soccerMinuteLimitForLiveTrading: number | undefined
55
+ ) => {
56
+ const currentClockNumber = Number(currentClock);
57
+ if (
58
+ (!Number.isNaN(currentClockNumber) &&
59
+ soccerMinuteLimitForLiveTrading !== undefined &&
60
+ currentClockNumber >= soccerMinuteLimitForLiveTrading) ||
61
+ (Number.isNaN(currentClockNumber) && currentPeriod.toLowerCase() != 'half')
62
+ ) {
63
+ return { allow: false, message: `Blocking game ${homeTeam} - ${awayTeam} due to clock: ${currentClock}min` };
64
+ }
65
+
66
+ return { allow: true, message: '' };
67
+ };
68
+
69
+ export const allowGameSportWithResultConstraint = (
70
+ opticOddsScoresApiResponse: ScoresObject,
71
+ homeTeam: string,
72
+ awayTeam: string,
73
+ currentPeriod: string,
74
+ currentScoreHome: number,
75
+ currentScoreAway: number,
76
+ marketLeague: League,
77
+ marketSport: Sport
78
+ ) => {
79
+ const setInProgress = Number(currentPeriod);
80
+ const currentResultInSet = fetchResultInCurrentSet(setInProgress, opticOddsScoresApiResponse);
81
+ const atpGrandSlamMatch = opticOddsScoresApiResponse.league.toLowerCase() == 'atp';
82
+ const currentSetsScore = { home: currentScoreHome, away: currentScoreAway };
83
+
84
+ if (marketSport == Sport.VOLLEYBALL) {
85
+ if (setInProgress == 5) {
86
+ return checkResultConstraint(
87
+ homeTeam,
88
+ awayTeam,
89
+ currentResultInSet,
90
+ currentSetsScore,
91
+ VOLLEYBALL_SET_THRESHOLD,
92
+ VOLLEYBALL_FIFTH_SET_POINTS_LIMIT
93
+ );
94
+ } else {
95
+ return checkResultConstraint(
96
+ homeTeam,
97
+ awayTeam,
98
+ currentResultInSet,
99
+ currentSetsScore,
100
+ VOLLEYBALL_SET_THRESHOLD,
101
+ VOLLEYBALL_POINTS_LIMIT
102
+ );
103
+ }
104
+ }
105
+
106
+ if (marketLeague.toString().startsWith(League.TENNIS_GS.toString()) && atpGrandSlamMatch) {
107
+ return checkResultConstraint(
108
+ homeTeam,
109
+ awayTeam,
110
+ currentResultInSet,
111
+ currentSetsScore,
112
+ TENNIS_ATP_GRAND_SLAM_SET_THRESHOLD,
113
+ TENNIS_GEMS_LIMIT
114
+ );
115
+ }
116
+
117
+ if (
118
+ (marketLeague.toString().startsWith(League.TENNIS_GS.toString()) && !atpGrandSlamMatch) ||
119
+ marketLeague.toString().startsWith(League.TENNIS_MASTERS.toString()) ||
120
+ marketLeague.toString().startsWith(League.SUMMER_OLYMPICS_TENNIS.toString()) ||
121
+ marketLeague.toString().startsWith(League.TENNIS_WTA.toString()) ||
122
+ marketLeague.toString().startsWith(League.TENNIS_ATP_CHALLENGER.toString())
123
+ ) {
124
+ return checkResultConstraint(
125
+ homeTeam,
126
+ awayTeam,
127
+ currentResultInSet,
128
+ currentSetsScore,
129
+ TENNIS_MASTERS_SET_THRESHOLD,
130
+ TENNIS_GEMS_LIMIT
131
+ );
132
+ }
133
+
134
+ return {
135
+ allow: true,
136
+ message: `The sport ${marketLeague} does not have result constraint`,
137
+ };
138
+ };
139
+
140
+ export const fetchResultInCurrentSet = (currentSet: number, opticOddsScoresApiResponse: ScoresObject) => {
141
+ let currentHomeGameScore = 0;
142
+ let currentAwayGameScore = 0;
143
+ switch (currentSet) {
144
+ case 1:
145
+ currentHomeGameScore = Number(opticOddsScoresApiResponse.homePeriod1);
146
+ currentAwayGameScore = Number(opticOddsScoresApiResponse.awayPeriod1);
147
+ break;
148
+ case 2:
149
+ currentHomeGameScore = Number(opticOddsScoresApiResponse.homePeriod2);
150
+ currentAwayGameScore = Number(opticOddsScoresApiResponse.awayPeriod2);
151
+ break;
152
+ case 3:
153
+ currentHomeGameScore = Number(opticOddsScoresApiResponse.homePeriod3);
154
+ currentAwayGameScore = Number(opticOddsScoresApiResponse.awayPeriod3);
155
+ break;
156
+ case 4:
157
+ currentHomeGameScore = Number(opticOddsScoresApiResponse.homePeriod4);
158
+ currentAwayGameScore = Number(opticOddsScoresApiResponse.awayPeriod4);
159
+ break;
160
+ case 5:
161
+ currentHomeGameScore = Number(opticOddsScoresApiResponse.homePeriod5);
162
+ currentAwayGameScore = Number(opticOddsScoresApiResponse.awayPeriod5);
163
+ break;
164
+ }
165
+ return { home: currentHomeGameScore, away: currentAwayGameScore };
166
+ };
167
+
168
+ const checkResultConstraint = (
169
+ homeTeam: string,
170
+ awayTeam: string,
171
+ currentResultInSet: { home: number; away: number },
172
+ currentSetsWon: { home: number; away: number },
173
+ setThreshold: number,
174
+ resultLimit: number
175
+ ) => {
176
+ if (Number(currentSetsWon.home) == setThreshold || Number(currentSetsWon.away) == setThreshold) {
177
+ if (Number(currentSetsWon.home) == setThreshold && currentResultInSet.home >= resultLimit) {
178
+ return {
179
+ allow: false,
180
+ message: `Blocking game ${homeTeam} - ${awayTeam} due to current result: ${currentSetsWon.home} - ${currentSetsWon.away} (${currentResultInSet.home} - ${currentResultInSet.away})`,
181
+ };
182
+ }
183
+
184
+ if (Number(currentSetsWon.away) == setThreshold && currentResultInSet.away >= resultLimit) {
185
+ return {
186
+ allow: false,
187
+ message: `Blocking game ${homeTeam} - ${awayTeam} due to current result: ${currentSetsWon.home} - ${currentSetsWon.away} (${currentResultInSet.home} - ${currentResultInSet.away})`,
188
+ };
189
+ }
190
+ return {
191
+ allow: true,
192
+ message: '',
193
+ currentHomeGameScore: currentResultInSet.home,
194
+ currentAwayGameScore: currentResultInSet.away,
195
+ };
196
+ }
197
+ return {
198
+ allow: true,
199
+ message: '',
200
+ currentHomeGameScore: currentResultInSet.home,
201
+ currentAwayGameScore: currentResultInSet.away,
202
+ };
203
+ };
204
+
205
+ const VOLLEYBALL_SET_THRESHOLD = 2;
206
+ const VOLLEYBALL_POINTS_LIMIT = 20;
207
+ const VOLLEYBALL_FIFTH_SET_POINTS_LIMIT = 10;
208
+ const TENNIS_ATP_GRAND_SLAM_SET_THRESHOLD = 2;
209
+ const TENNIS_MASTERS_SET_THRESHOLD = 1;
210
+ const TENNIS_GEMS_LIMIT = 5;
@@ -1,81 +1,81 @@
1
- import { LEAGUES_NO_FORMAL_HOME_AWAY } from '../constants/sports';
2
-
3
- export const teamNamesMatching = (
4
- leagueId: number,
5
- marketHomeTeam: string,
6
- marketAwayTeam: string,
7
- apiHomeTeam: string,
8
- apiAwayTeam: string,
9
- teamsMap: Map<string, string>
10
- ) => {
11
- let homeTeamsMatch;
12
- let awayTeamsMatch;
13
-
14
- if (LEAGUES_NO_FORMAL_HOME_AWAY.includes(leagueId)) {
15
- homeTeamsMatch =
16
- apiHomeTeam.toLowerCase() == marketHomeTeam.toLowerCase() ||
17
- apiHomeTeam.toLowerCase() == marketAwayTeam.toLowerCase();
18
- awayTeamsMatch =
19
- apiAwayTeam.toLowerCase() == marketHomeTeam.toLowerCase() ||
20
- apiAwayTeam.toLowerCase() == marketAwayTeam.toLowerCase();
21
- } else {
22
- homeTeamsMatch = apiHomeTeam.toLowerCase() == marketHomeTeam.toLowerCase();
23
- awayTeamsMatch = apiAwayTeam.toLowerCase() == marketAwayTeam.toLowerCase();
24
- }
25
-
26
- if (homeTeamsMatch !== true) {
27
- const homeTeamOpticOdds = teamsMap.get(apiHomeTeam.toLowerCase());
28
- const gameHomeTeam = teamsMap.get(marketHomeTeam.toLowerCase());
29
- const gameAwayTeam = teamsMap.get(marketAwayTeam.toLowerCase());
30
- const hasUndefinedName = [homeTeamOpticOdds, gameHomeTeam].some((name) => name == undefined);
31
-
32
- if (hasUndefinedName) {
33
- return false;
34
- }
35
-
36
- if (LEAGUES_NO_FORMAL_HOME_AWAY.includes(leagueId)) {
37
- homeTeamsMatch = homeTeamOpticOdds == gameHomeTeam || homeTeamOpticOdds == gameAwayTeam;
38
- } else {
39
- homeTeamsMatch = homeTeamOpticOdds == gameHomeTeam;
40
- }
41
- }
42
-
43
- if (awayTeamsMatch !== true) {
44
- const awayTeamOpticOdds = teamsMap.get(apiAwayTeam.toLowerCase());
45
- const gameHomeTeam = teamsMap.get(marketHomeTeam.toLowerCase());
46
- const gameAwayTeam = teamsMap.get(marketAwayTeam.toLowerCase());
47
-
48
- const hasUndefinedName = [awayTeamOpticOdds, gameAwayTeam].some((name) => name == undefined);
49
-
50
- if (hasUndefinedName) {
51
- return false;
52
- }
53
-
54
- if (LEAGUES_NO_FORMAL_HOME_AWAY.includes(leagueId)) {
55
- awayTeamsMatch = awayTeamOpticOdds == gameHomeTeam || awayTeamOpticOdds == gameAwayTeam;
56
- } else {
57
- awayTeamsMatch = awayTeamOpticOdds == gameAwayTeam;
58
- }
59
- }
60
-
61
- return homeTeamsMatch && awayTeamsMatch;
62
- };
63
-
64
- export const gamesDatesMatching = (
65
- marketMaturityDate: Date,
66
- apiStartDate: Date,
67
- sportId: number,
68
- timeDifferenceMinutes: number
69
- ) => {
70
- let datesMatch = false;
71
- sportId; // TODO: remove it from callers
72
-
73
- const opticOddsTimestamp = apiStartDate.getTime();
74
- const marketTimestamp = marketMaturityDate.getTime();
75
- const differenceBetweenDates = Math.abs(marketTimestamp - opticOddsTimestamp);
76
- if (differenceBetweenDates <= Number(timeDifferenceMinutes * 60 * 1000)) {
77
- datesMatch = true;
78
- }
79
-
80
- return datesMatch;
81
- };
1
+ import { LEAGUES_NO_FORMAL_HOME_AWAY } from '../constants/sports';
2
+
3
+ export const teamNamesMatching = (
4
+ leagueId: number,
5
+ marketHomeTeam: string,
6
+ marketAwayTeam: string,
7
+ apiHomeTeam: string,
8
+ apiAwayTeam: string,
9
+ teamsMap: Map<string, string>
10
+ ) => {
11
+ let homeTeamsMatch;
12
+ let awayTeamsMatch;
13
+
14
+ if (LEAGUES_NO_FORMAL_HOME_AWAY.includes(leagueId)) {
15
+ homeTeamsMatch =
16
+ apiHomeTeam.toLowerCase() == marketHomeTeam.toLowerCase() ||
17
+ apiHomeTeam.toLowerCase() == marketAwayTeam.toLowerCase();
18
+ awayTeamsMatch =
19
+ apiAwayTeam.toLowerCase() == marketHomeTeam.toLowerCase() ||
20
+ apiAwayTeam.toLowerCase() == marketAwayTeam.toLowerCase();
21
+ } else {
22
+ homeTeamsMatch = apiHomeTeam.toLowerCase() == marketHomeTeam.toLowerCase();
23
+ awayTeamsMatch = apiAwayTeam.toLowerCase() == marketAwayTeam.toLowerCase();
24
+ }
25
+
26
+ if (homeTeamsMatch !== true) {
27
+ const homeTeamOpticOdds = teamsMap.get(apiHomeTeam.toLowerCase());
28
+ const gameHomeTeam = teamsMap.get(marketHomeTeam.toLowerCase());
29
+ const gameAwayTeam = teamsMap.get(marketAwayTeam.toLowerCase());
30
+ const hasUndefinedName = [homeTeamOpticOdds, gameHomeTeam].some((name) => name == undefined);
31
+
32
+ if (hasUndefinedName) {
33
+ return false;
34
+ }
35
+
36
+ if (LEAGUES_NO_FORMAL_HOME_AWAY.includes(leagueId)) {
37
+ homeTeamsMatch = homeTeamOpticOdds == gameHomeTeam || homeTeamOpticOdds == gameAwayTeam;
38
+ } else {
39
+ homeTeamsMatch = homeTeamOpticOdds == gameHomeTeam;
40
+ }
41
+ }
42
+
43
+ if (awayTeamsMatch !== true) {
44
+ const awayTeamOpticOdds = teamsMap.get(apiAwayTeam.toLowerCase());
45
+ const gameHomeTeam = teamsMap.get(marketHomeTeam.toLowerCase());
46
+ const gameAwayTeam = teamsMap.get(marketAwayTeam.toLowerCase());
47
+
48
+ const hasUndefinedName = [awayTeamOpticOdds, gameAwayTeam].some((name) => name == undefined);
49
+
50
+ if (hasUndefinedName) {
51
+ return false;
52
+ }
53
+
54
+ if (LEAGUES_NO_FORMAL_HOME_AWAY.includes(leagueId)) {
55
+ awayTeamsMatch = awayTeamOpticOdds == gameHomeTeam || awayTeamOpticOdds == gameAwayTeam;
56
+ } else {
57
+ awayTeamsMatch = awayTeamOpticOdds == gameAwayTeam;
58
+ }
59
+ }
60
+
61
+ return homeTeamsMatch && awayTeamsMatch;
62
+ };
63
+
64
+ export const gamesDatesMatching = (
65
+ marketMaturityDate: Date,
66
+ apiStartDate: Date,
67
+ sportId: number,
68
+ timeDifferenceMinutes: number
69
+ ) => {
70
+ let datesMatch = false;
71
+ sportId; // TODO: remove it from callers
72
+
73
+ const opticOddsTimestamp = apiStartDate.getTime();
74
+ const marketTimestamp = marketMaturityDate.getTime();
75
+ const differenceBetweenDates = Math.abs(marketTimestamp - opticOddsTimestamp);
76
+ if (differenceBetweenDates <= Number(timeDifferenceMinutes * 60 * 1000)) {
77
+ datesMatch = true;
78
+ }
79
+
80
+ return datesMatch;
81
+ };