global: snapshot part 4

This commit is contained in:
nym21
2026-03-20 14:27:10 +01:00
parent 1d671ea41f
commit 8f93ff9f68
47 changed files with 683 additions and 637 deletions

View File

@@ -1330,13 +1330,13 @@ impl CapLossMvrvNetPriceProfitSoprPattern {
}
/// Pattern struct for repeated tree structure.
pub struct InInvestedMaxMinPercentilesSupplyPattern {
pub struct InMaxMinPerSupplyPattern {
pub in_loss: PerPattern,
pub in_profit: PerPattern,
pub invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
pub max: CentsSatsUsdPattern,
pub min: CentsSatsUsdPattern,
pub percentiles: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
pub per_coin: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
pub per_dollar: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
pub supply_density: BpsPercentRatioPattern3,
}
@@ -4045,6 +4045,8 @@ impl SeriesTree_Mining_Rewards {
pub struct SeriesTree_Mining_Rewards_Subsidy {
pub base: BtcCentsSatsUsdPattern,
pub cumulative: BtcCentsSatsUsdPattern,
pub sum: _1m1w1y24hPattern3,
pub average: _1m1w1y24hPattern3,
pub dominance: _1m1w1y24hBpsPercentRatioPattern,
pub sma_1y: CentsUsdPattern2,
}
@@ -4054,6 +4056,8 @@ impl SeriesTree_Mining_Rewards_Subsidy {
Self {
base: BtcCentsSatsUsdPattern::new(client.clone(), "subsidy".to_string()),
cumulative: BtcCentsSatsUsdPattern::new(client.clone(), "subsidy_cumulative".to_string()),
sum: _1m1w1y24hPattern3::new(client.clone(), "subsidy_sum".to_string()),
average: _1m1w1y24hPattern3::new(client.clone(), "subsidy_average".to_string()),
dominance: _1m1w1y24hBpsPercentRatioPattern::new(client.clone(), "subsidy_dominance".to_string()),
sma_1y: CentsUsdPattern2::new(client.clone(), "subsidy_sma_1y".to_string()),
}
@@ -6644,8 +6648,8 @@ pub struct SeriesTree_Cohorts_Utxo_All_CostBasis {
pub in_loss: PerPattern,
pub min: CentsSatsUsdPattern,
pub max: CentsSatsUsdPattern,
pub percentiles: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
pub invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
pub per_coin: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
pub per_dollar: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
pub supply_density: BpsPercentRatioPattern3,
}
@@ -6656,8 +6660,8 @@ impl SeriesTree_Cohorts_Utxo_All_CostBasis {
in_loss: PerPattern::new(client.clone(), "cost_basis_in_loss_per".to_string()),
min: CentsSatsUsdPattern::new(client.clone(), "cost_basis_min".to_string()),
max: CentsSatsUsdPattern::new(client.clone(), "cost_basis_max".to_string()),
percentiles: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern::new(client.clone(), "cost_basis".to_string()),
invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern::new(client.clone(), "invested_capital".to_string()),
per_coin: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern::new(client.clone(), "cost_basis_per_coin".to_string()),
per_dollar: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern::new(client.clone(), "cost_basis_per_dollar".to_string()),
supply_density: BpsPercentRatioPattern3::new(client.clone(), "supply_density".to_string()),
}
}
@@ -7114,8 +7118,8 @@ pub struct SeriesTree_Cohorts_Utxo_Sth_CostBasis {
pub in_loss: PerPattern,
pub min: CentsSatsUsdPattern,
pub max: CentsSatsUsdPattern,
pub percentiles: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
pub invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
pub per_coin: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
pub per_dollar: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
pub supply_density: BpsPercentRatioPattern3,
}
@@ -7126,8 +7130,8 @@ impl SeriesTree_Cohorts_Utxo_Sth_CostBasis {
in_loss: PerPattern::new(client.clone(), "sth_cost_basis_in_loss_per".to_string()),
min: CentsSatsUsdPattern::new(client.clone(), "sth_cost_basis_min".to_string()),
max: CentsSatsUsdPattern::new(client.clone(), "sth_cost_basis_max".to_string()),
percentiles: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern::new(client.clone(), "sth_cost_basis".to_string()),
invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern::new(client.clone(), "sth_invested_capital".to_string()),
per_coin: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern::new(client.clone(), "sth_cost_basis_per_coin".to_string()),
per_dollar: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern::new(client.clone(), "sth_cost_basis_per_dollar".to_string()),
supply_density: BpsPercentRatioPattern3::new(client.clone(), "sth_supply_density".to_string()),
}
}
@@ -7508,8 +7512,8 @@ pub struct SeriesTree_Cohorts_Utxo_Lth_CostBasis {
pub in_loss: PerPattern,
pub min: CentsSatsUsdPattern,
pub max: CentsSatsUsdPattern,
pub percentiles: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
pub invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
pub per_coin: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
pub per_dollar: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern,
pub supply_density: BpsPercentRatioPattern3,
}
@@ -7520,8 +7524,8 @@ impl SeriesTree_Cohorts_Utxo_Lth_CostBasis {
in_loss: PerPattern::new(client.clone(), "lth_cost_basis_in_loss_per".to_string()),
min: CentsSatsUsdPattern::new(client.clone(), "lth_cost_basis_min".to_string()),
max: CentsSatsUsdPattern::new(client.clone(), "lth_cost_basis_max".to_string()),
percentiles: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern::new(client.clone(), "lth_cost_basis".to_string()),
invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern::new(client.clone(), "lth_invested_capital".to_string()),
per_coin: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern::new(client.clone(), "lth_cost_basis_per_coin".to_string()),
per_dollar: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern::new(client.clone(), "lth_cost_basis_per_dollar".to_string()),
supply_density: BpsPercentRatioPattern3::new(client.clone(), "lth_supply_density".to_string()),
}
}

View File

@@ -7,7 +7,7 @@ use crate::{
indexes,
internal::{
BlockCountTarget24h, BlockCountTarget1w, BlockCountTarget1m, BlockCountTarget1y,
CachedWindowStarts, PerBlockCumulativeWithSums, ConstantVecs, Windows,
CachedWindowStarts, PerBlockCumulativeRolling, ConstantVecs, Windows,
},
};
@@ -25,7 +25,7 @@ impl Vecs {
_1m: ConstantVecs::new::<BlockCountTarget1m>("block_count_target_1m", version, indexes),
_1y: ConstantVecs::new::<BlockCountTarget1y>("block_count_target_1y", version, indexes),
},
total: PerBlockCumulativeWithSums::forced_import(
total: PerBlockCumulativeRolling::forced_import(
db,
"block_count",
version + Version::ONE,

View File

@@ -2,10 +2,10 @@ use brk_traversable::Traversable;
use brk_types::{StoredU32, StoredU64};
use vecdb::{Rw, StorageMode};
use crate::internal::{PerBlockCumulativeWithSums, ConstantVecs, Windows};
use crate::internal::{PerBlockCumulativeRolling, ConstantVecs, Windows};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub target: Windows<ConstantVecs<StoredU64>>,
pub total: PerBlockCumulativeWithSums<StoredU32, StoredU64, M>,
pub total: PerBlockCumulativeRolling<StoredU32, StoredU64, M>,
}

View File

@@ -6,7 +6,7 @@ use super::Vecs;
use crate::{
indexes,
internal::{
CachedWindowStarts, LazyPerBlock, OneMinusF64, PerBlock, PerBlockCumulativeWithSums,
CachedWindowStarts, LazyPerBlock, OneMinusF64, PerBlock, PerBlockCumulativeRolling,
},
};
@@ -27,10 +27,10 @@ impl Vecs {
);
Ok(Self {
coinblocks_created: PerBlockCumulativeWithSums::forced_import(
coinblocks_created: PerBlockCumulativeRolling::forced_import(
db, "coinblocks_created", version, indexes, cached_starts,
)?,
coinblocks_stored: PerBlockCumulativeWithSums::forced_import(
coinblocks_stored: PerBlockCumulativeRolling::forced_import(
db, "coinblocks_stored", version, indexes, cached_starts,
)?,
liveliness,

View File

@@ -2,12 +2,12 @@ use brk_traversable::Traversable;
use brk_types::StoredF64;
use vecdb::{Rw, StorageMode};
use crate::internal::{LazyPerBlock, PerBlock, PerBlockCumulativeWithSums};
use crate::internal::{LazyPerBlock, PerBlock, PerBlockCumulativeRolling};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub coinblocks_created: PerBlockCumulativeWithSums<StoredF64, StoredF64, M>,
pub coinblocks_stored: PerBlockCumulativeWithSums<StoredF64, StoredF64, M>,
pub coinblocks_created: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub coinblocks_stored: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub liveliness: PerBlock<StoredF64, M>,
pub vaultedness: LazyPerBlock<StoredF64>,
pub ratio: PerBlock<StoredF64, M>,

View File

@@ -5,7 +5,7 @@ use vecdb::Database;
use super::Vecs;
use crate::{
indexes,
internal::{CachedWindowStarts, PerBlockCumulativeWithSums},
internal::{CachedWindowStarts, PerBlockCumulativeRolling},
};
impl Vecs {
@@ -16,28 +16,28 @@ impl Vecs {
cached_starts: &CachedWindowStarts,
) -> Result<Self> {
Ok(Self {
destroyed: PerBlockCumulativeWithSums::forced_import(
destroyed: PerBlockCumulativeRolling::forced_import(
db,
"cointime_value_destroyed",
version,
indexes,
cached_starts,
)?,
created: PerBlockCumulativeWithSums::forced_import(
created: PerBlockCumulativeRolling::forced_import(
db,
"cointime_value_created",
version,
indexes,
cached_starts,
)?,
stored: PerBlockCumulativeWithSums::forced_import(
stored: PerBlockCumulativeRolling::forced_import(
db,
"cointime_value_stored",
version,
indexes,
cached_starts,
)?,
vocdd: PerBlockCumulativeWithSums::forced_import(
vocdd: PerBlockCumulativeRolling::forced_import(
db,
"vocdd",
version + Version::ONE,

View File

@@ -2,12 +2,12 @@ use brk_traversable::Traversable;
use brk_types::StoredF64;
use vecdb::{Rw, StorageMode};
use crate::internal::PerBlockCumulativeWithSums;
use crate::internal::PerBlockCumulativeRolling;
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub destroyed: PerBlockCumulativeWithSums<StoredF64, StoredF64, M>,
pub created: PerBlockCumulativeWithSums<StoredF64, StoredF64, M>,
pub stored: PerBlockCumulativeWithSums<StoredF64, StoredF64, M>,
pub vocdd: PerBlockCumulativeWithSums<StoredF64, StoredF64, M>,
pub destroyed: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub created: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub stored: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub vocdd: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
}

View File

@@ -6,7 +6,7 @@ use vecdb::{Database, Exit, Rw, StorageMode};
use crate::{
indexes,
internal::{CachedWindowStarts, PerBlockCumulativeWithSums},
internal::{CachedWindowStarts, PerBlockCumulativeRolling},
};
use super::TotalAddrCountVecs;
@@ -14,9 +14,9 @@ use super::TotalAddrCountVecs;
/// New address count per block (global + per-type)
#[derive(Traversable)]
pub struct NewAddrCountVecs<M: StorageMode = Rw> {
pub all: PerBlockCumulativeWithSums<StoredU64, StoredU64, M>,
pub all: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
#[traversable(flatten)]
pub by_addr_type: ByAddrType<PerBlockCumulativeWithSums<StoredU64, StoredU64, M>>,
pub by_addr_type: ByAddrType<PerBlockCumulativeRolling<StoredU64, StoredU64, M>>,
}
impl NewAddrCountVecs {
@@ -26,7 +26,7 @@ impl NewAddrCountVecs {
indexes: &indexes::Vecs,
cached_starts: &CachedWindowStarts,
) -> Result<Self> {
let all = PerBlockCumulativeWithSums::forced_import(
let all = PerBlockCumulativeRolling::forced_import(
db,
"new_addr_count",
version,
@@ -35,7 +35,7 @@ impl NewAddrCountVecs {
)?;
let by_addr_type = ByAddrType::new_with_name(|name| {
PerBlockCumulativeWithSums::forced_import(
PerBlockCumulativeRolling::forced_import(
db,
&format!("{name}_new_addr_count"),
version,

View File

@@ -25,7 +25,7 @@ use crate::{
state::UTXOCohortState,
},
indexes,
internal::{AmountPerBlockCumulativeWithSums, CachedWindowStarts},
internal::{AmountPerBlockCumulativeRolling, CachedWindowStarts},
prices,
};
@@ -50,7 +50,7 @@ pub struct UTXOCohorts<M: StorageMode = Rw> {
#[traversable(rename = "type")]
pub type_: SpendableType<UTXOCohortVecs<TypeCohortMetrics<M>>>,
pub profitability: ProfitabilityMetrics<M>,
pub matured: AgeRange<AmountPerBlockCumulativeWithSums<M>>,
pub matured: AgeRange<AmountPerBlockCumulativeRolling<M>>,
#[traversable(skip)]
pub(super) fenwick: CostBasisFenwick,
/// Cached partition_point positions for tick_tock boundary searches.
@@ -259,8 +259,8 @@ impl UTXOCohorts<Rw> {
let prefix = CohortContext::Utxo.prefix();
let matured = AgeRange::try_new(&|_f: Filter,
name: &'static str|
-> Result<AmountPerBlockCumulativeWithSums> {
AmountPerBlockCumulativeWithSums::forced_import(
-> Result<AmountPerBlockCumulativeRolling> {
AmountPerBlockCumulativeRolling::forced_import(
db,
&format!("{prefix}_{name}_matured_supply"),
v,
@@ -713,10 +713,11 @@ impl UTXOCohorts<Rw> {
}
vecs.extend(self.profitability.collect_all_vecs_mut());
for v in self.matured.iter_mut() {
vecs.push(&mut v.base.sats.height);
vecs.push(&mut v.base.cents.height);
vecs.push(&mut v.cumulative.sats.height);
vecs.push(&mut v.cumulative.cents.height);
let inner = &mut v.inner;
vecs.push(&mut inner.base.sats.height);
vecs.push(&mut inner.base.cents.height);
vecs.push(&mut inner.cumulative.sats.height);
vecs.push(&mut inner.cumulative.cents.height);
}
vecs.into_par_iter()
}

View File

@@ -6,7 +6,7 @@ use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
use crate::{
distribution::{metrics::ImportConfig, state::{CohortState, CostBasisOps, RealizedOps}},
internal::{AmountPerBlockCumulativeWithSums, PerBlockCumulativeWithSums},
internal::{AmountPerBlockCumulativeRolling, PerBlockCumulativeRolling},
prices,
};
@@ -19,11 +19,11 @@ pub struct ActivityCore<M: StorageMode = Rw> {
#[traversable(flatten)]
pub minimal: ActivityMinimal<M>,
pub coindays_destroyed: PerBlockCumulativeWithSums<StoredF64, StoredF64, M>,
pub coindays_destroyed: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
#[traversable(wrap = "transfer_volume", rename = "in_profit")]
pub transfer_volume_in_profit: AmountPerBlockCumulativeWithSums<M>,
pub transfer_volume_in_profit: AmountPerBlockCumulativeRolling<M>,
#[traversable(wrap = "transfer_volume", rename = "in_loss")]
pub transfer_volume_in_loss: AmountPerBlockCumulativeWithSums<M>,
pub transfer_volume_in_loss: AmountPerBlockCumulativeRolling<M>,
}
impl ActivityCore {
@@ -69,10 +69,10 @@ impl ActivityCore {
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
let mut vecs = self.minimal.collect_vecs_mut();
vecs.push(&mut self.coindays_destroyed.base.height);
vecs.push(&mut self.transfer_volume_in_profit.base.sats.height);
vecs.push(&mut self.transfer_volume_in_profit.base.cents.height);
vecs.push(&mut self.transfer_volume_in_loss.base.sats.height);
vecs.push(&mut self.transfer_volume_in_loss.base.cents.height);
vecs.push(&mut self.transfer_volume_in_profit.inner.base.sats.height);
vecs.push(&mut self.transfer_volume_in_profit.inner.base.cents.height);
vecs.push(&mut self.transfer_volume_in_loss.inner.base.sats.height);
vecs.push(&mut self.transfer_volume_in_loss.inner.base.cents.height);
vecs
}

View File

@@ -5,13 +5,13 @@ use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
use crate::{
distribution::{metrics::ImportConfig, state::{CohortState, CostBasisOps, RealizedOps}},
internal::AmountPerBlockCumulativeWithSums,
internal::AmountPerBlockCumulativeRolling,
prices,
};
#[derive(Traversable)]
pub struct ActivityMinimal<M: StorageMode = Rw> {
pub transfer_volume: AmountPerBlockCumulativeWithSums<M>,
pub transfer_volume: AmountPerBlockCumulativeRolling<M>,
}
impl ActivityMinimal {
@@ -39,9 +39,10 @@ impl ActivityMinimal {
}
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
let inner = &mut self.transfer_volume.inner;
vec![
&mut self.transfer_volume.base.sats.height as &mut dyn AnyStoredVec,
&mut self.transfer_volume.base.cents.height,
&mut inner.base.sats.height as &mut dyn AnyStoredVec,
&mut inner.base.cents.height,
]
}

View File

@@ -7,9 +7,9 @@ use vecdb::{BytesVec, BytesVecValue, Database, ImportableVec};
use crate::{
indexes,
internal::{
AmountPerBlock, AmountPerBlockCumulative, AmountPerBlockCumulativeWithSums,
AmountPerBlock, AmountPerBlockCumulative, AmountPerBlockCumulativeRolling,
CachedWindowStarts, CentsType, FiatPerBlock, FiatPerBlockCumulativeWithSums, NumericValue,
PerBlock, PerBlockCumulativeWithSums, PercentPerBlock, PercentRollingWindows, Price,
PerBlock, PerBlockCumulativeRolling, PercentPerBlock, PercentRollingWindows, Price,
PriceWithRatioExtendedPerBlock, PriceWithRatioPerBlock, RatioPerBlock,
RollingWindow24hPerBlock, RollingWindows, RollingWindowsFrom1w,
},
@@ -54,7 +54,7 @@ impl<T: NumericValue + JsonSchema> ConfigImport for PerBlock<T> {
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
}
}
impl<T, C> ConfigImport for PerBlockCumulativeWithSums<T, C>
impl<T, C> ConfigImport for PerBlockCumulativeRolling<T, C>
where
T: NumericValue + JsonSchema + Into<C>,
C: NumericValue + JsonSchema,
@@ -79,7 +79,7 @@ impl<T: NumericValue + JsonSchema> ConfigImport for RollingWindow24hPerBlock<T>
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
}
}
impl ConfigImport for AmountPerBlockCumulativeWithSums {
impl ConfigImport for AmountPerBlockCumulativeRolling {
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
Self::forced_import(
cfg.db,

View File

@@ -24,8 +24,8 @@ pub struct CostBasis<M: StorageMode = Rw> {
pub in_loss: CostBasisSide<M>,
pub min: Price<PerBlock<Cents, M>>,
pub max: Price<PerBlock<Cents, M>>,
pub percentiles: PercentilesVecs<M>,
pub invested_capital: PercentilesVecs<M>,
pub per_coin: PercentilesVecs<M>,
pub per_dollar: PercentilesVecs<M>,
pub supply_density: PercentPerBlock<BasisPoints16, M>,
}
@@ -42,15 +42,15 @@ impl CostBasis {
},
min: cfg.import("cost_basis_min", Version::ZERO)?,
max: cfg.import("cost_basis_max", Version::ZERO)?,
percentiles: PercentilesVecs::forced_import(
per_coin: PercentilesVecs::forced_import(
cfg.db,
&cfg.name("cost_basis"),
&cfg.name("cost_basis_per_coin"),
cfg.version,
cfg.indexes,
)?,
invested_capital: PercentilesVecs::forced_import(
per_dollar: PercentilesVecs::forced_import(
cfg.db,
&cfg.name("invested_capital"),
&cfg.name("cost_basis_per_dollar"),
cfg.version,
cfg.indexes,
)?,
@@ -84,8 +84,8 @@ impl CostBasis {
sat_prices: &[Cents; PERCENTILES_LEN],
usd_prices: &[Cents; PERCENTILES_LEN],
) {
self.percentiles.push(sat_prices);
self.invested_capital.push(usd_prices);
self.per_coin.push(sat_prices);
self.per_dollar.push(usd_prices);
}
#[inline(always)]
@@ -94,9 +94,9 @@ impl CostBasis {
}
pub(crate) fn validate_computed_versions(&mut self, base_version: Version) -> Result<()> {
self.percentiles
self.per_coin
.validate_computed_version_or_reset(base_version)?;
self.invested_capital
self.per_dollar
.validate_computed_version_or_reset(base_version)?;
Ok(())
}
@@ -112,13 +112,13 @@ impl CostBasis {
&mut self.supply_density.bps.height,
];
vecs.extend(
self.percentiles
self.per_coin
.vecs
.iter_mut()
.map(|v| &mut v.cents.height as &mut dyn AnyStoredVec),
);
vecs.extend(
self.invested_capital
self.per_dollar
.vecs
.iter_mut()
.map(|v| &mut v.cents.height as &mut dyn AnyStoredVec),

View File

@@ -5,14 +5,14 @@ use vecdb::{Exit, ReadableVec, Rw, StorageMode};
use crate::{
distribution::metrics::ImportConfig,
internal::{PerBlockCumulativeWithSums, RatioCents64, RollingWindows},
internal::{PerBlockCumulativeRolling, RatioCents64, RollingWindows},
};
#[derive(Traversable)]
pub struct AdjustedSopr<M: StorageMode = Rw> {
pub ratio: RollingWindows<StoredF64, M>,
pub transfer_volume: PerBlockCumulativeWithSums<Cents, Cents, M>,
pub value_destroyed: PerBlockCumulativeWithSums<Cents, Cents, M>,
pub transfer_volume: PerBlockCumulativeRolling<Cents, Cents, M>,
pub value_destroyed: PerBlockCumulativeRolling<Cents, Cents, M>,
}
impl AdjustedSopr {

View File

@@ -10,7 +10,7 @@ use crate::{
distribution::state::{CohortState, CostBasisOps, RealizedOps},
internal::{
FiatPerBlockCumulativeWithSumsAndDeltas, LazyPerBlock, NegCentsUnsignedToDollars,
PerBlockCumulativeWithSums, RatioCents64, RollingWindow24hPerBlock, Windows,
PerBlockCumulativeRolling, RatioCents64, RollingWindow24hPerBlock, Windows,
},
prices,
};
@@ -28,7 +28,7 @@ pub struct NegRealizedLoss {
#[derive(Traversable)]
pub struct RealizedSoprCore<M: StorageMode = Rw> {
pub value_destroyed: PerBlockCumulativeWithSums<Cents, Cents, M>,
pub value_destroyed: PerBlockCumulativeRolling<Cents, Cents, M>,
pub ratio: RollingWindow24hPerBlock<StoredF64, M>,
}
@@ -81,7 +81,7 @@ impl RealizedCore {
cfg.cached_starts,
)?;
let value_destroyed = PerBlockCumulativeWithSums::forced_import(
let value_destroyed = PerBlockCumulativeRolling::forced_import(
cfg.db,
&cfg.name("value_destroyed"),
cfg.version + v1,

View File

@@ -11,7 +11,7 @@ use crate::{
blocks,
distribution::state::{CohortState, CostBasisData, RealizedState, WithCapital},
internal::{
AmountPerBlockCumulativeWithSums, FiatPerBlockCumulativeWithSums, PercentPerBlock,
AmountPerBlockCumulativeRolling, FiatPerBlockCumulativeWithSums, PercentPerBlock,
PercentRollingWindows, PriceWithRatioExtendedPerBlock, RatioCents64, RatioCentsBp32,
RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32, RatioDollarsBp32,
RatioPerBlockPercentiles, RatioPerBlockStdDevBands, RatioSma, RollingWindows,
@@ -274,7 +274,7 @@ impl RealizedFull {
starting_indexes: &Indexes,
height_to_supply: &impl ReadableVec<Height, Bitcoin>,
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
activity_transfer_volume: &AmountPerBlockCumulativeWithSums,
activity_transfer_volume: &AmountPerBlockCumulativeRolling,
exit: &Exit,
) -> Result<()> {
self.core.compute_rest_part2(

View File

@@ -23,7 +23,7 @@ use crate::{
state::BlockState,
},
indexes, inputs,
internal::{CachedWindowStarts, PerBlockCumulativeWithSums, db_utils::{finalize_db, open_db}},
internal::{CachedWindowStarts, PerBlockCumulativeRolling, db_utils::{finalize_db, open_db}},
outputs, prices, transactions,
};
@@ -70,7 +70,7 @@ pub struct Vecs<M: StorageMode = Rw> {
#[traversable(wrap = "cohorts", rename = "addr")]
pub addr_cohorts: AddrCohorts<M>,
#[traversable(wrap = "cointime/activity")]
pub coinblocks_destroyed: PerBlockCumulativeWithSums<StoredF64, StoredF64, M>,
pub coinblocks_destroyed: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
pub addrs: AddrMetricsVecs<M>,
/// In-memory block state for UTXO processing. Persisted via supply_state.
@@ -173,7 +173,7 @@ impl Vecs {
utxo_cohorts,
addr_cohorts,
coinblocks_destroyed: PerBlockCumulativeWithSums::forced_import(
coinblocks_destroyed: PerBlockCumulativeRolling::forced_import(
&db,
"coinblocks_destroyed",
version + Version::TWO,

View File

@@ -1,28 +1,31 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Height, Sats, Version};
use brk_types::{Height, Sats, Version};
use derive_more::{Deref, DerefMut};
use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
use crate::{
indexes,
internal::{
AmountPerBlock, CachedWindowStarts, LazyRollingAvgsAmountFromHeight,
LazyRollingSumsAmountFromHeight, SatsToCents,
AmountPerBlockCumulative, CachedWindowStarts, LazyRollingAvgsAmountFromHeight,
LazyRollingSumsAmountFromHeight,
},
prices,
};
#[derive(Traversable)]
pub struct AmountPerBlockCumulativeWithSums<M: StorageMode = Rw> {
pub base: AmountPerBlock<M>,
pub cumulative: AmountPerBlock<M>,
#[derive(Deref, DerefMut, Traversable)]
pub struct AmountPerBlockCumulativeRolling<M: StorageMode = Rw> {
#[deref]
#[deref_mut]
#[traversable(flatten)]
pub inner: AmountPerBlockCumulative<M>,
pub sum: LazyRollingSumsAmountFromHeight,
pub average: LazyRollingAvgsAmountFromHeight,
}
const VERSION: Version = Version::TWO;
impl AmountPerBlockCumulativeWithSums {
impl AmountPerBlockCumulativeRolling {
pub(crate) fn forced_import(
db: &Database,
name: &str,
@@ -32,29 +35,26 @@ impl AmountPerBlockCumulativeWithSums {
) -> Result<Self> {
let v = version + VERSION;
let base = AmountPerBlock::forced_import(db, name, v, indexes)?;
let cumulative =
AmountPerBlock::forced_import(db, &format!("{name}_cumulative"), v, indexes)?;
let inner = AmountPerBlockCumulative::forced_import(db, name, v, indexes)?;
let sum = LazyRollingSumsAmountFromHeight::new(
&format!("{name}_sum"),
v,
&cumulative.sats.height,
&cumulative.cents.height,
&inner.cumulative.sats.height,
&inner.cumulative.cents.height,
cached_starts,
indexes,
);
let average = LazyRollingAvgsAmountFromHeight::new(
&format!("{name}_average"),
v,
&cumulative.sats.height,
&cumulative.cents.height,
&inner.cumulative.sats.height,
&inner.cumulative.cents.height,
cached_starts,
indexes,
);
Ok(Self {
base,
cumulative,
inner,
sum,
average,
})
@@ -77,26 +77,6 @@ impl AmountPerBlockCumulativeWithSums {
prices: &prices::Vecs,
exit: &Exit,
) -> Result<()> {
self.cumulative
.sats
.height
.compute_cumulative(max_from, &self.base.sats.height, exit)?;
self.base
.cents
.height
.compute_binary::<Sats, Cents, SatsToCents>(
max_from,
&self.base.sats.height,
&prices.spot.cents.height,
exit,
)?;
self.cumulative
.cents
.height
.compute_cumulative(max_from, &self.base.cents.height, exit)?;
Ok(())
self.inner.compute(prices, max_from, exit)
}
}

View File

@@ -1,24 +1,24 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Height, Sats, Version};
use brk_types::{Height, Sats, Version};
use derive_more::{Deref, DerefMut};
use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
use crate::{
indexes,
internal::{
AmountPerBlock, CachedWindowStarts, LazyRollingAvgsAmountFromHeight,
LazyRollingSumsAmountFromHeight, RollingDistributionAmountPerBlock, SatsToCents,
AmountPerBlockCumulativeRolling, CachedWindowStarts, RollingDistributionAmountPerBlock,
WindowStarts,
},
prices,
};
#[derive(Traversable)]
#[derive(Deref, DerefMut, Traversable)]
pub struct AmountPerBlockFull<M: StorageMode = Rw> {
pub base: AmountPerBlock<M>,
pub cumulative: AmountPerBlock<M>,
pub sum: LazyRollingSumsAmountFromHeight,
pub average: LazyRollingAvgsAmountFromHeight,
#[deref]
#[deref_mut]
#[traversable(flatten)]
pub inner: AmountPerBlockCumulativeRolling<M>,
#[traversable(flatten)]
pub distribution: RollingDistributionAmountPerBlock<M>,
}
@@ -35,33 +35,14 @@ impl AmountPerBlockFull {
) -> Result<Self> {
let v = version + VERSION;
let base = AmountPerBlock::forced_import(db, name, v, indexes)?;
let cumulative =
AmountPerBlock::forced_import(db, &format!("{name}_cumulative"), v, indexes)?;
let sum = LazyRollingSumsAmountFromHeight::new(
&format!("{name}_sum"),
v,
&cumulative.sats.height,
&cumulative.cents.height,
cached_starts,
indexes,
);
let average = LazyRollingAvgsAmountFromHeight::new(
&format!("{name}_average"),
v,
&cumulative.sats.height,
&cumulative.cents.height,
cached_starts,
indexes,
);
let rolling = RollingDistributionAmountPerBlock::forced_import(db, name, v, indexes)?;
let inner =
AmountPerBlockCumulativeRolling::forced_import(db, name, v, indexes, cached_starts)?;
let distribution =
RollingDistributionAmountPerBlock::forced_import(db, name, v, indexes)?;
Ok(Self {
base,
cumulative,
sum,
average,
distribution: rolling,
inner,
distribution,
})
}
@@ -73,33 +54,15 @@ impl AmountPerBlockFull {
exit: &Exit,
compute_sats: impl FnOnce(&mut EagerVec<PcoVec<Height, Sats>>) -> Result<()>,
) -> Result<()> {
compute_sats(&mut self.base.sats.height)?;
compute_sats(&mut self.inner.base.sats.height)?;
self.cumulative
.sats
.height
.compute_cumulative(max_from, &self.base.sats.height, exit)?;
self.base
.cents
.height
.compute_binary::<Sats, Cents, SatsToCents>(
max_from,
&self.base.sats.height,
&prices.spot.cents.height,
exit,
)?;
self.cumulative
.cents
.height
.compute_cumulative(max_from, &self.base.cents.height, exit)?;
self.inner.compute_rest(max_from, prices, exit)?;
self.distribution.compute(
max_from,
windows,
&self.base.sats.height,
&self.base.cents.height,
&self.inner.base.sats.height,
&self.inner.base.cents.height,
exit,
)?;

View File

@@ -1,6 +1,6 @@
mod base;
mod cumulative;
mod cumulative_sum;
mod cumulative_rolling;
mod full;
mod lazy;
mod lazy_derived_resolutions;
@@ -11,7 +11,7 @@ mod with_deltas;
pub use base::*;
pub use cumulative::*;
pub use cumulative_sum::*;
pub use cumulative_rolling::*;
pub use full::*;
pub use lazy::*;
pub use lazy_derived_resolutions::*;

View File

@@ -1,4 +1,4 @@
//! PerBlockCumulativeWithSums - base PerBlock + cumulative PerBlock + lazy rolling sums.
//! PerBlockCumulativeRolling - base PerBlock + cumulative PerBlock + lazy rolling sums.
//!
//! Rolling sums are derived lazily from the cumulative vec via LazyDeltaVec.
//! No rolling sum vecs are stored on disk.
@@ -24,7 +24,7 @@ use crate::{
};
#[derive(Traversable)]
pub struct PerBlockCumulativeWithSums<T, C, M: StorageMode = Rw>
pub struct PerBlockCumulativeRolling<T, C, M: StorageMode = Rw>
where
T: NumericValue + JsonSchema,
C: NumericValue + JsonSchema,
@@ -35,7 +35,7 @@ where
pub average: LazyRollingAvgsFromHeight<C>,
}
impl<T, C> PerBlockCumulativeWithSums<T, C>
impl<T, C> PerBlockCumulativeRolling<T, C>
where
T: NumericValue + JsonSchema + Into<C>,
C: NumericValue + JsonSchema,

View File

@@ -1,6 +1,6 @@
mod aggregated;
mod base;
mod cumulative_sum;
mod cumulative_rolling;
mod distribution;
mod full;
mod lazy_distribution;
@@ -12,7 +12,7 @@ mod with_deltas;
pub use aggregated::*;
pub use base::*;
pub use cumulative_sum::*;
pub use cumulative_rolling::*;
pub use distribution::*;
pub use full::*;
pub use lazy_distribution::*;

View File

@@ -6,7 +6,7 @@ use super::Vecs;
use crate::{
indexes,
internal::{
AmountPerBlockCumulative, AmountPerBlockCumulativeWithSums, AmountPerBlockFull,
AmountPerBlockCumulative, AmountPerBlockCumulativeRolling, AmountPerBlockFull,
CachedWindowStarts, FiatPerBlock, LazyPercentRollingWindows, OneMinusBp16,
PercentPerBlock, PercentRollingWindows, RatioRollingWindows,
},
@@ -33,10 +33,10 @@ impl Vecs {
);
Ok(Self {
coinbase: AmountPerBlockCumulativeWithSums::forced_import(
coinbase: AmountPerBlockCumulativeRolling::forced_import(
db, "coinbase", version, indexes, cached_starts,
)?,
subsidy: AmountPerBlockCumulativeWithSums::forced_import(
subsidy: AmountPerBlockCumulativeRolling::forced_import(
db, "subsidy", version, indexes, cached_starts,
)?,
fees: AmountPerBlockFull::forced_import(db, "fees", version, indexes, cached_starts)?,

View File

@@ -3,15 +3,15 @@ use brk_types::{BasisPoints16, BasisPoints32, Cents};
use vecdb::{Rw, StorageMode};
use crate::internal::{
AmountPerBlockCumulative, AmountPerBlockCumulativeWithSums, AmountPerBlockFull,
AmountPerBlockCumulative, AmountPerBlockCumulativeRolling, AmountPerBlockFull,
FiatPerBlock, LazyPercentRollingWindows, PercentPerBlock, PercentRollingWindows,
RatioRollingWindows,
};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub coinbase: AmountPerBlockCumulativeWithSums<M>,
pub subsidy: AmountPerBlockCumulativeWithSums<M>,
pub coinbase: AmountPerBlockCumulativeRolling<M>,
pub subsidy: AmountPerBlockCumulativeRolling<M>,
pub fees: AmountPerBlockFull<M>,
pub unclaimed: AmountPerBlockCumulative<M>,
#[traversable(wrap = "fees", rename = "dominance")]

View File

@@ -7,7 +7,7 @@ use vecdb::{BinaryTransform, Database, Exit, ReadableVec, Rw, StorageMode, Versi
use crate::{
blocks, indexes,
internal::{
AmountPerBlockCumulativeWithSums, CachedWindowStarts, MaskSats, PercentRollingWindows,
AmountPerBlockCumulativeRolling, CachedWindowStarts, MaskSats, PercentRollingWindows,
RatioU64Bp16,
},
mining, prices,
@@ -22,7 +22,7 @@ pub struct Vecs<M: StorageMode = Rw> {
#[traversable(flatten)]
pub base: minor::Vecs<M>,
pub rewards: AmountPerBlockCumulativeWithSums<M>,
pub rewards: AmountPerBlockCumulativeRolling<M>,
#[traversable(rename = "dominance")]
pub dominance_rolling: PercentRollingWindows<BasisPoints16, M>,
}
@@ -39,7 +39,7 @@ impl Vecs {
let base = minor::Vecs::forced_import(db, slug, version, indexes, cached_starts)?;
let rewards = AmountPerBlockCumulativeWithSums::forced_import(
let rewards = AmountPerBlockCumulativeRolling::forced_import(
db,
&suffix("rewards"),
version,

View File

@@ -8,7 +8,7 @@ use vecdb::{
use crate::{
blocks, indexes,
internal::{
CachedWindowStarts, PerBlockCumulativeWithSums, PercentPerBlock, RatioU64Bp16,
CachedWindowStarts, PerBlockCumulativeRolling, PercentPerBlock, RatioU64Bp16,
},
};
@@ -17,7 +17,7 @@ pub struct Vecs<M: StorageMode = Rw> {
#[traversable(skip)]
slug: PoolSlug,
pub blocks_mined: PerBlockCumulativeWithSums<StoredU32, StoredU64, M>,
pub blocks_mined: PerBlockCumulativeRolling<StoredU32, StoredU64, M>,
pub dominance: PercentPerBlock<BasisPoints16, M>,
}
@@ -31,7 +31,7 @@ impl Vecs {
) -> Result<Self> {
let suffix = |s: &str| format!("{}_{s}", slug);
let blocks_mined = PerBlockCumulativeWithSums::forced_import(
let blocks_mined = PerBlockCumulativeRolling::forced_import(
db,
&suffix("blocks_mined"),
version + Version::ONE,

View File

@@ -5,7 +5,7 @@ use vecdb::Database;
use super::Vecs;
use crate::{
indexes,
internal::{CachedWindowStarts, PerBlockCumulativeWithSums},
internal::{CachedWindowStarts, PerBlockCumulativeRolling},
};
impl Vecs {
@@ -16,23 +16,23 @@ impl Vecs {
cached_starts: &CachedWindowStarts,
) -> Result<Self> {
let p2a =
PerBlockCumulativeWithSums::forced_import(db, "p2a_count", version, indexes, cached_starts)?;
PerBlockCumulativeRolling::forced_import(db, "p2a_count", version, indexes, cached_starts)?;
let p2ms =
PerBlockCumulativeWithSums::forced_import(db, "p2ms_count", version, indexes, cached_starts)?;
PerBlockCumulativeRolling::forced_import(db, "p2ms_count", version, indexes, cached_starts)?;
let p2pk33 =
PerBlockCumulativeWithSums::forced_import(db, "p2pk33_count", version, indexes, cached_starts)?;
PerBlockCumulativeRolling::forced_import(db, "p2pk33_count", version, indexes, cached_starts)?;
let p2pk65 =
PerBlockCumulativeWithSums::forced_import(db, "p2pk65_count", version, indexes, cached_starts)?;
PerBlockCumulativeRolling::forced_import(db, "p2pk65_count", version, indexes, cached_starts)?;
let p2pkh =
PerBlockCumulativeWithSums::forced_import(db, "p2pkh_count", version, indexes, cached_starts)?;
PerBlockCumulativeRolling::forced_import(db, "p2pkh_count", version, indexes, cached_starts)?;
let p2sh =
PerBlockCumulativeWithSums::forced_import(db, "p2sh_count", version, indexes, cached_starts)?;
PerBlockCumulativeRolling::forced_import(db, "p2sh_count", version, indexes, cached_starts)?;
let p2tr =
PerBlockCumulativeWithSums::forced_import(db, "p2tr_count", version, indexes, cached_starts)?;
PerBlockCumulativeRolling::forced_import(db, "p2tr_count", version, indexes, cached_starts)?;
let p2wpkh =
PerBlockCumulativeWithSums::forced_import(db, "p2wpkh_count", version, indexes, cached_starts)?;
PerBlockCumulativeRolling::forced_import(db, "p2wpkh_count", version, indexes, cached_starts)?;
let p2wsh =
PerBlockCumulativeWithSums::forced_import(db, "p2wsh_count", version, indexes, cached_starts)?;
PerBlockCumulativeRolling::forced_import(db, "p2wsh_count", version, indexes, cached_starts)?;
Ok(Self {
p2a,
p2ms,
@@ -43,21 +43,21 @@ impl Vecs {
p2tr,
p2wpkh,
p2wsh,
op_return: PerBlockCumulativeWithSums::forced_import(
op_return: PerBlockCumulativeRolling::forced_import(
db,
"op_return_count",
version,
indexes,
cached_starts,
)?,
empty_output: PerBlockCumulativeWithSums::forced_import(
empty_output: PerBlockCumulativeRolling::forced_import(
db,
"empty_output_count",
version,
indexes,
cached_starts,
)?,
unknown_output: PerBlockCumulativeWithSums::forced_import(
unknown_output: PerBlockCumulativeRolling::forced_import(
db,
"unknown_output_count",
version,

View File

@@ -2,20 +2,20 @@ use brk_traversable::Traversable;
use brk_types::StoredU64;
use vecdb::{Rw, StorageMode};
use crate::internal::PerBlockCumulativeWithSums;
use crate::internal::PerBlockCumulativeRolling;
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub p2a: PerBlockCumulativeWithSums<StoredU64, StoredU64, M>,
pub p2ms: PerBlockCumulativeWithSums<StoredU64, StoredU64, M>,
pub p2pk33: PerBlockCumulativeWithSums<StoredU64, StoredU64, M>,
pub p2pk65: PerBlockCumulativeWithSums<StoredU64, StoredU64, M>,
pub p2pkh: PerBlockCumulativeWithSums<StoredU64, StoredU64, M>,
pub p2sh: PerBlockCumulativeWithSums<StoredU64, StoredU64, M>,
pub p2tr: PerBlockCumulativeWithSums<StoredU64, StoredU64, M>,
pub p2wpkh: PerBlockCumulativeWithSums<StoredU64, StoredU64, M>,
pub p2wsh: PerBlockCumulativeWithSums<StoredU64, StoredU64, M>,
pub op_return: PerBlockCumulativeWithSums<StoredU64, StoredU64, M>,
pub empty_output: PerBlockCumulativeWithSums<StoredU64, StoredU64, M>,
pub unknown_output: PerBlockCumulativeWithSums<StoredU64, StoredU64, M>,
pub p2a: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub p2ms: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub p2pk33: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub p2pk65: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub p2pkh: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub p2sh: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub p2tr: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub p2wpkh: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub p2wsh: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub op_return: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub empty_output: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub unknown_output: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
}

View File

@@ -3,7 +3,7 @@ use brk_types::Version;
use vecdb::Database;
use super::Vecs;
use crate::{indexes, internal::{AmountPerBlockCumulativeWithSums, CachedWindowStarts}};
use crate::{indexes, internal::{AmountPerBlockCumulativeRolling, CachedWindowStarts}};
impl Vecs {
pub(crate) fn forced_import(
@@ -13,7 +13,7 @@ impl Vecs {
cached_starts: &CachedWindowStarts,
) -> Result<Self> {
Ok(Self {
op_return: AmountPerBlockCumulativeWithSums::forced_import(
op_return: AmountPerBlockCumulativeRolling::forced_import(
db,
"op_return_value",
version,

View File

@@ -1,9 +1,9 @@
use brk_traversable::Traversable;
use vecdb::{Rw, StorageMode};
use crate::internal::AmountPerBlockCumulativeWithSums;
use crate::internal::AmountPerBlockCumulativeRolling;
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub op_return: AmountPerBlockCumulativeWithSums<M>,
pub op_return: AmountPerBlockCumulativeRolling<M>,
}

View File

@@ -3,7 +3,7 @@ use brk_types::Version;
use vecdb::Database;
use super::Vecs;
use crate::{indexes, internal::{AmountPerBlockCumulativeWithSums, CachedWindowStarts}};
use crate::{indexes, internal::{AmountPerBlockCumulativeRolling, CachedWindowStarts}};
impl Vecs {
pub(crate) fn forced_import(
@@ -13,7 +13,7 @@ impl Vecs {
cached_starts: &CachedWindowStarts,
) -> Result<Self> {
Ok(Self {
total: AmountPerBlockCumulativeWithSums::forced_import(
total: AmountPerBlockCumulativeRolling::forced_import(
db,
"unspendable_supply",
version,

View File

@@ -1,10 +1,10 @@
use brk_traversable::Traversable;
use vecdb::{Rw, StorageMode};
use crate::internal::AmountPerBlockCumulativeWithSums;
use crate::internal::AmountPerBlockCumulativeRolling;
#[derive(Traversable)]
#[traversable(transparent)]
pub struct Vecs<M: StorageMode = Rw> {
pub total: AmountPerBlockCumulativeWithSums<M>,
pub total: AmountPerBlockCumulativeRolling<M>,
}

View File

@@ -5,7 +5,7 @@ use vecdb::Database;
use super::Vecs;
use crate::{
indexes,
internal::{CachedWindowStarts, PerBlockCumulativeWithSums},
internal::{CachedWindowStarts, PerBlockCumulativeRolling},
};
impl Vecs {
@@ -16,9 +16,9 @@ impl Vecs {
cached_starts: &CachedWindowStarts,
) -> Result<Self> {
Ok(Self {
v1: PerBlockCumulativeWithSums::forced_import(db, "tx_v1", version, indexes, cached_starts)?,
v2: PerBlockCumulativeWithSums::forced_import(db, "tx_v2", version, indexes, cached_starts)?,
v3: PerBlockCumulativeWithSums::forced_import(db, "tx_v3", version, indexes, cached_starts)?,
v1: PerBlockCumulativeRolling::forced_import(db, "tx_v1", version, indexes, cached_starts)?,
v2: PerBlockCumulativeRolling::forced_import(db, "tx_v2", version, indexes, cached_starts)?,
v3: PerBlockCumulativeRolling::forced_import(db, "tx_v3", version, indexes, cached_starts)?,
})
}
}

View File

@@ -2,11 +2,11 @@ use brk_traversable::Traversable;
use brk_types::StoredU64;
use vecdb::{Rw, StorageMode};
use crate::internal::PerBlockCumulativeWithSums;
use crate::internal::PerBlockCumulativeRolling;
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub v1: PerBlockCumulativeWithSums<StoredU64, StoredU64, M>,
pub v2: PerBlockCumulativeWithSums<StoredU64, StoredU64, M>,
pub v3: PerBlockCumulativeWithSums<StoredU64, StoredU64, M>,
pub v1: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub v2: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
pub v3: PerBlockCumulativeRolling<StoredU64, StoredU64, M>,
}

View File

@@ -5,7 +5,7 @@ use vecdb::Database;
use super::Vecs;
use crate::{
indexes,
internal::{AmountPerBlockCumulativeWithSums, CachedWindowStarts, PerBlock, Windows},
internal::{AmountPerBlockCumulativeRolling, CachedWindowStarts, PerBlock, Windows},
};
impl Vecs {
@@ -17,7 +17,7 @@ impl Vecs {
) -> Result<Self> {
let v = version + Version::TWO;
Ok(Self {
transfer_volume: AmountPerBlockCumulativeWithSums::forced_import(
transfer_volume: AmountPerBlockCumulativeRolling::forced_import(
db,
"transfer_volume_bis",
version,

View File

@@ -2,11 +2,11 @@ use brk_traversable::Traversable;
use brk_types::StoredF32;
use vecdb::{Rw, StorageMode};
use crate::internal::{AmountPerBlockCumulativeWithSums, PerBlock, Windows};
use crate::internal::{AmountPerBlockCumulativeRolling, PerBlock, Windows};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub transfer_volume: AmountPerBlockCumulativeWithSums<M>,
pub transfer_volume: AmountPerBlockCumulativeRolling<M>,
pub tx_per_sec: Windows<PerBlock<StoredF32, M>>,
pub outputs_per_sec: Windows<PerBlock<StoredF32, M>>,
pub inputs_per_sec: Windows<PerBlock<StoredF32, M>>,

View File

@@ -2067,13 +2067,13 @@ function createCapLossMvrvNetPriceProfitSoprPattern(client, acc) {
}
/**
* @typedef {Object} InInvestedMaxMinPercentilesSupplyPattern
* @typedef {Object} InMaxMinPerSupplyPattern
* @property {PerPattern} inLoss
* @property {PerPattern} inProfit
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} investedCapital
* @property {CentsSatsUsdPattern} max
* @property {CentsSatsUsdPattern} min
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} percentiles
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} perCoin
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} perDollar
* @property {BpsPercentRatioPattern3} supplyDensity
*/
@@ -4413,6 +4413,8 @@ function createUnspentPattern(client, acc) {
* @typedef {Object} SeriesTree_Mining_Rewards_Subsidy
* @property {BtcCentsSatsUsdPattern} base
* @property {BtcCentsSatsUsdPattern} cumulative
* @property {_1m1w1y24hPattern3} sum
* @property {_1m1w1y24hPattern3} average
* @property {_1m1w1y24hBpsPercentRatioPattern} dominance
* @property {CentsUsdPattern2} sma1y
*/
@@ -5556,8 +5558,8 @@ function createUnspentPattern(client, acc) {
* @property {PerPattern} inLoss
* @property {CentsSatsUsdPattern} min
* @property {CentsSatsUsdPattern} max
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} percentiles
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} investedCapital
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} perCoin
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} perDollar
* @property {BpsPercentRatioPattern3} supplyDensity
*/
@@ -5764,8 +5766,8 @@ function createUnspentPattern(client, acc) {
* @property {PerPattern} inLoss
* @property {CentsSatsUsdPattern} min
* @property {CentsSatsUsdPattern} max
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} percentiles
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} investedCapital
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} perCoin
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} perDollar
* @property {BpsPercentRatioPattern3} supplyDensity
*/
@@ -5940,8 +5942,8 @@ function createUnspentPattern(client, acc) {
* @property {PerPattern} inLoss
* @property {CentsSatsUsdPattern} min
* @property {CentsSatsUsdPattern} max
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} percentiles
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} investedCapital
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} perCoin
* @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} perDollar
* @property {BpsPercentRatioPattern3} supplyDensity
*/
@@ -7786,6 +7788,8 @@ class BrkClient extends BrkClientBase {
subsidy: {
base: createBtcCentsSatsUsdPattern(this, 'subsidy'),
cumulative: createBtcCentsSatsUsdPattern(this, 'subsidy_cumulative'),
sum: create_1m1w1y24hPattern3(this, 'subsidy_sum'),
average: create_1m1w1y24hPattern3(this, 'subsidy_average'),
dominance: create_1m1w1y24hBpsPercentRatioPattern(this, 'subsidy_dominance'),
sma1y: createCentsUsdPattern2(this, 'subsidy_sma_1y'),
},
@@ -8611,8 +8615,8 @@ class BrkClient extends BrkClientBase {
inLoss: createPerPattern(this, 'cost_basis_in_loss_per'),
min: createCentsSatsUsdPattern(this, 'cost_basis_min'),
max: createCentsSatsUsdPattern(this, 'cost_basis_max'),
percentiles: createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(this, 'cost_basis'),
investedCapital: createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(this, 'invested_capital'),
perCoin: createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(this, 'cost_basis_per_coin'),
perDollar: createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(this, 'cost_basis_per_dollar'),
supplyDensity: createBpsPercentRatioPattern3(this, 'supply_density'),
},
unrealized: {
@@ -8766,8 +8770,8 @@ class BrkClient extends BrkClientBase {
inLoss: createPerPattern(this, 'sth_cost_basis_in_loss_per'),
min: createCentsSatsUsdPattern(this, 'sth_cost_basis_min'),
max: createCentsSatsUsdPattern(this, 'sth_cost_basis_max'),
percentiles: createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(this, 'sth_cost_basis'),
investedCapital: createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(this, 'sth_invested_capital'),
perCoin: createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(this, 'sth_cost_basis_per_coin'),
perDollar: createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(this, 'sth_cost_basis_per_dollar'),
supplyDensity: createBpsPercentRatioPattern3(this, 'sth_supply_density'),
},
unrealized: {
@@ -8901,8 +8905,8 @@ class BrkClient extends BrkClientBase {
inLoss: createPerPattern(this, 'lth_cost_basis_in_loss_per'),
min: createCentsSatsUsdPattern(this, 'lth_cost_basis_min'),
max: createCentsSatsUsdPattern(this, 'lth_cost_basis_max'),
percentiles: createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(this, 'lth_cost_basis'),
investedCapital: createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(this, 'lth_invested_capital'),
perCoin: createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(this, 'lth_cost_basis_per_coin'),
perDollar: createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(this, 'lth_cost_basis_per_dollar'),
supplyDensity: createBpsPercentRatioPattern3(this, 'lth_supply_density'),
},
unrealized: {

View File

@@ -2339,7 +2339,7 @@ class CapLossMvrvNetPriceProfitSoprPattern:
self.profit: BaseCumulativeSumPattern = BaseCumulativeSumPattern(client, _m(acc, 'realized_profit'))
self.sopr: RatioValuePattern = RatioValuePattern(client, acc)
class InInvestedMaxMinPercentilesSupplyPattern:
class InMaxMinPerSupplyPattern:
"""Pattern struct for repeated tree structure."""
pass
@@ -3639,6 +3639,8 @@ class SeriesTree_Mining_Rewards_Subsidy:
def __init__(self, client: BrkClientBase, base_path: str = ''):
self.base: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, 'subsidy')
self.cumulative: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, 'subsidy_cumulative')
self.sum: _1m1w1y24hPattern3 = _1m1w1y24hPattern3(client, 'subsidy_sum')
self.average: _1m1w1y24hPattern3 = _1m1w1y24hPattern3(client, 'subsidy_average')
self.dominance: _1m1w1y24hBpsPercentRatioPattern = _1m1w1y24hBpsPercentRatioPattern(client, 'subsidy_dominance')
self.sma_1y: CentsUsdPattern2 = CentsUsdPattern2(client, 'subsidy_sma_1y')
@@ -4866,8 +4868,8 @@ class SeriesTree_Cohorts_Utxo_All_CostBasis:
self.in_loss: PerPattern = PerPattern(client, 'cost_basis_in_loss_per')
self.min: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'cost_basis_min')
self.max: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'cost_basis_max')
self.percentiles: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern = Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, 'cost_basis')
self.invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern = Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, 'invested_capital')
self.per_coin: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern = Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, 'cost_basis_per_coin')
self.per_dollar: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern = Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, 'cost_basis_per_dollar')
self.supply_density: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'supply_density')
class SeriesTree_Cohorts_Utxo_All_Unrealized_Profit:
@@ -5092,8 +5094,8 @@ class SeriesTree_Cohorts_Utxo_Sth_CostBasis:
self.in_loss: PerPattern = PerPattern(client, 'sth_cost_basis_in_loss_per')
self.min: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'sth_cost_basis_min')
self.max: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'sth_cost_basis_max')
self.percentiles: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern = Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, 'sth_cost_basis')
self.invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern = Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, 'sth_invested_capital')
self.per_coin: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern = Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, 'sth_cost_basis_per_coin')
self.per_dollar: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern = Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, 'sth_cost_basis_per_dollar')
self.supply_density: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'sth_supply_density')
class SeriesTree_Cohorts_Utxo_Sth_Unrealized_Sentiment:
@@ -5282,8 +5284,8 @@ class SeriesTree_Cohorts_Utxo_Lth_CostBasis:
self.in_loss: PerPattern = PerPattern(client, 'lth_cost_basis_in_loss_per')
self.min: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'lth_cost_basis_min')
self.max: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'lth_cost_basis_max')
self.percentiles: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern = Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, 'lth_cost_basis')
self.invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern = Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, 'lth_invested_capital')
self.per_coin: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern = Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, 'lth_cost_basis_per_coin')
self.per_dollar: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern = Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, 'lth_cost_basis_per_dollar')
self.supply_density: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'lth_supply_density')
class SeriesTree_Cohorts_Utxo_Lth_Unrealized_Sentiment:

View File

@@ -5,9 +5,9 @@ import {
dots,
line,
price,
sumsArray,
multiSeriesTree,
percentRatioDots,
sumsAndAveragesCumulative,
} from "./series.js";
import { satsBtcUsd, priceRatioPercentilesTree } from "./shared.js";
@@ -277,50 +277,27 @@ export function createCointimeSection() {
{
name: "Coinblocks",
tree: [
{
name: "Compare",
tree: multiSeriesTree({
entries: coinblocks.map(({ pattern, name, color }) => ({
name,
color,
base: pattern.base,
average: pattern.average,
rolling: pattern.sum,
cumulative: pattern.cumulative,
})),
title: "Coinblocks",
unit: Unit.coinblocks,
}),
},
...multiSeriesTree({
entries: coinblocks.map(({ pattern, name, color }) => ({
name,
color,
average: pattern.average,
sum: pattern.sum,
cumulative: pattern.cumulative,
})),
title: "Coinblocks",
unit: Unit.coinblocks,
}),
...coinblocks.map(({ pattern, name, title, color }) => ({
name,
tree: [
{
name: "Per Block",
title,
bottom: [
line({
series: pattern.base,
name,
color,
unit: Unit.coinblocks,
}),
],
},
...sumsArray({ windows: pattern.sum, title, unit: Unit.coinblocks }),
{
name: "Cumulative",
title: `${title} (Total)`,
bottom: [
line({
series: pattern.cumulative,
name,
color,
unit: Unit.coinblocks,
}),
],
},
],
tree: sumsAndAveragesCumulative({
sum: pattern.sum,
average: pattern.average,
cumulative: pattern.cumulative,
title,
unit: Unit.coinblocks,
color,
}),
})),
],
},
@@ -328,95 +305,47 @@ export function createCointimeSection() {
{
name: "Value",
tree: [
{
name: "Compare",
tree: multiSeriesTree({
entries: [
...cointimeValues.map(({ pattern, name, color }) => ({
name,
color,
base: pattern.base,
average: pattern.average,
rolling: pattern.sum,
cumulative: pattern.cumulative,
})),
{
name: vocdd.name,
color: vocdd.color,
base: vocdd.pattern.base,
average: vocdd.pattern.average,
rolling: vocdd.pattern.sum,
cumulative: vocdd.pattern.cumulative,
},
],
title: "Cointime Value",
unit: Unit.usd,
}),
},
...cointimeValues.map(({ pattern, name, title, color }) => ({
name,
tree: [
...multiSeriesTree({
entries: [
...cointimeValues.map(({ pattern, name, color }) => ({
name,
color,
average: pattern.average,
sum: pattern.sum,
cumulative: pattern.cumulative,
})),
{
name: "Per Block",
title,
bottom: [
line({ series: pattern.base, name, color, unit: Unit.usd }),
],
},
...sumsArray({ windows: pattern.sum, title, unit: Unit.usd }),
{
name: "Cumulative",
title: `${title} (Total)`,
bottom: [
line({
series: pattern.cumulative,
name,
color,
unit: Unit.usd,
}),
],
name: vocdd.name,
color: vocdd.color,
average: vocdd.pattern.average,
sum: vocdd.pattern.sum,
cumulative: vocdd.pattern.cumulative,
},
],
title: "Cointime Value",
unit: Unit.usd,
}),
...cointimeValues.map(({ pattern, name, title, color }) => ({
name,
tree: sumsAndAveragesCumulative({
sum: pattern.sum,
average: pattern.average,
cumulative: pattern.cumulative,
title,
unit: Unit.usd,
color,
}),
})),
{
name: vocdd.name,
tree: [
{
name: "Per Block",
title: vocdd.title,
bottom: [
line({
series: vocdd.pattern.base,
name: vocdd.name,
color: vocdd.color,
unit: Unit.usd,
}),
line({
series: reserveRisk.vocddMedian1y,
name: "365d Median",
color: colors.time._1y,
unit: Unit.usd,
}),
],
},
...sumsArray({
windows: vocdd.pattern.sum,
title: vocdd.title,
unit: Unit.usd,
}),
{
name: "Cumulative",
title: `${vocdd.title} (Total)`,
bottom: [
line({
series: vocdd.pattern.cumulative,
name: vocdd.name,
color: vocdd.color,
unit: Unit.usd,
}),
],
},
],
tree: sumsAndAveragesCumulative({
sum: vocdd.pattern.sum,
average: vocdd.pattern.average,
cumulative: vocdd.pattern.cumulative,
title: vocdd.title,
unit: Unit.usd,
color: vocdd.color,
}),
},
],
},

View File

@@ -9,7 +9,15 @@
*/
import { Unit } from "../../utils/units.js";
import { line, baseline, dotsBaseline, percentRatio, chartsFromCount, averagesTree, ROLLING_WINDOWS } from "../series.js";
import {
line,
baseline,
dotsBaseline,
percentRatio,
chartsFromCount,
averagesArray,
ROLLING_WINDOWS,
} from "../series.js";
import {
satsBtcUsdFullTree,
mapCohortsWithAll,
@@ -33,7 +41,6 @@ function volumeAndCoinsTree(activity, color, title) {
name: "Volume",
tree: satsBtcUsdFullTree({
pattern: activity.transferVolume,
name: "Volume",
title: title("Sent Volume"),
color,
}),
@@ -62,7 +69,6 @@ function sentProfitLossTree(sent, title) {
name: "Sent In Profit",
tree: satsBtcUsdFullTree({
pattern: sent.inProfit,
name: "In Profit",
title: title("Sent Volume In Profit"),
color: colors.profit,
}),
@@ -71,7 +77,6 @@ function sentProfitLossTree(sent, title) {
name: "Sent In Loss",
tree: satsBtcUsdFullTree({
pattern: sent.inLoss,
name: "In Loss",
title: title("Sent Volume In Loss"),
color: colors.loss,
}),
@@ -90,7 +95,14 @@ function fullVolumeTree(activity, color, title) {
return [
...volumeAndCoinsTree(activity, color, title),
...sentProfitLossTree(activity.transferVolume, title),
averagesTree({ windows: activity.dormancy, title: title("Dormancy"), unit: Unit.days, name: "Dormancy" }),
{
name: "Dormancy",
tree: averagesArray({
windows: activity.dormancy,
title: title("Dormancy"),
unit: Unit.days,
}),
},
];
}
@@ -110,13 +122,26 @@ function singleRollingSoprTree(ratio, title, prefix = "") {
name: "Compare",
title: title(`${prefix}SOPR`),
bottom: ROLLING_WINDOWS.map((w) =>
baseline({ series: ratio[w.key], name: w.name, color: w.color, unit: Unit.ratio, base: 1 }),
baseline({
series: ratio[w.key],
name: w.name,
color: w.color,
unit: Unit.ratio,
base: 1,
}),
),
},
...ROLLING_WINDOWS.map((w) => ({
name: w.name,
title: title(`${prefix}SOPR (${w.title})`),
bottom: [baseline({ series: ratio[w.key], name: "SOPR", unit: Unit.ratio, base: 1 })],
bottom: [
baseline({
series: ratio[w.key],
name: "SOPR",
unit: Unit.ratio,
base: 1,
}),
],
})),
];
}
@@ -136,7 +161,11 @@ function singleSellSideRiskTree(sellSideRisk, title) {
name: "Compare",
title: title("Sell Side Risk"),
bottom: ROLLING_WINDOWS.flatMap((w) =>
percentRatio({ pattern: sellSideRisk[w.key], name: w.name, color: w.color }),
percentRatio({
pattern: sellSideRisk[w.key],
name: w.name,
color: w.color,
}),
),
},
...ROLLING_WINDOWS.map((w) => ({
@@ -171,11 +200,18 @@ export function createActivitySectionWithAdjusted({ cohort, title }) {
...singleRollingSoprTree(sopr.ratio, title),
{
name: "Adjusted",
tree: singleRollingSoprTree(sopr.adjusted.ratio, title, "Adjusted "),
tree: singleRollingSoprTree(
sopr.adjusted.ratio,
title,
"Adjusted ",
),
},
],
},
{ name: "Sell Side Risk", tree: singleSellSideRiskTree(r.sellSideRiskRatio, title) },
{
name: "Sell Side Risk",
tree: singleSellSideRiskTree(r.sellSideRiskRatio, title),
},
],
};
}
@@ -198,7 +234,10 @@ export function createActivitySection({ cohort, title }) {
name: "SOPR",
tree: singleRollingSoprTree(sopr.ratio, title),
},
{ name: "Sell Side Risk", tree: singleSellSideRiskTree(r.sellSideRiskRatio, title) },
{
name: "Sell Side Risk",
tree: singleSellSideRiskTree(r.sellSideRiskRatio, title),
},
],
};
}
@@ -220,13 +259,19 @@ export function createActivitySectionWithActivity({ cohort, title }) {
{
name: "SOPR",
title: title("SOPR (24h)"),
bottom: [dotsBaseline({ series: sopr.ratio._24h, name: "SOPR", unit: Unit.ratio, base: 1 })],
bottom: [
dotsBaseline({
series: sopr.ratio._24h,
name: "SOPR",
unit: Unit.ratio,
base: 1,
}),
],
},
],
};
}
/**
* Minimal activity section: volume only
* @param {{ cohort: CohortBasicWithMarketCap | CohortBasicWithoutMarketCap | CohortWithoutRelative | CohortAddr | AddrCohortObject, title: (name: string) => string }} args
@@ -237,7 +282,6 @@ export function createActivitySectionMinimal({ cohort, title }) {
name: "Activity",
tree: satsBtcUsdFullTree({
pattern: cohort.tree.activity.transferVolume,
name: "Volume",
title: title("Volume"),
}),
};
@@ -255,7 +299,12 @@ export function createGroupedActivitySectionMinimal({ list, all, title }) {
name: w.name,
title: title(`Volume (${w.title})`),
bottom: mapCohortsWithAll(list, all, ({ name, color, tree }) =>
line({ series: tree.activity.transferVolume.sum[w.key].sats, name, color, unit: Unit.sats }),
line({
series: tree.activity.transferVolume.sum[w.key].sats,
name,
color,
unit: Unit.sats,
}),
),
})),
};
@@ -280,7 +329,13 @@ function groupedSoprCharts(list, all, getRatio, title, prefix = "") {
name: w.name,
title: title(`${prefix}SOPR (${w.title})`),
bottom: mapCohortsWithAll(list, all, (c) =>
baseline({ series: getRatio(c)[w.key], name: c.name, color: c.color, unit: Unit.ratio, base: 1 }),
baseline({
series: getRatio(c)[w.key],
name: c.name,
color: c.color,
unit: Unit.ratio,
base: 1,
}),
),
}));
}
@@ -300,7 +355,6 @@ function groupedSoprCharts(list, all, getRatio, title, prefix = "") {
* @returns {PartialOptionsTree}
*/
// ============================================================================
// Grouped Activity Sections
// ============================================================================
@@ -317,16 +371,32 @@ export function createGroupedActivitySectionWithAdjusted({ list, all, title }) {
name: "Volume",
title: title("Sent Volume"),
bottom: flatMapCohortsWithAll(list, all, ({ name, color, tree }) => [
line({ series: tree.activity.transferVolume.sum._24h.sats, name, color, unit: Unit.sats }),
line({
series: tree.activity.transferVolume.sum._24h.sats,
name,
color,
unit: Unit.sats,
}),
]),
},
{
name: "SOPR",
tree: [
...groupedSoprCharts(list, all, (c) => c.tree.realized.sopr.ratio, title),
...groupedSoprCharts(
list,
all,
(c) => c.tree.realized.sopr.ratio,
title,
),
{
name: "Adjusted",
tree: groupedSoprCharts(list, all, (c) => c.tree.realized.sopr.adjusted.ratio, title, "Adjusted "),
tree: groupedSoprCharts(
list,
all,
(c) => c.tree.realized.sopr.adjusted.ratio,
title,
"Adjusted ",
),
},
],
},
@@ -336,7 +406,12 @@ export function createGroupedActivitySectionWithAdjusted({ list, all, title }) {
name: w.name,
title: title(`Sell Side Risk (${w.title})`),
bottom: mapCohortsWithAll(list, all, ({ name, color, tree }) =>
line({ series: tree.realized.sellSideRiskRatio[w.key].ratio, name, color, unit: Unit.ratio }),
line({
series: tree.realized.sellSideRiskRatio[w.key].ratio,
name,
color,
unit: Unit.ratio,
}),
),
})),
},
@@ -344,7 +419,12 @@ export function createGroupedActivitySectionWithAdjusted({ list, all, title }) {
name: "Coindays Destroyed",
title: title("Coindays Destroyed"),
bottom: flatMapCohortsWithAll(list, all, ({ name, color, tree }) => [
line({ series: tree.activity.coindaysDestroyed.sum._24h, name, color, unit: Unit.coindays }),
line({
series: tree.activity.coindaysDestroyed.sum._24h,
name,
color,
unit: Unit.coindays,
}),
]),
},
],
@@ -364,13 +444,23 @@ export function createGroupedActivitySection({ list, all, title }) {
name: "Volume",
title: title("Sent Volume"),
bottom: flatMapCohortsWithAll(list, all, ({ name, color, tree }) => [
line({ series: tree.activity.transferVolume.sum._24h.sats, name, color, unit: Unit.sats }),
line({
series: tree.activity.transferVolume.sum._24h.sats,
name,
color,
unit: Unit.sats,
}),
]),
},
{
name: "SOPR",
tree: [
...groupedSoprCharts(list, all, (c) => c.tree.realized.sopr.ratio, title),
...groupedSoprCharts(
list,
all,
(c) => c.tree.realized.sopr.ratio,
title,
),
],
},
{
@@ -379,7 +469,12 @@ export function createGroupedActivitySection({ list, all, title }) {
name: w.name,
title: title(`Sell Side Risk (${w.title})`),
bottom: mapCohortsWithAll(list, all, ({ name, color, tree }) =>
line({ series: tree.realized.sellSideRiskRatio[w.key].ratio, name, color, unit: Unit.ratio }),
line({
series: tree.realized.sellSideRiskRatio[w.key].ratio,
name,
color,
unit: Unit.ratio,
}),
),
})),
},
@@ -387,7 +482,12 @@ export function createGroupedActivitySection({ list, all, title }) {
name: "Coindays Destroyed",
title: title("Coindays Destroyed"),
bottom: flatMapCohortsWithAll(list, all, ({ name, color, tree }) => [
line({ series: tree.activity.coindaysDestroyed.sum._24h, name, color, unit: Unit.coindays }),
line({
series: tree.activity.coindaysDestroyed.sum._24h,
name,
color,
unit: Unit.coindays,
}),
]),
},
],
@@ -407,24 +507,39 @@ export function createGroupedActivitySectionWithActivity({ list, all, title }) {
name: "Volume",
title: title("Sent Volume"),
bottom: flatMapCohortsWithAll(list, all, ({ name, color, tree }) => [
line({ series: tree.activity.transferVolume.sum._24h.sats, name, color, unit: Unit.sats }),
line({
series: tree.activity.transferVolume.sum._24h.sats,
name,
color,
unit: Unit.sats,
}),
]),
},
{
name: "SOPR",
title: title("SOPR (24h)"),
bottom: mapCohortsWithAll(list, all, ({ name, color, tree }) =>
baseline({ series: tree.realized.sopr.ratio._24h, name, color, unit: Unit.ratio, base: 1 }),
baseline({
series: tree.realized.sopr.ratio._24h,
name,
color,
unit: Unit.ratio,
base: 1,
}),
),
},
{
name: "Coindays Destroyed",
title: title("Coindays Destroyed"),
bottom: flatMapCohortsWithAll(list, all, ({ name, color, tree }) => [
line({ series: tree.activity.coindaysDestroyed.sum._24h, name, color, unit: Unit.coindays }),
line({
series: tree.activity.coindaysDestroyed.sum._24h,
name,
color,
unit: Unit.coindays,
}),
]),
},
],
};
}

View File

@@ -93,7 +93,7 @@ export function createCostBasisSectionWithPercentiles({ cohort, title }) {
tree: singleWeightFolder({
avgPrice: tree.realized.price, avgName: "Average",
inProfit: cb.inProfit.perCoin, inLoss: cb.inLoss.perCoin,
percentiles: cb.percentiles, color, weightLabel: "BTC-weighted", title,
percentiles: cb.perCoin, color, weightLabel: "BTC-weighted", title,
min: cb.min, max: cb.max,
}),
},
@@ -102,7 +102,7 @@ export function createCostBasisSectionWithPercentiles({ cohort, title }) {
tree: singleWeightFolder({
avgPrice: tree.realized.investor.price, avgName: "Average",
inProfit: cb.inProfit.perDollar, inLoss: cb.inLoss.perDollar,
percentiles: cb.investedCapital, color, weightLabel: "USD-weighted", title,
percentiles: cb.perDollar, color, weightLabel: "USD-weighted", title,
}),
},
{
@@ -215,7 +215,7 @@ export function createGroupedCostBasisSectionWithPercentiles({ list, all, title
getAvgPrice: (c) => c.tree.realized.price,
getInProfit: (c) => c.tree.costBasis.inProfit.perCoin,
getInLoss: (c) => c.tree.costBasis.inLoss.perCoin,
getPercentiles: (c) => c.tree.costBasis.percentiles,
getPercentiles: (c) => c.tree.costBasis.perCoin,
avgTitle: "Average", weightLabel: "BTC-weighted",
}),
},
@@ -226,7 +226,7 @@ export function createGroupedCostBasisSectionWithPercentiles({ list, all, title
getAvgPrice: (c) => c.tree.realized.investor.price,
getInProfit: (c) => c.tree.costBasis.inProfit.perDollar,
getInLoss: (c) => c.tree.costBasis.inLoss.perDollar,
getPercentiles: (c) => c.tree.costBasis.investedCapital,
getPercentiles: (c) => c.tree.costBasis.perDollar,
avgTitle: "Average", weightLabel: "USD-weighted",
}),
},

View File

@@ -10,8 +10,19 @@
* - activity.js: SOPR, Volume, Lifespan
*/
import { formatCohortTitle, satsBtcUsd, satsBtcUsdFullTree } from "../shared.js";
import { ROLLING_WINDOWS, line, baseline, percentRatio, sumsTree, rollingPercentRatioTree } from "../series.js";
import {
formatCohortTitle,
satsBtcUsd,
satsBtcUsdFullTree,
} from "../shared.js";
import {
ROLLING_WINDOWS,
line,
baseline,
percentRatio,
sumsTree,
rollingPercentRatioTree,
} from "../series.js";
import { Unit } from "../../utils/units.js";
import { colors } from "../../utils/colors.js";
@@ -210,7 +221,6 @@ export function createCohortFolderAgeRangeWithMatured(cohort) {
name: "Matured",
tree: satsBtcUsdFullTree({
pattern: cohort.matured,
name: cohort.name,
title: title("Matured Supply"),
}),
});
@@ -452,13 +462,22 @@ export function createGroupedCohortFolderAgeRangeWithMatured({
list,
all,
}) {
const folder = createGroupedCohortFolderAgeRange({ name, title: groupTitle, list, all });
const folder = createGroupedCohortFolderAgeRange({
name,
title: groupTitle,
list,
all,
});
const title = formatCohortTitle(groupTitle);
folder.tree.push({
name: "Matured",
title: title("Matured Supply"),
bottom: list.flatMap((cohort) =>
satsBtcUsd({ pattern: cohort.matured.base, name: cohort.name, color: cohort.color }),
satsBtcUsd({
pattern: cohort.matured.base,
name: cohort.name,
color: cohort.color,
}),
),
});
return folder;
@@ -607,14 +626,32 @@ function singleBucketFolder({ name, color, pattern }) {
title: `${name}: Supply`,
bottom: [
...satsBtcUsd({ pattern: pattern.supply.all, name: "Total" }),
...satsBtcUsd({ pattern: pattern.supply.sth, name: "STH", color: colors.term.short }),
...satsBtcUsd({
pattern: pattern.supply.sth,
name: "STH",
color: colors.term.short,
}),
],
},
{
name: "Change",
tree: [
{ ...sumsTree({ windows: pattern.supply.all.delta.absolute, title: `${name}: Supply Change`, unit: Unit.sats, series: baseline }), name: "Absolute" },
{ ...rollingPercentRatioTree({ windows: pattern.supply.all.delta.rate, title: `${name}: Supply Rate` }), name: "Rate" },
{
...sumsTree({
windows: pattern.supply.all.delta.absolute,
title: `${name}: Supply Change`,
unit: Unit.sats,
series: baseline,
}),
name: "Absolute",
},
{
...rollingPercentRatioTree({
windows: pattern.supply.all.delta.rate,
title: `${name}: Supply Rate`,
}),
name: "Rate",
},
],
},
],
@@ -623,14 +660,25 @@ function singleBucketFolder({ name, color, pattern }) {
name: "Realized Cap",
title: `${name}: Realized Cap`,
bottom: [
line({ series: pattern.realizedCap.all, name: "Total", unit: Unit.usd }),
line({ series: pattern.realizedCap.sth, name: "STH", color: colors.term.short, unit: Unit.usd }),
line({
series: pattern.realizedCap.all,
name: "Total",
unit: Unit.usd,
}),
line({
series: pattern.realizedCap.sth,
name: "STH",
color: colors.term.short,
unit: Unit.usd,
}),
],
},
{
name: "NUPL",
title: `${name}: NUPL`,
bottom: [line({ series: pattern.nupl.ratio, name, color, unit: Unit.ratio })],
bottom: [
line({ series: pattern.nupl.ratio, name, color, unit: Unit.ratio }),
],
},
],
};
@@ -671,7 +719,12 @@ function groupedBucketCharts(list, titlePrefix) {
title: `${titlePrefix}: Supply Change`,
bottom: ROLLING_WINDOWS.flatMap((w) =>
list.map(({ name, color, pattern }) =>
baseline({ series: pattern.supply.all.delta.absolute[w.key], name: `${name} ${w.name}`, color, unit: Unit.sats }),
baseline({
series: pattern.supply.all.delta.absolute[w.key],
name: `${name} ${w.name}`,
color,
unit: Unit.sats,
}),
),
),
},
@@ -679,7 +732,12 @@ function groupedBucketCharts(list, titlePrefix) {
name: w.name,
title: `${titlePrefix}: Supply Change (${w.title})`,
bottom: list.map(({ name, color, pattern }) =>
baseline({ series: pattern.supply.all.delta.absolute[w.key], name, color, unit: Unit.sats }),
baseline({
series: pattern.supply.all.delta.absolute[w.key],
name,
color,
unit: Unit.sats,
}),
),
})),
],
@@ -692,7 +750,11 @@ function groupedBucketCharts(list, titlePrefix) {
title: `${titlePrefix}: Supply Rate`,
bottom: ROLLING_WINDOWS.flatMap((w) =>
list.flatMap(({ name, color, pattern }) =>
percentRatio({ pattern: pattern.supply.all.delta.rate[w.key], name: `${name} ${w.name}`, color }),
percentRatio({
pattern: pattern.supply.all.delta.rate[w.key],
name: `${name} ${w.name}`,
color,
}),
),
),
},
@@ -700,7 +762,11 @@ function groupedBucketCharts(list, titlePrefix) {
name: w.name,
title: `${titlePrefix}: Supply Rate (${w.title})`,
bottom: list.flatMap(({ name, color, pattern }) =>
percentRatio({ pattern: pattern.supply.all.delta.rate[w.key], name, color }),
percentRatio({
pattern: pattern.supply.all.delta.rate[w.key],
name,
color,
}),
),
})),
],
@@ -716,14 +782,24 @@ function groupedBucketCharts(list, titlePrefix) {
name: "All",
title: `${titlePrefix}: Realized Cap`,
bottom: list.map(({ name, color, pattern }) =>
line({ series: pattern.realizedCap.all, name, color, unit: Unit.usd }),
line({
series: pattern.realizedCap.all,
name,
color,
unit: Unit.usd,
}),
),
},
{
name: "STH",
title: `${titlePrefix}: STH Realized Cap`,
bottom: list.map(({ name, color, pattern }) =>
line({ series: pattern.realizedCap.sth, name, color, unit: Unit.usd }),
line({
series: pattern.realizedCap.sth,
name,
color,
unit: Unit.usd,
}),
),
},
],
@@ -749,7 +825,10 @@ export function createUtxoProfitabilitySection({ range, profit, loss }) {
{
name: "Range",
tree: [
{ name: "Compare", tree: groupedBucketCharts(range, "Profitability Range") },
{
name: "Compare",
tree: groupedBucketCharts(range, "Profitability Range"),
},
...range.map(singleBucketFolder),
],
},

View File

@@ -11,7 +11,7 @@
*/
import { Unit } from "../../utils/units.js";
import { ROLLING_WINDOWS, line, dotted, baseline, dots, dotsBaseline, percentRatio, percentRatioBaseline } from "../series.js";
import { ROLLING_WINDOWS, line, dotted, baseline, percentRatio, percentRatioBaseline } from "../series.js";
import { colors } from "../../utils/colors.js";
import { priceLine } from "../constants.js";
import {
@@ -236,7 +236,7 @@ function nuplSeries(nupl) {
// ============================================================================
/**
* Flat metric folder: Compare + windows + Cumulative + Per Block + optional % of Realized Cap
* Flat metric folder: Compare + windows + Cumulative + optional % of Realized Cap
* @param {Object} args
* @param {{ sum: Record<string, { usd: AnySeriesPattern }>, cumulative: { usd: AnySeriesPattern }, base: { usd: AnySeriesPattern } }} args.pattern
* @param {string} args.metricTitle
@@ -264,11 +264,6 @@ function realizedMetricFolder({ pattern, metricTitle, color, title, toRcap }) {
title: title(`Realized ${metricTitle} (Total)`),
bottom: [line({ series: pattern.cumulative.usd, name: metricTitle, color, unit: Unit.usd })],
},
{
name: "Per Block",
title: title(`Realized ${metricTitle} per Block`),
bottom: [dots({ series: pattern.base.usd, name: metricTitle, color, unit: Unit.usd })],
},
...(toRcap ? [{
name: "% of Realized Cap",
title: title(`Realized ${metricTitle} (% of Realized Cap)`),
@@ -278,7 +273,7 @@ function realizedMetricFolder({ pattern, metricTitle, color, title, toRcap }) {
}
/**
* Net P&L folder: Compare + windows + Cumulative + Per Block + optional % of Rcap + Change/
* Net P&L folder: Compare + windows + Cumulative + optional % of Rcap + Change/
* @param {Object} args
* @param {NetPnlFullPattern | NetPnlBasicPattern} args.netPnl
* @param {(name: string) => string} args.title
@@ -307,11 +302,6 @@ function realizedNetFolder({ netPnl, title, toRcap, extraChange = [] }) {
title: title("Net Realized P&L (Total)"),
bottom: [baseline({ series: netPnl.cumulative.usd, name: "Net", unit: Unit.usd })],
},
{
name: "Per Block",
title: title("Net Realized P&L per Block"),
bottom: [dotsBaseline({ series: netPnl.base.usd, name: "Net", unit: Unit.usd })],
},
...(toRcap ? [{
name: "% of Realized Cap",
title: title("Net Realized P&L (% of Realized Cap)"),
@@ -464,11 +454,6 @@ function realizedSubfolderFull(r, title) {
title: title("Peak Regret (Total)"),
bottom: [line({ series: r.peakRegret.cumulative.usd, name: "Peak Regret", unit: Unit.usd })],
},
{
name: "Per Block",
title: title("Peak Regret per Block"),
bottom: [dots({ series: r.peakRegret.base.usd, name: "Peak Regret", unit: Unit.usd })],
},
{
name: "% of Realized Cap",
title: title("Peak Regret (% of Realized Cap)"),

View File

@@ -18,6 +18,7 @@ import {
satsBtcUsdFrom,
satsBtcUsdFullTree,
revenueBtcSatsUsd,
revenueRollingBtcSatsUsd,
} from "./shared.js";
import { brk } from "../client.js";
@@ -122,7 +123,6 @@ export function createMiningSection() {
name: "Rewards",
tree: satsBtcUsdFullTree({
pattern: pool.rewards,
name: "Rewards",
title: `Rewards: ${name}`,
}),
},
@@ -283,77 +283,44 @@ export function createMiningSection() {
{
name: "Revenue",
tree: [
...ROLLING_WINDOWS.map((w) => ({
name: w.name,
title: `Revenue ${w.title} Averages`,
bottom: revenueRollingBtcSatsUsd({
coinbase: mining.rewards.coinbase.average[w.key],
subsidy: mining.rewards.subsidy.average[w.key],
fee: mining.rewards.fees.average[w.key],
}),
})),
{
name: "Compare",
tree: [
{
name: "Per Block",
title: "Revenue Comparison",
bottom: revenueBtcSatsUsd({
coinbase: mining.rewards.coinbase,
subsidy: mining.rewards.subsidy,
fee: mining.rewards.fees,
key: "base",
}),
},
{
name: "Cumulative",
title: "Revenue Comparison (Total)",
bottom: revenueBtcSatsUsd({
coinbase: mining.rewards.coinbase,
subsidy: mining.rewards.subsidy,
fee: mining.rewards.fees,
key: "cumulative",
}),
},
],
name: "Cumulative",
title: "Revenue Comparison (Total)",
bottom: revenueBtcSatsUsd({
coinbase: mining.rewards.coinbase,
subsidy: mining.rewards.subsidy,
fee: mining.rewards.fees,
key: "cumulative",
}),
},
{
name: "Coinbase",
tree: satsBtcUsdFullTree({
pattern: mining.rewards.coinbase,
name: "Coinbase",
title: "Coinbase Rewards",
}),
},
{
name: "Subsidy",
tree: [
{
name: "Per Block",
title: "Block Subsidy",
bottom: [
...satsBtcUsdFrom({
source: mining.rewards.subsidy,
key: "base",
name: "base",
}),
line({
series: mining.rewards.subsidy.sma1y.usd,
name: "1y SMA",
color: colors.time._1y,
unit: Unit.usd,
defaultActive: false,
}),
],
},
{
name: "Cumulative",
title: "Block Subsidy (Total)",
bottom: satsBtcUsdFrom({
source: mining.rewards.subsidy,
key: "cumulative",
name: "all-time",
}),
},
],
tree: satsBtcUsdFullTree({
pattern: mining.rewards.subsidy,
title: "Block Subsidy",
}),
},
{
name: "Fees",
tree: [
...satsBtcUsdFullTree({
pattern: mining.rewards.fees,
name: "Fees",
title: "Transaction Fee Revenue",
}),
{

View File

@@ -4,16 +4,14 @@ import { colors } from "../utils/colors.js";
import { brk } from "../client.js";
import { Unit } from "../utils/units.js";
import { entries } from "../utils/array.js";
import { priceLine } from "./constants.js";
import {
line,
dots,
fromSupplyPattern,
chartsFromFullPerBlock,
chartsFromCount,
chartsFromCountEntries,
chartsFromAggregatedPerBlock,
averagesTree,
averagesArray,
simpleDeltaTree,
ROLLING_WINDOWS,
chartsFromBlockAnd6b,
@@ -169,14 +167,14 @@ export function createNetworkSection() {
),
})),
},
...activityTypes.map((t) =>
averagesTree({
...activityTypes.map((t) => ({
name: t.name,
tree: averagesArray({
windows: addrs.activity[key][t.key],
title: `${titlePrefix}${t.name} Addresses`,
unit: Unit.count,
name: t.name,
}),
),
})),
],
},
];
@@ -308,7 +306,6 @@ export function createNetworkSection() {
name: "Volume",
tree: satsBtcUsdFullTree({
pattern: transactions.volume.transferVolume,
name: "base",
title: "Transaction Volume",
}),
},
@@ -429,31 +426,11 @@ export function createNetworkSection() {
},
{
name: "Interval",
tree: [
{
name: "Per Block",
title: "Block Interval",
bottom: [
dots({
series: blocks.interval.base,
name: "base",
unit: Unit.secs,
}),
line({
series: blocks.interval._24h,
name: "24h avg",
color: colors.stat.avg,
unit: Unit.secs,
}),
priceLine({ unit: Unit.secs, name: "Target", number: 600 }),
],
},
averagesTree({
windows: blocks.interval,
title: "Block Interval",
unit: Unit.secs,
}),
],
tree: averagesArray({
windows: blocks.interval,
title: "Block Interval",
unit: Unit.secs,
}),
},
{
name: "Size",
@@ -509,17 +486,15 @@ export function createNetworkSection() {
{
name: "Created",
color: colors.entity.output,
base: outputs.count.total.sum,
average: outputs.count.total.rolling.average,
rolling: outputs.count.total.rolling.sum,
sum: outputs.count.total.rolling.sum,
cumulative: outputs.count.total.cumulative,
},
{
name: "Spent",
color: colors.entity.input,
base: inputs.count.sum,
average: inputs.count.rolling.average,
rolling: inputs.count.rolling.sum,
sum: inputs.count.rolling.sum,
cumulative: inputs.count.cumulative,
},
],

View File

@@ -517,6 +517,61 @@ export function sumsArray({ windows, title, unit }) {
}));
}
/**
* Flat array of per-window charts with both sum (active) and average (off by default)
* @param {Object} args
* @param {{ _24h: AnySeriesPattern, _1w: AnySeriesPattern, _1m: AnySeriesPattern, _1y: AnySeriesPattern }} args.sum
* @param {{ _24h: AnySeriesPattern, _1w: AnySeriesPattern, _1m: AnySeriesPattern, _1y: AnySeriesPattern }} args.average
* @param {string} args.title
* @param {Unit} args.unit
* @returns {PartialChartOption[]}
*/
export function sumsAndAveragesArray({ sum, average, title, unit }) {
return ROLLING_WINDOWS.map((w) => ({
name: w.name,
title: `${title} ${w.title}`,
bottom: [
line({ series: sum[w.key], name: "Sum", color: w.color, unit }),
line({
series: average[w.key],
name: "Avg",
color: w.color,
unit,
defaultActive: false,
}),
],
}));
}
/**
* Windowed sum+avg charts + cumulative
* @param {Object} args
* @param {{ _24h: AnySeriesPattern, _1w: AnySeriesPattern, _1m: AnySeriesPattern, _1y: AnySeriesPattern }} args.sum
* @param {{ _24h: AnySeriesPattern, _1w: AnySeriesPattern, _1m: AnySeriesPattern, _1y: AnySeriesPattern }} args.average
* @param {AnySeriesPattern} args.cumulative
* @param {string} args.title
* @param {Unit} args.unit
* @param {Color} [args.color]
* @returns {PartialChartOption[]}
*/
export function sumsAndAveragesCumulative({ sum, average, cumulative, title, unit, color }) {
return [
{
name: "Compare",
title: `${title} Averages`,
bottom: ROLLING_WINDOWS.map((w) =>
line({ series: average[w.key], name: w.name, color: w.color, unit }),
),
},
...sumsAndAveragesArray({ sum, average, title, unit }),
{
name: "Cumulative",
title: `${title} (Total)`,
bottom: [{ series: cumulative, title: "all-time", color, unit }],
},
];
}
/**
* Rolling sums tree (Compare + individual windows in a folder)
* @param {Object} args
@@ -538,22 +593,21 @@ export function sumsTree({ windows, title, unit, series }) {
}
/**
* Rolling averages tree
* Flat array of per-window average charts
* @param {Object} args
* @param {{ _24h: AnySeriesPattern, _1w: AnySeriesPattern, _1m: AnySeriesPattern, _1y: AnySeriesPattern }} args.windows
* @param {string} args.title
* @param {Unit} args.unit
* @param {string} [args.name]
* @returns {PartialOptionsGroup}
* @returns {PartialChartOption[]}
*/
export function averagesTree({ windows, title, unit, name = "Averages" }) {
return rollingWindowsTree({
windows,
title,
windowTitle: (w) => `${title} ${w.title} Average`,
unit,
name,
});
export function averagesArray({ windows, title, unit }) {
return ROLLING_WINDOWS.map((w) => ({
name: w.name,
title: `${title} ${w.title} Average`,
bottom: [
line({ series: windows[w.key], name: w.name, color: w.color, unit }),
],
}));
}
/**
@@ -854,7 +908,7 @@ export function simpleDeltaTree({ delta, title, unit }) {
// These split patterns into separate Sum/Distribution/Cumulative charts
/**
* Split flat per-block pattern into charts (Sum/Rolling/Distribution/Cumulative)
* Split flat per-block pattern into charts (Averages/Sums/Distribution/Cumulative)
* Pattern has: .height, .cumulative, .sum (windowed), .average/.pct10/... (windowed, flat)
* @param {Object} args
* @param {FullPerBlockPattern} args.pattern
@@ -873,14 +927,14 @@ export function chartsFromFull({
? `${title} ${distributionSuffix}`
: title;
return [
averagesTree({ windows: pattern.average, title, unit }),
sumsTree({ windows: pattern.sum, title, unit }),
...sumsAndAveragesCumulative({
sum: pattern.sum,
average: pattern.average,
cumulative: pattern.cumulative,
title,
unit,
}),
distributionWindowsTree({ pattern, title: distTitle, unit }),
{
name: "Cumulative",
title: `${title} (Total)`,
bottom: [{ series: pattern.cumulative, title: "all-time", unit }],
},
];
}
@@ -914,18 +968,18 @@ export function chartsFromAggregated({
? `${title} ${distributionSuffix}`
: title;
return [
averagesTree({ windows: pattern.rolling.average, title, unit }),
sumsTree({ windows: pattern.rolling.sum, title, unit }),
...sumsAndAveragesCumulative({
sum: pattern.rolling.sum,
average: pattern.rolling.average,
cumulative: pattern.cumulative,
title,
unit,
}),
distributionWindowsTree({
pattern: pattern.rolling,
title: distTitle,
unit,
}),
{
name: "Cumulative",
title: `${title} (Total)`,
bottom: [{ series: pattern.cumulative, title: "all-time", unit }],
},
];
}
@@ -964,27 +1018,7 @@ export function chartsFromBlockAnd6b({ pattern, title, unit }) {
}
/**
* Sums + Cumulative charts (no Per Block)
* @param {Object} args
* @param {{ sum: { _24h: AnySeriesPattern, _1w: AnySeriesPattern, _1m: AnySeriesPattern, _1y: AnySeriesPattern }, cumulative: AnySeriesPattern }} args.pattern
* @param {string} args.title
* @param {Unit} args.unit
* @param {Color} [args.color]
* @returns {PartialOptionsTree}
*/
export function chartsFromSumsCumulative({ pattern, title, unit, color }) {
return [
...sumsArray({ windows: pattern.sum, title, unit }),
{
name: "Cumulative",
title: `${title} (Total)`,
bottom: [{ series: pattern.cumulative, title: "all-time", color, unit }],
},
];
}
/**
* Per Block + Sums + Cumulative charts
* Averages + Sums + Cumulative charts
* @param {Object} args
* @param {CountPattern<any>} args.pattern
* @param {string} args.title
@@ -993,14 +1027,26 @@ export function chartsFromSumsCumulative({ pattern, title, unit, color }) {
* @returns {PartialOptionsTree}
*/
export function chartsFromCount({ pattern, title, unit, color }) {
return [
averagesTree({ windows: pattern.average, title, unit }),
...chartsFromSumsCumulative({ pattern, title, unit, color }),
];
return sumsAndAveragesCumulative({
sum: pattern.sum,
average: pattern.average,
cumulative: pattern.cumulative,
title,
unit,
color,
});
}
/**
* Split multiple named entries (each with base/sum/cumulative) into Per Block/Sums/Cumulative charts
* Windowed sums + cumulative for multiple named entries (e.g. transaction versions)
* @param {Object} args
* @param {Array<[string, CountPattern<any>]>} args.entries
* @param {string} args.title
* @param {Unit} args.unit
* @returns {PartialOptionsTree}
*/
/**
* Windowed sums + cumulative for multiple named entries (e.g. transaction versions)
* @param {Object} args
* @param {Array<[string, CountPattern<any>]>} args.entries
* @param {string} args.title
@@ -1008,49 +1054,45 @@ export function chartsFromCount({ pattern, title, unit, color }) {
* @returns {PartialOptionsTree}
*/
export function chartsFromCountEntries({ entries, title, unit }) {
return multiSeriesTree({
entries: entries.map(([name, data], i, arr) => ({
name,
color: colors.at(i, arr.length),
base: data.base,
average: data.average,
rolling: data.sum,
cumulative: data.cumulative,
const items = entries.map(([name, data], i, arr) => ({
name,
color: colors.at(i, arr.length),
sum: data.sum,
cumulative: data.cumulative,
}));
return [
...ROLLING_WINDOWS.map((w) => ({
name: w.name,
title: `${title} ${w.title} Sum`,
bottom: items.map((e) =>
line({ series: e.sum[w.key], name: e.name, color: e.color, unit }),
),
})),
title,
unit,
});
{
name: "Cumulative",
title: `${title} (Total)`,
bottom: items.map((e) =>
line({ series: e.cumulative, name: e.name, color: e.color, unit }),
),
},
];
}
/**
* Per Block + Sums + Cumulative tree for multiple named series shown side-by-side
* Windowed averages + sums + cumulative for multiple named series (e.g. UTXO flow)
* @param {Object} args
* @param {Array<{ name: string, color: Color, base: AnySeriesPattern, average: { _24h: AnySeriesPattern, _1w: AnySeriesPattern, _1m: AnySeriesPattern, _1y: AnySeriesPattern }, rolling: { _24h: AnySeriesPattern, _1w: AnySeriesPattern, _1m: AnySeriesPattern, _1y: AnySeriesPattern }, cumulative: AnySeriesPattern }>} args.entries
* @param {Array<{ name: string, color: Color, average: { _24h: AnySeriesPattern, _1w: AnySeriesPattern, _1m: AnySeriesPattern, _1y: AnySeriesPattern }, sum: { _24h: AnySeriesPattern, _1w: AnySeriesPattern, _1m: AnySeriesPattern, _1y: AnySeriesPattern }, cumulative: AnySeriesPattern }>} args.entries
* @param {string} args.title
* @param {Unit} args.unit
* @returns {PartialOptionsTree}
*/
export function multiSeriesTree({ entries, title, unit }) {
return [
{
name: "Compare",
title: `${title} Average`,
bottom: ROLLING_WINDOWS.flatMap((w) =>
entries.map((e) =>
line({
series: e.average[w.key],
name: `${e.name} ${w.name}`,
color: e.color,
unit,
}),
),
),
},
...ROLLING_WINDOWS.map((w) => ({
name: w.name,
title: `${title} ${w.title} Sum`,
title: `${title} ${w.title} Averages`,
bottom: entries.map((e) =>
line({ series: e.rolling[w.key], name: e.name, color: e.color, unit }),
line({ series: e.average[w.key], name: e.name, color: e.color, unit }),
),
})),
{

View File

@@ -219,7 +219,6 @@ export function satsBtcUsdRolling({ pattern, name, color, defaultActive }) {
* Build a full Sum / Rolling / Cumulative tree from a FullValuePattern
* @param {Object} args
* @param {FullValuePattern} args.pattern
* @param {string} args.name
* @param {string} args.title
* @param {Color} [args.color]
* @returns {PartialOptionsTree}