Core concepts
Trading days and sessions
A trading day is the business day of the instrument's exchange, written
YYYY-MM-DD. It is not always the calendar date of every row: a session that
starts in the evening can belong to the next trading day. Whether that happens,
and when the evening session starts, is a property of the venue and the product.
Sessions are returned in UTC by GET /v2/catalog/calendar, with a kind label
from the exchange, such as night, day, auction, pre, regular or
post. The set of labels is open; treat an unknown label as a plain session.
Do not assume:
- that every venue has a night session;
- that an evening session always belongs to the next trading day;
- that two products on one venue share a session template.
Read the calendar for the venue and product you use.
Timestamps and row order
Every data row has:
ts: the exchange event time, in RFC 3339 UTC with nanosecond precision;trading_day: the trading day the row belongs to;seq: the order inside the same instrument, trading day and timestamp.
Rows are ordered by instrument, then by (ts, seq). A query across several
instruments returns each instrument's rows in time order, one instrument after
another.
Requests take either trading days (trading_day, or from_day and to_day) or
instants (start inclusive, end exclusive). Instants must include a zone or
Z.
Symbols
A public symbol is VENUE.code, for example SHFE.rb2701, SSE.600000 or
SHFE.rb.main. The code shape belongs to the venue:
- a product with a delivery month on a futures venue (
SHFE.rb2701); - an exchange code on an equity venue (
SSE.600000); - an option series (
SHFE.rb2701-C-3000); - a veinmesh continuous contract (
SHFE.rb.main,SHFE.rb.c1).
Symbols are resolved as of a date. If a spelling could name two instruments on
that day, the API answers ambiguous_symbol; use the full symbol or
instrument_id. instrument_id never changes and is never reused.
Exact decimals
Prices, sizes, multipliers and tick sizes are exact decimals. JSON returns them
as strings by default, for example "3061" or "0.01", to avoid floating-point
error. Add numbers=float to receive JSON numbers instead.
In the Python SDK, to_pandas() converts decimals to floats by default; pass
exact=True to keep Decimal values.
Paging and catalog versions
Data endpoints return one page at a time. Pass the response's next_cursor back
as cursor; the last page has next_cursor: null. A cursor belongs to the query
and the key that produced it.
Every response carries catalog_version, the identifier of the catalog snapshot
used to resolve symbols and partitions. Passing it back pins a reproducible
result. Only a limited window of versions is kept; an old one answers
version_unavailable (410). Bar responses also carry calc_version, the version
of the calculation rules.
What the API promises
/v2 changes additively only: new routes, new optional parameters, new response
fields and new enum values. Clients must ignore fields they do not know and
treat unknown enum values as "other". A version is never silently changed in a
way that alters an existing request.
Errors are always application/problem+json (RFC 9457). Branch on code, not
on detail: detail is for humans and may be reworded. See Errors.
What is not portable between markets
These are decided by the venue or the dataset, not by veinmesh:
- whether an evening session exists and which trading day it belongs to;
- the symbol shape, including the delivery-month format;
- the definition of the main contract and the roll schedule;
- whether volume is cumulative and when it resets;
- the session boundaries a K-line
anchor=sessionuses.
Read them from the catalog, the dataset schema and the calendar. The manual describes the behaviour of the markets served today; it is not a rulebook for every exchange.