global: snapshot

This commit is contained in:
nym21
2026-03-07 20:54:28 +01:00
parent 2df549f1f8
commit ee59731ed2
33 changed files with 419 additions and 390 deletions

View File

@@ -1797,6 +1797,34 @@ impl _1m1w1y24hBtcCentsSatsUsdPattern {
} }
} }
/// Pattern struct for repeated tree structure.
pub struct CoinblocksCoindaysSentPattern2 {
pub coinblocks_destroyed: MetricPattern1<StoredF64>,
pub coinblocks_destroyed_cumulative: MetricPattern1<StoredF64>,
pub coindays_destroyed: MetricPattern1<StoredF64>,
pub coindays_destroyed_cumulative: MetricPattern1<StoredF64>,
pub coindays_destroyed_sum: _1m1w1y24hPattern<StoredF64>,
pub sent: MetricPattern1<Sats>,
pub sent_sum: _24hPattern<Sats>,
pub sent_sum_extended: _1m1w1yPattern<Sats>,
}
impl CoinblocksCoindaysSentPattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
coinblocks_destroyed: MetricPattern1::new(client.clone(), _m(&acc, "coinblocks_destroyed")),
coinblocks_destroyed_cumulative: MetricPattern1::new(client.clone(), _m(&acc, "coinblocks_destroyed_cumulative")),
coindays_destroyed: MetricPattern1::new(client.clone(), _m(&acc, "coindays_destroyed")),
coindays_destroyed_cumulative: MetricPattern1::new(client.clone(), _m(&acc, "coindays_destroyed_cumulative")),
coindays_destroyed_sum: _1m1w1y24hPattern::new(client.clone(), _m(&acc, "coindays_destroyed")),
sent: MetricPattern1::new(client.clone(), _m(&acc, "sent")),
sent_sum: _24hPattern::new(client.clone(), _m(&acc, "sent_24h")),
sent_sum_extended: _1m1w1yPattern::new(client.clone(), _m(&acc, "sent")),
}
}
}
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern<T> { pub struct AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern<T> {
pub average: MetricPattern18<T>, pub average: MetricPattern18<T>,
@@ -2021,28 +2049,6 @@ impl BaseBtcCentsSatsUsdPattern {
} }
} }
/// Pattern struct for repeated tree structure.
pub struct CoinblocksCoindaysSentPattern {
pub coinblocks_destroyed: CumulativeHeightPattern<StoredF64>,
pub coindays_destroyed: CumulativeHeightSumPattern<StoredF64>,
pub sent: MetricPattern1<Sats>,
pub sent_sum: _24hPattern<Sats>,
pub sent_sum_extended: _1m1w1yPattern<Sats>,
}
impl CoinblocksCoindaysSentPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
coinblocks_destroyed: CumulativeHeightPattern::new(client.clone(), _m(&acc, "coinblocks_destroyed")),
coindays_destroyed: CumulativeHeightSumPattern::new(client.clone(), _m(&acc, "coindays_destroyed")),
sent: MetricPattern1::new(client.clone(), _m(&acc, "sent")),
sent_sum: _24hPattern::new(client.clone(), _m(&acc, "sent_24h")),
sent_sum_extended: _1m1w1yPattern::new(client.clone(), _m(&acc, "sent")),
}
}
}
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct EmaHistogramLineSignalPattern { pub struct EmaHistogramLineSignalPattern {
pub ema_fast: MetricPattern1<StoredF32>, pub ema_fast: MetricPattern1<StoredF32>,
@@ -2187,6 +2193,26 @@ impl BtcCentsSatsUsdPattern {
} }
} }
/// Pattern struct for repeated tree structure.
pub struct CoinblocksCoindaysSentPattern {
pub coinblocks_destroyed: MetricPattern1<StoredF64>,
pub coindays_destroyed: MetricPattern1<StoredF64>,
pub sent: MetricPattern1<Sats>,
pub sent_sum: _24hPattern<Sats>,
}
impl CoinblocksCoindaysSentPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
coinblocks_destroyed: MetricPattern1::new(client.clone(), _m(&acc, "coinblocks_destroyed")),
coindays_destroyed: MetricPattern1::new(client.clone(), _m(&acc, "coindays_destroyed")),
sent: MetricPattern1::new(client.clone(), _m(&acc, "sent")),
sent_sum: _24hPattern::new(client.clone(), _m(&acc, "sent_24h")),
}
}
}
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct InvestedMaxMinPercentilesPattern { pub struct InvestedMaxMinPercentilesPattern {
pub invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern, pub invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
@@ -5507,7 +5533,7 @@ impl MetricsTree_Distribution_UtxoCohorts {
pub struct MetricsTree_Distribution_UtxoCohorts_All { pub struct MetricsTree_Distribution_UtxoCohorts_All {
pub supply: ChangeHalvedTotalPattern, pub supply: ChangeHalvedTotalPattern,
pub outputs: UtxoPattern, pub outputs: UtxoPattern,
pub activity: CoinblocksCoindaysSentPattern, pub activity: CoinblocksCoindaysSentPattern2,
pub realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern, pub realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern,
pub cost_basis: InvestedMaxMinPercentilesPattern, pub cost_basis: InvestedMaxMinPercentilesPattern,
pub unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern, pub unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern,
@@ -5522,7 +5548,7 @@ impl MetricsTree_Distribution_UtxoCohorts_All {
Self { Self {
supply: ChangeHalvedTotalPattern::new(client.clone(), "supply".to_string()), supply: ChangeHalvedTotalPattern::new(client.clone(), "supply".to_string()),
outputs: UtxoPattern::new(client.clone(), "utxo_count".to_string()), outputs: UtxoPattern::new(client.clone(), "utxo_count".to_string()),
activity: CoinblocksCoindaysSentPattern::new(client.clone(), "".to_string()), activity: CoinblocksCoindaysSentPattern2::new(client.clone(), "".to_string()),
realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern::new(client.clone(), "".to_string()), realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern::new(client.clone(), "".to_string()),
cost_basis: InvestedMaxMinPercentilesPattern::new(client.clone(), "".to_string()), cost_basis: InvestedMaxMinPercentilesPattern::new(client.clone(), "".to_string()),
unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern::new(client.clone(), "".to_string()), unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern::new(client.clone(), "".to_string()),
@@ -5590,7 +5616,7 @@ impl MetricsTree_Distribution_UtxoCohorts_All_Relative {
pub struct MetricsTree_Distribution_UtxoCohorts_Sth { pub struct MetricsTree_Distribution_UtxoCohorts_Sth {
pub supply: ChangeHalvedTotalPattern, pub supply: ChangeHalvedTotalPattern,
pub outputs: UtxoPattern, pub outputs: UtxoPattern,
pub activity: CoinblocksCoindaysSentPattern, pub activity: CoinblocksCoindaysSentPattern2,
pub realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern, pub realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern,
pub cost_basis: InvestedMaxMinPercentilesPattern, pub cost_basis: InvestedMaxMinPercentilesPattern,
pub unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern, pub unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern,
@@ -5610,7 +5636,7 @@ impl MetricsTree_Distribution_UtxoCohorts_Sth {
Self { Self {
supply: ChangeHalvedTotalPattern::new(client.clone(), "sth_supply".to_string()), supply: ChangeHalvedTotalPattern::new(client.clone(), "sth_supply".to_string()),
outputs: UtxoPattern::new(client.clone(), "sth_utxo_count".to_string()), outputs: UtxoPattern::new(client.clone(), "sth_utxo_count".to_string()),
activity: CoinblocksCoindaysSentPattern::new(client.clone(), "sth".to_string()), activity: CoinblocksCoindaysSentPattern2::new(client.clone(), "sth".to_string()),
realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern::new(client.clone(), "sth".to_string()), realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern::new(client.clone(), "sth".to_string()),
cost_basis: InvestedMaxMinPercentilesPattern::new(client.clone(), "sth".to_string()), cost_basis: InvestedMaxMinPercentilesPattern::new(client.clone(), "sth".to_string()),
unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern::new(client.clone(), "sth".to_string()), unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern::new(client.clone(), "sth".to_string()),
@@ -5631,7 +5657,7 @@ impl MetricsTree_Distribution_UtxoCohorts_Sth {
pub struct MetricsTree_Distribution_UtxoCohorts_Lth { pub struct MetricsTree_Distribution_UtxoCohorts_Lth {
pub supply: ChangeHalvedTotalPattern, pub supply: ChangeHalvedTotalPattern,
pub outputs: UtxoPattern, pub outputs: UtxoPattern,
pub activity: CoinblocksCoindaysSentPattern, pub activity: CoinblocksCoindaysSentPattern2,
pub realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern, pub realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern,
pub cost_basis: InvestedMaxMinPercentilesPattern, pub cost_basis: InvestedMaxMinPercentilesPattern,
pub unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern, pub unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern,
@@ -5645,7 +5671,7 @@ impl MetricsTree_Distribution_UtxoCohorts_Lth {
Self { Self {
supply: ChangeHalvedTotalPattern::new(client.clone(), "lth_supply".to_string()), supply: ChangeHalvedTotalPattern::new(client.clone(), "lth_supply".to_string()),
outputs: UtxoPattern::new(client.clone(), "lth_utxo_count".to_string()), outputs: UtxoPattern::new(client.clone(), "lth_utxo_count".to_string()),
activity: CoinblocksCoindaysSentPattern::new(client.clone(), "lth".to_string()), activity: CoinblocksCoindaysSentPattern2::new(client.clone(), "lth".to_string()),
realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern::new(client.clone(), "lth".to_string()), realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern::new(client.clone(), "lth".to_string()),
cost_basis: InvestedMaxMinPercentilesPattern::new(client.clone(), "lth".to_string()), cost_basis: InvestedMaxMinPercentilesPattern::new(client.clone(), "lth".to_string()),
unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern::new(client.clone(), "lth".to_string()), unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern::new(client.clone(), "lth".to_string()),

View File

@@ -29,14 +29,12 @@ impl Vecs {
Ok(()) Ok(())
})?; })?;
let coinblocks_destroyed = &all_metrics.activity.coinblocks_destroyed;
self.coinblocks_stored self.coinblocks_stored
.compute(starting_indexes.height, &window_starts, exit, |vec| { .compute(starting_indexes.height, &window_starts, exit, |vec| {
vec.compute_subtract( vec.compute_subtract(
starting_indexes.height, starting_indexes.height,
&self.coinblocks_created.height, &self.coinblocks_created.height,
&coinblocks_destroyed.height, &all_metrics.activity.coinblocks_destroyed.height,
exit, exit,
)?; )?;
Ok(()) Ok(())
@@ -44,7 +42,7 @@ impl Vecs {
self.liveliness.height.compute_divide( self.liveliness.height.compute_divide(
starting_indexes.height, starting_indexes.height,
&coinblocks_destroyed.cumulative.height, &all_metrics.activity.coinblocks_destroyed_cumulative.height,
&self.coinblocks_created.cumulative.height, &self.coinblocks_created.cumulative.height,
exit, exit,
)?; )?;

View File

@@ -1,38 +1,68 @@
use brk_error::Result; use brk_error::Result;
use brk_traversable::Traversable; use brk_traversable::Traversable;
use brk_types::{Height, Indexes, Sats, Version}; use brk_types::{Bitcoin, Height, Indexes, Sats, StoredF64, Version};
use derive_more::{Deref, DerefMut};
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec}; use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
use crate::internal::{ComputedFromHeight, RollingWindow24h}; use crate::internal::ComputedFromHeight;
use crate::{blocks, distribution::metrics::ImportConfig}; use crate::{blocks, distribution::metrics::ImportConfig};
#[derive(Traversable)] use super::ActivityCore;
#[derive(Deref, DerefMut, Traversable)]
pub struct ActivityBase<M: StorageMode = Rw> { pub struct ActivityBase<M: StorageMode = Rw> {
pub sent: ComputedFromHeight<Sats, M>, #[deref]
pub sent_sum: RollingWindow24h<Sats, M>, #[deref_mut]
#[traversable(flatten)]
pub core: ActivityCore<M>,
pub coinblocks_destroyed: ComputedFromHeight<StoredF64, M>,
pub coindays_destroyed: ComputedFromHeight<StoredF64, M>,
} }
impl ActivityBase { impl ActivityBase {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> { pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
let v1 = Version::ONE; let v1 = Version::ONE;
Ok(Self { Ok(Self {
sent: cfg.import("sent", v1)?, core: ActivityCore::forced_import(cfg)?,
sent_sum: cfg.import("sent", v1)?, coinblocks_destroyed: cfg.import("coinblocks_destroyed", v1)?,
coindays_destroyed: cfg.import("coindays_destroyed", v1)?,
}) })
} }
pub(crate) fn min_len(&self) -> usize { pub(crate) fn min_len(&self) -> usize {
self.sent.height.len() self.core
.min_len()
.min(self.coinblocks_destroyed.height.len())
.min(self.coindays_destroyed.height.len())
} }
pub(crate) fn truncate_push(&mut self, height: Height, sent: Sats) -> Result<()> { pub(crate) fn truncate_push(
self.sent.height.truncate_push(height, sent)?; &mut self,
height: Height,
sent: Sats,
satblocks_destroyed: Sats,
satdays_destroyed: Sats,
) -> Result<()> {
self.core.truncate_push(height, sent)?;
self.coinblocks_destroyed.height.truncate_push(
height,
StoredF64::from(Bitcoin::from(satblocks_destroyed)),
)?;
self.coindays_destroyed.height.truncate_push(
height,
StoredF64::from(Bitcoin::from(satdays_destroyed)),
)?;
Ok(()) Ok(())
} }
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> { pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
vec![&mut self.sent.height as &mut dyn AnyStoredVec] vec![
&mut self.core.sent.height as &mut dyn AnyStoredVec,
&mut self.coinblocks_destroyed.height as &mut dyn AnyStoredVec,
&mut self.coindays_destroyed.height as &mut dyn AnyStoredVec,
]
} }
pub(crate) fn validate_computed_versions(&mut self, _base_version: Version) -> Result<()> { pub(crate) fn validate_computed_versions(&mut self, _base_version: Version) -> Result<()> {
@@ -45,14 +75,12 @@ impl ActivityBase {
others: &[&Self], others: &[&Self],
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
self.sent.height.compute_sum_of_others( let core_refs: Vec<&ActivityCore> = others.iter().map(|o| &o.core).collect();
starting_indexes.height, self.core
&others .compute_from_stateful(starting_indexes, &core_refs, exit)?;
.iter()
.map(|v| &v.sent.height) sum_others!(self, starting_indexes, others, exit; coinblocks_destroyed.height);
.collect::<Vec<_>>(), sum_others!(self, starting_indexes, others, exit; coindays_destroyed.height);
exit,
)?;
Ok(()) Ok(())
} }
@@ -62,12 +90,8 @@ impl ActivityBase {
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
self.sent_sum.compute_rolling_sum( self.core
starting_indexes.height, .compute_rest_part1(blocks, starting_indexes, exit)?;
&blocks.count.height_24h_ago,
&self.sent.height,
exit,
)?;
Ok(()) Ok(())
} }
} }

View File

@@ -0,0 +1,73 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Height, Indexes, Sats, Version};
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
use crate::internal::{ComputedFromHeight, RollingWindow24h};
use crate::{blocks, distribution::metrics::ImportConfig};
#[derive(Traversable)]
pub struct ActivityCore<M: StorageMode = Rw> {
pub sent: ComputedFromHeight<Sats, M>,
pub sent_sum: RollingWindow24h<Sats, M>,
}
impl ActivityCore {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
let v1 = Version::ONE;
Ok(Self {
sent: cfg.import("sent", v1)?,
sent_sum: cfg.import("sent", v1)?,
})
}
pub(crate) fn min_len(&self) -> usize {
self.sent.height.len()
}
pub(crate) fn truncate_push(&mut self, height: Height, sent: Sats) -> Result<()> {
self.sent.height.truncate_push(height, sent)?;
Ok(())
}
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
vec![&mut self.sent.height as &mut dyn AnyStoredVec]
}
pub(crate) fn validate_computed_versions(&mut self, _base_version: Version) -> Result<()> {
Ok(())
}
pub(crate) fn compute_from_stateful(
&mut self,
starting_indexes: &Indexes,
others: &[&Self],
exit: &Exit,
) -> Result<()> {
self.sent.height.compute_sum_of_others(
starting_indexes.height,
&others
.iter()
.map(|v| &v.sent.height)
.collect::<Vec<_>>(),
exit,
)?;
Ok(())
}
pub(crate) fn compute_rest_part1(
&mut self,
blocks: &blocks::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.sent_sum.compute_rolling_sum(
starting_indexes.height,
&blocks.count.height_24h_ago,
&self.sent.height,
exit,
)?;
Ok(())
}
}

View File

@@ -1,12 +1,10 @@
use brk_error::Result; use brk_error::Result;
use brk_traversable::Traversable; use brk_traversable::Traversable;
use brk_types::{Bitcoin, Height, Indexes, Sats, StoredF64, Version}; use brk_types::{Indexes, Sats, StoredF64, Version};
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec}; use vecdb::{Exit, Rw, StorageMode};
use crate::internal::{ use crate::internal::{ComputedFromHeight, RollingWindows, RollingWindowsFrom1w};
ComputedFromHeightCumulative, ComputedFromHeightCumulativeSum, RollingWindowsFrom1w,
};
use crate::{blocks, distribution::metrics::ImportConfig}; use crate::{blocks, distribution::metrics::ImportConfig};
@@ -17,10 +15,11 @@ pub struct ActivityFull<M: StorageMode = Rw> {
#[deref] #[deref]
#[deref_mut] #[deref_mut]
#[traversable(flatten)] #[traversable(flatten)]
pub base: ActivityBase<M>, pub inner: ActivityBase<M>,
pub coinblocks_destroyed: ComputedFromHeightCumulative<StoredF64, M>, pub coinblocks_destroyed_cumulative: ComputedFromHeight<StoredF64, M>,
pub coindays_destroyed: ComputedFromHeightCumulativeSum<StoredF64, M>, pub coindays_destroyed_cumulative: ComputedFromHeight<StoredF64, M>,
pub coindays_destroyed_sum: RollingWindows<StoredF64, M>,
pub sent_sum_extended: RollingWindowsFrom1w<Sats, M>, pub sent_sum_extended: RollingWindowsFrom1w<Sats, M>,
} }
@@ -29,65 +28,23 @@ impl ActivityFull {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> { pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
let v1 = Version::ONE; let v1 = Version::ONE;
Ok(Self { Ok(Self {
base: ActivityBase::forced_import(cfg)?, inner: ActivityBase::forced_import(cfg)?,
coinblocks_destroyed: cfg coinblocks_destroyed_cumulative: cfg
.import("coinblocks_destroyed", v1)?, .import("coinblocks_destroyed_cumulative", v1)?,
coindays_destroyed: cfg.import("coindays_destroyed", v1)?, coindays_destroyed_cumulative: cfg.import("coindays_destroyed_cumulative", v1)?,
coindays_destroyed_sum: cfg.import("coindays_destroyed", v1)?,
sent_sum_extended: cfg.import("sent", v1)?, sent_sum_extended: cfg.import("sent", v1)?,
}) })
} }
pub(crate) fn min_len(&self) -> usize {
self.base
.min_len()
.min(self.coinblocks_destroyed.height.len())
.min(self.coindays_destroyed.height.len())
}
pub(crate) fn truncate_push(
&mut self,
height: Height,
sent: Sats,
satblocks_destroyed: Sats,
satdays_destroyed: Sats,
) -> Result<()> {
self.base.truncate_push(height, sent)?;
self.coinblocks_destroyed.height.truncate_push(
height,
StoredF64::from(Bitcoin::from(satblocks_destroyed)),
)?;
self.coindays_destroyed.height.truncate_push(
height,
StoredF64::from(Bitcoin::from(satdays_destroyed)),
)?;
Ok(())
}
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
vec![
&mut self.base.sent.height as &mut dyn AnyStoredVec,
&mut self.coinblocks_destroyed.height as &mut dyn AnyStoredVec,
&mut self.coindays_destroyed.height as &mut dyn AnyStoredVec,
]
}
pub(crate) fn validate_computed_versions(&mut self, _base_version: Version) -> Result<()> {
Ok(())
}
pub(crate) fn compute_from_stateful( pub(crate) fn compute_from_stateful(
&mut self, &mut self,
starting_indexes: &Indexes, starting_indexes: &Indexes,
others: &[&Self], others: &[&ActivityBase],
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
let core_refs: Vec<&ActivityBase> = others.iter().map(|o| &o.base).collect(); self.inner
self.base .compute_from_stateful(starting_indexes, others, exit)
.compute_from_stateful(starting_indexes, &core_refs, exit)?;
sum_others!(self, starting_indexes, others, exit; coinblocks_destroyed.height);
sum_others!(self, starting_indexes, others, exit; coindays_destroyed.height);
Ok(())
} }
pub(crate) fn compute_rest_part1( pub(crate) fn compute_rest_part1(
@@ -96,20 +53,37 @@ impl ActivityFull {
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
self.base self.inner
.compute_rest_part1(blocks, starting_indexes, exit)?; .compute_rest_part1(blocks, starting_indexes, exit)?;
self.coinblocks_destroyed self.coinblocks_destroyed_cumulative
.compute_rest(starting_indexes.height, exit)?; .height
.compute_cumulative(
starting_indexes.height,
&self.inner.coinblocks_destroyed.height,
exit,
)?;
self.coindays_destroyed_cumulative
.height
.compute_cumulative(
starting_indexes.height,
&self.inner.coindays_destroyed.height,
exit,
)?;
let window_starts = blocks.count.window_starts(); let window_starts = blocks.count.window_starts();
self.coindays_destroyed self.coindays_destroyed_sum.compute_rolling_sum(
.compute_rest(starting_indexes.height, &window_starts, exit)?; starting_indexes.height,
&window_starts,
&self.inner.coindays_destroyed.height,
exit,
)?;
self.sent_sum_extended.compute_rolling_sum( self.sent_sum_extended.compute_rolling_sum(
starting_indexes.height, starting_indexes.height,
&window_starts, &window_starts,
&self.base.sent.height, &self.inner.core.sent.height,
exit, exit,
)?; )?;

View File

@@ -1,5 +1,75 @@
mod base; mod base;
mod core;
mod full; mod full;
pub use base::ActivityBase; pub use base::ActivityBase;
pub use self::core::ActivityCore;
pub use full::ActivityFull; pub use full::ActivityFull;
use brk_error::Result;
use brk_types::{Height, Indexes, Sats, Version};
use vecdb::Exit;
use crate::blocks;
pub trait ActivityLike: Send + Sync {
fn as_base(&self) -> &ActivityBase;
fn as_base_mut(&mut self) -> &mut ActivityBase;
fn min_len(&self) -> usize;
fn truncate_push(
&mut self,
height: Height,
sent: Sats,
satblocks_destroyed: Sats,
satdays_destroyed: Sats,
) -> Result<()>;
fn validate_computed_versions(&mut self, base_version: Version) -> Result<()>;
fn compute_from_stateful(
&mut self,
starting_indexes: &Indexes,
others: &[&ActivityBase],
exit: &Exit,
) -> Result<()>;
fn compute_rest_part1(
&mut self,
blocks: &blocks::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()>;
}
impl ActivityLike for ActivityBase {
fn as_base(&self) -> &ActivityBase { self }
fn as_base_mut(&mut self) -> &mut ActivityBase { self }
fn min_len(&self) -> usize { self.min_len() }
fn truncate_push(&mut self, height: Height, sent: Sats, satblocks_destroyed: Sats, satdays_destroyed: Sats) -> Result<()> {
self.truncate_push(height, sent, satblocks_destroyed, satdays_destroyed)
}
fn validate_computed_versions(&mut self, base_version: Version) -> Result<()> {
self.validate_computed_versions(base_version)
}
fn compute_from_stateful(&mut self, starting_indexes: &Indexes, others: &[&ActivityBase], exit: &Exit) -> Result<()> {
self.compute_from_stateful(starting_indexes, others, exit)
}
fn compute_rest_part1(&mut self, blocks: &blocks::Vecs, starting_indexes: &Indexes, exit: &Exit) -> Result<()> {
self.compute_rest_part1(blocks, starting_indexes, exit)
}
}
impl ActivityLike for ActivityFull {
fn as_base(&self) -> &ActivityBase { &self.inner }
fn as_base_mut(&mut self) -> &mut ActivityBase { &mut self.inner }
fn min_len(&self) -> usize { self.inner.min_len() }
fn truncate_push(&mut self, height: Height, sent: Sats, satblocks_destroyed: Sats, satdays_destroyed: Sats) -> Result<()> {
self.inner.truncate_push(height, sent, satblocks_destroyed, satdays_destroyed)
}
fn validate_computed_versions(&mut self, base_version: Version) -> Result<()> {
self.inner.validate_computed_versions(base_version)
}
fn compute_from_stateful(&mut self, starting_indexes: &Indexes, others: &[&ActivityBase], exit: &Exit) -> Result<()> {
self.compute_from_stateful(starting_indexes, others, exit)
}
fn compute_rest_part1(&mut self, blocks: &blocks::Vecs, starting_indexes: &Indexes, exit: &Exit) -> Result<()> {
self.compute_rest_part1(blocks, starting_indexes, exit)
}
}

View File

@@ -34,6 +34,7 @@ pub struct AllCohortMetrics<M: StorageMode = Rw> {
} }
impl CohortMetricsBase for AllCohortMetrics { impl CohortMetricsBase for AllCohortMetrics {
type ActivityVecs = ActivityFull;
type RealizedVecs = RealizedFull; type RealizedVecs = RealizedFull;
type UnrealizedVecs = UnrealizedFull; type UnrealizedVecs = UnrealizedFull;
type CostBasisVecs = CostBasisWithExtended; type CostBasisVecs = CostBasisWithExtended;

View File

@@ -7,7 +7,7 @@ use vecdb::{AnyStoredVec, Exit, ReadableVec, Rw, StorageMode};
use crate::{blocks, prices}; use crate::{blocks, prices};
use crate::distribution::metrics::{ use crate::distribution::metrics::{
ActivityFull, CohortMetricsBase, CostBasisBase, ImportConfig, OutputsMetrics, RealizedBase, ActivityBase, CohortMetricsBase, CostBasisBase, ImportConfig, OutputsMetrics, RealizedBase,
RelativeToAll, SupplyMetrics, UnrealizedBase, RelativeToAll, SupplyMetrics, UnrealizedBase,
}; };
@@ -19,7 +19,7 @@ pub struct BasicCohortMetrics<M: StorageMode = Rw> {
pub filter: Filter, pub filter: Filter,
pub supply: Box<SupplyMetrics<M>>, pub supply: Box<SupplyMetrics<M>>,
pub outputs: Box<OutputsMetrics<M>>, pub outputs: Box<OutputsMetrics<M>>,
pub activity: Box<ActivityFull<M>>, pub activity: Box<ActivityBase<M>>,
pub realized: Box<RealizedBase<M>>, pub realized: Box<RealizedBase<M>>,
pub cost_basis: Box<CostBasisBase<M>>, pub cost_basis: Box<CostBasisBase<M>>,
pub unrealized: Box<UnrealizedBase<M>>, pub unrealized: Box<UnrealizedBase<M>>,
@@ -27,6 +27,7 @@ pub struct BasicCohortMetrics<M: StorageMode = Rw> {
} }
impl CohortMetricsBase for BasicCohortMetrics { impl CohortMetricsBase for BasicCohortMetrics {
type ActivityVecs = ActivityBase;
type RealizedVecs = RealizedBase; type RealizedVecs = RealizedBase;
type UnrealizedVecs = UnrealizedBase; type UnrealizedVecs = UnrealizedBase;
type CostBasisVecs = CostBasisBase; type CostBasisVecs = CostBasisBase;
@@ -57,7 +58,7 @@ impl BasicCohortMetrics {
filter: cfg.filter.clone(), filter: cfg.filter.clone(),
supply: Box::new(supply), supply: Box::new(supply),
outputs: Box::new(OutputsMetrics::forced_import(cfg)?), outputs: Box::new(OutputsMetrics::forced_import(cfg)?),
activity: Box::new(ActivityFull::forced_import(cfg)?), activity: Box::new(ActivityBase::forced_import(cfg)?),
realized: Box::new(realized), realized: Box::new(realized),
cost_basis: Box::new(CostBasisBase::forced_import(cfg)?), cost_basis: Box::new(CostBasisBase::forced_import(cfg)?),
unrealized: Box::new(unrealized), unrealized: Box::new(unrealized),

View File

@@ -7,7 +7,7 @@ use vecdb::{AnyStoredVec, Exit, ReadableVec, Rw, StorageMode};
use crate::{blocks, prices}; use crate::{blocks, prices};
use crate::distribution::metrics::{ use crate::distribution::metrics::{
ActivityBase, CohortMetricsBase, RealizedCore, ImportConfig, OutputsMetrics, ActivityCore, CohortMetricsBase, RealizedCore, ImportConfig, OutputsMetrics,
RelativeToAll, SupplyMetrics, UnrealizedCore, RelativeToAll, SupplyMetrics, UnrealizedCore,
}; };
@@ -17,7 +17,7 @@ pub struct CoreCohortMetrics<M: StorageMode = Rw> {
pub filter: Filter, pub filter: Filter,
pub supply: Box<SupplyMetrics<M>>, pub supply: Box<SupplyMetrics<M>>,
pub outputs: Box<OutputsMetrics<M>>, pub outputs: Box<OutputsMetrics<M>>,
pub activity: Box<ActivityBase<M>>, pub activity: Box<ActivityCore<M>>,
pub realized: Box<RealizedCore<M>>, pub realized: Box<RealizedCore<M>>,
pub unrealized: Box<UnrealizedCore<M>>, pub unrealized: Box<UnrealizedCore<M>>,
pub relative: Box<RelativeToAll<M>>, pub relative: Box<RelativeToAll<M>>,
@@ -29,7 +29,7 @@ impl CoreCohortMetrics {
filter: cfg.filter.clone(), filter: cfg.filter.clone(),
supply: Box::new(SupplyMetrics::forced_import(cfg)?), supply: Box::new(SupplyMetrics::forced_import(cfg)?),
outputs: Box::new(OutputsMetrics::forced_import(cfg)?), outputs: Box::new(OutputsMetrics::forced_import(cfg)?),
activity: Box::new(ActivityBase::forced_import(cfg)?), activity: Box::new(ActivityCore::forced_import(cfg)?),
realized: Box::new(RealizedCore::forced_import(cfg)?), realized: Box::new(RealizedCore::forced_import(cfg)?),
unrealized: Box::new(UnrealizedCore::forced_import(cfg)?), unrealized: Box::new(UnrealizedCore::forced_import(cfg)?),
relative: Box::new(RelativeToAll::forced_import(cfg)?), relative: Box::new(RelativeToAll::forced_import(cfg)?),
@@ -80,7 +80,7 @@ impl CoreCohortMetrics {
)?; )?;
self.activity.compute_from_stateful( self.activity.compute_from_stateful(
starting_indexes, starting_indexes,
&others.iter().map(|v| &v.activity().base).collect::<Vec<_>>(), &others.iter().map(|v| &v.activity_base().core).collect::<Vec<_>>(),
exit, exit,
)?; )?;
self.realized.compute_from_stateful( self.realized.compute_from_stateful(

View File

@@ -32,6 +32,7 @@ pub struct ExtendedCohortMetrics<M: StorageMode = Rw> {
} }
impl CohortMetricsBase for ExtendedCohortMetrics { impl CohortMetricsBase for ExtendedCohortMetrics {
type ActivityVecs = ActivityFull;
type RealizedVecs = RealizedFull; type RealizedVecs = RealizedFull;
type UnrealizedVecs = UnrealizedFull; type UnrealizedVecs = UnrealizedFull;
type CostBasisVecs = CostBasisWithExtended; type CostBasisVecs = CostBasisWithExtended;

View File

@@ -7,8 +7,8 @@ use vecdb::{AnyStoredVec, Exit, ReadableVec, Rw, StorageMode};
use crate::{blocks, prices}; use crate::{blocks, prices};
use crate::distribution::metrics::{ use crate::distribution::metrics::{
CohortMetricsBase, CostBasisWithExtended, ImportConfig, RealizedAdjusted, RealizedFull, ActivityFull, CohortMetricsBase, CostBasisWithExtended, ImportConfig, RealizedAdjusted,
UnrealizedFull, RealizedFull, UnrealizedFull,
}; };
use super::ExtendedCohortMetrics; use super::ExtendedCohortMetrics;
@@ -27,6 +27,7 @@ pub struct ExtendedAdjustedCohortMetrics<M: StorageMode = Rw> {
} }
impl CohortMetricsBase for ExtendedAdjustedCohortMetrics { impl CohortMetricsBase for ExtendedAdjustedCohortMetrics {
type ActivityVecs = ActivityFull;
type RealizedVecs = RealizedFull; type RealizedVecs = RealizedFull;
type UnrealizedVecs = UnrealizedFull; type UnrealizedVecs = UnrealizedFull;
type CostBasisVecs = CostBasisWithExtended; type CostBasisVecs = CostBasisWithExtended;

View File

@@ -9,7 +9,7 @@ use crate::{blocks, prices};
use crate::internal::ValueFromHeight; use crate::internal::ValueFromHeight;
use crate::distribution::{ use crate::distribution::{
metrics::{ActivityBase, ImportConfig, OutputsMetrics, RealizedMinimal, SupplyMetrics}, metrics::{ActivityCore, ImportConfig, OutputsMetrics, RealizedMinimal, SupplyMetrics},
state::UnrealizedState, state::UnrealizedState,
}; };
@@ -31,7 +31,7 @@ pub struct MinimalCohortMetrics<M: StorageMode = Rw> {
pub filter: Filter, pub filter: Filter,
pub supply: Box<SupplyMetrics<M>>, pub supply: Box<SupplyMetrics<M>>,
pub outputs: Box<OutputsMetrics<M>>, pub outputs: Box<OutputsMetrics<M>>,
pub activity: Box<ActivityBase<M>>, pub activity: Box<ActivityCore<M>>,
pub realized: Box<RealizedMinimal<M>>, pub realized: Box<RealizedMinimal<M>>,
pub unrealized: Box<MinimalUnrealized<M>>, pub unrealized: Box<MinimalUnrealized<M>>,
} }
@@ -106,7 +106,7 @@ impl MinimalCohortMetrics {
filter: cfg.filter.clone(), filter: cfg.filter.clone(),
supply: Box::new(SupplyMetrics::forced_import(cfg)?), supply: Box::new(SupplyMetrics::forced_import(cfg)?),
outputs: Box::new(OutputsMetrics::forced_import(cfg)?), outputs: Box::new(OutputsMetrics::forced_import(cfg)?),
activity: Box::new(ActivityBase::forced_import(cfg)?), activity: Box::new(ActivityCore::forced_import(cfg)?),
realized: Box::new(RealizedMinimal::forced_import(cfg)?), realized: Box::new(RealizedMinimal::forced_import(cfg)?),
unrealized: Box::new(MinimalUnrealized::forced_import(cfg)?), unrealized: Box::new(MinimalUnrealized::forced_import(cfg)?),
}) })

View File

@@ -11,8 +11,8 @@ use crate::{
internal::{ internal::{
CentsType, ComputedFromHeight, ComputedFromHeightCumulative, CentsType, ComputedFromHeight, ComputedFromHeightCumulative,
ComputedFromHeightCumulativeSum, ComputedFromHeightRatio, FiatFromHeight, NumericValue, ComputedFromHeightCumulativeSum, ComputedFromHeightRatio, FiatFromHeight, NumericValue,
PercentFromHeight, PercentRollingEmas1w1m, PercentRollingWindows, Price, RollingEmas1w1m, PercentFromHeight, PercentRollingWindows, Price,
RollingEmas2w, RollingWindow24h, RollingWindows, RollingWindowsFrom1w, RollingWindow24h, RollingWindows, RollingWindowsFrom1w,
ValueFromHeight, ValueFromHeightChange, ValueFromHeightCumulative, ValueFromHeight, ValueFromHeightChange, ValueFromHeightCumulative,
}, },
}; };
@@ -41,12 +41,10 @@ impl_config_import!(
ValueFromHeightCumulative, ValueFromHeightCumulative,
ValueFromHeightChange, ValueFromHeightChange,
ComputedFromHeightRatio, ComputedFromHeightRatio,
RollingEmas2w,
PercentFromHeight<BasisPoints16>, PercentFromHeight<BasisPoints16>,
PercentFromHeight<BasisPoints32>, PercentFromHeight<BasisPoints32>,
PercentFromHeight<BasisPointsSigned32>, PercentFromHeight<BasisPointsSigned32>,
PercentRollingWindows<BasisPoints32>, PercentRollingWindows<BasisPoints32>,
PercentRollingEmas1w1m<BasisPoints32>,
Price<ComputedFromHeight<Cents>>, Price<ComputedFromHeight<Cents>>,
); );
@@ -81,11 +79,6 @@ impl<T: NumericValue + JsonSchema> ConfigImport for RollingWindowsFrom1w<T> {
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes) Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
} }
} }
impl<T: NumericValue + JsonSchema> ConfigImport for RollingEmas1w1m<T> {
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
}
}
impl<C: CentsType> ConfigImport for FiatFromHeight<C> { impl<C: CentsType> ConfigImport for FiatFromHeight<C> {
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> { fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes) Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)

View File

@@ -23,8 +23,8 @@ macro_rules! impl_cohort_accessors {
fn supply_mut(&mut self) -> &mut $crate::distribution::metrics::SupplyMetrics { &mut self.supply } fn supply_mut(&mut self) -> &mut $crate::distribution::metrics::SupplyMetrics { &mut self.supply }
fn outputs(&self) -> &$crate::distribution::metrics::OutputsMetrics { &self.outputs } fn outputs(&self) -> &$crate::distribution::metrics::OutputsMetrics { &self.outputs }
fn outputs_mut(&mut self) -> &mut $crate::distribution::metrics::OutputsMetrics { &mut self.outputs } fn outputs_mut(&mut self) -> &mut $crate::distribution::metrics::OutputsMetrics { &mut self.outputs }
fn activity(&self) -> &$crate::distribution::metrics::ActivityFull { &self.activity } fn activity(&self) -> &Self::ActivityVecs { &self.activity }
fn activity_mut(&mut self) -> &mut $crate::distribution::metrics::ActivityFull { &mut self.activity } fn activity_mut(&mut self) -> &mut Self::ActivityVecs { &mut self.activity }
fn realized(&self) -> &Self::RealizedVecs { &self.realized } fn realized(&self) -> &Self::RealizedVecs { &self.realized }
fn realized_mut(&mut self) -> &mut Self::RealizedVecs { &mut self.realized } fn realized_mut(&mut self) -> &mut Self::RealizedVecs { &mut self.realized }
fn unrealized(&self) -> &Self::UnrealizedVecs { &self.unrealized } fn unrealized(&self) -> &Self::UnrealizedVecs { &self.unrealized }
@@ -43,7 +43,7 @@ mod relative;
mod supply; mod supply;
mod unrealized; mod unrealized;
pub use activity::{ActivityBase, ActivityFull}; pub use activity::{ActivityBase, ActivityCore, ActivityFull, ActivityLike};
pub use cohort::{ pub use cohort::{
AllCohortMetrics, BasicCohortMetrics, CoreCohortMetrics, ExtendedAdjustedCohortMetrics, AllCohortMetrics, BasicCohortMetrics, CoreCohortMetrics, ExtendedAdjustedCohortMetrics,
ExtendedCohortMetrics, MinimalCohortMetrics, ExtendedCohortMetrics, MinimalCohortMetrics,
@@ -91,6 +91,7 @@ impl<M: StorageMode> CohortMetricsState for AllCohortMetrics<M> {
} }
pub trait CohortMetricsBase: CohortMetricsState<Realized = RealizedState> + Send + Sync { pub trait CohortMetricsBase: CohortMetricsState<Realized = RealizedState> + Send + Sync {
type ActivityVecs: ActivityLike;
type RealizedVecs: RealizedLike; type RealizedVecs: RealizedLike;
type UnrealizedVecs: UnrealizedLike; type UnrealizedVecs: UnrealizedLike;
type CostBasisVecs: CostBasisLike; type CostBasisVecs: CostBasisLike;
@@ -100,8 +101,8 @@ pub trait CohortMetricsBase: CohortMetricsState<Realized = RealizedState> + Send
fn supply_mut(&mut self) -> &mut SupplyMetrics; fn supply_mut(&mut self) -> &mut SupplyMetrics;
fn outputs(&self) -> &OutputsMetrics; fn outputs(&self) -> &OutputsMetrics;
fn outputs_mut(&mut self) -> &mut OutputsMetrics; fn outputs_mut(&mut self) -> &mut OutputsMetrics;
fn activity(&self) -> &ActivityFull; fn activity(&self) -> &Self::ActivityVecs;
fn activity_mut(&mut self) -> &mut ActivityFull; fn activity_mut(&mut self) -> &mut Self::ActivityVecs;
fn realized(&self) -> &Self::RealizedVecs; fn realized(&self) -> &Self::RealizedVecs;
fn realized_mut(&mut self) -> &mut Self::RealizedVecs; fn realized_mut(&mut self) -> &mut Self::RealizedVecs;
fn unrealized(&self) -> &Self::UnrealizedVecs; fn unrealized(&self) -> &Self::UnrealizedVecs;
@@ -109,6 +110,10 @@ pub trait CohortMetricsBase: CohortMetricsState<Realized = RealizedState> + Send
fn cost_basis(&self) -> &Self::CostBasisVecs; fn cost_basis(&self) -> &Self::CostBasisVecs;
fn cost_basis_mut(&mut self) -> &mut Self::CostBasisVecs; fn cost_basis_mut(&mut self) -> &mut Self::CostBasisVecs;
/// Convenience: access activity as `&ActivityBase` (via `ActivityLike::as_base`).
fn activity_base(&self) -> &ActivityBase { self.activity().as_base() }
fn activity_base_mut(&mut self) -> &mut ActivityBase { self.activity_mut().as_base_mut() }
/// Convenience: access realized as `&RealizedBase` (via `RealizedLike::as_base`). /// Convenience: access realized as `&RealizedBase` (via `RealizedLike::as_base`).
fn realized_base(&self) -> &RealizedBase { self.realized().as_base() } fn realized_base(&self) -> &RealizedBase { self.realized().as_base() }
fn realized_base_mut(&mut self) -> &mut RealizedBase { self.realized_mut().as_base_mut() } fn realized_base_mut(&mut self) -> &mut RealizedBase { self.realized_mut().as_base_mut() }
@@ -240,7 +245,7 @@ pub trait CohortMetricsBase: CohortMetricsState<Realized = RealizedState> + Send
)?; )?;
self.activity_mut().compute_from_stateful( self.activity_mut().compute_from_stateful(
starting_indexes, starting_indexes,
&others.iter().map(|v| v.activity()).collect::<Vec<_>>(), &others.iter().map(|v| v.activity_base()).collect::<Vec<_>>(),
exit, exit,
)?; )?;
self.realized_mut().compute_from_stateful( self.realized_mut().compute_from_stateful(

View File

@@ -5,7 +5,7 @@ use vecdb::{Exit, ReadableVec, Rw, StorageMode};
use crate::{ use crate::{
blocks, blocks,
internal::{ComputedFromHeight, RatioCents64, RollingEmas1w1m, RollingWindows}, internal::{ComputedFromHeight, RatioCents64, RollingWindows},
}; };
use crate::distribution::metrics::ImportConfig; use crate::distribution::metrics::ImportConfig;
@@ -19,7 +19,6 @@ pub struct RealizedAdjusted<M: StorageMode = Rw> {
pub adjusted_value_destroyed_sum: RollingWindows<Cents, M>, pub adjusted_value_destroyed_sum: RollingWindows<Cents, M>,
pub adjusted_sopr: RollingWindows<StoredF64, M>, pub adjusted_sopr: RollingWindows<StoredF64, M>,
pub adjusted_sopr_ema: RollingEmas1w1m<StoredF64, M>,
} }
impl RealizedAdjusted { impl RealizedAdjusted {
@@ -30,7 +29,6 @@ impl RealizedAdjusted {
adjusted_value_created_sum: cfg.import("adjusted_value_created", Version::ONE)?, adjusted_value_created_sum: cfg.import("adjusted_value_created", Version::ONE)?,
adjusted_value_destroyed_sum: cfg.import("adjusted_value_destroyed", Version::ONE)?, adjusted_value_destroyed_sum: cfg.import("adjusted_value_destroyed", Version::ONE)?,
adjusted_sopr: cfg.import("adjusted_sopr", Version::ONE)?, adjusted_sopr: cfg.import("adjusted_sopr", Version::ONE)?,
adjusted_sopr_ema: cfg.import("adjusted_sopr_24h", Version::ONE)?,
}) })
} }
@@ -90,15 +88,6 @@ impl RealizedAdjusted {
)?; )?;
} }
// Adjusted SOPR EMAs (based on 24h window)
self.adjusted_sopr_ema.compute_from_24h(
starting_indexes.height,
&blocks.count.height_1w_ago,
&blocks.count.height_1m_ago,
&self.adjusted_sopr._24h.height,
exit,
)?;
Ok(()) Ok(())
} }
} }

View File

@@ -17,9 +17,9 @@ use crate::{
CentsUnsignedToDollars, ComputedFromHeight, ComputedFromHeightCumulative, FiatFromHeight, CentsUnsignedToDollars, ComputedFromHeight, ComputedFromHeightCumulative, FiatFromHeight,
ComputedFromHeightRatio, ComputedFromHeightRatioPercentiles, ComputedFromHeightRatio, ComputedFromHeightRatioPercentiles,
ComputedFromHeightRatioStdDevBands, LazyFromHeight, PercentFromHeight, ComputedFromHeightRatioStdDevBands, LazyFromHeight, PercentFromHeight,
PercentRollingEmas1w1m, PercentRollingWindows, Price, RatioCents64, RatioCentsBp32, PercentRollingWindows, Price, RatioCents64, RatioCentsBp32,
RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32, RatioDollarsBp32, RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32, RatioDollarsBp32,
RollingEmas1w1m, RollingWindows, RollingWindowsFrom1w, RollingWindows, RollingWindowsFrom1w,
}, },
prices, prices,
}; };
@@ -65,7 +65,6 @@ pub struct RealizedFull<M: StorageMode = Rw> {
pub investor_cap_raw: M::Stored<BytesVec<Height, CentsSquaredSats>>, pub investor_cap_raw: M::Stored<BytesVec<Height, CentsSquaredSats>>,
pub sell_side_risk_ratio: PercentRollingWindows<BasisPoints32, M>, pub sell_side_risk_ratio: PercentRollingWindows<BasisPoints32, M>,
pub sell_side_risk_ratio_24h_ema: PercentRollingEmas1w1m<BasisPoints32, M>,
pub peak_regret: ComputedFromHeightCumulative<Cents, M>, pub peak_regret: ComputedFromHeightCumulative<Cents, M>,
pub peak_regret_rel_to_realized_cap: PercentFromHeight<BasisPoints32, M>, pub peak_regret_rel_to_realized_cap: PercentFromHeight<BasisPoints32, M>,
@@ -76,12 +75,6 @@ pub struct RealizedFull<M: StorageMode = Rw> {
pub realized_loss_sum: RollingWindows<Cents, M>, pub realized_loss_sum: RollingWindows<Cents, M>,
pub realized_profit_to_loss_ratio: RollingWindows<StoredF64, M>, pub realized_profit_to_loss_ratio: RollingWindows<StoredF64, M>,
pub realized_profit_ema_1w: ComputedFromHeight<Cents, M>,
pub realized_loss_ema_1w: ComputedFromHeight<Cents, M>,
pub net_realized_pnl_ema_1w: ComputedFromHeight<CentsSigned, M>,
pub sopr_24h_ema: RollingEmas1w1m<StoredF64, M>,
pub value_created_sum_extended: RollingWindowsFrom1w<Cents, M>, pub value_created_sum_extended: RollingWindowsFrom1w<Cents, M>,
pub value_destroyed_sum_extended: RollingWindowsFrom1w<Cents, M>, pub value_destroyed_sum_extended: RollingWindowsFrom1w<Cents, M>,
pub sopr_extended: RollingWindowsFrom1w<StoredF64, M>, pub sopr_extended: RollingWindowsFrom1w<StoredF64, M>,
@@ -135,8 +128,6 @@ impl RealizedFull {
let sell_side_risk_ratio = let sell_side_risk_ratio =
cfg.import("sell_side_risk_ratio", Version::new(2))?; cfg.import("sell_side_risk_ratio", Version::new(2))?;
let sell_side_risk_ratio_24h_ema =
cfg.import("sell_side_risk_ratio_24h", Version::new(2))?;
let peak_regret = cfg.import("realized_peak_regret", Version::new(2))?; let peak_regret = cfg.import("realized_peak_regret", Version::new(2))?;
let peak_regret_rel_to_realized_cap = let peak_regret_rel_to_realized_cap =
@@ -154,10 +145,6 @@ impl RealizedFull {
let net_realized_pnl_rel_to_realized_cap = let net_realized_pnl_rel_to_realized_cap =
cfg.import("net_realized_pnl_rel_to_realized_cap", Version::new(2))?; cfg.import("net_realized_pnl_rel_to_realized_cap", Version::new(2))?;
let realized_profit_ema_1w = cfg.import("realized_profit_ema_1w", v0)?;
let realized_loss_ema_1w = cfg.import("realized_loss_ema_1w", v0)?;
let net_realized_pnl_ema_1w = cfg.import("net_realized_pnl_ema_1w", v0)?;
let sopr_24h_ema = cfg.import("sopr_24h", v1)?;
let value_created_sum_extended = cfg.import("value_created", v1)?; let value_created_sum_extended = cfg.import("value_created", v1)?;
let value_destroyed_sum_extended = cfg.import("value_destroyed", v1)?; let value_destroyed_sum_extended = cfg.import("value_destroyed", v1)?;
let sopr_extended = cfg.import("sopr", v1)?; let sopr_extended = cfg.import("sopr", v1)?;
@@ -187,7 +174,6 @@ impl RealizedFull {
cap_raw, cap_raw,
investor_cap_raw, investor_cap_raw,
sell_side_risk_ratio, sell_side_risk_ratio,
sell_side_risk_ratio_24h_ema,
peak_regret, peak_regret,
peak_regret_rel_to_realized_cap, peak_regret_rel_to_realized_cap,
realized_cap_rel_to_own_market_cap: cfg realized_cap_rel_to_own_market_cap: cfg
@@ -196,10 +182,6 @@ impl RealizedFull {
realized_loss_sum: cfg.import("realized_loss", v1)?, realized_loss_sum: cfg.import("realized_loss", v1)?,
realized_profit_to_loss_ratio: cfg realized_profit_to_loss_ratio: cfg
.import("realized_profit_to_loss_ratio", v1)?, .import("realized_profit_to_loss_ratio", v1)?,
realized_profit_ema_1w,
realized_loss_ema_1w,
net_realized_pnl_ema_1w,
sopr_24h_ema,
value_created_sum_extended, value_created_sum_extended,
value_destroyed_sum_extended, value_destroyed_sum_extended,
sopr_extended, sopr_extended,
@@ -372,33 +354,6 @@ impl RealizedFull {
exit, exit,
)?; )?;
// EMAs
self.realized_profit_ema_1w.height.compute_rolling_ema(
starting_indexes.height,
&blocks.count.height_1w_ago,
&self.base.core.minimal.realized_profit.height,
exit,
)?;
self.realized_loss_ema_1w.height.compute_rolling_ema(
starting_indexes.height,
&blocks.count.height_1w_ago,
&self.base.core.minimal.realized_loss.height,
exit,
)?;
self.net_realized_pnl_ema_1w.height.compute_rolling_ema(
starting_indexes.height,
&blocks.count.height_1w_ago,
&self.base.core.net_realized_pnl.height,
exit,
)?;
self.sopr_24h_ema.compute_from_24h(
starting_indexes.height,
&blocks.count.height_1w_ago,
&blocks.count.height_1m_ago,
&self.base.core.sopr._24h.height,
exit,
)?;
// Sent in profit/loss rolling sums // Sent in profit/loss rolling sums
let window_starts = blocks.count.window_starts(); let window_starts = blocks.count.window_starts();
self.sent_in_profit_sum.compute_rolling_sum( self.sent_in_profit_sum.compute_rolling_sum(
@@ -516,14 +471,6 @@ impl RealizedFull {
)?; )?;
} }
self.sell_side_risk_ratio_24h_ema.compute_from_24h(
starting_indexes.height,
&blocks.count.height_1w_ago,
&blocks.count.height_1m_ago,
&self.sell_side_risk_ratio._24h.bps.height,
exit,
)?;
// Extended: realized profit/loss rolling sums // Extended: realized profit/loss rolling sums
let window_starts = blocks.count.window_starts(); let window_starts = blocks.count.window_starts();
self.realized_profit_sum.compute_rolling_sum( self.realized_profit_sum.compute_rolling_sum(

View File

@@ -1,30 +0,0 @@
use brk_traversable::Traversable;
#[derive(Clone, Traversable)]
pub struct Emas1w1m<A> {
#[traversable(rename = "1w")]
pub _1w: A,
#[traversable(rename = "1m")]
pub _1m: A,
}
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]
}
}

View File

@@ -1,9 +1,7 @@
mod distribution_stats; mod distribution_stats;
mod emas;
mod per_period; mod per_period;
mod windows; mod windows;
pub use distribution_stats::*; pub use distribution_stats::*;
pub use emas::*;
pub use per_period::*; pub use per_period::*;
pub use windows::*; pub use windows::*;

View File

@@ -66,27 +66,4 @@ impl ValueFromHeight {
.compute_rolling_sum(max_from, window_starts, cents_source, exit)?; .compute_rolling_sum(max_from, window_starts, cents_source, exit)?;
Ok(()) Ok(())
} }
pub(crate) fn compute_ema(
&mut self,
starting_height: Height,
window_starts: &impl ReadableVec<Height, Height>,
sats_source: &impl ReadableVec<Height, Sats>,
cents_source: &(impl ReadableVec<Height, Cents> + Sync),
exit: &Exit,
) -> Result<()> {
self.base.sats.height.compute_rolling_ema(
starting_height,
window_starts,
sats_source,
exit,
)?;
self.base.cents.height.compute_rolling_ema(
starting_height,
window_starts,
cents_source,
exit,
)?;
Ok(())
}
} }

View File

@@ -1,7 +0,0 @@
mod _1w_1m;
mod _2w;
mod percent_1w_1m;
pub use _1w_1m::*;
pub use _2w::*;
pub use percent_1w_1m::*;

View File

@@ -1,54 +0,0 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Height, Version};
use derive_more::{Deref, DerefMut};
use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode};
use crate::{
indexes,
internal::{BpsType, Emas1w1m, PercentFromHeight},
};
/// 2 EMA vecs (1w, 1m) sourced from 24h rolling window,
/// each storing basis points with lazy ratio and percent float views.
#[derive(Deref, DerefMut, Traversable)]
#[traversable(transparent)]
pub struct PercentRollingEmas1w1m<B: BpsType, M: StorageMode = Rw>(
pub Emas1w1m<PercentFromHeight<B, M>>,
);
impl<B: BpsType> PercentRollingEmas1w1m<B> {
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self(Emas1w1m::try_from_fn(|suffix| {
PercentFromHeight::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
})?))
}
pub(crate) fn compute_from_24h(
&mut self,
max_from: Height,
height_1w_ago: &impl ReadableVec<Height, Height>,
height_1m_ago: &impl ReadableVec<Height, Height>,
source: &impl ReadableVec<Height, B>,
exit: &Exit,
) -> Result<()>
where
f64: From<B>,
B: From<f64> + Default,
{
self._1w
.bps
.height
.compute_rolling_ema(max_from, height_1w_ago, source, exit)?;
self._1m
.bps
.height
.compute_rolling_ema(max_from, height_1m_ago, source, exit)?;
Ok(())
}
}

View File

@@ -1,12 +1,10 @@
mod distribution; mod distribution;
mod emas;
mod full; mod full;
mod percent_windows; mod percent_windows;
mod value_windows; mod value_windows;
mod windows; mod windows;
pub use distribution::*; pub use distribution::*;
pub use emas::*;
pub use full::*; pub use full::*;
pub use percent_windows::*; pub use percent_windows::*;
pub use value_windows::*; pub use value_windows::*;

View File

@@ -119,7 +119,7 @@ impl Formattable for DifficultyEpoch {
impl From<f64> for DifficultyEpoch { impl From<f64> for DifficultyEpoch {
#[inline] #[inline]
fn from(value: f64) -> Self { fn from(value: f64) -> Self {
debug_assert!(value >= 0.0); let value = value.max(0.0);
Self(value.round() as u16) Self(value.round() as u16)
} }
} }

View File

@@ -125,7 +125,7 @@ impl Formattable for HalvingEpoch {
impl From<f64> for HalvingEpoch { impl From<f64> for HalvingEpoch {
#[inline] #[inline]
fn from(value: f64) -> Self { fn from(value: f64) -> Self {
debug_assert!(value >= 0.0); let value = value.max(0.0);
Self(value.round() as u8) Self(value.round() as u8)
} }
} }

View File

@@ -83,7 +83,8 @@ impl AddAssign for StoredU16 {
impl From<f64> for StoredU16 { impl From<f64> for StoredU16 {
#[inline] #[inline]
fn from(value: f64) -> Self { fn from(value: f64) -> Self {
debug_assert!(value >= 0.0 && value <= u16::MAX as f64); let value = value.max(0.0);
debug_assert!(value <= u16::MAX as f64);
Self(value as u16) Self(value as u16)
} }
} }

View File

@@ -135,7 +135,8 @@ impl Mul<usize> for StoredU32 {
impl From<f64> for StoredU32 { impl From<f64> for StoredU32 {
#[inline] #[inline]
fn from(value: f64) -> Self { fn from(value: f64) -> Self {
debug_assert!(value >= 0.0 && value <= u32::MAX as f64); let value = value.max(0.0);
debug_assert!(value <= u32::MAX as f64);
Self(value as u32) Self(value as u32)
} }
} }

View File

@@ -108,7 +108,7 @@ impl SubAssign for StoredU64 {
impl From<f64> for StoredU64 { impl From<f64> for StoredU64 {
#[inline] #[inline]
fn from(value: f64) -> Self { fn from(value: f64) -> Self {
debug_assert!(value >= 0.0); let value = value.max(0.0);
Self(value as u64) Self(value as u64)
} }
} }

View File

@@ -60,7 +60,8 @@ impl AddAssign for StoredU8 {
impl From<f64> for StoredU8 { impl From<f64> for StoredU8 {
#[inline] #[inline]
fn from(value: f64) -> Self { fn from(value: f64) -> Self {
debug_assert!(value >= 0.0 && value <= u8::MAX as f64); let value = value.max(0.0);
debug_assert!(value <= u8::MAX as f64);
Self(value as u8) Self(value as u8)
} }
} }

View File

@@ -165,7 +165,8 @@ impl AddAssign for Timestamp {
impl From<f64> for Timestamp { impl From<f64> for Timestamp {
#[inline] #[inline]
fn from(value: f64) -> Self { fn from(value: f64) -> Self {
debug_assert!(value >= 0.0 && value <= u32::MAX as f64); let value = value.max(0.0);
debug_assert!(value <= u32::MAX as f64);
Self(value as u32) Self(value as u32)
} }
} }

View File

@@ -63,10 +63,8 @@ impl From<usize> for VSize {
impl From<f64> for VSize { impl From<f64> for VSize {
#[inline] #[inline]
fn from(value: f64) -> Self { fn from(value: f64) -> Self {
debug_assert!( let value = value.max(0.0);
value >= 0.0 && value.fract() == 0.0, debug_assert!(value.fract() == 0.0, "VSize must be an integer");
"VSize must be a non-negative integer"
);
Self(value as u64) Self(value as u64)
} }
} }

View File

@@ -76,7 +76,7 @@ impl From<usize> for Weight {
impl From<f64> for Weight { impl From<f64> for Weight {
#[inline] #[inline]
fn from(value: f64) -> Self { fn from(value: f64) -> Self {
debug_assert!(value >= 0.0); let value = value.max(0.0);
Self(value as u64) Self(value as u64)
} }
} }

View File

@@ -2492,6 +2492,37 @@ function create_1m1w1y24hBtcCentsSatsUsdPattern(client, acc) {
}; };
} }
/**
* @typedef {Object} CoinblocksCoindaysSentPattern2
* @property {MetricPattern1<StoredF64>} coinblocksDestroyed
* @property {MetricPattern1<StoredF64>} coinblocksDestroyedCumulative
* @property {MetricPattern1<StoredF64>} coindaysDestroyed
* @property {MetricPattern1<StoredF64>} coindaysDestroyedCumulative
* @property {_1m1w1y24hPattern<StoredF64>} coindaysDestroyedSum
* @property {MetricPattern1<Sats>} sent
* @property {_24hPattern<Sats>} sentSum
* @property {_1m1w1yPattern<Sats>} sentSumExtended
*/
/**
* Create a CoinblocksCoindaysSentPattern2 pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {CoinblocksCoindaysSentPattern2}
*/
function createCoinblocksCoindaysSentPattern2(client, acc) {
return {
coinblocksDestroyed: createMetricPattern1(client, _m(acc, 'coinblocks_destroyed')),
coinblocksDestroyedCumulative: createMetricPattern1(client, _m(acc, 'coinblocks_destroyed_cumulative')),
coindaysDestroyed: createMetricPattern1(client, _m(acc, 'coindays_destroyed')),
coindaysDestroyedCumulative: createMetricPattern1(client, _m(acc, 'coindays_destroyed_cumulative')),
coindaysDestroyedSum: create_1m1w1y24hPattern(client, _m(acc, 'coindays_destroyed')),
sent: createMetricPattern1(client, _m(acc, 'sent')),
sentSum: create_24hPattern(client, _m(acc, 'sent_24h')),
sentSumExtended: create_1m1w1yPattern(client, _m(acc, 'sent')),
};
}
/** /**
* @template T * @template T
* @typedef {Object} AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern * @typedef {Object} AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern
@@ -2745,31 +2776,6 @@ function createBaseBtcCentsSatsUsdPattern(client, acc) {
}; };
} }
/**
* @typedef {Object} CoinblocksCoindaysSentPattern
* @property {CumulativeHeightPattern<StoredF64>} coinblocksDestroyed
* @property {CumulativeHeightSumPattern<StoredF64>} coindaysDestroyed
* @property {MetricPattern1<Sats>} sent
* @property {_24hPattern<Sats>} sentSum
* @property {_1m1w1yPattern<Sats>} sentSumExtended
*/
/**
* Create a CoinblocksCoindaysSentPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {CoinblocksCoindaysSentPattern}
*/
function createCoinblocksCoindaysSentPattern(client, acc) {
return {
coinblocksDestroyed: createCumulativeHeightPattern(client, _m(acc, 'coinblocks_destroyed')),
coindaysDestroyed: createCumulativeHeightSumPattern(client, _m(acc, 'coindays_destroyed')),
sent: createMetricPattern1(client, _m(acc, 'sent')),
sentSum: create_24hPattern(client, _m(acc, 'sent_24h')),
sentSumExtended: create_1m1w1yPattern(client, _m(acc, 'sent')),
};
}
/** /**
* @typedef {Object} EmaHistogramLineSignalPattern * @typedef {Object} EmaHistogramLineSignalPattern
* @property {MetricPattern1<StoredF32>} emaFast * @property {MetricPattern1<StoredF32>} emaFast
@@ -2937,6 +2943,29 @@ function createBtcCentsSatsUsdPattern(client, acc) {
}; };
} }
/**
* @typedef {Object} CoinblocksCoindaysSentPattern
* @property {MetricPattern1<StoredF64>} coinblocksDestroyed
* @property {MetricPattern1<StoredF64>} coindaysDestroyed
* @property {MetricPattern1<Sats>} sent
* @property {_24hPattern<Sats>} sentSum
*/
/**
* Create a CoinblocksCoindaysSentPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {CoinblocksCoindaysSentPattern}
*/
function createCoinblocksCoindaysSentPattern(client, acc) {
return {
coinblocksDestroyed: createMetricPattern1(client, _m(acc, 'coinblocks_destroyed')),
coindaysDestroyed: createMetricPattern1(client, _m(acc, 'coindays_destroyed')),
sent: createMetricPattern1(client, _m(acc, 'sent')),
sentSum: create_24hPattern(client, _m(acc, 'sent_24h')),
};
}
/** /**
* @typedef {Object} InvestedMaxMinPercentilesPattern * @typedef {Object} InvestedMaxMinPercentilesPattern
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} investedCapital * @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} investedCapital
@@ -4762,7 +4791,7 @@ function create_24hPattern(client, acc) {
* @typedef {Object} MetricsTree_Distribution_UtxoCohorts_All * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_All
* @property {ChangeHalvedTotalPattern} supply * @property {ChangeHalvedTotalPattern} supply
* @property {UtxoPattern} outputs * @property {UtxoPattern} outputs
* @property {CoinblocksCoindaysSentPattern} activity * @property {CoinblocksCoindaysSentPattern2} activity
* @property {CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern} realized * @property {CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern} realized
* @property {InvestedMaxMinPercentilesPattern} costBasis * @property {InvestedMaxMinPercentilesPattern} costBasis
* @property {GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern} unrealized * @property {GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern} unrealized
@@ -4799,7 +4828,7 @@ function create_24hPattern(client, acc) {
* @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Sth * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Sth
* @property {ChangeHalvedTotalPattern} supply * @property {ChangeHalvedTotalPattern} supply
* @property {UtxoPattern} outputs * @property {UtxoPattern} outputs
* @property {CoinblocksCoindaysSentPattern} activity * @property {CoinblocksCoindaysSentPattern2} activity
* @property {CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern} realized * @property {CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern} realized
* @property {InvestedMaxMinPercentilesPattern} costBasis * @property {InvestedMaxMinPercentilesPattern} costBasis
* @property {GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern} unrealized * @property {GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern} unrealized
@@ -4818,7 +4847,7 @@ function create_24hPattern(client, acc) {
* @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Lth * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Lth
* @property {ChangeHalvedTotalPattern} supply * @property {ChangeHalvedTotalPattern} supply
* @property {UtxoPattern} outputs * @property {UtxoPattern} outputs
* @property {CoinblocksCoindaysSentPattern} activity * @property {CoinblocksCoindaysSentPattern2} activity
* @property {CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern} realized * @property {CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern} realized
* @property {InvestedMaxMinPercentilesPattern} costBasis * @property {InvestedMaxMinPercentilesPattern} costBasis
* @property {GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern} unrealized * @property {GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern} unrealized
@@ -6982,7 +7011,7 @@ class BrkClient extends BrkClientBase {
all: { all: {
supply: createChangeHalvedTotalPattern(this, 'supply'), supply: createChangeHalvedTotalPattern(this, 'supply'),
outputs: createUtxoPattern(this, 'utxo_count'), outputs: createUtxoPattern(this, 'utxo_count'),
activity: createCoinblocksCoindaysSentPattern(this, ''), activity: createCoinblocksCoindaysSentPattern2(this, ''),
realized: createCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(this, ''), realized: createCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(this, ''),
costBasis: createInvestedMaxMinPercentilesPattern(this, ''), costBasis: createInvestedMaxMinPercentilesPattern(this, ''),
unrealized: createGreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(this, ''), unrealized: createGreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(this, ''),
@@ -7011,7 +7040,7 @@ class BrkClient extends BrkClientBase {
sth: { sth: {
supply: createChangeHalvedTotalPattern(this, 'sth_supply'), supply: createChangeHalvedTotalPattern(this, 'sth_supply'),
outputs: createUtxoPattern(this, 'sth_utxo_count'), outputs: createUtxoPattern(this, 'sth_utxo_count'),
activity: createCoinblocksCoindaysSentPattern(this, 'sth'), activity: createCoinblocksCoindaysSentPattern2(this, 'sth'),
realized: createCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(this, 'sth'), realized: createCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(this, 'sth'),
costBasis: createInvestedMaxMinPercentilesPattern(this, 'sth'), costBasis: createInvestedMaxMinPercentilesPattern(this, 'sth'),
unrealized: createGreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(this, 'sth'), unrealized: createGreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(this, 'sth'),
@@ -7028,7 +7057,7 @@ class BrkClient extends BrkClientBase {
lth: { lth: {
supply: createChangeHalvedTotalPattern(this, 'lth_supply'), supply: createChangeHalvedTotalPattern(this, 'lth_supply'),
outputs: createUtxoPattern(this, 'lth_utxo_count'), outputs: createUtxoPattern(this, 'lth_utxo_count'),
activity: createCoinblocksCoindaysSentPattern(this, 'lth'), activity: createCoinblocksCoindaysSentPattern2(this, 'lth'),
realized: createCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(this, 'lth'), realized: createCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(this, 'lth'),
costBasis: createInvestedMaxMinPercentilesPattern(this, 'lth'), costBasis: createInvestedMaxMinPercentilesPattern(this, 'lth'),
unrealized: createGreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(this, 'lth'), unrealized: createGreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(this, 'lth'),

View File

@@ -2495,6 +2495,20 @@ class _1m1w1y24hBtcCentsSatsUsdPattern:
self.sats: MetricPattern18[Sats] = MetricPattern18(client, acc) self.sats: MetricPattern18[Sats] = MetricPattern18(client, acc)
self.usd: MetricPattern18[Dollars] = MetricPattern18(client, _m(acc, 'usd')) self.usd: MetricPattern18[Dollars] = MetricPattern18(client, _m(acc, 'usd'))
class CoinblocksCoindaysSentPattern2:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.coinblocks_destroyed: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'coinblocks_destroyed'))
self.coinblocks_destroyed_cumulative: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'coinblocks_destroyed_cumulative'))
self.coindays_destroyed: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'coindays_destroyed'))
self.coindays_destroyed_cumulative: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'coindays_destroyed_cumulative'))
self.coindays_destroyed_sum: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, _m(acc, 'coindays_destroyed'))
self.sent: MetricPattern1[Sats] = MetricPattern1(client, _m(acc, 'sent'))
self.sent_sum: _24hPattern[Sats] = _24hPattern(client, _m(acc, 'sent_24h'))
self.sent_sum_extended: _1m1w1yPattern[Sats] = _1m1w1yPattern(client, _m(acc, 'sent'))
class AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern(Generic[T]): class AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern(Generic[T]):
"""Pattern struct for repeated tree structure.""" """Pattern struct for repeated tree structure."""
@@ -2607,17 +2621,6 @@ class BaseBtcCentsSatsUsdPattern:
self.sats: MetricPattern1[Sats] = MetricPattern1(client, _m(acc, 'rewards_cumulative')) self.sats: MetricPattern1[Sats] = MetricPattern1(client, _m(acc, 'rewards_cumulative'))
self.usd: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'rewards_cumulative_usd')) self.usd: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'rewards_cumulative_usd'))
class CoinblocksCoindaysSentPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.coinblocks_destroyed: CumulativeHeightPattern[StoredF64] = CumulativeHeightPattern(client, _m(acc, 'coinblocks_destroyed'))
self.coindays_destroyed: CumulativeHeightSumPattern[StoredF64] = CumulativeHeightSumPattern(client, _m(acc, 'coindays_destroyed'))
self.sent: MetricPattern1[Sats] = MetricPattern1(client, _m(acc, 'sent'))
self.sent_sum: _24hPattern[Sats] = _24hPattern(client, _m(acc, 'sent_24h'))
self.sent_sum_extended: _1m1w1yPattern[Sats] = _1m1w1yPattern(client, _m(acc, 'sent'))
class EmaHistogramLineSignalPattern: class EmaHistogramLineSignalPattern:
"""Pattern struct for repeated tree structure.""" """Pattern struct for repeated tree structure."""
@@ -2690,6 +2693,16 @@ class BtcCentsSatsUsdPattern:
self.sats: MetricPattern1[Sats] = MetricPattern1(client, acc) self.sats: MetricPattern1[Sats] = MetricPattern1(client, acc)
self.usd: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd')) self.usd: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd'))
class CoinblocksCoindaysSentPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.coinblocks_destroyed: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'coinblocks_destroyed'))
self.coindays_destroyed: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'coindays_destroyed'))
self.sent: MetricPattern1[Sats] = MetricPattern1(client, _m(acc, 'sent'))
self.sent_sum: _24hPattern[Sats] = _24hPattern(client, _m(acc, 'sent_24h'))
class InvestedMaxMinPercentilesPattern: class InvestedMaxMinPercentilesPattern:
"""Pattern struct for repeated tree structure.""" """Pattern struct for repeated tree structure."""
@@ -4270,7 +4283,7 @@ class MetricsTree_Distribution_UtxoCohorts_All:
def __init__(self, client: BrkClientBase, base_path: str = ''): def __init__(self, client: BrkClientBase, base_path: str = ''):
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'supply') self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'supply')
self.outputs: UtxoPattern = UtxoPattern(client, 'utxo_count') self.outputs: UtxoPattern = UtxoPattern(client, 'utxo_count')
self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, '') self.activity: CoinblocksCoindaysSentPattern2 = CoinblocksCoindaysSentPattern2(client, '')
self.realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, '') self.realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, '')
self.cost_basis: InvestedMaxMinPercentilesPattern = InvestedMaxMinPercentilesPattern(client, '') self.cost_basis: InvestedMaxMinPercentilesPattern = InvestedMaxMinPercentilesPattern(client, '')
self.unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern = GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(client, '') self.unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern = GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(client, '')
@@ -4285,7 +4298,7 @@ class MetricsTree_Distribution_UtxoCohorts_Sth:
def __init__(self, client: BrkClientBase, base_path: str = ''): def __init__(self, client: BrkClientBase, base_path: str = ''):
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'sth_supply') self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'sth_supply')
self.outputs: UtxoPattern = UtxoPattern(client, 'sth_utxo_count') self.outputs: UtxoPattern = UtxoPattern(client, 'sth_utxo_count')
self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, 'sth') self.activity: CoinblocksCoindaysSentPattern2 = CoinblocksCoindaysSentPattern2(client, 'sth')
self.realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, 'sth') self.realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, 'sth')
self.cost_basis: InvestedMaxMinPercentilesPattern = InvestedMaxMinPercentilesPattern(client, 'sth') self.cost_basis: InvestedMaxMinPercentilesPattern = InvestedMaxMinPercentilesPattern(client, 'sth')
self.unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern = GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(client, 'sth') self.unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern = GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(client, 'sth')
@@ -4305,7 +4318,7 @@ class MetricsTree_Distribution_UtxoCohorts_Lth:
def __init__(self, client: BrkClientBase, base_path: str = ''): def __init__(self, client: BrkClientBase, base_path: str = ''):
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'lth_supply') self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'lth_supply')
self.outputs: UtxoPattern = UtxoPattern(client, 'lth_utxo_count') self.outputs: UtxoPattern = UtxoPattern(client, 'lth_utxo_count')
self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, 'lth') self.activity: CoinblocksCoindaysSentPattern2 = CoinblocksCoindaysSentPattern2(client, 'lth')
self.realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, 'lth') self.realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, 'lth')
self.cost_basis: InvestedMaxMinPercentilesPattern = InvestedMaxMinPercentilesPattern(client, 'lth') self.cost_basis: InvestedMaxMinPercentilesPattern = InvestedMaxMinPercentilesPattern(client, 'lth')
self.unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern = GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(client, 'lth') self.unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern = GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(client, 'lth')