feat: dashboard — last-evaluation per strategy + order timestamps#169
Merged
Conversation
Surfaces PR #168's last_eval_ms/last_asof_ms per unit (Strategies table's new Last eval column) and the store's order ts stamp on every order row (Orders page + Overview's open-orders table gain a Time column, mirroring the Fills table), so the dashboard finally answers "when did this happen".
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
StrategyStatus(and/api/strategies) now carrieslast_eval_ts(wall-clock of the last tick attempt) andlast_asof_ts(as-of of the last completed evaluation), read off PR fix: daemon tick performance — freshness gate + off-loop data loads #168'sStrategyRunner/PortfolioRunner.last_eval_ms/last_asof_msthrough the unit's runner. The Strategies table gains a Last eval column: relative time in the cell ("3m ago"), with the absolute evaluation instant and the as-of data date intitle. Muted—before the first tick. Skipped on the Overview KPI rows (/api/kpidoesn't carry these fields and widening it is out of scope for this PR)./api/orders, bothhistory=trueand open) now carriests(epoch ms, already the store's unit — no conversion needed). History rows read it straight off the store'stscolumn (a newSqliteStore.order_ts_map()bulk read — the domainOrderitself carries nots); open-order rows (sourced from the live router, which also carries no timestamp) look the sameclient_order_idup in the unit's store,nullwhen not found. The Orders page's Orders table and the Overview's open-orders table both gain a Time column, mirroring the Fills table's exact formatting (absoluteYYYY-MM-DD HH:mm:ss, relative time intitle); order history now renders most-recent-first (mirroring how Fills already does).Where
tscomes fromNot the domain
Order(it carries no timestamp) and not a per-row store lookup for history — a newSqliteStore.order_ts_map()(client_order_id -> ts, one query) feeds bothorder_history()andopen_orders()via a newStrategySupervisor._order_ts_map_of(unit)helper that mirrors_stored_fills_of's dual read path (flush + read the live store when running, else a store opened at the unit'sdb_path).Test plan
python -m pytest— 1201 passed, 9 deselectedruff check trading_bot/— cleanruff format --check trading_bot/— cleanmypy trading_bot/— clean/api/strategieslast_eval_ts/last_asof_ts null-before/set-after-tick;/api/ordershistory + open rows carry the rightts(incl. a "never persisted" id -> null);SqliteStore.order_ts_map()unit test; template smoke tests for the new column headersTestClientagainst a seeded paper supervisor (with and without a configured store) thatts/last_eval_ts/last_asof_tspopulate correctly🤖 Generated with Claude Code