From eedb8d22c107515a4b96288a6d8817b83bdd4d2a Mon Sep 17 00:00:00 2001 From: nym21 Date: Thu, 5 Mar 2026 16:11:25 +0100 Subject: [PATCH] global: snapshot --- crates/brk_bindgen/src/generate/constants.rs | 4 +- crates/brk_client/src/lib.rs | 986 +++++++-------- .../src/{by_year.rs => by_class.rs} | 100 +- crates/brk_cohort/src/cohort_context.rs | 4 +- crates/brk_cohort/src/filter.rs | 2 +- crates/brk_cohort/src/lib.rs | 4 +- crates/brk_cohort/src/utxo.rs | 18 +- crates/brk_computer/.gitignore | 1 + .../distribution/cohorts/address/groups.rs | 9 +- .../src/distribution/cohorts/address/vecs.rs | 17 +- .../src/distribution/cohorts/traits.rs | 8 +- .../src/distribution/cohorts/utxo/groups.rs | 489 +++----- .../distribution/cohorts/utxo/percentiles.rs | 275 +++-- .../src/distribution/cohorts/utxo/receive.rs | 6 +- .../src/distribution/cohorts/utxo/send.rs | 4 +- .../distribution/cohorts/utxo/tick_tock.rs | 30 +- .../src/distribution/cohorts/utxo/vecs.rs | 20 +- .../src/distribution/compute/block_loop.rs | 197 +-- .../src/distribution/metrics/activity.rs | 73 +- .../distribution/metrics/cohort/adjusted.rs | 14 +- .../src/distribution/metrics/cohort/all.rs | 8 +- .../src/distribution/metrics/cohort/basic.rs | 16 +- .../distribution/metrics/cohort/extended.rs | 8 +- .../metrics/cohort/extended_adjusted.rs | 8 +- .../metrics/cost_basis/extended.rs | 60 +- .../src/distribution/metrics/mod.rs | 22 +- .../src/distribution/metrics/realized/base.rs | 16 +- .../src/distribution/state/cohort/base.rs | 10 +- .../src/distribution/state/cost_basis/data.rs | 8 +- .../distribution/state/cost_basis/realized.rs | 24 + .../state/cost_basis/unrealized.rs | 21 +- .../src/distribution/state/transacted.rs | 3 +- .../internal/algo/expanding_percentiles.rs | 94 +- .../internal/from_height/cumulative_sum.rs | 13 + .../src/internal/from_height/percentiles.rs | 58 +- .../from_height/ratio/price_extended.rs | 25 +- .../src/internal/transform/mod.rs | 2 +- .../src/internal/transform/ratio.rs | 20 +- crates/brk_computer/src/market/compute.rs | 4 - crates/brk_computer/src/market/dca/compute.rs | 15 +- crates/brk_computer/src/market/import.rs | 2 +- crates/brk_computer/src/market/mod.rs | 2 +- .../src/market/moving_average/compute.rs | 4 +- .../src/market/moving_average/import.rs | 4 +- .../src/market/moving_average/vecs.rs | 66 +- .../src/market/returns/compute.rs | 22 +- .../brk_computer/src/market/returns/import.rs | 32 +- .../brk_computer/src/market/returns/vecs.rs | 9 +- .../src/market/volatility/compute.rs | 98 -- .../src/market/volatility/import.rs | 32 +- .../brk_computer/src/market/volatility/mod.rs | 1 - .../src/market/volatility/vecs.rs | 15 +- crates/brk_computer/src/pools/vecs.rs | 109 +- crates/brk_types/src/age.rs | 6 + crates/brk_types/src/basis_points_32.rs | 7 +- .../brk_types/src/basis_points_signed_32.rs | 7 +- modules/brk-client/index.js | 1070 ++++++++--------- packages/brk_client/brk_client/__init__.py | 584 ++++----- website/scripts/options/distribution/data.js | 10 +- website/scripts/options/market.js | 10 - website/scripts/options/partial.js | 6 +- 61 files changed, 2035 insertions(+), 2757 deletions(-) rename crates/brk_cohort/src/{by_year.rs => by_class.rs} (71%) delete mode 100644 crates/brk_computer/src/market/volatility/compute.rs diff --git a/crates/brk_bindgen/src/generate/constants.rs b/crates/brk_bindgen/src/generate/constants.rs index b0edccb8f..1bd1edfe5 100644 --- a/crates/brk_bindgen/src/generate/constants.rs +++ b/crates/brk_bindgen/src/generate/constants.rs @@ -7,7 +7,7 @@ use std::collections::BTreeMap; use brk_cohort::{ AGE_RANGE_NAMES, AMOUNT_RANGE_NAMES, EPOCH_NAMES, GE_AMOUNT_NAMES, LT_AMOUNT_NAMES, - MAX_AGE_NAMES, MIN_AGE_NAMES, SPENDABLE_TYPE_NAMES, TERM_NAMES, YEAR_NAMES, + MAX_AGE_NAMES, MIN_AGE_NAMES, SPENDABLE_TYPE_NAMES, TERM_NAMES, CLASS_NAMES, }; use brk_types::{Index, PoolSlug, pools}; use serde::Serialize; @@ -55,7 +55,7 @@ impl CohortConstants { vec![ ("TERM_NAMES", to_value(&TERM_NAMES)), ("EPOCH_NAMES", to_value(&EPOCH_NAMES)), - ("YEAR_NAMES", to_value(&YEAR_NAMES)), + ("CLASS_NAMES", to_value(&CLASS_NAMES)), ("SPENDABLE_TYPE_NAMES", to_value(&SPENDABLE_TYPE_NAMES)), ("AGE_RANGE_NAMES", to_value(&AGE_RANGE_NAMES)), ("MAX_AGE_NAMES", to_value(&MAX_AGE_NAMES)), diff --git a/crates/brk_client/src/lib.rs b/crates/brk_client/src/lib.rs index a5477533d..e7e51ff37 100644 --- a/crates/brk_client/src/lib.rs +++ b/crates/brk_client/src/lib.rs @@ -1479,60 +1479,6 @@ impl _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern { } } -/// Pattern struct for repeated tree structure. -pub struct BpsPriceRatioPattern { - pub bps: MetricPattern1, - pub price: CentsSatsUsdPattern, - pub ratio: MetricPattern1, - pub ratio_pct1: BpsRatioPattern, - pub ratio_pct1_price: CentsSatsUsdPattern, - pub ratio_pct2: BpsRatioPattern, - pub ratio_pct2_price: CentsSatsUsdPattern, - pub ratio_pct5: BpsRatioPattern, - pub ratio_pct5_price: CentsSatsUsdPattern, - pub ratio_pct95: BpsRatioPattern, - pub ratio_pct95_price: CentsSatsUsdPattern, - pub ratio_pct98: BpsRatioPattern, - pub ratio_pct98_price: CentsSatsUsdPattern, - pub ratio_pct99: BpsRatioPattern, - pub ratio_pct99_price: CentsSatsUsdPattern, - pub ratio_sd: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern, - pub ratio_sd_1y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern, - pub ratio_sd_2y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern, - pub ratio_sd_4y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern, - pub ratio_sma_1m: BpsRatioPattern, - pub ratio_sma_1w: BpsRatioPattern, -} - -impl BpsPriceRatioPattern { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - bps: MetricPattern1::new(client.clone(), _m(&acc, "ratio_bps")), - price: CentsSatsUsdPattern::new(client.clone(), acc.clone()), - ratio: MetricPattern1::new(client.clone(), _m(&acc, "ratio")), - ratio_pct1: BpsRatioPattern::new(client.clone(), _m(&acc, "ratio_pct1")), - ratio_pct1_price: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "ratio_pct1")), - ratio_pct2: BpsRatioPattern::new(client.clone(), _m(&acc, "ratio_pct2")), - ratio_pct2_price: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "ratio_pct2")), - ratio_pct5: BpsRatioPattern::new(client.clone(), _m(&acc, "ratio_pct5")), - ratio_pct5_price: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "ratio_pct5")), - ratio_pct95: BpsRatioPattern::new(client.clone(), _m(&acc, "ratio_pct95")), - ratio_pct95_price: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "ratio_pct95")), - ratio_pct98: BpsRatioPattern::new(client.clone(), _m(&acc, "ratio_pct98")), - ratio_pct98_price: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "ratio_pct98")), - ratio_pct99: BpsRatioPattern::new(client.clone(), _m(&acc, "ratio_pct99")), - ratio_pct99_price: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "ratio_pct99")), - ratio_sd: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern::new(client.clone(), _m(&acc, "ratio")), - ratio_sd_1y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern::new(client.clone(), _m(&acc, "ratio")), - ratio_sd_2y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern::new(client.clone(), _m(&acc, "ratio")), - ratio_sd_4y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern::new(client.clone(), _m(&acc, "ratio")), - ratio_sma_1m: BpsRatioPattern::new(client.clone(), _m(&acc, "ratio_sma_1m")), - ratio_sma_1w: BpsRatioPattern::new(client.clone(), _m(&acc, "ratio_sma_1w")), - } - } -} - /// Pattern struct for repeated tree structure. pub struct BpsRatioPattern2 { pub bps: MetricPattern1, @@ -1989,7 +1935,7 @@ impl AverageGainsLossesRsiStochPattern { /// Pattern struct for repeated tree structure. pub struct ActivityAddrCostOutputsRealizedRelativeSupplyUnrealizedPattern { - pub activity: CoinblocksCoindaysSatblocksSatdaysSentPattern, + pub activity: CoinblocksCoindaysSentPattern, pub addr_count: MetricPattern1, pub addr_count_change_1m: MetricPattern1, pub cost_basis: MaxMinPattern, @@ -2004,7 +1950,7 @@ impl ActivityAddrCostOutputsRealizedRelativeSupplyUnrealizedPattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - activity: CoinblocksCoindaysSatblocksSatdaysSentPattern::new(client.clone(), acc.clone()), + activity: CoinblocksCoindaysSentPattern::new(client.clone(), acc.clone()), addr_count: MetricPattern1::new(client.clone(), _m(&acc, "addr_count")), addr_count_change_1m: MetricPattern1::new(client.clone(), _m(&acc, "addr_count_change_1m")), cost_basis: MaxMinPattern::new(client.clone(), _m(&acc, "cost_basis")), @@ -2165,34 +2111,6 @@ impl _1m1w1y24hBtcCentsSatsUsdPattern { } } -/// Pattern struct for repeated tree structure. -pub struct BlocksCoinbaseDominanceFeeSubsidyPattern { - pub blocks_mined: CumulativeHeightSumPattern, - pub blocks_mined_sum: _1m1w1y24hPattern, - pub blocks_since_last_mined: MetricPattern1, - pub coinbase: BaseCumulativeSumPattern, - pub dominance: BpsPercentRatioPattern, - pub dominance_rolling: _1m1w1y24hPattern2, - pub fee: BaseCumulativeSumPattern, - pub subsidy: BaseCumulativeSumPattern, -} - -impl BlocksCoinbaseDominanceFeeSubsidyPattern { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - blocks_mined: CumulativeHeightSumPattern::new(client.clone(), _m(&acc, "blocks_mined")), - blocks_mined_sum: _1m1w1y24hPattern::new(client.clone(), _m(&acc, "blocks_mined_sum")), - blocks_since_last_mined: MetricPattern1::new(client.clone(), _m(&acc, "blocks_since_last_mined")), - coinbase: BaseCumulativeSumPattern::new(client.clone(), _m(&acc, "coinbase")), - dominance: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "dominance")), - dominance_rolling: _1m1w1y24hPattern2::new(client.clone(), _m(&acc, "dominance")), - fee: BaseCumulativeSumPattern::new(client.clone(), _m(&acc, "fee")), - subsidy: BaseCumulativeSumPattern::new(client.clone(), _m(&acc, "subsidy")), - } - } -} - /// Pattern struct for repeated tree structure. pub struct AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern { pub average: MetricPattern18, @@ -2249,8 +2167,8 @@ impl _10y2y3y4y5y6y8yPattern { /// Pattern struct for repeated tree structure. pub struct ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern { - pub activity: CoinblocksCoindaysSatblocksSatdaysSentPattern, - pub cost_basis: InvestedMaxMinPercentilesSpotPattern, + pub activity: CoinblocksCoindaysSentPattern, + pub cost_basis: InvestedMaxMinPercentilesPattern, pub outputs: UtxoPattern, pub realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern2, pub relative: InvestedNegNetNuplSupplyUnrealizedPattern2, @@ -2262,8 +2180,8 @@ impl ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - activity: CoinblocksCoindaysSatblocksSatdaysSentPattern::new(client.clone(), acc.clone()), - cost_basis: InvestedMaxMinPercentilesSpotPattern::new(client.clone(), acc.clone()), + activity: CoinblocksCoindaysSentPattern::new(client.clone(), acc.clone()), + cost_basis: InvestedMaxMinPercentilesPattern::new(client.clone(), acc.clone()), outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")), realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern2::new(client.clone(), acc.clone()), relative: InvestedNegNetNuplSupplyUnrealizedPattern2::new(client.clone(), acc.clone()), @@ -2275,7 +2193,7 @@ impl ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern { /// Pattern struct for repeated tree structure. pub struct ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 { - pub activity: CoinblocksCoindaysSatblocksSatdaysSentPattern, + pub activity: CoinblocksCoindaysSentPattern, pub cost_basis: MaxMinPattern, pub outputs: UtxoPattern, pub realized: AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern2, @@ -2288,7 +2206,7 @@ impl ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - activity: CoinblocksCoindaysSatblocksSatdaysSentPattern::new(client.clone(), acc.clone()), + activity: CoinblocksCoindaysSentPattern::new(client.clone(), acc.clone()), cost_basis: MaxMinPattern::new(client.clone(), _m(&acc, "cost_basis")), outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")), realized: AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern2::new(client.clone(), acc.clone()), @@ -2301,7 +2219,7 @@ impl ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 { /// Pattern struct for repeated tree structure. pub struct ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 { - pub activity: CoinblocksCoindaysSatblocksSatdaysSentPattern, + pub activity: CoinblocksCoindaysSentPattern, pub cost_basis: MaxMinPattern, pub outputs: UtxoPattern, pub realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern, @@ -2314,7 +2232,7 @@ impl ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - activity: CoinblocksCoindaysSatblocksSatdaysSentPattern::new(client.clone(), acc.clone()), + activity: CoinblocksCoindaysSentPattern::new(client.clone(), acc.clone()), cost_basis: MaxMinPattern::new(client.clone(), _m(&acc, "cost_basis")), outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")), realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern::new(client.clone(), acc.clone()), @@ -2373,54 +2291,6 @@ impl BalanceBothReactivatedReceivingSendingPattern { } } -/// Pattern struct for repeated tree structure. -pub struct CoinblocksCoindaysSatblocksSatdaysSentPattern { - pub coinblocks_destroyed: CumulativeHeightSumPattern, - pub coindays_destroyed: CumulativeHeightSumPattern, - pub satblocks_destroyed: MetricPattern18, - pub satdays_destroyed: MetricPattern18, - pub sent: BaseCumulativePattern, - pub sent_ema: _2wPattern, -} - -impl CoinblocksCoindaysSatblocksSatdaysSentPattern { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - coinblocks_destroyed: CumulativeHeightSumPattern::new(client.clone(), _m(&acc, "coinblocks_destroyed")), - coindays_destroyed: CumulativeHeightSumPattern::new(client.clone(), _m(&acc, "coindays_destroyed")), - satblocks_destroyed: MetricPattern18::new(client.clone(), _m(&acc, "satblocks_destroyed")), - satdays_destroyed: MetricPattern18::new(client.clone(), _m(&acc, "satdays_destroyed")), - sent: BaseCumulativePattern::new(client.clone(), _m(&acc, "sent")), - sent_ema: _2wPattern::new(client.clone(), _m(&acc, "sent_ema_2w")), - } - } -} - -/// Pattern struct for repeated tree structure. -pub struct InvestedMaxMinPercentilesSpotPattern { - pub invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern, - pub max: CentsSatsUsdPattern, - pub min: CentsSatsUsdPattern, - pub percentiles: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern, - pub spot_cost_basis_percentile: BpsPercentRatioPattern, - pub spot_invested_capital_percentile: BpsPercentRatioPattern, -} - -impl InvestedMaxMinPercentilesSpotPattern { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern::new(client.clone(), _m(&acc, "invested_capital")), - max: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "cost_basis_max")), - min: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "cost_basis_min")), - percentiles: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern::new(client.clone(), _m(&acc, "cost_basis")), - spot_cost_basis_percentile: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "spot_cost_basis_percentile")), - spot_invested_capital_percentile: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "spot_invested_capital_percentile")), - } - } -} - /// Pattern struct for repeated tree structure. pub struct EmaHistogramLineSignalPattern { pub ema_fast: MetricPattern1, @@ -2483,6 +2353,26 @@ impl _1m1w1y24hPattern5 { } } +/// Pattern struct for repeated tree structure. +pub struct BlocksDominanceRewardsPattern { + pub blocks_mined: CumulativeHeightSumPattern, + pub dominance: BpsPercentRatioPattern, + pub dominance_rolling: _1m1w1y24hPattern2, + pub rewards: BaseCumulativeSumPattern, +} + +impl BlocksDominanceRewardsPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + blocks_mined: CumulativeHeightSumPattern::new(client.clone(), _m(&acc, "blocks_mined")), + dominance: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "dominance")), + dominance_rolling: _1m1w1y24hPattern2::new(client.clone(), _m(&acc, "dominance")), + rewards: BaseCumulativeSumPattern::new(client.clone(), _m(&acc, "rewards")), + } + } +} + /// Pattern struct for repeated tree structure. pub struct BtcCentsSatsUsdPattern { pub btc: MetricPattern1, @@ -2503,6 +2393,46 @@ impl BtcCentsSatsUsdPattern { } } +/// Pattern struct for repeated tree structure. +pub struct CoinblocksCoindaysSentPattern { + pub coinblocks_destroyed: CumulativeHeightSumPattern, + pub coindays_destroyed: CumulativeHeightSumPattern, + pub sent: BaseCumulativePattern, + pub sent_ema: _2wPattern, +} + +impl CoinblocksCoindaysSentPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + coinblocks_destroyed: CumulativeHeightSumPattern::new(client.clone(), _m(&acc, "coinblocks_destroyed")), + coindays_destroyed: CumulativeHeightSumPattern::new(client.clone(), _m(&acc, "coindays_destroyed")), + sent: BaseCumulativePattern::new(client.clone(), _m(&acc, "sent")), + sent_ema: _2wPattern::new(client.clone(), _m(&acc, "sent_ema_2w")), + } + } +} + +/// Pattern struct for repeated tree structure. +pub struct InvestedMaxMinPercentilesPattern { + pub invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern, + pub max: CentsSatsUsdPattern, + pub min: CentsSatsUsdPattern, + pub percentiles: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern, +} + +impl InvestedMaxMinPercentilesPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern::new(client.clone(), _m(&acc, "invested_capital")), + max: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "cost_basis_max")), + min: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "cost_basis_min")), + percentiles: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern::new(client.clone(), _m(&acc, "cost_basis")), + } + } +} + /// Pattern struct for repeated tree structure. pub struct _1m1w1y24hPattern { pub _1m: MetricPattern1, @@ -2577,6 +2507,24 @@ impl BpsPercentRatioPattern { } } +/// Pattern struct for repeated tree structure. +pub struct BpsPriceRatioPattern { + pub bps: MetricPattern1, + pub price: CentsSatsUsdPattern, + pub ratio: MetricPattern1, +} + +impl BpsPriceRatioPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + bps: MetricPattern1::new(client.clone(), _m(&acc, "ratio_bps")), + price: CentsSatsUsdPattern::new(client.clone(), acc.clone()), + ratio: MetricPattern1::new(client.clone(), _m(&acc, "ratio")), + } + } +} + /// Pattern struct for repeated tree structure. pub struct CentsSatsUsdPattern2 { pub cents: MetricPattern2, @@ -4487,10 +4435,6 @@ pub struct MetricsTree_Market_Returns { pub price_return_24h_sd_1w: MetricsTree_Market_Returns_PriceReturn24hSd1w, pub price_return_24h_sd_1m: MetricsTree_Market_Returns_PriceReturn24hSd1m, pub price_return_24h_sd_1y: SdSmaPattern, - pub price_downside_24h: MetricPattern18, - pub price_downside_24h_sd_1w: MetricsTree_Market_Returns_PriceDownside24hSd1w, - pub price_downside_24h_sd_1m: MetricsTree_Market_Returns_PriceDownside24hSd1m, - pub price_downside_24h_sd_1y: SdSmaPattern, } impl MetricsTree_Market_Returns { @@ -4501,10 +4445,6 @@ impl MetricsTree_Market_Returns { price_return_24h_sd_1w: MetricsTree_Market_Returns_PriceReturn24hSd1w::new(client.clone(), format!("{base_path}_price_return_24h_sd_1w")), price_return_24h_sd_1m: MetricsTree_Market_Returns_PriceReturn24hSd1m::new(client.clone(), format!("{base_path}_price_return_24h_sd_1m")), price_return_24h_sd_1y: SdSmaPattern::new(client.clone(), "price_return_24h".to_string()), - price_downside_24h: MetricPattern18::new(client.clone(), "price_downside_24h".to_string()), - price_downside_24h_sd_1w: MetricsTree_Market_Returns_PriceDownside24hSd1w::new(client.clone(), format!("{base_path}_price_downside_24h_sd_1w")), - price_downside_24h_sd_1m: MetricsTree_Market_Returns_PriceDownside24hSd1m::new(client.clone(), format!("{base_path}_price_downside_24h_sd_1m")), - price_downside_24h_sd_1y: SdSmaPattern::new(client.clone(), "price_downside_24h".to_string()), } } } @@ -4576,47 +4516,11 @@ impl MetricsTree_Market_Returns_PriceReturn24hSd1m { } } -/// Metrics tree node. -pub struct MetricsTree_Market_Returns_PriceDownside24hSd1w { - pub sma: MetricPattern1, - pub sd: MetricPattern1, -} - -impl MetricsTree_Market_Returns_PriceDownside24hSd1w { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - sma: MetricPattern1::new(client.clone(), "price_downside_24h_sma_1w".to_string()), - sd: MetricPattern1::new(client.clone(), "price_downside_24h_sd_1w".to_string()), - } - } -} - -/// Metrics tree node. -pub struct MetricsTree_Market_Returns_PriceDownside24hSd1m { - pub sma: MetricPattern1, - pub sd: MetricPattern1, -} - -impl MetricsTree_Market_Returns_PriceDownside24hSd1m { - pub fn new(client: Arc, base_path: String) -> Self { - Self { - sma: MetricPattern1::new(client.clone(), "price_downside_24h_sma_1m".to_string()), - sd: MetricPattern1::new(client.clone(), "price_downside_24h_sd_1m".to_string()), - } - } -} - /// Metrics tree node. pub struct MetricsTree_Market_Volatility { pub price_volatility_1w: MetricPattern1, pub price_volatility_1m: MetricPattern1, pub price_volatility_1y: MetricPattern1, - pub price_sharpe_1w: MetricPattern1, - pub price_sharpe_1m: MetricPattern1, - pub price_sharpe_1y: MetricPattern1, - pub price_sortino_1w: MetricPattern1, - pub price_sortino_1m: MetricPattern1, - pub price_sortino_1y: MetricPattern1, } impl MetricsTree_Market_Volatility { @@ -4625,12 +4529,6 @@ impl MetricsTree_Market_Volatility { price_volatility_1w: MetricPattern1::new(client.clone(), "price_volatility_1w".to_string()), price_volatility_1m: MetricPattern1::new(client.clone(), "price_volatility_1m".to_string()), price_volatility_1y: MetricPattern1::new(client.clone(), "price_volatility_1y".to_string()), - price_sharpe_1w: MetricPattern1::new(client.clone(), "price_sharpe_1w".to_string()), - price_sharpe_1m: MetricPattern1::new(client.clone(), "price_sharpe_1m".to_string()), - price_sharpe_1y: MetricPattern1::new(client.clone(), "price_sharpe_1y".to_string()), - price_sortino_1w: MetricPattern1::new(client.clone(), "price_sortino_1w".to_string()), - price_sortino_1m: MetricPattern1::new(client.clone(), "price_sortino_1m".to_string()), - price_sortino_1y: MetricPattern1::new(client.clone(), "price_sortino_1y".to_string()), } } } @@ -5158,335 +5056,335 @@ impl MetricsTree_Pools { /// Metrics tree node. pub struct MetricsTree_Pools_Vecs { - pub unknown: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub blockfills: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub ultimuspool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub terrapool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub luxor: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub onethash: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub btccom: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bitfarms: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub huobipool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub wayicn: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub canoepool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub btctop: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bitcoincom: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub pool175btc: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub gbminers: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub axbt: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub asicminer: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bitminter: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bitcoinrussia: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub btcserv: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub simplecoinus: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub btcguild: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub eligius: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub ozcoin: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub eclipsemc: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub maxbtc: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub triplemining: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub coinlab: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub pool50btc: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub ghashio: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub stminingcorp: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bitparking: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub mmpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub polmine: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub kncminer: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bitalo: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub f2pool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub hhtt: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub megabigpower: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub mtred: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub nmcbit: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub yourbtcnet: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub givemecoins: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub braiinspool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub antpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub multicoinco: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bcpoolio: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub cointerra: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub kanopool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub solock: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub ckpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub nicehash: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bitclub: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bitcoinaffiliatenetwork: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub btcc: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bwpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub exxbw: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bitsolo: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bitfury: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub twentyoneinc: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub digitalbtc: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub eightbaochi: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub mybtccoinpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub tbdice: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub hashpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub nexious: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bravomining: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub hotpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub okexpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bcmonster: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub onehash: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bixin: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub tatmaspool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub viabtc: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub connectbtc: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub batpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub waterhole: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub dcexploration: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub dcex: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub btpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub fiftyeightcoin: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bitcoinindia: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub shawnp0wers: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub phashio: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub rigpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub haozhuzhu: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub sevenpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub miningkings: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub hashbx: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub dpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub rawpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub haominer: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub helix: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bitcoinukraine: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub poolin: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub secretsuperstar: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub tigerpoolnet: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub sigmapoolcom: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub okpooltop: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub hummerpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub tangpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bytepool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub spiderpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub novablock: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub miningcity: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub binancepool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub minerium: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub lubiancom: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub okkong: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub aaopool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub emcdpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub foundryusa: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub sbicrypto: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub arkpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub purebtccom: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub marapool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub kucoinpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub entrustcharitypool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub okminer: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub titan: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub pegapool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub btcnuggets: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub cloudhashing: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub digitalxmintsy: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub telco214: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub btcpoolparty: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub multipool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub transactioncoinmining: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub btcdig: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub trickysbtcpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub btcmp: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub eobot: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub unomp: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub patels: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub gogreenlight: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bitcoinindiapool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub ekanembtc: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub canoe: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub tiger: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub onem1x: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub zulupool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub secpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub ocean: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub whitepool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub wiz: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub wk057: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub futurebitapollosolo: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub carbonnegative: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub portlandhodl: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub phoenix: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub neopool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub maxipool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub bitfufupool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub gdpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub miningdutch: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub publicpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub miningsquared: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub innopolistech: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub btclab: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub parasite: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub redrockpool: BlocksCoinbaseDominanceFeeSubsidyPattern, - pub est3lar: BlocksCoinbaseDominanceFeeSubsidyPattern, + pub unknown: BlocksDominanceRewardsPattern, + pub blockfills: BlocksDominanceRewardsPattern, + pub ultimuspool: BlocksDominanceRewardsPattern, + pub terrapool: BlocksDominanceRewardsPattern, + pub luxor: BlocksDominanceRewardsPattern, + pub onethash: BlocksDominanceRewardsPattern, + pub btccom: BlocksDominanceRewardsPattern, + pub bitfarms: BlocksDominanceRewardsPattern, + pub huobipool: BlocksDominanceRewardsPattern, + pub wayicn: BlocksDominanceRewardsPattern, + pub canoepool: BlocksDominanceRewardsPattern, + pub btctop: BlocksDominanceRewardsPattern, + pub bitcoincom: BlocksDominanceRewardsPattern, + pub pool175btc: BlocksDominanceRewardsPattern, + pub gbminers: BlocksDominanceRewardsPattern, + pub axbt: BlocksDominanceRewardsPattern, + pub asicminer: BlocksDominanceRewardsPattern, + pub bitminter: BlocksDominanceRewardsPattern, + pub bitcoinrussia: BlocksDominanceRewardsPattern, + pub btcserv: BlocksDominanceRewardsPattern, + pub simplecoinus: BlocksDominanceRewardsPattern, + pub btcguild: BlocksDominanceRewardsPattern, + pub eligius: BlocksDominanceRewardsPattern, + pub ozcoin: BlocksDominanceRewardsPattern, + pub eclipsemc: BlocksDominanceRewardsPattern, + pub maxbtc: BlocksDominanceRewardsPattern, + pub triplemining: BlocksDominanceRewardsPattern, + pub coinlab: BlocksDominanceRewardsPattern, + pub pool50btc: BlocksDominanceRewardsPattern, + pub ghashio: BlocksDominanceRewardsPattern, + pub stminingcorp: BlocksDominanceRewardsPattern, + pub bitparking: BlocksDominanceRewardsPattern, + pub mmpool: BlocksDominanceRewardsPattern, + pub polmine: BlocksDominanceRewardsPattern, + pub kncminer: BlocksDominanceRewardsPattern, + pub bitalo: BlocksDominanceRewardsPattern, + pub f2pool: BlocksDominanceRewardsPattern, + pub hhtt: BlocksDominanceRewardsPattern, + pub megabigpower: BlocksDominanceRewardsPattern, + pub mtred: BlocksDominanceRewardsPattern, + pub nmcbit: BlocksDominanceRewardsPattern, + pub yourbtcnet: BlocksDominanceRewardsPattern, + pub givemecoins: BlocksDominanceRewardsPattern, + pub braiinspool: BlocksDominanceRewardsPattern, + pub antpool: BlocksDominanceRewardsPattern, + pub multicoinco: BlocksDominanceRewardsPattern, + pub bcpoolio: BlocksDominanceRewardsPattern, + pub cointerra: BlocksDominanceRewardsPattern, + pub kanopool: BlocksDominanceRewardsPattern, + pub solock: BlocksDominanceRewardsPattern, + pub ckpool: BlocksDominanceRewardsPattern, + pub nicehash: BlocksDominanceRewardsPattern, + pub bitclub: BlocksDominanceRewardsPattern, + pub bitcoinaffiliatenetwork: BlocksDominanceRewardsPattern, + pub btcc: BlocksDominanceRewardsPattern, + pub bwpool: BlocksDominanceRewardsPattern, + pub exxbw: BlocksDominanceRewardsPattern, + pub bitsolo: BlocksDominanceRewardsPattern, + pub bitfury: BlocksDominanceRewardsPattern, + pub twentyoneinc: BlocksDominanceRewardsPattern, + pub digitalbtc: BlocksDominanceRewardsPattern, + pub eightbaochi: BlocksDominanceRewardsPattern, + pub mybtccoinpool: BlocksDominanceRewardsPattern, + pub tbdice: BlocksDominanceRewardsPattern, + pub hashpool: BlocksDominanceRewardsPattern, + pub nexious: BlocksDominanceRewardsPattern, + pub bravomining: BlocksDominanceRewardsPattern, + pub hotpool: BlocksDominanceRewardsPattern, + pub okexpool: BlocksDominanceRewardsPattern, + pub bcmonster: BlocksDominanceRewardsPattern, + pub onehash: BlocksDominanceRewardsPattern, + pub bixin: BlocksDominanceRewardsPattern, + pub tatmaspool: BlocksDominanceRewardsPattern, + pub viabtc: BlocksDominanceRewardsPattern, + pub connectbtc: BlocksDominanceRewardsPattern, + pub batpool: BlocksDominanceRewardsPattern, + pub waterhole: BlocksDominanceRewardsPattern, + pub dcexploration: BlocksDominanceRewardsPattern, + pub dcex: BlocksDominanceRewardsPattern, + pub btpool: BlocksDominanceRewardsPattern, + pub fiftyeightcoin: BlocksDominanceRewardsPattern, + pub bitcoinindia: BlocksDominanceRewardsPattern, + pub shawnp0wers: BlocksDominanceRewardsPattern, + pub phashio: BlocksDominanceRewardsPattern, + pub rigpool: BlocksDominanceRewardsPattern, + pub haozhuzhu: BlocksDominanceRewardsPattern, + pub sevenpool: BlocksDominanceRewardsPattern, + pub miningkings: BlocksDominanceRewardsPattern, + pub hashbx: BlocksDominanceRewardsPattern, + pub dpool: BlocksDominanceRewardsPattern, + pub rawpool: BlocksDominanceRewardsPattern, + pub haominer: BlocksDominanceRewardsPattern, + pub helix: BlocksDominanceRewardsPattern, + pub bitcoinukraine: BlocksDominanceRewardsPattern, + pub poolin: BlocksDominanceRewardsPattern, + pub secretsuperstar: BlocksDominanceRewardsPattern, + pub tigerpoolnet: BlocksDominanceRewardsPattern, + pub sigmapoolcom: BlocksDominanceRewardsPattern, + pub okpooltop: BlocksDominanceRewardsPattern, + pub hummerpool: BlocksDominanceRewardsPattern, + pub tangpool: BlocksDominanceRewardsPattern, + pub bytepool: BlocksDominanceRewardsPattern, + pub spiderpool: BlocksDominanceRewardsPattern, + pub novablock: BlocksDominanceRewardsPattern, + pub miningcity: BlocksDominanceRewardsPattern, + pub binancepool: BlocksDominanceRewardsPattern, + pub minerium: BlocksDominanceRewardsPattern, + pub lubiancom: BlocksDominanceRewardsPattern, + pub okkong: BlocksDominanceRewardsPattern, + pub aaopool: BlocksDominanceRewardsPattern, + pub emcdpool: BlocksDominanceRewardsPattern, + pub foundryusa: BlocksDominanceRewardsPattern, + pub sbicrypto: BlocksDominanceRewardsPattern, + pub arkpool: BlocksDominanceRewardsPattern, + pub purebtccom: BlocksDominanceRewardsPattern, + pub marapool: BlocksDominanceRewardsPattern, + pub kucoinpool: BlocksDominanceRewardsPattern, + pub entrustcharitypool: BlocksDominanceRewardsPattern, + pub okminer: BlocksDominanceRewardsPattern, + pub titan: BlocksDominanceRewardsPattern, + pub pegapool: BlocksDominanceRewardsPattern, + pub btcnuggets: BlocksDominanceRewardsPattern, + pub cloudhashing: BlocksDominanceRewardsPattern, + pub digitalxmintsy: BlocksDominanceRewardsPattern, + pub telco214: BlocksDominanceRewardsPattern, + pub btcpoolparty: BlocksDominanceRewardsPattern, + pub multipool: BlocksDominanceRewardsPattern, + pub transactioncoinmining: BlocksDominanceRewardsPattern, + pub btcdig: BlocksDominanceRewardsPattern, + pub trickysbtcpool: BlocksDominanceRewardsPattern, + pub btcmp: BlocksDominanceRewardsPattern, + pub eobot: BlocksDominanceRewardsPattern, + pub unomp: BlocksDominanceRewardsPattern, + pub patels: BlocksDominanceRewardsPattern, + pub gogreenlight: BlocksDominanceRewardsPattern, + pub bitcoinindiapool: BlocksDominanceRewardsPattern, + pub ekanembtc: BlocksDominanceRewardsPattern, + pub canoe: BlocksDominanceRewardsPattern, + pub tiger: BlocksDominanceRewardsPattern, + pub onem1x: BlocksDominanceRewardsPattern, + pub zulupool: BlocksDominanceRewardsPattern, + pub secpool: BlocksDominanceRewardsPattern, + pub ocean: BlocksDominanceRewardsPattern, + pub whitepool: BlocksDominanceRewardsPattern, + pub wiz: BlocksDominanceRewardsPattern, + pub wk057: BlocksDominanceRewardsPattern, + pub futurebitapollosolo: BlocksDominanceRewardsPattern, + pub carbonnegative: BlocksDominanceRewardsPattern, + pub portlandhodl: BlocksDominanceRewardsPattern, + pub phoenix: BlocksDominanceRewardsPattern, + pub neopool: BlocksDominanceRewardsPattern, + pub maxipool: BlocksDominanceRewardsPattern, + pub bitfufupool: BlocksDominanceRewardsPattern, + pub gdpool: BlocksDominanceRewardsPattern, + pub miningdutch: BlocksDominanceRewardsPattern, + pub publicpool: BlocksDominanceRewardsPattern, + pub miningsquared: BlocksDominanceRewardsPattern, + pub innopolistech: BlocksDominanceRewardsPattern, + pub btclab: BlocksDominanceRewardsPattern, + pub parasite: BlocksDominanceRewardsPattern, + pub redrockpool: BlocksDominanceRewardsPattern, + pub est3lar: BlocksDominanceRewardsPattern, } impl MetricsTree_Pools_Vecs { pub fn new(client: Arc, base_path: String) -> Self { Self { - unknown: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "unknown".to_string()), - blockfills: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "blockfills".to_string()), - ultimuspool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "ultimuspool".to_string()), - terrapool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "terrapool".to_string()), - luxor: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "luxor".to_string()), - onethash: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "onethash".to_string()), - btccom: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "btccom".to_string()), - bitfarms: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bitfarms".to_string()), - huobipool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "huobipool".to_string()), - wayicn: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "wayicn".to_string()), - canoepool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "canoepool".to_string()), - btctop: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "btctop".to_string()), - bitcoincom: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bitcoincom".to_string()), - pool175btc: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "pool175btc".to_string()), - gbminers: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "gbminers".to_string()), - axbt: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "axbt".to_string()), - asicminer: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "asicminer".to_string()), - bitminter: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bitminter".to_string()), - bitcoinrussia: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bitcoinrussia".to_string()), - btcserv: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "btcserv".to_string()), - simplecoinus: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "simplecoinus".to_string()), - btcguild: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "btcguild".to_string()), - eligius: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "eligius".to_string()), - ozcoin: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "ozcoin".to_string()), - eclipsemc: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "eclipsemc".to_string()), - maxbtc: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "maxbtc".to_string()), - triplemining: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "triplemining".to_string()), - coinlab: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "coinlab".to_string()), - pool50btc: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "pool50btc".to_string()), - ghashio: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "ghashio".to_string()), - stminingcorp: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "stminingcorp".to_string()), - bitparking: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bitparking".to_string()), - mmpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "mmpool".to_string()), - polmine: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "polmine".to_string()), - kncminer: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "kncminer".to_string()), - bitalo: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bitalo".to_string()), - f2pool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "f2pool".to_string()), - hhtt: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "hhtt".to_string()), - megabigpower: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "megabigpower".to_string()), - mtred: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "mtred".to_string()), - nmcbit: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "nmcbit".to_string()), - yourbtcnet: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "yourbtcnet".to_string()), - givemecoins: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "givemecoins".to_string()), - braiinspool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "braiinspool".to_string()), - antpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "antpool".to_string()), - multicoinco: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "multicoinco".to_string()), - bcpoolio: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bcpoolio".to_string()), - cointerra: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "cointerra".to_string()), - kanopool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "kanopool".to_string()), - solock: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "solock".to_string()), - ckpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "ckpool".to_string()), - nicehash: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "nicehash".to_string()), - bitclub: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bitclub".to_string()), - bitcoinaffiliatenetwork: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bitcoinaffiliatenetwork".to_string()), - btcc: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "btcc".to_string()), - bwpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bwpool".to_string()), - exxbw: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "exxbw".to_string()), - bitsolo: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bitsolo".to_string()), - bitfury: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bitfury".to_string()), - twentyoneinc: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "twentyoneinc".to_string()), - digitalbtc: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "digitalbtc".to_string()), - eightbaochi: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "eightbaochi".to_string()), - mybtccoinpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "mybtccoinpool".to_string()), - tbdice: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "tbdice".to_string()), - hashpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "hashpool".to_string()), - nexious: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "nexious".to_string()), - bravomining: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bravomining".to_string()), - hotpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "hotpool".to_string()), - okexpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "okexpool".to_string()), - bcmonster: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bcmonster".to_string()), - onehash: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "onehash".to_string()), - bixin: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bixin".to_string()), - tatmaspool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "tatmaspool".to_string()), - viabtc: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "viabtc".to_string()), - connectbtc: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "connectbtc".to_string()), - batpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "batpool".to_string()), - waterhole: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "waterhole".to_string()), - dcexploration: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "dcexploration".to_string()), - dcex: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "dcex".to_string()), - btpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "btpool".to_string()), - fiftyeightcoin: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "fiftyeightcoin".to_string()), - bitcoinindia: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bitcoinindia".to_string()), - shawnp0wers: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "shawnp0wers".to_string()), - phashio: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "phashio".to_string()), - rigpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "rigpool".to_string()), - haozhuzhu: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "haozhuzhu".to_string()), - sevenpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "sevenpool".to_string()), - miningkings: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "miningkings".to_string()), - hashbx: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "hashbx".to_string()), - dpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "dpool".to_string()), - rawpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "rawpool".to_string()), - haominer: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "haominer".to_string()), - helix: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "helix".to_string()), - bitcoinukraine: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bitcoinukraine".to_string()), - poolin: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "poolin".to_string()), - secretsuperstar: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "secretsuperstar".to_string()), - tigerpoolnet: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "tigerpoolnet".to_string()), - sigmapoolcom: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "sigmapoolcom".to_string()), - okpooltop: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "okpooltop".to_string()), - hummerpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "hummerpool".to_string()), - tangpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "tangpool".to_string()), - bytepool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bytepool".to_string()), - spiderpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "spiderpool".to_string()), - novablock: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "novablock".to_string()), - miningcity: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "miningcity".to_string()), - binancepool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "binancepool".to_string()), - minerium: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "minerium".to_string()), - lubiancom: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "lubiancom".to_string()), - okkong: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "okkong".to_string()), - aaopool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "aaopool".to_string()), - emcdpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "emcdpool".to_string()), - foundryusa: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "foundryusa".to_string()), - sbicrypto: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "sbicrypto".to_string()), - arkpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "arkpool".to_string()), - purebtccom: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "purebtccom".to_string()), - marapool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "marapool".to_string()), - kucoinpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "kucoinpool".to_string()), - entrustcharitypool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "entrustcharitypool".to_string()), - okminer: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "okminer".to_string()), - titan: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "titan".to_string()), - pegapool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "pegapool".to_string()), - btcnuggets: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "btcnuggets".to_string()), - cloudhashing: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "cloudhashing".to_string()), - digitalxmintsy: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "digitalxmintsy".to_string()), - telco214: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "telco214".to_string()), - btcpoolparty: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "btcpoolparty".to_string()), - multipool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "multipool".to_string()), - transactioncoinmining: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "transactioncoinmining".to_string()), - btcdig: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "btcdig".to_string()), - trickysbtcpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "trickysbtcpool".to_string()), - btcmp: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "btcmp".to_string()), - eobot: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "eobot".to_string()), - unomp: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "unomp".to_string()), - patels: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "patels".to_string()), - gogreenlight: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "gogreenlight".to_string()), - bitcoinindiapool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bitcoinindiapool".to_string()), - ekanembtc: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "ekanembtc".to_string()), - canoe: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "canoe".to_string()), - tiger: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "tiger".to_string()), - onem1x: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "onem1x".to_string()), - zulupool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "zulupool".to_string()), - secpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "secpool".to_string()), - ocean: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "ocean".to_string()), - whitepool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "whitepool".to_string()), - wiz: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "wiz".to_string()), - wk057: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "wk057".to_string()), - futurebitapollosolo: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "futurebitapollosolo".to_string()), - carbonnegative: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "carbonnegative".to_string()), - portlandhodl: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "portlandhodl".to_string()), - phoenix: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "phoenix".to_string()), - neopool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "neopool".to_string()), - maxipool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "maxipool".to_string()), - bitfufupool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "bitfufupool".to_string()), - gdpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "gdpool".to_string()), - miningdutch: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "miningdutch".to_string()), - publicpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "publicpool".to_string()), - miningsquared: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "miningsquared".to_string()), - innopolistech: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "innopolistech".to_string()), - btclab: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "btclab".to_string()), - parasite: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "parasite".to_string()), - redrockpool: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "redrockpool".to_string()), - est3lar: BlocksCoinbaseDominanceFeeSubsidyPattern::new(client.clone(), "est3lar".to_string()), + unknown: BlocksDominanceRewardsPattern::new(client.clone(), "unknown".to_string()), + blockfills: BlocksDominanceRewardsPattern::new(client.clone(), "blockfills".to_string()), + ultimuspool: BlocksDominanceRewardsPattern::new(client.clone(), "ultimuspool".to_string()), + terrapool: BlocksDominanceRewardsPattern::new(client.clone(), "terrapool".to_string()), + luxor: BlocksDominanceRewardsPattern::new(client.clone(), "luxor".to_string()), + onethash: BlocksDominanceRewardsPattern::new(client.clone(), "onethash".to_string()), + btccom: BlocksDominanceRewardsPattern::new(client.clone(), "btccom".to_string()), + bitfarms: BlocksDominanceRewardsPattern::new(client.clone(), "bitfarms".to_string()), + huobipool: BlocksDominanceRewardsPattern::new(client.clone(), "huobipool".to_string()), + wayicn: BlocksDominanceRewardsPattern::new(client.clone(), "wayicn".to_string()), + canoepool: BlocksDominanceRewardsPattern::new(client.clone(), "canoepool".to_string()), + btctop: BlocksDominanceRewardsPattern::new(client.clone(), "btctop".to_string()), + bitcoincom: BlocksDominanceRewardsPattern::new(client.clone(), "bitcoincom".to_string()), + pool175btc: BlocksDominanceRewardsPattern::new(client.clone(), "pool175btc".to_string()), + gbminers: BlocksDominanceRewardsPattern::new(client.clone(), "gbminers".to_string()), + axbt: BlocksDominanceRewardsPattern::new(client.clone(), "axbt".to_string()), + asicminer: BlocksDominanceRewardsPattern::new(client.clone(), "asicminer".to_string()), + bitminter: BlocksDominanceRewardsPattern::new(client.clone(), "bitminter".to_string()), + bitcoinrussia: BlocksDominanceRewardsPattern::new(client.clone(), "bitcoinrussia".to_string()), + btcserv: BlocksDominanceRewardsPattern::new(client.clone(), "btcserv".to_string()), + simplecoinus: BlocksDominanceRewardsPattern::new(client.clone(), "simplecoinus".to_string()), + btcguild: BlocksDominanceRewardsPattern::new(client.clone(), "btcguild".to_string()), + eligius: BlocksDominanceRewardsPattern::new(client.clone(), "eligius".to_string()), + ozcoin: BlocksDominanceRewardsPattern::new(client.clone(), "ozcoin".to_string()), + eclipsemc: BlocksDominanceRewardsPattern::new(client.clone(), "eclipsemc".to_string()), + maxbtc: BlocksDominanceRewardsPattern::new(client.clone(), "maxbtc".to_string()), + triplemining: BlocksDominanceRewardsPattern::new(client.clone(), "triplemining".to_string()), + coinlab: BlocksDominanceRewardsPattern::new(client.clone(), "coinlab".to_string()), + pool50btc: BlocksDominanceRewardsPattern::new(client.clone(), "pool50btc".to_string()), + ghashio: BlocksDominanceRewardsPattern::new(client.clone(), "ghashio".to_string()), + stminingcorp: BlocksDominanceRewardsPattern::new(client.clone(), "stminingcorp".to_string()), + bitparking: BlocksDominanceRewardsPattern::new(client.clone(), "bitparking".to_string()), + mmpool: BlocksDominanceRewardsPattern::new(client.clone(), "mmpool".to_string()), + polmine: BlocksDominanceRewardsPattern::new(client.clone(), "polmine".to_string()), + kncminer: BlocksDominanceRewardsPattern::new(client.clone(), "kncminer".to_string()), + bitalo: BlocksDominanceRewardsPattern::new(client.clone(), "bitalo".to_string()), + f2pool: BlocksDominanceRewardsPattern::new(client.clone(), "f2pool".to_string()), + hhtt: BlocksDominanceRewardsPattern::new(client.clone(), "hhtt".to_string()), + megabigpower: BlocksDominanceRewardsPattern::new(client.clone(), "megabigpower".to_string()), + mtred: BlocksDominanceRewardsPattern::new(client.clone(), "mtred".to_string()), + nmcbit: BlocksDominanceRewardsPattern::new(client.clone(), "nmcbit".to_string()), + yourbtcnet: BlocksDominanceRewardsPattern::new(client.clone(), "yourbtcnet".to_string()), + givemecoins: BlocksDominanceRewardsPattern::new(client.clone(), "givemecoins".to_string()), + braiinspool: BlocksDominanceRewardsPattern::new(client.clone(), "braiinspool".to_string()), + antpool: BlocksDominanceRewardsPattern::new(client.clone(), "antpool".to_string()), + multicoinco: BlocksDominanceRewardsPattern::new(client.clone(), "multicoinco".to_string()), + bcpoolio: BlocksDominanceRewardsPattern::new(client.clone(), "bcpoolio".to_string()), + cointerra: BlocksDominanceRewardsPattern::new(client.clone(), "cointerra".to_string()), + kanopool: BlocksDominanceRewardsPattern::new(client.clone(), "kanopool".to_string()), + solock: BlocksDominanceRewardsPattern::new(client.clone(), "solock".to_string()), + ckpool: BlocksDominanceRewardsPattern::new(client.clone(), "ckpool".to_string()), + nicehash: BlocksDominanceRewardsPattern::new(client.clone(), "nicehash".to_string()), + bitclub: BlocksDominanceRewardsPattern::new(client.clone(), "bitclub".to_string()), + bitcoinaffiliatenetwork: BlocksDominanceRewardsPattern::new(client.clone(), "bitcoinaffiliatenetwork".to_string()), + btcc: BlocksDominanceRewardsPattern::new(client.clone(), "btcc".to_string()), + bwpool: BlocksDominanceRewardsPattern::new(client.clone(), "bwpool".to_string()), + exxbw: BlocksDominanceRewardsPattern::new(client.clone(), "exxbw".to_string()), + bitsolo: BlocksDominanceRewardsPattern::new(client.clone(), "bitsolo".to_string()), + bitfury: BlocksDominanceRewardsPattern::new(client.clone(), "bitfury".to_string()), + twentyoneinc: BlocksDominanceRewardsPattern::new(client.clone(), "twentyoneinc".to_string()), + digitalbtc: BlocksDominanceRewardsPattern::new(client.clone(), "digitalbtc".to_string()), + eightbaochi: BlocksDominanceRewardsPattern::new(client.clone(), "eightbaochi".to_string()), + mybtccoinpool: BlocksDominanceRewardsPattern::new(client.clone(), "mybtccoinpool".to_string()), + tbdice: BlocksDominanceRewardsPattern::new(client.clone(), "tbdice".to_string()), + hashpool: BlocksDominanceRewardsPattern::new(client.clone(), "hashpool".to_string()), + nexious: BlocksDominanceRewardsPattern::new(client.clone(), "nexious".to_string()), + bravomining: BlocksDominanceRewardsPattern::new(client.clone(), "bravomining".to_string()), + hotpool: BlocksDominanceRewardsPattern::new(client.clone(), "hotpool".to_string()), + okexpool: BlocksDominanceRewardsPattern::new(client.clone(), "okexpool".to_string()), + bcmonster: BlocksDominanceRewardsPattern::new(client.clone(), "bcmonster".to_string()), + onehash: BlocksDominanceRewardsPattern::new(client.clone(), "onehash".to_string()), + bixin: BlocksDominanceRewardsPattern::new(client.clone(), "bixin".to_string()), + tatmaspool: BlocksDominanceRewardsPattern::new(client.clone(), "tatmaspool".to_string()), + viabtc: BlocksDominanceRewardsPattern::new(client.clone(), "viabtc".to_string()), + connectbtc: BlocksDominanceRewardsPattern::new(client.clone(), "connectbtc".to_string()), + batpool: BlocksDominanceRewardsPattern::new(client.clone(), "batpool".to_string()), + waterhole: BlocksDominanceRewardsPattern::new(client.clone(), "waterhole".to_string()), + dcexploration: BlocksDominanceRewardsPattern::new(client.clone(), "dcexploration".to_string()), + dcex: BlocksDominanceRewardsPattern::new(client.clone(), "dcex".to_string()), + btpool: BlocksDominanceRewardsPattern::new(client.clone(), "btpool".to_string()), + fiftyeightcoin: BlocksDominanceRewardsPattern::new(client.clone(), "fiftyeightcoin".to_string()), + bitcoinindia: BlocksDominanceRewardsPattern::new(client.clone(), "bitcoinindia".to_string()), + shawnp0wers: BlocksDominanceRewardsPattern::new(client.clone(), "shawnp0wers".to_string()), + phashio: BlocksDominanceRewardsPattern::new(client.clone(), "phashio".to_string()), + rigpool: BlocksDominanceRewardsPattern::new(client.clone(), "rigpool".to_string()), + haozhuzhu: BlocksDominanceRewardsPattern::new(client.clone(), "haozhuzhu".to_string()), + sevenpool: BlocksDominanceRewardsPattern::new(client.clone(), "sevenpool".to_string()), + miningkings: BlocksDominanceRewardsPattern::new(client.clone(), "miningkings".to_string()), + hashbx: BlocksDominanceRewardsPattern::new(client.clone(), "hashbx".to_string()), + dpool: BlocksDominanceRewardsPattern::new(client.clone(), "dpool".to_string()), + rawpool: BlocksDominanceRewardsPattern::new(client.clone(), "rawpool".to_string()), + haominer: BlocksDominanceRewardsPattern::new(client.clone(), "haominer".to_string()), + helix: BlocksDominanceRewardsPattern::new(client.clone(), "helix".to_string()), + bitcoinukraine: BlocksDominanceRewardsPattern::new(client.clone(), "bitcoinukraine".to_string()), + poolin: BlocksDominanceRewardsPattern::new(client.clone(), "poolin".to_string()), + secretsuperstar: BlocksDominanceRewardsPattern::new(client.clone(), "secretsuperstar".to_string()), + tigerpoolnet: BlocksDominanceRewardsPattern::new(client.clone(), "tigerpoolnet".to_string()), + sigmapoolcom: BlocksDominanceRewardsPattern::new(client.clone(), "sigmapoolcom".to_string()), + okpooltop: BlocksDominanceRewardsPattern::new(client.clone(), "okpooltop".to_string()), + hummerpool: BlocksDominanceRewardsPattern::new(client.clone(), "hummerpool".to_string()), + tangpool: BlocksDominanceRewardsPattern::new(client.clone(), "tangpool".to_string()), + bytepool: BlocksDominanceRewardsPattern::new(client.clone(), "bytepool".to_string()), + spiderpool: BlocksDominanceRewardsPattern::new(client.clone(), "spiderpool".to_string()), + novablock: BlocksDominanceRewardsPattern::new(client.clone(), "novablock".to_string()), + miningcity: BlocksDominanceRewardsPattern::new(client.clone(), "miningcity".to_string()), + binancepool: BlocksDominanceRewardsPattern::new(client.clone(), "binancepool".to_string()), + minerium: BlocksDominanceRewardsPattern::new(client.clone(), "minerium".to_string()), + lubiancom: BlocksDominanceRewardsPattern::new(client.clone(), "lubiancom".to_string()), + okkong: BlocksDominanceRewardsPattern::new(client.clone(), "okkong".to_string()), + aaopool: BlocksDominanceRewardsPattern::new(client.clone(), "aaopool".to_string()), + emcdpool: BlocksDominanceRewardsPattern::new(client.clone(), "emcdpool".to_string()), + foundryusa: BlocksDominanceRewardsPattern::new(client.clone(), "foundryusa".to_string()), + sbicrypto: BlocksDominanceRewardsPattern::new(client.clone(), "sbicrypto".to_string()), + arkpool: BlocksDominanceRewardsPattern::new(client.clone(), "arkpool".to_string()), + purebtccom: BlocksDominanceRewardsPattern::new(client.clone(), "purebtccom".to_string()), + marapool: BlocksDominanceRewardsPattern::new(client.clone(), "marapool".to_string()), + kucoinpool: BlocksDominanceRewardsPattern::new(client.clone(), "kucoinpool".to_string()), + entrustcharitypool: BlocksDominanceRewardsPattern::new(client.clone(), "entrustcharitypool".to_string()), + okminer: BlocksDominanceRewardsPattern::new(client.clone(), "okminer".to_string()), + titan: BlocksDominanceRewardsPattern::new(client.clone(), "titan".to_string()), + pegapool: BlocksDominanceRewardsPattern::new(client.clone(), "pegapool".to_string()), + btcnuggets: BlocksDominanceRewardsPattern::new(client.clone(), "btcnuggets".to_string()), + cloudhashing: BlocksDominanceRewardsPattern::new(client.clone(), "cloudhashing".to_string()), + digitalxmintsy: BlocksDominanceRewardsPattern::new(client.clone(), "digitalxmintsy".to_string()), + telco214: BlocksDominanceRewardsPattern::new(client.clone(), "telco214".to_string()), + btcpoolparty: BlocksDominanceRewardsPattern::new(client.clone(), "btcpoolparty".to_string()), + multipool: BlocksDominanceRewardsPattern::new(client.clone(), "multipool".to_string()), + transactioncoinmining: BlocksDominanceRewardsPattern::new(client.clone(), "transactioncoinmining".to_string()), + btcdig: BlocksDominanceRewardsPattern::new(client.clone(), "btcdig".to_string()), + trickysbtcpool: BlocksDominanceRewardsPattern::new(client.clone(), "trickysbtcpool".to_string()), + btcmp: BlocksDominanceRewardsPattern::new(client.clone(), "btcmp".to_string()), + eobot: BlocksDominanceRewardsPattern::new(client.clone(), "eobot".to_string()), + unomp: BlocksDominanceRewardsPattern::new(client.clone(), "unomp".to_string()), + patels: BlocksDominanceRewardsPattern::new(client.clone(), "patels".to_string()), + gogreenlight: BlocksDominanceRewardsPattern::new(client.clone(), "gogreenlight".to_string()), + bitcoinindiapool: BlocksDominanceRewardsPattern::new(client.clone(), "bitcoinindiapool".to_string()), + ekanembtc: BlocksDominanceRewardsPattern::new(client.clone(), "ekanembtc".to_string()), + canoe: BlocksDominanceRewardsPattern::new(client.clone(), "canoe".to_string()), + tiger: BlocksDominanceRewardsPattern::new(client.clone(), "tiger".to_string()), + onem1x: BlocksDominanceRewardsPattern::new(client.clone(), "onem1x".to_string()), + zulupool: BlocksDominanceRewardsPattern::new(client.clone(), "zulupool".to_string()), + secpool: BlocksDominanceRewardsPattern::new(client.clone(), "secpool".to_string()), + ocean: BlocksDominanceRewardsPattern::new(client.clone(), "ocean".to_string()), + whitepool: BlocksDominanceRewardsPattern::new(client.clone(), "whitepool".to_string()), + wiz: BlocksDominanceRewardsPattern::new(client.clone(), "wiz".to_string()), + wk057: BlocksDominanceRewardsPattern::new(client.clone(), "wk057".to_string()), + futurebitapollosolo: BlocksDominanceRewardsPattern::new(client.clone(), "futurebitapollosolo".to_string()), + carbonnegative: BlocksDominanceRewardsPattern::new(client.clone(), "carbonnegative".to_string()), + portlandhodl: BlocksDominanceRewardsPattern::new(client.clone(), "portlandhodl".to_string()), + phoenix: BlocksDominanceRewardsPattern::new(client.clone(), "phoenix".to_string()), + neopool: BlocksDominanceRewardsPattern::new(client.clone(), "neopool".to_string()), + maxipool: BlocksDominanceRewardsPattern::new(client.clone(), "maxipool".to_string()), + bitfufupool: BlocksDominanceRewardsPattern::new(client.clone(), "bitfufupool".to_string()), + gdpool: BlocksDominanceRewardsPattern::new(client.clone(), "gdpool".to_string()), + miningdutch: BlocksDominanceRewardsPattern::new(client.clone(), "miningdutch".to_string()), + publicpool: BlocksDominanceRewardsPattern::new(client.clone(), "publicpool".to_string()), + miningsquared: BlocksDominanceRewardsPattern::new(client.clone(), "miningsquared".to_string()), + innopolistech: BlocksDominanceRewardsPattern::new(client.clone(), "innopolistech".to_string()), + btclab: BlocksDominanceRewardsPattern::new(client.clone(), "btclab".to_string()), + parasite: BlocksDominanceRewardsPattern::new(client.clone(), "parasite".to_string()), + redrockpool: BlocksDominanceRewardsPattern::new(client.clone(), "redrockpool".to_string()), + est3lar: BlocksDominanceRewardsPattern::new(client.clone(), "est3lar".to_string()), } } } @@ -5669,7 +5567,7 @@ pub struct MetricsTree_Distribution_UtxoCohorts { pub amount_range: MetricsTree_Distribution_UtxoCohorts_AmountRange, pub lt_amount: MetricsTree_Distribution_UtxoCohorts_LtAmount, pub epoch: MetricsTree_Distribution_UtxoCohorts_Epoch, - pub year: MetricsTree_Distribution_UtxoCohorts_Year, + pub class: MetricsTree_Distribution_UtxoCohorts_Class, pub type_: MetricsTree_Distribution_UtxoCohorts_Type, } @@ -5686,7 +5584,7 @@ impl MetricsTree_Distribution_UtxoCohorts { 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")), epoch: MetricsTree_Distribution_UtxoCohorts_Epoch::new(client.clone(), format!("{base_path}_epoch")), - year: MetricsTree_Distribution_UtxoCohorts_Year::new(client.clone(), format!("{base_path}_year")), + class: MetricsTree_Distribution_UtxoCohorts_Class::new(client.clone(), format!("{base_path}_class")), type_: MetricsTree_Distribution_UtxoCohorts_Type::new(client.clone(), format!("{base_path}_type_")), } } @@ -5696,9 +5594,9 @@ impl MetricsTree_Distribution_UtxoCohorts { pub struct MetricsTree_Distribution_UtxoCohorts_All { pub supply: ChangeHalvedTotalPattern, pub outputs: UtxoPattern, - pub activity: CoinblocksCoindaysSatblocksSatdaysSentPattern, + pub activity: CoinblocksCoindaysSentPattern, pub realized: AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern, - pub cost_basis: InvestedMaxMinPercentilesSpotPattern, + pub cost_basis: InvestedMaxMinPercentilesPattern, pub unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern, pub relative: MetricsTree_Distribution_UtxoCohorts_All_Relative, } @@ -5708,9 +5606,9 @@ impl MetricsTree_Distribution_UtxoCohorts_All { Self { supply: ChangeHalvedTotalPattern::new(client.clone(), "supply".to_string()), outputs: UtxoPattern::new(client.clone(), "utxo_count".to_string()), - activity: CoinblocksCoindaysSatblocksSatdaysSentPattern::new(client.clone(), "".to_string()), + activity: CoinblocksCoindaysSentPattern::new(client.clone(), "".to_string()), realized: AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern::new(client.clone(), "".to_string()), - cost_basis: InvestedMaxMinPercentilesSpotPattern::new(client.clone(), "".to_string()), + cost_basis: InvestedMaxMinPercentilesPattern::new(client.clone(), "".to_string()), unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern::new(client.clone(), "".to_string()), relative: MetricsTree_Distribution_UtxoCohorts_All_Relative::new(client.clone(), format!("{base_path}_relative")), } @@ -5758,9 +5656,9 @@ impl MetricsTree_Distribution_UtxoCohorts_All_Relative { pub struct MetricsTree_Distribution_UtxoCohorts_Sth { pub supply: ChangeHalvedTotalPattern, pub outputs: UtxoPattern, - pub activity: CoinblocksCoindaysSatblocksSatdaysSentPattern, + pub activity: CoinblocksCoindaysSentPattern, pub realized: AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern, - pub cost_basis: InvestedMaxMinPercentilesSpotPattern, + pub cost_basis: InvestedMaxMinPercentilesPattern, pub unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern, pub relative: InvestedNegNetNuplSupplyUnrealizedPattern2, } @@ -5770,9 +5668,9 @@ impl MetricsTree_Distribution_UtxoCohorts_Sth { Self { supply: ChangeHalvedTotalPattern::new(client.clone(), "sth_supply".to_string()), outputs: UtxoPattern::new(client.clone(), "sth_utxo_count".to_string()), - activity: CoinblocksCoindaysSatblocksSatdaysSentPattern::new(client.clone(), "sth".to_string()), + activity: CoinblocksCoindaysSentPattern::new(client.clone(), "sth".to_string()), realized: AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern::new(client.clone(), "sth".to_string()), - cost_basis: InvestedMaxMinPercentilesSpotPattern::new(client.clone(), "sth".to_string()), + cost_basis: InvestedMaxMinPercentilesPattern::new(client.clone(), "sth".to_string()), unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern::new(client.clone(), "sth".to_string()), relative: InvestedNegNetNuplSupplyUnrealizedPattern2::new(client.clone(), "sth".to_string()), } @@ -6063,7 +5961,7 @@ impl MetricsTree_Distribution_UtxoCohorts_Epoch { } /// Metrics tree node. -pub struct MetricsTree_Distribution_UtxoCohorts_Year { +pub struct MetricsTree_Distribution_UtxoCohorts_Class { pub _2009: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3, pub _2010: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3, pub _2011: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3, @@ -6084,27 +5982,27 @@ pub struct MetricsTree_Distribution_UtxoCohorts_Year { pub _2026: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3, } -impl MetricsTree_Distribution_UtxoCohorts_Year { +impl MetricsTree_Distribution_UtxoCohorts_Class { pub fn new(client: Arc, base_path: String) -> Self { Self { - _2009: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2009".to_string()), - _2010: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2010".to_string()), - _2011: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2011".to_string()), - _2012: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2012".to_string()), - _2013: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2013".to_string()), - _2014: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2014".to_string()), - _2015: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2015".to_string()), - _2016: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2016".to_string()), - _2017: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2017".to_string()), - _2018: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2018".to_string()), - _2019: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2019".to_string()), - _2020: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2020".to_string()), - _2021: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2021".to_string()), - _2022: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2022".to_string()), - _2023: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2023".to_string()), - _2024: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2024".to_string()), - _2025: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2025".to_string()), - _2026: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "year_2026".to_string()), + _2009: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2009".to_string()), + _2010: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2010".to_string()), + _2011: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2011".to_string()), + _2012: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2012".to_string()), + _2013: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2013".to_string()), + _2014: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2014".to_string()), + _2015: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2015".to_string()), + _2016: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2016".to_string()), + _2017: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2017".to_string()), + _2018: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2018".to_string()), + _2019: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2019".to_string()), + _2020: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2020".to_string()), + _2021: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2021".to_string()), + _2022: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2022".to_string()), + _2023: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2023".to_string()), + _2024: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2024".to_string()), + _2025: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2025".to_string()), + _2026: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3::new(client.clone(), "class_2026".to_string()), } } } diff --git a/crates/brk_cohort/src/by_year.rs b/crates/brk_cohort/src/by_class.rs similarity index 71% rename from crates/brk_cohort/src/by_year.rs rename to crates/brk_cohort/src/by_class.rs index dc5c81dfc..7b4972915 100644 --- a/crates/brk_cohort/src/by_year.rs +++ b/crates/brk_cohort/src/by_class.rs @@ -5,8 +5,8 @@ use serde::Serialize; use super::{CohortName, Filter}; -/// Year values -pub const YEAR_VALUES: ByYear = ByYear { +/// Class values +pub const CLASS_VALUES: ByClass = ByClass { _2009: Year::new(2009), _2010: Year::new(2010), _2011: Year::new(2011), @@ -27,52 +27,52 @@ pub const YEAR_VALUES: ByYear = ByYear { _2026: Year::new(2026), }; -/// Year filters -pub const YEAR_FILTERS: ByYear = ByYear { - _2009: Filter::Year(YEAR_VALUES._2009), - _2010: Filter::Year(YEAR_VALUES._2010), - _2011: Filter::Year(YEAR_VALUES._2011), - _2012: Filter::Year(YEAR_VALUES._2012), - _2013: Filter::Year(YEAR_VALUES._2013), - _2014: Filter::Year(YEAR_VALUES._2014), - _2015: Filter::Year(YEAR_VALUES._2015), - _2016: Filter::Year(YEAR_VALUES._2016), - _2017: Filter::Year(YEAR_VALUES._2017), - _2018: Filter::Year(YEAR_VALUES._2018), - _2019: Filter::Year(YEAR_VALUES._2019), - _2020: Filter::Year(YEAR_VALUES._2020), - _2021: Filter::Year(YEAR_VALUES._2021), - _2022: Filter::Year(YEAR_VALUES._2022), - _2023: Filter::Year(YEAR_VALUES._2023), - _2024: Filter::Year(YEAR_VALUES._2024), - _2025: Filter::Year(YEAR_VALUES._2025), - _2026: Filter::Year(YEAR_VALUES._2026), +/// Class filters +pub const CLASS_FILTERS: ByClass = ByClass { + _2009: Filter::Class(CLASS_VALUES._2009), + _2010: Filter::Class(CLASS_VALUES._2010), + _2011: Filter::Class(CLASS_VALUES._2011), + _2012: Filter::Class(CLASS_VALUES._2012), + _2013: Filter::Class(CLASS_VALUES._2013), + _2014: Filter::Class(CLASS_VALUES._2014), + _2015: Filter::Class(CLASS_VALUES._2015), + _2016: Filter::Class(CLASS_VALUES._2016), + _2017: Filter::Class(CLASS_VALUES._2017), + _2018: Filter::Class(CLASS_VALUES._2018), + _2019: Filter::Class(CLASS_VALUES._2019), + _2020: Filter::Class(CLASS_VALUES._2020), + _2021: Filter::Class(CLASS_VALUES._2021), + _2022: Filter::Class(CLASS_VALUES._2022), + _2023: Filter::Class(CLASS_VALUES._2023), + _2024: Filter::Class(CLASS_VALUES._2024), + _2025: Filter::Class(CLASS_VALUES._2025), + _2026: Filter::Class(CLASS_VALUES._2026), }; -/// Year names -pub const YEAR_NAMES: ByYear = ByYear { - _2009: CohortName::new("year_2009", "2009", "Year 2009"), - _2010: CohortName::new("year_2010", "2010", "Year 2010"), - _2011: CohortName::new("year_2011", "2011", "Year 2011"), - _2012: CohortName::new("year_2012", "2012", "Year 2012"), - _2013: CohortName::new("year_2013", "2013", "Year 2013"), - _2014: CohortName::new("year_2014", "2014", "Year 2014"), - _2015: CohortName::new("year_2015", "2015", "Year 2015"), - _2016: CohortName::new("year_2016", "2016", "Year 2016"), - _2017: CohortName::new("year_2017", "2017", "Year 2017"), - _2018: CohortName::new("year_2018", "2018", "Year 2018"), - _2019: CohortName::new("year_2019", "2019", "Year 2019"), - _2020: CohortName::new("year_2020", "2020", "Year 2020"), - _2021: CohortName::new("year_2021", "2021", "Year 2021"), - _2022: CohortName::new("year_2022", "2022", "Year 2022"), - _2023: CohortName::new("year_2023", "2023", "Year 2023"), - _2024: CohortName::new("year_2024", "2024", "Year 2024"), - _2025: CohortName::new("year_2025", "2025", "Year 2025"), - _2026: CohortName::new("year_2026", "2026", "Year 2026"), +/// Class names +pub const CLASS_NAMES: ByClass = ByClass { + _2009: CohortName::new("class_2009", "2009", "Class 2009"), + _2010: CohortName::new("class_2010", "2010", "Class 2010"), + _2011: CohortName::new("class_2011", "2011", "Class 2011"), + _2012: CohortName::new("class_2012", "2012", "Class 2012"), + _2013: CohortName::new("class_2013", "2013", "Class 2013"), + _2014: CohortName::new("class_2014", "2014", "Class 2014"), + _2015: CohortName::new("class_2015", "2015", "Class 2015"), + _2016: CohortName::new("class_2016", "2016", "Class 2016"), + _2017: CohortName::new("class_2017", "2017", "Class 2017"), + _2018: CohortName::new("class_2018", "2018", "Class 2018"), + _2019: CohortName::new("class_2019", "2019", "Class 2019"), + _2020: CohortName::new("class_2020", "2020", "Class 2020"), + _2021: CohortName::new("class_2021", "2021", "Class 2021"), + _2022: CohortName::new("class_2022", "2022", "Class 2022"), + _2023: CohortName::new("class_2023", "2023", "Class 2023"), + _2024: CohortName::new("class_2024", "2024", "Class 2024"), + _2025: CohortName::new("class_2025", "2025", "Class 2025"), + _2026: CohortName::new("class_2026", "2026", "Class 2026"), }; #[derive(Default, Clone, Traversable, Serialize)] -pub struct ByYear { +pub struct ByClass { pub _2009: T, pub _2010: T, pub _2011: T, @@ -93,19 +93,19 @@ pub struct ByYear { pub _2026: T, } -impl ByYear { +impl ByClass { pub const fn names() -> &'static Self { - &YEAR_NAMES + &CLASS_NAMES } } -impl ByYear { +impl ByClass { pub fn new(mut create: F) -> Self where F: FnMut(Filter, &'static str) -> T, { - let f = YEAR_FILTERS; - let n = YEAR_NAMES; + let f = CLASS_FILTERS; + let n = CLASS_NAMES; Self { _2009: create(f._2009, n._2009.id), _2010: create(f._2010, n._2010.id), @@ -132,8 +132,8 @@ impl ByYear { where F: FnMut(Filter, &'static str) -> Result, { - let f = YEAR_FILTERS; - let n = YEAR_NAMES; + let f = CLASS_FILTERS; + let n = CLASS_NAMES; Ok(Self { _2009: create(f._2009, n._2009.id)?, _2010: create(f._2010, n._2010.id)?, diff --git a/crates/brk_cohort/src/cohort_context.rs b/crates/brk_cohort/src/cohort_context.rs index d2cf5ac1b..3b8706954 100644 --- a/crates/brk_cohort/src/cohort_context.rs +++ b/crates/brk_cohort/src/cohort_context.rs @@ -24,14 +24,14 @@ impl CohortContext { /// Build full name for a filter, adding prefix only for Time/Amount filters. /// /// Prefix rules: - /// - No prefix: `All`, `Term`, `Epoch`, `Year`, `Type` + /// - No prefix: `All`, `Term`, `Epoch`, `Class`, `Type` /// - Context prefix: `Time`, `Amount` pub fn full_name(&self, filter: &Filter, name: &str) -> String { match filter { Filter::All | Filter::Term(_) | Filter::Epoch(_) - | Filter::Year(_) + | Filter::Class(_) | Filter::Type(_) => name.to_string(), Filter::Time(_) | Filter::Amount(_) => self.prefixed(name), } diff --git a/crates/brk_cohort/src/filter.rs b/crates/brk_cohort/src/filter.rs index 1ddcb23d5..e1324afbb 100644 --- a/crates/brk_cohort/src/filter.rs +++ b/crates/brk_cohort/src/filter.rs @@ -9,7 +9,7 @@ pub enum Filter { Time(TimeFilter), Amount(AmountFilter), Epoch(HalvingEpoch), - Year(Year), + Class(Year), Type(OutputType), } diff --git a/crates/brk_cohort/src/lib.rs b/crates/brk_cohort/src/lib.rs index f5eb33c50..20edff925 100644 --- a/crates/brk_cohort/src/lib.rs +++ b/crates/brk_cohort/src/lib.rs @@ -15,7 +15,7 @@ mod by_spendable_type; mod by_term; mod by_type; mod by_unspendable_type; -mod by_year; +mod by_class; mod cohort_context; mod cohort_name; mod filter; @@ -41,7 +41,7 @@ pub use by_spendable_type::*; pub use by_term::*; pub use by_type::*; pub use by_unspendable_type::*; -pub use by_year::*; +pub use by_class::*; pub use cohort_context::*; pub use cohort_name::*; pub use filter::*; diff --git a/crates/brk_cohort/src/utxo.rs b/crates/brk_cohort/src/utxo.rs index 0ad67aa49..bf0da73c9 100644 --- a/crates/brk_cohort/src/utxo.rs +++ b/crates/brk_cohort/src/utxo.rs @@ -3,7 +3,7 @@ use rayon::prelude::*; use crate::{ ByAgeRange, ByAmountRange, ByEpoch, ByGreatEqualAmount, ByLowerThanAmount, ByMaxAge, ByMinAge, - BySpendableType, ByTerm, ByYear, Filter, + ByClass, BySpendableType, ByTerm, Filter, }; #[derive(Default, Clone, Traversable)] @@ -11,7 +11,7 @@ pub struct UTXOGroups { pub all: T, pub age_range: ByAgeRange, pub epoch: ByEpoch, - pub year: ByYear, + pub class: ByClass, pub min_age: ByMinAge, pub ge_amount: ByGreatEqualAmount, pub amount_range: ByAmountRange, @@ -30,7 +30,7 @@ impl UTXOGroups { all: create(Filter::All, ""), age_range: ByAgeRange::new(&mut create), epoch: ByEpoch::new(&mut create), - year: ByYear::new(&mut create), + class: ByClass::new(&mut create), min_age: ByMinAge::new(&mut create), ge_amount: ByGreatEqualAmount::new(&mut create), amount_range: ByAmountRange::new(&mut create), @@ -50,7 +50,7 @@ impl UTXOGroups { .chain(self.ge_amount.iter()) .chain(self.age_range.iter()) .chain(self.epoch.iter()) - .chain(self.year.iter()) + .chain(self.class.iter()) .chain(self.amount_range.iter()) .chain(self.lt_amount.iter()) .chain(self.type_.iter()) @@ -65,7 +65,7 @@ impl UTXOGroups { .chain(self.ge_amount.iter_mut()) .chain(self.age_range.iter_mut()) .chain(self.epoch.iter_mut()) - .chain(self.year.iter_mut()) + .chain(self.class.iter_mut()) .chain(self.amount_range.iter_mut()) .chain(self.lt_amount.iter_mut()) .chain(self.type_.iter_mut()) @@ -83,7 +83,7 @@ impl UTXOGroups { .chain(self.ge_amount.par_iter_mut()) .chain(self.age_range.par_iter_mut()) .chain(self.epoch.par_iter_mut()) - .chain(self.year.par_iter_mut()) + .chain(self.class.par_iter_mut()) .chain(self.amount_range.par_iter_mut()) .chain(self.lt_amount.par_iter_mut()) .chain(self.type_.par_iter_mut()) @@ -93,7 +93,7 @@ impl UTXOGroups { self.age_range .iter() .chain(self.epoch.iter()) - .chain(self.year.iter()) + .chain(self.class.iter()) .chain(self.amount_range.iter()) .chain(self.type_.iter()) } @@ -102,7 +102,7 @@ impl UTXOGroups { self.age_range .iter_mut() .chain(self.epoch.iter_mut()) - .chain(self.year.iter_mut()) + .chain(self.class.iter_mut()) .chain(self.amount_range.iter_mut()) .chain(self.type_.iter_mut()) } @@ -114,7 +114,7 @@ impl UTXOGroups { self.age_range .par_iter_mut() .chain(self.epoch.par_iter_mut()) - .chain(self.year.par_iter_mut()) + .chain(self.class.par_iter_mut()) .chain(self.amount_range.par_iter_mut()) .chain(self.type_.par_iter_mut()) } diff --git a/crates/brk_computer/.gitignore b/crates/brk_computer/.gitignore index b1536b76e..b1b7655f2 100644 --- a/crates/brk_computer/.gitignore +++ b/crates/brk_computer/.gitignore @@ -1,3 +1,4 @@ *.md !README.md /*.py +/*.json diff --git a/crates/brk_computer/src/distribution/cohorts/address/groups.rs b/crates/brk_computer/src/distribution/cohorts/address/groups.rs index a54acfe1e..24b666726 100644 --- a/crates/brk_computer/src/distribution/cohorts/address/groups.rs +++ b/crates/brk_computer/src/distribution/cohorts/address/groups.rs @@ -111,13 +111,8 @@ impl AddressCohorts { self.par_iter_mut() .try_for_each(|v| v.compute_rest_part1(blocks, prices, starting_indexes, exit))?; - // 2. Compute net_sentiment.height for separate cohorts (greed - pain) - self.par_iter_separate_mut().try_for_each(|v| { - v.metrics - .compute_net_sentiment_height(starting_indexes, exit) - })?; - - // 3. Compute net_sentiment.height for aggregate cohorts (weighted average) + // 3. Compute net_sentiment.height for aggregate cohorts (weighted average). + // Separate cohorts already computed net_sentiment in step 2 (inside compute_rest_part1). self.for_each_aggregate(|vecs, sources| { let metrics: Vec<_> = sources.iter().map(|v| &v.metrics).collect(); vecs.metrics diff --git a/crates/brk_computer/src/distribution/cohorts/address/vecs.rs b/crates/brk_computer/src/distribution/cohorts/address/vecs.rs index 17cd556dd..dd7f56bec 100644 --- a/crates/brk_computer/src/distribution/cohorts/address/vecs.rs +++ b/crates/brk_computer/src/distribution/cohorts/address/vecs.rs @@ -189,12 +189,14 @@ impl DynCohortVecs for AddressCohortVecs { &mut self, height: Height, height_price: Cents, + is_day_boundary: bool, ) -> Result<()> { if let Some(state) = self.state.as_mut() { self.metrics.compute_then_truncate_push_unrealized_states( height, height_price, &mut state.inner, + is_day_boundary, )?; } Ok(()) @@ -209,18 +211,15 @@ impl DynCohortVecs for AddressCohortVecs { ) -> Result<()> { self.metrics .compute_rest_part1(blocks, prices, starting_indexes, exit)?; + // Separate cohorts (with state) compute net_sentiment = greed - pain directly. + // Aggregate cohorts get it via weighted average in groups.rs. + if self.state.is_some() { + self.metrics + .compute_net_sentiment_height(starting_indexes, exit)?; + } Ok(()) } - fn compute_net_sentiment_height( - &mut self, - starting_indexes: &Indexes, - exit: &Exit, - ) -> Result<()> { - self.metrics - .compute_net_sentiment_height(starting_indexes, exit) - } - fn write_state(&mut self, height: Height, cleanup: bool) -> Result<()> { if let Some(state) = self.state.as_mut() { state.inner.write(height, cleanup)?; diff --git a/crates/brk_computer/src/distribution/cohorts/traits.rs b/crates/brk_computer/src/distribution/cohorts/traits.rs index 8616a717d..b1f8c4eff 100644 --- a/crates/brk_computer/src/distribution/cohorts/traits.rs +++ b/crates/brk_computer/src/distribution/cohorts/traits.rs @@ -28,6 +28,7 @@ pub trait DynCohortVecs: Send + Sync { &mut self, height: Height, height_price: Cents, + is_day_boundary: bool, ) -> Result<()>; /// First phase of post-processing computations. @@ -39,13 +40,6 @@ pub trait DynCohortVecs: Send + Sync { exit: &Exit, ) -> Result<()>; - /// Compute net_sentiment.height for separate cohorts (greed - pain). - fn compute_net_sentiment_height( - &mut self, - starting_indexes: &Indexes, - exit: &Exit, - ) -> Result<()>; - /// Write state checkpoint to disk. fn write_state(&mut self, height: Height, cleanup: bool) -> Result<()>; diff --git a/crates/brk_computer/src/distribution/cohorts/utxo/groups.rs b/crates/brk_computer/src/distribution/cohorts/utxo/groups.rs index 9fd630a3b..49142ea2a 100644 --- a/crates/brk_computer/src/distribution/cohorts/utxo/groups.rs +++ b/crates/brk_computer/src/distribution/cohorts/utxo/groups.rs @@ -2,7 +2,7 @@ use std::path::Path; use brk_cohort::{ ByAgeRange, ByAmountRange, ByEpoch, ByGreatEqualAmount, ByLowerThanAmount, ByMaxAge, ByMinAge, - BySpendableType, ByYear, CohortContext, Filter, Term, + ByClass, BySpendableType, CohortContext, Filter, Term, }; use brk_error::Result; use brk_traversable::Traversable; @@ -17,7 +17,7 @@ use crate::distribution::metrics::{ ExtendedAdjustedCohortMetrics, ExtendedCohortMetrics, ImportConfig, SupplyMetrics, }; -use super::vecs::UTXOCohortVecs; +use super::{percentiles::PercentileCache, vecs::UTXOCohortVecs}; use crate::distribution::state::UTXOCohortState; @@ -27,7 +27,7 @@ const VERSION: Version = Version::new(0); /// /// Each group uses a concrete metrics type matching its required features: /// - age_range: extended realized + extended cost basis -/// - epoch/year/amount/type: basic metrics with relative +/// - epoch/class/amount/type: basic metrics with relative /// - all: extended + adjusted (no rel_to_all) /// - sth: extended + adjusted /// - lth: extended @@ -45,23 +45,22 @@ pub struct UTXOCohorts { pub amount_range: ByAmountRange>>, pub lt_amount: ByLowerThanAmount>>, pub epoch: ByEpoch>>, - pub year: ByYear>>, + pub class: ByClass>>, pub type_: BySpendableType>>, + #[traversable(skip)] + pub(super) percentile_cache: PercentileCache, + /// Cached partition_point positions for tick_tock boundary searches. + /// Avoids O(log n) binary search per boundary per block; scans forward + /// from last known position (typically O(1) per boundary). + #[traversable(skip)] + pub(super) tick_tock_cached_positions: [usize; 20], } -macro_rules! collect_separate { - ($self:expr, $method:ident, $trait_ref:ty) => {{ - let mut v: Vec<$trait_ref> = Vec::with_capacity(UTXOCohorts::SEPARATE_COHORT_CAPACITY); - v.extend($self.age_range.$method().map(|x| x as $trait_ref)); - v.extend($self.epoch.$method().map(|x| x as $trait_ref)); - v.extend($self.year.$method().map(|x| x as $trait_ref)); - v.extend($self.amount_range.$method().map(|x| x as $trait_ref)); - v.extend($self.type_.$method().map(|x| x as $trait_ref)); - v - }}; -} impl UTXOCohorts { + /// ~71 separate cohorts (21 age + 5 epoch + 18 class + 15 amount + 12 type) + const SEPARATE_COHORT_CAPACITY: usize = 80; + /// Import all UTXO cohorts from database. pub(crate) fn forced_import( db: &Database, @@ -123,7 +122,7 @@ impl UTXOCohorts { let amount_range = ByAmountRange::try_new(&basic_separate)?; let epoch = ByEpoch::try_new(&basic_separate)?; - let year = ByYear::try_new(&basic_separate)?; + let class = ByClass::try_new(&basic_separate)?; let type_ = BySpendableType::try_new(&basic_separate)?; // Phase 3: Import "all" cohort with pre-imported supply. @@ -223,7 +222,7 @@ impl UTXOCohorts { sth, lth, epoch, - year, + class, type_, max_age, min_age, @@ -231,26 +230,39 @@ impl UTXOCohorts { amount_range, lt_amount, ge_amount, + percentile_cache: PercentileCache::default(), + tick_tock_cached_positions: [0; 20], }) } - /// ~71 separate cohorts (21 age + 5 epoch + 18 year + 15 amount + 12 type) - const SEPARATE_COHORT_CAPACITY: usize = 80; - pub(crate) fn par_iter_separate_mut( &mut self, ) -> impl ParallelIterator { - collect_separate!(self, iter_mut, &mut dyn DynCohortVecs).into_par_iter() + let Self { + age_range, epoch, class, amount_range, type_, .. + } = self; + age_range + .par_iter_mut() + .map(|x| x as &mut dyn DynCohortVecs) + .chain(epoch.par_iter_mut().map(|x| x as &mut dyn DynCohortVecs)) + .chain(class.par_iter_mut().map(|x| x as &mut dyn DynCohortVecs)) + .chain( + amount_range + .par_iter_mut() + .map(|x| x as &mut dyn DynCohortVecs), + ) + .chain(type_.par_iter_mut().map(|x| x as &mut dyn DynCohortVecs)) } /// Immutable iterator over all separate (stateful) cohorts. pub(crate) fn iter_separate(&self) -> impl Iterator { - collect_separate!(self, iter, &dyn DynCohortVecs).into_iter() - } - - /// Mutable iterator over all separate cohorts (non-parallel). - pub(crate) fn iter_separate_mut(&mut self) -> impl Iterator { - collect_separate!(self, iter_mut, &mut dyn DynCohortVecs).into_iter() + self.age_range + .iter() + .map(|x| x as &dyn DynCohortVecs) + .chain(self.epoch.iter().map(|x| x as &dyn DynCohortVecs)) + .chain(self.class.iter().map(|x| x as &dyn DynCohortVecs)) + .chain(self.amount_range.iter().map(|x| x as &dyn DynCohortVecs)) + .chain(self.type_.iter().map(|x| x as &dyn DynCohortVecs)) } pub(crate) fn compute_overlapping_vecs( @@ -258,90 +270,53 @@ impl UTXOCohorts { starting_indexes: &Indexes, exit: &Exit, ) -> Result<()> { - let age_range = &self.age_range; - let amount_range = &self.amount_range; + let Self { + all, sth, lth, age_range, max_age, min_age, + ge_amount, amount_range, lt_amount, + .. + } = self; - // all: aggregate of all age_range - // Note: realized.extended rolling sums are computed from base in compute_rest_part2. - // Note: cost_basis.extended percentiles are computed in truncate_push_aggregate_percentiles. - { - let sources_dyn: Vec<&dyn CohortMetricsBase> = age_range - .iter() - .map(|v| &v.metrics as &dyn CohortMetricsBase) - .collect(); - self.all - .metrics - .compute_base_from_others(starting_indexes, &sources_dyn, exit)?; - } + let ar = &*age_range; + let amr = &*amount_range; + let si = starting_indexes; - // sth: aggregate of matching age_range - { - let sth_filter = self.sth.metrics.filter().clone(); - let sources_dyn: Vec<&dyn CohortMetricsBase> = age_range - .iter() - .filter(|v| sth_filter.includes(v.metrics.filter())) - .map(|v| &v.metrics as &dyn CohortMetricsBase) - .collect(); - self.sth - .metrics - .compute_base_from_others(starting_indexes, &sources_dyn, exit)?; - } + let tasks: Vec Result<()> + Send + '_>> = vec![ + Box::new(|| { + let sources = filter_sources_from(ar.iter(), None); + all.metrics.compute_base_from_others(si, &sources, exit) + }), + Box::new(|| { + let sources = filter_sources_from(ar.iter(), Some(sth.metrics.filter())); + sth.metrics.compute_base_from_others(si, &sources, exit) + }), + Box::new(|| { + let sources = filter_sources_from(ar.iter(), Some(lth.metrics.filter())); + lth.metrics.compute_base_from_others(si, &sources, exit) + }), + Box::new(|| { + min_age.par_iter_mut().try_for_each(|vecs| { + let sources = filter_sources_from(ar.iter(), Some(vecs.metrics.filter())); + vecs.metrics.compute_base_from_others(si, &sources, exit) + }) + }), + Box::new(|| { + max_age.par_iter_mut().try_for_each(|vecs| { + let sources = filter_sources_from(ar.iter(), Some(vecs.metrics.filter())); + vecs.metrics.compute_base_from_others(si, &sources, exit) + }) + }), + Box::new(|| { + ge_amount.par_iter_mut().chain(lt_amount.par_iter_mut()).try_for_each(|vecs| { + let sources = filter_sources_from(amr.iter(), Some(vecs.metrics.filter())); + vecs.metrics.compute_base_from_others(si, &sources, exit) + }) + }), + ]; - // lth: aggregate of matching age_range - { - let lth_filter = self.lth.metrics.filter().clone(); - let sources_dyn: Vec<&dyn CohortMetricsBase> = age_range - .iter() - .filter(|v| lth_filter.includes(v.metrics.filter())) - .map(|v| &v.metrics as &dyn CohortMetricsBase) - .collect(); - self.lth - .metrics - .compute_base_from_others(starting_indexes, &sources_dyn, exit)?; - } - - // min_age: base from matching age_range - self.min_age - .par_iter_mut() - .try_for_each(|vecs| -> Result<()> { - let filter = vecs.metrics.filter().clone(); - let sources_dyn: Vec<&dyn CohortMetricsBase> = age_range - .iter() - .filter(|v| filter.includes(v.metrics.filter())) - .map(|v| &v.metrics as &dyn CohortMetricsBase) - .collect(); - vecs.metrics - .compute_base_from_others(starting_indexes, &sources_dyn, exit) - })?; - - // max_age: base + peak_regret from matching age_range - self.max_age - .par_iter_mut() - .try_for_each(|vecs| -> Result<()> { - let filter = vecs.metrics.filter().clone(); - let sources_dyn: Vec<&dyn CohortMetricsBase> = age_range - .iter() - .filter(|v| filter.includes(v.metrics.filter())) - .map(|v| &v.metrics as &dyn CohortMetricsBase) - .collect(); - vecs.metrics - .compute_base_from_others(starting_indexes, &sources_dyn, exit) - })?; - - // ge_amount, lt_amount: base only from matching amount_range - self.ge_amount - .par_iter_mut() - .chain(self.lt_amount.par_iter_mut()) - .try_for_each(|vecs| { - let filter = vecs.metrics.filter().clone(); - let sources_dyn: Vec<&dyn CohortMetricsBase> = amount_range - .iter() - .filter(|v| filter.includes(v.metrics.filter())) - .map(|v| &v.metrics as &dyn CohortMetricsBase) - .collect(); - vecs.metrics - .compute_base_from_others(starting_indexes, &sources_dyn, exit) - })?; + tasks + .into_par_iter() + .map(|f| f()) + .collect::>>()?; Ok(()) } @@ -373,7 +348,7 @@ impl UTXOCohorts { .map(|x| x as &mut dyn DynCohortVecs), ); all.extend(self.epoch.iter_mut().map(|x| x as &mut dyn DynCohortVecs)); - all.extend(self.year.iter_mut().map(|x| x as &mut dyn DynCohortVecs)); + all.extend(self.class.iter_mut().map(|x| x as &mut dyn DynCohortVecs)); all.extend( self.amount_range .iter_mut() @@ -389,100 +364,56 @@ impl UTXOCohorts { .try_for_each(|v| v.compute_rest_part1(blocks, prices, starting_indexes, exit))?; } - // 2. Compute net_sentiment.height for separate cohorts (greed - pain) - self.par_iter_separate_mut() - .try_for_each(|v| v.compute_net_sentiment_height(starting_indexes, exit))?; - - // 3. Compute net_sentiment.height for aggregate cohorts (weighted average) + // 2. Compute net_sentiment.height for aggregate cohorts (weighted average). + // Separate cohorts already computed net_sentiment in step 1 (inside compute_rest_part1). { - let age_range = &self.age_range; - let amount_range = &self.amount_range; + let Self { + all, sth, lth, age_range, max_age, min_age, + ge_amount, amount_range, lt_amount, + .. + } = self; - // all - { - let sources: Vec<_> = age_range - .iter() - .map(|v| &v.metrics as &dyn CohortMetricsBase) - .collect(); - self.all.metrics.compute_net_sentiment_from_others_dyn( - starting_indexes, - &sources, - exit, - )?; - } + let ar = &*age_range; + let amr = &*amount_range; + let si = starting_indexes; - // sth - { - let filter = self.sth.metrics.filter().clone(); - let sources: Vec<_> = age_range - .iter() - .filter(|v| filter.includes(v.metrics.filter())) - .map(|v| &v.metrics as &dyn CohortMetricsBase) - .collect(); - self.sth.metrics.compute_net_sentiment_from_others_dyn( - starting_indexes, - &sources, - exit, - )?; - } + let tasks: Vec Result<()> + Send + '_>> = vec![ + Box::new(|| { + let sources = filter_sources_from(ar.iter(), None); + all.metrics.compute_net_sentiment_from_others_dyn(si, &sources, exit) + }), + Box::new(|| { + let sources = filter_sources_from(ar.iter(), Some(sth.metrics.filter())); + sth.metrics.compute_net_sentiment_from_others_dyn(si, &sources, exit) + }), + Box::new(|| { + let sources = filter_sources_from(ar.iter(), Some(lth.metrics.filter())); + lth.metrics.compute_net_sentiment_from_others_dyn(si, &sources, exit) + }), + Box::new(|| { + min_age.par_iter_mut().try_for_each(|vecs| { + let sources = filter_sources_from(ar.iter(), Some(vecs.metrics.filter())); + vecs.metrics.compute_net_sentiment_from_others_dyn(si, &sources, exit) + }) + }), + Box::new(|| { + max_age.par_iter_mut().try_for_each(|vecs| { + let sources = filter_sources_from(ar.iter(), Some(vecs.metrics.filter())); + vecs.metrics.compute_net_sentiment_from_others_dyn(si, &sources, exit) + }) + }), + Box::new(|| { + ge_amount.par_iter_mut().chain(lt_amount.par_iter_mut()).try_for_each(|vecs| { + let sources = filter_sources_from(amr.iter(), Some(vecs.metrics.filter())); + vecs.metrics.compute_net_sentiment_from_others_dyn(si, &sources, exit) + }) + }), + ]; - // lth - { - let filter = self.lth.metrics.filter().clone(); - let sources: Vec<_> = age_range - .iter() - .filter(|v| filter.includes(v.metrics.filter())) - .map(|v| &v.metrics as &dyn CohortMetricsBase) - .collect(); - self.lth.metrics.compute_net_sentiment_from_others_dyn( - starting_indexes, - &sources, - exit, - )?; - } - - // min_age, max_age from age_range - for vecs in self.min_age.iter_mut() { - let filter = vecs.metrics.filter().clone(); - let sources: Vec<_> = age_range - .iter() - .filter(|v| filter.includes(v.metrics.filter())) - .map(|v| &v.metrics as &dyn CohortMetricsBase) - .collect(); - vecs.metrics.compute_net_sentiment_from_others_dyn( - starting_indexes, - &sources, - exit, - )?; - } - for vecs in self.max_age.iter_mut() { - let filter = vecs.metrics.filter().clone(); - let sources: Vec<_> = age_range - .iter() - .filter(|v| filter.includes(v.metrics.filter())) - .map(|v| &v.metrics as &dyn CohortMetricsBase) - .collect(); - vecs.metrics.compute_net_sentiment_from_others_dyn( - starting_indexes, - &sources, - exit, - )?; - } - - // ge_amount, lt_amount from amount_range - for vecs in self.ge_amount.iter_mut().chain(self.lt_amount.iter_mut()) { - let filter = vecs.metrics.filter().clone(); - let sources: Vec<_> = amount_range - .iter() - .filter(|v| filter.includes(v.metrics.filter())) - .map(|v| &v.metrics as &dyn CohortMetricsBase) - .collect(); - vecs.metrics.compute_net_sentiment_from_others_dyn( - starting_indexes, - &sources, - exit, - )?; - } + tasks + .into_par_iter() + .map(|f| f()) + .collect::>>()?; } Ok(()) @@ -532,116 +463,37 @@ impl UTXOCohorts { // Clone all_supply_sats for non-all cohorts. let all_supply_sats = self.all.metrics.supply.total.sats.height.read_only_clone(); - self.sth.metrics.compute_rest_part2( - blocks, - prices, - starting_indexes, - height_to_market_cap, - &up_to_1h_value_created, - &up_to_1h_value_destroyed, - &all_supply_sats, - exit, - )?; - self.lth.metrics.compute_rest_part2( - blocks, - prices, - starting_indexes, - height_to_market_cap, - &all_supply_sats, - exit, - )?; - self.age_range.par_iter_mut().try_for_each(|v| { - v.metrics.compute_rest_part2( - blocks, - prices, - starting_indexes, - height_to_market_cap, - &all_supply_sats, - exit, - ) - })?; - self.max_age.par_iter_mut().try_for_each(|v| { - v.metrics.compute_rest_part2( - blocks, - prices, - starting_indexes, - height_to_market_cap, - &up_to_1h_value_created, - &up_to_1h_value_destroyed, - &all_supply_sats, - exit, - ) - })?; - self.min_age.par_iter_mut().try_for_each(|v| { - v.metrics.compute_rest_part2( - blocks, - prices, - starting_indexes, - height_to_market_cap, - &all_supply_sats, - exit, - ) - })?; - self.ge_amount.par_iter_mut().try_for_each(|v| { - v.metrics.compute_rest_part2( - blocks, - prices, - starting_indexes, - height_to_market_cap, - &all_supply_sats, - exit, - ) - })?; - self.epoch.par_iter_mut().try_for_each(|v| { - v.metrics.compute_rest_part2( - blocks, - prices, - starting_indexes, - height_to_market_cap, - &all_supply_sats, - exit, - ) - })?; - self.year.par_iter_mut().try_for_each(|v| { - v.metrics.compute_rest_part2( - blocks, - prices, - starting_indexes, - height_to_market_cap, - &all_supply_sats, - exit, - ) - })?; - self.amount_range.par_iter_mut().try_for_each(|v| { - v.metrics.compute_rest_part2( - blocks, - prices, - starting_indexes, - height_to_market_cap, - &all_supply_sats, - exit, - ) - })?; - self.lt_amount.par_iter_mut().try_for_each(|v| { - v.metrics.compute_rest_part2( - blocks, - prices, - starting_indexes, - height_to_market_cap, - &all_supply_sats, - exit, - ) - })?; - self.type_.par_iter_mut().try_for_each(|v| { - v.metrics.compute_rest_part2( - blocks, - prices, - starting_indexes, - height_to_market_cap, - &all_supply_sats, - exit, - ) - })?; + // Destructure to allow parallel mutable access to independent fields. + let Self { + sth, lth, age_range, max_age, min_age, + ge_amount, amount_range, lt_amount, epoch, class, type_, .. + } = self; + + // All remaining groups run in parallel. Each closure owns an exclusive &mut + // to its field and shares read-only references to common data. + let vc = &up_to_1h_value_created; + let vd = &up_to_1h_value_destroyed; + let ss = &all_supply_sats; + + let tasks: Vec Result<()> + Send + '_>> = vec![ + Box::new(|| sth.metrics.compute_rest_part2(blocks, prices, starting_indexes, height_to_market_cap, vc, vd, ss, exit)), + Box::new(|| lth.metrics.compute_rest_part2(blocks, prices, starting_indexes, height_to_market_cap, ss, exit)), + Box::new(|| age_range.par_iter_mut().try_for_each(|v| v.metrics.compute_rest_part2(blocks, prices, starting_indexes, height_to_market_cap, ss, exit))), + Box::new(|| max_age.par_iter_mut().try_for_each(|v| v.metrics.compute_rest_part2(blocks, prices, starting_indexes, height_to_market_cap, vc, vd, ss, exit))), + Box::new(|| min_age.par_iter_mut().try_for_each(|v| v.metrics.compute_rest_part2(blocks, prices, starting_indexes, height_to_market_cap, ss, exit))), + Box::new(|| ge_amount.par_iter_mut().try_for_each(|v| v.metrics.compute_rest_part2(blocks, prices, starting_indexes, height_to_market_cap, ss, exit))), + Box::new(|| epoch.par_iter_mut().try_for_each(|v| v.metrics.compute_rest_part2(blocks, prices, starting_indexes, height_to_market_cap, ss, exit))), + Box::new(|| class.par_iter_mut().try_for_each(|v| v.metrics.compute_rest_part2(blocks, prices, starting_indexes, height_to_market_cap, ss, exit))), + Box::new(|| amount_range.par_iter_mut().try_for_each(|v| v.metrics.compute_rest_part2(blocks, prices, starting_indexes, height_to_market_cap, ss, exit))), + Box::new(|| lt_amount.par_iter_mut().try_for_each(|v| v.metrics.compute_rest_part2(blocks, prices, starting_indexes, height_to_market_cap, ss, exit))), + Box::new(|| type_.par_iter_mut().try_for_each(|v| v.metrics.compute_rest_part2(blocks, prices, starting_indexes, height_to_market_cap, ss, exit))), + ]; + + tasks + .into_par_iter() + .map(|f| f()) + .collect::>>()?; + Ok(()) } @@ -668,7 +520,7 @@ impl UTXOCohorts { for v in self.epoch.iter_mut() { vecs.extend(v.metrics.collect_all_vecs_mut()); } - for v in self.year.iter_mut() { + for v in self.class.iter_mut() { vecs.extend(v.metrics.collect_all_vecs_mut()); } for v in self.amount_range.iter_mut() { @@ -744,3 +596,20 @@ impl UTXOCohorts { Ok(()) } } + +/// Filter source cohorts by an optional filter, returning dyn CohortMetricsBase refs. +/// If filter is None, returns all sources (used for "all" aggregate). +fn filter_sources_from<'a, M: CohortMetricsBase + 'a>( + sources: impl Iterator>, + filter: Option<&Filter>, +) -> Vec<&'a dyn CohortMetricsBase> { + match filter { + Some(f) => sources + .filter(|v| f.includes(v.metrics.filter())) + .map(|v| &v.metrics as &dyn CohortMetricsBase) + .collect(), + None => sources + .map(|v| &v.metrics as &dyn CohortMetricsBase) + .collect(), + } +} diff --git a/crates/brk_computer/src/distribution/cohorts/utxo/percentiles.rs b/crates/brk_computer/src/distribution/cohorts/utxo/percentiles.rs index 2a3bbe3c2..63b31b7ba 100644 --- a/crates/brk_computer/src/distribution/cohorts/utxo/percentiles.rs +++ b/crates/brk_computer/src/distribution/cohorts/utxo/percentiles.rs @@ -2,45 +2,69 @@ use std::{cmp::Reverse, collections::BinaryHeap, fs, path::Path}; use brk_cohort::{Filtered, TERM_NAMES}; use brk_error::Result; -use brk_types::{ - BasisPoints16, Cents, CentsCompact, CostBasisDistribution, Date, Height, Sats, -}; -use vecdb::WritableVec; +use brk_types::{Cents, CentsCompact, CostBasisDistribution, Date, Height, Sats}; -use crate::internal::{PERCENTILES, PERCENTILES_LEN, compute_spot_percentile_rank}; +use crate::internal::{PERCENTILES, PERCENTILES_LEN}; use crate::distribution::metrics::{CohortMetricsBase, CostBasisExtended}; use super::groups::UTXOCohorts; -/// Significant digits for cost basis prices (after rounding to dollars). const COST_BASIS_PRICE_DIGITS: i32 = 5; +#[derive(Clone, Default)] +pub(super) struct CachedPercentiles { + sat_result: [Cents; PERCENTILES_LEN], + usd_result: [Cents; PERCENTILES_LEN], +} + +impl CachedPercentiles { + fn push(&self, height: Height, ext: &mut CostBasisExtended) -> Result<()> { + ext.push_arrays(height, &self.sat_result, &self.usd_result) + } +} + +/// Cached percentile results for all/sth/lth. +/// Avoids re-merging 21 BTreeMaps on every block. +#[derive(Clone, Default)] +pub(super) struct PercentileCache { + all: CachedPercentiles, + sth: CachedPercentiles, + lth: CachedPercentiles, + initialized: bool, +} + impl UTXOCohorts { /// Compute and push percentiles for aggregate cohorts (all, sth, lth). /// - /// Single K-way merge pass over all age_range cohorts computes percentiles - /// for all 3 targets simultaneously, since each cohort belongs to exactly - /// one of STH/LTH and always contributes to ALL. - /// - /// Uses BinaryHeap with direct BTreeMap iterators — O(log K) merge - /// with zero intermediate Vec allocation. + /// Full K-way merge only runs at day boundaries or when the cache is empty. + /// For intermediate blocks, pushes cached percentile arrays. pub(crate) fn truncate_push_aggregate_percentiles( &mut self, height: Height, - spot: Cents, + date_opt: Option, + states_path: &Path, + ) -> Result<()> { + if date_opt.is_some() || !self.percentile_cache.initialized { + self.merge_and_push_percentiles(height, date_opt, states_path) + } else { + self.push_cached_percentiles(height) + } + } + + /// Full K-way merge: compute percentiles from scratch, update cache, push. + fn merge_and_push_percentiles( + &mut self, + height: Height, date_opt: Option, states_path: &Path, ) -> Result<()> { let collect_merged = date_opt.is_some(); - // Phase 1: compute totals + merge. - // Scoped so age_range borrows release before push_target borrows self.all/sth/lth. let targets = { let sth_filter = self.sth.metrics.filter().clone(); let mut totals = AllSthLth::<(u64, u128)>::default(); - // Collect BTreeMap refs from age_range, skip empty, compute totals. let maps: Vec<_> = self .age_range .iter() @@ -75,76 +99,121 @@ impl UTXOCohorts { let all_has_data = totals.all.0 > 0; let mut targets = totals.map(|(sats, usd)| PercTarget::new(sats, usd, cap)); - // K-way merge via BinaryHeap + BTreeMap iterators (no Vec copies) if all_has_data { - let mut iters: Vec<_> = maps - .iter() - .map(|(map, is_sth)| (map.iter().peekable(), *is_sth)) - .collect(); - - let mut heap: BinaryHeap> = - BinaryHeap::with_capacity(iters.len()); - for (i, (iter, _)) in iters.iter_mut().enumerate() { - if let Some(&(&price, _)) = iter.peek() { - heap.push(Reverse((price, i))); - } - } - - let mut current_price: Option = None; - let mut early_exit = false; - - while let Some(Reverse((price, ci))) = heap.pop() { - let (ref mut iter, is_sth) = iters[ci]; - let (_, &sats) = iter.next().unwrap(); - let amount = u64::from(sats); - let usd = Cents::from(price).as_u128() * amount as u128; - - if let Some(prev) = current_price - && prev != price - { - targets - .for_each_mut(|t| t.finalize_price(prev.into(), collect_merged)); - if !collect_merged && targets.all_match(|t| t.done()) { - early_exit = true; - break; - } - } - - current_price = Some(price); - targets.all.accumulate(amount, usd); - targets.term_mut(is_sth).accumulate(amount, usd); - - if let Some(&(&next_price, _)) = iter.peek() { - heap.push(Reverse((next_price, ci))); - } - } - - if !early_exit - && let Some(price) = current_price - { - targets.for_each_mut(|t| t.finalize_price(price.into(), collect_merged)); - } + merge_k_way(&maps, &mut targets, collect_merged); } targets }; - // Phase 2: push results (borrows self.all/sth/lth mutably) - push_target( - height, spot, date_opt, states_path, targets.all, - &mut self.all.metrics.cost_basis.extended, "all", - )?; - push_target( - height, spot, date_opt, states_path, targets.sth, - &mut self.sth.metrics.cost_basis.extended, TERM_NAMES.short.id, - )?; - push_target( - height, spot, date_opt, states_path, targets.lth, - &mut self.lth.metrics.cost_basis.extended, TERM_NAMES.long.id, - )?; + // Update cache + push + self.percentile_cache.all = targets.all.to_cached(); + self.percentile_cache.sth = targets.sth.to_cached(); + self.percentile_cache.lth = targets.lth.to_cached(); + self.percentile_cache.initialized = true; + + self.percentile_cache + .all + .push(height, &mut self.all.metrics.cost_basis.extended)?; + self.percentile_cache + .sth + .push(height, &mut self.sth.metrics.cost_basis.extended)?; + self.percentile_cache + .lth + .push(height, &mut self.lth.metrics.cost_basis.extended)?; + + // Serialize full distribution at day boundaries + if let Some(date) = date_opt { + write_distribution(states_path, "all", date, targets.all.merged)?; + write_distribution(states_path, TERM_NAMES.short.id, date, targets.sth.merged)?; + write_distribution(states_path, TERM_NAMES.long.id, date, targets.lth.merged)?; + } Ok(()) } + + /// Fast path: push cached percentile arrays. + fn push_cached_percentiles(&mut self, height: Height) -> Result<()> { + self.percentile_cache + .all + .push(height, &mut self.all.metrics.cost_basis.extended)?; + self.percentile_cache + .sth + .push(height, &mut self.sth.metrics.cost_basis.extended)?; + self.percentile_cache + .lth + .push(height, &mut self.lth.metrics.cost_basis.extended)?; + Ok(()) + } +} + +fn write_distribution( + states_path: &Path, + name: &str, + date: Date, + merged: Vec<(CentsCompact, Sats)>, +) -> Result<()> { + let dir = states_path.join(format!("utxo_{name}_cost_basis/by_date")); + fs::create_dir_all(&dir)?; + fs::write( + dir.join(date.to_string()), + CostBasisDistribution::serialize_iter(merged.into_iter())?, + )?; + Ok(()) +} + +/// K-way merge via BinaryHeap over BTreeMap iterators. +fn merge_k_way( + maps: &[(&std::collections::BTreeMap, bool)], + targets: &mut AllSthLth, + collect_merged: bool, +) { + let mut iters: Vec<_> = maps + .iter() + .map(|(map, is_sth)| (map.iter().peekable(), *is_sth)) + .collect(); + + let mut heap: BinaryHeap> = + BinaryHeap::with_capacity(iters.len()); + for (i, (iter, _)) in iters.iter_mut().enumerate() { + if let Some(&(&price, _)) = iter.peek() { + heap.push(Reverse((price, i))); + } + } + + let mut current_price: Option = None; + let mut early_exit = false; + + while let Some(Reverse((price, ci))) = heap.pop() { + let (ref mut iter, is_sth) = iters[ci]; + let (_, &sats) = iter.next().unwrap(); + let amount = u64::from(sats); + let usd = Cents::from(price).as_u128() * amount as u128; + + if let Some(prev) = current_price + && prev != price + { + targets.for_each_mut(|t| t.finalize_price(prev.into(), collect_merged)); + if !collect_merged && targets.all_match(|t| t.done()) { + early_exit = true; + break; + } + } + + current_price = Some(price); + targets.all.accumulate(amount, usd); + targets.term_mut(is_sth).accumulate(amount, usd); + + if let Some(&(&next_price, _)) = iter.peek() { + heap.push(Reverse((next_price, ci))); + } + } + + if !early_exit + && let Some(price) = current_price + { + targets.for_each_mut(|t| t.finalize_price(price.into(), collect_merged)); + } } struct AllSthLth { @@ -230,6 +299,13 @@ impl PercTarget { } } + fn to_cached(&self) -> CachedPercentiles { + CachedPercentiles { + sat_result: self.sat_result, + usd_result: self.usd_result, + } + } + #[inline] fn accumulate(&mut self, amount: u64, usd: u128) { self.price_sats += amount; @@ -275,48 +351,3 @@ impl PercTarget { && (self.total_usd == 0 || self.usd_idx >= PERCENTILES_LEN) } } - -#[allow(clippy::too_many_arguments)] -fn push_target( - height: Height, - spot: Cents, - date_opt: Option, - states_path: &Path, - target: PercTarget, - ext: &mut CostBasisExtended, - name: &str, -) -> Result<()> { - ext.percentiles.truncate_push(height, &target.sat_result)?; - ext.invested_capital - .truncate_push(height, &target.usd_result)?; - - let sat_rank = if target.total_sats > 0 { - compute_spot_percentile_rank(&target.sat_result, spot) - } else { - BasisPoints16::ZERO - }; - ext.spot_cost_basis_percentile - .bps - .height - .truncate_push(height, sat_rank)?; - - let usd_rank = if target.total_usd > 0 { - compute_spot_percentile_rank(&target.usd_result, spot) - } else { - BasisPoints16::ZERO - }; - ext.spot_invested_capital_percentile - .bps - .height - .truncate_push(height, usd_rank)?; - - if let Some(date) = date_opt { - let dir = states_path.join(format!("utxo_{name}_cost_basis/by_date")); - fs::create_dir_all(&dir)?; - fs::write( - dir.join(date.to_string()), - CostBasisDistribution::serialize_iter(target.merged.into_iter())?, - )?; - } - Ok(()) -} diff --git a/crates/brk_computer/src/distribution/cohorts/utxo/receive.rs b/crates/brk_computer/src/distribution/cohorts/utxo/receive.rs index 0b091d19c..ae0add351 100644 --- a/crates/brk_computer/src/distribution/cohorts/utxo/receive.rs +++ b/crates/brk_computer/src/distribution/cohorts/utxo/receive.rs @@ -11,7 +11,7 @@ impl UTXOCohorts { /// New UTXOs are added to: /// - The "up_to_1h" age cohort (all new UTXOs start at 0 hours old) /// - The appropriate epoch cohort based on block height - /// - The appropriate year cohort based on block timestamp + /// - The appropriate class cohort based on block timestamp /// - The appropriate output type cohort (P2PKH, P2SH, etc.) /// - The appropriate amount range cohort based on value pub(crate) fn receive( @@ -26,7 +26,7 @@ impl UTXOCohorts { // Pre-compute snapshot once for the 3 cohorts sharing the same supply_state let snapshot = CostBasisSnapshot::from_utxo(price, &supply_state); - // New UTXOs go into up_to_1h, current epoch, and current year + // New UTXOs go into up_to_1h, current epoch, and current class self.age_range .up_to_1h .state @@ -39,7 +39,7 @@ impl UTXOCohorts { .as_mut() .unwrap() .receive_utxo_snapshot(&supply_state, &snapshot); - self.year + self.class .mut_vec_from_timestamp(timestamp) .state .as_mut() diff --git a/crates/brk_computer/src/distribution/cohorts/utxo/send.rs b/crates/brk_computer/src/distribution/cohorts/utxo/send.rs index 51efb03f3..260e19c4b 100644 --- a/crates/brk_computer/src/distribution/cohorts/utxo/send.rs +++ b/crates/brk_computer/src/distribution/cohorts/utxo/send.rs @@ -70,7 +70,7 @@ impl UTXOCohorts { .as_mut() .unwrap() .send_utxo_precomputed(&sent.spendable_supply, &pre); - self.year + self.class .mut_vec_from_timestamp(block_state.timestamp) .state .as_mut() @@ -86,7 +86,7 @@ impl UTXOCohorts { .as_mut() .unwrap() .supply -= &sent.spendable_supply; - self.year + self.class .mut_vec_from_timestamp(block_state.timestamp) .state .as_mut() diff --git a/crates/brk_computer/src/distribution/cohorts/utxo/tick_tock.rs b/crates/brk_computer/src/distribution/cohorts/utxo/tick_tock.rs index ca25557c4..2f6e76ed3 100644 --- a/crates/brk_computer/src/distribution/cohorts/utxo/tick_tock.rs +++ b/crates/brk_computer/src/distribution/cohorts/utxo/tick_tock.rs @@ -1,6 +1,6 @@ use brk_cohort::AGE_BOUNDARIES; use brk_types::{CostBasisSnapshot, ONE_HOUR_IN_SEC, Timestamp}; -use vecdb::Rw; +use vecdb::{Rw, unlikely}; use crate::distribution::state::BlockState; @@ -12,10 +12,9 @@ impl UTXOCohorts { /// UTXOs age with each block. When they cross hour boundaries, /// they move between age-based cohorts (e.g., from "0-1h" to "1h-1d"). /// - /// Complexity: O(k * log n) where: - /// - k = 20 boundaries to check - /// - n = total blocks in chain_state - /// - Linear scan for end_idx is faster than binary search since typically 0-2 blocks cross each boundary + /// Uses cached positions per boundary to avoid binary search. + /// Since timestamps are monotonic, positions only advance forward. + /// Complexity: O(k * c) where k = 20 boundaries, c = ~1 (forward scan steps). pub(crate) fn tick_tock_next_block( &mut self, chain_state: &[BlockState], @@ -38,6 +37,7 @@ impl UTXOCohorts { // Cohort 0 covers [0, 1) hours // Cohort 20 covers [15*365*24, infinity) hours let mut age_cohorts: Vec<_> = self.age_range.iter_mut().map(|v| &mut v.state).collect(); + let cached = &mut self.tick_tock_cached_positions; // For each boundary (in hours), find blocks that just crossed it for (boundary_idx, &boundary_hours) in AGE_BOUNDARIES.iter().enumerate() { @@ -54,8 +54,24 @@ impl UTXOCohorts { continue; } - // Binary search to find start, then linear scan for end (typically 0-2 blocks) - let start_idx = chain_state.partition_point(|b| *b.timestamp <= lower_timestamp); + // Find start_idx: use cached position + forward scan (O(1) typical). + // On first call after restart, cached is 0 so fall back to binary search. + let start_idx = if unlikely(cached[boundary_idx] == 0 && chain_state.len() > 1) { + let idx = chain_state.partition_point(|b| *b.timestamp <= lower_timestamp); + cached[boundary_idx] = idx; + idx + } else { + let mut idx = cached[boundary_idx]; + while idx < chain_state.len() + && *chain_state[idx].timestamp <= lower_timestamp + { + idx += 1; + } + cached[boundary_idx] = idx; + idx + }; + + // Linear scan for end (typically 0-2 blocks past start) let end_idx = chain_state[start_idx..] .iter() .position(|b| *b.timestamp > upper_timestamp) diff --git a/crates/brk_computer/src/distribution/cohorts/utxo/vecs.rs b/crates/brk_computer/src/distribution/cohorts/utxo/vecs.rs index 5d97bfcb8..3e9ab1eaf 100644 --- a/crates/brk_computer/src/distribution/cohorts/utxo/vecs.rs +++ b/crates/brk_computer/src/distribution/cohorts/utxo/vecs.rs @@ -110,12 +110,14 @@ impl DynCohortVecs for UTXOCohortVecs< &mut self, height: Height, height_price: Cents, + is_day_boundary: bool, ) -> Result<()> { if let Some(state) = self.state.as_mut() { self.metrics.compute_then_truncate_push_unrealized_states( height, height_price, state, + is_day_boundary, )?; } Ok(()) @@ -129,16 +131,14 @@ impl DynCohortVecs for UTXOCohortVecs< exit: &Exit, ) -> Result<()> { self.metrics - .compute_rest_part1(blocks, prices, starting_indexes, exit) - } - - fn compute_net_sentiment_height( - &mut self, - starting_indexes: &Indexes, - exit: &Exit, - ) -> Result<()> { - self.metrics - .compute_net_sentiment_height(starting_indexes, exit) + .compute_rest_part1(blocks, prices, starting_indexes, exit)?; + // Separate cohorts (with state) compute net_sentiment = greed - pain directly. + // Aggregate cohorts get it via weighted average in groups.rs. + if self.state.is_some() { + self.metrics + .compute_net_sentiment_height(starting_indexes, exit)?; + } + Ok(()) } fn write_state(&mut self, height: Height, cleanup: bool) -> Result<()> { diff --git a/crates/brk_computer/src/distribution/compute/block_loop.rs b/crates/brk_computer/src/distribution/compute/block_loop.rs index a394255e3..cfec2099d 100644 --- a/crates/brk_computer/src/distribution/compute/block_loop.rs +++ b/crates/brk_computer/src/distribution/compute/block_loop.rs @@ -1,5 +1,3 @@ -use std::thread; - use brk_cohort::ByAddressType; use brk_error::Result; use brk_indexer::Indexer; @@ -95,6 +93,15 @@ pub(crate) fn process_blocks( let height_to_timestamp_collected = &cached_timestamps[start_usize..end_usize]; let height_to_price_collected = &cached_prices[start_usize..end_usize]; + // Pre-compute day boundaries to avoid per-block division in the hot loop + let is_last_of_day: Vec = (start_usize..end_usize) + .map(|h| { + h == end_usize - 1 + || *cached_timestamps[h] / ONE_DAY_IN_SEC + != *cached_timestamps[h + 1] / ONE_DAY_IN_SEC + }) + .collect(); + debug!("creating VecsReaders"); let mut vr = VecsReaders::new(&vecs.any_address_indexes, &vecs.addresses_data); debug!("VecsReaders created"); @@ -246,14 +253,11 @@ pub(crate) fn process_blocks( p2wsh: TypeIndex::from(first_p2wsh_vec[offset].to_usize()), }; - // Reset per-block values for all separate cohorts - reset_block_values(&mut vecs.utxo_cohorts, &mut vecs.address_cohorts); - // Reset per-block activity counts activity_counts.reset(); // Collect output/input data using reusable iterators (16KB buffered reads) - // Must be done before thread::scope since iterators aren't Send + // Must be done before rayon::join since iterators aren't Send let txoutdata_vec = txout_iters.collect_block_outputs(first_txoutindex, output_count); let (input_values, input_prev_heights, input_outputtypes, input_typeindexes) = @@ -263,55 +267,54 @@ pub(crate) fn process_blocks( (&[][..], &[][..], &[][..], &[][..]) }; - // Process outputs and inputs in parallel with tick-tock - let (outputs_result, inputs_result) = thread::scope(|scope| -> Result<_> { - // Tick-tock age transitions in background - scope.spawn(|| { + // Process outputs, inputs, and tick-tock in parallel via rayon::join + let (_, oi_result) = rayon::join( + || { vecs.utxo_cohorts .tick_tock_next_block(chain_state, timestamp); - }); - - let outputs_handle = scope.spawn(|| { - // Process outputs (receive) - process_outputs( - txoutindex_to_txindex, - txoutdata_vec, - &first_addressindexes, - &cache, - &vr, - &vecs.any_address_indexes, - &vecs.addresses_data, - ) - }); - - // Process inputs (send) - skip coinbase input - let inputs_result = if input_count > 1 { - process_inputs( - input_count - 1, - &txinindex_to_txindex[1..], // Skip coinbase - input_values, - input_outputtypes, - input_typeindexes, - input_prev_heights, - &first_addressindexes, - &cache, - &vr, - &vecs.any_address_indexes, - &vecs.addresses_data, - )? - } else { - InputsResult { - height_to_sent: Default::default(), - sent_data: Default::default(), - address_data: Default::default(), - txindex_vecs: Default::default(), - } - }; - - let outputs_result = outputs_handle.join().unwrap()?; - - Ok((outputs_result, inputs_result)) - })?; + }, + || -> Result<_> { + let (outputs_result, inputs_result) = rayon::join( + || { + process_outputs( + txoutindex_to_txindex, + txoutdata_vec, + &first_addressindexes, + &cache, + &vr, + &vecs.any_address_indexes, + &vecs.addresses_data, + ) + }, + || -> Result<_> { + if input_count > 1 { + process_inputs( + input_count - 1, + &txinindex_to_txindex[1..], + input_values, + input_outputtypes, + input_typeindexes, + input_prev_heights, + &first_addressindexes, + &cache, + &vr, + &vecs.any_address_indexes, + &vecs.addresses_data, + ) + } else { + Ok(InputsResult { + height_to_sent: Default::default(), + sent_data: Default::default(), + address_data: Default::default(), + txindex_vecs: Default::default(), + }) + } + }, + ); + Ok((outputs_result?, inputs_result?)) + }, + ); + let (outputs_result, inputs_result) = oi_result?; // Merge new address data into current cache cache.merge_funded(outputs_result.address_data); @@ -363,11 +366,20 @@ pub(crate) fn process_blocks( } // Process UTXO cohorts and Address cohorts in parallel - // - Main thread: UTXO cohorts receive/send - // - Spawned thread: Address cohorts process_received/process_sent - thread::scope(|scope| { - // Spawn address cohort processing in background thread - scope.spawn(|| { + let (_, addr_result) = rayon::join( + || { + // UTXO cohorts receive/send + vecs.utxo_cohorts + .receive(transacted, height, timestamp, block_price); + if let Some(min_h) = + vecs.utxo_cohorts + .send(height_to_sent, chain_state, ctx.price_range_max) + { + min_supply_modified = + Some(min_supply_modified.map_or(min_h, |cur| cur.min(min_h))); + } + }, + || -> Result<()> { let mut lookup = cache.as_lookup(); // Process received outputs (addresses receiving funds) @@ -382,7 +394,6 @@ pub(crate) fn process_blocks( ); // Process sent inputs (addresses sending funds) - // Uses separate price/timestamp vecs to avoid borrowing chain_state process_sent( inputs_result.sent_data, &mut vecs.address_cohorts, @@ -399,19 +410,9 @@ pub(crate) fn process_blocks( timestamp, &mut seen_senders, ) - .unwrap(); - }); - - // Main thread: Update UTXO cohorts - vecs.utxo_cohorts - .receive(transacted, height, timestamp, block_price); - if let Some(min_h) = - vecs.utxo_cohorts - .send(height_to_sent, chain_state, ctx.price_range_max) - { - min_supply_modified = Some(min_supply_modified.map_or(min_h, |cur| cur.min(min_h))); - } - }); + }, + ); + addr_result?; // Push to height-indexed vectors vecs.addr_count @@ -424,9 +425,7 @@ pub(crate) fn process_blocks( vecs.address_activity .truncate_push_height(height, &activity_counts)?; - let h = height.to_usize(); - let is_last_of_day = height == last_height - || *cached_timestamps[h] / ONE_DAY_IN_SEC != *cached_timestamps[h + 1] / ONE_DAY_IN_SEC; + let is_last_of_day = is_last_of_day[offset]; let date_opt = is_last_of_day.then(|| Date::from(timestamp)); push_cohort_states( @@ -434,11 +433,11 @@ pub(crate) fn process_blocks( &mut vecs.address_cohorts, height, block_price, + date_opt.is_some(), )?; vecs.utxo_cohorts.truncate_push_aggregate_percentiles( height, - block_price, date_opt, &vecs.states_path, )?; @@ -494,36 +493,42 @@ pub(crate) fn process_blocks( Ok(()) } -/// Reset per-block values for all separate cohorts. -fn reset_block_values(utxo_cohorts: &mut UTXOCohorts, address_cohorts: &mut AddressCohorts) { - utxo_cohorts - .iter_separate_mut() - .for_each(|v| v.reset_single_iteration_values()); - - address_cohorts - .iter_separate_mut() - .for_each(|v| v.reset_single_iteration_values()); -} - -/// Push cohort states to height-indexed vectors. +/// Push cohort states to height-indexed vectors, then reset per-block values. fn push_cohort_states( utxo_cohorts: &mut UTXOCohorts, address_cohorts: &mut AddressCohorts, height: Height, height_price: Cents, + is_day_boundary: bool, ) -> Result<()> { let (r1, r2) = rayon::join( || { - utxo_cohorts.par_iter_separate_mut().try_for_each(|v| { - v.truncate_push(height)?; - v.compute_then_truncate_push_unrealized_states(height, height_price) - }) + utxo_cohorts + .par_iter_separate_mut() + .try_for_each(|v| -> Result<()> { + v.truncate_push(height)?; + v.compute_then_truncate_push_unrealized_states( + height, + height_price, + is_day_boundary, + )?; + v.reset_single_iteration_values(); + Ok(()) + }) }, || { - address_cohorts.par_iter_separate_mut().try_for_each(|v| { - v.truncate_push(height)?; - v.compute_then_truncate_push_unrealized_states(height, height_price) - }) + address_cohorts + .par_iter_separate_mut() + .try_for_each(|v| -> Result<()> { + v.truncate_push(height)?; + v.compute_then_truncate_push_unrealized_states( + height, + height_price, + is_day_boundary, + )?; + v.reset_single_iteration_values(); + Ok(()) + }) }, ); r1?; diff --git a/crates/brk_computer/src/distribution/metrics/activity.rs b/crates/brk_computer/src/distribution/metrics/activity.rs index 61a474950..b8bbd0d4c 100644 --- a/crates/brk_computer/src/distribution/metrics/activity.rs +++ b/crates/brk_computer/src/distribution/metrics/activity.rs @@ -2,9 +2,7 @@ use brk_error::Result; use brk_traversable::Traversable; use brk_types::{Bitcoin, Height, Indexes, Sats, StoredF64, Version}; use rayon::prelude::*; -use vecdb::{ - AnyStoredVec, AnyVec, EagerVec, Exit, ImportableVec, PcoVec, Rw, StorageMode, WritableVec, -}; +use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec}; use crate::{ blocks, @@ -22,16 +20,10 @@ pub struct ActivityMetrics { /// 14-day EMA of sent supply (sats, btc, usd) pub sent_ema: RollingEmas2w, - /// Satoshi-blocks destroyed (supply * blocks_old when spent) - pub satblocks_destroyed: M::Stored>>, - - /// Satoshi-days destroyed (supply * days_old when spent) - pub satdays_destroyed: M::Stored>>, - - /// Coin-blocks destroyed (in BTC rather than sats) + /// Coin-blocks destroyed (in BTC) pub coinblocks_destroyed: ComputedFromHeightCumulativeSum, - /// Coin-days destroyed (in BTC rather than sats) + /// Coin-days destroyed (in BTC) pub coindays_destroyed: ComputedFromHeightCumulativeSum, } @@ -42,20 +34,9 @@ impl ActivityMetrics { sent: cfg.import_value_cumulative("sent", Version::ZERO)?, sent_ema: cfg.import_emas_2w("sent", Version::ZERO)?, - satblocks_destroyed: EagerVec::forced_import( - cfg.db, - &cfg.name("satblocks_destroyed"), - cfg.version, - )?, - satdays_destroyed: EagerVec::forced_import( - cfg.db, - &cfg.name("satdays_destroyed"), - cfg.version, - )?, - coinblocks_destroyed: cfg - .import_cumulative_sum("coinblocks_destroyed", Version::ZERO)?, - coindays_destroyed: cfg.import_cumulative_sum("coindays_destroyed", Version::ZERO)?, + .import_cumulative_sum("coinblocks_destroyed", Version::ONE)?, + coindays_destroyed: cfg.import_cumulative_sum("coindays_destroyed", Version::ONE)?, }) } @@ -66,8 +47,8 @@ impl ActivityMetrics { .sats .height .len() - .min(self.satblocks_destroyed.len()) - .min(self.satdays_destroyed.len()) + .min(self.coinblocks_destroyed.height.len()) + .min(self.coindays_destroyed.height.len()) } /// Push activity state values to height-indexed vectors. @@ -79,10 +60,14 @@ impl ActivityMetrics { satdays_destroyed: Sats, ) -> Result<()> { self.sent.base.sats.height.truncate_push(height, sent)?; - self.satblocks_destroyed - .truncate_push(height, satblocks_destroyed)?; - self.satdays_destroyed - .truncate_push(height, satdays_destroyed)?; + self.coinblocks_destroyed.height.truncate_push( + height, + StoredF64::from(Bitcoin::from(satblocks_destroyed)), + )?; + self.coindays_destroyed.height.truncate_push( + height, + StoredF64::from(Bitcoin::from(satdays_destroyed)), + )?; Ok(()) } @@ -90,8 +75,8 @@ impl ActivityMetrics { pub(crate) fn par_iter_mut(&mut self) -> impl ParallelIterator { vec![ &mut self.sent.base.sats.height as &mut dyn AnyStoredVec, - &mut self.satblocks_destroyed as &mut dyn AnyStoredVec, - &mut self.satdays_destroyed as &mut dyn AnyStoredVec, + &mut self.coinblocks_destroyed.height as &mut dyn AnyStoredVec, + &mut self.coindays_destroyed.height as &mut dyn AnyStoredVec, ] .into_par_iter() } @@ -120,8 +105,8 @@ impl ActivityMetrics { } sum_others!(sent.base.sats.height); - sum_others!(satblocks_destroyed); - sum_others!(satdays_destroyed); + sum_others!(coinblocks_destroyed.height); + sum_others!(coindays_destroyed.height); Ok(()) } @@ -144,26 +129,10 @@ impl ActivityMetrics { )?; self.coinblocks_destroyed - .compute(starting_indexes.height, &window_starts, exit, |v| { - v.compute_transform( - starting_indexes.height, - &self.satblocks_destroyed, - |(i, v, ..)| (i, StoredF64::from(Bitcoin::from(v))), - exit, - )?; - Ok(()) - })?; + .compute_rest(starting_indexes.height, &window_starts, exit)?; self.coindays_destroyed - .compute(starting_indexes.height, &window_starts, exit, |v| { - v.compute_transform( - starting_indexes.height, - &self.satdays_destroyed, - |(i, v, ..)| (i, StoredF64::from(Bitcoin::from(v))), - exit, - )?; - Ok(()) - })?; + .compute_rest(starting_indexes.height, &window_starts, exit)?; Ok(()) } diff --git a/crates/brk_computer/src/distribution/metrics/cohort/adjusted.rs b/crates/brk_computer/src/distribution/metrics/cohort/adjusted.rs index 249128b95..1e7478bef 100644 --- a/crates/brk_computer/src/distribution/metrics/cohort/adjusted.rs +++ b/crates/brk_computer/src/distribution/metrics/cohort/adjusted.rs @@ -5,7 +5,7 @@ use brk_types::{Cents, Dollars, Height, Indexes, Sats, Version}; use rayon::prelude::*; use vecdb::{AnyStoredVec, Exit, ReadableVec, Rw, StorageMode}; -use crate::{blocks, distribution::state::CohortState, prices}; +use crate::{blocks, prices}; use crate::distribution::metrics::{ ActivityMetrics, CohortMetricsBase, CostBasisBase, ImportConfig, OutputsMetrics, RealizedBase, @@ -73,18 +73,6 @@ impl CohortMetricsBase for AdjustedCohortMetrics { self.activity.validate_computed_versions(base_version)?; Ok(()) } - fn compute_then_truncate_push_unrealized_states( - &mut self, - height: Height, - height_price: Cents, - state: &mut CohortState, - ) -> Result<()> { - state.apply_pending(); - self.cost_basis.truncate_push_minmax(height, state)?; - let unrealized_state = state.compute_unrealized_state(height_price); - self.unrealized.truncate_push(height, &unrealized_state)?; - Ok(()) - } fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> { let mut vecs: Vec<&mut dyn AnyStoredVec> = Vec::new(); vecs.extend(self.supply.par_iter_mut().collect::>()); diff --git a/crates/brk_computer/src/distribution/metrics/cohort/all.rs b/crates/brk_computer/src/distribution/metrics/cohort/all.rs index 9f5e1e82a..8a3d256e1 100644 --- a/crates/brk_computer/src/distribution/metrics/cohort/all.rs +++ b/crates/brk_computer/src/distribution/metrics/cohort/all.rs @@ -80,14 +80,12 @@ impl CohortMetricsBase for AllCohortMetrics { height: Height, height_price: Cents, state: &mut CohortState, + is_day_boundary: bool, ) -> Result<()> { - state.apply_pending(); - self.cost_basis.truncate_push_minmax(height, state)?; - let unrealized_state = state.compute_unrealized_state(height_price); - self.unrealized.truncate_push(height, &unrealized_state)?; + self.compute_and_push_unrealized_base(height, height_price, state)?; self.cost_basis .extended - .truncate_push_percentiles(height, state, height_price)?; + .truncate_push_percentiles(height, state, is_day_boundary)?; Ok(()) } fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> { diff --git a/crates/brk_computer/src/distribution/metrics/cohort/basic.rs b/crates/brk_computer/src/distribution/metrics/cohort/basic.rs index 27a3a3dc5..e573104b7 100644 --- a/crates/brk_computer/src/distribution/metrics/cohort/basic.rs +++ b/crates/brk_computer/src/distribution/metrics/cohort/basic.rs @@ -1,11 +1,11 @@ use brk_cohort::Filter; use brk_error::Result; use brk_traversable::Traversable; -use brk_types::{Cents, Dollars, Height, Indexes, Sats, Version}; +use brk_types::{Dollars, Height, Indexes, Sats, Version}; use rayon::prelude::*; use vecdb::{AnyStoredVec, Exit, ReadableVec, Rw, StorageMode}; -use crate::{blocks, distribution::state::CohortState, prices}; +use crate::{blocks, prices}; use crate::distribution::metrics::{ ActivityMetrics, CohortMetricsBase, CostBasisBase, ImportConfig, OutputsMetrics, RealizedBase, @@ -72,18 +72,6 @@ impl CohortMetricsBase for BasicCohortMetrics { self.activity.validate_computed_versions(base_version)?; Ok(()) } - fn compute_then_truncate_push_unrealized_states( - &mut self, - height: Height, - height_price: Cents, - state: &mut CohortState, - ) -> Result<()> { - state.apply_pending(); - self.cost_basis.truncate_push_minmax(height, state)?; - let unrealized_state = state.compute_unrealized_state(height_price); - self.unrealized.truncate_push(height, &unrealized_state)?; - Ok(()) - } fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> { let mut vecs: Vec<&mut dyn AnyStoredVec> = Vec::new(); vecs.extend(self.supply.par_iter_mut().collect::>()); diff --git a/crates/brk_computer/src/distribution/metrics/cohort/extended.rs b/crates/brk_computer/src/distribution/metrics/cohort/extended.rs index c7c0b7c5f..0416a9a3f 100644 --- a/crates/brk_computer/src/distribution/metrics/cohort/extended.rs +++ b/crates/brk_computer/src/distribution/metrics/cohort/extended.rs @@ -80,14 +80,12 @@ impl CohortMetricsBase for ExtendedCohortMetrics { height: Height, height_price: Cents, state: &mut CohortState, + is_day_boundary: bool, ) -> Result<()> { - state.apply_pending(); - self.cost_basis.truncate_push_minmax(height, state)?; - let unrealized_state = state.compute_unrealized_state(height_price); - self.unrealized.truncate_push(height, &unrealized_state)?; + self.compute_and_push_unrealized_base(height, height_price, state)?; self.cost_basis .extended - .truncate_push_percentiles(height, state, height_price)?; + .truncate_push_percentiles(height, state, is_day_boundary)?; Ok(()) } fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> { diff --git a/crates/brk_computer/src/distribution/metrics/cohort/extended_adjusted.rs b/crates/brk_computer/src/distribution/metrics/cohort/extended_adjusted.rs index ca959db72..31139aa6d 100644 --- a/crates/brk_computer/src/distribution/metrics/cohort/extended_adjusted.rs +++ b/crates/brk_computer/src/distribution/metrics/cohort/extended_adjusted.rs @@ -79,14 +79,12 @@ impl CohortMetricsBase for ExtendedAdjustedCohortMetrics { height: Height, height_price: Cents, state: &mut CohortState, + is_day_boundary: bool, ) -> Result<()> { - state.apply_pending(); - self.cost_basis.truncate_push_minmax(height, state)?; - let unrealized_state = state.compute_unrealized_state(height_price); - self.unrealized.truncate_push(height, &unrealized_state)?; + self.compute_and_push_unrealized_base(height, height_price, state)?; self.cost_basis .extended - .truncate_push_percentiles(height, state, height_price)?; + .truncate_push_percentiles(height, state, is_day_boundary)?; Ok(()) } fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> { diff --git a/crates/brk_computer/src/distribution/metrics/cost_basis/extended.rs b/crates/brk_computer/src/distribution/metrics/cost_basis/extended.rs index 9a980a0af..7691e4c07 100644 --- a/crates/brk_computer/src/distribution/metrics/cost_basis/extended.rs +++ b/crates/brk_computer/src/distribution/metrics/cost_basis/extended.rs @@ -1,11 +1,11 @@ use brk_error::Result; use brk_traversable::Traversable; -use brk_types::{BasisPoints16, Cents, Height, Version}; -use vecdb::{AnyStoredVec, Rw, StorageMode, WritableVec}; +use brk_types::{Cents, Height, Version}; +use vecdb::{AnyStoredVec, Rw, StorageMode}; use crate::{ distribution::state::CohortState, - internal::{PERCENTILES_LEN, PercentFromHeight, PercentilesVecs, compute_spot_percentile_rank}, + internal::{PERCENTILES_LEN, PercentilesVecs}, }; use crate::distribution::metrics::ImportConfig; @@ -18,12 +18,6 @@ pub struct CostBasisExtended { /// Invested capital percentiles (USD-weighted) pub invested_capital: PercentilesVecs, - - /// What percentile of cost basis is below spot (sat-weighted) - pub spot_cost_basis_percentile: PercentFromHeight, - - /// What percentile of invested capital is below spot (USD-weighted) - pub spot_invested_capital_percentile: PercentFromHeight, } impl CostBasisExtended { @@ -41,10 +35,6 @@ impl CostBasisExtended { cfg.version, cfg.indexes, )?, - spot_cost_basis_percentile: cfg - .import_percent_bp16("spot_cost_basis_percentile", Version::ZERO)?, - spot_invested_capital_percentile: cfg - .import_percent_bp16("spot_invested_capital_percentile", Version::ZERO)?, }) } @@ -52,34 +42,36 @@ impl CostBasisExtended { &mut self, height: Height, state: &mut CohortState, - spot: Cents, + is_day_boundary: bool, ) -> Result<()> { - let computed = state.compute_percentiles(); + let computed = if is_day_boundary { + state.compute_percentiles() + } else { + state.cached_percentiles() + }; let sat_prices = computed .as_ref() .map(|p| p.sat_weighted) .unwrap_or([Cents::ZERO; PERCENTILES_LEN]); - - self.percentiles.truncate_push(height, &sat_prices)?; - let rank = compute_spot_percentile_rank(&sat_prices, spot); - self.spot_cost_basis_percentile - .bps - .height - .truncate_push(height, rank)?; - let usd_prices = computed .as_ref() .map(|p| p.usd_weighted) .unwrap_or([Cents::ZERO; PERCENTILES_LEN]); - self.invested_capital.truncate_push(height, &usd_prices)?; - let rank = compute_spot_percentile_rank(&usd_prices, spot); - self.spot_invested_capital_percentile - .bps - .height - .truncate_push(height, rank)?; + self.push_arrays(height, &sat_prices, &usd_prices) + } + /// Push pre-computed percentile arrays. + /// Shared by both individual cohort and aggregate (K-way merge) paths. + pub(crate) fn push_arrays( + &mut self, + height: Height, + sat_prices: &[Cents; PERCENTILES_LEN], + usd_prices: &[Cents; PERCENTILES_LEN], + ) -> Result<()> { + self.percentiles.truncate_push(height, sat_prices)?; + self.invested_capital.truncate_push(height, usd_prices)?; Ok(()) } @@ -97,8 +89,6 @@ impl CostBasisExtended { .iter_mut() .map(|v| &mut v.cents.height as &mut dyn AnyStoredVec), ); - vecs.push(&mut self.spot_cost_basis_percentile.bps.height); - vecs.push(&mut self.spot_invested_capital_percentile.bps.height); vecs } @@ -107,14 +97,6 @@ impl CostBasisExtended { .validate_computed_version_or_reset(base_version)?; self.invested_capital .validate_computed_version_or_reset(base_version)?; - self.spot_cost_basis_percentile - .bps - .height - .validate_computed_version_or_reset(base_version)?; - self.spot_invested_capital_percentile - .bps - .height - .validate_computed_version_or_reset(base_version)?; Ok(()) } } diff --git a/crates/brk_computer/src/distribution/metrics/mod.rs b/crates/brk_computer/src/distribution/metrics/mod.rs index 602f1a9a9..e237e4c3f 100644 --- a/crates/brk_computer/src/distribution/metrics/mod.rs +++ b/crates/brk_computer/src/distribution/metrics/mod.rs @@ -42,12 +42,32 @@ pub trait CohortMetricsBase: Send + Sync { fn validate_computed_versions(&mut self, base_version: Version) -> Result<()>; + /// Apply pending, push min/max cost basis, compute and push unrealized state. + fn compute_and_push_unrealized_base( + &mut self, + height: Height, + height_price: Cents, + state: &mut CohortState, + ) -> Result<()> { + state.apply_pending(); + self.cost_basis_base_mut() + .truncate_push_minmax(height, state)?; + let unrealized_state = state.compute_unrealized_state(height_price); + self.unrealized_base_mut() + .truncate_push(height, &unrealized_state)?; + Ok(()) + } + + /// Compute and push unrealized states. Extended types override to also push percentiles. fn compute_then_truncate_push_unrealized_states( &mut self, height: Height, height_price: Cents, state: &mut CohortState, - ) -> Result<()>; + _is_day_boundary: bool, + ) -> Result<()> { + self.compute_and_push_unrealized_base(height, height_price, state) + } fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec>; diff --git a/crates/brk_computer/src/distribution/metrics/realized/base.rs b/crates/brk_computer/src/distribution/metrics/realized/base.rs index 3df291011..2e6b13afe 100644 --- a/crates/brk_computer/src/distribution/metrics/realized/base.rs +++ b/crates/brk_computer/src/distribution/metrics/realized/base.rs @@ -1,7 +1,7 @@ use brk_error::Result; use brk_traversable::Traversable; use brk_types::{ - BasisPoints16, BasisPoints32, BasisPointsSigned32, Bitcoin, Cents, CentsSats, CentsSigned, + BasisPoints32, BasisPointsSigned32, Bitcoin, Cents, CentsSats, CentsSigned, CentsSquaredSats, Dollars, Height, Indexes, Sats, StoredF32, StoredF64, Version, }; use vecdb::{ @@ -16,7 +16,7 @@ use crate::{ CentsPlus, CentsUnsignedToDollars, ComputedFromHeight, ComputedFromHeightCumulative, ComputedFromHeightRatio, FiatFromHeight, Identity, LazyFromHeight, NegCentsUnsignedToDollars, PercentFromHeight, PercentRollingEmas1w1m, - PercentRollingWindows, Price, RatioCents64, RatioCentsBp16, RatioCentsBp32, + PercentRollingWindows, Price, RatioCents64, RatioCentsBp32, RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32, RollingEmas1w1m, RollingEmas2w, RollingWindows, ValueFromHeightCumulative, }, @@ -53,8 +53,8 @@ pub struct RealizedBase { pub net_realized_pnl_ema_1w: ComputedFromHeight, pub gross_pnl: FiatFromHeight, - pub realized_profit_rel_to_realized_cap: PercentFromHeight, - pub realized_loss_rel_to_realized_cap: PercentFromHeight, + pub realized_profit_rel_to_realized_cap: PercentFromHeight, + pub realized_loss_rel_to_realized_cap: PercentFromHeight, pub net_realized_pnl_rel_to_realized_cap: PercentFromHeight, pub profit_value_created: ComputedFromHeight, @@ -122,9 +122,9 @@ impl RealizedBase { let gross_pnl = cfg.import_fiat("realized_gross_pnl", v0)?; let realized_profit_rel_to_realized_cap = - cfg.import_percent_bp16("realized_profit_rel_to_realized_cap", v1)?; + cfg.import_percent_bp32("realized_profit_rel_to_realized_cap", Version::new(2))?; let realized_loss_rel_to_realized_cap = - cfg.import_percent_bp16("realized_loss_rel_to_realized_cap", v1)?; + cfg.import_percent_bp32("realized_loss_rel_to_realized_cap", Version::new(2))?; let net_realized_pnl_rel_to_realized_cap = cfg.import_percent_bps32("net_realized_pnl_rel_to_realized_cap", Version::new(2))?; @@ -649,14 +649,14 @@ impl RealizedBase { // Realized profit/loss/net relative to realized cap self.realized_profit_rel_to_realized_cap - .compute_binary::( + .compute_binary::( starting_indexes.height, &self.realized_profit.height, &self.realized_cap_cents.height, exit, )?; self.realized_loss_rel_to_realized_cap - .compute_binary::( + .compute_binary::( starting_indexes.height, &self.realized_loss.height, &self.realized_cap_cents.height, diff --git a/crates/brk_computer/src/distribution/state/cohort/base.rs b/crates/brk_computer/src/distribution/state/cohort/base.rs index 6b9addba0..87a5ba964 100644 --- a/crates/brk_computer/src/distribution/state/cohort/base.rs +++ b/crates/brk_computer/src/distribution/state/cohort/base.rs @@ -185,7 +185,11 @@ impl CohortState { let sats = supply.value; let current_ps = CentsSats::from_price_sats(current_price, sats); let prev_ps = CentsSats::from_price_sats(prev_price, sats); - let ath_ps = CentsSats::from_price_sats(ath, sats); + let ath_ps = if ath == current_price { + current_ps + } else { + CentsSats::from_price_sats(ath, sats) + }; let prev_investor_cap = prev_ps.to_investor_cap(prev_price); Some(SendPrecomputed { sats, @@ -287,6 +291,10 @@ impl CohortState { self.cost_basis_data.compute_percentiles() } + pub(crate) fn cached_percentiles(&self) -> Option { + self.cost_basis_data.cached_percentiles() + } + pub(crate) fn compute_unrealized_state(&mut self, height_price: Cents) -> UnrealizedState { self.cost_basis_data.compute_unrealized_state(height_price) } diff --git a/crates/brk_computer/src/distribution/state/cost_basis/data.rs b/crates/brk_computer/src/distribution/state/cost_basis/data.rs index a48376b82..4aa15608c 100644 --- a/crates/brk_computer/src/distribution/state/cost_basis/data.rs +++ b/crates/brk_computer/src/distribution/state/cost_basis/data.rs @@ -83,7 +83,7 @@ impl CostBasisData { } fn assert_pending_empty(&self) { - assert!( + debug_assert!( self.pending.is_empty() && self.pending_raw_is_zero(), "CostBasisData: pending not empty, call apply_pending first" ); @@ -180,7 +180,7 @@ impl CostBasisData { } pub(crate) fn apply_pending(&mut self) { - if self.pending.is_empty() && self.pending_raw_is_zero() { + if self.pending.is_empty() { return; } self.generation = self.generation.wrapping_add(1); @@ -277,6 +277,10 @@ impl CostBasisData { self.cached_percentiles = None; } + pub(crate) fn cached_percentiles(&self) -> Option { + self.cached_percentiles + } + pub(crate) fn compute_percentiles(&mut self) -> Option { self.assert_pending_empty(); if !self.percentiles_dirty { diff --git a/crates/brk_computer/src/distribution/state/cost_basis/realized.rs b/crates/brk_computer/src/distribution/state/cost_basis/realized.rs index 45e2f9ba8..2aef95c9b 100644 --- a/crates/brk_computer/src/distribution/state/cost_basis/realized.rs +++ b/crates/brk_computer/src/distribution/state/cost_basis/realized.rs @@ -35,6 +35,9 @@ impl RealizedState { /// Get realized cap as CentsUnsigned (divides by ONE_BTC). #[inline] pub(crate) fn cap(&self) -> Cents { + if self.cap_raw == 0 { + return Cents::ZERO; + } Cents::new((self.cap_raw / Sats::ONE_BTC_U128) as u64) } @@ -76,18 +79,27 @@ impl RealizedState { /// Get realized profit as CentsUnsigned. #[inline] pub(crate) fn profit(&self) -> Cents { + if self.profit_raw == 0 { + return Cents::ZERO; + } Cents::new((self.profit_raw / Sats::ONE_BTC_U128) as u64) } /// Get realized loss as CentsUnsigned. #[inline] pub(crate) fn loss(&self) -> Cents { + if self.loss_raw == 0 { + return Cents::ZERO; + } Cents::new((self.loss_raw / Sats::ONE_BTC_U128) as u64) } /// Get profit value created as CentsUnsigned (sell_price × sats for profit cases). #[inline] pub(crate) fn profit_value_created(&self) -> Cents { + if self.profit_value_created_raw == 0 { + return Cents::ZERO; + } Cents::new((self.profit_value_created_raw / Sats::ONE_BTC_U128) as u64) } @@ -95,12 +107,18 @@ impl RealizedState { /// This is also known as profit_flow. #[inline] pub(crate) fn profit_value_destroyed(&self) -> Cents { + if self.profit_value_destroyed_raw == 0 { + return Cents::ZERO; + } Cents::new((self.profit_value_destroyed_raw / Sats::ONE_BTC_U128) as u64) } /// Get loss value created as CentsUnsigned (sell_price × sats for loss cases). #[inline] pub(crate) fn loss_value_created(&self) -> Cents { + if self.loss_value_created_raw == 0 { + return Cents::ZERO; + } Cents::new((self.loss_value_created_raw / Sats::ONE_BTC_U128) as u64) } @@ -108,6 +126,9 @@ impl RealizedState { /// This is also known as capitulation_flow. #[inline] pub(crate) fn loss_value_destroyed(&self) -> Cents { + if self.loss_value_destroyed_raw == 0 { + return Cents::ZERO; + } Cents::new((self.loss_value_destroyed_raw / Sats::ONE_BTC_U128) as u64) } @@ -116,6 +137,9 @@ impl RealizedState { /// by selling at peak instead of when actually sold. #[inline] pub(crate) fn peak_regret(&self) -> Cents { + if self.peak_regret_raw == 0 { + return Cents::ZERO; + } Cents::new((self.peak_regret_raw / Sats::ONE_BTC_U128) as u64) } diff --git a/crates/brk_computer/src/distribution/state/cost_basis/unrealized.rs b/crates/brk_computer/src/distribution/state/cost_basis/unrealized.rs index 8ead22961..47a9dc6d3 100644 --- a/crates/brk_computer/src/distribution/state/cost_basis/unrealized.rs +++ b/crates/brk_computer/src/distribution/state/cost_basis/unrealized.rs @@ -61,17 +61,22 @@ struct CachedStateRaw { impl CachedStateRaw { /// Convert raw values to final output by dividing by ONE_BTC. fn to_output(&self) -> UnrealizedState { + #[inline(always)] + fn div_btc(raw: u128) -> Cents { + if raw == 0 { + Cents::ZERO + } else { + Cents::new((raw / Sats::ONE_BTC_U128) as u64) + } + } + UnrealizedState { supply_in_profit: self.supply_in_profit, supply_in_loss: self.supply_in_loss, - unrealized_profit: Cents::new((self.unrealized_profit / Sats::ONE_BTC_U128) as u64), - unrealized_loss: Cents::new((self.unrealized_loss / Sats::ONE_BTC_U128) as u64), - invested_capital_in_profit: Cents::new( - (self.invested_capital_in_profit / Sats::ONE_BTC_U128) as u64, - ), - invested_capital_in_loss: Cents::new( - (self.invested_capital_in_loss / Sats::ONE_BTC_U128) as u64, - ), + unrealized_profit: div_btc(self.unrealized_profit), + unrealized_loss: div_btc(self.unrealized_loss), + invested_capital_in_profit: div_btc(self.invested_capital_in_profit), + invested_capital_in_loss: div_btc(self.invested_capital_in_loss), investor_cap_in_profit_raw: self.investor_cap_in_profit, investor_cap_in_loss_raw: self.investor_cap_in_loss, invested_capital_in_profit_raw: self.invested_capital_in_profit, diff --git a/crates/brk_computer/src/distribution/state/transacted.rs b/crates/brk_computer/src/distribution/state/transacted.rs index 9f6039326..8dd8cddc9 100644 --- a/crates/brk_computer/src/distribution/state/transacted.rs +++ b/crates/brk_computer/src/distribution/state/transacted.rs @@ -2,6 +2,7 @@ use std::ops::{Add, AddAssign}; use brk_cohort::{ByAmountRange, GroupedByType}; use brk_types::{OutputType, Sats, SupplyState}; +use vecdb::unlikely; #[derive(Default, Debug)] pub struct Transacted { @@ -20,7 +21,7 @@ impl Transacted { *self.by_type.get_mut(_type) += &supply; - if _type.is_unspendable() { + if unlikely(_type.is_unspendable()) { return; } diff --git a/crates/brk_computer/src/internal/algo/expanding_percentiles.rs b/crates/brk_computer/src/internal/algo/expanding_percentiles.rs index d72566d45..71eeeef76 100644 --- a/crates/brk_computer/src/internal/algo/expanding_percentiles.rs +++ b/crates/brk_computer/src/internal/algo/expanding_percentiles.rs @@ -2,41 +2,36 @@ use brk_types::StoredF32; /// Fast expanding percentile tracker using a Fenwick tree (Binary Indexed Tree). /// -/// Values are discretized to BasisPoints32 precision (×10000) and tracked in +/// Values are discretized to 10 BPS (0.1%) resolution and tracked in /// a fixed-size frequency array with Fenwick prefix sums. This gives: -/// - O(log N) insert (N = tree size, ~18 ops for 200k buckets) +/// - O(log N) insert (N = tree size, ~16 ops for 43k buckets) /// - O(log N) percentile query via prefix-sum walk -/// - Exact at BasisPoints32 resolution (no approximation) +/// - 0.1% value resolution (10 BPS granularity) #[derive(Clone)] pub(crate) struct ExpandingPercentiles { /// Fenwick tree storing cumulative frequency counts. - /// Index 0 is unused (1-indexed). tree[i] covers bucket (i - 1 + offset). - tree: Vec, - count: u64, - /// Offset so bucket 0 in the tree corresponds to BPS value `offset`. - offset: i32, - size: usize, + /// 1-indexed: tree[0] is unused, tree[1..=TREE_SIZE] hold data. + tree: Vec, + count: u32, } -/// Max BPS value supported. Ratio of 42.0 = 420,000 BPS. +/// Bucket granularity in BPS. 10 BPS = 0.1% = 0.001 ratio. +const BUCKET_BPS: i32 = 10; +/// Max ratio supported: 43.0 = 430,000 BPS. const MAX_BPS: i32 = 430_000; -/// Min BPS value supported (0 = ratio of 0.0). -const MIN_BPS: i32 = 0; -const TREE_SIZE: usize = (MAX_BPS - MIN_BPS) as usize + 1; +const TREE_SIZE: usize = (MAX_BPS / BUCKET_BPS) as usize + 1; impl Default for ExpandingPercentiles { fn default() -> Self { Self { - tree: vec![0u64; TREE_SIZE + 1], // 1-indexed + tree: vec![0u32; TREE_SIZE + 1], // 1-indexed count: 0, - offset: MIN_BPS, - size: TREE_SIZE, } } } impl ExpandingPercentiles { - pub fn count(&self) -> u64 { + pub fn count(&self) -> u32 { self.count } @@ -47,29 +42,27 @@ impl ExpandingPercentiles { /// Convert f32 ratio to bucket index (1-indexed for Fenwick). #[inline] - fn to_bucket(&self, value: f32) -> usize { + fn to_bucket(value: f32) -> usize { let bps = (value as f64 * 10000.0).round() as i32; - let clamped = bps.clamp(self.offset, self.offset + self.size as i32 - 1); - (clamped - self.offset) as usize + 1 // 1-indexed + let bucket = (bps / BUCKET_BPS).clamp(0, TREE_SIZE as i32 - 1); + bucket as usize + 1 } /// Bulk-load values in O(n + N) instead of O(n log N). /// Builds raw frequency counts, then converts to Fenwick in-place. pub fn add_bulk(&mut self, values: &[StoredF32]) { - // Build raw frequency counts into tree (treated as flat array) for &v in values { let v = *v; if v.is_nan() { continue; } self.count += 1; - let bucket = self.to_bucket(v); - self.tree[bucket] += 1; + self.tree[Self::to_bucket(v)] += 1; } // Convert flat frequencies to Fenwick tree in O(N) - for i in 1..=self.size { + for i in 1..=TREE_SIZE { let parent = i + (i & i.wrapping_neg()); - if parent <= self.size { + if parent <= TREE_SIZE { let val = self.tree[i]; self.tree[parent] += val; } @@ -83,47 +76,40 @@ impl ExpandingPercentiles { return; } self.count += 1; - let mut i = self.to_bucket(value); - while i <= self.size { + let mut i = Self::to_bucket(value); + while i <= TREE_SIZE { self.tree[i] += 1; - i += i & i.wrapping_neg(); // i += lowbit(i) + i += i & i.wrapping_neg(); } } /// Find the bucket containing the k-th element (1-indexed k). /// Uses the standard Fenwick tree walk-down in O(log N). #[inline] - fn kth(&self, mut k: u64) -> usize { + fn kth(&self, mut k: u32) -> usize { let mut pos = 0; - let mut bit = 1 << (usize::BITS - 1 - self.size.leading_zeros()); // highest power of 2 <= size + let mut bit = 1 << (usize::BITS - 1 - TREE_SIZE.leading_zeros()); while bit > 0 { let next = pos + bit; - if next <= self.size && self.tree[next] < k { + if next <= TREE_SIZE && self.tree[next] < k { k -= self.tree[next]; pos = next; } bit >>= 1; } - pos + 1 // 1-indexed bucket - } - - /// Convert bucket index back to BPS u32 value. - #[inline] - fn bucket_to_bps(&self, bucket: usize) -> u32 { - (bucket as i32 - 1 + self.offset) as u32 + pos + 1 } /// Compute 6 percentiles in one call. O(6 × log N). - /// Quantiles q must be in (0, 1). + /// Quantiles q must be in (0, 1). Output is in BPS. pub fn quantiles(&self, qs: &[f64; 6], out: &mut [u32; 6]) { if self.count == 0 { out.iter_mut().for_each(|o| *o = 0); return; } for (i, &q) in qs.iter().enumerate() { - // k = ceil(q * count), clamped to [1, count] - let k = ((q * self.count as f64).ceil() as u64).clamp(1, self.count); - out[i] = self.bucket_to_bps(self.kth(k)); + let k = ((q * self.count as f64).ceil() as u32).clamp(1, self.count); + out[i] = (self.kth(k) as u32 - 1) * BUCKET_BPS as u32; } } } @@ -141,30 +127,19 @@ mod tests { #[test] fn basic_quantiles() { let mut ep = ExpandingPercentiles::default(); - // Add ratios 0.01 to 1.0 (BPS 100 to 10000) for i in 1..=1000 { ep.add(i as f32 / 1000.0); } assert_eq!(ep.count(), 1000); let median = quantile(&ep, 0.5); - // 0.5 ratio = 5000 BPS, median of 1..1000 ratios ≈ 500/1000 = 0.5 = 5000 BPS - assert!( - (median as i32 - 5000).abs() < 100, - "median was {median}" - ); + assert!((median as i32 - 5000).abs() < 100, "median was {median}"); let p99 = quantile(&ep, 0.99); - assert!( - (p99 as i32 - 9900).abs() < 100, - "p99 was {p99}" - ); + assert!((p99 as i32 - 9900).abs() < 100, "p99 was {p99}"); let p01 = quantile(&ep, 0.01); - assert!( - (p01 as i32 - 100).abs() < 100, - "p01 was {p01}" - ); + assert!((p01 as i32 - 100).abs() < 100, "p01 was {p01}"); } #[test] @@ -177,10 +152,9 @@ mod tests { #[test] fn single_value() { let mut ep = ExpandingPercentiles::default(); - ep.add(0.42); // 4200 BPS - assert_eq!(quantile(&ep, 0.0001), 4200); - assert_eq!(quantile(&ep, 0.5), 4200); - assert_eq!(quantile(&ep, 0.9999), 4200); + ep.add(0.42); + let v = quantile(&ep, 0.5); + assert!((v as i32 - 4200).abs() <= BUCKET_BPS, "got {v}"); } #[test] diff --git a/crates/brk_computer/src/internal/from_height/cumulative_sum.rs b/crates/brk_computer/src/internal/from_height/cumulative_sum.rs index b8ab055d6..3e6d8686a 100644 --- a/crates/brk_computer/src/internal/from_height/cumulative_sum.rs +++ b/crates/brk_computer/src/internal/from_height/cumulative_sum.rs @@ -61,6 +61,19 @@ where T: Default + SubAssign, { compute_height(&mut self.height)?; + self.compute_rest(max_from, windows, exit) + } + + /// Compute cumulative + rolling sum from already-populated height data. + pub(crate) fn compute_rest( + &mut self, + max_from: Height, + windows: &WindowStarts<'_>, + exit: &Exit, + ) -> Result<()> + where + T: Default + SubAssign, + { self.cumulative .height .compute_cumulative(max_from, &self.height, exit)?; diff --git a/crates/brk_computer/src/internal/from_height/percentiles.rs b/crates/brk_computer/src/internal/from_height/percentiles.rs index 57a2ba2c1..f0157c3ef 100644 --- a/crates/brk_computer/src/internal/from_height/percentiles.rs +++ b/crates/brk_computer/src/internal/from_height/percentiles.rs @@ -1,6 +1,6 @@ use brk_error::Result; use brk_traversable::{Traversable, TreeNode}; -use brk_types::{BasisPoints16, Cents, Height, Version}; +use brk_types::{Cents, Height, Version}; use vecdb::{AnyExportableVec, Database, ReadOnlyClone, Ro, Rw, StorageMode, WritableVec}; use crate::indexes; @@ -11,62 +11,6 @@ pub const PERCENTILES: [u8; 19] = [ ]; pub const PERCENTILES_LEN: usize = PERCENTILES.len(); -/// Compute spot percentile rank by interpolating within percentile bands. -/// Returns a value between 0 and 100 indicating where spot sits in the distribution. -pub(crate) fn compute_spot_percentile_rank( - percentile_prices: &[Cents; PERCENTILES_LEN], - spot: Cents, -) -> BasisPoints16 { - if spot == Cents::ZERO && percentile_prices[0] == Cents::ZERO { - return BasisPoints16::ZERO; - } - - let spot_f64 = f64::from(spot); - - // Below lowest percentile (p5) - extrapolate towards 0 - let p5 = f64::from(percentile_prices[0]); - if spot_f64 <= p5 { - if p5 == 0.0 { - return BasisPoints16::ZERO; - } - // Linear extrapolation: rank = 5% * (spot / p5) - return BasisPoints16::from((0.05 * spot_f64 / p5).max(0.0)); - } - - // Above highest percentile (p95) - extrapolate towards 100 - let p95 = f64::from(percentile_prices[PERCENTILES_LEN - 1]); - let p90 = f64::from(percentile_prices[PERCENTILES_LEN - 2]); - if spot_f64 >= p95 { - if p95 == p90 { - return BasisPoints16::ONE; - } - // Linear extrapolation using p90-p95 slope - let slope = 0.05 / (p95 - p90); - return BasisPoints16::from((0.95 + (spot_f64 - p95) * slope).min(1.0)); - } - - // Find the band containing spot and interpolate - for i in 0..PERCENTILES_LEN - 1 { - let lower = f64::from(percentile_prices[i]); - let upper = f64::from(percentile_prices[i + 1]); - - if spot_f64 >= lower && spot_f64 <= upper { - let lower_pct = f64::from(PERCENTILES[i]) / 100.0; - let upper_pct = f64::from(PERCENTILES[i + 1]) / 100.0; - - if upper == lower { - return BasisPoints16::from(lower_pct); - } - - // Linear interpolation - let ratio = (spot_f64 - lower) / (upper - lower); - return BasisPoints16::from(lower_pct + ratio * (upper_pct - lower_pct)); - } - } - - BasisPoints16::ZERO -} - pub struct PercentilesVecs { pub vecs: [Price>; PERCENTILES_LEN], } diff --git a/crates/brk_computer/src/internal/from_height/ratio/price_extended.rs b/crates/brk_computer/src/internal/from_height/ratio/price_extended.rs index 891ee841b..71fb36575 100644 --- a/crates/brk_computer/src/internal/from_height/ratio/price_extended.rs +++ b/crates/brk_computer/src/internal/from_height/ratio/price_extended.rs @@ -5,20 +5,20 @@ use derive_more::{Deref, DerefMut}; use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode}; use crate::internal::{ComputedFromHeight, Price}; -use crate::{blocks, indexes, prices}; +use crate::{indexes, prices}; -use super::ComputedFromHeightRatioExtended; +use super::ComputedFromHeightRatio; #[derive(Deref, DerefMut, Traversable)] -pub struct ComputedFromHeightPriceWithRatioExtended { +pub struct ComputedFromHeightPriceWithRatio { #[deref] #[deref_mut] #[traversable(flatten)] - pub inner: ComputedFromHeightRatioExtended, + pub inner: ComputedFromHeightRatio, pub price: Price>, } -impl ComputedFromHeightPriceWithRatioExtended { +impl ComputedFromHeightPriceWithRatio { pub(crate) fn forced_import( db: &Database, name: &str, @@ -27,15 +27,14 @@ impl ComputedFromHeightPriceWithRatioExtended { ) -> Result { let v = version + Version::TWO; Ok(Self { - inner: ComputedFromHeightRatioExtended::forced_import(db, name, version, indexes)?, + inner: ComputedFromHeightRatio::forced_import(db, name, version, indexes)?, price: Price::forced_import(db, name, v, indexes)?, }) } - /// Compute price via closure (in cents), then compute ratio + extended metrics. + /// Compute price via closure (in cents), then compute ratio. pub(crate) fn compute_all( &mut self, - blocks: &blocks::Vecs, prices: &prices::Vecs, starting_indexes: &Indexes, exit: &Exit, @@ -45,13 +44,9 @@ impl ComputedFromHeightPriceWithRatioExtended { F: FnMut(&mut EagerVec>) -> Result<()>, { compute_price(&mut self.price.cents.height)?; - self.inner.compute_rest( - blocks, - prices, - starting_indexes, - exit, - &self.price.cents.height, - )?; + let close_price = &prices.price.cents.height; + self.inner + .compute_ratio(starting_indexes, close_price, &self.price.cents.height, exit)?; Ok(()) } } diff --git a/crates/brk_computer/src/internal/transform/mod.rs b/crates/brk_computer/src/internal/transform/mod.rs index f7a4667ea..69a2f6dc2 100644 --- a/crates/brk_computer/src/internal/transform/mod.rs +++ b/crates/brk_computer/src/internal/transform/mod.rs @@ -23,7 +23,7 @@ pub use derived::{ RatioCents64, TimesSqrt, }; pub use ratio::{ - NegRatioDollarsBps32, RatioCentsBp16, RatioCentsBp32, RatioCentsSignedCentsBps32, + NegRatioDollarsBps32, RatioCentsBp32, RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32, RatioDiffCentsBps32, RatioDiffDollarsBps32, RatioDiffF32Bps32, RatioDollarsBp16, RatioDollarsBp32, RatioDollarsBps32, RatioSatsBp16, RatioU32Bp16, RatioU64Bp16, diff --git a/crates/brk_computer/src/internal/transform/ratio.rs b/crates/brk_computer/src/internal/transform/ratio.rs index 7fe06269b..7fbe67bce 100644 --- a/crates/brk_computer/src/internal/transform/ratio.rs +++ b/crates/brk_computer/src/internal/transform/ratio.rs @@ -30,19 +30,6 @@ impl BinaryTransform for RatioSatsBp16 { } } -pub struct RatioCentsBp16; - -impl BinaryTransform for RatioCentsBp16 { - #[inline(always)] - fn apply(numerator: Cents, denominator: Cents) -> BasisPoints16 { - if denominator == Cents::ZERO { - BasisPoints16::ZERO - } else { - BasisPoints16::from(numerator.inner() as f64 / denominator.inner() as f64) - } - } -} - pub struct RatioCentsBp32; impl BinaryTransform for RatioCentsBp32 { @@ -143,7 +130,12 @@ pub struct RatioDollarsBp32; impl BinaryTransform for RatioDollarsBp32 { #[inline(always)] fn apply(numerator: Dollars, denominator: Dollars) -> BasisPoints32 { - BasisPoints32::from(f64::from(numerator) / f64::from(denominator)) + let ratio = f64::from(numerator) / f64::from(denominator); + if ratio.is_finite() { + BasisPoints32::from(ratio) + } else { + BasisPoints32::ZERO + } } } diff --git a/crates/brk_computer/src/market/compute.rs b/crates/brk_computer/src/market/compute.rs index 5fd95ebee..0142c7e26 100644 --- a/crates/brk_computer/src/market/compute.rs +++ b/crates/brk_computer/src/market/compute.rs @@ -29,10 +29,6 @@ impl Vecs { self.returns .compute(prices, blocks, &self.lookback, starting_indexes, exit)?; - // Volatility (depends on returns) - self.volatility - .compute(&self.returns, starting_indexes.height, exit)?; - // Range metrics (independent) self.range.compute(prices, blocks, starting_indexes, exit)?; diff --git a/crates/brk_computer/src/market/dca/compute.rs b/crates/brk_computer/src/market/dca/compute.rs index df0f28bc4..f2c28c8cf 100644 --- a/crates/brk_computer/src/market/dca/compute.rs +++ b/crates/brk_computer/src/market/dca/compute.rs @@ -66,16 +66,17 @@ impl Vecs { self.period_cost_basis.zip_mut_with_days(&self.period_stack) { let days = days as usize; + let start = average_price.cents.height.len(); let stack_data = stack .sats .height - .collect_range_at(sh, stack.sats.height.len()); + .collect_range_at(start, stack.sats.height.len()); average_price.cents.height.compute_transform( starting_indexes.height, h2d, |(h, di, _)| { let di_usize = di.to_usize(); - let stack_sats = stack_data[h.to_usize() - sh]; + let stack_sats = stack_data[h.to_usize() - start]; let avg = if di_usize > first_price_di { let num_days = days.min(di_usize + 1).min(di_usize + 1 - first_price_di); Cents::from(DCA_AMOUNT * num_days / Bitcoin::from(stack_sats)) @@ -123,15 +124,16 @@ impl Vecs { self.period_lump_sum_stack.zip_mut_with_days(&lookback_dca) { let total_invested = DCA_AMOUNT * days as usize; + let ls_start = stack.sats.height.len(); let lookback_data = lookback_price .cents .height - .collect_range_at(sh, lookback_price.cents.height.len()); + .collect_range_at(ls_start, lookback_price.cents.height.len()); stack.sats.height.compute_transform( starting_indexes.height, h2d, |(h, _di, _)| { - let lp = lookback_data[h.to_usize() - sh]; + let lp = lookback_data[h.to_usize() - ls_start]; let sats = if lp == Cents::ZERO { Sats::ZERO } else { @@ -217,10 +219,11 @@ impl Vecs { .zip(start_days) { let from_usize = from.to_usize(); + let cls_start = average_price.cents.height.len(); let stack_data = stack .sats .height - .collect_range_at(sh, stack.sats.height.len()); + .collect_range_at(cls_start, stack.sats.height.len()); average_price.cents.height.compute_transform( starting_indexes.height, h2d, @@ -229,7 +232,7 @@ impl Vecs { if di_usize < from_usize { return (h, Cents::ZERO); } - let stack_sats = stack_data[h.to_usize() - sh]; + let stack_sats = stack_data[h.to_usize() - cls_start]; let num_days = di_usize + 1 - from_usize; let avg = Cents::from(DCA_AMOUNT * num_days / Bitcoin::from(stack_sats)); (h, avg) diff --git a/crates/brk_computer/src/market/import.rs b/crates/brk_computer/src/market/import.rs index 6f04a6f34..f834a05ee 100644 --- a/crates/brk_computer/src/market/import.rs +++ b/crates/brk_computer/src/market/import.rs @@ -25,7 +25,7 @@ impl Vecs { let ath = AthVecs::forced_import(&db, version, indexes)?; let lookback = LookbackVecs::forced_import(&db, version, indexes)?; let returns = ReturnsVecs::forced_import(&db, version, indexes)?; - let volatility = VolatilityVecs::forced_import(&db, version, indexes, &returns)?; + let volatility = VolatilityVecs::forced_import(version, &returns)?; let range = RangeVecs::forced_import(&db, version, indexes)?; let moving_average = MovingAverageVecs::forced_import(&db, version, indexes)?; let dca = DcaVecs::forced_import(&db, version, indexes)?; diff --git a/crates/brk_computer/src/market/mod.rs b/crates/brk_computer/src/market/mod.rs index df2db2562..23cf2c16c 100644 --- a/crates/brk_computer/src/market/mod.rs +++ b/crates/brk_computer/src/market/mod.rs @@ -29,7 +29,7 @@ pub struct Vecs { pub ath: AthVecs, pub lookback: LookbackVecs, pub returns: ReturnsVecs, - pub volatility: VolatilityVecs, + pub volatility: VolatilityVecs, pub range: RangeVecs, pub moving_average: MovingAverageVecs, pub dca: DcaVecs, diff --git a/crates/brk_computer/src/market/moving_average/compute.rs b/crates/brk_computer/src/market/moving_average/compute.rs index 0ab14881b..e8c8223fc 100644 --- a/crates/brk_computer/src/market/moving_average/compute.rs +++ b/crates/brk_computer/src/market/moving_average/compute.rs @@ -34,7 +34,7 @@ impl Vecs { (&mut self.price_sma_4y, 4 * 365), ] { let window_starts = blocks.count.start_vec(period); - sma.compute_all(blocks, prices, starting_indexes, exit, |v| { + sma.compute_all(prices, starting_indexes, exit, |v| { v.compute_rolling_average(starting_indexes.height, window_starts, close, exit)?; Ok(()) })?; @@ -59,7 +59,7 @@ impl Vecs { (&mut self.price_ema_4y, 4 * 365), ] { let window_starts = blocks.count.start_vec(period); - ema.compute_all(blocks, prices, starting_indexes, exit, |v| { + ema.compute_all(prices, starting_indexes, exit, |v| { v.compute_rolling_ema(starting_indexes.height, window_starts, close, exit)?; Ok(()) })?; diff --git a/crates/brk_computer/src/market/moving_average/import.rs b/crates/brk_computer/src/market/moving_average/import.rs index b9852b79f..3a3cdaf85 100644 --- a/crates/brk_computer/src/market/moving_average/import.rs +++ b/crates/brk_computer/src/market/moving_average/import.rs @@ -5,7 +5,7 @@ use vecdb::Database; use super::Vecs; use crate::{ indexes, - internal::{CentsTimesTenths, ComputedFromHeightPriceWithRatioExtended, Price}, + internal::{CentsTimesTenths, ComputedFromHeightPriceWithRatio, Price}, }; impl Vecs { @@ -16,7 +16,7 @@ impl Vecs { ) -> Result { macro_rules! import { ($name:expr) => { - ComputedFromHeightPriceWithRatioExtended::forced_import( + ComputedFromHeightPriceWithRatio::forced_import( db, $name, version, indexes, )? }; diff --git a/crates/brk_computer/src/market/moving_average/vecs.rs b/crates/brk_computer/src/market/moving_average/vecs.rs index c8989e486..84ff5a465 100644 --- a/crates/brk_computer/src/market/moving_average/vecs.rs +++ b/crates/brk_computer/src/market/moving_average/vecs.rs @@ -2,42 +2,42 @@ use brk_traversable::Traversable; use brk_types::Cents; use vecdb::{Rw, StorageMode}; -use crate::internal::{ComputedFromHeightPriceWithRatioExtended, LazyFromHeight, Price}; +use crate::internal::{ComputedFromHeightPriceWithRatio, LazyFromHeight, Price}; #[derive(Traversable)] pub struct Vecs { - pub price_sma_1w: ComputedFromHeightPriceWithRatioExtended, - pub price_sma_8d: ComputedFromHeightPriceWithRatioExtended, - pub price_sma_13d: ComputedFromHeightPriceWithRatioExtended, - pub price_sma_21d: ComputedFromHeightPriceWithRatioExtended, - pub price_sma_1m: ComputedFromHeightPriceWithRatioExtended, - pub price_sma_34d: ComputedFromHeightPriceWithRatioExtended, - pub price_sma_55d: ComputedFromHeightPriceWithRatioExtended, - pub price_sma_89d: ComputedFromHeightPriceWithRatioExtended, - pub price_sma_111d: ComputedFromHeightPriceWithRatioExtended, - pub price_sma_144d: ComputedFromHeightPriceWithRatioExtended, - pub price_sma_200d: ComputedFromHeightPriceWithRatioExtended, - pub price_sma_350d: ComputedFromHeightPriceWithRatioExtended, - pub price_sma_1y: ComputedFromHeightPriceWithRatioExtended, - pub price_sma_2y: ComputedFromHeightPriceWithRatioExtended, - pub price_sma_200w: ComputedFromHeightPriceWithRatioExtended, - pub price_sma_4y: ComputedFromHeightPriceWithRatioExtended, + pub price_sma_1w: ComputedFromHeightPriceWithRatio, + pub price_sma_8d: ComputedFromHeightPriceWithRatio, + pub price_sma_13d: ComputedFromHeightPriceWithRatio, + pub price_sma_21d: ComputedFromHeightPriceWithRatio, + pub price_sma_1m: ComputedFromHeightPriceWithRatio, + pub price_sma_34d: ComputedFromHeightPriceWithRatio, + pub price_sma_55d: ComputedFromHeightPriceWithRatio, + pub price_sma_89d: ComputedFromHeightPriceWithRatio, + pub price_sma_111d: ComputedFromHeightPriceWithRatio, + pub price_sma_144d: ComputedFromHeightPriceWithRatio, + pub price_sma_200d: ComputedFromHeightPriceWithRatio, + pub price_sma_350d: ComputedFromHeightPriceWithRatio, + pub price_sma_1y: ComputedFromHeightPriceWithRatio, + pub price_sma_2y: ComputedFromHeightPriceWithRatio, + pub price_sma_200w: ComputedFromHeightPriceWithRatio, + pub price_sma_4y: ComputedFromHeightPriceWithRatio, - pub price_ema_1w: ComputedFromHeightPriceWithRatioExtended, - pub price_ema_8d: ComputedFromHeightPriceWithRatioExtended, - pub price_ema_12d: ComputedFromHeightPriceWithRatioExtended, - pub price_ema_13d: ComputedFromHeightPriceWithRatioExtended, - pub price_ema_21d: ComputedFromHeightPriceWithRatioExtended, - pub price_ema_26d: ComputedFromHeightPriceWithRatioExtended, - pub price_ema_1m: ComputedFromHeightPriceWithRatioExtended, - pub price_ema_34d: ComputedFromHeightPriceWithRatioExtended, - pub price_ema_55d: ComputedFromHeightPriceWithRatioExtended, - pub price_ema_89d: ComputedFromHeightPriceWithRatioExtended, - pub price_ema_144d: ComputedFromHeightPriceWithRatioExtended, - pub price_ema_200d: ComputedFromHeightPriceWithRatioExtended, - pub price_ema_1y: ComputedFromHeightPriceWithRatioExtended, - pub price_ema_2y: ComputedFromHeightPriceWithRatioExtended, - pub price_ema_200w: ComputedFromHeightPriceWithRatioExtended, - pub price_ema_4y: ComputedFromHeightPriceWithRatioExtended, + pub price_ema_1w: ComputedFromHeightPriceWithRatio, + pub price_ema_8d: ComputedFromHeightPriceWithRatio, + pub price_ema_12d: ComputedFromHeightPriceWithRatio, + pub price_ema_13d: ComputedFromHeightPriceWithRatio, + pub price_ema_21d: ComputedFromHeightPriceWithRatio, + pub price_ema_26d: ComputedFromHeightPriceWithRatio, + pub price_ema_1m: ComputedFromHeightPriceWithRatio, + pub price_ema_34d: ComputedFromHeightPriceWithRatio, + pub price_ema_55d: ComputedFromHeightPriceWithRatio, + pub price_ema_89d: ComputedFromHeightPriceWithRatio, + pub price_ema_144d: ComputedFromHeightPriceWithRatio, + pub price_ema_200d: ComputedFromHeightPriceWithRatio, + pub price_ema_1y: ComputedFromHeightPriceWithRatio, + pub price_ema_2y: ComputedFromHeightPriceWithRatio, + pub price_ema_200w: ComputedFromHeightPriceWithRatio, + pub price_ema_4y: ComputedFromHeightPriceWithRatio, pub price_sma_200d_x2_4: Price>, pub price_sma_200d_x0_8: Price>, diff --git a/crates/brk_computer/src/market/returns/compute.rs b/crates/brk_computer/src/market/returns/compute.rs index 674048a5e..c371be217 100644 --- a/crates/brk_computer/src/market/returns/compute.rs +++ b/crates/brk_computer/src/market/returns/compute.rs @@ -1,5 +1,5 @@ use brk_error::Result; -use brk_types::{BasisPointsSigned32, Dollars, Indexes, StoredF32}; +use brk_types::{BasisPointsSigned32, Dollars, Indexes}; use vecdb::Exit; use super::Vecs; @@ -54,26 +54,6 @@ impl Vecs { sd.compute_all(blocks, starting_indexes, exit, _24h_price_return_ratio)?; } - // Downside returns: min(return, 0) - self.price_downside_24h.compute_transform( - starting_indexes.height, - _24h_price_return_ratio, - |(i, ret, ..)| { - let v = f32::from(ret).min(0.0); - (i, StoredF32::from(v)) - }, - exit, - )?; - - // Downside deviation (SD of downside returns) - for sd in [ - &mut self.price_downside_24h_sd_1w, - &mut self.price_downside_24h_sd_1m, - &mut self.price_downside_24h_sd_1y, - ] { - sd.compute_all(blocks, starting_indexes, exit, &self.price_downside_24h)?; - } - Ok(()) } } diff --git a/crates/brk_computer/src/market/returns/import.rs b/crates/brk_computer/src/market/returns/import.rs index 399283f01..2d9747c5f 100644 --- a/crates/brk_computer/src/market/returns/import.rs +++ b/crates/brk_computer/src/market/returns/import.rs @@ -1,6 +1,6 @@ use brk_error::Result; use brk_types::Version; -use vecdb::{Database, EagerVec, ImportableVec}; +use vecdb::Database; use super::super::lookback::ByLookbackPeriod; use super::Vecs; @@ -52,42 +52,12 @@ impl Vecs { indexes, )?; - let price_downside_24h = EagerVec::forced_import(db, "price_downside_24h", version)?; - let price_downside_24h_sd_1w = ComputedFromHeightStdDev::forced_import( - db, - "price_downside_24h", - "1w", - 7, - version + v1, - indexes, - )?; - let price_downside_24h_sd_1m = ComputedFromHeightStdDev::forced_import( - db, - "price_downside_24h", - "1m", - 30, - version + v1, - indexes, - )?; - let price_downside_24h_sd_1y = ComputedFromHeightStdDev::forced_import( - db, - "price_downside_24h", - "1y", - 365, - version + v1, - indexes, - )?; - Ok(Self { price_return, price_cagr, price_return_24h_sd_1w, price_return_24h_sd_1m, price_return_24h_sd_1y, - price_downside_24h, - price_downside_24h_sd_1w, - price_downside_24h_sd_1m, - price_downside_24h_sd_1y, }) } } diff --git a/crates/brk_computer/src/market/returns/vecs.rs b/crates/brk_computer/src/market/returns/vecs.rs index 0535c6400..843f8872c 100644 --- a/crates/brk_computer/src/market/returns/vecs.rs +++ b/crates/brk_computer/src/market/returns/vecs.rs @@ -1,6 +1,6 @@ use brk_traversable::Traversable; -use brk_types::{BasisPointsSigned32, Height, StoredF32}; -use vecdb::{EagerVec, PcoVec, Rw, StorageMode}; +use brk_types::BasisPointsSigned32; +use vecdb::{Rw, StorageMode}; use crate::{ internal::{ComputedFromHeightStdDev, PercentFromHeight}, @@ -18,9 +18,4 @@ pub struct Vecs { pub price_return_24h_sd_1m: ComputedFromHeightStdDev, pub price_return_24h_sd_1y: ComputedFromHeightStdDev, - // Downside returns and deviation (for Sortino ratio) - pub price_downside_24h: M::Stored>>, - pub price_downside_24h_sd_1w: ComputedFromHeightStdDev, - pub price_downside_24h_sd_1m: ComputedFromHeightStdDev, - pub price_downside_24h_sd_1y: ComputedFromHeightStdDev, } diff --git a/crates/brk_computer/src/market/volatility/compute.rs b/crates/brk_computer/src/market/volatility/compute.rs deleted file mode 100644 index af0ee1b66..000000000 --- a/crates/brk_computer/src/market/volatility/compute.rs +++ /dev/null @@ -1,98 +0,0 @@ -use brk_error::Result; -use brk_types::{Height, StoredF32}; -use vecdb::{EagerVec, Exit, PcoVec, ReadableVec}; - -use super::super::returns; -use super::Vecs; - -impl Vecs { - pub(crate) fn compute( - &mut self, - returns: &returns::Vecs, - starting_indexes_height: Height, - exit: &Exit, - ) -> Result<()> { - // Sharpe ratios: returns / volatility - for (out, ret, vol) in [ - ( - &mut self.price_sharpe_1w, - &returns.price_return._1w.ratio.height, - &self.price_volatility_1w.height, - ), - ( - &mut self.price_sharpe_1m, - &returns.price_return._1m.ratio.height, - &self.price_volatility_1m.height, - ), - ( - &mut self.price_sharpe_1y, - &returns.price_return._1y.ratio.height, - &self.price_volatility_1y.height, - ), - ] { - compute_divided( - &mut out.height, - starting_indexes_height, - ret, - vol, - 1.0, - exit, - )?; - } - - // Sortino ratios: returns / downside volatility (sd * sqrt(days)) - for (out, ret, sd, sqrt_days) in [ - ( - &mut self.price_sortino_1w, - &returns.price_return._1w.ratio.height, - &returns.price_downside_24h_sd_1w.sd.height, - 7.0_f32.sqrt(), - ), - ( - &mut self.price_sortino_1m, - &returns.price_return._1m.ratio.height, - &returns.price_downside_24h_sd_1m.sd.height, - 30.0_f32.sqrt(), - ), - ( - &mut self.price_sortino_1y, - &returns.price_return._1y.ratio.height, - &returns.price_downside_24h_sd_1y.sd.height, - 365.0_f32.sqrt(), - ), - ] { - compute_divided( - &mut out.height, - starting_indexes_height, - ret, - sd, - sqrt_days, - exit, - )?; - } - - Ok(()) - } -} - -fn compute_divided( - out: &mut EagerVec>, - starting_indexes_height: Height, - ret: &impl ReadableVec, - divisor: &impl ReadableVec, - divisor_scale: f32, - exit: &Exit, -) -> Result<()> { - out.compute_transform2( - starting_indexes_height, - ret, - divisor, - |(h, ret, div, ..)| { - let denom = (*div) * divisor_scale; - let ratio = if denom == 0.0 { 0.0 } else { (*ret) / denom }; - (h, StoredF32::from(ratio)) - }, - exit, - )?; - Ok(()) -} diff --git a/crates/brk_computer/src/market/volatility/import.rs b/crates/brk_computer/src/market/volatility/import.rs index fc2f9dfb5..6e7d83626 100644 --- a/crates/brk_computer/src/market/volatility/import.rs +++ b/crates/brk_computer/src/market/volatility/import.rs @@ -1,19 +1,13 @@ use brk_error::Result; use brk_types::Version; -use vecdb::{Database, ReadableCloneableVec}; +use vecdb::ReadableCloneableVec; use super::super::returns; use super::Vecs; -use crate::indexes; -use crate::internal::{ComputedFromHeight, Days7, Days30, Days365, LazyFromHeight, TimesSqrt}; +use crate::internal::{Days30, Days365, Days7, LazyFromHeight, TimesSqrt}; impl Vecs { - pub(crate) fn forced_import( - db: &Database, - version: Version, - indexes: &indexes::Vecs, - returns: &returns::Vecs, - ) -> Result { + pub(crate) fn forced_import(version: Version, returns: &returns::Vecs) -> Result { let v2 = Version::TWO; let price_volatility_1w = LazyFromHeight::from_computed::>( @@ -49,30 +43,10 @@ impl Vecs { &returns.price_return_24h_sd_1y.sd, ); - let price_sharpe_1w = - ComputedFromHeight::forced_import(db, "price_sharpe_1w", version + v2, indexes)?; - let price_sharpe_1m = - ComputedFromHeight::forced_import(db, "price_sharpe_1m", version + v2, indexes)?; - let price_sharpe_1y = - ComputedFromHeight::forced_import(db, "price_sharpe_1y", version + v2, indexes)?; - - let price_sortino_1w = - ComputedFromHeight::forced_import(db, "price_sortino_1w", version + v2, indexes)?; - let price_sortino_1m = - ComputedFromHeight::forced_import(db, "price_sortino_1m", version + v2, indexes)?; - let price_sortino_1y = - ComputedFromHeight::forced_import(db, "price_sortino_1y", version + v2, indexes)?; - Ok(Self { price_volatility_1w, price_volatility_1m, price_volatility_1y, - price_sharpe_1w, - price_sharpe_1m, - price_sharpe_1y, - price_sortino_1w, - price_sortino_1m, - price_sortino_1y, }) } } diff --git a/crates/brk_computer/src/market/volatility/mod.rs b/crates/brk_computer/src/market/volatility/mod.rs index 1136f9ebd..f8623047a 100644 --- a/crates/brk_computer/src/market/volatility/mod.rs +++ b/crates/brk_computer/src/market/volatility/mod.rs @@ -1,4 +1,3 @@ -mod compute; mod import; mod vecs; diff --git a/crates/brk_computer/src/market/volatility/vecs.rs b/crates/brk_computer/src/market/volatility/vecs.rs index bdc4630e9..e85473a8c 100644 --- a/crates/brk_computer/src/market/volatility/vecs.rs +++ b/crates/brk_computer/src/market/volatility/vecs.rs @@ -1,20 +1,11 @@ use brk_traversable::Traversable; -use vecdb::{Rw, StorageMode}; -use crate::internal::{ComputedFromHeight, LazyFromHeight}; +use crate::internal::LazyFromHeight; use brk_types::StoredF32; -#[derive(Traversable)] -pub struct Vecs { +#[derive(Clone, Traversable)] +pub struct Vecs { pub price_volatility_1w: LazyFromHeight, pub price_volatility_1m: LazyFromHeight, pub price_volatility_1y: LazyFromHeight, - - pub price_sharpe_1w: ComputedFromHeight, - pub price_sharpe_1m: ComputedFromHeight, - pub price_sharpe_1y: ComputedFromHeight, - - pub price_sortino_1w: ComputedFromHeight, - pub price_sortino_1m: ComputedFromHeight, - pub price_sortino_1y: ComputedFromHeight, } diff --git a/crates/brk_computer/src/pools/vecs.rs b/crates/brk_computer/src/pools/vecs.rs index 7ef498665..9f73b7964 100644 --- a/crates/brk_computer/src/pools/vecs.rs +++ b/crates/brk_computer/src/pools/vecs.rs @@ -2,14 +2,14 @@ use brk_error::Result; use brk_traversable::Traversable; use brk_types::{BasisPoints16, Height, Indexes, PoolSlug, StoredU32}; use vecdb::{ - AnyVec, BinaryTransform, Database, Exit, ReadableVec, Rw, StorageMode, VecIndex, Version, + BinaryTransform, Database, Exit, ReadableVec, Rw, StorageMode, Version, }; use crate::{ blocks, indexes, internal::{ - ComputedFromHeight, ComputedFromHeightCumulativeSum, MaskSats, PercentFromHeight, - PercentRollingWindows, RatioU32Bp16, RollingWindows, ValueFromHeightCumulativeSum, + ComputedFromHeightCumulativeSum, MaskSats, PercentFromHeight, + PercentRollingWindows, RatioU32Bp16, ValueFromHeightCumulativeSum, }, mining, prices, }; @@ -19,13 +19,9 @@ pub struct Vecs { slug: PoolSlug, pub blocks_mined: ComputedFromHeightCumulativeSum, - pub blocks_mined_sum: RollingWindows, - pub subsidy: ValueFromHeightCumulativeSum, - pub fee: ValueFromHeightCumulativeSum, - pub coinbase: ValueFromHeightCumulativeSum, + pub rewards: ValueFromHeightCumulativeSum, pub dominance: PercentFromHeight, pub dominance_rolling: PercentRollingWindows, - pub blocks_since_last_mined: ComputedFromHeight, } impl Vecs { @@ -45,17 +41,8 @@ impl Vecs { indexes, )?; - let blocks_mined_sum = - RollingWindows::forced_import(db, &suffix("blocks_mined_sum"), version, indexes)?; - - let subsidy = - ValueFromHeightCumulativeSum::forced_import(db, &suffix("subsidy"), version, indexes)?; - - let fee = - ValueFromHeightCumulativeSum::forced_import(db, &suffix("fee"), version, indexes)?; - - let coinbase = - ValueFromHeightCumulativeSum::forced_import(db, &suffix("coinbase"), version, indexes)?; + let rewards = + ValueFromHeightCumulativeSum::forced_import(db, &suffix("rewards"), version, indexes)?; let dominance = PercentFromHeight::forced_import(db, &suffix("dominance"), version, indexes)?; @@ -67,16 +54,7 @@ impl Vecs { dominance_rolling, slug, blocks_mined, - blocks_mined_sum, - coinbase, - subsidy, - fee, - blocks_since_last_mined: ComputedFromHeight::forced_import( - db, - &suffix("blocks_since_last_mined"), - version, - indexes, - )?, + rewards, }) } @@ -112,13 +90,6 @@ impl Vecs { Ok(()) })?; - self.blocks_mined_sum.compute_rolling_sum( - starting_indexes.height, - &window_starts, - &self.blocks_mined.height, - exit, - )?; - self.dominance .compute_binary::( starting_indexes.height, @@ -131,7 +102,7 @@ impl Vecs { .dominance_rolling .as_mut_array() .into_iter() - .zip(self.blocks_mined_sum.as_array()) + .zip(self.blocks_mined.sum.as_array()) .zip(blocks.count.block_count_sum.as_array()) { dom.compute_binary::( @@ -142,39 +113,7 @@ impl Vecs { )?; } - self.subsidy.compute( - starting_indexes.height, - &window_starts, - prices, - exit, - |vec| { - Ok(vec.compute_transform2( - starting_indexes.height, - &self.blocks_mined.height, - &mining.rewards.subsidy.base.sats.height, - |(h, mask, val, ..)| (h, MaskSats::apply(mask, val)), - exit, - )?) - }, - )?; - - self.fee.compute( - starting_indexes.height, - &window_starts, - prices, - exit, - |vec| { - Ok(vec.compute_transform2( - starting_indexes.height, - &self.blocks_mined.height, - &mining.rewards.fees.base.sats.height, - |(h, mask, val, ..)| (h, MaskSats::apply(mask, val)), - exit, - )?) - }, - )?; - - self.coinbase.compute( + self.rewards.compute( starting_indexes.height, &window_starts, prices, @@ -190,36 +129,6 @@ impl Vecs { }, )?; - { - let resume_from = self - .blocks_since_last_mined - .height - .len() - .min(starting_indexes.height.to_usize()); - let mut prev = if resume_from > 0 { - self.blocks_since_last_mined - .height - .collect_one_at(resume_from - 1) - .unwrap() - } else { - StoredU32::ZERO - }; - self.blocks_since_last_mined.height.compute_transform( - starting_indexes.height, - &self.blocks_mined.height, - |(h, mined, ..)| { - let blocks = if mined.is_zero() { - prev + StoredU32::ONE - } else { - StoredU32::ZERO - }; - prev = blocks; - (h, blocks) - }, - exit, - )?; - } - Ok(()) } } diff --git a/crates/brk_types/src/age.rs b/crates/brk_types/src/age.rs index f2a40274c..2d9605783 100644 --- a/crates/brk_types/src/age.rs +++ b/crates/brk_types/src/age.rs @@ -54,12 +54,18 @@ impl Age { /// Calculate satblocks destroyed for given supply #[inline] pub fn satblocks_destroyed(&self, supply: Sats) -> Sats { + if self.blocks == 0 { + return Sats::ZERO; + } Sats::from(u64::from(supply) * self.blocks as u64) } /// Calculate satdays destroyed for given supply #[inline] pub fn satdays_destroyed(&self, supply: Sats) -> Sats { + if self.blocks == 0 { + return Sats::ZERO; + } Sats::from((u64::from(supply) as f64 * self.days).floor() as u64) } } diff --git a/crates/brk_types/src/basis_points_32.rs b/crates/brk_types/src/basis_points_32.rs index 5f2007519..93bf0b266 100644 --- a/crates/brk_types/src/basis_points_32.rs +++ b/crates/brk_types/src/basis_points_32.rs @@ -78,11 +78,8 @@ impl From for u32 { impl From for BasisPoints32 { #[inline] fn from(value: f64) -> Self { - debug_assert!( - value >= 0.0 && value <= u32::MAX as f64 / 10000.0, - "f64 out of BasisPoints32 range: {value}" - ); - Self((value * 10000.0).round() as u32) + let scaled = (value * 10000.0).round().clamp(0.0, u32::MAX as f64); + Self(scaled as u32) } } diff --git a/crates/brk_types/src/basis_points_signed_32.rs b/crates/brk_types/src/basis_points_signed_32.rs index d800828ee..f7f05d625 100644 --- a/crates/brk_types/src/basis_points_signed_32.rs +++ b/crates/brk_types/src/basis_points_signed_32.rs @@ -83,11 +83,8 @@ impl From for i32 { impl From for BasisPointsSigned32 { #[inline] fn from(value: f64) -> Self { - debug_assert!( - value >= i32::MIN as f64 / 10000.0 && value <= i32::MAX as f64 / 10000.0, - "f64 out of BasisPointsSigned32 range: {value}" - ); - Self((value * 10000.0).round() as i32) + let scaled = (value * 10000.0).round().clamp(i32::MIN as f64, i32::MAX as f64); + Self(scaled as i32) } } diff --git a/modules/brk-client/index.js b/modules/brk-client/index.js index 138fdde79..cf8964988 100644 --- a/modules/brk-client/index.js +++ b/modules/brk-client/index.js @@ -2124,63 +2124,6 @@ function create_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern(client }; } -/** - * @typedef {Object} BpsPriceRatioPattern - * @property {MetricPattern1} bps - * @property {CentsSatsUsdPattern} price - * @property {MetricPattern1} ratio - * @property {BpsRatioPattern} ratioPct1 - * @property {CentsSatsUsdPattern} ratioPct1Price - * @property {BpsRatioPattern} ratioPct2 - * @property {CentsSatsUsdPattern} ratioPct2Price - * @property {BpsRatioPattern} ratioPct5 - * @property {CentsSatsUsdPattern} ratioPct5Price - * @property {BpsRatioPattern} ratioPct95 - * @property {CentsSatsUsdPattern} ratioPct95Price - * @property {BpsRatioPattern} ratioPct98 - * @property {CentsSatsUsdPattern} ratioPct98Price - * @property {BpsRatioPattern} ratioPct99 - * @property {CentsSatsUsdPattern} ratioPct99Price - * @property {_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern} ratioSd - * @property {_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern} ratioSd1y - * @property {_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern} ratioSd2y - * @property {_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern} ratioSd4y - * @property {BpsRatioPattern} ratioSma1m - * @property {BpsRatioPattern} ratioSma1w - */ - -/** - * Create a BpsPriceRatioPattern pattern node - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {BpsPriceRatioPattern} - */ -function createBpsPriceRatioPattern(client, acc) { - return { - bps: createMetricPattern1(client, _m(acc, 'ratio_bps')), - price: createCentsSatsUsdPattern(client, acc), - ratio: createMetricPattern1(client, _m(acc, 'ratio')), - ratioPct1: createBpsRatioPattern(client, _m(acc, 'ratio_pct1')), - ratioPct1Price: createCentsSatsUsdPattern(client, _m(acc, 'ratio_pct1')), - ratioPct2: createBpsRatioPattern(client, _m(acc, 'ratio_pct2')), - ratioPct2Price: createCentsSatsUsdPattern(client, _m(acc, 'ratio_pct2')), - ratioPct5: createBpsRatioPattern(client, _m(acc, 'ratio_pct5')), - ratioPct5Price: createCentsSatsUsdPattern(client, _m(acc, 'ratio_pct5')), - ratioPct95: createBpsRatioPattern(client, _m(acc, 'ratio_pct95')), - ratioPct95Price: createCentsSatsUsdPattern(client, _m(acc, 'ratio_pct95')), - ratioPct98: createBpsRatioPattern(client, _m(acc, 'ratio_pct98')), - ratioPct98Price: createCentsSatsUsdPattern(client, _m(acc, 'ratio_pct98')), - ratioPct99: createBpsRatioPattern(client, _m(acc, 'ratio_pct99')), - ratioPct99Price: createCentsSatsUsdPattern(client, _m(acc, 'ratio_pct99')), - ratioSd: create_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern(client, _m(acc, 'ratio')), - ratioSd1y: create_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern(client, _m(acc, 'ratio')), - ratioSd2y: create_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern(client, _m(acc, 'ratio')), - ratioSd4y: create_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern(client, _m(acc, 'ratio')), - ratioSma1m: createBpsRatioPattern(client, _m(acc, 'ratio_sma_1m')), - ratioSma1w: createBpsRatioPattern(client, _m(acc, 'ratio_sma_1w')), - }; -} - /** * @typedef {Object} BpsRatioPattern2 * @property {MetricPattern1} bps @@ -2670,7 +2613,7 @@ function createAverageGainsLossesRsiStochPattern(client, acc) { /** * @typedef {Object} ActivityAddrCostOutputsRealizedRelativeSupplyUnrealizedPattern - * @property {CoinblocksCoindaysSatblocksSatdaysSentPattern} activity + * @property {CoinblocksCoindaysSentPattern} activity * @property {MetricPattern1} addrCount * @property {MetricPattern1} addrCountChange1m * @property {MaxMinPattern} costBasis @@ -2689,7 +2632,7 @@ function createAverageGainsLossesRsiStochPattern(client, acc) { */ function createActivityAddrCostOutputsRealizedRelativeSupplyUnrealizedPattern(client, acc) { return { - activity: createCoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc), + activity: createCoinblocksCoindaysSentPattern(client, acc), addrCount: createMetricPattern1(client, _m(acc, 'addr_count')), addrCountChange1m: createMetricPattern1(client, _m(acc, 'addr_count_change_1m')), costBasis: createMaxMinPattern(client, _m(acc, 'cost_basis')), @@ -2866,37 +2809,6 @@ function create_1m1w1y24hBtcCentsSatsUsdPattern(client, acc) { }; } -/** - * @typedef {Object} BlocksCoinbaseDominanceFeeSubsidyPattern - * @property {CumulativeHeightSumPattern} blocksMined - * @property {_1m1w1y24hPattern} blocksMinedSum - * @property {MetricPattern1} blocksSinceLastMined - * @property {BaseCumulativeSumPattern} coinbase - * @property {BpsPercentRatioPattern} dominance - * @property {_1m1w1y24hPattern2} dominanceRolling - * @property {BaseCumulativeSumPattern} fee - * @property {BaseCumulativeSumPattern} subsidy - */ - -/** - * Create a BlocksCoinbaseDominanceFeeSubsidyPattern pattern node - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {BlocksCoinbaseDominanceFeeSubsidyPattern} - */ -function createBlocksCoinbaseDominanceFeeSubsidyPattern(client, acc) { - return { - blocksMined: createCumulativeHeightSumPattern(client, _m(acc, 'blocks_mined')), - blocksMinedSum: create_1m1w1y24hPattern(client, _m(acc, 'blocks_mined_sum')), - blocksSinceLastMined: createMetricPattern1(client, _m(acc, 'blocks_since_last_mined')), - coinbase: createBaseCumulativeSumPattern(client, _m(acc, 'coinbase')), - dominance: createBpsPercentRatioPattern(client, _m(acc, 'dominance')), - dominanceRolling: create_1m1w1y24hPattern2(client, _m(acc, 'dominance')), - fee: createBaseCumulativeSumPattern(client, _m(acc, 'fee')), - subsidy: createBaseCumulativeSumPattern(client, _m(acc, 'subsidy')), - }; -} - /** * @template T * @typedef {Object} AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern @@ -2961,8 +2873,8 @@ function create_10y2y3y4y5y6y8yPattern(client, acc) { /** * @typedef {Object} ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern - * @property {CoinblocksCoindaysSatblocksSatdaysSentPattern} activity - * @property {InvestedMaxMinPercentilesSpotPattern} costBasis + * @property {CoinblocksCoindaysSentPattern} activity + * @property {InvestedMaxMinPercentilesPattern} costBasis * @property {UtxoPattern} outputs * @property {CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern2} realized * @property {InvestedNegNetNuplSupplyUnrealizedPattern2} relative @@ -2978,8 +2890,8 @@ function create_10y2y3y4y5y6y8yPattern(client, acc) { */ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern(client, acc) { return { - activity: createCoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc), - costBasis: createInvestedMaxMinPercentilesSpotPattern(client, acc), + activity: createCoinblocksCoindaysSentPattern(client, acc), + costBasis: createInvestedMaxMinPercentilesPattern(client, acc), outputs: createUtxoPattern(client, _m(acc, 'utxo_count')), realized: createCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern2(client, acc), relative: createInvestedNegNetNuplSupplyUnrealizedPattern2(client, acc), @@ -2990,7 +2902,7 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern(client /** * @typedef {Object} ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 - * @property {CoinblocksCoindaysSatblocksSatdaysSentPattern} activity + * @property {CoinblocksCoindaysSentPattern} activity * @property {MaxMinPattern} costBasis * @property {UtxoPattern} outputs * @property {AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern2} realized @@ -3007,7 +2919,7 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern(client */ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(client, acc) { return { - activity: createCoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc), + activity: createCoinblocksCoindaysSentPattern(client, acc), costBasis: createMaxMinPattern(client, _m(acc, 'cost_basis')), outputs: createUtxoPattern(client, _m(acc, 'utxo_count')), realized: createAdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern2(client, acc), @@ -3019,7 +2931,7 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(clien /** * @typedef {Object} ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 - * @property {CoinblocksCoindaysSatblocksSatdaysSentPattern} activity + * @property {CoinblocksCoindaysSentPattern} activity * @property {MaxMinPattern} costBasis * @property {UtxoPattern} outputs * @property {CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern} realized @@ -3036,7 +2948,7 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(clien */ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, acc) { return { - activity: createCoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc), + activity: createCoinblocksCoindaysSentPattern(client, acc), costBasis: createMaxMinPattern(client, _m(acc, 'cost_basis')), outputs: createUtxoPattern(client, _m(acc, 'utxo_count')), realized: createCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, acc), @@ -3100,60 +3012,6 @@ function createBalanceBothReactivatedReceivingSendingPattern(client, acc) { }; } -/** - * @typedef {Object} CoinblocksCoindaysSatblocksSatdaysSentPattern - * @property {CumulativeHeightSumPattern} coinblocksDestroyed - * @property {CumulativeHeightSumPattern} coindaysDestroyed - * @property {MetricPattern18} satblocksDestroyed - * @property {MetricPattern18} satdaysDestroyed - * @property {BaseCumulativePattern} sent - * @property {_2wPattern} sentEma - */ - -/** - * Create a CoinblocksCoindaysSatblocksSatdaysSentPattern pattern node - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {CoinblocksCoindaysSatblocksSatdaysSentPattern} - */ -function createCoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc) { - return { - coinblocksDestroyed: createCumulativeHeightSumPattern(client, _m(acc, 'coinblocks_destroyed')), - coindaysDestroyed: createCumulativeHeightSumPattern(client, _m(acc, 'coindays_destroyed')), - satblocksDestroyed: createMetricPattern18(client, _m(acc, 'satblocks_destroyed')), - satdaysDestroyed: createMetricPattern18(client, _m(acc, 'satdays_destroyed')), - sent: createBaseCumulativePattern(client, _m(acc, 'sent')), - sentEma: create_2wPattern(client, _m(acc, 'sent_ema_2w')), - }; -} - -/** - * @typedef {Object} InvestedMaxMinPercentilesSpotPattern - * @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} investedCapital - * @property {CentsSatsUsdPattern} max - * @property {CentsSatsUsdPattern} min - * @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} percentiles - * @property {BpsPercentRatioPattern} spotCostBasisPercentile - * @property {BpsPercentRatioPattern} spotInvestedCapitalPercentile - */ - -/** - * Create a InvestedMaxMinPercentilesSpotPattern pattern node - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {InvestedMaxMinPercentilesSpotPattern} - */ -function createInvestedMaxMinPercentilesSpotPattern(client, acc) { - return { - investedCapital: createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, _m(acc, 'invested_capital')), - max: createCentsSatsUsdPattern(client, _m(acc, 'cost_basis_max')), - min: createCentsSatsUsdPattern(client, _m(acc, 'cost_basis_min')), - percentiles: createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, _m(acc, 'cost_basis')), - spotCostBasisPercentile: createBpsPercentRatioPattern(client, _m(acc, 'spot_cost_basis_percentile')), - spotInvestedCapitalPercentile: createBpsPercentRatioPattern(client, _m(acc, 'spot_invested_capital_percentile')), - }; -} - /** * @typedef {Object} EmaHistogramLineSignalPattern * @property {MetricPattern1} emaFast @@ -3225,6 +3083,29 @@ function create_1m1w1y24hPattern5(client, acc) { }; } +/** + * @typedef {Object} BlocksDominanceRewardsPattern + * @property {CumulativeHeightSumPattern} blocksMined + * @property {BpsPercentRatioPattern} dominance + * @property {_1m1w1y24hPattern2} dominanceRolling + * @property {BaseCumulativeSumPattern} rewards + */ + +/** + * Create a BlocksDominanceRewardsPattern pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {BlocksDominanceRewardsPattern} + */ +function createBlocksDominanceRewardsPattern(client, acc) { + return { + blocksMined: createCumulativeHeightSumPattern(client, _m(acc, 'blocks_mined')), + dominance: createBpsPercentRatioPattern(client, _m(acc, 'dominance')), + dominanceRolling: create_1m1w1y24hPattern2(client, _m(acc, 'dominance')), + rewards: createBaseCumulativeSumPattern(client, _m(acc, 'rewards')), + }; +} + /** * @typedef {Object} BtcCentsSatsUsdPattern * @property {MetricPattern1} btc @@ -3248,6 +3129,52 @@ function createBtcCentsSatsUsdPattern(client, acc) { }; } +/** + * @typedef {Object} CoinblocksCoindaysSentPattern + * @property {CumulativeHeightSumPattern} coinblocksDestroyed + * @property {CumulativeHeightSumPattern} coindaysDestroyed + * @property {BaseCumulativePattern} sent + * @property {_2wPattern} sentEma + */ + +/** + * Create a CoinblocksCoindaysSentPattern pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {CoinblocksCoindaysSentPattern} + */ +function createCoinblocksCoindaysSentPattern(client, acc) { + return { + coinblocksDestroyed: createCumulativeHeightSumPattern(client, _m(acc, 'coinblocks_destroyed')), + coindaysDestroyed: createCumulativeHeightSumPattern(client, _m(acc, 'coindays_destroyed')), + sent: createBaseCumulativePattern(client, _m(acc, 'sent')), + sentEma: create_2wPattern(client, _m(acc, 'sent_ema_2w')), + }; +} + +/** + * @typedef {Object} InvestedMaxMinPercentilesPattern + * @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} investedCapital + * @property {CentsSatsUsdPattern} max + * @property {CentsSatsUsdPattern} min + * @property {Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern} percentiles + */ + +/** + * Create a InvestedMaxMinPercentilesPattern pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {InvestedMaxMinPercentilesPattern} + */ +function createInvestedMaxMinPercentilesPattern(client, acc) { + return { + investedCapital: createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, _m(acc, 'invested_capital')), + max: createCentsSatsUsdPattern(client, _m(acc, 'cost_basis_max')), + min: createCentsSatsUsdPattern(client, _m(acc, 'cost_basis_min')), + percentiles: createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, _m(acc, 'cost_basis')), + }; +} + /** * @template T * @typedef {Object} _1m1w1y24hPattern @@ -3336,6 +3263,27 @@ function createBpsPercentRatioPattern(client, acc) { }; } +/** + * @typedef {Object} BpsPriceRatioPattern + * @property {MetricPattern1} bps + * @property {CentsSatsUsdPattern} price + * @property {MetricPattern1} ratio + */ + +/** + * Create a BpsPriceRatioPattern pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {BpsPriceRatioPattern} + */ +function createBpsPriceRatioPattern(client, acc) { + return { + bps: createMetricPattern1(client, _m(acc, 'ratio_bps')), + price: createCentsSatsUsdPattern(client, acc), + ratio: createMetricPattern1(client, _m(acc, 'ratio')), + }; +} + /** * @typedef {Object} CentsSatsUsdPattern2 * @property {MetricPattern2} cents @@ -4372,10 +4320,6 @@ function create_2wPattern(client, acc) { * @property {MetricsTree_Market_Returns_PriceReturn24hSd1w} priceReturn24hSd1w * @property {MetricsTree_Market_Returns_PriceReturn24hSd1m} priceReturn24hSd1m * @property {SdSmaPattern} priceReturn24hSd1y - * @property {MetricPattern18} priceDownside24h - * @property {MetricsTree_Market_Returns_PriceDownside24hSd1w} priceDownside24hSd1w - * @property {MetricsTree_Market_Returns_PriceDownside24hSd1m} priceDownside24hSd1m - * @property {SdSmaPattern} priceDownside24hSd1y */ /** @@ -4407,29 +4351,11 @@ function create_2wPattern(client, acc) { * @property {MetricPattern1} sd */ -/** - * @typedef {Object} MetricsTree_Market_Returns_PriceDownside24hSd1w - * @property {MetricPattern1} sma - * @property {MetricPattern1} sd - */ - -/** - * @typedef {Object} MetricsTree_Market_Returns_PriceDownside24hSd1m - * @property {MetricPattern1} sma - * @property {MetricPattern1} sd - */ - /** * @typedef {Object} MetricsTree_Market_Volatility * @property {MetricPattern1} priceVolatility1w * @property {MetricPattern1} priceVolatility1m * @property {MetricPattern1} priceVolatility1y - * @property {MetricPattern1} priceSharpe1w - * @property {MetricPattern1} priceSharpe1m - * @property {MetricPattern1} priceSharpe1y - * @property {MetricPattern1} priceSortino1w - * @property {MetricPattern1} priceSortino1m - * @property {MetricPattern1} priceSortino1y */ /** @@ -4669,168 +4595,168 @@ function create_2wPattern(client, acc) { /** * @typedef {Object} MetricsTree_Pools_Vecs - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} unknown - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} blockfills - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} ultimuspool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} terrapool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} luxor - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} onethash - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} btccom - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bitfarms - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} huobipool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} wayicn - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} canoepool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} btctop - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bitcoincom - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} pool175btc - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} gbminers - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} axbt - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} asicminer - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bitminter - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bitcoinrussia - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} btcserv - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} simplecoinus - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} btcguild - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} eligius - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} ozcoin - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} eclipsemc - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} maxbtc - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} triplemining - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} coinlab - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} pool50btc - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} ghashio - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} stminingcorp - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bitparking - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} mmpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} polmine - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} kncminer - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bitalo - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} f2pool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} hhtt - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} megabigpower - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} mtred - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} nmcbit - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} yourbtcnet - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} givemecoins - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} braiinspool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} antpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} multicoinco - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bcpoolio - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} cointerra - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} kanopool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} solock - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} ckpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} nicehash - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bitclub - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bitcoinaffiliatenetwork - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} btcc - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bwpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} exxbw - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bitsolo - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bitfury - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} twentyoneinc - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} digitalbtc - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} eightbaochi - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} mybtccoinpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} tbdice - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} hashpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} nexious - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bravomining - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} hotpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} okexpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bcmonster - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} onehash - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bixin - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} tatmaspool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} viabtc - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} connectbtc - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} batpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} waterhole - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} dcexploration - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} dcex - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} btpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} fiftyeightcoin - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bitcoinindia - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} shawnp0wers - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} phashio - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} rigpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} haozhuzhu - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} sevenpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} miningkings - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} hashbx - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} dpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} rawpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} haominer - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} helix - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bitcoinukraine - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} poolin - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} secretsuperstar - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} tigerpoolnet - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} sigmapoolcom - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} okpooltop - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} hummerpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} tangpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bytepool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} spiderpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} novablock - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} miningcity - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} binancepool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} minerium - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} lubiancom - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} okkong - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} aaopool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} emcdpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} foundryusa - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} sbicrypto - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} arkpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} purebtccom - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} marapool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} kucoinpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} entrustcharitypool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} okminer - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} titan - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} pegapool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} btcnuggets - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} cloudhashing - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} digitalxmintsy - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} telco214 - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} btcpoolparty - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} multipool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} transactioncoinmining - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} btcdig - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} trickysbtcpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} btcmp - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} eobot - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} unomp - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} patels - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} gogreenlight - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bitcoinindiapool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} ekanembtc - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} canoe - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} tiger - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} onem1x - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} zulupool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} secpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} ocean - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} whitepool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} wiz - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} wk057 - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} futurebitapollosolo - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} carbonnegative - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} portlandhodl - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} phoenix - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} neopool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} maxipool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} bitfufupool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} gdpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} miningdutch - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} publicpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} miningsquared - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} innopolistech - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} btclab - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} parasite - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} redrockpool - * @property {BlocksCoinbaseDominanceFeeSubsidyPattern} est3lar + * @property {BlocksDominanceRewardsPattern} unknown + * @property {BlocksDominanceRewardsPattern} blockfills + * @property {BlocksDominanceRewardsPattern} ultimuspool + * @property {BlocksDominanceRewardsPattern} terrapool + * @property {BlocksDominanceRewardsPattern} luxor + * @property {BlocksDominanceRewardsPattern} onethash + * @property {BlocksDominanceRewardsPattern} btccom + * @property {BlocksDominanceRewardsPattern} bitfarms + * @property {BlocksDominanceRewardsPattern} huobipool + * @property {BlocksDominanceRewardsPattern} wayicn + * @property {BlocksDominanceRewardsPattern} canoepool + * @property {BlocksDominanceRewardsPattern} btctop + * @property {BlocksDominanceRewardsPattern} bitcoincom + * @property {BlocksDominanceRewardsPattern} pool175btc + * @property {BlocksDominanceRewardsPattern} gbminers + * @property {BlocksDominanceRewardsPattern} axbt + * @property {BlocksDominanceRewardsPattern} asicminer + * @property {BlocksDominanceRewardsPattern} bitminter + * @property {BlocksDominanceRewardsPattern} bitcoinrussia + * @property {BlocksDominanceRewardsPattern} btcserv + * @property {BlocksDominanceRewardsPattern} simplecoinus + * @property {BlocksDominanceRewardsPattern} btcguild + * @property {BlocksDominanceRewardsPattern} eligius + * @property {BlocksDominanceRewardsPattern} ozcoin + * @property {BlocksDominanceRewardsPattern} eclipsemc + * @property {BlocksDominanceRewardsPattern} maxbtc + * @property {BlocksDominanceRewardsPattern} triplemining + * @property {BlocksDominanceRewardsPattern} coinlab + * @property {BlocksDominanceRewardsPattern} pool50btc + * @property {BlocksDominanceRewardsPattern} ghashio + * @property {BlocksDominanceRewardsPattern} stminingcorp + * @property {BlocksDominanceRewardsPattern} bitparking + * @property {BlocksDominanceRewardsPattern} mmpool + * @property {BlocksDominanceRewardsPattern} polmine + * @property {BlocksDominanceRewardsPattern} kncminer + * @property {BlocksDominanceRewardsPattern} bitalo + * @property {BlocksDominanceRewardsPattern} f2pool + * @property {BlocksDominanceRewardsPattern} hhtt + * @property {BlocksDominanceRewardsPattern} megabigpower + * @property {BlocksDominanceRewardsPattern} mtred + * @property {BlocksDominanceRewardsPattern} nmcbit + * @property {BlocksDominanceRewardsPattern} yourbtcnet + * @property {BlocksDominanceRewardsPattern} givemecoins + * @property {BlocksDominanceRewardsPattern} braiinspool + * @property {BlocksDominanceRewardsPattern} antpool + * @property {BlocksDominanceRewardsPattern} multicoinco + * @property {BlocksDominanceRewardsPattern} bcpoolio + * @property {BlocksDominanceRewardsPattern} cointerra + * @property {BlocksDominanceRewardsPattern} kanopool + * @property {BlocksDominanceRewardsPattern} solock + * @property {BlocksDominanceRewardsPattern} ckpool + * @property {BlocksDominanceRewardsPattern} nicehash + * @property {BlocksDominanceRewardsPattern} bitclub + * @property {BlocksDominanceRewardsPattern} bitcoinaffiliatenetwork + * @property {BlocksDominanceRewardsPattern} btcc + * @property {BlocksDominanceRewardsPattern} bwpool + * @property {BlocksDominanceRewardsPattern} exxbw + * @property {BlocksDominanceRewardsPattern} bitsolo + * @property {BlocksDominanceRewardsPattern} bitfury + * @property {BlocksDominanceRewardsPattern} twentyoneinc + * @property {BlocksDominanceRewardsPattern} digitalbtc + * @property {BlocksDominanceRewardsPattern} eightbaochi + * @property {BlocksDominanceRewardsPattern} mybtccoinpool + * @property {BlocksDominanceRewardsPattern} tbdice + * @property {BlocksDominanceRewardsPattern} hashpool + * @property {BlocksDominanceRewardsPattern} nexious + * @property {BlocksDominanceRewardsPattern} bravomining + * @property {BlocksDominanceRewardsPattern} hotpool + * @property {BlocksDominanceRewardsPattern} okexpool + * @property {BlocksDominanceRewardsPattern} bcmonster + * @property {BlocksDominanceRewardsPattern} onehash + * @property {BlocksDominanceRewardsPattern} bixin + * @property {BlocksDominanceRewardsPattern} tatmaspool + * @property {BlocksDominanceRewardsPattern} viabtc + * @property {BlocksDominanceRewardsPattern} connectbtc + * @property {BlocksDominanceRewardsPattern} batpool + * @property {BlocksDominanceRewardsPattern} waterhole + * @property {BlocksDominanceRewardsPattern} dcexploration + * @property {BlocksDominanceRewardsPattern} dcex + * @property {BlocksDominanceRewardsPattern} btpool + * @property {BlocksDominanceRewardsPattern} fiftyeightcoin + * @property {BlocksDominanceRewardsPattern} bitcoinindia + * @property {BlocksDominanceRewardsPattern} shawnp0wers + * @property {BlocksDominanceRewardsPattern} phashio + * @property {BlocksDominanceRewardsPattern} rigpool + * @property {BlocksDominanceRewardsPattern} haozhuzhu + * @property {BlocksDominanceRewardsPattern} sevenpool + * @property {BlocksDominanceRewardsPattern} miningkings + * @property {BlocksDominanceRewardsPattern} hashbx + * @property {BlocksDominanceRewardsPattern} dpool + * @property {BlocksDominanceRewardsPattern} rawpool + * @property {BlocksDominanceRewardsPattern} haominer + * @property {BlocksDominanceRewardsPattern} helix + * @property {BlocksDominanceRewardsPattern} bitcoinukraine + * @property {BlocksDominanceRewardsPattern} poolin + * @property {BlocksDominanceRewardsPattern} secretsuperstar + * @property {BlocksDominanceRewardsPattern} tigerpoolnet + * @property {BlocksDominanceRewardsPattern} sigmapoolcom + * @property {BlocksDominanceRewardsPattern} okpooltop + * @property {BlocksDominanceRewardsPattern} hummerpool + * @property {BlocksDominanceRewardsPattern} tangpool + * @property {BlocksDominanceRewardsPattern} bytepool + * @property {BlocksDominanceRewardsPattern} spiderpool + * @property {BlocksDominanceRewardsPattern} novablock + * @property {BlocksDominanceRewardsPattern} miningcity + * @property {BlocksDominanceRewardsPattern} binancepool + * @property {BlocksDominanceRewardsPattern} minerium + * @property {BlocksDominanceRewardsPattern} lubiancom + * @property {BlocksDominanceRewardsPattern} okkong + * @property {BlocksDominanceRewardsPattern} aaopool + * @property {BlocksDominanceRewardsPattern} emcdpool + * @property {BlocksDominanceRewardsPattern} foundryusa + * @property {BlocksDominanceRewardsPattern} sbicrypto + * @property {BlocksDominanceRewardsPattern} arkpool + * @property {BlocksDominanceRewardsPattern} purebtccom + * @property {BlocksDominanceRewardsPattern} marapool + * @property {BlocksDominanceRewardsPattern} kucoinpool + * @property {BlocksDominanceRewardsPattern} entrustcharitypool + * @property {BlocksDominanceRewardsPattern} okminer + * @property {BlocksDominanceRewardsPattern} titan + * @property {BlocksDominanceRewardsPattern} pegapool + * @property {BlocksDominanceRewardsPattern} btcnuggets + * @property {BlocksDominanceRewardsPattern} cloudhashing + * @property {BlocksDominanceRewardsPattern} digitalxmintsy + * @property {BlocksDominanceRewardsPattern} telco214 + * @property {BlocksDominanceRewardsPattern} btcpoolparty + * @property {BlocksDominanceRewardsPattern} multipool + * @property {BlocksDominanceRewardsPattern} transactioncoinmining + * @property {BlocksDominanceRewardsPattern} btcdig + * @property {BlocksDominanceRewardsPattern} trickysbtcpool + * @property {BlocksDominanceRewardsPattern} btcmp + * @property {BlocksDominanceRewardsPattern} eobot + * @property {BlocksDominanceRewardsPattern} unomp + * @property {BlocksDominanceRewardsPattern} patels + * @property {BlocksDominanceRewardsPattern} gogreenlight + * @property {BlocksDominanceRewardsPattern} bitcoinindiapool + * @property {BlocksDominanceRewardsPattern} ekanembtc + * @property {BlocksDominanceRewardsPattern} canoe + * @property {BlocksDominanceRewardsPattern} tiger + * @property {BlocksDominanceRewardsPattern} onem1x + * @property {BlocksDominanceRewardsPattern} zulupool + * @property {BlocksDominanceRewardsPattern} secpool + * @property {BlocksDominanceRewardsPattern} ocean + * @property {BlocksDominanceRewardsPattern} whitepool + * @property {BlocksDominanceRewardsPattern} wiz + * @property {BlocksDominanceRewardsPattern} wk057 + * @property {BlocksDominanceRewardsPattern} futurebitapollosolo + * @property {BlocksDominanceRewardsPattern} carbonnegative + * @property {BlocksDominanceRewardsPattern} portlandhodl + * @property {BlocksDominanceRewardsPattern} phoenix + * @property {BlocksDominanceRewardsPattern} neopool + * @property {BlocksDominanceRewardsPattern} maxipool + * @property {BlocksDominanceRewardsPattern} bitfufupool + * @property {BlocksDominanceRewardsPattern} gdpool + * @property {BlocksDominanceRewardsPattern} miningdutch + * @property {BlocksDominanceRewardsPattern} publicpool + * @property {BlocksDominanceRewardsPattern} miningsquared + * @property {BlocksDominanceRewardsPattern} innopolistech + * @property {BlocksDominanceRewardsPattern} btclab + * @property {BlocksDominanceRewardsPattern} parasite + * @property {BlocksDominanceRewardsPattern} redrockpool + * @property {BlocksDominanceRewardsPattern} est3lar */ /** @@ -4916,7 +4842,7 @@ function create_2wPattern(client, acc) { * @property {MetricsTree_Distribution_UtxoCohorts_AmountRange} amountRange * @property {MetricsTree_Distribution_UtxoCohorts_LtAmount} ltAmount * @property {MetricsTree_Distribution_UtxoCohorts_Epoch} epoch - * @property {MetricsTree_Distribution_UtxoCohorts_Year} year + * @property {MetricsTree_Distribution_UtxoCohorts_Class} class * @property {MetricsTree_Distribution_UtxoCohorts_Type} type */ @@ -4924,9 +4850,9 @@ function create_2wPattern(client, acc) { * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_All * @property {ChangeHalvedTotalPattern} supply * @property {UtxoPattern} outputs - * @property {CoinblocksCoindaysSatblocksSatdaysSentPattern} activity + * @property {CoinblocksCoindaysSentPattern} activity * @property {AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern} realized - * @property {InvestedMaxMinPercentilesSpotPattern} costBasis + * @property {InvestedMaxMinPercentilesPattern} costBasis * @property {GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern} unrealized * @property {MetricsTree_Distribution_UtxoCohorts_All_Relative} relative */ @@ -4952,9 +4878,9 @@ function create_2wPattern(client, acc) { * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Sth * @property {ChangeHalvedTotalPattern} supply * @property {UtxoPattern} outputs - * @property {CoinblocksCoindaysSatblocksSatdaysSentPattern} activity + * @property {CoinblocksCoindaysSentPattern} activity * @property {AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern} realized - * @property {InvestedMaxMinPercentilesSpotPattern} costBasis + * @property {InvestedMaxMinPercentilesPattern} costBasis * @property {GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern} unrealized * @property {InvestedNegNetNuplSupplyUnrealizedPattern2} relative */ @@ -5091,7 +5017,7 @@ function create_2wPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Year + * @typedef {Object} MetricsTree_Distribution_UtxoCohorts_Class * @property {ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3} _2009 * @property {ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3} _2010 * @property {ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3} _2011 @@ -5513,96 +5439,96 @@ class BrkClient extends BrkClientBase { } }); - YEAR_NAMES = /** @type {const} */ ({ + CLASS_NAMES = /** @type {const} */ ({ "_2009": { - "id": "year_2009", + "id": "class_2009", "short": "2009", - "long": "Year 2009" + "long": "Class 2009" }, "_2010": { - "id": "year_2010", + "id": "class_2010", "short": "2010", - "long": "Year 2010" + "long": "Class 2010" }, "_2011": { - "id": "year_2011", + "id": "class_2011", "short": "2011", - "long": "Year 2011" + "long": "Class 2011" }, "_2012": { - "id": "year_2012", + "id": "class_2012", "short": "2012", - "long": "Year 2012" + "long": "Class 2012" }, "_2013": { - "id": "year_2013", + "id": "class_2013", "short": "2013", - "long": "Year 2013" + "long": "Class 2013" }, "_2014": { - "id": "year_2014", + "id": "class_2014", "short": "2014", - "long": "Year 2014" + "long": "Class 2014" }, "_2015": { - "id": "year_2015", + "id": "class_2015", "short": "2015", - "long": "Year 2015" + "long": "Class 2015" }, "_2016": { - "id": "year_2016", + "id": "class_2016", "short": "2016", - "long": "Year 2016" + "long": "Class 2016" }, "_2017": { - "id": "year_2017", + "id": "class_2017", "short": "2017", - "long": "Year 2017" + "long": "Class 2017" }, "_2018": { - "id": "year_2018", + "id": "class_2018", "short": "2018", - "long": "Year 2018" + "long": "Class 2018" }, "_2019": { - "id": "year_2019", + "id": "class_2019", "short": "2019", - "long": "Year 2019" + "long": "Class 2019" }, "_2020": { - "id": "year_2020", + "id": "class_2020", "short": "2020", - "long": "Year 2020" + "long": "Class 2020" }, "_2021": { - "id": "year_2021", + "id": "class_2021", "short": "2021", - "long": "Year 2021" + "long": "Class 2021" }, "_2022": { - "id": "year_2022", + "id": "class_2022", "short": "2022", - "long": "Year 2022" + "long": "Class 2022" }, "_2023": { - "id": "year_2023", + "id": "class_2023", "short": "2023", - "long": "Year 2023" + "long": "Class 2023" }, "_2024": { - "id": "year_2024", + "id": "class_2024", "short": "2024", - "long": "Year 2024" + "long": "Class 2024" }, "_2025": { - "id": "year_2025", + "id": "class_2025", "short": "2025", - "long": "Year 2025" + "long": "Class 2025" }, "_2026": { - "id": "year_2026", + "id": "class_2026", "short": "2026", - "long": "Year 2026" + "long": "Class 2026" } }); @@ -6713,27 +6639,11 @@ class BrkClient extends BrkClientBase { sd: createMetricPattern1(this, 'price_return_24h_sd_1m'), }, priceReturn24hSd1y: createSdSmaPattern(this, 'price_return_24h'), - priceDownside24h: createMetricPattern18(this, 'price_downside_24h'), - priceDownside24hSd1w: { - sma: createMetricPattern1(this, 'price_downside_24h_sma_1w'), - sd: createMetricPattern1(this, 'price_downside_24h_sd_1w'), - }, - priceDownside24hSd1m: { - sma: createMetricPattern1(this, 'price_downside_24h_sma_1m'), - sd: createMetricPattern1(this, 'price_downside_24h_sd_1m'), - }, - priceDownside24hSd1y: createSdSmaPattern(this, 'price_downside_24h'), }, volatility: { priceVolatility1w: createMetricPattern1(this, 'price_volatility_1w'), priceVolatility1m: createMetricPattern1(this, 'price_volatility_1m'), priceVolatility1y: createMetricPattern1(this, 'price_volatility_1y'), - priceSharpe1w: createMetricPattern1(this, 'price_sharpe_1w'), - priceSharpe1m: createMetricPattern1(this, 'price_sharpe_1m'), - priceSharpe1y: createMetricPattern1(this, 'price_sharpe_1y'), - priceSortino1w: createMetricPattern1(this, 'price_sortino_1w'), - priceSortino1m: createMetricPattern1(this, 'price_sortino_1m'), - priceSortino1y: createMetricPattern1(this, 'price_sortino_1y'), }, range: { priceMin1w: createCentsSatsUsdPattern(this, 'price_min_1w'), @@ -6924,168 +6834,168 @@ class BrkClient extends BrkClientBase { pools: { heightToPool: createMetricPattern18(this, 'pool'), vecs: { - unknown: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'unknown'), - blockfills: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'blockfills'), - ultimuspool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'ultimuspool'), - terrapool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'terrapool'), - luxor: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'luxor'), - onethash: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'onethash'), - btccom: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'btccom'), - bitfarms: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bitfarms'), - huobipool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'huobipool'), - wayicn: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'wayicn'), - canoepool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'canoepool'), - btctop: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'btctop'), - bitcoincom: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bitcoincom'), - pool175btc: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'pool175btc'), - gbminers: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'gbminers'), - axbt: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'axbt'), - asicminer: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'asicminer'), - bitminter: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bitminter'), - bitcoinrussia: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bitcoinrussia'), - btcserv: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'btcserv'), - simplecoinus: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'simplecoinus'), - btcguild: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'btcguild'), - eligius: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'eligius'), - ozcoin: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'ozcoin'), - eclipsemc: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'eclipsemc'), - maxbtc: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'maxbtc'), - triplemining: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'triplemining'), - coinlab: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'coinlab'), - pool50btc: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'pool50btc'), - ghashio: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'ghashio'), - stminingcorp: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'stminingcorp'), - bitparking: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bitparking'), - mmpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'mmpool'), - polmine: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'polmine'), - kncminer: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'kncminer'), - bitalo: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bitalo'), - f2pool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'f2pool'), - hhtt: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'hhtt'), - megabigpower: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'megabigpower'), - mtred: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'mtred'), - nmcbit: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'nmcbit'), - yourbtcnet: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'yourbtcnet'), - givemecoins: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'givemecoins'), - braiinspool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'braiinspool'), - antpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'antpool'), - multicoinco: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'multicoinco'), - bcpoolio: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bcpoolio'), - cointerra: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'cointerra'), - kanopool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'kanopool'), - solock: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'solock'), - ckpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'ckpool'), - nicehash: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'nicehash'), - bitclub: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bitclub'), - bitcoinaffiliatenetwork: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bitcoinaffiliatenetwork'), - btcc: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'btcc'), - bwpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bwpool'), - exxbw: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'exxbw'), - bitsolo: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bitsolo'), - bitfury: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bitfury'), - twentyoneinc: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'twentyoneinc'), - digitalbtc: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'digitalbtc'), - eightbaochi: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'eightbaochi'), - mybtccoinpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'mybtccoinpool'), - tbdice: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'tbdice'), - hashpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'hashpool'), - nexious: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'nexious'), - bravomining: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bravomining'), - hotpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'hotpool'), - okexpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'okexpool'), - bcmonster: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bcmonster'), - onehash: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'onehash'), - bixin: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bixin'), - tatmaspool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'tatmaspool'), - viabtc: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'viabtc'), - connectbtc: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'connectbtc'), - batpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'batpool'), - waterhole: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'waterhole'), - dcexploration: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'dcexploration'), - dcex: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'dcex'), - btpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'btpool'), - fiftyeightcoin: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'fiftyeightcoin'), - bitcoinindia: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bitcoinindia'), - shawnp0wers: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'shawnp0wers'), - phashio: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'phashio'), - rigpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'rigpool'), - haozhuzhu: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'haozhuzhu'), - sevenpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'sevenpool'), - miningkings: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'miningkings'), - hashbx: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'hashbx'), - dpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'dpool'), - rawpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'rawpool'), - haominer: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'haominer'), - helix: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'helix'), - bitcoinukraine: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bitcoinukraine'), - poolin: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'poolin'), - secretsuperstar: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'secretsuperstar'), - tigerpoolnet: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'tigerpoolnet'), - sigmapoolcom: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'sigmapoolcom'), - okpooltop: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'okpooltop'), - hummerpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'hummerpool'), - tangpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'tangpool'), - bytepool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bytepool'), - spiderpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'spiderpool'), - novablock: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'novablock'), - miningcity: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'miningcity'), - binancepool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'binancepool'), - minerium: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'minerium'), - lubiancom: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'lubiancom'), - okkong: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'okkong'), - aaopool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'aaopool'), - emcdpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'emcdpool'), - foundryusa: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'foundryusa'), - sbicrypto: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'sbicrypto'), - arkpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'arkpool'), - purebtccom: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'purebtccom'), - marapool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'marapool'), - kucoinpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'kucoinpool'), - entrustcharitypool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'entrustcharitypool'), - okminer: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'okminer'), - titan: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'titan'), - pegapool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'pegapool'), - btcnuggets: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'btcnuggets'), - cloudhashing: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'cloudhashing'), - digitalxmintsy: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'digitalxmintsy'), - telco214: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'telco214'), - btcpoolparty: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'btcpoolparty'), - multipool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'multipool'), - transactioncoinmining: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'transactioncoinmining'), - btcdig: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'btcdig'), - trickysbtcpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'trickysbtcpool'), - btcmp: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'btcmp'), - eobot: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'eobot'), - unomp: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'unomp'), - patels: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'patels'), - gogreenlight: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'gogreenlight'), - bitcoinindiapool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bitcoinindiapool'), - ekanembtc: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'ekanembtc'), - canoe: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'canoe'), - tiger: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'tiger'), - onem1x: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'onem1x'), - zulupool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'zulupool'), - secpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'secpool'), - ocean: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'ocean'), - whitepool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'whitepool'), - wiz: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'wiz'), - wk057: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'wk057'), - futurebitapollosolo: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'futurebitapollosolo'), - carbonnegative: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'carbonnegative'), - portlandhodl: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'portlandhodl'), - phoenix: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'phoenix'), - neopool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'neopool'), - maxipool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'maxipool'), - bitfufupool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'bitfufupool'), - gdpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'gdpool'), - miningdutch: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'miningdutch'), - publicpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'publicpool'), - miningsquared: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'miningsquared'), - innopolistech: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'innopolistech'), - btclab: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'btclab'), - parasite: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'parasite'), - redrockpool: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'redrockpool'), - est3lar: createBlocksCoinbaseDominanceFeeSubsidyPattern(this, 'est3lar'), + unknown: createBlocksDominanceRewardsPattern(this, 'unknown'), + blockfills: createBlocksDominanceRewardsPattern(this, 'blockfills'), + ultimuspool: createBlocksDominanceRewardsPattern(this, 'ultimuspool'), + terrapool: createBlocksDominanceRewardsPattern(this, 'terrapool'), + luxor: createBlocksDominanceRewardsPattern(this, 'luxor'), + onethash: createBlocksDominanceRewardsPattern(this, 'onethash'), + btccom: createBlocksDominanceRewardsPattern(this, 'btccom'), + bitfarms: createBlocksDominanceRewardsPattern(this, 'bitfarms'), + huobipool: createBlocksDominanceRewardsPattern(this, 'huobipool'), + wayicn: createBlocksDominanceRewardsPattern(this, 'wayicn'), + canoepool: createBlocksDominanceRewardsPattern(this, 'canoepool'), + btctop: createBlocksDominanceRewardsPattern(this, 'btctop'), + bitcoincom: createBlocksDominanceRewardsPattern(this, 'bitcoincom'), + pool175btc: createBlocksDominanceRewardsPattern(this, 'pool175btc'), + gbminers: createBlocksDominanceRewardsPattern(this, 'gbminers'), + axbt: createBlocksDominanceRewardsPattern(this, 'axbt'), + asicminer: createBlocksDominanceRewardsPattern(this, 'asicminer'), + bitminter: createBlocksDominanceRewardsPattern(this, 'bitminter'), + bitcoinrussia: createBlocksDominanceRewardsPattern(this, 'bitcoinrussia'), + btcserv: createBlocksDominanceRewardsPattern(this, 'btcserv'), + simplecoinus: createBlocksDominanceRewardsPattern(this, 'simplecoinus'), + btcguild: createBlocksDominanceRewardsPattern(this, 'btcguild'), + eligius: createBlocksDominanceRewardsPattern(this, 'eligius'), + ozcoin: createBlocksDominanceRewardsPattern(this, 'ozcoin'), + eclipsemc: createBlocksDominanceRewardsPattern(this, 'eclipsemc'), + maxbtc: createBlocksDominanceRewardsPattern(this, 'maxbtc'), + triplemining: createBlocksDominanceRewardsPattern(this, 'triplemining'), + coinlab: createBlocksDominanceRewardsPattern(this, 'coinlab'), + pool50btc: createBlocksDominanceRewardsPattern(this, 'pool50btc'), + ghashio: createBlocksDominanceRewardsPattern(this, 'ghashio'), + stminingcorp: createBlocksDominanceRewardsPattern(this, 'stminingcorp'), + bitparking: createBlocksDominanceRewardsPattern(this, 'bitparking'), + mmpool: createBlocksDominanceRewardsPattern(this, 'mmpool'), + polmine: createBlocksDominanceRewardsPattern(this, 'polmine'), + kncminer: createBlocksDominanceRewardsPattern(this, 'kncminer'), + bitalo: createBlocksDominanceRewardsPattern(this, 'bitalo'), + f2pool: createBlocksDominanceRewardsPattern(this, 'f2pool'), + hhtt: createBlocksDominanceRewardsPattern(this, 'hhtt'), + megabigpower: createBlocksDominanceRewardsPattern(this, 'megabigpower'), + mtred: createBlocksDominanceRewardsPattern(this, 'mtred'), + nmcbit: createBlocksDominanceRewardsPattern(this, 'nmcbit'), + yourbtcnet: createBlocksDominanceRewardsPattern(this, 'yourbtcnet'), + givemecoins: createBlocksDominanceRewardsPattern(this, 'givemecoins'), + braiinspool: createBlocksDominanceRewardsPattern(this, 'braiinspool'), + antpool: createBlocksDominanceRewardsPattern(this, 'antpool'), + multicoinco: createBlocksDominanceRewardsPattern(this, 'multicoinco'), + bcpoolio: createBlocksDominanceRewardsPattern(this, 'bcpoolio'), + cointerra: createBlocksDominanceRewardsPattern(this, 'cointerra'), + kanopool: createBlocksDominanceRewardsPattern(this, 'kanopool'), + solock: createBlocksDominanceRewardsPattern(this, 'solock'), + ckpool: createBlocksDominanceRewardsPattern(this, 'ckpool'), + nicehash: createBlocksDominanceRewardsPattern(this, 'nicehash'), + bitclub: createBlocksDominanceRewardsPattern(this, 'bitclub'), + bitcoinaffiliatenetwork: createBlocksDominanceRewardsPattern(this, 'bitcoinaffiliatenetwork'), + btcc: createBlocksDominanceRewardsPattern(this, 'btcc'), + bwpool: createBlocksDominanceRewardsPattern(this, 'bwpool'), + exxbw: createBlocksDominanceRewardsPattern(this, 'exxbw'), + bitsolo: createBlocksDominanceRewardsPattern(this, 'bitsolo'), + bitfury: createBlocksDominanceRewardsPattern(this, 'bitfury'), + twentyoneinc: createBlocksDominanceRewardsPattern(this, 'twentyoneinc'), + digitalbtc: createBlocksDominanceRewardsPattern(this, 'digitalbtc'), + eightbaochi: createBlocksDominanceRewardsPattern(this, 'eightbaochi'), + mybtccoinpool: createBlocksDominanceRewardsPattern(this, 'mybtccoinpool'), + tbdice: createBlocksDominanceRewardsPattern(this, 'tbdice'), + hashpool: createBlocksDominanceRewardsPattern(this, 'hashpool'), + nexious: createBlocksDominanceRewardsPattern(this, 'nexious'), + bravomining: createBlocksDominanceRewardsPattern(this, 'bravomining'), + hotpool: createBlocksDominanceRewardsPattern(this, 'hotpool'), + okexpool: createBlocksDominanceRewardsPattern(this, 'okexpool'), + bcmonster: createBlocksDominanceRewardsPattern(this, 'bcmonster'), + onehash: createBlocksDominanceRewardsPattern(this, 'onehash'), + bixin: createBlocksDominanceRewardsPattern(this, 'bixin'), + tatmaspool: createBlocksDominanceRewardsPattern(this, 'tatmaspool'), + viabtc: createBlocksDominanceRewardsPattern(this, 'viabtc'), + connectbtc: createBlocksDominanceRewardsPattern(this, 'connectbtc'), + batpool: createBlocksDominanceRewardsPattern(this, 'batpool'), + waterhole: createBlocksDominanceRewardsPattern(this, 'waterhole'), + dcexploration: createBlocksDominanceRewardsPattern(this, 'dcexploration'), + dcex: createBlocksDominanceRewardsPattern(this, 'dcex'), + btpool: createBlocksDominanceRewardsPattern(this, 'btpool'), + fiftyeightcoin: createBlocksDominanceRewardsPattern(this, 'fiftyeightcoin'), + bitcoinindia: createBlocksDominanceRewardsPattern(this, 'bitcoinindia'), + shawnp0wers: createBlocksDominanceRewardsPattern(this, 'shawnp0wers'), + phashio: createBlocksDominanceRewardsPattern(this, 'phashio'), + rigpool: createBlocksDominanceRewardsPattern(this, 'rigpool'), + haozhuzhu: createBlocksDominanceRewardsPattern(this, 'haozhuzhu'), + sevenpool: createBlocksDominanceRewardsPattern(this, 'sevenpool'), + miningkings: createBlocksDominanceRewardsPattern(this, 'miningkings'), + hashbx: createBlocksDominanceRewardsPattern(this, 'hashbx'), + dpool: createBlocksDominanceRewardsPattern(this, 'dpool'), + rawpool: createBlocksDominanceRewardsPattern(this, 'rawpool'), + haominer: createBlocksDominanceRewardsPattern(this, 'haominer'), + helix: createBlocksDominanceRewardsPattern(this, 'helix'), + bitcoinukraine: createBlocksDominanceRewardsPattern(this, 'bitcoinukraine'), + poolin: createBlocksDominanceRewardsPattern(this, 'poolin'), + secretsuperstar: createBlocksDominanceRewardsPattern(this, 'secretsuperstar'), + tigerpoolnet: createBlocksDominanceRewardsPattern(this, 'tigerpoolnet'), + sigmapoolcom: createBlocksDominanceRewardsPattern(this, 'sigmapoolcom'), + okpooltop: createBlocksDominanceRewardsPattern(this, 'okpooltop'), + hummerpool: createBlocksDominanceRewardsPattern(this, 'hummerpool'), + tangpool: createBlocksDominanceRewardsPattern(this, 'tangpool'), + bytepool: createBlocksDominanceRewardsPattern(this, 'bytepool'), + spiderpool: createBlocksDominanceRewardsPattern(this, 'spiderpool'), + novablock: createBlocksDominanceRewardsPattern(this, 'novablock'), + miningcity: createBlocksDominanceRewardsPattern(this, 'miningcity'), + binancepool: createBlocksDominanceRewardsPattern(this, 'binancepool'), + minerium: createBlocksDominanceRewardsPattern(this, 'minerium'), + lubiancom: createBlocksDominanceRewardsPattern(this, 'lubiancom'), + okkong: createBlocksDominanceRewardsPattern(this, 'okkong'), + aaopool: createBlocksDominanceRewardsPattern(this, 'aaopool'), + emcdpool: createBlocksDominanceRewardsPattern(this, 'emcdpool'), + foundryusa: createBlocksDominanceRewardsPattern(this, 'foundryusa'), + sbicrypto: createBlocksDominanceRewardsPattern(this, 'sbicrypto'), + arkpool: createBlocksDominanceRewardsPattern(this, 'arkpool'), + purebtccom: createBlocksDominanceRewardsPattern(this, 'purebtccom'), + marapool: createBlocksDominanceRewardsPattern(this, 'marapool'), + kucoinpool: createBlocksDominanceRewardsPattern(this, 'kucoinpool'), + entrustcharitypool: createBlocksDominanceRewardsPattern(this, 'entrustcharitypool'), + okminer: createBlocksDominanceRewardsPattern(this, 'okminer'), + titan: createBlocksDominanceRewardsPattern(this, 'titan'), + pegapool: createBlocksDominanceRewardsPattern(this, 'pegapool'), + btcnuggets: createBlocksDominanceRewardsPattern(this, 'btcnuggets'), + cloudhashing: createBlocksDominanceRewardsPattern(this, 'cloudhashing'), + digitalxmintsy: createBlocksDominanceRewardsPattern(this, 'digitalxmintsy'), + telco214: createBlocksDominanceRewardsPattern(this, 'telco214'), + btcpoolparty: createBlocksDominanceRewardsPattern(this, 'btcpoolparty'), + multipool: createBlocksDominanceRewardsPattern(this, 'multipool'), + transactioncoinmining: createBlocksDominanceRewardsPattern(this, 'transactioncoinmining'), + btcdig: createBlocksDominanceRewardsPattern(this, 'btcdig'), + trickysbtcpool: createBlocksDominanceRewardsPattern(this, 'trickysbtcpool'), + btcmp: createBlocksDominanceRewardsPattern(this, 'btcmp'), + eobot: createBlocksDominanceRewardsPattern(this, 'eobot'), + unomp: createBlocksDominanceRewardsPattern(this, 'unomp'), + patels: createBlocksDominanceRewardsPattern(this, 'patels'), + gogreenlight: createBlocksDominanceRewardsPattern(this, 'gogreenlight'), + bitcoinindiapool: createBlocksDominanceRewardsPattern(this, 'bitcoinindiapool'), + ekanembtc: createBlocksDominanceRewardsPattern(this, 'ekanembtc'), + canoe: createBlocksDominanceRewardsPattern(this, 'canoe'), + tiger: createBlocksDominanceRewardsPattern(this, 'tiger'), + onem1x: createBlocksDominanceRewardsPattern(this, 'onem1x'), + zulupool: createBlocksDominanceRewardsPattern(this, 'zulupool'), + secpool: createBlocksDominanceRewardsPattern(this, 'secpool'), + ocean: createBlocksDominanceRewardsPattern(this, 'ocean'), + whitepool: createBlocksDominanceRewardsPattern(this, 'whitepool'), + wiz: createBlocksDominanceRewardsPattern(this, 'wiz'), + wk057: createBlocksDominanceRewardsPattern(this, 'wk057'), + futurebitapollosolo: createBlocksDominanceRewardsPattern(this, 'futurebitapollosolo'), + carbonnegative: createBlocksDominanceRewardsPattern(this, 'carbonnegative'), + portlandhodl: createBlocksDominanceRewardsPattern(this, 'portlandhodl'), + phoenix: createBlocksDominanceRewardsPattern(this, 'phoenix'), + neopool: createBlocksDominanceRewardsPattern(this, 'neopool'), + maxipool: createBlocksDominanceRewardsPattern(this, 'maxipool'), + bitfufupool: createBlocksDominanceRewardsPattern(this, 'bitfufupool'), + gdpool: createBlocksDominanceRewardsPattern(this, 'gdpool'), + miningdutch: createBlocksDominanceRewardsPattern(this, 'miningdutch'), + publicpool: createBlocksDominanceRewardsPattern(this, 'publicpool'), + miningsquared: createBlocksDominanceRewardsPattern(this, 'miningsquared'), + innopolistech: createBlocksDominanceRewardsPattern(this, 'innopolistech'), + btclab: createBlocksDominanceRewardsPattern(this, 'btclab'), + parasite: createBlocksDominanceRewardsPattern(this, 'parasite'), + redrockpool: createBlocksDominanceRewardsPattern(this, 'redrockpool'), + est3lar: createBlocksDominanceRewardsPattern(this, 'est3lar'), }, }, prices: { @@ -7130,9 +7040,9 @@ class BrkClient extends BrkClientBase { all: { supply: createChangeHalvedTotalPattern(this, 'supply'), outputs: createUtxoPattern(this, 'utxo_count'), - activity: createCoinblocksCoindaysSatblocksSatdaysSentPattern(this, ''), + activity: createCoinblocksCoindaysSentPattern(this, ''), realized: createAdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(this, ''), - costBasis: createInvestedMaxMinPercentilesSpotPattern(this, ''), + costBasis: createInvestedMaxMinPercentilesPattern(this, ''), unrealized: createGreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(this, ''), relative: { supplyInProfitRelToOwnSupply: createBpsPercentRatioPattern(this, 'supply_in_profit_rel_to_own_supply'), @@ -7153,9 +7063,9 @@ class BrkClient extends BrkClientBase { sth: { supply: createChangeHalvedTotalPattern(this, 'sth_supply'), outputs: createUtxoPattern(this, 'sth_utxo_count'), - activity: createCoinblocksCoindaysSatblocksSatdaysSentPattern(this, 'sth'), + activity: createCoinblocksCoindaysSentPattern(this, 'sth'), realized: createAdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(this, 'sth'), - costBasis: createInvestedMaxMinPercentilesSpotPattern(this, 'sth'), + costBasis: createInvestedMaxMinPercentilesPattern(this, 'sth'), unrealized: createGreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(this, 'sth'), relative: createInvestedNegNetNuplSupplyUnrealizedPattern2(this, 'sth'), }, @@ -7277,25 +7187,25 @@ class BrkClient extends BrkClientBase { _3: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'epoch_3'), _4: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'epoch_4'), }, - year: { - _2009: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2009'), - _2010: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2010'), - _2011: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2011'), - _2012: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2012'), - _2013: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2013'), - _2014: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2014'), - _2015: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2015'), - _2016: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2016'), - _2017: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2017'), - _2018: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2018'), - _2019: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2019'), - _2020: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2020'), - _2021: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2021'), - _2022: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2022'), - _2023: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2023'), - _2024: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2024'), - _2025: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2025'), - _2026: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'year_2026'), + class: { + _2009: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2009'), + _2010: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2010'), + _2011: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2011'), + _2012: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2012'), + _2013: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2013'), + _2014: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2014'), + _2015: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2015'), + _2016: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2016'), + _2017: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2017'), + _2018: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2018'), + _2019: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2019'), + _2020: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2020'), + _2021: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2021'), + _2022: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2022'), + _2023: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2023'), + _2024: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2024'), + _2025: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2025'), + _2026: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'class_2026'), }, type: { p2pk65: createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(this, 'p2pk65'), diff --git a/packages/brk_client/brk_client/__init__.py b/packages/brk_client/brk_client/__init__.py index 4008d53b5..1f566f9eb 100644 --- a/packages/brk_client/brk_client/__init__.py +++ b/packages/brk_client/brk_client/__init__.py @@ -2334,33 +2334,6 @@ class _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern: self.sma: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sma_4y')) self.zscore: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'zscore_4y')) -class BpsPriceRatioPattern: - """Pattern struct for repeated tree structure.""" - - def __init__(self, client: BrkClientBase, acc: str): - """Create pattern node with accumulated metric name.""" - self.bps: MetricPattern1[BasisPoints32] = MetricPattern1(client, _m(acc, 'ratio_bps')) - self.price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, acc) - self.ratio: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'ratio')) - self.ratio_pct1: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'ratio_pct1')) - self.ratio_pct1_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'ratio_pct1')) - self.ratio_pct2: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'ratio_pct2')) - self.ratio_pct2_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'ratio_pct2')) - self.ratio_pct5: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'ratio_pct5')) - self.ratio_pct5_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'ratio_pct5')) - self.ratio_pct95: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'ratio_pct95')) - self.ratio_pct95_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'ratio_pct95')) - self.ratio_pct98: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'ratio_pct98')) - self.ratio_pct98_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'ratio_pct98')) - self.ratio_pct99: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'ratio_pct99')) - self.ratio_pct99_price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'ratio_pct99')) - self.ratio_sd: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern = _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern(client, _m(acc, 'ratio')) - self.ratio_sd_1y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern = _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern(client, _m(acc, 'ratio')) - self.ratio_sd_2y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern = _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern(client, _m(acc, 'ratio')) - self.ratio_sd_4y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern = _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern(client, _m(acc, 'ratio')) - self.ratio_sma_1m: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'ratio_sma_1m')) - self.ratio_sma_1w: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'ratio_sma_1w')) - class BpsRatioPattern2: """Pattern struct for repeated tree structure.""" @@ -2593,7 +2566,7 @@ class ActivityAddrCostOutputsRealizedRelativeSupplyUnrealizedPattern: def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" - self.activity: CoinblocksCoindaysSatblocksSatdaysSentPattern = CoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc) + self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, acc) self.addr_count: MetricPattern1[StoredU64] = MetricPattern1(client, _m(acc, 'addr_count')) self.addr_count_change_1m: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'addr_count_change_1m')) self.cost_basis: MaxMinPattern = MaxMinPattern(client, _m(acc, 'cost_basis')) @@ -2677,20 +2650,6 @@ class _1m1w1y24hBtcCentsSatsUsdPattern: self.sats: MetricPattern18[Sats] = MetricPattern18(client, acc) self.usd: MetricPattern18[Dollars] = MetricPattern18(client, _m(acc, 'usd')) -class BlocksCoinbaseDominanceFeeSubsidyPattern: - """Pattern struct for repeated tree structure.""" - - def __init__(self, client: BrkClientBase, acc: str): - """Create pattern node with accumulated metric name.""" - self.blocks_mined: CumulativeHeightSumPattern[StoredU32] = CumulativeHeightSumPattern(client, _m(acc, 'blocks_mined')) - self.blocks_mined_sum: _1m1w1y24hPattern[StoredU32] = _1m1w1y24hPattern(client, _m(acc, 'blocks_mined_sum')) - self.blocks_since_last_mined: MetricPattern1[StoredU32] = MetricPattern1(client, _m(acc, 'blocks_since_last_mined')) - self.coinbase: BaseCumulativeSumPattern = BaseCumulativeSumPattern(client, _m(acc, 'coinbase')) - self.dominance: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'dominance')) - self.dominance_rolling: _1m1w1y24hPattern2 = _1m1w1y24hPattern2(client, _m(acc, 'dominance')) - self.fee: BaseCumulativeSumPattern = BaseCumulativeSumPattern(client, _m(acc, 'fee')) - self.subsidy: BaseCumulativeSumPattern = BaseCumulativeSumPattern(client, _m(acc, 'subsidy')) - class AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern(Generic[T]): """Pattern struct for repeated tree structure.""" @@ -2723,8 +2682,8 @@ class ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern: def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" - self.activity: CoinblocksCoindaysSatblocksSatdaysSentPattern = CoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc) - self.cost_basis: InvestedMaxMinPercentilesSpotPattern = InvestedMaxMinPercentilesSpotPattern(client, acc) + self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, acc) + self.cost_basis: InvestedMaxMinPercentilesPattern = InvestedMaxMinPercentilesPattern(client, acc) self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count')) self.realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern2 = CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern2(client, acc) self.relative: InvestedNegNetNuplSupplyUnrealizedPattern2 = InvestedNegNetNuplSupplyUnrealizedPattern2(client, acc) @@ -2736,7 +2695,7 @@ class ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4: def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" - self.activity: CoinblocksCoindaysSatblocksSatdaysSentPattern = CoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc) + self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, acc) self.cost_basis: MaxMinPattern = MaxMinPattern(client, _m(acc, 'cost_basis')) self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count')) self.realized: AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern2 = AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern2(client, acc) @@ -2749,7 +2708,7 @@ class ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3: def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" - self.activity: CoinblocksCoindaysSatblocksSatdaysSentPattern = CoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc) + self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, acc) self.cost_basis: MaxMinPattern = MaxMinPattern(client, _m(acc, 'cost_basis')) self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count')) self.realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, acc) @@ -2781,30 +2740,6 @@ class BalanceBothReactivatedReceivingSendingPattern: self.receiving: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredU32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'receiving')) self.sending: AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern[StoredU32] = AverageHeightMaxMedianMinPct10Pct25Pct75Pct90Pattern(client, _m(acc, 'sending')) -class CoinblocksCoindaysSatblocksSatdaysSentPattern: - """Pattern struct for repeated tree structure.""" - - def __init__(self, client: BrkClientBase, acc: str): - """Create pattern node with accumulated metric name.""" - self.coinblocks_destroyed: CumulativeHeightSumPattern[StoredF64] = CumulativeHeightSumPattern(client, _m(acc, 'coinblocks_destroyed')) - self.coindays_destroyed: CumulativeHeightSumPattern[StoredF64] = CumulativeHeightSumPattern(client, _m(acc, 'coindays_destroyed')) - self.satblocks_destroyed: MetricPattern18[Sats] = MetricPattern18(client, _m(acc, 'satblocks_destroyed')) - self.satdays_destroyed: MetricPattern18[Sats] = MetricPattern18(client, _m(acc, 'satdays_destroyed')) - self.sent: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent')) - self.sent_ema: _2wPattern = _2wPattern(client, _m(acc, 'sent_ema_2w')) - -class InvestedMaxMinPercentilesSpotPattern: - """Pattern struct for repeated tree structure.""" - - def __init__(self, client: BrkClientBase, acc: str): - """Create pattern node with accumulated metric name.""" - self.invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern = Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, _m(acc, 'invested_capital')) - self.max: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'cost_basis_max')) - self.min: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'cost_basis_min')) - self.percentiles: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern = Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, _m(acc, 'cost_basis')) - self.spot_cost_basis_percentile: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'spot_cost_basis_percentile')) - self.spot_invested_capital_percentile: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'spot_invested_capital_percentile')) - class EmaHistogramLineSignalPattern: """Pattern struct for repeated tree structure.""" @@ -2836,6 +2771,16 @@ class _1m1w1y24hPattern5: self._1y: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, '1y')) self._24h: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, '24h')) +class BlocksDominanceRewardsPattern: + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self.blocks_mined: CumulativeHeightSumPattern[StoredU32] = CumulativeHeightSumPattern(client, _m(acc, 'blocks_mined')) + self.dominance: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, 'dominance')) + self.dominance_rolling: _1m1w1y24hPattern2 = _1m1w1y24hPattern2(client, _m(acc, 'dominance')) + self.rewards: BaseCumulativeSumPattern = BaseCumulativeSumPattern(client, _m(acc, 'rewards')) + class BtcCentsSatsUsdPattern: """Pattern struct for repeated tree structure.""" @@ -2846,6 +2791,26 @@ class BtcCentsSatsUsdPattern: self.sats: MetricPattern1[Sats] = MetricPattern1(client, acc) self.usd: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd')) +class CoinblocksCoindaysSentPattern: + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self.coinblocks_destroyed: CumulativeHeightSumPattern[StoredF64] = CumulativeHeightSumPattern(client, _m(acc, 'coinblocks_destroyed')) + self.coindays_destroyed: CumulativeHeightSumPattern[StoredF64] = CumulativeHeightSumPattern(client, _m(acc, 'coindays_destroyed')) + self.sent: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent')) + self.sent_ema: _2wPattern = _2wPattern(client, _m(acc, 'sent_ema_2w')) + +class InvestedMaxMinPercentilesPattern: + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self.invested_capital: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern = Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, _m(acc, 'invested_capital')) + self.max: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'cost_basis_max')) + self.min: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'cost_basis_min')) + self.percentiles: Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern = Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75Pct80Pct85Pct90Pct95Pattern(client, _m(acc, 'cost_basis')) + class _1m1w1y24hPattern(Generic[T]): """Pattern struct for repeated tree structure.""" @@ -2883,6 +2848,15 @@ class BpsPercentRatioPattern: self.percent: MetricPattern1[StoredF32] = MetricPattern1(client, acc) self.ratio: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'ratio')) +class BpsPriceRatioPattern: + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self.bps: MetricPattern1[BasisPoints32] = MetricPattern1(client, _m(acc, 'ratio_bps')) + self.price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, acc) + self.ratio: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'ratio')) + class CentsSatsUsdPattern2: """Pattern struct for repeated tree structure.""" @@ -3797,20 +3771,6 @@ class MetricsTree_Market_Returns_PriceReturn24hSd1m: self.sma: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_return_24h_sma_1m') self.sd: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_return_24h_sd_1m') -class MetricsTree_Market_Returns_PriceDownside24hSd1w: - """Metrics tree node.""" - - def __init__(self, client: BrkClientBase, base_path: str = ''): - self.sma: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_downside_24h_sma_1w') - self.sd: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_downside_24h_sd_1w') - -class MetricsTree_Market_Returns_PriceDownside24hSd1m: - """Metrics tree node.""" - - def __init__(self, client: BrkClientBase, base_path: str = ''): - self.sma: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_downside_24h_sma_1m') - self.sd: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_downside_24h_sd_1m') - class MetricsTree_Market_Returns: """Metrics tree node.""" @@ -3820,10 +3780,6 @@ class MetricsTree_Market_Returns: self.price_return_24h_sd_1w: MetricsTree_Market_Returns_PriceReturn24hSd1w = MetricsTree_Market_Returns_PriceReturn24hSd1w(client) self.price_return_24h_sd_1m: MetricsTree_Market_Returns_PriceReturn24hSd1m = MetricsTree_Market_Returns_PriceReturn24hSd1m(client) self.price_return_24h_sd_1y: SdSmaPattern = SdSmaPattern(client, 'price_return_24h') - self.price_downside_24h: MetricPattern18[StoredF32] = MetricPattern18(client, 'price_downside_24h') - self.price_downside_24h_sd_1w: MetricsTree_Market_Returns_PriceDownside24hSd1w = MetricsTree_Market_Returns_PriceDownside24hSd1w(client) - self.price_downside_24h_sd_1m: MetricsTree_Market_Returns_PriceDownside24hSd1m = MetricsTree_Market_Returns_PriceDownside24hSd1m(client) - self.price_downside_24h_sd_1y: SdSmaPattern = SdSmaPattern(client, 'price_downside_24h') class MetricsTree_Market_Volatility: """Metrics tree node.""" @@ -3832,12 +3788,6 @@ class MetricsTree_Market_Volatility: self.price_volatility_1w: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_volatility_1w') self.price_volatility_1m: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_volatility_1m') self.price_volatility_1y: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_volatility_1y') - self.price_sharpe_1w: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_sharpe_1w') - self.price_sharpe_1m: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_sharpe_1m') - self.price_sharpe_1y: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_sharpe_1y') - self.price_sortino_1w: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_sortino_1w') - self.price_sortino_1m: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_sortino_1m') - self.price_sortino_1y: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_sortino_1y') class MetricsTree_Market_Range: """Metrics tree node.""" @@ -4101,168 +4051,168 @@ class MetricsTree_Pools_Vecs: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.unknown: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'unknown') - self.blockfills: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'blockfills') - self.ultimuspool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'ultimuspool') - self.terrapool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'terrapool') - self.luxor: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'luxor') - self.onethash: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'onethash') - self.btccom: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'btccom') - self.bitfarms: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bitfarms') - self.huobipool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'huobipool') - self.wayicn: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'wayicn') - self.canoepool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'canoepool') - self.btctop: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'btctop') - self.bitcoincom: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bitcoincom') - self.pool175btc: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'pool175btc') - self.gbminers: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'gbminers') - self.axbt: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'axbt') - self.asicminer: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'asicminer') - self.bitminter: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bitminter') - self.bitcoinrussia: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bitcoinrussia') - self.btcserv: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'btcserv') - self.simplecoinus: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'simplecoinus') - self.btcguild: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'btcguild') - self.eligius: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'eligius') - self.ozcoin: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'ozcoin') - self.eclipsemc: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'eclipsemc') - self.maxbtc: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'maxbtc') - self.triplemining: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'triplemining') - self.coinlab: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'coinlab') - self.pool50btc: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'pool50btc') - self.ghashio: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'ghashio') - self.stminingcorp: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'stminingcorp') - self.bitparking: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bitparking') - self.mmpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'mmpool') - self.polmine: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'polmine') - self.kncminer: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'kncminer') - self.bitalo: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bitalo') - self.f2pool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'f2pool') - self.hhtt: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'hhtt') - self.megabigpower: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'megabigpower') - self.mtred: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'mtred') - self.nmcbit: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'nmcbit') - self.yourbtcnet: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'yourbtcnet') - self.givemecoins: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'givemecoins') - self.braiinspool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'braiinspool') - self.antpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'antpool') - self.multicoinco: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'multicoinco') - self.bcpoolio: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bcpoolio') - self.cointerra: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'cointerra') - self.kanopool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'kanopool') - self.solock: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'solock') - self.ckpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'ckpool') - self.nicehash: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'nicehash') - self.bitclub: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bitclub') - self.bitcoinaffiliatenetwork: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bitcoinaffiliatenetwork') - self.btcc: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'btcc') - self.bwpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bwpool') - self.exxbw: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'exxbw') - self.bitsolo: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bitsolo') - self.bitfury: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bitfury') - self.twentyoneinc: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'twentyoneinc') - self.digitalbtc: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'digitalbtc') - self.eightbaochi: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'eightbaochi') - self.mybtccoinpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'mybtccoinpool') - self.tbdice: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'tbdice') - self.hashpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'hashpool') - self.nexious: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'nexious') - self.bravomining: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bravomining') - self.hotpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'hotpool') - self.okexpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'okexpool') - self.bcmonster: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bcmonster') - self.onehash: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'onehash') - self.bixin: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bixin') - self.tatmaspool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'tatmaspool') - self.viabtc: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'viabtc') - self.connectbtc: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'connectbtc') - self.batpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'batpool') - self.waterhole: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'waterhole') - self.dcexploration: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'dcexploration') - self.dcex: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'dcex') - self.btpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'btpool') - self.fiftyeightcoin: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'fiftyeightcoin') - self.bitcoinindia: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bitcoinindia') - self.shawnp0wers: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'shawnp0wers') - self.phashio: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'phashio') - self.rigpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'rigpool') - self.haozhuzhu: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'haozhuzhu') - self.sevenpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'sevenpool') - self.miningkings: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'miningkings') - self.hashbx: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'hashbx') - self.dpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'dpool') - self.rawpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'rawpool') - self.haominer: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'haominer') - self.helix: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'helix') - self.bitcoinukraine: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bitcoinukraine') - self.poolin: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'poolin') - self.secretsuperstar: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'secretsuperstar') - self.tigerpoolnet: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'tigerpoolnet') - self.sigmapoolcom: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'sigmapoolcom') - self.okpooltop: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'okpooltop') - self.hummerpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'hummerpool') - self.tangpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'tangpool') - self.bytepool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bytepool') - self.spiderpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'spiderpool') - self.novablock: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'novablock') - self.miningcity: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'miningcity') - self.binancepool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'binancepool') - self.minerium: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'minerium') - self.lubiancom: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'lubiancom') - self.okkong: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'okkong') - self.aaopool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'aaopool') - self.emcdpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'emcdpool') - self.foundryusa: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'foundryusa') - self.sbicrypto: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'sbicrypto') - self.arkpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'arkpool') - self.purebtccom: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'purebtccom') - self.marapool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'marapool') - self.kucoinpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'kucoinpool') - self.entrustcharitypool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'entrustcharitypool') - self.okminer: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'okminer') - self.titan: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'titan') - self.pegapool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'pegapool') - self.btcnuggets: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'btcnuggets') - self.cloudhashing: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'cloudhashing') - self.digitalxmintsy: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'digitalxmintsy') - self.telco214: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'telco214') - self.btcpoolparty: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'btcpoolparty') - self.multipool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'multipool') - self.transactioncoinmining: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'transactioncoinmining') - self.btcdig: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'btcdig') - self.trickysbtcpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'trickysbtcpool') - self.btcmp: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'btcmp') - self.eobot: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'eobot') - self.unomp: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'unomp') - self.patels: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'patels') - self.gogreenlight: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'gogreenlight') - self.bitcoinindiapool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bitcoinindiapool') - self.ekanembtc: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'ekanembtc') - self.canoe: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'canoe') - self.tiger: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'tiger') - self.onem1x: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'onem1x') - self.zulupool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'zulupool') - self.secpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'secpool') - self.ocean: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'ocean') - self.whitepool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'whitepool') - self.wiz: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'wiz') - self.wk057: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'wk057') - self.futurebitapollosolo: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'futurebitapollosolo') - self.carbonnegative: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'carbonnegative') - self.portlandhodl: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'portlandhodl') - self.phoenix: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'phoenix') - self.neopool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'neopool') - self.maxipool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'maxipool') - self.bitfufupool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'bitfufupool') - self.gdpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'gdpool') - self.miningdutch: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'miningdutch') - self.publicpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'publicpool') - self.miningsquared: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'miningsquared') - self.innopolistech: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'innopolistech') - self.btclab: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'btclab') - self.parasite: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'parasite') - self.redrockpool: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'redrockpool') - self.est3lar: BlocksCoinbaseDominanceFeeSubsidyPattern = BlocksCoinbaseDominanceFeeSubsidyPattern(client, 'est3lar') + self.unknown: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'unknown') + self.blockfills: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'blockfills') + self.ultimuspool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'ultimuspool') + self.terrapool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'terrapool') + self.luxor: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'luxor') + self.onethash: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'onethash') + self.btccom: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'btccom') + self.bitfarms: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bitfarms') + self.huobipool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'huobipool') + self.wayicn: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'wayicn') + self.canoepool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'canoepool') + self.btctop: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'btctop') + self.bitcoincom: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bitcoincom') + self.pool175btc: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'pool175btc') + self.gbminers: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'gbminers') + self.axbt: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'axbt') + self.asicminer: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'asicminer') + self.bitminter: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bitminter') + self.bitcoinrussia: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bitcoinrussia') + self.btcserv: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'btcserv') + self.simplecoinus: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'simplecoinus') + self.btcguild: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'btcguild') + self.eligius: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'eligius') + self.ozcoin: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'ozcoin') + self.eclipsemc: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'eclipsemc') + self.maxbtc: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'maxbtc') + self.triplemining: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'triplemining') + self.coinlab: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'coinlab') + self.pool50btc: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'pool50btc') + self.ghashio: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'ghashio') + self.stminingcorp: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'stminingcorp') + self.bitparking: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bitparking') + self.mmpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'mmpool') + self.polmine: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'polmine') + self.kncminer: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'kncminer') + self.bitalo: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bitalo') + self.f2pool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'f2pool') + self.hhtt: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'hhtt') + self.megabigpower: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'megabigpower') + self.mtred: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'mtred') + self.nmcbit: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'nmcbit') + self.yourbtcnet: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'yourbtcnet') + self.givemecoins: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'givemecoins') + self.braiinspool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'braiinspool') + self.antpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'antpool') + self.multicoinco: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'multicoinco') + self.bcpoolio: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bcpoolio') + self.cointerra: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'cointerra') + self.kanopool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'kanopool') + self.solock: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'solock') + self.ckpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'ckpool') + self.nicehash: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'nicehash') + self.bitclub: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bitclub') + self.bitcoinaffiliatenetwork: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bitcoinaffiliatenetwork') + self.btcc: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'btcc') + self.bwpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bwpool') + self.exxbw: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'exxbw') + self.bitsolo: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bitsolo') + self.bitfury: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bitfury') + self.twentyoneinc: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'twentyoneinc') + self.digitalbtc: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'digitalbtc') + self.eightbaochi: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'eightbaochi') + self.mybtccoinpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'mybtccoinpool') + self.tbdice: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'tbdice') + self.hashpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'hashpool') + self.nexious: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'nexious') + self.bravomining: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bravomining') + self.hotpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'hotpool') + self.okexpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'okexpool') + self.bcmonster: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bcmonster') + self.onehash: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'onehash') + self.bixin: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bixin') + self.tatmaspool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'tatmaspool') + self.viabtc: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'viabtc') + self.connectbtc: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'connectbtc') + self.batpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'batpool') + self.waterhole: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'waterhole') + self.dcexploration: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'dcexploration') + self.dcex: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'dcex') + self.btpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'btpool') + self.fiftyeightcoin: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'fiftyeightcoin') + self.bitcoinindia: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bitcoinindia') + self.shawnp0wers: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'shawnp0wers') + self.phashio: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'phashio') + self.rigpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'rigpool') + self.haozhuzhu: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'haozhuzhu') + self.sevenpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'sevenpool') + self.miningkings: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'miningkings') + self.hashbx: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'hashbx') + self.dpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'dpool') + self.rawpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'rawpool') + self.haominer: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'haominer') + self.helix: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'helix') + self.bitcoinukraine: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bitcoinukraine') + self.poolin: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'poolin') + self.secretsuperstar: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'secretsuperstar') + self.tigerpoolnet: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'tigerpoolnet') + self.sigmapoolcom: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'sigmapoolcom') + self.okpooltop: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'okpooltop') + self.hummerpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'hummerpool') + self.tangpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'tangpool') + self.bytepool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bytepool') + self.spiderpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'spiderpool') + self.novablock: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'novablock') + self.miningcity: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'miningcity') + self.binancepool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'binancepool') + self.minerium: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'minerium') + self.lubiancom: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'lubiancom') + self.okkong: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'okkong') + self.aaopool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'aaopool') + self.emcdpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'emcdpool') + self.foundryusa: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'foundryusa') + self.sbicrypto: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'sbicrypto') + self.arkpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'arkpool') + self.purebtccom: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'purebtccom') + self.marapool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'marapool') + self.kucoinpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'kucoinpool') + self.entrustcharitypool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'entrustcharitypool') + self.okminer: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'okminer') + self.titan: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'titan') + self.pegapool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'pegapool') + self.btcnuggets: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'btcnuggets') + self.cloudhashing: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'cloudhashing') + self.digitalxmintsy: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'digitalxmintsy') + self.telco214: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'telco214') + self.btcpoolparty: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'btcpoolparty') + self.multipool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'multipool') + self.transactioncoinmining: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'transactioncoinmining') + self.btcdig: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'btcdig') + self.trickysbtcpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'trickysbtcpool') + self.btcmp: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'btcmp') + self.eobot: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'eobot') + self.unomp: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'unomp') + self.patels: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'patels') + self.gogreenlight: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'gogreenlight') + self.bitcoinindiapool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bitcoinindiapool') + self.ekanembtc: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'ekanembtc') + self.canoe: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'canoe') + self.tiger: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'tiger') + self.onem1x: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'onem1x') + self.zulupool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'zulupool') + self.secpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'secpool') + self.ocean: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'ocean') + self.whitepool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'whitepool') + self.wiz: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'wiz') + self.wk057: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'wk057') + self.futurebitapollosolo: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'futurebitapollosolo') + self.carbonnegative: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'carbonnegative') + self.portlandhodl: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'portlandhodl') + self.phoenix: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'phoenix') + self.neopool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'neopool') + self.maxipool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'maxipool') + self.bitfufupool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'bitfufupool') + self.gdpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'gdpool') + self.miningdutch: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'miningdutch') + self.publicpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'publicpool') + self.miningsquared: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'miningsquared') + self.innopolistech: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'innopolistech') + self.btclab: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'btclab') + self.parasite: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'parasite') + self.redrockpool: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'redrockpool') + self.est3lar: BlocksDominanceRewardsPattern = BlocksDominanceRewardsPattern(client, 'est3lar') class MetricsTree_Pools: """Metrics tree node.""" @@ -4356,9 +4306,9 @@ class MetricsTree_Distribution_UtxoCohorts_All: def __init__(self, client: BrkClientBase, base_path: str = ''): self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'supply') self.outputs: UtxoPattern = UtxoPattern(client, 'utxo_count') - self.activity: CoinblocksCoindaysSatblocksSatdaysSentPattern = CoinblocksCoindaysSatblocksSatdaysSentPattern(client, '') + self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, '') self.realized: AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, '') - self.cost_basis: InvestedMaxMinPercentilesSpotPattern = InvestedMaxMinPercentilesSpotPattern(client, '') + self.cost_basis: InvestedMaxMinPercentilesPattern = InvestedMaxMinPercentilesPattern(client, '') self.unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern = GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(client, '') self.relative: MetricsTree_Distribution_UtxoCohorts_All_Relative = MetricsTree_Distribution_UtxoCohorts_All_Relative(client) @@ -4368,9 +4318,9 @@ class MetricsTree_Distribution_UtxoCohorts_Sth: def __init__(self, client: BrkClientBase, base_path: str = ''): self.supply: ChangeHalvedTotalPattern = ChangeHalvedTotalPattern(client, 'sth_supply') self.outputs: UtxoPattern = UtxoPattern(client, 'sth_utxo_count') - self.activity: CoinblocksCoindaysSatblocksSatdaysSentPattern = CoinblocksCoindaysSatblocksSatdaysSentPattern(client, 'sth') + self.activity: CoinblocksCoindaysSentPattern = CoinblocksCoindaysSentPattern(client, 'sth') self.realized: AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern = AdjustedCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern(client, 'sth') - self.cost_basis: InvestedMaxMinPercentilesSpotPattern = InvestedMaxMinPercentilesSpotPattern(client, 'sth') + self.cost_basis: InvestedMaxMinPercentilesPattern = InvestedMaxMinPercentilesPattern(client, 'sth') self.unrealized: GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern = GreedGrossInvestedInvestorNegNetPainSupplyUnrealizedPattern(client, 'sth') self.relative: InvestedNegNetNuplSupplyUnrealizedPattern2 = InvestedNegNetNuplSupplyUnrealizedPattern2(client, 'sth') @@ -4512,28 +4462,28 @@ class MetricsTree_Distribution_UtxoCohorts_Epoch: self._3: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'epoch_3') self._4: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'epoch_4') -class MetricsTree_Distribution_UtxoCohorts_Year: +class MetricsTree_Distribution_UtxoCohorts_Class: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self._2009: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2009') - self._2010: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2010') - self._2011: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2011') - self._2012: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2012') - self._2013: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2013') - self._2014: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2014') - self._2015: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2015') - self._2016: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2016') - self._2017: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2017') - self._2018: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2018') - self._2019: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2019') - self._2020: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2020') - self._2021: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2021') - self._2022: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2022') - self._2023: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2023') - self._2024: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2024') - self._2025: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2025') - self._2026: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'year_2026') + self._2009: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2009') + self._2010: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2010') + self._2011: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2011') + self._2012: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2012') + self._2013: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2013') + self._2014: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2014') + self._2015: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2015') + self._2016: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2016') + self._2017: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2017') + self._2018: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2018') + self._2019: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2019') + self._2020: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2020') + self._2021: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2021') + self._2022: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2022') + self._2023: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2023') + self._2024: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2024') + self._2025: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2025') + self._2026: ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 = ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(client, 'class_2026') class MetricsTree_Distribution_UtxoCohorts_Type: """Metrics tree node.""" @@ -4565,7 +4515,7 @@ class MetricsTree_Distribution_UtxoCohorts: 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.epoch: MetricsTree_Distribution_UtxoCohorts_Epoch = MetricsTree_Distribution_UtxoCohorts_Epoch(client) - self.year: MetricsTree_Distribution_UtxoCohorts_Year = MetricsTree_Distribution_UtxoCohorts_Year(client) + self.class: MetricsTree_Distribution_UtxoCohorts_Class = MetricsTree_Distribution_UtxoCohorts_Class(client) self.type_: MetricsTree_Distribution_UtxoCohorts_Type = MetricsTree_Distribution_UtxoCohorts_Type(client) class MetricsTree_Distribution_AddressCohorts_GeAmount: @@ -5002,96 +4952,96 @@ class BrkClient(BrkClientBase): } } - YEAR_NAMES = { + CLASS_NAMES = { "_2009": { - "id": "year_2009", + "id": "class_2009", "short": "2009", - "long": "Year 2009" + "long": "Class 2009" }, "_2010": { - "id": "year_2010", + "id": "class_2010", "short": "2010", - "long": "Year 2010" + "long": "Class 2010" }, "_2011": { - "id": "year_2011", + "id": "class_2011", "short": "2011", - "long": "Year 2011" + "long": "Class 2011" }, "_2012": { - "id": "year_2012", + "id": "class_2012", "short": "2012", - "long": "Year 2012" + "long": "Class 2012" }, "_2013": { - "id": "year_2013", + "id": "class_2013", "short": "2013", - "long": "Year 2013" + "long": "Class 2013" }, "_2014": { - "id": "year_2014", + "id": "class_2014", "short": "2014", - "long": "Year 2014" + "long": "Class 2014" }, "_2015": { - "id": "year_2015", + "id": "class_2015", "short": "2015", - "long": "Year 2015" + "long": "Class 2015" }, "_2016": { - "id": "year_2016", + "id": "class_2016", "short": "2016", - "long": "Year 2016" + "long": "Class 2016" }, "_2017": { - "id": "year_2017", + "id": "class_2017", "short": "2017", - "long": "Year 2017" + "long": "Class 2017" }, "_2018": { - "id": "year_2018", + "id": "class_2018", "short": "2018", - "long": "Year 2018" + "long": "Class 2018" }, "_2019": { - "id": "year_2019", + "id": "class_2019", "short": "2019", - "long": "Year 2019" + "long": "Class 2019" }, "_2020": { - "id": "year_2020", + "id": "class_2020", "short": "2020", - "long": "Year 2020" + "long": "Class 2020" }, "_2021": { - "id": "year_2021", + "id": "class_2021", "short": "2021", - "long": "Year 2021" + "long": "Class 2021" }, "_2022": { - "id": "year_2022", + "id": "class_2022", "short": "2022", - "long": "Year 2022" + "long": "Class 2022" }, "_2023": { - "id": "year_2023", + "id": "class_2023", "short": "2023", - "long": "Year 2023" + "long": "Class 2023" }, "_2024": { - "id": "year_2024", + "id": "class_2024", "short": "2024", - "long": "Year 2024" + "long": "Class 2024" }, "_2025": { - "id": "year_2025", + "id": "class_2025", "short": "2025", - "long": "Year 2025" + "long": "Class 2025" }, "_2026": { - "id": "year_2026", + "id": "class_2026", "short": "2026", - "long": "Year 2026" + "long": "Class 2026" } } diff --git a/website/scripts/options/distribution/data.js b/website/scripts/options/distribution/data.js index 9095d22a3..829ae1eeb 100644 --- a/website/scripts/options/distribution/data.js +++ b/website/scripts/options/distribution/data.js @@ -37,7 +37,7 @@ export function buildCohortData() { LT_AMOUNT_NAMES, AMOUNT_RANGE_NAMES, SPENDABLE_TYPE_NAMES, - YEAR_NAMES, + CLASS_NAMES, } = brk; // Base cohort representing "all" @@ -224,11 +224,11 @@ export function buildCohortData() { }; }); - // Year cohorts - const year = entries(utxoCohorts.year) + // Class cohorts + const class_ = entries(utxoCohorts.class) .reverse() .map(([key, tree], i, arr) => { - const names = YEAR_NAMES[key]; + const names = CLASS_NAMES[key]; return { name: names.short, title: names.long, @@ -253,6 +253,6 @@ export function buildCohortData() { addressesAmountRanges, typeAddressable, typeOther, - year, + class: class_, }; } diff --git a/website/scripts/options/market.js b/website/scripts/options/market.js index cd8cd576b..d4fa09005 100644 --- a/website/scripts/options/market.js +++ b/website/scripts/options/market.js @@ -538,16 +538,6 @@ export function createMarketSection() { ...priceLines({ unit: Unit.index, numbers: [61.8, 38.2] }), ], }, - volatilityChart("Sharpe Ratio", "Sharpe Ratio", Unit.ratio, { - _1w: volatility.sharpe1w, - _1m: volatility.sharpe1m, - _1y: volatility.sharpe1y, - }), - volatilityChart("Sortino Ratio", "Sortino Ratio", Unit.ratio, { - _1w: volatility.sortino1w, - _1m: volatility.sortino1m, - _1y: volatility.sortino1y, - }), ], }, diff --git a/website/scripts/options/partial.js b/website/scripts/options/partial.js index 7cc5bb8aa..2b7d02df7 100644 --- a/website/scripts/options/partial.js +++ b/website/scripts/options/partial.js @@ -51,7 +51,7 @@ export function createPartialOptions() { addressesAmountRanges, typeAddressable, typeOther, - year, + class: class_, } = buildCohortData(); return [ @@ -263,10 +263,10 @@ export function createPartialOptions() { createGroupedCohortFolderBasicWithoutMarketCap({ name: "Compare", title: "Years", - list: year, + list: class_, all: cohortAll, }), - ...year.map(createCohortFolderBasicWithoutMarketCap), + ...class_.map(createCohortFolderBasicWithoutMarketCap), ], }, ],