use crate::prelude::{Deserialize, Serialize};
use std::collections::HashSet;
use std::fmt::{Debug, Display};
#[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Default, Hash)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum StreamingMarketField {
MidOpen,
High,
Low,
Change,
ChangePct,
UpdateTime,
MarketDelay,
MarketState,
Bid,
#[default]
Offer,
}
impl Debug for StreamingMarketField {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let field_name = match self {
StreamingMarketField::MidOpen => "MID_OPEN",
StreamingMarketField::High => "HIGH",
StreamingMarketField::Low => "LOW",
StreamingMarketField::Change => "CHANGE",
StreamingMarketField::ChangePct => "CHANGE_PCT",
StreamingMarketField::UpdateTime => "UPDATE_TIME",
StreamingMarketField::MarketDelay => "MARKET_DELAY",
StreamingMarketField::MarketState => "MARKET_STATE",
StreamingMarketField::Bid => "BID",
StreamingMarketField::Offer => "OFFER",
};
write!(f, "{}", field_name)
}
}
impl Display for StreamingMarketField {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
pub(crate) fn get_streaming_market_fields(fields: &HashSet<StreamingMarketField>) -> Vec<String> {
let mut fields_vec = Vec::new();
for field in fields {
let val = serde_json::to_value(field).expect("Failed to serialize StreamingMarketField");
match val {
serde_json::Value::String(s) => fields_vec.push(s),
_ => fields_vec.push(format!("{:?}", field)),
}
}
fields_vec
}
#[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Default, Hash)]
#[serde(rename_all = "UPPERCASE")]
pub enum StreamingPriceField {
#[serde(rename = "MID_OPEN")]
MidOpen,
High,
Low,
BidQuoteId,
AskQuoteId,
BidPrice1,
BidPrice2,
BidPrice3,
BidPrice4,
BidPrice5,
AskPrice1,
AskPrice2,
AskPrice3,
AskPrice4,
#[default]
AskPrice5,
BidSize1,
BidSize2,
BidSize3,
BidSize4,
BidSize5,
AskSize1,
AskSize2,
AskSize3,
AskSize4,
AskSize5,
Currency0,
Currency1,
C1BidSize1,
C1BidSize2,
C1BidSize3,
C1BidSize4,
C1BidSize5,
C1AskSize1,
C1AskSize2,
C1AskSize3,
C1AskSize4,
C1AskSize5,
Currency2,
C2BidSize1,
C2BidSize2,
C2BidSize3,
C2BidSize4,
C2BidSize5,
C2AskSize1,
C2AskSize2,
C2AskSize3,
C2AskSize4,
C2AskSize5,
Currency3,
C3BidSize1,
C3BidSize2,
C3BidSize3,
C3BidSize4,
C3BidSize5,
C3AskSize1,
C3AskSize2,
C3AskSize3,
C3AskSize4,
C3AskSize5,
Currency4,
C4BidSize1,
C4BidSize2,
C4BidSize3,
C4BidSize4,
C4BidSize5,
C4AskSize1,
C4AskSize2,
C4AskSize3,
C4AskSize4,
C4AskSize5,
Currency5,
C5BidSize1,
C5BidSize2,
C5BidSize3,
C5BidSize4,
C5BidSize5,
C5AskSize1,
C5AskSize2,
C5AskSize3,
C5AskSize4,
C5AskSize5,
Timestamp,
#[serde(rename = "DLG_FLAG")]
DlgFlag,
#[serde(rename = "NET_CHG")]
NetChg,
#[serde(rename = "NET_CHG_PCT")]
NetChgPct,
Delay,
}
impl Debug for StreamingPriceField {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let field_name = match self {
StreamingPriceField::MidOpen => "MID_OPEN",
StreamingPriceField::High => "HIGH",
StreamingPriceField::Low => "LOW",
StreamingPriceField::BidQuoteId => "BIDQUOTEID",
StreamingPriceField::AskQuoteId => "ASKQUOTEID",
StreamingPriceField::BidPrice1 => "BIDPRICE1",
StreamingPriceField::BidPrice2 => "BIDPRICE2",
StreamingPriceField::BidPrice3 => "BIDPRICE3",
StreamingPriceField::BidPrice4 => "BIDPRICE4",
StreamingPriceField::BidPrice5 => "BIDPRICE5",
StreamingPriceField::AskPrice1 => "ASKPRICE1",
StreamingPriceField::AskPrice2 => "ASKPRICE2",
StreamingPriceField::AskPrice3 => "ASKPRICE3",
StreamingPriceField::AskPrice4 => "ASKPRICE4",
StreamingPriceField::AskPrice5 => "ASKPRICE5",
StreamingPriceField::BidSize1 => "BIDSIZE1",
StreamingPriceField::BidSize2 => "BIDSIZE2",
StreamingPriceField::BidSize3 => "BIDSIZE3",
StreamingPriceField::BidSize4 => "BIDSIZE4",
StreamingPriceField::BidSize5 => "BIDSIZE5",
StreamingPriceField::AskSize1 => "ASKSIZE1",
StreamingPriceField::AskSize2 => "ASKSIZE2",
StreamingPriceField::AskSize3 => "ASKSIZE3",
StreamingPriceField::AskSize4 => "ASKSIZE4",
StreamingPriceField::AskSize5 => "ASKSIZE5",
StreamingPriceField::Currency0 => "CURRENCY0",
StreamingPriceField::Currency1 => "CURRENCY1",
StreamingPriceField::C1BidSize1 => "C1BIDSIZE1",
StreamingPriceField::C1BidSize2 => "C1BIDSIZE2",
StreamingPriceField::C1BidSize3 => "C1BIDSIZE3",
StreamingPriceField::C1BidSize4 => "C1BIDSIZE4",
StreamingPriceField::C1BidSize5 => "C1BIDSIZE5",
StreamingPriceField::C1AskSize1 => "C1ASKSIZE1",
StreamingPriceField::C1AskSize2 => "C1ASKSIZE2",
StreamingPriceField::C1AskSize3 => "C1ASKSIZE3",
StreamingPriceField::C1AskSize4 => "C1ASKSIZE4",
StreamingPriceField::C1AskSize5 => "C1ASKSIZE5",
StreamingPriceField::Currency2 => "CURRENCY2",
StreamingPriceField::C2BidSize1 => "C2BIDSIZE1",
StreamingPriceField::C2BidSize2 => "C2BIDSIZE2",
StreamingPriceField::C2BidSize3 => "C2BIDSIZE3",
StreamingPriceField::C2BidSize4 => "C2BIDSIZE4",
StreamingPriceField::C2BidSize5 => "C2BIDSIZE5",
StreamingPriceField::C2AskSize1 => "C2ASKSIZE1",
StreamingPriceField::C2AskSize2 => "C2ASKSIZE2",
StreamingPriceField::C2AskSize3 => "C2ASKSIZE3",
StreamingPriceField::C2AskSize4 => "C2ASKSIZE4",
StreamingPriceField::C2AskSize5 => "C2ASKSIZE5",
StreamingPriceField::Currency3 => "CURRENCY3",
StreamingPriceField::C3BidSize1 => "C3BIDSIZE1",
StreamingPriceField::C3BidSize2 => "C3BIDSIZE2",
StreamingPriceField::C3BidSize3 => "C3BIDSIZE3",
StreamingPriceField::C3BidSize4 => "C3BIDSIZE4",
StreamingPriceField::C3BidSize5 => "C3BIDSIZE5",
StreamingPriceField::C3AskSize1 => "C3ASKSIZE1",
StreamingPriceField::C3AskSize2 => "C3ASKSIZE2",
StreamingPriceField::C3AskSize3 => "C3ASKSIZE3",
StreamingPriceField::C3AskSize4 => "C3ASKSIZE4",
StreamingPriceField::C3AskSize5 => "C3ASKSIZE5",
StreamingPriceField::Currency4 => "CURRENCY4",
StreamingPriceField::C4BidSize1 => "C4BIDSIZE1",
StreamingPriceField::C4BidSize2 => "C4BIDSIZE2",
StreamingPriceField::C4BidSize3 => "C4BIDSIZE3",
StreamingPriceField::C4BidSize4 => "C4BIDSIZE4",
StreamingPriceField::C4BidSize5 => "C4BIDSIZE5",
StreamingPriceField::C4AskSize1 => "C4ASKSIZE1",
StreamingPriceField::C4AskSize2 => "C4ASKSIZE2",
StreamingPriceField::C4AskSize3 => "C4ASKSIZE3",
StreamingPriceField::C4AskSize4 => "C4ASKSIZE4",
StreamingPriceField::C4AskSize5 => "C4ASKSIZE5",
StreamingPriceField::Currency5 => "CURRENCY5",
StreamingPriceField::C5BidSize1 => "C5BIDSIZE1",
StreamingPriceField::C5BidSize2 => "C5BIDSIZE2",
StreamingPriceField::C5BidSize3 => "C5BIDSIZE3",
StreamingPriceField::C5BidSize4 => "C5BIDSIZE4",
StreamingPriceField::C5BidSize5 => "C5BIDSIZE5",
StreamingPriceField::C5AskSize1 => "C5ASKSIZE1",
StreamingPriceField::C5AskSize2 => "C5ASKSIZE2",
StreamingPriceField::C5AskSize3 => "C5ASKSIZE3",
StreamingPriceField::C5AskSize4 => "C5ASKSIZE4",
StreamingPriceField::C5AskSize5 => "C5ASKSIZE5",
StreamingPriceField::Timestamp => "TIMESTAMP",
StreamingPriceField::DlgFlag => "DLG_FLAG",
StreamingPriceField::NetChg => "NET_CHG",
StreamingPriceField::NetChgPct => "NET_CHG_PCT",
StreamingPriceField::Delay => "DELAY",
};
write!(f, "{}", field_name)
}
}
impl Display for StreamingPriceField {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
pub(crate) fn get_streaming_price_fields(fields: &HashSet<StreamingPriceField>) -> Vec<String> {
let map_field = |f: &StreamingPriceField| -> &'static str {
match f {
StreamingPriceField::MidOpen => "MID_OPEN",
StreamingPriceField::High => "HIGH",
StreamingPriceField::Low => "LOW",
StreamingPriceField::BidQuoteId => "BIDQUOTEID",
StreamingPriceField::AskQuoteId => "ASKQUOTEID",
StreamingPriceField::BidPrice1 => "BIDPRICE1",
StreamingPriceField::BidPrice2 => "BIDPRICE2",
StreamingPriceField::BidPrice3 => "BIDPRICE3",
StreamingPriceField::BidPrice4 => "BIDPRICE4",
StreamingPriceField::BidPrice5 => "BIDPRICE5",
StreamingPriceField::AskPrice1 => "ASKPRICE1",
StreamingPriceField::AskPrice2 => "ASKPRICE2",
StreamingPriceField::AskPrice3 => "ASKPRICE3",
StreamingPriceField::AskPrice4 => "ASKPRICE4",
StreamingPriceField::AskPrice5 => "ASKPRICE5",
StreamingPriceField::BidSize1 => "BIDSIZE1",
StreamingPriceField::BidSize2 => "BIDSIZE2",
StreamingPriceField::BidSize3 => "BIDSIZE3",
StreamingPriceField::BidSize4 => "BIDSIZE4",
StreamingPriceField::BidSize5 => "BIDSIZE5",
StreamingPriceField::AskSize1 => "ASKSIZE1",
StreamingPriceField::AskSize2 => "ASKSIZE2",
StreamingPriceField::AskSize3 => "ASKSIZE3",
StreamingPriceField::AskSize4 => "ASKSIZE4",
StreamingPriceField::AskSize5 => "ASKSIZE5",
StreamingPriceField::Currency0 => "CURRENCY0",
StreamingPriceField::Currency1 => "CURRENCY1",
StreamingPriceField::Currency2 => "CURRENCY2",
StreamingPriceField::Currency3 => "CURRENCY3",
StreamingPriceField::Currency4 => "CURRENCY4",
StreamingPriceField::Currency5 => "CURRENCY5",
StreamingPriceField::C1BidSize1 => "C1BIDSIZE1",
StreamingPriceField::C1BidSize2 => "C1BIDSIZE2",
StreamingPriceField::C1BidSize3 => "C1BIDSIZE3",
StreamingPriceField::C1BidSize4 => "C1BIDSIZE4",
StreamingPriceField::C1BidSize5 => "C1BIDSIZE5",
StreamingPriceField::C1AskSize1 => "C1ASKSIZE1",
StreamingPriceField::C1AskSize2 => "C1ASKSIZE2",
StreamingPriceField::C1AskSize3 => "C1ASKSIZE3",
StreamingPriceField::C1AskSize4 => "C1ASKSIZE4",
StreamingPriceField::C1AskSize5 => "C1ASKSIZE5",
StreamingPriceField::C2BidSize1 => "C2BIDSIZE1",
StreamingPriceField::C2BidSize2 => "C2BIDSIZE2",
StreamingPriceField::C2BidSize3 => "C2BIDSIZE3",
StreamingPriceField::C2BidSize4 => "C2BIDSIZE4",
StreamingPriceField::C2BidSize5 => "C2BIDSIZE5",
StreamingPriceField::C2AskSize1 => "C2ASKSIZE1",
StreamingPriceField::C2AskSize2 => "C2ASKSIZE2",
StreamingPriceField::C2AskSize3 => "C2ASKSIZE3",
StreamingPriceField::C2AskSize4 => "C2ASKSIZE4",
StreamingPriceField::C2AskSize5 => "C2ASKSIZE5",
StreamingPriceField::C3BidSize1 => "C3BIDSIZE1",
StreamingPriceField::C3BidSize2 => "C3BIDSIZE2",
StreamingPriceField::C3BidSize3 => "C3BIDSIZE3",
StreamingPriceField::C3BidSize4 => "C3BIDSIZE4",
StreamingPriceField::C3BidSize5 => "C3BIDSIZE5",
StreamingPriceField::C3AskSize1 => "C3ASKSIZE1",
StreamingPriceField::C3AskSize2 => "C3ASKSIZE2",
StreamingPriceField::C3AskSize3 => "C3ASKSIZE3",
StreamingPriceField::C3AskSize4 => "C3ASKSIZE4",
StreamingPriceField::C3AskSize5 => "C3ASKSIZE5",
StreamingPriceField::C4BidSize1 => "C4BIDSIZE1",
StreamingPriceField::C4BidSize2 => "C4BIDSIZE2",
StreamingPriceField::C4BidSize3 => "C4BIDSIZE3",
StreamingPriceField::C4BidSize4 => "C4BIDSIZE4",
StreamingPriceField::C4BidSize5 => "C4BIDSIZE5",
StreamingPriceField::C4AskSize1 => "C4ASKSIZE1",
StreamingPriceField::C4AskSize2 => "C4ASKSIZE2",
StreamingPriceField::C4AskSize3 => "C4ASKSIZE3",
StreamingPriceField::C4AskSize4 => "C4ASKSIZE4",
StreamingPriceField::C4AskSize5 => "C4ASKSIZE5",
StreamingPriceField::C5BidSize1 => "C5BIDSIZE1",
StreamingPriceField::C5BidSize2 => "C5BIDSIZE2",
StreamingPriceField::C5BidSize3 => "C5BIDSIZE3",
StreamingPriceField::C5BidSize4 => "C5BIDSIZE4",
StreamingPriceField::C5BidSize5 => "C5BIDSIZE5",
StreamingPriceField::C5AskSize1 => "C5ASKSIZE1",
StreamingPriceField::C5AskSize2 => "C5ASKSIZE2",
StreamingPriceField::C5AskSize3 => "C5ASKSIZE3",
StreamingPriceField::C5AskSize4 => "C5ASKSIZE4",
StreamingPriceField::C5AskSize5 => "C5ASKSIZE5",
StreamingPriceField::Timestamp => "TIMESTAMP",
StreamingPriceField::DlgFlag => "DLG_FLAG",
StreamingPriceField::NetChg => "NET_CHG",
StreamingPriceField::NetChgPct => "NET_CHG_PCT",
StreamingPriceField::Delay => "DELAY",
}
};
let mut fields_vec = Vec::with_capacity(fields.len());
for field in fields {
fields_vec.push(map_field(field).to_string());
}
fields_vec
}
#[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Default, Hash)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum StreamingAccountDataField {
#[default]
Pnl,
Deposit,
AvailableCash,
PnlLr,
PnlNlr,
Funds,
Margin,
MarginLr,
MarginNlr,
AvailableToDeal,
Equity,
EquityUsed,
}
impl Debug for StreamingAccountDataField {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let field_name = match self {
StreamingAccountDataField::Pnl => "PNL",
StreamingAccountDataField::Deposit => "DEPOSIT",
StreamingAccountDataField::AvailableCash => "AVAILABLE_CASH",
StreamingAccountDataField::PnlLr => "PNL_LR",
StreamingAccountDataField::PnlNlr => "PNL_NLR",
StreamingAccountDataField::Funds => "FUNDS",
StreamingAccountDataField::Margin => "MARGIN",
StreamingAccountDataField::MarginLr => "MARGIN_LR",
StreamingAccountDataField::MarginNlr => "MARGIN_NLR",
StreamingAccountDataField::AvailableToDeal => "AVAILABLE_TO_DEAL",
StreamingAccountDataField::Equity => "EQUITY",
StreamingAccountDataField::EquityUsed => "EQUITY_USED",
};
write!(f, "{}", field_name)
}
}
impl Display for StreamingAccountDataField {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
pub(crate) fn get_streaming_account_data_fields(
fields: &HashSet<StreamingAccountDataField>,
) -> Vec<String> {
let mut fields_vec = Vec::new();
for field in fields {
let val =
serde_json::to_value(field).expect("Failed to serialize StreamingAccountDataField");
match val {
serde_json::Value::String(s) => fields_vec.push(s),
_ => fields_vec.push(format!("{:?}", field)),
}
}
fields_vec
}
#[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Default, Hash)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum StreamingChartField {
#[default]
Ltv,
Ttv,
Utm,
DayOpenMid,
DayNetChgMid,
DayPercChgMid,
DayHigh,
DayLow,
Bid,
Ofr,
Ltp,
OfrOpen,
OfrHigh,
OfrLow,
OfrClose,
BidOpen,
BidHigh,
BidLow,
BidClose,
LtpOpen,
LtpHigh,
LtpLow,
LtpClose,
ConsEnd,
ConsTickCount,
}
impl std::fmt::Debug for StreamingChartField {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let name = match self {
StreamingChartField::Ltv => "LTV",
StreamingChartField::Ttv => "TTV",
StreamingChartField::Utm => "UTM",
StreamingChartField::DayOpenMid => "DAY_OPEN_MID",
StreamingChartField::DayNetChgMid => "DAY_NET_CHG_MID",
StreamingChartField::DayPercChgMid => "DAY_PERC_CHG_MID",
StreamingChartField::DayHigh => "DAY_HIGH",
StreamingChartField::DayLow => "DAY_LOW",
StreamingChartField::Bid => "BID",
StreamingChartField::Ofr => "OFR",
StreamingChartField::Ltp => "LTP",
StreamingChartField::OfrOpen => "OFR_OPEN",
StreamingChartField::OfrHigh => "OFR_HIGH",
StreamingChartField::OfrLow => "OFR_LOW",
StreamingChartField::OfrClose => "OFR_CLOSE",
StreamingChartField::BidOpen => "BID_OPEN",
StreamingChartField::BidHigh => "BID_HIGH",
StreamingChartField::BidLow => "BID_LOW",
StreamingChartField::BidClose => "BID_CLOSE",
StreamingChartField::LtpOpen => "LTP_OPEN",
StreamingChartField::LtpHigh => "LTP_HIGH",
StreamingChartField::LtpLow => "LTP_LOW",
StreamingChartField::LtpClose => "LTP_CLOSE",
StreamingChartField::ConsEnd => "CONS_END",
StreamingChartField::ConsTickCount => "CONS_TICK_COUNT",
};
write!(f, "{}", name)
}
}
impl std::fmt::Display for StreamingChartField {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
pub(crate) fn get_streaming_chart_fields(fields: &HashSet<StreamingChartField>) -> Vec<String> {
let mut out = Vec::with_capacity(fields.len());
for field in fields {
let val = serde_json::to_value(field).expect("Failed to serialize StreamingChartField");
match val {
serde_json::Value::String(s) => out.push(s),
_ => out.push(format!("{:?}", field)),
}
}
out
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_streaming_market_field_default() {
let field = StreamingMarketField::default();
assert_eq!(field, StreamingMarketField::Offer);
}
#[test]
fn test_streaming_market_field_debug() {
assert_eq!(format!("{:?}", StreamingMarketField::Bid), "BID");
assert_eq!(format!("{:?}", StreamingMarketField::Offer), "OFFER");
assert_eq!(format!("{:?}", StreamingMarketField::High), "HIGH");
assert_eq!(format!("{:?}", StreamingMarketField::Low), "LOW");
assert_eq!(format!("{:?}", StreamingMarketField::Change), "CHANGE");
assert_eq!(
format!("{:?}", StreamingMarketField::ChangePct),
"CHANGE_PCT"
);
assert_eq!(
format!("{:?}", StreamingMarketField::UpdateTime),
"UPDATE_TIME"
);
assert_eq!(
format!("{:?}", StreamingMarketField::MarketDelay),
"MARKET_DELAY"
);
assert_eq!(
format!("{:?}", StreamingMarketField::MarketState),
"MARKET_STATE"
);
assert_eq!(format!("{:?}", StreamingMarketField::MidOpen), "MID_OPEN");
}
#[test]
fn test_streaming_market_field_display() {
assert_eq!(format!("{}", StreamingMarketField::Bid), "BID");
assert_eq!(format!("{}", StreamingMarketField::Offer), "OFFER");
}
#[test]
fn test_get_streaming_market_fields_empty() {
let fields: HashSet<StreamingMarketField> = HashSet::new();
let result = get_streaming_market_fields(&fields);
assert!(result.is_empty());
}
#[test]
fn test_get_streaming_market_fields_single() {
let mut fields = HashSet::new();
fields.insert(StreamingMarketField::Bid);
let result = get_streaming_market_fields(&fields);
assert_eq!(result.len(), 1);
assert!(result.contains(&"BID".to_string()));
}
#[test]
fn test_get_streaming_market_fields_multiple() {
let mut fields = HashSet::new();
fields.insert(StreamingMarketField::Bid);
fields.insert(StreamingMarketField::Offer);
fields.insert(StreamingMarketField::High);
let result = get_streaming_market_fields(&fields);
assert_eq!(result.len(), 3);
assert!(result.contains(&"BID".to_string()));
assert!(result.contains(&"OFFER".to_string()));
assert!(result.contains(&"HIGH".to_string()));
}
#[test]
fn test_streaming_price_field_default() {
let field = StreamingPriceField::default();
assert_eq!(field, StreamingPriceField::AskPrice5);
}
#[test]
fn test_streaming_price_field_debug() {
assert_eq!(format!("{:?}", StreamingPriceField::High), "HIGH");
assert_eq!(format!("{:?}", StreamingPriceField::Low), "LOW");
assert_eq!(format!("{:?}", StreamingPriceField::MidOpen), "MID_OPEN");
assert_eq!(format!("{:?}", StreamingPriceField::BidPrice1), "BIDPRICE1");
assert_eq!(format!("{:?}", StreamingPriceField::AskPrice1), "ASKPRICE1");
}
#[test]
fn test_streaming_price_field_display() {
assert_eq!(format!("{}", StreamingPriceField::High), "HIGH");
assert_eq!(format!("{}", StreamingPriceField::BidPrice1), "BIDPRICE1");
}
#[test]
fn test_streaming_account_field_default() {
let field = StreamingAccountDataField::default();
assert_eq!(field, StreamingAccountDataField::Pnl);
}
#[test]
fn test_streaming_account_field_debug() {
assert_eq!(format!("{:?}", StreamingAccountDataField::Pnl), "PNL");
assert_eq!(
format!("{:?}", StreamingAccountDataField::Deposit),
"DEPOSIT"
);
assert_eq!(format!("{:?}", StreamingAccountDataField::Margin), "MARGIN");
assert_eq!(format!("{:?}", StreamingAccountDataField::Equity), "EQUITY");
}
#[test]
fn test_streaming_account_field_display() {
assert_eq!(format!("{}", StreamingAccountDataField::Pnl), "PNL");
assert_eq!(format!("{}", StreamingAccountDataField::Equity), "EQUITY");
}
#[test]
fn test_get_streaming_account_fields_empty() {
let fields: HashSet<StreamingAccountDataField> = HashSet::new();
let result = get_streaming_account_data_fields(&fields);
assert!(result.is_empty());
}
#[test]
fn test_get_streaming_account_fields_multiple() {
let mut fields = HashSet::new();
fields.insert(StreamingAccountDataField::Pnl);
fields.insert(StreamingAccountDataField::Equity);
let result = get_streaming_account_data_fields(&fields);
assert_eq!(result.len(), 2);
assert!(result.contains(&"PNL".to_string()));
assert!(result.contains(&"EQUITY".to_string()));
}
#[test]
fn test_streaming_chart_field_default() {
let field = StreamingChartField::default();
assert_eq!(field, StreamingChartField::Ltv);
}
#[test]
fn test_streaming_chart_field_debug() {
assert_eq!(format!("{:?}", StreamingChartField::Bid), "BID");
assert_eq!(format!("{:?}", StreamingChartField::Ofr), "OFR");
assert_eq!(format!("{:?}", StreamingChartField::Ltp), "LTP");
assert_eq!(format!("{:?}", StreamingChartField::Ltv), "LTV");
assert_eq!(format!("{:?}", StreamingChartField::Utm), "UTM");
assert_eq!(format!("{:?}", StreamingChartField::DayHigh), "DAY_HIGH");
assert_eq!(format!("{:?}", StreamingChartField::DayLow), "DAY_LOW");
}
#[test]
fn test_streaming_chart_field_display() {
assert_eq!(format!("{}", StreamingChartField::Bid), "BID");
assert_eq!(format!("{}", StreamingChartField::Ofr), "OFR");
}
#[test]
fn test_get_streaming_chart_fields_empty() {
let fields: HashSet<StreamingChartField> = HashSet::new();
let result = get_streaming_chart_fields(&fields);
assert!(result.is_empty());
}
#[test]
fn test_get_streaming_chart_fields_multiple() {
let mut fields = HashSet::new();
fields.insert(StreamingChartField::Bid);
fields.insert(StreamingChartField::Ofr);
fields.insert(StreamingChartField::Ltp);
let result = get_streaming_chart_fields(&fields);
assert_eq!(result.len(), 3);
assert!(result.contains(&"BID".to_string()));
assert!(result.contains(&"OFR".to_string()));
assert!(result.contains(&"LTP".to_string()));
}
#[test]
fn test_streaming_market_field_serialization() {
let field = StreamingMarketField::Bid;
let json = serde_json::to_string(&field).expect("serialize failed");
assert_eq!(json, "\"BID\"");
let deserialized: StreamingMarketField =
serde_json::from_str(&json).expect("deserialize failed");
assert_eq!(deserialized, StreamingMarketField::Bid);
}
#[test]
fn test_streaming_account_field_serialization() {
let field = StreamingAccountDataField::Pnl;
let json = serde_json::to_string(&field).expect("serialize failed");
assert_eq!(json, "\"PNL\"");
let deserialized: StreamingAccountDataField =
serde_json::from_str(&json).expect("deserialize failed");
assert_eq!(deserialized, StreamingAccountDataField::Pnl);
}
#[test]
fn test_streaming_chart_field_serialization() {
let field = StreamingChartField::Bid;
let json = serde_json::to_string(&field).expect("serialize failed");
assert_eq!(json, "\"BID\"");
let deserialized: StreamingChartField =
serde_json::from_str(&json).expect("deserialize failed");
assert_eq!(deserialized, StreamingChartField::Bid);
}
#[test]
fn test_streaming_market_field_equality() {
let field1 = StreamingMarketField::Bid;
let field2 = StreamingMarketField::Bid;
let field3 = StreamingMarketField::Offer;
assert_eq!(field1, field2);
assert_ne!(field1, field3);
}
#[test]
fn test_streaming_market_field_hash() {
let mut set = HashSet::new();
set.insert(StreamingMarketField::Bid);
set.insert(StreamingMarketField::Bid);
assert_eq!(set.len(), 1);
}
#[test]
fn test_streaming_market_field_clone() {
let field = StreamingMarketField::High;
let cloned = field.clone();
assert_eq!(field, cloned);
}
}