Skip to main content

rustrade_instrument/
lib.rs

1#![forbid(unsafe_code)]
2#![deny(
3    clippy::unwrap_used,
4    clippy::expect_used,
5    clippy::cast_possible_truncation,
6    clippy::cast_sign_loss
7)]
8#![warn(
9    unused,
10    clippy::cognitive_complexity,
11    unused_crate_dependencies,
12    unused_extern_crates,
13    clippy::unused_self,
14    clippy::useless_let_if_seq,
15    missing_debug_implementations,
16    rust_2018_idioms
17)]
18#![allow(clippy::type_complexity, clippy::too_many_arguments, type_alias_bounds)]
19
20//! # Barter-Instrument
21//! Barter-Instrument contains core Exchange, Instrument and Asset data structures and associated utilities.
22//!
23//! ## Examples
24//! For a comprehensive collection of examples, see the Barter core Engine /examples directory.
25
26use derive_more::Constructor;
27use serde::{Deserialize, Serialize};
28use std::fmt::{Display, Formatter};
29
30/// Defines a global [`ExchangeId`](exchange::ExchangeId) enum covering all exchanges.
31pub mod exchange;
32
33/// [`Asset`](asset::Asset) related data structures.
34///
35/// eg/ `AssetKind`, `AssetNameInternal`, etc.
36pub mod asset;
37
38/// [`Instrument`](instrument::Instrument) related data structures.
39///
40/// eg/ `InstrumentKind`, `OptionContract``, etc.
41pub mod instrument;
42
43/// Indexed collection of exchanges, assets, and instruments. Provides a builder utility for
44/// indexing non-indexed collections.
45pub mod index;
46
47/// Interactive Brokers support types (behind `ibkr` feature).
48#[cfg(feature = "ibkr")]
49pub mod ibkr;
50
51/// A keyed value.
52///
53/// eg/ Keyed<InstrumentIndex, Instrument>
54#[derive(
55    Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize, Constructor,
56)]
57pub struct Keyed<Key, Value> {
58    pub key: Key,
59    pub value: Value,
60}
61
62impl<Key, Value> AsRef<Value> for Keyed<Key, Value> {
63    fn as_ref(&self) -> &Value {
64        &self.value
65    }
66}
67
68impl<Key, Value> Display for Keyed<Key, Value>
69where
70    Key: Display,
71    Value: Display,
72{
73    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
74        write!(f, "{}, {}", self.key, self.value)
75    }
76}
77
78/// Instrument Underlying containing a base and quote asset.
79///
80/// eg/ Underlying { base: "btc", quote: "usdt" }
81#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize)]
82pub struct Underlying<AssetKey> {
83    pub base: AssetKey,
84    pub quote: AssetKey,
85}
86
87impl<AssetKey> Underlying<AssetKey> {
88    pub fn new<A>(base: A, quote: A) -> Self
89    where
90        A: Into<AssetKey>,
91    {
92        Self {
93            base: base.into(),
94            quote: quote.into(),
95        }
96    }
97}
98
99/// [`Side`] of a trade or position - Buy or Sell.
100#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Deserialize, Serialize)]
101pub enum Side {
102    #[serde(alias = "buy", alias = "BUY", alias = "b")]
103    Buy,
104    #[serde(alias = "sell", alias = "SELL", alias = "s")]
105    Sell,
106}
107
108impl Display for Side {
109    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
110        write!(
111            f,
112            "{}",
113            match self {
114                Side::Buy => "buy",
115                Side::Sell => "sell",
116            }
117        )
118    }
119}
120
121pub mod test_utils {
122    use crate::{
123        Underlying,
124        asset::{
125            Asset, ExchangeAsset,
126            name::{AssetNameExchange, AssetNameInternal},
127        },
128        exchange::ExchangeId,
129        instrument::{
130            Instrument,
131            kind::InstrumentKind,
132            name::{InstrumentNameExchange, InstrumentNameInternal},
133            quote::InstrumentQuoteAsset,
134        },
135    };
136
137    pub fn exchange_asset(exchange: ExchangeId, symbol: &str) -> ExchangeAsset<Asset> {
138        ExchangeAsset {
139            exchange,
140            asset: asset(symbol),
141        }
142    }
143
144    pub fn asset(symbol: &str) -> Asset {
145        Asset {
146            name_internal: AssetNameInternal::from(symbol),
147            name_exchange: AssetNameExchange::from(symbol),
148        }
149    }
150
151    pub fn instrument(
152        exchange: ExchangeId,
153        base: &str,
154        quote: &str,
155    ) -> Instrument<ExchangeId, Asset> {
156        let name_exchange = InstrumentNameExchange::from(format!("{base}_{quote}"));
157        let name_internal =
158            InstrumentNameInternal::new_from_exchange(exchange, name_exchange.clone());
159        let base_asset = asset(base);
160        let quote_asset = asset(quote);
161
162        Instrument::new(
163            exchange,
164            name_internal,
165            name_exchange,
166            Underlying::new(base_asset, quote_asset),
167            InstrumentQuoteAsset::UnderlyingQuote,
168            InstrumentKind::Spot,
169            None,
170        )
171    }
172}