binance_client/http_api_v3/data/exchange_info/symbol/
mod.rs

1//!
2//! The exchange info symbol.
3//!
4
5pub mod filter;
6pub mod status;
7
8use rust_decimal::Decimal;
9use serde::Deserialize;
10
11use crate::http_api_v3::data::order_type::OrderType;
12use crate::http_api_v3::data::permission::Permission;
13
14use self::filter::Filter;
15use self::status::Status;
16
17///
18/// The trading symbol data.
19///
20#[derive(Debug, Deserialize, Clone)]
21#[serde(rename_all = "camelCase")]
22pub struct Symbol {
23    /// The symbol name.
24    pub symbol: String,
25    /// The symbol status on the exchange.
26    pub status: Status,
27    /// The secondary token in the trading pair.
28    pub base_asset: String,
29    /// The generic number of fractional digits in the secondary token.
30    /// Do not use for the price scale!
31    pub base_asset_precision: usize,
32    /// The primary token in the trading pair.
33    pub quote_asset: String,
34    /// The generic number of fractional digits in the primary token.
35    /// Do not use for the price scale!
36    pub quote_precision: usize,
37    /// The order types allowed for the symbol.
38    pub order_types: Vec<OrderType>,
39    /// If iceberd order is allowed for the symbol.
40    pub iceberg_allowed: bool,
41    /// The conditions Binance puts on the symbol.
42    pub filters: Vec<Filter>,
43    /// The allowed trading methods like spot, margin, etc.
44    pub permissions: Vec<Permission>,
45}
46
47impl Symbol {
48    ///
49    /// If the symbol is active and can be normally traded.
50    ///
51    pub fn is_trading(&self) -> bool {
52        matches!(self.status, Status::Trading)
53    }
54
55    ///
56    /// If margin trading is allowed for the symbol.
57    ///
58    pub fn has_margin(&self) -> bool {
59        self.permissions.contains(&Permission::Margin)
60    }
61
62    ///
63    /// The number of fractional digits in the symbol price.
64    ///
65    /// E.g. `0.000256` has `6` fractional digits.
66    /// E.g. `0.42` has `2` fractional digits.
67    ///
68    pub fn price_precision(&self) -> Option<u32> {
69        for filter in self.filters.iter() {
70            if let Filter::PriceFilter { tick_size, .. } = filter {
71                let mut scale = crate::r#const::PRECISION_DEFAULT;
72                let mut tick_size_check = Decimal::new(1, scale);
73                while *tick_size > tick_size_check && scale > 0 {
74                    tick_size_check *= Decimal::new(10, 0);
75                    scale -= 1;
76                }
77                return Some(scale);
78            }
79        }
80        None
81    }
82
83    ///
84    /// The number of fractional digits in the symbol quantity.
85    ///
86    pub fn quantity_precision(&self) -> Option<u32> {
87        for filter in self.filters.iter() {
88            if let Filter::LotSize { step_size, .. } = filter {
89                let mut scale = crate::r#const::PRECISION_DEFAULT;
90                let mut step_size_check = Decimal::new(1, scale);
91                while *step_size > step_size_check && scale > 0 {
92                    step_size_check *= Decimal::new(10, 0);
93                    scale -= 1;
94                }
95                return Some(scale);
96            }
97        }
98        None
99    }
100}