mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: snapshot
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,68 +1,37 @@
|
|||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{Bitcoin, Height, Indexes, Sats, StoredF64, Version};
|
use brk_types::{Height, Indexes, Sats, Version};
|
||||||
use derive_more::{Deref, DerefMut};
|
|
||||||
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
|
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
|
||||||
|
|
||||||
use crate::internal::ComputedFromHeightCumulativeSum;
|
use crate::internal::{RollingEmas2w, ValueFromHeightCumulative};
|
||||||
|
|
||||||
use crate::{blocks, distribution::metrics::ImportConfig, prices};
|
use crate::{blocks, distribution::metrics::ImportConfig, prices};
|
||||||
|
|
||||||
use super::ActivityCore;
|
#[derive(Traversable)]
|
||||||
|
pub struct ActivityBase<M: StorageMode = Rw> {
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
pub sent: ValueFromHeightCumulative<M>,
|
||||||
pub struct ActivityMetrics<M: StorageMode = Rw> {
|
pub sent_ema: RollingEmas2w<M>,
|
||||||
#[deref]
|
|
||||||
#[deref_mut]
|
|
||||||
#[traversable(flatten)]
|
|
||||||
pub core: ActivityCore<M>,
|
|
||||||
|
|
||||||
pub coinblocks_destroyed: ComputedFromHeightCumulativeSum<StoredF64, M>,
|
|
||||||
pub coindays_destroyed: ComputedFromHeightCumulativeSum<StoredF64, M>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActivityMetrics {
|
impl ActivityBase {
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
core: ActivityCore::forced_import(cfg)?,
|
sent: cfg.import_value_cumulative("sent", Version::ZERO)?,
|
||||||
coinblocks_destroyed: cfg
|
sent_ema: cfg.import_emas_2w("sent", Version::ZERO)?,
|
||||||
.import_cumulative_sum("coinblocks_destroyed", Version::ONE)?,
|
|
||||||
coindays_destroyed: cfg.import_cumulative_sum("coindays_destroyed", Version::ONE)?,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn min_len(&self) -> usize {
|
pub(crate) fn min_len(&self) -> usize {
|
||||||
self.core
|
self.sent.base.sats.height.len()
|
||||||
.min_len()
|
|
||||||
.min(self.coinblocks_destroyed.height.len())
|
|
||||||
.min(self.coindays_destroyed.height.len())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn truncate_push(
|
pub(crate) fn truncate_push(&mut self, height: Height, sent: Sats) -> Result<()> {
|
||||||
&mut self,
|
self.sent.base.sats.height.truncate_push(height, sent)?;
|
||||||
height: Height,
|
|
||||||
sent: Sats,
|
|
||||||
satblocks_destroyed: Sats,
|
|
||||||
satdays_destroyed: Sats,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.core.truncate_push(height, sent)?;
|
|
||||||
self.coinblocks_destroyed.height.truncate_push(
|
|
||||||
height,
|
|
||||||
StoredF64::from(Bitcoin::from(satblocks_destroyed)),
|
|
||||||
)?;
|
|
||||||
self.coindays_destroyed.height.truncate_push(
|
|
||||||
height,
|
|
||||||
StoredF64::from(Bitcoin::from(satdays_destroyed)),
|
|
||||||
)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||||
vec![
|
vec![&mut self.sent.base.sats.height as &mut dyn AnyStoredVec]
|
||||||
&mut self.core.sent.base.sats.height as &mut dyn AnyStoredVec,
|
|
||||||
&mut self.coinblocks_destroyed.height as &mut dyn AnyStoredVec,
|
|
||||||
&mut self.coindays_destroyed.height as &mut dyn AnyStoredVec,
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn validate_computed_versions(&mut self, _base_version: Version) -> Result<()> {
|
pub(crate) fn validate_computed_versions(&mut self, _base_version: Version) -> Result<()> {
|
||||||
@@ -75,12 +44,14 @@ impl ActivityMetrics {
|
|||||||
others: &[&Self],
|
others: &[&Self],
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let core_refs: Vec<&ActivityCore> = others.iter().map(|o| &o.core).collect();
|
self.sent.base.sats.height.compute_sum_of_others(
|
||||||
self.core
|
starting_indexes.height,
|
||||||
.compute_from_stateful(starting_indexes, &core_refs, exit)?;
|
&others
|
||||||
|
.iter()
|
||||||
sum_others!(self, starting_indexes, others, exit; coinblocks_destroyed.height);
|
.map(|v| &v.sent.base.sats.height)
|
||||||
sum_others!(self, starting_indexes, others, exit; coindays_destroyed.height);
|
.collect::<Vec<_>>(),
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,16 +62,16 @@ impl ActivityMetrics {
|
|||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.core
|
self.sent
|
||||||
.compute_rest_part1(blocks, prices, starting_indexes, exit)?;
|
.compute(prices, starting_indexes.height, exit)?;
|
||||||
|
|
||||||
let window_starts = blocks.count.window_starts();
|
self.sent_ema.compute(
|
||||||
|
starting_indexes.height,
|
||||||
self.coinblocks_destroyed
|
&blocks.count.height_2w_ago,
|
||||||
.compute_rest(starting_indexes.height, &window_starts, exit)?;
|
&self.sent.base.sats.height,
|
||||||
|
&self.sent.base.cents.height,
|
||||||
self.coindays_destroyed
|
exit,
|
||||||
.compute_rest(starting_indexes.height, &window_starts, exit)?;
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
use brk_error::Result;
|
|
||||||
use brk_traversable::Traversable;
|
|
||||||
use brk_types::{Height, Indexes, Sats, Version};
|
|
||||||
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
|
|
||||||
|
|
||||||
use crate::internal::{RollingEmas2w, ValueFromHeightCumulative};
|
|
||||||
|
|
||||||
use crate::{blocks, distribution::metrics::ImportConfig, prices};
|
|
||||||
|
|
||||||
#[derive(Traversable)]
|
|
||||||
pub struct ActivityCore<M: StorageMode = Rw> {
|
|
||||||
pub sent: ValueFromHeightCumulative<M>,
|
|
||||||
pub sent_ema: RollingEmas2w<M>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ActivityCore {
|
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
|
||||||
Ok(Self {
|
|
||||||
sent: cfg.import_value_cumulative("sent", Version::ZERO)?,
|
|
||||||
sent_ema: cfg.import_emas_2w("sent", Version::ZERO)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn min_len(&self) -> usize {
|
|
||||||
self.sent.base.sats.height.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn truncate_push(&mut self, height: Height, sent: Sats) -> Result<()> {
|
|
||||||
self.sent.base.sats.height.truncate_push(height, sent)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
|
||||||
vec![&mut self.sent.base.sats.height as &mut dyn AnyStoredVec]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn validate_computed_versions(&mut self, _base_version: Version) -> Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute_from_stateful(
|
|
||||||
&mut self,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
others: &[&Self],
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.sent.base.sats.height.compute_sum_of_others(
|
|
||||||
starting_indexes.height,
|
|
||||||
&others
|
|
||||||
.iter()
|
|
||||||
.map(|v| &v.sent.base.sats.height)
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute_rest_part1(
|
|
||||||
&mut self,
|
|
||||||
blocks: &blocks::Vecs,
|
|
||||||
prices: &prices::Vecs,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.sent
|
|
||||||
.compute(prices, starting_indexes.height, exit)?;
|
|
||||||
|
|
||||||
self.sent_ema.compute(
|
|
||||||
starting_indexes.height,
|
|
||||||
&blocks.count.height_2w_ago,
|
|
||||||
&self.sent.base.sats.height,
|
|
||||||
&self.sent.base.cents.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
107
crates/brk_computer/src/distribution/metrics/activity/full.rs
Normal file
107
crates/brk_computer/src/distribution/metrics/activity/full.rs
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
use brk_error::Result;
|
||||||
|
use brk_traversable::Traversable;
|
||||||
|
use brk_types::{Bitcoin, Height, Indexes, Sats, StoredF64, Version};
|
||||||
|
use derive_more::{Deref, DerefMut};
|
||||||
|
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
|
||||||
|
|
||||||
|
use crate::internal::ComputedFromHeightCumulativeSum;
|
||||||
|
|
||||||
|
use crate::{blocks, distribution::metrics::ImportConfig, prices};
|
||||||
|
|
||||||
|
use super::ActivityBase;
|
||||||
|
|
||||||
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
|
pub struct ActivityFull<M: StorageMode = Rw> {
|
||||||
|
#[deref]
|
||||||
|
#[deref_mut]
|
||||||
|
#[traversable(flatten)]
|
||||||
|
pub base: ActivityBase<M>,
|
||||||
|
|
||||||
|
pub coinblocks_destroyed: ComputedFromHeightCumulativeSum<StoredF64, M>,
|
||||||
|
pub coindays_destroyed: ComputedFromHeightCumulativeSum<StoredF64, M>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActivityFull {
|
||||||
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
|
Ok(Self {
|
||||||
|
base: ActivityBase::forced_import(cfg)?,
|
||||||
|
coinblocks_destroyed: cfg
|
||||||
|
.import_cumulative_sum("coinblocks_destroyed", Version::ONE)?,
|
||||||
|
coindays_destroyed: cfg.import_cumulative_sum("coindays_destroyed", Version::ONE)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn min_len(&self) -> usize {
|
||||||
|
self.base
|
||||||
|
.min_len()
|
||||||
|
.min(self.coinblocks_destroyed.height.len())
|
||||||
|
.min(self.coindays_destroyed.height.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn truncate_push(
|
||||||
|
&mut self,
|
||||||
|
height: Height,
|
||||||
|
sent: Sats,
|
||||||
|
satblocks_destroyed: Sats,
|
||||||
|
satdays_destroyed: Sats,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.base.truncate_push(height, sent)?;
|
||||||
|
self.coinblocks_destroyed.height.truncate_push(
|
||||||
|
height,
|
||||||
|
StoredF64::from(Bitcoin::from(satblocks_destroyed)),
|
||||||
|
)?;
|
||||||
|
self.coindays_destroyed.height.truncate_push(
|
||||||
|
height,
|
||||||
|
StoredF64::from(Bitcoin::from(satdays_destroyed)),
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||||
|
vec![
|
||||||
|
&mut self.base.sent.base.sats.height as &mut dyn AnyStoredVec,
|
||||||
|
&mut self.coinblocks_destroyed.height as &mut dyn AnyStoredVec,
|
||||||
|
&mut self.coindays_destroyed.height as &mut dyn AnyStoredVec,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn validate_computed_versions(&mut self, _base_version: Version) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compute_from_stateful(
|
||||||
|
&mut self,
|
||||||
|
starting_indexes: &Indexes,
|
||||||
|
others: &[&Self],
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()> {
|
||||||
|
let core_refs: Vec<&ActivityBase> = others.iter().map(|o| &o.base).collect();
|
||||||
|
self.base
|
||||||
|
.compute_from_stateful(starting_indexes, &core_refs, exit)?;
|
||||||
|
|
||||||
|
sum_others!(self, starting_indexes, others, exit; coinblocks_destroyed.height);
|
||||||
|
sum_others!(self, starting_indexes, others, exit; coindays_destroyed.height);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compute_rest_part1(
|
||||||
|
&mut self,
|
||||||
|
blocks: &blocks::Vecs,
|
||||||
|
prices: &prices::Vecs,
|
||||||
|
starting_indexes: &Indexes,
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.base
|
||||||
|
.compute_rest_part1(blocks, prices, starting_indexes, exit)?;
|
||||||
|
|
||||||
|
let window_starts = blocks.count.window_starts();
|
||||||
|
|
||||||
|
self.coinblocks_destroyed
|
||||||
|
.compute_rest(starting_indexes.height, &window_starts, exit)?;
|
||||||
|
|
||||||
|
self.coindays_destroyed
|
||||||
|
.compute_rest(starting_indexes.height, &window_starts, exit)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
mod base;
|
mod base;
|
||||||
mod core;
|
mod full;
|
||||||
|
|
||||||
pub use base::*;
|
pub use base::*;
|
||||||
pub use core::*;
|
pub use full::*;
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ use crate::{blocks, prices};
|
|||||||
use crate::internal::ComputedFromHeight;
|
use crate::internal::ComputedFromHeight;
|
||||||
|
|
||||||
use crate::distribution::metrics::{
|
use crate::distribution::metrics::{
|
||||||
ActivityMetrics, CostBasisWithExtended, ImportConfig, OutputsMetrics, RealizedAdjusted,
|
ActivityFull, CostBasisWithExtended, ImportConfig, OutputsMetrics, RealizedAdjusted,
|
||||||
RealizedWithExtended, RelativeForAll, SupplyMetrics, UnrealizedFull,
|
RealizedFull, RelativeForAll, SupplyMetrics, UnrealizedFull,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// All-cohort metrics: extended realized + adjusted (as composable add-on),
|
/// All-cohort metrics: extended realized + adjusted (as composable add-on),
|
||||||
@@ -22,8 +22,8 @@ pub struct AllCohortMetrics<M: StorageMode = Rw> {
|
|||||||
pub filter: Filter,
|
pub filter: Filter,
|
||||||
pub supply: Box<SupplyMetrics<M>>,
|
pub supply: Box<SupplyMetrics<M>>,
|
||||||
pub outputs: Box<OutputsMetrics<M>>,
|
pub outputs: Box<OutputsMetrics<M>>,
|
||||||
pub activity: Box<ActivityMetrics<M>>,
|
pub activity: Box<ActivityFull<M>>,
|
||||||
pub realized: Box<RealizedWithExtended<M>>,
|
pub realized: Box<RealizedFull<M>>,
|
||||||
pub cost_basis: Box<CostBasisWithExtended<M>>,
|
pub cost_basis: Box<CostBasisWithExtended<M>>,
|
||||||
pub unrealized: Box<UnrealizedFull<M>>,
|
pub unrealized: Box<UnrealizedFull<M>>,
|
||||||
pub adjusted: Box<RealizedAdjusted<M>>,
|
pub adjusted: Box<RealizedAdjusted<M>>,
|
||||||
@@ -44,7 +44,7 @@ impl AllCohortMetrics {
|
|||||||
supply: SupplyMetrics,
|
supply: SupplyMetrics,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let unrealized = UnrealizedFull::forced_import(cfg)?;
|
let unrealized = UnrealizedFull::forced_import(cfg)?;
|
||||||
let realized = RealizedWithExtended::forced_import(cfg)?;
|
let realized = RealizedFull::forced_import(cfg)?;
|
||||||
let adjusted = RealizedAdjusted::forced_import(cfg)?;
|
let adjusted = RealizedAdjusted::forced_import(cfg)?;
|
||||||
|
|
||||||
let relative = RelativeForAll::forced_import(cfg)?;
|
let relative = RelativeForAll::forced_import(cfg)?;
|
||||||
@@ -53,7 +53,7 @@ impl AllCohortMetrics {
|
|||||||
filter: cfg.filter.clone(),
|
filter: cfg.filter.clone(),
|
||||||
supply: Box::new(supply),
|
supply: Box::new(supply),
|
||||||
outputs: Box::new(OutputsMetrics::forced_import(cfg)?),
|
outputs: Box::new(OutputsMetrics::forced_import(cfg)?),
|
||||||
activity: Box::new(ActivityMetrics::forced_import(cfg)?),
|
activity: Box::new(ActivityFull::forced_import(cfg)?),
|
||||||
realized: Box::new(realized),
|
realized: Box::new(realized),
|
||||||
cost_basis: Box::new(CostBasisWithExtended::forced_import(cfg)?),
|
cost_basis: Box::new(CostBasisWithExtended::forced_import(cfg)?),
|
||||||
unrealized: Box::new(unrealized),
|
unrealized: Box::new(unrealized),
|
||||||
@@ -97,7 +97,7 @@ impl AllCohortMetrics {
|
|||||||
self.relative.compute(
|
self.relative.compute(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.unrealized,
|
&self.unrealized,
|
||||||
&self.realized.base,
|
&self.realized,
|
||||||
&self.supply.total.sats.height,
|
&self.supply.total.sats.height,
|
||||||
height_to_market_cap,
|
height_to_market_cap,
|
||||||
exit,
|
exit,
|
||||||
|
|||||||
@@ -7,20 +7,20 @@ use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
|||||||
use crate::{blocks, prices};
|
use crate::{blocks, prices};
|
||||||
|
|
||||||
use crate::distribution::metrics::{
|
use crate::distribution::metrics::{
|
||||||
ActivityMetrics, CostBasisBase, ImportConfig, OutputsMetrics, RealizedFull,
|
ActivityFull, CostBasisBase, ImportConfig, OutputsMetrics, RealizedBase,
|
||||||
RelativeWithRelToAll, SupplyMetrics, UnrealizedFull,
|
RelativeWithRelToAll, SupplyMetrics, UnrealizedFull,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Basic cohort metrics: no extensions, with relative (rel_to_all).
|
/// Basic cohort metrics: no extensions, with relative (rel_to_all).
|
||||||
/// Used by: epoch, year, type (spendable), amount, address cohorts.
|
/// Used by: age_range cohorts.
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct BasicCohortMetrics<M: StorageMode = Rw> {
|
pub struct BasicCohortMetrics<M: StorageMode = Rw> {
|
||||||
#[traversable(skip)]
|
#[traversable(skip)]
|
||||||
pub filter: Filter,
|
pub filter: Filter,
|
||||||
pub supply: Box<SupplyMetrics<M>>,
|
pub supply: Box<SupplyMetrics<M>>,
|
||||||
pub outputs: Box<OutputsMetrics<M>>,
|
pub outputs: Box<OutputsMetrics<M>>,
|
||||||
pub activity: Box<ActivityMetrics<M>>,
|
pub activity: Box<ActivityFull<M>>,
|
||||||
pub realized: Box<RealizedFull<M>>,
|
pub realized: Box<RealizedBase<M>>,
|
||||||
pub cost_basis: Box<CostBasisBase<M>>,
|
pub cost_basis: Box<CostBasisBase<M>>,
|
||||||
pub unrealized: Box<UnrealizedFull<M>>,
|
pub unrealized: Box<UnrealizedFull<M>>,
|
||||||
pub relative: Box<RelativeWithRelToAll<M>>,
|
pub relative: Box<RelativeWithRelToAll<M>>,
|
||||||
@@ -32,7 +32,7 @@ impl BasicCohortMetrics {
|
|||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
let supply = SupplyMetrics::forced_import(cfg)?;
|
let supply = SupplyMetrics::forced_import(cfg)?;
|
||||||
let unrealized = UnrealizedFull::forced_import(cfg)?;
|
let unrealized = UnrealizedFull::forced_import(cfg)?;
|
||||||
let realized = RealizedFull::forced_import(cfg)?;
|
let realized = RealizedBase::forced_import(cfg)?;
|
||||||
|
|
||||||
let relative = RelativeWithRelToAll::forced_import(cfg)?;
|
let relative = RelativeWithRelToAll::forced_import(cfg)?;
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ impl BasicCohortMetrics {
|
|||||||
filter: cfg.filter.clone(),
|
filter: cfg.filter.clone(),
|
||||||
supply: Box::new(supply),
|
supply: Box::new(supply),
|
||||||
outputs: Box::new(OutputsMetrics::forced_import(cfg)?),
|
outputs: Box::new(OutputsMetrics::forced_import(cfg)?),
|
||||||
activity: Box::new(ActivityMetrics::forced_import(cfg)?),
|
activity: Box::new(ActivityFull::forced_import(cfg)?),
|
||||||
realized: Box::new(realized),
|
realized: Box::new(realized),
|
||||||
cost_basis: Box::new(CostBasisBase::forced_import(cfg)?),
|
cost_basis: Box::new(CostBasisBase::forced_import(cfg)?),
|
||||||
unrealized: Box::new(unrealized),
|
unrealized: Box::new(unrealized),
|
||||||
@@ -62,7 +62,6 @@ impl BasicCohortMetrics {
|
|||||||
prices,
|
prices,
|
||||||
starting_indexes,
|
starting_indexes,
|
||||||
&self.supply.total.btc.height,
|
&self.supply.total.btc.height,
|
||||||
height_to_market_cap,
|
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ use vecdb::{AnyStoredVec, Exit, ReadableVec, Rw, StorageMode};
|
|||||||
use crate::{blocks, prices};
|
use crate::{blocks, prices};
|
||||||
|
|
||||||
use crate::distribution::metrics::{
|
use crate::distribution::metrics::{
|
||||||
ActivityCore, CohortMetricsBase, RealizedCore, ImportConfig, OutputsMetrics,
|
ActivityBase, CohortMetricsBase, RealizedBase, ImportConfig, OutputsMetrics,
|
||||||
RelativeCompleteWithRelToAll, SupplyMetrics, UnrealizedComplete,
|
RelativeBaseWithRelToAll, SupplyMetrics, UnrealizedBase,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
@@ -17,10 +17,10 @@ pub struct CoreCohortMetrics<M: StorageMode = Rw> {
|
|||||||
pub filter: Filter,
|
pub filter: Filter,
|
||||||
pub supply: Box<SupplyMetrics<M>>,
|
pub supply: Box<SupplyMetrics<M>>,
|
||||||
pub outputs: Box<OutputsMetrics<M>>,
|
pub outputs: Box<OutputsMetrics<M>>,
|
||||||
pub activity: Box<ActivityCore<M>>,
|
pub activity: Box<ActivityBase<M>>,
|
||||||
pub realized: Box<RealizedCore<M>>,
|
pub realized: Box<RealizedBase<M>>,
|
||||||
pub unrealized: Box<UnrealizedComplete<M>>,
|
pub unrealized: Box<UnrealizedBase<M>>,
|
||||||
pub relative: Box<RelativeCompleteWithRelToAll<M>>,
|
pub relative: Box<RelativeBaseWithRelToAll<M>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CoreCohortMetrics {
|
impl CoreCohortMetrics {
|
||||||
@@ -29,10 +29,10 @@ impl CoreCohortMetrics {
|
|||||||
filter: cfg.filter.clone(),
|
filter: cfg.filter.clone(),
|
||||||
supply: Box::new(SupplyMetrics::forced_import(cfg)?),
|
supply: Box::new(SupplyMetrics::forced_import(cfg)?),
|
||||||
outputs: Box::new(OutputsMetrics::forced_import(cfg)?),
|
outputs: Box::new(OutputsMetrics::forced_import(cfg)?),
|
||||||
activity: Box::new(ActivityCore::forced_import(cfg)?),
|
activity: Box::new(ActivityBase::forced_import(cfg)?),
|
||||||
realized: Box::new(RealizedCore::forced_import(cfg)?),
|
realized: Box::new(RealizedBase::forced_import(cfg)?),
|
||||||
unrealized: Box::new(UnrealizedComplete::forced_import(cfg)?),
|
unrealized: Box::new(UnrealizedBase::forced_import(cfg)?),
|
||||||
relative: Box::new(RelativeCompleteWithRelToAll::forced_import(cfg)?),
|
relative: Box::new(RelativeBaseWithRelToAll::forced_import(cfg)?),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,17 +80,17 @@ impl CoreCohortMetrics {
|
|||||||
)?;
|
)?;
|
||||||
self.activity.compute_from_stateful(
|
self.activity.compute_from_stateful(
|
||||||
starting_indexes,
|
starting_indexes,
|
||||||
&others.iter().map(|v| &v.activity().core).collect::<Vec<_>>(),
|
&others.iter().map(|v| &v.activity().base).collect::<Vec<_>>(),
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
self.realized.compute_from_stateful(
|
self.realized.compute_from_stateful(
|
||||||
starting_indexes,
|
starting_indexes,
|
||||||
&others.iter().map(|v| &v.realized_full().core).collect::<Vec<_>>(),
|
&others.iter().map(|v| v.realized_base()).collect::<Vec<_>>(),
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
self.unrealized.compute_from_stateful(
|
self.unrealized.compute_from_stateful(
|
||||||
starting_indexes,
|
starting_indexes,
|
||||||
&others.iter().map(|v| &v.unrealized_full().complete).collect::<Vec<_>>(),
|
&others.iter().map(|v| &v.unrealized_full().base).collect::<Vec<_>>(),
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@@ -114,6 +114,12 @@ impl CoreCohortMetrics {
|
|||||||
self.activity
|
self.activity
|
||||||
.compute_rest_part1(blocks, prices, starting_indexes, exit)?;
|
.compute_rest_part1(blocks, prices, starting_indexes, exit)?;
|
||||||
|
|
||||||
|
self.realized
|
||||||
|
.sent_in_profit
|
||||||
|
.compute(prices, starting_indexes.height, exit)?;
|
||||||
|
self.realized
|
||||||
|
.sent_in_loss
|
||||||
|
.compute(prices, starting_indexes.height, exit)?;
|
||||||
self.realized
|
self.realized
|
||||||
.compute_rest_part1(starting_indexes, exit)?;
|
.compute_rest_part1(starting_indexes, exit)?;
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ use crate::{blocks, prices};
|
|||||||
use crate::internal::ComputedFromHeight;
|
use crate::internal::ComputedFromHeight;
|
||||||
|
|
||||||
use crate::distribution::metrics::{
|
use crate::distribution::metrics::{
|
||||||
ActivityMetrics, CostBasisWithExtended, ImportConfig, OutputsMetrics,
|
ActivityFull, CostBasisWithExtended, ImportConfig, OutputsMetrics,
|
||||||
RealizedWithExtended, RelativeWithExtended, SupplyMetrics, UnrealizedFull,
|
RealizedFull, RelativeWithExtended, SupplyMetrics, UnrealizedFull,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Cohort metrics with extended realized + extended cost basis (no adjusted).
|
/// Cohort metrics with extended realized + extended cost basis (no adjusted).
|
||||||
@@ -21,8 +21,8 @@ pub struct ExtendedCohortMetrics<M: StorageMode = Rw> {
|
|||||||
pub filter: Filter,
|
pub filter: Filter,
|
||||||
pub supply: Box<SupplyMetrics<M>>,
|
pub supply: Box<SupplyMetrics<M>>,
|
||||||
pub outputs: Box<OutputsMetrics<M>>,
|
pub outputs: Box<OutputsMetrics<M>>,
|
||||||
pub activity: Box<ActivityMetrics<M>>,
|
pub activity: Box<ActivityFull<M>>,
|
||||||
pub realized: Box<RealizedWithExtended<M>>,
|
pub realized: Box<RealizedFull<M>>,
|
||||||
pub cost_basis: Box<CostBasisWithExtended<M>>,
|
pub cost_basis: Box<CostBasisWithExtended<M>>,
|
||||||
pub unrealized: Box<UnrealizedFull<M>>,
|
pub unrealized: Box<UnrealizedFull<M>>,
|
||||||
pub relative: Box<RelativeWithExtended<M>>,
|
pub relative: Box<RelativeWithExtended<M>>,
|
||||||
@@ -36,7 +36,7 @@ impl ExtendedCohortMetrics {
|
|||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
let supply = SupplyMetrics::forced_import(cfg)?;
|
let supply = SupplyMetrics::forced_import(cfg)?;
|
||||||
let unrealized = UnrealizedFull::forced_import(cfg)?;
|
let unrealized = UnrealizedFull::forced_import(cfg)?;
|
||||||
let realized = RealizedWithExtended::forced_import(cfg)?;
|
let realized = RealizedFull::forced_import(cfg)?;
|
||||||
|
|
||||||
let relative = RelativeWithExtended::forced_import(cfg)?;
|
let relative = RelativeWithExtended::forced_import(cfg)?;
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ impl ExtendedCohortMetrics {
|
|||||||
filter: cfg.filter.clone(),
|
filter: cfg.filter.clone(),
|
||||||
supply: Box::new(supply),
|
supply: Box::new(supply),
|
||||||
outputs: Box::new(OutputsMetrics::forced_import(cfg)?),
|
outputs: Box::new(OutputsMetrics::forced_import(cfg)?),
|
||||||
activity: Box::new(ActivityMetrics::forced_import(cfg)?),
|
activity: Box::new(ActivityFull::forced_import(cfg)?),
|
||||||
realized: Box::new(realized),
|
realized: Box::new(realized),
|
||||||
cost_basis: Box::new(CostBasisWithExtended::forced_import(cfg)?),
|
cost_basis: Box::new(CostBasisWithExtended::forced_import(cfg)?),
|
||||||
unrealized: Box::new(unrealized),
|
unrealized: Box::new(unrealized),
|
||||||
@@ -75,7 +75,7 @@ impl ExtendedCohortMetrics {
|
|||||||
self.relative.compute(
|
self.relative.compute(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.unrealized,
|
&self.unrealized,
|
||||||
&self.realized.base,
|
&self.realized,
|
||||||
&self.supply.total.sats.height,
|
&self.supply.total.sats.height,
|
||||||
height_to_market_cap,
|
height_to_market_cap,
|
||||||
all_supply_sats,
|
all_supply_sats,
|
||||||
|
|||||||
@@ -2,36 +2,22 @@ use brk_cohort::Filter;
|
|||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{
|
use brk_types::{
|
||||||
BasisPoints16, BasisPoints32, Bitcoin, Cents, Dollars, Height, Indexes, Sats, StoredF32,
|
BasisPoints16, Height, Indexes, Sats, Version,
|
||||||
Version,
|
|
||||||
};
|
};
|
||||||
use vecdb::{AnyStoredVec, AnyVec, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode, WritableVec};
|
use vecdb::{AnyStoredVec, AnyVec, Exit, ReadableVec, Rw, StorageMode, WritableVec};
|
||||||
|
|
||||||
use crate::{blocks, prices};
|
use crate::{blocks, prices};
|
||||||
|
|
||||||
use crate::internal::{
|
use crate::internal::{
|
||||||
CentsUnsignedToDollars, ComputedFromHeight, ComputedFromHeightCumulative,
|
PercentFromHeight, RatioSatsBp16,
|
||||||
ComputedFromHeightRatio, Identity, LazyFromHeight, PercentFromHeight, Price, RatioSatsBp16,
|
|
||||||
ValueFromHeight,
|
ValueFromHeight,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::distribution::{
|
use crate::distribution::{
|
||||||
metrics::{ActivityCore, ImportConfig, OutputsMetrics, SupplyMetrics},
|
metrics::{ActivityBase, ImportConfig, OutputsMetrics, RealizedMinimal, SupplyMetrics},
|
||||||
state::{RealizedOps, UnrealizedState},
|
state::UnrealizedState,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Minimal realized metrics: realized cap, realized price, MVRV, and realized P/L.
|
|
||||||
#[derive(Traversable)]
|
|
||||||
pub struct MinimalRealized<M: StorageMode = Rw> {
|
|
||||||
pub realized_cap_cents: ComputedFromHeight<Cents, M>,
|
|
||||||
pub realized_profit: ComputedFromHeightCumulative<Cents, M>,
|
|
||||||
pub realized_loss: ComputedFromHeightCumulative<Cents, M>,
|
|
||||||
pub realized_cap: LazyFromHeight<Dollars, Cents>,
|
|
||||||
pub realized_price: Price<ComputedFromHeight<Cents, M>>,
|
|
||||||
pub realized_price_ratio: ComputedFromHeightRatio<M>,
|
|
||||||
pub mvrv: LazyFromHeight<StoredF32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Minimal unrealized metrics: supply in profit/loss only.
|
/// Minimal unrealized metrics: supply in profit/loss only.
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct MinimalUnrealized<M: StorageMode = Rw> {
|
pub struct MinimalUnrealized<M: StorageMode = Rw> {
|
||||||
@@ -57,135 +43,12 @@ pub struct MinimalCohortMetrics<M: StorageMode = Rw> {
|
|||||||
pub filter: Filter,
|
pub filter: Filter,
|
||||||
pub supply: Box<SupplyMetrics<M>>,
|
pub supply: Box<SupplyMetrics<M>>,
|
||||||
pub outputs: Box<OutputsMetrics<M>>,
|
pub outputs: Box<OutputsMetrics<M>>,
|
||||||
pub activity: Box<ActivityCore<M>>,
|
pub activity: Box<ActivityBase<M>>,
|
||||||
pub realized: Box<MinimalRealized<M>>,
|
pub realized: Box<RealizedMinimal<M>>,
|
||||||
pub unrealized: Box<MinimalUnrealized<M>>,
|
pub unrealized: Box<MinimalUnrealized<M>>,
|
||||||
pub relative: Box<MinimalRelative<M>>,
|
pub relative: Box<MinimalRelative<M>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MinimalRealized {
|
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
|
||||||
let realized_cap_cents = cfg.import_computed("realized_cap_cents", Version::ZERO)?;
|
|
||||||
let realized_cap = LazyFromHeight::from_computed::<CentsUnsignedToDollars>(
|
|
||||||
&cfg.name("realized_cap"),
|
|
||||||
cfg.version,
|
|
||||||
realized_cap_cents.height.read_only_boxed_clone(),
|
|
||||||
&realized_cap_cents,
|
|
||||||
);
|
|
||||||
|
|
||||||
let realized_profit = cfg.import_cumulative("realized_profit", Version::ZERO)?;
|
|
||||||
let realized_loss = cfg.import_cumulative("realized_loss", Version::ZERO)?;
|
|
||||||
|
|
||||||
let realized_price = cfg.import_price("realized_price", Version::ONE)?;
|
|
||||||
let realized_price_ratio = cfg.import_ratio("realized_price", Version::ONE)?;
|
|
||||||
let mvrv = LazyFromHeight::from_lazy::<Identity<StoredF32>, BasisPoints32>(
|
|
||||||
&cfg.name("mvrv"),
|
|
||||||
cfg.version,
|
|
||||||
&realized_price_ratio.ratio,
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
realized_cap_cents,
|
|
||||||
realized_profit,
|
|
||||||
realized_loss,
|
|
||||||
realized_cap,
|
|
||||||
realized_price,
|
|
||||||
realized_price_ratio,
|
|
||||||
mvrv,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn min_stateful_height_len(&self) -> usize {
|
|
||||||
self.realized_cap_cents
|
|
||||||
.height
|
|
||||||
.len()
|
|
||||||
.min(self.realized_profit.height.len())
|
|
||||||
.min(self.realized_loss.height.len())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn truncate_push(
|
|
||||||
&mut self,
|
|
||||||
height: Height,
|
|
||||||
state: &impl RealizedOps,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.realized_cap_cents
|
|
||||||
.height
|
|
||||||
.truncate_push(height, state.cap())?;
|
|
||||||
self.realized_profit
|
|
||||||
.height
|
|
||||||
.truncate_push(height, state.profit())?;
|
|
||||||
self.realized_loss
|
|
||||||
.height
|
|
||||||
.truncate_push(height, state.loss())?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
|
||||||
vec![
|
|
||||||
&mut self.realized_cap_cents.height as &mut dyn AnyStoredVec,
|
|
||||||
&mut self.realized_profit.height,
|
|
||||||
&mut self.realized_loss.height,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute_from_sources(
|
|
||||||
&mut self,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
others: &[&Self],
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
sum_others!(self, starting_indexes, others, exit; realized_cap_cents.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; realized_profit.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; realized_loss.height);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute_rest_part1(
|
|
||||||
&mut self,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.realized_profit
|
|
||||||
.compute_rest(starting_indexes.height, exit)?;
|
|
||||||
self.realized_loss
|
|
||||||
.compute_rest(starting_indexes.height, exit)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute_rest_part2(
|
|
||||||
&mut self,
|
|
||||||
prices: &prices::Vecs,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
height_to_supply: &impl ReadableVec<Height, Bitcoin>,
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.realized_price.cents.height.compute_transform2(
|
|
||||||
starting_indexes.height,
|
|
||||||
&self.realized_cap_cents.height,
|
|
||||||
height_to_supply,
|
|
||||||
|(i, cap_cents, supply, ..)| {
|
|
||||||
let cap = cap_cents.as_u128();
|
|
||||||
let supply_sats = Sats::from(supply).as_u128();
|
|
||||||
if supply_sats == 0 {
|
|
||||||
(i, Cents::ZERO)
|
|
||||||
} else {
|
|
||||||
(i, Cents::from(cap * Sats::ONE_BTC_U128 / supply_sats))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
self.realized_price_ratio.compute_ratio(
|
|
||||||
starting_indexes,
|
|
||||||
&prices.price.cents.height,
|
|
||||||
&self.realized_price.cents.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MinimalUnrealized {
|
impl MinimalUnrealized {
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@@ -292,8 +155,8 @@ impl MinimalCohortMetrics {
|
|||||||
filter: cfg.filter.clone(),
|
filter: cfg.filter.clone(),
|
||||||
supply: Box::new(SupplyMetrics::forced_import(cfg)?),
|
supply: Box::new(SupplyMetrics::forced_import(cfg)?),
|
||||||
outputs: Box::new(OutputsMetrics::forced_import(cfg)?),
|
outputs: Box::new(OutputsMetrics::forced_import(cfg)?),
|
||||||
activity: Box::new(ActivityCore::forced_import(cfg)?),
|
activity: Box::new(ActivityBase::forced_import(cfg)?),
|
||||||
realized: Box::new(MinimalRealized::forced_import(cfg)?),
|
realized: Box::new(RealizedMinimal::forced_import(cfg)?),
|
||||||
unrealized: Box::new(MinimalUnrealized::forced_import(cfg)?),
|
unrealized: Box::new(MinimalUnrealized::forced_import(cfg)?),
|
||||||
relative: Box::new(MinimalRelative::forced_import(cfg)?),
|
relative: Box::new(MinimalRelative::forced_import(cfg)?),
|
||||||
})
|
})
|
||||||
@@ -345,7 +208,7 @@ impl MinimalCohortMetrics {
|
|||||||
&others.iter().map(|v| v.activity.as_ref()).collect::<Vec<_>>(),
|
&others.iter().map(|v| v.activity.as_ref()).collect::<Vec<_>>(),
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
self.realized.compute_from_sources(
|
self.realized.compute_from_stateful(
|
||||||
starting_indexes,
|
starting_indexes,
|
||||||
&others
|
&others
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@@ -68,6 +68,104 @@ macro_rules! impl_cohort_metrics_base {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn min_stateful_height_len(&self) -> usize {
|
||||||
|
self.supply.min_len()
|
||||||
|
.min(self.outputs.min_len())
|
||||||
|
.min(self.activity.min_len())
|
||||||
|
.min(self.realized.min_stateful_height_len())
|
||||||
|
.min(self.unrealized_full().min_stateful_height_len())
|
||||||
|
.min(self.cost_basis_base().min_stateful_height_len())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn truncate_push(
|
||||||
|
&mut self,
|
||||||
|
height: brk_types::Height,
|
||||||
|
state: &$crate::distribution::state::CohortState<$crate::distribution::state::RealizedState>,
|
||||||
|
) -> brk_error::Result<()> {
|
||||||
|
self.supply_mut()
|
||||||
|
.truncate_push(height, state.supply.value)?;
|
||||||
|
self.outputs_mut()
|
||||||
|
.truncate_push(height, state.supply.utxo_count)?;
|
||||||
|
self.activity_mut().truncate_push(
|
||||||
|
height,
|
||||||
|
state.sent,
|
||||||
|
state.satblocks_destroyed,
|
||||||
|
state.satdays_destroyed,
|
||||||
|
)?;
|
||||||
|
self.realized.truncate_push(height, &state.realized)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_base_from_others<T: $crate::distribution::metrics::CohortMetricsBase>(
|
||||||
|
&mut self,
|
||||||
|
starting_indexes: &brk_types::Indexes,
|
||||||
|
others: &[&T],
|
||||||
|
exit: &vecdb::Exit,
|
||||||
|
) -> brk_error::Result<()> {
|
||||||
|
self.supply_mut().compute_from_stateful(
|
||||||
|
starting_indexes,
|
||||||
|
&others.iter().map(|v| v.supply()).collect::<Vec<_>>(),
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.outputs_mut().compute_from_stateful(
|
||||||
|
starting_indexes,
|
||||||
|
&others.iter().map(|v| v.outputs()).collect::<Vec<_>>(),
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.activity_mut().compute_from_stateful(
|
||||||
|
starting_indexes,
|
||||||
|
&others.iter().map(|v| v.activity()).collect::<Vec<_>>(),
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.realized.compute_from_stateful(
|
||||||
|
starting_indexes,
|
||||||
|
&others.iter().map(|v| v.realized_base()).collect::<Vec<_>>(),
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.unrealized_full_mut().compute_from_stateful(
|
||||||
|
starting_indexes,
|
||||||
|
&others.iter().map(|v| v.unrealized_full()).collect::<Vec<_>>(),
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.cost_basis_base_mut().compute_from_stateful(
|
||||||
|
starting_indexes,
|
||||||
|
&others.iter().map(|v| v.cost_basis_base()).collect::<Vec<_>>(),
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_rest_part1(
|
||||||
|
&mut self,
|
||||||
|
blocks: &$crate::blocks::Vecs,
|
||||||
|
prices: &$crate::prices::Vecs,
|
||||||
|
starting_indexes: &brk_types::Indexes,
|
||||||
|
exit: &vecdb::Exit,
|
||||||
|
) -> brk_error::Result<()> {
|
||||||
|
self.supply_mut()
|
||||||
|
.compute(prices, starting_indexes.height, exit)?;
|
||||||
|
self.supply_mut()
|
||||||
|
.compute_rest_part1(blocks, starting_indexes, exit)?;
|
||||||
|
self.outputs_mut()
|
||||||
|
.compute_rest(blocks, starting_indexes, exit)?;
|
||||||
|
self.activity_mut()
|
||||||
|
.sent
|
||||||
|
.compute(prices, starting_indexes.height, exit)?;
|
||||||
|
self.activity_mut()
|
||||||
|
.compute_rest_part1(blocks, prices, starting_indexes, exit)?;
|
||||||
|
|
||||||
|
self.realized.sent_in_profit
|
||||||
|
.compute(prices, starting_indexes.height, exit)?;
|
||||||
|
self.realized.sent_in_loss
|
||||||
|
.compute(prices, starting_indexes.height, exit)?;
|
||||||
|
self.realized.compute_rest_part1(starting_indexes, exit)?;
|
||||||
|
|
||||||
|
self.unrealized_full_mut()
|
||||||
|
.compute_rest(prices, starting_indexes, exit)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn vecdb::AnyStoredVec> {
|
fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn vecdb::AnyStoredVec> {
|
||||||
let mut vecs: Vec<&mut dyn vecdb::AnyStoredVec> = Vec::new();
|
let mut vecs: Vec<&mut dyn vecdb::AnyStoredVec> = Vec::new();
|
||||||
vecs.extend(self.supply.collect_vecs_mut());
|
vecs.extend(self.supply.collect_vecs_mut());
|
||||||
@@ -103,6 +201,37 @@ macro_rules! impl_cohort_metrics_base {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn min_stateful_height_len(&self) -> usize {
|
||||||
|
self.inner.min_stateful_height_len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn truncate_push(
|
||||||
|
&mut self,
|
||||||
|
height: brk_types::Height,
|
||||||
|
state: &$crate::distribution::state::CohortState<$crate::distribution::state::RealizedState>,
|
||||||
|
) -> brk_error::Result<()> {
|
||||||
|
self.inner.truncate_push(height, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_rest_part1(
|
||||||
|
&mut self,
|
||||||
|
blocks: &$crate::blocks::Vecs,
|
||||||
|
prices: &$crate::prices::Vecs,
|
||||||
|
starting_indexes: &brk_types::Indexes,
|
||||||
|
exit: &vecdb::Exit,
|
||||||
|
) -> brk_error::Result<()> {
|
||||||
|
self.inner.compute_rest_part1(blocks, prices, starting_indexes, exit)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_base_from_others<T: $crate::distribution::metrics::CohortMetricsBase>(
|
||||||
|
&mut self,
|
||||||
|
starting_indexes: &brk_types::Indexes,
|
||||||
|
others: &[&T],
|
||||||
|
exit: &vecdb::Exit,
|
||||||
|
) -> brk_error::Result<()> {
|
||||||
|
self.inner.compute_base_from_others(starting_indexes, others, exit)
|
||||||
|
}
|
||||||
|
|
||||||
fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn vecdb::AnyStoredVec> {
|
fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn vecdb::AnyStoredVec> {
|
||||||
self.inner.collect_all_vecs_mut()
|
self.inner.collect_all_vecs_mut()
|
||||||
}
|
}
|
||||||
@@ -115,10 +244,10 @@ macro_rules! impl_cohort_metrics_base {
|
|||||||
fn supply_mut(&mut self) -> &mut $crate::distribution::metrics::SupplyMetrics { &mut self.supply }
|
fn supply_mut(&mut self) -> &mut $crate::distribution::metrics::SupplyMetrics { &mut self.supply }
|
||||||
fn outputs(&self) -> &$crate::distribution::metrics::OutputsMetrics { &self.outputs }
|
fn outputs(&self) -> &$crate::distribution::metrics::OutputsMetrics { &self.outputs }
|
||||||
fn outputs_mut(&mut self) -> &mut $crate::distribution::metrics::OutputsMetrics { &mut self.outputs }
|
fn outputs_mut(&mut self) -> &mut $crate::distribution::metrics::OutputsMetrics { &mut self.outputs }
|
||||||
fn activity(&self) -> &$crate::distribution::metrics::ActivityMetrics { &self.activity }
|
fn activity(&self) -> &$crate::distribution::metrics::ActivityFull { &self.activity }
|
||||||
fn activity_mut(&mut self) -> &mut $crate::distribution::metrics::ActivityMetrics { &mut self.activity }
|
fn activity_mut(&mut self) -> &mut $crate::distribution::metrics::ActivityFull { &mut self.activity }
|
||||||
fn realized_full(&self) -> &$crate::distribution::metrics::RealizedFull { &self.realized }
|
fn realized_base(&self) -> &$crate::distribution::metrics::RealizedBase { &self.realized }
|
||||||
fn realized_full_mut(&mut self) -> &mut $crate::distribution::metrics::RealizedFull { &mut self.realized }
|
fn realized_base_mut(&mut self) -> &mut $crate::distribution::metrics::RealizedBase { &mut self.realized }
|
||||||
fn unrealized_full(&self) -> &$crate::distribution::metrics::UnrealizedFull { &self.unrealized }
|
fn unrealized_full(&self) -> &$crate::distribution::metrics::UnrealizedFull { &self.unrealized }
|
||||||
fn unrealized_full_mut(&mut self) -> &mut $crate::distribution::metrics::UnrealizedFull { &mut self.unrealized }
|
fn unrealized_full_mut(&mut self) -> &mut $crate::distribution::metrics::UnrealizedFull { &mut self.unrealized }
|
||||||
fn cost_basis_base(&self) -> &$crate::distribution::metrics::CostBasisBase { &self.cost_basis }
|
fn cost_basis_base(&self) -> &$crate::distribution::metrics::CostBasisBase { &self.cost_basis }
|
||||||
@@ -131,10 +260,10 @@ macro_rules! impl_cohort_metrics_base {
|
|||||||
fn supply_mut(&mut self) -> &mut $crate::distribution::metrics::SupplyMetrics { self.inner.supply_mut() }
|
fn supply_mut(&mut self) -> &mut $crate::distribution::metrics::SupplyMetrics { self.inner.supply_mut() }
|
||||||
fn outputs(&self) -> &$crate::distribution::metrics::OutputsMetrics { self.inner.outputs() }
|
fn outputs(&self) -> &$crate::distribution::metrics::OutputsMetrics { self.inner.outputs() }
|
||||||
fn outputs_mut(&mut self) -> &mut $crate::distribution::metrics::OutputsMetrics { self.inner.outputs_mut() }
|
fn outputs_mut(&mut self) -> &mut $crate::distribution::metrics::OutputsMetrics { self.inner.outputs_mut() }
|
||||||
fn activity(&self) -> &$crate::distribution::metrics::ActivityMetrics { self.inner.activity() }
|
fn activity(&self) -> &$crate::distribution::metrics::ActivityFull { self.inner.activity() }
|
||||||
fn activity_mut(&mut self) -> &mut $crate::distribution::metrics::ActivityMetrics { self.inner.activity_mut() }
|
fn activity_mut(&mut self) -> &mut $crate::distribution::metrics::ActivityFull { self.inner.activity_mut() }
|
||||||
fn realized_full(&self) -> &$crate::distribution::metrics::RealizedFull { self.inner.realized_full() }
|
fn realized_base(&self) -> &$crate::distribution::metrics::RealizedBase { self.inner.realized_base() }
|
||||||
fn realized_full_mut(&mut self) -> &mut $crate::distribution::metrics::RealizedFull { self.inner.realized_full_mut() }
|
fn realized_base_mut(&mut self) -> &mut $crate::distribution::metrics::RealizedBase { self.inner.realized_base_mut() }
|
||||||
fn unrealized_full(&self) -> &$crate::distribution::metrics::UnrealizedFull { self.inner.unrealized_full() }
|
fn unrealized_full(&self) -> &$crate::distribution::metrics::UnrealizedFull { self.inner.unrealized_full() }
|
||||||
fn unrealized_full_mut(&mut self) -> &mut $crate::distribution::metrics::UnrealizedFull { self.inner.unrealized_full_mut() }
|
fn unrealized_full_mut(&mut self) -> &mut $crate::distribution::metrics::UnrealizedFull { self.inner.unrealized_full_mut() }
|
||||||
fn cost_basis_base(&self) -> &$crate::distribution::metrics::CostBasisBase { self.inner.cost_basis_base() }
|
fn cost_basis_base(&self) -> &$crate::distribution::metrics::CostBasisBase { self.inner.cost_basis_base() }
|
||||||
@@ -197,10 +326,10 @@ pub trait CohortMetricsBase: CohortMetricsState<Realized = RealizedState> + Send
|
|||||||
fn supply_mut(&mut self) -> &mut SupplyMetrics;
|
fn supply_mut(&mut self) -> &mut SupplyMetrics;
|
||||||
fn outputs(&self) -> &OutputsMetrics;
|
fn outputs(&self) -> &OutputsMetrics;
|
||||||
fn outputs_mut(&mut self) -> &mut OutputsMetrics;
|
fn outputs_mut(&mut self) -> &mut OutputsMetrics;
|
||||||
fn activity(&self) -> &ActivityMetrics;
|
fn activity(&self) -> &ActivityFull;
|
||||||
fn activity_mut(&mut self) -> &mut ActivityMetrics;
|
fn activity_mut(&mut self) -> &mut ActivityFull;
|
||||||
fn realized_full(&self) -> &RealizedFull;
|
fn realized_base(&self) -> &RealizedBase;
|
||||||
fn realized_full_mut(&mut self) -> &mut RealizedFull;
|
fn realized_base_mut(&mut self) -> &mut RealizedBase;
|
||||||
fn unrealized_full(&self) -> &UnrealizedFull;
|
fn unrealized_full(&self) -> &UnrealizedFull;
|
||||||
fn unrealized_full_mut(&mut self) -> &mut UnrealizedFull;
|
fn unrealized_full_mut(&mut self) -> &mut UnrealizedFull;
|
||||||
fn cost_basis_base(&self) -> &CostBasisBase;
|
fn cost_basis_base(&self) -> &CostBasisBase;
|
||||||
@@ -242,7 +371,7 @@ pub trait CohortMetricsBase: CohortMetricsState<Realized = RealizedState> + Send
|
|||||||
.min_len()
|
.min_len()
|
||||||
.min(self.outputs().min_len())
|
.min(self.outputs().min_len())
|
||||||
.min(self.activity().min_len())
|
.min(self.activity().min_len())
|
||||||
.min(self.realized_full().min_stateful_height_len())
|
.min(self.realized_base().min_stateful_height_len())
|
||||||
.min(self.unrealized_full().min_stateful_height_len())
|
.min(self.unrealized_full().min_stateful_height_len())
|
||||||
.min(self.cost_basis_base().min_stateful_height_len())
|
.min(self.cost_basis_base().min_stateful_height_len())
|
||||||
}
|
}
|
||||||
@@ -258,7 +387,7 @@ pub trait CohortMetricsBase: CohortMetricsState<Realized = RealizedState> + Send
|
|||||||
state.satblocks_destroyed,
|
state.satblocks_destroyed,
|
||||||
state.satdays_destroyed,
|
state.satdays_destroyed,
|
||||||
)?;
|
)?;
|
||||||
self.realized_full_mut()
|
self.realized_base_mut()
|
||||||
.truncate_push(height, &state.realized)?;
|
.truncate_push(height, &state.realized)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -272,7 +401,7 @@ pub trait CohortMetricsBase: CohortMetricsState<Realized = RealizedState> + Send
|
|||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let weights: Vec<_> = others
|
let weights: Vec<_> = others
|
||||||
.iter()
|
.iter()
|
||||||
.map(|o| &o.realized_full().realized_cap.height)
|
.map(|o| &o.realized_base().realized_cap.height)
|
||||||
.collect();
|
.collect();
|
||||||
let values: Vec<_> = others
|
let values: Vec<_> = others
|
||||||
.iter()
|
.iter()
|
||||||
@@ -308,13 +437,13 @@ pub trait CohortMetricsBase: CohortMetricsState<Realized = RealizedState> + Send
|
|||||||
self.activity_mut()
|
self.activity_mut()
|
||||||
.compute_rest_part1(blocks, prices, starting_indexes, exit)?;
|
.compute_rest_part1(blocks, prices, starting_indexes, exit)?;
|
||||||
|
|
||||||
self.realized_full_mut()
|
self.realized_base_mut()
|
||||||
.sent_in_profit
|
.sent_in_profit
|
||||||
.compute(prices, starting_indexes.height, exit)?;
|
.compute(prices, starting_indexes.height, exit)?;
|
||||||
self.realized_full_mut()
|
self.realized_base_mut()
|
||||||
.sent_in_loss
|
.sent_in_loss
|
||||||
.compute(prices, starting_indexes.height, exit)?;
|
.compute(prices, starting_indexes.height, exit)?;
|
||||||
self.realized_full_mut()
|
self.realized_base_mut()
|
||||||
.compute_rest_part1(starting_indexes, exit)?;
|
.compute_rest_part1(starting_indexes, exit)?;
|
||||||
|
|
||||||
self.unrealized_full_mut()
|
self.unrealized_full_mut()
|
||||||
@@ -354,7 +483,7 @@ pub trait CohortMetricsBase: CohortMetricsState<Realized = RealizedState> + Send
|
|||||||
aggregate!(supply_mut, supply);
|
aggregate!(supply_mut, supply);
|
||||||
aggregate!(outputs_mut, outputs);
|
aggregate!(outputs_mut, outputs);
|
||||||
aggregate!(activity_mut, activity);
|
aggregate!(activity_mut, activity);
|
||||||
aggregate!(realized_full_mut, realized_full);
|
aggregate!(realized_base_mut, realized_base);
|
||||||
aggregate!(unrealized_full_mut, unrealized_full);
|
aggregate!(unrealized_full_mut, unrealized_full);
|
||||||
aggregate!(cost_basis_base_mut, cost_basis_base);
|
aggregate!(cost_basis_base_mut, cost_basis_base);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -1,124 +1,172 @@
|
|||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{
|
use brk_types::{
|
||||||
BasisPoints32, Bitcoin, Cents, CentsSats, CentsSquaredSats, Dollars, Height, Indexes, Version,
|
BasisPoints32, BasisPointsSigned32, Bitcoin, Cents, CentsSigned, Dollars, Height, Indexes,
|
||||||
|
StoredF64, Version,
|
||||||
};
|
};
|
||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use vecdb::{AnyStoredVec, AnyVec, BytesVec, Exit, ReadableVec, Rw, StorageMode, WritableVec};
|
use vecdb::{
|
||||||
|
AnyStoredVec, AnyVec, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode, WritableVec,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
blocks,
|
blocks,
|
||||||
distribution::state::RealizedState,
|
distribution::state::RealizedOps,
|
||||||
internal::{
|
internal::{
|
||||||
ComputedFromHeight, ComputedFromHeightCumulative, ComputedFromHeightRatio,
|
ComputedFromHeight, ComputedFromHeightCumulative,
|
||||||
PercentFromHeight, PercentRollingEmas1w1m, PercentRollingWindows, Price, RatioCentsBp32,
|
ComputedFromHeightRatioPercentiles, FiatFromHeight,
|
||||||
|
LazyFromHeight, NegCentsUnsignedToDollars, PercentFromHeight, RatioCents64,
|
||||||
|
RatioCentsBp32, RatioCentsSignedCentsBps32, RollingEmas1w1m, RollingEmas2w,
|
||||||
|
RollingWindows, ValueFromHeightCumulative,
|
||||||
},
|
},
|
||||||
prices,
|
prices,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::distribution::metrics::ImportConfig;
|
use crate::distribution::metrics::ImportConfig;
|
||||||
|
|
||||||
use super::RealizedComplete;
|
use super::RealizedMinimal;
|
||||||
|
|
||||||
/// Full realized metrics (Source/Extended tier).
|
|
||||||
///
|
|
||||||
/// Contains all Complete-tier fields (via Deref to RealizedComplete) plus:
|
|
||||||
/// - Source-only: peak_regret, peak_regret_rel_to_realized_cap
|
|
||||||
/// - Extended-only: investor_price, price bands, cap_raw, sell_side_risk_ratio
|
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
pub struct RealizedFull<M: StorageMode = Rw> {
|
pub struct RealizedBase<M: StorageMode = Rw> {
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub complete: RealizedComplete<M>,
|
pub minimal: RealizedMinimal<M>,
|
||||||
|
|
||||||
// --- Extended-only fields ---
|
pub realized_cap_change_1m: ComputedFromHeight<CentsSigned, M>,
|
||||||
pub investor_price: Price<ComputedFromHeight<Cents, M>>,
|
|
||||||
pub investor_price_ratio: ComputedFromHeightRatio<M>,
|
|
||||||
|
|
||||||
pub lower_price_band: Price<ComputedFromHeight<Cents, M>>,
|
pub neg_realized_loss: LazyFromHeight<Dollars, Cents>,
|
||||||
pub upper_price_band: Price<ComputedFromHeight<Cents, M>>,
|
pub net_realized_pnl: ComputedFromHeightCumulative<CentsSigned, M>,
|
||||||
|
pub net_realized_pnl_ema_1w: ComputedFromHeight<CentsSigned, M>,
|
||||||
|
pub gross_pnl: FiatFromHeight<Cents, M>,
|
||||||
|
|
||||||
pub cap_raw: M::Stored<BytesVec<Height, CentsSats>>,
|
pub realized_profit_ema_1w: ComputedFromHeight<Cents, M>,
|
||||||
pub investor_cap_raw: M::Stored<BytesVec<Height, CentsSquaredSats>>,
|
pub realized_loss_ema_1w: ComputedFromHeight<Cents, M>,
|
||||||
|
|
||||||
pub sell_side_risk_ratio: PercentRollingWindows<BasisPoints32, M>,
|
pub realized_profit_rel_to_realized_cap: PercentFromHeight<BasisPoints32, M>,
|
||||||
pub sell_side_risk_ratio_24h_ema: PercentRollingEmas1w1m<BasisPoints32, M>,
|
pub realized_loss_rel_to_realized_cap: PercentFromHeight<BasisPoints32, M>,
|
||||||
|
pub net_realized_pnl_rel_to_realized_cap: PercentFromHeight<BasisPointsSigned32, M>,
|
||||||
|
|
||||||
// --- Source-only fields ---
|
pub value_created: ComputedFromHeight<Cents, M>,
|
||||||
pub peak_regret: ComputedFromHeightCumulative<Cents, M>,
|
pub value_destroyed: ComputedFromHeight<Cents, M>,
|
||||||
pub peak_regret_rel_to_realized_cap: PercentFromHeight<BasisPoints32, M>,
|
pub value_created_sum: RollingWindows<Cents, M>,
|
||||||
|
pub value_destroyed_sum: RollingWindows<Cents, M>,
|
||||||
|
pub sopr: RollingWindows<StoredF64, M>,
|
||||||
|
pub sopr_24h_ema: RollingEmas1w1m<StoredF64, M>,
|
||||||
|
|
||||||
|
pub realized_price_ratio_percentiles: ComputedFromHeightRatioPercentiles<M>,
|
||||||
|
|
||||||
|
pub sent_in_profit: ValueFromHeightCumulative<M>,
|
||||||
|
pub sent_in_loss: ValueFromHeightCumulative<M>,
|
||||||
|
pub sent_in_profit_ema: RollingEmas2w<M>,
|
||||||
|
pub sent_in_loss_ema: RollingEmas2w<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RealizedFull {
|
impl RealizedBase {
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
let v0 = Version::ZERO;
|
let v0 = Version::ZERO;
|
||||||
|
let v1 = Version::ONE;
|
||||||
|
|
||||||
let complete = RealizedComplete::forced_import(cfg)?;
|
let minimal = RealizedMinimal::forced_import(cfg)?;
|
||||||
|
|
||||||
let investor_price = cfg.import_price("investor_price", v0)?;
|
let neg_realized_loss = LazyFromHeight::from_height_source::<NegCentsUnsignedToDollars>(
|
||||||
let investor_price_ratio = cfg.import_ratio("investor_price", v0)?;
|
&cfg.name("neg_realized_loss"),
|
||||||
let lower_price_band = cfg.import_price("lower_price_band", v0)?;
|
cfg.version + Version::ONE,
|
||||||
let upper_price_band = cfg.import_price("upper_price_band", v0)?;
|
minimal.realized_loss.height.read_only_boxed_clone(),
|
||||||
|
cfg.indexes,
|
||||||
|
);
|
||||||
|
|
||||||
let cap_raw = cfg.import_bytes("cap_raw", v0)?;
|
let realized_profit_ema_1w = cfg.import_computed("realized_profit_ema_1w", v0)?;
|
||||||
let investor_cap_raw = cfg.import_bytes("investor_cap_raw", v0)?;
|
let realized_loss_ema_1w = cfg.import_computed("realized_loss_ema_1w", v0)?;
|
||||||
|
|
||||||
let sell_side_risk_ratio =
|
let net_realized_pnl = cfg.import_cumulative("net_realized_pnl", v0)?;
|
||||||
cfg.import_percent_rolling_bp32("sell_side_risk_ratio", Version::new(2))?;
|
let net_realized_pnl_ema_1w = cfg.import_computed("net_realized_pnl_ema_1w", v0)?;
|
||||||
let sell_side_risk_ratio_24h_ema =
|
let gross_pnl = cfg.import_fiat("realized_gross_pnl", v0)?;
|
||||||
cfg.import_percent_emas_1w_1m_bp32("sell_side_risk_ratio_24h", Version::new(2))?;
|
|
||||||
|
|
||||||
let peak_regret = cfg.import_cumulative("realized_peak_regret", Version::new(2))?;
|
let realized_profit_rel_to_realized_cap =
|
||||||
let peak_regret_rel_to_realized_cap =
|
cfg.import_percent_bp32("realized_profit_rel_to_realized_cap", Version::new(2))?;
|
||||||
cfg.import_percent_bp32("realized_peak_regret_rel_to_realized_cap", Version::new(2))?;
|
let realized_loss_rel_to_realized_cap =
|
||||||
|
cfg.import_percent_bp32("realized_loss_rel_to_realized_cap", Version::new(2))?;
|
||||||
|
let net_realized_pnl_rel_to_realized_cap =
|
||||||
|
cfg.import_percent_bps32("net_realized_pnl_rel_to_realized_cap", Version::new(2))?;
|
||||||
|
|
||||||
|
let value_created = cfg.import_computed("value_created", v0)?;
|
||||||
|
let value_destroyed = cfg.import_computed("value_destroyed", v0)?;
|
||||||
|
let value_created_sum = cfg.import_rolling("value_created", v1)?;
|
||||||
|
let value_destroyed_sum = cfg.import_rolling("value_destroyed", v1)?;
|
||||||
|
let sopr = cfg.import_rolling("sopr", v1)?;
|
||||||
|
let sopr_24h_ema = cfg.import_emas_1w_1m("sopr_24h", v1)?;
|
||||||
|
|
||||||
|
let realized_price_ratio_percentiles =
|
||||||
|
ComputedFromHeightRatioPercentiles::forced_import(
|
||||||
|
cfg.db,
|
||||||
|
&cfg.name("realized_price"),
|
||||||
|
cfg.version + v1,
|
||||||
|
cfg.indexes,
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
complete,
|
minimal,
|
||||||
investor_price,
|
realized_cap_change_1m: cfg.import_computed("realized_cap_change_1m", v0)?,
|
||||||
investor_price_ratio,
|
neg_realized_loss,
|
||||||
lower_price_band,
|
net_realized_pnl,
|
||||||
upper_price_band,
|
net_realized_pnl_ema_1w,
|
||||||
cap_raw,
|
gross_pnl,
|
||||||
investor_cap_raw,
|
realized_profit_ema_1w,
|
||||||
sell_side_risk_ratio,
|
realized_loss_ema_1w,
|
||||||
sell_side_risk_ratio_24h_ema,
|
realized_profit_rel_to_realized_cap,
|
||||||
peak_regret,
|
realized_loss_rel_to_realized_cap,
|
||||||
peak_regret_rel_to_realized_cap,
|
net_realized_pnl_rel_to_realized_cap,
|
||||||
|
value_created,
|
||||||
|
value_destroyed,
|
||||||
|
value_created_sum,
|
||||||
|
value_destroyed_sum,
|
||||||
|
sopr,
|
||||||
|
sopr_24h_ema,
|
||||||
|
realized_price_ratio_percentiles,
|
||||||
|
sent_in_profit: cfg.import_value_cumulative("sent_in_profit", v0)?,
|
||||||
|
sent_in_loss: cfg.import_value_cumulative("sent_in_loss", v0)?,
|
||||||
|
sent_in_profit_ema: cfg.import_emas_2w("sent_in_profit", v0)?,
|
||||||
|
sent_in_loss_ema: cfg.import_emas_2w("sent_in_loss", v0)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn min_stateful_height_len(&self) -> usize {
|
pub(crate) fn min_stateful_height_len(&self) -> usize {
|
||||||
self.complete
|
self.minimal
|
||||||
.min_stateful_height_len()
|
.min_stateful_height_len()
|
||||||
.min(self.investor_price.cents.height.len())
|
.min(self.value_created.height.len())
|
||||||
.min(self.cap_raw.len())
|
.min(self.value_destroyed.height.len())
|
||||||
.min(self.investor_cap_raw.len())
|
.min(self.sent_in_profit.base.sats.height.len())
|
||||||
.min(self.peak_regret.height.len())
|
.min(self.sent_in_loss.base.sats.height.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn truncate_push(&mut self, height: Height, state: &RealizedState) -> Result<()> {
|
pub(crate) fn truncate_push(&mut self, height: Height, state: &impl RealizedOps) -> Result<()> {
|
||||||
self.complete.truncate_push(height, state)?;
|
self.minimal.truncate_push(height, state)?;
|
||||||
self.investor_price
|
self.value_created
|
||||||
.cents
|
|
||||||
.height
|
.height
|
||||||
.truncate_push(height, state.investor_price())?;
|
.truncate_push(height, state.value_created())?;
|
||||||
self.cap_raw.truncate_push(height, state.cap_raw())?;
|
self.value_destroyed
|
||||||
self.investor_cap_raw
|
|
||||||
.truncate_push(height, state.investor_cap_raw())?;
|
|
||||||
self.peak_regret
|
|
||||||
.height
|
.height
|
||||||
.truncate_push(height, state.peak_regret())?;
|
.truncate_push(height, state.value_destroyed())?;
|
||||||
|
self.sent_in_profit
|
||||||
|
.base
|
||||||
|
.sats
|
||||||
|
.height
|
||||||
|
.truncate_push(height, state.sent_in_profit())?;
|
||||||
|
self.sent_in_loss
|
||||||
|
.base
|
||||||
|
.sats
|
||||||
|
.height
|
||||||
|
.truncate_push(height, state.sent_in_loss())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||||
let mut vecs = self.complete.collect_vecs_mut();
|
let mut vecs = self.minimal.collect_vecs_mut();
|
||||||
vecs.push(&mut self.investor_price.cents.height as &mut dyn AnyStoredVec);
|
vecs.push(&mut self.value_created.height as &mut dyn AnyStoredVec);
|
||||||
vecs.push(&mut self.cap_raw as &mut dyn AnyStoredVec);
|
vecs.push(&mut self.value_destroyed.height);
|
||||||
vecs.push(&mut self.investor_cap_raw as &mut dyn AnyStoredVec);
|
vecs.push(&mut self.sent_in_profit.base.sats.height as &mut dyn AnyStoredVec);
|
||||||
vecs.push(&mut self.peak_regret.height as &mut dyn AnyStoredVec);
|
vecs.push(&mut self.sent_in_loss.base.sats.height);
|
||||||
vecs
|
vecs
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,80 +176,14 @@ impl RealizedFull {
|
|||||||
others: &[&Self],
|
others: &[&Self],
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// Delegate Complete-tier aggregation
|
let minimal_refs: Vec<&RealizedMinimal> = others.iter().map(|o| &o.minimal).collect();
|
||||||
let complete_refs: Vec<&RealizedComplete> =
|
self.minimal
|
||||||
others.iter().map(|o| &o.complete).collect();
|
.compute_from_stateful(starting_indexes, &minimal_refs, exit)?;
|
||||||
self.complete
|
|
||||||
.compute_from_stateful(starting_indexes, &complete_refs, exit)?;
|
|
||||||
|
|
||||||
// Aggregate raw values for investor_price computation
|
sum_others!(self, starting_indexes, others, exit; value_created.height);
|
||||||
let investor_price_dep_version = others
|
sum_others!(self, starting_indexes, others, exit; value_destroyed.height);
|
||||||
.iter()
|
sum_others!(self, starting_indexes, others, exit; sent_in_profit.base.sats.height);
|
||||||
.map(|o| o.investor_price.cents.height.version())
|
sum_others!(self, starting_indexes, others, exit; sent_in_loss.base.sats.height);
|
||||||
.fold(vecdb::Version::ZERO, |acc, v| acc + v);
|
|
||||||
self.investor_price
|
|
||||||
.cents
|
|
||||||
.height
|
|
||||||
.validate_computed_version_or_reset(investor_price_dep_version)?;
|
|
||||||
|
|
||||||
let start = self
|
|
||||||
.cap_raw
|
|
||||||
.len()
|
|
||||||
.min(self.investor_cap_raw.len())
|
|
||||||
.min(self.investor_price.cents.height.len());
|
|
||||||
let end = others.iter().map(|o| o.cap_raw.len()).min().unwrap_or(0);
|
|
||||||
|
|
||||||
// Pre-collect all cohort data to avoid per-element BytesVec reads in nested loop
|
|
||||||
let cap_ranges: Vec<Vec<CentsSats>> = others
|
|
||||||
.iter()
|
|
||||||
.map(|o| o.cap_raw.collect_range_at(start, end))
|
|
||||||
.collect();
|
|
||||||
let investor_cap_ranges: Vec<Vec<CentsSquaredSats>> = others
|
|
||||||
.iter()
|
|
||||||
.map(|o| o.investor_cap_raw.collect_range_at(start, end))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
for i in start..end {
|
|
||||||
let height = Height::from(i);
|
|
||||||
let local_i = i - start;
|
|
||||||
|
|
||||||
let mut sum_cap = CentsSats::ZERO;
|
|
||||||
let mut sum_investor_cap = CentsSquaredSats::ZERO;
|
|
||||||
|
|
||||||
for idx in 0..others.len() {
|
|
||||||
sum_cap += cap_ranges[idx][local_i];
|
|
||||||
sum_investor_cap += investor_cap_ranges[idx][local_i];
|
|
||||||
}
|
|
||||||
|
|
||||||
self.cap_raw.truncate_push(height, sum_cap)?;
|
|
||||||
self.investor_cap_raw
|
|
||||||
.truncate_push(height, sum_investor_cap)?;
|
|
||||||
|
|
||||||
let investor_price = if sum_cap.inner() == 0 {
|
|
||||||
Cents::ZERO
|
|
||||||
} else {
|
|
||||||
Cents::new((sum_investor_cap / sum_cap.inner()) as u64)
|
|
||||||
};
|
|
||||||
self.investor_price
|
|
||||||
.cents
|
|
||||||
.height
|
|
||||||
.truncate_push(height, investor_price)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let _lock = exit.lock();
|
|
||||||
self.investor_price.cents.height.write()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Source-only: peak_regret
|
|
||||||
self.peak_regret.height.compute_sum_of_others(
|
|
||||||
starting_indexes.height,
|
|
||||||
&others
|
|
||||||
.iter()
|
|
||||||
.map(|v| &v.peak_regret.height)
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -211,10 +193,31 @@ impl RealizedFull {
|
|||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.complete.compute_rest_part1(starting_indexes, exit)?;
|
self.minimal.compute_rest_part1(starting_indexes, exit)?;
|
||||||
|
|
||||||
self.peak_regret
|
self.net_realized_pnl
|
||||||
.compute_rest(starting_indexes.height, exit)?;
|
.compute(starting_indexes.height, exit, |vec| {
|
||||||
|
vec.compute_transform2(
|
||||||
|
starting_indexes.height,
|
||||||
|
&self.minimal.realized_profit.height,
|
||||||
|
&self.minimal.realized_loss.height,
|
||||||
|
|(i, profit, loss, ..)| {
|
||||||
|
(
|
||||||
|
i,
|
||||||
|
CentsSigned::new(profit.inner() as i64 - loss.inner() as i64),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self.gross_pnl.cents.height.compute_add(
|
||||||
|
starting_indexes.height,
|
||||||
|
&self.minimal.realized_profit.height,
|
||||||
|
&self.minimal.realized_loss.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -225,91 +228,121 @@ impl RealizedFull {
|
|||||||
prices: &prices::Vecs,
|
prices: &prices::Vecs,
|
||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
height_to_supply: &impl ReadableVec<Height, Bitcoin>,
|
height_to_supply: &impl ReadableVec<Height, Bitcoin>,
|
||||||
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
|
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// Compute all Complete-tier fields
|
self.minimal
|
||||||
self.complete.compute_rest_part2(
|
.compute_rest_part2(prices, starting_indexes, height_to_supply, exit)?;
|
||||||
blocks,
|
|
||||||
prices,
|
|
||||||
starting_indexes,
|
|
||||||
height_to_supply,
|
|
||||||
height_to_market_cap,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// Extended-only: investor_price ratio and price bands
|
self.realized_cap_change_1m.height.compute_rolling_change(
|
||||||
self.investor_price_ratio.compute_ratio(
|
|
||||||
starting_indexes,
|
|
||||||
&prices.price.cents.height,
|
|
||||||
&self.investor_price.cents.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
self.lower_price_band.cents.height.compute_transform2(
|
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.complete.realized_price.cents.height,
|
&blocks.count.height_1m_ago,
|
||||||
&self.investor_price.cents.height,
|
&self.minimal.realized_cap_cents.height,
|
||||||
|(i, rp, ip, ..)| {
|
|
||||||
let rp = rp.as_u128();
|
|
||||||
let ip = ip.as_u128();
|
|
||||||
if ip == 0 {
|
|
||||||
(i, Cents::ZERO)
|
|
||||||
} else {
|
|
||||||
(i, Cents::from(rp * rp / ip))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.upper_price_band.cents.height.compute_transform2(
|
self.realized_profit_ema_1w.height.compute_rolling_ema(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.investor_price.cents.height,
|
&blocks.count.height_1w_ago,
|
||||||
&self.complete.realized_price.cents.height,
|
&self.minimal.realized_profit.height,
|
||||||
|(i, ip, rp, ..)| {
|
exit,
|
||||||
let ip = ip.as_u128();
|
)?;
|
||||||
let rp = rp.as_u128();
|
self.realized_loss_ema_1w.height.compute_rolling_ema(
|
||||||
if rp == 0 {
|
starting_indexes.height,
|
||||||
(i, Cents::ZERO)
|
&blocks.count.height_1w_ago,
|
||||||
} else {
|
&self.minimal.realized_loss.height,
|
||||||
(i, Cents::from(ip * ip / rp))
|
exit,
|
||||||
}
|
)?;
|
||||||
},
|
self.net_realized_pnl_ema_1w.height.compute_rolling_ema(
|
||||||
|
starting_indexes.height,
|
||||||
|
&blocks.count.height_1w_ago,
|
||||||
|
&self.net_realized_pnl.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Extended-only: sell-side risk ratios
|
self.realized_profit_rel_to_realized_cap
|
||||||
for (ssrr, rv) in self
|
.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
||||||
.sell_side_risk_ratio
|
starting_indexes.height,
|
||||||
|
&self.minimal.realized_profit.height,
|
||||||
|
&self.minimal.realized_cap_cents.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.realized_loss_rel_to_realized_cap
|
||||||
|
.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
||||||
|
starting_indexes.height,
|
||||||
|
&self.minimal.realized_loss.height,
|
||||||
|
&self.minimal.realized_cap_cents.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.net_realized_pnl_rel_to_realized_cap
|
||||||
|
.compute_binary::<CentsSigned, Cents, RatioCentsSignedCentsBps32>(
|
||||||
|
starting_indexes.height,
|
||||||
|
&self.net_realized_pnl.height,
|
||||||
|
&self.minimal.realized_cap_cents.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// SOPR: rolling sums of stateful value_created/destroyed, then ratio, then EMAs
|
||||||
|
let window_starts = blocks.count.window_starts();
|
||||||
|
self.value_created_sum.compute_rolling_sum(
|
||||||
|
starting_indexes.height,
|
||||||
|
&window_starts,
|
||||||
|
&self.value_created.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.value_destroyed_sum.compute_rolling_sum(
|
||||||
|
starting_indexes.height,
|
||||||
|
&window_starts,
|
||||||
|
&self.value_destroyed.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
for ((sopr, vc), vd) in self
|
||||||
|
.sopr
|
||||||
.as_mut_array()
|
.as_mut_array()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.zip(self.complete.gross_pnl_sum.as_array())
|
.zip(self.value_created_sum.as_array())
|
||||||
|
.zip(self.value_destroyed_sum.as_array())
|
||||||
{
|
{
|
||||||
ssrr.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
sopr.compute_binary::<Cents, Cents, RatioCents64>(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&rv.height,
|
&vc.height,
|
||||||
&self.complete.realized_cap_cents.height,
|
&vd.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extended-only: sell side risk EMAs
|
self.sopr_24h_ema.compute_from_24h(
|
||||||
self.sell_side_risk_ratio_24h_ema.compute_from_24h(
|
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&blocks.count.height_1w_ago,
|
&blocks.count.height_1w_ago,
|
||||||
&blocks.count.height_1m_ago,
|
&blocks.count.height_1m_ago,
|
||||||
&self.sell_side_risk_ratio._24h.bps.height,
|
&self.sopr._24h.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Source-only: peak_regret relative to realized cap
|
// Realized price ratio percentiles
|
||||||
self.peak_regret_rel_to_realized_cap
|
self.realized_price_ratio_percentiles.compute(
|
||||||
.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
blocks,
|
||||||
starting_indexes.height,
|
starting_indexes,
|
||||||
&self.peak_regret.height,
|
exit,
|
||||||
&self.complete.realized_cap_cents.height,
|
&self.minimal.realized_price_ratio.ratio.height,
|
||||||
exit,
|
&self.minimal.realized_price.cents.height,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// Sent in profit/loss EMAs
|
||||||
|
self.sent_in_profit_ema.compute(
|
||||||
|
starting_indexes.height,
|
||||||
|
&blocks.count.height_2w_ago,
|
||||||
|
&self.sent_in_profit.base.sats.height,
|
||||||
|
&self.sent_in_profit.base.cents.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.sent_in_loss_ema.compute(
|
||||||
|
starting_indexes.height,
|
||||||
|
&blocks.count.height_2w_ago,
|
||||||
|
&self.sent_in_loss.base.sats.height,
|
||||||
|
&self.sent_in_loss.base.cents.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,245 +0,0 @@
|
|||||||
use brk_error::Result;
|
|
||||||
use brk_traversable::Traversable;
|
|
||||||
use brk_types::{
|
|
||||||
BasisPointsSigned32, Bitcoin, Cents, CentsSigned, Dollars, Height, Indexes, Version,
|
|
||||||
};
|
|
||||||
use derive_more::{Deref, DerefMut};
|
|
||||||
use vecdb::{
|
|
||||||
AnyStoredVec, AnyVec, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode, WritableVec,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
blocks,
|
|
||||||
distribution::state::RealizedState,
|
|
||||||
internal::{
|
|
||||||
CentsUnsignedToDollars, ComputedFromHeight, LazyFromHeight, PercentFromHeight,
|
|
||||||
RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32, RollingEmas2w, RollingWindows,
|
|
||||||
ValueFromHeightCumulative,
|
|
||||||
},
|
|
||||||
prices,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::distribution::metrics::ImportConfig;
|
|
||||||
|
|
||||||
use super::RealizedCore;
|
|
||||||
|
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
|
||||||
pub struct RealizedComplete<M: StorageMode = Rw> {
|
|
||||||
#[deref]
|
|
||||||
#[deref_mut]
|
|
||||||
#[traversable(flatten)]
|
|
||||||
pub core: RealizedCore<M>,
|
|
||||||
|
|
||||||
pub profit_value_created: ComputedFromHeight<Cents, M>,
|
|
||||||
pub profit_value_destroyed: ComputedFromHeight<Cents, M>,
|
|
||||||
pub loss_value_created: ComputedFromHeight<Cents, M>,
|
|
||||||
pub loss_value_destroyed: ComputedFromHeight<Cents, M>,
|
|
||||||
|
|
||||||
pub capitulation_flow: LazyFromHeight<Dollars, Cents>,
|
|
||||||
pub profit_flow: LazyFromHeight<Dollars, Cents>,
|
|
||||||
|
|
||||||
pub gross_pnl_sum: RollingWindows<Cents, M>,
|
|
||||||
|
|
||||||
pub net_pnl_change_1m: ComputedFromHeight<CentsSigned, M>,
|
|
||||||
pub net_pnl_change_1m_rel_to_realized_cap: PercentFromHeight<BasisPointsSigned32, M>,
|
|
||||||
pub net_pnl_change_1m_rel_to_market_cap: PercentFromHeight<BasisPointsSigned32, M>,
|
|
||||||
|
|
||||||
pub sent_in_profit: ValueFromHeightCumulative<M>,
|
|
||||||
pub sent_in_profit_ema: RollingEmas2w<M>,
|
|
||||||
pub sent_in_loss: ValueFromHeightCumulative<M>,
|
|
||||||
pub sent_in_loss_ema: RollingEmas2w<M>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RealizedComplete {
|
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
|
||||||
let v0 = Version::ZERO;
|
|
||||||
|
|
||||||
let core = RealizedCore::forced_import(cfg)?;
|
|
||||||
|
|
||||||
let profit_value_created = cfg.import_computed("profit_value_created", v0)?;
|
|
||||||
let profit_value_destroyed = cfg.import_computed("profit_value_destroyed", v0)?;
|
|
||||||
let loss_value_created = cfg.import_computed("loss_value_created", v0)?;
|
|
||||||
let loss_value_destroyed = cfg.import_computed("loss_value_destroyed", v0)?;
|
|
||||||
|
|
||||||
let capitulation_flow = LazyFromHeight::from_computed::<CentsUnsignedToDollars>(
|
|
||||||
&cfg.name("capitulation_flow"),
|
|
||||||
cfg.version,
|
|
||||||
loss_value_destroyed.height.read_only_boxed_clone(),
|
|
||||||
&loss_value_destroyed,
|
|
||||||
);
|
|
||||||
let profit_flow = LazyFromHeight::from_computed::<CentsUnsignedToDollars>(
|
|
||||||
&cfg.name("profit_flow"),
|
|
||||||
cfg.version,
|
|
||||||
profit_value_destroyed.height.read_only_boxed_clone(),
|
|
||||||
&profit_value_destroyed,
|
|
||||||
);
|
|
||||||
|
|
||||||
let gross_pnl_sum = cfg.import_rolling("gross_pnl_sum", Version::ONE)?;
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
core,
|
|
||||||
profit_value_created,
|
|
||||||
profit_value_destroyed,
|
|
||||||
loss_value_created,
|
|
||||||
loss_value_destroyed,
|
|
||||||
capitulation_flow,
|
|
||||||
profit_flow,
|
|
||||||
gross_pnl_sum,
|
|
||||||
net_pnl_change_1m: cfg.import_computed("net_pnl_change_1m", Version::new(3))?,
|
|
||||||
net_pnl_change_1m_rel_to_realized_cap: cfg
|
|
||||||
.import_percent_bps32("net_pnl_change_1m_rel_to_realized_cap", Version::new(4))?,
|
|
||||||
net_pnl_change_1m_rel_to_market_cap: cfg
|
|
||||||
.import_percent_bps32("net_pnl_change_1m_rel_to_market_cap", Version::new(4))?,
|
|
||||||
sent_in_profit: cfg.import_value_cumulative("sent_in_profit", v0)?,
|
|
||||||
sent_in_profit_ema: cfg.import_emas_2w("sent_in_profit", v0)?,
|
|
||||||
sent_in_loss: cfg.import_value_cumulative("sent_in_loss", v0)?,
|
|
||||||
sent_in_loss_ema: cfg.import_emas_2w("sent_in_loss", v0)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn min_stateful_height_len(&self) -> usize {
|
|
||||||
self.core
|
|
||||||
.min_stateful_height_len()
|
|
||||||
.min(self.profit_value_created.height.len())
|
|
||||||
.min(self.profit_value_destroyed.height.len())
|
|
||||||
.min(self.loss_value_created.height.len())
|
|
||||||
.min(self.loss_value_destroyed.height.len())
|
|
||||||
.min(self.sent_in_profit.base.sats.height.len())
|
|
||||||
.min(self.sent_in_loss.base.sats.height.len())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn truncate_push(&mut self, height: Height, state: &RealizedState) -> Result<()> {
|
|
||||||
self.core.truncate_push(height, state)?;
|
|
||||||
self.profit_value_created
|
|
||||||
.height
|
|
||||||
.truncate_push(height, state.profit_value_created())?;
|
|
||||||
self.profit_value_destroyed
|
|
||||||
.height
|
|
||||||
.truncate_push(height, state.profit_value_destroyed())?;
|
|
||||||
self.loss_value_created
|
|
||||||
.height
|
|
||||||
.truncate_push(height, state.loss_value_created())?;
|
|
||||||
self.loss_value_destroyed
|
|
||||||
.height
|
|
||||||
.truncate_push(height, state.loss_value_destroyed())?;
|
|
||||||
self.sent_in_profit
|
|
||||||
.base
|
|
||||||
.sats
|
|
||||||
.height
|
|
||||||
.truncate_push(height, state.sent_in_profit())?;
|
|
||||||
self.sent_in_loss
|
|
||||||
.base
|
|
||||||
.sats
|
|
||||||
.height
|
|
||||||
.truncate_push(height, state.sent_in_loss())?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
|
||||||
let mut vecs = self.core.collect_vecs_mut();
|
|
||||||
vecs.push(&mut self.profit_value_created.height as &mut dyn AnyStoredVec);
|
|
||||||
vecs.push(&mut self.profit_value_destroyed.height);
|
|
||||||
vecs.push(&mut self.loss_value_created.height);
|
|
||||||
vecs.push(&mut self.loss_value_destroyed.height);
|
|
||||||
vecs.push(&mut self.sent_in_profit.base.sats.height);
|
|
||||||
vecs.push(&mut self.sent_in_loss.base.sats.height);
|
|
||||||
vecs
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute_from_stateful(
|
|
||||||
&mut self,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
others: &[&Self],
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
let core_refs: Vec<&RealizedCore> = others.iter().map(|o| &o.core).collect();
|
|
||||||
self.core
|
|
||||||
.compute_from_stateful(starting_indexes, &core_refs, exit)?;
|
|
||||||
|
|
||||||
sum_others!(self, starting_indexes, others, exit; profit_value_created.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; profit_value_destroyed.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; loss_value_created.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; loss_value_destroyed.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; sent_in_profit.base.sats.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; sent_in_loss.base.sats.height);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute_rest_part1(
|
|
||||||
&mut self,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.core.compute_rest_part1(starting_indexes, exit)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute_rest_part2(
|
|
||||||
&mut self,
|
|
||||||
blocks: &blocks::Vecs,
|
|
||||||
prices: &prices::Vecs,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
height_to_supply: &impl ReadableVec<Height, Bitcoin>,
|
|
||||||
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.core.compute_rest_part2(
|
|
||||||
blocks,
|
|
||||||
prices,
|
|
||||||
starting_indexes,
|
|
||||||
height_to_supply,
|
|
||||||
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,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
self.sent_in_profit_ema.compute(
|
|
||||||
starting_indexes.height,
|
|
||||||
&blocks.count.height_2w_ago,
|
|
||||||
&self.sent_in_profit.base.sats.height,
|
|
||||||
&self.sent_in_profit.base.cents.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
self.sent_in_loss_ema.compute(
|
|
||||||
starting_indexes.height,
|
|
||||||
&blocks.count.height_2w_ago,
|
|
||||||
&self.sent_in_loss.base.sats.height,
|
|
||||||
&self.sent_in_loss.base.cents.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
self.net_pnl_change_1m.height.compute_rolling_change(
|
|
||||||
starting_indexes.height,
|
|
||||||
&blocks.count.height_1m_ago,
|
|
||||||
&self.core.net_realized_pnl.cumulative.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
self.net_pnl_change_1m_rel_to_realized_cap
|
|
||||||
.compute_binary::<CentsSigned, Cents, RatioCentsSignedCentsBps32>(
|
|
||||||
starting_indexes.height,
|
|
||||||
&self.net_pnl_change_1m.height,
|
|
||||||
&self.core.realized_cap_cents.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
self.net_pnl_change_1m_rel_to_market_cap
|
|
||||||
.compute_binary::<CentsSigned, Dollars, RatioCentsSignedDollarsBps32>(
|
|
||||||
starting_indexes.height,
|
|
||||||
&self.net_pnl_change_1m.height,
|
|
||||||
height_to_market_cap,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,347 +0,0 @@
|
|||||||
use brk_error::Result;
|
|
||||||
use brk_traversable::Traversable;
|
|
||||||
use brk_types::{
|
|
||||||
BasisPoints32, BasisPointsSigned32, Bitcoin, Cents, CentsSigned, Dollars, Height, Indexes,
|
|
||||||
Sats, StoredF32, StoredF64, Version,
|
|
||||||
};
|
|
||||||
use vecdb::{
|
|
||||||
AnyStoredVec, AnyVec, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode, WritableVec,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
blocks,
|
|
||||||
distribution::state::RealizedOps,
|
|
||||||
internal::{
|
|
||||||
CentsUnsignedToDollars, ComputedFromHeight, ComputedFromHeightCumulative,
|
|
||||||
ComputedFromHeightRatio, FiatFromHeight, Identity, LazyFromHeight,
|
|
||||||
NegCentsUnsignedToDollars, PercentFromHeight, Price, RatioCents64, RatioCentsBp32,
|
|
||||||
RatioCentsSignedCentsBps32, RollingEmas1w1m, RollingWindows,
|
|
||||||
},
|
|
||||||
prices,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::distribution::metrics::ImportConfig;
|
|
||||||
|
|
||||||
#[derive(Traversable)]
|
|
||||||
pub struct RealizedCore<M: StorageMode = Rw> {
|
|
||||||
pub realized_cap_cents: ComputedFromHeight<Cents, M>,
|
|
||||||
pub realized_profit: ComputedFromHeightCumulative<Cents, M>,
|
|
||||||
pub realized_loss: ComputedFromHeightCumulative<Cents, M>,
|
|
||||||
|
|
||||||
pub realized_cap: LazyFromHeight<Dollars, Cents>,
|
|
||||||
pub realized_price: Price<ComputedFromHeight<Cents, M>>,
|
|
||||||
pub realized_price_ratio: ComputedFromHeightRatio<M>,
|
|
||||||
pub realized_cap_change_1m: ComputedFromHeight<CentsSigned, M>,
|
|
||||||
|
|
||||||
pub mvrv: LazyFromHeight<StoredF32>,
|
|
||||||
|
|
||||||
pub neg_realized_loss: LazyFromHeight<Dollars, Cents>,
|
|
||||||
pub net_realized_pnl: ComputedFromHeightCumulative<CentsSigned, M>,
|
|
||||||
pub net_realized_pnl_ema_1w: ComputedFromHeight<CentsSigned, M>,
|
|
||||||
pub gross_pnl: FiatFromHeight<Cents, M>,
|
|
||||||
|
|
||||||
pub realized_profit_ema_1w: ComputedFromHeight<Cents, M>,
|
|
||||||
pub realized_loss_ema_1w: ComputedFromHeight<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>,
|
|
||||||
|
|
||||||
pub value_created: ComputedFromHeight<Cents, M>,
|
|
||||||
pub value_destroyed: ComputedFromHeight<Cents, M>,
|
|
||||||
pub value_created_sum: RollingWindows<Cents, M>,
|
|
||||||
pub value_destroyed_sum: RollingWindows<Cents, M>,
|
|
||||||
pub sopr: RollingWindows<StoredF64, M>,
|
|
||||||
pub sopr_24h_ema: RollingEmas1w1m<StoredF64, M>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RealizedCore {
|
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
|
||||||
let v0 = Version::ZERO;
|
|
||||||
let v1 = Version::ONE;
|
|
||||||
|
|
||||||
let realized_cap_cents = cfg.import_computed("realized_cap_cents", v0)?;
|
|
||||||
let realized_cap = LazyFromHeight::from_computed::<CentsUnsignedToDollars>(
|
|
||||||
&cfg.name("realized_cap"),
|
|
||||||
cfg.version,
|
|
||||||
realized_cap_cents.height.read_only_boxed_clone(),
|
|
||||||
&realized_cap_cents,
|
|
||||||
);
|
|
||||||
|
|
||||||
let realized_profit = cfg.import_cumulative("realized_profit", v0)?;
|
|
||||||
let realized_profit_ema_1w = cfg.import_computed("realized_profit_ema_1w", v0)?;
|
|
||||||
let realized_loss = cfg.import_cumulative("realized_loss", v0)?;
|
|
||||||
let realized_loss_ema_1w = cfg.import_computed("realized_loss_ema_1w", v0)?;
|
|
||||||
|
|
||||||
let neg_realized_loss = LazyFromHeight::from_height_source::<NegCentsUnsignedToDollars>(
|
|
||||||
&cfg.name("neg_realized_loss"),
|
|
||||||
cfg.version + Version::ONE,
|
|
||||||
realized_loss.height.read_only_boxed_clone(),
|
|
||||||
cfg.indexes,
|
|
||||||
);
|
|
||||||
|
|
||||||
let net_realized_pnl = cfg.import_cumulative("net_realized_pnl", v0)?;
|
|
||||||
let net_realized_pnl_ema_1w = cfg.import_computed("net_realized_pnl_ema_1w", v0)?;
|
|
||||||
let gross_pnl = cfg.import_fiat("realized_gross_pnl", v0)?;
|
|
||||||
|
|
||||||
let realized_profit_rel_to_realized_cap =
|
|
||||||
cfg.import_percent_bp32("realized_profit_rel_to_realized_cap", Version::new(2))?;
|
|
||||||
let realized_loss_rel_to_realized_cap =
|
|
||||||
cfg.import_percent_bp32("realized_loss_rel_to_realized_cap", Version::new(2))?;
|
|
||||||
let net_realized_pnl_rel_to_realized_cap =
|
|
||||||
cfg.import_percent_bps32("net_realized_pnl_rel_to_realized_cap", Version::new(2))?;
|
|
||||||
|
|
||||||
let realized_price = cfg.import_price("realized_price", v1)?;
|
|
||||||
|
|
||||||
let realized_price_ratio = cfg.import_ratio("realized_price", v1)?;
|
|
||||||
let mvrv = LazyFromHeight::from_lazy::<Identity<StoredF32>, BasisPoints32>(
|
|
||||||
&cfg.name("mvrv"),
|
|
||||||
cfg.version,
|
|
||||||
&realized_price_ratio.ratio,
|
|
||||||
);
|
|
||||||
|
|
||||||
let value_created = cfg.import_computed("value_created", v0)?;
|
|
||||||
let value_destroyed = cfg.import_computed("value_destroyed", v0)?;
|
|
||||||
let value_created_sum = cfg.import_rolling("value_created", v1)?;
|
|
||||||
let value_destroyed_sum = cfg.import_rolling("value_destroyed", v1)?;
|
|
||||||
let sopr = cfg.import_rolling("sopr", v1)?;
|
|
||||||
let sopr_24h_ema = cfg.import_emas_1w_1m("sopr_24h", v1)?;
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
realized_cap_cents,
|
|
||||||
realized_cap,
|
|
||||||
realized_price,
|
|
||||||
realized_price_ratio,
|
|
||||||
realized_cap_change_1m: cfg.import_computed("realized_cap_change_1m", v0)?,
|
|
||||||
mvrv,
|
|
||||||
realized_profit,
|
|
||||||
realized_profit_ema_1w,
|
|
||||||
realized_loss,
|
|
||||||
realized_loss_ema_1w,
|
|
||||||
neg_realized_loss,
|
|
||||||
net_realized_pnl,
|
|
||||||
net_realized_pnl_ema_1w,
|
|
||||||
gross_pnl,
|
|
||||||
realized_profit_rel_to_realized_cap,
|
|
||||||
realized_loss_rel_to_realized_cap,
|
|
||||||
net_realized_pnl_rel_to_realized_cap,
|
|
||||||
value_created,
|
|
||||||
value_destroyed,
|
|
||||||
value_created_sum,
|
|
||||||
value_destroyed_sum,
|
|
||||||
sopr,
|
|
||||||
sopr_24h_ema,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn min_stateful_height_len(&self) -> usize {
|
|
||||||
self.realized_cap_cents
|
|
||||||
.height
|
|
||||||
.len()
|
|
||||||
.min(self.realized_profit.height.len())
|
|
||||||
.min(self.realized_loss.height.len())
|
|
||||||
.min(self.value_created.height.len())
|
|
||||||
.min(self.value_destroyed.height.len())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn truncate_push(&mut self, height: Height, state: &impl RealizedOps) -> Result<()> {
|
|
||||||
self.realized_cap_cents
|
|
||||||
.height
|
|
||||||
.truncate_push(height, state.cap())?;
|
|
||||||
self.realized_profit
|
|
||||||
.height
|
|
||||||
.truncate_push(height, state.profit())?;
|
|
||||||
self.realized_loss
|
|
||||||
.height
|
|
||||||
.truncate_push(height, state.loss())?;
|
|
||||||
self.value_created
|
|
||||||
.height
|
|
||||||
.truncate_push(height, state.value_created())?;
|
|
||||||
self.value_destroyed
|
|
||||||
.height
|
|
||||||
.truncate_push(height, state.value_destroyed())?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
|
||||||
vec![
|
|
||||||
&mut self.realized_cap_cents.height as &mut dyn AnyStoredVec,
|
|
||||||
&mut self.realized_profit.height,
|
|
||||||
&mut self.realized_loss.height,
|
|
||||||
&mut self.value_created.height,
|
|
||||||
&mut self.value_destroyed.height,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute_from_stateful(
|
|
||||||
&mut self,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
others: &[&Self],
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
sum_others!(self, starting_indexes, others, exit; realized_cap_cents.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; realized_profit.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; realized_loss.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; value_created.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; value_destroyed.height);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute_rest_part1(
|
|
||||||
&mut self,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.realized_profit
|
|
||||||
.compute_rest(starting_indexes.height, exit)?;
|
|
||||||
self.realized_loss
|
|
||||||
.compute_rest(starting_indexes.height, exit)?;
|
|
||||||
|
|
||||||
self.net_realized_pnl
|
|
||||||
.compute(starting_indexes.height, exit, |vec| {
|
|
||||||
vec.compute_transform2(
|
|
||||||
starting_indexes.height,
|
|
||||||
&self.realized_profit.height,
|
|
||||||
&self.realized_loss.height,
|
|
||||||
|(i, profit, loss, ..)| {
|
|
||||||
(
|
|
||||||
i,
|
|
||||||
CentsSigned::new(profit.inner() as i64 - loss.inner() as i64),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
Ok(())
|
|
||||||
})?;
|
|
||||||
|
|
||||||
self.gross_pnl.cents.height.compute_add(
|
|
||||||
starting_indexes.height,
|
|
||||||
&self.realized_profit.height,
|
|
||||||
&self.realized_loss.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute_rest_part2(
|
|
||||||
&mut self,
|
|
||||||
blocks: &blocks::Vecs,
|
|
||||||
prices: &prices::Vecs,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
height_to_supply: &impl ReadableVec<Height, Bitcoin>,
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.realized_price.cents.height.compute_transform2(
|
|
||||||
starting_indexes.height,
|
|
||||||
&self.realized_cap_cents.height,
|
|
||||||
height_to_supply,
|
|
||||||
|(i, cap_cents, supply, ..)| {
|
|
||||||
let cap = cap_cents.as_u128();
|
|
||||||
let supply_sats = Sats::from(supply).as_u128();
|
|
||||||
if supply_sats == 0 {
|
|
||||||
(i, Cents::ZERO)
|
|
||||||
} else {
|
|
||||||
(i, Cents::from(cap * Sats::ONE_BTC_U128 / supply_sats))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
self.realized_price_ratio.compute_ratio(
|
|
||||||
starting_indexes,
|
|
||||||
&prices.price.cents.height,
|
|
||||||
&self.realized_price.cents.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
self.realized_cap_change_1m.height.compute_rolling_change(
|
|
||||||
starting_indexes.height,
|
|
||||||
&blocks.count.height_1m_ago,
|
|
||||||
&self.realized_cap_cents.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
self.realized_profit_ema_1w.height.compute_rolling_ema(
|
|
||||||
starting_indexes.height,
|
|
||||||
&blocks.count.height_1w_ago,
|
|
||||||
&self.realized_profit.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
self.realized_loss_ema_1w.height.compute_rolling_ema(
|
|
||||||
starting_indexes.height,
|
|
||||||
&blocks.count.height_1w_ago,
|
|
||||||
&self.realized_loss.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
self.net_realized_pnl_ema_1w.height.compute_rolling_ema(
|
|
||||||
starting_indexes.height,
|
|
||||||
&blocks.count.height_1w_ago,
|
|
||||||
&self.net_realized_pnl.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
self.realized_profit_rel_to_realized_cap
|
|
||||||
.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
|
||||||
starting_indexes.height,
|
|
||||||
&self.realized_profit.height,
|
|
||||||
&self.realized_cap_cents.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
self.realized_loss_rel_to_realized_cap
|
|
||||||
.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
|
||||||
starting_indexes.height,
|
|
||||||
&self.realized_loss.height,
|
|
||||||
&self.realized_cap_cents.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
self.net_realized_pnl_rel_to_realized_cap
|
|
||||||
.compute_binary::<CentsSigned, Cents, RatioCentsSignedCentsBps32>(
|
|
||||||
starting_indexes.height,
|
|
||||||
&self.net_realized_pnl.height,
|
|
||||||
&self.realized_cap_cents.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// SOPR: rolling sums of stateful value_created/destroyed, then ratio, then EMAs
|
|
||||||
let window_starts = blocks.count.window_starts();
|
|
||||||
self.value_created_sum.compute_rolling_sum(
|
|
||||||
starting_indexes.height,
|
|
||||||
&window_starts,
|
|
||||||
&self.value_created.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
self.value_destroyed_sum.compute_rolling_sum(
|
|
||||||
starting_indexes.height,
|
|
||||||
&window_starts,
|
|
||||||
&self.value_destroyed.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
for ((sopr, vc), vd) in self
|
|
||||||
.sopr
|
|
||||||
.as_mut_array()
|
|
||||||
.into_iter()
|
|
||||||
.zip(self.value_created_sum.as_array())
|
|
||||||
.zip(self.value_destroyed_sum.as_array())
|
|
||||||
{
|
|
||||||
sopr.compute_binary::<Cents, Cents, RatioCents64>(
|
|
||||||
starting_indexes.height,
|
|
||||||
&vc.height,
|
|
||||||
&vd.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.sopr_24h_ema.compute_from_24h(
|
|
||||||
starting_indexes.height,
|
|
||||||
&blocks.count.height_1w_ago,
|
|
||||||
&blocks.count.height_1m_ago,
|
|
||||||
&self.sopr._24h.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
use brk_error::Result;
|
|
||||||
use brk_traversable::Traversable;
|
|
||||||
use brk_types::{BasisPoints32, Cents, Dollars, Height, Indexes, StoredF64, Version};
|
|
||||||
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
blocks,
|
|
||||||
internal::{
|
|
||||||
ComputedFromHeightRatioPercentiles, ComputedFromHeightRatioStdDevBands,
|
|
||||||
PercentFromHeight, RatioCents64, RatioDollarsBp32, RollingWindows,
|
|
||||||
},
|
|
||||||
prices,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::distribution::metrics::ImportConfig;
|
|
||||||
|
|
||||||
use super::RealizedFull;
|
|
||||||
|
|
||||||
#[derive(Traversable)]
|
|
||||||
pub struct RealizedExtended<M: StorageMode = Rw> {
|
|
||||||
pub realized_cap_rel_to_own_market_cap: PercentFromHeight<BasisPoints32, M>,
|
|
||||||
|
|
||||||
pub realized_profit_sum: RollingWindows<Cents, M>,
|
|
||||||
pub realized_loss_sum: RollingWindows<Cents, M>,
|
|
||||||
|
|
||||||
pub realized_profit_to_loss_ratio: RollingWindows<StoredF64, M>,
|
|
||||||
|
|
||||||
pub realized_price_ratio_percentiles: ComputedFromHeightRatioPercentiles<M>,
|
|
||||||
pub realized_price_ratio_std_dev: ComputedFromHeightRatioStdDevBands<M>,
|
|
||||||
pub investor_price_ratio_percentiles: ComputedFromHeightRatioPercentiles<M>,
|
|
||||||
pub investor_price_ratio_std_dev: ComputedFromHeightRatioStdDevBands<M>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RealizedExtended {
|
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
|
||||||
let realized_price_name = cfg.name("realized_price");
|
|
||||||
let realized_price_version = cfg.version + Version::ONE;
|
|
||||||
let investor_price_name = cfg.name("investor_price");
|
|
||||||
let investor_price_version = cfg.version;
|
|
||||||
|
|
||||||
Ok(RealizedExtended {
|
|
||||||
realized_cap_rel_to_own_market_cap: cfg
|
|
||||||
.import_percent_bp32("realized_cap_rel_to_own_market_cap", Version::ONE)?,
|
|
||||||
realized_profit_sum: cfg.import_rolling("realized_profit", Version::ONE)?,
|
|
||||||
realized_loss_sum: cfg.import_rolling("realized_loss", Version::ONE)?,
|
|
||||||
realized_profit_to_loss_ratio: cfg
|
|
||||||
.import_rolling("realized_profit_to_loss_ratio", Version::ONE)?,
|
|
||||||
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,
|
|
||||||
realized_price_version,
|
|
||||||
cfg.indexes,
|
|
||||||
)?,
|
|
||||||
investor_price_ratio_percentiles: ComputedFromHeightRatioPercentiles::forced_import(
|
|
||||||
cfg.db,
|
|
||||||
&investor_price_name,
|
|
||||||
investor_price_version,
|
|
||||||
cfg.indexes,
|
|
||||||
)?,
|
|
||||||
investor_price_ratio_std_dev: ComputedFromHeightRatioStdDevBands::forced_import(
|
|
||||||
cfg.db,
|
|
||||||
&investor_price_name,
|
|
||||||
investor_price_version,
|
|
||||||
cfg.indexes,
|
|
||||||
)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute_rest_part2(
|
|
||||||
&mut self,
|
|
||||||
base: &RealizedFull,
|
|
||||||
blocks: &blocks::Vecs,
|
|
||||||
prices: &prices::Vecs,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
// Realized profit/loss rolling sums
|
|
||||||
let window_starts = blocks.count.window_starts();
|
|
||||||
self.realized_profit_sum.compute_rolling_sum(
|
|
||||||
starting_indexes.height,
|
|
||||||
&window_starts,
|
|
||||||
&base.realized_profit.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
self.realized_loss_sum.compute_rolling_sum(
|
|
||||||
starting_indexes.height,
|
|
||||||
&window_starts,
|
|
||||||
&base.realized_loss.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// Realized cap relative to own market cap
|
|
||||||
self.realized_cap_rel_to_own_market_cap
|
|
||||||
.compute_binary::<Dollars, Dollars, RatioDollarsBp32>(
|
|
||||||
starting_indexes.height,
|
|
||||||
&base.realized_cap.height,
|
|
||||||
height_to_market_cap,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// Realized profit to loss ratios
|
|
||||||
for ((ratio, profit), loss) in self
|
|
||||||
.realized_profit_to_loss_ratio
|
|
||||||
.as_mut_array()
|
|
||||||
.into_iter()
|
|
||||||
.zip(self.realized_profit_sum.as_array())
|
|
||||||
.zip(self.realized_loss_sum.as_array())
|
|
||||||
{
|
|
||||||
ratio.compute_binary::<Cents, Cents, RatioCents64>(
|
|
||||||
starting_indexes.height,
|
|
||||||
&profit.height,
|
|
||||||
&loss.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Realized price: percentiles + stddev bands
|
|
||||||
let realized_price = &base.realized_price.cents.height;
|
|
||||||
self.realized_price_ratio_percentiles.compute(
|
|
||||||
blocks,
|
|
||||||
starting_indexes,
|
|
||||||
exit,
|
|
||||||
&base.realized_price_ratio.ratio.height,
|
|
||||||
realized_price,
|
|
||||||
)?;
|
|
||||||
self.realized_price_ratio_std_dev.compute(
|
|
||||||
blocks,
|
|
||||||
starting_indexes,
|
|
||||||
exit,
|
|
||||||
&base.realized_price_ratio.ratio.height,
|
|
||||||
realized_price,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// Investor price: percentiles + stddev bands
|
|
||||||
let investor_price = &base.investor_price.cents.height;
|
|
||||||
self.investor_price_ratio_percentiles.compute(
|
|
||||||
blocks,
|
|
||||||
starting_indexes,
|
|
||||||
exit,
|
|
||||||
&base.investor_price_ratio.ratio.height,
|
|
||||||
investor_price,
|
|
||||||
)?;
|
|
||||||
self.investor_price_ratio_std_dev.compute(
|
|
||||||
blocks,
|
|
||||||
starting_indexes,
|
|
||||||
exit,
|
|
||||||
&base.investor_price_ratio.ratio.height,
|
|
||||||
investor_price,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@ use brk_error::Result;
|
|||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{
|
use brk_types::{
|
||||||
BasisPoints32, BasisPointsSigned32, Bitcoin, Cents, CentsSats, CentsSigned, CentsSquaredSats,
|
BasisPoints32, BasisPointsSigned32, Bitcoin, Cents, CentsSats, CentsSigned, CentsSquaredSats,
|
||||||
Dollars, Height, Indexes, Version,
|
Dollars, Height, Indexes, StoredF64, Version,
|
||||||
};
|
};
|
||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use vecdb::{
|
use vecdb::{
|
||||||
@@ -15,26 +15,26 @@ use crate::{
|
|||||||
distribution::state::RealizedState,
|
distribution::state::RealizedState,
|
||||||
internal::{
|
internal::{
|
||||||
CentsUnsignedToDollars, ComputedFromHeight, ComputedFromHeightCumulative,
|
CentsUnsignedToDollars, ComputedFromHeight, ComputedFromHeightCumulative,
|
||||||
ComputedFromHeightRatio, ComputedFromHeightRatioPercentiles, LazyFromHeight,
|
ComputedFromHeightRatio, ComputedFromHeightRatioPercentiles,
|
||||||
PercentFromHeight, PercentRollingEmas1w1m, PercentRollingWindows, Price, RatioCentsBp32,
|
ComputedFromHeightRatioStdDevBands, LazyFromHeight, PercentFromHeight,
|
||||||
RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32, RollingEmas2w, RollingWindows,
|
PercentRollingEmas1w1m, PercentRollingWindows, Price, RatioCents64, RatioCentsBp32,
|
||||||
ValueFromHeightCumulative,
|
RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32, RatioDollarsBp32,
|
||||||
|
RollingWindows,
|
||||||
},
|
},
|
||||||
prices,
|
prices,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::distribution::metrics::ImportConfig;
|
use crate::distribution::metrics::ImportConfig;
|
||||||
|
|
||||||
use super::RealizedCore;
|
use super::RealizedBase;
|
||||||
|
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
pub struct RealizedBasic<M: StorageMode = Rw> {
|
pub struct RealizedFull<M: StorageMode = Rw> {
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub core: RealizedCore<M>,
|
pub core: RealizedBase<M>,
|
||||||
|
|
||||||
// --- Stateful fields ---
|
|
||||||
pub profit_value_created: ComputedFromHeight<Cents, M>,
|
pub profit_value_created: ComputedFromHeight<Cents, M>,
|
||||||
pub profit_value_destroyed: ComputedFromHeight<Cents, M>,
|
pub profit_value_destroyed: ComputedFromHeight<Cents, M>,
|
||||||
pub loss_value_created: ComputedFromHeight<Cents, M>,
|
pub loss_value_created: ComputedFromHeight<Cents, M>,
|
||||||
@@ -49,12 +49,6 @@ pub struct RealizedBasic<M: StorageMode = Rw> {
|
|||||||
pub net_pnl_change_1m_rel_to_realized_cap: PercentFromHeight<BasisPointsSigned32, M>,
|
pub net_pnl_change_1m_rel_to_realized_cap: PercentFromHeight<BasisPointsSigned32, M>,
|
||||||
pub net_pnl_change_1m_rel_to_market_cap: PercentFromHeight<BasisPointsSigned32, M>,
|
pub net_pnl_change_1m_rel_to_market_cap: PercentFromHeight<BasisPointsSigned32, M>,
|
||||||
|
|
||||||
pub sent_in_profit: ValueFromHeightCumulative<M>,
|
|
||||||
pub sent_in_profit_ema: RollingEmas2w<M>,
|
|
||||||
pub sent_in_loss: ValueFromHeightCumulative<M>,
|
|
||||||
pub sent_in_loss_ema: RollingEmas2w<M>,
|
|
||||||
|
|
||||||
// --- Investor price & price bands ---
|
|
||||||
pub investor_price: Price<ComputedFromHeight<Cents, M>>,
|
pub investor_price: Price<ComputedFromHeight<Cents, M>>,
|
||||||
pub investor_price_ratio: ComputedFromHeightRatio<M>,
|
pub investor_price_ratio: ComputedFromHeightRatio<M>,
|
||||||
|
|
||||||
@@ -67,22 +61,27 @@ pub struct RealizedBasic<M: StorageMode = Rw> {
|
|||||||
pub sell_side_risk_ratio: PercentRollingWindows<BasisPoints32, M>,
|
pub sell_side_risk_ratio: PercentRollingWindows<BasisPoints32, M>,
|
||||||
pub sell_side_risk_ratio_24h_ema: PercentRollingEmas1w1m<BasisPoints32, M>,
|
pub sell_side_risk_ratio_24h_ema: PercentRollingEmas1w1m<BasisPoints32, M>,
|
||||||
|
|
||||||
// --- Peak regret ---
|
|
||||||
pub peak_regret: ComputedFromHeightCumulative<Cents, M>,
|
pub peak_regret: ComputedFromHeightCumulative<Cents, M>,
|
||||||
pub peak_regret_rel_to_realized_cap: PercentFromHeight<BasisPoints32, M>,
|
pub peak_regret_rel_to_realized_cap: PercentFromHeight<BasisPoints32, M>,
|
||||||
|
|
||||||
// --- Realized price ratio percentiles ---
|
pub realized_cap_rel_to_own_market_cap: PercentFromHeight<BasisPoints32, M>,
|
||||||
pub realized_price_ratio_percentiles: ComputedFromHeightRatioPercentiles<M>,
|
|
||||||
|
pub realized_profit_sum: RollingWindows<Cents, M>,
|
||||||
|
pub realized_loss_sum: RollingWindows<Cents, M>,
|
||||||
|
pub realized_profit_to_loss_ratio: RollingWindows<StoredF64, M>,
|
||||||
|
|
||||||
|
pub realized_price_ratio_std_dev: ComputedFromHeightRatioStdDevBands<M>,
|
||||||
|
pub investor_price_ratio_percentiles: ComputedFromHeightRatioPercentiles<M>,
|
||||||
|
pub investor_price_ratio_std_dev: ComputedFromHeightRatioStdDevBands<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RealizedBasic {
|
impl RealizedFull {
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
let v0 = Version::ZERO;
|
let v0 = Version::ZERO;
|
||||||
let v1 = Version::ONE;
|
let v1 = Version::ONE;
|
||||||
|
|
||||||
let core = RealizedCore::forced_import(cfg)?;
|
let core = RealizedBase::forced_import(cfg)?;
|
||||||
|
|
||||||
// Stateful fields
|
|
||||||
let profit_value_created = cfg.import_computed("profit_value_created", v0)?;
|
let profit_value_created = cfg.import_computed("profit_value_created", v0)?;
|
||||||
let profit_value_destroyed = cfg.import_computed("profit_value_destroyed", v0)?;
|
let profit_value_destroyed = cfg.import_computed("profit_value_destroyed", v0)?;
|
||||||
let loss_value_created = cfg.import_computed("loss_value_created", v0)?;
|
let loss_value_created = cfg.import_computed("loss_value_created", v0)?;
|
||||||
@@ -101,9 +100,8 @@ impl RealizedBasic {
|
|||||||
&profit_value_destroyed,
|
&profit_value_destroyed,
|
||||||
);
|
);
|
||||||
|
|
||||||
let gross_pnl_sum = cfg.import_rolling("gross_pnl_sum", v1)?;
|
let gross_pnl_sum = cfg.import_rolling("gross_pnl_sum", Version::ONE)?;
|
||||||
|
|
||||||
// Investor price & price bands
|
|
||||||
let investor_price = cfg.import_price("investor_price", v0)?;
|
let investor_price = cfg.import_price("investor_price", v0)?;
|
||||||
let investor_price_ratio = cfg.import_ratio("investor_price", v0)?;
|
let investor_price_ratio = cfg.import_ratio("investor_price", v0)?;
|
||||||
let lower_price_band = cfg.import_price("lower_price_band", v0)?;
|
let lower_price_band = cfg.import_price("lower_price_band", v0)?;
|
||||||
@@ -117,19 +115,14 @@ impl RealizedBasic {
|
|||||||
let sell_side_risk_ratio_24h_ema =
|
let sell_side_risk_ratio_24h_ema =
|
||||||
cfg.import_percent_emas_1w_1m_bp32("sell_side_risk_ratio_24h", Version::new(2))?;
|
cfg.import_percent_emas_1w_1m_bp32("sell_side_risk_ratio_24h", Version::new(2))?;
|
||||||
|
|
||||||
// Peak regret
|
|
||||||
let peak_regret = cfg.import_cumulative("realized_peak_regret", Version::new(2))?;
|
let peak_regret = cfg.import_cumulative("realized_peak_regret", Version::new(2))?;
|
||||||
let peak_regret_rel_to_realized_cap =
|
let peak_regret_rel_to_realized_cap =
|
||||||
cfg.import_percent_bp32("realized_peak_regret_rel_to_realized_cap", Version::new(2))?;
|
cfg.import_percent_bp32("realized_peak_regret_rel_to_realized_cap", Version::new(2))?;
|
||||||
|
|
||||||
// Realized price ratio percentiles
|
let realized_price_name = cfg.name("realized_price");
|
||||||
let realized_price_ratio_percentiles =
|
let realized_price_version = cfg.version + v1;
|
||||||
ComputedFromHeightRatioPercentiles::forced_import(
|
let investor_price_name = cfg.name("investor_price");
|
||||||
cfg.db,
|
let investor_price_version = cfg.version;
|
||||||
&cfg.name("realized_price"),
|
|
||||||
cfg.version + v1,
|
|
||||||
cfg.indexes,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
core,
|
core,
|
||||||
@@ -145,10 +138,6 @@ impl RealizedBasic {
|
|||||||
.import_percent_bps32("net_pnl_change_1m_rel_to_realized_cap", Version::new(4))?,
|
.import_percent_bps32("net_pnl_change_1m_rel_to_realized_cap", Version::new(4))?,
|
||||||
net_pnl_change_1m_rel_to_market_cap: cfg
|
net_pnl_change_1m_rel_to_market_cap: cfg
|
||||||
.import_percent_bps32("net_pnl_change_1m_rel_to_market_cap", Version::new(4))?,
|
.import_percent_bps32("net_pnl_change_1m_rel_to_market_cap", Version::new(4))?,
|
||||||
sent_in_profit: cfg.import_value_cumulative("sent_in_profit", v0)?,
|
|
||||||
sent_in_profit_ema: cfg.import_emas_2w("sent_in_profit", v0)?,
|
|
||||||
sent_in_loss: cfg.import_value_cumulative("sent_in_loss", v0)?,
|
|
||||||
sent_in_loss_ema: cfg.import_emas_2w("sent_in_loss", v0)?,
|
|
||||||
investor_price,
|
investor_price,
|
||||||
investor_price_ratio,
|
investor_price_ratio,
|
||||||
lower_price_band,
|
lower_price_band,
|
||||||
@@ -159,7 +148,30 @@ impl RealizedBasic {
|
|||||||
sell_side_risk_ratio_24h_ema,
|
sell_side_risk_ratio_24h_ema,
|
||||||
peak_regret,
|
peak_regret,
|
||||||
peak_regret_rel_to_realized_cap,
|
peak_regret_rel_to_realized_cap,
|
||||||
realized_price_ratio_percentiles,
|
realized_cap_rel_to_own_market_cap: cfg
|
||||||
|
.import_percent_bp32("realized_cap_rel_to_own_market_cap", v1)?,
|
||||||
|
realized_profit_sum: cfg.import_rolling("realized_profit", v1)?,
|
||||||
|
realized_loss_sum: cfg.import_rolling("realized_loss", v1)?,
|
||||||
|
realized_profit_to_loss_ratio: cfg
|
||||||
|
.import_rolling("realized_profit_to_loss_ratio", v1)?,
|
||||||
|
realized_price_ratio_std_dev: ComputedFromHeightRatioStdDevBands::forced_import(
|
||||||
|
cfg.db,
|
||||||
|
&realized_price_name,
|
||||||
|
realized_price_version,
|
||||||
|
cfg.indexes,
|
||||||
|
)?,
|
||||||
|
investor_price_ratio_percentiles: ComputedFromHeightRatioPercentiles::forced_import(
|
||||||
|
cfg.db,
|
||||||
|
&investor_price_name,
|
||||||
|
investor_price_version,
|
||||||
|
cfg.indexes,
|
||||||
|
)?,
|
||||||
|
investor_price_ratio_std_dev: ComputedFromHeightRatioStdDevBands::forced_import(
|
||||||
|
cfg.db,
|
||||||
|
&investor_price_name,
|
||||||
|
investor_price_version,
|
||||||
|
cfg.indexes,
|
||||||
|
)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,8 +182,6 @@ impl RealizedBasic {
|
|||||||
.min(self.profit_value_destroyed.height.len())
|
.min(self.profit_value_destroyed.height.len())
|
||||||
.min(self.loss_value_created.height.len())
|
.min(self.loss_value_created.height.len())
|
||||||
.min(self.loss_value_destroyed.height.len())
|
.min(self.loss_value_destroyed.height.len())
|
||||||
.min(self.sent_in_profit.base.sats.height.len())
|
|
||||||
.min(self.sent_in_loss.base.sats.height.len())
|
|
||||||
.min(self.investor_price.cents.height.len())
|
.min(self.investor_price.cents.height.len())
|
||||||
.min(self.cap_raw.len())
|
.min(self.cap_raw.len())
|
||||||
.min(self.investor_cap_raw.len())
|
.min(self.investor_cap_raw.len())
|
||||||
@@ -192,16 +202,6 @@ impl RealizedBasic {
|
|||||||
self.loss_value_destroyed
|
self.loss_value_destroyed
|
||||||
.height
|
.height
|
||||||
.truncate_push(height, state.loss_value_destroyed())?;
|
.truncate_push(height, state.loss_value_destroyed())?;
|
||||||
self.sent_in_profit
|
|
||||||
.base
|
|
||||||
.sats
|
|
||||||
.height
|
|
||||||
.truncate_push(height, state.sent_in_profit())?;
|
|
||||||
self.sent_in_loss
|
|
||||||
.base
|
|
||||||
.sats
|
|
||||||
.height
|
|
||||||
.truncate_push(height, state.sent_in_loss())?;
|
|
||||||
self.investor_price
|
self.investor_price
|
||||||
.cents
|
.cents
|
||||||
.height
|
.height
|
||||||
@@ -222,8 +222,6 @@ impl RealizedBasic {
|
|||||||
vecs.push(&mut self.profit_value_destroyed.height);
|
vecs.push(&mut self.profit_value_destroyed.height);
|
||||||
vecs.push(&mut self.loss_value_created.height);
|
vecs.push(&mut self.loss_value_created.height);
|
||||||
vecs.push(&mut self.loss_value_destroyed.height);
|
vecs.push(&mut self.loss_value_destroyed.height);
|
||||||
vecs.push(&mut self.sent_in_profit.base.sats.height);
|
|
||||||
vecs.push(&mut self.sent_in_loss.base.sats.height);
|
|
||||||
vecs.push(&mut self.investor_price.cents.height);
|
vecs.push(&mut self.investor_price.cents.height);
|
||||||
vecs.push(&mut self.cap_raw as &mut dyn AnyStoredVec);
|
vecs.push(&mut self.cap_raw as &mut dyn AnyStoredVec);
|
||||||
vecs.push(&mut self.investor_cap_raw as &mut dyn AnyStoredVec);
|
vecs.push(&mut self.investor_cap_raw as &mut dyn AnyStoredVec);
|
||||||
@@ -231,92 +229,16 @@ impl RealizedBasic {
|
|||||||
vecs
|
vecs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Aggregate Core-level fields from source cohorts.
|
||||||
|
/// investor_price, cap_raw, investor_cap_raw come from the stateful scan, not aggregated.
|
||||||
pub(crate) fn compute_from_stateful(
|
pub(crate) fn compute_from_stateful(
|
||||||
&mut self,
|
&mut self,
|
||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
others: &[&Self],
|
others: &[&RealizedBase],
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// Core aggregation
|
|
||||||
let core_refs: Vec<&RealizedCore> = others.iter().map(|o| &o.core).collect();
|
|
||||||
self.core
|
self.core
|
||||||
.compute_from_stateful(starting_indexes, &core_refs, exit)?;
|
.compute_from_stateful(starting_indexes, others, exit)?;
|
||||||
|
|
||||||
// Stateful field aggregation
|
|
||||||
sum_others!(self, starting_indexes, others, exit; profit_value_created.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; profit_value_destroyed.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; loss_value_created.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; loss_value_destroyed.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; sent_in_profit.base.sats.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; sent_in_loss.base.sats.height);
|
|
||||||
|
|
||||||
// Investor price aggregation from raw values
|
|
||||||
let investor_price_dep_version = others
|
|
||||||
.iter()
|
|
||||||
.map(|o| o.investor_price.cents.height.version())
|
|
||||||
.fold(vecdb::Version::ZERO, |acc, v| acc + v);
|
|
||||||
self.investor_price
|
|
||||||
.cents
|
|
||||||
.height
|
|
||||||
.validate_computed_version_or_reset(investor_price_dep_version)?;
|
|
||||||
|
|
||||||
let start = self
|
|
||||||
.cap_raw
|
|
||||||
.len()
|
|
||||||
.min(self.investor_cap_raw.len())
|
|
||||||
.min(self.investor_price.cents.height.len());
|
|
||||||
let end = others.iter().map(|o| o.cap_raw.len()).min().unwrap_or(0);
|
|
||||||
|
|
||||||
let cap_ranges: Vec<Vec<CentsSats>> = others
|
|
||||||
.iter()
|
|
||||||
.map(|o| o.cap_raw.collect_range_at(start, end))
|
|
||||||
.collect();
|
|
||||||
let investor_cap_ranges: Vec<Vec<CentsSquaredSats>> = others
|
|
||||||
.iter()
|
|
||||||
.map(|o| o.investor_cap_raw.collect_range_at(start, end))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
for i in start..end {
|
|
||||||
let height = Height::from(i);
|
|
||||||
let local_i = i - start;
|
|
||||||
|
|
||||||
let mut sum_cap = CentsSats::ZERO;
|
|
||||||
let mut sum_investor_cap = CentsSquaredSats::ZERO;
|
|
||||||
|
|
||||||
for idx in 0..others.len() {
|
|
||||||
sum_cap += cap_ranges[idx][local_i];
|
|
||||||
sum_investor_cap += investor_cap_ranges[idx][local_i];
|
|
||||||
}
|
|
||||||
|
|
||||||
self.cap_raw.truncate_push(height, sum_cap)?;
|
|
||||||
self.investor_cap_raw
|
|
||||||
.truncate_push(height, sum_investor_cap)?;
|
|
||||||
|
|
||||||
let investor_price = if sum_cap.inner() == 0 {
|
|
||||||
Cents::ZERO
|
|
||||||
} else {
|
|
||||||
Cents::new((sum_investor_cap / sum_cap.inner()) as u64)
|
|
||||||
};
|
|
||||||
self.investor_price
|
|
||||||
.cents
|
|
||||||
.height
|
|
||||||
.truncate_push(height, investor_price)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let _lock = exit.lock();
|
|
||||||
self.investor_price.cents.height.write()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Peak regret aggregation
|
|
||||||
self.peak_regret.height.compute_sum_of_others(
|
|
||||||
starting_indexes.height,
|
|
||||||
&others
|
|
||||||
.iter()
|
|
||||||
.map(|v| &v.peak_regret.height)
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -329,7 +251,6 @@ impl RealizedBasic {
|
|||||||
self.core.compute_rest_part1(starting_indexes, exit)?;
|
self.core.compute_rest_part1(starting_indexes, exit)?;
|
||||||
self.peak_regret
|
self.peak_regret
|
||||||
.compute_rest(starting_indexes.height, exit)?;
|
.compute_rest(starting_indexes.height, exit)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,7 +263,6 @@ impl RealizedBasic {
|
|||||||
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
|
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// Core computation
|
|
||||||
self.core.compute_rest_part2(
|
self.core.compute_rest_part2(
|
||||||
blocks,
|
blocks,
|
||||||
prices,
|
prices,
|
||||||
@@ -351,7 +271,7 @@ impl RealizedBasic {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Gross PnL rolling sums
|
// Gross PnL rolling sum
|
||||||
let window_starts = blocks.count.window_starts();
|
let window_starts = blocks.count.window_starts();
|
||||||
self.gross_pnl_sum.compute_rolling_sum(
|
self.gross_pnl_sum.compute_rolling_sum(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
@@ -360,22 +280,6 @@ impl RealizedBasic {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Sent in profit/loss EMAs
|
|
||||||
self.sent_in_profit_ema.compute(
|
|
||||||
starting_indexes.height,
|
|
||||||
&blocks.count.height_2w_ago,
|
|
||||||
&self.sent_in_profit.base.sats.height,
|
|
||||||
&self.sent_in_profit.base.cents.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
self.sent_in_loss_ema.compute(
|
|
||||||
starting_indexes.height,
|
|
||||||
&blocks.count.height_2w_ago,
|
|
||||||
&self.sent_in_loss.base.sats.height,
|
|
||||||
&self.sent_in_loss.base.cents.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// Net PnL change 1m
|
// Net PnL change 1m
|
||||||
self.net_pnl_change_1m.height.compute_rolling_change(
|
self.net_pnl_change_1m.height.compute_rolling_change(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
@@ -383,15 +287,13 @@ impl RealizedBasic {
|
|||||||
&self.core.net_realized_pnl.cumulative.height,
|
&self.core.net_realized_pnl.cumulative.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.net_pnl_change_1m_rel_to_realized_cap
|
self.net_pnl_change_1m_rel_to_realized_cap
|
||||||
.compute_binary::<CentsSigned, Cents, RatioCentsSignedCentsBps32>(
|
.compute_binary::<CentsSigned, Cents, RatioCentsSignedCentsBps32>(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.net_pnl_change_1m.height,
|
&self.net_pnl_change_1m.height,
|
||||||
&self.core.realized_cap_cents.height,
|
&self.core.minimal.realized_cap_cents.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.net_pnl_change_1m_rel_to_market_cap
|
self.net_pnl_change_1m_rel_to_market_cap
|
||||||
.compute_binary::<CentsSigned, Dollars, RatioCentsSignedDollarsBps32>(
|
.compute_binary::<CentsSigned, Dollars, RatioCentsSignedDollarsBps32>(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
@@ -400,6 +302,15 @@ impl RealizedBasic {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// Peak regret
|
||||||
|
self.peak_regret_rel_to_realized_cap
|
||||||
|
.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
||||||
|
starting_indexes.height,
|
||||||
|
&self.peak_regret.height,
|
||||||
|
&self.core.minimal.realized_cap_cents.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
|
||||||
// Investor price ratio and price bands
|
// Investor price ratio and price bands
|
||||||
self.investor_price_ratio.compute_ratio(
|
self.investor_price_ratio.compute_ratio(
|
||||||
starting_indexes,
|
starting_indexes,
|
||||||
@@ -408,9 +319,10 @@ impl RealizedBasic {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// Use explicit field paths for split borrows
|
||||||
self.lower_price_band.cents.height.compute_transform2(
|
self.lower_price_band.cents.height.compute_transform2(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.core.realized_price.cents.height,
|
&self.core.minimal.realized_price.cents.height,
|
||||||
&self.investor_price.cents.height,
|
&self.investor_price.cents.height,
|
||||||
|(i, rp, ip, ..)| {
|
|(i, rp, ip, ..)| {
|
||||||
let rp = rp.as_u128();
|
let rp = rp.as_u128();
|
||||||
@@ -427,7 +339,7 @@ impl RealizedBasic {
|
|||||||
self.upper_price_band.cents.height.compute_transform2(
|
self.upper_price_band.cents.height.compute_transform2(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.investor_price.cents.height,
|
&self.investor_price.cents.height,
|
||||||
&self.core.realized_price.cents.height,
|
&self.core.minimal.realized_price.cents.height,
|
||||||
|(i, ip, rp, ..)| {
|
|(i, ip, rp, ..)| {
|
||||||
let ip = ip.as_u128();
|
let ip = ip.as_u128();
|
||||||
let rp = rp.as_u128();
|
let rp = rp.as_u128();
|
||||||
@@ -450,7 +362,7 @@ impl RealizedBasic {
|
|||||||
ssrr.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
ssrr.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&rv.height,
|
&rv.height,
|
||||||
&self.core.realized_cap_cents.height,
|
&self.core.minimal.realized_cap_cents.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
@@ -463,22 +375,70 @@ impl RealizedBasic {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Peak regret relative to realized cap
|
// Extended: realized profit/loss rolling sums
|
||||||
self.peak_regret_rel_to_realized_cap
|
let window_starts = blocks.count.window_starts();
|
||||||
.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
self.realized_profit_sum.compute_rolling_sum(
|
||||||
|
starting_indexes.height,
|
||||||
|
&window_starts,
|
||||||
|
&self.core.minimal.realized_profit.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.realized_loss_sum.compute_rolling_sum(
|
||||||
|
starting_indexes.height,
|
||||||
|
&window_starts,
|
||||||
|
&self.core.minimal.realized_loss.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Realized cap relative to own market cap
|
||||||
|
self.realized_cap_rel_to_own_market_cap
|
||||||
|
.compute_binary::<Dollars, Dollars, RatioDollarsBp32>(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.peak_regret.height,
|
&self.core.minimal.realized_cap.height,
|
||||||
&self.core.realized_cap_cents.height,
|
height_to_market_cap,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Realized price ratio percentiles
|
// Realized profit to loss ratios
|
||||||
self.realized_price_ratio_percentiles.compute(
|
for ((ratio, profit), loss) in self
|
||||||
|
.realized_profit_to_loss_ratio
|
||||||
|
.as_mut_array()
|
||||||
|
.into_iter()
|
||||||
|
.zip(self.realized_profit_sum.as_array())
|
||||||
|
.zip(self.realized_loss_sum.as_array())
|
||||||
|
{
|
||||||
|
ratio.compute_binary::<Cents, Cents, RatioCents64>(
|
||||||
|
starting_indexes.height,
|
||||||
|
&profit.height,
|
||||||
|
&loss.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Realized price stddev bands
|
||||||
|
self.realized_price_ratio_std_dev.compute(
|
||||||
blocks,
|
blocks,
|
||||||
starting_indexes,
|
starting_indexes,
|
||||||
exit,
|
exit,
|
||||||
&self.core.realized_price_ratio.ratio.height,
|
&self.core.minimal.realized_price_ratio.ratio.height,
|
||||||
&self.core.realized_price.cents.height,
|
&self.core.minimal.realized_price.cents.height,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Investor price: percentiles + stddev bands
|
||||||
|
let investor_price = &self.investor_price.cents.height;
|
||||||
|
self.investor_price_ratio_percentiles.compute(
|
||||||
|
blocks,
|
||||||
|
starting_indexes,
|
||||||
|
exit,
|
||||||
|
&self.investor_price_ratio.ratio.height,
|
||||||
|
investor_price,
|
||||||
|
)?;
|
||||||
|
self.investor_price_ratio_std_dev.compute(
|
||||||
|
blocks,
|
||||||
|
starting_indexes,
|
||||||
|
exit,
|
||||||
|
&self.investor_price_ratio.ratio.height,
|
||||||
|
investor_price,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
151
crates/brk_computer/src/distribution/metrics/realized/minimal.rs
Normal file
151
crates/brk_computer/src/distribution/metrics/realized/minimal.rs
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
use brk_error::Result;
|
||||||
|
use brk_traversable::Traversable;
|
||||||
|
use brk_types::{
|
||||||
|
BasisPoints32, Bitcoin, Cents, Dollars, Height, Indexes, Sats, StoredF32, Version,
|
||||||
|
};
|
||||||
|
use vecdb::{AnyStoredVec, AnyVec, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode, WritableVec};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
distribution::state::RealizedOps,
|
||||||
|
internal::{
|
||||||
|
CentsUnsignedToDollars, ComputedFromHeight, ComputedFromHeightCumulative,
|
||||||
|
ComputedFromHeightRatio, Identity, LazyFromHeight, Price,
|
||||||
|
},
|
||||||
|
prices,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::distribution::metrics::ImportConfig;
|
||||||
|
|
||||||
|
#[derive(Traversable)]
|
||||||
|
pub struct RealizedMinimal<M: StorageMode = Rw> {
|
||||||
|
pub realized_cap_cents: ComputedFromHeight<Cents, M>,
|
||||||
|
pub realized_profit: ComputedFromHeightCumulative<Cents, M>,
|
||||||
|
pub realized_loss: ComputedFromHeightCumulative<Cents, M>,
|
||||||
|
pub realized_cap: LazyFromHeight<Dollars, Cents>,
|
||||||
|
pub realized_price: Price<ComputedFromHeight<Cents, M>>,
|
||||||
|
pub realized_price_ratio: ComputedFromHeightRatio<M>,
|
||||||
|
pub mvrv: LazyFromHeight<StoredF32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RealizedMinimal {
|
||||||
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
|
let realized_cap_cents = cfg.import_computed("realized_cap_cents", Version::ZERO)?;
|
||||||
|
let realized_cap = LazyFromHeight::from_computed::<CentsUnsignedToDollars>(
|
||||||
|
&cfg.name("realized_cap"),
|
||||||
|
cfg.version,
|
||||||
|
realized_cap_cents.height.read_only_boxed_clone(),
|
||||||
|
&realized_cap_cents,
|
||||||
|
);
|
||||||
|
|
||||||
|
let realized_profit = cfg.import_cumulative("realized_profit", Version::ZERO)?;
|
||||||
|
let realized_loss = cfg.import_cumulative("realized_loss", Version::ZERO)?;
|
||||||
|
|
||||||
|
let realized_price = cfg.import_price("realized_price", Version::ONE)?;
|
||||||
|
let realized_price_ratio = cfg.import_ratio("realized_price", Version::ONE)?;
|
||||||
|
let mvrv = LazyFromHeight::from_lazy::<Identity<StoredF32>, BasisPoints32>(
|
||||||
|
&cfg.name("mvrv"),
|
||||||
|
cfg.version,
|
||||||
|
&realized_price_ratio.ratio,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
realized_cap_cents,
|
||||||
|
realized_profit,
|
||||||
|
realized_loss,
|
||||||
|
realized_cap,
|
||||||
|
realized_price,
|
||||||
|
realized_price_ratio,
|
||||||
|
mvrv,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn min_stateful_height_len(&self) -> usize {
|
||||||
|
self.realized_cap_cents
|
||||||
|
.height
|
||||||
|
.len()
|
||||||
|
.min(self.realized_profit.height.len())
|
||||||
|
.min(self.realized_loss.height.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn truncate_push(
|
||||||
|
&mut self,
|
||||||
|
height: Height,
|
||||||
|
state: &impl RealizedOps,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.realized_cap_cents
|
||||||
|
.height
|
||||||
|
.truncate_push(height, state.cap())?;
|
||||||
|
self.realized_profit
|
||||||
|
.height
|
||||||
|
.truncate_push(height, state.profit())?;
|
||||||
|
self.realized_loss
|
||||||
|
.height
|
||||||
|
.truncate_push(height, state.loss())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||||
|
vec![
|
||||||
|
&mut self.realized_cap_cents.height as &mut dyn AnyStoredVec,
|
||||||
|
&mut self.realized_profit.height,
|
||||||
|
&mut self.realized_loss.height,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compute_from_stateful(
|
||||||
|
&mut self,
|
||||||
|
starting_indexes: &Indexes,
|
||||||
|
others: &[&Self],
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()> {
|
||||||
|
sum_others!(self, starting_indexes, others, exit; realized_cap_cents.height);
|
||||||
|
sum_others!(self, starting_indexes, others, exit; realized_profit.height);
|
||||||
|
sum_others!(self, starting_indexes, others, exit; realized_loss.height);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compute_rest_part1(
|
||||||
|
&mut self,
|
||||||
|
starting_indexes: &Indexes,
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.realized_profit
|
||||||
|
.compute_rest(starting_indexes.height, exit)?;
|
||||||
|
self.realized_loss
|
||||||
|
.compute_rest(starting_indexes.height, exit)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compute_rest_part2(
|
||||||
|
&mut self,
|
||||||
|
prices: &prices::Vecs,
|
||||||
|
starting_indexes: &Indexes,
|
||||||
|
height_to_supply: &impl ReadableVec<Height, Bitcoin>,
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.realized_price.cents.height.compute_transform2(
|
||||||
|
starting_indexes.height,
|
||||||
|
&self.realized_cap_cents.height,
|
||||||
|
height_to_supply,
|
||||||
|
|(i, cap_cents, supply, ..)| {
|
||||||
|
let cap = cap_cents.as_u128();
|
||||||
|
let supply_sats = Sats::from(supply).as_u128();
|
||||||
|
if supply_sats == 0 {
|
||||||
|
(i, Cents::ZERO)
|
||||||
|
} else {
|
||||||
|
(i, Cents::from(cap * Sats::ONE_BTC_U128 / supply_sats))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
self.realized_price_ratio.compute_ratio(
|
||||||
|
starting_indexes,
|
||||||
|
&prices.price.cents.height,
|
||||||
|
&self.realized_price.cents.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +1,9 @@
|
|||||||
mod adjusted;
|
mod adjusted;
|
||||||
mod base;
|
mod base;
|
||||||
mod complete;
|
mod full;
|
||||||
mod core;
|
mod minimal;
|
||||||
mod extended;
|
|
||||||
|
|
||||||
mod with_extended;
|
|
||||||
|
|
||||||
pub use adjusted::*;
|
pub use adjusted::*;
|
||||||
pub use base::*;
|
pub use base::*;
|
||||||
pub use complete::*;
|
pub use full::*;
|
||||||
pub use core::*;
|
pub use minimal::*;
|
||||||
pub use extended::*;
|
|
||||||
|
|
||||||
pub use with_extended::*;
|
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
use brk_error::Result;
|
|
||||||
use brk_traversable::Traversable;
|
|
||||||
use brk_types::{Bitcoin, Dollars, Height, Indexes};
|
|
||||||
use derive_more::{Deref, DerefMut};
|
|
||||||
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
|
||||||
|
|
||||||
use crate::{blocks, prices};
|
|
||||||
|
|
||||||
use crate::distribution::metrics::ImportConfig;
|
|
||||||
|
|
||||||
use super::{RealizedFull, RealizedExtended};
|
|
||||||
|
|
||||||
/// Realized metrics with guaranteed extended (no Option).
|
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
|
||||||
pub struct RealizedWithExtended<M: StorageMode = Rw> {
|
|
||||||
#[deref]
|
|
||||||
#[deref_mut]
|
|
||||||
#[traversable(flatten)]
|
|
||||||
pub base: RealizedFull<M>,
|
|
||||||
#[traversable(flatten)]
|
|
||||||
pub extended: RealizedExtended<M>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RealizedWithExtended {
|
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
|
||||||
let base = RealizedFull::forced_import(cfg)?;
|
|
||||||
let extended = RealizedExtended::forced_import(cfg)?;
|
|
||||||
Ok(Self { base, extended })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute_rest_part2(
|
|
||||||
&mut self,
|
|
||||||
blocks: &blocks::Vecs,
|
|
||||||
prices: &prices::Vecs,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
height_to_supply: &impl ReadableVec<Height, Bitcoin>,
|
|
||||||
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.base.compute_rest_part2(
|
|
||||||
blocks,
|
|
||||||
prices,
|
|
||||||
starting_indexes,
|
|
||||||
height_to_supply,
|
|
||||||
height_to_market_cap,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
self.extended.compute_rest_part2(
|
|
||||||
&self.base,
|
|
||||||
blocks,
|
|
||||||
prices,
|
|
||||||
starting_indexes,
|
|
||||||
height_to_market_cap,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,71 +1,107 @@
|
|||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{BasisPoints16, BasisPointsSigned32, Dollars, Height, Sats, Version};
|
use brk_types::{BasisPoints16, BasisPointsSigned32, Dollars, Height, Sats, StoredF32, Version};
|
||||||
use derive_more::{Deref, DerefMut};
|
use vecdb::{Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode};
|
||||||
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
|
||||||
|
|
||||||
use crate::internal::{NegRatioDollarsBps32, PercentFromHeight, RatioDollarsBp16};
|
use crate::internal::{
|
||||||
|
Bps32ToFloat, LazyFromHeight, NegRatioDollarsBps32, PercentFromHeight, RatioDollarsBp16,
|
||||||
|
RatioDollarsBps32, RatioSatsBp16,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::distribution::metrics::{ImportConfig, RealizedFull, UnrealizedFull};
|
use crate::distribution::metrics::{ImportConfig, UnrealizedBase};
|
||||||
|
|
||||||
use super::RelativeComplete;
|
/// Relative metrics for the Complete tier (~6 fields).
|
||||||
|
|
||||||
/// Full relative metrics (Source/Extended tier).
|
|
||||||
///
|
///
|
||||||
/// Contains all Complete-tier fields (via Deref to RelativeComplete) plus:
|
/// Excludes source-only fields (invested_capital_in_profit/loss_rel_to_realized_cap).
|
||||||
/// - Source-only: neg_unrealized_loss_rel_to_market_cap, invested_capital_in_profit/loss_rel_to_realized_cap
|
#[derive(Traversable)]
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
|
||||||
pub struct RelativeBase<M: StorageMode = Rw> {
|
pub struct RelativeBase<M: StorageMode = Rw> {
|
||||||
#[deref]
|
pub supply_in_profit_rel_to_own_supply: PercentFromHeight<BasisPoints16, M>,
|
||||||
#[deref_mut]
|
pub supply_in_loss_rel_to_own_supply: PercentFromHeight<BasisPoints16, M>,
|
||||||
#[traversable(flatten)]
|
|
||||||
pub complete: RelativeComplete<M>,
|
|
||||||
|
|
||||||
// --- Source-only fields ---
|
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 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>,
|
|
||||||
pub invested_capital_in_loss_rel_to_realized_cap: PercentFromHeight<BasisPoints16, M>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RelativeBase {
|
impl RelativeBase {
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
let complete = RelativeComplete::forced_import(cfg)?;
|
let v1 = Version::ONE;
|
||||||
|
let v2 = Version::new(2);
|
||||||
|
|
||||||
|
let net_unrealized_pnl_rel_to_market_cap =
|
||||||
|
cfg.import_percent_bps32("net_unrealized_pnl_rel_to_market_cap", Version::new(3))?;
|
||||||
|
|
||||||
|
let nupl = LazyFromHeight::from_computed::<Bps32ToFloat>(
|
||||||
|
&cfg.name("nupl"),
|
||||||
|
cfg.version + Version::new(3),
|
||||||
|
net_unrealized_pnl_rel_to_market_cap
|
||||||
|
.bps
|
||||||
|
.height
|
||||||
|
.read_only_boxed_clone(),
|
||||||
|
&net_unrealized_pnl_rel_to_market_cap.bps,
|
||||||
|
);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
complete,
|
supply_in_profit_rel_to_own_supply: cfg
|
||||||
|
.import_percent_bp16("supply_in_profit_rel_to_own_supply", v1)?,
|
||||||
|
supply_in_loss_rel_to_own_supply: cfg
|
||||||
|
.import_percent_bp16("supply_in_loss_rel_to_own_supply", v1)?,
|
||||||
|
unrealized_profit_rel_to_market_cap: cfg
|
||||||
|
.import_percent_bp16("unrealized_profit_rel_to_market_cap", v2)?,
|
||||||
|
unrealized_loss_rel_to_market_cap: cfg
|
||||||
|
.import_percent_bp16("unrealized_loss_rel_to_market_cap", v2)?,
|
||||||
|
net_unrealized_pnl_rel_to_market_cap,
|
||||||
neg_unrealized_loss_rel_to_market_cap: cfg
|
neg_unrealized_loss_rel_to_market_cap: cfg
|
||||||
.import_percent_bps32("neg_unrealized_loss_rel_to_market_cap", Version::new(3))?,
|
.import_percent_bps32("neg_unrealized_loss_rel_to_market_cap", Version::new(3))?,
|
||||||
invested_capital_in_profit_rel_to_realized_cap: cfg.import_percent_bp16(
|
nupl,
|
||||||
"invested_capital_in_profit_rel_to_realized_cap",
|
|
||||||
Version::ZERO,
|
|
||||||
)?,
|
|
||||||
invested_capital_in_loss_rel_to_realized_cap: cfg.import_percent_bp16(
|
|
||||||
"invested_capital_in_loss_rel_to_realized_cap",
|
|
||||||
Version::ZERO,
|
|
||||||
)?,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn compute(
|
pub(crate) fn compute(
|
||||||
&mut self,
|
&mut self,
|
||||||
max_from: Height,
|
max_from: Height,
|
||||||
unrealized: &UnrealizedFull,
|
unrealized: &UnrealizedBase,
|
||||||
realized: &RealizedFull,
|
|
||||||
supply_total_sats: &impl ReadableVec<Height, Sats>,
|
supply_total_sats: &impl ReadableVec<Height, Sats>,
|
||||||
market_cap: &impl ReadableVec<Height, Dollars>,
|
market_cap: &impl ReadableVec<Height, Dollars>,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// Compute Complete-tier fields
|
self.supply_in_profit_rel_to_own_supply
|
||||||
self.complete.compute(
|
.compute_binary::<Sats, Sats, RatioSatsBp16>(
|
||||||
max_from,
|
max_from,
|
||||||
&unrealized.complete,
|
&unrealized.supply_in_profit.sats.height,
|
||||||
supply_total_sats,
|
supply_total_sats,
|
||||||
market_cap,
|
exit,
|
||||||
exit,
|
)?;
|
||||||
)?;
|
self.supply_in_loss_rel_to_own_supply
|
||||||
|
.compute_binary::<Sats, Sats, RatioSatsBp16>(
|
||||||
// Source-only
|
max_from,
|
||||||
|
&unrealized.supply_in_loss.sats.height,
|
||||||
|
supply_total_sats,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.unrealized_profit_rel_to_market_cap
|
||||||
|
.compute_binary::<Dollars, Dollars, RatioDollarsBp16>(
|
||||||
|
max_from,
|
||||||
|
&unrealized.unrealized_profit.usd.height,
|
||||||
|
market_cap,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.unrealized_loss_rel_to_market_cap
|
||||||
|
.compute_binary::<Dollars, Dollars, RatioDollarsBp16>(
|
||||||
|
max_from,
|
||||||
|
&unrealized.unrealized_loss.usd.height,
|
||||||
|
market_cap,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.net_unrealized_pnl_rel_to_market_cap
|
||||||
|
.compute_binary::<Dollars, Dollars, RatioDollarsBps32>(
|
||||||
|
max_from,
|
||||||
|
&unrealized.net_unrealized_pnl.usd.height,
|
||||||
|
market_cap,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
self.neg_unrealized_loss_rel_to_market_cap
|
self.neg_unrealized_loss_rel_to_market_cap
|
||||||
.compute_binary::<Dollars, Dollars, NegRatioDollarsBps32>(
|
.compute_binary::<Dollars, Dollars, NegRatioDollarsBps32>(
|
||||||
max_from,
|
max_from,
|
||||||
@@ -73,20 +109,6 @@ impl RelativeBase {
|
|||||||
market_cap,
|
market_cap,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
self.invested_capital_in_profit_rel_to_realized_cap
|
|
||||||
.compute_binary::<Dollars, Dollars, RatioDollarsBp16>(
|
|
||||||
max_from,
|
|
||||||
&unrealized.invested_capital_in_profit.usd.height,
|
|
||||||
&realized.realized_cap.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
self.invested_capital_in_loss_rel_to_realized_cap
|
|
||||||
.compute_binary::<Dollars, Dollars, RatioDollarsBp16>(
|
|
||||||
max_from,
|
|
||||||
&unrealized.invested_capital_in_loss.usd.height,
|
|
||||||
&realized.realized_cap.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
use brk_error::Result;
|
|
||||||
use brk_traversable::Traversable;
|
|
||||||
use brk_types::{BasisPoints16, BasisPointsSigned32, Dollars, Height, Sats, StoredF32, Version};
|
|
||||||
use vecdb::{Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode};
|
|
||||||
|
|
||||||
use crate::internal::{
|
|
||||||
Bps32ToFloat, LazyFromHeight, PercentFromHeight, RatioDollarsBp16, RatioDollarsBps32,
|
|
||||||
RatioSatsBp16,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::distribution::metrics::{ImportConfig, UnrealizedComplete};
|
|
||||||
|
|
||||||
/// Relative metrics for the Complete tier (~6 fields).
|
|
||||||
///
|
|
||||||
/// Excludes source-only fields (invested_capital_in_profit/loss_rel_to_realized_cap,
|
|
||||||
/// neg_unrealized_loss_rel_to_market_cap).
|
|
||||||
#[derive(Traversable)]
|
|
||||||
pub struct RelativeComplete<M: StorageMode = Rw> {
|
|
||||||
pub supply_in_profit_rel_to_own_supply: PercentFromHeight<BasisPoints16, M>,
|
|
||||||
pub supply_in_loss_rel_to_own_supply: PercentFromHeight<BasisPoints16, M>,
|
|
||||||
|
|
||||||
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 nupl: LazyFromHeight<StoredF32, BasisPointsSigned32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RelativeComplete {
|
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
|
||||||
let v1 = Version::ONE;
|
|
||||||
let v2 = Version::new(2);
|
|
||||||
|
|
||||||
let net_unrealized_pnl_rel_to_market_cap =
|
|
||||||
cfg.import_percent_bps32("net_unrealized_pnl_rel_to_market_cap", Version::new(3))?;
|
|
||||||
|
|
||||||
let nupl = LazyFromHeight::from_computed::<Bps32ToFloat>(
|
|
||||||
&cfg.name("nupl"),
|
|
||||||
cfg.version + Version::new(3),
|
|
||||||
net_unrealized_pnl_rel_to_market_cap
|
|
||||||
.bps
|
|
||||||
.height
|
|
||||||
.read_only_boxed_clone(),
|
|
||||||
&net_unrealized_pnl_rel_to_market_cap.bps,
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
supply_in_profit_rel_to_own_supply: cfg
|
|
||||||
.import_percent_bp16("supply_in_profit_rel_to_own_supply", v1)?,
|
|
||||||
supply_in_loss_rel_to_own_supply: cfg
|
|
||||||
.import_percent_bp16("supply_in_loss_rel_to_own_supply", v1)?,
|
|
||||||
unrealized_profit_rel_to_market_cap: cfg
|
|
||||||
.import_percent_bp16("unrealized_profit_rel_to_market_cap", v2)?,
|
|
||||||
unrealized_loss_rel_to_market_cap: cfg
|
|
||||||
.import_percent_bp16("unrealized_loss_rel_to_market_cap", v2)?,
|
|
||||||
net_unrealized_pnl_rel_to_market_cap,
|
|
||||||
nupl,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute(
|
|
||||||
&mut self,
|
|
||||||
max_from: Height,
|
|
||||||
unrealized: &UnrealizedComplete,
|
|
||||||
supply_total_sats: &impl ReadableVec<Height, Sats>,
|
|
||||||
market_cap: &impl ReadableVec<Height, Dollars>,
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.supply_in_profit_rel_to_own_supply
|
|
||||||
.compute_binary::<Sats, Sats, RatioSatsBp16>(
|
|
||||||
max_from,
|
|
||||||
&unrealized.supply_in_profit.sats.height,
|
|
||||||
supply_total_sats,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
self.supply_in_loss_rel_to_own_supply
|
|
||||||
.compute_binary::<Sats, Sats, RatioSatsBp16>(
|
|
||||||
max_from,
|
|
||||||
&unrealized.supply_in_loss.sats.height,
|
|
||||||
supply_total_sats,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
self.unrealized_profit_rel_to_market_cap
|
|
||||||
.compute_binary::<Dollars, Dollars, RatioDollarsBp16>(
|
|
||||||
max_from,
|
|
||||||
&unrealized.unrealized_profit.usd.height,
|
|
||||||
market_cap,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
self.unrealized_loss_rel_to_market_cap
|
|
||||||
.compute_binary::<Dollars, Dollars, RatioDollarsBp16>(
|
|
||||||
max_from,
|
|
||||||
&unrealized.unrealized_loss.usd.height,
|
|
||||||
market_cap,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
self.net_unrealized_pnl_rel_to_market_cap
|
|
||||||
.compute_binary::<Dollars, Dollars, RatioDollarsBps32>(
|
|
||||||
max_from,
|
|
||||||
&unrealized.net_unrealized_pnl.usd.height,
|
|
||||||
market_cap,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,9 +4,9 @@ use brk_types::{Dollars, Height, Sats};
|
|||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
||||||
|
|
||||||
use crate::distribution::metrics::{ImportConfig, RealizedFull, UnrealizedFull};
|
use crate::distribution::metrics::{ImportConfig, RealizedBase, UnrealizedFull};
|
||||||
|
|
||||||
use super::{RelativeBase, RelativeExtendedOwnPnl};
|
use super::{RelativeFull, RelativeExtendedOwnPnl};
|
||||||
|
|
||||||
/// Relative metrics for the "all" cohort (base + own_pnl, NO rel_to_all).
|
/// Relative metrics for the "all" cohort (base + own_pnl, NO rel_to_all).
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
@@ -14,7 +14,7 @@ pub struct RelativeForAll<M: StorageMode = Rw> {
|
|||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub base: RelativeBase<M>,
|
pub base: RelativeFull<M>,
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub extended_own_pnl: RelativeExtendedOwnPnl<M>,
|
pub extended_own_pnl: RelativeExtendedOwnPnl<M>,
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ pub struct RelativeForAll<M: StorageMode = Rw> {
|
|||||||
impl RelativeForAll {
|
impl RelativeForAll {
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
base: RelativeBase::forced_import(cfg)?,
|
base: RelativeFull::forced_import(cfg)?,
|
||||||
extended_own_pnl: RelativeExtendedOwnPnl::forced_import(cfg)?,
|
extended_own_pnl: RelativeExtendedOwnPnl::forced_import(cfg)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ impl RelativeForAll {
|
|||||||
&mut self,
|
&mut self,
|
||||||
max_from: Height,
|
max_from: Height,
|
||||||
unrealized: &UnrealizedFull,
|
unrealized: &UnrealizedFull,
|
||||||
realized: &RealizedFull,
|
realized: &RealizedBase,
|
||||||
supply_total_sats: &impl ReadableVec<Height, Sats>,
|
supply_total_sats: &impl ReadableVec<Height, Sats>,
|
||||||
market_cap: &impl ReadableVec<Height, Dollars>,
|
market_cap: &impl ReadableVec<Height, Dollars>,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
use brk_error::Result;
|
||||||
|
use brk_traversable::Traversable;
|
||||||
|
use brk_types::{BasisPoints16, Dollars, Height, Sats, Version};
|
||||||
|
use derive_more::{Deref, DerefMut};
|
||||||
|
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
||||||
|
|
||||||
|
use crate::internal::{PercentFromHeight, RatioDollarsBp16};
|
||||||
|
|
||||||
|
use crate::distribution::metrics::{ImportConfig, RealizedBase, UnrealizedFull};
|
||||||
|
|
||||||
|
use super::RelativeBase;
|
||||||
|
|
||||||
|
/// Full relative metrics (Source/Extended tier).
|
||||||
|
///
|
||||||
|
/// Contains all Complete-tier fields (via Deref to RelativeBase) plus:
|
||||||
|
/// - Source-only: invested_capital_in_profit/loss_rel_to_realized_cap
|
||||||
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
|
pub struct RelativeFull<M: StorageMode = Rw> {
|
||||||
|
#[deref]
|
||||||
|
#[deref_mut]
|
||||||
|
#[traversable(flatten)]
|
||||||
|
pub base: RelativeBase<M>,
|
||||||
|
|
||||||
|
// --- Source-only fields ---
|
||||||
|
pub invested_capital_in_profit_rel_to_realized_cap: PercentFromHeight<BasisPoints16, M>,
|
||||||
|
pub invested_capital_in_loss_rel_to_realized_cap: PercentFromHeight<BasisPoints16, M>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RelativeFull {
|
||||||
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
|
let base = RelativeBase::forced_import(cfg)?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
base,
|
||||||
|
invested_capital_in_profit_rel_to_realized_cap: cfg.import_percent_bp16(
|
||||||
|
"invested_capital_in_profit_rel_to_realized_cap",
|
||||||
|
Version::ZERO,
|
||||||
|
)?,
|
||||||
|
invested_capital_in_loss_rel_to_realized_cap: cfg.import_percent_bp16(
|
||||||
|
"invested_capital_in_loss_rel_to_realized_cap",
|
||||||
|
Version::ZERO,
|
||||||
|
)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compute(
|
||||||
|
&mut self,
|
||||||
|
max_from: Height,
|
||||||
|
unrealized: &UnrealizedFull,
|
||||||
|
realized: &RealizedBase,
|
||||||
|
supply_total_sats: &impl ReadableVec<Height, Sats>,
|
||||||
|
market_cap: &impl ReadableVec<Height, Dollars>,
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()> {
|
||||||
|
// Compute Complete-tier fields
|
||||||
|
self.base.compute(
|
||||||
|
max_from,
|
||||||
|
&unrealized.base,
|
||||||
|
supply_total_sats,
|
||||||
|
market_cap,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Source-only
|
||||||
|
self.invested_capital_in_profit_rel_to_realized_cap
|
||||||
|
.compute_binary::<Dollars, Dollars, RatioDollarsBp16>(
|
||||||
|
max_from,
|
||||||
|
&unrealized.invested_capital_in_profit.usd.height,
|
||||||
|
&realized.realized_cap.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.invested_capital_in_loss_rel_to_realized_cap
|
||||||
|
.compute_binary::<Dollars, Dollars, RatioDollarsBp16>(
|
||||||
|
max_from,
|
||||||
|
&unrealized.invested_capital_in_loss.usd.height,
|
||||||
|
&realized.realized_cap.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,21 +1,21 @@
|
|||||||
mod base;
|
mod base;
|
||||||
mod complete;
|
|
||||||
mod extended_own_market_cap;
|
mod extended_own_market_cap;
|
||||||
mod extended_own_pnl;
|
mod extended_own_pnl;
|
||||||
mod for_all;
|
mod for_all;
|
||||||
|
mod full;
|
||||||
|
|
||||||
mod to_all;
|
mod to_all;
|
||||||
mod with_extended;
|
mod with_extended;
|
||||||
mod with_rel_to_all;
|
mod with_rel_to_all;
|
||||||
mod with_rel_to_all_complete;
|
mod with_rel_to_all_base;
|
||||||
|
|
||||||
pub use base::*;
|
pub use base::*;
|
||||||
pub use complete::*;
|
|
||||||
pub use extended_own_market_cap::*;
|
pub use extended_own_market_cap::*;
|
||||||
pub use extended_own_pnl::*;
|
pub use extended_own_pnl::*;
|
||||||
pub use for_all::*;
|
pub use for_all::*;
|
||||||
|
pub use full::*;
|
||||||
|
|
||||||
pub use to_all::*;
|
pub use to_all::*;
|
||||||
pub use with_extended::*;
|
pub use with_extended::*;
|
||||||
pub use with_rel_to_all::*;
|
pub use with_rel_to_all::*;
|
||||||
pub use with_rel_to_all_complete::*;
|
pub use with_rel_to_all_base::*;
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ use brk_types::{Dollars, Height, Sats};
|
|||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
||||||
|
|
||||||
use crate::distribution::metrics::{ImportConfig, RealizedFull, UnrealizedFull};
|
use crate::distribution::metrics::{ImportConfig, RealizedBase, UnrealizedFull};
|
||||||
|
|
||||||
use super::{RelativeBase, RelativeExtendedOwnMarketCap, RelativeExtendedOwnPnl, RelativeToAll};
|
use super::{RelativeFull, RelativeExtendedOwnMarketCap, RelativeExtendedOwnPnl, RelativeToAll};
|
||||||
|
|
||||||
/// Full extended relative metrics (base + rel_to_all + own_market_cap + own_pnl).
|
/// Full extended relative metrics (base + rel_to_all + own_market_cap + own_pnl).
|
||||||
/// Used by: sth, lth, age_range cohorts.
|
/// Used by: sth, lth, age_range cohorts.
|
||||||
@@ -15,7 +15,7 @@ pub struct RelativeWithExtended<M: StorageMode = Rw> {
|
|||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub base: RelativeBase<M>,
|
pub base: RelativeFull<M>,
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub rel_to_all: RelativeToAll<M>,
|
pub rel_to_all: RelativeToAll<M>,
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
@@ -27,7 +27,7 @@ pub struct RelativeWithExtended<M: StorageMode = Rw> {
|
|||||||
impl RelativeWithExtended {
|
impl RelativeWithExtended {
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
base: RelativeBase::forced_import(cfg)?,
|
base: RelativeFull::forced_import(cfg)?,
|
||||||
rel_to_all: RelativeToAll::forced_import(cfg)?,
|
rel_to_all: RelativeToAll::forced_import(cfg)?,
|
||||||
extended_own_market_cap: RelativeExtendedOwnMarketCap::forced_import(cfg)?,
|
extended_own_market_cap: RelativeExtendedOwnMarketCap::forced_import(cfg)?,
|
||||||
extended_own_pnl: RelativeExtendedOwnPnl::forced_import(cfg)?,
|
extended_own_pnl: RelativeExtendedOwnPnl::forced_import(cfg)?,
|
||||||
@@ -39,7 +39,7 @@ impl RelativeWithExtended {
|
|||||||
&mut self,
|
&mut self,
|
||||||
max_from: Height,
|
max_from: Height,
|
||||||
unrealized: &UnrealizedFull,
|
unrealized: &UnrealizedFull,
|
||||||
realized: &RealizedFull,
|
realized: &RealizedBase,
|
||||||
supply_total_sats: &impl ReadableVec<Height, Sats>,
|
supply_total_sats: &impl ReadableVec<Height, Sats>,
|
||||||
market_cap: &impl ReadableVec<Height, Dollars>,
|
market_cap: &impl ReadableVec<Height, Dollars>,
|
||||||
all_supply_sats: &impl ReadableVec<Height, Sats>,
|
all_supply_sats: &impl ReadableVec<Height, Sats>,
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ use brk_types::{Dollars, Height, Sats};
|
|||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
||||||
|
|
||||||
use crate::distribution::metrics::{ImportConfig, RealizedFull, UnrealizedFull};
|
use crate::distribution::metrics::{ImportConfig, RealizedBase, UnrealizedFull};
|
||||||
|
|
||||||
use super::{RelativeBase, RelativeToAll};
|
use super::{RelativeFull, RelativeToAll};
|
||||||
|
|
||||||
/// Relative metrics with rel_to_all (no extended, no peak_regret).
|
/// Relative metrics with rel_to_all (no extended, no peak_regret).
|
||||||
/// Used by: epoch, year, type, amount, address cohorts.
|
/// Used by: epoch, year, type, amount, address cohorts.
|
||||||
@@ -15,7 +15,7 @@ pub struct RelativeWithRelToAll<M: StorageMode = Rw> {
|
|||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub base: RelativeBase<M>,
|
pub base: RelativeFull<M>,
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub rel_to_all: RelativeToAll<M>,
|
pub rel_to_all: RelativeToAll<M>,
|
||||||
}
|
}
|
||||||
@@ -23,7 +23,7 @@ pub struct RelativeWithRelToAll<M: StorageMode = Rw> {
|
|||||||
impl RelativeWithRelToAll {
|
impl RelativeWithRelToAll {
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
base: RelativeBase::forced_import(cfg)?,
|
base: RelativeFull::forced_import(cfg)?,
|
||||||
rel_to_all: RelativeToAll::forced_import(cfg)?,
|
rel_to_all: RelativeToAll::forced_import(cfg)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ impl RelativeWithRelToAll {
|
|||||||
&mut self,
|
&mut self,
|
||||||
max_from: Height,
|
max_from: Height,
|
||||||
unrealized: &UnrealizedFull,
|
unrealized: &UnrealizedFull,
|
||||||
realized: &RealizedFull,
|
realized: &RealizedBase,
|
||||||
supply_total_sats: &impl ReadableVec<Height, Sats>,
|
supply_total_sats: &impl ReadableVec<Height, Sats>,
|
||||||
market_cap: &impl ReadableVec<Height, Dollars>,
|
market_cap: &impl ReadableVec<Height, Dollars>,
|
||||||
all_supply_sats: &impl ReadableVec<Height, Sats>,
|
all_supply_sats: &impl ReadableVec<Height, Sats>,
|
||||||
|
|||||||
@@ -4,26 +4,26 @@ use brk_types::{Dollars, Height, Sats};
|
|||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
||||||
|
|
||||||
use crate::distribution::metrics::{ImportConfig, UnrealizedComplete};
|
use crate::distribution::metrics::{ImportConfig, UnrealizedBase};
|
||||||
|
|
||||||
use super::{RelativeComplete, RelativeToAll};
|
use super::{RelativeBase, RelativeToAll};
|
||||||
|
|
||||||
/// Complete relative metrics with rel_to_all.
|
/// Complete relative metrics with rel_to_all.
|
||||||
/// Used by CompleteCohortMetrics (epoch, class, min_age, max_age).
|
/// Used by CompleteCohortMetrics (epoch, class, min_age, max_age).
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
pub struct RelativeCompleteWithRelToAll<M: StorageMode = Rw> {
|
pub struct RelativeBaseWithRelToAll<M: StorageMode = Rw> {
|
||||||
#[deref]
|
#[deref]
|
||||||
#[deref_mut]
|
#[deref_mut]
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub base: RelativeComplete<M>,
|
pub base: RelativeBase<M>,
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub rel_to_all: RelativeToAll<M>,
|
pub rel_to_all: RelativeToAll<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RelativeCompleteWithRelToAll {
|
impl RelativeBaseWithRelToAll {
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
base: RelativeComplete::forced_import(cfg)?,
|
base: RelativeBase::forced_import(cfg)?,
|
||||||
rel_to_all: RelativeToAll::forced_import(cfg)?,
|
rel_to_all: RelativeToAll::forced_import(cfg)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ impl RelativeCompleteWithRelToAll {
|
|||||||
pub(crate) fn compute(
|
pub(crate) fn compute(
|
||||||
&mut self,
|
&mut self,
|
||||||
max_from: Height,
|
max_from: Height,
|
||||||
unrealized: &UnrealizedComplete,
|
unrealized: &UnrealizedBase,
|
||||||
supply_total_sats: &impl ReadableVec<Height, Sats>,
|
supply_total_sats: &impl ReadableVec<Height, Sats>,
|
||||||
market_cap: &impl ReadableVec<Height, Dollars>,
|
market_cap: &impl ReadableVec<Height, Dollars>,
|
||||||
all_supply_sats: &impl ReadableVec<Height, Sats>,
|
all_supply_sats: &impl ReadableVec<Height, Sats>,
|
||||||
@@ -1,93 +1,78 @@
|
|||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{Cents, CentsSats, CentsSigned, CentsSquaredSats, Height, Indexes, Version};
|
use brk_types::{Cents, CentsSigned, Height, Indexes, Version};
|
||||||
use derive_more::{Deref, DerefMut};
|
use vecdb::{AnyStoredVec, AnyVec, Exit, ReadableCloneableVec, Rw, StorageMode, WritableVec};
|
||||||
use vecdb::{AnyStoredVec, AnyVec, BytesVec, Exit, ReadableVec, Rw, StorageMode, WritableVec};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
distribution::state::UnrealizedState,
|
distribution::state::UnrealizedState,
|
||||||
internal::{CentsSubtractToCentsSigned, FiatFromHeight},
|
internal::{
|
||||||
prices,
|
CentsSubtractToCentsSigned, FiatFromHeight, LazyFromHeight, NegCentsUnsignedToDollars,
|
||||||
|
ValueFromHeight,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use brk_types::Dollars;
|
||||||
|
|
||||||
use crate::distribution::metrics::ImportConfig;
|
use crate::distribution::metrics::ImportConfig;
|
||||||
|
|
||||||
use super::UnrealizedComplete;
|
/// Unrealized metrics for the Complete tier (~6 fields).
|
||||||
|
|
||||||
/// Full unrealized metrics (Source/Extended tier).
|
|
||||||
///
|
///
|
||||||
/// Contains all Complete-tier fields (via Deref to UnrealizedComplete) plus:
|
/// Excludes source-only fields (invested_capital, raw BytesVecs)
|
||||||
/// - Source-only: invested_capital, raw BytesVecs, unrealized_gross_pnl
|
/// and extended-only fields (pain_index, greed_index, net_sentiment).
|
||||||
/// - Extended-only: pain_index, greed_index, net_sentiment
|
#[derive(Traversable)]
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
pub struct UnrealizedBase<M: StorageMode = Rw> {
|
||||||
pub struct UnrealizedFull<M: StorageMode = Rw> {
|
pub supply_in_profit: ValueFromHeight<M>,
|
||||||
#[deref]
|
pub supply_in_loss: ValueFromHeight<M>,
|
||||||
#[deref_mut]
|
|
||||||
#[traversable(flatten)]
|
|
||||||
pub complete: UnrealizedComplete<M>,
|
|
||||||
|
|
||||||
// --- Source-only fields ---
|
pub unrealized_profit: FiatFromHeight<Cents, M>,
|
||||||
pub invested_capital_in_profit: FiatFromHeight<Cents, M>,
|
pub unrealized_loss: FiatFromHeight<Cents, M>,
|
||||||
pub invested_capital_in_loss: FiatFromHeight<Cents, M>,
|
|
||||||
|
|
||||||
pub invested_capital_in_profit_raw: M::Stored<BytesVec<Height, CentsSats>>,
|
pub neg_unrealized_loss: LazyFromHeight<Dollars, Cents>,
|
||||||
pub invested_capital_in_loss_raw: M::Stored<BytesVec<Height, CentsSats>>,
|
|
||||||
pub investor_cap_in_profit_raw: M::Stored<BytesVec<Height, CentsSquaredSats>>,
|
|
||||||
pub investor_cap_in_loss_raw: M::Stored<BytesVec<Height, CentsSquaredSats>>,
|
|
||||||
|
|
||||||
pub gross_pnl: FiatFromHeight<Cents, M>,
|
pub gross_pnl: FiatFromHeight<Cents, M>,
|
||||||
|
|
||||||
// --- Extended-only fields ---
|
pub net_unrealized_pnl: FiatFromHeight<CentsSigned, M>,
|
||||||
pub pain_index: FiatFromHeight<Cents, M>,
|
|
||||||
pub greed_index: FiatFromHeight<Cents, M>,
|
|
||||||
pub net_sentiment: FiatFromHeight<CentsSigned, M>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnrealizedFull {
|
impl UnrealizedBase {
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
let v0 = Version::ZERO;
|
let v0 = Version::ZERO;
|
||||||
|
let supply_in_profit = cfg.import_value("supply_in_profit", v0)?;
|
||||||
|
let supply_in_loss = cfg.import_value("supply_in_loss", v0)?;
|
||||||
|
|
||||||
let complete = UnrealizedComplete::forced_import(cfg)?;
|
let unrealized_profit = cfg.import_fiat("unrealized_profit", v0)?;
|
||||||
|
let unrealized_loss = cfg.import_fiat("unrealized_loss", v0)?;
|
||||||
|
|
||||||
let invested_capital_in_profit = cfg.import_fiat("invested_capital_in_profit", v0)?;
|
let neg_unrealized_loss = LazyFromHeight::from_computed::<NegCentsUnsignedToDollars>(
|
||||||
let invested_capital_in_loss = cfg.import_fiat("invested_capital_in_loss", v0)?;
|
&cfg.name("neg_unrealized_loss"),
|
||||||
|
cfg.version,
|
||||||
let invested_capital_in_profit_raw =
|
unrealized_loss.cents.height.read_only_boxed_clone(),
|
||||||
cfg.import_bytes("invested_capital_in_profit_raw", v0)?;
|
&unrealized_loss.cents,
|
||||||
let invested_capital_in_loss_raw = cfg.import_bytes("invested_capital_in_loss_raw", v0)?;
|
);
|
||||||
let investor_cap_in_profit_raw = cfg.import_bytes("investor_cap_in_profit_raw", v0)?;
|
|
||||||
let investor_cap_in_loss_raw = cfg.import_bytes("investor_cap_in_loss_raw", v0)?;
|
|
||||||
|
|
||||||
let pain_index = cfg.import_fiat("pain_index", v0)?;
|
|
||||||
let greed_index = cfg.import_fiat("greed_index", v0)?;
|
|
||||||
let net_sentiment = cfg.import_fiat("net_sentiment", Version::ONE)?;
|
|
||||||
|
|
||||||
let gross_pnl = cfg.import_fiat("unrealized_gross_pnl", v0)?;
|
let gross_pnl = cfg.import_fiat("unrealized_gross_pnl", v0)?;
|
||||||
|
|
||||||
|
let net_unrealized_pnl = cfg.import_fiat("net_unrealized_pnl", v0)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
complete,
|
supply_in_profit,
|
||||||
invested_capital_in_profit,
|
supply_in_loss,
|
||||||
invested_capital_in_loss,
|
unrealized_profit,
|
||||||
invested_capital_in_profit_raw,
|
unrealized_loss,
|
||||||
invested_capital_in_loss_raw,
|
neg_unrealized_loss,
|
||||||
investor_cap_in_profit_raw,
|
|
||||||
investor_cap_in_loss_raw,
|
|
||||||
pain_index,
|
|
||||||
greed_index,
|
|
||||||
net_sentiment,
|
|
||||||
gross_pnl,
|
gross_pnl,
|
||||||
|
net_unrealized_pnl,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn min_stateful_height_len(&self) -> usize {
|
pub(crate) fn min_stateful_height_len(&self) -> usize {
|
||||||
self.complete
|
self.supply_in_profit
|
||||||
.min_stateful_height_len()
|
.sats
|
||||||
.min(self.invested_capital_in_profit.cents.height.len())
|
.height
|
||||||
.min(self.invested_capital_in_loss.cents.height.len())
|
.len()
|
||||||
.min(self.invested_capital_in_profit_raw.len())
|
.min(self.supply_in_loss.sats.height.len())
|
||||||
.min(self.invested_capital_in_loss_raw.len())
|
.min(self.unrealized_profit.cents.height.len())
|
||||||
.min(self.investor_cap_in_profit_raw.len())
|
.min(self.unrealized_loss.cents.height.len())
|
||||||
.min(self.investor_cap_in_loss_raw.len())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn truncate_push(
|
pub(crate) fn truncate_push(
|
||||||
@@ -95,46 +80,35 @@ impl UnrealizedFull {
|
|||||||
height: Height,
|
height: Height,
|
||||||
height_state: &UnrealizedState,
|
height_state: &UnrealizedState,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.complete.truncate_push(height, height_state)?;
|
self.supply_in_profit
|
||||||
|
.sats
|
||||||
self.invested_capital_in_profit
|
.height
|
||||||
|
.truncate_push(height, height_state.supply_in_profit)?;
|
||||||
|
self.supply_in_loss
|
||||||
|
.sats
|
||||||
|
.height
|
||||||
|
.truncate_push(height, height_state.supply_in_loss)?;
|
||||||
|
self.unrealized_profit
|
||||||
.cents
|
.cents
|
||||||
.height
|
.height
|
||||||
.truncate_push(height, height_state.invested_capital_in_profit)?;
|
.truncate_push(height, height_state.unrealized_profit)?;
|
||||||
self.invested_capital_in_loss
|
self.unrealized_loss
|
||||||
.cents
|
.cents
|
||||||
.height
|
.height
|
||||||
.truncate_push(height, height_state.invested_capital_in_loss)?;
|
.truncate_push(height, height_state.unrealized_loss)?;
|
||||||
|
|
||||||
self.invested_capital_in_profit_raw.truncate_push(
|
|
||||||
height,
|
|
||||||
CentsSats::new(height_state.invested_capital_in_profit_raw),
|
|
||||||
)?;
|
|
||||||
self.invested_capital_in_loss_raw.truncate_push(
|
|
||||||
height,
|
|
||||||
CentsSats::new(height_state.invested_capital_in_loss_raw),
|
|
||||||
)?;
|
|
||||||
self.investor_cap_in_profit_raw.truncate_push(
|
|
||||||
height,
|
|
||||||
CentsSquaredSats::new(height_state.investor_cap_in_profit_raw),
|
|
||||||
)?;
|
|
||||||
self.investor_cap_in_loss_raw.truncate_push(
|
|
||||||
height,
|
|
||||||
CentsSquaredSats::new(height_state.investor_cap_in_loss_raw),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||||
let mut vecs = self.complete.collect_vecs_mut();
|
vec![
|
||||||
vecs.push(&mut self.invested_capital_in_profit.cents.height as &mut dyn AnyStoredVec);
|
&mut self.supply_in_profit.base.sats.height as &mut dyn AnyStoredVec,
|
||||||
vecs.push(&mut self.invested_capital_in_loss.cents.height as &mut dyn AnyStoredVec);
|
&mut self.supply_in_profit.base.cents.height as &mut dyn AnyStoredVec,
|
||||||
vecs.push(&mut self.invested_capital_in_profit_raw as &mut dyn AnyStoredVec);
|
&mut self.supply_in_loss.base.sats.height as &mut dyn AnyStoredVec,
|
||||||
vecs.push(&mut self.invested_capital_in_loss_raw as &mut dyn AnyStoredVec);
|
&mut self.supply_in_loss.base.cents.height as &mut dyn AnyStoredVec,
|
||||||
vecs.push(&mut self.investor_cap_in_profit_raw as &mut dyn AnyStoredVec);
|
&mut self.unrealized_profit.cents.height,
|
||||||
vecs.push(&mut self.investor_cap_in_loss_raw as &mut dyn AnyStoredVec);
|
&mut self.unrealized_loss.cents.height,
|
||||||
vecs
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn compute_from_stateful(
|
pub(crate) fn compute_from_stateful(
|
||||||
@@ -143,149 +117,37 @@ impl UnrealizedFull {
|
|||||||
others: &[&Self],
|
others: &[&Self],
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// Delegate Complete-tier aggregation
|
sum_others!(self, starting_indexes, others, exit; supply_in_profit.sats.height);
|
||||||
let complete_refs: Vec<&UnrealizedComplete> =
|
sum_others!(self, starting_indexes, others, exit; supply_in_loss.sats.height);
|
||||||
others.iter().map(|o| &o.complete).collect();
|
sum_others!(self, starting_indexes, others, exit; unrealized_profit.cents.height);
|
||||||
self.complete
|
sum_others!(self, starting_indexes, others, exit; unrealized_loss.cents.height);
|
||||||
.compute_from_stateful(starting_indexes, &complete_refs, exit)?;
|
|
||||||
|
|
||||||
// Source-only: invested_capital
|
|
||||||
sum_others!(self, starting_indexes, others, exit; invested_capital_in_profit.cents.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; invested_capital_in_loss.cents.height);
|
|
||||||
|
|
||||||
// Source-only: raw BytesVec aggregation
|
|
||||||
let start = self
|
|
||||||
.invested_capital_in_profit_raw
|
|
||||||
.len()
|
|
||||||
.min(self.invested_capital_in_loss_raw.len())
|
|
||||||
.min(self.investor_cap_in_profit_raw.len())
|
|
||||||
.min(self.investor_cap_in_loss_raw.len());
|
|
||||||
let end = others
|
|
||||||
.iter()
|
|
||||||
.map(|o| o.invested_capital_in_profit_raw.len())
|
|
||||||
.min()
|
|
||||||
.unwrap_or(0);
|
|
||||||
|
|
||||||
// Pre-collect all cohort data to avoid per-element BytesVec reads in nested loop
|
|
||||||
let invested_profit_ranges: Vec<Vec<CentsSats>> = others
|
|
||||||
.iter()
|
|
||||||
.map(|o| {
|
|
||||||
o.invested_capital_in_profit_raw
|
|
||||||
.collect_range_at(start, end)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let invested_loss_ranges: Vec<Vec<CentsSats>> = others
|
|
||||||
.iter()
|
|
||||||
.map(|o| o.invested_capital_in_loss_raw.collect_range_at(start, end))
|
|
||||||
.collect();
|
|
||||||
let investor_profit_ranges: Vec<Vec<CentsSquaredSats>> = others
|
|
||||||
.iter()
|
|
||||||
.map(|o| o.investor_cap_in_profit_raw.collect_range_at(start, end))
|
|
||||||
.collect();
|
|
||||||
let investor_loss_ranges: Vec<Vec<CentsSquaredSats>> = others
|
|
||||||
.iter()
|
|
||||||
.map(|o| o.investor_cap_in_loss_raw.collect_range_at(start, end))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
for i in start..end {
|
|
||||||
let height = Height::from(i);
|
|
||||||
let local_i = i - start;
|
|
||||||
|
|
||||||
let mut sum_invested_profit = CentsSats::ZERO;
|
|
||||||
let mut sum_invested_loss = CentsSats::ZERO;
|
|
||||||
let mut sum_investor_profit = CentsSquaredSats::ZERO;
|
|
||||||
let mut sum_investor_loss = CentsSquaredSats::ZERO;
|
|
||||||
|
|
||||||
for idx in 0..others.len() {
|
|
||||||
sum_invested_profit += invested_profit_ranges[idx][local_i];
|
|
||||||
sum_invested_loss += invested_loss_ranges[idx][local_i];
|
|
||||||
sum_investor_profit += investor_profit_ranges[idx][local_i];
|
|
||||||
sum_investor_loss += investor_loss_ranges[idx][local_i];
|
|
||||||
}
|
|
||||||
|
|
||||||
self.invested_capital_in_profit_raw
|
|
||||||
.truncate_push(height, sum_invested_profit)?;
|
|
||||||
self.invested_capital_in_loss_raw
|
|
||||||
.truncate_push(height, sum_invested_loss)?;
|
|
||||||
self.investor_cap_in_profit_raw
|
|
||||||
.truncate_push(height, sum_investor_profit)?;
|
|
||||||
self.investor_cap_in_loss_raw
|
|
||||||
.truncate_push(height, sum_investor_loss)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute derived metrics from stored values + price.
|
/// Compute derived metrics from stored values.
|
||||||
pub(crate) fn compute_rest(
|
pub(crate) fn compute_rest(
|
||||||
&mut self,
|
&mut self,
|
||||||
prices: &prices::Vecs,
|
|
||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// Complete-tier: net_unrealized_pnl
|
|
||||||
self.complete.compute_rest(starting_indexes, exit)?;
|
|
||||||
|
|
||||||
// Extended-only: Pain index (investor_price_of_losers - spot)
|
|
||||||
self.pain_index.cents.height.compute_transform3(
|
|
||||||
starting_indexes.height,
|
|
||||||
&self.investor_cap_in_loss_raw,
|
|
||||||
&self.invested_capital_in_loss_raw,
|
|
||||||
&prices.price.cents.height,
|
|
||||||
|(h, investor_cap, invested_cap, spot, ..)| {
|
|
||||||
if invested_cap.inner() == 0 {
|
|
||||||
return (h, Cents::ZERO);
|
|
||||||
}
|
|
||||||
let investor_price_losers = investor_cap.inner() / invested_cap.inner();
|
|
||||||
let spot_u128 = spot.as_u128();
|
|
||||||
(h, Cents::new((investor_price_losers - spot_u128) as u64))
|
|
||||||
},
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// Extended-only: Greed index (spot - investor_price_of_winners)
|
|
||||||
self.greed_index.cents.height.compute_transform3(
|
|
||||||
starting_indexes.height,
|
|
||||||
&self.investor_cap_in_profit_raw,
|
|
||||||
&self.invested_capital_in_profit_raw,
|
|
||||||
&prices.price.cents.height,
|
|
||||||
|(h, investor_cap, invested_cap, spot, ..)| {
|
|
||||||
if invested_cap.inner() == 0 {
|
|
||||||
return (h, Cents::ZERO);
|
|
||||||
}
|
|
||||||
let investor_price_winners = investor_cap.inner() / invested_cap.inner();
|
|
||||||
let spot_u128 = spot.as_u128();
|
|
||||||
(h, Cents::new((spot_u128 - investor_price_winners) as u64))
|
|
||||||
},
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
// Source-only: unrealized gross pnl
|
|
||||||
self.gross_pnl.cents.height.compute_add(
|
self.gross_pnl.cents.height.compute_add(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.complete.unrealized_profit.cents.height,
|
&self.unrealized_profit.cents.height,
|
||||||
&self.complete.unrealized_loss.cents.height,
|
&self.unrealized_loss.cents.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(())
|
self.net_unrealized_pnl
|
||||||
}
|
|
||||||
|
|
||||||
/// Compute net_sentiment.height for separate cohorts (greed - pain).
|
|
||||||
pub(crate) fn compute_net_sentiment_height(
|
|
||||||
&mut self,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.net_sentiment
|
|
||||||
.cents
|
.cents
|
||||||
.height
|
.height
|
||||||
.compute_binary::<Cents, Cents, CentsSubtractToCentsSigned>(
|
.compute_binary::<Cents, Cents, CentsSubtractToCentsSigned>(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.greed_index.cents.height,
|
&self.unrealized_profit.cents.height,
|
||||||
&self.pain_index.cents.height,
|
&self.unrealized_loss.cents.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,141 +0,0 @@
|
|||||||
use brk_error::Result;
|
|
||||||
use brk_traversable::Traversable;
|
|
||||||
use brk_types::{Cents, CentsSigned, Height, Indexes, Version};
|
|
||||||
use vecdb::{AnyStoredVec, AnyVec, Exit, ReadableCloneableVec, Rw, StorageMode, WritableVec};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
distribution::state::UnrealizedState,
|
|
||||||
internal::{
|
|
||||||
CentsSubtractToCentsSigned, FiatFromHeight, LazyFromHeight, NegCentsUnsignedToDollars,
|
|
||||||
ValueFromHeight,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
use brk_types::Dollars;
|
|
||||||
|
|
||||||
use crate::distribution::metrics::ImportConfig;
|
|
||||||
|
|
||||||
/// Unrealized metrics for the Complete tier (~6 fields).
|
|
||||||
///
|
|
||||||
/// Excludes source-only fields (invested_capital, raw BytesVecs, unrealized_gross_pnl)
|
|
||||||
/// and extended-only fields (pain_index, greed_index, net_sentiment).
|
|
||||||
#[derive(Traversable)]
|
|
||||||
pub struct UnrealizedComplete<M: StorageMode = Rw> {
|
|
||||||
pub supply_in_profit: ValueFromHeight<M>,
|
|
||||||
pub supply_in_loss: ValueFromHeight<M>,
|
|
||||||
|
|
||||||
pub unrealized_profit: FiatFromHeight<Cents, M>,
|
|
||||||
pub unrealized_loss: FiatFromHeight<Cents, M>,
|
|
||||||
|
|
||||||
pub neg_unrealized_loss: LazyFromHeight<Dollars, Cents>,
|
|
||||||
|
|
||||||
pub net_unrealized_pnl: FiatFromHeight<CentsSigned, M>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UnrealizedComplete {
|
|
||||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
|
||||||
let v0 = Version::ZERO;
|
|
||||||
let supply_in_profit = cfg.import_value("supply_in_profit", v0)?;
|
|
||||||
let supply_in_loss = cfg.import_value("supply_in_loss", v0)?;
|
|
||||||
|
|
||||||
let unrealized_profit = cfg.import_fiat("unrealized_profit", v0)?;
|
|
||||||
let unrealized_loss = cfg.import_fiat("unrealized_loss", v0)?;
|
|
||||||
|
|
||||||
let neg_unrealized_loss = LazyFromHeight::from_computed::<NegCentsUnsignedToDollars>(
|
|
||||||
&cfg.name("neg_unrealized_loss"),
|
|
||||||
cfg.version,
|
|
||||||
unrealized_loss.cents.height.read_only_boxed_clone(),
|
|
||||||
&unrealized_loss.cents,
|
|
||||||
);
|
|
||||||
|
|
||||||
let net_unrealized_pnl = cfg.import_fiat("net_unrealized_pnl", v0)?;
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
supply_in_profit,
|
|
||||||
supply_in_loss,
|
|
||||||
unrealized_profit,
|
|
||||||
unrealized_loss,
|
|
||||||
neg_unrealized_loss,
|
|
||||||
net_unrealized_pnl,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn min_stateful_height_len(&self) -> usize {
|
|
||||||
self.supply_in_profit
|
|
||||||
.sats
|
|
||||||
.height
|
|
||||||
.len()
|
|
||||||
.min(self.supply_in_loss.sats.height.len())
|
|
||||||
.min(self.unrealized_profit.cents.height.len())
|
|
||||||
.min(self.unrealized_loss.cents.height.len())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn truncate_push(
|
|
||||||
&mut self,
|
|
||||||
height: Height,
|
|
||||||
height_state: &UnrealizedState,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.supply_in_profit
|
|
||||||
.sats
|
|
||||||
.height
|
|
||||||
.truncate_push(height, height_state.supply_in_profit)?;
|
|
||||||
self.supply_in_loss
|
|
||||||
.sats
|
|
||||||
.height
|
|
||||||
.truncate_push(height, height_state.supply_in_loss)?;
|
|
||||||
self.unrealized_profit
|
|
||||||
.cents
|
|
||||||
.height
|
|
||||||
.truncate_push(height, height_state.unrealized_profit)?;
|
|
||||||
self.unrealized_loss
|
|
||||||
.cents
|
|
||||||
.height
|
|
||||||
.truncate_push(height, height_state.unrealized_loss)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
|
||||||
vec![
|
|
||||||
&mut self.supply_in_profit.base.sats.height as &mut dyn AnyStoredVec,
|
|
||||||
&mut self.supply_in_profit.base.cents.height as &mut dyn AnyStoredVec,
|
|
||||||
&mut self.supply_in_loss.base.sats.height as &mut dyn AnyStoredVec,
|
|
||||||
&mut self.supply_in_loss.base.cents.height as &mut dyn AnyStoredVec,
|
|
||||||
&mut self.unrealized_profit.cents.height,
|
|
||||||
&mut self.unrealized_loss.cents.height,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn compute_from_stateful(
|
|
||||||
&mut self,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
others: &[&Self],
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
sum_others!(self, starting_indexes, others, exit; supply_in_profit.sats.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; supply_in_loss.sats.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; unrealized_profit.cents.height);
|
|
||||||
sum_others!(self, starting_indexes, others, exit; unrealized_loss.cents.height);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compute derived metrics from stored values.
|
|
||||||
pub(crate) fn compute_rest(
|
|
||||||
&mut self,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
exit: &Exit,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.net_unrealized_pnl
|
|
||||||
.cents
|
|
||||||
.height
|
|
||||||
.compute_binary::<Cents, Cents, CentsSubtractToCentsSigned>(
|
|
||||||
starting_indexes.height,
|
|
||||||
&self.unrealized_profit.cents.height,
|
|
||||||
&self.unrealized_loss.cents.height,
|
|
||||||
exit,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
278
crates/brk_computer/src/distribution/metrics/unrealized/full.rs
Normal file
278
crates/brk_computer/src/distribution/metrics/unrealized/full.rs
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
use brk_error::Result;
|
||||||
|
use brk_traversable::Traversable;
|
||||||
|
use brk_types::{Cents, CentsSats, CentsSigned, CentsSquaredSats, Height, Indexes, Version};
|
||||||
|
use derive_more::{Deref, DerefMut};
|
||||||
|
use vecdb::{AnyStoredVec, AnyVec, BytesVec, Exit, ReadableVec, Rw, StorageMode, WritableVec};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
distribution::state::UnrealizedState,
|
||||||
|
internal::{CentsSubtractToCentsSigned, FiatFromHeight},
|
||||||
|
prices,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::distribution::metrics::ImportConfig;
|
||||||
|
|
||||||
|
use super::UnrealizedBase;
|
||||||
|
|
||||||
|
/// Full unrealized metrics (Source/Extended tier).
|
||||||
|
///
|
||||||
|
/// Contains all Complete-tier fields (via Deref to UnrealizedBase) plus:
|
||||||
|
/// - Source-only: invested_capital, raw BytesVecs
|
||||||
|
/// - Extended-only: pain_index, greed_index, net_sentiment
|
||||||
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
|
pub struct UnrealizedFull<M: StorageMode = Rw> {
|
||||||
|
#[deref]
|
||||||
|
#[deref_mut]
|
||||||
|
#[traversable(flatten)]
|
||||||
|
pub base: UnrealizedBase<M>,
|
||||||
|
|
||||||
|
// --- Source-only fields ---
|
||||||
|
pub invested_capital_in_profit: FiatFromHeight<Cents, M>,
|
||||||
|
pub invested_capital_in_loss: FiatFromHeight<Cents, M>,
|
||||||
|
|
||||||
|
pub invested_capital_in_profit_raw: M::Stored<BytesVec<Height, CentsSats>>,
|
||||||
|
pub invested_capital_in_loss_raw: M::Stored<BytesVec<Height, CentsSats>>,
|
||||||
|
pub investor_cap_in_profit_raw: M::Stored<BytesVec<Height, CentsSquaredSats>>,
|
||||||
|
pub investor_cap_in_loss_raw: M::Stored<BytesVec<Height, CentsSquaredSats>>,
|
||||||
|
|
||||||
|
// --- Extended-only fields ---
|
||||||
|
pub pain_index: FiatFromHeight<Cents, M>,
|
||||||
|
pub greed_index: FiatFromHeight<Cents, M>,
|
||||||
|
pub net_sentiment: FiatFromHeight<CentsSigned, M>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UnrealizedFull {
|
||||||
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
|
let v0 = Version::ZERO;
|
||||||
|
|
||||||
|
let base = UnrealizedBase::forced_import(cfg)?;
|
||||||
|
|
||||||
|
let invested_capital_in_profit = cfg.import_fiat("invested_capital_in_profit", v0)?;
|
||||||
|
let invested_capital_in_loss = cfg.import_fiat("invested_capital_in_loss", v0)?;
|
||||||
|
|
||||||
|
let invested_capital_in_profit_raw =
|
||||||
|
cfg.import_bytes("invested_capital_in_profit_raw", v0)?;
|
||||||
|
let invested_capital_in_loss_raw = cfg.import_bytes("invested_capital_in_loss_raw", v0)?;
|
||||||
|
let investor_cap_in_profit_raw = cfg.import_bytes("investor_cap_in_profit_raw", v0)?;
|
||||||
|
let investor_cap_in_loss_raw = cfg.import_bytes("investor_cap_in_loss_raw", v0)?;
|
||||||
|
|
||||||
|
let pain_index = cfg.import_fiat("pain_index", v0)?;
|
||||||
|
let greed_index = cfg.import_fiat("greed_index", v0)?;
|
||||||
|
let net_sentiment = cfg.import_fiat("net_sentiment", Version::ONE)?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
base,
|
||||||
|
invested_capital_in_profit,
|
||||||
|
invested_capital_in_loss,
|
||||||
|
invested_capital_in_profit_raw,
|
||||||
|
invested_capital_in_loss_raw,
|
||||||
|
investor_cap_in_profit_raw,
|
||||||
|
investor_cap_in_loss_raw,
|
||||||
|
pain_index,
|
||||||
|
greed_index,
|
||||||
|
net_sentiment,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn min_stateful_height_len(&self) -> usize {
|
||||||
|
self.base
|
||||||
|
.min_stateful_height_len()
|
||||||
|
.min(self.invested_capital_in_profit.cents.height.len())
|
||||||
|
.min(self.invested_capital_in_loss.cents.height.len())
|
||||||
|
.min(self.invested_capital_in_profit_raw.len())
|
||||||
|
.min(self.invested_capital_in_loss_raw.len())
|
||||||
|
.min(self.investor_cap_in_profit_raw.len())
|
||||||
|
.min(self.investor_cap_in_loss_raw.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn truncate_push(
|
||||||
|
&mut self,
|
||||||
|
height: Height,
|
||||||
|
height_state: &UnrealizedState,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.base.truncate_push(height, height_state)?;
|
||||||
|
|
||||||
|
self.invested_capital_in_profit
|
||||||
|
.cents
|
||||||
|
.height
|
||||||
|
.truncate_push(height, height_state.invested_capital_in_profit)?;
|
||||||
|
self.invested_capital_in_loss
|
||||||
|
.cents
|
||||||
|
.height
|
||||||
|
.truncate_push(height, height_state.invested_capital_in_loss)?;
|
||||||
|
|
||||||
|
self.invested_capital_in_profit_raw.truncate_push(
|
||||||
|
height,
|
||||||
|
CentsSats::new(height_state.invested_capital_in_profit_raw),
|
||||||
|
)?;
|
||||||
|
self.invested_capital_in_loss_raw.truncate_push(
|
||||||
|
height,
|
||||||
|
CentsSats::new(height_state.invested_capital_in_loss_raw),
|
||||||
|
)?;
|
||||||
|
self.investor_cap_in_profit_raw.truncate_push(
|
||||||
|
height,
|
||||||
|
CentsSquaredSats::new(height_state.investor_cap_in_profit_raw),
|
||||||
|
)?;
|
||||||
|
self.investor_cap_in_loss_raw.truncate_push(
|
||||||
|
height,
|
||||||
|
CentsSquaredSats::new(height_state.investor_cap_in_loss_raw),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||||
|
let mut vecs = self.base.collect_vecs_mut();
|
||||||
|
vecs.push(&mut self.invested_capital_in_profit.cents.height as &mut dyn AnyStoredVec);
|
||||||
|
vecs.push(&mut self.invested_capital_in_loss.cents.height as &mut dyn AnyStoredVec);
|
||||||
|
vecs.push(&mut self.invested_capital_in_profit_raw as &mut dyn AnyStoredVec);
|
||||||
|
vecs.push(&mut self.invested_capital_in_loss_raw as &mut dyn AnyStoredVec);
|
||||||
|
vecs.push(&mut self.investor_cap_in_profit_raw as &mut dyn AnyStoredVec);
|
||||||
|
vecs.push(&mut self.investor_cap_in_loss_raw as &mut dyn AnyStoredVec);
|
||||||
|
vecs
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compute_from_stateful(
|
||||||
|
&mut self,
|
||||||
|
starting_indexes: &Indexes,
|
||||||
|
others: &[&Self],
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()> {
|
||||||
|
// Delegate Complete-tier aggregation
|
||||||
|
let base_refs: Vec<&UnrealizedBase> =
|
||||||
|
others.iter().map(|o| &o.base).collect();
|
||||||
|
self.base
|
||||||
|
.compute_from_stateful(starting_indexes, &base_refs, exit)?;
|
||||||
|
|
||||||
|
// Source-only: invested_capital
|
||||||
|
sum_others!(self, starting_indexes, others, exit; invested_capital_in_profit.cents.height);
|
||||||
|
sum_others!(self, starting_indexes, others, exit; invested_capital_in_loss.cents.height);
|
||||||
|
|
||||||
|
// Source-only: raw BytesVec aggregation
|
||||||
|
let start = self
|
||||||
|
.invested_capital_in_profit_raw
|
||||||
|
.len()
|
||||||
|
.min(self.invested_capital_in_loss_raw.len())
|
||||||
|
.min(self.investor_cap_in_profit_raw.len())
|
||||||
|
.min(self.investor_cap_in_loss_raw.len());
|
||||||
|
let end = others
|
||||||
|
.iter()
|
||||||
|
.map(|o| o.invested_capital_in_profit_raw.len())
|
||||||
|
.min()
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
// Pre-collect all cohort data to avoid per-element BytesVec reads in nested loop
|
||||||
|
let invested_profit_ranges: Vec<Vec<CentsSats>> = others
|
||||||
|
.iter()
|
||||||
|
.map(|o| {
|
||||||
|
o.invested_capital_in_profit_raw
|
||||||
|
.collect_range_at(start, end)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let invested_loss_ranges: Vec<Vec<CentsSats>> = others
|
||||||
|
.iter()
|
||||||
|
.map(|o| o.invested_capital_in_loss_raw.collect_range_at(start, end))
|
||||||
|
.collect();
|
||||||
|
let investor_profit_ranges: Vec<Vec<CentsSquaredSats>> = others
|
||||||
|
.iter()
|
||||||
|
.map(|o| o.investor_cap_in_profit_raw.collect_range_at(start, end))
|
||||||
|
.collect();
|
||||||
|
let investor_loss_ranges: Vec<Vec<CentsSquaredSats>> = others
|
||||||
|
.iter()
|
||||||
|
.map(|o| o.investor_cap_in_loss_raw.collect_range_at(start, end))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for i in start..end {
|
||||||
|
let height = Height::from(i);
|
||||||
|
let local_i = i - start;
|
||||||
|
|
||||||
|
let mut sum_invested_profit = CentsSats::ZERO;
|
||||||
|
let mut sum_invested_loss = CentsSats::ZERO;
|
||||||
|
let mut sum_investor_profit = CentsSquaredSats::ZERO;
|
||||||
|
let mut sum_investor_loss = CentsSquaredSats::ZERO;
|
||||||
|
|
||||||
|
for idx in 0..others.len() {
|
||||||
|
sum_invested_profit += invested_profit_ranges[idx][local_i];
|
||||||
|
sum_invested_loss += invested_loss_ranges[idx][local_i];
|
||||||
|
sum_investor_profit += investor_profit_ranges[idx][local_i];
|
||||||
|
sum_investor_loss += investor_loss_ranges[idx][local_i];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.invested_capital_in_profit_raw
|
||||||
|
.truncate_push(height, sum_invested_profit)?;
|
||||||
|
self.invested_capital_in_loss_raw
|
||||||
|
.truncate_push(height, sum_invested_loss)?;
|
||||||
|
self.investor_cap_in_profit_raw
|
||||||
|
.truncate_push(height, sum_investor_profit)?;
|
||||||
|
self.investor_cap_in_loss_raw
|
||||||
|
.truncate_push(height, sum_investor_loss)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compute derived metrics from stored values + price.
|
||||||
|
pub(crate) fn compute_rest(
|
||||||
|
&mut self,
|
||||||
|
prices: &prices::Vecs,
|
||||||
|
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.pain_index.cents.height.compute_transform3(
|
||||||
|
starting_indexes.height,
|
||||||
|
&self.investor_cap_in_loss_raw,
|
||||||
|
&self.invested_capital_in_loss_raw,
|
||||||
|
&prices.price.cents.height,
|
||||||
|
|(h, investor_cap, invested_cap, spot, ..)| {
|
||||||
|
if invested_cap.inner() == 0 {
|
||||||
|
return (h, Cents::ZERO);
|
||||||
|
}
|
||||||
|
let investor_price_losers = investor_cap.inner() / invested_cap.inner();
|
||||||
|
let spot_u128 = spot.as_u128();
|
||||||
|
(h, Cents::new((investor_price_losers - spot_u128) as u64))
|
||||||
|
},
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Extended-only: Greed index (spot - investor_price_of_winners)
|
||||||
|
self.greed_index.cents.height.compute_transform3(
|
||||||
|
starting_indexes.height,
|
||||||
|
&self.investor_cap_in_profit_raw,
|
||||||
|
&self.invested_capital_in_profit_raw,
|
||||||
|
&prices.price.cents.height,
|
||||||
|
|(h, investor_cap, invested_cap, spot, ..)| {
|
||||||
|
if invested_cap.inner() == 0 {
|
||||||
|
return (h, Cents::ZERO);
|
||||||
|
}
|
||||||
|
let investor_price_winners = investor_cap.inner() / invested_cap.inner();
|
||||||
|
let spot_u128 = spot.as_u128();
|
||||||
|
(h, Cents::new((spot_u128 - investor_price_winners) as u64))
|
||||||
|
},
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compute net_sentiment.height for separate cohorts (greed - pain).
|
||||||
|
pub(crate) fn compute_net_sentiment_height(
|
||||||
|
&mut self,
|
||||||
|
starting_indexes: &Indexes,
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.net_sentiment
|
||||||
|
.cents
|
||||||
|
.height
|
||||||
|
.compute_binary::<Cents, Cents, CentsSubtractToCentsSigned>(
|
||||||
|
starting_indexes.height,
|
||||||
|
&self.greed_index.cents.height,
|
||||||
|
&self.pain_index.cents.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
mod base;
|
mod base;
|
||||||
mod complete;
|
mod full;
|
||||||
|
|
||||||
pub use base::*;
|
pub use base::*;
|
||||||
pub use complete::*;
|
pub use full::*;
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ pub trait RealizedOps: Default + Clone + Send + Sync + 'static {
|
|||||||
fn value_destroyed(&self) -> Cents {
|
fn value_destroyed(&self) -> Cents {
|
||||||
Cents::ZERO
|
Cents::ZERO
|
||||||
}
|
}
|
||||||
|
fn sent_in_profit(&self) -> Sats {
|
||||||
|
Sats::ZERO
|
||||||
|
}
|
||||||
|
fn sent_in_loss(&self) -> Sats {
|
||||||
|
Sats::ZERO
|
||||||
|
}
|
||||||
fn set_cap_raw(&mut self, cap_raw: CentsSats);
|
fn set_cap_raw(&mut self, cap_raw: CentsSats);
|
||||||
fn set_investor_cap_raw(&mut self, investor_cap_raw: CentsSquaredSats);
|
fn set_investor_cap_raw(&mut self, investor_cap_raw: CentsSquaredSats);
|
||||||
fn reset_single_iteration_values(&mut self);
|
fn reset_single_iteration_values(&mut self);
|
||||||
@@ -121,13 +127,15 @@ impl RealizedOps for MinimalRealizedState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Core realized state: cap, profit, loss + value_created/destroyed for SOPR.
|
/// Core realized state: cap, profit, loss + value_created/destroyed for SOPR + sent tracking.
|
||||||
/// Used by CoreCohortMetrics cohorts (epoch, class, max_age, min_age — ~59 separate cohorts).
|
/// Used by CoreCohortMetrics cohorts (epoch, class, max_age, min_age — ~59 separate cohorts).
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct CoreRealizedState {
|
pub struct CoreRealizedState {
|
||||||
minimal: MinimalRealizedState,
|
minimal: MinimalRealizedState,
|
||||||
value_created_raw: u128,
|
value_created_raw: u128,
|
||||||
value_destroyed_raw: u128,
|
value_destroyed_raw: u128,
|
||||||
|
sent_in_profit: Sats,
|
||||||
|
sent_in_loss: Sats,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RealizedOps for CoreRealizedState {
|
impl RealizedOps for CoreRealizedState {
|
||||||
@@ -162,6 +170,16 @@ impl RealizedOps for CoreRealizedState {
|
|||||||
Cents::new((self.value_destroyed_raw / Sats::ONE_BTC_U128) as u64)
|
Cents::new((self.value_destroyed_raw / Sats::ONE_BTC_U128) as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sent_in_profit(&self) -> Sats {
|
||||||
|
self.sent_in_profit
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sent_in_loss(&self) -> Sats {
|
||||||
|
self.sent_in_loss
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_cap_raw(&mut self, cap_raw: CentsSats) {
|
fn set_cap_raw(&mut self, cap_raw: CentsSats) {
|
||||||
self.minimal.set_cap_raw(cap_raw);
|
self.minimal.set_cap_raw(cap_raw);
|
||||||
@@ -175,6 +193,8 @@ impl RealizedOps for CoreRealizedState {
|
|||||||
self.minimal.reset_single_iteration_values();
|
self.minimal.reset_single_iteration_values();
|
||||||
self.value_created_raw = 0;
|
self.value_created_raw = 0;
|
||||||
self.value_destroyed_raw = 0;
|
self.value_destroyed_raw = 0;
|
||||||
|
self.sent_in_profit = Sats::ZERO;
|
||||||
|
self.sent_in_loss = Sats::ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -205,6 +225,14 @@ impl RealizedOps for CoreRealizedState {
|
|||||||
.send(sats, current_ps, prev_ps, ath_ps, prev_investor_cap);
|
.send(sats, current_ps, prev_ps, ath_ps, prev_investor_cap);
|
||||||
self.value_created_raw += current_ps.as_u128();
|
self.value_created_raw += current_ps.as_u128();
|
||||||
self.value_destroyed_raw += prev_ps.as_u128();
|
self.value_destroyed_raw += prev_ps.as_u128();
|
||||||
|
match current_ps.cmp(&prev_ps) {
|
||||||
|
Ordering::Greater | Ordering::Equal => {
|
||||||
|
self.sent_in_profit += sats;
|
||||||
|
}
|
||||||
|
Ordering::Less => {
|
||||||
|
self.sent_in_loss += sats;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,10 +260,6 @@ pub struct RealizedState {
|
|||||||
loss_value_destroyed_raw: u128,
|
loss_value_destroyed_raw: u128,
|
||||||
/// Raw realized peak regret: Σ((peak - sell_price) × sats)
|
/// Raw realized peak regret: Σ((peak - sell_price) × sats)
|
||||||
peak_regret_raw: u128,
|
peak_regret_raw: u128,
|
||||||
/// Sats sent in profit
|
|
||||||
sent_in_profit: Sats,
|
|
||||||
/// Sats sent in loss
|
|
||||||
sent_in_loss: Sats,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RealizedOps for RealizedState {
|
impl RealizedOps for RealizedState {
|
||||||
@@ -272,6 +296,16 @@ impl RealizedOps for RealizedState {
|
|||||||
Cents::new((raw / Sats::ONE_BTC_U128) as u64)
|
Cents::new((raw / Sats::ONE_BTC_U128) as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sent_in_profit(&self) -> Sats {
|
||||||
|
self.core.sent_in_profit()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sent_in_loss(&self) -> Sats {
|
||||||
|
self.core.sent_in_loss()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_cap_raw(&mut self, cap_raw: CentsSats) {
|
fn set_cap_raw(&mut self, cap_raw: CentsSats) {
|
||||||
self.core.set_cap_raw(cap_raw);
|
self.core.set_cap_raw(cap_raw);
|
||||||
@@ -290,8 +324,6 @@ impl RealizedOps for RealizedState {
|
|||||||
self.loss_value_created_raw = 0;
|
self.loss_value_created_raw = 0;
|
||||||
self.loss_value_destroyed_raw = 0;
|
self.loss_value_destroyed_raw = 0;
|
||||||
self.peak_regret_raw = 0;
|
self.peak_regret_raw = 0;
|
||||||
self.sent_in_profit = Sats::ZERO;
|
|
||||||
self.sent_in_loss = Sats::ZERO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -323,7 +355,7 @@ impl RealizedOps for RealizedState {
|
|||||||
ath_ps: CentsSats,
|
ath_ps: CentsSats,
|
||||||
prev_investor_cap: CentsSquaredSats,
|
prev_investor_cap: CentsSquaredSats,
|
||||||
) {
|
) {
|
||||||
// Delegate cap/profit/loss + value_created/destroyed to core
|
// Delegate cap/profit/loss + value_created/destroyed + sent tracking to core
|
||||||
self.core
|
self.core
|
||||||
.send(sats, current_ps, prev_ps, ath_ps, prev_investor_cap);
|
.send(sats, current_ps, prev_ps, ath_ps, prev_investor_cap);
|
||||||
|
|
||||||
@@ -331,20 +363,13 @@ impl RealizedOps for RealizedState {
|
|||||||
let current = current_ps.as_u128();
|
let current = current_ps.as_u128();
|
||||||
let prev = prev_ps.as_u128();
|
let prev = prev_ps.as_u128();
|
||||||
match current_ps.cmp(&prev_ps) {
|
match current_ps.cmp(&prev_ps) {
|
||||||
Ordering::Greater => {
|
Ordering::Greater | Ordering::Equal => {
|
||||||
self.profit_value_created_raw += current;
|
self.profit_value_created_raw += current;
|
||||||
self.profit_value_destroyed_raw += prev;
|
self.profit_value_destroyed_raw += prev;
|
||||||
self.sent_in_profit += sats;
|
|
||||||
}
|
}
|
||||||
Ordering::Less => {
|
Ordering::Less => {
|
||||||
self.loss_value_created_raw += current;
|
self.loss_value_created_raw += current;
|
||||||
self.loss_value_destroyed_raw += prev;
|
self.loss_value_destroyed_raw += prev;
|
||||||
self.sent_in_loss += sats;
|
|
||||||
}
|
|
||||||
Ordering::Equal => {
|
|
||||||
self.profit_value_created_raw += current;
|
|
||||||
self.profit_value_destroyed_raw += prev;
|
|
||||||
self.sent_in_profit += sats;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,16 +446,4 @@ impl RealizedState {
|
|||||||
}
|
}
|
||||||
Cents::new((self.peak_regret_raw / Sats::ONE_BTC_U128) as u64)
|
Cents::new((self.peak_regret_raw / Sats::ONE_BTC_U128) as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get sats sent in profit.
|
|
||||||
#[inline]
|
|
||||||
pub(crate) fn sent_in_profit(&self) -> Sats {
|
|
||||||
self.sent_in_profit
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get sats sent in loss.
|
|
||||||
#[inline]
|
|
||||||
pub(crate) fn sent_in_loss(&self) -> Sats {
|
|
||||||
self.sent_in_loss
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
use brk_error::Result;
|
|
||||||
use brk_traversable::Traversable;
|
|
||||||
use brk_types::{Cents, Height, Indexes, Version};
|
|
||||||
use derive_more::{Deref, DerefMut};
|
|
||||||
use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode};
|
|
||||||
|
|
||||||
use crate::{blocks, indexes, prices};
|
|
||||||
|
|
||||||
use super::{ComputedFromHeightRatioExtended, ComputedFromHeightRatioStdDevBands};
|
|
||||||
|
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
|
||||||
pub struct ComputedFromHeightRatioFull<M: StorageMode = Rw> {
|
|
||||||
#[deref]
|
|
||||||
#[deref_mut]
|
|
||||||
#[traversable(flatten)]
|
|
||||||
pub base: ComputedFromHeightRatioExtended<M>,
|
|
||||||
#[traversable(flatten)]
|
|
||||||
pub std_dev: ComputedFromHeightRatioStdDevBands<M>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ComputedFromHeightRatioFull {
|
|
||||||
pub(crate) fn forced_import(
|
|
||||||
db: &Database,
|
|
||||||
name: &str,
|
|
||||||
version: Version,
|
|
||||||
indexes: &indexes::Vecs,
|
|
||||||
) -> Result<Self> {
|
|
||||||
Ok(Self {
|
|
||||||
base: ComputedFromHeightRatioExtended::forced_import(db, name, version, indexes)?,
|
|
||||||
std_dev: ComputedFromHeightRatioStdDevBands::forced_import(
|
|
||||||
db, name, version, indexes,
|
|
||||||
)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compute ratio, percentiles, and all stddev bands from an externally-provided metric price (in cents).
|
|
||||||
pub(crate) fn compute_rest(
|
|
||||||
&mut self,
|
|
||||||
blocks: &blocks::Vecs,
|
|
||||||
prices: &prices::Vecs,
|
|
||||||
starting_indexes: &Indexes,
|
|
||||||
exit: &Exit,
|
|
||||||
metric_price: &impl ReadableVec<Height, Cents>,
|
|
||||||
) -> Result<()> {
|
|
||||||
self.base
|
|
||||||
.compute_rest(blocks, prices, starting_indexes, exit, metric_price)?;
|
|
||||||
self.std_dev
|
|
||||||
.compute(blocks, starting_indexes, exit, &self.base.base.ratio.height, metric_price)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
mod extended;
|
mod extended;
|
||||||
mod full;
|
|
||||||
mod percentiles;
|
mod percentiles;
|
||||||
mod price_extended;
|
mod price_extended;
|
||||||
mod std_dev_bands;
|
mod std_dev_bands;
|
||||||
|
|
||||||
pub use extended::*;
|
pub use extended::*;
|
||||||
pub use full::*;
|
|
||||||
pub use percentiles::*;
|
pub use percentiles::*;
|
||||||
pub use price_extended::*;
|
pub use price_extended::*;
|
||||||
pub use std_dev_bands::*;
|
pub use std_dev_bands::*;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2064,17 +2064,11 @@ class MetricPattern35(Generic[T]):
|
|||||||
|
|
||||||
# Reusable structural pattern classes
|
# Reusable structural pattern classes
|
||||||
|
|
||||||
class AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern:
|
class CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, acc: str):
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
"""Create pattern node with accumulated metric name."""
|
"""Create pattern node with accumulated metric name."""
|
||||||
self.adjusted_sopr: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, _m(acc, 'adjusted_sopr'))
|
|
||||||
self.adjusted_sopr_ema: _1m1wPattern = _1m1wPattern(client, _m(acc, 'adjusted_sopr_24h_ema'))
|
|
||||||
self.adjusted_value_created: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'adjusted_value_created'))
|
|
||||||
self.adjusted_value_created_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'adjusted_value_created'))
|
|
||||||
self.adjusted_value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'adjusted_value_destroyed'))
|
|
||||||
self.adjusted_value_destroyed_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'adjusted_value_destroyed'))
|
|
||||||
self.cap_raw: MetricPattern18[CentsSats] = MetricPattern18(client, _m(acc, 'cap_raw'))
|
self.cap_raw: MetricPattern18[CentsSats] = MetricPattern18(client, _m(acc, 'cap_raw'))
|
||||||
self.capitulation_flow: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'capitulation_flow'))
|
self.capitulation_flow: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'capitulation_flow'))
|
||||||
self.gross_pnl: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'realized_gross_pnl'))
|
self.gross_pnl: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'realized_gross_pnl'))
|
||||||
@@ -2131,102 +2125,6 @@ class AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedS
|
|||||||
self.value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'value_destroyed'))
|
self.value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'value_destroyed'))
|
||||||
self.value_destroyed_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'value_destroyed'))
|
self.value_destroyed_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'value_destroyed'))
|
||||||
|
|
||||||
class CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern:
|
|
||||||
"""Pattern struct for repeated tree structure."""
|
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, acc: str):
|
|
||||||
"""Create pattern node with accumulated metric name."""
|
|
||||||
self.cap_raw: MetricPattern18[CentsSats] = MetricPattern18(client, _m(acc, 'cap_raw'))
|
|
||||||
self.capitulation_flow: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'capitulation_flow'))
|
|
||||||
self.gross_pnl: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'realized_gross_pnl'))
|
|
||||||
self.gross_pnl_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'gross_pnl_sum'))
|
|
||||||
self.investor_cap_raw: MetricPattern18[CentsSquaredSats] = MetricPattern18(client, _m(acc, 'investor_cap_raw'))
|
|
||||||
self.investor_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'investor_price'))
|
|
||||||
self.investor_price_ratio: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'investor_price_ratio'))
|
|
||||||
self.loss_value_created: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'loss_value_created'))
|
|
||||||
self.loss_value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'loss_value_destroyed'))
|
|
||||||
self.lower_price_band: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'lower_price_band'))
|
|
||||||
self.mvrv: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'mvrv'))
|
|
||||||
self.neg_realized_loss: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'neg_realized_loss'))
|
|
||||||
self.net_pnl_change_1m: MetricPattern1[CentsSigned] = MetricPattern1(client, _m(acc, 'net_pnl_change_1m'))
|
|
||||||
self.net_pnl_change_1m_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'net_pnl_change_1m_rel_to_market_cap'))
|
|
||||||
self.net_pnl_change_1m_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'net_pnl_change_1m_rel_to_realized_cap'))
|
|
||||||
self.net_realized_pnl: CumulativeHeightPattern[CentsSigned] = CumulativeHeightPattern(client, _m(acc, 'net_realized_pnl'))
|
|
||||||
self.net_realized_pnl_ema_1w: MetricPattern1[CentsSigned] = MetricPattern1(client, _m(acc, 'net_realized_pnl_ema_1w'))
|
|
||||||
self.net_realized_pnl_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'net_realized_pnl_rel_to_realized_cap'))
|
|
||||||
self.peak_regret: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, _m(acc, 'realized_peak_regret'))
|
|
||||||
self.peak_regret_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'realized_peak_regret_rel_to_realized_cap'))
|
|
||||||
self.profit_flow: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'profit_flow'))
|
|
||||||
self.profit_value_created: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'profit_value_created'))
|
|
||||||
self.profit_value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'profit_value_destroyed'))
|
|
||||||
self.realized_cap: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_cap'))
|
|
||||||
self.realized_cap_cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_cap_cents'))
|
|
||||||
self.realized_cap_change_1m: MetricPattern1[CentsSigned] = MetricPattern1(client, _m(acc, 'realized_cap_change_1m'))
|
|
||||||
self.realized_loss: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, _m(acc, 'realized_loss'))
|
|
||||||
self.realized_loss_ema_1w: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_loss_ema_1w'))
|
|
||||||
self.realized_loss_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'realized_loss_rel_to_realized_cap'))
|
|
||||||
self.realized_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'realized_price'))
|
|
||||||
self.realized_price_ratio: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'realized_price_ratio'))
|
|
||||||
self.realized_profit: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, _m(acc, 'realized_profit'))
|
|
||||||
self.realized_profit_ema_1w: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_profit_ema_1w'))
|
|
||||||
self.realized_profit_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'realized_profit_rel_to_realized_cap'))
|
|
||||||
self.sell_side_risk_ratio: _1m1w1y24hPattern2 = _1m1w1y24hPattern2(client, _m(acc, 'sell_side_risk_ratio'))
|
|
||||||
self.sell_side_risk_ratio_24h_ema: _1m1wPattern2 = _1m1wPattern2(client, _m(acc, 'sell_side_risk_ratio_24h_ema'))
|
|
||||||
self.sent_in_loss: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_loss'))
|
|
||||||
self.sent_in_loss_ema: _2wPattern = _2wPattern(client, _m(acc, 'sent_in_loss_ema_2w'))
|
|
||||||
self.sent_in_profit: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_profit'))
|
|
||||||
self.sent_in_profit_ema: _2wPattern = _2wPattern(client, _m(acc, 'sent_in_profit_ema_2w'))
|
|
||||||
self.sopr: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, _m(acc, 'sopr'))
|
|
||||||
self.sopr_24h_ema: _1m1wPattern = _1m1wPattern(client, _m(acc, 'sopr_24h_ema'))
|
|
||||||
self.upper_price_band: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'upper_price_band'))
|
|
||||||
self.value_created: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'value_created'))
|
|
||||||
self.value_created_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'value_created'))
|
|
||||||
self.value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'value_destroyed'))
|
|
||||||
self.value_destroyed_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'value_destroyed'))
|
|
||||||
|
|
||||||
class CapitulationGrossLossMvrvNegNetProfitRealizedSentSoprValuePattern:
|
|
||||||
"""Pattern struct for repeated tree structure."""
|
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, acc: str):
|
|
||||||
"""Create pattern node with accumulated metric name."""
|
|
||||||
self.capitulation_flow: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'capitulation_flow'))
|
|
||||||
self.gross_pnl: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'realized_gross_pnl'))
|
|
||||||
self.gross_pnl_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'gross_pnl_sum'))
|
|
||||||
self.loss_value_created: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'loss_value_created'))
|
|
||||||
self.loss_value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'loss_value_destroyed'))
|
|
||||||
self.mvrv: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'mvrv'))
|
|
||||||
self.neg_realized_loss: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'neg_realized_loss'))
|
|
||||||
self.net_pnl_change_1m: MetricPattern1[CentsSigned] = MetricPattern1(client, _m(acc, 'net_pnl_change_1m'))
|
|
||||||
self.net_pnl_change_1m_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'net_pnl_change_1m_rel_to_market_cap'))
|
|
||||||
self.net_pnl_change_1m_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'net_pnl_change_1m_rel_to_realized_cap'))
|
|
||||||
self.net_realized_pnl: CumulativeHeightPattern[CentsSigned] = CumulativeHeightPattern(client, _m(acc, 'net_realized_pnl'))
|
|
||||||
self.net_realized_pnl_ema_1w: MetricPattern1[CentsSigned] = MetricPattern1(client, _m(acc, 'net_realized_pnl_ema_1w'))
|
|
||||||
self.net_realized_pnl_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'net_realized_pnl_rel_to_realized_cap'))
|
|
||||||
self.profit_flow: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'profit_flow'))
|
|
||||||
self.profit_value_created: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'profit_value_created'))
|
|
||||||
self.profit_value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'profit_value_destroyed'))
|
|
||||||
self.realized_cap: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_cap'))
|
|
||||||
self.realized_cap_cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_cap_cents'))
|
|
||||||
self.realized_cap_change_1m: MetricPattern1[CentsSigned] = MetricPattern1(client, _m(acc, 'realized_cap_change_1m'))
|
|
||||||
self.realized_loss: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, _m(acc, 'realized_loss'))
|
|
||||||
self.realized_loss_ema_1w: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_loss_ema_1w'))
|
|
||||||
self.realized_loss_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'realized_loss_rel_to_realized_cap'))
|
|
||||||
self.realized_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'realized_price'))
|
|
||||||
self.realized_price_ratio: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'realized_price_ratio'))
|
|
||||||
self.realized_profit: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, _m(acc, 'realized_profit'))
|
|
||||||
self.realized_profit_ema_1w: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_profit_ema_1w'))
|
|
||||||
self.realized_profit_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'realized_profit_rel_to_realized_cap'))
|
|
||||||
self.sent_in_loss: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_loss'))
|
|
||||||
self.sent_in_loss_ema: _2wPattern = _2wPattern(client, _m(acc, 'sent_in_loss_ema_2w'))
|
|
||||||
self.sent_in_profit: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_profit'))
|
|
||||||
self.sent_in_profit_ema: _2wPattern = _2wPattern(client, _m(acc, 'sent_in_profit_ema_2w'))
|
|
||||||
self.sopr: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, _m(acc, 'sopr'))
|
|
||||||
self.sopr_24h_ema: _1m1wPattern = _1m1wPattern(client, _m(acc, 'sopr_24h_ema'))
|
|
||||||
self.value_created: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'value_created'))
|
|
||||||
self.value_created_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'value_created'))
|
|
||||||
self.value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'value_destroyed'))
|
|
||||||
self.value_destroyed_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'value_destroyed'))
|
|
||||||
|
|
||||||
class _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern:
|
class _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
@@ -2261,6 +2159,40 @@ class _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern:
|
|||||||
self.sma: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sma_4y'))
|
self.sma: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sma_4y'))
|
||||||
self.zscore: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'zscore_4y'))
|
self.zscore: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'zscore_4y'))
|
||||||
|
|
||||||
|
class GrossMvrvNegNetRealizedSentSoprValuePattern:
|
||||||
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
|
"""Create pattern node with accumulated metric name."""
|
||||||
|
self.gross_pnl: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'realized_gross_pnl'))
|
||||||
|
self.mvrv: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'mvrv'))
|
||||||
|
self.neg_realized_loss: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'neg_realized_loss'))
|
||||||
|
self.net_realized_pnl: CumulativeHeightPattern[CentsSigned] = CumulativeHeightPattern(client, _m(acc, 'net_realized_pnl'))
|
||||||
|
self.net_realized_pnl_ema_1w: MetricPattern1[CentsSigned] = MetricPattern1(client, _m(acc, 'net_realized_pnl_ema_1w'))
|
||||||
|
self.net_realized_pnl_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'net_realized_pnl_rel_to_realized_cap'))
|
||||||
|
self.realized_cap: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_cap'))
|
||||||
|
self.realized_cap_cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_cap_cents'))
|
||||||
|
self.realized_cap_change_1m: MetricPattern1[CentsSigned] = MetricPattern1(client, _m(acc, 'realized_cap_change_1m'))
|
||||||
|
self.realized_loss: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, _m(acc, 'realized_loss'))
|
||||||
|
self.realized_loss_ema_1w: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_loss_ema_1w'))
|
||||||
|
self.realized_loss_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'realized_loss_rel_to_realized_cap'))
|
||||||
|
self.realized_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'realized_price'))
|
||||||
|
self.realized_price_ratio: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'realized_price_ratio'))
|
||||||
|
self.realized_price_ratio_percentiles: RatioPattern = RatioPattern(client, _m(acc, 'realized_price_ratio'))
|
||||||
|
self.realized_profit: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, _m(acc, 'realized_profit'))
|
||||||
|
self.realized_profit_ema_1w: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_profit_ema_1w'))
|
||||||
|
self.realized_profit_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'realized_profit_rel_to_realized_cap'))
|
||||||
|
self.sent_in_loss: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_loss'))
|
||||||
|
self.sent_in_loss_ema: _2wPattern = _2wPattern(client, _m(acc, 'sent_in_loss_ema_2w'))
|
||||||
|
self.sent_in_profit: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_profit'))
|
||||||
|
self.sent_in_profit_ema: _2wPattern = _2wPattern(client, _m(acc, 'sent_in_profit_ema_2w'))
|
||||||
|
self.sopr: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, _m(acc, 'sopr'))
|
||||||
|
self.sopr_24h_ema: _1m1wPattern = _1m1wPattern(client, _m(acc, 'sopr_24h_ema'))
|
||||||
|
self.value_created: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'value_created'))
|
||||||
|
self.value_created_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'value_created'))
|
||||||
|
self.value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'value_destroyed'))
|
||||||
|
self.value_destroyed_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'value_destroyed'))
|
||||||
|
|
||||||
class InvestedNegNetNuplSupplyUnrealizedPattern3:
|
class InvestedNegNetNuplSupplyUnrealizedPattern3:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
@@ -2287,31 +2219,6 @@ class InvestedNegNetNuplSupplyUnrealizedPattern3:
|
|||||||
self.unrealized_profit_rel_to_own_gross_pnl: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'unrealized_profit_rel_to_own_gross_pnl'))
|
self.unrealized_profit_rel_to_own_gross_pnl: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'unrealized_profit_rel_to_own_gross_pnl'))
|
||||||
self.unrealized_profit_rel_to_own_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'unrealized_profit_rel_to_own_market_cap'))
|
self.unrealized_profit_rel_to_own_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'unrealized_profit_rel_to_own_market_cap'))
|
||||||
|
|
||||||
class GrossMvrvNegNetRealizedSoprPattern:
|
|
||||||
"""Pattern struct for repeated tree structure."""
|
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, acc: str):
|
|
||||||
"""Create pattern node with accumulated metric name."""
|
|
||||||
self.gross_pnl: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'realized_gross_pnl'))
|
|
||||||
self.mvrv: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'mvrv'))
|
|
||||||
self.neg_realized_loss: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'neg_realized_loss'))
|
|
||||||
self.net_realized_pnl: CumulativeHeightPattern[CentsSigned] = CumulativeHeightPattern(client, _m(acc, 'net_realized_pnl'))
|
|
||||||
self.net_realized_pnl_ema_1w: MetricPattern1[CentsSigned] = MetricPattern1(client, _m(acc, 'net_realized_pnl_ema_1w'))
|
|
||||||
self.net_realized_pnl_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'net_realized_pnl_rel_to_realized_cap'))
|
|
||||||
self.realized_cap: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_cap'))
|
|
||||||
self.realized_cap_cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_cap_cents'))
|
|
||||||
self.realized_cap_change_1m: MetricPattern1[CentsSigned] = MetricPattern1(client, _m(acc, 'realized_cap_change_1m'))
|
|
||||||
self.realized_loss: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, _m(acc, 'realized_loss'))
|
|
||||||
self.realized_loss_ema_1w: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_loss_ema_1w'))
|
|
||||||
self.realized_loss_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'realized_loss_rel_to_realized_cap'))
|
|
||||||
self.realized_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'realized_price'))
|
|
||||||
self.realized_price_ratio: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'realized_price_ratio'))
|
|
||||||
self.realized_profit: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, _m(acc, 'realized_profit'))
|
|
||||||
self.realized_profit_ema_1w: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_profit_ema_1w'))
|
|
||||||
self.realized_profit_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'realized_profit_rel_to_realized_cap'))
|
|
||||||
self.sopr: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, _m(acc, 'sopr'))
|
|
||||||
self.sopr_24h_ema: _1m1wPattern = _1m1wPattern(client, _m(acc, 'sopr_24h_ema'))
|
|
||||||
|
|
||||||
class Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern:
|
class Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
@@ -2505,6 +2412,22 @@ class AverageGainsLossesRsiStochPattern:
|
|||||||
self.stoch_rsi_d: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'stoch_d_24h'))
|
self.stoch_rsi_d: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'stoch_d_24h'))
|
||||||
self.stoch_rsi_k: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'stoch_k_24h'))
|
self.stoch_rsi_k: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'stoch_k_24h'))
|
||||||
|
|
||||||
|
class NegNetNuplSupplyUnrealizedPattern:
|
||||||
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
|
"""Create pattern node with accumulated metric name."""
|
||||||
|
self.neg_unrealized_loss_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'neg_unrealized_loss_rel_to_market_cap'))
|
||||||
|
self.net_unrealized_pnl_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'net_unrealized_pnl_rel_to_market_cap'))
|
||||||
|
self.nupl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'nupl'))
|
||||||
|
self.supply_in_loss_rel_to_circulating_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'supply_in_loss_rel_to_circulating_supply'))
|
||||||
|
self.supply_in_loss_rel_to_own_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'supply_in_loss_rel_to_own_supply'))
|
||||||
|
self.supply_in_profit_rel_to_circulating_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'supply_in_profit_rel_to_circulating_supply'))
|
||||||
|
self.supply_in_profit_rel_to_own_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'supply_in_profit_rel_to_own_supply'))
|
||||||
|
self.supply_rel_to_circulating_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'supply_rel_to_circulating_supply'))
|
||||||
|
self.unrealized_loss_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'unrealized_loss_rel_to_market_cap'))
|
||||||
|
self.unrealized_profit_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'unrealized_profit_rel_to_market_cap'))
|
||||||
|
|
||||||
class AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern:
|
class AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
@@ -2550,21 +2473,6 @@ class AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern:
|
|||||||
self.pct90: _1m1w1y24hPattern[StoredU64] = _1m1w1y24hPattern(client, _m(acc, 'p90'))
|
self.pct90: _1m1w1y24hPattern[StoredU64] = _1m1w1y24hPattern(client, _m(acc, 'p90'))
|
||||||
self.sum: _1m1w1y24hPattern[StoredU64] = _1m1w1y24hPattern(client, _m(acc, 'sum'))
|
self.sum: _1m1w1y24hPattern[StoredU64] = _1m1w1y24hPattern(client, _m(acc, 'sum'))
|
||||||
|
|
||||||
class NetNuplSupplyUnrealizedPattern:
|
|
||||||
"""Pattern struct for repeated tree structure."""
|
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, acc: str):
|
|
||||||
"""Create pattern node with accumulated metric name."""
|
|
||||||
self.net_unrealized_pnl_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'net_unrealized_pnl_rel_to_market_cap'))
|
|
||||||
self.nupl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'nupl'))
|
|
||||||
self.supply_in_loss_rel_to_circulating_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'supply_in_loss_rel_to_circulating_supply'))
|
|
||||||
self.supply_in_loss_rel_to_own_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'supply_in_loss_rel_to_own_supply'))
|
|
||||||
self.supply_in_profit_rel_to_circulating_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'supply_in_profit_rel_to_circulating_supply'))
|
|
||||||
self.supply_in_profit_rel_to_own_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'supply_in_profit_rel_to_own_supply'))
|
|
||||||
self.supply_rel_to_circulating_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'supply_rel_to_circulating_supply'))
|
|
||||||
self.unrealized_loss_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'unrealized_loss_rel_to_market_cap'))
|
|
||||||
self.unrealized_profit_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'unrealized_profit_rel_to_market_cap'))
|
|
||||||
|
|
||||||
class AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(Generic[T]):
|
class AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(Generic[T]):
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
@@ -2603,10 +2511,10 @@ class ActivityAddrOutputsRealizedRelativeSupplyUnrealizedPattern:
|
|||||||
self.addr_count: MetricPattern1[StoredU64] = MetricPattern1(client, _m(acc, 'addr_count'))
|
self.addr_count: MetricPattern1[StoredU64] = MetricPattern1(client, _m(acc, 'addr_count'))
|
||||||
self.addr_count_change_1m: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'addr_count_change_1m'))
|
self.addr_count_change_1m: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'addr_count_change_1m'))
|
||||||
self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count'))
|
self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count'))
|
||||||
self.realized: GrossMvrvNegNetRealizedSoprPattern = GrossMvrvNegNetRealizedSoprPattern(client, acc)
|
self.realized: MvrvRealizedPattern = MvrvRealizedPattern(client, acc)
|
||||||
self.relative: NetNuplSupplyUnrealizedPattern = NetNuplSupplyUnrealizedPattern(client, acc)
|
self.relative: SupplyPattern = SupplyPattern(client, _m(acc, 'supply_in'))
|
||||||
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, _m(acc, 'supply'))
|
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, _m(acc, 'supply'))
|
||||||
self.unrealized: NegNetSupplyUnrealizedPattern = NegNetSupplyUnrealizedPattern(client, acc)
|
self.unrealized: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply_in'))
|
||||||
|
|
||||||
class AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern(Generic[T]):
|
class AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern(Generic[T]):
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
@@ -2643,23 +2551,36 @@ class ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern:
|
|||||||
self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, acc)
|
self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, acc)
|
||||||
self.cost_basis: MaxMinPattern = MaxMinPattern(client, _m(acc, 'cost_basis'))
|
self.cost_basis: MaxMinPattern = MaxMinPattern(client, _m(acc, 'cost_basis'))
|
||||||
self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count'))
|
self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count'))
|
||||||
self.realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, acc)
|
self.realized: GrossMvrvNegNetRealizedSentSoprValuePattern = GrossMvrvNegNetRealizedSentSoprValuePattern(client, acc)
|
||||||
self.relative: InvestedNegNetNuplSupplyUnrealizedPattern = InvestedNegNetNuplSupplyUnrealizedPattern(client, acc)
|
self.relative: InvestedNegNetNuplSupplyUnrealizedPattern = InvestedNegNetNuplSupplyUnrealizedPattern(client, acc)
|
||||||
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, _m(acc, 'supply'))
|
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, _m(acc, 'supply'))
|
||||||
self.unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern = GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(client, acc)
|
self.unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern = GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(client, acc)
|
||||||
|
|
||||||
class ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4:
|
class GrossNegNetSupplyUnrealizedPattern:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, acc: str):
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
"""Create pattern node with accumulated metric name."""
|
"""Create pattern node with accumulated metric name."""
|
||||||
self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, acc)
|
self.gross_pnl: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'unrealized_gross_pnl'))
|
||||||
self.cost_basis: MaxMinPattern = MaxMinPattern(client, _m(acc, 'cost_basis'))
|
self.neg_unrealized_loss: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss'))
|
||||||
self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count'))
|
self.net_unrealized_pnl: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'net_unrealized_pnl'))
|
||||||
self.realized: CapitulationGrossLossMvrvNegNetProfitRealizedSentSoprValuePattern = CapitulationGrossLossMvrvNegNetProfitRealizedSentSoprValuePattern(client, acc)
|
self.supply_in_loss: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'supply_in_loss'))
|
||||||
self.relative: NetNuplSupplyUnrealizedPattern = NetNuplSupplyUnrealizedPattern(client, acc)
|
self.supply_in_profit: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'supply_in_profit'))
|
||||||
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, _m(acc, 'supply'))
|
self.unrealized_loss: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'unrealized_loss'))
|
||||||
self.unrealized: NegNetSupplyUnrealizedPattern = NegNetSupplyUnrealizedPattern(client, acc)
|
self.unrealized_profit: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'unrealized_profit'))
|
||||||
|
|
||||||
|
class MvrvRealizedPattern:
|
||||||
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
|
"""Create pattern node with accumulated metric name."""
|
||||||
|
self.mvrv: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'mvrv'))
|
||||||
|
self.realized_cap: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_cap'))
|
||||||
|
self.realized_cap_cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_cap_cents'))
|
||||||
|
self.realized_loss: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, _m(acc, 'realized_loss'))
|
||||||
|
self.realized_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'realized_price'))
|
||||||
|
self.realized_price_ratio: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'realized_price_ratio'))
|
||||||
|
self.realized_profit: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, _m(acc, 'realized_profit'))
|
||||||
|
|
||||||
class _1m1w1y24hBaseCumulativePattern:
|
class _1m1w1y24hBaseCumulativePattern:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
@@ -2673,6 +2594,18 @@ class _1m1w1y24hBaseCumulativePattern:
|
|||||||
self.base: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, acc)
|
self.base: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, acc)
|
||||||
self.cumulative: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'cumulative'))
|
self.cumulative: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'cumulative'))
|
||||||
|
|
||||||
|
class ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2:
|
||||||
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
|
"""Create pattern node with accumulated metric name."""
|
||||||
|
self.activity: SentPattern = SentPattern(client, _m(acc, 'sent'))
|
||||||
|
self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count'))
|
||||||
|
self.realized: GrossMvrvNegNetRealizedSentSoprValuePattern = GrossMvrvNegNetRealizedSentSoprValuePattern(client, acc)
|
||||||
|
self.relative: NegNetNuplSupplyUnrealizedPattern = NegNetNuplSupplyUnrealizedPattern(client, acc)
|
||||||
|
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, _m(acc, 'supply'))
|
||||||
|
self.unrealized: GrossNegNetSupplyUnrealizedPattern = GrossNegNetSupplyUnrealizedPattern(client, acc)
|
||||||
|
|
||||||
class ActivityOutputsRealizedRelativeSupplyUnrealizedPattern:
|
class ActivityOutputsRealizedRelativeSupplyUnrealizedPattern:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
@@ -2680,10 +2613,10 @@ class ActivityOutputsRealizedRelativeSupplyUnrealizedPattern:
|
|||||||
"""Create pattern node with accumulated metric name."""
|
"""Create pattern node with accumulated metric name."""
|
||||||
self.activity: SentPattern = SentPattern(client, _m(acc, 'sent'))
|
self.activity: SentPattern = SentPattern(client, _m(acc, 'sent'))
|
||||||
self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count'))
|
self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count'))
|
||||||
self.realized: GrossMvrvNegNetRealizedSoprPattern = GrossMvrvNegNetRealizedSoprPattern(client, acc)
|
self.realized: MvrvRealizedPattern = MvrvRealizedPattern(client, acc)
|
||||||
self.relative: NetNuplSupplyUnrealizedPattern = NetNuplSupplyUnrealizedPattern(client, acc)
|
self.relative: SupplyPattern = SupplyPattern(client, _m(acc, 'supply_in'))
|
||||||
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, _m(acc, 'supply'))
|
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, _m(acc, 'supply'))
|
||||||
self.unrealized: NegNetSupplyUnrealizedPattern = NegNetSupplyUnrealizedPattern(client, acc)
|
self.unrealized: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply_in'))
|
||||||
|
|
||||||
class BalanceBothReactivatedReceivingSendingPattern:
|
class BalanceBothReactivatedReceivingSendingPattern:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
@@ -2697,18 +2630,6 @@ class BalanceBothReactivatedReceivingSendingPattern:
|
|||||||
self.receiving: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredU32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'receiving'))
|
self.receiving: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredU32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'receiving'))
|
||||||
self.sending: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredU32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'sending'))
|
self.sending: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredU32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'sending'))
|
||||||
|
|
||||||
class NegNetSupplyUnrealizedPattern:
|
|
||||||
"""Pattern struct for repeated tree structure."""
|
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, acc: str):
|
|
||||||
"""Create pattern node with accumulated metric name."""
|
|
||||||
self.neg_unrealized_loss: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss'))
|
|
||||||
self.net_unrealized_pnl: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'net_unrealized_pnl'))
|
|
||||||
self.supply_in_loss: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'supply_in_loss'))
|
|
||||||
self.supply_in_profit: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'supply_in_profit'))
|
|
||||||
self.unrealized_loss: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'unrealized_loss'))
|
|
||||||
self.unrealized_profit: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'unrealized_profit'))
|
|
||||||
|
|
||||||
class EmaHistogramLineSignalPattern:
|
class EmaHistogramLineSignalPattern:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
@@ -2720,28 +2641,6 @@ class EmaHistogramLineSignalPattern:
|
|||||||
self.line: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'line_24h'))
|
self.line: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'line_24h'))
|
||||||
self.signal: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'signal_24h'))
|
self.signal: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'signal_24h'))
|
||||||
|
|
||||||
class MvrvRealizedPattern:
|
|
||||||
"""Pattern struct for repeated tree structure."""
|
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, acc: str):
|
|
||||||
"""Create pattern node with accumulated metric name."""
|
|
||||||
self.mvrv: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'mvrv'))
|
|
||||||
self.realized_cap: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_cap'))
|
|
||||||
self.realized_cap_cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_cap_cents'))
|
|
||||||
self.realized_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'realized_price'))
|
|
||||||
self.realized_price_ratio: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'realized_price_ratio'))
|
|
||||||
|
|
||||||
class OutputsRealizedRelativeSupplyUnrealizedPattern:
|
|
||||||
"""Pattern struct for repeated tree structure."""
|
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, acc: str):
|
|
||||||
"""Create pattern node with accumulated metric name."""
|
|
||||||
self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count'))
|
|
||||||
self.realized: MvrvRealizedPattern = MvrvRealizedPattern(client, acc)
|
|
||||||
self.relative: SupplyPattern = SupplyPattern(client, _m(acc, 'supply_in'))
|
|
||||||
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, _m(acc, 'supply'))
|
|
||||||
self.unrealized: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply_in'))
|
|
||||||
|
|
||||||
class _1m1w1y24hPattern2:
|
class _1m1w1y24hPattern2:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
@@ -4307,11 +4206,21 @@ class MetricsTree_Distribution_AddressesData:
|
|||||||
self.funded: MetricPattern34[FundedAddressData] = MetricPattern34(client, 'fundedaddressdata')
|
self.funded: MetricPattern34[FundedAddressData] = MetricPattern34(client, 'fundedaddressdata')
|
||||||
self.empty: MetricPattern35[EmptyAddressData] = MetricPattern35(client, 'emptyaddressdata')
|
self.empty: MetricPattern35[EmptyAddressData] = MetricPattern35(client, 'emptyaddressdata')
|
||||||
|
|
||||||
|
class MetricsTree_Distribution_UtxoCohorts_All_Adjusted:
|
||||||
|
"""Metrics tree node."""
|
||||||
|
|
||||||
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
|
self.adjusted_value_created: MetricPattern1[Cents] = MetricPattern1(client, 'adjusted_value_created')
|
||||||
|
self.adjusted_value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, 'adjusted_value_destroyed')
|
||||||
|
self.adjusted_value_created_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, 'adjusted_value_created')
|
||||||
|
self.adjusted_value_destroyed_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, 'adjusted_value_destroyed')
|
||||||
|
self.adjusted_sopr: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, 'adjusted_sopr')
|
||||||
|
self.adjusted_sopr_ema: _1m1wPattern = _1m1wPattern(client, 'adjusted_sopr_24h_ema')
|
||||||
|
|
||||||
class MetricsTree_Distribution_UtxoCohorts_All_Relative:
|
class MetricsTree_Distribution_UtxoCohorts_All_Relative:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
self.neg_unrealized_loss_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'neg_unrealized_loss_rel_to_market_cap')
|
|
||||||
self.invested_capital_in_profit_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'invested_capital_in_profit_rel_to_realized_cap')
|
self.invested_capital_in_profit_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'invested_capital_in_profit_rel_to_realized_cap')
|
||||||
self.invested_capital_in_loss_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'invested_capital_in_loss_rel_to_realized_cap')
|
self.invested_capital_in_loss_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'invested_capital_in_loss_rel_to_realized_cap')
|
||||||
self.supply_in_profit_rel_to_own_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'supply_in_profit_rel_to_own_supply')
|
self.supply_in_profit_rel_to_own_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'supply_in_profit_rel_to_own_supply')
|
||||||
@@ -4319,6 +4228,7 @@ class MetricsTree_Distribution_UtxoCohorts_All_Relative:
|
|||||||
self.unrealized_profit_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'unrealized_profit_rel_to_market_cap')
|
self.unrealized_profit_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'unrealized_profit_rel_to_market_cap')
|
||||||
self.unrealized_loss_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'unrealized_loss_rel_to_market_cap')
|
self.unrealized_loss_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'unrealized_loss_rel_to_market_cap')
|
||||||
self.net_unrealized_pnl_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'net_unrealized_pnl_rel_to_market_cap')
|
self.net_unrealized_pnl_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'net_unrealized_pnl_rel_to_market_cap')
|
||||||
|
self.neg_unrealized_loss_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'neg_unrealized_loss_rel_to_market_cap')
|
||||||
self.nupl: MetricPattern1[StoredF32] = MetricPattern1(client, 'nupl')
|
self.nupl: MetricPattern1[StoredF32] = MetricPattern1(client, 'nupl')
|
||||||
self.unrealized_profit_rel_to_own_gross_pnl: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'unrealized_profit_rel_to_own_gross_pnl')
|
self.unrealized_profit_rel_to_own_gross_pnl: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'unrealized_profit_rel_to_own_gross_pnl')
|
||||||
self.unrealized_loss_rel_to_own_gross_pnl: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'unrealized_loss_rel_to_own_gross_pnl')
|
self.unrealized_loss_rel_to_own_gross_pnl: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'unrealized_loss_rel_to_own_gross_pnl')
|
||||||
@@ -4332,10 +4242,13 @@ class MetricsTree_Distribution_UtxoCohorts_All:
|
|||||||
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'supply')
|
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'supply')
|
||||||
self.outputs: UtxoPattern = UtxoPattern(client, 'utxo_count')
|
self.outputs: UtxoPattern = UtxoPattern(client, 'utxo_count')
|
||||||
self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, '')
|
self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, '')
|
||||||
self.realized: AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, '')
|
self.realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, '')
|
||||||
self.cost_basis: InvestedMaxMinPercentilesPattern = InvestedMaxMinPercentilesPattern(client, '')
|
self.cost_basis: InvestedMaxMinPercentilesPattern = InvestedMaxMinPercentilesPattern(client, '')
|
||||||
self.unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern = GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(client, '')
|
self.unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern = GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(client, '')
|
||||||
|
self.adjusted: MetricsTree_Distribution_UtxoCohorts_All_Adjusted = MetricsTree_Distribution_UtxoCohorts_All_Adjusted(client)
|
||||||
self.relative: MetricsTree_Distribution_UtxoCohorts_All_Relative = MetricsTree_Distribution_UtxoCohorts_All_Relative(client)
|
self.relative: MetricsTree_Distribution_UtxoCohorts_All_Relative = MetricsTree_Distribution_UtxoCohorts_All_Relative(client)
|
||||||
|
self.dormancy: MetricPattern1[StoredF32] = MetricPattern1(client, 'dormancy')
|
||||||
|
self.velocity: MetricPattern1[StoredF32] = MetricPattern1(client, 'velocity')
|
||||||
|
|
||||||
class MetricsTree_Distribution_UtxoCohorts_Sth:
|
class MetricsTree_Distribution_UtxoCohorts_Sth:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
@@ -4344,70 +4257,18 @@ class MetricsTree_Distribution_UtxoCohorts_Sth:
|
|||||||
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'sth_supply')
|
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'sth_supply')
|
||||||
self.outputs: UtxoPattern = UtxoPattern(client, 'sth_utxo_count')
|
self.outputs: UtxoPattern = UtxoPattern(client, 'sth_utxo_count')
|
||||||
self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, 'sth')
|
self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, 'sth')
|
||||||
self.realized: AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, 'sth')
|
self.realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, 'sth')
|
||||||
self.cost_basis: InvestedMaxMinPercentilesPattern = InvestedMaxMinPercentilesPattern(client, 'sth')
|
self.cost_basis: InvestedMaxMinPercentilesPattern = InvestedMaxMinPercentilesPattern(client, 'sth')
|
||||||
self.unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern = GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(client, 'sth')
|
self.unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern = GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(client, 'sth')
|
||||||
self.relative: InvestedNegNetNuplSupplyUnrealizedPattern3 = InvestedNegNetNuplSupplyUnrealizedPattern3(client, 'sth')
|
self.relative: InvestedNegNetNuplSupplyUnrealizedPattern3 = InvestedNegNetNuplSupplyUnrealizedPattern3(client, 'sth')
|
||||||
|
self.dormancy: MetricPattern1[StoredF32] = MetricPattern1(client, 'sth_dormancy')
|
||||||
class MetricsTree_Distribution_UtxoCohorts_Lth_Realized:
|
self.velocity: MetricPattern1[StoredF32] = MetricPattern1(client, 'sth_velocity')
|
||||||
"""Metrics tree node."""
|
self.adjusted_value_created: MetricPattern1[Cents] = MetricPattern1(client, 'sth_adjusted_value_created')
|
||||||
|
self.adjusted_value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, 'sth_adjusted_value_destroyed')
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
self.adjusted_value_created_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, 'sth_adjusted_value_created')
|
||||||
self.investor_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'lth_investor_price')
|
self.adjusted_value_destroyed_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, 'sth_adjusted_value_destroyed')
|
||||||
self.investor_price_ratio: BpsRatioPattern = BpsRatioPattern(client, 'lth_investor_price_ratio')
|
self.adjusted_sopr: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, 'sth_adjusted_sopr')
|
||||||
self.lower_price_band: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'lth_lower_price_band')
|
self.adjusted_sopr_ema: _1m1wPattern = _1m1wPattern(client, 'sth_adjusted_sopr_24h_ema')
|
||||||
self.upper_price_band: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'lth_upper_price_band')
|
|
||||||
self.cap_raw: MetricPattern18[CentsSats] = MetricPattern18(client, 'lth_cap_raw')
|
|
||||||
self.investor_cap_raw: MetricPattern18[CentsSquaredSats] = MetricPattern18(client, 'lth_investor_cap_raw')
|
|
||||||
self.sell_side_risk_ratio: _1m1w1y24hPattern2 = _1m1w1y24hPattern2(client, 'lth_sell_side_risk_ratio')
|
|
||||||
self.sell_side_risk_ratio_24h_ema: _1m1wPattern2 = _1m1wPattern2(client, 'lth_sell_side_risk_ratio_24h_ema')
|
|
||||||
self.peak_regret: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, 'lth_realized_peak_regret')
|
|
||||||
self.peak_regret_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'lth_realized_peak_regret_rel_to_realized_cap')
|
|
||||||
self.profit_value_created: MetricPattern1[Cents] = MetricPattern1(client, 'lth_profit_value_created')
|
|
||||||
self.profit_value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, 'lth_profit_value_destroyed')
|
|
||||||
self.loss_value_created: MetricPattern1[Cents] = MetricPattern1(client, 'lth_loss_value_created')
|
|
||||||
self.loss_value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, 'lth_loss_value_destroyed')
|
|
||||||
self.value_created: MetricPattern1[Cents] = MetricPattern1(client, 'lth_value_created')
|
|
||||||
self.value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, 'lth_value_destroyed')
|
|
||||||
self.capitulation_flow: MetricPattern1[Dollars] = MetricPattern1(client, 'lth_capitulation_flow')
|
|
||||||
self.profit_flow: MetricPattern1[Dollars] = MetricPattern1(client, 'lth_profit_flow')
|
|
||||||
self.value_created_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, 'lth_value_created')
|
|
||||||
self.value_destroyed_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, 'lth_value_destroyed')
|
|
||||||
self.gross_pnl_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, 'lth_gross_pnl_sum')
|
|
||||||
self.net_pnl_change_1m: MetricPattern1[CentsSigned] = MetricPattern1(client, 'lth_net_pnl_change_1m')
|
|
||||||
self.net_pnl_change_1m_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'lth_net_pnl_change_1m_rel_to_realized_cap')
|
|
||||||
self.net_pnl_change_1m_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'lth_net_pnl_change_1m_rel_to_market_cap')
|
|
||||||
self.sent_in_profit: BaseCumulativePattern = BaseCumulativePattern(client, 'lth_sent_in_profit')
|
|
||||||
self.sent_in_profit_ema: _2wPattern = _2wPattern(client, 'lth_sent_in_profit_ema_2w')
|
|
||||||
self.sent_in_loss: BaseCumulativePattern = BaseCumulativePattern(client, 'lth_sent_in_loss')
|
|
||||||
self.sent_in_loss_ema: _2wPattern = _2wPattern(client, 'lth_sent_in_loss_ema_2w')
|
|
||||||
self.realized_cap_cents: MetricPattern1[Cents] = MetricPattern1(client, 'lth_realized_cap_cents')
|
|
||||||
self.realized_profit: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, 'lth_realized_profit')
|
|
||||||
self.realized_loss: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, 'lth_realized_loss')
|
|
||||||
self.realized_cap: MetricPattern1[Dollars] = MetricPattern1(client, 'lth_realized_cap')
|
|
||||||
self.realized_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'lth_realized_price')
|
|
||||||
self.realized_price_ratio: BpsRatioPattern = BpsRatioPattern(client, 'lth_realized_price_ratio')
|
|
||||||
self.realized_cap_change_1m: MetricPattern1[CentsSigned] = MetricPattern1(client, 'lth_realized_cap_change_1m')
|
|
||||||
self.mvrv: MetricPattern1[StoredF32] = MetricPattern1(client, 'lth_mvrv')
|
|
||||||
self.neg_realized_loss: MetricPattern1[Dollars] = MetricPattern1(client, 'lth_neg_realized_loss')
|
|
||||||
self.net_realized_pnl: CumulativeHeightPattern[CentsSigned] = CumulativeHeightPattern(client, 'lth_net_realized_pnl')
|
|
||||||
self.net_realized_pnl_ema_1w: MetricPattern1[CentsSigned] = MetricPattern1(client, 'lth_net_realized_pnl_ema_1w')
|
|
||||||
self.gross_pnl: CentsUsdPattern = CentsUsdPattern(client, 'lth_realized_gross_pnl')
|
|
||||||
self.realized_profit_ema_1w: MetricPattern1[Cents] = MetricPattern1(client, 'lth_realized_profit_ema_1w')
|
|
||||||
self.realized_loss_ema_1w: MetricPattern1[Cents] = MetricPattern1(client, 'lth_realized_loss_ema_1w')
|
|
||||||
self.sopr: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, 'lth_sopr')
|
|
||||||
self.sopr_24h_ema: _1m1wPattern = _1m1wPattern(client, 'lth_sopr_24h_ema')
|
|
||||||
self.realized_profit_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'lth_realized_profit_rel_to_realized_cap')
|
|
||||||
self.realized_loss_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'lth_realized_loss_rel_to_realized_cap')
|
|
||||||
self.net_realized_pnl_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'lth_net_realized_pnl_rel_to_realized_cap')
|
|
||||||
self.realized_cap_rel_to_own_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'lth_realized_cap_rel_to_own_market_cap')
|
|
||||||
self.realized_profit_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, 'lth_realized_profit')
|
|
||||||
self.realized_loss_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, 'lth_realized_loss')
|
|
||||||
self.realized_profit_to_loss_ratio: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, 'lth_realized_profit_to_loss_ratio')
|
|
||||||
self.realized_price_ratio_percentiles: RatioPattern = RatioPattern(client, 'lth_realized_price_ratio')
|
|
||||||
self.realized_price_ratio_std_dev: RatioPattern2 = RatioPattern2(client, 'lth_realized_price_ratio')
|
|
||||||
self.investor_price_ratio_percentiles: RatioPattern = RatioPattern(client, 'lth_investor_price_ratio')
|
|
||||||
self.investor_price_ratio_std_dev: RatioPattern2 = RatioPattern2(client, 'lth_investor_price_ratio')
|
|
||||||
|
|
||||||
class MetricsTree_Distribution_UtxoCohorts_Lth:
|
class MetricsTree_Distribution_UtxoCohorts_Lth:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
@@ -4416,10 +4277,12 @@ class MetricsTree_Distribution_UtxoCohorts_Lth:
|
|||||||
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'lth_supply')
|
self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'lth_supply')
|
||||||
self.outputs: UtxoPattern = UtxoPattern(client, 'lth_utxo_count')
|
self.outputs: UtxoPattern = UtxoPattern(client, 'lth_utxo_count')
|
||||||
self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, 'lth')
|
self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, 'lth')
|
||||||
self.realized: MetricsTree_Distribution_UtxoCohorts_Lth_Realized = MetricsTree_Distribution_UtxoCohorts_Lth_Realized(client)
|
self.realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, 'lth')
|
||||||
self.cost_basis: InvestedMaxMinPercentilesPattern = InvestedMaxMinPercentilesPattern(client, 'lth')
|
self.cost_basis: InvestedMaxMinPercentilesPattern = InvestedMaxMinPercentilesPattern(client, 'lth')
|
||||||
self.unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern = GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(client, 'lth')
|
self.unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern = GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(client, 'lth')
|
||||||
self.relative: InvestedNegNetNuplSupplyUnrealizedPattern3 = InvestedNegNetNuplSupplyUnrealizedPattern3(client, 'lth')
|
self.relative: InvestedNegNetNuplSupplyUnrealizedPattern3 = InvestedNegNetNuplSupplyUnrealizedPattern3(client, 'lth')
|
||||||
|
self.dormancy: MetricPattern1[StoredF32] = MetricPattern1(client, 'lth_dormancy')
|
||||||
|
self.velocity: MetricPattern1[StoredF32] = MetricPattern1(client, 'lth_velocity')
|
||||||
|
|
||||||
class MetricsTree_Distribution_UtxoCohorts_AgeRange:
|
class MetricsTree_Distribution_UtxoCohorts_AgeRange:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
@@ -4451,47 +4314,80 @@ class MetricsTree_Distribution_UtxoCohorts_MaxAge:
|
|||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
self._1w: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_1w_old')
|
self._1w: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_1w_old')
|
||||||
self._1m: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_1m_old')
|
self._1m: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_1m_old')
|
||||||
self._2m: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_2m_old')
|
self._2m: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_2m_old')
|
||||||
self._3m: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_3m_old')
|
self._3m: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_3m_old')
|
||||||
self._4m: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_4m_old')
|
self._4m: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_4m_old')
|
||||||
self._5m: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_5m_old')
|
self._5m: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_5m_old')
|
||||||
self._6m: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_6m_old')
|
self._6m: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_6m_old')
|
||||||
self._1y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_1y_old')
|
self._1y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_1y_old')
|
||||||
self._2y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_2y_old')
|
self._2y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_2y_old')
|
||||||
self._3y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_3y_old')
|
self._3y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_3y_old')
|
||||||
self._4y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_4y_old')
|
self._4y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_4y_old')
|
||||||
self._5y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_5y_old')
|
self._5y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_5y_old')
|
||||||
self._6y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_6y_old')
|
self._6y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_6y_old')
|
||||||
self._7y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_7y_old')
|
self._7y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_7y_old')
|
||||||
self._8y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_8y_old')
|
self._8y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_8y_old')
|
||||||
self._10y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_10y_old')
|
self._10y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_10y_old')
|
||||||
self._12y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_12y_old')
|
self._12y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_12y_old')
|
||||||
self._15y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_under_15y_old')
|
self._15y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_under_15y_old')
|
||||||
|
|
||||||
class MetricsTree_Distribution_UtxoCohorts_MinAge:
|
class MetricsTree_Distribution_UtxoCohorts_MinAge:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
self._1d: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_1d_old')
|
self._1d: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_1d_old')
|
||||||
self._1w: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_1w_old')
|
self._1w: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_1w_old')
|
||||||
self._1m: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_1m_old')
|
self._1m: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_1m_old')
|
||||||
self._2m: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_2m_old')
|
self._2m: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_2m_old')
|
||||||
self._3m: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_3m_old')
|
self._3m: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_3m_old')
|
||||||
self._4m: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_4m_old')
|
self._4m: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_4m_old')
|
||||||
self._5m: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_5m_old')
|
self._5m: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_5m_old')
|
||||||
self._6m: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_6m_old')
|
self._6m: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_6m_old')
|
||||||
self._1y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_1y_old')
|
self._1y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_1y_old')
|
||||||
self._2y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_2y_old')
|
self._2y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_2y_old')
|
||||||
self._3y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_3y_old')
|
self._3y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_3y_old')
|
||||||
self._4y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_4y_old')
|
self._4y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_4y_old')
|
||||||
self._5y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_5y_old')
|
self._5y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_5y_old')
|
||||||
self._6y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_6y_old')
|
self._6y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_6y_old')
|
||||||
self._7y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_7y_old')
|
self._7y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_7y_old')
|
||||||
self._8y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_8y_old')
|
self._8y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_8y_old')
|
||||||
self._10y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_10y_old')
|
self._10y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_10y_old')
|
||||||
self._12y: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, 'utxos_over_12y_old')
|
self._12y: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'utxos_over_12y_old')
|
||||||
|
|
||||||
|
class MetricsTree_Distribution_UtxoCohorts_Epoch:
|
||||||
|
"""Metrics tree node."""
|
||||||
|
|
||||||
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
|
self._0: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'epoch_0')
|
||||||
|
self._1: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'epoch_1')
|
||||||
|
self._2: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'epoch_2')
|
||||||
|
self._3: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'epoch_3')
|
||||||
|
self._4: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'epoch_4')
|
||||||
|
|
||||||
|
class MetricsTree_Distribution_UtxoCohorts_Class:
|
||||||
|
"""Metrics tree node."""
|
||||||
|
|
||||||
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
|
self._2009: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2009')
|
||||||
|
self._2010: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2010')
|
||||||
|
self._2011: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2011')
|
||||||
|
self._2012: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2012')
|
||||||
|
self._2013: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2013')
|
||||||
|
self._2014: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2014')
|
||||||
|
self._2015: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2015')
|
||||||
|
self._2016: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2016')
|
||||||
|
self._2017: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2017')
|
||||||
|
self._2018: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2018')
|
||||||
|
self._2019: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2019')
|
||||||
|
self._2020: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2020')
|
||||||
|
self._2021: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2021')
|
||||||
|
self._2022: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2022')
|
||||||
|
self._2023: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2023')
|
||||||
|
self._2024: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2024')
|
||||||
|
self._2025: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2025')
|
||||||
|
self._2026: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2 = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern2(client, 'class_2026')
|
||||||
|
|
||||||
class MetricsTree_Distribution_UtxoCohorts_GeAmount:
|
class MetricsTree_Distribution_UtxoCohorts_GeAmount:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
@@ -4549,54 +4445,21 @@ class MetricsTree_Distribution_UtxoCohorts_LtAmount:
|
|||||||
self._10k_btc: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'utxos_under_10k_btc')
|
self._10k_btc: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'utxos_under_10k_btc')
|
||||||
self._100k_btc: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'utxos_under_100k_btc')
|
self._100k_btc: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'utxos_under_100k_btc')
|
||||||
|
|
||||||
class MetricsTree_Distribution_UtxoCohorts_Epoch:
|
|
||||||
"""Metrics tree node."""
|
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
|
||||||
self._0: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'epoch_0')
|
|
||||||
self._1: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'epoch_1')
|
|
||||||
self._2: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'epoch_2')
|
|
||||||
self._3: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'epoch_3')
|
|
||||||
self._4: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'epoch_4')
|
|
||||||
|
|
||||||
class MetricsTree_Distribution_UtxoCohorts_Class:
|
|
||||||
"""Metrics tree node."""
|
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
|
||||||
self._2009: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2009')
|
|
||||||
self._2010: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2010')
|
|
||||||
self._2011: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2011')
|
|
||||||
self._2012: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2012')
|
|
||||||
self._2013: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2013')
|
|
||||||
self._2014: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2014')
|
|
||||||
self._2015: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2015')
|
|
||||||
self._2016: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2016')
|
|
||||||
self._2017: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2017')
|
|
||||||
self._2018: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2018')
|
|
||||||
self._2019: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2019')
|
|
||||||
self._2020: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2020')
|
|
||||||
self._2021: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2021')
|
|
||||||
self._2022: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2022')
|
|
||||||
self._2023: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2023')
|
|
||||||
self._2024: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2024')
|
|
||||||
self._2025: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2025')
|
|
||||||
self._2026: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'class_2026')
|
|
||||||
|
|
||||||
class MetricsTree_Distribution_UtxoCohorts_Type:
|
class MetricsTree_Distribution_UtxoCohorts_Type:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
self.p2pk65: OutputsRealizedRelativeSupplyUnrealizedPattern = OutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2pk65')
|
self.p2pk65: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2pk65')
|
||||||
self.p2pk33: OutputsRealizedRelativeSupplyUnrealizedPattern = OutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2pk33')
|
self.p2pk33: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2pk33')
|
||||||
self.p2pkh: OutputsRealizedRelativeSupplyUnrealizedPattern = OutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2pkh')
|
self.p2pkh: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2pkh')
|
||||||
self.p2ms: OutputsRealizedRelativeSupplyUnrealizedPattern = OutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2ms')
|
self.p2ms: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2ms')
|
||||||
self.p2sh: OutputsRealizedRelativeSupplyUnrealizedPattern = OutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2sh')
|
self.p2sh: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2sh')
|
||||||
self.p2wpkh: OutputsRealizedRelativeSupplyUnrealizedPattern = OutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2wpkh')
|
self.p2wpkh: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2wpkh')
|
||||||
self.p2wsh: OutputsRealizedRelativeSupplyUnrealizedPattern = OutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2wsh')
|
self.p2wsh: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2wsh')
|
||||||
self.p2tr: OutputsRealizedRelativeSupplyUnrealizedPattern = OutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2tr')
|
self.p2tr: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2tr')
|
||||||
self.p2a: OutputsRealizedRelativeSupplyUnrealizedPattern = OutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2a')
|
self.p2a: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'p2a')
|
||||||
self.unknown: OutputsRealizedRelativeSupplyUnrealizedPattern = OutputsRealizedRelativeSupplyUnrealizedPattern(client, 'unknown_outputs')
|
self.unknown: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'unknown_outputs')
|
||||||
self.empty: OutputsRealizedRelativeSupplyUnrealizedPattern = OutputsRealizedRelativeSupplyUnrealizedPattern(client, 'empty_outputs')
|
self.empty: ActivityOutputsRealizedRelativeSupplyUnrealizedPattern = ActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, 'empty_outputs')
|
||||||
|
|
||||||
class MetricsTree_Distribution_UtxoCohorts:
|
class MetricsTree_Distribution_UtxoCohorts:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
@@ -4608,11 +4471,11 @@ class MetricsTree_Distribution_UtxoCohorts:
|
|||||||
self.age_range: MetricsTree_Distribution_UtxoCohorts_AgeRange = MetricsTree_Distribution_UtxoCohorts_AgeRange(client)
|
self.age_range: MetricsTree_Distribution_UtxoCohorts_AgeRange = MetricsTree_Distribution_UtxoCohorts_AgeRange(client)
|
||||||
self.max_age: MetricsTree_Distribution_UtxoCohorts_MaxAge = MetricsTree_Distribution_UtxoCohorts_MaxAge(client)
|
self.max_age: MetricsTree_Distribution_UtxoCohorts_MaxAge = MetricsTree_Distribution_UtxoCohorts_MaxAge(client)
|
||||||
self.min_age: MetricsTree_Distribution_UtxoCohorts_MinAge = MetricsTree_Distribution_UtxoCohorts_MinAge(client)
|
self.min_age: MetricsTree_Distribution_UtxoCohorts_MinAge = MetricsTree_Distribution_UtxoCohorts_MinAge(client)
|
||||||
|
self.epoch: MetricsTree_Distribution_UtxoCohorts_Epoch = MetricsTree_Distribution_UtxoCohorts_Epoch(client)
|
||||||
|
self.class: MetricsTree_Distribution_UtxoCohorts_Class = MetricsTree_Distribution_UtxoCohorts_Class(client)
|
||||||
self.ge_amount: MetricsTree_Distribution_UtxoCohorts_GeAmount = MetricsTree_Distribution_UtxoCohorts_GeAmount(client)
|
self.ge_amount: MetricsTree_Distribution_UtxoCohorts_GeAmount = MetricsTree_Distribution_UtxoCohorts_GeAmount(client)
|
||||||
self.amount_range: MetricsTree_Distribution_UtxoCohorts_AmountRange = MetricsTree_Distribution_UtxoCohorts_AmountRange(client)
|
self.amount_range: MetricsTree_Distribution_UtxoCohorts_AmountRange = MetricsTree_Distribution_UtxoCohorts_AmountRange(client)
|
||||||
self.lt_amount: MetricsTree_Distribution_UtxoCohorts_LtAmount = MetricsTree_Distribution_UtxoCohorts_LtAmount(client)
|
self.lt_amount: MetricsTree_Distribution_UtxoCohorts_LtAmount = MetricsTree_Distribution_UtxoCohorts_LtAmount(client)
|
||||||
self.epoch: MetricsTree_Distribution_UtxoCohorts_Epoch = MetricsTree_Distribution_UtxoCohorts_Epoch(client)
|
|
||||||
self.class: MetricsTree_Distribution_UtxoCohorts_Class = MetricsTree_Distribution_UtxoCohorts_Class(client)
|
|
||||||
self.type_: MetricsTree_Distribution_UtxoCohorts_Type = MetricsTree_Distribution_UtxoCohorts_Type(client)
|
self.type_: MetricsTree_Distribution_UtxoCohorts_Type = MetricsTree_Distribution_UtxoCohorts_Type(client)
|
||||||
|
|
||||||
class MetricsTree_Distribution_AddressCohorts_GeAmount:
|
class MetricsTree_Distribution_AddressCohorts_GeAmount:
|
||||||
|
|||||||
Reference in New Issue
Block a user