@gotza02/sequential-thinking 10000.0.8 → 10000.1.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.
@@ -0,0 +1,461 @@
1
+ /**
2
+ * HISTORICAL ANALYZER
3
+ * Analyzes historical data for patterns and trends
4
+ */
5
+ /**
6
+ * Historical Analyzer
7
+ * Analyzes past matches for patterns and predictive insights
8
+ */
9
+ export class HistoricalAnalyzer {
10
+ matchHistory = [];
11
+ patterns = new Map();
12
+ constructor() {
13
+ this.loadHistoricalData();
14
+ }
15
+ /**
16
+ * Analyze team performance over time
17
+ */
18
+ analyzeTeamPerformance(teamId, query) {
19
+ const matches = this.getTeamMatches(teamId, query);
20
+ if (matches.length === 0) {
21
+ return this.createEmptyPerformance(teamId);
22
+ }
23
+ const wins = matches.filter(m => this.isWin(m, teamId)).length;
24
+ const draws = matches.filter(m => this.isDraw(m)).length;
25
+ const losses = matches.filter(m => this.isLoss(m, teamId)).length;
26
+ const totalGoalsFor = matches.reduce((sum, m) => sum + this.getGoalsFor(m, teamId), 0);
27
+ const totalGoalsAgainst = matches.reduce((sum, m) => sum + this.getGoalsAgainst(m, teamId), 0);
28
+ const patterns = this.findPatterns(teamId, matches);
29
+ return {
30
+ team: matches[0].homeTeam.id === teamId ? matches[0].homeTeam : matches[0].awayTeam,
31
+ totalMatches: matches.length,
32
+ wins,
33
+ draws,
34
+ losses,
35
+ avgGoalsFor: totalGoalsFor / matches.length,
36
+ avgGoalsAgainst: totalGoalsAgainst / matches.length,
37
+ homeAdvantage: this.calculateHomeAdvantage(teamId, matches),
38
+ patterns,
39
+ };
40
+ }
41
+ /**
42
+ * Analyze head-to-head history
43
+ */
44
+ analyzeHeadToHead(teamAId, teamBId, limit = 10) {
45
+ const matches = this.getH2HMatches(teamAId, teamBId, limit);
46
+ let homeWins = 0;
47
+ let awayWins = 0;
48
+ let draws = 0;
49
+ let homeGoals = 0;
50
+ let awayGoals = 0;
51
+ matches.forEach(match => {
52
+ if (!match.score)
53
+ return;
54
+ const isTeamAHome = match.homeTeam.id === teamAId;
55
+ if (match.score.home > match.score.away) {
56
+ if (isTeamAHome)
57
+ homeWins++;
58
+ else
59
+ awayWins++;
60
+ }
61
+ else if (match.score.home < match.score.away) {
62
+ if (isTeamAHome)
63
+ awayWins++;
64
+ else
65
+ homeWins++;
66
+ }
67
+ else {
68
+ draws++;
69
+ }
70
+ homeGoals += isTeamAHome ? match.score.home : match.score.away;
71
+ awayGoals += isTeamAHome ? match.score.away : match.score.home;
72
+ });
73
+ return {
74
+ homeTeam: matches[0]?.homeTeam || { id: teamAId, name: '', country: '' },
75
+ awayTeam: matches[0]?.awayTeam || { id: teamBId, name: '', country: '' },
76
+ totalMatches: matches.length,
77
+ homeWins,
78
+ draws,
79
+ awayWins,
80
+ homeGoals,
81
+ awayGoals,
82
+ recentMatches: matches.slice(0, 5),
83
+ };
84
+ }
85
+ /**
86
+ * Analyze trends for a team
87
+ */
88
+ analyzeTrends(teamId, windowSize = 5) {
89
+ const matches = this.getTeamMatches(teamId).slice(0, windowSize);
90
+ if (matches.length < 3) {
91
+ return {
92
+ direction: 'stable',
93
+ strength: 0,
94
+ confidence: 0,
95
+ dataPoints: matches.length,
96
+ description: 'Insufficient data for trend analysis',
97
+ };
98
+ }
99
+ // Calculate performance in recent matches
100
+ const recentPerformance = matches.slice(0, Math.ceil(windowSize / 2)).map(m => this.getMatchPoints(m, teamId));
101
+ const olderPerformance = matches.slice(Math.ceil(windowSize / 2)).map(m => this.getMatchPoints(m, teamId));
102
+ const recentAvg = recentPerformance.reduce((a, b) => a + b, 0) / recentPerformance.length;
103
+ const olderAvg = olderPerformance.reduce((a, b) => a + b, 0) / olderPerformance.length;
104
+ const difference = recentAvg - olderAvg;
105
+ const strength = Math.min(1, Math.abs(difference) / 2);
106
+ let direction;
107
+ if (difference > 0.5)
108
+ direction = 'up';
109
+ else if (difference < -0.5)
110
+ direction = 'down';
111
+ else
112
+ direction = 'stable';
113
+ const description = direction === 'up'
114
+ ? `Team improving: ${recentAvg.toFixed(2)} pts/game recently vs ${olderAvg.toFixed(2)} before`
115
+ : direction === 'down'
116
+ ? `Team declining: ${recentAvg.toFixed(2)} pts/game recently vs ${olderAvg.toFixed(2)} before`
117
+ : `Team stable: ${recentAvg.toFixed(2)} pts/game`;
118
+ return {
119
+ direction,
120
+ strength,
121
+ confidence: Math.min(100, matches.length * 10),
122
+ dataPoints: matches.length,
123
+ description,
124
+ };
125
+ }
126
+ /**
127
+ * Calculate performance metrics
128
+ */
129
+ calculateMetrics(teamId, query) {
130
+ const matches = this.getTeamMatches(teamId, query);
131
+ if (matches.length === 0) {
132
+ return {
133
+ winRate: 0,
134
+ drawRate: 0,
135
+ lossRate: 0,
136
+ avgGoalsFor: 0,
137
+ avgGoalsAgainst: 0,
138
+ cleanSheetRate: 0,
139
+ bothTeamsScoreRate: 0,
140
+ over25Rate: 0,
141
+ };
142
+ }
143
+ const wins = matches.filter(m => this.isWin(m, teamId)).length;
144
+ const draws = matches.filter(m => this.isDraw(m)).length;
145
+ const losses = matches.filter(m => this.isLoss(m, teamId)).length;
146
+ const totalGoalsFor = matches.reduce((sum, m) => sum + this.getGoalsFor(m, teamId), 0);
147
+ const totalGoalsAgainst = matches.reduce((sum, m) => sum + this.getGoalsAgainst(m, teamId), 0);
148
+ const cleanSheets = matches.filter(m => this.getGoalsAgainst(m, teamId) === 0).length;
149
+ const btts = matches.filter(m => this.getGoalsFor(m, teamId) > 0 && this.getGoalsAgainst(m, teamId) > 0).length;
150
+ const over25 = matches.filter(m => {
151
+ const total = this.getGoalsFor(m, teamId) + this.getGoalsAgainst(m, teamId);
152
+ return total > 2.5;
153
+ }).length;
154
+ return {
155
+ winRate: wins / matches.length,
156
+ drawRate: draws / matches.length,
157
+ lossRate: losses / matches.length,
158
+ avgGoalsFor: totalGoalsFor / matches.length,
159
+ avgGoalsAgainst: totalGoalsAgainst / matches.length,
160
+ cleanSheetRate: cleanSheets / matches.length,
161
+ bothTeamsScoreRate: btts / matches.length,
162
+ over25Rate: over25 / matches.length,
163
+ };
164
+ }
165
+ /**
166
+ * Find betting patterns
167
+ */
168
+ findBettingPatterns(query) {
169
+ const patterns = [];
170
+ const matches = this.queryMatches(query);
171
+ // Pattern: Home favorites
172
+ const homeFavorites = matches.filter(m => m.odds && m.odds.homeWin < 1.5 && m.score && m.score.home > m.score.away);
173
+ if (homeFavorites.length >= 5) {
174
+ patterns.push({
175
+ pattern: 'Home favorites win',
176
+ occurrence: homeFavorites.length,
177
+ successRate: homeFavorites.length / matches.filter(m => m.odds?.homeWin < 1.5).length,
178
+ avgOdds: homeFavorites.reduce((sum, m) => sum + (m.odds?.homeWin || 0), 0) / homeFavorites.length,
179
+ profit: this.calculateProfit(homeFavorites, 'home'),
180
+ });
181
+ }
182
+ // Pattern: Under 2.5 in low-scoring leagues
183
+ const lowScoringMatches = matches.filter(m => {
184
+ const total = (m.score?.home || 0) + (m.score?.away || 0);
185
+ return total < 2.5;
186
+ });
187
+ if (lowScoringMatches.length >= 10) {
188
+ patterns.push({
189
+ pattern: 'Under 2.5 goals',
190
+ occurrence: lowScoringMatches.length,
191
+ successRate: lowScoringMatches.length / matches.length,
192
+ avgOdds: 1.8, // Typical under 2.5 odds
193
+ profit: (lowScoringMatches.length * 0.8 - (matches.length - lowScoringMatches.length)) * 10,
194
+ });
195
+ }
196
+ // Pattern: BTTS
197
+ const bttsMatches = matches.filter(m => (m.score?.home || 0) > 0 && (m.score?.away || 0) > 0);
198
+ if (bttsMatches.length >= 10) {
199
+ patterns.push({
200
+ pattern: 'Both teams score',
201
+ occurrence: bttsMatches.length,
202
+ successRate: bttsMatches.length / matches.length,
203
+ avgOdds: 1.9, // Typical BTTS odds
204
+ profit: (bttsMatches.length * 0.9 - (matches.length - bttsMatches.length)) * 10,
205
+ });
206
+ }
207
+ return patterns.sort((a, b) => b.profit - a.profit);
208
+ }
209
+ /**
210
+ * Analyze referee bias
211
+ */
212
+ analyzeRefereeBias(refereeName, teamId) {
213
+ const matches = this.matchHistory.filter(m => m.referee?.name === refereeName && m.status === 'finished');
214
+ const homeWins = matches.filter(m => m.score && m.score.home > m.score.away).length;
215
+ // Calculate team bias if teamId provided
216
+ let teamBias;
217
+ if (teamId) {
218
+ const teamMatches = matches.filter(m => m.homeTeam.id === teamId || m.awayTeam.id === teamId);
219
+ const teamWins = teamMatches.filter(m => this.isWin(m, teamId)).length;
220
+ teamBias = teamWins / (teamMatches.length || 1);
221
+ }
222
+ return {
223
+ referee: refereeName,
224
+ matches: matches.length,
225
+ avgCards: 3.5, // Placeholder
226
+ homeWinRate: homeWins / (matches.length || 1),
227
+ teamBias,
228
+ };
229
+ }
230
+ /**
231
+ * Analyze weather impact
232
+ */
233
+ analyzeWeatherImpact(condition, teamId) {
234
+ const matches = this.matchHistory.filter(m => m.weather?.condition === condition && m.status === 'finished');
235
+ const totalGoals = matches.reduce((sum, m) => sum + (m.score?.home || 0) + (m.score?.away || 0), 0);
236
+ const homeWins = matches.filter(m => m.score && m.score.home > m.score.away).length;
237
+ let teamPerformance;
238
+ if (teamId) {
239
+ const teamMatches = matches.filter(m => m.homeTeam.id === teamId || m.awayTeam.id === teamId);
240
+ const points = teamMatches.reduce((sum, m) => sum + this.getMatchPoints(m, teamId), 0);
241
+ teamPerformance = points / (teamMatches.length || 1);
242
+ }
243
+ return {
244
+ condition,
245
+ matches: matches.length,
246
+ avgGoals: totalGoals / (matches.length || 1),
247
+ homeWinRate: homeWins / (matches.length || 1),
248
+ teamPerformance,
249
+ };
250
+ }
251
+ /**
252
+ * Get similar matches
253
+ */
254
+ findSimilarMatches(match, limit = 5) {
255
+ return this.matchHistory
256
+ .filter(m => m.id !== match.id &&
257
+ m.status === 'finished' &&
258
+ m.league.id === match.league.id)
259
+ .map(m => ({
260
+ match: m,
261
+ similarity: this.calculateSimilarity(match, m),
262
+ }))
263
+ .sort((a, b) => b.similarity - a.similarity)
264
+ .slice(0, limit)
265
+ .map(r => r.match);
266
+ }
267
+ /**
268
+ * Calculate similarity between two matches
269
+ */
270
+ calculateSimilarity(matchA, matchB) {
271
+ let score = 0;
272
+ // Same league
273
+ if (matchA.league.id === matchB.league.id)
274
+ score += 0.3;
275
+ // Similar odds
276
+ if (matchA.odds && matchB.odds) {
277
+ const oddsDiff = Math.abs(matchA.odds.homeWin - matchB.odds.homeWin);
278
+ score += Math.max(0, 0.3 - oddsDiff);
279
+ }
280
+ // Similar teams (by position)
281
+ if (matchA.homeTeam.stats?.position && matchB.homeTeam.stats?.position) {
282
+ const posDiff = Math.abs(matchA.homeTeam.stats.position - matchB.homeTeam.stats.position);
283
+ score += Math.max(0, 0.2 - (posDiff / 20));
284
+ }
285
+ // Same venue type
286
+ if (matchA.venue && matchB.venue)
287
+ score += 0.2;
288
+ return score;
289
+ }
290
+ // Helper methods
291
+ getTeamMatches(teamId, query) {
292
+ let matches = this.matchHistory.filter(m => (m.homeTeam.id === teamId || m.awayTeam.id === teamId) &&
293
+ m.status === 'finished');
294
+ if (query?.dateFrom) {
295
+ matches = matches.filter(m => m.date >= query.dateFrom);
296
+ }
297
+ if (query?.dateTo) {
298
+ matches = matches.filter(m => m.date <= query.dateTo);
299
+ }
300
+ if (query?.venue) {
301
+ matches = matches.filter(m => query.venue === 'home' ? m.homeTeam.id === teamId :
302
+ query.venue === 'away' ? m.awayTeam.id === teamId :
303
+ true);
304
+ }
305
+ return matches.sort((a, b) => b.date.getTime() - a.date.getTime());
306
+ }
307
+ getH2HMatches(teamAId, teamBId, limit) {
308
+ return this.matchHistory
309
+ .filter(m => ((m.homeTeam.id === teamAId && m.awayTeam.id === teamBId) ||
310
+ (m.homeTeam.id === teamBId && m.awayTeam.id === teamAId)) &&
311
+ m.status === 'finished')
312
+ .sort((a, b) => b.date.getTime() - a.date.getTime())
313
+ .slice(0, limit);
314
+ }
315
+ isWin(match, teamId) {
316
+ if (!match.score)
317
+ return false;
318
+ const isHome = match.homeTeam.id === teamId;
319
+ return isHome
320
+ ? match.score.home > match.score.away
321
+ : match.score.away > match.score.home;
322
+ }
323
+ isDraw(match) {
324
+ if (!match.score)
325
+ return false;
326
+ return match.score.home === match.score.away;
327
+ }
328
+ isLoss(match, teamId) {
329
+ if (!match.score)
330
+ return false;
331
+ const isHome = match.homeTeam.id === teamId;
332
+ return isHome
333
+ ? match.score.home < match.score.away
334
+ : match.score.away < match.score.home;
335
+ }
336
+ getGoalsFor(match, teamId) {
337
+ if (!match.score)
338
+ return 0;
339
+ return match.homeTeam.id === teamId
340
+ ? match.score.home
341
+ : match.score.away;
342
+ }
343
+ getGoalsAgainst(match, teamId) {
344
+ if (!match.score)
345
+ return 0;
346
+ return match.homeTeam.id === teamId
347
+ ? match.score.away
348
+ : match.score.home;
349
+ }
350
+ getMatchPoints(match, teamId) {
351
+ if (this.isWin(match, teamId))
352
+ return 3;
353
+ if (this.isDraw(match))
354
+ return 1;
355
+ return 0;
356
+ }
357
+ calculateHomeAdvantage(teamId, matches) {
358
+ const homeMatches = matches.filter(m => m.homeTeam.id === teamId);
359
+ const awayMatches = matches.filter(m => m.awayTeam.id === teamId);
360
+ if (homeMatches.length === 0 || awayMatches.length === 0)
361
+ return 0;
362
+ const homeWinRate = homeMatches.filter(m => this.isWin(m, teamId)).length / homeMatches.length;
363
+ const awayWinRate = awayMatches.filter(m => this.isWin(m, teamId)).length / awayMatches.length;
364
+ return homeWinRate - awayWinRate;
365
+ }
366
+ findPatterns(teamId, matches) {
367
+ const patterns = [];
368
+ // Pattern: Strong at home
369
+ const homeMatches = matches.filter(m => m.homeTeam.id === teamId);
370
+ const homeWins = homeMatches.filter(m => this.isWin(m, teamId)).length;
371
+ if (homeMatches.length >= 5 && homeWins / homeMatches.length > 0.6) {
372
+ patterns.push({
373
+ pattern: 'Strong home record',
374
+ occurrence: homeWins,
375
+ successRate: homeWins / homeMatches.length,
376
+ avgOdds: 1.8,
377
+ profit: 0,
378
+ });
379
+ }
380
+ // Pattern: High scoring
381
+ const highScoring = matches.filter(m => this.getGoalsFor(m, teamId) + this.getGoalsAgainst(m, teamId) > 2.5);
382
+ if (highScoring.length / matches.length > 0.6) {
383
+ patterns.push({
384
+ pattern: 'High scoring matches',
385
+ occurrence: highScoring.length,
386
+ successRate: highScoring.length / matches.length,
387
+ avgOdds: 1.9,
388
+ profit: 0,
389
+ });
390
+ }
391
+ return patterns;
392
+ }
393
+ calculateProfit(matches, betOn) {
394
+ let profit = 0;
395
+ matches.forEach(m => {
396
+ if (!m.odds || !m.score)
397
+ return;
398
+ const won = betOn === 'home' && m.score.home > m.score.away ||
399
+ betOn === 'away' && m.score.away > m.score.home ||
400
+ betOn === 'draw' && m.score.home === m.score.away;
401
+ if (won) {
402
+ profit += (m.odds[betOn === 'home' ? 'homeWin' : betOn === 'away' ? 'awayWin' : 'draw'] - 1) * 10;
403
+ }
404
+ else {
405
+ profit -= 10;
406
+ }
407
+ });
408
+ return profit;
409
+ }
410
+ queryMatches(query) {
411
+ let matches = this.matchHistory.filter(m => m.status === 'finished');
412
+ if (query.team) {
413
+ matches = matches.filter(m => m.homeTeam.name === query.team || m.awayTeam.name === query.team);
414
+ }
415
+ if (query.league) {
416
+ matches = matches.filter(m => m.league.name === query.league);
417
+ }
418
+ if (query.dateFrom) {
419
+ matches = matches.filter(m => m.date >= query.dateFrom);
420
+ }
421
+ if (query.dateTo) {
422
+ matches = matches.filter(m => m.date <= query.dateTo);
423
+ }
424
+ return matches;
425
+ }
426
+ createEmptyPerformance(teamId) {
427
+ return {
428
+ team: { id: teamId, name: '', country: '' },
429
+ totalMatches: 0,
430
+ wins: 0,
431
+ draws: 0,
432
+ losses: 0,
433
+ avgGoalsFor: 0,
434
+ avgGoalsAgainst: 0,
435
+ homeAdvantage: 0,
436
+ patterns: [],
437
+ };
438
+ }
439
+ loadHistoricalData() {
440
+ // Would load from database
441
+ // For now, start empty
442
+ }
443
+ /**
444
+ * Add match to history
445
+ */
446
+ addMatch(match) {
447
+ this.matchHistory.push(match);
448
+ // Keep only last 1000 matches
449
+ if (this.matchHistory.length > 1000) {
450
+ this.matchHistory.shift();
451
+ }
452
+ }
453
+ }
454
+ // Singleton instance
455
+ let globalHistoricalAnalyzer = null;
456
+ export function getHistoricalAnalyzer() {
457
+ if (!globalHistoricalAnalyzer) {
458
+ globalHistoricalAnalyzer = new HistoricalAnalyzer();
459
+ }
460
+ return globalHistoricalAnalyzer;
461
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * SPORTS MODULE CORE - Exports
3
+ */
4
+ export * from './types.js';
5
+ export { CacheService, getGlobalCache, resetGlobalCache } from './cache.js';
6
+ export { CircuitBreaker, CircuitBreakerOpenError, getCircuitBreaker, getAllCircuitBreakerStatus } from './circuit-breaker.js';
7
+ export { withRetry, withRetryAndCircuitBreaker, createRetryable, DEFAULT_RETRY_CONFIG, AGGRESSIVE_RETRY_CONFIG, LIVE_DATA_RETRY_CONFIG } from './retry.js';
8
+ export { RealtimeDataManager, getRealtimeManager, resetRealtimeManager } from './realtime-manager.js';
9
+ export { AlertManager, getAlertManager, resetAlertManager } from './alert-manager.js';
10
+ export { DataQualityValidator, getDataQualityValidator } from './data-quality.js';
11
+ export { MLPredictionEngine, getPredictionEngine } from './ml-prediction.js';
12
+ export { HistoricalAnalyzer, getHistoricalAnalyzer } from './historical-analyzer.js';
13
+ export { API_CONFIG, CACHE_CONFIG, SCRAPER_CONFIG, LEAGUES, QUERY_TYPES, BETTING, POSITIONS, MATCH_STATUS, ERRORS, ALERT_CONFIG, REALTIME_CONFIG, ML_CONFIG, MODULE_INFO } from './constants.js';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * SPORTS MODULE CORE - Exports
3
+ */
4
+ // Types
5
+ export * from './types.js';
6
+ // Core classes
7
+ export { CacheService, getGlobalCache, resetGlobalCache } from './cache.js';
8
+ export { CircuitBreaker, CircuitBreakerOpenError, getCircuitBreaker, getAllCircuitBreakerStatus } from './circuit-breaker.js';
9
+ export { withRetry, withRetryAndCircuitBreaker, createRetryable, DEFAULT_RETRY_CONFIG, AGGRESSIVE_RETRY_CONFIG, LIVE_DATA_RETRY_CONFIG } from './retry.js';
10
+ export { RealtimeDataManager, getRealtimeManager, resetRealtimeManager } from './realtime-manager.js';
11
+ export { AlertManager, getAlertManager, resetAlertManager } from './alert-manager.js';
12
+ export { DataQualityValidator, getDataQualityValidator } from './data-quality.js';
13
+ export { MLPredictionEngine, getPredictionEngine } from './ml-prediction.js';
14
+ export { HistoricalAnalyzer, getHistoricalAnalyzer } from './historical-analyzer.js';
15
+ // Constants
16
+ export { API_CONFIG, CACHE_CONFIG, SCRAPER_CONFIG, LEAGUES, QUERY_TYPES, BETTING, POSITIONS, MATCH_STATUS, ERRORS, ALERT_CONFIG, REALTIME_CONFIG, ML_CONFIG, MODULE_INFO } from './constants.js';
@@ -0,0 +1,134 @@
1
+ /**
2
+ * ML PREDICTION ENGINE
3
+ * Machine learning based match outcome prediction
4
+ */
5
+ import type { Match, TeamStats, PredictionFactor, HeadToHead } from './types.js';
6
+ export interface PredictionInput {
7
+ match: Match;
8
+ homeForm: FormData;
9
+ awayForm: FormData;
10
+ h2h: HeadToHead;
11
+ homeStats: TeamStats;
12
+ awayStats: TeamStats;
13
+ injuries: InjuryData;
14
+ weather?: WeatherData;
15
+ }
16
+ export interface FormData {
17
+ last5: ('W' | 'D' | 'L')[];
18
+ goalsFor: number;
19
+ goalsAgainst: number;
20
+ xG: number;
21
+ xGA: number;
22
+ }
23
+ export interface InjuryData {
24
+ home: {
25
+ keyPlayers: number;
26
+ total: number;
27
+ };
28
+ away: {
29
+ keyPlayers: number;
30
+ total: number;
31
+ };
32
+ }
33
+ export interface WeatherData {
34
+ temperature: number;
35
+ condition: string;
36
+ windSpeed: number;
37
+ precipitation: boolean;
38
+ }
39
+ export interface PredictionResult {
40
+ homeWin: number;
41
+ draw: number;
42
+ awayWin: number;
43
+ over25: number;
44
+ btts: number;
45
+ confidence: number;
46
+ factors: PredictionFactor[];
47
+ }
48
+ /**
49
+ * ML Prediction Engine
50
+ * Uses weighted factors and historical patterns for predictions
51
+ */
52
+ export declare class MLPredictionEngine {
53
+ private weights;
54
+ private historicalData;
55
+ constructor();
56
+ /**
57
+ * Predict match outcome
58
+ */
59
+ predict(input: PredictionInput): Promise<PredictionResult>;
60
+ /**
61
+ * Calculate form score (-1 to 1)
62
+ */
63
+ private calculateFormScore;
64
+ private formToPoints;
65
+ /**
66
+ * Calculate H2H score (-1 to 1)
67
+ */
68
+ private calculateH2HScore;
69
+ /**
70
+ * Calculate home advantage score (0 to 1)
71
+ */
72
+ private calculateHomeAdvantage;
73
+ /**
74
+ * Calculate xG score (-1 to 1)
75
+ */
76
+ private calculateXgScore;
77
+ /**
78
+ * Calculate injury impact (-1 to 1)
79
+ */
80
+ private calculateInjuryImpact;
81
+ /**
82
+ * Calculate fatigue impact (-1 to 1)
83
+ */
84
+ private calculateFatigueImpact;
85
+ /**
86
+ * Calculate weather impact (-0.5 to 0.5)
87
+ */
88
+ private calculateWeatherImpact;
89
+ /**
90
+ * Combine weighted scores
91
+ */
92
+ private combineScores;
93
+ /**
94
+ * Convert score to probabilities
95
+ */
96
+ private scoreToProbabilities;
97
+ /**
98
+ * Calculate confidence level
99
+ */
100
+ private calculateConfidence;
101
+ /**
102
+ * Predict Over 2.5 goals
103
+ */
104
+ private predictOver25;
105
+ /**
106
+ * Predict Both Teams to Score
107
+ */
108
+ private predictBTTS;
109
+ /**
110
+ * Describe form impact
111
+ */
112
+ private describeFormImpact;
113
+ /**
114
+ * Describe H2H impact
115
+ */
116
+ private describeH2HImpact;
117
+ /**
118
+ * Describe injury impact
119
+ */
120
+ private describeInjuryImpact;
121
+ /**
122
+ * Describe weather impact
123
+ */
124
+ private describeWeatherImpact;
125
+ /**
126
+ * Load historical data
127
+ */
128
+ private loadHistoricalData;
129
+ /**
130
+ * Learn from past predictions
131
+ */
132
+ learnFromResult(prediction: PredictionResult, actualResult: 'home' | 'draw' | 'away', odds: number): void;
133
+ }
134
+ export declare function getPredictionEngine(): MLPredictionEngine;