mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: snapshot
This commit is contained in:
@@ -6,8 +6,8 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use brk_cohort::{
|
use brk_cohort::{
|
||||||
AGE_RANGE_NAMES, AMOUNT_RANGE_NAMES, EPOCH_NAMES, GE_AMOUNT_NAMES, LT_AMOUNT_NAMES,
|
AGE_RANGE_NAMES, AMOUNT_RANGE_NAMES, EPOCH_NAMES, OVER_AMOUNT_NAMES, UNDER_AMOUNT_NAMES,
|
||||||
MAX_AGE_NAMES, MIN_AGE_NAMES, SPENDABLE_TYPE_NAMES, TERM_NAMES, CLASS_NAMES,
|
UNDER_AGE_NAMES, OVER_AGE_NAMES, SPENDABLE_TYPE_NAMES, TERM_NAMES, CLASS_NAMES,
|
||||||
};
|
};
|
||||||
use brk_types::{Index, PoolSlug, pools};
|
use brk_types::{Index, PoolSlug, pools};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
@@ -58,11 +58,11 @@ impl CohortConstants {
|
|||||||
("CLASS_NAMES", to_value(&CLASS_NAMES)),
|
("CLASS_NAMES", to_value(&CLASS_NAMES)),
|
||||||
("SPENDABLE_TYPE_NAMES", to_value(&SPENDABLE_TYPE_NAMES)),
|
("SPENDABLE_TYPE_NAMES", to_value(&SPENDABLE_TYPE_NAMES)),
|
||||||
("AGE_RANGE_NAMES", to_value(&AGE_RANGE_NAMES)),
|
("AGE_RANGE_NAMES", to_value(&AGE_RANGE_NAMES)),
|
||||||
("MAX_AGE_NAMES", to_value(&MAX_AGE_NAMES)),
|
("UNDER_AGE_NAMES", to_value(&UNDER_AGE_NAMES)),
|
||||||
("MIN_AGE_NAMES", to_value(&MIN_AGE_NAMES)),
|
("OVER_AGE_NAMES", to_value(&OVER_AGE_NAMES)),
|
||||||
("AMOUNT_RANGE_NAMES", to_value(&AMOUNT_RANGE_NAMES)),
|
("AMOUNT_RANGE_NAMES", to_value(&AMOUNT_RANGE_NAMES)),
|
||||||
("GE_AMOUNT_NAMES", to_value(&GE_AMOUNT_NAMES)),
|
("OVER_AMOUNT_NAMES", to_value(&OVER_AMOUNT_NAMES)),
|
||||||
("LT_AMOUNT_NAMES", to_value(<_AMOUNT_NAMES)),
|
("UNDER_AMOUNT_NAMES", to_value(&UNDER_AMOUNT_NAMES)),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ fn main() -> brk_client::Result<()> {
|
|||||||
.metrics()
|
.metrics()
|
||||||
.blocks
|
.blocks
|
||||||
.count
|
.count
|
||||||
.block_count
|
.total
|
||||||
.sum
|
.sum
|
||||||
._24h
|
._24h
|
||||||
.by
|
.by
|
||||||
|
|||||||
@@ -2422,7 +2422,7 @@ pub struct OutputsRealizedSupplyUnrealizedPattern {
|
|||||||
pub outputs: UnspentPattern,
|
pub outputs: UnspentPattern,
|
||||||
pub realized: CapLossMvrvNuplPriceProfitSoprPattern,
|
pub realized: CapLossMvrvNuplPriceProfitSoprPattern,
|
||||||
pub supply: HalvedInTotalPattern,
|
pub supply: HalvedInTotalPattern,
|
||||||
pub unrealized: LossProfitPattern2,
|
pub unrealized: LossProfitPattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OutputsRealizedSupplyUnrealizedPattern {
|
impl OutputsRealizedSupplyUnrealizedPattern {
|
||||||
@@ -2432,7 +2432,7 @@ impl OutputsRealizedSupplyUnrealizedPattern {
|
|||||||
outputs: UnspentPattern::new(client.clone(), _m(&acc, "utxo_count")),
|
outputs: UnspentPattern::new(client.clone(), _m(&acc, "utxo_count")),
|
||||||
realized: CapLossMvrvNuplPriceProfitSoprPattern::new(client.clone(), acc.clone()),
|
realized: CapLossMvrvNuplPriceProfitSoprPattern::new(client.clone(), acc.clone()),
|
||||||
supply: HalvedInTotalPattern::new(client.clone(), _m(&acc, "supply")),
|
supply: HalvedInTotalPattern::new(client.clone(), _m(&acc, "supply")),
|
||||||
unrealized: LossProfitPattern2::new(client.clone(), _m(&acc, "unrealized")),
|
unrealized: LossProfitPattern::new(client.clone(), _m(&acc, "unrealized")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3024,12 +3024,12 @@ impl InPattern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Pattern struct for repeated tree structure.
|
/// Pattern struct for repeated tree structure.
|
||||||
pub struct LossProfitPattern2 {
|
pub struct LossProfitPattern {
|
||||||
pub loss: RawSumPattern2,
|
pub loss: RawSumPattern2,
|
||||||
pub profit: RawSumPattern2,
|
pub profit: RawSumPattern2,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LossProfitPattern2 {
|
impl LossProfitPattern {
|
||||||
/// Create a new pattern node with accumulated metric name.
|
/// Create a new pattern node with accumulated metric name.
|
||||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -5742,7 +5742,7 @@ impl MetricsTree_Market_Dca_Period_CostBasis {
|
|||||||
pub struct MetricsTree_Market_Dca_Class {
|
pub struct MetricsTree_Market_Dca_Class {
|
||||||
pub stack: MetricsTree_Market_Dca_Class_Stack,
|
pub stack: MetricsTree_Market_Dca_Class_Stack,
|
||||||
pub cost_basis: MetricsTree_Market_Dca_Class_CostBasis,
|
pub cost_basis: MetricsTree_Market_Dca_Class_CostBasis,
|
||||||
pub r#return: MetricsTree_Market_Dca_Class_R#return,
|
pub r#return: MetricsTree_Market_Dca_Class_Return,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetricsTree_Market_Dca_Class {
|
impl MetricsTree_Market_Dca_Class {
|
||||||
@@ -5750,7 +5750,7 @@ impl MetricsTree_Market_Dca_Class {
|
|||||||
Self {
|
Self {
|
||||||
stack: MetricsTree_Market_Dca_Class_Stack::new(client.clone(), format!("{base_path}_stack")),
|
stack: MetricsTree_Market_Dca_Class_Stack::new(client.clone(), format!("{base_path}_stack")),
|
||||||
cost_basis: MetricsTree_Market_Dca_Class_CostBasis::new(client.clone(), format!("{base_path}_cost_basis")),
|
cost_basis: MetricsTree_Market_Dca_Class_CostBasis::new(client.clone(), format!("{base_path}_cost_basis")),
|
||||||
r#return: MetricsTree_Market_Dca_Class_R#return::new(client.clone(), format!("{base_path}_r#return")),
|
r#return: MetricsTree_Market_Dca_Class_Return::new(client.clone(), format!("{base_path}_return")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5826,7 +5826,7 @@ impl MetricsTree_Market_Dca_Class_CostBasis {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Metrics tree node.
|
/// Metrics tree node.
|
||||||
pub struct MetricsTree_Market_Dca_Class_R#return {
|
pub struct MetricsTree_Market_Dca_Class_Return {
|
||||||
pub from_2015: BpsPercentRatioPattern,
|
pub from_2015: BpsPercentRatioPattern,
|
||||||
pub from_2016: BpsPercentRatioPattern,
|
pub from_2016: BpsPercentRatioPattern,
|
||||||
pub from_2017: BpsPercentRatioPattern,
|
pub from_2017: BpsPercentRatioPattern,
|
||||||
@@ -5841,7 +5841,7 @@ pub struct MetricsTree_Market_Dca_Class_R#return {
|
|||||||
pub from_2026: BpsPercentRatioPattern,
|
pub from_2026: BpsPercentRatioPattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetricsTree_Market_Dca_Class_R#return {
|
impl MetricsTree_Market_Dca_Class_Return {
|
||||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
from_2015: BpsPercentRatioPattern::new(client.clone(), "dca_return_from_2015".to_string()),
|
from_2015: BpsPercentRatioPattern::new(client.clone(), "dca_return_from_2015".to_string()),
|
||||||
@@ -6725,13 +6725,13 @@ pub struct MetricsTree_Distribution_Cohorts_Utxo {
|
|||||||
pub sth: MetricsTree_Distribution_Cohorts_Utxo_Sth,
|
pub sth: MetricsTree_Distribution_Cohorts_Utxo_Sth,
|
||||||
pub lth: MetricsTree_Distribution_Cohorts_Utxo_Lth,
|
pub lth: MetricsTree_Distribution_Cohorts_Utxo_Lth,
|
||||||
pub age_range: MetricsTree_Distribution_Cohorts_Utxo_AgeRange,
|
pub age_range: MetricsTree_Distribution_Cohorts_Utxo_AgeRange,
|
||||||
pub max_age: MetricsTree_Distribution_Cohorts_Utxo_MaxAge,
|
pub under_age: MetricsTree_Distribution_Cohorts_Utxo_UnderAge,
|
||||||
pub min_age: MetricsTree_Distribution_Cohorts_Utxo_MinAge,
|
pub over_age: MetricsTree_Distribution_Cohorts_Utxo_OverAge,
|
||||||
pub epoch: MetricsTree_Distribution_Cohorts_Utxo_Epoch,
|
pub epoch: MetricsTree_Distribution_Cohorts_Utxo_Epoch,
|
||||||
pub class: MetricsTree_Distribution_Cohorts_Utxo_Class,
|
pub class: MetricsTree_Distribution_Cohorts_Utxo_Class,
|
||||||
pub ge_amount: MetricsTree_Distribution_Cohorts_Utxo_GeAmount,
|
pub over_amount: MetricsTree_Distribution_Cohorts_Utxo_OverAmount,
|
||||||
pub amount_range: MetricsTree_Distribution_Cohorts_Utxo_AmountRange,
|
pub amount_range: MetricsTree_Distribution_Cohorts_Utxo_AmountRange,
|
||||||
pub lt_amount: MetricsTree_Distribution_Cohorts_Utxo_LtAmount,
|
pub under_amount: MetricsTree_Distribution_Cohorts_Utxo_UnderAmount,
|
||||||
pub r#type: MetricsTree_Distribution_Cohorts_Utxo_Type,
|
pub r#type: MetricsTree_Distribution_Cohorts_Utxo_Type,
|
||||||
pub profitability: MetricsTree_Distribution_Cohorts_Utxo_Profitability,
|
pub profitability: MetricsTree_Distribution_Cohorts_Utxo_Profitability,
|
||||||
pub matured: MetricsTree_Distribution_Cohorts_Utxo_Matured,
|
pub matured: MetricsTree_Distribution_Cohorts_Utxo_Matured,
|
||||||
@@ -6744,13 +6744,13 @@ impl MetricsTree_Distribution_Cohorts_Utxo {
|
|||||||
sth: MetricsTree_Distribution_Cohorts_Utxo_Sth::new(client.clone(), format!("{base_path}_sth")),
|
sth: MetricsTree_Distribution_Cohorts_Utxo_Sth::new(client.clone(), format!("{base_path}_sth")),
|
||||||
lth: MetricsTree_Distribution_Cohorts_Utxo_Lth::new(client.clone(), format!("{base_path}_lth")),
|
lth: MetricsTree_Distribution_Cohorts_Utxo_Lth::new(client.clone(), format!("{base_path}_lth")),
|
||||||
age_range: MetricsTree_Distribution_Cohorts_Utxo_AgeRange::new(client.clone(), format!("{base_path}_age_range")),
|
age_range: MetricsTree_Distribution_Cohorts_Utxo_AgeRange::new(client.clone(), format!("{base_path}_age_range")),
|
||||||
max_age: MetricsTree_Distribution_Cohorts_Utxo_MaxAge::new(client.clone(), format!("{base_path}_max_age")),
|
under_age: MetricsTree_Distribution_Cohorts_Utxo_UnderAge::new(client.clone(), format!("{base_path}_under_age")),
|
||||||
min_age: MetricsTree_Distribution_Cohorts_Utxo_MinAge::new(client.clone(), format!("{base_path}_min_age")),
|
over_age: MetricsTree_Distribution_Cohorts_Utxo_OverAge::new(client.clone(), format!("{base_path}_over_age")),
|
||||||
epoch: MetricsTree_Distribution_Cohorts_Utxo_Epoch::new(client.clone(), format!("{base_path}_epoch")),
|
epoch: MetricsTree_Distribution_Cohorts_Utxo_Epoch::new(client.clone(), format!("{base_path}_epoch")),
|
||||||
class: MetricsTree_Distribution_Cohorts_Utxo_Class::new(client.clone(), format!("{base_path}_class")),
|
class: MetricsTree_Distribution_Cohorts_Utxo_Class::new(client.clone(), format!("{base_path}_class")),
|
||||||
ge_amount: MetricsTree_Distribution_Cohorts_Utxo_GeAmount::new(client.clone(), format!("{base_path}_ge_amount")),
|
over_amount: MetricsTree_Distribution_Cohorts_Utxo_OverAmount::new(client.clone(), format!("{base_path}_over_amount")),
|
||||||
amount_range: MetricsTree_Distribution_Cohorts_Utxo_AmountRange::new(client.clone(), format!("{base_path}_amount_range")),
|
amount_range: MetricsTree_Distribution_Cohorts_Utxo_AmountRange::new(client.clone(), format!("{base_path}_amount_range")),
|
||||||
lt_amount: MetricsTree_Distribution_Cohorts_Utxo_LtAmount::new(client.clone(), format!("{base_path}_lt_amount")),
|
under_amount: MetricsTree_Distribution_Cohorts_Utxo_UnderAmount::new(client.clone(), format!("{base_path}_under_amount")),
|
||||||
r#type: MetricsTree_Distribution_Cohorts_Utxo_Type::new(client.clone(), format!("{base_path}_type")),
|
r#type: MetricsTree_Distribution_Cohorts_Utxo_Type::new(client.clone(), format!("{base_path}_type")),
|
||||||
profitability: MetricsTree_Distribution_Cohorts_Utxo_Profitability::new(client.clone(), format!("{base_path}_profitability")),
|
profitability: MetricsTree_Distribution_Cohorts_Utxo_Profitability::new(client.clone(), format!("{base_path}_profitability")),
|
||||||
matured: MetricsTree_Distribution_Cohorts_Utxo_Matured::new(client.clone(), format!("{base_path}_matured")),
|
matured: MetricsTree_Distribution_Cohorts_Utxo_Matured::new(client.clone(), format!("{base_path}_matured")),
|
||||||
@@ -7066,7 +7066,7 @@ impl MetricsTree_Distribution_Cohorts_Utxo_AgeRange {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Metrics tree node.
|
/// Metrics tree node.
|
||||||
pub struct MetricsTree_Distribution_Cohorts_Utxo_MaxAge {
|
pub struct MetricsTree_Distribution_Cohorts_Utxo_UnderAge {
|
||||||
pub _1w: ActivityOutputsRealizedSupplyUnrealizedPattern2,
|
pub _1w: ActivityOutputsRealizedSupplyUnrealizedPattern2,
|
||||||
pub _1m: ActivityOutputsRealizedSupplyUnrealizedPattern2,
|
pub _1m: ActivityOutputsRealizedSupplyUnrealizedPattern2,
|
||||||
pub _2m: ActivityOutputsRealizedSupplyUnrealizedPattern2,
|
pub _2m: ActivityOutputsRealizedSupplyUnrealizedPattern2,
|
||||||
@@ -7087,7 +7087,7 @@ pub struct MetricsTree_Distribution_Cohorts_Utxo_MaxAge {
|
|||||||
pub _15y: ActivityOutputsRealizedSupplyUnrealizedPattern2,
|
pub _15y: ActivityOutputsRealizedSupplyUnrealizedPattern2,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetricsTree_Distribution_Cohorts_Utxo_MaxAge {
|
impl MetricsTree_Distribution_Cohorts_Utxo_UnderAge {
|
||||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
_1w: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_1w_old".to_string()),
|
_1w: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_under_1w_old".to_string()),
|
||||||
@@ -7113,7 +7113,7 @@ impl MetricsTree_Distribution_Cohorts_Utxo_MaxAge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Metrics tree node.
|
/// Metrics tree node.
|
||||||
pub struct MetricsTree_Distribution_Cohorts_Utxo_MinAge {
|
pub struct MetricsTree_Distribution_Cohorts_Utxo_OverAge {
|
||||||
pub _1d: ActivityOutputsRealizedSupplyUnrealizedPattern2,
|
pub _1d: ActivityOutputsRealizedSupplyUnrealizedPattern2,
|
||||||
pub _1w: ActivityOutputsRealizedSupplyUnrealizedPattern2,
|
pub _1w: ActivityOutputsRealizedSupplyUnrealizedPattern2,
|
||||||
pub _1m: ActivityOutputsRealizedSupplyUnrealizedPattern2,
|
pub _1m: ActivityOutputsRealizedSupplyUnrealizedPattern2,
|
||||||
@@ -7134,7 +7134,7 @@ pub struct MetricsTree_Distribution_Cohorts_Utxo_MinAge {
|
|||||||
pub _12y: ActivityOutputsRealizedSupplyUnrealizedPattern2,
|
pub _12y: ActivityOutputsRealizedSupplyUnrealizedPattern2,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetricsTree_Distribution_Cohorts_Utxo_MinAge {
|
impl MetricsTree_Distribution_Cohorts_Utxo_OverAge {
|
||||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
_1d: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_1d_old".to_string()),
|
_1d: ActivityOutputsRealizedSupplyUnrealizedPattern2::new(client.clone(), "utxos_over_1d_old".to_string()),
|
||||||
@@ -7228,7 +7228,7 @@ impl MetricsTree_Distribution_Cohorts_Utxo_Class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Metrics tree node.
|
/// Metrics tree node.
|
||||||
pub struct MetricsTree_Distribution_Cohorts_Utxo_GeAmount {
|
pub struct MetricsTree_Distribution_Cohorts_Utxo_OverAmount {
|
||||||
pub _1sat: OutputsRealizedSupplyPattern,
|
pub _1sat: OutputsRealizedSupplyPattern,
|
||||||
pub _10sats: OutputsRealizedSupplyPattern,
|
pub _10sats: OutputsRealizedSupplyPattern,
|
||||||
pub _100sats: OutputsRealizedSupplyPattern,
|
pub _100sats: OutputsRealizedSupplyPattern,
|
||||||
@@ -7244,7 +7244,7 @@ pub struct MetricsTree_Distribution_Cohorts_Utxo_GeAmount {
|
|||||||
pub _10k_btc: OutputsRealizedSupplyPattern,
|
pub _10k_btc: OutputsRealizedSupplyPattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetricsTree_Distribution_Cohorts_Utxo_GeAmount {
|
impl MetricsTree_Distribution_Cohorts_Utxo_OverAmount {
|
||||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
_1sat: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_1sat".to_string()),
|
_1sat: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_over_1sat".to_string()),
|
||||||
@@ -7306,7 +7306,7 @@ impl MetricsTree_Distribution_Cohorts_Utxo_AmountRange {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Metrics tree node.
|
/// Metrics tree node.
|
||||||
pub struct MetricsTree_Distribution_Cohorts_Utxo_LtAmount {
|
pub struct MetricsTree_Distribution_Cohorts_Utxo_UnderAmount {
|
||||||
pub _10sats: OutputsRealizedSupplyPattern,
|
pub _10sats: OutputsRealizedSupplyPattern,
|
||||||
pub _100sats: OutputsRealizedSupplyPattern,
|
pub _100sats: OutputsRealizedSupplyPattern,
|
||||||
pub _1k_sats: OutputsRealizedSupplyPattern,
|
pub _1k_sats: OutputsRealizedSupplyPattern,
|
||||||
@@ -7322,7 +7322,7 @@ pub struct MetricsTree_Distribution_Cohorts_Utxo_LtAmount {
|
|||||||
pub _100k_btc: OutputsRealizedSupplyPattern,
|
pub _100k_btc: OutputsRealizedSupplyPattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetricsTree_Distribution_Cohorts_Utxo_LtAmount {
|
impl MetricsTree_Distribution_Cohorts_Utxo_UnderAmount {
|
||||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
_10sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_10sats".to_string()),
|
_10sats: OutputsRealizedSupplyPattern::new(client.clone(), "utxos_under_10sats".to_string()),
|
||||||
@@ -7394,61 +7394,61 @@ impl MetricsTree_Distribution_Cohorts_Utxo_Profitability {
|
|||||||
|
|
||||||
/// Metrics tree node.
|
/// Metrics tree node.
|
||||||
pub struct MetricsTree_Distribution_Cohorts_Utxo_Profitability_Range {
|
pub struct MetricsTree_Distribution_Cohorts_Utxo_Profitability_Range {
|
||||||
pub profit_over_1000: RealizedSupplyPattern,
|
pub over_1000pct_in_profit: RealizedSupplyPattern,
|
||||||
pub profit_500_to_1000: RealizedSupplyPattern,
|
pub _500pct_to_1000pct_in_profit: RealizedSupplyPattern,
|
||||||
pub profit_300_to_500: RealizedSupplyPattern,
|
pub _300pct_to_500pct_in_profit: RealizedSupplyPattern,
|
||||||
pub profit_200_to_300: RealizedSupplyPattern,
|
pub _200pct_to_300pct_in_profit: RealizedSupplyPattern,
|
||||||
pub profit_100_to_200: RealizedSupplyPattern,
|
pub _100pct_to_200pct_in_profit: RealizedSupplyPattern,
|
||||||
pub profit_90_to_100: RealizedSupplyPattern,
|
pub _90pct_to_100pct_in_profit: RealizedSupplyPattern,
|
||||||
pub profit_80_to_90: RealizedSupplyPattern,
|
pub _80pct_to_90pct_in_profit: RealizedSupplyPattern,
|
||||||
pub profit_70_to_80: RealizedSupplyPattern,
|
pub _70pct_to_80pct_in_profit: RealizedSupplyPattern,
|
||||||
pub profit_60_to_70: RealizedSupplyPattern,
|
pub _60pct_to_70pct_in_profit: RealizedSupplyPattern,
|
||||||
pub profit_50_to_60: RealizedSupplyPattern,
|
pub _50pct_to_60pct_in_profit: RealizedSupplyPattern,
|
||||||
pub profit_40_to_50: RealizedSupplyPattern,
|
pub _40pct_to_50pct_in_profit: RealizedSupplyPattern,
|
||||||
pub profit_30_to_40: RealizedSupplyPattern,
|
pub _30pct_to_40pct_in_profit: RealizedSupplyPattern,
|
||||||
pub profit_20_to_30: RealizedSupplyPattern,
|
pub _20pct_to_30pct_in_profit: RealizedSupplyPattern,
|
||||||
pub profit_10_to_20: RealizedSupplyPattern,
|
pub _10pct_to_20pct_in_profit: RealizedSupplyPattern,
|
||||||
pub profit_0_to_10: RealizedSupplyPattern,
|
pub _0pct_to_10pct_in_profit: RealizedSupplyPattern,
|
||||||
pub loss_0_to_10: RealizedSupplyPattern,
|
pub _0pct_to_10pct_in_loss: RealizedSupplyPattern,
|
||||||
pub loss_10_to_20: RealizedSupplyPattern,
|
pub _10pct_to_20pct_in_loss: RealizedSupplyPattern,
|
||||||
pub loss_20_to_30: RealizedSupplyPattern,
|
pub _20pct_to_30pct_in_loss: RealizedSupplyPattern,
|
||||||
pub loss_30_to_40: RealizedSupplyPattern,
|
pub _30pct_to_40pct_in_loss: RealizedSupplyPattern,
|
||||||
pub loss_40_to_50: RealizedSupplyPattern,
|
pub _40pct_to_50pct_in_loss: RealizedSupplyPattern,
|
||||||
pub loss_50_to_60: RealizedSupplyPattern,
|
pub _50pct_to_60pct_in_loss: RealizedSupplyPattern,
|
||||||
pub loss_60_to_70: RealizedSupplyPattern,
|
pub _60pct_to_70pct_in_loss: RealizedSupplyPattern,
|
||||||
pub loss_70_to_80: RealizedSupplyPattern,
|
pub _70pct_to_80pct_in_loss: RealizedSupplyPattern,
|
||||||
pub loss_80_to_90: RealizedSupplyPattern,
|
pub _80pct_to_90pct_in_loss: RealizedSupplyPattern,
|
||||||
pub loss_90_to_100: RealizedSupplyPattern,
|
pub _90pct_to_100pct_in_loss: RealizedSupplyPattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetricsTree_Distribution_Cohorts_Utxo_Profitability_Range {
|
impl MetricsTree_Distribution_Cohorts_Utxo_Profitability_Range {
|
||||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
profit_over_1000: RealizedSupplyPattern::new(client.clone(), "utxos_over_1000pct_up".to_string()),
|
over_1000pct_in_profit: RealizedSupplyPattern::new(client.clone(), "utxos_over_1000pct_in_profit".to_string()),
|
||||||
profit_500_to_1000: RealizedSupplyPattern::new(client.clone(), "utxos_500pct_to_1000pct_up".to_string()),
|
_500pct_to_1000pct_in_profit: RealizedSupplyPattern::new(client.clone(), "utxos_500pct_to_1000pct_in_profit".to_string()),
|
||||||
profit_300_to_500: RealizedSupplyPattern::new(client.clone(), "utxos_300pct_to_500pct_up".to_string()),
|
_300pct_to_500pct_in_profit: RealizedSupplyPattern::new(client.clone(), "utxos_300pct_to_500pct_in_profit".to_string()),
|
||||||
profit_200_to_300: RealizedSupplyPattern::new(client.clone(), "utxos_200pct_to_300pct_up".to_string()),
|
_200pct_to_300pct_in_profit: RealizedSupplyPattern::new(client.clone(), "utxos_200pct_to_300pct_in_profit".to_string()),
|
||||||
profit_100_to_200: RealizedSupplyPattern::new(client.clone(), "utxos_100pct_to_200pct_up".to_string()),
|
_100pct_to_200pct_in_profit: RealizedSupplyPattern::new(client.clone(), "utxos_100pct_to_200pct_in_profit".to_string()),
|
||||||
profit_90_to_100: RealizedSupplyPattern::new(client.clone(), "utxos_90pct_to_100pct_up".to_string()),
|
_90pct_to_100pct_in_profit: RealizedSupplyPattern::new(client.clone(), "utxos_90pct_to_100pct_in_profit".to_string()),
|
||||||
profit_80_to_90: RealizedSupplyPattern::new(client.clone(), "utxos_80pct_to_90pct_up".to_string()),
|
_80pct_to_90pct_in_profit: RealizedSupplyPattern::new(client.clone(), "utxos_80pct_to_90pct_in_profit".to_string()),
|
||||||
profit_70_to_80: RealizedSupplyPattern::new(client.clone(), "utxos_70pct_to_80pct_up".to_string()),
|
_70pct_to_80pct_in_profit: RealizedSupplyPattern::new(client.clone(), "utxos_70pct_to_80pct_in_profit".to_string()),
|
||||||
profit_60_to_70: RealizedSupplyPattern::new(client.clone(), "utxos_60pct_to_70pct_up".to_string()),
|
_60pct_to_70pct_in_profit: RealizedSupplyPattern::new(client.clone(), "utxos_60pct_to_70pct_in_profit".to_string()),
|
||||||
profit_50_to_60: RealizedSupplyPattern::new(client.clone(), "utxos_50pct_to_60pct_up".to_string()),
|
_50pct_to_60pct_in_profit: RealizedSupplyPattern::new(client.clone(), "utxos_50pct_to_60pct_in_profit".to_string()),
|
||||||
profit_40_to_50: RealizedSupplyPattern::new(client.clone(), "utxos_40pct_to_50pct_up".to_string()),
|
_40pct_to_50pct_in_profit: RealizedSupplyPattern::new(client.clone(), "utxos_40pct_to_50pct_in_profit".to_string()),
|
||||||
profit_30_to_40: RealizedSupplyPattern::new(client.clone(), "utxos_30pct_to_40pct_up".to_string()),
|
_30pct_to_40pct_in_profit: RealizedSupplyPattern::new(client.clone(), "utxos_30pct_to_40pct_in_profit".to_string()),
|
||||||
profit_20_to_30: RealizedSupplyPattern::new(client.clone(), "utxos_20pct_to_30pct_up".to_string()),
|
_20pct_to_30pct_in_profit: RealizedSupplyPattern::new(client.clone(), "utxos_20pct_to_30pct_in_profit".to_string()),
|
||||||
profit_10_to_20: RealizedSupplyPattern::new(client.clone(), "utxos_10pct_to_20pct_up".to_string()),
|
_10pct_to_20pct_in_profit: RealizedSupplyPattern::new(client.clone(), "utxos_10pct_to_20pct_in_profit".to_string()),
|
||||||
profit_0_to_10: RealizedSupplyPattern::new(client.clone(), "utxos_0pct_to_10pct_up".to_string()),
|
_0pct_to_10pct_in_profit: RealizedSupplyPattern::new(client.clone(), "utxos_0pct_to_10pct_in_profit".to_string()),
|
||||||
loss_0_to_10: RealizedSupplyPattern::new(client.clone(), "utxos_0pct_to_10pct_down".to_string()),
|
_0pct_to_10pct_in_loss: RealizedSupplyPattern::new(client.clone(), "utxos_0pct_to_10pct_in_loss".to_string()),
|
||||||
loss_10_to_20: RealizedSupplyPattern::new(client.clone(), "utxos_10pct_to_20pct_down".to_string()),
|
_10pct_to_20pct_in_loss: RealizedSupplyPattern::new(client.clone(), "utxos_10pct_to_20pct_in_loss".to_string()),
|
||||||
loss_20_to_30: RealizedSupplyPattern::new(client.clone(), "utxos_20pct_to_30pct_down".to_string()),
|
_20pct_to_30pct_in_loss: RealizedSupplyPattern::new(client.clone(), "utxos_20pct_to_30pct_in_loss".to_string()),
|
||||||
loss_30_to_40: RealizedSupplyPattern::new(client.clone(), "utxos_30pct_to_40pct_down".to_string()),
|
_30pct_to_40pct_in_loss: RealizedSupplyPattern::new(client.clone(), "utxos_30pct_to_40pct_in_loss".to_string()),
|
||||||
loss_40_to_50: RealizedSupplyPattern::new(client.clone(), "utxos_40pct_to_50pct_down".to_string()),
|
_40pct_to_50pct_in_loss: RealizedSupplyPattern::new(client.clone(), "utxos_40pct_to_50pct_in_loss".to_string()),
|
||||||
loss_50_to_60: RealizedSupplyPattern::new(client.clone(), "utxos_50pct_to_60pct_down".to_string()),
|
_50pct_to_60pct_in_loss: RealizedSupplyPattern::new(client.clone(), "utxos_50pct_to_60pct_in_loss".to_string()),
|
||||||
loss_60_to_70: RealizedSupplyPattern::new(client.clone(), "utxos_60pct_to_70pct_down".to_string()),
|
_60pct_to_70pct_in_loss: RealizedSupplyPattern::new(client.clone(), "utxos_60pct_to_70pct_in_loss".to_string()),
|
||||||
loss_70_to_80: RealizedSupplyPattern::new(client.clone(), "utxos_70pct_to_80pct_down".to_string()),
|
_70pct_to_80pct_in_loss: RealizedSupplyPattern::new(client.clone(), "utxos_70pct_to_80pct_in_loss".to_string()),
|
||||||
loss_80_to_90: RealizedSupplyPattern::new(client.clone(), "utxos_80pct_to_90pct_down".to_string()),
|
_80pct_to_90pct_in_loss: RealizedSupplyPattern::new(client.clone(), "utxos_80pct_to_90pct_in_loss".to_string()),
|
||||||
loss_90_to_100: RealizedSupplyPattern::new(client.clone(), "utxos_90pct_to_100pct_down".to_string()),
|
_90pct_to_100pct_in_loss: RealizedSupplyPattern::new(client.clone(), "utxos_90pct_to_100pct_in_loss".to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7469,27 +7469,25 @@ pub struct MetricsTree_Distribution_Cohorts_Utxo_Profitability_Profit {
|
|||||||
pub _200pct: RealizedSupplyPattern,
|
pub _200pct: RealizedSupplyPattern,
|
||||||
pub _300pct: RealizedSupplyPattern,
|
pub _300pct: RealizedSupplyPattern,
|
||||||
pub _500pct: RealizedSupplyPattern,
|
pub _500pct: RealizedSupplyPattern,
|
||||||
pub _1000pct: RealizedSupplyPattern,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetricsTree_Distribution_Cohorts_Utxo_Profitability_Profit {
|
impl MetricsTree_Distribution_Cohorts_Utxo_Profitability_Profit {
|
||||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
breakeven: RealizedSupplyPattern::new(client.clone(), "profit_ge_breakeven".to_string()),
|
breakeven: RealizedSupplyPattern::new(client.clone(), "utxos_in_profit".to_string()),
|
||||||
_10pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_10pct".to_string()),
|
_10pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_10pct_in_profit".to_string()),
|
||||||
_20pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_20pct".to_string()),
|
_20pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_20pct_in_profit".to_string()),
|
||||||
_30pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_30pct".to_string()),
|
_30pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_30pct_in_profit".to_string()),
|
||||||
_40pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_40pct".to_string()),
|
_40pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_40pct_in_profit".to_string()),
|
||||||
_50pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_50pct".to_string()),
|
_50pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_50pct_in_profit".to_string()),
|
||||||
_60pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_60pct".to_string()),
|
_60pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_60pct_in_profit".to_string()),
|
||||||
_70pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_70pct".to_string()),
|
_70pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_70pct_in_profit".to_string()),
|
||||||
_80pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_80pct".to_string()),
|
_80pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_80pct_in_profit".to_string()),
|
||||||
_90pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_90pct".to_string()),
|
_90pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_90pct_in_profit".to_string()),
|
||||||
_100pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_100pct".to_string()),
|
_100pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_100pct_in_profit".to_string()),
|
||||||
_200pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_200pct".to_string()),
|
_200pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_200pct_in_profit".to_string()),
|
||||||
_300pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_300pct".to_string()),
|
_300pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_300pct_in_profit".to_string()),
|
||||||
_500pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_500pct".to_string()),
|
_500pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_500pct_in_profit".to_string()),
|
||||||
_1000pct: RealizedSupplyPattern::new(client.clone(), "profit_ge_1000pct".to_string()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7505,22 +7503,20 @@ pub struct MetricsTree_Distribution_Cohorts_Utxo_Profitability_Loss {
|
|||||||
pub _60pct: RealizedSupplyPattern,
|
pub _60pct: RealizedSupplyPattern,
|
||||||
pub _70pct: RealizedSupplyPattern,
|
pub _70pct: RealizedSupplyPattern,
|
||||||
pub _80pct: RealizedSupplyPattern,
|
pub _80pct: RealizedSupplyPattern,
|
||||||
pub _90pct: RealizedSupplyPattern,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetricsTree_Distribution_Cohorts_Utxo_Profitability_Loss {
|
impl MetricsTree_Distribution_Cohorts_Utxo_Profitability_Loss {
|
||||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
breakeven: RealizedSupplyPattern::new(client.clone(), "loss_ge_breakeven".to_string()),
|
breakeven: RealizedSupplyPattern::new(client.clone(), "utxos_in_loss".to_string()),
|
||||||
_10pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_10pct".to_string()),
|
_10pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_10pct_in_loss".to_string()),
|
||||||
_20pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_20pct".to_string()),
|
_20pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_20pct_in_loss".to_string()),
|
||||||
_30pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_30pct".to_string()),
|
_30pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_30pct_in_loss".to_string()),
|
||||||
_40pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_40pct".to_string()),
|
_40pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_40pct_in_loss".to_string()),
|
||||||
_50pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_50pct".to_string()),
|
_50pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_50pct_in_loss".to_string()),
|
||||||
_60pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_60pct".to_string()),
|
_60pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_60pct_in_loss".to_string()),
|
||||||
_70pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_70pct".to_string()),
|
_70pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_70pct_in_loss".to_string()),
|
||||||
_80pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_80pct".to_string()),
|
_80pct: RealizedSupplyPattern::new(client.clone(), "utxos_over_80pct_in_loss".to_string()),
|
||||||
_90pct: RealizedSupplyPattern::new(client.clone(), "loss_ge_90pct".to_string()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7580,23 +7576,23 @@ impl MetricsTree_Distribution_Cohorts_Utxo_Matured {
|
|||||||
|
|
||||||
/// Metrics tree node.
|
/// Metrics tree node.
|
||||||
pub struct MetricsTree_Distribution_Cohorts_Address {
|
pub struct MetricsTree_Distribution_Cohorts_Address {
|
||||||
pub ge_amount: MetricsTree_Distribution_Cohorts_Address_GeAmount,
|
pub over_amount: MetricsTree_Distribution_Cohorts_Address_OverAmount,
|
||||||
pub amount_range: MetricsTree_Distribution_Cohorts_Address_AmountRange,
|
pub amount_range: MetricsTree_Distribution_Cohorts_Address_AmountRange,
|
||||||
pub lt_amount: MetricsTree_Distribution_Cohorts_Address_LtAmount,
|
pub under_amount: MetricsTree_Distribution_Cohorts_Address_UnderAmount,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetricsTree_Distribution_Cohorts_Address {
|
impl MetricsTree_Distribution_Cohorts_Address {
|
||||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ge_amount: MetricsTree_Distribution_Cohorts_Address_GeAmount::new(client.clone(), format!("{base_path}_ge_amount")),
|
over_amount: MetricsTree_Distribution_Cohorts_Address_OverAmount::new(client.clone(), format!("{base_path}_over_amount")),
|
||||||
amount_range: MetricsTree_Distribution_Cohorts_Address_AmountRange::new(client.clone(), format!("{base_path}_amount_range")),
|
amount_range: MetricsTree_Distribution_Cohorts_Address_AmountRange::new(client.clone(), format!("{base_path}_amount_range")),
|
||||||
lt_amount: MetricsTree_Distribution_Cohorts_Address_LtAmount::new(client.clone(), format!("{base_path}_lt_amount")),
|
under_amount: MetricsTree_Distribution_Cohorts_Address_UnderAmount::new(client.clone(), format!("{base_path}_under_amount")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Metrics tree node.
|
/// Metrics tree node.
|
||||||
pub struct MetricsTree_Distribution_Cohorts_Address_GeAmount {
|
pub struct MetricsTree_Distribution_Cohorts_Address_OverAmount {
|
||||||
pub _1sat: AddrOutputsRealizedSupplyPattern,
|
pub _1sat: AddrOutputsRealizedSupplyPattern,
|
||||||
pub _10sats: AddrOutputsRealizedSupplyPattern,
|
pub _10sats: AddrOutputsRealizedSupplyPattern,
|
||||||
pub _100sats: AddrOutputsRealizedSupplyPattern,
|
pub _100sats: AddrOutputsRealizedSupplyPattern,
|
||||||
@@ -7612,7 +7608,7 @@ pub struct MetricsTree_Distribution_Cohorts_Address_GeAmount {
|
|||||||
pub _10k_btc: AddrOutputsRealizedSupplyPattern,
|
pub _10k_btc: AddrOutputsRealizedSupplyPattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetricsTree_Distribution_Cohorts_Address_GeAmount {
|
impl MetricsTree_Distribution_Cohorts_Address_OverAmount {
|
||||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
_1sat: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_1sat".to_string()),
|
_1sat: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_over_1sat".to_string()),
|
||||||
@@ -7674,7 +7670,7 @@ impl MetricsTree_Distribution_Cohorts_Address_AmountRange {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Metrics tree node.
|
/// Metrics tree node.
|
||||||
pub struct MetricsTree_Distribution_Cohorts_Address_LtAmount {
|
pub struct MetricsTree_Distribution_Cohorts_Address_UnderAmount {
|
||||||
pub _10sats: AddrOutputsRealizedSupplyPattern,
|
pub _10sats: AddrOutputsRealizedSupplyPattern,
|
||||||
pub _100sats: AddrOutputsRealizedSupplyPattern,
|
pub _100sats: AddrOutputsRealizedSupplyPattern,
|
||||||
pub _1k_sats: AddrOutputsRealizedSupplyPattern,
|
pub _1k_sats: AddrOutputsRealizedSupplyPattern,
|
||||||
@@ -7690,7 +7686,7 @@ pub struct MetricsTree_Distribution_Cohorts_Address_LtAmount {
|
|||||||
pub _100k_btc: AddrOutputsRealizedSupplyPattern,
|
pub _100k_btc: AddrOutputsRealizedSupplyPattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetricsTree_Distribution_Cohorts_Address_LtAmount {
|
impl MetricsTree_Distribution_Cohorts_Address_UnderAmount {
|
||||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
_10sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_10sats".to_string()),
|
_10sats: AddrOutputsRealizedSupplyPattern::new(client.clone(), "addrs_under_10sats".to_string()),
|
||||||
@@ -8106,6 +8102,24 @@ impl BrkClient {
|
|||||||
self.base.get_json(&format!("/api/metric/{metric}/{}/latest", index.name()))
|
self.base.get_json(&format!("/api/metric/{metric}/{}/latest", index.name()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get metric data length
|
||||||
|
///
|
||||||
|
/// Returns the total number of data points for a metric at the given index.
|
||||||
|
///
|
||||||
|
/// Endpoint: `GET /api/metric/{metric}/{index}/len`
|
||||||
|
pub fn get_metric_len(&self, metric: Metric, index: Index) -> Result<f64> {
|
||||||
|
self.base.get_json(&format!("/api/metric/{metric}/{}/len", index.name()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get metric version
|
||||||
|
///
|
||||||
|
/// Returns the current version of a metric. Changes when the metric data is updated.
|
||||||
|
///
|
||||||
|
/// Endpoint: `GET /api/metric/{metric}/{index}/version`
|
||||||
|
pub fn get_metric_version(&self, metric: Metric, index: Index) -> Result<Version> {
|
||||||
|
self.base.get_json(&format!("/api/metric/{metric}/{}/version", index.name()))
|
||||||
|
}
|
||||||
|
|
||||||
/// Metrics catalog
|
/// Metrics catalog
|
||||||
///
|
///
|
||||||
/// Returns the complete hierarchical catalog of available metrics organized as a tree structure. Metrics are grouped by categories and subcategories.
|
/// Returns the complete hierarchical catalog of available metrics organized as a tree structure. Metrics are grouped by categories and subcategories.
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ use rayon::prelude::*;
|
|||||||
|
|
||||||
use crate::Filter;
|
use crate::Filter;
|
||||||
|
|
||||||
use super::{ByAmountRange, ByGreatEqualAmount, ByLowerThanAmount};
|
use super::{AmountRange, OverAmount, UnderAmount};
|
||||||
|
|
||||||
#[derive(Default, Clone, Traversable)]
|
#[derive(Default, Clone, Traversable)]
|
||||||
pub struct AddressGroups<T> {
|
pub struct AddressGroups<T> {
|
||||||
pub ge_amount: ByGreatEqualAmount<T>,
|
pub over_amount: OverAmount<T>,
|
||||||
pub amount_range: ByAmountRange<T>,
|
pub amount_range: AmountRange<T>,
|
||||||
pub lt_amount: ByLowerThanAmount<T>,
|
pub under_amount: UnderAmount<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> AddressGroups<T> {
|
impl<T> AddressGroups<T> {
|
||||||
@@ -18,9 +18,9 @@ impl<T> AddressGroups<T> {
|
|||||||
F: FnMut(Filter, &'static str) -> T,
|
F: FnMut(Filter, &'static str) -> T,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
ge_amount: ByGreatEqualAmount::new(&mut create),
|
over_amount: OverAmount::new(&mut create),
|
||||||
amount_range: ByAmountRange::new(&mut create),
|
amount_range: AmountRange::new(&mut create),
|
||||||
lt_amount: ByLowerThanAmount::new(&mut create),
|
under_amount: UnderAmount::new(&mut create),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,34 +29,34 @@ impl<T> AddressGroups<T> {
|
|||||||
F: Fn(Filter, &'static str) -> Result<T, E>,
|
F: Fn(Filter, &'static str) -> Result<T, E>,
|
||||||
{
|
{
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
ge_amount: ByGreatEqualAmount::try_new(create)?,
|
over_amount: OverAmount::try_new(create)?,
|
||||||
amount_range: ByAmountRange::try_new(create)?,
|
amount_range: AmountRange::try_new(create)?,
|
||||||
lt_amount: ByLowerThanAmount::try_new(create)?,
|
under_amount: UnderAmount::try_new(create)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> impl Iterator<Item = &T> {
|
pub fn iter(&self) -> impl Iterator<Item = &T> {
|
||||||
self.ge_amount
|
self.over_amount
|
||||||
.iter()
|
.iter()
|
||||||
.chain(self.amount_range.iter())
|
.chain(self.amount_range.iter())
|
||||||
.chain(self.lt_amount.iter())
|
.chain(self.under_amount.iter())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
|
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
|
||||||
self.ge_amount
|
self.over_amount
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.chain(self.amount_range.iter_mut())
|
.chain(self.amount_range.iter_mut())
|
||||||
.chain(self.lt_amount.iter_mut())
|
.chain(self.under_amount.iter_mut())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn par_iter_mut(&mut self) -> impl ParallelIterator<Item = &mut T>
|
pub fn par_iter_mut(&mut self) -> impl ParallelIterator<Item = &mut T>
|
||||||
where
|
where
|
||||||
T: Send + Sync,
|
T: Send + Sync,
|
||||||
{
|
{
|
||||||
self.ge_amount
|
self.over_amount
|
||||||
.par_iter_mut()
|
.par_iter_mut()
|
||||||
.chain(self.amount_range.par_iter_mut())
|
.chain(self.amount_range.par_iter_mut())
|
||||||
.chain(self.lt_amount.par_iter_mut())
|
.chain(self.under_amount.par_iter_mut())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_separate(&self) -> impl Iterator<Item = &T> {
|
pub fn iter_separate(&self) -> impl Iterator<Item = &T> {
|
||||||
@@ -75,7 +75,7 @@ impl<T> AddressGroups<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_overlapping_mut(&mut self) -> impl Iterator<Item = &mut T> {
|
pub fn iter_overlapping_mut(&mut self) -> impl Iterator<Item = &mut T> {
|
||||||
self.lt_amount.iter_mut().chain(self.ge_amount.iter_mut())
|
self.under_amount.iter_mut().chain(self.over_amount.iter_mut())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ pub const AGE_BOUNDARIES: [usize; 20] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
/// Age range bounds (end = usize::MAX means unbounded)
|
/// Age range bounds (end = usize::MAX means unbounded)
|
||||||
pub const AGE_RANGE_BOUNDS: ByAgeRange<Range<usize>> = ByAgeRange {
|
pub const AGE_RANGE_BOUNDS: AgeRange<Range<usize>> = AgeRange {
|
||||||
up_to_1h: 0..HOURS_1H,
|
up_to_1h: 0..HOURS_1H,
|
||||||
_1h_to_1d: HOURS_1H..HOURS_1D,
|
_1h_to_1d: HOURS_1H..HOURS_1D,
|
||||||
_1d_to_1w: HOURS_1D..HOURS_1W,
|
_1d_to_1w: HOURS_1D..HOURS_1W,
|
||||||
@@ -63,7 +63,7 @@ pub const AGE_RANGE_BOUNDS: ByAgeRange<Range<usize>> = ByAgeRange {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Age range filters
|
/// Age range filters
|
||||||
pub const AGE_RANGE_FILTERS: ByAgeRange<Filter> = ByAgeRange {
|
pub const AGE_RANGE_FILTERS: AgeRange<Filter> = AgeRange {
|
||||||
up_to_1h: Filter::Time(TimeFilter::Range(AGE_RANGE_BOUNDS.up_to_1h)),
|
up_to_1h: Filter::Time(TimeFilter::Range(AGE_RANGE_BOUNDS.up_to_1h)),
|
||||||
_1h_to_1d: Filter::Time(TimeFilter::Range(AGE_RANGE_BOUNDS._1h_to_1d)),
|
_1h_to_1d: Filter::Time(TimeFilter::Range(AGE_RANGE_BOUNDS._1h_to_1d)),
|
||||||
_1d_to_1w: Filter::Time(TimeFilter::Range(AGE_RANGE_BOUNDS._1d_to_1w)),
|
_1d_to_1w: Filter::Time(TimeFilter::Range(AGE_RANGE_BOUNDS._1d_to_1w)),
|
||||||
@@ -88,7 +88,7 @@ pub const AGE_RANGE_FILTERS: ByAgeRange<Filter> = ByAgeRange {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Age range names
|
/// Age range names
|
||||||
pub const AGE_RANGE_NAMES: ByAgeRange<CohortName> = ByAgeRange {
|
pub const AGE_RANGE_NAMES: AgeRange<CohortName> = AgeRange {
|
||||||
up_to_1h: CohortName::new("under_1h_old", "<1h", "Under 1 Hour Old"),
|
up_to_1h: CohortName::new("under_1h_old", "<1h", "Under 1 Hour Old"),
|
||||||
_1h_to_1d: CohortName::new("1h_to_1d_old", "1h-1d", "1 Hour to 1 Day Old"),
|
_1h_to_1d: CohortName::new("1h_to_1d_old", "1h-1d", "1 Hour to 1 Day Old"),
|
||||||
_1d_to_1w: CohortName::new("1d_to_1w_old", "1d-1w", "1 Day to 1 Week Old"),
|
_1d_to_1w: CohortName::new("1d_to_1w_old", "1d-1w", "1 Day to 1 Week Old"),
|
||||||
@@ -112,14 +112,14 @@ pub const AGE_RANGE_NAMES: ByAgeRange<CohortName> = ByAgeRange {
|
|||||||
from_15y: CohortName::new("over_15y_old", "15y+", "15+ Years Old"),
|
from_15y: CohortName::new("over_15y_old", "15y+", "15+ Years Old"),
|
||||||
};
|
};
|
||||||
|
|
||||||
impl ByAgeRange<CohortName> {
|
impl AgeRange<CohortName> {
|
||||||
pub const fn names() -> &'static Self {
|
pub const fn names() -> &'static Self {
|
||||||
&AGE_RANGE_NAMES
|
&AGE_RANGE_NAMES
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone, Traversable, Serialize)]
|
#[derive(Default, Clone, Traversable, Serialize)]
|
||||||
pub struct ByAgeRange<T> {
|
pub struct AgeRange<T> {
|
||||||
pub up_to_1h: T,
|
pub up_to_1h: T,
|
||||||
pub _1h_to_1d: T,
|
pub _1h_to_1d: T,
|
||||||
pub _1d_to_1w: T,
|
pub _1d_to_1w: T,
|
||||||
@@ -143,7 +143,7 @@ pub struct ByAgeRange<T> {
|
|||||||
pub from_15y: T,
|
pub from_15y: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ByAgeRange<T> {
|
impl<T> AgeRange<T> {
|
||||||
/// Get mutable reference by Age. O(1).
|
/// Get mutable reference by Age. O(1).
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_mut(&mut self, age: Age) -> &mut T {
|
pub fn get_mut(&mut self, age: Age) -> &mut T {
|
||||||
@@ -13,7 +13,7 @@ pub struct AmountBucket(u8);
|
|||||||
|
|
||||||
impl AmountBucket {
|
impl AmountBucket {
|
||||||
/// Returns (self, other) if buckets differ, None if same.
|
/// Returns (self, other) if buckets differ, None if same.
|
||||||
/// Use with `ByAmountRange::get_mut_by_bucket` to avoid recomputing.
|
/// Use with `AmountRange::get_mut_by_bucket` to avoid recomputing.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn transition_to(self, other: Self) -> Option<(Self, Self)> {
|
pub fn transition_to(self, other: Self) -> Option<(Self, Self)> {
|
||||||
if self != other {
|
if self != other {
|
||||||
@@ -59,7 +59,7 @@ pub fn amounts_in_different_buckets(a: Sats, b: Sats) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Amount range bounds
|
/// Amount range bounds
|
||||||
pub const AMOUNT_RANGE_BOUNDS: ByAmountRange<Range<Sats>> = ByAmountRange {
|
pub const AMOUNT_RANGE_BOUNDS: AmountRange<Range<Sats>> = AmountRange {
|
||||||
_0sats: Sats::ZERO..Sats::_1,
|
_0sats: Sats::ZERO..Sats::_1,
|
||||||
_1sat_to_10sats: Sats::_1..Sats::_10,
|
_1sat_to_10sats: Sats::_1..Sats::_10,
|
||||||
_10sats_to_100sats: Sats::_10..Sats::_100,
|
_10sats_to_100sats: Sats::_10..Sats::_100,
|
||||||
@@ -78,7 +78,7 @@ pub const AMOUNT_RANGE_BOUNDS: ByAmountRange<Range<Sats>> = ByAmountRange {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Amount range names
|
/// Amount range names
|
||||||
pub const AMOUNT_RANGE_NAMES: ByAmountRange<CohortName> = ByAmountRange {
|
pub const AMOUNT_RANGE_NAMES: AmountRange<CohortName> = AmountRange {
|
||||||
_0sats: CohortName::new("with_0sats", "0 sats", "0 Sats"),
|
_0sats: CohortName::new("with_0sats", "0 sats", "0 Sats"),
|
||||||
_1sat_to_10sats: CohortName::new("above_1sat_under_10sats", "1-10 sats", "1-10 Sats"),
|
_1sat_to_10sats: CohortName::new("above_1sat_under_10sats", "1-10 sats", "1-10 Sats"),
|
||||||
_10sats_to_100sats: CohortName::new("above_10sats_under_100sats", "10-100 sats", "10-100 Sats"),
|
_10sats_to_100sats: CohortName::new("above_10sats_under_100sats", "10-100 sats", "10-100 Sats"),
|
||||||
@@ -121,7 +121,7 @@ pub const AMOUNT_RANGE_NAMES: ByAmountRange<CohortName> = ByAmountRange {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Amount range filters
|
/// Amount range filters
|
||||||
pub const AMOUNT_RANGE_FILTERS: ByAmountRange<Filter> = ByAmountRange {
|
pub const AMOUNT_RANGE_FILTERS: AmountRange<Filter> = AmountRange {
|
||||||
_0sats: Filter::Amount(AmountFilter::Range(AMOUNT_RANGE_BOUNDS._0sats)),
|
_0sats: Filter::Amount(AmountFilter::Range(AMOUNT_RANGE_BOUNDS._0sats)),
|
||||||
_1sat_to_10sats: Filter::Amount(AmountFilter::Range(AMOUNT_RANGE_BOUNDS._1sat_to_10sats)),
|
_1sat_to_10sats: Filter::Amount(AmountFilter::Range(AMOUNT_RANGE_BOUNDS._1sat_to_10sats)),
|
||||||
_10sats_to_100sats: Filter::Amount(AmountFilter::Range(AMOUNT_RANGE_BOUNDS._10sats_to_100sats)),
|
_10sats_to_100sats: Filter::Amount(AmountFilter::Range(AMOUNT_RANGE_BOUNDS._10sats_to_100sats)),
|
||||||
@@ -152,7 +152,7 @@ pub const AMOUNT_RANGE_FILTERS: ByAmountRange<Filter> = ByAmountRange {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Traversable, Serialize)]
|
#[derive(Debug, Default, Clone, Traversable, Serialize)]
|
||||||
pub struct ByAmountRange<T> {
|
pub struct AmountRange<T> {
|
||||||
pub _0sats: T,
|
pub _0sats: T,
|
||||||
pub _1sat_to_10sats: T,
|
pub _1sat_to_10sats: T,
|
||||||
pub _10sats_to_100sats: T,
|
pub _10sats_to_100sats: T,
|
||||||
@@ -170,13 +170,13 @@ pub struct ByAmountRange<T> {
|
|||||||
pub _100k_btc_or_more: T,
|
pub _100k_btc_or_more: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ByAmountRange<CohortName> {
|
impl AmountRange<CohortName> {
|
||||||
pub const fn names() -> &'static Self {
|
pub const fn names() -> &'static Self {
|
||||||
&AMOUNT_RANGE_NAMES
|
&AMOUNT_RANGE_NAMES
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ByAmountRange<T> {
|
impl<T> AmountRange<T> {
|
||||||
pub fn new<F>(mut create: F) -> Self
|
pub fn new<F>(mut create: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnMut(Filter, &'static str) -> T,
|
F: FnMut(Filter, &'static str) -> T,
|
||||||
@@ -385,7 +385,7 @@ impl<T> ByAmountRange<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Add for ByAmountRange<T>
|
impl<T> Add for AmountRange<T>
|
||||||
where
|
where
|
||||||
T: Add<Output = T>,
|
T: Add<Output = T>,
|
||||||
{
|
{
|
||||||
@@ -411,7 +411,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> AddAssign for ByAmountRange<T>
|
impl<T> AddAssign for AmountRange<T>
|
||||||
where
|
where
|
||||||
T: AddAssign,
|
T: AddAssign,
|
||||||
{
|
{
|
||||||
@@ -2,15 +2,15 @@ use std::ops::{Add, AddAssign};
|
|||||||
|
|
||||||
use brk_types::OutputType;
|
use brk_types::OutputType;
|
||||||
|
|
||||||
use super::{BySpendableType, ByUnspendableType};
|
use super::{SpendableType, UnspendableType};
|
||||||
|
|
||||||
#[derive(Default, Clone, Debug)]
|
#[derive(Default, Clone, Debug)]
|
||||||
pub struct GroupedByType<T> {
|
pub struct ByType<T> {
|
||||||
pub spendable: BySpendableType<T>,
|
pub spendable: SpendableType<T>,
|
||||||
pub unspendable: ByUnspendableType<T>,
|
pub unspendable: UnspendableType<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> GroupedByType<T> {
|
impl<T> ByType<T> {
|
||||||
pub fn get(&self, output_type: OutputType) -> &T {
|
pub fn get(&self, output_type: OutputType) -> &T {
|
||||||
match output_type {
|
match output_type {
|
||||||
OutputType::P2PK65 => &self.spendable.p2pk65,
|
OutputType::P2PK65 => &self.spendable.p2pk65,
|
||||||
@@ -46,7 +46,7 @@ impl<T> GroupedByType<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Add for GroupedByType<T>
|
impl<T> Add for ByType<T>
|
||||||
where
|
where
|
||||||
T: Add<Output = T>,
|
T: Add<Output = T>,
|
||||||
{
|
{
|
||||||
@@ -59,7 +59,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> AddAssign for GroupedByType<T>
|
impl<T> AddAssign for ByType<T>
|
||||||
where
|
where
|
||||||
T: AddAssign,
|
T: AddAssign,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
#[derive(Default, Clone)]
|
|
||||||
pub struct GroupedByValue<T> {
|
|
||||||
pub up_to_1cent: T,
|
|
||||||
pub from_1c_to_10c: T,
|
|
||||||
pub from_10c_to_1d: T,
|
|
||||||
pub from_1d_to_10d: T,
|
|
||||||
pub from_10usd_to_100usd: T,
|
|
||||||
pub from_100usd_to_1_000usd: T,
|
|
||||||
pub from_1_000usd_to_10_000usd: T,
|
|
||||||
pub from_10_000usd_to_100_000usd: T,
|
|
||||||
pub from_100_000usd_to_1_000_000usd: T,
|
|
||||||
pub from_1_000_000usd_to_10_000_000usd: T,
|
|
||||||
pub from_10_000_000usd_to_100_000_000usd: T,
|
|
||||||
pub from_100_000_000usd_to_1_000_000_000usd: T,
|
|
||||||
pub from_1_000_000_000usd: T,
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> GroupedByValue<T> {
|
|
||||||
pub fn as_mut_vec(&mut self) -> Vec<&mut T> {
|
|
||||||
vec![
|
|
||||||
&mut self.up_to_1cent,
|
|
||||||
&mut self.from_1c_to_10c,
|
|
||||||
&mut self.from_10c_to_1d,
|
|
||||||
&mut self.from_1d_to_10d,
|
|
||||||
&mut self.from_10usd_to_100usd,
|
|
||||||
&mut self.from_100usd_to_1_000usd,
|
|
||||||
&mut self.from_1_000usd_to_10_000usd,
|
|
||||||
&mut self.from_10_000usd_to_100_000usd,
|
|
||||||
&mut self.from_100_000usd_to_1_000_000usd,
|
|
||||||
&mut self.from_1_000_000usd_to_10_000_000usd,
|
|
||||||
&mut self.from_10_000_000usd_to_100_000_000usd,
|
|
||||||
&mut self.from_100_000_000usd_to_1_000_000_000usd,
|
|
||||||
&mut self.from_1_000_000_000usd,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,7 @@ use serde::Serialize;
|
|||||||
use super::{CohortName, Filter};
|
use super::{CohortName, Filter};
|
||||||
|
|
||||||
/// Class values
|
/// Class values
|
||||||
pub const CLASS_VALUES: ByClass<Year> = ByClass {
|
pub const CLASS_VALUES: Class<Year> = Class {
|
||||||
_2009: Year::new(2009),
|
_2009: Year::new(2009),
|
||||||
_2010: Year::new(2010),
|
_2010: Year::new(2010),
|
||||||
_2011: Year::new(2011),
|
_2011: Year::new(2011),
|
||||||
@@ -28,7 +28,7 @@ pub const CLASS_VALUES: ByClass<Year> = ByClass {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Class filters
|
/// Class filters
|
||||||
pub const CLASS_FILTERS: ByClass<Filter> = ByClass {
|
pub const CLASS_FILTERS: Class<Filter> = Class {
|
||||||
_2009: Filter::Class(CLASS_VALUES._2009),
|
_2009: Filter::Class(CLASS_VALUES._2009),
|
||||||
_2010: Filter::Class(CLASS_VALUES._2010),
|
_2010: Filter::Class(CLASS_VALUES._2010),
|
||||||
_2011: Filter::Class(CLASS_VALUES._2011),
|
_2011: Filter::Class(CLASS_VALUES._2011),
|
||||||
@@ -50,7 +50,7 @@ pub const CLASS_FILTERS: ByClass<Filter> = ByClass {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Class names
|
/// Class names
|
||||||
pub const CLASS_NAMES: ByClass<CohortName> = ByClass {
|
pub const CLASS_NAMES: Class<CohortName> = Class {
|
||||||
_2009: CohortName::new("class_2009", "2009", "Class 2009"),
|
_2009: CohortName::new("class_2009", "2009", "Class 2009"),
|
||||||
_2010: CohortName::new("class_2010", "2010", "Class 2010"),
|
_2010: CohortName::new("class_2010", "2010", "Class 2010"),
|
||||||
_2011: CohortName::new("class_2011", "2011", "Class 2011"),
|
_2011: CohortName::new("class_2011", "2011", "Class 2011"),
|
||||||
@@ -72,7 +72,7 @@ pub const CLASS_NAMES: ByClass<CohortName> = ByClass {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default, Clone, Traversable, Serialize)]
|
#[derive(Default, Clone, Traversable, Serialize)]
|
||||||
pub struct ByClass<T> {
|
pub struct Class<T> {
|
||||||
pub _2009: T,
|
pub _2009: T,
|
||||||
pub _2010: T,
|
pub _2010: T,
|
||||||
pub _2011: T,
|
pub _2011: T,
|
||||||
@@ -93,13 +93,13 @@ pub struct ByClass<T> {
|
|||||||
pub _2026: T,
|
pub _2026: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ByClass<CohortName> {
|
impl Class<CohortName> {
|
||||||
pub const fn names() -> &'static Self {
|
pub const fn names() -> &'static Self {
|
||||||
&CLASS_NAMES
|
&CLASS_NAMES
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ByClass<T> {
|
impl<T> Class<T> {
|
||||||
pub fn new<F>(mut create: F) -> Self
|
pub fn new<F>(mut create: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnMut(Filter, &'static str) -> T,
|
F: FnMut(Filter, &'static str) -> T,
|
||||||
@@ -89,7 +89,7 @@ impl Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Whether to compute adjusted metrics (adjusted SOPR, adjusted value created/destroyed)
|
/// Whether to compute adjusted metrics (adjusted SOPR, adjusted value created/destroyed)
|
||||||
/// For UTXO context: true for All, STH, and max_age (LowerThan)
|
/// For UTXO context: true for All, STH, and under_age (LowerThan)
|
||||||
/// For Address context: always false
|
/// For Address context: always false
|
||||||
/// Note: LTH doesn't need adjusted (everything >= 5 months is already > 1 hour)
|
/// Note: LTH doesn't need adjusted (everything >= 5 months is already > 1 hour)
|
||||||
/// Note: age ranges don't need adjusted (0-1h data lives in its own cohort)
|
/// Note: age ranges don't need adjusted (0-1h data lives in its own cohort)
|
||||||
|
|||||||
@@ -2,56 +2,56 @@
|
|||||||
|
|
||||||
mod address;
|
mod address;
|
||||||
mod amount_filter;
|
mod amount_filter;
|
||||||
|
mod age_range;
|
||||||
|
mod amount_range;
|
||||||
mod by_address_type;
|
mod by_address_type;
|
||||||
mod by_age_range;
|
|
||||||
mod by_amount_range;
|
|
||||||
mod by_any_address;
|
mod by_any_address;
|
||||||
mod by_epoch;
|
mod by_epoch;
|
||||||
mod by_ge_amount;
|
|
||||||
mod by_loss;
|
|
||||||
mod by_lt_amount;
|
|
||||||
mod by_max_age;
|
|
||||||
mod by_min_age;
|
|
||||||
mod by_profitability_range;
|
|
||||||
mod by_profit;
|
|
||||||
mod by_spendable_type;
|
|
||||||
mod by_term;
|
mod by_term;
|
||||||
mod by_type;
|
mod by_type;
|
||||||
mod by_unspendable_type;
|
mod class;
|
||||||
mod by_class;
|
|
||||||
mod cohort_context;
|
mod cohort_context;
|
||||||
mod cohort_name;
|
mod cohort_name;
|
||||||
mod filter;
|
mod filter;
|
||||||
mod filtered;
|
mod filtered;
|
||||||
|
mod loss;
|
||||||
|
mod over_age;
|
||||||
|
mod over_amount;
|
||||||
|
mod profit;
|
||||||
|
mod profitability_range;
|
||||||
|
mod spendable_type;
|
||||||
mod state_level;
|
mod state_level;
|
||||||
mod time_filter;
|
mod time_filter;
|
||||||
|
mod under_age;
|
||||||
|
mod under_amount;
|
||||||
|
mod unspendable_type;
|
||||||
mod utxo;
|
mod utxo;
|
||||||
|
|
||||||
pub use brk_types::{Age, Term};
|
pub use brk_types::{Age, Term};
|
||||||
|
|
||||||
pub use address::*;
|
pub use address::*;
|
||||||
pub use amount_filter::*;
|
pub use amount_filter::*;
|
||||||
|
pub use age_range::*;
|
||||||
|
pub use amount_range::*;
|
||||||
pub use by_address_type::*;
|
pub use by_address_type::*;
|
||||||
pub use by_age_range::*;
|
|
||||||
pub use by_amount_range::*;
|
|
||||||
pub use by_any_address::*;
|
pub use by_any_address::*;
|
||||||
pub use by_epoch::*;
|
pub use by_epoch::*;
|
||||||
pub use by_ge_amount::*;
|
|
||||||
pub use by_loss::*;
|
|
||||||
pub use by_lt_amount::*;
|
|
||||||
pub use by_max_age::*;
|
|
||||||
pub use by_min_age::*;
|
|
||||||
pub use by_profitability_range::*;
|
|
||||||
pub use by_profit::*;
|
|
||||||
pub use by_spendable_type::*;
|
|
||||||
pub use by_term::*;
|
pub use by_term::*;
|
||||||
pub use by_type::*;
|
pub use by_type::*;
|
||||||
pub use by_unspendable_type::*;
|
pub use class::*;
|
||||||
pub use by_class::*;
|
|
||||||
pub use cohort_context::*;
|
pub use cohort_context::*;
|
||||||
pub use cohort_name::*;
|
pub use cohort_name::*;
|
||||||
pub use filter::*;
|
pub use filter::*;
|
||||||
pub use filtered::*;
|
pub use filtered::*;
|
||||||
|
pub use loss::*;
|
||||||
|
pub use over_age::*;
|
||||||
|
pub use over_amount::*;
|
||||||
|
pub use profit::*;
|
||||||
|
pub use profitability_range::*;
|
||||||
|
pub use spendable_type::*;
|
||||||
pub use state_level::*;
|
pub use state_level::*;
|
||||||
pub use time_filter::*;
|
pub use time_filter::*;
|
||||||
|
pub use under_age::*;
|
||||||
|
pub use under_amount::*;
|
||||||
|
pub use unspendable_type::*;
|
||||||
pub use utxo::*;
|
pub use utxo::*;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use serde::Serialize;
|
|||||||
use super::CohortName;
|
use super::CohortName;
|
||||||
|
|
||||||
/// "At least X% loss" threshold names (10 thresholds).
|
/// "At least X% loss" threshold names (10 thresholds).
|
||||||
pub const LOSS_NAMES: ByLoss<CohortName> = ByLoss {
|
pub const LOSS_NAMES: Loss<CohortName> = Loss {
|
||||||
breakeven: CohortName::new("utxos_in_loss", "<0%", "In Loss (Below Breakeven)"),
|
breakeven: CohortName::new("utxos_in_loss", "<0%", "In Loss (Below Breakeven)"),
|
||||||
_10pct: CohortName::new("utxos_over_10pct_in_loss", "≥10%L", "10%+ Loss"),
|
_10pct: CohortName::new("utxos_over_10pct_in_loss", "≥10%L", "10%+ Loss"),
|
||||||
_20pct: CohortName::new("utxos_over_20pct_in_loss", "≥20%L", "20%+ Loss"),
|
_20pct: CohortName::new("utxos_over_20pct_in_loss", "≥20%L", "20%+ Loss"),
|
||||||
@@ -15,13 +15,12 @@ pub const LOSS_NAMES: ByLoss<CohortName> = ByLoss {
|
|||||||
_60pct: CohortName::new("utxos_over_60pct_in_loss", "≥60%L", "60%+ Loss"),
|
_60pct: CohortName::new("utxos_over_60pct_in_loss", "≥60%L", "60%+ Loss"),
|
||||||
_70pct: CohortName::new("utxos_over_70pct_in_loss", "≥70%L", "70%+ Loss"),
|
_70pct: CohortName::new("utxos_over_70pct_in_loss", "≥70%L", "70%+ Loss"),
|
||||||
_80pct: CohortName::new("utxos_over_80pct_in_loss", "≥80%L", "80%+ Loss"),
|
_80pct: CohortName::new("utxos_over_80pct_in_loss", "≥80%L", "80%+ Loss"),
|
||||||
_90pct: CohortName::new("utxos_over_90pct_in_loss", "≥90%L", "90%+ Loss"),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Number of loss thresholds.
|
/// Number of loss thresholds.
|
||||||
pub const LOSS_COUNT: usize = 10;
|
pub const LOSS_COUNT: usize = 9;
|
||||||
|
|
||||||
impl ByLoss<CohortName> {
|
impl Loss<CohortName> {
|
||||||
pub const fn names() -> &'static Self {
|
pub const fn names() -> &'static Self {
|
||||||
&LOSS_NAMES
|
&LOSS_NAMES
|
||||||
}
|
}
|
||||||
@@ -31,7 +30,7 @@ impl ByLoss<CohortName> {
|
|||||||
///
|
///
|
||||||
/// Each is a suffix sum over the profitability ranges, from most loss-making up.
|
/// Each is a suffix sum over the profitability ranges, from most loss-making up.
|
||||||
#[derive(Default, Clone, Traversable, Serialize)]
|
#[derive(Default, Clone, Traversable, Serialize)]
|
||||||
pub struct ByLoss<T> {
|
pub struct Loss<T> {
|
||||||
pub breakeven: T,
|
pub breakeven: T,
|
||||||
pub _10pct: T,
|
pub _10pct: T,
|
||||||
pub _20pct: T,
|
pub _20pct: T,
|
||||||
@@ -41,10 +40,9 @@ pub struct ByLoss<T> {
|
|||||||
pub _60pct: T,
|
pub _60pct: T,
|
||||||
pub _70pct: T,
|
pub _70pct: T,
|
||||||
pub _80pct: T,
|
pub _80pct: T,
|
||||||
pub _90pct: T,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ByLoss<T> {
|
impl<T> Loss<T> {
|
||||||
pub fn new<F>(mut create: F) -> Self
|
pub fn new<F>(mut create: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnMut(&'static str) -> T,
|
F: FnMut(&'static str) -> T,
|
||||||
@@ -60,7 +58,6 @@ impl<T> ByLoss<T> {
|
|||||||
_60pct: create(n._60pct.id),
|
_60pct: create(n._60pct.id),
|
||||||
_70pct: create(n._70pct.id),
|
_70pct: create(n._70pct.id),
|
||||||
_80pct: create(n._80pct.id),
|
_80pct: create(n._80pct.id),
|
||||||
_90pct: create(n._90pct.id),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +76,6 @@ impl<T> ByLoss<T> {
|
|||||||
_60pct: create(n._60pct.id)?,
|
_60pct: create(n._60pct.id)?,
|
||||||
_70pct: create(n._70pct.id)?,
|
_70pct: create(n._70pct.id)?,
|
||||||
_80pct: create(n._80pct.id)?,
|
_80pct: create(n._80pct.id)?,
|
||||||
_90pct: create(n._90pct.id)?,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +90,6 @@ impl<T> ByLoss<T> {
|
|||||||
&self._60pct,
|
&self._60pct,
|
||||||
&self._70pct,
|
&self._70pct,
|
||||||
&self._80pct,
|
&self._80pct,
|
||||||
&self._90pct,
|
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
}
|
}
|
||||||
@@ -110,7 +105,6 @@ impl<T> ByLoss<T> {
|
|||||||
&mut self._60pct,
|
&mut self._60pct,
|
||||||
&mut self._70pct,
|
&mut self._70pct,
|
||||||
&mut self._80pct,
|
&mut self._80pct,
|
||||||
&mut self._90pct,
|
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
}
|
}
|
||||||
@@ -129,7 +123,6 @@ impl<T> ByLoss<T> {
|
|||||||
&mut self._60pct,
|
&mut self._60pct,
|
||||||
&mut self._70pct,
|
&mut self._70pct,
|
||||||
&mut self._80pct,
|
&mut self._80pct,
|
||||||
&mut self._90pct,
|
|
||||||
]
|
]
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
}
|
}
|
||||||
@@ -146,7 +139,6 @@ impl<T> ByLoss<T> {
|
|||||||
&mut self._60pct,
|
&mut self._60pct,
|
||||||
&mut self._70pct,
|
&mut self._70pct,
|
||||||
&mut self._80pct,
|
&mut self._80pct,
|
||||||
&mut self._90pct,
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,8 +8,8 @@ use super::{
|
|||||||
HOURS_10Y, HOURS_12Y, TimeFilter,
|
HOURS_10Y, HOURS_12Y, TimeFilter,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Min age thresholds in hours
|
/// Over-age thresholds in hours
|
||||||
pub const MIN_AGE_HOURS: ByMinAge<usize> = ByMinAge {
|
pub const OVER_AGE_HOURS: OverAge<usize> = OverAge {
|
||||||
_1d: HOURS_1D,
|
_1d: HOURS_1D,
|
||||||
_1w: HOURS_1W,
|
_1w: HOURS_1W,
|
||||||
_1m: HOURS_1M,
|
_1m: HOURS_1M,
|
||||||
@@ -30,30 +30,30 @@ pub const MIN_AGE_HOURS: ByMinAge<usize> = ByMinAge {
|
|||||||
_12y: HOURS_12Y,
|
_12y: HOURS_12Y,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Min age filters (GreaterOrEqual threshold in hours)
|
/// Over-age filters (GreaterOrEqual threshold in hours)
|
||||||
pub const MIN_AGE_FILTERS: ByMinAge<Filter> = ByMinAge {
|
pub const OVER_AGE_FILTERS: OverAge<Filter> = OverAge {
|
||||||
_1d: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._1d)),
|
_1d: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._1d)),
|
||||||
_1w: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._1w)),
|
_1w: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._1w)),
|
||||||
_1m: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._1m)),
|
_1m: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._1m)),
|
||||||
_2m: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._2m)),
|
_2m: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._2m)),
|
||||||
_3m: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._3m)),
|
_3m: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._3m)),
|
||||||
_4m: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._4m)),
|
_4m: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._4m)),
|
||||||
_5m: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._5m)),
|
_5m: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._5m)),
|
||||||
_6m: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._6m)),
|
_6m: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._6m)),
|
||||||
_1y: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._1y)),
|
_1y: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._1y)),
|
||||||
_2y: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._2y)),
|
_2y: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._2y)),
|
||||||
_3y: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._3y)),
|
_3y: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._3y)),
|
||||||
_4y: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._4y)),
|
_4y: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._4y)),
|
||||||
_5y: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._5y)),
|
_5y: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._5y)),
|
||||||
_6y: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._6y)),
|
_6y: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._6y)),
|
||||||
_7y: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._7y)),
|
_7y: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._7y)),
|
||||||
_8y: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._8y)),
|
_8y: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._8y)),
|
||||||
_10y: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._10y)),
|
_10y: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._10y)),
|
||||||
_12y: Filter::Time(TimeFilter::GreaterOrEqual(MIN_AGE_HOURS._12y)),
|
_12y: Filter::Time(TimeFilter::GreaterOrEqual(OVER_AGE_HOURS._12y)),
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Min age names
|
/// Over-age names
|
||||||
pub const MIN_AGE_NAMES: ByMinAge<CohortName> = ByMinAge {
|
pub const OVER_AGE_NAMES: OverAge<CohortName> = OverAge {
|
||||||
_1d: CohortName::new("over_1d_old", "1d+", "Over 1 Day Old"),
|
_1d: CohortName::new("over_1d_old", "1d+", "Over 1 Day Old"),
|
||||||
_1w: CohortName::new("over_1w_old", "1w+", "Over 1 Week Old"),
|
_1w: CohortName::new("over_1w_old", "1w+", "Over 1 Week Old"),
|
||||||
_1m: CohortName::new("over_1m_old", "1m+", "Over 1 Month Old"),
|
_1m: CohortName::new("over_1m_old", "1m+", "Over 1 Month Old"),
|
||||||
@@ -75,7 +75,7 @@ pub const MIN_AGE_NAMES: ByMinAge<CohortName> = ByMinAge {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default, Clone, Traversable, Serialize)]
|
#[derive(Default, Clone, Traversable, Serialize)]
|
||||||
pub struct ByMinAge<T> {
|
pub struct OverAge<T> {
|
||||||
pub _1d: T,
|
pub _1d: T,
|
||||||
pub _1w: T,
|
pub _1w: T,
|
||||||
pub _1m: T,
|
pub _1m: T,
|
||||||
@@ -96,19 +96,19 @@ pub struct ByMinAge<T> {
|
|||||||
pub _12y: T,
|
pub _12y: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ByMinAge<CohortName> {
|
impl OverAge<CohortName> {
|
||||||
pub const fn names() -> &'static Self {
|
pub const fn names() -> &'static Self {
|
||||||
&MIN_AGE_NAMES
|
&OVER_AGE_NAMES
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ByMinAge<T> {
|
impl<T> OverAge<T> {
|
||||||
pub fn new<F>(mut create: F) -> Self
|
pub fn new<F>(mut create: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnMut(Filter, &'static str) -> T,
|
F: FnMut(Filter, &'static str) -> T,
|
||||||
{
|
{
|
||||||
let f = MIN_AGE_FILTERS;
|
let f = OVER_AGE_FILTERS;
|
||||||
let n = MIN_AGE_NAMES;
|
let n = OVER_AGE_NAMES;
|
||||||
Self {
|
Self {
|
||||||
_1d: create(f._1d.clone(), n._1d.id),
|
_1d: create(f._1d.clone(), n._1d.id),
|
||||||
_1w: create(f._1w.clone(), n._1w.id),
|
_1w: create(f._1w.clone(), n._1w.id),
|
||||||
@@ -135,8 +135,8 @@ impl<T> ByMinAge<T> {
|
|||||||
where
|
where
|
||||||
F: FnMut(Filter, &'static str) -> Result<T, E>,
|
F: FnMut(Filter, &'static str) -> Result<T, E>,
|
||||||
{
|
{
|
||||||
let f = MIN_AGE_FILTERS;
|
let f = OVER_AGE_FILTERS;
|
||||||
let n = MIN_AGE_NAMES;
|
let n = OVER_AGE_NAMES;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
_1d: create(f._1d.clone(), n._1d.id)?,
|
_1d: create(f._1d.clone(), n._1d.id)?,
|
||||||
_1w: create(f._1w.clone(), n._1w.id)?,
|
_1w: create(f._1w.clone(), n._1w.id)?,
|
||||||
@@ -5,8 +5,8 @@ use serde::Serialize;
|
|||||||
|
|
||||||
use super::{AmountFilter, CohortName, Filter};
|
use super::{AmountFilter, CohortName, Filter};
|
||||||
|
|
||||||
/// Greater-or-equal amount thresholds
|
/// Over-amount thresholds
|
||||||
pub const GE_AMOUNT_THRESHOLDS: ByGreatEqualAmount<Sats> = ByGreatEqualAmount {
|
pub const OVER_AMOUNT_THRESHOLDS: OverAmount<Sats> = OverAmount {
|
||||||
_1sat: Sats::_1,
|
_1sat: Sats::_1,
|
||||||
_10sats: Sats::_10,
|
_10sats: Sats::_10,
|
||||||
_100sats: Sats::_100,
|
_100sats: Sats::_100,
|
||||||
@@ -22,8 +22,8 @@ pub const GE_AMOUNT_THRESHOLDS: ByGreatEqualAmount<Sats> = ByGreatEqualAmount {
|
|||||||
_10k_btc: Sats::_10K_BTC,
|
_10k_btc: Sats::_10K_BTC,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Greater-or-equal amount names
|
/// Over-amount names
|
||||||
pub const GE_AMOUNT_NAMES: ByGreatEqualAmount<CohortName> = ByGreatEqualAmount {
|
pub const OVER_AMOUNT_NAMES: OverAmount<CohortName> = OverAmount {
|
||||||
_1sat: CohortName::new("over_1sat", "1+ sats", "Over 1 Sat"),
|
_1sat: CohortName::new("over_1sat", "1+ sats", "Over 1 Sat"),
|
||||||
_10sats: CohortName::new("over_10sats", "10+ sats", "Over 10 Sats"),
|
_10sats: CohortName::new("over_10sats", "10+ sats", "Over 10 Sats"),
|
||||||
_100sats: CohortName::new("over_100sats", "100+ sats", "Over 100 Sats"),
|
_100sats: CohortName::new("over_100sats", "100+ sats", "Over 100 Sats"),
|
||||||
@@ -39,27 +39,27 @@ pub const GE_AMOUNT_NAMES: ByGreatEqualAmount<CohortName> = ByGreatEqualAmount {
|
|||||||
_10k_btc: CohortName::new("over_10k_btc", "10k+ BTC", "Over 10K BTC"),
|
_10k_btc: CohortName::new("over_10k_btc", "10k+ BTC", "Over 10K BTC"),
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Greater-or-equal amount filters
|
/// Over-amount filters
|
||||||
pub const GE_AMOUNT_FILTERS: ByGreatEqualAmount<Filter> = ByGreatEqualAmount {
|
pub const OVER_AMOUNT_FILTERS: OverAmount<Filter> = OverAmount {
|
||||||
_1sat: Filter::Amount(AmountFilter::GreaterOrEqual(GE_AMOUNT_THRESHOLDS._1sat)),
|
_1sat: Filter::Amount(AmountFilter::GreaterOrEqual(OVER_AMOUNT_THRESHOLDS._1sat)),
|
||||||
_10sats: Filter::Amount(AmountFilter::GreaterOrEqual(GE_AMOUNT_THRESHOLDS._10sats)),
|
_10sats: Filter::Amount(AmountFilter::GreaterOrEqual(OVER_AMOUNT_THRESHOLDS._10sats)),
|
||||||
_100sats: Filter::Amount(AmountFilter::GreaterOrEqual(GE_AMOUNT_THRESHOLDS._100sats)),
|
_100sats: Filter::Amount(AmountFilter::GreaterOrEqual(OVER_AMOUNT_THRESHOLDS._100sats)),
|
||||||
_1k_sats: Filter::Amount(AmountFilter::GreaterOrEqual(GE_AMOUNT_THRESHOLDS._1k_sats)),
|
_1k_sats: Filter::Amount(AmountFilter::GreaterOrEqual(OVER_AMOUNT_THRESHOLDS._1k_sats)),
|
||||||
_10k_sats: Filter::Amount(AmountFilter::GreaterOrEqual(GE_AMOUNT_THRESHOLDS._10k_sats)),
|
_10k_sats: Filter::Amount(AmountFilter::GreaterOrEqual(OVER_AMOUNT_THRESHOLDS._10k_sats)),
|
||||||
_100k_sats: Filter::Amount(AmountFilter::GreaterOrEqual(
|
_100k_sats: Filter::Amount(AmountFilter::GreaterOrEqual(
|
||||||
GE_AMOUNT_THRESHOLDS._100k_sats,
|
OVER_AMOUNT_THRESHOLDS._100k_sats,
|
||||||
)),
|
)),
|
||||||
_1m_sats: Filter::Amount(AmountFilter::GreaterOrEqual(GE_AMOUNT_THRESHOLDS._1m_sats)),
|
_1m_sats: Filter::Amount(AmountFilter::GreaterOrEqual(OVER_AMOUNT_THRESHOLDS._1m_sats)),
|
||||||
_10m_sats: Filter::Amount(AmountFilter::GreaterOrEqual(GE_AMOUNT_THRESHOLDS._10m_sats)),
|
_10m_sats: Filter::Amount(AmountFilter::GreaterOrEqual(OVER_AMOUNT_THRESHOLDS._10m_sats)),
|
||||||
_1btc: Filter::Amount(AmountFilter::GreaterOrEqual(GE_AMOUNT_THRESHOLDS._1btc)),
|
_1btc: Filter::Amount(AmountFilter::GreaterOrEqual(OVER_AMOUNT_THRESHOLDS._1btc)),
|
||||||
_10btc: Filter::Amount(AmountFilter::GreaterOrEqual(GE_AMOUNT_THRESHOLDS._10btc)),
|
_10btc: Filter::Amount(AmountFilter::GreaterOrEqual(OVER_AMOUNT_THRESHOLDS._10btc)),
|
||||||
_100btc: Filter::Amount(AmountFilter::GreaterOrEqual(GE_AMOUNT_THRESHOLDS._100btc)),
|
_100btc: Filter::Amount(AmountFilter::GreaterOrEqual(OVER_AMOUNT_THRESHOLDS._100btc)),
|
||||||
_1k_btc: Filter::Amount(AmountFilter::GreaterOrEqual(GE_AMOUNT_THRESHOLDS._1k_btc)),
|
_1k_btc: Filter::Amount(AmountFilter::GreaterOrEqual(OVER_AMOUNT_THRESHOLDS._1k_btc)),
|
||||||
_10k_btc: Filter::Amount(AmountFilter::GreaterOrEqual(GE_AMOUNT_THRESHOLDS._10k_btc)),
|
_10k_btc: Filter::Amount(AmountFilter::GreaterOrEqual(OVER_AMOUNT_THRESHOLDS._10k_btc)),
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default, Clone, Traversable, Serialize)]
|
#[derive(Default, Clone, Traversable, Serialize)]
|
||||||
pub struct ByGreatEqualAmount<T> {
|
pub struct OverAmount<T> {
|
||||||
pub _1sat: T,
|
pub _1sat: T,
|
||||||
pub _10sats: T,
|
pub _10sats: T,
|
||||||
pub _100sats: T,
|
pub _100sats: T,
|
||||||
@@ -75,19 +75,19 @@ pub struct ByGreatEqualAmount<T> {
|
|||||||
pub _10k_btc: T,
|
pub _10k_btc: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ByGreatEqualAmount<CohortName> {
|
impl OverAmount<CohortName> {
|
||||||
pub const fn names() -> &'static Self {
|
pub const fn names() -> &'static Self {
|
||||||
&GE_AMOUNT_NAMES
|
&OVER_AMOUNT_NAMES
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ByGreatEqualAmount<T> {
|
impl<T> OverAmount<T> {
|
||||||
pub fn new<F>(mut create: F) -> Self
|
pub fn new<F>(mut create: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnMut(Filter, &'static str) -> T,
|
F: FnMut(Filter, &'static str) -> T,
|
||||||
{
|
{
|
||||||
let f = GE_AMOUNT_FILTERS;
|
let f = OVER_AMOUNT_FILTERS;
|
||||||
let n = GE_AMOUNT_NAMES;
|
let n = OVER_AMOUNT_NAMES;
|
||||||
Self {
|
Self {
|
||||||
_1sat: create(f._1sat.clone(), n._1sat.id),
|
_1sat: create(f._1sat.clone(), n._1sat.id),
|
||||||
_10sats: create(f._10sats.clone(), n._10sats.id),
|
_10sats: create(f._10sats.clone(), n._10sats.id),
|
||||||
@@ -109,8 +109,8 @@ impl<T> ByGreatEqualAmount<T> {
|
|||||||
where
|
where
|
||||||
F: FnMut(Filter, &'static str) -> Result<T, E>,
|
F: FnMut(Filter, &'static str) -> Result<T, E>,
|
||||||
{
|
{
|
||||||
let f = GE_AMOUNT_FILTERS;
|
let f = OVER_AMOUNT_FILTERS;
|
||||||
let n = GE_AMOUNT_NAMES;
|
let n = OVER_AMOUNT_NAMES;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
_1sat: create(f._1sat.clone(), n._1sat.id)?,
|
_1sat: create(f._1sat.clone(), n._1sat.id)?,
|
||||||
_10sats: create(f._10sats.clone(), n._10sats.id)?,
|
_10sats: create(f._10sats.clone(), n._10sats.id)?,
|
||||||
@@ -5,7 +5,7 @@ use serde::Serialize;
|
|||||||
use super::CohortName;
|
use super::CohortName;
|
||||||
|
|
||||||
/// "At least X% profit" threshold names (15 thresholds).
|
/// "At least X% profit" threshold names (15 thresholds).
|
||||||
pub const PROFIT_NAMES: ByProfit<CohortName> = ByProfit {
|
pub const PROFIT_NAMES: Profit<CohortName> = Profit {
|
||||||
breakeven: CohortName::new("utxos_in_profit", "≥0%", "In Profit (Breakeven+)"),
|
breakeven: CohortName::new("utxos_in_profit", "≥0%", "In Profit (Breakeven+)"),
|
||||||
_10pct: CohortName::new("utxos_over_10pct_in_profit", "≥10%", "10%+ Profit"),
|
_10pct: CohortName::new("utxos_over_10pct_in_profit", "≥10%", "10%+ Profit"),
|
||||||
_20pct: CohortName::new("utxos_over_20pct_in_profit", "≥20%", "20%+ Profit"),
|
_20pct: CohortName::new("utxos_over_20pct_in_profit", "≥20%", "20%+ Profit"),
|
||||||
@@ -20,13 +20,12 @@ pub const PROFIT_NAMES: ByProfit<CohortName> = ByProfit {
|
|||||||
_200pct: CohortName::new("utxos_over_200pct_in_profit", "≥200%", "200%+ Profit"),
|
_200pct: CohortName::new("utxos_over_200pct_in_profit", "≥200%", "200%+ Profit"),
|
||||||
_300pct: CohortName::new("utxos_over_300pct_in_profit", "≥300%", "300%+ Profit"),
|
_300pct: CohortName::new("utxos_over_300pct_in_profit", "≥300%", "300%+ Profit"),
|
||||||
_500pct: CohortName::new("utxos_over_500pct_in_profit", "≥500%", "500%+ Profit"),
|
_500pct: CohortName::new("utxos_over_500pct_in_profit", "≥500%", "500%+ Profit"),
|
||||||
_1000pct: CohortName::new("utxos_over_1000pct_in_profit", "≥1000%", "1000%+ Profit"),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Number of profit thresholds.
|
/// Number of profit thresholds.
|
||||||
pub const PROFIT_COUNT: usize = 15;
|
pub const PROFIT_COUNT: usize = 14;
|
||||||
|
|
||||||
impl ByProfit<CohortName> {
|
impl Profit<CohortName> {
|
||||||
pub const fn names() -> &'static Self {
|
pub const fn names() -> &'static Self {
|
||||||
&PROFIT_NAMES
|
&PROFIT_NAMES
|
||||||
}
|
}
|
||||||
@@ -36,7 +35,7 @@ impl ByProfit<CohortName> {
|
|||||||
///
|
///
|
||||||
/// Each is a prefix sum over the profitability ranges, from most profitable down.
|
/// Each is a prefix sum over the profitability ranges, from most profitable down.
|
||||||
#[derive(Default, Clone, Traversable, Serialize)]
|
#[derive(Default, Clone, Traversable, Serialize)]
|
||||||
pub struct ByProfit<T> {
|
pub struct Profit<T> {
|
||||||
pub breakeven: T,
|
pub breakeven: T,
|
||||||
pub _10pct: T,
|
pub _10pct: T,
|
||||||
pub _20pct: T,
|
pub _20pct: T,
|
||||||
@@ -51,10 +50,9 @@ pub struct ByProfit<T> {
|
|||||||
pub _200pct: T,
|
pub _200pct: T,
|
||||||
pub _300pct: T,
|
pub _300pct: T,
|
||||||
pub _500pct: T,
|
pub _500pct: T,
|
||||||
pub _1000pct: T,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ByProfit<T> {
|
impl<T> Profit<T> {
|
||||||
pub fn new<F>(mut create: F) -> Self
|
pub fn new<F>(mut create: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnMut(&'static str) -> T,
|
F: FnMut(&'static str) -> T,
|
||||||
@@ -75,7 +73,6 @@ impl<T> ByProfit<T> {
|
|||||||
_200pct: create(n._200pct.id),
|
_200pct: create(n._200pct.id),
|
||||||
_300pct: create(n._300pct.id),
|
_300pct: create(n._300pct.id),
|
||||||
_500pct: create(n._500pct.id),
|
_500pct: create(n._500pct.id),
|
||||||
_1000pct: create(n._1000pct.id),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +96,6 @@ impl<T> ByProfit<T> {
|
|||||||
_200pct: create(n._200pct.id)?,
|
_200pct: create(n._200pct.id)?,
|
||||||
_300pct: create(n._300pct.id)?,
|
_300pct: create(n._300pct.id)?,
|
||||||
_500pct: create(n._500pct.id)?,
|
_500pct: create(n._500pct.id)?,
|
||||||
_1000pct: create(n._1000pct.id)?,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +115,6 @@ impl<T> ByProfit<T> {
|
|||||||
&self._200pct,
|
&self._200pct,
|
||||||
&self._300pct,
|
&self._300pct,
|
||||||
&self._500pct,
|
&self._500pct,
|
||||||
&self._1000pct,
|
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
}
|
}
|
||||||
@@ -140,7 +135,6 @@ impl<T> ByProfit<T> {
|
|||||||
&mut self._200pct,
|
&mut self._200pct,
|
||||||
&mut self._300pct,
|
&mut self._300pct,
|
||||||
&mut self._500pct,
|
&mut self._500pct,
|
||||||
&mut self._1000pct,
|
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
}
|
}
|
||||||
@@ -164,7 +158,6 @@ impl<T> ByProfit<T> {
|
|||||||
&mut self._200pct,
|
&mut self._200pct,
|
||||||
&mut self._300pct,
|
&mut self._300pct,
|
||||||
&mut self._500pct,
|
&mut self._500pct,
|
||||||
&mut self._1000pct,
|
|
||||||
]
|
]
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
}
|
}
|
||||||
@@ -186,7 +179,6 @@ impl<T> ByProfit<T> {
|
|||||||
&mut self._200pct,
|
&mut self._200pct,
|
||||||
&mut self._300pct,
|
&mut self._300pct,
|
||||||
&mut self._500pct,
|
&mut self._500pct,
|
||||||
&mut self._1000pct,
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ pub fn compute_profitability_boundaries(spot: Cents) -> [Cents; PROFITABILITY_BO
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Profitability range names (25 ranges, from most profitable to most in loss)
|
/// Profitability range names (25 ranges, from most profitable to most in loss)
|
||||||
pub const PROFITABILITY_RANGE_NAMES: ByProfitabilityRange<CohortName> = ByProfitabilityRange {
|
pub const PROFITABILITY_RANGE_NAMES: ProfitabilityRange<CohortName> = ProfitabilityRange {
|
||||||
over_1000pct_in_profit: CohortName::new("utxos_over_1000pct_in_profit", ">1000%", "Over 1000% Profit"),
|
over_1000pct_in_profit: CohortName::new("utxos_over_1000pct_in_profit", ">1000%", "Over 1000% Profit"),
|
||||||
_500pct_to_1000pct_in_profit: CohortName::new("utxos_500pct_to_1000pct_in_profit", "500-1000%", "500-1000% Profit"),
|
_500pct_to_1000pct_in_profit: CohortName::new("utxos_500pct_to_1000pct_in_profit", "500-1000%", "500-1000% Profit"),
|
||||||
_300pct_to_500pct_in_profit: CohortName::new("utxos_300pct_to_500pct_in_profit", "300-500%", "300-500% Profit"),
|
_300pct_to_500pct_in_profit: CohortName::new("utxos_300pct_to_500pct_in_profit", "300-500%", "300-500% Profit"),
|
||||||
@@ -110,7 +110,7 @@ pub const PROFITABILITY_RANGE_NAMES: ByProfitabilityRange<CohortName> = ByProfit
|
|||||||
_90pct_to_100pct_in_loss: CohortName::new("utxos_90pct_to_100pct_in_loss", "90-100%L", "90-100% Loss"),
|
_90pct_to_100pct_in_loss: CohortName::new("utxos_90pct_to_100pct_in_loss", "90-100%L", "90-100% Loss"),
|
||||||
};
|
};
|
||||||
|
|
||||||
impl ByProfitabilityRange<CohortName> {
|
impl ProfitabilityRange<CohortName> {
|
||||||
pub const fn names() -> &'static Self {
|
pub const fn names() -> &'static Self {
|
||||||
&PROFITABILITY_RANGE_NAMES
|
&PROFITABILITY_RANGE_NAMES
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,7 @@ impl ByProfitabilityRange<CohortName> {
|
|||||||
/// During the k-way merge (ascending price order), the cursor starts at bucket 0
|
/// During the k-way merge (ascending price order), the cursor starts at bucket 0
|
||||||
/// (over_1000pct_in_profit, lowest cost basis) and advances as price crosses each boundary.
|
/// (over_1000pct_in_profit, lowest cost basis) and advances as price crosses each boundary.
|
||||||
#[derive(Default, Clone, Traversable, Serialize)]
|
#[derive(Default, Clone, Traversable, Serialize)]
|
||||||
pub struct ByProfitabilityRange<T> {
|
pub struct ProfitabilityRange<T> {
|
||||||
pub over_1000pct_in_profit: T,
|
pub over_1000pct_in_profit: T,
|
||||||
pub _500pct_to_1000pct_in_profit: T,
|
pub _500pct_to_1000pct_in_profit: T,
|
||||||
pub _300pct_to_500pct_in_profit: T,
|
pub _300pct_to_500pct_in_profit: T,
|
||||||
@@ -152,7 +152,7 @@ pub struct ByProfitabilityRange<T> {
|
|||||||
/// Number of profitability range buckets.
|
/// Number of profitability range buckets.
|
||||||
pub const PROFITABILITY_RANGE_COUNT: usize = 25;
|
pub const PROFITABILITY_RANGE_COUNT: usize = 25;
|
||||||
|
|
||||||
impl<T> ByProfitabilityRange<T> {
|
impl<T> ProfitabilityRange<T> {
|
||||||
pub fn new<F>(mut create: F) -> Self
|
pub fn new<F>(mut create: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnMut(&'static str) -> T,
|
F: FnMut(&'static str) -> T,
|
||||||
@@ -8,7 +8,7 @@ use serde::Serialize;
|
|||||||
use super::{CohortName, Filter};
|
use super::{CohortName, Filter};
|
||||||
|
|
||||||
/// Spendable type values
|
/// Spendable type values
|
||||||
pub const SPENDABLE_TYPE_VALUES: BySpendableType<OutputType> = BySpendableType {
|
pub const SPENDABLE_TYPE_VALUES: SpendableType<OutputType> = SpendableType {
|
||||||
p2pk65: OutputType::P2PK65,
|
p2pk65: OutputType::P2PK65,
|
||||||
p2pk33: OutputType::P2PK33,
|
p2pk33: OutputType::P2PK33,
|
||||||
p2pkh: OutputType::P2PKH,
|
p2pkh: OutputType::P2PKH,
|
||||||
@@ -23,7 +23,7 @@ pub const SPENDABLE_TYPE_VALUES: BySpendableType<OutputType> = BySpendableType {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Spendable type filters
|
/// Spendable type filters
|
||||||
pub const SPENDABLE_TYPE_FILTERS: BySpendableType<Filter> = BySpendableType {
|
pub const SPENDABLE_TYPE_FILTERS: SpendableType<Filter> = SpendableType {
|
||||||
p2pk65: Filter::Type(SPENDABLE_TYPE_VALUES.p2pk65),
|
p2pk65: Filter::Type(SPENDABLE_TYPE_VALUES.p2pk65),
|
||||||
p2pk33: Filter::Type(SPENDABLE_TYPE_VALUES.p2pk33),
|
p2pk33: Filter::Type(SPENDABLE_TYPE_VALUES.p2pk33),
|
||||||
p2pkh: Filter::Type(SPENDABLE_TYPE_VALUES.p2pkh),
|
p2pkh: Filter::Type(SPENDABLE_TYPE_VALUES.p2pkh),
|
||||||
@@ -38,7 +38,7 @@ pub const SPENDABLE_TYPE_FILTERS: BySpendableType<Filter> = BySpendableType {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Spendable type names
|
/// Spendable type names
|
||||||
pub const SPENDABLE_TYPE_NAMES: BySpendableType<CohortName> = BySpendableType {
|
pub const SPENDABLE_TYPE_NAMES: SpendableType<CohortName> = SpendableType {
|
||||||
p2pk65: CohortName::new("p2pk65", "P2PK65", "Pay to Public Key (65 bytes)"),
|
p2pk65: CohortName::new("p2pk65", "P2PK65", "Pay to Public Key (65 bytes)"),
|
||||||
p2pk33: CohortName::new("p2pk33", "P2PK33", "Pay to Public Key (33 bytes)"),
|
p2pk33: CohortName::new("p2pk33", "P2PK33", "Pay to Public Key (33 bytes)"),
|
||||||
p2pkh: CohortName::new("p2pkh", "P2PKH", "Pay to Public Key Hash"),
|
p2pkh: CohortName::new("p2pkh", "P2PKH", "Pay to Public Key Hash"),
|
||||||
@@ -53,7 +53,7 @@ pub const SPENDABLE_TYPE_NAMES: BySpendableType<CohortName> = BySpendableType {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default, Clone, Debug, Traversable, Serialize)]
|
#[derive(Default, Clone, Debug, Traversable, Serialize)]
|
||||||
pub struct BySpendableType<T> {
|
pub struct SpendableType<T> {
|
||||||
pub p2pk65: T,
|
pub p2pk65: T,
|
||||||
pub p2pk33: T,
|
pub p2pk33: T,
|
||||||
pub p2pkh: T,
|
pub p2pkh: T,
|
||||||
@@ -67,13 +67,13 @@ pub struct BySpendableType<T> {
|
|||||||
pub empty: T,
|
pub empty: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BySpendableType<CohortName> {
|
impl SpendableType<CohortName> {
|
||||||
pub const fn names() -> &'static Self {
|
pub const fn names() -> &'static Self {
|
||||||
&SPENDABLE_TYPE_NAMES
|
&SPENDABLE_TYPE_NAMES
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> BySpendableType<T> {
|
impl<T> SpendableType<T> {
|
||||||
pub fn new<F>(mut create: F) -> Self
|
pub fn new<F>(mut create: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnMut(Filter, &'static str) -> T,
|
F: FnMut(Filter, &'static str) -> T,
|
||||||
@@ -222,7 +222,7 @@ impl<T> BySpendableType<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Add for BySpendableType<T>
|
impl<T> Add for SpendableType<T>
|
||||||
where
|
where
|
||||||
T: Add<Output = T>,
|
T: Add<Output = T>,
|
||||||
{
|
{
|
||||||
@@ -244,7 +244,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> AddAssign for BySpendableType<T>
|
impl<T> AddAssign for SpendableType<T>
|
||||||
where
|
where
|
||||||
T: AddAssign,
|
T: AddAssign,
|
||||||
{
|
{
|
||||||
@@ -8,8 +8,8 @@ use super::{
|
|||||||
HOURS_12Y, HOURS_15Y, TimeFilter,
|
HOURS_12Y, HOURS_15Y, TimeFilter,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Max age thresholds in hours
|
/// Under-age thresholds in hours
|
||||||
pub const MAX_AGE_HOURS: ByMaxAge<usize> = ByMaxAge {
|
pub const UNDER_AGE_HOURS: UnderAge<usize> = UnderAge {
|
||||||
_1w: HOURS_1W,
|
_1w: HOURS_1W,
|
||||||
_1m: HOURS_1M,
|
_1m: HOURS_1M,
|
||||||
_2m: HOURS_2M,
|
_2m: HOURS_2M,
|
||||||
@@ -30,30 +30,30 @@ pub const MAX_AGE_HOURS: ByMaxAge<usize> = ByMaxAge {
|
|||||||
_15y: HOURS_15Y,
|
_15y: HOURS_15Y,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Max age filters (LowerThan threshold in hours)
|
/// Under-age filters (LowerThan threshold in hours)
|
||||||
pub const MAX_AGE_FILTERS: ByMaxAge<Filter> = ByMaxAge {
|
pub const UNDER_AGE_FILTERS: UnderAge<Filter> = UnderAge {
|
||||||
_1w: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._1w)),
|
_1w: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._1w)),
|
||||||
_1m: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._1m)),
|
_1m: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._1m)),
|
||||||
_2m: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._2m)),
|
_2m: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._2m)),
|
||||||
_3m: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._3m)),
|
_3m: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._3m)),
|
||||||
_4m: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._4m)),
|
_4m: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._4m)),
|
||||||
_5m: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._5m)),
|
_5m: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._5m)),
|
||||||
_6m: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._6m)),
|
_6m: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._6m)),
|
||||||
_1y: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._1y)),
|
_1y: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._1y)),
|
||||||
_2y: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._2y)),
|
_2y: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._2y)),
|
||||||
_3y: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._3y)),
|
_3y: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._3y)),
|
||||||
_4y: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._4y)),
|
_4y: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._4y)),
|
||||||
_5y: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._5y)),
|
_5y: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._5y)),
|
||||||
_6y: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._6y)),
|
_6y: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._6y)),
|
||||||
_7y: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._7y)),
|
_7y: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._7y)),
|
||||||
_8y: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._8y)),
|
_8y: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._8y)),
|
||||||
_10y: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._10y)),
|
_10y: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._10y)),
|
||||||
_12y: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._12y)),
|
_12y: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._12y)),
|
||||||
_15y: Filter::Time(TimeFilter::LowerThan(MAX_AGE_HOURS._15y)),
|
_15y: Filter::Time(TimeFilter::LowerThan(UNDER_AGE_HOURS._15y)),
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Max age names
|
/// Under-age names
|
||||||
pub const MAX_AGE_NAMES: ByMaxAge<CohortName> = ByMaxAge {
|
pub const UNDER_AGE_NAMES: UnderAge<CohortName> = UnderAge {
|
||||||
_1w: CohortName::new("under_1w_old", "<1w", "Under 1 Week Old"),
|
_1w: CohortName::new("under_1w_old", "<1w", "Under 1 Week Old"),
|
||||||
_1m: CohortName::new("under_1m_old", "<1m", "Under 1 Month Old"),
|
_1m: CohortName::new("under_1m_old", "<1m", "Under 1 Month Old"),
|
||||||
_2m: CohortName::new("under_2m_old", "<2m", "Under 2 Months Old"),
|
_2m: CohortName::new("under_2m_old", "<2m", "Under 2 Months Old"),
|
||||||
@@ -75,7 +75,7 @@ pub const MAX_AGE_NAMES: ByMaxAge<CohortName> = ByMaxAge {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default, Clone, Traversable, Serialize)]
|
#[derive(Default, Clone, Traversable, Serialize)]
|
||||||
pub struct ByMaxAge<T> {
|
pub struct UnderAge<T> {
|
||||||
pub _1w: T,
|
pub _1w: T,
|
||||||
pub _1m: T,
|
pub _1m: T,
|
||||||
pub _2m: T,
|
pub _2m: T,
|
||||||
@@ -96,19 +96,19 @@ pub struct ByMaxAge<T> {
|
|||||||
pub _15y: T,
|
pub _15y: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ByMaxAge<CohortName> {
|
impl UnderAge<CohortName> {
|
||||||
pub const fn names() -> &'static Self {
|
pub const fn names() -> &'static Self {
|
||||||
&MAX_AGE_NAMES
|
&UNDER_AGE_NAMES
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ByMaxAge<T> {
|
impl<T> UnderAge<T> {
|
||||||
pub fn new<F>(mut create: F) -> Self
|
pub fn new<F>(mut create: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnMut(Filter, &'static str) -> T,
|
F: FnMut(Filter, &'static str) -> T,
|
||||||
{
|
{
|
||||||
let f = MAX_AGE_FILTERS;
|
let f = UNDER_AGE_FILTERS;
|
||||||
let n = MAX_AGE_NAMES;
|
let n = UNDER_AGE_NAMES;
|
||||||
Self {
|
Self {
|
||||||
_1w: create(f._1w.clone(), n._1w.id),
|
_1w: create(f._1w.clone(), n._1w.id),
|
||||||
_1m: create(f._1m.clone(), n._1m.id),
|
_1m: create(f._1m.clone(), n._1m.id),
|
||||||
@@ -135,8 +135,8 @@ impl<T> ByMaxAge<T> {
|
|||||||
where
|
where
|
||||||
F: FnMut(Filter, &'static str) -> Result<T, E>,
|
F: FnMut(Filter, &'static str) -> Result<T, E>,
|
||||||
{
|
{
|
||||||
let f = MAX_AGE_FILTERS;
|
let f = UNDER_AGE_FILTERS;
|
||||||
let n = MAX_AGE_NAMES;
|
let n = UNDER_AGE_NAMES;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
_1w: create(f._1w.clone(), n._1w.id)?,
|
_1w: create(f._1w.clone(), n._1w.id)?,
|
||||||
_1m: create(f._1m.clone(), n._1m.id)?,
|
_1m: create(f._1m.clone(), n._1m.id)?,
|
||||||
@@ -5,8 +5,8 @@ use serde::Serialize;
|
|||||||
|
|
||||||
use super::{AmountFilter, CohortName, Filter};
|
use super::{AmountFilter, CohortName, Filter};
|
||||||
|
|
||||||
/// Lower-than amount thresholds
|
/// Under-amount thresholds
|
||||||
pub const LT_AMOUNT_THRESHOLDS: ByLowerThanAmount<Sats> = ByLowerThanAmount {
|
pub const UNDER_AMOUNT_THRESHOLDS: UnderAmount<Sats> = UnderAmount {
|
||||||
_10sats: Sats::_10,
|
_10sats: Sats::_10,
|
||||||
_100sats: Sats::_100,
|
_100sats: Sats::_100,
|
||||||
_1k_sats: Sats::_1K,
|
_1k_sats: Sats::_1K,
|
||||||
@@ -22,8 +22,8 @@ pub const LT_AMOUNT_THRESHOLDS: ByLowerThanAmount<Sats> = ByLowerThanAmount {
|
|||||||
_100k_btc: Sats::_100K_BTC,
|
_100k_btc: Sats::_100K_BTC,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Lower-than amount names
|
/// Under-amount names
|
||||||
pub const LT_AMOUNT_NAMES: ByLowerThanAmount<CohortName> = ByLowerThanAmount {
|
pub const UNDER_AMOUNT_NAMES: UnderAmount<CohortName> = UnderAmount {
|
||||||
_10sats: CohortName::new("under_10sats", "<10 sats", "Under 10 Sats"),
|
_10sats: CohortName::new("under_10sats", "<10 sats", "Under 10 Sats"),
|
||||||
_100sats: CohortName::new("under_100sats", "<100 sats", "Under 100 Sats"),
|
_100sats: CohortName::new("under_100sats", "<100 sats", "Under 100 Sats"),
|
||||||
_1k_sats: CohortName::new("under_1k_sats", "<1k sats", "Under 1K Sats"),
|
_1k_sats: CohortName::new("under_1k_sats", "<1k sats", "Under 1K Sats"),
|
||||||
@@ -39,25 +39,25 @@ pub const LT_AMOUNT_NAMES: ByLowerThanAmount<CohortName> = ByLowerThanAmount {
|
|||||||
_100k_btc: CohortName::new("under_100k_btc", "<100k BTC", "Under 100K BTC"),
|
_100k_btc: CohortName::new("under_100k_btc", "<100k BTC", "Under 100K BTC"),
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Lower-than amount filters
|
/// Under-amount filters
|
||||||
pub const LT_AMOUNT_FILTERS: ByLowerThanAmount<Filter> = ByLowerThanAmount {
|
pub const UNDER_AMOUNT_FILTERS: UnderAmount<Filter> = UnderAmount {
|
||||||
_10sats: Filter::Amount(AmountFilter::LowerThan(LT_AMOUNT_THRESHOLDS._10sats)),
|
_10sats: Filter::Amount(AmountFilter::LowerThan(UNDER_AMOUNT_THRESHOLDS._10sats)),
|
||||||
_100sats: Filter::Amount(AmountFilter::LowerThan(LT_AMOUNT_THRESHOLDS._100sats)),
|
_100sats: Filter::Amount(AmountFilter::LowerThan(UNDER_AMOUNT_THRESHOLDS._100sats)),
|
||||||
_1k_sats: Filter::Amount(AmountFilter::LowerThan(LT_AMOUNT_THRESHOLDS._1k_sats)),
|
_1k_sats: Filter::Amount(AmountFilter::LowerThan(UNDER_AMOUNT_THRESHOLDS._1k_sats)),
|
||||||
_10k_sats: Filter::Amount(AmountFilter::LowerThan(LT_AMOUNT_THRESHOLDS._10k_sats)),
|
_10k_sats: Filter::Amount(AmountFilter::LowerThan(UNDER_AMOUNT_THRESHOLDS._10k_sats)),
|
||||||
_100k_sats: Filter::Amount(AmountFilter::LowerThan(LT_AMOUNT_THRESHOLDS._100k_sats)),
|
_100k_sats: Filter::Amount(AmountFilter::LowerThan(UNDER_AMOUNT_THRESHOLDS._100k_sats)),
|
||||||
_1m_sats: Filter::Amount(AmountFilter::LowerThan(LT_AMOUNT_THRESHOLDS._1m_sats)),
|
_1m_sats: Filter::Amount(AmountFilter::LowerThan(UNDER_AMOUNT_THRESHOLDS._1m_sats)),
|
||||||
_10m_sats: Filter::Amount(AmountFilter::LowerThan(LT_AMOUNT_THRESHOLDS._10m_sats)),
|
_10m_sats: Filter::Amount(AmountFilter::LowerThan(UNDER_AMOUNT_THRESHOLDS._10m_sats)),
|
||||||
_1btc: Filter::Amount(AmountFilter::LowerThan(LT_AMOUNT_THRESHOLDS._1btc)),
|
_1btc: Filter::Amount(AmountFilter::LowerThan(UNDER_AMOUNT_THRESHOLDS._1btc)),
|
||||||
_10btc: Filter::Amount(AmountFilter::LowerThan(LT_AMOUNT_THRESHOLDS._10btc)),
|
_10btc: Filter::Amount(AmountFilter::LowerThan(UNDER_AMOUNT_THRESHOLDS._10btc)),
|
||||||
_100btc: Filter::Amount(AmountFilter::LowerThan(LT_AMOUNT_THRESHOLDS._100btc)),
|
_100btc: Filter::Amount(AmountFilter::LowerThan(UNDER_AMOUNT_THRESHOLDS._100btc)),
|
||||||
_1k_btc: Filter::Amount(AmountFilter::LowerThan(LT_AMOUNT_THRESHOLDS._1k_btc)),
|
_1k_btc: Filter::Amount(AmountFilter::LowerThan(UNDER_AMOUNT_THRESHOLDS._1k_btc)),
|
||||||
_10k_btc: Filter::Amount(AmountFilter::LowerThan(LT_AMOUNT_THRESHOLDS._10k_btc)),
|
_10k_btc: Filter::Amount(AmountFilter::LowerThan(UNDER_AMOUNT_THRESHOLDS._10k_btc)),
|
||||||
_100k_btc: Filter::Amount(AmountFilter::LowerThan(LT_AMOUNT_THRESHOLDS._100k_btc)),
|
_100k_btc: Filter::Amount(AmountFilter::LowerThan(UNDER_AMOUNT_THRESHOLDS._100k_btc)),
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default, Clone, Traversable, Serialize)]
|
#[derive(Default, Clone, Traversable, Serialize)]
|
||||||
pub struct ByLowerThanAmount<T> {
|
pub struct UnderAmount<T> {
|
||||||
pub _10sats: T,
|
pub _10sats: T,
|
||||||
pub _100sats: T,
|
pub _100sats: T,
|
||||||
pub _1k_sats: T,
|
pub _1k_sats: T,
|
||||||
@@ -73,19 +73,19 @@ pub struct ByLowerThanAmount<T> {
|
|||||||
pub _100k_btc: T,
|
pub _100k_btc: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ByLowerThanAmount<CohortName> {
|
impl UnderAmount<CohortName> {
|
||||||
pub const fn names() -> &'static Self {
|
pub const fn names() -> &'static Self {
|
||||||
<_AMOUNT_NAMES
|
&UNDER_AMOUNT_NAMES
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ByLowerThanAmount<T> {
|
impl<T> UnderAmount<T> {
|
||||||
pub fn new<F>(mut create: F) -> Self
|
pub fn new<F>(mut create: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnMut(Filter, &'static str) -> T,
|
F: FnMut(Filter, &'static str) -> T,
|
||||||
{
|
{
|
||||||
let f = LT_AMOUNT_FILTERS;
|
let f = UNDER_AMOUNT_FILTERS;
|
||||||
let n = LT_AMOUNT_NAMES;
|
let n = UNDER_AMOUNT_NAMES;
|
||||||
Self {
|
Self {
|
||||||
_10sats: create(f._10sats.clone(), n._10sats.id),
|
_10sats: create(f._10sats.clone(), n._10sats.id),
|
||||||
_100sats: create(f._100sats.clone(), n._100sats.id),
|
_100sats: create(f._100sats.clone(), n._100sats.id),
|
||||||
@@ -107,8 +107,8 @@ impl<T> ByLowerThanAmount<T> {
|
|||||||
where
|
where
|
||||||
F: FnMut(Filter, &'static str) -> Result<T, E>,
|
F: FnMut(Filter, &'static str) -> Result<T, E>,
|
||||||
{
|
{
|
||||||
let f = LT_AMOUNT_FILTERS;
|
let f = UNDER_AMOUNT_FILTERS;
|
||||||
let n = LT_AMOUNT_NAMES;
|
let n = UNDER_AMOUNT_NAMES;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
_10sats: create(f._10sats.clone(), n._10sats.id)?,
|
_10sats: create(f._10sats.clone(), n._10sats.id)?,
|
||||||
_100sats: create(f._100sats.clone(), n._100sats.id)?,
|
_100sats: create(f._100sats.clone(), n._100sats.id)?,
|
||||||
@@ -3,17 +3,17 @@ use std::ops::{Add, AddAssign};
|
|||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
|
|
||||||
#[derive(Default, Clone, Debug, Traversable)]
|
#[derive(Default, Clone, Debug, Traversable)]
|
||||||
pub struct ByUnspendableType<T> {
|
pub struct UnspendableType<T> {
|
||||||
pub opreturn: T,
|
pub opreturn: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ByUnspendableType<T> {
|
impl<T> UnspendableType<T> {
|
||||||
pub fn as_vec(&self) -> [&T; 1] {
|
pub fn as_vec(&self) -> [&T; 1] {
|
||||||
[&self.opreturn]
|
[&self.opreturn]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Add for ByUnspendableType<T>
|
impl<T> Add for UnspendableType<T>
|
||||||
where
|
where
|
||||||
T: Add<Output = T>,
|
T: Add<Output = T>,
|
||||||
{
|
{
|
||||||
@@ -25,7 +25,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> AddAssign for ByUnspendableType<T>
|
impl<T> AddAssign for UnspendableType<T>
|
||||||
where
|
where
|
||||||
T: AddAssign,
|
T: AddAssign,
|
||||||
{
|
{
|
||||||
@@ -2,23 +2,23 @@ use brk_traversable::Traversable;
|
|||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ByAgeRange, ByAmountRange, ByEpoch, ByGreatEqualAmount, ByLowerThanAmount, ByMaxAge, ByMinAge,
|
AgeRange, AmountRange, ByEpoch, OverAmount, UnderAmount, UnderAge, OverAge,
|
||||||
ByClass, BySpendableType, ByTerm, Filter,
|
Class, SpendableType, ByTerm, Filter,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default, Clone, Traversable)]
|
#[derive(Default, Clone, Traversable)]
|
||||||
pub struct UTXOGroups<T> {
|
pub struct UTXOGroups<T> {
|
||||||
pub all: T,
|
pub all: T,
|
||||||
pub age_range: ByAgeRange<T>,
|
pub age_range: AgeRange<T>,
|
||||||
pub epoch: ByEpoch<T>,
|
pub epoch: ByEpoch<T>,
|
||||||
pub class: ByClass<T>,
|
pub class: Class<T>,
|
||||||
pub min_age: ByMinAge<T>,
|
pub over_age: OverAge<T>,
|
||||||
pub ge_amount: ByGreatEqualAmount<T>,
|
pub over_amount: OverAmount<T>,
|
||||||
pub amount_range: ByAmountRange<T>,
|
pub amount_range: AmountRange<T>,
|
||||||
pub term: ByTerm<T>,
|
pub term: ByTerm<T>,
|
||||||
pub type_: BySpendableType<T>,
|
pub type_: SpendableType<T>,
|
||||||
pub max_age: ByMaxAge<T>,
|
pub under_age: UnderAge<T>,
|
||||||
pub lt_amount: ByLowerThanAmount<T>,
|
pub under_amount: UnderAmount<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> UTXOGroups<T> {
|
impl<T> UTXOGroups<T> {
|
||||||
@@ -28,16 +28,16 @@ impl<T> UTXOGroups<T> {
|
|||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
all: create(Filter::All, ""),
|
all: create(Filter::All, ""),
|
||||||
age_range: ByAgeRange::new(&mut create),
|
age_range: AgeRange::new(&mut create),
|
||||||
epoch: ByEpoch::new(&mut create),
|
epoch: ByEpoch::new(&mut create),
|
||||||
class: ByClass::new(&mut create),
|
class: Class::new(&mut create),
|
||||||
min_age: ByMinAge::new(&mut create),
|
over_age: OverAge::new(&mut create),
|
||||||
ge_amount: ByGreatEqualAmount::new(&mut create),
|
over_amount: OverAmount::new(&mut create),
|
||||||
amount_range: ByAmountRange::new(&mut create),
|
amount_range: AmountRange::new(&mut create),
|
||||||
term: ByTerm::new(&mut create),
|
term: ByTerm::new(&mut create),
|
||||||
type_: BySpendableType::new(&mut create),
|
type_: SpendableType::new(&mut create),
|
||||||
max_age: ByMaxAge::new(&mut create),
|
under_age: UnderAge::new(&mut create),
|
||||||
lt_amount: ByLowerThanAmount::new(&mut create),
|
under_amount: UnderAmount::new(&mut create),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,14 +45,14 @@ impl<T> UTXOGroups<T> {
|
|||||||
[&self.all]
|
[&self.all]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(self.term.iter())
|
.chain(self.term.iter())
|
||||||
.chain(self.max_age.iter())
|
.chain(self.under_age.iter())
|
||||||
.chain(self.min_age.iter())
|
.chain(self.over_age.iter())
|
||||||
.chain(self.ge_amount.iter())
|
.chain(self.over_amount.iter())
|
||||||
.chain(self.age_range.iter())
|
.chain(self.age_range.iter())
|
||||||
.chain(self.epoch.iter())
|
.chain(self.epoch.iter())
|
||||||
.chain(self.class.iter())
|
.chain(self.class.iter())
|
||||||
.chain(self.amount_range.iter())
|
.chain(self.amount_range.iter())
|
||||||
.chain(self.lt_amount.iter())
|
.chain(self.under_amount.iter())
|
||||||
.chain(self.type_.iter())
|
.chain(self.type_.iter())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,14 +60,14 @@ impl<T> UTXOGroups<T> {
|
|||||||
[&mut self.all]
|
[&mut self.all]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(self.term.iter_mut())
|
.chain(self.term.iter_mut())
|
||||||
.chain(self.max_age.iter_mut())
|
.chain(self.under_age.iter_mut())
|
||||||
.chain(self.min_age.iter_mut())
|
.chain(self.over_age.iter_mut())
|
||||||
.chain(self.ge_amount.iter_mut())
|
.chain(self.over_amount.iter_mut())
|
||||||
.chain(self.age_range.iter_mut())
|
.chain(self.age_range.iter_mut())
|
||||||
.chain(self.epoch.iter_mut())
|
.chain(self.epoch.iter_mut())
|
||||||
.chain(self.class.iter_mut())
|
.chain(self.class.iter_mut())
|
||||||
.chain(self.amount_range.iter_mut())
|
.chain(self.amount_range.iter_mut())
|
||||||
.chain(self.lt_amount.iter_mut())
|
.chain(self.under_amount.iter_mut())
|
||||||
.chain(self.type_.iter_mut())
|
.chain(self.type_.iter_mut())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,14 +78,14 @@ impl<T> UTXOGroups<T> {
|
|||||||
[&mut self.all]
|
[&mut self.all]
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.chain(self.term.par_iter_mut())
|
.chain(self.term.par_iter_mut())
|
||||||
.chain(self.max_age.par_iter_mut())
|
.chain(self.under_age.par_iter_mut())
|
||||||
.chain(self.min_age.par_iter_mut())
|
.chain(self.over_age.par_iter_mut())
|
||||||
.chain(self.ge_amount.par_iter_mut())
|
.chain(self.over_amount.par_iter_mut())
|
||||||
.chain(self.age_range.par_iter_mut())
|
.chain(self.age_range.par_iter_mut())
|
||||||
.chain(self.epoch.par_iter_mut())
|
.chain(self.epoch.par_iter_mut())
|
||||||
.chain(self.class.par_iter_mut())
|
.chain(self.class.par_iter_mut())
|
||||||
.chain(self.amount_range.par_iter_mut())
|
.chain(self.amount_range.par_iter_mut())
|
||||||
.chain(self.lt_amount.par_iter_mut())
|
.chain(self.under_amount.par_iter_mut())
|
||||||
.chain(self.type_.par_iter_mut())
|
.chain(self.type_.par_iter_mut())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,10 +123,10 @@ impl<T> UTXOGroups<T> {
|
|||||||
[&mut self.all]
|
[&mut self.all]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(self.term.iter_mut())
|
.chain(self.term.iter_mut())
|
||||||
.chain(self.max_age.iter_mut())
|
.chain(self.under_age.iter_mut())
|
||||||
.chain(self.min_age.iter_mut())
|
.chain(self.over_age.iter_mut())
|
||||||
.chain(self.lt_amount.iter_mut())
|
.chain(self.under_amount.iter_mut())
|
||||||
.chain(self.ge_amount.iter_mut())
|
.chain(self.over_amount.iter_mut())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterator over aggregate cohorts (all, sth, lth) that compute values from sub-cohorts.
|
/// Iterator over aggregate cohorts (all, sth, lth) that compute values from sub-cohorts.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use brk_cohort::{
|
use brk_cohort::{
|
||||||
AddressGroups, ByAmountRange, ByGreatEqualAmount, ByLowerThanAmount, Filter, Filtered,
|
AddressGroups, AmountRange, OverAmount, UnderAmount, Filter, Filtered,
|
||||||
};
|
};
|
||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
@@ -41,9 +41,9 @@ impl AddressCohorts {
|
|||||||
let none = |f: Filter, name: &'static str| create(f, name, false);
|
let none = |f: Filter, name: &'static str| create(f, name, false);
|
||||||
|
|
||||||
Ok(Self(AddressGroups {
|
Ok(Self(AddressGroups {
|
||||||
amount_range: ByAmountRange::try_new(&full)?,
|
amount_range: AmountRange::try_new(&full)?,
|
||||||
lt_amount: ByLowerThanAmount::try_new(&none)?,
|
under_amount: UnderAmount::try_new(&none)?,
|
||||||
ge_amount: ByGreatEqualAmount::try_new(&none)?,
|
over_amount: OverAmount::try_new(&none)?,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,9 +56,9 @@ impl AddressCohorts {
|
|||||||
|
|
||||||
let pairs: Vec<_> = self
|
let pairs: Vec<_> = self
|
||||||
.0
|
.0
|
||||||
.ge_amount
|
.over_amount
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.chain(self.0.lt_amount.iter_mut())
|
.chain(self.0.under_amount.iter_mut())
|
||||||
.map(|vecs| {
|
.map(|vecs| {
|
||||||
let filter = vecs.filter().clone();
|
let filter = vecs.filter().clone();
|
||||||
(
|
(
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use brk_cohort::{
|
use brk_cohort::{
|
||||||
ByAgeRange, ByAmountRange, ByClass, ByEpoch, ByGreatEqualAmount, ByLowerThanAmount, ByMaxAge,
|
AgeRange, AmountRange, Class, ByEpoch, OverAmount, UnderAmount, UnderAge,
|
||||||
ByMinAge, BySpendableType, CohortContext, Filter, Filtered, Term,
|
OverAge, SpendableType, CohortContext, Filter, Filtered, Term,
|
||||||
};
|
};
|
||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
@@ -39,18 +39,18 @@ pub struct UTXOCohorts<M: StorageMode = Rw> {
|
|||||||
pub all: UTXOCohortVecs<AllCohortMetrics<M>>,
|
pub all: UTXOCohortVecs<AllCohortMetrics<M>>,
|
||||||
pub sth: UTXOCohortVecs<ExtendedAdjustedCohortMetrics<M>>,
|
pub sth: UTXOCohortVecs<ExtendedAdjustedCohortMetrics<M>>,
|
||||||
pub lth: UTXOCohortVecs<ExtendedCohortMetrics<M>>,
|
pub lth: UTXOCohortVecs<ExtendedCohortMetrics<M>>,
|
||||||
pub age_range: ByAgeRange<UTXOCohortVecs<BasicCohortMetrics<M>>>,
|
pub age_range: AgeRange<UTXOCohortVecs<BasicCohortMetrics<M>>>,
|
||||||
pub max_age: ByMaxAge<UTXOCohortVecs<CoreCohortMetrics<M>>>,
|
pub under_age: UnderAge<UTXOCohortVecs<CoreCohortMetrics<M>>>,
|
||||||
pub min_age: ByMinAge<UTXOCohortVecs<CoreCohortMetrics<M>>>,
|
pub over_age: OverAge<UTXOCohortVecs<CoreCohortMetrics<M>>>,
|
||||||
pub epoch: ByEpoch<UTXOCohortVecs<CoreCohortMetrics<M>>>,
|
pub epoch: ByEpoch<UTXOCohortVecs<CoreCohortMetrics<M>>>,
|
||||||
pub class: ByClass<UTXOCohortVecs<CoreCohortMetrics<M>>>,
|
pub class: Class<UTXOCohortVecs<CoreCohortMetrics<M>>>,
|
||||||
pub ge_amount: ByGreatEqualAmount<UTXOCohortVecs<MinimalCohortMetrics<M>>>,
|
pub over_amount: OverAmount<UTXOCohortVecs<MinimalCohortMetrics<M>>>,
|
||||||
pub amount_range: ByAmountRange<UTXOCohortVecs<MinimalCohortMetrics<M>>>,
|
pub amount_range: AmountRange<UTXOCohortVecs<MinimalCohortMetrics<M>>>,
|
||||||
pub lt_amount: ByLowerThanAmount<UTXOCohortVecs<MinimalCohortMetrics<M>>>,
|
pub under_amount: UnderAmount<UTXOCohortVecs<MinimalCohortMetrics<M>>>,
|
||||||
#[traversable(rename = "type")]
|
#[traversable(rename = "type")]
|
||||||
pub type_: BySpendableType<UTXOCohortVecs<TypeCohortMetrics<M>>>,
|
pub type_: SpendableType<UTXOCohortVecs<TypeCohortMetrics<M>>>,
|
||||||
pub profitability: ProfitabilityMetrics<M>,
|
pub profitability: ProfitabilityMetrics<M>,
|
||||||
pub matured: ByAgeRange<AmountPerBlock<M>>,
|
pub matured: AgeRange<AmountPerBlock<M>>,
|
||||||
#[traversable(skip)]
|
#[traversable(skip)]
|
||||||
pub(super) fenwick: CostBasisFenwick,
|
pub(super) fenwick: CostBasisFenwick,
|
||||||
/// Cached partition_point positions for tick_tock boundary searches.
|
/// Cached partition_point positions for tick_tock boundary searches.
|
||||||
@@ -104,7 +104,7 @@ impl UTXOCohorts<Rw> {
|
|||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
let age_range = ByAgeRange::try_new(&basic_separate)?;
|
let age_range = AgeRange::try_new(&basic_separate)?;
|
||||||
|
|
||||||
let core_separate =
|
let core_separate =
|
||||||
|f: Filter, name: &'static str| -> Result<UTXOCohortVecs<CoreCohortMetrics>> {
|
|f: Filter, name: &'static str| -> Result<UTXOCohortVecs<CoreCohortMetrics>> {
|
||||||
@@ -124,7 +124,7 @@ impl UTXOCohorts<Rw> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let epoch = ByEpoch::try_new(&core_separate)?;
|
let epoch = ByEpoch::try_new(&core_separate)?;
|
||||||
let class = ByClass::try_new(&core_separate)?;
|
let class = Class::try_new(&core_separate)?;
|
||||||
|
|
||||||
// Helper for separate cohorts with MinimalCohortMetrics + MinimalRealizedState
|
// Helper for separate cohorts with MinimalCohortMetrics + MinimalRealizedState
|
||||||
let minimal_separate =
|
let minimal_separate =
|
||||||
@@ -144,7 +144,7 @@ impl UTXOCohorts<Rw> {
|
|||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
let amount_range = ByAmountRange::try_new(&minimal_separate)?;
|
let amount_range = AmountRange::try_new(&minimal_separate)?;
|
||||||
|
|
||||||
let type_separate =
|
let type_separate =
|
||||||
|f: Filter, name: &'static str| -> Result<UTXOCohortVecs<TypeCohortMetrics>> {
|
|f: Filter, name: &'static str| -> Result<UTXOCohortVecs<TypeCohortMetrics>> {
|
||||||
@@ -163,7 +163,7 @@ impl UTXOCohorts<Rw> {
|
|||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
let type_ = BySpendableType::try_new(&type_separate)?;
|
let type_ = SpendableType::try_new(&type_separate)?;
|
||||||
|
|
||||||
// Phase 3: Import "all" cohort with pre-imported supply.
|
// Phase 3: Import "all" cohort with pre-imported supply.
|
||||||
let all = UTXOCohortVecs::new(
|
let all = UTXOCohortVecs::new(
|
||||||
@@ -221,11 +221,11 @@ impl UTXOCohorts<Rw> {
|
|||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
// max_age: CoreCohortMetrics (no state, aggregates from age_range)
|
// under_age: CoreCohortMetrics (no state, aggregates from age_range)
|
||||||
let max_age = ByMaxAge::try_new(&core_no_state)?;
|
let under_age = UnderAge::try_new(&core_no_state)?;
|
||||||
|
|
||||||
// min_age: CoreCohortMetrics (no state, aggregates from age_range)
|
// over_age: CoreCohortMetrics (no state, aggregates from age_range)
|
||||||
let min_age = ByMinAge::try_new(&core_no_state)?;
|
let over_age = OverAge::try_new(&core_no_state)?;
|
||||||
|
|
||||||
let minimal_no_state =
|
let minimal_no_state =
|
||||||
|f: Filter, name: &'static str| -> Result<UTXOCohortVecs<MinimalCohortMetrics>> {
|
|f: Filter, name: &'static str| -> Result<UTXOCohortVecs<MinimalCohortMetrics>> {
|
||||||
@@ -243,10 +243,10 @@ impl UTXOCohorts<Rw> {
|
|||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
let lt_amount = ByLowerThanAmount::try_new(&minimal_no_state)?;
|
let under_amount = UnderAmount::try_new(&minimal_no_state)?;
|
||||||
let ge_amount = ByGreatEqualAmount::try_new(&minimal_no_state)?;
|
let over_amount = OverAmount::try_new(&minimal_no_state)?;
|
||||||
|
|
||||||
let matured = ByAgeRange::try_new(&|_f: Filter,
|
let matured = AgeRange::try_new(&|_f: Filter,
|
||||||
name: &'static str|
|
name: &'static str|
|
||||||
-> Result<AmountPerBlock> {
|
-> Result<AmountPerBlock> {
|
||||||
AmountPerBlock::forced_import(db, &format!("utxo_{name}_matured"), v, indexes)
|
AmountPerBlock::forced_import(db, &format!("utxo_{name}_matured"), v, indexes)
|
||||||
@@ -259,12 +259,12 @@ impl UTXOCohorts<Rw> {
|
|||||||
epoch,
|
epoch,
|
||||||
class,
|
class,
|
||||||
type_,
|
type_,
|
||||||
max_age,
|
under_age,
|
||||||
min_age,
|
over_age,
|
||||||
age_range,
|
age_range,
|
||||||
amount_range,
|
amount_range,
|
||||||
lt_amount,
|
under_amount,
|
||||||
ge_amount,
|
over_amount,
|
||||||
profitability,
|
profitability,
|
||||||
matured,
|
matured,
|
||||||
fenwick: CostBasisFenwick::new(),
|
fenwick: CostBasisFenwick::new(),
|
||||||
@@ -325,7 +325,7 @@ impl UTXOCohorts<Rw> {
|
|||||||
pub(crate) fn push_maturation(
|
pub(crate) fn push_maturation(
|
||||||
&mut self,
|
&mut self,
|
||||||
height: Height,
|
height: Height,
|
||||||
matured: &ByAgeRange<Sats>,
|
matured: &AgeRange<Sats>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
for (v, &sats) in self.matured.iter_mut().zip(matured.iter()) {
|
for (v, &sats) in self.matured.iter_mut().zip(matured.iter()) {
|
||||||
v.sats.height.truncate_push(height, sats)?;
|
v.sats.height.truncate_push(height, sats)?;
|
||||||
@@ -398,11 +398,11 @@ impl UTXOCohorts<Rw> {
|
|||||||
sth,
|
sth,
|
||||||
lth,
|
lth,
|
||||||
age_range,
|
age_range,
|
||||||
max_age,
|
under_age,
|
||||||
min_age,
|
over_age,
|
||||||
ge_amount,
|
over_amount,
|
||||||
amount_range,
|
amount_range,
|
||||||
lt_amount,
|
under_amount,
|
||||||
..
|
..
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
@@ -424,21 +424,21 @@ impl UTXOCohorts<Rw> {
|
|||||||
lth.metrics.compute_base_from_others(si, &sources, exit)
|
lth.metrics.compute_base_from_others(si, &sources, exit)
|
||||||
}),
|
}),
|
||||||
Box::new(|| {
|
Box::new(|| {
|
||||||
min_age.par_iter_mut().try_for_each(|vecs| {
|
over_age.par_iter_mut().try_for_each(|vecs| {
|
||||||
let sources = filter_sources_from(ar.iter(), Some(&vecs.metrics.filter));
|
let sources = filter_sources_from(ar.iter(), Some(&vecs.metrics.filter));
|
||||||
vecs.metrics.compute_from_base_sources(si, &sources, exit)
|
vecs.metrics.compute_from_base_sources(si, &sources, exit)
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
Box::new(|| {
|
Box::new(|| {
|
||||||
max_age.par_iter_mut().try_for_each(|vecs| {
|
under_age.par_iter_mut().try_for_each(|vecs| {
|
||||||
let sources = filter_sources_from(ar.iter(), Some(&vecs.metrics.filter));
|
let sources = filter_sources_from(ar.iter(), Some(&vecs.metrics.filter));
|
||||||
vecs.metrics.compute_from_base_sources(si, &sources, exit)
|
vecs.metrics.compute_from_base_sources(si, &sources, exit)
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
Box::new(|| {
|
Box::new(|| {
|
||||||
ge_amount
|
over_amount
|
||||||
.par_iter_mut()
|
.par_iter_mut()
|
||||||
.chain(lt_amount.par_iter_mut())
|
.chain(under_amount.par_iter_mut())
|
||||||
.try_for_each(|vecs| {
|
.try_for_each(|vecs| {
|
||||||
let sources =
|
let sources =
|
||||||
filter_minimal_sources_from(amr.iter(), Some(&vecs.metrics.filter));
|
filter_minimal_sources_from(amr.iter(), Some(&vecs.metrics.filter));
|
||||||
@@ -471,10 +471,10 @@ impl UTXOCohorts<Rw> {
|
|||||||
all.push(&mut self.all);
|
all.push(&mut self.all);
|
||||||
all.push(&mut self.sth);
|
all.push(&mut self.sth);
|
||||||
all.push(&mut self.lth);
|
all.push(&mut self.lth);
|
||||||
all.extend(self.max_age.iter_mut().map(|x| x as &mut dyn DynCohortVecs));
|
all.extend(self.under_age.iter_mut().map(|x| x as &mut dyn DynCohortVecs));
|
||||||
all.extend(self.min_age.iter_mut().map(|x| x as &mut dyn DynCohortVecs));
|
all.extend(self.over_age.iter_mut().map(|x| x as &mut dyn DynCohortVecs));
|
||||||
all.extend(
|
all.extend(
|
||||||
self.ge_amount
|
self.over_amount
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.map(|x| x as &mut dyn DynCohortVecs),
|
.map(|x| x as &mut dyn DynCohortVecs),
|
||||||
);
|
);
|
||||||
@@ -491,7 +491,7 @@ impl UTXOCohorts<Rw> {
|
|||||||
.map(|x| x as &mut dyn DynCohortVecs),
|
.map(|x| x as &mut dyn DynCohortVecs),
|
||||||
);
|
);
|
||||||
all.extend(
|
all.extend(
|
||||||
self.lt_amount
|
self.under_amount
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.map(|x| x as &mut dyn DynCohortVecs),
|
.map(|x| x as &mut dyn DynCohortVecs),
|
||||||
);
|
);
|
||||||
@@ -563,11 +563,11 @@ impl UTXOCohorts<Rw> {
|
|||||||
sth,
|
sth,
|
||||||
lth,
|
lth,
|
||||||
age_range,
|
age_range,
|
||||||
max_age,
|
under_age,
|
||||||
min_age,
|
over_age,
|
||||||
ge_amount,
|
over_amount,
|
||||||
amount_range,
|
amount_range,
|
||||||
lt_amount,
|
under_amount,
|
||||||
epoch,
|
epoch,
|
||||||
class,
|
class,
|
||||||
type_,
|
type_,
|
||||||
@@ -610,19 +610,19 @@ impl UTXOCohorts<Rw> {
|
|||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
Box::new(|| {
|
Box::new(|| {
|
||||||
max_age.par_iter_mut().try_for_each(|v| {
|
under_age.par_iter_mut().try_for_each(|v| {
|
||||||
v.metrics
|
v.metrics
|
||||||
.compute_rest_part2(blocks, prices, starting_indexes, ss, exit)
|
.compute_rest_part2(blocks, prices, starting_indexes, ss, exit)
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
Box::new(|| {
|
Box::new(|| {
|
||||||
min_age.par_iter_mut().try_for_each(|v| {
|
over_age.par_iter_mut().try_for_each(|v| {
|
||||||
v.metrics
|
v.metrics
|
||||||
.compute_rest_part2(blocks, prices, starting_indexes, ss, exit)
|
.compute_rest_part2(blocks, prices, starting_indexes, ss, exit)
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
Box::new(|| {
|
Box::new(|| {
|
||||||
ge_amount
|
over_amount
|
||||||
.par_iter_mut()
|
.par_iter_mut()
|
||||||
.try_for_each(|v| v.metrics.compute_rest_part2(prices, starting_indexes, exit))
|
.try_for_each(|v| v.metrics.compute_rest_part2(prices, starting_indexes, exit))
|
||||||
}),
|
}),
|
||||||
@@ -644,7 +644,7 @@ impl UTXOCohorts<Rw> {
|
|||||||
.try_for_each(|v| v.metrics.compute_rest_part2(prices, starting_indexes, exit))
|
.try_for_each(|v| v.metrics.compute_rest_part2(prices, starting_indexes, exit))
|
||||||
}),
|
}),
|
||||||
Box::new(|| {
|
Box::new(|| {
|
||||||
lt_amount
|
under_amount
|
||||||
.par_iter_mut()
|
.par_iter_mut()
|
||||||
.try_for_each(|v| v.metrics.compute_rest_part2(prices, starting_indexes, exit))
|
.try_for_each(|v| v.metrics.compute_rest_part2(prices, starting_indexes, exit))
|
||||||
}),
|
}),
|
||||||
@@ -674,13 +674,13 @@ impl UTXOCohorts<Rw> {
|
|||||||
for v in self.age_range.iter_mut() {
|
for v in self.age_range.iter_mut() {
|
||||||
vecs.extend(v.metrics.collect_all_vecs_mut());
|
vecs.extend(v.metrics.collect_all_vecs_mut());
|
||||||
}
|
}
|
||||||
for v in self.max_age.iter_mut() {
|
for v in self.under_age.iter_mut() {
|
||||||
vecs.extend(v.metrics.collect_all_vecs_mut());
|
vecs.extend(v.metrics.collect_all_vecs_mut());
|
||||||
}
|
}
|
||||||
for v in self.min_age.iter_mut() {
|
for v in self.over_age.iter_mut() {
|
||||||
vecs.extend(v.metrics.collect_all_vecs_mut());
|
vecs.extend(v.metrics.collect_all_vecs_mut());
|
||||||
}
|
}
|
||||||
for v in self.ge_amount.iter_mut() {
|
for v in self.over_amount.iter_mut() {
|
||||||
vecs.extend(v.metrics.collect_all_vecs_mut());
|
vecs.extend(v.metrics.collect_all_vecs_mut());
|
||||||
}
|
}
|
||||||
for v in self.epoch.iter_mut() {
|
for v in self.epoch.iter_mut() {
|
||||||
@@ -692,7 +692,7 @@ impl UTXOCohorts<Rw> {
|
|||||||
for v in self.amount_range.iter_mut() {
|
for v in self.amount_range.iter_mut() {
|
||||||
vecs.extend(v.metrics.collect_all_vecs_mut());
|
vecs.extend(v.metrics.collect_all_vecs_mut());
|
||||||
}
|
}
|
||||||
for v in self.lt_amount.iter_mut() {
|
for v in self.under_amount.iter_mut() {
|
||||||
vecs.extend(v.metrics.collect_all_vecs_mut());
|
vecs.extend(v.metrics.collect_all_vecs_mut());
|
||||||
}
|
}
|
||||||
for v in self.type_.iter_mut() {
|
for v in self.type_.iter_mut() {
|
||||||
@@ -764,10 +764,10 @@ impl UTXOCohorts<Rw> {
|
|||||||
self.all.metrics.validate_computed_versions(base_version)?;
|
self.all.metrics.validate_computed_versions(base_version)?;
|
||||||
self.sth.metrics.validate_computed_versions(base_version)?;
|
self.sth.metrics.validate_computed_versions(base_version)?;
|
||||||
self.lth.metrics.validate_computed_versions(base_version)?;
|
self.lth.metrics.validate_computed_versions(base_version)?;
|
||||||
for v in self.min_age.iter_mut() {
|
for v in self.over_age.iter_mut() {
|
||||||
v.metrics.validate_computed_versions(base_version)?;
|
v.metrics.validate_computed_versions(base_version)?;
|
||||||
}
|
}
|
||||||
for v in self.max_age.iter_mut() {
|
for v in self.under_age.iter_mut() {
|
||||||
v.metrics.validate_computed_versions(base_version)?;
|
v.metrics.validate_computed_versions(base_version)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -121,8 +121,8 @@ fn push_profitability(
|
|||||||
bucket.truncate_push(height, Sats::from(sats), raw_usd_to_dollars(usd_raw))?;
|
bucket.truncate_push(height, Sats::from(sats), raw_usd_to_dollars(usd_raw))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ByProfit: forward cumulative sum over ranges[0..15], pushed in reverse.
|
// Profit: forward cumulative sum over ranges[0..15], pushed in reverse.
|
||||||
// profit[0] (breakeven) = sum(0..=14), ..., profit[14] (_1000pct) = ranges[0]
|
// profit[0] (breakeven) = sum(0..=13), ..., profit[13] (_500pct) = ranges[0]
|
||||||
let profit_arr = metrics.profit.as_array_mut();
|
let profit_arr = metrics.profit.as_array_mut();
|
||||||
let mut cum_sats = 0u64;
|
let mut cum_sats = 0u64;
|
||||||
let mut cum_usd = 0u128;
|
let mut cum_usd = 0u128;
|
||||||
@@ -133,8 +133,8 @@ fn push_profitability(
|
|||||||
.truncate_push(height, Sats::from(cum_sats), raw_usd_to_dollars(cum_usd))?;
|
.truncate_push(height, Sats::from(cum_sats), raw_usd_to_dollars(cum_usd))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ByLoss: backward cumulative sum over ranges[15..25], pushed in reverse.
|
// Loss: backward cumulative sum over ranges[15..25], pushed in reverse.
|
||||||
// loss[0] (breakeven) = sum(15..=24), ..., loss[9] (_90pct) = ranges[24]
|
// loss[0] (breakeven) = sum(15..=24), ..., loss[8] (_80pct) = ranges[24]
|
||||||
let loss_arr = metrics.loss.as_array_mut();
|
let loss_arr = metrics.loss.as_array_mut();
|
||||||
let loss_count = loss_arr.len();
|
let loss_count = loss_arr.len();
|
||||||
cum_sats = 0;
|
cum_sats = 0;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use brk_cohort::{AGE_BOUNDARIES, ByAgeRange};
|
use brk_cohort::{AGE_BOUNDARIES, AgeRange};
|
||||||
use brk_types::{CostBasisSnapshot, ONE_HOUR_IN_SEC, Sats, Timestamp};
|
use brk_types::{CostBasisSnapshot, ONE_HOUR_IN_SEC, Sats, Timestamp};
|
||||||
use vecdb::{Rw, unlikely};
|
use vecdb::{Rw, unlikely};
|
||||||
|
|
||||||
@@ -22,9 +22,9 @@ impl UTXOCohorts<Rw> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
chain_state: &[BlockState],
|
chain_state: &[BlockState],
|
||||||
timestamp: Timestamp,
|
timestamp: Timestamp,
|
||||||
) -> ByAgeRange<Sats> {
|
) -> AgeRange<Sats> {
|
||||||
if chain_state.is_empty() {
|
if chain_state.is_empty() {
|
||||||
return ByAgeRange::default();
|
return AgeRange::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
let prev_timestamp = chain_state.last().unwrap().timestamp;
|
let prev_timestamp = chain_state.last().unwrap().timestamp;
|
||||||
@@ -32,7 +32,7 @@ impl UTXOCohorts<Rw> {
|
|||||||
|
|
||||||
// Skip if no time has passed
|
// Skip if no time has passed
|
||||||
if elapsed == 0 {
|
if elapsed == 0 {
|
||||||
return ByAgeRange::default();
|
return AgeRange::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut matured = [Sats::ZERO; 21];
|
let mut matured = [Sats::ZERO; 21];
|
||||||
@@ -96,6 +96,6 @@ impl UTXOCohorts<Rw> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ByAgeRange::from_array(matured)
|
AgeRange::from_array(matured)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ impl CoreCohortMetrics {
|
|||||||
vecs
|
vecs
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Aggregate Core-tier fields from CohortMetricsBase sources (e.g. age_range → max_age/min_age).
|
/// Aggregate Core-tier fields from CohortMetricsBase sources (e.g. age_range → under_age/over_age).
|
||||||
pub(crate) fn compute_from_base_sources<T: CohortMetricsBase>(
|
pub(crate) fn compute_from_base_sources<T: CohortMetricsBase>(
|
||||||
&mut self,
|
&mut self,
|
||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use brk_cohort::{ByLoss, ByProfit, ByProfitabilityRange};
|
use brk_cohort::{Loss, Profit, ProfitabilityRange};
|
||||||
use brk_error::Result;
|
use brk_error::Result;
|
||||||
use brk_traversable::Traversable;
|
use brk_traversable::Traversable;
|
||||||
use brk_types::{Dollars, Height, Sats, Version};
|
use brk_types::{Dollars, Height, Sats, Version};
|
||||||
@@ -66,9 +66,9 @@ impl ProfitabilityBucket {
|
|||||||
/// All profitability metrics: 25 ranges + 15 profit thresholds + 10 loss thresholds.
|
/// All profitability metrics: 25 ranges + 15 profit thresholds + 10 loss thresholds.
|
||||||
#[derive(Traversable)]
|
#[derive(Traversable)]
|
||||||
pub struct ProfitabilityMetrics<M: StorageMode = Rw> {
|
pub struct ProfitabilityMetrics<M: StorageMode = Rw> {
|
||||||
pub range: ByProfitabilityRange<ProfitabilityBucket<M>>,
|
pub range: ProfitabilityRange<ProfitabilityBucket<M>>,
|
||||||
pub profit: ByProfit<ProfitabilityBucket<M>>,
|
pub profit: Profit<ProfitabilityBucket<M>>,
|
||||||
pub loss: ByLoss<ProfitabilityBucket<M>>,
|
pub loss: Loss<ProfitabilityBucket<M>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: StorageMode> ProfitabilityMetrics<M> {
|
impl<M: StorageMode> ProfitabilityMetrics<M> {
|
||||||
@@ -88,15 +88,15 @@ impl ProfitabilityMetrics {
|
|||||||
version: Version,
|
version: Version,
|
||||||
indexes: &indexes::Vecs,
|
indexes: &indexes::Vecs,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let range = ByProfitabilityRange::try_new(|name| {
|
let range = ProfitabilityRange::try_new(|name| {
|
||||||
ProfitabilityBucket::forced_import(db, name, version, indexes)
|
ProfitabilityBucket::forced_import(db, name, version, indexes)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let profit = ByProfit::try_new(|name| {
|
let profit = Profit::try_new(|name| {
|
||||||
ProfitabilityBucket::forced_import(db, name, version, indexes)
|
ProfitabilityBucket::forced_import(db, name, version, indexes)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let loss = ByLoss::try_new(|name| {
|
let loss = Loss::try_new(|name| {
|
||||||
ProfitabilityBucket::forced_import(db, name, version, indexes)
|
ProfitabilityBucket::forced_import(db, name, version, indexes)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ impl RealizedOps for MinimalRealizedState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Core realized state: extends Minimal with sent_in_profit/loss tracking.
|
/// Core realized state: extends Minimal with sent_in_profit/loss tracking.
|
||||||
/// Used by CoreCohortMetrics cohorts (epoch, class, max_age, min_age — ~59 separate cohorts).
|
/// Used by CoreCohortMetrics cohorts (epoch, class, under_age, over_age — ~59 separate cohorts).
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct CoreRealizedState {
|
pub struct CoreRealizedState {
|
||||||
minimal: MinimalRealizedState,
|
minimal: MinimalRealizedState,
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
use std::ops::{Add, AddAssign};
|
use std::ops::{Add, AddAssign};
|
||||||
|
|
||||||
use brk_cohort::{ByAmountRange, GroupedByType};
|
use brk_cohort::{AmountRange, ByType};
|
||||||
use brk_types::{OutputType, Sats, SupplyState};
|
use brk_types::{OutputType, Sats, SupplyState};
|
||||||
use vecdb::unlikely;
|
use vecdb::unlikely;
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct Transacted {
|
pub struct Transacted {
|
||||||
pub spendable_supply: SupplyState,
|
pub spendable_supply: SupplyState,
|
||||||
pub by_type: GroupedByType<SupplyState>,
|
pub by_type: ByType<SupplyState>,
|
||||||
pub by_size_group: ByAmountRange<SupplyState>,
|
pub by_size_group: AmountRange<SupplyState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Transacted {
|
impl Transacted {
|
||||||
|
|||||||
@@ -116,6 +116,24 @@ impl Query {
|
|||||||
vec.last_json_value().ok_or(Error::NoData)
|
vec.last_json_value().ok_or(Error::NoData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the length (total data points) for a single metric.
|
||||||
|
pub fn len(&self, metric: &Metric, index: Index) -> Result<usize> {
|
||||||
|
let vec = self
|
||||||
|
.vecs()
|
||||||
|
.get(metric, index)
|
||||||
|
.ok_or_else(|| self.metric_not_found_error(metric))?;
|
||||||
|
Ok(vec.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the version for a single metric.
|
||||||
|
pub fn version(&self, metric: &Metric, index: Index) -> Result<Version> {
|
||||||
|
let vec = self
|
||||||
|
.vecs()
|
||||||
|
.get(metric, index)
|
||||||
|
.ok_or_else(|| self.metric_not_found_error(metric))?;
|
||||||
|
Ok(vec.version())
|
||||||
|
}
|
||||||
|
|
||||||
/// Search for vecs matching the given metrics and index.
|
/// Search for vecs matching the given metrics and index.
|
||||||
/// Returns error if no metrics requested or any requested metric is not found.
|
/// Returns error if no metrics requested or any requested metric is not found.
|
||||||
pub fn search(&self, params: &MetricSelection) -> Result<Vec<&'static dyn AnyExportableVec>> {
|
pub fn search(&self, params: &MetricSelection) -> Result<Vec<&'static dyn AnyExportableVec>> {
|
||||||
@@ -290,7 +308,7 @@ impl Query {
|
|||||||
let indexes = index_to_vec.keys().copied().collect();
|
let indexes = index_to_vec.keys().copied().collect();
|
||||||
Some(MetricInfo {
|
Some(MetricInfo {
|
||||||
indexes,
|
indexes,
|
||||||
value_type,
|
value_type: value_type.into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -195,6 +195,50 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
|
|||||||
.not_found(),
|
.not_found(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.api_route(
|
||||||
|
"/api/metric/{metric}/{index}/len",
|
||||||
|
get_with(
|
||||||
|
async |uri: Uri,
|
||||||
|
headers: HeaderMap,
|
||||||
|
State(state): State<AppState>,
|
||||||
|
Path(path): Path<MetricWithIndex>| {
|
||||||
|
state
|
||||||
|
.cached_json(&headers, CacheStrategy::Height, &uri, move |q| {
|
||||||
|
q.len(&path.metric, path.index)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
},
|
||||||
|
|op| op
|
||||||
|
.id("get_metric_len")
|
||||||
|
.metrics_tag()
|
||||||
|
.summary("Get metric data length")
|
||||||
|
.description("Returns the total number of data points for a metric at the given index.")
|
||||||
|
.ok_response::<usize>()
|
||||||
|
.not_found(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.api_route(
|
||||||
|
"/api/metric/{metric}/{index}/version",
|
||||||
|
get_with(
|
||||||
|
async |uri: Uri,
|
||||||
|
headers: HeaderMap,
|
||||||
|
State(state): State<AppState>,
|
||||||
|
Path(path): Path<MetricWithIndex>| {
|
||||||
|
state
|
||||||
|
.cached_json(&headers, CacheStrategy::Height, &uri, move |q| {
|
||||||
|
q.version(&path.metric, path.index)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
},
|
||||||
|
|op| op
|
||||||
|
.id("get_metric_version")
|
||||||
|
.metrics_tag()
|
||||||
|
.summary("Get metric version")
|
||||||
|
.description("Returns the current version of a metric. Changes when the metric data is updated.")
|
||||||
|
.ok_response::<brk_types::Version>()
|
||||||
|
.not_found(),
|
||||||
|
),
|
||||||
|
)
|
||||||
.api_route(
|
.api_route(
|
||||||
"/api/metric/{metric}/{index}/data",
|
"/api/metric/{metric}/{index}/data",
|
||||||
get_with(
|
get_with(
|
||||||
|
|||||||
@@ -395,6 +395,7 @@ fn generate_field_traversals(infos: &[FieldInfo], merge: bool) -> proc_macro2::T
|
|||||||
let field_name = info.name;
|
let field_name = info.name;
|
||||||
let field_name_str = {
|
let field_name_str = {
|
||||||
let s = field_name.to_string();
|
let s = field_name.to_string();
|
||||||
|
let s = s.strip_prefix("r#").unwrap_or(&s).to_string();
|
||||||
s.strip_prefix('_').map(String::from).unwrap_or(s)
|
s.strip_prefix('_').map(String::from).unwrap_or(s)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::Serialize;
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::Index;
|
use crate::Index;
|
||||||
|
|
||||||
/// Metadata about a metric
|
/// Metadata about a metric
|
||||||
#[derive(Debug, Serialize, JsonSchema)]
|
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
|
||||||
pub struct MetricInfo {
|
pub struct MetricInfo {
|
||||||
/// Available indexes
|
/// Available indexes
|
||||||
pub indexes: Vec<Index>,
|
pub indexes: Vec<Index>,
|
||||||
/// Value type (e.g. "f32", "u64", "Sats")
|
/// Value type (e.g. "f32", "u64", "Sats")
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub value_type: &'static str,
|
pub value_type: Cow<'static, str>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3270,7 +3270,7 @@ function createInRawSumPattern2(client, acc) {
|
|||||||
* @property {UnspentPattern} outputs
|
* @property {UnspentPattern} outputs
|
||||||
* @property {CapLossMvrvNuplPriceProfitSoprPattern} realized
|
* @property {CapLossMvrvNuplPriceProfitSoprPattern} realized
|
||||||
* @property {HalvedInTotalPattern} supply
|
* @property {HalvedInTotalPattern} supply
|
||||||
* @property {LossProfitPattern2} unrealized
|
* @property {LossProfitPattern} unrealized
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3284,7 +3284,7 @@ function createOutputsRealizedSupplyUnrealizedPattern(client, acc) {
|
|||||||
outputs: createUnspentPattern(client, _m(acc, 'utxo_count')),
|
outputs: createUnspentPattern(client, _m(acc, 'utxo_count')),
|
||||||
realized: createCapLossMvrvNuplPriceProfitSoprPattern(client, acc),
|
realized: createCapLossMvrvNuplPriceProfitSoprPattern(client, acc),
|
||||||
supply: createHalvedInTotalPattern(client, _m(acc, 'supply')),
|
supply: createHalvedInTotalPattern(client, _m(acc, 'supply')),
|
||||||
unrealized: createLossProfitPattern2(client, _m(acc, 'unrealized')),
|
unrealized: createLossProfitPattern(client, _m(acc, 'unrealized')),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3983,18 +3983,18 @@ function createInPattern(client, acc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} LossProfitPattern2
|
* @typedef {Object} LossProfitPattern
|
||||||
* @property {RawSumPattern2} loss
|
* @property {RawSumPattern2} loss
|
||||||
* @property {RawSumPattern2} profit
|
* @property {RawSumPattern2} profit
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a LossProfitPattern2 pattern node
|
* Create a LossProfitPattern pattern node
|
||||||
* @param {BrkClientBase} client
|
* @param {BrkClientBase} client
|
||||||
* @param {string} acc - Accumulated metric name
|
* @param {string} acc - Accumulated metric name
|
||||||
* @returns {LossProfitPattern2}
|
* @returns {LossProfitPattern}
|
||||||
*/
|
*/
|
||||||
function createLossProfitPattern2(client, acc) {
|
function createLossProfitPattern(client, acc) {
|
||||||
return {
|
return {
|
||||||
loss: createRawSumPattern2(client, _m(acc, 'loss')),
|
loss: createRawSumPattern2(client, _m(acc, 'loss')),
|
||||||
profit: createRawSumPattern2(client, _m(acc, 'profit')),
|
profit: createRawSumPattern2(client, _m(acc, 'profit')),
|
||||||
@@ -5390,7 +5390,7 @@ function createRawPattern2(client, acc) {
|
|||||||
* @typedef {Object} MetricsTree_Market_Dca_Period
|
* @typedef {Object} MetricsTree_Market_Dca_Period
|
||||||
* @property {_10y1m1w1y2y3m3y4y5y6m6y8yPattern3} stack
|
* @property {_10y1m1w1y2y3m3y4y5y6m6y8yPattern3} stack
|
||||||
* @property {MetricsTree_Market_Dca_Period_CostBasis} costBasis
|
* @property {MetricsTree_Market_Dca_Period_CostBasis} costBasis
|
||||||
* @property {_10y1m1w1y2y3m3y4y5y6m6y8yPattern2} r#return
|
* @property {_10y1m1w1y2y3m3y4y5y6m6y8yPattern2} return
|
||||||
* @property {_10y2y3y4y5y6y8yPattern} cagr
|
* @property {_10y2y3y4y5y6y8yPattern} cagr
|
||||||
* @property {_10y1m1w1y2y3m3y4y5y6m6y8yPattern3} lumpSumStack
|
* @property {_10y1m1w1y2y3m3y4y5y6m6y8yPattern3} lumpSumStack
|
||||||
* @property {_10y1m1w1y2y3m3y4y5y6m6y8yPattern2} lumpSumReturn
|
* @property {_10y1m1w1y2y3m3y4y5y6m6y8yPattern2} lumpSumReturn
|
||||||
@@ -5416,7 +5416,7 @@ function createRawPattern2(client, acc) {
|
|||||||
* @typedef {Object} MetricsTree_Market_Dca_Class
|
* @typedef {Object} MetricsTree_Market_Dca_Class
|
||||||
* @property {MetricsTree_Market_Dca_Class_Stack} stack
|
* @property {MetricsTree_Market_Dca_Class_Stack} stack
|
||||||
* @property {MetricsTree_Market_Dca_Class_CostBasis} costBasis
|
* @property {MetricsTree_Market_Dca_Class_CostBasis} costBasis
|
||||||
* @property {MetricsTree_Market_Dca_Class_R#return} r#return
|
* @property {MetricsTree_Market_Dca_Class_Return} return
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -5452,7 +5452,7 @@ function createRawPattern2(client, acc) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} MetricsTree_Market_Dca_Class_R#return
|
* @typedef {Object} MetricsTree_Market_Dca_Class_Return
|
||||||
* @property {BpsPercentRatioPattern} from2015
|
* @property {BpsPercentRatioPattern} from2015
|
||||||
* @property {BpsPercentRatioPattern} from2016
|
* @property {BpsPercentRatioPattern} from2016
|
||||||
* @property {BpsPercentRatioPattern} from2017
|
* @property {BpsPercentRatioPattern} from2017
|
||||||
@@ -5865,13 +5865,13 @@ function createRawPattern2(client, acc) {
|
|||||||
* @property {MetricsTree_Distribution_Cohorts_Utxo_Sth} sth
|
* @property {MetricsTree_Distribution_Cohorts_Utxo_Sth} sth
|
||||||
* @property {MetricsTree_Distribution_Cohorts_Utxo_Lth} lth
|
* @property {MetricsTree_Distribution_Cohorts_Utxo_Lth} lth
|
||||||
* @property {MetricsTree_Distribution_Cohorts_Utxo_AgeRange} ageRange
|
* @property {MetricsTree_Distribution_Cohorts_Utxo_AgeRange} ageRange
|
||||||
* @property {MetricsTree_Distribution_Cohorts_Utxo_MaxAge} maxAge
|
* @property {MetricsTree_Distribution_Cohorts_Utxo_UnderAge} underAge
|
||||||
* @property {MetricsTree_Distribution_Cohorts_Utxo_MinAge} minAge
|
* @property {MetricsTree_Distribution_Cohorts_Utxo_OverAge} overAge
|
||||||
* @property {MetricsTree_Distribution_Cohorts_Utxo_Epoch} epoch
|
* @property {MetricsTree_Distribution_Cohorts_Utxo_Epoch} epoch
|
||||||
* @property {MetricsTree_Distribution_Cohorts_Utxo_Class} class
|
* @property {MetricsTree_Distribution_Cohorts_Utxo_Class} class
|
||||||
* @property {MetricsTree_Distribution_Cohorts_Utxo_GeAmount} geAmount
|
* @property {MetricsTree_Distribution_Cohorts_Utxo_OverAmount} overAmount
|
||||||
* @property {MetricsTree_Distribution_Cohorts_Utxo_AmountRange} amountRange
|
* @property {MetricsTree_Distribution_Cohorts_Utxo_AmountRange} amountRange
|
||||||
* @property {MetricsTree_Distribution_Cohorts_Utxo_LtAmount} ltAmount
|
* @property {MetricsTree_Distribution_Cohorts_Utxo_UnderAmount} underAmount
|
||||||
* @property {MetricsTree_Distribution_Cohorts_Utxo_Type} type
|
* @property {MetricsTree_Distribution_Cohorts_Utxo_Type} type
|
||||||
* @property {MetricsTree_Distribution_Cohorts_Utxo_Profitability} profitability
|
* @property {MetricsTree_Distribution_Cohorts_Utxo_Profitability} profitability
|
||||||
* @property {MetricsTree_Distribution_Cohorts_Utxo_Matured} matured
|
* @property {MetricsTree_Distribution_Cohorts_Utxo_Matured} matured
|
||||||
@@ -6012,7 +6012,7 @@ function createRawPattern2(client, acc) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_MaxAge
|
* @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_UnderAge
|
||||||
* @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _1w
|
* @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _1w
|
||||||
* @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _1m
|
* @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _1m
|
||||||
* @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _2m
|
* @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _2m
|
||||||
@@ -6034,7 +6034,7 @@ function createRawPattern2(client, acc) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_MinAge
|
* @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_OverAge
|
||||||
* @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _1d
|
* @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _1d
|
||||||
* @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _1w
|
* @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _1w
|
||||||
* @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _1m
|
* @property {ActivityOutputsRealizedSupplyUnrealizedPattern2} _1m
|
||||||
@@ -6087,7 +6087,7 @@ function createRawPattern2(client, acc) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_GeAmount
|
* @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_OverAmount
|
||||||
* @property {OutputsRealizedSupplyPattern} _1sat
|
* @property {OutputsRealizedSupplyPattern} _1sat
|
||||||
* @property {OutputsRealizedSupplyPattern} _10sats
|
* @property {OutputsRealizedSupplyPattern} _10sats
|
||||||
* @property {OutputsRealizedSupplyPattern} _100sats
|
* @property {OutputsRealizedSupplyPattern} _100sats
|
||||||
@@ -6123,7 +6123,7 @@ function createRawPattern2(client, acc) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_LtAmount
|
* @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_UnderAmount
|
||||||
* @property {OutputsRealizedSupplyPattern} _10sats
|
* @property {OutputsRealizedSupplyPattern} _10sats
|
||||||
* @property {OutputsRealizedSupplyPattern} _100sats
|
* @property {OutputsRealizedSupplyPattern} _100sats
|
||||||
* @property {OutputsRealizedSupplyPattern} _1kSats
|
* @property {OutputsRealizedSupplyPattern} _1kSats
|
||||||
@@ -6163,31 +6163,31 @@ function createRawPattern2(client, acc) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_Profitability_Range
|
* @typedef {Object} MetricsTree_Distribution_Cohorts_Utxo_Profitability_Range
|
||||||
* @property {RealizedSupplyPattern} profitOver1000
|
* @property {RealizedSupplyPattern} over1000pctInProfit
|
||||||
* @property {RealizedSupplyPattern} profit500To1000
|
* @property {RealizedSupplyPattern} _500pctTo1000pctInProfit
|
||||||
* @property {RealizedSupplyPattern} profit300To500
|
* @property {RealizedSupplyPattern} _300pctTo500pctInProfit
|
||||||
* @property {RealizedSupplyPattern} profit200To300
|
* @property {RealizedSupplyPattern} _200pctTo300pctInProfit
|
||||||
* @property {RealizedSupplyPattern} profit100To200
|
* @property {RealizedSupplyPattern} _100pctTo200pctInProfit
|
||||||
* @property {RealizedSupplyPattern} profit90To100
|
* @property {RealizedSupplyPattern} _90pctTo100pctInProfit
|
||||||
* @property {RealizedSupplyPattern} profit80To90
|
* @property {RealizedSupplyPattern} _80pctTo90pctInProfit
|
||||||
* @property {RealizedSupplyPattern} profit70To80
|
* @property {RealizedSupplyPattern} _70pctTo80pctInProfit
|
||||||
* @property {RealizedSupplyPattern} profit60To70
|
* @property {RealizedSupplyPattern} _60pctTo70pctInProfit
|
||||||
* @property {RealizedSupplyPattern} profit50To60
|
* @property {RealizedSupplyPattern} _50pctTo60pctInProfit
|
||||||
* @property {RealizedSupplyPattern} profit40To50
|
* @property {RealizedSupplyPattern} _40pctTo50pctInProfit
|
||||||
* @property {RealizedSupplyPattern} profit30To40
|
* @property {RealizedSupplyPattern} _30pctTo40pctInProfit
|
||||||
* @property {RealizedSupplyPattern} profit20To30
|
* @property {RealizedSupplyPattern} _20pctTo30pctInProfit
|
||||||
* @property {RealizedSupplyPattern} profit10To20
|
* @property {RealizedSupplyPattern} _10pctTo20pctInProfit
|
||||||
* @property {RealizedSupplyPattern} profit0To10
|
* @property {RealizedSupplyPattern} _0pctTo10pctInProfit
|
||||||
* @property {RealizedSupplyPattern} loss0To10
|
* @property {RealizedSupplyPattern} _0pctTo10pctInLoss
|
||||||
* @property {RealizedSupplyPattern} loss10To20
|
* @property {RealizedSupplyPattern} _10pctTo20pctInLoss
|
||||||
* @property {RealizedSupplyPattern} loss20To30
|
* @property {RealizedSupplyPattern} _20pctTo30pctInLoss
|
||||||
* @property {RealizedSupplyPattern} loss30To40
|
* @property {RealizedSupplyPattern} _30pctTo40pctInLoss
|
||||||
* @property {RealizedSupplyPattern} loss40To50
|
* @property {RealizedSupplyPattern} _40pctTo50pctInLoss
|
||||||
* @property {RealizedSupplyPattern} loss50To60
|
* @property {RealizedSupplyPattern} _50pctTo60pctInLoss
|
||||||
* @property {RealizedSupplyPattern} loss60To70
|
* @property {RealizedSupplyPattern} _60pctTo70pctInLoss
|
||||||
* @property {RealizedSupplyPattern} loss70To80
|
* @property {RealizedSupplyPattern} _70pctTo80pctInLoss
|
||||||
* @property {RealizedSupplyPattern} loss80To90
|
* @property {RealizedSupplyPattern} _80pctTo90pctInLoss
|
||||||
* @property {RealizedSupplyPattern} loss90To100
|
* @property {RealizedSupplyPattern} _90pctTo100pctInLoss
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -6206,7 +6206,6 @@ function createRawPattern2(client, acc) {
|
|||||||
* @property {RealizedSupplyPattern} _200pct
|
* @property {RealizedSupplyPattern} _200pct
|
||||||
* @property {RealizedSupplyPattern} _300pct
|
* @property {RealizedSupplyPattern} _300pct
|
||||||
* @property {RealizedSupplyPattern} _500pct
|
* @property {RealizedSupplyPattern} _500pct
|
||||||
* @property {RealizedSupplyPattern} _1000pct
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -6220,7 +6219,6 @@ function createRawPattern2(client, acc) {
|
|||||||
* @property {RealizedSupplyPattern} _60pct
|
* @property {RealizedSupplyPattern} _60pct
|
||||||
* @property {RealizedSupplyPattern} _70pct
|
* @property {RealizedSupplyPattern} _70pct
|
||||||
* @property {RealizedSupplyPattern} _80pct
|
* @property {RealizedSupplyPattern} _80pct
|
||||||
* @property {RealizedSupplyPattern} _90pct
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -6250,13 +6248,13 @@ function createRawPattern2(client, acc) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} MetricsTree_Distribution_Cohorts_Address
|
* @typedef {Object} MetricsTree_Distribution_Cohorts_Address
|
||||||
* @property {MetricsTree_Distribution_Cohorts_Address_GeAmount} geAmount
|
* @property {MetricsTree_Distribution_Cohorts_Address_OverAmount} overAmount
|
||||||
* @property {MetricsTree_Distribution_Cohorts_Address_AmountRange} amountRange
|
* @property {MetricsTree_Distribution_Cohorts_Address_AmountRange} amountRange
|
||||||
* @property {MetricsTree_Distribution_Cohorts_Address_LtAmount} ltAmount
|
* @property {MetricsTree_Distribution_Cohorts_Address_UnderAmount} underAmount
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} MetricsTree_Distribution_Cohorts_Address_GeAmount
|
* @typedef {Object} MetricsTree_Distribution_Cohorts_Address_OverAmount
|
||||||
* @property {AddrOutputsRealizedSupplyPattern} _1sat
|
* @property {AddrOutputsRealizedSupplyPattern} _1sat
|
||||||
* @property {AddrOutputsRealizedSupplyPattern} _10sats
|
* @property {AddrOutputsRealizedSupplyPattern} _10sats
|
||||||
* @property {AddrOutputsRealizedSupplyPattern} _100sats
|
* @property {AddrOutputsRealizedSupplyPattern} _100sats
|
||||||
@@ -6292,7 +6290,7 @@ function createRawPattern2(client, acc) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} MetricsTree_Distribution_Cohorts_Address_LtAmount
|
* @typedef {Object} MetricsTree_Distribution_Cohorts_Address_UnderAmount
|
||||||
* @property {AddrOutputsRealizedSupplyPattern} _10sats
|
* @property {AddrOutputsRealizedSupplyPattern} _10sats
|
||||||
* @property {AddrOutputsRealizedSupplyPattern} _100sats
|
* @property {AddrOutputsRealizedSupplyPattern} _100sats
|
||||||
* @property {AddrOutputsRealizedSupplyPattern} _1kSats
|
* @property {AddrOutputsRealizedSupplyPattern} _1kSats
|
||||||
@@ -6847,7 +6845,7 @@ class BrkClient extends BrkClientBase {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
MAX_AGE_NAMES = /** @type {const} */ ({
|
UNDER_AGE_NAMES = /** @type {const} */ ({
|
||||||
"_1w": {
|
"_1w": {
|
||||||
"id": "under_1w_old",
|
"id": "under_1w_old",
|
||||||
"short": "<1w",
|
"short": "<1w",
|
||||||
@@ -6940,7 +6938,7 @@ class BrkClient extends BrkClientBase {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
MIN_AGE_NAMES = /** @type {const} */ ({
|
OVER_AGE_NAMES = /** @type {const} */ ({
|
||||||
"_1d": {
|
"_1d": {
|
||||||
"id": "over_1d_old",
|
"id": "over_1d_old",
|
||||||
"short": "1d+",
|
"short": "1d+",
|
||||||
@@ -7111,7 +7109,7 @@ class BrkClient extends BrkClientBase {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
GE_AMOUNT_NAMES = /** @type {const} */ ({
|
OVER_AMOUNT_NAMES = /** @type {const} */ ({
|
||||||
"_1sat": {
|
"_1sat": {
|
||||||
"id": "over_1sat",
|
"id": "over_1sat",
|
||||||
"short": "1+ sats",
|
"short": "1+ sats",
|
||||||
@@ -7179,7 +7177,7 @@ class BrkClient extends BrkClientBase {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
LT_AMOUNT_NAMES = /** @type {const} */ ({
|
UNDER_AMOUNT_NAMES = /** @type {const} */ ({
|
||||||
"_10sats": {
|
"_10sats": {
|
||||||
"id": "under_10sats",
|
"id": "under_10sats",
|
||||||
"short": "<10 sats",
|
"short": "<10 sats",
|
||||||
@@ -7943,7 +7941,7 @@ class BrkClient extends BrkClientBase {
|
|||||||
_8y: createCentsSatsUsdPattern(this, 'dca_cost_basis_8y'),
|
_8y: createCentsSatsUsdPattern(this, 'dca_cost_basis_8y'),
|
||||||
_10y: createCentsSatsUsdPattern(this, 'dca_cost_basis_10y'),
|
_10y: createCentsSatsUsdPattern(this, 'dca_cost_basis_10y'),
|
||||||
},
|
},
|
||||||
r#return: create_10y1m1w1y2y3m3y4y5y6m6y8yPattern2(this, 'dca_return'),
|
return: create_10y1m1w1y2y3m3y4y5y6m6y8yPattern2(this, 'dca_return'),
|
||||||
cagr: create_10y2y3y4y5y6y8yPattern(this, 'dca_cagr'),
|
cagr: create_10y2y3y4y5y6y8yPattern(this, 'dca_cagr'),
|
||||||
lumpSumStack: create_10y1m1w1y2y3m3y4y5y6m6y8yPattern3(this, 'lump_sum_stack'),
|
lumpSumStack: create_10y1m1w1y2y3m3y4y5y6m6y8yPattern3(this, 'lump_sum_stack'),
|
||||||
lumpSumReturn: create_10y1m1w1y2y3m3y4y5y6m6y8yPattern2(this, 'lump_sum_return'),
|
lumpSumReturn: create_10y1m1w1y2y3m3y4y5y6m6y8yPattern2(this, 'lump_sum_return'),
|
||||||
@@ -7977,7 +7975,7 @@ class BrkClient extends BrkClientBase {
|
|||||||
from2025: createCentsSatsUsdPattern(this, 'dca_cost_basis_from_2025'),
|
from2025: createCentsSatsUsdPattern(this, 'dca_cost_basis_from_2025'),
|
||||||
from2026: createCentsSatsUsdPattern(this, 'dca_cost_basis_from_2026'),
|
from2026: createCentsSatsUsdPattern(this, 'dca_cost_basis_from_2026'),
|
||||||
},
|
},
|
||||||
r#return: {
|
return: {
|
||||||
from2015: createBpsPercentRatioPattern(this, 'dca_return_from_2015'),
|
from2015: createBpsPercentRatioPattern(this, 'dca_return_from_2015'),
|
||||||
from2016: createBpsPercentRatioPattern(this, 'dca_return_from_2016'),
|
from2016: createBpsPercentRatioPattern(this, 'dca_return_from_2016'),
|
||||||
from2017: createBpsPercentRatioPattern(this, 'dca_return_from_2017'),
|
from2017: createBpsPercentRatioPattern(this, 'dca_return_from_2017'),
|
||||||
@@ -8410,7 +8408,7 @@ class BrkClient extends BrkClientBase {
|
|||||||
_12yTo15y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_12y_to_15y_old'),
|
_12yTo15y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_12y_to_15y_old'),
|
||||||
from15y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_over_15y_old'),
|
from15y: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_over_15y_old'),
|
||||||
},
|
},
|
||||||
maxAge: {
|
underAge: {
|
||||||
_1w: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_1w_old'),
|
_1w: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_1w_old'),
|
||||||
_1m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_1m_old'),
|
_1m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_1m_old'),
|
||||||
_2m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_2m_old'),
|
_2m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_2m_old'),
|
||||||
@@ -8430,7 +8428,7 @@ class BrkClient extends BrkClientBase {
|
|||||||
_12y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_12y_old'),
|
_12y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_12y_old'),
|
||||||
_15y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_15y_old'),
|
_15y: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_under_15y_old'),
|
||||||
},
|
},
|
||||||
minAge: {
|
overAge: {
|
||||||
_1d: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_1d_old'),
|
_1d: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_1d_old'),
|
||||||
_1w: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_1w_old'),
|
_1w: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_1w_old'),
|
||||||
_1m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_1m_old'),
|
_1m: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'utxos_over_1m_old'),
|
||||||
@@ -8477,7 +8475,7 @@ class BrkClient extends BrkClientBase {
|
|||||||
_2025: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2025'),
|
_2025: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2025'),
|
||||||
_2026: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2026'),
|
_2026: createActivityOutputsRealizedSupplyUnrealizedPattern2(this, 'class_2026'),
|
||||||
},
|
},
|
||||||
geAmount: {
|
overAmount: {
|
||||||
_1sat: createOutputsRealizedSupplyPattern(this, 'utxos_over_1sat'),
|
_1sat: createOutputsRealizedSupplyPattern(this, 'utxos_over_1sat'),
|
||||||
_10sats: createOutputsRealizedSupplyPattern(this, 'utxos_over_10sats'),
|
_10sats: createOutputsRealizedSupplyPattern(this, 'utxos_over_10sats'),
|
||||||
_100sats: createOutputsRealizedSupplyPattern(this, 'utxos_over_100sats'),
|
_100sats: createOutputsRealizedSupplyPattern(this, 'utxos_over_100sats'),
|
||||||
@@ -8509,7 +8507,7 @@ class BrkClient extends BrkClientBase {
|
|||||||
_10kBtcTo100kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_above_10k_btc_under_100k_btc'),
|
_10kBtcTo100kBtc: createOutputsRealizedSupplyPattern(this, 'utxos_above_10k_btc_under_100k_btc'),
|
||||||
_100kBtcOrMore: createOutputsRealizedSupplyPattern(this, 'utxos_above_100k_btc'),
|
_100kBtcOrMore: createOutputsRealizedSupplyPattern(this, 'utxos_above_100k_btc'),
|
||||||
},
|
},
|
||||||
ltAmount: {
|
underAmount: {
|
||||||
_10sats: createOutputsRealizedSupplyPattern(this, 'utxos_under_10sats'),
|
_10sats: createOutputsRealizedSupplyPattern(this, 'utxos_under_10sats'),
|
||||||
_100sats: createOutputsRealizedSupplyPattern(this, 'utxos_under_100sats'),
|
_100sats: createOutputsRealizedSupplyPattern(this, 'utxos_under_100sats'),
|
||||||
_1kSats: createOutputsRealizedSupplyPattern(this, 'utxos_under_1k_sats'),
|
_1kSats: createOutputsRealizedSupplyPattern(this, 'utxos_under_1k_sats'),
|
||||||
@@ -8539,60 +8537,58 @@ class BrkClient extends BrkClientBase {
|
|||||||
},
|
},
|
||||||
profitability: {
|
profitability: {
|
||||||
range: {
|
range: {
|
||||||
profitOver1000: createRealizedSupplyPattern(this, 'utxos_over_1000pct_up'),
|
over1000pctInProfit: createRealizedSupplyPattern(this, 'utxos_over_1000pct_in_profit'),
|
||||||
profit500To1000: createRealizedSupplyPattern(this, 'utxos_500pct_to_1000pct_up'),
|
_500pctTo1000pctInProfit: createRealizedSupplyPattern(this, 'utxos_500pct_to_1000pct_in_profit'),
|
||||||
profit300To500: createRealizedSupplyPattern(this, 'utxos_300pct_to_500pct_up'),
|
_300pctTo500pctInProfit: createRealizedSupplyPattern(this, 'utxos_300pct_to_500pct_in_profit'),
|
||||||
profit200To300: createRealizedSupplyPattern(this, 'utxos_200pct_to_300pct_up'),
|
_200pctTo300pctInProfit: createRealizedSupplyPattern(this, 'utxos_200pct_to_300pct_in_profit'),
|
||||||
profit100To200: createRealizedSupplyPattern(this, 'utxos_100pct_to_200pct_up'),
|
_100pctTo200pctInProfit: createRealizedSupplyPattern(this, 'utxos_100pct_to_200pct_in_profit'),
|
||||||
profit90To100: createRealizedSupplyPattern(this, 'utxos_90pct_to_100pct_up'),
|
_90pctTo100pctInProfit: createRealizedSupplyPattern(this, 'utxos_90pct_to_100pct_in_profit'),
|
||||||
profit80To90: createRealizedSupplyPattern(this, 'utxos_80pct_to_90pct_up'),
|
_80pctTo90pctInProfit: createRealizedSupplyPattern(this, 'utxos_80pct_to_90pct_in_profit'),
|
||||||
profit70To80: createRealizedSupplyPattern(this, 'utxos_70pct_to_80pct_up'),
|
_70pctTo80pctInProfit: createRealizedSupplyPattern(this, 'utxos_70pct_to_80pct_in_profit'),
|
||||||
profit60To70: createRealizedSupplyPattern(this, 'utxos_60pct_to_70pct_up'),
|
_60pctTo70pctInProfit: createRealizedSupplyPattern(this, 'utxos_60pct_to_70pct_in_profit'),
|
||||||
profit50To60: createRealizedSupplyPattern(this, 'utxos_50pct_to_60pct_up'),
|
_50pctTo60pctInProfit: createRealizedSupplyPattern(this, 'utxos_50pct_to_60pct_in_profit'),
|
||||||
profit40To50: createRealizedSupplyPattern(this, 'utxos_40pct_to_50pct_up'),
|
_40pctTo50pctInProfit: createRealizedSupplyPattern(this, 'utxos_40pct_to_50pct_in_profit'),
|
||||||
profit30To40: createRealizedSupplyPattern(this, 'utxos_30pct_to_40pct_up'),
|
_30pctTo40pctInProfit: createRealizedSupplyPattern(this, 'utxos_30pct_to_40pct_in_profit'),
|
||||||
profit20To30: createRealizedSupplyPattern(this, 'utxos_20pct_to_30pct_up'),
|
_20pctTo30pctInProfit: createRealizedSupplyPattern(this, 'utxos_20pct_to_30pct_in_profit'),
|
||||||
profit10To20: createRealizedSupplyPattern(this, 'utxos_10pct_to_20pct_up'),
|
_10pctTo20pctInProfit: createRealizedSupplyPattern(this, 'utxos_10pct_to_20pct_in_profit'),
|
||||||
profit0To10: createRealizedSupplyPattern(this, 'utxos_0pct_to_10pct_up'),
|
_0pctTo10pctInProfit: createRealizedSupplyPattern(this, 'utxos_0pct_to_10pct_in_profit'),
|
||||||
loss0To10: createRealizedSupplyPattern(this, 'utxos_0pct_to_10pct_down'),
|
_0pctTo10pctInLoss: createRealizedSupplyPattern(this, 'utxos_0pct_to_10pct_in_loss'),
|
||||||
loss10To20: createRealizedSupplyPattern(this, 'utxos_10pct_to_20pct_down'),
|
_10pctTo20pctInLoss: createRealizedSupplyPattern(this, 'utxos_10pct_to_20pct_in_loss'),
|
||||||
loss20To30: createRealizedSupplyPattern(this, 'utxos_20pct_to_30pct_down'),
|
_20pctTo30pctInLoss: createRealizedSupplyPattern(this, 'utxos_20pct_to_30pct_in_loss'),
|
||||||
loss30To40: createRealizedSupplyPattern(this, 'utxos_30pct_to_40pct_down'),
|
_30pctTo40pctInLoss: createRealizedSupplyPattern(this, 'utxos_30pct_to_40pct_in_loss'),
|
||||||
loss40To50: createRealizedSupplyPattern(this, 'utxos_40pct_to_50pct_down'),
|
_40pctTo50pctInLoss: createRealizedSupplyPattern(this, 'utxos_40pct_to_50pct_in_loss'),
|
||||||
loss50To60: createRealizedSupplyPattern(this, 'utxos_50pct_to_60pct_down'),
|
_50pctTo60pctInLoss: createRealizedSupplyPattern(this, 'utxos_50pct_to_60pct_in_loss'),
|
||||||
loss60To70: createRealizedSupplyPattern(this, 'utxos_60pct_to_70pct_down'),
|
_60pctTo70pctInLoss: createRealizedSupplyPattern(this, 'utxos_60pct_to_70pct_in_loss'),
|
||||||
loss70To80: createRealizedSupplyPattern(this, 'utxos_70pct_to_80pct_down'),
|
_70pctTo80pctInLoss: createRealizedSupplyPattern(this, 'utxos_70pct_to_80pct_in_loss'),
|
||||||
loss80To90: createRealizedSupplyPattern(this, 'utxos_80pct_to_90pct_down'),
|
_80pctTo90pctInLoss: createRealizedSupplyPattern(this, 'utxos_80pct_to_90pct_in_loss'),
|
||||||
loss90To100: createRealizedSupplyPattern(this, 'utxos_90pct_to_100pct_down'),
|
_90pctTo100pctInLoss: createRealizedSupplyPattern(this, 'utxos_90pct_to_100pct_in_loss'),
|
||||||
},
|
},
|
||||||
profit: {
|
profit: {
|
||||||
breakeven: createRealizedSupplyPattern(this, 'profit_ge_breakeven'),
|
breakeven: createRealizedSupplyPattern(this, 'utxos_in_profit'),
|
||||||
_10pct: createRealizedSupplyPattern(this, 'profit_ge_10pct'),
|
_10pct: createRealizedSupplyPattern(this, 'utxos_over_10pct_in_profit'),
|
||||||
_20pct: createRealizedSupplyPattern(this, 'profit_ge_20pct'),
|
_20pct: createRealizedSupplyPattern(this, 'utxos_over_20pct_in_profit'),
|
||||||
_30pct: createRealizedSupplyPattern(this, 'profit_ge_30pct'),
|
_30pct: createRealizedSupplyPattern(this, 'utxos_over_30pct_in_profit'),
|
||||||
_40pct: createRealizedSupplyPattern(this, 'profit_ge_40pct'),
|
_40pct: createRealizedSupplyPattern(this, 'utxos_over_40pct_in_profit'),
|
||||||
_50pct: createRealizedSupplyPattern(this, 'profit_ge_50pct'),
|
_50pct: createRealizedSupplyPattern(this, 'utxos_over_50pct_in_profit'),
|
||||||
_60pct: createRealizedSupplyPattern(this, 'profit_ge_60pct'),
|
_60pct: createRealizedSupplyPattern(this, 'utxos_over_60pct_in_profit'),
|
||||||
_70pct: createRealizedSupplyPattern(this, 'profit_ge_70pct'),
|
_70pct: createRealizedSupplyPattern(this, 'utxos_over_70pct_in_profit'),
|
||||||
_80pct: createRealizedSupplyPattern(this, 'profit_ge_80pct'),
|
_80pct: createRealizedSupplyPattern(this, 'utxos_over_80pct_in_profit'),
|
||||||
_90pct: createRealizedSupplyPattern(this, 'profit_ge_90pct'),
|
_90pct: createRealizedSupplyPattern(this, 'utxos_over_90pct_in_profit'),
|
||||||
_100pct: createRealizedSupplyPattern(this, 'profit_ge_100pct'),
|
_100pct: createRealizedSupplyPattern(this, 'utxos_over_100pct_in_profit'),
|
||||||
_200pct: createRealizedSupplyPattern(this, 'profit_ge_200pct'),
|
_200pct: createRealizedSupplyPattern(this, 'utxos_over_200pct_in_profit'),
|
||||||
_300pct: createRealizedSupplyPattern(this, 'profit_ge_300pct'),
|
_300pct: createRealizedSupplyPattern(this, 'utxos_over_300pct_in_profit'),
|
||||||
_500pct: createRealizedSupplyPattern(this, 'profit_ge_500pct'),
|
_500pct: createRealizedSupplyPattern(this, 'utxos_over_500pct_in_profit'),
|
||||||
_1000pct: createRealizedSupplyPattern(this, 'profit_ge_1000pct'),
|
|
||||||
},
|
},
|
||||||
loss: {
|
loss: {
|
||||||
breakeven: createRealizedSupplyPattern(this, 'loss_ge_breakeven'),
|
breakeven: createRealizedSupplyPattern(this, 'utxos_in_loss'),
|
||||||
_10pct: createRealizedSupplyPattern(this, 'loss_ge_10pct'),
|
_10pct: createRealizedSupplyPattern(this, 'utxos_over_10pct_in_loss'),
|
||||||
_20pct: createRealizedSupplyPattern(this, 'loss_ge_20pct'),
|
_20pct: createRealizedSupplyPattern(this, 'utxos_over_20pct_in_loss'),
|
||||||
_30pct: createRealizedSupplyPattern(this, 'loss_ge_30pct'),
|
_30pct: createRealizedSupplyPattern(this, 'utxos_over_30pct_in_loss'),
|
||||||
_40pct: createRealizedSupplyPattern(this, 'loss_ge_40pct'),
|
_40pct: createRealizedSupplyPattern(this, 'utxos_over_40pct_in_loss'),
|
||||||
_50pct: createRealizedSupplyPattern(this, 'loss_ge_50pct'),
|
_50pct: createRealizedSupplyPattern(this, 'utxos_over_50pct_in_loss'),
|
||||||
_60pct: createRealizedSupplyPattern(this, 'loss_ge_60pct'),
|
_60pct: createRealizedSupplyPattern(this, 'utxos_over_60pct_in_loss'),
|
||||||
_70pct: createRealizedSupplyPattern(this, 'loss_ge_70pct'),
|
_70pct: createRealizedSupplyPattern(this, 'utxos_over_70pct_in_loss'),
|
||||||
_80pct: createRealizedSupplyPattern(this, 'loss_ge_80pct'),
|
_80pct: createRealizedSupplyPattern(this, 'utxos_over_80pct_in_loss'),
|
||||||
_90pct: createRealizedSupplyPattern(this, 'loss_ge_90pct'),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
matured: {
|
matured: {
|
||||||
@@ -8620,7 +8616,7 @@ class BrkClient extends BrkClientBase {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
address: {
|
address: {
|
||||||
geAmount: {
|
overAmount: {
|
||||||
_1sat: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_1sat'),
|
_1sat: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_1sat'),
|
||||||
_10sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_10sats'),
|
_10sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_10sats'),
|
||||||
_100sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_100sats'),
|
_100sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_over_100sats'),
|
||||||
@@ -8652,7 +8648,7 @@ class BrkClient extends BrkClientBase {
|
|||||||
_10kBtcTo100kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_10k_btc_under_100k_btc'),
|
_10kBtcTo100kBtc: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_10k_btc_under_100k_btc'),
|
||||||
_100kBtcOrMore: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_100k_btc'),
|
_100kBtcOrMore: createAddrOutputsRealizedSupplyPattern(this, 'addrs_above_100k_btc'),
|
||||||
},
|
},
|
||||||
ltAmount: {
|
underAmount: {
|
||||||
_10sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_10sats'),
|
_10sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_10sats'),
|
||||||
_100sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_100sats'),
|
_100sats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_100sats'),
|
||||||
_1kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_1k_sats'),
|
_1kSats: createAddrOutputsRealizedSupplyPattern(this, 'addrs_under_1k_sats'),
|
||||||
@@ -9084,6 +9080,36 @@ class BrkClient extends BrkClientBase {
|
|||||||
return this.getJson(`/api/metric/${metric}/${index}/latest`);
|
return this.getJson(`/api/metric/${metric}/${index}/latest`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get metric data length
|
||||||
|
*
|
||||||
|
* Returns the total number of data points for a metric at the given index.
|
||||||
|
*
|
||||||
|
* Endpoint: `GET /api/metric/{metric}/{index}/len`
|
||||||
|
*
|
||||||
|
* @param {Metric} metric - Metric name
|
||||||
|
* @param {Index} index - Aggregation index
|
||||||
|
* @returns {Promise<number>}
|
||||||
|
*/
|
||||||
|
async getMetricLen(metric, index) {
|
||||||
|
return this.getJson(`/api/metric/${metric}/${index}/len`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get metric version
|
||||||
|
*
|
||||||
|
* Returns the current version of a metric. Changes when the metric data is updated.
|
||||||
|
*
|
||||||
|
* Endpoint: `GET /api/metric/{metric}/{index}/version`
|
||||||
|
*
|
||||||
|
* @param {Metric} metric - Metric name
|
||||||
|
* @param {Index} index - Aggregation index
|
||||||
|
* @returns {Promise<Version>}
|
||||||
|
*/
|
||||||
|
async getMetricVersion(metric, index) {
|
||||||
|
return this.getJson(`/api/metric/${metric}/${index}/version`);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metrics catalog
|
* Metrics catalog
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -2863,7 +2863,7 @@ class OutputsRealizedSupplyUnrealizedPattern:
|
|||||||
self.outputs: UnspentPattern = UnspentPattern(client, _m(acc, 'utxo_count'))
|
self.outputs: UnspentPattern = UnspentPattern(client, _m(acc, 'utxo_count'))
|
||||||
self.realized: CapLossMvrvNuplPriceProfitSoprPattern = CapLossMvrvNuplPriceProfitSoprPattern(client, acc)
|
self.realized: CapLossMvrvNuplPriceProfitSoprPattern = CapLossMvrvNuplPriceProfitSoprPattern(client, acc)
|
||||||
self.supply: HalvedInTotalPattern = HalvedInTotalPattern(client, _m(acc, 'supply'))
|
self.supply: HalvedInTotalPattern = HalvedInTotalPattern(client, _m(acc, 'supply'))
|
||||||
self.unrealized: LossProfitPattern2 = LossProfitPattern2(client, _m(acc, 'unrealized'))
|
self.unrealized: LossProfitPattern = LossProfitPattern(client, _m(acc, 'unrealized'))
|
||||||
|
|
||||||
class _1m1w1y24hPattern(Generic[T]):
|
class _1m1w1y24hPattern(Generic[T]):
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
@@ -3158,7 +3158,7 @@ class InPattern:
|
|||||||
self.in_loss: RawPattern2[CentsSats] = RawPattern2(client, _m(acc, 'loss_raw'))
|
self.in_loss: RawPattern2[CentsSats] = RawPattern2(client, _m(acc, 'loss_raw'))
|
||||||
self.in_profit: RawPattern2[CentsSats] = RawPattern2(client, _m(acc, 'profit_raw'))
|
self.in_profit: RawPattern2[CentsSats] = RawPattern2(client, _m(acc, 'profit_raw'))
|
||||||
|
|
||||||
class LossProfitPattern2:
|
class LossProfitPattern:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, acc: str):
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
@@ -4450,7 +4450,7 @@ class MetricsTree_Market_Dca_Class_CostBasis:
|
|||||||
self.from_2025: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'dca_cost_basis_from_2025')
|
self.from_2025: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'dca_cost_basis_from_2025')
|
||||||
self.from_2026: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'dca_cost_basis_from_2026')
|
self.from_2026: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'dca_cost_basis_from_2026')
|
||||||
|
|
||||||
class MetricsTree_Market_Dca_Class_R#return:
|
class MetricsTree_Market_Dca_Class_Return:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
@@ -4473,7 +4473,7 @@ class MetricsTree_Market_Dca_Class:
|
|||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
self.stack: MetricsTree_Market_Dca_Class_Stack = MetricsTree_Market_Dca_Class_Stack(client)
|
self.stack: MetricsTree_Market_Dca_Class_Stack = MetricsTree_Market_Dca_Class_Stack(client)
|
||||||
self.cost_basis: MetricsTree_Market_Dca_Class_CostBasis = MetricsTree_Market_Dca_Class_CostBasis(client)
|
self.cost_basis: MetricsTree_Market_Dca_Class_CostBasis = MetricsTree_Market_Dca_Class_CostBasis(client)
|
||||||
self.r#return: MetricsTree_Market_Dca_Class_R#return = MetricsTree_Market_Dca_Class_R#return(client)
|
self.r#return: MetricsTree_Market_Dca_Class_Return = MetricsTree_Market_Dca_Class_Return(client)
|
||||||
|
|
||||||
class MetricsTree_Market_Dca:
|
class MetricsTree_Market_Dca:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
@@ -5044,7 +5044,7 @@ class MetricsTree_Distribution_Cohorts_Utxo_AgeRange:
|
|||||||
self._12y_to_15y: ActivityOutputsRealizedSupplyUnrealizedPattern = ActivityOutputsRealizedSupplyUnrealizedPattern(client, 'utxos_12y_to_15y_old')
|
self._12y_to_15y: ActivityOutputsRealizedSupplyUnrealizedPattern = ActivityOutputsRealizedSupplyUnrealizedPattern(client, 'utxos_12y_to_15y_old')
|
||||||
self.from_15y: ActivityOutputsRealizedSupplyUnrealizedPattern = ActivityOutputsRealizedSupplyUnrealizedPattern(client, 'utxos_over_15y_old')
|
self.from_15y: ActivityOutputsRealizedSupplyUnrealizedPattern = ActivityOutputsRealizedSupplyUnrealizedPattern(client, 'utxos_over_15y_old')
|
||||||
|
|
||||||
class MetricsTree_Distribution_Cohorts_Utxo_MaxAge:
|
class MetricsTree_Distribution_Cohorts_Utxo_UnderAge:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
@@ -5067,7 +5067,7 @@ class MetricsTree_Distribution_Cohorts_Utxo_MaxAge:
|
|||||||
self._12y: ActivityOutputsRealizedSupplyUnrealizedPattern2 = ActivityOutputsRealizedSupplyUnrealizedPattern2(client, 'utxos_under_12y_old')
|
self._12y: ActivityOutputsRealizedSupplyUnrealizedPattern2 = ActivityOutputsRealizedSupplyUnrealizedPattern2(client, 'utxos_under_12y_old')
|
||||||
self._15y: ActivityOutputsRealizedSupplyUnrealizedPattern2 = ActivityOutputsRealizedSupplyUnrealizedPattern2(client, 'utxos_under_15y_old')
|
self._15y: ActivityOutputsRealizedSupplyUnrealizedPattern2 = ActivityOutputsRealizedSupplyUnrealizedPattern2(client, 'utxos_under_15y_old')
|
||||||
|
|
||||||
class MetricsTree_Distribution_Cohorts_Utxo_MinAge:
|
class MetricsTree_Distribution_Cohorts_Utxo_OverAge:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
@@ -5123,7 +5123,7 @@ class MetricsTree_Distribution_Cohorts_Utxo_Class:
|
|||||||
self._2025: ActivityOutputsRealizedSupplyUnrealizedPattern2 = ActivityOutputsRealizedSupplyUnrealizedPattern2(client, 'class_2025')
|
self._2025: ActivityOutputsRealizedSupplyUnrealizedPattern2 = ActivityOutputsRealizedSupplyUnrealizedPattern2(client, 'class_2025')
|
||||||
self._2026: ActivityOutputsRealizedSupplyUnrealizedPattern2 = ActivityOutputsRealizedSupplyUnrealizedPattern2(client, 'class_2026')
|
self._2026: ActivityOutputsRealizedSupplyUnrealizedPattern2 = ActivityOutputsRealizedSupplyUnrealizedPattern2(client, 'class_2026')
|
||||||
|
|
||||||
class MetricsTree_Distribution_Cohorts_Utxo_GeAmount:
|
class MetricsTree_Distribution_Cohorts_Utxo_OverAmount:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
@@ -5161,7 +5161,7 @@ class MetricsTree_Distribution_Cohorts_Utxo_AmountRange:
|
|||||||
self._10k_btc_to_100k_btc: OutputsRealizedSupplyPattern = OutputsRealizedSupplyPattern(client, 'utxos_above_10k_btc_under_100k_btc')
|
self._10k_btc_to_100k_btc: OutputsRealizedSupplyPattern = OutputsRealizedSupplyPattern(client, 'utxos_above_10k_btc_under_100k_btc')
|
||||||
self._100k_btc_or_more: OutputsRealizedSupplyPattern = OutputsRealizedSupplyPattern(client, 'utxos_above_100k_btc')
|
self._100k_btc_or_more: OutputsRealizedSupplyPattern = OutputsRealizedSupplyPattern(client, 'utxos_above_100k_btc')
|
||||||
|
|
||||||
class MetricsTree_Distribution_Cohorts_Utxo_LtAmount:
|
class MetricsTree_Distribution_Cohorts_Utxo_UnderAmount:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
@@ -5199,66 +5199,64 @@ class MetricsTree_Distribution_Cohorts_Utxo_Profitability_Range:
|
|||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
self.profit_over_1000: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_1000pct_up')
|
self.over_1000pct_in_profit: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_1000pct_in_profit')
|
||||||
self.profit_500_to_1000: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_500pct_to_1000pct_up')
|
self._500pct_to_1000pct_in_profit: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_500pct_to_1000pct_in_profit')
|
||||||
self.profit_300_to_500: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_300pct_to_500pct_up')
|
self._300pct_to_500pct_in_profit: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_300pct_to_500pct_in_profit')
|
||||||
self.profit_200_to_300: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_200pct_to_300pct_up')
|
self._200pct_to_300pct_in_profit: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_200pct_to_300pct_in_profit')
|
||||||
self.profit_100_to_200: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_100pct_to_200pct_up')
|
self._100pct_to_200pct_in_profit: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_100pct_to_200pct_in_profit')
|
||||||
self.profit_90_to_100: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_90pct_to_100pct_up')
|
self._90pct_to_100pct_in_profit: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_90pct_to_100pct_in_profit')
|
||||||
self.profit_80_to_90: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_80pct_to_90pct_up')
|
self._80pct_to_90pct_in_profit: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_80pct_to_90pct_in_profit')
|
||||||
self.profit_70_to_80: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_70pct_to_80pct_up')
|
self._70pct_to_80pct_in_profit: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_70pct_to_80pct_in_profit')
|
||||||
self.profit_60_to_70: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_60pct_to_70pct_up')
|
self._60pct_to_70pct_in_profit: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_60pct_to_70pct_in_profit')
|
||||||
self.profit_50_to_60: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_50pct_to_60pct_up')
|
self._50pct_to_60pct_in_profit: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_50pct_to_60pct_in_profit')
|
||||||
self.profit_40_to_50: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_40pct_to_50pct_up')
|
self._40pct_to_50pct_in_profit: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_40pct_to_50pct_in_profit')
|
||||||
self.profit_30_to_40: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_30pct_to_40pct_up')
|
self._30pct_to_40pct_in_profit: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_30pct_to_40pct_in_profit')
|
||||||
self.profit_20_to_30: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_20pct_to_30pct_up')
|
self._20pct_to_30pct_in_profit: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_20pct_to_30pct_in_profit')
|
||||||
self.profit_10_to_20: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_10pct_to_20pct_up')
|
self._10pct_to_20pct_in_profit: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_10pct_to_20pct_in_profit')
|
||||||
self.profit_0_to_10: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_0pct_to_10pct_up')
|
self._0pct_to_10pct_in_profit: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_0pct_to_10pct_in_profit')
|
||||||
self.loss_0_to_10: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_0pct_to_10pct_down')
|
self._0pct_to_10pct_in_loss: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_0pct_to_10pct_in_loss')
|
||||||
self.loss_10_to_20: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_10pct_to_20pct_down')
|
self._10pct_to_20pct_in_loss: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_10pct_to_20pct_in_loss')
|
||||||
self.loss_20_to_30: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_20pct_to_30pct_down')
|
self._20pct_to_30pct_in_loss: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_20pct_to_30pct_in_loss')
|
||||||
self.loss_30_to_40: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_30pct_to_40pct_down')
|
self._30pct_to_40pct_in_loss: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_30pct_to_40pct_in_loss')
|
||||||
self.loss_40_to_50: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_40pct_to_50pct_down')
|
self._40pct_to_50pct_in_loss: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_40pct_to_50pct_in_loss')
|
||||||
self.loss_50_to_60: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_50pct_to_60pct_down')
|
self._50pct_to_60pct_in_loss: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_50pct_to_60pct_in_loss')
|
||||||
self.loss_60_to_70: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_60pct_to_70pct_down')
|
self._60pct_to_70pct_in_loss: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_60pct_to_70pct_in_loss')
|
||||||
self.loss_70_to_80: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_70pct_to_80pct_down')
|
self._70pct_to_80pct_in_loss: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_70pct_to_80pct_in_loss')
|
||||||
self.loss_80_to_90: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_80pct_to_90pct_down')
|
self._80pct_to_90pct_in_loss: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_80pct_to_90pct_in_loss')
|
||||||
self.loss_90_to_100: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_90pct_to_100pct_down')
|
self._90pct_to_100pct_in_loss: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_90pct_to_100pct_in_loss')
|
||||||
|
|
||||||
class MetricsTree_Distribution_Cohorts_Utxo_Profitability_Profit:
|
class MetricsTree_Distribution_Cohorts_Utxo_Profitability_Profit:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
self.breakeven: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_breakeven')
|
self.breakeven: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_in_profit')
|
||||||
self._10pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_10pct')
|
self._10pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_10pct_in_profit')
|
||||||
self._20pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_20pct')
|
self._20pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_20pct_in_profit')
|
||||||
self._30pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_30pct')
|
self._30pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_30pct_in_profit')
|
||||||
self._40pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_40pct')
|
self._40pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_40pct_in_profit')
|
||||||
self._50pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_50pct')
|
self._50pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_50pct_in_profit')
|
||||||
self._60pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_60pct')
|
self._60pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_60pct_in_profit')
|
||||||
self._70pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_70pct')
|
self._70pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_70pct_in_profit')
|
||||||
self._80pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_80pct')
|
self._80pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_80pct_in_profit')
|
||||||
self._90pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_90pct')
|
self._90pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_90pct_in_profit')
|
||||||
self._100pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_100pct')
|
self._100pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_100pct_in_profit')
|
||||||
self._200pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_200pct')
|
self._200pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_200pct_in_profit')
|
||||||
self._300pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_300pct')
|
self._300pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_300pct_in_profit')
|
||||||
self._500pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_500pct')
|
self._500pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_500pct_in_profit')
|
||||||
self._1000pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'profit_ge_1000pct')
|
|
||||||
|
|
||||||
class MetricsTree_Distribution_Cohorts_Utxo_Profitability_Loss:
|
class MetricsTree_Distribution_Cohorts_Utxo_Profitability_Loss:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
self.breakeven: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_ge_breakeven')
|
self.breakeven: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_in_loss')
|
||||||
self._10pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_ge_10pct')
|
self._10pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_10pct_in_loss')
|
||||||
self._20pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_ge_20pct')
|
self._20pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_20pct_in_loss')
|
||||||
self._30pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_ge_30pct')
|
self._30pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_30pct_in_loss')
|
||||||
self._40pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_ge_40pct')
|
self._40pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_40pct_in_loss')
|
||||||
self._50pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_ge_50pct')
|
self._50pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_50pct_in_loss')
|
||||||
self._60pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_ge_60pct')
|
self._60pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_60pct_in_loss')
|
||||||
self._70pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_ge_70pct')
|
self._70pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_70pct_in_loss')
|
||||||
self._80pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_ge_80pct')
|
self._80pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'utxos_over_80pct_in_loss')
|
||||||
self._90pct: RealizedSupplyPattern = RealizedSupplyPattern(client, 'loss_ge_90pct')
|
|
||||||
|
|
||||||
class MetricsTree_Distribution_Cohorts_Utxo_Profitability:
|
class MetricsTree_Distribution_Cohorts_Utxo_Profitability:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
@@ -5302,18 +5300,18 @@ class MetricsTree_Distribution_Cohorts_Utxo:
|
|||||||
self.sth: MetricsTree_Distribution_Cohorts_Utxo_Sth = MetricsTree_Distribution_Cohorts_Utxo_Sth(client)
|
self.sth: MetricsTree_Distribution_Cohorts_Utxo_Sth = MetricsTree_Distribution_Cohorts_Utxo_Sth(client)
|
||||||
self.lth: MetricsTree_Distribution_Cohorts_Utxo_Lth = MetricsTree_Distribution_Cohorts_Utxo_Lth(client)
|
self.lth: MetricsTree_Distribution_Cohorts_Utxo_Lth = MetricsTree_Distribution_Cohorts_Utxo_Lth(client)
|
||||||
self.age_range: MetricsTree_Distribution_Cohorts_Utxo_AgeRange = MetricsTree_Distribution_Cohorts_Utxo_AgeRange(client)
|
self.age_range: MetricsTree_Distribution_Cohorts_Utxo_AgeRange = MetricsTree_Distribution_Cohorts_Utxo_AgeRange(client)
|
||||||
self.max_age: MetricsTree_Distribution_Cohorts_Utxo_MaxAge = MetricsTree_Distribution_Cohorts_Utxo_MaxAge(client)
|
self.under_age: MetricsTree_Distribution_Cohorts_Utxo_UnderAge = MetricsTree_Distribution_Cohorts_Utxo_UnderAge(client)
|
||||||
self.min_age: MetricsTree_Distribution_Cohorts_Utxo_MinAge = MetricsTree_Distribution_Cohorts_Utxo_MinAge(client)
|
self.over_age: MetricsTree_Distribution_Cohorts_Utxo_OverAge = MetricsTree_Distribution_Cohorts_Utxo_OverAge(client)
|
||||||
self.epoch: MetricsTree_Distribution_Cohorts_Utxo_Epoch = MetricsTree_Distribution_Cohorts_Utxo_Epoch(client)
|
self.epoch: MetricsTree_Distribution_Cohorts_Utxo_Epoch = MetricsTree_Distribution_Cohorts_Utxo_Epoch(client)
|
||||||
self.class: MetricsTree_Distribution_Cohorts_Utxo_Class = MetricsTree_Distribution_Cohorts_Utxo_Class(client)
|
self.class: MetricsTree_Distribution_Cohorts_Utxo_Class = MetricsTree_Distribution_Cohorts_Utxo_Class(client)
|
||||||
self.ge_amount: MetricsTree_Distribution_Cohorts_Utxo_GeAmount = MetricsTree_Distribution_Cohorts_Utxo_GeAmount(client)
|
self.over_amount: MetricsTree_Distribution_Cohorts_Utxo_OverAmount = MetricsTree_Distribution_Cohorts_Utxo_OverAmount(client)
|
||||||
self.amount_range: MetricsTree_Distribution_Cohorts_Utxo_AmountRange = MetricsTree_Distribution_Cohorts_Utxo_AmountRange(client)
|
self.amount_range: MetricsTree_Distribution_Cohorts_Utxo_AmountRange = MetricsTree_Distribution_Cohorts_Utxo_AmountRange(client)
|
||||||
self.lt_amount: MetricsTree_Distribution_Cohorts_Utxo_LtAmount = MetricsTree_Distribution_Cohorts_Utxo_LtAmount(client)
|
self.under_amount: MetricsTree_Distribution_Cohorts_Utxo_UnderAmount = MetricsTree_Distribution_Cohorts_Utxo_UnderAmount(client)
|
||||||
self.r#type: MetricsTree_Distribution_Cohorts_Utxo_Type = MetricsTree_Distribution_Cohorts_Utxo_Type(client)
|
self.r#type: MetricsTree_Distribution_Cohorts_Utxo_Type = MetricsTree_Distribution_Cohorts_Utxo_Type(client)
|
||||||
self.profitability: MetricsTree_Distribution_Cohorts_Utxo_Profitability = MetricsTree_Distribution_Cohorts_Utxo_Profitability(client)
|
self.profitability: MetricsTree_Distribution_Cohorts_Utxo_Profitability = MetricsTree_Distribution_Cohorts_Utxo_Profitability(client)
|
||||||
self.matured: MetricsTree_Distribution_Cohorts_Utxo_Matured = MetricsTree_Distribution_Cohorts_Utxo_Matured(client)
|
self.matured: MetricsTree_Distribution_Cohorts_Utxo_Matured = MetricsTree_Distribution_Cohorts_Utxo_Matured(client)
|
||||||
|
|
||||||
class MetricsTree_Distribution_Cohorts_Address_GeAmount:
|
class MetricsTree_Distribution_Cohorts_Address_OverAmount:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
@@ -5351,7 +5349,7 @@ class MetricsTree_Distribution_Cohorts_Address_AmountRange:
|
|||||||
self._10k_btc_to_100k_btc: AddrOutputsRealizedSupplyPattern = AddrOutputsRealizedSupplyPattern(client, 'addrs_above_10k_btc_under_100k_btc')
|
self._10k_btc_to_100k_btc: AddrOutputsRealizedSupplyPattern = AddrOutputsRealizedSupplyPattern(client, 'addrs_above_10k_btc_under_100k_btc')
|
||||||
self._100k_btc_or_more: AddrOutputsRealizedSupplyPattern = AddrOutputsRealizedSupplyPattern(client, 'addrs_above_100k_btc')
|
self._100k_btc_or_more: AddrOutputsRealizedSupplyPattern = AddrOutputsRealizedSupplyPattern(client, 'addrs_above_100k_btc')
|
||||||
|
|
||||||
class MetricsTree_Distribution_Cohorts_Address_LtAmount:
|
class MetricsTree_Distribution_Cohorts_Address_UnderAmount:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
@@ -5373,9 +5371,9 @@ class MetricsTree_Distribution_Cohorts_Address:
|
|||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
self.ge_amount: MetricsTree_Distribution_Cohorts_Address_GeAmount = MetricsTree_Distribution_Cohorts_Address_GeAmount(client)
|
self.over_amount: MetricsTree_Distribution_Cohorts_Address_OverAmount = MetricsTree_Distribution_Cohorts_Address_OverAmount(client)
|
||||||
self.amount_range: MetricsTree_Distribution_Cohorts_Address_AmountRange = MetricsTree_Distribution_Cohorts_Address_AmountRange(client)
|
self.amount_range: MetricsTree_Distribution_Cohorts_Address_AmountRange = MetricsTree_Distribution_Cohorts_Address_AmountRange(client)
|
||||||
self.lt_amount: MetricsTree_Distribution_Cohorts_Address_LtAmount = MetricsTree_Distribution_Cohorts_Address_LtAmount(client)
|
self.under_amount: MetricsTree_Distribution_Cohorts_Address_UnderAmount = MetricsTree_Distribution_Cohorts_Address_UnderAmount(client)
|
||||||
|
|
||||||
class MetricsTree_Distribution_Cohorts:
|
class MetricsTree_Distribution_Cohorts:
|
||||||
"""Metrics tree node."""
|
"""Metrics tree node."""
|
||||||
@@ -5956,7 +5954,7 @@ class BrkClient(BrkClientBase):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MAX_AGE_NAMES = {
|
UNDER_AGE_NAMES = {
|
||||||
"_1w": {
|
"_1w": {
|
||||||
"id": "under_1w_old",
|
"id": "under_1w_old",
|
||||||
"short": "<1w",
|
"short": "<1w",
|
||||||
@@ -6049,7 +6047,7 @@ class BrkClient(BrkClientBase):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MIN_AGE_NAMES = {
|
OVER_AGE_NAMES = {
|
||||||
"_1d": {
|
"_1d": {
|
||||||
"id": "over_1d_old",
|
"id": "over_1d_old",
|
||||||
"short": "1d+",
|
"short": "1d+",
|
||||||
@@ -6220,7 +6218,7 @@ class BrkClient(BrkClientBase):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GE_AMOUNT_NAMES = {
|
OVER_AMOUNT_NAMES = {
|
||||||
"_1sat": {
|
"_1sat": {
|
||||||
"id": "over_1sat",
|
"id": "over_1sat",
|
||||||
"short": "1+ sats",
|
"short": "1+ sats",
|
||||||
@@ -6288,7 +6286,7 @@ class BrkClient(BrkClientBase):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LT_AMOUNT_NAMES = {
|
UNDER_AMOUNT_NAMES = {
|
||||||
"_10sats": {
|
"_10sats": {
|
||||||
"id": "under_10sats",
|
"id": "under_10sats",
|
||||||
"short": "<10 sats",
|
"short": "<10 sats",
|
||||||
@@ -6612,6 +6610,22 @@ class BrkClient(BrkClientBase):
|
|||||||
Endpoint: `GET /api/metric/{metric}/{index}/latest`"""
|
Endpoint: `GET /api/metric/{metric}/{index}/latest`"""
|
||||||
return self.get_json(f'/api/metric/{metric}/{index}/latest')
|
return self.get_json(f'/api/metric/{metric}/{index}/latest')
|
||||||
|
|
||||||
|
def get_metric_len(self, metric: Metric, index: Index) -> float:
|
||||||
|
"""Get metric data length.
|
||||||
|
|
||||||
|
Returns the total number of data points for a metric at the given index.
|
||||||
|
|
||||||
|
Endpoint: `GET /api/metric/{metric}/{index}/len`"""
|
||||||
|
return self.get_json(f'/api/metric/{metric}/{index}/len')
|
||||||
|
|
||||||
|
def get_metric_version(self, metric: Metric, index: Index) -> Version:
|
||||||
|
"""Get metric version.
|
||||||
|
|
||||||
|
Returns the current version of a metric. Changes when the metric data is updated.
|
||||||
|
|
||||||
|
Endpoint: `GET /api/metric/{metric}/{index}/version`"""
|
||||||
|
return self.get_json(f'/api/metric/{metric}/{index}/version')
|
||||||
|
|
||||||
def get_metrics_tree(self) -> TreeNode:
|
def get_metrics_tree(self) -> TreeNode:
|
||||||
"""Metrics catalog.
|
"""Metrics catalog.
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,11 @@ Get the latest value:
|
|||||||
|
|
||||||
GET /api/metric/{metric}/{index}/latest
|
GET /api/metric/{metric}/{index}/latest
|
||||||
|
|
||||||
|
Get the data length or version:
|
||||||
|
|
||||||
|
GET /api/metric/{metric}/{index}/len
|
||||||
|
GET /api/metric/{metric}/{index}/version
|
||||||
|
|
||||||
Example — last 30 days of Bitcoin closing price:
|
Example — last 30 days of Bitcoin closing price:
|
||||||
|
|
||||||
GET /api/metric/price/day?start=-30
|
GET /api/metric/price/day?start=-30
|
||||||
|
|||||||
Reference in New Issue
Block a user