global: snapshot

This commit is contained in:
nym21
2026-03-19 18:16:45 +01:00
parent 8910c0988e
commit 45de61b438
30 changed files with 1387 additions and 1392 deletions

View File

@@ -16,12 +16,12 @@ impl Vecs {
) -> Result<()> {
self.inflation_rate.bps.height.compute_transform2(
starting_indexes.height,
&activity.liveliness.height,
&activity.ratio.height,
&supply.inflation_rate.bps.height,
|(h, liveliness, inflation, ..)| {
|(h, a2vr, inflation, ..)| {
(
h,
BasisPointsSigned32::from(f64::from(liveliness) * f64::from(inflation)),
BasisPointsSigned32::from(f64::from(a2vr) * f64::from(inflation)),
)
},
exit,

View File

@@ -18,7 +18,7 @@ impl Vecs {
inflation_rate: PercentPerBlock::forced_import(
db,
"cointime_adj_inflation_rate",
version,
version + Version::ONE,
indexes,
)?,
tx_velocity_native: PerBlock::forced_import(

View File

@@ -166,6 +166,7 @@ impl DynCohortVecs for AddrCohortVecs {
.push(state.addr_count.into());
self.metrics.supply.push_state(&state.inner);
self.metrics.outputs.push_state(&state.inner);
self.metrics.activity.push_state(&state.inner);
self.metrics.realized.push_state(&state.inner);
}
}

View File

@@ -540,8 +540,7 @@ impl UTXOCohorts<Rw> {
.age_range
.under_1h
.metrics
.realized
.minimal
.activity
.transfer_volume
.base
.cents

View File

@@ -39,6 +39,7 @@ impl DynCohortVecs for UTXOCohortVecs<MinimalCohortMetrics> {
if let Some(state) = self.state.as_ref() {
self.metrics.supply.push_state(state);
self.metrics.outputs.push_state(state);
self.metrics.activity.push_state(state);
self.metrics.realized.push_state(state);
}
}

View File

@@ -36,6 +36,7 @@ impl DynCohortVecs for UTXOCohortVecs<TypeCohortMetrics> {
if let Some(state) = self.state.as_ref() {
self.metrics.supply.push_state(state);
self.metrics.outputs.push_state(state);
self.metrics.activity.push_state(state);
self.metrics.realized.push_state(state);
}
}

View File

@@ -1,6 +1,7 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Bitcoin, Indexes, StoredF64, Version};
use derive_more::{Deref, DerefMut};
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
use crate::{
@@ -9,9 +10,15 @@ use crate::{
prices,
};
#[derive(Traversable)]
use super::ActivityMinimal;
#[derive(Deref, DerefMut, Traversable)]
pub struct ActivityCore<M: StorageMode = Rw> {
pub transfer_volume: AmountPerBlockCumulativeWithSums<M>,
#[deref]
#[deref_mut]
#[traversable(flatten)]
pub minimal: ActivityMinimal<M>,
pub coindays_destroyed: PerBlockCumulativeWithSums<StoredF64, StoredF64, M>,
#[traversable(wrap = "transfer_volume", rename = "in_profit")]
pub transfer_volume_in_profit: AmountPerBlockCumulativeWithSums<M>,
@@ -23,7 +30,7 @@ impl ActivityCore {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
let v1 = Version::ONE;
Ok(Self {
transfer_volume: cfg.import("transfer_volume", v1)?,
minimal: ActivityMinimal::forced_import(cfg)?,
coindays_destroyed: cfg.import("coindays_destroyed", v1)?,
transfer_volume_in_profit: cfg.import("transfer_volume_in_profit", v1)?,
transfer_volume_in_loss: cfg.import("transfer_volume_in_loss", v1)?,
@@ -31,11 +38,8 @@ impl ActivityCore {
}
pub(crate) fn min_len(&self) -> usize {
self.transfer_volume
.base
.sats
.height
.len()
self.minimal
.min_len()
.min(self.coindays_destroyed.base.height.len())
.min(self.transfer_volume_in_profit.base.sats.height.len())
.min(self.transfer_volume_in_loss.base.sats.height.len())
@@ -46,7 +50,7 @@ impl ActivityCore {
&mut self,
state: &CohortState<impl RealizedOps, impl CostBasisOps>,
) {
self.transfer_volume.base.sats.height.push(state.sent);
self.minimal.push_state(state);
self.coindays_destroyed.base.height.push(
StoredF64::from(Bitcoin::from(state.satdays_destroyed)),
);
@@ -63,15 +67,13 @@ impl ActivityCore {
}
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
vec![
&mut self.transfer_volume.base.sats.height as &mut dyn AnyStoredVec,
&mut self.transfer_volume.base.cents.height,
&mut self.coindays_destroyed.base.height,
&mut self.transfer_volume_in_profit.base.sats.height,
&mut self.transfer_volume_in_profit.base.cents.height,
&mut self.transfer_volume_in_loss.base.sats.height,
&mut self.transfer_volume_in_loss.base.cents.height,
]
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
}
pub(crate) fn validate_computed_versions(&mut self, _base_version: Version) -> Result<()> {
@@ -84,14 +86,9 @@ impl ActivityCore {
others: &[&Self],
exit: &Exit,
) -> Result<()> {
self.transfer_volume.base.sats.height.compute_sum_of_others(
starting_indexes.height,
&others
.iter()
.map(|v| &v.transfer_volume.base.sats.height)
.collect::<Vec<_>>(),
exit,
)?;
let minimal_refs: Vec<&ActivityMinimal> = others.iter().map(|o| &o.minimal).collect();
self.minimal
.compute_from_stateful(starting_indexes, &minimal_refs, exit)?;
sum_others!(self, starting_indexes, others, exit; coindays_destroyed.base.height);
sum_others!(self, starting_indexes, others, exit; transfer_volume_in_profit.base.sats.height);
@@ -106,8 +103,8 @@ impl ActivityCore {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.transfer_volume
.compute_rest(starting_indexes.height, prices, exit)?;
self.minimal
.compute_rest_part1(prices, starting_indexes, exit)?;
self.coindays_destroyed
.compute_rest(starting_indexes.height, exit)?;
Ok(())

View File

@@ -1,10 +1,10 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Bitcoin, Indexes, StoredF32, StoredF64, Version};
use brk_types::{Indexes, StoredF32, StoredF64, Version};
use derive_more::{Deref, DerefMut};
use vecdb::{AnyStoredVec, Exit, ReadableCloneableVec, Rw, StorageMode};
use crate::internal::{Identity, LazyPerBlock, PerBlock};
use crate::internal::{Identity, LazyPerBlock, PerBlock, Windows};
use crate::{
distribution::{metrics::ImportConfig, state::{CohortState, CostBasisOps, RealizedOps}},
@@ -22,7 +22,7 @@ pub struct ActivityFull<M: StorageMode = Rw> {
pub coinyears_destroyed: LazyPerBlock<StoredF64, StoredF64>,
pub dormancy: PerBlock<StoredF32, M>,
pub dormancy: Windows<PerBlock<StoredF32, M>>,
}
impl ActivityFull {
@@ -37,10 +37,19 @@ impl ActivityFull {
cfg.indexes,
);
let dormancy = Windows::try_from_fn(|suffix| {
PerBlock::forced_import(
cfg.db,
&cfg.name(&format!("dormancy_{suffix}")),
cfg.version + v1,
cfg.indexes,
)
})?;
Ok(Self {
inner,
coinyears_destroyed,
dormancy: cfg.import("dormancy", v1)?,
dormancy,
})
}
@@ -58,7 +67,9 @@ impl ActivityFull {
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
let mut vecs = self.inner.collect_vecs_mut();
vecs.push(&mut self.dormancy.height);
for d in self.dormancy.as_mut_array() {
vecs.push(&mut d.height);
}
vecs
}
@@ -86,20 +97,28 @@ impl ActivityFull {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.dormancy.height.compute_transform2(
starting_indexes.height,
&self.inner.coindays_destroyed.base.height,
&self.inner.transfer_volume.base.sats.height,
|(i, cdd, sent_sats, ..)| {
let sent_btc = f64::from(Bitcoin::from(sent_sats));
if sent_btc == 0.0 {
(i, StoredF32::from(0.0f32))
} else {
(i, StoredF32::from((f64::from(cdd) / sent_btc) as f32))
}
},
exit,
)?;
for ((dormancy, cdd_sum), tv_sum) in self
.dormancy
.as_mut_array()
.into_iter()
.zip(self.inner.coindays_destroyed.sum.as_array())
.zip(self.inner.minimal.transfer_volume.sum.0.as_array())
{
dormancy.height.compute_transform2(
starting_indexes.height,
&cdd_sum.height,
&tv_sum.btc.height,
|(i, rolling_cdd, rolling_btc, ..)| {
let btc = f64::from(rolling_btc);
if btc == 0.0 {
(i, StoredF32::from(0.0f32))
} else {
(i, StoredF32::from((f64::from(rolling_cdd) / btc) as f32))
}
},
exit,
)?;
}
Ok(())
}

View File

@@ -0,0 +1,76 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Indexes, Version};
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
use crate::{
distribution::{metrics::ImportConfig, state::{CohortState, CostBasisOps, RealizedOps}},
internal::AmountPerBlockCumulativeWithSums,
prices,
};
#[derive(Traversable)]
pub struct ActivityMinimal<M: StorageMode = Rw> {
pub transfer_volume: AmountPerBlockCumulativeWithSums<M>,
}
impl ActivityMinimal {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
let v1 = Version::ONE;
Ok(Self {
transfer_volume: cfg.import("transfer_volume", v1)?,
})
}
pub(crate) fn min_len(&self) -> usize {
self.transfer_volume
.base
.sats
.height
.len()
}
#[inline(always)]
pub(crate) fn push_state(
&mut self,
state: &CohortState<impl RealizedOps, impl CostBasisOps>,
) {
self.transfer_volume.base.sats.height.push(state.sent);
}
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
vec![
&mut self.transfer_volume.base.sats.height as &mut dyn AnyStoredVec,
&mut self.transfer_volume.base.cents.height,
]
}
pub(crate) fn compute_from_stateful(
&mut self,
starting_indexes: &Indexes,
others: &[&Self],
exit: &Exit,
) -> Result<()> {
self.transfer_volume.base.sats.height.compute_sum_of_others(
starting_indexes.height,
&others
.iter()
.map(|v| &v.transfer_volume.base.sats.height)
.collect::<Vec<_>>(),
exit,
)?;
Ok(())
}
pub(crate) fn compute_rest_part1(
&mut self,
prices: &prices::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.transfer_volume
.compute_rest(starting_indexes.height, prices, exit)?;
Ok(())
}
}

View File

@@ -1,8 +1,10 @@
mod core;
mod full;
mod minimal;
pub use self::core::ActivityCore;
pub use full::ActivityFull;
pub use minimal::ActivityMinimal;
use brk_error::Result;
use brk_types::{Indexes, Version};

View File

@@ -116,6 +116,7 @@ impl AllCohortMetrics {
starting_indexes,
&self.supply.total.btc.height,
height_to_market_cap,
&self.activity.transfer_volume,
exit,
)?;
@@ -128,7 +129,7 @@ impl AllCohortMetrics {
self.asopr.compute_rest_part2(
starting_indexes,
&self.realized.minimal.transfer_volume.base.cents.height,
&self.activity.transfer_volume.base.cents.height,
&self.realized.core.sopr.value_destroyed.base.height,
under_1h_value_created,
under_1h_value_destroyed,

View File

@@ -75,6 +75,7 @@ impl BasicCohortMetrics {
prices,
starting_indexes,
&self.supply.total.btc.height,
&self.activity.transfer_volume.sum._24h.cents.height,
exit,
)?;

View File

@@ -63,7 +63,7 @@ impl CoreCohortMetrics {
vecs
}
/// Aggregate Core-tier fields from CohortMetricsBase sources (e.g. age_range under_age/over_age).
/// Aggregate Core-tier fields from CohortMetricsBase sources (e.g. age_range -> under_age/over_age).
pub(crate) fn compute_from_base_sources<T: CohortMetricsBase>(
&mut self,
starting_indexes: &Indexes,
@@ -114,7 +114,7 @@ impl CoreCohortMetrics {
.compute_sent_profitability(prices, starting_indexes, exit)?;
self.realized
.compute_rest_part1(prices, starting_indexes, exit)?;
.compute_rest_part1(starting_indexes, exit)?;
self.unrealized.compute_rest(starting_indexes, exit)?;
@@ -132,6 +132,7 @@ impl CoreCohortMetrics {
prices,
starting_indexes,
&self.supply.total.btc.height,
&self.activity.transfer_volume.sum._24h.cents.height,
exit,
)?;

View File

@@ -103,6 +103,7 @@ impl ExtendedCohortMetrics {
starting_indexes,
&self.supply.total.btc.height,
height_to_market_cap,
&self.activity.transfer_volume,
exit,
)?;

View File

@@ -80,7 +80,7 @@ impl ExtendedAdjustedCohortMetrics {
self.asopr.compute_rest_part2(
starting_indexes,
&self.inner.realized.minimal.transfer_volume.base.cents.height,
&self.inner.activity.transfer_volume.base.cents.height,
&self.inner.realized.core.sopr.value_destroyed.base.height,
under_1h_value_created,
under_1h_value_destroyed,

View File

@@ -6,7 +6,7 @@ use vecdb::{AnyStoredVec, Exit, Rw, StorageMode};
use crate::{
distribution::metrics::{
ImportConfig, OutputsBase, RealizedMinimal, SupplyBase, UnrealizedMinimal,
ActivityMinimal, ImportConfig, OutputsBase, RealizedMinimal, SupplyBase, UnrealizedMinimal,
},
prices,
};
@@ -21,6 +21,7 @@ pub struct MinimalCohortMetrics<M: StorageMode = Rw> {
pub filter: Filter,
pub supply: Box<SupplyBase<M>>,
pub outputs: Box<OutputsBase<M>>,
pub activity: Box<ActivityMinimal<M>>,
pub realized: Box<RealizedMinimal<M>>,
pub unrealized: Box<UnrealizedMinimal<M>>,
}
@@ -31,6 +32,7 @@ impl MinimalCohortMetrics {
filter: cfg.filter.clone(),
supply: Box::new(SupplyBase::forced_import(cfg)?),
outputs: Box::new(OutputsBase::forced_import(cfg)?),
activity: Box::new(ActivityMinimal::forced_import(cfg)?),
realized: Box::new(RealizedMinimal::forced_import(cfg)?),
unrealized: Box::new(UnrealizedMinimal::forced_import(cfg)?),
})
@@ -40,6 +42,7 @@ impl MinimalCohortMetrics {
self.supply
.min_len()
.min(self.outputs.min_len())
.min(self.activity.min_len())
.min(self.realized.min_stateful_len())
}
@@ -47,6 +50,7 @@ impl MinimalCohortMetrics {
let mut vecs: Vec<&mut dyn AnyStoredVec> = Vec::new();
vecs.extend(self.supply.collect_vecs_mut());
vecs.extend(self.outputs.collect_vecs_mut());
vecs.extend(self.activity.collect_vecs_mut());
vecs.extend(self.realized.collect_vecs_mut());
vecs
}
@@ -71,6 +75,14 @@ impl MinimalCohortMetrics {
.collect::<Vec<_>>(),
exit,
)?;
self.activity.compute_from_stateful(
starting_indexes,
&others
.iter()
.map(|v| v.activity.as_ref())
.collect::<Vec<_>>(),
exit,
)?;
self.realized.compute_from_stateful(
starting_indexes,
&others
@@ -89,8 +101,10 @@ impl MinimalCohortMetrics {
exit: &Exit,
) -> Result<()> {
self.supply.compute(prices, starting_indexes.height, exit)?;
self.realized
self.activity
.compute_rest_part1(prices, starting_indexes, exit)?;
self.realized
.compute_rest_part1(starting_indexes, exit)?;
Ok(())
}

View File

@@ -6,7 +6,7 @@ use vecdb::{AnyStoredVec, Exit, Rw, StorageMode};
use crate::{
distribution::metrics::{
ImportConfig, OutputsBase, RealizedMinimal, SupplyCore, UnrealizedBasic,
ActivityMinimal, ImportConfig, OutputsBase, RealizedMinimal, SupplyCore, UnrealizedBasic,
},
prices,
};
@@ -20,6 +20,7 @@ pub struct TypeCohortMetrics<M: StorageMode = Rw> {
pub filter: Filter,
pub supply: Box<SupplyCore<M>>,
pub outputs: Box<OutputsBase<M>>,
pub activity: Box<ActivityMinimal<M>>,
pub realized: Box<RealizedMinimal<M>>,
pub unrealized: Box<UnrealizedBasic<M>>,
}
@@ -30,6 +31,7 @@ impl TypeCohortMetrics {
filter: cfg.filter.clone(),
supply: Box::new(SupplyCore::forced_import(cfg)?),
outputs: Box::new(OutputsBase::forced_import(cfg)?),
activity: Box::new(ActivityMinimal::forced_import(cfg)?),
realized: Box::new(RealizedMinimal::forced_import(cfg)?),
unrealized: Box::new(UnrealizedBasic::forced_import(cfg)?),
})
@@ -39,6 +41,7 @@ impl TypeCohortMetrics {
self.supply
.min_len()
.min(self.outputs.min_len())
.min(self.activity.min_len())
.min(self.realized.min_stateful_len())
.min(self.unrealized.min_stateful_len())
}
@@ -47,6 +50,7 @@ impl TypeCohortMetrics {
let mut vecs: Vec<&mut dyn AnyStoredVec> = Vec::new();
vecs.extend(self.supply.collect_vecs_mut());
vecs.extend(self.outputs.collect_vecs_mut());
vecs.extend(self.activity.collect_vecs_mut());
vecs.extend(self.realized.collect_vecs_mut());
vecs.extend(self.unrealized.collect_vecs_mut());
vecs
@@ -59,8 +63,10 @@ impl TypeCohortMetrics {
exit: &Exit,
) -> Result<()> {
self.supply.compute(prices, starting_indexes.height, exit)?;
self.realized
self.activity
.compute_rest_part1(prices, starting_indexes, exit)?;
self.realized
.compute_rest_part1(starting_indexes, exit)?;
Ok(())
}

View File

@@ -64,7 +64,7 @@ mod relative;
mod supply;
mod unrealized;
pub use activity::{ActivityCore, ActivityFull, ActivityLike};
pub use activity::{ActivityCore, ActivityFull, ActivityLike, ActivityMinimal};
pub use cohort::{
AllCohortMetrics, BasicCohortMetrics, CoreCohortMetrics, ExtendedAdjustedCohortMetrics,
ExtendedCohortMetrics, MinimalCohortMetrics, TypeCohortMetrics,
@@ -228,7 +228,7 @@ pub trait CohortMetricsBase:
.compute_sent_profitability(prices, starting_indexes, exit)?;
self.realized_mut()
.compute_rest_part1(prices, starting_indexes, exit)?;
.compute_rest_part1(starting_indexes, exit)?;
self.unrealized_mut()
.compute_rest(prices, starting_indexes, exit)?;

View File

@@ -132,12 +132,11 @@ impl RealizedCore {
pub(crate) fn compute_rest_part1(
&mut self,
prices: &prices::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.minimal
.compute_rest_part1(prices, starting_indexes, exit)?;
.compute_rest_part1(starting_indexes, exit)?;
self.sopr
.value_destroyed
@@ -164,6 +163,7 @@ impl RealizedCore {
prices: &prices::Vecs,
starting_indexes: &Indexes,
height_to_supply: &impl ReadableVec<Height, Bitcoin>,
transfer_volume_sum_24h_cents: &impl ReadableVec<Height, Cents>,
exit: &Exit,
) -> Result<()> {
self.minimal
@@ -177,7 +177,7 @@ impl RealizedCore {
._24h
.compute_binary::<Cents, Cents, RatioCents64>(
starting_indexes.height,
&self.minimal.transfer_volume.sum._24h.cents.height,
transfer_volume_sum_24h_cents,
&self.sopr.value_destroyed.sum._24h.height,
exit,
)?;

View File

@@ -5,18 +5,14 @@ use brk_types::{
Dollars, Height, Indexes, StoredF64, Version,
};
use derive_more::{Deref, DerefMut};
use vecdb::{
AnyStoredVec, AnyVec, BytesVec, Exit, ReadableVec, Rw, StorageMode,
WritableVec,
};
use vecdb::{AnyStoredVec, AnyVec, BytesVec, Exit, ReadableVec, Rw, StorageMode, WritableVec};
use crate::{
blocks,
distribution::state::{WithCapital, CohortState, CostBasisData, RealizedState},
distribution::state::{CohortState, CostBasisData, RealizedState, WithCapital},
internal::{
FiatPerBlockCumulativeWithSums,
PercentPerBlock, PercentRollingWindows,
PriceWithRatioExtendedPerBlock, RatioCents64, RatioCentsBp32,
AmountPerBlockCumulativeWithSums, FiatPerBlockCumulativeWithSums, PercentPerBlock,
PercentRollingWindows, PriceWithRatioExtendedPerBlock, RatioCents64, RatioCentsBp32,
RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32, RatioDollarsBp32,
RatioPerBlockPercentiles, RatioPerBlockStdDevBands, RatioSma, RollingWindows,
RollingWindowsFrom1w,
@@ -119,12 +115,9 @@ impl RealizedFull {
// Net PnL
let net_pnl = RealizedNetPnl {
to_rcap: cfg
.import("net_realized_pnl_to_rcap", Version::new(2))?,
change_1m_to_rcap: cfg
.import("net_pnl_change_1m_to_rcap", Version::new(4))?,
change_1m_to_mcap: cfg
.import("net_pnl_change_1m_to_mcap", Version::new(4))?,
to_rcap: cfg.import("net_realized_pnl_to_rcap", Version::new(2))?,
change_1m_to_rcap: cfg.import("net_pnl_change_1m_to_rcap", Version::new(4))?,
change_1m_to_mcap: cfg.import("net_pnl_change_1m_to_mcap", Version::new(4))?,
};
// SOPR
@@ -135,8 +128,7 @@ impl RealizedFull {
// Peak regret
let peak_regret = RealizedPeakRegret {
value: cfg.import("realized_peak_regret", Version::new(2))?,
to_rcap: cfg
.import("realized_peak_regret_to_rcap", Version::new(2))?,
to_rcap: cfg.import("realized_peak_regret_to_rcap", Version::new(2))?,
};
// Investor
@@ -184,7 +176,11 @@ impl RealizedFull {
}
pub(crate) fn min_stateful_len(&self) -> usize {
self.investor.price.cents.height.len()
self.investor
.price
.cents
.height
.len()
.min(self.cap_raw.len())
.min(self.investor.cap_raw.len())
.min(self.peak_regret.value.base.cents.height.len())
@@ -201,8 +197,7 @@ impl RealizedFull {
.cents
.height
.push(state.realized.investor_price());
self.cap_raw
.push(state.realized.cap_raw());
self.cap_raw.push(state.realized.cap_raw());
self.investor
.cap_raw
.push(state.realized.investor_cap_raw());
@@ -236,15 +231,9 @@ impl RealizedFull {
}
#[inline(always)]
pub(crate) fn push_accum(
&mut self,
accum: &RealizedFullAccum,
) {
self.cap_raw
.push(accum.cap_raw);
self.investor
.cap_raw
.push(accum.investor_cap_raw);
pub(crate) fn push_accum(&mut self, accum: &RealizedFullAccum) {
self.cap_raw.push(accum.cap_raw);
self.investor.cap_raw.push(accum.investor_cap_raw);
let investor_price = {
let cap = accum.cap_raw.as_u128();
@@ -254,11 +243,7 @@ impl RealizedFull {
Cents::new((accum.investor_cap_raw / cap) as u64)
}
};
self.investor
.price
.cents
.height
.push(investor_price);
self.investor.price.cents.height.push(investor_price);
self.peak_regret
.value
@@ -270,12 +255,10 @@ impl RealizedFull {
pub(crate) fn compute_rest_part1(
&mut self,
prices: &prices::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.core
.compute_rest_part1(prices, starting_indexes, exit)?;
self.core.compute_rest_part1(starting_indexes, exit)?;
self.peak_regret
.value
@@ -283,6 +266,7 @@ impl RealizedFull {
Ok(())
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn compute_rest_part2(
&mut self,
blocks: &blocks::Vecs,
@@ -290,22 +274,24 @@ impl RealizedFull {
starting_indexes: &Indexes,
height_to_supply: &impl ReadableVec<Height, Bitcoin>,
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
activity_transfer_volume: &AmountPerBlockCumulativeWithSums,
exit: &Exit,
) -> Result<()> {
self.core.compute_rest_part2(
prices,
starting_indexes,
height_to_supply,
&activity_transfer_volume.sum._24h.cents.height,
exit,
)?;
// SOPR ratios from lazy rolling sums
// SOPR ratios from lazy rolling sums (1w, 1m, 1y)
for ((sopr, vc), vd) in self
.sopr
.ratio_extended
.as_mut_array()
.into_iter()
.zip(self.core.minimal.transfer_volume.sum.0.as_array()[1..].iter())
.zip(activity_transfer_volume.sum.0.as_array()[1..].iter())
.zip(self.core.sopr.value_destroyed.sum.as_array()[1..].iter())
{
sopr.compute_binary::<Cents, Cents, RatioCents64>(
@@ -349,8 +335,7 @@ impl RealizedFull {
&self.core.minimal.loss.base.cents.height,
exit,
)?;
self.gross_pnl
.compute_rest(starting_indexes.height, exit)?;
self.gross_pnl.compute_rest(starting_indexes.height, exit)?;
// Net PnL 1m change relative to rcap and mcap
self.net_pnl
@@ -381,11 +366,9 @@ impl RealizedFull {
)?;
// Investor price ratio, percentiles and bands
self.investor.price.compute_rest(
prices,
starting_indexes,
exit,
)?;
self.investor
.price
.compute_rest(prices, starting_indexes, exit)?;
// Sell-side risk ratios
for (ssrr, rv) in self

View File

@@ -11,7 +11,7 @@ use vecdb::{
use crate::{
distribution::state::{CohortState, CostBasisOps, RealizedOps},
internal::{
AmountPerBlockCumulativeWithSums, FiatPerBlockCumulativeWithSums,
FiatPerBlockCumulativeWithSums,
FiatPerBlockWithDeltas, Identity, LazyPerBlock, PriceWithRatioPerBlock,
},
prices,
@@ -26,8 +26,6 @@ pub struct RealizedMinimal<M: StorageMode = Rw> {
pub loss: FiatPerBlockCumulativeWithSums<Cents, M>,
pub price: PriceWithRatioPerBlock<M>,
pub mvrv: LazyPerBlock<StoredF32>,
pub transfer_volume: AmountPerBlockCumulativeWithSums<M>,
}
impl RealizedMinimal {
@@ -50,21 +48,12 @@ impl RealizedMinimal {
&price.ratio,
);
let transfer_volume = AmountPerBlockCumulativeWithSums::forced_import(
cfg.db,
&cfg.name("transfer_volume"),
cfg.version,
cfg.indexes,
cfg.cached_starts,
)?;
Ok(Self {
cap,
profit: cfg.import("realized_profit", v1)?,
loss: cfg.import("realized_loss", v1)?,
price,
mvrv,
transfer_volume,
})
}
@@ -75,7 +64,6 @@ impl RealizedMinimal {
.len()
.min(self.profit.base.cents.height.len())
.min(self.loss.base.cents.height.len())
.min(self.transfer_volume.base.sats.height.len())
}
#[inline(always)]
@@ -83,7 +71,6 @@ impl RealizedMinimal {
self.cap.cents.height.push(state.realized.cap());
self.profit.base.cents.height.push(state.realized.profit());
self.loss.base.cents.height.push(state.realized.loss());
self.transfer_volume.base.sats.height.push(state.sent);
}
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
@@ -91,7 +78,6 @@ impl RealizedMinimal {
&mut self.cap.cents.height as &mut dyn AnyStoredVec,
&mut self.profit.base.cents.height,
&mut self.loss.base.cents.height,
&mut self.transfer_volume.base.sats.height,
]
}
@@ -104,20 +90,16 @@ impl RealizedMinimal {
sum_others!(self, starting_indexes, others, exit; cap.cents.height);
sum_others!(self, starting_indexes, others, exit; profit.base.cents.height);
sum_others!(self, starting_indexes, others, exit; loss.base.cents.height);
sum_others!(self, starting_indexes, others, exit; transfer_volume.base.sats.height);
Ok(())
}
pub(crate) fn compute_rest_part1(
&mut self,
prices: &prices::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.profit.compute_rest(starting_indexes.height, exit)?;
self.loss.compute_rest(starting_indexes.height, exit)?;
self.transfer_volume
.compute_rest(starting_indexes.height, prices, exit)?;
Ok(())
}

View File

@@ -12,14 +12,14 @@ use brk_error::Result;
use brk_types::Indexes;
use vecdb::Exit;
use crate::{distribution::state::{WithCapital, CohortState, CostBasisData, RealizedState}, prices};
use crate::distribution::state::{WithCapital, CohortState, CostBasisData, RealizedState};
pub trait RealizedLike: Send + Sync {
fn as_core(&self) -> &RealizedCore;
fn as_core_mut(&mut self) -> &mut RealizedCore;
fn min_stateful_len(&self) -> usize;
fn push_state(&mut self, state: &CohortState<RealizedState, CostBasisData<WithCapital>>);
fn compute_rest_part1(&mut self, prices: &prices::Vecs, starting_indexes: &Indexes, exit: &Exit) -> Result<()>;
fn compute_rest_part1(&mut self, starting_indexes: &Indexes, exit: &Exit) -> Result<()>;
fn compute_from_stateful(
&mut self,
starting_indexes: &Indexes,
@@ -36,8 +36,8 @@ impl RealizedLike for RealizedCore {
fn push_state(&mut self, state: &CohortState<RealizedState, CostBasisData<WithCapital>>) {
self.push_state(state)
}
fn compute_rest_part1(&mut self, prices: &prices::Vecs, starting_indexes: &Indexes, exit: &Exit) -> Result<()> {
self.compute_rest_part1(prices, starting_indexes, exit)
fn compute_rest_part1(&mut self, starting_indexes: &Indexes, exit: &Exit) -> Result<()> {
self.compute_rest_part1(starting_indexes, exit)
}
fn compute_from_stateful(&mut self, starting_indexes: &Indexes, others: &[&RealizedCore], exit: &Exit) -> Result<()> {
self.compute_from_stateful(starting_indexes, others, exit)
@@ -52,8 +52,8 @@ impl RealizedLike for RealizedFull {
fn push_state(&mut self, state: &CohortState<RealizedState, CostBasisData<WithCapital>>) {
self.push_state(state)
}
fn compute_rest_part1(&mut self, prices: &prices::Vecs, starting_indexes: &Indexes, exit: &Exit) -> Result<()> {
self.compute_rest_part1(prices, starting_indexes, exit)
fn compute_rest_part1(&mut self, starting_indexes: &Indexes, exit: &Exit) -> Result<()> {
self.compute_rest_part1(starting_indexes, exit)
}
fn compute_from_stateful(&mut self, starting_indexes: &Indexes, others: &[&RealizedCore], exit: &Exit) -> Result<()> {
self.compute_from_stateful(starting_indexes, others, exit)

View File

@@ -71,7 +71,6 @@ impl RealizedOps for MinimalRealizedState {
Cents::new((self.loss_raw / Sats::ONE_BTC_U128) as u64)
}
#[inline]
#[inline]
fn value_destroyed(&self) -> Cents {
if self.value_destroyed_raw == 0 {

View File

@@ -128,7 +128,7 @@ impl Vecs {
.height
.compute_transform2(
starting_indexes.height,
&all_activity.dormancy.height,
&all_activity.dormancy._24h.height,
supply_total_sats,
|(i, dormancy, supply_sats, ..)| {
let supply = f64::from(Bitcoin::from(supply_sats));
@@ -164,7 +164,7 @@ impl Vecs {
self.dormancy.flow.height.compute_transform2(
starting_indexes.height,
supply_total_sats,
&all_activity.dormancy.height,
&all_activity.dormancy._24h.height,
|(i, supply_sats, dormancy, ..)| {
let d = f64::from(dormancy);
if d == 0.0 {