overtime-live-trading-utils 4.0.4 → 4.0.5-rc.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "overtime-live-trading-utils",
3
- "version": "4.0.4",
3
+ "version": "4.0.5-rc.0",
4
4
  "description": "",
5
5
  "main": "main.js",
6
6
  "scripts": {
@@ -66,6 +66,15 @@ export enum MoneylineTypes {
66
66
  MONEYLINE = 'Moneyline',
67
67
  }
68
68
 
69
+ export enum ChildMarketType {
70
+ TOTAL = 'Total',
71
+ SPREAD = 'Spread',
72
+ MONEYLINE = 'Moneyline',
73
+ CORRECT_SCORE = 'Correct Score',
74
+ DOUBLE_CHANCE = 'Double Chance',
75
+ BOTH_TEAMS_TO_SCORE = 'Both Teams To Score',
76
+ }
77
+
69
78
  export enum SpreadTypes {
70
79
  ASIAN_HANDICAP = 'Asian Handicap',
71
80
  GAME_SPREAD = 'Game Spread',
@@ -1,3 +1,4 @@
1
+ import { ChildMarketType } from '../../enums/sports';
1
2
  import { LeagueConfigInfo } from '../../types/sports';
2
3
 
3
4
  const baseLeagueInfo: LeagueConfigInfo = {
@@ -5,7 +6,7 @@ const baseLeagueInfo: LeagueConfigInfo = {
5
6
  enabled: 'true',
6
7
  marketName: 'Moneyline',
7
8
  typeId: 0,
8
- type: 'moneyline',
9
+ type: ChildMarketType.MONEYLINE,
9
10
  maxOdds: 0.25,
10
11
  minOdds: 0.75,
11
12
  };
@@ -15,7 +16,7 @@ const baseLeagueInfoNba: LeagueConfigInfo = {
15
16
  enabled: 'true',
16
17
  marketName: 'Moneyline',
17
18
  typeId: 0,
18
- type: 'moneyline',
19
+ type: ChildMarketType.MONEYLINE,
19
20
  maxOdds: 0.25,
20
21
  minOdds: 0.75,
21
22
  };
@@ -25,7 +26,7 @@ const spreadMock: LeagueConfigInfo = {
25
26
  enabled: 'true',
26
27
  marketName: 'Goal Spread',
27
28
  typeId: 10001,
28
- type: 'Spread',
29
+ type: ChildMarketType.SPREAD,
29
30
  maxOdds: 0.25,
30
31
  minOdds: 0.75,
31
32
  };
@@ -35,7 +36,7 @@ const totalMock: LeagueConfigInfo = {
35
36
  enabled: 'true',
36
37
  marketName: 'Total Goals',
37
38
  typeId: 10002,
38
- type: 'Total',
39
+ type: ChildMarketType.TOTAL,
39
40
  maxOdds: 0.25,
40
41
  minOdds: 0.75,
41
42
  };
@@ -45,7 +46,7 @@ const doubleChanceMock: LeagueConfigInfo = {
45
46
  enabled: 'true',
46
47
  marketName: 'Double Chance',
47
48
  typeId: 10003,
48
- type: 'Double Chance',
49
+ type: ChildMarketType.DOUBLE_CHANCE,
49
50
  maxOdds: 0.01,
50
51
  minOdds: 0.99,
51
52
  };
@@ -55,7 +56,7 @@ const correctScoreMock: LeagueConfigInfo = {
55
56
  enabled: 'true',
56
57
  marketName: 'Correct Score',
57
58
  typeId: 10100,
58
- type: 'Correct Score',
59
+ type: ChildMarketType.CORRECT_SCORE,
59
60
  maxOdds: 0.25,
60
61
  minOdds: 0.75,
61
62
  };
@@ -65,7 +66,7 @@ const childMoneylineMock: LeagueConfigInfo = {
65
66
  enabled: 'true',
66
67
  marketName: '1st Half Moneyline',
67
68
  typeId: 10022,
68
- type: 'Moneyline',
69
+ type: ChildMarketType.MONEYLINE,
69
70
  maxOdds: 0.25,
70
71
  minOdds: 0.75,
71
72
  };
@@ -75,7 +76,7 @@ const bothTeamsToScoreMock: LeagueConfigInfo = {
75
76
  enabled: 'true',
76
77
  marketName: 'Both Teams To Score',
77
78
  typeId: 10009,
78
- type: 'Both Teams To Score',
79
+ type: ChildMarketType.BOTH_TEAMS_TO_SCORE,
79
80
  maxOdds: 0.01,
80
81
  minOdds: 0.99,
81
82
  };
@@ -85,7 +86,7 @@ const bothTeamsToScoreMock1stHalf: LeagueConfigInfo = {
85
86
  enabled: 'true',
86
87
  marketName: '1st Half Both Teams To Score',
87
88
  typeId: 10101,
88
- type: 'Both Teams To Score',
89
+ type: ChildMarketType.BOTH_TEAMS_TO_SCORE,
89
90
  maxOdds: 0.01,
90
91
  minOdds: 0.99,
91
92
  };
@@ -95,7 +96,7 @@ const bothTeamsToScoreMock2ndHalf: LeagueConfigInfo = {
95
96
  enabled: 'true',
96
97
  marketName: '2nd Half Both Teams To Score',
97
98
  typeId: 10102,
98
- type: 'Both Teams To Score',
99
+ type: ChildMarketType.BOTH_TEAMS_TO_SCORE,
99
100
  maxOdds: 0.01,
100
101
  minOdds: 0.99,
101
102
  };
@@ -105,7 +106,7 @@ const drawNoBetMock: LeagueConfigInfo = {
105
106
  enabled: 'true',
106
107
  marketName: 'Draw No Bet',
107
108
  typeId: 10010,
108
- type: 'Moneyline',
109
+ type: ChildMarketType.MONEYLINE,
109
110
  maxOdds: 0.01,
110
111
  minOdds: 0.99,
111
112
  };
@@ -115,7 +116,7 @@ const willThereBeOvertime: LeagueConfigInfo = {
115
116
  enabled: 'true',
116
117
  marketName: 'Will There Be Overtime',
117
118
  typeId: 10131,
118
- type: 'Both Teams To Score',
119
+ type: ChildMarketType.BOTH_TEAMS_TO_SCORE,
119
120
  maxOdds: 0.01,
120
121
  minOdds: 0.99,
121
122
  };
@@ -125,7 +126,7 @@ const teamTotal: LeagueConfigInfo = {
125
126
  enabled: 'true',
126
127
  marketName: 'Team Total',
127
128
  typeId: 10017,
128
- type: 'Total',
129
+ type: ChildMarketType.TOTAL,
129
130
  maxOdds: 0.25,
130
131
  minOdds: 0.75,
131
132
  primaryBookmaker: 'draftkings',
@@ -138,7 +139,7 @@ const PlayerAssist: LeagueConfigInfo[] = [
138
139
  enabled: 'true',
139
140
  marketName: 'Player Assists',
140
141
  typeId: 11039,
141
- type: 'Total',
142
+ type: ChildMarketType.TOTAL,
142
143
  maxOdds: 0.25,
143
144
  minOdds: 0.75,
144
145
  primaryBookmaker: 'superbet',
@@ -152,7 +153,7 @@ const PlayerAssistWithSecondaryBookmaker: LeagueConfigInfo[] = [
152
153
  enabled: 'true',
153
154
  marketName: 'Player Assists',
154
155
  typeId: 11039,
155
- type: 'Total',
156
+ type: ChildMarketType.TOTAL,
156
157
  maxOdds: 0.25,
157
158
  minOdds: 0.75,
158
159
  primaryBookmaker: 'superbet',
@@ -165,7 +166,7 @@ const teamTotal2: LeagueConfigInfo = {
165
166
  enabled: 'true',
166
167
  marketName: 'Team Total',
167
168
  typeId: 10018,
168
- type: 'Total',
169
+ type: ChildMarketType.TOTAL,
169
170
  maxOdds: 0.25,
170
171
  minOdds: 0.75,
171
172
  primaryBookmaker: 'draftkings',
@@ -1,14 +1,17 @@
1
+ import { ChildMarketType } from '../enums/sports';
2
+
1
3
  export type LeagueConfigInfo = {
2
4
  sportId: number;
3
5
  typeId: number;
4
6
  marketName: string;
5
- type: string;
7
+ type: ChildMarketType;
6
8
  enabled: string;
7
9
  minOdds: number;
8
10
  maxOdds: number;
9
11
  addedSpread?: number;
10
12
  primaryBookmaker?: string;
11
13
  secondaryBookmaker?: string;
14
+ percentageDiffForLines?: number;
12
15
  };
13
16
 
14
17
  export type ChildMarket = {
@@ -4,6 +4,7 @@ import {
4
4
  ZERO_ODDS_MESSAGE,
5
5
  ZERO_ODDS_MESSAGE_SINGLE_BOOKMAKER,
6
6
  } from '../constants/errors';
7
+ import { ChildMarketType } from '../enums/sports';
7
8
  import { BookmakersConfig } from '../types/bookmakers';
8
9
  import { Anchor, OddsWithLeagueInfo } from '../types/odds';
9
10
  import { LastPolledArray, LeagueConfigInfo } from '../types/sports';
@@ -157,7 +158,7 @@ export const checkOddsFromBookmakersForChildMarkets = (
157
158
  lastPolledData: LastPolledArray,
158
159
  maxAllowedProviderDataStaleDelay: number,
159
160
  anchors: Anchor[],
160
- percentageDiffForPPLines: number
161
+ maxPercentageDiffForLines: number
161
162
  ): OddsWithLeagueInfo => {
162
163
  const formattedOdds = Object.entries(odds as any).reduce((acc: any, [key, value]: [string, any]) => {
163
164
  const [sportsBookName, marketName, points, selection, selectionLine] = key.split('_');
@@ -197,9 +198,12 @@ export const checkOddsFromBookmakersForChildMarkets = (
197
198
 
198
199
  acc.push(value);
199
200
  } else {
200
- // if its player props and we didnt find the correct line, try adjusting points by steps defined and search again
201
- if (value.playerId) {
202
- const steps = getStepsForPointAdjustment(Number(points), percentageDiffForPPLines);
201
+ // if the market is Total or Spread and we didnt find the correct line, try adjusting points by steps defined and search again
202
+ if (info.type === ChildMarketType.SPREAD || info.type === ChildMarketType.TOTAL) {
203
+ const steps = getStepsForPointAdjustment(
204
+ Number(points),
205
+ info.percentageDiffForLines ?? maxPercentageDiffForLines // use the value defined in csv if available, else use default from env variable
206
+ );
203
207
  for (const step of steps) {
204
208
  const adjustedPoints = (Number(points) + step).toString();
205
209
 
@@ -317,14 +321,12 @@ const shouldBlockOdds = (ourOdds: number, otherOdds: number, anchors: Anchor[])
317
321
  };
318
322
 
319
323
  const getStepsForPointAdjustment = (points: number, percentageDiffForPPLines: number): number[] => {
320
- const stepsDelta = Math.round((points * percentageDiffForPPLines) / 100); // Example logic: 10% of the points value
324
+ const stepsDelta = Math.round((points * percentageDiffForPPLines) / 100);
321
325
  const steps: number[] = [];
322
- for (let index = 1; index <= stepsDelta; index++) {
326
+ for (let index = 0.5; index <= stepsDelta; index += 0.5) {
323
327
  steps.push(-index, index);
324
328
  }
325
-
326
329
  return steps;
327
330
  };
328
-
329
331
  // Export only when running tests
330
332
  export const __test__ = { getRequiredOtherOdds, shouldBlockOdds };
@@ -30,7 +30,7 @@ export const processMarket = (
30
30
  lastPolledData: LastPolledArray,
31
31
  maxAllowedProviderDataStaleDelay: number,
32
32
  playersMap: Map<string, number>,
33
- maxPercentageDiffForPPLines: number
33
+ maxPercentageDiffForLines: number
34
34
  ) => {
35
35
  const leagueInfo = getLeagueInfo(market.leagueId, leagueMap);
36
36
 
@@ -85,7 +85,7 @@ export const processMarket = (
85
85
  maxAllowedProviderDataStaleDelay,
86
86
  anchors,
87
87
  playersMap,
88
- maxPercentageDiffForPPLines
88
+ maxPercentageDiffForLines
89
89
  );
90
90
 
91
91
  const packedChildMarkets = childMarkets.map((childMarket: any) => {
package/src/utils/odds.ts CHANGED
@@ -2,7 +2,7 @@ import * as oddslib from 'oddslib';
2
2
  import { isOneSideExtendedPlayerPropsMarket, MarketType, MarketTypeMap } from 'overtime-utils';
3
3
  import { DRAW, ZERO } from '../constants/common';
4
4
  import { LAST_POLLED_TOO_OLD, NO_MARKETS_FOR_LEAGUE_ID } from '../constants/errors';
5
- import { MoneylineTypes } from '../enums/sports';
5
+ import { ChildMarketType, MoneylineTypes } from '../enums/sports';
6
6
  import { Anchor, HomeAwayTeams, Odds, OddsObject } from '../types/odds';
7
7
  import { ChildMarket, LastPolledArray, LeagueConfigInfo } from '../types/sports';
8
8
  import {
@@ -238,17 +238,17 @@ export const createChildMarkets: (
238
238
  maxPercentageDiffForPPLines
239
239
  );
240
240
  checkedChildOdds.forEach((odd) => {
241
- if (odd.type === 'Total') {
241
+ if (odd.type === ChildMarketType.TOTAL) {
242
242
  if (Math.abs(Number(odd.points) % 1) === 0.5) totalOdds.push(odd);
243
- } else if (odd.type === 'Spread') {
243
+ } else if (odd.type === ChildMarketType.SPREAD) {
244
244
  if (Math.abs(Number(odd.points) % 1) === 0.5) spreadOdds.push(odd);
245
- } else if (odd.type === 'Moneyline') {
245
+ } else if (odd.type === ChildMarketType.MONEYLINE) {
246
246
  moneylineOdds.push(odd);
247
- } else if (odd.type === 'Correct Score') {
247
+ } else if (odd.type === ChildMarketType.CORRECT_SCORE) {
248
248
  correctScoreOdds.push(odd);
249
- } else if (odd.type === 'Double Chance') {
249
+ } else if (odd.type === ChildMarketType.DOUBLE_CHANCE) {
250
250
  doubleChanceOdds.push(odd);
251
- } else if (odd.type === 'Both Teams To Score') {
251
+ } else if (odd.type === ChildMarketType.BOTH_TEAMS_TO_SCORE) {
252
252
  ggOdds.push(odd);
253
253
  }
254
254
  });
@@ -294,7 +294,7 @@ export const createChildMarkets: (
294
294
  const maxOdds = leagueInfoByTypeId?.maxOdds; // maximum odds configured for child market (e.g. 0.05 implied probability)
295
295
 
296
296
  if (minOdds && maxOdds) {
297
- const allowZeroOdds = ['Total'].includes(data.type);
297
+ const allowZeroOdds = [ChildMarketType.TOTAL].includes(data.type);
298
298
  const conditionToAddChildMarket = data.odds.every(
299
299
  (odd: number) => (odd < minOdds && odd > maxOdds) || (allowZeroOdds && odd === ZERO)
300
300
  );
@@ -875,7 +875,7 @@ export const groupAndFormatCorrectScoreOdds = (oddsArray: any[], commonData: Hom
875
875
  line: 0,
876
876
  positionNames: positionNames,
877
877
  odds: Object.values(oddsMap),
878
- type: odds?.[0]?.type ? odds[0].type : 'Correct Score',
878
+ type: odds?.[0]?.type ? odds[0].type : ChildMarketType.CORRECT_SCORE,
879
879
  typeId: Number(typeId),
880
880
  sportId: odds?.[0]?.sportId ? odds[0].sportId : undefined,
881
881
  };
@@ -924,7 +924,7 @@ export const groupAndFormatDoubleChanceOdds = (oddsArray: any[], commonData: Hom
924
924
  awayTeam: commonData.awayTeam,
925
925
  line: 0,
926
926
  odds: [probability1X, probability12, probabilityX2],
927
- type: 'Double Chance',
927
+ type: ChildMarketType.DOUBLE_CHANCE,
928
928
  typeId: 10003,
929
929
  sportId: sportId,
930
930
  };