mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-04 12:11:59 -07:00
global: snapshot
This commit is contained in:
@@ -17,6 +17,23 @@ pub struct DistributionStats<A, B = A, C = A, D = A, E = A, F = A, G = A, H = A>
|
||||
}
|
||||
|
||||
impl<A> DistributionStats<A> {
|
||||
pub const SUFFIXES: [&'static str; 8] = ["average", "min", "max", "p10", "p25", "median", "p75", "p90"];
|
||||
|
||||
pub fn try_from_fn<E>(
|
||||
mut f: impl FnMut(&str) -> std::result::Result<A, E>,
|
||||
) -> std::result::Result<Self, E> {
|
||||
Ok(Self {
|
||||
average: f(Self::SUFFIXES[0])?,
|
||||
min: f(Self::SUFFIXES[1])?,
|
||||
max: f(Self::SUFFIXES[2])?,
|
||||
pct10: f(Self::SUFFIXES[3])?,
|
||||
pct25: f(Self::SUFFIXES[4])?,
|
||||
median: f(Self::SUFFIXES[5])?,
|
||||
pct75: f(Self::SUFFIXES[6])?,
|
||||
pct90: f(Self::SUFFIXES[7])?,
|
||||
})
|
||||
}
|
||||
|
||||
/// Apply a fallible operation to each of the 8 fields.
|
||||
pub fn try_for_each_mut(&mut self, mut f: impl FnMut(&mut A) -> brk_error::Result<()>) -> brk_error::Result<()> {
|
||||
f(&mut self.average)?;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! EagerIndexes - newtype on Indexes with EagerVec<PcoVec<I, T>> per field.
|
||||
//! EagerIndexes - newtype on PerPeriod with EagerVec<PcoVec<I, T>> per field.
|
||||
//!
|
||||
//! Used for data eagerly computed and stored per period during indexing,
|
||||
//! such as timestamp (first value per period) and OHLC (first/min/max per period).
|
||||
@@ -8,7 +8,7 @@ use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour4, Hour12,
|
||||
Minute10, Minute30, Month1, Month3, Month6, Version, Week1, Year1, Year10,
|
||||
Indexes, Minute10, Minute30, Month1, Month3, Month6, Version, Week1, Year1, Year10,
|
||||
};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use schemars::JsonSchema;
|
||||
@@ -18,15 +18,15 @@ use vecdb::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
ComputeIndexes, indexes, indexes_apply, indexes_from,
|
||||
internal::{ComputedVecValue, Indexes, NumericValue},
|
||||
indexes, indexes_apply, indexes_from,
|
||||
internal::{ComputedVecValue, NumericValue, PerPeriod},
|
||||
};
|
||||
|
||||
#[derive(Deref, DerefMut, Traversable)]
|
||||
#[traversable(transparent)]
|
||||
pub struct EagerIndexes<T, M: StorageMode = Rw>(
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub Indexes<
|
||||
pub PerPeriod<
|
||||
<M as StorageMode>::Stored<EagerVec<PcoVec<Minute10, T>>>,
|
||||
<M as StorageMode>::Stored<EagerVec<PcoVec<Minute30, T>>>,
|
||||
<M as StorageMode>::Stored<EagerVec<PcoVec<Hour1, T>>>,
|
||||
@@ -68,15 +68,17 @@ where
|
||||
/// Compute "first value per period" — for each period, looks up `source[first_height[period]]`.
|
||||
pub(crate) fn compute_first(
|
||||
&mut self,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
starting_indexes: &Indexes,
|
||||
height_source: &impl ReadableVec<Height, T>,
|
||||
indexes: &indexes::Vecs,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
let prev_height = starting_indexes.height.decremented().unwrap_or_default();
|
||||
|
||||
macro_rules! period {
|
||||
($field:ident) => {
|
||||
self.0.$field.compute_indirect_sequential(
|
||||
starting_indexes.$field,
|
||||
indexes.height.$field.collect_one(prev_height).unwrap_or_default(),
|
||||
&indexes.$field.first_height,
|
||||
height_source,
|
||||
exit,
|
||||
@@ -92,18 +94,19 @@ where
|
||||
/// Compute "max value per period" — for each period, finds `max(source[first_height[period]..first_height[period+1]])`.
|
||||
pub(crate) fn compute_max(
|
||||
&mut self,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
starting_indexes: &Indexes,
|
||||
height_source: &impl ReadableVec<Height, T>,
|
||||
indexes: &indexes::Vecs,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
let src_len = height_source.len();
|
||||
let prev_height = starting_indexes.height.decremented().unwrap_or_default();
|
||||
|
||||
macro_rules! period {
|
||||
($field:ident) => {
|
||||
compute_period_extremum(
|
||||
&mut self.0.$field,
|
||||
starting_indexes.$field,
|
||||
indexes.height.$field.collect_one(prev_height).unwrap_or_default(),
|
||||
&indexes.$field.first_height,
|
||||
height_source,
|
||||
src_len,
|
||||
@@ -121,18 +124,19 @@ where
|
||||
/// Compute "min value per period" — for each period, finds `min(source[first_height[period]..first_height[period+1]])`.
|
||||
pub(crate) fn compute_min(
|
||||
&mut self,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
starting_indexes: &Indexes,
|
||||
height_source: &impl ReadableVec<Height, T>,
|
||||
indexes: &indexes::Vecs,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
let src_len = height_source.len();
|
||||
let prev_height = starting_indexes.height.decremented().unwrap_or_default();
|
||||
|
||||
macro_rules! period {
|
||||
($field:ident) => {
|
||||
compute_period_extremum(
|
||||
&mut self.0.$field,
|
||||
starting_indexes.$field,
|
||||
indexes.height.$field.collect_one(prev_height).unwrap_or_default(),
|
||||
&indexes.$field.first_height,
|
||||
height_source,
|
||||
src_len,
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//! Generic 2-slot container for 1w + 1m EMA pairs.
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Emas1w1m<A, B = A> {
|
||||
#[traversable(rename = "1w")]
|
||||
pub _1w: A,
|
||||
#[traversable(rename = "1m")]
|
||||
pub _1m: B,
|
||||
}
|
||||
|
||||
impl<A> Emas1w1m<A> {
|
||||
pub const SUFFIXES: [&'static str; 2] = ["ema_1w", "ema_1m"];
|
||||
|
||||
pub fn try_from_fn<E>(
|
||||
mut f: impl FnMut(&str) -> std::result::Result<A, E>,
|
||||
) -> std::result::Result<Self, E> {
|
||||
Ok(Self {
|
||||
_1w: f(Self::SUFFIXES[0])?,
|
||||
_1m: f(Self::SUFFIXES[1])?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn as_array(&self) -> [&A; 2] {
|
||||
[&self._1w, &self._1m]
|
||||
}
|
||||
|
||||
pub fn as_mut_array(&mut self) -> [&mut A; 2] {
|
||||
[&mut self._1w, &mut self._1m]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
//! Generic 1-slot container for 2w EMA.
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Emas2w<A> {
|
||||
#[traversable(rename = "2w")]
|
||||
pub _2w: A,
|
||||
}
|
||||
|
||||
impl<A> Emas2w<A> {
|
||||
pub const SUFFIXES: [&'static str; 1] = ["ema_2w"];
|
||||
|
||||
pub fn try_from_fn<E>(
|
||||
mut f: impl FnMut(&str) -> std::result::Result<A, E>,
|
||||
) -> std::result::Result<Self, E> {
|
||||
Ok(Self {
|
||||
_2w: f(Self::SUFFIXES[0])?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn as_array(&self) -> [&A; 1] {
|
||||
[&self._2w]
|
||||
}
|
||||
|
||||
pub fn as_mut_array(&mut self) -> [&mut A; 1] {
|
||||
[&mut self._2w]
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
mod _1w_1m;
|
||||
mod _2w;
|
||||
mod emas_1w_1m;
|
||||
mod emas_2w;
|
||||
|
||||
pub use _1w_1m::*;
|
||||
pub use _2w::*;
|
||||
pub use emas_1w_1m::*;
|
||||
pub use emas_2w::*;
|
||||
|
||||
@@ -29,16 +29,9 @@ impl RollingFullSlot {
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
sum: ByUnit::forced_import(db, &format!("{name}_sum"), version, indexes)?,
|
||||
distribution: DistributionStats {
|
||||
average: ByUnit::forced_import(db, &format!("{name}_average"), version, indexes)?,
|
||||
min: ByUnit::forced_import(db, &format!("{name}_min"), version, indexes)?,
|
||||
max: ByUnit::forced_import(db, &format!("{name}_max"), version, indexes)?,
|
||||
pct10: ByUnit::forced_import(db, &format!("{name}_p10"), version, indexes)?,
|
||||
pct25: ByUnit::forced_import(db, &format!("{name}_p25"), version, indexes)?,
|
||||
median: ByUnit::forced_import(db, &format!("{name}_median"), version, indexes)?,
|
||||
pct75: ByUnit::forced_import(db, &format!("{name}_p75"), version, indexes)?,
|
||||
pct90: ByUnit::forced_import(db, &format!("{name}_p90"), version, indexes)?,
|
||||
},
|
||||
distribution: DistributionStats::try_from_fn(|suffix| {
|
||||
ByUnit::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
|
||||
})?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -55,21 +48,19 @@ impl RollingFullSlot {
|
||||
|
||||
let d = &mut self.distribution;
|
||||
|
||||
compute_rolling_distribution_from_starts(
|
||||
max_from, starts, sats_source,
|
||||
&mut d.average.sats.height, &mut d.min.sats.height,
|
||||
&mut d.max.sats.height, &mut d.pct10.sats.height,
|
||||
&mut d.pct25.sats.height, &mut d.median.sats.height,
|
||||
&mut d.pct75.sats.height, &mut d.pct90.sats.height, exit,
|
||||
)?;
|
||||
|
||||
compute_rolling_distribution_from_starts(
|
||||
max_from, starts, cents_source,
|
||||
&mut d.average.cents.height, &mut d.min.cents.height,
|
||||
&mut d.max.cents.height, &mut d.pct10.cents.height,
|
||||
&mut d.pct25.cents.height, &mut d.median.cents.height,
|
||||
&mut d.pct75.cents.height, &mut d.pct90.cents.height, exit,
|
||||
)?;
|
||||
macro_rules! compute_unit {
|
||||
($unit:ident, $source:expr) => {
|
||||
compute_rolling_distribution_from_starts(
|
||||
max_from, starts, $source,
|
||||
&mut d.average.$unit.height, &mut d.min.$unit.height,
|
||||
&mut d.max.$unit.height, &mut d.pct10.$unit.height,
|
||||
&mut d.pct25.$unit.height, &mut d.median.$unit.height,
|
||||
&mut d.pct75.$unit.height, &mut d.pct90.$unit.height, exit,
|
||||
)?
|
||||
};
|
||||
}
|
||||
compute_unit!(sats, sats_source);
|
||||
compute_unit!(cents, cents_source);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Cents, Height, Version};
|
||||
use brk_types::{Cents, Height, Indexes, Version};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode};
|
||||
|
||||
use crate::{ComputeIndexes, blocks, indexes, prices};
|
||||
use crate::{blocks, indexes, prices};
|
||||
|
||||
use super::{ComputedFromHeightRatio, ComputedFromHeightRatioExtension};
|
||||
|
||||
@@ -36,7 +36,7 @@ impl ComputedFromHeightRatioExtended {
|
||||
&mut self,
|
||||
blocks: &blocks::Vecs,
|
||||
prices: &prices::Vecs,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
metric_price: &impl ReadableVec<Height, Cents>,
|
||||
) -> Result<()> {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{BasisPoints32, Cents, Height, StoredF32, Version};
|
||||
use brk_types::{BasisPoints32, Cents, Height, Indexes, StoredF32, Version};
|
||||
use vecdb::{AnyStoredVec, AnyVec, Database, EagerVec, Exit, PcoVec, ReadableVec, Rw, StorageMode, VecIndex, WritableVec};
|
||||
|
||||
use crate::{
|
||||
ComputeIndexes, blocks, indexes,
|
||||
blocks, indexes,
|
||||
internal::{ComputedFromHeightStdDevExtended, Price, TDigest},
|
||||
};
|
||||
|
||||
@@ -104,7 +104,7 @@ impl ComputedFromHeightRatioExtension {
|
||||
pub(crate) fn compute_rest(
|
||||
&mut self,
|
||||
blocks: &blocks::Vecs,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
ratio_source: &impl ReadableVec<Height, StoredF32>,
|
||||
) -> Result<()> {
|
||||
@@ -182,14 +182,9 @@ impl ComputedFromHeightRatioExtension {
|
||||
}
|
||||
|
||||
// Compute stddev at height level
|
||||
self.ratio_sd
|
||||
.compute_all(blocks, starting_indexes, exit, ratio_source)?;
|
||||
self.ratio_sd_4y
|
||||
.compute_all(blocks, starting_indexes, exit, ratio_source)?;
|
||||
self.ratio_sd_2y
|
||||
.compute_all(blocks, starting_indexes, exit, ratio_source)?;
|
||||
self.ratio_sd_1y
|
||||
.compute_all(blocks, starting_indexes, exit, ratio_source)?;
|
||||
for sd in [&mut self.ratio_sd, &mut self.ratio_sd_4y, &mut self.ratio_sd_2y, &mut self.ratio_sd_1y] {
|
||||
sd.compute_all(blocks, starting_indexes, exit, ratio_source)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -197,7 +192,7 @@ impl ComputedFromHeightRatioExtension {
|
||||
/// Compute cents ratio bands: cents_band = metric_price_cents * ratio_percentile
|
||||
pub(crate) fn compute_cents_bands(
|
||||
&mut self,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
starting_indexes: &Indexes,
|
||||
metric_price: &impl ReadableVec<Height, Cents>,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
@@ -224,14 +219,9 @@ impl ComputedFromHeightRatioExtension {
|
||||
compute_band!(ratio_pct1_price, &self.ratio_pct1.bps.height);
|
||||
|
||||
// Stddev cents bands
|
||||
self.ratio_sd
|
||||
.compute_cents_bands(starting_indexes, metric_price, exit)?;
|
||||
self.ratio_sd_4y
|
||||
.compute_cents_bands(starting_indexes, metric_price, exit)?;
|
||||
self.ratio_sd_2y
|
||||
.compute_cents_bands(starting_indexes, metric_price, exit)?;
|
||||
self.ratio_sd_1y
|
||||
.compute_cents_bands(starting_indexes, metric_price, exit)?;
|
||||
for sd in [&mut self.ratio_sd, &mut self.ratio_sd_4y, &mut self.ratio_sd_2y, &mut self.ratio_sd_1y] {
|
||||
sd.compute_cents_bands(starting_indexes, metric_price, exit)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -8,10 +8,10 @@ pub use price_extended::*;
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{BasisPoints32, Cents, Height, StoredF32, Version};
|
||||
use brk_types::{BasisPoints32, Cents, Height, Indexes, StoredF32, Version};
|
||||
use vecdb::{Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode};
|
||||
|
||||
use crate::{ComputeIndexes, indexes, internal::Bp32ToFloat};
|
||||
use crate::{indexes, internal::Bp32ToFloat};
|
||||
|
||||
use super::{ComputedFromHeight, LazyFromHeight};
|
||||
|
||||
@@ -56,7 +56,7 @@ impl ComputedFromHeightRatio {
|
||||
/// Compute ratio = close_price / metric_price at height level (both in cents)
|
||||
pub(crate) fn compute_ratio(
|
||||
&mut self,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
starting_indexes: &Indexes,
|
||||
close_price: &impl ReadableVec<Height, Cents>,
|
||||
metric_price: &impl ReadableVec<Height, Cents>,
|
||||
exit: &Exit,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Cents, Height, Version};
|
||||
use brk_types::{Cents, Height, Indexes, Version};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
|
||||
|
||||
use crate::internal::{ComputedFromHeight, Price};
|
||||
use crate::{ComputeIndexes, blocks, indexes, prices};
|
||||
use crate::{blocks, indexes, prices};
|
||||
|
||||
use super::ComputedFromHeightRatioExtended;
|
||||
|
||||
@@ -37,7 +37,7 @@ impl ComputedFromHeightPriceWithRatioExtended {
|
||||
&mut self,
|
||||
blocks: &blocks::Vecs,
|
||||
prices: &prices::Vecs,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
mut compute_price: F,
|
||||
) -> Result<()>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Cents, Height, StoredF32, Version};
|
||||
use brk_types::{Cents, Height, Indexes, StoredF32, Version};
|
||||
use vecdb::{
|
||||
AnyStoredVec, AnyVec, Database, EagerVec, Exit, PcoVec, ReadableVec, Rw, StorageMode, VecIndex,
|
||||
WritableVec,
|
||||
};
|
||||
|
||||
use crate::{ComputeIndexes, blocks, indexes};
|
||||
use crate::{blocks, indexes};
|
||||
|
||||
use crate::internal::{ComputedFromHeight, Price};
|
||||
|
||||
@@ -110,7 +110,7 @@ impl ComputedFromHeightStdDevExtended {
|
||||
pub(crate) fn compute_all(
|
||||
&mut self,
|
||||
blocks: &blocks::Vecs,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
source: &impl ReadableVec<Height, StoredF32>,
|
||||
) -> Result<()> {
|
||||
@@ -123,7 +123,7 @@ impl ComputedFromHeightStdDevExtended {
|
||||
|
||||
pub(crate) fn compute_bands(
|
||||
&mut self,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
sma_opt: Option<&impl ReadableVec<Height, StoredF32>>,
|
||||
source: &impl ReadableVec<Height, StoredF32>,
|
||||
@@ -202,7 +202,7 @@ impl ComputedFromHeightStdDevExtended {
|
||||
/// Compute cents price bands: cents_band = metric_price_cents * band_ratio
|
||||
pub(crate) fn compute_cents_bands(
|
||||
&mut self,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
starting_indexes: &Indexes,
|
||||
metric_price: &impl ReadableVec<Height, Cents>,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
|
||||
@@ -4,10 +4,10 @@ pub use extended::*;
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Height, StoredF32, Version};
|
||||
use brk_types::{Height, Indexes, StoredF32, Version};
|
||||
use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode};
|
||||
|
||||
use crate::{ComputeIndexes, blocks, indexes};
|
||||
use crate::{blocks, indexes};
|
||||
|
||||
use crate::internal::ComputedFromHeight;
|
||||
|
||||
@@ -57,7 +57,7 @@ impl ComputedFromHeightStdDev {
|
||||
pub(crate) fn compute_all(
|
||||
&mut self,
|
||||
blocks: &blocks::Vecs,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
source: &impl ReadableVec<Height, StoredF32>,
|
||||
) -> Result<()> {
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::TxIndex;
|
||||
use brk_types::{Indexes, TxIndex};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{Database, EagerVec, Exit, ImportableVec, PcoVec, Rw, StorageMode, Version};
|
||||
|
||||
use crate::{
|
||||
ComputeIndexes, indexes,
|
||||
indexes,
|
||||
internal::{ComputedVecValue, NumericValue, TxDerivedDistribution},
|
||||
};
|
||||
|
||||
@@ -43,7 +43,7 @@ where
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
skip_count: usize,
|
||||
) -> Result<()>
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::TxIndex;
|
||||
use brk_types::{Indexes, TxIndex};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{Database, Exit, LazyVecFrom2, ReadableVec, Rw, StorageMode, Version};
|
||||
|
||||
use crate::{
|
||||
ComputeIndexes, indexes,
|
||||
indexes,
|
||||
internal::{ComputedVecValue, NumericValue, TxDerivedDistribution},
|
||||
};
|
||||
|
||||
@@ -47,7 +47,7 @@ where
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()>
|
||||
where
|
||||
|
||||
@@ -13,14 +13,14 @@ use vecdb::{
|
||||
|
||||
use crate::{
|
||||
indexes, indexes_from,
|
||||
internal::{ComputedVecValue, Indexes, NumericValue},
|
||||
internal::{ComputedVecValue, NumericValue, PerPeriod},
|
||||
};
|
||||
|
||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||
#[traversable(transparent)]
|
||||
pub struct ComputedHeightDerived<T>(
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub Indexes<
|
||||
pub PerPeriod<
|
||||
LazyAggVec<Minute10, Option<T>, Height, Height, T>,
|
||||
LazyAggVec<Minute30, Option<T>, Height, Height, T>,
|
||||
LazyAggVec<Hour1, Option<T>, Height, Height, T>,
|
||||
|
||||
@@ -16,7 +16,7 @@ use vecdb::{
|
||||
use crate::{
|
||||
indexes, indexes_from,
|
||||
internal::{
|
||||
ComputedFromHeight, ComputedHeightDerived, ComputedVecValue, Indexes, NumericValue,
|
||||
ComputedFromHeight, ComputedHeightDerived, ComputedVecValue, NumericValue, PerPeriod,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -59,7 +59,7 @@ where
|
||||
#[traversable(transparent)]
|
||||
pub struct LazyHeightDerived<T, S1T = T>(
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub Indexes<
|
||||
pub PerPeriod<
|
||||
LazyTransformLast<Minute10, Option<T>, Option<S1T>>,
|
||||
LazyTransformLast<Minute30, Option<T>, Option<S1T>>,
|
||||
LazyTransformLast<Hour1, Option<T>, Option<S1T>>,
|
||||
|
||||
@@ -7,7 +7,7 @@ use brk_traversable::Traversable;
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
#[traversable(merge)]
|
||||
pub struct Indexes<M10, M30, H1, H4, H12, D1, D3, W1, Mo1, Mo3, Mo6, Y1, Y10, HE, DE> {
|
||||
pub struct PerPeriod<M10, M30, H1, H4, H12, D1, D3, W1, Mo1, Mo3, Mo6, Y1, Y10, HE, DE> {
|
||||
pub minute10: M10,
|
||||
pub minute30: M30,
|
||||
pub hour1: H1,
|
||||
@@ -25,7 +25,7 @@ pub struct Indexes<M10, M30, H1, H4, H12, D1, D3, W1, Mo1, Mo3, Mo6, Y1, Y10, HE
|
||||
pub difficultyepoch: DE,
|
||||
}
|
||||
|
||||
/// Helper macro to construct an `Indexes` by applying a macro to each field.
|
||||
/// Helper macro to construct a `PerPeriod` by applying a macro to each field.
|
||||
///
|
||||
/// Usage:
|
||||
/// ```ignore
|
||||
@@ -35,7 +35,7 @@ pub struct Indexes<M10, M30, H1, H4, H12, D1, D3, W1, Mo1, Mo3, Mo6, Y1, Y10, HE
|
||||
#[macro_export]
|
||||
macro_rules! indexes_from {
|
||||
($period:ident, $epoch:ident) => {
|
||||
$crate::internal::Indexes {
|
||||
$crate::internal::PerPeriod {
|
||||
minute10: $period!(minute10),
|
||||
minute30: $period!(minute30),
|
||||
hour1: $period!(hour1),
|
||||
|
||||
@@ -14,14 +14,14 @@ use vecdb::{LazyVecFrom1, ReadableCloneableVec, UnaryTransform};
|
||||
|
||||
use crate::{
|
||||
indexes_from,
|
||||
internal::{ComputedVecValue, EagerIndexes, Indexes},
|
||||
internal::{ComputedVecValue, EagerIndexes, PerPeriod},
|
||||
};
|
||||
|
||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||
#[traversable(transparent)]
|
||||
pub struct LazyEagerIndexes<T, S>(
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub Indexes<
|
||||
pub PerPeriod<
|
||||
LazyVecFrom1<Minute10, T, Minute10, S>,
|
||||
LazyVecFrom1<Minute30, T, Minute30, S>,
|
||||
LazyVecFrom1<Hour1, T, Hour1, S>,
|
||||
|
||||
@@ -37,16 +37,9 @@ where
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
let v = version + VERSION;
|
||||
Ok(Self(DistributionStats {
|
||||
average: RollingWindows::forced_import(db, &format!("{name}_average"), v, indexes)?,
|
||||
min: RollingWindows::forced_import(db, &format!("{name}_min"), v, indexes)?,
|
||||
max: RollingWindows::forced_import(db, &format!("{name}_max"), v, indexes)?,
|
||||
pct10: RollingWindows::forced_import(db, &format!("{name}_p10"), v, indexes)?,
|
||||
pct25: RollingWindows::forced_import(db, &format!("{name}_p25"), v, indexes)?,
|
||||
median: RollingWindows::forced_import(db, &format!("{name}_median"), v, indexes)?,
|
||||
pct75: RollingWindows::forced_import(db, &format!("{name}_p75"), v, indexes)?,
|
||||
pct90: RollingWindows::forced_import(db, &format!("{name}_p90"), v, indexes)?,
|
||||
}))
|
||||
Ok(Self(DistributionStats::try_from_fn(|suffix| {
|
||||
RollingWindows::forced_import(db, &format!("{name}_{suffix}"), v, indexes)
|
||||
})?))
|
||||
}
|
||||
|
||||
/// Compute all 8 distribution stats across all 4 windows from a single source.
|
||||
@@ -66,34 +59,21 @@ where
|
||||
T: Copy + Ord + From<f64> + Default,
|
||||
f64: From<T>,
|
||||
{
|
||||
compute_rolling_distribution_from_starts(
|
||||
max_from, windows._24h, source,
|
||||
&mut self.0.average._24h.height, &mut self.0.min._24h.height,
|
||||
&mut self.0.max._24h.height, &mut self.0.pct10._24h.height,
|
||||
&mut self.0.pct25._24h.height, &mut self.0.median._24h.height,
|
||||
&mut self.0.pct75._24h.height, &mut self.0.pct90._24h.height, exit,
|
||||
)?;
|
||||
compute_rolling_distribution_from_starts(
|
||||
max_from, windows._1w, source,
|
||||
&mut self.0.average._1w.height, &mut self.0.min._1w.height,
|
||||
&mut self.0.max._1w.height, &mut self.0.pct10._1w.height,
|
||||
&mut self.0.pct25._1w.height, &mut self.0.median._1w.height,
|
||||
&mut self.0.pct75._1w.height, &mut self.0.pct90._1w.height, exit,
|
||||
)?;
|
||||
compute_rolling_distribution_from_starts(
|
||||
max_from, windows._1m, source,
|
||||
&mut self.0.average._1m.height, &mut self.0.min._1m.height,
|
||||
&mut self.0.max._1m.height, &mut self.0.pct10._1m.height,
|
||||
&mut self.0.pct25._1m.height, &mut self.0.median._1m.height,
|
||||
&mut self.0.pct75._1m.height, &mut self.0.pct90._1m.height, exit,
|
||||
)?;
|
||||
compute_rolling_distribution_from_starts(
|
||||
max_from, windows._1y, source,
|
||||
&mut self.0.average._1y.height, &mut self.0.min._1y.height,
|
||||
&mut self.0.max._1y.height, &mut self.0.pct10._1y.height,
|
||||
&mut self.0.pct25._1y.height, &mut self.0.median._1y.height,
|
||||
&mut self.0.pct75._1y.height, &mut self.0.pct90._1y.height, exit,
|
||||
)?;
|
||||
macro_rules! compute_window {
|
||||
($w:ident) => {
|
||||
compute_rolling_distribution_from_starts(
|
||||
max_from, windows.$w, source,
|
||||
&mut self.0.average.$w.height, &mut self.0.min.$w.height,
|
||||
&mut self.0.max.$w.height, &mut self.0.pct10.$w.height,
|
||||
&mut self.0.pct25.$w.height, &mut self.0.median.$w.height,
|
||||
&mut self.0.pct75.$w.height, &mut self.0.pct90.$w.height, exit,
|
||||
)?
|
||||
};
|
||||
}
|
||||
compute_window!(_24h);
|
||||
compute_window!(_1w);
|
||||
compute_window!(_1m);
|
||||
compute_window!(_1y);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -7,12 +7,12 @@ use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Height, TxIndex};
|
||||
use brk_types::{Height, Indexes, TxIndex};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode, Version};
|
||||
|
||||
use crate::{
|
||||
ComputeIndexes, indexes,
|
||||
indexes,
|
||||
internal::{ComputedVecValue, Distribution, NumericValue},
|
||||
};
|
||||
|
||||
@@ -66,7 +66,7 @@ where
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
starting_indexes: &Indexes,
|
||||
txindex_source: &impl ReadableVec<TxIndex, T>,
|
||||
exit: &Exit,
|
||||
) -> Result<()>
|
||||
@@ -93,7 +93,7 @@ where
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
starting_indexes: &ComputeIndexes,
|
||||
starting_indexes: &Indexes,
|
||||
txindex_source: &impl ReadableVec<TxIndex, T>,
|
||||
exit: &Exit,
|
||||
skip_count: usize,
|
||||
|
||||
Reference in New Issue
Block a user