mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-23 22:29:59 -07:00
global: snapshot
This commit is contained in:
@@ -1,18 +1,19 @@
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
BasisPoints32, Bitcoin, Cents, Dollars, Height, Indexes, Sats, StoredF32, Version,
|
||||
BasisPoints32, BasisPointsSigned32, Bitcoin, Cents, Height, Indexes, Sats, StoredF32,
|
||||
Version,
|
||||
};
|
||||
use vecdb::{
|
||||
AnyStoredVec, AnyVec, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode, WritableVec,
|
||||
AnyStoredVec, AnyVec, Exit, ReadableVec, Rw, StorageMode, WritableVec,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
blocks,
|
||||
distribution::state::RealizedOps,
|
||||
distribution::state::{CohortState, RealizedOps},
|
||||
internal::{
|
||||
CentsUnsignedToDollars, ComputedPerBlock, ComputedPerBlockCumulative, Identity,
|
||||
LazyPerBlock, Price, RatioPerBlock, RollingWindow24h,
|
||||
ComputedPerBlock, FiatPerBlock, FiatPerBlockWithSum24h, Identity, LazyPerBlock,
|
||||
PerBlockWithSum24h, Price, RatioPerBlock,
|
||||
},
|
||||
prices,
|
||||
};
|
||||
@@ -20,77 +21,92 @@ use crate::{
|
||||
use crate::distribution::metrics::ImportConfig;
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct RealizedMinimal<M: StorageMode = Rw> {
|
||||
pub cap_cents: ComputedPerBlock<Cents, M>,
|
||||
pub profit: ComputedPerBlockCumulative<Cents, M>,
|
||||
pub loss: ComputedPerBlockCumulative<Cents, M>,
|
||||
pub cap: LazyPerBlock<Dollars, Cents>,
|
||||
pub price: Price<ComputedPerBlock<Cents, M>>,
|
||||
pub price_ratio: RatioPerBlock<M>,
|
||||
pub mvrv: LazyPerBlock<StoredF32>,
|
||||
pub struct RealizedSoprMinimal<M: StorageMode = Rw> {
|
||||
pub value_created: PerBlockWithSum24h<Cents, M>,
|
||||
pub value_destroyed: PerBlockWithSum24h<Cents, M>,
|
||||
}
|
||||
|
||||
pub profit_sum: RollingWindow24h<Cents, M>,
|
||||
pub loss_sum: RollingWindow24h<Cents, M>,
|
||||
/// Minimal realized metrics: cap (fiat), profit/loss (fiat + 24h sum),
|
||||
/// price, mvrv, nupl, sopr (value_created/destroyed with 24h sums).
|
||||
#[derive(Traversable)]
|
||||
pub struct RealizedMinimal<M: StorageMode = Rw> {
|
||||
pub cap: FiatPerBlock<Cents, M>,
|
||||
pub profit: FiatPerBlockWithSum24h<Cents, M>,
|
||||
pub loss: FiatPerBlockWithSum24h<Cents, M>,
|
||||
pub price: Price<ComputedPerBlock<Cents, M>>,
|
||||
pub price_ratio: RatioPerBlock<BasisPoints32, M>,
|
||||
pub mvrv: LazyPerBlock<StoredF32>,
|
||||
pub nupl: RatioPerBlock<BasisPointsSigned32, M>,
|
||||
|
||||
pub sopr: RealizedSoprMinimal<M>,
|
||||
}
|
||||
|
||||
impl RealizedMinimal {
|
||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||
let realized_cap_cents: ComputedPerBlock<Cents> =
|
||||
cfg.import("realized_cap_cents", Version::ZERO)?;
|
||||
let realized_cap = LazyPerBlock::from_computed::<CentsUnsignedToDollars>(
|
||||
&cfg.name("realized_cap"),
|
||||
cfg.version,
|
||||
realized_cap_cents.height.read_only_boxed_clone(),
|
||||
&realized_cap_cents,
|
||||
);
|
||||
let v1 = Version::ONE;
|
||||
|
||||
let realized_profit = cfg.import("realized_profit", Version::ZERO)?;
|
||||
let realized_loss = cfg.import("realized_loss", Version::ZERO)?;
|
||||
let cap: FiatPerBlock<Cents> = cfg.import("realized_cap", Version::ZERO)?;
|
||||
|
||||
let realized_price = cfg.import("realized_price", Version::ONE)?;
|
||||
let realized_price_ratio: RatioPerBlock = cfg.import("realized_price", Version::ONE)?;
|
||||
let realized_price = cfg.import("realized_price", v1)?;
|
||||
let realized_price_ratio: RatioPerBlock = cfg.import("realized_price", v1)?;
|
||||
let mvrv = LazyPerBlock::from_lazy::<Identity<StoredF32>, BasisPoints32>(
|
||||
&cfg.name("mvrv"),
|
||||
cfg.version,
|
||||
&realized_price_ratio.ratio,
|
||||
);
|
||||
|
||||
let realized_profit_sum = cfg.import("realized_profit", Version::ONE)?;
|
||||
let realized_loss_sum = cfg.import("realized_loss", Version::ONE)?;
|
||||
let nupl = cfg.import("nupl", v1)?;
|
||||
|
||||
Ok(Self {
|
||||
cap_cents: realized_cap_cents,
|
||||
profit: realized_profit,
|
||||
loss: realized_loss,
|
||||
cap: realized_cap,
|
||||
cap,
|
||||
profit: cfg.import("realized_profit", v1)?,
|
||||
loss: cfg.import("realized_loss", v1)?,
|
||||
price: realized_price,
|
||||
price_ratio: realized_price_ratio,
|
||||
mvrv,
|
||||
profit_sum: realized_profit_sum,
|
||||
loss_sum: realized_loss_sum,
|
||||
nupl,
|
||||
sopr: RealizedSoprMinimal {
|
||||
value_created: cfg.import("value_created", v1)?,
|
||||
value_destroyed: cfg.import("value_destroyed", v1)?,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn min_stateful_height_len(&self) -> usize {
|
||||
self.cap_cents
|
||||
self.cap
|
||||
.cents
|
||||
.height
|
||||
.len()
|
||||
.min(self.profit.height.len())
|
||||
.min(self.loss.height.len())
|
||||
.min(self.profit.raw.cents.height.len())
|
||||
.min(self.loss.raw.cents.height.len())
|
||||
.min(self.sopr.value_created.raw.height.len())
|
||||
.min(self.sopr.value_destroyed.raw.height.len())
|
||||
}
|
||||
|
||||
pub(crate) fn truncate_push(&mut self, height: Height, state: &impl RealizedOps) -> Result<()> {
|
||||
self.cap_cents.height.truncate_push(height, state.cap())?;
|
||||
self.profit.height.truncate_push(height, state.profit())?;
|
||||
self.loss.height.truncate_push(height, state.loss())?;
|
||||
pub(crate) fn truncate_push(&mut self, height: Height, state: &CohortState<impl RealizedOps>) -> Result<()> {
|
||||
self.cap.cents.height.truncate_push(height, state.realized.cap())?;
|
||||
self.profit.raw.cents.height.truncate_push(height, state.realized.profit())?;
|
||||
self.loss.raw.cents.height.truncate_push(height, state.realized.loss())?;
|
||||
self.sopr
|
||||
.value_created
|
||||
.raw
|
||||
.height
|
||||
.truncate_push(height, state.realized.value_created())?;
|
||||
self.sopr
|
||||
.value_destroyed
|
||||
.raw
|
||||
.height
|
||||
.truncate_push(height, state.realized.value_destroyed())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
vec![
|
||||
&mut self.cap_cents.height as &mut dyn AnyStoredVec,
|
||||
&mut self.profit.height,
|
||||
&mut self.loss.height,
|
||||
&mut self.cap.cents.height as &mut dyn AnyStoredVec,
|
||||
&mut self.profit.raw.cents.height,
|
||||
&mut self.loss.raw.cents.height,
|
||||
&mut self.sopr.value_created.raw.height,
|
||||
&mut self.sopr.value_destroyed.raw.height,
|
||||
]
|
||||
}
|
||||
|
||||
@@ -100,9 +116,11 @@ impl RealizedMinimal {
|
||||
others: &[&Self],
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
sum_others!(self, starting_indexes, others, exit; cap_cents.height);
|
||||
sum_others!(self, starting_indexes, others, exit; profit.height);
|
||||
sum_others!(self, starting_indexes, others, exit; loss.height);
|
||||
sum_others!(self, starting_indexes, others, exit; cap.cents.height);
|
||||
sum_others!(self, starting_indexes, others, exit; profit.raw.cents.height);
|
||||
sum_others!(self, starting_indexes, others, exit; loss.raw.cents.height);
|
||||
sum_others!(self, starting_indexes, others, exit; sopr.value_created.raw.height);
|
||||
sum_others!(self, starting_indexes, others, exit; sopr.value_destroyed.raw.height);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -112,18 +130,28 @@ impl RealizedMinimal {
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.profit.compute_rest(starting_indexes.height, exit)?;
|
||||
self.loss.compute_rest(starting_indexes.height, exit)?;
|
||||
self.profit_sum.compute_rolling_sum(
|
||||
self.profit.sum.compute_rolling_sum(
|
||||
starting_indexes.height,
|
||||
&blocks.lookback.height_24h_ago,
|
||||
&self.profit.height,
|
||||
&self.profit.raw.cents.height,
|
||||
exit,
|
||||
)?;
|
||||
self.loss_sum.compute_rolling_sum(
|
||||
self.loss.sum.compute_rolling_sum(
|
||||
starting_indexes.height,
|
||||
&blocks.lookback.height_24h_ago,
|
||||
&self.loss.height,
|
||||
&self.loss.raw.cents.height,
|
||||
exit,
|
||||
)?;
|
||||
self.sopr.value_created.sum.compute_rolling_sum(
|
||||
starting_indexes.height,
|
||||
&blocks.lookback.height_24h_ago,
|
||||
&self.sopr.value_created.raw.height,
|
||||
exit,
|
||||
)?;
|
||||
self.sopr.value_destroyed.sum.compute_rolling_sum(
|
||||
starting_indexes.height,
|
||||
&blocks.lookback.height_24h_ago,
|
||||
&self.sopr.value_destroyed.raw.height,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
@@ -138,7 +166,7 @@ impl RealizedMinimal {
|
||||
) -> Result<()> {
|
||||
self.price.cents.height.compute_transform2(
|
||||
starting_indexes.height,
|
||||
&self.cap_cents.height,
|
||||
&self.cap.cents.height,
|
||||
height_to_supply,
|
||||
|(i, cap_cents, supply, ..)| {
|
||||
let cap = cap_cents.as_u128();
|
||||
@@ -159,6 +187,23 @@ impl RealizedMinimal {
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.nupl.bps.height.compute_transform2(
|
||||
starting_indexes.height,
|
||||
&prices.price.cents.height,
|
||||
&self.price.cents.height,
|
||||
|(i, price, realized_price, ..)| {
|
||||
let p = price.as_u128();
|
||||
if p == 0 {
|
||||
(i, BasisPointsSigned32::ZERO)
|
||||
} else {
|
||||
let rp = realized_price.as_u128();
|
||||
let nupl_bps = ((p as i128 - rp as i128) * 10000) / p as i128;
|
||||
(i, BasisPointsSigned32::from(nupl_bps as i32))
|
||||
}
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user