#market-data #data-exchange #backtesting #trading #investment #stock #crypto

barter-data

High performance & normalised WebSocket intergration for leading cryptocurrency exchanges - batteries included

51 releases

0.9.1 Jan 4, 2025
0.9.0 Oct 20, 2024
0.8.1 Jul 8, 2024
0.7.0 Apr 16, 2023
0.2.10 Nov 27, 2021

#7 in #backtesting

Download history 79/week @ 2024-09-25 15/week @ 2024-10-02 22/week @ 2024-10-09 148/week @ 2024-10-16 35/week @ 2024-10-23 32/week @ 2024-10-30 32/week @ 2024-11-06 3/week @ 2024-11-13 11/week @ 2024-11-20 19/week @ 2024-11-27 20/week @ 2024-12-04 23/week @ 2024-12-11 10/week @ 2024-12-18 151/week @ 2025-01-01 35/week @ 2025-01-08

199 downloads per month
Used in barter

MIT license

645KB
13K SLoC

Barter-Data

A high-performance WebSocket integration library for streaming public market data from leading cryptocurrency exchanges - batteries included. It is:

  • Easy: Barter-Data's simple StreamBuilder interface allows for easy & quick setup (see example below!).
  • Normalised: Barter-Data's unified interface for consuming public WebSocket data means every Exchange returns a normalised data model.
  • Real-Time: Barter-Data utilises real-time WebSocket integrations enabling the consumption of normalised tick-by-tick data.
  • Extensible: Barter-Data is highly extensible, and therefore easy to contribute to with coding new integrations!

See: Barter, Barter-Instrument, Barter-Execution & Barter-Integration for comprehensive documentation of other Barter libraries.

Crates.io MIT licensed Discord chat

API Documentation | Chat

Overview

Barter-Data is a high-performance WebSocket integration library for streaming public market data from leading cryptocurrency exchanges. It presents an easy-to-use and extensible set of interfaces that can deliver normalised exchange data in real-time.

From a user perspective, the major component is the StreamBuilder structures that assists in initialising an arbitrary number of exchange MarketStreams using input Subscriptions. Simply build your dream set of MarketStreams and Barter-Data will do the rest!

Supported Exchange Subscriptions

Exchange Constructor Code InstrumentKinds SubscriptionKinds
BinanceSpot BinanceSpot::default() Spot PublicTrades
OrderBooksL1
OrderBooksL2
BinanceFuturesUsd BinanceFuturesUsd::default() Perpetual PublicTrades
OrderBooksL1
OrderBooksL2
Bitfinex Bitfinex Spot PublicTrades
Bitmex Bitmex Perpetual PublicTrades
BybitSpot BybitSpot::default() Spot PublicTrades
BybitPerpetualsUsd BybitPerpetualsUsd::default() Perpetual PublicTrades
Coinbase Coinbase Spot PublicTrades
GateioSpot GateioSpot::default() Spot PublicTrades
GateioFuturesUsd GateioFuturesUsd::default() Future PublicTrades
GateioFuturesBtc GateioFuturesBtc::default() Future PublicTrades
GateioPerpetualsUsd GateioPerpetualsUsd::default() Perpetual PublicTrades
GateioPerpetualsBtc GateioPerpetualsBtc::default() Perpetual PublicTrades
GateioOptionsBtc GateioOptions::default() Option PublicTrades
Kraken Kraken Spot PublicTrades
OrderBooksL1
Okx Okx Spot
Future
Perpetual
Option
PublicTrades

Examples

See barter-data-rs/examples for a more comprehensive selection of examples!

Multi Exchange Public Trades

use barter_data::{
    exchange::{
        binance::{futures::BinanceFuturesUsd, spot::BinanceSpot},
        bitmex::Bitmex,
        bybit::{futures::BybitPerpetualsUsd, spot::BybitSpot},
        coinbase::Coinbase,
        gateio::{
            option::GateioOptions,
            perpetual::{GateioPerpetualsBtc, GateioPerpetualsUsd},
            spot::GateioSpot,
        },
        okx::Okx,
    },
    streams::{Streams, reconnect::stream::ReconnectingStream},
    subscription::trade::PublicTrades,
};
use barter_integration::model::instrument::kind::{
    FutureContract, InstrumentKind, OptionContract, OptionExercise, OptionKind,
};
use chrono::{TimeZone, Utc};
use futures::StreamExt;

#[tokio::main]
async fn main() {
    // Initialise PublicTrades Streams for various exchanges
    // '--> each call to StreamBuilder::subscribe() creates a separate WebSocket connection
    let streams = Streams::<PublicTrades>::builder()
        .subscribe([
            (BinanceSpot::default(), "btc", "usdt", InstrumentKind::Spot, PublicTrades),
            (BinanceSpot::default(), "eth", "usdt", InstrumentKind::Spot, PublicTrades),
        ])
        .subscribe([
            (BinanceFuturesUsd::default(), "btc", "usdt", InstrumentKind::Perpetual, PublicTrades),
            (BinanceFuturesUsd::default(), "eth", "usdt", InstrumentKind::Perpetual, PublicTrades),
        ])
        .subscribe([
            (Coinbase, "btc", "usd", InstrumentKind::Spot, PublicTrades),
            (Coinbase, "eth", "usd", InstrumentKind::Spot, PublicTrades),
        ])
        .subscribe([
            (GateioSpot::default(), "btc", "usdt", InstrumentKind::Spot, PublicTrades),
        ])
        .subscribe([
            (GateioPerpetualsUsd::default(), "btc", "usdt", InstrumentKind::Perpetual, PublicTrades),
        ])
        .subscribe([
            (GateioPerpetualsBtc::default(), "btc", "usd", InstrumentKind::Perpetual, PublicTrades),
        ])
        .subscribe([
            (GateioOptions::default(), "btc", "usdt", InstrumentKind::Option(put_contract()), PublicTrades),
        ])
        .subscribe([
            (Okx, "btc", "usdt", InstrumentKind::Spot, PublicTrades),
            (Okx, "btc", "usdt", InstrumentKind::Perpetual, PublicTrades),
            (Okx, "btc", "usd", InstrumentKind::Future(future_contract()), PublicTrades),
            (Okx, "btc", "usd", InstrumentKind::Option(call_contract()), PublicTrades),
        ])
        .subscribe([
            (BybitSpot::default(), "btc", "usdt", InstrumentKind::Spot, PublicTrades),
            (BybitSpot::default(), "eth", "usdt", InstrumentKind::Spot, PublicTrades),
        ])
        .subscribe([
            (BybitPerpetualsUsd::default(), "btc", "usdt", InstrumentKind::Perpetual, PublicTrades),
        ])
        .subscribe([
            (Bitmex, "xbt", "usd", InstrumentKind::Perpetual, PublicTrades)
        ])
        .init()
        .await
        .unwrap();

    // Select and merge every exchange Stream using futures_util::stream::select_all
    // Note: use `Streams.select(ExchangeId)` to interact with individual exchange streams!
    let mut joined_stream = streams
        .select_all()
        .with_error_handler(|error| println!(format!("MarketStream generated error: {error:?}")));

    while let Some(event) = joined_stream.next().await {
        println!("{event:?}");
    }
}

Getting Help

Firstly, see if the answer to your question can be found in the API Documentation. If the answer is not there, I'd be happy to help via Chat
and try answer your question via Discord.

Support Barter Development

Help us advance Barter's capabilities by becoming a sponsor (or supporting me with a tip!).

Your contribution will allow me to dedicate more time to Barter, accelerating feature development and improvements.

Please email justastream.code@gmail.com for all inquiries

Please see here for more information.

Contributing

Thanks in advance for helping to develop the Barter ecosystem! Please do get hesitate to get touch via the Discord Chat to discuss development, new features, and the future roadmap.

Adding A New Exchange Connector

  1. Add a new Connector trait implementation in src/exchange/<exchange_name>.mod.rs (eg/ see exchange::okx::Okx).
  2. Follow on from "Adding A New Subscription Kind For An Existing Exchange Connector" below!

Adding A New SubscriptionKind For An Existing Exchange Connector

  1. Add a new SubscriptionKind trait implementation in src/subscription/<sub_kind_name>.rs (eg/ see subscription::trade::PublicTrades).
  2. Define the SubscriptionKind::Event data model (eg/ see subscription::trade::PublicTrade).
  3. Define the MarketStream type the exchange Connector will initialise for the new SubscriptionKind:
    ie/ impl StreamSelector<SubscriptionKind> for <ExistingExchangeConnector> { ... }
  4. Try to compile and follow the remaining steps!
  5. Add a barter-data-rs/examples/<sub_kind_name>_streams.rs example in the standard format :)

Licence

This project is licensed under the MIT license.

Contribution License Agreement

Any contribution you intentionally submit for inclusion in Barter workspace crates shall be:

  1. Licensed under MIT
  2. Subject to all disclaimers and limitations of liability stated below
  3. Provided without any additional terms or conditions
  4. Submitted with the understanding that the educational-only purpose and risk warnings apply

By submitting a contribution, you certify that you have the right to do so under these terms.

PLEASE READ THIS DISCLAIMER CAREFULLY BEFORE USING THE SOFTWARE. BY ACCESSING OR USING THE SOFTWARE, YOU ACKNOWLEDGE AND AGREE TO BE BOUND BY THE TERMS HEREIN.

  1. EDUCATIONAL PURPOSE This software and related documentation ("Software") are provided solely for educational and research purposes. The Software is not intended, designed, tested, verified or certified for commercial deployment, live trading, or production use of any kind.

  2. NO FINANCIAL ADVICE Nothing contained in the Software constitutes financial, investment, legal, or tax advice. No aspect of the Software should be relied upon for trading decisions or financial planning. Users are strongly advised to consult qualified professionals for investment guidance specific to their circumstances.

  3. ASSUMPTION OF RISK Trading in financial markets, including but not limited to cryptocurrencies, securities, derivatives, and other financial instruments, carries substantial risk of loss. Users acknowledge that: a) They may lose their entire investment; b) Past performance does not indicate future results; c) Hypothetical or simulated performance results have inherent limitations and biases.

  4. DISCLAIMER OF WARRANTIES THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE AUTHORS AND COPYRIGHT HOLDERS EXPRESSLY DISCLAIM ALL WARRANTIES, INCLUDING BUT NOT LIMITED TO: a) MERCHANTABILITY b) FITNESS FOR A PARTICULAR PURPOSE c) NON-INFRINGEMENT d) ACCURACY OR RELIABILITY OF RESULTS e) SYSTEM INTEGRATION f) QUIET ENJOYMENT

  5. LIMITATION OF LIABILITY IN NO EVENT SHALL THE AUTHORS, COPYRIGHT HOLDERS, CONTRIBUTORS, OR ANY AFFILIATED PARTIES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING BUT NOT LIMITED TO PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  6. REGULATORY COMPLIANCE The Software is not registered with, endorsed by, or approved by any financial regulatory authority. Users are solely responsible for: a) Determining whether their use complies with applicable laws and regulations b) Obtaining any required licenses, permits, or registrations c) Meeting any regulatory obligations in their jurisdiction

  7. INDEMNIFICATION Users agree to indemnify, defend, and hold harmless the authors, copyright holders, and any affiliated parties from and against any claims, liabilities, damages, losses, and expenses arising from their use of the Software.

  8. ACKNOWLEDGMENT BY USING THE SOFTWARE, USERS ACKNOWLEDGE THAT THEY HAVE READ THIS DISCLAIMER, UNDERSTOOD IT, AND AGREE TO BE BOUND BY ITS TERMS AND CONDITIONS.

THE ABOVE LIMITATIONS MAY NOT APPLY IN JURISDICTIONS THAT DO NOT ALLOW THE EXCLUSION OF CERTAIN WARRANTIES OR LIMITATIONS OF LIABILITY.

Dependencies

~12–27MB
~402K SLoC