use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Dollars, Indexes, Version};
use derive_more::{Deref, DerefMut};
use vecdb::{AnyStoredVec, AnyVec, Exit, ReadableCloneableVec, Rw, StorageMode, WritableVec};
use crate::{
distribution::{metrics::ImportConfig, state::UnrealizedState},
internal::{FiatPerBlock, LazyPerBlock, NegCentsUnsignedToDollars},
};
use super::UnrealizedMinimal;
#[derive(Deref, DerefMut, Traversable)]
pub struct UnrealizedBasic<M: StorageMode = Rw> {
#[deref]
#[deref_mut]
#[traversable(flatten)]
pub minimal: UnrealizedMinimal<M>,
pub profit: FiatPerBlock<Cents, M>,
pub loss: FiatPerBlock<Cents, M>,
#[traversable(wrap = "loss", rename = "negative")]
pub neg_loss: LazyPerBlock<Dollars, Cents>,
}
impl UnrealizedBasic {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
let v1 = Version::ONE;
let loss: FiatPerBlock<Cents> = cfg.import("unrealized_loss", v1)?;
let neg_loss = LazyPerBlock::from_computed::<NegCentsUnsignedToDollars>(
&cfg.name("unrealized_loss_neg"),
cfg.version,
loss.cents.height.read_only_boxed_clone(),
&loss.cents,
);
Ok(Self {
minimal: UnrealizedMinimal::forced_import(cfg)?,
profit: cfg.import("unrealized_profit", v1)?,
loss,
neg_loss,
})
}
pub(crate) fn min_stateful_len(&self) -> usize {
self.profit
.cents
.height
.len()
.min(self.loss.cents.height.len())
}
#[inline(always)]
pub(crate) fn push_state(&mut self, state: &UnrealizedState) {
self.profit.cents.height.push(state.unrealized_profit);
self.loss.cents.height.push(state.unrealized_loss);
}
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
vec![
&mut self.profit.cents.height as &mut dyn AnyStoredVec,
&mut self.loss.cents.height,
]
}
pub(crate) fn compute_from_sources(
&mut self,
starting_indexes: &Indexes,
others: &[&Self],
exit: &Exit,
) -> Result<()> {
sum_others!(self, starting_indexes, others, exit; profit.cents.height);
sum_others!(self, starting_indexes, others, exit; loss.cents.height);
Ok(())
}
}