mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-18 10:49:44 -07:00
global: snapshot
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::Dollars;
|
||||
use brk_types::Cents;
|
||||
use vecdb::Exit;
|
||||
|
||||
use super::super::{activity, value};
|
||||
@@ -17,12 +17,12 @@ impl Vecs {
|
||||
value: &value::Vecs,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
let realized_cap = &distribution
|
||||
let realized_cap_cents = &distribution
|
||||
.utxo_cohorts
|
||||
.all
|
||||
.metrics
|
||||
.realized
|
||||
.realized_cap
|
||||
.realized_cap_cents
|
||||
.height;
|
||||
|
||||
let circulating_supply = &distribution
|
||||
@@ -34,36 +34,42 @@ impl Vecs {
|
||||
.btc
|
||||
.height;
|
||||
|
||||
self.thermo_cap.height.compute_transform(
|
||||
self.thermo_cap.cents.height.compute_transform(
|
||||
starting_indexes.height,
|
||||
&mining.rewards.subsidy.cumulative.usd.height,
|
||||
&mining.rewards.subsidy.cumulative.cents.height,
|
||||
|(i, v, ..)| (i, v),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.investor_cap.height.compute_subtract(
|
||||
self.investor_cap.cents.height.compute_subtract(
|
||||
starting_indexes.height,
|
||||
realized_cap,
|
||||
&self.thermo_cap.height,
|
||||
realized_cap_cents,
|
||||
&self.thermo_cap.cents.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.vaulted_cap.height.compute_divide(
|
||||
self.vaulted_cap.cents.height.compute_transform2(
|
||||
starting_indexes.height,
|
||||
realized_cap,
|
||||
realized_cap_cents,
|
||||
&activity.vaultedness.height,
|
||||
|(i, cap, vaultedness, ..)| {
|
||||
(i, Cents::from(f64::from(cap) / f64::from(vaultedness)))
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.active_cap.height.compute_multiply(
|
||||
self.active_cap.cents.height.compute_transform2(
|
||||
starting_indexes.height,
|
||||
realized_cap,
|
||||
realized_cap_cents,
|
||||
&activity.liveliness.height,
|
||||
|(i, cap, liveliness, ..)| {
|
||||
(i, Cents::from(f64::from(cap) * f64::from(liveliness)))
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// cointime_cap = (cointime_value_destroyed_cumulative * circulating_supply) / coinblocks_stored_cumulative
|
||||
self.cointime_cap.height.compute_transform3(
|
||||
self.cointime_cap.cents.height.compute_transform3(
|
||||
starting_indexes.height,
|
||||
&value.cointime_value_destroyed.cumulative.height,
|
||||
circulating_supply,
|
||||
@@ -72,7 +78,7 @@ impl Vecs {
|
||||
let destroyed: f64 = *destroyed;
|
||||
let supply: f64 = supply.into();
|
||||
let stored: f64 = *stored;
|
||||
(i, Dollars::from(destroyed * supply / stored))
|
||||
(i, Cents::from(destroyed * supply / stored))
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
@@ -3,16 +3,16 @@ use brk_types::Version;
|
||||
use vecdb::Database;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{indexes, internal::ComputedFromHeightLast};
|
||||
use crate::{indexes, internal::FiatFromHeightLast};
|
||||
|
||||
impl Vecs {
|
||||
pub(crate) fn forced_import(db: &Database, version: Version, indexes: &indexes::Vecs) -> Result<Self> {
|
||||
Ok(Self {
|
||||
thermo_cap: ComputedFromHeightLast::forced_import(db, "thermo_cap", version, indexes)?,
|
||||
investor_cap: ComputedFromHeightLast::forced_import(db, "investor_cap", version, indexes)?,
|
||||
vaulted_cap: ComputedFromHeightLast::forced_import(db, "vaulted_cap", version, indexes)?,
|
||||
active_cap: ComputedFromHeightLast::forced_import(db, "active_cap", version, indexes)?,
|
||||
cointime_cap: ComputedFromHeightLast::forced_import(db, "cointime_cap", version, indexes)?,
|
||||
thermo_cap: FiatFromHeightLast::forced_import(db, "thermo_cap", version, indexes)?,
|
||||
investor_cap: FiatFromHeightLast::forced_import(db, "investor_cap", version, indexes)?,
|
||||
vaulted_cap: FiatFromHeightLast::forced_import(db, "vaulted_cap", version, indexes)?,
|
||||
active_cap: FiatFromHeightLast::forced_import(db, "active_cap", version, indexes)?,
|
||||
cointime_cap: FiatFromHeightLast::forced_import(db, "cointime_cap", version, indexes)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::Dollars;
|
||||
use brk_types::Cents;
|
||||
use vecdb::{Rw, StorageMode};
|
||||
|
||||
use crate::internal::ComputedFromHeightLast;
|
||||
use crate::internal::FiatFromHeightLast;
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub thermo_cap: ComputedFromHeightLast<Dollars, M>,
|
||||
pub investor_cap: ComputedFromHeightLast<Dollars, M>,
|
||||
pub vaulted_cap: ComputedFromHeightLast<Dollars, M>,
|
||||
pub active_cap: ComputedFromHeightLast<Dollars, M>,
|
||||
pub cointime_cap: ComputedFromHeightLast<Dollars, M>,
|
||||
pub thermo_cap: FiatFromHeightLast<Cents, M>,
|
||||
pub investor_cap: FiatFromHeightLast<Cents, M>,
|
||||
pub vaulted_cap: FiatFromHeightLast<Cents, M>,
|
||||
pub active_cap: FiatFromHeightLast<Cents, M>,
|
||||
pub cointime_cap: FiatFromHeightLast<Cents, M>,
|
||||
}
|
||||
|
||||
@@ -74,10 +74,10 @@ impl Vecs {
|
||||
|
||||
self.true_market_mean.cents.height.compute_transform2(
|
||||
starting_indexes.height,
|
||||
&cap.investor_cap.height,
|
||||
&cap.investor_cap.cents.height,
|
||||
&supply.active_supply.btc.height,
|
||||
|(i, cap_dollars, supply_btc, ..)| {
|
||||
(i, Cents::from(f64::from(Cents::from(cap_dollars)) / f64::from(supply_btc)))
|
||||
|(i, cap_cents, supply_btc, ..)| {
|
||||
(i, Cents::from(f64::from(cap_cents) / f64::from(supply_btc)))
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
@@ -93,10 +93,10 @@ impl Vecs {
|
||||
// cointime_price = cointime_cap / circulating_supply
|
||||
self.cointime_price.cents.height.compute_transform2(
|
||||
starting_indexes.height,
|
||||
&cap.cointime_cap.height,
|
||||
&cap.cointime_cap.cents.height,
|
||||
circulating_supply,
|
||||
|(i, cap_dollars, supply_btc, ..)| {
|
||||
(i, Cents::from(f64::from(Cents::from(cap_dollars)) / f64::from(supply_btc)))
|
||||
|(i, cap_cents, supply_btc, ..)| {
|
||||
(i, Cents::from(f64::from(cap_cents) / f64::from(supply_btc)))
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
@@ -1091,8 +1091,9 @@ impl UTXOCohorts<Rw> {
|
||||
.unrealized
|
||||
.peak_regret_ext
|
||||
.peak_regret
|
||||
.cents
|
||||
.height
|
||||
.truncate_push(current_height, Dollars::ZERO)?;
|
||||
.truncate_push(current_height, Cents::ZERO)?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
@@ -1116,12 +1117,12 @@ impl UTXOCohorts<Rw> {
|
||||
}
|
||||
});
|
||||
|
||||
let regrets: [Dollars; 21] = ranges
|
||||
let regrets: [Cents; 21] = ranges
|
||||
.into_par_iter()
|
||||
.map(|(range_start, range_end)| {
|
||||
let effective_start = range_start.max(start_height);
|
||||
if effective_start >= range_end {
|
||||
return Dollars::ZERO;
|
||||
return Cents::ZERO;
|
||||
}
|
||||
|
||||
let mut regret: u128 = 0;
|
||||
@@ -1146,7 +1147,7 @@ impl UTXOCohorts<Rw> {
|
||||
};
|
||||
}
|
||||
|
||||
Cents::new((regret / Sats::ONE_BTC_U128) as u64).to_dollars()
|
||||
Cents::new((regret / Sats::ONE_BTC_U128) as u64)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.try_into()
|
||||
@@ -1158,6 +1159,7 @@ impl UTXOCohorts<Rw> {
|
||||
.unrealized
|
||||
.peak_regret_ext
|
||||
.peak_regret
|
||||
.cents
|
||||
.height
|
||||
.truncate_push(current_height, regret)?;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ impl AdjustedCohortMetrics {
|
||||
&self.supply.total.sats.height,
|
||||
height_to_market_cap,
|
||||
all_supply_sats,
|
||||
&self.unrealized.peak_regret_ext.peak_regret.height,
|
||||
&self.unrealized.peak_regret_ext.peak_regret.usd.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ impl AllCohortMetrics {
|
||||
&self.realized.base,
|
||||
&self.supply.total.sats.height,
|
||||
height_to_market_cap,
|
||||
&self.unrealized.peak_regret_ext.peak_regret.height,
|
||||
&self.unrealized.peak_regret_ext.peak_regret.usd.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ impl ExtendedCohortMetrics {
|
||||
height_to_market_cap,
|
||||
all_supply_sats,
|
||||
&self.supply.total.usd.height,
|
||||
&self.unrealized.peak_regret_ext.peak_regret.height,
|
||||
&self.unrealized.peak_regret_ext.peak_regret.usd.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ impl ExtendedAdjustedCohortMetrics {
|
||||
height_to_market_cap,
|
||||
all_supply_sats,
|
||||
&self.supply.total.usd.height,
|
||||
&self.unrealized.peak_regret_ext.peak_regret.height,
|
||||
&self.unrealized.peak_regret_ext.peak_regret.usd.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ impl PeakRegretCohortMetrics {
|
||||
&self.supply.total.sats.height,
|
||||
height_to_market_cap,
|
||||
all_supply_sats,
|
||||
&self.unrealized.peak_regret_ext.peak_regret.height,
|
||||
&self.unrealized.peak_regret_ext.peak_regret.usd.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
|
||||
@@ -109,11 +109,12 @@ pub trait CohortMetricsBase: Send + Sync {
|
||||
.collect();
|
||||
let values: Vec<_> = others
|
||||
.iter()
|
||||
.map(|o| &o.unrealized_base().net_sentiment.height)
|
||||
.map(|o| &o.unrealized_base().net_sentiment.cents.height)
|
||||
.collect();
|
||||
|
||||
self.unrealized_base_mut()
|
||||
.net_sentiment
|
||||
.cents
|
||||
.height
|
||||
.compute_weighted_average_of_others(starting_indexes.height, &weights, &values, exit)?;
|
||||
|
||||
@@ -133,11 +134,12 @@ pub trait CohortMetricsBase: Send + Sync {
|
||||
.collect();
|
||||
let values: Vec<_> = others
|
||||
.iter()
|
||||
.map(|o| &o.unrealized_base().net_sentiment.height)
|
||||
.map(|o| &o.unrealized_base().net_sentiment.cents.height)
|
||||
.collect();
|
||||
|
||||
self.unrealized_base_mut()
|
||||
.net_sentiment
|
||||
.cents
|
||||
.height
|
||||
.compute_weighted_average_of_others(starting_indexes.height, &weights, &values, exit)?;
|
||||
|
||||
|
||||
@@ -94,27 +94,27 @@ impl RelativeBase {
|
||||
)?;
|
||||
self.unrealized_profit_rel_to_market_cap
|
||||
.compute_binary::<Dollars, Dollars, PercentageDollarsF32>(
|
||||
max_from, &unrealized.unrealized_profit.height, market_cap, exit,
|
||||
max_from, &unrealized.unrealized_profit.usd.height, market_cap, exit,
|
||||
)?;
|
||||
self.unrealized_loss_rel_to_market_cap
|
||||
.compute_binary::<Dollars, Dollars, PercentageDollarsF32>(
|
||||
max_from, &unrealized.unrealized_loss.height, market_cap, exit,
|
||||
max_from, &unrealized.unrealized_loss.usd.height, market_cap, exit,
|
||||
)?;
|
||||
self.neg_unrealized_loss_rel_to_market_cap
|
||||
.compute_binary::<Dollars, Dollars, NegPercentageDollarsF32>(
|
||||
max_from, &unrealized.unrealized_loss.height, market_cap, exit,
|
||||
max_from, &unrealized.unrealized_loss.usd.height, market_cap, exit,
|
||||
)?;
|
||||
self.net_unrealized_pnl_rel_to_market_cap
|
||||
.compute_binary::<Dollars, Dollars, PercentageDollarsF32>(
|
||||
max_from, &unrealized.net_unrealized_pnl.height, market_cap, exit,
|
||||
max_from, &unrealized.net_unrealized_pnl.usd.height, market_cap, exit,
|
||||
)?;
|
||||
self.invested_capital_in_profit_pct
|
||||
.compute_binary::<Dollars, Dollars, PercentageDollarsF32>(
|
||||
max_from, &unrealized.invested_capital_in_profit.height, &realized.realized_cap.height, exit,
|
||||
max_from, &unrealized.invested_capital_in_profit.usd.height, &realized.realized_cap.height, exit,
|
||||
)?;
|
||||
self.invested_capital_in_loss_pct
|
||||
.compute_binary::<Dollars, Dollars, PercentageDollarsF32>(
|
||||
max_from, &unrealized.invested_capital_in_loss.height, &realized.realized_cap.height, exit,
|
||||
max_from, &unrealized.invested_capital_in_loss.usd.height, &realized.realized_cap.height, exit,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -69,19 +69,19 @@ impl RelativeExtendedOwnMarketCap {
|
||||
) -> Result<()> {
|
||||
self.unrealized_profit_rel_to_own_market_cap
|
||||
.compute_binary::<Dollars, Dollars, PercentageDollarsF32>(
|
||||
max_from, &unrealized.unrealized_profit.height, own_market_cap, exit,
|
||||
max_from, &unrealized.unrealized_profit.usd.height, own_market_cap, exit,
|
||||
)?;
|
||||
self.unrealized_loss_rel_to_own_market_cap
|
||||
.compute_binary::<Dollars, Dollars, PercentageDollarsF32>(
|
||||
max_from, &unrealized.unrealized_loss.height, own_market_cap, exit,
|
||||
max_from, &unrealized.unrealized_loss.usd.height, own_market_cap, exit,
|
||||
)?;
|
||||
self.neg_unrealized_loss_rel_to_own_market_cap
|
||||
.compute_binary::<Dollars, Dollars, NegPercentageDollarsF32>(
|
||||
max_from, &unrealized.unrealized_loss.height, own_market_cap, exit,
|
||||
max_from, &unrealized.unrealized_loss.usd.height, own_market_cap, exit,
|
||||
)?;
|
||||
self.net_unrealized_pnl_rel_to_own_market_cap
|
||||
.compute_binary::<Dollars, Dollars, PercentageDollarsF32>(
|
||||
max_from, &unrealized.net_unrealized_pnl.height, own_market_cap, exit,
|
||||
max_from, &unrealized.net_unrealized_pnl.usd.height, own_market_cap, exit,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -69,19 +69,19 @@ impl RelativeExtendedOwnPnl {
|
||||
) -> Result<()> {
|
||||
self.unrealized_profit_rel_to_own_total_unrealized_pnl
|
||||
.compute_binary::<Dollars, Dollars, PercentageDollarsF32>(
|
||||
max_from, &unrealized.unrealized_profit.height, &unrealized.total_unrealized_pnl.height, exit,
|
||||
max_from, &unrealized.unrealized_profit.usd.height, &unrealized.total_unrealized_pnl.usd.height, exit,
|
||||
)?;
|
||||
self.unrealized_loss_rel_to_own_total_unrealized_pnl
|
||||
.compute_binary::<Dollars, Dollars, PercentageDollarsF32>(
|
||||
max_from, &unrealized.unrealized_loss.height, &unrealized.total_unrealized_pnl.height, exit,
|
||||
max_from, &unrealized.unrealized_loss.usd.height, &unrealized.total_unrealized_pnl.usd.height, exit,
|
||||
)?;
|
||||
self.neg_unrealized_loss_rel_to_own_total_unrealized_pnl
|
||||
.compute_binary::<Dollars, Dollars, NegPercentageDollarsF32>(
|
||||
max_from, &unrealized.unrealized_loss.height, &unrealized.total_unrealized_pnl.height, exit,
|
||||
max_from, &unrealized.unrealized_loss.usd.height, &unrealized.total_unrealized_pnl.usd.height, exit,
|
||||
)?;
|
||||
self.net_unrealized_pnl_rel_to_own_total_unrealized_pnl
|
||||
.compute_binary::<Dollars, Dollars, PercentageDollarsF32>(
|
||||
max_from, &unrealized.net_unrealized_pnl.height, &unrealized.total_unrealized_pnl.height, exit,
|
||||
max_from, &unrealized.net_unrealized_pnl.usd.height, &unrealized.total_unrealized_pnl.usd.height, exit,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ impl RelativePeakRegret {
|
||||
&mut self,
|
||||
max_from: Height,
|
||||
peak_regret: &impl ReadableVec<Height, Dollars>,
|
||||
|
||||
market_cap: &impl ReadableVec<Height, Dollars>,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Cents, CentsSats, CentsSquaredSats, Dollars, Height, Version};
|
||||
use brk_types::{Cents, CentsSats, CentsSigned, CentsSquaredSats, Height, Version};
|
||||
use vecdb::{
|
||||
AnyStoredVec, AnyVec, BytesVec, Exit, ImportableVec, Negate, ReadableCloneableVec, ReadableVec,
|
||||
AnyStoredVec, AnyVec, BytesVec, Exit, ImportableVec, ReadableCloneableVec, ReadableVec,
|
||||
Rw, StorageMode, WritableVec,
|
||||
};
|
||||
|
||||
@@ -10,11 +10,14 @@ use crate::{
|
||||
ComputeIndexes,
|
||||
distribution::state::UnrealizedState,
|
||||
internal::{
|
||||
ComputedFromHeightLast, LazyFromHeightLast, ValueFromHeightLast,
|
||||
CentsSubtractToCentsSigned, FiatFromHeightLast, LazyFromHeightLast, NegCentsUnsignedToDollars,
|
||||
ValueFromHeightLast,
|
||||
},
|
||||
prices,
|
||||
};
|
||||
|
||||
use brk_types::Dollars;
|
||||
|
||||
use crate::distribution::metrics::ImportConfig;
|
||||
|
||||
/// Base unrealized profit/loss metrics (always computed).
|
||||
@@ -25,12 +28,12 @@ pub struct UnrealizedBase<M: StorageMode = Rw> {
|
||||
pub supply_in_loss: ValueFromHeightLast<M>,
|
||||
|
||||
// === Unrealized Profit/Loss ===
|
||||
pub unrealized_profit: ComputedFromHeightLast<Dollars, M>,
|
||||
pub unrealized_loss: ComputedFromHeightLast<Dollars, M>,
|
||||
pub unrealized_profit: FiatFromHeightLast<Cents, M>,
|
||||
pub unrealized_loss: FiatFromHeightLast<Cents, M>,
|
||||
|
||||
// === Invested Capital in Profit/Loss ===
|
||||
pub invested_capital_in_profit: ComputedFromHeightLast<Dollars, M>,
|
||||
pub invested_capital_in_loss: ComputedFromHeightLast<Dollars, M>,
|
||||
pub invested_capital_in_profit: FiatFromHeightLast<Cents, M>,
|
||||
pub invested_capital_in_loss: FiatFromHeightLast<Cents, M>,
|
||||
|
||||
// === Raw values for precise aggregation (used to compute pain/greed indices) ===
|
||||
pub invested_capital_in_profit_raw: M::Stored<BytesVec<Height, CentsSats>>,
|
||||
@@ -39,16 +42,16 @@ pub struct UnrealizedBase<M: StorageMode = Rw> {
|
||||
pub investor_cap_in_loss_raw: M::Stored<BytesVec<Height, CentsSquaredSats>>,
|
||||
|
||||
// === Pain/Greed Indices ===
|
||||
pub pain_index: ComputedFromHeightLast<Dollars, M>,
|
||||
pub greed_index: ComputedFromHeightLast<Dollars, M>,
|
||||
pub net_sentiment: ComputedFromHeightLast<Dollars, M>,
|
||||
pub pain_index: FiatFromHeightLast<Cents, M>,
|
||||
pub greed_index: FiatFromHeightLast<Cents, M>,
|
||||
pub net_sentiment: FiatFromHeightLast<CentsSigned, M>,
|
||||
|
||||
// === Negated ===
|
||||
pub neg_unrealized_loss: LazyFromHeightLast<Dollars>,
|
||||
pub neg_unrealized_loss: LazyFromHeightLast<Dollars, Cents>,
|
||||
|
||||
// === Net and Total ===
|
||||
pub net_unrealized_pnl: ComputedFromHeightLast<Dollars, M>,
|
||||
pub total_unrealized_pnl: ComputedFromHeightLast<Dollars, M>,
|
||||
pub net_unrealized_pnl: FiatFromHeightLast<CentsSigned, M>,
|
||||
pub total_unrealized_pnl: FiatFromHeightLast<Cents, M>,
|
||||
}
|
||||
|
||||
impl UnrealizedBase {
|
||||
@@ -66,26 +69,26 @@ impl UnrealizedBase {
|
||||
cfg.indexes,
|
||||
)?;
|
||||
|
||||
let unrealized_profit = ComputedFromHeightLast::forced_import(
|
||||
let unrealized_profit = FiatFromHeightLast::forced_import(
|
||||
cfg.db,
|
||||
&cfg.name("unrealized_profit"),
|
||||
cfg.version,
|
||||
cfg.indexes,
|
||||
)?;
|
||||
let unrealized_loss = ComputedFromHeightLast::forced_import(
|
||||
let unrealized_loss = FiatFromHeightLast::forced_import(
|
||||
cfg.db,
|
||||
&cfg.name("unrealized_loss"),
|
||||
cfg.version,
|
||||
cfg.indexes,
|
||||
)?;
|
||||
|
||||
let invested_capital_in_profit = ComputedFromHeightLast::forced_import(
|
||||
let invested_capital_in_profit = FiatFromHeightLast::forced_import(
|
||||
cfg.db,
|
||||
&cfg.name("invested_capital_in_profit"),
|
||||
cfg.version,
|
||||
cfg.indexes,
|
||||
)?;
|
||||
let invested_capital_in_loss = ComputedFromHeightLast::forced_import(
|
||||
let invested_capital_in_loss = FiatFromHeightLast::forced_import(
|
||||
cfg.db,
|
||||
&cfg.name("invested_capital_in_loss"),
|
||||
cfg.version,
|
||||
@@ -113,39 +116,39 @@ impl UnrealizedBase {
|
||||
cfg.version,
|
||||
)?;
|
||||
|
||||
let pain_index = ComputedFromHeightLast::forced_import(
|
||||
let pain_index = FiatFromHeightLast::forced_import(
|
||||
cfg.db,
|
||||
&cfg.name("pain_index"),
|
||||
cfg.version,
|
||||
cfg.indexes,
|
||||
)?;
|
||||
let greed_index = ComputedFromHeightLast::forced_import(
|
||||
let greed_index = FiatFromHeightLast::forced_import(
|
||||
cfg.db,
|
||||
&cfg.name("greed_index"),
|
||||
cfg.version,
|
||||
cfg.indexes,
|
||||
)?;
|
||||
let net_sentiment = ComputedFromHeightLast::forced_import(
|
||||
let net_sentiment = FiatFromHeightLast::forced_import(
|
||||
cfg.db,
|
||||
&cfg.name("net_sentiment"),
|
||||
cfg.version + Version::ONE,
|
||||
cfg.indexes,
|
||||
)?;
|
||||
|
||||
let neg_unrealized_loss = LazyFromHeightLast::from_computed::<Negate>(
|
||||
let neg_unrealized_loss = LazyFromHeightLast::from_computed::<NegCentsUnsignedToDollars>(
|
||||
&cfg.name("neg_unrealized_loss"),
|
||||
cfg.version,
|
||||
unrealized_loss.height.read_only_boxed_clone(),
|
||||
&unrealized_loss,
|
||||
unrealized_loss.cents.height.read_only_boxed_clone(),
|
||||
&unrealized_loss.cents,
|
||||
);
|
||||
|
||||
let net_unrealized_pnl = ComputedFromHeightLast::forced_import(
|
||||
let net_unrealized_pnl = FiatFromHeightLast::forced_import(
|
||||
cfg.db,
|
||||
&cfg.name("net_unrealized_pnl"),
|
||||
cfg.version,
|
||||
cfg.indexes,
|
||||
)?;
|
||||
let total_unrealized_pnl = ComputedFromHeightLast::forced_import(
|
||||
let total_unrealized_pnl = FiatFromHeightLast::forced_import(
|
||||
cfg.db,
|
||||
&cfg.name("total_unrealized_pnl"),
|
||||
cfg.version,
|
||||
@@ -178,10 +181,10 @@ impl UnrealizedBase {
|
||||
.height
|
||||
.len()
|
||||
.min(self.supply_in_loss.sats.height.len())
|
||||
.min(self.unrealized_profit.height.len())
|
||||
.min(self.unrealized_loss.height.len())
|
||||
.min(self.invested_capital_in_profit.height.len())
|
||||
.min(self.invested_capital_in_loss.height.len())
|
||||
.min(self.unrealized_profit.cents.height.len())
|
||||
.min(self.unrealized_loss.cents.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())
|
||||
@@ -202,17 +205,21 @@ impl UnrealizedBase {
|
||||
.height
|
||||
.truncate_push(height, height_state.supply_in_loss)?;
|
||||
self.unrealized_profit
|
||||
.cents
|
||||
.height
|
||||
.truncate_push(height, height_state.unrealized_profit.to_dollars())?;
|
||||
.truncate_push(height, height_state.unrealized_profit)?;
|
||||
self.unrealized_loss
|
||||
.cents
|
||||
.height
|
||||
.truncate_push(height, height_state.unrealized_loss.to_dollars())?;
|
||||
.truncate_push(height, height_state.unrealized_loss)?;
|
||||
self.invested_capital_in_profit
|
||||
.cents
|
||||
.height
|
||||
.truncate_push(height, height_state.invested_capital_in_profit.to_dollars())?;
|
||||
.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.to_dollars())?;
|
||||
.truncate_push(height, height_state.invested_capital_in_loss)?;
|
||||
|
||||
self.invested_capital_in_profit_raw.truncate_push(
|
||||
height,
|
||||
@@ -240,10 +247,10 @@ impl UnrealizedBase {
|
||||
&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.height,
|
||||
&mut self.unrealized_loss.height,
|
||||
&mut self.invested_capital_in_profit.height,
|
||||
&mut self.invested_capital_in_loss.height,
|
||||
&mut self.unrealized_profit.cents.height,
|
||||
&mut self.unrealized_loss.cents.height,
|
||||
&mut self.invested_capital_in_profit.cents.height,
|
||||
&mut self.invested_capital_in_loss.cents.height,
|
||||
&mut self.invested_capital_in_profit_raw as &mut dyn AnyStoredVec,
|
||||
&mut self.invested_capital_in_loss_raw as &mut dyn AnyStoredVec,
|
||||
&mut self.investor_cap_in_profit_raw as &mut dyn AnyStoredVec,
|
||||
@@ -280,40 +287,43 @@ impl UnrealizedBase {
|
||||
exit,
|
||||
)?;
|
||||
self.unrealized_profit
|
||||
.cents
|
||||
.height
|
||||
.compute_sum_of_others(
|
||||
starting_indexes.height,
|
||||
&others
|
||||
.iter()
|
||||
.map(|v| &v.unrealized_profit.height)
|
||||
.map(|v| &v.unrealized_profit.cents.height)
|
||||
.collect::<Vec<_>>(),
|
||||
exit,
|
||||
)?;
|
||||
self.unrealized_loss.height.compute_sum_of_others(
|
||||
self.unrealized_loss.cents.height.compute_sum_of_others(
|
||||
starting_indexes.height,
|
||||
&others
|
||||
.iter()
|
||||
.map(|v| &v.unrealized_loss.height)
|
||||
.map(|v| &v.unrealized_loss.cents.height)
|
||||
.collect::<Vec<_>>(),
|
||||
exit,
|
||||
)?;
|
||||
self.invested_capital_in_profit
|
||||
.cents
|
||||
.height
|
||||
.compute_sum_of_others(
|
||||
starting_indexes.height,
|
||||
&others
|
||||
.iter()
|
||||
.map(|v| &v.invested_capital_in_profit.height)
|
||||
.map(|v| &v.invested_capital_in_profit.cents.height)
|
||||
.collect::<Vec<_>>(),
|
||||
exit,
|
||||
)?;
|
||||
self.invested_capital_in_loss
|
||||
.cents
|
||||
.height
|
||||
.compute_sum_of_others(
|
||||
starting_indexes.height,
|
||||
&others
|
||||
.iter()
|
||||
.map(|v| &v.invested_capital_in_loss.height)
|
||||
.map(|v| &v.invested_capital_in_loss.cents.height)
|
||||
.collect::<Vec<_>>(),
|
||||
exit,
|
||||
)?;
|
||||
@@ -386,55 +396,58 @@ impl UnrealizedBase {
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
// Pain index: investor_price_of_losers - spot
|
||||
self.pain_index.height.compute_transform3(
|
||||
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, Dollars::ZERO);
|
||||
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).to_dollars(),
|
||||
Cents::new((investor_price_losers - spot_u128) as u64),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Greed index: spot - investor_price_of_winners
|
||||
self.greed_index.height.compute_transform3(
|
||||
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, Dollars::ZERO);
|
||||
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).to_dollars(),
|
||||
Cents::new((spot_u128 - investor_price_winners) as u64),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.net_unrealized_pnl.height.compute_subtract(
|
||||
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,
|
||||
)?;
|
||||
self.total_unrealized_pnl.cents.height.compute_add(
|
||||
starting_indexes.height,
|
||||
&self.unrealized_profit.height,
|
||||
&self.unrealized_loss.height,
|
||||
exit,
|
||||
)?;
|
||||
self.total_unrealized_pnl.height.compute_add(
|
||||
starting_indexes.height,
|
||||
&self.unrealized_profit.height,
|
||||
&self.unrealized_loss.height,
|
||||
&self.unrealized_profit.cents.height,
|
||||
&self.unrealized_loss.cents.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
@@ -447,11 +460,15 @@ impl UnrealizedBase {
|
||||
starting_indexes: &ComputeIndexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
Ok(self.net_sentiment.height.compute_subtract(
|
||||
starting_indexes.height,
|
||||
&self.greed_index.height,
|
||||
&self.pain_index.height,
|
||||
exit,
|
||||
)?)
|
||||
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,9 +1,9 @@
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::Dollars;
|
||||
use brk_types::Cents;
|
||||
use vecdb::{AnyStoredVec, Exit, Rw, StorageMode};
|
||||
|
||||
use crate::{ComputeIndexes, internal::ComputedFromHeightLast};
|
||||
use crate::{ComputeIndexes, internal::FiatFromHeightLast};
|
||||
|
||||
use crate::distribution::metrics::ImportConfig;
|
||||
|
||||
@@ -11,13 +11,13 @@ use crate::distribution::metrics::ImportConfig;
|
||||
#[derive(Traversable)]
|
||||
pub struct UnrealizedPeakRegret<M: StorageMode = Rw> {
|
||||
/// Unrealized peak regret: sum of (peak_price - reference_price) x supply
|
||||
pub peak_regret: ComputedFromHeightLast<Dollars, M>,
|
||||
pub peak_regret: FiatFromHeightLast<Cents, M>,
|
||||
}
|
||||
|
||||
impl UnrealizedPeakRegret {
|
||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||
Ok(Self {
|
||||
peak_regret: ComputedFromHeightLast::forced_import(
|
||||
peak_regret: FiatFromHeightLast::forced_import(
|
||||
cfg.db,
|
||||
&cfg.name("unrealized_peak_regret"),
|
||||
cfg.version,
|
||||
@@ -27,7 +27,7 @@ impl UnrealizedPeakRegret {
|
||||
}
|
||||
|
||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
vec![&mut self.peak_regret.height]
|
||||
vec![&mut self.peak_regret.cents.height]
|
||||
}
|
||||
|
||||
pub(crate) fn compute_from_stateful(
|
||||
@@ -36,11 +36,11 @@ impl UnrealizedPeakRegret {
|
||||
others: &[&Self],
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.peak_regret.height.compute_sum_of_others(
|
||||
self.peak_regret.cents.height.compute_sum_of_others(
|
||||
starting_indexes.height,
|
||||
&others
|
||||
.iter()
|
||||
.map(|v| &v.peak_regret.height)
|
||||
.map(|v| &v.peak_regret.cents.height)
|
||||
.collect::<Vec<_>>(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Cents, CentsSigned, Dollars, Version};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{Database, ReadableCloneableVec, Rw, StorageMode, UnaryTransform};
|
||||
|
||||
use super::{ComputedFromHeightLast, LazyFromHeightLast};
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{CentsSignedToDollars, CentsUnsignedToDollars, NumericValue},
|
||||
};
|
||||
|
||||
/// Trait that associates a cents type with its transform to Dollars.
|
||||
pub trait CentsType: NumericValue + JsonSchema {
|
||||
type ToDollars: UnaryTransform<Self, Dollars>;
|
||||
}
|
||||
|
||||
impl CentsType for Cents {
|
||||
type ToDollars = CentsUnsignedToDollars;
|
||||
}
|
||||
|
||||
impl CentsType for CentsSigned {
|
||||
type ToDollars = CentsSignedToDollars;
|
||||
}
|
||||
|
||||
/// Height-indexed fiat monetary value: cents (eager, integer) + usd (lazy, float).
|
||||
/// Generic over `C` to support both `Cents` (unsigned) and `CentsSigned` (signed).
|
||||
#[derive(Traversable)]
|
||||
pub struct FiatFromHeightLast<C: CentsType, M: StorageMode = Rw> {
|
||||
pub cents: ComputedFromHeightLast<C, M>,
|
||||
pub usd: LazyFromHeightLast<Dollars, C>,
|
||||
}
|
||||
|
||||
impl<C: CentsType> FiatFromHeightLast<C> {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
let cents = ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
&format!("{name}_cents"),
|
||||
version,
|
||||
indexes,
|
||||
)?;
|
||||
let usd = LazyFromHeightLast::from_computed::<C::ToDollars>(
|
||||
&format!("{name}_usd"),
|
||||
version,
|
||||
cents.height.read_only_boxed_clone(),
|
||||
¢s,
|
||||
);
|
||||
Ok(Self { cents, usd })
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
mod by_unit;
|
||||
mod constant;
|
||||
mod cumulative;
|
||||
mod fiat;
|
||||
mod cumulative_full;
|
||||
mod cumulative_sum;
|
||||
mod distribution;
|
||||
@@ -23,6 +24,7 @@ pub use by_unit::*;
|
||||
pub use constant::*;
|
||||
pub use cumulative::*;
|
||||
pub use cumulative_full::*;
|
||||
pub use fiat::*;
|
||||
pub use cumulative_sum::*;
|
||||
pub use distribution::*;
|
||||
pub use full::*;
|
||||
|
||||
@@ -32,12 +32,8 @@ impl Price<ComputedFromHeightLast<Cents>> {
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
let cents = ComputedFromHeightLast::forced_import(
|
||||
db,
|
||||
&format!("{name}_cents"),
|
||||
version,
|
||||
indexes,
|
||||
)?;
|
||||
let cents =
|
||||
ComputedFromHeightLast::forced_import(db, &format!("{name}_cents"), version, indexes)?;
|
||||
let usd = LazyFromHeightLast::from_computed::<CentsUnsignedToDollars>(
|
||||
&format!("{name}_usd"),
|
||||
version,
|
||||
@@ -51,26 +47,6 @@ impl Price<ComputedFromHeightLast<Cents>> {
|
||||
);
|
||||
Ok(Self { cents, usd, sats })
|
||||
}
|
||||
|
||||
/// Wrap an already-imported ComputedFromHeightLast<Cents> with lazy USD + sats.
|
||||
pub(crate) fn from_cents(
|
||||
name: &str,
|
||||
version: Version,
|
||||
cents: ComputedFromHeightLast<Cents>,
|
||||
) -> Self {
|
||||
let usd = LazyFromHeightLast::from_computed::<CentsUnsignedToDollars>(
|
||||
&format!("{name}_usd"),
|
||||
version,
|
||||
cents.height.read_only_boxed_clone(),
|
||||
¢s,
|
||||
);
|
||||
let sats = LazyFromHeightLast::from_lazy::<DollarsToSatsFract, Cents>(
|
||||
&format!("{name}_sats"),
|
||||
version,
|
||||
&usd,
|
||||
);
|
||||
Self { cents, usd, sats }
|
||||
}
|
||||
}
|
||||
|
||||
impl<ST> Price<LazyFromHeightLast<Cents, ST>>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
use brk_types::{Cents, CentsSigned};
|
||||
use vecdb::BinaryTransform;
|
||||
|
||||
/// (Cents, Cents) -> CentsSigned (a - b)
|
||||
/// Produces a signed result from two unsigned inputs.
|
||||
pub struct CentsSubtractToCentsSigned;
|
||||
|
||||
impl BinaryTransform<Cents, Cents, CentsSigned> for CentsSubtractToCentsSigned {
|
||||
#[inline(always)]
|
||||
fn apply(a: Cents, b: Cents) -> CentsSigned {
|
||||
CentsSigned::from(a.inner() as i64 - b.inner() as i64)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
mod block_count_target;
|
||||
mod cents_plus;
|
||||
mod cents_signed_to_dollars;
|
||||
mod cents_subtract_to_cents_signed;
|
||||
mod cents_times_tenths;
|
||||
mod cents_to_dollars;
|
||||
mod cents_to_sats;
|
||||
@@ -42,6 +43,7 @@ mod volatility_sqrt7;
|
||||
pub use block_count_target::*;
|
||||
pub use cents_plus::*;
|
||||
pub use cents_signed_to_dollars::*;
|
||||
pub use cents_subtract_to_cents_signed::*;
|
||||
pub use cents_times_tenths::*;
|
||||
pub use cents_to_dollars::*;
|
||||
pub use cents_to_sats::*;
|
||||
|
||||
@@ -28,7 +28,7 @@ impl Vecs {
|
||||
self.puell_multiple.height.compute_divide(
|
||||
starting_indexes.height,
|
||||
&rewards.subsidy.base.usd.height,
|
||||
&rewards.subsidy_usd_1y_sma.height,
|
||||
&rewards.subsidy_usd_1y_sma.usd.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
|
||||
@@ -190,10 +190,10 @@ impl Vecs {
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.subsidy_usd_1y_sma.height.compute_rolling_average(
|
||||
self.subsidy_usd_1y_sma.cents.height.compute_rolling_average(
|
||||
starting_indexes.height,
|
||||
&count_vecs.height_1y_ago,
|
||||
&self.subsidy.base.usd.height,
|
||||
&self.subsidy.base.cents.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use super::Vecs;
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
ComputedFromHeightLast, ValueFromHeightFull,
|
||||
ComputedFromHeightLast, FiatFromHeightLast, ValueFromHeightFull,
|
||||
ValueFromHeightSumCumulative,
|
||||
},
|
||||
};
|
||||
@@ -87,7 +87,7 @@ impl Vecs {
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
subsidy_usd_1y_sma: ComputedFromHeightLast::forced_import(
|
||||
subsidy_usd_1y_sma: FiatFromHeightLast::forced_import(
|
||||
db,
|
||||
"subsidy_usd_1y_sma",
|
||||
version,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Dollars, StoredF32};
|
||||
use brk_types::{Cents, StoredF32};
|
||||
use vecdb::{Rw, StorageMode};
|
||||
|
||||
use crate::internal::{
|
||||
ComputedFromHeightLast, ValueFromHeightFull,
|
||||
ComputedFromHeightLast, FiatFromHeightLast, ValueFromHeightFull,
|
||||
ValueFromHeightSumCumulative,
|
||||
};
|
||||
|
||||
@@ -24,5 +24,5 @@ pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub subsidy_dominance_7d: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub subsidy_dominance_30d: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub subsidy_dominance_1y: ComputedFromHeightLast<StoredF32, M>,
|
||||
pub subsidy_usd_1y_sma: ComputedFromHeightLast<Dollars, M>,
|
||||
pub subsidy_usd_1y_sma: FiatFromHeightLast<Cents, M>,
|
||||
}
|
||||
|
||||
@@ -3,14 +3,13 @@ use std::path::Path;
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Cents, Version};
|
||||
use vecdb::{Database, ReadableCloneableVec, PAGE_SIZE};
|
||||
use vecdb::{Database, PAGE_SIZE};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
distribution, indexes,
|
||||
internal::{
|
||||
ComputedFromHeightLast, DollarsIdentity,
|
||||
LazyFromHeightLast, LazyValueFromHeightLast,
|
||||
ComputedFromHeightLast, DollarsIdentity, LazyFromHeightLast, LazyValueFromHeightLast,
|
||||
SatsIdentity, SatsToBitcoin,
|
||||
},
|
||||
};
|
||||
@@ -31,11 +30,11 @@ impl Vecs {
|
||||
let supply_metrics = &distribution.utxo_cohorts.all.metrics.supply;
|
||||
|
||||
// Circulating supply - lazy refs to distribution
|
||||
let circulating = LazyValueFromHeightLast::from_block_source::<SatsIdentity, SatsToBitcoin, DollarsIdentity>(
|
||||
"circulating_supply",
|
||||
&supply_metrics.total,
|
||||
version,
|
||||
);
|
||||
let circulating = LazyValueFromHeightLast::from_block_source::<
|
||||
SatsIdentity,
|
||||
SatsToBitcoin,
|
||||
DollarsIdentity,
|
||||
>("circulating_supply", &supply_metrics.total, version);
|
||||
|
||||
// Burned/unspendable supply - computed from scripts
|
||||
let burned = super::burned::Vecs::forced_import(&db, version, indexes)?;
|
||||
@@ -45,8 +44,7 @@ impl Vecs {
|
||||
ComputedFromHeightLast::forced_import(&db, "inflation_rate", version, indexes)?;
|
||||
|
||||
// Velocity
|
||||
let velocity =
|
||||
super::velocity::Vecs::forced_import(&db, version, indexes)?;
|
||||
let velocity = super::velocity::Vecs::forced_import(&db, version, indexes)?;
|
||||
|
||||
// Market cap - lazy identity from distribution supply in USD
|
||||
let market_cap = LazyFromHeightLast::from_lazy::<DollarsIdentity, Cents>(
|
||||
|
||||
Reference in New Issue
Block a user