mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-27 18:58:10 -07:00
global: snapshot
This commit is contained in:
@@ -10,10 +10,10 @@ use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
CentsType, ComputedFromHeight, ComputedFromHeightCumulative,
|
||||
ComputedFromHeightCumulativeSum, ComputedFromHeightRatio, FiatFromHeight, NumericValue,
|
||||
PercentFromHeight, PercentRollingWindows, Price, RollingDelta1m, RollingDeltaExcept1m,
|
||||
RollingWindow24h, RollingWindows, RollingWindowsFrom1w,
|
||||
ValueFromHeight, ValueFromHeightCumulative,
|
||||
ComputedFromHeightCumulativeSum, ComputedFromHeightRatio, FiatFromHeight,
|
||||
FiatRollingDelta1m, FiatRollingDeltaExcept1m, NumericValue, PercentFromHeight,
|
||||
PercentRollingWindows, Price, RollingDelta1m, RollingDeltaExcept1m, RollingWindow24h,
|
||||
RollingWindows, RollingWindowsFrom1w, ValueFromHeight, ValueFromHeightCumulative,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -96,6 +96,16 @@ impl<S: NumericValue + JsonSchema, C: NumericValue + JsonSchema> ConfigImport
|
||||
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
|
||||
}
|
||||
}
|
||||
impl<S: NumericValue + JsonSchema, C: CentsType> ConfigImport for FiatRollingDelta1m<S, C> {
|
||||
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
|
||||
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
|
||||
}
|
||||
}
|
||||
impl<S: NumericValue + JsonSchema, C: CentsType> ConfigImport for FiatRollingDeltaExcept1m<S, C> {
|
||||
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
|
||||
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
|
||||
}
|
||||
}
|
||||
impl<T: BytesVecValue> ConfigImport for BytesVec<Height, T> {
|
||||
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
|
||||
Ok(Self::forced_import(
|
||||
|
||||
@@ -36,6 +36,7 @@ mod cohort;
|
||||
mod config;
|
||||
mod cost_basis;
|
||||
mod outputs;
|
||||
mod profitability;
|
||||
mod realized;
|
||||
mod relative;
|
||||
mod supply;
|
||||
@@ -48,6 +49,7 @@ pub use cohort::{
|
||||
};
|
||||
pub use config::ImportConfig;
|
||||
pub use cost_basis::CostBasis;
|
||||
pub use profitability::ProfitabilityMetrics;
|
||||
pub use outputs::OutputsMetrics;
|
||||
pub use realized::{
|
||||
RealizedAdjusted, RealizedBase, RealizedCore, RealizedFull, RealizedLike, RealizedMinimal,
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
use brk_cohort::{ByLoss, ByProfit, ByProfitabilityRange};
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Dollars, Height, Sats, Version};
|
||||
use vecdb::{AnyStoredVec, AnyVec, Database, Rw, StorageMode, WritableVec};
|
||||
|
||||
use crate::{indexes, internal::ComputedFromHeight};
|
||||
|
||||
/// Supply + realized cap for a single profitability bucket.
|
||||
#[derive(Traversable)]
|
||||
pub struct ProfitabilityBucket<M: StorageMode = Rw> {
|
||||
pub supply: ComputedFromHeight<Sats, M>,
|
||||
pub realized_cap: ComputedFromHeight<Dollars, M>,
|
||||
}
|
||||
|
||||
impl<M: StorageMode> ProfitabilityBucket<M> {
|
||||
fn min_len(&self) -> usize {
|
||||
self.supply.height.len().min(self.realized_cap.height.len())
|
||||
}
|
||||
}
|
||||
|
||||
impl ProfitabilityBucket {
|
||||
fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
supply: ComputedFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_supply"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
realized_cap: ComputedFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_realized_cap"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn truncate_push(
|
||||
&mut self,
|
||||
height: Height,
|
||||
supply: Sats,
|
||||
realized_cap: Dollars,
|
||||
) -> Result<()> {
|
||||
self.supply.height.truncate_push(height, supply)?;
|
||||
self.realized_cap
|
||||
.height
|
||||
.truncate_push(height, realized_cap)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
vec![
|
||||
&mut self.supply.height as &mut dyn AnyStoredVec,
|
||||
&mut self.realized_cap.height as &mut dyn AnyStoredVec,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/// All profitability metrics: 25 ranges + 15 profit thresholds + 10 loss thresholds.
|
||||
#[derive(Traversable)]
|
||||
pub struct ProfitabilityMetrics<M: StorageMode = Rw> {
|
||||
pub range: ByProfitabilityRange<ProfitabilityBucket<M>>,
|
||||
pub profit: ByProfit<ProfitabilityBucket<M>>,
|
||||
pub loss: ByLoss<ProfitabilityBucket<M>>,
|
||||
}
|
||||
|
||||
impl<M: StorageMode> ProfitabilityMetrics<M> {
|
||||
pub(crate) fn min_stateful_height_len(&self) -> usize {
|
||||
self.range.iter()
|
||||
.chain(self.profit.iter())
|
||||
.chain(self.loss.iter())
|
||||
.map(|b| b.min_len())
|
||||
.min()
|
||||
.unwrap_or(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl ProfitabilityMetrics {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
let range = ByProfitabilityRange::try_new(|name| {
|
||||
ProfitabilityBucket::forced_import(db, name, version, indexes)
|
||||
})?;
|
||||
|
||||
let profit = ByProfit::try_new(|name| {
|
||||
ProfitabilityBucket::forced_import(db, name, version, indexes)
|
||||
})?;
|
||||
|
||||
let loss = ByLoss::try_new(|name| {
|
||||
ProfitabilityBucket::forced_import(db, name, version, indexes)
|
||||
})?;
|
||||
|
||||
Ok(Self {
|
||||
range,
|
||||
profit,
|
||||
loss,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
let mut vecs = Vec::new();
|
||||
for bucket in self.range.iter_mut() {
|
||||
vecs.extend(bucket.collect_all_vecs_mut());
|
||||
}
|
||||
for bucket in self.profit.iter_mut() {
|
||||
vecs.extend(bucket.collect_all_vecs_mut());
|
||||
}
|
||||
for bucket in self.loss.iter_mut() {
|
||||
vecs.extend(bucket.collect_all_vecs_mut());
|
||||
}
|
||||
vecs
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,8 +10,8 @@ use crate::{
|
||||
blocks,
|
||||
distribution::state::RealizedOps,
|
||||
internal::{
|
||||
ComputedFromHeight, LazyFromHeight, NegCentsUnsignedToDollars, RatioCents64,
|
||||
RollingDelta1m, RollingWindow24h,
|
||||
ComputedFromHeight, FiatRollingDelta1m, LazyFromHeight, NegCentsUnsignedToDollars,
|
||||
RatioCents64, RollingWindow24h,
|
||||
},
|
||||
prices,
|
||||
};
|
||||
@@ -27,7 +27,7 @@ pub struct RealizedCore<M: StorageMode = Rw> {
|
||||
#[traversable(flatten)]
|
||||
pub minimal: RealizedMinimal<M>,
|
||||
|
||||
pub realized_cap_delta: RollingDelta1m<Cents, CentsSigned, M>,
|
||||
pub realized_cap_delta: FiatRollingDelta1m<Cents, CentsSigned, M>,
|
||||
|
||||
pub neg_realized_loss: LazyFromHeight<Dollars, Cents>,
|
||||
pub net_realized_pnl: ComputedFromHeight<CentsSigned, M>,
|
||||
|
||||
@@ -14,12 +14,12 @@ use crate::{
|
||||
blocks,
|
||||
distribution::state::RealizedState,
|
||||
internal::{
|
||||
CentsUnsignedToDollars, ComputedFromHeight, ComputedFromHeightCumulative, FiatFromHeight,
|
||||
CentsUnsignedToDollars, ComputedFromHeight, ComputedFromHeightCumulative,
|
||||
ComputedFromHeightRatio, ComputedFromHeightRatioPercentiles,
|
||||
ComputedFromHeightRatioStdDevBands, LazyFromHeight, PercentFromHeight,
|
||||
PercentRollingWindows, Price, RatioCents64, RatioCentsBp32,
|
||||
RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32, RatioDollarsBp32,
|
||||
RollingDelta1m, RollingDeltaExcept1m, RollingWindows, RollingWindowsFrom1w,
|
||||
ComputedFromHeightRatioStdDevBands, FiatFromHeight, FiatRollingDelta1m,
|
||||
FiatRollingDeltaExcept1m, LazyFromHeight, PercentFromHeight, PercentRollingWindows, Price,
|
||||
RatioCents64, RatioCentsBp32, RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32,
|
||||
RatioDollarsBp32, RollingWindows, RollingWindowsFrom1w,
|
||||
},
|
||||
prices,
|
||||
};
|
||||
@@ -59,12 +59,12 @@ pub struct RealizedFull<M: StorageMode = Rw> {
|
||||
pub net_realized_pnl_cumulative: ComputedFromHeight<CentsSigned, M>,
|
||||
pub net_realized_pnl_sum_extended: RollingWindowsFrom1w<CentsSigned, M>,
|
||||
|
||||
pub net_pnl_delta: RollingDelta1m<CentsSigned, CentsSigned, M>,
|
||||
pub net_pnl_delta_extended: RollingDeltaExcept1m<CentsSigned, CentsSigned, M>,
|
||||
pub net_pnl_delta: FiatRollingDelta1m<CentsSigned, CentsSigned, M>,
|
||||
pub net_pnl_delta_extended: FiatRollingDeltaExcept1m<CentsSigned, 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 realized_cap_delta_extended: RollingDeltaExcept1m<Cents, CentsSigned, M>,
|
||||
pub realized_cap_delta_extended: FiatRollingDeltaExcept1m<Cents, CentsSigned, M>,
|
||||
|
||||
pub investor_price: Price<ComputedFromHeight<Cents, M>>,
|
||||
pub investor_price_ratio: ComputedFromHeightRatio<M>,
|
||||
@@ -468,14 +468,14 @@ impl RealizedFull {
|
||||
self.net_pnl_change_1m_rel_to_realized_cap
|
||||
.compute_binary::<CentsSigned, Cents, RatioCentsSignedCentsBps32>(
|
||||
starting_indexes.height,
|
||||
&self.net_pnl_delta.change_1m.height,
|
||||
&self.net_pnl_delta.change_1m.cents.height,
|
||||
&self.base.core.minimal.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_delta.change_1m.height,
|
||||
&self.net_pnl_delta.change_1m.cents.height,
|
||||
height_to_market_cap,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Reference in New Issue
Block a user