feat(backtest): historical strategy backtester
Adds an interactive backtester that replays the SuspensionFlip detector over all flagged anomalies under a chosen score threshold and staking rule (flat / percent-of-bankroll / Kelly), and reports the headline numbers a user needs to judge edge: final bankroll, ROI, max drawdown (peak-to-trough), win/loss streaks, plus per-bet equity curve. Domain (pure): - StakeRule enum + BacktestStrategy params (with validation). - BacktestSimulator: deterministic function taking strategy + chronological candidates → BacktestResult. Implements Kelly with post-flip implied prob as p (skipping negative-edge bets), peak-to-trough drawdown tracking, and win/loss streak rollups. Mirrors AnomalyOutcomeEvaluator on the 2-way Draw guard so tennis data inconsistencies are refused rather than miss-counted. - Skipped counter split into SkippedByThreshold / SkippedByDataQuality / SkippedByBankroll so the UI can distinguish "strategy choice" from "data-quality" from "bankroll empty". Application: - RunBacktestUseCase: loads anomalies + events + results, parses evidence, builds candidates, hands event titles into the simulator so the UI does zero repository round-trips of its own. UI: - Pages/Anomalies/Backtest.razor: hero, strategy form (MudBlazor — conditional sub-field per staking rule), 4-card KPI strip (final bankroll / net profit / ROI / max drawdown), counters row, inline-SVG equity curve, trade-trace table with per-bet outcome pills and link-back to the source anomaly. - Nav entry under Analysis. RU + EN i18n. Tests: +20 (16 simulator math — flat / percent compounding / Kelly +/- edge / quarter-Kelly / bankroll-exceeded / out-of-order chronology / Draw favourite / multi-window drawdown / event-title pass-through + 4 use-case join). All 399 tests pass. Money rounding switched to MidpointRounding.AwayFromZero throughout the simulator output for accounting convention. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -423,4 +423,52 @@
|
||||
<data name="Journal.Resolve.None"><value>Ожидающих ставок к расчёту нет.</value></data>
|
||||
<data name="Journal.Resolve.Done"><value>Рассчитано ожидающих: {0}.</value></data>
|
||||
<data name="Journal.Confirm.Delete"><value>Удалить эту ставку безвозвратно?</value></data>
|
||||
|
||||
<data name="Nav.Backtest"><value>Бэктест</value></data>
|
||||
<data name="Backtest.Kicker"><value>Симулятор</value></data>
|
||||
<data name="Backtest.Title"><value>Прогон детектора по истории</value></data>
|
||||
<data name="Backtest.Lede"><value>Запустите гипотетическую стратегию на всех зафиксированных аномалиях. Выберите порог уверенности и правило стейкинга — симулятор разыграет каждую ставку против реального исхода, нарастит банк и покажет ключевые метрики для оценки преимущества.</value></data>
|
||||
<data name="Backtest.Section.Strategy"><value>Стратегия</value></data>
|
||||
<data name="Backtest.Section.Headline"><value>Результат</value></data>
|
||||
<data name="Backtest.Section.Equity"><value>Кривая банка</value></data>
|
||||
<data name="Backtest.Section.Trace"><value>Хронология ставок</value></data>
|
||||
<data name="Backtest.Field.Bankroll"><value>Стартовый банк</value></data>
|
||||
<data name="Backtest.Field.MinScore"><value>Мин. score аномалии</value></data>
|
||||
<data name="Backtest.Field.MinScore.Hint"><value>Ставим только при уверенности не ниже этого порога.</value></data>
|
||||
<data name="Backtest.Field.StakeRule"><value>Правило стейкинга</value></data>
|
||||
<data name="Backtest.Field.FlatStake"><value>Фикс. ставка</value></data>
|
||||
<data name="Backtest.Field.PercentOfBankroll"><value>Процент от банка</value></data>
|
||||
<data name="Backtest.Field.KellyFraction"><value>Доля Келли</value></data>
|
||||
<data name="Backtest.Field.KellyFraction.Hint"><value>0,25 (четверть-Келли) — консервативный дефолт.</value></data>
|
||||
<data name="Backtest.StakeRule.Flat"><value>Фиксированная</value></data>
|
||||
<data name="Backtest.StakeRule.PercentOfBankroll"><value>% от банка</value></data>
|
||||
<data name="Backtest.StakeRule.Kelly"><value>Келли</value></data>
|
||||
<data name="Backtest.Action.Run"><value>Запустить</value></data>
|
||||
<data name="Backtest.Action.Running"><value>Симуляция…</value></data>
|
||||
<data name="Backtest.Stat.FinalBankroll"><value>Итоговый банк</value></data>
|
||||
<data name="Backtest.Stat.NetProfit"><value>Чистая прибыль</value></data>
|
||||
<data name="Backtest.Stat.Roi"><value>ROI</value></data>
|
||||
<data name="Backtest.Stat.MaxDrawdown"><value>Макс. просадка</value></data>
|
||||
<data name="Backtest.Stat.BetsPlaced"><value>Поставлено</value></data>
|
||||
<data name="Backtest.Stat.Wins"><value>Победы</value></data>
|
||||
<data name="Backtest.Stat.Losses"><value>Поражения</value></data>
|
||||
<data name="Backtest.Stat.Skipped"><value>Пропущено</value></data>
|
||||
<data name="Backtest.Stat.MaxWinStreak"><value>Макс. серия побед</value></data>
|
||||
<data name="Backtest.Stat.MaxLossStreak"><value>Макс. серия пораж.</value></data>
|
||||
<data name="Backtest.Stat.TotalStaked"><value>Всего поставлено</value></data>
|
||||
<data name="Backtest.Stat.TotalReturned"><value>Всего возвращено</value></data>
|
||||
<data name="Backtest.Column.DetectedAt"><value>Замечено</value></data>
|
||||
<data name="Backtest.Column.Match"><value>Матч</value></data>
|
||||
<data name="Backtest.Column.Score"><value>Score</value></data>
|
||||
<data name="Backtest.Column.Pick"><value>Выбор</value></data>
|
||||
<data name="Backtest.Column.Rate"><value>Кэф</value></data>
|
||||
<data name="Backtest.Column.Stake"><value>Ставка</value></data>
|
||||
<data name="Backtest.Column.Payout"><value>Выплата</value></data>
|
||||
<data name="Backtest.Column.Bankroll"><value>Банк</value></data>
|
||||
<data name="Backtest.Column.Outcome"><value>Исход</value></data>
|
||||
<data name="Backtest.Outcome.Win"><value>Победа</value></data>
|
||||
<data name="Backtest.Outcome.Loss"><value>Проигрыш</value></data>
|
||||
<data name="Backtest.Empty.NoData"><value>Аномалий с результатом ещё нет. Запустите загрузчик результатов, чтобы симулятору было на чём прогоняться.</value></data>
|
||||
<data name="Backtest.Empty.NoBetsPlaced"><value>Стратегия не сделала ни одной ставки — снизьте порог score или поменяйте правило стейкинга.</value></data>
|
||||
<data name="Backtest.Error.Generic"><value>Симуляция упала — проверьте параметры формы и повторите.</value></data>
|
||||
</root>
|
||||
|
||||
Reference in New Issue
Block a user