Data sources - sbOogway/sbt2 GitHub Wiki

Data sources

The framework is source-agnostic, just as it is asset-class-agnostic (see Asset classes). A source adapter plugs into Data: download (where files live, how to fetch them) and ingest (how to parse them). Everything downstream of the catalog only sees nautilus types and never knows which source the data came from.

The adapter interface

Each adapter subclasses Source, the abstract base class in data/sources/base.py. Other modules get one with sbt2.core.data.sources.source(name, known_gaps_file) and never import an adapter.

A subclass implements what is specific to its source:

Member What it gives
name class variable: the source's list in known_gaps.toml, e.g. "bybit"
data_types the nautilus types served as one raw file per UTC day (e.g. TradeTick, FundingRateUpdate, MarkPriceUpdate)
day_file(symbol, data_type, day) a RawFile for that day
instrument_snapshot(symbol, taken_on) a RawFile for today's instrument spec, named with the date it's taken on
instrument_id(symbol) the source's nautilus InstrumentId format
symbol(instrument_id) the inverse of instrument_id, so Run can fetch a spec's instruments by symbol
parse(path, data_type, instrument) a raw day file's records as nautilus types, in time order, for ingest; the instrument gives precisions and anything else the parser needs
parse_instrument(path) the instrument of a snapshot, with ts_init at the start of the day it was taken on

The base owns what every source shares:

Member What it gives
Source.listing(entries) the source built from its list in known_gaps.toml, each entry turned into a Gap through instrument_id and the source's names for its data types
known_gaps the gaps below, as (instrument id, data type, day)
served(names) the served data types with those nautilus names, all of them when none are given; an unserved name raises UnsupportedDataTypeError listing what the source serves
is_known_gap(symbol, data_type, day) whether that day is a known gap, so download and ingest skip it

A subclass is constructible from its known gaps alone, since listing builds it that way. The known gaps file names a data type by its nautilus name (TradeTick) unless the source overrides _listed_data_type, as Bybit does with its channel names (trades).

A RawFile is a path under the raw root plus its origin: either a URL that download fetches itself (a 404 means missing), or a coroutine returning the file's bytes, for data the source fetches from an API; it raises MissingAtSourceError when the source has nothing. Download stays source-agnostic either way: it owns scheduling, retries, .part files and the missing-days summary.

A source ships inside the package that provides it (sbt2 itself for Bybit) and registers under the sbt2.sources entry point, so another package can add a source without a release of sbt2.

Known gaps

Sources sometimes lack a day (e.g. a missing dump file). Each source keeps a known-gaps list in the data root's known_gaps.toml, one list per source (e.g. bybit = [{ symbol = "BTCUSDT", data = "trades", day = 2020-03-25 }]): (instrument, data type, day) entries confirmed as unavailable at the source. A missing file means no known gaps; known_gaps(file) gives every source's, for sbt2 data status. The file is edited by hand or from the GUI: listed_gaps(file) lists the entries with their source, and add_known_gaps and remove_known_gaps change them, each write validated (a known source and data type) and atomic (see Config area on Architecture). Run's coverage check allows these days and records them in the run's summary; any other missing day still fails the run. A gap is added to the list deliberately, never automatically. A day the source serves with no rows is not a gap: ingest writes it as a zero-row file (see Data).

Source Status Page
Bybit (linear perps: L2, trades, funding, mark price) first adapter Source Bybit