{"id":13876160,"url":"https://github.com/tardis-dev/tardis-node","last_synced_at":"2025-04-14T22:11:32.467Z","repository":{"id":40636935,"uuid":"191725387","full_name":"tardis-dev/tardis-node","owner":"tardis-dev","description":"Convenient access to tick-level real-time and historical cryptocurrency market data via Node.js","archived":false,"fork":false,"pushed_at":"2025-02-27T15:14:55.000Z","size":10988,"stargazers_count":315,"open_issues_count":6,"forks_count":67,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-04-07T19:06:24.330Z","etag":null,"topics":["arbitrage","async-iterable","binance","bitmex","bitmex-api","bitmexbot","btc","ccxt","cryptocurrency-api","cryptocurrency-exchanges","deribit","eth","exchange","historical-data","market-data","orderbook","orderbook-tick-data","real-time","trading","websocket"],"latest_commit_sha":null,"homepage":"https://docs.tardis.dev/api/node-js","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tardis-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-13T08:46:04.000Z","updated_at":"2025-03-26T18:41:00.000Z","dependencies_parsed_at":"2023-12-16T05:42:45.000Z","dependency_job_id":"9c51e246-a0b8-496e-8fc4-63c5cb3ed897","html_url":"https://github.com/tardis-dev/tardis-node","commit_stats":{"total_commits":871,"total_committers":97,"mean_commits":8.97938144329897,"dds":0.129735935706085,"last_synced_commit":"fb69509edd6dc80fd2b0c48ca65bc9dade24e371"},"previous_names":["tardis-dev/node-client"],"tags_count":305,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tardis-dev%2Ftardis-node","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tardis-dev%2Ftardis-node/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tardis-dev%2Ftardis-node/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tardis-dev%2Ftardis-node/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tardis-dev","download_url":"https://codeload.github.com/tardis-dev/tardis-node/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248968914,"owners_count":21191162,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arbitrage","async-iterable","binance","bitmex","bitmex-api","bitmexbot","btc","ccxt","cryptocurrency-api","cryptocurrency-exchanges","deribit","eth","exchange","historical-data","market-data","orderbook","orderbook-tick-data","real-time","trading","websocket"],"created_at":"2024-08-06T06:01:05.179Z","updated_at":"2025-04-14T22:11:32.449Z","avatar_url":"https://github.com/tardis-dev.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","websocket"],"sub_categories":[],"readme":"# tardis-dev\n\n[![Version](https://img.shields.io/npm/v/tardis-dev.svg)](https://www.npmjs.org/package/tardis-dev)\n[![Try on RunKit](https://badge.runkitcdn.com/tardis-dev.svg)](https://runkit.com/npm/tardis-dev)\n\n\u003cbr/\u003e\n\nNode.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/api/node-js#seamless-switching-between-real-time-streaming-and-historical-market-data-replay) or [computing derived data locally](https://docs.tardis.dev/api/node-js#computing-derived-data-locally).\n\n\u003cbr/\u003e\n\n```javascript\nconst { replayNormalized, normalizeTrades, normalizeBookChanges } = require('tardis-dev')\n\nconst messages = replayNormalized(\n  {\n    exchange: 'bitmex',\n    symbols: ['XBTUSD', 'ETHUSD'],\n    from: '2019-05-01',\n    to: '2019-05-02'\n  },\n  normalizeTrades,\n  normalizeBookChanges\n)\n\nfor await (const message of messages) {\n  console.log(message)\n}\n```\n\n[![Try this code live on RunKit](https://img.shields.io/badge/-Try%20this%20code%20live%20on%20RunKit-c?color=5558be)](https://runkit.com/thad/tardis-dev-replay-market-data-normalized)\n\n\u003cbr/\u003e\n\u003cbr/\u003e\n\n## Features\n\n- historical tick-level [market data replay](https://docs.tardis.dev/api/node-js#replaying-historical-market-data) backed by [tardis.dev HTTP API](https://docs.tardis.dev/api/http#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\n\n  \u003cbr/\u003e\n\n- consolidated [real-time data streaming API](https://docs.tardis.dev/api/node-js#streaming-real-time-market-data) connecting directly to exchanges' public WebSocket APIs\n\n\u003cbr/\u003e\n\n- support for both [exchange-native](https://docs.tardis.dev/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format) and [normalized market data](https://docs.tardis.dev/faq/data#what-is-a-difference-between-exchange-native-and-normalized-data-format) formats (unified format for accessing market data across all supported exchanges — normalized trades, order book and ticker data)\n\n\u003cbr/\u003e\n\n- [seamless switching between real-time streaming and historical market data replay](https://docs.tardis.dev/api/node-js#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\n\n\u003cbr/\u003e\n\n- transparent historical local data caching \\(cached data is stored on disk in compressed GZIP format and decompressed on demand when reading the data\\)\n\n\u003cbr/\u003e\n\n- support for top cryptocurrency exchanges: BitMEX, Deribit, Binance, FTX, OKEx, Huobi Futures, Huobi Global, Bitfinex, Coinbase Pro, Kraken Futures, Kraken, Bitstamp, Gemini, Poloniex, Bybit, Phemex, Delta Exchange, FTX US, Binance US, Gate.io, OKCoin, bitFlyer, HitBTC, CoinFLEX (2.0), Binance Jersey and more\n\n\u003cbr/\u003e\n\n- automatic closed connections and stale connections reconnection logic for real-time streams\n\n\u003cbr/\u003e\n\n- [combining multiple exchanges feeds into single one](https://docs.tardis.dev/api/node-js#combining-data-streams) via [`combine`](https://docs.tardis.dev/api/node-js#combine-iterators) helper function — synchronized historical market data replay and consolidated real-time data streaming from multiple exchanges\n\n\u003cbr/\u003e\n\n- [computing derived data locally](https://docs.tardis.dev/api/node-js#computing-derived-data-locally) like order book imbalance, custom trade bars, book snapshots and more via [`compute`](https://docs.tardis.dev/api/node-js#compute-iterator-computables) helper function and `computables`, e.g., volume based bars, top 20 levels order book snapshots taken every 10 ms etc.\n\n\u003cbr/\u003e\n\n- [full limit order book reconstruction](https://docs.tardis.dev/api/node-js#limit-order-book-reconstruction) both for real-time and historical data via `OrderBook` object\n\n\u003cbr/\u003e\n\n- fast and lightweight architecture — low memory footprint and no heavy in-memory buffering\n\n\u003cbr/\u003e\n\n- [extensible mapping logic](https://docs.tardis.dev/api/node-js#modifying-built-in-and-adding-custom-normalizers) that allows adjusting normalized formats for specific needs\n\n\u003cbr/\u003e\n\n- [built-in TypeScript support](https://docs.tardis.dev/api/node-js#usage-with-typescript)\n\n\u003cbr/\u003e\n\u003cbr/\u003e\n\u003cbr/\u003e\n\n## Installation\n\nRequires Node.js v12+ installed.\n\n```bash\nnpm install tardis-dev --save\n```\n\n\u003cbr/\u003e\n\u003cbr/\u003e\n\n## Documentation\n\n### [See official docs](https://docs.tardis.dev/api/node-js).\n\n\u003cbr/\u003e\n\u003cbr/\u003e\n\n## Examples\n\n### Real-time spread across multiple exchanges\n\nExample 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`).\n\n```javascript\nconst tardis = require('tardis-dev')\nconst { streamNormalized, normalizeBookChanges, combine, compute, computeBookSnapshots } = tardis\n\nconst exchangesToStream = [\n  { exchange: 'bitmex', symbols: ['XBTUSD'] },\n  { exchange: 'deribit', symbols: ['BTC-PERPETUAL'] },\n  { exchange: 'cryptofacilities', symbols: ['PI_XBTUSD'] }\n]\n// for each specified exchange call streamNormalized for it\n// so we have multiple real-time streams for all specified exchanges\nconst realTimeStreams = exchangesToStream.map((e) =\u003e {\n  return streamNormalized(e, normalizeBookChanges)\n})\n\n// combine all real-time message streams into one\nconst messages = combine(...realTimeStreams)\n\n// create book snapshots with depth1 that are produced\n// every time best bid/ask info is changed\n// effectively computing real-time quotes\nconst realTimeQuoteComputable = computeBookSnapshots({\n  depth: 1,\n  interval: 0,\n  name: 'realtime_quote'\n})\n\n// compute real-time quotes for combines real-time messages\nconst messagesWithQuotes = compute(messages, realTimeQuoteComputable)\n\nconst spreads = {}\n\n// print spreads info every 100ms\nsetInterval(() =\u003e {\n  console.clear()\n  console.log(spreads)\n}, 100)\n\n// update spreads info real-time\nfor await (const message of messagesWithQuotes) {\n  if (message.type === 'book_snapshot') {\n    spreads[message.exchange] = {\n      spread: message.asks[0].price - message.bids[0].price,\n      bestBid: message.bids[0],\n      bestAsk: message.asks[0]\n    }\n  }\n}\n```\n\n[![Try this code live on RunKit](https://img.shields.io/badge/-Try%20this%20code%20live%20on%20RunKit-c?color=5558be)](https://runkit.com/thad/tardis-dev-real-time-spread-for-multiple-exchanges)\n\n\u003cbr/\u003e\n\n### Seamless switching between real-time streaming and historical market data replay\n\nExample 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.\n\n```javascript\nconst tardis = require('tardis-dev')\nconst { replayNormalized, streamNormalized, normalizeTrades, compute, computeTradeBars } = tardis\n\nconst historicalMessages = replayNormalized(\n  {\n    exchange: 'bitmex',\n    symbols: ['XBTUSD'],\n    from: '2019-08-01',\n    to: '2019-08-02'\n  },\n  normalizeTrades\n)\n\nconst realTimeMessages = streamNormalized(\n  {\n    exchange: 'bitmex',\n    symbols: ['XBTUSD']\n  },\n  normalizeTrades\n)\n\nasync function produceVolumeBasedTradeBars(messages) {\n  const withVolumeTradeBars = compute(\n    messages,\n    computeTradeBars({\n      kind: 'volume',\n      interval: 100 * 1000 // aggregate by 100k contracts volume\n    })\n  )\n\n  for await (const message of withVolumeTradeBars) {\n    if (message.type === 'trade_bar') {\n      console.log(message.name, message)\n    }\n  }\n}\n\nawait produceVolumeBasedTradeBars(historicalMessages)\n\n// or for real time data\n//  await produceVolumeBasedTradeBars(realTimeMessages)\n```\n\n[![Try this code live on RunKit](https://img.shields.io/badge/-Try%20this%20code%20live%20on%20RunKit-c?color=5558be)](https://runkit.com/thad/tardis-dev-seamless-switching-between-real-time-streaming-and-historical-market-data-replay)\n\n\u003cbr/\u003e\n\n### Stream real-time market data in exchange native data format\n\n```javascript\nconst { stream } = require('tardis-dev')\n\nconst messages = stream({\n  exchange: 'bitmex',\n  filters: [\n    { channel: 'trade', symbols: ['XBTUSD'] },\n    { channel: 'orderBookL2', symbols: ['XBTUSD'] }\n  ]\n})\n\nfor await (const message of messages) {\n  console.log(message)\n}\n```\n\n[![Try this code live on RunKit](https://img.shields.io/badge/-Try%20this%20code%20live%20on%20RunKit-b?color=5558be)](https://runkit.com/thad/tardis-dev-stream-market-data)\n\n\u003cbr/\u003e\n\n### Replay historical market data in exchange native data format\n\n```javascript\nconst { replay } = require('tardis-dev')\n\nconst messages = replay({\n  exchange: 'bitmex',\n  filters: [\n    { channel: 'trade', symbols: ['XBTUSD'] },\n    { channel: 'orderBookL2', symbols: ['XBTUSD'] }\n  ],\n  from: '2019-05-01',\n  to: '2019-05-02'\n})\n\nfor await (const message of messages) {\n  console.log(message)\n}\n```\n\n[![Try this code live on RunKit](https://img.shields.io/badge/-Try%20this%20code%20live%20on%20RunKit-b?color=5558be)](https://runkit.com/thad/tardis-dev-replay-market-data)\n\n\u003cbr/\u003e\n\u003cbr/\u003e\n\n## See the [tardis-dev docs](https://docs.tardis.dev/api/node-js) for more examples.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftardis-dev%2Ftardis-node","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftardis-dev%2Ftardis-node","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftardis-dev%2Ftardis-node/lists"}