global: adding support for safe lengths

This commit is contained in:
nym21
2026-05-06 15:33:07 +02:00
parent da7671744f
commit 086bfd9938
177 changed files with 2445 additions and 2049 deletions
@@ -1,9 +1,10 @@
use brk_error::Result;
use brk_indexer::Lengths;
use brk_traversable::Traversable;
use brk_types::{
Day1, Day3, Epoch, Halving, Height, Hour1, Hour4, Hour12, Indexes, Minute10, Minute30, Month1,
Month3, Month6, Version, Week1, Year1, Year10,
Day1, Day3, Epoch, Halving, Height, Hour1, Hour4, Hour12, Minute10, Minute30, Month1, Month3,
Month6, Version, Week1, Year1, Year10,
};
use derive_more::{Deref, DerefMut};
use schemars::JsonSchema;
@@ -74,12 +75,12 @@ where
pub(crate) fn compute_first(
&mut self,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
height_source: &impl ReadableVec<Height, T>,
indexes: &indexes::Vecs,
exit: &Exit,
) -> Result<()> {
let prev_height = starting_indexes.height.decremented().unwrap_or_default();
let prev_height = starting_lengths.height.decremented().unwrap_or_default();
macro_rules! period {
($field:ident) => {
@@ -117,13 +118,13 @@ where
pub(crate) fn compute_max(
&mut self,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
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();
let prev_height = starting_lengths.height.decremented().unwrap_or_default();
macro_rules! period {
($field:ident) => {
@@ -164,13 +165,13 @@ where
pub(crate) fn compute_min(
&mut self,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
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();
let prev_height = starting_lengths.height.decremented().unwrap_or_default();
macro_rules! period {
($field:ident) => {
@@ -1,6 +1,7 @@
use brk_error::Result;
use brk_indexer::Lengths;
use brk_traversable::Traversable;
use brk_types::{BasisPoints32, Cents, Height, Indexes, StoredF32, Version};
use brk_types::{BasisPoints32, Cents, Height, StoredF32, Version};
use vecdb::{Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode};
use crate::{
@@ -50,13 +51,13 @@ impl<B: BpsType> RatioPerBlock<B> {
impl RatioPerBlock<BasisPoints32> {
pub(crate) fn compute_ratio(
&mut self,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
close_price: &impl ReadableVec<Height, Cents>,
series_price: &impl ReadableVec<Height, Cents>,
exit: &Exit,
) -> Result<()> {
self.bps.height.compute_transform2(
starting_indexes.height,
starting_lengths.height,
close_price,
series_price,
|(i, close, price, ..)| {
@@ -1,6 +1,7 @@
use brk_error::Result;
use brk_indexer::Lengths;
use brk_traversable::Traversable;
use brk_types::{BasisPoints32, Cents, Height, Indexes, StoredF32, Version};
use brk_types::{BasisPoints32, Cents, Height, StoredF32, Version};
use vecdb::{
AnyStoredVec, AnyVec, Database, EagerVec, Exit, PcoVec, ReadableVec, Rw, StorageMode, VecIndex,
WritableVec,
@@ -86,7 +87,7 @@ impl RatioPerBlockPercentiles {
pub(crate) fn compute(
&mut self,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
exit: &Exit,
ratio_source: &impl ReadableVec<Height, StoredF32>,
series_price: &impl ReadableVec<Height, Cents>,
@@ -102,7 +103,7 @@ impl RatioPerBlockPercentiles {
.map(|v| Height::from(v.len()))
.min()
.unwrap()
.min(starting_indexes.height);
.min(starting_lengths.height);
let start = starting_height.to_usize();
let ratio_len = ratio_source.len();
@@ -159,7 +160,7 @@ impl RatioPerBlockPercentiles {
.price
.cents
.compute_binary::<Cents, BasisPoints32, PriceTimesRatioBp32Cents>(
starting_indexes.height,
starting_lengths.height,
series_price,
&self.$band.ratio.bps.height,
exit,
@@ -1,6 +1,7 @@
use brk_error::Result;
use brk_indexer::Lengths;
use brk_traversable::Traversable;
use brk_types::{BasisPoints32, Cents, Dollars, Height, Indexes, SatsFract, StoredF32, Version};
use brk_types::{BasisPoints32, Cents, Dollars, Height, SatsFract, StoredF32, Version};
use derive_more::{Deref, DerefMut};
use vecdb::{Database, EagerVec, Exit, PcoVec, ReadableVec, Rw, StorageMode};
@@ -39,12 +40,12 @@ impl PriceWithRatioPerBlock {
/// Compute ratio from close price and this metric's price.
pub(crate) fn compute_ratio(
&mut self,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
close_price: &impl ReadableVec<Height, Cents>,
exit: &Exit,
) -> Result<()> {
self.bps.height.compute_transform2(
starting_indexes.height,
starting_lengths.height,
close_price,
&self.cents.height,
|(i, close, price, ..)| {
@@ -63,7 +64,7 @@ impl PriceWithRatioPerBlock {
pub(crate) fn compute_all<F>(
&mut self,
prices: &prices::Vecs,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
exit: &Exit,
mut compute_price: F,
) -> Result<()>
@@ -71,7 +72,7 @@ impl PriceWithRatioPerBlock {
F: FnMut(&mut EagerVec<PcoVec<Height, Cents>>) -> Result<()>,
{
compute_price(&mut self.cents.height)?;
self.compute_ratio(starting_indexes, &prices.spot.cents.height, exit)
self.compute_ratio(starting_lengths, &prices.spot.cents.height, exit)
}
}
@@ -101,14 +102,14 @@ impl PriceWithRatioExtendedPerBlock {
pub(crate) fn compute_rest(
&mut self,
prices: &prices::Vecs,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
exit: &Exit,
) -> Result<()> {
let close_price = &prices.spot.cents.height;
self.base
.compute_ratio(starting_indexes, close_price, exit)?;
.compute_ratio(starting_lengths, close_price, exit)?;
self.percentiles.compute(
starting_indexes,
starting_lengths,
exit,
&self.base.ratio.height,
&self.base.cents.height,
@@ -120,7 +121,7 @@ impl PriceWithRatioExtendedPerBlock {
pub(crate) fn compute_all<F>(
&mut self,
prices: &prices::Vecs,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
exit: &Exit,
mut compute_price: F,
) -> Result<()>
@@ -128,6 +129,6 @@ impl PriceWithRatioExtendedPerBlock {
F: FnMut(&mut EagerVec<PcoVec<Height, Cents>>) -> Result<()>,
{
compute_price(&mut self.base.cents.height)?;
self.compute_rest(prices, starting_indexes, exit)
self.compute_rest(prices, starting_lengths, exit)
}
}
@@ -1,6 +1,7 @@
use brk_error::Result;
use brk_indexer::Lengths;
use brk_traversable::Traversable;
use brk_types::{BasisPoints32, Height, Indexes, StoredF32, Version};
use brk_types::{BasisPoints32, Height, StoredF32, Version};
use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode};
use crate::{blocks, indexes};
@@ -52,13 +53,13 @@ impl RatioSma {
pub(crate) fn compute(
&mut self,
blocks: &blocks::Vecs,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
exit: &Exit,
ratio_source: &impl ReadableVec<Height, StoredF32>,
) -> Result<()> {
// Expanding SMA (all history)
self.all.bps.height.compute_sma_(
starting_indexes.height,
starting_lengths.height,
ratio_source,
usize::MAX,
exit,
@@ -74,7 +75,7 @@ impl RatioSma {
(&mut self._4y, &blocks.lookback._4y),
] {
sma.bps.height.compute_rolling_average(
starting_indexes.height,
starting_lengths.height,
lookback,
ratio_source,
exit,
@@ -1,6 +1,7 @@
use brk_error::Result;
use brk_indexer::Lengths;
use brk_traversable::Traversable;
use brk_types::{Cents, Height, Indexes, StoredF32, Version};
use brk_types::{Cents, Height, StoredF32, Version};
use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode};
use crate::{blocks, indexes, internal::StdDevPerBlockExtended};
@@ -43,7 +44,7 @@ impl RatioPerBlockStdDevBands {
pub(crate) fn compute(
&mut self,
blocks: &blocks::Vecs,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
exit: &Exit,
ratio_source: &impl ReadableVec<Height, StoredF32>,
series_price: &impl ReadableVec<Height, Cents>,
@@ -55,8 +56,8 @@ impl RatioPerBlockStdDevBands {
(&mut self._2y, &sma._2y.ratio.height),
(&mut self._1y, &sma._1y.ratio.height),
] {
sd.compute_all(blocks, starting_indexes, exit, ratio_source, sma_ratio)?;
sd.compute_cents_bands(starting_indexes, series_price, sma_ratio, exit)?;
sd.compute_all(blocks, starting_lengths, exit, ratio_source, sma_ratio)?;
sd.compute_cents_bands(starting_lengths, series_price, sma_ratio, exit)?;
}
Ok(())
@@ -1,6 +1,7 @@
use brk_error::Result;
use brk_indexer::Lengths;
use brk_traversable::Traversable;
use brk_types::{Height, Indexes, StoredF32, Version};
use brk_types::{Height, StoredF32, Version};
use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode};
use crate::{blocks, indexes, internal::PerBlock};
@@ -35,20 +36,20 @@ impl StdDevPerBlock {
pub(crate) fn compute_all(
&mut self,
blocks: &blocks::Vecs,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
exit: &Exit,
source: &impl ReadableVec<Height, StoredF32>,
) -> Result<()> {
if self.days == usize::MAX {
self.sma.height.compute_sma_(
starting_indexes.height,
starting_lengths.height,
source,
usize::MAX,
exit,
None,
)?;
self.sd.height.compute_expanding_sd(
starting_indexes.height,
starting_lengths.height,
source,
&self.sma.height,
exit,
@@ -59,14 +60,14 @@ impl StdDevPerBlock {
let window_starts = blocks.lookback.start_vec(self.days);
self.sma.height.compute_rolling_average(
starting_indexes.height,
starting_lengths.height,
window_starts,
source,
exit,
)?;
self.sd.height.compute_rolling_sd(
starting_indexes.height,
starting_lengths.height,
window_starts,
source,
&self.sma.height,
@@ -1,6 +1,7 @@
use brk_error::Result;
use brk_indexer::Lengths;
use brk_traversable::Traversable;
use brk_types::{Cents, Height, Indexes, StoredF32, Version};
use brk_types::{Cents, Height, StoredF32, Version};
use vecdb::{
AnyStoredVec, AnyVec, Database, EagerVec, Exit, PcoVec, ReadableVec, Rw, StorageMode, VecIndex,
WritableVec,
@@ -95,7 +96,7 @@ impl StdDevPerBlockExtended {
pub(crate) fn compute_all(
&mut self,
blocks: &blocks::Vecs,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
exit: &Exit,
source: &impl ReadableVec<Height, StoredF32>,
sma: &impl ReadableVec<Height, StoredF32>,
@@ -103,11 +104,11 @@ impl StdDevPerBlockExtended {
if self.days == usize::MAX {
self.sd
.height
.compute_expanding_sd(starting_indexes.height, source, sma, exit)?;
.compute_expanding_sd(starting_lengths.height, source, sma, exit)?;
} else {
let window_starts = blocks.lookback.start_vec(self.days);
self.sd.height.compute_rolling_sd(
starting_indexes.height,
starting_lengths.height,
window_starts,
source,
sma,
@@ -115,12 +116,12 @@ impl StdDevPerBlockExtended {
)?;
}
self.compute_bands(starting_indexes, exit, sma, source)
self.compute_bands(starting_lengths, exit, sma, source)
}
fn compute_bands(
&mut self,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
exit: &Exit,
sma: &impl ReadableVec<Height, StoredF32>,
source: &impl ReadableVec<Height, StoredF32>,
@@ -138,7 +139,7 @@ impl StdDevPerBlockExtended {
.map(|v| Height::from(v.len()))
.min()
.unwrap()
.min(starting_indexes.height);
.min(starting_lengths.height);
let start = starting_height.to_usize();
@@ -167,7 +168,7 @@ impl StdDevPerBlockExtended {
}
self.zscore.height.compute_zscore(
starting_indexes.height,
starting_lengths.height,
source,
sma,
&self.sd.height,
@@ -179,7 +180,7 @@ impl StdDevPerBlockExtended {
pub(crate) fn compute_cents_bands(
&mut self,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
series_price: &impl ReadableVec<Height, Cents>,
sma: &impl ReadableVec<Height, StoredF32>,
exit: &Exit,
@@ -189,7 +190,7 @@ impl StdDevPerBlockExtended {
$price
.cents
.compute_binary::<Cents, StoredF32, PriceTimesRatioCents>(
starting_indexes.height,
starting_lengths.height,
series_price,
$band_source,
exit,
@@ -1,8 +1,8 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_indexer::{Indexer, Lengths};
use brk_traversable::Traversable;
use brk_types::{Indexes, TxIndex, VSize};
use brk_types::{TxIndex, VSize};
use schemars::JsonSchema;
use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode, Version};
@@ -68,7 +68,7 @@ where
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
tx_index_source: &impl ReadableVec<TxIndex, T>,
exit: &Exit,
) -> Result<()>
@@ -76,7 +76,7 @@ where
T: Copy + Ord + From<f64> + Default,
f64: From<T>,
{
self.derive_from_with_skip(indexer, indexes, starting_indexes, tx_index_source, exit, 0)
self.derive_from_with_skip(indexer, indexes, starting_lengths, tx_index_source, exit, 0)
}
#[allow(clippy::too_many_arguments)]
@@ -84,7 +84,7 @@ where
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
tx_index_source: &impl ReadableVec<TxIndex, T>,
exit: &Exit,
skip_count: usize,
@@ -94,7 +94,7 @@ where
f64: From<T>,
{
self.block.compute_with_skip(
starting_indexes.height,
starting_lengths.height,
tx_index_source,
&indexer.vecs.transactions.first_tx_index,
&indexes.height.tx_index_count,
@@ -103,7 +103,7 @@ where
)?;
self.distribution._6b.compute_from_nblocks(
starting_indexes.height,
starting_lengths.height,
tx_index_source,
&indexer.vecs.transactions.first_tx_index,
&indexes.height.tx_index_count,
@@ -121,7 +121,7 @@ where
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
tx_index_source: &impl ReadableVec<TxIndex, T>,
vsize_source: &impl ReadableVec<TxIndex, VSize>,
exit: &Exit,
@@ -132,7 +132,7 @@ where
f64: From<T>,
{
self.block.compute_with_skip_weighted(
starting_indexes.height,
starting_lengths.height,
tx_index_source,
vsize_source,
&indexer.vecs.transactions.first_tx_index,
@@ -142,7 +142,7 @@ where
)?;
self.distribution._6b.compute_from_nblocks(
starting_indexes.height,
starting_lengths.height,
tx_index_source,
&indexer.vecs.transactions.first_tx_index,
&indexes.height.tx_index_count,
@@ -4,9 +4,9 @@
//! and stored rather than lazily derived.
use brk_error::Result;
use brk_indexer::Indexer;
use brk_indexer::{Indexer, Lengths};
use brk_traversable::Traversable;
use brk_types::{Indexes, TxIndex, VSize};
use brk_types::{TxIndex, VSize};
use schemars::JsonSchema;
use vecdb::{
Database, EagerVec, Exit, ImportableVec, PcoVec, ReadableVec, Rw, StorageMode, Version,
@@ -50,7 +50,7 @@ where
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
exit: &Exit,
skip_count: usize,
) -> Result<()>
@@ -61,7 +61,7 @@ where
self.distribution.derive_from_with_skip(
indexer,
indexes,
starting_indexes,
starting_lengths,
&self.tx_index,
exit,
skip_count,
@@ -73,7 +73,7 @@ where
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
vsize_source: &impl ReadableVec<TxIndex, VSize>,
exit: &Exit,
skip_count: usize,
@@ -85,7 +85,7 @@ where
self.distribution.derive_from_with_skip_weighted(
indexer,
indexes,
starting_indexes,
starting_lengths,
&self.tx_index,
vsize_source,
exit,
@@ -1,7 +1,7 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_indexer::{Indexer, Lengths};
use brk_traversable::Traversable;
use brk_types::{Indexes, TxIndex};
use brk_types::TxIndex;
use schemars::JsonSchema;
use vecdb::{Database, Exit, LazyVecFrom2, ReadableVec, Rw, StorageMode, Version};
@@ -46,7 +46,7 @@ where
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
starting_lengths: &Lengths,
exit: &Exit,
) -> Result<()>
where
@@ -55,6 +55,6 @@ where
LazyVecFrom2<TxIndex, T, TxIndex, S1, TxIndex, S2>: ReadableVec<TxIndex, T>,
{
self.distribution
.derive_from(indexer, indexes, starting_indexes, &self.tx_index, exit)
.derive_from(indexer, indexes, starting_lengths, &self.tx_index, exit)
}
}
@@ -4,8 +4,9 @@
use brk_cohort::ByAddrType;
use brk_error::Result;
use brk_indexer::Lengths;
use brk_traversable::Traversable;
use brk_types::{Height, Indexes, Sats, Version};
use brk_types::{Height, Sats, Version};
use rayon::prelude::*;
use schemars::JsonSchema;
use vecdb::{AnyStoredVec, AnyVec, Database, EagerVec, Exit, PcoVec, WritableVec};
@@ -83,12 +84,12 @@ where
}
/// Compute `all.height` as the per-block sum of the per-type vecs.
pub(crate) fn compute_rest(&mut self, starting_indexes: &Indexes, exit: &Exit) -> Result<()> {
pub(crate) fn compute_rest(&mut self, starting_lengths: &Lengths, exit: &Exit) -> Result<()> {
let sources: Vec<&EagerVec<PcoVec<Height, T>>> =
self.by_addr_type.values().map(|v| &v.height).collect();
self.all
.height
.compute_sum_of_others(starting_indexes.height, &sources, exit)?;
.compute_sum_of_others(starting_lengths.height, &sources, exit)?;
Ok(())
}
}