diff options
| author | Kevin Hoerr <kjhoerr@submelon.dev> | 2026-04-16 17:06:16 -0400 |
|---|---|---|
| committer | Kevin Hoerr <kjhoerr@submelon.dev> | 2026-04-16 17:06:16 -0400 |
| commit | 223a91e938bc019cad1566753eb6bb61c3cec779 (patch) | |
| tree | 8f2d2c69313cc94b45bf73cdbd9ba7eb97295b23 /src/app | |
| parent | f7132dc28043fd375e74328e3acff5282927caf1 (diff) | |
| download | equity-tracker-223a91e938bc019cad1566753eb6bb61c3cec779.tar.gz equity-tracker-223a91e938bc019cad1566753eb6bb61c3cec779.tar.bz2 equity-tracker-223a91e938bc019cad1566753eb6bb61c3cec779.zip | |
records.rs: Utility
Diffstat (limited to 'src/app')
| -rw-r--r-- | src/app/store/records.rs | 90 |
1 files changed, 80 insertions, 10 deletions
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<Context> = std::sync::LazyLock::new(|| Context::default().with_rounding_mode(ROUNDING_MODE)); +pub static DECIMAL_CONTEXT: LazyLock<Context> = 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<chrono::Utc>, } @@ -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 |
