The base URL swap
Replace https://www.alphavantage.co/query with
https://cuckootrade.com/api/v1/alphavantage/query. The
function-switched interface is unchanged:
curl 'https://cuckootrade.com/api/v1/alphavantage/query?function=TIME_SERIES_DAILY&symbol=IBM'
{
"Meta Data": {
"1. Information": "Daily Prices (open, high, low, close) and Volumes",
"2. Symbol": "IBM",
"3. Last Refreshed": "2026-08-19",
"4. Output Size": "Compact",
"5. Time Zone": "US/Eastern"
},
"Time Series (Daily)": {
"2026-08-19": {
"1. open": "241.8300",
"2. high": "244.1900",
"3. low": "240.5500",
"4. close": "243.0700",
"5. volume": "3814227"
}
}
}
Intraday, free
On the real API, intraday history sits behind a premium plan. Here it is generated on demand, so it costs nothing:
curl 'https://cuckootrade.com/api/v1/alphavantage/query?function=TIME_SERIES_INTRADAY&symbol=IBM&interval=5min' # a specific month of history curl 'https://cuckootrade.com/api/v1/alphavantage/query?function=TIME_SERIES_INTRADAY&symbol=IBM&interval=1min&month=2026-07&outputsize=full'
| function | Notes |
|---|---|
| TIME_SERIES_INTRADAY | interval= 1min, 5min, 15min, 30min, 60min. month=YYYY-MM selects a month. |
| TIME_SERIES_DAILY | Keyed YYYY-MM-DD. |
| TIME_SERIES_WEEKLY | Keyed by the last trading day of the week. |
| TIME_SERIES_MONTHLY | Keyed by the last trading day of the month. |
| GLOBAL_QUOTE | The single-quote shape. |
outputsize=compact (100 rows, the default) and
full both behave as documented.
apikey, adjusted and
extended_hours are accepted and ignored.
Errors arrive as HTTP 200
The real API reports failures with a success status line, and its
client libraries sniff for the Error Message key rather
than checking the status. That is faithfully reproduced here,
because code that gets this wrong fails silently in production:
import requests
r = requests.get("https://cuckootrade.com/api/v1/alphavantage/query",
params={"function": "TIME_SERIES_DAILY",
"symbol": "IBM"}).json()
# Errors arrive as 200. r.raise_for_status() would never fire.
if "Error Message" in r:
raise SystemExit(r["Error Message"])
series = r["Time Series (Daily)"]
for day, ohlcv in list(series.items())[:5]: # newest first
print(day, float(ohlcv["4. close"])) # values are strings
The one deliberate exception is
scenario=status:503: you explicitly asked for a status
code, so the request wins over the mimicry. That gives you both
behaviors to test against.
Scenario tickers and fault injection
All three provider surfaces read from the same deterministic engine, so scenario tickers work here identically — only the wire format differs:
curl 'https://cuckootrade.com/api/v1/alphavantage/query?function=TIME_SERIES_DAILY&symbol=CRASH' # and a transport that fails twice before it works curl -i 'https://cuckootrade.com/api/v1/alphavantage/query?function=TIME_SERIES_DAILY&symbol=IBM&scenario=flap:2'
Deviations, stated plainly
- Completed bars only. There is no partial current day, week, or month row — determinism requires it.
- Regular session only. 09:30–16:00 ET; extended hours are not modeled.
- No rate limit worth planning around. 60 requests/minute per address rather than the real API’s daily cap.
- Fundamentals, FX, and crypto functions are not implemented. Time series and
GLOBAL_QUOTEare.
X-Cuckoo-Synthetic: true. For exercising code paths, not
for validating trading strategies.