global: snapshot

This commit is contained in:
nym21
2026-03-07 11:42:11 +01:00
parent 5a73f1a88e
commit bf07570848
31 changed files with 1151 additions and 1009 deletions
@@ -8,11 +8,6 @@
//! | `sending` | Unique addresses that sent this block |
//! | `reactivated` | Addresses that were empty and now have funds |
//! | `both` | Addresses that both sent AND received same block |
//! | `balance_increased` | Receive-only addresses (balance definitely increased) |
//! | `balance_decreased` | Send-only addresses (balance definitely decreased) |
//!
//! Note: `balance_increased` and `balance_decreased` exclude "both" addresses
//! since their net balance change requires more complex tracking.
use brk_cohort::ByAddressType;
use brk_error::Result;
@@ -24,14 +19,10 @@ use vecdb::{AnyStoredVec, AnyVec, Database, Exit, Rw, StorageMode, WritableVec};
use crate::{
indexes,
internal::{ComputedFromHeightDistribution, WindowStarts},
internal::{ComputedFromHeightRollingAverage, WindowStarts},
};
/// Per-block activity counts - reset each block.
///
/// Note: `balance_increased` and `balance_decreased` are derived:
/// - `balance_increased = receiving - both` (receive-only addresses)
/// - `balance_decreased = sending - both` (send-only addresses)
#[derive(Debug, Default, Clone)]
pub struct BlockActivityCounts {
pub reactivated: u32,
@@ -74,12 +65,10 @@ impl AddressTypeToActivityCounts {
/// Activity count vectors for a single category (e.g., one address type or "all").
#[derive(Traversable)]
pub struct ActivityCountVecs<M: StorageMode = Rw> {
pub reactivated: ComputedFromHeightDistribution<StoredU32, M>,
pub sending: ComputedFromHeightDistribution<StoredU32, M>,
pub receiving: ComputedFromHeightDistribution<StoredU32, M>,
pub balance_increased: ComputedFromHeightDistribution<StoredU32, M>,
pub balance_decreased: ComputedFromHeightDistribution<StoredU32, M>,
pub both: ComputedFromHeightDistribution<StoredU32, M>,
pub reactivated: ComputedFromHeightRollingAverage<StoredU32, M>,
pub sending: ComputedFromHeightRollingAverage<StoredU32, M>,
pub receiving: ComputedFromHeightRollingAverage<StoredU32, M>,
pub both: ComputedFromHeightRollingAverage<StoredU32, M>,
}
impl ActivityCountVecs {
@@ -90,37 +79,25 @@ impl ActivityCountVecs {
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
reactivated: ComputedFromHeightDistribution::forced_import(
reactivated: ComputedFromHeightRollingAverage::forced_import(
db,
&format!("{name}_reactivated"),
version,
indexes,
)?,
sending: ComputedFromHeightDistribution::forced_import(
sending: ComputedFromHeightRollingAverage::forced_import(
db,
&format!("{name}_sending"),
version,
indexes,
)?,
receiving: ComputedFromHeightDistribution::forced_import(
receiving: ComputedFromHeightRollingAverage::forced_import(
db,
&format!("{name}_receiving"),
version,
indexes,
)?,
balance_increased: ComputedFromHeightDistribution::forced_import(
db,
&format!("{name}_balance_increased"),
version,
indexes,
)?,
balance_decreased: ComputedFromHeightDistribution::forced_import(
db,
&format!("{name}_balance_decreased"),
version,
indexes,
)?,
both: ComputedFromHeightDistribution::forced_import(
both: ComputedFromHeightRollingAverage::forced_import(
db,
&format!("{name}_both"),
version,
@@ -135,8 +112,6 @@ impl ActivityCountVecs {
.len()
.min(self.sending.height.len())
.min(self.receiving.height.len())
.min(self.balance_increased.height.len())
.min(self.balance_decreased.height.len())
.min(self.both.height.len())
}
@@ -147,8 +122,6 @@ impl ActivityCountVecs {
&mut self.reactivated.height as &mut dyn AnyStoredVec,
&mut self.sending.height as &mut dyn AnyStoredVec,
&mut self.receiving.height as &mut dyn AnyStoredVec,
&mut self.balance_increased.height as &mut dyn AnyStoredVec,
&mut self.balance_decreased.height as &mut dyn AnyStoredVec,
&mut self.both.height as &mut dyn AnyStoredVec,
]
.into_par_iter()
@@ -158,8 +131,6 @@ impl ActivityCountVecs {
self.reactivated.height.reset()?;
self.sending.height.reset()?;
self.receiving.height.reset()?;
self.balance_increased.height.reset()?;
self.balance_decreased.height.reset()?;
self.both.height.reset()?;
Ok(())
}
@@ -178,14 +149,6 @@ impl ActivityCountVecs {
self.receiving
.height
.truncate_push(height, counts.receiving.into())?;
// Derived: balance_increased = receiving - both (receive-only addresses)
self.balance_increased
.height
.truncate_push(height, (counts.receiving - counts.both).into())?;
// Derived: balance_decreased = sending - both (send-only addresses)
self.balance_decreased
.height
.truncate_push(height, (counts.sending - counts.both).into())?;
self.both.height.truncate_push(height, counts.both.into())?;
Ok(())
}
@@ -199,10 +162,6 @@ impl ActivityCountVecs {
self.reactivated.compute_rest(max_from, windows, exit)?;
self.sending.compute_rest(max_from, windows, exit)?;
self.receiving.compute_rest(max_from, windows, exit)?;
self.balance_increased
.compute_rest(max_from, windows, exit)?;
self.balance_decreased
.compute_rest(max_from, windows, exit)?;
self.both.compute_rest(max_from, windows, exit)?;
Ok(())
}
@@ -254,8 +213,6 @@ impl AddressTypeToActivityCountVecs {
vecs.push(&mut type_vecs.reactivated.height);
vecs.push(&mut type_vecs.sending.height);
vecs.push(&mut type_vecs.receiving.height);
vecs.push(&mut type_vecs.balance_increased.height);
vecs.push(&mut type_vecs.balance_decreased.height);
vecs.push(&mut type_vecs.both.height);
}
vecs.into_par_iter()
@@ -11,7 +11,6 @@ use crate::{
distribution::state::RealizedOps,
internal::{
ComputedFromHeight, ComputedFromHeightCumulative,
ComputedFromHeightRatioPercentiles, FiatFromHeight,
LazyFromHeight, NegCentsUnsignedToDollars, RatioCents64,
RollingWindows, ValueFromHeightCumulative,
},
@@ -33,7 +32,6 @@ pub struct RealizedBase<M: StorageMode = Rw> {
pub neg_realized_loss: LazyFromHeight<Dollars, Cents>,
pub net_realized_pnl: ComputedFromHeightCumulative<CentsSigned, M>,
pub gross_pnl: FiatFromHeight<Cents, M>,
pub value_created: ComputedFromHeight<Cents, M>,
pub value_destroyed: ComputedFromHeight<Cents, M>,
@@ -41,8 +39,6 @@ pub struct RealizedBase<M: StorageMode = Rw> {
pub value_destroyed_sum: RollingWindows<Cents, M>,
pub sopr: RollingWindows<StoredF64, M>,
pub realized_price_ratio_percentiles: ComputedFromHeightRatioPercentiles<M>,
pub sent_in_profit: ValueFromHeightCumulative<M>,
pub sent_in_loss: ValueFromHeightCumulative<M>,
}
@@ -62,7 +58,6 @@ impl RealizedBase {
);
let net_realized_pnl = cfg.import("net_realized_pnl", v0)?;
let gross_pnl = cfg.import("realized_gross_pnl", v0)?;
let value_created = cfg.import("value_created", v0)?;
let value_destroyed = cfg.import("value_destroyed", v0)?;
@@ -70,26 +65,16 @@ impl RealizedBase {
let value_destroyed_sum = cfg.import("value_destroyed", v1)?;
let sopr = cfg.import("sopr", v1)?;
let realized_price_ratio_percentiles =
ComputedFromHeightRatioPercentiles::forced_import(
cfg.db,
&cfg.name("realized_price"),
cfg.version + v1,
cfg.indexes,
)?;
Ok(Self {
minimal,
realized_cap_change_1m: cfg.import("realized_cap_change_1m", v0)?,
neg_realized_loss,
net_realized_pnl,
gross_pnl,
value_created,
value_destroyed,
value_created_sum,
value_destroyed_sum,
sopr,
realized_price_ratio_percentiles,
sent_in_profit: cfg.import("sent_in_profit", v0)?,
sent_in_loss: cfg.import("sent_in_loss", v0)?,
})
@@ -176,13 +161,6 @@ impl RealizedBase {
Ok(())
})?;
self.gross_pnl.cents.height.compute_add(
starting_indexes.height,
&self.minimal.realized_profit.height,
&self.minimal.realized_loss.height,
exit,
)?;
Ok(())
}
@@ -234,15 +212,6 @@ impl RealizedBase {
)?;
}
// Realized price ratio percentiles
self.realized_price_ratio_percentiles.compute(
blocks,
starting_indexes,
exit,
&self.minimal.realized_price_ratio.ratio.height,
&self.minimal.realized_price.cents.height,
)?;
Ok(())
}
}
@@ -14,7 +14,7 @@ use crate::{
blocks,
distribution::state::RealizedState,
internal::{
CentsUnsignedToDollars, ComputedFromHeight, ComputedFromHeightCumulative,
CentsUnsignedToDollars, ComputedFromHeight, ComputedFromHeightCumulative, FiatFromHeight,
ComputedFromHeightRatio, ComputedFromHeightRatioPercentiles,
ComputedFromHeightRatioStdDevBands, LazyFromHeight, PercentFromHeight,
PercentRollingEmas1w1m, PercentRollingWindows, Price, RatioCents64, RatioCentsBp32,
@@ -35,6 +35,8 @@ pub struct RealizedFull<M: StorageMode = Rw> {
#[traversable(flatten)]
pub core: RealizedBase<M>,
pub gross_pnl: FiatFromHeight<Cents, M>,
pub realized_profit_rel_to_realized_cap: PercentFromHeight<BasisPoints32, M>,
pub realized_loss_rel_to_realized_cap: PercentFromHeight<BasisPoints32, M>,
pub net_realized_pnl_rel_to_realized_cap: PercentFromHeight<BasisPointsSigned32, M>,
@@ -83,6 +85,7 @@ pub struct RealizedFull<M: StorageMode = Rw> {
pub sent_in_profit_ema: RollingEmas2w<M>,
pub sent_in_loss_ema: RollingEmas2w<M>,
pub realized_price_ratio_percentiles: ComputedFromHeightRatioPercentiles<M>,
pub realized_price_ratio_std_dev: ComputedFromHeightRatioStdDevBands<M>,
pub investor_price_ratio_percentiles: ComputedFromHeightRatioPercentiles<M>,
}
@@ -94,6 +97,8 @@ impl RealizedFull {
let core = RealizedBase::forced_import(cfg)?;
let gross_pnl = cfg.import("realized_gross_pnl", v0)?;
let profit_value_created = cfg.import("profit_value_created", v0)?;
let profit_value_destroyed: ComputedFromHeight<Cents> =
cfg.import("profit_value_destroyed", v0)?;
@@ -154,6 +159,7 @@ impl RealizedFull {
Ok(Self {
core,
gross_pnl,
realized_profit_rel_to_realized_cap,
realized_loss_rel_to_realized_cap,
net_realized_pnl_rel_to_realized_cap,
@@ -191,6 +197,12 @@ impl RealizedFull {
sopr_24h_ema,
sent_in_profit_ema,
sent_in_loss_ema,
realized_price_ratio_percentiles: ComputedFromHeightRatioPercentiles::forced_import(
cfg.db,
&realized_price_name,
realized_price_version,
cfg.indexes,
)?,
realized_price_ratio_std_dev: ComputedFromHeightRatioStdDevBands::forced_import(
cfg.db,
&realized_price_name,
@@ -366,12 +378,19 @@ impl RealizedFull {
exit,
)?;
// Gross PnL rolling sum
// Gross PnL
self.gross_pnl.cents.height.compute_add(
starting_indexes.height,
&self.core.minimal.realized_profit.height,
&self.core.minimal.realized_loss.height,
exit,
)?;
let window_starts = blocks.count.window_starts();
self.gross_pnl_sum.compute_rolling_sum(
starting_indexes.height,
&window_starts,
&self.core.gross_pnl.cents.height,
&self.gross_pnl.cents.height,
exit,
)?;
@@ -510,7 +529,14 @@ impl RealizedFull {
)?;
}
// Realized price stddev bands
self.realized_price_ratio_percentiles.compute(
blocks,
starting_indexes,
exit,
&self.core.minimal.realized_price_ratio.ratio.height,
&self.core.minimal.realized_price.cents.height,
)?;
self.realized_price_ratio_std_dev.compute(
blocks,
starting_indexes,
@@ -3,9 +3,7 @@ use brk_traversable::Traversable;
use brk_types::{BasisPoints16, BasisPoints32, BasisPointsSigned32, Dollars, Height, Version};
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
use crate::internal::{
NegRatioDollarsBps32, PercentFromHeight, RatioDollarsBp16, RatioDollarsBp32, RatioDollarsBps32,
};
use crate::internal::{PercentFromHeight, RatioDollarsBp16, RatioDollarsBp32, RatioDollarsBps32};
use crate::distribution::metrics::{ImportConfig, UnrealizedFull};
@@ -14,7 +12,6 @@ use crate::distribution::metrics::{ImportConfig, UnrealizedFull};
pub struct RelativeExtendedOwnMarketCap<M: StorageMode = Rw> {
pub unrealized_profit_rel_to_own_market_cap: PercentFromHeight<BasisPoints16, M>,
pub unrealized_loss_rel_to_own_market_cap: PercentFromHeight<BasisPoints32, M>,
pub neg_unrealized_loss_rel_to_own_market_cap: PercentFromHeight<BasisPointsSigned32, M>,
pub net_unrealized_pnl_rel_to_own_market_cap: PercentFromHeight<BasisPointsSigned32, M>,
}
@@ -27,8 +24,6 @@ impl RelativeExtendedOwnMarketCap {
.import("unrealized_profit_rel_to_own_market_cap", v2)?,
unrealized_loss_rel_to_own_market_cap: cfg
.import("unrealized_loss_rel_to_own_market_cap", Version::new(3))?,
neg_unrealized_loss_rel_to_own_market_cap: cfg
.import("neg_unrealized_loss_rel_to_own_market_cap", Version::new(3))?,
net_unrealized_pnl_rel_to_own_market_cap: cfg
.import("net_unrealized_pnl_rel_to_own_market_cap", Version::new(3))?,
})
@@ -55,13 +50,6 @@ impl RelativeExtendedOwnMarketCap {
own_market_cap,
exit,
)?;
self.neg_unrealized_loss_rel_to_own_market_cap
.compute_binary::<Dollars, Dollars, NegRatioDollarsBps32>(
max_from,
&unrealized.unrealized_loss.usd.height,
own_market_cap,
exit,
)?;
self.net_unrealized_pnl_rel_to_own_market_cap
.compute_binary::<Dollars, Dollars, RatioDollarsBps32>(
max_from,
@@ -3,9 +3,7 @@ use brk_traversable::Traversable;
use brk_types::{BasisPoints16, BasisPointsSigned32, Dollars, Height, Version};
use vecdb::{Exit, Rw, StorageMode};
use crate::internal::{
NegRatioDollarsBps32, PercentFromHeight, RatioDollarsBp16, RatioDollarsBps32,
};
use crate::internal::{PercentFromHeight, RatioDollarsBp16, RatioDollarsBps32};
use crate::distribution::metrics::{ImportConfig, UnrealizedFull};
@@ -14,7 +12,6 @@ use crate::distribution::metrics::{ImportConfig, UnrealizedFull};
pub struct RelativeExtendedOwnPnl<M: StorageMode = Rw> {
pub unrealized_profit_rel_to_own_gross_pnl: PercentFromHeight<BasisPoints16, M>,
pub unrealized_loss_rel_to_own_gross_pnl: PercentFromHeight<BasisPoints16, M>,
pub neg_unrealized_loss_rel_to_own_gross_pnl: PercentFromHeight<BasisPointsSigned32, M>,
pub net_unrealized_pnl_rel_to_own_gross_pnl: PercentFromHeight<BasisPointsSigned32, M>,
}
@@ -27,8 +24,6 @@ impl RelativeExtendedOwnPnl {
.import("unrealized_profit_rel_to_own_gross_pnl", v1)?,
unrealized_loss_rel_to_own_gross_pnl: cfg
.import("unrealized_loss_rel_to_own_gross_pnl", v1)?,
neg_unrealized_loss_rel_to_own_gross_pnl: cfg
.import("neg_unrealized_loss_rel_to_own_gross_pnl", Version::new(2))?,
net_unrealized_pnl_rel_to_own_gross_pnl: cfg
.import("net_unrealized_pnl_rel_to_own_gross_pnl", Version::new(3))?,
})
@@ -54,13 +49,6 @@ impl RelativeExtendedOwnPnl {
&unrealized.gross_pnl.usd.height,
exit,
)?;
self.neg_unrealized_loss_rel_to_own_gross_pnl
.compute_binary::<Dollars, Dollars, NegRatioDollarsBps32>(
max_from,
&unrealized.unrealized_loss.usd.height,
&unrealized.gross_pnl.usd.height,
exit,
)?;
self.net_unrealized_pnl_rel_to_own_gross_pnl
.compute_binary::<Dollars, Dollars, RatioDollarsBps32>(
max_from,
@@ -7,8 +7,7 @@ use derive_more::{Deref, DerefMut};
use vecdb::{Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode};
use crate::internal::{
Bps32ToFloat, LazyFromHeight, NegRatioDollarsBps32, PercentFromHeight, RatioDollarsBp16,
RatioDollarsBps32,
Bps32ToFloat, LazyFromHeight, PercentFromHeight, RatioDollarsBp16, RatioDollarsBps32,
};
use crate::distribution::metrics::{ImportConfig, RealizedBase, UnrealizedFull};
@@ -26,7 +25,6 @@ pub struct RelativeFull<M: StorageMode = Rw> {
pub unrealized_profit_rel_to_market_cap: PercentFromHeight<BasisPoints16, M>,
pub unrealized_loss_rel_to_market_cap: PercentFromHeight<BasisPoints16, M>,
pub net_unrealized_pnl_rel_to_market_cap: PercentFromHeight<BasisPointsSigned32, M>,
pub neg_unrealized_loss_rel_to_market_cap: PercentFromHeight<BasisPointsSigned32, M>,
pub nupl: LazyFromHeight<StoredF32, BasisPointsSigned32>,
pub invested_capital_in_profit_rel_to_realized_cap: PercentFromHeight<BasisPoints16, M>,
@@ -60,8 +58,6 @@ impl RelativeFull {
unrealized_loss_rel_to_market_cap: cfg
.import("unrealized_loss_rel_to_market_cap", v2)?,
net_unrealized_pnl_rel_to_market_cap,
neg_unrealized_loss_rel_to_market_cap: cfg
.import("neg_unrealized_loss_rel_to_market_cap", v3)?,
nupl,
invested_capital_in_profit_rel_to_realized_cap: cfg.import(
"invested_capital_in_profit_rel_to_realized_cap",
@@ -111,14 +107,6 @@ impl RelativeFull {
market_cap,
exit,
)?;
self.neg_unrealized_loss_rel_to_market_cap
.compute_binary::<Dollars, Dollars, NegRatioDollarsBps32>(
max_from,
&unrealized.unrealized_loss.usd.height,
market_cap,
exit,
)?;
self.invested_capital_in_profit_rel_to_realized_cap
.compute_binary::<Dollars, Dollars, RatioDollarsBp16>(
max_from,
@@ -29,8 +29,6 @@ pub struct UnrealizedBase<M: StorageMode = Rw> {
pub neg_unrealized_loss: LazyFromHeight<Dollars, Cents>,
pub gross_pnl: FiatFromHeight<Cents, M>,
pub net_unrealized_pnl: FiatFromHeight<CentsSigned, M>,
}
@@ -50,8 +48,6 @@ impl UnrealizedBase {
&unrealized_loss.cents,
);
let gross_pnl = cfg.import("unrealized_gross_pnl", v0)?;
let net_unrealized_pnl = cfg.import("net_unrealized_pnl", v0)?;
Ok(Self {
@@ -60,7 +56,6 @@ impl UnrealizedBase {
unrealized_profit,
unrealized_loss,
neg_unrealized_loss,
gross_pnl,
net_unrealized_pnl,
})
}
@@ -131,13 +126,6 @@ impl UnrealizedBase {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.gross_pnl.cents.height.compute_add(
starting_indexes.height,
&self.unrealized_profit.cents.height,
&self.unrealized_loss.cents.height,
exit,
)?;
self.net_unrealized_pnl
.cents
.height
@@ -26,7 +26,8 @@ pub struct UnrealizedFull<M: StorageMode = Rw> {
#[traversable(flatten)]
pub base: UnrealizedBase<M>,
// --- Source-only fields ---
pub gross_pnl: FiatFromHeight<Cents, M>,
pub invested_capital_in_profit: FiatFromHeight<Cents, M>,
pub invested_capital_in_loss: FiatFromHeight<Cents, M>,
@@ -47,6 +48,8 @@ impl UnrealizedFull {
let base = UnrealizedBase::forced_import(cfg)?;
let gross_pnl = cfg.import("unrealized_gross_pnl", v0)?;
let invested_capital_in_profit = cfg.import("invested_capital_in_profit", v0)?;
let invested_capital_in_loss = cfg.import("invested_capital_in_loss", v0)?;
@@ -62,6 +65,7 @@ impl UnrealizedFull {
Ok(Self {
base,
gross_pnl,
invested_capital_in_profit,
invested_capital_in_loss,
invested_capital_in_profit_raw,
@@ -218,10 +222,16 @@ impl UnrealizedFull {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
// Complete-tier: net_unrealized_pnl
self.base.compute_rest(starting_indexes, exit)?;
// Extended-only: Pain index (investor_price_of_losers - spot)
self.gross_pnl.cents.height.compute_add(
starting_indexes.height,
&self.base.unrealized_profit.cents.height,
&self.base.unrealized_loss.cents.height,
exit,
)?;
// Pain index (investor_price_of_losers - spot)
self.pain_index.cents.height.compute_transform3(
starting_indexes.height,
&self.investor_cap_in_loss_raw,