global: snapshot

This commit is contained in:
nym21
2026-03-14 15:53:40 +01:00
parent f705cc04a9
commit 9d365f4bbb
18 changed files with 456 additions and 516 deletions
+117 -119
View File
@@ -1915,28 +1915,6 @@ impl BtcCentsRelSatsUsdPattern2 {
}
}
/// Pattern struct for repeated tree structure.
pub struct CoindaysCoinyearsDormancySentVelocityPattern {
pub coindays_destroyed: BaseCumulativeSumPattern<StoredF64>,
pub coinyears_destroyed: MetricPattern1<StoredF64>,
pub dormancy: MetricPattern1<StoredF32>,
pub sent: BaseCumulativeInSumPattern,
pub velocity: MetricPattern1<StoredF32>,
}
impl CoindaysCoinyearsDormancySentVelocityPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
coindays_destroyed: BaseCumulativeSumPattern::new(client.clone(), _m(&acc, "coindays_destroyed")),
coinyears_destroyed: MetricPattern1::new(client.clone(), _m(&acc, "coinyears_destroyed")),
dormancy: MetricPattern1::new(client.clone(), _m(&acc, "dormancy")),
sent: BaseCumulativeInSumPattern::new(client.clone(), _m(&acc, "sent")),
velocity: MetricPattern1::new(client.clone(), _m(&acc, "velocity")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct DeltaHalfInTotalPattern2 {
pub delta: ChangeRatePattern,
@@ -2327,6 +2305,26 @@ impl CentsRelUsdPattern2 {
}
}
/// Pattern struct for repeated tree structure.
pub struct CoindaysCoinyearsDormancySentPattern {
pub coindays_destroyed: BaseCumulativeSumPattern<StoredF64>,
pub coinyears_destroyed: MetricPattern1<StoredF64>,
pub dormancy: MetricPattern1<StoredF32>,
pub sent: BaseCumulativeInSumPattern,
}
impl CoindaysCoinyearsDormancySentPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
coindays_destroyed: BaseCumulativeSumPattern::new(client.clone(), _m(&acc, "coindays_destroyed")),
coinyears_destroyed: MetricPattern1::new(client.clone(), _m(&acc, "coinyears_destroyed")),
dormancy: MetricPattern1::new(client.clone(), _m(&acc, "dormancy")),
sent: BaseCumulativeInSumPattern::new(client.clone(), _m(&acc, "sent")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct LossNetNuplProfitPattern {
pub loss: BaseCumulativeNegativeSumPattern,
@@ -3122,9 +3120,9 @@ pub struct MetricsTree_Blocks {
pub count: MetricsTree_Blocks_Count,
pub lookback: MetricsTree_Blocks_Lookback,
pub interval: _1m1w1y24hHeightPattern<Timestamp>,
pub halving: MetricsTree_Blocks_Halving,
pub vbytes: AverageBaseCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern,
pub fullness: MetricsTree_Blocks_Fullness,
pub halving: MetricsTree_Blocks_Halving,
}
impl MetricsTree_Blocks {
@@ -3138,9 +3136,9 @@ impl MetricsTree_Blocks {
count: MetricsTree_Blocks_Count::new(client.clone(), format!("{base_path}_count")),
lookback: MetricsTree_Blocks_Lookback::new(client.clone(), format!("{base_path}_lookback")),
interval: _1m1w1y24hHeightPattern::new(client.clone(), "block_interval".to_string()),
halving: MetricsTree_Blocks_Halving::new(client.clone(), format!("{base_path}_halving")),
vbytes: AverageBaseCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern::new(client.clone(), "block_vbytes".to_string()),
fullness: MetricsTree_Blocks_Fullness::new(client.clone(), format!("{base_path}_fullness")),
halving: MetricsTree_Blocks_Halving::new(client.clone(), format!("{base_path}_halving")),
}
}
}
@@ -3363,23 +3361,6 @@ impl MetricsTree_Blocks_Lookback {
}
}
/// Metrics tree node.
pub struct MetricsTree_Blocks_Halving {
pub epoch: MetricPattern1<Halving>,
pub blocks_before_next: MetricPattern1<StoredU32>,
pub days_before_next: MetricPattern1<StoredF32>,
}
impl MetricsTree_Blocks_Halving {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
epoch: MetricPattern1::new(client.clone(), "halving_epoch".to_string()),
blocks_before_next: MetricPattern1::new(client.clone(), "blocks_before_next_halving".to_string()),
days_before_next: MetricPattern1::new(client.clone(), "days_before_next_halving".to_string()),
}
}
}
/// Metrics tree node.
pub struct MetricsTree_Blocks_Fullness {
pub bps: _1m1w1y24hHeightPattern<BasisPoints16>,
@@ -3397,6 +3378,23 @@ impl MetricsTree_Blocks_Fullness {
}
}
/// Metrics tree node.
pub struct MetricsTree_Blocks_Halving {
pub epoch: MetricPattern1<Halving>,
pub blocks_before_next: MetricPattern1<StoredU32>,
pub days_before_next: MetricPattern1<StoredF32>,
}
impl MetricsTree_Blocks_Halving {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
epoch: MetricPattern1::new(client.clone(), "halving_epoch".to_string()),
blocks_before_next: MetricPattern1::new(client.clone(), "blocks_before_next_halving".to_string()),
days_before_next: MetricPattern1::new(client.clone(), "days_before_next_halving".to_string()),
}
}
}
/// Metrics tree node.
pub struct MetricsTree_Transactions {
pub raw: MetricsTree_Transactions_Raw,
@@ -6423,6 +6421,7 @@ impl MetricsTree_Prices_Spot {
/// Metrics tree node.
pub struct MetricsTree_Supply {
pub state: MetricPattern18<SupplyState>,
pub circulating: BtcCentsSatsUsdPattern,
pub burned: MetricsTree_Supply_Burned,
pub inflation_rate: BpsPercentRatioPattern,
@@ -6430,12 +6429,12 @@ pub struct MetricsTree_Supply {
pub market_cap: CentsDeltaUsdPattern,
pub market_minus_realized_cap_growth_rate: _1m1w1y24hPattern<BasisPointsSigned32>,
pub hodled_or_lost: BtcCentsSatsUsdPattern,
pub state: MetricPattern18<SupplyState>,
}
impl MetricsTree_Supply {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
state: MetricPattern18::new(client.clone(), "supply_state".to_string()),
circulating: BtcCentsSatsUsdPattern::new(client.clone(), "circulating_supply".to_string()),
burned: MetricsTree_Supply_Burned::new(client.clone(), format!("{base_path}_burned")),
inflation_rate: BpsPercentRatioPattern::new(client.clone(), "inflation_rate".to_string()),
@@ -6443,7 +6442,6 @@ impl MetricsTree_Supply {
market_cap: CentsDeltaUsdPattern::new(client.clone(), "market_cap".to_string()),
market_minus_realized_cap_growth_rate: _1m1w1y24hPattern::new(client.clone(), "market_minus_realized_cap_growth_rate".to_string()),
hodled_or_lost: BtcCentsSatsUsdPattern::new(client.clone(), "hodled_or_lost_coins".to_string()),
state: MetricPattern18::new(client.clone(), "supply_state".to_string()),
}
}
}
@@ -6465,15 +6463,15 @@ impl MetricsTree_Supply_Burned {
/// Metrics tree node.
pub struct MetricsTree_Supply_Velocity {
pub btc: MetricPattern1<StoredF64>,
pub usd: MetricPattern1<StoredF64>,
pub native: MetricPattern1<StoredF64>,
pub fiat: MetricPattern1<StoredF64>,
}
impl MetricsTree_Supply_Velocity {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
btc: MetricPattern1::new(client.clone(), "velocity_btc".to_string()),
usd: MetricPattern1::new(client.clone(), "velocity_usd".to_string()),
native: MetricPattern1::new(client.clone(), "velocity".to_string()),
fiat: MetricPattern1::new(client.clone(), "velocity_fiat".to_string()),
}
}
}
@@ -6536,7 +6534,7 @@ impl MetricsTree_Cohorts_Utxo {
pub struct MetricsTree_Cohorts_Utxo_All {
pub supply: MetricsTree_Cohorts_Utxo_All_Supply,
pub outputs: UnspentPattern,
pub activity: CoindaysCoinyearsDormancySentVelocityPattern,
pub activity: CoindaysCoinyearsDormancySentPattern,
pub realized: CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern,
pub cost_basis: InvestedMaxMinPercentilesSupplyPattern,
pub unrealized: MetricsTree_Cohorts_Utxo_All_Unrealized,
@@ -6547,7 +6545,7 @@ impl MetricsTree_Cohorts_Utxo_All {
Self {
supply: MetricsTree_Cohorts_Utxo_All_Supply::new(client.clone(), format!("{base_path}_supply")),
outputs: UnspentPattern::new(client.clone(), "utxo_count".to_string()),
activity: CoindaysCoinyearsDormancySentVelocityPattern::new(client.clone(), "".to_string()),
activity: CoindaysCoinyearsDormancySentPattern::new(client.clone(), "".to_string()),
realized: CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern::new(client.clone(), "".to_string()),
cost_basis: InvestedMaxMinPercentilesSupplyPattern::new(client.clone(), "".to_string()),
unrealized: MetricsTree_Cohorts_Utxo_All_Unrealized::new(client.clone(), format!("{base_path}_unrealized")),
@@ -6557,86 +6555,46 @@ impl MetricsTree_Cohorts_Utxo_All {
/// Metrics tree node.
pub struct MetricsTree_Cohorts_Utxo_All_Supply {
pub in_profit: BtcCentsRelSatsUsdPattern2,
pub in_loss: BtcCentsRelSatsUsdPattern2,
pub total: BtcCentsSatsUsdPattern,
pub half: BtcCentsSatsUsdPattern,
pub delta: ChangeRatePattern,
pub in_profit: BtcCentsRelSatsUsdPattern2,
pub in_loss: BtcCentsRelSatsUsdPattern2,
}
impl MetricsTree_Cohorts_Utxo_All_Supply {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
in_profit: BtcCentsRelSatsUsdPattern2::new(client.clone(), "supply_in_profit".to_string()),
in_loss: BtcCentsRelSatsUsdPattern2::new(client.clone(), "supply_in_loss".to_string()),
total: BtcCentsSatsUsdPattern::new(client.clone(), "supply".to_string()),
half: BtcCentsSatsUsdPattern::new(client.clone(), "supply_half".to_string()),
delta: ChangeRatePattern::new(client.clone(), "supply_delta".to_string()),
in_profit: BtcCentsRelSatsUsdPattern2::new(client.clone(), "supply_in_profit".to_string()),
in_loss: BtcCentsRelSatsUsdPattern2::new(client.clone(), "supply_in_loss".to_string()),
}
}
}
/// Metrics tree node.
pub struct MetricsTree_Cohorts_Utxo_All_Unrealized {
pub nupl: BpsRatioPattern,
pub profit: MetricsTree_Cohorts_Utxo_All_Unrealized_Profit,
pub loss: MetricsTree_Cohorts_Utxo_All_Unrealized_Loss,
pub net_pnl: MetricsTree_Cohorts_Utxo_All_Unrealized_NetPnl,
pub gross_pnl: CentsUsdPattern2,
pub invested_capital: InPattern,
pub sentiment: GreedNetPainPattern,
pub loss: MetricsTree_Cohorts_Utxo_All_Unrealized_Loss,
pub net_pnl: MetricsTree_Cohorts_Utxo_All_Unrealized_NetPnl,
pub profit: MetricsTree_Cohorts_Utxo_All_Unrealized_Profit,
pub nupl: BpsRatioPattern,
}
impl MetricsTree_Cohorts_Utxo_All_Unrealized {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
nupl: BpsRatioPattern::new(client.clone(), "nupl".to_string()),
profit: MetricsTree_Cohorts_Utxo_All_Unrealized_Profit::new(client.clone(), format!("{base_path}_profit")),
loss: MetricsTree_Cohorts_Utxo_All_Unrealized_Loss::new(client.clone(), format!("{base_path}_loss")),
net_pnl: MetricsTree_Cohorts_Utxo_All_Unrealized_NetPnl::new(client.clone(), format!("{base_path}_net_pnl")),
gross_pnl: CentsUsdPattern2::new(client.clone(), "unrealized_gross_pnl".to_string()),
invested_capital: InPattern::new(client.clone(), "invested_capital_in".to_string()),
sentiment: GreedNetPainPattern::new(client.clone(), "".to_string()),
loss: MetricsTree_Cohorts_Utxo_All_Unrealized_Loss::new(client.clone(), format!("{base_path}_loss")),
net_pnl: MetricsTree_Cohorts_Utxo_All_Unrealized_NetPnl::new(client.clone(), format!("{base_path}_net_pnl")),
profit: MetricsTree_Cohorts_Utxo_All_Unrealized_Profit::new(client.clone(), format!("{base_path}_profit")),
nupl: BpsRatioPattern::new(client.clone(), "nupl".to_string()),
}
}
}
/// Metrics tree node.
pub struct MetricsTree_Cohorts_Utxo_All_Unrealized_Loss {
pub negative: MetricPattern1<Dollars>,
pub base: CentsUsdPattern2,
pub cumulative: CentsUsdPattern2,
pub sum: _1m1w1y24hPattern4,
pub rel_to_mcap: BpsPercentRatioPattern3,
pub rel_to_own_gross: BpsPercentRatioPattern3,
}
impl MetricsTree_Cohorts_Utxo_All_Unrealized_Loss {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
negative: MetricPattern1::new(client.clone(), "neg_unrealized_loss".to_string()),
base: CentsUsdPattern2::new(client.clone(), "unrealized_loss".to_string()),
cumulative: CentsUsdPattern2::new(client.clone(), "unrealized_loss_cumulative".to_string()),
sum: _1m1w1y24hPattern4::new(client.clone(), "unrealized_loss_sum".to_string()),
rel_to_mcap: BpsPercentRatioPattern3::new(client.clone(), "unrealized_loss_rel_to_mcap".to_string()),
rel_to_own_gross: BpsPercentRatioPattern3::new(client.clone(), "unrealized_loss_rel_to_own_gross_pnl".to_string()),
}
}
}
/// Metrics tree node.
pub struct MetricsTree_Cohorts_Utxo_All_Unrealized_NetPnl {
pub cents: MetricPattern1<CentsSigned>,
pub usd: MetricPattern1<Dollars>,
pub rel_to_own_gross: BpsPercentRatioPattern,
}
impl MetricsTree_Cohorts_Utxo_All_Unrealized_NetPnl {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
cents: MetricPattern1::new(client.clone(), "net_unrealized_pnl_cents".to_string()),
usd: MetricPattern1::new(client.clone(), "net_unrealized_pnl".to_string()),
rel_to_own_gross: BpsPercentRatioPattern::new(client.clone(), "net_unrealized_pnl_rel_to_own_gross_pnl".to_string()),
}
}
}
@@ -6662,12 +6620,52 @@ impl MetricsTree_Cohorts_Utxo_All_Unrealized_Profit {
}
}
/// Metrics tree node.
pub struct MetricsTree_Cohorts_Utxo_All_Unrealized_Loss {
pub base: CentsUsdPattern2,
pub cumulative: CentsUsdPattern2,
pub sum: _1m1w1y24hPattern4,
pub negative: MetricPattern1<Dollars>,
pub rel_to_mcap: BpsPercentRatioPattern3,
pub rel_to_own_gross: BpsPercentRatioPattern3,
}
impl MetricsTree_Cohorts_Utxo_All_Unrealized_Loss {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
base: CentsUsdPattern2::new(client.clone(), "unrealized_loss".to_string()),
cumulative: CentsUsdPattern2::new(client.clone(), "unrealized_loss_cumulative".to_string()),
sum: _1m1w1y24hPattern4::new(client.clone(), "unrealized_loss_sum".to_string()),
negative: MetricPattern1::new(client.clone(), "neg_unrealized_loss".to_string()),
rel_to_mcap: BpsPercentRatioPattern3::new(client.clone(), "unrealized_loss_rel_to_mcap".to_string()),
rel_to_own_gross: BpsPercentRatioPattern3::new(client.clone(), "unrealized_loss_rel_to_own_gross_pnl".to_string()),
}
}
}
/// Metrics tree node.
pub struct MetricsTree_Cohorts_Utxo_All_Unrealized_NetPnl {
pub cents: MetricPattern1<CentsSigned>,
pub usd: MetricPattern1<Dollars>,
pub rel_to_own_gross: BpsPercentRatioPattern,
}
impl MetricsTree_Cohorts_Utxo_All_Unrealized_NetPnl {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
cents: MetricPattern1::new(client.clone(), "net_unrealized_pnl_cents".to_string()),
usd: MetricPattern1::new(client.clone(), "net_unrealized_pnl".to_string()),
rel_to_own_gross: BpsPercentRatioPattern::new(client.clone(), "net_unrealized_pnl_rel_to_own_gross_pnl".to_string()),
}
}
}
/// Metrics tree node.
pub struct MetricsTree_Cohorts_Utxo_Sth {
pub realized: CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern,
pub supply: DeltaHalfInRelTotalPattern2,
pub outputs: UnspentPattern,
pub activity: CoindaysCoinyearsDormancySentVelocityPattern,
pub activity: CoindaysCoinyearsDormancySentPattern,
pub realized: CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern,
pub cost_basis: InvestedMaxMinPercentilesSupplyPattern,
pub unrealized: GrossInvestedLossNetNuplProfitSentimentPattern2,
}
@@ -6675,10 +6673,10 @@ pub struct MetricsTree_Cohorts_Utxo_Sth {
impl MetricsTree_Cohorts_Utxo_Sth {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
realized: CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern::new(client.clone(), "sth".to_string()),
supply: DeltaHalfInRelTotalPattern2::new(client.clone(), "sth_supply".to_string()),
outputs: UnspentPattern::new(client.clone(), "sth_utxo_count".to_string()),
activity: CoindaysCoinyearsDormancySentVelocityPattern::new(client.clone(), "sth".to_string()),
activity: CoindaysCoinyearsDormancySentPattern::new(client.clone(), "sth".to_string()),
realized: CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern::new(client.clone(), "sth".to_string()),
cost_basis: InvestedMaxMinPercentilesSupplyPattern::new(client.clone(), "sth".to_string()),
unrealized: GrossInvestedLossNetNuplProfitSentimentPattern2::new(client.clone(), "sth".to_string()),
}
@@ -6689,7 +6687,7 @@ impl MetricsTree_Cohorts_Utxo_Sth {
pub struct MetricsTree_Cohorts_Utxo_Lth {
pub supply: DeltaHalfInRelTotalPattern2,
pub outputs: UnspentPattern,
pub activity: CoindaysCoinyearsDormancySentVelocityPattern,
pub activity: CoindaysCoinyearsDormancySentPattern,
pub realized: MetricsTree_Cohorts_Utxo_Lth_Realized,
pub cost_basis: InvestedMaxMinPercentilesSupplyPattern,
pub unrealized: GrossInvestedLossNetNuplProfitSentimentPattern2,
@@ -6700,7 +6698,7 @@ impl MetricsTree_Cohorts_Utxo_Lth {
Self {
supply: DeltaHalfInRelTotalPattern2::new(client.clone(), "lth_supply".to_string()),
outputs: UnspentPattern::new(client.clone(), "lth_utxo_count".to_string()),
activity: CoindaysCoinyearsDormancySentVelocityPattern::new(client.clone(), "lth".to_string()),
activity: CoindaysCoinyearsDormancySentPattern::new(client.clone(), "lth".to_string()),
realized: MetricsTree_Cohorts_Utxo_Lth_Realized::new(client.clone(), format!("{base_path}_realized")),
cost_basis: InvestedMaxMinPercentilesSupplyPattern::new(client.clone(), "lth".to_string()),
unrealized: GrossInvestedLossNetNuplProfitSentimentPattern2::new(client.clone(), "lth".to_string()),
@@ -6710,52 +6708,52 @@ impl MetricsTree_Cohorts_Utxo_Lth {
/// Metrics tree node.
pub struct MetricsTree_Cohorts_Utxo_Lth_Realized {
pub cap: CentsDeltaRelUsdPattern,
pub profit: BaseCumulativeDistributionRelSumValuePattern,
pub loss: BaseCapitulationCumulativeNegativeRelSumValuePattern,
pub price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern,
pub mvrv: MetricPattern1<StoredF32>,
pub sopr: MetricsTree_Cohorts_Utxo_Lth_Realized_Sopr,
pub net_pnl: BaseChangeCumulativeDeltaRelSumPattern,
pub gross_pnl: BaseCumulativeSumPattern3,
pub sell_side_risk_ratio: _1m1w1y24hPattern6,
pub net_pnl: BaseChangeCumulativeDeltaRelSumPattern,
pub sopr: MetricsTree_Cohorts_Utxo_Lth_Realized_Sopr,
pub peak_regret: BaseCumulativeRelPattern,
pub investor: LowerPriceUpperPattern,
pub profit_to_loss_ratio: _1m1w1y24hPattern<StoredF64>,
pub cap: CentsDeltaRelUsdPattern,
pub price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern,
pub mvrv: MetricPattern1<StoredF32>,
}
impl MetricsTree_Cohorts_Utxo_Lth_Realized {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
cap: CentsDeltaRelUsdPattern::new(client.clone(), "lth_realized_cap".to_string()),
profit: BaseCumulativeDistributionRelSumValuePattern::new(client.clone(), "lth".to_string()),
loss: BaseCapitulationCumulativeNegativeRelSumValuePattern::new(client.clone(), "lth".to_string()),
price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern::new(client.clone(), "lth_realized_price".to_string()),
mvrv: MetricPattern1::new(client.clone(), "lth_mvrv".to_string()),
sopr: MetricsTree_Cohorts_Utxo_Lth_Realized_Sopr::new(client.clone(), format!("{base_path}_sopr")),
net_pnl: BaseChangeCumulativeDeltaRelSumPattern::new(client.clone(), "lth_net".to_string()),
gross_pnl: BaseCumulativeSumPattern3::new(client.clone(), "lth_realized_gross_pnl".to_string()),
sell_side_risk_ratio: _1m1w1y24hPattern6::new(client.clone(), "lth_sell_side_risk_ratio".to_string()),
net_pnl: BaseChangeCumulativeDeltaRelSumPattern::new(client.clone(), "lth_net".to_string()),
sopr: MetricsTree_Cohorts_Utxo_Lth_Realized_Sopr::new(client.clone(), format!("{base_path}_sopr")),
peak_regret: BaseCumulativeRelPattern::new(client.clone(), "lth_realized_peak_regret".to_string()),
investor: LowerPriceUpperPattern::new(client.clone(), "lth".to_string()),
profit_to_loss_ratio: _1m1w1y24hPattern::new(client.clone(), "lth_realized_profit_to_loss_ratio".to_string()),
cap: CentsDeltaRelUsdPattern::new(client.clone(), "lth_realized_cap".to_string()),
price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern::new(client.clone(), "lth_realized_price".to_string()),
mvrv: MetricPattern1::new(client.clone(), "lth_mvrv".to_string()),
}
}
}
/// Metrics tree node.
pub struct MetricsTree_Cohorts_Utxo_Lth_Realized_Sopr {
pub ratio: _1m1w1y24hPattern<StoredF64>,
pub value_created: BaseCumulativeSumPattern<Cents>,
pub value_destroyed: BaseCumulativeSumPattern<Cents>,
pub ratio: _1m1w1y24hPattern<StoredF64>,
}
impl MetricsTree_Cohorts_Utxo_Lth_Realized_Sopr {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
ratio: _1m1w1y24hPattern::new(client.clone(), "lth_sopr".to_string()),
value_created: BaseCumulativeSumPattern::new(client.clone(), "lth_value_created".to_string()),
value_destroyed: BaseCumulativeSumPattern::new(client.clone(), "lth_value_destroyed".to_string()),
ratio: _1m1w1y24hPattern::new(client.clone(), "lth_sopr".to_string()),
}
}
}
@@ -30,14 +30,14 @@ impl Vecs {
self.tx_velocity_btc.height.compute_multiply(
starting_indexes.height,
&activity.ratio.height,
&supply.velocity.btc.height,
&supply.velocity.native.height,
exit,
)?;
self.tx_velocity_usd.height.compute_multiply(
starting_indexes.height,
&activity.ratio.height,
&supply.velocity.usd.height,
&supply.velocity.fiat.height,
exit,
)?;
@@ -1,10 +1,10 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Bitcoin, Height, Indexes, Sats, StoredF32, StoredF64, Version};
use brk_types::{Bitcoin, Height, Indexes, StoredF32, StoredF64, Version};
use derive_more::{Deref, DerefMut};
use vecdb::{AnyStoredVec, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode};
use vecdb::{AnyStoredVec, Exit, ReadableCloneableVec, Rw, StorageMode};
use crate::internal::{PerBlock, Identity, LazyPerBlock};
use crate::internal::{Identity, LazyPerBlock, PerBlock};
use crate::distribution::{metrics::ImportConfig, state::{CohortState, CostBasisOps, RealizedOps}};
@@ -20,7 +20,6 @@ pub struct ActivityFull<M: StorageMode = Rw> {
pub coinyears_destroyed: LazyPerBlock<StoredF64, StoredF64>,
pub dormancy: PerBlock<StoredF32, M>,
pub velocity: PerBlock<StoredF32, M>,
}
impl ActivityFull {
@@ -39,7 +38,6 @@ impl ActivityFull {
inner,
coinyears_destroyed,
dormancy: cfg.import("dormancy", v1)?,
velocity: cfg.import("velocity", v1)?,
})
}
@@ -58,7 +56,6 @@ impl ActivityFull {
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
let mut vecs = self.inner.collect_vecs_mut();
vecs.push(&mut self.dormancy.height);
vecs.push(&mut self.velocity.height);
vecs
}
@@ -83,7 +80,6 @@ impl ActivityFull {
pub(crate) fn compute_rest_part2(
&mut self,
starting_indexes: &Indexes,
supply_total_sats: &impl ReadableVec<Height, Sats>,
exit: &Exit,
) -> Result<()> {
self.dormancy.height.compute_transform2(
@@ -101,21 +97,6 @@ impl ActivityFull {
exit,
)?;
self.velocity.height.compute_transform2(
starting_indexes.height,
&self.inner.sent.base.height,
supply_total_sats,
|(i, sent_sats, supply_sats, ..)| {
let supply = supply_sats.as_u128() as f64;
if supply == 0.0 {
(i, StoredF32::from(0.0f32))
} else {
(i, StoredF32::from((sent_sats.as_u128() as f64 / supply) as f32))
}
},
exit,
)?;
Ok(())
}
}
@@ -145,7 +145,6 @@ impl AllCohortMetrics {
self.activity.compute_rest_part2(
starting_indexes,
&self.supply.total.sats.height,
exit,
)?;
@@ -125,7 +125,6 @@ impl ExtendedCohortMetrics {
self.activity.compute_rest_part2(
starting_indexes,
&self.supply.total.sats.height,
exit,
)?;
@@ -10,17 +10,17 @@ use crate::{
#[derive(Traversable)]
pub struct AdjustedSopr<M: StorageMode = Rw> {
pub ratio: RollingWindows<StoredF64, M>,
pub value_created: PerBlockCumulativeWithSums<Cents, Cents, M>,
pub value_destroyed: PerBlockCumulativeWithSums<Cents, Cents, M>,
pub ratio: RollingWindows<StoredF64, M>,
}
impl AdjustedSopr {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
Ok(Self {
ratio: cfg.import("asopr", Version::ONE)?,
value_created: cfg.import("adj_value_created", Version::ONE)?,
value_destroyed: cfg.import("adj_value_destroyed", Version::ONE)?,
ratio: cfg.import("asopr", Version::ONE)?,
})
}
@@ -17,8 +17,8 @@ impl Vecs {
// velocity = rolling_1y_sum(volume) / circulating_supply
let circulating_supply = &distribution.utxo_cohorts.all.metrics.supply.total;
// BTC velocity at height level
self.btc.height.compute_rolling_ratio(
// Native velocity at height level
self.native.height.compute_rolling_ratio(
starting_indexes.height,
&blocks.lookback._1y,
&transactions.volume.sent_sum.base.sats.height,
@@ -26,8 +26,8 @@ impl Vecs {
exit,
)?;
// USD velocity at height level
self.usd.height.compute_rolling_ratio(
// Fiat velocity at height level
self.fiat.height.compute_rolling_ratio(
starting_indexes.height,
&blocks.lookback._1y,
&transactions.volume.sent_sum.base.usd.height,
@@ -12,8 +12,8 @@ impl Vecs {
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
btc: PerBlock::forced_import(db, "velocity_btc", version, indexes)?,
usd: PerBlock::forced_import(db, "velocity_usd", version, indexes)?,
native: PerBlock::forced_import(db, "velocity", version, indexes)?,
fiat: PerBlock::forced_import(db, "velocity_fiat", version, indexes)?,
})
}
}
@@ -6,6 +6,6 @@ use crate::internal::PerBlock;
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub btc: PerBlock<StoredF64, M>,
pub usd: PerBlock<StoredF64, M>,
pub native: PerBlock<StoredF64, M>,
pub fiat: PerBlock<StoredF64, M>,
}
+80 -89
View File
@@ -394,90 +394,95 @@ fn build_where_clause(
}
fn generate_field_traversals(infos: &[FieldInfo], merge: bool) -> proc_macro2::TokenStream {
let normal_entries: Vec<_> = infos
// Process all fields in declaration order (interleaving normal and flatten)
// so that struct field order determines tree key order.
let field_operations: Vec<_> = infos
.iter()
.filter(|i| matches!(i.attr, FieldAttr::Normal) && !i.hidden)
.filter(|i| !i.hidden)
.map(|info| {
let field_name = info.name;
let field_name_str = {
let s = field_name.to_string();
let s = s.strip_prefix("r#").unwrap_or(&s).to_string();
s.strip_prefix('_').map(String::from).unwrap_or(s)
};
match info.attr {
FieldAttr::Normal => {
let field_name = info.name;
let field_name_str = {
let s = field_name.to_string();
let s = s.strip_prefix("r#").unwrap_or(&s).to_string();
s.strip_prefix('_').map(String::from).unwrap_or(s)
};
// Determine the tree key and optional wrapping path.
// wrap = "a/b" means: outer_key = "a", wrap the node under "b" then under the rename/field name.
// wrap = "a" means: outer_key = "a", wrap under rename or field name.
// No wrap: outer_key = rename or field name, no wrapping.
let (outer_key, wrap_path): (String, Vec<&str>) =
match (info.wrap.as_deref(), info.rename.as_deref()) {
(Some(wrap), Some(rename)) => {
let parts: Vec<&str> = wrap.split('/').collect();
let outer = parts[0].to_string();
let mut path: Vec<&str> = parts[1..].to_vec();
path.push(rename);
(outer, path)
}
(Some(wrap), None) => {
let parts: Vec<&str> = wrap.split('/').collect();
let outer = parts[0].to_string();
let mut path: Vec<&str> = parts[1..].to_vec();
path.push(&field_name_str);
(outer, path)
}
(None, Some(rename)) => (rename.to_string(), vec![]),
(None, None) => (field_name_str.clone(), vec![]),
};
// Determine the tree key and optional wrapping path.
// wrap = "a/b" means: outer_key = "a", wrap the node under "b" then under the rename/field name.
// wrap = "a" means: outer_key = "a", wrap under rename or field name.
// No wrap: outer_key = rename or field name, no wrapping.
let (outer_key, wrap_path): (String, Vec<&str>) =
match (info.wrap.as_deref(), info.rename.as_deref()) {
(Some(wrap), Some(rename)) => {
let parts: Vec<&str> = wrap.split('/').collect();
let outer = parts[0].to_string();
let mut path: Vec<&str> = parts[1..].to_vec();
path.push(rename);
(outer, path)
}
(Some(wrap), None) => {
let parts: Vec<&str> = wrap.split('/').collect();
let outer = parts[0].to_string();
let mut path: Vec<&str> = parts[1..].to_vec();
path.push(&field_name_str);
(outer, path)
}
(None, Some(rename)) => (rename.to_string(), vec![]),
(None, None) => (field_name_str.clone(), vec![]),
};
// Build nested wrapping: wrap(path[last], wrap(path[last-1], ... node))
let build_wrapped = |base: proc_macro2::TokenStream| -> proc_macro2::TokenStream {
wrap_path.iter().rev().fold(base, |inner, key| {
quote! { brk_traversable::TreeNode::wrap(#key, #inner) }
})
};
// Build nested wrapping: wrap(path[last], wrap(path[last-1], ... node))
let build_wrapped = |base: proc_macro2::TokenStream| -> proc_macro2::TokenStream {
wrap_path.iter().rev().fold(base, |inner, key| {
quote! { brk_traversable::TreeNode::wrap(#key, #inner) }
})
};
if info.is_option {
let node_expr = build_wrapped(quote! { nested.to_tree_node() });
quote! {
self.#field_name.as_ref().map(|nested| (String::from(#outer_key), #node_expr))
}
} else {
let node_expr_self = build_wrapped(quote! { self.#field_name.to_tree_node() });
quote! {
Some((String::from(#outer_key), #node_expr_self))
}
}
})
.collect();
let flatten_entries: Vec<_> = infos
.iter()
.filter(|i| matches!(i.attr, FieldAttr::Flatten) && !i.hidden)
.map(|info| {
let field_name = info.name;
let merge_branch = quote! {
brk_traversable::TreeNode::Branch(map) => {
for (key, node) in map {
brk_traversable::TreeNode::merge_node(&mut collected, key, node)
.expect("Conflicting values for same key during flatten");
if info.is_option {
let node_expr = build_wrapped(quote! { nested.to_tree_node() });
quote! {
if let Some(entry) = self.#field_name.as_ref().map(|nested| (String::from(#outer_key), #node_expr)) {
brk_traversable::TreeNode::merge_node(&mut collected, entry.0, entry.1)
.expect("Conflicting values for same key");
}
}
} else {
let node_expr_self = build_wrapped(quote! { self.#field_name.to_tree_node() });
quote! {
brk_traversable::TreeNode::merge_node(&mut collected, String::from(#outer_key), #node_expr_self)
.expect("Conflicting values for same key");
}
}
}
leaf @ brk_traversable::TreeNode::Leaf(_) => {
brk_traversable::TreeNode::merge_node(&mut collected, String::from(stringify!(#field_name)), leaf)
.expect("Conflicting values for same key during flatten");
}
};
FieldAttr::Flatten => {
let field_name = info.name;
let merge_branch = quote! {
brk_traversable::TreeNode::Branch(map) => {
for (key, node) in map {
brk_traversable::TreeNode::merge_node(&mut collected, key, node)
.expect("Conflicting values for same key during flatten");
}
}
leaf @ brk_traversable::TreeNode::Leaf(_) => {
brk_traversable::TreeNode::merge_node(&mut collected, String::from(stringify!(#field_name)), leaf)
.expect("Conflicting values for same key during flatten");
}
};
if info.is_option {
quote! {
if let Some(ref nested) = self.#field_name {
match nested.to_tree_node() { #merge_branch }
if info.is_option {
quote! {
if let Some(ref nested) = self.#field_name {
match nested.to_tree_node() { #merge_branch }
}
}
} else {
quote! {
match self.#field_name.to_tree_node() { #merge_branch }
}
}
}
} else {
quote! {
match self.#field_name.to_tree_node() { #merge_branch }
}
}
})
.collect();
@@ -493,23 +498,9 @@ fn generate_field_traversals(infos: &[FieldInfo], merge: bool) -> proc_macro2::T
brk_traversable::IndexMap::new();
};
let normal_insert = if !normal_entries.is_empty() {
quote! {
for entry in [#(#normal_entries,)*].into_iter().flatten() {
brk_traversable::TreeNode::merge_node(&mut collected, entry.0, entry.1)
.expect("Conflicting values for same key");
}
}
} else {
quote! {}
};
let flatten_insert = quote! { #(#flatten_entries)* };
quote! {
#init_collected
#normal_insert
#flatten_insert
#(#field_operations)*
#final_expr
}
}