use std::cmp::Ordering;
use super::{Index, IndexAnalytics, SecurityBoard};
pub trait IndexesExt {
fn retain_actual_by_till(&mut self);
fn into_actual_by_till(mut self) -> Self
where
Self: Sized,
{
self.retain_actual_by_till();
self
}
}
impl IndexesExt for Vec<Index> {
fn retain_actual_by_till(&mut self) {
let latest_till = self.iter().filter_map(Index::till).max();
self.retain(|index| index.till() == latest_till);
}
}
pub trait IndexAnalyticsExt {
fn retain_actual_by_session(&mut self);
fn into_actual_by_session(mut self) -> Self
where
Self: Sized,
{
self.retain_actual_by_session();
self
}
fn sort_by_weight_desc(&mut self);
fn into_sorted_by_weight_desc(mut self) -> Self
where
Self: Sized,
{
self.sort_by_weight_desc();
self
}
}
impl IndexAnalyticsExt for Vec<IndexAnalytics> {
fn retain_actual_by_session(&mut self) {
let Some(latest_trade_session_date) =
self.iter().map(IndexAnalytics::trade_session_date).max()
else {
return;
};
self.retain(|item| item.trade_session_date() == latest_trade_session_date);
let Some(latest_tradingsession) = self.iter().map(IndexAnalytics::tradingsession).max()
else {
return;
};
self.retain(|item| item.tradingsession() == latest_tradingsession);
}
fn sort_by_weight_desc(&mut self) {
self.sort_by(|left, right| {
right
.weight()
.partial_cmp(&left.weight())
.unwrap_or(Ordering::Equal)
.then_with(|| left.secid().as_str().cmp(right.secid().as_str()))
});
}
}
pub trait SecurityBoardsExt {
fn stock_primary_or_first(&self) -> Option<&SecurityBoard>;
fn into_stock_primary_or_first(self) -> Option<SecurityBoard>
where
Self: Sized;
}
impl SecurityBoardsExt for Vec<SecurityBoard> {
fn stock_primary_or_first(&self) -> Option<&SecurityBoard> {
let mut fallback = None;
for board in self {
if board.engine().as_str() != "stock" {
continue;
}
if board.is_primary() {
return Some(board);
}
if fallback.is_none() {
fallback = Some(board);
}
}
fallback
}
fn into_stock_primary_or_first(self) -> Option<SecurityBoard> {
let mut fallback = None;
for board in self {
if board.engine().as_str() != "stock" {
continue;
}
if board.is_primary() {
return Some(board);
}
if fallback.is_none() {
fallback = Some(board);
}
}
fallback
}
}