Quantifying A-Share Market Mood
Mood is not a feeling — it is numbers: breadth, limit-up counts, turnover, style rotation. Three free endpoints are enough to read "how hot is the market today". Code and caveats below.
Why breadth beats the index
An index can rise 1% while 3,000 stocks fall — heavyweight names distort it. Advance/decline breadth shows what the majority of stocks actually did, which matches how retail investors experience the market.
Likewise, limit-up counts read money-making effect directly, and turnover reads participation.
Step 1: today’s breadth (free)
`/v1/changedist` is the recommended entry for breadth, and it is the current session figure.
import requests
r = requests.get("https://api.ashareapi.com/v1/changedist", timeout=10)
b = r.json()
rows = b.get("structured") or b["data"]
for row in rows:
print(row) # advances/declines, limit-ups/downs, turnover, distribution⚠️ The caveat: current session vs T-1
- `/v1/changedist` = current session — use this for today’s mood
- `/v1/market-overview?type=updown` = T-1 (the response states its data date; it can lag by one trading day) — the two will not match
- Do not treat T-1 breadth as today’s — this is the most common mistake
Step 2: market profile and style rotation (free)
# Overall market profile
print(requests.get("https://api.ashareapi.com/v1/market-overview",
params={"type": "summary"}, timeout=10).json()["data"])
# Style rotation (large vs small cap, growth vs value)
print(requests.get("https://api.ashareapi.com/v1/market-overview",
params={"type": "rotation"}, timeout=10).json()["data"])
# Valuation percentile (CSI All Share PE/PB/PS vs history)
print(requests.get("https://api.ashareapi.com/v1/market-overview",
params={"type": "valuation"}, timeout=10).json()["data"])- `type=summary` profile · `trade` close · `interval` multi-period · `technical` index technicals
- `type=margin` margin trading · `valuation` percentiles · `rotation` style rotation
Step 3: what money is chasing (free)
The hot list reflects retail attention. Read it with breadth: good breadth + concentrated hot list = a clear main line; poor breadth + scattered hot list = fading mood.
hot = requests.get("https://api.ashareapi.com/v1/hot",
params={"limit": 10}, timeout=10).json()
for row in hot.get("structured") or hot["data"]:
print(row) # attention ranking + change %Turn three readings into a "market temperature"
| Reading | Means | How to use |
|---|---|---|
| Advances vs declines | Breadth | > 60% advancing = broad rally; < 40% = broad decline |
| Limit-up count | Money-making effect | Compare with its 20-day average; a clear expansion = heating up |
| Turnover | Participation | Rising volume + rising price = new money; falling volume + rising price = existing money only |
| Style rotation | Where money goes | Small caps leading = higher risk appetite; large caps leading = defensive |
| Valuation percentile | Position | High percentile ≠ imminent drop, but the odds get worse |
Three rules to write down
- One day’s mood does not predict tomorrow — mood describes a state, it is not a buy/sell signal
- Always compare with history — is 80 limit-ups a lot? Only a 20-day average tells you
- Separate volume-up from volume-down — a rally on rising volume and one on falling volume are different events
Common mistakes and boundaries
- Mixing T-1 with the current session → use `/v1/changedist` for today, not `market-overview?type=updown`
- Only looking at limit-up counts → without the failure rate you can misread (high limit-ups + high failure = unstable mood)
- Units → `volume` is in lots, `amount` in CNY; do not mix them
- Anonymous limits are 5 req/min → this tutorial uses only free endpoints; batch jobs should `sleep()` or upgrade
FAQ
No. `changedist`, `market-overview` and `hot` are all among the five free endpoints — no signup, no key.
Check the definition first: our `/v1/changedist` is the current session, while `/v1/market-overview?type=updown` is T-1 (its response states the data date). Platforms also differ on what counts (ST, Beijing exchange, suspended). Align those two points first.
No. Mood is a state description, not a signal. The same "good mood" means opposite things early in a trend and at its end — direction needs price position and volume. This tutorial only covers how to compute mood.
Look at the field name and magnitude: `amount` fields are generally in CNY (e.g. `135160431.2` = 1.35×10^8 CNY). Sanity-checking against a familiar trading day is the fastest way.
Yes — these three endpoints need no key and cost nothing. For intraday polling, note the anonymous limit of 5 requests/minute; keep ≥12s between calls, or solve one PoW challenge to reach 60/min.
Last updated: 2026-09-23
Code and definitions come from live responses (verified 2026-09-23: changedist is current-session; market-overview?type=updown returns a T-1 data date). Units and rate limits follow the endpoint docs.