38e1d64437
CI / lint-test-build (push) Successful in 2m31s
- Introduced backtesting page and fragment in the dashboard for running backtests and viewing recent reports. - Implemented backtest run logic with configuration options including event path, starting balances, trade capital, and fee profiles. - Added recent backtest reports storage and retrieval. - Created a new strategy module for statistical arbitrage experiments with validation on configuration parameters. - Updated settings to include parameters for the statistical arbitrage strategy. - Enhanced dashboard controls to support the new strategy mode. - Added unit tests for backtesting functionality and strategy validation. - Updated templates for backtesting UI integration.
143 lines
4.3 KiB
HTML
143 lines
4.3 KiB
HTML
<div id="backtesting-shell" class="panel">
|
|
<div
|
|
class="grid"
|
|
style="grid-template-columns: repeat(auto-fit, minmax(280px, 1fr))"
|
|
>
|
|
<article class="card">
|
|
<div class="label">Run Status</div>
|
|
<div class="value">{{ status }}</div>
|
|
<div class="meta">{{ message }}</div>
|
|
</article>
|
|
<article class="card">
|
|
<div class="label">Latest Report</div>
|
|
{% if latest_report %}
|
|
<div class="meta">Run at {{ latest_report.run_at }}</div>
|
|
<div class="meta">Events: {{ latest_report.events_path }}</div>
|
|
<div class="meta">
|
|
Processed: {{ latest_report.report.processed_events }}
|
|
</div>
|
|
<div class="meta">
|
|
Opportunities: {{ latest_report.report.opportunities_seen }}
|
|
</div>
|
|
<div class="meta">Trades: {{ latest_report.report.trades_executed }}</div>
|
|
<div class="meta">
|
|
Realized P&L: {{
|
|
'%.4f'|format(latest_report.report.realized_pnl_usd) }} USD
|
|
</div>
|
|
<div class="meta">
|
|
Max drawdown: {{ '%.4f'|format(latest_report.report.max_drawdown_usd) }}
|
|
USD
|
|
</div>
|
|
{% else %}
|
|
<div class="meta">No runs yet.</div>
|
|
{% endif %}
|
|
</article>
|
|
</div>
|
|
|
|
<article class="card" style="margin-top: 16px">
|
|
<div class="label">Run Backtest</div>
|
|
<form
|
|
class="form-grid"
|
|
hx-post="{{ run_endpoint }}"
|
|
hx-target="#backtesting-shell"
|
|
hx-swap="outerHTML"
|
|
>
|
|
<label class="field">
|
|
<span>Replay events path (JSONL)</span>
|
|
<input
|
|
name="events_path"
|
|
type="text"
|
|
value="{{ events_path }}"
|
|
placeholder="data/replay.jsonl"
|
|
/>
|
|
</label>
|
|
<label class="field">
|
|
<span>Starting balances</span>
|
|
<input
|
|
name="starting_balances"
|
|
type="text"
|
|
value="{{ starting_balances }}"
|
|
placeholder="USD=1000.0,BTC=0.0"
|
|
/>
|
|
</label>
|
|
<label class="field">
|
|
<span>Trade capital</span>
|
|
<input
|
|
name="trade_capital"
|
|
type="number"
|
|
min="0"
|
|
step="0.01"
|
|
value="{{ trade_capital }}"
|
|
/>
|
|
</label>
|
|
<label class="field">
|
|
<span>Min profit threshold</span>
|
|
<input
|
|
name="min_profit_threshold"
|
|
type="number"
|
|
min="0"
|
|
step="0.0001"
|
|
value="{{ min_profit_threshold }}"
|
|
/>
|
|
</label>
|
|
<label class="field">
|
|
<span>Fee profile</span>
|
|
<select name="fee_profile">
|
|
{% set sel = "selected" if fee_profile == "standard" else "" %}
|
|
<option value="standard" {{ sel }}>standard</option>
|
|
{% set sel = "selected" if fee_profile == "maker_heavy" else "" %}
|
|
<option value="maker_heavy" {{ sel }}>maker_heavy</option>
|
|
{% set sel = "selected" if fee_profile == "taker_heavy" else "" %}
|
|
<option value="taker_heavy" {{ sel }}>taker_heavy</option>
|
|
{% set sel = "selected" if fee_profile == "custom" else "" %}
|
|
<option value="custom" {{ sel }}>custom</option>
|
|
</select>
|
|
</label>
|
|
<label class="field">
|
|
<span>Custom fee rate (if fee profile = custom)</span>
|
|
<input
|
|
name="custom_fee_rate"
|
|
type="number"
|
|
min="0"
|
|
step="0.0001"
|
|
value="{{ custom_fee_rate }}"
|
|
/>
|
|
</label>
|
|
<label class="field">
|
|
<span>Slippage (bps)</span>
|
|
<input
|
|
name="slippage_bps"
|
|
type="number"
|
|
min="0"
|
|
step="0.1"
|
|
value="{{ slippage_bps }}"
|
|
/>
|
|
</label>
|
|
<label class="field">
|
|
<span>Execution latency (ms)</span>
|
|
<input
|
|
name="execution_latency_ms"
|
|
type="number"
|
|
min="0"
|
|
step="0.1"
|
|
value="{{ execution_latency_ms }}"
|
|
/>
|
|
</label>
|
|
<button type="submit" class="button">Run backtest</button>
|
|
</form>
|
|
</article>
|
|
|
|
<article class="card" style="margin-top: 16px">
|
|
<div class="label">Recent Runs</div>
|
|
{% if recent_reports %} {% for item in recent_reports %}
|
|
<div class="meta">
|
|
{{ item.run_at }} | {{ item.events_path }} | trades={{
|
|
item.report.trades_executed }} | pnl={{
|
|
'%.4f'|format(item.report.realized_pnl_usd) }} USD
|
|
</div>
|
|
{% endfor %} {% else %}
|
|
<div class="meta">No recent reports yet.</div>
|
|
{% endif %}
|
|
</article>
|
|
</div>
|