Skip to content

feat(admin): trace detail in the Backtest panel's shape - #644

Merged
MrParamecium merged 2 commits into
mainfrom
feat/admin-trace-backtest-layout
Oct 16, 2026
Merged

MrParamecium merged 2 commits into
mainfrom
feat/admin-trace-backtest-layout

Conversation

@MrParamecium

Copy link
Copy Markdown
Collaborator

Summary

The admin trace page now follows the Backtest panel's layout: run config on the left, the chart with benchmarks and the comparison table in the middle, the trading log on the right, and the timeline below the table. The timeline and the trading log no longer repeat each other.

Backend

  • New GET /api/admin/traces/{trace_id}/chart-data (admin-only). It returns the same payload as /api/backtest/{run_id}/chart-data (agent, DJIA, Nasdaq-100, stored Buy & Hold) and uses the same builder and market-hour filter. The run is looked up by the trace's exact run ID across owners. When a run has no stored equity, the endpoint answers available: false, and the chart falls back to the decision snapshots.

Frontend

  • Chart and comparison: multiple series, a legend that toggles series, 1D/1W/ALL ranges, and yellow markers on trade decisions. The table reuses BacktestComparison (now loaded on /admin) for its columns and Best values. Sharpe is left out until the engine computes it with its interval (2026-10-14 direction).
  • Timeline shows the process only: one row per step, with consecutive holds and setup steps folded into one row. Filters are All / Errors. Each event shows its type, tool, status, and duration, and the JSON is collapsible. Symbols and reasoning no longer appear here. A trade row shows N orders (x filled, y rejected) · duration and has a button that jumps to its orders.
  • Trading log: orders are grouped by decision and a shared reason is printed once. Rejected orders are listed with their reason. A filter selects All / Buys / Sells / Rejected.
  • Navigation: jumps work both ways with a highlight, between timeline rows, log groups, and chart markers. A sticky ← Agent traces / ← User analytics button follows where the admin came from, and Esc goes back as well.

Testing

  • New test_admin_trace_chart_data.py: exact-run series, unavailable states, 404, and the admin dependency.
  • test_admin_traces_frontend.py was updated for the new rendering: the timeline never shows symbols or reasoning, reasons in the log are grouped, quiet rows fold, the Errors filter keeps a failed trade, and the Back target follows the entry point. The tests that pin script and CSS versions were bumped.
  • Admin, trace, and composition suites: 167 passed, 1 skipped.
  • Full backend suite: 6856 passed, 2 failed. The 2 failures (backtesting/test_indicator_lookahead.py::test_fallbacks_reproduce_the_library_once_a_window_is_full[missing|exception]) also fail on unmodified main in my environment, and this PR does not touch that code.
  • Manual check on a local server with a seeded trace and real Yahoo benchmarks: three series rendered, the comparison table, both filters, both jump directions, ranges, legend toggles, and Esc going back to the list. The console showed no errors.

Not in this PR

  • Sharpe in the comparison table, which waits for the engine.
  • Buy & Hold appears only when the run stored a paired baseline. This matches the Backtest panel.

🤖 Generated with Claude Code

The trace page now reads like the Backtest panel: run config on the left,
the chart with its benchmarks and comparison table in the middle, the
trading log on the right, and the timeline below the table.

- New GET /api/admin/traces/{id}/chart-data: the same chart payload the
  Backtest panel uses (agent, DJIA, Nasdaq-100, stored Buy & Hold), looked
  up by the trace's exact run across owners. A run with no stored equity
  answers available: false, and the chart falls back to decision snapshots.
- Chart and comparison reuse BacktestComparison for columns and Best.
  Sharpe stays out until the engine computes it (2026-10-14 direction).
- Timeline shows the process only: one row per step, holds and setup folded,
  All / Errors filters, tool and failure status per event. Symbols and
  reasoning live in the trading log alone; a trade row links to its orders.
- Trading log groups orders by decision, prints a shared reason once, lists
  rejected orders, and filters by side or rejection.
- Two-way jumps with a highlight between timeline rows, log groups and chart
  markers; a sticky Back button that follows the entry point, and Esc.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@vercel

vercel Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
agentic-trading-lab Ready Ready Preview Oct 16, 2026 12:42pm UTC

@MrParamecium

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-16T12:30:32.535126Z 2817038 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2817038ddc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +5 to +7
// Bars per US session at hourly cadence; the range buttons count bars, not
// calendar time, because the x axis skips closed hours like Backtest's.
const RANGE_BARS = { '1D': 7, '1W': 35, ALL: Infinity };

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Derive chart ranges from timestamps instead of fixed bar counts

For current Alpaca runs, the backtest engine records equity at the 5-minute valuation cadence, so slicing the last 7 or 35 array entries makes the controls display roughly 35 minutes and 175 minutes rather than the advertised 1D and 1W periods. The same constants are also unsuitable for markets with different session lengths; calculate the cutoff from the supplied timestamps and market sessions instead of assuming seven hourly bars per day.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 73ecb52. Ranges now count the trading days present in the series (1D = last session, 1W = last 5 sessions) instead of fixed bar counts, so 5-minute runs and other session lengths work. Covered by test_chart_ranges_count_trading_days_not_bars (78 bars/session).

Comment thread dashboard/frontend/js/admin-traces.js Outdated
Comment on lines +633 to +635
if (envelope.status !== state.chartStatus) {
state.chartData = await loadChartData(traceId);
state.chartStatus = envelope.status;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate the poll before updating shared chart state

When a running trace finishes while the administrator navigates to another trace, this poll awaits the old trace's chart request and writes its result into global state before checking seq and state.traceId. If the new trace has already loaded, the stale response can overwrite its chartData and chartStatus, causing a later rerender or poll to show the previous run's comparison chart. Keep the loaded chart data local until the current-request check passes.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 73ecb52. The poll now keeps the chart response local and writes chartData/chartStatus only after the seq / traceId check passes. test_a_stale_poll_does_not_write_its_chart_into_the_next_trace holds the old trace’s chart request open across a navigation; it fails on the previous code (shows the old run) and passes now.

Codex review on #644:

- 1D/1W counted 7 and 35 bars, which assumed hourly bars. A 5-minute
  Alpaca run showed about 35 minutes for "1D". Ranges now count the trading
  days present in the series, so any cadence or session length works.
- A poll for a trace the admin had left wrote that trace's chart into
  shared state before the current-request check. A late response could then
  replace the next trace's comparison chart. The response is now held
  locally until the check passes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@MrParamecium
MrParamecium merged commit 0cf397c into main Oct 16, 2026
8 checks passed

This branch was successfully deployed

1 active deployment
Preview — 73ecb52f Deployed Oct 16, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant