mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-25 23:29:58 -07:00
global: snapshot
This commit is contained in:
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::*;
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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(())
|
||||
}
|
||||
}
|
||||
@@ -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(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user