diff --git a/crates/brk_client/src/lib.rs b/crates/brk_client/src/lib.rs index 0c7fa5259..2224928cb 100644 --- a/crates/brk_client/src/lib.rs +++ b/crates/brk_client/src/lib.rs @@ -956,9 +956,10 @@ pub struct CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSell pub lower_price_band: CentsSatsUsdPattern, pub mvrv: MetricPattern1, pub neg_realized_loss: MetricPattern1, - pub net_pnl_change_1m: MetricPattern1, pub net_pnl_change_1m_rel_to_market_cap: BpsPercentRatioPattern, pub net_pnl_change_1m_rel_to_realized_cap: BpsPercentRatioPattern, + pub net_pnl_delta: ChangeRatePattern, + pub net_pnl_delta_extended: _24hChangeRatePattern, pub net_realized_pnl: CumulativeHeightPattern, pub net_realized_pnl_rel_to_realized_cap: BpsPercentRatioPattern, pub peak_regret: CumulativeHeightPattern, @@ -970,7 +971,8 @@ pub struct CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSell pub profit_value_destroyed_sum: _1m1w1y24hPattern, pub realized_cap: MetricPattern1, pub realized_cap_cents: MetricPattern1, - pub realized_cap_change_1m: MetricPattern1, + pub realized_cap_delta: ChangeRatePattern, + pub realized_cap_delta_extended: _24hChangeRatePattern, pub realized_cap_rel_to_own_market_cap: BpsPercentRatioPattern, pub realized_loss: CumulativeHeightPattern, pub realized_loss_rel_to_realized_cap: BpsPercentRatioPattern, @@ -1022,9 +1024,10 @@ impl CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSo lower_price_band: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "lower_price_band")), mvrv: MetricPattern1::new(client.clone(), _m(&acc, "mvrv")), neg_realized_loss: MetricPattern1::new(client.clone(), _m(&acc, "neg_realized_loss")), - net_pnl_change_1m: MetricPattern1::new(client.clone(), _m(&acc, "net_pnl_change_1m")), net_pnl_change_1m_rel_to_market_cap: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "net_pnl_change_1m_rel_to_market_cap")), net_pnl_change_1m_rel_to_realized_cap: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "net_pnl_change_1m_rel_to_realized_cap")), + net_pnl_delta: ChangeRatePattern::new(client.clone(), _m(&acc, "net_pnl_delta")), + net_pnl_delta_extended: _24hChangeRatePattern::new(client.clone(), _m(&acc, "net_pnl_delta")), net_realized_pnl: CumulativeHeightPattern::new(client.clone(), _m(&acc, "net_realized_pnl")), net_realized_pnl_rel_to_realized_cap: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "net_realized_pnl_rel_to_realized_cap")), peak_regret: CumulativeHeightPattern::new(client.clone(), _m(&acc, "realized_peak_regret")), @@ -1036,7 +1039,8 @@ impl CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSo profit_value_destroyed_sum: _1m1w1y24hPattern::new(client.clone(), _m(&acc, "profit_value_destroyed")), realized_cap: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap")), realized_cap_cents: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap_cents")), - realized_cap_change_1m: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap_change_1m")), + realized_cap_delta: ChangeRatePattern::new(client.clone(), _m(&acc, "realized_cap_delta")), + realized_cap_delta_extended: _24hChangeRatePattern::new(client.clone(), _m(&acc, "realized_cap_delta")), realized_cap_rel_to_own_market_cap: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "realized_cap_rel_to_own_market_cap")), realized_loss: CumulativeHeightPattern::new(client.clone(), _m(&acc, "realized_loss")), realized_loss_rel_to_realized_cap: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "realized_loss_rel_to_realized_cap")), @@ -1146,7 +1150,7 @@ pub struct MvrvNegNetRealizedSentSoprValuePattern { pub net_realized_pnl: CumulativeHeightPattern, pub realized_cap: MetricPattern1, pub realized_cap_cents: MetricPattern1, - pub realized_cap_change_1m: MetricPattern1, + pub realized_cap_delta: ChangeRatePattern, pub realized_loss: CumulativeHeightPattern, pub realized_loss_sum: _24hPattern, pub realized_price: CentsSatsUsdPattern, @@ -1173,7 +1177,7 @@ impl MvrvNegNetRealizedSentSoprValuePattern { net_realized_pnl: CumulativeHeightPattern::new(client.clone(), _m(&acc, "net_realized_pnl")), realized_cap: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap")), realized_cap_cents: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap_cents")), - realized_cap_change_1m: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap_change_1m")), + realized_cap_delta: ChangeRatePattern::new(client.clone(), _m(&acc, "realized_cap_delta")), realized_loss: CumulativeHeightPattern::new(client.clone(), _m(&acc, "realized_loss")), realized_loss_sum: _24hPattern::new(client.clone(), _m(&acc, "realized_loss_24h")), realized_price: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "realized_price")), @@ -1250,7 +1254,7 @@ pub struct MvrvNegNetRealizedSoprValuePattern { pub net_realized_pnl: CumulativeHeightPattern, pub realized_cap: MetricPattern1, pub realized_cap_cents: MetricPattern1, - pub realized_cap_change_1m: MetricPattern1, + pub realized_cap_delta: ChangeRatePattern, pub realized_loss: CumulativeHeightPattern, pub realized_loss_sum: _24hPattern, pub realized_price: CentsSatsUsdPattern, @@ -1273,7 +1277,7 @@ impl MvrvNegNetRealizedSoprValuePattern { net_realized_pnl: CumulativeHeightPattern::new(client.clone(), _m(&acc, "net_realized_pnl")), realized_cap: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap")), realized_cap_cents: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap_cents")), - realized_cap_change_1m: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap_change_1m")), + realized_cap_delta: ChangeRatePattern::new(client.clone(), _m(&acc, "realized_cap_delta")), realized_loss: CumulativeHeightPattern::new(client.clone(), _m(&acc, "realized_loss")), realized_loss_sum: _24hPattern::new(client.clone(), _m(&acc, "realized_loss_24h")), realized_price: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "realized_price")), @@ -1934,7 +1938,7 @@ pub struct ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern { pub outputs: UtxoPattern, pub realized: MvrvNegNetRealizedSentSoprValuePattern, pub relative: SupplyPattern2, - pub supply: ChangeHalvedTotalPattern, + pub supply: DeltaHalvedTotalPattern, pub unrealized: InvestedInvestorNegNetSupplyUnrealizedPattern, } @@ -1947,7 +1951,7 @@ impl ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern { outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")), realized: MvrvNegNetRealizedSentSoprValuePattern::new(client.clone(), acc.clone()), relative: SupplyPattern2::new(client.clone(), _m(&acc, "supply")), - supply: ChangeHalvedTotalPattern::new(client.clone(), _m(&acc, "supply")), + supply: DeltaHalvedTotalPattern::new(client.clone(), _m(&acc, "supply")), unrealized: InvestedInvestorNegNetSupplyUnrealizedPattern::new(client.clone(), acc.clone()), } } @@ -1957,10 +1961,10 @@ impl ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern { pub struct ActivityAddrOutputsRealizedSupplyUnrealizedPattern { pub activity: SentPattern, pub addr_count: MetricPattern1, - pub addr_count_change_1m: MetricPattern1, + pub addr_count_delta: ChangeRatePattern, pub outputs: UtxoPattern, pub realized: MvrvRealizedPattern, - pub supply: ChangeHalvedTotalPattern, + pub supply: DeltaHalvedTotalPattern, pub unrealized: SupplyPattern, } @@ -1970,10 +1974,10 @@ impl ActivityAddrOutputsRealizedSupplyUnrealizedPattern { Self { activity: SentPattern::new(client.clone(), _m(&acc, "sent")), addr_count: MetricPattern1::new(client.clone(), _m(&acc, "addr_count")), - addr_count_change_1m: MetricPattern1::new(client.clone(), _m(&acc, "addr_count_change_1m")), + addr_count_delta: ChangeRatePattern::new(client.clone(), _m(&acc, "addr_count_delta")), outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")), realized: MvrvRealizedPattern::new(client.clone(), acc.clone()), - supply: ChangeHalvedTotalPattern::new(client.clone(), _m(&acc, "supply")), + supply: DeltaHalvedTotalPattern::new(client.clone(), _m(&acc, "supply")), unrealized: SupplyPattern::new(client.clone(), _m(&acc, "supply_in")), } } @@ -1985,7 +1989,7 @@ pub struct ActivityOutputsRealizedRelativeSupplyUnrealizedPattern { pub outputs: UtxoPattern, pub realized: MvrvNegNetRealizedSoprValuePattern, pub relative: SupplyPattern2, - pub supply: ChangeHalvedTotalPattern, + pub supply: DeltaHalvedTotalPattern, pub unrealized: NegNetSupplyUnrealizedPattern, } @@ -1997,7 +2001,7 @@ impl ActivityOutputsRealizedRelativeSupplyUnrealizedPattern { outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")), realized: MvrvNegNetRealizedSoprValuePattern::new(client.clone(), acc.clone()), relative: SupplyPattern2::new(client.clone(), _m(&acc, "supply")), - supply: ChangeHalvedTotalPattern::new(client.clone(), _m(&acc, "supply")), + supply: DeltaHalvedTotalPattern::new(client.clone(), _m(&acc, "supply")), unrealized: NegNetSupplyUnrealizedPattern::new(client.clone(), acc.clone()), } } @@ -2032,7 +2036,7 @@ pub struct ActivityOutputsRealizedSupplyUnrealizedPattern { pub activity: SentPattern, pub outputs: UtxoPattern, pub realized: MvrvRealizedPattern, - pub supply: ChangeHalvedTotalPattern, + pub supply: DeltaHalvedTotalPattern, pub unrealized: SupplyPattern, } @@ -2043,7 +2047,7 @@ impl ActivityOutputsRealizedSupplyUnrealizedPattern { activity: SentPattern::new(client.clone(), _m(&acc, "sent")), outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")), realized: MvrvRealizedPattern::new(client.clone(), acc.clone()), - supply: ChangeHalvedTotalPattern::new(client.clone(), _m(&acc, "supply")), + supply: DeltaHalvedTotalPattern::new(client.clone(), _m(&acc, "supply")), unrealized: SupplyPattern::new(client.clone(), _m(&acc, "supply_in")), } } @@ -2115,6 +2119,28 @@ impl _1m1w1y24hHeightPattern { } } +/// Pattern struct for repeated tree structure. +pub struct _24hChangeRatePattern { + pub _24h: BaseBpsPercentRatioPattern, + pub change_1w: MetricPattern1, + pub change_1y: MetricPattern1, + pub rate_1w: BpsPercentRatioPattern, + pub rate_1y: BpsPercentRatioPattern, +} + +impl _24hChangeRatePattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + _24h: BaseBpsPercentRatioPattern::new(client.clone(), acc.clone()), + change_1w: MetricPattern1::new(client.clone(), _m(&acc, "change_1w")), + change_1y: MetricPattern1::new(client.clone(), _m(&acc, "change_1y")), + rate_1w: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rate_1w")), + rate_1y: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rate_1y")), + } + } +} + /// Pattern struct for repeated tree structure. pub struct _1m1w1y24hPattern6 { pub _1m: BaseBtcCentsSatsUsdPattern, @@ -2175,6 +2201,26 @@ impl _1m1w1y24hPattern5 { } } +/// Pattern struct for repeated tree structure. +pub struct BaseBpsPercentRatioPattern { + pub base: MetricPattern1, + pub bps: MetricPattern1, + pub percent: MetricPattern1, + pub ratio: MetricPattern1, +} + +impl BaseBpsPercentRatioPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + base: MetricPattern1::new(client.clone(), _m(&acc, "change_24h")), + bps: MetricPattern1::new(client.clone(), _m(&acc, "rate_24h_bps")), + percent: MetricPattern1::new(client.clone(), _m(&acc, "rate_24h")), + ratio: MetricPattern1::new(client.clone(), _m(&acc, "rate_24h_ratio")), + } + } +} + /// Pattern struct for repeated tree structure. pub struct BothReactivatedReceivingSendingPattern { pub both: _1m1w1y24hHeightPattern, @@ -2386,17 +2432,17 @@ impl CentsSatsUsdPattern { } /// Pattern struct for repeated tree structure. -pub struct ChangeHalvedTotalPattern { - pub change_1m: BtcCentsSatsUsdPattern, +pub struct DeltaHalvedTotalPattern { + pub delta: ChangeRatePattern, pub halved: BtcCentsSatsUsdPattern, pub total: BtcCentsSatsUsdPattern, } -impl ChangeHalvedTotalPattern { +impl DeltaHalvedTotalPattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - change_1m: BtcCentsSatsUsdPattern::new(client.clone(), _m(&acc, "change_1m")), + delta: ChangeRatePattern::new(client.clone(), _m(&acc, "delta")), halved: BtcCentsSatsUsdPattern::new(client.clone(), _m(&acc, "halved")), total: BtcCentsSatsUsdPattern::new(client.clone(), acc.clone()), } @@ -2540,12 +2586,12 @@ impl CentsUsdPattern { } /// Pattern struct for repeated tree structure. -pub struct ChangeRatePattern { +pub struct ChangeRatePattern2 { pub change: _1m1w1y24hPattern, pub rate: _1m1w1y24hPattern2, } -impl ChangeRatePattern { +impl ChangeRatePattern2 { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { @@ -2622,7 +2668,7 @@ impl SupplyPattern { /// Pattern struct for repeated tree structure. pub struct UtxoPattern { pub utxo_count: MetricPattern1, - pub utxo_count_change_1m: MetricPattern1, + pub utxo_count_delta: ChangeRatePattern, } impl UtxoPattern { @@ -2630,7 +2676,23 @@ impl UtxoPattern { pub fn new(client: Arc, acc: String) -> Self { Self { utxo_count: MetricPattern1::new(client.clone(), acc.clone()), - utxo_count_change_1m: MetricPattern1::new(client.clone(), _m(&acc, "change_1m")), + utxo_count_delta: ChangeRatePattern::new(client.clone(), _m(&acc, "delta")), + } + } +} + +/// Pattern struct for repeated tree structure. +pub struct ChangeRatePattern { + pub change_1m: MetricPattern1, + pub rate_1m: BpsPercentRatioPattern, +} + +impl ChangeRatePattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + change_1m: MetricPattern1::new(client.clone(), _m(&acc, "change_1m")), + rate_1m: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rate_1m")), } } } @@ -5521,7 +5583,7 @@ impl MetricsTree_Distribution_UtxoCohorts { /// Metrics tree node. pub struct MetricsTree_Distribution_UtxoCohorts_All { - pub supply: ChangeHalvedTotalPattern, + pub supply: DeltaHalvedTotalPattern, pub outputs: UtxoPattern, pub activity: CoinblocksCoindaysSentPattern2, pub realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern, @@ -5531,12 +5593,14 @@ pub struct MetricsTree_Distribution_UtxoCohorts_All { pub relative: MetricsTree_Distribution_UtxoCohorts_All_Relative, pub dormancy: MetricPattern1, pub velocity: MetricPattern1, + pub supply_delta_extended: _24hChangeRatePattern, + pub utxo_count_delta_extended: _24hChangeRatePattern, } impl MetricsTree_Distribution_UtxoCohorts_All { pub fn new(client: Arc, base_path: String) -> Self { Self { - supply: ChangeHalvedTotalPattern::new(client.clone(), "supply".to_string()), + supply: DeltaHalvedTotalPattern::new(client.clone(), "supply".to_string()), outputs: UtxoPattern::new(client.clone(), "utxo_count".to_string()), activity: CoinblocksCoindaysSentPattern2::new(client.clone(), "".to_string()), realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern::new(client.clone(), "".to_string()), @@ -5546,6 +5610,8 @@ impl MetricsTree_Distribution_UtxoCohorts_All { relative: MetricsTree_Distribution_UtxoCohorts_All_Relative::new(client.clone(), format!("{base_path}_relative")), dormancy: MetricPattern1::new(client.clone(), "dormancy".to_string()), velocity: MetricPattern1::new(client.clone(), "velocity".to_string()), + supply_delta_extended: _24hChangeRatePattern::new(client.clone(), "supply_delta".to_string()), + utxo_count_delta_extended: _24hChangeRatePattern::new(client.clone(), "utxo_count_delta".to_string()), } } } @@ -5602,7 +5668,7 @@ impl MetricsTree_Distribution_UtxoCohorts_All_Relative { /// Metrics tree node. pub struct MetricsTree_Distribution_UtxoCohorts_Sth { - pub supply: ChangeHalvedTotalPattern, + pub supply: DeltaHalvedTotalPattern, pub outputs: UtxoPattern, pub activity: CoinblocksCoindaysSentPattern2, pub realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern, @@ -5611,6 +5677,8 @@ pub struct MetricsTree_Distribution_UtxoCohorts_Sth { pub relative: NetNuplSupplyUnrealizedPattern2, pub dormancy: MetricPattern1, pub velocity: MetricPattern1, + pub supply_delta_extended: _24hChangeRatePattern, + pub utxo_count_delta_extended: _24hChangeRatePattern, pub adjusted_value_created: MetricPattern1, pub adjusted_value_destroyed: MetricPattern1, pub adjusted_value_created_sum: _1m1w1y24hPattern, @@ -5621,7 +5689,7 @@ pub struct MetricsTree_Distribution_UtxoCohorts_Sth { impl MetricsTree_Distribution_UtxoCohorts_Sth { pub fn new(client: Arc, base_path: String) -> Self { Self { - supply: ChangeHalvedTotalPattern::new(client.clone(), "sth_supply".to_string()), + supply: DeltaHalvedTotalPattern::new(client.clone(), "sth_supply".to_string()), outputs: UtxoPattern::new(client.clone(), "sth_utxo_count".to_string()), activity: CoinblocksCoindaysSentPattern2::new(client.clone(), "sth".to_string()), realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern::new(client.clone(), "sth".to_string()), @@ -5630,6 +5698,8 @@ impl MetricsTree_Distribution_UtxoCohorts_Sth { relative: NetNuplSupplyUnrealizedPattern2::new(client.clone(), "sth".to_string()), dormancy: MetricPattern1::new(client.clone(), "sth_dormancy".to_string()), velocity: MetricPattern1::new(client.clone(), "sth_velocity".to_string()), + supply_delta_extended: _24hChangeRatePattern::new(client.clone(), "sth_supply_delta".to_string()), + utxo_count_delta_extended: _24hChangeRatePattern::new(client.clone(), "sth_utxo_count_delta".to_string()), adjusted_value_created: MetricPattern1::new(client.clone(), "sth_adjusted_value_created".to_string()), adjusted_value_destroyed: MetricPattern1::new(client.clone(), "sth_adjusted_value_destroyed".to_string()), adjusted_value_created_sum: _1m1w1y24hPattern::new(client.clone(), "sth_adjusted_value_created".to_string()), @@ -5641,7 +5711,7 @@ impl MetricsTree_Distribution_UtxoCohorts_Sth { /// Metrics tree node. pub struct MetricsTree_Distribution_UtxoCohorts_Lth { - pub supply: ChangeHalvedTotalPattern, + pub supply: DeltaHalvedTotalPattern, pub outputs: UtxoPattern, pub activity: CoinblocksCoindaysSentPattern2, pub realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern, @@ -5650,12 +5720,14 @@ pub struct MetricsTree_Distribution_UtxoCohorts_Lth { pub relative: NetNuplSupplyUnrealizedPattern2, pub dormancy: MetricPattern1, pub velocity: MetricPattern1, + pub supply_delta_extended: _24hChangeRatePattern, + pub utxo_count_delta_extended: _24hChangeRatePattern, } impl MetricsTree_Distribution_UtxoCohorts_Lth { pub fn new(client: Arc, base_path: String) -> Self { Self { - supply: ChangeHalvedTotalPattern::new(client.clone(), "lth_supply".to_string()), + supply: DeltaHalvedTotalPattern::new(client.clone(), "lth_supply".to_string()), outputs: UtxoPattern::new(client.clone(), "lth_utxo_count".to_string()), activity: CoinblocksCoindaysSentPattern2::new(client.clone(), "lth".to_string()), realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern::new(client.clone(), "lth".to_string()), @@ -5664,6 +5736,8 @@ impl MetricsTree_Distribution_UtxoCohorts_Lth { relative: NetNuplSupplyUnrealizedPattern2::new(client.clone(), "lth".to_string()), dormancy: MetricPattern1::new(client.clone(), "lth_dormancy".to_string()), velocity: MetricPattern1::new(client.clone(), "lth_velocity".to_string()), + supply_delta_extended: _24hChangeRatePattern::new(client.clone(), "lth_supply_delta".to_string()), + utxo_count_delta_extended: _24hChangeRatePattern::new(client.clone(), "lth_utxo_count_delta".to_string()), } } } @@ -6223,29 +6297,29 @@ impl MetricsTree_Distribution_NewAddrCount { /// Metrics tree node. pub struct MetricsTree_Distribution_Delta { - pub all: ChangeRatePattern, - pub p2pk65: ChangeRatePattern, - pub p2pk33: ChangeRatePattern, - pub p2pkh: ChangeRatePattern, - pub p2sh: ChangeRatePattern, - pub p2wpkh: ChangeRatePattern, - pub p2wsh: ChangeRatePattern, - pub p2tr: ChangeRatePattern, - pub p2a: ChangeRatePattern, + pub all: ChangeRatePattern2, + pub p2pk65: ChangeRatePattern2, + pub p2pk33: ChangeRatePattern2, + pub p2pkh: ChangeRatePattern2, + pub p2sh: ChangeRatePattern2, + pub p2wpkh: ChangeRatePattern2, + pub p2wsh: ChangeRatePattern2, + pub p2tr: ChangeRatePattern2, + pub p2a: ChangeRatePattern2, } impl MetricsTree_Distribution_Delta { pub fn new(client: Arc, base_path: String) -> Self { Self { - all: ChangeRatePattern::new(client.clone(), "addr_count".to_string()), - p2pk65: ChangeRatePattern::new(client.clone(), "p2pk65_addr_count".to_string()), - p2pk33: ChangeRatePattern::new(client.clone(), "p2pk33_addr_count".to_string()), - p2pkh: ChangeRatePattern::new(client.clone(), "p2pkh_addr_count".to_string()), - p2sh: ChangeRatePattern::new(client.clone(), "p2sh_addr_count".to_string()), - p2wpkh: ChangeRatePattern::new(client.clone(), "p2wpkh_addr_count".to_string()), - p2wsh: ChangeRatePattern::new(client.clone(), "p2wsh_addr_count".to_string()), - p2tr: ChangeRatePattern::new(client.clone(), "p2tr_addr_count".to_string()), - p2a: ChangeRatePattern::new(client.clone(), "p2a_addr_count".to_string()), + all: ChangeRatePattern2::new(client.clone(), "addr_count".to_string()), + p2pk65: ChangeRatePattern2::new(client.clone(), "p2pk65_addr_count".to_string()), + p2pk33: ChangeRatePattern2::new(client.clone(), "p2pk33_addr_count".to_string()), + p2pkh: ChangeRatePattern2::new(client.clone(), "p2pkh_addr_count".to_string()), + p2sh: ChangeRatePattern2::new(client.clone(), "p2sh_addr_count".to_string()), + p2wpkh: ChangeRatePattern2::new(client.clone(), "p2wpkh_addr_count".to_string()), + p2wsh: ChangeRatePattern2::new(client.clone(), "p2wsh_addr_count".to_string()), + p2tr: ChangeRatePattern2::new(client.clone(), "p2tr_addr_count".to_string()), + p2a: ChangeRatePattern2::new(client.clone(), "p2a_addr_count".to_string()), } } } @@ -6257,9 +6331,9 @@ pub struct MetricsTree_Supply { pub inflation_rate: BpsPercentRatioPattern, pub velocity: MetricsTree_Supply_Velocity, pub market_cap: MetricPattern1, - pub market_cap_growth_rate: BpsPercentRatioPattern, - pub realized_cap_growth_rate: BpsPercentRatioPattern, - pub market_minus_realized_cap_growth_rate: MetricPattern1, + pub market_cap_growth_rate: _1m1w1y24hPattern2, + pub realized_cap_growth_rate: _1m1w1y24hPattern2, + pub market_minus_realized_cap_growth_rate: _1m1w1y24hPattern, } impl MetricsTree_Supply { @@ -6270,9 +6344,9 @@ impl MetricsTree_Supply { inflation_rate: BpsPercentRatioPattern::new(client.clone(), "inflation_rate".to_string()), velocity: MetricsTree_Supply_Velocity::new(client.clone(), format!("{base_path}_velocity")), market_cap: MetricPattern1::new(client.clone(), "market_cap".to_string()), - market_cap_growth_rate: BpsPercentRatioPattern::new(client.clone(), "market_cap_growth_rate".to_string()), - realized_cap_growth_rate: BpsPercentRatioPattern::new(client.clone(), "realized_cap_growth_rate".to_string()), - market_minus_realized_cap_growth_rate: MetricPattern1::new(client.clone(), "market_minus_realized_cap_growth_rate".to_string()), + market_cap_growth_rate: _1m1w1y24hPattern2::new(client.clone(), "market_cap_growth_rate".to_string()), + realized_cap_growth_rate: _1m1w1y24hPattern2::new(client.clone(), "realized_cap_growth_rate".to_string()), + market_minus_realized_cap_growth_rate: _1m1w1y24hPattern::new(client.clone(), "market_minus_realized_cap_growth_rate".to_string()), } } } diff --git a/crates/brk_computer/src/distribution/address/new_addr_count.rs b/crates/brk_computer/src/distribution/address/new_addr_count.rs index 0018b7c77..320e93884 100644 --- a/crates/brk_computer/src/distribution/address/new_addr_count.rs +++ b/crates/brk_computer/src/distribution/address/new_addr_count.rs @@ -6,7 +6,7 @@ use vecdb::{Database, Exit, Rw, StorageMode}; use crate::{ indexes, - internal::{ComputedFromHeightFull, WindowStarts}, + internal::{ComputedFromHeightSum, WindowStarts}, }; use super::TotalAddrCountVecs; @@ -14,9 +14,9 @@ use super::TotalAddrCountVecs; /// New address count per block (global + per-type) #[derive(Traversable)] pub struct NewAddrCountVecs { - pub all: ComputedFromHeightFull, + pub all: ComputedFromHeightSum, #[traversable(flatten)] - pub by_addresstype: ByAddressType>, + pub by_addresstype: ByAddressType>, } impl NewAddrCountVecs { @@ -25,11 +25,11 @@ impl NewAddrCountVecs { version: Version, indexes: &indexes::Vecs, ) -> Result { - let all = ComputedFromHeightFull::forced_import(db, "new_addr_count", version, indexes)?; + let all = ComputedFromHeightSum::forced_import(db, "new_addr_count", version, indexes)?; - let by_addresstype: ByAddressType> = + let by_addresstype: ByAddressType> = ByAddressType::new_with_name(|name| { - ComputedFromHeightFull::forced_import( + ComputedFromHeightSum::forced_import( db, &format!("{name}_new_addr_count"), version, diff --git a/crates/brk_computer/src/distribution/cohorts/address/groups.rs b/crates/brk_computer/src/distribution/cohorts/address/groups.rs index b659561f4..85199a01a 100644 --- a/crates/brk_computer/src/distribution/cohorts/address/groups.rs +++ b/crates/brk_computer/src/distribution/cohorts/address/groups.rs @@ -96,7 +96,7 @@ impl AddressCohorts { exit: &Exit, ) -> Result<()> { self.par_iter_mut().try_for_each(|v| { - v.addr_count_change_1m.height.compute_rolling_change( + v.addr_count_delta.compute( starting_indexes.height, &blocks.count.height_1m_ago, &v.addr_count.height, diff --git a/crates/brk_computer/src/distribution/cohorts/address/vecs.rs b/crates/brk_computer/src/distribution/cohorts/address/vecs.rs index e14fdb82b..86cbf7343 100644 --- a/crates/brk_computer/src/distribution/cohorts/address/vecs.rs +++ b/crates/brk_computer/src/distribution/cohorts/address/vecs.rs @@ -3,7 +3,7 @@ use std::path::Path; use brk_cohort::{CohortContext, Filter, Filtered}; use brk_error::Result; use brk_traversable::Traversable; -use brk_types::{Cents, Height, Indexes, StoredF64, StoredU64, Version}; +use brk_types::{Cents, Height, Indexes, StoredI64, StoredU64, Version}; use rayon::prelude::*; use vecdb::{AnyStoredVec, AnyVec, Database, Exit, ReadableVec, Rw, StorageMode, WritableVec}; @@ -11,7 +11,7 @@ use crate::{ blocks, distribution::state::{AddressCohortState, MinimalRealizedState}, indexes, - internal::ComputedFromHeight, + internal::{ComputedFromHeight, RollingDelta1m}, prices, }; @@ -29,7 +29,7 @@ pub struct AddressCohortVecs { pub metrics: MinimalCohortMetrics, pub addr_count: ComputedFromHeight, - pub addr_count_change_1m: ComputedFromHeight, + pub addr_count_delta: RollingDelta1m, } impl AddressCohortVecs { @@ -64,10 +64,10 @@ impl AddressCohortVecs { version, indexes, )?, - addr_count_change_1m: ComputedFromHeight::forced_import( + addr_count_delta: RollingDelta1m::forced_import( db, - &cfg.name("addr_count_change_1m"), - version, + &cfg.name("addr_count_delta"), + version + Version::ONE, indexes, )?, }) diff --git a/crates/brk_computer/src/distribution/metrics/cohort/all.rs b/crates/brk_computer/src/distribution/metrics/cohort/all.rs index 1733769b8..0b4382780 100644 --- a/crates/brk_computer/src/distribution/metrics/cohort/all.rs +++ b/crates/brk_computer/src/distribution/metrics/cohort/all.rs @@ -1,13 +1,16 @@ use brk_cohort::Filter; use brk_error::Result; use brk_traversable::Traversable; -use brk_types::{Bitcoin, Cents, Dollars, Height, Indexes, StoredF32, Version}; +use brk_types::{ + Bitcoin, Cents, Dollars, Height, Indexes, Sats, SatsSigned, StoredF32, StoredI64, StoredU64, + Version, +}; use vecdb::AnyStoredVec; use vecdb::{Exit, ReadableVec, Rw, StorageMode}; use crate::{blocks, prices}; -use crate::internal::ComputedFromHeight; +use crate::internal::{ComputedFromHeight, RollingDeltaExcept1m}; use crate::distribution::metrics::{ ActivityFull, CohortMetricsBase, CostBasisWithExtended, ImportConfig, OutputsMetrics, @@ -31,6 +34,9 @@ pub struct AllCohortMetrics { pub relative: Box>, pub dormancy: ComputedFromHeight, pub velocity: ComputedFromHeight, + + pub supply_delta_extended: RollingDeltaExcept1m, + pub utxo_count_delta_extended: RollingDeltaExcept1m, } impl CohortMetricsBase for AllCohortMetrics { @@ -82,6 +88,8 @@ impl AllCohortMetrics { relative: Box::new(relative), dormancy: cfg.import("dormancy", Version::ONE)?, velocity: cfg.import("velocity", Version::ONE)?, + supply_delta_extended: cfg.import("supply_delta", Version::ONE)?, + utxo_count_delta_extended: cfg.import("utxo_count_delta", Version::ONE)?, }) } @@ -123,6 +131,20 @@ impl AllCohortMetrics { exit, )?; + let window_starts = blocks.count.window_starts(); + self.supply_delta_extended.compute( + starting_indexes.height, + &window_starts, + &self.supply.total.sats.height, + exit, + )?; + self.utxo_count_delta_extended.compute( + starting_indexes.height, + &window_starts, + &self.outputs.utxo_count.height, + exit, + )?; + self.dormancy.height.compute_transform2( starting_indexes.height, &self.activity.coindays_destroyed.height, diff --git a/crates/brk_computer/src/distribution/metrics/cohort/extended.rs b/crates/brk_computer/src/distribution/metrics/cohort/extended.rs index 9b4754a5b..2768ac723 100644 --- a/crates/brk_computer/src/distribution/metrics/cohort/extended.rs +++ b/crates/brk_computer/src/distribution/metrics/cohort/extended.rs @@ -1,13 +1,15 @@ use brk_cohort::Filter; use brk_error::Result; use brk_traversable::Traversable; -use brk_types::{Bitcoin, Dollars, Height, Indexes, Sats, StoredF32, Version}; +use brk_types::{ + Bitcoin, Dollars, Height, Indexes, Sats, SatsSigned, StoredF32, StoredI64, StoredU64, Version, +}; use vecdb::AnyStoredVec; use vecdb::{Exit, ReadableVec, Rw, StorageMode}; use crate::{blocks, prices}; -use crate::internal::ComputedFromHeight; +use crate::internal::{ComputedFromHeight, RollingDeltaExcept1m}; use crate::distribution::metrics::{ ActivityFull, CohortMetricsBase, CostBasisWithExtended, ImportConfig, OutputsMetrics, @@ -29,6 +31,9 @@ pub struct ExtendedCohortMetrics { pub relative: Box>, pub dormancy: ComputedFromHeight, pub velocity: ComputedFromHeight, + + pub supply_delta_extended: RollingDeltaExcept1m, + pub utxo_count_delta_extended: RollingDeltaExcept1m, } impl CohortMetricsBase for ExtendedCohortMetrics { @@ -72,6 +77,8 @@ impl ExtendedCohortMetrics { relative: Box::new(relative), dormancy: cfg.import("dormancy", Version::ONE)?, velocity: cfg.import("velocity", Version::ONE)?, + supply_delta_extended: cfg.import("supply_delta", Version::ONE)?, + utxo_count_delta_extended: cfg.import("utxo_count_delta", Version::ONE)?, }) } @@ -103,6 +110,20 @@ impl ExtendedCohortMetrics { exit, )?; + let window_starts = blocks.count.window_starts(); + self.supply_delta_extended.compute( + starting_indexes.height, + &window_starts, + &self.supply.total.sats.height, + exit, + )?; + self.utxo_count_delta_extended.compute( + starting_indexes.height, + &window_starts, + &self.outputs.utxo_count.height, + exit, + )?; + self.dormancy.height.compute_transform2( starting_indexes.height, &self.activity.coindays_destroyed.height, diff --git a/crates/brk_computer/src/distribution/metrics/config.rs b/crates/brk_computer/src/distribution/metrics/config.rs index 25d8e2620..45e4c18f8 100644 --- a/crates/brk_computer/src/distribution/metrics/config.rs +++ b/crates/brk_computer/src/distribution/metrics/config.rs @@ -11,9 +11,9 @@ use crate::{ internal::{ CentsType, ComputedFromHeight, ComputedFromHeightCumulative, ComputedFromHeightCumulativeSum, ComputedFromHeightRatio, FiatFromHeight, NumericValue, - PercentFromHeight, PercentRollingWindows, Price, + PercentFromHeight, PercentRollingWindows, Price, RollingDelta1m, RollingDeltaExcept1m, RollingWindow24h, RollingWindows, RollingWindowsFrom1w, - ValueFromHeight, ValueFromHeightChange, ValueFromHeightCumulative, + ValueFromHeight, ValueFromHeightCumulative, }, }; @@ -39,7 +39,6 @@ macro_rules! impl_config_import { impl_config_import!( ValueFromHeight, ValueFromHeightCumulative, - ValueFromHeightChange, ComputedFromHeightRatio, PercentFromHeight, PercentFromHeight, @@ -84,6 +83,19 @@ impl ConfigImport for FiatFromHeight { Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes) } } +impl ConfigImport for RollingDelta1m +{ + fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result { + Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes) + } +} +impl ConfigImport + for RollingDeltaExcept1m +{ + fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result { + Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes) + } +} impl ConfigImport for BytesVec { fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result { Ok(Self::forced_import( diff --git a/crates/brk_computer/src/distribution/metrics/outputs.rs b/crates/brk_computer/src/distribution/metrics/outputs.rs index 8c4fe809d..4d2280650 100644 --- a/crates/brk_computer/src/distribution/metrics/outputs.rs +++ b/crates/brk_computer/src/distribution/metrics/outputs.rs @@ -1,9 +1,9 @@ use brk_error::Result; use brk_traversable::Traversable; -use brk_types::{Height, Indexes, StoredF64, StoredU64, Version}; +use brk_types::{Height, Indexes, StoredI64, StoredU64, Version}; use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec}; -use crate::{blocks, internal::ComputedFromHeight}; +use crate::{blocks, internal::{ComputedFromHeight, RollingDelta1m}}; use super::ImportConfig; @@ -11,7 +11,7 @@ use super::ImportConfig; #[derive(Traversable)] pub struct OutputsMetrics { pub utxo_count: ComputedFromHeight, - pub utxo_count_change_1m: ComputedFromHeight, + pub utxo_count_delta: RollingDelta1m, } impl OutputsMetrics { @@ -19,7 +19,7 @@ impl OutputsMetrics { pub(crate) fn forced_import(cfg: &ImportConfig) -> Result { Ok(Self { utxo_count: cfg.import("utxo_count", Version::ZERO)?, - utxo_count_change_1m: cfg.import("utxo_count_change_1m", Version::ZERO)?, + utxo_count_delta: cfg.import("utxo_count_delta", Version::ONE)?, }) } @@ -65,7 +65,7 @@ impl OutputsMetrics { starting_indexes: &Indexes, exit: &Exit, ) -> Result<()> { - self.utxo_count_change_1m.height.compute_rolling_change( + self.utxo_count_delta.compute( starting_indexes.height, &blocks.count.height_1m_ago, &self.utxo_count.height, diff --git a/crates/brk_computer/src/distribution/metrics/realized/core.rs b/crates/brk_computer/src/distribution/metrics/realized/core.rs index 01e100bf0..a5087f8ec 100644 --- a/crates/brk_computer/src/distribution/metrics/realized/core.rs +++ b/crates/brk_computer/src/distribution/metrics/realized/core.rs @@ -11,7 +11,7 @@ use crate::{ distribution::state::RealizedOps, internal::{ ComputedFromHeight, ComputedFromHeightCumulative, LazyFromHeight, - NegCentsUnsignedToDollars, RatioCents64, RollingWindow24h, + NegCentsUnsignedToDollars, RatioCents64, RollingDelta1m, RollingWindow24h, }, prices, }; @@ -27,7 +27,7 @@ pub struct RealizedCore { #[traversable(flatten)] pub minimal: RealizedMinimal, - pub realized_cap_change_1m: ComputedFromHeight, + pub realized_cap_delta: RollingDelta1m, pub neg_realized_loss: LazyFromHeight, pub net_realized_pnl: ComputedFromHeightCumulative, @@ -63,7 +63,7 @@ impl RealizedCore { Ok(Self { minimal, - realized_cap_change_1m: cfg.import("realized_cap_change_1m", v0)?, + realized_cap_delta: cfg.import("realized_cap_delta", v1)?, neg_realized_loss, net_realized_pnl, value_created, @@ -154,7 +154,7 @@ impl RealizedCore { self.minimal .compute_rest_part2(prices, starting_indexes, height_to_supply, exit)?; - self.realized_cap_change_1m.height.compute_rolling_change( + self.realized_cap_delta.compute( starting_indexes.height, &blocks.count.height_1m_ago, &self.minimal.realized_cap_cents.height, diff --git a/crates/brk_computer/src/distribution/metrics/realized/full.rs b/crates/brk_computer/src/distribution/metrics/realized/full.rs index d472a1b56..ef6e7cfd6 100644 --- a/crates/brk_computer/src/distribution/metrics/realized/full.rs +++ b/crates/brk_computer/src/distribution/metrics/realized/full.rs @@ -19,7 +19,7 @@ use crate::{ ComputedFromHeightRatioStdDevBands, LazyFromHeight, PercentFromHeight, PercentRollingWindows, Price, RatioCents64, RatioCentsBp32, RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32, RatioDollarsBp32, - RollingWindows, RollingWindowsFrom1w, + RollingDelta1m, RollingDeltaExcept1m, RollingWindows, RollingWindowsFrom1w, }, prices, }; @@ -56,10 +56,13 @@ pub struct RealizedFull { pub gross_pnl_sum: RollingWindows, - pub net_pnl_change_1m: ComputedFromHeight, + pub net_pnl_delta: RollingDelta1m, + pub net_pnl_delta_extended: RollingDeltaExcept1m, pub net_pnl_change_1m_rel_to_realized_cap: PercentFromHeight, pub net_pnl_change_1m_rel_to_market_cap: PercentFromHeight, + pub realized_cap_delta_extended: RollingDeltaExcept1m, + pub investor_price: Price>, pub investor_price_ratio: ComputedFromHeightRatio, @@ -176,11 +179,13 @@ impl RealizedFull { capitulation_flow, profit_flow, gross_pnl_sum, - net_pnl_change_1m: cfg.import("net_pnl_change_1m", Version::new(3))?, + net_pnl_delta: cfg.import("net_pnl_delta", Version::new(5))?, + net_pnl_delta_extended: cfg.import("net_pnl_delta", Version::new(5))?, net_pnl_change_1m_rel_to_realized_cap: cfg .import("net_pnl_change_1m_rel_to_realized_cap", Version::new(4))?, net_pnl_change_1m_rel_to_market_cap: cfg .import("net_pnl_change_1m_rel_to_market_cap", Version::new(4))?, + realized_cap_delta_extended: cfg.import("realized_cap_delta", Version::new(5))?, investor_price, investor_price_ratio, lower_price_band, @@ -425,28 +430,42 @@ impl RealizedFull { exit, )?; - // Net PnL change 1m - self.net_pnl_change_1m.height.compute_rolling_change( + // Net PnL delta (1m base + 24h/1w/1y extended) + self.net_pnl_delta.compute( starting_indexes.height, &blocks.count.height_1m_ago, &self.base.core.net_realized_pnl.cumulative.height, exit, )?; + self.net_pnl_delta_extended.compute( + starting_indexes.height, + &window_starts, + &self.base.core.net_realized_pnl.cumulative.height, + exit, + )?; self.net_pnl_change_1m_rel_to_realized_cap .compute_binary::( starting_indexes.height, - &self.net_pnl_change_1m.height, + &self.net_pnl_delta.change_1m.height, &self.base.core.minimal.realized_cap_cents.height, exit, )?; self.net_pnl_change_1m_rel_to_market_cap .compute_binary::( starting_indexes.height, - &self.net_pnl_change_1m.height, + &self.net_pnl_delta.change_1m.height, height_to_market_cap, exit, )?; + // Realized cap delta extended (24h/1w/1y — 1m is in RealizedCore) + self.realized_cap_delta_extended.compute( + starting_indexes.height, + &window_starts, + &self.base.core.minimal.realized_cap_cents.height, + exit, + )?; + // Peak regret self.peak_regret_rel_to_realized_cap .compute_binary::( diff --git a/crates/brk_computer/src/distribution/metrics/supply.rs b/crates/brk_computer/src/distribution/metrics/supply.rs index 48c23220f..0460c70f5 100644 --- a/crates/brk_computer/src/distribution/metrics/supply.rs +++ b/crates/brk_computer/src/distribution/metrics/supply.rs @@ -1,13 +1,13 @@ use brk_error::Result; use brk_traversable::Traversable; -use brk_types::{Height, Indexes, Sats, Version}; +use brk_types::{Height, Indexes, Sats, SatsSigned, Version}; use crate::{blocks, prices}; use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec}; use crate::internal::{ - HalveCents, HalveDollars, HalveSats, HalveSatsToBitcoin, LazyValueFromHeight, ValueFromHeight, - ValueFromHeightChange, + HalveCents, HalveDollars, HalveSats, HalveSatsToBitcoin, LazyValueFromHeight, + RollingDelta1m, ValueFromHeight, }; use super::ImportConfig; @@ -17,8 +17,7 @@ use super::ImportConfig; pub struct SupplyMetrics { pub total: ValueFromHeight, pub halved: LazyValueFromHeight, - /// 1-month change in supply (net position change) - sats, btc, usd - pub change_1m: ValueFromHeightChange, + pub delta: RollingDelta1m, } impl SupplyMetrics { @@ -33,12 +32,12 @@ impl SupplyMetrics { HalveDollars, >(&cfg.name("supply_halved"), &supply, cfg.version); - let change_1m = cfg.import("supply_change_1m", Version::ZERO)?; + let delta = cfg.import("supply_delta", Version::ONE)?; Ok(Self { total: supply, halved: supply_halved, - change_1m, + delta, }) } @@ -101,11 +100,10 @@ impl SupplyMetrics { starting_indexes: &Indexes, exit: &Exit, ) -> Result<()> { - self.change_1m.compute_rolling( + self.delta.compute( starting_indexes.height, &blocks.count.height_1m_ago, &self.total.sats.height, - &self.total.cents.height, exit, ) } diff --git a/crates/brk_computer/src/internal/from_height/computed/delta.rs b/crates/brk_computer/src/internal/from_height/computed/delta.rs index 8690d37ab..9f49049c2 100644 --- a/crates/brk_computer/src/internal/from_height/computed/delta.rs +++ b/crates/brk_computer/src/internal/from_height/computed/delta.rs @@ -1,4 +1,9 @@ -//! RollingDelta - raw change + growth rate (%) across 4 time windows. +//! RollingDelta - raw change + growth rate (%) across time windows. +//! +//! Three tiers: +//! - `RollingDelta1m` — 1m window only (2 stored vecs: change + rate). Default for all cohorts. +//! - `RollingDeltaExcept1m` — 24h + 1w + 1y windows (6 stored vecs). Extended tier only. +//! - `RollingDelta` — all 4 windows (8 stored vecs). Used for standalone global metrics. //! //! For a monotonic source (e.g., cumulative address count): //! - `change._24h` = count_now - count_24h_ago @@ -6,15 +11,76 @@ use brk_error::Result; use brk_traversable::Traversable; -use brk_types::{BasisPoints32, Height, Version}; +use brk_types::{BasisPoints32, BasisPointsSigned32, Height, Version}; use schemars::JsonSchema; -use vecdb::{AnyVec, Database, Exit, ReadableVec, Rw, StorageMode, VecIndex}; +use vecdb::{AnyVec, Database, EagerVec, Exit, PcoVec, ReadableVec, Rw, StorageMode, VecIndex}; use crate::{ indexes, - internal::{NumericValue, PercentRollingWindows, RollingWindows, WindowStarts}, + internal::{ + ComputedFromHeight, NumericValue, PercentFromHeight, PercentRollingWindows, + RollingWindows, WindowStarts, + }, }; +/// Pre-collect source data from the earliest needed offset. +/// Returns (source_data, offset) for use in compute_delta_window. +fn collect_source( + source: &impl ReadableVec, + skip: usize, + earliest_starts: &impl ReadableVec, +) -> (Vec, usize) { + let source_len = source.len(); + let offset = if skip > 0 && skip < earliest_starts.len() { + earliest_starts.collect_one_at(skip).unwrap().to_usize() + } else { + 0 + }; + (source.collect_range_at(offset, source_len), offset) +} + +/// Shared computation: change = current - ago, rate = change / ago. +fn compute_delta_window( + change_h: &mut EagerVec>, + rate_bps_h: &mut EagerVec>, + max_from: Height, + starts: &impl ReadableVec, + source_data: &[S], + offset: usize, + exit: &Exit, +) -> Result<()> +where + S: NumericValue, + C: NumericValue, + B: NumericValue, +{ + change_h.compute_transform( + max_from, + starts, + |(h, ago_h, ..)| { + let current: f64 = source_data[h.to_usize() - offset].into(); + let ago: f64 = source_data[ago_h.to_usize() - offset].into(); + (h, C::from(current - ago)) + }, + exit, + )?; + + rate_bps_h.compute_transform( + max_from, + &*change_h, + |(h, change, ..)| { + let current_f: f64 = source_data[h.to_usize() - offset].into(); + let change_f: f64 = change.into(); + let ago = current_f - change_f; + let rate = if ago == 0.0 { 0.0 } else { change_f / ago }; + (h, B::from(rate)) + }, + exit, + )?; + + Ok(()) +} + #[derive(Traversable)] pub struct RollingDelta where @@ -60,58 +126,193 @@ where windows: &WindowStarts<'_>, source: &impl ReadableVec, exit: &Exit, - ) -> Result<()> - where - S: Default, - { - // Step 1: change = current - ago - for (change_w, starts) in self.change.0.as_mut_array().into_iter().zip(windows.as_array()) - { - // Pre-collect source from earliest ago_h to end for fast array indexing - let skip = change_w.height.len(); - let source_len = source.len(); - let offset = if skip > 0 && skip < starts.len() { - starts.collect_one_at(skip).unwrap().to_usize() - } else { - 0 - }; - let source_data = source.collect_range_at(offset, source_len); + ) -> Result<()> { + // Pre-collect once using the widest window (1y has earliest ago heights) + let skip = self.change.0._24h.height.len(); + let (source_data, offset) = collect_source(source, skip, windows._1y); - change_w.height.compute_transform( - max_from, - *starts, - |(h, ago_h, ..)| { - let current: f64 = source_data[h.to_usize() - offset].into(); - let ago: f64 = source_data[ago_h.to_usize() - offset].into(); - (h, C::from(current - ago)) - }, - exit, - )?; - } - - // Step 2: rate = change / ago = change / (current - change) - for (growth_w, change_w) in self - .rate + for ((change_w, rate_w), starts) in self + .change .0 .as_mut_array() .into_iter() - .zip(self.change.0.as_array()) + .zip(self.rate.0.as_mut_array()) + .zip(windows.as_array()) { - growth_w.bps.height.compute_transform2( + compute_delta_window( + &mut change_w.height, + &mut rate_w.bps.height, max_from, - source, - &change_w.height, - |(h, current, change, ..)| { - let current_f: f64 = current.into(); - let change_f: f64 = change.into(); - let ago = current_f - change_f; - let rate = if ago == 0.0 { 0.0 } else { change_f / ago }; - (h, BasisPoints32::from(rate)) - }, + *starts, + &source_data, + offset, + exit, + )?; + } + Ok(()) + } +} + +/// 1m-only delta: change + growth rate for the 1-month window. +/// Default tier for all cohorts (2 stored vecs). +#[derive(Traversable)] +pub struct RollingDelta1m +where + S: NumericValue + JsonSchema, + C: NumericValue + JsonSchema, +{ + pub change_1m: ComputedFromHeight, + pub rate_1m: PercentFromHeight, + _phantom: std::marker::PhantomData, +} + +impl RollingDelta1m +where + S: NumericValue + JsonSchema, + C: NumericValue + JsonSchema, +{ + pub(crate) fn forced_import( + db: &Database, + name: &str, + version: Version, + indexes: &indexes::Vecs, + ) -> Result { + Ok(Self { + change_1m: ComputedFromHeight::forced_import( + db, + &format!("{name}_change_1m"), + version, + indexes, + )?, + rate_1m: PercentFromHeight::forced_import( + db, + &format!("{name}_rate_1m"), + version, + indexes, + )?, + _phantom: std::marker::PhantomData, + }) + } + + pub(crate) fn compute( + &mut self, + max_from: Height, + height_1m_ago: &impl ReadableVec, + source: &impl ReadableVec, + exit: &Exit, + ) -> Result<()> { + let skip = self.change_1m.height.len(); + let (source_data, offset) = collect_source(source, skip, height_1m_ago); + + compute_delta_window( + &mut self.change_1m.height, + &mut self.rate_1m.bps.height, + max_from, + height_1m_ago, + &source_data, + offset, + exit, + ) + } +} + +/// Extended delta: 24h + 1w + 1y windows (6 stored vecs). +/// Only for All/LTH/STH cohorts (Extended tier). +#[derive(Traversable)] +pub struct RollingDeltaExcept1m +where + S: NumericValue + JsonSchema, + C: NumericValue + JsonSchema, +{ + #[traversable(rename = "24h")] + pub change_24h: ComputedFromHeight, + pub change_1w: ComputedFromHeight, + pub change_1y: ComputedFromHeight, + #[traversable(rename = "24h")] + pub rate_24h: PercentFromHeight, + pub rate_1w: PercentFromHeight, + pub rate_1y: PercentFromHeight, + _phantom: std::marker::PhantomData, +} + +impl RollingDeltaExcept1m +where + S: NumericValue + JsonSchema, + C: NumericValue + JsonSchema, +{ + pub(crate) fn forced_import( + db: &Database, + name: &str, + version: Version, + indexes: &indexes::Vecs, + ) -> Result { + Ok(Self { + change_24h: ComputedFromHeight::forced_import( + db, + &format!("{name}_change_24h"), + version, + indexes, + )?, + change_1w: ComputedFromHeight::forced_import( + db, + &format!("{name}_change_1w"), + version, + indexes, + )?, + change_1y: ComputedFromHeight::forced_import( + db, + &format!("{name}_change_1y"), + version, + indexes, + )?, + rate_24h: PercentFromHeight::forced_import( + db, + &format!("{name}_rate_24h"), + version, + indexes, + )?, + rate_1w: PercentFromHeight::forced_import( + db, + &format!("{name}_rate_1w"), + version, + indexes, + )?, + rate_1y: PercentFromHeight::forced_import( + db, + &format!("{name}_rate_1y"), + version, + indexes, + )?, + _phantom: std::marker::PhantomData, + }) + } + + pub(crate) fn compute( + &mut self, + max_from: Height, + windows: &WindowStarts<'_>, + source: &impl ReadableVec, + exit: &Exit, + ) -> Result<()> { + // Pre-collect once using the widest window (1y has earliest ago heights) + let skip = self.change_24h.height.len(); + let (source_data, offset) = collect_source(source, skip, windows._1y); + + let changes = [&mut self.change_24h, &mut self.change_1w, &mut self.change_1y]; + let rates = [&mut self.rate_24h, &mut self.rate_1w, &mut self.rate_1y]; + let starts = [windows._24h, windows._1w, windows._1y]; + + for ((change_w, rate_w), starts) in changes.into_iter().zip(rates).zip(starts) { + compute_delta_window( + &mut change_w.height, + &mut rate_w.bps.height, + max_from, + starts, + &source_data, + offset, exit, )?; } - Ok(()) } } diff --git a/crates/brk_computer/src/internal/from_height/computed/mod.rs b/crates/brk_computer/src/internal/from_height/computed/mod.rs index d71bd7517..702958f80 100644 --- a/crates/brk_computer/src/internal/from_height/computed/mod.rs +++ b/crates/brk_computer/src/internal/from_height/computed/mod.rs @@ -1,13 +1,15 @@ mod aggregated; mod cumulative; mod cumulative_sum; -mod full; mod delta; +mod full; mod rolling_average; +mod sum; pub use aggregated::*; pub use cumulative::*; pub use cumulative_sum::*; -pub use full::*; pub use delta::*; +pub use full::*; pub use rolling_average::*; +pub use sum::*; diff --git a/crates/brk_computer/src/internal/from_height/computed/sum.rs b/crates/brk_computer/src/internal/from_height/computed/sum.rs new file mode 100644 index 000000000..0257f3793 --- /dev/null +++ b/crates/brk_computer/src/internal/from_height/computed/sum.rs @@ -0,0 +1,59 @@ +//! ComputedFromHeightSum - stored height + RollingWindows (sum only). +//! +//! Like ComputedFromHeightCumulativeSum but without the cumulative vec. + +use std::ops::SubAssign; + +use brk_error::Result; +use brk_traversable::Traversable; +use brk_types::{Height, Version}; +use schemars::JsonSchema; +use vecdb::{Database, EagerVec, Exit, ImportableVec, PcoVec, Rw, StorageMode}; + +use crate::{ + indexes, + internal::{NumericValue, RollingWindows, WindowStarts}, +}; + +#[derive(Traversable)] +pub struct ComputedFromHeightSum +where + T: NumericValue + JsonSchema, +{ + pub height: M::Stored>>, + pub sum: RollingWindows, +} + +impl ComputedFromHeightSum +where + T: NumericValue + JsonSchema, +{ + pub(crate) fn forced_import( + db: &Database, + name: &str, + version: Version, + indexes: &indexes::Vecs, + ) -> Result { + let height: EagerVec> = EagerVec::forced_import(db, name, version)?; + let sum = RollingWindows::forced_import(db, &format!("{name}_sum"), version, indexes)?; + + Ok(Self { height, sum }) + } + + /// Compute height data via closure, then rolling sum. + pub(crate) fn compute( + &mut self, + max_from: Height, + windows: &WindowStarts<'_>, + exit: &Exit, + compute_height: impl FnOnce(&mut EagerVec>) -> Result<()>, + ) -> Result<()> + where + T: Default + SubAssign, + { + compute_height(&mut self.height)?; + self.sum + .compute_rolling_sum(max_from, windows, &self.height, exit)?; + Ok(()) + } +} diff --git a/crates/brk_computer/src/internal/from_height/value/change.rs b/crates/brk_computer/src/internal/from_height/value/change.rs deleted file mode 100644 index 523623232..000000000 --- a/crates/brk_computer/src/internal/from_height/value/change.rs +++ /dev/null @@ -1,79 +0,0 @@ -//! Change values from Height - stores signed sats and dollars (changes can be negative). - -use brk_error::Result; -use brk_traversable::Traversable; -use brk_types::{Bitcoin, Cents, CentsSigned, Dollars, Height, Sats, SatsSigned, Version}; -use vecdb::{Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode}; - -use crate::{ - indexes, - internal::{CentsSignedToDollars, ComputedFromHeight, LazyFromHeight, SatsSignedToBitcoin}, -}; - -/// Change values indexed by height - sats (stored), btc (lazy), cents (stored), usd (lazy). -#[derive(Traversable)] -pub struct ValueFromHeightChange { - pub sats: ComputedFromHeight, - pub btc: LazyFromHeight, - pub cents: ComputedFromHeight, - pub usd: LazyFromHeight, -} - -impl ValueFromHeightChange { - pub(crate) fn forced_import( - db: &Database, - name: &str, - version: Version, - indexes: &indexes::Vecs, - ) -> Result { - let sats = ComputedFromHeight::forced_import(db, name, version, indexes)?; - - let btc = LazyFromHeight::from_computed::( - &format!("{name}_btc"), - version, - sats.height.read_only_boxed_clone(), - &sats, - ); - - let cents = - ComputedFromHeight::forced_import(db, &format!("{name}_cents"), version, indexes)?; - - let usd = LazyFromHeight::from_computed::( - &format!("{name}_usd"), - version, - cents.height.read_only_boxed_clone(), - ¢s, - ); - - Ok(Self { - sats, - btc, - cents, - usd, - }) - } - - /// Compute rolling change for both sats and cents in one call. - pub(crate) fn compute_rolling( - &mut self, - starting_height: Height, - window_starts: &impl ReadableVec, - sats_source: &impl ReadableVec, - cents_source: &(impl ReadableVec + Sync), - exit: &Exit, - ) -> Result<()> { - self.sats.height.compute_rolling_change( - starting_height, - window_starts, - sats_source, - exit, - )?; - self.cents.height.compute_rolling_change( - starting_height, - window_starts, - cents_source, - exit, - )?; - Ok(()) - } -} diff --git a/crates/brk_computer/src/internal/from_height/value/mod.rs b/crates/brk_computer/src/internal/from_height/value/mod.rs index afd73770e..7d7c37f4e 100644 --- a/crates/brk_computer/src/internal/from_height/value/mod.rs +++ b/crates/brk_computer/src/internal/from_height/value/mod.rs @@ -1,5 +1,4 @@ mod base; -mod change; mod cumulative; mod cumulative_sum; mod full; @@ -7,7 +6,6 @@ mod lazy; mod rolling; pub use base::*; -pub use change::*; pub use cumulative::*; pub use cumulative_sum::*; pub use full::*; diff --git a/crates/brk_computer/src/internal/transform/currency.rs b/crates/brk_computer/src/internal/transform/currency.rs index df3532cb3..07e4a75ee 100644 --- a/crates/brk_computer/src/internal/transform/currency.rs +++ b/crates/brk_computer/src/internal/transform/currency.rs @@ -1,4 +1,4 @@ -use brk_types::{Bitcoin, Cents, CentsSigned, Dollars, Sats, SatsFract, SatsSigned}; +use brk_types::{Bitcoin, Cents, CentsSigned, Dollars, Sats, SatsFract}; use vecdb::{BinaryTransform, UnaryTransform}; pub struct SatsToBitcoin; @@ -10,15 +10,6 @@ impl UnaryTransform for SatsToBitcoin { } } -pub struct SatsSignedToBitcoin; - -impl UnaryTransform for SatsSignedToBitcoin { - #[inline(always)] - fn apply(sats: SatsSigned) -> Bitcoin { - Bitcoin::from(sats) - } -} - pub struct SatsToCents; impl BinaryTransform for SatsToCents { diff --git a/crates/brk_computer/src/internal/transform/mod.rs b/crates/brk_computer/src/internal/transform/mod.rs index e1d775d2f..11fa8010e 100644 --- a/crates/brk_computer/src/internal/transform/mod.rs +++ b/crates/brk_computer/src/internal/transform/mod.rs @@ -16,7 +16,7 @@ pub use bps::{ pub use currency::{ CentsSignedToDollars, CentsSubtractToCentsSigned, CentsTimesTenths, CentsUnsignedToDollars, CentsUnsignedToSats, DollarsToSatsFract, NegCentsUnsignedToDollars, - SatsSignedToBitcoin, SatsToBitcoin, SatsToCents, + SatsToBitcoin, SatsToCents, }; pub use derived::{ Days7, Days30, Days365, DaysToYears, PerSec, PriceTimesRatioBp32Cents, PriceTimesRatioCents, diff --git a/crates/brk_computer/src/supply/compute.rs b/crates/brk_computer/src/supply/compute.rs index 155b0f1f4..c81e91c4e 100644 --- a/crates/brk_computer/src/supply/compute.rs +++ b/crates/brk_computer/src/supply/compute.rs @@ -44,16 +44,8 @@ impl Vecs { self.velocity .compute(blocks, transactions, distribution, starting_indexes, exit)?; - // 4. Compute cap growth rates using 1y lookback - self.market_cap_growth_rate - .bps - .height - .compute_rolling_ratio_change( - starting_indexes.height, - &blocks.count.height_1y_ago, - &self.market_cap.height, - exit, - )?; + // 4. Compute cap growth rates across 4 windows + let window_starts = blocks.count.window_starts(); let realized_cap = &distribution .utxo_cohorts @@ -62,25 +54,32 @@ impl Vecs { .realized .realized_cap .height; - self.realized_cap_growth_rate - .bps - .height - .compute_rolling_ratio_change( + + let mcgr_arr = self.market_cap_growth_rate.0.as_mut_array(); + let rcgr_arr = self.realized_cap_growth_rate.0.as_mut_array(); + let diff_arr = self.market_minus_realized_cap_growth_rate.0.as_mut_array(); + let starts_arr = window_starts.as_array(); + + for i in 0..4 { + mcgr_arr[i].bps.height.compute_rolling_ratio_change( starting_indexes.height, - &blocks.count.height_1y_ago, + *starts_arr[i], + &self.market_cap.height, + exit, + )?; + rcgr_arr[i].bps.height.compute_rolling_ratio_change( + starting_indexes.height, + *starts_arr[i], realized_cap, exit, )?; - - // 5. Compute cap growth rate diff: market - realized - self.market_minus_realized_cap_growth_rate - .height - .compute_subtract( + diff_arr[i].height.compute_subtract( starting_indexes.height, - &self.market_cap_growth_rate.bps.height, - &self.realized_cap_growth_rate.bps.height, + &mcgr_arr[i].bps.height, + &rcgr_arr[i].bps.height, exit, )?; + } let _lock = exit.lock(); self.db.compact()?; diff --git a/crates/brk_computer/src/supply/import.rs b/crates/brk_computer/src/supply/import.rs index cdb3ea82c..6356e5d11 100644 --- a/crates/brk_computer/src/supply/import.rs +++ b/crates/brk_computer/src/supply/import.rs @@ -6,8 +6,8 @@ use brk_types::{Cents, Dollars, Sats, Version}; use crate::{ distribution, indexes, internal::{ - ComputedFromHeight, Identity, LazyFromHeight, LazyValueFromHeight, PercentFromHeight, - SatsToBitcoin, finalize_db, open_db, + Identity, LazyFromHeight, LazyValueFromHeight, PercentFromHeight, PercentRollingWindows, + RollingWindows, SatsToBitcoin, finalize_db, open_db, }, }; @@ -52,23 +52,23 @@ impl Vecs { &supply_metrics.total.usd, ); - // Growth rates - let market_cap_growth_rate = PercentFromHeight::forced_import( + // Growth rates (4 windows: 24h, 1w, 1m, 1y) + let market_cap_growth_rate = PercentRollingWindows::forced_import( &db, "market_cap_growth_rate", - version + Version::ONE, + version + Version::TWO, indexes, )?; - let realized_cap_growth_rate = PercentFromHeight::forced_import( + let realized_cap_growth_rate = PercentRollingWindows::forced_import( &db, "realized_cap_growth_rate", - version + Version::ONE, + version + Version::TWO, indexes, )?; - let market_minus_realized_cap_growth_rate = ComputedFromHeight::forced_import( + let market_minus_realized_cap_growth_rate = RollingWindows::forced_import( &db, "market_minus_realized_cap_growth_rate", - version, + version + Version::ONE, indexes, )?; diff --git a/crates/brk_computer/src/supply/vecs.rs b/crates/brk_computer/src/supply/vecs.rs index 8aaa1d961..0e8e789fc 100644 --- a/crates/brk_computer/src/supply/vecs.rs +++ b/crates/brk_computer/src/supply/vecs.rs @@ -3,7 +3,9 @@ use brk_types::{BasisPointsSigned32, Dollars}; use vecdb::{Database, Rw, StorageMode}; use super::{burned, velocity}; -use crate::internal::{ComputedFromHeight, LazyFromHeight, LazyValueFromHeight, PercentFromHeight}; +use crate::internal::{ + LazyFromHeight, LazyValueFromHeight, PercentFromHeight, PercentRollingWindows, RollingWindows, +}; #[derive(Traversable)] pub struct Vecs { @@ -15,7 +17,7 @@ pub struct Vecs { pub inflation_rate: PercentFromHeight, pub velocity: velocity::Vecs, pub market_cap: LazyFromHeight, - pub market_cap_growth_rate: PercentFromHeight, - pub realized_cap_growth_rate: PercentFromHeight, - pub market_minus_realized_cap_growth_rate: ComputedFromHeight, + pub market_cap_growth_rate: PercentRollingWindows, + pub realized_cap_growth_rate: PercentRollingWindows, + pub market_minus_realized_cap_growth_rate: RollingWindows, } diff --git a/modules/brk-client/index.js b/modules/brk-client/index.js index 33e42c616..92acfa600 100644 --- a/modules/brk-client/index.js +++ b/modules/brk-client/index.js @@ -1591,9 +1591,10 @@ function createMetricPattern35(client, name) { return /** @type {MetricPattern35 * @property {CentsSatsUsdPattern} lowerPriceBand * @property {MetricPattern1} mvrv * @property {MetricPattern1} negRealizedLoss - * @property {MetricPattern1} netPnlChange1m * @property {BpsPercentRatioPattern} netPnlChange1mRelToMarketCap * @property {BpsPercentRatioPattern} netPnlChange1mRelToRealizedCap + * @property {ChangeRatePattern} netPnlDelta + * @property {_24hChangeRatePattern} netPnlDeltaExtended * @property {CumulativeHeightPattern} netRealizedPnl * @property {BpsPercentRatioPattern} netRealizedPnlRelToRealizedCap * @property {CumulativeHeightPattern} peakRegret @@ -1605,7 +1606,8 @@ function createMetricPattern35(client, name) { return /** @type {MetricPattern35 * @property {_1m1w1y24hPattern} profitValueDestroyedSum * @property {MetricPattern1} realizedCap * @property {MetricPattern1} realizedCapCents - * @property {MetricPattern1} realizedCapChange1m + * @property {ChangeRatePattern} realizedCapDelta + * @property {_24hChangeRatePattern} realizedCapDeltaExtended * @property {BpsPercentRatioPattern} realizedCapRelToOwnMarketCap * @property {CumulativeHeightPattern} realizedLoss * @property {BpsPercentRatioPattern} realizedLossRelToRealizedCap @@ -1661,9 +1663,10 @@ function createCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealized lowerPriceBand: createCentsSatsUsdPattern(client, _m(acc, 'lower_price_band')), mvrv: createMetricPattern1(client, _m(acc, 'mvrv')), negRealizedLoss: createMetricPattern1(client, _m(acc, 'neg_realized_loss')), - netPnlChange1m: createMetricPattern1(client, _m(acc, 'net_pnl_change_1m')), netPnlChange1mRelToMarketCap: createBpsPercentRatioPattern(client, _m(acc, 'net_pnl_change_1m_rel_to_market_cap')), netPnlChange1mRelToRealizedCap: createBpsPercentRatioPattern(client, _m(acc, 'net_pnl_change_1m_rel_to_realized_cap')), + netPnlDelta: createChangeRatePattern(client, _m(acc, 'net_pnl_delta')), + netPnlDeltaExtended: create_24hChangeRatePattern(client, _m(acc, 'net_pnl_delta')), netRealizedPnl: createCumulativeHeightPattern(client, _m(acc, 'net_realized_pnl')), netRealizedPnlRelToRealizedCap: createBpsPercentRatioPattern(client, _m(acc, 'net_realized_pnl_rel_to_realized_cap')), peakRegret: createCumulativeHeightPattern(client, _m(acc, 'realized_peak_regret')), @@ -1675,7 +1678,8 @@ function createCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealized profitValueDestroyedSum: create_1m1w1y24hPattern(client, _m(acc, 'profit_value_destroyed')), realizedCap: createMetricPattern1(client, _m(acc, 'realized_cap')), realizedCapCents: createMetricPattern1(client, _m(acc, 'realized_cap_cents')), - realizedCapChange1m: createMetricPattern1(client, _m(acc, 'realized_cap_change_1m')), + realizedCapDelta: createChangeRatePattern(client, _m(acc, 'realized_cap_delta')), + realizedCapDeltaExtended: create_24hChangeRatePattern(client, _m(acc, 'realized_cap_delta')), realizedCapRelToOwnMarketCap: createBpsPercentRatioPattern(client, _m(acc, 'realized_cap_rel_to_own_market_cap')), realizedLoss: createCumulativeHeightPattern(client, _m(acc, 'realized_loss')), realizedLossRelToRealizedCap: createBpsPercentRatioPattern(client, _m(acc, 'realized_loss_rel_to_realized_cap')), @@ -1787,7 +1791,7 @@ function create_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern(client * @property {CumulativeHeightPattern} netRealizedPnl * @property {MetricPattern1} realizedCap * @property {MetricPattern1} realizedCapCents - * @property {MetricPattern1} realizedCapChange1m + * @property {ChangeRatePattern} realizedCapDelta * @property {CumulativeHeightPattern} realizedLoss * @property {_24hPattern} realizedLossSum * @property {CentsSatsUsdPattern} realizedPrice @@ -1818,7 +1822,7 @@ function createMvrvNegNetRealizedSentSoprValuePattern(client, acc) { netRealizedPnl: createCumulativeHeightPattern(client, _m(acc, 'net_realized_pnl')), realizedCap: createMetricPattern1(client, _m(acc, 'realized_cap')), realizedCapCents: createMetricPattern1(client, _m(acc, 'realized_cap_cents')), - realizedCapChange1m: createMetricPattern1(client, _m(acc, 'realized_cap_change_1m')), + realizedCapDelta: createChangeRatePattern(client, _m(acc, 'realized_cap_delta')), realizedLoss: createCumulativeHeightPattern(client, _m(acc, 'realized_loss')), realizedLossSum: create_24hPattern(client, _m(acc, 'realized_loss_24h')), realizedPrice: createCentsSatsUsdPattern(client, _m(acc, 'realized_price')), @@ -1897,7 +1901,7 @@ function createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65 * @property {CumulativeHeightPattern} netRealizedPnl * @property {MetricPattern1} realizedCap * @property {MetricPattern1} realizedCapCents - * @property {MetricPattern1} realizedCapChange1m + * @property {ChangeRatePattern} realizedCapDelta * @property {CumulativeHeightPattern} realizedLoss * @property {_24hPattern} realizedLossSum * @property {CentsSatsUsdPattern} realizedPrice @@ -1924,7 +1928,7 @@ function createMvrvNegNetRealizedSoprValuePattern(client, acc) { netRealizedPnl: createCumulativeHeightPattern(client, _m(acc, 'net_realized_pnl')), realizedCap: createMetricPattern1(client, _m(acc, 'realized_cap')), realizedCapCents: createMetricPattern1(client, _m(acc, 'realized_cap_cents')), - realizedCapChange1m: createMetricPattern1(client, _m(acc, 'realized_cap_change_1m')), + realizedCapDelta: createChangeRatePattern(client, _m(acc, 'realized_cap_delta')), realizedLoss: createCumulativeHeightPattern(client, _m(acc, 'realized_loss')), realizedLossSum: create_24hPattern(client, _m(acc, 'realized_loss_24h')), realizedPrice: createCentsSatsUsdPattern(client, _m(acc, 'realized_price')), @@ -2643,7 +2647,7 @@ function create_10y2y3y4y5y6y8yPattern(client, acc) { * @property {UtxoPattern} outputs * @property {MvrvNegNetRealizedSentSoprValuePattern} realized * @property {SupplyPattern2} relative - * @property {ChangeHalvedTotalPattern} supply + * @property {DeltaHalvedTotalPattern} supply * @property {InvestedInvestorNegNetSupplyUnrealizedPattern} unrealized */ @@ -2660,7 +2664,7 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern(client outputs: createUtxoPattern(client, _m(acc, 'utxo_count')), realized: createMvrvNegNetRealizedSentSoprValuePattern(client, acc), relative: createSupplyPattern2(client, _m(acc, 'supply')), - supply: createChangeHalvedTotalPattern(client, _m(acc, 'supply')), + supply: createDeltaHalvedTotalPattern(client, _m(acc, 'supply')), unrealized: createInvestedInvestorNegNetSupplyUnrealizedPattern(client, acc), }; } @@ -2669,10 +2673,10 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern(client * @typedef {Object} ActivityAddrOutputsRealizedSupplyUnrealizedPattern * @property {SentPattern} activity * @property {MetricPattern1} addrCount - * @property {MetricPattern1} addrCountChange1m + * @property {ChangeRatePattern} addrCountDelta * @property {UtxoPattern} outputs * @property {MvrvRealizedPattern} realized - * @property {ChangeHalvedTotalPattern} supply + * @property {DeltaHalvedTotalPattern} supply * @property {SupplyPattern} unrealized */ @@ -2686,10 +2690,10 @@ function createActivityAddrOutputsRealizedSupplyUnrealizedPattern(client, acc) { return { activity: createSentPattern(client, _m(acc, 'sent')), addrCount: createMetricPattern1(client, _m(acc, 'addr_count')), - addrCountChange1m: createMetricPattern1(client, _m(acc, 'addr_count_change_1m')), + addrCountDelta: createChangeRatePattern(client, _m(acc, 'addr_count_delta')), outputs: createUtxoPattern(client, _m(acc, 'utxo_count')), realized: createMvrvRealizedPattern(client, acc), - supply: createChangeHalvedTotalPattern(client, _m(acc, 'supply')), + supply: createDeltaHalvedTotalPattern(client, _m(acc, 'supply')), unrealized: createSupplyPattern(client, _m(acc, 'supply_in')), }; } @@ -2700,7 +2704,7 @@ function createActivityAddrOutputsRealizedSupplyUnrealizedPattern(client, acc) { * @property {UtxoPattern} outputs * @property {MvrvNegNetRealizedSoprValuePattern} realized * @property {SupplyPattern2} relative - * @property {ChangeHalvedTotalPattern} supply + * @property {DeltaHalvedTotalPattern} supply * @property {NegNetSupplyUnrealizedPattern} unrealized */ @@ -2716,7 +2720,7 @@ function createActivityOutputsRealizedRelativeSupplyUnrealizedPattern(client, ac outputs: createUtxoPattern(client, _m(acc, 'utxo_count')), realized: createMvrvNegNetRealizedSoprValuePattern(client, acc), relative: createSupplyPattern2(client, _m(acc, 'supply')), - supply: createChangeHalvedTotalPattern(client, _m(acc, 'supply')), + supply: createDeltaHalvedTotalPattern(client, _m(acc, 'supply')), unrealized: createNegNetSupplyUnrealizedPattern(client, acc), }; } @@ -2753,7 +2757,7 @@ function createNegNetSupplyUnrealizedPattern(client, acc) { * @property {SentPattern} activity * @property {UtxoPattern} outputs * @property {MvrvRealizedPattern} realized - * @property {ChangeHalvedTotalPattern} supply + * @property {DeltaHalvedTotalPattern} supply * @property {SupplyPattern} unrealized */ @@ -2768,7 +2772,7 @@ function createActivityOutputsRealizedSupplyUnrealizedPattern(client, acc) { activity: createSentPattern(client, _m(acc, 'sent')), outputs: createUtxoPattern(client, _m(acc, 'utxo_count')), realized: createMvrvRealizedPattern(client, acc), - supply: createChangeHalvedTotalPattern(client, _m(acc, 'supply')), + supply: createDeltaHalvedTotalPattern(client, _m(acc, 'supply')), unrealized: createSupplyPattern(client, _m(acc, 'supply_in')), }; } @@ -2850,6 +2854,33 @@ function create_1m1w1y24hHeightPattern(client, acc) { }; } +/** + * @template T + * @typedef {Object} _24hChangeRatePattern + * @property {BaseBpsPercentRatioPattern} _24h + * @property {MetricPattern1} change1w + * @property {MetricPattern1} change1y + * @property {BpsPercentRatioPattern} rate1w + * @property {BpsPercentRatioPattern} rate1y + */ + +/** + * Create a _24hChangeRatePattern pattern node + * @template T + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {_24hChangeRatePattern} + */ +function create_24hChangeRatePattern(client, acc) { + return { + _24h: createBaseBpsPercentRatioPattern(client, acc), + change1w: createMetricPattern1(client, _m(acc, 'change_1w')), + change1y: createMetricPattern1(client, _m(acc, 'change_1y')), + rate1w: createBpsPercentRatioPattern(client, _m(acc, 'rate_1w')), + rate1y: createBpsPercentRatioPattern(client, _m(acc, 'rate_1y')), + }; +} + /** * @typedef {Object} _1m1w1y24hPattern6 * @property {BaseBtcCentsSatsUsdPattern} _1m @@ -2919,6 +2950,29 @@ function create_1m1w1y24hPattern5(client, acc) { }; } +/** + * @typedef {Object} BaseBpsPercentRatioPattern + * @property {MetricPattern1} base + * @property {MetricPattern1} bps + * @property {MetricPattern1} percent + * @property {MetricPattern1} ratio + */ + +/** + * Create a BaseBpsPercentRatioPattern pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {BaseBpsPercentRatioPattern} + */ +function createBaseBpsPercentRatioPattern(client, acc) { + return { + base: createMetricPattern1(client, _m(acc, 'change_24h')), + bps: createMetricPattern1(client, _m(acc, 'rate_24h_bps')), + percent: createMetricPattern1(client, _m(acc, 'rate_24h')), + ratio: createMetricPattern1(client, _m(acc, 'rate_24h_ratio')), + }; +} + /** * @typedef {Object} BothReactivatedReceivingSendingPattern * @property {_1m1w1y24hHeightPattern} both @@ -3165,21 +3219,21 @@ function createCentsSatsUsdPattern(client, acc) { } /** - * @typedef {Object} ChangeHalvedTotalPattern - * @property {BtcCentsSatsUsdPattern} change1m + * @typedef {Object} DeltaHalvedTotalPattern + * @property {ChangeRatePattern} delta * @property {BtcCentsSatsUsdPattern} halved * @property {BtcCentsSatsUsdPattern} total */ /** - * Create a ChangeHalvedTotalPattern pattern node + * Create a DeltaHalvedTotalPattern pattern node * @param {BrkClientBase} client * @param {string} acc - Accumulated metric name - * @returns {ChangeHalvedTotalPattern} + * @returns {DeltaHalvedTotalPattern} */ -function createChangeHalvedTotalPattern(client, acc) { +function createDeltaHalvedTotalPattern(client, acc) { return { - change1m: createBtcCentsSatsUsdPattern(client, _m(acc, 'change_1m')), + delta: createChangeRatePattern(client, _m(acc, 'delta')), halved: createBtcCentsSatsUsdPattern(client, _m(acc, 'halved')), total: createBtcCentsSatsUsdPattern(client, acc), }; @@ -3352,18 +3406,18 @@ function createCentsUsdPattern(client, acc) { } /** - * @typedef {Object} ChangeRatePattern + * @typedef {Object} ChangeRatePattern2 * @property {_1m1w1y24hPattern} change * @property {_1m1w1y24hPattern2} rate */ /** - * Create a ChangeRatePattern pattern node + * Create a ChangeRatePattern2 pattern node * @param {BrkClientBase} client * @param {string} acc - Accumulated metric name - * @returns {ChangeRatePattern} + * @returns {ChangeRatePattern2} */ -function createChangeRatePattern(client, acc) { +function createChangeRatePattern2(client, acc) { return { change: create_1m1w1y24hPattern(client, _m(acc, 'change')), rate: create_1m1w1y24hPattern2(client, _m(acc, 'rate')), @@ -3449,7 +3503,7 @@ function createSupplyPattern(client, acc) { /** * @typedef {Object} UtxoPattern * @property {MetricPattern1} utxoCount - * @property {MetricPattern1} utxoCountChange1m + * @property {ChangeRatePattern} utxoCountDelta */ /** @@ -3461,7 +3515,28 @@ function createSupplyPattern(client, acc) { function createUtxoPattern(client, acc) { return { utxoCount: createMetricPattern1(client, acc), - utxoCountChange1m: createMetricPattern1(client, _m(acc, 'change_1m')), + utxoCountDelta: createChangeRatePattern(client, _m(acc, 'delta')), + }; +} + +/** + * @template T + * @typedef {Object} ChangeRatePattern + * @property {MetricPattern1} change1m + * @property {BpsPercentRatioPattern} rate1m + */ + +/** + * Create a ChangeRatePattern pattern node + * @template T + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {ChangeRatePattern} + */ +function createChangeRatePattern(client, acc) { + return { + change1m: createMetricPattern1(client, _m(acc, 'change_1m')), + rate1m: createBpsPercentRatioPattern(client, _m(acc, 'rate_1m')), }; } @@ -4773,7 +4848,7 @@ function create_24hPattern(client, acc) { /** * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_All - * @property {ChangeHalvedTotalPattern} supply + * @property {DeltaHalvedTotalPattern} supply * @property {UtxoPattern} outputs * @property {CoinblocksCoindaysSentPattern2} activity * @property {CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern} realized @@ -4783,6 +4858,8 @@ function create_24hPattern(client, acc) { * @property {MetricsTree_Distribution_UtxoCohorts_All_Relative} relative * @property {MetricPattern1} dormancy * @property {MetricPattern1} velocity + * @property {_24hChangeRatePattern} supplyDeltaExtended + * @property {_24hChangeRatePattern} utxoCountDeltaExtended */ /** @@ -4809,7 +4886,7 @@ function create_24hPattern(client, acc) { /** * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Sth - * @property {ChangeHalvedTotalPattern} supply + * @property {DeltaHalvedTotalPattern} supply * @property {UtxoPattern} outputs * @property {CoinblocksCoindaysSentPattern2} activity * @property {CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern} realized @@ -4818,6 +4895,8 @@ function create_24hPattern(client, acc) { * @property {NetNuplSupplyUnrealizedPattern2} relative * @property {MetricPattern1} dormancy * @property {MetricPattern1} velocity + * @property {_24hChangeRatePattern} supplyDeltaExtended + * @property {_24hChangeRatePattern} utxoCountDeltaExtended * @property {MetricPattern1} adjustedValueCreated * @property {MetricPattern1} adjustedValueDestroyed * @property {_1m1w1y24hPattern} adjustedValueCreatedSum @@ -4827,7 +4906,7 @@ function create_24hPattern(client, acc) { /** * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Lth - * @property {ChangeHalvedTotalPattern} supply + * @property {DeltaHalvedTotalPattern} supply * @property {UtxoPattern} outputs * @property {CoinblocksCoindaysSentPattern2} activity * @property {CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern} realized @@ -4836,6 +4915,8 @@ function create_24hPattern(client, acc) { * @property {NetNuplSupplyUnrealizedPattern2} relative * @property {MetricPattern1} dormancy * @property {MetricPattern1} velocity + * @property {_24hChangeRatePattern} supplyDeltaExtended + * @property {_24hChangeRatePattern} utxoCountDeltaExtended */ /** @@ -5094,15 +5175,15 @@ function create_24hPattern(client, acc) { /** * @typedef {Object} MetricsTree_Distribution_Delta - * @property {ChangeRatePattern} all - * @property {ChangeRatePattern} p2pk65 - * @property {ChangeRatePattern} p2pk33 - * @property {ChangeRatePattern} p2pkh - * @property {ChangeRatePattern} p2sh - * @property {ChangeRatePattern} p2wpkh - * @property {ChangeRatePattern} p2wsh - * @property {ChangeRatePattern} p2tr - * @property {ChangeRatePattern} p2a + * @property {ChangeRatePattern2} all + * @property {ChangeRatePattern2} p2pk65 + * @property {ChangeRatePattern2} p2pk33 + * @property {ChangeRatePattern2} p2pkh + * @property {ChangeRatePattern2} p2sh + * @property {ChangeRatePattern2} p2wpkh + * @property {ChangeRatePattern2} p2wsh + * @property {ChangeRatePattern2} p2tr + * @property {ChangeRatePattern2} p2a */ /** @@ -5112,9 +5193,9 @@ function create_24hPattern(client, acc) { * @property {BpsPercentRatioPattern} inflationRate * @property {MetricsTree_Supply_Velocity} velocity * @property {MetricPattern1} marketCap - * @property {BpsPercentRatioPattern} marketCapGrowthRate - * @property {BpsPercentRatioPattern} realizedCapGrowthRate - * @property {MetricPattern1} marketMinusRealizedCapGrowthRate + * @property {_1m1w1y24hPattern2} marketCapGrowthRate + * @property {_1m1w1y24hPattern2} realizedCapGrowthRate + * @property {_1m1w1y24hPattern} marketMinusRealizedCapGrowthRate */ /** @@ -6991,7 +7072,7 @@ class BrkClient extends BrkClientBase { }, utxoCohorts: { all: { - supply: createChangeHalvedTotalPattern(this, 'supply'), + supply: createDeltaHalvedTotalPattern(this, 'supply'), outputs: createUtxoPattern(this, 'utxo_count'), activity: createCoinblocksCoindaysSentPattern2(this, ''), realized: createCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(this, ''), @@ -7017,9 +7098,11 @@ class BrkClient extends BrkClientBase { }, dormancy: createMetricPattern1(this, 'dormancy'), velocity: createMetricPattern1(this, 'velocity'), + supplyDeltaExtended: create_24hChangeRatePattern(this, 'supply_delta'), + utxoCountDeltaExtended: create_24hChangeRatePattern(this, 'utxo_count_delta'), }, sth: { - supply: createChangeHalvedTotalPattern(this, 'sth_supply'), + supply: createDeltaHalvedTotalPattern(this, 'sth_supply'), outputs: createUtxoPattern(this, 'sth_utxo_count'), activity: createCoinblocksCoindaysSentPattern2(this, 'sth'), realized: createCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(this, 'sth'), @@ -7028,6 +7111,8 @@ class BrkClient extends BrkClientBase { relative: createNetNuplSupplyUnrealizedPattern2(this, 'sth'), dormancy: createMetricPattern1(this, 'sth_dormancy'), velocity: createMetricPattern1(this, 'sth_velocity'), + supplyDeltaExtended: create_24hChangeRatePattern(this, 'sth_supply_delta'), + utxoCountDeltaExtended: create_24hChangeRatePattern(this, 'sth_utxo_count_delta'), adjustedValueCreated: createMetricPattern1(this, 'sth_adjusted_value_created'), adjustedValueDestroyed: createMetricPattern1(this, 'sth_adjusted_value_destroyed'), adjustedValueCreatedSum: create_1m1w1y24hPattern(this, 'sth_adjusted_value_created'), @@ -7035,7 +7120,7 @@ class BrkClient extends BrkClientBase { adjustedSopr: create_1m1w1y24hPattern(this, 'sth_adjusted_sopr'), }, lth: { - supply: createChangeHalvedTotalPattern(this, 'lth_supply'), + supply: createDeltaHalvedTotalPattern(this, 'lth_supply'), outputs: createUtxoPattern(this, 'lth_utxo_count'), activity: createCoinblocksCoindaysSentPattern2(this, 'lth'), realized: createCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(this, 'lth'), @@ -7044,6 +7129,8 @@ class BrkClient extends BrkClientBase { relative: createNetNuplSupplyUnrealizedPattern2(this, 'lth'), dormancy: createMetricPattern1(this, 'lth_dormancy'), velocity: createMetricPattern1(this, 'lth_velocity'), + supplyDeltaExtended: create_24hChangeRatePattern(this, 'lth_supply_delta'), + utxoCountDeltaExtended: create_24hChangeRatePattern(this, 'lth_utxo_count_delta'), }, ageRange: { upTo1h: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern(this, 'utxos_under_1h_old'), @@ -7271,15 +7358,15 @@ class BrkClient extends BrkClientBase { p2a: createAverageCumulativeHeightMaxMedianMinPct10Pct25Pct75Pct90SumPattern(this, 'p2a_new_addr_count'), }, delta: { - all: createChangeRatePattern(this, 'addr_count'), - p2pk65: createChangeRatePattern(this, 'p2pk65_addr_count'), - p2pk33: createChangeRatePattern(this, 'p2pk33_addr_count'), - p2pkh: createChangeRatePattern(this, 'p2pkh_addr_count'), - p2sh: createChangeRatePattern(this, 'p2sh_addr_count'), - p2wpkh: createChangeRatePattern(this, 'p2wpkh_addr_count'), - p2wsh: createChangeRatePattern(this, 'p2wsh_addr_count'), - p2tr: createChangeRatePattern(this, 'p2tr_addr_count'), - p2a: createChangeRatePattern(this, 'p2a_addr_count'), + all: createChangeRatePattern2(this, 'addr_count'), + p2pk65: createChangeRatePattern2(this, 'p2pk65_addr_count'), + p2pk33: createChangeRatePattern2(this, 'p2pk33_addr_count'), + p2pkh: createChangeRatePattern2(this, 'p2pkh_addr_count'), + p2sh: createChangeRatePattern2(this, 'p2sh_addr_count'), + p2wpkh: createChangeRatePattern2(this, 'p2wpkh_addr_count'), + p2wsh: createChangeRatePattern2(this, 'p2wsh_addr_count'), + p2tr: createChangeRatePattern2(this, 'p2tr_addr_count'), + p2a: createChangeRatePattern2(this, 'p2a_addr_count'), }, fundedaddressindex: createMetricPattern34(this, 'fundedaddressindex'), emptyaddressindex: createMetricPattern35(this, 'emptyaddressindex'), @@ -7296,9 +7383,9 @@ class BrkClient extends BrkClientBase { usd: createMetricPattern1(this, 'velocity_usd'), }, marketCap: createMetricPattern1(this, 'market_cap'), - marketCapGrowthRate: createBpsPercentRatioPattern(this, 'market_cap_growth_rate'), - realizedCapGrowthRate: createBpsPercentRatioPattern(this, 'realized_cap_growth_rate'), - marketMinusRealizedCapGrowthRate: createMetricPattern1(this, 'market_minus_realized_cap_growth_rate'), + marketCapGrowthRate: create_1m1w1y24hPattern2(this, 'market_cap_growth_rate'), + realizedCapGrowthRate: create_1m1w1y24hPattern2(this, 'realized_cap_growth_rate'), + marketMinusRealizedCapGrowthRate: create_1m1w1y24hPattern(this, 'market_minus_realized_cap_growth_rate'), }, }; } diff --git a/packages/brk_client/brk_client/__init__.py b/packages/brk_client/brk_client/__init__.py index 8b3574d7c..20fae3ca0 100644 --- a/packages/brk_client/brk_client/__init__.py +++ b/packages/brk_client/brk_client/__init__.py @@ -2086,9 +2086,10 @@ class CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentS self.lower_price_band: CentsSatsUsdPattern = CentsSatsUsdPattern(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_pnl_change_1m: MetricPattern1[CentsSigned] = MetricPattern1(client, _m(acc, 'net_pnl_change_1m')) self.net_pnl_change_1m_rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'net_pnl_change_1m_rel_to_market_cap')) self.net_pnl_change_1m_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'net_pnl_change_1m_rel_to_realized_cap')) + self.net_pnl_delta: ChangeRatePattern[CentsSigned] = ChangeRatePattern(client, _m(acc, 'net_pnl_delta')) + self.net_pnl_delta_extended: _24hChangeRatePattern[CentsSigned] = _24hChangeRatePattern(client, _m(acc, 'net_pnl_delta')) self.net_realized_pnl: CumulativeHeightPattern[CentsSigned] = CumulativeHeightPattern(client, _m(acc, 'net_realized_pnl')) self.net_realized_pnl_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'net_realized_pnl_rel_to_realized_cap')) self.peak_regret: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, _m(acc, 'realized_peak_regret')) @@ -2100,7 +2101,8 @@ class CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentS self.profit_value_destroyed_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'profit_value_destroyed')) self.realized_cap: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_cap')) self.realized_cap_cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_cap_cents')) - self.realized_cap_change_1m: MetricPattern1[CentsSigned] = MetricPattern1(client, _m(acc, 'realized_cap_change_1m')) + self.realized_cap_delta: ChangeRatePattern[CentsSigned] = ChangeRatePattern(client, _m(acc, 'realized_cap_delta')) + self.realized_cap_delta_extended: _24hChangeRatePattern[CentsSigned] = _24hChangeRatePattern(client, _m(acc, 'realized_cap_delta')) self.realized_cap_rel_to_own_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'realized_cap_rel_to_own_market_cap')) self.realized_loss: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, _m(acc, 'realized_loss')) self.realized_loss_rel_to_realized_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'realized_loss_rel_to_realized_cap')) @@ -2176,7 +2178,7 @@ class MvrvNegNetRealizedSentSoprValuePattern: self.net_realized_pnl: CumulativeHeightPattern[CentsSigned] = CumulativeHeightPattern(client, _m(acc, 'net_realized_pnl')) self.realized_cap: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_cap')) self.realized_cap_cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_cap_cents')) - self.realized_cap_change_1m: MetricPattern1[CentsSigned] = MetricPattern1(client, _m(acc, 'realized_cap_change_1m')) + self.realized_cap_delta: ChangeRatePattern[CentsSigned] = ChangeRatePattern(client, _m(acc, 'realized_cap_delta')) self.realized_loss: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, _m(acc, 'realized_loss')) self.realized_loss_sum: _24hPattern[Cents] = _24hPattern(client, _m(acc, 'realized_loss_24h')) self.realized_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'realized_price')) @@ -2228,7 +2230,7 @@ class MvrvNegNetRealizedSoprValuePattern: self.net_realized_pnl: CumulativeHeightPattern[CentsSigned] = CumulativeHeightPattern(client, _m(acc, 'net_realized_pnl')) self.realized_cap: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'realized_cap')) self.realized_cap_cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'realized_cap_cents')) - self.realized_cap_change_1m: MetricPattern1[CentsSigned] = MetricPattern1(client, _m(acc, 'realized_cap_change_1m')) + self.realized_cap_delta: ChangeRatePattern[CentsSigned] = ChangeRatePattern(client, _m(acc, 'realized_cap_delta')) self.realized_loss: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, _m(acc, 'realized_loss')) self.realized_loss_sum: _24hPattern[Cents] = _24hPattern(client, _m(acc, 'realized_loss_24h')) self.realized_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'realized_price')) @@ -2570,7 +2572,7 @@ class ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern: self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count')) self.realized: MvrvNegNetRealizedSentSoprValuePattern = MvrvNegNetRealizedSentSoprValuePattern(client, acc) self.relative: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply')) - self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, _m(acc, 'supply')) + self.supply: DeltaHalvedTotalPattern = DeltaHalvedTotalPattern(client, _m(acc, 'supply')) self.unrealized: InvestedInvestorNegNetSupplyUnrealizedPattern = InvestedInvestorNegNetSupplyUnrealizedPattern(client, acc) class ActivityAddrOutputsRealizedSupplyUnrealizedPattern: @@ -2580,10 +2582,10 @@ class ActivityAddrOutputsRealizedSupplyUnrealizedPattern: """Create pattern node with accumulated metric name.""" self.activity: SentPattern = SentPattern(client, _m(acc, 'sent')) self.addr_count: MetricPattern1[StoredU64] = MetricPattern1(client, _m(acc, 'addr_count')) - self.addr_count_change_1m: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'addr_count_change_1m')) + self.addr_count_delta: ChangeRatePattern[StoredI64] = ChangeRatePattern(client, _m(acc, 'addr_count_delta')) self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count')) self.realized: MvrvRealizedPattern = MvrvRealizedPattern(client, acc) - self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, _m(acc, 'supply')) + self.supply: DeltaHalvedTotalPattern = DeltaHalvedTotalPattern(client, _m(acc, 'supply')) self.unrealized: SupplyPattern = SupplyPattern(client, _m(acc, 'supply_in')) class ActivityOutputsRealizedRelativeSupplyUnrealizedPattern: @@ -2595,7 +2597,7 @@ class ActivityOutputsRealizedRelativeSupplyUnrealizedPattern: self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count')) self.realized: MvrvNegNetRealizedSoprValuePattern = MvrvNegNetRealizedSoprValuePattern(client, acc) self.relative: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply')) - self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, _m(acc, 'supply')) + self.supply: DeltaHalvedTotalPattern = DeltaHalvedTotalPattern(client, _m(acc, 'supply')) self.unrealized: NegNetSupplyUnrealizedPattern = NegNetSupplyUnrealizedPattern(client, acc) class NegNetSupplyUnrealizedPattern: @@ -2618,7 +2620,7 @@ class ActivityOutputsRealizedSupplyUnrealizedPattern: self.activity: SentPattern = SentPattern(client, _m(acc, 'sent')) self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count')) self.realized: MvrvRealizedPattern = MvrvRealizedPattern(client, acc) - self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, _m(acc, 'supply')) + self.supply: DeltaHalvedTotalPattern = DeltaHalvedTotalPattern(client, _m(acc, 'supply')) self.unrealized: SupplyPattern = SupplyPattern(client, _m(acc, 'supply_in')) class BaseBtcCentsSatsUsdPattern: @@ -2654,6 +2656,17 @@ class _1m1w1y24hHeightPattern(Generic[T]): self._24h: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'average_24h')) self.height: MetricPattern18[T] = MetricPattern18(client, acc) +class _24hChangeRatePattern(Generic[T]): + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self._24h: BaseBpsPercentRatioPattern = BaseBpsPercentRatioPattern(client, acc) + self.change_1w: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'change_1w')) + self.change_1y: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'change_1y')) + self.rate_1w: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rate_1w')) + self.rate_1y: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rate_1y')) + class _1m1w1y24hPattern6: """Pattern struct for repeated tree structure.""" @@ -2684,6 +2697,16 @@ class _1m1w1y24hPattern5: self._1y: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, '1y')) self._24h: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, '24h')) +class BaseBpsPercentRatioPattern: + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self.base: MetricPattern1[CentsSigned] = MetricPattern1(client, _m(acc, 'change_24h')) + self.bps: MetricPattern1[BasisPointsSigned32] = MetricPattern1(client, _m(acc, 'rate_24h_bps')) + self.percent: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'rate_24h')) + self.ratio: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'rate_24h_ratio')) + class BothReactivatedReceivingSendingPattern: """Pattern struct for repeated tree structure.""" @@ -2789,12 +2812,12 @@ class CentsSatsUsdPattern: self.sats: MetricPattern1[SatsFract] = MetricPattern1(client, _m(acc, 'sats')) self.usd: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd')) -class ChangeHalvedTotalPattern: +class DeltaHalvedTotalPattern: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" - self.change_1m: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'change_1m')) + self.delta: ChangeRatePattern[SatsSigned] = ChangeRatePattern(client, _m(acc, 'delta')) self.halved: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'halved')) self.total: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, acc) @@ -2866,7 +2889,7 @@ class CentsUsdPattern: self.cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'cents')) self.usd: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd')) -class ChangeRatePattern: +class ChangeRatePattern2: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): @@ -2912,7 +2935,15 @@ class UtxoPattern: def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" self.utxo_count: MetricPattern1[StoredU64] = MetricPattern1(client, acc) - self.utxo_count_change_1m: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'change_1m')) + self.utxo_count_delta: ChangeRatePattern[StoredI64] = ChangeRatePattern(client, _m(acc, 'delta')) + +class ChangeRatePattern(Generic[T]): + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self.change_1m: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'change_1m')) + self.rate_1m: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rate_1m')) class CumulativeHeightPattern(Generic[T]): """Pattern struct for repeated tree structure.""" @@ -4275,7 +4306,7 @@ class MetricsTree_Distribution_UtxoCohorts_All: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'supply') + self.supply: DeltaHalvedTotalPattern = DeltaHalvedTotalPattern(client, 'supply') self.outputs: UtxoPattern = UtxoPattern(client, 'utxo_count') self.activity: CoinblocksCoindaysSentPattern2 = CoinblocksCoindaysSentPattern2(client, '') self.realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, '') @@ -4285,12 +4316,14 @@ class MetricsTree_Distribution_UtxoCohorts_All: self.relative: MetricsTree_Distribution_UtxoCohorts_All_Relative = MetricsTree_Distribution_UtxoCohorts_All_Relative(client) self.dormancy: MetricPattern1[StoredF32] = MetricPattern1(client, 'dormancy') self.velocity: MetricPattern1[StoredF32] = MetricPattern1(client, 'velocity') + self.supply_delta_extended: _24hChangeRatePattern[SatsSigned] = _24hChangeRatePattern(client, 'supply_delta') + self.utxo_count_delta_extended: _24hChangeRatePattern[StoredI64] = _24hChangeRatePattern(client, 'utxo_count_delta') class MetricsTree_Distribution_UtxoCohorts_Sth: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'sth_supply') + self.supply: DeltaHalvedTotalPattern = DeltaHalvedTotalPattern(client, 'sth_supply') self.outputs: UtxoPattern = UtxoPattern(client, 'sth_utxo_count') self.activity: CoinblocksCoindaysSentPattern2 = CoinblocksCoindaysSentPattern2(client, 'sth') self.realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, 'sth') @@ -4299,6 +4332,8 @@ class MetricsTree_Distribution_UtxoCohorts_Sth: self.relative: NetNuplSupplyUnrealizedPattern2 = NetNuplSupplyUnrealizedPattern2(client, 'sth') self.dormancy: MetricPattern1[StoredF32] = MetricPattern1(client, 'sth_dormancy') self.velocity: MetricPattern1[StoredF32] = MetricPattern1(client, 'sth_velocity') + self.supply_delta_extended: _24hChangeRatePattern[SatsSigned] = _24hChangeRatePattern(client, 'sth_supply_delta') + self.utxo_count_delta_extended: _24hChangeRatePattern[StoredI64] = _24hChangeRatePattern(client, 'sth_utxo_count_delta') self.adjusted_value_created: MetricPattern1[Cents] = MetricPattern1(client, 'sth_adjusted_value_created') self.adjusted_value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, 'sth_adjusted_value_destroyed') self.adjusted_value_created_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, 'sth_adjusted_value_created') @@ -4309,7 +4344,7 @@ class MetricsTree_Distribution_UtxoCohorts_Lth: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'lth_supply') + self.supply: DeltaHalvedTotalPattern = DeltaHalvedTotalPattern(client, 'lth_supply') self.outputs: UtxoPattern = UtxoPattern(client, 'lth_utxo_count') self.activity: CoinblocksCoindaysSentPattern2 = CoinblocksCoindaysSentPattern2(client, 'lth') self.realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, 'lth') @@ -4318,6 +4353,8 @@ class MetricsTree_Distribution_UtxoCohorts_Lth: self.relative: NetNuplSupplyUnrealizedPattern2 = NetNuplSupplyUnrealizedPattern2(client, 'lth') self.dormancy: MetricPattern1[StoredF32] = MetricPattern1(client, 'lth_dormancy') self.velocity: MetricPattern1[StoredF32] = MetricPattern1(client, 'lth_velocity') + self.supply_delta_extended: _24hChangeRatePattern[SatsSigned] = _24hChangeRatePattern(client, 'lth_supply_delta') + self.utxo_count_delta_extended: _24hChangeRatePattern[StoredI64] = _24hChangeRatePattern(client, 'lth_utxo_count_delta') class MetricsTree_Distribution_UtxoCohorts_AgeRange: """Metrics tree node.""" @@ -4609,15 +4646,15 @@ class MetricsTree_Distribution_Delta: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.all: ChangeRatePattern = ChangeRatePattern(client, 'addr_count') - self.p2pk65: ChangeRatePattern = ChangeRatePattern(client, 'p2pk65_addr_count') - self.p2pk33: ChangeRatePattern = ChangeRatePattern(client, 'p2pk33_addr_count') - self.p2pkh: ChangeRatePattern = ChangeRatePattern(client, 'p2pkh_addr_count') - self.p2sh: ChangeRatePattern = ChangeRatePattern(client, 'p2sh_addr_count') - self.p2wpkh: ChangeRatePattern = ChangeRatePattern(client, 'p2wpkh_addr_count') - self.p2wsh: ChangeRatePattern = ChangeRatePattern(client, 'p2wsh_addr_count') - self.p2tr: ChangeRatePattern = ChangeRatePattern(client, 'p2tr_addr_count') - self.p2a: ChangeRatePattern = ChangeRatePattern(client, 'p2a_addr_count') + self.all: ChangeRatePattern2 = ChangeRatePattern2(client, 'addr_count') + self.p2pk65: ChangeRatePattern2 = ChangeRatePattern2(client, 'p2pk65_addr_count') + self.p2pk33: ChangeRatePattern2 = ChangeRatePattern2(client, 'p2pk33_addr_count') + self.p2pkh: ChangeRatePattern2 = ChangeRatePattern2(client, 'p2pkh_addr_count') + self.p2sh: ChangeRatePattern2 = ChangeRatePattern2(client, 'p2sh_addr_count') + self.p2wpkh: ChangeRatePattern2 = ChangeRatePattern2(client, 'p2wpkh_addr_count') + self.p2wsh: ChangeRatePattern2 = ChangeRatePattern2(client, 'p2wsh_addr_count') + self.p2tr: ChangeRatePattern2 = ChangeRatePattern2(client, 'p2tr_addr_count') + self.p2a: ChangeRatePattern2 = ChangeRatePattern2(client, 'p2a_addr_count') class MetricsTree_Distribution: """Metrics tree node.""" @@ -4660,9 +4697,9 @@ class MetricsTree_Supply: self.inflation_rate: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'inflation_rate') self.velocity: MetricsTree_Supply_Velocity = MetricsTree_Supply_Velocity(client) self.market_cap: MetricPattern1[Dollars] = MetricPattern1(client, 'market_cap') - self.market_cap_growth_rate: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'market_cap_growth_rate') - self.realized_cap_growth_rate: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'realized_cap_growth_rate') - self.market_minus_realized_cap_growth_rate: MetricPattern1[BasisPointsSigned32] = MetricPattern1(client, 'market_minus_realized_cap_growth_rate') + self.market_cap_growth_rate: _1m1w1y24hPattern2 = _1m1w1y24hPattern2(client, 'market_cap_growth_rate') + self.realized_cap_growth_rate: _1m1w1y24hPattern2 = _1m1w1y24hPattern2(client, 'realized_cap_growth_rate') + self.market_minus_realized_cap_growth_rate: _1m1w1y24hPattern[BasisPointsSigned32] = _1m1w1y24hPattern(client, 'market_minus_realized_cap_growth_rate') class MetricsTree: """Metrics tree node."""