Skip to main content

brokapi_tbank/
lib.rs

1//! T-Bank (T-Invest) connectors: `MarketDataConnector` + `UserDataConnector` over gRPC.
2//!
3//! This crate is the connector layer for T-Bank. It sits on the protocol layer `brokapi-tbank-protocol`
4//! (generated gRPC client, endpoints, token) and implements the capability traits of `brokapi-core`,
5//! so code written against those traits also works with the other brokers. Timing, rate limits and
6//! stream supervision come from `brokapi-runtime` and `brokapi-sansio`.
7//!
8//! - [`MarketDataConnector`] - order book, trades, quotes, candles, instrument directory. Not tied to
9//!   an account.
10//! - [`UserDataConnector`] - orders, own trades, portfolio and stop orders of ONE account
11//!   (`account_id` in the config). Several accounts need several connectors with one token.
12//! - [`TbankRaw`] (`connector.raw()`) - any other method of the API, with the connector's token,
13//!   endpoint and rate limiter.
14//! - Rate limits are per user: give every connector of one user the same `Arc<BrokerLimiter>`
15//!   (see [`limits::default_limits`]).
16//!
17//! T-Bank specifics worth knowing before you trade:
18//!
19//! - Quantities are in UNITS of the instrument (shares, bonds, contracts), as at every broker. T-Bank counts in
20//!   lots, and the connectors convert both ways (see [`lots`]). An order that is not a whole number of lots is
21//!   refused before it is sent. Prices are per one instrument.
22//! - A trading command that gets no answer is never repeated. The result is `Error::Unknown` and the
23//!   caller checks the order first.
24//! - `reconcile` must succeed once before the first order. It opens the command gate.
25//!
26//! The full guide is in the book: <https://brokapi.ru/docs/>.
27//!
28//! # Examples
29//!
30//! The example starts the market data connector against the in-process mock of the broker and reads
31//! an order book. Nothing touches the network.
32//!
33//! ```
34//! use brokapi_core::{InstrumentId, InstrumentKey, NativeId, OrderBook, OrderBookSource, ShutdownMode};
35//! use brokapi_runtime::BrokerLimiter;
36//! use brokapi_tbank::limits::default_limits;
37//! use brokapi_tbank::{MarketDataConfig, MarketDataConnector};
38//! use tokio::sync::mpsc;
39//! # use brokapi_mocks::tbank::{MockServer, TOKEN};
40//! # use brokapi_tbank_protocol::TbankConfig;
41//!
42//! # #[tokio::main(flavor = "current_thread")]
43//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
44//! # let server = MockServer::start(Default::default()).await;
45//! # let cfg = TbankConfig::for_mock(TOKEN, &server.endpoint);
46//! // In real code: `let cfg = brokapi_tbank_protocol::TbankConfig::sandbox("t.your-token");`
47//! let (events_tx, _events) = mpsc::channel(256);
48//! let limiter = BrokerLimiter::new(&default_limits());
49//! let md = MarketDataConnector::start(MarketDataConfig::new(cfg, "tbank-md"), limiter, events_tx).await?;
50//!
51//! let sber = InstrumentId::new(InstrumentKey::new("SBER", "TQBR"), NativeId::Uid("uid-sber".into()));
52//! let OrderBook::Snapshot { bids, asks, .. } = md.order_book(&sber, 5).await? else {
53//!     panic!("T-Bank answers a snapshot")
54//! };
55//! assert!(!bids.is_empty() && !asks.is_empty());
56//!
57//! md.shutdown(ShutdownMode::Immediate).await;
58//! # Ok(())
59//! # }
60//! ```
61//!
62//! For trading see [`UserDataConnector`]: it has the full place, cancel and refusal example.
63
64#![warn(missing_docs)]
65
66pub mod cid;
67pub mod config;
68pub mod core;
69pub mod emit;
70pub mod error;
71pub mod ids;
72pub mod limits;
73pub mod lots;
74pub mod map;
75pub mod md;
76pub mod raw;
77pub mod stream;
78pub mod ud;
79pub mod util;
80
81pub use cid::TbankCidCodec;
82pub use config::{MarketDataConfig, UserDataConfig};
83pub use core::{MdCore, MdFrame, UdCore, UdFrame};
84pub use md::MarketDataConnector;
85pub use raw::TbankRaw;
86pub use ud::UserDataConnector;