mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-26 10:18:10 -07:00
global: snapshot
This commit is contained in:
+130
-56
@@ -956,9 +956,10 @@ pub struct CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSell
|
||||
pub lower_price_band: CentsSatsUsdPattern,
|
||||
pub mvrv: MetricPattern1<StoredF32>,
|
||||
pub neg_realized_loss: MetricPattern1<Dollars>,
|
||||
pub net_pnl_change_1m: MetricPattern1<CentsSigned>,
|
||||
pub net_pnl_change_1m_rel_to_market_cap: BpsPercentRatioPattern,
|
||||
pub net_pnl_change_1m_rel_to_realized_cap: BpsPercentRatioPattern,
|
||||
pub net_pnl_delta: ChangeRatePattern<CentsSigned>,
|
||||
pub net_pnl_delta_extended: _24hChangeRatePattern<CentsSigned>,
|
||||
pub net_realized_pnl: CumulativeHeightPattern<CentsSigned>,
|
||||
pub net_realized_pnl_rel_to_realized_cap: BpsPercentRatioPattern,
|
||||
pub peak_regret: CumulativeHeightPattern<Cents>,
|
||||
@@ -970,7 +971,8 @@ pub struct CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSell
|
||||
pub profit_value_destroyed_sum: _1m1w1y24hPattern<Cents>,
|
||||
pub realized_cap: MetricPattern1<Dollars>,
|
||||
pub realized_cap_cents: MetricPattern1<Cents>,
|
||||
pub realized_cap_change_1m: MetricPattern1<CentsSigned>,
|
||||
pub realized_cap_delta: ChangeRatePattern<CentsSigned>,
|
||||
pub realized_cap_delta_extended: _24hChangeRatePattern<CentsSigned>,
|
||||
pub realized_cap_rel_to_own_market_cap: BpsPercentRatioPattern,
|
||||
pub realized_loss: CumulativeHeightPattern<Cents>,
|
||||
pub realized_loss_rel_to_realized_cap: BpsPercentRatioPattern,
|
||||
@@ -1022,9 +1024,10 @@ impl CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSo
|
||||
lower_price_band: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "lower_price_band")),
|
||||
mvrv: MetricPattern1::new(client.clone(), _m(&acc, "mvrv")),
|
||||
neg_realized_loss: MetricPattern1::new(client.clone(), _m(&acc, "neg_realized_loss")),
|
||||
net_pnl_change_1m: MetricPattern1::new(client.clone(), _m(&acc, "net_pnl_change_1m")),
|
||||
net_pnl_change_1m_rel_to_market_cap: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "net_pnl_change_1m_rel_to_market_cap")),
|
||||
net_pnl_change_1m_rel_to_realized_cap: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "net_pnl_change_1m_rel_to_realized_cap")),
|
||||
net_pnl_delta: ChangeRatePattern::new(client.clone(), _m(&acc, "net_pnl_delta")),
|
||||
net_pnl_delta_extended: _24hChangeRatePattern::new(client.clone(), _m(&acc, "net_pnl_delta")),
|
||||
net_realized_pnl: CumulativeHeightPattern::new(client.clone(), _m(&acc, "net_realized_pnl")),
|
||||
net_realized_pnl_rel_to_realized_cap: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "net_realized_pnl_rel_to_realized_cap")),
|
||||
peak_regret: CumulativeHeightPattern::new(client.clone(), _m(&acc, "realized_peak_regret")),
|
||||
@@ -1036,7 +1039,8 @@ impl CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSo
|
||||
profit_value_destroyed_sum: _1m1w1y24hPattern::new(client.clone(), _m(&acc, "profit_value_destroyed")),
|
||||
realized_cap: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap")),
|
||||
realized_cap_cents: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap_cents")),
|
||||
realized_cap_change_1m: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap_change_1m")),
|
||||
realized_cap_delta: ChangeRatePattern::new(client.clone(), _m(&acc, "realized_cap_delta")),
|
||||
realized_cap_delta_extended: _24hChangeRatePattern::new(client.clone(), _m(&acc, "realized_cap_delta")),
|
||||
realized_cap_rel_to_own_market_cap: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "realized_cap_rel_to_own_market_cap")),
|
||||
realized_loss: CumulativeHeightPattern::new(client.clone(), _m(&acc, "realized_loss")),
|
||||
realized_loss_rel_to_realized_cap: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "realized_loss_rel_to_realized_cap")),
|
||||
@@ -1146,7 +1150,7 @@ pub struct MvrvNegNetRealizedSentSoprValuePattern {
|
||||
pub net_realized_pnl: CumulativeHeightPattern<CentsSigned>,
|
||||
pub realized_cap: MetricPattern1<Dollars>,
|
||||
pub realized_cap_cents: MetricPattern1<Cents>,
|
||||
pub realized_cap_change_1m: MetricPattern1<CentsSigned>,
|
||||
pub realized_cap_delta: ChangeRatePattern<CentsSigned>,
|
||||
pub realized_loss: CumulativeHeightPattern<Cents>,
|
||||
pub realized_loss_sum: _24hPattern<Cents>,
|
||||
pub realized_price: CentsSatsUsdPattern,
|
||||
@@ -1173,7 +1177,7 @@ impl MvrvNegNetRealizedSentSoprValuePattern {
|
||||
net_realized_pnl: CumulativeHeightPattern::new(client.clone(), _m(&acc, "net_realized_pnl")),
|
||||
realized_cap: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap")),
|
||||
realized_cap_cents: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap_cents")),
|
||||
realized_cap_change_1m: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap_change_1m")),
|
||||
realized_cap_delta: ChangeRatePattern::new(client.clone(), _m(&acc, "realized_cap_delta")),
|
||||
realized_loss: CumulativeHeightPattern::new(client.clone(), _m(&acc, "realized_loss")),
|
||||
realized_loss_sum: _24hPattern::new(client.clone(), _m(&acc, "realized_loss_24h")),
|
||||
realized_price: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "realized_price")),
|
||||
@@ -1250,7 +1254,7 @@ pub struct MvrvNegNetRealizedSoprValuePattern {
|
||||
pub net_realized_pnl: CumulativeHeightPattern<CentsSigned>,
|
||||
pub realized_cap: MetricPattern1<Dollars>,
|
||||
pub realized_cap_cents: MetricPattern1<Cents>,
|
||||
pub realized_cap_change_1m: MetricPattern1<CentsSigned>,
|
||||
pub realized_cap_delta: ChangeRatePattern<CentsSigned>,
|
||||
pub realized_loss: CumulativeHeightPattern<Cents>,
|
||||
pub realized_loss_sum: _24hPattern<Cents>,
|
||||
pub realized_price: CentsSatsUsdPattern,
|
||||
@@ -1273,7 +1277,7 @@ impl MvrvNegNetRealizedSoprValuePattern {
|
||||
net_realized_pnl: CumulativeHeightPattern::new(client.clone(), _m(&acc, "net_realized_pnl")),
|
||||
realized_cap: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap")),
|
||||
realized_cap_cents: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap_cents")),
|
||||
realized_cap_change_1m: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap_change_1m")),
|
||||
realized_cap_delta: ChangeRatePattern::new(client.clone(), _m(&acc, "realized_cap_delta")),
|
||||
realized_loss: CumulativeHeightPattern::new(client.clone(), _m(&acc, "realized_loss")),
|
||||
realized_loss_sum: _24hPattern::new(client.clone(), _m(&acc, "realized_loss_24h")),
|
||||
realized_price: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "realized_price")),
|
||||
@@ -1934,7 +1938,7 @@ pub struct ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern {
|
||||
pub outputs: UtxoPattern,
|
||||
pub realized: MvrvNegNetRealizedSentSoprValuePattern,
|
||||
pub relative: SupplyPattern2,
|
||||
pub supply: ChangeHalvedTotalPattern,
|
||||
pub supply: DeltaHalvedTotalPattern,
|
||||
pub unrealized: InvestedInvestorNegNetSupplyUnrealizedPattern,
|
||||
}
|
||||
|
||||
@@ -1947,7 +1951,7 @@ impl ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern {
|
||||
outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")),
|
||||
realized: MvrvNegNetRealizedSentSoprValuePattern::new(client.clone(), acc.clone()),
|
||||
relative: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
|
||||
supply: ChangeHalvedTotalPattern::new(client.clone(), _m(&acc, "supply")),
|
||||
supply: DeltaHalvedTotalPattern::new(client.clone(), _m(&acc, "supply")),
|
||||
unrealized: InvestedInvestorNegNetSupplyUnrealizedPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
@@ -1957,10 +1961,10 @@ impl ActivityCostOutputsRealizedRelativeSupplyUnrealizedPattern {
|
||||
pub struct ActivityAddrOutputsRealizedSupplyUnrealizedPattern {
|
||||
pub activity: SentPattern,
|
||||
pub addr_count: MetricPattern1<StoredU64>,
|
||||
pub addr_count_change_1m: MetricPattern1<StoredF64>,
|
||||
pub addr_count_delta: ChangeRatePattern<StoredI64>,
|
||||
pub outputs: UtxoPattern,
|
||||
pub realized: MvrvRealizedPattern,
|
||||
pub supply: ChangeHalvedTotalPattern,
|
||||
pub supply: DeltaHalvedTotalPattern,
|
||||
pub unrealized: SupplyPattern,
|
||||
}
|
||||
|
||||
@@ -1970,10 +1974,10 @@ impl ActivityAddrOutputsRealizedSupplyUnrealizedPattern {
|
||||
Self {
|
||||
activity: SentPattern::new(client.clone(), _m(&acc, "sent")),
|
||||
addr_count: MetricPattern1::new(client.clone(), _m(&acc, "addr_count")),
|
||||
addr_count_change_1m: MetricPattern1::new(client.clone(), _m(&acc, "addr_count_change_1m")),
|
||||
addr_count_delta: ChangeRatePattern::new(client.clone(), _m(&acc, "addr_count_delta")),
|
||||
outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")),
|
||||
realized: MvrvRealizedPattern::new(client.clone(), acc.clone()),
|
||||
supply: ChangeHalvedTotalPattern::new(client.clone(), _m(&acc, "supply")),
|
||||
supply: DeltaHalvedTotalPattern::new(client.clone(), _m(&acc, "supply")),
|
||||
unrealized: SupplyPattern::new(client.clone(), _m(&acc, "supply_in")),
|
||||
}
|
||||
}
|
||||
@@ -1985,7 +1989,7 @@ pub struct ActivityOutputsRealizedRelativeSupplyUnrealizedPattern {
|
||||
pub outputs: UtxoPattern,
|
||||
pub realized: MvrvNegNetRealizedSoprValuePattern,
|
||||
pub relative: SupplyPattern2,
|
||||
pub supply: ChangeHalvedTotalPattern,
|
||||
pub supply: DeltaHalvedTotalPattern,
|
||||
pub unrealized: NegNetSupplyUnrealizedPattern,
|
||||
}
|
||||
|
||||
@@ -1997,7 +2001,7 @@ impl ActivityOutputsRealizedRelativeSupplyUnrealizedPattern {
|
||||
outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")),
|
||||
realized: MvrvNegNetRealizedSoprValuePattern::new(client.clone(), acc.clone()),
|
||||
relative: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
|
||||
supply: ChangeHalvedTotalPattern::new(client.clone(), _m(&acc, "supply")),
|
||||
supply: DeltaHalvedTotalPattern::new(client.clone(), _m(&acc, "supply")),
|
||||
unrealized: NegNetSupplyUnrealizedPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
@@ -2032,7 +2036,7 @@ pub struct ActivityOutputsRealizedSupplyUnrealizedPattern {
|
||||
pub activity: SentPattern,
|
||||
pub outputs: UtxoPattern,
|
||||
pub realized: MvrvRealizedPattern,
|
||||
pub supply: ChangeHalvedTotalPattern,
|
||||
pub supply: DeltaHalvedTotalPattern,
|
||||
pub unrealized: SupplyPattern,
|
||||
}
|
||||
|
||||
@@ -2043,7 +2047,7 @@ impl ActivityOutputsRealizedSupplyUnrealizedPattern {
|
||||
activity: SentPattern::new(client.clone(), _m(&acc, "sent")),
|
||||
outputs: UtxoPattern::new(client.clone(), _m(&acc, "utxo_count")),
|
||||
realized: MvrvRealizedPattern::new(client.clone(), acc.clone()),
|
||||
supply: ChangeHalvedTotalPattern::new(client.clone(), _m(&acc, "supply")),
|
||||
supply: DeltaHalvedTotalPattern::new(client.clone(), _m(&acc, "supply")),
|
||||
unrealized: SupplyPattern::new(client.clone(), _m(&acc, "supply_in")),
|
||||
}
|
||||
}
|
||||
@@ -2115,6 +2119,28 @@ impl<T: DeserializeOwned> _1m1w1y24hHeightPattern<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _24hChangeRatePattern<T> {
|
||||
pub _24h: BaseBpsPercentRatioPattern,
|
||||
pub change_1w: MetricPattern1<T>,
|
||||
pub change_1y: MetricPattern1<T>,
|
||||
pub rate_1w: BpsPercentRatioPattern,
|
||||
pub rate_1y: BpsPercentRatioPattern,
|
||||
}
|
||||
|
||||
impl<T: DeserializeOwned> _24hChangeRatePattern<T> {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
_24h: BaseBpsPercentRatioPattern::new(client.clone(), acc.clone()),
|
||||
change_1w: MetricPattern1::new(client.clone(), _m(&acc, "change_1w")),
|
||||
change_1y: MetricPattern1::new(client.clone(), _m(&acc, "change_1y")),
|
||||
rate_1w: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rate_1w")),
|
||||
rate_1y: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rate_1y")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _1m1w1y24hPattern6 {
|
||||
pub _1m: BaseBtcCentsSatsUsdPattern,
|
||||
@@ -2175,6 +2201,26 @@ impl _1m1w1y24hPattern5 {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct BaseBpsPercentRatioPattern {
|
||||
pub base: MetricPattern1<CentsSigned>,
|
||||
pub bps: MetricPattern1<BasisPointsSigned32>,
|
||||
pub percent: MetricPattern1<StoredF32>,
|
||||
pub ratio: MetricPattern1<StoredF32>,
|
||||
}
|
||||
|
||||
impl BaseBpsPercentRatioPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
base: MetricPattern1::new(client.clone(), _m(&acc, "change_24h")),
|
||||
bps: MetricPattern1::new(client.clone(), _m(&acc, "rate_24h_bps")),
|
||||
percent: MetricPattern1::new(client.clone(), _m(&acc, "rate_24h")),
|
||||
ratio: MetricPattern1::new(client.clone(), _m(&acc, "rate_24h_ratio")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct BothReactivatedReceivingSendingPattern {
|
||||
pub both: _1m1w1y24hHeightPattern<StoredU32>,
|
||||
@@ -2386,17 +2432,17 @@ impl CentsSatsUsdPattern {
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct ChangeHalvedTotalPattern {
|
||||
pub change_1m: BtcCentsSatsUsdPattern,
|
||||
pub struct DeltaHalvedTotalPattern {
|
||||
pub delta: ChangeRatePattern<SatsSigned>,
|
||||
pub halved: BtcCentsSatsUsdPattern,
|
||||
pub total: BtcCentsSatsUsdPattern,
|
||||
}
|
||||
|
||||
impl ChangeHalvedTotalPattern {
|
||||
impl DeltaHalvedTotalPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
change_1m: BtcCentsSatsUsdPattern::new(client.clone(), _m(&acc, "change_1m")),
|
||||
delta: ChangeRatePattern::new(client.clone(), _m(&acc, "delta")),
|
||||
halved: BtcCentsSatsUsdPattern::new(client.clone(), _m(&acc, "halved")),
|
||||
total: BtcCentsSatsUsdPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
@@ -2540,12 +2586,12 @@ impl CentsUsdPattern {
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct ChangeRatePattern {
|
||||
pub struct ChangeRatePattern2 {
|
||||
pub change: _1m1w1y24hPattern<StoredI64>,
|
||||
pub rate: _1m1w1y24hPattern2,
|
||||
}
|
||||
|
||||
impl ChangeRatePattern {
|
||||
impl ChangeRatePattern2 {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
@@ -2622,7 +2668,7 @@ impl SupplyPattern {
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct UtxoPattern {
|
||||
pub utxo_count: MetricPattern1<StoredU64>,
|
||||
pub utxo_count_change_1m: MetricPattern1<StoredF64>,
|
||||
pub utxo_count_delta: ChangeRatePattern<StoredI64>,
|
||||
}
|
||||
|
||||
impl UtxoPattern {
|
||||
@@ -2630,7 +2676,23 @@ impl UtxoPattern {
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
utxo_count: MetricPattern1::new(client.clone(), acc.clone()),
|
||||
utxo_count_change_1m: MetricPattern1::new(client.clone(), _m(&acc, "change_1m")),
|
||||
utxo_count_delta: ChangeRatePattern::new(client.clone(), _m(&acc, "delta")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct ChangeRatePattern<T> {
|
||||
pub change_1m: MetricPattern1<T>,
|
||||
pub rate_1m: BpsPercentRatioPattern,
|
||||
}
|
||||
|
||||
impl<T: DeserializeOwned> ChangeRatePattern<T> {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
change_1m: MetricPattern1::new(client.clone(), _m(&acc, "change_1m")),
|
||||
rate_1m: BpsPercentRatioPattern::new(client.clone(), _m(&acc, "rate_1m")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5521,7 +5583,7 @@ impl MetricsTree_Distribution_UtxoCohorts {
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Distribution_UtxoCohorts_All {
|
||||
pub supply: ChangeHalvedTotalPattern,
|
||||
pub supply: DeltaHalvedTotalPattern,
|
||||
pub outputs: UtxoPattern,
|
||||
pub activity: CoinblocksCoindaysSentPattern2,
|
||||
pub realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern,
|
||||
@@ -5531,12 +5593,14 @@ pub struct MetricsTree_Distribution_UtxoCohorts_All {
|
||||
pub relative: MetricsTree_Distribution_UtxoCohorts_All_Relative,
|
||||
pub dormancy: MetricPattern1<StoredF32>,
|
||||
pub velocity: MetricPattern1<StoredF32>,
|
||||
pub supply_delta_extended: _24hChangeRatePattern<SatsSigned>,
|
||||
pub utxo_count_delta_extended: _24hChangeRatePattern<StoredI64>,
|
||||
}
|
||||
|
||||
impl MetricsTree_Distribution_UtxoCohorts_All {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
supply: ChangeHalvedTotalPattern::new(client.clone(), "supply".to_string()),
|
||||
supply: DeltaHalvedTotalPattern::new(client.clone(), "supply".to_string()),
|
||||
outputs: UtxoPattern::new(client.clone(), "utxo_count".to_string()),
|
||||
activity: CoinblocksCoindaysSentPattern2::new(client.clone(), "".to_string()),
|
||||
realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern::new(client.clone(), "".to_string()),
|
||||
@@ -5546,6 +5610,8 @@ impl MetricsTree_Distribution_UtxoCohorts_All {
|
||||
relative: MetricsTree_Distribution_UtxoCohorts_All_Relative::new(client.clone(), format!("{base_path}_relative")),
|
||||
dormancy: MetricPattern1::new(client.clone(), "dormancy".to_string()),
|
||||
velocity: MetricPattern1::new(client.clone(), "velocity".to_string()),
|
||||
supply_delta_extended: _24hChangeRatePattern::new(client.clone(), "supply_delta".to_string()),
|
||||
utxo_count_delta_extended: _24hChangeRatePattern::new(client.clone(), "utxo_count_delta".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5602,7 +5668,7 @@ impl MetricsTree_Distribution_UtxoCohorts_All_Relative {
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Distribution_UtxoCohorts_Sth {
|
||||
pub supply: ChangeHalvedTotalPattern,
|
||||
pub supply: DeltaHalvedTotalPattern,
|
||||
pub outputs: UtxoPattern,
|
||||
pub activity: CoinblocksCoindaysSentPattern2,
|
||||
pub realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern,
|
||||
@@ -5611,6 +5677,8 @@ pub struct MetricsTree_Distribution_UtxoCohorts_Sth {
|
||||
pub relative: NetNuplSupplyUnrealizedPattern2,
|
||||
pub dormancy: MetricPattern1<StoredF32>,
|
||||
pub velocity: MetricPattern1<StoredF32>,
|
||||
pub supply_delta_extended: _24hChangeRatePattern<SatsSigned>,
|
||||
pub utxo_count_delta_extended: _24hChangeRatePattern<StoredI64>,
|
||||
pub adjusted_value_created: MetricPattern1<Cents>,
|
||||
pub adjusted_value_destroyed: MetricPattern1<Cents>,
|
||||
pub adjusted_value_created_sum: _1m1w1y24hPattern<Cents>,
|
||||
@@ -5621,7 +5689,7 @@ pub struct MetricsTree_Distribution_UtxoCohorts_Sth {
|
||||
impl MetricsTree_Distribution_UtxoCohorts_Sth {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
supply: ChangeHalvedTotalPattern::new(client.clone(), "sth_supply".to_string()),
|
||||
supply: DeltaHalvedTotalPattern::new(client.clone(), "sth_supply".to_string()),
|
||||
outputs: UtxoPattern::new(client.clone(), "sth_utxo_count".to_string()),
|
||||
activity: CoinblocksCoindaysSentPattern2::new(client.clone(), "sth".to_string()),
|
||||
realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern::new(client.clone(), "sth".to_string()),
|
||||
@@ -5630,6 +5698,8 @@ impl MetricsTree_Distribution_UtxoCohorts_Sth {
|
||||
relative: NetNuplSupplyUnrealizedPattern2::new(client.clone(), "sth".to_string()),
|
||||
dormancy: MetricPattern1::new(client.clone(), "sth_dormancy".to_string()),
|
||||
velocity: MetricPattern1::new(client.clone(), "sth_velocity".to_string()),
|
||||
supply_delta_extended: _24hChangeRatePattern::new(client.clone(), "sth_supply_delta".to_string()),
|
||||
utxo_count_delta_extended: _24hChangeRatePattern::new(client.clone(), "sth_utxo_count_delta".to_string()),
|
||||
adjusted_value_created: MetricPattern1::new(client.clone(), "sth_adjusted_value_created".to_string()),
|
||||
adjusted_value_destroyed: MetricPattern1::new(client.clone(), "sth_adjusted_value_destroyed".to_string()),
|
||||
adjusted_value_created_sum: _1m1w1y24hPattern::new(client.clone(), "sth_adjusted_value_created".to_string()),
|
||||
@@ -5641,7 +5711,7 @@ impl MetricsTree_Distribution_UtxoCohorts_Sth {
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Distribution_UtxoCohorts_Lth {
|
||||
pub supply: ChangeHalvedTotalPattern,
|
||||
pub supply: DeltaHalvedTotalPattern,
|
||||
pub outputs: UtxoPattern,
|
||||
pub activity: CoinblocksCoindaysSentPattern2,
|
||||
pub realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern,
|
||||
@@ -5650,12 +5720,14 @@ pub struct MetricsTree_Distribution_UtxoCohorts_Lth {
|
||||
pub relative: NetNuplSupplyUnrealizedPattern2,
|
||||
pub dormancy: MetricPattern1<StoredF32>,
|
||||
pub velocity: MetricPattern1<StoredF32>,
|
||||
pub supply_delta_extended: _24hChangeRatePattern<SatsSigned>,
|
||||
pub utxo_count_delta_extended: _24hChangeRatePattern<StoredI64>,
|
||||
}
|
||||
|
||||
impl MetricsTree_Distribution_UtxoCohorts_Lth {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
supply: ChangeHalvedTotalPattern::new(client.clone(), "lth_supply".to_string()),
|
||||
supply: DeltaHalvedTotalPattern::new(client.clone(), "lth_supply".to_string()),
|
||||
outputs: UtxoPattern::new(client.clone(), "lth_utxo_count".to_string()),
|
||||
activity: CoinblocksCoindaysSentPattern2::new(client.clone(), "lth".to_string()),
|
||||
realized: CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern::new(client.clone(), "lth".to_string()),
|
||||
@@ -5664,6 +5736,8 @@ impl MetricsTree_Distribution_UtxoCohorts_Lth {
|
||||
relative: NetNuplSupplyUnrealizedPattern2::new(client.clone(), "lth".to_string()),
|
||||
dormancy: MetricPattern1::new(client.clone(), "lth_dormancy".to_string()),
|
||||
velocity: MetricPattern1::new(client.clone(), "lth_velocity".to_string()),
|
||||
supply_delta_extended: _24hChangeRatePattern::new(client.clone(), "lth_supply_delta".to_string()),
|
||||
utxo_count_delta_extended: _24hChangeRatePattern::new(client.clone(), "lth_utxo_count_delta".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6223,29 +6297,29 @@ impl MetricsTree_Distribution_NewAddrCount {
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Distribution_Delta {
|
||||
pub all: ChangeRatePattern,
|
||||
pub p2pk65: ChangeRatePattern,
|
||||
pub p2pk33: ChangeRatePattern,
|
||||
pub p2pkh: ChangeRatePattern,
|
||||
pub p2sh: ChangeRatePattern,
|
||||
pub p2wpkh: ChangeRatePattern,
|
||||
pub p2wsh: ChangeRatePattern,
|
||||
pub p2tr: ChangeRatePattern,
|
||||
pub p2a: ChangeRatePattern,
|
||||
pub all: ChangeRatePattern2,
|
||||
pub p2pk65: ChangeRatePattern2,
|
||||
pub p2pk33: ChangeRatePattern2,
|
||||
pub p2pkh: ChangeRatePattern2,
|
||||
pub p2sh: ChangeRatePattern2,
|
||||
pub p2wpkh: ChangeRatePattern2,
|
||||
pub p2wsh: ChangeRatePattern2,
|
||||
pub p2tr: ChangeRatePattern2,
|
||||
pub p2a: ChangeRatePattern2,
|
||||
}
|
||||
|
||||
impl MetricsTree_Distribution_Delta {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
all: ChangeRatePattern::new(client.clone(), "addr_count".to_string()),
|
||||
p2pk65: ChangeRatePattern::new(client.clone(), "p2pk65_addr_count".to_string()),
|
||||
p2pk33: ChangeRatePattern::new(client.clone(), "p2pk33_addr_count".to_string()),
|
||||
p2pkh: ChangeRatePattern::new(client.clone(), "p2pkh_addr_count".to_string()),
|
||||
p2sh: ChangeRatePattern::new(client.clone(), "p2sh_addr_count".to_string()),
|
||||
p2wpkh: ChangeRatePattern::new(client.clone(), "p2wpkh_addr_count".to_string()),
|
||||
p2wsh: ChangeRatePattern::new(client.clone(), "p2wsh_addr_count".to_string()),
|
||||
p2tr: ChangeRatePattern::new(client.clone(), "p2tr_addr_count".to_string()),
|
||||
p2a: ChangeRatePattern::new(client.clone(), "p2a_addr_count".to_string()),
|
||||
all: ChangeRatePattern2::new(client.clone(), "addr_count".to_string()),
|
||||
p2pk65: ChangeRatePattern2::new(client.clone(), "p2pk65_addr_count".to_string()),
|
||||
p2pk33: ChangeRatePattern2::new(client.clone(), "p2pk33_addr_count".to_string()),
|
||||
p2pkh: ChangeRatePattern2::new(client.clone(), "p2pkh_addr_count".to_string()),
|
||||
p2sh: ChangeRatePattern2::new(client.clone(), "p2sh_addr_count".to_string()),
|
||||
p2wpkh: ChangeRatePattern2::new(client.clone(), "p2wpkh_addr_count".to_string()),
|
||||
p2wsh: ChangeRatePattern2::new(client.clone(), "p2wsh_addr_count".to_string()),
|
||||
p2tr: ChangeRatePattern2::new(client.clone(), "p2tr_addr_count".to_string()),
|
||||
p2a: ChangeRatePattern2::new(client.clone(), "p2a_addr_count".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6257,9 +6331,9 @@ pub struct MetricsTree_Supply {
|
||||
pub inflation_rate: BpsPercentRatioPattern,
|
||||
pub velocity: MetricsTree_Supply_Velocity,
|
||||
pub market_cap: MetricPattern1<Dollars>,
|
||||
pub market_cap_growth_rate: BpsPercentRatioPattern,
|
||||
pub realized_cap_growth_rate: BpsPercentRatioPattern,
|
||||
pub market_minus_realized_cap_growth_rate: MetricPattern1<BasisPointsSigned32>,
|
||||
pub market_cap_growth_rate: _1m1w1y24hPattern2,
|
||||
pub realized_cap_growth_rate: _1m1w1y24hPattern2,
|
||||
pub market_minus_realized_cap_growth_rate: _1m1w1y24hPattern<BasisPointsSigned32>,
|
||||
}
|
||||
|
||||
impl MetricsTree_Supply {
|
||||
@@ -6270,9 +6344,9 @@ impl MetricsTree_Supply {
|
||||
inflation_rate: BpsPercentRatioPattern::new(client.clone(), "inflation_rate".to_string()),
|
||||
velocity: MetricsTree_Supply_Velocity::new(client.clone(), format!("{base_path}_velocity")),
|
||||
market_cap: MetricPattern1::new(client.clone(), "market_cap".to_string()),
|
||||
market_cap_growth_rate: BpsPercentRatioPattern::new(client.clone(), "market_cap_growth_rate".to_string()),
|
||||
realized_cap_growth_rate: BpsPercentRatioPattern::new(client.clone(), "realized_cap_growth_rate".to_string()),
|
||||
market_minus_realized_cap_growth_rate: MetricPattern1::new(client.clone(), "market_minus_realized_cap_growth_rate".to_string()),
|
||||
market_cap_growth_rate: _1m1w1y24hPattern2::new(client.clone(), "market_cap_growth_rate".to_string()),
|
||||
realized_cap_growth_rate: _1m1w1y24hPattern2::new(client.clone(), "realized_cap_growth_rate".to_string()),
|
||||
market_minus_realized_cap_growth_rate: _1m1w1y24hPattern::new(client.clone(), "market_minus_realized_cap_growth_rate".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use vecdb::{Database, Exit, Rw, StorageMode};
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{ComputedFromHeightFull, WindowStarts},
|
||||
internal::{ComputedFromHeightSum, WindowStarts},
|
||||
};
|
||||
|
||||
use super::TotalAddrCountVecs;
|
||||
@@ -14,9 +14,9 @@ use super::TotalAddrCountVecs;
|
||||
/// New address count per block (global + per-type)
|
||||
#[derive(Traversable)]
|
||||
pub struct NewAddrCountVecs<M: StorageMode = Rw> {
|
||||
pub all: ComputedFromHeightFull<StoredU64, M>,
|
||||
pub all: ComputedFromHeightSum<StoredU64, M>,
|
||||
#[traversable(flatten)]
|
||||
pub by_addresstype: ByAddressType<ComputedFromHeightFull<StoredU64, M>>,
|
||||
pub by_addresstype: ByAddressType<ComputedFromHeightSum<StoredU64, M>>,
|
||||
}
|
||||
|
||||
impl NewAddrCountVecs {
|
||||
@@ -25,11 +25,11 @@ impl NewAddrCountVecs {
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
let all = ComputedFromHeightFull::forced_import(db, "new_addr_count", version, indexes)?;
|
||||
let all = ComputedFromHeightSum::forced_import(db, "new_addr_count", version, indexes)?;
|
||||
|
||||
let by_addresstype: ByAddressType<ComputedFromHeightFull<StoredU64>> =
|
||||
let by_addresstype: ByAddressType<ComputedFromHeightSum<StoredU64>> =
|
||||
ByAddressType::new_with_name(|name| {
|
||||
ComputedFromHeightFull::forced_import(
|
||||
ComputedFromHeightSum::forced_import(
|
||||
db,
|
||||
&format!("{name}_new_addr_count"),
|
||||
version,
|
||||
|
||||
@@ -96,7 +96,7 @@ impl AddressCohorts {
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.par_iter_mut().try_for_each(|v| {
|
||||
v.addr_count_change_1m.height.compute_rolling_change(
|
||||
v.addr_count_delta.compute(
|
||||
starting_indexes.height,
|
||||
&blocks.count.height_1m_ago,
|
||||
&v.addr_count.height,
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::path::Path;
|
||||
use brk_cohort::{CohortContext, Filter, Filtered};
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Cents, Height, Indexes, StoredF64, StoredU64, Version};
|
||||
use brk_types::{Cents, Height, Indexes, StoredI64, StoredU64, Version};
|
||||
use rayon::prelude::*;
|
||||
use vecdb::{AnyStoredVec, AnyVec, Database, Exit, ReadableVec, Rw, StorageMode, WritableVec};
|
||||
|
||||
@@ -11,7 +11,7 @@ use crate::{
|
||||
blocks,
|
||||
distribution::state::{AddressCohortState, MinimalRealizedState},
|
||||
indexes,
|
||||
internal::ComputedFromHeight,
|
||||
internal::{ComputedFromHeight, RollingDelta1m},
|
||||
prices,
|
||||
};
|
||||
|
||||
@@ -29,7 +29,7 @@ pub struct AddressCohortVecs<M: StorageMode = Rw> {
|
||||
pub metrics: MinimalCohortMetrics<M>,
|
||||
|
||||
pub addr_count: ComputedFromHeight<StoredU64, M>,
|
||||
pub addr_count_change_1m: ComputedFromHeight<StoredF64, M>,
|
||||
pub addr_count_delta: RollingDelta1m<StoredU64, StoredI64, M>,
|
||||
}
|
||||
|
||||
impl AddressCohortVecs {
|
||||
@@ -64,10 +64,10 @@ impl AddressCohortVecs {
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
addr_count_change_1m: ComputedFromHeight::forced_import(
|
||||
addr_count_delta: RollingDelta1m::forced_import(
|
||||
db,
|
||||
&cfg.name("addr_count_change_1m"),
|
||||
version,
|
||||
&cfg.name("addr_count_delta"),
|
||||
version + Version::ONE,
|
||||
indexes,
|
||||
)?,
|
||||
})
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
use brk_cohort::Filter;
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Bitcoin, Cents, Dollars, Height, Indexes, StoredF32, Version};
|
||||
use brk_types::{
|
||||
Bitcoin, Cents, Dollars, Height, Indexes, Sats, SatsSigned, StoredF32, StoredI64, StoredU64,
|
||||
Version,
|
||||
};
|
||||
use vecdb::AnyStoredVec;
|
||||
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
||||
|
||||
use crate::{blocks, prices};
|
||||
|
||||
use crate::internal::ComputedFromHeight;
|
||||
use crate::internal::{ComputedFromHeight, RollingDeltaExcept1m};
|
||||
|
||||
use crate::distribution::metrics::{
|
||||
ActivityFull, CohortMetricsBase, CostBasisWithExtended, ImportConfig, OutputsMetrics,
|
||||
@@ -31,6 +34,9 @@ pub struct AllCohortMetrics<M: StorageMode = Rw> {
|
||||
pub relative: Box<RelativeForAll<M>>,
|
||||
pub dormancy: ComputedFromHeight<StoredF32, M>,
|
||||
pub velocity: ComputedFromHeight<StoredF32, M>,
|
||||
|
||||
pub supply_delta_extended: RollingDeltaExcept1m<Sats, SatsSigned, M>,
|
||||
pub utxo_count_delta_extended: RollingDeltaExcept1m<StoredU64, StoredI64, M>,
|
||||
}
|
||||
|
||||
impl CohortMetricsBase for AllCohortMetrics {
|
||||
@@ -82,6 +88,8 @@ impl AllCohortMetrics {
|
||||
relative: Box::new(relative),
|
||||
dormancy: cfg.import("dormancy", Version::ONE)?,
|
||||
velocity: cfg.import("velocity", Version::ONE)?,
|
||||
supply_delta_extended: cfg.import("supply_delta", Version::ONE)?,
|
||||
utxo_count_delta_extended: cfg.import("utxo_count_delta", Version::ONE)?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -123,6 +131,20 @@ impl AllCohortMetrics {
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let window_starts = blocks.count.window_starts();
|
||||
self.supply_delta_extended.compute(
|
||||
starting_indexes.height,
|
||||
&window_starts,
|
||||
&self.supply.total.sats.height,
|
||||
exit,
|
||||
)?;
|
||||
self.utxo_count_delta_extended.compute(
|
||||
starting_indexes.height,
|
||||
&window_starts,
|
||||
&self.outputs.utxo_count.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dormancy.height.compute_transform2(
|
||||
starting_indexes.height,
|
||||
&self.activity.coindays_destroyed.height,
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
use brk_cohort::Filter;
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Bitcoin, Dollars, Height, Indexes, Sats, StoredF32, Version};
|
||||
use brk_types::{
|
||||
Bitcoin, Dollars, Height, Indexes, Sats, SatsSigned, StoredF32, StoredI64, StoredU64, Version,
|
||||
};
|
||||
use vecdb::AnyStoredVec;
|
||||
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
||||
|
||||
use crate::{blocks, prices};
|
||||
|
||||
use crate::internal::ComputedFromHeight;
|
||||
use crate::internal::{ComputedFromHeight, RollingDeltaExcept1m};
|
||||
|
||||
use crate::distribution::metrics::{
|
||||
ActivityFull, CohortMetricsBase, CostBasisWithExtended, ImportConfig, OutputsMetrics,
|
||||
@@ -29,6 +31,9 @@ pub struct ExtendedCohortMetrics<M: StorageMode = Rw> {
|
||||
pub relative: Box<RelativeWithExtended<M>>,
|
||||
pub dormancy: ComputedFromHeight<StoredF32, M>,
|
||||
pub velocity: ComputedFromHeight<StoredF32, M>,
|
||||
|
||||
pub supply_delta_extended: RollingDeltaExcept1m<Sats, SatsSigned, M>,
|
||||
pub utxo_count_delta_extended: RollingDeltaExcept1m<StoredU64, StoredI64, M>,
|
||||
}
|
||||
|
||||
impl CohortMetricsBase for ExtendedCohortMetrics {
|
||||
@@ -72,6 +77,8 @@ impl ExtendedCohortMetrics {
|
||||
relative: Box::new(relative),
|
||||
dormancy: cfg.import("dormancy", Version::ONE)?,
|
||||
velocity: cfg.import("velocity", Version::ONE)?,
|
||||
supply_delta_extended: cfg.import("supply_delta", Version::ONE)?,
|
||||
utxo_count_delta_extended: cfg.import("utxo_count_delta", Version::ONE)?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -103,6 +110,20 @@ impl ExtendedCohortMetrics {
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let window_starts = blocks.count.window_starts();
|
||||
self.supply_delta_extended.compute(
|
||||
starting_indexes.height,
|
||||
&window_starts,
|
||||
&self.supply.total.sats.height,
|
||||
exit,
|
||||
)?;
|
||||
self.utxo_count_delta_extended.compute(
|
||||
starting_indexes.height,
|
||||
&window_starts,
|
||||
&self.outputs.utxo_count.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dormancy.height.compute_transform2(
|
||||
starting_indexes.height,
|
||||
&self.activity.coindays_destroyed.height,
|
||||
|
||||
@@ -11,9 +11,9 @@ use crate::{
|
||||
internal::{
|
||||
CentsType, ComputedFromHeight, ComputedFromHeightCumulative,
|
||||
ComputedFromHeightCumulativeSum, ComputedFromHeightRatio, FiatFromHeight, NumericValue,
|
||||
PercentFromHeight, PercentRollingWindows, Price,
|
||||
PercentFromHeight, PercentRollingWindows, Price, RollingDelta1m, RollingDeltaExcept1m,
|
||||
RollingWindow24h, RollingWindows, RollingWindowsFrom1w,
|
||||
ValueFromHeight, ValueFromHeightChange, ValueFromHeightCumulative,
|
||||
ValueFromHeight, ValueFromHeightCumulative,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -39,7 +39,6 @@ macro_rules! impl_config_import {
|
||||
impl_config_import!(
|
||||
ValueFromHeight,
|
||||
ValueFromHeightCumulative,
|
||||
ValueFromHeightChange,
|
||||
ComputedFromHeightRatio,
|
||||
PercentFromHeight<BasisPoints16>,
|
||||
PercentFromHeight<BasisPoints32>,
|
||||
@@ -84,6 +83,19 @@ impl<C: CentsType> ConfigImport for FiatFromHeight<C> {
|
||||
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
|
||||
}
|
||||
}
|
||||
impl<S: NumericValue + JsonSchema, C: NumericValue + JsonSchema> ConfigImport for RollingDelta1m<S, C>
|
||||
{
|
||||
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
|
||||
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
|
||||
}
|
||||
}
|
||||
impl<S: NumericValue + JsonSchema, C: NumericValue + JsonSchema> ConfigImport
|
||||
for RollingDeltaExcept1m<S, C>
|
||||
{
|
||||
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
|
||||
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
|
||||
}
|
||||
}
|
||||
impl<T: BytesVecValue> ConfigImport for BytesVec<Height, T> {
|
||||
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
|
||||
Ok(Self::forced_import(
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Height, Indexes, StoredF64, StoredU64, Version};
|
||||
use brk_types::{Height, Indexes, StoredI64, StoredU64, Version};
|
||||
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
|
||||
|
||||
use crate::{blocks, internal::ComputedFromHeight};
|
||||
use crate::{blocks, internal::{ComputedFromHeight, RollingDelta1m}};
|
||||
|
||||
use super::ImportConfig;
|
||||
|
||||
@@ -11,7 +11,7 @@ use super::ImportConfig;
|
||||
#[derive(Traversable)]
|
||||
pub struct OutputsMetrics<M: StorageMode = Rw> {
|
||||
pub utxo_count: ComputedFromHeight<StoredU64, M>,
|
||||
pub utxo_count_change_1m: ComputedFromHeight<StoredF64, M>,
|
||||
pub utxo_count_delta: RollingDelta1m<StoredU64, StoredI64, M>,
|
||||
}
|
||||
|
||||
impl OutputsMetrics {
|
||||
@@ -19,7 +19,7 @@ impl OutputsMetrics {
|
||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||
Ok(Self {
|
||||
utxo_count: cfg.import("utxo_count", Version::ZERO)?,
|
||||
utxo_count_change_1m: cfg.import("utxo_count_change_1m", Version::ZERO)?,
|
||||
utxo_count_delta: cfg.import("utxo_count_delta", Version::ONE)?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ impl OutputsMetrics {
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.utxo_count_change_1m.height.compute_rolling_change(
|
||||
self.utxo_count_delta.compute(
|
||||
starting_indexes.height,
|
||||
&blocks.count.height_1m_ago,
|
||||
&self.utxo_count.height,
|
||||
|
||||
@@ -11,7 +11,7 @@ use crate::{
|
||||
distribution::state::RealizedOps,
|
||||
internal::{
|
||||
ComputedFromHeight, ComputedFromHeightCumulative, LazyFromHeight,
|
||||
NegCentsUnsignedToDollars, RatioCents64, RollingWindow24h,
|
||||
NegCentsUnsignedToDollars, RatioCents64, RollingDelta1m, RollingWindow24h,
|
||||
},
|
||||
prices,
|
||||
};
|
||||
@@ -27,7 +27,7 @@ pub struct RealizedCore<M: StorageMode = Rw> {
|
||||
#[traversable(flatten)]
|
||||
pub minimal: RealizedMinimal<M>,
|
||||
|
||||
pub realized_cap_change_1m: ComputedFromHeight<CentsSigned, M>,
|
||||
pub realized_cap_delta: RollingDelta1m<Cents, CentsSigned, M>,
|
||||
|
||||
pub neg_realized_loss: LazyFromHeight<Dollars, Cents>,
|
||||
pub net_realized_pnl: ComputedFromHeightCumulative<CentsSigned, M>,
|
||||
@@ -63,7 +63,7 @@ impl RealizedCore {
|
||||
|
||||
Ok(Self {
|
||||
minimal,
|
||||
realized_cap_change_1m: cfg.import("realized_cap_change_1m", v0)?,
|
||||
realized_cap_delta: cfg.import("realized_cap_delta", v1)?,
|
||||
neg_realized_loss,
|
||||
net_realized_pnl,
|
||||
value_created,
|
||||
@@ -154,7 +154,7 @@ impl RealizedCore {
|
||||
self.minimal
|
||||
.compute_rest_part2(prices, starting_indexes, height_to_supply, exit)?;
|
||||
|
||||
self.realized_cap_change_1m.height.compute_rolling_change(
|
||||
self.realized_cap_delta.compute(
|
||||
starting_indexes.height,
|
||||
&blocks.count.height_1m_ago,
|
||||
&self.minimal.realized_cap_cents.height,
|
||||
|
||||
@@ -19,7 +19,7 @@ use crate::{
|
||||
ComputedFromHeightRatioStdDevBands, LazyFromHeight, PercentFromHeight,
|
||||
PercentRollingWindows, Price, RatioCents64, RatioCentsBp32,
|
||||
RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32, RatioDollarsBp32,
|
||||
RollingWindows, RollingWindowsFrom1w,
|
||||
RollingDelta1m, RollingDeltaExcept1m, RollingWindows, RollingWindowsFrom1w,
|
||||
},
|
||||
prices,
|
||||
};
|
||||
@@ -56,10 +56,13 @@ pub struct RealizedFull<M: StorageMode = Rw> {
|
||||
|
||||
pub gross_pnl_sum: RollingWindows<Cents, M>,
|
||||
|
||||
pub net_pnl_change_1m: ComputedFromHeight<CentsSigned, M>,
|
||||
pub net_pnl_delta: RollingDelta1m<CentsSigned, CentsSigned, M>,
|
||||
pub net_pnl_delta_extended: RollingDeltaExcept1m<CentsSigned, CentsSigned, M>,
|
||||
pub net_pnl_change_1m_rel_to_realized_cap: PercentFromHeight<BasisPointsSigned32, M>,
|
||||
pub net_pnl_change_1m_rel_to_market_cap: PercentFromHeight<BasisPointsSigned32, M>,
|
||||
|
||||
pub realized_cap_delta_extended: RollingDeltaExcept1m<Cents, CentsSigned, M>,
|
||||
|
||||
pub investor_price: Price<ComputedFromHeight<Cents, M>>,
|
||||
pub investor_price_ratio: ComputedFromHeightRatio<M>,
|
||||
|
||||
@@ -176,11 +179,13 @@ impl RealizedFull {
|
||||
capitulation_flow,
|
||||
profit_flow,
|
||||
gross_pnl_sum,
|
||||
net_pnl_change_1m: cfg.import("net_pnl_change_1m", Version::new(3))?,
|
||||
net_pnl_delta: cfg.import("net_pnl_delta", Version::new(5))?,
|
||||
net_pnl_delta_extended: cfg.import("net_pnl_delta", Version::new(5))?,
|
||||
net_pnl_change_1m_rel_to_realized_cap: cfg
|
||||
.import("net_pnl_change_1m_rel_to_realized_cap", Version::new(4))?,
|
||||
net_pnl_change_1m_rel_to_market_cap: cfg
|
||||
.import("net_pnl_change_1m_rel_to_market_cap", Version::new(4))?,
|
||||
realized_cap_delta_extended: cfg.import("realized_cap_delta", Version::new(5))?,
|
||||
investor_price,
|
||||
investor_price_ratio,
|
||||
lower_price_band,
|
||||
@@ -425,28 +430,42 @@ impl RealizedFull {
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Net PnL change 1m
|
||||
self.net_pnl_change_1m.height.compute_rolling_change(
|
||||
// Net PnL delta (1m base + 24h/1w/1y extended)
|
||||
self.net_pnl_delta.compute(
|
||||
starting_indexes.height,
|
||||
&blocks.count.height_1m_ago,
|
||||
&self.base.core.net_realized_pnl.cumulative.height,
|
||||
exit,
|
||||
)?;
|
||||
self.net_pnl_delta_extended.compute(
|
||||
starting_indexes.height,
|
||||
&window_starts,
|
||||
&self.base.core.net_realized_pnl.cumulative.height,
|
||||
exit,
|
||||
)?;
|
||||
self.net_pnl_change_1m_rel_to_realized_cap
|
||||
.compute_binary::<CentsSigned, Cents, RatioCentsSignedCentsBps32>(
|
||||
starting_indexes.height,
|
||||
&self.net_pnl_change_1m.height,
|
||||
&self.net_pnl_delta.change_1m.height,
|
||||
&self.base.core.minimal.realized_cap_cents.height,
|
||||
exit,
|
||||
)?;
|
||||
self.net_pnl_change_1m_rel_to_market_cap
|
||||
.compute_binary::<CentsSigned, Dollars, RatioCentsSignedDollarsBps32>(
|
||||
starting_indexes.height,
|
||||
&self.net_pnl_change_1m.height,
|
||||
&self.net_pnl_delta.change_1m.height,
|
||||
height_to_market_cap,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Realized cap delta extended (24h/1w/1y — 1m is in RealizedCore)
|
||||
self.realized_cap_delta_extended.compute(
|
||||
starting_indexes.height,
|
||||
&window_starts,
|
||||
&self.base.core.minimal.realized_cap_cents.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Peak regret
|
||||
self.peak_regret_rel_to_realized_cap
|
||||
.compute_binary::<Cents, Cents, RatioCentsBp32>(
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Height, Indexes, Sats, Version};
|
||||
use brk_types::{Height, Indexes, Sats, SatsSigned, Version};
|
||||
|
||||
use crate::{blocks, prices};
|
||||
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
|
||||
|
||||
use crate::internal::{
|
||||
HalveCents, HalveDollars, HalveSats, HalveSatsToBitcoin, LazyValueFromHeight, ValueFromHeight,
|
||||
ValueFromHeightChange,
|
||||
HalveCents, HalveDollars, HalveSats, HalveSatsToBitcoin, LazyValueFromHeight,
|
||||
RollingDelta1m, ValueFromHeight,
|
||||
};
|
||||
|
||||
use super::ImportConfig;
|
||||
@@ -17,8 +17,7 @@ use super::ImportConfig;
|
||||
pub struct SupplyMetrics<M: StorageMode = Rw> {
|
||||
pub total: ValueFromHeight<M>,
|
||||
pub halved: LazyValueFromHeight,
|
||||
/// 1-month change in supply (net position change) - sats, btc, usd
|
||||
pub change_1m: ValueFromHeightChange<M>,
|
||||
pub delta: RollingDelta1m<Sats, SatsSigned, M>,
|
||||
}
|
||||
|
||||
impl SupplyMetrics {
|
||||
@@ -33,12 +32,12 @@ impl SupplyMetrics {
|
||||
HalveDollars,
|
||||
>(&cfg.name("supply_halved"), &supply, cfg.version);
|
||||
|
||||
let change_1m = cfg.import("supply_change_1m", Version::ZERO)?;
|
||||
let delta = cfg.import("supply_delta", Version::ONE)?;
|
||||
|
||||
Ok(Self {
|
||||
total: supply,
|
||||
halved: supply_halved,
|
||||
change_1m,
|
||||
delta,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -101,11 +100,10 @@ impl SupplyMetrics {
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.change_1m.compute_rolling(
|
||||
self.delta.compute(
|
||||
starting_indexes.height,
|
||||
&blocks.count.height_1m_ago,
|
||||
&self.total.sats.height,
|
||||
&self.total.cents.height,
|
||||
exit,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
//! RollingDelta - raw change + growth rate (%) across 4 time windows.
|
||||
//! RollingDelta - raw change + growth rate (%) across time windows.
|
||||
//!
|
||||
//! Three tiers:
|
||||
//! - `RollingDelta1m` — 1m window only (2 stored vecs: change + rate). Default for all cohorts.
|
||||
//! - `RollingDeltaExcept1m` — 24h + 1w + 1y windows (6 stored vecs). Extended tier only.
|
||||
//! - `RollingDelta` — all 4 windows (8 stored vecs). Used for standalone global metrics.
|
||||
//!
|
||||
//! For a monotonic source (e.g., cumulative address count):
|
||||
//! - `change._24h` = count_now - count_24h_ago
|
||||
@@ -6,15 +11,76 @@
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{BasisPoints32, Height, Version};
|
||||
use brk_types::{BasisPoints32, BasisPointsSigned32, Height, Version};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{AnyVec, Database, Exit, ReadableVec, Rw, StorageMode, VecIndex};
|
||||
use vecdb::{AnyVec, Database, EagerVec, Exit, PcoVec, ReadableVec, Rw, StorageMode, VecIndex};
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{NumericValue, PercentRollingWindows, RollingWindows, WindowStarts},
|
||||
internal::{
|
||||
ComputedFromHeight, NumericValue, PercentFromHeight, PercentRollingWindows,
|
||||
RollingWindows, WindowStarts,
|
||||
},
|
||||
};
|
||||
|
||||
/// Pre-collect source data from the earliest needed offset.
|
||||
/// Returns (source_data, offset) for use in compute_delta_window.
|
||||
fn collect_source<S: NumericValue>(
|
||||
source: &impl ReadableVec<Height, S>,
|
||||
skip: usize,
|
||||
earliest_starts: &impl ReadableVec<Height, Height>,
|
||||
) -> (Vec<S>, usize) {
|
||||
let source_len = source.len();
|
||||
let offset = if skip > 0 && skip < earliest_starts.len() {
|
||||
earliest_starts.collect_one_at(skip).unwrap().to_usize()
|
||||
} else {
|
||||
0
|
||||
};
|
||||
(source.collect_range_at(offset, source_len), offset)
|
||||
}
|
||||
|
||||
/// Shared computation: change = current - ago, rate = change / ago.
|
||||
fn compute_delta_window<S, C, B>(
|
||||
change_h: &mut EagerVec<PcoVec<Height, C>>,
|
||||
rate_bps_h: &mut EagerVec<PcoVec<Height, B>>,
|
||||
max_from: Height,
|
||||
starts: &impl ReadableVec<Height, Height>,
|
||||
source_data: &[S],
|
||||
offset: usize,
|
||||
exit: &Exit,
|
||||
) -> Result<()>
|
||||
where
|
||||
S: NumericValue,
|
||||
C: NumericValue,
|
||||
B: NumericValue,
|
||||
{
|
||||
change_h.compute_transform(
|
||||
max_from,
|
||||
starts,
|
||||
|(h, ago_h, ..)| {
|
||||
let current: f64 = source_data[h.to_usize() - offset].into();
|
||||
let ago: f64 = source_data[ago_h.to_usize() - offset].into();
|
||||
(h, C::from(current - ago))
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
rate_bps_h.compute_transform(
|
||||
max_from,
|
||||
&*change_h,
|
||||
|(h, change, ..)| {
|
||||
let current_f: f64 = source_data[h.to_usize() - offset].into();
|
||||
let change_f: f64 = change.into();
|
||||
let ago = current_f - change_f;
|
||||
let rate = if ago == 0.0 { 0.0 } else { change_f / ago };
|
||||
(h, B::from(rate))
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct RollingDelta<S, C = S, M: StorageMode = Rw>
|
||||
where
|
||||
@@ -60,58 +126,193 @@ where
|
||||
windows: &WindowStarts<'_>,
|
||||
source: &impl ReadableVec<Height, S>,
|
||||
exit: &Exit,
|
||||
) -> Result<()>
|
||||
where
|
||||
S: Default,
|
||||
{
|
||||
// Step 1: change = current - ago
|
||||
for (change_w, starts) in self.change.0.as_mut_array().into_iter().zip(windows.as_array())
|
||||
{
|
||||
// Pre-collect source from earliest ago_h to end for fast array indexing
|
||||
let skip = change_w.height.len();
|
||||
let source_len = source.len();
|
||||
let offset = if skip > 0 && skip < starts.len() {
|
||||
starts.collect_one_at(skip).unwrap().to_usize()
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let source_data = source.collect_range_at(offset, source_len);
|
||||
) -> Result<()> {
|
||||
// Pre-collect once using the widest window (1y has earliest ago heights)
|
||||
let skip = self.change.0._24h.height.len();
|
||||
let (source_data, offset) = collect_source(source, skip, windows._1y);
|
||||
|
||||
change_w.height.compute_transform(
|
||||
max_from,
|
||||
*starts,
|
||||
|(h, ago_h, ..)| {
|
||||
let current: f64 = source_data[h.to_usize() - offset].into();
|
||||
let ago: f64 = source_data[ago_h.to_usize() - offset].into();
|
||||
(h, C::from(current - ago))
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
}
|
||||
|
||||
// Step 2: rate = change / ago = change / (current - change)
|
||||
for (growth_w, change_w) in self
|
||||
.rate
|
||||
for ((change_w, rate_w), starts) in self
|
||||
.change
|
||||
.0
|
||||
.as_mut_array()
|
||||
.into_iter()
|
||||
.zip(self.change.0.as_array())
|
||||
.zip(self.rate.0.as_mut_array())
|
||||
.zip(windows.as_array())
|
||||
{
|
||||
growth_w.bps.height.compute_transform2(
|
||||
compute_delta_window(
|
||||
&mut change_w.height,
|
||||
&mut rate_w.bps.height,
|
||||
max_from,
|
||||
source,
|
||||
&change_w.height,
|
||||
|(h, current, change, ..)| {
|
||||
let current_f: f64 = current.into();
|
||||
let change_f: f64 = change.into();
|
||||
let ago = current_f - change_f;
|
||||
let rate = if ago == 0.0 { 0.0 } else { change_f / ago };
|
||||
(h, BasisPoints32::from(rate))
|
||||
},
|
||||
*starts,
|
||||
&source_data,
|
||||
offset,
|
||||
exit,
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// 1m-only delta: change + growth rate for the 1-month window.
|
||||
/// Default tier for all cohorts (2 stored vecs).
|
||||
#[derive(Traversable)]
|
||||
pub struct RollingDelta1m<S, C = S, M: StorageMode = Rw>
|
||||
where
|
||||
S: NumericValue + JsonSchema,
|
||||
C: NumericValue + JsonSchema,
|
||||
{
|
||||
pub change_1m: ComputedFromHeight<C, M>,
|
||||
pub rate_1m: PercentFromHeight<BasisPointsSigned32, M>,
|
||||
_phantom: std::marker::PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<S, C> RollingDelta1m<S, C>
|
||||
where
|
||||
S: NumericValue + JsonSchema,
|
||||
C: NumericValue + JsonSchema,
|
||||
{
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
change_1m: ComputedFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_change_1m"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
rate_1m: PercentFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_rate_1m"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
_phantom: std::marker::PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn compute(
|
||||
&mut self,
|
||||
max_from: Height,
|
||||
height_1m_ago: &impl ReadableVec<Height, Height>,
|
||||
source: &impl ReadableVec<Height, S>,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
let skip = self.change_1m.height.len();
|
||||
let (source_data, offset) = collect_source(source, skip, height_1m_ago);
|
||||
|
||||
compute_delta_window(
|
||||
&mut self.change_1m.height,
|
||||
&mut self.rate_1m.bps.height,
|
||||
max_from,
|
||||
height_1m_ago,
|
||||
&source_data,
|
||||
offset,
|
||||
exit,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Extended delta: 24h + 1w + 1y windows (6 stored vecs).
|
||||
/// Only for All/LTH/STH cohorts (Extended tier).
|
||||
#[derive(Traversable)]
|
||||
pub struct RollingDeltaExcept1m<S, C = S, M: StorageMode = Rw>
|
||||
where
|
||||
S: NumericValue + JsonSchema,
|
||||
C: NumericValue + JsonSchema,
|
||||
{
|
||||
#[traversable(rename = "24h")]
|
||||
pub change_24h: ComputedFromHeight<C, M>,
|
||||
pub change_1w: ComputedFromHeight<C, M>,
|
||||
pub change_1y: ComputedFromHeight<C, M>,
|
||||
#[traversable(rename = "24h")]
|
||||
pub rate_24h: PercentFromHeight<BasisPointsSigned32, M>,
|
||||
pub rate_1w: PercentFromHeight<BasisPointsSigned32, M>,
|
||||
pub rate_1y: PercentFromHeight<BasisPointsSigned32, M>,
|
||||
_phantom: std::marker::PhantomData<S>,
|
||||
}
|
||||
|
||||
impl<S, C> RollingDeltaExcept1m<S, C>
|
||||
where
|
||||
S: NumericValue + JsonSchema,
|
||||
C: NumericValue + JsonSchema,
|
||||
{
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
change_24h: ComputedFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_change_24h"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
change_1w: ComputedFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_change_1w"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
change_1y: ComputedFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_change_1y"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
rate_24h: PercentFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_rate_24h"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
rate_1w: PercentFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_rate_1w"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
rate_1y: PercentFromHeight::forced_import(
|
||||
db,
|
||||
&format!("{name}_rate_1y"),
|
||||
version,
|
||||
indexes,
|
||||
)?,
|
||||
_phantom: std::marker::PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn compute(
|
||||
&mut self,
|
||||
max_from: Height,
|
||||
windows: &WindowStarts<'_>,
|
||||
source: &impl ReadableVec<Height, S>,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
// Pre-collect once using the widest window (1y has earliest ago heights)
|
||||
let skip = self.change_24h.height.len();
|
||||
let (source_data, offset) = collect_source(source, skip, windows._1y);
|
||||
|
||||
let changes = [&mut self.change_24h, &mut self.change_1w, &mut self.change_1y];
|
||||
let rates = [&mut self.rate_24h, &mut self.rate_1w, &mut self.rate_1y];
|
||||
let starts = [windows._24h, windows._1w, windows._1y];
|
||||
|
||||
for ((change_w, rate_w), starts) in changes.into_iter().zip(rates).zip(starts) {
|
||||
compute_delta_window(
|
||||
&mut change_w.height,
|
||||
&mut rate_w.bps.height,
|
||||
max_from,
|
||||
starts,
|
||||
&source_data,
|
||||
offset,
|
||||
exit,
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
mod aggregated;
|
||||
mod cumulative;
|
||||
mod cumulative_sum;
|
||||
mod full;
|
||||
mod delta;
|
||||
mod full;
|
||||
mod rolling_average;
|
||||
mod sum;
|
||||
|
||||
pub use aggregated::*;
|
||||
pub use cumulative::*;
|
||||
pub use cumulative_sum::*;
|
||||
pub use full::*;
|
||||
pub use delta::*;
|
||||
pub use full::*;
|
||||
pub use rolling_average::*;
|
||||
pub use sum::*;
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
//! ComputedFromHeightSum - stored height + RollingWindows (sum only).
|
||||
//!
|
||||
//! Like ComputedFromHeightCumulativeSum but without the cumulative vec.
|
||||
|
||||
use std::ops::SubAssign;
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Height, Version};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{Database, EagerVec, Exit, ImportableVec, PcoVec, Rw, StorageMode};
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{NumericValue, RollingWindows, WindowStarts},
|
||||
};
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct ComputedFromHeightSum<T, M: StorageMode = Rw>
|
||||
where
|
||||
T: NumericValue + JsonSchema,
|
||||
{
|
||||
pub height: M::Stored<EagerVec<PcoVec<Height, T>>>,
|
||||
pub sum: RollingWindows<T, M>,
|
||||
}
|
||||
|
||||
impl<T> ComputedFromHeightSum<T>
|
||||
where
|
||||
T: NumericValue + JsonSchema,
|
||||
{
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
let height: EagerVec<PcoVec<Height, T>> = EagerVec::forced_import(db, name, version)?;
|
||||
let sum = RollingWindows::forced_import(db, &format!("{name}_sum"), version, indexes)?;
|
||||
|
||||
Ok(Self { height, sum })
|
||||
}
|
||||
|
||||
/// Compute height data via closure, then rolling sum.
|
||||
pub(crate) fn compute(
|
||||
&mut self,
|
||||
max_from: Height,
|
||||
windows: &WindowStarts<'_>,
|
||||
exit: &Exit,
|
||||
compute_height: impl FnOnce(&mut EagerVec<PcoVec<Height, T>>) -> Result<()>,
|
||||
) -> Result<()>
|
||||
where
|
||||
T: Default + SubAssign,
|
||||
{
|
||||
compute_height(&mut self.height)?;
|
||||
self.sum
|
||||
.compute_rolling_sum(max_from, windows, &self.height, exit)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
//! Change values from Height - stores signed sats and dollars (changes can be negative).
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Bitcoin, Cents, CentsSigned, Dollars, Height, Sats, SatsSigned, Version};
|
||||
use vecdb::{Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode};
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{CentsSignedToDollars, ComputedFromHeight, LazyFromHeight, SatsSignedToBitcoin},
|
||||
};
|
||||
|
||||
/// Change values indexed by height - sats (stored), btc (lazy), cents (stored), usd (lazy).
|
||||
#[derive(Traversable)]
|
||||
pub struct ValueFromHeightChange<M: StorageMode = Rw> {
|
||||
pub sats: ComputedFromHeight<SatsSigned, M>,
|
||||
pub btc: LazyFromHeight<Bitcoin, SatsSigned>,
|
||||
pub cents: ComputedFromHeight<CentsSigned, M>,
|
||||
pub usd: LazyFromHeight<Dollars, CentsSigned>,
|
||||
}
|
||||
|
||||
impl ValueFromHeightChange {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
let sats = ComputedFromHeight::forced_import(db, name, version, indexes)?;
|
||||
|
||||
let btc = LazyFromHeight::from_computed::<SatsSignedToBitcoin>(
|
||||
&format!("{name}_btc"),
|
||||
version,
|
||||
sats.height.read_only_boxed_clone(),
|
||||
&sats,
|
||||
);
|
||||
|
||||
let cents =
|
||||
ComputedFromHeight::forced_import(db, &format!("{name}_cents"), version, indexes)?;
|
||||
|
||||
let usd = LazyFromHeight::from_computed::<CentsSignedToDollars>(
|
||||
&format!("{name}_usd"),
|
||||
version,
|
||||
cents.height.read_only_boxed_clone(),
|
||||
¢s,
|
||||
);
|
||||
|
||||
Ok(Self {
|
||||
sats,
|
||||
btc,
|
||||
cents,
|
||||
usd,
|
||||
})
|
||||
}
|
||||
|
||||
/// Compute rolling change for both sats and cents in one call.
|
||||
pub(crate) fn compute_rolling(
|
||||
&mut self,
|
||||
starting_height: Height,
|
||||
window_starts: &impl ReadableVec<Height, Height>,
|
||||
sats_source: &impl ReadableVec<Height, Sats>,
|
||||
cents_source: &(impl ReadableVec<Height, Cents> + Sync),
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.sats.height.compute_rolling_change(
|
||||
starting_height,
|
||||
window_starts,
|
||||
sats_source,
|
||||
exit,
|
||||
)?;
|
||||
self.cents.height.compute_rolling_change(
|
||||
starting_height,
|
||||
window_starts,
|
||||
cents_source,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
mod base;
|
||||
mod change;
|
||||
mod cumulative;
|
||||
mod cumulative_sum;
|
||||
mod full;
|
||||
@@ -7,7 +6,6 @@ mod lazy;
|
||||
mod rolling;
|
||||
|
||||
pub use base::*;
|
||||
pub use change::*;
|
||||
pub use cumulative::*;
|
||||
pub use cumulative_sum::*;
|
||||
pub use full::*;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use brk_types::{Bitcoin, Cents, CentsSigned, Dollars, Sats, SatsFract, SatsSigned};
|
||||
use brk_types::{Bitcoin, Cents, CentsSigned, Dollars, Sats, SatsFract};
|
||||
use vecdb::{BinaryTransform, UnaryTransform};
|
||||
|
||||
pub struct SatsToBitcoin;
|
||||
@@ -10,15 +10,6 @@ impl UnaryTransform<Sats, Bitcoin> for SatsToBitcoin {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SatsSignedToBitcoin;
|
||||
|
||||
impl UnaryTransform<SatsSigned, Bitcoin> for SatsSignedToBitcoin {
|
||||
#[inline(always)]
|
||||
fn apply(sats: SatsSigned) -> Bitcoin {
|
||||
Bitcoin::from(sats)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SatsToCents;
|
||||
|
||||
impl BinaryTransform<Sats, Cents, Cents> for SatsToCents {
|
||||
|
||||
@@ -16,7 +16,7 @@ pub use bps::{
|
||||
pub use currency::{
|
||||
CentsSignedToDollars, CentsSubtractToCentsSigned, CentsTimesTenths,
|
||||
CentsUnsignedToDollars, CentsUnsignedToSats, DollarsToSatsFract, NegCentsUnsignedToDollars,
|
||||
SatsSignedToBitcoin, SatsToBitcoin, SatsToCents,
|
||||
SatsToBitcoin, SatsToCents,
|
||||
};
|
||||
pub use derived::{
|
||||
Days7, Days30, Days365, DaysToYears, PerSec, PriceTimesRatioBp32Cents, PriceTimesRatioCents,
|
||||
|
||||
@@ -44,16 +44,8 @@ impl Vecs {
|
||||
self.velocity
|
||||
.compute(blocks, transactions, distribution, starting_indexes, exit)?;
|
||||
|
||||
// 4. Compute cap growth rates using 1y lookback
|
||||
self.market_cap_growth_rate
|
||||
.bps
|
||||
.height
|
||||
.compute_rolling_ratio_change(
|
||||
starting_indexes.height,
|
||||
&blocks.count.height_1y_ago,
|
||||
&self.market_cap.height,
|
||||
exit,
|
||||
)?;
|
||||
// 4. Compute cap growth rates across 4 windows
|
||||
let window_starts = blocks.count.window_starts();
|
||||
|
||||
let realized_cap = &distribution
|
||||
.utxo_cohorts
|
||||
@@ -62,25 +54,32 @@ impl Vecs {
|
||||
.realized
|
||||
.realized_cap
|
||||
.height;
|
||||
self.realized_cap_growth_rate
|
||||
.bps
|
||||
.height
|
||||
.compute_rolling_ratio_change(
|
||||
|
||||
let mcgr_arr = self.market_cap_growth_rate.0.as_mut_array();
|
||||
let rcgr_arr = self.realized_cap_growth_rate.0.as_mut_array();
|
||||
let diff_arr = self.market_minus_realized_cap_growth_rate.0.as_mut_array();
|
||||
let starts_arr = window_starts.as_array();
|
||||
|
||||
for i in 0..4 {
|
||||
mcgr_arr[i].bps.height.compute_rolling_ratio_change(
|
||||
starting_indexes.height,
|
||||
&blocks.count.height_1y_ago,
|
||||
*starts_arr[i],
|
||||
&self.market_cap.height,
|
||||
exit,
|
||||
)?;
|
||||
rcgr_arr[i].bps.height.compute_rolling_ratio_change(
|
||||
starting_indexes.height,
|
||||
*starts_arr[i],
|
||||
realized_cap,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// 5. Compute cap growth rate diff: market - realized
|
||||
self.market_minus_realized_cap_growth_rate
|
||||
.height
|
||||
.compute_subtract(
|
||||
diff_arr[i].height.compute_subtract(
|
||||
starting_indexes.height,
|
||||
&self.market_cap_growth_rate.bps.height,
|
||||
&self.realized_cap_growth_rate.bps.height,
|
||||
&mcgr_arr[i].bps.height,
|
||||
&rcgr_arr[i].bps.height,
|
||||
exit,
|
||||
)?;
|
||||
}
|
||||
|
||||
let _lock = exit.lock();
|
||||
self.db.compact()?;
|
||||
|
||||
@@ -6,8 +6,8 @@ use brk_types::{Cents, Dollars, Sats, Version};
|
||||
use crate::{
|
||||
distribution, indexes,
|
||||
internal::{
|
||||
ComputedFromHeight, Identity, LazyFromHeight, LazyValueFromHeight, PercentFromHeight,
|
||||
SatsToBitcoin, finalize_db, open_db,
|
||||
Identity, LazyFromHeight, LazyValueFromHeight, PercentFromHeight, PercentRollingWindows,
|
||||
RollingWindows, SatsToBitcoin, finalize_db, open_db,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -52,23 +52,23 @@ impl Vecs {
|
||||
&supply_metrics.total.usd,
|
||||
);
|
||||
|
||||
// Growth rates
|
||||
let market_cap_growth_rate = PercentFromHeight::forced_import(
|
||||
// Growth rates (4 windows: 24h, 1w, 1m, 1y)
|
||||
let market_cap_growth_rate = PercentRollingWindows::forced_import(
|
||||
&db,
|
||||
"market_cap_growth_rate",
|
||||
version + Version::ONE,
|
||||
version + Version::TWO,
|
||||
indexes,
|
||||
)?;
|
||||
let realized_cap_growth_rate = PercentFromHeight::forced_import(
|
||||
let realized_cap_growth_rate = PercentRollingWindows::forced_import(
|
||||
&db,
|
||||
"realized_cap_growth_rate",
|
||||
version + Version::ONE,
|
||||
version + Version::TWO,
|
||||
indexes,
|
||||
)?;
|
||||
let market_minus_realized_cap_growth_rate = ComputedFromHeight::forced_import(
|
||||
let market_minus_realized_cap_growth_rate = RollingWindows::forced_import(
|
||||
&db,
|
||||
"market_minus_realized_cap_growth_rate",
|
||||
version,
|
||||
version + Version::ONE,
|
||||
indexes,
|
||||
)?;
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@ use brk_types::{BasisPointsSigned32, Dollars};
|
||||
use vecdb::{Database, Rw, StorageMode};
|
||||
|
||||
use super::{burned, velocity};
|
||||
use crate::internal::{ComputedFromHeight, LazyFromHeight, LazyValueFromHeight, PercentFromHeight};
|
||||
use crate::internal::{
|
||||
LazyFromHeight, LazyValueFromHeight, PercentFromHeight, PercentRollingWindows, RollingWindows,
|
||||
};
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct Vecs<M: StorageMode = Rw> {
|
||||
@@ -15,7 +17,7 @@ pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub inflation_rate: PercentFromHeight<BasisPointsSigned32, M>,
|
||||
pub velocity: velocity::Vecs<M>,
|
||||
pub market_cap: LazyFromHeight<Dollars>,
|
||||
pub market_cap_growth_rate: PercentFromHeight<BasisPointsSigned32, M>,
|
||||
pub realized_cap_growth_rate: PercentFromHeight<BasisPointsSigned32, M>,
|
||||
pub market_minus_realized_cap_growth_rate: ComputedFromHeight<BasisPointsSigned32, M>,
|
||||
pub market_cap_growth_rate: PercentRollingWindows<BasisPointsSigned32, M>,
|
||||
pub realized_cap_growth_rate: PercentRollingWindows<BasisPointsSigned32, M>,
|
||||
pub market_minus_realized_cap_growth_rate: RollingWindows<BasisPointsSigned32, M>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user