tardis-dev
Version:
Convenient access to tick-level historical and real-time cryptocurrency market data via Node.js
258 lines (181 loc) • 8.52 kB
Markdown
# tardis-dev
[](https://www.npmjs.org/package/tardis-dev)
<br/>
Node.js `tardis-dev` library provides convenient access to tick-level real-time and historical cryptocurrency market data both in exchange native and normalized formats. Instead of callbacks it relies on [async iteration (for await ...of)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of) enabling composability features like [seamless switching between real-time data streaming and historical data replay](https://docs.tardis.dev/node-client/normalization#seamless-switching-between-real-time-streaming-and-historical-market-data-replay) or [computing derived data locally](https://docs.tardis.dev/node-client/normalization#computing-derived-data-locally).
<br/>
```javascript
import { replayNormalized, normalizeTrades, normalizeBookChanges } from 'tardis-dev'
const messages = replayNormalized(
{
exchange: 'binance',
symbols: ['btcusdt'],
from: '2024-03-01',
to: '2024-03-02'
},
normalizeTrades,
normalizeBookChanges
)
for await (const message of messages) {
console.log(message)
}
```
<br/>
## Features
- historical tick-level [market data replay](https://docs.tardis.dev/node-client/replaying-historical-data) backed by [tardis.dev HTTP API](https://docs.tardis.dev/api/http-api-reference#data-feeds-exchange) — includes full order book depth snapshots plus incremental updates, tick-by-tick trades, historical open interest, funding, index, mark prices, liquidations and more
<br/>
- consolidated [real-time data streaming API](https://docs.tardis.dev/node-client/streaming-real-time-data) connecting directly to exchanges' public WebSocket APIs
<br/>
- support for both [exchange-native and normalized market data](https://docs.tardis.dev/faq/data) formats (unified format for accessing market data across all supported exchanges — normalized trades, order book and ticker data)
<br/>
- [seamless switching between real-time streaming and historical market data replay](https://docs.tardis.dev/node-client/normalization#seamless-switching-between-real-time-streaming-and-historical-market-data-replay) thanks to [`async iterables`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of) providing unified way of consuming data messages
<br/>
- transparent historical local data caching \(cached data is stored on disk per slice in compressed format and decompressed on demand when reading the data\)
<br/>
- support for many cryptocurrency exchanges — see [docs.tardis.dev](https://docs.tardis.dev) for the full list
<br/>
- automatic closed connections and stale connections reconnection logic for real-time streams
<br/>
- [combining multiple exchanges feeds into single one](https://docs.tardis.dev/node-client/normalization#combining-data-streams) via [`combine`](https://docs.tardis.dev/node-client/normalization#combining-data-streams) helper function — synchronized historical market data replay and consolidated real-time data streaming from multiple exchanges
<br/>
- [computing derived data locally](https://docs.tardis.dev/node-client/normalization#computing-derived-data-locally) like order book imbalance, custom trade bars, book snapshots and more via [`compute`](https://docs.tardis.dev/node-client/normalization#computing-derived-data-locally) helper function and `computables`, e.g., volume based bars, top 20 levels order book snapshots taken every 10 ms etc.
<br/>
- [full limit order book reconstruction](https://docs.tardis.dev/node-client/normalization#limit-order-book-reconstruction) both for real-time and historical data via `OrderBook` object
<br/>
- fast and lightweight architecture — low memory footprint and no heavy in-memory buffering
<br/>
- [extensible mapping logic](https://docs.tardis.dev/node-client/normalization#modifying-built-in-and-adding-custom-normalizers) that allows adjusting normalized formats for specific needs
<br/>
- [built-in TypeScript support](https://docs.tardis.dev/node-client/quickstart#es-modules-and-typescript)
<br/>
<br/>
<br/>
## Installation
Requires Node.js v25+ installed.
```bash
npm install tardis-dev --save
```
`tardis-dev` is ESM-only. Examples in this README use ES modules and top-level await. Save snippets as `.mjs` or set `"type": "module"` in your `package.json`.
<br/>
<br/>
## Documentation
### [See official docs](https://docs.tardis.dev/node-client/quickstart).
<br/>
<br/>
## Examples
### Real-time spread across multiple exchanges
Example showing how to quickly display real-time spread and best bid/ask info across multiple exchanges at once. It can be easily adapted to do the same for historical data \(`replayNormalized` instead of `streamNormalized`).
```javascript
import { streamNormalized, normalizeBookChanges, combine, compute, computeBookSnapshots } from 'tardis-dev'
const exchangesToStream = [
{ exchange: 'bitmex', symbols: ['XBTUSD'] },
{ exchange: 'deribit', symbols: ['BTC-PERPETUAL'] },
{ exchange: 'cryptofacilities', symbols: ['PI_XBTUSD'] }
]
// for each specified exchange call streamNormalized for it
// so we have multiple real-time streams for all specified exchanges
const realTimeStreams = exchangesToStream.map((e) => {
return streamNormalized(e, normalizeBookChanges)
})
// combine all real-time message streams into one
const messages = combine(...realTimeStreams)
// create book snapshots with depth1 that are produced
// every time best bid/ask info is changed
// effectively computing real-time quotes
const realTimeQuoteComputable = computeBookSnapshots({
depth: 1,
interval: 0,
name: 'realtime_quote'
})
// compute real-time quotes for combines real-time messages
const messagesWithQuotes = compute(messages, realTimeQuoteComputable)
const spreads = {}
// print spreads info every 100ms
setInterval(() => {
console.clear()
console.log(spreads)
}, 100)
// update spreads info real-time
for await (const message of messagesWithQuotes) {
if (message.type === 'book_snapshot') {
spreads[message.exchange] = {
spread: message.asks[0].price - message.bids[0].price,
bestBid: message.bids[0],
bestAsk: message.asks[0]
}
}
}
```
<br/>
### Seamless switching between real-time streaming and historical market data replay
Example showing simple pattern of providing `async iterable` of market data messages to the function that can process them no matter if it's is real-time or historical market data. That effectively enables having the same 'data pipeline' for backtesting and live trading.
```javascript
import { replayNormalized, streamNormalized, normalizeTrades, compute, computeTradeBars } from 'tardis-dev'
const historicalMessages = replayNormalized(
{
exchange: 'binance',
symbols: ['btcusdt'],
from: '2024-03-01',
to: '2024-03-02'
},
normalizeTrades
)
const realTimeMessages = streamNormalized(
{
exchange: 'binance',
symbols: ['btcusdt']
},
normalizeTrades
)
async function produceVolumeBasedTradeBars(messages) {
const withVolumeTradeBars = compute(
messages,
computeTradeBars({
kind: 'volume',
interval: 1 // aggregate by 1 BTC traded volume
})
)
for await (const message of withVolumeTradeBars) {
if (message.type === 'trade_bar') {
console.log(message.name, message)
}
}
}
await produceVolumeBasedTradeBars(historicalMessages)
// or for real time data
// await produceVolumeBasedTradeBars(realTimeMessages)
```
<br/>
### Stream real-time market data in exchange native data format
```javascript
import { stream } from 'tardis-dev'
const messages = stream({
exchange: 'binance',
filters: [
{ channel: 'trade', symbols: ['btcusdt'] },
{ channel: 'depth', symbols: ['btcusdt'] }
]
})
for await (const { localTimestamp, message } of messages) {
console.log(localTimestamp, message)
}
```
<br/>
### Replay historical market data in exchange native data format
```javascript
import { replay } from 'tardis-dev'
const messages = replay({
exchange: 'binance',
filters: [
{ channel: 'trade', symbols: ['btcusdt'] },
{ channel: 'depth', symbols: ['btcusdt'] }
],
from: '2024-03-01',
to: '2024-03-02'
})
for await (const { localTimestamp, message } of messages) {
console.log(localTimestamp, message)
}
```
<br/>
<br/>
## See the [tardis-dev docs](https://docs.tardis.dev/node-client/quickstart) for more examples.