mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-13 03:58:12 -07:00
global: snapshot
This commit is contained in:
@@ -25,7 +25,7 @@ use crate::{
|
||||
|
||||
/// Pre-collect source data from the earliest needed offset.
|
||||
/// Returns (source_data, offset) for use in compute_delta_window.
|
||||
fn collect_source<S: NumericValue>(
|
||||
pub(super) fn collect_source<S: NumericValue>(
|
||||
source: &impl ReadableVec<Height, S>,
|
||||
skip: usize,
|
||||
earliest_starts: &impl ReadableVec<Height, Height>,
|
||||
@@ -40,7 +40,7 @@ fn collect_source<S: NumericValue>(
|
||||
}
|
||||
|
||||
/// Shared computation: change = current - ago, rate = change / ago.
|
||||
fn compute_delta_window<S, C, B>(
|
||||
pub(super) fn compute_delta_window<S, C, B>(
|
||||
change_h: &mut EagerVec<PcoVec<Height, C>>,
|
||||
rate_bps_h: &mut EagerVec<PcoVec<Height, B>>,
|
||||
max_from: Height,
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
//! Fiat delta variants — same as RollingDelta* but change is FiatFromHeight<C>
|
||||
//! (stored cents + lazy USD) instead of ComputedFromHeight<C> (stored cents only).
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{BasisPointsSigned32, Height, Version};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{AnyVec, Database, Exit, ReadableVec, Rw, StorageMode};
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
CentsType, FiatFromHeight, NumericValue, PercentFromHeight, PercentRollingWindows,
|
||||
WindowStarts,
|
||||
},
|
||||
};
|
||||
|
||||
use super::delta::{collect_source, compute_delta_window};
|
||||
|
||||
/// Fiat 1m-only delta: fiat change (cents + usd) + rate for the 1-month window.
|
||||
#[derive(Traversable)]
|
||||
pub struct FiatRollingDelta1m<S, C, M: StorageMode = Rw>
|
||||
where
|
||||
S: NumericValue + JsonSchema,
|
||||
C: CentsType,
|
||||
{
|
||||
pub change_1m: FiatFromHeight<C, M>,
|
||||
pub rate_1m: PercentFromHeight<BasisPointsSigned32, M>,
|
||||
_phantom: std::marker::PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<S, C> FiatRollingDelta1m<S, C>
|
||||
where
|
||||
S: NumericValue + JsonSchema,
|
||||
C: CentsType,
|
||||
{
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
change_1m: FiatFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_change_1m"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
rate_1m: PercentFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_rate_1m"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
_phantom: std::marker::PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn compute(
|
||||
&mut self,
|
||||
max_from: Height,
|
||||
height_1m_ago: &impl ReadableVec<Height, Height>,
|
||||
source: &impl ReadableVec<Height, S>,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
let skip = self.change_1m.cents.height.len();
|
||||
let (source_data, offset) = collect_source(source, skip, height_1m_ago);
|
||||
|
||||
compute_delta_window(
|
||||
&mut self.change_1m.cents.height,
|
||||
&mut self.rate_1m.bps.height,
|
||||
max_from,
|
||||
height_1m_ago,
|
||||
&source_data,
|
||||
offset,
|
||||
exit,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Fiat extended delta: 24h + 1w + 1y windows, fiat change (cents + usd) + rate.
|
||||
#[derive(Traversable)]
|
||||
pub struct FiatRollingDeltaExcept1m<S, C, M: StorageMode = Rw>
|
||||
where
|
||||
S: NumericValue + JsonSchema,
|
||||
C: CentsType,
|
||||
{
|
||||
#[traversable(rename = "24h")]
|
||||
pub change_24h: FiatFromHeight<C, M>,
|
||||
pub change_1w: FiatFromHeight<C, M>,
|
||||
pub change_1y: FiatFromHeight<C, M>,
|
||||
#[traversable(rename = "24h")]
|
||||
pub rate_24h: PercentFromHeight<BasisPointsSigned32, M>,
|
||||
pub rate_1w: PercentFromHeight<BasisPointsSigned32, M>,
|
||||
pub rate_1y: PercentFromHeight<BasisPointsSigned32, M>,
|
||||
_phantom: std::marker::PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<S, C> FiatRollingDeltaExcept1m<S, C>
|
||||
where
|
||||
S: NumericValue + JsonSchema,
|
||||
C: CentsType,
|
||||
{
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
change_24h: FiatFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_change_24h"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
change_1w: FiatFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_change_1w"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
change_1y: FiatFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_change_1y"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
rate_24h: PercentFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_rate_24h"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
rate_1w: PercentFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_rate_1w"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
rate_1y: PercentFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_rate_1y"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
_phantom: std::marker::PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn compute(
|
||||
&mut self,
|
||||
max_from: Height,
|
||||
windows: &WindowStarts<'_>,
|
||||
source: &impl ReadableVec<Height, S>,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
let skip = self.change_24h.cents.height.len();
|
||||
let (source_data, offset) = collect_source(source, skip, windows._1y);
|
||||
|
||||
let changes: [&mut FiatFromHeight<C>; 3] =
|
||||
[&mut self.change_24h, &mut self.change_1w, &mut self.change_1y];
|
||||
let rates = [&mut self.rate_24h, &mut self.rate_1w, &mut self.rate_1y];
|
||||
let starts = [windows._24h, windows._1w, windows._1y];
|
||||
|
||||
for ((change_w, rate_w), starts) in changes.into_iter().zip(rates).zip(starts) {
|
||||
compute_delta_window(
|
||||
&mut change_w.cents.height,
|
||||
&mut rate_w.bps.height,
|
||||
max_from,
|
||||
starts,
|
||||
&source_data,
|
||||
offset,
|
||||
exit,
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Fiat rolling delta: all 4 windows, fiat change (cents + usd) + rate.
|
||||
#[derive(Traversable)]
|
||||
pub struct FiatRollingDelta<S, C, M: StorageMode = Rw>
|
||||
where
|
||||
S: NumericValue + JsonSchema,
|
||||
C: CentsType,
|
||||
{
|
||||
pub change_24h: FiatFromHeight<C, M>,
|
||||
pub change_1w: FiatFromHeight<C, M>,
|
||||
pub change_1m: FiatFromHeight<C, M>,
|
||||
pub change_1y: FiatFromHeight<C, M>,
|
||||
pub rate: PercentRollingWindows<BasisPointsSigned32, M>,
|
||||
_phantom: std::marker::PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<S, C> FiatRollingDelta<S, C>
|
||||
where
|
||||
S: NumericValue + JsonSchema,
|
||||
C: CentsType,
|
||||
{
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
change_24h: FiatFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_change_24h"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
change_1w: FiatFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_change_1w"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
change_1m: FiatFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_change_1m"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
change_1y: FiatFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_change_1y"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
rate: PercentRollingWindows::forced_import(
|
||||
db,
|
||||
&format!("{name}_rate"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
_phantom: std::marker::PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn compute(
|
||||
&mut self,
|
||||
max_from: Height,
|
||||
windows: &WindowStarts<'_>,
|
||||
source: &impl ReadableVec<Height, S>,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
let skip = self.change_24h.cents.height.len();
|
||||
let (source_data, offset) = collect_source(source, skip, windows._1y);
|
||||
|
||||
let changes: [&mut FiatFromHeight<C>; 4] = [
|
||||
&mut self.change_24h,
|
||||
&mut self.change_1w,
|
||||
&mut self.change_1m,
|
||||
&mut self.change_1y,
|
||||
];
|
||||
let rates = self.rate.0.as_mut_array();
|
||||
let starts = windows.as_array();
|
||||
|
||||
for ((change_w, rate_w), starts) in changes.into_iter().zip(rates).zip(starts) {
|
||||
compute_delta_window(
|
||||
&mut change_w.cents.height,
|
||||
&mut rate_w.bps.height,
|
||||
max_from,
|
||||
*starts,
|
||||
&source_data,
|
||||
offset,
|
||||
exit,
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ mod aggregated;
|
||||
mod cumulative;
|
||||
mod cumulative_sum;
|
||||
mod delta;
|
||||
mod fiat_delta;
|
||||
mod full;
|
||||
mod rolling_average;
|
||||
mod sum;
|
||||
@@ -10,6 +11,7 @@ pub use aggregated::*;
|
||||
pub use cumulative::*;
|
||||
pub use cumulative_sum::*;
|
||||
pub use delta::*;
|
||||
pub use fiat_delta::*;
|
||||
pub use full::*;
|
||||
pub use rolling_average::*;
|
||||
pub use sum::*;
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Dollars, Version};
|
||||
use vecdb::ReadableCloneableVec;
|
||||
|
||||
use super::{ComputedFromHeight, LazyFromHeight};
|
||||
use crate::internal::{Identity, NumericValue};
|
||||
|
||||
use super::fiat::CentsType;
|
||||
|
||||
/// Lazy fiat: both cents and usd are lazy views of a stored source.
|
||||
/// Zero extra stored vecs.
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct LazyFiatFromHeight<C: CentsType> {
|
||||
pub cents: LazyFromHeight<C, C>,
|
||||
pub usd: LazyFromHeight<Dollars, C>,
|
||||
}
|
||||
|
||||
impl<C: CentsType> LazyFiatFromHeight<C> {
|
||||
pub(crate) fn from_computed(
|
||||
name: &str,
|
||||
version: Version,
|
||||
source: &ComputedFromHeight<C>,
|
||||
) -> Self
|
||||
where
|
||||
C: NumericValue,
|
||||
{
|
||||
let cents = LazyFromHeight::from_computed::<Identity<C>>(
|
||||
&format!("{name}_cents"),
|
||||
version,
|
||||
source.height.read_only_boxed_clone(),
|
||||
source,
|
||||
);
|
||||
let usd = LazyFromHeight::from_computed::<C::ToDollars>(
|
||||
&format!("{name}_usd"),
|
||||
version,
|
||||
source.height.read_only_boxed_clone(),
|
||||
source,
|
||||
);
|
||||
Self { cents, usd }
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ mod computed;
|
||||
mod constant;
|
||||
mod fiat;
|
||||
mod lazy;
|
||||
mod lazy_fiat;
|
||||
mod percent;
|
||||
mod percentiles;
|
||||
mod price;
|
||||
@@ -17,6 +18,7 @@ pub use computed::*;
|
||||
pub use constant::*;
|
||||
pub use fiat::*;
|
||||
pub use lazy::*;
|
||||
pub use lazy_fiat::*;
|
||||
pub use percent::*;
|
||||
pub use percentiles::*;
|
||||
pub use price::*;
|
||||
|
||||
Reference in New Issue
Block a user