overtime-live-trading-utils 3.0.2-rc.2 → 3.0.3

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.
@@ -1,6 +1,6 @@
1
1
  import * as oddslib from 'oddslib';
2
2
  import { ZERO_ODDS_AFTER_SPREAD_ADJUSTMENT } from '../constants/errors';
3
- import { Anchor, OddsObject } from '../types/odds';
3
+ import { OddsObject } from '../types/odds';
4
4
  import { LastPolledArray } from '../types/sports';
5
5
  import { createChildMarkets, getParentOdds } from './odds';
6
6
  import { getLeagueInfo } from './sports';
@@ -16,10 +16,8 @@ import { adjustAddedSpread } from './spread';
16
16
  * @param {Array} spreadData - Spread data for odds.
17
17
  * @param {Boolean} isDrawAvailable - Is it two or three-positional sport
18
18
  * @param {Number} defaultSpreadForLiveMarkets - Default spread for live markets
19
- * @param {Object} leagueMap - League map for additional league information
20
- * @param {LastPolledArray} lastPolledData - Array containing last polled timestamps for bookmakers
21
- * @param {Number} maxAllowedProviderDataStaleDelay - Maximum allowed delay for provider data to be considered fresh
22
- * @param {Map<string, number>} playersMap - Map of player OO IDs to our internal player ID
19
+ * @param {Number} maxPercentageDiffBetwenOdds - Maximum allowed percentage difference between same position odds from different providers
20
+ * @param {Boolean} isTestnet - Flag showing should we process for testnet or mainnet
23
21
  * @returns {Promise<Object|null>} A promise that resolves to the processed event object or null if the event is invalid or mapping fails.
24
22
  */
25
23
  export const processMarket = (
@@ -29,11 +27,10 @@ export const processMarket = (
29
27
  spreadData: any,
30
28
  isDrawAvailable: any,
31
29
  defaultSpreadForLiveMarkets: any,
32
- anchors: Anchor[],
30
+ maxPercentageDiffBetwenOdds: number,
33
31
  leagueMap: any,
34
32
  lastPolledData: LastPolledArray,
35
- maxAllowedProviderDataStaleDelay: number,
36
- playersMap: Map<string, number>
33
+ maxAllowedProviderDataStaleDelay: number
37
34
  ) => {
38
35
  const sportSpreadData = spreadData.filter((data: any) => data.sportId === String(market.leagueId));
39
36
  const leagueInfo = getLeagueInfo(market.leagueId, leagueMap);
@@ -45,7 +42,7 @@ export const processMarket = (
45
42
  apiResponseWithOdds,
46
43
  market.leagueId,
47
44
  defaultSpreadForLiveMarkets,
48
- anchors,
45
+ maxPercentageDiffBetwenOdds,
49
46
  leagueInfo,
50
47
  lastPolledData,
51
48
  maxAllowedProviderDataStaleDelay
@@ -92,8 +89,7 @@ export const processMarket = (
92
89
  leagueMap,
93
90
  lastPolledData,
94
91
  maxAllowedProviderDataStaleDelay,
95
- anchors,
96
- playersMap
92
+ maxPercentageDiffBetwenOdds
97
93
  );
98
94
 
99
95
  const packedChildMarkets = childMarkets.map((childMarket: any) => {
package/src/utils/odds.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as oddslib from 'oddslib';
2
2
  import { MarketType, MarketTypeMap } from 'overtime-utils';
3
- import { DRAW, MONEYLINE_TYPE_ID, ZERO } from '../constants/common';
3
+ import { DRAW, MIN_ODDS_FOR_DIFF_CHECKING, MONEYLINE_TYPE_ID, ZERO } from '../constants/common';
4
4
  import { LAST_POLLED_TOO_OLD, NO_MARKETS_FOR_LEAGUE_ID } from '../constants/errors';
5
5
  import { MoneylineTypes } from '../enums/sports';
6
- import { Anchor, HomeAwayTeams, Odds, OddsObject } from '../types/odds';
6
+ import { HomeAwayTeams, Odds, OddsObject } from '../types/odds';
7
7
  import { ChildMarket, LastPolledArray, LeagueConfigInfo } from '../types/sports';
8
8
  import {
9
9
  checkOddsFromBookmakers,
@@ -128,7 +128,7 @@ export const getParentOdds = (
128
128
  oddsApiObject: OddsObject,
129
129
  sportId: string,
130
130
  defaultSpreadForLiveMarkets: number,
131
- anchors: Anchor[],
131
+ maxPercentageDiffBetwenOdds: number,
132
132
  leagueInfo: LeagueConfigInfo[],
133
133
  lastPolledData: LastPolledArray,
134
134
  maxAllowedProviderDataStaleDelay: number
@@ -164,7 +164,13 @@ export const getParentOdds = (
164
164
  );
165
165
 
166
166
  // CHECKING AND COMPARING ODDS FOR THE GIVEN BOOKMAKERS
167
- const oddsObject = checkOddsFromBookmakers(moneylineOddsMap, bookmakers, isTwoPositionalSport, anchors);
167
+ const oddsObject = checkOddsFromBookmakers(
168
+ moneylineOddsMap,
169
+ bookmakers,
170
+ isTwoPositionalSport,
171
+ maxPercentageDiffBetwenOdds,
172
+ MIN_ODDS_FOR_DIFF_CHECKING
173
+ );
168
174
 
169
175
  if (oddsObject.errorMessage) {
170
176
  return {
@@ -208,8 +214,7 @@ export const createChildMarkets: (
208
214
  leagueMap: any,
209
215
  lastPolledData: LastPolledArray,
210
216
  maxAllowedProviderDataStaleDelay: number,
211
- anchors: Anchor[],
212
- playersMap: Map<string, number>
217
+ maxImpliedPercentageDifference: number
213
218
  ) => ChildMarket[] = (
214
219
  apiResponseWithOdds,
215
220
  spreadDataForSport,
@@ -219,8 +224,7 @@ export const createChildMarkets: (
219
224
  leagueMap,
220
225
  lastPolledData,
221
226
  maxAllowedProviderDataStaleDelay,
222
- anchors,
223
- playersMap
227
+ maxImpliedPercentageDifference
224
228
  ) => {
225
229
  const [spreadOdds, totalOdds, moneylineOdds, correctScoreOdds, doubleChanceOdds, ggOdds, childMarkets]: any[] = [
226
230
  [],
@@ -238,14 +242,14 @@ export const createChildMarkets: (
238
242
  };
239
243
 
240
244
  if (leagueInfo.length > 0) {
241
- const allChildOdds = filterOdds(apiResponseWithOdds.odds, leagueInfo, playersMap);
245
+ const allChildOdds = filterOddsByMarketNameBookmaker(apiResponseWithOdds.odds, leagueInfo);
242
246
  const checkedChildOdds = checkOddsFromBookmakersForChildMarkets(
243
247
  allChildOdds,
244
248
  leagueInfo,
245
249
  liveOddsProviders,
246
250
  lastPolledData,
247
251
  maxAllowedProviderDataStaleDelay,
248
- anchors
252
+ maxImpliedPercentageDifference
249
253
  );
250
254
  checkedChildOdds.forEach((odd) => {
251
255
  if (odd.type === 'Total') {
@@ -265,7 +269,7 @@ export const createChildMarkets: (
265
269
 
266
270
  const homeAwayFormattedOdds = [
267
271
  ...groupAndFormatSpreadOdds(spreadOdds, commonData),
268
- ...groupAndFormatTotalOdds(totalOdds, commonData), // playerProps are handled inside this function
272
+ ...groupAndFormatTotalOdds(totalOdds, commonData),
269
273
  ...groupAndFormatMoneylineOdds(moneylineOdds, commonData),
270
274
  ...groupAndFormatGGOdds(ggOdds),
271
275
  ...groupAndFormatDoubleChanceOdds(doubleChanceOdds, commonData),
@@ -280,29 +284,13 @@ export const createChildMarkets: (
280
284
  );
281
285
 
282
286
  homeAwayOddsWithSpreadAdjusted.forEach((data) => {
283
- let childMarket = {
287
+ const childMarket = {
284
288
  leagueId: Number(data.sportId),
285
289
  typeId: Number(data.typeId),
286
290
  type: MarketTypeMap[data.typeId as MarketType]?.key || '',
287
291
  line: Number(data.line || 0),
288
292
  odds: data.odds,
289
- playerProps: {
290
- playerId: 0,
291
- playerName: '',
292
- },
293
- isPlayerPropsMarket: false,
294
293
  };
295
- if (data.playerProps) {
296
- childMarket = {
297
- ...childMarket,
298
- playerProps: {
299
- playerId: playersMap.get(data.playerProps.playerId.toString()) || 0, // convert from opticOdds playerId to our internal playerId
300
- playerName: data.playerProps.playerName,
301
- },
302
- isPlayerPropsMarket: true,
303
- };
304
- }
305
-
306
294
  const leagueInfoByTypeId = leagueInfo.find((league) => Number(league.typeId) === Number(data.typeId));
307
295
  const minOdds = leagueInfoByTypeId?.minOdds; // minimum odds configured for child market (e.g. 0.95 implied probability)
308
296
  const maxOdds = leagueInfoByTypeId?.maxOdds; // maximum odds configured for child market (e.g. 0.05 implied probability)
@@ -355,7 +343,7 @@ export const createChildMarkets: (
355
343
  * @param {string} oddsProvider - The main odds provider to filter by.
356
344
  * @returns {Array} The filtered odds array.
357
345
  */
358
- export const filterOdds = (oddsArray: Odds, leagueInfos: LeagueConfigInfo[], playersMap: Map<string, number>): any => {
346
+ export const filterOddsByMarketNameBookmaker = (oddsArray: Odds, leagueInfos: LeagueConfigInfo[]): any => {
359
347
  const allChildMarketsTypes = leagueInfos
360
348
  .filter(
361
349
  (leagueInfo) =>
@@ -365,10 +353,7 @@ export const filterOdds = (oddsArray: Odds, leagueInfos: LeagueConfigInfo[], pla
365
353
  .map((leagueInfo) => leagueInfo.marketName.toLowerCase());
366
354
  return oddsArray.reduce((acc: any, odd: any) => {
367
355
  if (allChildMarketsTypes.includes(odd.marketName.toLowerCase())) {
368
- const { points, marketName, selection, selectionLine, sportsBookName, playerId } = odd;
369
- if (playerId && !playersMap.has(playerId)) {
370
- return acc;
371
- }
356
+ const { points, marketName, selection, selectionLine, sportsBookName } = odd;
372
357
  const key = `${sportsBookName.toLowerCase()}_${marketName.toLowerCase()}_${points}_${selection}_${selectionLine}`;
373
358
  acc[key] = {
374
359
  ...odd,
@@ -455,13 +440,6 @@ export const groupAndFormatTotalOdds = (oddsArray: any[], commonData: HomeAwayTe
455
440
  acc[key].typeId = odd.typeId;
456
441
  acc[key].type = odd.type;
457
442
  acc[key].sportId = odd.sportId;
458
-
459
- if (odd.playerId) {
460
- acc[key].playerProps = {
461
- playerId: odd.playerId, // Player ID from OpticOdds, this will be converted to our internal playerId later
462
- playerName: odd.selection,
463
- };
464
- }
465
443
  }
466
444
 
467
445
  return acc;
@@ -469,8 +447,8 @@ export const groupAndFormatTotalOdds = (oddsArray: any[], commonData: HomeAwayTe
469
447
 
470
448
  // Format the grouped odds into the desired output
471
449
  const formattedOdds = Object.entries(groupedOdds as any).reduce((acc: any, [key, value]) => {
472
- const [_marketName, selection, points] = key.split('_');
473
- const line = parseFloat(points);
450
+ const [_marketName, selection, selectionLine] = key.split('_');
451
+ const line = parseFloat(selectionLine);
474
452
 
475
453
  // if we have away team in total odds we know the market is team total and we need to increase typeId by one.
476
454
  // if this is false typeId is already mapped correctly
@@ -482,7 +460,6 @@ export const groupAndFormatTotalOdds = (oddsArray: any[], commonData: HomeAwayTe
482
460
  typeId: !isAwayTeam ? (value as any).typeId : Number((value as any).typeId) + 1,
483
461
  sportId: (value as any).sportId,
484
462
  type: (value as any).type,
485
- playerProps: (value as any).playerProps,
486
463
  });
487
464
  }
488
465
  return acc;
@@ -1,19 +0,0 @@
1
- // For each ourOdds, this is the minimum otherOdds we require to NOT block
2
- // USED FOR TESTS ONLY, real anchors are passed from risk repo
3
- export const ODDS_THRESHOLD_ANCHORS = [
4
- { our: 1.05, otherMin: 1.03 },
5
- { our: 1.1, otherMin: 1.06 },
6
- { our: 1.2, otherMin: 1.15 },
7
- { our: 1.3, otherMin: 1.25 },
8
- { our: 1.4, otherMin: 1.33 },
9
- { our: 1.5, otherMin: 1.4 },
10
-
11
- { our: 2.0, otherMin: 1.85 },
12
- { our: 2.5, otherMin: 2.25 },
13
- { our: 3.0, otherMin: 2.5 },
14
- { our: 4.0, otherMin: 3.5 },
15
-
16
- { our: 8.0, otherMin: 6.5 },
17
- { our: 10.0, otherMin: 8.0 },
18
- { our: 100.0, otherMin: 70.0 },
19
- ];