computer: snapshot

This commit is contained in:
nym21
2026-02-06 21:40:34 +01:00
parent ed10e21ee9
commit 9cba9bfec4
19 changed files with 443 additions and 250 deletions
+45 -29
View File
@@ -858,7 +858,7 @@ impl<T: DeserializeOwned> MetricPattern<T> for MetricPattern32<T> { fn get(&self
// Reusable pattern structs
/// Pattern struct for repeated tree structure.
pub struct AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern {
pub struct AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern {
pub adjusted_sopr: MetricPattern6<StoredF64>,
pub adjusted_sopr_30d_ema: MetricPattern6<StoredF64>,
pub adjusted_sopr_7d_ema: MetricPattern6<StoredF64>,
@@ -866,6 +866,8 @@ pub struct AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSe
pub adjusted_value_destroyed: MetricPattern1<Dollars>,
pub cap_raw: MetricPattern11<CentsSats>,
pub capitulation_flow: MetricPattern1<Dollars>,
pub ceiling_price: DollarsSatsPattern,
pub floor_price: DollarsSatsPattern,
pub investor_cap_raw: MetricPattern11<CentsSquaredSats>,
pub investor_price: DollarsSatsPattern,
pub investor_price_cents: MetricPattern1<CentsUnsigned>,
@@ -914,7 +916,7 @@ pub struct AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSe
pub value_destroyed: MetricPattern1<Dollars>,
}
impl AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern {
impl AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
@@ -925,6 +927,8 @@ impl AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSopr
adjusted_value_destroyed: MetricPattern1::new(client.clone(), _m(&acc, "adjusted_value_destroyed")),
cap_raw: MetricPattern11::new(client.clone(), _m(&acc, "cap_raw")),
capitulation_flow: MetricPattern1::new(client.clone(), _m(&acc, "capitulation_flow")),
ceiling_price: DollarsSatsPattern::new(client.clone(), _m(&acc, "ceiling_price")),
floor_price: DollarsSatsPattern::new(client.clone(), _m(&acc, "floor_price")),
investor_cap_raw: MetricPattern11::new(client.clone(), _m(&acc, "investor_cap_raw")),
investor_price: DollarsSatsPattern::new(client.clone(), _m(&acc, "investor_price")),
investor_price_cents: MetricPattern1::new(client.clone(), _m(&acc, "investor_price_cents")),
@@ -976,7 +980,7 @@ impl AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSopr
}
/// Pattern struct for repeated tree structure.
pub struct AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 {
pub struct AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 {
pub adjusted_sopr: MetricPattern6<StoredF64>,
pub adjusted_sopr_30d_ema: MetricPattern6<StoredF64>,
pub adjusted_sopr_7d_ema: MetricPattern6<StoredF64>,
@@ -984,6 +988,8 @@ pub struct AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSe
pub adjusted_value_destroyed: MetricPattern1<Dollars>,
pub cap_raw: MetricPattern11<CentsSats>,
pub capitulation_flow: MetricPattern1<Dollars>,
pub ceiling_price: DollarsSatsPattern,
pub floor_price: DollarsSatsPattern,
pub investor_cap_raw: MetricPattern11<CentsSquaredSats>,
pub investor_price: DollarsSatsPattern,
pub investor_price_cents: MetricPattern1<CentsUnsigned>,
@@ -1030,7 +1036,7 @@ pub struct AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSe
pub value_destroyed: MetricPattern1<Dollars>,
}
impl AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 {
impl AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
@@ -1041,6 +1047,8 @@ impl AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSopr
adjusted_value_destroyed: MetricPattern1::new(client.clone(), _m(&acc, "adjusted_value_destroyed")),
cap_raw: MetricPattern11::new(client.clone(), _m(&acc, "cap_raw")),
capitulation_flow: MetricPattern1::new(client.clone(), _m(&acc, "capitulation_flow")),
ceiling_price: DollarsSatsPattern::new(client.clone(), _m(&acc, "ceiling_price")),
floor_price: DollarsSatsPattern::new(client.clone(), _m(&acc, "floor_price")),
investor_cap_raw: MetricPattern11::new(client.clone(), _m(&acc, "investor_cap_raw")),
investor_price: DollarsSatsPattern::new(client.clone(), _m(&acc, "investor_price")),
investor_price_cents: MetricPattern1::new(client.clone(), _m(&acc, "investor_price_cents")),
@@ -1090,9 +1098,11 @@ impl AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSopr
}
/// Pattern struct for repeated tree structure.
pub struct CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 {
pub struct CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 {
pub cap_raw: MetricPattern11<CentsSats>,
pub capitulation_flow: MetricPattern1<Dollars>,
pub ceiling_price: DollarsSatsPattern,
pub floor_price: DollarsSatsPattern,
pub investor_cap_raw: MetricPattern11<CentsSquaredSats>,
pub investor_price: DollarsSatsPattern,
pub investor_price_cents: MetricPattern1<CentsUnsigned>,
@@ -1141,12 +1151,14 @@ pub struct CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTo
pub value_destroyed: MetricPattern1<Dollars>,
}
impl CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 {
impl CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
cap_raw: MetricPattern11::new(client.clone(), _m(&acc, "cap_raw")),
capitulation_flow: MetricPattern1::new(client.clone(), _m(&acc, "capitulation_flow")),
ceiling_price: DollarsSatsPattern::new(client.clone(), _m(&acc, "ceiling_price")),
floor_price: DollarsSatsPattern::new(client.clone(), _m(&acc, "floor_price")),
investor_cap_raw: MetricPattern11::new(client.clone(), _m(&acc, "investor_cap_raw")),
investor_price: DollarsSatsPattern::new(client.clone(), _m(&acc, "investor_price")),
investor_price_cents: MetricPattern1::new(client.clone(), _m(&acc, "investor_price_cents")),
@@ -1198,9 +1210,11 @@ impl CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalVal
}
/// Pattern struct for repeated tree structure.
pub struct CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern {
pub struct CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern {
pub cap_raw: MetricPattern11<CentsSats>,
pub capitulation_flow: MetricPattern1<Dollars>,
pub ceiling_price: DollarsSatsPattern,
pub floor_price: DollarsSatsPattern,
pub investor_cap_raw: MetricPattern11<CentsSquaredSats>,
pub investor_price: DollarsSatsPattern,
pub investor_price_cents: MetricPattern1<CentsUnsigned>,
@@ -1247,12 +1261,14 @@ pub struct CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTo
pub value_destroyed: MetricPattern1<Dollars>,
}
impl CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern {
impl CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
cap_raw: MetricPattern11::new(client.clone(), _m(&acc, "cap_raw")),
capitulation_flow: MetricPattern1::new(client.clone(), _m(&acc, "capitulation_flow")),
ceiling_price: DollarsSatsPattern::new(client.clone(), _m(&acc, "ceiling_price")),
floor_price: DollarsSatsPattern::new(client.clone(), _m(&acc, "floor_price")),
investor_cap_raw: MetricPattern11::new(client.clone(), _m(&acc, "investor_cap_raw")),
investor_price: DollarsSatsPattern::new(client.clone(), _m(&acc, "investor_price")),
investor_price_cents: MetricPattern1::new(client.clone(), _m(&acc, "investor_price_cents")),
@@ -2032,7 +2048,7 @@ pub struct ActivityAddrCostOutputsRealizedRelativeSupplyUnrealizedPattern {
pub addr_count_30d_change: MetricPattern4<StoredF64>,
pub cost_basis: MaxMinPattern,
pub outputs: UtxoPattern,
pub realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern,
pub realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern,
pub relative: InvestedNegNetNuplSupplyUnrealizedPattern,
pub supply: _30dHalvedTotalPattern,
pub unrealized: GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern,
@@ -2047,7 +2063,7 @@ impl ActivityAddrCostOutputsRealizedRelativeSupplyUnrealizedPattern {
addr_count_30d_change: MetricPattern4::new(client.clone(), _m(&acc, "addr_count_30d_change")),
cost_basis: MaxMinPattern::new(client.clone(), acc.clone()),
outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")),
realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern::new(client.clone(), acc.clone()),
realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern::new(client.clone(), acc.clone()),
relative: InvestedNegNetNuplSupplyUnrealizedPattern::new(client.clone(), acc.clone()),
supply: _30dHalvedTotalPattern::new(client.clone(), acc.clone()),
unrealized: GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern::new(client.clone(), acc.clone()),
@@ -2176,7 +2192,7 @@ pub struct ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern {
pub activity: CoinblocksCoindaysSatblocksSatdaysSentPattern,
pub cost_basis: InvestedMaxMinPercentilesSpotPattern,
pub outputs: UtxoPattern,
pub realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2,
pub realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2,
pub relative: InvestedNegNetSupplyUnrealizedPattern,
pub supply: _30dHalvedTotalPattern,
pub unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern,
@@ -2189,7 +2205,7 @@ impl ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern {
activity: CoinblocksCoindaysSatblocksSatdaysSentPattern::new(client.clone(), acc.clone()),
cost_basis: InvestedMaxMinPercentilesSpotPattern::new(client.clone(), acc.clone()),
outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")),
realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2::new(client.clone(), acc.clone()),
realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2::new(client.clone(), acc.clone()),
relative: InvestedNegNetSupplyUnrealizedPattern::new(client.clone(), acc.clone()),
supply: _30dHalvedTotalPattern::new(client.clone(), acc.clone()),
unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern::new(client.clone(), acc.clone()),
@@ -2202,7 +2218,7 @@ pub struct ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern5 {
pub activity: CoinblocksCoindaysSatblocksSatdaysSentPattern,
pub cost_basis: MaxMinPattern,
pub outputs: UtxoPattern,
pub realized: AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2,
pub realized: AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2,
pub relative: InvestedNegNetNuplSupplyUnrealizedPattern3,
pub supply: _30dHalvedTotalPattern,
pub unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern,
@@ -2215,7 +2231,7 @@ impl ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern5 {
activity: CoinblocksCoindaysSatblocksSatdaysSentPattern::new(client.clone(), acc.clone()),
cost_basis: MaxMinPattern::new(client.clone(), acc.clone()),
outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")),
realized: AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2::new(client.clone(), acc.clone()),
realized: AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2::new(client.clone(), acc.clone()),
relative: InvestedNegNetNuplSupplyUnrealizedPattern3::new(client.clone(), acc.clone()),
supply: _30dHalvedTotalPattern::new(client.clone(), acc.clone()),
unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern::new(client.clone(), acc.clone()),
@@ -2228,7 +2244,7 @@ pub struct ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 {
pub activity: CoinblocksCoindaysSatblocksSatdaysSentPattern,
pub cost_basis: MaxMinPattern,
pub outputs: UtxoPattern,
pub realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern,
pub realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern,
pub relative: InvestedNegNetNuplSupplyUnrealizedPattern,
pub supply: _30dHalvedTotalPattern,
pub unrealized: GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern,
@@ -2241,7 +2257,7 @@ impl ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4 {
activity: CoinblocksCoindaysSatblocksSatdaysSentPattern::new(client.clone(), acc.clone()),
cost_basis: MaxMinPattern::new(client.clone(), acc.clone()),
outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")),
realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern::new(client.clone(), acc.clone()),
realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern::new(client.clone(), acc.clone()),
relative: InvestedNegNetNuplSupplyUnrealizedPattern::new(client.clone(), acc.clone()),
supply: _30dHalvedTotalPattern::new(client.clone(), acc.clone()),
unrealized: GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern::new(client.clone(), acc.clone()),
@@ -2254,7 +2270,7 @@ pub struct ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern6 {
pub activity: CoinblocksCoindaysSatblocksSatdaysSentPattern,
pub cost_basis: MaxMinPattern,
pub outputs: UtxoPattern,
pub realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern,
pub realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern,
pub relative: InvestedNegNetNuplSupplyUnrealizedPattern3,
pub supply: _30dHalvedTotalPattern,
pub unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern,
@@ -2267,7 +2283,7 @@ impl ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern6 {
activity: CoinblocksCoindaysSatblocksSatdaysSentPattern::new(client.clone(), acc.clone()),
cost_basis: MaxMinPattern::new(client.clone(), acc.clone()),
outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")),
realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern::new(client.clone(), acc.clone()),
realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern::new(client.clone(), acc.clone()),
relative: InvestedNegNetNuplSupplyUnrealizedPattern3::new(client.clone(), acc.clone()),
supply: _30dHalvedTotalPattern::new(client.clone(), acc.clone()),
unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern::new(client.clone(), acc.clone()),
@@ -2280,7 +2296,7 @@ pub struct ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 {
pub activity: CoinblocksCoindaysSatblocksSatdaysSentPattern,
pub cost_basis: MaxMinPattern,
pub outputs: UtxoPattern,
pub realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern,
pub realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern,
pub relative: InvestedSupplyPattern,
pub supply: _30dHalvedTotalPattern,
pub unrealized: GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern,
@@ -2293,7 +2309,7 @@ impl ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3 {
activity: CoinblocksCoindaysSatblocksSatdaysSentPattern::new(client.clone(), acc.clone()),
cost_basis: MaxMinPattern::new(client.clone(), acc.clone()),
outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")),
realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern::new(client.clone(), acc.clone()),
realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern::new(client.clone(), acc.clone()),
relative: InvestedSupplyPattern::new(client.clone(), acc.clone()),
supply: _30dHalvedTotalPattern::new(client.clone(), acc.clone()),
unrealized: GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern::new(client.clone(), acc.clone()),
@@ -2306,7 +2322,7 @@ pub struct ActivityCostOutputsRealizedSupplyUnrealizedPattern {
pub activity: CoinblocksCoindaysSatblocksSatdaysSentPattern,
pub cost_basis: MaxMinPattern,
pub outputs: UtxoPattern,
pub realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern,
pub realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern,
pub supply: _30dHalvedTotalPattern,
pub unrealized: GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern,
}
@@ -2318,7 +2334,7 @@ impl ActivityCostOutputsRealizedSupplyUnrealizedPattern {
activity: CoinblocksCoindaysSatblocksSatdaysSentPattern::new(client.clone(), acc.clone()),
cost_basis: MaxMinPattern::new(client.clone(), acc.clone()),
outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")),
realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern::new(client.clone(), acc.clone()),
realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern::new(client.clone(), acc.clone()),
supply: _30dHalvedTotalPattern::new(client.clone(), acc.clone()),
unrealized: GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern::new(client.clone(), acc.clone()),
}
@@ -5240,7 +5256,7 @@ pub struct MetricsTree_Distribution_UtxoCohorts_All {
pub supply: _30dHalvedTotalPattern,
pub outputs: UtxoPattern,
pub activity: CoinblocksCoindaysSatblocksSatdaysSentPattern,
pub realized: AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern,
pub realized: AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern,
pub unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern,
pub cost_basis: InvestedMaxMinPercentilesSpotPattern,
pub relative: MetricsTree_Distribution_UtxoCohorts_All_Relative,
@@ -5252,7 +5268,7 @@ impl MetricsTree_Distribution_UtxoCohorts_All {
supply: _30dHalvedTotalPattern::new(client.clone(), "".to_string()),
outputs: UtxoPattern::new(client.clone(), "utxo_count".to_string()),
activity: CoinblocksCoindaysSatblocksSatdaysSentPattern::new(client.clone(), "".to_string()),
realized: AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern::new(client.clone(), "".to_string()),
realized: AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern::new(client.clone(), "".to_string()),
unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern::new(client.clone(), "".to_string()),
cost_basis: InvestedMaxMinPercentilesSpotPattern::new(client.clone(), "".to_string()),
relative: MetricsTree_Distribution_UtxoCohorts_All_Relative::new(client.clone(), format!("{base_path}_relative")),
@@ -5565,7 +5581,7 @@ pub struct MetricsTree_Distribution_UtxoCohorts_Term_Short {
pub supply: _30dHalvedTotalPattern,
pub outputs: UtxoPattern,
pub activity: CoinblocksCoindaysSatblocksSatdaysSentPattern,
pub realized: AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern,
pub realized: AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern,
pub unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern,
pub cost_basis: InvestedMaxMinPercentilesSpotPattern,
pub relative: InvestedNegNetNuplSupplyUnrealizedPattern4,
@@ -5577,7 +5593,7 @@ impl MetricsTree_Distribution_UtxoCohorts_Term_Short {
supply: _30dHalvedTotalPattern::new(client.clone(), "sth".to_string()),
outputs: UtxoPattern::new(client.clone(), "sth_utxo_count".to_string()),
activity: CoinblocksCoindaysSatblocksSatdaysSentPattern::new(client.clone(), "sth".to_string()),
realized: AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern::new(client.clone(), "sth".to_string()),
realized: AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern::new(client.clone(), "sth".to_string()),
unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern::new(client.clone(), "sth".to_string()),
cost_basis: InvestedMaxMinPercentilesSpotPattern::new(client.clone(), "sth".to_string()),
relative: InvestedNegNetNuplSupplyUnrealizedPattern4::new(client.clone(), "sth".to_string()),
@@ -5590,7 +5606,7 @@ pub struct MetricsTree_Distribution_UtxoCohorts_Term_Long {
pub supply: _30dHalvedTotalPattern,
pub outputs: UtxoPattern,
pub activity: CoinblocksCoindaysSatblocksSatdaysSentPattern,
pub realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2,
pub realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2,
pub unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern,
pub cost_basis: InvestedMaxMinPercentilesSpotPattern,
pub relative: InvestedNegNetNuplSupplyUnrealizedPattern4,
@@ -5602,7 +5618,7 @@ impl MetricsTree_Distribution_UtxoCohorts_Term_Long {
supply: _30dHalvedTotalPattern::new(client.clone(), "lth".to_string()),
outputs: UtxoPattern::new(client.clone(), "lth_utxo_count".to_string()),
activity: CoinblocksCoindaysSatblocksSatdaysSentPattern::new(client.clone(), "lth".to_string()),
realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2::new(client.clone(), "lth".to_string()),
realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2::new(client.clone(), "lth".to_string()),
unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern::new(client.clone(), "lth".to_string()),
cost_basis: InvestedMaxMinPercentilesSpotPattern::new(client.clone(), "lth".to_string()),
relative: InvestedNegNetNuplSupplyUnrealizedPattern4::new(client.clone(), "lth".to_string()),
@@ -6051,7 +6067,7 @@ pub struct BrkClient {
impl BrkClient {
/// Client version.
pub const VERSION: &'static str = "v0.1.5";
pub const VERSION: &'static str = "v0.1.6";
/// Create a new client with the given base URL.
pub fn new(base_url: impl Into<String>) -> Self {
@@ -17,7 +17,8 @@ use crate::{
internal::{
CentsUnsignedToDollars, ComputedFromDateLast, ComputedFromDateRatio,
ComputedFromHeightLast, ComputedFromHeightSum, ComputedFromHeightSumCum, DollarsMinus,
DollarsPlus, LazyBinaryFromHeightSum, LazyBinaryFromHeightSumCum,
DollarsPlus, DollarsSquaredDivide, LazyBinaryFromHeightSum, LazyBinaryFromHeightSumCum,
LazyBinaryPriceFromHeight,
LazyComputedValueFromHeightSumCum, LazyFromDateLast, LazyFromHeightLast, LazyFromHeightSum,
LazyFromHeightSumCum, LazyPriceFromCents, PercentageDollarsF32, PriceFromHeight,
StoredF32Identity, ValueFromDateLast,
@@ -43,6 +44,10 @@ pub struct RealizedMetrics {
pub investor_price: LazyPriceFromCents,
pub investor_price_extra: ComputedFromDateRatio,
// === Floor/Ceiling Price Bands (lazy: realized²/investor, investor²/realized) ===
pub floor_price: LazyBinaryPriceFromHeight,
pub ceiling_price: LazyBinaryPriceFromHeight,
// === Raw values for aggregation (needed to compute investor_price for aggregated cohorts) ===
/// Raw Σ(price × sats) for realized cap aggregation
pub cap_raw: BytesVec<Height, CentsSats>,
@@ -286,6 +291,26 @@ impl RealizedMetrics {
extended,
)?;
// Floor price = realized² / investor (lower band)
let floor_price = LazyBinaryPriceFromHeight::forced_import::<DollarsSquaredDivide>(
cfg.db,
&cfg.name("floor_price"),
cfg.version,
realized_price.dollars.height.boxed_clone(),
investor_price.dollars.height.boxed_clone(),
cfg.indexes,
)?;
// Ceiling price = investor² / realized (upper band)
let ceiling_price = LazyBinaryPriceFromHeight::forced_import::<DollarsSquaredDivide>(
cfg.db,
&cfg.name("ceiling_price"),
cfg.version,
investor_price.dollars.height.boxed_clone(),
realized_price.dollars.height.boxed_clone(),
cfg.indexes,
)?;
// Raw values for aggregation
let cap_raw = BytesVec::forced_import(cfg.db, &cfg.name("cap_raw"), cfg.version)?;
let investor_cap_raw =
@@ -429,6 +454,11 @@ impl RealizedMetrics {
investor_price_cents,
investor_price,
investor_price_extra,
// === Floor/Ceiling Price Bands ===
floor_price,
ceiling_price,
cap_raw,
investor_cap_raw,
@@ -1148,6 +1178,10 @@ impl RealizedMetrics {
)?;
}
// Floor/ceiling price bands (derive stored dateindex from lazy height)
self.floor_price.dollars.derive_from(indexes, starting_indexes, exit)?;
self.ceiling_price.dollars.derive_from(indexes, starting_indexes, exit)?;
Ok(())
}
}
@@ -3,9 +3,7 @@ use std::path::Path;
use brk_error::Result;
use brk_types::{Age, CentsSats, CentsUnsigned, CostBasisSnapshot, Height, Sats, SupplyState};
use super::super::cost_basis::{
CachedUnrealizedState, CostBasisData, Percentiles, RealizedState, UnrealizedState,
};
use super::super::cost_basis::{CostBasisData, Percentiles, RealizedState, UnrealizedState};
#[derive(Clone)]
pub struct CohortState {
@@ -15,9 +13,6 @@ pub struct CohortState {
pub satblocks_destroyed: Sats,
pub satdays_destroyed: Sats,
cost_basis_data: Option<CostBasisData>,
cached_unrealized: Option<CachedUnrealizedState>,
/// If set, prices are rounded to nearest dollar with N significant digits.
price_rounding_digits: Option<i32>,
}
impl CohortState {
@@ -29,28 +24,18 @@ impl CohortState {
satblocks_destroyed: Sats::ZERO,
satdays_destroyed: Sats::ZERO,
cost_basis_data: compute_dollars.then_some(CostBasisData::create(path, name)),
cached_unrealized: None,
price_rounding_digits: None,
}
}
/// Enable price rounding for cost basis data.
pub fn with_price_rounding(mut self, digits: i32) -> Self {
self.price_rounding_digits = Some(digits);
if let Some(data) = self.cost_basis_data.take() {
self.cost_basis_data = Some(data.with_price_rounding(digits));
}
self
}
/// Round price if rounding is enabled.
#[inline]
fn round_price(&self, price: CentsUnsigned) -> CentsUnsigned {
match self.price_rounding_digits {
Some(digits) => price.round_to_dollar(digits),
None => price,
}
}
pub fn import_at_or_before(&mut self, height: Height) -> Result<Height> {
self.cached_unrealized = None;
match self.cost_basis_data.as_mut() {
Some(p) => p.import_at_or_before(height),
None => Ok(height),
@@ -73,7 +58,6 @@ impl CohortState {
p.clean()?;
p.init();
}
self.cached_unrealized = None;
Ok(())
}
@@ -111,21 +95,16 @@ impl CohortState {
self.supply += &s.supply_state;
if s.supply_state.value > Sats::ZERO && self.realized.is_some() {
let rounded_price = self.round_price(s.realized_price);
self.realized
.as_mut()
.unwrap()
.increment_snapshot(s.price_sats, s.investor_cap);
self.cost_basis_data.as_mut().unwrap().increment(
rounded_price,
s.realized_price,
s.supply_state.value,
s.price_sats,
s.investor_cap,
);
if let Some(cache) = self.cached_unrealized.as_mut() {
cache.on_receive(rounded_price, s.supply_state.value);
}
}
}
@@ -140,21 +119,16 @@ impl CohortState {
self.supply -= &s.supply_state;
if s.supply_state.value > Sats::ZERO && self.realized.is_some() {
let rounded_price = self.round_price(s.realized_price);
self.realized
.as_mut()
.unwrap()
.decrement_snapshot(s.price_sats, s.investor_cap);
self.cost_basis_data.as_mut().unwrap().decrement(
rounded_price,
s.realized_price,
s.supply_state.value,
s.price_sats,
s.investor_cap,
);
if let Some(cache) = self.cached_unrealized.as_mut() {
cache.on_send(rounded_price, s.supply_state.value);
}
}
}
@@ -179,10 +153,6 @@ impl CohortState {
price_sats,
investor_cap,
);
if let Some(cache) = self.cached_unrealized.as_mut() {
cache.on_receive(price, sats);
}
}
}
@@ -195,37 +165,27 @@ impl CohortState {
) {
self.supply += supply;
if supply.value > Sats::ZERO && self.realized.is_some() {
// Pre-compute rounded prices before mutable borrows
let current_rounded = self.round_price(current.realized_price);
let prev_rounded = self.round_price(prev.realized_price);
self.realized.as_mut().unwrap().receive(price, supply.value);
if supply.value > Sats::ZERO
&& let Some(realized) = self.realized.as_mut()
{
realized.receive(price, supply.value);
if current.supply_state.value.is_not_zero() {
self.cost_basis_data.as_mut().unwrap().increment(
current_rounded,
current.realized_price,
current.supply_state.value,
current.price_sats,
current.investor_cap,
);
if let Some(cache) = self.cached_unrealized.as_mut() {
cache.on_receive(current_rounded, current.supply_state.value);
}
}
if prev.supply_state.value.is_not_zero() {
self.cost_basis_data.as_mut().unwrap().decrement(
prev_rounded,
prev.realized_price,
prev.supply_state.value,
prev.price_sats,
prev.investor_cap,
);
if let Some(cache) = self.cached_unrealized.as_mut() {
cache.on_send(prev_rounded, prev.supply_state.value);
}
}
}
}
@@ -269,10 +229,6 @@ impl CohortState {
prev_ps,
prev_investor_cap,
);
if let Some(cache) = self.cached_unrealized.as_mut() {
cache.on_send(pp, sats);
}
}
}
}
@@ -299,7 +255,7 @@ impl CohortState {
self.satblocks_destroyed += age.satblocks_destroyed(supply.value);
self.satdays_destroyed += age.satdays_destroyed(supply.value);
if self.realized.is_some() {
if let Some(realized) = self.realized.as_mut() {
let sats = supply.value;
// Compute once for realized.send using typed values
@@ -308,39 +264,24 @@ impl CohortState {
let ath_ps = CentsSats::from_price_sats(ath, sats);
let prev_investor_cap = prev_ps.to_investor_cap(prev_price);
// Pre-compute rounded prices before mutable borrows
let current_rounded = self.round_price(current.realized_price);
let prev_rounded = self.round_price(prev.realized_price);
self.realized
.as_mut()
.unwrap()
.send(sats, current_ps, prev_ps, ath_ps, prev_investor_cap);
realized.send(sats, current_ps, prev_ps, ath_ps, prev_investor_cap);
if current.supply_state.value.is_not_zero() {
self.cost_basis_data.as_mut().unwrap().increment(
current_rounded,
current.realized_price,
current.supply_state.value,
current.price_sats,
current.investor_cap,
);
if let Some(cache) = self.cached_unrealized.as_mut() {
cache.on_receive(current_rounded, current.supply_state.value);
}
}
if prev.supply_state.value.is_not_zero() {
self.cost_basis_data.as_mut().unwrap().decrement(
prev_rounded,
prev.realized_price,
prev.supply_state.value,
prev.price_sats,
prev.investor_cap,
);
if let Some(cache) = self.cached_unrealized.as_mut() {
cache.on_send(prev_rounded, prev.supply_state.value);
}
}
}
}
@@ -355,25 +296,10 @@ impl CohortState {
height_price: CentsUnsigned,
date_price: Option<CentsUnsigned>,
) -> (UnrealizedState, Option<UnrealizedState>) {
let cost_basis_data = match self.cost_basis_data.as_ref() {
Some(p) if !p.is_empty() => p,
_ => return (UnrealizedState::ZERO, date_price.map(|_| UnrealizedState::ZERO)),
};
let date_state = date_price.map(|date_price| {
CachedUnrealizedState::compute_full_standalone(date_price.into(), cost_basis_data)
});
let height_state = if let Some(cache) = self.cached_unrealized.as_mut() {
cache.get_at_price(height_price, cost_basis_data)
} else {
let cache = CachedUnrealizedState::compute_fresh(height_price, cost_basis_data);
let state = cache.current_state();
self.cached_unrealized = Some(cache);
state
};
(height_state, date_state)
match self.cost_basis_data.as_mut() {
Some(p) => p.compute_unrealized_states(height_price, date_price),
None => (UnrealizedState::ZERO, date_price.map(|_| UnrealizedState::ZERO)),
}
}
pub fn write(&mut self, height: Height, cleanup: bool) -> Result<()> {
@@ -1,7 +1,6 @@
use std::{
collections::BTreeMap,
fs,
ops::Bound,
path::{Path, PathBuf},
};
@@ -15,7 +14,10 @@ use vecdb::Bytes;
use crate::utils::OptionExt;
use super::Percentiles;
use super::{CachedUnrealizedState, Percentiles, UnrealizedState};
/// Type alias for the price-to-sats map used in cost basis data.
pub(super) type CostBasisMap = BTreeMap<CentsUnsignedCompact, Sats>;
#[derive(Clone, Debug, Default)]
struct PendingRaw {
@@ -31,6 +33,8 @@ pub struct CostBasisData {
state: Option<State>,
pending: FxHashMap<CentsUnsignedCompact, (Sats, Sats)>,
pending_raw: PendingRaw,
cache: Option<CachedUnrealizedState>,
rounding_digits: Option<i32>,
}
const STATE_TO_KEEP: usize = 10;
@@ -42,6 +46,21 @@ impl CostBasisData {
state: None,
pending: FxHashMap::default(),
pending_raw: PendingRaw::default(),
cache: None,
rounding_digits: None,
}
}
pub fn with_price_rounding(mut self, digits: i32) -> Self {
self.rounding_digits = Some(digits);
self
}
#[inline]
fn round_price(&self, price: CentsUnsigned) -> CentsUnsigned {
match self.rounding_digits {
Some(digits) => price.round_to_dollar(digits),
None => price,
}
}
@@ -53,6 +72,7 @@ impl CostBasisData {
self.state = Some(State::deserialize(&fs::read(path)?)?);
self.pending.clear();
self.pending_raw = PendingRaw::default();
self.cache = None;
Ok(height)
}
@@ -75,14 +95,6 @@ impl CostBasisData {
self.state.u().base.map.iter().map(|(&k, v)| (k, v))
}
pub fn range(
&self,
bounds: (Bound<CentsUnsignedCompact>, Bound<CentsUnsignedCompact>),
) -> impl Iterator<Item = (CentsUnsignedCompact, &Sats)> {
self.assert_pending_empty();
self.state.u().base.map.range(bounds).map(|(&k, v)| (k, v))
}
pub fn is_empty(&self) -> bool {
self.pending.is_empty() && self.state.u().base.map.is_empty()
}
@@ -119,7 +131,8 @@ impl CostBasisData {
self.state.u().investor_cap_raw
}
/// Increment with pre-computed typed values
/// Increment with pre-computed typed values.
/// Handles rounding and cache update.
pub fn increment(
&mut self,
price: CentsUnsigned,
@@ -127,14 +140,19 @@ impl CostBasisData {
price_sats: CentsSats,
investor_cap: CentsSquaredSats,
) {
let price = self.round_price(price);
self.pending.entry(price.into()).or_default().0 += sats;
self.pending_raw.cap_inc += price_sats;
if investor_cap != CentsSquaredSats::ZERO {
self.pending_raw.investor_cap_inc += investor_cap;
}
if let Some(cache) = self.cache.as_mut() {
cache.on_receive(price, sats);
}
}
/// Decrement with pre-computed typed values
/// Decrement with pre-computed typed values.
/// Handles rounding and cache update.
pub fn decrement(
&mut self,
price: CentsUnsigned,
@@ -142,11 +160,15 @@ impl CostBasisData {
price_sats: CentsSats,
investor_cap: CentsSquaredSats,
) {
let price = self.round_price(price);
self.pending.entry(price.into()).or_default().1 += sats;
self.pending_raw.cap_dec += price_sats;
if investor_cap != CentsSquaredSats::ZERO {
self.pending_raw.investor_cap_dec += investor_cap;
}
if let Some(cache) = self.cache.as_mut() {
cache.on_send(price, sats);
}
}
pub fn apply_pending(&mut self) {
@@ -214,6 +236,7 @@ impl CostBasisData {
self.state.replace(State::default());
self.pending.clear();
self.pending_raw = PendingRaw::default();
self.cache = None;
}
pub fn compute_percentiles(&self) -> Option<Percentiles> {
@@ -221,9 +244,36 @@ impl CostBasisData {
Percentiles::compute(self.iter().map(|(k, &v)| (k, v)))
}
pub fn compute_unrealized_states(
&mut self,
height_price: CentsUnsigned,
date_price: Option<CentsUnsigned>,
) -> (UnrealizedState, Option<UnrealizedState>) {
if self.is_empty() {
return (UnrealizedState::ZERO, date_price.map(|_| UnrealizedState::ZERO));
}
let map = &self.state.u().base.map;
let date_state =
date_price.map(|p| CachedUnrealizedState::compute_full_standalone(p.into(), map));
let height_state = if let Some(cache) = self.cache.as_mut() {
cache.get_at_price(height_price, map)
} else {
let cache = CachedUnrealizedState::compute_fresh(height_price, map);
let state = cache.current_state();
self.cache = Some(cache);
state
};
(height_state, date_state)
}
pub fn clean(&mut self) -> Result<()> {
let _ = fs::remove_dir_all(&self.pathbuf);
fs::create_dir_all(self.path_by_height())?;
self.cache = None;
Ok(())
}
@@ -6,4 +6,7 @@ mod unrealized;
pub use data::*;
pub use percentiles::*;
pub use realized::*;
pub use unrealized::*;
pub use unrealized::UnrealizedState;
// Internal use only
pub(super) use unrealized::CachedUnrealizedState;
@@ -2,7 +2,7 @@ use std::ops::Bound;
use brk_types::{CentsUnsigned, CentsUnsignedCompact, Sats};
use super::data::CostBasisData;
use super::CostBasisMap;
#[derive(Debug, Default, Clone)]
pub struct UnrealizedState {
@@ -113,9 +113,9 @@ pub struct CachedUnrealizedState {
}
impl CachedUnrealizedState {
pub fn compute_fresh(price: CentsUnsigned, cost_basis_data: &CostBasisData) -> Self {
pub fn compute_fresh(price: CentsUnsigned, map: &CostBasisMap) -> Self {
let price: CentsUnsignedCompact = price.into();
let state = Self::compute_raw(price, cost_basis_data);
let state = Self::compute_raw(price, map);
Self {
state,
at_price: price,
@@ -130,11 +130,11 @@ impl CachedUnrealizedState {
pub fn get_at_price(
&mut self,
new_price: CentsUnsigned,
cost_basis_data: &CostBasisData,
map: &CostBasisMap,
) -> UnrealizedState {
let new_price: CentsUnsignedCompact = new_price.into();
if new_price != self.at_price {
self.update_for_price_change(new_price, cost_basis_data);
self.update_for_price_change(new_price, map);
}
self.state.to_output()
}
@@ -187,11 +187,7 @@ impl CachedUnrealizedState {
}
}
fn update_for_price_change(
&mut self,
new_price: CentsUnsignedCompact,
cost_basis_data: &CostBasisData,
) {
fn update_for_price_change(&mut self, new_price: CentsUnsignedCompact, map: &CostBasisMap) {
let old_price = self.at_price;
if new_price > old_price {
@@ -202,8 +198,7 @@ impl CachedUnrealizedState {
// First, process UTXOs crossing from loss to profit
// Range (old_price, new_price] means: old_price < price <= new_price
for (price, &sats) in
cost_basis_data.range((Bound::Excluded(old_price), Bound::Included(new_price)))
for (&price, &sats) in map.range((Bound::Excluded(old_price), Bound::Included(new_price)))
{
let sats_u128 = sats.as_u128();
let price_u128 = price.as_u128();
@@ -244,8 +239,7 @@ impl CachedUnrealizedState {
// First, process UTXOs crossing from profit to loss
// Range (new_price, old_price] means: new_price < price <= old_price
for (price, &sats) in
cost_basis_data.range((Bound::Excluded(new_price), Bound::Included(old_price)))
for (&price, &sats) in map.range((Bound::Excluded(new_price), Bound::Included(old_price)))
{
let sats_u128 = sats.as_u128();
let price_u128 = price.as_u128();
@@ -283,14 +277,11 @@ impl CachedUnrealizedState {
self.at_price = new_price;
}
/// Compute raw cached state from cost_basis_data.
fn compute_raw(
current_price: CentsUnsignedCompact,
cost_basis_data: &CostBasisData,
) -> CachedStateRaw {
/// Compute raw cached state from the map.
fn compute_raw(current_price: CentsUnsignedCompact, map: &CostBasisMap) -> CachedStateRaw {
let mut state = CachedStateRaw::default();
for (price, &sats) in cost_basis_data.iter() {
for (&price, &sats) in map.iter() {
let sats_u128 = sats.as_u128();
let price_u128 = price.as_u128();
let invested_capital = price_u128 * sats_u128;
@@ -320,8 +311,8 @@ impl CachedUnrealizedState {
/// Used for date_state which doesn't use the cache.
pub fn compute_full_standalone(
current_price: CentsUnsignedCompact,
cost_basis_data: &CostBasisData,
map: &CostBasisMap,
) -> UnrealizedState {
Self::compute_raw(current_price, cost_basis_data).to_output()
Self::compute_raw(current_price, map).to_output()
}
}
@@ -0,0 +1,63 @@
//! Lazy binary price wrapper with both USD and sats representations.
//!
//! Height-level value is lazy binary: transform(source1[h], source2[h]).
//! Sats are derived lazily from the dollars output.
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Dollars, Height, SatsFract, Version};
use derive_more::{Deref, DerefMut};
use schemars::JsonSchema;
use vecdb::{BinaryTransform, Database, IterableBoxedVec, IterableCloneableVec};
use super::LazyBinaryComputedFromHeightLast;
use crate::{
indexes,
internal::{ComputedVecValue, DollarsToSatsFract, LazyFromHeightLast, NumericValue},
};
/// Lazy binary price metric with both USD and sats representations.
///
/// Dollars: lazy binary transform at height, stored at dateindex.
/// Sats: lazy unary transform of dollars (fully lazy).
#[derive(Clone, Deref, DerefMut, Traversable)]
#[traversable(merge)]
pub struct LazyBinaryPriceFromHeight<S1T = Dollars, S2T = Dollars>
where
S1T: ComputedVecValue + JsonSchema,
S2T: ComputedVecValue + JsonSchema,
{
#[deref]
#[deref_mut]
#[traversable(flatten)]
pub dollars: LazyBinaryComputedFromHeightLast<Dollars, S1T, S2T>,
pub sats: LazyFromHeightLast<SatsFract, Dollars>,
}
impl<S1T, S2T> LazyBinaryPriceFromHeight<S1T, S2T>
where
S1T: NumericValue + JsonSchema,
S2T: NumericValue + JsonSchema,
{
pub fn forced_import<F: BinaryTransform<S1T, S2T, Dollars>>(
db: &Database,
name: &str,
version: Version,
source1: IterableBoxedVec<Height, S1T>,
source2: IterableBoxedVec<Height, S2T>,
indexes: &indexes::Vecs,
) -> Result<Self> {
let dollars = LazyBinaryComputedFromHeightLast::forced_import::<F>(
db, name, version, source1, source2, indexes,
)?;
let sats = LazyFromHeightLast::from_lazy_binary_computed::<DollarsToSatsFract, S1T, S2T>(
&format!("{name}_sats"),
version,
dollars.height.boxed_clone(),
&dollars,
);
Ok(Self { dollars, sats })
}
}
@@ -11,6 +11,7 @@ mod lazy_transform_distribution;
mod lazy_binary_computed_distribution;
mod lazy_binary_computed_full;
mod lazy_binary_computed_last;
mod lazy_binary_price;
mod lazy_binary_computed_sum;
mod lazy_binary_computed_sum_cum;
mod lazy_computed_full;
@@ -47,6 +48,7 @@ pub use lazy_transform_distribution::*;
pub use lazy_binary_computed_distribution::*;
pub use lazy_binary_computed_full::*;
pub use lazy_binary_computed_last::*;
pub use lazy_binary_price::*;
pub use lazy_binary_computed_sum::*;
pub use lazy_binary_computed_sum_cum::*;
pub use lazy_computed_full::*;
@@ -0,0 +1,18 @@
use brk_types::Dollars;
use vecdb::BinaryTransform;
/// (Dollars, Dollars) -> Dollars: a² / b
pub struct DollarsSquaredDivide;
impl BinaryTransform<Dollars, Dollars, Dollars> for DollarsSquaredDivide {
#[inline(always)]
fn apply(a: Dollars, b: Dollars) -> Dollars {
let af = f64::from(a);
let bf = f64::from(b);
if bf == 0.0 {
Dollars::NAN
} else {
Dollars::from(af * af / bf)
}
}
}
@@ -3,6 +3,7 @@ mod cents_unsigned_to_sats_fract;
mod close_price_times_sats;
mod difference_f32;
mod dollar_halve;
mod dollars_squared_divide;
mod dollar_identity;
mod dollar_minus;
mod dollar_plus;
@@ -45,6 +46,7 @@ pub use cents_unsigned_to_sats_fract::*;
pub use close_price_times_sats::*;
pub use difference_f32::*;
pub use dollar_halve::*;
pub use dollars_squared_divide::*;
pub use dollar_identity::*;
pub use dollar_minus::*;
pub use dollar_plus::*;
+36 -10
View File
@@ -1,34 +1,60 @@
use std::path::Path;
use axum::{body::Body, extract::State, http::Response};
use axum::{
body::Body,
extract::State,
http::{HeaderMap, Response, StatusCode},
};
use crate::{HeaderMapExtended, Result, Website};
pub async fn file_handler(
State(website): State<Website>,
headers: HeaderMap,
path: axum::extract::Path<String>,
) -> Result<Response<Body>> {
serve(&website, &path.0)
serve(&website, &path.0, &headers)
}
pub async fn index_handler(State(website): State<Website>) -> Result<Response<Body>> {
serve(&website, "")
pub async fn index_handler(
State(website): State<Website>,
headers: HeaderMap,
) -> Result<Response<Body>> {
serve(&website, "", &headers)
}
fn serve(website: &Website, path: &str) -> Result<Response<Body>> {
fn serve(website: &Website, path: &str, request_headers: &HeaderMap) -> Result<Response<Body>> {
let path = sanitize(path);
let content = website.get_file(&path)?;
let mut response = Response::new(Body::from(content));
let headers = response.headers_mut();
// Empty path or no extension = index.html (SPA fallback)
let is_html = path.is_empty()
|| Path::new(&path).extension().is_none()
|| path.ends_with(".html");
// Etag 304 check (release mode, HTML only)
if is_html {
if let Some(etag) = website.index_etag() {
if request_headers.has_etag(etag) {
let mut response = Response::builder()
.status(StatusCode::NOT_MODIFIED)
.body(Body::empty())
.unwrap();
let headers = response.headers_mut();
headers.insert_etag(etag);
headers.insert_cache_control_must_revalidate();
return Ok(response);
}
}
}
let content = website.get_file(&path)?;
let mut response = Response::new(Body::from(content));
let headers = response.headers_mut();
if is_html {
headers.insert_content_type_text_html();
if let Some(etag) = website.index_etag() {
headers.insert_etag(etag);
}
} else {
headers.insert_content_type(Path::new(&path));
}
+11
View File
@@ -3,6 +3,8 @@ use std::path::Path;
use axum::http::{HeaderMap, header};
pub trait HeaderMapExtended {
fn has_etag(&self, etag: &str) -> bool;
fn insert_etag(&mut self, etag: &str);
fn insert_cache_control_must_revalidate(&mut self);
fn insert_cache_control_immutable(&mut self);
fn insert_content_type(&mut self, path: &Path);
@@ -10,6 +12,15 @@ pub trait HeaderMapExtended {
}
impl HeaderMapExtended for HeaderMap {
fn has_etag(&self, etag: &str) -> bool {
self.get(header::IF_NONE_MATCH)
.is_some_and(|v| v == etag)
}
fn insert_etag(&mut self, etag: &str) {
self.insert(header::ETAG, etag.parse().unwrap());
}
fn insert_cache_control_must_revalidate(&mut self) {
self.insert(
header::CACHE_CONTROL,
+47 -22
View File
@@ -1,5 +1,6 @@
use std::{
fs,
hash::{DefaultHasher, Hash, Hasher},
path::{Path, PathBuf},
str::FromStr,
sync::OnceLock,
@@ -15,8 +16,13 @@ use crate::{Error, Result};
/// Embedded website assets
pub static EMBEDDED_WEBSITE: Dir = include_dir!("$CARGO_MANIFEST_DIR/website");
struct CachedIndex {
html: Vec<u8>,
etag: String,
}
/// Cached index.html with importmap injected
static INDEX_HTML: OnceLock<String> = OnceLock::new();
static INDEX_HTML: OnceLock<CachedIndex> = OnceLock::new();
/// Website configuration:
/// - `true` or omitted: serve embedded website
@@ -35,6 +41,14 @@ impl Website {
!matches!(self, Self::Disabled)
}
/// Returns the cached index.html etag (None in debug mode or before first request)
pub fn index_etag(&self) -> Option<&str> {
if cfg!(debug_assertions) {
return None;
}
INDEX_HTML.get().map(|cached| cached.etag.as_str())
}
/// Returns the filesystem path if available, None means use embedded
pub fn filesystem_path(&self) -> Option<PathBuf> {
match self {
@@ -96,35 +110,46 @@ impl Website {
}
// Release mode: cache with importmap
let html = INDEX_HTML.get_or_init(|| match self.filesystem_path() {
None => {
let file = EMBEDDED_WEBSITE
.get_file("index.html")
.expect("index.html must exist in embedded website");
let cached = INDEX_HTML.get_or_init(|| {
let html = match self.filesystem_path() {
None => {
let file = EMBEDDED_WEBSITE
.get_file("index.html")
.expect("index.html must exist in embedded website");
let html =
std::str::from_utf8(file.contents()).expect("index.html must be valid UTF-8");
let html =
std::str::from_utf8(file.contents()).expect("index.html must be valid UTF-8");
let importmap = ImportMap::scan_embedded(&EMBEDDED_WEBSITE, "");
importmap
.transform_html(html)
.unwrap_or_else(|| html.to_string())
}
Some(base) => {
let html =
fs::read_to_string(base.join("index.html")).expect("index.html must exist");
let importmap = ImportMap::scan_embedded(&EMBEDDED_WEBSITE, "");
importmap
.transform_html(html)
.unwrap_or_else(|| html.to_string())
}
Some(base) => {
let html =
fs::read_to_string(base.join("index.html")).expect("index.html must exist");
match ImportMap::scan(&base, "") {
Ok(importmap) => importmap.transform_html(&html).unwrap_or(html),
Err(e) => {
error!("Failed to scan for importmap: {e}");
html
match ImportMap::scan(&base, "") {
Ok(importmap) => importmap.transform_html(&html).unwrap_or(html),
Err(e) => {
error!("Failed to scan for importmap: {e}");
html
}
}
}
};
let mut hasher = DefaultHasher::new();
html.hash(&mut hasher);
let etag = format!("\"{}\"", hasher.finish());
CachedIndex {
html: html.into_bytes(),
etag,
}
});
Ok(html.as_bytes().to_vec())
Ok(cached.html.clone())
}
fn get_embedded(&self, path: &str) -> Result<Vec<u8>> {
+53 -37
View File
@@ -1438,7 +1438,7 @@ function createMetricPattern32(client, name) { return _mp(client, name, _i32); }
// Reusable structural pattern factories
/**
* @typedef {Object} AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern
* @typedef {Object} AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern
* @property {MetricPattern6<StoredF64>} adjustedSopr
* @property {MetricPattern6<StoredF64>} adjustedSopr30dEma
* @property {MetricPattern6<StoredF64>} adjustedSopr7dEma
@@ -1446,6 +1446,8 @@ function createMetricPattern32(client, name) { return _mp(client, name, _i32); }
* @property {MetricPattern1<Dollars>} adjustedValueDestroyed
* @property {MetricPattern11<CentsSats>} capRaw
* @property {MetricPattern1<Dollars>} capitulationFlow
* @property {DollarsSatsPattern} ceilingPrice
* @property {DollarsSatsPattern} floorPrice
* @property {MetricPattern11<CentsSquaredSats>} investorCapRaw
* @property {DollarsSatsPattern} investorPrice
* @property {MetricPattern1<CentsUnsigned>} investorPriceCents
@@ -1495,12 +1497,12 @@ function createMetricPattern32(client, name) { return _mp(client, name, _i32); }
*/
/**
* Create a AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern pattern node
* Create a AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern}
* @returns {AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern}
*/
function createAdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc) {
function createAdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc) {
return {
adjustedSopr: createMetricPattern6(client, _m(acc, 'adjusted_sopr')),
adjustedSopr30dEma: createMetricPattern6(client, _m(acc, 'adjusted_sopr_30d_ema')),
@@ -1509,6 +1511,8 @@ function createAdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSe
adjustedValueDestroyed: createMetricPattern1(client, _m(acc, 'adjusted_value_destroyed')),
capRaw: createMetricPattern11(client, _m(acc, 'cap_raw')),
capitulationFlow: createMetricPattern1(client, _m(acc, 'capitulation_flow')),
ceilingPrice: createDollarsSatsPattern(client, _m(acc, 'ceiling_price')),
floorPrice: createDollarsSatsPattern(client, _m(acc, 'floor_price')),
investorCapRaw: createMetricPattern11(client, _m(acc, 'investor_cap_raw')),
investorPrice: createDollarsSatsPattern(client, _m(acc, 'investor_price')),
investorPriceCents: createMetricPattern1(client, _m(acc, 'investor_price_cents')),
@@ -1559,7 +1563,7 @@ function createAdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSe
}
/**
* @typedef {Object} AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2
* @typedef {Object} AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2
* @property {MetricPattern6<StoredF64>} adjustedSopr
* @property {MetricPattern6<StoredF64>} adjustedSopr30dEma
* @property {MetricPattern6<StoredF64>} adjustedSopr7dEma
@@ -1567,6 +1571,8 @@ function createAdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSe
* @property {MetricPattern1<Dollars>} adjustedValueDestroyed
* @property {MetricPattern11<CentsSats>} capRaw
* @property {MetricPattern1<Dollars>} capitulationFlow
* @property {DollarsSatsPattern} ceilingPrice
* @property {DollarsSatsPattern} floorPrice
* @property {MetricPattern11<CentsSquaredSats>} investorCapRaw
* @property {DollarsSatsPattern} investorPrice
* @property {MetricPattern1<CentsUnsigned>} investorPriceCents
@@ -1614,12 +1620,12 @@ function createAdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSe
*/
/**
* Create a AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 pattern node
* Create a AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2}
* @returns {AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2}
*/
function createAdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2(client, acc) {
function createAdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2(client, acc) {
return {
adjustedSopr: createMetricPattern6(client, _m(acc, 'adjusted_sopr')),
adjustedSopr30dEma: createMetricPattern6(client, _m(acc, 'adjusted_sopr_30d_ema')),
@@ -1628,6 +1634,8 @@ function createAdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSe
adjustedValueDestroyed: createMetricPattern1(client, _m(acc, 'adjusted_value_destroyed')),
capRaw: createMetricPattern11(client, _m(acc, 'cap_raw')),
capitulationFlow: createMetricPattern1(client, _m(acc, 'capitulation_flow')),
ceilingPrice: createDollarsSatsPattern(client, _m(acc, 'ceiling_price')),
floorPrice: createDollarsSatsPattern(client, _m(acc, 'floor_price')),
investorCapRaw: createMetricPattern11(client, _m(acc, 'investor_cap_raw')),
investorPrice: createDollarsSatsPattern(client, _m(acc, 'investor_price')),
investorPriceCents: createMetricPattern1(client, _m(acc, 'investor_price_cents')),
@@ -1676,9 +1684,11 @@ function createAdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSe
}
/**
* @typedef {Object} CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2
* @typedef {Object} CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2
* @property {MetricPattern11<CentsSats>} capRaw
* @property {MetricPattern1<Dollars>} capitulationFlow
* @property {DollarsSatsPattern} ceilingPrice
* @property {DollarsSatsPattern} floorPrice
* @property {MetricPattern11<CentsSquaredSats>} investorCapRaw
* @property {DollarsSatsPattern} investorPrice
* @property {MetricPattern1<CentsUnsigned>} investorPriceCents
@@ -1728,15 +1738,17 @@ function createAdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSe
*/
/**
* Create a CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 pattern node
* Create a CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2}
* @returns {CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2}
*/
function createCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2(client, acc) {
function createCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2(client, acc) {
return {
capRaw: createMetricPattern11(client, _m(acc, 'cap_raw')),
capitulationFlow: createMetricPattern1(client, _m(acc, 'capitulation_flow')),
ceilingPrice: createDollarsSatsPattern(client, _m(acc, 'ceiling_price')),
floorPrice: createDollarsSatsPattern(client, _m(acc, 'floor_price')),
investorCapRaw: createMetricPattern11(client, _m(acc, 'investor_cap_raw')),
investorPrice: createDollarsSatsPattern(client, _m(acc, 'investor_price')),
investorPriceCents: createMetricPattern1(client, _m(acc, 'investor_price_cents')),
@@ -1787,9 +1799,11 @@ function createCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSo
}
/**
* @typedef {Object} CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern
* @typedef {Object} CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern
* @property {MetricPattern11<CentsSats>} capRaw
* @property {MetricPattern1<Dollars>} capitulationFlow
* @property {DollarsSatsPattern} ceilingPrice
* @property {DollarsSatsPattern} floorPrice
* @property {MetricPattern11<CentsSquaredSats>} investorCapRaw
* @property {DollarsSatsPattern} investorPrice
* @property {MetricPattern1<CentsUnsigned>} investorPriceCents
@@ -1837,15 +1851,17 @@ function createCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSo
*/
/**
* Create a CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern pattern node
* Create a CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern}
* @returns {CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern}
*/
function createCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc) {
function createCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc) {
return {
capRaw: createMetricPattern11(client, _m(acc, 'cap_raw')),
capitulationFlow: createMetricPattern1(client, _m(acc, 'capitulation_flow')),
ceilingPrice: createDollarsSatsPattern(client, _m(acc, 'ceiling_price')),
floorPrice: createDollarsSatsPattern(client, _m(acc, 'floor_price')),
investorCapRaw: createMetricPattern11(client, _m(acc, 'investor_cap_raw')),
investorPrice: createDollarsSatsPattern(client, _m(acc, 'investor_price')),
investorPriceCents: createMetricPattern1(client, _m(acc, 'investor_price_cents')),
@@ -2683,7 +2699,7 @@ function createAverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern2(clie
* @property {MetricPattern4<StoredF64>} addrCount30dChange
* @property {MaxMinPattern} costBasis
* @property {UtxoPattern} outputs
* @property {CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} realized
* @property {CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} realized
* @property {InvestedNegNetNuplSupplyUnrealizedPattern} relative
* @property {_30dHalvedTotalPattern} supply
* @property {GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern} unrealized
@@ -2702,7 +2718,7 @@ function createActivityAddrCostOutputsRealizedRelativeSupplyUnrealizedPattern(cl
addrCount30dChange: createMetricPattern4(client, _m(acc, 'addr_count_30d_change')),
costBasis: createMaxMinPattern(client, acc),
outputs: createUtxoPattern(client, _m(acc, 'utxo_count')),
realized: createCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc),
realized: createCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc),
relative: createInvestedNegNetNuplSupplyUnrealizedPattern(client, acc),
supply: create_30dHalvedTotalPattern(client, acc),
unrealized: createGreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern(client, acc),
@@ -2846,7 +2862,7 @@ function create_10y2y3y4y5y6y8yPattern(client, acc) {
* @property {CoinblocksCoindaysSatblocksSatdaysSentPattern} activity
* @property {InvestedMaxMinPercentilesSpotPattern} costBasis
* @property {UtxoPattern} outputs
* @property {CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2} realized
* @property {CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2} realized
* @property {InvestedNegNetSupplyUnrealizedPattern} relative
* @property {_30dHalvedTotalPattern} supply
* @property {GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern} unrealized
@@ -2863,7 +2879,7 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern(client
activity: createCoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc),
costBasis: createInvestedMaxMinPercentilesSpotPattern(client, acc),
outputs: createUtxoPattern(client, _m(acc, 'utxo_count')),
realized: createCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2(client, acc),
realized: createCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2(client, acc),
relative: createInvestedNegNetSupplyUnrealizedPattern(client, acc),
supply: create_30dHalvedTotalPattern(client, acc),
unrealized: createGreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern(client, acc),
@@ -2875,7 +2891,7 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern(client
* @property {CoinblocksCoindaysSatblocksSatdaysSentPattern} activity
* @property {MaxMinPattern} costBasis
* @property {UtxoPattern} outputs
* @property {AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2} realized
* @property {AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2} realized
* @property {InvestedNegNetNuplSupplyUnrealizedPattern3} relative
* @property {_30dHalvedTotalPattern} supply
* @property {GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern} unrealized
@@ -2892,7 +2908,7 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern5(clien
activity: createCoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc),
costBasis: createMaxMinPattern(client, acc),
outputs: createUtxoPattern(client, _m(acc, 'utxo_count')),
realized: createAdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2(client, acc),
realized: createAdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2(client, acc),
relative: createInvestedNegNetNuplSupplyUnrealizedPattern3(client, acc),
supply: create_30dHalvedTotalPattern(client, acc),
unrealized: createGreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern(client, acc),
@@ -2904,7 +2920,7 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern5(clien
* @property {CoinblocksCoindaysSatblocksSatdaysSentPattern} activity
* @property {MaxMinPattern} costBasis
* @property {UtxoPattern} outputs
* @property {CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} realized
* @property {CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} realized
* @property {InvestedNegNetNuplSupplyUnrealizedPattern} relative
* @property {_30dHalvedTotalPattern} supply
* @property {GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern} unrealized
@@ -2921,7 +2937,7 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(clien
activity: createCoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc),
costBasis: createMaxMinPattern(client, acc),
outputs: createUtxoPattern(client, _m(acc, 'utxo_count')),
realized: createCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc),
realized: createCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc),
relative: createInvestedNegNetNuplSupplyUnrealizedPattern(client, acc),
supply: create_30dHalvedTotalPattern(client, acc),
unrealized: createGreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern(client, acc),
@@ -2933,7 +2949,7 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4(clien
* @property {CoinblocksCoindaysSatblocksSatdaysSentPattern} activity
* @property {MaxMinPattern} costBasis
* @property {UtxoPattern} outputs
* @property {CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} realized
* @property {CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} realized
* @property {InvestedNegNetNuplSupplyUnrealizedPattern3} relative
* @property {_30dHalvedTotalPattern} supply
* @property {GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern} unrealized
@@ -2950,7 +2966,7 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern6(clien
activity: createCoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc),
costBasis: createMaxMinPattern(client, acc),
outputs: createUtxoPattern(client, _m(acc, 'utxo_count')),
realized: createCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc),
realized: createCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc),
relative: createInvestedNegNetNuplSupplyUnrealizedPattern3(client, acc),
supply: create_30dHalvedTotalPattern(client, acc),
unrealized: createGreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern(client, acc),
@@ -2962,7 +2978,7 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern6(clien
* @property {CoinblocksCoindaysSatblocksSatdaysSentPattern} activity
* @property {MaxMinPattern} costBasis
* @property {UtxoPattern} outputs
* @property {CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} realized
* @property {CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} realized
* @property {InvestedSupplyPattern} relative
* @property {_30dHalvedTotalPattern} supply
* @property {GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern} unrealized
@@ -2979,7 +2995,7 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(clien
activity: createCoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc),
costBasis: createMaxMinPattern(client, acc),
outputs: createUtxoPattern(client, _m(acc, 'utxo_count')),
realized: createCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc),
realized: createCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc),
relative: createInvestedSupplyPattern(client, acc),
supply: create_30dHalvedTotalPattern(client, acc),
unrealized: createGreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern(client, acc),
@@ -2991,7 +3007,7 @@ function createActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3(clien
* @property {CoinblocksCoindaysSatblocksSatdaysSentPattern} activity
* @property {MaxMinPattern} costBasis
* @property {UtxoPattern} outputs
* @property {CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} realized
* @property {CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} realized
* @property {_30dHalvedTotalPattern} supply
* @property {GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern} unrealized
*/
@@ -3007,7 +3023,7 @@ function createActivityCostOutputsRealizedSupplyUnrealizedPattern(client, acc) {
activity: createCoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc),
costBasis: createMaxMinPattern(client, acc),
outputs: createUtxoPattern(client, _m(acc, 'utxo_count')),
realized: createCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc),
realized: createCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc),
supply: create_30dHalvedTotalPattern(client, acc),
unrealized: createGreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern(client, acc),
};
@@ -4611,7 +4627,7 @@ function createRatioPattern2(client, acc) {
* @property {_30dHalvedTotalPattern} supply
* @property {UtxoPattern} outputs
* @property {CoinblocksCoindaysSatblocksSatdaysSentPattern} activity
* @property {AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} realized
* @property {AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} realized
* @property {GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern} unrealized
* @property {InvestedMaxMinPercentilesSpotPattern} costBasis
* @property {MetricsTree_Distribution_UtxoCohorts_All_Relative} relative
@@ -4760,7 +4776,7 @@ function createRatioPattern2(client, acc) {
* @property {_30dHalvedTotalPattern} supply
* @property {UtxoPattern} outputs
* @property {CoinblocksCoindaysSatblocksSatdaysSentPattern} activity
* @property {AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} realized
* @property {AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} realized
* @property {GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern} unrealized
* @property {InvestedMaxMinPercentilesSpotPattern} costBasis
* @property {InvestedNegNetNuplSupplyUnrealizedPattern4} relative
@@ -4771,7 +4787,7 @@ function createRatioPattern2(client, acc) {
* @property {_30dHalvedTotalPattern} supply
* @property {UtxoPattern} outputs
* @property {CoinblocksCoindaysSatblocksSatdaysSentPattern} activity
* @property {CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2} realized
* @property {CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2} realized
* @property {GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern} unrealized
* @property {InvestedMaxMinPercentilesSpotPattern} costBasis
* @property {InvestedNegNetNuplSupplyUnrealizedPattern4} relative
@@ -4976,7 +4992,7 @@ function createRatioPattern2(client, acc) {
* @extends BrkClientBase
*/
class BrkClient extends BrkClientBase {
VERSION = "v0.1.5";
VERSION = "v0.1.6";
INDEXES = /** @type {const} */ ([
"dateindex",
@@ -6736,7 +6752,7 @@ class BrkClient extends BrkClientBase {
supply: create_30dHalvedTotalPattern(this, ''),
outputs: createUtxoPattern(this, 'utxo_count'),
activity: createCoinblocksCoindaysSatblocksSatdaysSentPattern(this, ''),
realized: createAdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(this, ''),
realized: createAdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(this, ''),
unrealized: createGreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern(this, ''),
costBasis: createInvestedMaxMinPercentilesSpotPattern(this, ''),
relative: {
@@ -6863,7 +6879,7 @@ class BrkClient extends BrkClientBase {
supply: create_30dHalvedTotalPattern(this, 'sth'),
outputs: createUtxoPattern(this, 'sth_utxo_count'),
activity: createCoinblocksCoindaysSatblocksSatdaysSentPattern(this, 'sth'),
realized: createAdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(this, 'sth'),
realized: createAdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(this, 'sth'),
unrealized: createGreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern(this, 'sth'),
costBasis: createInvestedMaxMinPercentilesSpotPattern(this, 'sth'),
relative: createInvestedNegNetNuplSupplyUnrealizedPattern4(this, 'sth'),
@@ -6872,7 +6888,7 @@ class BrkClient extends BrkClientBase {
supply: create_30dHalvedTotalPattern(this, 'lth'),
outputs: createUtxoPattern(this, 'lth_utxo_count'),
activity: createCoinblocksCoindaysSatblocksSatdaysSentPattern(this, 'lth'),
realized: createCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2(this, 'lth'),
realized: createCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2(this, 'lth'),
unrealized: createGreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern(this, 'lth'),
costBasis: createInvestedMaxMinPercentilesSpotPattern(this, 'lth'),
relative: createInvestedNegNetNuplSupplyUnrealizedPattern4(this, 'lth'),
+1 -1
View File
@@ -34,5 +34,5 @@
"url": "git+https://github.com/bitcoinresearchkit/brk.git"
},
"type": "module",
"version": "0.1.5"
"version": "0.1.6"
}
+23 -15
View File
@@ -1862,7 +1862,7 @@ class MetricPattern32(Generic[T]):
# Reusable structural pattern classes
class AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern:
class AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
@@ -1874,6 +1874,8 @@ class AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSop
self.adjusted_value_destroyed: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'adjusted_value_destroyed'))
self.cap_raw: MetricPattern11[CentsSats] = MetricPattern11(client, _m(acc, 'cap_raw'))
self.capitulation_flow: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'capitulation_flow'))
self.ceiling_price: DollarsSatsPattern = DollarsSatsPattern(client, _m(acc, 'ceiling_price'))
self.floor_price: DollarsSatsPattern = DollarsSatsPattern(client, _m(acc, 'floor_price'))
self.investor_cap_raw: MetricPattern11[CentsSquaredSats] = MetricPattern11(client, _m(acc, 'investor_cap_raw'))
self.investor_price: DollarsSatsPattern = DollarsSatsPattern(client, _m(acc, 'investor_price'))
self.investor_price_cents: MetricPattern1[CentsUnsigned] = MetricPattern1(client, _m(acc, 'investor_price_cents'))
@@ -1921,7 +1923,7 @@ class AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSop
self.value_created: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'value_created'))
self.value_destroyed: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'value_destroyed'))
class AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2:
class AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
@@ -1933,6 +1935,8 @@ class AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSop
self.adjusted_value_destroyed: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'adjusted_value_destroyed'))
self.cap_raw: MetricPattern11[CentsSats] = MetricPattern11(client, _m(acc, 'cap_raw'))
self.capitulation_flow: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'capitulation_flow'))
self.ceiling_price: DollarsSatsPattern = DollarsSatsPattern(client, _m(acc, 'ceiling_price'))
self.floor_price: DollarsSatsPattern = DollarsSatsPattern(client, _m(acc, 'floor_price'))
self.investor_cap_raw: MetricPattern11[CentsSquaredSats] = MetricPattern11(client, _m(acc, 'investor_cap_raw'))
self.investor_price: DollarsSatsPattern = DollarsSatsPattern(client, _m(acc, 'investor_price'))
self.investor_price_cents: MetricPattern1[CentsUnsigned] = MetricPattern1(client, _m(acc, 'investor_price_cents'))
@@ -1978,13 +1982,15 @@ class AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSop
self.value_created: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'value_created'))
self.value_destroyed: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'value_destroyed'))
class CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2:
class CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.cap_raw: MetricPattern11[CentsSats] = MetricPattern11(client, _m(acc, 'cap_raw'))
self.capitulation_flow: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'capitulation_flow'))
self.ceiling_price: DollarsSatsPattern = DollarsSatsPattern(client, _m(acc, 'ceiling_price'))
self.floor_price: DollarsSatsPattern = DollarsSatsPattern(client, _m(acc, 'floor_price'))
self.investor_cap_raw: MetricPattern11[CentsSquaredSats] = MetricPattern11(client, _m(acc, 'investor_cap_raw'))
self.investor_price: DollarsSatsPattern = DollarsSatsPattern(client, _m(acc, 'investor_price'))
self.investor_price_cents: MetricPattern1[CentsUnsigned] = MetricPattern1(client, _m(acc, 'investor_price_cents'))
@@ -2032,13 +2038,15 @@ class CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalVa
self.value_created: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'value_created'))
self.value_destroyed: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'value_destroyed'))
class CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern:
class CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.cap_raw: MetricPattern11[CentsSats] = MetricPattern11(client, _m(acc, 'cap_raw'))
self.capitulation_flow: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'capitulation_flow'))
self.ceiling_price: DollarsSatsPattern = DollarsSatsPattern(client, _m(acc, 'ceiling_price'))
self.floor_price: DollarsSatsPattern = DollarsSatsPattern(client, _m(acc, 'floor_price'))
self.investor_cap_raw: MetricPattern11[CentsSquaredSats] = MetricPattern11(client, _m(acc, 'investor_cap_raw'))
self.investor_price: DollarsSatsPattern = DollarsSatsPattern(client, _m(acc, 'investor_price'))
self.investor_price_cents: MetricPattern1[CentsUnsigned] = MetricPattern1(client, _m(acc, 'investor_price_cents'))
@@ -2456,7 +2464,7 @@ class ActivityAddrCostOutputsRealizedRelativeSupplyUnrealizedPattern:
self.addr_count_30d_change: MetricPattern4[StoredF64] = MetricPattern4(client, _m(acc, 'addr_count_30d_change'))
self.cost_basis: MaxMinPattern = MaxMinPattern(client, acc)
self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count'))
self.realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern = CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc)
self.realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern = CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc)
self.relative: InvestedNegNetNuplSupplyUnrealizedPattern = InvestedNegNetNuplSupplyUnrealizedPattern(client, acc)
self.supply: _30dHalvedTotalPattern = _30dHalvedTotalPattern(client, acc)
self.unrealized: GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern = GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern(client, acc)
@@ -2527,7 +2535,7 @@ class ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern:
self.activity: CoinblocksCoindaysSatblocksSatdaysSentPattern = CoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc)
self.cost_basis: InvestedMaxMinPercentilesSpotPattern = InvestedMaxMinPercentilesSpotPattern(client, acc)
self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count'))
self.realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 = CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2(client, acc)
self.realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 = CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2(client, acc)
self.relative: InvestedNegNetSupplyUnrealizedPattern = InvestedNegNetSupplyUnrealizedPattern(client, acc)
self.supply: _30dHalvedTotalPattern = _30dHalvedTotalPattern(client, acc)
self.unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern = GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern(client, acc)
@@ -2540,7 +2548,7 @@ class ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern5:
self.activity: CoinblocksCoindaysSatblocksSatdaysSentPattern = CoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc)
self.cost_basis: MaxMinPattern = MaxMinPattern(client, acc)
self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count'))
self.realized: AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 = AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2(client, acc)
self.realized: AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 = AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2(client, acc)
self.relative: InvestedNegNetNuplSupplyUnrealizedPattern3 = InvestedNegNetNuplSupplyUnrealizedPattern3(client, acc)
self.supply: _30dHalvedTotalPattern = _30dHalvedTotalPattern(client, acc)
self.unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern = GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern(client, acc)
@@ -2553,7 +2561,7 @@ class ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern4:
self.activity: CoinblocksCoindaysSatblocksSatdaysSentPattern = CoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc)
self.cost_basis: MaxMinPattern = MaxMinPattern(client, acc)
self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count'))
self.realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern = CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc)
self.realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern = CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc)
self.relative: InvestedNegNetNuplSupplyUnrealizedPattern = InvestedNegNetNuplSupplyUnrealizedPattern(client, acc)
self.supply: _30dHalvedTotalPattern = _30dHalvedTotalPattern(client, acc)
self.unrealized: GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern = GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern(client, acc)
@@ -2566,7 +2574,7 @@ class ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern6:
self.activity: CoinblocksCoindaysSatblocksSatdaysSentPattern = CoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc)
self.cost_basis: MaxMinPattern = MaxMinPattern(client, acc)
self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count'))
self.realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern = CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc)
self.realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern = CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc)
self.relative: InvestedNegNetNuplSupplyUnrealizedPattern3 = InvestedNegNetNuplSupplyUnrealizedPattern3(client, acc)
self.supply: _30dHalvedTotalPattern = _30dHalvedTotalPattern(client, acc)
self.unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern = GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern(client, acc)
@@ -2579,7 +2587,7 @@ class ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern3:
self.activity: CoinblocksCoindaysSatblocksSatdaysSentPattern = CoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc)
self.cost_basis: MaxMinPattern = MaxMinPattern(client, acc)
self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count'))
self.realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern = CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc)
self.realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern = CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc)
self.relative: InvestedSupplyPattern = InvestedSupplyPattern(client, acc)
self.supply: _30dHalvedTotalPattern = _30dHalvedTotalPattern(client, acc)
self.unrealized: GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern = GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern(client, acc)
@@ -2592,7 +2600,7 @@ class ActivityCostOutputsRealizedSupplyUnrealizedPattern:
self.activity: CoinblocksCoindaysSatblocksSatdaysSentPattern = CoinblocksCoindaysSatblocksSatdaysSentPattern(client, acc)
self.cost_basis: MaxMinPattern = MaxMinPattern(client, acc)
self.outputs: UtxoPattern = UtxoPattern(client, _m(acc, 'utxo_count'))
self.realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern = CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc)
self.realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern = CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, acc)
self.supply: _30dHalvedTotalPattern = _30dHalvedTotalPattern(client, acc)
self.unrealized: GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern = GreedInvestedInvestorNegNetPainSupplyTotalUnrealizedPattern(client, acc)
@@ -3979,7 +3987,7 @@ class MetricsTree_Distribution_UtxoCohorts_All:
self.supply: _30dHalvedTotalPattern = _30dHalvedTotalPattern(client, '')
self.outputs: UtxoPattern = UtxoPattern(client, 'utxo_count')
self.activity: CoinblocksCoindaysSatblocksSatdaysSentPattern = CoinblocksCoindaysSatblocksSatdaysSentPattern(client, '')
self.realized: AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern = AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, '')
self.realized: AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern = AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, '')
self.unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern = GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern(client, '')
self.cost_basis: InvestedMaxMinPercentilesSpotPattern = InvestedMaxMinPercentilesSpotPattern(client, '')
self.relative: MetricsTree_Distribution_UtxoCohorts_All_Relative = MetricsTree_Distribution_UtxoCohorts_All_Relative(client)
@@ -4111,7 +4119,7 @@ class MetricsTree_Distribution_UtxoCohorts_Term_Short:
self.supply: _30dHalvedTotalPattern = _30dHalvedTotalPattern(client, 'sth')
self.outputs: UtxoPattern = UtxoPattern(client, 'sth_utxo_count')
self.activity: CoinblocksCoindaysSatblocksSatdaysSentPattern = CoinblocksCoindaysSatblocksSatdaysSentPattern(client, 'sth')
self.realized: AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern = AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, 'sth')
self.realized: AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern = AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern(client, 'sth')
self.unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern = GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern(client, 'sth')
self.cost_basis: InvestedMaxMinPercentilesSpotPattern = InvestedMaxMinPercentilesSpotPattern(client, 'sth')
self.relative: InvestedNegNetNuplSupplyUnrealizedPattern4 = InvestedNegNetNuplSupplyUnrealizedPattern4(client, 'sth')
@@ -4123,7 +4131,7 @@ class MetricsTree_Distribution_UtxoCohorts_Term_Long:
self.supply: _30dHalvedTotalPattern = _30dHalvedTotalPattern(client, 'lth')
self.outputs: UtxoPattern = UtxoPattern(client, 'lth_utxo_count')
self.activity: CoinblocksCoindaysSatblocksSatdaysSentPattern = CoinblocksCoindaysSatblocksSatdaysSentPattern(client, 'lth')
self.realized: CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 = CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2(client, 'lth')
self.realized: CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2 = CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2(client, 'lth')
self.unrealized: GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern = GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern(client, 'lth')
self.cost_basis: InvestedMaxMinPercentilesSpotPattern = InvestedMaxMinPercentilesSpotPattern(client, 'lth')
self.relative: InvestedNegNetNuplSupplyUnrealizedPattern4 = InvestedNegNetNuplSupplyUnrealizedPattern4(client, 'lth')
@@ -4401,7 +4409,7 @@ class MetricsTree:
class BrkClient(BrkClientBase):
"""Main BRK client with metrics tree and API methods."""
VERSION = "v0.1.5"
VERSION = "v0.1.6"
INDEXES = [
"dateindex",
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "brk-client"
version = "0.1.5"
version = "0.1.6"
description = "Python client for the Bitcoin Research Kit"
readme = "README.md"
requires-python = ">=3.9"
@@ -19,7 +19,7 @@ import { baseline, price } from "../series.js";
import { Unit } from "../../utils/units.js";
/**
* @param {{ realized: { realizedPrice: ActivePricePattern, investorPrice: ActivePricePattern } }} tree
* @param {{ realized: { realizedPrice: ActivePricePattern, investorPrice: ActivePricePattern, floorPrice: ActivePricePattern, ceilingPrice: ActivePricePattern } }} tree
* @param {(metric: string) => string} title
* @returns {PartialChartOption}
*/
@@ -30,6 +30,8 @@ function createCompareChart(tree, title) {
top: [
price({ metric: tree.realized.realizedPrice, name: "Realized", color: colors.realized }),
price({ metric: tree.realized.investorPrice, name: "Investor", color: colors.investor }),
price({ metric: tree.realized.ceilingPrice, name: "I²/R", color: colors.stat.max, style: 2, defaultActive: false }),
price({ metric: tree.realized.floorPrice, name: "R²/I", color: colors.stat.min, style: 2, defaultActive: false }),
],
};
}
+4 -4
View File
@@ -89,10 +89,10 @@
* @typedef {Brk.GreedInvestedInvestorNegNetPainPeakSupplyTotalUnrealizedPattern} UnrealizedFullPattern
*
* Realized patterns
* @typedef {Brk.CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} RealizedPattern
* @typedef {Brk.CapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2} RealizedPattern2
* @typedef {Brk.AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} RealizedPattern3
* @typedef {Brk.AdjustedCapCapitulationInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2} RealizedPattern4
* @typedef {Brk.CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} RealizedPattern
* @typedef {Brk.CapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2} RealizedPattern2
* @typedef {Brk.AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern} RealizedPattern3
* @typedef {Brk.AdjustedCapCapitulationCeilingFloorInvestorLossMvrvNegNetPeakProfitRealizedSellSentSoprTotalValuePattern2} RealizedPattern4
*/
/**