mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-12 16:03:31 -07:00
global: refactor
This commit is contained in:
@@ -1135,7 +1135,7 @@ pub struct CapCapitalizedGrossLossMvrvNetPeakPriceProfitSellSoprPattern {
|
||||
pub price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern,
|
||||
pub profit: BlockCumulativeSumPattern,
|
||||
pub profit_to_loss_ratio: _1m1w1y24hPattern<StoredF64>,
|
||||
pub sell_side_risk_ratio: _1m1w1y24hPattern7,
|
||||
pub sell_side_risk_ratio: _1m1w1y24hPattern8,
|
||||
pub sopr: AdjustedRatioValuePattern,
|
||||
}
|
||||
|
||||
@@ -1777,7 +1777,7 @@ impl CentsNegativeToUsdPattern2 {
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct DeltaDominanceHalfInTotalPattern2 {
|
||||
pub delta: AbsoluteRatePattern,
|
||||
pub delta: AbsoluteRatePattern3,
|
||||
pub dominance: BpsPercentRatioPattern2,
|
||||
pub half: BtcCentsSatsUsdPattern,
|
||||
pub in_loss: BtcCentsSatsShareUsdPattern,
|
||||
@@ -1789,7 +1789,7 @@ impl DeltaDominanceHalfInTotalPattern2 {
|
||||
/// Create a new pattern node with accumulated series name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
delta: AbsoluteRatePattern::new(client.clone(), _m(&acc, "delta")),
|
||||
delta: AbsoluteRatePattern3::new(client.clone(), _m(&acc, "delta")),
|
||||
dominance: BpsPercentRatioPattern2::new(client.clone(), _m(&acc, "dominance")),
|
||||
half: BtcCentsSatsUsdPattern::new(client.clone(), _m(&acc, "half")),
|
||||
in_loss: BtcCentsSatsShareUsdPattern::new(client.clone(), _m(&acc, "in_loss")),
|
||||
@@ -1801,7 +1801,7 @@ impl DeltaDominanceHalfInTotalPattern2 {
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct DeltaDominanceHalfInTotalPattern {
|
||||
pub delta: AbsoluteRatePattern,
|
||||
pub delta: AbsoluteRatePattern3,
|
||||
pub dominance: BpsPercentRatioPattern2,
|
||||
pub half: BtcCentsSatsUsdPattern,
|
||||
pub in_loss: BtcCentsSatsUsdPattern,
|
||||
@@ -1813,7 +1813,7 @@ impl DeltaDominanceHalfInTotalPattern {
|
||||
/// Create a new pattern node with accumulated series name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
delta: AbsoluteRatePattern::new(client.clone(), _m(&acc, "delta")),
|
||||
delta: AbsoluteRatePattern3::new(client.clone(), _m(&acc, "delta")),
|
||||
dominance: BpsPercentRatioPattern2::new(client.clone(), _m(&acc, "dominance")),
|
||||
half: BtcCentsSatsUsdPattern::new(client.clone(), _m(&acc, "half")),
|
||||
in_loss: BtcCentsSatsUsdPattern::new(client.clone(), _m(&acc, "in_loss")),
|
||||
@@ -1981,7 +1981,7 @@ impl BpsCentsRatioSatsUsdPattern {
|
||||
pub struct BtcCentsDeltaSatsUsdPattern {
|
||||
pub btc: SeriesPattern1<Bitcoin>,
|
||||
pub cents: SeriesPattern1<Cents>,
|
||||
pub delta: AbsoluteRatePattern,
|
||||
pub delta: AbsoluteRatePattern3,
|
||||
pub sats: SeriesPattern1<Sats>,
|
||||
pub usd: SeriesPattern1<Dollars>,
|
||||
}
|
||||
@@ -1992,7 +1992,7 @@ impl BtcCentsDeltaSatsUsdPattern {
|
||||
Self {
|
||||
btc: SeriesPattern1::new(client.clone(), acc.clone()),
|
||||
cents: SeriesPattern1::new(client.clone(), _m(&acc, "cents")),
|
||||
delta: AbsoluteRatePattern::new(client.clone(), _m(&acc, "delta")),
|
||||
delta: AbsoluteRatePattern3::new(client.clone(), _m(&acc, "delta")),
|
||||
sats: SeriesPattern1::new(client.clone(), _m(&acc, "sats")),
|
||||
usd: SeriesPattern1::new(client.clone(), _m(&acc, "usd")),
|
||||
}
|
||||
@@ -2117,14 +2117,14 @@ impl _1m1w1y24hPattern2 {
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _1m1w1y24hPattern7 {
|
||||
pub struct _1m1w1y24hPattern8 {
|
||||
pub _1m: BpsPercentRatioPattern4,
|
||||
pub _1w: BpsPercentRatioPattern4,
|
||||
pub _1y: BpsPercentRatioPattern4,
|
||||
pub _24h: BpsPercentRatioPattern4,
|
||||
}
|
||||
|
||||
impl _1m1w1y24hPattern7 {
|
||||
impl _1m1w1y24hPattern8 {
|
||||
/// Create a new pattern node with accumulated series name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
@@ -2176,6 +2176,26 @@ impl _1m1w1y24hPattern3 {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _1m1w1y24hPattern7 {
|
||||
pub _1m: BtcSatsPattern,
|
||||
pub _1w: BtcSatsPattern,
|
||||
pub _1y: BtcSatsPattern,
|
||||
pub _24h: BtcSatsPattern,
|
||||
}
|
||||
|
||||
impl _1m1w1y24hPattern7 {
|
||||
/// Create a new pattern node with accumulated series name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
_1m: BtcSatsPattern::new(client.clone(), _m(&acc, "1m")),
|
||||
_1w: BtcSatsPattern::new(client.clone(), _m(&acc, "1w")),
|
||||
_1y: BtcSatsPattern::new(client.clone(), _m(&acc, "1y")),
|
||||
_24h: BtcSatsPattern::new(client.clone(), _m(&acc, "24h")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _1m1w1y2wPattern {
|
||||
pub _1m: CentsSatsUsdPattern,
|
||||
@@ -2760,7 +2780,7 @@ impl CumulativeRollingSumPattern {
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct DeltaDominanceTotalPattern {
|
||||
pub delta: AbsoluteRatePattern,
|
||||
pub delta: AbsoluteRatePattern3,
|
||||
pub dominance: BpsPercentRatioPattern2,
|
||||
pub total: BtcCentsSatsUsdPattern,
|
||||
}
|
||||
@@ -2769,7 +2789,7 @@ impl DeltaDominanceTotalPattern {
|
||||
/// Create a new pattern node with accumulated series name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
delta: AbsoluteRatePattern::new(client.clone(), _m(&acc, "delta")),
|
||||
delta: AbsoluteRatePattern3::new(client.clone(), _m(&acc, "delta")),
|
||||
dominance: BpsPercentRatioPattern2::new(client.clone(), _m(&acc, "dominance")),
|
||||
total: BtcCentsSatsUsdPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
@@ -2916,6 +2936,22 @@ impl AbsoluteRatePattern2 {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct AbsoluteRatePattern3 {
|
||||
pub absolute: _1m1w1y24hPattern7,
|
||||
pub rate: _1m1w1y24hPattern2,
|
||||
}
|
||||
|
||||
impl AbsoluteRatePattern3 {
|
||||
/// Create a new pattern node with accumulated series name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
absolute: _1m1w1y24hPattern7::new(client.clone(), acc.clone()),
|
||||
rate: _1m1w1y24hPattern2::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct AddrUtxoPattern {
|
||||
pub addr: BtcCentsSatsUsdPattern,
|
||||
@@ -3060,6 +3096,22 @@ impl BpsRatioPattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct BtcSatsPattern {
|
||||
pub btc: SeriesPattern1<Bitcoin>,
|
||||
pub sats: SeriesPattern1<SatsSigned>,
|
||||
}
|
||||
|
||||
impl BtcSatsPattern {
|
||||
/// Create a new pattern node with accumulated series name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
btc: SeriesPattern1::new(client.clone(), acc.clone()),
|
||||
sats: SeriesPattern1::new(client.clone(), _m(&acc, "sats")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct CentsUsdPattern3 {
|
||||
pub cents: SeriesPattern1<Cents>,
|
||||
@@ -7049,7 +7101,7 @@ pub struct SeriesTree_Cohorts_Utxo_All_Realized {
|
||||
pub net_pnl: BlockChangeCumulativeDeltaSumPattern,
|
||||
pub sopr: SeriesTree_Cohorts_Utxo_All_Realized_Sopr,
|
||||
pub gross_pnl: BlockCumulativeSumPattern,
|
||||
pub sell_side_risk_ratio: _1m1w1y24hPattern7,
|
||||
pub sell_side_risk_ratio: _1m1w1y24hPattern8,
|
||||
pub peak_regret: BlockCumulativeSumPattern,
|
||||
pub capitalized: PricePattern,
|
||||
pub profit_to_loss_ratio: _1m1w1y24hPattern<StoredF64>,
|
||||
@@ -7066,7 +7118,7 @@ impl SeriesTree_Cohorts_Utxo_All_Realized {
|
||||
net_pnl: BlockChangeCumulativeDeltaSumPattern::new(client.clone(), "net".to_string()),
|
||||
sopr: SeriesTree_Cohorts_Utxo_All_Realized_Sopr::new(client.clone(), format!("{base_path}_sopr")),
|
||||
gross_pnl: BlockCumulativeSumPattern::new(client.clone(), "realized_gross_pnl".to_string()),
|
||||
sell_side_risk_ratio: _1m1w1y24hPattern7::new(client.clone(), "sell_side_risk_ratio".to_string()),
|
||||
sell_side_risk_ratio: _1m1w1y24hPattern8::new(client.clone(), "sell_side_risk_ratio".to_string()),
|
||||
peak_regret: BlockCumulativeSumPattern::new(client.clone(), "realized_peak_regret".to_string()),
|
||||
capitalized: PricePattern::new(client.clone(), "capitalized_price".to_string()),
|
||||
profit_to_loss_ratio: _1m1w1y24hPattern::new(client.clone(), "realized_profit_to_loss_ratio".to_string()),
|
||||
@@ -7481,7 +7533,7 @@ pub struct SeriesTree_Cohorts_Utxo_Sth_Realized {
|
||||
pub net_pnl: BlockChangeCumulativeDeltaSumPattern,
|
||||
pub sopr: AdjustedRatioValuePattern,
|
||||
pub gross_pnl: BlockCumulativeSumPattern,
|
||||
pub sell_side_risk_ratio: _1m1w1y24hPattern7,
|
||||
pub sell_side_risk_ratio: _1m1w1y24hPattern8,
|
||||
pub peak_regret: BlockCumulativeSumPattern,
|
||||
pub capitalized: PricePattern,
|
||||
pub profit_to_loss_ratio: _1m1w1y24hPattern<StoredF64>,
|
||||
@@ -7498,7 +7550,7 @@ impl SeriesTree_Cohorts_Utxo_Sth_Realized {
|
||||
net_pnl: BlockChangeCumulativeDeltaSumPattern::new(client.clone(), "sth_net".to_string()),
|
||||
sopr: AdjustedRatioValuePattern::new(client.clone(), "sth".to_string()),
|
||||
gross_pnl: BlockCumulativeSumPattern::new(client.clone(), "sth_realized_gross_pnl".to_string()),
|
||||
sell_side_risk_ratio: _1m1w1y24hPattern7::new(client.clone(), "sth_sell_side_risk_ratio".to_string()),
|
||||
sell_side_risk_ratio: _1m1w1y24hPattern8::new(client.clone(), "sth_sell_side_risk_ratio".to_string()),
|
||||
peak_regret: BlockCumulativeSumPattern::new(client.clone(), "sth_realized_peak_regret".to_string()),
|
||||
capitalized: PricePattern::new(client.clone(), "sth_capitalized_price".to_string()),
|
||||
profit_to_loss_ratio: _1m1w1y24hPattern::new(client.clone(), "sth_realized_profit_to_loss_ratio".to_string()),
|
||||
@@ -7751,7 +7803,7 @@ pub struct SeriesTree_Cohorts_Utxo_Lth_Realized {
|
||||
pub net_pnl: BlockChangeCumulativeDeltaSumPattern,
|
||||
pub sopr: SeriesTree_Cohorts_Utxo_Lth_Realized_Sopr,
|
||||
pub gross_pnl: BlockCumulativeSumPattern,
|
||||
pub sell_side_risk_ratio: _1m1w1y24hPattern7,
|
||||
pub sell_side_risk_ratio: _1m1w1y24hPattern8,
|
||||
pub peak_regret: BlockCumulativeSumPattern,
|
||||
pub capitalized: PricePattern,
|
||||
pub profit_to_loss_ratio: _1m1w1y24hPattern<StoredF64>,
|
||||
@@ -7768,7 +7820,7 @@ impl SeriesTree_Cohorts_Utxo_Lth_Realized {
|
||||
net_pnl: BlockChangeCumulativeDeltaSumPattern::new(client.clone(), "lth_net".to_string()),
|
||||
sopr: SeriesTree_Cohorts_Utxo_Lth_Realized_Sopr::new(client.clone(), format!("{base_path}_sopr")),
|
||||
gross_pnl: BlockCumulativeSumPattern::new(client.clone(), "lth_realized_gross_pnl".to_string()),
|
||||
sell_side_risk_ratio: _1m1w1y24hPattern7::new(client.clone(), "lth_sell_side_risk_ratio".to_string()),
|
||||
sell_side_risk_ratio: _1m1w1y24hPattern8::new(client.clone(), "lth_sell_side_risk_ratio".to_string()),
|
||||
peak_regret: BlockCumulativeSumPattern::new(client.clone(), "lth_realized_peak_regret".to_string()),
|
||||
capitalized: PricePattern::new(client.clone(), "lth_capitalized_price".to_string()),
|
||||
profit_to_loss_ratio: _1m1w1y24hPattern::new(client.clone(), "lth_realized_profit_to_loss_ratio".to_string()),
|
||||
@@ -8703,7 +8755,7 @@ pub struct BrkClient {
|
||||
|
||||
impl BrkClient {
|
||||
/// Client version.
|
||||
pub const VERSION: &'static str = "v0.3.0-beta.2";
|
||||
pub const VERSION: &'static str = "v0.3.0-beta.3";
|
||||
|
||||
/// Create a new client with the given base URL.
|
||||
pub fn new(base_url: impl Into<String>) -> Self {
|
||||
|
||||
@@ -3,7 +3,7 @@ use brk_types::Version;
|
||||
use vecdb::Database;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{indexes, internal::AmountPerBlock};
|
||||
use crate::{indexes, internal::ValuePerBlock};
|
||||
|
||||
impl Vecs {
|
||||
pub(crate) fn forced_import(
|
||||
@@ -12,8 +12,8 @@ impl Vecs {
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
vaulted: AmountPerBlock::forced_import(db, "vaulted_supply", version, indexes)?,
|
||||
active: AmountPerBlock::forced_import(db, "active_supply", version, indexes)?,
|
||||
vaulted: ValuePerBlock::forced_import(db, "vaulted_supply", version, indexes)?,
|
||||
active: ValuePerBlock::forced_import(db, "active_supply", version, indexes)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use brk_traversable::Traversable;
|
||||
use vecdb::{Rw, StorageMode};
|
||||
|
||||
use crate::internal::AmountPerBlock;
|
||||
use crate::internal::ValuePerBlock;
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub vaulted: AmountPerBlock<M>,
|
||||
pub active: AmountPerBlock<M>,
|
||||
pub vaulted: ValuePerBlock<M>,
|
||||
pub active: ValuePerBlock<M>,
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use brk_types::{Height, Sats};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use vecdb::ReadableVec;
|
||||
|
||||
use crate::internal::AmountPerBlock;
|
||||
use crate::internal::ValuePerBlock;
|
||||
|
||||
use super::vecs::ExposedAddrSupplyVecs;
|
||||
|
||||
@@ -24,7 +24,7 @@ impl From<(&ExposedAddrSupplyVecs, Height)> for AddrTypeToExposedSupply {
|
||||
fn from((vecs, starting_height): (&ExposedAddrSupplyVecs, Height)) -> Self {
|
||||
if let Some(prev_height) = starting_height.decremented() {
|
||||
let read =
|
||||
|v: &AmountPerBlock| -> Sats { v.sats.height.collect_one(prev_height).unwrap() };
|
||||
|v: &ValuePerBlock| -> Sats { v.sats.height.collect_one(prev_height).unwrap() };
|
||||
Self(ByAddrType {
|
||||
p2pk65: read(&vecs.by_addr_type.p2pk65),
|
||||
p2pk33: read(&vecs.by_addr_type.p2pk33),
|
||||
|
||||
@@ -6,7 +6,7 @@ use vecdb::{Database, Rw, StorageMode};
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{AmountPerBlock, WithAddrTypes},
|
||||
internal::{ValuePerBlock, WithAddrTypes},
|
||||
};
|
||||
|
||||
/// Exposed address supply (sats/btc/cents/usd) — `all` + per-address-type.
|
||||
@@ -15,7 +15,7 @@ use crate::{
|
||||
/// post-hoc from sats × spot price.
|
||||
#[derive(Deref, DerefMut, Traversable)]
|
||||
pub struct ExposedAddrSupplyVecs<M: StorageMode = Rw>(
|
||||
#[traversable(flatten)] pub WithAddrTypes<AmountPerBlock<M>>,
|
||||
#[traversable(flatten)] pub WithAddrTypes<ValuePerBlock<M>>,
|
||||
);
|
||||
|
||||
impl ExposedAddrSupplyVecs {
|
||||
@@ -24,7 +24,7 @@ impl ExposedAddrSupplyVecs {
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
Ok(Self(WithAddrTypes::<AmountPerBlock>::forced_import(
|
||||
Ok(Self(WithAddrTypes::<ValuePerBlock>::forced_import(
|
||||
db,
|
||||
"exposed_supply",
|
||||
version,
|
||||
|
||||
@@ -25,7 +25,7 @@ use crate::{
|
||||
state::UTXOCohortState,
|
||||
},
|
||||
indexes,
|
||||
internal::{AmountPerBlockCumulativeRolling, WindowStartVec, Windows},
|
||||
internal::{ValuePerBlockCumulativeRolling, WindowStartVec, Windows},
|
||||
prices,
|
||||
};
|
||||
|
||||
@@ -50,7 +50,7 @@ pub struct UTXOCohorts<M: StorageMode = Rw> {
|
||||
#[traversable(rename = "type")]
|
||||
pub type_: SpendableType<UTXOCohortVecs<TypeCohortMetrics<M>>>,
|
||||
pub profitability: ProfitabilityMetrics<M>,
|
||||
pub matured: AgeRange<AmountPerBlockCumulativeRolling<M>>,
|
||||
pub matured: AgeRange<ValuePerBlockCumulativeRolling<M>>,
|
||||
#[traversable(skip)]
|
||||
pub(super) caches: UTXOCohortsTransientState,
|
||||
}
|
||||
@@ -264,8 +264,8 @@ impl UTXOCohorts<Rw> {
|
||||
let prefix = CohortContext::Utxo.prefix();
|
||||
let matured = AgeRange::try_new(&|_f: Filter,
|
||||
name: &'static str|
|
||||
-> Result<AmountPerBlockCumulativeRolling> {
|
||||
AmountPerBlockCumulativeRolling::forced_import(
|
||||
-> Result<ValuePerBlockCumulativeRolling> {
|
||||
ValuePerBlockCumulativeRolling::forced_import(
|
||||
db,
|
||||
&format!("{prefix}_{name}_matured_supply"),
|
||||
v,
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::{
|
||||
metrics::ImportConfig,
|
||||
state::{CohortState, CostBasisOps, RealizedOps},
|
||||
},
|
||||
internal::{AmountPerBlockCumulativeRolling, PerBlockCumulativeRolling},
|
||||
internal::{ValuePerBlockCumulativeRolling, PerBlockCumulativeRolling},
|
||||
prices,
|
||||
};
|
||||
|
||||
@@ -24,9 +24,9 @@ pub struct ActivityCore<M: StorageMode = Rw> {
|
||||
|
||||
pub coindays_destroyed: PerBlockCumulativeRolling<StoredF64, StoredF64, M>,
|
||||
#[traversable(wrap = "transfer_volume", rename = "in_profit")]
|
||||
pub transfer_volume_in_profit: AmountPerBlockCumulativeRolling<M>,
|
||||
pub transfer_volume_in_profit: ValuePerBlockCumulativeRolling<M>,
|
||||
#[traversable(wrap = "transfer_volume", rename = "in_loss")]
|
||||
pub transfer_volume_in_loss: AmountPerBlockCumulativeRolling<M>,
|
||||
pub transfer_volume_in_loss: ValuePerBlockCumulativeRolling<M>,
|
||||
}
|
||||
|
||||
impl ActivityCore {
|
||||
|
||||
@@ -8,13 +8,13 @@ use crate::{
|
||||
metrics::ImportConfig,
|
||||
state::{CohortState, CostBasisOps, RealizedOps},
|
||||
},
|
||||
internal::AmountPerBlockCumulativeRolling,
|
||||
internal::ValuePerBlockCumulativeRolling,
|
||||
prices,
|
||||
};
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct ActivityMinimal<M: StorageMode = Rw> {
|
||||
pub transfer_volume: AmountPerBlockCumulativeRolling<M>,
|
||||
pub transfer_volume: ValuePerBlockCumulativeRolling<M>,
|
||||
}
|
||||
|
||||
impl ActivityMinimal {
|
||||
|
||||
@@ -7,7 +7,7 @@ use vecdb::{BytesVec, BytesVecValue, Database, ImportableVec};
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
AmountPerBlock, AmountPerBlockCumulative, AmountPerBlockCumulativeRolling, CentsType,
|
||||
ValuePerBlock, ValuePerBlockCumulative, ValuePerBlockCumulativeRolling, FiatType,
|
||||
FiatPerBlock, FiatPerBlockCumulativeWithSums, NumericValue, PerBlock,
|
||||
PerBlockCumulativeRolling, PercentPerBlock, PercentRollingWindows, Price,
|
||||
PriceWithRatioExtendedPerBlock, PriceWithRatioPerBlock, RatioPerBlock,
|
||||
@@ -35,8 +35,8 @@ macro_rules! impl_config_import {
|
||||
|
||||
// Non-generic types
|
||||
impl_config_import!(
|
||||
AmountPerBlock,
|
||||
AmountPerBlockCumulative,
|
||||
ValuePerBlock,
|
||||
ValuePerBlockCumulative,
|
||||
PriceWithRatioPerBlock,
|
||||
PriceWithRatioExtendedPerBlock,
|
||||
RatioPerBlock<BasisPoints32>,
|
||||
@@ -79,7 +79,7 @@ impl<T: NumericValue + JsonSchema> ConfigImport for RollingWindow24hPerBlock<T>
|
||||
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
|
||||
}
|
||||
}
|
||||
impl ConfigImport for AmountPerBlockCumulativeRolling {
|
||||
impl ConfigImport for ValuePerBlockCumulativeRolling {
|
||||
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
|
||||
Self::forced_import(
|
||||
cfg.db,
|
||||
@@ -90,7 +90,7 @@ impl ConfigImport for AmountPerBlockCumulativeRolling {
|
||||
)
|
||||
}
|
||||
}
|
||||
impl<C: CentsType> ConfigImport for FiatPerBlockCumulativeWithSums<C> {
|
||||
impl<C: FiatType> ConfigImport for FiatPerBlockCumulativeWithSums<C> {
|
||||
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
|
||||
Self::forced_import(
|
||||
cfg.db,
|
||||
@@ -106,7 +106,7 @@ impl<T: NumericValue + JsonSchema> ConfigImport for RollingWindowsFrom1w<T> {
|
||||
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
|
||||
}
|
||||
}
|
||||
impl<C: CentsType> ConfigImport for FiatPerBlock<C> {
|
||||
impl<C: FiatType> ConfigImport for FiatPerBlock<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)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use vecdb::{AnyStoredVec, AnyVec, Database, Exit, Rw, StorageMode, WritableVec};
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
AmountPerBlock, AmountPerBlockWithDeltas, PerBlock, RatioPerBlock, WindowStartVec, Windows,
|
||||
ValuePerBlock, ValuePerBlockWithDeltas, PerBlock, RatioPerBlock, WindowStartVec, Windows,
|
||||
},
|
||||
prices,
|
||||
};
|
||||
@@ -20,7 +20,7 @@ pub struct WithSth<All, Sth = All> {
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct ProfitabilityBucket<M: StorageMode = Rw> {
|
||||
pub supply: WithSth<AmountPerBlockWithDeltas<M>, AmountPerBlock<M>>,
|
||||
pub supply: WithSth<ValuePerBlockWithDeltas<M>, ValuePerBlock<M>>,
|
||||
pub realized_cap: WithSth<PerBlock<Dollars, M>>,
|
||||
pub unrealized_pnl: WithSth<PerBlock<Dollars, M>>,
|
||||
pub nupl: RatioPerBlock<BasisPointsSigned32, M>,
|
||||
@@ -47,14 +47,14 @@ impl ProfitabilityBucket {
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
supply: WithSth {
|
||||
all: AmountPerBlockWithDeltas::forced_import(
|
||||
all: ValuePerBlockWithDeltas::forced_import(
|
||||
db,
|
||||
&format!("{name}_supply"),
|
||||
version,
|
||||
indexes,
|
||||
cached_starts,
|
||||
)?,
|
||||
sth: AmountPerBlock::forced_import(
|
||||
sth: ValuePerBlock::forced_import(
|
||||
db,
|
||||
&format!("{name}_sth_supply"),
|
||||
version,
|
||||
|
||||
@@ -11,7 +11,7 @@ use crate::{
|
||||
blocks,
|
||||
distribution::state::{CohortState, CostBasisData, RealizedState, WithCapital},
|
||||
internal::{
|
||||
AmountPerBlockCumulativeRolling, FiatPerBlockCumulativeWithSums, PercentPerBlock,
|
||||
ValuePerBlockCumulativeRolling, FiatPerBlockCumulativeWithSums, PercentPerBlock,
|
||||
PercentRollingWindows, PriceWithRatioExtendedPerBlock, RatioCents64, RatioCentsBp32,
|
||||
RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32, RatioDollarsBp32,
|
||||
RatioPerBlockPercentiles, RatioPerBlockStdDevBands, RatioSma, RollingWindows,
|
||||
@@ -243,7 +243,7 @@ impl RealizedFull {
|
||||
starting_indexes: &Indexes,
|
||||
height_to_supply: &impl ReadableVec<Height, Bitcoin>,
|
||||
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
|
||||
activity_transfer_volume: &AmountPerBlockCumulativeRolling,
|
||||
activity_transfer_volume: &ValuePerBlockCumulativeRolling,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.core.compute_rest_part2(
|
||||
|
||||
@@ -3,15 +3,15 @@ use brk_traversable::Traversable;
|
||||
use brk_types::{Height, Sats, StoredU64, Version};
|
||||
use vecdb::{AnyStoredVec, Database, Exit, ReadableVec, Rw, StorageMode, WritableVec};
|
||||
|
||||
use crate::{indexes, internal::AmountPerBlock, prices};
|
||||
use crate::{indexes, internal::ValuePerBlock, prices};
|
||||
|
||||
/// Average amount held per UTXO and per funded address.
|
||||
///
|
||||
/// `utxo = supply / utxo_count`, `addr = supply / funded_addr_count`.
|
||||
#[derive(Traversable)]
|
||||
pub struct AvgAmountMetrics<M: StorageMode = Rw> {
|
||||
pub utxo: AmountPerBlock<M>,
|
||||
pub addr: AmountPerBlock<M>,
|
||||
pub utxo: ValuePerBlock<M>,
|
||||
pub addr: ValuePerBlock<M>,
|
||||
}
|
||||
|
||||
impl AvgAmountMetrics {
|
||||
@@ -29,8 +29,8 @@ impl AvgAmountMetrics {
|
||||
}
|
||||
};
|
||||
Ok(Self {
|
||||
utxo: AmountPerBlock::forced_import(db, &name("avg_utxo_amount"), version, indexes)?,
|
||||
addr: AmountPerBlock::forced_import(db, &name("avg_addr_amount"), version, indexes)?,
|
||||
utxo: ValuePerBlock::forced_import(db, &name("avg_utxo_amount"), version, indexes)?,
|
||||
addr: ValuePerBlock::forced_import(db, &name("avg_addr_amount"), version, indexes)?,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::{
|
||||
};
|
||||
|
||||
use crate::internal::{
|
||||
AmountPerBlock, LazyRollingDeltasFromHeight, PercentPerBlock, RatioSatsBp16,
|
||||
LazyRollingDeltasAmountFromHeight, PercentPerBlock, RatioSatsBp16, ValuePerBlock,
|
||||
};
|
||||
|
||||
use crate::distribution::metrics::ImportConfig;
|
||||
@@ -17,17 +17,17 @@ use crate::distribution::metrics::ImportConfig;
|
||||
/// Base supply metrics: total supply + dominance (share of circulating).
|
||||
#[derive(Traversable)]
|
||||
pub struct SupplyBase<M: StorageMode = Rw> {
|
||||
pub total: AmountPerBlock<M>,
|
||||
pub delta: LazyRollingDeltasFromHeight<Sats, SatsSigned, BasisPointsSigned32>,
|
||||
pub total: ValuePerBlock<M>,
|
||||
pub delta: LazyRollingDeltasAmountFromHeight<Sats, SatsSigned, BasisPointsSigned32>,
|
||||
#[traversable(rename = "dominance")]
|
||||
pub dominance: PercentPerBlock<BasisPoints16, M>,
|
||||
}
|
||||
|
||||
impl SupplyBase {
|
||||
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||
let supply: AmountPerBlock = cfg.import("supply", Version::ZERO)?;
|
||||
let supply: ValuePerBlock = cfg.import("supply", Version::ZERO)?;
|
||||
|
||||
let delta = LazyRollingDeltasFromHeight::new(
|
||||
let delta = LazyRollingDeltasAmountFromHeight::new(
|
||||
&cfg.name("supply_delta"),
|
||||
cfg.version + Version::ONE,
|
||||
&supply.sats.height,
|
||||
|
||||
@@ -7,7 +7,7 @@ use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
|
||||
use crate::{distribution::state::UnrealizedState, prices};
|
||||
|
||||
use crate::internal::{
|
||||
AmountPerBlock, HalveCents, HalveDollars, HalveSats, HalveSatsToBitcoin, LazyAmountPerBlock,
|
||||
ValuePerBlock, HalveCents, HalveDollars, HalveSats, HalveSatsToBitcoin, LazyValuePerBlock,
|
||||
};
|
||||
|
||||
use crate::distribution::metrics::ImportConfig;
|
||||
@@ -22,9 +22,9 @@ pub struct SupplyCore<M: StorageMode = Rw> {
|
||||
#[traversable(flatten)]
|
||||
pub base: SupplyBase<M>,
|
||||
|
||||
pub half: LazyAmountPerBlock,
|
||||
pub in_profit: AmountPerBlock<M>,
|
||||
pub in_loss: AmountPerBlock<M>,
|
||||
pub half: LazyValuePerBlock,
|
||||
pub in_profit: ValuePerBlock<M>,
|
||||
pub in_loss: ValuePerBlock<M>,
|
||||
}
|
||||
|
||||
impl SupplyCore {
|
||||
@@ -32,7 +32,7 @@ impl SupplyCore {
|
||||
let v0 = Version::ZERO;
|
||||
let base = SupplyBase::forced_import(cfg)?;
|
||||
|
||||
let half = LazyAmountPerBlock::from_block_source::<
|
||||
let half = LazyValuePerBlock::from_block_source::<
|
||||
HalveSats,
|
||||
HalveSatsToBitcoin,
|
||||
HalveCents,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
pub(crate) mod algo;
|
||||
mod amount;
|
||||
mod block_walker;
|
||||
mod cache_budget;
|
||||
mod containers;
|
||||
@@ -9,9 +8,9 @@ mod per_block;
|
||||
mod per_tx;
|
||||
mod traits;
|
||||
mod transform;
|
||||
mod value;
|
||||
mod with_addr_types;
|
||||
|
||||
pub(crate) use amount::*;
|
||||
pub(crate) use block_walker::*;
|
||||
pub(crate) use cache_budget::*;
|
||||
pub(crate) use containers::*;
|
||||
@@ -20,4 +19,5 @@ pub(crate) use per_block::*;
|
||||
pub(crate) use per_tx::*;
|
||||
pub(crate) use traits::*;
|
||||
pub use transform::*;
|
||||
pub(crate) use value::*;
|
||||
pub(crate) use with_addr_types::*;
|
||||
|
||||
@@ -12,27 +12,27 @@ use crate::{
|
||||
};
|
||||
|
||||
/// Trait that associates a cents type with its transform to Dollars.
|
||||
pub trait CentsType: NumericValue + JsonSchema {
|
||||
pub trait FiatType: NumericValue + JsonSchema {
|
||||
type ToDollars: UnaryTransform<Self, Dollars>;
|
||||
}
|
||||
|
||||
impl CentsType for Cents {
|
||||
impl FiatType for Cents {
|
||||
type ToDollars = CentsUnsignedToDollars;
|
||||
}
|
||||
|
||||
impl CentsType for CentsSigned {
|
||||
impl FiatType for CentsSigned {
|
||||
type ToDollars = CentsSignedToDollars;
|
||||
}
|
||||
|
||||
/// Height-indexed fiat monetary value: cents (eager, integer) + usd (lazy, float).
|
||||
/// Generic over `C` to support both `Cents` (unsigned) and `CentsSigned` (signed).
|
||||
#[derive(Traversable)]
|
||||
pub struct FiatPerBlock<C: CentsType, M: StorageMode = Rw> {
|
||||
pub struct FiatPerBlock<C: FiatType, M: StorageMode = Rw> {
|
||||
pub usd: LazyPerBlock<Dollars, C>,
|
||||
pub cents: PerBlock<C, M>,
|
||||
}
|
||||
|
||||
impl<C: CentsType> FiatPerBlock<C> {
|
||||
impl<C: FiatType> FiatPerBlock<C> {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
|
||||
@@ -5,16 +5,16 @@ use vecdb::{
|
||||
Database, EagerVec, ImportableVec, LazyVecFrom1, PcoVec, ReadableCloneableVec, Rw, StorageMode,
|
||||
};
|
||||
|
||||
use super::CentsType;
|
||||
use super::FiatType;
|
||||
|
||||
/// Raw per-block fiat data: cents (stored) + usd (lazy), no resolutions.
|
||||
#[derive(Traversable)]
|
||||
pub struct FiatBlock<C: CentsType, M: StorageMode = Rw> {
|
||||
pub struct FiatBlock<C: FiatType, M: StorageMode = Rw> {
|
||||
pub usd: LazyVecFrom1<Height, Dollars, Height, C>,
|
||||
pub cents: M::Stored<EagerVec<PcoVec<Height, C>>>,
|
||||
}
|
||||
|
||||
impl<C: CentsType> FiatBlock<C> {
|
||||
impl<C: FiatType> FiatBlock<C> {
|
||||
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
let cents: EagerVec<PcoVec<Height, C>> =
|
||||
EagerVec::forced_import(db, &format!("{name}_cents"), version)?;
|
||||
|
||||
@@ -6,18 +6,18 @@ use vecdb::{Database, Exit, Rw, StorageMode};
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
CentsType, FiatBlock, FiatPerBlock, LazyRollingSumsFiatFromHeight, WindowStartVec, Windows,
|
||||
FiatType, FiatBlock, FiatPerBlock, LazyRollingSumsFiatFromHeight, WindowStartVec, Windows,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct FiatPerBlockCumulativeWithSums<C: CentsType, M: StorageMode = Rw> {
|
||||
pub struct FiatPerBlockCumulativeWithSums<C: FiatType, M: StorageMode = Rw> {
|
||||
pub block: FiatBlock<C, M>,
|
||||
pub cumulative: FiatPerBlock<C, M>,
|
||||
pub sum: LazyRollingSumsFiatFromHeight<C>,
|
||||
}
|
||||
|
||||
impl<C: CentsType> FiatPerBlockCumulativeWithSums<C> {
|
||||
impl<C: FiatType> FiatPerBlockCumulativeWithSums<C> {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
|
||||
@@ -9,13 +9,13 @@ use crate::{
|
||||
internal::{BpsType, LazyRollingDeltasFiatFromHeight, WindowStartVec, Windows},
|
||||
};
|
||||
|
||||
use super::{CentsType, FiatPerBlockCumulativeWithSums};
|
||||
use super::{FiatType, FiatPerBlockCumulativeWithSums};
|
||||
|
||||
#[derive(Deref, DerefMut, Traversable)]
|
||||
pub struct FiatPerBlockCumulativeWithSumsAndDeltas<C, CS, B, M: StorageMode = Rw>
|
||||
where
|
||||
C: CentsType + Into<f64>,
|
||||
CS: CentsType + From<f64>,
|
||||
C: FiatType + Into<f64>,
|
||||
CS: FiatType + From<f64>,
|
||||
B: BpsType + From<f64>,
|
||||
{
|
||||
#[deref]
|
||||
@@ -27,8 +27,8 @@ where
|
||||
|
||||
impl<C, CS, B> FiatPerBlockCumulativeWithSumsAndDeltas<C, CS, B>
|
||||
where
|
||||
C: CentsType + Into<f64>,
|
||||
CS: CentsType + From<f64>,
|
||||
C: FiatType + Into<f64>,
|
||||
CS: FiatType + From<f64>,
|
||||
B: BpsType + From<f64>,
|
||||
{
|
||||
pub(crate) fn forced_import(
|
||||
|
||||
@@ -2,17 +2,17 @@ use brk_traversable::Traversable;
|
||||
use brk_types::{Dollars, Version};
|
||||
use vecdb::ReadableCloneableVec;
|
||||
|
||||
use crate::internal::{CentsType, Identity, LazyPerBlock, NumericValue, PerBlock};
|
||||
use crate::internal::{FiatType, Identity, LazyPerBlock, NumericValue, PerBlock};
|
||||
|
||||
/// Lazy fiat: both cents and usd are lazy views of a stored source.
|
||||
/// Zero extra stored vecs.
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct LazyFiatPerBlock<C: CentsType> {
|
||||
pub struct LazyFiatPerBlock<C: FiatType> {
|
||||
pub usd: LazyPerBlock<Dollars, C>,
|
||||
pub cents: LazyPerBlock<C, C>,
|
||||
}
|
||||
|
||||
impl<C: CentsType> LazyFiatPerBlock<C> {
|
||||
impl<C: FiatType> LazyFiatPerBlock<C> {
|
||||
pub(crate) fn from_computed(name: &str, version: Version, source: &PerBlock<C>) -> Self
|
||||
where
|
||||
C: NumericValue,
|
||||
|
||||
@@ -6,24 +6,24 @@ use vecdb::{DeltaSub, LazyDeltaVec, LazyVecFrom1, ReadOnlyClone, ReadableCloneab
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
CentsType, DerivedResolutions, LazyPerBlock, LazyRollingSumFromHeight, Resolutions,
|
||||
FiatType, DerivedResolutions, LazyPerBlock, LazyRollingSumFromHeight, Resolutions,
|
||||
WindowStartVec, Windows,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct LazyRollingSumFiatFromHeight<C: CentsType> {
|
||||
pub struct LazyRollingSumFiatFromHeight<C: FiatType> {
|
||||
pub usd: LazyPerBlock<Dollars, C>,
|
||||
pub cents: LazyRollingSumFromHeight<C>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||
#[traversable(transparent)]
|
||||
pub struct LazyRollingSumsFiatFromHeight<C: CentsType>(
|
||||
pub struct LazyRollingSumsFiatFromHeight<C: FiatType>(
|
||||
pub Windows<LazyRollingSumFiatFromHeight<C>>,
|
||||
);
|
||||
|
||||
impl<C: CentsType> LazyRollingSumsFiatFromHeight<C> {
|
||||
impl<C: FiatType> LazyRollingSumsFiatFromHeight<C> {
|
||||
pub fn new(
|
||||
name: &str,
|
||||
version: Version,
|
||||
|
||||
@@ -10,13 +10,13 @@ use crate::{
|
||||
internal::{BpsType, LazyRollingDeltasFiatFromHeight, WindowStartVec, Windows},
|
||||
};
|
||||
|
||||
use super::{CentsType, FiatPerBlock};
|
||||
use super::{FiatType, FiatPerBlock};
|
||||
|
||||
#[derive(Deref, DerefMut, Traversable)]
|
||||
pub struct FiatPerBlockWithDeltas<C, CS, B, M: StorageMode = Rw>
|
||||
where
|
||||
C: CentsType + Into<f64>,
|
||||
CS: CentsType + From<f64>,
|
||||
C: FiatType + Into<f64>,
|
||||
CS: FiatType + From<f64>,
|
||||
B: BpsType + From<f64>,
|
||||
{
|
||||
#[deref]
|
||||
@@ -28,8 +28,8 @@ where
|
||||
|
||||
impl<C, CS, B> FiatPerBlockWithDeltas<C, CS, B>
|
||||
where
|
||||
C: CentsType + JsonSchema + Into<f64>,
|
||||
CS: CentsType + From<f64>,
|
||||
C: FiatType + JsonSchema + Into<f64>,
|
||||
CS: FiatType + From<f64>,
|
||||
B: BpsType + From<f64>,
|
||||
{
|
||||
pub(crate) fn forced_import(
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
mod amount;
|
||||
mod computed;
|
||||
mod fiat;
|
||||
mod lazy;
|
||||
@@ -8,8 +7,8 @@ mod price;
|
||||
mod ratio;
|
||||
mod rolling;
|
||||
mod stddev;
|
||||
mod value;
|
||||
|
||||
pub use amount::*;
|
||||
pub use computed::*;
|
||||
pub use fiat::*;
|
||||
pub use lazy::*;
|
||||
@@ -19,3 +18,4 @@ pub use price::*;
|
||||
pub use ratio::*;
|
||||
pub use rolling::*;
|
||||
pub use stddev::*;
|
||||
pub use value::*;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Dollars, Height, StoredF32, Version};
|
||||
use brk_types::{Bitcoin, Dollars, Height, StoredF32, Version};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{
|
||||
@@ -10,8 +10,8 @@ use vecdb::{
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
BpsType, CentsType, DerivedResolutions, LazyPerBlock, NumericValue, Percent, Resolutions,
|
||||
WindowStartVec, Windows,
|
||||
AmountType, BpsType, DerivedResolutions, FiatType, LazyPerBlock, NumericValue, Percent,
|
||||
Resolutions, WindowStartVec, Windows,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -160,6 +160,152 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Amount delta types (sats change + lazy BTC + rate)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Single-slot amount delta change: sats delta + lazy BTC.
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct LazyDeltaAmountFromHeight<S, C>
|
||||
where
|
||||
S: VecValue,
|
||||
C: AmountType,
|
||||
{
|
||||
pub btc: LazyPerBlock<Bitcoin, C>,
|
||||
pub sats: LazyDeltaFromHeight<S, C, DeltaChange>,
|
||||
}
|
||||
|
||||
/// Lazy amount rolling deltas for all 4 windows.
|
||||
///
|
||||
/// Tree shape: `absolute._24h.{sats,btc}/...`, `rate._24h/...` — mirrors
|
||||
/// `LazyRollingDeltasFiatFromHeight` but stores sats instead of cents and
|
||||
/// derives a lazy BTC view alongside (free, since sats → btc is a scalar
|
||||
/// transform).
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct LazyRollingDeltasAmountFromHeight<S, C, B>
|
||||
where
|
||||
S: VecValue,
|
||||
C: AmountType,
|
||||
B: BpsType,
|
||||
{
|
||||
pub absolute: Windows<LazyDeltaAmountFromHeight<S, C>>,
|
||||
pub rate: Windows<LazyDeltaPercentFromHeight<S, B>>,
|
||||
}
|
||||
|
||||
impl<S, C, B> LazyRollingDeltasAmountFromHeight<S, C, B>
|
||||
where
|
||||
S: VecValue + Into<f64>,
|
||||
C: AmountType + From<f64>,
|
||||
B: BpsType + From<f64>,
|
||||
{
|
||||
pub fn new(
|
||||
name: &str,
|
||||
version: Version,
|
||||
source: &(impl ReadableCloneableVec<Height, S> + 'static),
|
||||
cached_starts: &Windows<&WindowStartVec>,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Self {
|
||||
let src = source.read_only_boxed_clone();
|
||||
|
||||
let make_slot = |suffix: &str, cached_start: &&WindowStartVec| {
|
||||
let full_name = format!("{name}_{suffix}");
|
||||
let cached = cached_start.read_only_clone();
|
||||
let starts_version = cached.version();
|
||||
|
||||
// Absolute change (sats): source[h] - source[ago] as C (via f64)
|
||||
let sats_name = format!("{full_name}_sats");
|
||||
let change_vec = LazyDeltaVec::<Height, S, C, DeltaChange>::new(
|
||||
&sats_name,
|
||||
version,
|
||||
src.clone(),
|
||||
starts_version,
|
||||
{
|
||||
let cached = cached.clone();
|
||||
move || cached.cached()
|
||||
},
|
||||
);
|
||||
let change_resolutions =
|
||||
Resolutions::forced_import(&sats_name, change_vec.clone(), version, indexes);
|
||||
let sats = LazyDeltaFromHeight {
|
||||
height: change_vec,
|
||||
resolutions: Box::new(change_resolutions),
|
||||
};
|
||||
|
||||
// Absolute change (btc): lazy from sats delta
|
||||
let btc = LazyPerBlock {
|
||||
height: LazyVecFrom1::transformed::<C::ToBitcoin>(
|
||||
&full_name,
|
||||
version,
|
||||
sats.height.read_only_boxed_clone(),
|
||||
),
|
||||
resolutions: Box::new(DerivedResolutions::from_derived_computed::<C::ToBitcoin>(
|
||||
&full_name,
|
||||
version,
|
||||
&sats.resolutions,
|
||||
)),
|
||||
};
|
||||
|
||||
let absolute = LazyDeltaAmountFromHeight { btc, sats };
|
||||
|
||||
// Rate BPS: (source[h] - source[ago]) / source[ago] as B (via f64)
|
||||
let rate_bps_name = format!("{full_name}_rate_bps");
|
||||
let rate_vec = LazyDeltaVec::<Height, S, B, DeltaRate>::new(
|
||||
&rate_bps_name,
|
||||
version,
|
||||
src.clone(),
|
||||
starts_version,
|
||||
move || cached.cached(),
|
||||
);
|
||||
let rate_resolutions =
|
||||
Resolutions::forced_import(&rate_bps_name, rate_vec.clone(), version, indexes);
|
||||
let bps = LazyDeltaFromHeight {
|
||||
height: rate_vec,
|
||||
resolutions: Box::new(rate_resolutions),
|
||||
};
|
||||
|
||||
let rate_ratio_name = format!("{full_name}_rate_ratio");
|
||||
let ratio = LazyPerBlock {
|
||||
height: LazyVecFrom1::transformed::<B::ToRatio>(
|
||||
&rate_ratio_name,
|
||||
version,
|
||||
bps.height.read_only_boxed_clone(),
|
||||
),
|
||||
resolutions: Box::new(DerivedResolutions::from_derived_computed::<B::ToRatio>(
|
||||
&rate_ratio_name,
|
||||
version,
|
||||
&bps.resolutions,
|
||||
)),
|
||||
};
|
||||
|
||||
let rate_name = format!("{full_name}_rate");
|
||||
let percent = LazyPerBlock {
|
||||
height: LazyVecFrom1::transformed::<B::ToPercent>(
|
||||
&rate_name,
|
||||
version,
|
||||
bps.height.read_only_boxed_clone(),
|
||||
),
|
||||
resolutions: Box::new(DerivedResolutions::from_derived_computed::<B::ToPercent>(
|
||||
&rate_name,
|
||||
version,
|
||||
&bps.resolutions,
|
||||
)),
|
||||
};
|
||||
|
||||
let rate = LazyDeltaPercentFromHeight(Percent {
|
||||
bps,
|
||||
ratio,
|
||||
percent,
|
||||
});
|
||||
|
||||
(absolute, rate)
|
||||
};
|
||||
|
||||
let (absolute, rate) = cached_starts.map_with_suffix(make_slot).unzip();
|
||||
|
||||
Self { absolute, rate }
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Fiat delta types (cents change + lazy USD + rate)
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -169,7 +315,7 @@ where
|
||||
pub struct LazyDeltaFiatFromHeight<S, C>
|
||||
where
|
||||
S: VecValue,
|
||||
C: CentsType,
|
||||
C: FiatType,
|
||||
{
|
||||
pub usd: LazyPerBlock<Dollars, C>,
|
||||
pub cents: LazyDeltaFromHeight<S, C, DeltaChange>,
|
||||
@@ -184,7 +330,7 @@ where
|
||||
pub struct LazyRollingDeltasFiatFromHeight<S, C, B>
|
||||
where
|
||||
S: VecValue,
|
||||
C: CentsType,
|
||||
C: FiatType,
|
||||
B: BpsType,
|
||||
{
|
||||
pub absolute: Windows<LazyDeltaFiatFromHeight<S, C>>,
|
||||
@@ -194,7 +340,7 @@ where
|
||||
impl<S, C, B> LazyRollingDeltasFiatFromHeight<S, C, B>
|
||||
where
|
||||
S: VecValue + Into<f64>,
|
||||
C: CentsType + From<f64>,
|
||||
C: FiatType + From<f64>,
|
||||
B: BpsType + From<f64>,
|
||||
{
|
||||
pub fn new(
|
||||
|
||||
+22
-5
@@ -1,23 +1,40 @@
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
|
||||
use vecdb::{Database, Exit, ReadableCloneableVec, Rw, StorageMode};
|
||||
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, SatsSigned, Version};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{Database, Exit, ReadableCloneableVec, Rw, StorageMode, UnaryTransform};
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{CentsUnsignedToDollars, LazyPerBlock, PerBlock, SatsToBitcoin, SatsToCents},
|
||||
internal::{
|
||||
CentsUnsignedToDollars, LazyPerBlock, NumericValue, PerBlock, SatsSignedToBitcoin,
|
||||
SatsToBitcoin, SatsToCents,
|
||||
},
|
||||
prices,
|
||||
};
|
||||
|
||||
/// Trait that associates a sats type with its transform to Bitcoin.
|
||||
pub trait AmountType: NumericValue + JsonSchema {
|
||||
type ToBitcoin: UnaryTransform<Self, Bitcoin>;
|
||||
}
|
||||
|
||||
impl AmountType for Sats {
|
||||
type ToBitcoin = SatsToBitcoin;
|
||||
}
|
||||
|
||||
impl AmountType for SatsSigned {
|
||||
type ToBitcoin = SatsSignedToBitcoin;
|
||||
}
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct AmountPerBlock<M: StorageMode = Rw> {
|
||||
pub struct ValuePerBlock<M: StorageMode = Rw> {
|
||||
pub btc: LazyPerBlock<Bitcoin, Sats>,
|
||||
pub sats: PerBlock<Sats, M>,
|
||||
pub usd: LazyPerBlock<Dollars, Cents>,
|
||||
pub cents: PerBlock<Cents, M>,
|
||||
}
|
||||
|
||||
impl AmountPerBlock {
|
||||
impl ValuePerBlock {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
+2
-2
@@ -13,14 +13,14 @@ use crate::{
|
||||
|
||||
/// Raw per-block amount data: sats + cents (stored), btc + usd (lazy), no resolutions.
|
||||
#[derive(Traversable)]
|
||||
pub struct AmountBlock<M: StorageMode = Rw> {
|
||||
pub struct ValueBlock<M: StorageMode = Rw> {
|
||||
pub btc: LazyVecFrom1<Height, Bitcoin, Height, Sats>,
|
||||
pub sats: M::Stored<EagerVec<PcoVec<Height, Sats>>>,
|
||||
pub usd: LazyVecFrom1<Height, Dollars, Height, Cents>,
|
||||
pub cents: M::Stored<EagerVec<PcoVec<Height, Cents>>>,
|
||||
}
|
||||
|
||||
impl AmountBlock {
|
||||
impl ValueBlock {
|
||||
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
let sats: EagerVec<PcoVec<Height, Sats>> =
|
||||
EagerVec::forced_import(db, &format!("{name}_sats"), version)?;
|
||||
+7
-7
@@ -5,19 +5,19 @@ use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{AmountBlock, AmountPerBlock},
|
||||
internal::{ValueBlock, ValuePerBlock},
|
||||
prices,
|
||||
};
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct AmountPerBlockCumulative<M: StorageMode = Rw> {
|
||||
pub block: AmountBlock<M>,
|
||||
pub cumulative: AmountPerBlock<M>,
|
||||
pub struct ValuePerBlockCumulative<M: StorageMode = Rw> {
|
||||
pub block: ValueBlock<M>,
|
||||
pub cumulative: ValuePerBlock<M>,
|
||||
}
|
||||
|
||||
const VERSION: Version = Version::ONE;
|
||||
|
||||
impl AmountPerBlockCumulative {
|
||||
impl ValuePerBlockCumulative {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
@@ -27,8 +27,8 @@ impl AmountPerBlockCumulative {
|
||||
let v = version + VERSION;
|
||||
|
||||
Ok(Self {
|
||||
block: AmountBlock::forced_import(db, name, v)?,
|
||||
cumulative: AmountPerBlock::forced_import(
|
||||
block: ValueBlock::forced_import(db, name, v)?,
|
||||
cumulative: ValuePerBlock::forced_import(
|
||||
db,
|
||||
&format!("{name}_cumulative"),
|
||||
v,
|
||||
+5
-5
@@ -7,25 +7,25 @@ use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
AmountPerBlockCumulative, LazyRollingAvgsAmountFromHeight, LazyRollingSumsAmountFromHeight,
|
||||
ValuePerBlockCumulative, LazyRollingAvgsAmountFromHeight, LazyRollingSumsAmountFromHeight,
|
||||
WindowStartVec, Windows,
|
||||
},
|
||||
prices,
|
||||
};
|
||||
|
||||
#[derive(Deref, DerefMut, Traversable)]
|
||||
pub struct AmountPerBlockCumulativeRolling<M: StorageMode = Rw> {
|
||||
pub struct ValuePerBlockCumulativeRolling<M: StorageMode = Rw> {
|
||||
#[deref]
|
||||
#[deref_mut]
|
||||
#[traversable(flatten)]
|
||||
pub inner: AmountPerBlockCumulative<M>,
|
||||
pub inner: ValuePerBlockCumulative<M>,
|
||||
pub sum: LazyRollingSumsAmountFromHeight,
|
||||
pub average: LazyRollingAvgsAmountFromHeight,
|
||||
}
|
||||
|
||||
const VERSION: Version = Version::TWO;
|
||||
|
||||
impl AmountPerBlockCumulativeRolling {
|
||||
impl ValuePerBlockCumulativeRolling {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
@@ -35,7 +35,7 @@ impl AmountPerBlockCumulativeRolling {
|
||||
) -> Result<Self> {
|
||||
let v = version + VERSION;
|
||||
|
||||
let inner = AmountPerBlockCumulative::forced_import(db, name, v, indexes)?;
|
||||
let inner = ValuePerBlockCumulative::forced_import(db, name, v, indexes)?;
|
||||
let sum = LazyRollingSumsAmountFromHeight::new(
|
||||
&format!("{name}_sum"),
|
||||
v,
|
||||
+7
-7
@@ -7,25 +7,25 @@ use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
AmountPerBlockCumulativeRolling, RollingDistributionAmountPerBlock, WindowStartVec,
|
||||
ValuePerBlockCumulativeRolling, RollingDistributionValuePerBlock, WindowStartVec,
|
||||
WindowStarts, Windows,
|
||||
},
|
||||
prices,
|
||||
};
|
||||
|
||||
#[derive(Deref, DerefMut, Traversable)]
|
||||
pub struct AmountPerBlockFull<M: StorageMode = Rw> {
|
||||
pub struct ValuePerBlockFull<M: StorageMode = Rw> {
|
||||
#[deref]
|
||||
#[deref_mut]
|
||||
#[traversable(flatten)]
|
||||
pub inner: AmountPerBlockCumulativeRolling<M>,
|
||||
pub inner: ValuePerBlockCumulativeRolling<M>,
|
||||
#[traversable(flatten)]
|
||||
pub distribution: RollingDistributionAmountPerBlock<M>,
|
||||
pub distribution: RollingDistributionValuePerBlock<M>,
|
||||
}
|
||||
|
||||
const VERSION: Version = Version::TWO;
|
||||
|
||||
impl AmountPerBlockFull {
|
||||
impl ValuePerBlockFull {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
@@ -36,8 +36,8 @@ impl AmountPerBlockFull {
|
||||
let v = version + VERSION;
|
||||
|
||||
let inner =
|
||||
AmountPerBlockCumulativeRolling::forced_import(db, name, v, indexes, cached_starts)?;
|
||||
let distribution = RollingDistributionAmountPerBlock::forced_import(db, name, v, indexes)?;
|
||||
ValuePerBlockCumulativeRolling::forced_import(db, name, v, indexes, cached_starts)?;
|
||||
let distribution = RollingDistributionValuePerBlock::forced_import(db, name, v, indexes)?;
|
||||
|
||||
Ok(Self {
|
||||
inner,
|
||||
+11
-11
@@ -1,4 +1,4 @@
|
||||
//! Lazy value wrapper for AmountPerBlock - all transforms are lazy.
|
||||
//! Lazy value wrapper for ValuePerBlock - all transforms are lazy.
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
|
||||
@@ -6,22 +6,22 @@ use derive_more::{Deref, DerefMut};
|
||||
use vecdb::UnaryTransform;
|
||||
|
||||
use crate::internal::{
|
||||
AmountPerBlock, Identity, LazyAmount, LazyAmountDerivedResolutions, SatsToBitcoin,
|
||||
ValuePerBlock, Identity, LazyValue, LazyValueDerivedResolutions, SatsToBitcoin,
|
||||
};
|
||||
|
||||
/// Lazy value wrapper with height + all derived last transforms from AmountPerBlock.
|
||||
/// Lazy value wrapper with height + all derived last transforms from ValuePerBlock.
|
||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||
#[traversable(merge)]
|
||||
pub struct LazyAmountPerBlock {
|
||||
pub struct LazyValuePerBlock {
|
||||
#[traversable(flatten)]
|
||||
pub height: LazyAmount<Height>,
|
||||
pub height: LazyValue<Height>,
|
||||
#[deref]
|
||||
#[deref_mut]
|
||||
#[traversable(flatten)]
|
||||
pub resolutions: Box<LazyAmountDerivedResolutions>,
|
||||
pub resolutions: Box<LazyValueDerivedResolutions>,
|
||||
}
|
||||
|
||||
impl LazyAmountPerBlock {
|
||||
impl LazyValuePerBlock {
|
||||
pub(crate) fn from_block_source<
|
||||
SatsTransform,
|
||||
BitcoinTransform,
|
||||
@@ -29,7 +29,7 @@ impl LazyAmountPerBlock {
|
||||
DollarsTransform,
|
||||
>(
|
||||
name: &str,
|
||||
source: &AmountPerBlock,
|
||||
source: &ValuePerBlock,
|
||||
version: Version,
|
||||
) -> Self
|
||||
where
|
||||
@@ -38,14 +38,14 @@ impl LazyAmountPerBlock {
|
||||
CentsTransform: UnaryTransform<Cents, Cents>,
|
||||
DollarsTransform: UnaryTransform<Dollars, Dollars>,
|
||||
{
|
||||
let height = LazyAmount::from_block_source::<
|
||||
let height = LazyValue::from_block_source::<
|
||||
SatsTransform,
|
||||
BitcoinTransform,
|
||||
CentsTransform,
|
||||
DollarsTransform,
|
||||
>(name, source, version);
|
||||
|
||||
let resolutions = LazyAmountDerivedResolutions::from_block_source::<
|
||||
let resolutions = LazyValueDerivedResolutions::from_block_source::<
|
||||
SatsTransform,
|
||||
BitcoinTransform,
|
||||
CentsTransform,
|
||||
@@ -58,7 +58,7 @@ impl LazyAmountPerBlock {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn identity(name: &str, source: &AmountPerBlock, version: Version) -> Self {
|
||||
pub(crate) fn identity(name: &str, source: &ValuePerBlock, version: Version) -> Self {
|
||||
Self::from_block_source::<Identity<Sats>, SatsToBitcoin, Identity<Cents>, Identity<Dollars>>(
|
||||
name, source, version,
|
||||
)
|
||||
+4
-4
@@ -2,17 +2,17 @@ use brk_traversable::Traversable;
|
||||
use brk_types::{Bitcoin, Cents, Dollars, Sats, Version};
|
||||
use vecdb::UnaryTransform;
|
||||
|
||||
use crate::internal::{AmountPerBlock, DerivedResolutions};
|
||||
use crate::internal::{ValuePerBlock, DerivedResolutions};
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct LazyAmountDerivedResolutions {
|
||||
pub struct LazyValueDerivedResolutions {
|
||||
pub btc: DerivedResolutions<Bitcoin, Sats>,
|
||||
pub sats: DerivedResolutions<Sats, Sats>,
|
||||
pub usd: DerivedResolutions<Dollars, Dollars>,
|
||||
pub cents: DerivedResolutions<Cents, Cents>,
|
||||
}
|
||||
|
||||
impl LazyAmountDerivedResolutions {
|
||||
impl LazyValueDerivedResolutions {
|
||||
pub(crate) fn from_block_source<
|
||||
SatsTransform,
|
||||
BitcoinTransform,
|
||||
@@ -20,7 +20,7 @@ impl LazyAmountDerivedResolutions {
|
||||
DollarsTransform,
|
||||
>(
|
||||
name: &str,
|
||||
source: &AmountPerBlock,
|
||||
source: &ValuePerBlock,
|
||||
version: Version,
|
||||
) -> Self
|
||||
where
|
||||
+5
-5
@@ -7,7 +7,7 @@ use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode};
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
AmountPerBlock, DistributionStats, WindowStarts, Windows,
|
||||
ValuePerBlock, DistributionStats, WindowStarts, Windows,
|
||||
algo::compute_rolling_distribution_from_starts,
|
||||
},
|
||||
};
|
||||
@@ -18,11 +18,11 @@ use crate::{
|
||||
/// Series: `{name}_average_24h`, `{name}_max_24h`, etc.
|
||||
#[derive(Deref, DerefMut, Traversable)]
|
||||
#[traversable(transparent)]
|
||||
pub struct RollingDistributionAmountPerBlock<M: StorageMode = Rw>(
|
||||
pub DistributionStats<Windows<AmountPerBlock<M>>>,
|
||||
pub struct RollingDistributionValuePerBlock<M: StorageMode = Rw>(
|
||||
pub DistributionStats<Windows<ValuePerBlock<M>>>,
|
||||
);
|
||||
|
||||
impl RollingDistributionAmountPerBlock {
|
||||
impl RollingDistributionValuePerBlock {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
@@ -31,7 +31,7 @@ impl RollingDistributionAmountPerBlock {
|
||||
) -> Result<Self> {
|
||||
Ok(Self(DistributionStats::try_from_fn(|stat_suffix| {
|
||||
Windows::try_from_fn(|window_suffix| {
|
||||
AmountPerBlock::forced_import(
|
||||
ValuePerBlock::forced_import(
|
||||
db,
|
||||
&format!("{name}_{stat_suffix}_{window_suffix}"),
|
||||
version,
|
||||
+7
-7
@@ -6,19 +6,19 @@ use vecdb::{Database, Rw, StorageMode};
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{AmountPerBlock, LazyRollingDeltasFromHeight, WindowStartVec, Windows},
|
||||
internal::{LazyRollingDeltasAmountFromHeight, ValuePerBlock, WindowStartVec, Windows},
|
||||
};
|
||||
|
||||
#[derive(Deref, DerefMut, Traversable)]
|
||||
pub struct AmountPerBlockWithDeltas<M: StorageMode = Rw> {
|
||||
pub struct ValuePerBlockWithDeltas<M: StorageMode = Rw> {
|
||||
#[deref]
|
||||
#[deref_mut]
|
||||
#[traversable(flatten)]
|
||||
pub inner: AmountPerBlock<M>,
|
||||
pub delta: LazyRollingDeltasFromHeight<Sats, SatsSigned, BasisPointsSigned32>,
|
||||
pub inner: ValuePerBlock<M>,
|
||||
pub delta: LazyRollingDeltasAmountFromHeight<Sats, SatsSigned, BasisPointsSigned32>,
|
||||
}
|
||||
|
||||
impl AmountPerBlockWithDeltas {
|
||||
impl ValuePerBlockWithDeltas {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
@@ -26,9 +26,9 @@ impl AmountPerBlockWithDeltas {
|
||||
indexes: &indexes::Vecs,
|
||||
cached_starts: &Windows<&WindowStartVec>,
|
||||
) -> Result<Self> {
|
||||
let inner = AmountPerBlock::forced_import(db, name, version, indexes)?;
|
||||
let inner = ValuePerBlock::forced_import(db, name, version, indexes)?;
|
||||
|
||||
let delta = LazyRollingDeltasFromHeight::new(
|
||||
let delta = LazyRollingDeltasAmountFromHeight::new(
|
||||
&format!("{name}_delta"),
|
||||
version + Version::ONE,
|
||||
&inner.sats.height,
|
||||
@@ -17,7 +17,7 @@ pub use bps::{
|
||||
pub use currency::{
|
||||
AvgCentsToUsd, AvgSatsToBtc, CentsSignedToDollars, CentsSubtractToCentsSigned,
|
||||
CentsTimesTenths, CentsUnsignedToDollars, CentsUnsignedToSats, DollarsToSatsFract,
|
||||
NegCentsUnsignedToDollars, SatsToBitcoin, SatsToCents,
|
||||
NegCentsUnsignedToDollars, SatsSignedToBitcoin, SatsToBitcoin, SatsToCents,
|
||||
};
|
||||
pub use derived::{
|
||||
Days1, Days7, Days30, Days365, DaysToYears, PriceTimesRatioBp32Cents, PriceTimesRatioCents,
|
||||
|
||||
+4
-4
@@ -2,20 +2,20 @@ use brk_traversable::Traversable;
|
||||
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
|
||||
use vecdb::{LazyVecFrom1, ReadableCloneableVec, UnaryTransform, VecIndex};
|
||||
|
||||
use crate::internal::AmountPerBlock;
|
||||
use crate::internal::ValuePerBlock;
|
||||
|
||||
/// Fully lazy value type at height level.
|
||||
///
|
||||
/// All fields are lazy transforms from existing sources - no storage.
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct LazyAmount<I: VecIndex> {
|
||||
pub struct LazyValue<I: VecIndex> {
|
||||
pub btc: LazyVecFrom1<I, Bitcoin, I, Sats>,
|
||||
pub sats: LazyVecFrom1<I, Sats, I, Sats>,
|
||||
pub usd: LazyVecFrom1<I, Dollars, I, Dollars>,
|
||||
pub cents: LazyVecFrom1<I, Cents, I, Cents>,
|
||||
}
|
||||
|
||||
impl LazyAmount<Height> {
|
||||
impl LazyValue<Height> {
|
||||
pub(crate) fn from_block_source<
|
||||
SatsTransform,
|
||||
BitcoinTransform,
|
||||
@@ -23,7 +23,7 @@ impl LazyAmount<Height> {
|
||||
DollarsTransform,
|
||||
>(
|
||||
name: &str,
|
||||
source: &AmountPerBlock,
|
||||
source: &ValuePerBlock,
|
||||
version: Version,
|
||||
) -> Self
|
||||
where
|
||||
@@ -13,7 +13,7 @@ use vecdb::{AnyStoredVec, AnyVec, Database, EagerVec, Exit, PcoVec, WritableVec}
|
||||
use crate::{indexes, prices};
|
||||
|
||||
use super::{
|
||||
AmountPerBlock, BpsType, NumericValue, PerBlock, PerBlockCumulativeRolling, PercentPerBlock,
|
||||
ValuePerBlock, BpsType, NumericValue, PerBlock, PerBlockCumulativeRolling, PercentPerBlock,
|
||||
WindowStartVec, Windows,
|
||||
};
|
||||
|
||||
@@ -176,16 +176,16 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl WithAddrTypes<AmountPerBlock> {
|
||||
impl WithAddrTypes<ValuePerBlock> {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
let all = AmountPerBlock::forced_import(db, name, version, indexes)?;
|
||||
let all = ValuePerBlock::forced_import(db, name, version, indexes)?;
|
||||
let by_addr_type = ByAddrType::new_with_name(|type_name| {
|
||||
AmountPerBlock::forced_import(db, &format!("{type_name}_{name}"), version, indexes)
|
||||
ValuePerBlock::forced_import(db, &format!("{type_name}_{name}"), version, indexes)
|
||||
})?;
|
||||
Ok(Self { all, by_addr_type })
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use super::{ByDcaCagr, ByDcaClass, ByDcaPeriod, Vecs};
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
AmountPerBlock, PercentPerBlock, Price,
|
||||
ValuePerBlock, PercentPerBlock, Price,
|
||||
db_utils::{finalize_db, open_db},
|
||||
},
|
||||
};
|
||||
@@ -23,7 +23,7 @@ impl Vecs {
|
||||
let db = open_db(parent_path, super::DB_NAME, 50_000)?;
|
||||
let version = parent_version;
|
||||
let stack = ByDcaPeriod::try_new(|name, _days| {
|
||||
AmountPerBlock::forced_import(&db, &format!("dca_stack_{name}"), version, indexes)
|
||||
ValuePerBlock::forced_import(&db, &format!("dca_stack_{name}"), version, indexes)
|
||||
})?;
|
||||
|
||||
let cost_basis = ByDcaPeriod::try_new(|name, _days| {
|
||||
@@ -39,7 +39,7 @@ impl Vecs {
|
||||
})?;
|
||||
|
||||
let lump_sum_stack = ByDcaPeriod::try_new(|name, _days| {
|
||||
AmountPerBlock::forced_import(&db, &format!("lump_sum_stack_{name}"), version, indexes)
|
||||
ValuePerBlock::forced_import(&db, &format!("lump_sum_stack_{name}"), version, indexes)
|
||||
})?;
|
||||
|
||||
let lump_sum_return = ByDcaPeriod::try_new(|name, _days| {
|
||||
@@ -52,7 +52,7 @@ impl Vecs {
|
||||
})?;
|
||||
|
||||
let class_stack = ByDcaClass::try_new(|name, _year, _day1| {
|
||||
AmountPerBlock::forced_import(&db, &format!("dca_stack_{name}"), version, indexes)
|
||||
ValuePerBlock::forced_import(&db, &format!("dca_stack_{name}"), version, indexes)
|
||||
})?;
|
||||
|
||||
let class_cost_basis = ByDcaClass::try_new(|name, _year, _day1| {
|
||||
|
||||
@@ -3,21 +3,21 @@ use brk_types::{BasisPointsSigned32, Cents, Height, Sats};
|
||||
use vecdb::{Database, EagerVec, PcoVec, Rw, StorageMode};
|
||||
|
||||
use super::{ByDcaCagr, ByDcaClass, ByDcaPeriod};
|
||||
use crate::internal::{AmountPerBlock, PerBlock, PercentPerBlock, Price};
|
||||
use crate::internal::{ValuePerBlock, PerBlock, PercentPerBlock, Price};
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct PeriodVecs<M: StorageMode = Rw> {
|
||||
pub dca_stack: ByDcaPeriod<AmountPerBlock<M>>,
|
||||
pub dca_stack: ByDcaPeriod<ValuePerBlock<M>>,
|
||||
pub dca_cost_basis: ByDcaPeriod<Price<PerBlock<Cents, M>>>,
|
||||
pub dca_return: ByDcaPeriod<PercentPerBlock<BasisPointsSigned32, M>>,
|
||||
pub dca_cagr: ByDcaCagr<PercentPerBlock<BasisPointsSigned32, M>>,
|
||||
pub lump_sum_stack: ByDcaPeriod<AmountPerBlock<M>>,
|
||||
pub lump_sum_stack: ByDcaPeriod<ValuePerBlock<M>>,
|
||||
pub lump_sum_return: ByDcaPeriod<PercentPerBlock<BasisPointsSigned32, M>>,
|
||||
}
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct ClassVecs<M: StorageMode = Rw> {
|
||||
pub dca_stack: ByDcaClass<AmountPerBlock<M>>,
|
||||
pub dca_stack: ByDcaClass<ValuePerBlock<M>>,
|
||||
pub dca_cost_basis: ByDcaClass<Price<PerBlock<Cents, M>>>,
|
||||
pub dca_return: ByDcaClass<PercentPerBlock<BasisPointsSigned32, M>>,
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use super::Vecs;
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
AmountPerBlockCumulative, AmountPerBlockCumulativeRolling, AmountPerBlockFull,
|
||||
ValuePerBlockCumulative, ValuePerBlockCumulativeRolling, ValuePerBlockFull,
|
||||
LazyPercentCumulativeRolling, OneMinusBp16, PercentCumulativeRolling, RatioRollingWindows,
|
||||
WindowStartVec, Windows,
|
||||
},
|
||||
@@ -29,23 +29,23 @@ impl Vecs {
|
||||
);
|
||||
|
||||
Ok(Self {
|
||||
coinbase: AmountPerBlockCumulativeRolling::forced_import(
|
||||
coinbase: ValuePerBlockCumulativeRolling::forced_import(
|
||||
db,
|
||||
"coinbase",
|
||||
version,
|
||||
indexes,
|
||||
cached_starts,
|
||||
)?,
|
||||
subsidy: AmountPerBlockCumulativeRolling::forced_import(
|
||||
subsidy: ValuePerBlockCumulativeRolling::forced_import(
|
||||
db,
|
||||
"subsidy",
|
||||
version,
|
||||
indexes,
|
||||
cached_starts,
|
||||
)?,
|
||||
fees: AmountPerBlockFull::forced_import(db, "fees", version, indexes, cached_starts)?,
|
||||
fees: ValuePerBlockFull::forced_import(db, "fees", version, indexes, cached_starts)?,
|
||||
output_volume: EagerVec::forced_import(db, "output_volume", version)?,
|
||||
unclaimed: AmountPerBlockCumulative::forced_import(
|
||||
unclaimed: ValuePerBlockCumulative::forced_import(
|
||||
db,
|
||||
"unclaimed_rewards",
|
||||
version,
|
||||
|
||||
@@ -3,17 +3,17 @@ use brk_types::{BasisPoints16, BasisPoints32, Height, Sats};
|
||||
use vecdb::{EagerVec, PcoVec, Rw, StorageMode};
|
||||
|
||||
use crate::internal::{
|
||||
AmountPerBlockCumulative, AmountPerBlockCumulativeRolling, AmountPerBlockFull,
|
||||
ValuePerBlockCumulative, ValuePerBlockCumulativeRolling, ValuePerBlockFull,
|
||||
LazyPercentCumulativeRolling, PercentCumulativeRolling, RatioRollingWindows,
|
||||
};
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub coinbase: AmountPerBlockCumulativeRolling<M>,
|
||||
pub subsidy: AmountPerBlockCumulativeRolling<M>,
|
||||
pub fees: AmountPerBlockFull<M>,
|
||||
pub coinbase: ValuePerBlockCumulativeRolling<M>,
|
||||
pub subsidy: ValuePerBlockCumulativeRolling<M>,
|
||||
pub fees: ValuePerBlockFull<M>,
|
||||
pub output_volume: M::Stored<EagerVec<PcoVec<Height, Sats>>>,
|
||||
pub unclaimed: AmountPerBlockCumulative<M>,
|
||||
pub unclaimed: ValuePerBlockCumulative<M>,
|
||||
#[traversable(wrap = "fees", rename = "dominance")]
|
||||
pub fee_dominance: PercentCumulativeRolling<BasisPoints16, M>,
|
||||
#[traversable(wrap = "subsidy", rename = "dominance")]
|
||||
|
||||
@@ -3,7 +3,7 @@ use brk_types::Version;
|
||||
use vecdb::Database;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{indexes, internal::AmountPerBlockCumulative};
|
||||
use crate::{indexes, internal::ValuePerBlockCumulative};
|
||||
|
||||
impl Vecs {
|
||||
pub(crate) fn forced_import(
|
||||
@@ -12,7 +12,7 @@ impl Vecs {
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
op_return: AmountPerBlockCumulative::forced_import(
|
||||
op_return: ValuePerBlockCumulative::forced_import(
|
||||
db,
|
||||
"op_return_value",
|
||||
version,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use brk_traversable::Traversable;
|
||||
use vecdb::{Rw, StorageMode};
|
||||
|
||||
use crate::internal::AmountPerBlockCumulative;
|
||||
use crate::internal::ValuePerBlockCumulative;
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub op_return: AmountPerBlockCumulative<M>,
|
||||
pub op_return: ValuePerBlockCumulative<M>,
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use vecdb::{BinaryTransform, Database, Exit, ReadableVec, Rw, StorageMode, Versi
|
||||
use crate::{
|
||||
blocks, indexes,
|
||||
internal::{
|
||||
AmountPerBlockCumulativeRolling, MaskSats, PercentRollingWindows, RatioU64Bp16,
|
||||
ValuePerBlockCumulativeRolling, MaskSats, PercentRollingWindows, RatioU64Bp16,
|
||||
WindowStartVec, Windows,
|
||||
},
|
||||
mining, prices,
|
||||
@@ -22,7 +22,7 @@ pub struct Vecs<M: StorageMode = Rw> {
|
||||
#[traversable(flatten)]
|
||||
pub base: minor::Vecs<M>,
|
||||
|
||||
pub rewards: AmountPerBlockCumulativeRolling<M>,
|
||||
pub rewards: ValuePerBlockCumulativeRolling<M>,
|
||||
#[traversable(rename = "dominance")]
|
||||
pub dominance_rolling: PercentRollingWindows<BasisPoints16, M>,
|
||||
}
|
||||
@@ -39,7 +39,7 @@ impl Vecs {
|
||||
|
||||
let base = minor::Vecs::forced_import(db, slug, version, indexes, cached_starts)?;
|
||||
|
||||
let rewards = AmountPerBlockCumulativeRolling::forced_import(
|
||||
let rewards = ValuePerBlockCumulativeRolling::forced_import(
|
||||
db,
|
||||
&suffix("rewards"),
|
||||
version,
|
||||
|
||||
@@ -3,7 +3,7 @@ use brk_types::Version;
|
||||
use vecdb::Database;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{indexes, internal::AmountPerBlockCumulative};
|
||||
use crate::{indexes, internal::ValuePerBlockCumulative};
|
||||
|
||||
impl Vecs {
|
||||
pub(crate) fn forced_import(
|
||||
@@ -12,7 +12,7 @@ impl Vecs {
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
total: AmountPerBlockCumulative::forced_import(
|
||||
total: ValuePerBlockCumulative::forced_import(
|
||||
db,
|
||||
"unspendable_supply",
|
||||
version,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use brk_traversable::Traversable;
|
||||
use vecdb::{Rw, StorageMode};
|
||||
|
||||
use crate::internal::AmountPerBlockCumulative;
|
||||
use crate::internal::ValuePerBlockCumulative;
|
||||
|
||||
#[derive(Traversable)]
|
||||
#[traversable(transparent)]
|
||||
pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub total: AmountPerBlockCumulative<M>,
|
||||
pub total: ValuePerBlockCumulative<M>,
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use brk_types::Version;
|
||||
use crate::{
|
||||
cointime, distribution, indexes,
|
||||
internal::{
|
||||
LazyAmountPerBlock, LazyFiatPerBlock, LazyRollingDeltasFiatFromHeight, PercentPerBlock,
|
||||
LazyValuePerBlock, LazyFiatPerBlock, LazyRollingDeltasFiatFromHeight, PercentPerBlock,
|
||||
RollingWindows, WindowStartVec, Windows,
|
||||
db_utils::{finalize_db, open_db},
|
||||
},
|
||||
@@ -32,7 +32,7 @@ impl Vecs {
|
||||
let supply_metrics = &distribution.utxo_cohorts.all.metrics.supply;
|
||||
|
||||
let circulating =
|
||||
LazyAmountPerBlock::identity("circulating_supply", &supply_metrics.total, version);
|
||||
LazyValuePerBlock::identity("circulating_supply", &supply_metrics.total, version);
|
||||
|
||||
let burned = burned::Vecs::forced_import(&db, version, indexes)?;
|
||||
|
||||
@@ -63,7 +63,7 @@ impl Vecs {
|
||||
indexes,
|
||||
)?;
|
||||
|
||||
let hodled_or_lost = LazyAmountPerBlock::identity(
|
||||
let hodled_or_lost = LazyValuePerBlock::identity(
|
||||
"hodled_or_lost_supply",
|
||||
&cointime.supply.vaulted,
|
||||
version,
|
||||
|
||||
@@ -4,7 +4,7 @@ use vecdb::{Database, Rw, StorageMode};
|
||||
|
||||
use super::{burned, velocity};
|
||||
use crate::internal::{
|
||||
LazyAmountPerBlock, LazyFiatPerBlock, LazyRollingDeltasFiatFromHeight, PercentPerBlock,
|
||||
LazyValuePerBlock, LazyFiatPerBlock, LazyRollingDeltasFiatFromHeight, PercentPerBlock,
|
||||
RollingWindows,
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ pub struct Vecs<M: StorageMode = Rw> {
|
||||
#[traversable(skip)]
|
||||
pub(crate) db: Database,
|
||||
|
||||
pub circulating: LazyAmountPerBlock,
|
||||
pub circulating: LazyValuePerBlock,
|
||||
pub burned: burned::Vecs<M>,
|
||||
pub inflation_rate: PercentPerBlock<BasisPointsSigned32, M>,
|
||||
pub velocity: velocity::Vecs<M>,
|
||||
@@ -21,5 +21,5 @@ pub struct Vecs<M: StorageMode = Rw> {
|
||||
#[traversable(wrap = "market_cap", rename = "delta")]
|
||||
pub market_cap_delta: LazyRollingDeltasFiatFromHeight<Cents, CentsSigned, BasisPointsSigned32>,
|
||||
pub market_minus_realized_cap_growth_rate: RollingWindows<BasisPointsSigned32, M>,
|
||||
pub hodled_or_lost: LazyAmountPerBlock,
|
||||
pub hodled_or_lost: LazyValuePerBlock,
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use vecdb::Database;
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{AmountPerBlockCumulativeRolling, PerBlock, WindowStartVec, Windows},
|
||||
internal::{ValuePerBlockCumulativeRolling, PerBlock, WindowStartVec, Windows},
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
@@ -17,7 +17,7 @@ impl Vecs {
|
||||
) -> Result<Self> {
|
||||
let v = version + Version::TWO;
|
||||
Ok(Self {
|
||||
transfer_volume: AmountPerBlockCumulativeRolling::forced_import(
|
||||
transfer_volume: ValuePerBlockCumulativeRolling::forced_import(
|
||||
db,
|
||||
"transfer_volume_bis",
|
||||
version,
|
||||
|
||||
@@ -2,10 +2,10 @@ use brk_traversable::Traversable;
|
||||
use brk_types::StoredF32;
|
||||
use vecdb::{Rw, StorageMode};
|
||||
|
||||
use crate::internal::{AmountPerBlockCumulativeRolling, PerBlock, Windows};
|
||||
use crate::internal::{ValuePerBlockCumulativeRolling, PerBlock, Windows};
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct Vecs<M: StorageMode = Rw> {
|
||||
pub transfer_volume: AmountPerBlockCumulativeRolling<M>,
|
||||
pub transfer_volume: ValuePerBlockCumulativeRolling<M>,
|
||||
pub tx_per_sec: Windows<PerBlock<StoredF32, M>>,
|
||||
}
|
||||
|
||||
+81
-20
@@ -2109,7 +2109,7 @@ function create_10y1m1w1y2y3m3y4y5y6m6y8yPattern3(client, acc) {
|
||||
* @property {BpsCentsPercentilesRatioSatsSmaStdUsdPattern} price
|
||||
* @property {BlockCumulativeSumPattern} profit
|
||||
* @property {_1m1w1y24hPattern<StoredF64>} profitToLossRatio
|
||||
* @property {_1m1w1y24hPattern7} sellSideRiskRatio
|
||||
* @property {_1m1w1y24hPattern8} sellSideRiskRatio
|
||||
* @property {AdjustedRatioValuePattern} sopr
|
||||
*/
|
||||
|
||||
@@ -2821,7 +2821,7 @@ function createCentsNegativeToUsdPattern2(client, acc) {
|
||||
|
||||
/**
|
||||
* @typedef {Object} DeltaDominanceHalfInTotalPattern2
|
||||
* @property {AbsoluteRatePattern} delta
|
||||
* @property {AbsoluteRatePattern3} delta
|
||||
* @property {BpsPercentRatioPattern2} dominance
|
||||
* @property {BtcCentsSatsUsdPattern} half
|
||||
* @property {BtcCentsSatsShareUsdPattern} inLoss
|
||||
@@ -2837,7 +2837,7 @@ function createCentsNegativeToUsdPattern2(client, acc) {
|
||||
*/
|
||||
function createDeltaDominanceHalfInTotalPattern2(client, acc) {
|
||||
return {
|
||||
delta: createAbsoluteRatePattern(client, _m(acc, 'delta')),
|
||||
delta: createAbsoluteRatePattern3(client, _m(acc, 'delta')),
|
||||
dominance: createBpsPercentRatioPattern2(client, _m(acc, 'dominance')),
|
||||
half: createBtcCentsSatsUsdPattern(client, _m(acc, 'half')),
|
||||
inLoss: createBtcCentsSatsShareUsdPattern(client, _m(acc, 'in_loss')),
|
||||
@@ -2848,7 +2848,7 @@ function createDeltaDominanceHalfInTotalPattern2(client, acc) {
|
||||
|
||||
/**
|
||||
* @typedef {Object} DeltaDominanceHalfInTotalPattern
|
||||
* @property {AbsoluteRatePattern} delta
|
||||
* @property {AbsoluteRatePattern3} delta
|
||||
* @property {BpsPercentRatioPattern2} dominance
|
||||
* @property {BtcCentsSatsUsdPattern} half
|
||||
* @property {BtcCentsSatsUsdPattern} inLoss
|
||||
@@ -2864,7 +2864,7 @@ function createDeltaDominanceHalfInTotalPattern2(client, acc) {
|
||||
*/
|
||||
function createDeltaDominanceHalfInTotalPattern(client, acc) {
|
||||
return {
|
||||
delta: createAbsoluteRatePattern(client, _m(acc, 'delta')),
|
||||
delta: createAbsoluteRatePattern3(client, _m(acc, 'delta')),
|
||||
dominance: createBpsPercentRatioPattern2(client, _m(acc, 'dominance')),
|
||||
half: createBtcCentsSatsUsdPattern(client, _m(acc, 'half')),
|
||||
inLoss: createBtcCentsSatsUsdPattern(client, _m(acc, 'in_loss')),
|
||||
@@ -3052,7 +3052,7 @@ function createBpsCentsRatioSatsUsdPattern(client, acc) {
|
||||
* @typedef {Object} BtcCentsDeltaSatsUsdPattern
|
||||
* @property {SeriesPattern1<Bitcoin>} btc
|
||||
* @property {SeriesPattern1<Cents>} cents
|
||||
* @property {AbsoluteRatePattern} delta
|
||||
* @property {AbsoluteRatePattern3} delta
|
||||
* @property {SeriesPattern1<Sats>} sats
|
||||
* @property {SeriesPattern1<Dollars>} usd
|
||||
*/
|
||||
@@ -3067,7 +3067,7 @@ function createBtcCentsDeltaSatsUsdPattern(client, acc) {
|
||||
return {
|
||||
btc: createSeriesPattern1(client, acc),
|
||||
cents: createSeriesPattern1(client, _m(acc, 'cents')),
|
||||
delta: createAbsoluteRatePattern(client, _m(acc, 'delta')),
|
||||
delta: createAbsoluteRatePattern3(client, _m(acc, 'delta')),
|
||||
sats: createSeriesPattern1(client, _m(acc, 'sats')),
|
||||
usd: createSeriesPattern1(client, _m(acc, 'usd')),
|
||||
};
|
||||
@@ -3206,7 +3206,7 @@ function create_1m1w1y24hPattern2(client, acc) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} _1m1w1y24hPattern7
|
||||
* @typedef {Object} _1m1w1y24hPattern8
|
||||
* @property {BpsPercentRatioPattern4} _1m
|
||||
* @property {BpsPercentRatioPattern4} _1w
|
||||
* @property {BpsPercentRatioPattern4} _1y
|
||||
@@ -3214,12 +3214,12 @@ function create_1m1w1y24hPattern2(client, acc) {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a _1m1w1y24hPattern7 pattern node
|
||||
* Create a _1m1w1y24hPattern8 pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated series name
|
||||
* @returns {_1m1w1y24hPattern7}
|
||||
* @returns {_1m1w1y24hPattern8}
|
||||
*/
|
||||
function create_1m1w1y24hPattern7(client, acc) {
|
||||
function create_1m1w1y24hPattern8(client, acc) {
|
||||
return {
|
||||
_1m: createBpsPercentRatioPattern4(client, _m(acc, '1m')),
|
||||
_1w: createBpsPercentRatioPattern4(client, _m(acc, '1w')),
|
||||
@@ -3274,6 +3274,29 @@ function create_1m1w1y24hPattern3(client, acc) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} _1m1w1y24hPattern7
|
||||
* @property {BtcSatsPattern} _1m
|
||||
* @property {BtcSatsPattern} _1w
|
||||
* @property {BtcSatsPattern} _1y
|
||||
* @property {BtcSatsPattern} _24h
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a _1m1w1y24hPattern7 pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated series name
|
||||
* @returns {_1m1w1y24hPattern7}
|
||||
*/
|
||||
function create_1m1w1y24hPattern7(client, acc) {
|
||||
return {
|
||||
_1m: createBtcSatsPattern(client, _m(acc, '1m')),
|
||||
_1w: createBtcSatsPattern(client, _m(acc, '1w')),
|
||||
_1y: createBtcSatsPattern(client, _m(acc, '1y')),
|
||||
_24h: createBtcSatsPattern(client, _m(acc, '24h')),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} _1m1w1y2wPattern
|
||||
* @property {CentsSatsUsdPattern} _1m
|
||||
@@ -3953,7 +3976,7 @@ function createCumulativeRollingSumPattern(client, acc) {
|
||||
|
||||
/**
|
||||
* @typedef {Object} DeltaDominanceTotalPattern
|
||||
* @property {AbsoluteRatePattern} delta
|
||||
* @property {AbsoluteRatePattern3} delta
|
||||
* @property {BpsPercentRatioPattern2} dominance
|
||||
* @property {BtcCentsSatsUsdPattern} total
|
||||
*/
|
||||
@@ -3966,7 +3989,7 @@ function createCumulativeRollingSumPattern(client, acc) {
|
||||
*/
|
||||
function createDeltaDominanceTotalPattern(client, acc) {
|
||||
return {
|
||||
delta: createAbsoluteRatePattern(client, _m(acc, 'delta')),
|
||||
delta: createAbsoluteRatePattern3(client, _m(acc, 'delta')),
|
||||
dominance: createBpsPercentRatioPattern2(client, _m(acc, 'dominance')),
|
||||
total: createBtcCentsSatsUsdPattern(client, acc),
|
||||
};
|
||||
@@ -4139,6 +4162,25 @@ function createAbsoluteRatePattern2(client, acc) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} AbsoluteRatePattern3
|
||||
* @property {_1m1w1y24hPattern7} absolute
|
||||
* @property {_1m1w1y24hPattern2} rate
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a AbsoluteRatePattern3 pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated series name
|
||||
* @returns {AbsoluteRatePattern3}
|
||||
*/
|
||||
function createAbsoluteRatePattern3(client, acc) {
|
||||
return {
|
||||
absolute: create_1m1w1y24hPattern7(client, acc),
|
||||
rate: create_1m1w1y24hPattern2(client, acc),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} AddrUtxoPattern
|
||||
* @property {BtcCentsSatsUsdPattern} addr
|
||||
@@ -4311,6 +4353,25 @@ function createBpsRatioPattern(client, acc) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} BtcSatsPattern
|
||||
* @property {SeriesPattern1<Bitcoin>} btc
|
||||
* @property {SeriesPattern1<SatsSigned>} sats
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a BtcSatsPattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated series name
|
||||
* @returns {BtcSatsPattern}
|
||||
*/
|
||||
function createBtcSatsPattern(client, acc) {
|
||||
return {
|
||||
btc: createSeriesPattern1(client, acc),
|
||||
sats: createSeriesPattern1(client, _m(acc, 'sats')),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} CentsUsdPattern3
|
||||
* @property {SeriesPattern1<Cents>} cents
|
||||
@@ -6259,7 +6320,7 @@ function createTransferPattern(client, acc) {
|
||||
* @property {BlockChangeCumulativeDeltaSumPattern} netPnl
|
||||
* @property {SeriesTree_Cohorts_Utxo_All_Realized_Sopr} sopr
|
||||
* @property {BlockCumulativeSumPattern} grossPnl
|
||||
* @property {_1m1w1y24hPattern7} sellSideRiskRatio
|
||||
* @property {_1m1w1y24hPattern8} sellSideRiskRatio
|
||||
* @property {BlockCumulativeSumPattern} peakRegret
|
||||
* @property {PricePattern} capitalized
|
||||
* @property {_1m1w1y24hPattern<StoredF64>} profitToLossRatio
|
||||
@@ -6451,7 +6512,7 @@ function createTransferPattern(client, acc) {
|
||||
* @property {BlockChangeCumulativeDeltaSumPattern} netPnl
|
||||
* @property {AdjustedRatioValuePattern} sopr
|
||||
* @property {BlockCumulativeSumPattern} grossPnl
|
||||
* @property {_1m1w1y24hPattern7} sellSideRiskRatio
|
||||
* @property {_1m1w1y24hPattern8} sellSideRiskRatio
|
||||
* @property {BlockCumulativeSumPattern} peakRegret
|
||||
* @property {PricePattern} capitalized
|
||||
* @property {_1m1w1y24hPattern<StoredF64>} profitToLossRatio
|
||||
@@ -6574,7 +6635,7 @@ function createTransferPattern(client, acc) {
|
||||
* @property {BlockChangeCumulativeDeltaSumPattern} netPnl
|
||||
* @property {SeriesTree_Cohorts_Utxo_Lth_Realized_Sopr} sopr
|
||||
* @property {BlockCumulativeSumPattern} grossPnl
|
||||
* @property {_1m1w1y24hPattern7} sellSideRiskRatio
|
||||
* @property {_1m1w1y24hPattern8} sellSideRiskRatio
|
||||
* @property {BlockCumulativeSumPattern} peakRegret
|
||||
* @property {PricePattern} capitalized
|
||||
* @property {_1m1w1y24hPattern<StoredF64>} profitToLossRatio
|
||||
@@ -7007,7 +7068,7 @@ function createTransferPattern(client, acc) {
|
||||
* @extends BrkClientBase
|
||||
*/
|
||||
class BrkClient extends BrkClientBase {
|
||||
VERSION = "v0.3.0-beta.2";
|
||||
VERSION = "v0.3.0-beta.3";
|
||||
|
||||
INDEXES = /** @type {const} */ ([
|
||||
"minute10",
|
||||
@@ -9409,7 +9470,7 @@ class BrkClient extends BrkClientBase {
|
||||
},
|
||||
},
|
||||
grossPnl: createBlockCumulativeSumPattern(this, 'realized_gross_pnl'),
|
||||
sellSideRiskRatio: create_1m1w1y24hPattern7(this, 'sell_side_risk_ratio'),
|
||||
sellSideRiskRatio: create_1m1w1y24hPattern8(this, 'sell_side_risk_ratio'),
|
||||
peakRegret: createBlockCumulativeSumPattern(this, 'realized_peak_regret'),
|
||||
capitalized: createPricePattern(this, 'capitalized_price'),
|
||||
profitToLossRatio: create_1m1w1y24hPattern(this, 'realized_profit_to_loss_ratio'),
|
||||
@@ -9546,7 +9607,7 @@ class BrkClient extends BrkClientBase {
|
||||
netPnl: createBlockChangeCumulativeDeltaSumPattern(this, 'sth_net'),
|
||||
sopr: createAdjustedRatioValuePattern(this, 'sth'),
|
||||
grossPnl: createBlockCumulativeSumPattern(this, 'sth_realized_gross_pnl'),
|
||||
sellSideRiskRatio: create_1m1w1y24hPattern7(this, 'sth_sell_side_risk_ratio'),
|
||||
sellSideRiskRatio: create_1m1w1y24hPattern8(this, 'sth_sell_side_risk_ratio'),
|
||||
peakRegret: createBlockCumulativeSumPattern(this, 'sth_realized_peak_regret'),
|
||||
capitalized: createPricePattern(this, 'sth_capitalized_price'),
|
||||
profitToLossRatio: create_1m1w1y24hPattern(this, 'sth_realized_profit_to_loss_ratio'),
|
||||
@@ -9649,7 +9710,7 @@ class BrkClient extends BrkClientBase {
|
||||
ratio: create_1m1w1y24hPattern(this, 'lth_sopr'),
|
||||
},
|
||||
grossPnl: createBlockCumulativeSumPattern(this, 'lth_realized_gross_pnl'),
|
||||
sellSideRiskRatio: create_1m1w1y24hPattern7(this, 'lth_sell_side_risk_ratio'),
|
||||
sellSideRiskRatio: create_1m1w1y24hPattern8(this, 'lth_sell_side_risk_ratio'),
|
||||
peakRegret: createBlockCumulativeSumPattern(this, 'lth_realized_peak_regret'),
|
||||
capitalized: createPricePattern(this, 'lth_capitalized_price'),
|
||||
profitToLossRatio: create_1m1w1y24hPattern(this, 'lth_realized_profit_to_loss_ratio'),
|
||||
|
||||
@@ -40,5 +40,5 @@
|
||||
"url": "git+https://github.com/bitcoinresearchkit/brk.git"
|
||||
},
|
||||
"type": "module",
|
||||
"version": "0.3.0-beta.2"
|
||||
"version": "0.3.0-beta.3"
|
||||
}
|
||||
|
||||
@@ -2974,7 +2974,7 @@ class DeltaDominanceHalfInTotalPattern2:
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated series name."""
|
||||
self.delta: AbsoluteRatePattern = AbsoluteRatePattern(client, _m(acc, 'delta'))
|
||||
self.delta: AbsoluteRatePattern3 = AbsoluteRatePattern3(client, _m(acc, 'delta'))
|
||||
self.dominance: BpsPercentRatioPattern2 = BpsPercentRatioPattern2(client, _m(acc, 'dominance'))
|
||||
self.half: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'half'))
|
||||
self.in_loss: BtcCentsSatsShareUsdPattern = BtcCentsSatsShareUsdPattern(client, _m(acc, 'in_loss'))
|
||||
@@ -2986,7 +2986,7 @@ class DeltaDominanceHalfInTotalPattern:
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated series name."""
|
||||
self.delta: AbsoluteRatePattern = AbsoluteRatePattern(client, _m(acc, 'delta'))
|
||||
self.delta: AbsoluteRatePattern3 = AbsoluteRatePattern3(client, _m(acc, 'delta'))
|
||||
self.dominance: BpsPercentRatioPattern2 = BpsPercentRatioPattern2(client, _m(acc, 'dominance'))
|
||||
self.half: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'half'))
|
||||
self.in_loss: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'in_loss'))
|
||||
@@ -3077,7 +3077,7 @@ class BtcCentsDeltaSatsUsdPattern:
|
||||
"""Create pattern node with accumulated series name."""
|
||||
self.btc: SeriesPattern1[Bitcoin] = SeriesPattern1(client, acc)
|
||||
self.cents: SeriesPattern1[Cents] = SeriesPattern1(client, _m(acc, 'cents'))
|
||||
self.delta: AbsoluteRatePattern = AbsoluteRatePattern(client, _m(acc, 'delta'))
|
||||
self.delta: AbsoluteRatePattern3 = AbsoluteRatePattern3(client, _m(acc, 'delta'))
|
||||
self.sats: SeriesPattern1[Sats] = SeriesPattern1(client, _m(acc, 'sats'))
|
||||
self.usd: SeriesPattern1[Dollars] = SeriesPattern1(client, _m(acc, 'usd'))
|
||||
|
||||
@@ -3139,7 +3139,7 @@ class _1m1w1y24hPattern2:
|
||||
self._1y: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, '1y_rate'))
|
||||
self._24h: BpsPercentRatioPattern = BpsPercentRatioPattern(client, _m(acc, '24h_rate'))
|
||||
|
||||
class _1m1w1y24hPattern7:
|
||||
class _1m1w1y24hPattern8:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
@@ -3169,6 +3169,16 @@ class _1m1w1y24hPattern3:
|
||||
self._1y: BtcCentsSatsUsdPattern2 = BtcCentsSatsUsdPattern2(client, _m(acc, '1y'))
|
||||
self._24h: BtcCentsSatsUsdPattern2 = BtcCentsSatsUsdPattern2(client, _m(acc, '24h'))
|
||||
|
||||
class _1m1w1y24hPattern7:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated series name."""
|
||||
self._1m: BtcSatsPattern = BtcSatsPattern(client, _m(acc, '1m'))
|
||||
self._1w: BtcSatsPattern = BtcSatsPattern(client, _m(acc, '1w'))
|
||||
self._1y: BtcSatsPattern = BtcSatsPattern(client, _m(acc, '1y'))
|
||||
self._24h: BtcSatsPattern = BtcSatsPattern(client, _m(acc, '24h'))
|
||||
|
||||
class _1m1w1y2wPattern:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
@@ -3465,7 +3475,7 @@ class DeltaDominanceTotalPattern:
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated series name."""
|
||||
self.delta: AbsoluteRatePattern = AbsoluteRatePattern(client, _m(acc, 'delta'))
|
||||
self.delta: AbsoluteRatePattern3 = AbsoluteRatePattern3(client, _m(acc, 'delta'))
|
||||
self.dominance: BpsPercentRatioPattern2 = BpsPercentRatioPattern2(client, _m(acc, 'dominance'))
|
||||
self.total: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, acc)
|
||||
|
||||
@@ -3539,6 +3549,14 @@ class AbsoluteRatePattern2:
|
||||
self.absolute: _1m1w1y24hPattern5 = _1m1w1y24hPattern5(client, acc)
|
||||
self.rate: _1m1w1y24hPattern2 = _1m1w1y24hPattern2(client, acc)
|
||||
|
||||
class AbsoluteRatePattern3:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated series name."""
|
||||
self.absolute: _1m1w1y24hPattern7 = _1m1w1y24hPattern7(client, acc)
|
||||
self.rate: _1m1w1y24hPattern2 = _1m1w1y24hPattern2(client, acc)
|
||||
|
||||
class AddrUtxoPattern:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
@@ -3611,6 +3629,14 @@ class BpsRatioPattern:
|
||||
self.bps: SeriesPattern1[BasisPointsSigned32] = SeriesPattern1(client, _m(acc, 'bps'))
|
||||
self.ratio: SeriesPattern1[StoredF32] = SeriesPattern1(client, acc)
|
||||
|
||||
class BtcSatsPattern:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated series name."""
|
||||
self.btc: SeriesPattern1[Bitcoin] = SeriesPattern1(client, acc)
|
||||
self.sats: SeriesPattern1[SatsSigned] = SeriesPattern1(client, _m(acc, 'sats'))
|
||||
|
||||
class CentsUsdPattern3:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
@@ -5593,7 +5619,7 @@ class SeriesTree_Cohorts_Utxo_All_Realized:
|
||||
self.net_pnl: BlockChangeCumulativeDeltaSumPattern = BlockChangeCumulativeDeltaSumPattern(client, 'net')
|
||||
self.sopr: SeriesTree_Cohorts_Utxo_All_Realized_Sopr = SeriesTree_Cohorts_Utxo_All_Realized_Sopr(client)
|
||||
self.gross_pnl: BlockCumulativeSumPattern = BlockCumulativeSumPattern(client, 'realized_gross_pnl')
|
||||
self.sell_side_risk_ratio: _1m1w1y24hPattern7 = _1m1w1y24hPattern7(client, 'sell_side_risk_ratio')
|
||||
self.sell_side_risk_ratio: _1m1w1y24hPattern8 = _1m1w1y24hPattern8(client, 'sell_side_risk_ratio')
|
||||
self.peak_regret: BlockCumulativeSumPattern = BlockCumulativeSumPattern(client, 'realized_peak_regret')
|
||||
self.capitalized: PricePattern = PricePattern(client, 'capitalized_price')
|
||||
self.profit_to_loss_ratio: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, 'realized_profit_to_loss_ratio')
|
||||
@@ -5785,7 +5811,7 @@ class SeriesTree_Cohorts_Utxo_Sth_Realized:
|
||||
self.net_pnl: BlockChangeCumulativeDeltaSumPattern = BlockChangeCumulativeDeltaSumPattern(client, 'sth_net')
|
||||
self.sopr: AdjustedRatioValuePattern = AdjustedRatioValuePattern(client, 'sth')
|
||||
self.gross_pnl: BlockCumulativeSumPattern = BlockCumulativeSumPattern(client, 'sth_realized_gross_pnl')
|
||||
self.sell_side_risk_ratio: _1m1w1y24hPattern7 = _1m1w1y24hPattern7(client, 'sth_sell_side_risk_ratio')
|
||||
self.sell_side_risk_ratio: _1m1w1y24hPattern8 = _1m1w1y24hPattern8(client, 'sth_sell_side_risk_ratio')
|
||||
self.peak_regret: BlockCumulativeSumPattern = BlockCumulativeSumPattern(client, 'sth_realized_peak_regret')
|
||||
self.capitalized: PricePattern = PricePattern(client, 'sth_capitalized_price')
|
||||
self.profit_to_loss_ratio: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, 'sth_realized_profit_to_loss_ratio')
|
||||
@@ -5923,7 +5949,7 @@ class SeriesTree_Cohorts_Utxo_Lth_Realized:
|
||||
self.net_pnl: BlockChangeCumulativeDeltaSumPattern = BlockChangeCumulativeDeltaSumPattern(client, 'lth_net')
|
||||
self.sopr: SeriesTree_Cohorts_Utxo_Lth_Realized_Sopr = SeriesTree_Cohorts_Utxo_Lth_Realized_Sopr(client)
|
||||
self.gross_pnl: BlockCumulativeSumPattern = BlockCumulativeSumPattern(client, 'lth_realized_gross_pnl')
|
||||
self.sell_side_risk_ratio: _1m1w1y24hPattern7 = _1m1w1y24hPattern7(client, 'lth_sell_side_risk_ratio')
|
||||
self.sell_side_risk_ratio: _1m1w1y24hPattern8 = _1m1w1y24hPattern8(client, 'lth_sell_side_risk_ratio')
|
||||
self.peak_regret: BlockCumulativeSumPattern = BlockCumulativeSumPattern(client, 'lth_realized_peak_regret')
|
||||
self.capitalized: PricePattern = PricePattern(client, 'lth_capitalized_price')
|
||||
self.profit_to_loss_ratio: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, 'lth_realized_profit_to_loss_ratio')
|
||||
@@ -6329,7 +6355,7 @@ class SeriesTree:
|
||||
class BrkClient(BrkClientBase):
|
||||
"""Main BRK client with series tree and API methods."""
|
||||
|
||||
VERSION = "v0.3.0-beta.2"
|
||||
VERSION = "v0.3.0-beta.3"
|
||||
|
||||
INDEXES = [
|
||||
"minute10",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "brk-client"
|
||||
version = "0.3.0-beta.2"
|
||||
version = "0.3.0-beta.3"
|
||||
description = "Bitcoin on-chain analytics client — thousands of metrics, block explorer, and address index"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.9"
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
*/
|
||||
/**
|
||||
* Sell side risk rolling windows pattern
|
||||
* @typedef {Brk._1m1w1y24hPattern7} SellSideRiskPattern
|
||||
* @typedef {Brk._1m1w1y24hPattern8} SellSideRiskPattern
|
||||
*/
|
||||
/**
|
||||
* Stats pattern: min, max, median, percentiles
|
||||
@@ -245,6 +245,8 @@
|
||||
* Delta patterns with absolute + rate rolling windows
|
||||
* @typedef {Brk.AbsoluteRatePattern} DeltaPattern
|
||||
* @typedef {Brk.AbsoluteRatePattern2} FiatDeltaPattern
|
||||
* @typedef {Brk.AbsoluteRatePattern3} AmountDeltaPattern
|
||||
* @typedef {Brk.BtcSatsPattern} AmountPattern
|
||||
*
|
||||
* Capitalized price percentiles (pct1/2/5/95/98/99)
|
||||
* @typedef {Brk.Pct0Pct1Pct2Pct5Pct95Pct98Pct99Pattern} CapitalizedPercentilesPattern
|
||||
|
||||
@@ -15,12 +15,14 @@ import {
|
||||
line,
|
||||
baseline,
|
||||
sumsTreeBaseline,
|
||||
amountSumsTreeBaseline,
|
||||
rollingPercentRatioTree,
|
||||
percentRatio,
|
||||
percentRatioBaseline,
|
||||
chartsFromCount,
|
||||
} from "../series.js";
|
||||
import {
|
||||
amountBaseline,
|
||||
satsBtcUsd,
|
||||
flatMapCohorts,
|
||||
mapCohortsWithAll,
|
||||
@@ -160,6 +162,79 @@ function groupedDeltaItems(list, all, getDelta, unit, title, name) {
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Amount-valued single-cohort delta: Change exposes sats + lazy btc per window.
|
||||
* @param {AmountDeltaPattern} delta
|
||||
* @param {(name: string) => string} title
|
||||
* @param {string} name
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function singleAmountDeltaItems(delta, title, name) {
|
||||
return [
|
||||
{
|
||||
...amountSumsTreeBaseline({
|
||||
windows: delta.absolute,
|
||||
title,
|
||||
metric: `${name} Change`,
|
||||
legend: "Change",
|
||||
}),
|
||||
name: "Change",
|
||||
},
|
||||
{
|
||||
...rollingPercentRatioTree({
|
||||
windows: delta.rate,
|
||||
title,
|
||||
metric: `${name} Growth Rate`,
|
||||
}),
|
||||
name: "Growth Rate",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Amount-valued grouped-cohort delta: Change exposes sats + lazy btc per window.
|
||||
* @template {{ name: string, color: Color }} T
|
||||
* @template {{ name: string, color: Color }} A
|
||||
* @param {readonly T[]} list
|
||||
* @param {A} all
|
||||
* @param {(c: T | A) => AmountDeltaPattern} getDelta
|
||||
* @param {(name: string) => string} title
|
||||
* @param {string} name
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
function groupedAmountDeltaItems(list, all, getDelta, title, name) {
|
||||
return [
|
||||
{
|
||||
name: "Change",
|
||||
tree: ROLLING_WINDOWS.map((w) => ({
|
||||
name: w.name,
|
||||
title: title(`${w.title} ${name} Change`),
|
||||
bottom: flatMapCohortsWithAll(list, all, (c) =>
|
||||
amountBaseline({
|
||||
pattern: getDelta(c).absolute[w.key],
|
||||
name: c.name,
|
||||
color: c.color,
|
||||
}),
|
||||
),
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: "Growth Rate",
|
||||
tree: ROLLING_WINDOWS.map((w) => ({
|
||||
name: w.name,
|
||||
title: title(`${w.title} ${name} Growth Rate`),
|
||||
bottom: flatMapCohortsWithAll(list, all, (c) =>
|
||||
percentRatioBaseline({
|
||||
pattern: getDelta(c).rate[w.key],
|
||||
name: c.name,
|
||||
color: c.color,
|
||||
}),
|
||||
),
|
||||
})),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Single Cohort Composable Builders
|
||||
// ============================================================================
|
||||
@@ -292,7 +367,7 @@ export function createHoldingsSection({ cohort, title }) {
|
||||
bottom: simpleSupplySeries(supply),
|
||||
},
|
||||
dominanceChart(supply, cohort.color, title),
|
||||
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
||||
...singleAmountDeltaItems(supply.delta, title, "Supply"),
|
||||
],
|
||||
},
|
||||
outputsFolder(cohort.tree.outputs, cohort.color, title),
|
||||
@@ -321,7 +396,7 @@ export function createHoldingsSectionAll({ cohort, title }) {
|
||||
profitabilityCompositionChart(supply, title),
|
||||
],
|
||||
},
|
||||
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
||||
...singleAmountDeltaItems(supply.delta, title, "Supply"),
|
||||
],
|
||||
},
|
||||
outputsFolder(cohort.tree.outputs, cohort.color, title),
|
||||
@@ -352,7 +427,7 @@ export function createHoldingsSectionWithRelative({ cohort, title }) {
|
||||
profitabilityCompositionChart(supply, title),
|
||||
],
|
||||
},
|
||||
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
||||
...singleAmountDeltaItems(supply.delta, title, "Supply"),
|
||||
],
|
||||
},
|
||||
outputsFolder(cohort.tree.outputs, cohort.color, title),
|
||||
@@ -379,7 +454,7 @@ export function createHoldingsSectionWithOwnSupply({ cohort, title }) {
|
||||
name: "Profitability",
|
||||
tree: [profitabilityAmountChart(supply, title)],
|
||||
},
|
||||
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
||||
...singleAmountDeltaItems(supply.delta, title, "Supply"),
|
||||
],
|
||||
},
|
||||
outputsFolder(cohort.tree.outputs, cohort.color, title),
|
||||
@@ -406,7 +481,7 @@ export function createHoldingsSectionWithProfitLoss({ cohort, title }) {
|
||||
name: "Profitability",
|
||||
tree: [profitabilityAmountChart(supply, title)],
|
||||
},
|
||||
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
||||
...singleAmountDeltaItems(supply.delta, title, "Supply"),
|
||||
],
|
||||
},
|
||||
outputsFolder(cohort.tree.outputs, cohort.color, title),
|
||||
@@ -433,7 +508,7 @@ export function createHoldingsSectionAddress({ cohort, title }) {
|
||||
name: "Profitability",
|
||||
tree: [profitabilityAmountChart(supply, title)],
|
||||
},
|
||||
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
||||
...singleAmountDeltaItems(supply.delta, title, "Supply"),
|
||||
],
|
||||
},
|
||||
outputsFolder(cohort.tree.outputs, cohort.color, title),
|
||||
@@ -457,7 +532,7 @@ export function createHoldingsSectionAddressAmount({ cohort, title }) {
|
||||
bottom: simpleSupplySeries(supply),
|
||||
},
|
||||
dominanceChart(supply, cohort.color, title),
|
||||
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
||||
...singleAmountDeltaItems(supply.delta, title, "Supply"),
|
||||
],
|
||||
},
|
||||
outputsFolder(cohort.tree.outputs, cohort.color, title),
|
||||
@@ -529,7 +604,7 @@ export function createGroupedHoldingsSectionAddress({ list, all, title }) {
|
||||
name: "Profitability",
|
||||
tree: groupedSupplyProfitLoss(list, all, title),
|
||||
},
|
||||
...groupedDeltaItems(list, all, (c) => c.tree.supply.delta, Unit.sats, title, "Supply"),
|
||||
...groupedAmountDeltaItems(list, all, (c) => c.tree.supply.delta, title, "Supply"),
|
||||
],
|
||||
},
|
||||
groupedOutputsFolder(list, all, title),
|
||||
@@ -580,7 +655,7 @@ export function createGroupedHoldingsSectionAddressAmount({ list, all, title })
|
||||
tree: [
|
||||
groupedSupplyTotal(list, all, title),
|
||||
groupedDominanceChart(list, title),
|
||||
...groupedDeltaItems(list, all, (c) => c.tree.supply.delta, Unit.sats, title, "Supply"),
|
||||
...groupedAmountDeltaItems(list, all, (c) => c.tree.supply.delta, title, "Supply"),
|
||||
],
|
||||
},
|
||||
groupedOutputsFolder(list, all, title),
|
||||
@@ -608,7 +683,7 @@ export function createGroupedHoldingsSection({ list, all, title }) {
|
||||
tree: [
|
||||
groupedSupplyTotal(list, all, title),
|
||||
groupedDominanceChart(list, title),
|
||||
...groupedDeltaItems(list, all, (c) => c.tree.supply.delta, Unit.sats, title, "Supply"),
|
||||
...groupedAmountDeltaItems(list, all, (c) => c.tree.supply.delta, title, "Supply"),
|
||||
],
|
||||
},
|
||||
groupedOutputsFolder(list, all, title),
|
||||
@@ -627,7 +702,7 @@ export function createGroupedHoldingsSectionWithProfitLoss({ list, all, title })
|
||||
name: "Profitability",
|
||||
tree: groupedSupplyProfitLoss(list, all, title),
|
||||
},
|
||||
...groupedDeltaItems(list, all, (c) => c.tree.supply.delta, Unit.sats, title, "Supply"),
|
||||
...groupedAmountDeltaItems(list, all, (c) => c.tree.supply.delta, title, "Supply"),
|
||||
],
|
||||
},
|
||||
groupedOutputsFolder(list, all, title),
|
||||
@@ -646,7 +721,7 @@ export function createGroupedHoldingsSectionWithOwnSupply({ list, all, title })
|
||||
name: "Profitability",
|
||||
tree: groupedSupplyProfitLoss(list, all, title),
|
||||
},
|
||||
...groupedDeltaItems(list, all, (c) => c.tree.supply.delta, Unit.sats, title, "Supply"),
|
||||
...groupedAmountDeltaItems(list, all, (c) => c.tree.supply.delta, title, "Supply"),
|
||||
],
|
||||
},
|
||||
groupedOutputsFolder(list, all, title),
|
||||
@@ -679,7 +754,7 @@ export function createGroupedHoldingsSectionWithRelative({ list, all, title }) {
|
||||
},
|
||||
],
|
||||
},
|
||||
...groupedDeltaItems(list, all, (c) => c.tree.supply.delta, Unit.sats, title, "Supply"),
|
||||
...groupedAmountDeltaItems(list, all, (c) => c.tree.supply.delta, title, "Supply"),
|
||||
],
|
||||
},
|
||||
groupedOutputsFolder(list, all, title),
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
import {
|
||||
formatCohortTitle,
|
||||
amountBaseline,
|
||||
satsBtcUsd,
|
||||
satsBtcUsdFullTree,
|
||||
avgHoldingsSubtree,
|
||||
@@ -21,9 +22,8 @@ import {
|
||||
import {
|
||||
ROLLING_WINDOWS,
|
||||
line,
|
||||
baseline,
|
||||
percentRatio,
|
||||
sumsTreeBaseline,
|
||||
amountSumsTreeBaseline,
|
||||
rollingPercentRatioTree,
|
||||
} from "../series.js";
|
||||
import { Unit } from "../../utils/units.js";
|
||||
@@ -528,11 +528,10 @@ function singleBucketFolder({ name, color, pattern }, parentName) {
|
||||
],
|
||||
},
|
||||
{
|
||||
...sumsTreeBaseline({
|
||||
...amountSumsTreeBaseline({
|
||||
windows: pattern.supply.all.delta.absolute,
|
||||
title,
|
||||
metric: "Supply Change",
|
||||
unit: Unit.sats,
|
||||
legend: "Change",
|
||||
}),
|
||||
name: "Change",
|
||||
@@ -622,12 +621,11 @@ function groupedBucketCharts(list, groupTitle) {
|
||||
tree: ROLLING_WINDOWS.map((w) => ({
|
||||
name: w.name,
|
||||
title: title(`${w.title} Supply Change`),
|
||||
bottom: list.map(({ name, color, pattern }) =>
|
||||
baseline({
|
||||
series: pattern.supply.all.delta.absolute[w.key],
|
||||
bottom: list.flatMap(({ name, color, pattern }) =>
|
||||
amountBaseline({
|
||||
pattern: pattern.supply.all.delta.absolute[w.key],
|
||||
name,
|
||||
color,
|
||||
unit: Unit.sats,
|
||||
}),
|
||||
),
|
||||
})),
|
||||
|
||||
@@ -629,6 +629,39 @@ export function sumsTreeBaseline({ windows, title = (s) => s, metric, unit, lege
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Rolling tree with baseline series for an amount pattern (sats + lazy btc per window).
|
||||
* @param {Object} args
|
||||
* @param {{ _24h: AmountPattern, _1w: AmountPattern, _1m: AmountPattern, _1y: AmountPattern }} args.windows
|
||||
* @param {(metric: string) => string} [args.title]
|
||||
* @param {string} args.metric
|
||||
* @param {string} [args.legend]
|
||||
* @returns {PartialOptionsGroup}
|
||||
*/
|
||||
export function amountSumsTreeBaseline({ windows, title = (s) => s, metric, legend = "Sum" }) {
|
||||
return {
|
||||
name: "Sums",
|
||||
tree: [
|
||||
{
|
||||
name: "Compare",
|
||||
title: title(metric),
|
||||
bottom: ROLLING_WINDOWS.flatMap((w) => [
|
||||
baseline({ series: windows[w.key].btc, name: w.name, color: w.color, unit: Unit.btc }),
|
||||
baseline({ series: windows[w.key].sats, name: w.name, color: w.color, unit: Unit.sats }),
|
||||
]),
|
||||
},
|
||||
...ROLLING_WINDOWS.map((w) => ({
|
||||
name: w.name,
|
||||
title: title(`${w.title} ${metric}`),
|
||||
bottom: [
|
||||
baseline({ series: windows[w.key].btc, name: legend, unit: Unit.btc }),
|
||||
baseline({ series: windows[w.key].sats, name: legend, unit: Unit.sats }),
|
||||
],
|
||||
})),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Flat array of per-window average charts
|
||||
* @param {Object} args
|
||||
|
||||
@@ -86,6 +86,65 @@ export function flatMapCohortsWithAll(list, all, fn) {
|
||||
export const formatCohortTitle = (cohortTitle) => (name) =>
|
||||
cohortTitle ? `${name}: ${cohortTitle}` : name;
|
||||
|
||||
/**
|
||||
* Create line series from an amount pattern (sats stored + lazy btc).
|
||||
* @param {Object} args
|
||||
* @param {AmountPattern} args.pattern
|
||||
* @param {string} args.name
|
||||
* @param {Color} [args.color]
|
||||
* @param {boolean} [args.defaultActive]
|
||||
* @param {number} [args.style]
|
||||
* @returns {FetchedLineSeriesBlueprint[]}
|
||||
*/
|
||||
export function amount({ pattern, name, color, defaultActive, style }) {
|
||||
return [
|
||||
line({
|
||||
series: pattern.btc,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.btc,
|
||||
defaultActive,
|
||||
style,
|
||||
}),
|
||||
line({
|
||||
series: pattern.sats,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.sats,
|
||||
defaultActive,
|
||||
style,
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create baseline series from an amount pattern (sats stored + lazy btc).
|
||||
* @param {Object} args
|
||||
* @param {AmountPattern} args.pattern
|
||||
* @param {string} args.name
|
||||
* @param {Color} [args.color]
|
||||
* @param {boolean} [args.defaultActive]
|
||||
* @returns {FetchedBaselineSeriesBlueprint[]}
|
||||
*/
|
||||
export function amountBaseline({ pattern, name, color, defaultActive }) {
|
||||
return [
|
||||
baseline({
|
||||
series: pattern.btc,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.btc,
|
||||
defaultActive,
|
||||
}),
|
||||
baseline({
|
||||
series: pattern.sats,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.sats,
|
||||
defaultActive,
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create sats/btc/usd line series from a pattern with .sats/.btc/.usd
|
||||
* @param {Object} args
|
||||
|
||||
Reference in New Issue
Block a user