ByteTrend Monitor
ByteTrend Monitor
GET /api/monitor A daily health check of one asset type in the bytetrend universe, in one response: stocks (the default), ETFs, crypto or commodities. It shows how many members are in each trend regime, which ones moved to a top or bottom score today, how the type’s groups compare (for stocks: sectors, countries and industries), and, for stocks, where the strongest and weakest sit. You also get a table with all four scores for every member.
The Monitor is computed once a day, after the daily run, and this endpoint returns the latest one. To see how any of its group figures has moved over time, use Monitor History.
Example
curl --compressed https://api.bytetree.io/api/monitor \
-H "Authorization: Bearer YOUR_API_KEY" const res = await fetch("https://api.bytetree.io/api/monitor", {
headers: { "Authorization": "Bearer YOUR_API_KEY" },
});
const body = await res.json(); import requests
res = requests.get(
"https://api.bytetree.io/api/monitor",
headers={"Authorization": "Bearer YOUR_API_KEY"},
)
body = res.json() 200 Abridged: one variant, first entries, rounded {
"contractVersion": 3,
"asOf": "2026-10-07",
"generatedAt": "2026-10-08T10:20:22.769Z",
"universe": "bytetrend",
"type": "stock",
"meta": { "candidates": 4093, "members": 4004, "stale": 313, "dropped": 89, "livenessDays": 7, "intradaySkipped": 0 },
"variants": {
"capr200w": {
"summary": {
"n": 3832, "avg": 1.6863, "bins": [1357, 679, 578, 588, 287, 343],
"p5": 0.0895, "p0": 0.3541,
"leading": 19, "emerging": 21, "weakening": 117, "bear": 340,
"highs": 40, "lows": 457, "ups": 108, "downs": 234
},
"highs": {
"count": 40,
"rows": [
{
"symbol": "MSFT", "name": "Microsoft Corporation",
"country": "United States", "sector": "Technology",
"industry": "Software - Infrastructure", "mktCapUsd": 3935587040000,
"return1D": 0.0009, "score": 4, "regime": "Emerging Trend", "change": 0, "asOf": "2026-10-07"
}
]
},
"lows": { "count": 457, "rows": ["..."] },
"new5": { "count": 14, "rows": ["..."] },
"new0": { "count": 51, "rows": ["..."] },
"dims": [
{ "key": "sector", "label": "Sector", "minN": 1 },
{ "key": "country", "label": "Country", "minN": 20 },
{ "key": "industry", "label": "Industry", "minN": 10 }
],
"groups": {
"sector": [
{ "key": "Financial Services", "n": 659, "n5": 98, "n0": 175, "p5": 0.1487, "p0": 0.2656, "avg": 2.0728, "avgChg": -0.0926 }
],
"country": [
{ "key": "United States", "n": 1506, "n5": 130, "n0": 516, "p5": 0.0863, "p0": 0.3426, "avg": 1.6919, "avgChg": -0.0392 }
],
"industry": [
{ "key": "Banks - Regional", "sector": "Financial Services", "n": 265, "n5": 42, "n0": 74, "p5": 0.1585, "p0": 0.2792, "avg": 2.0943, "avgChg": -0.1358 }
]
},
"sizeVol": {
"cuts": [0.2933, 0.4402],
"cells": {
"All|All": { "n": 3832, "avg": 1.6863 },
"All|High": { "n": 1220, "avg": 2.0877 },
"All|Low": { "n": 1312, "avg": 1.314 },
"...": "..."
}
},
"sunburst": {
"5": [
{
"country": "United States", "n": 130, "base": 1506,
"sectors": [
{ "sector": "Healthcare", "n": 35, "base": 294 },
{ "sector": "Technology", "n": 32, "base": 208 }
]
}
],
"0": ["..."]
},
"regimes": { "Leading": ["..."], "Bear": ["..."] },
"extremes": {
"scored": 3832,
"regions": [
{
"region": "North America", "n5": 141, "n0": 571, "base": 1688,
"sectors": [
{ "sector": "Healthcare", "n5": 38, "n0": 96, "base": 318 },
{ "sector": "Technology", "n5": 34, "n0": 71, "base": 236 }
]
}
],
"sectors": [
{ "sector": "Financial Services", "n5": 98, "n0": 175, "base": 659 }
]
},
"sectors": "… deprecated copy of groups.sector",
"countries": "… deprecated copy of groups.country",
"industries": "… deprecated copy of groups.industry"
},
"capr30d": "...",
"local200w": "...",
"local30d": "..."
},
"stocks": [
{
"symbol": "000001.SZ", "name": "Ping An Bank Co., Ltd.", "country": "China",
"sector": "Financial Services", "industry": "Banks - Regional",
"mktCapUsd": 33438727364.75, "volatility30w": 0.1748, "return1D": 0.0177,
"return3M": 0.1386, "return12M": 0.0753,
"asOf": "2026-09-30", "stale": true,
"capr200w": { "score": 3, "regime": "Neutral", "change": 0, "consec5": 0, "consec0": 0, "extLong": -0.1714, "extShort": 0.0183 },
"capr30d": { "score": 3, "regime": "Neutral", "change": 0, "consec5": 0, "consec0": 0, "extLong": 0.0073, "extShort": 0.0031 },
"local200w": { "score": 5, "regime": "Neutral", "change": 0, "consec5": 24, "consec0": 0, "extLong": 0.101, "extShort": 0.043 },
"local30d": { "score": 3, "regime": "Neutral", "change": 0, "consec5": 0, "consec0": 0, "extLong": 0.0387, "extShort": -0.0067 }
}
]
} The crypto snapshot
curl --compressed "https://api.bytetree.io/api/monitor?type=crypto" \
-H "Authorization: Bearer YOUR_API_KEY" The commodity snapshot as TOON
curl --compressed "https://api.bytetree.io/api/monitor?type=commodity&format=toon" \
-H "Authorization: Bearer YOUR_API_KEY" Query Parameters
Any parameter not listed here returns 400.
| Name | Type | Required | Description |
|---|---|---|---|
type |
string |
No | The asset type: stock (default), etf, crypto or commodity. An unrecognised value returns 400. See Asset types |
format |
string |
No | Response format: json (default) or toon. csv is not available here because the response holds several tables. See Formats |
Size and caching
The response is large: about 2.4 MB for the stock Monitor, which covers around 4,000 stocks. Send Accept-Encoding: gzip (the --compressed flag in the examples), which shrinks it about seven times, to roughly 340 KB. The Monitor changes once a day, so responses are sent with Cache-Control: private, max-age=300. There is no need to poll it more often than that.
Asset types
Every type returns the same response shape. What differs is which groupings the type has, how its stock lists are ordered, and whether the size × volatility grid, the sunburst, the regime map and the winners and losers matrix are filled in.
type |
Groupings (dims) |
Member lists ordered by | sizeVol, sunburst, regimes, extremes |
|---|---|---|---|
stock (default) |
sector; country (20 or more members); industry (10 or more members; each row also carries its sector; the catch-all Other is never listed) |
Market cap, largest first | Filled in |
etf |
assetClass, exposureRegion, exposureSector: what the fund holds, each listing groups with 5 or more members. The values come from each fund’s etf object on its asset record |
Largest first, by assets under management once a fund is classified (then mktCapUsd holds the fund’s AUM), otherwise by the provider’s market cap |
null |
crypto |
capTier: Large (over $10B), Mid ($1B up to and including $10B), Small ($100M or more, under $1B), Micro (above $0, under $100M). A market cap of null or 0 puts the asset in no tier |
Market cap, largest first | null |
commodity |
futuresGroup: Agriculture & livestock, Metals, Energy, Rates, Stock indices, Dollar |
Largest score change first, by size whatever its direction (a change of -3 comes before +1), then the day’s return, highest first (null last), then symbol. Commodities have no market cap, so ignore mktCapUsd |
null |
On bytetrend.io, crypto is labelled Digital and commodity is labelled Futures. The parameter values are always crypto and commodity.
A member with no value for a grouping (an unclassified ETF, a crypto asset with no market cap, a commodity with no futures group) is left out of that grouping’s groups, but still counts in the summary and the member lists.
A type’s snapshot appears once it has been computed. Until then, asking for that type returns 404 (see Errors).
Who is in it
Members are the active assets of the requested type in the bytetrend universe, with complete data from within the last 7 days, measured back from the latest close. An asset with nothing in that window is left out. A data row dated the same day the Monitor is computed may be incomplete, so it is skipped and the previous complete row is used. Crypto has no row dated the UTC day the Monitor is computed, so its asOf is normally the day before (UTC); other types’ asOf is their latest close, which can be earlier (a stock snapshot computed on a Sunday covers Friday). meta shows how the membership was counted.
A stale member is one whose market did not trade on asOf, for example because of a local holiday. It keeps its latest scores, but its change is 0, so it never counts towards ups, downs, new5 or new0.
Response
Top level
| Field | Type | Description |
|---|---|---|
contractVersion |
number |
The version of this response shape, currently 3. A snapshot computed before version 3 reports 2, and its member table rows have no return3M, return12M, consec5, consec0, extLong or extShort keys at all (they are left out, not null) |
asOf |
string or null |
The latest close the snapshot covers, YYYY-MM-DD |
generatedAt |
string or null |
When the snapshot was computed (ISO 8601 timestamp) |
universe |
string or null |
"bytetrend" |
type |
string |
The asset type you asked for |
meta |
object |
How the membership was counted. See below |
variants |
object |
One block per score, keyed capr200w, capr30d, local200w, local30d. See Variant blocks |
stocks |
object[] |
One row per member, ordered by symbol. It is called stocks for every type. See Member table |
asOf, generatedAt and universe are null only if the published snapshot is damaged. The rest of the response is still served.
The four variant keys are the four ByteTrend scores. 200w is Weekly and 30d is Daily. capr is CAPR (scored against the world stock market) and local is Local (scored on the asset’s own price). For example, capr200w is Weekly CAPR. See Key Concepts.
meta
| Field | Type | Description |
|---|---|---|
candidates |
number |
Active assets of this type in the universe, before the 7-day check |
members |
number |
Candidates with complete data inside the window. These are the assets the Monitor covers |
stale |
number |
Members whose market did not trade on asOf |
dropped |
number |
Candidates left out, either because their data is too old or because they have none |
livenessDays |
number |
The window in days, currently 7 |
intradaySkipped |
number |
Candidates whose newest row was skipped as incomplete because it was dated the day of the computation. Normally 0 |
Variant blocks
Each of variants.capr200w, variants.capr30d, variants.local200w and variants.local30d has the same fields:
| Field | Type | Description |
|---|---|---|
summary |
object |
Headline counts for the universe. See Summary |
highs |
object |
Members in the Leading Trend or Emerging Trend regime |
lows |
object |
Members in the Weakening Trend or Bear Trend regime |
new5 |
object |
Members that reached a score of 5 today, moving up |
new0 |
object |
Members that reached a score of 0 today, moving down |
dims |
object[] |
The type’s groupings, in display order: { key, label, minN }. key names a list in groups, label is a display name, and minN is the fewest scored members a group needs to be listed. minN is checked against the variant where the group has the most scored members, so a listed group can show a smaller n in another variant. See Asset types |
groups |
object |
The group rows for each grouping, keyed by the dims keys, largest group first (ties by name). Every key in dims is present, possibly as an empty list |
sizeVol |
object or null |
Stocks only, null for other types. Average score by company size and volatility. See Size × volatility grid |
sunburst |
object or null |
Stocks only, null for other types. Where the score-5 and score-0 stocks are, by country and then sector. See Sunburst |
regimes |
object or null |
Stocks only, null for other types. Where the Leading Trend and Bear Trend stocks are, by country and then sector. See Regime map |
extremes |
object or null |
Stocks only, null for other types. How many stocks are at score 5 and at score 0 in each region and sector, out of how many are scored there. See Winners and losers |
sectors, countries, industries |
object[] |
Deprecated, stocks only. Copies of groups.sector, groups.country and groups.industry, kept for older clients. They will be removed in a future release, so read groups instead |
Regimes are the standard trend regimes: Leading Trend, Emerging Trend, Weakening Trend, Bear Trend, Neutral.
Summary
| Field | Type | Description |
|---|---|---|
n |
number |
Members with a score for this variant |
avg |
number or null |
Average score |
bins |
number[6] |
How many members sit at each score: bins[0] counts score 0, up to bins[5] for score 5. The six add up to n |
p5 |
number or null |
Fraction of n at score 5, from 0 to 1 (0.15 means 15%) |
p0 |
number or null |
Fraction of n at score 0, from 0 to 1 |
leading |
number |
Members in Leading Trend |
emerging |
number |
Members in Emerging Trend |
weakening |
number |
Members in Weakening Trend |
bear |
number |
Members in Bear Trend |
highs |
number |
leading + emerging |
lows |
number |
weakening + bear |
ups |
number |
Members (not stale) whose score rose today |
downs |
number |
Members (not stale) whose score fell today |
Member lists
highs, lows, new5 and new0 have the same shape:
| Field | Type | Description |
|---|---|---|
count |
number |
How many members qualify in total |
rows |
object[] |
Up to 50 of them, in the type’s order (see Asset types). count can be larger than rows.length |
Each row:
| Field | Type | Description |
|---|---|---|
symbol |
string |
Ticker symbol |
name |
string |
Name |
country |
string or null |
Country |
sector |
string or null |
Sector |
industry |
string or null |
Industry. For commodities, this is the field the futuresGroup grouping is read from |
mktCapUsd |
number or null |
Market capitalisation in US dollars. For a classified ETF, its assets under management in US dollars instead |
return1D |
number or null |
The day’s return in US dollars, as a fraction (0.012 means +1.2%). null when there is no previous close |
score |
number |
This variant’s ByteTrend score, 0–5 |
regime |
string or null |
This variant’s trend regime |
change |
number |
Today’s score change (0 for a stale member) |
asOf |
string |
The member’s own latest complete close, YYYY-MM-DD. It matches the snapshot’s asOf unless the member is stale |
country, sector and industry are filled in where the asset has them. For types other than stock they are often null.
Group rows
Entries in each groups list:
| Field | Type | Description |
|---|---|---|
key |
string |
The group’s name, for example a sector, a country, a crypto cap tier or a futures group. Use it as group on Monitor History |
sector |
string or null |
Stock industry groups only. The sector most of the industry’s members belong to |
n |
number |
Scored members in the group |
n5 |
number |
Members at score 5 |
n0 |
number |
Members at score 0 |
bins |
number[6] or null |
Members at each score, bins[0] for score 0 up to bins[5] for score 5. The six add up to n. null when the snapshot was computed without the tally |
p5 |
number or null |
Fraction at score 5, from 0 to 1 |
p0 |
number or null |
Fraction at score 0, from 0 to 1 |
avg |
number or null |
Average score |
avgChg |
number or null |
Average score change today (stale members count as 0) |
Size × volatility grid
Stocks only. For other types sizeVol is null. sizeVol splits the members by market cap and by volatility, and gives the average score of each cell.
| Field | Type | Description |
|---|---|---|
cuts |
[number, number] or null |
The two volatility30w values that divide members into thirds: Low is below cuts[0], Mid is from cuts[0] up to cuts[1], High is cuts[1] and above. null when fewer than 30 members have a volatility figure |
cells |
object |
Keyed "<size>|<volatility>". Each value is { n, avg }: how many members are in the cell, and their average score, which can be null |
Size is Mega (market cap of $200B or more), Large ($10B to $200B) or Mid (under $10B). Volatility is Low, Mid or High. Either half can also be All, which gives the row and column totals, for example "Mega|All", "All|High" or "All|All". When cuts is null, only the "<size>|All" cells are present. A stock with no market cap is not placed in a size band.
Sunburst
Stocks only. For other types sunburst is null. sunburst shows where the score-5 and score-0 stocks are, by country and then by sector, for a ring or sunburst chart. It has two keys: "5" and "0".
| Field | Type | Description |
|---|---|---|
country |
string |
Country |
n |
number |
Members in this country at the given score |
base |
number |
All members in this country, at any score |
sectors |
object[] |
The same split by sector: { sector, n, base }. The sector n values add up to the country’s n |
Countries are ordered by n, largest first. A country with no stocks at that score is left out. A member with no country is listed under a country of "Unclassified", and one with no sector under a sector of "Unclassified", so the country n values add up to the number of members at that score.
Regime map
Stocks only. For other types regimes is null. It can also be null on snapshots computed before this field was added.
regimes has the same country-then-sector shape as the sunburst, but keyed by trend regime instead of score. It has two keys, Leading and Bear, and uses this variant’s regime: a Weekly variant’s regime for capr200w, a Daily one for capr30d, and so on.
| Field | Type | Description |
|---|---|---|
country |
string |
Country, or "Unclassified" |
n |
number |
Members in this country in that regime |
base |
number |
All members in this country, in any regime |
sectors |
object[] |
The same split by sector: { sector, n, base }, with "Unclassified" for a member with no sector. The sector n values add up to the country’s n |
Countries are ordered by n, largest first. The country n values under Leading add up to summary.leading, and those under Bear to summary.bear.
Winners and losers
Stocks only. For other types extremes is null. It is also null on snapshots computed before this field was added.
extremes counts the score-5 stocks (winners) and score-0 stocks (losers) by region and then by sector. Unlike the sunburst, every cell also gives how many stocks are scored there, and a region or sector with no stocks at either score is still listed, so you can read each count as a share.
| Field | Type | Description |
|---|---|---|
scored |
number |
Members with a score for this variant. Always equal to summary.n |
regions |
object[] |
One entry for every region with a scored member: { region, n5, n0, base, sectors } |
sectors |
object[] |
The same counts by sector across all regions: { sector, n5, n0, base } |
In each region or sector entry:
| Field | Type | Description |
|---|---|---|
region or sector |
string |
The region or sector, or "Unclassified" for a member with none |
n5 |
number |
Members here at score 5 |
n0 |
number |
Members here at score 0 |
base |
number |
Members here with a score for this variant, at any score |
sectors |
object[] |
Regions only. The region split by sector: { sector, n5, n0, base }, with every sector that has a scored member in the region |
The region is the same one the asset’s region field and /api/macro/region use. Every list is ordered by base, largest first, then by name. The counts add up exactly at every level: the base values add up to scored (across regions, and across sectors), the n5 values to summary.bins[5], the n0 values to summary.bins[0], and a region’s sectors add up to the region’s own figures.
Member table
stocks has one row for each member, ordered by symbol, with all four scores side by side. It keeps the name stocks for every type.
| Field | Type | Description |
|---|---|---|
symbol, name, country, sector, industry, mktCapUsd, return1D |
As in member lists | |
volatility30w |
number or null |
Annualised 30-week volatility, as a decimal |
return3M |
number or null |
Total return in US dollars over the last 3 months, as a fraction (0.12 means +12%). null when there is not enough history |
return12M |
number or null |
Total return in US dollars over the last 12 months, as a fraction. null when there is not enough history |
asOf |
string |
The member’s own latest complete close, YYYY-MM-DD |
stale |
boolean |
true when the member’s market did not trade on the snapshot’s asOf |
capr200w, capr30d, local200w, local30d |
object |
The member’s figures for that variant. See below |
Per-variant figures
Each of a row’s capr200w, capr30d, local200w and local30d objects has these fields:
| Field | Type | Description |
|---|---|---|
score |
number or null |
This variant’s ByteTrend score, 0–5 |
regime |
string or null |
This variant’s trend regime |
change |
number or null |
Today’s score change. 0 when the member is stale, null when there is no score |
consec5 |
number or null |
How many trading days in a row the member has been at score 5 on this variant. See below |
consec0 |
number or null |
How many trading days in a row the member has been at score 0 on this variant. See below |
extLong |
number or null |
How far the variant’s series is above (or below) its long moving average, as a fraction: series ÷ long average − 1 (0.05 means 5% above). See below |
extShort |
number or null |
The same against the short moving average: series ÷ short average − 1 |
For extLong and extShort, the series and averages depend on the variant:
| Variant | Series | Long average | Short average |
|---|---|---|---|
capr200w |
CAPR | 200-week | 30-week |
capr30d |
CAPR | 200-day | 30-day |
local200w |
The close in the asset’s own currency | 200-week | 30-week |
local30d |
The close in the asset’s own currency | 200-day | 30-day |
The Local close is the adjusted close, or the unadjusted close on a day with no adjusted figure. It is always in the asset’s own currency, never in US dollars, because that is the series the Local averages are built on. extLong or extShort is null when the series value or the average is missing, or the average is zero or negative.
The two counters count trading days on every variant, Weekly included: they are not converted to weeks. A counter goes back to 0 on the first day the score is something else. On a day with no score at all (a gap in the data), it keeps its previous value rather than resetting, so consec5 can be above 0 while score is null. A counter is null when the member’s data has none. A stale member keeps the values from its own latest close, like its scores.
Example
The first row of stocks here is stale: its market last traded on 2026-09-30, so its change values are 0.
A crypto snapshot (?type=crypto) has the same shape. It groups by cap tier, has no size × volatility grid or sunburst, and has no deprecated lists. Abridged, Daily CAPR shown:
{
"contractVersion": 3,
"asOf": "2026-10-07",
"type": "crypto",
"meta": { "candidates": 178, "members": 175, "stale": 1, "dropped": 3, "livenessDays": 7, "intradaySkipped": 0 },
"variants": {
"capr30d": {
"summary": { "n": 175, "avg": 2.9543, "bins": [14, 13, 19, 69, 41, 19], "p5": 0.1086, "p0": 0.08, "...": "..." },
"highs": {
"count": 1,
"rows": [
{
"symbol": "KCSUSD", "name": "KuCoin Token USD", "country": null, "sector": "Cryptocurrency", "industry": null,
"mktCapUsd": 1008472345.04, "return1D": -0.0027, "score": 3, "regime": "Emerging Trend", "change": 0, "asOf": "2026-10-07"
}
]
},
"dims": [{ "key": "capTier", "label": "Market-cap tier", "minN": 1 }],
"groups": {
"capTier": [
{ "key": "Micro", "n": 70, "n5": 2, "n0": 14, "p5": 0.0286, "p0": 0.2, "avg": 2.2, "avgChg": -0.2571 },
{ "key": "Small", "n": 62, "n5": 9, "n0": 0, "p5": 0.1452, "p0": 0, "avg": 3.3387, "avgChg": -0.371 },
{ "key": "Mid", "n": 32, "n5": 8, "n0": 0, "p5": 0.25, "p0": 0, "avg": 3.7188, "avgChg": -0.2188 },
{ "key": "Large", "n": 11, "n5": 0, "n0": 0, "p5": 0, "p0": 0, "avg": 3.3636, "avgChg": -0.5455 }
]
},
"sizeVol": null,
"sunburst": null,
"...": "..."
},
"...": "..."
},
"stocks": ["..."]
}
Errors
| Status | When |
|---|---|
400 |
An unknown query parameter, an unknown type, or format=csv |
401 |
Missing or invalid API key |
403 |
Key lacks the api+mcp capability |
404 |
No snapshot has been published yet for that type: { "error": "no monitor snapshot has been published yet" } |
503 |
The stored snapshot could not be served: { "error": "the monitor snapshot is incomplete; try again later" }. This is rare and temporary, so retry later |