Changelog
Notable changes to the ByteTree API’s public contract.
2026-06-12 — BYT-353: Global Trends universe is global-trends-200 on the MCP surface; sector now natively defined
The Global Trends universe key in grouping data changed from globalTrends to
global-trends-200, aligning the MCP tool layer’s vocabulary with the universe slugs
used across the REST API. At the same time, Global Trends gained its own sector
dimension config, so sector no longer falls back to default.
What changed
- Grouping slugs returned by
list_grouping_configsand accepted bygroupingfilters readglobal-trends-200/<dimension>(e.g.global-trends-200/region). get_group_metricstakesuniverse: "global-trends-200".- Global Trends now defines region, sector, and industry; only type and country fall
back to
default.
Compatibility
Breaking for MCP clients holding the old key: globalTrends/* slugs and
universe: "globalTrends" no longer match any data — re-run
list_grouping_configs to refresh. On the REST
surface, which already speaks the customer universe slugs, the only visible change is
global-trends-200/sector now resolving to Global Trends’ own config rather than
returning the macro fallback (no fallback: true) — see Universes.
2026-06-12 — splits endpoints withdrawn from the public API
GET /api/splits and GET /api/splits/:symbol are no longer part of the public API
surface — they have moved to ByteTree’s internal operations layer, and their
documentation pages have been retired.
Why consumers don’t need them
All public OHLCV is split-adjusted by default — the splits ledger remains the
internal input that drives the adjustment, so charts, scores, and returns are unaffected
by corporate actions without any consumer-side handling. See Data Model
for how the adjustment works and ?raw=true on
GET /api/prices/:symbol for the forensic raw view.
Compatibility
Breaking for consumers of the two splits endpoints: requests to these paths now return
401. All other endpoints are unaffected.
2026-06-10 — BYT-337: API-key authentication is live
Key enforcement is now in force. Every documented endpoint
requires an API key — sent as Authorization: Bearer <key> — with one exception:
GET /api/health stays open as a liveness check. The Authentication
page documents the full model.
What changed
- Unauthenticated requests to protected endpoints return
401with the standard{ "error": "<message>" }envelope. - Every key carries a two-dimensional scope:
universes[](which universes it may read) andcapability(view|api+mcp— programmatic access requiresapi+mcp). - A valid key requesting a universe outside its scope receives
403; list endpoints return only in-scope rows. - Universe paths take the customer universe slugs (
macro,public-50, …) — see Universes for the vocabulary.
Compatibility
Breaking for keyless consumers: all reads except GET /api/health now require a key.
Obtain a key through your ByteTree.io account and send it as a bearer token — no other
request changes are needed.
2026-05-26 — BYT-327: ByteTree MCP docs refresh — naming convention, 90-day series default, 800 KB response guard
The public ByteTree MCP documentation gets a clarity pass on three already-shipped behaviours. No engine or MCP behaviour change — this is a docs-only update.
What’s clearer now
- Weekly / Daily naming convention. Customer-facing prose uses Weekly and Daily as the canonical labels for the two ByteTrend arcs; the wire-format suffixes
…200wand…30dappear as code references alongside the human labels (sobyteTrendCapr200wis the Weekly CAPR ByteTrend score,byteTrendCapr30dis the Daily CAPR ByteTrend score, and so on). See the naming-convention callout on the Concepts page. - 90-day series default.
get_metrics_seriesandget_pricesdefault to a 90-day window ending today when neitherfromnortois supplied — surfaced explicitly in the Tool Reference for both tools, in their parameter tables, and in the Overview’s response-size discipline section. - 800 KB response guard. The tool layer caps results at ~800 KB and returns an explicit error with narrowing guidance past the cap (rather than silently truncating). The Overview frames it as a server-published convention — surfaced via the MCP
instructionsfield at initialization — so connected agents adapt without needing to read this page first.
Compatibility
Documentation-only update. No engine or MCP behaviour change.
2026-05-22 — BYT-321: weekly rolling high/low window moves 30-week → 20-week
The four persisted weekly rolling high/low metrics move from a 30-week to a 20-week window and are renamed accordingly:
localMax30w → localMax20w, localMin30w → localMin20w, caprMax30w → caprMax20w, caprMin30w → caprMin20w.
What changed
- The weekly raw high/low fields are renamed
…30w→…20won Latest Metrics and Metrics Time-Series. - The old 30-week raw high/low fields are removed from the API surface.
- The
%dev-from-30-week deviation fields (devFromLocalHigh30w,devFromLocalLow30w,devFromCaprHigh30w,devFromCaprLow30w) are unchanged — they keep their 30-week basis and continue to drive trend-regime classification.
Compatibility
Breaking for consumers that read the weekly raw high/low fields by name: update …30w → …20w. The deviation fields, all daily windows (…20d / …30d), and the 200-week entries are unaffected.
2026-05-08 — BYT-285: documenting /api/fx/:symbol/prices
The canonical close-only FX price series endpoint shipped under BYT-281 is now documented. See the endpoint page.
Why now
BYT-278’s polymorphic-FX docs cutover deliberately scoped to BYT-274’s veneer surface and skipped the dedicated FX price route. This entry closes that doc gap.
Shape
GET /api/fx/:symbol/prices returns { symbol, count, data: [{ date, close }, ...] } with optional from / to ISO date filters. Close-only by design — FX is conventionally rendered as line series and the endpoint reflects that. 404 when the symbol has no FX records.
The polymorphic /api/prices/:symbol returns the same shape for FX symbols; the new dedicated route exists for FX-only consumers that want a zero-ambiguity surface within /api/fx/*.
Compatibility
Documentation-only update. No engine or API behaviour change.
2026-05-07 — BYT-299: trend-regime transition event log
A new public, no-auth endpoint GET /api/metrics/regime-transitions returning the cross-asset event log of trend-regime changes. See the endpoint page.
What’s new
- Filter by
window(200w-CAPR,200w-Local,30d-CAPR,30d-Local), targetregime,direction(into/outOf/any), date range, and the standard asset filter set (type,status,sector,q, universe group filters). - Per-row
metricsAtTransitionsnapshot, with the included keys controllable viafields(default:closeUsd, byteTrendCapr200w, byteTrendCapr30d, returnUsd1M, marketCapUsd, sharpe52w). 200w-CAPRrows carry the confirmation-lag tripletrendAgeAtTransition/confirmedTransitionDate/pendingStartDate; the three raw windows omit those fields entirely.- 5001-row short-circuit returns
400to keep the cap honest.type=fxis rejected. - Backs the public ByteTree MCP’s
get_regime_transitionstool.
Compatibility
Additive. No effect on existing endpoints.
2026-05-07 — BYT-298: cross-sectional metric distribution endpoint
A new public, no-auth endpoint GET /api/metrics/distribution returning per-timestep summary statistics (and, where applicable, histograms) of any allow-listed metric across the asset population. See the endpoint page.
What’s new
- 40-metric allow-list — the four ByteTrend score variants,
trendAge200w, plus 35 continuous metrics (returns, Sharpe, dollar volume, market cap, MA deviations, etc.). frequencyofdaily,weekly, ormonthly(defaultweekly);fromis required,todefaults to today.- Bucket-vs-percentile branching: discrete-score metrics emit a six-key
bucket-discretehistogram (0..5, zeros included);trendAge200wemits a six-keybucket-rangehistogram (lower bounds0,5,30,90,365,1825); continuous metrics emitstatsonly withmean,median,p25,p75,p90. - Standard asset filters (
type,status,sector,q, universe group filters). - Projected-rows cap at 5000;
type=fxis rejected. - Backs the public ByteTree MCP’s
get_metric_distributiontool.
Compatibility
Additive. No effect on existing endpoints.
2026-05-07 — BYT-297: dataset-overview endpoint /api/summary
A new public, no-auth endpoint that returns a single-screen dataset overview — asset counts grouped by (type, status), per-type PriceData date envelopes, and an FX-collection summary. See the endpoint page.
What’s new
GET /api/summary— purpose-built for tools that need a “what does this dataset look like?” answer in one round-trip without unwinding to the symbol level.- Backs the public ByteTree MCP’s
summarise_datasettool. - Standard
?format=json|toon|csvsupport. - 60-second public cache (
Cache-Control: public, max-age=60);generatedAtechoes the recompute moment within the window.
Compatibility
Additive. No effect on existing endpoints.
2026-05-05 — BYT-283: split-adjusted OHLCV by default, raw access via opt-in
/api/prices/:symbol now returns split-adjusted OHLCV by default — open, high, low, close, and volume are all derived from our own pure-function adjustment of RawPriceData against the internal splits ledger, idempotent and immune to upstream retroactive rewrites. The previous “raw close + sidecar metadata.rawClose” pattern is replaced by a clean toggle.
What changed
GET /api/prices/:symbol— full OHLCV is split-adjusted by default. Pass?raw=truefor the unmodified market-printed values (forensic mode). See the endpoint page.GET /api/prices— list-formclose(and the rest of OHLCV) is split-adjusted. There is no list-level raw toggle; use the symbol endpoint when raw is needed./api/metrics/*closeUsd,capr,marketCapUsd— flipped from raw to split-adjusted semantics so quoted-state values match the basis used by every time-series metric.- New raw-access fields on
/api/metrics/*—closeRawUsd,caprRaw,marketCapRawUsdexpose the same trio on raw close.
Three-layer data model
A new conceptual reference page Data Model explains the three layers — RawPriceData (forensic archive, not exposed), PriceData raw fields (the provider’s evolving view, mutable), and own-computed split-adjusted OHLCV (idempotent, default) — and which view a given consumer wants.
FX
FX pairs aren’t subject to splits, so adjusted and raw views are identical. The /api/fx/* namespace and the polymorphic FX rows on /api/assets and /api/metrics therefore expose only the default values.
Compatibility
Breaking semantics for raw consumers. The fields closeUsd, capr, and marketCapUsd previously held raw values; they now hold split-adjusted values. Any consumer that needs the previous raw semantics must migrate to closeRawUsd, caprRaw, or marketCapRawUsd. There are no public consumers as of the cutover.
The OHLCV change on /api/prices/:symbol is also a semantics flip — the field names are unchanged. Consumers that explicitly want raw OHLCV must add ?raw=true.
2026-05-05 — BYT-274: polymorphic FX synthesis on /api/assets and /api/metrics
Asset and metric endpoints now resolve FX-pair symbols through a fallback path so polymorphic consumers (clients iterating across mixed asset types — stocks, crypto, FX) can use a single resolution path.
What changed
GET /api/assets?type=fxreturns FX pairs synthesised from rate data, with asset-only fields (isin,sector,industry,country,region,mktCap,mktCapUsd)nullandnamerendered in slash form (e.g."EUR/USD"). See Polymorphic FX rows.GET /api/assets/:idfalls back to a synthesised FX row when:idis a recognised FX-pair symbol with no registered Asset. MongoDB-ID lookups are not synthesised. See Polymorphic FX fallback.GET /api/metrics/:symbol/latestandGET /api/metrics/:symbol(series) fall back to FX rate data on PriceData miss, so the same client path resolves any tracked symbol.
Recommended surface for FX-only consumers
A dedicated /api/fx namespace ships alongside the polymorphic veneer as the canonical zero-ambiguity surface for FX score and metric data:
GET /api/fx— list of tracked FX pairs with latest scores and trend regimeGET /api/fx/:symbol— latest computed metrics for a single FX pairGET /api/fx/:symbol/series— daily metric time series for a single FX pair
List-form metrics endpoint
The pre-existing GET /api/metrics/latest (no :symbol) gains a ?type=fx branch that returns FX-pair records derived from rate data. The endpoint returns a symbol-keyed object as data rather than an array — see the endpoint page for the envelope.
Compatibility
Additive. Pre-existing /api/assets and /api/metrics consumers see no change in behaviour for stock, crypto, etf, index, or commodity symbols. The new fx value on ?type= and the FX-symbol fallback paths extend the resolution surface without altering existing rows.
/api/rates, /api/rates/sparklines, and /api/rates/:pair remain scoped to raw OHLC rate data — no scores, no metrics. Consumers wanting computed FX metrics should use /api/fx/*.
2026-05-02 — BYT-268: ByteTrend score bin histograms on GroupMetric
Group metric responses now carry per-variant score histograms — byteTrendBins — so consumers can render distribution shape without re-deriving from the underlying assets list. Surfaces automatically on all three /api/universes read paths.
Field
byteTrendBins is a nested object with one key per ByteTrend score variant:
| Key | Type | Description |
|---|---|---|
local200w | number[6] | Score histogram for Weekly Local — bins[i] = count of assets at score i |
local30d | number[6] | Score histogram for Daily Local |
capr200w | number[6] | Score histogram for Weekly CAPR |
capr30d | number[6] | Score histogram for Daily CAPR |
For each variant, sum(bins) ≤ assetCount — the gap is the number of group members whose score is null (e.g. asset hasn’t accumulated the long window yet).
"byteTrendBins": {
"local200w": [4, 7, 27, 3, 17, 47],
"local30d": [11, 15, 16, 17, 10, 37],
"capr200w": [23, 16, 15, 16, 13, 22],
"capr30d": [40, 10, 18, 11, 4, 23]
}
Endpoints
Visible on every read path that returns GroupMetric rows — see Universe Groups → ByteTrend Score Bins for the canonical field reference.
GET /api/universes/:universeGET /api/universes/:universe/:categoryGET /api/universes/:universe/:category/:group
Compatibility
Additive. The field is omitted (byteTrendBins: undefined) on responses that read pre-existing storage rows — callers should treat absent bins as “not yet populated”, not as zero counts.
Forward-only — backfill caveat
The daily 04:00 UTC group aggregator populates byteTrendBins going forward. GroupMetric rows aggregated before 2026-05-02 do not have the field — including the 2026-05-02 row itself, which was aggregated by the cron that ran before the engine deploy. Two paths to populate stored rows:
- Natural propagation — wait for the next daily aggregator run; that day’s row onwards carries bins.
- Manual re-aggregation — ByteTree operators can rewrite stored rows for a date range on request. Not run by default; full historical backfill is opt-in.
Time-series consumers reading multi-month responses will therefore see byteTrendBins populated only for dates from the cutover forward unless a manual backfill has been run.
2026-05-01 — pagination envelope harmonisation
Consumer-paginated list endpoints now return a richer envelope. GET /api/assets and GET /api/splits add total, limit, and offset alongside the existing count and data. This was the harmonisation pass scoped into BYT-252 that didn’t ship with the original splits cutover; closing the loose end now while the contract is still fresh. (The splits endpoints were later withdrawn from the public API — see the 2026-06-12 entry.)
Envelope
{
"count": 10,
"total": 4287,
"limit": 10,
"offset": 0,
"data": [ /* records on this page */ ]
}
count— length of the returneddataarray (records on this page). Semantics unchanged from the legacy envelope.total— full match count for the same filter, ignoringlimitandoffset. Computed viacountDocumentsin parallel with the paged query — no extra latency on the critical path.limit/offset— echoed input. Consumers paginate by advancingoffsetuntiloffset + count >= total.
See Response Conventions → Paginated list envelope for the canonical reference.
Endpoint changes
GET /api/assets—limitandoffsetquery parameters are now documented (default500, capped at1000;offsetdefaults to0). The endpoint already accepted these inputs; they are now part of the published contract and are echoed in the response.GET /api/splits— addsoffsetas a new query parameter. Previously cap-only vialimit.
Unchanged
GET /api/assets/:id— single-record read, returns{ data: ... }.GET /api/splits/:symbol— single-symbol all-records lookup, intentionally stays on{symbol, count, data}. Split histories are naturally bounded (well under 30 entries per symbol), so pagination would be empty ceremony./api/rates,/api/prices,/api/metrics,/api/universes,/api/currencies— bounded reads, remain on the legacy{count, data}envelope. They will adopt the full envelope if/when they become consumer-driven paginated surfaces.
Compatibility
Additive. Callers that read only count and data are unaffected — the new fields appear alongside.
2026-04-30 — BYT-252: public splits API
Closes the BYT-238 trilogy phase 3. Two new public endpoints expose the corporate-actions data layer that drives adjusted-close computation. (Both were later withdrawn from the public API — see the 2026-06-12 entry.)
Endpoints
GET /api/splits— universe-wide history, date-descending, defaultlimit500, capped at 1000.GET /api/splits/:symbol— per-symbol history, date-descending, no limit.
Data shape
Default projection: symbol, date, numerator, denominator, ratio, source. The ratio field denormalises numerator / denominator for query convenience — reverse splits have ratio < 1. Operations fields (firstSeenAt, confirmedAt, metadata) are hidden by default and opt-in via ?fields=.
Pipeline
A daily 02:00 UTC cron pulls the upstream stock-split calendar over a rolling ±90-day window into a new splits collection. Each ingested split is auto-reconciled against the price-anomaly review queue from BYT-251 phase 2 — a 'likely-split' anomaly within ±3 calendar days of a confirmed split is auto-acknowledged, populating splitId on the anomaly and confirmedAt on the split.
Trilogy completion
- Phase 1 (2026-04-28) — metrics moved to adjusted close.
- Phase 2 (engine-internal) — close-to-close anomaly sensor; no public-API surface.
- Phase 3 (this entry) — corporate-actions feed, sourced from the upstream split calendar.
2026-04-28 — BYT-238 phase 1: adjusted-close backfill, monthly refresh
Time-series metrics (MAs, slopes, rolling highs/lows, ByteTrend scores, deviations, drawdowns, returns, volatility, Sharpe, beta) are now computed on adjusted close instead of raw close. Closes the hidden corruption that unaccounted-for splits introduced into trend computation (the “BKNG-style” failure: a 1-for-6 split or large dividend silently steps the entire historical series, breaking MA crossings, ATH tracking, and drawdown depth).
Rationale
The prices endpoints have always surfaced adjusted close as close (raw close in metadata.rawClose). Metrics computation was reading raw close, which meant any unrecorded split corrupted every windowed metric until the split worked its way out of the longest window. Aligning metrics with the adjustment model the prices endpoints already use means scores and drawdowns survive splits cleanly.
Renamed
| Old | New |
|---|---|
allTimeHighUsd | allTimeHighAdjUsd |
The new name makes the adjustment model explicit. drawdownATH keeps its name; its semantics shift to ”% below adjusted-close all-time high”.
Semantic shift (same keys)
Every time-series metric below — keys, units, and ranges unchanged — is now computed on adjusted close:
- ByteTrend scores:
byteTrendLocal{200w,30d},byteTrendCapr{200w,30d}and all companions (*Rules,change*,trendRegime*,consec*5/0). - Moving averages and slopes: all 8 MAs + 8 slopes.
- Rolling highs/lows: all 14 fields (
*Max20d/30d/30w/200w,*Min20d/30d/30w). - Deviations:
devFrom*MaLong200w,devFrom*High*,devFrom*Low*. - Trend quality:
divergenceLocal/Capr,scoreVelocity5d200w,cumulHighs12w,volumeConfirmation30d. - Risk:
volatility30w,sharpe52w,beta52w,returnVolRatio. - Drawdown:
drawdown52w,drawdownATH,allTimeHighAdjUsd,maxDrawdown30w/52w. - Returns:
returnUsd*,returnFwdUsd*. - Relative strength:
relStrengthRaw*,relStrengthCapped*.
Backtest impact. Historical series for any asset that has split (or paid a large enough dividend to register in the adjustment) will differ from pre-cutover values. Backtests that join pre- and post-2026-04-28 metrics across a split will see a one-time step on the cutover day. Affected today: 211 stocks and 1 index. Commodities and crypto are unaffected — the engine sets adjClose = close for those types, so compute paths remain uniform but values are identical to pre-cutover.
Stayed on raw close
These three fields represent today’s quoted state, not a trend over time:
closeUsd— current USD close.marketCapUsd— current market cap.capr— current USD price ÷ MSCI World close.
Added (infrastructure)
adjClosefield on PriceData — internal compute input, nullable for pre-backfill records (compute readsadjClose ?? close). Not exposed on the public API surface.adjclose-refreshorchestrator stage — monthly cron that refetches full history for stocks/ETFs/indexes, diffs against storedadjClose, writes changes, and triggers per-asset recompute on detected diffs. Catches splits the daily ingest path missed.
Follow-ups
- Phase 2 — close-to-close sensor. Engine-side detection of unexplained close-to-close gaps that suggest an unrecorded split. Engine-internal; no public-API surface.
- Phase 3 — split-calendar cross-ref. Validation against external split-calendar data. See the BYT-252 entry for the public splits API.
2026-04-28 — BYT-241: legacy field cleanup + uniform window-suffix convention
The BYT-240 dual-write window has closed. Legacy field names emitted alongside the canonical BYT-240 surface have been removed, and a uniform window-suffix convention now applies to every window-bearing metric across the API.
Rationale
- One name per field, suffix matches the actual window. Before BYT-241,
localMaShort200wwas actually a 30-week MA (named for the pair it belonged to);localMax30dwas actually a 20-day window per its docs description; the assets endpoint surfacedbyteTrendCapr(unsuffixed) as an alias ofbyteTrendCapr200w. All three patterns are gone. Every window-bearing field now carries the actual window in its identifier —30d,200d,30w,200w— and there is exactly one canonical name per field across every endpoint. - No transitional aliases. Legacy names from BYT-240 are removed outright, not deprecated. New integrations were already advised to use the canonical names from BYT-240’s day one.
- Composite-name exception preserved. ByteTrend score families (
byteTrendLocal200wand friends) and divergence (divergenceLocal/divergenceCapr) keep their pair/architecture names — they identify a score class, not a single-window measurement.
Renamed
Underlying MAs (pair-label sweep — suffix now denotes actual window):
| Old | New |
|---|---|
localMaShort200w | localMaShort30w |
caprMaShort200w | caprMaShort30w |
localMaLong30d | localMaLong200d |
caprMaLong30d | caprMaLong200d |
MA slopes (4 weekly + 4 daily, all newly suffixed to match their underlying MA):
localMaLong200wSlope, localMaShort30wSlope, caprMaLong200wSlope, caprMaShort30wSlope, localMaLong200dSlope, localMaShort30dSlope, caprMaLong200dSlope, caprMaShort30dSlope (was localMaLongSlope, localMaShortSlope, caprMaLongSlope, caprMaShortSlope).
Rolling highs/lows:
| Old | New |
|---|---|
localMax | localMax30w |
localMin | localMin30w |
caprMax | caprMax30w |
caprMin | caprMin30w |
Trend regime / age / pending:
| Old | New |
|---|---|
confirmedRegimeCapr | confirmedRegimeCapr200w |
pendingRegimeCapr | pendingRegimeCapr200w |
pendingRegimeCount | pendingRegimeCount200w |
trendAge | trendAge200w |
Deviations (suffix the long MA they reference):
| Old | New |
|---|---|
devFromLocalMaLong | devFromLocalMaLong200w |
devFromCaprMaLong | devFromCaprMaLong200w |
Other:
| Old | New |
|---|---|
volumeConfirmation | volumeConfirmation30d |
scoreVelocity5d | scoreVelocity5d200w (now tracks byteTrendLocal200w) |
Assets endpoint denormalised fields:
| Old | New |
|---|---|
byteTrendCapr | byteTrendCapr200w |
trendRegimeCapr | trendRegimeCapr200w |
changeCapr | changeCapr200w |
GroupMetrics aggregates: legacy unsuffixed avgByteTrendFast/Local/Capr, medianByteTrendLocal, pctScore{5,0}{Local,Capr} removed; use the suffixed equivalents listed in Universe Groups.
Added
- 20-day rolling high/low set —
localMax20d,localMin20d,caprMax20d,caprMin20d. Used by Daily score’slastTouchMaxrule (recent-extremum tracking). Replaces the dropped legacyfastMax/fastMin. - 30-week CAPR rolling pair —
caprMax30w/caprMin30w(symmetric with the renamedlocalMax30w/localMin30w). - 200-week CAPR rolling high —
caprMax200w(symmetric withlocalMax200w). - Daily MA slopes —
localMaLong200dSlope,localMaShort30dSlope,caprMaLong200dSlope,caprMaShort30dSlope. Previously only weekly MA slopes were emitted. - Pending regime fields documented —
pendingRegimeCapr200wandpendingRegimeCount200wwere already emitted but not previously listed in the docs.
Removed (no replacement)
scoreVelocity1ddivergenceWeekly*(entire VWAP-sampled family — never used by consumers post-VWAP removal)- All BYT-240 transitional alias fields:
byteTrendFast/Local/Capr(unsuffixed) + their*Rulesandchange*companions;consecLocal/Capr 5/0(unsuffixed);trendRegimeLocal/Capr(unsuffixed);byteTrendWeekly{Fast,Local,Capr}+ companions;weekly{Fast,Local,Capr}{MaLong,MaShort,Max,Min};vwap1W/caprVwap1W;fastMaLong/Short,fastMax/Min;localMaLong/Short,caprMaLong/Short(unsuffixed pre-BYT-240 names).
Docs corrections
- The Rolling Highs & Lows description for
localMax30d/localMin30d/caprMax30d/caprMin30dpreviously read “20-day rolling high/low” — corrected to 30-day. The fields are genuinely 30-day (used by Daily score regime classification, matches the daily short MA window). The actual 20-day pair is the newlocalMax20d/localMin20d/caprMax20d/caprMin20d.
Preserved under existing names
byteTrendLocal200w/byteTrendLocal30d/byteTrendCapr200w/byteTrendCapr30dand all their companions (*Rules,change*,consec*5/consec*0,trendRegime*).divergenceLocal/divergenceCapr— kept under their BYT-240 names with Daily−Weekly semantics.
See the BYT-240 entry for the prior cutover.
2026-04-22 — BYT-240: ByteTrend score rename, VWAP removal
Four collision-free ByteTrend scores replace the previous six, naming window into the identifier. The legacy VWAP-weighted weekly infrastructure has been removed.
Rationale
- Collision-free naming. Window (
200wor30d) is baked into the score identifier, removing the ambiguity that produced the “CAPR (Daily)” UI label on what was actually a weekly-window score. - Real Daily CAPR.
byteTrendCapr30dis a net-new score — a true 200d/30d/20d CAPR signal where the previous surface only offered the weekly-windowbyteTrendCapr. - VWAP removal. The VWAP-based weekly overlays were a misstep — they added surface without conceptual clarity.
byteTrendWeekly{Fast,Local,Capr}, their rule/change companions, allweekly*Ma*/weekly*Max/Minoverlays, andvwap1W/caprVwap1Ware gone.
Canonical scores
| Field | UI Label | Windows |
|---|---|---|
byteTrendLocal200w | Local (Weekly) | 200w / 30w / 30w on local close |
byteTrendLocal30d | Local (Daily) | 200d / 30d / 20d on local close |
byteTrendCapr200w | CAPR (Weekly) | 200w / 30w / 30w on CAPR |
byteTrendCapr30d | CAPR (Daily) | 200d / 30d / 20d on CAPR |
Each carries *Rules, change*, trendRegime*, and consec*5/consec*0 companions on the same suffix.
Added
- Four new scores with full companions (rules, changes, regimes, 8 × consec counters)
- Moving-average aliases per window:
localMaLong{200w,30d},localMaShort{200w,30d},caprMaLong{200w,30d},caprMaShort{200w,30d} - 30-day rolling highs/lows:
localMax30d,localMin30d,caprMax30d,caprMin30d - 30-day deviations:
devFromLocalHigh30d,devFromLocalLow30d,devFromCaprHigh30d,devFromCaprLow30d - Group aggregates (16 fields):
avgByteTrend{Local,Capr}{200w,30d},medianByteTrend{Local,Capr}{200w,30d},pctScore{5,0}{Local,Capr}{200w,30d}
Removed
vwap1W,caprVwap1WbyteTrendWeeklyFast,byteTrendWeeklyLocal,byteTrendWeeklyCapr(+ their*Rulesandchange*companions)- Weekly VWAP overlays:
weeklyFastMaLong/Short,weeklyLocalMaLong/Short,weeklyCaprMaLong/Short - Weekly VWAP high/lows:
weeklyFastMax/Min,weeklyLocalMax/Min,weeklyCaprMax/Min
Semantic shift (same keys)
divergenceLocal/divergenceCapr— now Daily − Weekly (was Daily − VWAP-weekly). Keys, units, and range unchanged. Historical series are not directly comparable across the cutover — any backtest that joins pre- and post-2026-04-22 divergence values will see an artificial step.
Migration
The engine dual-wrote canonical and legacy names during the BYT-240 → BYT-241 transition window. Dual-write closed at BYT-241 (2026-04-28); only the canonical names are emitted now. See the BYT-241 entry for the full removal list.