Available symbols
Discover available symbols and their configuration through the Python SDK.
HTTP endpoints on this page
- GET/data/calibrated-data
Parameters and response shapes for each are in the API reference.
Use client.data.calibrated_data() to retrieve the instruments that are already calibrated, and therefore simulatable, with their available dates, trading parameters and volume statistics. This is the list to drive a symbol picker from. It also accepts optional filters, so you can ask for one symbol, one exchange, or one date instead of the whole catalog.
The endpoint only ever returns calibrated instrument-days — it filters on pipeline state server-side. So there is no status or stage for you to check: if a date is in the response, you can simulate it. Those two fields are reported for provenance, and always read complete / model_calibration.
Get available symbols
data.calibrated_data(symbol=None, q=None, exchange=None, provider=None, date=None, limit=None, offset=None)Return the calibrated instruments, with their dates, trading parameters and volume statistics.Any tier
Called with no arguments it returns the whole catalog, which is large. Every filter narrows it server-side, and they combine with AND.
Parameters
- symbol : str, optional
- Exact ticker, e.g.
"700.HK". Not a prefix or substring match — useqfor that. - q : str, optional
- Case-insensitive substring match over the ticker and the company name — the search a symbol picker needs.
"angl"finds ANGLO AMERICAN. - exchange : str, optional
- Exchange protocol, e.g.
"hkex_securities". The same spellingsimulation.run()takes. - provider : str, optional
- Data provider, e.g.
"omd"or"bmll". Pass it alongsidesymbolwhenever you need one specific row — see the note below. - date : str, optional
- Calibration date
"YYYY-MM-DD". Keeps only symbols calibrated on it, and also narrows each symbol'savailable_datesto that date — so the two averages then describe that date alone rather than the symbol's whole history. - limit : int, optional
- Maximum symbols to return, 1–1000.
- offset : int, optional
- Symbols to skip, for paging alongside limit.
Returns
dict
{total, limit, offset, symbols} — the same envelope as data.available_data(). total is the match count before paging, so offset + len(symbols) < total means a limit truncated the result. Each entry in symbols is one instrument, carrying every calibrated date for it:
- symbol : str
- Symbol ticker, e.g. 700.HK.
- company_name : str or None
- Company name, e.g. KUAISHOU-W. None where the provider reports no company name, so always fall back to symbol.
- provider : str
- Data provider the row was sourced from.
- exchange : str
- Exchange protocol.
- instrument_type : {"equity", "derivative"}
- Type of instrument.
- currency : str
- Trading currency, e.g. HKD.
- tick_size : float
- Minimum price increment.
- lot_size : int
- Minimum order size. Multiply an execution algorithm's
order_size, which is denominated in lots, by this to reason in shares. - available_dates : list of dict
- Per-date calibration records:
date,status,stage,number_of_msgs,volume_tradedandreference_price. A date appears at most once per instrument. - avg_number_of_msgs : float
- Mean message count over exactly the dates shown.
- avg_volume_traded : float
- Mean daily volume over exactly the dates shown.
Notes
The endpoint only ever returns calibrated instrument-days — it filters on pipeline state server-side. There is no status or stage for you to check: if a date is in the response, you can simulate it. Both fields are reported for provenance and always read complete / model_calibration.
Paging is by instrument, not by row, so a limit can never cut one instrument's dates in half and misreport what is available.
The same ticker can appear more than once, sourced from different providers or exchange protocols — and those entries carry different dates and different tick sizes. Tencent is 700.HK under omd but 700 under bmll. A row is identified by (symbol, provider, exchange), not by symbol alone — use that triple as the key if you cache the catalog.
Examples
catalog = client.data.calibrated_data(limit=5)
print(catalog["total"], "calibrated instruments")
# Every date returned is already calibrated and ready to simulate.
# company_name is null for some providers, so fall back to the ticker.
for sym in catalog["symbols"]:
label = sym["company_name"] or sym["symbol"]
dates = [d["date"] for d in sym["available_dates"]]
print(f"{sym['symbol']} ({label}) on {sym['provider']}: {len(dates)} dates")
print(f" {dates[:4]}")# Which dates is this symbol already calibrated for?
tencent = client.data.calibrated_data(symbol="700.HK")["symbols"]
print([d["date"] for d in tencent[0]["available_dates"]])
# Which symbols are ready on a particular date?
ready = client.data.calibrated_data(date="2025-09-02")["symbols"]
print([s["symbol"] for s in ready])
# Search by ticker or company name
hits = client.data.calibrated_data(q="angl")["symbols"]
print([(s["symbol"], s["company_name"]) for s in hits])Paging through one exchange until total is reached:
offset, instruments = 0, []
while True:
page = client.data.calibrated_data(
exchange="hkex_securities", limit=50, offset=offset
)
instruments += page["symbols"]
offset += len(page["symbols"])
if not page["symbols"] or offset >= page["total"]:
break
print(len(instruments), "of", page["total"])Example response
One entry in symbols per instrument, each with every calibrated date for it. A date appears at most once per instrument, and the two averages are means over exactly the dates shown.
{
"total": 1,
"limit": null,
"offset": 0,
"symbols": [
{
"symbol": "700.HK",
"company_name": null,
"provider": "omd",
"exchange": "hkex_securities",
"instrument_type": "equity",
"currency": "HKD",
"tick_size": 0.5,
"lot_size": 100,
"available_dates": [
{
"date": "2025-09-02",
"status": "complete",
"stage": "model_calibration",
"number_of_msgs": 252812,
"volume_traded": 21861323.0,
"reference_price": 605.0
},
{
"date": "2025-09-03",
"status": "complete",
"stage": "model_calibration",
"number_of_msgs": 263787,
"volume_traded": 24493985.0,
"reference_price": 606.0
},
{
"date": "2025-09-04",
"status": "complete",
"stage": "model_calibration",
"number_of_msgs": 274606,
"volume_traded": 31023758.0,
"reference_price": 604.5
}
],
"avg_number_of_msgs": 263735.0,
"avg_volume_traded": 25793022.0
}
]
}Get the latest calibrated date
A single call answers “what is the most recent date I can simulate?” — every date the endpoint returns is already calibrated, so the newest one is always safe to pass to run(). Filter server-side rather than pulling the whole catalog, and pass provider when a ticker exists under more than one.
def latest_cal_date(client, symbol: str, provider: str = None) -> str | None:
"""Return the most recent calibrated date for *symbol*, or None."""
rows = client.data.calibrated_data(symbol=symbol, provider=provider)["symbols"]
dates = [d["date"] for row in rows for d in row["available_dates"]]
return max(dates) if dates else None
cal_date = latest_cal_date(client, "700.HK", provider="omd")
print(f"Latest ready date: {cal_date}")