Backtesting Results Display in Mobile App
Backtest runs for hours on server, iterating through historical data. Mobile app receives ready results and must display them so trader understands: does strategy work or not, under what conditions does it drawdown, how much worse than live trading.
Backtest Result Structure
Backtest result is not a single PnL number. Full report contains:
{
"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 }
]
}
Volume of equityCurve and trades can be large—10,000+ points per year of minute-level backtest. Load in pages: first summary and equity curve (main screen), detailed trades—on user request.
Equity Curve and Drawdown
Two charts that answer the main question—"how did the account behave":
Equity Curve—growth of initial capital over time. Ideally—smooth upward line. In practice—sawtooth with drawdown periods.
Drawdown—area below equity curve, showing how deep the account fell from previous maximum. Usually shown as separate chart below equity curve. Red area: the deeper and longer—the worse.
On Flutter both charts via fl_chart, LineChart with belowBarData for 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 as separate LineChart with negative values
// equityMax[i] = max(equity[0..i]), drawdown[i] = (equity[i] - equityMax[i]) / equityMax[i]
10,000 FlSpot is a lot. On weak devices rendering will lag. Solution: downsampling via LTTB algorithm (Largest Triangle Three Buckets) to 500–1000 points. LTTB preserves visual curve shape at significant point reduction.
Monthly Breakdown
Month-by-month table—quick way to see strategy seasonality:
| Month | PnL | Trades | Win Rate |
|---|---|---|---|
| Jan 2023 | +342 USDT | 68 | 59% |
| Feb 2023 | +128 USDT | 71 | 54% |
| Mar 2023 | −280 USDT | 64 | 41% |
| ... |
PnL cells with color coding: green gradient for profitable months, red for losing. Color intensity—normalized PnL relative to best/worst month.
Backtest Comparison
User ran one backtest with parameters A and another with parameters B. Comparison screen—two equity curves on same chart plus summary metrics table.
// iOS — compare two backtests
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),
])
}
}
}
What's Included
- Summary dashboard with key metrics
- Equity curve with LTTB-downsampling for performance
- Drawdown chart
- Monthly breakdown table with color coding
- Trade history with pagination
- Backtest comparison screen (optional)
Timeline
5–8 business days depending on chart set and comparison presence. Cost is calculated individually after requirements analysis.







