overtime-live-trading-utils 3.0.1 → 3.0.2-rc.1
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.
- package/main.js +1 -1
- package/package.json +1 -1
- package/src/tests/unit/bookmakers.test.ts +18 -7
- package/src/tests/unit/markets.test.ts +44 -7
- package/src/tests/unit/odds.test.ts +14 -5
- package/src/tests/unit/spread.test.ts +16 -6
- package/src/tests/utils/helper.ts +8 -0
- package/src/utils/markets.ts +4 -2
- package/src/utils/odds.ts +32 -8
package/package.json
CHANGED
|
@@ -10,9 +10,14 @@ import {
|
|
|
10
10
|
MockOnlyMoneylineWithDifferentSportsbook,
|
|
11
11
|
} from '../mock/MockOpticSoccer';
|
|
12
12
|
import { mockSoccer } from '../mock/MockSoccerRedis';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
getLastPolledDataForBookmakers,
|
|
15
|
+
getPlayersMap,
|
|
16
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
17
|
+
} from '../utils/helper';
|
|
14
18
|
|
|
15
19
|
const lastPolledData = getLastPolledDataForBookmakers();
|
|
20
|
+
const playersMap = getPlayersMap();
|
|
16
21
|
|
|
17
22
|
describe('Bookmakers', () => {
|
|
18
23
|
it('Should return zero odds for moneyline when one of the bookmakers has no odds', () => {
|
|
@@ -28,7 +33,8 @@ describe('Bookmakers', () => {
|
|
|
28
33
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
29
34
|
LeagueMocks.leagueInfoEnabledSpeadAndTotals,
|
|
30
35
|
lastPolledData,
|
|
31
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
36
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
37
|
+
playersMap
|
|
32
38
|
);
|
|
33
39
|
|
|
34
40
|
const hasOdds = market.odds.some(
|
|
@@ -53,7 +59,8 @@ describe('Bookmakers', () => {
|
|
|
53
59
|
5,
|
|
54
60
|
LeagueMocks.leagueInfoOnlyParent,
|
|
55
61
|
lastPolledData,
|
|
56
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
62
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
63
|
+
playersMap
|
|
57
64
|
);
|
|
58
65
|
|
|
59
66
|
const hasOdds = market.odds.some(
|
|
@@ -78,7 +85,8 @@ describe('Bookmakers', () => {
|
|
|
78
85
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
79
86
|
LeagueMocks.leagueInfoEnabledSpeadAndTotals,
|
|
80
87
|
lastPolledData,
|
|
81
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
88
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
89
|
+
playersMap
|
|
82
90
|
);
|
|
83
91
|
|
|
84
92
|
const hasOdds = market.odds.some(
|
|
@@ -103,7 +111,8 @@ describe('Bookmakers', () => {
|
|
|
103
111
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
104
112
|
LeagueMocks.leagueInfoEnabledSpeadAndTotals,
|
|
105
113
|
lastPolledData,
|
|
106
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
114
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
115
|
+
playersMap
|
|
107
116
|
);
|
|
108
117
|
|
|
109
118
|
expect(market.childMarkets.length).toBe(2);
|
|
@@ -122,7 +131,8 @@ describe('Bookmakers', () => {
|
|
|
122
131
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
123
132
|
LeagueMocks.leaguInfoDifferentPrimaryBookmaker,
|
|
124
133
|
lastPolledData,
|
|
125
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
134
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
135
|
+
playersMap
|
|
126
136
|
);
|
|
127
137
|
|
|
128
138
|
expect(market.childMarkets.length).toBe(3);
|
|
@@ -141,7 +151,8 @@ describe('Bookmakers', () => {
|
|
|
141
151
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
142
152
|
LeagueMocks.leagueInfoEnabledSpeadAndTotals,
|
|
143
153
|
lastPolledData,
|
|
144
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
154
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
155
|
+
playersMap
|
|
145
156
|
);
|
|
146
157
|
|
|
147
158
|
expect(market.childMarkets.length).toBe(1);
|
|
@@ -5,9 +5,16 @@ import { mapOpticOddsApiFixtureOdds } from '../../utils/opticOdds';
|
|
|
5
5
|
import { LeagueMocks } from '../mock/MockLeagueMap';
|
|
6
6
|
import { MockOnlyMoneyline, MockOpticSoccer } from '../mock/MockOpticSoccer';
|
|
7
7
|
import { mockSoccer } from '../mock/MockSoccerRedis';
|
|
8
|
-
import {
|
|
8
|
+
import { MockNbaData } from '../mock/OpticOddsMock/MockNBA';
|
|
9
|
+
import { MockRedisNba } from '../mock/OpticOddsMock/MockRedisNba';
|
|
10
|
+
import {
|
|
11
|
+
getLastPolledDataForBookmakers,
|
|
12
|
+
getPlayersMap,
|
|
13
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
14
|
+
} from '../utils/helper';
|
|
9
15
|
|
|
10
16
|
const lastPolledData = getLastPolledDataForBookmakers();
|
|
17
|
+
const playersMap = getPlayersMap();
|
|
11
18
|
|
|
12
19
|
describe('Markets', () => {
|
|
13
20
|
describe('LeagueMap configuration', () => {
|
|
@@ -25,7 +32,8 @@ describe('Markets', () => {
|
|
|
25
32
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
26
33
|
LeagueMocks.leagueInfoOnlyParent,
|
|
27
34
|
lastPolledData,
|
|
28
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
35
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
36
|
+
playersMap
|
|
29
37
|
);
|
|
30
38
|
|
|
31
39
|
expect(market.childMarkets).toHaveLength(0);
|
|
@@ -44,7 +52,8 @@ describe('Markets', () => {
|
|
|
44
52
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
45
53
|
LeagueMocks.leagueInfoMockDisabledChilds,
|
|
46
54
|
lastPolledData,
|
|
47
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
55
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
56
|
+
playersMap
|
|
48
57
|
);
|
|
49
58
|
|
|
50
59
|
expect(market.childMarkets).toHaveLength(0);
|
|
@@ -63,7 +72,8 @@ describe('Markets', () => {
|
|
|
63
72
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
64
73
|
LeagueMocks.leagueInfoEnabledSpreadDisabledTotals,
|
|
65
74
|
lastPolledData,
|
|
66
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
75
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
76
|
+
playersMap
|
|
67
77
|
);
|
|
68
78
|
|
|
69
79
|
const containsSpread = market.childMarkets.some((child: any) => child.type === 'spread');
|
|
@@ -86,7 +96,8 @@ describe('Markets', () => {
|
|
|
86
96
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
87
97
|
LeagueMocks.leagueInfoEnabledSpeadAndTotals,
|
|
88
98
|
lastPolledData,
|
|
89
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
99
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
100
|
+
playersMap
|
|
90
101
|
);
|
|
91
102
|
|
|
92
103
|
const containsSpread = market.childMarkets.some((child: any) => child.type === 'spread');
|
|
@@ -109,7 +120,8 @@ describe('Markets', () => {
|
|
|
109
120
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
110
121
|
LeagueMocks.leagueInfoEnabledAll,
|
|
111
122
|
lastPolledData,
|
|
112
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
123
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
124
|
+
playersMap
|
|
113
125
|
);
|
|
114
126
|
|
|
115
127
|
const containsSpread = market.childMarkets.some((child: any) => child.type === 'spread');
|
|
@@ -164,7 +176,8 @@ describe('Markets', () => {
|
|
|
164
176
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
165
177
|
LeagueMocks.leagueInfoOnlyParentDiffSportId,
|
|
166
178
|
lastPolledData,
|
|
167
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
179
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
180
|
+
playersMap
|
|
168
181
|
);
|
|
169
182
|
|
|
170
183
|
expect(warnSpy).toHaveBeenCalled();
|
|
@@ -173,5 +186,29 @@ describe('Markets', () => {
|
|
|
173
186
|
// Restore the original implementation
|
|
174
187
|
warnSpy.mockRestore();
|
|
175
188
|
});
|
|
189
|
+
|
|
190
|
+
it('Should return child markets with player props', () => {
|
|
191
|
+
const freshMockSoccer = JSON.parse(JSON.stringify(MockRedisNba));
|
|
192
|
+
const freshMockOpticSoccer = JSON.parse(JSON.stringify(MockNbaData));
|
|
193
|
+
const market = processMarket(
|
|
194
|
+
freshMockSoccer,
|
|
195
|
+
mapOpticOddsApiFixtureOdds([freshMockOpticSoccer])[0],
|
|
196
|
+
['bovada', 'draftkings'], // this will be ignored as primaryBookmaker is defined in LeagueMap
|
|
197
|
+
[],
|
|
198
|
+
true,
|
|
199
|
+
undefined,
|
|
200
|
+
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
201
|
+
LeagueMocks.PlayerAssist, // league map with player props configured
|
|
202
|
+
lastPolledData,
|
|
203
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
204
|
+
playersMap
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
market.childMarkets.forEach((child: any) => {
|
|
208
|
+
expect(child.playerProps).toBeDefined();
|
|
209
|
+
expect(child.playerProps.playerId).toBeDefined();
|
|
210
|
+
expect(child.playerProps.playerName).toBeDefined();
|
|
211
|
+
});
|
|
212
|
+
});
|
|
176
213
|
});
|
|
177
214
|
});
|
|
@@ -10,9 +10,14 @@ import {
|
|
|
10
10
|
MockZeroOdds,
|
|
11
11
|
} from '../mock/MockOpticSoccer';
|
|
12
12
|
import { mockSoccer } from '../mock/MockSoccerRedis';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
getLastPolledDataForBookmakers,
|
|
15
|
+
getPlayersMap,
|
|
16
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
17
|
+
} from '../utils/helper';
|
|
14
18
|
|
|
15
19
|
const lastPolledData = getLastPolledDataForBookmakers();
|
|
20
|
+
const playersMap = getPlayersMap();
|
|
16
21
|
|
|
17
22
|
describe('Odds', () => {
|
|
18
23
|
it('Should return odds for moneyline', () => {
|
|
@@ -28,7 +33,8 @@ describe('Odds', () => {
|
|
|
28
33
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
29
34
|
LeagueMocks.leagueInfoOnlyParent,
|
|
30
35
|
lastPolledData,
|
|
31
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
36
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
37
|
+
playersMap
|
|
32
38
|
);
|
|
33
39
|
|
|
34
40
|
const hasOdds = market.odds.some(
|
|
@@ -51,7 +57,8 @@ describe('Odds', () => {
|
|
|
51
57
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
52
58
|
LeagueMocks.leagueInfoEnabledSpeadAndTotals,
|
|
53
59
|
lastPolledData,
|
|
54
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
60
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
61
|
+
playersMap
|
|
55
62
|
);
|
|
56
63
|
|
|
57
64
|
const hasOdds = market.odds.some(
|
|
@@ -76,7 +83,8 @@ describe('Odds', () => {
|
|
|
76
83
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
77
84
|
LeagueMocks.leagueInfoEnabledSpeadAndTotals,
|
|
78
85
|
lastPolledData,
|
|
79
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
86
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
87
|
+
playersMap
|
|
80
88
|
);
|
|
81
89
|
|
|
82
90
|
const hasChildMarkets = market.childMarkets.length > 0;
|
|
@@ -96,7 +104,8 @@ describe('Odds', () => {
|
|
|
96
104
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
97
105
|
LeagueMocks.leagueInfoEnabledSpeadAndTotals,
|
|
98
106
|
lastPolledData,
|
|
99
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
107
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
108
|
+
playersMap
|
|
100
109
|
);
|
|
101
110
|
|
|
102
111
|
expect(market.childMarkets).toHaveLength(0);
|
|
@@ -5,9 +5,14 @@ import { mapOpticOddsApiFixtureOdds } from '../../utils/opticOdds';
|
|
|
5
5
|
import { LeagueMocks } from '../mock/MockLeagueMap';
|
|
6
6
|
import { MockAfterSpreadZeroOdds1, MockOnlyMoneylineFavorite, MockOpticSoccer } from '../mock/MockOpticSoccer';
|
|
7
7
|
import { mockSoccer } from '../mock/MockSoccerRedis';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
getLastPolledDataForBookmakers,
|
|
10
|
+
getPlayersMap,
|
|
11
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
12
|
+
} from '../utils/helper';
|
|
9
13
|
|
|
10
14
|
const lastPolledData = getLastPolledDataForBookmakers();
|
|
15
|
+
const playersMap = getPlayersMap();
|
|
11
16
|
|
|
12
17
|
describe('Spread configuration', () => {
|
|
13
18
|
it('Should return zero odds for quotes that sum up total probability above 1', () => {
|
|
@@ -23,7 +28,8 @@ describe('Spread configuration', () => {
|
|
|
23
28
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
24
29
|
LeagueMocks.leagueInfoEnabledSpeadAndTotals,
|
|
25
30
|
lastPolledData,
|
|
26
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
31
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
32
|
+
playersMap
|
|
27
33
|
);
|
|
28
34
|
|
|
29
35
|
const hasOdds = market.odds.some(
|
|
@@ -50,7 +56,8 @@ describe('Spread configuration', () => {
|
|
|
50
56
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
51
57
|
LeagueMocks.leagueInfoOnlyParent,
|
|
52
58
|
lastPolledData,
|
|
53
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
59
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
60
|
+
playersMap
|
|
54
61
|
)
|
|
55
62
|
)
|
|
56
63
|
);
|
|
@@ -67,7 +74,8 @@ describe('Spread configuration', () => {
|
|
|
67
74
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
68
75
|
LeagueMocks.leagueInfoOnlyParentWithSpreadAdded,
|
|
69
76
|
lastPolledData,
|
|
70
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
77
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
78
|
+
playersMap
|
|
71
79
|
)
|
|
72
80
|
)
|
|
73
81
|
);
|
|
@@ -104,7 +112,8 @@ describe('Spread configuration', () => {
|
|
|
104
112
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
105
113
|
LeagueMocks.leagueInfoOnlyParent,
|
|
106
114
|
lastPolledData,
|
|
107
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
115
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
116
|
+
playersMap
|
|
108
117
|
)
|
|
109
118
|
)
|
|
110
119
|
);
|
|
@@ -121,7 +130,8 @@ describe('Spread configuration', () => {
|
|
|
121
130
|
MAX_IMPLIED_PERCENTAGE_DIFF,
|
|
122
131
|
LeagueMocks.leagueInfoOnlyParentWithSpreadAdded,
|
|
123
132
|
lastPolledData,
|
|
124
|
-
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST
|
|
133
|
+
MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST,
|
|
134
|
+
playersMap
|
|
125
135
|
)
|
|
126
136
|
)
|
|
127
137
|
);
|
|
@@ -8,4 +8,12 @@ export const getLastPolledDataForBookmakers = () => {
|
|
|
8
8
|
return lastPolledData;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
+
export const getPlayersMap = () => {
|
|
12
|
+
const playersMap: Map<string, number> = new Map<string, number>();
|
|
13
|
+
playersMap.set('0C07D14CC5DC', 13234);
|
|
14
|
+
playersMap.set('AD91EA260284', 56789);
|
|
15
|
+
playersMap.set('674851E026BC', 98765);
|
|
16
|
+
return playersMap;
|
|
17
|
+
};
|
|
18
|
+
|
|
11
19
|
export const MAX_ALLOWED_PROVIDER_DATA_STALE_DELAY_TEST = 30000; // 30 seconds
|
package/src/utils/markets.ts
CHANGED
|
@@ -30,7 +30,8 @@ export const processMarket = (
|
|
|
30
30
|
maxPercentageDiffBetwenOdds: number,
|
|
31
31
|
leagueMap: any,
|
|
32
32
|
lastPolledData: LastPolledArray,
|
|
33
|
-
maxAllowedProviderDataStaleDelay: number
|
|
33
|
+
maxAllowedProviderDataStaleDelay: number,
|
|
34
|
+
playersMap: Map<string, number>
|
|
34
35
|
) => {
|
|
35
36
|
const sportSpreadData = spreadData.filter((data: any) => data.sportId === String(market.leagueId));
|
|
36
37
|
const leagueInfo = getLeagueInfo(market.leagueId, leagueMap);
|
|
@@ -89,7 +90,8 @@ export const processMarket = (
|
|
|
89
90
|
leagueMap,
|
|
90
91
|
lastPolledData,
|
|
91
92
|
maxAllowedProviderDataStaleDelay,
|
|
92
|
-
maxPercentageDiffBetwenOdds
|
|
93
|
+
maxPercentageDiffBetwenOdds,
|
|
94
|
+
playersMap
|
|
93
95
|
);
|
|
94
96
|
|
|
95
97
|
const packedChildMarkets = childMarkets.map((childMarket: any) => {
|
package/src/utils/odds.ts
CHANGED
|
@@ -214,7 +214,8 @@ export const createChildMarkets: (
|
|
|
214
214
|
leagueMap: any,
|
|
215
215
|
lastPolledData: LastPolledArray,
|
|
216
216
|
maxAllowedProviderDataStaleDelay: number,
|
|
217
|
-
maxImpliedPercentageDifference: number
|
|
217
|
+
maxImpliedPercentageDifference: number,
|
|
218
|
+
playersMap: Map<string, number>
|
|
218
219
|
) => ChildMarket[] = (
|
|
219
220
|
apiResponseWithOdds,
|
|
220
221
|
spreadDataForSport,
|
|
@@ -224,7 +225,8 @@ export const createChildMarkets: (
|
|
|
224
225
|
leagueMap,
|
|
225
226
|
lastPolledData,
|
|
226
227
|
maxAllowedProviderDataStaleDelay,
|
|
227
|
-
maxImpliedPercentageDifference
|
|
228
|
+
maxImpliedPercentageDifference,
|
|
229
|
+
playersMap
|
|
228
230
|
) => {
|
|
229
231
|
const [spreadOdds, totalOdds, moneylineOdds, correctScoreOdds, doubleChanceOdds, ggOdds, childMarkets]: any[] = [
|
|
230
232
|
[],
|
|
@@ -242,7 +244,7 @@ export const createChildMarkets: (
|
|
|
242
244
|
};
|
|
243
245
|
|
|
244
246
|
if (leagueInfo.length > 0) {
|
|
245
|
-
const allChildOdds =
|
|
247
|
+
const allChildOdds = filterOdds(apiResponseWithOdds.odds, leagueInfo, playersMap);
|
|
246
248
|
const checkedChildOdds = checkOddsFromBookmakersForChildMarkets(
|
|
247
249
|
allChildOdds,
|
|
248
250
|
leagueInfo,
|
|
@@ -269,7 +271,7 @@ export const createChildMarkets: (
|
|
|
269
271
|
|
|
270
272
|
const homeAwayFormattedOdds = [
|
|
271
273
|
...groupAndFormatSpreadOdds(spreadOdds, commonData),
|
|
272
|
-
...groupAndFormatTotalOdds(totalOdds, commonData),
|
|
274
|
+
...groupAndFormatTotalOdds(totalOdds, commonData), // playerProps are handled inside this function
|
|
273
275
|
...groupAndFormatMoneylineOdds(moneylineOdds, commonData),
|
|
274
276
|
...groupAndFormatGGOdds(ggOdds),
|
|
275
277
|
...groupAndFormatDoubleChanceOdds(doubleChanceOdds, commonData),
|
|
@@ -284,12 +286,23 @@ export const createChildMarkets: (
|
|
|
284
286
|
);
|
|
285
287
|
|
|
286
288
|
homeAwayOddsWithSpreadAdjusted.forEach((data) => {
|
|
289
|
+
let playerProps = {
|
|
290
|
+
playerId: 0,
|
|
291
|
+
playerName: '',
|
|
292
|
+
};
|
|
293
|
+
if (data.playerProps) {
|
|
294
|
+
playerProps = {
|
|
295
|
+
playerId: playersMap.get(data.playerProps.playerId.toString()) || 0, // convert from opticOdds playerId to our internal playerId
|
|
296
|
+
playerName: data.playerProps.playerName,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
287
299
|
const childMarket = {
|
|
288
300
|
leagueId: Number(data.sportId),
|
|
289
301
|
typeId: Number(data.typeId),
|
|
290
302
|
type: MarketTypeMap[data.typeId as MarketType]?.key || '',
|
|
291
303
|
line: Number(data.line || 0),
|
|
292
304
|
odds: data.odds,
|
|
305
|
+
playerProps,
|
|
293
306
|
};
|
|
294
307
|
const leagueInfoByTypeId = leagueInfo.find((league) => Number(league.typeId) === Number(data.typeId));
|
|
295
308
|
const minOdds = leagueInfoByTypeId?.minOdds; // minimum odds configured for child market (e.g. 0.95 implied probability)
|
|
@@ -343,7 +356,7 @@ export const createChildMarkets: (
|
|
|
343
356
|
* @param {string} oddsProvider - The main odds provider to filter by.
|
|
344
357
|
* @returns {Array} The filtered odds array.
|
|
345
358
|
*/
|
|
346
|
-
export const
|
|
359
|
+
export const filterOdds = (oddsArray: Odds, leagueInfos: LeagueConfigInfo[], playersMap: Map<string, number>): any => {
|
|
347
360
|
const allChildMarketsTypes = leagueInfos
|
|
348
361
|
.filter(
|
|
349
362
|
(leagueInfo) =>
|
|
@@ -353,7 +366,10 @@ export const filterOddsByMarketNameBookmaker = (oddsArray: Odds, leagueInfos: Le
|
|
|
353
366
|
.map((leagueInfo) => leagueInfo.marketName.toLowerCase());
|
|
354
367
|
return oddsArray.reduce((acc: any, odd: any) => {
|
|
355
368
|
if (allChildMarketsTypes.includes(odd.marketName.toLowerCase())) {
|
|
356
|
-
const { points, marketName, selection, selectionLine, sportsBookName } = odd;
|
|
369
|
+
const { points, marketName, selection, selectionLine, sportsBookName, playerId } = odd;
|
|
370
|
+
if (playerId && !playersMap.has(playerId)) {
|
|
371
|
+
return acc;
|
|
372
|
+
}
|
|
357
373
|
const key = `${sportsBookName.toLowerCase()}_${marketName.toLowerCase()}_${points}_${selection}_${selectionLine}`;
|
|
358
374
|
acc[key] = {
|
|
359
375
|
...odd,
|
|
@@ -440,6 +456,13 @@ export const groupAndFormatTotalOdds = (oddsArray: any[], commonData: HomeAwayTe
|
|
|
440
456
|
acc[key].typeId = odd.typeId;
|
|
441
457
|
acc[key].type = odd.type;
|
|
442
458
|
acc[key].sportId = odd.sportId;
|
|
459
|
+
|
|
460
|
+
if (odd.playerId) {
|
|
461
|
+
acc[key].playerProps = {
|
|
462
|
+
playerId: odd.playerId, // Player ID from OpticOdds, this will be converted to our internal playerId later
|
|
463
|
+
playerName: odd.selection,
|
|
464
|
+
};
|
|
465
|
+
}
|
|
443
466
|
}
|
|
444
467
|
|
|
445
468
|
return acc;
|
|
@@ -447,8 +470,8 @@ export const groupAndFormatTotalOdds = (oddsArray: any[], commonData: HomeAwayTe
|
|
|
447
470
|
|
|
448
471
|
// Format the grouped odds into the desired output
|
|
449
472
|
const formattedOdds = Object.entries(groupedOdds as any).reduce((acc: any, [key, value]) => {
|
|
450
|
-
const [_marketName, selection,
|
|
451
|
-
const line = parseFloat(
|
|
473
|
+
const [_marketName, selection, points] = key.split('_');
|
|
474
|
+
const line = parseFloat(points);
|
|
452
475
|
|
|
453
476
|
// if we have away team in total odds we know the market is team total and we need to increase typeId by one.
|
|
454
477
|
// if this is false typeId is already mapped correctly
|
|
@@ -460,6 +483,7 @@ export const groupAndFormatTotalOdds = (oddsArray: any[], commonData: HomeAwayTe
|
|
|
460
483
|
typeId: !isAwayTeam ? (value as any).typeId : Number((value as any).typeId) + 1,
|
|
461
484
|
sportId: (value as any).sportId,
|
|
462
485
|
type: (value as any).type,
|
|
486
|
+
playerProps: (value as any).playerProps,
|
|
463
487
|
});
|
|
464
488
|
}
|
|
465
489
|
return acc;
|