mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-23 22:29:59 -07:00
global: snap
This commit is contained in:
8
Cargo.lock
generated
8
Cargo.lock
generated
@@ -2453,9 +2453,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.8.5"
|
version = "0.8.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha",
|
"rand_chacha",
|
||||||
@@ -3100,9 +3100,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.52.0"
|
version = "1.52.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a91135f59b1cbf38c91e73cf3386fca9bb77915c45ce2771460c9d92f0f3d776"
|
checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio",
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ serde_bytes = "0.11.19"
|
|||||||
serde_derive = "1.0.228"
|
serde_derive = "1.0.228"
|
||||||
serde_json = { version = "1.0.149", features = ["float_roundtrip", "preserve_order"] }
|
serde_json = { version = "1.0.149", features = ["float_roundtrip", "preserve_order"] }
|
||||||
smallvec = "1.15.1"
|
smallvec = "1.15.1"
|
||||||
tokio = { version = "1.52.0", features = ["rt-multi-thread"] }
|
tokio = { version = "1.52.1", features = ["rt-multi-thread"] }
|
||||||
tower-http = { version = "0.6.8", features = ["catch-panic", "compression-br", "compression-gzip", "compression-zstd", "cors", "normalize-path", "timeout", "trace"] }
|
tower-http = { version = "0.6.8", features = ["catch-panic", "compression-br", "compression-gzip", "compression-zstd", "cors", "normalize-path", "timeout", "trace"] }
|
||||||
tower-layer = "0.3"
|
tower-layer = "0.3"
|
||||||
tracing = { version = "0.1", default-features = false, features = ["std"] }
|
tracing = { version = "0.1", default-features = false, features = ["std"] }
|
||||||
|
|||||||
@@ -3,7 +3,10 @@
|
|||||||
//! This module detects repeating tree structures and analyzes them
|
//! This module detects repeating tree structures and analyzes them
|
||||||
//! using the bottom-up name deconstruction algorithm.
|
//! using the bottom-up name deconstruction algorithm.
|
||||||
|
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::{
|
||||||
|
cmp::Reverse,
|
||||||
|
collections::{BTreeMap, BTreeSet},
|
||||||
|
};
|
||||||
|
|
||||||
use brk_types::{TreeNode, extract_json_type};
|
use brk_types::{TreeNode, extract_json_type};
|
||||||
|
|
||||||
@@ -111,7 +114,7 @@ pub fn detect_structural_patterns(
|
|||||||
// Also collects node bases for each tree path
|
// Also collects node bases for each tree path
|
||||||
let node_bases = analyze_pattern_modes(tree, &mut patterns, &pattern_lookup);
|
let node_bases = analyze_pattern_modes(tree, &mut patterns, &pattern_lookup);
|
||||||
|
|
||||||
patterns.sort_by(|a, b| b.fields.len().cmp(&a.fields.len()));
|
patterns.sort_by_key(|p| Reverse(p.fields.len()));
|
||||||
(patterns, concrete_to_pattern, type_mappings, node_bases)
|
(patterns, concrete_to_pattern, type_mappings, node_bases)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ impl ClientConstants {
|
|||||||
|
|
||||||
let pools = pools();
|
let pools = pools();
|
||||||
let mut sorted_pools: Vec<_> = pools.iter().collect();
|
let mut sorted_pools: Vec<_> = pools.iter().collect();
|
||||||
sorted_pools.sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
|
sorted_pools.sort_by_key(|p| p.name.to_lowercase());
|
||||||
let pool_map: BTreeMap<PoolSlug, &'static str> =
|
let pool_map: BTreeMap<PoolSlug, &'static str> =
|
||||||
sorted_pools.iter().map(|p| (p.slug(), p.name)).collect();
|
sorted_pools.iter().map(|p| (p.slug(), p.name)).collect();
|
||||||
|
|
||||||
|
|||||||
@@ -1310,7 +1310,7 @@ impl IndexPct0Pct1Pct2Pct5Pct95Pct98Pct99ScorePattern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Pattern struct for repeated tree structure.
|
/// Pattern struct for repeated tree structure.
|
||||||
pub struct AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5 {
|
pub struct AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6 {
|
||||||
pub all: AverageBlockCumulativeSumPattern<StoredU64>,
|
pub all: AverageBlockCumulativeSumPattern<StoredU64>,
|
||||||
pub p2a: AverageBlockCumulativeSumPattern<StoredU64>,
|
pub p2a: AverageBlockCumulativeSumPattern<StoredU64>,
|
||||||
pub p2pk33: AverageBlockCumulativeSumPattern<StoredU64>,
|
pub p2pk33: AverageBlockCumulativeSumPattern<StoredU64>,
|
||||||
@@ -1322,7 +1322,7 @@ pub struct AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5 {
|
|||||||
pub p2wsh: AverageBlockCumulativeSumPattern<StoredU64>,
|
pub p2wsh: AverageBlockCumulativeSumPattern<StoredU64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5 {
|
impl AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6 {
|
||||||
/// Create a new pattern node with accumulated series name.
|
/// Create a new pattern node with accumulated series name.
|
||||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -1340,7 +1340,7 @@ impl AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Pattern struct for repeated tree structure.
|
/// Pattern struct for repeated tree structure.
|
||||||
pub struct AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3 {
|
pub struct AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4 {
|
||||||
pub all: SeriesPattern1<StoredU64>,
|
pub all: SeriesPattern1<StoredU64>,
|
||||||
pub p2a: SeriesPattern1<StoredU64>,
|
pub p2a: SeriesPattern1<StoredU64>,
|
||||||
pub p2pk33: SeriesPattern1<StoredU64>,
|
pub p2pk33: SeriesPattern1<StoredU64>,
|
||||||
@@ -1352,7 +1352,7 @@ pub struct AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3 {
|
|||||||
pub p2wsh: SeriesPattern1<StoredU64>,
|
pub p2wsh: SeriesPattern1<StoredU64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3 {
|
impl AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4 {
|
||||||
/// Create a new pattern node with accumulated series name.
|
/// Create a new pattern node with accumulated series name.
|
||||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -1370,7 +1370,7 @@ impl AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Pattern struct for repeated tree structure.
|
/// Pattern struct for repeated tree structure.
|
||||||
pub struct AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6 {
|
pub struct AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7 {
|
||||||
pub all: _1m1w1y24hBpsPercentRatioPattern,
|
pub all: _1m1w1y24hBpsPercentRatioPattern,
|
||||||
pub p2a: _1m1w1y24hBpsPercentRatioPattern,
|
pub p2a: _1m1w1y24hBpsPercentRatioPattern,
|
||||||
pub p2pk33: _1m1w1y24hBpsPercentRatioPattern,
|
pub p2pk33: _1m1w1y24hBpsPercentRatioPattern,
|
||||||
@@ -1382,7 +1382,7 @@ pub struct AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6 {
|
|||||||
pub p2wsh: _1m1w1y24hBpsPercentRatioPattern,
|
pub p2wsh: _1m1w1y24hBpsPercentRatioPattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6 {
|
impl AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7 {
|
||||||
/// Create a new pattern node with accumulated series name.
|
/// Create a new pattern node with accumulated series name.
|
||||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -1434,7 +1434,7 @@ pub struct CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2 {
|
|||||||
pub capitalized_cap_in_loss_raw: SeriesPattern18<CentsSquaredSats>,
|
pub capitalized_cap_in_loss_raw: SeriesPattern18<CentsSquaredSats>,
|
||||||
pub capitalized_cap_in_profit_raw: SeriesPattern18<CentsSquaredSats>,
|
pub capitalized_cap_in_profit_raw: SeriesPattern18<CentsSquaredSats>,
|
||||||
pub gross_pnl: CentsUsdPattern3,
|
pub gross_pnl: CentsUsdPattern3,
|
||||||
pub invested_capital: InPattern,
|
pub invested_capital: InPattern2,
|
||||||
pub loss: CentsNegativeToUsdPattern2,
|
pub loss: CentsNegativeToUsdPattern2,
|
||||||
pub net_pnl: CentsToUsdPattern3,
|
pub net_pnl: CentsToUsdPattern3,
|
||||||
pub nupl: BpsRatioPattern,
|
pub nupl: BpsRatioPattern,
|
||||||
@@ -1449,7 +1449,7 @@ impl CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2 {
|
|||||||
capitalized_cap_in_loss_raw: SeriesPattern18::new(client.clone(), _m(&acc, "capitalized_cap_in_loss_raw")),
|
capitalized_cap_in_loss_raw: SeriesPattern18::new(client.clone(), _m(&acc, "capitalized_cap_in_loss_raw")),
|
||||||
capitalized_cap_in_profit_raw: SeriesPattern18::new(client.clone(), _m(&acc, "capitalized_cap_in_profit_raw")),
|
capitalized_cap_in_profit_raw: SeriesPattern18::new(client.clone(), _m(&acc, "capitalized_cap_in_profit_raw")),
|
||||||
gross_pnl: CentsUsdPattern3::new(client.clone(), _m(&acc, "unrealized_gross_pnl")),
|
gross_pnl: CentsUsdPattern3::new(client.clone(), _m(&acc, "unrealized_gross_pnl")),
|
||||||
invested_capital: InPattern::new(client.clone(), _m(&acc, "invested_capital_in")),
|
invested_capital: InPattern2::new(client.clone(), _m(&acc, "invested_capital_in")),
|
||||||
loss: CentsNegativeToUsdPattern2::new(client.clone(), _m(&acc, "unrealized_loss")),
|
loss: CentsNegativeToUsdPattern2::new(client.clone(), _m(&acc, "unrealized_loss")),
|
||||||
net_pnl: CentsToUsdPattern3::new(client.clone(), _m(&acc, "net_unrealized_pnl")),
|
net_pnl: CentsToUsdPattern3::new(client.clone(), _m(&acc, "net_unrealized_pnl")),
|
||||||
nupl: BpsRatioPattern::new(client.clone(), _m(&acc, "nupl")),
|
nupl: BpsRatioPattern::new(client.clone(), _m(&acc, "nupl")),
|
||||||
@@ -1960,7 +1960,7 @@ impl ActivityOutputsRealizedSupplyUnrealizedPattern2 {
|
|||||||
/// Pattern struct for repeated tree structure.
|
/// Pattern struct for repeated tree structure.
|
||||||
pub struct BlockChangeCumulativeDeltaSumPattern {
|
pub struct BlockChangeCumulativeDeltaSumPattern {
|
||||||
pub block: CentsUsdPattern4,
|
pub block: CentsUsdPattern4,
|
||||||
pub change_1m: ToPattern,
|
pub change_1m: ToPattern2,
|
||||||
pub cumulative: CentsUsdPattern,
|
pub cumulative: CentsUsdPattern,
|
||||||
pub delta: AbsoluteRatePattern2,
|
pub delta: AbsoluteRatePattern2,
|
||||||
pub sum: _1m1w1y24hPattern5,
|
pub sum: _1m1w1y24hPattern5,
|
||||||
@@ -1971,7 +1971,7 @@ impl BlockChangeCumulativeDeltaSumPattern {
|
|||||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
block: CentsUsdPattern4::new(client.clone(), _m(&acc, "realized_pnl")),
|
block: CentsUsdPattern4::new(client.clone(), _m(&acc, "realized_pnl")),
|
||||||
change_1m: ToPattern::new(client.clone(), _m(&acc, "pnl_change_1m_to")),
|
change_1m: ToPattern2::new(client.clone(), _m(&acc, "pnl_change_1m_to")),
|
||||||
cumulative: CentsUsdPattern::new(client.clone(), _m(&acc, "realized_pnl_cumulative")),
|
cumulative: CentsUsdPattern::new(client.clone(), _m(&acc, "realized_pnl_cumulative")),
|
||||||
delta: AbsoluteRatePattern2::new(client.clone(), _m(&acc, "realized_pnl_delta")),
|
delta: AbsoluteRatePattern2::new(client.clone(), _m(&acc, "realized_pnl_delta")),
|
||||||
sum: _1m1w1y24hPattern5::new(client.clone(), _m(&acc, "realized_pnl_sum")),
|
sum: _1m1w1y24hPattern5::new(client.clone(), _m(&acc, "realized_pnl_sum")),
|
||||||
@@ -2966,6 +2966,22 @@ impl AbsoluteRatePattern2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Pattern struct for repeated tree structure.
|
||||||
|
pub struct AddrUtxoPattern {
|
||||||
|
pub addr: BtcCentsSatsUsdPattern,
|
||||||
|
pub utxo: BtcCentsSatsUsdPattern,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddrUtxoPattern {
|
||||||
|
/// Create a new pattern node with accumulated series name.
|
||||||
|
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||||
|
Self {
|
||||||
|
addr: BtcCentsSatsUsdPattern::new(client.clone(), _m(&acc, "addr_amount")),
|
||||||
|
utxo: BtcCentsSatsUsdPattern::new(client.clone(), _m(&acc, "utxo_amount")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Pattern struct for repeated tree structure.
|
/// Pattern struct for repeated tree structure.
|
||||||
pub struct AllSthPattern2 {
|
pub struct AllSthPattern2 {
|
||||||
pub all: BtcCentsDeltaSatsUsdPattern,
|
pub all: BtcCentsDeltaSatsUsdPattern,
|
||||||
@@ -3192,32 +3208,48 @@ impl DeltaTotalPattern {
|
|||||||
|
|
||||||
/// Pattern struct for repeated tree structure.
|
/// Pattern struct for repeated tree structure.
|
||||||
pub struct FundedTotalPattern {
|
pub struct FundedTotalPattern {
|
||||||
pub funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3,
|
pub funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4,
|
||||||
pub total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3,
|
pub total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FundedTotalPattern {
|
impl FundedTotalPattern {
|
||||||
/// Create a new pattern node with accumulated series name.
|
/// Create a new pattern node with accumulated series name.
|
||||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3::new(client.clone(), acc.clone()),
|
funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4::new(client.clone(), acc.clone()),
|
||||||
total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3::new(client.clone(), _p("total", &acc)),
|
total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4::new(client.clone(), _p("total", &acc)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pattern struct for repeated tree structure.
|
||||||
|
pub struct InPattern2 {
|
||||||
|
pub in_loss: CentsUsdPattern3,
|
||||||
|
pub in_profit: CentsUsdPattern3,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InPattern2 {
|
||||||
|
/// Create a new pattern node with accumulated series name.
|
||||||
|
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||||
|
Self {
|
||||||
|
in_loss: CentsUsdPattern3::new(client.clone(), _m(&acc, "loss")),
|
||||||
|
in_profit: CentsUsdPattern3::new(client.clone(), _m(&acc, "profit")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pattern struct for repeated tree structure.
|
/// Pattern struct for repeated tree structure.
|
||||||
pub struct InPattern {
|
pub struct InPattern {
|
||||||
pub in_loss: CentsUsdPattern3,
|
pub in_loss: ToPattern,
|
||||||
pub in_profit: CentsUsdPattern3,
|
pub in_profit: ToPattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InPattern {
|
impl InPattern {
|
||||||
/// Create a new pattern node with accumulated series name.
|
/// Create a new pattern node with accumulated series name.
|
||||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
in_loss: CentsUsdPattern3::new(client.clone(), _m(&acc, "loss")),
|
in_loss: ToPattern::new(client.clone(), _m(&acc, "loss_to_own")),
|
||||||
in_profit: CentsUsdPattern3::new(client.clone(), _m(&acc, "profit")),
|
in_profit: ToPattern::new(client.clone(), _m(&acc, "profit_to_own")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3277,12 +3309,12 @@ pub struct SdSmaPattern {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Pattern struct for repeated tree structure.
|
/// Pattern struct for repeated tree structure.
|
||||||
pub struct ToPattern {
|
pub struct ToPattern2 {
|
||||||
pub to_mcap: BpsPercentRatioPattern,
|
pub to_mcap: BpsPercentRatioPattern,
|
||||||
pub to_rcap: BpsPercentRatioPattern,
|
pub to_rcap: BpsPercentRatioPattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToPattern {
|
impl ToPattern2 {
|
||||||
/// Create a new pattern node with accumulated series name.
|
/// Create a new pattern node with accumulated series name.
|
||||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -3334,6 +3366,20 @@ impl PricePattern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Pattern struct for repeated tree structure.
|
||||||
|
pub struct ToPattern {
|
||||||
|
pub to_own: BpsPercentRatioPattern2,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPattern {
|
||||||
|
/// Create a new pattern node with accumulated series name.
|
||||||
|
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||||
|
Self {
|
||||||
|
to_own: BpsPercentRatioPattern2::new(client.clone(), acc.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Pattern struct for repeated tree structure.
|
/// Pattern struct for repeated tree structure.
|
||||||
pub struct TransferPattern {
|
pub struct TransferPattern {
|
||||||
pub transfer_volume: AverageBlockCumulativeSumPattern3,
|
pub transfer_volume: AverageBlockCumulativeSumPattern3,
|
||||||
@@ -4197,14 +4243,15 @@ pub struct SeriesTree_Addrs {
|
|||||||
pub raw: SeriesTree_Addrs_Raw,
|
pub raw: SeriesTree_Addrs_Raw,
|
||||||
pub indexes: SeriesTree_Addrs_Indexes,
|
pub indexes: SeriesTree_Addrs_Indexes,
|
||||||
pub data: SeriesTree_Addrs_Data,
|
pub data: SeriesTree_Addrs_Data,
|
||||||
pub funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3,
|
pub funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4,
|
||||||
pub empty: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3,
|
pub empty: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4,
|
||||||
pub activity: SeriesTree_Addrs_Activity,
|
pub activity: SeriesTree_Addrs_Activity,
|
||||||
pub total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3,
|
pub total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4,
|
||||||
pub new: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5,
|
pub new: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6,
|
||||||
pub reused: SeriesTree_Addrs_Reused,
|
pub reused: SeriesTree_Addrs_Reused,
|
||||||
pub exposed: SeriesTree_Addrs_Exposed,
|
pub exposed: SeriesTree_Addrs_Exposed,
|
||||||
pub delta: SeriesTree_Addrs_Delta,
|
pub delta: SeriesTree_Addrs_Delta,
|
||||||
|
pub avg_amount: SeriesTree_Addrs_AvgAmount,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SeriesTree_Addrs {
|
impl SeriesTree_Addrs {
|
||||||
@@ -4213,14 +4260,15 @@ impl SeriesTree_Addrs {
|
|||||||
raw: SeriesTree_Addrs_Raw::new(client.clone(), format!("{base_path}_raw")),
|
raw: SeriesTree_Addrs_Raw::new(client.clone(), format!("{base_path}_raw")),
|
||||||
indexes: SeriesTree_Addrs_Indexes::new(client.clone(), format!("{base_path}_indexes")),
|
indexes: SeriesTree_Addrs_Indexes::new(client.clone(), format!("{base_path}_indexes")),
|
||||||
data: SeriesTree_Addrs_Data::new(client.clone(), format!("{base_path}_data")),
|
data: SeriesTree_Addrs_Data::new(client.clone(), format!("{base_path}_data")),
|
||||||
funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3::new(client.clone(), "addr_count".to_string()),
|
funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4::new(client.clone(), "addr_count".to_string()),
|
||||||
empty: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3::new(client.clone(), "empty_addr_count".to_string()),
|
empty: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4::new(client.clone(), "empty_addr_count".to_string()),
|
||||||
activity: SeriesTree_Addrs_Activity::new(client.clone(), format!("{base_path}_activity")),
|
activity: SeriesTree_Addrs_Activity::new(client.clone(), format!("{base_path}_activity")),
|
||||||
total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3::new(client.clone(), "total_addr_count".to_string()),
|
total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4::new(client.clone(), "total_addr_count".to_string()),
|
||||||
new: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5::new(client.clone(), "new_addr_count".to_string()),
|
new: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6::new(client.clone(), "new_addr_count".to_string()),
|
||||||
reused: SeriesTree_Addrs_Reused::new(client.clone(), format!("{base_path}_reused")),
|
reused: SeriesTree_Addrs_Reused::new(client.clone(), format!("{base_path}_reused")),
|
||||||
exposed: SeriesTree_Addrs_Exposed::new(client.clone(), format!("{base_path}_exposed")),
|
exposed: SeriesTree_Addrs_Exposed::new(client.clone(), format!("{base_path}_exposed")),
|
||||||
delta: SeriesTree_Addrs_Delta::new(client.clone(), format!("{base_path}_delta")),
|
delta: SeriesTree_Addrs_Delta::new(client.clone(), format!("{base_path}_delta")),
|
||||||
|
avg_amount: SeriesTree_Addrs_AvgAmount::new(client.clone(), format!("{base_path}_avg_amount")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4485,11 +4533,11 @@ impl SeriesTree_Addrs_Reused {
|
|||||||
|
|
||||||
/// Series tree node.
|
/// Series tree node.
|
||||||
pub struct SeriesTree_Addrs_Reused_Events {
|
pub struct SeriesTree_Addrs_Reused_Events {
|
||||||
pub output_to_reused_addr_count: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5,
|
pub output_to_reused_addr_count: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6,
|
||||||
pub output_to_reused_addr_share: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6,
|
pub output_to_reused_addr_share: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7,
|
||||||
pub spendable_output_to_reused_addr_share: _1m1w1y24hBpsPercentRatioPattern,
|
pub spendable_output_to_reused_addr_share: _1m1w1y24hBpsPercentRatioPattern,
|
||||||
pub input_from_reused_addr_count: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5,
|
pub input_from_reused_addr_count: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6,
|
||||||
pub input_from_reused_addr_share: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6,
|
pub input_from_reused_addr_share: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7,
|
||||||
pub active_reused_addr_count: _1m1w1y24hBlockPattern,
|
pub active_reused_addr_count: _1m1w1y24hBlockPattern,
|
||||||
pub active_reused_addr_share: SeriesTree_Addrs_Reused_Events_ActiveReusedAddrShare,
|
pub active_reused_addr_share: SeriesTree_Addrs_Reused_Events_ActiveReusedAddrShare,
|
||||||
}
|
}
|
||||||
@@ -4497,11 +4545,11 @@ pub struct SeriesTree_Addrs_Reused_Events {
|
|||||||
impl SeriesTree_Addrs_Reused_Events {
|
impl SeriesTree_Addrs_Reused_Events {
|
||||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
output_to_reused_addr_count: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5::new(client.clone(), "output_to_reused_addr_count".to_string()),
|
output_to_reused_addr_count: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6::new(client.clone(), "output_to_reused_addr_count".to_string()),
|
||||||
output_to_reused_addr_share: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6::new(client.clone(), "output_to_reused_addr_share".to_string()),
|
output_to_reused_addr_share: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7::new(client.clone(), "output_to_reused_addr_share".to_string()),
|
||||||
spendable_output_to_reused_addr_share: _1m1w1y24hBpsPercentRatioPattern::new(client.clone(), "spendable_output_to_reused_addr_share".to_string()),
|
spendable_output_to_reused_addr_share: _1m1w1y24hBpsPercentRatioPattern::new(client.clone(), "spendable_output_to_reused_addr_share".to_string()),
|
||||||
input_from_reused_addr_count: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5::new(client.clone(), "input_from_reused_addr_count".to_string()),
|
input_from_reused_addr_count: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6::new(client.clone(), "input_from_reused_addr_count".to_string()),
|
||||||
input_from_reused_addr_share: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6::new(client.clone(), "input_from_reused_addr_share".to_string()),
|
input_from_reused_addr_share: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7::new(client.clone(), "input_from_reused_addr_share".to_string()),
|
||||||
active_reused_addr_count: _1m1w1y24hBlockPattern::new(client.clone(), "active_reused_addr_count".to_string()),
|
active_reused_addr_count: _1m1w1y24hBlockPattern::new(client.clone(), "active_reused_addr_count".to_string()),
|
||||||
active_reused_addr_share: SeriesTree_Addrs_Reused_Events_ActiveReusedAddrShare::new(client.clone(), format!("{base_path}_active_reused_addr_share")),
|
active_reused_addr_share: SeriesTree_Addrs_Reused_Events_ActiveReusedAddrShare::new(client.clone(), format!("{base_path}_active_reused_addr_share")),
|
||||||
}
|
}
|
||||||
@@ -4633,6 +4681,35 @@ impl SeriesTree_Addrs_Delta {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Series tree node.
|
||||||
|
pub struct SeriesTree_Addrs_AvgAmount {
|
||||||
|
pub all: AddrUtxoPattern,
|
||||||
|
pub p2pk65: AddrUtxoPattern,
|
||||||
|
pub p2pk33: AddrUtxoPattern,
|
||||||
|
pub p2pkh: AddrUtxoPattern,
|
||||||
|
pub p2sh: AddrUtxoPattern,
|
||||||
|
pub p2wpkh: AddrUtxoPattern,
|
||||||
|
pub p2wsh: AddrUtxoPattern,
|
||||||
|
pub p2tr: AddrUtxoPattern,
|
||||||
|
pub p2a: AddrUtxoPattern,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SeriesTree_Addrs_AvgAmount {
|
||||||
|
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||||
|
Self {
|
||||||
|
all: AddrUtxoPattern::new(client.clone(), "avg".to_string()),
|
||||||
|
p2pk65: AddrUtxoPattern::new(client.clone(), "p2pk65_avg".to_string()),
|
||||||
|
p2pk33: AddrUtxoPattern::new(client.clone(), "p2pk33_avg".to_string()),
|
||||||
|
p2pkh: AddrUtxoPattern::new(client.clone(), "p2pkh_avg".to_string()),
|
||||||
|
p2sh: AddrUtxoPattern::new(client.clone(), "p2sh_avg".to_string()),
|
||||||
|
p2wpkh: AddrUtxoPattern::new(client.clone(), "p2wpkh_avg".to_string()),
|
||||||
|
p2wsh: AddrUtxoPattern::new(client.clone(), "p2wsh_avg".to_string()),
|
||||||
|
p2tr: AddrUtxoPattern::new(client.clone(), "p2tr_avg".to_string()),
|
||||||
|
p2a: AddrUtxoPattern::new(client.clone(), "p2a_avg".to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Series tree node.
|
/// Series tree node.
|
||||||
pub struct SeriesTree_Scripts {
|
pub struct SeriesTree_Scripts {
|
||||||
pub raw: SeriesTree_Scripts_Raw,
|
pub raw: SeriesTree_Scripts_Raw,
|
||||||
@@ -6975,6 +7052,7 @@ pub struct SeriesTree_Cohorts_Utxo_All {
|
|||||||
pub realized: SeriesTree_Cohorts_Utxo_All_Realized,
|
pub realized: SeriesTree_Cohorts_Utxo_All_Realized,
|
||||||
pub cost_basis: SeriesTree_Cohorts_Utxo_All_CostBasis,
|
pub cost_basis: SeriesTree_Cohorts_Utxo_All_CostBasis,
|
||||||
pub unrealized: SeriesTree_Cohorts_Utxo_All_Unrealized,
|
pub unrealized: SeriesTree_Cohorts_Utxo_All_Unrealized,
|
||||||
|
pub invested_capital: InPattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SeriesTree_Cohorts_Utxo_All {
|
impl SeriesTree_Cohorts_Utxo_All {
|
||||||
@@ -6986,6 +7064,7 @@ impl SeriesTree_Cohorts_Utxo_All {
|
|||||||
realized: SeriesTree_Cohorts_Utxo_All_Realized::new(client.clone(), format!("{base_path}_realized")),
|
realized: SeriesTree_Cohorts_Utxo_All_Realized::new(client.clone(), format!("{base_path}_realized")),
|
||||||
cost_basis: SeriesTree_Cohorts_Utxo_All_CostBasis::new(client.clone(), format!("{base_path}_cost_basis")),
|
cost_basis: SeriesTree_Cohorts_Utxo_All_CostBasis::new(client.clone(), format!("{base_path}_cost_basis")),
|
||||||
unrealized: SeriesTree_Cohorts_Utxo_All_Unrealized::new(client.clone(), format!("{base_path}_unrealized")),
|
unrealized: SeriesTree_Cohorts_Utxo_All_Unrealized::new(client.clone(), format!("{base_path}_unrealized")),
|
||||||
|
invested_capital: InPattern::new(client.clone(), "invested_capital_in".to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7358,7 +7437,7 @@ pub struct SeriesTree_Cohorts_Utxo_All_Unrealized {
|
|||||||
pub loss: SeriesTree_Cohorts_Utxo_All_Unrealized_Loss,
|
pub loss: SeriesTree_Cohorts_Utxo_All_Unrealized_Loss,
|
||||||
pub net_pnl: SeriesTree_Cohorts_Utxo_All_Unrealized_NetPnl,
|
pub net_pnl: SeriesTree_Cohorts_Utxo_All_Unrealized_NetPnl,
|
||||||
pub gross_pnl: CentsUsdPattern3,
|
pub gross_pnl: CentsUsdPattern3,
|
||||||
pub invested_capital: InPattern,
|
pub invested_capital: InPattern2,
|
||||||
pub capitalized_cap_in_profit_raw: SeriesPattern18<CentsSquaredSats>,
|
pub capitalized_cap_in_profit_raw: SeriesPattern18<CentsSquaredSats>,
|
||||||
pub capitalized_cap_in_loss_raw: SeriesPattern18<CentsSquaredSats>,
|
pub capitalized_cap_in_loss_raw: SeriesPattern18<CentsSquaredSats>,
|
||||||
pub sentiment: SeriesTree_Cohorts_Utxo_All_Unrealized_Sentiment,
|
pub sentiment: SeriesTree_Cohorts_Utxo_All_Unrealized_Sentiment,
|
||||||
@@ -7372,7 +7451,7 @@ impl SeriesTree_Cohorts_Utxo_All_Unrealized {
|
|||||||
loss: SeriesTree_Cohorts_Utxo_All_Unrealized_Loss::new(client.clone(), format!("{base_path}_loss")),
|
loss: SeriesTree_Cohorts_Utxo_All_Unrealized_Loss::new(client.clone(), format!("{base_path}_loss")),
|
||||||
net_pnl: SeriesTree_Cohorts_Utxo_All_Unrealized_NetPnl::new(client.clone(), format!("{base_path}_net_pnl")),
|
net_pnl: SeriesTree_Cohorts_Utxo_All_Unrealized_NetPnl::new(client.clone(), format!("{base_path}_net_pnl")),
|
||||||
gross_pnl: CentsUsdPattern3::new(client.clone(), "unrealized_gross_pnl".to_string()),
|
gross_pnl: CentsUsdPattern3::new(client.clone(), "unrealized_gross_pnl".to_string()),
|
||||||
invested_capital: InPattern::new(client.clone(), "invested_capital_in".to_string()),
|
invested_capital: InPattern2::new(client.clone(), "invested_capital_in".to_string()),
|
||||||
capitalized_cap_in_profit_raw: SeriesPattern18::new(client.clone(), "capitalized_cap_in_profit_raw".to_string()),
|
capitalized_cap_in_profit_raw: SeriesPattern18::new(client.clone(), "capitalized_cap_in_profit_raw".to_string()),
|
||||||
capitalized_cap_in_loss_raw: SeriesPattern18::new(client.clone(), "capitalized_cap_in_loss_raw".to_string()),
|
capitalized_cap_in_loss_raw: SeriesPattern18::new(client.clone(), "capitalized_cap_in_loss_raw".to_string()),
|
||||||
sentiment: SeriesTree_Cohorts_Utxo_All_Unrealized_Sentiment::new(client.clone(), format!("{base_path}_sentiment")),
|
sentiment: SeriesTree_Cohorts_Utxo_All_Unrealized_Sentiment::new(client.clone(), format!("{base_path}_sentiment")),
|
||||||
@@ -7462,6 +7541,7 @@ pub struct SeriesTree_Cohorts_Utxo_Sth {
|
|||||||
pub realized: SeriesTree_Cohorts_Utxo_Sth_Realized,
|
pub realized: SeriesTree_Cohorts_Utxo_Sth_Realized,
|
||||||
pub cost_basis: InMaxMinPerSupplyPattern,
|
pub cost_basis: InMaxMinPerSupplyPattern,
|
||||||
pub unrealized: CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2,
|
pub unrealized: CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2,
|
||||||
|
pub invested_capital: InPattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SeriesTree_Cohorts_Utxo_Sth {
|
impl SeriesTree_Cohorts_Utxo_Sth {
|
||||||
@@ -7473,6 +7553,7 @@ impl SeriesTree_Cohorts_Utxo_Sth {
|
|||||||
realized: SeriesTree_Cohorts_Utxo_Sth_Realized::new(client.clone(), format!("{base_path}_realized")),
|
realized: SeriesTree_Cohorts_Utxo_Sth_Realized::new(client.clone(), format!("{base_path}_realized")),
|
||||||
cost_basis: InMaxMinPerSupplyPattern::new(client.clone(), "sth".to_string()),
|
cost_basis: InMaxMinPerSupplyPattern::new(client.clone(), "sth".to_string()),
|
||||||
unrealized: CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2::new(client.clone(), "sth".to_string()),
|
unrealized: CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2::new(client.clone(), "sth".to_string()),
|
||||||
|
invested_capital: InPattern::new(client.clone(), "sth_invested_capital_in".to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7730,6 +7811,7 @@ pub struct SeriesTree_Cohorts_Utxo_Lth {
|
|||||||
pub realized: SeriesTree_Cohorts_Utxo_Lth_Realized,
|
pub realized: SeriesTree_Cohorts_Utxo_Lth_Realized,
|
||||||
pub cost_basis: InMaxMinPerSupplyPattern,
|
pub cost_basis: InMaxMinPerSupplyPattern,
|
||||||
pub unrealized: CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2,
|
pub unrealized: CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2,
|
||||||
|
pub invested_capital: InPattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SeriesTree_Cohorts_Utxo_Lth {
|
impl SeriesTree_Cohorts_Utxo_Lth {
|
||||||
@@ -7741,6 +7823,7 @@ impl SeriesTree_Cohorts_Utxo_Lth {
|
|||||||
realized: SeriesTree_Cohorts_Utxo_Lth_Realized::new(client.clone(), format!("{base_path}_realized")),
|
realized: SeriesTree_Cohorts_Utxo_Lth_Realized::new(client.clone(), format!("{base_path}_realized")),
|
||||||
cost_basis: InMaxMinPerSupplyPattern::new(client.clone(), "lth".to_string()),
|
cost_basis: InMaxMinPerSupplyPattern::new(client.clone(), "lth".to_string()),
|
||||||
unrealized: CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2::new(client.clone(), "lth".to_string()),
|
unrealized: CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2::new(client.clone(), "lth".to_string()),
|
||||||
|
invested_capital: InPattern::new(client.clone(), "lth_invested_capital_in".to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,14 +67,14 @@ pub(crate) fn process_funded_addrs(
|
|||||||
|
|
||||||
// Pure pushes - no holes remain
|
// Pure pushes - no holes remain
|
||||||
addrs_data.funded.reserve_pushed(pushes_iter.len());
|
addrs_data.funded.reserve_pushed(pushes_iter.len());
|
||||||
let mut next_index = addrs_data.funded.len();
|
for (next_index, (addr_type, type_index, data)) in
|
||||||
for (addr_type, type_index, data) in pushes_iter {
|
(addrs_data.funded.len()..).zip(pushes_iter)
|
||||||
|
{
|
||||||
addrs_data.funded.push(data);
|
addrs_data.funded.push(data);
|
||||||
result.get_mut(addr_type).unwrap().insert(
|
result.get_mut(addr_type).unwrap().insert(
|
||||||
type_index,
|
type_index,
|
||||||
AnyAddrIndex::from(FundedAddrIndex::from(next_index)),
|
AnyAddrIndex::from(FundedAddrIndex::from(next_index)),
|
||||||
);
|
);
|
||||||
next_index += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
@@ -138,14 +138,14 @@ pub(crate) fn process_empty_addrs(
|
|||||||
|
|
||||||
// Pure pushes - no holes remain
|
// Pure pushes - no holes remain
|
||||||
addrs_data.empty.reserve_pushed(pushes_iter.len());
|
addrs_data.empty.reserve_pushed(pushes_iter.len());
|
||||||
let mut next_index = addrs_data.empty.len();
|
for (next_index, (addr_type, type_index, data)) in
|
||||||
for (addr_type, type_index, data) in pushes_iter {
|
(addrs_data.empty.len()..).zip(pushes_iter)
|
||||||
|
{
|
||||||
addrs_data.empty.push(data);
|
addrs_data.empty.push(data);
|
||||||
result.get_mut(addr_type).unwrap().insert(
|
result.get_mut(addr_type).unwrap().insert(
|
||||||
type_index,
|
type_index,
|
||||||
AnyAddrIndex::from(EmptyAddrIndex::from(next_index)),
|
AnyAddrIndex::from(EmptyAddrIndex::from(next_index)),
|
||||||
);
|
);
|
||||||
next_index += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
|
|||||||
@@ -542,17 +542,14 @@ impl UTXOCohorts<Rw> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Second phase of post-processing: compute relative metrics.
|
/// Second phase of post-processing: compute relative metrics.
|
||||||
pub(crate) fn compute_rest_part2<HM>(
|
pub(crate) fn compute_rest_part2(
|
||||||
&mut self,
|
&mut self,
|
||||||
blocks: &blocks::Vecs,
|
blocks: &blocks::Vecs,
|
||||||
prices: &prices::Vecs,
|
prices: &prices::Vecs,
|
||||||
starting_indexes: &Indexes,
|
starting_indexes: &Indexes,
|
||||||
height_to_market_cap: &HM,
|
height_to_market_cap: &impl ReadableVec<Height, Dollars>,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()>
|
) -> Result<()> {
|
||||||
where
|
|
||||||
HM: ReadableVec<Height, Dollars> + Sync,
|
|
||||||
{
|
|
||||||
// Get under_1h value sources for adjusted computation (cloned to avoid borrow conflicts).
|
// Get under_1h value sources for adjusted computation (cloned to avoid borrow conflicts).
|
||||||
let under_1h_value_created = self
|
let under_1h_value_created = self
|
||||||
.age_range
|
.age_range
|
||||||
|
|||||||
@@ -258,6 +258,7 @@ pub(crate) fn process_blocks(
|
|||||||
.chain(vecs.addrs.activity.par_iter_height_mut())
|
.chain(vecs.addrs.activity.par_iter_height_mut())
|
||||||
.chain(vecs.addrs.reused.par_iter_height_mut())
|
.chain(vecs.addrs.reused.par_iter_height_mut())
|
||||||
.chain(vecs.addrs.exposed.par_iter_height_mut())
|
.chain(vecs.addrs.exposed.par_iter_height_mut())
|
||||||
|
.chain(vecs.addrs.avg_amount.par_iter_height_mut())
|
||||||
.chain(rayon::iter::once(
|
.chain(rayon::iter::once(
|
||||||
&mut vecs.coinblocks_destroyed.block as &mut dyn AnyStoredVec,
|
&mut vecs.coinblocks_destroyed.block as &mut dyn AnyStoredVec,
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ impl AllCohortMetrics {
|
|||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.supply,
|
&self.supply,
|
||||||
&self.unrealized,
|
&self.unrealized,
|
||||||
|
&self.realized,
|
||||||
height_to_market_cap,
|
height_to_market_cap,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ impl ExtendedCohortMetrics {
|
|||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
&self.supply,
|
&self.supply,
|
||||||
&self.unrealized,
|
&self.unrealized,
|
||||||
|
&self.realized,
|
||||||
height_to_market_cap,
|
height_to_market_cap,
|
||||||
all_supply_sats,
|
all_supply_sats,
|
||||||
&self.supply.total.usd.height,
|
&self.supply.total.usd.height,
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ pub use realized::{
|
|||||||
AdjustedSopr, RealizedCore, RealizedFull, RealizedFullAccum, RealizedLike, RealizedMinimal,
|
AdjustedSopr, RealizedCore, RealizedFull, RealizedFullAccum, RealizedLike, RealizedMinimal,
|
||||||
};
|
};
|
||||||
pub use relative::{RelativeForAll, RelativeToAll, RelativeWithExtended};
|
pub use relative::{RelativeForAll, RelativeToAll, RelativeWithExtended};
|
||||||
pub use supply::{SupplyBase, SupplyCore};
|
pub use supply::{AvgAmountMetrics, SupplyBase, SupplyCore};
|
||||||
pub use unrealized::{
|
pub use unrealized::{
|
||||||
UnrealizedBasic, UnrealizedCore, UnrealizedFull, UnrealizedLike, UnrealizedMinimal,
|
UnrealizedBasic, UnrealizedCore, UnrealizedFull, UnrealizedLike, UnrealizedMinimal,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -118,11 +118,11 @@ impl RealizedMinimal {
|
|||||||
|(i, cap_cents, supply, ..)| {
|
|(i, cap_cents, supply, ..)| {
|
||||||
let cap = cap_cents.as_u128();
|
let cap = cap_cents.as_u128();
|
||||||
let supply_sats = Sats::from(supply).as_u128();
|
let supply_sats = Sats::from(supply).as_u128();
|
||||||
if supply_sats == 0 {
|
let cents = (cap * Sats::ONE_BTC_U128)
|
||||||
(i, Cents::ZERO)
|
.checked_div(supply_sats)
|
||||||
} else {
|
.map(Cents::from)
|
||||||
(i, Cents::from(cap * Sats::ONE_BTC_U128 / supply_sats))
|
.unwrap_or(Cents::ZERO);
|
||||||
}
|
(i, cents)
|
||||||
},
|
},
|
||||||
exit,
|
exit,
|
||||||
)?)
|
)?)
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ use brk_types::{Dollars, Height};
|
|||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
||||||
|
|
||||||
use crate::distribution::metrics::{ImportConfig, SupplyCore, UnrealizedFull};
|
use crate::distribution::metrics::{ImportConfig, RealizedFull, SupplyCore, UnrealizedFull};
|
||||||
|
|
||||||
use super::{RelativeExtendedOwnPnl, RelativeFull};
|
use super::{RelativeExtendedOwnPnl, RelativeFull, RelativeInvestedCapital};
|
||||||
|
|
||||||
/// Relative metrics for the "all" cohort (base + own_pnl, NO rel_to_all).
|
/// Relative metrics for the "all" cohort (base + own_pnl, NO rel_to_all).
|
||||||
#[derive(Deref, DerefMut, Traversable)]
|
#[derive(Deref, DerefMut, Traversable)]
|
||||||
@@ -17,6 +17,8 @@ pub struct RelativeForAll<M: StorageMode = Rw> {
|
|||||||
pub base: RelativeFull<M>,
|
pub base: RelativeFull<M>,
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub extended_own_pnl: RelativeExtendedOwnPnl<M>,
|
pub extended_own_pnl: RelativeExtendedOwnPnl<M>,
|
||||||
|
#[traversable(flatten)]
|
||||||
|
pub invested_capital: RelativeInvestedCapital<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RelativeForAll {
|
impl RelativeForAll {
|
||||||
@@ -24,6 +26,7 @@ impl RelativeForAll {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
base: RelativeFull::forced_import(cfg)?,
|
base: RelativeFull::forced_import(cfg)?,
|
||||||
extended_own_pnl: RelativeExtendedOwnPnl::forced_import(cfg)?,
|
extended_own_pnl: RelativeExtendedOwnPnl::forced_import(cfg)?,
|
||||||
|
invested_capital: RelativeInvestedCapital::forced_import(cfg)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,6 +35,7 @@ impl RelativeForAll {
|
|||||||
max_from: Height,
|
max_from: Height,
|
||||||
supply: &SupplyCore,
|
supply: &SupplyCore,
|
||||||
unrealized: &UnrealizedFull,
|
unrealized: &UnrealizedFull,
|
||||||
|
realized: &RealizedFull,
|
||||||
market_cap: &impl ReadableVec<Height, Dollars>,
|
market_cap: &impl ReadableVec<Height, Dollars>,
|
||||||
exit: &Exit,
|
exit: &Exit,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@@ -43,6 +47,8 @@ impl RelativeForAll {
|
|||||||
&unrealized.gross_pnl.usd.height,
|
&unrealized.gross_pnl.usd.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
self.invested_capital
|
||||||
|
.compute(max_from, unrealized, realized, exit)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
use brk_error::Result;
|
||||||
|
use brk_traversable::Traversable;
|
||||||
|
use brk_types::{BasisPoints16, Cents, Height, Version};
|
||||||
|
use vecdb::{Exit, Rw, StorageMode};
|
||||||
|
|
||||||
|
use crate::internal::{PercentPerBlock, RatioCentsBp16};
|
||||||
|
|
||||||
|
use crate::distribution::metrics::{ImportConfig, RealizedFull, UnrealizedFull};
|
||||||
|
|
||||||
|
/// Shares of invested capital in profit / in loss relative to own realized cap.
|
||||||
|
/// Present for cohorts with `UnrealizedFull` (all, sth, lth).
|
||||||
|
#[derive(Traversable)]
|
||||||
|
pub struct RelativeInvestedCapital<M: StorageMode = Rw> {
|
||||||
|
#[traversable(wrap = "invested_capital/in_profit", rename = "to_own")]
|
||||||
|
pub in_profit_to_own: PercentPerBlock<BasisPoints16, M>,
|
||||||
|
#[traversable(wrap = "invested_capital/in_loss", rename = "to_own")]
|
||||||
|
pub in_loss_to_own: PercentPerBlock<BasisPoints16, M>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RelativeInvestedCapital {
|
||||||
|
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
|
||||||
|
let v0 = Version::ZERO;
|
||||||
|
Ok(Self {
|
||||||
|
in_profit_to_own: cfg.import("invested_capital_in_profit_to_own", v0)?,
|
||||||
|
in_loss_to_own: cfg.import("invested_capital_in_loss_to_own", v0)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compute(
|
||||||
|
&mut self,
|
||||||
|
max_from: Height,
|
||||||
|
unrealized: &UnrealizedFull,
|
||||||
|
realized: &RealizedFull,
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()> {
|
||||||
|
let realized_cap = &realized.core.minimal.cap.cents.height;
|
||||||
|
self.in_profit_to_own
|
||||||
|
.compute_binary::<Cents, Cents, RatioCentsBp16>(
|
||||||
|
max_from,
|
||||||
|
&unrealized.invested_capital.in_profit.cents.height,
|
||||||
|
realized_cap,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
self.in_loss_to_own
|
||||||
|
.compute_binary::<Cents, Cents, RatioCentsBp16>(
|
||||||
|
max_from,
|
||||||
|
&unrealized.invested_capital.in_loss.cents.height,
|
||||||
|
realized_cap,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ mod extended_own_market_cap;
|
|||||||
mod extended_own_pnl;
|
mod extended_own_pnl;
|
||||||
mod for_all;
|
mod for_all;
|
||||||
mod full;
|
mod full;
|
||||||
|
mod invested_capital;
|
||||||
mod to_all;
|
mod to_all;
|
||||||
mod with_extended;
|
mod with_extended;
|
||||||
|
|
||||||
@@ -9,5 +10,6 @@ pub use extended_own_market_cap::RelativeExtendedOwnMarketCap;
|
|||||||
pub use extended_own_pnl::RelativeExtendedOwnPnl;
|
pub use extended_own_pnl::RelativeExtendedOwnPnl;
|
||||||
pub use for_all::RelativeForAll;
|
pub use for_all::RelativeForAll;
|
||||||
pub use full::RelativeFull;
|
pub use full::RelativeFull;
|
||||||
|
pub use invested_capital::RelativeInvestedCapital;
|
||||||
pub use to_all::RelativeToAll;
|
pub use to_all::RelativeToAll;
|
||||||
pub use with_extended::RelativeWithExtended;
|
pub use with_extended::RelativeWithExtended;
|
||||||
|
|||||||
@@ -4,9 +4,12 @@ use brk_types::{Dollars, Height, Sats};
|
|||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
use vecdb::{Exit, ReadableVec, Rw, StorageMode};
|
||||||
|
|
||||||
use crate::distribution::metrics::{ImportConfig, SupplyCore, UnrealizedFull};
|
use crate::distribution::metrics::{ImportConfig, RealizedFull, SupplyCore, UnrealizedFull};
|
||||||
|
|
||||||
use super::{RelativeExtendedOwnMarketCap, RelativeExtendedOwnPnl, RelativeFull, RelativeToAll};
|
use super::{
|
||||||
|
RelativeExtendedOwnMarketCap, RelativeExtendedOwnPnl, RelativeFull, RelativeInvestedCapital,
|
||||||
|
RelativeToAll,
|
||||||
|
};
|
||||||
|
|
||||||
/// Full extended relative metrics (base + rel_to_all + own_market_cap + own_pnl).
|
/// Full extended relative metrics (base + rel_to_all + own_market_cap + own_pnl).
|
||||||
/// Used by: sth, lth cohorts.
|
/// Used by: sth, lth cohorts.
|
||||||
@@ -22,6 +25,8 @@ pub struct RelativeWithExtended<M: StorageMode = Rw> {
|
|||||||
pub extended_own_market_cap: RelativeExtendedOwnMarketCap<M>,
|
pub extended_own_market_cap: RelativeExtendedOwnMarketCap<M>,
|
||||||
#[traversable(flatten)]
|
#[traversable(flatten)]
|
||||||
pub extended_own_pnl: RelativeExtendedOwnPnl<M>,
|
pub extended_own_pnl: RelativeExtendedOwnPnl<M>,
|
||||||
|
#[traversable(flatten)]
|
||||||
|
pub invested_capital: RelativeInvestedCapital<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RelativeWithExtended {
|
impl RelativeWithExtended {
|
||||||
@@ -31,6 +36,7 @@ impl RelativeWithExtended {
|
|||||||
rel_to_all: RelativeToAll::forced_import(cfg)?,
|
rel_to_all: RelativeToAll::forced_import(cfg)?,
|
||||||
extended_own_market_cap: RelativeExtendedOwnMarketCap::forced_import(cfg)?,
|
extended_own_market_cap: RelativeExtendedOwnMarketCap::forced_import(cfg)?,
|
||||||
extended_own_pnl: RelativeExtendedOwnPnl::forced_import(cfg)?,
|
extended_own_pnl: RelativeExtendedOwnPnl::forced_import(cfg)?,
|
||||||
|
invested_capital: RelativeInvestedCapital::forced_import(cfg)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,6 +46,7 @@ impl RelativeWithExtended {
|
|||||||
max_from: Height,
|
max_from: Height,
|
||||||
supply: &SupplyCore,
|
supply: &SupplyCore,
|
||||||
unrealized: &UnrealizedFull,
|
unrealized: &UnrealizedFull,
|
||||||
|
realized: &RealizedFull,
|
||||||
market_cap: &impl ReadableVec<Height, Dollars>,
|
market_cap: &impl ReadableVec<Height, Dollars>,
|
||||||
all_supply_sats: &impl ReadableVec<Height, Sats>,
|
all_supply_sats: &impl ReadableVec<Height, Sats>,
|
||||||
own_market_cap: &impl ReadableVec<Height, Dollars>,
|
own_market_cap: &impl ReadableVec<Height, Dollars>,
|
||||||
@@ -57,6 +64,8 @@ impl RelativeWithExtended {
|
|||||||
&unrealized.gross_pnl.usd.height,
|
&unrealized.gross_pnl.usd.height,
|
||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
self.invested_capital
|
||||||
|
.compute(max_from, unrealized, realized, exit)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
use brk_error::Result;
|
||||||
|
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};
|
||||||
|
|
||||||
|
/// 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>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AvgAmountMetrics {
|
||||||
|
pub(crate) fn forced_import(
|
||||||
|
db: &Database,
|
||||||
|
prefix: &str,
|
||||||
|
version: Version,
|
||||||
|
indexes: &indexes::Vecs,
|
||||||
|
) -> Result<Self> {
|
||||||
|
let name = |suffix: &str| {
|
||||||
|
if prefix.is_empty() {
|
||||||
|
suffix.to_string()
|
||||||
|
} else {
|
||||||
|
format!("{prefix}_{suffix}")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(Self {
|
||||||
|
utxo: AmountPerBlock::forced_import(db, &name("avg_utxo_amount"), version, indexes)?,
|
||||||
|
addr: AmountPerBlock::forced_import(db, &name("avg_addr_amount"), version, indexes)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||||
|
vec![
|
||||||
|
&mut self.utxo.sats.height as &mut dyn AnyStoredVec,
|
||||||
|
&mut self.utxo.cents.height,
|
||||||
|
&mut self.addr.sats.height,
|
||||||
|
&mut self.addr.cents.height,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn reset_height(&mut self) -> Result<()> {
|
||||||
|
self.utxo.sats.height.reset()?;
|
||||||
|
self.utxo.cents.height.reset()?;
|
||||||
|
self.addr.sats.height.reset()?;
|
||||||
|
self.addr.cents.height.reset()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn compute(
|
||||||
|
&mut self,
|
||||||
|
prices: &prices::Vecs,
|
||||||
|
supply_sats: &impl ReadableVec<Height, Sats>,
|
||||||
|
utxo_count: &impl ReadableVec<Height, StoredU64>,
|
||||||
|
funded_addr_count: &impl ReadableVec<Height, StoredU64>,
|
||||||
|
max_from: Height,
|
||||||
|
exit: &Exit,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.utxo
|
||||||
|
.sats
|
||||||
|
.height
|
||||||
|
.compute_divide(max_from, supply_sats, utxo_count, exit)?;
|
||||||
|
self.utxo.compute(prices, max_from, exit)?;
|
||||||
|
|
||||||
|
self.addr
|
||||||
|
.sats
|
||||||
|
.height
|
||||||
|
.compute_divide(max_from, supply_sats, funded_addr_count, exit)?;
|
||||||
|
self.addr.compute(prices, max_from, exit)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,7 +49,7 @@ impl SupplyBase {
|
|||||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||||
vec![
|
vec![
|
||||||
&mut self.total.sats.height as &mut dyn AnyStoredVec,
|
&mut self.total.sats.height as &mut dyn AnyStoredVec,
|
||||||
&mut self.total.cents.height as &mut dyn AnyStoredVec,
|
&mut self.total.cents.height,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
mod avg_amount;
|
||||||
mod base;
|
mod base;
|
||||||
mod core;
|
mod core;
|
||||||
|
|
||||||
|
pub use avg_amount::AvgAmountMetrics;
|
||||||
pub use self::core::SupplyCore;
|
pub use self::core::SupplyCore;
|
||||||
pub use base::SupplyBase;
|
pub use base::SupplyBase;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
indexes, inputs,
|
indexes, inputs,
|
||||||
internal::{
|
internal::{
|
||||||
PerBlockCumulativeRolling, WindowStartVec, Windows,
|
PerBlockCumulativeRolling, WindowStartVec, Windows, WithAddrTypes,
|
||||||
db_utils::{finalize_db, open_db},
|
db_utils::{finalize_db, open_db},
|
||||||
},
|
},
|
||||||
outputs, prices, transactions,
|
outputs, prices, transactions,
|
||||||
@@ -37,6 +37,7 @@ use super::{
|
|||||||
AddrActivityVecs, AddrCountsVecs, DeltaVecs, ExposedAddrVecs, NewAddrCountVecs,
|
AddrActivityVecs, AddrCountsVecs, DeltaVecs, ExposedAddrVecs, NewAddrCountVecs,
|
||||||
ReusedAddrVecs, TotalAddrCountVecs,
|
ReusedAddrVecs, TotalAddrCountVecs,
|
||||||
},
|
},
|
||||||
|
metrics::AvgAmountMetrics,
|
||||||
};
|
};
|
||||||
|
|
||||||
const VERSION: Version = Version::new(23);
|
const VERSION: Version = Version::new(23);
|
||||||
@@ -51,6 +52,7 @@ pub struct AddrMetricsVecs<M: StorageMode = Rw> {
|
|||||||
pub reused: ReusedAddrVecs<M>,
|
pub reused: ReusedAddrVecs<M>,
|
||||||
pub exposed: ExposedAddrVecs<M>,
|
pub exposed: ExposedAddrVecs<M>,
|
||||||
pub delta: DeltaVecs,
|
pub delta: DeltaVecs,
|
||||||
|
pub avg_amount: WithAddrTypes<AvgAmountMetrics<M>>,
|
||||||
#[traversable(wrap = "indexes", rename = "funded")]
|
#[traversable(wrap = "indexes", rename = "funded")]
|
||||||
pub funded_index:
|
pub funded_index:
|
||||||
LazyVecFrom1<FundedAddrIndex, FundedAddrIndex, FundedAddrIndex, FundedAddrData>,
|
LazyVecFrom1<FundedAddrIndex, FundedAddrIndex, FundedAddrIndex, FundedAddrData>,
|
||||||
@@ -170,6 +172,9 @@ impl Vecs {
|
|||||||
// Growth rate: delta change + rate (global + per-type)
|
// Growth rate: delta change + rate (global + per-type)
|
||||||
let delta = DeltaVecs::new(version, &addr_count, cached_starts, indexes);
|
let delta = DeltaVecs::new(version, &addr_count, cached_starts, indexes);
|
||||||
|
|
||||||
|
// Average amount (supply / utxo_count, supply / funded_addr_count) for `all` and per addr type.
|
||||||
|
let avg_amount = WithAddrTypes::<AvgAmountMetrics>::forced_import(&db, version, indexes)?;
|
||||||
|
|
||||||
let this = Self {
|
let this = Self {
|
||||||
supply_state: BytesVec::forced_import_with(
|
supply_state: BytesVec::forced_import_with(
|
||||||
vecdb::ImportOptions::new(&db, "supply_state", version)
|
vecdb::ImportOptions::new(&db, "supply_state", version)
|
||||||
@@ -185,6 +190,7 @@ impl Vecs {
|
|||||||
reused: reused_addr_count,
|
reused: reused_addr_count,
|
||||||
exposed: exposed_addr_vecs,
|
exposed: exposed_addr_vecs,
|
||||||
delta,
|
delta,
|
||||||
|
avg_amount,
|
||||||
funded_index: funded_addr_index,
|
funded_index: funded_addr_index,
|
||||||
empty_index: empty_addr_index,
|
empty_index: empty_addr_index,
|
||||||
},
|
},
|
||||||
@@ -302,6 +308,7 @@ impl Vecs {
|
|||||||
self.addrs.activity.reset_height()?;
|
self.addrs.activity.reset_height()?;
|
||||||
self.addrs.reused.reset_height()?;
|
self.addrs.reused.reset_height()?;
|
||||||
self.addrs.exposed.reset_height()?;
|
self.addrs.exposed.reset_height()?;
|
||||||
|
self.addrs.avg_amount.reset_height()?;
|
||||||
reset_state(
|
reset_state(
|
||||||
&mut self.any_addr_indexes,
|
&mut self.any_addr_indexes,
|
||||||
&mut self.addrs_data,
|
&mut self.addrs_data,
|
||||||
@@ -490,6 +497,34 @@ impl Vecs {
|
|||||||
exit,
|
exit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// Average amount (supply / utxo_count, supply / funded_addr_count) for `all` and per addr type.
|
||||||
|
let all_m = &self.utxo_cohorts.all.metrics;
|
||||||
|
self.addrs.avg_amount.all.compute(
|
||||||
|
prices,
|
||||||
|
&all_m.supply.total.sats.height,
|
||||||
|
&all_m.outputs.unspent_count.height,
|
||||||
|
&self.addrs.funded.all.height,
|
||||||
|
starting_indexes.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
for ((ot, avg), (_, funded)) in self
|
||||||
|
.addrs
|
||||||
|
.avg_amount
|
||||||
|
.by_addr_type
|
||||||
|
.iter_mut()
|
||||||
|
.zip(self.addrs.funded.by_addr_type.iter())
|
||||||
|
{
|
||||||
|
let type_m = &t.get(ot).metrics;
|
||||||
|
avg.compute(
|
||||||
|
prices,
|
||||||
|
&type_m.supply.total.sats.height,
|
||||||
|
&type_m.outputs.unspent_count.height,
|
||||||
|
&funded.height,
|
||||||
|
starting_indexes.height,
|
||||||
|
exit,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
// 6c. Compute total_addr_count = addr_count + empty_addr_count
|
// 6c. Compute total_addr_count = addr_count + empty_addr_count
|
||||||
self.addrs.total.compute(
|
self.addrs.total.compute(
|
||||||
starting_indexes.height,
|
starting_indexes.height,
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ impl<T: NumericValue + JsonSchema> PerBlockDistribution<T> {
|
|||||||
vec.push(zero);
|
vec.push(zero);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
weighted.sort_unstable_by(|a, b| a.0.cmp(&b.0));
|
weighted.sort_unstable_by_key(|a| a.0);
|
||||||
|
|
||||||
max.push(weighted.last().unwrap().0);
|
max.push(weighted.last().unwrap().0);
|
||||||
pct90.push(get_weighted_percentile(&weighted, 0.90));
|
pct90.push(get_weighted_percentile(&weighted, 0.90));
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ pub use derived::{
|
|||||||
RatioCents64, TimesSqrt,
|
RatioCents64, TimesSqrt,
|
||||||
};
|
};
|
||||||
pub use ratio::{
|
pub use ratio::{
|
||||||
RatioCentsBp32, RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32, RatioDiffCentsBps32,
|
RatioCentsBp16, RatioCentsBp32, RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32,
|
||||||
RatioDiffDollarsBps32, RatioDiffF32Bps32, RatioDollarsBp16, RatioDollarsBp32,
|
RatioDiffCentsBps32, RatioDiffDollarsBps32, RatioDiffF32Bps32, RatioDollarsBp16,
|
||||||
RatioDollarsBps32, RatioSatsBp16, RatioU64Bp16, RatioU64F32,
|
RatioDollarsBp32, RatioDollarsBps32, RatioSatsBp16, RatioU64Bp16, RatioU64F32,
|
||||||
};
|
};
|
||||||
pub use specialized::{
|
pub use specialized::{
|
||||||
BlockCountTarget1m, BlockCountTarget1w, BlockCountTarget1y, BlockCountTarget24h,
|
BlockCountTarget1m, BlockCountTarget1w, BlockCountTarget1y, BlockCountTarget24h,
|
||||||
|
|||||||
@@ -43,6 +43,19 @@ impl BinaryTransform<Cents, Cents, BasisPoints32> for RatioCentsBp32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct RatioCentsBp16;
|
||||||
|
|
||||||
|
impl BinaryTransform<Cents, Cents, BasisPoints16> for RatioCentsBp16 {
|
||||||
|
#[inline(always)]
|
||||||
|
fn apply(numerator: Cents, denominator: Cents) -> BasisPoints16 {
|
||||||
|
if denominator == Cents::ZERO {
|
||||||
|
BasisPoints16::ZERO
|
||||||
|
} else {
|
||||||
|
BasisPoints16::from(numerator.inner() as f64 / denominator.inner() as f64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct RatioDollarsBp16;
|
pub struct RatioDollarsBp16;
|
||||||
|
|
||||||
impl BinaryTransform<Dollars, Dollars, BasisPoints16> for RatioDollarsBp16 {
|
impl BinaryTransform<Dollars, Dollars, BasisPoints16> for RatioDollarsBp16 {
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ use super::{
|
|||||||
WindowStartVec, Windows,
|
WindowStartVec, Windows,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::distribution::metrics::AvgAmountMetrics;
|
||||||
|
|
||||||
/// `all` aggregate plus per-`AddrType` breakdown.
|
/// `all` aggregate plus per-`AddrType` breakdown.
|
||||||
#[derive(Clone, Traversable)]
|
#[derive(Clone, Traversable)]
|
||||||
pub struct WithAddrTypes<T> {
|
pub struct WithAddrTypes<T> {
|
||||||
@@ -246,6 +248,42 @@ impl WithAddrTypes<AmountPerBlock> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl WithAddrTypes<AvgAmountMetrics> {
|
||||||
|
pub(crate) fn forced_import(
|
||||||
|
db: &Database,
|
||||||
|
version: Version,
|
||||||
|
indexes: &indexes::Vecs,
|
||||||
|
) -> Result<Self> {
|
||||||
|
let all = AvgAmountMetrics::forced_import(db, "", version, indexes)?;
|
||||||
|
let by_addr_type = ByAddrType::new_with_name(|type_name| {
|
||||||
|
AvgAmountMetrics::forced_import(db, type_name, version, indexes)
|
||||||
|
})?;
|
||||||
|
Ok(Self { all, by_addr_type })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||||
|
let mut vecs = self.all.collect_vecs_mut();
|
||||||
|
for v in self.by_addr_type.values_mut() {
|
||||||
|
vecs.extend(v.collect_vecs_mut());
|
||||||
|
}
|
||||||
|
vecs
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn par_iter_height_mut(
|
||||||
|
&mut self,
|
||||||
|
) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||||
|
self.collect_vecs_mut().into_par_iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn reset_height(&mut self) -> Result<()> {
|
||||||
|
self.all.reset_height()?;
|
||||||
|
for v in self.by_addr_type.values_mut() {
|
||||||
|
v.reset_height()?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<B: BpsType> WithAddrTypes<PercentPerBlock<B>> {
|
impl<B: BpsType> WithAddrTypes<PercentPerBlock<B>> {
|
||||||
pub(crate) fn forced_import(
|
pub(crate) fn forced_import(
|
||||||
db: &Database,
|
db: &Database,
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::cmp::Reverse;
|
||||||
|
|
||||||
use super::{BLOCK_VSIZE, package::Package};
|
use super::{BLOCK_VSIZE, package::Package};
|
||||||
use crate::types::SelectedTx;
|
use crate::types::SelectedTx;
|
||||||
|
|
||||||
@@ -13,7 +15,7 @@ pub fn partition_into_blocks(
|
|||||||
mut packages: Vec<Package>,
|
mut packages: Vec<Package>,
|
||||||
num_blocks: usize,
|
num_blocks: usize,
|
||||||
) -> Vec<Vec<SelectedTx>> {
|
) -> Vec<Vec<SelectedTx>> {
|
||||||
packages.sort_unstable_by(|a, b| b.fee_rate.cmp(&a.fee_rate));
|
packages.sort_unstable_by_key(|p| Reverse(p.fee_rate));
|
||||||
|
|
||||||
let mut blocks: Vec<Vec<SelectedTx>> = Vec::with_capacity(num_blocks);
|
let mut blocks: Vec<Vec<SelectedTx>> = Vec::with_capacity(num_blocks);
|
||||||
let mut current_block: Vec<SelectedTx> = Vec::new();
|
let mut current_block: Vec<SelectedTx> = Vec::new();
|
||||||
|
|||||||
@@ -375,11 +375,7 @@ impl Query {
|
|||||||
slug: pool_slug,
|
slug: pool_slug,
|
||||||
miner_names,
|
miner_names,
|
||||||
},
|
},
|
||||||
avg_fee: Sats::from(if non_coinbase > 0 {
|
avg_fee: Sats::from(total_fees_u64.checked_div(non_coinbase).unwrap_or(0)),
|
||||||
total_fees_u64 / non_coinbase
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}),
|
|
||||||
avg_fee_rate: FeeRate::from((total_fees, VSize::from(vsize))),
|
avg_fee_rate: FeeRate::from((total_fees, VSize::from(vsize))),
|
||||||
coinbase_raw,
|
coinbase_raw,
|
||||||
coinbase_address,
|
coinbase_address,
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ impl BlockWindow {
|
|||||||
.prices
|
.prices
|
||||||
.spot.cents.height
|
.spot.cents.height
|
||||||
.collect_range_at(self.start, self.end);
|
.collect_range_at(self.start, self.end);
|
||||||
let read_start = self.start.saturating_sub(1).max(0);
|
let read_start = self.start.saturating_sub(1);
|
||||||
let all_cum = cumulative.collect_range_at(read_start, self.end);
|
let all_cum = cumulative.collect_range_at(read_start, self.end);
|
||||||
let offset = if self.start > 0 { 1 } else { 0 };
|
let offset = if self.start > 0 { 1 } else { 0 };
|
||||||
|
|
||||||
@@ -91,19 +91,19 @@ impl BlockWindow {
|
|||||||
while pos < total {
|
while pos < total {
|
||||||
let window_end = (pos + self.window).min(total);
|
let window_end = (pos + self.window).min(total);
|
||||||
let block_count = (window_end - pos) as u64;
|
let block_count = (window_end - pos) as u64;
|
||||||
if block_count > 0 {
|
let mid = (pos + window_end) / 2;
|
||||||
let mid = (pos + window_end) / 2;
|
let cum_end = all_cum[window_end - 1 + offset];
|
||||||
let cum_end = all_cum[window_end - 1 + offset];
|
let cum_start = if pos + offset > 0 {
|
||||||
let cum_start = if pos + offset > 0 {
|
all_cum[pos + offset - 1]
|
||||||
all_cum[pos + offset - 1]
|
} else {
|
||||||
} else {
|
Sats::ZERO
|
||||||
Sats::ZERO
|
};
|
||||||
};
|
let total_sats = cum_end - cum_start;
|
||||||
let total_sats = cum_end - cum_start;
|
if let Some(avg) = (*total_sats).checked_div(block_count) {
|
||||||
results.push(WindowAvg {
|
results.push(WindowAvg {
|
||||||
avg_height: Height::from(self.start + mid),
|
avg_height: Height::from(self.start + mid),
|
||||||
timestamp: all_ts[mid],
|
timestamp: all_ts[mid],
|
||||||
avg_value: Sats::from(*total_sats / block_count),
|
avg_value: Sats::from(avg),
|
||||||
usd: Dollars::from(all_prices[mid]),
|
usd: Dollars::from(all_prices[mid]),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::cmp::Reverse;
|
||||||
|
|
||||||
use brk_error::{Error, Result};
|
use brk_error::{Error, Result};
|
||||||
use brk_types::{
|
use brk_types::{
|
||||||
BlockInfoV1, Day1, Height, Pool, PoolBlockCounts, PoolBlockShares, PoolDetail, PoolDetailInfo,
|
BlockInfoV1, Day1, Height, Pool, PoolBlockCounts, PoolBlockShares, PoolDetail, PoolDetailInfo,
|
||||||
@@ -89,7 +91,7 @@ impl Query {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sort by block count descending
|
// Sort by block count descending
|
||||||
pool_data.sort_by(|a, b| b.1.cmp(&a.1));
|
pool_data.sort_by_key(|p| Reverse(p.1));
|
||||||
|
|
||||||
let total_blocks: u64 = pool_data.iter().map(|(_, count)| count).sum();
|
let total_blocks: u64 = pool_data.iter().map(|(_, count)| count).sum();
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
//! Run with:
|
//! Run with:
|
||||||
//! cargo run -p brk_rpc --example compare_backends --features corepc
|
//! cargo run -p brk_rpc --example compare_backends --features corepc
|
||||||
|
|
||||||
|
#[cfg(all(feature = "bitcoincore-rpc", feature = "corepc"))]
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
#[cfg(not(all(feature = "bitcoincore-rpc", feature = "corepc")))]
|
#[cfg(not(all(feature = "bitcoincore-rpc", feature = "corepc")))]
|
||||||
@@ -260,6 +261,7 @@ fn main() {
|
|||||||
println!("=== All checks passed ===");
|
println!("=== All checks passed ===");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(feature = "bitcoincore-rpc", feature = "corepc"))]
|
||||||
fn timed<T>(f: impl FnOnce() -> T) -> (Duration, T) {
|
fn timed<T>(f: impl FnOnce() -> T) -> (Duration, T) {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let result = f();
|
let result = f();
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#![allow(unreachable_patterns, reason = "P2PK65 and P2PK33 both serialize as 'p2pk'")]
|
||||||
|
|
||||||
use bitcoin::{AddressType, ScriptBuf, opcodes::all::OP_PUSHBYTES_2};
|
use bitcoin::{AddressType, ScriptBuf, opcodes::all::OP_PUSHBYTES_2};
|
||||||
use brk_error::Error;
|
use brk_error::Error;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use schemars::JsonSchema;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use vecdb::{CheckedSub, Formattable, Pco, SaturatingAdd};
|
use vecdb::{CheckedSub, Formattable, Pco, SaturatingAdd};
|
||||||
|
|
||||||
use crate::StoredF64;
|
use crate::{StoredF64, StoredU64};
|
||||||
|
|
||||||
use super::{Bitcoin, Cents, Dollars, Height};
|
use super::{Bitcoin, Cents, Dollars, Height};
|
||||||
|
|
||||||
@@ -204,35 +204,34 @@ impl Sum for Sats {
|
|||||||
|
|
||||||
impl Div<Dollars> for Sats {
|
impl Div<Dollars> for Sats {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
#[allow(clippy::suspicious_arithmetic_impl, reason = "cents-precision upscale before division")]
|
||||||
fn div(self, rhs: Dollars) -> Self::Output {
|
fn div(self, rhs: Dollars) -> Self::Output {
|
||||||
let raw_cents = u64::from(Cents::from(rhs));
|
let raw_cents = u64::from(Cents::from(rhs));
|
||||||
if raw_cents != 0 {
|
(self.0 * 100)
|
||||||
Self(self.0 * 100 / raw_cents)
|
.checked_div(raw_cents)
|
||||||
} else {
|
.map(Self)
|
||||||
Self::MAX
|
.unwrap_or(Self::MAX)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Div<Sats> for Sats {
|
impl Div<Sats> for Sats {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn div(self, rhs: Sats) -> Self::Output {
|
fn div(self, rhs: Sats) -> Self::Output {
|
||||||
if rhs.0 == 0 {
|
Self(self.0.checked_div(rhs.0).unwrap_or(0))
|
||||||
Self(0)
|
|
||||||
} else {
|
|
||||||
Self(self.0 / rhs.0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Div<usize> for Sats {
|
impl Div<usize> for Sats {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn div(self, rhs: usize) -> Self::Output {
|
fn div(self, rhs: usize) -> Self::Output {
|
||||||
if rhs == 0 {
|
Self(self.0.checked_div(rhs as u64).unwrap_or(0))
|
||||||
Self::ZERO
|
}
|
||||||
} else {
|
}
|
||||||
Self(self.0 / rhs as u64)
|
|
||||||
}
|
impl Div<StoredU64> for Sats {
|
||||||
|
type Output = Self;
|
||||||
|
fn div(self, rhs: StoredU64) -> Self::Output {
|
||||||
|
Self(self.0.checked_div(u64::from(rhs)).unwrap_or(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,10 +99,8 @@ fn sanitize(dirty: impl Iterator<Item = String>) -> Vec<String> {
|
|||||||
let mut current = String::new();
|
let mut current = String::new();
|
||||||
for c in s.to_lowercase().chars() {
|
for c in s.to_lowercase().chars() {
|
||||||
match c {
|
match c {
|
||||||
' ' | ',' | '+' => {
|
' ' | ',' | '+' if !current.is_empty() => {
|
||||||
if !current.is_empty() {
|
clean.push(mem::take(&mut current));
|
||||||
clean.push(mem::take(&mut current));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
'-' => current.push('_'),
|
'-' => current.push('_'),
|
||||||
c if c.is_alphanumeric() || c == '_' => current.push(c),
|
c if c.is_alphanumeric() || c == '_' => current.push(c),
|
||||||
|
|||||||
@@ -2301,7 +2301,7 @@ function createIndexPct0Pct1Pct2Pct5Pct95Pct98Pct99ScorePattern(client, acc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5
|
* @typedef {Object} AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6
|
||||||
* @property {AverageBlockCumulativeSumPattern<StoredU64>} all
|
* @property {AverageBlockCumulativeSumPattern<StoredU64>} all
|
||||||
* @property {AverageBlockCumulativeSumPattern<StoredU64>} p2a
|
* @property {AverageBlockCumulativeSumPattern<StoredU64>} p2a
|
||||||
* @property {AverageBlockCumulativeSumPattern<StoredU64>} p2pk33
|
* @property {AverageBlockCumulativeSumPattern<StoredU64>} p2pk33
|
||||||
@@ -2314,12 +2314,12 @@ function createIndexPct0Pct1Pct2Pct5Pct95Pct98Pct99ScorePattern(client, acc) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5 pattern node
|
* Create a AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6 pattern node
|
||||||
* @param {BrkClientBase} client
|
* @param {BrkClientBase} client
|
||||||
* @param {string} acc - Accumulated series name
|
* @param {string} acc - Accumulated series name
|
||||||
* @returns {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5}
|
* @returns {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6}
|
||||||
*/
|
*/
|
||||||
function createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5(client, acc) {
|
function createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6(client, acc) {
|
||||||
return {
|
return {
|
||||||
all: createAverageBlockCumulativeSumPattern(client, acc),
|
all: createAverageBlockCumulativeSumPattern(client, acc),
|
||||||
p2a: createAverageBlockCumulativeSumPattern(client, _p('p2a', acc)),
|
p2a: createAverageBlockCumulativeSumPattern(client, _p('p2a', acc)),
|
||||||
@@ -2334,7 +2334,7 @@ function createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5(client, acc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3
|
* @typedef {Object} AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4
|
||||||
* @property {SeriesPattern1<StoredU64>} all
|
* @property {SeriesPattern1<StoredU64>} all
|
||||||
* @property {SeriesPattern1<StoredU64>} p2a
|
* @property {SeriesPattern1<StoredU64>} p2a
|
||||||
* @property {SeriesPattern1<StoredU64>} p2pk33
|
* @property {SeriesPattern1<StoredU64>} p2pk33
|
||||||
@@ -2347,12 +2347,12 @@ function createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5(client, acc) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3 pattern node
|
* Create a AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4 pattern node
|
||||||
* @param {BrkClientBase} client
|
* @param {BrkClientBase} client
|
||||||
* @param {string} acc - Accumulated series name
|
* @param {string} acc - Accumulated series name
|
||||||
* @returns {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3}
|
* @returns {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4}
|
||||||
*/
|
*/
|
||||||
function createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(client, acc) {
|
function createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4(client, acc) {
|
||||||
return {
|
return {
|
||||||
all: createSeriesPattern1(client, acc),
|
all: createSeriesPattern1(client, acc),
|
||||||
p2a: createSeriesPattern1(client, _p('p2a', acc)),
|
p2a: createSeriesPattern1(client, _p('p2a', acc)),
|
||||||
@@ -2367,7 +2367,7 @@ function createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(client, acc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6
|
* @typedef {Object} AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7
|
||||||
* @property {_1m1w1y24hBpsPercentRatioPattern} all
|
* @property {_1m1w1y24hBpsPercentRatioPattern} all
|
||||||
* @property {_1m1w1y24hBpsPercentRatioPattern} p2a
|
* @property {_1m1w1y24hBpsPercentRatioPattern} p2a
|
||||||
* @property {_1m1w1y24hBpsPercentRatioPattern} p2pk33
|
* @property {_1m1w1y24hBpsPercentRatioPattern} p2pk33
|
||||||
@@ -2380,12 +2380,12 @@ function createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(client, acc) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6 pattern node
|
* Create a AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7 pattern node
|
||||||
* @param {BrkClientBase} client
|
* @param {BrkClientBase} client
|
||||||
* @param {string} acc - Accumulated series name
|
* @param {string} acc - Accumulated series name
|
||||||
* @returns {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6}
|
* @returns {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7}
|
||||||
*/
|
*/
|
||||||
function createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6(client, acc) {
|
function createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7(client, acc) {
|
||||||
return {
|
return {
|
||||||
all: create_1m1w1y24hBpsPercentRatioPattern(client, acc),
|
all: create_1m1w1y24hBpsPercentRatioPattern(client, acc),
|
||||||
p2a: create_1m1w1y24hBpsPercentRatioPattern(client, _p('p2a', acc)),
|
p2a: create_1m1w1y24hBpsPercentRatioPattern(client, _p('p2a', acc)),
|
||||||
@@ -2437,7 +2437,7 @@ function createAverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern(client, acc) {
|
|||||||
* @property {SeriesPattern18<CentsSquaredSats>} capitalizedCapInLossRaw
|
* @property {SeriesPattern18<CentsSquaredSats>} capitalizedCapInLossRaw
|
||||||
* @property {SeriesPattern18<CentsSquaredSats>} capitalizedCapInProfitRaw
|
* @property {SeriesPattern18<CentsSquaredSats>} capitalizedCapInProfitRaw
|
||||||
* @property {CentsUsdPattern3} grossPnl
|
* @property {CentsUsdPattern3} grossPnl
|
||||||
* @property {InPattern} investedCapital
|
* @property {InPattern2} investedCapital
|
||||||
* @property {CentsNegativeToUsdPattern2} loss
|
* @property {CentsNegativeToUsdPattern2} loss
|
||||||
* @property {CentsToUsdPattern3} netPnl
|
* @property {CentsToUsdPattern3} netPnl
|
||||||
* @property {BpsRatioPattern} nupl
|
* @property {BpsRatioPattern} nupl
|
||||||
@@ -2456,7 +2456,7 @@ function createCapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2(client
|
|||||||
capitalizedCapInLossRaw: createSeriesPattern18(client, _m(acc, 'capitalized_cap_in_loss_raw')),
|
capitalizedCapInLossRaw: createSeriesPattern18(client, _m(acc, 'capitalized_cap_in_loss_raw')),
|
||||||
capitalizedCapInProfitRaw: createSeriesPattern18(client, _m(acc, 'capitalized_cap_in_profit_raw')),
|
capitalizedCapInProfitRaw: createSeriesPattern18(client, _m(acc, 'capitalized_cap_in_profit_raw')),
|
||||||
grossPnl: createCentsUsdPattern3(client, _m(acc, 'unrealized_gross_pnl')),
|
grossPnl: createCentsUsdPattern3(client, _m(acc, 'unrealized_gross_pnl')),
|
||||||
investedCapital: createInPattern(client, _m(acc, 'invested_capital_in')),
|
investedCapital: createInPattern2(client, _m(acc, 'invested_capital_in')),
|
||||||
loss: createCentsNegativeToUsdPattern2(client, _m(acc, 'unrealized_loss')),
|
loss: createCentsNegativeToUsdPattern2(client, _m(acc, 'unrealized_loss')),
|
||||||
netPnl: createCentsToUsdPattern3(client, _m(acc, 'net_unrealized_pnl')),
|
netPnl: createCentsToUsdPattern3(client, _m(acc, 'net_unrealized_pnl')),
|
||||||
nupl: createBpsRatioPattern(client, _m(acc, 'nupl')),
|
nupl: createBpsRatioPattern(client, _m(acc, 'nupl')),
|
||||||
@@ -3028,7 +3028,7 @@ function createActivityOutputsRealizedSupplyUnrealizedPattern2(client, acc) {
|
|||||||
/**
|
/**
|
||||||
* @typedef {Object} BlockChangeCumulativeDeltaSumPattern
|
* @typedef {Object} BlockChangeCumulativeDeltaSumPattern
|
||||||
* @property {CentsUsdPattern4} block
|
* @property {CentsUsdPattern4} block
|
||||||
* @property {ToPattern} change1m
|
* @property {ToPattern2} change1m
|
||||||
* @property {CentsUsdPattern} cumulative
|
* @property {CentsUsdPattern} cumulative
|
||||||
* @property {AbsoluteRatePattern2} delta
|
* @property {AbsoluteRatePattern2} delta
|
||||||
* @property {_1m1w1y24hPattern5} sum
|
* @property {_1m1w1y24hPattern5} sum
|
||||||
@@ -3043,7 +3043,7 @@ function createActivityOutputsRealizedSupplyUnrealizedPattern2(client, acc) {
|
|||||||
function createBlockChangeCumulativeDeltaSumPattern(client, acc) {
|
function createBlockChangeCumulativeDeltaSumPattern(client, acc) {
|
||||||
return {
|
return {
|
||||||
block: createCentsUsdPattern4(client, _m(acc, 'realized_pnl')),
|
block: createCentsUsdPattern4(client, _m(acc, 'realized_pnl')),
|
||||||
change1m: createToPattern(client, _m(acc, 'pnl_change_1m_to')),
|
change1m: createToPattern2(client, _m(acc, 'pnl_change_1m_to')),
|
||||||
cumulative: createCentsUsdPattern(client, _m(acc, 'realized_pnl_cumulative')),
|
cumulative: createCentsUsdPattern(client, _m(acc, 'realized_pnl_cumulative')),
|
||||||
delta: createAbsoluteRatePattern2(client, _m(acc, 'realized_pnl_delta')),
|
delta: createAbsoluteRatePattern2(client, _m(acc, 'realized_pnl_delta')),
|
||||||
sum: create_1m1w1y24hPattern5(client, _m(acc, 'realized_pnl_sum')),
|
sum: create_1m1w1y24hPattern5(client, _m(acc, 'realized_pnl_sum')),
|
||||||
@@ -4195,6 +4195,25 @@ function createAbsoluteRatePattern2(client, acc) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} AddrUtxoPattern
|
||||||
|
* @property {BtcCentsSatsUsdPattern} addr
|
||||||
|
* @property {BtcCentsSatsUsdPattern} utxo
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a AddrUtxoPattern pattern node
|
||||||
|
* @param {BrkClientBase} client
|
||||||
|
* @param {string} acc - Accumulated series name
|
||||||
|
* @returns {AddrUtxoPattern}
|
||||||
|
*/
|
||||||
|
function createAddrUtxoPattern(client, acc) {
|
||||||
|
return {
|
||||||
|
addr: createBtcCentsSatsUsdPattern(client, _m(acc, 'addr_amount')),
|
||||||
|
utxo: createBtcCentsSatsUsdPattern(client, _m(acc, 'utxo_amount')),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} AllSthPattern2
|
* @typedef {Object} AllSthPattern2
|
||||||
* @property {BtcCentsDeltaSatsUsdPattern} all
|
* @property {BtcCentsDeltaSatsUsdPattern} all
|
||||||
@@ -4464,8 +4483,8 @@ function createDeltaTotalPattern(client, acc) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} FundedTotalPattern
|
* @typedef {Object} FundedTotalPattern
|
||||||
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3} funded
|
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4} funded
|
||||||
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3} total
|
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4} total
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -4476,15 +4495,34 @@ function createDeltaTotalPattern(client, acc) {
|
|||||||
*/
|
*/
|
||||||
function createFundedTotalPattern(client, acc) {
|
function createFundedTotalPattern(client, acc) {
|
||||||
return {
|
return {
|
||||||
funded: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(client, acc),
|
funded: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4(client, acc),
|
||||||
total: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(client, _p('total', acc)),
|
total: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4(client, _p('total', acc)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} InPattern2
|
||||||
|
* @property {CentsUsdPattern3} inLoss
|
||||||
|
* @property {CentsUsdPattern3} inProfit
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a InPattern2 pattern node
|
||||||
|
* @param {BrkClientBase} client
|
||||||
|
* @param {string} acc - Accumulated series name
|
||||||
|
* @returns {InPattern2}
|
||||||
|
*/
|
||||||
|
function createInPattern2(client, acc) {
|
||||||
|
return {
|
||||||
|
inLoss: createCentsUsdPattern3(client, _m(acc, 'loss')),
|
||||||
|
inProfit: createCentsUsdPattern3(client, _m(acc, 'profit')),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} InPattern
|
* @typedef {Object} InPattern
|
||||||
* @property {CentsUsdPattern3} inLoss
|
* @property {ToPattern} inLoss
|
||||||
* @property {CentsUsdPattern3} inProfit
|
* @property {ToPattern} inProfit
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -4495,8 +4533,8 @@ function createFundedTotalPattern(client, acc) {
|
|||||||
*/
|
*/
|
||||||
function createInPattern(client, acc) {
|
function createInPattern(client, acc) {
|
||||||
return {
|
return {
|
||||||
inLoss: createCentsUsdPattern3(client, _m(acc, 'loss')),
|
inLoss: createToPattern(client, _m(acc, 'loss_to_own')),
|
||||||
inProfit: createCentsUsdPattern3(client, _m(acc, 'profit')),
|
inProfit: createToPattern(client, _m(acc, 'profit_to_own')),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4565,18 +4603,18 @@ function createRatioValuePattern(client, acc) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} ToPattern
|
* @typedef {Object} ToPattern2
|
||||||
* @property {BpsPercentRatioPattern} toMcap
|
* @property {BpsPercentRatioPattern} toMcap
|
||||||
* @property {BpsPercentRatioPattern} toRcap
|
* @property {BpsPercentRatioPattern} toRcap
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a ToPattern pattern node
|
* Create a ToPattern2 pattern node
|
||||||
* @param {BrkClientBase} client
|
* @param {BrkClientBase} client
|
||||||
* @param {string} acc - Accumulated series name
|
* @param {string} acc - Accumulated series name
|
||||||
* @returns {ToPattern}
|
* @returns {ToPattern2}
|
||||||
*/
|
*/
|
||||||
function createToPattern(client, acc) {
|
function createToPattern2(client, acc) {
|
||||||
return {
|
return {
|
||||||
toMcap: createBpsPercentRatioPattern(client, _m(acc, 'mcap')),
|
toMcap: createBpsPercentRatioPattern(client, _m(acc, 'mcap')),
|
||||||
toRcap: createBpsPercentRatioPattern(client, _m(acc, 'rcap')),
|
toRcap: createBpsPercentRatioPattern(client, _m(acc, 'rcap')),
|
||||||
@@ -4634,6 +4672,23 @@ function createPricePattern(client, acc) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} ToPattern
|
||||||
|
* @property {BpsPercentRatioPattern2} toOwn
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a ToPattern pattern node
|
||||||
|
* @param {BrkClientBase} client
|
||||||
|
* @param {string} acc - Accumulated series name
|
||||||
|
* @returns {ToPattern}
|
||||||
|
*/
|
||||||
|
function createToPattern(client, acc) {
|
||||||
|
return {
|
||||||
|
toOwn: createBpsPercentRatioPattern2(client, acc),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} TransferPattern
|
* @typedef {Object} TransferPattern
|
||||||
* @property {AverageBlockCumulativeSumPattern3} transferVolume
|
* @property {AverageBlockCumulativeSumPattern3} transferVolume
|
||||||
@@ -5028,14 +5083,15 @@ function createTransferPattern(client, acc) {
|
|||||||
* @property {SeriesTree_Addrs_Raw} raw
|
* @property {SeriesTree_Addrs_Raw} raw
|
||||||
* @property {SeriesTree_Addrs_Indexes} indexes
|
* @property {SeriesTree_Addrs_Indexes} indexes
|
||||||
* @property {SeriesTree_Addrs_Data} data
|
* @property {SeriesTree_Addrs_Data} data
|
||||||
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3} funded
|
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4} funded
|
||||||
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3} empty
|
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4} empty
|
||||||
* @property {SeriesTree_Addrs_Activity} activity
|
* @property {SeriesTree_Addrs_Activity} activity
|
||||||
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3} total
|
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4} total
|
||||||
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5} new
|
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6} new
|
||||||
* @property {SeriesTree_Addrs_Reused} reused
|
* @property {SeriesTree_Addrs_Reused} reused
|
||||||
* @property {SeriesTree_Addrs_Exposed} exposed
|
* @property {SeriesTree_Addrs_Exposed} exposed
|
||||||
* @property {SeriesTree_Addrs_Delta} delta
|
* @property {SeriesTree_Addrs_Delta} delta
|
||||||
|
* @property {SeriesTree_Addrs_AvgAmount} avgAmount
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -5148,11 +5204,11 @@ function createTransferPattern(client, acc) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} SeriesTree_Addrs_Reused_Events
|
* @typedef {Object} SeriesTree_Addrs_Reused_Events
|
||||||
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5} outputToReusedAddrCount
|
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6} outputToReusedAddrCount
|
||||||
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6} outputToReusedAddrShare
|
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7} outputToReusedAddrShare
|
||||||
* @property {_1m1w1y24hBpsPercentRatioPattern} spendableOutputToReusedAddrShare
|
* @property {_1m1w1y24hBpsPercentRatioPattern} spendableOutputToReusedAddrShare
|
||||||
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5} inputFromReusedAddrCount
|
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6} inputFromReusedAddrCount
|
||||||
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6} inputFromReusedAddrShare
|
* @property {AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7} inputFromReusedAddrShare
|
||||||
* @property {_1m1w1y24hBlockPattern} activeReusedAddrCount
|
* @property {_1m1w1y24hBlockPattern} activeReusedAddrCount
|
||||||
* @property {SeriesTree_Addrs_Reused_Events_ActiveReusedAddrShare} activeReusedAddrShare
|
* @property {SeriesTree_Addrs_Reused_Events_ActiveReusedAddrShare} activeReusedAddrShare
|
||||||
*/
|
*/
|
||||||
@@ -5212,6 +5268,19 @@ function createTransferPattern(client, acc) {
|
|||||||
* @property {AbsoluteRatePattern} p2a
|
* @property {AbsoluteRatePattern} p2a
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} SeriesTree_Addrs_AvgAmount
|
||||||
|
* @property {AddrUtxoPattern} all
|
||||||
|
* @property {AddrUtxoPattern} p2pk65
|
||||||
|
* @property {AddrUtxoPattern} p2pk33
|
||||||
|
* @property {AddrUtxoPattern} p2pkh
|
||||||
|
* @property {AddrUtxoPattern} p2sh
|
||||||
|
* @property {AddrUtxoPattern} p2wpkh
|
||||||
|
* @property {AddrUtxoPattern} p2wsh
|
||||||
|
* @property {AddrUtxoPattern} p2tr
|
||||||
|
* @property {AddrUtxoPattern} p2a
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} SeriesTree_Scripts
|
* @typedef {Object} SeriesTree_Scripts
|
||||||
* @property {SeriesTree_Scripts_Raw} raw
|
* @property {SeriesTree_Scripts_Raw} raw
|
||||||
@@ -6237,6 +6306,7 @@ function createTransferPattern(client, acc) {
|
|||||||
* @property {SeriesTree_Cohorts_Utxo_All_Realized} realized
|
* @property {SeriesTree_Cohorts_Utxo_All_Realized} realized
|
||||||
* @property {SeriesTree_Cohorts_Utxo_All_CostBasis} costBasis
|
* @property {SeriesTree_Cohorts_Utxo_All_CostBasis} costBasis
|
||||||
* @property {SeriesTree_Cohorts_Utxo_All_Unrealized} unrealized
|
* @property {SeriesTree_Cohorts_Utxo_All_Unrealized} unrealized
|
||||||
|
* @property {InPattern} investedCapital
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -6407,7 +6477,7 @@ function createTransferPattern(client, acc) {
|
|||||||
* @property {SeriesTree_Cohorts_Utxo_All_Unrealized_Loss} loss
|
* @property {SeriesTree_Cohorts_Utxo_All_Unrealized_Loss} loss
|
||||||
* @property {SeriesTree_Cohorts_Utxo_All_Unrealized_NetPnl} netPnl
|
* @property {SeriesTree_Cohorts_Utxo_All_Unrealized_NetPnl} netPnl
|
||||||
* @property {CentsUsdPattern3} grossPnl
|
* @property {CentsUsdPattern3} grossPnl
|
||||||
* @property {InPattern} investedCapital
|
* @property {InPattern2} investedCapital
|
||||||
* @property {SeriesPattern18<CentsSquaredSats>} capitalizedCapInProfitRaw
|
* @property {SeriesPattern18<CentsSquaredSats>} capitalizedCapInProfitRaw
|
||||||
* @property {SeriesPattern18<CentsSquaredSats>} capitalizedCapInLossRaw
|
* @property {SeriesPattern18<CentsSquaredSats>} capitalizedCapInLossRaw
|
||||||
* @property {SeriesTree_Cohorts_Utxo_All_Unrealized_Sentiment} sentiment
|
* @property {SeriesTree_Cohorts_Utxo_All_Unrealized_Sentiment} sentiment
|
||||||
@@ -6452,6 +6522,7 @@ function createTransferPattern(client, acc) {
|
|||||||
* @property {SeriesTree_Cohorts_Utxo_Sth_Realized} realized
|
* @property {SeriesTree_Cohorts_Utxo_Sth_Realized} realized
|
||||||
* @property {InMaxMinPerSupplyPattern} costBasis
|
* @property {InMaxMinPerSupplyPattern} costBasis
|
||||||
* @property {CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2} unrealized
|
* @property {CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2} unrealized
|
||||||
|
* @property {InPattern} investedCapital
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -6574,6 +6645,7 @@ function createTransferPattern(client, acc) {
|
|||||||
* @property {SeriesTree_Cohorts_Utxo_Lth_Realized} realized
|
* @property {SeriesTree_Cohorts_Utxo_Lth_Realized} realized
|
||||||
* @property {InMaxMinPerSupplyPattern} costBasis
|
* @property {InMaxMinPerSupplyPattern} costBasis
|
||||||
* @property {CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2} unrealized
|
* @property {CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2} unrealized
|
||||||
|
* @property {InPattern} investedCapital
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -8515,8 +8587,8 @@ class BrkClient extends BrkClientBase {
|
|||||||
funded: createSeriesPattern34(this, 'funded_addr_data'),
|
funded: createSeriesPattern34(this, 'funded_addr_data'),
|
||||||
empty: createSeriesPattern35(this, 'empty_addr_data'),
|
empty: createSeriesPattern35(this, 'empty_addr_data'),
|
||||||
},
|
},
|
||||||
funded: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(this, 'addr_count'),
|
funded: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4(this, 'addr_count'),
|
||||||
empty: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(this, 'empty_addr_count'),
|
empty: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4(this, 'empty_addr_count'),
|
||||||
activity: {
|
activity: {
|
||||||
all: {
|
all: {
|
||||||
reactivated: create_1m1w1y24hBlockPattern(this, 'reactivated_addrs'),
|
reactivated: create_1m1w1y24hBlockPattern(this, 'reactivated_addrs'),
|
||||||
@@ -8534,16 +8606,16 @@ class BrkClient extends BrkClientBase {
|
|||||||
p2tr: createActiveBidirectionalReactivatedReceivingSendingPattern(this, 'p2tr'),
|
p2tr: createActiveBidirectionalReactivatedReceivingSendingPattern(this, 'p2tr'),
|
||||||
p2a: createActiveBidirectionalReactivatedReceivingSendingPattern(this, 'p2a'),
|
p2a: createActiveBidirectionalReactivatedReceivingSendingPattern(this, 'p2a'),
|
||||||
},
|
},
|
||||||
total: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(this, 'total_addr_count'),
|
total: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4(this, 'total_addr_count'),
|
||||||
new: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5(this, 'new_addr_count'),
|
new: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6(this, 'new_addr_count'),
|
||||||
reused: {
|
reused: {
|
||||||
count: createFundedTotalPattern(this, 'reused_addr_count'),
|
count: createFundedTotalPattern(this, 'reused_addr_count'),
|
||||||
events: {
|
events: {
|
||||||
outputToReusedAddrCount: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5(this, 'output_to_reused_addr_count'),
|
outputToReusedAddrCount: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6(this, 'output_to_reused_addr_count'),
|
||||||
outputToReusedAddrShare: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6(this, 'output_to_reused_addr_share'),
|
outputToReusedAddrShare: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7(this, 'output_to_reused_addr_share'),
|
||||||
spendableOutputToReusedAddrShare: create_1m1w1y24hBpsPercentRatioPattern(this, 'spendable_output_to_reused_addr_share'),
|
spendableOutputToReusedAddrShare: create_1m1w1y24hBpsPercentRatioPattern(this, 'spendable_output_to_reused_addr_share'),
|
||||||
inputFromReusedAddrCount: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5(this, 'input_from_reused_addr_count'),
|
inputFromReusedAddrCount: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6(this, 'input_from_reused_addr_count'),
|
||||||
inputFromReusedAddrShare: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6(this, 'input_from_reused_addr_share'),
|
inputFromReusedAddrShare: createAllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7(this, 'input_from_reused_addr_share'),
|
||||||
activeReusedAddrCount: create_1m1w1y24hBlockPattern(this, 'active_reused_addr_count'),
|
activeReusedAddrCount: create_1m1w1y24hBlockPattern(this, 'active_reused_addr_count'),
|
||||||
activeReusedAddrShare: {
|
activeReusedAddrShare: {
|
||||||
block: createSeriesPattern18(this, 'active_reused_addr_share'),
|
block: createSeriesPattern18(this, 'active_reused_addr_share'),
|
||||||
@@ -8590,6 +8662,17 @@ class BrkClient extends BrkClientBase {
|
|||||||
p2tr: createAbsoluteRatePattern(this, 'p2tr_addr_count'),
|
p2tr: createAbsoluteRatePattern(this, 'p2tr_addr_count'),
|
||||||
p2a: createAbsoluteRatePattern(this, 'p2a_addr_count'),
|
p2a: createAbsoluteRatePattern(this, 'p2a_addr_count'),
|
||||||
},
|
},
|
||||||
|
avgAmount: {
|
||||||
|
all: createAddrUtxoPattern(this, 'avg'),
|
||||||
|
p2pk65: createAddrUtxoPattern(this, 'p2pk65_avg'),
|
||||||
|
p2pk33: createAddrUtxoPattern(this, 'p2pk33_avg'),
|
||||||
|
p2pkh: createAddrUtxoPattern(this, 'p2pkh_avg'),
|
||||||
|
p2sh: createAddrUtxoPattern(this, 'p2sh_avg'),
|
||||||
|
p2wpkh: createAddrUtxoPattern(this, 'p2wpkh_avg'),
|
||||||
|
p2wsh: createAddrUtxoPattern(this, 'p2wsh_avg'),
|
||||||
|
p2tr: createAddrUtxoPattern(this, 'p2tr_avg'),
|
||||||
|
p2a: createAddrUtxoPattern(this, 'p2a_avg'),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
scripts: {
|
scripts: {
|
||||||
raw: {
|
raw: {
|
||||||
@@ -9452,7 +9535,7 @@ class BrkClient extends BrkClientBase {
|
|||||||
toOwnGrossPnl: createBpsPercentRatioPattern(this, 'net_unrealized_pnl_to_own_gross_pnl'),
|
toOwnGrossPnl: createBpsPercentRatioPattern(this, 'net_unrealized_pnl_to_own_gross_pnl'),
|
||||||
},
|
},
|
||||||
grossPnl: createCentsUsdPattern3(this, 'unrealized_gross_pnl'),
|
grossPnl: createCentsUsdPattern3(this, 'unrealized_gross_pnl'),
|
||||||
investedCapital: createInPattern(this, 'invested_capital_in'),
|
investedCapital: createInPattern2(this, 'invested_capital_in'),
|
||||||
capitalizedCapInProfitRaw: createSeriesPattern18(this, 'capitalized_cap_in_profit_raw'),
|
capitalizedCapInProfitRaw: createSeriesPattern18(this, 'capitalized_cap_in_profit_raw'),
|
||||||
capitalizedCapInLossRaw: createSeriesPattern18(this, 'capitalized_cap_in_loss_raw'),
|
capitalizedCapInLossRaw: createSeriesPattern18(this, 'capitalized_cap_in_loss_raw'),
|
||||||
sentiment: {
|
sentiment: {
|
||||||
@@ -9461,6 +9544,7 @@ class BrkClient extends BrkClientBase {
|
|||||||
net: createCentsUsdPattern(this, 'net_sentiment'),
|
net: createCentsUsdPattern(this, 'net_sentiment'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
investedCapital: createInPattern(this, 'invested_capital_in'),
|
||||||
},
|
},
|
||||||
sth: {
|
sth: {
|
||||||
supply: createDeltaHalfInToTotalPattern2(this, 'sth_supply'),
|
supply: createDeltaHalfInToTotalPattern2(this, 'sth_supply'),
|
||||||
@@ -9560,6 +9644,7 @@ class BrkClient extends BrkClientBase {
|
|||||||
},
|
},
|
||||||
costBasis: createInMaxMinPerSupplyPattern(this, 'sth'),
|
costBasis: createInMaxMinPerSupplyPattern(this, 'sth'),
|
||||||
unrealized: createCapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2(this, 'sth'),
|
unrealized: createCapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2(this, 'sth'),
|
||||||
|
investedCapital: createInPattern(this, 'sth_invested_capital_in'),
|
||||||
},
|
},
|
||||||
lth: {
|
lth: {
|
||||||
supply: createDeltaHalfInToTotalPattern2(this, 'lth_supply'),
|
supply: createDeltaHalfInToTotalPattern2(this, 'lth_supply'),
|
||||||
@@ -9662,6 +9747,7 @@ class BrkClient extends BrkClientBase {
|
|||||||
},
|
},
|
||||||
costBasis: createInMaxMinPerSupplyPattern(this, 'lth'),
|
costBasis: createInMaxMinPerSupplyPattern(this, 'lth'),
|
||||||
unrealized: createCapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2(this, 'lth'),
|
unrealized: createCapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2(this, 'lth'),
|
||||||
|
investedCapital: createInPattern(this, 'lth_invested_capital_in'),
|
||||||
},
|
},
|
||||||
ageRange: {
|
ageRange: {
|
||||||
under1h: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_under_1h_old'),
|
under1h: createActivityOutputsRealizedSupplyUnrealizedPattern(this, 'utxos_under_1h_old'),
|
||||||
|
|||||||
@@ -2738,7 +2738,7 @@ class IndexPct0Pct1Pct2Pct5Pct95Pct98Pct99ScorePattern:
|
|||||||
self.pct99_5: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'pct99_5'))
|
self.pct99_5: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'pct99_5'))
|
||||||
self.score: SeriesPattern1[StoredI8] = SeriesPattern1(client, _m(acc, 'score'))
|
self.score: SeriesPattern1[StoredI8] = SeriesPattern1(client, _m(acc, 'score'))
|
||||||
|
|
||||||
class AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5:
|
class AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, acc: str):
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
@@ -2753,7 +2753,7 @@ class AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5:
|
|||||||
self.p2wpkh: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, _p('p2wpkh', acc))
|
self.p2wpkh: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, _p('p2wpkh', acc))
|
||||||
self.p2wsh: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, _p('p2wsh', acc))
|
self.p2wsh: AverageBlockCumulativeSumPattern[StoredU64] = AverageBlockCumulativeSumPattern(client, _p('p2wsh', acc))
|
||||||
|
|
||||||
class AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3:
|
class AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, acc: str):
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
@@ -2768,7 +2768,7 @@ class AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3:
|
|||||||
self.p2wpkh: SeriesPattern1[StoredU64] = SeriesPattern1(client, _p('p2wpkh', acc))
|
self.p2wpkh: SeriesPattern1[StoredU64] = SeriesPattern1(client, _p('p2wpkh', acc))
|
||||||
self.p2wsh: SeriesPattern1[StoredU64] = SeriesPattern1(client, _p('p2wsh', acc))
|
self.p2wsh: SeriesPattern1[StoredU64] = SeriesPattern1(client, _p('p2wsh', acc))
|
||||||
|
|
||||||
class AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6:
|
class AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, acc: str):
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
@@ -2806,7 +2806,7 @@ class CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2:
|
|||||||
self.capitalized_cap_in_loss_raw: SeriesPattern18[CentsSquaredSats] = SeriesPattern18(client, _m(acc, 'capitalized_cap_in_loss_raw'))
|
self.capitalized_cap_in_loss_raw: SeriesPattern18[CentsSquaredSats] = SeriesPattern18(client, _m(acc, 'capitalized_cap_in_loss_raw'))
|
||||||
self.capitalized_cap_in_profit_raw: SeriesPattern18[CentsSquaredSats] = SeriesPattern18(client, _m(acc, 'capitalized_cap_in_profit_raw'))
|
self.capitalized_cap_in_profit_raw: SeriesPattern18[CentsSquaredSats] = SeriesPattern18(client, _m(acc, 'capitalized_cap_in_profit_raw'))
|
||||||
self.gross_pnl: CentsUsdPattern3 = CentsUsdPattern3(client, _m(acc, 'unrealized_gross_pnl'))
|
self.gross_pnl: CentsUsdPattern3 = CentsUsdPattern3(client, _m(acc, 'unrealized_gross_pnl'))
|
||||||
self.invested_capital: InPattern = InPattern(client, _m(acc, 'invested_capital_in'))
|
self.invested_capital: InPattern2 = InPattern2(client, _m(acc, 'invested_capital_in'))
|
||||||
self.loss: CentsNegativeToUsdPattern2 = CentsNegativeToUsdPattern2(client, _m(acc, 'unrealized_loss'))
|
self.loss: CentsNegativeToUsdPattern2 = CentsNegativeToUsdPattern2(client, _m(acc, 'unrealized_loss'))
|
||||||
self.net_pnl: CentsToUsdPattern3 = CentsToUsdPattern3(client, _m(acc, 'net_unrealized_pnl'))
|
self.net_pnl: CentsToUsdPattern3 = CentsToUsdPattern3(client, _m(acc, 'net_unrealized_pnl'))
|
||||||
self.nupl: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'nupl'))
|
self.nupl: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'nupl'))
|
||||||
@@ -3066,7 +3066,7 @@ class BlockChangeCumulativeDeltaSumPattern:
|
|||||||
def __init__(self, client: BrkClientBase, acc: str):
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
"""Create pattern node with accumulated series name."""
|
"""Create pattern node with accumulated series name."""
|
||||||
self.block: CentsUsdPattern4 = CentsUsdPattern4(client, _m(acc, 'realized_pnl'))
|
self.block: CentsUsdPattern4 = CentsUsdPattern4(client, _m(acc, 'realized_pnl'))
|
||||||
self.change_1m: ToPattern = ToPattern(client, _m(acc, 'pnl_change_1m_to'))
|
self.change_1m: ToPattern2 = ToPattern2(client, _m(acc, 'pnl_change_1m_to'))
|
||||||
self.cumulative: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'realized_pnl_cumulative'))
|
self.cumulative: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'realized_pnl_cumulative'))
|
||||||
self.delta: AbsoluteRatePattern2 = AbsoluteRatePattern2(client, _m(acc, 'realized_pnl_delta'))
|
self.delta: AbsoluteRatePattern2 = AbsoluteRatePattern2(client, _m(acc, 'realized_pnl_delta'))
|
||||||
self.sum: _1m1w1y24hPattern5 = _1m1w1y24hPattern5(client, _m(acc, 'realized_pnl_sum'))
|
self.sum: _1m1w1y24hPattern5 = _1m1w1y24hPattern5(client, _m(acc, 'realized_pnl_sum'))
|
||||||
@@ -3564,6 +3564,14 @@ class AbsoluteRatePattern2:
|
|||||||
self.absolute: _1m1w1y24hPattern5 = _1m1w1y24hPattern5(client, acc)
|
self.absolute: _1m1w1y24hPattern5 = _1m1w1y24hPattern5(client, acc)
|
||||||
self.rate: _1m1w1y24hPattern2 = _1m1w1y24hPattern2(client, acc)
|
self.rate: _1m1w1y24hPattern2 = _1m1w1y24hPattern2(client, acc)
|
||||||
|
|
||||||
|
class AddrUtxoPattern:
|
||||||
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
|
"""Create pattern node with accumulated series name."""
|
||||||
|
self.addr: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'addr_amount'))
|
||||||
|
self.utxo: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'utxo_amount'))
|
||||||
|
|
||||||
class AllSthPattern2:
|
class AllSthPattern2:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
@@ -3681,10 +3689,10 @@ class FundedTotalPattern:
|
|||||||
|
|
||||||
def __init__(self, client: BrkClientBase, acc: str):
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
"""Create pattern node with accumulated series name."""
|
"""Create pattern node with accumulated series name."""
|
||||||
self.funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(client, acc)
|
self.funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4(client, acc)
|
||||||
self.total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(client, _p('total', acc))
|
self.total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4(client, _p('total', acc))
|
||||||
|
|
||||||
class InPattern:
|
class InPattern2:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, acc: str):
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
@@ -3692,6 +3700,14 @@ class InPattern:
|
|||||||
self.in_loss: CentsUsdPattern3 = CentsUsdPattern3(client, _m(acc, 'loss'))
|
self.in_loss: CentsUsdPattern3 = CentsUsdPattern3(client, _m(acc, 'loss'))
|
||||||
self.in_profit: CentsUsdPattern3 = CentsUsdPattern3(client, _m(acc, 'profit'))
|
self.in_profit: CentsUsdPattern3 = CentsUsdPattern3(client, _m(acc, 'profit'))
|
||||||
|
|
||||||
|
class InPattern:
|
||||||
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
|
"""Create pattern node with accumulated series name."""
|
||||||
|
self.in_loss: ToPattern = ToPattern(client, _m(acc, 'loss_to_own'))
|
||||||
|
self.in_profit: ToPattern = ToPattern(client, _m(acc, 'profit_to_own'))
|
||||||
|
|
||||||
class PerPattern:
|
class PerPattern:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
@@ -3720,7 +3736,7 @@ class SdSmaPattern:
|
|||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class ToPattern:
|
class ToPattern2:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, acc: str):
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
@@ -3749,6 +3765,13 @@ class PricePattern:
|
|||||||
"""Create pattern node with accumulated series name."""
|
"""Create pattern node with accumulated series name."""
|
||||||
self.price: BpsCentsPercentilesRatioSatsUsdPattern = BpsCentsPercentilesRatioSatsUsdPattern(client, acc)
|
self.price: BpsCentsPercentilesRatioSatsUsdPattern = BpsCentsPercentilesRatioSatsUsdPattern(client, acc)
|
||||||
|
|
||||||
|
class ToPattern:
|
||||||
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
|
def __init__(self, client: BrkClientBase, acc: str):
|
||||||
|
"""Create pattern node with accumulated series name."""
|
||||||
|
self.to_own: BpsPercentRatioPattern2 = BpsPercentRatioPattern2(client, acc)
|
||||||
|
|
||||||
class TransferPattern:
|
class TransferPattern:
|
||||||
"""Pattern struct for repeated tree structure."""
|
"""Pattern struct for repeated tree structure."""
|
||||||
|
|
||||||
@@ -4269,11 +4292,11 @@ class SeriesTree_Addrs_Reused_Events:
|
|||||||
"""Series tree node."""
|
"""Series tree node."""
|
||||||
|
|
||||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
self.output_to_reused_addr_count: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5(client, 'output_to_reused_addr_count')
|
self.output_to_reused_addr_count: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6(client, 'output_to_reused_addr_count')
|
||||||
self.output_to_reused_addr_share: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6(client, 'output_to_reused_addr_share')
|
self.output_to_reused_addr_share: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7(client, 'output_to_reused_addr_share')
|
||||||
self.spendable_output_to_reused_addr_share: _1m1w1y24hBpsPercentRatioPattern = _1m1w1y24hBpsPercentRatioPattern(client, 'spendable_output_to_reused_addr_share')
|
self.spendable_output_to_reused_addr_share: _1m1w1y24hBpsPercentRatioPattern = _1m1w1y24hBpsPercentRatioPattern(client, 'spendable_output_to_reused_addr_share')
|
||||||
self.input_from_reused_addr_count: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5(client, 'input_from_reused_addr_count')
|
self.input_from_reused_addr_count: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6(client, 'input_from_reused_addr_count')
|
||||||
self.input_from_reused_addr_share: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6(client, 'input_from_reused_addr_share')
|
self.input_from_reused_addr_share: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern7(client, 'input_from_reused_addr_share')
|
||||||
self.active_reused_addr_count: _1m1w1y24hBlockPattern = _1m1w1y24hBlockPattern(client, 'active_reused_addr_count')
|
self.active_reused_addr_count: _1m1w1y24hBlockPattern = _1m1w1y24hBlockPattern(client, 'active_reused_addr_count')
|
||||||
self.active_reused_addr_share: SeriesTree_Addrs_Reused_Events_ActiveReusedAddrShare = SeriesTree_Addrs_Reused_Events_ActiveReusedAddrShare(client)
|
self.active_reused_addr_share: SeriesTree_Addrs_Reused_Events_ActiveReusedAddrShare = SeriesTree_Addrs_Reused_Events_ActiveReusedAddrShare(client)
|
||||||
|
|
||||||
@@ -4334,6 +4357,20 @@ class SeriesTree_Addrs_Delta:
|
|||||||
self.p2tr: AbsoluteRatePattern = AbsoluteRatePattern(client, 'p2tr_addr_count')
|
self.p2tr: AbsoluteRatePattern = AbsoluteRatePattern(client, 'p2tr_addr_count')
|
||||||
self.p2a: AbsoluteRatePattern = AbsoluteRatePattern(client, 'p2a_addr_count')
|
self.p2a: AbsoluteRatePattern = AbsoluteRatePattern(client, 'p2a_addr_count')
|
||||||
|
|
||||||
|
class SeriesTree_Addrs_AvgAmount:
|
||||||
|
"""Series tree node."""
|
||||||
|
|
||||||
|
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||||
|
self.all: AddrUtxoPattern = AddrUtxoPattern(client, 'avg')
|
||||||
|
self.p2pk65: AddrUtxoPattern = AddrUtxoPattern(client, 'p2pk65_avg')
|
||||||
|
self.p2pk33: AddrUtxoPattern = AddrUtxoPattern(client, 'p2pk33_avg')
|
||||||
|
self.p2pkh: AddrUtxoPattern = AddrUtxoPattern(client, 'p2pkh_avg')
|
||||||
|
self.p2sh: AddrUtxoPattern = AddrUtxoPattern(client, 'p2sh_avg')
|
||||||
|
self.p2wpkh: AddrUtxoPattern = AddrUtxoPattern(client, 'p2wpkh_avg')
|
||||||
|
self.p2wsh: AddrUtxoPattern = AddrUtxoPattern(client, 'p2wsh_avg')
|
||||||
|
self.p2tr: AddrUtxoPattern = AddrUtxoPattern(client, 'p2tr_avg')
|
||||||
|
self.p2a: AddrUtxoPattern = AddrUtxoPattern(client, 'p2a_avg')
|
||||||
|
|
||||||
class SeriesTree_Addrs:
|
class SeriesTree_Addrs:
|
||||||
"""Series tree node."""
|
"""Series tree node."""
|
||||||
|
|
||||||
@@ -4341,14 +4378,15 @@ class SeriesTree_Addrs:
|
|||||||
self.raw: SeriesTree_Addrs_Raw = SeriesTree_Addrs_Raw(client)
|
self.raw: SeriesTree_Addrs_Raw = SeriesTree_Addrs_Raw(client)
|
||||||
self.indexes: SeriesTree_Addrs_Indexes = SeriesTree_Addrs_Indexes(client)
|
self.indexes: SeriesTree_Addrs_Indexes = SeriesTree_Addrs_Indexes(client)
|
||||||
self.data: SeriesTree_Addrs_Data = SeriesTree_Addrs_Data(client)
|
self.data: SeriesTree_Addrs_Data = SeriesTree_Addrs_Data(client)
|
||||||
self.funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(client, 'addr_count')
|
self.funded: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4(client, 'addr_count')
|
||||||
self.empty: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(client, 'empty_addr_count')
|
self.empty: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4(client, 'empty_addr_count')
|
||||||
self.activity: SeriesTree_Addrs_Activity = SeriesTree_Addrs_Activity(client)
|
self.activity: SeriesTree_Addrs_Activity = SeriesTree_Addrs_Activity(client)
|
||||||
self.total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3(client, 'total_addr_count')
|
self.total: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern4(client, 'total_addr_count')
|
||||||
self.new: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern5(client, 'new_addr_count')
|
self.new: AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6 = AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern6(client, 'new_addr_count')
|
||||||
self.reused: SeriesTree_Addrs_Reused = SeriesTree_Addrs_Reused(client)
|
self.reused: SeriesTree_Addrs_Reused = SeriesTree_Addrs_Reused(client)
|
||||||
self.exposed: SeriesTree_Addrs_Exposed = SeriesTree_Addrs_Exposed(client)
|
self.exposed: SeriesTree_Addrs_Exposed = SeriesTree_Addrs_Exposed(client)
|
||||||
self.delta: SeriesTree_Addrs_Delta = SeriesTree_Addrs_Delta(client)
|
self.delta: SeriesTree_Addrs_Delta = SeriesTree_Addrs_Delta(client)
|
||||||
|
self.avg_amount: SeriesTree_Addrs_AvgAmount = SeriesTree_Addrs_AvgAmount(client)
|
||||||
|
|
||||||
class SeriesTree_Scripts_Raw_Empty:
|
class SeriesTree_Scripts_Raw_Empty:
|
||||||
"""Series tree node."""
|
"""Series tree node."""
|
||||||
@@ -5659,7 +5697,7 @@ class SeriesTree_Cohorts_Utxo_All_Unrealized:
|
|||||||
self.loss: SeriesTree_Cohorts_Utxo_All_Unrealized_Loss = SeriesTree_Cohorts_Utxo_All_Unrealized_Loss(client)
|
self.loss: SeriesTree_Cohorts_Utxo_All_Unrealized_Loss = SeriesTree_Cohorts_Utxo_All_Unrealized_Loss(client)
|
||||||
self.net_pnl: SeriesTree_Cohorts_Utxo_All_Unrealized_NetPnl = SeriesTree_Cohorts_Utxo_All_Unrealized_NetPnl(client)
|
self.net_pnl: SeriesTree_Cohorts_Utxo_All_Unrealized_NetPnl = SeriesTree_Cohorts_Utxo_All_Unrealized_NetPnl(client)
|
||||||
self.gross_pnl: CentsUsdPattern3 = CentsUsdPattern3(client, 'unrealized_gross_pnl')
|
self.gross_pnl: CentsUsdPattern3 = CentsUsdPattern3(client, 'unrealized_gross_pnl')
|
||||||
self.invested_capital: InPattern = InPattern(client, 'invested_capital_in')
|
self.invested_capital: InPattern2 = InPattern2(client, 'invested_capital_in')
|
||||||
self.capitalized_cap_in_profit_raw: SeriesPattern18[CentsSquaredSats] = SeriesPattern18(client, 'capitalized_cap_in_profit_raw')
|
self.capitalized_cap_in_profit_raw: SeriesPattern18[CentsSquaredSats] = SeriesPattern18(client, 'capitalized_cap_in_profit_raw')
|
||||||
self.capitalized_cap_in_loss_raw: SeriesPattern18[CentsSquaredSats] = SeriesPattern18(client, 'capitalized_cap_in_loss_raw')
|
self.capitalized_cap_in_loss_raw: SeriesPattern18[CentsSquaredSats] = SeriesPattern18(client, 'capitalized_cap_in_loss_raw')
|
||||||
self.sentiment: SeriesTree_Cohorts_Utxo_All_Unrealized_Sentiment = SeriesTree_Cohorts_Utxo_All_Unrealized_Sentiment(client)
|
self.sentiment: SeriesTree_Cohorts_Utxo_All_Unrealized_Sentiment = SeriesTree_Cohorts_Utxo_All_Unrealized_Sentiment(client)
|
||||||
@@ -5674,6 +5712,7 @@ class SeriesTree_Cohorts_Utxo_All:
|
|||||||
self.realized: SeriesTree_Cohorts_Utxo_All_Realized = SeriesTree_Cohorts_Utxo_All_Realized(client)
|
self.realized: SeriesTree_Cohorts_Utxo_All_Realized = SeriesTree_Cohorts_Utxo_All_Realized(client)
|
||||||
self.cost_basis: SeriesTree_Cohorts_Utxo_All_CostBasis = SeriesTree_Cohorts_Utxo_All_CostBasis(client)
|
self.cost_basis: SeriesTree_Cohorts_Utxo_All_CostBasis = SeriesTree_Cohorts_Utxo_All_CostBasis(client)
|
||||||
self.unrealized: SeriesTree_Cohorts_Utxo_All_Unrealized = SeriesTree_Cohorts_Utxo_All_Unrealized(client)
|
self.unrealized: SeriesTree_Cohorts_Utxo_All_Unrealized = SeriesTree_Cohorts_Utxo_All_Unrealized(client)
|
||||||
|
self.invested_capital: InPattern = InPattern(client, 'invested_capital_in')
|
||||||
|
|
||||||
class SeriesTree_Cohorts_Utxo_Sth_Realized_Price_StdDev_All:
|
class SeriesTree_Cohorts_Utxo_Sth_Realized_Price_StdDev_All:
|
||||||
"""Series tree node."""
|
"""Series tree node."""
|
||||||
@@ -5804,6 +5843,7 @@ class SeriesTree_Cohorts_Utxo_Sth:
|
|||||||
self.realized: SeriesTree_Cohorts_Utxo_Sth_Realized = SeriesTree_Cohorts_Utxo_Sth_Realized(client)
|
self.realized: SeriesTree_Cohorts_Utxo_Sth_Realized = SeriesTree_Cohorts_Utxo_Sth_Realized(client)
|
||||||
self.cost_basis: InMaxMinPerSupplyPattern = InMaxMinPerSupplyPattern(client, 'sth')
|
self.cost_basis: InMaxMinPerSupplyPattern = InMaxMinPerSupplyPattern(client, 'sth')
|
||||||
self.unrealized: CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2 = CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2(client, 'sth')
|
self.unrealized: CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2 = CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2(client, 'sth')
|
||||||
|
self.invested_capital: InPattern = InPattern(client, 'sth_invested_capital_in')
|
||||||
|
|
||||||
class SeriesTree_Cohorts_Utxo_Lth_Realized_Price_StdDev_All:
|
class SeriesTree_Cohorts_Utxo_Lth_Realized_Price_StdDev_All:
|
||||||
"""Series tree node."""
|
"""Series tree node."""
|
||||||
@@ -5941,6 +5981,7 @@ class SeriesTree_Cohorts_Utxo_Lth:
|
|||||||
self.realized: SeriesTree_Cohorts_Utxo_Lth_Realized = SeriesTree_Cohorts_Utxo_Lth_Realized(client)
|
self.realized: SeriesTree_Cohorts_Utxo_Lth_Realized = SeriesTree_Cohorts_Utxo_Lth_Realized(client)
|
||||||
self.cost_basis: InMaxMinPerSupplyPattern = InMaxMinPerSupplyPattern(client, 'lth')
|
self.cost_basis: InMaxMinPerSupplyPattern = InMaxMinPerSupplyPattern(client, 'lth')
|
||||||
self.unrealized: CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2 = CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2(client, 'lth')
|
self.unrealized: CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2 = CapitalizedGrossInvestedLossNetNuplProfitSentimentPattern2(client, 'lth')
|
||||||
|
self.invested_capital: InPattern = InPattern(client, 'lth_invested_capital_in')
|
||||||
|
|
||||||
class SeriesTree_Cohorts_Utxo_AgeRange:
|
class SeriesTree_Cohorts_Utxo_AgeRange:
|
||||||
"""Series tree node."""
|
"""Series tree node."""
|
||||||
|
|||||||
276
website/assets/logo/demo-svg.html
Normal file
276
website/assets/logo/demo-svg.html
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<title>bitview logo (svg)</title>
|
||||||
|
<style>
|
||||||
|
/* Website's Lilex (the site's --font-mono). */
|
||||||
|
@font-face {
|
||||||
|
font-family: Lilex;
|
||||||
|
src: url("../fonts/Lilex[wght]-v2_620.woff2") format("woff2");
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 100 700;
|
||||||
|
font-display: block;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: Lilex;
|
||||||
|
src: url("../fonts/Lilex-Italic[wght]-v2_620.woff2.woff2") format("woff2");
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 100 700;
|
||||||
|
font-display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
color-scheme: light dark;
|
||||||
|
--cube: 4.5rem;
|
||||||
|
--orange: oklch(67.64% 0.191 44.41);
|
||||||
|
--white: oklch(95% 0 0);
|
||||||
|
--black: oklch(15% 0 0);
|
||||||
|
--light-gray: oklch(90% 0 0);
|
||||||
|
--dark-gray: oklch(20% 0 0);
|
||||||
|
--border-color: light-dark(var(--light-gray), var(--dark-gray));
|
||||||
|
--background-color: light-dark(var(--white), var(--black));
|
||||||
|
--fill: 0.5;
|
||||||
|
--empty-alpha: 0.3;
|
||||||
|
--face-step: 0.033;
|
||||||
|
--iso-scale: 0.866;
|
||||||
|
--blur-stddev: 3;
|
||||||
|
--font-size-xs: 0.75rem;
|
||||||
|
--font-size-sm: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- page chrome ---- */
|
||||||
|
html, body { margin: 0; padding: 0; }
|
||||||
|
body {
|
||||||
|
font: 14px/1.4 -apple-system, system-ui, sans-serif;
|
||||||
|
color: #111;
|
||||||
|
background: #f7f8fa;
|
||||||
|
}
|
||||||
|
.wrap { max-width: 1440px; margin: 0 auto; padding: 40px 24px 80px; }
|
||||||
|
section { margin: 0 0 12px; }
|
||||||
|
.row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
.controls {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0 0 24px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
|
.controls select { font-size: 13px; padding: 2px 6px; }
|
||||||
|
.tile {
|
||||||
|
position: relative;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
border-radius: 14px;
|
||||||
|
display: grid; place-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 0 0 1px rgba(0,0,0,0.08);
|
||||||
|
}
|
||||||
|
.tile .label {
|
||||||
|
position: absolute; left: 10px; bottom: 8px;
|
||||||
|
font: 11px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||||||
|
color: rgba(0,0,0,0.55);
|
||||||
|
background: rgba(255,255,255,0.7); padding: 2px 6px; border-radius: 4px;
|
||||||
|
backdrop-filter: blur(6px);
|
||||||
|
}
|
||||||
|
.tile.scheme-light { color-scheme: light; }
|
||||||
|
.tile.scheme-dark { color-scheme: dark; color: #e8e8ea; }
|
||||||
|
.tile.scheme-dark .label { color: rgba(255,255,255,0.75); background: rgba(0,0,0,0.4); }
|
||||||
|
.bg-auto { background: var(--background-color); }
|
||||||
|
.bg-paper { background: light-dark(#f0ece3, #2a2823); }
|
||||||
|
.bg-gradient { background: linear-gradient(135deg, oklch(70% 0.16 260), oklch(72% 0.19 330)); }
|
||||||
|
.bg-image-1 { background: url('https://picsum.photos/seed/brk1/440/440') center/cover; }
|
||||||
|
.bg-image-2 { background: url('https://picsum.photos/seed/brk2/440/440') center/cover; }
|
||||||
|
|
||||||
|
/* ---- cube slot: just holds the svg ---- */
|
||||||
|
.logo-slot {
|
||||||
|
position: relative;
|
||||||
|
width: 160px; height: 160px;
|
||||||
|
display: grid; place-items: center;
|
||||||
|
}
|
||||||
|
.logo-slot svg {
|
||||||
|
/* Iso cube silhouette is 2·iso × 2 (taller than wide, aspect
|
||||||
|
sqrt(3)/2 : 1). The viewBox is square 0 0 200 200 for clean
|
||||||
|
polygon coordinates; preserveAspectRatio="none" stretches it
|
||||||
|
into the right aspect at render time. */
|
||||||
|
width: calc(var(--cube) * var(--iso-scale) * 2);
|
||||||
|
height: calc(var(--cube) * 2);
|
||||||
|
/* Frost: backdrop-filter on the non-transformed <svg> (Safari
|
||||||
|
honours it) clipped to the hex silhouette so the blur only
|
||||||
|
shows where the cube's translucent faces show through. */
|
||||||
|
clip-path: polygon(
|
||||||
|
50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%
|
||||||
|
);
|
||||||
|
backdrop-filter: blur(3px);
|
||||||
|
-webkit-backdrop-filter: blur(3px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- cube face colors (derived from --face-color, same logic
|
||||||
|
as website/styles/panes/explorer.css) ---- */
|
||||||
|
svg.cube {
|
||||||
|
--face-color: var(--orange);
|
||||||
|
--face-right: light-dark(
|
||||||
|
oklch(from var(--face-color) calc(l - var(--face-step) * 2) c h),
|
||||||
|
var(--face-color)
|
||||||
|
);
|
||||||
|
--face-left: light-dark(
|
||||||
|
oklch(from var(--face-color) calc(l - var(--face-step)) c h),
|
||||||
|
oklch(from var(--face-color) calc(l + var(--face-step)) c h)
|
||||||
|
);
|
||||||
|
--face-top: light-dark(
|
||||||
|
var(--face-color),
|
||||||
|
oklch(from var(--face-color) calc(l + var(--face-step) * 2) c h)
|
||||||
|
);
|
||||||
|
--face-bottom: oklch(from var(--face-color) calc(l - var(--face-step) * 3) c h);
|
||||||
|
color: light-dark(var(--black), var(--white));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Glass fills — translucent (--empty-alpha).
|
||||||
|
Front faces (visible in iso): top, right, left.
|
||||||
|
Rear faces (hidden in iso but visible through the translucent
|
||||||
|
fronts as "interior depth"): bottom (y-), rear-left (x-),
|
||||||
|
rear-right (z-). Colors mirror the HTML demo:
|
||||||
|
rear bottom → face-bottom
|
||||||
|
rear-left (x-) → face-top
|
||||||
|
rear-right (z-) → face-left
|
||||||
|
Liquid polygons are opaque, drawn between rear and front. */
|
||||||
|
svg.cube .glass-top { fill: var(--face-top); fill-opacity: var(--empty-alpha); }
|
||||||
|
svg.cube .glass-right { fill: var(--face-right); fill-opacity: var(--empty-alpha); }
|
||||||
|
svg.cube .glass-left { fill: var(--face-left); fill-opacity: var(--empty-alpha); }
|
||||||
|
svg.cube .glass-bottom { fill: var(--face-bottom); fill-opacity: var(--empty-alpha); }
|
||||||
|
svg.cube .glass-rear-left { fill: var(--face-top); fill-opacity: var(--empty-alpha); }
|
||||||
|
svg.cube .glass-rear-right { fill: var(--face-left); fill-opacity: var(--empty-alpha); }
|
||||||
|
svg.cube .liquid-top { fill: var(--face-top); }
|
||||||
|
svg.cube .liquid-right { fill: var(--face-right); }
|
||||||
|
svg.cube .liquid-left { fill: var(--face-left); }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="controls">
|
||||||
|
<span>SVG cube — blur via SVG <code>feGaussianBlur</code> with <code>BackgroundImage</code>.</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Cube template.
|
||||||
|
viewBox 0 0 200 200, hex center = (100, 100), iso half-width = 86.6.
|
||||||
|
Points: V_top=(100,0) VR_upper=(187,50) VR_lower=(187,150)
|
||||||
|
V_bottom=(100,200) VL_lower=(13,150) VL_upper=(13,50)
|
||||||
|
V_center=(100,100)
|
||||||
|
Face polygons (3 visible):
|
||||||
|
top = V_upper_left, V_top, V_upper_right, V_center
|
||||||
|
right = V_upper_right, V_lower_right, V_bottom, V_center
|
||||||
|
left = V_upper_left, V_lower_left, V_bottom, V_center
|
||||||
|
Liquid surface at fill f in [0,1] — 4 corners:
|
||||||
|
(13, 150 - 100f) (187, 150 - 100f) (100, 100 - 100f) (100, 200 - 100f)
|
||||||
|
JS computes liquid sub-polygons per tile based on --fill. -->
|
||||||
|
<template id="logo-template">
|
||||||
|
<div class="logo-slot">
|
||||||
|
<svg class="cube" viewBox="0 0 200 200" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<!-- Rear glass (hidden 3D faces at their iso positions).
|
||||||
|
Drawn first so translucent front faces composite over
|
||||||
|
them for a "depth" look. -->
|
||||||
|
<g class="glass-rear">
|
||||||
|
<polygon class="glass-bottom" points="100,100 200,150 100,200 0,150"/>
|
||||||
|
<polygon class="glass-rear-left" points="100,100 0,150 0,50 100,0"/>
|
||||||
|
<polygon class="glass-rear-right" points="100,100 200,150 200,50 100,0"/>
|
||||||
|
</g>
|
||||||
|
<!-- Liquid (opaque): JS injects polygons sized from --fill. -->
|
||||||
|
<g class="liquid"></g>
|
||||||
|
<!-- Front glass (visible 3D faces). -->
|
||||||
|
<g class="glass-front">
|
||||||
|
<polygon class="glass-top" points="0,50 100,0 200,50 100,100"/>
|
||||||
|
<polygon class="glass-right" points="200,50 200,150 100,200 100,100"/>
|
||||||
|
<polygon class="glass-left" points="0,50 0,150 100,200 100,100"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<div class="row" id="row"></div>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<div class="row" id="fills"></div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Liquid surface at fill f in [0,1]: horizontal cross-section of
|
||||||
|
// the cube at y=f, projected to viewBox (hex fills 200×200).
|
||||||
|
const surface = (f) => ({
|
||||||
|
tl: [0, 150 - 100 * f], // left side at surface
|
||||||
|
tr: [200, 150 - 100 * f], // right side at surface
|
||||||
|
back: [100, 100 - 100 * f], // back vertex (upper)
|
||||||
|
front: [100, 200 - 100 * f], // front vertex (lower)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Liquid = 3 sub-polygons of the 3 visible faces, clipped at the
|
||||||
|
// surface line. The surface rhombus has 4 corners:
|
||||||
|
// back — back vertex of the cross-section
|
||||||
|
// tr/tl — right/left side vertices of the cross-section (shared
|
||||||
|
// with the right/left visible faces)
|
||||||
|
// front — front vertex of the cross-section (shared with both
|
||||||
|
// side faces' front edge)
|
||||||
|
// Each side face's upper edge at the surface runs from its side
|
||||||
|
// corner (tr or tl) to the shared front corner.
|
||||||
|
const liquidPolygons = (f) => {
|
||||||
|
if (f <= 0) return [];
|
||||||
|
const s = surface(f);
|
||||||
|
return [
|
||||||
|
{ cls: 'liquid-top', pts: [s.back, s.tr, s.front, s.tl] },
|
||||||
|
{ cls: 'liquid-right', pts: [s.tr, [200, 150], [100, 200], s.front] },
|
||||||
|
{ cls: 'liquid-left', pts: [s.tl, [0, 150], [100, 200], s.front] },
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
const template = document.getElementById('logo-template');
|
||||||
|
const SVGNS = 'http://www.w3.org/2000/svg';
|
||||||
|
|
||||||
|
const makeLogo = ({ fill = 0.5, faceColor, cubeScheme } = {}) => {
|
||||||
|
const slot = template.content.cloneNode(true).firstElementChild;
|
||||||
|
const svg = slot.querySelector('svg');
|
||||||
|
svg.style.setProperty('--fill', String(fill));
|
||||||
|
if (faceColor) svg.style.setProperty('--face-color', faceColor);
|
||||||
|
svg.style.setProperty('color-scheme', cubeScheme ?? 'light');
|
||||||
|
|
||||||
|
const liquid = svg.querySelector('.liquid');
|
||||||
|
for (const { cls, pts } of liquidPolygons(fill)) {
|
||||||
|
const poly = document.createElementNS(SVGNS, 'polygon');
|
||||||
|
poly.setAttribute('class', cls);
|
||||||
|
poly.setAttribute('points', pts.map(p => p.join(',')).join(' '));
|
||||||
|
liquid.appendChild(poly);
|
||||||
|
}
|
||||||
|
return slot;
|
||||||
|
};
|
||||||
|
|
||||||
|
const makeTile = (cls, label, content) => {
|
||||||
|
const tile = document.createElement('div');
|
||||||
|
tile.className = `tile ${cls}`;
|
||||||
|
tile.appendChild(content);
|
||||||
|
const lbl = document.createElement('span');
|
||||||
|
lbl.className = 'label';
|
||||||
|
lbl.textContent = label;
|
||||||
|
tile.appendChild(lbl);
|
||||||
|
return tile;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Row 1: cube on each background.
|
||||||
|
const row = document.getElementById('row');
|
||||||
|
row.appendChild(makeTile('bg-auto scheme-light', 'light', makeLogo()));
|
||||||
|
row.appendChild(makeTile('bg-auto scheme-dark', 'dark', makeLogo()));
|
||||||
|
row.appendChild(makeTile('bg-paper scheme-light', 'paper', makeLogo()));
|
||||||
|
row.appendChild(makeTile('bg-gradient scheme-light', 'gradient', makeLogo()));
|
||||||
|
row.appendChild(makeTile('bg-image-1 scheme-light', 'img 1', makeLogo()));
|
||||||
|
row.appendChild(makeTile('bg-image-2 scheme-light', 'img 2', makeLogo()));
|
||||||
|
|
||||||
|
// Row 2: fill levels.
|
||||||
|
const fills = document.getElementById('fills');
|
||||||
|
for (const f of [0, 0.1, 0.25, 0.5, 0.75, 1])
|
||||||
|
fills.appendChild(makeTile('bg-auto scheme-light', `fill ${f}`, makeLogo({ fill: f })));
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
721
website/assets/logo/demo.html
Normal file
721
website/assets/logo/demo.html
Normal file
File diff suppressed because one or more lines are too long
@@ -128,6 +128,9 @@
|
|||||||
*
|
*
|
||||||
* Address count pattern (base + delta with absolute + rate)
|
* Address count pattern (base + delta with absolute + rate)
|
||||||
* @typedef {Brk.BaseDeltaPattern} AddrCountPattern
|
* @typedef {Brk.BaseDeltaPattern} AddrCountPattern
|
||||||
|
* @typedef {Brk.AddrUtxoPattern} AvgAmountPattern
|
||||||
|
* @typedef {Brk.SeriesTree_Addrs_Exposed} ExposedTree
|
||||||
|
* @typedef {Brk.SeriesTree_Addrs_Reused} ReusedTree
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -273,6 +273,15 @@ function createBlockCube(block) {
|
|||||||
function createCube() {
|
function createCube() {
|
||||||
const cubeElement = document.createElement("div");
|
const cubeElement = document.createElement("div");
|
||||||
cubeElement.classList.add("cube");
|
cubeElement.classList.add("cube");
|
||||||
|
const bottomElement = document.createElement("div");
|
||||||
|
bottomElement.classList.add("face", "bottom");
|
||||||
|
cubeElement.append(bottomElement);
|
||||||
|
const rearRightElement = document.createElement("div");
|
||||||
|
rearRightElement.classList.add("face", "rear-right");
|
||||||
|
cubeElement.append(rearRightElement);
|
||||||
|
const rearLeftElement = document.createElement("div");
|
||||||
|
rearLeftElement.classList.add("face", "rear-left");
|
||||||
|
cubeElement.append(rearLeftElement);
|
||||||
const innerTopElement = document.createElement("div");
|
const innerTopElement = document.createElement("div");
|
||||||
innerTopElement.classList.add("face", "inner-top");
|
innerTopElement.classList.add("face", "inner-top");
|
||||||
cubeElement.append(innerTopElement);
|
cubeElement.append(innerTopElement);
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ export function buildCohortData() {
|
|||||||
base: addrs.funded.all,
|
base: addrs.funded.all,
|
||||||
delta: addrs.delta.all,
|
delta: addrs.delta.all,
|
||||||
},
|
},
|
||||||
|
avgAmount: addrs.avgAmount.all,
|
||||||
};
|
};
|
||||||
|
|
||||||
const shortNames = TERM_NAMES.short;
|
const shortNames = TERM_NAMES.short;
|
||||||
@@ -174,6 +175,9 @@ export function buildCohortData() {
|
|||||||
base: addrs.funded[key],
|
base: addrs.funded[key],
|
||||||
delta: addrs.delta[key],
|
delta: addrs.delta[key],
|
||||||
},
|
},
|
||||||
|
avgAmount: addrs.avgAmount[key],
|
||||||
|
exposed: addrs.exposed,
|
||||||
|
reused: addrs.reused,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import {
|
|||||||
groupedWindowsCumulativeWithAll,
|
groupedWindowsCumulativeWithAll,
|
||||||
} from "../shared.js";
|
} from "../shared.js";
|
||||||
import { colors } from "../../utils/colors.js";
|
import { colors } from "../../utils/colors.js";
|
||||||
import { priceLines } from "../constants.js";
|
import { priceLine } from "../constants.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple supply series (total + half only, no profit/loss)
|
* Simple supply series (total + half only, no profit/loss)
|
||||||
@@ -165,41 +165,44 @@ function groupedDeltaItems(list, all, getDelta, unit, title, name) {
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Profitability chart (in profit + in loss supply)
|
* Amount chart: total + halved + in profit + in loss in sats/btc/usd.
|
||||||
* @param {{ total: AnyValuePattern, half: AnyValuePattern, inProfit: AnyValuePattern, inLoss: AnyValuePattern }} supply
|
* @param {{ total: AnyValuePattern, half: AnyValuePattern, inProfit: AnyValuePattern, inLoss: AnyValuePattern }} supply
|
||||||
* @param {(name: string) => string} title
|
* @param {(name: string) => string} title
|
||||||
* @returns {PartialChartOption}
|
* @returns {PartialChartOption}
|
||||||
*/
|
*/
|
||||||
function profitabilityChart(supply, title) {
|
function profitabilityAmountChart(supply, title) {
|
||||||
return {
|
return {
|
||||||
name: "Profitability",
|
name: "Amount",
|
||||||
title: title("Supply Profitability"),
|
title: title("Supply Profitability"),
|
||||||
bottom: [
|
bottom: [
|
||||||
...satsBtcUsd({
|
...satsBtcUsd({ pattern: supply.total, name: "Total", color: colors.default }),
|
||||||
pattern: supply.total,
|
...satsBtcUsd({ pattern: supply.inProfit, name: "In Profit", color: colors.profit }),
|
||||||
name: "Total",
|
...satsBtcUsd({ pattern: supply.inLoss, name: "In Loss", color: colors.loss }),
|
||||||
color: colors.default,
|
...satsBtcUsd({ pattern: supply.half, name: "Halved", color: colors.gray, style: 4 }),
|
||||||
}),
|
|
||||||
...satsBtcUsd({
|
|
||||||
pattern: supply.inProfit,
|
|
||||||
name: "In Profit",
|
|
||||||
color: colors.profit,
|
|
||||||
}),
|
|
||||||
...satsBtcUsd({
|
|
||||||
pattern: supply.inLoss,
|
|
||||||
name: "In Loss",
|
|
||||||
color: colors.loss,
|
|
||||||
}),
|
|
||||||
...satsBtcUsd({
|
|
||||||
pattern: supply.half,
|
|
||||||
name: "Halved",
|
|
||||||
color: colors.gray,
|
|
||||||
style: 4,
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Share chart: in profit / in loss as % of own supply.
|
||||||
|
* @param {{ inProfit: { toOwn: { percent: AnySeriesPattern, ratio: AnySeriesPattern } }, inLoss: { toOwn: { percent: AnySeriesPattern, ratio: AnySeriesPattern } } }} supply
|
||||||
|
* @param {(name: string) => string} title
|
||||||
|
* @returns {PartialChartOption}
|
||||||
|
*/
|
||||||
|
function profitabilityShareChart(supply, title) {
|
||||||
|
return {
|
||||||
|
name: "Share",
|
||||||
|
title: title("Supply Profitability"),
|
||||||
|
bottom: [
|
||||||
|
...percentRatio({ pattern: supply.inProfit.toOwn, name: "In Profit", color: colors.profit }),
|
||||||
|
...percentRatio({ pattern: supply.inLoss.toOwn, name: "In Loss", color: colors.loss }),
|
||||||
|
priceLine({ number: 100, color: colors.default, style: 0, unit: Unit.percentage }),
|
||||||
|
priceLine({ number: 50, unit: Unit.percentage }),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {{ toCirculating: PercentRatioPattern, inProfit: { toCirculating: PercentRatioPattern }, inLoss: { toCirculating: PercentRatioPattern } }} supply
|
* @param {{ toCirculating: PercentRatioPattern, inProfit: { toCirculating: PercentRatioPattern }, inLoss: { toCirculating: PercentRatioPattern } }} supply
|
||||||
* @param {(name: string) => string} title
|
* @param {(name: string) => string} title
|
||||||
@@ -207,8 +210,8 @@ function profitabilityChart(supply, title) {
|
|||||||
*/
|
*/
|
||||||
function circulatingChart(supply, title) {
|
function circulatingChart(supply, title) {
|
||||||
return {
|
return {
|
||||||
name: "% of Circulating",
|
name: "Dominance",
|
||||||
title: title("Supply (% of Circulating)"),
|
title: title("Supply Dominance"),
|
||||||
bottom: [
|
bottom: [
|
||||||
...percentRatio({ pattern: supply.toCirculating, name: "Total", color: colors.default }),
|
...percentRatio({ pattern: supply.toCirculating, name: "Total", color: colors.default }),
|
||||||
...percentRatio({ pattern: supply.inProfit.toCirculating, name: "In Profit", color: colors.profit }),
|
...percentRatio({ pattern: supply.inProfit.toCirculating, name: "In Profit", color: colors.profit }),
|
||||||
@@ -217,23 +220,6 @@ function circulatingChart(supply, title) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {{ inProfit: { toOwn: { percent: AnySeriesPattern, ratio: AnySeriesPattern } }, inLoss: { toOwn: { percent: AnySeriesPattern, ratio: AnySeriesPattern } } }} supply
|
|
||||||
* @param {(name: string) => string} title
|
|
||||||
* @returns {PartialChartOption}
|
|
||||||
*/
|
|
||||||
function ownSupplyChart(supply, title) {
|
|
||||||
return {
|
|
||||||
name: "% of Own Supply",
|
|
||||||
title: title("Supply (% of Own)"),
|
|
||||||
bottom: [
|
|
||||||
...percentRatio({ pattern: supply.inProfit.toOwn, name: "In Profit", color: colors.profit }),
|
|
||||||
...percentRatio({ pattern: supply.inLoss.toOwn, name: "In Loss", color: colors.loss }),
|
|
||||||
...priceLines({ numbers: [100, 50, 0], unit: Unit.percentage }),
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {OutputsPattern} outputs
|
* @param {OutputsPattern} outputs
|
||||||
* @param {Color} color
|
* @param {Color} color
|
||||||
@@ -330,8 +316,13 @@ export function createHoldingsSectionAll({ cohort, title }) {
|
|||||||
title: title("Supply"),
|
title: title("Supply"),
|
||||||
bottom: simpleSupplySeries(supply),
|
bottom: simpleSupplySeries(supply),
|
||||||
},
|
},
|
||||||
profitabilityChart(supply, title),
|
{
|
||||||
ownSupplyChart(supply, title),
|
name: "Profitability",
|
||||||
|
tree: [
|
||||||
|
profitabilityAmountChart(supply, title),
|
||||||
|
profitabilityShareChart(supply, title),
|
||||||
|
],
|
||||||
|
},
|
||||||
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -355,9 +346,14 @@ export function createHoldingsSectionWithRelative({ cohort, title }) {
|
|||||||
title: title("Supply"),
|
title: title("Supply"),
|
||||||
bottom: simpleSupplySeries(supply),
|
bottom: simpleSupplySeries(supply),
|
||||||
},
|
},
|
||||||
profitabilityChart(supply, title),
|
{
|
||||||
circulatingChart(supply, title),
|
name: "Profitability",
|
||||||
ownSupplyChart(supply, title),
|
tree: [
|
||||||
|
profitabilityAmountChart(supply, title),
|
||||||
|
profitabilityShareChart(supply, title),
|
||||||
|
circulatingChart(supply, title),
|
||||||
|
],
|
||||||
|
},
|
||||||
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -380,8 +376,13 @@ export function createHoldingsSectionWithOwnSupply({ cohort, title }) {
|
|||||||
title: title("Supply"),
|
title: title("Supply"),
|
||||||
bottom: simpleSupplySeries(supply),
|
bottom: simpleSupplySeries(supply),
|
||||||
},
|
},
|
||||||
profitabilityChart(supply, title),
|
{
|
||||||
circulatingChart(supply, title),
|
name: "Profitability",
|
||||||
|
tree: [
|
||||||
|
profitabilityAmountChart(supply, title),
|
||||||
|
circulatingChart(supply, title),
|
||||||
|
],
|
||||||
|
},
|
||||||
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -404,7 +405,10 @@ export function createHoldingsSectionWithProfitLoss({ cohort, title }) {
|
|||||||
title: title("Supply"),
|
title: title("Supply"),
|
||||||
bottom: simpleSupplySeries(supply),
|
bottom: simpleSupplySeries(supply),
|
||||||
},
|
},
|
||||||
profitabilityChart(supply, title),
|
{
|
||||||
|
name: "Profitability",
|
||||||
|
tree: [profitabilityAmountChart(supply, title)],
|
||||||
|
},
|
||||||
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -427,7 +431,10 @@ export function createHoldingsSectionAddress({ cohort, title }) {
|
|||||||
title: title("Supply"),
|
title: title("Supply"),
|
||||||
bottom: simpleSupplySeries(supply),
|
bottom: simpleSupplySeries(supply),
|
||||||
},
|
},
|
||||||
profitabilityChart(supply, title),
|
{
|
||||||
|
name: "Profitability",
|
||||||
|
tree: [profitabilityAmountChart(supply, title)],
|
||||||
|
},
|
||||||
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
...singleDeltaItems(supply.delta, Unit.sats, title, "Supply"),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -502,7 +509,10 @@ export function createGroupedHoldingsSectionAddress({ list, all, title }) {
|
|||||||
name: "Supply",
|
name: "Supply",
|
||||||
tree: [
|
tree: [
|
||||||
groupedSupplyTotal(list, all, title),
|
groupedSupplyTotal(list, all, title),
|
||||||
...groupedSupplyProfitLoss(list, all, title),
|
{
|
||||||
|
name: "Profitability",
|
||||||
|
tree: groupedSupplyProfitLoss(list, all, title),
|
||||||
|
},
|
||||||
...groupedDeltaItems(list, all, (c) => c.tree.supply.delta, Unit.sats, title, "Supply"),
|
...groupedDeltaItems(list, all, (c) => c.tree.supply.delta, Unit.sats, title, "Supply"),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -520,6 +530,25 @@ export function createGroupedHoldingsSectionAddress({ list, all, title }) {
|
|||||||
...groupedDeltaItems(list, all, (c) => c.addressCount.delta, Unit.count, title, "Address Count"),
|
...groupedDeltaItems(list, all, (c) => c.addressCount.delta, Unit.count, title, "Address Count"),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Average Holdings",
|
||||||
|
tree: [
|
||||||
|
{
|
||||||
|
name: "Per UTXO",
|
||||||
|
title: title("Average Holdings per UTXO"),
|
||||||
|
bottom: flatMapCohortsWithAll(list, all, ({ name, color, avgAmount }) =>
|
||||||
|
satsBtcUsd({ pattern: avgAmount.utxo, name, color }),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Per Address",
|
||||||
|
title: title("Average Holdings per Funded Address"),
|
||||||
|
bottom: flatMapCohortsWithAll(list, all, ({ name, color, avgAmount }) =>
|
||||||
|
satsBtcUsd({ pattern: avgAmount.addr, name, color }),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ import {
|
|||||||
formatCohortTitle,
|
formatCohortTitle,
|
||||||
satsBtcUsd,
|
satsBtcUsd,
|
||||||
satsBtcUsdFullTree,
|
satsBtcUsdFullTree,
|
||||||
|
avgHoldingsSubtree,
|
||||||
|
exposedSubtree,
|
||||||
|
reusedSubtree,
|
||||||
} from "../shared.js";
|
} from "../shared.js";
|
||||||
import {
|
import {
|
||||||
ROLLING_WINDOWS,
|
ROLLING_WINDOWS,
|
||||||
@@ -103,6 +106,7 @@ export function createCohortFolderAll(cohort) {
|
|||||||
createCostBasisSectionWithPercentiles({ cohort, title }),
|
createCostBasisSectionWithPercentiles({ cohort, title }),
|
||||||
createProfitabilitySectionAll({ cohort, title }),
|
createProfitabilitySectionAll({ cohort, title }),
|
||||||
createActivitySectionWithAdjusted({ cohort, title }),
|
createActivitySectionWithAdjusted({ cohort, title }),
|
||||||
|
avgHoldingsSubtree(cohort.avgAmount, title),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -259,6 +263,9 @@ export function createCohortFolderAddress(cohort) {
|
|||||||
createPricesSectionBasic({ cohort, title }),
|
createPricesSectionBasic({ cohort, title }),
|
||||||
createProfitabilitySectionWithProfitLoss({ cohort, title }),
|
createProfitabilitySectionWithProfitLoss({ cohort, title }),
|
||||||
createActivitySectionMinimal({ cohort, title }),
|
createActivitySectionMinimal({ cohort, title }),
|
||||||
|
avgHoldingsSubtree(cohort.avgAmount, title),
|
||||||
|
reusedSubtree(cohort.reused, cohort.key, title),
|
||||||
|
exposedSubtree(cohort.exposed, cohort.key, title),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { Unit } from "../../utils/units.js";
|
|||||||
import { colors } from "../../utils/colors.js";
|
import { colors } from "../../utils/colors.js";
|
||||||
import { ROLLING_WINDOWS, line, baseline, mapWindows, sumsTreeBaseline, rollingPercentRatioTree, percentRatio, percentRatioBaseline } from "../series.js";
|
import { ROLLING_WINDOWS, line, baseline, mapWindows, sumsTreeBaseline, rollingPercentRatioTree, percentRatio, percentRatioBaseline } from "../series.js";
|
||||||
import { ratioBottomSeries, mapCohortsWithAll, flatMapCohortsWithAll } from "../shared.js";
|
import { ratioBottomSeries, mapCohortsWithAll, flatMapCohortsWithAll } from "../shared.js";
|
||||||
|
import { priceLine } from "../constants.js";
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Shared building blocks
|
// Shared building blocks
|
||||||
@@ -80,11 +81,26 @@ export function createValuationSectionFull({ cohort, title }) {
|
|||||||
{ name: "Total", title: title("Realized Cap"), bottom: [line({ series: tree.realized.cap.usd, name: "Realized Cap", color, unit: Unit.usd })] },
|
{ name: "Total", title: title("Realized Cap"), bottom: [line({ series: tree.realized.cap.usd, name: "Realized Cap", color, unit: Unit.usd })] },
|
||||||
{
|
{
|
||||||
name: "Profitability",
|
name: "Profitability",
|
||||||
title: title("Invested Capital"),
|
tree: [
|
||||||
bottom: [
|
{
|
||||||
line({ series: tree.realized.cap.usd, name: "Total", color: colors.default, unit: Unit.usd }),
|
name: "Amount",
|
||||||
line({ series: tree.unrealized.investedCapital.inProfit.usd, name: "In Profit", color: colors.profit, unit: Unit.usd }),
|
title: title("Invested Capital"),
|
||||||
line({ series: tree.unrealized.investedCapital.inLoss.usd, name: "In Loss", color: colors.loss, unit: Unit.usd }),
|
bottom: [
|
||||||
|
line({ series: tree.realized.cap.usd, name: "Total", color: colors.default, unit: Unit.usd }),
|
||||||
|
line({ series: tree.unrealized.investedCapital.inProfit.usd, name: "In Profit", color: colors.profit, unit: Unit.usd }),
|
||||||
|
line({ series: tree.unrealized.investedCapital.inLoss.usd, name: "In Loss", color: colors.loss, unit: Unit.usd }),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Share",
|
||||||
|
title: title("Invested Capital Profitability"),
|
||||||
|
bottom: [
|
||||||
|
...percentRatio({ pattern: tree.investedCapital.inProfit.toOwn, name: "In Profit", color: colors.profit }),
|
||||||
|
...percentRatio({ pattern: tree.investedCapital.inLoss.toOwn, name: "In Loss", color: colors.loss }),
|
||||||
|
priceLine({ number: 100, color: colors.default, style: 0, unit: Unit.percentage }),
|
||||||
|
priceLine({ number: 50, unit: Unit.percentage }),
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ name: "MVRV", title: title("MVRV"), bottom: ratioBottomSeries(tree.realized.price) },
|
{ name: "MVRV", title: title("MVRV"), bottom: ratioBottomSeries(tree.realized.price) },
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
ROLLING_WINDOWS,
|
ROLLING_WINDOWS,
|
||||||
chartsFromBlockAnd6b,
|
chartsFromBlockAnd6b,
|
||||||
multiSeriesTree,
|
multiSeriesTree,
|
||||||
|
percentRatio,
|
||||||
percentRatioDots,
|
percentRatioDots,
|
||||||
} from "./series.js";
|
} from "./series.js";
|
||||||
import {
|
import {
|
||||||
@@ -29,6 +30,9 @@ import {
|
|||||||
satsBtcUsdFullTree,
|
satsBtcUsdFullTree,
|
||||||
formatCohortTitle,
|
formatCohortTitle,
|
||||||
groupedWindowsCumulative,
|
groupedWindowsCumulative,
|
||||||
|
avgHoldingsSubtree,
|
||||||
|
exposedSubtree,
|
||||||
|
reusedSubtree,
|
||||||
} from "./shared.js";
|
} from "./shared.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -210,34 +214,6 @@ export function createNetworkSection() {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const reusedOutputsSubtreeForType =
|
|
||||||
/**
|
|
||||||
* @param {AddressableType} key
|
|
||||||
* @param {(name: string) => string} title
|
|
||||||
*/
|
|
||||||
(key, title) => ({
|
|
||||||
name: "Outputs",
|
|
||||||
tree: [
|
|
||||||
{
|
|
||||||
name: "Count",
|
|
||||||
tree: chartsFromCount({
|
|
||||||
pattern: addrs.reused.events.outputToReusedAddrCount[key],
|
|
||||||
title,
|
|
||||||
metric: "Transaction Outputs to Reused Addresses",
|
|
||||||
unit: Unit.count,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Share",
|
|
||||||
tree: chartsFromPercentCumulative({
|
|
||||||
pattern: addrs.reused.events.outputToReusedAddrShare[key],
|
|
||||||
title,
|
|
||||||
metric: "Share of Transaction Outputs to Reused Addresses",
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
const reusedActiveSubtreeForAll =
|
const reusedActiveSubtreeForAll =
|
||||||
/** @param {(name: string) => string} title */
|
/** @param {(name: string) => string} title */
|
||||||
(title) => ({
|
(title) => ({
|
||||||
@@ -276,19 +252,6 @@ export function createNetworkSection() {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const reusedSubtreeForType =
|
|
||||||
/**
|
|
||||||
* @param {AddressableType} key
|
|
||||||
* @param {(name: string) => string} title
|
|
||||||
*/
|
|
||||||
(key, title) => ({
|
|
||||||
name: "Reused",
|
|
||||||
tree: [
|
|
||||||
...reusedSetEntries(key, title),
|
|
||||||
reusedOutputsSubtreeForType(key, title),
|
|
||||||
reusedInputsSubtree(key, title),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
const countSubtree =
|
const countSubtree =
|
||||||
/**
|
/**
|
||||||
@@ -324,64 +287,6 @@ export function createNetworkSection() {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const exposedSubtree =
|
|
||||||
/**
|
|
||||||
* @param {AddressableType | "all"} key
|
|
||||||
* @param {(name: string) => string} title
|
|
||||||
*/
|
|
||||||
(key, title) => ({
|
|
||||||
name: "Exposed",
|
|
||||||
tree: [
|
|
||||||
{
|
|
||||||
name: "Compare",
|
|
||||||
title: title("Exposed Address Count"),
|
|
||||||
bottom: [
|
|
||||||
line({
|
|
||||||
series: addrs.exposed.count.funded[key],
|
|
||||||
name: "Funded",
|
|
||||||
unit: Unit.count,
|
|
||||||
}),
|
|
||||||
line({
|
|
||||||
series: addrs.exposed.count.total[key],
|
|
||||||
name: "Total",
|
|
||||||
color: colors.gray,
|
|
||||||
unit: Unit.count,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Funded",
|
|
||||||
title: title("Funded Exposed Address Count"),
|
|
||||||
bottom: [
|
|
||||||
line({
|
|
||||||
series: addrs.exposed.count.funded[key],
|
|
||||||
name: "Funded Exposed",
|
|
||||||
unit: Unit.count,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Total",
|
|
||||||
title: title("Total Exposed Address Count"),
|
|
||||||
bottom: [
|
|
||||||
line({
|
|
||||||
series: addrs.exposed.count.total[key],
|
|
||||||
name: "Total Exposed",
|
|
||||||
color: colors.gray,
|
|
||||||
unit: Unit.count,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Supply",
|
|
||||||
title: title("Supply in Exposed Addresses"),
|
|
||||||
bottom: satsBtcUsd({
|
|
||||||
pattern: addrs.exposed.supply[key],
|
|
||||||
name: "Supply",
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
const activityPerTypeEntries =
|
const activityPerTypeEntries =
|
||||||
/**
|
/**
|
||||||
@@ -478,7 +383,8 @@ export function createNetworkSection() {
|
|||||||
}),
|
}),
|
||||||
activitySubtreeForAll(title),
|
activitySubtreeForAll(title),
|
||||||
reusedSubtreeForAll(title),
|
reusedSubtreeForAll(title),
|
||||||
exposedSubtree("all", title),
|
exposedSubtree(addrs.exposed, "all", title),
|
||||||
|
avgHoldingsSubtree(addrs.avgAmount.all, title),
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -507,8 +413,9 @@ export function createNetworkSection() {
|
|||||||
unit: Unit.count,
|
unit: Unit.count,
|
||||||
}),
|
}),
|
||||||
activitySubtreeForType(addrType, title),
|
activitySubtreeForType(addrType, title),
|
||||||
reusedSubtreeForType(addrType, title),
|
reusedSubtree(addrs.reused, addrType, title),
|
||||||
exposedSubtree(addrType, title),
|
exposedSubtree(addrs.exposed, addrType, title),
|
||||||
|
avgHoldingsSubtree(addrs.avgAmount[addrType], title),
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -761,6 +668,49 @@ export function createNetworkSection() {
|
|||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Share",
|
||||||
|
title: "Share of Supply in Exposed Addresses by Type",
|
||||||
|
bottom: addressTypes.flatMap((t) =>
|
||||||
|
percentRatio({
|
||||||
|
pattern: addrs.exposed.supply.share[t.key],
|
||||||
|
name: t.name,
|
||||||
|
color: t.color,
|
||||||
|
defaultActive: t.defaultActive,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// Average Holdings
|
||||||
|
{
|
||||||
|
name: "Average Holdings",
|
||||||
|
tree: [
|
||||||
|
{
|
||||||
|
name: "Per UTXO",
|
||||||
|
title: "Average Holdings per UTXO by Type",
|
||||||
|
bottom: addressTypes.flatMap((t) =>
|
||||||
|
satsBtcUsd({
|
||||||
|
pattern: addrs.avgAmount[t.key].utxo,
|
||||||
|
name: t.name,
|
||||||
|
color: t.color,
|
||||||
|
defaultActive: t.defaultActive,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Per Address",
|
||||||
|
title: "Average Holdings per Funded Address by Type",
|
||||||
|
bottom: addressTypes.flatMap((t) =>
|
||||||
|
satsBtcUsd({
|
||||||
|
pattern: addrs.avgAmount[t.key].addr,
|
||||||
|
name: t.name,
|
||||||
|
color: t.color,
|
||||||
|
defaultActive: t.defaultActive,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ import {
|
|||||||
line,
|
line,
|
||||||
baseline,
|
baseline,
|
||||||
price,
|
price,
|
||||||
|
percentRatio,
|
||||||
|
chartsFromCount,
|
||||||
|
chartsFromPercentCumulative,
|
||||||
sumsAndAveragesCumulativeWith,
|
sumsAndAveragesCumulativeWith,
|
||||||
} from "./series.js";
|
} from "./series.js";
|
||||||
import { priceLine, priceLines } from "./constants.js";
|
import { priceLine, priceLines } from "./constants.js";
|
||||||
@@ -243,6 +246,198 @@ export function satsBtcUsdFullTree({ pattern, title, metric, color }) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "Exposed" subtree (quantum-risk / revealed-pubkey addresses).
|
||||||
|
* Shape: Compare (funded + total) / Funded / Total / Supply / Share.
|
||||||
|
* Shared between Network and Distribution (per-type cohort view).
|
||||||
|
* @param {ExposedTree} exposed
|
||||||
|
* @param {AddressableType | "all"} key
|
||||||
|
* @param {(name: string) => string} title
|
||||||
|
* @returns {PartialOptionsGroup}
|
||||||
|
*/
|
||||||
|
export function exposedSubtree(exposed, key, title) {
|
||||||
|
return {
|
||||||
|
name: "Exposed",
|
||||||
|
tree: [
|
||||||
|
{
|
||||||
|
name: "Compare",
|
||||||
|
title: title("Exposed Address Count"),
|
||||||
|
bottom: [
|
||||||
|
line({ series: exposed.count.funded[key], name: "Funded", unit: Unit.count }),
|
||||||
|
line({
|
||||||
|
series: exposed.count.total[key],
|
||||||
|
name: "Total",
|
||||||
|
color: colors.gray,
|
||||||
|
unit: Unit.count,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Funded",
|
||||||
|
title: title("Funded Exposed Address Count"),
|
||||||
|
bottom: [
|
||||||
|
line({ series: exposed.count.funded[key], name: "Funded Exposed", unit: Unit.count }),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Total",
|
||||||
|
title: title("Total Exposed Address Count"),
|
||||||
|
bottom: [
|
||||||
|
line({
|
||||||
|
series: exposed.count.total[key],
|
||||||
|
name: "Total Exposed",
|
||||||
|
color: colors.gray,
|
||||||
|
unit: Unit.count,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Supply",
|
||||||
|
title: title("Supply in Exposed Addresses"),
|
||||||
|
bottom: satsBtcUsd({ pattern: exposed.supply[key], name: "Supply" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Share",
|
||||||
|
title: title("Share of Supply in Exposed Addresses"),
|
||||||
|
bottom: percentRatio({ pattern: exposed.supply.share[key], name: "Supply" }),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "Reused" subtree (per-type / per-cohort — no "Active" window, since that
|
||||||
|
* data is only tracked globally). Shape:
|
||||||
|
* Compare (funded + total) / Funded / Total / Outputs / Inputs.
|
||||||
|
* @param {ReusedTree} reused
|
||||||
|
* @param {AddressableType | "all"} key
|
||||||
|
* @param {(name: string) => string} title
|
||||||
|
* @returns {PartialOptionsGroup}
|
||||||
|
*/
|
||||||
|
export function reusedSubtree(reused, key, title) {
|
||||||
|
return {
|
||||||
|
name: "Reused",
|
||||||
|
tree: [
|
||||||
|
{
|
||||||
|
name: "Compare",
|
||||||
|
title: title("Reused Address Count"),
|
||||||
|
bottom: [
|
||||||
|
line({ series: reused.count.funded[key], name: "Funded", unit: Unit.count }),
|
||||||
|
line({
|
||||||
|
series: reused.count.total[key],
|
||||||
|
name: "Total",
|
||||||
|
color: colors.gray,
|
||||||
|
unit: Unit.count,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Funded",
|
||||||
|
title: title("Funded Reused Addresses"),
|
||||||
|
bottom: [
|
||||||
|
line({ series: reused.count.funded[key], name: "Funded Reused", unit: Unit.count }),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Total",
|
||||||
|
title: title("Total Reused Addresses"),
|
||||||
|
bottom: [
|
||||||
|
line({
|
||||||
|
series: reused.count.total[key],
|
||||||
|
name: "Total Reused",
|
||||||
|
color: colors.gray,
|
||||||
|
unit: Unit.count,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Outputs",
|
||||||
|
tree: [
|
||||||
|
{
|
||||||
|
name: "Count",
|
||||||
|
tree: chartsFromCount({
|
||||||
|
pattern: reused.events.outputToReusedAddrCount[key],
|
||||||
|
title,
|
||||||
|
metric: "Transaction Outputs to Reused Addresses",
|
||||||
|
unit: Unit.count,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Share",
|
||||||
|
tree: chartsFromPercentCumulative({
|
||||||
|
pattern: reused.events.outputToReusedAddrShare[key],
|
||||||
|
title,
|
||||||
|
metric: "Share of Transaction Outputs to Reused Addresses",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Inputs",
|
||||||
|
tree: [
|
||||||
|
{
|
||||||
|
name: "Count",
|
||||||
|
tree: chartsFromCount({
|
||||||
|
pattern: reused.events.inputFromReusedAddrCount[key],
|
||||||
|
title,
|
||||||
|
metric: "Transaction Inputs from Reused Addresses",
|
||||||
|
unit: Unit.count,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Share",
|
||||||
|
tree: chartsFromPercentCumulative({
|
||||||
|
pattern: reused.events.inputFromReusedAddrShare[key],
|
||||||
|
title,
|
||||||
|
metric: "Share of Transaction Inputs from Reused Addresses",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "Average Holdings" subtree: Compare (both) + Per UTXO + Per Funded Address.
|
||||||
|
* Shared between Network and Distribution.
|
||||||
|
* @param {AvgAmountPattern} pattern
|
||||||
|
* @param {(name: string) => string} title
|
||||||
|
* @returns {PartialOptionsGroup}
|
||||||
|
*/
|
||||||
|
export function avgHoldingsSubtree(pattern, title) {
|
||||||
|
return {
|
||||||
|
name: "Average Holdings",
|
||||||
|
tree: [
|
||||||
|
{
|
||||||
|
name: "Compare",
|
||||||
|
title: title("Average Holdings"),
|
||||||
|
bottom: [
|
||||||
|
...satsBtcUsd({ pattern: pattern.utxo, name: "Per UTXO" }),
|
||||||
|
...satsBtcUsd({
|
||||||
|
pattern: pattern.addr,
|
||||||
|
name: "Per Funded Address",
|
||||||
|
color: colors.gray,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Per UTXO",
|
||||||
|
title: title("Average Holdings per UTXO"),
|
||||||
|
bottom: satsBtcUsd({ pattern: pattern.utxo, name: "Per UTXO" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Per Address",
|
||||||
|
title: title("Average Holdings per Funded Address"),
|
||||||
|
bottom: satsBtcUsd({
|
||||||
|
pattern: pattern.addr,
|
||||||
|
name: "Per Funded Address",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create Price + Ratio charts from a simple price pattern (BpsCentsRatioSatsUsdPattern)
|
* Create Price + Ratio charts from a simple price pattern (BpsCentsRatioSatsUsdPattern)
|
||||||
* @param {Object} args
|
* @param {Object} args
|
||||||
|
|||||||
@@ -183,6 +183,7 @@
|
|||||||
* @property {Color} color
|
* @property {Color} color
|
||||||
* @property {PatternAll} tree
|
* @property {PatternAll} tree
|
||||||
* @property {AddrCountPattern} addressCount
|
* @property {AddrCountPattern} addressCount
|
||||||
|
* @property {AvgAmountPattern} avgAmount
|
||||||
*
|
*
|
||||||
* Full cohort: adjustedSopr + percentiles + RelToMarketCap (term.short)
|
* Full cohort: adjustedSopr + percentiles + RelToMarketCap (term.short)
|
||||||
* @typedef {Object} CohortFull
|
* @typedef {Object} CohortFull
|
||||||
@@ -251,7 +252,7 @@
|
|||||||
* ============================================================================
|
* ============================================================================
|
||||||
*
|
*
|
||||||
* Addressable cohort with address count (for "type" cohorts - uses OutputsRealizedSupplyUnrealizedPattern2)
|
* Addressable cohort with address count (for "type" cohorts - uses OutputsRealizedSupplyUnrealizedPattern2)
|
||||||
* @typedef {{ name: string, title: string, color: Color, tree: EmptyPattern, addressCount: AddrCountPattern }} CohortAddr
|
* @typedef {{ name: string, key: AddressableType, title: string, color: Color, tree: EmptyPattern, addressCount: AddrCountPattern, avgAmount: AvgAmountPattern, exposed: ExposedTree, reused: ReusedTree }} CohortAddr
|
||||||
*
|
*
|
||||||
* ============================================================================
|
* ============================================================================
|
||||||
* Cohort Group Types (by capability)
|
* Cohort Group Types (by capability)
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ nav {
|
|||||||
}
|
}
|
||||||
|
|
||||||
a:visited {
|
a:visited {
|
||||||
color: transparent;
|
font-style: italic;
|
||||||
|
/*color: var(--orange);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
|
|||||||
@@ -72,7 +72,11 @@
|
|||||||
--block-gap: calc(
|
--block-gap: calc(
|
||||||
var(--min-gap) + var(--t) * (var(--max-gap) - var(--min-gap))
|
var(--min-gap) + var(--t) * (var(--max-gap) - var(--min-gap))
|
||||||
);
|
);
|
||||||
--empty-alpha: 0.5;
|
--empty-alpha: 0.3;
|
||||||
|
--iso-scale: 0.866;
|
||||||
|
--ox: 0.3;
|
||||||
|
--oy: 0.6;
|
||||||
|
--fill-pct: calc(var(--fill, 1) * 100%);
|
||||||
--face-step: 0.033;
|
--face-step: 0.033;
|
||||||
--face-right-color: light-dark(
|
--face-right-color: light-dark(
|
||||||
oklch(from var(--face-color) calc(l - var(--face-step) * 2) c h),
|
oklch(from var(--face-color) calc(l - var(--face-step) * 2) c h),
|
||||||
@@ -86,7 +90,6 @@
|
|||||||
var(--face-color),
|
var(--face-color),
|
||||||
oklch(from var(--face-color) calc(l + var(--face-step) * 2) c h)
|
oklch(from var(--face-color) calc(l + var(--face-step) * 2) c h)
|
||||||
);
|
);
|
||||||
/*margin-top: -0.375rem;*/
|
|
||||||
margin-left: calc(var(--cube) * -0.25);
|
margin-left: calc(var(--cube) * -0.25);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -97,29 +100,9 @@
|
|||||||
line-height: var(--line-height-sm);
|
line-height: var(--line-height-sm);
|
||||||
--face-color: var(--border-color);
|
--face-color: var(--border-color);
|
||||||
color: var(--color);
|
color: var(--color);
|
||||||
transition:
|
transition-property: color, background-color;
|
||||||
color,
|
|
||||||
background-color,
|
|
||||||
border-color,
|
|
||||||
outline-color,
|
|
||||||
text-decoration-color,
|
|
||||||
fill,
|
|
||||||
stroke,
|
|
||||||
opacity,
|
|
||||||
box-shadow,
|
|
||||||
transform,
|
|
||||||
translate,
|
|
||||||
scale,
|
|
||||||
rotate,
|
|
||||||
filter,
|
|
||||||
-webkit-backdrop-filter,
|
|
||||||
backdrop-filter,
|
|
||||||
display,
|
|
||||||
content-visibility,
|
|
||||||
overlay,
|
|
||||||
pointer-events;
|
|
||||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
transition-duration: 50ms;
|
transition-duration: 50ms;
|
||||||
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|
||||||
@@ -143,33 +126,74 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
width: var(--cube);
|
width: var(--cube);
|
||||||
height: var(--cube);
|
height: var(--cube);
|
||||||
|
}
|
||||||
|
|
||||||
|
.right,
|
||||||
|
.left,
|
||||||
|
.top {
|
||||||
padding: 0.1rem;
|
padding: 0.1rem;
|
||||||
backdrop-filter: blur(4px);
|
backdrop-filter: blur(4px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.inner-top {
|
.right,
|
||||||
backdrop-filter: none;
|
.left,
|
||||||
background-color: var(--face-top-color);
|
.rear-right,
|
||||||
/*-webkit-mask-image: linear-gradient(transparent, black 0.5rem, black calc(100% - 0.5rem), transparent);
|
.rear-left {
|
||||||
mask-image: linear-gradient(transparent, black 0.5rem, black calc(100% - 0.5rem), transparent);*/
|
background: linear-gradient(
|
||||||
|
to top,
|
||||||
|
var(--fc) var(--fill-pct),
|
||||||
|
oklch(from var(--fc) l c h / var(--empty-alpha)) var(--fill-pct)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom {
|
||||||
|
background-color: var(--face-color);
|
||||||
transform: rotate(30deg) skew(-30deg)
|
transform: rotate(30deg) skew(-30deg)
|
||||||
translate(
|
translate(
|
||||||
calc(var(--cube) * (1.99 - var(--fill, 1))),
|
calc(var(--cube) * (var(--ox) + 1 + var(--oy) / var(--iso-scale))),
|
||||||
calc(var(--cube) * (0.599 - 0.864 * var(--fill, 1)))
|
calc(var(--cube) * var(--oy))
|
||||||
)
|
)
|
||||||
scaleY(0.864);
|
scaleY(var(--iso-scale));
|
||||||
|
}
|
||||||
|
|
||||||
|
.rear-right {
|
||||||
|
--fc: var(--face-left-color);
|
||||||
|
transform: rotate(30deg) skewX(30deg)
|
||||||
|
translate(
|
||||||
|
calc(var(--cube) * (var(--ox) + 1)),
|
||||||
|
calc(var(--cube) * (var(--oy) - var(--iso-scale)))
|
||||||
|
)
|
||||||
|
scaleY(var(--iso-scale));
|
||||||
|
}
|
||||||
|
|
||||||
|
.rear-left {
|
||||||
|
--fc: var(--face-top-color);
|
||||||
|
transform: rotate(-30deg) skewX(-30deg)
|
||||||
|
translate(
|
||||||
|
calc(var(--cube) * (var(--ox) + 1)),
|
||||||
|
calc(var(--cube) * (var(--ox) * var(--iso-scale) + var(--oy)))
|
||||||
|
)
|
||||||
|
scale(-1, var(--iso-scale));
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner-top {
|
||||||
|
background-color: var(--face-top-color);
|
||||||
|
transform: rotate(30deg) skew(-30deg)
|
||||||
|
translate(
|
||||||
|
calc(var(--cube) * (var(--ox) + 1 + var(--oy) / var(--iso-scale) - var(--fill, 1))),
|
||||||
|
calc(var(--cube) * (var(--oy) - var(--iso-scale) * var(--fill, 1)))
|
||||||
|
)
|
||||||
|
scaleY(var(--iso-scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
.right {
|
.right {
|
||||||
background: linear-gradient(
|
--fc: var(--face-right-color);
|
||||||
to top,
|
|
||||||
var(--face-right-color) calc(var(--fill, 1) * 100%),
|
|
||||||
oklch(from var(--face-right-color) l c h / var(--empty-alpha))
|
|
||||||
calc(var(--fill, 1) * 100%)
|
|
||||||
);
|
|
||||||
transform: rotate(-30deg) skewX(-30deg)
|
transform: rotate(-30deg) skewX(-30deg)
|
||||||
translate(calc(var(--cube) * 1.3), calc(var(--cube) * 1.725))
|
translate(
|
||||||
scaleY(0.864);
|
calc(var(--cube) * (var(--ox) + 1)),
|
||||||
|
calc(var(--cube) * ((var(--ox) + 1) * var(--iso-scale) + var(--oy)))
|
||||||
|
)
|
||||||
|
scaleY(var(--iso-scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
.top {
|
.top {
|
||||||
@@ -179,8 +203,11 @@
|
|||||||
calc(var(--empty-alpha) + var(--is-full) * (1 - var(--empty-alpha)))
|
calc(var(--empty-alpha) + var(--is-full) * (1 - var(--empty-alpha)))
|
||||||
);
|
);
|
||||||
transform: rotate(30deg) skew(-30deg)
|
transform: rotate(30deg) skew(-30deg)
|
||||||
translate(calc(var(--cube) * 0.99), calc(var(--cube) * -0.265))
|
translate(
|
||||||
scaleY(0.864);
|
calc(var(--cube) * (var(--ox) + var(--oy) / var(--iso-scale))),
|
||||||
|
calc(var(--cube) * (var(--oy) - var(--iso-scale)))
|
||||||
|
)
|
||||||
|
scaleY(var(--iso-scale));
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -192,17 +219,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.left {
|
.left {
|
||||||
|
--fc: var(--face-left-color);
|
||||||
font-size: var(--font-size-xs);
|
font-size: var(--font-size-xs);
|
||||||
line-height: var(--line-height-xs);
|
line-height: var(--line-height-xs);
|
||||||
background: linear-gradient(
|
|
||||||
to top,
|
|
||||||
var(--face-left-color) calc(var(--fill, 1) * 100%),
|
|
||||||
oklch(from var(--face-left-color) l c h / var(--empty-alpha))
|
|
||||||
calc(var(--fill, 1) * 100%)
|
|
||||||
);
|
|
||||||
transform: rotate(30deg) skewX(30deg)
|
transform: rotate(30deg) skewX(30deg)
|
||||||
translate(calc(var(--cube) * 0.3), calc(var(--cube) * 0.6))
|
translate(
|
||||||
scaleY(0.864);
|
calc(var(--cube) * var(--ox)),
|
||||||
|
calc(var(--cube) * var(--oy))
|
||||||
|
)
|
||||||
|
scaleY(var(--iso-scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
&.skeleton {
|
&.skeleton {
|
||||||
|
|||||||
Reference in New Issue
Block a user