Complete alpha-101 demo — 10 alphas, catalog stream, consolidated dashboards#29
Merged
Conversation
Closes #27. Extends the existing alpha-101 app to also implement WorldQuant Alpha #2: -1 * correlation(rank(delta(log(volume), 2)), rank((close - open) / open), 6) Shared pipeline changes (affecting Alpha #1 too, verified non-breaking): - random_market_data gains a `volume` field (uniform [1, 100] per tick). - market_data + mv_market_data plumb volume through. - v_bars now exposes `open` (earliest price in bucket), `close` (latest price), and `volume` (sum of tick volumes). Alpha #1's downstream chain works unchanged. New views for Alpha #2: - v_features_2: per-stock per-bucket intraday_ret = (close - open) / open, log_vol_delta_2 = log(volume_t) - log(volume_{t-2}), and bucket-to-bucket returns (plumbed for the backtest). - v_ranks_2: per-bucket cross-sectional rank of BOTH features (using the same mean-zero rank pattern as Alpha #1, computed once per bucket via group_array + array_sort + array_first_index for each feature). - v_alpha_2: per-stock 6-bucket rolling Pearson correlation between the two rank series, negated. Manual covariance / variance computation via array_reduce('avg', array_map(...)) over lags(_, 0, 5). - v_backtest_2: same shape as v_backtest, branched on `strategy` config (linear | sign). Two new dashboards: - "Alpha #2 Live" (volume per bucket, leaderboard, alpha over time) - "Alpha #2 Backtest" (t-stat tile, summary, per-stock, portfolio PnL) End-to-end live-verified: install of the rebuilt .tpapp produces both alphas; v_alpha_2 values bounded in [-1, 1]; v_backtest_2 emits sensible pnl on each (time, stock) row. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closed
…ources Rename so alpha-specific views are clearly tagged and shared pipeline pieces stay unsuffixed: v_features → v_features_alpha_1 v_ts_argmax_5 → v_ts_argmax_5_alpha_1 v_backtest → v_backtest_alpha_1 v_features_2 → v_features_alpha_2 v_ranks_2 → v_ranks_alpha_2 v_backtest_2 → v_backtest_alpha_2 Unchanged (shared or already-suffixed): random_market_data, market_data, mv_market_data, v_bars, v_alpha_1, v_alpha_2 DDL filenames updated to match the view names. All cross-references (FROM clauses, manifest resource list, dashboard viz_content) updated to the new names. Verified end-to-end with a fresh .tpapp install: 9 views provisioned with the expected names, both alphas emit valid values, both backtest layers emit pnl. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
With consistent _alpha_N naming, the dashboard SQL can template the
alpha suffix at runtime. Each dashboard now has a single "Alpha"
dropdown (values: 1, 2) writing to `filter_alpha`, and the panel
queries reference views as `alpha_101.v_alpha_{{filter_alpha}}` and
`alpha_101.v_backtest_alpha_{{filter_alpha}}`.
Before: 4 dashboards (Realtime Alpha 101, Alpha #1 Backtest, Alpha #2
Live, Alpha #2 Backtest).
After: 2 dashboards (Realtime Alpha 101, Alpha 101 Backtest), each
serving both alphas via the dropdown.
The Realtime dashboard also shows price AND volume side-by-side
(both filtered by the stock dropdown), since those are shared
market-data views that don't change between alphas.
Adding Alpha #N now requires only:
- a new DDL chain (v_features_alpha_N, ..., v_backtest_alpha_N)
- appending "N" to the Alpha dropdown's inlineValues
No new dashboard files. Verified end-to-end: 2 dashboards register
with 6 panels each; switching the Alpha dropdown updates the
leaderboard / alpha-over-time / all backtest panels in place.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Timeplus dashboard UI persisted the rendered value of the
inlineValues template (literal "STOCK_0,STOCK_1,STOCK_2") instead
of the template itself, which broke auto-scaling to non-default
num_stocks. Restore the original:
"[[ range $i, $_ := until (int .Config.num_stocks) ]]
[[ if $i ]],[[ end ]]STOCK_[[ $i ]][[ end ]]"
Verified by installing with config[num_stocks]=5 — the rendered
inlineValues correctly resolves to STOCK_0,STOCK_1,STOCK_2,STOCK_3,STOCK_4.
UI-side improvements kept as-is (these are real fixes, not noise):
- Live Volume + Portfolio PnL column charts: updateMode/Key changed
from "time" to "all" (cleaner streaming render for column charts).
- Alpha selector in backtest dashboard: position shifted from x=0
to x=2 (layout polish).
Also save the broader gotcha to the skill: dashboard UI edits can
silently render-and-persist template expressions, replacing the
authored template with its evaluated string.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When a Timeplus user opens a dashboard installed from a .tpapp via the UI and re-saves a layout tweak, any [[ ]] Sprig expressions in the JSON (e.g. an inlineValues template referencing .Config.*) get replaced by their rendered string. Auto-scaling behavior breaks silently on next install with a different config. Hit this on the alpha-101 stock selector after the user moved a panel. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Closes #27.
Summary
Completes the alpha-101 demo with 10 WorldQuant 101 alphas, a catalog mutable stream describing each one, and two consolidated dashboards (Live + Backtest) with an
Alphadropdown that switches between all 10 signals.What ships
1. Ten alphas — one per streaming-SQL pattern
lagswindow +signed_power+array_first_indexfor ts_argmax + cross-sectional rank viagroup_array + array_sort + ARRAY JOIN array_enumeratearray_count(x -> x <= current, lags(_, 0, 8))array_min/array_maxoverlags(_, 0, 4)+multi_ifnested conditionalslags(_, 1, 1),sign, multiplication; tiny SQL footprintdeltaof correlation × cross-sectional rank of rolling stddevv_bars(sum(price*volume) / sum(volume)) + intra-bar nonlinear2. Shared pipeline
Each alpha branch:
Simpler alphas (#12, #41, #54) skip the features and ranks layers.
3.
alpha_catalogmutable streamInstall-time seed via a single
INSERT INTO ... VALUES (…)(registered astype: systemin the manifest). After install,SELECT * FROM alpha_101.alpha_catalogreturns one row per alpha with its name, short description, and original WorldQuant formula. Mutable-stream semantics mean re-inserting on the samealpha_nameupserts in place — the catalog is editable without rebuilding.4. Consolidated dashboards
Two dashboards, each with an Alpha dropdown (
1, 2, 3, 4, 6, 9, 12, 22, 41, 54) that templates the suffix into panel queries —FROM alpha_101.v_alpha_{{filter_alpha}}resolves at render time:Realtime Alpha 101 (6 panels)
alpha_catalog, shows the description and equation of the chosen alphaAlpha 101 Backtest (6 panels)
Adding Alpha #N from here: a new DDL chain (
v_features_alpha_N → … → v_backtest_alpha_N), append,Nto each dropdown'sinlineValues, and INSERT a row into the catalog. No new dashboard files.5. Naming convention
6. Synthetic-data caveat (documented in README)
Alphas operating on raw price levels (
#3rank(open),#4rank(low),#6correlation(open, …)) are degenerate on this synthetic feed because per-stock price bands never overlap — STOCK_0'slowis always lowest, STOCK_2's is always highest, so cross-sectional ranks of price levels are constants. The math is correct, the alphas are honest about having no information to extract. Alphas operating on returns, deltas, or intra-bar quantities (#1, #2, #9, #12, #22, #41, #54) produce meaningful varying signals.7. Bundled skill / docs improvements
skill/SKILL.mdCommon Errors gained four entries during this PR:colorsetWHEREfilters must usetime(not_tp_time) on tumble-derived views#truncates unquoted strings in manifest valuesnullifis rejected; usenull_ifVerified end-to-end
.tpappinstallpnlalpha_catalogpopulated on installSELECT * FROM alpha_catalogWHERE alpha_name = 'alpha_{{filter_alpha}}'config[num_stocks]=5→STOCK_0..STOCK_4Alphadropdown switches all panelsTest plan
make build && make installwith default configmake installwithconfig[num_stocks]=5 config[bucket]=5s config[strategy]=signSELECT alpha_name, description, equation FROM alpha_101.alpha_catalogreturns all 10 rows🤖 Generated with Claude Code