diff --git a/crates/brk_client/examples/basic.rs b/crates/brk_client/examples/basic.rs index 25441f997..e4d070d93 100644 --- a/crates/brk_client/examples/basic.rs +++ b/crates/brk_client/examples/basic.rs @@ -18,9 +18,9 @@ fn main() -> brk_client::Result<()> { let price_close = client .metrics() .prices - .usd .split .close + .usd .by .day1() .last(3) diff --git a/crates/brk_client/src/lib.rs b/crates/brk_client/src/lib.rs index dd026ad1f..61bce3958 100644 --- a/crates/brk_client/src/lib.rs +++ b/crates/brk_client/src/lib.rs @@ -1006,13 +1006,13 @@ pub struct AdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedS pub lower_price_band: SatsUsdPattern, pub mvrv: MetricPattern1, pub neg_realized_loss: MetricPattern1, - pub net_realized_pnl: CumulativeHeightPattern, + pub net_realized_pnl: CumulativeHeightPattern, pub net_realized_pnl_7d_ema: MetricPattern1, pub net_realized_pnl_cumulative_30d_delta: MetricPattern1, pub net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: MetricPattern1, pub net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: MetricPattern1, pub net_realized_pnl_rel_to_realized_cap: MetricPattern1, - pub peak_regret: CumulativeHeightPattern, + pub peak_regret: CumulativeHeightPattern, pub peak_regret_rel_to_realized_cap: MetricPattern1, pub profit_flow: MetricPattern1, pub profit_value_created: MetricPattern1, @@ -1021,7 +1021,7 @@ pub struct AdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedS pub realized_cap_30d_delta: MetricPattern1, pub realized_cap_cents: MetricPattern1, pub realized_cap_rel_to_own_market_cap: MetricPattern1, - pub realized_loss: CumulativeHeightPattern, + pub realized_loss: CumulativeHeightPattern, pub realized_loss_1y: MetricPattern1, pub realized_loss_24h: MetricPattern1, pub realized_loss_30d: MetricPattern1, @@ -1031,7 +1031,7 @@ pub struct AdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedS pub realized_price: SatsUsdPattern, pub realized_price_extra: RatioPattern2, pub realized_price_ratio_ext: RatioPattern3, - pub realized_profit: CumulativeHeightPattern, + pub realized_profit: CumulativeHeightPattern, pub realized_profit_1y: MetricPattern1, pub realized_profit_24h: MetricPattern1, pub realized_profit_30d: MetricPattern1, @@ -1056,9 +1056,9 @@ pub struct AdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedS pub sell_side_risk_ratio_30d_ema: MetricPattern1, pub sell_side_risk_ratio_7d: MetricPattern1, pub sell_side_risk_ratio_7d_ema: MetricPattern1, - pub sent_in_loss: BtcSatsUsdPattern2, + pub sent_in_loss: BaseCumulativePattern, pub sent_in_loss_14d_ema: BtcSatsUsdPattern, - pub sent_in_profit: BtcSatsUsdPattern2, + pub sent_in_profit: BaseCumulativePattern, pub sent_in_profit_14d_ema: BtcSatsUsdPattern, pub sopr: MetricPattern1, pub sopr_1y: MetricPattern1, @@ -1168,9 +1168,9 @@ impl AdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSen sell_side_risk_ratio_30d_ema: MetricPattern1::new(client.clone(), _m(&acc, "sell_side_risk_ratio_30d_ema")), sell_side_risk_ratio_7d: MetricPattern1::new(client.clone(), _m(&acc, "sell_side_risk_ratio_7d")), sell_side_risk_ratio_7d_ema: MetricPattern1::new(client.clone(), _m(&acc, "sell_side_risk_ratio_7d_ema")), - sent_in_loss: BtcSatsUsdPattern2::new(client.clone(), _m(&acc, "sent_in_loss")), + sent_in_loss: BaseCumulativePattern::new(client.clone(), _m(&acc, "sent_in_loss")), sent_in_loss_14d_ema: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "sent_in_loss_14d_ema")), - sent_in_profit: BtcSatsUsdPattern2::new(client.clone(), _m(&acc, "sent_in_profit")), + sent_in_profit: BaseCumulativePattern::new(client.clone(), _m(&acc, "sent_in_profit")), sent_in_profit_14d_ema: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "sent_in_profit_14d_ema")), sopr: MetricPattern1::new(client.clone(), _m(&acc, "sopr")), sopr_1y: MetricPattern1::new(client.clone(), _m(&acc, "sopr_1y")), @@ -1229,13 +1229,13 @@ pub struct AdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedS pub lower_price_band: SatsUsdPattern, pub mvrv: MetricPattern1, pub neg_realized_loss: MetricPattern1, - pub net_realized_pnl: CumulativeHeightPattern, + pub net_realized_pnl: CumulativeHeightPattern, pub net_realized_pnl_7d_ema: MetricPattern1, pub net_realized_pnl_cumulative_30d_delta: MetricPattern1, pub net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: MetricPattern1, pub net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: MetricPattern1, pub net_realized_pnl_rel_to_realized_cap: MetricPattern1, - pub peak_regret: CumulativeHeightPattern, + pub peak_regret: CumulativeHeightPattern, pub peak_regret_rel_to_realized_cap: MetricPattern1, pub profit_flow: MetricPattern1, pub profit_value_created: MetricPattern1, @@ -1243,12 +1243,12 @@ pub struct AdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedS pub realized_cap: MetricPattern1, pub realized_cap_30d_delta: MetricPattern1, pub realized_cap_cents: MetricPattern1, - pub realized_loss: CumulativeHeightPattern, + pub realized_loss: CumulativeHeightPattern, pub realized_loss_7d_ema: MetricPattern1, pub realized_loss_rel_to_realized_cap: MetricPattern1, pub realized_price: SatsUsdPattern, pub realized_price_extra: RatioPattern2, - pub realized_profit: CumulativeHeightPattern, + pub realized_profit: CumulativeHeightPattern, pub realized_profit_7d_ema: MetricPattern1, pub realized_profit_rel_to_realized_cap: MetricPattern1, pub realized_value: MetricPattern1, @@ -1265,9 +1265,9 @@ pub struct AdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedS pub sell_side_risk_ratio_30d_ema: MetricPattern1, pub sell_side_risk_ratio_7d: MetricPattern1, pub sell_side_risk_ratio_7d_ema: MetricPattern1, - pub sent_in_loss: BtcSatsUsdPattern2, + pub sent_in_loss: BaseCumulativePattern, pub sent_in_loss_14d_ema: BtcSatsUsdPattern, - pub sent_in_profit: BtcSatsUsdPattern2, + pub sent_in_profit: BaseCumulativePattern, pub sent_in_profit_14d_ema: BtcSatsUsdPattern, pub sopr: MetricPattern1, pub sopr_1y: MetricPattern1, @@ -1362,9 +1362,9 @@ impl AdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSen sell_side_risk_ratio_30d_ema: MetricPattern1::new(client.clone(), _m(&acc, "sell_side_risk_ratio_30d_ema")), sell_side_risk_ratio_7d: MetricPattern1::new(client.clone(), _m(&acc, "sell_side_risk_ratio_7d")), sell_side_risk_ratio_7d_ema: MetricPattern1::new(client.clone(), _m(&acc, "sell_side_risk_ratio_7d_ema")), - sent_in_loss: BtcSatsUsdPattern2::new(client.clone(), _m(&acc, "sent_in_loss")), + sent_in_loss: BaseCumulativePattern::new(client.clone(), _m(&acc, "sent_in_loss")), sent_in_loss_14d_ema: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "sent_in_loss_14d_ema")), - sent_in_profit: BtcSatsUsdPattern2::new(client.clone(), _m(&acc, "sent_in_profit")), + sent_in_profit: BaseCumulativePattern::new(client.clone(), _m(&acc, "sent_in_profit")), sent_in_profit_14d_ema: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "sent_in_profit_14d_ema")), sopr: MetricPattern1::new(client.clone(), _m(&acc, "sopr")), sopr_1y: MetricPattern1::new(client.clone(), _m(&acc, "sopr_1y")), @@ -1405,13 +1405,13 @@ pub struct CapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentS pub lower_price_band: SatsUsdPattern, pub mvrv: MetricPattern1, pub neg_realized_loss: MetricPattern1, - pub net_realized_pnl: CumulativeHeightPattern, + pub net_realized_pnl: CumulativeHeightPattern, pub net_realized_pnl_7d_ema: MetricPattern1, pub net_realized_pnl_cumulative_30d_delta: MetricPattern1, pub net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: MetricPattern1, pub net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: MetricPattern1, pub net_realized_pnl_rel_to_realized_cap: MetricPattern1, - pub peak_regret: CumulativeHeightPattern, + pub peak_regret: CumulativeHeightPattern, pub peak_regret_rel_to_realized_cap: MetricPattern1, pub profit_flow: MetricPattern1, pub profit_value_created: MetricPattern1, @@ -1420,7 +1420,7 @@ pub struct CapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentS pub realized_cap_30d_delta: MetricPattern1, pub realized_cap_cents: MetricPattern1, pub realized_cap_rel_to_own_market_cap: MetricPattern1, - pub realized_loss: CumulativeHeightPattern, + pub realized_loss: CumulativeHeightPattern, pub realized_loss_1y: MetricPattern1, pub realized_loss_24h: MetricPattern1, pub realized_loss_30d: MetricPattern1, @@ -1430,7 +1430,7 @@ pub struct CapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentS pub realized_price: SatsUsdPattern, pub realized_price_extra: RatioPattern2, pub realized_price_ratio_ext: RatioPattern3, - pub realized_profit: CumulativeHeightPattern, + pub realized_profit: CumulativeHeightPattern, pub realized_profit_1y: MetricPattern1, pub realized_profit_24h: MetricPattern1, pub realized_profit_30d: MetricPattern1, @@ -1455,9 +1455,9 @@ pub struct CapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentS pub sell_side_risk_ratio_30d_ema: MetricPattern1, pub sell_side_risk_ratio_7d: MetricPattern1, pub sell_side_risk_ratio_7d_ema: MetricPattern1, - pub sent_in_loss: BtcSatsUsdPattern2, + pub sent_in_loss: BaseCumulativePattern, pub sent_in_loss_14d_ema: BtcSatsUsdPattern, - pub sent_in_profit: BtcSatsUsdPattern2, + pub sent_in_profit: BaseCumulativePattern, pub sent_in_profit_14d_ema: BtcSatsUsdPattern, pub sopr: MetricPattern1, pub sopr_1y: MetricPattern1, @@ -1548,9 +1548,9 @@ impl CapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprTot sell_side_risk_ratio_30d_ema: MetricPattern1::new(client.clone(), _m(&acc, "sell_side_risk_ratio_30d_ema")), sell_side_risk_ratio_7d: MetricPattern1::new(client.clone(), _m(&acc, "sell_side_risk_ratio_7d")), sell_side_risk_ratio_7d_ema: MetricPattern1::new(client.clone(), _m(&acc, "sell_side_risk_ratio_7d_ema")), - sent_in_loss: BtcSatsUsdPattern2::new(client.clone(), _m(&acc, "sent_in_loss")), + sent_in_loss: BaseCumulativePattern::new(client.clone(), _m(&acc, "sent_in_loss")), sent_in_loss_14d_ema: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "sent_in_loss_14d_ema")), - sent_in_profit: BtcSatsUsdPattern2::new(client.clone(), _m(&acc, "sent_in_profit")), + sent_in_profit: BaseCumulativePattern::new(client.clone(), _m(&acc, "sent_in_profit")), sent_in_profit_14d_ema: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "sent_in_profit_14d_ema")), sopr: MetricPattern1::new(client.clone(), _m(&acc, "sopr")), sopr_1y: MetricPattern1::new(client.clone(), _m(&acc, "sopr_1y")), @@ -1590,13 +1590,13 @@ pub struct CapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentS pub lower_price_band: SatsUsdPattern, pub mvrv: MetricPattern1, pub neg_realized_loss: MetricPattern1, - pub net_realized_pnl: CumulativeHeightPattern, + pub net_realized_pnl: CumulativeHeightPattern, pub net_realized_pnl_7d_ema: MetricPattern1, pub net_realized_pnl_cumulative_30d_delta: MetricPattern1, pub net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: MetricPattern1, pub net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: MetricPattern1, pub net_realized_pnl_rel_to_realized_cap: MetricPattern1, - pub peak_regret: CumulativeHeightPattern, + pub peak_regret: CumulativeHeightPattern, pub peak_regret_rel_to_realized_cap: MetricPattern1, pub profit_flow: MetricPattern1, pub profit_value_created: MetricPattern1, @@ -1604,12 +1604,12 @@ pub struct CapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentS pub realized_cap: MetricPattern1, pub realized_cap_30d_delta: MetricPattern1, pub realized_cap_cents: MetricPattern1, - pub realized_loss: CumulativeHeightPattern, + pub realized_loss: CumulativeHeightPattern, pub realized_loss_7d_ema: MetricPattern1, pub realized_loss_rel_to_realized_cap: MetricPattern1, pub realized_price: SatsUsdPattern, pub realized_price_extra: RatioPattern2, - pub realized_profit: CumulativeHeightPattern, + pub realized_profit: CumulativeHeightPattern, pub realized_profit_7d_ema: MetricPattern1, pub realized_profit_rel_to_realized_cap: MetricPattern1, pub realized_value: MetricPattern1, @@ -1626,9 +1626,9 @@ pub struct CapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentS pub sell_side_risk_ratio_30d_ema: MetricPattern1, pub sell_side_risk_ratio_7d: MetricPattern1, pub sell_side_risk_ratio_7d_ema: MetricPattern1, - pub sent_in_loss: BtcSatsUsdPattern2, + pub sent_in_loss: BaseCumulativePattern, pub sent_in_loss_14d_ema: BtcSatsUsdPattern, - pub sent_in_profit: BtcSatsUsdPattern2, + pub sent_in_profit: BaseCumulativePattern, pub sent_in_profit_14d_ema: BtcSatsUsdPattern, pub sopr: MetricPattern1, pub sopr_1y: MetricPattern1, @@ -1704,9 +1704,9 @@ impl CapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprTot sell_side_risk_ratio_30d_ema: MetricPattern1::new(client.clone(), _m(&acc, "sell_side_risk_ratio_30d_ema")), sell_side_risk_ratio_7d: MetricPattern1::new(client.clone(), _m(&acc, "sell_side_risk_ratio_7d")), sell_side_risk_ratio_7d_ema: MetricPattern1::new(client.clone(), _m(&acc, "sell_side_risk_ratio_7d_ema")), - sent_in_loss: BtcSatsUsdPattern2::new(client.clone(), _m(&acc, "sent_in_loss")), + sent_in_loss: BaseCumulativePattern::new(client.clone(), _m(&acc, "sent_in_loss")), sent_in_loss_14d_ema: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "sent_in_loss_14d_ema")), - sent_in_profit: BtcSatsUsdPattern2::new(client.clone(), _m(&acc, "sent_in_profit")), + sent_in_profit: BaseCumulativePattern::new(client.clone(), _m(&acc, "sent_in_profit")), sent_in_profit_14d_ema: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "sent_in_profit_14d_ema")), sopr: MetricPattern1::new(client.clone(), _m(&acc, "sopr")), sopr_1y: MetricPattern1::new(client.clone(), _m(&acc, "sopr_1y")), @@ -2199,15 +2199,15 @@ pub struct BlocksCoinbaseDaysDominanceFeeSubsidyPattern { pub blocks_mined_1y_sum: MetricPattern1, pub blocks_mined_24h_sum: MetricPattern1, pub blocks_since_block: MetricPattern1, - pub coinbase: BtcSatsUsdPattern4, + pub coinbase: BaseCumulativeSumPattern, pub days_since_block: MetricPattern1, pub dominance: MetricPattern1, pub dominance_1m: MetricPattern1, pub dominance_1w: MetricPattern1, pub dominance_1y: MetricPattern1, pub dominance_24h: MetricPattern1, - pub fee: BtcSatsUsdPattern4, - pub subsidy: BtcSatsUsdPattern4, + pub fee: BaseCumulativeSumPattern, + pub subsidy: BaseCumulativeSumPattern, } impl BlocksCoinbaseDaysDominanceFeeSubsidyPattern { @@ -2220,15 +2220,15 @@ impl BlocksCoinbaseDaysDominanceFeeSubsidyPattern { blocks_mined_1y_sum: MetricPattern1::new(client.clone(), _m(&acc, "blocks_mined_1y_sum")), blocks_mined_24h_sum: MetricPattern1::new(client.clone(), _m(&acc, "blocks_mined_24h_sum")), blocks_since_block: MetricPattern1::new(client.clone(), _m(&acc, "blocks_since_block")), - coinbase: BtcSatsUsdPattern4::new(client.clone(), _m(&acc, "coinbase")), + coinbase: BaseCumulativeSumPattern::new(client.clone(), _m(&acc, "coinbase")), days_since_block: MetricPattern1::new(client.clone(), _m(&acc, "days_since_block")), dominance: MetricPattern1::new(client.clone(), _m(&acc, "dominance")), dominance_1m: MetricPattern1::new(client.clone(), _m(&acc, "dominance_1m")), dominance_1w: MetricPattern1::new(client.clone(), _m(&acc, "dominance_1w")), dominance_1y: MetricPattern1::new(client.clone(), _m(&acc, "dominance_1y")), dominance_24h: MetricPattern1::new(client.clone(), _m(&acc, "dominance_24h")), - fee: BtcSatsUsdPattern4::new(client.clone(), _m(&acc, "fee")), - subsidy: BtcSatsUsdPattern4::new(client.clone(), _m(&acc, "subsidy")), + fee: BaseCumulativeSumPattern::new(client.clone(), _m(&acc, "fee")), + subsidy: BaseCumulativeSumPattern::new(client.clone(), _m(&acc, "subsidy")), } } } @@ -2426,7 +2426,7 @@ pub struct AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern { pub pct25: MetricPattern20, pub pct75: MetricPattern20, pub pct90: MetricPattern20, - pub rolling: AverageMaxMedianMinP10P25P75P90SumPattern, + pub rolling: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern, pub sum: MetricPattern20, } @@ -2443,27 +2443,61 @@ impl AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern { pct25: MetricPattern20::new(client.clone(), _m(&acc, "pct25")), pct75: MetricPattern20::new(client.clone(), _m(&acc, "pct75")), pct90: MetricPattern20::new(client.clone(), _m(&acc, "pct90")), - rolling: AverageMaxMedianMinP10P25P75P90SumPattern::new(client.clone(), acc.clone()), + rolling: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern::new(client.clone(), acc.clone()), sum: MetricPattern20::new(client.clone(), _m(&acc, "sum")), } } } /// Pattern struct for repeated tree structure. -pub struct AverageCumulativeMaxMedianMinP10P25P75P90SumPattern { +pub struct AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern { + pub average: _1y24h30d7dPattern, + pub cumulative: MetricPattern1, + pub height: MetricPattern20, + pub max: _1y24h30d7dPattern, + pub median: _1y24h30d7dPattern, + pub min: _1y24h30d7dPattern, + pub pct10: _1y24h30d7dPattern, + pub pct25: _1y24h30d7dPattern, + pub pct75: _1y24h30d7dPattern, + pub pct90: _1y24h30d7dPattern, + pub sum: _1y24h30d7dPattern, +} + +impl AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + average: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "average")), + cumulative: MetricPattern1::new(client.clone(), _m(&acc, "cumulative")), + height: MetricPattern20::new(client.clone(), acc.clone()), + max: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "max")), + median: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "median")), + min: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "min")), + pct10: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p10")), + pct25: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p25")), + pct75: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p75")), + pct90: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p90")), + sum: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "sum")), + } + } +} + +/// Pattern struct for repeated tree structure. +pub struct AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern { pub average: _1y24h30d7dPattern, pub cumulative: MetricPattern1, pub max: _1y24h30d7dPattern, pub median: _1y24h30d7dPattern, pub min: _1y24h30d7dPattern, - pub p10: _1y24h30d7dPattern, - pub p25: _1y24h30d7dPattern, - pub p75: _1y24h30d7dPattern, - pub p90: _1y24h30d7dPattern, + pub pct10: _1y24h30d7dPattern, + pub pct25: _1y24h30d7dPattern, + pub pct75: _1y24h30d7dPattern, + pub pct90: _1y24h30d7dPattern, pub sum: _1y24h30d7dPattern, } -impl AverageCumulativeMaxMedianMinP10P25P75P90SumPattern { +impl AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { @@ -2472,10 +2506,10 @@ impl AverageCumulativeMaxMedianMinP10P25P75P90SumPattern { max: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "max")), median: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "median")), min: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "min")), - p10: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p10")), - p25: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p25")), - p75: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p75")), - p90: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p90")), + pct10: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p10")), + pct25: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p25")), + pct75: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p75")), + pct90: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p90")), sum: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "sum")), } } @@ -2574,19 +2608,49 @@ impl AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern { } /// Pattern struct for repeated tree structure. -pub struct AverageMaxMedianMinP10P25P75P90SumPattern { +pub struct AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2 { + pub average: BtcSatsUsdPattern, + pub max: BtcSatsUsdPattern, + pub median: BtcSatsUsdPattern, + pub min: BtcSatsUsdPattern, + pub pct10: BtcSatsUsdPattern, + pub pct25: BtcSatsUsdPattern, + pub pct75: BtcSatsUsdPattern, + pub pct90: BtcSatsUsdPattern, + pub sum: BtcSatsUsdPattern, +} + +impl AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2 { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + average: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "average")), + max: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "max")), + median: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "median")), + min: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "min")), + pct10: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "p10")), + pct25: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "p25")), + pct75: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "p75")), + pct90: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "p90")), + sum: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "sum")), + } + } +} + +/// Pattern struct for repeated tree structure. +pub struct AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern { pub average: _1y24h30d7dPattern, pub max: _1y24h30d7dPattern, pub median: _1y24h30d7dPattern, pub min: _1y24h30d7dPattern, - pub p10: _1y24h30d7dPattern, - pub p25: _1y24h30d7dPattern, - pub p75: _1y24h30d7dPattern, - pub p90: _1y24h30d7dPattern, + pub pct10: _1y24h30d7dPattern, + pub pct25: _1y24h30d7dPattern, + pub pct75: _1y24h30d7dPattern, + pub pct90: _1y24h30d7dPattern, pub sum: _1y24h30d7dPattern, } -impl AverageMaxMedianMinP10P25P75P90SumPattern { +impl AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { @@ -2594,29 +2658,29 @@ impl AverageMaxMedianMinP10P25P75P90SumPattern { max: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "max")), median: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "median")), min: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "min")), - p10: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p10")), - p25: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p25")), - p75: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p75")), - p90: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p90")), + pct10: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p10")), + pct25: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p25")), + pct75: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p75")), + pct90: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p90")), sum: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "sum")), } } } /// Pattern struct for repeated tree structure. -pub struct AverageHeightMaxMedianMinP10P25P75P90Pattern { +pub struct AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern { pub average: _1y24h30d7dPattern, pub height: MetricPattern20, pub max: _1y24h30d7dPattern, pub median: _1y24h30d7dPattern, pub min: _1y24h30d7dPattern, - pub p10: _1y24h30d7dPattern, - pub p25: _1y24h30d7dPattern, - pub p75: _1y24h30d7dPattern, - pub p90: _1y24h30d7dPattern, + pub pct10: _1y24h30d7dPattern, + pub pct25: _1y24h30d7dPattern, + pub pct75: _1y24h30d7dPattern, + pub pct90: _1y24h30d7dPattern, } -impl AverageHeightMaxMedianMinP10P25P75P90Pattern { +impl AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { @@ -2625,10 +2689,10 @@ impl AverageHeightMaxMedianMinP10P25P75P90Pattern { max: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "max")), median: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "median")), min: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "min")), - p10: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p10")), - p25: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p25")), - p75: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p75")), - p90: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p90")), + pct10: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p10")), + pct25: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p25")), + pct75: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p75")), + pct90: _1y24h30d7dPattern::new(client.clone(), _m(&acc, "p90")), } } } @@ -2687,6 +2751,32 @@ impl _10y2y3y4y5y6y8yPattern { } } +/// Pattern struct for repeated tree structure. +pub struct _1y24h30d7dBtcSatsUsdPattern { + pub _1y: BtcSatsUsdPattern, + pub _24h: BtcSatsUsdPattern, + pub _30d: BtcSatsUsdPattern, + pub _7d: BtcSatsUsdPattern, + pub btc: MetricPattern20, + pub sats: MetricPattern20, + pub usd: MetricPattern20, +} + +impl _1y24h30d7dBtcSatsUsdPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + _1y: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "1y")), + _24h: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "24h")), + _30d: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "30d")), + _7d: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "7d")), + btc: MetricPattern20::new(client.clone(), _m(&acc, "btc")), + sats: MetricPattern20::new(client.clone(), acc.clone()), + usd: MetricPattern20::new(client.clone(), _m(&acc, "usd")), + } + } +} + /// Pattern struct for repeated tree structure. pub struct ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern { pub activity: CoinblocksCoindaysSatblocksSatdaysSentPattern, @@ -2791,26 +2881,50 @@ impl ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern5 { } } +/// Pattern struct for repeated tree structure. +pub struct _1y24h30d7dBaseCumulativePattern { + pub _1y: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2, + pub _24h: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2, + pub _30d: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2, + pub _7d: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2, + pub base: BtcSatsUsdPattern, + pub cumulative: BtcSatsUsdPattern, +} + +impl _1y24h30d7dBaseCumulativePattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + _1y: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2::new(client.clone(), _m(&acc, "1y")), + _24h: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2::new(client.clone(), _m(&acc, "24h")), + _30d: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2::new(client.clone(), _m(&acc, "30d")), + _7d: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2::new(client.clone(), _m(&acc, "7d")), + base: BtcSatsUsdPattern::new(client.clone(), acc.clone()), + cumulative: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "cumulative")), + } + } +} + /// Pattern struct for repeated tree structure. pub struct BalanceBothReactivatedReceivingSendingPattern { - pub balance_decreased: AverageHeightMaxMedianMinP10P25P75P90Pattern, - pub balance_increased: AverageHeightMaxMedianMinP10P25P75P90Pattern, - pub both: AverageHeightMaxMedianMinP10P25P75P90Pattern, - pub reactivated: AverageHeightMaxMedianMinP10P25P75P90Pattern, - pub receiving: AverageHeightMaxMedianMinP10P25P75P90Pattern, - pub sending: AverageHeightMaxMedianMinP10P25P75P90Pattern, + pub balance_decreased: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, + pub balance_increased: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, + pub both: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, + pub reactivated: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, + pub receiving: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, + pub sending: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, } impl BalanceBothReactivatedReceivingSendingPattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - balance_decreased: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), _m(&acc, "balance_decreased")), - balance_increased: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), _m(&acc, "balance_increased")), - both: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), _m(&acc, "both")), - reactivated: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), _m(&acc, "reactivated")), - receiving: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), _m(&acc, "receiving")), - sending: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), _m(&acc, "sending")), + balance_decreased: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), _m(&acc, "balance_decreased")), + balance_increased: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), _m(&acc, "balance_increased")), + both: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), _m(&acc, "both")), + reactivated: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), _m(&acc, "reactivated")), + receiving: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), _m(&acc, "receiving")), + sending: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), _m(&acc, "sending")), } } } @@ -2821,7 +2935,7 @@ pub struct CoinblocksCoindaysSatblocksSatdaysSentPattern { pub coindays_destroyed: CumulativeHeightSumPattern, pub satblocks_destroyed: MetricPattern20, pub satdays_destroyed: MetricPattern20, - pub sent: BtcSatsUsdPattern2, + pub sent: BaseCumulativePattern, pub sent_14d_ema: BtcSatsUsdPattern, } @@ -2833,7 +2947,7 @@ impl CoinblocksCoindaysSatblocksSatdaysSentPattern { coindays_destroyed: CumulativeHeightSumPattern::new(client.clone(), _m(&acc, "coindays_destroyed")), satblocks_destroyed: MetricPattern20::new(client.clone(), _m(&acc, "satblocks_destroyed")), satdays_destroyed: MetricPattern20::new(client.clone(), _m(&acc, "satdays_destroyed")), - sent: BtcSatsUsdPattern2::new(client.clone(), _m(&acc, "sent")), + sent: BaseCumulativePattern::new(client.clone(), _m(&acc, "sent")), sent_14d_ema: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "sent_14d_ema")), } } @@ -2883,26 +2997,6 @@ impl _1y24h30d7dPattern2 { } } -/// Pattern struct for repeated tree structure. -pub struct BtcRollingSatsUsdPattern { - pub btc: MetricPattern20, - pub rolling: _1y24h30d7dPattern2, - pub sats: MetricPattern20, - pub usd: MetricPattern20, -} - -impl BtcRollingSatsUsdPattern { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - btc: MetricPattern20::new(client.clone(), _m(&acc, "btc")), - rolling: _1y24h30d7dPattern2::new(client.clone(), acc.clone()), - sats: MetricPattern20::new(client.clone(), acc.clone()), - usd: MetricPattern20::new(client.clone(), _m(&acc, "usd")), - } - } -} - /// Pattern struct for repeated tree structure. pub struct _1h24hBlockTxindexPattern { pub _1h: AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern, @@ -2962,55 +3056,19 @@ impl _30dHalvedTotalPattern { } /// Pattern struct for repeated tree structure. -pub struct BtcSatsUsdPattern2 { - pub btc: MetricPattern1, - pub sats: CumulativeHeightPattern, - pub usd: MetricPattern1, +pub struct BaseCumulativeSumPattern { + pub base: BtcSatsUsdPattern, + pub cumulative: BtcSatsUsdPattern, + pub sum: _1y24h30d7dPattern2, } -impl BtcSatsUsdPattern2 { +impl BaseCumulativeSumPattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - btc: MetricPattern1::new(client.clone(), _m(&acc, "btc")), - sats: CumulativeHeightPattern::new(client.clone(), acc.clone()), - usd: MetricPattern1::new(client.clone(), _m(&acc, "usd")), - } - } -} - -/// Pattern struct for repeated tree structure. -pub struct BtcSatsUsdPattern3 { - pub btc: MetricPattern1, - pub sats: CumulativeHeightRollingPattern, - pub usd: CumulativeHeightRollingPattern, -} - -impl BtcSatsUsdPattern3 { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - btc: MetricPattern1::new(client.clone(), _m(&acc, "btc")), - sats: CumulativeHeightRollingPattern::new(client.clone(), acc.clone()), - usd: CumulativeHeightRollingPattern::new(client.clone(), _m(&acc, "usd")), - } - } -} - -/// Pattern struct for repeated tree structure. -pub struct BtcSatsUsdPattern4 { - pub btc: MetricPattern1, - pub sats: CumulativeHeightSumPattern, - pub usd: CumulativeHeightSumPattern, -} - -impl BtcSatsUsdPattern4 { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - btc: MetricPattern1::new(client.clone(), _m(&acc, "btc")), - sats: CumulativeHeightSumPattern::new(client.clone(), acc.clone()), - usd: CumulativeHeightSumPattern::new(client.clone(), _m(&acc, "usd")), + base: BtcSatsUsdPattern::new(client.clone(), acc.clone()), + cumulative: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "cumulative")), + sum: _1y24h30d7dPattern2::new(client.clone(), _m(&acc, "sum")), } } } @@ -3069,24 +3127,6 @@ impl HistogramLineSignalPattern { } } -/// Pattern struct for repeated tree structure. -pub struct CumulativeHeightRollingPattern { - pub cumulative: MetricPattern1, - pub height: MetricPattern20, - pub rolling: AverageMaxMedianMinP10P25P75P90SumPattern, -} - -impl CumulativeHeightRollingPattern { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - cumulative: MetricPattern1::new(client.clone(), _m(&acc, "cumulative")), - height: MetricPattern20::new(client.clone(), acc.clone()), - rolling: AverageMaxMedianMinP10P25P75P90SumPattern::new(client.clone(), acc.clone()), - } - } -} - /// Pattern struct for repeated tree structure. pub struct CumulativeHeightSumPattern { pub cumulative: MetricPattern1, @@ -3121,10 +3161,26 @@ impl _30dCountPattern { } } +/// Pattern struct for repeated tree structure. +pub struct BaseCumulativePattern { + pub base: BtcSatsUsdPattern, + pub cumulative: BtcSatsUsdPattern, +} + +impl BaseCumulativePattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + base: BtcSatsUsdPattern::new(client.clone(), acc.clone()), + cumulative: BtcSatsUsdPattern::new(client.clone(), _m(&acc, "cumulative")), + } + } +} + /// Pattern struct for repeated tree structure. pub struct BaseRestPattern { pub base: MetricPattern20, - pub rest: AverageCumulativeMaxMedianMinP10P25P75P90SumPattern, + pub rest: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern, } impl BaseRestPattern { @@ -3132,7 +3188,23 @@ impl BaseRestPattern { pub fn new(client: Arc, acc: String) -> Self { Self { base: MetricPattern20::new(client.clone(), acc.clone()), - rest: AverageCumulativeMaxMedianMinP10P25P75P90SumPattern::new(client.clone(), acc.clone()), + rest: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern::new(client.clone(), acc.clone()), + } + } +} + +/// Pattern struct for repeated tree structure. +pub struct CumulativeHeightPattern { + pub cumulative: MetricPattern1, + pub height: MetricPattern20, +} + +impl CumulativeHeightPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + cumulative: MetricPattern1::new(client.clone(), _m(&acc, "cumulative")), + height: MetricPattern20::new(client.clone(), acc.clone()), } } } @@ -3201,22 +3273,6 @@ impl UtxoPattern { } } -/// Pattern struct for repeated tree structure. -pub struct CumulativeHeightPattern { - pub cumulative: MetricPattern1, - pub height: MetricPattern20, -} - -impl CumulativeHeightPattern { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - cumulative: MetricPattern1::new(client.clone(), _m(&acc, "cumulative")), - height: MetricPattern20::new(client.clone(), acc.clone()), - } - } -} - /// Pattern struct for repeated tree structure. pub struct RatioPattern2 { pub ratio: MetricPattern1, @@ -3284,11 +3340,11 @@ pub struct MetricsTree_Blocks { pub total_size: MetricPattern20, pub weight: MetricsTree_Blocks_Weight, pub count: MetricsTree_Blocks_Count, - pub interval: AverageHeightMaxMedianMinP10P25P75P90Pattern, + pub interval: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, pub halving: MetricsTree_Blocks_Halving, - pub vbytes: CumulativeHeightRollingPattern, - pub size: AverageCumulativeMaxMedianMinP10P25P75P90SumPattern, - pub fullness: AverageHeightMaxMedianMinP10P25P75P90Pattern, + pub vbytes: AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern, + pub size: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern, + pub fullness: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, } impl MetricsTree_Blocks { @@ -3300,11 +3356,11 @@ impl MetricsTree_Blocks { total_size: MetricPattern20::new(client.clone(), "total_size".to_string()), weight: MetricsTree_Blocks_Weight::new(client.clone(), format!("{base_path}_weight")), count: MetricsTree_Blocks_Count::new(client.clone(), format!("{base_path}_count")), - interval: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), "block_interval".to_string()), + interval: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), "block_interval".to_string()), halving: MetricsTree_Blocks_Halving::new(client.clone(), format!("{base_path}_halving")), - vbytes: CumulativeHeightRollingPattern::new(client.clone(), "block_vbytes".to_string()), - size: AverageCumulativeMaxMedianMinP10P25P75P90SumPattern::new(client.clone(), "block_size".to_string()), - fullness: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), "block_fullness".to_string()), + vbytes: AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern::new(client.clone(), "block_vbytes".to_string()), + size: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern::new(client.clone(), "block_size".to_string()), + fullness: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), "block_fullness".to_string()), } } } @@ -3404,11 +3460,11 @@ pub struct MetricsTree_Blocks_Weight { pub average: _1y24h30d7dPattern, pub min: _1y24h30d7dPattern, pub max: _1y24h30d7dPattern, - pub p10: _1y24h30d7dPattern, - pub p25: _1y24h30d7dPattern, + pub pct10: _1y24h30d7dPattern, + pub pct25: _1y24h30d7dPattern, pub median: _1y24h30d7dPattern, - pub p75: _1y24h30d7dPattern, - pub p90: _1y24h30d7dPattern, + pub pct75: _1y24h30d7dPattern, + pub pct90: _1y24h30d7dPattern, } impl MetricsTree_Blocks_Weight { @@ -3420,11 +3476,11 @@ impl MetricsTree_Blocks_Weight { average: _1y24h30d7dPattern::new(client.clone(), "block_weight_average".to_string()), min: _1y24h30d7dPattern::new(client.clone(), "block_weight_min".to_string()), max: _1y24h30d7dPattern::new(client.clone(), "block_weight_max".to_string()), - p10: _1y24h30d7dPattern::new(client.clone(), "block_weight_p10".to_string()), - p25: _1y24h30d7dPattern::new(client.clone(), "block_weight_p25".to_string()), + pct10: _1y24h30d7dPattern::new(client.clone(), "block_weight_p10".to_string()), + pct25: _1y24h30d7dPattern::new(client.clone(), "block_weight_p25".to_string()), median: _1y24h30d7dPattern::new(client.clone(), "block_weight_median".to_string()), - p75: _1y24h30d7dPattern::new(client.clone(), "block_weight_p75".to_string()), - p90: _1y24h30d7dPattern::new(client.clone(), "block_weight_p90".to_string()), + pct75: _1y24h30d7dPattern::new(client.clone(), "block_weight_p75".to_string()), + pct90: _1y24h30d7dPattern::new(client.clone(), "block_weight_p90".to_string()), } } } @@ -3568,14 +3624,14 @@ impl MetricsTree_Transactions { /// Metrics tree node. pub struct MetricsTree_Transactions_Count { - pub tx_count: CumulativeHeightRollingPattern, + pub tx_count: AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern, pub is_coinbase: MetricPattern21, } impl MetricsTree_Transactions_Count { pub fn new(client: Arc, base_path: String) -> Self { Self { - tx_count: CumulativeHeightRollingPattern::new(client.clone(), "tx_count".to_string()), + tx_count: AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern::new(client.clone(), "tx_count".to_string()), is_coinbase: MetricPattern21::new(client.clone(), "is_coinbase".to_string()), } } @@ -3634,8 +3690,8 @@ impl MetricsTree_Transactions_Versions { /// Metrics tree node. pub struct MetricsTree_Transactions_Volume { - pub sent_sum: BtcRollingSatsUsdPattern, - pub received_sum: BtcRollingSatsUsdPattern, + pub sent_sum: _1y24h30d7dBtcSatsUsdPattern, + pub received_sum: _1y24h30d7dBtcSatsUsdPattern, pub annualized_volume: BtcSatsUsdPattern, pub tx_per_sec: MetricPattern1, pub outputs_per_sec: MetricPattern1, @@ -3645,8 +3701,8 @@ pub struct MetricsTree_Transactions_Volume { impl MetricsTree_Transactions_Volume { pub fn new(client: Arc, base_path: String) -> Self { Self { - sent_sum: BtcRollingSatsUsdPattern::new(client.clone(), "sent_sum".to_string()), - received_sum: BtcRollingSatsUsdPattern::new(client.clone(), "received_sum".to_string()), + sent_sum: _1y24h30d7dBtcSatsUsdPattern::new(client.clone(), "sent_sum".to_string()), + received_sum: _1y24h30d7dBtcSatsUsdPattern::new(client.clone(), "received_sum".to_string()), annualized_volume: BtcSatsUsdPattern::new(client.clone(), "annualized_volume".to_string()), tx_per_sec: MetricPattern1::new(client.clone(), "tx_per_sec".to_string()), outputs_per_sec: MetricPattern1::new(client.clone(), "outputs_per_sec".to_string()), @@ -3803,6 +3859,7 @@ pub struct MetricsTree_Scripts { pub unknown_to_txindex: MetricPattern35, pub count: MetricsTree_Scripts_Count, pub value: MetricsTree_Scripts_Value, + pub adoption: MetricsTree_Scripts_Adoption, } impl MetricsTree_Scripts { @@ -3818,6 +3875,7 @@ impl MetricsTree_Scripts { unknown_to_txindex: MetricPattern35::new(client.clone(), "txindex".to_string()), count: MetricsTree_Scripts_Count::new(client.clone(), format!("{base_path}_count")), value: MetricsTree_Scripts_Value::new(client.clone(), format!("{base_path}_value")), + adoption: MetricsTree_Scripts_Adoption::new(client.clone(), format!("{base_path}_adoption")), } } } @@ -3837,8 +3895,6 @@ pub struct MetricsTree_Scripts_Count { pub emptyoutput: CumulativeHeightSumPattern, pub unknownoutput: CumulativeHeightSumPattern, pub segwit: CumulativeHeightSumPattern, - pub taproot_adoption: MetricPattern1, - pub segwit_adoption: MetricPattern1, } impl MetricsTree_Scripts_Count { @@ -3857,21 +3913,34 @@ impl MetricsTree_Scripts_Count { emptyoutput: CumulativeHeightSumPattern::new(client.clone(), "emptyoutput_count".to_string()), unknownoutput: CumulativeHeightSumPattern::new(client.clone(), "unknownoutput_count".to_string()), segwit: CumulativeHeightSumPattern::new(client.clone(), "segwit_count".to_string()), - taproot_adoption: MetricPattern1::new(client.clone(), "taproot_adoption".to_string()), - segwit_adoption: MetricPattern1::new(client.clone(), "segwit_adoption".to_string()), } } } /// Metrics tree node. pub struct MetricsTree_Scripts_Value { - pub opreturn: BtcSatsUsdPattern3, + pub opreturn: _1y24h30d7dBaseCumulativePattern, } impl MetricsTree_Scripts_Value { pub fn new(client: Arc, base_path: String) -> Self { Self { - opreturn: BtcSatsUsdPattern3::new(client.clone(), "opreturn_value".to_string()), + opreturn: _1y24h30d7dBaseCumulativePattern::new(client.clone(), "opreturn_value".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Scripts_Adoption { + pub taproot: MetricPattern1, + pub segwit: MetricPattern1, +} + +impl MetricsTree_Scripts_Adoption { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + taproot: MetricPattern1::new(client.clone(), "taproot_adoption".to_string()), + segwit: MetricPattern1::new(client.clone(), "segwit_adoption".to_string()), } } } @@ -3893,10 +3962,10 @@ impl MetricsTree_Mining { /// Metrics tree node. pub struct MetricsTree_Mining_Rewards { - pub coinbase: BtcSatsUsdPattern3, - pub subsidy: BtcSatsUsdPattern3, - pub fees: BtcSatsUsdPattern3, - pub unclaimed_rewards: BtcSatsUsdPattern4, + pub coinbase: _1y24h30d7dBaseCumulativePattern, + pub subsidy: _1y24h30d7dBaseCumulativePattern, + pub fees: _1y24h30d7dBaseCumulativePattern, + pub unclaimed_rewards: BaseCumulativeSumPattern, pub fee_dominance: MetricPattern1, pub fee_dominance_24h: MetricPattern1, pub fee_dominance_7d: MetricPattern1, @@ -3913,10 +3982,10 @@ pub struct MetricsTree_Mining_Rewards { impl MetricsTree_Mining_Rewards { pub fn new(client: Arc, base_path: String) -> Self { Self { - coinbase: BtcSatsUsdPattern3::new(client.clone(), "coinbase".to_string()), - subsidy: BtcSatsUsdPattern3::new(client.clone(), "subsidy".to_string()), - fees: BtcSatsUsdPattern3::new(client.clone(), "fees".to_string()), - unclaimed_rewards: BtcSatsUsdPattern4::new(client.clone(), "unclaimed_rewards".to_string()), + coinbase: _1y24h30d7dBaseCumulativePattern::new(client.clone(), "coinbase".to_string()), + subsidy: _1y24h30d7dBaseCumulativePattern::new(client.clone(), "subsidy".to_string()), + fees: _1y24h30d7dBaseCumulativePattern::new(client.clone(), "fees".to_string()), + unclaimed_rewards: BaseCumulativeSumPattern::new(client.clone(), "unclaimed_rewards".to_string()), fee_dominance: MetricPattern1::new(client.clone(), "fee_dominance".to_string()), fee_dominance_24h: MetricPattern1::new(client.clone(), "fee_dominance_24h".to_string()), fee_dominance_7d: MetricPattern1::new(client.clone(), "fee_dominance_7d".to_string()), @@ -4864,7 +4933,7 @@ impl MetricsTree_Market_Ath { /// Metrics tree node. pub struct MetricsTree_Market_Lookback { - pub _1d: SatsUsdPattern, + pub _24h: SatsUsdPattern, pub _1w: SatsUsdPattern, pub _1m: SatsUsdPattern, pub _3m: SatsUsdPattern, @@ -4882,7 +4951,7 @@ pub struct MetricsTree_Market_Lookback { impl MetricsTree_Market_Lookback { pub fn new(client: Arc, base_path: String) -> Self { Self { - _1d: SatsUsdPattern::new(client.clone(), "price_1d_ago".to_string()), + _24h: SatsUsdPattern::new(client.clone(), "price_24h_ago".to_string()), _1w: SatsUsdPattern::new(client.clone(), "price_1w_ago".to_string()), _1m: SatsUsdPattern::new(client.clone(), "price_1m_ago".to_string()), _3m: SatsUsdPattern::new(client.clone(), "price_3m_ago".to_string()), @@ -4930,7 +4999,7 @@ impl MetricsTree_Market_Returns { /// Metrics tree node. pub struct MetricsTree_Market_Returns_PriceReturns { - pub _1d: MetricPattern1, + pub _24h: MetricPattern1, pub _1w: MetricPattern1, pub _1m: MetricPattern1, pub _3m: MetricPattern1, @@ -4948,7 +5017,7 @@ pub struct MetricsTree_Market_Returns_PriceReturns { impl MetricsTree_Market_Returns_PriceReturns { pub fn new(client: Arc, base_path: String) -> Self { Self { - _1d: MetricPattern1::new(client.clone(), "1d_price_returns".to_string()), + _24h: MetricPattern1::new(client.clone(), "24h_price_returns".to_string()), _1w: MetricPattern1::new(client.clone(), "1w_price_returns".to_string()), _1m: MetricPattern1::new(client.clone(), "1m_price_returns".to_string()), _3m: MetricPattern1::new(client.clone(), "3m_price_returns".to_string()), @@ -6824,29 +6893,29 @@ impl MetricsTree_Distribution_NewAddrCount { /// Metrics tree node. pub struct MetricsTree_Distribution_GrowthRate { - pub all: AverageHeightMaxMedianMinP10P25P75P90Pattern, - pub p2pk65: AverageHeightMaxMedianMinP10P25P75P90Pattern, - pub p2pk33: AverageHeightMaxMedianMinP10P25P75P90Pattern, - pub p2pkh: AverageHeightMaxMedianMinP10P25P75P90Pattern, - pub p2sh: AverageHeightMaxMedianMinP10P25P75P90Pattern, - pub p2wpkh: AverageHeightMaxMedianMinP10P25P75P90Pattern, - pub p2wsh: AverageHeightMaxMedianMinP10P25P75P90Pattern, - pub p2tr: AverageHeightMaxMedianMinP10P25P75P90Pattern, - pub p2a: AverageHeightMaxMedianMinP10P25P75P90Pattern, + pub all: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, + pub p2pk65: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, + pub p2pk33: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, + pub p2pkh: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, + pub p2sh: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, + pub p2wpkh: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, + pub p2wsh: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, + pub p2tr: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, + pub p2a: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern, } impl MetricsTree_Distribution_GrowthRate { pub fn new(client: Arc, base_path: String) -> Self { Self { - all: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), "growth_rate".to_string()), - p2pk65: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), "p2pk65_growth_rate".to_string()), - p2pk33: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), "p2pk33_growth_rate".to_string()), - p2pkh: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), "p2pkh_growth_rate".to_string()), - p2sh: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), "p2sh_growth_rate".to_string()), - p2wpkh: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), "p2wpkh_growth_rate".to_string()), - p2wsh: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), "p2wsh_growth_rate".to_string()), - p2tr: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), "p2tr_growth_rate".to_string()), - p2a: AverageHeightMaxMedianMinP10P25P75P90Pattern::new(client.clone(), "p2a_growth_rate".to_string()), + all: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), "growth_rate".to_string()), + p2pk65: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), "p2pk65_growth_rate".to_string()), + p2pk33: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), "p2pk33_growth_rate".to_string()), + p2pkh: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), "p2pkh_growth_rate".to_string()), + p2sh: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), "p2sh_growth_rate".to_string()), + p2wpkh: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), "p2wpkh_growth_rate".to_string()), + p2wsh: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), "p2wsh_growth_rate".to_string()), + p2tr: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), "p2tr_growth_rate".to_string()), + p2a: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern::new(client.clone(), "p2a_growth_rate".to_string()), } } } @@ -6880,15 +6949,15 @@ impl MetricsTree_Supply { /// Metrics tree node. pub struct MetricsTree_Supply_Burned { - pub opreturn: BtcSatsUsdPattern4, - pub unspendable: BtcSatsUsdPattern4, + pub opreturn: BaseCumulativeSumPattern, + pub unspendable: BaseCumulativeSumPattern, } impl MetricsTree_Supply_Burned { pub fn new(client: Arc, base_path: String) -> Self { Self { - opreturn: BtcSatsUsdPattern4::new(client.clone(), "opreturn_supply".to_string()), - unspendable: BtcSatsUsdPattern4::new(client.clone(), "unspendable_supply".to_string()), + opreturn: BaseCumulativeSumPattern::new(client.clone(), "opreturn_supply".to_string()), + unspendable: BaseCumulativeSumPattern::new(client.clone(), "unspendable_supply".to_string()), } } } diff --git a/crates/brk_computer/src/cointime/cap/compute.rs b/crates/brk_computer/src/cointime/cap/compute.rs index 4faf90a02..7e3cf618b 100644 --- a/crates/brk_computer/src/cointime/cap/compute.rs +++ b/crates/brk_computer/src/cointime/cap/compute.rs @@ -36,7 +36,7 @@ impl Vecs { self.thermo_cap.height.compute_transform( starting_indexes.height, - &mining.rewards.subsidy.usd.cumulative.height, + &mining.rewards.subsidy.cumulative.usd.height, |(i, v, ..)| (i, v), exit, )?; diff --git a/crates/brk_computer/src/distribution/compute/block_loop.rs b/crates/brk_computer/src/distribution/compute/block_loop.rs index f9a3c647d..caca96ac9 100644 --- a/crates/brk_computer/src/distribution/compute/block_loop.rs +++ b/crates/brk_computer/src/distribution/compute/block_loop.rs @@ -30,8 +30,8 @@ use super::{ vecs::Vecs, }, BIP30_DUPLICATE_HEIGHT_1, BIP30_DUPLICATE_HEIGHT_2, BIP30_ORIGINAL_HEIGHT_1, - BIP30_ORIGINAL_HEIGHT_2, ComputeContext, FLUSH_INTERVAL, TxInReaders, TxOutReaders, - IndexToTxIndexBuf, VecsReaders, + BIP30_ORIGINAL_HEIGHT_2, ComputeContext, FLUSH_INTERVAL, IndexToTxIndexBuf, TxInReaders, + TxOutReaders, VecsReaders, }; /// Process all blocks from starting_height to last_height. @@ -278,7 +278,7 @@ pub(crate) fn process_blocks( let outputs_handle = scope.spawn(|| { // Process outputs (receive) process_outputs( - &txoutindex_to_txindex, + txoutindex_to_txindex, &txoutdata_vec, &first_addressindexes, &cache, diff --git a/crates/brk_computer/src/distribution/metrics/activity.rs b/crates/brk_computer/src/distribution/metrics/activity.rs index 6062a01db..cdeab7bec 100644 --- a/crates/brk_computer/src/distribution/metrics/activity.rs +++ b/crates/brk_computer/src/distribution/metrics/activity.rs @@ -82,6 +82,7 @@ impl ActivityMetrics { /// Get minimum length across height-indexed vectors. pub(crate) fn min_len(&self) -> usize { self.sent + .base .sats .height .len() @@ -97,7 +98,7 @@ impl ActivityMetrics { satblocks_destroyed: Sats, satdays_destroyed: Sats, ) -> Result<()> { - self.sent.sats.height.truncate_push(height, sent)?; + self.sent.base.sats.height.truncate_push(height, sent)?; self.satblocks_destroyed .truncate_push(height, satblocks_destroyed)?; self.satdays_destroyed @@ -108,7 +109,7 @@ impl ActivityMetrics { /// Returns a parallel iterator over all vecs for parallel writing. pub(crate) fn par_iter_mut(&mut self) -> impl ParallelIterator { vec![ - &mut self.sent.sats.height as &mut dyn AnyStoredVec, + &mut self.sent.base.sats.height as &mut dyn AnyStoredVec, &mut self.satblocks_destroyed as &mut dyn AnyStoredVec, &mut self.satdays_destroyed as &mut dyn AnyStoredVec, ] @@ -128,11 +129,11 @@ impl ActivityMetrics { others: &[&Self], exit: &Exit, ) -> Result<()> { - self.sent.sats.height.compute_sum_of_others( + self.sent.base.sats.height.compute_sum_of_others( starting_indexes.height, &others .iter() - .map(|v| &v.sent.sats.height) + .map(|v| &v.sent.base.sats.height) .collect::>(), exit, )?; @@ -168,8 +169,8 @@ impl ActivityMetrics { self.sent_14d_ema.compute_rolling_average( starting_indexes.height, &blocks.count.height_2w_ago, - &self.sent.sats.height, - &self.sent.usd.height, + &self.sent.base.sats.height, + &self.sent.base.usd.height, exit, )?; diff --git a/crates/brk_computer/src/distribution/metrics/realized/base.rs b/crates/brk_computer/src/distribution/metrics/realized/base.rs index a0318012e..ccc3937d7 100644 --- a/crates/brk_computer/src/distribution/metrics/realized/base.rs +++ b/crates/brk_computer/src/distribution/metrics/realized/base.rs @@ -582,8 +582,8 @@ impl RealizedBase { .min(self.loss_value_created.height.len()) .min(self.loss_value_destroyed.height.len()) .min(self.peak_regret.height.len()) - .min(self.sent_in_profit.sats.height.len()) - .min(self.sent_in_loss.sats.height.len()) + .min(self.sent_in_profit.base.sats.height.len()) + .min(self.sent_in_loss.base.sats.height.len()) } /// Push realized state values to height-indexed vectors. @@ -619,10 +619,12 @@ impl RealizedBase { .height .truncate_push(height, state.peak_regret().to_dollars())?; 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())?; @@ -644,8 +646,8 @@ impl RealizedBase { &mut self.loss_value_created.height, &mut self.loss_value_destroyed.height, &mut self.peak_regret.height, - &mut self.sent_in_profit.sats.height, - &mut self.sent_in_loss.sats.height, + &mut self.sent_in_profit.base.sats.height, + &mut self.sent_in_loss.base.sats.height, ] } @@ -778,19 +780,19 @@ impl RealizedBase { .collect::>(), exit, )?; - self.sent_in_profit.sats.height.compute_sum_of_others( + self.sent_in_profit.base.sats.height.compute_sum_of_others( starting_indexes.height, &others .iter() - .map(|v| &v.sent_in_profit.sats.height) + .map(|v| &v.sent_in_profit.base.sats.height) .collect::>(), exit, )?; - self.sent_in_loss.sats.height.compute_sum_of_others( + self.sent_in_loss.base.sats.height.compute_sum_of_others( starting_indexes.height, &others .iter() - .map(|v| &v.sent_in_loss.sats.height) + .map(|v| &v.sent_in_loss.base.sats.height) .collect::>(), exit, )?; @@ -1045,15 +1047,15 @@ impl RealizedBase { self.sent_in_profit_14d_ema.compute_rolling_average( starting_indexes.height, &blocks.count.height_2w_ago, - &self.sent_in_profit.sats.height, - &self.sent_in_profit.usd.height, + &self.sent_in_profit.base.sats.height, + &self.sent_in_profit.base.usd.height, exit, )?; self.sent_in_loss_14d_ema.compute_rolling_average( starting_indexes.height, &blocks.count.height_2w_ago, - &self.sent_in_loss.sats.height, - &self.sent_in_loss.usd.height, + &self.sent_in_loss.base.sats.height, + &self.sent_in_loss.base.usd.height, exit, )?; diff --git a/crates/brk_computer/src/distribution/metrics/supply.rs b/crates/brk_computer/src/distribution/metrics/supply.rs index 8a87d522f..46778bc27 100644 --- a/crates/brk_computer/src/distribution/metrics/supply.rs +++ b/crates/brk_computer/src/distribution/metrics/supply.rs @@ -66,8 +66,8 @@ impl SupplyMetrics { /// Returns a parallel iterator over all vecs for parallel writing. pub(crate) fn par_iter_mut(&mut self) -> impl ParallelIterator { vec![ - &mut self.total.sats.height as &mut dyn AnyStoredVec, - &mut self.total.usd.height as &mut dyn AnyStoredVec, + &mut self.total.base.sats.height as &mut dyn AnyStoredVec, + &mut self.total.base.usd.height as &mut dyn AnyStoredVec, ] .into_par_iter() } diff --git a/crates/brk_computer/src/distribution/metrics/unrealized/base.rs b/crates/brk_computer/src/distribution/metrics/unrealized/base.rs index 7b9310400..ff719e474 100644 --- a/crates/brk_computer/src/distribution/metrics/unrealized/base.rs +++ b/crates/brk_computer/src/distribution/metrics/unrealized/base.rs @@ -236,10 +236,10 @@ impl UnrealizedBase { pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> { vec![ - &mut self.supply_in_profit.sats.height as &mut dyn AnyStoredVec, - &mut self.supply_in_profit.usd.height as &mut dyn AnyStoredVec, - &mut self.supply_in_loss.sats.height as &mut dyn AnyStoredVec, - &mut self.supply_in_loss.usd.height as &mut dyn AnyStoredVec, + &mut self.supply_in_profit.base.sats.height as &mut dyn AnyStoredVec, + &mut self.supply_in_profit.base.usd.height as &mut dyn AnyStoredVec, + &mut self.supply_in_loss.base.sats.height as &mut dyn AnyStoredVec, + &mut self.supply_in_loss.base.usd.height as &mut dyn AnyStoredVec, &mut self.unrealized_profit.height, &mut self.unrealized_loss.height, &mut self.invested_capital_in_profit.height, diff --git a/crates/brk_computer/src/internal/distribution_stats.rs b/crates/brk_computer/src/internal/distribution_stats.rs index 62e5e4821..a854c35f2 100644 --- a/crates/brk_computer/src/internal/distribution_stats.rs +++ b/crates/brk_computer/src/internal/distribution_stats.rs @@ -9,11 +9,11 @@ pub struct DistributionStats pub average: A, pub min: B, pub max: C, - pub p10: D, - pub p25: E, + pub pct10: D, + pub pct25: E, pub median: F, - pub p75: G, - pub p90: H, + pub pct75: G, + pub pct90: H, } impl DistributionStats { @@ -22,11 +22,11 @@ impl DistributionStats { f(&mut self.average)?; f(&mut self.min)?; f(&mut self.max)?; - f(&mut self.p10)?; - f(&mut self.p25)?; + f(&mut self.pct10)?; + f(&mut self.pct25)?; f(&mut self.median)?; - f(&mut self.p75)?; - f(&mut self.p90)?; + f(&mut self.pct75)?; + f(&mut self.pct90)?; Ok(()) } @@ -35,11 +35,11 @@ impl DistributionStats { f(&self.average) .min(f(&self.min)) .min(f(&self.max)) - .min(f(&self.p10)) - .min(f(&self.p25)) + .min(f(&self.pct10)) + .min(f(&self.pct25)) .min(f(&self.median)) - .min(f(&self.p75)) - .min(f(&self.p90)) + .min(f(&self.pct75)) + .min(f(&self.pct90)) } } diff --git a/crates/brk_computer/src/internal/multi/from_height/by_unit/mod.rs b/crates/brk_computer/src/internal/multi/from_height/by_unit/mod.rs new file mode 100644 index 000000000..795f30620 --- /dev/null +++ b/crates/brk_computer/src/internal/multi/from_height/by_unit/mod.rs @@ -0,0 +1,46 @@ +mod rolling_full; +mod rolling_sum; +mod windows; + +use brk_error::Result; +use brk_traversable::Traversable; +use brk_types::{Bitcoin, Dollars, Sats, Version}; +use vecdb::{Database, ReadableCloneableVec, Rw, StorageMode}; + +use crate::{ + indexes, + internal::{ComputedFromHeightLast, LazyFromHeightLast, SatsToBitcoin}, +}; + +pub use rolling_full::*; +pub use rolling_sum::*; + +#[derive(Traversable)] +pub struct ByUnit { + pub sats: ComputedFromHeightLast, + pub btc: LazyFromHeightLast, + pub usd: ComputedFromHeightLast, +} + +impl ByUnit { + pub(crate) fn forced_import( + db: &Database, + name: &str, + version: Version, + indexes: &indexes::Vecs, + ) -> Result { + let sats = ComputedFromHeightLast::forced_import(db, name, version, indexes)?; + + let btc = LazyFromHeightLast::from_computed::( + &format!("{name}_btc"), + version, + sats.height.read_only_boxed_clone(), + &sats, + ); + + let usd = + ComputedFromHeightLast::forced_import(db, &format!("{name}_usd"), version, indexes)?; + + Ok(Self { sats, btc, usd }) + } +} diff --git a/crates/brk_computer/src/internal/multi/from_height/by_unit/rolling_full.rs b/crates/brk_computer/src/internal/multi/from_height/by_unit/rolling_full.rs new file mode 100644 index 000000000..d870fc473 --- /dev/null +++ b/crates/brk_computer/src/internal/multi/from_height/by_unit/rolling_full.rs @@ -0,0 +1,116 @@ +use brk_error::Result; +use brk_traversable::Traversable; +use brk_types::{Dollars, Height, Sats, Version}; +use derive_more::{Deref, DerefMut}; +use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode}; + +use crate::{ + indexes, + internal::{ByUnit, DistributionStats, WindowStarts, Windows}, + traits::compute_rolling_distribution_from_starts, +}; + +/// One window slot: sum + 8 distribution stats, each a ByUnit. +/// +/// Tree: `sum.sats.height`, `average.sats.height`, etc. +#[derive(Traversable)] +pub struct RollingFullSlot { + pub sum: ByUnit, + #[traversable(flatten)] + pub distribution: DistributionStats>, +} + +impl RollingFullSlot { + pub(crate) fn forced_import( + db: &Database, + name: &str, + version: Version, + indexes: &indexes::Vecs, + ) -> Result { + Ok(Self { + sum: ByUnit::forced_import(db, &format!("{name}_sum"), version, indexes)?, + distribution: DistributionStats { + average: ByUnit::forced_import(db, &format!("{name}_average"), version, indexes)?, + min: ByUnit::forced_import(db, &format!("{name}_min"), version, indexes)?, + max: ByUnit::forced_import(db, &format!("{name}_max"), version, indexes)?, + pct10: ByUnit::forced_import(db, &format!("{name}_p10"), version, indexes)?, + pct25: ByUnit::forced_import(db, &format!("{name}_p25"), version, indexes)?, + median: ByUnit::forced_import(db, &format!("{name}_median"), version, indexes)?, + pct75: ByUnit::forced_import(db, &format!("{name}_p75"), version, indexes)?, + pct90: ByUnit::forced_import(db, &format!("{name}_p90"), version, indexes)?, + }, + }) + } + + pub(crate) fn compute( + &mut self, + max_from: Height, + starts: &impl ReadableVec, + sats_source: &impl ReadableVec, + usd_source: &impl ReadableVec, + exit: &Exit, + ) -> Result<()> { + self.sum.sats.height.compute_rolling_sum(max_from, starts, sats_source, exit)?; + self.sum.usd.height.compute_rolling_sum(max_from, starts, usd_source, exit)?; + + let d = &mut self.distribution; + + compute_rolling_distribution_from_starts( + max_from, starts, sats_source, + &mut d.average.sats.height, &mut d.min.sats.height, + &mut d.max.sats.height, &mut d.pct10.sats.height, + &mut d.pct25.sats.height, &mut d.median.sats.height, + &mut d.pct75.sats.height, &mut d.pct90.sats.height, exit, + )?; + + compute_rolling_distribution_from_starts( + max_from, starts, usd_source, + &mut d.average.usd.height, &mut d.min.usd.height, + &mut d.max.usd.height, &mut d.pct10.usd.height, + &mut d.pct25.usd.height, &mut d.median.usd.height, + &mut d.pct75.usd.height, &mut d.pct90.usd.height, exit, + )?; + + Ok(()) + } +} + +/// Rolling sum + distribution across 4 windows, window-first. +/// +/// Tree: `_24h.sum.sats.height`, `_24h.average.sats.height`, etc. +#[derive(Deref, DerefMut, Traversable)] +#[traversable(transparent)] +pub struct RollingFullByUnit(pub Windows>); + +const VERSION: Version = Version::ZERO; + +impl RollingFullByUnit { + pub(crate) fn forced_import( + db: &Database, + name: &str, + version: Version, + indexes: &indexes::Vecs, + ) -> Result { + let v = version + VERSION; + Ok(Self(Windows { + _24h: RollingFullSlot::forced_import(db, &format!("{name}_24h"), v, indexes)?, + _7d: RollingFullSlot::forced_import(db, &format!("{name}_7d"), v, indexes)?, + _30d: RollingFullSlot::forced_import(db, &format!("{name}_30d"), v, indexes)?, + _1y: RollingFullSlot::forced_import(db, &format!("{name}_1y"), v, indexes)?, + })) + } + + pub(crate) fn compute( + &mut self, + max_from: Height, + windows: &WindowStarts<'_>, + sats_source: &impl ReadableVec, + usd_source: &impl ReadableVec, + exit: &Exit, + ) -> Result<()> { + for (slot, starts) in self.0.as_mut_array().into_iter().zip(windows.as_array()) { + slot.compute(max_from, starts, sats_source, usd_source, exit)?; + } + Ok(()) + } +} diff --git a/crates/brk_computer/src/internal/multi/from_height/by_unit/rolling_sum.rs b/crates/brk_computer/src/internal/multi/from_height/by_unit/rolling_sum.rs new file mode 100644 index 000000000..5bcd52534 --- /dev/null +++ b/crates/brk_computer/src/internal/multi/from_height/by_unit/rolling_sum.rs @@ -0,0 +1,46 @@ +use brk_error::Result; +use brk_traversable::Traversable; +use brk_types::{Dollars, Height, Sats, Version}; +use derive_more::{Deref, DerefMut}; +use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode}; + +use crate::{ + indexes, + internal::{ByUnit, WindowStarts, Windows}, +}; + +/// Rolling sum only, window-first then unit. +/// +/// Tree: `_24h.sats.height`, `_24h.btc.height`, etc. +#[derive(Deref, DerefMut, Traversable)] +#[traversable(transparent)] +pub struct RollingSumByUnit(pub Windows>); + +const VERSION: Version = Version::ZERO; + +impl RollingSumByUnit { + pub(crate) fn forced_import( + db: &Database, + name: &str, + version: Version, + indexes: &indexes::Vecs, + ) -> Result { + let v = version + VERSION; + Ok(Self(Windows::::forced_import(db, &format!("{name}_sum"), v, indexes)?)) + } + + pub(crate) fn compute_rolling_sum( + &mut self, + max_from: Height, + windows: &WindowStarts<'_>, + sats_source: &impl ReadableVec, + usd_source: &impl ReadableVec, + exit: &Exit, + ) -> Result<()> { + for (w, starts) in self.0.as_mut_array().into_iter().zip(windows.as_array()) { + w.sats.height.compute_rolling_sum(max_from, starts, sats_source, exit)?; + w.usd.height.compute_rolling_sum(max_from, starts, usd_source, exit)?; + } + Ok(()) + } +} diff --git a/crates/brk_computer/src/internal/multi/from_height/by_unit/windows.rs b/crates/brk_computer/src/internal/multi/from_height/by_unit/windows.rs new file mode 100644 index 000000000..4c2a142fc --- /dev/null +++ b/crates/brk_computer/src/internal/multi/from_height/by_unit/windows.rs @@ -0,0 +1,24 @@ +use brk_error::Result; +use brk_types::Version; +use vecdb::Database; + +use crate::{ + indexes, + internal::{ByUnit, Windows}, +}; + +impl Windows { + pub(crate) fn forced_import( + db: &Database, + name: &str, + version: Version, + indexes: &indexes::Vecs, + ) -> Result { + Ok(Self { + _24h: ByUnit::forced_import(db, &format!("{name}_24h"), version, indexes)?, + _7d: ByUnit::forced_import(db, &format!("{name}_7d"), version, indexes)?, + _30d: ByUnit::forced_import(db, &format!("{name}_30d"), version, indexes)?, + _1y: ByUnit::forced_import(db, &format!("{name}_1y"), version, indexes)?, + }) + } +} diff --git a/crates/brk_computer/src/internal/multi/from_height/cumulative_rolling_full.rs b/crates/brk_computer/src/internal/multi/from_height/cumulative_rolling_full.rs index c6b8d3b5a..7e8d1e4f2 100644 --- a/crates/brk_computer/src/internal/multi/from_height/cumulative_rolling_full.rs +++ b/crates/brk_computer/src/internal/multi/from_height/cumulative_rolling_full.rs @@ -23,6 +23,7 @@ where { pub height: M::Stored>>, pub cumulative: ComputedFromHeightLast, + #[traversable(flatten)] pub rolling: RollingFull, } diff --git a/crates/brk_computer/src/internal/multi/from_height/mod.rs b/crates/brk_computer/src/internal/multi/from_height/mod.rs index 934801e09..96d904563 100644 --- a/crates/brk_computer/src/internal/multi/from_height/mod.rs +++ b/crates/brk_computer/src/internal/multi/from_height/mod.rs @@ -1,3 +1,4 @@ +mod by_unit; mod constant; mod cumulative; mod cumulative_rolling_full; @@ -21,6 +22,7 @@ mod value_lazy_computed_cumulative; mod value_lazy_last; mod value_sum_cumulative; +pub use by_unit::*; pub use constant::*; pub use cumulative::*; pub use cumulative_rolling_full::*; diff --git a/crates/brk_computer/src/internal/multi/from_height/stored_value_last.rs b/crates/brk_computer/src/internal/multi/from_height/stored_value_last.rs index 538c56fd1..263f0b9bd 100644 --- a/crates/brk_computer/src/internal/multi/from_height/stored_value_last.rs +++ b/crates/brk_computer/src/internal/multi/from_height/stored_value_last.rs @@ -1,26 +1,22 @@ -//! Stored value type for Last pattern from Height. -//! -//! Both sats and USD are stored eagerly at the height level. -//! Used for rolling-window sums where USD = sum(usd_per_block), -//! NOT sats * current_price. - use brk_error::Result; use brk_traversable::Traversable; -use brk_types::{Bitcoin, Dollars, Height, Sats, Version}; -use vecdb::{Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode}; +use brk_types::{Dollars, Height, Sats, Version}; +use derive_more::{Deref, DerefMut}; +use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode}; use crate::{ indexes, - internal::{ComputedFromHeightLast, LazyFromHeightLast, SatsToBitcoin}, + internal::ByUnit, }; const VERSION: Version = Version::ZERO; -#[derive(Traversable)] +#[derive(Deref, DerefMut, Traversable)] +#[traversable(transparent)] pub struct StoredValueFromHeightLast { - pub sats: ComputedFromHeightLast, - pub btc: LazyFromHeightLast, - pub usd: ComputedFromHeightLast, + #[deref] + #[deref_mut] + pub base: ByUnit, } impl StoredValueFromHeightLast { @@ -31,19 +27,9 @@ impl StoredValueFromHeightLast { indexes: &indexes::Vecs, ) -> Result { let v = version + VERSION; - - let sats = ComputedFromHeightLast::forced_import(db, name, v, indexes)?; - - let btc = LazyFromHeightLast::from_computed::( - &format!("{name}_btc"), - v, - sats.height.read_only_boxed_clone(), - &sats, - ); - - let usd = ComputedFromHeightLast::forced_import(db, &format!("{name}_usd"), v, indexes)?; - - Ok(Self { sats, btc, usd }) + Ok(Self { + base: ByUnit::forced_import(db, name, v, indexes)?, + }) } pub(crate) fn compute_rolling_sum( @@ -54,10 +40,12 @@ impl StoredValueFromHeightLast { usd_source: &impl ReadableVec, exit: &Exit, ) -> Result<()> { - self.sats + self.base + .sats .height .compute_rolling_sum(max_from, window_starts, sats_source, exit)?; - self.usd + self.base + .usd .height .compute_rolling_sum(max_from, window_starts, usd_source, exit)?; Ok(()) diff --git a/crates/brk_computer/src/internal/multi/from_height/value_ema.rs b/crates/brk_computer/src/internal/multi/from_height/value_ema.rs index 72faca466..75869d6a4 100644 --- a/crates/brk_computer/src/internal/multi/from_height/value_ema.rs +++ b/crates/brk_computer/src/internal/multi/from_height/value_ema.rs @@ -1,23 +1,22 @@ -//! Rolling average values from Height - stores sats and dollars, btc is lazy. - use brk_error::Result; use brk_traversable::Traversable; -use brk_types::{Bitcoin, Dollars, Height, Sats, Version}; -use vecdb::{Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode}; +use brk_types::{Dollars, Height, Sats, Version}; +use derive_more::{Deref, DerefMut}; +use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode}; use crate::{ indexes, - internal::{ComputedFromHeightLast, LazyFromHeightLast, SatsToBitcoin}, + internal::ByUnit, }; const VERSION: Version = Version::ZERO; -/// Rolling average values indexed by height - sats (stored), btc (lazy), usd (stored). -#[derive(Traversable)] +#[derive(Deref, DerefMut, Traversable)] +#[traversable(transparent)] pub struct ValueEmaFromHeight { - pub sats: ComputedFromHeightLast, - pub btc: LazyFromHeightLast, - pub usd: ComputedFromHeightLast, + #[deref] + #[deref_mut] + pub base: ByUnit, } impl ValueEmaFromHeight { @@ -28,27 +27,11 @@ impl ValueEmaFromHeight { indexes: &indexes::Vecs, ) -> Result { let v = version + VERSION; - - let sats = ComputedFromHeightLast::forced_import(db, name, v, indexes)?; - - let btc = LazyFromHeightLast::from_computed::( - &format!("{name}_btc"), - v, - sats.height.read_only_boxed_clone(), - &sats, - ); - - let usd = ComputedFromHeightLast::forced_import( - db, - &format!("{name}_usd"), - v, - indexes, - )?; - - Ok(Self { sats, btc, usd }) + Ok(Self { + base: ByUnit::forced_import(db, name, v, indexes)?, + }) } - /// Compute rolling average for both sats and dollars in one call. pub(crate) fn compute_rolling_average( &mut self, starting_height: Height, @@ -57,10 +40,12 @@ impl ValueEmaFromHeight { dollars_source: &(impl ReadableVec + Sync), exit: &Exit, ) -> Result<()> { - self.sats + self.base + .sats .height .compute_rolling_average(starting_height, window_starts, sats_source, exit)?; - self.usd + self.base + .usd .height .compute_rolling_average(starting_height, window_starts, dollars_source, exit)?; Ok(()) diff --git a/crates/brk_computer/src/internal/multi/from_height/value_full.rs b/crates/brk_computer/src/internal/multi/from_height/value_full.rs index c4c466f4c..8f486c1aa 100644 --- a/crates/brk_computer/src/internal/multi/from_height/value_full.rs +++ b/crates/brk_computer/src/internal/multi/from_height/value_full.rs @@ -1,30 +1,23 @@ -//! Value type for Full pattern from Height. -//! -//! Height-level USD stats are stored (eagerly computed from sats × price). -//! Uses CumFull: stored base + cumulative + rolling windows. - use brk_error::Result; use brk_traversable::Traversable; -use brk_types::{Bitcoin, Dollars, Height, Sats, Version}; -use vecdb::{Database, EagerVec, Exit, PcoVec, ReadableCloneableVec, Rw, StorageMode}; +use brk_types::{Dollars, Height, Sats, Version}; +use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode}; use crate::{ indexes, - internal::{ - ComputedFromHeightCumulativeFull, LazyFromHeightLast, SatsToBitcoin, SatsToDollars, - WindowStarts, - }, + internal::{ByUnit, RollingFullByUnit, SatsToDollars, WindowStarts}, prices, }; #[derive(Traversable)] pub struct ValueFromHeightFull { - pub sats: ComputedFromHeightCumulativeFull, - pub btc: LazyFromHeightLast, - pub usd: ComputedFromHeightCumulativeFull, + pub base: ByUnit, + pub cumulative: ByUnit, + #[traversable(flatten)] + pub rolling: RollingFullByUnit, } -const VERSION: Version = Version::TWO; // Bumped for stored height dollars +const VERSION: Version = Version::TWO; impl ValueFromHeightFull { pub(crate) fn forced_import( @@ -35,19 +28,11 @@ impl ValueFromHeightFull { ) -> Result { let v = version + VERSION; - let sats = ComputedFromHeightCumulativeFull::forced_import(db, name, v, indexes)?; - - let btc = LazyFromHeightLast::from_height_source::( - &format!("{name}_btc"), - v, - sats.height.read_only_boxed_clone(), - indexes, - ); - - let usd = - ComputedFromHeightCumulativeFull::forced_import(db, &format!("{name}_usd"), v, indexes)?; - - Ok(Self { sats, btc, usd }) + Ok(Self { + base: ByUnit::forced_import(db, name, v, indexes)?, + cumulative: ByUnit::forced_import(db, &format!("{name}_cumulative"), v, indexes)?, + rolling: RollingFullByUnit::forced_import(db, name, v, indexes)?, + }) } pub(crate) fn compute( @@ -58,15 +43,36 @@ impl ValueFromHeightFull { exit: &Exit, compute_sats: impl FnOnce(&mut EagerVec>) -> Result<()>, ) -> Result<()> { - self.sats.compute(max_from, windows, exit, compute_sats)?; + compute_sats(&mut self.base.sats.height)?; - self.usd.compute(max_from, windows, exit, |vec| { - Ok(vec.compute_binary::( + self.cumulative + .sats + .height + .compute_cumulative(max_from, &self.base.sats.height, exit)?; + + self.base + .usd + .height + .compute_binary::( max_from, - &self.sats.height, + &self.base.sats.height, &prices.price.usd, exit, - )?) - }) + )?; + + self.cumulative + .usd + .height + .compute_cumulative(max_from, &self.base.usd.height, exit)?; + + self.rolling.compute( + max_from, + windows, + &self.base.sats.height, + &self.base.usd.height, + exit, + )?; + + Ok(()) } } diff --git a/crates/brk_computer/src/internal/multi/from_height/value_last.rs b/crates/brk_computer/src/internal/multi/from_height/value_last.rs index eb63b59e5..770ba2490 100644 --- a/crates/brk_computer/src/internal/multi/from_height/value_last.rs +++ b/crates/brk_computer/src/internal/multi/from_height/value_last.rs @@ -1,26 +1,23 @@ -//! Value type for Last pattern from Height. -//! -//! Height-level USD value is stored (eagerly computed from sats × price). -//! Day1 last is stored since it requires finding the last value within each date. - use brk_error::Result; use brk_traversable::Traversable; -use brk_types::{Bitcoin, Dollars, Height, Sats, Version}; -use vecdb::{Database, Exit, ReadableCloneableVec, Rw, StorageMode}; +use brk_types::{Dollars, Height, Sats, Version}; +use derive_more::{Deref, DerefMut}; +use vecdb::{Database, Exit, Rw, StorageMode}; use crate::{ indexes, prices, - internal::{ComputedFromHeightLast, LazyFromHeightLast, SatsToBitcoin, SatsToDollars}, + internal::{ByUnit, SatsToDollars}, }; -#[derive(Traversable)] +#[derive(Deref, DerefMut, Traversable)] +#[traversable(transparent)] pub struct ValueFromHeightLast { - pub sats: ComputedFromHeightLast, - pub btc: LazyFromHeightLast, - pub usd: ComputedFromHeightLast, + #[deref] + #[deref_mut] + pub base: ByUnit, } -const VERSION: Version = Version::TWO; // Bumped for stored height dollars +const VERSION: Version = Version::TWO; impl ValueFromHeightLast { pub(crate) fn forced_import( @@ -30,35 +27,20 @@ impl ValueFromHeightLast { indexes: &indexes::Vecs, ) -> Result { let v = version + VERSION; - - let sats = ComputedFromHeightLast::forced_import(db, name, v, indexes)?; - - let btc = LazyFromHeightLast::from_computed::( - &format!("{name}_btc"), - v, - sats.height.read_only_boxed_clone(), - &sats, - ); - - let usd = ComputedFromHeightLast::forced_import(db, &format!("{name}_usd"), v, indexes)?; - Ok(Self { - sats, - btc, - usd, + base: ByUnit::forced_import(db, name, v, indexes)?, }) } - /// Eagerly compute USD height values: sats[h] * price[h]. pub(crate) fn compute( &mut self, prices: &prices::Vecs, max_from: Height, exit: &Exit, ) -> Result<()> { - self.usd.compute_binary::( + self.base.usd.compute_binary::( max_from, - &self.sats.height, + &self.base.sats.height, &prices.price.usd, exit, )?; diff --git a/crates/brk_computer/src/internal/multi/from_height/value_last_rolling.rs b/crates/brk_computer/src/internal/multi/from_height/value_last_rolling.rs index cee15a989..583c853db 100644 --- a/crates/brk_computer/src/internal/multi/from_height/value_last_rolling.rs +++ b/crates/brk_computer/src/internal/multi/from_height/value_last_rolling.rs @@ -21,6 +21,7 @@ pub struct ValueFromHeightLastRolling { #[deref_mut] #[traversable(flatten)] pub value: ValueFromHeight, + #[traversable(flatten)] pub rolling: StoredValueRollingWindows, } diff --git a/crates/brk_computer/src/internal/multi/from_height/value_lazy_computed_cumulative.rs b/crates/brk_computer/src/internal/multi/from_height/value_lazy_computed_cumulative.rs index 385a39f53..a72cdcae8 100644 --- a/crates/brk_computer/src/internal/multi/from_height/value_lazy_computed_cumulative.rs +++ b/crates/brk_computer/src/internal/multi/from_height/value_lazy_computed_cumulative.rs @@ -1,32 +1,21 @@ -//! Value type with stored sats height + cumulative, stored usd, lazy btc. -//! -//! - Sats: stored height + cumulative (ComputedFromHeightCumulative) -//! - BTC: lazy transform from sats (LazyFromHeightLast) -//! - USD: stored (eagerly computed from price × sats) - use brk_error::Result; use brk_traversable::Traversable; -use brk_types::{Bitcoin, Dollars, Height, Sats, Version}; -use vecdb::{Database, Exit, ReadableCloneableVec, Rw, StorageMode}; +use brk_types::{Dollars, Height, Sats, Version}; +use vecdb::{Database, Exit, Rw, StorageMode}; use crate::{ indexes, - internal::{ - ComputedFromHeightCumulative, ComputedFromHeightLast, LazyFromHeightLast, SatsToBitcoin, - SatsToDollars, - }, + internal::{ByUnit, SatsToDollars}, prices, }; -/// Value wrapper with stored sats height + cumulative, lazy btc + stored usd. #[derive(Traversable)] pub struct LazyComputedValueFromHeightCumulative { - pub sats: ComputedFromHeightCumulative, - pub btc: LazyFromHeightLast, - pub usd: ComputedFromHeightLast, + pub base: ByUnit, + pub cumulative: ByUnit, } -const VERSION: Version = Version::ONE; // Bumped for stored height dollars +const VERSION: Version = Version::ONE; impl LazyComputedValueFromHeightCumulative { pub(crate) fn forced_import( @@ -37,35 +26,37 @@ impl LazyComputedValueFromHeightCumulative { ) -> Result { let v = version + VERSION; - let sats = ComputedFromHeightCumulative::forced_import(db, name, v, indexes)?; - - let btc = LazyFromHeightLast::from_height_source::( - &format!("{name}_btc"), - v, - sats.height.read_only_boxed_clone(), - indexes, - ); - - let usd = ComputedFromHeightLast::forced_import(db, &format!("{name}_usd"), v, indexes)?; - - Ok(Self { sats, btc, usd }) + Ok(Self { + base: ByUnit::forced_import(db, name, v, indexes)?, + cumulative: ByUnit::forced_import(db, &format!("{name}_cumulative"), v, indexes)?, + }) } - /// Compute cumulative + USD from already-filled sats height vec. pub(crate) fn compute( &mut self, prices: &prices::Vecs, max_from: Height, exit: &Exit, ) -> Result<()> { - self.sats.compute_rest(max_from, exit)?; + self.cumulative + .sats + .height + .compute_cumulative(max_from, &self.base.sats.height, exit)?; + + self.base + .usd + .compute_binary::( + max_from, + &self.base.sats.height, + &prices.price.usd, + exit, + )?; + + self.cumulative + .usd + .height + .compute_cumulative(max_from, &self.base.usd.height, exit)?; - self.usd.compute_binary::( - max_from, - &self.sats.height, - &prices.price.usd, - exit, - )?; Ok(()) } } diff --git a/crates/brk_computer/src/internal/multi/from_height/value_sum_cumulative.rs b/crates/brk_computer/src/internal/multi/from_height/value_sum_cumulative.rs index 5a19d0acc..55a2f78ba 100644 --- a/crates/brk_computer/src/internal/multi/from_height/value_sum_cumulative.rs +++ b/crates/brk_computer/src/internal/multi/from_height/value_sum_cumulative.rs @@ -1,29 +1,22 @@ -//! Value type for SumCumulative pattern from Height. -//! -//! Height-level USD sum is stored (eagerly computed from sats × price). -//! Uses CumSum: stored base + cumulative + rolling sum windows. - use brk_error::Result; use brk_traversable::Traversable; -use brk_types::{Bitcoin, Dollars, Height, Sats, Version}; -use vecdb::{Database, EagerVec, Exit, PcoVec, ReadableCloneableVec, Rw, StorageMode}; +use brk_types::{Dollars, Height, Sats, Version}; +use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode}; use crate::{ - indexes, prices, - internal::{ - ComputedFromHeightCumulativeSum, LazyFromHeightLast, SatsToBitcoin, SatsToDollars, - WindowStarts, - }, + indexes, + internal::{ByUnit, RollingSumByUnit, SatsToDollars, WindowStarts}, + prices, }; #[derive(Traversable)] pub struct ValueFromHeightSumCumulative { - pub sats: ComputedFromHeightCumulativeSum, - pub btc: LazyFromHeightLast, - pub usd: ComputedFromHeightCumulativeSum, + pub base: ByUnit, + pub cumulative: ByUnit, + pub sum: RollingSumByUnit, } -const VERSION: Version = Version::TWO; // Bumped for stored height dollars +const VERSION: Version = Version::TWO; impl ValueFromHeightSumCumulative { pub(crate) fn forced_import( @@ -34,19 +27,11 @@ impl ValueFromHeightSumCumulative { ) -> Result { let v = version + VERSION; - let sats = ComputedFromHeightCumulativeSum::forced_import(db, name, v, indexes)?; - - let btc = LazyFromHeightLast::from_height_source::( - &format!("{name}_btc"), - v, - sats.height.read_only_boxed_clone(), - indexes, - ); - - let usd = - ComputedFromHeightCumulativeSum::forced_import(db, &format!("{name}_usd"), v, indexes)?; - - Ok(Self { sats, btc, usd }) + Ok(Self { + base: ByUnit::forced_import(db, name, v, indexes)?, + cumulative: ByUnit::forced_import(db, &format!("{name}_cumulative"), v, indexes)?, + sum: RollingSumByUnit::forced_import(db, name, v, indexes)?, + }) } pub(crate) fn compute( @@ -57,15 +42,36 @@ impl ValueFromHeightSumCumulative { exit: &Exit, compute_sats: impl FnOnce(&mut EagerVec>) -> Result<()>, ) -> Result<()> { - self.sats.compute(max_from, windows, exit, compute_sats)?; + compute_sats(&mut self.base.sats.height)?; - self.usd.compute(max_from, windows, exit, |vec| { - Ok(vec.compute_binary::( + self.cumulative + .sats + .height + .compute_cumulative(max_from, &self.base.sats.height, exit)?; + + self.base + .usd + .height + .compute_binary::( max_from, - &self.sats.height, + &self.base.sats.height, &prices.price.usd, exit, - )?) - }) + )?; + + self.cumulative + .usd + .height + .compute_cumulative(max_from, &self.base.usd.height, exit)?; + + self.sum.compute_rolling_sum( + max_from, + windows, + &self.base.sats.height, + &self.base.usd.height, + exit, + )?; + + Ok(()) } } diff --git a/crates/brk_computer/src/internal/multi/height_derived/last.rs b/crates/brk_computer/src/internal/multi/height_derived/last.rs index c06839236..1a369650f 100644 --- a/crates/brk_computer/src/internal/multi/height_derived/last.rs +++ b/crates/brk_computer/src/internal/multi/height_derived/last.rs @@ -2,12 +2,14 @@ use brk_traversable::Traversable; use brk_types::{ - Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour4, Hour12, Minute1, Minute5, - Minute10, Minute30, Month1, Month3, Month6, Version, Week1, Year1, Year10, + Day1, Day3, DifficultyEpoch, FromCoarserIndex, HalvingEpoch, Height, Hour1, Hour4, Hour12, + Minute1, Minute5, Minute10, Minute30, Month1, Month3, Month6, Version, Week1, Year1, Year10, }; use derive_more::{Deref, DerefMut}; use schemars::JsonSchema; -use vecdb::{LazyAggVec, ReadOnlyClone, ReadableBoxedVec, ReadableCloneableVec}; +use vecdb::{ + Cursor, LazyAggVec, ReadOnlyClone, ReadableBoxedVec, ReadableCloneableVec, VecIndex, VecValue, +}; use crate::{ indexes, indexes_from, @@ -77,13 +79,45 @@ where }; } + fn for_each_range_from_coarser< + I: VecIndex, + O: VecValue, + S1I: VecIndex + FromCoarserIndex, + S2T: VecValue, + >( + from: usize, + to: usize, + source: &ReadableBoxedVec, + mapping: &ReadableBoxedVec, + f: &mut dyn FnMut(O), + ) { + let mapping_len = mapping.len(); + let source_len = source.len(); + let mut cursor = Cursor::from_dyn(&**source); + for i in from..to { + if i >= mapping_len { + break; + } + let target = S1I::max_from(I::from(i), source_len); + if cursor.position() <= target { + cursor.advance(target - cursor.position()); + if let Some(v) = cursor.next() { + f(v); + } + } else if let Some(v) = source.collect_one_at(target) { + f(v); + } + } + } + macro_rules! epoch { ($idx:ident) => { - LazyAggVec::from_source( + LazyAggVec::new( name, v, height_source.clone(), indexes.$idx.identity.read_only_boxed_clone(), + for_each_range_from_coarser, ) }; } diff --git a/crates/brk_computer/src/internal/single/group/distribution.rs b/crates/brk_computer/src/internal/single/group/distribution.rs index a95ae27d8..002014202 100644 --- a/crates/brk_computer/src/internal/single/group/distribution.rs +++ b/crates/brk_computer/src/internal/single/group/distribution.rs @@ -1,29 +1,25 @@ use brk_error::Result; -use brk_traversable::Traversable; use schemars::JsonSchema; use vecdb::{ - Database, Exit, ReadableVec, Ro, Rw, StorageMode, VecIndex, VecValue, Version, + Database, Exit, ReadableVec, Ro, Rw, VecIndex, VecValue, Version, }; use crate::internal::{ - AverageVec, ComputedVecValue, MaxVec, MedianVec, MinVec, Pct10Vec, Pct25Vec, Pct75Vec, - Pct90Vec, + AverageVec, ComputedVecValue, DistributionStats, MaxVec, MedianVec, MinVec, Pct10Vec, + Pct25Vec, Pct75Vec, Pct90Vec, }; -/// Distribution stats (average + min + max + percentiles) — flat 8-field struct. -#[derive(Traversable)] -pub struct Distribution { - pub average: AverageVec, - #[traversable(flatten)] - pub min: MinVec, - #[traversable(flatten)] - pub max: MaxVec, - pub pct10: Pct10Vec, - pub pct25: Pct25Vec, - pub median: MedianVec, - pub pct75: Pct75Vec, - pub pct90: Pct90Vec, -} +/// Distribution stats (average + min + max + percentiles) — concrete vec type alias. +pub type Distribution = DistributionStats< + AverageVec, + MinVec, + MaxVec, + Pct10Vec, + Pct25Vec, + MedianVec, + Pct75Vec, + Pct90Vec, +>; impl Distribution { pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result { @@ -111,7 +107,7 @@ impl Distribution { } pub fn read_only_clone(&self) -> Distribution { - Distribution { + DistributionStats { average: self.average.read_only_clone(), min: self.min.read_only_clone(), max: self.max.read_only_clone(), diff --git a/crates/brk_computer/src/internal/single/rolling/distribution.rs b/crates/brk_computer/src/internal/single/rolling/distribution.rs index 325f9888e..2537bcc37 100644 --- a/crates/brk_computer/src/internal/single/rolling/distribution.rs +++ b/crates/brk_computer/src/internal/single/rolling/distribution.rs @@ -41,11 +41,11 @@ where average: RollingWindows::forced_import(db, &format!("{name}_average"), v, indexes)?, min: RollingWindows::forced_import(db, &format!("{name}_min"), v, indexes)?, max: RollingWindows::forced_import(db, &format!("{name}_max"), v, indexes)?, - p10: RollingWindows::forced_import(db, &format!("{name}_p10"), v, indexes)?, - p25: RollingWindows::forced_import(db, &format!("{name}_p25"), v, indexes)?, + pct10: RollingWindows::forced_import(db, &format!("{name}_p10"), v, indexes)?, + pct25: RollingWindows::forced_import(db, &format!("{name}_p25"), v, indexes)?, median: RollingWindows::forced_import(db, &format!("{name}_median"), v, indexes)?, - p75: RollingWindows::forced_import(db, &format!("{name}_p75"), v, indexes)?, - p90: RollingWindows::forced_import(db, &format!("{name}_p90"), v, indexes)?, + pct75: RollingWindows::forced_import(db, &format!("{name}_p75"), v, indexes)?, + pct90: RollingWindows::forced_import(db, &format!("{name}_p90"), v, indexes)?, })) } @@ -69,30 +69,30 @@ where compute_rolling_distribution_from_starts( max_from, windows._24h, source, &mut self.0.average._24h.height, &mut self.0.min._24h.height, - &mut self.0.max._24h.height, &mut self.0.p10._24h.height, - &mut self.0.p25._24h.height, &mut self.0.median._24h.height, - &mut self.0.p75._24h.height, &mut self.0.p90._24h.height, exit, + &mut self.0.max._24h.height, &mut self.0.pct10._24h.height, + &mut self.0.pct25._24h.height, &mut self.0.median._24h.height, + &mut self.0.pct75._24h.height, &mut self.0.pct90._24h.height, exit, )?; compute_rolling_distribution_from_starts( max_from, windows._7d, source, &mut self.0.average._7d.height, &mut self.0.min._7d.height, - &mut self.0.max._7d.height, &mut self.0.p10._7d.height, - &mut self.0.p25._7d.height, &mut self.0.median._7d.height, - &mut self.0.p75._7d.height, &mut self.0.p90._7d.height, exit, + &mut self.0.max._7d.height, &mut self.0.pct10._7d.height, + &mut self.0.pct25._7d.height, &mut self.0.median._7d.height, + &mut self.0.pct75._7d.height, &mut self.0.pct90._7d.height, exit, )?; compute_rolling_distribution_from_starts( max_from, windows._30d, source, &mut self.0.average._30d.height, &mut self.0.min._30d.height, - &mut self.0.max._30d.height, &mut self.0.p10._30d.height, - &mut self.0.p25._30d.height, &mut self.0.median._30d.height, - &mut self.0.p75._30d.height, &mut self.0.p90._30d.height, exit, + &mut self.0.max._30d.height, &mut self.0.pct10._30d.height, + &mut self.0.pct25._30d.height, &mut self.0.median._30d.height, + &mut self.0.pct75._30d.height, &mut self.0.pct90._30d.height, exit, )?; compute_rolling_distribution_from_starts( max_from, windows._1y, source, &mut self.0.average._1y.height, &mut self.0.min._1y.height, - &mut self.0.max._1y.height, &mut self.0.p10._1y.height, - &mut self.0.p25._1y.height, &mut self.0.median._1y.height, - &mut self.0.p75._1y.height, &mut self.0.p90._1y.height, exit, + &mut self.0.max._1y.height, &mut self.0.pct10._1y.height, + &mut self.0.pct25._1y.height, &mut self.0.median._1y.height, + &mut self.0.pct75._1y.height, &mut self.0.pct90._1y.height, exit, )?; Ok(()) diff --git a/crates/brk_computer/src/internal/single/transform/mod.rs b/crates/brk_computer/src/internal/single/transform/mod.rs index f044efd61..b891c2cae 100644 --- a/crates/brk_computer/src/internal/single/transform/mod.rs +++ b/crates/brk_computer/src/internal/single/transform/mod.rs @@ -1,15 +1,14 @@ mod block_count_target; mod cents_to_dollars; mod cents_to_sats; -mod ohlc_cents_to_dollars; -mod ohlc_cents_to_sats; - mod dollar_halve; mod dollar_identity; mod dollar_plus; mod dollar_times_tenths; mod dollars_to_sats_fract; mod f32_identity; +mod ohlc_cents_to_dollars; +mod ohlc_cents_to_sats; mod percentage_diff_close_dollars; mod percentage_dollars_f32; mod percentage_dollars_f32_neg; @@ -18,7 +17,7 @@ mod percentage_u32_f32; mod price_times_ratio; mod ratio32; mod ratio64; - +mod ratio_u64_f32; mod return_f32_tenths; mod return_i8; mod return_u16; @@ -52,13 +51,12 @@ pub use percentage_dollars_f32_neg::*; pub use percentage_sats_f64::*; pub use percentage_u32_f32::*; pub use price_times_ratio::*; - pub use ratio32::*; pub use ratio64::*; +pub use ratio_u64_f32::*; pub use return_f32_tenths::*; pub use return_i8::*; pub use return_u16::*; - pub use sat_halve::*; pub use sat_halve_to_bitcoin::*; pub use sat_identity::*; diff --git a/crates/brk_computer/src/internal/single/transform/ratio_u64_f32.rs b/crates/brk_computer/src/internal/single/transform/ratio_u64_f32.rs new file mode 100644 index 000000000..cc8aaa262 --- /dev/null +++ b/crates/brk_computer/src/internal/single/transform/ratio_u64_f32.rs @@ -0,0 +1,17 @@ +use brk_types::{StoredF32, StoredU64}; +use vecdb::BinaryTransform; + +/// (StoredU64, StoredU64) -> StoredF32 ratio (a/b) +/// Used for adoption ratio calculations (script_count / total_outputs) +pub struct RatioU64F32; + +impl BinaryTransform for RatioU64F32 { + #[inline(always)] + fn apply(numerator: StoredU64, denominator: StoredU64) -> StoredF32 { + if *denominator > 0 { + StoredF32::from(*numerator as f64 / *denominator as f64) + } else { + StoredF32::from(0.0) + } + } +} diff --git a/crates/brk_computer/src/market/indicators/compute.rs b/crates/brk_computer/src/market/indicators/compute.rs index 0752ef24f..2c9c8aa50 100644 --- a/crates/brk_computer/src/market/indicators/compute.rs +++ b/crates/brk_computer/src/market/indicators/compute.rs @@ -27,7 +27,7 @@ impl Vecs { ) -> Result<()> { self.puell_multiple.height.compute_divide( starting_indexes.height, - &rewards.coinbase.usd.height, + &rewards.coinbase.base.usd.height, &rewards.subsidy_usd_1y_sma.height, exit, )?; diff --git a/crates/brk_computer/src/mining/compute.rs b/crates/brk_computer/src/mining/compute.rs index 0c9be771f..8f197ec08 100644 --- a/crates/brk_computer/src/mining/compute.rs +++ b/crates/brk_computer/src/mining/compute.rs @@ -31,8 +31,8 @@ impl Vecs { self.hashrate.compute( &blocks.count, &blocks.difficulty, - &self.rewards.coinbase.sats.rolling.sum._24h.height, - &self.rewards.coinbase.usd.rolling.sum._24h.height, + &self.rewards.coinbase.rolling._24h.sum.sats.height, + &self.rewards.coinbase.rolling._24h.sum.usd.height, starting_indexes, exit, )?; diff --git a/crates/brk_computer/src/mining/rewards/compute.rs b/crates/brk_computer/src/mining/rewards/compute.rs index 0f768c07a..5bc4030c5 100644 --- a/crates/brk_computer/src/mining/rewards/compute.rs +++ b/crates/brk_computer/src/mining/rewards/compute.rs @@ -84,8 +84,8 @@ impl Vecs { |vec| { vec.compute_transform2( starting_indexes.height, - &self.coinbase.sats.height, - &self.fees.sats.height, + &self.coinbase.base.sats.height, + &self.fees.base.sats.height, |(height, coinbase, fees, ..)| { ( height, @@ -109,7 +109,7 @@ impl Vecs { |vec| { vec.compute_transform( starting_indexes.height, - &self.subsidy.sats.height, + &self.subsidy.base.sats.height, |(height, subsidy, ..)| { let halving = HalvingEpoch::from(height); let expected = Sats::FIFTY_BTC / 2_usize.pow(halving.to_usize() as u32); @@ -124,42 +124,42 @@ impl Vecs { // All-time cumulative fee dominance self.fee_dominance.height.compute_percentage( starting_indexes.height, - &self.fees.sats.cumulative.height, - &self.coinbase.sats.cumulative.height, + &self.fees.cumulative.sats.height, + &self.coinbase.cumulative.sats.height, exit, )?; // Rolling fee dominance = sum(fees) / sum(coinbase) * 100 self.fee_dominance_24h.height.compute_percentage( starting_indexes.height, - &self.fees.sats.rolling.sum._24h.height, - &self.coinbase.sats.rolling.sum._24h.height, + &self.fees.rolling._24h.sum.sats.height, + &self.coinbase.rolling._24h.sum.sats.height, exit, )?; self.fee_dominance_7d.height.compute_percentage( starting_indexes.height, - &self.fees.sats.rolling.sum._7d.height, - &self.coinbase.sats.rolling.sum._7d.height, + &self.fees.rolling._7d.sum.sats.height, + &self.coinbase.rolling._7d.sum.sats.height, exit, )?; self.fee_dominance_30d.height.compute_percentage( starting_indexes.height, - &self.fees.sats.rolling.sum._30d.height, - &self.coinbase.sats.rolling.sum._30d.height, + &self.fees.rolling._30d.sum.sats.height, + &self.coinbase.rolling._30d.sum.sats.height, exit, )?; self.fee_dominance_1y.height.compute_percentage( starting_indexes.height, - &self.fees.sats.rolling.sum._1y.height, - &self.coinbase.sats.rolling.sum._1y.height, + &self.fees.rolling._1y.sum.sats.height, + &self.coinbase.rolling._1y.sum.sats.height, exit, )?; // All-time cumulative subsidy dominance self.subsidy_dominance.height.compute_percentage( starting_indexes.height, - &self.subsidy.sats.cumulative.height, - &self.coinbase.sats.cumulative.height, + &self.subsidy.cumulative.sats.height, + &self.coinbase.cumulative.sats.height, exit, )?; @@ -193,7 +193,7 @@ impl Vecs { self.subsidy_usd_1y_sma.height.compute_rolling_average( starting_indexes.height, &count_vecs.height_1y_ago, - &self.coinbase.usd.height, + &self.coinbase.base.usd.height, exit, )?; diff --git a/crates/brk_computer/src/pools/vecs.rs b/crates/brk_computer/src/pools/vecs.rs index 4053e2653..f93d6d140 100644 --- a/crates/brk_computer/src/pools/vecs.rs +++ b/crates/brk_computer/src/pools/vecs.rs @@ -237,7 +237,7 @@ impl Vecs { Ok(vec.compute_transform2( starting_indexes.height, &self.blocks_mined.height, - &mining.rewards.subsidy.sats.height, + &mining.rewards.subsidy.base.sats.height, |(h, mask, val, ..)| (h, MaskSats::apply(mask, val)), exit, )?) @@ -253,7 +253,7 @@ impl Vecs { Ok(vec.compute_transform2( starting_indexes.height, &self.blocks_mined.height, - &mining.rewards.fees.sats.height, + &mining.rewards.fees.base.sats.height, |(h, mask, val, ..)| (h, MaskSats::apply(mask, val)), exit, )?) @@ -269,7 +269,7 @@ impl Vecs { Ok(vec.compute_transform2( starting_indexes.height, &self.blocks_mined.height, - &mining.rewards.coinbase.sats.height, + &mining.rewards.coinbase.base.sats.height, |(h, mask, val, ..)| (h, MaskSats::apply(mask, val)), exit, )?) diff --git a/crates/brk_computer/src/scripts/adoption.rs b/crates/brk_computer/src/scripts/adoption.rs new file mode 100644 index 000000000..f7f468c99 --- /dev/null +++ b/crates/brk_computer/src/scripts/adoption.rs @@ -0,0 +1,56 @@ +use brk_error::Result; +use brk_traversable::Traversable; +use brk_types::{StoredF32, Version}; +use vecdb::{Database, Exit, Rw, StorageMode}; + +use crate::{ComputeIndexes, indexes, internal::{ComputedFromHeightLast, RatioU64F32}, outputs}; + +use super::count::Vecs as CountVecs; + +#[derive(Traversable)] +pub struct Vecs { + pub taproot: ComputedFromHeightLast, + pub segwit: ComputedFromHeightLast, +} + +impl Vecs { + pub(crate) fn forced_import( + db: &Database, + version: Version, + indexes: &indexes::Vecs, + ) -> Result { + Ok(Self { + taproot: ComputedFromHeightLast::forced_import( + db, + "taproot_adoption", + version, + indexes, + )?, + segwit: ComputedFromHeightLast::forced_import(db, "segwit_adoption", version, indexes)?, + }) + } + + pub(crate) fn compute( + &mut self, + count: &CountVecs, + outputs_count: &outputs::CountVecs, + starting_indexes: &ComputeIndexes, + exit: &Exit, + ) -> Result<()> { + self.taproot.compute_binary::<_, _, RatioU64F32>( + starting_indexes.height, + &count.p2tr.height, + &outputs_count.total_count.full.sum_cumulative.sum.0, + exit, + )?; + + self.segwit.compute_binary::<_, _, RatioU64F32>( + starting_indexes.height, + &count.segwit.height, + &outputs_count.total_count.full.sum_cumulative.sum.0, + exit, + )?; + + Ok(()) + } +} diff --git a/crates/brk_computer/src/scripts/compute.rs b/crates/brk_computer/src/scripts/compute.rs index 22bca90a7..b0da212a8 100644 --- a/crates/brk_computer/src/scripts/compute.rs +++ b/crates/brk_computer/src/scripts/compute.rs @@ -17,11 +17,14 @@ impl Vecs { exit: &Exit, ) -> Result<()> { self.count - .compute(indexer, &blocks.count, &outputs.count, starting_indexes, exit)?; + .compute(indexer, &blocks.count, starting_indexes, exit)?; self.value .compute(indexer, &blocks.count, prices, starting_indexes, exit)?; + self.adoption + .compute(&self.count, &outputs.count, starting_indexes, exit)?; + let _lock = exit.lock(); self.db.compact()?; Ok(()) diff --git a/crates/brk_computer/src/scripts/count/compute.rs b/crates/brk_computer/src/scripts/count/compute.rs index 4260de0f3..4d9c4a04b 100644 --- a/crates/brk_computer/src/scripts/count/compute.rs +++ b/crates/brk_computer/src/scripts/count/compute.rs @@ -1,18 +1,16 @@ use brk_error::Result; use brk_indexer::Indexer; -use brk_types::StoredF32; use brk_types::StoredU64; use vecdb::Exit; use super::Vecs; -use crate::{ComputeIndexes, blocks, outputs}; +use crate::{ComputeIndexes, blocks}; impl Vecs { pub(crate) fn compute( &mut self, indexer: &Indexer, count_vecs: &blocks::CountVecs, - outputs_count: &outputs::CountVecs, starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { @@ -151,37 +149,6 @@ impl Vecs { )?) })?; - // Adoption ratios: per-block ratio of script type / total outputs - self.taproot_adoption.height.compute_transform2( - starting_indexes.height, - &self.p2tr.height, - &outputs_count.total_count.full.sum_cumulative.sum.0, - |(h, p2tr, total, ..)| { - let ratio = if *total > 0 { - StoredF32::from(*p2tr as f64 / *total as f64) - } else { - StoredF32::from(0.0) - }; - (h, ratio) - }, - exit, - )?; - - self.segwit_adoption.height.compute_transform2( - starting_indexes.height, - &self.segwit.height, - &outputs_count.total_count.full.sum_cumulative.sum.0, - |(h, segwit, total, ..)| { - let ratio = if *total > 0 { - StoredF32::from(*segwit as f64 / *total as f64) - } else { - StoredF32::from(0.0) - }; - (h, ratio) - }, - exit, - )?; - Ok(()) } } diff --git a/crates/brk_computer/src/scripts/count/import.rs b/crates/brk_computer/src/scripts/count/import.rs index 30a6fbac9..b61351433 100644 --- a/crates/brk_computer/src/scripts/count/import.rs +++ b/crates/brk_computer/src/scripts/count/import.rs @@ -3,10 +3,7 @@ use brk_types::Version; use vecdb::Database; use super::Vecs; -use crate::{ - indexes, - internal::{ComputedFromHeightCumulativeSum, ComputedFromHeightLast}, -}; +use crate::{indexes, internal::ComputedFromHeightCumulativeSum}; impl Vecs { pub(crate) fn forced_import( @@ -58,18 +55,6 @@ impl Vecs { indexes, )?, segwit, - taproot_adoption: ComputedFromHeightLast::forced_import( - db, - "taproot_adoption", - version, - indexes, - )?, - segwit_adoption: ComputedFromHeightLast::forced_import( - db, - "segwit_adoption", - version, - indexes, - )?, }) } } diff --git a/crates/brk_computer/src/scripts/count/vecs.rs b/crates/brk_computer/src/scripts/count/vecs.rs index 68c535f87..3ad6f7a00 100644 --- a/crates/brk_computer/src/scripts/count/vecs.rs +++ b/crates/brk_computer/src/scripts/count/vecs.rs @@ -1,8 +1,8 @@ use brk_traversable::Traversable; -use brk_types::{StoredF32, StoredU64}; +use brk_types::StoredU64; use vecdb::{Rw, StorageMode}; -use crate::internal::{ComputedFromHeightCumulativeSum, ComputedFromHeightLast}; +use crate::internal::ComputedFromHeightCumulativeSum; #[derive(Traversable)] pub struct Vecs { @@ -23,8 +23,4 @@ pub struct Vecs { // Aggregate counts /// SegWit output count (p2wpkh + p2wsh + p2tr) pub segwit: ComputedFromHeightCumulativeSum, - - // Adoption ratios (stored per-block, lazy period views) - pub taproot_adoption: ComputedFromHeightLast, - pub segwit_adoption: ComputedFromHeightLast, } diff --git a/crates/brk_computer/src/scripts/import.rs b/crates/brk_computer/src/scripts/import.rs index 345f83d30..750624e9e 100644 --- a/crates/brk_computer/src/scripts/import.rs +++ b/crates/brk_computer/src/scripts/import.rs @@ -7,7 +7,7 @@ use vecdb::{Database, PAGE_SIZE}; use crate::indexes; -use super::{CountVecs, ValueVecs, Vecs}; +use super::{AdoptionVecs, CountVecs, ValueVecs, Vecs}; impl Vecs { pub(crate) fn forced_import( @@ -22,8 +22,9 @@ impl Vecs { let count = CountVecs::forced_import(&db, version, indexes)?; let value = ValueVecs::forced_import(&db, version, indexes)?; + let adoption = AdoptionVecs::forced_import(&db, version, indexes)?; - let this = Self { db, count, value }; + let this = Self { db, count, value, adoption }; this.db.retain_regions( this.iter_any_exportable() diff --git a/crates/brk_computer/src/scripts/mod.rs b/crates/brk_computer/src/scripts/mod.rs index 1b7042e55..4fbea183d 100644 --- a/crates/brk_computer/src/scripts/mod.rs +++ b/crates/brk_computer/src/scripts/mod.rs @@ -1,3 +1,4 @@ +pub mod adoption; pub mod count; pub mod value; @@ -7,6 +8,7 @@ mod import; use brk_traversable::Traversable; use vecdb::{Database, Rw, StorageMode}; +pub use adoption::Vecs as AdoptionVecs; pub use count::Vecs as CountVecs; pub use value::Vecs as ValueVecs; @@ -19,4 +21,5 @@ pub struct Vecs { pub count: CountVecs, pub value: ValueVecs, + pub adoption: AdoptionVecs, } diff --git a/crates/brk_computer/src/supply/burned/compute.rs b/crates/brk_computer/src/supply/burned/compute.rs index 7717e4d1f..739ec47e7 100644 --- a/crates/brk_computer/src/supply/burned/compute.rs +++ b/crates/brk_computer/src/supply/burned/compute.rs @@ -22,11 +22,11 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, prices, exit, |height_vec| { // Validate computed versions against dependencies - let opreturn_dep_version = scripts.value.opreturn.sats.height.version(); + let opreturn_dep_version = scripts.value.opreturn.base.sats.height.version(); height_vec.validate_computed_version_or_reset(opreturn_dep_version)?; // Copy per-block opreturn values from scripts - let scripts_target = scripts.value.opreturn.sats.height.len(); + let scripts_target = scripts.value.opreturn.base.sats.height.len(); if scripts_target > 0 { let target_height = Height::from(scripts_target - 1); let current_len = height_vec.len(); @@ -36,7 +36,7 @@ impl Vecs { if starting_height <= target_height { let start = starting_height.to_usize(); let end = target_height.to_usize() + 1; - scripts.value.opreturn.sats.height.fold_range_at( + scripts.value.opreturn.base.sats.height.fold_range_at( start, end, start, |idx, value| { height_vec.truncate_push(Height::from(idx), value).unwrap(); @@ -52,8 +52,8 @@ impl Vecs { // 2. Compute unspendable supply = opreturn + unclaimed_rewards + genesis (at height 0) // Get reference to opreturn height vec for computing unspendable - let opreturn_height = &self.opreturn.sats.height; - let unclaimed_height = &mining.rewards.unclaimed_rewards.sats.height; + let opreturn_height = &self.opreturn.base.sats.height; + let unclaimed_height = &mining.rewards.unclaimed_rewards.base.sats.height; self.unspendable .compute(starting_indexes.height, &window_starts, prices, exit, |height_vec| { diff --git a/crates/brk_query/src/impl/mining/block_fees.rs b/crates/brk_query/src/impl/mining/block_fees.rs index 5fd32597a..756af985a 100644 --- a/crates/brk_query/src/impl/mining/block_fees.rs +++ b/crates/brk_query/src/impl/mining/block_fees.rs @@ -15,7 +15,7 @@ impl Query { let iter = Day1Iter::new(computer, start, current_height.to_usize()); - let cumulative = &computer.mining.rewards.fees.sats.cumulative.height; + let cumulative = &computer.mining.rewards.fees.cumulative.sats.height; let first_height = &computer.indexes.day1.first_height; Ok(iter.collect(|di, ts, h| { diff --git a/crates/brk_query/src/impl/mining/block_rewards.rs b/crates/brk_query/src/impl/mining/block_rewards.rs index 3c785b224..3d1bb1d8c 100644 --- a/crates/brk_query/src/impl/mining/block_rewards.rs +++ b/crates/brk_query/src/impl/mining/block_rewards.rs @@ -19,11 +19,11 @@ impl Query { .mining .rewards .coinbase - .sats .rolling + ._24h .distribution .average - ._24h + .sats .day1; Ok(iter.collect(|di, ts, h| { diff --git a/crates/brk_query/src/impl/mining/reward_stats.rs b/crates/brk_query/src/impl/mining/reward_stats.rs index e4544c80b..c53d8d718 100644 --- a/crates/brk_query/src/impl/mining/reward_stats.rs +++ b/crates/brk_query/src/impl/mining/reward_stats.rs @@ -12,8 +12,8 @@ impl Query { let end_block = current_height; let start_block = Height::from(current_height.to_usize().saturating_sub(block_count - 1)); - let coinbase_vec = &computer.mining.rewards.coinbase.sats.height; - let fee_vec = &computer.mining.rewards.fees.sats.height; + let coinbase_vec = &computer.mining.rewards.coinbase.base.sats.height; + let fee_vec = &computer.mining.rewards.fees.base.sats.height; let tx_count_vec = &computer.transactions.count.tx_count.height; let start = start_block.to_usize(); diff --git a/crates/brk_types/src/day1.rs b/crates/brk_types/src/day1.rs index 9ce60c272..09e5575c5 100644 --- a/crates/brk_types/src/day1.rs +++ b/crates/brk_types/src/day1.rs @@ -7,9 +7,9 @@ use brk_error::Error; use jiff::Span; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use vecdb::{CheckedSub, Formattable, FromCoarserIndex, Pco, PrintableIndex}; +use vecdb::{CheckedSub, Formattable, Pco, PrintableIndex}; -use crate::{Year10, Month1, Month3, Month6, Week1, Year1}; +use crate::{FromCoarserIndex, Month1, Month3, Month6, Week1, Year1, Year10}; use super::Date; diff --git a/crates/brk_types/src/from_coarser.rs b/crates/brk_types/src/from_coarser.rs new file mode 100644 index 000000000..6ed2c0215 --- /dev/null +++ b/crates/brk_types/src/from_coarser.rs @@ -0,0 +1,39 @@ +use std::ops::RangeInclusive; + +/// Maps coarser-grained indices to ranges of finer-grained indices. +/// +/// Useful for hierarchical index systems where one index type represents +/// a range of another (e.g., mapping hour indices to timestamp ranges). +pub trait FromCoarserIndex +where + T: Ord + From, +{ + /// Returns the minimum fine-grained index represented by the coarse index. + fn min_from(coarser: T) -> usize; + + /// Returns the maximum fine-grained index represented by the coarse index. + /// Note: May exceed actual data length - use `max_from` for bounded results. + fn max_from_(coarser: T) -> usize; + + /// Returns the maximum fine-grained index, bounded by the data length. + /// Returns 0 if len is 0 (empty data). + fn max_from(coarser: T, len: usize) -> usize { + if len == 0 { + return 0; + } + Self::max_from_(coarser).min(len - 1) + } + + /// Returns the inclusive range of fine-grained indices for the coarse index. + /// Returns an empty range (1..=0) if len is 0. + fn inclusive_range_from(coarser: T, len: usize) -> RangeInclusive + where + T: Clone, + { + if len == 0 { + #[allow(clippy::reversed_empty_ranges)] + return 1..=0; // Empty range + } + Self::min_from(coarser.clone())..=Self::max_from(coarser, len) + } +} diff --git a/crates/brk_types/src/height.rs b/crates/brk_types/src/height.rs index 44bf6f3bc..9dc3fe3f9 100644 --- a/crates/brk_types/src/height.rs +++ b/crates/brk_types/src/height.rs @@ -8,13 +8,11 @@ use byteview::ByteView; use derive_more::Deref; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use vecdb::{Bytes, CheckedSub, Formattable, FromCoarserIndex, Pco, PrintableIndex, Stamp}; +use vecdb::{Bytes, CheckedSub, Formattable, Pco, PrintableIndex, Stamp}; -use super::{DifficultyEpoch, HalvingEpoch}; +use crate::{BLOCKS_PER_DIFF_EPOCHS, BLOCKS_PER_HALVING, FromCoarserIndex}; -use crate::{BLOCKS_PER_DIFF_EPOCHS, BLOCKS_PER_HALVING}; - -use super::StoredU64; +use super::{DifficultyEpoch, HalvingEpoch, StoredU64}; /// Block height #[derive( diff --git a/crates/brk_types/src/lib.rs b/crates/brk_types/src/lib.rs index 96eabc40f..3c052c06e 100644 --- a/crates/brk_types/src/lib.rs +++ b/crates/brk_types/src/lib.rs @@ -64,6 +64,7 @@ mod feerate; mod feeratepercentiles; mod format; mod formatresponse; +mod from_coarser; mod fundedaddressdata; mod fundedaddressindex; mod halvingepoch; @@ -252,6 +253,7 @@ pub use feerate::*; pub use feeratepercentiles::*; pub use format::*; pub use formatresponse::*; +pub use from_coarser::*; pub use fundedaddressdata::*; pub use fundedaddressindex::*; pub use halvingepoch::*; diff --git a/modules/brk-client/index.js b/modules/brk-client/index.js index 13d9a98f9..4ea8607af 100644 --- a/modules/brk-client/index.js +++ b/modules/brk-client/index.js @@ -1582,13 +1582,13 @@ function createMetricPattern37(client, name) { return /** @type {MetricPattern37 * @property {SatsUsdPattern} lowerPriceBand * @property {MetricPattern1} mvrv * @property {MetricPattern1} negRealizedLoss - * @property {CumulativeHeightPattern} netRealizedPnl + * @property {CumulativeHeightPattern} netRealizedPnl * @property {MetricPattern1} netRealizedPnl7dEma * @property {MetricPattern1} netRealizedPnlCumulative30dDelta * @property {MetricPattern1} netRealizedPnlCumulative30dDeltaRelToMarketCap * @property {MetricPattern1} netRealizedPnlCumulative30dDeltaRelToRealizedCap * @property {MetricPattern1} netRealizedPnlRelToRealizedCap - * @property {CumulativeHeightPattern} peakRegret + * @property {CumulativeHeightPattern} peakRegret * @property {MetricPattern1} peakRegretRelToRealizedCap * @property {MetricPattern1} profitFlow * @property {MetricPattern1} profitValueCreated @@ -1597,7 +1597,7 @@ function createMetricPattern37(client, name) { return /** @type {MetricPattern37 * @property {MetricPattern1} realizedCap30dDelta * @property {MetricPattern1} realizedCapCents * @property {MetricPattern1} realizedCapRelToOwnMarketCap - * @property {CumulativeHeightPattern} realizedLoss + * @property {CumulativeHeightPattern} realizedLoss * @property {MetricPattern1} realizedLoss1y * @property {MetricPattern1} realizedLoss24h * @property {MetricPattern1} realizedLoss30d @@ -1607,7 +1607,7 @@ function createMetricPattern37(client, name) { return /** @type {MetricPattern37 * @property {SatsUsdPattern} realizedPrice * @property {RatioPattern2} realizedPriceExtra * @property {RatioPattern3} realizedPriceRatioExt - * @property {CumulativeHeightPattern} realizedProfit + * @property {CumulativeHeightPattern} realizedProfit * @property {MetricPattern1} realizedProfit1y * @property {MetricPattern1} realizedProfit24h * @property {MetricPattern1} realizedProfit30d @@ -1632,9 +1632,9 @@ function createMetricPattern37(client, name) { return /** @type {MetricPattern37 * @property {MetricPattern1} sellSideRiskRatio30dEma * @property {MetricPattern1} sellSideRiskRatio7d * @property {MetricPattern1} sellSideRiskRatio7dEma - * @property {BtcSatsUsdPattern2} sentInLoss + * @property {BaseCumulativePattern} sentInLoss * @property {BtcSatsUsdPattern} sentInLoss14dEma - * @property {BtcSatsUsdPattern2} sentInProfit + * @property {BaseCumulativePattern} sentInProfit * @property {BtcSatsUsdPattern} sentInProfit14dEma * @property {MetricPattern1} sopr * @property {MetricPattern1} sopr1y @@ -1748,9 +1748,9 @@ function createAdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitReali sellSideRiskRatio30dEma: createMetricPattern1(client, _m(acc, 'sell_side_risk_ratio_30d_ema')), sellSideRiskRatio7d: createMetricPattern1(client, _m(acc, 'sell_side_risk_ratio_7d')), sellSideRiskRatio7dEma: createMetricPattern1(client, _m(acc, 'sell_side_risk_ratio_7d_ema')), - sentInLoss: createBtcSatsUsdPattern2(client, _m(acc, 'sent_in_loss')), + sentInLoss: createBaseCumulativePattern(client, _m(acc, 'sent_in_loss')), sentInLoss14dEma: createBtcSatsUsdPattern(client, _m(acc, 'sent_in_loss_14d_ema')), - sentInProfit: createBtcSatsUsdPattern2(client, _m(acc, 'sent_in_profit')), + sentInProfit: createBaseCumulativePattern(client, _m(acc, 'sent_in_profit')), sentInProfit14dEma: createBtcSatsUsdPattern(client, _m(acc, 'sent_in_profit_14d_ema')), sopr: createMetricPattern1(client, _m(acc, 'sopr')), sopr1y: createMetricPattern1(client, _m(acc, 'sopr_1y')), @@ -1808,13 +1808,13 @@ function createAdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitReali * @property {SatsUsdPattern} lowerPriceBand * @property {MetricPattern1} mvrv * @property {MetricPattern1} negRealizedLoss - * @property {CumulativeHeightPattern} netRealizedPnl + * @property {CumulativeHeightPattern} netRealizedPnl * @property {MetricPattern1} netRealizedPnl7dEma * @property {MetricPattern1} netRealizedPnlCumulative30dDelta * @property {MetricPattern1} netRealizedPnlCumulative30dDeltaRelToMarketCap * @property {MetricPattern1} netRealizedPnlCumulative30dDeltaRelToRealizedCap * @property {MetricPattern1} netRealizedPnlRelToRealizedCap - * @property {CumulativeHeightPattern} peakRegret + * @property {CumulativeHeightPattern} peakRegret * @property {MetricPattern1} peakRegretRelToRealizedCap * @property {MetricPattern1} profitFlow * @property {MetricPattern1} profitValueCreated @@ -1822,12 +1822,12 @@ function createAdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitReali * @property {MetricPattern1} realizedCap * @property {MetricPattern1} realizedCap30dDelta * @property {MetricPattern1} realizedCapCents - * @property {CumulativeHeightPattern} realizedLoss + * @property {CumulativeHeightPattern} realizedLoss * @property {MetricPattern1} realizedLoss7dEma * @property {MetricPattern1} realizedLossRelToRealizedCap * @property {SatsUsdPattern} realizedPrice * @property {RatioPattern2} realizedPriceExtra - * @property {CumulativeHeightPattern} realizedProfit + * @property {CumulativeHeightPattern} realizedProfit * @property {MetricPattern1} realizedProfit7dEma * @property {MetricPattern1} realizedProfitRelToRealizedCap * @property {MetricPattern1} realizedValue @@ -1844,9 +1844,9 @@ function createAdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitReali * @property {MetricPattern1} sellSideRiskRatio30dEma * @property {MetricPattern1} sellSideRiskRatio7d * @property {MetricPattern1} sellSideRiskRatio7dEma - * @property {BtcSatsUsdPattern2} sentInLoss + * @property {BaseCumulativePattern} sentInLoss * @property {BtcSatsUsdPattern} sentInLoss14dEma - * @property {BtcSatsUsdPattern2} sentInProfit + * @property {BaseCumulativePattern} sentInProfit * @property {BtcSatsUsdPattern} sentInProfit14dEma * @property {MetricPattern1} sopr * @property {MetricPattern1} sopr1y @@ -1945,9 +1945,9 @@ function createAdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitReali sellSideRiskRatio30dEma: createMetricPattern1(client, _m(acc, 'sell_side_risk_ratio_30d_ema')), sellSideRiskRatio7d: createMetricPattern1(client, _m(acc, 'sell_side_risk_ratio_7d')), sellSideRiskRatio7dEma: createMetricPattern1(client, _m(acc, 'sell_side_risk_ratio_7d_ema')), - sentInLoss: createBtcSatsUsdPattern2(client, _m(acc, 'sent_in_loss')), + sentInLoss: createBaseCumulativePattern(client, _m(acc, 'sent_in_loss')), sentInLoss14dEma: createBtcSatsUsdPattern(client, _m(acc, 'sent_in_loss_14d_ema')), - sentInProfit: createBtcSatsUsdPattern2(client, _m(acc, 'sent_in_profit')), + sentInProfit: createBaseCumulativePattern(client, _m(acc, 'sent_in_profit')), sentInProfit14dEma: createBtcSatsUsdPattern(client, _m(acc, 'sent_in_profit_14d_ema')), sopr: createMetricPattern1(client, _m(acc, 'sopr')), sopr1y: createMetricPattern1(client, _m(acc, 'sopr_1y')), @@ -1987,13 +1987,13 @@ function createAdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitReali * @property {SatsUsdPattern} lowerPriceBand * @property {MetricPattern1} mvrv * @property {MetricPattern1} negRealizedLoss - * @property {CumulativeHeightPattern} netRealizedPnl + * @property {CumulativeHeightPattern} netRealizedPnl * @property {MetricPattern1} netRealizedPnl7dEma * @property {MetricPattern1} netRealizedPnlCumulative30dDelta * @property {MetricPattern1} netRealizedPnlCumulative30dDeltaRelToMarketCap * @property {MetricPattern1} netRealizedPnlCumulative30dDeltaRelToRealizedCap * @property {MetricPattern1} netRealizedPnlRelToRealizedCap - * @property {CumulativeHeightPattern} peakRegret + * @property {CumulativeHeightPattern} peakRegret * @property {MetricPattern1} peakRegretRelToRealizedCap * @property {MetricPattern1} profitFlow * @property {MetricPattern1} profitValueCreated @@ -2002,7 +2002,7 @@ function createAdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitReali * @property {MetricPattern1} realizedCap30dDelta * @property {MetricPattern1} realizedCapCents * @property {MetricPattern1} realizedCapRelToOwnMarketCap - * @property {CumulativeHeightPattern} realizedLoss + * @property {CumulativeHeightPattern} realizedLoss * @property {MetricPattern1} realizedLoss1y * @property {MetricPattern1} realizedLoss24h * @property {MetricPattern1} realizedLoss30d @@ -2012,7 +2012,7 @@ function createAdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitReali * @property {SatsUsdPattern} realizedPrice * @property {RatioPattern2} realizedPriceExtra * @property {RatioPattern3} realizedPriceRatioExt - * @property {CumulativeHeightPattern} realizedProfit + * @property {CumulativeHeightPattern} realizedProfit * @property {MetricPattern1} realizedProfit1y * @property {MetricPattern1} realizedProfit24h * @property {MetricPattern1} realizedProfit30d @@ -2037,9 +2037,9 @@ function createAdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitReali * @property {MetricPattern1} sellSideRiskRatio30dEma * @property {MetricPattern1} sellSideRiskRatio7d * @property {MetricPattern1} sellSideRiskRatio7dEma - * @property {BtcSatsUsdPattern2} sentInLoss + * @property {BaseCumulativePattern} sentInLoss * @property {BtcSatsUsdPattern} sentInLoss14dEma - * @property {BtcSatsUsdPattern2} sentInProfit + * @property {BaseCumulativePattern} sentInProfit * @property {BtcSatsUsdPattern} sentInProfit14dEma * @property {MetricPattern1} sopr * @property {MetricPattern1} sopr1y @@ -2134,9 +2134,9 @@ function createCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellS sellSideRiskRatio30dEma: createMetricPattern1(client, _m(acc, 'sell_side_risk_ratio_30d_ema')), sellSideRiskRatio7d: createMetricPattern1(client, _m(acc, 'sell_side_risk_ratio_7d')), sellSideRiskRatio7dEma: createMetricPattern1(client, _m(acc, 'sell_side_risk_ratio_7d_ema')), - sentInLoss: createBtcSatsUsdPattern2(client, _m(acc, 'sent_in_loss')), + sentInLoss: createBaseCumulativePattern(client, _m(acc, 'sent_in_loss')), sentInLoss14dEma: createBtcSatsUsdPattern(client, _m(acc, 'sent_in_loss_14d_ema')), - sentInProfit: createBtcSatsUsdPattern2(client, _m(acc, 'sent_in_profit')), + sentInProfit: createBaseCumulativePattern(client, _m(acc, 'sent_in_profit')), sentInProfit14dEma: createBtcSatsUsdPattern(client, _m(acc, 'sent_in_profit_14d_ema')), sopr: createMetricPattern1(client, _m(acc, 'sopr')), sopr1y: createMetricPattern1(client, _m(acc, 'sopr_1y')), @@ -2175,13 +2175,13 @@ function createCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellS * @property {SatsUsdPattern} lowerPriceBand * @property {MetricPattern1} mvrv * @property {MetricPattern1} negRealizedLoss - * @property {CumulativeHeightPattern} netRealizedPnl + * @property {CumulativeHeightPattern} netRealizedPnl * @property {MetricPattern1} netRealizedPnl7dEma * @property {MetricPattern1} netRealizedPnlCumulative30dDelta * @property {MetricPattern1} netRealizedPnlCumulative30dDeltaRelToMarketCap * @property {MetricPattern1} netRealizedPnlCumulative30dDeltaRelToRealizedCap * @property {MetricPattern1} netRealizedPnlRelToRealizedCap - * @property {CumulativeHeightPattern} peakRegret + * @property {CumulativeHeightPattern} peakRegret * @property {MetricPattern1} peakRegretRelToRealizedCap * @property {MetricPattern1} profitFlow * @property {MetricPattern1} profitValueCreated @@ -2189,12 +2189,12 @@ function createCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellS * @property {MetricPattern1} realizedCap * @property {MetricPattern1} realizedCap30dDelta * @property {MetricPattern1} realizedCapCents - * @property {CumulativeHeightPattern} realizedLoss + * @property {CumulativeHeightPattern} realizedLoss * @property {MetricPattern1} realizedLoss7dEma * @property {MetricPattern1} realizedLossRelToRealizedCap * @property {SatsUsdPattern} realizedPrice * @property {RatioPattern2} realizedPriceExtra - * @property {CumulativeHeightPattern} realizedProfit + * @property {CumulativeHeightPattern} realizedProfit * @property {MetricPattern1} realizedProfit7dEma * @property {MetricPattern1} realizedProfitRelToRealizedCap * @property {MetricPattern1} realizedValue @@ -2211,9 +2211,9 @@ function createCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellS * @property {MetricPattern1} sellSideRiskRatio30dEma * @property {MetricPattern1} sellSideRiskRatio7d * @property {MetricPattern1} sellSideRiskRatio7dEma - * @property {BtcSatsUsdPattern2} sentInLoss + * @property {BaseCumulativePattern} sentInLoss * @property {BtcSatsUsdPattern} sentInLoss14dEma - * @property {BtcSatsUsdPattern2} sentInProfit + * @property {BaseCumulativePattern} sentInProfit * @property {BtcSatsUsdPattern} sentInProfit14dEma * @property {MetricPattern1} sopr * @property {MetricPattern1} sopr1y @@ -2293,9 +2293,9 @@ function createCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellS sellSideRiskRatio30dEma: createMetricPattern1(client, _m(acc, 'sell_side_risk_ratio_30d_ema')), sellSideRiskRatio7d: createMetricPattern1(client, _m(acc, 'sell_side_risk_ratio_7d')), sellSideRiskRatio7dEma: createMetricPattern1(client, _m(acc, 'sell_side_risk_ratio_7d_ema')), - sentInLoss: createBtcSatsUsdPattern2(client, _m(acc, 'sent_in_loss')), + sentInLoss: createBaseCumulativePattern(client, _m(acc, 'sent_in_loss')), sentInLoss14dEma: createBtcSatsUsdPattern(client, _m(acc, 'sent_in_loss_14d_ema')), - sentInProfit: createBtcSatsUsdPattern2(client, _m(acc, 'sent_in_profit')), + sentInProfit: createBaseCumulativePattern(client, _m(acc, 'sent_in_profit')), sentInProfit14dEma: createBtcSatsUsdPattern(client, _m(acc, 'sent_in_profit_14d_ema')), sopr: createMetricPattern1(client, _m(acc, 'sopr')), sopr1y: createMetricPattern1(client, _m(acc, 'sopr_1y')), @@ -2816,15 +2816,15 @@ function createGreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern(clien * @property {MetricPattern1} blocksMined1ySum * @property {MetricPattern1} blocksMined24hSum * @property {MetricPattern1} blocksSinceBlock - * @property {BtcSatsUsdPattern4} coinbase + * @property {BaseCumulativeSumPattern} coinbase * @property {MetricPattern1} daysSinceBlock * @property {MetricPattern1} dominance * @property {MetricPattern1} dominance1m * @property {MetricPattern1} dominance1w * @property {MetricPattern1} dominance1y * @property {MetricPattern1} dominance24h - * @property {BtcSatsUsdPattern4} fee - * @property {BtcSatsUsdPattern4} subsidy + * @property {BaseCumulativeSumPattern} fee + * @property {BaseCumulativeSumPattern} subsidy */ /** @@ -2841,15 +2841,15 @@ function createBlocksCoinbaseDaysDominanceFeeSubsidyPattern(client, acc) { blocksMined1ySum: createMetricPattern1(client, _m(acc, 'blocks_mined_1y_sum')), blocksMined24hSum: createMetricPattern1(client, _m(acc, 'blocks_mined_24h_sum')), blocksSinceBlock: createMetricPattern1(client, _m(acc, 'blocks_since_block')), - coinbase: createBtcSatsUsdPattern4(client, _m(acc, 'coinbase')), + coinbase: createBaseCumulativeSumPattern(client, _m(acc, 'coinbase')), daysSinceBlock: createMetricPattern1(client, _m(acc, 'days_since_block')), dominance: createMetricPattern1(client, _m(acc, 'dominance')), dominance1m: createMetricPattern1(client, _m(acc, 'dominance_1m')), dominance1w: createMetricPattern1(client, _m(acc, 'dominance_1w')), dominance1y: createMetricPattern1(client, _m(acc, 'dominance_1y')), dominance24h: createMetricPattern1(client, _m(acc, 'dominance_24h')), - fee: createBtcSatsUsdPattern4(client, _m(acc, 'fee')), - subsidy: createBtcSatsUsdPattern4(client, _m(acc, 'subsidy')), + fee: createBaseCumulativeSumPattern(client, _m(acc, 'fee')), + subsidy: createBaseCumulativeSumPattern(client, _m(acc, 'subsidy')), }; } @@ -3065,7 +3065,7 @@ function create_201520162017201820192020202120222023202420252026Pattern2(client, * @property {MetricPattern20} pct25 * @property {MetricPattern20} pct75 * @property {MetricPattern20} pct90 - * @property {AverageMaxMedianMinP10P25P75P90SumPattern} rolling + * @property {AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern} rolling * @property {MetricPattern20} sum */ @@ -3086,42 +3086,79 @@ function createAverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPatter pct25: createMetricPattern20(client, _m(acc, 'pct25')), pct75: createMetricPattern20(client, _m(acc, 'pct75')), pct90: createMetricPattern20(client, _m(acc, 'pct90')), - rolling: createAverageMaxMedianMinP10P25P75P90SumPattern(client, acc), + rolling: createAverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern(client, acc), sum: createMetricPattern20(client, _m(acc, 'sum')), }; } /** - * @typedef {Object} AverageCumulativeMaxMedianMinP10P25P75P90SumPattern + * @typedef {Object} AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern + * @property {_1y24h30d7dPattern} average + * @property {MetricPattern1} cumulative + * @property {MetricPattern20} height + * @property {_1y24h30d7dPattern} max + * @property {_1y24h30d7dPattern} median + * @property {_1y24h30d7dPattern} min + * @property {_1y24h30d7dPattern} pct10 + * @property {_1y24h30d7dPattern} pct25 + * @property {_1y24h30d7dPattern} pct75 + * @property {_1y24h30d7dPattern} pct90 + * @property {_1y24h30d7dPattern} sum + */ + +/** + * Create a AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern} + */ +function createAverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern(client, acc) { + return { + average: create_1y24h30d7dPattern(client, _m(acc, 'average')), + cumulative: createMetricPattern1(client, _m(acc, 'cumulative')), + height: createMetricPattern20(client, acc), + max: create_1y24h30d7dPattern(client, _m(acc, 'max')), + median: create_1y24h30d7dPattern(client, _m(acc, 'median')), + min: create_1y24h30d7dPattern(client, _m(acc, 'min')), + pct10: create_1y24h30d7dPattern(client, _m(acc, 'p10')), + pct25: create_1y24h30d7dPattern(client, _m(acc, 'p25')), + pct75: create_1y24h30d7dPattern(client, _m(acc, 'p75')), + pct90: create_1y24h30d7dPattern(client, _m(acc, 'p90')), + sum: create_1y24h30d7dPattern(client, _m(acc, 'sum')), + }; +} + +/** + * @typedef {Object} AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern * @property {_1y24h30d7dPattern} average * @property {MetricPattern1} cumulative * @property {_1y24h30d7dPattern} max * @property {_1y24h30d7dPattern} median * @property {_1y24h30d7dPattern} min - * @property {_1y24h30d7dPattern} p10 - * @property {_1y24h30d7dPattern} p25 - * @property {_1y24h30d7dPattern} p75 - * @property {_1y24h30d7dPattern} p90 + * @property {_1y24h30d7dPattern} pct10 + * @property {_1y24h30d7dPattern} pct25 + * @property {_1y24h30d7dPattern} pct75 + * @property {_1y24h30d7dPattern} pct90 * @property {_1y24h30d7dPattern} sum */ /** - * Create a AverageCumulativeMaxMedianMinP10P25P75P90SumPattern pattern node + * Create a AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern pattern node * @param {BrkClientBase} client * @param {string} acc - Accumulated metric name - * @returns {AverageCumulativeMaxMedianMinP10P25P75P90SumPattern} + * @returns {AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern} */ -function createAverageCumulativeMaxMedianMinP10P25P75P90SumPattern(client, acc) { +function createAverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern(client, acc) { return { average: create_1y24h30d7dPattern(client, _m(acc, 'average')), cumulative: createMetricPattern1(client, _m(acc, 'cumulative')), max: create_1y24h30d7dPattern(client, _m(acc, 'max')), median: create_1y24h30d7dPattern(client, _m(acc, 'median')), min: create_1y24h30d7dPattern(client, _m(acc, 'min')), - p10: create_1y24h30d7dPattern(client, _m(acc, 'p10')), - p25: create_1y24h30d7dPattern(client, _m(acc, 'p25')), - p75: create_1y24h30d7dPattern(client, _m(acc, 'p75')), - p90: create_1y24h30d7dPattern(client, _m(acc, 'p90')), + pct10: create_1y24h30d7dPattern(client, _m(acc, 'p10')), + pct25: create_1y24h30d7dPattern(client, _m(acc, 'p25')), + pct75: create_1y24h30d7dPattern(client, _m(acc, 'p75')), + pct90: create_1y24h30d7dPattern(client, _m(acc, 'p90')), sum: create_1y24h30d7dPattern(client, _m(acc, 'sum')), }; } @@ -3228,70 +3265,103 @@ function createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern(client, acc) { } /** - * @typedef {Object} AverageMaxMedianMinP10P25P75P90SumPattern + * @typedef {Object} AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2 + * @property {BtcSatsUsdPattern} average + * @property {BtcSatsUsdPattern} max + * @property {BtcSatsUsdPattern} median + * @property {BtcSatsUsdPattern} min + * @property {BtcSatsUsdPattern} pct10 + * @property {BtcSatsUsdPattern} pct25 + * @property {BtcSatsUsdPattern} pct75 + * @property {BtcSatsUsdPattern} pct90 + * @property {BtcSatsUsdPattern} sum + */ + +/** + * Create a AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2 pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2} + */ +function createAverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2(client, acc) { + return { + average: createBtcSatsUsdPattern(client, _m(acc, 'average')), + max: createBtcSatsUsdPattern(client, _m(acc, 'max')), + median: createBtcSatsUsdPattern(client, _m(acc, 'median')), + min: createBtcSatsUsdPattern(client, _m(acc, 'min')), + pct10: createBtcSatsUsdPattern(client, _m(acc, 'p10')), + pct25: createBtcSatsUsdPattern(client, _m(acc, 'p25')), + pct75: createBtcSatsUsdPattern(client, _m(acc, 'p75')), + pct90: createBtcSatsUsdPattern(client, _m(acc, 'p90')), + sum: createBtcSatsUsdPattern(client, _m(acc, 'sum')), + }; +} + +/** + * @typedef {Object} AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern * @property {_1y24h30d7dPattern} average * @property {_1y24h30d7dPattern} max * @property {_1y24h30d7dPattern} median * @property {_1y24h30d7dPattern} min - * @property {_1y24h30d7dPattern} p10 - * @property {_1y24h30d7dPattern} p25 - * @property {_1y24h30d7dPattern} p75 - * @property {_1y24h30d7dPattern} p90 + * @property {_1y24h30d7dPattern} pct10 + * @property {_1y24h30d7dPattern} pct25 + * @property {_1y24h30d7dPattern} pct75 + * @property {_1y24h30d7dPattern} pct90 * @property {_1y24h30d7dPattern} sum */ /** - * Create a AverageMaxMedianMinP10P25P75P90SumPattern pattern node + * Create a AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern pattern node * @param {BrkClientBase} client * @param {string} acc - Accumulated metric name - * @returns {AverageMaxMedianMinP10P25P75P90SumPattern} + * @returns {AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern} */ -function createAverageMaxMedianMinP10P25P75P90SumPattern(client, acc) { +function createAverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern(client, acc) { return { average: create_1y24h30d7dPattern(client, _m(acc, 'average')), max: create_1y24h30d7dPattern(client, _m(acc, 'max')), median: create_1y24h30d7dPattern(client, _m(acc, 'median')), min: create_1y24h30d7dPattern(client, _m(acc, 'min')), - p10: create_1y24h30d7dPattern(client, _m(acc, 'p10')), - p25: create_1y24h30d7dPattern(client, _m(acc, 'p25')), - p75: create_1y24h30d7dPattern(client, _m(acc, 'p75')), - p90: create_1y24h30d7dPattern(client, _m(acc, 'p90')), + pct10: create_1y24h30d7dPattern(client, _m(acc, 'p10')), + pct25: create_1y24h30d7dPattern(client, _m(acc, 'p25')), + pct75: create_1y24h30d7dPattern(client, _m(acc, 'p75')), + pct90: create_1y24h30d7dPattern(client, _m(acc, 'p90')), sum: create_1y24h30d7dPattern(client, _m(acc, 'sum')), }; } /** * @template T - * @typedef {Object} AverageHeightMaxMedianMinP10P25P75P90Pattern + * @typedef {Object} AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern * @property {_1y24h30d7dPattern} average * @property {MetricPattern20} height * @property {_1y24h30d7dPattern} max * @property {_1y24h30d7dPattern} median * @property {_1y24h30d7dPattern} min - * @property {_1y24h30d7dPattern} p10 - * @property {_1y24h30d7dPattern} p25 - * @property {_1y24h30d7dPattern} p75 - * @property {_1y24h30d7dPattern} p90 + * @property {_1y24h30d7dPattern} pct10 + * @property {_1y24h30d7dPattern} pct25 + * @property {_1y24h30d7dPattern} pct75 + * @property {_1y24h30d7dPattern} pct90 */ /** - * Create a AverageHeightMaxMedianMinP10P25P75P90Pattern pattern node + * Create a AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern pattern node * @template T * @param {BrkClientBase} client * @param {string} acc - Accumulated metric name - * @returns {AverageHeightMaxMedianMinP10P25P75P90Pattern} + * @returns {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} */ -function createAverageHeightMaxMedianMinP10P25P75P90Pattern(client, acc) { +function createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, acc) { return { average: create_1y24h30d7dPattern(client, _m(acc, 'average')), height: createMetricPattern20(client, acc), max: create_1y24h30d7dPattern(client, _m(acc, 'max')), median: create_1y24h30d7dPattern(client, _m(acc, 'median')), min: create_1y24h30d7dPattern(client, _m(acc, 'min')), - p10: create_1y24h30d7dPattern(client, _m(acc, 'p10')), - p25: create_1y24h30d7dPattern(client, _m(acc, 'p25')), - p75: create_1y24h30d7dPattern(client, _m(acc, 'p75')), - p90: create_1y24h30d7dPattern(client, _m(acc, 'p90')), + pct10: create_1y24h30d7dPattern(client, _m(acc, 'p10')), + pct25: create_1y24h30d7dPattern(client, _m(acc, 'p25')), + pct75: create_1y24h30d7dPattern(client, _m(acc, 'p75')), + pct90: create_1y24h30d7dPattern(client, _m(acc, 'p90')), }; } @@ -3357,6 +3427,35 @@ function create_10y2y3y4y5y6y8yPattern(client, acc) { }; } +/** + * @typedef {Object} _1y24h30d7dBtcSatsUsdPattern + * @property {BtcSatsUsdPattern} _1y + * @property {BtcSatsUsdPattern} _24h + * @property {BtcSatsUsdPattern} _30d + * @property {BtcSatsUsdPattern} _7d + * @property {MetricPattern20} btc + * @property {MetricPattern20} sats + * @property {MetricPattern20} usd + */ + +/** + * Create a _1y24h30d7dBtcSatsUsdPattern pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {_1y24h30d7dBtcSatsUsdPattern} + */ +function create_1y24h30d7dBtcSatsUsdPattern(client, acc) { + return { + _1y: createBtcSatsUsdPattern(client, _m(acc, '1y')), + _24h: createBtcSatsUsdPattern(client, _m(acc, '24h')), + _30d: createBtcSatsUsdPattern(client, _m(acc, '30d')), + _7d: createBtcSatsUsdPattern(client, _m(acc, '7d')), + btc: createMetricPattern20(client, _m(acc, 'btc')), + sats: createMetricPattern20(client, acc), + usd: createMetricPattern20(client, _m(acc, 'usd')), + }; +} + /** * @typedef {Object} ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern * @property {CoinblocksCoindaysSatblocksSatdaysSentPattern} activity @@ -3473,14 +3572,41 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern5(clien }; } +/** + * @typedef {Object} _1y24h30d7dBaseCumulativePattern + * @property {AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2} _1y + * @property {AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2} _24h + * @property {AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2} _30d + * @property {AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2} _7d + * @property {BtcSatsUsdPattern} base + * @property {BtcSatsUsdPattern} cumulative + */ + +/** + * Create a _1y24h30d7dBaseCumulativePattern pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {_1y24h30d7dBaseCumulativePattern} + */ +function create_1y24h30d7dBaseCumulativePattern(client, acc) { + return { + _1y: createAverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2(client, _m(acc, '1y')), + _24h: createAverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2(client, _m(acc, '24h')), + _30d: createAverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2(client, _m(acc, '30d')), + _7d: createAverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2(client, _m(acc, '7d')), + base: createBtcSatsUsdPattern(client, acc), + cumulative: createBtcSatsUsdPattern(client, _m(acc, 'cumulative')), + }; +} + /** * @typedef {Object} BalanceBothReactivatedReceivingSendingPattern - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} balanceDecreased - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} balanceIncreased - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} both - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} reactivated - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} receiving - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} sending + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} balanceDecreased + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} balanceIncreased + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} both + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} reactivated + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} receiving + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} sending */ /** @@ -3491,12 +3617,12 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern5(clien */ function createBalanceBothReactivatedReceivingSendingPattern(client, acc) { return { - balanceDecreased: createAverageHeightMaxMedianMinP10P25P75P90Pattern(client, _m(acc, 'balance_decreased')), - balanceIncreased: createAverageHeightMaxMedianMinP10P25P75P90Pattern(client, _m(acc, 'balance_increased')), - both: createAverageHeightMaxMedianMinP10P25P75P90Pattern(client, _m(acc, 'both')), - reactivated: createAverageHeightMaxMedianMinP10P25P75P90Pattern(client, _m(acc, 'reactivated')), - receiving: createAverageHeightMaxMedianMinP10P25P75P90Pattern(client, _m(acc, 'receiving')), - sending: createAverageHeightMaxMedianMinP10P25P75P90Pattern(client, _m(acc, 'sending')), + balanceDecreased: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'balance_decreased')), + balanceIncreased: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'balance_increased')), + both: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'both')), + reactivated: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'reactivated')), + receiving: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'receiving')), + sending: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'sending')), }; } @@ -3506,7 +3632,7 @@ function createBalanceBothReactivatedReceivingSendingPattern(client, acc) { * @property {CumulativeHeightSumPattern} coindaysDestroyed * @property {MetricPattern20} satblocksDestroyed * @property {MetricPattern20} satdaysDestroyed - * @property {BtcSatsUsdPattern2} sent + * @property {BaseCumulativePattern} sent * @property {BtcSatsUsdPattern} sent14dEma */ @@ -3522,7 +3648,7 @@ function createCoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc) { coindaysDestroyed: createCumulativeHeightSumPattern(client, _m(acc, 'coindays_destroyed')), satblocksDestroyed: createMetricPattern20(client, _m(acc, 'satblocks_destroyed')), satdaysDestroyed: createMetricPattern20(client, _m(acc, 'satdays_destroyed')), - sent: createBtcSatsUsdPattern2(client, _m(acc, 'sent')), + sent: createBaseCumulativePattern(client, _m(acc, 'sent')), sent14dEma: createBtcSatsUsdPattern(client, _m(acc, 'sent_14d_ema')), }; } @@ -3577,29 +3703,6 @@ function create_1y24h30d7dPattern2(client, acc) { }; } -/** - * @typedef {Object} BtcRollingSatsUsdPattern - * @property {MetricPattern20} btc - * @property {_1y24h30d7dPattern2} rolling - * @property {MetricPattern20} sats - * @property {MetricPattern20} usd - */ - -/** - * Create a BtcRollingSatsUsdPattern pattern node - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {BtcRollingSatsUsdPattern} - */ -function createBtcRollingSatsUsdPattern(client, acc) { - return { - btc: createMetricPattern20(client, _m(acc, 'btc')), - rolling: create_1y24h30d7dPattern2(client, acc), - sats: createMetricPattern20(client, acc), - usd: createMetricPattern20(client, _m(acc, 'usd')), - }; -} - /** * @template T * @typedef {Object} _1h24hBlockTxindexPattern @@ -3672,65 +3775,23 @@ function create_30dHalvedTotalPattern(client, acc) { } /** - * @typedef {Object} BtcSatsUsdPattern2 - * @property {MetricPattern1} btc - * @property {CumulativeHeightPattern} sats - * @property {MetricPattern1} usd + * @typedef {Object} BaseCumulativeSumPattern + * @property {BtcSatsUsdPattern} base + * @property {BtcSatsUsdPattern} cumulative + * @property {_1y24h30d7dPattern2} sum */ /** - * Create a BtcSatsUsdPattern2 pattern node + * Create a BaseCumulativeSumPattern pattern node * @param {BrkClientBase} client * @param {string} acc - Accumulated metric name - * @returns {BtcSatsUsdPattern2} + * @returns {BaseCumulativeSumPattern} */ -function createBtcSatsUsdPattern2(client, acc) { +function createBaseCumulativeSumPattern(client, acc) { return { - btc: createMetricPattern1(client, _m(acc, 'btc')), - sats: createCumulativeHeightPattern(client, acc), - usd: createMetricPattern1(client, _m(acc, 'usd')), - }; -} - -/** - * @typedef {Object} BtcSatsUsdPattern3 - * @property {MetricPattern1} btc - * @property {CumulativeHeightRollingPattern} sats - * @property {CumulativeHeightRollingPattern} usd - */ - -/** - * Create a BtcSatsUsdPattern3 pattern node - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {BtcSatsUsdPattern3} - */ -function createBtcSatsUsdPattern3(client, acc) { - return { - btc: createMetricPattern1(client, _m(acc, 'btc')), - sats: createCumulativeHeightRollingPattern(client, acc), - usd: createCumulativeHeightRollingPattern(client, _m(acc, 'usd')), - }; -} - -/** - * @typedef {Object} BtcSatsUsdPattern4 - * @property {MetricPattern1} btc - * @property {CumulativeHeightSumPattern} sats - * @property {CumulativeHeightSumPattern} usd - */ - -/** - * Create a BtcSatsUsdPattern4 pattern node - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {BtcSatsUsdPattern4} - */ -function createBtcSatsUsdPattern4(client, acc) { - return { - btc: createMetricPattern1(client, _m(acc, 'btc')), - sats: createCumulativeHeightSumPattern(client, acc), - usd: createCumulativeHeightSumPattern(client, _m(acc, 'usd')), + base: createBtcSatsUsdPattern(client, acc), + cumulative: createBtcSatsUsdPattern(client, _m(acc, 'cumulative')), + sum: create_1y24h30d7dPattern2(client, _m(acc, 'sum')), }; } @@ -3797,29 +3858,6 @@ function createHistogramLineSignalPattern(client, acc) { }; } -/** - * @template T - * @typedef {Object} CumulativeHeightRollingPattern - * @property {MetricPattern1} cumulative - * @property {MetricPattern20} height - * @property {AverageMaxMedianMinP10P25P75P90SumPattern} rolling - */ - -/** - * Create a CumulativeHeightRollingPattern pattern node - * @template T - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {CumulativeHeightRollingPattern} - */ -function createCumulativeHeightRollingPattern(client, acc) { - return { - cumulative: createMetricPattern1(client, _m(acc, 'cumulative')), - height: createMetricPattern20(client, acc), - rolling: createAverageMaxMedianMinP10P25P75P90SumPattern(client, acc), - }; -} - /** * @template T * @typedef {Object} CumulativeHeightSumPattern @@ -3862,10 +3900,29 @@ function create_30dCountPattern(client, acc) { }; } +/** + * @typedef {Object} BaseCumulativePattern + * @property {BtcSatsUsdPattern} base + * @property {BtcSatsUsdPattern} cumulative + */ + +/** + * Create a BaseCumulativePattern pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {BaseCumulativePattern} + */ +function createBaseCumulativePattern(client, acc) { + return { + base: createBtcSatsUsdPattern(client, acc), + cumulative: createBtcSatsUsdPattern(client, _m(acc, 'cumulative')), + }; +} + /** * @typedef {Object} BaseRestPattern * @property {MetricPattern20} base - * @property {AverageCumulativeMaxMedianMinP10P25P75P90SumPattern} rest + * @property {AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern} rest */ /** @@ -3877,7 +3934,26 @@ function create_30dCountPattern(client, acc) { function createBaseRestPattern(client, acc) { return { base: createMetricPattern20(client, acc), - rest: createAverageCumulativeMaxMedianMinP10P25P75P90SumPattern(client, acc), + rest: createAverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern(client, acc), + }; +} + +/** + * @typedef {Object} CumulativeHeightPattern + * @property {MetricPattern1} cumulative + * @property {MetricPattern20} height + */ + +/** + * Create a CumulativeHeightPattern pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {CumulativeHeightPattern} + */ +function createCumulativeHeightPattern(client, acc) { + return { + cumulative: createMetricPattern1(client, _m(acc, 'cumulative')), + height: createMetricPattern20(client, acc), }; } @@ -3957,27 +4033,6 @@ function createUtxoPattern(client, acc) { }; } -/** - * @template T - * @typedef {Object} CumulativeHeightPattern - * @property {MetricPattern1} cumulative - * @property {MetricPattern20} height - */ - -/** - * Create a CumulativeHeightPattern pattern node - * @template T - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {CumulativeHeightPattern} - */ -function createCumulativeHeightPattern(client, acc) { - return { - cumulative: createMetricPattern1(client, _m(acc, 'cumulative')), - height: createMetricPattern20(client, acc), - }; -} - /** * @typedef {Object} RatioPattern2 * @property {MetricPattern1} ratio @@ -4025,11 +4080,11 @@ function createRatioPattern2(client, acc) { * @property {MetricPattern20} totalSize * @property {MetricsTree_Blocks_Weight} weight * @property {MetricsTree_Blocks_Count} count - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} interval + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} interval * @property {MetricsTree_Blocks_Halving} halving - * @property {CumulativeHeightRollingPattern} vbytes - * @property {AverageCumulativeMaxMedianMinP10P25P75P90SumPattern} size - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} fullness + * @property {AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern} vbytes + * @property {AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern} size + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} fullness */ /** @@ -4079,11 +4134,11 @@ function createRatioPattern2(client, acc) { * @property {_1y24h30d7dPattern} average * @property {_1y24h30d7dPattern} min * @property {_1y24h30d7dPattern} max - * @property {_1y24h30d7dPattern} p10 - * @property {_1y24h30d7dPattern} p25 + * @property {_1y24h30d7dPattern} pct10 + * @property {_1y24h30d7dPattern} pct25 * @property {_1y24h30d7dPattern} median - * @property {_1y24h30d7dPattern} p75 - * @property {_1y24h30d7dPattern} p90 + * @property {_1y24h30d7dPattern} pct75 + * @property {_1y24h30d7dPattern} pct90 */ /** @@ -4152,7 +4207,7 @@ function createRatioPattern2(client, acc) { /** * @typedef {Object} MetricsTree_Transactions_Count - * @property {CumulativeHeightRollingPattern} txCount + * @property {AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern} txCount * @property {MetricPattern21} isCoinbase */ @@ -4179,8 +4234,8 @@ function createRatioPattern2(client, acc) { /** * @typedef {Object} MetricsTree_Transactions_Volume - * @property {BtcRollingSatsUsdPattern} sentSum - * @property {BtcRollingSatsUsdPattern} receivedSum + * @property {_1y24h30d7dBtcSatsUsdPattern} sentSum + * @property {_1y24h30d7dBtcSatsUsdPattern} receivedSum * @property {BtcSatsUsdPattern} annualizedVolume * @property {MetricPattern1} txPerSec * @property {MetricPattern1} outputsPerSec @@ -4258,6 +4313,7 @@ function createRatioPattern2(client, acc) { * @property {MetricPattern35} unknownToTxindex * @property {MetricsTree_Scripts_Count} count * @property {MetricsTree_Scripts_Value} value + * @property {MetricsTree_Scripts_Adoption} adoption */ /** @@ -4275,13 +4331,17 @@ function createRatioPattern2(client, acc) { * @property {CumulativeHeightSumPattern} emptyoutput * @property {CumulativeHeightSumPattern} unknownoutput * @property {CumulativeHeightSumPattern} segwit - * @property {MetricPattern1} taprootAdoption - * @property {MetricPattern1} segwitAdoption */ /** * @typedef {Object} MetricsTree_Scripts_Value - * @property {BtcSatsUsdPattern3} opreturn + * @property {_1y24h30d7dBaseCumulativePattern} opreturn + */ + +/** + * @typedef {Object} MetricsTree_Scripts_Adoption + * @property {MetricPattern1} taproot + * @property {MetricPattern1} segwit */ /** @@ -4292,10 +4352,10 @@ function createRatioPattern2(client, acc) { /** * @typedef {Object} MetricsTree_Mining_Rewards - * @property {BtcSatsUsdPattern3} coinbase - * @property {BtcSatsUsdPattern3} subsidy - * @property {BtcSatsUsdPattern3} fees - * @property {BtcSatsUsdPattern4} unclaimedRewards + * @property {_1y24h30d7dBaseCumulativePattern} coinbase + * @property {_1y24h30d7dBaseCumulativePattern} subsidy + * @property {_1y24h30d7dBaseCumulativePattern} fees + * @property {BaseCumulativeSumPattern} unclaimedRewards * @property {MetricPattern1} feeDominance * @property {MetricPattern1} feeDominance24h * @property {MetricPattern1} feeDominance7d @@ -4704,7 +4764,7 @@ function createRatioPattern2(client, acc) { /** * @typedef {Object} MetricsTree_Market_Lookback - * @property {SatsUsdPattern} _1d + * @property {SatsUsdPattern} _24h * @property {SatsUsdPattern} _1w * @property {SatsUsdPattern} _1m * @property {SatsUsdPattern} _3m @@ -4734,7 +4794,7 @@ function createRatioPattern2(client, acc) { /** * @typedef {Object} MetricsTree_Market_Returns_PriceReturns - * @property {MetricPattern1} _1d + * @property {MetricPattern1} _24h * @property {MetricPattern1} _1w * @property {MetricPattern1} _1m * @property {MetricPattern1} _3m @@ -5606,15 +5666,15 @@ function createRatioPattern2(client, acc) { /** * @typedef {Object} MetricsTree_Distribution_GrowthRate - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} all - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} p2pk65 - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} p2pk33 - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} p2pkh - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} p2sh - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} p2wpkh - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} p2wsh - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} p2tr - * @property {AverageHeightMaxMedianMinP10P25P75P90Pattern} p2a + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} all + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} p2pk65 + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} p2pk33 + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} p2pkh + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} p2sh + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} p2wpkh + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} p2wsh + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} p2tr + * @property {AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} p2a */ /** @@ -5631,8 +5691,8 @@ function createRatioPattern2(client, acc) { /** * @typedef {Object} MetricsTree_Supply_Burned - * @property {BtcSatsUsdPattern4} opreturn - * @property {BtcSatsUsdPattern4} unspendable + * @property {BaseCumulativeSumPattern} opreturn + * @property {BaseCumulativeSumPattern} unspendable */ /** @@ -6631,11 +6691,11 @@ class BrkClient extends BrkClientBase { average: create_1y24h30d7dPattern(this, 'block_weight_average'), min: create_1y24h30d7dPattern(this, 'block_weight_min'), max: create_1y24h30d7dPattern(this, 'block_weight_max'), - p10: create_1y24h30d7dPattern(this, 'block_weight_p10'), - p25: create_1y24h30d7dPattern(this, 'block_weight_p25'), + pct10: create_1y24h30d7dPattern(this, 'block_weight_p10'), + pct25: create_1y24h30d7dPattern(this, 'block_weight_p25'), median: create_1y24h30d7dPattern(this, 'block_weight_median'), - p75: create_1y24h30d7dPattern(this, 'block_weight_p75'), - p90: create_1y24h30d7dPattern(this, 'block_weight_p90'), + pct75: create_1y24h30d7dPattern(this, 'block_weight_p75'), + pct90: create_1y24h30d7dPattern(this, 'block_weight_p90'), }, count: { blockCountTarget: createMetricPattern1(this, 'block_count_target'), @@ -6673,15 +6733,15 @@ class BrkClient extends BrkClientBase { height8yAgo: createMetricPattern20(this, 'height_8y_ago'), height10yAgo: createMetricPattern20(this, 'height_10y_ago'), }, - interval: createAverageHeightMaxMedianMinP10P25P75P90Pattern(this, 'block_interval'), + interval: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(this, 'block_interval'), halving: { epoch: createMetricPattern1(this, 'halving_epoch'), blocksBeforeNextHalving: createMetricPattern1(this, 'blocks_before_next_halving'), daysBeforeNextHalving: createMetricPattern1(this, 'days_before_next_halving'), }, - vbytes: createCumulativeHeightRollingPattern(this, 'block_vbytes'), - size: createAverageCumulativeMaxMedianMinP10P25P75P90SumPattern(this, 'block_size'), - fullness: createAverageHeightMaxMedianMinP10P25P75P90Pattern(this, 'block_fullness'), + vbytes: createAverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern(this, 'block_vbytes'), + size: createAverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern(this, 'block_size'), + fullness: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(this, 'block_fullness'), }, transactions: { firstTxindex: createMetricPattern20(this, 'first_txindex'), @@ -6695,7 +6755,7 @@ class BrkClient extends BrkClientBase { firstTxinindex: createMetricPattern21(this, 'first_txinindex'), firstTxoutindex: createMetricPattern21(this, 'first_txoutindex'), count: { - txCount: createCumulativeHeightRollingPattern(this, 'tx_count'), + txCount: createAverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern(this, 'tx_count'), isCoinbase: createMetricPattern21(this, 'is_coinbase'), }, size: { @@ -6714,8 +6774,8 @@ class BrkClient extends BrkClientBase { v3: createCumulativeHeightSumPattern(this, 'tx_v3'), }, volume: { - sentSum: createBtcRollingSatsUsdPattern(this, 'sent_sum'), - receivedSum: createBtcRollingSatsUsdPattern(this, 'received_sum'), + sentSum: create_1y24h30d7dBtcSatsUsdPattern(this, 'sent_sum'), + receivedSum: create_1y24h30d7dBtcSatsUsdPattern(this, 'received_sum'), annualizedVolume: createBtcSatsUsdPattern(this, 'annualized_volume'), txPerSec: createMetricPattern1(this, 'tx_per_sec'), outputsPerSec: createMetricPattern1(this, 'outputs_per_sec'), @@ -6789,19 +6849,21 @@ class BrkClient extends BrkClientBase { emptyoutput: createCumulativeHeightSumPattern(this, 'emptyoutput_count'), unknownoutput: createCumulativeHeightSumPattern(this, 'unknownoutput_count'), segwit: createCumulativeHeightSumPattern(this, 'segwit_count'), - taprootAdoption: createMetricPattern1(this, 'taproot_adoption'), - segwitAdoption: createMetricPattern1(this, 'segwit_adoption'), }, value: { - opreturn: createBtcSatsUsdPattern3(this, 'opreturn_value'), + opreturn: create_1y24h30d7dBaseCumulativePattern(this, 'opreturn_value'), + }, + adoption: { + taproot: createMetricPattern1(this, 'taproot_adoption'), + segwit: createMetricPattern1(this, 'segwit_adoption'), }, }, mining: { rewards: { - coinbase: createBtcSatsUsdPattern3(this, 'coinbase'), - subsidy: createBtcSatsUsdPattern3(this, 'subsidy'), - fees: createBtcSatsUsdPattern3(this, 'fees'), - unclaimedRewards: createBtcSatsUsdPattern4(this, 'unclaimed_rewards'), + coinbase: create_1y24h30d7dBaseCumulativePattern(this, 'coinbase'), + subsidy: create_1y24h30d7dBaseCumulativePattern(this, 'subsidy'), + fees: create_1y24h30d7dBaseCumulativePattern(this, 'fees'), + unclaimedRewards: createBaseCumulativeSumPattern(this, 'unclaimed_rewards'), feeDominance: createMetricPattern1(this, 'fee_dominance'), feeDominance24h: createMetricPattern1(this, 'fee_dominance_24h'), feeDominance7d: createMetricPattern1(this, 'fee_dominance_7d'), @@ -7063,7 +7125,7 @@ class BrkClient extends BrkClientBase { maxYearsBetweenPriceAths: createMetricPattern2(this, 'max_years_between_price_aths'), }, lookback: { - _1d: createSatsUsdPattern(this, 'price_1d_ago'), + _24h: createSatsUsdPattern(this, 'price_24h_ago'), _1w: createSatsUsdPattern(this, 'price_1w_ago'), _1m: createSatsUsdPattern(this, 'price_1m_ago'), _3m: createSatsUsdPattern(this, 'price_3m_ago'), @@ -7079,7 +7141,7 @@ class BrkClient extends BrkClientBase { }, returns: { priceReturns: { - _1d: createMetricPattern1(this, '1d_price_returns'), + _24h: createMetricPattern1(this, '24h_price_returns'), _1w: createMetricPattern1(this, '1w_price_returns'), _1m: createMetricPattern1(this, '1m_price_returns'), _3m: createMetricPattern1(this, '3m_price_returns'), @@ -7816,15 +7878,15 @@ class BrkClient extends BrkClientBase { p2a: createBaseRestPattern(this, 'p2a_new_addr_count'), }, growthRate: { - all: createAverageHeightMaxMedianMinP10P25P75P90Pattern(this, 'growth_rate'), - p2pk65: createAverageHeightMaxMedianMinP10P25P75P90Pattern(this, 'p2pk65_growth_rate'), - p2pk33: createAverageHeightMaxMedianMinP10P25P75P90Pattern(this, 'p2pk33_growth_rate'), - p2pkh: createAverageHeightMaxMedianMinP10P25P75P90Pattern(this, 'p2pkh_growth_rate'), - p2sh: createAverageHeightMaxMedianMinP10P25P75P90Pattern(this, 'p2sh_growth_rate'), - p2wpkh: createAverageHeightMaxMedianMinP10P25P75P90Pattern(this, 'p2wpkh_growth_rate'), - p2wsh: createAverageHeightMaxMedianMinP10P25P75P90Pattern(this, 'p2wsh_growth_rate'), - p2tr: createAverageHeightMaxMedianMinP10P25P75P90Pattern(this, 'p2tr_growth_rate'), - p2a: createAverageHeightMaxMedianMinP10P25P75P90Pattern(this, 'p2a_growth_rate'), + all: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(this, 'growth_rate'), + p2pk65: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(this, 'p2pk65_growth_rate'), + p2pk33: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(this, 'p2pk33_growth_rate'), + p2pkh: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(this, 'p2pkh_growth_rate'), + p2sh: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(this, 'p2sh_growth_rate'), + p2wpkh: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(this, 'p2wpkh_growth_rate'), + p2wsh: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(this, 'p2wsh_growth_rate'), + p2tr: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(this, 'p2tr_growth_rate'), + p2a: createAverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(this, 'p2a_growth_rate'), }, fundedaddressindex: createMetricPattern36(this, 'fundedaddressindex'), emptyaddressindex: createMetricPattern37(this, 'emptyaddressindex'), @@ -7832,8 +7894,8 @@ class BrkClient extends BrkClientBase { supply: { circulating: createBtcSatsUsdPattern(this, 'circulating_supply'), burned: { - opreturn: createBtcSatsUsdPattern4(this, 'opreturn_supply'), - unspendable: createBtcSatsUsdPattern4(this, 'unspendable_supply'), + opreturn: createBaseCumulativeSumPattern(this, 'opreturn_supply'), + unspendable: createBaseCumulativeSumPattern(this, 'unspendable_supply'), }, inflation: createMetricPattern1(this, 'inflation_rate'), velocity: { diff --git a/packages/brk_client/brk_client/__init__.py b/packages/brk_client/brk_client/__init__.py index a35f107d7..b147a1d93 100644 --- a/packages/brk_client/brk_client/__init__.py +++ b/packages/brk_client/brk_client/__init__.py @@ -2117,13 +2117,13 @@ class AdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSe self.lower_price_band: SatsUsdPattern = SatsUsdPattern(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_realized_pnl: CumulativeHeightPattern[Dollars] = CumulativeHeightPattern(client, _m(acc, 'net_realized_pnl')) + self.net_realized_pnl: CumulativeHeightPattern = CumulativeHeightPattern(client, _m(acc, 'net_realized_pnl')) self.net_realized_pnl_7d_ema: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'net_realized_pnl_7d_ema')) self.net_realized_pnl_cumulative_30d_delta: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'net_realized_pnl_cumulative_30d_delta')) self.net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_realized_pnl_cumulative_30d_delta_rel_to_market_cap')) self.net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap')) self.net_realized_pnl_rel_to_realized_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_realized_pnl_rel_to_realized_cap')) - self.peak_regret: CumulativeHeightPattern[Dollars] = CumulativeHeightPattern(client, _m(acc, 'realized_peak_regret')) + self.peak_regret: CumulativeHeightPattern = CumulativeHeightPattern(client, _m(acc, 'realized_peak_regret')) self.peak_regret_rel_to_realized_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'peak_regret_rel_to_realized_cap')) self.profit_flow: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'profit_flow')) self.profit_value_created: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'profit_value_created')) @@ -2132,7 +2132,7 @@ class AdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSe self.realized_cap_30d_delta: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_cap_30d_delta')) self.realized_cap_cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_cap_cents')) self.realized_cap_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'realized_cap_rel_to_own_market_cap')) - self.realized_loss: CumulativeHeightPattern[Dollars] = CumulativeHeightPattern(client, _m(acc, 'realized_loss')) + self.realized_loss: CumulativeHeightPattern = CumulativeHeightPattern(client, _m(acc, 'realized_loss')) self.realized_loss_1y: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_loss_1y')) self.realized_loss_24h: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_loss_24h')) self.realized_loss_30d: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_loss_30d')) @@ -2142,7 +2142,7 @@ class AdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSe self.realized_price: SatsUsdPattern = SatsUsdPattern(client, _m(acc, 'realized_price')) self.realized_price_extra: RatioPattern2 = RatioPattern2(client, _m(acc, 'realized_price_ratio')) self.realized_price_ratio_ext: RatioPattern3 = RatioPattern3(client, _m(acc, 'realized_price_ratio')) - self.realized_profit: CumulativeHeightPattern[Dollars] = CumulativeHeightPattern(client, _m(acc, 'realized_profit')) + self.realized_profit: CumulativeHeightPattern = CumulativeHeightPattern(client, _m(acc, 'realized_profit')) self.realized_profit_1y: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_profit_1y')) self.realized_profit_24h: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_profit_24h')) self.realized_profit_30d: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_profit_30d')) @@ -2167,9 +2167,9 @@ class AdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSe self.sell_side_risk_ratio_30d_ema: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sell_side_risk_ratio_30d_ema')) self.sell_side_risk_ratio_7d: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sell_side_risk_ratio_7d')) self.sell_side_risk_ratio_7d_ema: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sell_side_risk_ratio_7d_ema')) - self.sent_in_loss: BtcSatsUsdPattern2 = BtcSatsUsdPattern2(client, _m(acc, 'sent_in_loss')) + self.sent_in_loss: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_loss')) self.sent_in_loss_14d_ema: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'sent_in_loss_14d_ema')) - self.sent_in_profit: BtcSatsUsdPattern2 = BtcSatsUsdPattern2(client, _m(acc, 'sent_in_profit')) + self.sent_in_profit: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_profit')) self.sent_in_profit_14d_ema: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'sent_in_profit_14d_ema')) self.sopr: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'sopr')) self.sopr_1y: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'sopr_1y')) @@ -2228,13 +2228,13 @@ class AdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSe self.lower_price_band: SatsUsdPattern = SatsUsdPattern(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_realized_pnl: CumulativeHeightPattern[Dollars] = CumulativeHeightPattern(client, _m(acc, 'net_realized_pnl')) + self.net_realized_pnl: CumulativeHeightPattern = CumulativeHeightPattern(client, _m(acc, 'net_realized_pnl')) self.net_realized_pnl_7d_ema: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'net_realized_pnl_7d_ema')) self.net_realized_pnl_cumulative_30d_delta: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'net_realized_pnl_cumulative_30d_delta')) self.net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_realized_pnl_cumulative_30d_delta_rel_to_market_cap')) self.net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap')) self.net_realized_pnl_rel_to_realized_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_realized_pnl_rel_to_realized_cap')) - self.peak_regret: CumulativeHeightPattern[Dollars] = CumulativeHeightPattern(client, _m(acc, 'realized_peak_regret')) + self.peak_regret: CumulativeHeightPattern = CumulativeHeightPattern(client, _m(acc, 'realized_peak_regret')) self.peak_regret_rel_to_realized_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'peak_regret_rel_to_realized_cap')) self.profit_flow: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'profit_flow')) self.profit_value_created: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'profit_value_created')) @@ -2242,12 +2242,12 @@ class AdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSe self.realized_cap: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_cap')) self.realized_cap_30d_delta: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_cap_30d_delta')) self.realized_cap_cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_cap_cents')) - self.realized_loss: CumulativeHeightPattern[Dollars] = CumulativeHeightPattern(client, _m(acc, 'realized_loss')) + self.realized_loss: CumulativeHeightPattern = CumulativeHeightPattern(client, _m(acc, 'realized_loss')) self.realized_loss_7d_ema: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_loss_7d_ema')) self.realized_loss_rel_to_realized_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'realized_loss_rel_to_realized_cap')) self.realized_price: SatsUsdPattern = SatsUsdPattern(client, _m(acc, 'realized_price')) self.realized_price_extra: RatioPattern2 = RatioPattern2(client, _m(acc, 'realized_price_ratio')) - self.realized_profit: CumulativeHeightPattern[Dollars] = CumulativeHeightPattern(client, _m(acc, 'realized_profit')) + self.realized_profit: CumulativeHeightPattern = CumulativeHeightPattern(client, _m(acc, 'realized_profit')) self.realized_profit_7d_ema: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_profit_7d_ema')) self.realized_profit_rel_to_realized_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'realized_profit_rel_to_realized_cap')) self.realized_value: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_value')) @@ -2264,9 +2264,9 @@ class AdjustedCapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSe self.sell_side_risk_ratio_30d_ema: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sell_side_risk_ratio_30d_ema')) self.sell_side_risk_ratio_7d: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sell_side_risk_ratio_7d')) self.sell_side_risk_ratio_7d_ema: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sell_side_risk_ratio_7d_ema')) - self.sent_in_loss: BtcSatsUsdPattern2 = BtcSatsUsdPattern2(client, _m(acc, 'sent_in_loss')) + self.sent_in_loss: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_loss')) self.sent_in_loss_14d_ema: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'sent_in_loss_14d_ema')) - self.sent_in_profit: BtcSatsUsdPattern2 = BtcSatsUsdPattern2(client, _m(acc, 'sent_in_profit')) + self.sent_in_profit: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_profit')) self.sent_in_profit_14d_ema: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'sent_in_profit_14d_ema')) self.sopr: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'sopr')) self.sopr_1y: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'sopr_1y')) @@ -2307,13 +2307,13 @@ class CapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprTo self.lower_price_band: SatsUsdPattern = SatsUsdPattern(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_realized_pnl: CumulativeHeightPattern[Dollars] = CumulativeHeightPattern(client, _m(acc, 'net_realized_pnl')) + self.net_realized_pnl: CumulativeHeightPattern = CumulativeHeightPattern(client, _m(acc, 'net_realized_pnl')) self.net_realized_pnl_7d_ema: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'net_realized_pnl_7d_ema')) self.net_realized_pnl_cumulative_30d_delta: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'net_realized_pnl_cumulative_30d_delta')) self.net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_realized_pnl_cumulative_30d_delta_rel_to_market_cap')) self.net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap')) self.net_realized_pnl_rel_to_realized_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_realized_pnl_rel_to_realized_cap')) - self.peak_regret: CumulativeHeightPattern[Dollars] = CumulativeHeightPattern(client, _m(acc, 'realized_peak_regret')) + self.peak_regret: CumulativeHeightPattern = CumulativeHeightPattern(client, _m(acc, 'realized_peak_regret')) self.peak_regret_rel_to_realized_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'peak_regret_rel_to_realized_cap')) self.profit_flow: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'profit_flow')) self.profit_value_created: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'profit_value_created')) @@ -2322,7 +2322,7 @@ class CapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprTo self.realized_cap_30d_delta: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_cap_30d_delta')) self.realized_cap_cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_cap_cents')) self.realized_cap_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'realized_cap_rel_to_own_market_cap')) - self.realized_loss: CumulativeHeightPattern[Dollars] = CumulativeHeightPattern(client, _m(acc, 'realized_loss')) + self.realized_loss: CumulativeHeightPattern = CumulativeHeightPattern(client, _m(acc, 'realized_loss')) self.realized_loss_1y: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_loss_1y')) self.realized_loss_24h: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_loss_24h')) self.realized_loss_30d: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_loss_30d')) @@ -2332,7 +2332,7 @@ class CapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprTo self.realized_price: SatsUsdPattern = SatsUsdPattern(client, _m(acc, 'realized_price')) self.realized_price_extra: RatioPattern2 = RatioPattern2(client, _m(acc, 'realized_price_ratio')) self.realized_price_ratio_ext: RatioPattern3 = RatioPattern3(client, _m(acc, 'realized_price_ratio')) - self.realized_profit: CumulativeHeightPattern[Dollars] = CumulativeHeightPattern(client, _m(acc, 'realized_profit')) + self.realized_profit: CumulativeHeightPattern = CumulativeHeightPattern(client, _m(acc, 'realized_profit')) self.realized_profit_1y: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_profit_1y')) self.realized_profit_24h: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_profit_24h')) self.realized_profit_30d: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_profit_30d')) @@ -2357,9 +2357,9 @@ class CapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprTo self.sell_side_risk_ratio_30d_ema: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sell_side_risk_ratio_30d_ema')) self.sell_side_risk_ratio_7d: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sell_side_risk_ratio_7d')) self.sell_side_risk_ratio_7d_ema: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sell_side_risk_ratio_7d_ema')) - self.sent_in_loss: BtcSatsUsdPattern2 = BtcSatsUsdPattern2(client, _m(acc, 'sent_in_loss')) + self.sent_in_loss: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_loss')) self.sent_in_loss_14d_ema: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'sent_in_loss_14d_ema')) - self.sent_in_profit: BtcSatsUsdPattern2 = BtcSatsUsdPattern2(client, _m(acc, 'sent_in_profit')) + self.sent_in_profit: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_profit')) self.sent_in_profit_14d_ema: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'sent_in_profit_14d_ema')) self.sopr: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'sopr')) self.sopr_1y: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'sopr_1y')) @@ -2399,13 +2399,13 @@ class CapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprTo self.lower_price_band: SatsUsdPattern = SatsUsdPattern(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_realized_pnl: CumulativeHeightPattern[Dollars] = CumulativeHeightPattern(client, _m(acc, 'net_realized_pnl')) + self.net_realized_pnl: CumulativeHeightPattern = CumulativeHeightPattern(client, _m(acc, 'net_realized_pnl')) self.net_realized_pnl_7d_ema: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'net_realized_pnl_7d_ema')) self.net_realized_pnl_cumulative_30d_delta: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'net_realized_pnl_cumulative_30d_delta')) self.net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_realized_pnl_cumulative_30d_delta_rel_to_market_cap')) self.net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap')) self.net_realized_pnl_rel_to_realized_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_realized_pnl_rel_to_realized_cap')) - self.peak_regret: CumulativeHeightPattern[Dollars] = CumulativeHeightPattern(client, _m(acc, 'realized_peak_regret')) + self.peak_regret: CumulativeHeightPattern = CumulativeHeightPattern(client, _m(acc, 'realized_peak_regret')) self.peak_regret_rel_to_realized_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'peak_regret_rel_to_realized_cap')) self.profit_flow: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'profit_flow')) self.profit_value_created: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'profit_value_created')) @@ -2413,12 +2413,12 @@ class CapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprTo self.realized_cap: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_cap')) self.realized_cap_30d_delta: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_cap_30d_delta')) self.realized_cap_cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_cap_cents')) - self.realized_loss: CumulativeHeightPattern[Dollars] = CumulativeHeightPattern(client, _m(acc, 'realized_loss')) + self.realized_loss: CumulativeHeightPattern = CumulativeHeightPattern(client, _m(acc, 'realized_loss')) self.realized_loss_7d_ema: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_loss_7d_ema')) self.realized_loss_rel_to_realized_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'realized_loss_rel_to_realized_cap')) self.realized_price: SatsUsdPattern = SatsUsdPattern(client, _m(acc, 'realized_price')) self.realized_price_extra: RatioPattern2 = RatioPattern2(client, _m(acc, 'realized_price_ratio')) - self.realized_profit: CumulativeHeightPattern[Dollars] = CumulativeHeightPattern(client, _m(acc, 'realized_profit')) + self.realized_profit: CumulativeHeightPattern = CumulativeHeightPattern(client, _m(acc, 'realized_profit')) self.realized_profit_7d_ema: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_profit_7d_ema')) self.realized_profit_rel_to_realized_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'realized_profit_rel_to_realized_cap')) self.realized_value: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_value')) @@ -2435,9 +2435,9 @@ class CapCapitulationInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprTo self.sell_side_risk_ratio_30d_ema: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sell_side_risk_ratio_30d_ema')) self.sell_side_risk_ratio_7d: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sell_side_risk_ratio_7d')) self.sell_side_risk_ratio_7d_ema: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sell_side_risk_ratio_7d_ema')) - self.sent_in_loss: BtcSatsUsdPattern2 = BtcSatsUsdPattern2(client, _m(acc, 'sent_in_loss')) + self.sent_in_loss: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_loss')) self.sent_in_loss_14d_ema: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'sent_in_loss_14d_ema')) - self.sent_in_profit: BtcSatsUsdPattern2 = BtcSatsUsdPattern2(client, _m(acc, 'sent_in_profit')) + self.sent_in_profit: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_profit')) self.sent_in_profit_14d_ema: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'sent_in_profit_14d_ema')) self.sopr: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'sopr')) self.sopr_1y: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'sopr_1y')) @@ -2701,15 +2701,15 @@ class BlocksCoinbaseDaysDominanceFeeSubsidyPattern: self.blocks_mined_1y_sum: MetricPattern1[StoredU32] = MetricPattern1(client, _m(acc, 'blocks_mined_1y_sum')) self.blocks_mined_24h_sum: MetricPattern1[StoredU32] = MetricPattern1(client, _m(acc, 'blocks_mined_24h_sum')) self.blocks_since_block: MetricPattern1[StoredU32] = MetricPattern1(client, _m(acc, 'blocks_since_block')) - self.coinbase: BtcSatsUsdPattern4 = BtcSatsUsdPattern4(client, _m(acc, 'coinbase')) + self.coinbase: BaseCumulativeSumPattern = BaseCumulativeSumPattern(client, _m(acc, 'coinbase')) self.days_since_block: MetricPattern1[StoredU16] = MetricPattern1(client, _m(acc, 'days_since_block')) self.dominance: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'dominance')) self.dominance_1m: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'dominance_1m')) self.dominance_1w: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'dominance_1w')) self.dominance_1y: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'dominance_1y')) self.dominance_24h: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'dominance_24h')) - self.fee: BtcSatsUsdPattern4 = BtcSatsUsdPattern4(client, _m(acc, 'fee')) - self.subsidy: BtcSatsUsdPattern4 = BtcSatsUsdPattern4(client, _m(acc, 'subsidy')) + self.fee: BaseCumulativeSumPattern = BaseCumulativeSumPattern(client, _m(acc, 'fee')) + self.subsidy: BaseCumulativeSumPattern = BaseCumulativeSumPattern(client, _m(acc, 'subsidy')) class InvestedNegNetNuplSupplyUnrealizedPattern4: """Pattern struct for repeated tree structure.""" @@ -2816,10 +2816,27 @@ class AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern: self.pct25: MetricPattern20[StoredU64] = MetricPattern20(client, _m(acc, 'pct25')) self.pct75: MetricPattern20[StoredU64] = MetricPattern20(client, _m(acc, 'pct75')) self.pct90: MetricPattern20[StoredU64] = MetricPattern20(client, _m(acc, 'pct90')) - self.rolling: AverageMaxMedianMinP10P25P75P90SumPattern = AverageMaxMedianMinP10P25P75P90SumPattern(client, acc) + self.rolling: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern = AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern(client, acc) self.sum: MetricPattern20[StoredU64] = MetricPattern20(client, _m(acc, 'sum')) -class AverageCumulativeMaxMedianMinP10P25P75P90SumPattern: +class AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern: + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self.average: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'average')) + self.cumulative: MetricPattern1[StoredU64] = MetricPattern1(client, _m(acc, 'cumulative')) + self.height: MetricPattern20[StoredU64] = MetricPattern20(client, acc) + self.max: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'max')) + self.median: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'median')) + self.min: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'min')) + self.pct10: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p10')) + self.pct25: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p25')) + self.pct75: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p75')) + self.pct90: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p90')) + self.sum: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'sum')) + +class AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): @@ -2829,10 +2846,10 @@ class AverageCumulativeMaxMedianMinP10P25P75P90SumPattern: self.max: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'max')) self.median: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'median')) self.min: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'min')) - self.p10: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p10')) - self.p25: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p25')) - self.p75: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p75')) - self.p90: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p90')) + self.pct10: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p10')) + self.pct25: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p25')) + self.pct75: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p75')) + self.pct90: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p90')) self.sum: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'sum')) class AverageGainsLossesRsiStochPattern: @@ -2881,7 +2898,22 @@ class AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern: self.p2wpkh: _30dCountPattern = _30dCountPattern(client, _p('p2wpkh', acc)) self.p2wsh: _30dCountPattern = _30dCountPattern(client, _p('p2wsh', acc)) -class AverageMaxMedianMinP10P25P75P90SumPattern: +class AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2: + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self.average: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'average')) + self.max: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'max')) + self.median: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'median')) + self.min: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'min')) + self.pct10: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'p10')) + self.pct25: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'p25')) + self.pct75: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'p75')) + self.pct90: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'p90')) + self.sum: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'sum')) + +class AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): @@ -2890,13 +2922,13 @@ class AverageMaxMedianMinP10P25P75P90SumPattern: self.max: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'max')) self.median: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'median')) self.min: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'min')) - self.p10: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p10')) - self.p25: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p25')) - self.p75: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p75')) - self.p90: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p90')) + self.pct10: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p10')) + self.pct25: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p25')) + self.pct75: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p75')) + self.pct90: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'p90')) self.sum: _1y24h30d7dPattern[StoredU64] = _1y24h30d7dPattern(client, _m(acc, 'sum')) -class AverageHeightMaxMedianMinP10P25P75P90Pattern(Generic[T]): +class AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(Generic[T]): """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): @@ -2906,10 +2938,10 @@ class AverageHeightMaxMedianMinP10P25P75P90Pattern(Generic[T]): self.max: _1y24h30d7dPattern[T] = _1y24h30d7dPattern(client, _m(acc, 'max')) self.median: _1y24h30d7dPattern[T] = _1y24h30d7dPattern(client, _m(acc, 'median')) self.min: _1y24h30d7dPattern[T] = _1y24h30d7dPattern(client, _m(acc, 'min')) - self.p10: _1y24h30d7dPattern[T] = _1y24h30d7dPattern(client, _m(acc, 'p10')) - self.p25: _1y24h30d7dPattern[T] = _1y24h30d7dPattern(client, _m(acc, 'p25')) - self.p75: _1y24h30d7dPattern[T] = _1y24h30d7dPattern(client, _m(acc, 'p75')) - self.p90: _1y24h30d7dPattern[T] = _1y24h30d7dPattern(client, _m(acc, 'p90')) + self.pct10: _1y24h30d7dPattern[T] = _1y24h30d7dPattern(client, _m(acc, 'p10')) + self.pct25: _1y24h30d7dPattern[T] = _1y24h30d7dPattern(client, _m(acc, 'p25')) + self.pct75: _1y24h30d7dPattern[T] = _1y24h30d7dPattern(client, _m(acc, 'p75')) + self.pct90: _1y24h30d7dPattern[T] = _1y24h30d7dPattern(client, _m(acc, 'p90')) class AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern(Generic[T]): """Pattern struct for repeated tree structure.""" @@ -2938,6 +2970,19 @@ class _10y2y3y4y5y6y8yPattern: self._6y: MetricPattern1[StoredF32] = MetricPattern1(client, _p('6y', acc)) self._8y: MetricPattern1[StoredF32] = MetricPattern1(client, _p('8y', acc)) +class _1y24h30d7dBtcSatsUsdPattern: + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self._1y: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, '1y')) + self._24h: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, '24h')) + self._30d: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, '30d')) + self._7d: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, '7d')) + self.btc: MetricPattern20[Bitcoin] = MetricPattern20(client, _m(acc, 'btc')) + self.sats: MetricPattern20[Sats] = MetricPattern20(client, acc) + self.usd: MetricPattern20[Dollars] = MetricPattern20(client, _m(acc, 'usd')) + class ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern: """Pattern struct for repeated tree structure.""" @@ -2990,17 +3035,29 @@ class ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern5: self.supply: _30dHalvedTotalPattern = _30dHalvedTotalPattern(client, acc) self.unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern = GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern(client, acc) +class _1y24h30d7dBaseCumulativePattern: + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self._1y: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2 = AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2(client, _m(acc, '1y')) + self._24h: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2 = AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2(client, _m(acc, '24h')) + self._30d: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2 = AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2(client, _m(acc, '30d')) + self._7d: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2 = AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2(client, _m(acc, '7d')) + self.base: BtcSatsUsdPattern = BtcSatsUsdPattern(client, acc) + self.cumulative: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'cumulative')) + class BalanceBothReactivatedReceivingSendingPattern: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" - self.balance_decreased: AverageHeightMaxMedianMinP10P25P75P90Pattern[StoredU32] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, _m(acc, 'balance_decreased')) - self.balance_increased: AverageHeightMaxMedianMinP10P25P75P90Pattern[StoredU32] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, _m(acc, 'balance_increased')) - self.both: AverageHeightMaxMedianMinP10P25P75P90Pattern[StoredU32] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, _m(acc, 'both')) - self.reactivated: AverageHeightMaxMedianMinP10P25P75P90Pattern[StoredU32] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, _m(acc, 'reactivated')) - self.receiving: AverageHeightMaxMedianMinP10P25P75P90Pattern[StoredU32] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, _m(acc, 'receiving')) - self.sending: AverageHeightMaxMedianMinP10P25P75P90Pattern[StoredU32] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, _m(acc, 'sending')) + self.balance_decreased: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredU32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'balance_decreased')) + self.balance_increased: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredU32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'balance_increased')) + self.both: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredU32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'both')) + self.reactivated: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredU32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'reactivated')) + self.receiving: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredU32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'receiving')) + self.sending: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredU32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'sending')) class CoinblocksCoindaysSatblocksSatdaysSentPattern: """Pattern struct for repeated tree structure.""" @@ -3011,7 +3068,7 @@ class CoinblocksCoindaysSatblocksSatdaysSentPattern: self.coindays_destroyed: CumulativeHeightSumPattern[StoredF64] = CumulativeHeightSumPattern(client, _m(acc, 'coindays_destroyed')) self.satblocks_destroyed: MetricPattern20[Sats] = MetricPattern20(client, _m(acc, 'satblocks_destroyed')) self.satdays_destroyed: MetricPattern20[Sats] = MetricPattern20(client, _m(acc, 'satdays_destroyed')) - self.sent: BtcSatsUsdPattern2 = BtcSatsUsdPattern2(client, _m(acc, 'sent')) + self.sent: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent')) self.sent_14d_ema: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'sent_14d_ema')) class InvestedMaxMinPercentilesSpotPattern: @@ -3036,16 +3093,6 @@ class _1y24h30d7dPattern2: self._30d: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, '30d')) self._7d: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, '7d')) -class BtcRollingSatsUsdPattern: - """Pattern struct for repeated tree structure.""" - - def __init__(self, client: BrkClientBase, acc: str): - """Create pattern node with accumulated metric name.""" - self.btc: MetricPattern20[Bitcoin] = MetricPattern20(client, _m(acc, 'btc')) - self.rolling: _1y24h30d7dPattern2 = _1y24h30d7dPattern2(client, acc) - self.sats: MetricPattern20[Sats] = MetricPattern20(client, acc) - self.usd: MetricPattern20[Dollars] = MetricPattern20(client, _m(acc, 'usd')) - class _1h24hBlockTxindexPattern(Generic[T]): """Pattern struct for repeated tree structure.""" @@ -3075,32 +3122,14 @@ class _30dHalvedTotalPattern: self.halved: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'supply_halved')) self.total: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'supply')) -class BtcSatsUsdPattern2: +class BaseCumulativeSumPattern: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" - self.btc: MetricPattern1[Bitcoin] = MetricPattern1(client, _m(acc, 'btc')) - self.sats: CumulativeHeightPattern[Sats] = CumulativeHeightPattern(client, acc) - self.usd: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd')) - -class BtcSatsUsdPattern3: - """Pattern struct for repeated tree structure.""" - - def __init__(self, client: BrkClientBase, acc: str): - """Create pattern node with accumulated metric name.""" - self.btc: MetricPattern1[Bitcoin] = MetricPattern1(client, _m(acc, 'btc')) - self.sats: CumulativeHeightRollingPattern[Sats] = CumulativeHeightRollingPattern(client, acc) - self.usd: CumulativeHeightRollingPattern[Dollars] = CumulativeHeightRollingPattern(client, _m(acc, 'usd')) - -class BtcSatsUsdPattern4: - """Pattern struct for repeated tree structure.""" - - def __init__(self, client: BrkClientBase, acc: str): - """Create pattern node with accumulated metric name.""" - self.btc: MetricPattern1[Bitcoin] = MetricPattern1(client, _m(acc, 'btc')) - self.sats: CumulativeHeightSumPattern[Sats] = CumulativeHeightSumPattern(client, acc) - self.usd: CumulativeHeightSumPattern[Dollars] = CumulativeHeightSumPattern(client, _m(acc, 'usd')) + self.base: BtcSatsUsdPattern = BtcSatsUsdPattern(client, acc) + self.cumulative: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'cumulative')) + self.sum: _1y24h30d7dPattern2 = _1y24h30d7dPattern2(client, _m(acc, 'sum')) class BtcSatsUsdPattern: """Pattern struct for repeated tree structure.""" @@ -3129,15 +3158,6 @@ class HistogramLineSignalPattern: self.line: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'line_1y')) self.signal: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'signal_1y')) -class CumulativeHeightRollingPattern(Generic[T]): - """Pattern struct for repeated tree structure.""" - - def __init__(self, client: BrkClientBase, acc: str): - """Create pattern node with accumulated metric name.""" - self.cumulative: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'cumulative')) - self.height: MetricPattern20[T] = MetricPattern20(client, acc) - self.rolling: AverageMaxMedianMinP10P25P75P90SumPattern = AverageMaxMedianMinP10P25P75P90SumPattern(client, acc) - class CumulativeHeightSumPattern(Generic[T]): """Pattern struct for repeated tree structure.""" @@ -3155,13 +3175,29 @@ class _30dCountPattern: self._30d_change: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, '30d_change')) self.count: MetricPattern1[StoredU64] = MetricPattern1(client, acc) +class BaseCumulativePattern: + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self.base: BtcSatsUsdPattern = BtcSatsUsdPattern(client, acc) + self.cumulative: BtcSatsUsdPattern = BtcSatsUsdPattern(client, _m(acc, 'cumulative')) + class BaseRestPattern: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" self.base: MetricPattern20[StoredU64] = MetricPattern20(client, acc) - self.rest: AverageCumulativeMaxMedianMinP10P25P75P90SumPattern = AverageCumulativeMaxMedianMinP10P25P75P90SumPattern(client, acc) + self.rest: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern = AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern(client, acc) + +class CumulativeHeightPattern: + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self.cumulative: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'cumulative')) + self.height: MetricPattern20[Dollars] = MetricPattern20(client, acc) class MaxMinPattern: """Pattern struct for repeated tree structure.""" @@ -3195,14 +3231,6 @@ class UtxoPattern: self.utxo_count: MetricPattern1[StoredU64] = MetricPattern1(client, acc) self.utxo_count_30d_change: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, '30d_change')) -class CumulativeHeightPattern(Generic[T]): - """Pattern struct for repeated tree structure.""" - - def __init__(self, client: BrkClientBase, acc: str): - """Create pattern node with accumulated metric name.""" - self.cumulative: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'cumulative')) - self.height: MetricPattern20[T] = MetricPattern20(client, acc) - class RatioPattern2: """Pattern struct for repeated tree structure.""" @@ -3264,11 +3292,11 @@ class MetricsTree_Blocks_Weight: self.average: _1y24h30d7dPattern[Weight] = _1y24h30d7dPattern(client, 'block_weight_average') self.min: _1y24h30d7dPattern[Weight] = _1y24h30d7dPattern(client, 'block_weight_min') self.max: _1y24h30d7dPattern[Weight] = _1y24h30d7dPattern(client, 'block_weight_max') - self.p10: _1y24h30d7dPattern[Weight] = _1y24h30d7dPattern(client, 'block_weight_p10') - self.p25: _1y24h30d7dPattern[Weight] = _1y24h30d7dPattern(client, 'block_weight_p25') + self.pct10: _1y24h30d7dPattern[Weight] = _1y24h30d7dPattern(client, 'block_weight_p10') + self.pct25: _1y24h30d7dPattern[Weight] = _1y24h30d7dPattern(client, 'block_weight_p25') self.median: _1y24h30d7dPattern[Weight] = _1y24h30d7dPattern(client, 'block_weight_median') - self.p75: _1y24h30d7dPattern[Weight] = _1y24h30d7dPattern(client, 'block_weight_p75') - self.p90: _1y24h30d7dPattern[Weight] = _1y24h30d7dPattern(client, 'block_weight_p90') + self.pct75: _1y24h30d7dPattern[Weight] = _1y24h30d7dPattern(client, 'block_weight_p75') + self.pct90: _1y24h30d7dPattern[Weight] = _1y24h30d7dPattern(client, 'block_weight_p90') class MetricsTree_Blocks_Count: """Metrics tree node.""" @@ -3327,17 +3355,17 @@ class MetricsTree_Blocks: self.total_size: MetricPattern20[StoredU64] = MetricPattern20(client, 'total_size') self.weight: MetricsTree_Blocks_Weight = MetricsTree_Blocks_Weight(client) self.count: MetricsTree_Blocks_Count = MetricsTree_Blocks_Count(client) - self.interval: AverageHeightMaxMedianMinP10P25P75P90Pattern[Timestamp] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, 'block_interval') + self.interval: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[Timestamp] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, 'block_interval') self.halving: MetricsTree_Blocks_Halving = MetricsTree_Blocks_Halving(client) - self.vbytes: CumulativeHeightRollingPattern[StoredU64] = CumulativeHeightRollingPattern(client, 'block_vbytes') - self.size: AverageCumulativeMaxMedianMinP10P25P75P90SumPattern = AverageCumulativeMaxMedianMinP10P25P75P90SumPattern(client, 'block_size') - self.fullness: AverageHeightMaxMedianMinP10P25P75P90Pattern[StoredF32] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, 'block_fullness') + self.vbytes: AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern = AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern(client, 'block_vbytes') + self.size: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern = AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern(client, 'block_size') + self.fullness: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredF32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, 'block_fullness') class MetricsTree_Transactions_Count: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.tx_count: CumulativeHeightRollingPattern[StoredU64] = CumulativeHeightRollingPattern(client, 'tx_count') + self.tx_count: AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern = AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern(client, 'tx_count') self.is_coinbase: MetricPattern21[StoredBool] = MetricPattern21(client, 'is_coinbase') class MetricsTree_Transactions_Size: @@ -3368,8 +3396,8 @@ class MetricsTree_Transactions_Volume: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.sent_sum: BtcRollingSatsUsdPattern = BtcRollingSatsUsdPattern(client, 'sent_sum') - self.received_sum: BtcRollingSatsUsdPattern = BtcRollingSatsUsdPattern(client, 'received_sum') + self.sent_sum: _1y24h30d7dBtcSatsUsdPattern = _1y24h30d7dBtcSatsUsdPattern(client, 'sent_sum') + self.received_sum: _1y24h30d7dBtcSatsUsdPattern = _1y24h30d7dBtcSatsUsdPattern(client, 'received_sum') self.annualized_volume: BtcSatsUsdPattern = BtcSatsUsdPattern(client, 'annualized_volume') self.tx_per_sec: MetricPattern1[StoredF32] = MetricPattern1(client, 'tx_per_sec') self.outputs_per_sec: MetricPattern1[StoredF32] = MetricPattern1(client, 'outputs_per_sec') @@ -3477,14 +3505,19 @@ class MetricsTree_Scripts_Count: self.emptyoutput: CumulativeHeightSumPattern[StoredU64] = CumulativeHeightSumPattern(client, 'emptyoutput_count') self.unknownoutput: CumulativeHeightSumPattern[StoredU64] = CumulativeHeightSumPattern(client, 'unknownoutput_count') self.segwit: CumulativeHeightSumPattern[StoredU64] = CumulativeHeightSumPattern(client, 'segwit_count') - self.taproot_adoption: MetricPattern1[StoredF32] = MetricPattern1(client, 'taproot_adoption') - self.segwit_adoption: MetricPattern1[StoredF32] = MetricPattern1(client, 'segwit_adoption') class MetricsTree_Scripts_Value: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.opreturn: BtcSatsUsdPattern3 = BtcSatsUsdPattern3(client, 'opreturn_value') + self.opreturn: _1y24h30d7dBaseCumulativePattern = _1y24h30d7dBaseCumulativePattern(client, 'opreturn_value') + +class MetricsTree_Scripts_Adoption: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.taproot: MetricPattern1[StoredF32] = MetricPattern1(client, 'taproot_adoption') + self.segwit: MetricPattern1[StoredF32] = MetricPattern1(client, 'segwit_adoption') class MetricsTree_Scripts: """Metrics tree node.""" @@ -3500,15 +3533,16 @@ class MetricsTree_Scripts: self.unknown_to_txindex: MetricPattern35[TxIndex] = MetricPattern35(client, 'txindex') self.count: MetricsTree_Scripts_Count = MetricsTree_Scripts_Count(client) self.value: MetricsTree_Scripts_Value = MetricsTree_Scripts_Value(client) + self.adoption: MetricsTree_Scripts_Adoption = MetricsTree_Scripts_Adoption(client) class MetricsTree_Mining_Rewards: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.coinbase: BtcSatsUsdPattern3 = BtcSatsUsdPattern3(client, 'coinbase') - self.subsidy: BtcSatsUsdPattern3 = BtcSatsUsdPattern3(client, 'subsidy') - self.fees: BtcSatsUsdPattern3 = BtcSatsUsdPattern3(client, 'fees') - self.unclaimed_rewards: BtcSatsUsdPattern4 = BtcSatsUsdPattern4(client, 'unclaimed_rewards') + self.coinbase: _1y24h30d7dBaseCumulativePattern = _1y24h30d7dBaseCumulativePattern(client, 'coinbase') + self.subsidy: _1y24h30d7dBaseCumulativePattern = _1y24h30d7dBaseCumulativePattern(client, 'subsidy') + self.fees: _1y24h30d7dBaseCumulativePattern = _1y24h30d7dBaseCumulativePattern(client, 'fees') + self.unclaimed_rewards: BaseCumulativeSumPattern = BaseCumulativeSumPattern(client, 'unclaimed_rewards') self.fee_dominance: MetricPattern1[StoredF32] = MetricPattern1(client, 'fee_dominance') self.fee_dominance_24h: MetricPattern1[StoredF32] = MetricPattern1(client, 'fee_dominance_24h') self.fee_dominance_7d: MetricPattern1[StoredF32] = MetricPattern1(client, 'fee_dominance_7d') @@ -3960,7 +3994,7 @@ class MetricsTree_Market_Lookback: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self._1d: SatsUsdPattern = SatsUsdPattern(client, 'price_1d_ago') + self._24h: SatsUsdPattern = SatsUsdPattern(client, 'price_24h_ago') self._1w: SatsUsdPattern = SatsUsdPattern(client, 'price_1w_ago') self._1m: SatsUsdPattern = SatsUsdPattern(client, 'price_1m_ago') self._3m: SatsUsdPattern = SatsUsdPattern(client, 'price_3m_ago') @@ -3978,7 +4012,7 @@ class MetricsTree_Market_Returns_PriceReturns: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self._1d: MetricPattern1[StoredF32] = MetricPattern1(client, '1d_price_returns') + self._24h: MetricPattern1[StoredF32] = MetricPattern1(client, '24h_price_returns') self._1w: MetricPattern1[StoredF32] = MetricPattern1(client, '1w_price_returns') self._1m: MetricPattern1[StoredF32] = MetricPattern1(client, '1m_price_returns') self._3m: MetricPattern1[StoredF32] = MetricPattern1(client, '3m_price_returns') @@ -4909,15 +4943,15 @@ class MetricsTree_Distribution_GrowthRate: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.all: AverageHeightMaxMedianMinP10P25P75P90Pattern[StoredF32] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, 'growth_rate') - self.p2pk65: AverageHeightMaxMedianMinP10P25P75P90Pattern[StoredF32] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, 'p2pk65_growth_rate') - self.p2pk33: AverageHeightMaxMedianMinP10P25P75P90Pattern[StoredF32] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, 'p2pk33_growth_rate') - self.p2pkh: AverageHeightMaxMedianMinP10P25P75P90Pattern[StoredF32] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, 'p2pkh_growth_rate') - self.p2sh: AverageHeightMaxMedianMinP10P25P75P90Pattern[StoredF32] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, 'p2sh_growth_rate') - self.p2wpkh: AverageHeightMaxMedianMinP10P25P75P90Pattern[StoredF32] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, 'p2wpkh_growth_rate') - self.p2wsh: AverageHeightMaxMedianMinP10P25P75P90Pattern[StoredF32] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, 'p2wsh_growth_rate') - self.p2tr: AverageHeightMaxMedianMinP10P25P75P90Pattern[StoredF32] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, 'p2tr_growth_rate') - self.p2a: AverageHeightMaxMedianMinP10P25P75P90Pattern[StoredF32] = AverageHeightMaxMedianMinP10P25P75P90Pattern(client, 'p2a_growth_rate') + self.all: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredF32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, 'growth_rate') + self.p2pk65: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredF32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, 'p2pk65_growth_rate') + self.p2pk33: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredF32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, 'p2pk33_growth_rate') + self.p2pkh: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredF32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, 'p2pkh_growth_rate') + self.p2sh: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredF32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, 'p2sh_growth_rate') + self.p2wpkh: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredF32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, 'p2wpkh_growth_rate') + self.p2wsh: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredF32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, 'p2wsh_growth_rate') + self.p2tr: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredF32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, 'p2tr_growth_rate') + self.p2a: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredF32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, 'p2a_growth_rate') class MetricsTree_Distribution: """Metrics tree node.""" @@ -4941,8 +4975,8 @@ class MetricsTree_Supply_Burned: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.opreturn: BtcSatsUsdPattern4 = BtcSatsUsdPattern4(client, 'opreturn_supply') - self.unspendable: BtcSatsUsdPattern4 = BtcSatsUsdPattern4(client, 'unspendable_supply') + self.opreturn: BaseCumulativeSumPattern = BaseCumulativeSumPattern(client, 'opreturn_supply') + self.unspendable: BaseCumulativeSumPattern = BaseCumulativeSumPattern(client, 'unspendable_supply') class MetricsTree_Supply_Velocity: """Metrics tree node.""" diff --git a/packages/brk_client/tests/test_basic.py b/packages/brk_client/tests/test_basic.py index d68a9ad46..e9311e070 100644 --- a/packages/brk_client/tests/test_basic.py +++ b/packages/brk_client/tests/test_basic.py @@ -56,7 +56,7 @@ def test_fetch_typed_metric(): ) print(e) f = ( - client.metrics.distribution.address_cohorts.amount_range._10k_sats_to_100k_sats.activity.sent.usd.cumulative.by.day1() + client.metrics.distribution.address_cohorts.amount_range._10k_sats_to_100k_sats.activity.sent.cumulative.usd.by.day1() .tail(10) .fetch() ) diff --git a/website/scripts/chart/index.js b/website/scripts/chart/index.js index f43086d61..e55ffee88 100644 --- a/website/scripts/chart/index.js +++ b/website/scripts/chart/index.js @@ -87,7 +87,7 @@ export function createChart({ parent, brk, fitContent }) { const getTimeEndpoint = (idx) => idx === "height" ? brk.metrics.blocks.time.timestampMonotonic.by[idx] - : brk.metrics.blocks.time.timestamp.by[idx]; + : /** @type {any} */ (brk.metrics.blocks.time.timestamp)[idx].by[idx]; const index = { /** @type {Set<(index: ChartableIndex) => void>} */ @@ -137,7 +137,7 @@ export function createChart({ parent, brk, fitContent }) { if (cached) { this.data = cached; } - endpoint.slice(-10000).fetch((result) => { + endpoint.slice(-10000).fetch((/** @type {any} */ result) => { if (currentGen !== generation) return; cache.set(endpoint.path, result); this.data = result; diff --git a/website/scripts/options/cointime.js b/website/scripts/options/cointime.js index 6512886fa..b52e1cf6c 100644 --- a/website/scripts/options/cointime.js +++ b/website/scripts/options/cointime.js @@ -1,7 +1,7 @@ import { colors } from "../utils/colors.js"; import { brk } from "../client.js"; import { Unit } from "../utils/units.js"; -import { dots, line, price } from "./series.js"; +import { dots, line, price, rollingWindowsTree } from "./series.js"; import { satsBtcUsd, createPriceRatioCharts } from "./shared.js"; /** @@ -255,11 +255,11 @@ export function createCointimeSection() { name: "Compare", tree: [ { - name: "Sum", + name: "Base", title: "Coinblocks", bottom: coinblocks.map(({ pattern, name, color }) => line({ - metric: pattern.sum, + metric: pattern.height, name, color, unit: Unit.coinblocks, @@ -284,17 +284,18 @@ export function createCointimeSection() { name, tree: [ { - name: "Sum", + name: "Base", title, bottom: [ line({ - metric: pattern.sum, + metric: pattern.height, name, color, unit: Unit.coinblocks, }), ], }, + rollingWindowsTree({ windows: pattern.sum, title, unit: Unit.coinblocks }), { name: "Cumulative", title: `${title} (Total)`, @@ -320,14 +321,14 @@ export function createCointimeSection() { name: "Compare", tree: [ { - name: "Sum", + name: "Base", title: "Cointime Value", bottom: [ ...cointimeValues.map(({ pattern, name, color }) => - line({ metric: pattern.sum, name, color, unit: Unit.usd }), + line({ metric: pattern.height, name, color, unit: Unit.usd }), ), line({ - metric: vocdd.pattern.sum, + metric: vocdd.pattern.height, name: vocdd.name, color: vocdd.color, unit: Unit.usd, @@ -360,12 +361,13 @@ export function createCointimeSection() { name, tree: [ { - name: "Sum", + name: "Base", title, bottom: [ - line({ metric: pattern.sum, name, color, unit: Unit.usd }), + line({ metric: pattern.height, name, color, unit: Unit.usd }), ], }, + rollingWindowsTree({ windows: pattern.sum, title, unit: Unit.usd }), { name: "Cumulative", title: `${title} (Total)`, @@ -384,11 +386,11 @@ export function createCointimeSection() { name: vocdd.name, tree: [ { - name: "Sum", + name: "Base", title: vocdd.title, bottom: [ line({ - metric: vocdd.pattern.sum, + metric: vocdd.pattern.height, name: vocdd.name, color: vocdd.color, unit: Unit.usd, @@ -401,6 +403,7 @@ export function createCointimeSection() { }), ], }, + rollingWindowsTree({ windows: vocdd.pattern.sum, title: vocdd.title, unit: Unit.usd }), { name: "Cumulative", title: `${vocdd.title} (Total)`, diff --git a/website/scripts/options/distribution/activity.js b/website/scripts/options/distribution/activity.js index 1a4af3f99..2d0f6c5e5 100644 --- a/website/scripts/options/distribution/activity.js +++ b/website/scripts/options/distribution/activity.js @@ -174,13 +174,13 @@ function coinsDestroyedTree(list, all, title) { title: title("Coins Destroyed"), bottom: flatMapCohortsWithAll(list, all, ({ name, color, tree }) => [ line({ - metric: tree.activity.coinblocksDestroyed.sum, + metric: tree.activity.coinblocksDestroyed.sum._24h, name, color, unit: Unit.coinblocks, }), line({ - metric: tree.activity.coindaysDestroyed.sum, + metric: tree.activity.coindaysDestroyed.sum._24h, name, color, unit: Unit.coindays, @@ -677,19 +677,19 @@ export function createActivitySection({ defaultActive: false, }), line({ - metric: tree.activity.sent.sats.sum, + metric: tree.activity.sent.base.sats, name: "sum", color, unit: Unit.sats, }), line({ - metric: tree.activity.sent.btc.sum, + metric: tree.activity.sent.base.btc, name: "sum", color, unit: Unit.btc, }), line({ - metric: tree.activity.sent.usd.sum, + metric: tree.activity.sent.base.usd, name: "sum", color, unit: Unit.usd, @@ -701,19 +701,19 @@ export function createActivitySection({ title: title("Sent Volume (Total)"), bottom: [ line({ - metric: tree.activity.sent.sats.cumulative, + metric: tree.activity.sent.cumulative.sats, name: "all-time", color, unit: Unit.sats, }), line({ - metric: tree.activity.sent.btc.cumulative, + metric: tree.activity.sent.cumulative.btc, name: "all-time", color, unit: Unit.btc, }), line({ - metric: tree.activity.sent.usd.cumulative, + metric: tree.activity.sent.cumulative.usd, name: "all-time", color, unit: Unit.usd, @@ -816,13 +816,13 @@ export function createActivitySection({ title: title("Coins Destroyed"), bottom: [ line({ - metric: tree.activity.coinblocksDestroyed.sum, + metric: tree.activity.coinblocksDestroyed.sum._24h, name: "Coinblocks", color, unit: Unit.coinblocks, }), line({ - metric: tree.activity.coindaysDestroyed.sum, + metric: tree.activity.coindaysDestroyed.sum._24h, name: "Coindays", color, unit: Unit.coindays, @@ -1021,9 +1021,9 @@ export function createGroupedActivitySection({ bottom: flatMapCohortsWithAll(list, all, ({ name, color, tree }) => satsBtcUsd({ pattern: { - sats: tree.activity.sent.sats.sum, - btc: tree.activity.sent.btc.sum, - usd: tree.activity.sent.usd.sum, + sats: tree.activity.sent.base.sats, + btc: tree.activity.sent.base.btc, + usd: tree.activity.sent.base.usd, }, name, color, diff --git a/website/scripts/options/distribution/prices.js b/website/scripts/options/distribution/prices.js index a2af05ac6..fb15905b4 100644 --- a/website/scripts/options/distribution/prices.js +++ b/website/scripts/options/distribution/prices.js @@ -74,7 +74,7 @@ export function createPricesSectionFull({ cohort, title }) { context: cohort.name, legend: "Realized", pricePattern: tree.realized.realizedPrice, - ratio: tree.realized.realizedPriceExtra, + ratio: { ...tree.realized.realizedPriceExtra, ...tree.realized.realizedPriceRatioExt }, color, priceTitle: title("Realized Price"), titlePrefix: "Realized Price", @@ -86,7 +86,7 @@ export function createPricesSectionFull({ cohort, title }) { context: cohort.name, legend: "Investor", pricePattern: tree.realized.investorPrice, - ratio: tree.realized.investorPriceExtra, + ratio: { ...tree.realized.investorPriceExtra, ...tree.realized.investorPriceRatioExt }, color, priceTitle: title("Investor Price"), titlePrefix: "Investor Price", diff --git a/website/scripts/options/distribution/profitability.js b/website/scripts/options/distribution/profitability.js index c19b7df0f..e13acaa4c 100644 --- a/website/scripts/options/distribution/profitability.js +++ b/website/scripts/options/distribution/profitability.js @@ -519,21 +519,21 @@ function realizedPnlSum(tree) { unit: Unit.usd, }), dots({ - metric: r.realizedProfit.sum, + metric: r.realizedProfit.height, name: "Profit", color: colors.profit, unit: Unit.usd, defaultActive: false, }), dots({ - metric: r.negRealizedLoss.sum, + metric: r.negRealizedLoss, name: "Negative Loss", color: colors.loss, unit: Unit.usd, defaultActive: false, }), dots({ - metric: r.realizedLoss.sum, + metric: r.realizedLoss.height, name: "Loss", color: colors.loss, unit: Unit.usd, @@ -547,13 +547,13 @@ function realizedPnlSum(tree) { defaultActive: false, }), baseline({ - metric: r.realizedProfitRelToRealizedCap.sum, + metric: r.realizedProfitRelToRealizedCap, name: "Profit", color: colors.profit, unit: Unit.pctRcap, }), baseline({ - metric: r.realizedLossRelToRealizedCap.sum, + metric: r.realizedLossRelToRealizedCap, name: "Loss", color: colors.loss, unit: Unit.pctRcap, @@ -575,13 +575,13 @@ function realizedNetPnlSum(tree) { unit: Unit.usd, }), dotsBaseline({ - metric: r.netRealizedPnl.sum, + metric: r.netRealizedPnl.height, name: "Net", unit: Unit.usd, defaultActive: false, }), baseline({ - metric: r.netRealizedPnlRelToRealizedCap.sum, + metric: r.netRealizedPnlRelToRealizedCap, name: "Net", unit: Unit.pctRcap, }), @@ -609,20 +609,20 @@ function realizedPnlCumulative(tree) { unit: Unit.usd, }), line({ - metric: r.negRealizedLoss.cumulative, + metric: r.negRealizedLoss, name: "Negative Loss", color: colors.loss, unit: Unit.usd, defaultActive: false, }), baseline({ - metric: r.realizedProfitRelToRealizedCap.cumulative, + metric: r.realizedProfitRelToRealizedCap, name: "Profit", color: colors.profit, unit: Unit.pctRcap, }), baseline({ - metric: r.realizedLossRelToRealizedCap.cumulative, + metric: r.realizedLossRelToRealizedCap, name: "Loss", color: colors.loss, unit: Unit.pctRcap, @@ -644,7 +644,7 @@ function realizedNetPnlCumulative(tree) { unit: Unit.usd, }), baseline({ - metric: r.netRealizedPnlRelToRealizedCap.cumulative, + metric: r.netRealizedPnlRelToRealizedCap, name: "Net", unit: Unit.pctRcap, }), @@ -704,13 +704,13 @@ function sentInPnlTree(tree, title) { }), ...satsBtcUsdFrom({ source: r.sentInProfit, - key: "sum", + key: "base", name: "In Profit", color: colors.profit, }), ...satsBtcUsdFrom({ source: r.sentInLoss, - key: "sum", + key: "base", name: "In Loss", color: colors.loss, }), @@ -945,7 +945,7 @@ function realizedSubfolder(tree, title, rollingTree) { title: title("Realized Peak Regret"), bottom: [ line({ - metric: r.peakRegret.sum, + metric: r.peakRegret.height, name: "Peak Regret", unit: Unit.usd, }), @@ -1839,7 +1839,7 @@ function groupedRealizedPnlSum(list, all, title) { title: title("Realized Profit"), bottom: mapCohortsWithAll(list, all, ({ name, color, tree }) => line({ - metric: tree.realized.realizedProfit.sum, + metric: tree.realized.realizedProfit.height, name, color, unit: Unit.usd, @@ -1851,7 +1851,7 @@ function groupedRealizedPnlSum(list, all, title) { title: title("Realized Loss"), bottom: mapCohortsWithAll(list, all, ({ name, color, tree }) => line({ - metric: tree.realized.negRealizedLoss.sum, + metric: tree.realized.negRealizedLoss, name, color, unit: Unit.usd, @@ -1936,7 +1936,7 @@ function groupedRealizedPnlCumulative(list, all, title) { title: title("Cumulative Realized Loss"), bottom: mapCohortsWithAll(list, all, ({ name, color, tree }) => line({ - metric: tree.realized.negRealizedLoss.cumulative, + metric: tree.realized.realizedLoss.cumulative, name, color, unit: Unit.usd, @@ -1973,7 +1973,7 @@ function groupedSentInPnl(list, all, title) { ...flatMapCohortsWithAll(list, all, ({ name, color, tree }) => satsBtcUsdFrom({ source: tree.realized.sentInProfit, - key: "sum", + key: "base", name, color, }), @@ -1995,7 +1995,7 @@ function groupedSentInPnl(list, all, title) { ...flatMapCohortsWithAll(list, all, ({ name, color, tree }) => satsBtcUsdFrom({ source: tree.realized.sentInLoss, - key: "sum", + key: "base", name, color, }), @@ -2104,7 +2104,7 @@ function groupedRealizedSubfolder(list, all, title) { title: title("Net Realized P&L"), bottom: mapCohortsWithAll(list, all, ({ name, color, tree }) => baseline({ - metric: tree.realized.netRealizedPnl.sum, + metric: tree.realized.netRealizedPnl.height, name, color, unit: Unit.usd, @@ -2166,7 +2166,7 @@ function groupedRealizedSubfolderWithExtras(list, all, title) { title: title("Net Realized P&L"), bottom: mapCohortsWithAll(list, all, ({ name, color, tree }) => baseline({ - metric: tree.realized.netRealizedPnl.sum, + metric: tree.realized.netRealizedPnl.height, name, color, unit: Unit.usd, diff --git a/website/scripts/options/distribution/valuation.js b/website/scripts/options/distribution/valuation.js index f4522ef4b..52c0709c7 100644 --- a/website/scripts/options/distribution/valuation.js +++ b/website/scripts/options/distribution/valuation.js @@ -76,7 +76,7 @@ export function createValuationSectionFull({ cohort, title }) { createRatioChart({ title, pricePattern: tree.realized.realizedPrice, - ratio: tree.realized.realizedPriceExtra, + ratio: { ...tree.realized.realizedPriceExtra, ...tree.realized.realizedPriceRatioExt }, color, name: "MVRV", }), diff --git a/website/scripts/options/mining.js b/website/scripts/options/mining.js index 9b073c6ce..93767c575 100644 --- a/website/scripts/options/mining.js +++ b/website/scripts/options/mining.js @@ -9,11 +9,11 @@ import { dots, dotted, distributionBtcSatsUsd, + rollingWindowsTree, } from "./series.js"; import { satsBtcUsd, satsBtcUsdFrom, - satsBtcUsdFromFull, revenueBtcSatsUsd, } from "./shared.js"; import { brk } from "../client.js"; @@ -53,7 +53,7 @@ const ANTPOOL_AND_FRIENDS_IDS = /** @type {const} */ ([ * @returns {PartialOptionsGroup} */ export function createMiningSection() { - const { blocks, transactions, pools, mining } = brk.metrics; + const { blocks, pools, mining } = brk.metrics; // Pre-compute pool entries with resolved names const poolData = entries(pools.vecs).map(([id, pool]) => ({ @@ -116,44 +116,17 @@ export function createMiningSection() { name: "Blocks Mined", tree: [ { - name: "Sum", + name: "Base", title: `Blocks Mined: ${name}`, bottom: [ line({ - metric: pool.blocksMined.sum, - name: "sum", + metric: pool.blocksMined.height, + name: "base", unit: Unit.count, }), - line({ - metric: pool.blocksMined24hSum, - name: "24h", - color: colors.time._24h, - unit: Unit.count, - defaultActive: false, - }), - line({ - metric: pool.blocksMined1wSum, - name: "1w", - color: colors.time._1w, - unit: Unit.count, - defaultActive: false, - }), - line({ - metric: pool.blocksMined1mSum, - name: "1m", - color: colors.time._1m, - unit: Unit.count, - defaultActive: false, - }), - line({ - metric: pool.blocksMined1ySum, - name: "1y", - color: colors.time._1y, - unit: Unit.count, - defaultActive: false, - }), ], }, + rollingWindowsTree({ windows: pool.blocksMined.sum, title: `Blocks Mined: ${name}`, unit: Unit.count }), { name: "Cumulative", title: `Blocks Mined: ${name} (Total)`, @@ -177,7 +150,7 @@ export function createMiningSection() { coinbase: pool.coinbase, subsidy: pool.subsidy, fee: pool.fee, - key: "sum", + key: "base", }), }, { @@ -372,8 +345,8 @@ export function createMiningSection() { bottom: revenueBtcSatsUsd({ coinbase: mining.rewards.coinbase, subsidy: mining.rewards.subsidy, - fee: transactions.fees.fee, - key: "sum", + fee: mining.rewards.fees, + key: "base", }), }, { @@ -382,7 +355,7 @@ export function createMiningSection() { bottom: revenueBtcSatsUsd({ coinbase: mining.rewards.coinbase, subsidy: mining.rewards.subsidy, - fee: transactions.fees.fee, + fee: mining.rewards.fees, key: "cumulative", }), }, @@ -394,24 +367,11 @@ export function createMiningSection() { { name: "Sum", title: "Coinbase Rewards", - bottom: [ - ...satsBtcUsdFromFull({ - source: mining.rewards.coinbase, - key: "base", - name: "sum", - }), - ...satsBtcUsdFrom({ - source: mining.rewards.coinbase, - key: "sum", - name: "sum", - }), - ...satsBtcUsd({ - pattern: mining.rewards.coinbase24hSum, - name: "24h", - color: colors.time._24h, - defaultActive: false, - }), - ], + bottom: satsBtcUsdFrom({ + source: mining.rewards.coinbase, + key: "base", + name: "sum", + }), }, { name: "Rolling", @@ -421,22 +381,22 @@ export function createMiningSection() { title: "Coinbase Rolling Sum", bottom: [ ...satsBtcUsd({ - pattern: mining.rewards.coinbase24hSum, + pattern: mining.rewards.coinbase._24h.sum, name: "24h", color: colors.time._24h, }), ...satsBtcUsd({ - pattern: mining.rewards.coinbase7dSum, + pattern: mining.rewards.coinbase._7d.sum, name: "7d", color: colors.time._1w, }), ...satsBtcUsd({ - pattern: mining.rewards.coinbase30dSum, + pattern: mining.rewards.coinbase._30d.sum, name: "30d", color: colors.time._1m, }), ...satsBtcUsd({ - pattern: mining.rewards.coinbase1ySum, + pattern: mining.rewards.coinbase._1y.sum, name: "1y", color: colors.time._1y, }), @@ -446,7 +406,7 @@ export function createMiningSection() { name: "24h", title: "Coinbase 24h Rolling Sum", bottom: satsBtcUsd({ - pattern: mining.rewards.coinbase24hSum, + pattern: mining.rewards.coinbase._24h.sum, name: "24h", color: colors.time._24h, }), @@ -455,7 +415,7 @@ export function createMiningSection() { name: "7d", title: "Coinbase 7d Rolling Sum", bottom: satsBtcUsd({ - pattern: mining.rewards.coinbase7dSum, + pattern: mining.rewards.coinbase._7d.sum, name: "7d", color: colors.time._1w, }), @@ -464,7 +424,7 @@ export function createMiningSection() { name: "30d", title: "Coinbase 30d Rolling Sum", bottom: satsBtcUsd({ - pattern: mining.rewards.coinbase30dSum, + pattern: mining.rewards.coinbase._30d.sum, name: "30d", color: colors.time._1m, }), @@ -473,7 +433,7 @@ export function createMiningSection() { name: "1y", title: "Coinbase 1y Rolling Sum", bottom: satsBtcUsd({ - pattern: mining.rewards.coinbase1ySum, + pattern: mining.rewards.coinbase._1y.sum, name: "1y", color: colors.time._1y, }), @@ -483,7 +443,7 @@ export function createMiningSection() { { name: "Distribution", title: "Coinbase Rewards per Block Distribution", - bottom: distributionBtcSatsUsd(mining.rewards.coinbase), + bottom: distributionBtcSatsUsd(mining.rewards.coinbase._24h), }, { name: "Cumulative", @@ -503,14 +463,9 @@ export function createMiningSection() { name: "Sum", title: "Block Subsidy", bottom: [ - ...satsBtcUsdFromFull({ - source: mining.rewards.subsidy, - key: "base", - name: "sum", - }), ...satsBtcUsdFrom({ source: mining.rewards.subsidy, - key: "sum", + key: "base", name: "sum", }), line({ @@ -522,10 +477,77 @@ export function createMiningSection() { }), ], }, + { + name: "Rolling", + tree: [ + { + name: "Compare", + title: "Subsidy Rolling Sum", + bottom: [ + ...satsBtcUsd({ + pattern: mining.rewards.subsidy._24h.sum, + name: "24h", + color: colors.time._24h, + }), + ...satsBtcUsd({ + pattern: mining.rewards.subsidy._7d.sum, + name: "7d", + color: colors.time._1w, + }), + ...satsBtcUsd({ + pattern: mining.rewards.subsidy._30d.sum, + name: "30d", + color: colors.time._1m, + }), + ...satsBtcUsd({ + pattern: mining.rewards.subsidy._1y.sum, + name: "1y", + color: colors.time._1y, + }), + ], + }, + { + name: "24h", + title: "Subsidy 24h Rolling Sum", + bottom: satsBtcUsd({ + pattern: mining.rewards.subsidy._24h.sum, + name: "24h", + color: colors.time._24h, + }), + }, + { + name: "7d", + title: "Subsidy 7d Rolling Sum", + bottom: satsBtcUsd({ + pattern: mining.rewards.subsidy._7d.sum, + name: "7d", + color: colors.time._1w, + }), + }, + { + name: "30d", + title: "Subsidy 30d Rolling Sum", + bottom: satsBtcUsd({ + pattern: mining.rewards.subsidy._30d.sum, + name: "30d", + color: colors.time._1m, + }), + }, + { + name: "1y", + title: "Subsidy 1y Rolling Sum", + bottom: satsBtcUsd({ + pattern: mining.rewards.subsidy._1y.sum, + name: "1y", + color: colors.time._1y, + }), + }, + ], + }, { name: "Distribution", title: "Block Subsidy Distribution", - bottom: distributionBtcSatsUsd(mining.rewards.subsidy), + bottom: distributionBtcSatsUsd(mining.rewards.subsidy._24h), }, { name: "Cumulative", @@ -545,8 +567,8 @@ export function createMiningSection() { name: "Sum", title: "Transaction Fee Revenue per Block", bottom: satsBtcUsdFrom({ - source: transactions.fees.fee, - key: "sum", + source: mining.rewards.fees, + key: "base", name: "sum", }), }, @@ -558,22 +580,22 @@ export function createMiningSection() { title: "Fee Rolling Sum", bottom: [ ...satsBtcUsd({ - pattern: mining.rewards.fee24hSum, + pattern: mining.rewards.fees._24h.sum, name: "24h", color: colors.time._24h, }), ...satsBtcUsd({ - pattern: mining.rewards.fee7dSum, + pattern: mining.rewards.fees._7d.sum, name: "7d", color: colors.time._1w, }), ...satsBtcUsd({ - pattern: mining.rewards.fee30dSum, + pattern: mining.rewards.fees._30d.sum, name: "30d", color: colors.time._1m, }), ...satsBtcUsd({ - pattern: mining.rewards.fee1ySum, + pattern: mining.rewards.fees._1y.sum, name: "1y", color: colors.time._1y, }), @@ -583,7 +605,7 @@ export function createMiningSection() { name: "24h", title: "Fee 24h Rolling Sum", bottom: satsBtcUsd({ - pattern: mining.rewards.fee24hSum, + pattern: mining.rewards.fees._24h.sum, name: "24h", color: colors.time._24h, }), @@ -592,7 +614,7 @@ export function createMiningSection() { name: "7d", title: "Fee 7d Rolling Sum", bottom: satsBtcUsd({ - pattern: mining.rewards.fee7dSum, + pattern: mining.rewards.fees._7d.sum, name: "7d", color: colors.time._1w, }), @@ -601,7 +623,7 @@ export function createMiningSection() { name: "30d", title: "Fee 30d Rolling Sum", bottom: satsBtcUsd({ - pattern: mining.rewards.fee30dSum, + pattern: mining.rewards.fees._30d.sum, name: "30d", color: colors.time._1m, }), @@ -610,7 +632,7 @@ export function createMiningSection() { name: "1y", title: "Fee 1y Rolling Sum", bottom: satsBtcUsd({ - pattern: mining.rewards.fee1ySum, + pattern: mining.rewards.fees._1y.sum, name: "1y", color: colors.time._1y, }), @@ -620,13 +642,13 @@ export function createMiningSection() { { name: "Distribution", title: "Transaction Fee Revenue per Block Distribution", - bottom: distributionBtcSatsUsd(transactions.fees.fee), + bottom: distributionBtcSatsUsd(mining.rewards.fees._24h), }, { name: "Cumulative", title: "Transaction Fee Revenue (Total)", bottom: satsBtcUsdFrom({ - source: transactions.fees.fee, + source: mining.rewards.fees, key: "cumulative", name: "all-time", }), @@ -813,7 +835,7 @@ export function createMiningSection() { title: "Unclaimed Rewards", bottom: satsBtcUsdFrom({ source: mining.rewards.unclaimedRewards, - key: "sum", + key: "base", name: "sum", }), }, @@ -988,7 +1010,7 @@ export function createMiningSection() { bottom: majorPools.flatMap((p, i) => satsBtcUsdFrom({ source: p.pool.coinbase, - key: "sum", + key: "base", name: p.name, color: colors.at(i, majorPools.length), }), @@ -1030,7 +1052,7 @@ export function createMiningSection() { bottom: antpoolFriends.flatMap((p, i) => satsBtcUsdFrom({ source: p.pool.coinbase, - key: "sum", + key: "base", name: p.name, color: colors.at(i, antpoolFriends.length), }), diff --git a/website/scripts/options/network.js b/website/scripts/options/network.js index 3d7586ed3..9bb101a07 100644 --- a/website/scripts/options/network.js +++ b/website/scripts/options/network.js @@ -12,9 +12,12 @@ import { fromSupplyPattern, fromBaseStatsPattern, chartsFromFullPerBlock, + chartsFromCount, chartsFromValueFull, fromStatsPattern, chartsFromSumPerBlock, + statsAtWindow, + rollingWindowsTree, } from "./series.js"; import { satsBtcUsd, satsBtcUsdFrom } from "./shared.js"; @@ -204,17 +207,34 @@ export function createNetworkSection() { }, { name: "New", - tree: chartsFromFullPerBlock({ - pattern: distribution.newAddrCount[key], - title: `${titlePrefix}New Address Count`, - unit: Unit.count, - }), + tree: (() => { + const p = distribution.newAddrCount[key]; + const t = `${titlePrefix}New Address Count`; + return [ + { + name: "Sum", + title: t, + bottom: [ + line({ metric: p.base, name: "base", unit: Unit.count }), + ], + }, + rollingWindowsTree({ windows: p.rest.sum, title: t, unit: Unit.count }), + { + name: "Cumulative", + title: `${t} (Total)`, + bottom: [ + line({ metric: p.rest.cumulative, name: "all-time", unit: Unit.count }), + ], + }, + ]; + })(), }, { name: "Reactivated", title: `${titlePrefix}Reactivated Addresses per Block`, bottom: fromBaseStatsPattern({ pattern: distribution.addressActivity[key].reactivated, + window: "_24h", unit: Unit.count, }), }, @@ -223,6 +243,7 @@ export function createNetworkSection() { title: `${titlePrefix}Address Growth Rate per Block`, bottom: fromBaseStatsPattern({ pattern: distribution.growthRate[key], + window: "_24h", unit: Unit.ratio, }), }, @@ -235,6 +256,7 @@ export function createNetworkSection() { title: `${titlePrefix}${t.title}`, bottom: fromBaseStatsPattern({ pattern: distribution.addressActivity[key][t.key], + window: "_24h", unit: Unit.count, }), })), @@ -246,6 +268,7 @@ export function createNetworkSection() { title: `${titlePrefix}${b.title}`, bottom: fromBaseStatsPattern({ pattern: distribution.addressActivity[key][b.key], + window: "_24h", unit: Unit.count, }), })), @@ -287,7 +310,7 @@ export function createNetworkSection() { unit: Unit.count, }), line({ - metric: distribution.newAddrCount[t.key].sum, + metric: distribution.newAddrCount[t.key].rest.sum._24h, name: t.name, color: t.color, unit: Unit.count, @@ -299,13 +322,14 @@ export function createNetworkSection() { title: `${groupName} Reactivated Addresses per Block`, bottom: types.flatMap((t) => [ line({ - metric: distribution.addressActivity[t.key].reactivated.base, + metric: distribution.addressActivity[t.key].reactivated.height, name: t.name, color: t.color, unit: Unit.count, }), line({ - metric: distribution.addressActivity[t.key].reactivated.average, + metric: + distribution.addressActivity[t.key].reactivated.average._24h, name: t.name, color: t.color, unit: Unit.count, @@ -317,13 +341,13 @@ export function createNetworkSection() { title: `${groupName} Address Growth Rate per Block`, bottom: types.flatMap((t) => [ dots({ - metric: distribution.growthRate[t.key].base, + metric: distribution.growthRate[t.key].height, name: t.name, color: t.color, unit: Unit.ratio, }), dots({ - metric: distribution.growthRate[t.key].average, + metric: distribution.growthRate[t.key].average._24h, name: t.name, color: t.color, unit: Unit.ratio, @@ -337,13 +361,14 @@ export function createNetworkSection() { title: `${groupName} ${tr.compareTitle}`, bottom: types.flatMap((t) => [ line({ - metric: distribution.addressActivity[t.key][tr.key].base, + metric: distribution.addressActivity[t.key][tr.key].height, name: t.name, color: t.color, unit: Unit.count, }), line({ - metric: distribution.addressActivity[t.key][tr.key].average, + metric: + distribution.addressActivity[t.key][tr.key].average._24h, name: t.name, color: t.color, unit: Unit.count, @@ -358,13 +383,14 @@ export function createNetworkSection() { title: `${groupName} ${b.compareTitle}`, bottom: types.flatMap((t) => [ line({ - metric: distribution.addressActivity[t.key][b.key].base, + metric: distribution.addressActivity[t.key][b.key].height, name: t.name, color: t.color, unit: Unit.count, }), line({ - metric: distribution.addressActivity[t.key][b.key].average, + metric: + distribution.addressActivity[t.key][b.key].average._24h, name: t.name, color: t.color, unit: Unit.count, @@ -398,7 +424,7 @@ export function createNetworkSection() { title: `${groupName} Output Count`, bottom: types.map((t) => line({ - metric: scripts.count[t.key].sum, + metric: /** @type {CountPattern} */ (scripts.count[t.key]).sum._24h, name: t.name, color: t.color, unit: Unit.count, @@ -410,7 +436,7 @@ export function createNetworkSection() { title: `${groupName} Output Count (Total)`, bottom: types.map((t) => line({ - metric: scripts.count[t.key].cumulative, + metric: /** @type {CountPattern} */ (scripts.count[t.key]).cumulative, name: t.name, color: t.color, unit: Unit.count, @@ -454,7 +480,7 @@ export function createNetworkSection() { title: "Unspendable Supply", bottom: satsBtcUsdFrom({ source: supply.burned.unspendable, - key: "sum", + key: "base", name: "sum", }), }, @@ -495,7 +521,7 @@ export function createNetworkSection() { name: "Fee Rate", title: "Transaction Fee Rate", bottom: fromStatsPattern({ - pattern: transactions.fees.feeRate, + pattern: transactions.fees.feeRate.block, unit: Unit.feeRate, }), }, @@ -532,11 +558,11 @@ export function createNetworkSection() { title: "Transaction Size", bottom: [ ...fromStatsPattern({ - pattern: transactions.size.weight, + pattern: transactions.size.weight.block, unit: Unit.wu, }), ...fromStatsPattern({ - pattern: transactions.size.vsize, + pattern: transactions.size.vsize.block, unit: Unit.vb, }), ], @@ -545,12 +571,12 @@ export function createNetworkSection() { name: "Versions", tree: [ { - name: "Sum", + name: "Base", title: "Transaction Versions", bottom: entries(transactions.versions).map( ([v, data], i, arr) => line({ - metric: data.sum, + metric: data.height, name: v, color: colors.at(i, arr.length), unit: Unit.count, @@ -600,12 +626,12 @@ export function createNetworkSection() { name: "Count", tree: [ { - name: "Sum", + name: "Base", title: "Block Count", bottom: [ line({ - metric: blocks.count.blockCount.sum, - name: "sum", + metric: blocks.count.blockCount.height, + name: "base", unit: Unit.count, }), line({ @@ -617,36 +643,11 @@ export function createNetworkSection() { }), ], }, - { - name: "Rolling", - title: "Block Count (Rolling)", - bottom: [ - line({ - metric: blocks.count.blockCount24hSum, - name: "24h", - color: colors.time._24h, - unit: Unit.count, - }), - line({ - metric: blocks.count.blockCount1wSum, - name: "1w", - color: colors.time._1w, - unit: Unit.count, - }), - line({ - metric: blocks.count.blockCount1mSum, - name: "1m", - color: colors.time._1m, - unit: Unit.count, - }), - line({ - metric: blocks.count.blockCount1ySum, - name: "1y", - color: colors.time._1y, - unit: Unit.count, - }), - ], - }, + rollingWindowsTree({ + windows: blocks.count.blockCountSum, + title: "Block Count", + unit: Unit.count, + }), { name: "Cumulative", title: "Block Count (Total)", @@ -666,6 +667,7 @@ export function createNetworkSection() { bottom: [ ...fromBaseStatsPattern({ pattern: blocks.interval, + window: "_24h", unit: Unit.secs, }), priceLine({ unit: Unit.secs, name: "Target", number: 600 }), @@ -675,7 +677,7 @@ export function createNetworkSection() { name: "Size", tree: [ { - name: "Sum", + name: "Base", title: "Block Size", bottom: [ line({ @@ -683,13 +685,9 @@ export function createNetworkSection() { name: "base", unit: Unit.bytes, }), - line({ - metric: blocks.size.sum, - name: "sum", - unit: Unit.bytes, - }), ], }, + rollingWindowsTree({ windows: blocks.size.sum, title: "Block Size", unit: Unit.bytes }), { name: "Distribution", title: "Block Size Distribution", @@ -700,7 +698,7 @@ export function createNetworkSection() { unit: Unit.bytes, }), ...fromStatsPattern({ - pattern: blocks.size, + pattern: statsAtWindow(blocks.size, "_24h"), unit: Unit.bytes, }), ], @@ -722,7 +720,7 @@ export function createNetworkSection() { name: "Weight", tree: [ { - name: "Sum", + name: "Base", title: "Block Weight", bottom: [ line({ @@ -730,13 +728,9 @@ export function createNetworkSection() { name: "base", unit: Unit.wu, }), - line({ - metric: blocks.weight.sum, - name: "sum", - unit: Unit.wu, - }), ], }, + rollingWindowsTree({ windows: blocks.weight.sum, title: "Block Weight", unit: Unit.wu }), { name: "Distribution", title: "Block Weight Distribution", @@ -747,7 +741,7 @@ export function createNetworkSection() { unit: Unit.wu, }), ...fromStatsPattern({ - pattern: blocks.weight, + pattern: statsAtWindow(blocks.weight, "_24h"), unit: Unit.wu, }), ], @@ -769,32 +763,28 @@ export function createNetworkSection() { name: "vBytes", tree: [ { - name: "Sum", + name: "Base", title: "Block vBytes", bottom: [ line({ - metric: blocks.vbytes.base, + metric: blocks.vbytes.height, name: "base", unit: Unit.vb, }), - line({ - metric: blocks.vbytes.sum, - name: "sum", - unit: Unit.vb, - }), ], }, + rollingWindowsTree({ windows: blocks.vbytes.sum, title: "Block vBytes", unit: Unit.vb }), { name: "Distribution", title: "Block vBytes Distribution", bottom: [ line({ - metric: blocks.vbytes.base, + metric: blocks.vbytes.height, name: "base", unit: Unit.vb, }), ...fromStatsPattern({ - pattern: blocks.vbytes, + pattern: statsAtWindow(blocks.vbytes, "_24h"), unit: Unit.vb, }), ], @@ -817,6 +807,7 @@ export function createNetworkSection() { title: "Block Fullness", bottom: fromBaseStatsPattern({ pattern: blocks.fullness, + window: "_24h", unit: Unit.percentage, }), }, @@ -949,7 +940,7 @@ export function createNetworkSection() { defaultActive: t.defaultActive, }), line({ - metric: distribution.newAddrCount[t.key].sum, + metric: distribution.newAddrCount[t.key].rest.sum._24h, name: t.name, color: t.color, unit: Unit.count, @@ -963,7 +954,7 @@ export function createNetworkSection() { bottom: addressTypes.flatMap((t) => [ line({ metric: - distribution.addressActivity[t.key].reactivated.base, + distribution.addressActivity[t.key].reactivated.height, name: t.name, color: t.color, unit: Unit.count, @@ -971,7 +962,7 @@ export function createNetworkSection() { }), line({ metric: - distribution.addressActivity[t.key].reactivated.average, + distribution.addressActivity[t.key].reactivated.average._24h, name: t.name, color: t.color, unit: Unit.count, @@ -984,14 +975,14 @@ export function createNetworkSection() { title: "Address Growth Rate per Block by Type", bottom: addressTypes.flatMap((t) => [ dots({ - metric: distribution.growthRate[t.key].base, + metric: distribution.growthRate[t.key].height, name: t.name, color: t.color, unit: Unit.ratio, defaultActive: t.defaultActive, }), dots({ - metric: distribution.growthRate[t.key].average, + metric: distribution.growthRate[t.key].average._24h, name: t.name, color: t.color, unit: Unit.ratio, @@ -1006,7 +997,7 @@ export function createNetworkSection() { title: tr.compareTitle, bottom: addressTypes.flatMap((t) => [ line({ - metric: distribution.addressActivity[t.key][tr.key].base, + metric: distribution.addressActivity[t.key][tr.key].height, name: t.name, color: t.color, unit: Unit.count, @@ -1014,7 +1005,7 @@ export function createNetworkSection() { }), line({ metric: - distribution.addressActivity[t.key][tr.key].average, + distribution.addressActivity[t.key][tr.key].average._24h, name: t.name, color: t.color, unit: Unit.count, @@ -1030,7 +1021,7 @@ export function createNetworkSection() { title: b.compareTitle, bottom: addressTypes.flatMap((t) => [ line({ - metric: distribution.addressActivity[t.key][b.key].base, + metric: distribution.addressActivity[t.key][b.key].height, name: t.name, color: t.color, unit: Unit.count, @@ -1038,7 +1029,7 @@ export function createNetworkSection() { }), line({ metric: - distribution.addressActivity[t.key][b.key].average, + distribution.addressActivity[t.key][b.key].average._24h, name: t.name, color: t.color, unit: Unit.count, @@ -1104,7 +1095,7 @@ export function createNetworkSection() { title: "Output Count by Script Type", bottom: scriptTypes.map((t) => line({ - metric: scripts.count[t.key].sum, + metric: /** @type {CountPattern} */ (scripts.count[t.key]).sum._24h, name: t.name, color: t.color, unit: Unit.count, @@ -1133,8 +1124,8 @@ export function createNetworkSection() { createScriptCompare("Legacy", legacyScripts), ...legacyScripts.map((t) => ({ name: t.name, - tree: chartsFromFullPerBlock({ - pattern: scripts.count[t.key], + tree: chartsFromCount({ + pattern: /** @type {CountPattern} */ (scripts.count[t.key]), title: `${t.name} Output Count`, unit: Unit.count, }), @@ -1147,8 +1138,8 @@ export function createNetworkSection() { createScriptCompare("Script Hash", scriptHashScripts), ...scriptHashScripts.map((t) => ({ name: t.name, - tree: chartsFromFullPerBlock({ - pattern: scripts.count[t.key], + tree: chartsFromCount({ + pattern: /** @type {CountPattern} */ (scripts.count[t.key]), title: `${t.name} Output Count`, unit: Unit.count, }), @@ -1161,8 +1152,8 @@ export function createNetworkSection() { createScriptCompare("SegWit", segwitScripts), ...segwitScripts.map((t) => ({ name: t.name, - tree: chartsFromFullPerBlock({ - pattern: scripts.count[t.key], + tree: chartsFromCount({ + pattern: /** @type {CountPattern} */ (scripts.count[t.key]), title: `${t.name} Output Count`, unit: Unit.count, }), @@ -1175,8 +1166,8 @@ export function createNetworkSection() { createScriptCompare("Taproot", taprootAddresses), ...taprootAddresses.map((t) => ({ name: t.name, - tree: chartsFromFullPerBlock({ - pattern: scripts.count[t.key], + tree: chartsFromCount({ + pattern: /** @type {CountPattern} */ (scripts.count[t.key]), title: `${t.name} Output Count`, unit: Unit.count, }), @@ -1189,8 +1180,8 @@ export function createNetworkSection() { createScriptCompare("Other", otherScripts), ...otherScripts.map((t) => ({ name: t.name, - tree: chartsFromFullPerBlock({ - pattern: scripts.count[t.key], + tree: chartsFromCount({ + pattern: /** @type {CountPattern} */ (scripts.count[t.key]), title: `${t.name} Output Count`, unit: Unit.count, }), @@ -1207,13 +1198,13 @@ export function createNetworkSection() { title: "Script Adoption", bottom: [ line({ - metric: scripts.count.segwitAdoption.cumulative, + metric: scripts.adoption.segwit, name: "SegWit", color: colors.segwit, unit: Unit.percentage, }), line({ - metric: scripts.count.taprootAdoption.cumulative, + metric: scripts.adoption.taproot, name: "Taproot", color: taprootAddresses[1].color, unit: Unit.percentage, @@ -1225,19 +1216,8 @@ export function createNetworkSection() { title: "SegWit Adoption", bottom: [ line({ - metric: scripts.count.segwitAdoption.base, - name: "Base", - unit: Unit.percentage, - }), - line({ - metric: scripts.count.segwitAdoption.sum, - name: "Sum", - unit: Unit.percentage, - }), - line({ - metric: scripts.count.segwitAdoption.cumulative, - name: "All-Time", - color: colors.time.all, + metric: scripts.adoption.segwit, + name: "Adoption", unit: Unit.percentage, }), ], @@ -1247,19 +1227,8 @@ export function createNetworkSection() { title: "Taproot Adoption", bottom: [ line({ - metric: scripts.count.taprootAdoption.base, - name: "Base", - unit: Unit.percentage, - }), - line({ - metric: scripts.count.taprootAdoption.sum, - name: "Sum", - unit: Unit.percentage, - }), - line({ - metric: scripts.count.taprootAdoption.cumulative, - name: "All-Time", - color: colors.time.all, + metric: scripts.adoption.taproot, + name: "Adoption", unit: Unit.percentage, }), ], diff --git a/website/scripts/options/series.js b/website/scripts/options/series.js index a5d0b9aa6..c29e13bd2 100644 --- a/website/scripts/options/series.js +++ b/website/scripts/options/series.js @@ -47,7 +47,7 @@ export function price({ /** * Create percentile series (max/min/median/pct75/pct25/pct90/pct10) from any stats pattern - * @param {StatsPattern | BaseStatsPattern | FullStatsPattern | AnyStatsPattern} pattern + * @param {DistributionStats} pattern * @param {Unit} unit * @param {string} title * @returns {AnyFetchedSeriesBlueprint[]} @@ -356,9 +356,10 @@ export function histogram({ } /** - * Create series from a BaseStatsPattern (base + avg + percentiles, NO sum) + * Create series from an AverageHeightMaxMedianMinP10P25P75P90Pattern (height + rolling stats) * @param {Object} args - * @param {BaseStatsPattern} args.pattern + * @param {{ height: AnyMetricPattern } & Record} args.pattern - Pattern with .height and rolling stats (p10/p25/p75/p90 as _1y24h30d7dPattern) + * @param {string} args.window - Rolling window key (e.g., '_24h', '_7d', '_30d', '_1y') * @param {Unit} args.unit * @param {string} [args.title] * @param {Color} [args.baseColor] @@ -367,34 +368,37 @@ export function histogram({ */ export function fromBaseStatsPattern({ pattern, + window, unit, title = "", baseColor, avgActive = true, }) { const { stat } = colors; + const stats = statsAtWindow(pattern, window); return [ dots({ - metric: pattern.base, + metric: pattern.height, name: title || "base", color: baseColor, unit, }), dots({ - metric: pattern.average, + metric: stats.average, name: `${title} avg`.trim(), color: stat.avg, unit, defaultActive: avgActive, }), - ...percentileSeries(pattern, unit, title), + ...percentileSeries(stats, unit, title), ]; } /** - * Create series from any pattern with avg + percentiles (works with StatsPattern, SumStatsPattern, etc.) + * Create series from a flat stats pattern (average + pct percentiles as single metrics) + * Use statsAtWindow() to extract from patterns with _1y24h30d7dPattern stats * @param {Object} args - * @param {StatsPattern | BaseStatsPattern | FullStatsPattern | AnyStatsPattern} args.pattern + * @param {{ average: AnyMetricPattern, median: AnyMetricPattern, max: AnyMetricPattern, min: AnyMetricPattern, pct75: AnyMetricPattern, pct25: AnyMetricPattern, pct90: AnyMetricPattern, pct10: AnyMetricPattern }} args.pattern * @param {Unit} args.unit * @param {string} [args.title] * @returns {AnyFetchedSeriesBlueprint[]} @@ -412,14 +416,96 @@ export function fromStatsPattern({ pattern, unit, title = "" }) { } /** - * Create distribution series for btc/sats/usd from a value pattern with stats (average + percentiles) - * @param {FullValuePattern | SumValuePattern} source + * Extract stats at a specific rolling window from patterns with _1y24h30d7dPattern stats + * @param {Record} pattern - Pattern with pct10/pct25/pct75/pct90 and average/median/max/min as _1y24h30d7dPattern + * @param {string} window + */ +export function statsAtWindow(pattern, window) { + return { + average: pattern.average[window], + median: pattern.median[window], + max: pattern.max[window], + min: pattern.min[window], + pct75: pattern.pct75[window], + pct25: pattern.pct25[window], + pct90: pattern.pct90[window], + pct10: pattern.pct10[window], + }; +} + +/** + * Create a Rolling folder tree from a _1y24h30d7dPattern (4 rolling windows) + * @param {Object} args + * @param {{ _24h: AnyMetricPattern, _7d: AnyMetricPattern, _30d: AnyMetricPattern, _1y: AnyMetricPattern }} args.windows + * @param {string} args.title + * @param {Unit} args.unit + * @returns {PartialOptionsGroup} + */ +export function rollingWindowsTree({ windows, title, unit }) { + return { + name: "Rolling", + tree: [ + { + name: "Compare", + title: `${title} Rolling`, + bottom: [ + line({ metric: windows._24h, name: "24h", color: colors.time._24h, unit }), + line({ metric: windows._7d, name: "7d", color: colors.time._1w, unit }), + line({ metric: windows._30d, name: "30d", color: colors.time._1m, unit }), + line({ metric: windows._1y, name: "1y", color: colors.time._1y, unit }), + ], + }, + { + name: "24h", + title: `${title} 24h`, + bottom: [line({ metric: windows._24h, name: "24h", color: colors.time._24h, unit })], + }, + { + name: "7d", + title: `${title} 7d`, + bottom: [line({ metric: windows._7d, name: "7d", color: colors.time._1w, unit })], + }, + { + name: "30d", + title: `${title} 30d`, + bottom: [line({ metric: windows._30d, name: "30d", color: colors.time._1m, unit })], + }, + { + name: "1y", + title: `${title} 1y`, + bottom: [line({ metric: windows._1y, name: "1y", color: colors.time._1y, unit })], + }, + ], + }; +} + +/** + * Map a rolling window slot's stats to a specific unit, producing a stats-compatible pattern + * @param {RollingWindowSlot} slot - Rolling window slot (e.g., pattern.rolling._24h) + * @param {BtcSatsUsdKey} unitKey + */ +function rollingSlotForUnit(slot, unitKey) { + return { + average: slot.average[unitKey], + median: slot.median[unitKey], + max: slot.max[unitKey], + min: slot.min[unitKey], + pct75: slot.pct75[unitKey], + pct25: slot.pct25[unitKey], + pct90: slot.pct90[unitKey], + pct10: slot.pct10[unitKey], + }; +} + +/** + * Create distribution series for btc/sats/usd from a rolling window slot + * @param {RollingWindowSlot} slot - Rolling window slot (e.g., pattern.rolling._24h) * @returns {AnyFetchedSeriesBlueprint[]} */ -export const distributionBtcSatsUsd = (source) => [ - ...fromStatsPattern({ pattern: source.btc, unit: Unit.btc }), - ...fromStatsPattern({ pattern: source.sats, unit: Unit.sats }), - ...fromStatsPattern({ pattern: source.usd, unit: Unit.usd }), +export const distributionBtcSatsUsd = (slot) => [ + ...fromStatsPattern({ pattern: rollingSlotForUnit(slot, "btc"), unit: Unit.btc }), + ...fromStatsPattern({ pattern: rollingSlotForUnit(slot, "sats"), unit: Unit.sats }), + ...fromStatsPattern({ pattern: rollingSlotForUnit(slot, "usd"), unit: Unit.usd }), ]; /** @@ -460,7 +546,7 @@ export function fromSupplyPattern({ pattern, title, color }) { /** * Create distribution series (avg + percentiles) - * @param {StatsPattern | BaseStatsPattern | FullStatsPattern | AnyStatsPattern} pattern + * @param {DistributionStats} pattern * @param {Unit} unit * @returns {AnyFetchedSeriesBlueprint[]} */ @@ -556,9 +642,10 @@ function btcSatsUsdSeries({ metrics, name, color, defaultActive }) { } /** - * Split pattern with base + sum + distribution + cumulative into 3 charts + * Split flat per-block pattern into charts (Sum/Rolling/Distribution/Cumulative) + * Pattern has: .height, .cumulative, .sum (windowed), .average/.pct10/... (windowed, flat) * @param {Object} args - * @param {FullStatsPattern} args.pattern + * @param {FullPerBlockPattern} args.pattern * @param {string} args.title * @param {Unit} args.unit * @param {string} [args.distributionSuffix] @@ -577,15 +664,13 @@ export function chartsFromFull({ { name: "Sum", title, - bottom: [ - { metric: pattern.base, title: "sum", unit }, - { metric: pattern.sum, title: "sum", unit }, - ], + bottom: [{ metric: pattern.height, title: "base", unit }], }, + rollingWindowsTree({ windows: pattern.sum, title, unit }), { name: "Distribution", title: distTitle, - bottom: distributionSeries(pattern, unit), + bottom: distributionSeries(statsAtWindow(pattern, "_24h"), unit), }, { name: "Cumulative", @@ -596,9 +681,9 @@ export function chartsFromFull({ } /** - * Split pattern into 3 charts with "per Block" in distribution title + * Split pattern into 4 charts with "per Block" in distribution title * @param {Object} args - * @param {FullStatsPattern} args.pattern + * @param {FullPerBlockPattern} args.pattern * @param {string} args.title * @param {Unit} args.unit * @returns {PartialOptionsTree} @@ -609,7 +694,7 @@ export const chartsFromFullPerBlock = (args) => /** * Split pattern with sum + distribution + cumulative into 3 charts (no base) * @param {Object} args - * @param {AnyStatsPattern} args.pattern + * @param {FullStatsPattern} args.pattern * @param {string} args.title * @param {Unit} args.unit * @param {string} [args.distributionSuffix] @@ -647,7 +732,7 @@ export function chartsFromSum({ /** * Split pattern into 3 charts with "per Block" in distribution title (no base) * @param {Object} args - * @param {AnyStatsPattern} args.pattern + * @param {FullStatsPattern} args.pattern * @param {string} args.title * @param {Unit} args.unit * @returns {PartialOptionsTree} @@ -656,7 +741,7 @@ export const chartsFromSumPerBlock = (args) => chartsFromSum({ ...args, distributionSuffix: "per Block" }); /** - * Split pattern with sum + cumulative into 2 charts + * Split pattern with rolling sum windows + cumulative into charts * @param {Object} args * @param {CountPattern} args.pattern * @param {string} args.title @@ -666,11 +751,7 @@ export const chartsFromSumPerBlock = (args) => */ export function chartsFromCount({ pattern, title, unit, color }) { return [ - { - name: "Sum", - title, - bottom: [{ metric: pattern.sum, title: "sum", color, unit }], - }, + rollingWindowsTree({ windows: pattern.sum, title, unit }), { name: "Cumulative", title: `${title} (Total)`, @@ -680,46 +761,7 @@ export function chartsFromCount({ pattern, title, unit, color }) { } /** - * Split value pattern (btc/sats/usd with sum + cumulative) into 2 charts - * @param {Object} args - * @param {ValuePattern} args.pattern - * @param {string} args.title - * @param {Color} [args.color] - * @returns {PartialOptionsTree} - */ -export function chartsFromValue({ pattern, title, color }) { - return [ - { - name: "Sum", - title, - bottom: btcSatsUsdSeries({ - metrics: { - btc: pattern.btc.sum, - sats: pattern.sats.sum, - usd: pattern.usd.sum, - }, - name: "sum", - color, - }), - }, - { - name: "Cumulative", - title: `${title} (Total)`, - bottom: btcSatsUsdSeries({ - metrics: { - btc: pattern.btc.cumulative, - sats: pattern.sats.cumulative, - usd: pattern.usd.cumulative, - }, - name: "all-time", - color, - }), - }, - ]; -} - -/** - * Split btc/sats/usd pattern with full stats into 3 charts + * Split BaseCumulativeRollingPattern into 3 charts (Sum/Distribution/Cumulative) * @param {Object} args * @param {CoinbasePattern} args.pattern * @param {string} args.title @@ -731,44 +773,23 @@ export function chartsFromValueFull({ pattern, title }) { name: "Sum", title, bottom: [ + ...btcSatsUsdSeries({ metrics: pattern.base, name: "sum" }), ...btcSatsUsdSeries({ - metrics: { - btc: pattern.btc.base, - sats: pattern.sats.base, - usd: pattern.usd.base, - }, - name: "sum", - }), - ...btcSatsUsdSeries({ - metrics: { - btc: pattern.btc.sum, - sats: pattern.sats.sum, - usd: pattern.usd.sum, - }, - name: "sum", + metrics: pattern._24h.sum, + name: "24h sum", + defaultActive: false, }), ], }, { name: "Distribution", title: `${title} Distribution`, - bottom: [ - ...distributionSeries(pattern.btc, Unit.btc), - ...distributionSeries(pattern.sats, Unit.sats), - ...distributionSeries(pattern.usd, Unit.usd), - ], + bottom: distributionBtcSatsUsd(pattern._24h), }, { name: "Cumulative", title: `${title} (Total)`, - bottom: btcSatsUsdSeries({ - metrics: { - btc: pattern.btc.cumulative, - sats: pattern.sats.cumulative, - usd: pattern.usd.cumulative, - }, - name: "all-time", - }), + bottom: btcSatsUsdSeries({ metrics: pattern.cumulative, name: "all-time" }), }, ]; } diff --git a/website/scripts/options/shared.js b/website/scripts/options/shared.js index 77a9bb203..11e786c58 100644 --- a/website/scripts/options/shared.js +++ b/website/scripts/options/shared.js @@ -146,10 +146,10 @@ export function satsBtcUsdBaseline({ pattern, name, color, defaultActive }) { } /** - * Create sats/btc/usd series from any value pattern using sum or cumulative key + * Create sats/btc/usd series from any value pattern using base or cumulative key * @param {Object} args * @param {AnyValuePatternType} args.source - * @param {'sum' | 'cumulative'} args.key + * @param {'base' | 'cumulative'} args.key * @param {string} args.name * @param {Color} [args.color] * @param {boolean} [args.defaultActive] @@ -157,11 +157,7 @@ export function satsBtcUsdBaseline({ pattern, name, color, defaultActive }) { */ export function satsBtcUsdFrom({ source, key, name, color, defaultActive }) { return satsBtcUsd({ - pattern: { - btc: source.btc[key], - sats: source.sats[key], - usd: source.usd[key], - }, + pattern: source[key], name, color, defaultActive, @@ -169,10 +165,10 @@ export function satsBtcUsdFrom({ source, key, name, color, defaultActive }) { } /** - * Create sats/btc/usd series from a full value pattern using base or average key + * Create sats/btc/usd series from a full value pattern using base or cumulative key * @param {Object} args * @param {FullValuePattern} args.source - * @param {'base' | 'average'} args.key + * @param {'base' | 'cumulative'} args.key * @param {string} args.name * @param {Color} [args.color] * @param {boolean} [args.defaultActive] @@ -186,11 +182,7 @@ export function satsBtcUsdFromFull({ defaultActive, }) { return satsBtcUsd({ - pattern: { - btc: source.btc[key], - sats: source.sats[key], - usd: source.usd[key], - }, + pattern: source[key], name, color, defaultActive, @@ -203,7 +195,7 @@ export function satsBtcUsdFromFull({ * @param {AnyValuePatternType} args.coinbase * @param {AnyValuePatternType} args.subsidy * @param {AnyValuePatternType} args.fee - * @param {'sum' | 'cumulative'} args.key + * @param {'base' | 'cumulative'} args.key * @returns {FetchedLineSeriesBlueprint[]} */ export function revenueBtcSatsUsd({ coinbase, subsidy, fee, key }) { @@ -229,6 +221,47 @@ export function revenueBtcSatsUsd({ coinbase, subsidy, fee, key }) { ]; } +/** + * Create sats/btc/usd series from a rolling window (24h/7d/30d/1y sum) + * @param {Object} args + * @param {AnyValuePattern} args.pattern - A BtcSatsUsdPattern (e.g., source.rolling._24h.sum) + * @param {string} args.name + * @param {Color} [args.color] + * @param {boolean} [args.defaultActive] + * @returns {FetchedLineSeriesBlueprint[]} + */ +export function satsBtcUsdRolling({ pattern, name, color, defaultActive }) { + return satsBtcUsd({ pattern, name, color, defaultActive }); +} + +/** + * Create coinbase/subsidy/fee rolling sum series from separate sources + * @param {Object} args + * @param {AnyValuePattern} args.coinbase - Rolling sum pattern (e.g., mining.rewards.coinbase.rolling._24h.sum) + * @param {AnyValuePattern} args.subsidy + * @param {AnyValuePattern} args.fee + * @returns {FetchedLineSeriesBlueprint[]} + */ +export function revenueRollingBtcSatsUsd({ coinbase, subsidy, fee }) { + return [ + ...satsBtcUsd({ + pattern: coinbase, + name: "Coinbase", + color: colors.mining.coinbase, + }), + ...satsBtcUsd({ + pattern: subsidy, + name: "Subsidy", + color: colors.mining.subsidy, + }), + ...satsBtcUsd({ + pattern: fee, + name: "Fees", + color: colors.mining.fee, + }), + ]; +} + /** * Build percentile USD mappings from a ratio pattern * @param {AnyRatioPattern} ratio diff --git a/website/scripts/options/types.js b/website/scripts/options/types.js index a0ea40968..94e0b97fc 100644 --- a/website/scripts/options/types.js +++ b/website/scripts/options/types.js @@ -163,9 +163,8 @@ * - AgeRangePattern (ageRange.*) * @typedef {LongTermPattern | AgeRangePattern} PatternWithPercentiles * - * Patterns with RelToMarketCap in relative (RelativePattern): - * - BasicUtxoPattern (minAge.*, geAmount.*, ltAmount.*) - * @typedef {BasicUtxoPattern} PatternBasicWithMarketCap + * Patterns with RelToMarketCap in relative (geAmount.*, ltAmount.*): + * @typedef {UtxoAmountPattern | AddressAmountPattern} PatternBasicWithMarketCap * * Patterns without RelToMarketCap in relative (RelativePattern4): * - EpochPattern (epoch.*, amountRange.*, year.*, type.*) diff --git a/website/scripts/panes/chart.js b/website/scripts/panes/chart.js index 1beb3b52a..ab8c17456 100644 --- a/website/scripts/panes/chart.js +++ b/website/scripts/panes/chart.js @@ -45,7 +45,7 @@ export function init() { const usdPrice = { type: "Candlestick", title: "Price", - metric: brk.metrics.prices.ohlc.usd, + metric: brk.metrics.prices.ohlc.usd.day1, }; result.set(Unit.usd, [usdPrice, ...(optionTop.get(Unit.usd) ?? [])]); @@ -54,7 +54,7 @@ export function init() { const satsPrice = { type: "Candlestick", title: "Price", - metric: brk.metrics.prices.ohlc.sats, + metric: brk.metrics.prices.ohlc.sats.day1, colors: /** @type {const} */ ([colors.bi.p1[1], colors.bi.p1[0]]), }; result.set(Unit.sats, [satsPrice, ...(optionTop.get(Unit.sats) ?? [])]); diff --git a/website/scripts/types.js b/website/scripts/types.js index 0e76c6a53..a95e645aa 100644 --- a/website/scripts/types.js +++ b/website/scripts/types.js @@ -33,40 +33,41 @@ * @typedef {Brk.MetricsTree_Distribution_UtxoCohorts} UtxoCohortTree * @typedef {Brk.MetricsTree_Distribution_AddressCohorts} AddressCohortTree * @typedef {Brk.MetricsTree_Distribution_UtxoCohorts_All} AllUtxoPattern - * @typedef {Brk.MetricsTree_Distribution_UtxoCohorts_Term_Short} ShortTermPattern - * @typedef {Brk.MetricsTree_Distribution_UtxoCohorts_Term_Long} LongTermPattern + * @typedef {Brk.MetricsTree_Distribution_UtxoCohorts_Sth} ShortTermPattern + * @typedef {Brk.ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern} LongTermPattern * @typedef {Brk.MetricsTree_Distribution_UtxoCohorts_All_Relative} AllRelativePattern + * @typedef {keyof Brk.BtcSatsUsdPattern} BtcSatsUsdKey * @typedef {Brk.BtcSatsUsdPattern} SupplyPattern - * @typedef {Brk.MetricsTree_Blocks_Size} BlockSizePattern + * @typedef {Brk.AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern} BlockSizePattern * @typedef {keyof Brk.MetricsTree_Distribution_UtxoCohorts_Type} SpendableType * @typedef {keyof Brk.MetricsTree_Distribution_AnyAddressIndexes} AddressableType * * Brk pattern types (using new pattern names) - * @typedef {Brk.ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern5} MaxAgePattern + * @typedef {Brk.ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4} MaxAgePattern * @typedef {Brk.ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern} AgeRangePattern * @typedef {Brk.ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3} UtxoAmountPattern * @typedef {Brk.ActivityAddrCostOutputsRealizedRelativeSupplyUnrealizedPattern} AddressAmountPattern * @typedef {Brk.ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4} BasicUtxoPattern - * MinAgePattern: minAge cohorts have peakRegret in unrealized (Pattern6) - * @typedef {Brk.ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern6} MinAgePattern + * MinAgePattern: minAge cohorts have peakRegret in unrealized + * @typedef {Brk.ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern5} MinAgePattern * @typedef {Brk.ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3} EpochPattern - * @typedef {Brk.ActivityCostOutputsRealizedSupplyUnrealizedPattern} EmptyPattern + * @typedef {Brk.ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3} EmptyPattern * @typedef {Brk._0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern} Ratio1ySdPattern * @typedef {Brk.Dollars} Dollars - * CoinbasePattern: patterns with btc/sats/usd each having base + sum + cumulative + stats - * @typedef {Brk.BtcSatsUsdPattern3} CoinbasePattern + * CoinbasePattern: base + cumulative + rolling windows (flattened) + * @typedef {Brk._1y24h30d7dBaseCumulativePattern} CoinbasePattern * ActivePriceRatioPattern: ratio pattern with price (extended) * @typedef {Brk.PriceRatioPattern} ActivePriceRatioPattern * AnyRatioPattern: full ratio patterns (with or without price) - has ratio, percentiles, z-scores * @typedef {Brk.RatioPattern | Brk.PriceRatioPattern} AnyRatioPattern - * ValuePattern: patterns with minimal stats (sum, cumulative only) for btc/sats/usd - * @typedef {Brk.BtcSatsUsdPattern5 | Brk.BtcSatsUsdPattern2} ValuePattern - * FullValuePattern: patterns with full stats (base, sum, cumulative, average, percentiles) for btc/sats/usd - * @typedef {Brk.BtcSatsUsdPattern3} FullValuePattern - * SumValuePattern: patterns with sum stats (sum, cumulative, average, percentiles - no base) for bitcoin/sats/dollars - * @typedef {{btc: SumStatsPattern, sats: SumStatsPattern, usd: SumStatsPattern}} SumValuePattern + * ValuePattern: patterns with base + cumulative (no rolling) + * @typedef {Brk.BaseCumulativeSumPattern | Brk.BaseCumulativePattern} ValuePattern + * FullValuePattern: base + cumulative + rolling windows (flattened) + * @typedef {Brk._1y24h30d7dBaseCumulativePattern} FullValuePattern + * RollingWindowSlot: a single rolling window with stats (average, pct10, pct25, median, pct75, pct90, max, min, sum) per unit + * @typedef {Brk.AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2} RollingWindowSlot * AnyValuePatternType: union of all value pattern types - * @typedef {ValuePattern | FullValuePattern} AnyValuePatternType + * @typedef {Brk._1y24h30d7dBaseCumulativePattern | Brk.BaseCumulativeSumPattern | Brk.BaseCumulativePattern} AnyValuePatternType * @typedef {Brk.AnyMetricPattern} AnyMetricPattern * @typedef {Brk.SatsUsdPattern} ActivePricePattern * @typedef {Brk.AnyMetricEndpointBuilder} AnyMetricEndpoint @@ -78,11 +79,11 @@ * - GlobalPeakRelativePattern: GlobalRelativePattern + unrealizedPeakRegretRelToMarketCap * - OwnRelativePattern: has RelToOwnMarketCap metrics (netUnrealizedPnlRelToOwnMarketCap, etc) * - FullRelativePattern: has BOTH RelToMarketCap AND RelToOwnMarketCap + unrealizedPeakRegretRelToMarketCap - * @typedef {Brk.InvestedSupplyPattern} BasicRelativePattern + * @typedef {Brk.InvestedNegNetNuplSupplyUnrealizedPattern} BasicRelativePattern * @typedef {Brk.InvestedNegNetNuplSupplyUnrealizedPattern} GlobalRelativePattern - * @typedef {Brk.InvestedNegNetNuplSupplyUnrealizedPattern3} GlobalPeakRelativePattern - * @typedef {Brk.InvestedNegNetSupplyUnrealizedPattern} OwnRelativePattern - * @typedef {Brk.InvestedNegNetNuplSupplyUnrealizedPattern4} FullRelativePattern + * @typedef {Brk.InvestedNegNetNuplSupplyUnrealizedPattern4} GlobalPeakRelativePattern + * @typedef {Brk.InvestedNegNetNuplSupplyUnrealizedPattern2} OwnRelativePattern + * @typedef {Brk.InvestedNegNetNuplSupplyUnrealizedPattern2} FullRelativePattern * @typedef {Brk.GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern} UnrealizedPattern * @typedef {Brk.GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern} UnrealizedFullPattern * @@ -98,37 +99,43 @@ * @typedef {Brk.MetricEndpointBuilder} MetricEndpoint */ /** - * Stats pattern: average, min, max, percentiles (NO base) + * Stats pattern: average, min, max, percentiles (height-only indexes, NO base) * @template T - * @typedef {Brk.AverageMaxMedianMinPct10Pct25Pct75Pct90TxindexPattern} StatsPattern + * @typedef {Brk.AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern} StatsPattern */ /** - * Base stats pattern: base, average, min, max, percentiles (NO sum/cumulative) + * Base stats pattern: height, average, min, max, percentiles (windowed, NO sum/cumulative) * @template T - * @typedef {Brk.AverageBaseMaxMedianMinPct10Pct25Pct75Pct90Pattern} BaseStatsPattern + * @typedef {Brk.AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern} BaseStatsPattern */ /** - * Full stats pattern: base, average, sum, cumulative, min, max, percentiles - * @template T - * @typedef {Brk.AverageBaseCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern} FullStatsPattern + * Full stats pattern: cumulative, sum, average, min, max, percentiles + rolling + * @typedef {Brk.AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern} FullStatsPattern */ /** - * Sum stats pattern: average, sum, cumulative, percentiles (NO base) - * @template T - * @typedef {Brk.AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern2} SumStatsPattern + * Sum stats pattern: cumulative, sum, average, min, max, percentiles + rolling (same as FullStatsPattern) + * @typedef {Brk.AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern} SumStatsPattern */ /** - * Full stats pattern for Bitcoin (non-generic variant with btc-specific indexes) - * @typedef {Brk.AverageBaseCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern2} BtcFullStatsPattern + * Full stats pattern for Bitcoin (non-generic variant) - same as FullStatsPattern + * @typedef {Brk.AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern} BtcFullStatsPattern */ /** - * Count pattern: sum and cumulative only + * Count pattern: height, cumulative, and rolling sum windows * @template T - * @typedef {Brk.CumulativeSumPattern} CountPattern + * @typedef {Brk.CumulativeHeightSumPattern} CountPattern + */ +/** + * Full per-block pattern: height, cumulative, sum, and distribution stats (all flat) + * @typedef {Brk.AverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern} FullPerBlockPattern */ /** * Any stats pattern union - patterns with sum/cumulative + percentiles - * @typedef {SumStatsPattern | FullStatsPattern | BtcFullStatsPattern | BlockSizePattern} AnyStatsPattern + * @typedef {FullStatsPattern | BtcFullStatsPattern} AnyStatsPattern + */ +/** + * Distribution stats: 8 metric fields (average, min, max, median, pct10/25/75/90) + * @typedef {{ average: AnyMetricPattern, min: AnyMetricPattern, max: AnyMetricPattern, median: AnyMetricPattern, pct10: AnyMetricPattern, pct25: AnyMetricPattern, pct75: AnyMetricPattern, pct90: AnyMetricPattern }} DistributionStats */ /** @@ -144,7 +151,7 @@ * @typedef {Brk.MetricsTree_Market_Dca} MarketDca * @typedef {Brk._10y2y3y4y5y6y8yPattern} PeriodCagrPattern * Full stats pattern union (both generic and non-generic variants) - * @typedef {FullStatsPattern | BtcFullStatsPattern} AnyFullStatsPattern + * @typedef {FullStatsPattern | BtcFullStatsPattern} AnyFullStatsPattern * * DCA period keys - derived from pattern types * @typedef {keyof Brk._10y2y3y4y5y6y8yPattern} LongPeriodKey