aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Hoerr <kjhoerr@submelon.dev>2026-04-16 17:06:16 -0400
committerKevin Hoerr <kjhoerr@submelon.dev>2026-04-16 17:06:16 -0400
commit223a91e938bc019cad1566753eb6bb61c3cec779 (patch)
tree8f2d2c69313cc94b45bf73cdbd9ba7eb97295b23
parentf7132dc28043fd375e74328e3acff5282927caf1 (diff)
downloadequity-tracker-223a91e938bc019cad1566753eb6bb61c3cec779.tar.gz
equity-tracker-223a91e938bc019cad1566753eb6bb61c3cec779.tar.bz2
equity-tracker-223a91e938bc019cad1566753eb6bb61c3cec779.zip
records.rs: Utility
-rw-r--r--src/app/store/records.rs90
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