use super::order::Symbol;
use crate::api::quote_streaming::DxFeedSymbol;
use chrono::{DateTime, Utc};
use pretty_simple_display::{DebugPretty, DisplaySimple};
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fmt::Display;
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum InstrumentType {
Equity,
#[serde(rename = "Equity Option")]
EquityOption,
#[serde(rename = "Equity Offering")]
EquityOffering,
Future,
#[serde(rename = "Future Option")]
FutureOption,
Cryptocurrency,
}
impl Display for InstrumentType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
InstrumentType::Equity => write!(f, "Equity"),
InstrumentType::EquityOption => write!(f, "Equity Option"),
InstrumentType::EquityOffering => write!(f, "Equity Offering"),
InstrumentType::Future => write!(f, "Future"),
InstrumentType::FutureOption => write!(f, "Future Option"),
InstrumentType::Cryptocurrency => write!(f, "Cryptocurrency"),
}
}
}
#[derive(DebugPretty, DisplaySimple, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct EquityInstrumentInfo {
pub symbol: Symbol,
pub streamer_symbol: DxFeedSymbol,
}
#[derive(DebugPretty, DisplaySimple, Serialize, Deserialize, Clone)]
#[serde(rename_all = "kebab-case")]
pub struct TickSize {
pub value: String,
pub threshold: Option<String>,
}
#[derive(DebugPretty, DisplaySimple, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct EquityInstrument {
pub id: u64,
pub symbol: Symbol,
pub instrument_type: InstrumentType,
pub cusip: Option<String>,
pub short_description: String,
pub is_index: bool,
pub listed_market: String,
pub description: String,
pub lendability: Option<String>,
pub borrow_rate: Option<String>,
pub market_time_instrument_collection: String,
pub is_closing_only: bool,
pub is_options_closing_only: bool,
pub active: bool,
#[serde(default)]
pub is_fractional_quantity_eligible: bool,
pub is_illiquid: bool,
pub is_etf: bool,
pub bypass_manual_review: bool,
pub is_fraud_risk: bool,
pub streamer_symbol: DxFeedSymbol,
pub tick_sizes: Option<Vec<TickSize>>,
pub option_tick_sizes: Option<Vec<TickSize>>,
}
#[derive(DebugPretty, DisplaySimple, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct Strike {
#[serde(with = "rust_decimal::serde::arbitrary_precision")]
pub strike_price: Decimal,
pub call: Symbol,
pub call_streamer_symbol: DxFeedSymbol,
pub put: Symbol,
pub put_streamer_symbol: DxFeedSymbol,
}
#[derive(DebugPretty, DisplaySimple, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct Expiration {
pub expiration_type: String,
pub expiration_date: String,
pub days_to_expiration: u64,
pub settlement_type: String,
pub strikes: Vec<Strike>,
}
#[derive(DebugPretty, DisplaySimple, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct NestedOptionChain {
pub underlying_symbol: Symbol,
pub root_symbol: Symbol,
pub option_chain_type: String,
pub shares_per_contract: u64,
pub expirations: Vec<Expiration>,
}
#[derive(DebugPretty, DisplaySimple, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct EquityOption {
pub symbol: Symbol,
pub instrument_type: InstrumentType,
pub active: bool,
#[serde(with = "rust_decimal::serde::arbitrary_precision")]
pub strike_price: Decimal,
pub root_symbol: Symbol,
pub underlying_symbol: Symbol,
pub expiration_date: String,
pub exercise_style: String,
pub shares_per_contract: u64,
pub option_type: String,
pub option_chain_type: String,
pub expiration_type: String,
pub settlement_type: String,
pub stops_trading_at: String,
pub market_time_instrument_collection: String,
pub days_to_expiration: u64,
pub expires_at: String,
pub is_closing_only: bool,
pub streamer_symbol: DxFeedSymbol,
}
#[derive(DebugPretty, DisplaySimple, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct Future {
pub symbol: Symbol,
pub product_code: String,
pub contract_size: String,
pub tick_size: String,
pub notional_multiplier: String,
pub main_fraction: String,
pub sub_fraction: String,
pub display_factor: String,
pub last_trade_date: String,
pub expiration_date: String,
pub closing_only_date: Option<String>,
pub active: bool,
pub active_month: bool,
pub next_active_month: bool,
pub is_closing_only: bool,
pub stops_trading_at: String,
pub expires_at: String,
pub product_group: String,
pub exchange: String,
pub roll_target_symbol: Option<Symbol>,
pub streamer_exchange_code: String,
pub streamer_symbol: DxFeedSymbol,
pub back_month_first_calendar_symbol: bool,
pub is_tradeable: bool,
pub future_product: FutureProduct,
#[serde(default)]
pub tick_sizes: Vec<TickSize>,
#[serde(default)]
pub option_tick_sizes: Vec<TickSize>,
pub spread_tick_sizes: Option<Vec<HashMap<String, String>>>,
}
#[derive(DebugPretty, DisplaySimple, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct FutureProduct {
pub root_symbol: Symbol,
pub code: String,
pub description: String,
pub clearing_code: String,
pub clearing_exchange_code: String,
pub clearport_code: Option<String>,
pub legacy_code: Option<String>,
pub exchange: String,
pub legacy_exchange_code: Option<String>,
pub product_type: String,
pub listed_months: Vec<String>,
pub active_months: Vec<String>,
pub notional_multiplier: String,
pub tick_size: String,
pub display_factor: String,
pub streamer_exchange_code: String,
pub small_notional: bool,
pub back_month_first_calendar_symbol: bool,
pub first_notice: bool,
pub cash_settled: bool,
pub security_group: String,
pub market_sector: String,
pub roll: FutureRoll,
}
#[derive(DebugPretty, DisplaySimple, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct FutureRoll {
pub name: String,
pub active_count: u32,
pub cash_settled: bool,
pub business_days_offset: u32,
pub first_notice: bool,
}
#[derive(DebugPretty, DisplaySimple, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct FutureOption {
pub symbol: Symbol,
pub underlying_symbol: Symbol,
pub product_code: String,
pub expiration_date: String,
pub root_symbol: Symbol,
pub option_root_symbol: String,
#[serde(with = "rust_decimal::serde::arbitrary_precision")]
pub strike_price: Decimal,
pub exchange: String,
pub exchange_symbol: String,
pub streamer_symbol: DxFeedSymbol,
pub option_type: String,
pub exercise_style: String,
pub is_vanilla: bool,
pub is_primary_deliverable: bool,
pub future_price_ratio: String,
pub multiplier: String,
pub underlying_count: String,
pub is_confirmed: bool,
pub notional_value: String,
pub display_factor: String,
pub security_exchange: String,
pub sx_id: String,
pub settlement_type: String,
pub strike_factor: String,
pub maturity_date: String,
pub is_exercisable_weekly: bool,
pub last_trade_time: String,
pub days_to_expiration: i32,
pub is_closing_only: bool,
pub active: bool,
pub stops_trading_at: String,
pub expires_at: String,
pub future_option_product: FutureOptionProduct,
}
#[derive(DebugPretty, DisplaySimple, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct FutureOptionProduct {
pub root_symbol: String,
pub cash_settled: bool,
pub code: String,
pub legacy_code: String,
pub clearport_code: String,
pub clearing_code: String,
pub clearing_exchange_code: String,
pub clearing_price_multiplier: String,
pub display_factor: String,
pub exchange: String,
pub product_type: String,
pub expiration_type: String,
pub settlement_delay_days: u32,
pub is_rollover: bool,
pub market_sector: String,
}
#[derive(DebugPretty, DisplaySimple, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct Cryptocurrency {
pub id: u64,
pub symbol: Symbol,
pub instrument_type: InstrumentType,
pub short_description: String,
pub description: String,
pub is_closing_only: bool,
pub active: bool,
pub tick_size: String,
pub streamer_symbol: DxFeedSymbol,
pub destination_venue_symbols: Vec<DestinationVenueSymbol>,
}
#[derive(DebugPretty, DisplaySimple, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct DestinationVenueSymbol {
pub id: u64,
pub symbol: Symbol,
pub destination_venue: String,
pub max_quantity_precision: u32,
pub max_price_precision: u32,
pub routable: bool,
}
#[derive(DebugPretty, DisplaySimple, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct Warrant {
pub symbol: Symbol,
pub instrument_type: InstrumentType,
pub listed_market: String,
pub description: String,
pub is_closing_only: bool,
pub active: bool,
}
#[derive(DebugPretty, DisplaySimple, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct QuantityDecimalPrecision {
pub instrument_type: InstrumentType,
pub symbol: Option<Symbol>,
pub value: u32,
pub minimum_increment_precision: u32,
}
#[derive(Clone, Serialize, Deserialize, DebugPretty, DisplaySimple)]
pub struct SymbolEntry {
pub symbol: String,
pub epic: String,
pub name: String,
pub instrument_type: InstrumentType,
pub exchange: String,
pub expiry: DateTime<Utc>,
pub last_update: DateTime<Utc>,
}
impl PartialEq for SymbolEntry {
fn eq(&self, other: &Self) -> bool {
self.symbol == other.symbol && self.epic == other.epic
}
}
impl Eq for SymbolEntry {}
impl std::hash::Hash for SymbolEntry {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.symbol.hash(state);
self.epic.hash(state);
}
}