Expand description
Finam connectors: market data and user data over the Finam Trade API (gRPC).
This is the connector layer. It implements the shared traits of brokapi-core on top of the protocol
layer (brokapi-finam-protocol), the sans-io logic (brokapi-sansio) and the runtime pieces (brokapi-runtime:
rate limiter, command gate, shutdown).
| Type | Role | Traits |
|---|---|---|
MarketDataConnector | order books, trades, quotes, candles, instrument directory. Not tied to an account | OrderBookSource, MarketDataSource, InstrumentSource |
UserDataConnector | orders, stop orders, own trades, portfolio of ONE account | OrderExecutor, StopOrderExecutor, ExecutionSource, PortfolioSource |
FinamRaw | any other Finam method, with the connector’s token and rate limiter | none, see connector.raw() |
Things that are true for the whole crate:
- One user data connector is one account. To trade two accounts, start two connectors. They can
share one token manager (
FinamApiConfig::shared_tokens) and must share one rate limiter. - One rate limiter per Finam user. Finam documents one request quota for the whole API. The bundled
limits (
limits::default_limits) are meant to be shared by every connector of the user. - A place command that got no answer is never repeated. A timeout or a broken connection gives
Error::Unknown, because a repeat could create a second order. Ask the order state or callreconcileto learn what happened. - A rejected order is a final answer.
Error::Rejectedmeans the broker did not take the order. - Quantity is in pieces (units of the instrument), as everywhere in the Finam API and in this library, not in lots.
- Instruments are
SYMBOL@MIC(for exampleSBER@MISX), carried asNativeId::SymbolMic.
Finam has no sandbox. The examples in this documentation run against an in-process imitation of the
broker (brokapi-mocks). The imitation is written from the broker documentation. It does not prove how
the live broker behaves.
The book with the full guide: https://brokapi.ru/docs/
§Examples
Read an order book, then place a limit order far from the market and cancel it:
use brokapi_core::{
ClientOrderId, InstrumentId, InstrumentKey, NativeId, OrderBook, OrderBookSource, OrderExecutor,
OrderType, PlaceOrderRequest, Price, Qty, ShutdownMode, Side,
};
use brokapi_finam::limits::default_limits;
use brokapi_finam::{MarketDataConfig, MarketDataConnector, UserDataConfig, UserDataConnector};
use brokapi_runtime::BrokerLimiter;
use tokio::sync::mpsc;
// `api` holds your secret (and the endpoint of the real broker by default).
// One limiter per Finam user, shared by every connector.
let limiter = BrokerLimiter::new(&default_limits());
let (events, _rx) = mpsc::channel(256);
let md = MarketDataConnector::start(
MarketDataConfig::new(api.clone(), "finam-md"),
limiter.clone(),
events.clone(),
)
.await?;
let sber = InstrumentId::new(
InstrumentKey::new("SBER", "MISX"),
NativeId::SymbolMic { symbol: "SBER".into(), mic: "MISX".into() },
);
let book = md.order_book(&sber, 5).await?;
assert!(matches!(book, OrderBook::Snapshot { .. }));
let ud = UserDataConnector::start(
UserDataConfig::new(api, account, "finam-ud"),
limiter,
events,
)
.await?;
// Orders are refused until the connector is reconciled with the broker (empty ledger here).
ud.reconcile(&[]).await?;
let cid = ClientOrderId::new_v4();
let ack = ud
.place(PlaceOrderRequest {
cid,
instrument: sber,
side: Side::Buy,
order_type: OrderType::Limit,
qty: Qty::from(1),
price: Some(Price::from(1)),
})
.await?;
assert_eq!(ack.cid, cid);
ud.cancel(cid).await?;
md.shutdown(ShutdownMode::Immediate).await;
ud.shutdown(ShutdownMode::Immediate).await;connector.raw() (FinamRaw) reaches any other method of the API with the connector’s token,
endpoint and rate limiter.
Re-exports§
pub use cid::FinamCidCodec;pub use config::FinamApiConfig;pub use config::MarketDataConfig;pub use config::UserDataConfig;pub use config::api_config_from_env;pub use core::MdCore;pub use core::SubStatus;pub use core::UdCore;pub use md::MarketDataConnector;pub use raw::FinamRaw;pub use ud::UserDataConnector;
Modules§
- cid
- Client order id codec
- config
- Connector configuration: the credentials and endpoint shared by both roles (
FinamApiConfig) and the settings of each role (MarketDataConfig,UserDataConfig). - core
- Sans-io cores: frames in, normalized events out. No sockets, timers or tasks here.
- error
- Map protocol errors to public connector errors.
- index
- Client order id <-> Finam order id.
- limits
- Rate limits of the Finam connectors, loaded from the bundled
limits.toml. - map
- Translation between Finam protobuf messages and
brokapi-coretypes. - md
- Finam market data connector:
MarketDataConnector. - pump
- Event pump: frames -> core -> per-subscription buffers -> the client’s
Sender. - raw
- Direct access to any Finam Trade API method (“back door”): same secret and token manager, same
endpoint, same [
BrokerLimiter] as the connector it came from. - rpc
- Unary call helper: deadline, one re-auth retry for reads.
- stream
- One supervised gRPC server-stream: open, read, reopen with backoff.
- subs
- Subscription id generator (unique within one connector).
- ud
- Finam user data connector:
UserDataConnector. One connector = one account. - util
- Shared helpers: instrument ids, timestamps, decimals.