From e4bd11317a72ff6d3152d8dd88b16d9105868344 Mon Sep 17 00:00:00 2001 From: nym21 Date: Mon, 9 Mar 2026 12:13:33 +0100 Subject: [PATCH] computer: snapshot --- .../src/internal/from_height/amount/base.rs | 106 +++++++++++++++++ .../src/internal/from_height/amount/mod.rs | 111 +----------------- .../src/internal/from_height/ratio/base.rs | 71 +++++++++++ .../src/internal/from_height/ratio/mod.rs | 73 +----------- .../src/internal/from_height/stddev/base.rs | 75 ++++++++++++ .../src/internal/from_height/stddev/mod.rs | 78 +----------- 6 files changed, 259 insertions(+), 255 deletions(-) create mode 100644 crates/brk_computer/src/internal/from_height/amount/base.rs create mode 100644 crates/brk_computer/src/internal/from_height/ratio/base.rs create mode 100644 crates/brk_computer/src/internal/from_height/stddev/base.rs diff --git a/crates/brk_computer/src/internal/from_height/amount/base.rs b/crates/brk_computer/src/internal/from_height/amount/base.rs new file mode 100644 index 000000000..8a542afdb --- /dev/null +++ b/crates/brk_computer/src/internal/from_height/amount/base.rs @@ -0,0 +1,106 @@ +use brk_error::Result; +use brk_traversable::Traversable; +use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version}; +use vecdb::{AnyVec, Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode}; + +use crate::{ + indexes, + internal::{ + CentsUnsignedToDollars, ComputedFromHeight, LazyFromHeight, SatsToBitcoin, SatsToCents, + Windows, + }, + prices, +}; + +#[derive(Traversable)] +pub struct AmountFromHeight { + pub sats: ComputedFromHeight, + pub btc: LazyFromHeight, + pub cents: ComputedFromHeight, + pub usd: LazyFromHeight, +} + +impl AmountFromHeight { + pub(crate) fn forced_import( + db: &Database, + name: &str, + version: Version, + indexes: &indexes::Vecs, + ) -> Result { + let sats = + ComputedFromHeight::forced_import(db, &format!("{name}_sats"), version, indexes)?; + + let btc = LazyFromHeight::from_computed::( + name, + version, + sats.height.read_only_boxed_clone(), + &sats, + ); + + let cents = + ComputedFromHeight::forced_import(db, &format!("{name}_cents"), version, indexes)?; + + let usd = LazyFromHeight::from_computed::( + &format!("{name}_usd"), + version, + cents.height.read_only_boxed_clone(), + ¢s, + ); + + Ok(Self { + sats, + btc, + cents, + usd, + }) + } + + pub(crate) fn min_stateful_len(&self) -> usize { + self.sats.height.len() + } + + pub(crate) fn compute( + &mut self, + prices: &prices::Vecs, + max_from: Height, + exit: &Exit, + ) -> Result<()> { + self.cents.compute_binary::( + max_from, + &self.sats.height, + &prices.price.cents.height, + exit, + )?; + Ok(()) + } + + pub(crate) fn compute_rolling_sum( + &mut self, + max_from: Height, + window_starts: &impl ReadableVec, + sats_source: &impl ReadableVec, + cents_source: &impl ReadableVec, + exit: &Exit, + ) -> Result<()> { + self.sats + .height + .compute_rolling_sum(max_from, window_starts, sats_source, exit)?; + self.cents + .height + .compute_rolling_sum(max_from, window_starts, cents_source, exit)?; + Ok(()) + } +} + +impl Windows { + pub(crate) fn forced_import( + db: &Database, + name: &str, + version: Version, + indexes: &indexes::Vecs, + ) -> Result { + Windows::try_from_fn(|suffix| { + AmountFromHeight::forced_import(db, &format!("{name}_{suffix}"), version, indexes) + }) + } +} diff --git a/crates/brk_computer/src/internal/from_height/amount/mod.rs b/crates/brk_computer/src/internal/from_height/amount/mod.rs index d0e61ddba..61eb8b807 100644 --- a/crates/brk_computer/src/internal/from_height/amount/mod.rs +++ b/crates/brk_computer/src/internal/from_height/amount/mod.rs @@ -1,3 +1,4 @@ +mod base; mod cumulative; mod cumulative_sum; mod full; @@ -8,119 +9,13 @@ mod rolling_full; mod rolling_sum; mod windows; -use brk_error::Result; -use brk_traversable::Traversable; -use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version}; -use vecdb::{AnyVec, Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode}; - -use crate::{ - indexes, - internal::{ - CentsUnsignedToDollars, ComputedFromHeight, LazyFromHeight, SatsToBitcoin, SatsToCents, - Windows, - }, - prices, -}; - +pub use base::*; pub use cumulative::*; pub use cumulative_sum::*; pub use full::*; pub use lazy::*; +pub use lazy_derived::*; pub use rolling::*; pub use rolling_full::*; pub use rolling_sum::*; -pub use lazy_derived::*; pub use windows::*; - -#[derive(Traversable)] -pub struct AmountFromHeight { - pub sats: ComputedFromHeight, - pub btc: LazyFromHeight, - pub cents: ComputedFromHeight, - pub usd: LazyFromHeight, -} - -impl AmountFromHeight { - pub(crate) fn forced_import( - db: &Database, - name: &str, - version: Version, - indexes: &indexes::Vecs, - ) -> Result { - let sats = - ComputedFromHeight::forced_import(db, &format!("{name}_sats"), version, indexes)?; - - let btc = LazyFromHeight::from_computed::( - name, - version, - sats.height.read_only_boxed_clone(), - &sats, - ); - - let cents = - ComputedFromHeight::forced_import(db, &format!("{name}_cents"), version, indexes)?; - - let usd = LazyFromHeight::from_computed::( - &format!("{name}_usd"), - version, - cents.height.read_only_boxed_clone(), - ¢s, - ); - - Ok(Self { - sats, - btc, - cents, - usd, - }) - } - - pub(crate) fn min_stateful_len(&self) -> usize { - self.sats.height.len() - } - - pub(crate) fn compute( - &mut self, - prices: &prices::Vecs, - max_from: Height, - exit: &Exit, - ) -> Result<()> { - self.cents.compute_binary::( - max_from, - &self.sats.height, - &prices.price.cents.height, - exit, - )?; - Ok(()) - } - - pub(crate) fn compute_rolling_sum( - &mut self, - max_from: Height, - window_starts: &impl ReadableVec, - sats_source: &impl ReadableVec, - cents_source: &impl ReadableVec, - exit: &Exit, - ) -> Result<()> { - self.sats - .height - .compute_rolling_sum(max_from, window_starts, sats_source, exit)?; - self.cents - .height - .compute_rolling_sum(max_from, window_starts, cents_source, exit)?; - Ok(()) - } -} - -impl Windows { - pub(crate) fn forced_import( - db: &Database, - name: &str, - version: Version, - indexes: &indexes::Vecs, - ) -> Result { - Windows::try_from_fn(|suffix| { - AmountFromHeight::forced_import(db, &format!("{name}_{suffix}"), version, indexes) - }) - } -} diff --git a/crates/brk_computer/src/internal/from_height/ratio/base.rs b/crates/brk_computer/src/internal/from_height/ratio/base.rs new file mode 100644 index 000000000..0d738c034 --- /dev/null +++ b/crates/brk_computer/src/internal/from_height/ratio/base.rs @@ -0,0 +1,71 @@ +use brk_error::Result; +use brk_traversable::Traversable; +use brk_types::{BasisPoints32, Cents, Height, Indexes, StoredF32, Version}; +use vecdb::{Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode}; + +use crate::{ + indexes, + internal::{Bp32ToFloat, ComputedFromHeight, LazyFromHeight}, +}; + +#[derive(Traversable)] +pub struct ComputedFromHeightRatio { + pub bps: ComputedFromHeight, + pub ratio: LazyFromHeight, +} + +const VERSION: Version = Version::TWO; + +impl ComputedFromHeightRatio { + pub(crate) fn forced_import( + db: &Database, + name: &str, + version: Version, + indexes: &indexes::Vecs, + ) -> Result { + Self::forced_import_raw(db, &format!("{name}_ratio"), version, indexes) + } + + pub(crate) fn forced_import_raw( + db: &Database, + name: &str, + version: Version, + indexes: &indexes::Vecs, + ) -> Result { + let v = version + VERSION; + + let bps = ComputedFromHeight::forced_import(db, &format!("{name}_bps"), v, indexes)?; + + let ratio = LazyFromHeight::from_computed::( + name, + v, + bps.height.read_only_boxed_clone(), + &bps, + ); + + Ok(Self { bps, ratio }) + } + + pub(crate) fn compute_ratio( + &mut self, + starting_indexes: &Indexes, + close_price: &impl ReadableVec, + metric_price: &impl ReadableVec, + exit: &Exit, + ) -> Result<()> { + self.bps.height.compute_transform2( + starting_indexes.height, + close_price, + metric_price, + |(i, close, price, ..)| { + if price == Cents::ZERO { + (i, BasisPoints32::from(1.0)) + } else { + (i, BasisPoints32::from(f64::from(close) / f64::from(price))) + } + }, + exit, + )?; + Ok(()) + } +} diff --git a/crates/brk_computer/src/internal/from_height/ratio/mod.rs b/crates/brk_computer/src/internal/from_height/ratio/mod.rs index 51ea8db22..0a97bc602 100644 --- a/crates/brk_computer/src/internal/from_height/ratio/mod.rs +++ b/crates/brk_computer/src/internal/from_height/ratio/mod.rs @@ -1,80 +1,11 @@ +mod base; mod extended; mod percentiles; mod price_extended; mod std_dev_bands; +pub use base::*; pub use extended::*; pub use percentiles::*; pub use price_extended::*; pub use std_dev_bands::*; - -use brk_error::Result; -use brk_traversable::Traversable; -use brk_types::{BasisPoints32, Cents, Height, Indexes, StoredF32, Version}; -use vecdb::{Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode}; - -use crate::{indexes, internal::Bp32ToFloat}; - -use super::{ComputedFromHeight, LazyFromHeight}; - -#[derive(Traversable)] -pub struct ComputedFromHeightRatio { - pub bps: ComputedFromHeight, - pub ratio: LazyFromHeight, -} - -const VERSION: Version = Version::TWO; - -impl ComputedFromHeightRatio { - pub(crate) fn forced_import( - db: &Database, - name: &str, - version: Version, - indexes: &indexes::Vecs, - ) -> Result { - Self::forced_import_raw(db, &format!("{name}_ratio"), version, indexes) - } - - pub(crate) fn forced_import_raw( - db: &Database, - name: &str, - version: Version, - indexes: &indexes::Vecs, - ) -> Result { - let v = version + VERSION; - - let bps = ComputedFromHeight::forced_import(db, &format!("{name}_bps"), v, indexes)?; - - let ratio = LazyFromHeight::from_computed::( - name, - v, - bps.height.read_only_boxed_clone(), - &bps, - ); - - Ok(Self { bps, ratio }) - } - - pub(crate) fn compute_ratio( - &mut self, - starting_indexes: &Indexes, - close_price: &impl ReadableVec, - metric_price: &impl ReadableVec, - exit: &Exit, - ) -> Result<()> { - self.bps.height.compute_transform2( - starting_indexes.height, - close_price, - metric_price, - |(i, close, price, ..)| { - if price == Cents::ZERO { - (i, BasisPoints32::from(1.0)) - } else { - (i, BasisPoints32::from(f64::from(close) / f64::from(price))) - } - }, - exit, - )?; - Ok(()) - } -} diff --git a/crates/brk_computer/src/internal/from_height/stddev/base.rs b/crates/brk_computer/src/internal/from_height/stddev/base.rs new file mode 100644 index 000000000..fca17d7e7 --- /dev/null +++ b/crates/brk_computer/src/internal/from_height/stddev/base.rs @@ -0,0 +1,75 @@ +use brk_error::Result; +use brk_traversable::Traversable; +use brk_types::{Height, Indexes, StoredF32, Version}; +use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode}; + +use crate::{blocks, indexes, internal::ComputedFromHeight}; + +use super::period_suffix; + +#[derive(Traversable)] +pub struct ComputedFromHeightStdDev { + days: usize, + pub sma: ComputedFromHeight, + pub sd: ComputedFromHeight, +} + +impl ComputedFromHeightStdDev { + pub(crate) fn forced_import( + db: &Database, + name: &str, + period: &str, + days: usize, + parent_version: Version, + indexes: &indexes::Vecs, + ) -> Result { + let version = parent_version + Version::TWO; + let p = period_suffix(period); + + let sma = + ComputedFromHeight::forced_import(db, &format!("{name}_sma{p}"), version, indexes)?; + let sd = ComputedFromHeight::forced_import(db, &format!("{name}_sd{p}"), version, indexes)?; + + Ok(Self { days, sma, sd }) + } + + pub(crate) fn compute_all( + &mut self, + blocks: &blocks::Vecs, + starting_indexes: &Indexes, + exit: &Exit, + source: &impl ReadableVec, + ) -> Result<()> { + if self.days == usize::MAX { + self.sma + .height + .compute_sma_(starting_indexes.height, source, usize::MAX, exit, None)?; + self.sd.height.compute_expanding_sd( + starting_indexes.height, + source, + &self.sma.height, + exit, + )?; + return Ok(()); + } + + let window_starts = blocks.lookback.start_vec(self.days); + + self.sma.height.compute_rolling_average( + starting_indexes.height, + window_starts, + source, + exit, + )?; + + self.sd.height.compute_rolling_sd( + starting_indexes.height, + window_starts, + source, + &self.sma.height, + exit, + )?; + + Ok(()) + } +} diff --git a/crates/brk_computer/src/internal/from_height/stddev/mod.rs b/crates/brk_computer/src/internal/from_height/stddev/mod.rs index d69028b33..cc909c00e 100644 --- a/crates/brk_computer/src/internal/from_height/stddev/mod.rs +++ b/crates/brk_computer/src/internal/from_height/stddev/mod.rs @@ -1,16 +1,9 @@ +mod base; mod extended; +pub use base::*; pub use extended::*; -use brk_error::Result; -use brk_traversable::Traversable; -use brk_types::{Height, Indexes, StoredF32, Version}; -use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode}; - -use crate::{blocks, indexes}; - -use crate::internal::ComputedFromHeight; - fn period_suffix(period: &str) -> String { if period.is_empty() { String::new() @@ -18,70 +11,3 @@ fn period_suffix(period: &str) -> String { format!("_{period}") } } - -#[derive(Traversable)] -pub struct ComputedFromHeightStdDev { - days: usize, - pub sma: ComputedFromHeight, - pub sd: ComputedFromHeight, -} - -impl ComputedFromHeightStdDev { - pub(crate) fn forced_import( - db: &Database, - name: &str, - period: &str, - days: usize, - parent_version: Version, - indexes: &indexes::Vecs, - ) -> Result { - let version = parent_version + Version::TWO; - let p = period_suffix(period); - - let sma = - ComputedFromHeight::forced_import(db, &format!("{name}_sma{p}"), version, indexes)?; - let sd = ComputedFromHeight::forced_import(db, &format!("{name}_sd{p}"), version, indexes)?; - - Ok(Self { days, sma, sd }) - } - - pub(crate) fn compute_all( - &mut self, - blocks: &blocks::Vecs, - starting_indexes: &Indexes, - exit: &Exit, - source: &impl ReadableVec, - ) -> Result<()> { - if self.days == usize::MAX { - self.sma - .height - .compute_sma_(starting_indexes.height, source, usize::MAX, exit, None)?; - self.sd.height.compute_expanding_sd( - starting_indexes.height, - source, - &self.sma.height, - exit, - )?; - return Ok(()); - } - - let window_starts = blocks.lookback.start_vec(self.days); - - self.sma.height.compute_rolling_average( - starting_indexes.height, - window_starts, - source, - exit, - )?; - - self.sd.height.compute_rolling_sd( - starting_indexes.height, - window_starts, - source, - &self.sma.height, - exit, - )?; - - Ok(()) - } -}