Files
maraphon-app/src/Marathon.Domain/AnomalyDetection/IAnomalyDetector.cs
T
alexei.dolgolyov 2b1025cae3 feat(anomaly): IAnomalyDetector seam + steam-move detector
- Introduce IAnomalyDetector; the existing flip detector implements it.
- Extract MatchWinEvidence so every detector writes the identical pre/post
  evidence shape — the UI parser and outcome evaluator handle new kinds with no
  branching (steam moves get hit-rate calibrated for free).
- Add SteamMoveDetector: flags a rapid one-directional implied-probability rise
  over a short CONTINUOUS window (no suspension gap inside it), so it never
  double-flags the same interval as the suspension-flip detector.
- DetectAnomaliesUseCase fans out over both detectors; dedup keys on EventId+Kind
  so flip and steam signals persist independently. Add AnomalyKind.SteamMove +
  SteamMove window/threshold options. 8 detector tests.
2026-05-28 22:59:12 +03:00

19 lines
686 B
C#

using Marathon.Domain.Entities;
using Marathon.Domain.ValueObjects;
namespace Marathon.Domain.AnomalyDetection;
/// <summary>
/// A pure, stateless detector that scans one event's snapshot timeline and returns
/// any anomalies it finds. Implementations are deterministic and free of I/O so they
/// can be composed (fanned out) and unit-tested in isolation.
/// </summary>
public interface IAnomalyDetector
{
/// <summary>
/// Analyses <paramref name="snapshots"/> for <paramref name="eventId"/> and returns
/// 0 or more anomalies. May be empty; never null.
/// </summary>
IReadOnlyList<Anomaly> Detect(EventId eventId, IReadOnlyList<OddsSnapshot> snapshots);
}