[verified] Real backtest engine + backtest UI section (start/end dates, P&L, persisted)
- backtest.py: buy-and-hold backtest over [start,end] — allocates 50/20/30 at first available rebalance date, marks to market to end, accrues dividend, reports {final_value, price_pnl, dividend_income, net_return, trades, holdings}
- Fixed double-spend bug (was allocating full capital every rebalance -> negative cash)
- dashboard.default_scores(): per-symbol combined/dividend/yield baseline for backtest
- POST /api/v1/backtest + GET /api/v1/backtest/runs (results persisted in app state -> survive refresh)
- Frontend: backtest section w/ start/end/capital/freq inputs + P&L KPIs + run history table
- Honest note: uses current combined scores as static baseline (non-PIT); PIT score_fn pluggable
- Verified: 1M -> 1.088M (+8.80%) over 2024-06..2026-06; history persists across refresh
This commit is contained in:
@@ -189,6 +189,21 @@ tbody tr:hover { background: rgba(255,255,255,.025); }
|
||||
.calc-step-note { font-size: 11px; color: var(--faint); margin-top: 3px; line-height: 1.5; }
|
||||
.calc-z { font-size: 11px; color: var(--faint); margin-top: 8px; line-height: 1.6; }
|
||||
|
||||
/* backtest section */
|
||||
.backtest-controls { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; padding: 16px 0; }
|
||||
.backtest-controls label { display: flex; flex-direction: column; gap: 4px; font-size: 11px; color: var(--faint); }
|
||||
.backtest-controls input, .backtest-controls select { background: #0a0e14; border: 1px solid var(--line-bright); color: var(--text); border-radius: 6px; padding: 7px 9px; font-size: 12px; }
|
||||
.primary-btn { background: var(--mint); color: #062a1f; border: none; border-radius: 7px; padding: 9px 16px; font-weight: 700; cursor: pointer; font-size: 12px; }
|
||||
.primary-btn:disabled { opacity: .5; cursor: not-allowed; }
|
||||
.bt-kpi-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 12px 0; }
|
||||
.bt-kpi { background: rgba(255,255,255,.03); border: 1px solid var(--line-bright); border-radius: 8px; padding: 12px; }
|
||||
.bt-kpi span { display: block; font-size: 11px; color: var(--faint); margin-bottom: 6px; }
|
||||
.bt-kpi strong { font-size: 15px; font-family: 'DM Mono', monospace; }
|
||||
.bt-meta { margin: 4px 0 10px; font-size: 11px; }
|
||||
.bt-holdings { margin-top: 8px; font-size: 12px; color: var(--text-2); display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
|
||||
.bt-history { margin-top: 20px; }
|
||||
.bt-history .source-table td { font-size: 12px; padding: 6px 8px; }
|
||||
|
||||
.thesis-list { display: flex; flex-direction: column; gap: 10px; margin: 12px 0; }
|
||||
.thesis-row { display: flex; gap: 10px; align-items: baseline; padding-bottom: 8px; border-bottom: 1px solid var(--line-weak, rgba(255,255,255,.05)); }
|
||||
.thesis-theme { min-width: 130px; color: var(--accent); }
|
||||
|
||||
Reference in New Issue
Block a user