overtime-utils 0.1.74-rc.0 → 0.1.74

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-utils",
3
- "version": "0.1.74-rc.0",
3
+ "version": "0.1.74",
4
4
  "description": "",
5
5
  "main": "main.js",
6
6
  "scripts": {
@@ -3836,7 +3836,6 @@ export const MarketTypeMap: Record<MarketType, MarketTypeInfo> = {
3836
3836
  name: 'Total fouls',
3837
3837
  resultType: ResultType.OVER_UNDER,
3838
3838
  },
3839
-
3840
3839
  };
3841
3840
 
3842
3841
  export const WINNER_MARKET_TYPES = [
@@ -4431,6 +4430,7 @@ export const PLAYER_PROPS_MARKET_TYPES = [
4431
4430
  MarketType.PLAYER_PROPS_MAN_OF_THE_MATCH,
4432
4431
  MarketType.PLAYER_PROPS_WICKETS_TAKEN,
4433
4432
  MarketType.PLAYER_PROPS_SIXES,
4433
+ MarketType.PLAYER_PROPS_FOURS,
4434
4434
  MarketType.PLAYER_PROPS_THREE_DART_AVERAGE,
4435
4435
  MarketType.PLAYER_PROPS_180,
4436
4436
  MarketType.PLAYER_PROPS_100_PLUS_CHECKOUTS,
package/src/utils/odds.ts DELETED
@@ -1,579 +0,0 @@
1
- const ZERO = 0;
2
- const MULTIPLIER_100 = 100;
3
- const MINIMAL_PROBABILITY_SUM = 1.02;
4
-
5
- const log = (...args: any[]) => {
6
- const isTest = process.env.NODE_ENV === 'test';
7
- if (isTest) {
8
- console.log(...args);
9
- }
10
- };
11
-
12
- /**
13
- * Checks if the sum of odds is greater than MINIMAL_PROBABILITY_SUM.
14
- * @param {Array<number>} odds - Array of odds.
15
- * @returns {{ odds: Array<number>, isValid: boolean, sumOfOdds: number }}
16
- * - odds: adjusted odds or array of zeros
17
- * - isValid: true if sum >= MINIMAL_PROBABILITY_SUM, false otherwise
18
- * - sumOfOdds: sum of all odds
19
- */
20
- function checkOddsIfGreaterThanMinimalSum(
21
- odds: number[],
22
- minimal = MINIMAL_PROBABILITY_SUM
23
- ): { odds: Array<number>; isValid: boolean; sumOfOdds: number } {
24
- const sumOfOdds = odds.reduce((sum, odd) => sum + odd, ZERO);
25
- const isValid = sumOfOdds >= minimal;
26
-
27
- if (!isValid) {
28
- log('Odds sum invalid: sum=%s, expected >= %s, odds=%o -> returning zeros.', sumOfOdds, minimal, odds);
29
- }
30
-
31
- return {
32
- odds: isValid ? odds : new Array(odds.length).fill(ZERO),
33
- isValid,
34
- sumOfOdds,
35
- };
36
- }
37
-
38
- /**
39
- * Rebalances the given odds based on provided cap and risk values for two positions.
40
- *
41
- * @param {Array<number>} currentOddsArray - The array of odds to be rebalanced.
42
- * @param {number} cap - The cap value used for adjustments.
43
- * @param {number} positionOneRisk - The risk adjustment for position one.
44
- * @param {number} positionTwoRisk - The risk adjustment for position two.
45
- * @param {number} [lowerPercentageRisk=33] - The lower percentage risk threshold.
46
- * @param {number} [middlePercentageRisk=50] - The middle percentage risk threshold.
47
- * @param {number} [higherPercentageRisk=66] - The higher percentage risk threshold.
48
- * @param {number} [lowerPercentageRiskRebalance=1] - Rebalance % when in (lower, middle].
49
- * @param {number} [middlePercentageRiskRebalance=1.5]- Rebalance % when in (middle, higher].
50
- * @param {number} [higherPercentageRiskRebalance=2] - Rebalance % when > higher.
51
- * @param {boolean} [rebalanceOnRiskSideOnly=true] - If true, only the higher-risk side is boosted and
52
- * the other side is left as-is; if false, the opposite side is reduced as well.
53
- * @returns {{ odds: number[], isRebalanced: boolean, minPercantage: number, adjustedPercantage: number }}
54
- */
55
- function rebalanceOdds(
56
- currentOddsArray: number[],
57
- cap: number,
58
- positionOneRisk: number,
59
- positionTwoRisk: number,
60
- lowerPercentageRisk: number = 33,
61
- middlePercentageRisk: number = 50,
62
- higherPercentageRisk: number = 66,
63
- lowerPercentageRiskRebalance: number = 1, // %
64
- middlePercentageRiskRebalance: number = 1.5, // %
65
- higherPercentageRiskRebalance: number = 2, // %
66
- rebalanceOnRiskSideOnly: boolean = true
67
- ): { odds: number[]; isRebalanced: boolean; minPercantage: number; adjustedPercantage: number } {
68
- // Validate input
69
- if (!Array.isArray(currentOddsArray) || currentOddsArray.length !== 2) {
70
- log('Invalid odds array. Returning [0, 0].');
71
- return {
72
- odds: [ZERO, ZERO],
73
- isRebalanced: false,
74
- minPercantage: 0,
75
- adjustedPercantage: 0,
76
- };
77
- }
78
-
79
- if (cap <= ZERO) {
80
- log('Invalid cap value. Returning current odds.');
81
- return {
82
- odds: currentOddsArray,
83
- isRebalanced: false,
84
- minPercantage: 0,
85
- adjustedPercantage: 0,
86
- };
87
- }
88
-
89
- const [odds1, odds2] = currentOddsArray;
90
-
91
- // Check if odds are within valid range
92
- if (odds1 <= ZERO || odds1 >= 1 || odds2 <= ZERO || odds2 >= 1 || odds1 + odds2 <= 1) {
93
- log('Invalid odds: either individual odds are out of range or their sum is less than 1. Returning [0, 0].');
94
- return {
95
- odds: [ZERO, ZERO],
96
- isRebalanced: false,
97
- minPercantage: 0,
98
- adjustedPercantage: 0,
99
- };
100
- }
101
-
102
- // Find the maximum risk and its associated position
103
- const maxRisk = Math.max(positionOneRisk, positionTwoRisk);
104
- const riskPercentage = (Math.abs(maxRisk) / cap) * MULTIPLIER_100;
105
-
106
- log('Max Risk: %s, Risk Percentage: %s%%', maxRisk, riskPercentage);
107
-
108
- // Determine the adjustment factor
109
- let adjustment = ZERO;
110
- if (riskPercentage > lowerPercentageRisk && riskPercentage <= middlePercentageRisk) {
111
- adjustment = lowerPercentageRiskRebalance / MULTIPLIER_100;
112
- } else if (riskPercentage > middlePercentageRisk && riskPercentage <= higherPercentageRisk) {
113
- adjustment = middlePercentageRiskRebalance / MULTIPLIER_100;
114
- } else if (riskPercentage > higherPercentageRisk) {
115
- adjustment = higherPercentageRiskRebalance / MULTIPLIER_100;
116
- }
117
-
118
- // If no adjustment is needed, return the current odds
119
- if (adjustment === ZERO) {
120
- log('Risk percentage is within acceptable limits. No rebalancing needed. Current odds: %o', currentOddsArray);
121
- return {
122
- odds: currentOddsArray,
123
- isRebalanced: false,
124
- minPercantage: 0,
125
- adjustedPercantage: 0,
126
- };
127
- }
128
-
129
- // Log original odds before rebalancing
130
- log('Original Odds: [%s, %s]', odds1, odds2);
131
-
132
- // Adjust the odds by multiplying with (1 ± adjustment)
133
- let newOdds1, newOdds2;
134
-
135
- if (maxRisk === positionOneRisk) {
136
- newOdds1 = odds1 * (1 + adjustment); // Increase odds1
137
- // do not change or decrease odds2 depending on a rebalanceOnRiskSideOnly flag
138
- newOdds2 = rebalanceOnRiskSideOnly ? odds2 : odds2 * (1 - adjustment);
139
- } else {
140
- // do not change or decrease odds1 depending on a rebalanceOnRiskSideOnly flag
141
- newOdds1 = rebalanceOnRiskSideOnly ? odds1 : odds1 * (1 - adjustment);
142
- newOdds2 = odds2 * (1 + adjustment); // Increase odds2
143
- }
144
-
145
- log('Rebalanced Odds: [%s, %s]', newOdds1, newOdds2);
146
-
147
- // Check if rebalanced odds are valid
148
- const { odds: sumCheckedOdds, isValid, sumOfOdds } = checkOddsIfGreaterThanMinimalSum([newOdds1, newOdds2]);
149
-
150
- // Check if rebalanced odds are valid
151
- if (newOdds1 <= ZERO || newOdds2 <= ZERO || newOdds1 >= 1 || newOdds2 >= 1 || !isValid) {
152
- log(
153
- 'Rebalanced odds invalid: sum=%s, expected >= %s, odds=[%s, %s] -> returning [0, 0].',
154
- sumOfOdds,
155
- MINIMAL_PROBABILITY_SUM,
156
- newOdds1,
157
- newOdds2
158
- );
159
- return {
160
- odds: [ZERO, ZERO],
161
- isRebalanced: false,
162
- minPercantage: 0,
163
- adjustedPercantage: 0,
164
- };
165
- }
166
-
167
- // Return valid rebalanced odds
168
- return {
169
- odds: sumCheckedOdds,
170
- isRebalanced: true,
171
- minPercantage: lowerPercentageRisk,
172
- adjustedPercantage: riskPercentage,
173
- };
174
- }
175
-
176
- /**
177
- * Rebalances multi-way (≥3) implied odds by shifting probability toward the
178
- * highest-risk position and reducing the rest (implicitly via sum check).
179
- *
180
- * @param {number[]} currentOddsArray - Implied probabilities per position (each in (0,1)), N ≥ 3.
181
- * @param {number} cap - Absolute cap used to normalize risk to percentage (must be > 0).
182
- * @param {number[]} positionRisks - Risks per position; only first N used; missing padded with 0.
183
- * @param {number} [lowerPercentageRisk=33] - Lower risk % threshold.
184
- * @param {number} [middlePercentageRisk=50] - Middle risk % threshold.
185
- * @param {number} [higherPercentageRisk=66] - Higher risk % threshold.
186
- * @param {number} [lowerPercentageRiskRebalance=1] - % increase when in (lower, middle].
187
- * @param {number} [middlePercentageRiskRebalance=1.5]- % increase when in (middle, higher].
188
- * @param {number} [higherPercentageRiskRebalance=2] - % increase when > higher.
189
- * @param {boolean} [rebalanceOnRiskSideOnly=true] - If true, only the highest-risk side is boosted and
190
- * all other positions stay unchanged. If false, other positions are slightly reduced so that
191
- * the overall probability mass is approximately conserved.
192
- * @returns {{ odds: number[], isRebalanced: boolean, minPercantage: number, adjustedPercantage: number }} Rebalanced odds and flag.
193
- */
194
- function rebalanceMultiOdds(
195
- currentOddsArray: number[],
196
- cap: number,
197
- positionRisks: number[],
198
- lowerPercentageRisk: number = 33,
199
- middlePercentageRisk: number = 50,
200
- higherPercentageRisk: number = 66,
201
- lowerPercentageRiskRebalance: number = 1, // %
202
- middlePercentageRiskRebalance: number = 1.5, // %
203
- higherPercentageRiskRebalance: number = 2, // %
204
- rebalanceOnRiskSideOnly: boolean = true
205
- ): { odds: number[]; isRebalanced: boolean; minPercantage: number; adjustedPercantage: number } {
206
- // Basic validation
207
- if (!Array.isArray(currentOddsArray)) {
208
- log('Invalid odds array (not an array). Returning zeros.');
209
- return {
210
- odds: new Array(3).fill(ZERO), // same behavior as before when not an array
211
- isRebalanced: false,
212
- minPercantage: 0,
213
- adjustedPercantage: 0,
214
- };
215
- }
216
-
217
- if (currentOddsArray.length < 3) {
218
- log('Multi-way rebalancing needs >= 3 positions. Returning current odds.');
219
- return {
220
- odds: currentOddsArray,
221
- isRebalanced: false,
222
- minPercantage: 0,
223
- adjustedPercantage: 0,
224
- };
225
- }
226
-
227
- if (cap <= ZERO) {
228
- log('Invalid cap value. Returning current odds.');
229
- return {
230
- odds: currentOddsArray,
231
- isRebalanced: false,
232
- minPercantage: 0,
233
- adjustedPercantage: 0,
234
- };
235
- }
236
-
237
- const N = currentOddsArray.length;
238
-
239
- const sum = currentOddsArray.reduce((s, o) => s + o, ZERO);
240
- if (currentOddsArray.some((o) => o < ZERO || o >= 1) || sum <= 1) {
241
- log('Invalid odds for multi-way. Returning zeros.');
242
- return {
243
- odds: new Array(N).fill(ZERO),
244
- isRebalanced: false,
245
- minPercantage: 0,
246
- adjustedPercantage: 0,
247
- };
248
- }
249
-
250
- // Use risks for the first N positions (pad with 0)
251
- const risks = Array.from({ length: N }, (_, i) => Number(positionRisks?.[i] ?? ZERO));
252
-
253
- // Find index of max risk (consistent with 2-way: Math.max, then abs() for %)
254
- let maxIdx = 0;
255
- for (let i = 1; i < N; i++) if (risks[i] > risks[maxIdx]) maxIdx = i;
256
- const maxRisk = risks[maxIdx];
257
- const riskPercentage = (Math.abs(maxRisk) / cap) * MULTIPLIER_100;
258
-
259
- let adjustment = ZERO;
260
- if (riskPercentage > lowerPercentageRisk && riskPercentage <= middlePercentageRisk) {
261
- adjustment = lowerPercentageRiskRebalance / MULTIPLIER_100;
262
- } else if (riskPercentage > middlePercentageRisk && riskPercentage <= higherPercentageRisk) {
263
- adjustment = middlePercentageRiskRebalance / MULTIPLIER_100;
264
- } else if (riskPercentage > higherPercentageRisk) {
265
- adjustment = higherPercentageRiskRebalance / MULTIPLIER_100;
266
- }
267
-
268
- if (adjustment === ZERO) {
269
- log('Risk %% within limits (multi-way). No rebalancing. Current odds: %o', currentOddsArray);
270
- return {
271
- odds: currentOddsArray,
272
- isRebalanced: false,
273
- minPercantage: 0,
274
- adjustedPercantage: 0,
275
- };
276
- }
277
-
278
- const downFactor = adjustment / (N - 1); // e.g., +2% on one => -1% on each of two
279
- const newOdds = currentOddsArray.map((o, i) => {
280
- if (i === maxIdx) return o * (1 + adjustment);
281
- if (rebalanceOnRiskSideOnly) return o;
282
- return o * (1 - downFactor);
283
- });
284
-
285
- // Validate new odds using the helper
286
- const { odds: sumCheckedOdds, isValid, sumOfOdds } = checkOddsIfGreaterThanMinimalSum(newOdds);
287
-
288
- // fail only on negatives or failed sum check
289
- if (newOdds.some((o) => o < ZERO) || !isValid) {
290
- log(
291
- 'Rebalanced multi-way odds invalid: sum=%s, expected >= %s, odds=%o -> returning zeros.',
292
- sumOfOdds,
293
- MINIMAL_PROBABILITY_SUM,
294
- newOdds
295
- );
296
- return {
297
- odds: new Array(N).fill(ZERO),
298
- isRebalanced: false,
299
- minPercantage: 0,
300
- adjustedPercantage: 0,
301
- };
302
- }
303
-
304
- // valid → clamp any >= 1 to 0 (don’t revalidate)
305
- const overOneIdx: number[] = [];
306
- const finalOdds = sumCheckedOdds.map((o, i) => {
307
- if (o >= 1) {
308
- overOneIdx.push(i);
309
- return ZERO;
310
- }
311
- return o;
312
- });
313
- if (overOneIdx.length) {
314
- log('Odds >= 1 found at indexes %o; set to 0.', overOneIdx);
315
- }
316
-
317
- return {
318
- odds: finalOdds,
319
- isRebalanced: true,
320
- minPercantage: lowerPercentageRisk,
321
- adjustedPercantage: riskPercentage,
322
- };
323
- }
324
-
325
- /**
326
- * Adjusts a single odds value based on risk exposure and predefined rebalancing thresholds.
327
- *
328
- * @param {number[]} currentOdds - An array containing a single odds value to be rebalanced.
329
- * @param {number} cap - The maximum risk exposure allowed.
330
- * @param {number} risk - The risk associated with the odds position.
331
- * @param {number} [lowerPercentageRisk=33] - Lower threshold.
332
- * @param {number} [middlePercentageRisk=50] - Middle threshold.
333
- * @param {number} [higherPercentageRisk=66] - Higher threshold.
334
- * @param {number} [lowerPercentageRiskRebalance=1] - % when in (lower, middle].
335
- * @param {number} [middlePercentageRiskRebalance=1.5]- % when in (middle, higher].
336
- * @param {number} [higherPercentageRiskRebalance=2] - % when > higher.
337
- * @returns {{ odds: number[], isRebalanced: boolean, minPercantage: number, adjustedPercantage: number }}
338
- */
339
- function rebalanceSingleOdd(
340
- currentOdds: number[],
341
- cap: number,
342
- risk: number,
343
- lowerPercentageRisk: number = 33,
344
- middlePercentageRisk: number = 50,
345
- higherPercentageRisk: number = 66,
346
- lowerPercentageRiskRebalance: number = 1, // %
347
- middlePercentageRiskRebalance: number = 1.5, // %
348
- higherPercentageRiskRebalance: number = 2 // %
349
- ): { odds: number[]; isRebalanced: boolean; minPercantage: number; adjustedPercantage: number } {
350
- // Validate input
351
- if (!Array.isArray(currentOdds) || currentOdds.length !== 1) {
352
- log('Invalid odds input. Expected an array with one element. Returning [ZERO].');
353
- return {
354
- odds: [ZERO],
355
- isRebalanced: false,
356
- minPercantage: 0,
357
- adjustedPercantage: 0,
358
- };
359
- }
360
-
361
- const [odd] = currentOdds;
362
-
363
- if (odd <= ZERO || odd >= 1) {
364
- log('Invalid odd value. Returning [ZERO].');
365
- return {
366
- odds: [ZERO],
367
- isRebalanced: false,
368
- minPercantage: 0,
369
- adjustedPercantage: 0,
370
- };
371
- }
372
-
373
- if (cap <= ZERO) {
374
- log('Invalid cap value. Returning current odds.');
375
- return {
376
- odds: currentOdds,
377
- isRebalanced: false,
378
- minPercantage: 0,
379
- adjustedPercantage: 0,
380
- };
381
- }
382
-
383
- // Calculate risk percentage
384
- const riskPercentage = (Math.abs(risk) / cap) * MULTIPLIER_100;
385
-
386
- log('Risk: %s, Risk Percentage: %s%%', risk, riskPercentage);
387
-
388
- // Determine the adjustment factor
389
- let adjustment = ZERO;
390
- if (riskPercentage > lowerPercentageRisk && riskPercentage <= middlePercentageRisk) {
391
- adjustment = lowerPercentageRiskRebalance / MULTIPLIER_100;
392
- } else if (riskPercentage > middlePercentageRisk && riskPercentage <= higherPercentageRisk) {
393
- adjustment = middlePercentageRiskRebalance / MULTIPLIER_100;
394
- } else if (riskPercentage > higherPercentageRisk) {
395
- adjustment = higherPercentageRiskRebalance / MULTIPLIER_100;
396
- }
397
-
398
- // If no adjustment is needed, return the current odds
399
- if (adjustment === ZERO) {
400
- log('No rebalancing needed. Current odds: %o', currentOdds);
401
- return {
402
- odds: currentOdds,
403
- isRebalanced: false,
404
- minPercantage: 0,
405
- adjustedPercantage: 0,
406
- };
407
- }
408
-
409
- // Log original odds before rebalancing
410
- log('Original Odds: %s', odd);
411
-
412
- // Adjust the odd based on risk direction (only positive adjustment)
413
- let newOdd = odd;
414
- let isRebalanced = false;
415
- if (risk >= ZERO) {
416
- newOdd = odd * (1 + adjustment);
417
- isRebalanced = true;
418
- }
419
-
420
- log('Rebalanced Odd: %s', newOdd);
421
-
422
- // Validate rebalanced odd
423
- if (newOdd <= ZERO || newOdd >= 1) {
424
- log('Rebalanced odd is invalid (out of range). Returning [ZERO].');
425
- return {
426
- odds: [ZERO],
427
- isRebalanced: false,
428
- minPercantage: 0,
429
- adjustedPercantage: 0,
430
- };
431
- }
432
-
433
- return {
434
- odds: [newOdd],
435
- isRebalanced,
436
- minPercantage: lowerPercentageRisk,
437
- adjustedPercantage: riskPercentage,
438
- };
439
- }
440
-
441
- /**
442
- * Rebalances odds based on risk data for a specific type ID.
443
- *
444
- * @param {Array<number>} currentOddsArray - The array of odds to be rebalanced.
445
- * @param {number} typeId - The type ID used to filter risk data.
446
- * @param {Object} riskData - The risk data object containing risk information.
447
- * @param {number|null} [playerId=null] - Optional player ID for player-specific risk filtering.
448
- * @returns {{ odds: number[], isRebalanced: boolean, minPercantage: number, adjustedPercantage: number }} - The rebalanced odds array and a flag indicating whether rebalancing was applied.
449
- */
450
- export function rebalanceOddsBasedOnRisk(
451
- currentOddsArray: number[],
452
- typeId: number,
453
- riskData: { fileExists: boolean; riskObject: any[] },
454
- playerId: number | null = null
455
- ): { odds: number[]; isRebalanced: boolean; minPercantage: number; adjustedPercantage: number } {
456
- // Step 1: Check if riskData is missing or invalid
457
- if (!riskData || !riskData.fileExists || !Array.isArray(riskData.riskObject)) {
458
- log('Invalid or missing risk data. Return odds as it is.');
459
- return {
460
- odds: currentOddsArray,
461
- isRebalanced: false,
462
- minPercantage: 0,
463
- adjustedPercantage: 0,
464
- };
465
- }
466
-
467
- // Step 2: Find risk configuration for the given typeId (and playerId if provided)
468
- const filteredRisk = riskData.riskObject.find(
469
- (entry) => entry.typeId === typeId && (playerId === null || entry.playerId === Number(playerId))
470
- );
471
-
472
- if (!filteredRisk) {
473
- log(
474
- 'No risk entry found for typeId: %s%s. Returning original odds array: %o',
475
- typeId,
476
- playerId !== null && playerId !== undefined ? ` and playerId: ${playerId}` : '',
477
- currentOddsArray
478
- );
479
- return {
480
- odds: currentOddsArray,
481
- isRebalanced: false,
482
- minPercantage: 0,
483
- adjustedPercantage: 0,
484
- };
485
- }
486
-
487
- // Step 3: Validate the odds array
488
- if (!Array.isArray(currentOddsArray)) {
489
- log('Invalid odds array. Returning all zeros.');
490
- return {
491
- odds: new Array(filteredRisk.numberOfPositions).fill(ZERO),
492
- isRebalanced: false,
493
- minPercantage: 0,
494
- adjustedPercantage: 0,
495
- };
496
- }
497
-
498
- const oddsLength = currentOddsArray.length;
499
-
500
- // Step 4: Check the total implied probability
501
- const { odds: adjustedOdds, isValid, sumOfOdds } = checkOddsIfGreaterThanMinimalSum(currentOddsArray);
502
-
503
- if (!isValid && adjustedOdds.length > 1) {
504
- log(
505
- 'Total implied probabilities too low: sum=%s, expected >= %s. Odds=%o -> returning zeros.',
506
- sumOfOdds,
507
- MINIMAL_PROBABILITY_SUM,
508
- currentOddsArray
509
- );
510
- return {
511
- odds: new Array(oddsLength).fill(ZERO),
512
- isRebalanced: false,
513
- minPercantage: 0,
514
- adjustedPercantage: 0,
515
- };
516
- }
517
-
518
- // Step 4: Extract risk values
519
- const {
520
- cap,
521
- positionRisk = [],
522
- lowerPercentageRisk,
523
- middlePercentageRisk,
524
- higherPercentageRisk,
525
- lowerPercentageRiskRebalance,
526
- middlePercentageRiskRebalance,
527
- higherPercentageRiskRebalance,
528
- rebalanceOnRiskSideOnly,
529
- } = filteredRisk;
530
-
531
- // Step 5: Handle one-positional, two-positional, or multi-positional odds
532
- if (oddsLength === 2) {
533
- log('Rebalancing two-positional odds for typeId: %s', typeId);
534
- return rebalanceOdds(
535
- currentOddsArray,
536
- cap,
537
- Number(positionRisk[0] ?? ZERO),
538
- Number(positionRisk[1] ?? ZERO),
539
- lowerPercentageRisk,
540
- middlePercentageRisk,
541
- higherPercentageRisk,
542
- lowerPercentageRiskRebalance,
543
- middlePercentageRiskRebalance,
544
- higherPercentageRiskRebalance,
545
- rebalanceOnRiskSideOnly
546
- );
547
- } else if (oddsLength === 1) {
548
- log('Rebalancing single odd for typeId: %s', typeId);
549
- return rebalanceSingleOdd(
550
- currentOddsArray,
551
- cap,
552
- Number(positionRisk[0] ?? ZERO),
553
- lowerPercentageRisk,
554
- middlePercentageRisk,
555
- higherPercentageRisk,
556
- lowerPercentageRiskRebalance,
557
- middlePercentageRiskRebalance,
558
- higherPercentageRiskRebalance
559
- );
560
- }
561
-
562
- // Step 7: Handle N-positional odds
563
- log('Rebalancing %d-positional odds for typeId: %s', oddsLength, typeId);
564
-
565
- const positionRisks = Array.from({ length: oddsLength }, (_, i) => Number(positionRisk[i] ?? ZERO));
566
-
567
- return rebalanceMultiOdds(
568
- currentOddsArray,
569
- cap,
570
- positionRisks,
571
- lowerPercentageRisk,
572
- middlePercentageRisk,
573
- higherPercentageRisk,
574
- lowerPercentageRiskRebalance,
575
- middlePercentageRiskRebalance,
576
- higherPercentageRiskRebalance,
577
- rebalanceOnRiskSideOnly
578
- );
579
- }