Why ask a server for a moving average you could compute yourself?
A moving average is a mean. Anyone can write it. So it is worth being clear about what /technical/{ticker} is actually for, before the rest of this unit shows you how to get it wrong.
What the endpoint offers
One required parameter, function, chosen from twenty values:
sma ema wma volatility stochastic rsi stddev
stochrsi slope dmi adx macd atr cci sar
beta bbands splitadjusted avgvol avgvolccy
The response is an array of {date, ...} objects whose extra fields depend on the function: sma returns sma; macd returns macd, signal and divergence (not macd_signal and macd_hist, whatever you may have read — check the keys you actually received); bbands returns uband, mband and lband; stochastic returns k_values and d_values (read 29 September 2026; k_values is the slow %K); and splitadjusted returns split-adjusted OHLCV.
Real values for AAPL.US, on data through 2026-07-27, fetched on that date. Every one of them is computed on the adjusted column, so re-fetching the identical window after the next ex-dividend returns slightly different numbers — the reason is two sections down:
function=sma, period=50 2026-07-27: 306.9922
function=sma, period=200 last value: 276.0692
function=rsi, period=14 last value: 67.2912
function=macd (12, 26, 9) last value: 8.9310
function=atr, period=14 last value: 8.1406
function=adx, period=14 last value: 27.6999
The server is checkable, and you should check it
Ask for function=sma&period=2 and check it against two closes you pulled separately. Run in July 2026 the served value was 334.965, and the last two close values for AAPL.US were 336.91 on 2026-07-27 and 333.02 on 2026-07-24 — (336.91 + 333.02) ÷ 2 = 334.965 exactly.
Run the same request for the same two days now and the server returns 334.6763, which is not the mean of those closes. It is the mean of their adjusted_close values, 336.6197 and 332.7330. Nothing broke: a dividend went ex in the meantime, the adjusted column was rewritten, and the indicator moved with it.
So the audit answers two questions, and the second one only once the two columns have parted company: the formula, and which price column it ran on. The answer for the price indicators is adjusted_close, which makes them total-return figures. It is not universal — splitadjusted returns split-adjusted OHLCV, avgvol returns a share count, and splitadjusted_only=1 restricts selected functions to splits alone. Run the check against both columns per function, and know that it tells you nothing about the column on a window where no ex-date has passed since.
So why not compute them yourself?
Not because the arithmetic is hard. Because the alternative is: download and store full price history for every symbol you want an indicator on, keep it current, handle every corporate action correctly, and then reimplement each indicator's conventions — which smoothing does this EMA use, is this RSI Wilder's or a simple mean, does this ATR seed from a simple average? Those conventions differ between libraries, and two "RSI(14)" series from two sources routinely disagree in the third decimal and occasionally in the first.
One request per symbol per indicator moves all of that into one place with one set of conventions. That is the trade: less code and more consistency, in exchange for a dependency and a per-call cost.
The costs, stated plainly
One function per request. There is no multi-indicator response and no multi-symbol response. A dashboard covering 20 symbols with 3 indicators each is 60 requests, every refresh — and this endpoint is metered at 5 API calls per request, so it is 300 calls against the daily quota and 60 against the per-minute request ceiling. Those are two different currencies, as the API Foundations course sets out, and the arithmetic is worth doing before you build the dashboard rather than after.
What these numbers mean — when a 50-day average crossing a 200-day average is worth anyone's attention, what an RSI of 67 does and does not imply — is the subject of the Technical Analysis domain, and specifically its "Indicators that Matter" course. This unit is about obtaining them without changing them by accident.
Try it now
- The first table is
/technical/AAPL.US?function=sma&period=2over 24 to 27 July 2026, the same two sessions as above; the second is/eodfor those sessions, both close columns. Average the twoclosevalues yourself, then the twoadjusted_closevalues. Whichever one matches is the column the endpoint used — and if both match, no ex-date has passed since your window and the test has told you nothing yet.
- Here is
bbandswithperiod=20over 3 August to 25 September 2026. Confirm you get three fields per row rather than one. Then read the date of the first row: this endpoint computes only over the bars inside your window and does not reach back for the warm-up, so give it afromat leastperiodbars earlier than you need. Count the sessions the window lost. Asking for a 200-day average across that same window returned200and an empty array on 28 September 2026, not an error.
- Count the requests your intended dashboard costs per refresh, then per day. Do it now, on paper.