brokapi_bcs/map/
instrument.rs1use brokapi_bcs_protocol::http::models::{
4 InstrumentInfo, TradingParamsSnapshot, TradingStatusResponse,
5};
6use brokapi_core::{
7 Instrument, InstrumentId, InstrumentKey, InstrumentKind, Money, Price, Qty,
8 TradingAvailability, TradingParams, TradingStatus,
9};
10
11use super::instrument_id_ticker;
12
13pub fn map_trading_params(snapshot: &TradingParamsSnapshot) -> TradingParams {
18 let instrument = instrument_id_ticker(&snapshot.ticker, &snapshot.class_code);
19 TradingParams {
20 instrument,
21 lot_size: Qty::new(snapshot.lot_size),
22 min_qty: Qty::new(snapshot.lot_size),
23 price_step: Price::new(snapshot.price_step),
24 price_step_value: Money::new(snapshot.price_step_value),
25 currency: snapshot.currency.clone(),
26 }
27}
28
29pub fn map_instrument_info(info: &InstrumentInfo, class_code: &str) -> Instrument {
38 let instrument = instrument_id_ticker(&info.ticker, class_code);
39 Instrument {
40 id: instrument,
41 name: info
42 .display_name
43 .clone()
44 .or_else(|| info.short_name.clone())
45 .unwrap_or_else(|| info.ticker.clone()),
46 isin: info.isin.clone(),
47 kind: map_kind(info.instrument_type.as_deref()),
48 currency: info
49 .trading_currency
50 .clone()
51 .unwrap_or_else(|| "RUB".into()),
52 exchange: info
53 .boards
54 .iter()
55 .find(|b| b.class_code == class_code)
56 .map(|b| b.exchange.clone())
57 .unwrap_or_else(|| "MOEX".into()),
58 }
59}
60
61pub fn map_trading_status(
82 ticker: &str,
83 class_code: &str,
84 resp: &TradingStatusResponse,
85) -> TradingStatus {
86 let instrument = instrument_id_ticker(ticker, class_code);
87 let availability = if resp.trading_session_status.eq_ignore_ascii_case("OPEN") {
88 TradingAvailability::Open
89 } else if resp.trading_session_status.eq_ignore_ascii_case("CLOSE") {
90 TradingAvailability::Closed
91 } else {
92 TradingAvailability::Unknown
93 };
94 TradingStatus {
95 instrument,
96 availability,
97 reason: Some(resp.trading_session_type.clone()),
98 ts: None,
99 }
100}
101
102fn map_kind(raw: Option<&str>) -> InstrumentKind {
103 match raw {
104 Some(s) if s.contains("STOCK") => InstrumentKind::Stock,
105 Some(s) if s.contains("BOND") => InstrumentKind::Bond,
106 Some(s) if s.contains("FUTURE") => InstrumentKind::Future,
107 Some(s) if s.contains("OPTION") => InstrumentKind::Option,
108 Some(s) if s.contains("ETF") => InstrumentKind::Etf,
109 Some(s) if s.contains("FUND") => InstrumentKind::MutualFund,
110 Some(s) if s.contains("CURRENCY") => InstrumentKind::Currency,
111 _ => InstrumentKind::Other,
112 }
113}
114
115pub fn instrument_from_native(id: &InstrumentId) -> InstrumentKey {
117 id.key.clone()
118}