diff --git a/Cargo.lock b/Cargo.lock index 020d22a8b..0cc2c0555 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -529,6 +529,8 @@ dependencies = [ "rayon", "rlimit", "rustc-hash", + "schemars", + "serde", "tracing", "vecdb", ] @@ -594,7 +596,9 @@ dependencies = [ "brk_types", "derive_more", "jiff", + "parking_lot", "quickmatch", + "serde_json", "tokio", "vecdb", ] diff --git a/crates/brk_client/src/lib.rs b/crates/brk_client/src/lib.rs index 2fd0ed428..c18191f30 100644 --- a/crates/brk_client/src/lib.rs +++ b/crates/brk_client/src/lib.rs @@ -1390,7 +1390,7 @@ pub struct CapLossMvrvNetNuplPriceProfitSoprPattern { pub cap: CentsDeltaUsdPattern, pub loss: CumulativeNegativeRawSumPattern, pub mvrv: MetricPattern1, - pub net_pnl: RawSumPattern2, + pub net_pnl: RawSumPattern3, pub nupl: BpsRatioPattern, pub price: BpsCentsRatioSatsUsdPattern, pub profit: CumulativeRawSumPattern2, @@ -1404,7 +1404,7 @@ impl CapLossMvrvNetNuplPriceProfitSoprPattern { cap: CentsDeltaUsdPattern::new(client.clone(), _m(&acc, "realized_cap")), loss: CumulativeNegativeRawSumPattern::new(client.clone(), acc.clone()), mvrv: MetricPattern1::new(client.clone(), _m(&acc, "mvrv")), - net_pnl: RawSumPattern2::new(client.clone(), _m(&acc, "net_realized_pnl")), + net_pnl: RawSumPattern3::new(client.clone(), _m(&acc, "net_realized_pnl")), nupl: BpsRatioPattern::new(client.clone(), _m(&acc, "nupl_ratio")), price: BpsCentsRatioSatsUsdPattern::new(client.clone(), _m(&acc, "realized_price")), profit: CumulativeRawSumPattern2::new(client.clone(), _m(&acc, "realized_profit")), @@ -1524,11 +1524,11 @@ impl _1m1w1y24hBpsPercentRatioPattern { /// Pattern struct for repeated tree structure. pub struct CapLossMvrvNuplPriceProfitSoprPattern { pub cap: CentsUsdPattern, - pub loss: RawSumPattern, + pub loss: RawSumPattern2, pub mvrv: MetricPattern1, pub nupl: BpsRatioPattern, pub price: BpsCentsRatioSatsUsdPattern, - pub profit: RawSumPattern, + pub profit: RawSumPattern2, pub sopr: ValuePattern, } @@ -1537,11 +1537,11 @@ impl CapLossMvrvNuplPriceProfitSoprPattern { pub fn new(client: Arc, acc: String) -> Self { Self { cap: CentsUsdPattern::new(client.clone(), _m(&acc, "realized_cap")), - loss: RawSumPattern::new(client.clone(), _m(&acc, "realized_loss")), + loss: RawSumPattern2::new(client.clone(), _m(&acc, "realized_loss")), mvrv: MetricPattern1::new(client.clone(), _m(&acc, "mvrv")), nupl: BpsRatioPattern::new(client.clone(), _m(&acc, "nupl_ratio")), price: BpsCentsRatioSatsUsdPattern::new(client.clone(), _m(&acc, "realized_price")), - profit: RawSumPattern::new(client.clone(), _m(&acc, "realized_profit")), + profit: RawSumPattern2::new(client.clone(), _m(&acc, "realized_profit")), sopr: ValuePattern::new(client.clone(), _m(&acc, "value")), } } @@ -1651,7 +1651,7 @@ impl BpsCentsPercentilesRatioSatsUsdPattern { pub struct BtcCentsRelSatsUsdPattern3 { pub btc: MetricPattern1, pub cents: MetricPattern1, - pub rel_to_circulating_supply: BpsPercentRatioPattern, + pub rel_to_circulating: BpsPercentRatioPattern, pub rel_to_own_supply: BpsPercentRatioPattern, pub sats: MetricPattern1, pub usd: MetricPattern1, @@ -1663,7 +1663,7 @@ impl BtcCentsRelSatsUsdPattern3 { Self { btc: MetricPattern1::new(client.clone(), acc.clone()), cents: MetricPattern1::new(client.clone(), _m(&acc, "cents")), - rel_to_circulating_supply: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rel_to_circulating_supply")), + rel_to_circulating: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rel_to_circulating_supply")), rel_to_own_supply: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rel_to_own_supply")), sats: MetricPattern1::new(client.clone(), _m(&acc, "sats")), usd: MetricPattern1::new(client.clone(), _m(&acc, "usd")), @@ -1695,37 +1695,13 @@ impl ChangeCumulativeDeltaRawRelSumPattern { } } -/// Pattern struct for repeated tree structure. -pub struct DeltaHalvedInRelTotalPattern { - pub delta: ChangeRatePattern, - pub halved: BtcCentsSatsUsdPattern, - pub in_loss: BtcCentsRelSatsUsdPattern, - pub in_profit: BtcCentsRelSatsUsdPattern, - pub rel_to_circulating_supply: BpsPercentRatioPattern, - pub total: BtcCentsSatsUsdPattern, -} - -impl DeltaHalvedInRelTotalPattern { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - delta: ChangeRatePattern::new(client.clone(), _m(&acc, "delta")), - halved: BtcCentsSatsUsdPattern::new(client.clone(), _m(&acc, "halved")), - in_loss: BtcCentsRelSatsUsdPattern::new(client.clone(), _m(&acc, "in_loss")), - in_profit: BtcCentsRelSatsUsdPattern::new(client.clone(), _m(&acc, "in_profit")), - rel_to_circulating_supply: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rel_to_circulating_supply")), - total: BtcCentsSatsUsdPattern::new(client.clone(), acc.clone()), - } - } -} - /// Pattern struct for repeated tree structure. pub struct DeltaHalvedInRelTotalPattern2 { - pub delta: ChangeRatePattern2, + pub delta: ChangeRatePattern, pub halved: BtcCentsSatsUsdPattern, pub in_loss: BtcCentsRelSatsUsdPattern3, pub in_profit: BtcCentsRelSatsUsdPattern3, - pub rel_to_circulating_supply: BpsPercentRatioPattern, + pub rel_to_circulating: BpsPercentRatioPattern, pub total: BtcCentsSatsUsdPattern, } @@ -1733,11 +1709,35 @@ impl DeltaHalvedInRelTotalPattern2 { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - delta: ChangeRatePattern2::new(client.clone(), _m(&acc, "delta")), + delta: ChangeRatePattern::new(client.clone(), _m(&acc, "delta")), halved: BtcCentsSatsUsdPattern::new(client.clone(), _m(&acc, "halved")), in_loss: BtcCentsRelSatsUsdPattern3::new(client.clone(), _m(&acc, "in_loss")), in_profit: BtcCentsRelSatsUsdPattern3::new(client.clone(), _m(&acc, "in_profit")), - rel_to_circulating_supply: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rel_to_circulating_supply")), + rel_to_circulating: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rel_to_circulating_supply")), + total: BtcCentsSatsUsdPattern::new(client.clone(), acc.clone()), + } + } +} + +/// Pattern struct for repeated tree structure. +pub struct DeltaHalvedInRelTotalPattern { + pub delta: ChangeRatePattern2, + pub halved: BtcCentsSatsUsdPattern, + pub in_loss: BtcCentsRelSatsUsdPattern, + pub in_profit: BtcCentsRelSatsUsdPattern, + pub rel_to_circulating: BpsPercentRatioPattern, + pub total: BtcCentsSatsUsdPattern, +} + +impl DeltaHalvedInRelTotalPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + delta: ChangeRatePattern2::new(client.clone(), _m(&acc, "delta")), + halved: BtcCentsSatsUsdPattern::new(client.clone(), _m(&acc, "halved")), + in_loss: BtcCentsRelSatsUsdPattern::new(client.clone(), _m(&acc, "in_loss")), + in_profit: BtcCentsRelSatsUsdPattern::new(client.clone(), _m(&acc, "in_profit")), + rel_to_circulating: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rel_to_circulating_supply")), total: BtcCentsSatsUsdPattern::new(client.clone(), acc.clone()), } } @@ -1748,7 +1748,7 @@ pub struct NegativeRawRelSumPattern2 { pub negative: MetricPattern1, pub raw: CentsUsdPattern, pub rel_to_market_cap: BpsPercentRatioPattern, - pub rel_to_own_gross_pnl: BpsPercentRatioPattern, + pub rel_to_own_gross: BpsPercentRatioPattern, pub rel_to_own_market_cap: BpsPercentRatioPattern, pub sum: _24hPattern, } @@ -1760,7 +1760,7 @@ impl NegativeRawRelSumPattern2 { negative: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss")), raw: CentsUsdPattern::new(client.clone(), _m(&acc, "unrealized_loss")), rel_to_market_cap: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_market_cap")), - rel_to_own_gross_pnl: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_own_gross_pnl")), + rel_to_own_gross: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_own_gross_pnl")), rel_to_own_market_cap: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_own_market_cap")), sum: _24hPattern::new(client.clone(), _m(&acc, "unrealized_loss_24h")), } @@ -1861,7 +1861,7 @@ impl BpsCentsRatioSatsUsdPattern { pub struct BtcCentsRelSatsUsdPattern { pub btc: MetricPattern1, pub cents: MetricPattern1, - pub rel_to_circulating_supply: BpsPercentRatioPattern, + pub rel_to_circulating: BpsPercentRatioPattern, pub sats: MetricPattern1, pub usd: MetricPattern1, } @@ -1872,7 +1872,7 @@ impl BtcCentsRelSatsUsdPattern { Self { btc: MetricPattern1::new(client.clone(), acc.clone()), cents: MetricPattern1::new(client.clone(), _m(&acc, "cents")), - rel_to_circulating_supply: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rel_to_circulating_supply")), + rel_to_circulating: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rel_to_circulating_supply")), sats: MetricPattern1::new(client.clone(), _m(&acc, "sats")), usd: MetricPattern1::new(client.clone(), _m(&acc, "usd")), } @@ -1973,7 +1973,7 @@ pub struct InvestedInvestorLossNetProfitPattern { pub investor_cap: InPattern, pub loss: NegativeRawSumPattern, pub net_pnl: CentsUsdPattern, - pub profit: RawSumPattern, + pub profit: RawSumPattern2, } impl InvestedInvestorLossNetProfitPattern { @@ -1984,7 +1984,7 @@ impl InvestedInvestorLossNetProfitPattern { investor_cap: InPattern::new(client.clone(), _m(&acc, "investor_cap_in")), loss: NegativeRawSumPattern::new(client.clone(), acc.clone()), net_pnl: CentsUsdPattern::new(client.clone(), _m(&acc, "net_unrealized_pnl")), - profit: RawSumPattern::new(client.clone(), _m(&acc, "unrealized_profit")), + profit: RawSumPattern2::new(client.clone(), _m(&acc, "unrealized_profit")), } } } @@ -2037,7 +2037,7 @@ impl PhsReboundThsPattern { pub struct RawRelSumPattern2 { pub raw: CentsUsdPattern, pub rel_to_market_cap: BpsPercentRatioPattern, - pub rel_to_own_gross_pnl: BpsPercentRatioPattern, + pub rel_to_own_gross: BpsPercentRatioPattern, pub rel_to_own_market_cap: BpsPercentRatioPattern, pub sum: _24hPattern, } @@ -2048,7 +2048,7 @@ impl RawRelSumPattern2 { Self { raw: CentsUsdPattern::new(client.clone(), acc.clone()), rel_to_market_cap: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rel_to_market_cap")), - rel_to_own_gross_pnl: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rel_to_own_gross_pnl")), + rel_to_own_gross: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rel_to_own_gross_pnl")), rel_to_own_market_cap: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rel_to_own_market_cap")), sum: _24hPattern::new(client.clone(), _m(&acc, "24h")), } @@ -2241,8 +2241,8 @@ impl AddrOutputsRealizedSupplyPattern { pub struct AdjustedRatioValuePattern { pub adjusted: RatioValuePattern2, pub ratio: _1m1w1y24hPattern, - pub value_created: RawSumPattern3, - pub value_destroyed: RawSumPattern3, + pub value_created: RawSumPattern, + pub value_destroyed: RawSumPattern, } impl AdjustedRatioValuePattern { @@ -2251,8 +2251,8 @@ impl AdjustedRatioValuePattern { Self { adjusted: RatioValuePattern2::new(client.clone(), _m(&acc, "adjusted")), ratio: _1m1w1y24hPattern::new(client.clone(), _m(&acc, "sopr")), - value_created: RawSumPattern3::new(client.clone(), _m(&acc, "value_created")), - value_destroyed: RawSumPattern3::new(client.clone(), _m(&acc, "value_destroyed")), + value_created: RawSumPattern::new(client.clone(), _m(&acc, "value_created")), + value_destroyed: RawSumPattern::new(client.clone(), _m(&acc, "value_destroyed")), } } } @@ -2299,7 +2299,7 @@ impl BtcCentsSatsUsdPattern { /// Pattern struct for repeated tree structure. pub struct CapLowerPriceUpperPattern { - pub cap: RawPattern, + pub cap: RawPattern2, pub lower_price_band: CentsSatsUsdPattern, pub price: BpsCentsPercentilesRatioSatsUsdPattern, pub upper_price_band: CentsSatsUsdPattern, @@ -2309,7 +2309,7 @@ impl CapLowerPriceUpperPattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - cap: RawPattern::new(client.clone(), _m(&acc, "investor_cap_raw")), + cap: RawPattern2::new(client.clone(), _m(&acc, "investor_cap_raw")), lower_price_band: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "lower_price_band")), price: BpsCentsPercentilesRatioSatsUsdPattern::new(client.clone(), _m(&acc, "investor_price")), upper_price_band: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "upper_price_band")), @@ -2320,7 +2320,7 @@ impl CapLowerPriceUpperPattern { /// Pattern struct for repeated tree structure. pub struct CentsRelUsdPattern2 { pub cents: MetricPattern1, - pub rel_to_own_gross_pnl: BpsPercentRatioPattern, + pub rel_to_own_gross: BpsPercentRatioPattern, pub rel_to_own_market_cap: BpsPercentRatioPattern, pub usd: MetricPattern1, } @@ -2330,7 +2330,7 @@ impl CentsRelUsdPattern2 { pub fn new(client: Arc, acc: String) -> Self { Self { cents: MetricPattern1::new(client.clone(), _m(&acc, "cents")), - rel_to_own_gross_pnl: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rel_to_own_gross_pnl")), + rel_to_own_gross: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rel_to_own_gross_pnl")), rel_to_own_market_cap: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rel_to_own_market_cap")), usd: MetricPattern1::new(client.clone(), acc.clone()), } @@ -2659,7 +2659,7 @@ impl GreedNetPainPattern { pub struct LossNetProfitPattern { pub loss: NegativeRawSumPattern, pub net_pnl: CentsUsdPattern, - pub profit: RawSumPattern, + pub profit: RawSumPattern2, } impl LossNetProfitPattern { @@ -2668,7 +2668,7 @@ impl LossNetProfitPattern { Self { loss: NegativeRawSumPattern::new(client.clone(), acc.clone()), net_pnl: CentsUsdPattern::new(client.clone(), _m(&acc, "net_unrealized_pnl")), - profit: RawSumPattern::new(client.clone(), _m(&acc, "unrealized_profit")), + profit: RawSumPattern2::new(client.clone(), _m(&acc, "unrealized_profit")), } } } @@ -2730,8 +2730,8 @@ impl RatioValuePattern2 { /// Pattern struct for repeated tree structure. pub struct RatioValuePattern { pub ratio: _24hPattern2, - pub value_created: RawSumPattern2, - pub value_destroyed: RawSumPattern2, + pub value_created: RawSumPattern3, + pub value_destroyed: RawSumPattern3, } impl RatioValuePattern { @@ -2739,8 +2739,8 @@ impl RatioValuePattern { pub fn new(client: Arc, acc: String) -> Self { Self { ratio: _24hPattern2::new(client.clone(), _m(&acc, "sopr_24h")), - value_created: RawSumPattern2::new(client.clone(), _m(&acc, "value_created")), - value_destroyed: RawSumPattern2::new(client.clone(), _m(&acc, "value_destroyed")), + value_created: RawSumPattern3::new(client.clone(), _m(&acc, "value_created")), + value_destroyed: RawSumPattern3::new(client.clone(), _m(&acc, "value_destroyed")), } } } @@ -2799,22 +2799,6 @@ impl CumulativeRawSumPattern { } } -/// Pattern struct for repeated tree structure. -pub struct BaseCumulativePattern { - pub base: BtcCentsSatsUsdPattern, - pub cumulative: BtcCentsSatsUsdPattern, -} - -impl BaseCumulativePattern { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - base: BtcCentsSatsUsdPattern::new(client.clone(), acc.clone()), - cumulative: BtcCentsSatsUsdPattern::new(client.clone(), _m(&acc, "cumulative")), - } - } -} - /// Pattern struct for repeated tree structure. pub struct BaseSumPattern { pub base: MetricPattern1, @@ -2832,12 +2816,12 @@ impl BaseSumPattern { } /// Pattern struct for repeated tree structure. -pub struct BaseDeltaPattern { +pub struct BaseDeltaPattern2 { pub base: MetricPattern1, pub delta: ChangeRatePattern, } -impl BaseDeltaPattern { +impl BaseDeltaPattern2 { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { @@ -2848,12 +2832,12 @@ impl BaseDeltaPattern { } /// Pattern struct for repeated tree structure. -pub struct BaseDeltaPattern2 { +pub struct BaseDeltaPattern { pub base: MetricPattern1, pub delta: ChangeRatePattern2, } -impl BaseDeltaPattern2 { +impl BaseDeltaPattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { @@ -2912,12 +2896,12 @@ impl CentsUsdPattern { } /// Pattern struct for repeated tree structure. -pub struct ChangeRatePattern2 { +pub struct ChangeRatePattern { pub change: _1m1w1y24hPattern, pub rate: _1m1w1y24hPattern2, } -impl ChangeRatePattern2 { +impl ChangeRatePattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { @@ -2944,12 +2928,12 @@ impl ChangeRatePattern4 { } /// Pattern struct for repeated tree structure. -pub struct ChangeRatePattern { +pub struct ChangeRatePattern2 { pub change: _1mPattern, pub rate: _1mPattern2, } -impl ChangeRatePattern { +impl ChangeRatePattern2 { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { @@ -2977,7 +2961,7 @@ impl ChangeRatePattern3 { /// Pattern struct for repeated tree structure. pub struct CoindaysSentPattern { - pub coindays_destroyed: RawSumPattern2, + pub coindays_destroyed: RawSumPattern3, pub sent: InRawSumPattern, } @@ -2985,7 +2969,7 @@ impl CoindaysSentPattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - coindays_destroyed: RawSumPattern2::new(client.clone(), _m(&acc, "coindays_destroyed")), + coindays_destroyed: RawSumPattern3::new(client.clone(), _m(&acc, "coindays_destroyed")), sent: InRawSumPattern::new(client.clone(), _m(&acc, "sent")), } } @@ -3025,32 +3009,32 @@ impl InPattern2 { /// Pattern struct for repeated tree structure. pub struct InPattern { - pub in_loss: RawPattern, - pub in_profit: RawPattern, + pub in_loss: RawPattern2, + pub in_profit: RawPattern2, } impl InPattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - in_loss: RawPattern::new(client.clone(), _m(&acc, "loss_raw")), - in_profit: RawPattern::new(client.clone(), _m(&acc, "profit_raw")), + in_loss: RawPattern2::new(client.clone(), _m(&acc, "loss_raw")), + in_profit: RawPattern2::new(client.clone(), _m(&acc, "profit_raw")), } } } /// Pattern struct for repeated tree structure. pub struct LossProfitPattern2 { - pub loss: RawSumPattern, - pub profit: RawSumPattern, + pub loss: RawSumPattern2, + pub profit: RawSumPattern2, } impl LossProfitPattern2 { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - loss: RawSumPattern::new(client.clone(), _m(&acc, "loss")), - profit: RawSumPattern::new(client.clone(), _m(&acc, "profit")), + loss: RawSumPattern2::new(client.clone(), _m(&acc, "loss")), + profit: RawSumPattern2::new(client.clone(), _m(&acc, "profit")), } } } @@ -3104,12 +3088,12 @@ impl RawSumPattern4 { } /// Pattern struct for repeated tree structure. -pub struct RawSumPattern { +pub struct RawSumPattern2 { pub raw: CentsUsdPattern, pub sum: _24hPattern, } -impl RawSumPattern { +impl RawSumPattern2 { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { @@ -3169,16 +3153,16 @@ impl SdSmaPattern { /// Pattern struct for repeated tree structure. pub struct ValuePattern { - pub value_created: RawSumPattern2, - pub value_destroyed: RawSumPattern2, + pub value_created: RawSumPattern3, + pub value_destroyed: RawSumPattern3, } impl ValuePattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - value_created: RawSumPattern2::new(client.clone(), _m(&acc, "created")), - value_destroyed: RawSumPattern2::new(client.clone(), _m(&acc, "destroyed")), + value_created: RawSumPattern3::new(client.clone(), _m(&acc, "created")), + value_destroyed: RawSumPattern3::new(client.clone(), _m(&acc, "destroyed")), } } } @@ -3200,12 +3184,12 @@ impl CumulativeRawPattern { } /// Pattern struct for repeated tree structure. -pub struct RawSumPattern3 { +pub struct RawSumPattern { pub raw: MetricPattern1, pub sum: _1m1w1y24hPattern, } -impl RawSumPattern3 { +impl RawSumPattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { @@ -3216,12 +3200,12 @@ impl RawSumPattern3 { } /// Pattern struct for repeated tree structure. -pub struct RawSumPattern2 { +pub struct RawSumPattern3 { pub raw: MetricPattern1, pub sum: _24hPattern2, } -impl RawSumPattern2 { +impl RawSumPattern3 { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { @@ -3358,11 +3342,11 @@ impl _24hPattern2 { } /// Pattern struct for repeated tree structure. -pub struct RawPattern { +pub struct RawPattern2 { pub raw: MetricPattern18, } -impl RawPattern { +impl RawPattern2 { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { @@ -3457,8 +3441,8 @@ pub struct MetricsTree_Blocks_Difficulty { pub as_hash: MetricPattern1, pub adjustment: BpsPercentRatioPattern, pub epoch: MetricPattern1, - pub blocks_before_next_adjustment: MetricPattern1, - pub days_before_next_adjustment: MetricPattern1, + pub blocks_before_next: MetricPattern1, + pub days_before_next: MetricPattern1, } impl MetricsTree_Blocks_Difficulty { @@ -3468,8 +3452,8 @@ impl MetricsTree_Blocks_Difficulty { as_hash: MetricPattern1::new(client.clone(), "difficulty_as_hash".to_string()), adjustment: BpsPercentRatioPattern::new(client.clone(), "difficulty_adjustment".to_string()), epoch: MetricPattern1::new(client.clone(), "difficulty_epoch".to_string()), - blocks_before_next_adjustment: MetricPattern1::new(client.clone(), "blocks_before_next_difficulty_adjustment".to_string()), - days_before_next_adjustment: MetricPattern1::new(client.clone(), "days_before_next_difficulty_adjustment".to_string()), + blocks_before_next: MetricPattern1::new(client.clone(), "blocks_before_next_difficulty_adjustment".to_string()), + days_before_next: MetricPattern1::new(client.clone(), "days_before_next_difficulty_adjustment".to_string()), } } } @@ -3672,16 +3656,16 @@ impl MetricsTree_Blocks_Lookback { /// Metrics tree node. pub struct MetricsTree_Blocks_Halving { pub epoch: MetricPattern1, - pub blocks_before_next_halving: MetricPattern1, - pub days_before_next_halving: MetricPattern1, + pub blocks_before_next: MetricPattern1, + pub days_before_next: MetricPattern1, } impl MetricsTree_Blocks_Halving { pub fn new(client: Arc, base_path: String) -> Self { Self { epoch: MetricPattern1::new(client.clone(), "halving_epoch".to_string()), - blocks_before_next_halving: MetricPattern1::new(client.clone(), "blocks_before_next_halving".to_string()), - days_before_next_halving: MetricPattern1::new(client.clone(), "days_before_next_halving".to_string()), + blocks_before_next: MetricPattern1::new(client.clone(), "blocks_before_next_halving".to_string()), + days_before_next: MetricPattern1::new(client.clone(), "days_before_next_halving".to_string()), } } } @@ -3705,6 +3689,29 @@ impl MetricsTree_Blocks_Fullness { /// Metrics tree node. pub struct MetricsTree_Transactions { + pub raw: MetricsTree_Transactions_Raw, + pub count: MetricsTree_Transactions_Count, + pub size: MetricsTree_Transactions_Size, + pub fees: MetricsTree_Transactions_Fees, + pub versions: MetricsTree_Transactions_Versions, + pub volume: MetricsTree_Transactions_Volume, +} + +impl MetricsTree_Transactions { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + raw: MetricsTree_Transactions_Raw::new(client.clone(), format!("{base_path}_raw")), + count: MetricsTree_Transactions_Count::new(client.clone(), format!("{base_path}_count")), + size: MetricsTree_Transactions_Size::new(client.clone(), format!("{base_path}_size")), + fees: MetricsTree_Transactions_Fees::new(client.clone(), format!("{base_path}_fees")), + versions: MetricsTree_Transactions_Versions::new(client.clone(), format!("{base_path}_versions")), + volume: MetricsTree_Transactions_Volume::new(client.clone(), format!("{base_path}_volume")), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Transactions_Raw { pub first_txindex: MetricPattern18, pub height: MetricPattern19, pub txid: MetricPattern19, @@ -3715,14 +3722,9 @@ pub struct MetricsTree_Transactions { pub is_explicitly_rbf: MetricPattern19, pub first_txinindex: MetricPattern19, pub first_txoutindex: MetricPattern19, - pub count: MetricsTree_Transactions_Count, - pub size: MetricsTree_Transactions_Size, - pub fees: MetricsTree_Transactions_Fees, - pub versions: MetricsTree_Transactions_Versions, - pub volume: MetricsTree_Transactions_Volume, } -impl MetricsTree_Transactions { +impl MetricsTree_Transactions_Raw { pub fn new(client: Arc, base_path: String) -> Self { Self { first_txindex: MetricPattern18::new(client.clone(), "first_txindex".to_string()), @@ -3735,11 +3737,6 @@ impl MetricsTree_Transactions { is_explicitly_rbf: MetricPattern19::new(client.clone(), "is_explicitly_rbf".to_string()), first_txinindex: MetricPattern19::new(client.clone(), "first_txinindex".to_string()), first_txoutindex: MetricPattern19::new(client.clone(), "first_txoutindex".to_string()), - count: MetricsTree_Transactions_Count::new(client.clone(), format!("{base_path}_count")), - size: MetricsTree_Transactions_Size::new(client.clone(), format!("{base_path}_size")), - fees: MetricsTree_Transactions_Fees::new(client.clone(), format!("{base_path}_fees")), - versions: MetricsTree_Transactions_Versions::new(client.clone(), format!("{base_path}_versions")), - volume: MetricsTree_Transactions_Volume::new(client.clone(), format!("{base_path}_volume")), } } } @@ -3814,7 +3811,7 @@ impl MetricsTree_Transactions_Versions { pub struct MetricsTree_Transactions_Volume { pub sent_sum: _1m1w1y24hBtcCentsSatsUsdPattern, pub received_sum: _1m1w1y24hBtcCentsSatsUsdPattern, - pub annualized_volume: BtcCentsSatsUsdPattern, + pub annualized: BtcCentsSatsUsdPattern, pub tx_per_sec: MetricPattern1, pub outputs_per_sec: MetricPattern1, pub inputs_per_sec: MetricPattern1, @@ -3825,7 +3822,7 @@ impl MetricsTree_Transactions_Volume { Self { sent_sum: _1m1w1y24hBtcCentsSatsUsdPattern::new(client.clone(), "sent_sum".to_string()), received_sum: _1m1w1y24hBtcCentsSatsUsdPattern::new(client.clone(), "received_sum".to_string()), - annualized_volume: BtcCentsSatsUsdPattern::new(client.clone(), "annualized_volume".to_string()), + annualized: BtcCentsSatsUsdPattern::new(client.clone(), "annualized_volume".to_string()), tx_per_sec: MetricPattern1::new(client.clone(), "tx_per_sec".to_string()), outputs_per_sec: MetricPattern1::new(client.clone(), "outputs_per_sec".to_string()), inputs_per_sec: MetricPattern1::new(client.clone(), "inputs_per_sec".to_string()), @@ -3835,16 +3832,31 @@ impl MetricsTree_Transactions_Volume { /// Metrics tree node. pub struct MetricsTree_Inputs { - pub first_txinindex: MetricPattern18, - pub outpoint: MetricPattern20, - pub txindex: MetricPattern20, - pub outputtype: MetricPattern20, - pub typeindex: MetricPattern20, + pub raw: MetricsTree_Inputs_Raw, pub spent: MetricsTree_Inputs_Spent, pub count: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern, } impl MetricsTree_Inputs { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + raw: MetricsTree_Inputs_Raw::new(client.clone(), format!("{base_path}_raw")), + spent: MetricsTree_Inputs_Spent::new(client.clone(), format!("{base_path}_spent")), + count: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern::new(client.clone(), "input_count".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Inputs_Raw { + pub first_txinindex: MetricPattern18, + pub outpoint: MetricPattern20, + pub txindex: MetricPattern20, + pub outputtype: MetricPattern20, + pub typeindex: MetricPattern20, +} + +impl MetricsTree_Inputs_Raw { pub fn new(client: Arc, base_path: String) -> Self { Self { first_txinindex: MetricPattern18::new(client.clone(), "first_txinindex".to_string()), @@ -3852,8 +3864,6 @@ impl MetricsTree_Inputs { txindex: MetricPattern20::new(client.clone(), "txindex".to_string()), outputtype: MetricPattern20::new(client.clone(), "outputtype".to_string()), typeindex: MetricPattern20::new(client.clone(), "typeindex".to_string()), - spent: MetricsTree_Inputs_Spent::new(client.clone(), format!("{base_path}_spent")), - count: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern::new(client.clone(), "input_count".to_string()), } } } @@ -3875,16 +3885,31 @@ impl MetricsTree_Inputs_Spent { /// Metrics tree node. pub struct MetricsTree_Outputs { - pub first_txoutindex: MetricPattern18, - pub value: MetricPattern21, - pub outputtype: MetricPattern21, - pub typeindex: MetricPattern21, - pub txindex: MetricPattern21, + pub raw: MetricsTree_Outputs_Raw, pub spent: MetricsTree_Outputs_Spent, pub count: MetricsTree_Outputs_Count, } impl MetricsTree_Outputs { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + raw: MetricsTree_Outputs_Raw::new(client.clone(), format!("{base_path}_raw")), + spent: MetricsTree_Outputs_Spent::new(client.clone(), format!("{base_path}_spent")), + count: MetricsTree_Outputs_Count::new(client.clone(), format!("{base_path}_count")), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Outputs_Raw { + pub first_txoutindex: MetricPattern18, + pub value: MetricPattern21, + pub outputtype: MetricPattern21, + pub typeindex: MetricPattern21, + pub txindex: MetricPattern21, +} + +impl MetricsTree_Outputs_Raw { pub fn new(client: Arc, base_path: String) -> Self { Self { first_txoutindex: MetricPattern18::new(client.clone(), "first_txoutindex".to_string()), @@ -3892,8 +3917,6 @@ impl MetricsTree_Outputs { outputtype: MetricPattern21::new(client.clone(), "outputtype".to_string()), typeindex: MetricPattern21::new(client.clone(), "typeindex".to_string()), txindex: MetricPattern21::new(client.clone(), "txindex".to_string()), - spent: MetricsTree_Outputs_Spent::new(client.clone(), format!("{base_path}_spent")), - count: MetricsTree_Outputs_Count::new(client.clone(), format!("{base_path}_count")), } } } @@ -3914,71 +3937,181 @@ impl MetricsTree_Outputs_Spent { /// Metrics tree node. pub struct MetricsTree_Outputs_Count { pub total: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern, - pub utxo_count: MetricPattern1, + pub unspent: MetricPattern1, } impl MetricsTree_Outputs_Count { pub fn new(client: Arc, base_path: String) -> Self { Self { total: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern::new(client.clone(), "output_count".to_string()), - utxo_count: MetricPattern1::new(client.clone(), "exact_utxo_count".to_string()), + unspent: MetricPattern1::new(client.clone(), "exact_utxo_count".to_string()), } } } /// Metrics tree node. pub struct MetricsTree_Addresses { - pub first_p2pk65addressindex: MetricPattern18, - pub first_p2pk33addressindex: MetricPattern18, - pub first_p2pkhaddressindex: MetricPattern18, - pub first_p2shaddressindex: MetricPattern18, - pub first_p2wpkhaddressindex: MetricPattern18, - pub first_p2wshaddressindex: MetricPattern18, - pub first_p2traddressindex: MetricPattern18, - pub first_p2aaddressindex: MetricPattern18, - pub p2pk65bytes: MetricPattern27, - pub p2pk33bytes: MetricPattern26, - pub p2pkhbytes: MetricPattern28, - pub p2shbytes: MetricPattern29, - pub p2wpkhbytes: MetricPattern31, - pub p2wshbytes: MetricPattern32, - pub p2trbytes: MetricPattern30, - pub p2abytes: MetricPattern24, + pub raw: MetricsTree_Addresses_Raw, } impl MetricsTree_Addresses { pub fn new(client: Arc, base_path: String) -> Self { Self { - first_p2pk65addressindex: MetricPattern18::new(client.clone(), "first_p2pk65addressindex".to_string()), - first_p2pk33addressindex: MetricPattern18::new(client.clone(), "first_p2pk33addressindex".to_string()), - first_p2pkhaddressindex: MetricPattern18::new(client.clone(), "first_p2pkhaddressindex".to_string()), - first_p2shaddressindex: MetricPattern18::new(client.clone(), "first_p2shaddressindex".to_string()), - first_p2wpkhaddressindex: MetricPattern18::new(client.clone(), "first_p2wpkhaddressindex".to_string()), - first_p2wshaddressindex: MetricPattern18::new(client.clone(), "first_p2wshaddressindex".to_string()), - first_p2traddressindex: MetricPattern18::new(client.clone(), "first_p2traddressindex".to_string()), - first_p2aaddressindex: MetricPattern18::new(client.clone(), "first_p2aaddressindex".to_string()), - p2pk65bytes: MetricPattern27::new(client.clone(), "p2pk65bytes".to_string()), - p2pk33bytes: MetricPattern26::new(client.clone(), "p2pk33bytes".to_string()), - p2pkhbytes: MetricPattern28::new(client.clone(), "p2pkhbytes".to_string()), - p2shbytes: MetricPattern29::new(client.clone(), "p2shbytes".to_string()), - p2wpkhbytes: MetricPattern31::new(client.clone(), "p2wpkhbytes".to_string()), - p2wshbytes: MetricPattern32::new(client.clone(), "p2wshbytes".to_string()), - p2trbytes: MetricPattern30::new(client.clone(), "p2trbytes".to_string()), - p2abytes: MetricPattern24::new(client.clone(), "p2abytes".to_string()), + raw: MetricsTree_Addresses_Raw::new(client.clone(), format!("{base_path}_raw")), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Addresses_Raw { + pub p2pk65: MetricsTree_Addresses_Raw_P2pk65, + pub p2pk33: MetricsTree_Addresses_Raw_P2pk33, + pub p2pkh: MetricsTree_Addresses_Raw_P2pkh, + pub p2sh: MetricsTree_Addresses_Raw_P2sh, + pub p2wpkh: MetricsTree_Addresses_Raw_P2wpkh, + pub p2wsh: MetricsTree_Addresses_Raw_P2wsh, + pub p2tr: MetricsTree_Addresses_Raw_P2tr, + pub p2a: MetricsTree_Addresses_Raw_P2a, +} + +impl MetricsTree_Addresses_Raw { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + p2pk65: MetricsTree_Addresses_Raw_P2pk65::new(client.clone(), format!("{base_path}_p2pk65")), + p2pk33: MetricsTree_Addresses_Raw_P2pk33::new(client.clone(), format!("{base_path}_p2pk33")), + p2pkh: MetricsTree_Addresses_Raw_P2pkh::new(client.clone(), format!("{base_path}_p2pkh")), + p2sh: MetricsTree_Addresses_Raw_P2sh::new(client.clone(), format!("{base_path}_p2sh")), + p2wpkh: MetricsTree_Addresses_Raw_P2wpkh::new(client.clone(), format!("{base_path}_p2wpkh")), + p2wsh: MetricsTree_Addresses_Raw_P2wsh::new(client.clone(), format!("{base_path}_p2wsh")), + p2tr: MetricsTree_Addresses_Raw_P2tr::new(client.clone(), format!("{base_path}_p2tr")), + p2a: MetricsTree_Addresses_Raw_P2a::new(client.clone(), format!("{base_path}_p2a")), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Addresses_Raw_P2pk65 { + pub first_index: MetricPattern18, + pub bytes: MetricPattern27, +} + +impl MetricsTree_Addresses_Raw_P2pk65 { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + first_index: MetricPattern18::new(client.clone(), "first_p2pk65addressindex".to_string()), + bytes: MetricPattern27::new(client.clone(), "p2pk65bytes".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Addresses_Raw_P2pk33 { + pub first_index: MetricPattern18, + pub bytes: MetricPattern26, +} + +impl MetricsTree_Addresses_Raw_P2pk33 { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + first_index: MetricPattern18::new(client.clone(), "first_p2pk33addressindex".to_string()), + bytes: MetricPattern26::new(client.clone(), "p2pk33bytes".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Addresses_Raw_P2pkh { + pub first_index: MetricPattern18, + pub bytes: MetricPattern28, +} + +impl MetricsTree_Addresses_Raw_P2pkh { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + first_index: MetricPattern18::new(client.clone(), "first_p2pkhaddressindex".to_string()), + bytes: MetricPattern28::new(client.clone(), "p2pkhbytes".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Addresses_Raw_P2sh { + pub first_index: MetricPattern18, + pub bytes: MetricPattern29, +} + +impl MetricsTree_Addresses_Raw_P2sh { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + first_index: MetricPattern18::new(client.clone(), "first_p2shaddressindex".to_string()), + bytes: MetricPattern29::new(client.clone(), "p2shbytes".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Addresses_Raw_P2wpkh { + pub first_index: MetricPattern18, + pub bytes: MetricPattern31, +} + +impl MetricsTree_Addresses_Raw_P2wpkh { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + first_index: MetricPattern18::new(client.clone(), "first_p2wpkhaddressindex".to_string()), + bytes: MetricPattern31::new(client.clone(), "p2wpkhbytes".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Addresses_Raw_P2wsh { + pub first_index: MetricPattern18, + pub bytes: MetricPattern32, +} + +impl MetricsTree_Addresses_Raw_P2wsh { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + first_index: MetricPattern18::new(client.clone(), "first_p2wshaddressindex".to_string()), + bytes: MetricPattern32::new(client.clone(), "p2wshbytes".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Addresses_Raw_P2tr { + pub first_index: MetricPattern18, + pub bytes: MetricPattern30, +} + +impl MetricsTree_Addresses_Raw_P2tr { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + first_index: MetricPattern18::new(client.clone(), "first_p2traddressindex".to_string()), + bytes: MetricPattern30::new(client.clone(), "p2trbytes".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Addresses_Raw_P2a { + pub first_index: MetricPattern18, + pub bytes: MetricPattern24, +} + +impl MetricsTree_Addresses_Raw_P2a { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + first_index: MetricPattern18::new(client.clone(), "first_p2aaddressindex".to_string()), + bytes: MetricPattern24::new(client.clone(), "p2abytes".to_string()), } } } /// Metrics tree node. pub struct MetricsTree_Scripts { - pub first_emptyoutputindex: MetricPattern18, - pub first_opreturnindex: MetricPattern18, - pub first_p2msoutputindex: MetricPattern18, - pub first_unknownoutputindex: MetricPattern18, - pub empty_to_txindex: MetricPattern22, - pub opreturn_to_txindex: MetricPattern23, - pub p2ms_to_txindex: MetricPattern25, - pub unknown_to_txindex: MetricPattern33, + pub raw: MetricsTree_Scripts_Raw, pub count: MetricsTree_Scripts_Count, pub value: MetricsTree_Scripts_Value, pub adoption: MetricsTree_Scripts_Adoption, @@ -3987,14 +4120,7 @@ pub struct MetricsTree_Scripts { impl MetricsTree_Scripts { pub fn new(client: Arc, base_path: String) -> Self { Self { - first_emptyoutputindex: MetricPattern18::new(client.clone(), "first_emptyoutputindex".to_string()), - first_opreturnindex: MetricPattern18::new(client.clone(), "first_opreturnindex".to_string()), - first_p2msoutputindex: MetricPattern18::new(client.clone(), "first_p2msoutputindex".to_string()), - first_unknownoutputindex: MetricPattern18::new(client.clone(), "first_unknownoutputindex".to_string()), - empty_to_txindex: MetricPattern22::new(client.clone(), "txindex".to_string()), - opreturn_to_txindex: MetricPattern23::new(client.clone(), "txindex".to_string()), - p2ms_to_txindex: MetricPattern25::new(client.clone(), "txindex".to_string()), - unknown_to_txindex: MetricPattern33::new(client.clone(), "txindex".to_string()), + raw: MetricsTree_Scripts_Raw::new(client.clone(), format!("{base_path}_raw")), count: MetricsTree_Scripts_Count::new(client.clone(), format!("{base_path}_count")), value: MetricsTree_Scripts_Value::new(client.clone(), format!("{base_path}_value")), adoption: MetricsTree_Scripts_Adoption::new(client.clone(), format!("{base_path}_adoption")), @@ -4002,6 +4128,85 @@ impl MetricsTree_Scripts { } } +/// Metrics tree node. +pub struct MetricsTree_Scripts_Raw { + pub empty: MetricsTree_Scripts_Raw_Empty, + pub opreturn: MetricsTree_Scripts_Raw_Opreturn, + pub p2ms: MetricsTree_Scripts_Raw_P2ms, + pub unknown: MetricsTree_Scripts_Raw_Unknown, +} + +impl MetricsTree_Scripts_Raw { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + empty: MetricsTree_Scripts_Raw_Empty::new(client.clone(), format!("{base_path}_empty")), + opreturn: MetricsTree_Scripts_Raw_Opreturn::new(client.clone(), format!("{base_path}_opreturn")), + p2ms: MetricsTree_Scripts_Raw_P2ms::new(client.clone(), format!("{base_path}_p2ms")), + unknown: MetricsTree_Scripts_Raw_Unknown::new(client.clone(), format!("{base_path}_unknown")), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Scripts_Raw_Empty { + pub first_index: MetricPattern18, + pub to_txindex: MetricPattern22, +} + +impl MetricsTree_Scripts_Raw_Empty { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + first_index: MetricPattern18::new(client.clone(), "first_emptyoutputindex".to_string()), + to_txindex: MetricPattern22::new(client.clone(), "txindex".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Scripts_Raw_Opreturn { + pub first_index: MetricPattern18, + pub to_txindex: MetricPattern23, +} + +impl MetricsTree_Scripts_Raw_Opreturn { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + first_index: MetricPattern18::new(client.clone(), "first_opreturnindex".to_string()), + to_txindex: MetricPattern23::new(client.clone(), "txindex".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Scripts_Raw_P2ms { + pub first_index: MetricPattern18, + pub to_txindex: MetricPattern25, +} + +impl MetricsTree_Scripts_Raw_P2ms { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + first_index: MetricPattern18::new(client.clone(), "first_p2msoutputindex".to_string()), + to_txindex: MetricPattern25::new(client.clone(), "txindex".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Scripts_Raw_Unknown { + pub first_index: MetricPattern18, + pub to_txindex: MetricPattern33, +} + +impl MetricsTree_Scripts_Raw_Unknown { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + first_index: MetricPattern18::new(client.clone(), "first_unknownoutputindex".to_string()), + to_txindex: MetricPattern33::new(client.clone(), "txindex".to_string()), + } + } +} + /// Metrics tree node. pub struct MetricsTree_Scripts_Count { pub p2a: CumulativeRawSumPattern, @@ -4041,13 +4246,28 @@ impl MetricsTree_Scripts_Count { /// Metrics tree node. pub struct MetricsTree_Scripts_Value { - pub opreturn: BaseCumulativePattern, + pub opreturn: MetricsTree_Scripts_Value_Opreturn, } impl MetricsTree_Scripts_Value { pub fn new(client: Arc, base_path: String) -> Self { Self { - opreturn: BaseCumulativePattern::new(client.clone(), "opreturn_value".to_string()), + opreturn: MetricsTree_Scripts_Value_Opreturn::new(client.clone(), format!("{base_path}_opreturn")), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Scripts_Value_Opreturn { + pub base: BtcCentsSatsUsdPattern, + pub cumulative: BtcCentsSatsUsdPattern, +} + +impl MetricsTree_Scripts_Value_Opreturn { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + base: BtcCentsSatsUsdPattern::new(client.clone(), "opreturn_value".to_string()), + cumulative: BtcCentsSatsUsdPattern::new(client.clone(), "opreturn_value_cumulative".to_string()), } } } @@ -4085,26 +4305,37 @@ impl MetricsTree_Mining { /// Metrics tree node. pub struct MetricsTree_Mining_Rewards { pub coinbase: BaseCumulativeSumPattern, - pub subsidy: BaseCumulativePattern, + pub subsidy: MetricsTree_Mining_Rewards_Subsidy, pub fees: MetricsTree_Mining_Rewards_Fees, - pub unclaimed_rewards: BaseCumulativeSumPattern, - pub fee_dominance: _1m1w1y24hBpsPercentRatioPattern, - pub subsidy_dominance: _1m1w1y24hBpsPercentRatioPattern, - pub subsidy_sma_1y: CentsUsdPattern, - pub fee_ratio_multiple: MetricsTree_Mining_Rewards_FeeRatioMultiple, + pub unclaimed: BaseCumulativeSumPattern, } impl MetricsTree_Mining_Rewards { pub fn new(client: Arc, base_path: String) -> Self { Self { coinbase: BaseCumulativeSumPattern::new(client.clone(), "coinbase".to_string()), - subsidy: BaseCumulativePattern::new(client.clone(), "subsidy".to_string()), + subsidy: MetricsTree_Mining_Rewards_Subsidy::new(client.clone(), format!("{base_path}_subsidy")), fees: MetricsTree_Mining_Rewards_Fees::new(client.clone(), format!("{base_path}_fees")), - unclaimed_rewards: BaseCumulativeSumPattern::new(client.clone(), "unclaimed_rewards".to_string()), - fee_dominance: _1m1w1y24hBpsPercentRatioPattern::new(client.clone(), "fee_dominance".to_string()), - subsidy_dominance: _1m1w1y24hBpsPercentRatioPattern::new(client.clone(), "subsidy_dominance".to_string()), - subsidy_sma_1y: CentsUsdPattern::new(client.clone(), "subsidy_sma_1y".to_string()), - fee_ratio_multiple: MetricsTree_Mining_Rewards_FeeRatioMultiple::new(client.clone(), format!("{base_path}_fee_ratio_multiple")), + unclaimed: BaseCumulativeSumPattern::new(client.clone(), "unclaimed_rewards".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Mining_Rewards_Subsidy { + pub base: BtcCentsSatsUsdPattern, + pub cumulative: BtcCentsSatsUsdPattern, + pub dominance: _1m1w1y24hBpsPercentRatioPattern, + pub sma_1y: CentsUsdPattern, +} + +impl MetricsTree_Mining_Rewards_Subsidy { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + base: BtcCentsSatsUsdPattern::new(client.clone(), "subsidy".to_string()), + cumulative: BtcCentsSatsUsdPattern::new(client.clone(), "subsidy_cumulative".to_string()), + dominance: _1m1w1y24hBpsPercentRatioPattern::new(client.clone(), "subsidy_dominance".to_string()), + sma_1y: CentsUsdPattern::new(client.clone(), "subsidy_sma_1y".to_string()), } } } @@ -4117,6 +4348,8 @@ pub struct MetricsTree_Mining_Rewards_Fees { pub _1w: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2, pub _1m: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2, pub _1y: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2, + pub dominance: _1m1w1y24hBpsPercentRatioPattern, + pub ratio_multiple: MetricsTree_Mining_Rewards_Fees_RatioMultiple, } impl MetricsTree_Mining_Rewards_Fees { @@ -4128,19 +4361,21 @@ impl MetricsTree_Mining_Rewards_Fees { _1w: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2::new(client.clone(), "fees_1w".to_string()), _1m: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2::new(client.clone(), "fees_1m".to_string()), _1y: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2::new(client.clone(), "fees_1y".to_string()), + dominance: _1m1w1y24hBpsPercentRatioPattern::new(client.clone(), "fee_dominance".to_string()), + ratio_multiple: MetricsTree_Mining_Rewards_Fees_RatioMultiple::new(client.clone(), format!("{base_path}_ratio_multiple")), } } } /// Metrics tree node. -pub struct MetricsTree_Mining_Rewards_FeeRatioMultiple { +pub struct MetricsTree_Mining_Rewards_Fees_RatioMultiple { pub _24h: BpsRatioPattern, pub _1w: BpsRatioPattern, pub _1m: BpsRatioPattern, pub _1y: BpsRatioPattern, } -impl MetricsTree_Mining_Rewards_FeeRatioMultiple { +impl MetricsTree_Mining_Rewards_Fees_RatioMultiple { pub fn new(client: Arc, base_path: String) -> Self { Self { _24h: BpsRatioPattern::new(client.clone(), "fee_ratio_multiple_24h".to_string()), @@ -5082,7 +5317,7 @@ impl MetricsTree_Market { /// Metrics tree node. pub struct MetricsTree_Market_Ath { - pub price: CentsSatsUsdPattern, + pub high: CentsSatsUsdPattern, pub drawdown: BpsPercentRatioPattern, pub days_since: MetricPattern1, pub years_since: MetricPattern2, @@ -5093,7 +5328,7 @@ pub struct MetricsTree_Market_Ath { impl MetricsTree_Market_Ath { pub fn new(client: Arc, base_path: String) -> Self { Self { - price: CentsSatsUsdPattern::new(client.clone(), "price_ath".to_string()), + high: CentsSatsUsdPattern::new(client.clone(), "price_ath".to_string()), drawdown: BpsPercentRatioPattern::new(client.clone(), "price_drawdown".to_string()), days_since: MetricPattern1::new(client.clone(), "days_since_price_ath".to_string()), years_since: MetricPattern2::new(client.clone(), "years_since_price_ath".to_string()), @@ -6207,7 +6442,7 @@ impl MetricsTree_Pools_Minor { pub struct MetricsTree_Prices { pub split: MetricsTree_Prices_Split, pub ohlc: MetricsTree_Prices_Ohlc, - pub price: MetricsTree_Prices_Price, + pub spot: MetricsTree_Prices_Spot, } impl MetricsTree_Prices { @@ -6215,7 +6450,7 @@ impl MetricsTree_Prices { Self { split: MetricsTree_Prices_Split::new(client.clone(), format!("{base_path}_split")), ohlc: MetricsTree_Prices_Ohlc::new(client.clone(), format!("{base_path}_ohlc")), - price: MetricsTree_Prices_Price::new(client.clone(), format!("{base_path}_price")), + spot: MetricsTree_Prices_Spot::new(client.clone(), format!("{base_path}_spot")), } } } @@ -6274,13 +6509,13 @@ impl MetricsTree_Prices_Ohlc { } /// Metrics tree node. -pub struct MetricsTree_Prices_Price { +pub struct MetricsTree_Prices_Spot { pub cents: MetricPattern1, pub usd: MetricPattern1, pub sats: MetricPattern1, } -impl MetricsTree_Prices_Price { +impl MetricsTree_Prices_Spot { pub fn new(client: Arc, base_path: String) -> Self { Self { cents: MetricPattern1::new(client.clone(), "price_cents".to_string()), @@ -6293,30 +6528,51 @@ impl MetricsTree_Prices_Price { /// Metrics tree node. pub struct MetricsTree_Distribution { pub supply_state: MetricPattern18, - pub any_address_indexes: MetricsTree_Distribution_AnyAddressIndexes, - pub addresses_data: MetricsTree_Distribution_AddressesData, - pub utxo_cohorts: MetricsTree_Distribution_UtxoCohorts, - pub address_cohorts: MetricsTree_Distribution_AddressCohorts, - pub coinblocks_destroyed: CumulativeRawPattern, pub addresses: MetricsTree_Distribution_Addresses, + pub cohorts: MetricsTree_Distribution_Cohorts, + pub coinblocks_destroyed: CumulativeRawPattern, } impl MetricsTree_Distribution { pub fn new(client: Arc, base_path: String) -> Self { Self { supply_state: MetricPattern18::new(client.clone(), "supply_state".to_string()), - any_address_indexes: MetricsTree_Distribution_AnyAddressIndexes::new(client.clone(), format!("{base_path}_any_address_indexes")), - addresses_data: MetricsTree_Distribution_AddressesData::new(client.clone(), format!("{base_path}_addresses_data")), - utxo_cohorts: MetricsTree_Distribution_UtxoCohorts::new(client.clone(), format!("{base_path}_utxo_cohorts")), - address_cohorts: MetricsTree_Distribution_AddressCohorts::new(client.clone(), format!("{base_path}_address_cohorts")), - coinblocks_destroyed: CumulativeRawPattern::new(client.clone(), "coinblocks_destroyed".to_string()), addresses: MetricsTree_Distribution_Addresses::new(client.clone(), format!("{base_path}_addresses")), + cohorts: MetricsTree_Distribution_Cohorts::new(client.clone(), format!("{base_path}_cohorts")), + coinblocks_destroyed: CumulativeRawPattern::new(client.clone(), "coinblocks_destroyed".to_string()), } } } /// Metrics tree node. -pub struct MetricsTree_Distribution_AnyAddressIndexes { +pub struct MetricsTree_Distribution_Addresses { + pub indexes: MetricsTree_Distribution_Addresses_Indexes, + pub data: MetricsTree_Distribution_Addresses_Data, + pub funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3, + pub empty: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3, + pub activity: MetricsTree_Distribution_Addresses_Activity, + pub total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3, + pub new: MetricsTree_Distribution_Addresses_New, + pub delta: MetricsTree_Distribution_Addresses_Delta, +} + +impl MetricsTree_Distribution_Addresses { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + indexes: MetricsTree_Distribution_Addresses_Indexes::new(client.clone(), format!("{base_path}_indexes")), + data: MetricsTree_Distribution_Addresses_Data::new(client.clone(), format!("{base_path}_data")), + funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3::new(client.clone(), "addr_count".to_string()), + empty: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3::new(client.clone(), "empty_addr_count".to_string()), + activity: MetricsTree_Distribution_Addresses_Activity::new(client.clone(), format!("{base_path}_activity")), + total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3::new(client.clone(), "total_addr_count".to_string()), + new: MetricsTree_Distribution_Addresses_New::new(client.clone(), format!("{base_path}_new")), + delta: MetricsTree_Distribution_Addresses_Delta::new(client.clone(), format!("{base_path}_delta")), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Addresses_Indexes { pub p2a: MetricPattern24, pub p2pk33: MetricPattern26, pub p2pk65: MetricPattern27, @@ -6325,9 +6581,11 @@ pub struct MetricsTree_Distribution_AnyAddressIndexes { pub p2tr: MetricPattern30, pub p2wpkh: MetricPattern31, pub p2wsh: MetricPattern32, + pub funded: MetricPattern34, + pub empty: MetricPattern35, } -impl MetricsTree_Distribution_AnyAddressIndexes { +impl MetricsTree_Distribution_Addresses_Indexes { pub fn new(client: Arc, base_path: String) -> Self { Self { p2a: MetricPattern24::new(client.clone(), "anyaddressindex".to_string()), @@ -6338,17 +6596,19 @@ impl MetricsTree_Distribution_AnyAddressIndexes { p2tr: MetricPattern30::new(client.clone(), "anyaddressindex".to_string()), p2wpkh: MetricPattern31::new(client.clone(), "anyaddressindex".to_string()), p2wsh: MetricPattern32::new(client.clone(), "anyaddressindex".to_string()), + funded: MetricPattern34::new(client.clone(), "funded_address_index".to_string()), + empty: MetricPattern35::new(client.clone(), "empty_address_index".to_string()), } } } /// Metrics tree node. -pub struct MetricsTree_Distribution_AddressesData { +pub struct MetricsTree_Distribution_Addresses_Data { pub funded: MetricPattern34, pub empty: MetricPattern35, } -impl MetricsTree_Distribution_AddressesData { +impl MetricsTree_Distribution_Addresses_Data { pub fn new(client: Arc, base_path: String) -> Self { Self { funded: MetricPattern34::new(client.clone(), "fundedaddressdata".to_string()), @@ -6357,1024 +6617,6 @@ impl MetricsTree_Distribution_AddressesData { } } -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts { - pub all: MetricsTree_Distribution_UtxoCohorts_All, - pub sth: MetricsTree_Distribution_UtxoCohorts_Sth, - pub lth: MetricsTree_Distribution_UtxoCohorts_Lth, - pub age_range: MetricsTree_Distribution_UtxoCohorts_AgeRange, - pub max_age: MetricsTree_Distribution_UtxoCohorts_MaxAge, - pub min_age: MetricsTree_Distribution_UtxoCohorts_MinAge, - pub epoch: MetricsTree_Distribution_UtxoCohorts_Epoch, - pub class: MetricsTree_Distribution_UtxoCohorts_Class, - pub ge_amount: MetricsTree_Distribution_UtxoCohorts_GeAmount, - pub amount_range: MetricsTree_Distribution_UtxoCohorts_AmountRange, - pub lt_amount: MetricsTree_Distribution_UtxoCohorts_LtAmount, - pub r#type: MetricsTree_Distribution_UtxoCohorts_Type, - pub profitability: MetricsTree_Distribution_UtxoCohorts_Profitability, - pub matured: MetricsTree_Distribution_UtxoCohorts_Matured, -} - -impl MetricsTree_Distribution_UtxoCohorts { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - all: MetricsTree_Distribution_UtxoCohorts_All::new(client.clone(), format!("{base_path}_all")), - sth: MetricsTree_Distribution_UtxoCohorts_Sth::new(client.clone(), format!("{base_path}_sth")), - lth: MetricsTree_Distribution_UtxoCohorts_Lth::new(client.clone(), format!("{base_path}_lth")), - age_range: MetricsTree_Distribution_UtxoCohorts_AgeRange::new(client.clone(), format!("{base_path}_age_range")), - max_age: MetricsTree_Distribution_UtxoCohorts_MaxAge::new(client.clone(), format!("{base_path}_max_age")), - min_age: MetricsTree_Distribution_UtxoCohorts_MinAge::new(client.clone(), format!("{base_path}_min_age")), - epoch: MetricsTree_Distribution_UtxoCohorts_Epoch::new(client.clone(), format!("{base_path}_epoch")), - class: MetricsTree_Distribution_UtxoCohorts_Class::new(client.clone(), format!("{base_path}_class")), - ge_amount: MetricsTree_Distribution_UtxoCohorts_GeAmount::new(client.clone(), format!("{base_path}_ge_amount")), - amount_range: MetricsTree_Distribution_UtxoCohorts_AmountRange::new(client.clone(), format!("{base_path}_amount_range")), - lt_amount: MetricsTree_Distribution_UtxoCohorts_LtAmount::new(client.clone(), format!("{base_path}_lt_amount")), - r#type: MetricsTree_Distribution_UtxoCohorts_Type::new(client.clone(), format!("{base_path}_type")), - profitability: MetricsTree_Distribution_UtxoCohorts_Profitability::new(client.clone(), format!("{base_path}_profitability")), - matured: MetricsTree_Distribution_UtxoCohorts_Matured::new(client.clone(), format!("{base_path}_matured")), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_All { - pub supply: MetricsTree_Distribution_UtxoCohorts_All_Supply, - pub outputs: UnspentPattern3, - pub activity: CoindaysCoinyearsDormancySentVelocityPattern, - pub realized: CapGrossInvestorLossMvrvNetNuplPeakPriceProfitSoprPattern, - pub cost_basis: InvestedMaxMinPercentilesSupplyPattern, - pub unrealized: MetricsTree_Distribution_UtxoCohorts_All_Unrealized, -} - -impl MetricsTree_Distribution_UtxoCohorts_All { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - supply: MetricsTree_Distribution_UtxoCohorts_All_Supply::new(client.clone(), format!("{base_path}_supply")), - outputs: UnspentPattern3::new(client.clone(), "utxo_count".to_string()), - activity: CoindaysCoinyearsDormancySentVelocityPattern::new(client.clone(), "".to_string()), - realized: CapGrossInvestorLossMvrvNetNuplPeakPriceProfitSoprPattern::new(client.clone(), "".to_string()), - cost_basis: InvestedMaxMinPercentilesSupplyPattern::new(client.clone(), "".to_string()), - unrealized: MetricsTree_Distribution_UtxoCohorts_All_Unrealized::new(client.clone(), format!("{base_path}_unrealized")), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_All_Supply { - pub delta: ChangeRatePattern2, - pub in_profit: BtcCentsRelSatsUsdPattern2, - pub in_loss: BtcCentsRelSatsUsdPattern2, - pub total: BtcCentsSatsUsdPattern, - pub halved: BtcCentsSatsUsdPattern, -} - -impl MetricsTree_Distribution_UtxoCohorts_All_Supply { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - delta: ChangeRatePattern2::new(client.clone(), "supply_delta".to_string()), - in_profit: BtcCentsRelSatsUsdPattern2::new(client.clone(), "supply_in_profit".to_string()), - in_loss: BtcCentsRelSatsUsdPattern2::new(client.clone(), "supply_in_loss".to_string()), - total: BtcCentsSatsUsdPattern::new(client.clone(), "supply".to_string()), - halved: BtcCentsSatsUsdPattern::new(client.clone(), "supply_halved".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_All_Unrealized { - pub gross_pnl: CentsUsdPattern, - pub invested_capital: InPattern2, - pub sentiment: GreedNetPainPattern, - pub investor_cap: InPattern, - pub loss: MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Loss, - pub net_pnl: MetricsTree_Distribution_UtxoCohorts_All_Unrealized_NetPnl, - pub profit: MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Profit, -} - -impl MetricsTree_Distribution_UtxoCohorts_All_Unrealized { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - gross_pnl: CentsUsdPattern::new(client.clone(), "unrealized_gross_pnl".to_string()), - invested_capital: InPattern2::new(client.clone(), "invested_capital_in".to_string()), - sentiment: GreedNetPainPattern::new(client.clone(), "".to_string()), - investor_cap: InPattern::new(client.clone(), "investor_cap_in".to_string()), - loss: MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Loss::new(client.clone(), format!("{base_path}_loss")), - net_pnl: MetricsTree_Distribution_UtxoCohorts_All_Unrealized_NetPnl::new(client.clone(), format!("{base_path}_net_pnl")), - profit: MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Profit::new(client.clone(), format!("{base_path}_profit")), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Loss { - pub negative: MetricPattern1, - pub raw: CentsUsdPattern, - pub sum: _24hPattern, - pub rel_to_market_cap: BpsPercentRatioPattern, - pub rel_to_own_gross_pnl: BpsPercentRatioPattern, -} - -impl MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Loss { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - negative: MetricPattern1::new(client.clone(), "neg_unrealized_loss".to_string()), - raw: CentsUsdPattern::new(client.clone(), "unrealized_loss".to_string()), - sum: _24hPattern::new(client.clone(), "unrealized_loss_24h".to_string()), - rel_to_market_cap: BpsPercentRatioPattern::new(client.clone(), "unrealized_loss_rel_to_market_cap".to_string()), - rel_to_own_gross_pnl: BpsPercentRatioPattern::new(client.clone(), "unrealized_loss_rel_to_own_gross_pnl".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_All_Unrealized_NetPnl { - pub cents: MetricPattern1, - pub usd: MetricPattern1, - pub rel_to_own_gross_pnl: BpsPercentRatioPattern, -} - -impl MetricsTree_Distribution_UtxoCohorts_All_Unrealized_NetPnl { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - cents: MetricPattern1::new(client.clone(), "net_unrealized_pnl_cents".to_string()), - usd: MetricPattern1::new(client.clone(), "net_unrealized_pnl".to_string()), - rel_to_own_gross_pnl: BpsPercentRatioPattern::new(client.clone(), "net_unrealized_pnl_rel_to_own_gross_pnl".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Profit { - pub raw: CentsUsdPattern, - pub sum: _24hPattern, - pub rel_to_market_cap: BpsPercentRatioPattern, - pub rel_to_own_gross_pnl: BpsPercentRatioPattern, -} - -impl MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Profit { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - raw: CentsUsdPattern::new(client.clone(), "unrealized_profit".to_string()), - sum: _24hPattern::new(client.clone(), "unrealized_profit_24h".to_string()), - rel_to_market_cap: BpsPercentRatioPattern::new(client.clone(), "unrealized_profit_rel_to_market_cap".to_string()), - rel_to_own_gross_pnl: BpsPercentRatioPattern::new(client.clone(), "unrealized_profit_rel_to_own_gross_pnl".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_Sth { - pub realized: CapGrossInvestorLossMvrvNetNuplPeakPriceProfitSoprPattern, - pub supply: DeltaHalvedInRelTotalPattern2, - pub outputs: UnspentPattern3, - pub activity: CoindaysCoinyearsDormancySentVelocityPattern, - pub cost_basis: InvestedMaxMinPercentilesSupplyPattern, - pub unrealized: GrossInvestedInvestorLossNetProfitSentimentPattern2, -} - -impl MetricsTree_Distribution_UtxoCohorts_Sth { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - realized: CapGrossInvestorLossMvrvNetNuplPeakPriceProfitSoprPattern::new(client.clone(), "sth".to_string()), - supply: DeltaHalvedInRelTotalPattern2::new(client.clone(), "sth_supply".to_string()), - outputs: UnspentPattern3::new(client.clone(), "sth_utxo_count".to_string()), - activity: CoindaysCoinyearsDormancySentVelocityPattern::new(client.clone(), "sth".to_string()), - cost_basis: InvestedMaxMinPercentilesSupplyPattern::new(client.clone(), "sth".to_string()), - unrealized: GrossInvestedInvestorLossNetProfitSentimentPattern2::new(client.clone(), "sth".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_Lth { - pub supply: DeltaHalvedInRelTotalPattern2, - pub outputs: UnspentPattern3, - pub activity: CoindaysCoinyearsDormancySentVelocityPattern, - pub realized: MetricsTree_Distribution_UtxoCohorts_Lth_Realized, - pub cost_basis: InvestedMaxMinPercentilesSupplyPattern, - pub unrealized: GrossInvestedInvestorLossNetProfitSentimentPattern2, -} - -impl MetricsTree_Distribution_UtxoCohorts_Lth { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - supply: DeltaHalvedInRelTotalPattern2::new(client.clone(), "lth_supply".to_string()), - outputs: UnspentPattern3::new(client.clone(), "lth_utxo_count".to_string()), - activity: CoindaysCoinyearsDormancySentVelocityPattern::new(client.clone(), "lth".to_string()), - realized: MetricsTree_Distribution_UtxoCohorts_Lth_Realized::new(client.clone(), format!("{base_path}_realized")), - cost_basis: InvestedMaxMinPercentilesSupplyPattern::new(client.clone(), "lth".to_string()), - unrealized: GrossInvestedInvestorLossNetProfitSentimentPattern2::new(client.clone(), "lth".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_Lth_Realized { - pub profit: CumulativeDistributionRawRelSumValuePattern, - pub loss: CapitulationCumulativeNegativeRawRelSumValuePattern, - pub gross_pnl: RawSellSumPattern, - pub net_pnl: ChangeCumulativeDeltaRawRelSumPattern, - pub sopr: MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr, - pub peak_regret: CumulativeRawRelPattern, - pub investor: CapLowerPriceUpperPattern, - pub profit_to_loss_ratio: _1m1w1y24hPattern, - pub cap: CentsDeltaRawRelUsdPattern, - pub price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern, - pub mvrv: MetricPattern1, - pub nupl: BpsRatioPattern, -} - -impl MetricsTree_Distribution_UtxoCohorts_Lth_Realized { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - profit: CumulativeDistributionRawRelSumValuePattern::new(client.clone(), "lth".to_string()), - loss: CapitulationCumulativeNegativeRawRelSumValuePattern::new(client.clone(), "lth".to_string()), - gross_pnl: RawSellSumPattern::new(client.clone(), "lth".to_string()), - net_pnl: ChangeCumulativeDeltaRawRelSumPattern::new(client.clone(), "lth_net".to_string()), - sopr: MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr::new(client.clone(), format!("{base_path}_sopr")), - peak_regret: CumulativeRawRelPattern::new(client.clone(), "lth_realized_peak_regret".to_string()), - investor: CapLowerPriceUpperPattern::new(client.clone(), "lth".to_string()), - profit_to_loss_ratio: _1m1w1y24hPattern::new(client.clone(), "lth_realized_profit_to_loss_ratio".to_string()), - cap: CentsDeltaRawRelUsdPattern::new(client.clone(), "lth".to_string()), - price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern::new(client.clone(), "lth_realized_price".to_string()), - mvrv: MetricPattern1::new(client.clone(), "lth_mvrv".to_string()), - nupl: BpsRatioPattern::new(client.clone(), "lth_nupl_ratio".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr { - pub value_created: MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueCreated, - pub value_destroyed: MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueDestroyed, - pub ratio: _1m1w1y24hPattern, -} - -impl MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - value_created: MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueCreated::new(client.clone(), format!("{base_path}_value_created")), - value_destroyed: MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueDestroyed::new(client.clone(), format!("{base_path}_value_destroyed")), - ratio: _1m1w1y24hPattern::new(client.clone(), "lth_sopr".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueCreated { - pub sum: _1m1w1y24hPattern, - pub raw: MetricPattern1, -} - -impl MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueCreated { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - sum: _1m1w1y24hPattern::new(client.clone(), "lth_value_created".to_string()), - raw: MetricPattern1::new(client.clone(), "lth_value_created".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueDestroyed { - pub sum: _1m1w1y24hPattern, - pub raw: MetricPattern1, -} - -impl MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueDestroyed { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - sum: _1m1w1y24hPattern::new(client.clone(), "lth_value_destroyed".to_string()), - raw: MetricPattern1::new(client.clone(), "lth_value_destroyed".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_AgeRange { - pub up_to_1h: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _1h_to_1d: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _1d_to_1w: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _1w_to_1m: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _1m_to_2m: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _2m_to_3m: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _3m_to_4m: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _4m_to_5m: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _5m_to_6m: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _6m_to_1y: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _1y_to_2y: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _2y_to_3y: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _3y_to_4y: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _4y_to_5y: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _5y_to_6y: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _6y_to_7y: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _7y_to_8y: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _8y_to_10y: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _10y_to_12y: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub _12y_to_15y: ActivityOutputsRealizedSupplyUnrealizedPattern, - pub from_15y: ActivityOutputsRealizedSupplyUnrealizedPattern, -} - -impl MetricsTree_Distribution_UtxoCohorts_AgeRange { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - up_to_1h: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_under_1h_old".to_string()), - _1h_to_1d: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_1h_to_1d_old".to_string()), - _1d_to_1w: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_1d_to_1w_old".to_string()), - _1w_to_1m: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_1w_to_1m_old".to_string()), - _1m_to_2m: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_1m_to_2m_old".to_string()), - _2m_to_3m: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_2m_to_3m_old".to_string()), - _3m_to_4m: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_3m_to_4m_old".to_string()), - _4m_to_5m: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_4m_to_5m_old".to_string()), - _5m_to_6m: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_5m_to_6m_old".to_string()), - _6m_to_1y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_6m_to_1y_old".to_string()), - _1y_to_2y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_1y_to_2y_old".to_string()), - _2y_to_3y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_2y_to_3y_old".to_string()), - _3y_to_4y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_3y_to_4y_old".to_string()), - _4y_to_5y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_4y_to_5y_old".to_string()), - _5y_to_6y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_5y_to_6y_old".to_string()), - _6y_to_7y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_6y_to_7y_old".to_string()), - _7y_to_8y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_7y_to_8y_old".to_string()), - _8y_to_10y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_8y_to_10y_old".to_string()), - _10y_to_12y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_10y_to_12y_old".to_string()), - _12y_to_15y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_12y_to_15y_old".to_string()), - from_15y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_over_15y_old".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_MaxAge { - pub _1w: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _1m: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2m: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _3m: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _4m: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _5m: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _6m: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _1y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _3y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _4y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _5y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _6y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _7y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _8y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _10y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _12y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _15y: ActivityOutputsRealizedSupplyUnrealizedPattern2, -} - -impl MetricsTree_Distribution_UtxoCohorts_MaxAge { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - _1w: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_1w_old".to_string()), - _1m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_1m_old".to_string()), - _2m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_2m_old".to_string()), - _3m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_3m_old".to_string()), - _4m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_4m_old".to_string()), - _5m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_5m_old".to_string()), - _6m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_6m_old".to_string()), - _1y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_1y_old".to_string()), - _2y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_2y_old".to_string()), - _3y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_3y_old".to_string()), - _4y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_4y_old".to_string()), - _5y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_5y_old".to_string()), - _6y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_6y_old".to_string()), - _7y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_7y_old".to_string()), - _8y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_8y_old".to_string()), - _10y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_10y_old".to_string()), - _12y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_12y_old".to_string()), - _15y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_15y_old".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_MinAge { - pub _1d: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _1w: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _1m: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2m: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _3m: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _4m: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _5m: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _6m: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _1y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _3y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _4y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _5y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _6y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _7y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _8y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _10y: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _12y: ActivityOutputsRealizedSupplyUnrealizedPattern2, -} - -impl MetricsTree_Distribution_UtxoCohorts_MinAge { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - _1d: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_1d_old".to_string()), - _1w: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_1w_old".to_string()), - _1m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_1m_old".to_string()), - _2m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_2m_old".to_string()), - _3m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_3m_old".to_string()), - _4m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_4m_old".to_string()), - _5m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_5m_old".to_string()), - _6m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_6m_old".to_string()), - _1y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_1y_old".to_string()), - _2y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_2y_old".to_string()), - _3y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_3y_old".to_string()), - _4y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_4y_old".to_string()), - _5y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_5y_old".to_string()), - _6y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_6y_old".to_string()), - _7y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_7y_old".to_string()), - _8y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_8y_old".to_string()), - _10y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_10y_old".to_string()), - _12y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_12y_old".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_Epoch { - pub _0: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _1: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _3: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _4: ActivityOutputsRealizedSupplyUnrealizedPattern2, -} - -impl MetricsTree_Distribution_UtxoCohorts_Epoch { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - _0: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "epoch_0".to_string()), - _1: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "epoch_1".to_string()), - _2: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "epoch_2".to_string()), - _3: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "epoch_3".to_string()), - _4: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "epoch_4".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_Class { - pub _2009: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2010: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2011: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2012: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2013: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2014: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2015: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2016: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2017: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2018: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2019: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2020: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2021: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2022: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2023: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2024: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2025: ActivityOutputsRealizedSupplyUnrealizedPattern2, - pub _2026: ActivityOutputsRealizedSupplyUnrealizedPattern2, -} - -impl MetricsTree_Distribution_UtxoCohorts_Class { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - _2009: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2009".to_string()), - _2010: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2010".to_string()), - _2011: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2011".to_string()), - _2012: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2012".to_string()), - _2013: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2013".to_string()), - _2014: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2014".to_string()), - _2015: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2015".to_string()), - _2016: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2016".to_string()), - _2017: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2017".to_string()), - _2018: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2018".to_string()), - _2019: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2019".to_string()), - _2020: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2020".to_string()), - _2021: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2021".to_string()), - _2022: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2022".to_string()), - _2023: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2023".to_string()), - _2024: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2024".to_string()), - _2025: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2025".to_string()), - _2026: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2026".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_GeAmount { - pub _1sat: OutputsRealizedSupplyPattern, - pub _10sats: OutputsRealizedSupplyPattern, - pub _100sats: OutputsRealizedSupplyPattern, - pub _1k_sats: OutputsRealizedSupplyPattern, - pub _10k_sats: OutputsRealizedSupplyPattern, - pub _100k_sats: OutputsRealizedSupplyPattern, - pub _1m_sats: OutputsRealizedSupplyPattern, - pub _10m_sats: OutputsRealizedSupplyPattern, - pub _1btc: OutputsRealizedSupplyPattern, - pub _10btc: OutputsRealizedSupplyPattern, - pub _100btc: OutputsRealizedSupplyPattern, - pub _1k_btc: OutputsRealizedSupplyPattern, - pub _10k_btc: OutputsRealizedSupplyPattern, -} - -impl MetricsTree_Distribution_UtxoCohorts_GeAmount { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - _1sat: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_1sat".to_string()), - _10sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_10sats".to_string()), - _100sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_100sats".to_string()), - _1k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_1k_sats".to_string()), - _10k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_10k_sats".to_string()), - _100k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_100k_sats".to_string()), - _1m_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_1m_sats".to_string()), - _10m_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_10m_sats".to_string()), - _1btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_1btc".to_string()), - _10btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_10btc".to_string()), - _100btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_100btc".to_string()), - _1k_btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_1k_btc".to_string()), - _10k_btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_10k_btc".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_AmountRange { - pub _0sats: OutputsRealizedSupplyPattern, - pub _1sat_to_10sats: OutputsRealizedSupplyPattern, - pub _10sats_to_100sats: OutputsRealizedSupplyPattern, - pub _100sats_to_1k_sats: OutputsRealizedSupplyPattern, - pub _1k_sats_to_10k_sats: OutputsRealizedSupplyPattern, - pub _10k_sats_to_100k_sats: OutputsRealizedSupplyPattern, - pub _100k_sats_to_1m_sats: OutputsRealizedSupplyPattern, - pub _1m_sats_to_10m_sats: OutputsRealizedSupplyPattern, - pub _10m_sats_to_1btc: OutputsRealizedSupplyPattern, - pub _1btc_to_10btc: OutputsRealizedSupplyPattern, - pub _10btc_to_100btc: OutputsRealizedSupplyPattern, - pub _100btc_to_1k_btc: OutputsRealizedSupplyPattern, - pub _1k_btc_to_10k_btc: OutputsRealizedSupplyPattern, - pub _10k_btc_to_100k_btc: OutputsRealizedSupplyPattern, - pub _100k_btc_or_more: OutputsRealizedSupplyPattern, -} - -impl MetricsTree_Distribution_UtxoCohorts_AmountRange { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - _0sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_with_0sats".to_string()), - _1sat_to_10sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_1sat_under_10sats".to_string()), - _10sats_to_100sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_10sats_under_100sats".to_string()), - _100sats_to_1k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_100sats_under_1k_sats".to_string()), - _1k_sats_to_10k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_1k_sats_under_10k_sats".to_string()), - _10k_sats_to_100k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_10k_sats_under_100k_sats".to_string()), - _100k_sats_to_1m_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_100k_sats_under_1m_sats".to_string()), - _1m_sats_to_10m_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_1m_sats_under_10m_sats".to_string()), - _10m_sats_to_1btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_10m_sats_under_1btc".to_string()), - _1btc_to_10btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_1btc_under_10btc".to_string()), - _10btc_to_100btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_10btc_under_100btc".to_string()), - _100btc_to_1k_btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_100btc_under_1k_btc".to_string()), - _1k_btc_to_10k_btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_1k_btc_under_10k_btc".to_string()), - _10k_btc_to_100k_btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_10k_btc_under_100k_btc".to_string()), - _100k_btc_or_more: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_100k_btc".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_LtAmount { - pub _10sats: OutputsRealizedSupplyPattern, - pub _100sats: OutputsRealizedSupplyPattern, - pub _1k_sats: OutputsRealizedSupplyPattern, - pub _10k_sats: OutputsRealizedSupplyPattern, - pub _100k_sats: OutputsRealizedSupplyPattern, - pub _1m_sats: OutputsRealizedSupplyPattern, - pub _10m_sats: OutputsRealizedSupplyPattern, - pub _1btc: OutputsRealizedSupplyPattern, - pub _10btc: OutputsRealizedSupplyPattern, - pub _100btc: OutputsRealizedSupplyPattern, - pub _1k_btc: OutputsRealizedSupplyPattern, - pub _10k_btc: OutputsRealizedSupplyPattern, - pub _100k_btc: OutputsRealizedSupplyPattern, -} - -impl MetricsTree_Distribution_UtxoCohorts_LtAmount { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - _10sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_10sats".to_string()), - _100sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_100sats".to_string()), - _1k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_1k_sats".to_string()), - _10k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_10k_sats".to_string()), - _100k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_100k_sats".to_string()), - _1m_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_1m_sats".to_string()), - _10m_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_10m_sats".to_string()), - _1btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_1btc".to_string()), - _10btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_10btc".to_string()), - _100btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_100btc".to_string()), - _1k_btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_1k_btc".to_string()), - _10k_btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_10k_btc".to_string()), - _100k_btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_100k_btc".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_Type { - pub p2pk65: OutputsRealizedSupplyUnrealizedPattern, - pub p2pk33: OutputsRealizedSupplyUnrealizedPattern, - pub p2pkh: OutputsRealizedSupplyUnrealizedPattern, - pub p2ms: OutputsRealizedSupplyUnrealizedPattern, - pub p2sh: OutputsRealizedSupplyUnrealizedPattern, - pub p2wpkh: OutputsRealizedSupplyUnrealizedPattern, - pub p2wsh: OutputsRealizedSupplyUnrealizedPattern, - pub p2tr: OutputsRealizedSupplyUnrealizedPattern, - pub p2a: OutputsRealizedSupplyUnrealizedPattern, - pub unknown: OutputsRealizedSupplyUnrealizedPattern, - pub empty: OutputsRealizedSupplyUnrealizedPattern, -} - -impl MetricsTree_Distribution_UtxoCohorts_Type { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - p2pk65: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2pk65".to_string()), - p2pk33: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2pk33".to_string()), - p2pkh: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2pkh".to_string()), - p2ms: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2ms".to_string()), - p2sh: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2sh".to_string()), - p2wpkh: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2wpkh".to_string()), - p2wsh: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2wsh".to_string()), - p2tr: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2tr".to_string()), - p2a: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2a".to_string()), - unknown: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "unknown_outputs".to_string()), - empty: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "empty_outputs".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_Profitability { - pub range: MetricsTree_Distribution_UtxoCohorts_Profitability_Range, - pub profit: MetricsTree_Distribution_UtxoCohorts_Profitability_Profit, - pub loss: MetricsTree_Distribution_UtxoCohorts_Profitability_Loss, -} - -impl MetricsTree_Distribution_UtxoCohorts_Profitability { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - range: MetricsTree_Distribution_UtxoCohorts_Profitability_Range::new(client.clone(), format!("{base_path}_range")), - profit: MetricsTree_Distribution_UtxoCohorts_Profitability_Profit::new(client.clone(), format!("{base_path}_profit")), - loss: MetricsTree_Distribution_UtxoCohorts_Profitability_Loss::new(client.clone(), format!("{base_path}_loss")), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_Profitability_Range { - pub profit_over_1000: RealizedSupplyPattern, - pub profit_500_to_1000: RealizedSupplyPattern, - pub profit_300_to_500: RealizedSupplyPattern, - pub profit_200_to_300: RealizedSupplyPattern, - pub profit_100_to_200: RealizedSupplyPattern, - pub profit_90_to_100: RealizedSupplyPattern, - pub profit_80_to_90: RealizedSupplyPattern, - pub profit_70_to_80: RealizedSupplyPattern, - pub profit_60_to_70: RealizedSupplyPattern, - pub profit_50_to_60: RealizedSupplyPattern, - pub profit_40_to_50: RealizedSupplyPattern, - pub profit_30_to_40: RealizedSupplyPattern, - pub profit_20_to_30: RealizedSupplyPattern, - pub profit_10_to_20: RealizedSupplyPattern, - pub profit_0_to_10: RealizedSupplyPattern, - pub loss_0_to_10: RealizedSupplyPattern, - pub loss_10_to_20: RealizedSupplyPattern, - pub loss_20_to_30: RealizedSupplyPattern, - pub loss_30_to_40: RealizedSupplyPattern, - pub loss_40_to_50: RealizedSupplyPattern, - pub loss_50_to_60: RealizedSupplyPattern, - pub loss_60_to_70: RealizedSupplyPattern, - pub loss_70_to_80: RealizedSupplyPattern, - pub loss_80_to_90: RealizedSupplyPattern, - pub loss_90_to_100: RealizedSupplyPattern, -} - -impl MetricsTree_Distribution_UtxoCohorts_Profitability_Range { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - profit_over_1000: RealizedSupplyPattern::new(client.clone(), "profit_over_1000pct".to_string()), - profit_500_to_1000: RealizedSupplyPattern::new(client.clone(), "profit_500_to_1000pct".to_string()), - profit_300_to_500: RealizedSupplyPattern::new(client.clone(), "profit_300_to_500pct".to_string()), - profit_200_to_300: RealizedSupplyPattern::new(client.clone(), "profit_200_to_300pct".to_string()), - profit_100_to_200: RealizedSupplyPattern::new(client.clone(), "profit_100_to_200pct".to_string()), - profit_90_to_100: RealizedSupplyPattern::new(client.clone(), "profit_90_to_100pct".to_string()), - profit_80_to_90: RealizedSupplyPattern::new(client.clone(), "profit_80_to_90pct".to_string()), - profit_70_to_80: RealizedSupplyPattern::new(client.clone(), "profit_70_to_80pct".to_string()), - profit_60_to_70: RealizedSupplyPattern::new(client.clone(), "profit_60_to_70pct".to_string()), - profit_50_to_60: RealizedSupplyPattern::new(client.clone(), "profit_50_to_60pct".to_string()), - profit_40_to_50: RealizedSupplyPattern::new(client.clone(), "profit_40_to_50pct".to_string()), - profit_30_to_40: RealizedSupplyPattern::new(client.clone(), "profit_30_to_40pct".to_string()), - profit_20_to_30: RealizedSupplyPattern::new(client.clone(), "profit_20_to_30pct".to_string()), - profit_10_to_20: RealizedSupplyPattern::new(client.clone(), "profit_10_to_20pct".to_string()), - profit_0_to_10: RealizedSupplyPattern::new(client.clone(), "profit_0_to_10pct".to_string()), - loss_0_to_10: RealizedSupplyPattern::new(client.clone(), "loss_0_to_10pct".to_string()), - loss_10_to_20: RealizedSupplyPattern::new(client.clone(), "loss_10_to_20pct".to_string()), - loss_20_to_30: RealizedSupplyPattern::new(client.clone(), "loss_20_to_30pct".to_string()), - loss_30_to_40: RealizedSupplyPattern::new(client.clone(), "loss_30_to_40pct".to_string()), - loss_40_to_50: RealizedSupplyPattern::new(client.clone(), "loss_40_to_50pct".to_string()), - loss_50_to_60: RealizedSupplyPattern::new(client.clone(), "loss_50_to_60pct".to_string()), - loss_60_to_70: RealizedSupplyPattern::new(client.clone(), "loss_60_to_70pct".to_string()), - loss_70_to_80: RealizedSupplyPattern::new(client.clone(), "loss_70_to_80pct".to_string()), - loss_80_to_90: RealizedSupplyPattern::new(client.clone(), "loss_80_to_90pct".to_string()), - loss_90_to_100: RealizedSupplyPattern::new(client.clone(), "loss_90_to_100pct".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_Profitability_Profit { - pub breakeven: RealizedSupplyPattern, - pub _10pct: RealizedSupplyPattern, - pub _20pct: RealizedSupplyPattern, - pub _30pct: RealizedSupplyPattern, - pub _40pct: RealizedSupplyPattern, - pub _50pct: RealizedSupplyPattern, - pub _60pct: RealizedSupplyPattern, - pub _70pct: RealizedSupplyPattern, - pub _80pct: RealizedSupplyPattern, - pub _90pct: RealizedSupplyPattern, - pub _100pct: RealizedSupplyPattern, - pub _200pct: RealizedSupplyPattern, - pub _300pct: RealizedSupplyPattern, - pub _500pct: RealizedSupplyPattern, - pub _1000pct: RealizedSupplyPattern, -} - -impl MetricsTree_Distribution_UtxoCohorts_Profitability_Profit { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - breakeven: RealizedSupplyPattern::new(client.clone(), "profit_ge_breakeven".to_string()), - _10pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_10pct".to_string()), - _20pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_20pct".to_string()), - _30pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_30pct".to_string()), - _40pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_40pct".to_string()), - _50pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_50pct".to_string()), - _60pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_60pct".to_string()), - _70pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_70pct".to_string()), - _80pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_80pct".to_string()), - _90pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_90pct".to_string()), - _100pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_100pct".to_string()), - _200pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_200pct".to_string()), - _300pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_300pct".to_string()), - _500pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_500pct".to_string()), - _1000pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_1000pct".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_Profitability_Loss { - pub breakeven: RealizedSupplyPattern, - pub _10pct: RealizedSupplyPattern, - pub _20pct: RealizedSupplyPattern, - pub _30pct: RealizedSupplyPattern, - pub _40pct: RealizedSupplyPattern, - pub _50pct: RealizedSupplyPattern, - pub _60pct: RealizedSupplyPattern, - pub _70pct: RealizedSupplyPattern, - pub _80pct: RealizedSupplyPattern, - pub _90pct: RealizedSupplyPattern, -} - -impl MetricsTree_Distribution_UtxoCohorts_Profitability_Loss { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - breakeven: RealizedSupplyPattern::new(client.clone(), "loss_ge_breakeven".to_string()), - _10pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_10pct".to_string()), - _20pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_20pct".to_string()), - _30pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_30pct".to_string()), - _40pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_40pct".to_string()), - _50pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_50pct".to_string()), - _60pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_60pct".to_string()), - _70pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_70pct".to_string()), - _80pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_80pct".to_string()), - _90pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_90pct".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_Matured { - pub up_to_1h: BtcCentsSatsUsdPattern, - pub _1h_to_1d: BtcCentsSatsUsdPattern, - pub _1d_to_1w: BtcCentsSatsUsdPattern, - pub _1w_to_1m: BtcCentsSatsUsdPattern, - pub _1m_to_2m: BtcCentsSatsUsdPattern, - pub _2m_to_3m: BtcCentsSatsUsdPattern, - pub _3m_to_4m: BtcCentsSatsUsdPattern, - pub _4m_to_5m: BtcCentsSatsUsdPattern, - pub _5m_to_6m: BtcCentsSatsUsdPattern, - pub _6m_to_1y: BtcCentsSatsUsdPattern, - pub _1y_to_2y: BtcCentsSatsUsdPattern, - pub _2y_to_3y: BtcCentsSatsUsdPattern, - pub _3y_to_4y: BtcCentsSatsUsdPattern, - pub _4y_to_5y: BtcCentsSatsUsdPattern, - pub _5y_to_6y: BtcCentsSatsUsdPattern, - pub _6y_to_7y: BtcCentsSatsUsdPattern, - pub _7y_to_8y: BtcCentsSatsUsdPattern, - pub _8y_to_10y: BtcCentsSatsUsdPattern, - pub _10y_to_12y: BtcCentsSatsUsdPattern, - pub _12y_to_15y: BtcCentsSatsUsdPattern, - pub from_15y: BtcCentsSatsUsdPattern, -} - -impl MetricsTree_Distribution_UtxoCohorts_Matured { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - up_to_1h: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_under_1h_old_matured".to_string()), - _1h_to_1d: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_1h_to_1d_old_matured".to_string()), - _1d_to_1w: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_1d_to_1w_old_matured".to_string()), - _1w_to_1m: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_1w_to_1m_old_matured".to_string()), - _1m_to_2m: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_1m_to_2m_old_matured".to_string()), - _2m_to_3m: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_2m_to_3m_old_matured".to_string()), - _3m_to_4m: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_3m_to_4m_old_matured".to_string()), - _4m_to_5m: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_4m_to_5m_old_matured".to_string()), - _5m_to_6m: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_5m_to_6m_old_matured".to_string()), - _6m_to_1y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_6m_to_1y_old_matured".to_string()), - _1y_to_2y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_1y_to_2y_old_matured".to_string()), - _2y_to_3y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_2y_to_3y_old_matured".to_string()), - _3y_to_4y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_3y_to_4y_old_matured".to_string()), - _4y_to_5y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_4y_to_5y_old_matured".to_string()), - _5y_to_6y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_5y_to_6y_old_matured".to_string()), - _6y_to_7y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_6y_to_7y_old_matured".to_string()), - _7y_to_8y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_7y_to_8y_old_matured".to_string()), - _8y_to_10y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_8y_to_10y_old_matured".to_string()), - _10y_to_12y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_10y_to_12y_old_matured".to_string()), - _12y_to_15y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_12y_to_15y_old_matured".to_string()), - from_15y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_over_15y_old_matured".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_AddressCohorts { - pub ge_amount: MetricsTree_Distribution_AddressCohorts_GeAmount, - pub amount_range: MetricsTree_Distribution_AddressCohorts_AmountRange, - pub lt_amount: MetricsTree_Distribution_AddressCohorts_LtAmount, -} - -impl MetricsTree_Distribution_AddressCohorts { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - ge_amount: MetricsTree_Distribution_AddressCohorts_GeAmount::new(client.clone(), format!("{base_path}_ge_amount")), - amount_range: MetricsTree_Distribution_AddressCohorts_AmountRange::new(client.clone(), format!("{base_path}_amount_range")), - lt_amount: MetricsTree_Distribution_AddressCohorts_LtAmount::new(client.clone(), format!("{base_path}_lt_amount")), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_AddressCohorts_GeAmount { - pub _1sat: AddrOutputsRealizedSupplyPattern, - pub _10sats: AddrOutputsRealizedSupplyPattern, - pub _100sats: AddrOutputsRealizedSupplyPattern, - pub _1k_sats: AddrOutputsRealizedSupplyPattern, - pub _10k_sats: AddrOutputsRealizedSupplyPattern, - pub _100k_sats: AddrOutputsRealizedSupplyPattern, - pub _1m_sats: AddrOutputsRealizedSupplyPattern, - pub _10m_sats: AddrOutputsRealizedSupplyPattern, - pub _1btc: AddrOutputsRealizedSupplyPattern, - pub _10btc: AddrOutputsRealizedSupplyPattern, - pub _100btc: AddrOutputsRealizedSupplyPattern, - pub _1k_btc: AddrOutputsRealizedSupplyPattern, - pub _10k_btc: AddrOutputsRealizedSupplyPattern, -} - -impl MetricsTree_Distribution_AddressCohorts_GeAmount { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - _1sat: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_1sat".to_string()), - _10sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_10sats".to_string()), - _100sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_100sats".to_string()), - _1k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_1k_sats".to_string()), - _10k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_10k_sats".to_string()), - _100k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_100k_sats".to_string()), - _1m_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_1m_sats".to_string()), - _10m_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_10m_sats".to_string()), - _1btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_1btc".to_string()), - _10btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_10btc".to_string()), - _100btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_100btc".to_string()), - _1k_btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_1k_btc".to_string()), - _10k_btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_10k_btc".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_AddressCohorts_AmountRange { - pub _0sats: AddrOutputsRealizedSupplyPattern, - pub _1sat_to_10sats: AddrOutputsRealizedSupplyPattern, - pub _10sats_to_100sats: AddrOutputsRealizedSupplyPattern, - pub _100sats_to_1k_sats: AddrOutputsRealizedSupplyPattern, - pub _1k_sats_to_10k_sats: AddrOutputsRealizedSupplyPattern, - pub _10k_sats_to_100k_sats: AddrOutputsRealizedSupplyPattern, - pub _100k_sats_to_1m_sats: AddrOutputsRealizedSupplyPattern, - pub _1m_sats_to_10m_sats: AddrOutputsRealizedSupplyPattern, - pub _10m_sats_to_1btc: AddrOutputsRealizedSupplyPattern, - pub _1btc_to_10btc: AddrOutputsRealizedSupplyPattern, - pub _10btc_to_100btc: AddrOutputsRealizedSupplyPattern, - pub _100btc_to_1k_btc: AddrOutputsRealizedSupplyPattern, - pub _1k_btc_to_10k_btc: AddrOutputsRealizedSupplyPattern, - pub _10k_btc_to_100k_btc: AddrOutputsRealizedSupplyPattern, - pub _100k_btc_or_more: AddrOutputsRealizedSupplyPattern, -} - -impl MetricsTree_Distribution_AddressCohorts_AmountRange { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - _0sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_with_0sats".to_string()), - _1sat_to_10sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_1sat_under_10sats".to_string()), - _10sats_to_100sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_10sats_under_100sats".to_string()), - _100sats_to_1k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_100sats_under_1k_sats".to_string()), - _1k_sats_to_10k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_1k_sats_under_10k_sats".to_string()), - _10k_sats_to_100k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_10k_sats_under_100k_sats".to_string()), - _100k_sats_to_1m_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_100k_sats_under_1m_sats".to_string()), - _1m_sats_to_10m_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_1m_sats_under_10m_sats".to_string()), - _10m_sats_to_1btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_10m_sats_under_1btc".to_string()), - _1btc_to_10btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_1btc_under_10btc".to_string()), - _10btc_to_100btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_10btc_under_100btc".to_string()), - _100btc_to_1k_btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_100btc_under_1k_btc".to_string()), - _1k_btc_to_10k_btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_1k_btc_under_10k_btc".to_string()), - _10k_btc_to_100k_btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_10k_btc_under_100k_btc".to_string()), - _100k_btc_or_more: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_100k_btc".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_AddressCohorts_LtAmount { - pub _10sats: AddrOutputsRealizedSupplyPattern, - pub _100sats: AddrOutputsRealizedSupplyPattern, - pub _1k_sats: AddrOutputsRealizedSupplyPattern, - pub _10k_sats: AddrOutputsRealizedSupplyPattern, - pub _100k_sats: AddrOutputsRealizedSupplyPattern, - pub _1m_sats: AddrOutputsRealizedSupplyPattern, - pub _10m_sats: AddrOutputsRealizedSupplyPattern, - pub _1btc: AddrOutputsRealizedSupplyPattern, - pub _10btc: AddrOutputsRealizedSupplyPattern, - pub _100btc: AddrOutputsRealizedSupplyPattern, - pub _1k_btc: AddrOutputsRealizedSupplyPattern, - pub _10k_btc: AddrOutputsRealizedSupplyPattern, - pub _100k_btc: AddrOutputsRealizedSupplyPattern, -} - -impl MetricsTree_Distribution_AddressCohorts_LtAmount { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - _10sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_10sats".to_string()), - _100sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_100sats".to_string()), - _1k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_1k_sats".to_string()), - _10k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_10k_sats".to_string()), - _100k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_100k_sats".to_string()), - _1m_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_1m_sats".to_string()), - _10m_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_10m_sats".to_string()), - _1btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_1btc".to_string()), - _10btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_10btc".to_string()), - _100btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_100btc".to_string()), - _1k_btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_1k_btc".to_string()), - _10k_btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_10k_btc".to_string()), - _100k_btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_100k_btc".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Distribution_Addresses { - pub funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3, - pub empty: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3, - pub activity: MetricsTree_Distribution_Addresses_Activity, - pub total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3, - pub new: MetricsTree_Distribution_Addresses_New, - pub delta: MetricsTree_Distribution_Addresses_Delta, - pub funded_index: MetricPattern34, - pub empty_index: MetricPattern35, -} - -impl MetricsTree_Distribution_Addresses { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3::new(client.clone(), "addr_count".to_string()), - empty: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3::new(client.clone(), "empty_addr_count".to_string()), - activity: MetricsTree_Distribution_Addresses_Activity::new(client.clone(), format!("{base_path}_activity")), - total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3::new(client.clone(), "total_addr_count".to_string()), - new: MetricsTree_Distribution_Addresses_New::new(client.clone(), format!("{base_path}_new")), - delta: MetricsTree_Distribution_Addresses_Delta::new(client.clone(), format!("{base_path}_delta")), - funded_index: MetricPattern34::new(client.clone(), "funded_address_index".to_string()), - empty_index: MetricPattern35::new(client.clone(), "empty_address_index".to_string()), - } - } -} - /// Metrics tree node. pub struct MetricsTree_Distribution_Addresses_Activity { pub all: BothReactivatedReceivingSendingPattern, @@ -7406,58 +6648,1064 @@ impl MetricsTree_Distribution_Addresses_Activity { /// Metrics tree node. pub struct MetricsTree_Distribution_Addresses_New { - pub all: RawSumPattern3, - pub p2pk65: RawSumPattern3, - pub p2pk33: RawSumPattern3, - pub p2pkh: RawSumPattern3, - pub p2sh: RawSumPattern3, - pub p2wpkh: RawSumPattern3, - pub p2wsh: RawSumPattern3, - pub p2tr: RawSumPattern3, - pub p2a: RawSumPattern3, + pub all: RawSumPattern, + pub p2pk65: RawSumPattern, + pub p2pk33: RawSumPattern, + pub p2pkh: RawSumPattern, + pub p2sh: RawSumPattern, + pub p2wpkh: RawSumPattern, + pub p2wsh: RawSumPattern, + pub p2tr: RawSumPattern, + pub p2a: RawSumPattern, } impl MetricsTree_Distribution_Addresses_New { pub fn new(client: Arc, base_path: String) -> Self { Self { - all: RawSumPattern3::new(client.clone(), "new_addr_count".to_string()), - p2pk65: RawSumPattern3::new(client.clone(), "p2pk65_new_addr_count".to_string()), - p2pk33: RawSumPattern3::new(client.clone(), "p2pk33_new_addr_count".to_string()), - p2pkh: RawSumPattern3::new(client.clone(), "p2pkh_new_addr_count".to_string()), - p2sh: RawSumPattern3::new(client.clone(), "p2sh_new_addr_count".to_string()), - p2wpkh: RawSumPattern3::new(client.clone(), "p2wpkh_new_addr_count".to_string()), - p2wsh: RawSumPattern3::new(client.clone(), "p2wsh_new_addr_count".to_string()), - p2tr: RawSumPattern3::new(client.clone(), "p2tr_new_addr_count".to_string()), - p2a: RawSumPattern3::new(client.clone(), "p2a_new_addr_count".to_string()), + all: RawSumPattern::new(client.clone(), "new_addr_count".to_string()), + p2pk65: RawSumPattern::new(client.clone(), "p2pk65_new_addr_count".to_string()), + p2pk33: RawSumPattern::new(client.clone(), "p2pk33_new_addr_count".to_string()), + p2pkh: RawSumPattern::new(client.clone(), "p2pkh_new_addr_count".to_string()), + p2sh: RawSumPattern::new(client.clone(), "p2sh_new_addr_count".to_string()), + p2wpkh: RawSumPattern::new(client.clone(), "p2wpkh_new_addr_count".to_string()), + p2wsh: RawSumPattern::new(client.clone(), "p2wsh_new_addr_count".to_string()), + p2tr: RawSumPattern::new(client.clone(), "p2tr_new_addr_count".to_string()), + p2a: RawSumPattern::new(client.clone(), "p2a_new_addr_count".to_string()), } } } /// Metrics tree node. pub struct MetricsTree_Distribution_Addresses_Delta { - 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, + 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, } impl MetricsTree_Distribution_Addresses_Delta { pub fn new(client: Arc, base_path: String) -> Self { Self { - 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()), + 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()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts { + pub utxo: MetricsTree_Distribution_Cohorts_Utxo, + pub address: MetricsTree_Distribution_Cohorts_Address, +} + +impl MetricsTree_Distribution_Cohorts { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + utxo: MetricsTree_Distribution_Cohorts_Utxo::new(client.clone(), format!("{base_path}_utxo")), + address: MetricsTree_Distribution_Cohorts_Address::new(client.clone(), format!("{base_path}_address")), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo { + pub all: MetricsTree_Distribution_Cohorts_Utxo_All, + pub sth: MetricsTree_Distribution_Cohorts_Utxo_Sth, + pub lth: MetricsTree_Distribution_Cohorts_Utxo_Lth, + pub age_range: MetricsTree_Distribution_Cohorts_Utxo_AgeRange, + pub max_age: MetricsTree_Distribution_Cohorts_Utxo_MaxAge, + pub min_age: MetricsTree_Distribution_Cohorts_Utxo_MinAge, + pub epoch: MetricsTree_Distribution_Cohorts_Utxo_Epoch, + pub class: MetricsTree_Distribution_Cohorts_Utxo_Class, + pub ge_amount: MetricsTree_Distribution_Cohorts_Utxo_GeAmount, + pub amount_range: MetricsTree_Distribution_Cohorts_Utxo_AmountRange, + pub lt_amount: MetricsTree_Distribution_Cohorts_Utxo_LtAmount, + pub r#type: MetricsTree_Distribution_Cohorts_Utxo_Type, + pub profitability: MetricsTree_Distribution_Cohorts_Utxo_Profitability, + pub matured: MetricsTree_Distribution_Cohorts_Utxo_Matured, +} + +impl MetricsTree_Distribution_Cohorts_Utxo { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + all: MetricsTree_Distribution_Cohorts_Utxo_All::new(client.clone(), format!("{base_path}_all")), + sth: MetricsTree_Distribution_Cohorts_Utxo_Sth::new(client.clone(), format!("{base_path}_sth")), + lth: MetricsTree_Distribution_Cohorts_Utxo_Lth::new(client.clone(), format!("{base_path}_lth")), + age_range: MetricsTree_Distribution_Cohorts_Utxo_AgeRange::new(client.clone(), format!("{base_path}_age_range")), + max_age: MetricsTree_Distribution_Cohorts_Utxo_MaxAge::new(client.clone(), format!("{base_path}_max_age")), + min_age: MetricsTree_Distribution_Cohorts_Utxo_MinAge::new(client.clone(), format!("{base_path}_min_age")), + epoch: MetricsTree_Distribution_Cohorts_Utxo_Epoch::new(client.clone(), format!("{base_path}_epoch")), + class: MetricsTree_Distribution_Cohorts_Utxo_Class::new(client.clone(), format!("{base_path}_class")), + ge_amount: MetricsTree_Distribution_Cohorts_Utxo_GeAmount::new(client.clone(), format!("{base_path}_ge_amount")), + amount_range: MetricsTree_Distribution_Cohorts_Utxo_AmountRange::new(client.clone(), format!("{base_path}_amount_range")), + lt_amount: MetricsTree_Distribution_Cohorts_Utxo_LtAmount::new(client.clone(), format!("{base_path}_lt_amount")), + r#type: MetricsTree_Distribution_Cohorts_Utxo_Type::new(client.clone(), format!("{base_path}_type")), + profitability: MetricsTree_Distribution_Cohorts_Utxo_Profitability::new(client.clone(), format!("{base_path}_profitability")), + matured: MetricsTree_Distribution_Cohorts_Utxo_Matured::new(client.clone(), format!("{base_path}_matured")), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_All { + pub supply: MetricsTree_Distribution_Cohorts_Utxo_All_Supply, + pub outputs: UnspentPattern3, + pub activity: CoindaysCoinyearsDormancySentVelocityPattern, + pub realized: CapGrossInvestorLossMvrvNetNuplPeakPriceProfitSoprPattern, + pub cost_basis: InvestedMaxMinPercentilesSupplyPattern, + pub unrealized: MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_All { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + supply: MetricsTree_Distribution_Cohorts_Utxo_All_Supply::new(client.clone(), format!("{base_path}_supply")), + outputs: UnspentPattern3::new(client.clone(), "utxo_count".to_string()), + activity: CoindaysCoinyearsDormancySentVelocityPattern::new(client.clone(), "".to_string()), + realized: CapGrossInvestorLossMvrvNetNuplPeakPriceProfitSoprPattern::new(client.clone(), "".to_string()), + cost_basis: InvestedMaxMinPercentilesSupplyPattern::new(client.clone(), "".to_string()), + unrealized: MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized::new(client.clone(), format!("{base_path}_unrealized")), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_All_Supply { + pub delta: ChangeRatePattern, + pub in_profit: BtcCentsRelSatsUsdPattern2, + pub in_loss: BtcCentsRelSatsUsdPattern2, + pub total: BtcCentsSatsUsdPattern, + pub halved: BtcCentsSatsUsdPattern, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_All_Supply { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + delta: ChangeRatePattern::new(client.clone(), "supply_delta".to_string()), + in_profit: BtcCentsRelSatsUsdPattern2::new(client.clone(), "supply_in_profit".to_string()), + in_loss: BtcCentsRelSatsUsdPattern2::new(client.clone(), "supply_in_loss".to_string()), + total: BtcCentsSatsUsdPattern::new(client.clone(), "supply".to_string()), + halved: BtcCentsSatsUsdPattern::new(client.clone(), "supply_halved".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized { + pub gross_pnl: CentsUsdPattern, + pub invested_capital: InPattern2, + pub sentiment: GreedNetPainPattern, + pub investor_cap: InPattern, + pub loss: MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Loss, + pub net_pnl: MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_NetPnl, + pub profit: MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Profit, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + gross_pnl: CentsUsdPattern::new(client.clone(), "unrealized_gross_pnl".to_string()), + invested_capital: InPattern2::new(client.clone(), "invested_capital_in".to_string()), + sentiment: GreedNetPainPattern::new(client.clone(), "".to_string()), + investor_cap: InPattern::new(client.clone(), "investor_cap_in".to_string()), + loss: MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Loss::new(client.clone(), format!("{base_path}_loss")), + net_pnl: MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_NetPnl::new(client.clone(), format!("{base_path}_net_pnl")), + profit: MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Profit::new(client.clone(), format!("{base_path}_profit")), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Loss { + pub negative: MetricPattern1, + pub raw: CentsUsdPattern, + pub sum: _24hPattern, + pub rel_to_market_cap: BpsPercentRatioPattern, + pub rel_to_own_gross: BpsPercentRatioPattern, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Loss { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + negative: MetricPattern1::new(client.clone(), "neg_unrealized_loss".to_string()), + raw: CentsUsdPattern::new(client.clone(), "unrealized_loss".to_string()), + sum: _24hPattern::new(client.clone(), "unrealized_loss_24h".to_string()), + rel_to_market_cap: BpsPercentRatioPattern::new(client.clone(), "unrealized_loss_rel_to_market_cap".to_string()), + rel_to_own_gross: BpsPercentRatioPattern::new(client.clone(), "unrealized_loss_rel_to_own_gross_pnl".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_NetPnl { + pub cents: MetricPattern1, + pub usd: MetricPattern1, + pub rel_to_own_gross: BpsPercentRatioPattern, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_NetPnl { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + cents: MetricPattern1::new(client.clone(), "net_unrealized_pnl_cents".to_string()), + usd: MetricPattern1::new(client.clone(), "net_unrealized_pnl".to_string()), + rel_to_own_gross: BpsPercentRatioPattern::new(client.clone(), "net_unrealized_pnl_rel_to_own_gross_pnl".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Profit { + pub raw: CentsUsdPattern, + pub sum: _24hPattern, + pub rel_to_market_cap: BpsPercentRatioPattern, + pub rel_to_own_gross: BpsPercentRatioPattern, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Profit { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + raw: CentsUsdPattern::new(client.clone(), "unrealized_profit".to_string()), + sum: _24hPattern::new(client.clone(), "unrealized_profit_24h".to_string()), + rel_to_market_cap: BpsPercentRatioPattern::new(client.clone(), "unrealized_profit_rel_to_market_cap".to_string()), + rel_to_own_gross: BpsPercentRatioPattern::new(client.clone(), "unrealized_profit_rel_to_own_gross_pnl".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_Sth { + pub realized: CapGrossInvestorLossMvrvNetNuplPeakPriceProfitSoprPattern, + pub supply: DeltaHalvedInRelTotalPattern2, + pub outputs: UnspentPattern3, + pub activity: CoindaysCoinyearsDormancySentVelocityPattern, + pub cost_basis: InvestedMaxMinPercentilesSupplyPattern, + pub unrealized: GrossInvestedInvestorLossNetProfitSentimentPattern2, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_Sth { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + realized: CapGrossInvestorLossMvrvNetNuplPeakPriceProfitSoprPattern::new(client.clone(), "sth".to_string()), + supply: DeltaHalvedInRelTotalPattern2::new(client.clone(), "sth_supply".to_string()), + outputs: UnspentPattern3::new(client.clone(), "sth_utxo_count".to_string()), + activity: CoindaysCoinyearsDormancySentVelocityPattern::new(client.clone(), "sth".to_string()), + cost_basis: InvestedMaxMinPercentilesSupplyPattern::new(client.clone(), "sth".to_string()), + unrealized: GrossInvestedInvestorLossNetProfitSentimentPattern2::new(client.clone(), "sth".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_Lth { + pub supply: DeltaHalvedInRelTotalPattern2, + pub outputs: UnspentPattern3, + pub activity: CoindaysCoinyearsDormancySentVelocityPattern, + pub realized: MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized, + pub cost_basis: InvestedMaxMinPercentilesSupplyPattern, + pub unrealized: GrossInvestedInvestorLossNetProfitSentimentPattern2, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_Lth { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + supply: DeltaHalvedInRelTotalPattern2::new(client.clone(), "lth_supply".to_string()), + outputs: UnspentPattern3::new(client.clone(), "lth_utxo_count".to_string()), + activity: CoindaysCoinyearsDormancySentVelocityPattern::new(client.clone(), "lth".to_string()), + realized: MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized::new(client.clone(), format!("{base_path}_realized")), + cost_basis: InvestedMaxMinPercentilesSupplyPattern::new(client.clone(), "lth".to_string()), + unrealized: GrossInvestedInvestorLossNetProfitSentimentPattern2::new(client.clone(), "lth".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized { + pub profit: CumulativeDistributionRawRelSumValuePattern, + pub loss: CapitulationCumulativeNegativeRawRelSumValuePattern, + pub gross_pnl: RawSellSumPattern, + pub net_pnl: ChangeCumulativeDeltaRawRelSumPattern, + pub sopr: MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr, + pub peak_regret: CumulativeRawRelPattern, + pub investor: CapLowerPriceUpperPattern, + pub profit_to_loss_ratio: _1m1w1y24hPattern, + pub cap: CentsDeltaRawRelUsdPattern, + pub price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern, + pub mvrv: MetricPattern1, + pub nupl: BpsRatioPattern, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + profit: CumulativeDistributionRawRelSumValuePattern::new(client.clone(), "lth".to_string()), + loss: CapitulationCumulativeNegativeRawRelSumValuePattern::new(client.clone(), "lth".to_string()), + gross_pnl: RawSellSumPattern::new(client.clone(), "lth".to_string()), + net_pnl: ChangeCumulativeDeltaRawRelSumPattern::new(client.clone(), "lth_net".to_string()), + sopr: MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr::new(client.clone(), format!("{base_path}_sopr")), + peak_regret: CumulativeRawRelPattern::new(client.clone(), "lth_realized_peak_regret".to_string()), + investor: CapLowerPriceUpperPattern::new(client.clone(), "lth".to_string()), + profit_to_loss_ratio: _1m1w1y24hPattern::new(client.clone(), "lth_realized_profit_to_loss_ratio".to_string()), + cap: CentsDeltaRawRelUsdPattern::new(client.clone(), "lth".to_string()), + price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern::new(client.clone(), "lth_realized_price".to_string()), + mvrv: MetricPattern1::new(client.clone(), "lth_mvrv".to_string()), + nupl: BpsRatioPattern::new(client.clone(), "lth_nupl_ratio".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr { + pub value_created: MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueCreated, + pub value_destroyed: MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueDestroyed, + pub ratio: _1m1w1y24hPattern, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + value_created: MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueCreated::new(client.clone(), format!("{base_path}_value_created")), + value_destroyed: MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueDestroyed::new(client.clone(), format!("{base_path}_value_destroyed")), + ratio: _1m1w1y24hPattern::new(client.clone(), "lth_sopr".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueCreated { + pub sum: _1m1w1y24hPattern, + pub raw: MetricPattern1, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueCreated { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + sum: _1m1w1y24hPattern::new(client.clone(), "lth_value_created".to_string()), + raw: MetricPattern1::new(client.clone(), "lth_value_created".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueDestroyed { + pub sum: _1m1w1y24hPattern, + pub raw: MetricPattern1, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueDestroyed { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + sum: _1m1w1y24hPattern::new(client.clone(), "lth_value_destroyed".to_string()), + raw: MetricPattern1::new(client.clone(), "lth_value_destroyed".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_AgeRange { + pub up_to_1h: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _1h_to_1d: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _1d_to_1w: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _1w_to_1m: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _1m_to_2m: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _2m_to_3m: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _3m_to_4m: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _4m_to_5m: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _5m_to_6m: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _6m_to_1y: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _1y_to_2y: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _2y_to_3y: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _3y_to_4y: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _4y_to_5y: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _5y_to_6y: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _6y_to_7y: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _7y_to_8y: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _8y_to_10y: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _10y_to_12y: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub _12y_to_15y: ActivityOutputsRealizedSupplyUnrealizedPattern, + pub from_15y: ActivityOutputsRealizedSupplyUnrealizedPattern, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_AgeRange { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + up_to_1h: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_under_1h_old".to_string()), + _1h_to_1d: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_1h_to_1d_old".to_string()), + _1d_to_1w: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_1d_to_1w_old".to_string()), + _1w_to_1m: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_1w_to_1m_old".to_string()), + _1m_to_2m: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_1m_to_2m_old".to_string()), + _2m_to_3m: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_2m_to_3m_old".to_string()), + _3m_to_4m: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_3m_to_4m_old".to_string()), + _4m_to_5m: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_4m_to_5m_old".to_string()), + _5m_to_6m: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_5m_to_6m_old".to_string()), + _6m_to_1y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_6m_to_1y_old".to_string()), + _1y_to_2y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_1y_to_2y_old".to_string()), + _2y_to_3y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_2y_to_3y_old".to_string()), + _3y_to_4y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_3y_to_4y_old".to_string()), + _4y_to_5y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_4y_to_5y_old".to_string()), + _5y_to_6y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_5y_to_6y_old".to_string()), + _6y_to_7y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_6y_to_7y_old".to_string()), + _7y_to_8y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_7y_to_8y_old".to_string()), + _8y_to_10y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_8y_to_10y_old".to_string()), + _10y_to_12y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_10y_to_12y_old".to_string()), + _12y_to_15y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_12y_to_15y_old".to_string()), + from_15y: ActivityOutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "utxos_over_15y_old".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_MaxAge { + pub _1w: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _1m: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2m: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _3m: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _4m: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _5m: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _6m: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _1y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _3y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _4y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _5y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _6y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _7y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _8y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _10y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _12y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _15y: ActivityOutputsRealizedSupplyUnrealizedPattern2, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_MaxAge { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + _1w: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_1w_old".to_string()), + _1m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_1m_old".to_string()), + _2m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_2m_old".to_string()), + _3m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_3m_old".to_string()), + _4m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_4m_old".to_string()), + _5m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_5m_old".to_string()), + _6m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_6m_old".to_string()), + _1y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_1y_old".to_string()), + _2y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_2y_old".to_string()), + _3y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_3y_old".to_string()), + _4y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_4y_old".to_string()), + _5y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_5y_old".to_string()), + _6y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_6y_old".to_string()), + _7y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_7y_old".to_string()), + _8y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_8y_old".to_string()), + _10y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_10y_old".to_string()), + _12y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_12y_old".to_string()), + _15y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_15y_old".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_MinAge { + pub _1d: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _1w: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _1m: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2m: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _3m: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _4m: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _5m: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _6m: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _1y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _3y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _4y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _5y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _6y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _7y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _8y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _10y: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _12y: ActivityOutputsRealizedSupplyUnrealizedPattern2, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_MinAge { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + _1d: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_1d_old".to_string()), + _1w: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_1w_old".to_string()), + _1m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_1m_old".to_string()), + _2m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_2m_old".to_string()), + _3m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_3m_old".to_string()), + _4m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_4m_old".to_string()), + _5m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_5m_old".to_string()), + _6m: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_6m_old".to_string()), + _1y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_1y_old".to_string()), + _2y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_2y_old".to_string()), + _3y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_3y_old".to_string()), + _4y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_4y_old".to_string()), + _5y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_5y_old".to_string()), + _6y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_6y_old".to_string()), + _7y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_7y_old".to_string()), + _8y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_8y_old".to_string()), + _10y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_10y_old".to_string()), + _12y: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_12y_old".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_Epoch { + pub _0: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _1: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _3: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _4: ActivityOutputsRealizedSupplyUnrealizedPattern2, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_Epoch { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + _0: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "epoch_0".to_string()), + _1: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "epoch_1".to_string()), + _2: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "epoch_2".to_string()), + _3: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "epoch_3".to_string()), + _4: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "epoch_4".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_Class { + pub _2009: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2010: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2011: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2012: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2013: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2014: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2015: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2016: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2017: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2018: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2019: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2020: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2021: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2022: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2023: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2024: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2025: ActivityOutputsRealizedSupplyUnrealizedPattern2, + pub _2026: ActivityOutputsRealizedSupplyUnrealizedPattern2, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_Class { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + _2009: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2009".to_string()), + _2010: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2010".to_string()), + _2011: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2011".to_string()), + _2012: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2012".to_string()), + _2013: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2013".to_string()), + _2014: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2014".to_string()), + _2015: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2015".to_string()), + _2016: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2016".to_string()), + _2017: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2017".to_string()), + _2018: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2018".to_string()), + _2019: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2019".to_string()), + _2020: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2020".to_string()), + _2021: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2021".to_string()), + _2022: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2022".to_string()), + _2023: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2023".to_string()), + _2024: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2024".to_string()), + _2025: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2025".to_string()), + _2026: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "class_2026".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_GeAmount { + pub _1sat: OutputsRealizedSupplyPattern, + pub _10sats: OutputsRealizedSupplyPattern, + pub _100sats: OutputsRealizedSupplyPattern, + pub _1k_sats: OutputsRealizedSupplyPattern, + pub _10k_sats: OutputsRealizedSupplyPattern, + pub _100k_sats: OutputsRealizedSupplyPattern, + pub _1m_sats: OutputsRealizedSupplyPattern, + pub _10m_sats: OutputsRealizedSupplyPattern, + pub _1btc: OutputsRealizedSupplyPattern, + pub _10btc: OutputsRealizedSupplyPattern, + pub _100btc: OutputsRealizedSupplyPattern, + pub _1k_btc: OutputsRealizedSupplyPattern, + pub _10k_btc: OutputsRealizedSupplyPattern, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_GeAmount { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + _1sat: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_1sat".to_string()), + _10sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_10sats".to_string()), + _100sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_100sats".to_string()), + _1k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_1k_sats".to_string()), + _10k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_10k_sats".to_string()), + _100k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_100k_sats".to_string()), + _1m_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_1m_sats".to_string()), + _10m_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_10m_sats".to_string()), + _1btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_1btc".to_string()), + _10btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_10btc".to_string()), + _100btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_100btc".to_string()), + _1k_btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_1k_btc".to_string()), + _10k_btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_10k_btc".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_AmountRange { + pub _0sats: OutputsRealizedSupplyPattern, + pub _1sat_to_10sats: OutputsRealizedSupplyPattern, + pub _10sats_to_100sats: OutputsRealizedSupplyPattern, + pub _100sats_to_1k_sats: OutputsRealizedSupplyPattern, + pub _1k_sats_to_10k_sats: OutputsRealizedSupplyPattern, + pub _10k_sats_to_100k_sats: OutputsRealizedSupplyPattern, + pub _100k_sats_to_1m_sats: OutputsRealizedSupplyPattern, + pub _1m_sats_to_10m_sats: OutputsRealizedSupplyPattern, + pub _10m_sats_to_1btc: OutputsRealizedSupplyPattern, + pub _1btc_to_10btc: OutputsRealizedSupplyPattern, + pub _10btc_to_100btc: OutputsRealizedSupplyPattern, + pub _100btc_to_1k_btc: OutputsRealizedSupplyPattern, + pub _1k_btc_to_10k_btc: OutputsRealizedSupplyPattern, + pub _10k_btc_to_100k_btc: OutputsRealizedSupplyPattern, + pub _100k_btc_or_more: OutputsRealizedSupplyPattern, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_AmountRange { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + _0sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_with_0sats".to_string()), + _1sat_to_10sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_1sat_under_10sats".to_string()), + _10sats_to_100sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_10sats_under_100sats".to_string()), + _100sats_to_1k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_100sats_under_1k_sats".to_string()), + _1k_sats_to_10k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_1k_sats_under_10k_sats".to_string()), + _10k_sats_to_100k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_10k_sats_under_100k_sats".to_string()), + _100k_sats_to_1m_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_100k_sats_under_1m_sats".to_string()), + _1m_sats_to_10m_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_1m_sats_under_10m_sats".to_string()), + _10m_sats_to_1btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_10m_sats_under_1btc".to_string()), + _1btc_to_10btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_1btc_under_10btc".to_string()), + _10btc_to_100btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_10btc_under_100btc".to_string()), + _100btc_to_1k_btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_100btc_under_1k_btc".to_string()), + _1k_btc_to_10k_btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_1k_btc_under_10k_btc".to_string()), + _10k_btc_to_100k_btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_10k_btc_under_100k_btc".to_string()), + _100k_btc_or_more: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_above_100k_btc".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_LtAmount { + pub _10sats: OutputsRealizedSupplyPattern, + pub _100sats: OutputsRealizedSupplyPattern, + pub _1k_sats: OutputsRealizedSupplyPattern, + pub _10k_sats: OutputsRealizedSupplyPattern, + pub _100k_sats: OutputsRealizedSupplyPattern, + pub _1m_sats: OutputsRealizedSupplyPattern, + pub _10m_sats: OutputsRealizedSupplyPattern, + pub _1btc: OutputsRealizedSupplyPattern, + pub _10btc: OutputsRealizedSupplyPattern, + pub _100btc: OutputsRealizedSupplyPattern, + pub _1k_btc: OutputsRealizedSupplyPattern, + pub _10k_btc: OutputsRealizedSupplyPattern, + pub _100k_btc: OutputsRealizedSupplyPattern, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_LtAmount { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + _10sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_10sats".to_string()), + _100sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_100sats".to_string()), + _1k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_1k_sats".to_string()), + _10k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_10k_sats".to_string()), + _100k_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_100k_sats".to_string()), + _1m_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_1m_sats".to_string()), + _10m_sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_10m_sats".to_string()), + _1btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_1btc".to_string()), + _10btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_10btc".to_string()), + _100btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_100btc".to_string()), + _1k_btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_1k_btc".to_string()), + _10k_btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_10k_btc".to_string()), + _100k_btc: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_100k_btc".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_Type { + pub p2pk65: OutputsRealizedSupplyUnrealizedPattern, + pub p2pk33: OutputsRealizedSupplyUnrealizedPattern, + pub p2pkh: OutputsRealizedSupplyUnrealizedPattern, + pub p2ms: OutputsRealizedSupplyUnrealizedPattern, + pub p2sh: OutputsRealizedSupplyUnrealizedPattern, + pub p2wpkh: OutputsRealizedSupplyUnrealizedPattern, + pub p2wsh: OutputsRealizedSupplyUnrealizedPattern, + pub p2tr: OutputsRealizedSupplyUnrealizedPattern, + pub p2a: OutputsRealizedSupplyUnrealizedPattern, + pub unknown: OutputsRealizedSupplyUnrealizedPattern, + pub empty: OutputsRealizedSupplyUnrealizedPattern, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_Type { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + p2pk65: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2pk65".to_string()), + p2pk33: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2pk33".to_string()), + p2pkh: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2pkh".to_string()), + p2ms: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2ms".to_string()), + p2sh: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2sh".to_string()), + p2wpkh: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2wpkh".to_string()), + p2wsh: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2wsh".to_string()), + p2tr: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2tr".to_string()), + p2a: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "p2a".to_string()), + unknown: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "unknown_outputs".to_string()), + empty: OutputsRealizedSupplyUnrealizedPattern::new(client.clone(), "empty_outputs".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_Profitability { + pub range: MetricsTree_Distribution_Cohorts_Utxo_Profitability_Range, + pub profit: MetricsTree_Distribution_Cohorts_Utxo_Profitability_Profit, + pub loss: MetricsTree_Distribution_Cohorts_Utxo_Profitability_Loss, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_Profitability { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + range: MetricsTree_Distribution_Cohorts_Utxo_Profitability_Range::new(client.clone(), format!("{base_path}_range")), + profit: MetricsTree_Distribution_Cohorts_Utxo_Profitability_Profit::new(client.clone(), format!("{base_path}_profit")), + loss: MetricsTree_Distribution_Cohorts_Utxo_Profitability_Loss::new(client.clone(), format!("{base_path}_loss")), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_Profitability_Range { + pub profit_over_1000: RealizedSupplyPattern, + pub profit_500_to_1000: RealizedSupplyPattern, + pub profit_300_to_500: RealizedSupplyPattern, + pub profit_200_to_300: RealizedSupplyPattern, + pub profit_100_to_200: RealizedSupplyPattern, + pub profit_90_to_100: RealizedSupplyPattern, + pub profit_80_to_90: RealizedSupplyPattern, + pub profit_70_to_80: RealizedSupplyPattern, + pub profit_60_to_70: RealizedSupplyPattern, + pub profit_50_to_60: RealizedSupplyPattern, + pub profit_40_to_50: RealizedSupplyPattern, + pub profit_30_to_40: RealizedSupplyPattern, + pub profit_20_to_30: RealizedSupplyPattern, + pub profit_10_to_20: RealizedSupplyPattern, + pub profit_0_to_10: RealizedSupplyPattern, + pub loss_0_to_10: RealizedSupplyPattern, + pub loss_10_to_20: RealizedSupplyPattern, + pub loss_20_to_30: RealizedSupplyPattern, + pub loss_30_to_40: RealizedSupplyPattern, + pub loss_40_to_50: RealizedSupplyPattern, + pub loss_50_to_60: RealizedSupplyPattern, + pub loss_60_to_70: RealizedSupplyPattern, + pub loss_70_to_80: RealizedSupplyPattern, + pub loss_80_to_90: RealizedSupplyPattern, + pub loss_90_to_100: RealizedSupplyPattern, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_Profitability_Range { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + profit_over_1000: RealizedSupplyPattern::new(client.clone(), "utxos_over_1000pct_up".to_string()), + profit_500_to_1000: RealizedSupplyPattern::new(client.clone(), "utxos_500pct_to_1000pct_up".to_string()), + profit_300_to_500: RealizedSupplyPattern::new(client.clone(), "utxos_300pct_to_500pct_up".to_string()), + profit_200_to_300: RealizedSupplyPattern::new(client.clone(), "utxos_200pct_to_300pct_up".to_string()), + profit_100_to_200: RealizedSupplyPattern::new(client.clone(), "utxos_100pct_to_200pct_up".to_string()), + profit_90_to_100: RealizedSupplyPattern::new(client.clone(), "utxos_90pct_to_100pct_up".to_string()), + profit_80_to_90: RealizedSupplyPattern::new(client.clone(), "utxos_80pct_to_90pct_up".to_string()), + profit_70_to_80: RealizedSupplyPattern::new(client.clone(), "utxos_70pct_to_80pct_up".to_string()), + profit_60_to_70: RealizedSupplyPattern::new(client.clone(), "utxos_60pct_to_70pct_up".to_string()), + profit_50_to_60: RealizedSupplyPattern::new(client.clone(), "utxos_50pct_to_60pct_up".to_string()), + profit_40_to_50: RealizedSupplyPattern::new(client.clone(), "utxos_40pct_to_50pct_up".to_string()), + profit_30_to_40: RealizedSupplyPattern::new(client.clone(), "utxos_30pct_to_40pct_up".to_string()), + profit_20_to_30: RealizedSupplyPattern::new(client.clone(), "utxos_20pct_to_30pct_up".to_string()), + profit_10_to_20: RealizedSupplyPattern::new(client.clone(), "utxos_10pct_to_20pct_up".to_string()), + profit_0_to_10: RealizedSupplyPattern::new(client.clone(), "utxos_0pct_to_10pct_up".to_string()), + loss_0_to_10: RealizedSupplyPattern::new(client.clone(), "utxos_0pct_to_10pct_down".to_string()), + loss_10_to_20: RealizedSupplyPattern::new(client.clone(), "utxos_10pct_to_20pct_down".to_string()), + loss_20_to_30: RealizedSupplyPattern::new(client.clone(), "utxos_20pct_to_30pct_down".to_string()), + loss_30_to_40: RealizedSupplyPattern::new(client.clone(), "utxos_30pct_to_40pct_down".to_string()), + loss_40_to_50: RealizedSupplyPattern::new(client.clone(), "utxos_40pct_to_50pct_down".to_string()), + loss_50_to_60: RealizedSupplyPattern::new(client.clone(), "utxos_50pct_to_60pct_down".to_string()), + loss_60_to_70: RealizedSupplyPattern::new(client.clone(), "utxos_60pct_to_70pct_down".to_string()), + loss_70_to_80: RealizedSupplyPattern::new(client.clone(), "utxos_70pct_to_80pct_down".to_string()), + loss_80_to_90: RealizedSupplyPattern::new(client.clone(), "utxos_80pct_to_90pct_down".to_string()), + loss_90_to_100: RealizedSupplyPattern::new(client.clone(), "utxos_90pct_to_100pct_down".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_Profitability_Profit { + pub breakeven: RealizedSupplyPattern, + pub _10pct: RealizedSupplyPattern, + pub _20pct: RealizedSupplyPattern, + pub _30pct: RealizedSupplyPattern, + pub _40pct: RealizedSupplyPattern, + pub _50pct: RealizedSupplyPattern, + pub _60pct: RealizedSupplyPattern, + pub _70pct: RealizedSupplyPattern, + pub _80pct: RealizedSupplyPattern, + pub _90pct: RealizedSupplyPattern, + pub _100pct: RealizedSupplyPattern, + pub _200pct: RealizedSupplyPattern, + pub _300pct: RealizedSupplyPattern, + pub _500pct: RealizedSupplyPattern, + pub _1000pct: RealizedSupplyPattern, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_Profitability_Profit { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + breakeven: RealizedSupplyPattern::new(client.clone(), "profit_ge_breakeven".to_string()), + _10pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_10pct".to_string()), + _20pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_20pct".to_string()), + _30pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_30pct".to_string()), + _40pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_40pct".to_string()), + _50pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_50pct".to_string()), + _60pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_60pct".to_string()), + _70pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_70pct".to_string()), + _80pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_80pct".to_string()), + _90pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_90pct".to_string()), + _100pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_100pct".to_string()), + _200pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_200pct".to_string()), + _300pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_300pct".to_string()), + _500pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_500pct".to_string()), + _1000pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_1000pct".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_Profitability_Loss { + pub breakeven: RealizedSupplyPattern, + pub _10pct: RealizedSupplyPattern, + pub _20pct: RealizedSupplyPattern, + pub _30pct: RealizedSupplyPattern, + pub _40pct: RealizedSupplyPattern, + pub _50pct: RealizedSupplyPattern, + pub _60pct: RealizedSupplyPattern, + pub _70pct: RealizedSupplyPattern, + pub _80pct: RealizedSupplyPattern, + pub _90pct: RealizedSupplyPattern, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_Profitability_Loss { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + breakeven: RealizedSupplyPattern::new(client.clone(), "loss_ge_breakeven".to_string()), + _10pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_10pct".to_string()), + _20pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_20pct".to_string()), + _30pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_30pct".to_string()), + _40pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_40pct".to_string()), + _50pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_50pct".to_string()), + _60pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_60pct".to_string()), + _70pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_70pct".to_string()), + _80pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_80pct".to_string()), + _90pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_90pct".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Utxo_Matured { + pub up_to_1h: BtcCentsSatsUsdPattern, + pub _1h_to_1d: BtcCentsSatsUsdPattern, + pub _1d_to_1w: BtcCentsSatsUsdPattern, + pub _1w_to_1m: BtcCentsSatsUsdPattern, + pub _1m_to_2m: BtcCentsSatsUsdPattern, + pub _2m_to_3m: BtcCentsSatsUsdPattern, + pub _3m_to_4m: BtcCentsSatsUsdPattern, + pub _4m_to_5m: BtcCentsSatsUsdPattern, + pub _5m_to_6m: BtcCentsSatsUsdPattern, + pub _6m_to_1y: BtcCentsSatsUsdPattern, + pub _1y_to_2y: BtcCentsSatsUsdPattern, + pub _2y_to_3y: BtcCentsSatsUsdPattern, + pub _3y_to_4y: BtcCentsSatsUsdPattern, + pub _4y_to_5y: BtcCentsSatsUsdPattern, + pub _5y_to_6y: BtcCentsSatsUsdPattern, + pub _6y_to_7y: BtcCentsSatsUsdPattern, + pub _7y_to_8y: BtcCentsSatsUsdPattern, + pub _8y_to_10y: BtcCentsSatsUsdPattern, + pub _10y_to_12y: BtcCentsSatsUsdPattern, + pub _12y_to_15y: BtcCentsSatsUsdPattern, + pub from_15y: BtcCentsSatsUsdPattern, +} + +impl MetricsTree_Distribution_Cohorts_Utxo_Matured { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + up_to_1h: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_under_1h_old_matured".to_string()), + _1h_to_1d: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_1h_to_1d_old_matured".to_string()), + _1d_to_1w: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_1d_to_1w_old_matured".to_string()), + _1w_to_1m: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_1w_to_1m_old_matured".to_string()), + _1m_to_2m: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_1m_to_2m_old_matured".to_string()), + _2m_to_3m: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_2m_to_3m_old_matured".to_string()), + _3m_to_4m: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_3m_to_4m_old_matured".to_string()), + _4m_to_5m: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_4m_to_5m_old_matured".to_string()), + _5m_to_6m: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_5m_to_6m_old_matured".to_string()), + _6m_to_1y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_6m_to_1y_old_matured".to_string()), + _1y_to_2y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_1y_to_2y_old_matured".to_string()), + _2y_to_3y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_2y_to_3y_old_matured".to_string()), + _3y_to_4y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_3y_to_4y_old_matured".to_string()), + _4y_to_5y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_4y_to_5y_old_matured".to_string()), + _5y_to_6y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_5y_to_6y_old_matured".to_string()), + _6y_to_7y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_6y_to_7y_old_matured".to_string()), + _7y_to_8y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_7y_to_8y_old_matured".to_string()), + _8y_to_10y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_8y_to_10y_old_matured".to_string()), + _10y_to_12y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_10y_to_12y_old_matured".to_string()), + _12y_to_15y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_12y_to_15y_old_matured".to_string()), + from_15y: BtcCentsSatsUsdPattern::new(client.clone(), "utxo_over_15y_old_matured".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Address { + pub ge_amount: MetricsTree_Distribution_Cohorts_Address_GeAmount, + pub amount_range: MetricsTree_Distribution_Cohorts_Address_AmountRange, + pub lt_amount: MetricsTree_Distribution_Cohorts_Address_LtAmount, +} + +impl MetricsTree_Distribution_Cohorts_Address { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + ge_amount: MetricsTree_Distribution_Cohorts_Address_GeAmount::new(client.clone(), format!("{base_path}_ge_amount")), + amount_range: MetricsTree_Distribution_Cohorts_Address_AmountRange::new(client.clone(), format!("{base_path}_amount_range")), + lt_amount: MetricsTree_Distribution_Cohorts_Address_LtAmount::new(client.clone(), format!("{base_path}_lt_amount")), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Address_GeAmount { + pub _1sat: AddrOutputsRealizedSupplyPattern, + pub _10sats: AddrOutputsRealizedSupplyPattern, + pub _100sats: AddrOutputsRealizedSupplyPattern, + pub _1k_sats: AddrOutputsRealizedSupplyPattern, + pub _10k_sats: AddrOutputsRealizedSupplyPattern, + pub _100k_sats: AddrOutputsRealizedSupplyPattern, + pub _1m_sats: AddrOutputsRealizedSupplyPattern, + pub _10m_sats: AddrOutputsRealizedSupplyPattern, + pub _1btc: AddrOutputsRealizedSupplyPattern, + pub _10btc: AddrOutputsRealizedSupplyPattern, + pub _100btc: AddrOutputsRealizedSupplyPattern, + pub _1k_btc: AddrOutputsRealizedSupplyPattern, + pub _10k_btc: AddrOutputsRealizedSupplyPattern, +} + +impl MetricsTree_Distribution_Cohorts_Address_GeAmount { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + _1sat: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_1sat".to_string()), + _10sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_10sats".to_string()), + _100sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_100sats".to_string()), + _1k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_1k_sats".to_string()), + _10k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_10k_sats".to_string()), + _100k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_100k_sats".to_string()), + _1m_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_1m_sats".to_string()), + _10m_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_10m_sats".to_string()), + _1btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_1btc".to_string()), + _10btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_10btc".to_string()), + _100btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_100btc".to_string()), + _1k_btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_1k_btc".to_string()), + _10k_btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_10k_btc".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Address_AmountRange { + pub _0sats: AddrOutputsRealizedSupplyPattern, + pub _1sat_to_10sats: AddrOutputsRealizedSupplyPattern, + pub _10sats_to_100sats: AddrOutputsRealizedSupplyPattern, + pub _100sats_to_1k_sats: AddrOutputsRealizedSupplyPattern, + pub _1k_sats_to_10k_sats: AddrOutputsRealizedSupplyPattern, + pub _10k_sats_to_100k_sats: AddrOutputsRealizedSupplyPattern, + pub _100k_sats_to_1m_sats: AddrOutputsRealizedSupplyPattern, + pub _1m_sats_to_10m_sats: AddrOutputsRealizedSupplyPattern, + pub _10m_sats_to_1btc: AddrOutputsRealizedSupplyPattern, + pub _1btc_to_10btc: AddrOutputsRealizedSupplyPattern, + pub _10btc_to_100btc: AddrOutputsRealizedSupplyPattern, + pub _100btc_to_1k_btc: AddrOutputsRealizedSupplyPattern, + pub _1k_btc_to_10k_btc: AddrOutputsRealizedSupplyPattern, + pub _10k_btc_to_100k_btc: AddrOutputsRealizedSupplyPattern, + pub _100k_btc_or_more: AddrOutputsRealizedSupplyPattern, +} + +impl MetricsTree_Distribution_Cohorts_Address_AmountRange { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + _0sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_with_0sats".to_string()), + _1sat_to_10sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_1sat_under_10sats".to_string()), + _10sats_to_100sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_10sats_under_100sats".to_string()), + _100sats_to_1k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_100sats_under_1k_sats".to_string()), + _1k_sats_to_10k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_1k_sats_under_10k_sats".to_string()), + _10k_sats_to_100k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_10k_sats_under_100k_sats".to_string()), + _100k_sats_to_1m_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_100k_sats_under_1m_sats".to_string()), + _1m_sats_to_10m_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_1m_sats_under_10m_sats".to_string()), + _10m_sats_to_1btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_10m_sats_under_1btc".to_string()), + _1btc_to_10btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_1btc_under_10btc".to_string()), + _10btc_to_100btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_10btc_under_100btc".to_string()), + _100btc_to_1k_btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_100btc_under_1k_btc".to_string()), + _1k_btc_to_10k_btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_1k_btc_under_10k_btc".to_string()), + _10k_btc_to_100k_btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_10k_btc_under_100k_btc".to_string()), + _100k_btc_or_more: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_above_100k_btc".to_string()), + } + } +} + +/// Metrics tree node. +pub struct MetricsTree_Distribution_Cohorts_Address_LtAmount { + pub _10sats: AddrOutputsRealizedSupplyPattern, + pub _100sats: AddrOutputsRealizedSupplyPattern, + pub _1k_sats: AddrOutputsRealizedSupplyPattern, + pub _10k_sats: AddrOutputsRealizedSupplyPattern, + pub _100k_sats: AddrOutputsRealizedSupplyPattern, + pub _1m_sats: AddrOutputsRealizedSupplyPattern, + pub _10m_sats: AddrOutputsRealizedSupplyPattern, + pub _1btc: AddrOutputsRealizedSupplyPattern, + pub _10btc: AddrOutputsRealizedSupplyPattern, + pub _100btc: AddrOutputsRealizedSupplyPattern, + pub _1k_btc: AddrOutputsRealizedSupplyPattern, + pub _10k_btc: AddrOutputsRealizedSupplyPattern, + pub _100k_btc: AddrOutputsRealizedSupplyPattern, +} + +impl MetricsTree_Distribution_Cohorts_Address_LtAmount { + pub fn new(client: Arc, base_path: String) -> Self { + Self { + _10sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_10sats".to_string()), + _100sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_100sats".to_string()), + _1k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_1k_sats".to_string()), + _10k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_10k_sats".to_string()), + _100k_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_100k_sats".to_string()), + _1m_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_1m_sats".to_string()), + _10m_sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_10m_sats".to_string()), + _1btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_1btc".to_string()), + _10btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_10btc".to_string()), + _100btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_100btc".to_string()), + _1k_btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_1k_btc".to_string()), + _10k_btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_10k_btc".to_string()), + _100k_btc: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_100k_btc".to_string()), } } } @@ -7800,12 +8048,12 @@ impl BrkClient { self.base.get_json(&format!("/api/mempool/txids")) } - /// Get supported indexes for a metric + /// Get metric info /// - /// Returns the list of indexes supported by the specified metric. For example, `realized_price` might be available on day1, week1, and month1. + /// Returns the supported indexes and value type for the specified metric. /// /// Endpoint: `GET /api/metric/{metric}` - pub fn get_metric_info(&self, metric: Metric) -> Result> { + pub fn get_metric_info(&self, metric: Metric) -> Result { self.base.get_json(&format!("/api/metric/{metric}")) } @@ -7814,7 +8062,7 @@ impl BrkClient { /// Fetch data for a specific metric at the given index. Use query parameters to filter by date range and format (json/csv). /// /// Endpoint: `GET /api/metric/{metric}/{index}` - pub fn get_metric(&self, metric: Metric, index: Index, start: Option, end: Option, limit: Option<&str>, format: Option) -> Result> { + pub fn get_metric(&self, metric: Metric, index: Index, start: Option<&str>, end: Option<&str>, limit: Option<&str>, format: Option) -> Result> { let mut query = Vec::new(); if let Some(v) = start { query.push(format!("start={}", v)); } if let Some(v) = end { query.push(format!("end={}", v)); } @@ -7829,6 +8077,35 @@ impl BrkClient { } } + /// Get raw metric data + /// + /// Returns just the data array without the MetricData wrapper. Supports the same range and format parameters as the standard endpoint. + /// + /// Endpoint: `GET /api/metric/{metric}/{index}/data` + pub fn get_metric_data(&self, metric: Metric, index: Index, start: Option<&str>, end: Option<&str>, limit: Option<&str>, format: Option) -> Result>> { + let mut query = Vec::new(); + if let Some(v) = start { query.push(format!("start={}", v)); } + if let Some(v) = end { query.push(format!("end={}", v)); } + if let Some(v) = limit { query.push(format!("limit={}", v)); } + if let Some(v) = format { query.push(format!("format={}", v)); } + let query_str = if query.is_empty() { String::new() } else { format!("?{}", query.join("&")) }; + let path = format!("/api/metric/{metric}/{}/data{}", index.name(), query_str); + if format == Some(Format::CSV) { + self.base.get_text(&path).map(FormatResponse::Csv) + } else { + self.base.get_json(&path).map(FormatResponse::Json) + } + } + + /// Get latest metric value + /// + /// Returns the single most recent value for a metric, unwrapped (not inside a MetricData object). + /// + /// Endpoint: `GET /api/metric/{metric}/{index}/latest` + pub fn get_metric_latest(&self, metric: Metric, index: Index) -> Result { + self.base.get_json(&format!("/api/metric/{metric}/{}/latest", index.name())) + } + /// Metrics catalog /// /// Returns the complete hierarchical catalog of available metrics organized as a tree structure. Metrics are grouped by categories and subcategories. @@ -7843,7 +8120,7 @@ impl BrkClient { /// Fetch multiple metrics in a single request. Supports filtering by index and date range. Returns an array of MetricData objects. For a single metric, use `get_metric` instead. /// /// Endpoint: `GET /api/metrics/bulk` - pub fn get_metrics(&self, metrics: Metrics, index: Index, start: Option, end: Option, limit: Option<&str>, format: Option) -> Result>> { + pub fn get_metrics(&self, metrics: Metrics, index: Index, start: Option<&str>, end: Option<&str>, limit: Option<&str>, format: Option) -> Result>> { let mut query = Vec::new(); query.push(format!("metrics={}", metrics)); query.push(format!("index={}", index)); @@ -7931,12 +8208,13 @@ impl BrkClient { /// /// Fuzzy search for metrics by name. Supports partial matches and typos. /// - /// Endpoint: `GET /api/metrics/search/{metric}` - pub fn search_metrics(&self, metric: Metric, limit: Option) -> Result> { + /// Endpoint: `GET /api/metrics/search` + pub fn search_metrics(&self, q: Metric, limit: Option) -> Result> { let mut query = Vec::new(); + query.push(format!("q={}", q)); if let Some(v) = limit { query.push(format!("limit={}", v)); } let query_str = if query.is_empty() { String::new() } else { format!("?{}", query.join("&")) }; - let path = format!("/api/metrics/search/{metric}{}", query_str); + let path = format!("/api/metrics/search{}", query_str); self.base.get_json(&path) } diff --git a/crates/brk_cohort/src/by_loss.rs b/crates/brk_cohort/src/by_loss.rs index 79315d5d4..132c71730 100644 --- a/crates/brk_cohort/src/by_loss.rs +++ b/crates/brk_cohort/src/by_loss.rs @@ -6,16 +6,16 @@ use super::CohortName; /// "At least X% loss" threshold names (10 thresholds). pub const LOSS_NAMES: ByLoss = ByLoss { - breakeven: CohortName::new("loss_ge_breakeven", "<0%", "In Loss (Below Breakeven)"), - _10pct: CohortName::new("loss_ge_10pct", "≥10%L", "10%+ Loss"), - _20pct: CohortName::new("loss_ge_20pct", "≥20%L", "20%+ Loss"), - _30pct: CohortName::new("loss_ge_30pct", "≥30%L", "30%+ Loss"), - _40pct: CohortName::new("loss_ge_40pct", "≥40%L", "40%+ Loss"), - _50pct: CohortName::new("loss_ge_50pct", "≥50%L", "50%+ Loss"), - _60pct: CohortName::new("loss_ge_60pct", "≥60%L", "60%+ Loss"), - _70pct: CohortName::new("loss_ge_70pct", "≥70%L", "70%+ Loss"), - _80pct: CohortName::new("loss_ge_80pct", "≥80%L", "80%+ Loss"), - _90pct: CohortName::new("loss_ge_90pct", "≥90%L", "90%+ Loss"), + breakeven: CohortName::new("utxos_in_loss", "<0%", "In Loss (Below Breakeven)"), + _10pct: CohortName::new("utxos_over_10pct_in_loss", "≥10%L", "10%+ Loss"), + _20pct: CohortName::new("utxos_over_20pct_in_loss", "≥20%L", "20%+ Loss"), + _30pct: CohortName::new("utxos_over_30pct_in_loss", "≥30%L", "30%+ Loss"), + _40pct: CohortName::new("utxos_over_40pct_in_loss", "≥40%L", "40%+ Loss"), + _50pct: CohortName::new("utxos_over_50pct_in_loss", "≥50%L", "50%+ Loss"), + _60pct: CohortName::new("utxos_over_60pct_in_loss", "≥60%L", "60%+ Loss"), + _70pct: CohortName::new("utxos_over_70pct_in_loss", "≥70%L", "70%+ Loss"), + _80pct: CohortName::new("utxos_over_80pct_in_loss", "≥80%L", "80%+ Loss"), + _90pct: CohortName::new("utxos_over_90pct_in_loss", "≥90%L", "90%+ Loss"), }; /// Number of loss thresholds. diff --git a/crates/brk_cohort/src/by_profit.rs b/crates/brk_cohort/src/by_profit.rs index 2ea09429e..9c281163a 100644 --- a/crates/brk_cohort/src/by_profit.rs +++ b/crates/brk_cohort/src/by_profit.rs @@ -6,21 +6,21 @@ use super::CohortName; /// "At least X% profit" threshold names (15 thresholds). pub const PROFIT_NAMES: ByProfit = ByProfit { - breakeven: CohortName::new("profit_ge_breakeven", "≥0%", "In Profit (Breakeven+)"), - _10pct: CohortName::new("profit_ge_10pct", "≥10%", "10%+ Profit"), - _20pct: CohortName::new("profit_ge_20pct", "≥20%", "20%+ Profit"), - _30pct: CohortName::new("profit_ge_30pct", "≥30%", "30%+ Profit"), - _40pct: CohortName::new("profit_ge_40pct", "≥40%", "40%+ Profit"), - _50pct: CohortName::new("profit_ge_50pct", "≥50%", "50%+ Profit"), - _60pct: CohortName::new("profit_ge_60pct", "≥60%", "60%+ Profit"), - _70pct: CohortName::new("profit_ge_70pct", "≥70%", "70%+ Profit"), - _80pct: CohortName::new("profit_ge_80pct", "≥80%", "80%+ Profit"), - _90pct: CohortName::new("profit_ge_90pct", "≥90%", "90%+ Profit"), - _100pct: CohortName::new("profit_ge_100pct", "≥100%", "100%+ Profit"), - _200pct: CohortName::new("profit_ge_200pct", "≥200%", "200%+ Profit"), - _300pct: CohortName::new("profit_ge_300pct", "≥300%", "300%+ Profit"), - _500pct: CohortName::new("profit_ge_500pct", "≥500%", "500%+ Profit"), - _1000pct: CohortName::new("profit_ge_1000pct", "≥1000%", "1000%+ Profit"), + breakeven: CohortName::new("utxos_in_profit", "≥0%", "In Profit (Breakeven+)"), + _10pct: CohortName::new("utxos_over_10pct_in_profit", "≥10%", "10%+ Profit"), + _20pct: CohortName::new("utxos_over_20pct_in_profit", "≥20%", "20%+ Profit"), + _30pct: CohortName::new("utxos_over_30pct_in_profit", "≥30%", "30%+ Profit"), + _40pct: CohortName::new("utxos_over_40pct_in_profit", "≥40%", "40%+ Profit"), + _50pct: CohortName::new("utxos_over_50pct_in_profit", "≥50%", "50%+ Profit"), + _60pct: CohortName::new("utxos_over_60pct_in_profit", "≥60%", "60%+ Profit"), + _70pct: CohortName::new("utxos_over_70pct_in_profit", "≥70%", "70%+ Profit"), + _80pct: CohortName::new("utxos_over_80pct_in_profit", "≥80%", "80%+ Profit"), + _90pct: CohortName::new("utxos_over_90pct_in_profit", "≥90%", "90%+ Profit"), + _100pct: CohortName::new("utxos_over_100pct_in_profit", "≥100%", "100%+ Profit"), + _200pct: CohortName::new("utxos_over_200pct_in_profit", "≥200%", "200%+ Profit"), + _300pct: CohortName::new("utxos_over_300pct_in_profit", "≥300%", "300%+ Profit"), + _500pct: CohortName::new("utxos_over_500pct_in_profit", "≥500%", "500%+ Profit"), + _1000pct: CohortName::new("utxos_over_1000pct_in_profit", "≥1000%", "1000%+ Profit"), }; /// Number of profit thresholds. diff --git a/crates/brk_cohort/src/by_profitability_range.rs b/crates/brk_cohort/src/by_profitability_range.rs index b69e5db98..d345ce842 100644 --- a/crates/brk_cohort/src/by_profitability_range.rs +++ b/crates/brk_cohort/src/by_profitability_range.rs @@ -22,31 +22,31 @@ pub const PROFITABILITY_BOUNDARY_COUNT: usize = 24; pub fn compute_profitability_boundaries(spot: Cents) -> [Cents; PROFITABILITY_BOUNDARY_COUNT] { let s = spot.as_u128(); // Divisors in ascending boundary order (ascending price): - // profit_over_1000: price < spot/11 → boundary at spot*100/1100 = spot/11 - // profit_500_to_1000: spot/11 ≤ p < spot/6 → boundary at spot*100/600 = spot/6 - // profit_300_to_500: spot/6 ≤ p < spot/4 → boundary at spot*100/400 = spot/4 - // profit_200_to_300: spot/4 ≤ p < spot/3 → boundary at spot*100/300 = spot/3 - // profit_100_to_200: spot/3 ≤ p < spot/2 → boundary at spot*100/200 = spot/2 - // profit_90_to_100: spot/2 ≤ p < spot*100/190 → boundary at spot*100/190 - // profit_80_to_90: → boundary at spot*100/180 - // profit_70_to_80: → boundary at spot*100/170 - // profit_60_to_70: → boundary at spot*100/160 - // profit_50_to_60: → boundary at spot*100/150 - // profit_40_to_50: → boundary at spot*100/140 - // profit_30_to_40: → boundary at spot*100/130 - // profit_20_to_30: → boundary at spot*100/120 - // profit_10_to_20: → boundary at spot*100/110 - // profit_0_to_10: → boundary at spot (= spot*100/100) - // loss_0_to_10: spot ≤ p < spot*100/90 → boundary at spot*100/90 - // loss_10_to_20: → boundary at spot*100/80 - // loss_20_to_30: → boundary at spot*100/70 - // loss_30_to_40: → boundary at spot*100/60 - // loss_40_to_50: → boundary at spot*100/50 = spot*2 - // loss_50_to_60: → boundary at spot*100/40 = spot*5/2 - // loss_60_to_70: → boundary at spot*100/30 = spot*10/3 - // loss_70_to_80: → boundary at spot*100/20 = spot*5 - // loss_80_to_90: → boundary at spot*100/10 = spot*10 - // loss_90_to_100: spot*10 ≤ p (no upper boundary) + // over_1000pct_in_profit: price < spot/11 → boundary at spot*100/1100 = spot/11 + // 500pct_to_1000pct_in_profit: spot/11 ≤ p < spot/6 → boundary at spot*100/600 = spot/6 + // 300pct_to_500pct_in_profit: spot/6 ≤ p < spot/4 → boundary at spot*100/400 = spot/4 + // 200pct_to_300pct_in_profit: spot/4 ≤ p < spot/3 → boundary at spot*100/300 = spot/3 + // 100pct_to_200pct_in_profit: spot/3 ≤ p < spot/2 → boundary at spot*100/200 = spot/2 + // 90pct_to_100pct_in_profit: spot/2 ≤ p < spot*100/190 → boundary at spot*100/190 + // 80pct_to_90pct_in_profit: → boundary at spot*100/180 + // 70pct_to_80pct_in_profit: → boundary at spot*100/170 + // 60pct_to_70pct_in_profit: → boundary at spot*100/160 + // 50pct_to_60pct_in_profit: → boundary at spot*100/150 + // 40pct_to_50pct_in_profit: → boundary at spot*100/140 + // 30pct_to_40pct_in_profit: → boundary at spot*100/130 + // 20pct_to_30pct_in_profit: → boundary at spot*100/120 + // 10pct_to_20pct_in_profit: → boundary at spot*100/110 + // 0pct_to_10pct_in_profit: → boundary at spot (= spot*100/100) + // 0pct_to_10pct_in_loss: spot ≤ p < spot*100/90 → boundary at spot*100/90 + // 10pct_to_20pct_in_loss: → boundary at spot*100/80 + // 20pct_to_30pct_in_loss: → boundary at spot*100/70 + // 30pct_to_40pct_in_loss: → boundary at spot*100/60 + // 40pct_to_50pct_in_loss: → boundary at spot*100/50 = spot*2 + // 50pct_to_60pct_in_loss: → boundary at spot*100/40 = spot*5/2 + // 60pct_to_70pct_in_loss: → boundary at spot*100/30 = spot*10/3 + // 70pct_to_80pct_in_loss: → boundary at spot*100/20 = spot*5 + // 80pct_to_90pct_in_loss: → boundary at spot*100/10 = spot*10 + // 90pct_to_100pct_in_loss: spot*10 ≤ p (no upper boundary) let divisors: [u128; PROFITABILITY_BOUNDARY_COUNT] = [ 1100, // >1000% profit upper bound (spot/11) 600, // 500-1000% profit upper bound (spot/6) @@ -83,31 +83,31 @@ pub fn compute_profitability_boundaries(spot: Cents) -> [Cents; PROFITABILITY_BO /// Profitability range names (25 ranges, from most profitable to most in loss) pub const PROFITABILITY_RANGE_NAMES: ByProfitabilityRange = ByProfitabilityRange { - profit_over_1000: CohortName::new("profit_over_1000pct", ">1000%", "Over 1000% Profit"), - profit_500_to_1000: CohortName::new("profit_500_to_1000pct", "500-1000%", "500-1000% Profit"), - profit_300_to_500: CohortName::new("profit_300_to_500pct", "300-500%", "300-500% Profit"), - profit_200_to_300: CohortName::new("profit_200_to_300pct", "200-300%", "200-300% Profit"), - profit_100_to_200: CohortName::new("profit_100_to_200pct", "100-200%", "100-200% Profit"), - profit_90_to_100: CohortName::new("profit_90_to_100pct", "90-100%", "90-100% Profit"), - profit_80_to_90: CohortName::new("profit_80_to_90pct", "80-90%", "80-90% Profit"), - profit_70_to_80: CohortName::new("profit_70_to_80pct", "70-80%", "70-80% Profit"), - profit_60_to_70: CohortName::new("profit_60_to_70pct", "60-70%", "60-70% Profit"), - profit_50_to_60: CohortName::new("profit_50_to_60pct", "50-60%", "50-60% Profit"), - profit_40_to_50: CohortName::new("profit_40_to_50pct", "40-50%", "40-50% Profit"), - profit_30_to_40: CohortName::new("profit_30_to_40pct", "30-40%", "30-40% Profit"), - profit_20_to_30: CohortName::new("profit_20_to_30pct", "20-30%", "20-30% Profit"), - profit_10_to_20: CohortName::new("profit_10_to_20pct", "10-20%", "10-20% Profit"), - profit_0_to_10: CohortName::new("profit_0_to_10pct", "0-10%", "0-10% Profit"), - loss_0_to_10: CohortName::new("loss_0_to_10pct", "0-10%L", "0-10% Loss"), - loss_10_to_20: CohortName::new("loss_10_to_20pct", "10-20%L", "10-20% Loss"), - loss_20_to_30: CohortName::new("loss_20_to_30pct", "20-30%L", "20-30% Loss"), - loss_30_to_40: CohortName::new("loss_30_to_40pct", "30-40%L", "30-40% Loss"), - loss_40_to_50: CohortName::new("loss_40_to_50pct", "40-50%L", "40-50% Loss"), - loss_50_to_60: CohortName::new("loss_50_to_60pct", "50-60%L", "50-60% Loss"), - loss_60_to_70: CohortName::new("loss_60_to_70pct", "60-70%L", "60-70% Loss"), - loss_70_to_80: CohortName::new("loss_70_to_80pct", "70-80%L", "70-80% Loss"), - loss_80_to_90: CohortName::new("loss_80_to_90pct", "80-90%L", "80-90% Loss"), - loss_90_to_100: CohortName::new("loss_90_to_100pct", "90-100%L", "90-100% Loss"), + over_1000pct_in_profit: CohortName::new("utxos_over_1000pct_in_profit", ">1000%", "Over 1000% Profit"), + _500pct_to_1000pct_in_profit: CohortName::new("utxos_500pct_to_1000pct_in_profit", "500-1000%", "500-1000% Profit"), + _300pct_to_500pct_in_profit: CohortName::new("utxos_300pct_to_500pct_in_profit", "300-500%", "300-500% Profit"), + _200pct_to_300pct_in_profit: CohortName::new("utxos_200pct_to_300pct_in_profit", "200-300%", "200-300% Profit"), + _100pct_to_200pct_in_profit: CohortName::new("utxos_100pct_to_200pct_in_profit", "100-200%", "100-200% Profit"), + _90pct_to_100pct_in_profit: CohortName::new("utxos_90pct_to_100pct_in_profit", "90-100%", "90-100% Profit"), + _80pct_to_90pct_in_profit: CohortName::new("utxos_80pct_to_90pct_in_profit", "80-90%", "80-90% Profit"), + _70pct_to_80pct_in_profit: CohortName::new("utxos_70pct_to_80pct_in_profit", "70-80%", "70-80% Profit"), + _60pct_to_70pct_in_profit: CohortName::new("utxos_60pct_to_70pct_in_profit", "60-70%", "60-70% Profit"), + _50pct_to_60pct_in_profit: CohortName::new("utxos_50pct_to_60pct_in_profit", "50-60%", "50-60% Profit"), + _40pct_to_50pct_in_profit: CohortName::new("utxos_40pct_to_50pct_in_profit", "40-50%", "40-50% Profit"), + _30pct_to_40pct_in_profit: CohortName::new("utxos_30pct_to_40pct_in_profit", "30-40%", "30-40% Profit"), + _20pct_to_30pct_in_profit: CohortName::new("utxos_20pct_to_30pct_in_profit", "20-30%", "20-30% Profit"), + _10pct_to_20pct_in_profit: CohortName::new("utxos_10pct_to_20pct_in_profit", "10-20%", "10-20% Profit"), + _0pct_to_10pct_in_profit: CohortName::new("utxos_0pct_to_10pct_in_profit", "0-10%", "0-10% Profit"), + _0pct_to_10pct_in_loss: CohortName::new("utxos_0pct_to_10pct_in_loss", "0-10%L", "0-10% Loss"), + _10pct_to_20pct_in_loss: CohortName::new("utxos_10pct_to_20pct_in_loss", "10-20%L", "10-20% Loss"), + _20pct_to_30pct_in_loss: CohortName::new("utxos_20pct_to_30pct_in_loss", "20-30%L", "20-30% Loss"), + _30pct_to_40pct_in_loss: CohortName::new("utxos_30pct_to_40pct_in_loss", "30-40%L", "30-40% Loss"), + _40pct_to_50pct_in_loss: CohortName::new("utxos_40pct_to_50pct_in_loss", "40-50%L", "40-50% Loss"), + _50pct_to_60pct_in_loss: CohortName::new("utxos_50pct_to_60pct_in_loss", "50-60%L", "50-60% Loss"), + _60pct_to_70pct_in_loss: CohortName::new("utxos_60pct_to_70pct_in_loss", "60-70%L", "60-70% Loss"), + _70pct_to_80pct_in_loss: CohortName::new("utxos_70pct_to_80pct_in_loss", "70-80%L", "70-80% Loss"), + _80pct_to_90pct_in_loss: CohortName::new("utxos_80pct_to_90pct_in_loss", "80-90%L", "80-90% Loss"), + _90pct_to_100pct_in_loss: CohortName::new("utxos_90pct_to_100pct_in_loss", "90-100%L", "90-100% Loss"), }; impl ByProfitabilityRange { @@ -119,34 +119,34 @@ impl ByProfitabilityRange { /// 25 profitability range buckets ordered from most profitable to most in loss. /// /// During the k-way merge (ascending price order), the cursor starts at bucket 0 -/// (profit_over_1000, lowest cost basis) and advances as price crosses each boundary. +/// (over_1000pct_in_profit, lowest cost basis) and advances as price crosses each boundary. #[derive(Default, Clone, Traversable, Serialize)] pub struct ByProfitabilityRange { - pub profit_over_1000: T, - pub profit_500_to_1000: T, - pub profit_300_to_500: T, - pub profit_200_to_300: T, - pub profit_100_to_200: T, - pub profit_90_to_100: T, - pub profit_80_to_90: T, - pub profit_70_to_80: T, - pub profit_60_to_70: T, - pub profit_50_to_60: T, - pub profit_40_to_50: T, - pub profit_30_to_40: T, - pub profit_20_to_30: T, - pub profit_10_to_20: T, - pub profit_0_to_10: T, - pub loss_0_to_10: T, - pub loss_10_to_20: T, - pub loss_20_to_30: T, - pub loss_30_to_40: T, - pub loss_40_to_50: T, - pub loss_50_to_60: T, - pub loss_60_to_70: T, - pub loss_70_to_80: T, - pub loss_80_to_90: T, - pub loss_90_to_100: T, + pub over_1000pct_in_profit: T, + pub _500pct_to_1000pct_in_profit: T, + pub _300pct_to_500pct_in_profit: T, + pub _200pct_to_300pct_in_profit: T, + pub _100pct_to_200pct_in_profit: T, + pub _90pct_to_100pct_in_profit: T, + pub _80pct_to_90pct_in_profit: T, + pub _70pct_to_80pct_in_profit: T, + pub _60pct_to_70pct_in_profit: T, + pub _50pct_to_60pct_in_profit: T, + pub _40pct_to_50pct_in_profit: T, + pub _30pct_to_40pct_in_profit: T, + pub _20pct_to_30pct_in_profit: T, + pub _10pct_to_20pct_in_profit: T, + pub _0pct_to_10pct_in_profit: T, + pub _0pct_to_10pct_in_loss: T, + pub _10pct_to_20pct_in_loss: T, + pub _20pct_to_30pct_in_loss: T, + pub _30pct_to_40pct_in_loss: T, + pub _40pct_to_50pct_in_loss: T, + pub _50pct_to_60pct_in_loss: T, + pub _60pct_to_70pct_in_loss: T, + pub _70pct_to_80pct_in_loss: T, + pub _80pct_to_90pct_in_loss: T, + pub _90pct_to_100pct_in_loss: T, } /// Number of profitability range buckets. @@ -159,31 +159,31 @@ impl ByProfitabilityRange { { let n = &PROFITABILITY_RANGE_NAMES; Self { - profit_over_1000: create(n.profit_over_1000.id), - profit_500_to_1000: create(n.profit_500_to_1000.id), - profit_300_to_500: create(n.profit_300_to_500.id), - profit_200_to_300: create(n.profit_200_to_300.id), - profit_100_to_200: create(n.profit_100_to_200.id), - profit_90_to_100: create(n.profit_90_to_100.id), - profit_80_to_90: create(n.profit_80_to_90.id), - profit_70_to_80: create(n.profit_70_to_80.id), - profit_60_to_70: create(n.profit_60_to_70.id), - profit_50_to_60: create(n.profit_50_to_60.id), - profit_40_to_50: create(n.profit_40_to_50.id), - profit_30_to_40: create(n.profit_30_to_40.id), - profit_20_to_30: create(n.profit_20_to_30.id), - profit_10_to_20: create(n.profit_10_to_20.id), - profit_0_to_10: create(n.profit_0_to_10.id), - loss_0_to_10: create(n.loss_0_to_10.id), - loss_10_to_20: create(n.loss_10_to_20.id), - loss_20_to_30: create(n.loss_20_to_30.id), - loss_30_to_40: create(n.loss_30_to_40.id), - loss_40_to_50: create(n.loss_40_to_50.id), - loss_50_to_60: create(n.loss_50_to_60.id), - loss_60_to_70: create(n.loss_60_to_70.id), - loss_70_to_80: create(n.loss_70_to_80.id), - loss_80_to_90: create(n.loss_80_to_90.id), - loss_90_to_100: create(n.loss_90_to_100.id), + over_1000pct_in_profit: create(n.over_1000pct_in_profit.id), + _500pct_to_1000pct_in_profit: create(n._500pct_to_1000pct_in_profit.id), + _300pct_to_500pct_in_profit: create(n._300pct_to_500pct_in_profit.id), + _200pct_to_300pct_in_profit: create(n._200pct_to_300pct_in_profit.id), + _100pct_to_200pct_in_profit: create(n._100pct_to_200pct_in_profit.id), + _90pct_to_100pct_in_profit: create(n._90pct_to_100pct_in_profit.id), + _80pct_to_90pct_in_profit: create(n._80pct_to_90pct_in_profit.id), + _70pct_to_80pct_in_profit: create(n._70pct_to_80pct_in_profit.id), + _60pct_to_70pct_in_profit: create(n._60pct_to_70pct_in_profit.id), + _50pct_to_60pct_in_profit: create(n._50pct_to_60pct_in_profit.id), + _40pct_to_50pct_in_profit: create(n._40pct_to_50pct_in_profit.id), + _30pct_to_40pct_in_profit: create(n._30pct_to_40pct_in_profit.id), + _20pct_to_30pct_in_profit: create(n._20pct_to_30pct_in_profit.id), + _10pct_to_20pct_in_profit: create(n._10pct_to_20pct_in_profit.id), + _0pct_to_10pct_in_profit: create(n._0pct_to_10pct_in_profit.id), + _0pct_to_10pct_in_loss: create(n._0pct_to_10pct_in_loss.id), + _10pct_to_20pct_in_loss: create(n._10pct_to_20pct_in_loss.id), + _20pct_to_30pct_in_loss: create(n._20pct_to_30pct_in_loss.id), + _30pct_to_40pct_in_loss: create(n._30pct_to_40pct_in_loss.id), + _40pct_to_50pct_in_loss: create(n._40pct_to_50pct_in_loss.id), + _50pct_to_60pct_in_loss: create(n._50pct_to_60pct_in_loss.id), + _60pct_to_70pct_in_loss: create(n._60pct_to_70pct_in_loss.id), + _70pct_to_80pct_in_loss: create(n._70pct_to_80pct_in_loss.id), + _80pct_to_90pct_in_loss: create(n._80pct_to_90pct_in_loss.id), + _90pct_to_100pct_in_loss: create(n._90pct_to_100pct_in_loss.id), } } @@ -193,92 +193,92 @@ impl ByProfitabilityRange { { let n = &PROFITABILITY_RANGE_NAMES; Ok(Self { - profit_over_1000: create(n.profit_over_1000.id)?, - profit_500_to_1000: create(n.profit_500_to_1000.id)?, - profit_300_to_500: create(n.profit_300_to_500.id)?, - profit_200_to_300: create(n.profit_200_to_300.id)?, - profit_100_to_200: create(n.profit_100_to_200.id)?, - profit_90_to_100: create(n.profit_90_to_100.id)?, - profit_80_to_90: create(n.profit_80_to_90.id)?, - profit_70_to_80: create(n.profit_70_to_80.id)?, - profit_60_to_70: create(n.profit_60_to_70.id)?, - profit_50_to_60: create(n.profit_50_to_60.id)?, - profit_40_to_50: create(n.profit_40_to_50.id)?, - profit_30_to_40: create(n.profit_30_to_40.id)?, - profit_20_to_30: create(n.profit_20_to_30.id)?, - profit_10_to_20: create(n.profit_10_to_20.id)?, - profit_0_to_10: create(n.profit_0_to_10.id)?, - loss_0_to_10: create(n.loss_0_to_10.id)?, - loss_10_to_20: create(n.loss_10_to_20.id)?, - loss_20_to_30: create(n.loss_20_to_30.id)?, - loss_30_to_40: create(n.loss_30_to_40.id)?, - loss_40_to_50: create(n.loss_40_to_50.id)?, - loss_50_to_60: create(n.loss_50_to_60.id)?, - loss_60_to_70: create(n.loss_60_to_70.id)?, - loss_70_to_80: create(n.loss_70_to_80.id)?, - loss_80_to_90: create(n.loss_80_to_90.id)?, - loss_90_to_100: create(n.loss_90_to_100.id)?, + over_1000pct_in_profit: create(n.over_1000pct_in_profit.id)?, + _500pct_to_1000pct_in_profit: create(n._500pct_to_1000pct_in_profit.id)?, + _300pct_to_500pct_in_profit: create(n._300pct_to_500pct_in_profit.id)?, + _200pct_to_300pct_in_profit: create(n._200pct_to_300pct_in_profit.id)?, + _100pct_to_200pct_in_profit: create(n._100pct_to_200pct_in_profit.id)?, + _90pct_to_100pct_in_profit: create(n._90pct_to_100pct_in_profit.id)?, + _80pct_to_90pct_in_profit: create(n._80pct_to_90pct_in_profit.id)?, + _70pct_to_80pct_in_profit: create(n._70pct_to_80pct_in_profit.id)?, + _60pct_to_70pct_in_profit: create(n._60pct_to_70pct_in_profit.id)?, + _50pct_to_60pct_in_profit: create(n._50pct_to_60pct_in_profit.id)?, + _40pct_to_50pct_in_profit: create(n._40pct_to_50pct_in_profit.id)?, + _30pct_to_40pct_in_profit: create(n._30pct_to_40pct_in_profit.id)?, + _20pct_to_30pct_in_profit: create(n._20pct_to_30pct_in_profit.id)?, + _10pct_to_20pct_in_profit: create(n._10pct_to_20pct_in_profit.id)?, + _0pct_to_10pct_in_profit: create(n._0pct_to_10pct_in_profit.id)?, + _0pct_to_10pct_in_loss: create(n._0pct_to_10pct_in_loss.id)?, + _10pct_to_20pct_in_loss: create(n._10pct_to_20pct_in_loss.id)?, + _20pct_to_30pct_in_loss: create(n._20pct_to_30pct_in_loss.id)?, + _30pct_to_40pct_in_loss: create(n._30pct_to_40pct_in_loss.id)?, + _40pct_to_50pct_in_loss: create(n._40pct_to_50pct_in_loss.id)?, + _50pct_to_60pct_in_loss: create(n._50pct_to_60pct_in_loss.id)?, + _60pct_to_70pct_in_loss: create(n._60pct_to_70pct_in_loss.id)?, + _70pct_to_80pct_in_loss: create(n._70pct_to_80pct_in_loss.id)?, + _80pct_to_90pct_in_loss: create(n._80pct_to_90pct_in_loss.id)?, + _90pct_to_100pct_in_loss: create(n._90pct_to_100pct_in_loss.id)?, }) } pub fn iter(&self) -> impl Iterator { [ - &self.profit_over_1000, - &self.profit_500_to_1000, - &self.profit_300_to_500, - &self.profit_200_to_300, - &self.profit_100_to_200, - &self.profit_90_to_100, - &self.profit_80_to_90, - &self.profit_70_to_80, - &self.profit_60_to_70, - &self.profit_50_to_60, - &self.profit_40_to_50, - &self.profit_30_to_40, - &self.profit_20_to_30, - &self.profit_10_to_20, - &self.profit_0_to_10, - &self.loss_0_to_10, - &self.loss_10_to_20, - &self.loss_20_to_30, - &self.loss_30_to_40, - &self.loss_40_to_50, - &self.loss_50_to_60, - &self.loss_60_to_70, - &self.loss_70_to_80, - &self.loss_80_to_90, - &self.loss_90_to_100, + &self.over_1000pct_in_profit, + &self._500pct_to_1000pct_in_profit, + &self._300pct_to_500pct_in_profit, + &self._200pct_to_300pct_in_profit, + &self._100pct_to_200pct_in_profit, + &self._90pct_to_100pct_in_profit, + &self._80pct_to_90pct_in_profit, + &self._70pct_to_80pct_in_profit, + &self._60pct_to_70pct_in_profit, + &self._50pct_to_60pct_in_profit, + &self._40pct_to_50pct_in_profit, + &self._30pct_to_40pct_in_profit, + &self._20pct_to_30pct_in_profit, + &self._10pct_to_20pct_in_profit, + &self._0pct_to_10pct_in_profit, + &self._0pct_to_10pct_in_loss, + &self._10pct_to_20pct_in_loss, + &self._20pct_to_30pct_in_loss, + &self._30pct_to_40pct_in_loss, + &self._40pct_to_50pct_in_loss, + &self._50pct_to_60pct_in_loss, + &self._60pct_to_70pct_in_loss, + &self._70pct_to_80pct_in_loss, + &self._80pct_to_90pct_in_loss, + &self._90pct_to_100pct_in_loss, ] .into_iter() } pub fn iter_mut(&mut self) -> impl Iterator { [ - &mut self.profit_over_1000, - &mut self.profit_500_to_1000, - &mut self.profit_300_to_500, - &mut self.profit_200_to_300, - &mut self.profit_100_to_200, - &mut self.profit_90_to_100, - &mut self.profit_80_to_90, - &mut self.profit_70_to_80, - &mut self.profit_60_to_70, - &mut self.profit_50_to_60, - &mut self.profit_40_to_50, - &mut self.profit_30_to_40, - &mut self.profit_20_to_30, - &mut self.profit_10_to_20, - &mut self.profit_0_to_10, - &mut self.loss_0_to_10, - &mut self.loss_10_to_20, - &mut self.loss_20_to_30, - &mut self.loss_30_to_40, - &mut self.loss_40_to_50, - &mut self.loss_50_to_60, - &mut self.loss_60_to_70, - &mut self.loss_70_to_80, - &mut self.loss_80_to_90, - &mut self.loss_90_to_100, + &mut self.over_1000pct_in_profit, + &mut self._500pct_to_1000pct_in_profit, + &mut self._300pct_to_500pct_in_profit, + &mut self._200pct_to_300pct_in_profit, + &mut self._100pct_to_200pct_in_profit, + &mut self._90pct_to_100pct_in_profit, + &mut self._80pct_to_90pct_in_profit, + &mut self._70pct_to_80pct_in_profit, + &mut self._60pct_to_70pct_in_profit, + &mut self._50pct_to_60pct_in_profit, + &mut self._40pct_to_50pct_in_profit, + &mut self._30pct_to_40pct_in_profit, + &mut self._20pct_to_30pct_in_profit, + &mut self._10pct_to_20pct_in_profit, + &mut self._0pct_to_10pct_in_profit, + &mut self._0pct_to_10pct_in_loss, + &mut self._10pct_to_20pct_in_loss, + &mut self._20pct_to_30pct_in_loss, + &mut self._30pct_to_40pct_in_loss, + &mut self._40pct_to_50pct_in_loss, + &mut self._50pct_to_60pct_in_loss, + &mut self._60pct_to_70pct_in_loss, + &mut self._70pct_to_80pct_in_loss, + &mut self._80pct_to_90pct_in_loss, + &mut self._90pct_to_100pct_in_loss, ] .into_iter() } @@ -288,31 +288,31 @@ impl ByProfitabilityRange { T: Send + Sync, { [ - &mut self.profit_over_1000, - &mut self.profit_500_to_1000, - &mut self.profit_300_to_500, - &mut self.profit_200_to_300, - &mut self.profit_100_to_200, - &mut self.profit_90_to_100, - &mut self.profit_80_to_90, - &mut self.profit_70_to_80, - &mut self.profit_60_to_70, - &mut self.profit_50_to_60, - &mut self.profit_40_to_50, - &mut self.profit_30_to_40, - &mut self.profit_20_to_30, - &mut self.profit_10_to_20, - &mut self.profit_0_to_10, - &mut self.loss_0_to_10, - &mut self.loss_10_to_20, - &mut self.loss_20_to_30, - &mut self.loss_30_to_40, - &mut self.loss_40_to_50, - &mut self.loss_50_to_60, - &mut self.loss_60_to_70, - &mut self.loss_70_to_80, - &mut self.loss_80_to_90, - &mut self.loss_90_to_100, + &mut self.over_1000pct_in_profit, + &mut self._500pct_to_1000pct_in_profit, + &mut self._300pct_to_500pct_in_profit, + &mut self._200pct_to_300pct_in_profit, + &mut self._100pct_to_200pct_in_profit, + &mut self._90pct_to_100pct_in_profit, + &mut self._80pct_to_90pct_in_profit, + &mut self._70pct_to_80pct_in_profit, + &mut self._60pct_to_70pct_in_profit, + &mut self._50pct_to_60pct_in_profit, + &mut self._40pct_to_50pct_in_profit, + &mut self._30pct_to_40pct_in_profit, + &mut self._20pct_to_30pct_in_profit, + &mut self._10pct_to_20pct_in_profit, + &mut self._0pct_to_10pct_in_profit, + &mut self._0pct_to_10pct_in_loss, + &mut self._10pct_to_20pct_in_loss, + &mut self._20pct_to_30pct_in_loss, + &mut self._30pct_to_40pct_in_loss, + &mut self._40pct_to_50pct_in_loss, + &mut self._50pct_to_60pct_in_loss, + &mut self._60pct_to_70pct_in_loss, + &mut self._70pct_to_80pct_in_loss, + &mut self._80pct_to_90pct_in_loss, + &mut self._90pct_to_100pct_in_loss, ] .into_par_iter() } @@ -320,62 +320,62 @@ impl ByProfitabilityRange { /// Access as a fixed-size array of references (for indexed access during merge). pub fn as_array(&self) -> [&T; PROFITABILITY_RANGE_COUNT] { [ - &self.profit_over_1000, - &self.profit_500_to_1000, - &self.profit_300_to_500, - &self.profit_200_to_300, - &self.profit_100_to_200, - &self.profit_90_to_100, - &self.profit_80_to_90, - &self.profit_70_to_80, - &self.profit_60_to_70, - &self.profit_50_to_60, - &self.profit_40_to_50, - &self.profit_30_to_40, - &self.profit_20_to_30, - &self.profit_10_to_20, - &self.profit_0_to_10, - &self.loss_0_to_10, - &self.loss_10_to_20, - &self.loss_20_to_30, - &self.loss_30_to_40, - &self.loss_40_to_50, - &self.loss_50_to_60, - &self.loss_60_to_70, - &self.loss_70_to_80, - &self.loss_80_to_90, - &self.loss_90_to_100, + &self.over_1000pct_in_profit, + &self._500pct_to_1000pct_in_profit, + &self._300pct_to_500pct_in_profit, + &self._200pct_to_300pct_in_profit, + &self._100pct_to_200pct_in_profit, + &self._90pct_to_100pct_in_profit, + &self._80pct_to_90pct_in_profit, + &self._70pct_to_80pct_in_profit, + &self._60pct_to_70pct_in_profit, + &self._50pct_to_60pct_in_profit, + &self._40pct_to_50pct_in_profit, + &self._30pct_to_40pct_in_profit, + &self._20pct_to_30pct_in_profit, + &self._10pct_to_20pct_in_profit, + &self._0pct_to_10pct_in_profit, + &self._0pct_to_10pct_in_loss, + &self._10pct_to_20pct_in_loss, + &self._20pct_to_30pct_in_loss, + &self._30pct_to_40pct_in_loss, + &self._40pct_to_50pct_in_loss, + &self._50pct_to_60pct_in_loss, + &self._60pct_to_70pct_in_loss, + &self._70pct_to_80pct_in_loss, + &self._80pct_to_90pct_in_loss, + &self._90pct_to_100pct_in_loss, ] } /// Access as a fixed-size array of mutable references (for indexed access during merge). pub fn as_array_mut(&mut self) -> [&mut T; PROFITABILITY_RANGE_COUNT] { [ - &mut self.profit_over_1000, - &mut self.profit_500_to_1000, - &mut self.profit_300_to_500, - &mut self.profit_200_to_300, - &mut self.profit_100_to_200, - &mut self.profit_90_to_100, - &mut self.profit_80_to_90, - &mut self.profit_70_to_80, - &mut self.profit_60_to_70, - &mut self.profit_50_to_60, - &mut self.profit_40_to_50, - &mut self.profit_30_to_40, - &mut self.profit_20_to_30, - &mut self.profit_10_to_20, - &mut self.profit_0_to_10, - &mut self.loss_0_to_10, - &mut self.loss_10_to_20, - &mut self.loss_20_to_30, - &mut self.loss_30_to_40, - &mut self.loss_40_to_50, - &mut self.loss_50_to_60, - &mut self.loss_60_to_70, - &mut self.loss_70_to_80, - &mut self.loss_80_to_90, - &mut self.loss_90_to_100, + &mut self.over_1000pct_in_profit, + &mut self._500pct_to_1000pct_in_profit, + &mut self._300pct_to_500pct_in_profit, + &mut self._200pct_to_300pct_in_profit, + &mut self._100pct_to_200pct_in_profit, + &mut self._90pct_to_100pct_in_profit, + &mut self._80pct_to_90pct_in_profit, + &mut self._70pct_to_80pct_in_profit, + &mut self._60pct_to_70pct_in_profit, + &mut self._50pct_to_60pct_in_profit, + &mut self._40pct_to_50pct_in_profit, + &mut self._30pct_to_40pct_in_profit, + &mut self._20pct_to_30pct_in_profit, + &mut self._10pct_to_20pct_in_profit, + &mut self._0pct_to_10pct_in_profit, + &mut self._0pct_to_10pct_in_loss, + &mut self._10pct_to_20pct_in_loss, + &mut self._20pct_to_30pct_in_loss, + &mut self._30pct_to_40pct_in_loss, + &mut self._40pct_to_50pct_in_loss, + &mut self._50pct_to_60pct_in_loss, + &mut self._60pct_to_70pct_in_loss, + &mut self._70pct_to_80pct_in_loss, + &mut self._80pct_to_90pct_in_loss, + &mut self._90pct_to_100pct_in_loss, ] } } diff --git a/crates/brk_computer/src/blocks/difficulty/compute.rs b/crates/brk_computer/src/blocks/difficulty/compute.rs index 0a0a29e82..dfa537dea 100644 --- a/crates/brk_computer/src/blocks/difficulty/compute.rs +++ b/crates/brk_computer/src/blocks/difficulty/compute.rs @@ -43,7 +43,7 @@ impl Vecs { )?; // Compute blocks before next adjustment - self.blocks_before_next_adjustment + self.blocks_before_next .height .compute_transform( starting_indexes.height, @@ -53,9 +53,9 @@ impl Vecs { )?; // Compute days before next adjustment - self.days_before_next_adjustment.height.compute_transform( + self.days_before_next.height.compute_transform( starting_indexes.height, - &self.blocks_before_next_adjustment.height, + &self.blocks_before_next.height, |(h, blocks, ..)| (h, (*blocks as f32 / TARGET_BLOCKS_PER_DAY_F32).into()), exit, )?; diff --git a/crates/brk_computer/src/blocks/difficulty/import.rs b/crates/brk_computer/src/blocks/difficulty/import.rs index a799d8fbe..aa96e8b11 100644 --- a/crates/brk_computer/src/blocks/difficulty/import.rs +++ b/crates/brk_computer/src/blocks/difficulty/import.rs @@ -33,13 +33,13 @@ impl Vecs { indexes, )?, epoch: ComputedPerBlock::forced_import(db, "difficulty_epoch", version, indexes)?, - blocks_before_next_adjustment: ComputedPerBlock::forced_import( + blocks_before_next: ComputedPerBlock::forced_import( db, "blocks_before_next_difficulty_adjustment", version + v2, indexes, )?, - days_before_next_adjustment: ComputedPerBlock::forced_import( + days_before_next: ComputedPerBlock::forced_import( db, "days_before_next_difficulty_adjustment", version + v2, diff --git a/crates/brk_computer/src/blocks/difficulty/vecs.rs b/crates/brk_computer/src/blocks/difficulty/vecs.rs index b1cafa90f..2e246477e 100644 --- a/crates/brk_computer/src/blocks/difficulty/vecs.rs +++ b/crates/brk_computer/src/blocks/difficulty/vecs.rs @@ -9,6 +9,6 @@ pub struct Vecs { pub as_hash: ComputedPerBlock, pub adjustment: PercentPerBlock, pub epoch: ComputedPerBlock, - pub blocks_before_next_adjustment: ComputedPerBlock, - pub days_before_next_adjustment: ComputedPerBlock, + pub blocks_before_next: ComputedPerBlock, + pub days_before_next: ComputedPerBlock, } diff --git a/crates/brk_computer/src/blocks/halving/compute.rs b/crates/brk_computer/src/blocks/halving/compute.rs index c720914b7..c106324b6 100644 --- a/crates/brk_computer/src/blocks/halving/compute.rs +++ b/crates/brk_computer/src/blocks/halving/compute.rs @@ -20,16 +20,16 @@ impl Vecs { exit, )?; - self.blocks_before_next_halving.height.compute_transform( + self.blocks_before_next.height.compute_transform( starting_indexes.height, &indexes.height.identity, |(h, ..)| (h, StoredU32::from(h.left_before_next_halving())), exit, )?; - self.days_before_next_halving.height.compute_transform( + self.days_before_next.height.compute_transform( starting_indexes.height, - &self.blocks_before_next_halving.height, + &self.blocks_before_next.height, |(h, blocks, ..)| (h, (*blocks as f32 / TARGET_BLOCKS_PER_DAY_F32).into()), exit, )?; diff --git a/crates/brk_computer/src/blocks/halving/import.rs b/crates/brk_computer/src/blocks/halving/import.rs index 4db2ae4cd..69f4c5cf9 100644 --- a/crates/brk_computer/src/blocks/halving/import.rs +++ b/crates/brk_computer/src/blocks/halving/import.rs @@ -15,13 +15,13 @@ impl Vecs { Ok(Self { epoch: ComputedPerBlock::forced_import(db, "halving_epoch", version, indexes)?, - blocks_before_next_halving: ComputedPerBlock::forced_import( + blocks_before_next: ComputedPerBlock::forced_import( db, "blocks_before_next_halving", version + v2, indexes, )?, - days_before_next_halving: ComputedPerBlock::forced_import( + days_before_next: ComputedPerBlock::forced_import( db, "days_before_next_halving", version + v2, diff --git a/crates/brk_computer/src/blocks/halving/vecs.rs b/crates/brk_computer/src/blocks/halving/vecs.rs index a3561f0bd..3553bd08f 100644 --- a/crates/brk_computer/src/blocks/halving/vecs.rs +++ b/crates/brk_computer/src/blocks/halving/vecs.rs @@ -6,6 +6,6 @@ use crate::internal::ComputedPerBlock; #[derive(Traversable)] pub struct Vecs { pub epoch: ComputedPerBlock, - pub blocks_before_next_halving: ComputedPerBlock, - pub days_before_next_halving: ComputedPerBlock, + pub blocks_before_next: ComputedPerBlock, + pub days_before_next: ComputedPerBlock, } diff --git a/crates/brk_computer/src/cointime/reserve_risk/compute.rs b/crates/brk_computer/src/cointime/reserve_risk/compute.rs index db41f1c53..aac339ccf 100644 --- a/crates/brk_computer/src/cointime/reserve_risk/compute.rs +++ b/crates/brk_computer/src/cointime/reserve_risk/compute.rs @@ -23,7 +23,7 @@ impl Vecs { self.hodl_bank.compute_cumulative_transformed_binary( starting_indexes.height, - &prices.price.usd.height, + &prices.spot.usd.height, &self.vocdd_median_1y, |price, median| StoredF64::from(f64::from(price) - f64::from(median)), exit, @@ -31,7 +31,7 @@ impl Vecs { self.value.height.compute_divide( starting_indexes.height, - &prices.price.usd.height, + &prices.spot.usd.height, &self.hodl_bank, exit, )?; diff --git a/crates/brk_computer/src/cointime/value/compute.rs b/crates/brk_computer/src/cointime/value/compute.rs index a055cc8f2..9251ee958 100644 --- a/crates/brk_computer/src/cointime/value/compute.rs +++ b/crates/brk_computer/src/cointime/value/compute.rs @@ -27,7 +27,7 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, exit, |vec| { vec.compute_multiply( starting_indexes.height, - &prices.price.usd.height, + &prices.spot.usd.height, &coinblocks_destroyed.raw.height, exit, )?; @@ -38,7 +38,7 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, exit, |vec| { vec.compute_multiply( starting_indexes.height, - &prices.price.usd.height, + &prices.spot.usd.height, &activity.coinblocks_created.raw.height, exit, )?; @@ -49,7 +49,7 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, exit, |vec| { vec.compute_multiply( starting_indexes.height, - &prices.price.usd.height, + &prices.spot.usd.height, &activity.coinblocks_stored.raw.height, exit, )?; @@ -63,7 +63,7 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, exit, |vec| { vec.compute_transform3( starting_indexes.height, - &prices.price.usd.height, + &prices.spot.usd.height, &coindays_destroyed.raw.height, circulating_supply, |(i, price, cdd, supply, _): (_, Dollars, StoredF64, Bitcoin, _)| { diff --git a/crates/brk_computer/src/distribution/compute/block_loop.rs b/crates/brk_computer/src/distribution/compute/block_loop.rs index 0865ab671..9f4d7a5ee 100644 --- a/crates/brk_computer/src/distribution/compute/block_loop.rs +++ b/crates/brk_computer/src/distribution/compute/block_loop.rs @@ -144,42 +144,42 @@ pub(crate) fn process_blocks( let first_p2a_vec = indexer .vecs .addresses - .first_p2aaddressindex + .p2a.first_index .collect_range_at(start_usize, end_usize); let first_p2pk33_vec = indexer .vecs .addresses - .first_p2pk33addressindex + .p2pk33.first_index .collect_range_at(start_usize, end_usize); let first_p2pk65_vec = indexer .vecs .addresses - .first_p2pk65addressindex + .p2pk65.first_index .collect_range_at(start_usize, end_usize); let first_p2pkh_vec = indexer .vecs .addresses - .first_p2pkhaddressindex + .p2pkh.first_index .collect_range_at(start_usize, end_usize); let first_p2sh_vec = indexer .vecs .addresses - .first_p2shaddressindex + .p2sh.first_index .collect_range_at(start_usize, end_usize); let first_p2tr_vec = indexer .vecs .addresses - .first_p2traddressindex + .p2tr.first_index .collect_range_at(start_usize, end_usize); let first_p2wpkh_vec = indexer .vecs .addresses - .first_p2wpkhaddressindex + .p2wpkh.first_index .collect_range_at(start_usize, end_usize); let first_p2wsh_vec = indexer .vecs .addresses - .first_p2wshaddressindex + .p2wsh.first_index .collect_range_at(start_usize, end_usize); // Track running totals - recover from previous height if resuming diff --git a/crates/brk_computer/src/distribution/metrics/realized/minimal.rs b/crates/brk_computer/src/distribution/metrics/realized/minimal.rs index 38241bcbb..6c960278b 100644 --- a/crates/brk_computer/src/distribution/metrics/realized/minimal.rs +++ b/crates/brk_computer/src/distribution/metrics/realized/minimal.rs @@ -182,7 +182,7 @@ impl RealizedMinimal { self.nupl.bps.height.compute_transform2( starting_indexes.height, - &prices.price.cents.height, + &prices.spot.cents.height, &self.price.cents.height, |(i, price, realized_price, ..)| { let p = price.as_u128(); diff --git a/crates/brk_computer/src/distribution/metrics/relative/extended_own_pnl.rs b/crates/brk_computer/src/distribution/metrics/relative/extended_own_pnl.rs index cc5182187..24bd655e4 100644 --- a/crates/brk_computer/src/distribution/metrics/relative/extended_own_pnl.rs +++ b/crates/brk_computer/src/distribution/metrics/relative/extended_own_pnl.rs @@ -10,11 +10,11 @@ use crate::distribution::metrics::{ImportConfig, UnrealizedCore}; /// Extended relative metrics for own total unrealized PnL (extended only). #[derive(Traversable)] pub struct RelativeExtendedOwnPnl { - #[traversable(wrap = "unrealized/profit", rename = "rel_to_own_gross_pnl")] + #[traversable(wrap = "unrealized/profit", rename = "rel_to_own_gross")] pub unrealized_profit_rel_to_own_gross_pnl: PercentPerBlock, - #[traversable(wrap = "unrealized/loss", rename = "rel_to_own_gross_pnl")] + #[traversable(wrap = "unrealized/loss", rename = "rel_to_own_gross")] pub unrealized_loss_rel_to_own_gross_pnl: PercentPerBlock, - #[traversable(wrap = "unrealized/net_pnl", rename = "rel_to_own_gross_pnl")] + #[traversable(wrap = "unrealized/net_pnl", rename = "rel_to_own_gross")] pub net_unrealized_pnl_rel_to_own_gross_pnl: PercentPerBlock, } diff --git a/crates/brk_computer/src/distribution/metrics/relative/to_all.rs b/crates/brk_computer/src/distribution/metrics/relative/to_all.rs index a0ddab851..28e57d269 100644 --- a/crates/brk_computer/src/distribution/metrics/relative/to_all.rs +++ b/crates/brk_computer/src/distribution/metrics/relative/to_all.rs @@ -10,11 +10,11 @@ use crate::distribution::metrics::{ImportConfig, SupplyCore}; /// Relative-to-all metrics (not present for the "all" cohort itself). #[derive(Traversable)] pub struct RelativeToAll { - #[traversable(wrap = "supply", rename = "rel_to_circulating_supply")] + #[traversable(wrap = "supply", rename = "rel_to_circulating")] pub supply_rel_to_circulating_supply: PercentPerBlock, - #[traversable(wrap = "supply/in_profit", rename = "rel_to_circulating_supply")] + #[traversable(wrap = "supply/in_profit", rename = "rel_to_circulating")] pub supply_in_profit_rel_to_circulating_supply: PercentPerBlock, - #[traversable(wrap = "supply/in_loss", rename = "rel_to_circulating_supply")] + #[traversable(wrap = "supply/in_loss", rename = "rel_to_circulating")] pub supply_in_loss_rel_to_circulating_supply: PercentPerBlock, } diff --git a/crates/brk_computer/src/distribution/metrics/unrealized/full.rs b/crates/brk_computer/src/distribution/metrics/unrealized/full.rs index 3d2b2dc19..370928ca4 100644 --- a/crates/brk_computer/src/distribution/metrics/unrealized/full.rs +++ b/crates/brk_computer/src/distribution/metrics/unrealized/full.rs @@ -136,7 +136,7 @@ impl UnrealizedFull { starting_indexes.height, &self.inner.investor_cap_in_loss_raw, &self.inner.invested_capital_in_loss_raw, - &prices.price.cents.height, + &prices.spot.cents.height, |(h, investor_cap, invested_cap, spot, ..)| { if invested_cap.inner() == 0 { return (h, Cents::ZERO); @@ -152,7 +152,7 @@ impl UnrealizedFull { starting_indexes.height, &self.inner.investor_cap_in_profit_raw, &self.inner.invested_capital_in_profit_raw, - &prices.price.cents.height, + &prices.spot.cents.height, |(h, investor_cap, invested_cap, spot, ..)| { if invested_cap.inner() == 0 { return (h, Cents::ZERO); diff --git a/crates/brk_computer/src/distribution/mod.rs b/crates/brk_computer/src/distribution/mod.rs index a8624d84f..534bdcf67 100644 --- a/crates/brk_computer/src/distribution/mod.rs +++ b/crates/brk_computer/src/distribution/mod.rs @@ -3,11 +3,10 @@ mod block; pub mod cohorts; pub mod compute; pub mod metrics; -mod range_map; mod state; mod vecs; -pub use range_map::RangeMap; +pub use brk_types::RangeMap; pub use vecs::Vecs; pub const DB_NAME: &str = "distribution"; diff --git a/crates/brk_computer/src/distribution/vecs.rs b/crates/brk_computer/src/distribution/vecs.rs index b454213a2..cbb1fc881 100644 --- a/crates/brk_computer/src/distribution/vecs.rs +++ b/crates/brk_computer/src/distribution/vecs.rs @@ -45,8 +45,10 @@ pub struct AddressMetricsVecs { pub total: TotalAddrCountVecs, pub new: NewAddrCountVecs, pub delta: DeltaVecs, + #[traversable(wrap = "indexes", rename = "funded")] pub funded_index: LazyVecFrom1, + #[traversable(wrap = "indexes", rename = "empty")] pub empty_index: LazyVecFrom1, } @@ -59,9 +61,13 @@ pub struct Vecs { pub states_path: PathBuf, pub supply_state: M::Stored>, + #[traversable(wrap = "addresses", rename = "indexes")] pub any_address_indexes: AnyAddressIndexesVecs, + #[traversable(wrap = "addresses", rename = "data")] pub addresses_data: AddressesDataVecs, + #[traversable(wrap = "cohorts", rename = "utxo")] pub utxo_cohorts: UTXOCohorts, + #[traversable(wrap = "cohorts", rename = "address")] pub address_cohorts: AddressCohorts, pub coinblocks_destroyed: ComputedPerBlockCumulative, pub addresses: AddressMetricsVecs, @@ -213,7 +219,7 @@ impl Vecs { exit: &Exit, ) -> Result<()> { let cache_target_len = prices - .price + .spot .cents .height .len() @@ -225,7 +231,7 @@ impl Vecs { self.cached_price_range_max.truncate(cache_target_len); } else if cache_target_len > cache_current_len { let new_prices = prices - .price + .spot .cents .height .collect_range_at(cache_current_len, cache_target_len); diff --git a/crates/brk_computer/src/indexes/address.rs b/crates/brk_computer/src/indexes/address.rs index c058a1f4c..280d36b93 100644 --- a/crates/brk_computer/src/indexes/address.rs +++ b/crates/brk_computer/src/indexes/address.rs @@ -94,7 +94,7 @@ impl Vecs { identity: LazyVecFrom1::init( "p2pk33addressindex", version, - indexer.vecs.addresses.p2pk33bytes.read_only_boxed_clone(), + indexer.vecs.addresses.p2pk33.bytes.read_only_boxed_clone(), |index, _| index, ), }, @@ -102,7 +102,7 @@ impl Vecs { identity: LazyVecFrom1::init( "p2pk65addressindex", version, - indexer.vecs.addresses.p2pk65bytes.read_only_boxed_clone(), + indexer.vecs.addresses.p2pk65.bytes.read_only_boxed_clone(), |index, _| index, ), }, @@ -110,7 +110,7 @@ impl Vecs { identity: LazyVecFrom1::init( "p2pkhaddressindex", version, - indexer.vecs.addresses.p2pkhbytes.read_only_boxed_clone(), + indexer.vecs.addresses.p2pkh.bytes.read_only_boxed_clone(), |index, _| index, ), }, @@ -118,7 +118,7 @@ impl Vecs { identity: LazyVecFrom1::init( "p2shaddressindex", version, - indexer.vecs.addresses.p2shbytes.read_only_boxed_clone(), + indexer.vecs.addresses.p2sh.bytes.read_only_boxed_clone(), |index, _| index, ), }, @@ -126,7 +126,7 @@ impl Vecs { identity: LazyVecFrom1::init( "p2traddressindex", version, - indexer.vecs.addresses.p2trbytes.read_only_boxed_clone(), + indexer.vecs.addresses.p2tr.bytes.read_only_boxed_clone(), |index, _| index, ), }, @@ -134,7 +134,7 @@ impl Vecs { identity: LazyVecFrom1::init( "p2wpkhaddressindex", version, - indexer.vecs.addresses.p2wpkhbytes.read_only_boxed_clone(), + indexer.vecs.addresses.p2wpkh.bytes.read_only_boxed_clone(), |index, _| index, ), }, @@ -142,7 +142,7 @@ impl Vecs { identity: LazyVecFrom1::init( "p2wshaddressindex", version, - indexer.vecs.addresses.p2wshbytes.read_only_boxed_clone(), + indexer.vecs.addresses.p2wsh.bytes.read_only_boxed_clone(), |index, _| index, ), }, @@ -150,7 +150,7 @@ impl Vecs { identity: LazyVecFrom1::init( "p2aaddressindex", version, - indexer.vecs.addresses.p2abytes.read_only_boxed_clone(), + indexer.vecs.addresses.p2a.bytes.read_only_boxed_clone(), |index, _| index, ), }, @@ -158,7 +158,7 @@ impl Vecs { identity: LazyVecFrom1::init( "p2msoutputindex", version, - indexer.vecs.scripts.p2ms_to_txindex.read_only_boxed_clone(), + indexer.vecs.scripts.p2ms.to_txindex.read_only_boxed_clone(), |index, _| index, ), }, @@ -169,7 +169,7 @@ impl Vecs { indexer .vecs .scripts - .empty_to_txindex + .empty.to_txindex .read_only_boxed_clone(), |index, _| index, ), @@ -181,7 +181,7 @@ impl Vecs { indexer .vecs .scripts - .unknown_to_txindex + .unknown.to_txindex .read_only_boxed_clone(), |index, _| index, ), @@ -193,7 +193,7 @@ impl Vecs { indexer .vecs .scripts - .opreturn_to_txindex + .opreturn.to_txindex .read_only_boxed_clone(), |index, _| index, ), diff --git a/crates/brk_computer/src/internal/amount/base.rs b/crates/brk_computer/src/internal/amount/base.rs index eb6f6132b..4ace22218 100644 --- a/crates/brk_computer/src/internal/amount/base.rs +++ b/crates/brk_computer/src/internal/amount/base.rs @@ -59,7 +59,7 @@ impl Amount { self.cents.compute_binary::( max_from, &self.sats, - &prices.price.cents.height, + &prices.spot.cents.height, exit, )?; Ok(()) diff --git a/crates/brk_computer/src/internal/per_block/amount/base.rs b/crates/brk_computer/src/internal/per_block/amount/base.rs index 3f501282e..7b3e782c8 100644 --- a/crates/brk_computer/src/internal/per_block/amount/base.rs +++ b/crates/brk_computer/src/internal/per_block/amount/base.rs @@ -68,7 +68,7 @@ impl AmountPerBlock { self.cents.compute_binary::( max_from, &self.sats.height, - &prices.price.cents.height, + &prices.spot.cents.height, exit, )?; Ok(()) diff --git a/crates/brk_computer/src/internal/per_block/amount/cumulative.rs b/crates/brk_computer/src/internal/per_block/amount/cumulative.rs index 269570d67..d3d7ddfc1 100644 --- a/crates/brk_computer/src/internal/per_block/amount/cumulative.rs +++ b/crates/brk_computer/src/internal/per_block/amount/cumulative.rs @@ -62,7 +62,7 @@ impl AmountPerBlockCumulative { self.base.cents.compute_binary::( max_from, &self.base.sats.height, - &prices.price.cents.height, + &prices.spot.cents.height, exit, )?; diff --git a/crates/brk_computer/src/internal/per_block/amount/cumulative_sum.rs b/crates/brk_computer/src/internal/per_block/amount/cumulative_sum.rs index db732e23d..284887e3f 100644 --- a/crates/brk_computer/src/internal/per_block/amount/cumulative_sum.rs +++ b/crates/brk_computer/src/internal/per_block/amount/cumulative_sum.rs @@ -60,7 +60,7 @@ impl AmountPerBlockCumulativeSum { .compute_binary::( max_from, &self.base.sats.height, - &prices.price.cents.height, + &prices.spot.cents.height, exit, )?; diff --git a/crates/brk_computer/src/internal/per_block/amount/full.rs b/crates/brk_computer/src/internal/per_block/amount/full.rs index 2c38d421c..4f377df01 100644 --- a/crates/brk_computer/src/internal/per_block/amount/full.rs +++ b/crates/brk_computer/src/internal/per_block/amount/full.rs @@ -61,7 +61,7 @@ impl AmountPerBlockFull { .compute_binary::( max_from, &self.base.sats.height, - &prices.price.cents.height, + &prices.spot.cents.height, exit, )?; diff --git a/crates/brk_computer/src/internal/per_block/computed/resolutions.rs b/crates/brk_computer/src/internal/per_block/computed/resolutions.rs index 39ce599e8..87ae46742 100644 --- a/crates/brk_computer/src/internal/per_block/computed/resolutions.rs +++ b/crates/brk_computer/src/internal/per_block/computed/resolutions.rs @@ -1,7 +1,7 @@ use brk_traversable::Traversable; use brk_types::{ - Day1, Day3, Epoch, FromCoarserIndex, Halving, Height, Hour1, Hour4, Hour12, - Minute10, Minute30, Month1, Month3, Month6, Version, Week1, Year1, Year10, + Day1, Day3, Epoch, FromCoarserIndex, Halving, Height, Hour1, Hour4, Hour12, Minute10, Minute30, + Month1, Month3, Month6, Version, Week1, Year1, Year10, }; use derive_more::{Deref, DerefMut}; use schemars::JsonSchema; @@ -70,7 +70,7 @@ where }; } - fn for_each_range_from_coarser< + fn for_each_range< I: VecIndex, O: VecValue, S1I: VecIndex + FromCoarserIndex, @@ -103,7 +103,7 @@ where version, height_source.clone(), indexes.$idx.identity.read_only_boxed_clone(), - for_each_range_from_coarser, + for_each_range, ) }; } diff --git a/crates/brk_computer/src/internal/per_block/ratio/price_extended.rs b/crates/brk_computer/src/internal/per_block/ratio/price_extended.rs index 81120fba0..73dc707c1 100644 --- a/crates/brk_computer/src/internal/per_block/ratio/price_extended.rs +++ b/crates/brk_computer/src/internal/per_block/ratio/price_extended.rs @@ -71,7 +71,7 @@ impl PriceWithRatioPerBlock { F: FnMut(&mut EagerVec>) -> Result<()>, { compute_price(&mut self.cents.height)?; - self.compute_ratio(starting_indexes, &prices.price.cents.height, exit) + self.compute_ratio(starting_indexes, &prices.spot.cents.height, exit) } } @@ -104,7 +104,7 @@ impl PriceWithRatioExtendedPerBlock { starting_indexes: &Indexes, exit: &Exit, ) -> Result<()> { - let close_price = &prices.price.cents.height; + let close_price = &prices.spot.cents.height; self.base.compute_ratio(starting_indexes, close_price, exit)?; self.percentiles.compute( starting_indexes, diff --git a/crates/brk_computer/src/market/ath/compute.rs b/crates/brk_computer/src/market/ath/compute.rs index 38aecb7ed..d6afa9394 100644 --- a/crates/brk_computer/src/market/ath/compute.rs +++ b/crates/brk_computer/src/market/ath/compute.rs @@ -13,17 +13,17 @@ impl Vecs { starting_indexes: &Indexes, exit: &Exit, ) -> Result<()> { - self.price.cents.height.compute_all_time_high( + self.high.cents.height.compute_all_time_high( starting_indexes.height, - &prices.price.cents.height, + &prices.spot.cents.height, exit, )?; let mut ath_ts: Option = None; self.days_since.height.compute_transform3( starting_indexes.height, - &self.price.cents.height, - &prices.price.cents.height, + &self.high.cents.height, + &prices.spot.cents.height, &blocks.time.timestamp_monotonic, |(i, ath, price, ts, slf)| { if ath_ts.is_none() { @@ -68,8 +68,8 @@ impl Vecs { self.drawdown.compute_drawdown( starting_indexes.height, - &prices.price.cents.height, - &self.price.cents.height, + &prices.spot.cents.height, + &self.high.cents.height, exit, )?; diff --git a/crates/brk_computer/src/market/ath/import.rs b/crates/brk_computer/src/market/ath/import.rs index ea5c98709..b9f80e1bd 100644 --- a/crates/brk_computer/src/market/ath/import.rs +++ b/crates/brk_computer/src/market/ath/import.rs @@ -18,7 +18,7 @@ impl Vecs { ) -> Result { let v = version + VERSION; - let price = Price::forced_import(db, "price_ath", v, indexes)?; + let high = Price::forced_import(db, "price_ath", v, indexes)?; let max_days_between = ComputedPerBlock::forced_import(db, "max_days_between_price_ath", v, indexes)?; @@ -41,7 +41,7 @@ impl Vecs { let drawdown = PercentPerBlock::forced_import(db, "price_drawdown", v, indexes)?; Ok(Self { - price, + high, drawdown, days_since, years_since, diff --git a/crates/brk_computer/src/market/ath/vecs.rs b/crates/brk_computer/src/market/ath/vecs.rs index ce35e21f3..9e6ab93c0 100644 --- a/crates/brk_computer/src/market/ath/vecs.rs +++ b/crates/brk_computer/src/market/ath/vecs.rs @@ -6,7 +6,7 @@ use crate::internal::{ComputedPerBlock, DerivedResolutions, PercentPerBlock, Pri #[derive(Traversable)] pub struct Vecs { - pub price: Price>, + pub high: Price>, pub drawdown: PercentPerBlock, pub days_since: ComputedPerBlock, pub years_since: DerivedResolutions, diff --git a/crates/brk_computer/src/market/dca/compute.rs b/crates/brk_computer/src/market/dca/compute.rs index c10e9d780..745edce07 100644 --- a/crates/brk_computer/src/market/dca/compute.rs +++ b/crates/brk_computer/src/market/dca/compute.rs @@ -98,7 +98,7 @@ impl Vecs { { returns.compute_binary::( starting_indexes.height, - &prices.price.cents.height, + &prices.spot.cents.height, &average_price.cents.height, exit, )?; @@ -155,7 +155,7 @@ impl Vecs { { returns.compute_binary::( starting_indexes.height, - &prices.price.cents.height, + &prices.spot.cents.height, &lookback_price.cents.height, exit, )?; @@ -253,7 +253,7 @@ impl Vecs { { returns.compute_binary::( starting_indexes.height, - &prices.price.cents.height, + &prices.spot.cents.height, &average_price.cents.height, exit, )?; diff --git a/crates/brk_computer/src/market/lookback/compute.rs b/crates/brk_computer/src/market/lookback/compute.rs index 1a8496f38..116332c9c 100644 --- a/crates/brk_computer/src/market/lookback/compute.rs +++ b/crates/brk_computer/src/market/lookback/compute.rs @@ -13,7 +13,7 @@ impl Vecs { starting_indexes: &Indexes, exit: &Exit, ) -> Result<()> { - let price = &prices.price.cents.height; + let price = &prices.spot.cents.height; for (price_lookback, days) in self.price_lookback.iter_mut_with_days() { let window_starts = blocks.lookback.start_vec(days as usize); diff --git a/crates/brk_computer/src/market/moving_average/compute.rs b/crates/brk_computer/src/market/moving_average/compute.rs index c5b9a9608..69eeaa10d 100644 --- a/crates/brk_computer/src/market/moving_average/compute.rs +++ b/crates/brk_computer/src/market/moving_average/compute.rs @@ -13,7 +13,7 @@ impl Vecs { starting_indexes: &Indexes, exit: &Exit, ) -> Result<()> { - let close = &prices.price.cents.height; + let close = &prices.spot.cents.height; for (sma, period) in [ (&mut self.sma._1w, 7), diff --git a/crates/brk_computer/src/market/range/compute.rs b/crates/brk_computer/src/market/range/compute.rs index 95987e377..6acef0785 100644 --- a/crates/brk_computer/src/market/range/compute.rs +++ b/crates/brk_computer/src/market/range/compute.rs @@ -13,7 +13,7 @@ impl Vecs { starting_indexes: &Indexes, exit: &Exit, ) -> Result<()> { - let price = &prices.price.cents.height; + let price = &prices.spot.cents.height; for (min_vec, max_vec, starts) in [ ( diff --git a/crates/brk_computer/src/market/returns/compute.rs b/crates/brk_computer/src/market/returns/compute.rs index 2c95008c2..ec5ed8e78 100644 --- a/crates/brk_computer/src/market/returns/compute.rs +++ b/crates/brk_computer/src/market/returns/compute.rs @@ -22,7 +22,7 @@ impl Vecs { { returns.compute_binary::( starting_indexes.height, - &prices.price.usd.height, + &prices.spot.usd.height, &lookback_price.usd.height, exit, )?; diff --git a/crates/brk_computer/src/market/technical/compute.rs b/crates/brk_computer/src/market/technical/compute.rs index 5a5f1ba26..71b611452 100644 --- a/crates/brk_computer/src/market/technical/compute.rs +++ b/crates/brk_computer/src/market/technical/compute.rs @@ -24,7 +24,7 @@ impl Vecs { ) -> Result<()> { // Stochastic Oscillator: K = (close - low_2w) / (high_2w - low_2w), stored as ratio (0-1) { - let price = &prices.price.usd.height; + let price = &prices.spot.usd.height; self.stoch_k.bps.height.compute_transform3( starting_indexes.height, price, diff --git a/crates/brk_computer/src/market/technical/macd.rs b/crates/brk_computer/src/market/technical/macd.rs index a9728e5d3..9d5ccfac3 100644 --- a/crates/brk_computer/src/market/technical/macd.rs +++ b/crates/brk_computer/src/market/technical/macd.rs @@ -16,7 +16,7 @@ pub(super) fn compute( starting_indexes: &Indexes, exit: &Exit, ) -> Result<()> { - let close = &prices.price.usd.height; + let close = &prices.spot.usd.height; let ws_fast = blocks.lookback.start_vec(fast_days); let ws_slow = blocks.lookback.start_vec(slow_days); let ws_signal = blocks.lookback.start_vec(signal_days); diff --git a/crates/brk_computer/src/mining/rewards/compute.rs b/crates/brk_computer/src/mining/rewards/compute.rs index f01662438..235c3a11f 100644 --- a/crates/brk_computer/src/mining/rewards/compute.rs +++ b/crates/brk_computer/src/mining/rewards/compute.rs @@ -92,7 +92,7 @@ impl Vecs { )?; self.subsidy.compute(prices, starting_indexes.height, exit)?; - self.unclaimed_rewards.compute( + self.unclaimed.compute( starting_indexes.height, &window_starts, prices, diff --git a/crates/brk_computer/src/mining/rewards/import.rs b/crates/brk_computer/src/mining/rewards/import.rs index 6b2d3737c..cf638cbcc 100644 --- a/crates/brk_computer/src/mining/rewards/import.rs +++ b/crates/brk_computer/src/mining/rewards/import.rs @@ -23,7 +23,7 @@ impl Vecs { )?, subsidy: AmountPerBlockCumulative::forced_import(db, "subsidy", version, indexes)?, fees: AmountPerBlockFull::forced_import(db, "fees", version, indexes)?, - unclaimed_rewards: AmountPerBlockCumulativeSum::forced_import( + unclaimed: AmountPerBlockCumulativeSum::forced_import( db, "unclaimed_rewards", version, diff --git a/crates/brk_computer/src/mining/rewards/vecs.rs b/crates/brk_computer/src/mining/rewards/vecs.rs index 53338342f..94da4fb63 100644 --- a/crates/brk_computer/src/mining/rewards/vecs.rs +++ b/crates/brk_computer/src/mining/rewards/vecs.rs @@ -12,13 +12,17 @@ pub struct Vecs { pub coinbase: AmountPerBlockCumulativeSum, pub subsidy: AmountPerBlockCumulative, pub fees: AmountPerBlockFull, - pub unclaimed_rewards: AmountPerBlockCumulativeSum, + pub unclaimed: AmountPerBlockCumulativeSum, + #[traversable(wrap = "fees", rename = "dominance")] pub fee_dominance: PercentPerBlock, - #[traversable(rename = "fee_dominance")] + #[traversable(wrap = "fees", rename = "dominance")] pub fee_dominance_rolling: PercentRollingWindows, + #[traversable(wrap = "subsidy", rename = "dominance")] pub subsidy_dominance: PercentPerBlock, - #[traversable(rename = "subsidy_dominance")] + #[traversable(wrap = "subsidy", rename = "dominance")] pub subsidy_dominance_rolling: PercentRollingWindows, + #[traversable(wrap = "subsidy", rename = "sma_1y")] pub subsidy_sma_1y: FiatPerBlock, + #[traversable(wrap = "fees", rename = "ratio_multiple")] pub fee_ratio_multiple: RatioRollingWindows, } diff --git a/crates/brk_computer/src/outputs/count/compute.rs b/crates/brk_computer/src/outputs/count/compute.rs index 30e7845d7..a0f9c5cf7 100644 --- a/crates/brk_computer/src/outputs/count/compute.rs +++ b/crates/brk_computer/src/outputs/count/compute.rs @@ -31,7 +31,7 @@ impl Vecs { ) })?; - self.utxo_count.height.compute_transform3( + self.unspent.height.compute_transform3( starting_indexes.height, &self.total.full.cumulative, &inputs_count.full.cumulative, diff --git a/crates/brk_computer/src/outputs/count/import.rs b/crates/brk_computer/src/outputs/count/import.rs index 5e6ddc16f..28905529d 100644 --- a/crates/brk_computer/src/outputs/count/import.rs +++ b/crates/brk_computer/src/outputs/count/import.rs @@ -21,7 +21,7 @@ impl Vecs { version, indexes, )?, - utxo_count: ComputedPerBlock::forced_import( + unspent: ComputedPerBlock::forced_import( db, "exact_utxo_count", version, diff --git a/crates/brk_computer/src/outputs/count/vecs.rs b/crates/brk_computer/src/outputs/count/vecs.rs index babdc2c9b..9e89486dc 100644 --- a/crates/brk_computer/src/outputs/count/vecs.rs +++ b/crates/brk_computer/src/outputs/count/vecs.rs @@ -7,5 +7,5 @@ use crate::internal::{ComputedPerBlock, ComputedPerBlockAggregated}; #[derive(Traversable)] pub struct Vecs { pub total: ComputedPerBlockAggregated, - pub utxo_count: ComputedPerBlock, + pub unspent: ComputedPerBlock, } diff --git a/crates/brk_computer/src/pools/mod.rs b/crates/brk_computer/src/pools/mod.rs index 6837474fe..6063908a8 100644 --- a/crates/brk_computer/src/pools/mod.rs +++ b/crates/brk_computer/src/pools/mod.rs @@ -120,14 +120,14 @@ impl Vecs { let first_txoutindex = indexer.vecs.transactions.first_txoutindex.reader(); let outputtype = indexer.vecs.outputs.outputtype.reader(); let typeindex = indexer.vecs.outputs.typeindex.reader(); - let p2pk65 = indexer.vecs.addresses.p2pk65bytes.reader(); - let p2pk33 = indexer.vecs.addresses.p2pk33bytes.reader(); - let p2pkh = indexer.vecs.addresses.p2pkhbytes.reader(); - let p2sh = indexer.vecs.addresses.p2shbytes.reader(); - let p2wpkh = indexer.vecs.addresses.p2wpkhbytes.reader(); - let p2wsh = indexer.vecs.addresses.p2wshbytes.reader(); - let p2tr = indexer.vecs.addresses.p2trbytes.reader(); - let p2a = indexer.vecs.addresses.p2abytes.reader(); + let p2pk65 = indexer.vecs.addresses.p2pk65.bytes.reader(); + let p2pk33 = indexer.vecs.addresses.p2pk33.bytes.reader(); + let p2pkh = indexer.vecs.addresses.p2pkh.bytes.reader(); + let p2sh = indexer.vecs.addresses.p2sh.bytes.reader(); + let p2wpkh = indexer.vecs.addresses.p2wpkh.bytes.reader(); + let p2wsh = indexer.vecs.addresses.p2wsh.bytes.reader(); + let p2tr = indexer.vecs.addresses.p2tr.bytes.reader(); + let p2a = indexer.vecs.addresses.p2a.bytes.reader(); let unknown = self.pools.get_unknown(); diff --git a/crates/brk_computer/src/prices/compute.rs b/crates/brk_computer/src/prices/compute.rs index b1ba18347..018e05b3e 100644 --- a/crates/brk_computer/src/prices/compute.rs +++ b/crates/brk_computer/src/prices/compute.rs @@ -73,7 +73,7 @@ impl Vecs { // Reorg: truncate to starting_indexes let truncate_to = self - .price + .spot .cents .height .len() @@ -101,7 +101,7 @@ impl Vecs { let config = Config::default(); let committed = self.spot.cents.height.len(); let prev_cents = self - .price + .spot .cents .height .collect_one_at(committed - 1) @@ -234,7 +234,7 @@ impl Vecs { let config = Config::default(); let height = indexer.vecs.blocks.timestamp.len(); let last_cents = self - .price + .spot .cents .height .collect_one_at(self.spot.cents.height.len() - 1) diff --git a/crates/brk_computer/src/scripts/count/compute.rs b/crates/brk_computer/src/scripts/count/compute.rs index 252c68a45..e4925d5db 100644 --- a/crates/brk_computer/src/scripts/count/compute.rs +++ b/crates/brk_computer/src/scripts/count/compute.rs @@ -20,8 +20,8 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, exit, |v| { Ok(v.compute_count_from_indexes( starting_indexes.height, - &indexer.vecs.addresses.first_p2aaddressindex, - &indexer.vecs.addresses.p2abytes, + &indexer.vecs.addresses.p2a.first_index, + &indexer.vecs.addresses.p2a.bytes, exit, )?) })?; @@ -30,8 +30,8 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, exit, |v| { Ok(v.compute_count_from_indexes( starting_indexes.height, - &indexer.vecs.scripts.first_p2msoutputindex, - &indexer.vecs.scripts.p2ms_to_txindex, + &indexer.vecs.scripts.p2ms.first_index, + &indexer.vecs.scripts.p2ms.to_txindex, exit, )?) })?; @@ -40,8 +40,8 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, exit, |v| { Ok(v.compute_count_from_indexes( starting_indexes.height, - &indexer.vecs.addresses.first_p2pk33addressindex, - &indexer.vecs.addresses.p2pk33bytes, + &indexer.vecs.addresses.p2pk33.first_index, + &indexer.vecs.addresses.p2pk33.bytes, exit, )?) })?; @@ -50,8 +50,8 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, exit, |v| { Ok(v.compute_count_from_indexes( starting_indexes.height, - &indexer.vecs.addresses.first_p2pk65addressindex, - &indexer.vecs.addresses.p2pk65bytes, + &indexer.vecs.addresses.p2pk65.first_index, + &indexer.vecs.addresses.p2pk65.bytes, exit, )?) })?; @@ -60,8 +60,8 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, exit, |v| { Ok(v.compute_count_from_indexes( starting_indexes.height, - &indexer.vecs.addresses.first_p2pkhaddressindex, - &indexer.vecs.addresses.p2pkhbytes, + &indexer.vecs.addresses.p2pkh.first_index, + &indexer.vecs.addresses.p2pkh.bytes, exit, )?) })?; @@ -70,8 +70,8 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, exit, |v| { Ok(v.compute_count_from_indexes( starting_indexes.height, - &indexer.vecs.addresses.first_p2shaddressindex, - &indexer.vecs.addresses.p2shbytes, + &indexer.vecs.addresses.p2sh.first_index, + &indexer.vecs.addresses.p2sh.bytes, exit, )?) })?; @@ -80,8 +80,8 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, exit, |v| { Ok(v.compute_count_from_indexes( starting_indexes.height, - &indexer.vecs.addresses.first_p2traddressindex, - &indexer.vecs.addresses.p2trbytes, + &indexer.vecs.addresses.p2tr.first_index, + &indexer.vecs.addresses.p2tr.bytes, exit, )?) })?; @@ -90,8 +90,8 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, exit, |v| { Ok(v.compute_count_from_indexes( starting_indexes.height, - &indexer.vecs.addresses.first_p2wpkhaddressindex, - &indexer.vecs.addresses.p2wpkhbytes, + &indexer.vecs.addresses.p2wpkh.first_index, + &indexer.vecs.addresses.p2wpkh.bytes, exit, )?) })?; @@ -100,8 +100,8 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, exit, |v| { Ok(v.compute_count_from_indexes( starting_indexes.height, - &indexer.vecs.addresses.first_p2wshaddressindex, - &indexer.vecs.addresses.p2wshbytes, + &indexer.vecs.addresses.p2wsh.first_index, + &indexer.vecs.addresses.p2wsh.bytes, exit, )?) })?; @@ -110,8 +110,8 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, exit, |v| { Ok(v.compute_count_from_indexes( starting_indexes.height, - &indexer.vecs.scripts.first_opreturnindex, - &indexer.vecs.scripts.opreturn_to_txindex, + &indexer.vecs.scripts.opreturn.first_index, + &indexer.vecs.scripts.opreturn.to_txindex, exit, )?) })?; @@ -120,8 +120,8 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, exit, |v| { Ok(v.compute_count_from_indexes( starting_indexes.height, - &indexer.vecs.scripts.first_unknownoutputindex, - &indexer.vecs.scripts.unknown_to_txindex, + &indexer.vecs.scripts.unknown.first_index, + &indexer.vecs.scripts.unknown.to_txindex, exit, )?) })?; @@ -130,8 +130,8 @@ impl Vecs { .compute(starting_indexes.height, &window_starts, exit, |v| { Ok(v.compute_count_from_indexes( starting_indexes.height, - &indexer.vecs.scripts.first_emptyoutputindex, - &indexer.vecs.scripts.empty_to_txindex, + &indexer.vecs.scripts.empty.first_index, + &indexer.vecs.scripts.empty.to_txindex, exit, )?) })?; diff --git a/crates/brk_computer/src/supply/burned/compute.rs b/crates/brk_computer/src/supply/burned/compute.rs index 08ee78c53..1c26427c9 100644 --- a/crates/brk_computer/src/supply/burned/compute.rs +++ b/crates/brk_computer/src/supply/burned/compute.rs @@ -60,7 +60,7 @@ impl Vecs { // 2. Compute unspendable supply = opreturn + unclaimed_rewards + genesis (at height 0) // Get reference to opreturn height vec for computing unspendable let opreturn_height = &self.opreturn.base.sats.height; - let unclaimed_height = &mining.rewards.unclaimed_rewards.base.sats.height; + let unclaimed_height = &mining.rewards.unclaimed.base.sats.height; self.unspendable.compute( starting_indexes.height, diff --git a/crates/brk_computer/src/transactions/volume/compute.rs b/crates/brk_computer/src/transactions/volume/compute.rs index cbe78a628..ad7876e2c 100644 --- a/crates/brk_computer/src/transactions/volume/compute.rs +++ b/crates/brk_computer/src/transactions/volume/compute.rs @@ -58,13 +58,13 @@ impl Vecs { )?; // Annualized volume: rolling 1y sum of per-block sent volume - self.annualized_volume.sats.height.compute_rolling_sum( + self.annualized.sats.height.compute_rolling_sum( starting_indexes.height, &blocks.lookback._1y, &self.sent_sum.sats, exit, )?; - self.annualized_volume + self.annualized .compute(prices, starting_indexes.height, exit)?; self.tx_per_sec diff --git a/crates/brk_computer/src/transactions/volume/import.rs b/crates/brk_computer/src/transactions/volume/import.rs index 4095ed580..328454cfd 100644 --- a/crates/brk_computer/src/transactions/volume/import.rs +++ b/crates/brk_computer/src/transactions/volume/import.rs @@ -23,7 +23,7 @@ impl Vecs { version, indexes, )?, - annualized_volume: AmountPerBlock::forced_import( + annualized: AmountPerBlock::forced_import( db, "annualized_volume", version, diff --git a/crates/brk_computer/src/transactions/volume/vecs.rs b/crates/brk_computer/src/transactions/volume/vecs.rs index f2c286f25..aa887442e 100644 --- a/crates/brk_computer/src/transactions/volume/vecs.rs +++ b/crates/brk_computer/src/transactions/volume/vecs.rs @@ -8,7 +8,7 @@ use crate::internal::{AmountPerBlock, AmountPerBlockRolling, ComputedPerBlock}; pub struct Vecs { pub sent_sum: AmountPerBlockRolling, pub received_sum: AmountPerBlockRolling, - pub annualized_volume: AmountPerBlock, + pub annualized: AmountPerBlock, pub tx_per_sec: ComputedPerBlock, pub outputs_per_sec: ComputedPerBlock, pub inputs_per_sec: ComputedPerBlock, diff --git a/crates/brk_error/src/lib.rs b/crates/brk_error/src/lib.rs index 33c303bc4..ea9c1e801 100644 --- a/crates/brk_error/src/lib.rs +++ b/crates/brk_error/src/lib.rs @@ -117,7 +117,7 @@ pub enum Error { #[error("{0}")] OutOfRange(String), - #[error("Parse error: {0}")] + #[error("{0}")] Parse(String), #[error("Internal error: {0}")] @@ -136,6 +136,9 @@ pub enum Error { #[error("No metrics specified")] NoMetrics, + #[error("No data available")] + NoData, + #[error("Request weight {requested} exceeds maximum {max}")] WeightExceeded { requested: usize, max: usize }, diff --git a/crates/brk_indexer/Cargo.toml b/crates/brk_indexer/Cargo.toml index 1ff8e3285..ad5ac7c2c 100644 --- a/crates/brk_indexer/Cargo.toml +++ b/crates/brk_indexer/Cargo.toml @@ -20,6 +20,8 @@ brk_store = { workspace = true } brk_types = { workspace = true } brk_traversable = { workspace = true } fjall = { workspace = true } +schemars = { workspace = true } +serde = { workspace = true } tracing = { workspace = true } rayon = { workspace = true } rlimit = "0.11.0" diff --git a/crates/brk_indexer/src/indexes.rs b/crates/brk_indexer/src/indexes.rs index 09b8e2945..e673a69cf 100644 --- a/crates/brk_indexer/src/indexes.rs +++ b/crates/brk_indexer/src/indexes.rs @@ -30,40 +30,40 @@ impl IndexesExt for Indexes { .first_txoutindex .checked_push(height, self.txoutindex)?; vecs.scripts - .first_emptyoutputindex + .empty.first_index .checked_push(height, self.emptyoutputindex)?; vecs.scripts - .first_p2msoutputindex + .p2ms.first_index .checked_push(height, self.p2msoutputindex)?; vecs.scripts - .first_opreturnindex + .opreturn.first_index .checked_push(height, self.opreturnindex)?; vecs.addresses - .first_p2aaddressindex + .p2a.first_index .checked_push(height, self.p2aaddressindex)?; vecs.scripts - .first_unknownoutputindex + .unknown.first_index .checked_push(height, self.unknownoutputindex)?; vecs.addresses - .first_p2pk33addressindex + .p2pk33.first_index .checked_push(height, self.p2pk33addressindex)?; vecs.addresses - .first_p2pk65addressindex + .p2pk65.first_index .checked_push(height, self.p2pk65addressindex)?; vecs.addresses - .first_p2pkhaddressindex + .p2pkh.first_index .checked_push(height, self.p2pkhaddressindex)?; vecs.addresses - .first_p2shaddressindex + .p2sh.first_index .checked_push(height, self.p2shaddressindex)?; vecs.addresses - .first_p2traddressindex + .p2tr.first_index .checked_push(height, self.p2traddressindex)?; vecs.addresses - .first_p2wpkhaddressindex + .p2wpkh.first_index .checked_push(height, self.p2wpkhaddressindex)?; vecs.addresses - .first_p2wshaddressindex + .p2wsh.first_index .checked_push(height, self.p2wshaddressindex)?; Ok(()) @@ -98,68 +98,68 @@ impl IndexesExt for Indexes { }; let emptyoutputindex = starting_index( - &vecs.scripts.first_emptyoutputindex, - &vecs.scripts.empty_to_txindex, + &vecs.scripts.empty.first_index, + &vecs.scripts.empty.to_txindex, starting_height, )?; let p2msoutputindex = starting_index( - &vecs.scripts.first_p2msoutputindex, - &vecs.scripts.p2ms_to_txindex, + &vecs.scripts.p2ms.first_index, + &vecs.scripts.p2ms.to_txindex, starting_height, )?; let opreturnindex = starting_index( - &vecs.scripts.first_opreturnindex, - &vecs.scripts.opreturn_to_txindex, + &vecs.scripts.opreturn.first_index, + &vecs.scripts.opreturn.to_txindex, starting_height, )?; let p2pk33addressindex = starting_index( - &vecs.addresses.first_p2pk33addressindex, - &vecs.addresses.p2pk33bytes, + &vecs.addresses.p2pk33.first_index, + &vecs.addresses.p2pk33.bytes, starting_height, )?; let p2pk65addressindex = starting_index( - &vecs.addresses.first_p2pk65addressindex, - &vecs.addresses.p2pk65bytes, + &vecs.addresses.p2pk65.first_index, + &vecs.addresses.p2pk65.bytes, starting_height, )?; let p2pkhaddressindex = starting_index( - &vecs.addresses.first_p2pkhaddressindex, - &vecs.addresses.p2pkhbytes, + &vecs.addresses.p2pkh.first_index, + &vecs.addresses.p2pkh.bytes, starting_height, )?; let p2shaddressindex = starting_index( - &vecs.addresses.first_p2shaddressindex, - &vecs.addresses.p2shbytes, + &vecs.addresses.p2sh.first_index, + &vecs.addresses.p2sh.bytes, starting_height, )?; let p2traddressindex = starting_index( - &vecs.addresses.first_p2traddressindex, - &vecs.addresses.p2trbytes, + &vecs.addresses.p2tr.first_index, + &vecs.addresses.p2tr.bytes, starting_height, )?; let p2wpkhaddressindex = starting_index( - &vecs.addresses.first_p2wpkhaddressindex, - &vecs.addresses.p2wpkhbytes, + &vecs.addresses.p2wpkh.first_index, + &vecs.addresses.p2wpkh.bytes, starting_height, )?; let p2wshaddressindex = starting_index( - &vecs.addresses.first_p2wshaddressindex, - &vecs.addresses.p2wshbytes, + &vecs.addresses.p2wsh.first_index, + &vecs.addresses.p2wsh.bytes, starting_height, )?; let p2aaddressindex = starting_index( - &vecs.addresses.first_p2aaddressindex, - &vecs.addresses.p2abytes, + &vecs.addresses.p2a.first_index, + &vecs.addresses.p2a.bytes, starting_height, )?; @@ -182,8 +182,8 @@ impl IndexesExt for Indexes { )?; let unknownoutputindex = starting_index( - &vecs.scripts.first_unknownoutputindex, - &vecs.scripts.unknown_to_txindex, + &vecs.scripts.unknown.first_index, + &vecs.scripts.unknown.to_txindex, starting_height, )?; diff --git a/crates/brk_indexer/src/processor/txout.rs b/crates/brk_indexer/src/processor/txout.rs index ded57a328..59a76a997 100644 --- a/crates/brk_indexer/src/processor/txout.rs +++ b/crates/brk_indexer/src/processor/txout.rs @@ -168,25 +168,25 @@ pub(super) fn finalize_outputs( match outputtype { OutputType::P2MS => { scripts - .p2ms_to_txindex + .p2ms.to_txindex .checked_push(indexes.p2msoutputindex, txindex)?; indexes.p2msoutputindex.copy_then_increment() } OutputType::OpReturn => { scripts - .opreturn_to_txindex + .opreturn.to_txindex .checked_push(indexes.opreturnindex, txindex)?; indexes.opreturnindex.copy_then_increment() } OutputType::Empty => { scripts - .empty_to_txindex + .empty.to_txindex .checked_push(indexes.emptyoutputindex, txindex)?; indexes.emptyoutputindex.copy_then_increment() } OutputType::Unknown => { scripts - .unknown_to_txindex + .unknown.to_txindex .checked_push(indexes.unknownoutputindex, txindex)?; indexes.unknownoutputindex.copy_then_increment() } diff --git a/crates/brk_indexer/src/readers.rs b/crates/brk_indexer/src/readers.rs index 098c95b28..d0c1ec638 100644 --- a/crates/brk_indexer/src/readers.rs +++ b/crates/brk_indexer/src/readers.rs @@ -39,14 +39,14 @@ impl Readers { txoutindex_to_outputtype: vecs.outputs.outputtype.reader(), txoutindex_to_typeindex: vecs.outputs.typeindex.reader(), addressbytes: AddressReaders { - p2pk65: vecs.addresses.p2pk65bytes.reader(), - p2pk33: vecs.addresses.p2pk33bytes.reader(), - p2pkh: vecs.addresses.p2pkhbytes.reader(), - p2sh: vecs.addresses.p2shbytes.reader(), - p2wpkh: vecs.addresses.p2wpkhbytes.reader(), - p2wsh: vecs.addresses.p2wshbytes.reader(), - p2tr: vecs.addresses.p2trbytes.reader(), - p2a: vecs.addresses.p2abytes.reader(), + p2pk65: vecs.addresses.p2pk65.bytes.reader(), + p2pk33: vecs.addresses.p2pk33.bytes.reader(), + p2pkh: vecs.addresses.p2pkh.bytes.reader(), + p2sh: vecs.addresses.p2sh.bytes.reader(), + p2wpkh: vecs.addresses.p2wpkh.bytes.reader(), + p2wsh: vecs.addresses.p2wsh.bytes.reader(), + p2tr: vecs.addresses.p2tr.bytes.reader(), + p2a: vecs.addresses.p2a.bytes.reader(), }, } } diff --git a/crates/brk_indexer/src/vecs/addresses.rs b/crates/brk_indexer/src/vecs/addresses.rs index 9952a7bce..7c0ca24ea 100644 --- a/crates/brk_indexer/src/vecs/addresses.rs +++ b/crates/brk_indexer/src/vecs/addresses.rs @@ -7,34 +7,32 @@ use brk_types::{ P2WSHBytes, TypeIndex, Version, }; use rayon::prelude::*; +use schemars::JsonSchema; +use serde::Serialize; use vecdb::{ - AnyStoredVec, BytesVec, Database, ImportableVec, PcoVec, ReadableVec, Rw, Stamp, StorageMode, - VecIndex, WritableVec, + AnyStoredVec, BytesVec, BytesVecValue, Database, Formattable, ImportableVec, PcoVec, + PcoVecValue, ReadableVec, Rw, Stamp, StorageMode, VecIndex, WritableVec, }; use crate::parallel_import; use crate::readers::AddressReaders; +#[derive(Traversable)] +pub struct AddressTypeVecs { + pub first_index: M::Stored>, + pub bytes: M::Stored>, +} + #[derive(Traversable)] pub struct AddressesVecs { - // Height to first address index (per address type) - pub first_p2pk65addressindex: M::Stored>, - pub first_p2pk33addressindex: M::Stored>, - pub first_p2pkhaddressindex: M::Stored>, - pub first_p2shaddressindex: M::Stored>, - pub first_p2wpkhaddressindex: M::Stored>, - pub first_p2wshaddressindex: M::Stored>, - pub first_p2traddressindex: M::Stored>, - pub first_p2aaddressindex: M::Stored>, - // Address index to bytes (per address type) - pub p2pk65bytes: M::Stored>, - pub p2pk33bytes: M::Stored>, - pub p2pkhbytes: M::Stored>, - pub p2shbytes: M::Stored>, - pub p2wpkhbytes: M::Stored>, - pub p2wshbytes: M::Stored>, - pub p2trbytes: M::Stored>, - pub p2abytes: M::Stored>, + pub p2pk65: AddressTypeVecs, + pub p2pk33: AddressTypeVecs, + pub p2pkh: AddressTypeVecs, + pub p2sh: AddressTypeVecs, + pub p2wpkh: AddressTypeVecs, + pub p2wsh: AddressTypeVecs, + pub p2tr: AddressTypeVecs, + pub p2a: AddressTypeVecs, } impl AddressesVecs { @@ -75,22 +73,14 @@ impl AddressesVecs { p2abytes = BytesVec::forced_import(db, "p2abytes", version), }; Ok(Self { - first_p2pk65addressindex, - first_p2pk33addressindex, - first_p2pkhaddressindex, - first_p2shaddressindex, - first_p2wpkhaddressindex, - first_p2wshaddressindex, - first_p2traddressindex, - first_p2aaddressindex, - p2pk65bytes, - p2pk33bytes, - p2pkhbytes, - p2shbytes, - p2wpkhbytes, - p2wshbytes, - p2trbytes, - p2abytes, + p2pk65: AddressTypeVecs { first_index: first_p2pk65addressindex, bytes: p2pk65bytes }, + p2pk33: AddressTypeVecs { first_index: first_p2pk33addressindex, bytes: p2pk33bytes }, + p2pkh: AddressTypeVecs { first_index: first_p2pkhaddressindex, bytes: p2pkhbytes }, + p2sh: AddressTypeVecs { first_index: first_p2shaddressindex, bytes: p2shbytes }, + p2wpkh: AddressTypeVecs { first_index: first_p2wpkhaddressindex, bytes: p2wpkhbytes }, + p2wsh: AddressTypeVecs { first_index: first_p2wshaddressindex, bytes: p2wshbytes }, + p2tr: AddressTypeVecs { first_index: first_p2traddressindex, bytes: p2trbytes }, + p2a: AddressTypeVecs { first_index: first_p2aaddressindex, bytes: p2abytes }, }) } @@ -108,59 +98,59 @@ impl AddressesVecs { p2aaddressindex: P2AAddressIndex, stamp: Stamp, ) -> Result<()> { - self.first_p2pk65addressindex + self.p2pk65.first_index .truncate_if_needed_with_stamp(height, stamp)?; - self.first_p2pk33addressindex + self.p2pk33.first_index .truncate_if_needed_with_stamp(height, stamp)?; - self.first_p2pkhaddressindex + self.p2pkh.first_index .truncate_if_needed_with_stamp(height, stamp)?; - self.first_p2shaddressindex + self.p2sh.first_index .truncate_if_needed_with_stamp(height, stamp)?; - self.first_p2wpkhaddressindex + self.p2wpkh.first_index .truncate_if_needed_with_stamp(height, stamp)?; - self.first_p2wshaddressindex + self.p2wsh.first_index .truncate_if_needed_with_stamp(height, stamp)?; - self.first_p2traddressindex + self.p2tr.first_index .truncate_if_needed_with_stamp(height, stamp)?; - self.first_p2aaddressindex + self.p2a.first_index .truncate_if_needed_with_stamp(height, stamp)?; - self.p2pk65bytes + self.p2pk65.bytes .truncate_if_needed_with_stamp(p2pk65addressindex, stamp)?; - self.p2pk33bytes + self.p2pk33.bytes .truncate_if_needed_with_stamp(p2pk33addressindex, stamp)?; - self.p2pkhbytes + self.p2pkh.bytes .truncate_if_needed_with_stamp(p2pkhaddressindex, stamp)?; - self.p2shbytes + self.p2sh.bytes .truncate_if_needed_with_stamp(p2shaddressindex, stamp)?; - self.p2wpkhbytes + self.p2wpkh.bytes .truncate_if_needed_with_stamp(p2wpkhaddressindex, stamp)?; - self.p2wshbytes + self.p2wsh.bytes .truncate_if_needed_with_stamp(p2wshaddressindex, stamp)?; - self.p2trbytes + self.p2tr.bytes .truncate_if_needed_with_stamp(p2traddressindex, stamp)?; - self.p2abytes + self.p2a.bytes .truncate_if_needed_with_stamp(p2aaddressindex, stamp)?; Ok(()) } pub fn par_iter_mut_any(&mut self) -> impl ParallelIterator { [ - &mut self.first_p2pk65addressindex as &mut dyn AnyStoredVec, - &mut self.first_p2pk33addressindex, - &mut self.first_p2pkhaddressindex, - &mut self.first_p2shaddressindex, - &mut self.first_p2wpkhaddressindex, - &mut self.first_p2wshaddressindex, - &mut self.first_p2traddressindex, - &mut self.first_p2aaddressindex, - &mut self.p2pk65bytes, - &mut self.p2pk33bytes, - &mut self.p2pkhbytes, - &mut self.p2shbytes, - &mut self.p2wpkhbytes, - &mut self.p2wshbytes, - &mut self.p2trbytes, - &mut self.p2abytes, + &mut self.p2pk65.first_index as &mut dyn AnyStoredVec, + &mut self.p2pk33.first_index, + &mut self.p2pkh.first_index, + &mut self.p2sh.first_index, + &mut self.p2wpkh.first_index, + &mut self.p2wsh.first_index, + &mut self.p2tr.first_index, + &mut self.p2a.first_index, + &mut self.p2pk65.bytes, + &mut self.p2pk33.bytes, + &mut self.p2pkh.bytes, + &mut self.p2sh.bytes, + &mut self.p2wpkh.bytes, + &mut self.p2wsh.bytes, + &mut self.p2tr.bytes, + &mut self.p2a.bytes, ] .into_par_iter() } @@ -175,35 +165,35 @@ impl AddressesVecs { ) -> Option { match addresstype { OutputType::P2PK65 => self - .p2pk65bytes + .p2pk65.bytes .get_pushed_or_read(typeindex.into(), &readers.p2pk65) .map(AddressBytes::from), OutputType::P2PK33 => self - .p2pk33bytes + .p2pk33.bytes .get_pushed_or_read(typeindex.into(), &readers.p2pk33) .map(AddressBytes::from), OutputType::P2PKH => self - .p2pkhbytes + .p2pkh.bytes .get_pushed_or_read(typeindex.into(), &readers.p2pkh) .map(AddressBytes::from), OutputType::P2SH => self - .p2shbytes + .p2sh.bytes .get_pushed_or_read(typeindex.into(), &readers.p2sh) .map(AddressBytes::from), OutputType::P2WPKH => self - .p2wpkhbytes + .p2wpkh.bytes .get_pushed_or_read(typeindex.into(), &readers.p2wpkh) .map(AddressBytes::from), OutputType::P2WSH => self - .p2wshbytes + .p2wsh.bytes .get_pushed_or_read(typeindex.into(), &readers.p2wsh) .map(AddressBytes::from), OutputType::P2TR => self - .p2trbytes + .p2tr.bytes .get_pushed_or_read(typeindex.into(), &readers.p2tr) .map(AddressBytes::from), OutputType::P2A => self - .p2abytes + .p2a.bytes .get_pushed_or_read(typeindex.into(), &readers.p2a) .map(AddressBytes::from), _ => unreachable!("get_bytes_by_type called with non-address type"), @@ -212,14 +202,14 @@ impl AddressesVecs { pub fn push_bytes_if_needed(&mut self, index: TypeIndex, bytes: AddressBytes) -> Result<()> { match bytes { - AddressBytes::P2PK65(bytes) => self.p2pk65bytes.checked_push(index.into(), bytes)?, - AddressBytes::P2PK33(bytes) => self.p2pk33bytes.checked_push(index.into(), bytes)?, - AddressBytes::P2PKH(bytes) => self.p2pkhbytes.checked_push(index.into(), bytes)?, - AddressBytes::P2SH(bytes) => self.p2shbytes.checked_push(index.into(), bytes)?, - AddressBytes::P2WPKH(bytes) => self.p2wpkhbytes.checked_push(index.into(), bytes)?, - AddressBytes::P2WSH(bytes) => self.p2wshbytes.checked_push(index.into(), bytes)?, - AddressBytes::P2TR(bytes) => self.p2trbytes.checked_push(index.into(), bytes)?, - AddressBytes::P2A(bytes) => self.p2abytes.checked_push(index.into(), bytes)?, + AddressBytes::P2PK65(bytes) => self.p2pk65.bytes.checked_push(index.into(), bytes)?, + AddressBytes::P2PK33(bytes) => self.p2pk33.bytes.checked_push(index.into(), bytes)?, + AddressBytes::P2PKH(bytes) => self.p2pkh.bytes.checked_push(index.into(), bytes)?, + AddressBytes::P2SH(bytes) => self.p2sh.bytes.checked_push(index.into(), bytes)?, + AddressBytes::P2WPKH(bytes) => self.p2wpkh.bytes.checked_push(index.into(), bytes)?, + AddressBytes::P2WSH(bytes) => self.p2wsh.bytes.checked_push(index.into(), bytes)?, + AddressBytes::P2TR(bytes) => self.p2tr.bytes.checked_push(index.into(), bytes)?, + AddressBytes::P2A(bytes) => self.p2a.bytes.checked_push(index.into(), bytes)?, }; Ok(()) } @@ -233,10 +223,10 @@ impl AddressesVecs { height: Height, ) -> Result + '_>> { macro_rules! make_iter { - ($height_vec:expr, $bytes_vec:expr) => {{ - match $height_vec.collect_one(height) { + ($addr:expr) => {{ + match $addr.first_index.collect_one(height) { Some(mut index) => { - let reader = $bytes_vec.reader(); + let reader = $addr.bytes.reader(); Ok(Box::new(std::iter::from_fn(move || { reader.try_get(index.to_usize()).map(|typedbytes| { let bytes = AddressBytes::from(typedbytes); @@ -255,14 +245,14 @@ impl AddressesVecs { } match address_type { - OutputType::P2PK65 => make_iter!(self.first_p2pk65addressindex, self.p2pk65bytes), - OutputType::P2PK33 => make_iter!(self.first_p2pk33addressindex, self.p2pk33bytes), - OutputType::P2PKH => make_iter!(self.first_p2pkhaddressindex, self.p2pkhbytes), - OutputType::P2SH => make_iter!(self.first_p2shaddressindex, self.p2shbytes), - OutputType::P2WPKH => make_iter!(self.first_p2wpkhaddressindex, self.p2wpkhbytes), - OutputType::P2WSH => make_iter!(self.first_p2wshaddressindex, self.p2wshbytes), - OutputType::P2TR => make_iter!(self.first_p2traddressindex, self.p2trbytes), - OutputType::P2A => make_iter!(self.first_p2aaddressindex, self.p2abytes), + OutputType::P2PK65 => make_iter!(self.p2pk65), + OutputType::P2PK33 => make_iter!(self.p2pk33), + OutputType::P2PKH => make_iter!(self.p2pkh), + OutputType::P2SH => make_iter!(self.p2sh), + OutputType::P2WPKH => make_iter!(self.p2wpkh), + OutputType::P2WSH => make_iter!(self.p2wsh), + OutputType::P2TR => make_iter!(self.p2tr), + OutputType::P2A => make_iter!(self.p2a), _ => Ok(Box::new(std::iter::empty())), } } diff --git a/crates/brk_indexer/src/vecs/mod.rs b/crates/brk_indexer/src/vecs/mod.rs index 9497eca76..2abf8f997 100644 --- a/crates/brk_indexer/src/vecs/mod.rs +++ b/crates/brk_indexer/src/vecs/mod.rs @@ -32,10 +32,15 @@ pub struct Vecs { #[traversable(skip)] db: Database, pub blocks: BlocksVecs, + #[traversable(wrap = "transactions", rename = "raw")] pub transactions: TransactionsVecs, + #[traversable(wrap = "inputs", rename = "raw")] pub inputs: InputsVecs, + #[traversable(wrap = "outputs", rename = "raw")] pub outputs: OutputsVecs, + #[traversable(wrap = "addresses", rename = "raw")] pub addresses: AddressesVecs, + #[traversable(wrap = "scripts", rename = "raw")] pub scripts: ScriptsVecs, } diff --git a/crates/brk_indexer/src/vecs/scripts.rs b/crates/brk_indexer/src/vecs/scripts.rs index d08136f7e..e74140070 100644 --- a/crates/brk_indexer/src/vecs/scripts.rs +++ b/crates/brk_indexer/src/vecs/scripts.rs @@ -4,22 +4,27 @@ use brk_types::{ EmptyOutputIndex, Height, OpReturnIndex, P2MSOutputIndex, TxIndex, UnknownOutputIndex, Version, }; use rayon::prelude::*; -use vecdb::{AnyStoredVec, Database, ImportableVec, PcoVec, Rw, Stamp, StorageMode, WritableVec}; +use schemars::JsonSchema; +use serde::Serialize; +use vecdb::{ + AnyStoredVec, Database, Formattable, ImportableVec, PcoVec, PcoVecValue, Rw, Stamp, + StorageMode, VecIndex, WritableVec, +}; use crate::parallel_import; +#[derive(Traversable)] +pub struct ScriptTypeVecs { + pub first_index: M::Stored>, + pub to_txindex: M::Stored>, +} + #[derive(Traversable)] pub struct ScriptsVecs { - // Height to first output index (per output type) - pub first_emptyoutputindex: M::Stored>, - pub first_opreturnindex: M::Stored>, - pub first_p2msoutputindex: M::Stored>, - pub first_unknownoutputindex: M::Stored>, - // Output index to txindex (per output type) - pub empty_to_txindex: M::Stored>, - pub opreturn_to_txindex: M::Stored>, - pub p2ms_to_txindex: M::Stored>, - pub unknown_to_txindex: M::Stored>, + pub empty: ScriptTypeVecs, + pub opreturn: ScriptTypeVecs, + pub p2ms: ScriptTypeVecs, + pub unknown: ScriptTypeVecs, } impl ScriptsVecs { @@ -44,14 +49,10 @@ impl ScriptsVecs { unknownoutputindex_to_txindex = PcoVec::forced_import(db, "txindex", version), }; Ok(Self { - first_emptyoutputindex, - first_opreturnindex, - first_p2msoutputindex, - first_unknownoutputindex, - empty_to_txindex: emptyoutputindex_to_txindex, - opreturn_to_txindex: opreturnindex_to_txindex, - p2ms_to_txindex: p2msoutputindex_to_txindex, - unknown_to_txindex: unknownoutputindex_to_txindex, + empty: ScriptTypeVecs { first_index: first_emptyoutputindex, to_txindex: emptyoutputindex_to_txindex }, + opreturn: ScriptTypeVecs { first_index: first_opreturnindex, to_txindex: opreturnindex_to_txindex }, + p2ms: ScriptTypeVecs { first_index: first_p2msoutputindex, to_txindex: p2msoutputindex_to_txindex }, + unknown: ScriptTypeVecs { first_index: first_unknownoutputindex, to_txindex: unknownoutputindex_to_txindex }, }) } @@ -64,35 +65,35 @@ impl ScriptsVecs { unknownoutputindex: UnknownOutputIndex, stamp: Stamp, ) -> Result<()> { - self.first_emptyoutputindex + self.empty.first_index .truncate_if_needed_with_stamp(height, stamp)?; - self.first_opreturnindex + self.opreturn.first_index .truncate_if_needed_with_stamp(height, stamp)?; - self.first_p2msoutputindex + self.p2ms.first_index .truncate_if_needed_with_stamp(height, stamp)?; - self.first_unknownoutputindex + self.unknown.first_index .truncate_if_needed_with_stamp(height, stamp)?; - self.empty_to_txindex + self.empty.to_txindex .truncate_if_needed_with_stamp(emptyoutputindex, stamp)?; - self.opreturn_to_txindex + self.opreturn.to_txindex .truncate_if_needed_with_stamp(opreturnindex, stamp)?; - self.p2ms_to_txindex + self.p2ms.to_txindex .truncate_if_needed_with_stamp(p2msoutputindex, stamp)?; - self.unknown_to_txindex + self.unknown.to_txindex .truncate_if_needed_with_stamp(unknownoutputindex, stamp)?; Ok(()) } pub fn par_iter_mut_any(&mut self) -> impl ParallelIterator { [ - &mut self.first_emptyoutputindex as &mut dyn AnyStoredVec, - &mut self.first_opreturnindex, - &mut self.first_p2msoutputindex, - &mut self.first_unknownoutputindex, - &mut self.empty_to_txindex, - &mut self.opreturn_to_txindex, - &mut self.p2ms_to_txindex, - &mut self.unknown_to_txindex, + &mut self.empty.first_index as &mut dyn AnyStoredVec, + &mut self.opreturn.first_index, + &mut self.p2ms.first_index, + &mut self.unknown.first_index, + &mut self.empty.to_txindex, + &mut self.opreturn.to_txindex, + &mut self.p2ms.to_txindex, + &mut self.unknown.to_txindex, ] .into_par_iter() } diff --git a/crates/brk_query/Cargo.toml b/crates/brk_query/Cargo.toml index 191abc12c..fe451731e 100644 --- a/crates/brk_query/Cargo.toml +++ b/crates/brk_query/Cargo.toml @@ -23,7 +23,9 @@ brk_traversable = { workspace = true } brk_types = { workspace = true } derive_more = { workspace = true } jiff = { workspace = true } +parking_lot = { workspace = true } quickmatch = { path = "../../../quickmatch" } # quickmatch = "0.3.1" tokio = { workspace = true, optional = true } +serde_json = { workspace = true } vecdb = { workspace = true } diff --git a/crates/brk_query/src/impl/metrics.rs b/crates/brk_query/src/impl/metrics.rs index c06285caf..2a43cfc68 100644 --- a/crates/brk_query/src/impl/metrics.rs +++ b/crates/brk_query/src/impl/metrics.rs @@ -1,27 +1,33 @@ -use std::collections::BTreeMap; +use std::{collections::BTreeMap, sync::LazyLock}; use brk_error::{Error, Result}; use brk_traversable::TreeNode; use brk_types::{ - DetailedMetricCount, Etag, Format, Index, IndexInfo, LegacyValue, Limit, Metric, MetricData, - MetricOutput, MetricOutputLegacy, MetricSelection, Output, OutputLegacy, PaginatedMetrics, - Pagination, PaginationIndex, Version, + Date, DetailedMetricCount, Epoch, Etag, Format, Halving, Height, Index, IndexInfo, LegacyValue, + Limit, Metric, MetricData, MetricInfo, MetricOutput, MetricOutputLegacy, MetricSelection, + Output, OutputLegacy, PaginatedMetrics, Pagination, PaginationIndex, RangeIndex, RangeMap, + SearchQuery, Timestamp, Version, }; -use vecdb::AnyExportableVec; +use parking_lot::RwLock; +use vecdb::{AnyExportableVec, ReadableVec}; use crate::{ Query, vecs::{IndexToVec, MetricToVec}, }; +/// Monotonic block timestamps → height. Lazily extended as new blocks are indexed. +static HEIGHT_BY_MONOTONIC_TIMESTAMP: LazyLock>> = + LazyLock::new(|| RwLock::new(RangeMap::default())); + /// Estimated bytes per column header const CSV_HEADER_BYTES_PER_COL: usize = 10; /// Estimated bytes per cell value const CSV_CELL_BYTES: usize = 15; impl Query { - pub fn match_metric(&self, metric: &Metric, limit: Limit) -> Vec<&'static str> { - self.vecs().matches(metric, limit) + pub fn search_metrics(&self, query: &SearchQuery) -> Vec<&'static str> { + self.vecs().matches(&query.q, query.limit) } pub fn metric_not_found_error(&self, metric: &Metric) -> Error { @@ -40,7 +46,7 @@ impl Query { // Metric doesn't exist, suggest alternatives let matches = self - .match_metric(metric, Limit::DEFAULT) + .vecs().matches(metric, Limit::DEFAULT) .into_iter() .map(|s| s.to_string()) .collect(); @@ -101,6 +107,15 @@ impl Query { Ok(csv) } + /// Returns the latest value for a single metric as a JSON value. + pub fn latest(&self, metric: &Metric, index: Index) -> Result { + let vec = self + .vecs() + .get(metric, index) + .ok_or_else(|| self.metric_not_found_error(metric))?; + vec.last_json_value().ok_or(Error::NoData) + } + /// Search for vecs matching the given metrics and index. /// Returns error if no metrics requested or any requested metric is not found. pub fn search(&self, params: &MetricSelection) -> Result> { @@ -129,21 +144,29 @@ impl Query { let total = vecs.iter().map(|v| v.len()).min().unwrap_or(0); let version: Version = vecs.iter().map(|v| v.version()).sum(); + let index = params.index; - let start = params - .start() - .map(|s| vecs.iter().map(|v| v.i64_to_usize(s)).min().unwrap_or(0)) - .unwrap_or(0); + let start = match params.start() { + Some(ri) => { + let i = self.range_index_to_i64(ri, index)?; + vecs.iter().map(|v| v.i64_to_usize(i)).min().unwrap_or(0) + } + None => 0, + }; - let end = params - .end_for_len(total) - .map(|e| { + let end = match params.end() { + Some(ri) => { + let i = self.range_index_to_i64(ri, index)?; vecs.iter() - .map(|v| v.i64_to_usize(e)) + .map(|v| v.i64_to_usize(i)) .min() .unwrap_or(total) - }) - .unwrap_or(total); + } + None => params + .limit() + .map(|l| (start + *l).min(total)) + .unwrap_or(total), + }; let weight = Self::weight(&vecs, Some(start as i64), Some(end as i64)); if weight > max_weight { @@ -211,6 +234,25 @@ impl Query { }) } + /// Format a resolved query as raw data (just the JSON array, no MetricData wrapper). + pub fn format_raw(&self, resolved: ResolvedQuery) -> Result { + let ResolvedQuery { + vecs, version, total, start, end, .. + } = resolved; + + let count = end.saturating_sub(start); + let mut buf = Vec::with_capacity(count * 12 + 2); + vecs[0].write_json(Some(start), Some(end), &mut buf)?; + + Ok(MetricOutput { + output: Output::Json(buf), + version, + total, + start, + end, + }) + } + pub fn metric_to_index_to_vec(&self) -> &BTreeMap<&str, IndexToVec<'_>> { &self.vecs().metric_to_index_to_vec } @@ -242,10 +284,76 @@ impl Query { self.vecs().index_to_ids(paginated_index) } + pub fn metric_info(&self, metric: &Metric) -> Option { + let index_to_vec = self.vecs().metric_to_index_to_vec.get(metric.replace("-", "_").as_str())?; + let value_type = index_to_vec.values().next()?.value_type_to_string(); + let indexes = index_to_vec.keys().copied().collect(); + Some(MetricInfo { + indexes, + value_type, + }) + } + pub fn metric_to_indexes(&self, metric: Metric) -> Option<&Vec> { self.vecs().metric_to_indexes(metric) } + /// Resolve a RangeIndex to an i64 offset for the given index type. + fn range_index_to_i64(&self, ri: RangeIndex, index: Index) -> Result { + match ri { + RangeIndex::Int(i) => Ok(i), + RangeIndex::Date(date) => self.date_to_i64(date, index), + RangeIndex::Timestamp(ts) => self.timestamp_to_i64(ts, index), + } + } + + fn date_to_i64(&self, date: Date, index: Index) -> Result { + // Direct date-based index conversion (day1, week1, month1, etc.) + if let Some(idx) = index.date_to_index(date) { + return Ok(idx as i64); + } + // Fall through to timestamp-based resolution (height, epoch, halving) + self.timestamp_to_i64(Timestamp::from(date), index) + } + + fn timestamp_to_i64(&self, ts: Timestamp, index: Index) -> Result { + // Direct timestamp-based index conversion (minute10, hour1, etc.) + if let Some(idx) = index.timestamp_to_index(ts) { + return Ok(idx as i64); + } + // Height-based indexes: find block height, then convert + let height = Height::from(self.height_for_timestamp(ts)); + match index { + Index::Height => Ok(usize::from(height) as i64), + Index::Epoch => Ok(usize::from(Epoch::from(height)) as i64), + Index::Halving => Ok(usize::from(Halving::from(height)) as i64), + _ => Err(Error::Parse(format!( + "date/timestamp ranges not supported for index '{index}'" + ))), + } + } + + /// Find the first block height at or after a given timestamp. + /// O(log n) binary search. Lazily rebuilt as new blocks arrive. + fn height_for_timestamp(&self, ts: Timestamp) -> usize { + let current_height: usize = self.height().into(); + + // Fast path: read lock, ceil is &self + { + let map = HEIGHT_BY_MONOTONIC_TIMESTAMP.read(); + if map.len() > current_height { + return map.ceil(ts).map(usize::from).unwrap_or(current_height); + } + } + + // Slow path: rebuild from computer's precomputed monotonic timestamps + let mut map = HEIGHT_BY_MONOTONIC_TIMESTAMP.write(); + if map.len() <= current_height { + *map = RangeMap::from(self.computer().blocks.time.timestamp_monotonic.collect()); + } + map.ceil(ts).map(usize::from).unwrap_or(current_height) + } + /// Deprecated - format a resolved query as legacy output (expensive). pub fn format_legacy(&self, resolved: ResolvedQuery) -> Result { let ResolvedQuery { diff --git a/crates/brk_query/src/impl/mod.rs b/crates/brk_query/src/impl/mod.rs index 2323b2dbb..085e6108c 100644 --- a/crates/brk_query/src/impl/mod.rs +++ b/crates/brk_query/src/impl/mod.rs @@ -8,3 +8,4 @@ mod price; mod transaction; pub use block::BLOCK_TXS_PAGE_SIZE; +pub use metrics::ResolvedQuery; diff --git a/crates/brk_query/src/lib.rs b/crates/brk_query/src/lib.rs index d9f04ed80..718470caa 100644 --- a/crates/brk_query/src/lib.rs +++ b/crates/brk_query/src/lib.rs @@ -19,7 +19,7 @@ mod r#impl; #[cfg(feature = "tokio")] pub use r#async::*; -pub use r#impl::BLOCK_TXS_PAGE_SIZE; +pub use r#impl::{BLOCK_TXS_PAGE_SIZE, ResolvedQuery}; pub use vecs::Vecs; #[derive(Clone)] diff --git a/crates/brk_query/src/vecs.rs b/crates/brk_query/src/vecs.rs index cc2bf461d..f8108ac37 100644 --- a/crates/brk_query/src/vecs.rs +++ b/crates/brk_query/src/vecs.rs @@ -142,7 +142,7 @@ impl<'a> Vecs<'a> { self.counts_by_db .entry(db.to_string()) .or_default() - .add_endpoint(is_lazy); + .add_endpoint(name, is_lazy); } pub fn metrics(&'static self, pagination: Pagination) -> PaginatedMetrics { diff --git a/crates/brk_server/src/api/metrics/data.rs b/crates/brk_server/src/api/metrics/data.rs index c9b8d2b65..e233f071e 100644 --- a/crates/brk_server/src/api/metrics/data.rs +++ b/crates/brk_server/src/api/metrics/data.rs @@ -7,7 +7,9 @@ use axum::{ http::{HeaderMap, StatusCode, Uri}, response::{IntoResponse, Response}, }; -use brk_types::{Format, MetricSelection, Output}; +use brk_error::Result as BrkResult; +use brk_query::{Query as BrkQuery, ResolvedQuery}; +use brk_types::{Format, MetricOutput, MetricSelection, Output}; use crate::{ Result, @@ -20,9 +22,30 @@ use super::AppState; pub async fn handler( uri: Uri, headers: HeaderMap, - Extension(addr): Extension, + addr: Extension, Query(params): Query, - State(state): State, + state: State, +) -> Result { + format_and_respond(uri, headers, addr, params, state, |q, r| q.format(r)).await +} + +pub async fn raw_handler( + uri: Uri, + headers: HeaderMap, + addr: Extension, + Query(params): Query, + state: State, +) -> Result { + format_and_respond(uri, headers, addr, params, state, |q, r| q.format_raw(r)).await +} + +async fn format_and_respond( + uri: Uri, + headers: HeaderMap, + Extension(addr): Extension, + params: MetricSelection, + state: State, + formatter: fn(&BrkQuery, ResolvedQuery) -> BrkResult, ) -> Result { // Phase 1: Search and resolve metadata (cheap) let resolved = state @@ -51,7 +74,7 @@ pub async fn handler( .get_or_insert(&cache_key, async move { query .run(move |q| { - let out = q.format(resolved)?; + let out = formatter(q, resolved)?; let raw = match out.output { Output::CSV(s) => Bytes::from(s), Output::Json(v) => Bytes::from(v), diff --git a/crates/brk_server/src/api/metrics/mod.rs b/crates/brk_server/src/api/metrics/mod.rs index 5426f7262..07b49c2fe 100644 --- a/crates/brk_server/src/api/metrics/mod.rs +++ b/crates/brk_server/src/api/metrics/mod.rs @@ -10,8 +10,9 @@ use axum::{ use brk_traversable::TreeNode; use brk_types::{ CostBasisCohortParam, CostBasisFormatted, CostBasisParams, CostBasisQuery, DataRangeFormat, - Date, Index, IndexInfo, LimitParam, Metric, MetricCount, MetricData, MetricParam, + Date, Index, IndexInfo, Metric, MetricCount, MetricData, MetricInfo, MetricParam, MetricSelection, MetricSelectionLegacy, MetricWithIndex, Metrics, PaginatedMetrics, Pagination, + SearchQuery, }; use crate::{CacheStrategy, Error, extended::TransformResponseExtended}; @@ -124,16 +125,15 @@ impl ApiMetricsRoutes for ApiRouter { ), ) .api_route( - "/api/metrics/search/{metric}", + "/api/metrics/search", get_with( async | uri: Uri, headers: HeaderMap, State(state): State, - Path(path): Path, - Query(query): Query + Query(query): Query | { - state.cached_json(&headers, CacheStrategy::Static, &uri, move |q| Ok(q.match_metric(&path.metric, query.limit))).await + state.cached_json(&headers, CacheStrategy::Static, &uri, move |q| Ok(q.search_metrics(&query))).await }, |op| op .id("search_metrics") @@ -155,26 +155,80 @@ impl ApiMetricsRoutes for ApiRouter { Path(path): Path | { state.cached_json(&headers, CacheStrategy::Static, &uri, move |q| { - if let Some(indexes) = q.metric_to_indexes(path.metric.clone()) { - return Ok(indexes.clone()) - } - Err(q.metric_not_found_error(&path.metric)) + q.metric_info(&path.metric).ok_or_else(|| q.metric_not_found_error(&path.metric)) }).await }, |op| op .id("get_metric_info") .metrics_tag() - .summary("Get supported indexes for a metric") + .summary("Get metric info") .description( - "Returns the list of indexes supported by the specified metric. \ - For example, `realized_price` might be available on day1, week1, and month1." + "Returns the supported indexes and value type for the specified metric." ) - .ok_response::>() + .ok_response::() .not_modified() .not_found() .server_error(), ), ) + .api_route( + "/api/metric/{metric}/{index}/latest", + get_with( + async |uri: Uri, + headers: HeaderMap, + State(state): State, + Path(path): Path| { + state + .cached_json(&headers, CacheStrategy::Height, &uri, move |q| { + q.latest(&path.metric, path.index) + }) + .await + }, + |op| op + .id("get_metric_latest") + .metrics_tag() + .summary("Get latest metric value") + .description( + "Returns the single most recent value for a metric, unwrapped (not inside a MetricData object)." + ) + .ok_response::() + .not_found(), + ), + ) + .api_route( + "/api/metric/{metric}/{index}/data", + get_with( + async |uri: Uri, + headers: HeaderMap, + addr: Extension, + state: State, + Path(path): Path, + Query(range): Query| + -> Response { + data::raw_handler( + uri, + headers, + addr, + Query(MetricSelection::from((path.index, path.metric, range))), + state, + ) + .await + .into_response() + }, + |op| op + .id("get_metric_data") + .metrics_tag() + .summary("Get raw metric data") + .description( + "Returns just the data array without the MetricData wrapper. \ + Supports the same range and format parameters as the standard endpoint." + ) + .ok_response::>() + .csv_response() + .not_modified() + .not_found(), + ), + ) .api_route( "/api/metric/{metric}/{index}", get_with( diff --git a/crates/brk_server/src/api/openapi/mod.rs b/crates/brk_server/src/api/openapi/mod.rs index bf3325110..fca92f043 100644 --- a/crates/brk_server/src/api/openapi/mod.rs +++ b/crates/brk_server/src/api/openapi/mod.rs @@ -35,8 +35,9 @@ pub fn create_openapi() -> OpenApi { ```bash curl -s https://bitview.space/api/block-height/0 -curl -s https://bitview.space/api/metrics/search/price -curl -s https://bitview.space/api/metric/price/day1 +curl -s https://bitview.space/api/metrics/search?q=price +curl -s https://bitview.space/api/metric/price/day +curl -s https://bitview.space/api/metric/price/day/latest ``` ### Errors diff --git a/crates/brk_server/src/error.rs b/crates/brk_server/src/error.rs index 91aa30993..00d64c477 100644 --- a/crates/brk_server/src/error.rs +++ b/crates/brk_server/src/error.rs @@ -57,6 +57,7 @@ fn error_status(e: &BrkError) -> StatusCode { BrkError::UnknownAddress | BrkError::UnknownTxid | BrkError::NotFound(_) + | BrkError::NoData | BrkError::MetricNotFound(_) => StatusCode::NOT_FOUND, BrkError::AuthFailed => StatusCode::FORBIDDEN, @@ -79,6 +80,7 @@ fn error_code(e: &BrkError) -> &'static str { BrkError::UnknownAddress => "unknown_address", BrkError::UnknownTxid => "unknown_txid", BrkError::NotFound(_) => "not_found", + BrkError::NoData => "no_data", BrkError::MetricNotFound(_) => "metric_not_found", BrkError::MempoolNotAvailable => "mempool_not_available", BrkError::AuthFailed => "auth_failed", diff --git a/crates/brk_types/src/day1.rs b/crates/brk_types/src/day1.rs index 6a754f55a..66ce4e5a3 100644 --- a/crates/brk_types/src/day1.rs +++ b/crates/brk_types/src/day1.rs @@ -202,7 +202,7 @@ impl PrintableIndex for Day1 { } fn to_possible_strings() -> &'static [&'static str] { - &["1d", "d", "date", "daily", "day1", "dateindex"] + &["1d", "d", "day", "date", "daily", "day1", "dateindex"] } } diff --git a/crates/brk_types/src/dollars.rs b/crates/brk_types/src/dollars.rs index 0f700f9e1..2a79a28a6 100644 --- a/crates/brk_types/src/dollars.rs +++ b/crates/brk_types/src/dollars.rs @@ -120,14 +120,14 @@ impl From for Dollars { impl Add for Dollars { type Output = Self; fn add(self, rhs: Self) -> Self::Output { - Self::from(CentsSigned::from(self) + CentsSigned::from(rhs)) + Self(self.0 + rhs.0) } } impl Sub for Dollars { type Output = Self; fn sub(self, rhs: Self) -> Self::Output { - Self::from(CentsSigned::from(self) - CentsSigned::from(rhs)) + Self(self.0 - rhs.0) } } @@ -346,13 +346,13 @@ impl From for u128 { impl AddAssign for Dollars { fn add_assign(&mut self, rhs: Self) { - *self = Dollars::from(CentsSigned::from(*self) + CentsSigned::from(rhs)); + self.0 += rhs.0; } } impl SubAssign for Dollars { fn sub_assign(&mut self, rhs: Self) { - *self = Dollars::from(CentsSigned::from(*self) - CentsSigned::from(rhs)); + self.0 -= rhs.0; } } diff --git a/crates/brk_types/src/hour1.rs b/crates/brk_types/src/hour1.rs index 1088365d3..fff8287d4 100644 --- a/crates/brk_types/src/hour1.rs +++ b/crates/brk_types/src/hour1.rs @@ -67,7 +67,7 @@ impl PrintableIndex for Hour1 { } fn to_possible_strings() -> &'static [&'static str] { - &["1h", "hour1"] + &["1h", "h", "hour", "hourly", "hour1"] } } diff --git a/crates/brk_types/src/index.rs b/crates/brk_types/src/index.rs index e6fb9ff85..1c8545cf6 100644 --- a/crates/brk_types/src/index.rs +++ b/crates/brk_types/src/index.rs @@ -253,7 +253,7 @@ impl Index { Self::Day3 => return Some(usize::from(Day3::from_timestamp(ts))), _ => return self.date_to_index(Date::from(ts)), }; - Some(((*ts - INDEX_EPOCH) / interval) as usize) + Some((*ts).saturating_sub(INDEX_EPOCH) as usize / interval as usize) } /// Convert an index value to a date for day-precision or coarser indexes. @@ -299,12 +299,7 @@ impl<'de> Deserialize<'de> for Index { D: serde::Deserializer<'de>, { let str = String::deserialize(deserializer)?; - if let Ok(index) = Index::try_from(str.as_str()) { - // dbg!(index); - Ok(index) - } else { - Err(serde::de::Error::custom("Bad index")) - } + Index::try_from(str.as_str()).map_err(|e| serde::de::Error::custom(e)) } } diff --git a/crates/brk_types/src/lib.rs b/crates/brk_types/src/lib.rs index ac22f5de1..d47d3c75a 100644 --- a/crates/brk_types/src/lib.rs +++ b/crates/brk_types/src/lib.rs @@ -92,6 +92,7 @@ mod mempoolinfo; mod metric; mod metriccount; mod metricdata; +mod metricinfo; mod metricoutput; mod metricparam; mod metrics; @@ -141,12 +142,14 @@ mod poolslugparam; mod poolssummary; mod poolstats; mod port; +mod range_map; mod rangeindex; mod rawlocktime; mod recommendedfees; mod rewardstats; mod sats; mod sats_signed; +mod searchquery; mod satsfract; mod stored_bool; mod stored_f32; @@ -285,6 +288,7 @@ pub use mempoolinfo::*; pub use metric::*; pub use metriccount::*; pub use metricdata::*; +pub use metricinfo::*; pub use metricoutput::*; pub use metricparam::*; pub use metrics::*; @@ -334,6 +338,7 @@ pub use poolslugparam::*; pub use poolssummary::*; pub use poolstats::*; pub use port::*; +pub use range_map::*; pub use rangeindex::*; pub use rawlocktime::*; pub use recommendedfees::*; @@ -341,6 +346,7 @@ pub use rewardstats::*; pub use sats::*; pub use sats_signed::*; pub use satsfract::*; +pub use searchquery::*; pub use stored_bool::*; pub use stored_f32::*; pub use stored_f64::*; diff --git a/crates/brk_types/src/metriccount.rs b/crates/brk_types/src/metriccount.rs index a12b2fdb3..949d0993f 100644 --- a/crates/brk_types/src/metriccount.rs +++ b/crates/brk_types/src/metriccount.rs @@ -1,5 +1,6 @@ use std::collections::BTreeMap; +use rustc_hash::FxHashSet; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -18,16 +19,21 @@ pub struct MetricCount { /// Number of eager (stored on disk) metric-index combinations #[schemars(example = 16000)] pub stored_endpoints: usize, + #[serde(skip)] + seen: FxHashSet, } impl MetricCount { - pub fn add_endpoint(&mut self, is_lazy: bool) { + pub fn add_endpoint(&mut self, name: &str, is_lazy: bool) { self.total_endpoints += 1; if is_lazy { self.lazy_endpoints += 1; } else { self.stored_endpoints += 1; } + if self.seen.insert(name.to_string()) { + self.distinct_metrics += 1; + } } } diff --git a/crates/brk_types/src/metricdata.rs b/crates/brk_types/src/metricdata.rs index f26dfd724..296dce5c4 100644 --- a/crates/brk_types/src/metricdata.rs +++ b/crates/brk_types/src/metricdata.rs @@ -17,6 +17,9 @@ pub struct MetricData { pub version: Version, /// The index type used for this query pub index: Index, + /// Value type (e.g. "f32", "u64", "Sats") + #[serde(rename = "type", default)] + pub value_type: String, /// Total number of data points in the metric pub total: usize, /// Start index (inclusive) of the returned range @@ -48,6 +51,8 @@ impl MetricData { buf.extend_from_slice(itoa_buf.format(u32::from(vec.version())).as_bytes()); buf.extend_from_slice(b",\"index\":\""); buf.extend_from_slice(index.name().as_bytes()); + buf.extend_from_slice(b"\",\"type\":\""); + buf.extend_from_slice(vec.value_type_to_string().as_bytes()); buf.extend_from_slice(b"\",\"total\":"); buf.extend_from_slice(itoa_buf.format(total).as_bytes()); buf.extend_from_slice(b",\"start\":"); @@ -186,373 +191,3 @@ impl<'de, T: DeserializeOwned> Deserialize<'de> for DateMetricData { }) } } - -#[cfg(test)] -mod tests { - use super::*; - - fn date_based_metric() -> MetricData { - MetricData { - version: Version::ONE, - index: Index::Day1, - total: 100, - start: 0, - end: 5, - stamp: "2024-01-01T00:00:00Z".to_string(), - data: vec![100, 200, 300, 400, 500], - } - } - - fn height_based_metric() -> MetricData { - MetricData { - version: Version::ONE, - index: Index::Height, - total: 1000, - start: 800000, - end: 800005, - stamp: "2024-01-01T00:00:00Z".to_string(), - data: vec![1.5, 2.5, 3.5, 4.5, 5.5], - } - } - - #[test] - fn test_indexes_returns_range() { - let metric = date_based_metric(); - let indexes: Vec<_> = metric.indexes().collect(); - assert_eq!(indexes, vec![0, 1, 2, 3, 4]); - } - - #[test] - fn test_indexes_with_offset() { - let metric = height_based_metric(); - let indexes: Vec<_> = metric.indexes().collect(); - assert_eq!(indexes, vec![800000, 800001, 800002, 800003, 800004]); - } - - #[test] - fn test_is_date_based_true() { - let metric = date_based_metric(); - assert!(metric.is_date_based()); - } - - #[test] - fn test_is_date_based_false() { - let metric = height_based_metric(); - assert!(!metric.is_date_based()); - } - - #[test] - fn test_dates_for_day1() { - let metric = date_based_metric(); - let dates: Vec<_> = metric.dates().unwrap().collect(); - assert_eq!(dates.len(), 5); - // Day1 0 = Jan 1, 2009 - assert_eq!(dates[0].year(), 2009); - assert_eq!(dates[0].month(), 1); - assert_eq!(dates[0].day(), 1); - // Day1 1 = Jan 2, 2009 - assert_eq!(dates[1].year(), 2009); - assert_eq!(dates[1].month(), 1); - assert_eq!(dates[1].day(), 2); - } - - #[test] - fn test_iter() { - let metric = date_based_metric(); - let pairs: Vec<_> = metric.iter().collect(); - assert_eq!(pairs.len(), 5); - assert_eq!(pairs[0], (0, &100)); - assert_eq!(pairs[1], (1, &200)); - assert_eq!(pairs[4], (4, &500)); - } - - #[test] - fn test_iter_with_offset() { - let metric = height_based_metric(); - let pairs: Vec<_> = metric.iter().collect(); - assert_eq!(pairs.len(), 5); - assert_eq!(pairs[0], (800000, &1.5)); - assert_eq!(pairs[4], (800004, &5.5)); - } - - #[test] - fn test_iter_dates() { - let metric = date_based_metric(); - let pairs: Vec<_> = metric.iter_dates().unwrap().collect(); - assert_eq!(pairs.len(), 5); - // First pair: (Jan 1 2009, 100) - assert_eq!(pairs[0].0.year(), 2009); - assert_eq!(pairs[0].0.month(), 1); - assert_eq!(pairs[0].0.day(), 1); - assert_eq!(pairs[0].1, &100); - // Second pair: (Jan 2 2009, 200) - assert_eq!(pairs[1].0.day(), 2); - assert_eq!(pairs[1].1, &200); - } - - #[test] - fn test_dates_returns_none_for_non_date_index() { - let metric = height_based_metric(); - assert!(metric.dates().is_none()); - } - - #[test] - fn test_iter_dates_returns_none_for_non_date_index() { - let metric = height_based_metric(); - assert!(metric.iter_dates().is_none()); - } - - #[test] - fn test_date_metric_data_try_new_ok() { - let metric = date_based_metric(); - let date_metric = DateMetricData::try_new(metric).unwrap(); - assert_eq!(date_metric.data.len(), 5); - let dates: Vec<_> = date_metric.dates().unwrap().collect(); - assert_eq!(dates.len(), 5); - assert_eq!(dates[0].year(), 2009); - } - - #[test] - fn test_date_metric_data_try_new_err() { - let metric = height_based_metric(); - assert!(DateMetricData::try_new(metric).is_err()); - } - - #[test] - fn test_date_metric_data_iter_dates() { - let metric = date_based_metric(); - let date_metric = DateMetricData::try_new(metric).unwrap(); - let pairs: Vec<_> = date_metric.iter_dates().unwrap().collect(); - assert_eq!(pairs.len(), 5); - assert_eq!(pairs[0].0.day(), 1); - assert_eq!(pairs[0].1, &100); - } - - #[test] - fn test_date_metric_data_deref() { - let metric = date_based_metric(); - let date_metric = DateMetricData::try_new(metric).unwrap(); - // Access MetricData methods via Deref - assert!(date_metric.is_date_based()); - assert_eq!(date_metric.indexes().count(), 5); - } - - // Sub-daily tests - - fn sub_daily_metric() -> MetricData { - MetricData { - version: Version::ONE, - index: Index::Hour1, - total: 200000, - start: 0, - end: 3, - stamp: "2024-01-01T00:00:00Z".to_string(), - data: vec![10.0, 20.0, 30.0], - } - } - - #[test] - fn test_sub_daily_is_date_based() { - let metric = sub_daily_metric(); - assert!(metric.is_date_based()); - } - - #[test] - fn test_sub_daily_dates_returns_none() { - let metric = sub_daily_metric(); - assert!(metric.dates().is_none()); - } - - #[test] - fn test_sub_daily_timestamps_returns_some() { - let metric = sub_daily_metric(); - let ts: Vec<_> = metric.timestamps().unwrap().collect(); - assert_eq!(ts.len(), 3); - // Hour1 index 0 = INDEX_EPOCH (2009-01-01 00:00:00 UTC) - assert_eq!(*ts[0], 1230768000); - // Hour1 index 1 = INDEX_EPOCH + 3600 - assert_eq!(*ts[1], 1230768000 + 3600); - } - - #[test] - fn test_sub_daily_iter_timestamps() { - let metric = sub_daily_metric(); - let pairs: Vec<_> = metric.iter_timestamps().unwrap().collect(); - assert_eq!(pairs.len(), 3); - assert_eq!(*pairs[0].0, 1230768000); - assert_eq!(pairs[0].1, &10.0); - } - - #[test] - fn test_date_metric_data_sub_daily_timestamps() { - let metric = sub_daily_metric(); - let date_metric = DateMetricData::try_new(metric).unwrap(); - // dates() returns None for sub-daily - assert!(date_metric.dates().is_none()); - // timestamps() works for all date-based - let ts: Vec<_> = date_metric.timestamps().collect(); - assert_eq!(ts.len(), 3); - } - - #[test] - fn test_date_metric_data_iter_timestamps() { - let metric = sub_daily_metric(); - let date_metric = DateMetricData::try_new(metric).unwrap(); - let pairs: Vec<_> = date_metric.iter_timestamps().collect(); - assert_eq!(pairs.len(), 3); - assert_eq!(pairs[2].1, &30.0); - } - - #[test] - fn test_day1_timestamps_also_works() { - // timestamps() works for daily indexes too - let metric = date_based_metric(); - let ts: Vec<_> = metric.timestamps().unwrap().collect(); - assert_eq!(ts.len(), 5); - } - - // Empty data - - fn empty_metric() -> MetricData { - MetricData { - version: Version::ONE, - index: Index::Day1, - total: 100, - start: 5, - end: 5, - stamp: "2024-01-01T00:00:00Z".to_string(), - data: vec![], - } - } - - #[test] - fn test_empty_indexes() { - let metric = empty_metric(); - assert_eq!(metric.indexes().count(), 0); - } - - #[test] - fn test_empty_iter() { - let metric = empty_metric(); - assert_eq!(metric.iter().count(), 0); - } - - #[test] - fn test_empty_dates() { - let metric = empty_metric(); - assert_eq!(metric.dates().unwrap().count(), 0); - } - - #[test] - fn test_empty_timestamps() { - let metric = empty_metric(); - assert_eq!(metric.timestamps().unwrap().count(), 0); - } - - // Non-date timestamps/iter_timestamps - - #[test] - fn test_timestamps_returns_none_for_non_date() { - let metric = height_based_metric(); - assert!(metric.timestamps().is_none()); - } - - #[test] - fn test_iter_timestamps_returns_none_for_non_date() { - let metric = height_based_metric(); - assert!(metric.iter_timestamps().is_none()); - } - - // DateMetricData sub-daily iter_dates returns None - - #[test] - fn test_date_metric_data_sub_daily_iter_dates_returns_none() { - let metric = sub_daily_metric(); - let date_metric = DateMetricData::try_new(metric).unwrap(); - assert!(date_metric.iter_dates().is_none()); - } - - // Month1 dates - - fn month1_metric() -> MetricData { - MetricData { - version: Version::ONE, - index: Index::Month1, - total: 200, - start: 0, - end: 3, - stamp: "2024-01-01T00:00:00Z".to_string(), - data: vec![1000, 2000, 3000], - } - } - - #[test] - fn test_dates_for_month1() { - let metric = month1_metric(); - let dates: Vec<_> = metric.dates().unwrap().collect(); - assert_eq!(dates.len(), 3); - assert_eq!(dates[0].year(), 2009); - assert_eq!(dates[0].month(), 1); - assert_eq!(dates[0].day(), 1); - assert_eq!(dates[1].month(), 2); - assert_eq!(dates[2].month(), 3); - } - - #[test] - fn test_timestamps_for_month1() { - let metric = month1_metric(); - let ts: Vec<_> = metric.timestamps().unwrap().collect(); - assert_eq!(ts.len(), 3); - // Each should be a valid timestamp - assert!(*ts[0] > 0); - assert!(*ts[1] > *ts[0]); - assert!(*ts[2] > *ts[1]); - } - - // Deserialize roundtrip - - #[test] - fn test_date_metric_data_deserialize_valid() { - let json = r#"{"version":1,"index":"day1","total":100,"start":0,"end":2,"stamp":"2024-01-01T00:00:00Z","data":[1,2]}"#; - let result: Result, _> = serde_json::from_str(json); - assert!(result.is_ok()); - let dm = result.unwrap(); - assert_eq!(dm.data.len(), 2); - } - - #[test] - fn test_date_metric_data_deserialize_rejects_non_date() { - let json = r#"{"version":1,"index":"height","total":100,"start":0,"end":2,"stamp":"2024-01-01T00:00:00Z","data":[1,2]}"#; - let result: Result, _> = serde_json::from_str(json); - assert!(result.is_err()); - let err = result.unwrap_err().to_string(); - assert!( - err.contains("date-based"), - "error should mention date-based: {}", - err - ); - } - - // timestamp_to_index tests - - #[test] - fn test_timestamp_to_index_hour1() { - // INDEX_EPOCH + 2 hours - let ts = Timestamp::new(1230768000 + 7200); - assert_eq!(Index::Hour1.timestamp_to_index(ts), Some(2)); - } - - #[test] - fn test_timestamp_to_index_non_date_returns_none() { - let ts = Timestamp::new(1230768000); - assert!(Index::Height.timestamp_to_index(ts).is_none()); - } - - #[test] - fn test_timestamp_to_index_day1_via_date_fallback() { - // Day1 goes through date_to_index fallback - // 2009-01-09 = Day1 index 8 - let ts = Timestamp::from(Date::new(2009, 1, 9)); - assert_eq!(Index::Day1.timestamp_to_index(ts), Some(8)); - } -} diff --git a/crates/brk_types/src/metricinfo.rs b/crates/brk_types/src/metricinfo.rs new file mode 100644 index 000000000..4f4aa8a3c --- /dev/null +++ b/crates/brk_types/src/metricinfo.rs @@ -0,0 +1,14 @@ +use schemars::JsonSchema; +use serde::Serialize; + +use crate::Index; + +/// Metadata about a metric +#[derive(Debug, Serialize, JsonSchema)] +pub struct MetricInfo { + /// Available indexes + pub indexes: Vec, + /// Value type (e.g. "f32", "u64", "Sats") + #[serde(rename = "type")] + pub value_type: &'static str, +} diff --git a/crates/brk_computer/src/distribution/range_map.rs b/crates/brk_types/src/range_map.rs similarity index 50% rename from crates/brk_computer/src/distribution/range_map.rs rename to crates/brk_types/src/range_map.rs index 0eea71d5f..3d69a8267 100644 --- a/crates/brk_computer/src/distribution/range_map.rs +++ b/crates/brk_types/src/range_map.rs @@ -4,22 +4,41 @@ use std::marker::PhantomData; const CACHE_SIZE: usize = 128; const CACHE_MASK: usize = CACHE_SIZE - 1; +/// Cache entry: (range_low, range_high, value, occupied). +type CacheEntry = (I, I, V, bool); + /// Maps ranges of indices to values for efficient reverse lookups. /// -/// Instead of storing a value for every index, stores first_index values -/// in a sorted Vec and uses binary search to find the value for any index. -/// The value is derived from the position in the Vec. +/// Stores first_index values in a sorted Vec and uses binary search +/// to find the value for any index. The value is derived from the position. /// -/// Includes a direct-mapped cache for O(1) lookups when there's locality. -#[derive(Debug, Clone)] +/// Includes a direct-mapped cache for O(1) floor lookups when there's locality. pub struct RangeMap { - /// Sorted vec of first_index values. Position in vec = value. first_indexes: Vec, - /// Direct-mapped cache: (range_low, range_high, value, occupied). Inline for zero indirection. - cache: [(I, I, V, bool); CACHE_SIZE], + cache: [CacheEntry; CACHE_SIZE], _phantom: PhantomData, } +impl Clone for RangeMap { + fn clone(&self) -> Self { + Self { + first_indexes: self.first_indexes.clone(), + cache: [(I::default(), I::default(), V::default(), false); CACHE_SIZE], + _phantom: PhantomData, + } + } +} + +impl From> for RangeMap { + fn from(first_indexes: Vec) -> Self { + Self { + first_indexes, + cache: [(I::default(), I::default(), V::default(), false); CACHE_SIZE], + _phantom: PhantomData, + } + } +} + impl Default for RangeMap { fn default() -> Self { Self { @@ -32,20 +51,25 @@ impl Default for RangeMap { impl, V: From + Copy + Default> RangeMap { /// Number of ranges stored. - pub(crate) fn len(&self) -> usize { + pub fn len(&self) -> usize { self.first_indexes.len() } /// Truncate to `new_len` ranges and clear the cache. - pub(crate) fn truncate(&mut self, new_len: usize) { + pub fn truncate(&mut self, new_len: usize) { self.first_indexes.truncate(new_len); self.clear_cache(); } + /// Reserve capacity for additional entries. + pub fn reserve(&mut self, additional: usize) { + self.first_indexes.reserve(additional); + } + /// Push a new first_index. Value is implicitly the current length. /// Must be called in order (first_index must be >= all previous). #[inline] - pub(crate) fn push(&mut self, first_index: I) { + pub fn push(&mut self, first_index: I) { debug_assert!( self.first_indexes .last() @@ -55,40 +79,52 @@ impl, V: From + Copy + Default> Ran self.first_indexes.push(first_index); } - /// Look up value for an index, checking cache first. - /// Returns the value (position) of the largest first_index <= given index. + /// Returns the last pushed first_index, if any. #[inline] - pub(crate) fn get(&mut self, index: I) -> Option { + pub fn last_key(&self) -> Option { + self.first_indexes.last().copied() + } + + /// Floor: returns the value (position) of the largest first_index <= given index. + #[inline] + pub fn get(&mut self, index: I) -> Option { if self.first_indexes.is_empty() { return None; } - // Direct-mapped cache lookup: O(1), no aging let slot = Self::cache_slot(&index); let entry = &self.cache[slot]; if entry.3 && index >= entry.0 && index < entry.1 { return Some(entry.2); } - // Cache miss - binary search let pos = self.first_indexes.partition_point(|&first| first <= index); if pos > 0 { let value = V::from(pos - 1); - let low = self.first_indexes[pos - 1]; - let is_last = pos == self.first_indexes.len(); - - // Cache non-last ranges (last range has unbounded high) - if !is_last { - let high = self.first_indexes[pos]; - self.cache[slot] = (low, high, value, true); + if pos < self.first_indexes.len() { + self.cache[slot] = (self.first_indexes[pos - 1], self.first_indexes[pos], value, true); } - Some(value) } else { None } } + /// Ceil: returns the value (position) of the smallest first_index >= given index. + #[inline] + pub fn ceil(&self, index: I) -> Option { + if self.first_indexes.is_empty() { + return None; + } + + let pos = self.first_indexes.partition_point(|&first| first < index); + if pos < self.first_indexes.len() { + Some(V::from(pos)) + } else { + None + } + } + #[inline] fn cache_slot(index: &I) -> usize { let v: usize = (*index).into(); diff --git a/crates/brk_types/src/searchquery.rs b/crates/brk_types/src/searchquery.rs new file mode 100644 index 000000000..715c4c288 --- /dev/null +++ b/crates/brk_types/src/searchquery.rs @@ -0,0 +1,13 @@ +use schemars::JsonSchema; +use serde::Deserialize; + +use crate::{Limit, Metric}; + +#[derive(Debug, Deserialize, JsonSchema)] +pub struct SearchQuery { + /// Search query string + pub q: Metric, + /// Maximum number of results + #[serde(default)] + pub limit: Limit, +} diff --git a/crates/brk_types/src/timestamp.rs b/crates/brk_types/src/timestamp.rs index 9e56e884f..44c912c20 100644 --- a/crates/brk_types/src/timestamp.rs +++ b/crates/brk_types/src/timestamp.rs @@ -124,6 +124,13 @@ impl From for Timestamp { } } +impl From for usize { + #[inline] + fn from(value: Timestamp) -> Self { + value.0 as usize + } +} + impl From for Timestamp { #[inline] fn from(value: Date) -> Self { diff --git a/modules/brk-client/index.js b/modules/brk-client/index.js index c97f8f1b1..3981510d5 100644 --- a/modules/brk-client/index.js +++ b/modules/brk-client/index.js @@ -267,8 +267,8 @@ * Data range with output format for API query parameters * * @typedef {Object} DataRangeFormat - * @property {?number=} start - Inclusive starting index, if negative counts from end. Aliases: `from`, `f`, `s` - * @property {?number=} end - Exclusive ending index, if negative counts from end. Aliases: `to`, `t`, `e` + * @property {(RangeIndex|null)=} start - Inclusive start: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `from`, `f`, `s` + * @property {(RangeIndex|null)=} end - Exclusive end: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `to`, `t`, `e` * @property {(Limit|null)=} limit - Maximum number of values to return (ignored if `end` is set). Aliases: `count`, `c`, `l` * @property {Format=} format - Format of the output */ @@ -446,10 +446,6 @@ * * @typedef {number} Limit */ -/** - * @typedef {Object} LimitParam - * @property {Limit=} limit - */ /** * Lowest price value for a time period * @@ -488,6 +484,13 @@ * @property {number} lazyEndpoints - Number of lazy (computed on-the-fly) metric-index combinations * @property {number} storedEndpoints - Number of eager (stored on disk) metric-index combinations */ +/** + * Metadata about a metric + * + * @typedef {Object} MetricInfo + * @property {Index[]} indexes - Available indexes + * @property {string} type - Value type (e.g. "f32", "u64", "Sats") + */ /** * MetricLeaf with JSON Schema for client generation * @@ -507,8 +510,8 @@ * @typedef {Object} MetricSelection * @property {Metrics} metrics - Requested metrics * @property {Index} index - Index to query - * @property {?number=} start - Inclusive starting index, if negative counts from end. Aliases: `from`, `f`, `s` - * @property {?number=} end - Exclusive ending index, if negative counts from end. Aliases: `to`, `t`, `e` + * @property {(RangeIndex|null)=} start - Inclusive start: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `from`, `f`, `s` + * @property {(RangeIndex|null)=} end - Exclusive end: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `to`, `t`, `e` * @property {(Limit|null)=} limit - Maximum number of values to return (ignored if `end` is set). Aliases: `count`, `c`, `l` * @property {Format=} format - Format of the output */ @@ -518,8 +521,8 @@ * @typedef {Object} MetricSelectionLegacy * @property {Index} index * @property {Metrics} ids - * @property {?number=} start - Inclusive starting index, if negative counts from end. Aliases: `from`, `f`, `s` - * @property {?number=} end - Exclusive ending index, if negative counts from end. Aliases: `to`, `t`, `e` + * @property {(RangeIndex|null)=} start - Inclusive start: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `from`, `f`, `s` + * @property {(RangeIndex|null)=} end - Exclusive end: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `to`, `t`, `e` * @property {(Limit|null)=} limit - Maximum number of values to return (ignored if `end` is set). Aliases: `count`, `c`, `l` * @property {Format=} format - Format of the output */ @@ -679,6 +682,11 @@ * @property {number} blockCount - Total blocks in the time period * @property {number} lastEstimatedHashrate - Estimated network hashrate (hashes per second) */ +/** + * A range boundary: integer index, date, or timestamp. + * + * @typedef {(number|Date|Timestamp)} RangeIndex + */ /** * Transaction locktime * @@ -727,6 +735,11 @@ * * @typedef {number} SatsSigned */ +/** + * @typedef {Object} SearchQuery + * @property {Metric} q - Search query string + * @property {Limit=} limit - Maximum number of results + */ /** * Fixed-size boolean value optimized for on-disk storage (stored as u8) * @@ -2083,7 +2096,7 @@ function createBpsCentsPercentilesRatioSatsSmaStdUsdPattern(client, acc) { * @property {CentsDeltaUsdPattern} cap * @property {CumulativeNegativeRawSumPattern} loss * @property {MetricPattern1} mvrv - * @property {RawSumPattern2} netPnl + * @property {RawSumPattern3} netPnl * @property {BpsRatioPattern} nupl * @property {BpsCentsRatioSatsUsdPattern} price * @property {CumulativeRawSumPattern2} profit @@ -2101,7 +2114,7 @@ function createCapLossMvrvNetNuplPriceProfitSoprPattern(client, acc) { cap: createCentsDeltaUsdPattern(client, _m(acc, 'realized_cap')), loss: createCumulativeNegativeRawSumPattern(client, acc), mvrv: createMetricPattern1(client, _m(acc, 'mvrv')), - netPnl: createRawSumPattern2(client, _m(acc, 'net_realized_pnl')), + netPnl: createRawSumPattern3(client, _m(acc, 'net_realized_pnl')), nupl: createBpsRatioPattern(client, _m(acc, 'nupl_ratio')), price: createBpsCentsRatioSatsUsdPattern(client, _m(acc, 'realized_price')), profit: createCumulativeRawSumPattern2(client, _m(acc, 'realized_profit')), @@ -2234,11 +2247,11 @@ function create_1m1w1y24hBpsPercentRatioPattern(client, acc) { /** * @typedef {Object} CapLossMvrvNuplPriceProfitSoprPattern * @property {CentsUsdPattern} cap - * @property {RawSumPattern} loss + * @property {RawSumPattern2} loss * @property {MetricPattern1} mvrv * @property {BpsRatioPattern} nupl * @property {BpsCentsRatioSatsUsdPattern} price - * @property {RawSumPattern} profit + * @property {RawSumPattern2} profit * @property {ValuePattern} sopr */ @@ -2251,11 +2264,11 @@ function create_1m1w1y24hBpsPercentRatioPattern(client, acc) { function createCapLossMvrvNuplPriceProfitSoprPattern(client, acc) { return { cap: createCentsUsdPattern(client, _m(acc, 'realized_cap')), - loss: createRawSumPattern(client, _m(acc, 'realized_loss')), + loss: createRawSumPattern2(client, _m(acc, 'realized_loss')), mvrv: createMetricPattern1(client, _m(acc, 'mvrv')), nupl: createBpsRatioPattern(client, _m(acc, 'nupl_ratio')), price: createBpsCentsRatioSatsUsdPattern(client, _m(acc, 'realized_price')), - profit: createRawSumPattern(client, _m(acc, 'realized_profit')), + profit: createRawSumPattern2(client, _m(acc, 'realized_profit')), sopr: createValuePattern(client, _m(acc, 'value')), }; } @@ -2376,7 +2389,7 @@ function createBpsCentsPercentilesRatioSatsUsdPattern(client, acc) { * @typedef {Object} BtcCentsRelSatsUsdPattern3 * @property {MetricPattern1} btc * @property {MetricPattern1} cents - * @property {BpsPercentRatioPattern} relToCirculatingSupply + * @property {BpsPercentRatioPattern} relToCirculating * @property {BpsPercentRatioPattern} relToOwnSupply * @property {MetricPattern1} sats * @property {MetricPattern1} usd @@ -2392,7 +2405,7 @@ function createBtcCentsRelSatsUsdPattern3(client, acc) { return { btc: createMetricPattern1(client, acc), cents: createMetricPattern1(client, _m(acc, 'cents')), - relToCirculatingSupply: createBpsPercentRatioPattern(client, _m(acc, 'rel_to_circulating_supply')), + relToCirculating: createBpsPercentRatioPattern(client, _m(acc, 'rel_to_circulating_supply')), relToOwnSupply: createBpsPercentRatioPattern(client, _m(acc, 'rel_to_own_supply')), sats: createMetricPattern1(client, _m(acc, 'sats')), usd: createMetricPattern1(client, _m(acc, 'usd')), @@ -2426,40 +2439,13 @@ function createChangeCumulativeDeltaRawRelSumPattern(client, acc) { }; } -/** - * @typedef {Object} DeltaHalvedInRelTotalPattern - * @property {ChangeRatePattern} delta - * @property {BtcCentsSatsUsdPattern} halved - * @property {BtcCentsRelSatsUsdPattern} inLoss - * @property {BtcCentsRelSatsUsdPattern} inProfit - * @property {BpsPercentRatioPattern} relToCirculatingSupply - * @property {BtcCentsSatsUsdPattern} total - */ - -/** - * Create a DeltaHalvedInRelTotalPattern pattern node - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {DeltaHalvedInRelTotalPattern} - */ -function createDeltaHalvedInRelTotalPattern(client, acc) { - return { - delta: createChangeRatePattern(client, _m(acc, 'delta')), - halved: createBtcCentsSatsUsdPattern(client, _m(acc, 'halved')), - inLoss: createBtcCentsRelSatsUsdPattern(client, _m(acc, 'in_loss')), - inProfit: createBtcCentsRelSatsUsdPattern(client, _m(acc, 'in_profit')), - relToCirculatingSupply: createBpsPercentRatioPattern(client, _m(acc, 'rel_to_circulating_supply')), - total: createBtcCentsSatsUsdPattern(client, acc), - }; -} - /** * @typedef {Object} DeltaHalvedInRelTotalPattern2 - * @property {ChangeRatePattern2} delta + * @property {ChangeRatePattern} delta * @property {BtcCentsSatsUsdPattern} halved * @property {BtcCentsRelSatsUsdPattern3} inLoss * @property {BtcCentsRelSatsUsdPattern3} inProfit - * @property {BpsPercentRatioPattern} relToCirculatingSupply + * @property {BpsPercentRatioPattern} relToCirculating * @property {BtcCentsSatsUsdPattern} total */ @@ -2471,11 +2457,38 @@ function createDeltaHalvedInRelTotalPattern(client, acc) { */ function createDeltaHalvedInRelTotalPattern2(client, acc) { return { - delta: createChangeRatePattern2(client, _m(acc, 'delta')), + delta: createChangeRatePattern(client, _m(acc, 'delta')), halved: createBtcCentsSatsUsdPattern(client, _m(acc, 'halved')), inLoss: createBtcCentsRelSatsUsdPattern3(client, _m(acc, 'in_loss')), inProfit: createBtcCentsRelSatsUsdPattern3(client, _m(acc, 'in_profit')), - relToCirculatingSupply: createBpsPercentRatioPattern(client, _m(acc, 'rel_to_circulating_supply')), + relToCirculating: createBpsPercentRatioPattern(client, _m(acc, 'rel_to_circulating_supply')), + total: createBtcCentsSatsUsdPattern(client, acc), + }; +} + +/** + * @typedef {Object} DeltaHalvedInRelTotalPattern + * @property {ChangeRatePattern2} delta + * @property {BtcCentsSatsUsdPattern} halved + * @property {BtcCentsRelSatsUsdPattern} inLoss + * @property {BtcCentsRelSatsUsdPattern} inProfit + * @property {BpsPercentRatioPattern} relToCirculating + * @property {BtcCentsSatsUsdPattern} total + */ + +/** + * Create a DeltaHalvedInRelTotalPattern pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {DeltaHalvedInRelTotalPattern} + */ +function createDeltaHalvedInRelTotalPattern(client, acc) { + return { + delta: createChangeRatePattern2(client, _m(acc, 'delta')), + halved: createBtcCentsSatsUsdPattern(client, _m(acc, 'halved')), + inLoss: createBtcCentsRelSatsUsdPattern(client, _m(acc, 'in_loss')), + inProfit: createBtcCentsRelSatsUsdPattern(client, _m(acc, 'in_profit')), + relToCirculating: createBpsPercentRatioPattern(client, _m(acc, 'rel_to_circulating_supply')), total: createBtcCentsSatsUsdPattern(client, acc), }; } @@ -2485,7 +2498,7 @@ function createDeltaHalvedInRelTotalPattern2(client, acc) { * @property {MetricPattern1} negative * @property {CentsUsdPattern} raw * @property {BpsPercentRatioPattern} relToMarketCap - * @property {BpsPercentRatioPattern} relToOwnGrossPnl + * @property {BpsPercentRatioPattern} relToOwnGross * @property {BpsPercentRatioPattern} relToOwnMarketCap * @property {_24hPattern} sum */ @@ -2501,7 +2514,7 @@ function createNegativeRawRelSumPattern2(client, acc) { negative: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss')), raw: createCentsUsdPattern(client, _m(acc, 'unrealized_loss')), relToMarketCap: createBpsPercentRatioPattern(client, _m(acc, 'unrealized_loss_rel_to_market_cap')), - relToOwnGrossPnl: createBpsPercentRatioPattern(client, _m(acc, 'unrealized_loss_rel_to_own_gross_pnl')), + relToOwnGross: createBpsPercentRatioPattern(client, _m(acc, 'unrealized_loss_rel_to_own_gross_pnl')), relToOwnMarketCap: createBpsPercentRatioPattern(client, _m(acc, 'unrealized_loss_rel_to_own_market_cap')), sum: create_24hPattern(client, _m(acc, 'unrealized_loss_24h')), }; @@ -2613,7 +2626,7 @@ function createBpsCentsRatioSatsUsdPattern(client, acc) { * @typedef {Object} BtcCentsRelSatsUsdPattern * @property {MetricPattern1} btc * @property {MetricPattern1} cents - * @property {BpsPercentRatioPattern} relToCirculatingSupply + * @property {BpsPercentRatioPattern} relToCirculating * @property {MetricPattern1} sats * @property {MetricPattern1} usd */ @@ -2628,7 +2641,7 @@ function createBtcCentsRelSatsUsdPattern(client, acc) { return { btc: createMetricPattern1(client, acc), cents: createMetricPattern1(client, _m(acc, 'cents')), - relToCirculatingSupply: createBpsPercentRatioPattern(client, _m(acc, 'rel_to_circulating_supply')), + relToCirculating: createBpsPercentRatioPattern(client, _m(acc, 'rel_to_circulating_supply')), sats: createMetricPattern1(client, _m(acc, 'sats')), usd: createMetricPattern1(client, _m(acc, 'usd')), }; @@ -2740,7 +2753,7 @@ function createEmaHistogramLineSignalPattern(client, acc) { * @property {InPattern} investorCap * @property {NegativeRawSumPattern} loss * @property {CentsUsdPattern} netPnl - * @property {RawSumPattern} profit + * @property {RawSumPattern2} profit */ /** @@ -2755,7 +2768,7 @@ function createInvestedInvestorLossNetProfitPattern(client, acc) { investorCap: createInPattern(client, _m(acc, 'investor_cap_in')), loss: createNegativeRawSumPattern(client, acc), netPnl: createCentsUsdPattern(client, _m(acc, 'net_unrealized_pnl')), - profit: createRawSumPattern(client, _m(acc, 'unrealized_profit')), + profit: createRawSumPattern2(client, _m(acc, 'unrealized_profit')), }; } @@ -2813,7 +2826,7 @@ function createPhsReboundThsPattern(client, acc) { * @typedef {Object} RawRelSumPattern2 * @property {CentsUsdPattern} raw * @property {BpsPercentRatioPattern} relToMarketCap - * @property {BpsPercentRatioPattern} relToOwnGrossPnl + * @property {BpsPercentRatioPattern} relToOwnGross * @property {BpsPercentRatioPattern} relToOwnMarketCap * @property {_24hPattern} sum */ @@ -2828,7 +2841,7 @@ function createRawRelSumPattern2(client, acc) { return { raw: createCentsUsdPattern(client, acc), relToMarketCap: createBpsPercentRatioPattern(client, _m(acc, 'rel_to_market_cap')), - relToOwnGrossPnl: createBpsPercentRatioPattern(client, _m(acc, 'rel_to_own_gross_pnl')), + relToOwnGross: createBpsPercentRatioPattern(client, _m(acc, 'rel_to_own_gross_pnl')), relToOwnMarketCap: createBpsPercentRatioPattern(client, _m(acc, 'rel_to_own_market_cap')), sum: create_24hPattern(client, _m(acc, '24h')), }; @@ -3049,8 +3062,8 @@ function createAddrOutputsRealizedSupplyPattern(client, acc) { * @typedef {Object} AdjustedRatioValuePattern * @property {RatioValuePattern2} adjusted * @property {_1m1w1y24hPattern} ratio - * @property {RawSumPattern3} valueCreated - * @property {RawSumPattern3} valueDestroyed + * @property {RawSumPattern} valueCreated + * @property {RawSumPattern} valueDestroyed */ /** @@ -3063,8 +3076,8 @@ function createAdjustedRatioValuePattern(client, acc) { return { adjusted: createRatioValuePattern2(client, _m(acc, 'adjusted')), ratio: create_1m1w1y24hPattern(client, _m(acc, 'sopr')), - valueCreated: createRawSumPattern3(client, _m(acc, 'value_created')), - valueDestroyed: createRawSumPattern3(client, _m(acc, 'value_destroyed')), + valueCreated: createRawSumPattern(client, _m(acc, 'value_created')), + valueDestroyed: createRawSumPattern(client, _m(acc, 'value_destroyed')), }; } @@ -3116,7 +3129,7 @@ function createBtcCentsSatsUsdPattern(client, acc) { /** * @typedef {Object} CapLowerPriceUpperPattern - * @property {RawPattern} cap + * @property {RawPattern2} cap * @property {CentsSatsUsdPattern} lowerPriceBand * @property {BpsCentsPercentilesRatioSatsUsdPattern} price * @property {CentsSatsUsdPattern} upperPriceBand @@ -3130,7 +3143,7 @@ function createBtcCentsSatsUsdPattern(client, acc) { */ function createCapLowerPriceUpperPattern(client, acc) { return { - cap: createRawPattern(client, _m(acc, 'investor_cap_raw')), + cap: createRawPattern2(client, _m(acc, 'investor_cap_raw')), lowerPriceBand: createCentsSatsUsdPattern(client, _m(acc, 'lower_price_band')), price: createBpsCentsPercentilesRatioSatsUsdPattern(client, _m(acc, 'investor_price')), upperPriceBand: createCentsSatsUsdPattern(client, _m(acc, 'upper_price_band')), @@ -3140,7 +3153,7 @@ function createCapLowerPriceUpperPattern(client, acc) { /** * @typedef {Object} CentsRelUsdPattern2 * @property {MetricPattern1} cents - * @property {BpsPercentRatioPattern} relToOwnGrossPnl + * @property {BpsPercentRatioPattern} relToOwnGross * @property {BpsPercentRatioPattern} relToOwnMarketCap * @property {MetricPattern1} usd */ @@ -3154,7 +3167,7 @@ function createCapLowerPriceUpperPattern(client, acc) { function createCentsRelUsdPattern2(client, acc) { return { cents: createMetricPattern1(client, _m(acc, 'cents')), - relToOwnGrossPnl: createBpsPercentRatioPattern(client, _m(acc, 'rel_to_own_gross_pnl')), + relToOwnGross: createBpsPercentRatioPattern(client, _m(acc, 'rel_to_own_gross_pnl')), relToOwnMarketCap: createBpsPercentRatioPattern(client, _m(acc, 'rel_to_own_market_cap')), usd: createMetricPattern1(client, acc), }; @@ -3535,7 +3548,7 @@ function createGreedNetPainPattern(client, acc) { * @typedef {Object} LossNetProfitPattern * @property {NegativeRawSumPattern} loss * @property {CentsUsdPattern} netPnl - * @property {RawSumPattern} profit + * @property {RawSumPattern2} profit */ /** @@ -3548,7 +3561,7 @@ function createLossNetProfitPattern(client, acc) { return { loss: createNegativeRawSumPattern(client, acc), netPnl: createCentsUsdPattern(client, _m(acc, 'net_unrealized_pnl')), - profit: createRawSumPattern(client, _m(acc, 'unrealized_profit')), + profit: createRawSumPattern2(client, _m(acc, 'unrealized_profit')), }; } @@ -3618,8 +3631,8 @@ function createRatioValuePattern2(client, acc) { /** * @typedef {Object} RatioValuePattern * @property {_24hPattern2} ratio - * @property {RawSumPattern2} valueCreated - * @property {RawSumPattern2} valueDestroyed + * @property {RawSumPattern3} valueCreated + * @property {RawSumPattern3} valueDestroyed */ /** @@ -3631,8 +3644,8 @@ function createRatioValuePattern2(client, acc) { function createRatioValuePattern(client, acc) { return { ratio: create_24hPattern2(client, _m(acc, 'sopr_24h')), - valueCreated: createRawSumPattern2(client, _m(acc, 'value_created')), - valueDestroyed: createRawSumPattern2(client, _m(acc, 'value_destroyed')), + valueCreated: createRawSumPattern3(client, _m(acc, 'value_created')), + valueDestroyed: createRawSumPattern3(client, _m(acc, 'value_destroyed')), }; } @@ -3703,25 +3716,6 @@ function createCumulativeRawSumPattern(client, acc) { }; } -/** - * @typedef {Object} BaseCumulativePattern - * @property {BtcCentsSatsUsdPattern} base - * @property {BtcCentsSatsUsdPattern} cumulative - */ - -/** - * Create a BaseCumulativePattern pattern node - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {BaseCumulativePattern} - */ -function createBaseCumulativePattern(client, acc) { - return { - base: createBtcCentsSatsUsdPattern(client, acc), - cumulative: createBtcCentsSatsUsdPattern(client, _m(acc, 'cumulative')), - }; -} - /** * @typedef {Object} BaseSumPattern * @property {MetricPattern1} base @@ -3741,29 +3735,10 @@ function createBaseSumPattern(client, acc) { }; } -/** - * @typedef {Object} BaseDeltaPattern - * @property {MetricPattern1} base - * @property {ChangeRatePattern} delta - */ - -/** - * Create a BaseDeltaPattern pattern node - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {BaseDeltaPattern} - */ -function createBaseDeltaPattern(client, acc) { - return { - base: createMetricPattern1(client, acc), - delta: createChangeRatePattern(client, _m(acc, 'delta')), - }; -} - /** * @typedef {Object} BaseDeltaPattern2 * @property {MetricPattern1} base - * @property {ChangeRatePattern2} delta + * @property {ChangeRatePattern} delta */ /** @@ -3773,6 +3748,25 @@ function createBaseDeltaPattern(client, acc) { * @returns {BaseDeltaPattern2} */ function createBaseDeltaPattern2(client, acc) { + return { + base: createMetricPattern1(client, acc), + delta: createChangeRatePattern(client, _m(acc, 'delta')), + }; +} + +/** + * @typedef {Object} BaseDeltaPattern + * @property {MetricPattern1} base + * @property {ChangeRatePattern2} delta + */ + +/** + * Create a BaseDeltaPattern pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {BaseDeltaPattern} + */ +function createBaseDeltaPattern(client, acc) { return { base: createMetricPattern1(client, acc), delta: createChangeRatePattern2(client, _m(acc, 'delta')), @@ -3837,18 +3831,18 @@ function createCentsUsdPattern(client, acc) { } /** - * @typedef {Object} ChangeRatePattern2 + * @typedef {Object} ChangeRatePattern * @property {_1m1w1y24hPattern} change * @property {_1m1w1y24hPattern2} rate */ /** - * Create a ChangeRatePattern2 pattern node + * Create a ChangeRatePattern pattern node * @param {BrkClientBase} client * @param {string} acc - Accumulated metric name - * @returns {ChangeRatePattern2} + * @returns {ChangeRatePattern} */ -function createChangeRatePattern2(client, acc) { +function createChangeRatePattern(client, acc) { return { change: create_1m1w1y24hPattern(client, _m(acc, 'change')), rate: create_1m1w1y24hPattern2(client, _m(acc, 'rate')), @@ -3875,18 +3869,18 @@ function createChangeRatePattern4(client, acc) { } /** - * @typedef {Object} ChangeRatePattern + * @typedef {Object} ChangeRatePattern2 * @property {_1mPattern} change * @property {_1mPattern2} 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_1mPattern(client, _m(acc, 'change_1m')), rate: create_1mPattern2(client, _m(acc, 'rate_1m')), @@ -3914,7 +3908,7 @@ function createChangeRatePattern3(client, acc) { /** * @typedef {Object} CoindaysSentPattern - * @property {RawSumPattern2} coindaysDestroyed + * @property {RawSumPattern3} coindaysDestroyed * @property {InRawSumPattern} sent */ @@ -3926,7 +3920,7 @@ function createChangeRatePattern3(client, acc) { */ function createCoindaysSentPattern(client, acc) { return { - coindaysDestroyed: createRawSumPattern2(client, _m(acc, 'coindays_destroyed')), + coindaysDestroyed: createRawSumPattern3(client, _m(acc, 'coindays_destroyed')), sent: createInRawSumPattern(client, _m(acc, 'sent')), }; } @@ -3971,8 +3965,8 @@ function createInPattern2(client, acc) { /** * @typedef {Object} InPattern - * @property {RawPattern} inLoss - * @property {RawPattern} inProfit + * @property {RawPattern2} inLoss + * @property {RawPattern2} inProfit */ /** @@ -3983,15 +3977,15 @@ function createInPattern2(client, acc) { */ function createInPattern(client, acc) { return { - inLoss: createRawPattern(client, _m(acc, 'loss_raw')), - inProfit: createRawPattern(client, _m(acc, 'profit_raw')), + inLoss: createRawPattern2(client, _m(acc, 'loss_raw')), + inProfit: createRawPattern2(client, _m(acc, 'profit_raw')), }; } /** * @typedef {Object} LossProfitPattern2 - * @property {RawSumPattern} loss - * @property {RawSumPattern} profit + * @property {RawSumPattern2} loss + * @property {RawSumPattern2} profit */ /** @@ -4002,8 +3996,8 @@ function createInPattern(client, acc) { */ function createLossProfitPattern2(client, acc) { return { - loss: createRawSumPattern(client, _m(acc, 'loss')), - profit: createRawSumPattern(client, _m(acc, 'profit')), + loss: createRawSumPattern2(client, _m(acc, 'loss')), + profit: createRawSumPattern2(client, _m(acc, 'profit')), }; } @@ -4065,18 +4059,18 @@ function createRawSumPattern4(client, acc) { } /** - * @typedef {Object} RawSumPattern + * @typedef {Object} RawSumPattern2 * @property {CentsUsdPattern} raw * @property {_24hPattern} sum */ /** - * Create a RawSumPattern pattern node + * Create a RawSumPattern2 pattern node * @param {BrkClientBase} client * @param {string} acc - Accumulated metric name - * @returns {RawSumPattern} + * @returns {RawSumPattern2} */ -function createRawSumPattern(client, acc) { +function createRawSumPattern2(client, acc) { return { raw: createCentsUsdPattern(client, acc), sum: create_24hPattern(client, _m(acc, '24h')), @@ -4142,8 +4136,8 @@ function createSdSmaPattern(client, acc) { /** * @typedef {Object} ValuePattern - * @property {RawSumPattern2} valueCreated - * @property {RawSumPattern2} valueDestroyed + * @property {RawSumPattern3} valueCreated + * @property {RawSumPattern3} valueDestroyed */ /** @@ -4154,8 +4148,8 @@ function createSdSmaPattern(client, acc) { */ function createValuePattern(client, acc) { return { - valueCreated: createRawSumPattern2(client, _m(acc, 'created')), - valueDestroyed: createRawSumPattern2(client, _m(acc, 'destroyed')), + valueCreated: createRawSumPattern3(client, _m(acc, 'created')), + valueDestroyed: createRawSumPattern3(client, _m(acc, 'destroyed')), }; } @@ -4182,11 +4176,32 @@ function createCumulativeRawPattern(client, acc) { /** * @template T - * @typedef {Object} RawSumPattern3 + * @typedef {Object} RawSumPattern * @property {MetricPattern1} raw * @property {_1m1w1y24hPattern} sum */ +/** + * Create a RawSumPattern pattern node + * @template T + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {RawSumPattern} + */ +function createRawSumPattern(client, acc) { + return { + raw: createMetricPattern1(client, acc), + sum: create_1m1w1y24hPattern(client, _m(acc, 'sum')), + }; +} + +/** + * @template T + * @typedef {Object} RawSumPattern3 + * @property {MetricPattern1} raw + * @property {_24hPattern2} sum + */ + /** * Create a RawSumPattern3 pattern node * @template T @@ -4195,27 +4210,6 @@ function createCumulativeRawPattern(client, acc) { * @returns {RawSumPattern3} */ function createRawSumPattern3(client, acc) { - return { - raw: createMetricPattern1(client, acc), - sum: create_1m1w1y24hPattern(client, _m(acc, 'sum')), - }; -} - -/** - * @template T - * @typedef {Object} RawSumPattern2 - * @property {MetricPattern1} raw - * @property {_24hPattern2} sum - */ - -/** - * Create a RawSumPattern2 pattern node - * @template T - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {RawSumPattern2} - */ -function createRawSumPattern2(client, acc) { return { raw: createMetricPattern1(client, acc), sum: create_24hPattern2(client, _m(acc, '24h')), @@ -4381,18 +4375,18 @@ function create_24hPattern2(client, acc) { /** * @template T - * @typedef {Object} RawPattern + * @typedef {Object} RawPattern2 * @property {MetricPattern18} raw */ /** - * Create a RawPattern pattern node + * Create a RawPattern2 pattern node * @template T * @param {BrkClientBase} client * @param {string} acc - Accumulated metric name - * @returns {RawPattern} + * @returns {RawPattern2} */ -function createRawPattern(client, acc) { +function createRawPattern2(client, acc) { return { raw: createMetricPattern18(client, acc), }; @@ -4442,8 +4436,8 @@ function createRawPattern(client, acc) { * @property {MetricPattern1} asHash * @property {BpsPercentRatioPattern} adjustment * @property {MetricPattern1} epoch - * @property {MetricPattern1} blocksBeforeNextAdjustment - * @property {MetricPattern1} daysBeforeNextAdjustment + * @property {MetricPattern1} blocksBeforeNext + * @property {MetricPattern1} daysBeforeNext */ /** @@ -4539,8 +4533,8 @@ function createRawPattern(client, acc) { /** * @typedef {Object} MetricsTree_Blocks_Halving * @property {MetricPattern1} epoch - * @property {MetricPattern1} blocksBeforeNextHalving - * @property {MetricPattern1} daysBeforeNextHalving + * @property {MetricPattern1} blocksBeforeNext + * @property {MetricPattern1} daysBeforeNext */ /** @@ -4552,6 +4546,16 @@ function createRawPattern(client, acc) { /** * @typedef {Object} MetricsTree_Transactions + * @property {MetricsTree_Transactions_Raw} raw + * @property {MetricsTree_Transactions_Count} count + * @property {MetricsTree_Transactions_Size} size + * @property {MetricsTree_Transactions_Fees} fees + * @property {MetricsTree_Transactions_Versions} versions + * @property {MetricsTree_Transactions_Volume} volume + */ + +/** + * @typedef {Object} MetricsTree_Transactions_Raw * @property {MetricPattern18} firstTxindex * @property {MetricPattern19} height * @property {MetricPattern19} txid @@ -4562,11 +4566,6 @@ function createRawPattern(client, acc) { * @property {MetricPattern19} isExplicitlyRbf * @property {MetricPattern19} firstTxinindex * @property {MetricPattern19} firstTxoutindex - * @property {MetricsTree_Transactions_Count} count - * @property {MetricsTree_Transactions_Size} size - * @property {MetricsTree_Transactions_Fees} fees - * @property {MetricsTree_Transactions_Versions} versions - * @property {MetricsTree_Transactions_Volume} volume */ /** @@ -4600,7 +4599,7 @@ function createRawPattern(client, acc) { * @typedef {Object} MetricsTree_Transactions_Volume * @property {_1m1w1y24hBtcCentsSatsUsdPattern} sentSum * @property {_1m1w1y24hBtcCentsSatsUsdPattern} receivedSum - * @property {BtcCentsSatsUsdPattern} annualizedVolume + * @property {BtcCentsSatsUsdPattern} annualized * @property {MetricPattern1} txPerSec * @property {MetricPattern1} outputsPerSec * @property {MetricPattern1} inputsPerSec @@ -4608,13 +4607,18 @@ function createRawPattern(client, acc) { /** * @typedef {Object} MetricsTree_Inputs + * @property {MetricsTree_Inputs_Raw} raw + * @property {MetricsTree_Inputs_Spent} spent + * @property {AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern} count + */ + +/** + * @typedef {Object} MetricsTree_Inputs_Raw * @property {MetricPattern18} firstTxinindex * @property {MetricPattern20} outpoint * @property {MetricPattern20} txindex * @property {MetricPattern20} outputtype * @property {MetricPattern20} typeindex - * @property {MetricsTree_Inputs_Spent} spent - * @property {AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern} count */ /** @@ -4625,13 +4629,18 @@ function createRawPattern(client, acc) { /** * @typedef {Object} MetricsTree_Outputs + * @property {MetricsTree_Outputs_Raw} raw + * @property {MetricsTree_Outputs_Spent} spent + * @property {MetricsTree_Outputs_Count} count + */ + +/** + * @typedef {Object} MetricsTree_Outputs_Raw * @property {MetricPattern18} firstTxoutindex * @property {MetricPattern21} value * @property {MetricPattern21} outputtype * @property {MetricPattern21} typeindex * @property {MetricPattern21} txindex - * @property {MetricsTree_Outputs_Spent} spent - * @property {MetricsTree_Outputs_Count} count */ /** @@ -4642,44 +4651,114 @@ function createRawPattern(client, acc) { /** * @typedef {Object} MetricsTree_Outputs_Count * @property {AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern} total - * @property {MetricPattern1} utxoCount + * @property {MetricPattern1} unspent */ /** * @typedef {Object} MetricsTree_Addresses - * @property {MetricPattern18} firstP2pk65addressindex - * @property {MetricPattern18} firstP2pk33addressindex - * @property {MetricPattern18} firstP2pkhaddressindex - * @property {MetricPattern18} firstP2shaddressindex - * @property {MetricPattern18} firstP2wpkhaddressindex - * @property {MetricPattern18} firstP2wshaddressindex - * @property {MetricPattern18} firstP2traddressindex - * @property {MetricPattern18} firstP2aaddressindex - * @property {MetricPattern27} p2pk65bytes - * @property {MetricPattern26} p2pk33bytes - * @property {MetricPattern28} p2pkhbytes - * @property {MetricPattern29} p2shbytes - * @property {MetricPattern31} p2wpkhbytes - * @property {MetricPattern32} p2wshbytes - * @property {MetricPattern30} p2trbytes - * @property {MetricPattern24} p2abytes + * @property {MetricsTree_Addresses_Raw} raw + */ + +/** + * @typedef {Object} MetricsTree_Addresses_Raw + * @property {MetricsTree_Addresses_Raw_P2pk65} p2pk65 + * @property {MetricsTree_Addresses_Raw_P2pk33} p2pk33 + * @property {MetricsTree_Addresses_Raw_P2pkh} p2pkh + * @property {MetricsTree_Addresses_Raw_P2sh} p2sh + * @property {MetricsTree_Addresses_Raw_P2wpkh} p2wpkh + * @property {MetricsTree_Addresses_Raw_P2wsh} p2wsh + * @property {MetricsTree_Addresses_Raw_P2tr} p2tr + * @property {MetricsTree_Addresses_Raw_P2a} p2a + */ + +/** + * @typedef {Object} MetricsTree_Addresses_Raw_P2pk65 + * @property {MetricPattern18} firstIndex + * @property {MetricPattern27} bytes + */ + +/** + * @typedef {Object} MetricsTree_Addresses_Raw_P2pk33 + * @property {MetricPattern18} firstIndex + * @property {MetricPattern26} bytes + */ + +/** + * @typedef {Object} MetricsTree_Addresses_Raw_P2pkh + * @property {MetricPattern18} firstIndex + * @property {MetricPattern28} bytes + */ + +/** + * @typedef {Object} MetricsTree_Addresses_Raw_P2sh + * @property {MetricPattern18} firstIndex + * @property {MetricPattern29} bytes + */ + +/** + * @typedef {Object} MetricsTree_Addresses_Raw_P2wpkh + * @property {MetricPattern18} firstIndex + * @property {MetricPattern31} bytes + */ + +/** + * @typedef {Object} MetricsTree_Addresses_Raw_P2wsh + * @property {MetricPattern18} firstIndex + * @property {MetricPattern32} bytes + */ + +/** + * @typedef {Object} MetricsTree_Addresses_Raw_P2tr + * @property {MetricPattern18} firstIndex + * @property {MetricPattern30} bytes + */ + +/** + * @typedef {Object} MetricsTree_Addresses_Raw_P2a + * @property {MetricPattern18} firstIndex + * @property {MetricPattern24} bytes */ /** * @typedef {Object} MetricsTree_Scripts - * @property {MetricPattern18} firstEmptyoutputindex - * @property {MetricPattern18} firstOpreturnindex - * @property {MetricPattern18} firstP2msoutputindex - * @property {MetricPattern18} firstUnknownoutputindex - * @property {MetricPattern22} emptyToTxindex - * @property {MetricPattern23} opreturnToTxindex - * @property {MetricPattern25} p2msToTxindex - * @property {MetricPattern33} unknownToTxindex + * @property {MetricsTree_Scripts_Raw} raw * @property {MetricsTree_Scripts_Count} count * @property {MetricsTree_Scripts_Value} value * @property {MetricsTree_Scripts_Adoption} adoption */ +/** + * @typedef {Object} MetricsTree_Scripts_Raw + * @property {MetricsTree_Scripts_Raw_Empty} empty + * @property {MetricsTree_Scripts_Raw_Opreturn} opreturn + * @property {MetricsTree_Scripts_Raw_P2ms} p2ms + * @property {MetricsTree_Scripts_Raw_Unknown} unknown + */ + +/** + * @typedef {Object} MetricsTree_Scripts_Raw_Empty + * @property {MetricPattern18} firstIndex + * @property {MetricPattern22} toTxindex + */ + +/** + * @typedef {Object} MetricsTree_Scripts_Raw_Opreturn + * @property {MetricPattern18} firstIndex + * @property {MetricPattern23} toTxindex + */ + +/** + * @typedef {Object} MetricsTree_Scripts_Raw_P2ms + * @property {MetricPattern18} firstIndex + * @property {MetricPattern25} toTxindex + */ + +/** + * @typedef {Object} MetricsTree_Scripts_Raw_Unknown + * @property {MetricPattern18} firstIndex + * @property {MetricPattern33} toTxindex + */ + /** * @typedef {Object} MetricsTree_Scripts_Count * @property {CumulativeRawSumPattern} p2a @@ -4699,7 +4778,13 @@ function createRawPattern(client, acc) { /** * @typedef {Object} MetricsTree_Scripts_Value - * @property {BaseCumulativePattern} opreturn + * @property {MetricsTree_Scripts_Value_Opreturn} opreturn + */ + +/** + * @typedef {Object} MetricsTree_Scripts_Value_Opreturn + * @property {BtcCentsSatsUsdPattern} base + * @property {BtcCentsSatsUsdPattern} cumulative */ /** @@ -4717,13 +4802,17 @@ function createRawPattern(client, acc) { /** * @typedef {Object} MetricsTree_Mining_Rewards * @property {BaseCumulativeSumPattern} coinbase - * @property {BaseCumulativePattern} subsidy + * @property {MetricsTree_Mining_Rewards_Subsidy} subsidy * @property {MetricsTree_Mining_Rewards_Fees} fees - * @property {BaseCumulativeSumPattern} unclaimedRewards - * @property {_1m1w1y24hBpsPercentRatioPattern} feeDominance - * @property {_1m1w1y24hBpsPercentRatioPattern} subsidyDominance - * @property {CentsUsdPattern} subsidySma1y - * @property {MetricsTree_Mining_Rewards_FeeRatioMultiple} feeRatioMultiple + * @property {BaseCumulativeSumPattern} unclaimed + */ + +/** + * @typedef {Object} MetricsTree_Mining_Rewards_Subsidy + * @property {BtcCentsSatsUsdPattern} base + * @property {BtcCentsSatsUsdPattern} cumulative + * @property {_1m1w1y24hBpsPercentRatioPattern} dominance + * @property {CentsUsdPattern} sma1y */ /** @@ -4734,10 +4823,12 @@ function createRawPattern(client, acc) { * @property {AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2} _1w * @property {AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2} _1m * @property {AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2} _1y + * @property {_1m1w1y24hBpsPercentRatioPattern} dominance + * @property {MetricsTree_Mining_Rewards_Fees_RatioMultiple} ratioMultiple */ /** - * @typedef {Object} MetricsTree_Mining_Rewards_FeeRatioMultiple + * @typedef {Object} MetricsTree_Mining_Rewards_Fees_RatioMultiple * @property {BpsRatioPattern} _24h * @property {BpsRatioPattern} _1w * @property {BpsRatioPattern} _1m @@ -5137,7 +5228,7 @@ function createRawPattern(client, acc) { /** * @typedef {Object} MetricsTree_Market_Ath - * @property {CentsSatsUsdPattern} price + * @property {CentsSatsUsdPattern} high * @property {BpsPercentRatioPattern} drawdown * @property {MetricPattern1} daysSince * @property {MetricPattern2} yearsSince @@ -5651,7 +5742,7 @@ function createRawPattern(client, acc) { * @typedef {Object} MetricsTree_Prices * @property {MetricsTree_Prices_Split} split * @property {MetricsTree_Prices_Ohlc} ohlc - * @property {MetricsTree_Prices_Price} price + * @property {MetricsTree_Prices_Spot} spot */ /** @@ -5677,7 +5768,7 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Prices_Price + * @typedef {Object} MetricsTree_Prices_Spot * @property {MetricPattern1} cents * @property {MetricPattern1} usd * @property {MetricPattern1} sats @@ -5686,16 +5777,25 @@ function createRawPattern(client, acc) { /** * @typedef {Object} MetricsTree_Distribution * @property {MetricPattern18} supplyState - * @property {MetricsTree_Distribution_AnyAddressIndexes} anyAddressIndexes - * @property {MetricsTree_Distribution_AddressesData} addressesData - * @property {MetricsTree_Distribution_UtxoCohorts} utxoCohorts - * @property {MetricsTree_Distribution_AddressCohorts} addressCohorts - * @property {CumulativeRawPattern} coinblocksDestroyed * @property {MetricsTree_Distribution_Addresses} addresses + * @property {MetricsTree_Distribution_Cohorts} cohorts + * @property {CumulativeRawPattern} coinblocksDestroyed */ /** - * @typedef {Object} MetricsTree_Distribution_AnyAddressIndexes + * @typedef {Object} MetricsTree_Distribution_Addresses + * @property {MetricsTree_Distribution_Addresses_Indexes} indexes + * @property {MetricsTree_Distribution_Addresses_Data} data + * @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3} funded + * @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3} empty + * @property {MetricsTree_Distribution_Addresses_Activity} activity + * @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3} total + * @property {MetricsTree_Distribution_Addresses_New} new + * @property {MetricsTree_Distribution_Addresses_Delta} delta + */ + +/** + * @typedef {Object} MetricsTree_Distribution_Addresses_Indexes * @property {MetricPattern24} p2a * @property {MetricPattern26} p2pk33 * @property {MetricPattern27} p2pk65 @@ -5704,45 +5804,92 @@ function createRawPattern(client, acc) { * @property {MetricPattern30} p2tr * @property {MetricPattern31} p2wpkh * @property {MetricPattern32} p2wsh + * @property {MetricPattern34} funded + * @property {MetricPattern35} empty */ /** - * @typedef {Object} MetricsTree_Distribution_AddressesData + * @typedef {Object} MetricsTree_Distribution_Addresses_Data * @property {MetricPattern34} funded * @property {MetricPattern35} empty */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts - * @property {MetricsTree_Distribution_UtxoCohorts_All} all - * @property {MetricsTree_Distribution_UtxoCohorts_Sth} sth - * @property {MetricsTree_Distribution_UtxoCohorts_Lth} lth - * @property {MetricsTree_Distribution_UtxoCohorts_AgeRange} ageRange - * @property {MetricsTree_Distribution_UtxoCohorts_MaxAge} maxAge - * @property {MetricsTree_Distribution_UtxoCohorts_MinAge} minAge - * @property {MetricsTree_Distribution_UtxoCohorts_Epoch} epoch - * @property {MetricsTree_Distribution_UtxoCohorts_Class} class - * @property {MetricsTree_Distribution_UtxoCohorts_GeAmount} geAmount - * @property {MetricsTree_Distribution_UtxoCohorts_AmountRange} amountRange - * @property {MetricsTree_Distribution_UtxoCohorts_LtAmount} ltAmount - * @property {MetricsTree_Distribution_UtxoCohorts_Type} type - * @property {MetricsTree_Distribution_UtxoCohorts_Profitability} profitability - * @property {MetricsTree_Distribution_UtxoCohorts_Matured} matured + * @typedef {Object} MetricsTree_Distribution_Addresses_Activity + * @property {BothReactivatedReceivingSendingPattern} all + * @property {BothReactivatedReceivingSendingPattern} p2pk65 + * @property {BothReactivatedReceivingSendingPattern} p2pk33 + * @property {BothReactivatedReceivingSendingPattern} p2pkh + * @property {BothReactivatedReceivingSendingPattern} p2sh + * @property {BothReactivatedReceivingSendingPattern} p2wpkh + * @property {BothReactivatedReceivingSendingPattern} p2wsh + * @property {BothReactivatedReceivingSendingPattern} p2tr + * @property {BothReactivatedReceivingSendingPattern} p2a */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_All - * @property {MetricsTree_Distribution_UtxoCohorts_All_Supply} supply + * @typedef {Object} MetricsTree_Distribution_Addresses_New + * @property {RawSumPattern} all + * @property {RawSumPattern} p2pk65 + * @property {RawSumPattern} p2pk33 + * @property {RawSumPattern} p2pkh + * @property {RawSumPattern} p2sh + * @property {RawSumPattern} p2wpkh + * @property {RawSumPattern} p2wsh + * @property {RawSumPattern} p2tr + * @property {RawSumPattern} p2a + */ + +/** + * @typedef {Object} MetricsTree_Distribution_Addresses_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 + */ + +/** + * @typedef {Object} MetricsTree_Distribution_Cohorts + * @property {MetricsTree_Distribution_Cohorts_Utxo} utxo + * @property {MetricsTree_Distribution_Cohorts_Address} address + */ + +/** + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo + * @property {MetricsTree_Distribution_Cohorts_Utxo_All} all + * @property {MetricsTree_Distribution_Cohorts_Utxo_Sth} sth + * @property {MetricsTree_Distribution_Cohorts_Utxo_Lth} lth + * @property {MetricsTree_Distribution_Cohorts_Utxo_AgeRange} ageRange + * @property {MetricsTree_Distribution_Cohorts_Utxo_MaxAge} maxAge + * @property {MetricsTree_Distribution_Cohorts_Utxo_MinAge} minAge + * @property {MetricsTree_Distribution_Cohorts_Utxo_Epoch} epoch + * @property {MetricsTree_Distribution_Cohorts_Utxo_Class} class + * @property {MetricsTree_Distribution_Cohorts_Utxo_GeAmount} geAmount + * @property {MetricsTree_Distribution_Cohorts_Utxo_AmountRange} amountRange + * @property {MetricsTree_Distribution_Cohorts_Utxo_LtAmount} ltAmount + * @property {MetricsTree_Distribution_Cohorts_Utxo_Type} type + * @property {MetricsTree_Distribution_Cohorts_Utxo_Profitability} profitability + * @property {MetricsTree_Distribution_Cohorts_Utxo_Matured} matured + */ + +/** + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_All + * @property {MetricsTree_Distribution_Cohorts_Utxo_All_Supply} supply * @property {UnspentPattern3} outputs * @property {CoindaysCoinyearsDormancySentVelocityPattern} activity * @property {CapGrossInvestorLossMvrvNetNuplPeakPriceProfitSoprPattern} realized * @property {InvestedMaxMinPercentilesSupplyPattern} costBasis - * @property {MetricsTree_Distribution_UtxoCohorts_All_Unrealized} unrealized + * @property {MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized} unrealized */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_All_Supply - * @property {ChangeRatePattern2} delta + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_All_Supply + * @property {ChangeRatePattern} delta * @property {BtcCentsRelSatsUsdPattern2} inProfit * @property {BtcCentsRelSatsUsdPattern2} inLoss * @property {BtcCentsSatsUsdPattern} total @@ -5750,42 +5897,42 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_All_Unrealized + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized * @property {CentsUsdPattern} grossPnl * @property {InPattern2} investedCapital * @property {GreedNetPainPattern} sentiment * @property {InPattern} investorCap - * @property {MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Loss} loss - * @property {MetricsTree_Distribution_UtxoCohorts_All_Unrealized_NetPnl} netPnl - * @property {MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Profit} profit + * @property {MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Loss} loss + * @property {MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_NetPnl} netPnl + * @property {MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Profit} profit */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Loss + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Loss * @property {MetricPattern1} negative * @property {CentsUsdPattern} raw * @property {_24hPattern} sum * @property {BpsPercentRatioPattern} relToMarketCap - * @property {BpsPercentRatioPattern} relToOwnGrossPnl + * @property {BpsPercentRatioPattern} relToOwnGross */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_All_Unrealized_NetPnl + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_NetPnl * @property {MetricPattern1} cents * @property {MetricPattern1} usd - * @property {BpsPercentRatioPattern} relToOwnGrossPnl + * @property {BpsPercentRatioPattern} relToOwnGross */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Profit + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Profit * @property {CentsUsdPattern} raw * @property {_24hPattern} sum * @property {BpsPercentRatioPattern} relToMarketCap - * @property {BpsPercentRatioPattern} relToOwnGrossPnl + * @property {BpsPercentRatioPattern} relToOwnGross */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Sth + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_Sth * @property {CapGrossInvestorLossMvrvNetNuplPeakPriceProfitSoprPattern} realized * @property {DeltaHalvedInRelTotalPattern2} supply * @property {UnspentPattern3} outputs @@ -5795,22 +5942,22 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Lth + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_Lth * @property {DeltaHalvedInRelTotalPattern2} supply * @property {UnspentPattern3} outputs * @property {CoindaysCoinyearsDormancySentVelocityPattern} activity - * @property {MetricsTree_Distribution_UtxoCohorts_Lth_Realized} realized + * @property {MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized} realized * @property {InvestedMaxMinPercentilesSupplyPattern} costBasis * @property {GrossInvestedInvestorLossNetProfitSentimentPattern2} unrealized */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Lth_Realized + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized * @property {CumulativeDistributionRawRelSumValuePattern} profit * @property {CapitulationCumulativeNegativeRawRelSumValuePattern} loss * @property {RawSellSumPattern} grossPnl * @property {ChangeCumulativeDeltaRawRelSumPattern} netPnl - * @property {MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr} sopr + * @property {MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr} sopr * @property {CumulativeRawRelPattern} peakRegret * @property {CapLowerPriceUpperPattern} investor * @property {_1m1w1y24hPattern} profitToLossRatio @@ -5821,26 +5968,26 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr - * @property {MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueCreated} valueCreated - * @property {MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueDestroyed} valueDestroyed + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr + * @property {MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueCreated} valueCreated + * @property {MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueDestroyed} valueDestroyed * @property {_1m1w1y24hPattern} ratio */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueCreated + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueCreated * @property {_1m1w1y24hPattern} sum * @property {MetricPattern1} raw */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueDestroyed + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueDestroyed * @property {_1m1w1y24hPattern} sum * @property {MetricPattern1} raw */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_AgeRange + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_AgeRange * @property {ActivityOutputsRealizedSupplyUnrealizedPattern} upTo1h * @property {ActivityOutputsRealizedSupplyUnrealizedPattern} _1hTo1d * @property {ActivityOutputsRealizedSupplyUnrealizedPattern} _1dTo1w @@ -5865,7 +6012,7 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_MaxAge + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_MaxAge * @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _1w * @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _1m * @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _2m @@ -5887,7 +6034,7 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_MinAge + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_MinAge * @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _1d * @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _1w * @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _1m @@ -5909,7 +6056,7 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Epoch + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_Epoch * @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _0 * @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _1 * @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _2 @@ -5918,7 +6065,7 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Class + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_Class * @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _2009 * @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _2010 * @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _2011 @@ -5940,7 +6087,7 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_GeAmount + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_GeAmount * @property {OutputsRealizedSupplyPattern} _1sat * @property {OutputsRealizedSupplyPattern} _10sats * @property {OutputsRealizedSupplyPattern} _100sats @@ -5957,7 +6104,7 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_AmountRange + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_AmountRange * @property {OutputsRealizedSupplyPattern} _0sats * @property {OutputsRealizedSupplyPattern} _1satTo10sats * @property {OutputsRealizedSupplyPattern} _10satsTo100sats @@ -5976,7 +6123,7 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_LtAmount + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_LtAmount * @property {OutputsRealizedSupplyPattern} _10sats * @property {OutputsRealizedSupplyPattern} _100sats * @property {OutputsRealizedSupplyPattern} _1kSats @@ -5993,7 +6140,7 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Type + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_Type * @property {OutputsRealizedSupplyUnrealizedPattern} p2pk65 * @property {OutputsRealizedSupplyUnrealizedPattern} p2pk33 * @property {OutputsRealizedSupplyUnrealizedPattern} p2pkh @@ -6008,14 +6155,14 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Profitability - * @property {MetricsTree_Distribution_UtxoCohorts_Profitability_Range} range - * @property {MetricsTree_Distribution_UtxoCohorts_Profitability_Profit} profit - * @property {MetricsTree_Distribution_UtxoCohorts_Profitability_Loss} loss + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_Profitability + * @property {MetricsTree_Distribution_Cohorts_Utxo_Profitability_Range} range + * @property {MetricsTree_Distribution_Cohorts_Utxo_Profitability_Profit} profit + * @property {MetricsTree_Distribution_Cohorts_Utxo_Profitability_Loss} loss */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Profitability_Range + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_Profitability_Range * @property {RealizedSupplyPattern} profitOver1000 * @property {RealizedSupplyPattern} profit500To1000 * @property {RealizedSupplyPattern} profit300To500 @@ -6044,7 +6191,7 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Profitability_Profit + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_Profitability_Profit * @property {RealizedSupplyPattern} breakeven * @property {RealizedSupplyPattern} _10pct * @property {RealizedSupplyPattern} _20pct @@ -6063,7 +6210,7 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Profitability_Loss + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_Profitability_Loss * @property {RealizedSupplyPattern} breakeven * @property {RealizedSupplyPattern} _10pct * @property {RealizedSupplyPattern} _20pct @@ -6077,7 +6224,7 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Matured + * @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_Matured * @property {BtcCentsSatsUsdPattern} upTo1h * @property {BtcCentsSatsUsdPattern} _1hTo1d * @property {BtcCentsSatsUsdPattern} _1dTo1w @@ -6102,14 +6249,14 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_AddressCohorts - * @property {MetricsTree_Distribution_AddressCohorts_GeAmount} geAmount - * @property {MetricsTree_Distribution_AddressCohorts_AmountRange} amountRange - * @property {MetricsTree_Distribution_AddressCohorts_LtAmount} ltAmount + * @typedef {Object} MetricsTree_Distribution_Cohorts_Address + * @property {MetricsTree_Distribution_Cohorts_Address_GeAmount} geAmount + * @property {MetricsTree_Distribution_Cohorts_Address_AmountRange} amountRange + * @property {MetricsTree_Distribution_Cohorts_Address_LtAmount} ltAmount */ /** - * @typedef {Object} MetricsTree_Distribution_AddressCohorts_GeAmount + * @typedef {Object} MetricsTree_Distribution_Cohorts_Address_GeAmount * @property {AddrOutputsRealizedSupplyPattern} _1sat * @property {AddrOutputsRealizedSupplyPattern} _10sats * @property {AddrOutputsRealizedSupplyPattern} _100sats @@ -6126,7 +6273,7 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_AddressCohorts_AmountRange + * @typedef {Object} MetricsTree_Distribution_Cohorts_Address_AmountRange * @property {AddrOutputsRealizedSupplyPattern} _0sats * @property {AddrOutputsRealizedSupplyPattern} _1satTo10sats * @property {AddrOutputsRealizedSupplyPattern} _10satsTo100sats @@ -6145,7 +6292,7 @@ function createRawPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_AddressCohorts_LtAmount + * @typedef {Object} MetricsTree_Distribution_Cohorts_Address_LtAmount * @property {AddrOutputsRealizedSupplyPattern} _10sats * @property {AddrOutputsRealizedSupplyPattern} _100sats * @property {AddrOutputsRealizedSupplyPattern} _1kSats @@ -6161,57 +6308,6 @@ function createRawPattern(client, acc) { * @property {AddrOutputsRealizedSupplyPattern} _100kBtc */ -/** - * @typedef {Object} MetricsTree_Distribution_Addresses - * @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3} funded - * @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3} empty - * @property {MetricsTree_Distribution_Addresses_Activity} activity - * @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3} total - * @property {MetricsTree_Distribution_Addresses_New} new - * @property {MetricsTree_Distribution_Addresses_Delta} delta - * @property {MetricPattern34} fundedIndex - * @property {MetricPattern35} emptyIndex - */ - -/** - * @typedef {Object} MetricsTree_Distribution_Addresses_Activity - * @property {BothReactivatedReceivingSendingPattern} all - * @property {BothReactivatedReceivingSendingPattern} p2pk65 - * @property {BothReactivatedReceivingSendingPattern} p2pk33 - * @property {BothReactivatedReceivingSendingPattern} p2pkh - * @property {BothReactivatedReceivingSendingPattern} p2sh - * @property {BothReactivatedReceivingSendingPattern} p2wpkh - * @property {BothReactivatedReceivingSendingPattern} p2wsh - * @property {BothReactivatedReceivingSendingPattern} p2tr - * @property {BothReactivatedReceivingSendingPattern} p2a - */ - -/** - * @typedef {Object} MetricsTree_Distribution_Addresses_New - * @property {RawSumPattern3} all - * @property {RawSumPattern3} p2pk65 - * @property {RawSumPattern3} p2pk33 - * @property {RawSumPattern3} p2pkh - * @property {RawSumPattern3} p2sh - * @property {RawSumPattern3} p2wpkh - * @property {RawSumPattern3} p2wsh - * @property {RawSumPattern3} p2tr - * @property {RawSumPattern3} p2a - */ - -/** - * @typedef {Object} MetricsTree_Distribution_Addresses_Delta - * @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 - */ - /** * @typedef {Object} MetricsTree_Supply * @property {BtcCentsSatsUsdPattern} circulating @@ -7195,8 +7291,8 @@ class BrkClient extends BrkClientBase { asHash: createMetricPattern1(this, 'difficulty_as_hash'), adjustment: createBpsPercentRatioPattern(this, 'difficulty_adjustment'), epoch: createMetricPattern1(this, 'difficulty_epoch'), - blocksBeforeNextAdjustment: createMetricPattern1(this, 'blocks_before_next_difficulty_adjustment'), - daysBeforeNextAdjustment: createMetricPattern1(this, 'days_before_next_difficulty_adjustment'), + blocksBeforeNext: createMetricPattern1(this, 'blocks_before_next_difficulty_adjustment'), + daysBeforeNext: createMetricPattern1(this, 'days_before_next_difficulty_adjustment'), }, time: { timestamp: createMetricPattern1(this, 'timestamp'), @@ -7281,8 +7377,8 @@ class BrkClient extends BrkClientBase { interval: create_1m1w1y24hHeightPattern(this, 'block_interval'), halving: { epoch: createMetricPattern1(this, 'halving_epoch'), - blocksBeforeNextHalving: createMetricPattern1(this, 'blocks_before_next_halving'), - daysBeforeNextHalving: createMetricPattern1(this, 'days_before_next_halving'), + blocksBeforeNext: createMetricPattern1(this, 'blocks_before_next_halving'), + daysBeforeNext: createMetricPattern1(this, 'days_before_next_halving'), }, vbytes: createAverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RawSumPattern(this, 'block_vbytes'), fullness: { @@ -7292,16 +7388,18 @@ class BrkClient extends BrkClientBase { }, }, transactions: { - firstTxindex: createMetricPattern18(this, 'first_txindex'), - height: createMetricPattern19(this, 'height'), - txid: createMetricPattern19(this, 'txid'), - txversion: createMetricPattern19(this, 'txversion'), - rawlocktime: createMetricPattern19(this, 'rawlocktime'), - baseSize: createMetricPattern19(this, 'base_size'), - totalSize: createMetricPattern19(this, 'total_size'), - isExplicitlyRbf: createMetricPattern19(this, 'is_explicitly_rbf'), - firstTxinindex: createMetricPattern19(this, 'first_txinindex'), - firstTxoutindex: createMetricPattern19(this, 'first_txoutindex'), + raw: { + firstTxindex: createMetricPattern18(this, 'first_txindex'), + height: createMetricPattern19(this, 'height'), + txid: createMetricPattern19(this, 'txid'), + txversion: createMetricPattern19(this, 'txversion'), + rawlocktime: createMetricPattern19(this, 'rawlocktime'), + baseSize: createMetricPattern19(this, 'base_size'), + totalSize: createMetricPattern19(this, 'total_size'), + isExplicitlyRbf: createMetricPattern19(this, 'is_explicitly_rbf'), + firstTxinindex: createMetricPattern19(this, 'first_txinindex'), + firstTxoutindex: createMetricPattern19(this, 'first_txoutindex'), + }, count: { total: createAverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RawSumPattern(this, 'tx_count'), isCoinbase: createMetricPattern19(this, 'is_coinbase'), @@ -7324,18 +7422,20 @@ class BrkClient extends BrkClientBase { volume: { sentSum: create_1m1w1y24hBtcCentsSatsUsdPattern(this, 'sent_sum'), receivedSum: create_1m1w1y24hBtcCentsSatsUsdPattern(this, 'received_sum'), - annualizedVolume: createBtcCentsSatsUsdPattern(this, 'annualized_volume'), + annualized: createBtcCentsSatsUsdPattern(this, 'annualized_volume'), txPerSec: createMetricPattern1(this, 'tx_per_sec'), outputsPerSec: createMetricPattern1(this, 'outputs_per_sec'), inputsPerSec: createMetricPattern1(this, 'inputs_per_sec'), }, }, inputs: { - firstTxinindex: createMetricPattern18(this, 'first_txinindex'), - outpoint: createMetricPattern20(this, 'outpoint'), - txindex: createMetricPattern20(this, 'txindex'), - outputtype: createMetricPattern20(this, 'outputtype'), - typeindex: createMetricPattern20(this, 'typeindex'), + raw: { + firstTxinindex: createMetricPattern18(this, 'first_txinindex'), + outpoint: createMetricPattern20(this, 'outpoint'), + txindex: createMetricPattern20(this, 'txindex'), + outputtype: createMetricPattern20(this, 'outputtype'), + typeindex: createMetricPattern20(this, 'typeindex'), + }, spent: { txoutindex: createMetricPattern20(this, 'txoutindex'), value: createMetricPattern20(this, 'value'), @@ -7343,46 +7443,76 @@ class BrkClient extends BrkClientBase { count: createAverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern(this, 'input_count'), }, outputs: { - firstTxoutindex: createMetricPattern18(this, 'first_txoutindex'), - value: createMetricPattern21(this, 'value'), - outputtype: createMetricPattern21(this, 'outputtype'), - typeindex: createMetricPattern21(this, 'typeindex'), - txindex: createMetricPattern21(this, 'txindex'), + raw: { + firstTxoutindex: createMetricPattern18(this, 'first_txoutindex'), + value: createMetricPattern21(this, 'value'), + outputtype: createMetricPattern21(this, 'outputtype'), + typeindex: createMetricPattern21(this, 'typeindex'), + txindex: createMetricPattern21(this, 'txindex'), + }, spent: { txinindex: createMetricPattern21(this, 'txinindex'), }, count: { total: createAverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern(this, 'output_count'), - utxoCount: createMetricPattern1(this, 'exact_utxo_count'), + unspent: createMetricPattern1(this, 'exact_utxo_count'), }, }, addresses: { - firstP2pk65addressindex: createMetricPattern18(this, 'first_p2pk65addressindex'), - firstP2pk33addressindex: createMetricPattern18(this, 'first_p2pk33addressindex'), - firstP2pkhaddressindex: createMetricPattern18(this, 'first_p2pkhaddressindex'), - firstP2shaddressindex: createMetricPattern18(this, 'first_p2shaddressindex'), - firstP2wpkhaddressindex: createMetricPattern18(this, 'first_p2wpkhaddressindex'), - firstP2wshaddressindex: createMetricPattern18(this, 'first_p2wshaddressindex'), - firstP2traddressindex: createMetricPattern18(this, 'first_p2traddressindex'), - firstP2aaddressindex: createMetricPattern18(this, 'first_p2aaddressindex'), - p2pk65bytes: createMetricPattern27(this, 'p2pk65bytes'), - p2pk33bytes: createMetricPattern26(this, 'p2pk33bytes'), - p2pkhbytes: createMetricPattern28(this, 'p2pkhbytes'), - p2shbytes: createMetricPattern29(this, 'p2shbytes'), - p2wpkhbytes: createMetricPattern31(this, 'p2wpkhbytes'), - p2wshbytes: createMetricPattern32(this, 'p2wshbytes'), - p2trbytes: createMetricPattern30(this, 'p2trbytes'), - p2abytes: createMetricPattern24(this, 'p2abytes'), + raw: { + p2pk65: { + firstIndex: createMetricPattern18(this, 'first_p2pk65addressindex'), + bytes: createMetricPattern27(this, 'p2pk65bytes'), + }, + p2pk33: { + firstIndex: createMetricPattern18(this, 'first_p2pk33addressindex'), + bytes: createMetricPattern26(this, 'p2pk33bytes'), + }, + p2pkh: { + firstIndex: createMetricPattern18(this, 'first_p2pkhaddressindex'), + bytes: createMetricPattern28(this, 'p2pkhbytes'), + }, + p2sh: { + firstIndex: createMetricPattern18(this, 'first_p2shaddressindex'), + bytes: createMetricPattern29(this, 'p2shbytes'), + }, + p2wpkh: { + firstIndex: createMetricPattern18(this, 'first_p2wpkhaddressindex'), + bytes: createMetricPattern31(this, 'p2wpkhbytes'), + }, + p2wsh: { + firstIndex: createMetricPattern18(this, 'first_p2wshaddressindex'), + bytes: createMetricPattern32(this, 'p2wshbytes'), + }, + p2tr: { + firstIndex: createMetricPattern18(this, 'first_p2traddressindex'), + bytes: createMetricPattern30(this, 'p2trbytes'), + }, + p2a: { + firstIndex: createMetricPattern18(this, 'first_p2aaddressindex'), + bytes: createMetricPattern24(this, 'p2abytes'), + }, + }, }, scripts: { - firstEmptyoutputindex: createMetricPattern18(this, 'first_emptyoutputindex'), - firstOpreturnindex: createMetricPattern18(this, 'first_opreturnindex'), - firstP2msoutputindex: createMetricPattern18(this, 'first_p2msoutputindex'), - firstUnknownoutputindex: createMetricPattern18(this, 'first_unknownoutputindex'), - emptyToTxindex: createMetricPattern22(this, 'txindex'), - opreturnToTxindex: createMetricPattern23(this, 'txindex'), - p2msToTxindex: createMetricPattern25(this, 'txindex'), - unknownToTxindex: createMetricPattern33(this, 'txindex'), + raw: { + empty: { + firstIndex: createMetricPattern18(this, 'first_emptyoutputindex'), + toTxindex: createMetricPattern22(this, 'txindex'), + }, + opreturn: { + firstIndex: createMetricPattern18(this, 'first_opreturnindex'), + toTxindex: createMetricPattern23(this, 'txindex'), + }, + p2ms: { + firstIndex: createMetricPattern18(this, 'first_p2msoutputindex'), + toTxindex: createMetricPattern25(this, 'txindex'), + }, + unknown: { + firstIndex: createMetricPattern18(this, 'first_unknownoutputindex'), + toTxindex: createMetricPattern33(this, 'txindex'), + }, + }, count: { p2a: createCumulativeRawSumPattern(this, 'p2a_count'), p2ms: createCumulativeRawSumPattern(this, 'p2ms_count'), @@ -7399,7 +7529,10 @@ class BrkClient extends BrkClientBase { segwit: createCumulativeRawSumPattern(this, 'segwit_count'), }, value: { - opreturn: createBaseCumulativePattern(this, 'opreturn_value'), + opreturn: { + base: createBtcCentsSatsUsdPattern(this, 'opreturn_value'), + cumulative: createBtcCentsSatsUsdPattern(this, 'opreturn_value_cumulative'), + }, }, adoption: { taproot: createBpsPercentRatioPattern(this, 'taproot_adoption'), @@ -7409,7 +7542,12 @@ class BrkClient extends BrkClientBase { mining: { rewards: { coinbase: createBaseCumulativeSumPattern(this, 'coinbase'), - subsidy: createBaseCumulativePattern(this, 'subsidy'), + subsidy: { + base: createBtcCentsSatsUsdPattern(this, 'subsidy'), + cumulative: createBtcCentsSatsUsdPattern(this, 'subsidy_cumulative'), + dominance: create_1m1w1y24hBpsPercentRatioPattern(this, 'subsidy_dominance'), + sma1y: createCentsUsdPattern(this, 'subsidy_sma_1y'), + }, fees: { base: createBtcCentsSatsUsdPattern(this, 'fees'), cumulative: createBtcCentsSatsUsdPattern(this, 'fees_cumulative'), @@ -7417,17 +7555,15 @@ class BrkClient extends BrkClientBase { _1w: createAverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2(this, 'fees_1w'), _1m: createAverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2(this, 'fees_1m'), _1y: createAverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2(this, 'fees_1y'), + dominance: create_1m1w1y24hBpsPercentRatioPattern(this, 'fee_dominance'), + ratioMultiple: { + _24h: createBpsRatioPattern(this, 'fee_ratio_multiple_24h'), + _1w: createBpsRatioPattern(this, 'fee_ratio_multiple_1w'), + _1m: createBpsRatioPattern(this, 'fee_ratio_multiple_1m'), + _1y: createBpsRatioPattern(this, 'fee_ratio_multiple_1y'), + }, }, - unclaimedRewards: createBaseCumulativeSumPattern(this, 'unclaimed_rewards'), - feeDominance: create_1m1w1y24hBpsPercentRatioPattern(this, 'fee_dominance'), - subsidyDominance: create_1m1w1y24hBpsPercentRatioPattern(this, 'subsidy_dominance'), - subsidySma1y: createCentsUsdPattern(this, 'subsidy_sma_1y'), - feeRatioMultiple: { - _24h: createBpsRatioPattern(this, 'fee_ratio_multiple_24h'), - _1w: createBpsRatioPattern(this, 'fee_ratio_multiple_1w'), - _1m: createBpsRatioPattern(this, 'fee_ratio_multiple_1m'), - _1y: createBpsRatioPattern(this, 'fee_ratio_multiple_1y'), - }, + unclaimed: createBaseCumulativeSumPattern(this, 'unclaimed_rewards'), }, hashrate: { rate: { @@ -7673,7 +7809,7 @@ class BrkClient extends BrkClientBase { }, market: { ath: { - price: createCentsSatsUsdPattern(this, 'price_ath'), + high: createCentsSatsUsdPattern(this, 'price_ath'), drawdown: createBpsPercentRatioPattern(this, 'price_drawdown'), daysSince: createMetricPattern1(this, 'days_since_price_ath'), yearsSince: createMetricPattern2(this, 'years_since_price_ath'), @@ -8111,7 +8247,7 @@ class BrkClient extends BrkClientBase { usd: createMetricPattern2(this, 'price_ohlc'), sats: createMetricPattern2(this, 'price_ohlc_sats'), }, - price: { + spot: { cents: createMetricPattern1(this, 'price_cents'), usd: createMetricPattern1(this, 'price'), sats: createMetricPattern1(this, 'price_sats'), @@ -8119,380 +8255,23 @@ class BrkClient extends BrkClientBase { }, distribution: { supplyState: createMetricPattern18(this, 'supply_state'), - anyAddressIndexes: { - p2a: createMetricPattern24(this, 'anyaddressindex'), - p2pk33: createMetricPattern26(this, 'anyaddressindex'), - p2pk65: createMetricPattern27(this, 'anyaddressindex'), - p2pkh: createMetricPattern28(this, 'anyaddressindex'), - p2sh: createMetricPattern29(this, 'anyaddressindex'), - p2tr: createMetricPattern30(this, 'anyaddressindex'), - p2wpkh: createMetricPattern31(this, 'anyaddressindex'), - p2wsh: createMetricPattern32(this, 'anyaddressindex'), - }, - addressesData: { - funded: createMetricPattern34(this, 'fundedaddressdata'), - empty: createMetricPattern35(this, 'emptyaddressdata'), - }, - utxoCohorts: { - all: { - supply: { - delta: createChangeRatePattern2(this, 'supply_delta'), - inProfit: createBtcCentsRelSatsUsdPattern2(this, 'supply_in_profit'), - inLoss: createBtcCentsRelSatsUsdPattern2(this, 'supply_in_loss'), - total: createBtcCentsSatsUsdPattern(this, 'supply'), - halved: createBtcCentsSatsUsdPattern(this, 'supply_halved'), - }, - outputs: createUnspentPattern3(this, 'utxo_count'), - activity: createCoindaysCoinyearsDormancySentVelocityPattern(this, ''), - realized: createCapGrossInvestorLossMvrvNetNuplPeakPriceProfitSoprPattern(this, ''), - costBasis: createInvestedMaxMinPercentilesSupplyPattern(this, ''), - unrealized: { - grossPnl: createCentsUsdPattern(this, 'unrealized_gross_pnl'), - investedCapital: createInPattern2(this, 'invested_capital_in'), - sentiment: createGreedNetPainPattern(this, ''), - investorCap: createInPattern(this, 'investor_cap_in'), - loss: { - negative: createMetricPattern1(this, 'neg_unrealized_loss'), - raw: createCentsUsdPattern(this, 'unrealized_loss'), - sum: create_24hPattern(this, 'unrealized_loss_24h'), - relToMarketCap: createBpsPercentRatioPattern(this, 'unrealized_loss_rel_to_market_cap'), - relToOwnGrossPnl: createBpsPercentRatioPattern(this, 'unrealized_loss_rel_to_own_gross_pnl'), - }, - netPnl: { - cents: createMetricPattern1(this, 'net_unrealized_pnl_cents'), - usd: createMetricPattern1(this, 'net_unrealized_pnl'), - relToOwnGrossPnl: createBpsPercentRatioPattern(this, 'net_unrealized_pnl_rel_to_own_gross_pnl'), - }, - profit: { - raw: createCentsUsdPattern(this, 'unrealized_profit'), - sum: create_24hPattern(this, 'unrealized_profit_24h'), - relToMarketCap: createBpsPercentRatioPattern(this, 'unrealized_profit_rel_to_market_cap'), - relToOwnGrossPnl: createBpsPercentRatioPattern(this, 'unrealized_profit_rel_to_own_gross_pnl'), - }, - }, - }, - sth: { - realized: createCapGrossInvestorLossMvrvNetNuplPeakPriceProfitSoprPattern(this, 'sth'), - supply: createDeltaHalvedInRelTotalPattern2(this, 'sth_supply'), - outputs: createUnspentPattern3(this, 'sth_utxo_count'), - activity: createCoindaysCoinyearsDormancySentVelocityPattern(this, 'sth'), - costBasis: createInvestedMaxMinPercentilesSupplyPattern(this, 'sth'), - unrealized: createGrossInvestedInvestorLossNetProfitSentimentPattern2(this, 'sth'), - }, - lth: { - supply: createDeltaHalvedInRelTotalPattern2(this, 'lth_supply'), - outputs: createUnspentPattern3(this, 'lth_utxo_count'), - activity: createCoindaysCoinyearsDormancySentVelocityPattern(this, 'lth'), - realized: { - profit: createCumulativeDistributionRawRelSumValuePattern(this, 'lth'), - loss: createCapitulationCumulativeNegativeRawRelSumValuePattern(this, 'lth'), - grossPnl: createRawSellSumPattern(this, 'lth'), - netPnl: createChangeCumulativeDeltaRawRelSumPattern(this, 'lth_net'), - sopr: { - valueCreated: { - sum: create_1m1w1y24hPattern(this, 'lth_value_created'), - raw: createMetricPattern1(this, 'lth_value_created'), - }, - valueDestroyed: { - sum: create_1m1w1y24hPattern(this, 'lth_value_destroyed'), - raw: createMetricPattern1(this, 'lth_value_destroyed'), - }, - ratio: create_1m1w1y24hPattern(this, 'lth_sopr'), - }, - peakRegret: createCumulativeRawRelPattern(this, 'lth_realized_peak_regret'), - investor: createCapLowerPriceUpperPattern(this, 'lth'), - profitToLossRatio: create_1m1w1y24hPattern(this, 'lth_realized_profit_to_loss_ratio'), - cap: createCentsDeltaRawRelUsdPattern(this, 'lth'), - price: createBpsCentsPercentilesRatioSatsSmaStdUsdPattern(this, 'lth_realized_price'), - mvrv: createMetricPattern1(this, 'lth_mvrv'), - nupl: createBpsRatioPattern(this, 'lth_nupl_ratio'), - }, - costBasis: createInvestedMaxMinPercentilesSupplyPattern(this, 'lth'), - unrealized: createGrossInvestedInvestorLossNetProfitSentimentPattern2(this, 'lth'), - }, - ageRange: { - upTo1h: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_under_1h_old'), - _1hTo1d: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_1h_to_1d_old'), - _1dTo1w: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_1d_to_1w_old'), - _1wTo1m: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_1w_to_1m_old'), - _1mTo2m: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_1m_to_2m_old'), - _2mTo3m: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_2m_to_3m_old'), - _3mTo4m: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_3m_to_4m_old'), - _4mTo5m: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_4m_to_5m_old'), - _5mTo6m: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_5m_to_6m_old'), - _6mTo1y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_6m_to_1y_old'), - _1yTo2y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_1y_to_2y_old'), - _2yTo3y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_2y_to_3y_old'), - _3yTo4y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_3y_to_4y_old'), - _4yTo5y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_4y_to_5y_old'), - _5yTo6y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_5y_to_6y_old'), - _6yTo7y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_6y_to_7y_old'), - _7yTo8y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_7y_to_8y_old'), - _8yTo10y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_8y_to_10y_old'), - _10yTo12y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_10y_to_12y_old'), - _12yTo15y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_12y_to_15y_old'), - from15y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_over_15y_old'), - }, - maxAge: { - _1w: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_1w_old'), - _1m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_1m_old'), - _2m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_2m_old'), - _3m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_3m_old'), - _4m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_4m_old'), - _5m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_5m_old'), - _6m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_6m_old'), - _1y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_1y_old'), - _2y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_2y_old'), - _3y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_3y_old'), - _4y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_4y_old'), - _5y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_5y_old'), - _6y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_6y_old'), - _7y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_7y_old'), - _8y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_8y_old'), - _10y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_10y_old'), - _12y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_12y_old'), - _15y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_15y_old'), - }, - minAge: { - _1d: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_1d_old'), - _1w: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_1w_old'), - _1m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_1m_old'), - _2m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_2m_old'), - _3m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_3m_old'), - _4m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_4m_old'), - _5m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_5m_old'), - _6m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_6m_old'), - _1y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_1y_old'), - _2y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_2y_old'), - _3y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_3y_old'), - _4y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_4y_old'), - _5y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_5y_old'), - _6y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_6y_old'), - _7y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_7y_old'), - _8y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_8y_old'), - _10y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_10y_old'), - _12y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_12y_old'), - }, - epoch: { - _0: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'epoch_0'), - _1: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'epoch_1'), - _2: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'epoch_2'), - _3: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'epoch_3'), - _4: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'epoch_4'), - }, - class: { - _2009: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2009'), - _2010: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2010'), - _2011: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2011'), - _2012: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2012'), - _2013: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2013'), - _2014: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2014'), - _2015: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2015'), - _2016: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2016'), - _2017: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2017'), - _2018: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2018'), - _2019: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2019'), - _2020: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2020'), - _2021: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2021'), - _2022: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2022'), - _2023: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2023'), - _2024: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2024'), - _2025: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2025'), - _2026: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2026'), - }, - geAmount: { - _1sat: createOutputsRealizedSupplyPattern(this, 'utxos_over_1sat'), - _10sats: createOutputsRealizedSupplyPattern(this, 'utxos_over_10sats'), - _100sats: createOutputsRealizedSupplyPattern(this, 'utxos_over_100sats'), - _1kSats: createOutputsRealizedSupplyPattern(this, 'utxos_over_1k_sats'), - _10kSats: createOutputsRealizedSupplyPattern(this, 'utxos_over_10k_sats'), - _100kSats: createOutputsRealizedSupplyPattern(this, 'utxos_over_100k_sats'), - _1mSats: createOutputsRealizedSupplyPattern(this, 'utxos_over_1m_sats'), - _10mSats: createOutputsRealizedSupplyPattern(this, 'utxos_over_10m_sats'), - _1btc: createOutputsRealizedSupplyPattern(this, 'utxos_over_1btc'), - _10btc: createOutputsRealizedSupplyPattern(this, 'utxos_over_10btc'), - _100btc: createOutputsRealizedSupplyPattern(this, 'utxos_over_100btc'), - _1kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_over_1k_btc'), - _10kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_over_10k_btc'), - }, - amountRange: { - _0sats: createOutputsRealizedSupplyPattern(this, 'utxos_with_0sats'), - _1satTo10sats: createOutputsRealizedSupplyPattern(this, 'utxos_above_1sat_under_10sats'), - _10satsTo100sats: createOutputsRealizedSupplyPattern(this, 'utxos_above_10sats_under_100sats'), - _100satsTo1kSats: createOutputsRealizedSupplyPattern(this, 'utxos_above_100sats_under_1k_sats'), - _1kSatsTo10kSats: createOutputsRealizedSupplyPattern(this, 'utxos_above_1k_sats_under_10k_sats'), - _10kSatsTo100kSats: createOutputsRealizedSupplyPattern(this, 'utxos_above_10k_sats_under_100k_sats'), - _100kSatsTo1mSats: createOutputsRealizedSupplyPattern(this, 'utxos_above_100k_sats_under_1m_sats'), - _1mSatsTo10mSats: createOutputsRealizedSupplyPattern(this, 'utxos_above_1m_sats_under_10m_sats'), - _10mSatsTo1btc: createOutputsRealizedSupplyPattern(this, 'utxos_above_10m_sats_under_1btc'), - _1btcTo10btc: createOutputsRealizedSupplyPattern(this, 'utxos_above_1btc_under_10btc'), - _10btcTo100btc: createOutputsRealizedSupplyPattern(this, 'utxos_above_10btc_under_100btc'), - _100btcTo1kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_above_100btc_under_1k_btc'), - _1kBtcTo10kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_above_1k_btc_under_10k_btc'), - _10kBtcTo100kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_above_10k_btc_under_100k_btc'), - _100kBtcOrMore: createOutputsRealizedSupplyPattern(this, 'utxos_above_100k_btc'), - }, - ltAmount: { - _10sats: createOutputsRealizedSupplyPattern(this, 'utxos_under_10sats'), - _100sats: createOutputsRealizedSupplyPattern(this, 'utxos_under_100sats'), - _1kSats: createOutputsRealizedSupplyPattern(this, 'utxos_under_1k_sats'), - _10kSats: createOutputsRealizedSupplyPattern(this, 'utxos_under_10k_sats'), - _100kSats: createOutputsRealizedSupplyPattern(this, 'utxos_under_100k_sats'), - _1mSats: createOutputsRealizedSupplyPattern(this, 'utxos_under_1m_sats'), - _10mSats: createOutputsRealizedSupplyPattern(this, 'utxos_under_10m_sats'), - _1btc: createOutputsRealizedSupplyPattern(this, 'utxos_under_1btc'), - _10btc: createOutputsRealizedSupplyPattern(this, 'utxos_under_10btc'), - _100btc: createOutputsRealizedSupplyPattern(this, 'utxos_under_100btc'), - _1kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_under_1k_btc'), - _10kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_under_10k_btc'), - _100kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_under_100k_btc'), - }, - type: { - p2pk65: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2pk65'), - p2pk33: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2pk33'), - p2pkh: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2pkh'), - p2ms: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2ms'), - p2sh: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2sh'), - p2wpkh: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2wpkh'), - p2wsh: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2wsh'), - p2tr: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2tr'), - p2a: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2a'), - unknown: createOutputsRealizedSupplyUnrealizedPattern(this, 'unknown_outputs'), - empty: createOutputsRealizedSupplyUnrealizedPattern(this, 'empty_outputs'), - }, - profitability: { - range: { - profitOver1000: createRealizedSupplyPattern(this, 'profit_over_1000pct'), - profit500To1000: createRealizedSupplyPattern(this, 'profit_500_to_1000pct'), - profit300To500: createRealizedSupplyPattern(this, 'profit_300_to_500pct'), - profit200To300: createRealizedSupplyPattern(this, 'profit_200_to_300pct'), - profit100To200: createRealizedSupplyPattern(this, 'profit_100_to_200pct'), - profit90To100: createRealizedSupplyPattern(this, 'profit_90_to_100pct'), - profit80To90: createRealizedSupplyPattern(this, 'profit_80_to_90pct'), - profit70To80: createRealizedSupplyPattern(this, 'profit_70_to_80pct'), - profit60To70: createRealizedSupplyPattern(this, 'profit_60_to_70pct'), - profit50To60: createRealizedSupplyPattern(this, 'profit_50_to_60pct'), - profit40To50: createRealizedSupplyPattern(this, 'profit_40_to_50pct'), - profit30To40: createRealizedSupplyPattern(this, 'profit_30_to_40pct'), - profit20To30: createRealizedSupplyPattern(this, 'profit_20_to_30pct'), - profit10To20: createRealizedSupplyPattern(this, 'profit_10_to_20pct'), - profit0To10: createRealizedSupplyPattern(this, 'profit_0_to_10pct'), - loss0To10: createRealizedSupplyPattern(this, 'loss_0_to_10pct'), - loss10To20: createRealizedSupplyPattern(this, 'loss_10_to_20pct'), - loss20To30: createRealizedSupplyPattern(this, 'loss_20_to_30pct'), - loss30To40: createRealizedSupplyPattern(this, 'loss_30_to_40pct'), - loss40To50: createRealizedSupplyPattern(this, 'loss_40_to_50pct'), - loss50To60: createRealizedSupplyPattern(this, 'loss_50_to_60pct'), - loss60To70: createRealizedSupplyPattern(this, 'loss_60_to_70pct'), - loss70To80: createRealizedSupplyPattern(this, 'loss_70_to_80pct'), - loss80To90: createRealizedSupplyPattern(this, 'loss_80_to_90pct'), - loss90To100: createRealizedSupplyPattern(this, 'loss_90_to_100pct'), - }, - profit: { - breakeven: createRealizedSupplyPattern(this, 'profit_ge_breakeven'), - _10pct: createRealizedSupplyPattern(this, 'profit_ge_10pct'), - _20pct: createRealizedSupplyPattern(this, 'profit_ge_20pct'), - _30pct: createRealizedSupplyPattern(this, 'profit_ge_30pct'), - _40pct: createRealizedSupplyPattern(this, 'profit_ge_40pct'), - _50pct: createRealizedSupplyPattern(this, 'profit_ge_50pct'), - _60pct: createRealizedSupplyPattern(this, 'profit_ge_60pct'), - _70pct: createRealizedSupplyPattern(this, 'profit_ge_70pct'), - _80pct: createRealizedSupplyPattern(this, 'profit_ge_80pct'), - _90pct: createRealizedSupplyPattern(this, 'profit_ge_90pct'), - _100pct: createRealizedSupplyPattern(this, 'profit_ge_100pct'), - _200pct: createRealizedSupplyPattern(this, 'profit_ge_200pct'), - _300pct: createRealizedSupplyPattern(this, 'profit_ge_300pct'), - _500pct: createRealizedSupplyPattern(this, 'profit_ge_500pct'), - _1000pct: createRealizedSupplyPattern(this, 'profit_ge_1000pct'), - }, - loss: { - breakeven: createRealizedSupplyPattern(this, 'loss_ge_breakeven'), - _10pct: createRealizedSupplyPattern(this, 'loss_ge_10pct'), - _20pct: createRealizedSupplyPattern(this, 'loss_ge_20pct'), - _30pct: createRealizedSupplyPattern(this, 'loss_ge_30pct'), - _40pct: createRealizedSupplyPattern(this, 'loss_ge_40pct'), - _50pct: createRealizedSupplyPattern(this, 'loss_ge_50pct'), - _60pct: createRealizedSupplyPattern(this, 'loss_ge_60pct'), - _70pct: createRealizedSupplyPattern(this, 'loss_ge_70pct'), - _80pct: createRealizedSupplyPattern(this, 'loss_ge_80pct'), - _90pct: createRealizedSupplyPattern(this, 'loss_ge_90pct'), - }, - }, - matured: { - upTo1h: createBtcCentsSatsUsdPattern(this, 'utxo_under_1h_old_matured'), - _1hTo1d: createBtcCentsSatsUsdPattern(this, 'utxo_1h_to_1d_old_matured'), - _1dTo1w: createBtcCentsSatsUsdPattern(this, 'utxo_1d_to_1w_old_matured'), - _1wTo1m: createBtcCentsSatsUsdPattern(this, 'utxo_1w_to_1m_old_matured'), - _1mTo2m: createBtcCentsSatsUsdPattern(this, 'utxo_1m_to_2m_old_matured'), - _2mTo3m: createBtcCentsSatsUsdPattern(this, 'utxo_2m_to_3m_old_matured'), - _3mTo4m: createBtcCentsSatsUsdPattern(this, 'utxo_3m_to_4m_old_matured'), - _4mTo5m: createBtcCentsSatsUsdPattern(this, 'utxo_4m_to_5m_old_matured'), - _5mTo6m: createBtcCentsSatsUsdPattern(this, 'utxo_5m_to_6m_old_matured'), - _6mTo1y: createBtcCentsSatsUsdPattern(this, 'utxo_6m_to_1y_old_matured'), - _1yTo2y: createBtcCentsSatsUsdPattern(this, 'utxo_1y_to_2y_old_matured'), - _2yTo3y: createBtcCentsSatsUsdPattern(this, 'utxo_2y_to_3y_old_matured'), - _3yTo4y: createBtcCentsSatsUsdPattern(this, 'utxo_3y_to_4y_old_matured'), - _4yTo5y: createBtcCentsSatsUsdPattern(this, 'utxo_4y_to_5y_old_matured'), - _5yTo6y: createBtcCentsSatsUsdPattern(this, 'utxo_5y_to_6y_old_matured'), - _6yTo7y: createBtcCentsSatsUsdPattern(this, 'utxo_6y_to_7y_old_matured'), - _7yTo8y: createBtcCentsSatsUsdPattern(this, 'utxo_7y_to_8y_old_matured'), - _8yTo10y: createBtcCentsSatsUsdPattern(this, 'utxo_8y_to_10y_old_matured'), - _10yTo12y: createBtcCentsSatsUsdPattern(this, 'utxo_10y_to_12y_old_matured'), - _12yTo15y: createBtcCentsSatsUsdPattern(this, 'utxo_12y_to_15y_old_matured'), - from15y: createBtcCentsSatsUsdPattern(this, 'utxo_over_15y_old_matured'), - }, - }, - addressCohorts: { - geAmount: { - _1sat: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_1sat'), - _10sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_10sats'), - _100sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_100sats'), - _1kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_1k_sats'), - _10kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_10k_sats'), - _100kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_100k_sats'), - _1mSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_1m_sats'), - _10mSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_10m_sats'), - _1btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_1btc'), - _10btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_10btc'), - _100btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_100btc'), - _1kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_1k_btc'), - _10kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_10k_btc'), - }, - amountRange: { - _0sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_with_0sats'), - _1satTo10sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_1sat_under_10sats'), - _10satsTo100sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_10sats_under_100sats'), - _100satsTo1kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_100sats_under_1k_sats'), - _1kSatsTo10kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_1k_sats_under_10k_sats'), - _10kSatsTo100kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_10k_sats_under_100k_sats'), - _100kSatsTo1mSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_100k_sats_under_1m_sats'), - _1mSatsTo10mSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_1m_sats_under_10m_sats'), - _10mSatsTo1btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_10m_sats_under_1btc'), - _1btcTo10btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_1btc_under_10btc'), - _10btcTo100btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_10btc_under_100btc'), - _100btcTo1kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_100btc_under_1k_btc'), - _1kBtcTo10kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_1k_btc_under_10k_btc'), - _10kBtcTo100kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_10k_btc_under_100k_btc'), - _100kBtcOrMore: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_100k_btc'), - }, - ltAmount: { - _10sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_10sats'), - _100sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_100sats'), - _1kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_1k_sats'), - _10kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_10k_sats'), - _100kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_100k_sats'), - _1mSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_1m_sats'), - _10mSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_10m_sats'), - _1btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_1btc'), - _10btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_10btc'), - _100btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_100btc'), - _1kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_1k_btc'), - _10kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_10k_btc'), - _100kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_100k_btc'), - }, - }, - coinblocksDestroyed: createCumulativeRawPattern(this, 'coinblocks_destroyed'), addresses: { + indexes: { + p2a: createMetricPattern24(this, 'anyaddressindex'), + p2pk33: createMetricPattern26(this, 'anyaddressindex'), + p2pk65: createMetricPattern27(this, 'anyaddressindex'), + p2pkh: createMetricPattern28(this, 'anyaddressindex'), + p2sh: createMetricPattern29(this, 'anyaddressindex'), + p2tr: createMetricPattern30(this, 'anyaddressindex'), + p2wpkh: createMetricPattern31(this, 'anyaddressindex'), + p2wsh: createMetricPattern32(this, 'anyaddressindex'), + funded: createMetricPattern34(this, 'funded_address_index'), + empty: createMetricPattern35(this, 'empty_address_index'), + }, + data: { + funded: createMetricPattern34(this, 'fundedaddressdata'), + empty: createMetricPattern35(this, 'emptyaddressdata'), + }, funded: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(this, 'addr_count'), empty: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(this, 'empty_addr_count'), activity: { @@ -8508,30 +8287,389 @@ class BrkClient extends BrkClientBase { }, total: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(this, 'total_addr_count'), new: { - all: createRawSumPattern3(this, 'new_addr_count'), - p2pk65: createRawSumPattern3(this, 'p2pk65_new_addr_count'), - p2pk33: createRawSumPattern3(this, 'p2pk33_new_addr_count'), - p2pkh: createRawSumPattern3(this, 'p2pkh_new_addr_count'), - p2sh: createRawSumPattern3(this, 'p2sh_new_addr_count'), - p2wpkh: createRawSumPattern3(this, 'p2wpkh_new_addr_count'), - p2wsh: createRawSumPattern3(this, 'p2wsh_new_addr_count'), - p2tr: createRawSumPattern3(this, 'p2tr_new_addr_count'), - p2a: createRawSumPattern3(this, 'p2a_new_addr_count'), + all: createRawSumPattern(this, 'new_addr_count'), + p2pk65: createRawSumPattern(this, 'p2pk65_new_addr_count'), + p2pk33: createRawSumPattern(this, 'p2pk33_new_addr_count'), + p2pkh: createRawSumPattern(this, 'p2pkh_new_addr_count'), + p2sh: createRawSumPattern(this, 'p2sh_new_addr_count'), + p2wpkh: createRawSumPattern(this, 'p2wpkh_new_addr_count'), + p2wsh: createRawSumPattern(this, 'p2wsh_new_addr_count'), + p2tr: createRawSumPattern(this, 'p2tr_new_addr_count'), + p2a: createRawSumPattern(this, 'p2a_new_addr_count'), }, delta: { - 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'), + 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'), }, - fundedIndex: createMetricPattern34(this, 'funded_address_index'), - emptyIndex: createMetricPattern35(this, 'empty_address_index'), }, + cohorts: { + utxo: { + all: { + supply: { + delta: createChangeRatePattern(this, 'supply_delta'), + inProfit: createBtcCentsRelSatsUsdPattern2(this, 'supply_in_profit'), + inLoss: createBtcCentsRelSatsUsdPattern2(this, 'supply_in_loss'), + total: createBtcCentsSatsUsdPattern(this, 'supply'), + halved: createBtcCentsSatsUsdPattern(this, 'supply_halved'), + }, + outputs: createUnspentPattern3(this, 'utxo_count'), + activity: createCoindaysCoinyearsDormancySentVelocityPattern(this, ''), + realized: createCapGrossInvestorLossMvrvNetNuplPeakPriceProfitSoprPattern(this, ''), + costBasis: createInvestedMaxMinPercentilesSupplyPattern(this, ''), + unrealized: { + grossPnl: createCentsUsdPattern(this, 'unrealized_gross_pnl'), + investedCapital: createInPattern2(this, 'invested_capital_in'), + sentiment: createGreedNetPainPattern(this, ''), + investorCap: createInPattern(this, 'investor_cap_in'), + loss: { + negative: createMetricPattern1(this, 'neg_unrealized_loss'), + raw: createCentsUsdPattern(this, 'unrealized_loss'), + sum: create_24hPattern(this, 'unrealized_loss_24h'), + relToMarketCap: createBpsPercentRatioPattern(this, 'unrealized_loss_rel_to_market_cap'), + relToOwnGross: createBpsPercentRatioPattern(this, 'unrealized_loss_rel_to_own_gross_pnl'), + }, + netPnl: { + cents: createMetricPattern1(this, 'net_unrealized_pnl_cents'), + usd: createMetricPattern1(this, 'net_unrealized_pnl'), + relToOwnGross: createBpsPercentRatioPattern(this, 'net_unrealized_pnl_rel_to_own_gross_pnl'), + }, + profit: { + raw: createCentsUsdPattern(this, 'unrealized_profit'), + sum: create_24hPattern(this, 'unrealized_profit_24h'), + relToMarketCap: createBpsPercentRatioPattern(this, 'unrealized_profit_rel_to_market_cap'), + relToOwnGross: createBpsPercentRatioPattern(this, 'unrealized_profit_rel_to_own_gross_pnl'), + }, + }, + }, + sth: { + realized: createCapGrossInvestorLossMvrvNetNuplPeakPriceProfitSoprPattern(this, 'sth'), + supply: createDeltaHalvedInRelTotalPattern2(this, 'sth_supply'), + outputs: createUnspentPattern3(this, 'sth_utxo_count'), + activity: createCoindaysCoinyearsDormancySentVelocityPattern(this, 'sth'), + costBasis: createInvestedMaxMinPercentilesSupplyPattern(this, 'sth'), + unrealized: createGrossInvestedInvestorLossNetProfitSentimentPattern2(this, 'sth'), + }, + lth: { + supply: createDeltaHalvedInRelTotalPattern2(this, 'lth_supply'), + outputs: createUnspentPattern3(this, 'lth_utxo_count'), + activity: createCoindaysCoinyearsDormancySentVelocityPattern(this, 'lth'), + realized: { + profit: createCumulativeDistributionRawRelSumValuePattern(this, 'lth'), + loss: createCapitulationCumulativeNegativeRawRelSumValuePattern(this, 'lth'), + grossPnl: createRawSellSumPattern(this, 'lth'), + netPnl: createChangeCumulativeDeltaRawRelSumPattern(this, 'lth_net'), + sopr: { + valueCreated: { + sum: create_1m1w1y24hPattern(this, 'lth_value_created'), + raw: createMetricPattern1(this, 'lth_value_created'), + }, + valueDestroyed: { + sum: create_1m1w1y24hPattern(this, 'lth_value_destroyed'), + raw: createMetricPattern1(this, 'lth_value_destroyed'), + }, + ratio: create_1m1w1y24hPattern(this, 'lth_sopr'), + }, + peakRegret: createCumulativeRawRelPattern(this, 'lth_realized_peak_regret'), + investor: createCapLowerPriceUpperPattern(this, 'lth'), + profitToLossRatio: create_1m1w1y24hPattern(this, 'lth_realized_profit_to_loss_ratio'), + cap: createCentsDeltaRawRelUsdPattern(this, 'lth'), + price: createBpsCentsPercentilesRatioSatsSmaStdUsdPattern(this, 'lth_realized_price'), + mvrv: createMetricPattern1(this, 'lth_mvrv'), + nupl: createBpsRatioPattern(this, 'lth_nupl_ratio'), + }, + costBasis: createInvestedMaxMinPercentilesSupplyPattern(this, 'lth'), + unrealized: createGrossInvestedInvestorLossNetProfitSentimentPattern2(this, 'lth'), + }, + ageRange: { + upTo1h: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_under_1h_old'), + _1hTo1d: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_1h_to_1d_old'), + _1dTo1w: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_1d_to_1w_old'), + _1wTo1m: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_1w_to_1m_old'), + _1mTo2m: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_1m_to_2m_old'), + _2mTo3m: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_2m_to_3m_old'), + _3mTo4m: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_3m_to_4m_old'), + _4mTo5m: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_4m_to_5m_old'), + _5mTo6m: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_5m_to_6m_old'), + _6mTo1y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_6m_to_1y_old'), + _1yTo2y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_1y_to_2y_old'), + _2yTo3y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_2y_to_3y_old'), + _3yTo4y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_3y_to_4y_old'), + _4yTo5y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_4y_to_5y_old'), + _5yTo6y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_5y_to_6y_old'), + _6yTo7y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_6y_to_7y_old'), + _7yTo8y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_7y_to_8y_old'), + _8yTo10y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_8y_to_10y_old'), + _10yTo12y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_10y_to_12y_old'), + _12yTo15y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_12y_to_15y_old'), + from15y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_over_15y_old'), + }, + maxAge: { + _1w: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_1w_old'), + _1m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_1m_old'), + _2m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_2m_old'), + _3m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_3m_old'), + _4m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_4m_old'), + _5m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_5m_old'), + _6m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_6m_old'), + _1y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_1y_old'), + _2y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_2y_old'), + _3y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_3y_old'), + _4y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_4y_old'), + _5y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_5y_old'), + _6y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_6y_old'), + _7y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_7y_old'), + _8y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_8y_old'), + _10y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_10y_old'), + _12y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_12y_old'), + _15y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_15y_old'), + }, + minAge: { + _1d: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_1d_old'), + _1w: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_1w_old'), + _1m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_1m_old'), + _2m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_2m_old'), + _3m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_3m_old'), + _4m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_4m_old'), + _5m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_5m_old'), + _6m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_6m_old'), + _1y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_1y_old'), + _2y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_2y_old'), + _3y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_3y_old'), + _4y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_4y_old'), + _5y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_5y_old'), + _6y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_6y_old'), + _7y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_7y_old'), + _8y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_8y_old'), + _10y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_10y_old'), + _12y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_12y_old'), + }, + epoch: { + _0: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'epoch_0'), + _1: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'epoch_1'), + _2: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'epoch_2'), + _3: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'epoch_3'), + _4: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'epoch_4'), + }, + class: { + _2009: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2009'), + _2010: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2010'), + _2011: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2011'), + _2012: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2012'), + _2013: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2013'), + _2014: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2014'), + _2015: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2015'), + _2016: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2016'), + _2017: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2017'), + _2018: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2018'), + _2019: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2019'), + _2020: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2020'), + _2021: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2021'), + _2022: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2022'), + _2023: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2023'), + _2024: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2024'), + _2025: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2025'), + _2026: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2026'), + }, + geAmount: { + _1sat: createOutputsRealizedSupplyPattern(this, 'utxos_over_1sat'), + _10sats: createOutputsRealizedSupplyPattern(this, 'utxos_over_10sats'), + _100sats: createOutputsRealizedSupplyPattern(this, 'utxos_over_100sats'), + _1kSats: createOutputsRealizedSupplyPattern(this, 'utxos_over_1k_sats'), + _10kSats: createOutputsRealizedSupplyPattern(this, 'utxos_over_10k_sats'), + _100kSats: createOutputsRealizedSupplyPattern(this, 'utxos_over_100k_sats'), + _1mSats: createOutputsRealizedSupplyPattern(this, 'utxos_over_1m_sats'), + _10mSats: createOutputsRealizedSupplyPattern(this, 'utxos_over_10m_sats'), + _1btc: createOutputsRealizedSupplyPattern(this, 'utxos_over_1btc'), + _10btc: createOutputsRealizedSupplyPattern(this, 'utxos_over_10btc'), + _100btc: createOutputsRealizedSupplyPattern(this, 'utxos_over_100btc'), + _1kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_over_1k_btc'), + _10kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_over_10k_btc'), + }, + amountRange: { + _0sats: createOutputsRealizedSupplyPattern(this, 'utxos_with_0sats'), + _1satTo10sats: createOutputsRealizedSupplyPattern(this, 'utxos_above_1sat_under_10sats'), + _10satsTo100sats: createOutputsRealizedSupplyPattern(this, 'utxos_above_10sats_under_100sats'), + _100satsTo1kSats: createOutputsRealizedSupplyPattern(this, 'utxos_above_100sats_under_1k_sats'), + _1kSatsTo10kSats: createOutputsRealizedSupplyPattern(this, 'utxos_above_1k_sats_under_10k_sats'), + _10kSatsTo100kSats: createOutputsRealizedSupplyPattern(this, 'utxos_above_10k_sats_under_100k_sats'), + _100kSatsTo1mSats: createOutputsRealizedSupplyPattern(this, 'utxos_above_100k_sats_under_1m_sats'), + _1mSatsTo10mSats: createOutputsRealizedSupplyPattern(this, 'utxos_above_1m_sats_under_10m_sats'), + _10mSatsTo1btc: createOutputsRealizedSupplyPattern(this, 'utxos_above_10m_sats_under_1btc'), + _1btcTo10btc: createOutputsRealizedSupplyPattern(this, 'utxos_above_1btc_under_10btc'), + _10btcTo100btc: createOutputsRealizedSupplyPattern(this, 'utxos_above_10btc_under_100btc'), + _100btcTo1kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_above_100btc_under_1k_btc'), + _1kBtcTo10kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_above_1k_btc_under_10k_btc'), + _10kBtcTo100kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_above_10k_btc_under_100k_btc'), + _100kBtcOrMore: createOutputsRealizedSupplyPattern(this, 'utxos_above_100k_btc'), + }, + ltAmount: { + _10sats: createOutputsRealizedSupplyPattern(this, 'utxos_under_10sats'), + _100sats: createOutputsRealizedSupplyPattern(this, 'utxos_under_100sats'), + _1kSats: createOutputsRealizedSupplyPattern(this, 'utxos_under_1k_sats'), + _10kSats: createOutputsRealizedSupplyPattern(this, 'utxos_under_10k_sats'), + _100kSats: createOutputsRealizedSupplyPattern(this, 'utxos_under_100k_sats'), + _1mSats: createOutputsRealizedSupplyPattern(this, 'utxos_under_1m_sats'), + _10mSats: createOutputsRealizedSupplyPattern(this, 'utxos_under_10m_sats'), + _1btc: createOutputsRealizedSupplyPattern(this, 'utxos_under_1btc'), + _10btc: createOutputsRealizedSupplyPattern(this, 'utxos_under_10btc'), + _100btc: createOutputsRealizedSupplyPattern(this, 'utxos_under_100btc'), + _1kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_under_1k_btc'), + _10kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_under_10k_btc'), + _100kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_under_100k_btc'), + }, + type: { + p2pk65: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2pk65'), + p2pk33: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2pk33'), + p2pkh: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2pkh'), + p2ms: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2ms'), + p2sh: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2sh'), + p2wpkh: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2wpkh'), + p2wsh: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2wsh'), + p2tr: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2tr'), + p2a: createOutputsRealizedSupplyUnrealizedPattern(this, 'p2a'), + unknown: createOutputsRealizedSupplyUnrealizedPattern(this, 'unknown_outputs'), + empty: createOutputsRealizedSupplyUnrealizedPattern(this, 'empty_outputs'), + }, + profitability: { + range: { + profitOver1000: createRealizedSupplyPattern(this, 'utxos_over_1000pct_up'), + profit500To1000: createRealizedSupplyPattern(this, 'utxos_500pct_to_1000pct_up'), + profit300To500: createRealizedSupplyPattern(this, 'utxos_300pct_to_500pct_up'), + profit200To300: createRealizedSupplyPattern(this, 'utxos_200pct_to_300pct_up'), + profit100To200: createRealizedSupplyPattern(this, 'utxos_100pct_to_200pct_up'), + profit90To100: createRealizedSupplyPattern(this, 'utxos_90pct_to_100pct_up'), + profit80To90: createRealizedSupplyPattern(this, 'utxos_80pct_to_90pct_up'), + profit70To80: createRealizedSupplyPattern(this, 'utxos_70pct_to_80pct_up'), + profit60To70: createRealizedSupplyPattern(this, 'utxos_60pct_to_70pct_up'), + profit50To60: createRealizedSupplyPattern(this, 'utxos_50pct_to_60pct_up'), + profit40To50: createRealizedSupplyPattern(this, 'utxos_40pct_to_50pct_up'), + profit30To40: createRealizedSupplyPattern(this, 'utxos_30pct_to_40pct_up'), + profit20To30: createRealizedSupplyPattern(this, 'utxos_20pct_to_30pct_up'), + profit10To20: createRealizedSupplyPattern(this, 'utxos_10pct_to_20pct_up'), + profit0To10: createRealizedSupplyPattern(this, 'utxos_0pct_to_10pct_up'), + loss0To10: createRealizedSupplyPattern(this, 'utxos_0pct_to_10pct_down'), + loss10To20: createRealizedSupplyPattern(this, 'utxos_10pct_to_20pct_down'), + loss20To30: createRealizedSupplyPattern(this, 'utxos_20pct_to_30pct_down'), + loss30To40: createRealizedSupplyPattern(this, 'utxos_30pct_to_40pct_down'), + loss40To50: createRealizedSupplyPattern(this, 'utxos_40pct_to_50pct_down'), + loss50To60: createRealizedSupplyPattern(this, 'utxos_50pct_to_60pct_down'), + loss60To70: createRealizedSupplyPattern(this, 'utxos_60pct_to_70pct_down'), + loss70To80: createRealizedSupplyPattern(this, 'utxos_70pct_to_80pct_down'), + loss80To90: createRealizedSupplyPattern(this, 'utxos_80pct_to_90pct_down'), + loss90To100: createRealizedSupplyPattern(this, 'utxos_90pct_to_100pct_down'), + }, + profit: { + breakeven: createRealizedSupplyPattern(this, 'profit_ge_breakeven'), + _10pct: createRealizedSupplyPattern(this, 'profit_ge_10pct'), + _20pct: createRealizedSupplyPattern(this, 'profit_ge_20pct'), + _30pct: createRealizedSupplyPattern(this, 'profit_ge_30pct'), + _40pct: createRealizedSupplyPattern(this, 'profit_ge_40pct'), + _50pct: createRealizedSupplyPattern(this, 'profit_ge_50pct'), + _60pct: createRealizedSupplyPattern(this, 'profit_ge_60pct'), + _70pct: createRealizedSupplyPattern(this, 'profit_ge_70pct'), + _80pct: createRealizedSupplyPattern(this, 'profit_ge_80pct'), + _90pct: createRealizedSupplyPattern(this, 'profit_ge_90pct'), + _100pct: createRealizedSupplyPattern(this, 'profit_ge_100pct'), + _200pct: createRealizedSupplyPattern(this, 'profit_ge_200pct'), + _300pct: createRealizedSupplyPattern(this, 'profit_ge_300pct'), + _500pct: createRealizedSupplyPattern(this, 'profit_ge_500pct'), + _1000pct: createRealizedSupplyPattern(this, 'profit_ge_1000pct'), + }, + loss: { + breakeven: createRealizedSupplyPattern(this, 'loss_ge_breakeven'), + _10pct: createRealizedSupplyPattern(this, 'loss_ge_10pct'), + _20pct: createRealizedSupplyPattern(this, 'loss_ge_20pct'), + _30pct: createRealizedSupplyPattern(this, 'loss_ge_30pct'), + _40pct: createRealizedSupplyPattern(this, 'loss_ge_40pct'), + _50pct: createRealizedSupplyPattern(this, 'loss_ge_50pct'), + _60pct: createRealizedSupplyPattern(this, 'loss_ge_60pct'), + _70pct: createRealizedSupplyPattern(this, 'loss_ge_70pct'), + _80pct: createRealizedSupplyPattern(this, 'loss_ge_80pct'), + _90pct: createRealizedSupplyPattern(this, 'loss_ge_90pct'), + }, + }, + matured: { + upTo1h: createBtcCentsSatsUsdPattern(this, 'utxo_under_1h_old_matured'), + _1hTo1d: createBtcCentsSatsUsdPattern(this, 'utxo_1h_to_1d_old_matured'), + _1dTo1w: createBtcCentsSatsUsdPattern(this, 'utxo_1d_to_1w_old_matured'), + _1wTo1m: createBtcCentsSatsUsdPattern(this, 'utxo_1w_to_1m_old_matured'), + _1mTo2m: createBtcCentsSatsUsdPattern(this, 'utxo_1m_to_2m_old_matured'), + _2mTo3m: createBtcCentsSatsUsdPattern(this, 'utxo_2m_to_3m_old_matured'), + _3mTo4m: createBtcCentsSatsUsdPattern(this, 'utxo_3m_to_4m_old_matured'), + _4mTo5m: createBtcCentsSatsUsdPattern(this, 'utxo_4m_to_5m_old_matured'), + _5mTo6m: createBtcCentsSatsUsdPattern(this, 'utxo_5m_to_6m_old_matured'), + _6mTo1y: createBtcCentsSatsUsdPattern(this, 'utxo_6m_to_1y_old_matured'), + _1yTo2y: createBtcCentsSatsUsdPattern(this, 'utxo_1y_to_2y_old_matured'), + _2yTo3y: createBtcCentsSatsUsdPattern(this, 'utxo_2y_to_3y_old_matured'), + _3yTo4y: createBtcCentsSatsUsdPattern(this, 'utxo_3y_to_4y_old_matured'), + _4yTo5y: createBtcCentsSatsUsdPattern(this, 'utxo_4y_to_5y_old_matured'), + _5yTo6y: createBtcCentsSatsUsdPattern(this, 'utxo_5y_to_6y_old_matured'), + _6yTo7y: createBtcCentsSatsUsdPattern(this, 'utxo_6y_to_7y_old_matured'), + _7yTo8y: createBtcCentsSatsUsdPattern(this, 'utxo_7y_to_8y_old_matured'), + _8yTo10y: createBtcCentsSatsUsdPattern(this, 'utxo_8y_to_10y_old_matured'), + _10yTo12y: createBtcCentsSatsUsdPattern(this, 'utxo_10y_to_12y_old_matured'), + _12yTo15y: createBtcCentsSatsUsdPattern(this, 'utxo_12y_to_15y_old_matured'), + from15y: createBtcCentsSatsUsdPattern(this, 'utxo_over_15y_old_matured'), + }, + }, + address: { + geAmount: { + _1sat: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_1sat'), + _10sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_10sats'), + _100sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_100sats'), + _1kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_1k_sats'), + _10kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_10k_sats'), + _100kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_100k_sats'), + _1mSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_1m_sats'), + _10mSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_10m_sats'), + _1btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_1btc'), + _10btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_10btc'), + _100btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_100btc'), + _1kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_1k_btc'), + _10kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_10k_btc'), + }, + amountRange: { + _0sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_with_0sats'), + _1satTo10sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_1sat_under_10sats'), + _10satsTo100sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_10sats_under_100sats'), + _100satsTo1kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_100sats_under_1k_sats'), + _1kSatsTo10kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_1k_sats_under_10k_sats'), + _10kSatsTo100kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_10k_sats_under_100k_sats'), + _100kSatsTo1mSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_100k_sats_under_1m_sats'), + _1mSatsTo10mSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_1m_sats_under_10m_sats'), + _10mSatsTo1btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_10m_sats_under_1btc'), + _1btcTo10btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_1btc_under_10btc'), + _10btcTo100btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_10btc_under_100btc'), + _100btcTo1kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_100btc_under_1k_btc'), + _1kBtcTo10kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_1k_btc_under_10k_btc'), + _10kBtcTo100kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_10k_btc_under_100k_btc'), + _100kBtcOrMore: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_100k_btc'), + }, + ltAmount: { + _10sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_10sats'), + _100sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_100sats'), + _1kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_1k_sats'), + _10kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_10k_sats'), + _100kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_100k_sats'), + _1mSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_1m_sats'), + _10mSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_10m_sats'), + _1btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_1btc'), + _10btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_10btc'), + _100btc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_100btc'), + _1kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_1k_btc'), + _10kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_10k_btc'), + _100kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_100k_btc'), + }, + }, + }, + coinblocksDestroyed: createCumulativeRawPattern(this, 'coinblocks_destroyed'), }, supply: { circulating: createBtcCentsSatsUsdPattern(this, 'circulating_supply'), @@ -8860,14 +8998,14 @@ class BrkClient extends BrkClientBase { } /** - * Get supported indexes for a metric + * Get metric info * - * Returns the list of indexes supported by the specified metric. For example, `realized_price` might be available on day1, week1, and month1. + * Returns the supported indexes and value type for the specified metric. * * Endpoint: `GET /api/metric/{metric}` * * @param {Metric} metric - * @returns {Promise} + * @returns {Promise} */ async getMetricInfo(metric) { return this.getJson(`/api/metric/${metric}`); @@ -8882,8 +9020,8 @@ class BrkClient extends BrkClientBase { * * @param {Metric} metric - Metric name * @param {Index} index - Aggregation index - * @param {number=} [start] - Inclusive starting index, if negative counts from end. Aliases: `from`, `f`, `s` - * @param {number=} [end] - Exclusive ending index, if negative counts from end. Aliases: `to`, `t`, `e` + * @param {string=} [start] - Inclusive start: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `from`, `f`, `s` + * @param {string=} [end] - Exclusive end: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `to`, `t`, `e` * @param {string=} [limit] - Maximum number of values to return (ignored if `end` is set). Aliases: `count`, `c`, `l` * @param {Format=} [format] - Format of the output * @returns {Promise} @@ -8902,6 +9040,50 @@ class BrkClient extends BrkClientBase { return this.getJson(path); } + /** + * Get raw metric data + * + * Returns just the data array without the MetricData wrapper. Supports the same range and format parameters as the standard endpoint. + * + * Endpoint: `GET /api/metric/{metric}/{index}/data` + * + * @param {Metric} metric - Metric name + * @param {Index} index - Aggregation index + * @param {string=} [start] - Inclusive start: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `from`, `f`, `s` + * @param {string=} [end] - Exclusive end: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `to`, `t`, `e` + * @param {string=} [limit] - Maximum number of values to return (ignored if `end` is set). Aliases: `count`, `c`, `l` + * @param {Format=} [format] - Format of the output + * @returns {Promise} + */ + async getMetricData(metric, index, start, end, limit, format) { + const params = new URLSearchParams(); + if (start !== undefined) params.set('start', String(start)); + if (end !== undefined) params.set('end', String(end)); + if (limit !== undefined) params.set('limit', String(limit)); + if (format !== undefined) params.set('format', String(format)); + const query = params.toString(); + const path = `/api/metric/${metric}/${index}/data${query ? '?' + query : ''}`; + if (format === 'csv') { + return this.getText(path); + } + return this.getJson(path); + } + + /** + * Get latest metric value + * + * Returns the single most recent value for a metric, unwrapped (not inside a MetricData object). + * + * Endpoint: `GET /api/metric/{metric}/{index}/latest` + * + * @param {Metric} metric - Metric name + * @param {Index} index - Aggregation index + * @returns {Promise<*>} + */ + async getMetricLatest(metric, index) { + return this.getJson(`/api/metric/${metric}/${index}/latest`); + } + /** * Metrics catalog * @@ -8923,8 +9105,8 @@ class BrkClient extends BrkClientBase { * * @param {Metrics} [metrics] - Requested metrics * @param {Index} [index] - Index to query - * @param {number=} [start] - Inclusive starting index, if negative counts from end. Aliases: `from`, `f`, `s` - * @param {number=} [end] - Exclusive ending index, if negative counts from end. Aliases: `to`, `t`, `e` + * @param {string=} [start] - Inclusive start: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `from`, `f`, `s` + * @param {string=} [end] - Exclusive end: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `to`, `t`, `e` * @param {string=} [limit] - Maximum number of values to return (ignored if `end` is set). Aliases: `count`, `c`, `l` * @param {Format=} [format] - Format of the output * @returns {Promise} @@ -9044,17 +9226,18 @@ class BrkClient extends BrkClientBase { * * Fuzzy search for metrics by name. Supports partial matches and typos. * - * Endpoint: `GET /api/metrics/search/{metric}` + * Endpoint: `GET /api/metrics/search` * - * @param {Metric} metric - * @param {Limit=} [limit] + * @param {Metric} [q] - Search query string + * @param {Limit=} [limit] - Maximum number of results * @returns {Promise} */ - async searchMetrics(metric, limit) { + async searchMetrics(q, limit) { const params = new URLSearchParams(); + params.set('q', String(q)); if (limit !== undefined) params.set('limit', String(limit)); const query = params.toString(); - const path = `/api/metrics/search/${metric}${query ? '?' + query : ''}`; + const path = `/api/metrics/search${query ? '?' + query : ''}`; return this.getJson(path); } diff --git a/packages/brk_client/brk_client/__init__.py b/packages/brk_client/brk_client/__init__.py index aca46f4b0..be95d18e9 100644 --- a/packages/brk_client/brk_client/__init__.py +++ b/packages/brk_client/brk_client/__init__.py @@ -80,12 +80,14 @@ CostBasisBucket = Literal["raw", "lin200", "lin500", "lin1000", "log10", "log50" # Value type for cost basis distribution. # Options: supply (BTC), realized (USD, price × supply), unrealized (USD, spot × supply). CostBasisValue = Literal["supply", "realized", "unrealized"] +# Date in YYYYMMDD format stored as u32 +Date = int # Output format for API responses Format = Literal["json", "csv"] # Maximum number of results to return. Defaults to 100 if not specified. Limit = int -# Date in YYYYMMDD format stored as u32 -Date = int +# A range boundary: integer index, date, or timestamp. +RangeIndex = Union[int, Date, Timestamp] Day1 = int Day3 = int # US Dollar amount as floating point @@ -431,13 +433,13 @@ class DataRangeFormat(TypedDict): Data range with output format for API query parameters Attributes: - start: Inclusive starting index, if negative counts from end. Aliases: `from`, `f`, `s` - end: Exclusive ending index, if negative counts from end. Aliases: `to`, `t`, `e` + start: Inclusive start: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `from`, `f`, `s` + end: Exclusive end: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `to`, `t`, `e` limit: Maximum number of values to return (ignored if `end` is set). Aliases: `count`, `c`, `l` format: Format of the output """ - start: Optional[int] - end: Optional[int] + start: Union[RangeIndex, None] + end: Union[RangeIndex, None] limit: Union[Limit, None] format: Format @@ -625,9 +627,6 @@ class IndexInfo(TypedDict): index: Index aliases: List[str] -class LimitParam(TypedDict): - limit: Limit - class MempoolBlock(TypedDict): """ Block info in a mempool.space like format for fee estimation. @@ -675,6 +674,17 @@ class MetricCount(TypedDict): lazy_endpoints: int stored_endpoints: int +class MetricInfo(TypedDict): + """ + Metadata about a metric + + Attributes: + indexes: Available indexes + type: Value type (e.g. "f32", "u64", "Sats") + """ + indexes: List[Index] + type: str + class MetricParam(TypedDict): metric: Metric @@ -685,15 +695,15 @@ class MetricSelection(TypedDict): Attributes: metrics: Requested metrics index: Index to query - start: Inclusive starting index, if negative counts from end. Aliases: `from`, `f`, `s` - end: Exclusive ending index, if negative counts from end. Aliases: `to`, `t`, `e` + start: Inclusive start: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `from`, `f`, `s` + end: Exclusive end: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `to`, `t`, `e` limit: Maximum number of values to return (ignored if `end` is set). Aliases: `count`, `c`, `l` format: Format of the output """ metrics: Metrics index: Index - start: Optional[int] - end: Optional[int] + start: Union[RangeIndex, None] + end: Union[RangeIndex, None] limit: Union[Limit, None] format: Format @@ -702,15 +712,15 @@ class MetricSelectionLegacy(TypedDict): Legacy metric selection parameters (deprecated) Attributes: - start: Inclusive starting index, if negative counts from end. Aliases: `from`, `f`, `s` - end: Exclusive ending index, if negative counts from end. Aliases: `to`, `t`, `e` + start: Inclusive start: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `from`, `f`, `s` + end: Exclusive end: integer index, date (YYYY-MM-DD), or timestamp (ISO 8601). Negative integers count from end. Aliases: `to`, `t`, `e` limit: Maximum number of values to return (ignored if `end` is set). Aliases: `count`, `c`, `l` format: Format of the output """ index: Index ids: Metrics - start: Optional[int] - end: Optional[int] + start: Union[RangeIndex, None] + end: Union[RangeIndex, None] limit: Union[Limit, None] format: Format @@ -917,6 +927,15 @@ class RewardStats(TypedDict): totalFee: Sats totalTx: int +class SearchQuery(TypedDict): + """ + Attributes: + q: Search query string + limit: Maximum number of results + """ + q: Metric + limit: Limit + class SupplyState(TypedDict): """ Current supply state tracking UTXO count and total value @@ -2328,7 +2347,7 @@ class CapLossMvrvNetNuplPriceProfitSoprPattern: self.cap: CentsDeltaUsdPattern = CentsDeltaUsdPattern(client, _m(acc, 'realized_cap')) self.loss: CumulativeNegativeRawSumPattern = CumulativeNegativeRawSumPattern(client, acc) self.mvrv: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'mvrv')) - self.net_pnl: RawSumPattern2[CentsSigned] = RawSumPattern2(client, _m(acc, 'net_realized_pnl')) + self.net_pnl: RawSumPattern3[CentsSigned] = RawSumPattern3(client, _m(acc, 'net_realized_pnl')) self.nupl: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'nupl_ratio')) self.price: BpsCentsRatioSatsUsdPattern = BpsCentsRatioSatsUsdPattern(client, _m(acc, 'realized_price')) self.profit: CumulativeRawSumPattern2 = CumulativeRawSumPattern2(client, _m(acc, 'realized_profit')) @@ -2394,11 +2413,11 @@ class CapLossMvrvNuplPriceProfitSoprPattern: def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" self.cap: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'realized_cap')) - self.loss: RawSumPattern = RawSumPattern(client, _m(acc, 'realized_loss')) + self.loss: RawSumPattern2 = RawSumPattern2(client, _m(acc, 'realized_loss')) self.mvrv: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'mvrv')) self.nupl: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'nupl_ratio')) self.price: BpsCentsRatioSatsUsdPattern = BpsCentsRatioSatsUsdPattern(client, _m(acc, 'realized_price')) - self.profit: RawSumPattern = RawSumPattern(client, _m(acc, 'realized_profit')) + self.profit: RawSumPattern2 = RawSumPattern2(client, _m(acc, 'realized_profit')) self.sopr: ValuePattern = ValuePattern(client, _m(acc, 'value')) class CumulativeDistributionRawRelSumValuePattern: @@ -2458,7 +2477,7 @@ class BtcCentsRelSatsUsdPattern3: """Create pattern node with accumulated metric name.""" self.btc: MetricPattern1[Bitcoin] = MetricPattern1(client, acc) self.cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'cents')) - self.rel_to_circulating_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rel_to_circulating_supply')) + self.rel_to_circulating: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rel_to_circulating_supply')) self.rel_to_own_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rel_to_own_supply')) self.sats: MetricPattern1[Sats] = MetricPattern1(client, _m(acc, 'sats')) self.usd: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd')) @@ -2475,28 +2494,28 @@ class ChangeCumulativeDeltaRawRelSumPattern: self.rel_to_rcap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'realized_pnl_rel_to_realized_cap')) self.sum: _1m1w1y24hPattern[CentsSigned] = _1m1w1y24hPattern(client, _m(acc, 'realized_pnl')) -class DeltaHalvedInRelTotalPattern: +class DeltaHalvedInRelTotalPattern2: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" self.delta: ChangeRatePattern = ChangeRatePattern(client, _m(acc, 'delta')) self.halved: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'halved')) - self.in_loss: BtcCentsRelSatsUsdPattern = BtcCentsRelSatsUsdPattern(client, _m(acc, 'in_loss')) - self.in_profit: BtcCentsRelSatsUsdPattern = BtcCentsRelSatsUsdPattern(client, _m(acc, 'in_profit')) - self.rel_to_circulating_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rel_to_circulating_supply')) + self.in_loss: BtcCentsRelSatsUsdPattern3 = BtcCentsRelSatsUsdPattern3(client, _m(acc, 'in_loss')) + self.in_profit: BtcCentsRelSatsUsdPattern3 = BtcCentsRelSatsUsdPattern3(client, _m(acc, 'in_profit')) + self.rel_to_circulating: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rel_to_circulating_supply')) self.total: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, acc) -class DeltaHalvedInRelTotalPattern2: +class DeltaHalvedInRelTotalPattern: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" self.delta: ChangeRatePattern2 = ChangeRatePattern2(client, _m(acc, 'delta')) self.halved: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'halved')) - self.in_loss: BtcCentsRelSatsUsdPattern3 = BtcCentsRelSatsUsdPattern3(client, _m(acc, 'in_loss')) - self.in_profit: BtcCentsRelSatsUsdPattern3 = BtcCentsRelSatsUsdPattern3(client, _m(acc, 'in_profit')) - self.rel_to_circulating_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rel_to_circulating_supply')) + self.in_loss: BtcCentsRelSatsUsdPattern = BtcCentsRelSatsUsdPattern(client, _m(acc, 'in_loss')) + self.in_profit: BtcCentsRelSatsUsdPattern = BtcCentsRelSatsUsdPattern(client, _m(acc, 'in_profit')) + self.rel_to_circulating: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rel_to_circulating_supply')) self.total: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, acc) class NegativeRawRelSumPattern2: @@ -2507,7 +2526,7 @@ class NegativeRawRelSumPattern2: self.negative: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss')) self.raw: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'unrealized_loss')) self.rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'unrealized_loss_rel_to_market_cap')) - self.rel_to_own_gross_pnl: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'unrealized_loss_rel_to_own_gross_pnl')) + self.rel_to_own_gross: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'unrealized_loss_rel_to_own_gross_pnl')) self.rel_to_own_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'unrealized_loss_rel_to_own_market_cap')) self.sum: _24hPattern = _24hPattern(client, _m(acc, 'unrealized_loss_24h')) @@ -2563,7 +2582,7 @@ class BtcCentsRelSatsUsdPattern: """Create pattern node with accumulated metric name.""" self.btc: MetricPattern1[Bitcoin] = MetricPattern1(client, acc) self.cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'cents')) - self.rel_to_circulating_supply: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rel_to_circulating_supply')) + self.rel_to_circulating: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rel_to_circulating_supply')) self.sats: MetricPattern1[Sats] = MetricPattern1(client, _m(acc, 'sats')) self.usd: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd')) @@ -2620,7 +2639,7 @@ class InvestedInvestorLossNetProfitPattern: self.investor_cap: InPattern = InPattern(client, _m(acc, 'investor_cap_in')) self.loss: NegativeRawSumPattern = NegativeRawSumPattern(client, acc) self.net_pnl: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'net_unrealized_pnl')) - self.profit: RawSumPattern = RawSumPattern(client, _m(acc, 'unrealized_profit')) + self.profit: RawSumPattern2 = RawSumPattern2(client, _m(acc, 'unrealized_profit')) class InvestedMaxMinPercentilesSupplyPattern: """Pattern struct for repeated tree structure.""" @@ -2651,7 +2670,7 @@ class RawRelSumPattern2: """Create pattern node with accumulated metric name.""" self.raw: CentsUsdPattern = CentsUsdPattern(client, acc) self.rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rel_to_market_cap')) - self.rel_to_own_gross_pnl: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rel_to_own_gross_pnl')) + self.rel_to_own_gross: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rel_to_own_gross_pnl')) self.rel_to_own_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rel_to_own_market_cap')) self.sum: _24hPattern = _24hPattern(client, _m(acc, '24h')) @@ -2753,8 +2772,8 @@ class AdjustedRatioValuePattern: """Create pattern node with accumulated metric name.""" self.adjusted: RatioValuePattern2 = RatioValuePattern2(client, _m(acc, 'adjusted')) self.ratio: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, _m(acc, 'sopr')) - self.value_created: RawSumPattern3[Cents] = RawSumPattern3(client, _m(acc, 'value_created')) - self.value_destroyed: RawSumPattern3[Cents] = RawSumPattern3(client, _m(acc, 'value_destroyed')) + self.value_created: RawSumPattern[Cents] = RawSumPattern(client, _m(acc, 'value_created')) + self.value_destroyed: RawSumPattern[Cents] = RawSumPattern(client, _m(acc, 'value_destroyed')) class BothReactivatedReceivingSendingPattern: """Pattern struct for repeated tree structure.""" @@ -2781,7 +2800,7 @@ class CapLowerPriceUpperPattern: def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" - self.cap: RawPattern[CentsSquaredSats] = RawPattern(client, _m(acc, 'investor_cap_raw')) + self.cap: RawPattern2[CentsSquaredSats] = RawPattern2(client, _m(acc, 'investor_cap_raw')) self.lower_price_band: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'lower_price_band')) self.price: BpsCentsPercentilesRatioSatsUsdPattern = BpsCentsPercentilesRatioSatsUsdPattern(client, _m(acc, 'investor_price')) self.upper_price_band: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'upper_price_band')) @@ -2792,7 +2811,7 @@ class CentsRelUsdPattern2: def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" self.cents: MetricPattern1[CentsSigned] = MetricPattern1(client, _m(acc, 'cents')) - self.rel_to_own_gross_pnl: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rel_to_own_gross_pnl')) + self.rel_to_own_gross: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rel_to_own_gross_pnl')) self.rel_to_own_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'rel_to_own_market_cap')) self.usd: MetricPattern1[Dollars] = MetricPattern1(client, acc) @@ -2962,7 +2981,7 @@ class LossNetProfitPattern: """Create pattern node with accumulated metric name.""" self.loss: NegativeRawSumPattern = NegativeRawSumPattern(client, acc) self.net_pnl: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'net_unrealized_pnl')) - self.profit: RawSumPattern = RawSumPattern(client, _m(acc, 'unrealized_profit')) + self.profit: RawSumPattern2 = RawSumPattern2(client, _m(acc, 'unrealized_profit')) class NegativeRawSumPattern: """Pattern struct for repeated tree structure.""" @@ -2997,8 +3016,8 @@ class RatioValuePattern: def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" self.ratio: _24hPattern2[StoredF64] = _24hPattern2(client, _m(acc, 'sopr_24h')) - self.value_created: RawSumPattern2[Cents] = RawSumPattern2(client, _m(acc, 'value_created')) - self.value_destroyed: RawSumPattern2[Cents] = RawSumPattern2(client, _m(acc, 'value_destroyed')) + self.value_created: RawSumPattern3[Cents] = RawSumPattern3(client, _m(acc, 'value_created')) + self.value_destroyed: RawSumPattern3[Cents] = RawSumPattern3(client, _m(acc, 'value_destroyed')) class RawSellSumPattern: """Pattern struct for repeated tree structure.""" @@ -3027,14 +3046,6 @@ class CumulativeRawSumPattern(Generic[T]): self.raw: MetricPattern1[T] = MetricPattern1(client, acc) self.sum: _1m1w1y24hPattern[T] = _1m1w1y24hPattern(client, acc) -class BaseCumulativePattern: - """Pattern struct for repeated tree structure.""" - - def __init__(self, client: BrkClientBase, acc: str): - """Create pattern node with accumulated metric name.""" - self.base: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, acc) - self.cumulative: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'cumulative')) - class BaseSumPattern: """Pattern struct for repeated tree structure.""" @@ -3043,7 +3054,7 @@ class BaseSumPattern: self.base: MetricPattern1[Cents] = MetricPattern1(client, acc) self.sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, acc) -class BaseDeltaPattern: +class BaseDeltaPattern2: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): @@ -3051,7 +3062,7 @@ class BaseDeltaPattern: self.base: MetricPattern1[StoredU64] = MetricPattern1(client, acc) self.delta: ChangeRatePattern = ChangeRatePattern(client, _m(acc, 'delta')) -class BaseDeltaPattern2: +class BaseDeltaPattern: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): @@ -3083,7 +3094,7 @@ class CentsUsdPattern: self.cents: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'cents')) self.usd: MetricPattern1[Dollars] = MetricPattern1(client, acc) -class ChangeRatePattern2: +class ChangeRatePattern: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): @@ -3099,7 +3110,7 @@ class ChangeRatePattern4: self.change: _1m1w1y24hPattern4 = _1m1w1y24hPattern4(client, _m(acc, 'change')) self.rate: _1m1w1y24hPattern2 = _1m1w1y24hPattern2(client, _m(acc, 'rate')) -class ChangeRatePattern: +class ChangeRatePattern2: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): @@ -3120,7 +3131,7 @@ class CoindaysSentPattern: def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" - self.coindays_destroyed: RawSumPattern2[StoredF64] = RawSumPattern2(client, _m(acc, 'coindays_destroyed')) + self.coindays_destroyed: RawSumPattern3[StoredF64] = RawSumPattern3(client, _m(acc, 'coindays_destroyed')) self.sent: InRawSumPattern = InRawSumPattern(client, _m(acc, 'sent')) class HalvedTotalPattern: @@ -3144,16 +3155,16 @@ class InPattern: def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" - self.in_loss: RawPattern[CentsSats] = RawPattern(client, _m(acc, 'loss_raw')) - self.in_profit: RawPattern[CentsSats] = RawPattern(client, _m(acc, 'profit_raw')) + self.in_loss: RawPattern2[CentsSats] = RawPattern2(client, _m(acc, 'loss_raw')) + self.in_profit: RawPattern2[CentsSats] = RawPattern2(client, _m(acc, 'profit_raw')) class LossProfitPattern2: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" - self.loss: RawSumPattern = RawSumPattern(client, _m(acc, 'loss')) - self.profit: RawSumPattern = RawSumPattern(client, _m(acc, 'profit')) + self.loss: RawSumPattern2 = RawSumPattern2(client, _m(acc, 'loss')) + self.profit: RawSumPattern2 = RawSumPattern2(client, _m(acc, 'profit')) class PriceValuePattern: """Pattern struct for repeated tree structure.""" @@ -3179,7 +3190,7 @@ class RawSumPattern4: self.raw: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, acc) self.sum: _24hPattern3 = _24hPattern3(client, _m(acc, '24h')) -class RawSumPattern: +class RawSumPattern2: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): @@ -3216,8 +3227,8 @@ class ValuePattern: def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" - self.value_created: RawSumPattern2[Cents] = RawSumPattern2(client, _m(acc, 'created')) - self.value_destroyed: RawSumPattern2[Cents] = RawSumPattern2(client, _m(acc, 'destroyed')) + self.value_created: RawSumPattern3[Cents] = RawSumPattern3(client, _m(acc, 'created')) + self.value_destroyed: RawSumPattern3[Cents] = RawSumPattern3(client, _m(acc, 'destroyed')) class CumulativeRawPattern(Generic[T]): """Pattern struct for repeated tree structure.""" @@ -3227,7 +3238,7 @@ class CumulativeRawPattern(Generic[T]): self.cumulative: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'cumulative')) self.raw: MetricPattern1[T] = MetricPattern1(client, acc) -class RawSumPattern3(Generic[T]): +class RawSumPattern(Generic[T]): """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): @@ -3235,7 +3246,7 @@ class RawSumPattern3(Generic[T]): self.raw: MetricPattern1[T] = MetricPattern1(client, acc) self.sum: _1m1w1y24hPattern[T] = _1m1w1y24hPattern(client, _m(acc, 'sum')) -class RawSumPattern2(Generic[T]): +class RawSumPattern3(Generic[T]): """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): @@ -3306,7 +3317,7 @@ class _24hPattern2(Generic[T]): """Create pattern node with accumulated metric name.""" self._24h: MetricPattern1[T] = MetricPattern1(client, acc) -class RawPattern(Generic[T]): +class RawPattern2(Generic[T]): """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): @@ -3323,8 +3334,8 @@ class MetricsTree_Blocks_Difficulty: self.as_hash: MetricPattern1[StoredF64] = MetricPattern1(client, 'difficulty_as_hash') self.adjustment: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'difficulty_adjustment') self.epoch: MetricPattern1[Epoch] = MetricPattern1(client, 'difficulty_epoch') - self.blocks_before_next_adjustment: MetricPattern1[StoredU32] = MetricPattern1(client, 'blocks_before_next_difficulty_adjustment') - self.days_before_next_adjustment: MetricPattern1[StoredF32] = MetricPattern1(client, 'days_before_next_difficulty_adjustment') + self.blocks_before_next: MetricPattern1[StoredU32] = MetricPattern1(client, 'blocks_before_next_difficulty_adjustment') + self.days_before_next: MetricPattern1[StoredF32] = MetricPattern1(client, 'days_before_next_difficulty_adjustment') class MetricsTree_Blocks_Time: """Metrics tree node.""" @@ -3426,8 +3437,8 @@ class MetricsTree_Blocks_Halving: def __init__(self, client: BrkClientBase, base_path: str = ''): self.epoch: MetricPattern1[Halving] = MetricPattern1(client, 'halving_epoch') - self.blocks_before_next_halving: MetricPattern1[StoredU32] = MetricPattern1(client, 'blocks_before_next_halving') - self.days_before_next_halving: MetricPattern1[StoredF32] = MetricPattern1(client, 'days_before_next_halving') + self.blocks_before_next: MetricPattern1[StoredU32] = MetricPattern1(client, 'blocks_before_next_halving') + self.days_before_next: MetricPattern1[StoredF32] = MetricPattern1(client, 'days_before_next_halving') class MetricsTree_Blocks_Fullness: """Metrics tree node.""" @@ -3453,6 +3464,21 @@ class MetricsTree_Blocks: self.vbytes: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RawSumPattern = AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RawSumPattern(client, 'block_vbytes') self.fullness: MetricsTree_Blocks_Fullness = MetricsTree_Blocks_Fullness(client) +class MetricsTree_Transactions_Raw: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.first_txindex: MetricPattern18[TxIndex] = MetricPattern18(client, 'first_txindex') + self.height: MetricPattern19[Height] = MetricPattern19(client, 'height') + self.txid: MetricPattern19[Txid] = MetricPattern19(client, 'txid') + self.txversion: MetricPattern19[TxVersion] = MetricPattern19(client, 'txversion') + self.rawlocktime: MetricPattern19[RawLockTime] = MetricPattern19(client, 'rawlocktime') + self.base_size: MetricPattern19[StoredU32] = MetricPattern19(client, 'base_size') + self.total_size: MetricPattern19[StoredU32] = MetricPattern19(client, 'total_size') + self.is_explicitly_rbf: MetricPattern19[StoredBool] = MetricPattern19(client, 'is_explicitly_rbf') + self.first_txinindex: MetricPattern19[TxInIndex] = MetricPattern19(client, 'first_txinindex') + self.first_txoutindex: MetricPattern19[TxOutIndex] = MetricPattern19(client, 'first_txoutindex') + class MetricsTree_Transactions_Count: """Metrics tree node.""" @@ -3490,7 +3516,7 @@ class MetricsTree_Transactions_Volume: def __init__(self, client: BrkClientBase, base_path: str = ''): self.sent_sum: _1m1w1y24hBtcCentsSatsUsdPattern = _1m1w1y24hBtcCentsSatsUsdPattern(client, 'sent_sum') self.received_sum: _1m1w1y24hBtcCentsSatsUsdPattern = _1m1w1y24hBtcCentsSatsUsdPattern(client, 'received_sum') - self.annualized_volume: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, 'annualized_volume') + self.annualized: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, 'annualized_volume') self.tx_per_sec: MetricPattern1[StoredF32] = MetricPattern1(client, 'tx_per_sec') self.outputs_per_sec: MetricPattern1[StoredF32] = MetricPattern1(client, 'outputs_per_sec') self.inputs_per_sec: MetricPattern1[StoredF32] = MetricPattern1(client, 'inputs_per_sec') @@ -3499,22 +3525,23 @@ class MetricsTree_Transactions: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.first_txindex: MetricPattern18[TxIndex] = MetricPattern18(client, 'first_txindex') - self.height: MetricPattern19[Height] = MetricPattern19(client, 'height') - self.txid: MetricPattern19[Txid] = MetricPattern19(client, 'txid') - self.txversion: MetricPattern19[TxVersion] = MetricPattern19(client, 'txversion') - self.rawlocktime: MetricPattern19[RawLockTime] = MetricPattern19(client, 'rawlocktime') - self.base_size: MetricPattern19[StoredU32] = MetricPattern19(client, 'base_size') - self.total_size: MetricPattern19[StoredU32] = MetricPattern19(client, 'total_size') - self.is_explicitly_rbf: MetricPattern19[StoredBool] = MetricPattern19(client, 'is_explicitly_rbf') - self.first_txinindex: MetricPattern19[TxInIndex] = MetricPattern19(client, 'first_txinindex') - self.first_txoutindex: MetricPattern19[TxOutIndex] = MetricPattern19(client, 'first_txoutindex') + self.raw: MetricsTree_Transactions_Raw = MetricsTree_Transactions_Raw(client) self.count: MetricsTree_Transactions_Count = MetricsTree_Transactions_Count(client) self.size: MetricsTree_Transactions_Size = MetricsTree_Transactions_Size(client) self.fees: MetricsTree_Transactions_Fees = MetricsTree_Transactions_Fees(client) self.versions: MetricsTree_Transactions_Versions = MetricsTree_Transactions_Versions(client) self.volume: MetricsTree_Transactions_Volume = MetricsTree_Transactions_Volume(client) +class MetricsTree_Inputs_Raw: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.first_txinindex: MetricPattern18[TxInIndex] = MetricPattern18(client, 'first_txinindex') + self.outpoint: MetricPattern20[OutPoint] = MetricPattern20(client, 'outpoint') + self.txindex: MetricPattern20[TxIndex] = MetricPattern20(client, 'txindex') + self.outputtype: MetricPattern20[OutputType] = MetricPattern20(client, 'outputtype') + self.typeindex: MetricPattern20[TypeIndex] = MetricPattern20(client, 'typeindex') + class MetricsTree_Inputs_Spent: """Metrics tree node.""" @@ -3526,14 +3553,20 @@ class MetricsTree_Inputs: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.first_txinindex: MetricPattern18[TxInIndex] = MetricPattern18(client, 'first_txinindex') - self.outpoint: MetricPattern20[OutPoint] = MetricPattern20(client, 'outpoint') - self.txindex: MetricPattern20[TxIndex] = MetricPattern20(client, 'txindex') - self.outputtype: MetricPattern20[OutputType] = MetricPattern20(client, 'outputtype') - self.typeindex: MetricPattern20[TypeIndex] = MetricPattern20(client, 'typeindex') + self.raw: MetricsTree_Inputs_Raw = MetricsTree_Inputs_Raw(client) self.spent: MetricsTree_Inputs_Spent = MetricsTree_Inputs_Spent(client) self.count: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern = AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern(client, 'input_count') +class MetricsTree_Outputs_Raw: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.first_txoutindex: MetricPattern18[TxOutIndex] = MetricPattern18(client, 'first_txoutindex') + self.value: MetricPattern21[Sats] = MetricPattern21(client, 'value') + self.outputtype: MetricPattern21[OutputType] = MetricPattern21(client, 'outputtype') + self.typeindex: MetricPattern21[TypeIndex] = MetricPattern21(client, 'typeindex') + self.txindex: MetricPattern21[TxIndex] = MetricPattern21(client, 'txindex') + class MetricsTree_Outputs_Spent: """Metrics tree node.""" @@ -3545,40 +3578,127 @@ class MetricsTree_Outputs_Count: def __init__(self, client: BrkClientBase, base_path: str = ''): self.total: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern = AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern(client, 'output_count') - self.utxo_count: MetricPattern1[StoredU64] = MetricPattern1(client, 'exact_utxo_count') + self.unspent: MetricPattern1[StoredU64] = MetricPattern1(client, 'exact_utxo_count') class MetricsTree_Outputs: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.first_txoutindex: MetricPattern18[TxOutIndex] = MetricPattern18(client, 'first_txoutindex') - self.value: MetricPattern21[Sats] = MetricPattern21(client, 'value') - self.outputtype: MetricPattern21[OutputType] = MetricPattern21(client, 'outputtype') - self.typeindex: MetricPattern21[TypeIndex] = MetricPattern21(client, 'typeindex') - self.txindex: MetricPattern21[TxIndex] = MetricPattern21(client, 'txindex') + self.raw: MetricsTree_Outputs_Raw = MetricsTree_Outputs_Raw(client) self.spent: MetricsTree_Outputs_Spent = MetricsTree_Outputs_Spent(client) self.count: MetricsTree_Outputs_Count = MetricsTree_Outputs_Count(client) +class MetricsTree_Addresses_Raw_P2pk65: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.first_index: MetricPattern18[P2PK65AddressIndex] = MetricPattern18(client, 'first_p2pk65addressindex') + self.bytes: MetricPattern27[P2PK65Bytes] = MetricPattern27(client, 'p2pk65bytes') + +class MetricsTree_Addresses_Raw_P2pk33: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.first_index: MetricPattern18[P2PK33AddressIndex] = MetricPattern18(client, 'first_p2pk33addressindex') + self.bytes: MetricPattern26[P2PK33Bytes] = MetricPattern26(client, 'p2pk33bytes') + +class MetricsTree_Addresses_Raw_P2pkh: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.first_index: MetricPattern18[P2PKHAddressIndex] = MetricPattern18(client, 'first_p2pkhaddressindex') + self.bytes: MetricPattern28[P2PKHBytes] = MetricPattern28(client, 'p2pkhbytes') + +class MetricsTree_Addresses_Raw_P2sh: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.first_index: MetricPattern18[P2SHAddressIndex] = MetricPattern18(client, 'first_p2shaddressindex') + self.bytes: MetricPattern29[P2SHBytes] = MetricPattern29(client, 'p2shbytes') + +class MetricsTree_Addresses_Raw_P2wpkh: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.first_index: MetricPattern18[P2WPKHAddressIndex] = MetricPattern18(client, 'first_p2wpkhaddressindex') + self.bytes: MetricPattern31[P2WPKHBytes] = MetricPattern31(client, 'p2wpkhbytes') + +class MetricsTree_Addresses_Raw_P2wsh: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.first_index: MetricPattern18[P2WSHAddressIndex] = MetricPattern18(client, 'first_p2wshaddressindex') + self.bytes: MetricPattern32[P2WSHBytes] = MetricPattern32(client, 'p2wshbytes') + +class MetricsTree_Addresses_Raw_P2tr: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.first_index: MetricPattern18[P2TRAddressIndex] = MetricPattern18(client, 'first_p2traddressindex') + self.bytes: MetricPattern30[P2TRBytes] = MetricPattern30(client, 'p2trbytes') + +class MetricsTree_Addresses_Raw_P2a: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.first_index: MetricPattern18[P2AAddressIndex] = MetricPattern18(client, 'first_p2aaddressindex') + self.bytes: MetricPattern24[P2ABytes] = MetricPattern24(client, 'p2abytes') + +class MetricsTree_Addresses_Raw: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.p2pk65: MetricsTree_Addresses_Raw_P2pk65 = MetricsTree_Addresses_Raw_P2pk65(client) + self.p2pk33: MetricsTree_Addresses_Raw_P2pk33 = MetricsTree_Addresses_Raw_P2pk33(client) + self.p2pkh: MetricsTree_Addresses_Raw_P2pkh = MetricsTree_Addresses_Raw_P2pkh(client) + self.p2sh: MetricsTree_Addresses_Raw_P2sh = MetricsTree_Addresses_Raw_P2sh(client) + self.p2wpkh: MetricsTree_Addresses_Raw_P2wpkh = MetricsTree_Addresses_Raw_P2wpkh(client) + self.p2wsh: MetricsTree_Addresses_Raw_P2wsh = MetricsTree_Addresses_Raw_P2wsh(client) + self.p2tr: MetricsTree_Addresses_Raw_P2tr = MetricsTree_Addresses_Raw_P2tr(client) + self.p2a: MetricsTree_Addresses_Raw_P2a = MetricsTree_Addresses_Raw_P2a(client) + class MetricsTree_Addresses: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.first_p2pk65addressindex: MetricPattern18[P2PK65AddressIndex] = MetricPattern18(client, 'first_p2pk65addressindex') - self.first_p2pk33addressindex: MetricPattern18[P2PK33AddressIndex] = MetricPattern18(client, 'first_p2pk33addressindex') - self.first_p2pkhaddressindex: MetricPattern18[P2PKHAddressIndex] = MetricPattern18(client, 'first_p2pkhaddressindex') - self.first_p2shaddressindex: MetricPattern18[P2SHAddressIndex] = MetricPattern18(client, 'first_p2shaddressindex') - self.first_p2wpkhaddressindex: MetricPattern18[P2WPKHAddressIndex] = MetricPattern18(client, 'first_p2wpkhaddressindex') - self.first_p2wshaddressindex: MetricPattern18[P2WSHAddressIndex] = MetricPattern18(client, 'first_p2wshaddressindex') - self.first_p2traddressindex: MetricPattern18[P2TRAddressIndex] = MetricPattern18(client, 'first_p2traddressindex') - self.first_p2aaddressindex: MetricPattern18[P2AAddressIndex] = MetricPattern18(client, 'first_p2aaddressindex') - self.p2pk65bytes: MetricPattern27[P2PK65Bytes] = MetricPattern27(client, 'p2pk65bytes') - self.p2pk33bytes: MetricPattern26[P2PK33Bytes] = MetricPattern26(client, 'p2pk33bytes') - self.p2pkhbytes: MetricPattern28[P2PKHBytes] = MetricPattern28(client, 'p2pkhbytes') - self.p2shbytes: MetricPattern29[P2SHBytes] = MetricPattern29(client, 'p2shbytes') - self.p2wpkhbytes: MetricPattern31[P2WPKHBytes] = MetricPattern31(client, 'p2wpkhbytes') - self.p2wshbytes: MetricPattern32[P2WSHBytes] = MetricPattern32(client, 'p2wshbytes') - self.p2trbytes: MetricPattern30[P2TRBytes] = MetricPattern30(client, 'p2trbytes') - self.p2abytes: MetricPattern24[P2ABytes] = MetricPattern24(client, 'p2abytes') + self.raw: MetricsTree_Addresses_Raw = MetricsTree_Addresses_Raw(client) + +class MetricsTree_Scripts_Raw_Empty: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.first_index: MetricPattern18[EmptyOutputIndex] = MetricPattern18(client, 'first_emptyoutputindex') + self.to_txindex: MetricPattern22[TxIndex] = MetricPattern22(client, 'txindex') + +class MetricsTree_Scripts_Raw_Opreturn: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.first_index: MetricPattern18[OpReturnIndex] = MetricPattern18(client, 'first_opreturnindex') + self.to_txindex: MetricPattern23[TxIndex] = MetricPattern23(client, 'txindex') + +class MetricsTree_Scripts_Raw_P2ms: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.first_index: MetricPattern18[P2MSOutputIndex] = MetricPattern18(client, 'first_p2msoutputindex') + self.to_txindex: MetricPattern25[TxIndex] = MetricPattern25(client, 'txindex') + +class MetricsTree_Scripts_Raw_Unknown: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.first_index: MetricPattern18[UnknownOutputIndex] = MetricPattern18(client, 'first_unknownoutputindex') + self.to_txindex: MetricPattern33[TxIndex] = MetricPattern33(client, 'txindex') + +class MetricsTree_Scripts_Raw: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.empty: MetricsTree_Scripts_Raw_Empty = MetricsTree_Scripts_Raw_Empty(client) + self.opreturn: MetricsTree_Scripts_Raw_Opreturn = MetricsTree_Scripts_Raw_Opreturn(client) + self.p2ms: MetricsTree_Scripts_Raw_P2ms = MetricsTree_Scripts_Raw_P2ms(client) + self.unknown: MetricsTree_Scripts_Raw_Unknown = MetricsTree_Scripts_Raw_Unknown(client) class MetricsTree_Scripts_Count: """Metrics tree node.""" @@ -3598,11 +3718,18 @@ class MetricsTree_Scripts_Count: self.unknownoutput: CumulativeRawSumPattern[StoredU64] = CumulativeRawSumPattern(client, 'unknownoutput_count') self.segwit: CumulativeRawSumPattern[StoredU64] = CumulativeRawSumPattern(client, 'segwit_count') +class MetricsTree_Scripts_Value_Opreturn: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.base: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, 'opreturn_value') + self.cumulative: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, 'opreturn_value_cumulative') + class MetricsTree_Scripts_Value: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.opreturn: BaseCumulativePattern = BaseCumulativePattern(client, 'opreturn_value') + self.opreturn: MetricsTree_Scripts_Value_Opreturn = MetricsTree_Scripts_Value_Opreturn(client) class MetricsTree_Scripts_Adoption: """Metrics tree node.""" @@ -3615,18 +3742,29 @@ class MetricsTree_Scripts: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.first_emptyoutputindex: MetricPattern18[EmptyOutputIndex] = MetricPattern18(client, 'first_emptyoutputindex') - self.first_opreturnindex: MetricPattern18[OpReturnIndex] = MetricPattern18(client, 'first_opreturnindex') - self.first_p2msoutputindex: MetricPattern18[P2MSOutputIndex] = MetricPattern18(client, 'first_p2msoutputindex') - self.first_unknownoutputindex: MetricPattern18[UnknownOutputIndex] = MetricPattern18(client, 'first_unknownoutputindex') - self.empty_to_txindex: MetricPattern22[TxIndex] = MetricPattern22(client, 'txindex') - self.opreturn_to_txindex: MetricPattern23[TxIndex] = MetricPattern23(client, 'txindex') - self.p2ms_to_txindex: MetricPattern25[TxIndex] = MetricPattern25(client, 'txindex') - self.unknown_to_txindex: MetricPattern33[TxIndex] = MetricPattern33(client, 'txindex') + self.raw: MetricsTree_Scripts_Raw = MetricsTree_Scripts_Raw(client) self.count: MetricsTree_Scripts_Count = MetricsTree_Scripts_Count(client) self.value: MetricsTree_Scripts_Value = MetricsTree_Scripts_Value(client) self.adoption: MetricsTree_Scripts_Adoption = MetricsTree_Scripts_Adoption(client) +class MetricsTree_Mining_Rewards_Subsidy: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.base: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, 'subsidy') + self.cumulative: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, 'subsidy_cumulative') + self.dominance: _1m1w1y24hBpsPercentRatioPattern = _1m1w1y24hBpsPercentRatioPattern(client, 'subsidy_dominance') + self.sma_1y: CentsUsdPattern = CentsUsdPattern(client, 'subsidy_sma_1y') + +class MetricsTree_Mining_Rewards_Fees_RatioMultiple: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self._24h: BpsRatioPattern = BpsRatioPattern(client, 'fee_ratio_multiple_24h') + self._1w: BpsRatioPattern = BpsRatioPattern(client, 'fee_ratio_multiple_1w') + self._1m: BpsRatioPattern = BpsRatioPattern(client, 'fee_ratio_multiple_1m') + self._1y: BpsRatioPattern = BpsRatioPattern(client, 'fee_ratio_multiple_1y') + class MetricsTree_Mining_Rewards_Fees: """Metrics tree node.""" @@ -3637,28 +3775,17 @@ class MetricsTree_Mining_Rewards_Fees: self._1w: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2 = AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2(client, 'fees_1w') self._1m: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2 = AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2(client, 'fees_1m') self._1y: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2 = AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern2(client, 'fees_1y') - -class MetricsTree_Mining_Rewards_FeeRatioMultiple: - """Metrics tree node.""" - - def __init__(self, client: BrkClientBase, base_path: str = ''): - self._24h: BpsRatioPattern = BpsRatioPattern(client, 'fee_ratio_multiple_24h') - self._1w: BpsRatioPattern = BpsRatioPattern(client, 'fee_ratio_multiple_1w') - self._1m: BpsRatioPattern = BpsRatioPattern(client, 'fee_ratio_multiple_1m') - self._1y: BpsRatioPattern = BpsRatioPattern(client, 'fee_ratio_multiple_1y') + self.dominance: _1m1w1y24hBpsPercentRatioPattern = _1m1w1y24hBpsPercentRatioPattern(client, 'fee_dominance') + self.ratio_multiple: MetricsTree_Mining_Rewards_Fees_RatioMultiple = MetricsTree_Mining_Rewards_Fees_RatioMultiple(client) class MetricsTree_Mining_Rewards: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): self.coinbase: BaseCumulativeSumPattern = BaseCumulativeSumPattern(client, 'coinbase') - self.subsidy: BaseCumulativePattern = BaseCumulativePattern(client, 'subsidy') + self.subsidy: MetricsTree_Mining_Rewards_Subsidy = MetricsTree_Mining_Rewards_Subsidy(client) self.fees: MetricsTree_Mining_Rewards_Fees = MetricsTree_Mining_Rewards_Fees(client) - self.unclaimed_rewards: BaseCumulativeSumPattern = BaseCumulativeSumPattern(client, 'unclaimed_rewards') - self.fee_dominance: _1m1w1y24hBpsPercentRatioPattern = _1m1w1y24hBpsPercentRatioPattern(client, 'fee_dominance') - self.subsidy_dominance: _1m1w1y24hBpsPercentRatioPattern = _1m1w1y24hBpsPercentRatioPattern(client, 'subsidy_dominance') - self.subsidy_sma_1y: CentsUsdPattern = CentsUsdPattern(client, 'subsidy_sma_1y') - self.fee_ratio_multiple: MetricsTree_Mining_Rewards_FeeRatioMultiple = MetricsTree_Mining_Rewards_FeeRatioMultiple(client) + self.unclaimed: BaseCumulativeSumPattern = BaseCumulativeSumPattern(client, 'unclaimed_rewards') class MetricsTree_Mining_Hashrate_Rate_Sma: """Metrics tree node.""" @@ -4098,7 +4225,7 @@ class MetricsTree_Market_Ath: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'price_ath') + self.high: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'price_ath') self.drawdown: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'price_drawdown') self.days_since: MetricPattern1[StoredF32] = MetricPattern1(client, 'days_since_price_ath') self.years_since: MetricPattern2[StoredF32] = MetricPattern2(client, 'years_since_price_ath') @@ -4677,7 +4804,7 @@ class MetricsTree_Prices_Ohlc: self.usd: MetricPattern2[OHLCDollars] = MetricPattern2(client, 'price_ohlc') self.sats: MetricPattern2[OHLCSats] = MetricPattern2(client, 'price_ohlc_sats') -class MetricsTree_Prices_Price: +class MetricsTree_Prices_Spot: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -4691,9 +4818,9 @@ class MetricsTree_Prices: def __init__(self, client: BrkClientBase, base_path: str = ''): self.split: MetricsTree_Prices_Split = MetricsTree_Prices_Split(client) self.ohlc: MetricsTree_Prices_Ohlc = MetricsTree_Prices_Ohlc(client) - self.price: MetricsTree_Prices_Price = MetricsTree_Prices_Price(client) + self.spot: MetricsTree_Prices_Spot = MetricsTree_Prices_Spot(client) -class MetricsTree_Distribution_AnyAddressIndexes: +class MetricsTree_Distribution_Addresses_Indexes: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -4705,25 +4832,82 @@ class MetricsTree_Distribution_AnyAddressIndexes: self.p2tr: MetricPattern30[AnyAddressIndex] = MetricPattern30(client, 'anyaddressindex') self.p2wpkh: MetricPattern31[AnyAddressIndex] = MetricPattern31(client, 'anyaddressindex') self.p2wsh: MetricPattern32[AnyAddressIndex] = MetricPattern32(client, 'anyaddressindex') + self.funded: MetricPattern34[FundedAddressIndex] = MetricPattern34(client, 'funded_address_index') + self.empty: MetricPattern35[EmptyAddressIndex] = MetricPattern35(client, 'empty_address_index') -class MetricsTree_Distribution_AddressesData: +class MetricsTree_Distribution_Addresses_Data: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): self.funded: MetricPattern34[FundedAddressData] = MetricPattern34(client, 'fundedaddressdata') self.empty: MetricPattern35[EmptyAddressData] = MetricPattern35(client, 'emptyaddressdata') -class MetricsTree_Distribution_UtxoCohorts_All_Supply: +class MetricsTree_Distribution_Addresses_Activity: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.delta: ChangeRatePattern2 = ChangeRatePattern2(client, 'supply_delta') + self.all: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'address_activity') + self.p2pk65: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'p2pk65_address_activity') + self.p2pk33: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'p2pk33_address_activity') + self.p2pkh: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'p2pkh_address_activity') + self.p2sh: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'p2sh_address_activity') + self.p2wpkh: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'p2wpkh_address_activity') + self.p2wsh: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'p2wsh_address_activity') + self.p2tr: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'p2tr_address_activity') + self.p2a: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'p2a_address_activity') + +class MetricsTree_Distribution_Addresses_New: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.all: RawSumPattern[StoredU64] = RawSumPattern(client, 'new_addr_count') + self.p2pk65: RawSumPattern[StoredU64] = RawSumPattern(client, 'p2pk65_new_addr_count') + self.p2pk33: RawSumPattern[StoredU64] = RawSumPattern(client, 'p2pk33_new_addr_count') + self.p2pkh: RawSumPattern[StoredU64] = RawSumPattern(client, 'p2pkh_new_addr_count') + self.p2sh: RawSumPattern[StoredU64] = RawSumPattern(client, 'p2sh_new_addr_count') + self.p2wpkh: RawSumPattern[StoredU64] = RawSumPattern(client, 'p2wpkh_new_addr_count') + self.p2wsh: RawSumPattern[StoredU64] = RawSumPattern(client, 'p2wsh_new_addr_count') + self.p2tr: RawSumPattern[StoredU64] = RawSumPattern(client, 'p2tr_new_addr_count') + self.p2a: RawSumPattern[StoredU64] = RawSumPattern(client, 'p2a_new_addr_count') + +class MetricsTree_Distribution_Addresses_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') + +class MetricsTree_Distribution_Addresses: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.indexes: MetricsTree_Distribution_Addresses_Indexes = MetricsTree_Distribution_Addresses_Indexes(client) + self.data: MetricsTree_Distribution_Addresses_Data = MetricsTree_Distribution_Addresses_Data(client) + self.funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(client, 'addr_count') + self.empty: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(client, 'empty_addr_count') + self.activity: MetricsTree_Distribution_Addresses_Activity = MetricsTree_Distribution_Addresses_Activity(client) + self.total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(client, 'total_addr_count') + self.new: MetricsTree_Distribution_Addresses_New = MetricsTree_Distribution_Addresses_New(client) + self.delta: MetricsTree_Distribution_Addresses_Delta = MetricsTree_Distribution_Addresses_Delta(client) + +class MetricsTree_Distribution_Cohorts_Utxo_All_Supply: + """Metrics tree node.""" + + def __init__(self, client: BrkClientBase, base_path: str = ''): + self.delta: ChangeRatePattern = ChangeRatePattern(client, 'supply_delta') self.in_profit: BtcCentsRelSatsUsdPattern2 = BtcCentsRelSatsUsdPattern2(client, 'supply_in_profit') self.in_loss: BtcCentsRelSatsUsdPattern2 = BtcCentsRelSatsUsdPattern2(client, 'supply_in_loss') self.total: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, 'supply') self.halved: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, 'supply_halved') -class MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Loss: +class MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Loss: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -4731,26 +4915,26 @@ class MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Loss: self.raw: CentsUsdPattern = CentsUsdPattern(client, 'unrealized_loss') self.sum: _24hPattern = _24hPattern(client, 'unrealized_loss_24h') self.rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'unrealized_loss_rel_to_market_cap') - self.rel_to_own_gross_pnl: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'unrealized_loss_rel_to_own_gross_pnl') + self.rel_to_own_gross: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'unrealized_loss_rel_to_own_gross_pnl') -class MetricsTree_Distribution_UtxoCohorts_All_Unrealized_NetPnl: +class MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_NetPnl: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): self.cents: MetricPattern1[CentsSigned] = MetricPattern1(client, 'net_unrealized_pnl_cents') self.usd: MetricPattern1[Dollars] = MetricPattern1(client, 'net_unrealized_pnl') - self.rel_to_own_gross_pnl: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'net_unrealized_pnl_rel_to_own_gross_pnl') + self.rel_to_own_gross: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'net_unrealized_pnl_rel_to_own_gross_pnl') -class MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Profit: +class MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Profit: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): self.raw: CentsUsdPattern = CentsUsdPattern(client, 'unrealized_profit') self.sum: _24hPattern = _24hPattern(client, 'unrealized_profit_24h') self.rel_to_market_cap: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'unrealized_profit_rel_to_market_cap') - self.rel_to_own_gross_pnl: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'unrealized_profit_rel_to_own_gross_pnl') + self.rel_to_own_gross: BpsPercentRatioPattern = BpsPercentRatioPattern(client, 'unrealized_profit_rel_to_own_gross_pnl') -class MetricsTree_Distribution_UtxoCohorts_All_Unrealized: +class MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -4758,22 +4942,22 @@ class MetricsTree_Distribution_UtxoCohorts_All_Unrealized: self.invested_capital: InPattern2 = InPattern2(client, 'invested_capital_in') self.sentiment: GreedNetPainPattern = GreedNetPainPattern(client, '') self.investor_cap: InPattern = InPattern(client, 'investor_cap_in') - self.loss: MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Loss = MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Loss(client) - self.net_pnl: MetricsTree_Distribution_UtxoCohorts_All_Unrealized_NetPnl = MetricsTree_Distribution_UtxoCohorts_All_Unrealized_NetPnl(client) - self.profit: MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Profit = MetricsTree_Distribution_UtxoCohorts_All_Unrealized_Profit(client) + self.loss: MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Loss = MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Loss(client) + self.net_pnl: MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_NetPnl = MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_NetPnl(client) + self.profit: MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Profit = MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized_Profit(client) -class MetricsTree_Distribution_UtxoCohorts_All: +class MetricsTree_Distribution_Cohorts_Utxo_All: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.supply: MetricsTree_Distribution_UtxoCohorts_All_Supply = MetricsTree_Distribution_UtxoCohorts_All_Supply(client) + self.supply: MetricsTree_Distribution_Cohorts_Utxo_All_Supply = MetricsTree_Distribution_Cohorts_Utxo_All_Supply(client) self.outputs: UnspentPattern3 = UnspentPattern3(client, 'utxo_count') self.activity: CoindaysCoinyearsDormancySentVelocityPattern = CoindaysCoinyearsDormancySentVelocityPattern(client, '') self.realized: CapGrossInvestorLossMvrvNetNuplPeakPriceProfitSoprPattern = CapGrossInvestorLossMvrvNetNuplPeakPriceProfitSoprPattern(client, '') self.cost_basis: InvestedMaxMinPercentilesSupplyPattern = InvestedMaxMinPercentilesSupplyPattern(client, '') - self.unrealized: MetricsTree_Distribution_UtxoCohorts_All_Unrealized = MetricsTree_Distribution_UtxoCohorts_All_Unrealized(client) + self.unrealized: MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized = MetricsTree_Distribution_Cohorts_Utxo_All_Unrealized(client) -class MetricsTree_Distribution_UtxoCohorts_Sth: +class MetricsTree_Distribution_Cohorts_Utxo_Sth: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -4784,29 +4968,29 @@ class MetricsTree_Distribution_UtxoCohorts_Sth: self.cost_basis: InvestedMaxMinPercentilesSupplyPattern = InvestedMaxMinPercentilesSupplyPattern(client, 'sth') self.unrealized: GrossInvestedInvestorLossNetProfitSentimentPattern2 = GrossInvestedInvestorLossNetProfitSentimentPattern2(client, 'sth') -class MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueCreated: +class MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueCreated: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): self.sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, 'lth_value_created') self.raw: MetricPattern1[Cents] = MetricPattern1(client, 'lth_value_created') -class MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueDestroyed: +class MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueDestroyed: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): self.sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, 'lth_value_destroyed') self.raw: MetricPattern1[Cents] = MetricPattern1(client, 'lth_value_destroyed') -class MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr: +class MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.value_created: MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueCreated = MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueCreated(client) - self.value_destroyed: MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueDestroyed = MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr_ValueDestroyed(client) + self.value_created: MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueCreated = MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueCreated(client) + self.value_destroyed: MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueDestroyed = MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr_ValueDestroyed(client) self.ratio: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, 'lth_sopr') -class MetricsTree_Distribution_UtxoCohorts_Lth_Realized: +class MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -4814,7 +4998,7 @@ class MetricsTree_Distribution_UtxoCohorts_Lth_Realized: self.loss: CapitulationCumulativeNegativeRawRelSumValuePattern = CapitulationCumulativeNegativeRawRelSumValuePattern(client, 'lth') self.gross_pnl: RawSellSumPattern = RawSellSumPattern(client, 'lth') self.net_pnl: ChangeCumulativeDeltaRawRelSumPattern = ChangeCumulativeDeltaRawRelSumPattern(client, 'lth_net') - self.sopr: MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr = MetricsTree_Distribution_UtxoCohorts_Lth_Realized_Sopr(client) + self.sopr: MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr = MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized_Sopr(client) self.peak_regret: CumulativeRawRelPattern = CumulativeRawRelPattern(client, 'lth_realized_peak_regret') self.investor: CapLowerPriceUpperPattern = CapLowerPriceUpperPattern(client, 'lth') self.profit_to_loss_ratio: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, 'lth_realized_profit_to_loss_ratio') @@ -4823,18 +5007,18 @@ class MetricsTree_Distribution_UtxoCohorts_Lth_Realized: self.mvrv: MetricPattern1[StoredF32] = MetricPattern1(client, 'lth_mvrv') self.nupl: BpsRatioPattern = BpsRatioPattern(client, 'lth_nupl_ratio') -class MetricsTree_Distribution_UtxoCohorts_Lth: +class MetricsTree_Distribution_Cohorts_Utxo_Lth: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): self.supply: DeltaHalvedInRelTotalPattern2 = DeltaHalvedInRelTotalPattern2(client, 'lth_supply') self.outputs: UnspentPattern3 = UnspentPattern3(client, 'lth_utxo_count') self.activity: CoindaysCoinyearsDormancySentVelocityPattern = CoindaysCoinyearsDormancySentVelocityPattern(client, 'lth') - self.realized: MetricsTree_Distribution_UtxoCohorts_Lth_Realized = MetricsTree_Distribution_UtxoCohorts_Lth_Realized(client) + self.realized: MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized = MetricsTree_Distribution_Cohorts_Utxo_Lth_Realized(client) self.cost_basis: InvestedMaxMinPercentilesSupplyPattern = InvestedMaxMinPercentilesSupplyPattern(client, 'lth') self.unrealized: GrossInvestedInvestorLossNetProfitSentimentPattern2 = GrossInvestedInvestorLossNetProfitSentimentPattern2(client, 'lth') -class MetricsTree_Distribution_UtxoCohorts_AgeRange: +class MetricsTree_Distribution_Cohorts_Utxo_AgeRange: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -4860,7 +5044,7 @@ class MetricsTree_Distribution_UtxoCohorts_AgeRange: self._12y_to_15y: ActivityOutputsRealizedSupplyUnrealizedPattern = ActivityOutputsRealizedSupplyUnrealizedPattern(client, 'utxos_12y_to_15y_old') self.from_15y: ActivityOutputsRealizedSupplyUnrealizedPattern = ActivityOutputsRealizedSupplyUnrealizedPattern(client, 'utxos_over_15y_old') -class MetricsTree_Distribution_UtxoCohorts_MaxAge: +class MetricsTree_Distribution_Cohorts_Utxo_MaxAge: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -4883,7 +5067,7 @@ class MetricsTree_Distribution_UtxoCohorts_MaxAge: self._12y: ActivityOutputsRealizedSupplyUnrealizedPattern2 = ActivityOutputsRealizedSupplyUnrealizedPattern2(client, 'utxos_under_12y_old') self._15y: ActivityOutputsRealizedSupplyUnrealizedPattern2 = ActivityOutputsRealizedSupplyUnrealizedPattern2(client, 'utxos_under_15y_old') -class MetricsTree_Distribution_UtxoCohorts_MinAge: +class MetricsTree_Distribution_Cohorts_Utxo_MinAge: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -4906,7 +5090,7 @@ class MetricsTree_Distribution_UtxoCohorts_MinAge: self._10y: ActivityOutputsRealizedSupplyUnrealizedPattern2 = ActivityOutputsRealizedSupplyUnrealizedPattern2(client, 'utxos_over_10y_old') self._12y: ActivityOutputsRealizedSupplyUnrealizedPattern2 = ActivityOutputsRealizedSupplyUnrealizedPattern2(client, 'utxos_over_12y_old') -class MetricsTree_Distribution_UtxoCohorts_Epoch: +class MetricsTree_Distribution_Cohorts_Utxo_Epoch: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -4916,7 +5100,7 @@ class MetricsTree_Distribution_UtxoCohorts_Epoch: self._3: ActivityOutputsRealizedSupplyUnrealizedPattern2 = ActivityOutputsRealizedSupplyUnrealizedPattern2(client, 'epoch_3') self._4: ActivityOutputsRealizedSupplyUnrealizedPattern2 = ActivityOutputsRealizedSupplyUnrealizedPattern2(client, 'epoch_4') -class MetricsTree_Distribution_UtxoCohorts_Class: +class MetricsTree_Distribution_Cohorts_Utxo_Class: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -4939,7 +5123,7 @@ class MetricsTree_Distribution_UtxoCohorts_Class: self._2025: ActivityOutputsRealizedSupplyUnrealizedPattern2 = ActivityOutputsRealizedSupplyUnrealizedPattern2(client, 'class_2025') self._2026: ActivityOutputsRealizedSupplyUnrealizedPattern2 = ActivityOutputsRealizedSupplyUnrealizedPattern2(client, 'class_2026') -class MetricsTree_Distribution_UtxoCohorts_GeAmount: +class MetricsTree_Distribution_Cohorts_Utxo_GeAmount: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -4957,7 +5141,7 @@ class MetricsTree_Distribution_UtxoCohorts_GeAmount: self._1k_btc: OutputsRealizedSupplyPattern = OutputsRealizedSupplyPattern(client, 'utxos_over_1k_btc') self._10k_btc: OutputsRealizedSupplyPattern = OutputsRealizedSupplyPattern(client, 'utxos_over_10k_btc') -class MetricsTree_Distribution_UtxoCohorts_AmountRange: +class MetricsTree_Distribution_Cohorts_Utxo_AmountRange: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -4977,7 +5161,7 @@ class MetricsTree_Distribution_UtxoCohorts_AmountRange: self._10k_btc_to_100k_btc: OutputsRealizedSupplyPattern = OutputsRealizedSupplyPattern(client, 'utxos_above_10k_btc_under_100k_btc') self._100k_btc_or_more: OutputsRealizedSupplyPattern = OutputsRealizedSupplyPattern(client, 'utxos_above_100k_btc') -class MetricsTree_Distribution_UtxoCohorts_LtAmount: +class MetricsTree_Distribution_Cohorts_Utxo_LtAmount: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -4995,7 +5179,7 @@ class MetricsTree_Distribution_UtxoCohorts_LtAmount: self._10k_btc: OutputsRealizedSupplyPattern = OutputsRealizedSupplyPattern(client, 'utxos_under_10k_btc') self._100k_btc: OutputsRealizedSupplyPattern = OutputsRealizedSupplyPattern(client, 'utxos_under_100k_btc') -class MetricsTree_Distribution_UtxoCohorts_Type: +class MetricsTree_Distribution_Cohorts_Utxo_Type: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -5011,37 +5195,37 @@ class MetricsTree_Distribution_UtxoCohorts_Type: self.unknown: OutputsRealizedSupplyUnrealizedPattern = OutputsRealizedSupplyUnrealizedPattern(client, 'unknown_outputs') self.empty: OutputsRealizedSupplyUnrealizedPattern = OutputsRealizedSupplyUnrealizedPattern(client, 'empty_outputs') -class MetricsTree_Distribution_UtxoCohorts_Profitability_Range: +class MetricsTree_Distribution_Cohorts_Utxo_Profitability_Range: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.profit_over_1000: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_over_1000pct') - self.profit_500_to_1000: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_500_to_1000pct') - self.profit_300_to_500: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_300_to_500pct') - self.profit_200_to_300: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_200_to_300pct') - self.profit_100_to_200: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_100_to_200pct') - self.profit_90_to_100: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_90_to_100pct') - self.profit_80_to_90: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_80_to_90pct') - self.profit_70_to_80: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_70_to_80pct') - self.profit_60_to_70: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_60_to_70pct') - self.profit_50_to_60: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_50_to_60pct') - self.profit_40_to_50: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_40_to_50pct') - self.profit_30_to_40: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_30_to_40pct') - self.profit_20_to_30: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_20_to_30pct') - self.profit_10_to_20: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_10_to_20pct') - self.profit_0_to_10: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_0_to_10pct') - self.loss_0_to_10: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_0_to_10pct') - self.loss_10_to_20: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_10_to_20pct') - self.loss_20_to_30: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_20_to_30pct') - self.loss_30_to_40: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_30_to_40pct') - self.loss_40_to_50: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_40_to_50pct') - self.loss_50_to_60: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_50_to_60pct') - self.loss_60_to_70: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_60_to_70pct') - self.loss_70_to_80: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_70_to_80pct') - self.loss_80_to_90: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_80_to_90pct') - self.loss_90_to_100: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_90_to_100pct') + self.profit_over_1000: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_1000pct_up') + self.profit_500_to_1000: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_500pct_to_1000pct_up') + self.profit_300_to_500: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_300pct_to_500pct_up') + self.profit_200_to_300: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_200pct_to_300pct_up') + self.profit_100_to_200: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_100pct_to_200pct_up') + self.profit_90_to_100: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_90pct_to_100pct_up') + self.profit_80_to_90: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_80pct_to_90pct_up') + self.profit_70_to_80: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_70pct_to_80pct_up') + self.profit_60_to_70: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_60pct_to_70pct_up') + self.profit_50_to_60: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_50pct_to_60pct_up') + self.profit_40_to_50: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_40pct_to_50pct_up') + self.profit_30_to_40: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_30pct_to_40pct_up') + self.profit_20_to_30: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_20pct_to_30pct_up') + self.profit_10_to_20: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_10pct_to_20pct_up') + self.profit_0_to_10: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_0pct_to_10pct_up') + self.loss_0_to_10: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_0pct_to_10pct_down') + self.loss_10_to_20: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_10pct_to_20pct_down') + self.loss_20_to_30: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_20pct_to_30pct_down') + self.loss_30_to_40: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_30pct_to_40pct_down') + self.loss_40_to_50: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_40pct_to_50pct_down') + self.loss_50_to_60: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_50pct_to_60pct_down') + self.loss_60_to_70: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_60pct_to_70pct_down') + self.loss_70_to_80: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_70pct_to_80pct_down') + self.loss_80_to_90: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_80pct_to_90pct_down') + self.loss_90_to_100: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_90pct_to_100pct_down') -class MetricsTree_Distribution_UtxoCohorts_Profitability_Profit: +class MetricsTree_Distribution_Cohorts_Utxo_Profitability_Profit: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -5061,7 +5245,7 @@ class MetricsTree_Distribution_UtxoCohorts_Profitability_Profit: self._500pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_500pct') self._1000pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_1000pct') -class MetricsTree_Distribution_UtxoCohorts_Profitability_Loss: +class MetricsTree_Distribution_Cohorts_Utxo_Profitability_Loss: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -5076,15 +5260,15 @@ class MetricsTree_Distribution_UtxoCohorts_Profitability_Loss: self._80pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_ge_80pct') self._90pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_ge_90pct') -class MetricsTree_Distribution_UtxoCohorts_Profitability: +class MetricsTree_Distribution_Cohorts_Utxo_Profitability: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.range: MetricsTree_Distribution_UtxoCohorts_Profitability_Range = MetricsTree_Distribution_UtxoCohorts_Profitability_Range(client) - self.profit: MetricsTree_Distribution_UtxoCohorts_Profitability_Profit = MetricsTree_Distribution_UtxoCohorts_Profitability_Profit(client) - self.loss: MetricsTree_Distribution_UtxoCohorts_Profitability_Loss = MetricsTree_Distribution_UtxoCohorts_Profitability_Loss(client) + self.range: MetricsTree_Distribution_Cohorts_Utxo_Profitability_Range = MetricsTree_Distribution_Cohorts_Utxo_Profitability_Range(client) + self.profit: MetricsTree_Distribution_Cohorts_Utxo_Profitability_Profit = MetricsTree_Distribution_Cohorts_Utxo_Profitability_Profit(client) + self.loss: MetricsTree_Distribution_Cohorts_Utxo_Profitability_Loss = MetricsTree_Distribution_Cohorts_Utxo_Profitability_Loss(client) -class MetricsTree_Distribution_UtxoCohorts_Matured: +class MetricsTree_Distribution_Cohorts_Utxo_Matured: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -5110,26 +5294,26 @@ class MetricsTree_Distribution_UtxoCohorts_Matured: self._12y_to_15y: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, 'utxo_12y_to_15y_old_matured') self.from_15y: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, 'utxo_over_15y_old_matured') -class MetricsTree_Distribution_UtxoCohorts: +class MetricsTree_Distribution_Cohorts_Utxo: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.all: MetricsTree_Distribution_UtxoCohorts_All = MetricsTree_Distribution_UtxoCohorts_All(client) - self.sth: MetricsTree_Distribution_UtxoCohorts_Sth = MetricsTree_Distribution_UtxoCohorts_Sth(client) - self.lth: MetricsTree_Distribution_UtxoCohorts_Lth = MetricsTree_Distribution_UtxoCohorts_Lth(client) - self.age_range: MetricsTree_Distribution_UtxoCohorts_AgeRange = MetricsTree_Distribution_UtxoCohorts_AgeRange(client) - self.max_age: MetricsTree_Distribution_UtxoCohorts_MaxAge = MetricsTree_Distribution_UtxoCohorts_MaxAge(client) - self.min_age: MetricsTree_Distribution_UtxoCohorts_MinAge = MetricsTree_Distribution_UtxoCohorts_MinAge(client) - self.epoch: MetricsTree_Distribution_UtxoCohorts_Epoch = MetricsTree_Distribution_UtxoCohorts_Epoch(client) - self.class: MetricsTree_Distribution_UtxoCohorts_Class = MetricsTree_Distribution_UtxoCohorts_Class(client) - self.ge_amount: MetricsTree_Distribution_UtxoCohorts_GeAmount = MetricsTree_Distribution_UtxoCohorts_GeAmount(client) - self.amount_range: MetricsTree_Distribution_UtxoCohorts_AmountRange = MetricsTree_Distribution_UtxoCohorts_AmountRange(client) - self.lt_amount: MetricsTree_Distribution_UtxoCohorts_LtAmount = MetricsTree_Distribution_UtxoCohorts_LtAmount(client) - self.r#type: MetricsTree_Distribution_UtxoCohorts_Type = MetricsTree_Distribution_UtxoCohorts_Type(client) - self.profitability: MetricsTree_Distribution_UtxoCohorts_Profitability = MetricsTree_Distribution_UtxoCohorts_Profitability(client) - self.matured: MetricsTree_Distribution_UtxoCohorts_Matured = MetricsTree_Distribution_UtxoCohorts_Matured(client) + self.all: MetricsTree_Distribution_Cohorts_Utxo_All = MetricsTree_Distribution_Cohorts_Utxo_All(client) + self.sth: MetricsTree_Distribution_Cohorts_Utxo_Sth = MetricsTree_Distribution_Cohorts_Utxo_Sth(client) + self.lth: MetricsTree_Distribution_Cohorts_Utxo_Lth = MetricsTree_Distribution_Cohorts_Utxo_Lth(client) + self.age_range: MetricsTree_Distribution_Cohorts_Utxo_AgeRange = MetricsTree_Distribution_Cohorts_Utxo_AgeRange(client) + self.max_age: MetricsTree_Distribution_Cohorts_Utxo_MaxAge = MetricsTree_Distribution_Cohorts_Utxo_MaxAge(client) + self.min_age: MetricsTree_Distribution_Cohorts_Utxo_MinAge = MetricsTree_Distribution_Cohorts_Utxo_MinAge(client) + self.epoch: MetricsTree_Distribution_Cohorts_Utxo_Epoch = MetricsTree_Distribution_Cohorts_Utxo_Epoch(client) + self.class: MetricsTree_Distribution_Cohorts_Utxo_Class = MetricsTree_Distribution_Cohorts_Utxo_Class(client) + self.ge_amount: MetricsTree_Distribution_Cohorts_Utxo_GeAmount = MetricsTree_Distribution_Cohorts_Utxo_GeAmount(client) + self.amount_range: MetricsTree_Distribution_Cohorts_Utxo_AmountRange = MetricsTree_Distribution_Cohorts_Utxo_AmountRange(client) + self.lt_amount: MetricsTree_Distribution_Cohorts_Utxo_LtAmount = MetricsTree_Distribution_Cohorts_Utxo_LtAmount(client) + self.r#type: MetricsTree_Distribution_Cohorts_Utxo_Type = MetricsTree_Distribution_Cohorts_Utxo_Type(client) + self.profitability: MetricsTree_Distribution_Cohorts_Utxo_Profitability = MetricsTree_Distribution_Cohorts_Utxo_Profitability(client) + self.matured: MetricsTree_Distribution_Cohorts_Utxo_Matured = MetricsTree_Distribution_Cohorts_Utxo_Matured(client) -class MetricsTree_Distribution_AddressCohorts_GeAmount: +class MetricsTree_Distribution_Cohorts_Address_GeAmount: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -5147,7 +5331,7 @@ class MetricsTree_Distribution_AddressCohorts_GeAmount: self._1k_btc: AddrOutputsRealizedSupplyPattern = AddrOutputsRealizedSupplyPattern(client, 'addrs_over_1k_btc') self._10k_btc: AddrOutputsRealizedSupplyPattern = AddrOutputsRealizedSupplyPattern(client, 'addrs_over_10k_btc') -class MetricsTree_Distribution_AddressCohorts_AmountRange: +class MetricsTree_Distribution_Cohorts_Address_AmountRange: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -5167,7 +5351,7 @@ class MetricsTree_Distribution_AddressCohorts_AmountRange: self._10k_btc_to_100k_btc: AddrOutputsRealizedSupplyPattern = AddrOutputsRealizedSupplyPattern(client, 'addrs_above_10k_btc_under_100k_btc') self._100k_btc_or_more: AddrOutputsRealizedSupplyPattern = AddrOutputsRealizedSupplyPattern(client, 'addrs_above_100k_btc') -class MetricsTree_Distribution_AddressCohorts_LtAmount: +class MetricsTree_Distribution_Cohorts_Address_LtAmount: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): @@ -5185,80 +5369,29 @@ class MetricsTree_Distribution_AddressCohorts_LtAmount: self._10k_btc: AddrOutputsRealizedSupplyPattern = AddrOutputsRealizedSupplyPattern(client, 'addrs_under_10k_btc') self._100k_btc: AddrOutputsRealizedSupplyPattern = AddrOutputsRealizedSupplyPattern(client, 'addrs_under_100k_btc') -class MetricsTree_Distribution_AddressCohorts: +class MetricsTree_Distribution_Cohorts_Address: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.ge_amount: MetricsTree_Distribution_AddressCohorts_GeAmount = MetricsTree_Distribution_AddressCohorts_GeAmount(client) - self.amount_range: MetricsTree_Distribution_AddressCohorts_AmountRange = MetricsTree_Distribution_AddressCohorts_AmountRange(client) - self.lt_amount: MetricsTree_Distribution_AddressCohorts_LtAmount = MetricsTree_Distribution_AddressCohorts_LtAmount(client) + self.ge_amount: MetricsTree_Distribution_Cohorts_Address_GeAmount = MetricsTree_Distribution_Cohorts_Address_GeAmount(client) + self.amount_range: MetricsTree_Distribution_Cohorts_Address_AmountRange = MetricsTree_Distribution_Cohorts_Address_AmountRange(client) + self.lt_amount: MetricsTree_Distribution_Cohorts_Address_LtAmount = MetricsTree_Distribution_Cohorts_Address_LtAmount(client) -class MetricsTree_Distribution_Addresses_Activity: +class MetricsTree_Distribution_Cohorts: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.all: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'address_activity') - self.p2pk65: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'p2pk65_address_activity') - self.p2pk33: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'p2pk33_address_activity') - self.p2pkh: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'p2pkh_address_activity') - self.p2sh: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'p2sh_address_activity') - self.p2wpkh: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'p2wpkh_address_activity') - self.p2wsh: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'p2wsh_address_activity') - self.p2tr: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'p2tr_address_activity') - self.p2a: BothReactivatedReceivingSendingPattern = BothReactivatedReceivingSendingPattern(client, 'p2a_address_activity') - -class MetricsTree_Distribution_Addresses_New: - """Metrics tree node.""" - - def __init__(self, client: BrkClientBase, base_path: str = ''): - self.all: RawSumPattern3[StoredU64] = RawSumPattern3(client, 'new_addr_count') - self.p2pk65: RawSumPattern3[StoredU64] = RawSumPattern3(client, 'p2pk65_new_addr_count') - self.p2pk33: RawSumPattern3[StoredU64] = RawSumPattern3(client, 'p2pk33_new_addr_count') - self.p2pkh: RawSumPattern3[StoredU64] = RawSumPattern3(client, 'p2pkh_new_addr_count') - self.p2sh: RawSumPattern3[StoredU64] = RawSumPattern3(client, 'p2sh_new_addr_count') - self.p2wpkh: RawSumPattern3[StoredU64] = RawSumPattern3(client, 'p2wpkh_new_addr_count') - self.p2wsh: RawSumPattern3[StoredU64] = RawSumPattern3(client, 'p2wsh_new_addr_count') - self.p2tr: RawSumPattern3[StoredU64] = RawSumPattern3(client, 'p2tr_new_addr_count') - self.p2a: RawSumPattern3[StoredU64] = RawSumPattern3(client, 'p2a_new_addr_count') - -class MetricsTree_Distribution_Addresses_Delta: - """Metrics tree node.""" - - def __init__(self, client: BrkClientBase, base_path: str = ''): - 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_Addresses: - """Metrics tree node.""" - - def __init__(self, client: BrkClientBase, base_path: str = ''): - self.funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(client, 'addr_count') - self.empty: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(client, 'empty_addr_count') - self.activity: MetricsTree_Distribution_Addresses_Activity = MetricsTree_Distribution_Addresses_Activity(client) - self.total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(client, 'total_addr_count') - self.new: MetricsTree_Distribution_Addresses_New = MetricsTree_Distribution_Addresses_New(client) - self.delta: MetricsTree_Distribution_Addresses_Delta = MetricsTree_Distribution_Addresses_Delta(client) - self.funded_index: MetricPattern34[FundedAddressIndex] = MetricPattern34(client, 'funded_address_index') - self.empty_index: MetricPattern35[EmptyAddressIndex] = MetricPattern35(client, 'empty_address_index') + self.utxo: MetricsTree_Distribution_Cohorts_Utxo = MetricsTree_Distribution_Cohorts_Utxo(client) + self.address: MetricsTree_Distribution_Cohorts_Address = MetricsTree_Distribution_Cohorts_Address(client) class MetricsTree_Distribution: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): self.supply_state: MetricPattern18[SupplyState] = MetricPattern18(client, 'supply_state') - self.any_address_indexes: MetricsTree_Distribution_AnyAddressIndexes = MetricsTree_Distribution_AnyAddressIndexes(client) - self.addresses_data: MetricsTree_Distribution_AddressesData = MetricsTree_Distribution_AddressesData(client) - self.utxo_cohorts: MetricsTree_Distribution_UtxoCohorts = MetricsTree_Distribution_UtxoCohorts(client) - self.address_cohorts: MetricsTree_Distribution_AddressCohorts = MetricsTree_Distribution_AddressCohorts(client) - self.coinblocks_destroyed: CumulativeRawPattern[StoredF64] = CumulativeRawPattern(client, 'coinblocks_destroyed') self.addresses: MetricsTree_Distribution_Addresses = MetricsTree_Distribution_Addresses(client) + self.cohorts: MetricsTree_Distribution_Cohorts = MetricsTree_Distribution_Cohorts(client) + self.coinblocks_destroyed: CumulativeRawPattern[StoredF64] = CumulativeRawPattern(client, 'coinblocks_destroyed') class MetricsTree_Supply_Burned: """Metrics tree node.""" @@ -6429,15 +6562,15 @@ class BrkClient(BrkClientBase): Endpoint: `GET /api/mempool/txids`""" return self.get_json('/api/mempool/txids') - def get_metric_info(self, metric: Metric) -> List[Index]: - """Get supported indexes for a metric. + def get_metric_info(self, metric: Metric) -> MetricInfo: + """Get metric info. - Returns the list of indexes supported by the specified metric. For example, `realized_price` might be available on day1, week1, and month1. + Returns the supported indexes and value type for the specified metric. Endpoint: `GET /api/metric/{metric}`""" return self.get_json(f'/api/metric/{metric}') - def get_metric(self, metric: Metric, index: Index, start: Optional[float] = None, end: Optional[float] = None, limit: Optional[str] = None, format: Optional[Format] = None) -> Union[AnyMetricData, str]: + def get_metric(self, metric: Metric, index: Index, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[str] = None, format: Optional[Format] = None) -> Union[AnyMetricData, str]: """Get metric data. Fetch data for a specific metric at the given index. Use query parameters to filter by date range and format (json/csv). @@ -6454,6 +6587,31 @@ class BrkClient(BrkClientBase): return self.get_text(path) return self.get_json(path) + def get_metric_data(self, metric: Metric, index: Index, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[str] = None, format: Optional[Format] = None) -> Union[List[bool], str]: + """Get raw metric data. + + Returns just the data array without the MetricData wrapper. Supports the same range and format parameters as the standard endpoint. + + Endpoint: `GET /api/metric/{metric}/{index}/data`""" + params = [] + if start is not None: params.append(f'start={start}') + if end is not None: params.append(f'end={end}') + if limit is not None: params.append(f'limit={limit}') + if format is not None: params.append(f'format={format}') + query = '&'.join(params) + path = f'/api/metric/{metric}/{index}/data{"?" + query if query else ""}' + if format == 'csv': + return self.get_text(path) + return self.get_json(path) + + def get_metric_latest(self, metric: Metric, index: Index) -> Any: + """Get latest metric value. + + Returns the single most recent value for a metric, unwrapped (not inside a MetricData object). + + Endpoint: `GET /api/metric/{metric}/{index}/latest`""" + return self.get_json(f'/api/metric/{metric}/{index}/latest') + def get_metrics_tree(self) -> TreeNode: """Metrics catalog. @@ -6462,7 +6620,7 @@ class BrkClient(BrkClientBase): Endpoint: `GET /api/metrics`""" return self.get_json('/api/metrics') - def get_metrics(self, metrics: Metrics, index: Index, start: Optional[float] = None, end: Optional[float] = None, limit: Optional[str] = None, format: Optional[Format] = None) -> Union[List[AnyMetricData], str]: + def get_metrics(self, metrics: Metrics, index: Index, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[str] = None, format: Optional[Format] = None) -> Union[List[AnyMetricData], str]: """Bulk metric data. Fetch multiple metrics in a single request. Supports filtering by index and date range. Returns an array of MetricData objects. For a single metric, use `get_metric` instead. @@ -6542,16 +6700,17 @@ class BrkClient(BrkClientBase): path = f'/api/metrics/list{"?" + query if query else ""}' return self.get_json(path) - def search_metrics(self, metric: Metric, limit: Optional[Limit] = None) -> List[Metric]: + def search_metrics(self, q: Metric, limit: Optional[Limit] = None) -> List[Metric]: """Search metrics. Fuzzy search for metrics by name. Supports partial matches and typos. - Endpoint: `GET /api/metrics/search/{metric}`""" + Endpoint: `GET /api/metrics/search`""" params = [] + params.append(f'q={q}') if limit is not None: params.append(f'limit={limit}') query = '&'.join(params) - path = f'/api/metrics/search/{metric}{"?" + query if query else ""}' + path = f'/api/metrics/search{"?" + query if query else ""}' return self.get_json(path) def get_disk_usage(self) -> DiskUsage: diff --git a/website/llms.txt b/website/llms.txt index d2e50ea1f..2df10e1cd 100644 --- a/website/llms.txt +++ b/website/llms.txt @@ -16,7 +16,11 @@ Free, no auth required. JSON and CSV output. Mempool.space compatible for block/ Search for metrics by keyword: - GET /api/metrics/search/{query} + GET /api/metrics/search?q={query} + +Get metric info (available indexes, value type): + + GET /api/metric/{metric} Browse all available metrics: @@ -35,17 +39,26 @@ Browse the full metric catalog as a tree: Get a metric by name and index: GET /api/metric/{metric}/{index} + GET /api/metric/{metric}/{index}?start=2025-01-01&end=2025-06-01 GET /api/metric/{metric}/{index}?start=-30 +Get just the data array (no wrapper): + + GET /api/metric/{metric}/{index}/data + +Get the latest value: + + GET /api/metric/{metric}/{index}/latest + Example — last 30 days of Bitcoin closing price: - GET /api/metric/close/1d?start=-30 + GET /api/metric/price/day?start=-30 Fetch multiple metrics at once: GET /api/metrics/bulk?index={index}&metrics={metric1},{metric2} -See the `MetricData` schema and query parameters (`start`, `end`, `limit`) in the [OpenAPI spec](https://bitview.space/api.json). +Range parameters `start` and `end` accept integers, dates (YYYY-MM-DD), or ISO 8601 timestamps. See the [OpenAPI spec](https://bitview.space/api.json) for full details. ## Block Explorer