global: snapshot

This commit is contained in:
nym21
2026-02-01 22:38:01 +01:00
parent f03bbd9a92
commit f7d7c5704a
47 changed files with 2924 additions and 837 deletions

View File

@@ -832,4 +832,41 @@ where
decadeindex: period!(decadeindex),
}
}
/// Create from a ComputedFromDateLast and a LazyDateDerivedLast.
pub fn from_computed_and_derived_last<F: BinaryTransform<S1T, S2T, T>>(
name: &str,
version: Version,
source1: &ComputedFromDateLast<S1T>,
dateindex_source2: IterableBoxedVec<DateIndex, S2T>,
source2: &LazyDateDerivedLast<S2T>,
) -> Self {
let v = version + VERSION;
macro_rules! period {
($p:ident) => {
LazyBinaryTransformLast::from_lazy_last::<F, _, _, _, _>(
name,
v,
&source1.$p,
&source2.$p,
)
};
}
Self {
dateindex: LazyVecFrom2::transformed::<F>(
name,
v,
source1.dateindex.boxed_clone(),
dateindex_source2,
),
weekindex: period!(weekindex),
monthindex: period!(monthindex),
quarterindex: period!(quarterindex),
semesterindex: period!(semesterindex),
yearindex: period!(yearindex),
decadeindex: period!(decadeindex),
}
}
}

View File

@@ -7,7 +7,10 @@ use brk_types::{
use schemars::JsonSchema;
use vecdb::{BinaryTransform, IterableCloneableVec};
use crate::internal::{ComputedVecValue, ComputedHeightDerivedSum, LazyBinaryTransformSum, NumericValue};
use crate::internal::{
ComputedFromHeightSumCum, ComputedHeightDerivedSum, ComputedVecValue, LazyBinaryTransformSum,
LazyFromHeightLast, NumericValue,
};
const VERSION: Version = Version::ZERO;
@@ -91,4 +94,41 @@ where
decadeindex: period!(decadeindex),
}
}
/// Create from a SumCum source (using only sum) and a LazyLast source.
pub fn from_sumcum_lazy_last<F, S2ST>(
name: &str,
version: Version,
source1: &ComputedFromHeightSumCum<S1T>,
source2: &LazyFromHeightLast<S2T, S2ST>,
) -> Self
where
F: BinaryTransform<S1T, S2T, T>,
S2ST: ComputedVecValue + JsonSchema,
{
let v = version + VERSION;
// source1 has SumCum pattern with .dateindex.sum, .weekindex.sum, etc.
// source2 has Last pattern via deref chain: .dates.dateindex, .dates.weekindex, etc.
macro_rules! period {
($p:ident) => {
LazyBinaryTransformSum::from_boxed::<F>(
name,
v,
source1.$p.sum.boxed_clone(),
source2.dates.$p.boxed_clone(),
)
};
}
Self {
dateindex: period!(dateindex),
weekindex: period!(weekindex),
monthindex: period!(monthindex),
quarterindex: period!(quarterindex),
semesterindex: period!(semesterindex),
yearindex: period!(yearindex),
decadeindex: period!(decadeindex),
}
}
}

View File

@@ -19,6 +19,8 @@ mod price;
mod ratio;
mod stddev;
mod unary_last;
mod value_change;
mod value_change_derived;
mod value_derived_last;
mod value_last;
mod value_lazy_last;
@@ -44,6 +46,8 @@ pub use price::*;
pub use ratio::*;
pub use stddev::*;
pub use unary_last::*;
pub use value_change::*;
pub use value_change_derived::*;
pub use value_derived_last::*;
pub use value_last::*;
pub use value_lazy_last::*;

View File

@@ -0,0 +1,77 @@
//! Change values from DateIndex - stores signed sats (changes can be negative).
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{DateIndex, Dollars, Sats, SatsSigned, Version};
use vecdb::{CollectableVec, Database, EagerVec, Exit, ImportableVec, IterableCloneableVec, PcoVec};
use crate::{ComputeIndexes, indexes, price};
use super::LazyValueChangeDateDerived;
const VERSION: Version = Version::ZERO;
/// Change values indexed by date - uses signed sats since changes can be negative.
#[derive(Clone, Traversable)]
#[traversable(merge)]
pub struct ValueChangeFromDate {
#[traversable(rename = "sats")]
pub sats: EagerVec<PcoVec<DateIndex, SatsSigned>>,
#[traversable(flatten)]
pub rest: LazyValueChangeDateDerived,
}
impl ValueChangeFromDate {
pub fn forced_import(
db: &Database,
name: &str,
version: Version,
compute_dollars: bool,
indexes: &indexes::Vecs,
) -> Result<Self> {
let sats = EagerVec::forced_import(db, name, version + VERSION)?;
let rest = LazyValueChangeDateDerived::from_source(
db,
name,
sats.boxed_clone(),
version + VERSION,
compute_dollars,
indexes,
)?;
Ok(Self { sats, rest })
}
/// Compute N-day change from unsigned sats source and optional dollars source.
pub fn compute_change(
&mut self,
starting_dateindex: DateIndex,
sats_source: &impl CollectableVec<DateIndex, Sats>,
dollars_source: Option<&impl CollectableVec<DateIndex, Dollars>>,
period: usize,
exit: &Exit,
) -> Result<()> {
self.sats
.compute_change(starting_dateindex, sats_source, period, exit)?;
if let (Some(dollars), Some(source)) = (self.rest.dollars.as_mut(), dollars_source) {
dollars
.dateindex
.compute_change(starting_dateindex, source, period, exit)?;
}
Ok(())
}
/// Compute dollars from price after sats change is computed.
pub fn compute_dollars_from_price(
&mut self,
price: Option<&price::Vecs>,
starting_indexes: &ComputeIndexes,
exit: &Exit,
) -> Result<()> {
self.rest
.compute_dollars_from_price(price, starting_indexes, exit)
}
}

View File

@@ -0,0 +1,84 @@
//! Lazy derived values for change (bitcoin from sats, period aggregations).
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Bitcoin, DateIndex, Dollars, SatsSigned, Version};
use vecdb::{Database, Exit, IterableBoxedVec};
use crate::{
ComputeIndexes, indexes,
internal::{ComputedFromDateLast, LazyDateDerivedLast, LazyFromDateLast, SatsSignedToBitcoin},
price,
traits::ComputeFromBitcoin,
utils::OptionExt,
};
const VERSION: Version = Version::ZERO;
/// Lazy derived values for change (bitcoin from sats, period aggregations).
#[derive(Clone, Traversable)]
pub struct LazyValueChangeDateDerived {
pub sats: LazyDateDerivedLast<SatsSigned>,
pub bitcoin: LazyFromDateLast<Bitcoin, SatsSigned>,
pub dollars: Option<ComputedFromDateLast<Dollars>>,
}
impl LazyValueChangeDateDerived {
pub fn from_source(
db: &Database,
name: &str,
source: IterableBoxedVec<DateIndex, SatsSigned>,
version: Version,
compute_dollars: bool,
indexes: &indexes::Vecs,
) -> Result<Self> {
let sats =
LazyDateDerivedLast::from_source(name, version + VERSION, source.clone(), indexes);
let bitcoin = LazyFromDateLast::from_derived::<SatsSignedToBitcoin>(
&format!("{name}_btc"),
version + VERSION,
source,
&sats,
);
let dollars = compute_dollars
.then(|| {
ComputedFromDateLast::forced_import(
db,
&format!("{name}_usd"),
version + VERSION,
indexes,
)
})
.transpose()?;
Ok(Self {
sats,
bitcoin,
dollars,
})
}
pub fn compute_dollars_from_price(
&mut self,
price: Option<&price::Vecs>,
starting_indexes: &ComputeIndexes,
exit: &Exit,
) -> Result<()> {
if let Some(dollars) = self.dollars.as_mut() {
let dateindex_to_bitcoin = &*self.bitcoin.dateindex;
let dateindex_to_price_close = &price.u().usd.split.close.dateindex;
dollars.compute_all(starting_indexes, exit, |v| {
v.compute_from_bitcoin(
starting_indexes.dateindex,
dateindex_to_bitcoin,
dateindex_to_price_close,
exit,
)
})?;
}
Ok(())
}
}

View File

@@ -2,13 +2,13 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{DateIndex, Sats, Version};
use brk_types::{DateIndex, Dollars, Sats, Version};
use derive_more::{Deref, DerefMut};
use vecdb::{Database, EagerVec, Exit, ImportableVec, IterableCloneableVec, PcoVec};
use vecdb::{CollectableVec, Database, EagerVec, Exit, ImportableVec, IterableCloneableVec, PcoVec};
use crate::{ComputeIndexes, indexes, price};
use super::LazyValueDateDerivedLast;
use super::{ComputedFromDateLast, LazyValueDateDerivedLast};
#[derive(Clone, Deref, DerefMut, Traversable)]
#[traversable(merge)]
@@ -70,7 +70,7 @@ impl ValueFromDateLast {
pub fn compute_dollars<F>(&mut self, compute: F) -> Result<()>
where
F: FnMut(&mut crate::internal::ComputedFromDateLast<brk_types::Dollars>) -> Result<()>,
F: FnMut(&mut ComputedFromDateLast<Dollars>) -> Result<()>,
{
self.rest.compute_dollars(compute)
}
@@ -84,4 +84,63 @@ impl ValueFromDateLast {
self.rest
.compute_dollars_from_price(price, starting_indexes, exit)
}
/// Compute both sats and dollars using provided closures.
pub fn compute_both<S, D>(
&mut self,
compute_sats: S,
compute_dollars: D,
) -> Result<()>
where
S: FnOnce(&mut EagerVec<PcoVec<DateIndex, Sats>>) -> Result<()>,
D: FnOnce(&mut ComputedFromDateLast<Dollars>) -> Result<()>,
{
compute_sats(&mut self.sats_dateindex)?;
if let Some(dollars) = self.rest.dollars.as_mut() {
compute_dollars(dollars)?;
}
Ok(())
}
/// Compute EMA for sats and optionally dollars from source vecs.
pub fn compute_ema(
&mut self,
starting_dateindex: DateIndex,
sats_source: &impl CollectableVec<DateIndex, Sats>,
dollars_source: Option<&impl CollectableVec<DateIndex, Dollars>>,
period: usize,
exit: &Exit,
) -> Result<()> {
self.sats_dateindex
.compute_ema(starting_dateindex, sats_source, period, exit)?;
if let (Some(dollars), Some(source)) = (self.rest.dollars.as_mut(), dollars_source) {
dollars
.dateindex
.compute_ema(starting_dateindex, source, period, exit)?;
}
Ok(())
}
/// Compute N-day change for sats and optionally dollars from source vecs.
pub fn compute_change(
&mut self,
starting_dateindex: DateIndex,
sats_source: &impl CollectableVec<DateIndex, Sats>,
dollars_source: Option<&impl CollectableVec<DateIndex, Dollars>>,
period: usize,
exit: &Exit,
) -> Result<()> {
self.sats_dateindex
.compute_change(starting_dateindex, sats_source, period, exit)?;
if let (Some(dollars), Some(source)) = (self.rest.dollars.as_mut(), dollars_source) {
dollars
.dateindex
.compute_change(starting_dateindex, source, period, exit)?;
}
Ok(())
}
}

View File

@@ -7,8 +7,8 @@ use schemars::JsonSchema;
use vecdb::{BinaryTransform, IterableBoxedVec, IterableCloneableVec, LazyVecFrom2};
use crate::internal::{
ComputedFromHeightSum, ComputedHeightDerivedSum, ComputedVecValue, LazyBinaryHeightDerivedSum,
NumericValue,
ComputedFromHeightSum, ComputedFromHeightSumCum, ComputedHeightDerivedSum, ComputedVecValue,
LazyBinaryHeightDerivedSum, LazyFromHeightLast, NumericValue,
};
const VERSION: Version = Version::ZERO;
@@ -100,4 +100,31 @@ where
),
}
}
/// Create from a SumCum source (using only sum) and a LazyLast source.
/// Produces sum-only output (no cumulative).
pub fn from_sumcum_lazy_last<F, S2ST>(
name: &str,
version: Version,
height_source1: IterableBoxedVec<Height, S1T>,
height_source2: IterableBoxedVec<Height, S2T>,
source1: &ComputedFromHeightSumCum<S1T>,
source2: &LazyFromHeightLast<S2T, S2ST>,
) -> Self
where
F: BinaryTransform<S1T, S2T, T>,
S2ST: ComputedVecValue + JsonSchema,
{
let v = version + VERSION;
Self {
height: LazyVecFrom2::transformed::<F>(name, v, height_source1, height_source2),
rest: LazyBinaryHeightDerivedSum::from_sumcum_lazy_last::<F, S2ST>(
name,
v,
source1,
source2,
),
}
}
}

View File

@@ -6,7 +6,10 @@ use derive_more::{Deref, DerefMut};
use schemars::JsonSchema;
use vecdb::{BinaryTransform, IterableCloneableVec};
use crate::internal::{ComputedVecValue, ComputedHeightDerivedSum, LazyBinaryFromDateSum, LazyBinaryTransformSum, NumericValue};
use crate::internal::{
ComputedFromHeightSumCum, ComputedHeightDerivedSum, ComputedVecValue, LazyBinaryFromDateSum,
LazyBinaryTransformSum, LazyFromHeightLast, NumericValue,
};
const VERSION: Version = Version::ZERO;
@@ -80,4 +83,33 @@ where
),
}
}
/// Create from a SumCum source (using only sum) and a LazyLast source.
pub fn from_sumcum_lazy_last<F, S2ST>(
name: &str,
version: Version,
source1: &ComputedFromHeightSumCum<S1T>,
source2: &LazyFromHeightLast<S2T, S2ST>,
) -> Self
where
F: BinaryTransform<S1T, S2T, T>,
S2ST: ComputedVecValue + JsonSchema,
{
let v = version + VERSION;
Self {
dates: LazyBinaryFromDateSum::from_sumcum_lazy_last::<F, S2ST>(
name,
v,
source1,
source2,
),
difficultyepoch: LazyBinaryTransformSum::from_boxed::<F>(
name,
v,
source1.difficultyepoch.sum.boxed_clone(),
source2.difficultyepoch.boxed_clone(),
),
}
}
}