Відображення результатів бектестингу в мобільному додатку
Бектест працює годинами на сервері, перебираючи історичні дані. Мобільний додаток отримує готові результати та повинен їх показати так, щоб трейдер розумів: стратегія працює чи ні, за яких умов просідає, наскільки гірше реальної торгівлі.
Структура результатів бектесту
Результат бектесту — це не одне число PnL. Повний звіт містить:
{
"summary": {
"totalPnl": 4820.50,
"winRate": 0.62,
"profitFactor": 1.94,
"maxDrawdown": -0.183,
"sharpeRatio": 1.42,
"totalTrades": 847,
"avgTradeReturn": 0.0057,
"period": { "from": "2023-01-01", "to": "2024-01-01" }
},
"equityCurve": [
{ "ts": 1672531200, "equity": 10000.0 },
{ "ts": 1672617600, "equity": 10084.5 }
],
"trades": [...],
"monthlyBreakdown": [
{ "month": "2023-01", "pnl": 342.5, "trades": 68, "winRate": 0.59 }
],
"drawdownPeriods": [
{ "from": "2023-03-10", "to": "2023-03-25", "depth": -0.183 }
]
}
Обсяг equityCurve та trades може бути великим — 10,000+ точок за рік мінутного бектесту. Завантажуємо постарницево: спочатку summary та equity curve (основний екран), детальні угоди — за запитом користувача.
Equity Curve та Drawdown
Два графіки, які відповідають на головне питання — «як поводився рахунок»:
Equity Curve — ріст початкового капіталу у часі. Ідеально — гладка лінія вгору. На практиці — пилоподібна з drawdown-періодами.
Drawdown — площа під equity curve, що показує наскільки глибоко рахунок падав від попереднього максимуму. Зазвичай показують як окремий графік нижче equity curve. Червона область: чим глибше та довше — тим гірше.
На Flutter обидва графіки через fl_chart, LineChart з belowBarData для drawdown:
// Equity curve
LineChartBarData(
spots: equityCurve.map((p) => FlSpot(p.ts.toDouble(), p.equity)).toList(),
isCurved: false,
color: Colors.green,
barWidth: 1.5,
dotData: const FlDotData(show: false),
)
// Drawdown як окремий LineChart з від'ємними значеннями
// equityMax[i] = max(equity[0..i]), drawdown[i] = (equity[i] - equityMax[i]) / equityMax[i]
10,000 FlSpot — це багато. На слабких пристроях рендеринг просядає. Рішення: downsampling через LTTB-алгоритм (Largest Triangle Three Buckets) до 500–1000 точок. LTTB зберігає візуальну форму кривої при значному зменшенні кількості точок.
Monthly Breakdown
Таблиця за місяцями — швидкий спосіб побачити сезонність стратегії:
| Місяць | PnL | Угоди | Win Rate |
|---|---|---|---|
| Січ 2023 | +342 USDT | 68 | 59% |
| Лют 2023 | +128 USDT | 71 | 54% |
| Бер 2023 | −280 USDT | 64 | 41% |
| ... |
Комірки PnL із кольоровим кодуванням: зелений градієнт для прибуткових місяців, червоний — для збиткових. Інтенсивність кольору — нормалізована величина PnL щодо найкращого/найгіршого місяця.
Порівняння бектестів
Користувач запустив один бектест з параметрами A та інший з параметрами B. Екран порівняння — два equity curve на одному графіку плюс summary таблиця метрик.
// iOS — порівняння двох бектестів
struct BacktestCompareView: View {
let testA: BacktestResult
let testB: BacktestResult
var body: some View {
VStack {
ComparisonChart(curveA: testA.equityCurve, curveB: testB.equityCurve)
ComparisonMetricsTable(rows: [
("Win Rate", testA.summary.winRate.pct, testB.summary.winRate.pct),
("Max DD", testA.summary.maxDrawdown.pct, testB.summary.maxDrawdown.pct),
("Profit Factor", testA.summary.profitFactor.fmt, testB.summary.profitFactor.fmt),
("Sharpe", testA.summary.sharpeRatio.fmt, testB.summary.sharpeRatio.fmt),
])
}
}
}
Що входить до роботи
- Дашборд summary з ключовими метриками
- Equity curve з LTTB-downsampling для продуктивності
- Drawdown графік
- Monthly breakdown таблиця із кольоровим кодуванням
- Історія угод з пагінацією
- Екран порівняння двох бектестів (опціонально)
Терміни
5–8 робочих днів залежно від набору графіків та наявності порівняння. Вартість розраховується індивідуально після аналізу вимог.







