global: snapshot

This commit is contained in:
nym21
2026-03-16 11:47:40 +01:00
parent b74319bf10
commit bdb0c0878e
8 changed files with 325 additions and 386 deletions
+114 -118
View File
@@ -1861,28 +1861,6 @@ pub struct InvestedMaxMinPercentilesSupplyPattern {
pub supply_density: BpsPercentRatioPattern3,
}
/// Pattern struct for repeated tree structure.
pub struct MvrvNuplRealizedSupplyPattern {
pub mvrv: MetricPattern1<StoredF32>,
pub nupl: BpsRatioPattern,
pub realized_cap: AllSthPattern,
pub realized_price: BpsCentsRatioSatsUsdPattern,
pub supply: AllSthPattern2,
}
impl MvrvNuplRealizedSupplyPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
mvrv: MetricPattern1::new(client.clone(), _m(&acc, "mvrv")),
nupl: BpsRatioPattern::new(client.clone(), _m(&acc, "nupl")),
realized_cap: AllSthPattern::new(client.clone(), acc.clone()),
realized_price: BpsCentsRatioSatsUsdPattern::new(client.clone(), _m(&acc, "realized_price")),
supply: AllSthPattern2::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct PhsReboundThsPattern {
pub phs: MetricPattern1<StoredF32>,
@@ -2555,6 +2533,24 @@ pub struct LowerPriceUpperPattern {
pub upper_price_band: CentsSatsUsdPattern,
}
/// Pattern struct for repeated tree structure.
pub struct NuplRealizedSupplyPattern {
pub nupl: BpsRatioPattern,
pub realized_cap: AllSthPattern,
pub supply: AllSthPattern2,
}
impl NuplRealizedSupplyPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
nupl: BpsRatioPattern::new(client.clone(), _m(&acc, "nupl")),
realized_cap: AllSthPattern::new(client.clone(), acc.clone()),
supply: AllSthPattern2::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct RatioValuePattern2 {
pub ratio: _1m1w1y24hPattern<StoredF64>,
@@ -8054,129 +8050,129 @@ impl MetricsTree_Cohorts_Utxo_Profitability {
/// Metrics tree node.
pub struct MetricsTree_Cohorts_Utxo_Profitability_Range {
pub over_1000pct_in_profit: MvrvNuplRealizedSupplyPattern,
pub _500pct_to_1000pct_in_profit: MvrvNuplRealizedSupplyPattern,
pub _300pct_to_500pct_in_profit: MvrvNuplRealizedSupplyPattern,
pub _200pct_to_300pct_in_profit: MvrvNuplRealizedSupplyPattern,
pub _100pct_to_200pct_in_profit: MvrvNuplRealizedSupplyPattern,
pub _90pct_to_100pct_in_profit: MvrvNuplRealizedSupplyPattern,
pub _80pct_to_90pct_in_profit: MvrvNuplRealizedSupplyPattern,
pub _70pct_to_80pct_in_profit: MvrvNuplRealizedSupplyPattern,
pub _60pct_to_70pct_in_profit: MvrvNuplRealizedSupplyPattern,
pub _50pct_to_60pct_in_profit: MvrvNuplRealizedSupplyPattern,
pub _40pct_to_50pct_in_profit: MvrvNuplRealizedSupplyPattern,
pub _30pct_to_40pct_in_profit: MvrvNuplRealizedSupplyPattern,
pub _20pct_to_30pct_in_profit: MvrvNuplRealizedSupplyPattern,
pub _10pct_to_20pct_in_profit: MvrvNuplRealizedSupplyPattern,
pub _0pct_to_10pct_in_profit: MvrvNuplRealizedSupplyPattern,
pub _0pct_to_10pct_in_loss: MvrvNuplRealizedSupplyPattern,
pub _10pct_to_20pct_in_loss: MvrvNuplRealizedSupplyPattern,
pub _20pct_to_30pct_in_loss: MvrvNuplRealizedSupplyPattern,
pub _30pct_to_40pct_in_loss: MvrvNuplRealizedSupplyPattern,
pub _40pct_to_50pct_in_loss: MvrvNuplRealizedSupplyPattern,
pub _50pct_to_60pct_in_loss: MvrvNuplRealizedSupplyPattern,
pub _60pct_to_70pct_in_loss: MvrvNuplRealizedSupplyPattern,
pub _70pct_to_80pct_in_loss: MvrvNuplRealizedSupplyPattern,
pub _80pct_to_90pct_in_loss: MvrvNuplRealizedSupplyPattern,
pub _90pct_to_100pct_in_loss: MvrvNuplRealizedSupplyPattern,
pub over_1000pct_in_profit: NuplRealizedSupplyPattern,
pub _500pct_to_1000pct_in_profit: NuplRealizedSupplyPattern,
pub _300pct_to_500pct_in_profit: NuplRealizedSupplyPattern,
pub _200pct_to_300pct_in_profit: NuplRealizedSupplyPattern,
pub _100pct_to_200pct_in_profit: NuplRealizedSupplyPattern,
pub _90pct_to_100pct_in_profit: NuplRealizedSupplyPattern,
pub _80pct_to_90pct_in_profit: NuplRealizedSupplyPattern,
pub _70pct_to_80pct_in_profit: NuplRealizedSupplyPattern,
pub _60pct_to_70pct_in_profit: NuplRealizedSupplyPattern,
pub _50pct_to_60pct_in_profit: NuplRealizedSupplyPattern,
pub _40pct_to_50pct_in_profit: NuplRealizedSupplyPattern,
pub _30pct_to_40pct_in_profit: NuplRealizedSupplyPattern,
pub _20pct_to_30pct_in_profit: NuplRealizedSupplyPattern,
pub _10pct_to_20pct_in_profit: NuplRealizedSupplyPattern,
pub _0pct_to_10pct_in_profit: NuplRealizedSupplyPattern,
pub _0pct_to_10pct_in_loss: NuplRealizedSupplyPattern,
pub _10pct_to_20pct_in_loss: NuplRealizedSupplyPattern,
pub _20pct_to_30pct_in_loss: NuplRealizedSupplyPattern,
pub _30pct_to_40pct_in_loss: NuplRealizedSupplyPattern,
pub _40pct_to_50pct_in_loss: NuplRealizedSupplyPattern,
pub _50pct_to_60pct_in_loss: NuplRealizedSupplyPattern,
pub _60pct_to_70pct_in_loss: NuplRealizedSupplyPattern,
pub _70pct_to_80pct_in_loss: NuplRealizedSupplyPattern,
pub _80pct_to_90pct_in_loss: NuplRealizedSupplyPattern,
pub _90pct_to_100pct_in_loss: NuplRealizedSupplyPattern,
}
impl MetricsTree_Cohorts_Utxo_Profitability_Range {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
over_1000pct_in_profit: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_1000pct_in_profit".to_string()),
_500pct_to_1000pct_in_profit: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_500pct_to_1000pct_in_profit".to_string()),
_300pct_to_500pct_in_profit: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_300pct_to_500pct_in_profit".to_string()),
_200pct_to_300pct_in_profit: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_200pct_to_300pct_in_profit".to_string()),
_100pct_to_200pct_in_profit: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_100pct_to_200pct_in_profit".to_string()),
_90pct_to_100pct_in_profit: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_90pct_to_100pct_in_profit".to_string()),
_80pct_to_90pct_in_profit: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_80pct_to_90pct_in_profit".to_string()),
_70pct_to_80pct_in_profit: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_70pct_to_80pct_in_profit".to_string()),
_60pct_to_70pct_in_profit: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_60pct_to_70pct_in_profit".to_string()),
_50pct_to_60pct_in_profit: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_50pct_to_60pct_in_profit".to_string()),
_40pct_to_50pct_in_profit: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_40pct_to_50pct_in_profit".to_string()),
_30pct_to_40pct_in_profit: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_30pct_to_40pct_in_profit".to_string()),
_20pct_to_30pct_in_profit: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_20pct_to_30pct_in_profit".to_string()),
_10pct_to_20pct_in_profit: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_10pct_to_20pct_in_profit".to_string()),
_0pct_to_10pct_in_profit: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_0pct_to_10pct_in_profit".to_string()),
_0pct_to_10pct_in_loss: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_0pct_to_10pct_in_loss".to_string()),
_10pct_to_20pct_in_loss: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_10pct_to_20pct_in_loss".to_string()),
_20pct_to_30pct_in_loss: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_20pct_to_30pct_in_loss".to_string()),
_30pct_to_40pct_in_loss: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_30pct_to_40pct_in_loss".to_string()),
_40pct_to_50pct_in_loss: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_40pct_to_50pct_in_loss".to_string()),
_50pct_to_60pct_in_loss: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_50pct_to_60pct_in_loss".to_string()),
_60pct_to_70pct_in_loss: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_60pct_to_70pct_in_loss".to_string()),
_70pct_to_80pct_in_loss: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_70pct_to_80pct_in_loss".to_string()),
_80pct_to_90pct_in_loss: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_80pct_to_90pct_in_loss".to_string()),
_90pct_to_100pct_in_loss: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_90pct_to_100pct_in_loss".to_string()),
over_1000pct_in_profit: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_1000pct_in_profit".to_string()),
_500pct_to_1000pct_in_profit: NuplRealizedSupplyPattern::new(client.clone(), "utxos_500pct_to_1000pct_in_profit".to_string()),
_300pct_to_500pct_in_profit: NuplRealizedSupplyPattern::new(client.clone(), "utxos_300pct_to_500pct_in_profit".to_string()),
_200pct_to_300pct_in_profit: NuplRealizedSupplyPattern::new(client.clone(), "utxos_200pct_to_300pct_in_profit".to_string()),
_100pct_to_200pct_in_profit: NuplRealizedSupplyPattern::new(client.clone(), "utxos_100pct_to_200pct_in_profit".to_string()),
_90pct_to_100pct_in_profit: NuplRealizedSupplyPattern::new(client.clone(), "utxos_90pct_to_100pct_in_profit".to_string()),
_80pct_to_90pct_in_profit: NuplRealizedSupplyPattern::new(client.clone(), "utxos_80pct_to_90pct_in_profit".to_string()),
_70pct_to_80pct_in_profit: NuplRealizedSupplyPattern::new(client.clone(), "utxos_70pct_to_80pct_in_profit".to_string()),
_60pct_to_70pct_in_profit: NuplRealizedSupplyPattern::new(client.clone(), "utxos_60pct_to_70pct_in_profit".to_string()),
_50pct_to_60pct_in_profit: NuplRealizedSupplyPattern::new(client.clone(), "utxos_50pct_to_60pct_in_profit".to_string()),
_40pct_to_50pct_in_profit: NuplRealizedSupplyPattern::new(client.clone(), "utxos_40pct_to_50pct_in_profit".to_string()),
_30pct_to_40pct_in_profit: NuplRealizedSupplyPattern::new(client.clone(), "utxos_30pct_to_40pct_in_profit".to_string()),
_20pct_to_30pct_in_profit: NuplRealizedSupplyPattern::new(client.clone(), "utxos_20pct_to_30pct_in_profit".to_string()),
_10pct_to_20pct_in_profit: NuplRealizedSupplyPattern::new(client.clone(), "utxos_10pct_to_20pct_in_profit".to_string()),
_0pct_to_10pct_in_profit: NuplRealizedSupplyPattern::new(client.clone(), "utxos_0pct_to_10pct_in_profit".to_string()),
_0pct_to_10pct_in_loss: NuplRealizedSupplyPattern::new(client.clone(), "utxos_0pct_to_10pct_in_loss".to_string()),
_10pct_to_20pct_in_loss: NuplRealizedSupplyPattern::new(client.clone(), "utxos_10pct_to_20pct_in_loss".to_string()),
_20pct_to_30pct_in_loss: NuplRealizedSupplyPattern::new(client.clone(), "utxos_20pct_to_30pct_in_loss".to_string()),
_30pct_to_40pct_in_loss: NuplRealizedSupplyPattern::new(client.clone(), "utxos_30pct_to_40pct_in_loss".to_string()),
_40pct_to_50pct_in_loss: NuplRealizedSupplyPattern::new(client.clone(), "utxos_40pct_to_50pct_in_loss".to_string()),
_50pct_to_60pct_in_loss: NuplRealizedSupplyPattern::new(client.clone(), "utxos_50pct_to_60pct_in_loss".to_string()),
_60pct_to_70pct_in_loss: NuplRealizedSupplyPattern::new(client.clone(), "utxos_60pct_to_70pct_in_loss".to_string()),
_70pct_to_80pct_in_loss: NuplRealizedSupplyPattern::new(client.clone(), "utxos_70pct_to_80pct_in_loss".to_string()),
_80pct_to_90pct_in_loss: NuplRealizedSupplyPattern::new(client.clone(), "utxos_80pct_to_90pct_in_loss".to_string()),
_90pct_to_100pct_in_loss: NuplRealizedSupplyPattern::new(client.clone(), "utxos_90pct_to_100pct_in_loss".to_string()),
}
}
}
/// Metrics tree node.
pub struct MetricsTree_Cohorts_Utxo_Profitability_Profit {
pub breakeven: MvrvNuplRealizedSupplyPattern,
pub _10pct: MvrvNuplRealizedSupplyPattern,
pub _20pct: MvrvNuplRealizedSupplyPattern,
pub _30pct: MvrvNuplRealizedSupplyPattern,
pub _40pct: MvrvNuplRealizedSupplyPattern,
pub _50pct: MvrvNuplRealizedSupplyPattern,
pub _60pct: MvrvNuplRealizedSupplyPattern,
pub _70pct: MvrvNuplRealizedSupplyPattern,
pub _80pct: MvrvNuplRealizedSupplyPattern,
pub _90pct: MvrvNuplRealizedSupplyPattern,
pub _100pct: MvrvNuplRealizedSupplyPattern,
pub _200pct: MvrvNuplRealizedSupplyPattern,
pub _300pct: MvrvNuplRealizedSupplyPattern,
pub _500pct: MvrvNuplRealizedSupplyPattern,
pub breakeven: NuplRealizedSupplyPattern,
pub _10pct: NuplRealizedSupplyPattern,
pub _20pct: NuplRealizedSupplyPattern,
pub _30pct: NuplRealizedSupplyPattern,
pub _40pct: NuplRealizedSupplyPattern,
pub _50pct: NuplRealizedSupplyPattern,
pub _60pct: NuplRealizedSupplyPattern,
pub _70pct: NuplRealizedSupplyPattern,
pub _80pct: NuplRealizedSupplyPattern,
pub _90pct: NuplRealizedSupplyPattern,
pub _100pct: NuplRealizedSupplyPattern,
pub _200pct: NuplRealizedSupplyPattern,
pub _300pct: NuplRealizedSupplyPattern,
pub _500pct: NuplRealizedSupplyPattern,
}
impl MetricsTree_Cohorts_Utxo_Profitability_Profit {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
breakeven: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_in_profit".to_string()),
_10pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_10pct_in_profit".to_string()),
_20pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_20pct_in_profit".to_string()),
_30pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_30pct_in_profit".to_string()),
_40pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_40pct_in_profit".to_string()),
_50pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_50pct_in_profit".to_string()),
_60pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_60pct_in_profit".to_string()),
_70pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_70pct_in_profit".to_string()),
_80pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_80pct_in_profit".to_string()),
_90pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_90pct_in_profit".to_string()),
_100pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_100pct_in_profit".to_string()),
_200pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_200pct_in_profit".to_string()),
_300pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_300pct_in_profit".to_string()),
_500pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_500pct_in_profit".to_string()),
breakeven: NuplRealizedSupplyPattern::new(client.clone(), "utxos_in_profit".to_string()),
_10pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_10pct_in_profit".to_string()),
_20pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_20pct_in_profit".to_string()),
_30pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_30pct_in_profit".to_string()),
_40pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_40pct_in_profit".to_string()),
_50pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_50pct_in_profit".to_string()),
_60pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_60pct_in_profit".to_string()),
_70pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_70pct_in_profit".to_string()),
_80pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_80pct_in_profit".to_string()),
_90pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_90pct_in_profit".to_string()),
_100pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_100pct_in_profit".to_string()),
_200pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_200pct_in_profit".to_string()),
_300pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_300pct_in_profit".to_string()),
_500pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_500pct_in_profit".to_string()),
}
}
}
/// Metrics tree node.
pub struct MetricsTree_Cohorts_Utxo_Profitability_Loss {
pub breakeven: MvrvNuplRealizedSupplyPattern,
pub _10pct: MvrvNuplRealizedSupplyPattern,
pub _20pct: MvrvNuplRealizedSupplyPattern,
pub _30pct: MvrvNuplRealizedSupplyPattern,
pub _40pct: MvrvNuplRealizedSupplyPattern,
pub _50pct: MvrvNuplRealizedSupplyPattern,
pub _60pct: MvrvNuplRealizedSupplyPattern,
pub _70pct: MvrvNuplRealizedSupplyPattern,
pub _80pct: MvrvNuplRealizedSupplyPattern,
pub breakeven: NuplRealizedSupplyPattern,
pub _10pct: NuplRealizedSupplyPattern,
pub _20pct: NuplRealizedSupplyPattern,
pub _30pct: NuplRealizedSupplyPattern,
pub _40pct: NuplRealizedSupplyPattern,
pub _50pct: NuplRealizedSupplyPattern,
pub _60pct: NuplRealizedSupplyPattern,
pub _70pct: NuplRealizedSupplyPattern,
pub _80pct: NuplRealizedSupplyPattern,
}
impl MetricsTree_Cohorts_Utxo_Profitability_Loss {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
breakeven: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_in_loss".to_string()),
_10pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_10pct_in_loss".to_string()),
_20pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_20pct_in_loss".to_string()),
_30pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_30pct_in_loss".to_string()),
_40pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_40pct_in_loss".to_string()),
_50pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_50pct_in_loss".to_string()),
_60pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_60pct_in_loss".to_string()),
_70pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_70pct_in_loss".to_string()),
_80pct: MvrvNuplRealizedSupplyPattern::new(client.clone(), "utxos_over_80pct_in_loss".to_string()),
breakeven: NuplRealizedSupplyPattern::new(client.clone(), "utxos_in_loss".to_string()),
_10pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_10pct_in_loss".to_string()),
_20pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_20pct_in_loss".to_string()),
_30pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_30pct_in_loss".to_string()),
_40pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_40pct_in_loss".to_string()),
_50pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_50pct_in_loss".to_string()),
_60pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_60pct_in_loss".to_string()),
_70pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_70pct_in_loss".to_string()),
_80pct: NuplRealizedSupplyPattern::new(client.clone(), "utxos_over_80pct_in_loss".to_string()),
}
}
}
@@ -1,17 +1,12 @@
use brk_cohort::{Loss, Profit, ProfitabilityRange};
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{
BasisPoints32, BasisPointsSigned32, Cents, Dollars, Indexes, Sats, StoredF32, Version,
};
use brk_types::{BasisPointsSigned32, Cents, Dollars, Indexes, Sats, Version};
use vecdb::{AnyStoredVec, AnyVec, Database, Exit, Rw, StorageMode, WritableVec};
use crate::{
indexes,
internal::{
AmountPerBlock, AmountPerBlockWithDeltas, CachedWindowStarts, Identity, LazyPerBlock,
PerBlock, PriceWithRatioPerBlock, RatioPerBlock,
},
internal::{AmountPerBlock, AmountPerBlockWithDeltas, CachedWindowStarts, PerBlock, RatioPerBlock},
prices,
};
@@ -25,8 +20,6 @@ pub struct WithSth<All, Sth = All> {
pub struct ProfitabilityBucket<M: StorageMode = Rw> {
pub supply: WithSth<AmountPerBlockWithDeltas<M>, AmountPerBlock<M>>,
pub realized_cap: WithSth<PerBlock<Dollars, M>>,
pub realized_price: PriceWithRatioPerBlock<M>,
pub mvrv: LazyPerBlock<StoredF32>,
pub nupl: RatioPerBlock<BasisPointsSigned32, M>,
}
@@ -49,19 +42,6 @@ impl ProfitabilityBucket {
indexes: &indexes::Vecs,
cached_starts: &CachedWindowStarts,
) -> Result<Self> {
let realized_price = PriceWithRatioPerBlock::forced_import(
db,
&format!("{name}_realized_price"),
version,
indexes,
)?;
let mvrv = LazyPerBlock::from_lazy::<Identity<StoredF32>, BasisPoints32>(
&format!("{name}_mvrv"),
version,
&realized_price.ratio,
);
Ok(Self {
supply: WithSth {
all: AmountPerBlockWithDeltas::forced_import(
@@ -92,8 +72,6 @@ impl ProfitabilityBucket {
indexes,
)?,
},
realized_price,
mvrv,
nupl: RatioPerBlock::forced_import_raw(
db,
&format!("{name}_nupl"),
@@ -128,38 +106,20 @@ impl ProfitabilityBucket {
self.supply.all.compute(prices, max_from, exit)?;
self.supply.sth.compute(prices, max_from, exit)?;
// Realized price cents = realized_cap_cents × ONE_BTC / supply_sats
self.realized_price.cents.height.compute_transform2(
max_from,
&self.realized_cap.all.height,
&self.supply.all.sats.height,
|(i, cap_dollars, supply_sats, ..)| {
let cap_cents = Cents::from(cap_dollars).as_u128();
let supply = supply_sats.as_u128();
if supply == 0 {
(i, Cents::ZERO)
} else {
(i, Cents::from(cap_cents * Sats::ONE_BTC_U128 / supply))
}
},
exit,
)?;
// Ratio (spot / realized_price) → feeds MVRV lazily
self.realized_price
.compute_ratio(starting_indexes, &prices.spot.cents.height, exit)?;
// NUPL = (spot - realized_price) / spot
self.nupl.bps.height.compute_transform2(
// where realized_price = realized_cap_cents × ONE_BTC / supply_sats
self.nupl.bps.height.compute_transform3(
max_from,
&prices.spot.cents.height,
&self.realized_price.cents.height,
|(i, spot, realized, ..)| {
&self.realized_cap.all.height,
&self.supply.all.sats.height,
|(i, spot, cap_dollars, supply_sats, ..)| {
let p = spot.as_u128();
if p == 0 {
let supply = supply_sats.as_u128();
if p == 0 || supply == 0 {
(i, BasisPointsSigned32::ZERO)
} else {
let rp = realized.as_u128();
let rp = Cents::from(cap_dollars).as_u128() * Sats::ONE_BTC_U128 / supply;
let bps = ((p as i128 - rp as i128) * 10000) / p as i128;
(i, BasisPointsSigned32::from(bps as i32))
}
@@ -173,14 +133,12 @@ impl ProfitabilityBucket {
pub(crate) fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
vec![
&mut self.supply.all.inner.sats.height as &mut dyn AnyStoredVec,
&mut self.supply.all.inner.cents.height as &mut dyn AnyStoredVec,
&mut self.supply.sth.sats.height as &mut dyn AnyStoredVec,
&mut self.supply.sth.cents.height as &mut dyn AnyStoredVec,
&mut self.realized_cap.all.height as &mut dyn AnyStoredVec,
&mut self.realized_cap.sth.height as &mut dyn AnyStoredVec,
&mut self.realized_price.cents.height as &mut dyn AnyStoredVec,
&mut self.realized_price.bps.height as &mut dyn AnyStoredVec,
&mut self.nupl.bps.height as &mut dyn AnyStoredVec,
&mut self.supply.all.inner.cents.height,
&mut self.supply.sth.sats.height,
&mut self.supply.sth.cents.height,
&mut self.realized_cap.all.height,
&mut self.realized_cap.sth.height,
&mut self.nupl.bps.height,
]
}
}
+1
View File
@@ -19,6 +19,7 @@ pub struct BRK {
}
impl BRK {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Self::new_with_agent(crate::new_agent(30))
}
+15 -3
View File
@@ -19,6 +19,7 @@ pub struct Kraken {
}
impl Kraken {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Self::new_with_agent(crate::new_agent(30))
}
@@ -38,7 +39,11 @@ impl Kraken {
timestamp: Timestamp,
previous_timestamp: Option<Timestamp>,
) -> Result<OHLCCents> {
if self._1mn.as_ref().and_then(|m| m.last_key_value()).is_none_or(|(k, _)| k <= &timestamp)
if self
._1mn
.as_ref()
.and_then(|m| m.last_key_value())
.is_none_or(|(k, _)| k <= &timestamp)
{
self._1mn.replace(self.fetch_1mn()?);
}
@@ -62,7 +67,12 @@ impl Kraken {
}
fn get_from_1d(&mut self, date: &Date) -> Result<OHLCCents> {
if self._1d.as_ref().and_then(|m| m.last_key_value()).is_none_or(|(k, _)| k <= date) {
if self
._1d
.as_ref()
.and_then(|m| m.last_key_value())
.is_none_or(|(k, _)| k <= date)
{
self._1d.replace(self.fetch_1d()?);
}
self._1d
@@ -114,7 +124,9 @@ impl Kraken {
}
pub fn ping(&self) -> Result<()> {
self.agent.get("https://api.kraken.com/0/public/Time").call()?;
self.agent
.get("https://api.kraken.com/0/public/Time")
.call()?;
Ok(())
}
}