From 223a91e938bc019cad1566753eb6bb61c3cec779 Mon Sep 17 00:00:00 2001 From: Kevin Hoerr Date: Thu, 16 Apr 2026 17:06:16 -0400 Subject: records.rs: Utility --- src/app/store/records.rs | 90 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 80 insertions(+), 10 deletions(-) (limited to 'src/app/store/records.rs') diff --git a/src/app/store/records.rs b/src/app/store/records.rs index 39d2aa3..024c06e 100644 --- a/src/app/store/records.rs +++ b/src/app/store/records.rs @@ -1,9 +1,9 @@ use bigdecimal::{BigDecimal, Context, RoundingMode}; use std::sync::LazyLock; -static ROUNDING_MODE: RoundingMode = RoundingMode::HalfEven; +pub static ROUNDING_MODE: RoundingMode = RoundingMode::HalfEven; /// Will use default precision (either 100 or ${RUST_BIGDECIMAL_DEFAULT_PRECISION}) -static DECIMAL_CONTEXT: LazyLock = std::sync::LazyLock::new(|| Context::default().with_rounding_mode(ROUNDING_MODE)); +pub static DECIMAL_CONTEXT: LazyLock = std::sync::LazyLock::new(|| Context::default().with_rounding_mode(ROUNDING_MODE)); /// Represents an account that holds equity. An account may hold equity with /// multiple equity symbols. @@ -80,7 +80,7 @@ pub struct EquityChangeEvent { pub fiduciary_account_id: u8, pub equity_symbol_id: usize, pub equity_change_quantity: BigDecimal, - pub equity_change_cost_basis_usd: BigDecimal, + pub equity_change_cost_basis: BigDecimal, pub equity_change_type: ChangeEventType, pub equity_change_timestamp: chrono::DateTime, } @@ -90,7 +90,17 @@ impl EquityChangeEvent { /// Provides an estimate of the numerated change based on the cost basis /// of the equity and the quantity pub fn estimated_price(&self) -> BigDecimal { - DECIMAL_CONTEXT.multiply(&self.equity_change_cost_basis_usd, &self.equity_change_quantity) + DECIMAL_CONTEXT.multiply(&self.equity_change_cost_basis, &self.equity_change_quantity) + } + + /// Provides the quantity of the event relativized by the event type's score + pub fn scored_quantity(&self) -> BigDecimal { + self.equity_change_quantity.clone() * self.equity_change_type.score() + } + + /// Provides the estimated cost basis of the event relativized by the event type's score + pub fn scored_cost_basis(&self) -> BigDecimal { + self.equity_change_cost_basis.clone() * self.equity_change_type.score() } } @@ -105,16 +115,16 @@ mod tests { #[test] fn event_type_score_buy() { - let eventType = ChangeEventType::BUY; + let event_type = ChangeEventType::BUY; - assert_eq!(eventType.score(), 1_i8); + assert_eq!(event_type.score(), 1_i8); } #[test] fn event_type_score_sell() { - let eventType = ChangeEventType::SELL; + let event_type = ChangeEventType::SELL; - assert_eq!(eventType.score(), -1_i8); + assert_eq!(event_type.score(), -1_i8); } #[test] @@ -124,7 +134,7 @@ mod tests { fiduciary_account_id: 0, equity_symbol_id: 0, equity_change_quantity: BigDecimal::from_str("0.125").unwrap(), - equity_change_cost_basis_usd: BigDecimal::from_str("82.80").unwrap(), + equity_change_cost_basis: BigDecimal::from_str("82.80").unwrap(), equity_change_type: ChangeEventType::BUY, equity_change_timestamp: chrono::Local::now().to_utc(), }; @@ -139,7 +149,7 @@ mod tests { fiduciary_account_id: 0, equity_symbol_id: 0, equity_change_quantity: BigDecimal::from_str("87.12808").unwrap(), - equity_change_cost_basis_usd: BigDecimal::from_str("14.91").unwrap(), + equity_change_cost_basis: BigDecimal::from_str("14.91").unwrap(), equity_change_type: ChangeEventType::BUY, equity_change_timestamp: chrono::Local::now().to_utc(), }; @@ -147,4 +157,64 @@ mod tests { // actual: 1299.0796728 assert_eq!(nat(event.estimated_price()).to_plain_string(), "1299.08"); } + + #[test] + fn change_event_scored_quantity_buy() { + let event = EquityChangeEvent { + equity_change_event_id: 0, + fiduciary_account_id: 0, + equity_symbol_id: 0, + equity_change_quantity: BigDecimal::from_str("0.125").unwrap(), + equity_change_cost_basis: BigDecimal::from_str("82.80").unwrap(), + equity_change_type: ChangeEventType::BUY, + equity_change_timestamp: chrono::Local::now().to_utc(), + }; + + assert_eq!(event.scored_quantity().to_plain_string(), "0.125"); + } + + #[test] + fn change_event_scored_quantity_sell() { + let event = EquityChangeEvent { + equity_change_event_id: 0, + fiduciary_account_id: 0, + equity_symbol_id: 0, + equity_change_quantity: BigDecimal::from_str("0.125").unwrap(), + equity_change_cost_basis: BigDecimal::from_str("82.80").unwrap(), + equity_change_type: ChangeEventType::SELL, + equity_change_timestamp: chrono::Local::now().to_utc(), + }; + + assert_eq!(event.scored_quantity().to_plain_string(), "-0.125"); + } + + #[test] + fn change_event_scored_estimated_price_buy() { + let event = EquityChangeEvent { + equity_change_event_id: 0, + fiduciary_account_id: 0, + equity_symbol_id: 0, + equity_change_quantity: BigDecimal::from_str("0.125").unwrap(), + equity_change_cost_basis: BigDecimal::from_str("82.80").unwrap(), + equity_change_type: ChangeEventType::BUY, + equity_change_timestamp: chrono::Local::now().to_utc(), + }; + + assert_eq!(nat(event.scored_cost_basis()).to_plain_string(), "82.80"); + } + + #[test] + fn change_event_scored_estimated_price_sell() { + let event = EquityChangeEvent { + equity_change_event_id: 0, + fiduciary_account_id: 0, + equity_symbol_id: 0, + equity_change_quantity: BigDecimal::from_str("0.125").unwrap(), + equity_change_cost_basis: BigDecimal::from_str("82.80").unwrap(), + equity_change_type: ChangeEventType::SELL, + equity_change_timestamp: chrono::Local::now().to_utc(), + }; + + assert_eq!(nat(event.scored_cost_basis()).to_plain_string(), "-82.80"); + } } \ No newline at end of file -- cgit v1.3