global: snapshot

This commit is contained in:
nym21
2026-01-18 16:04:24 +01:00
parent 4031bf3e79
commit c90953adbe
26 changed files with 1065 additions and 828 deletions

1
.gitignore vendored
View File

@@ -20,6 +20,7 @@ _*
/*.html /*.html
/research /research
/filter_* /filter_*
/heatmaps
# Logs # Logs
*.log* *.log*

33
Cargo.lock generated
View File

@@ -463,6 +463,7 @@ dependencies = [
"color-eyre", "color-eyre",
"derive_more", "derive_more",
"pco", "pco",
"plotters",
"rayon", "rayon",
"rustc-hash", "rustc-hash",
"schemars", "schemars",
@@ -562,6 +563,21 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "brk_playground"
version = "0.1.0-alpha.6"
dependencies = [
"brk_computer",
"brk_error",
"brk_fetcher",
"brk_indexer",
"brk_logger",
"brk_types",
"plotters",
"tracing",
"vecdb",
]
[[package]] [[package]]
name = "brk_query" name = "brk_query"
version = "0.1.0-alpha.6" version = "0.1.0-alpha.6"
@@ -628,9 +644,8 @@ dependencies = [
"brk_rpc", "brk_rpc",
"brk_traversable", "brk_traversable",
"brk_types", "brk_types",
"brk_website",
"derive_more", "derive_more",
"importmap",
"include_dir",
"jiff", "jiff",
"quick_cache", "quick_cache",
"schemars", "schemars",
@@ -695,6 +710,20 @@ dependencies = [
"vecdb", "vecdb",
] ]
[[package]]
name = "brk_website"
version = "0.1.0-alpha.6"
dependencies = [
"axum",
"brk_logger",
"importmap",
"include_dir",
"tokio",
"tower-http",
"tower-layer",
"tracing",
]
[[package]] [[package]]
name = "brotli" name = "brotli"
version = "8.0.2" version = "8.0.2"

View File

@@ -61,6 +61,7 @@ brk_store = { version = "0.1.0-alpha.6", path = "crates/brk_store" }
brk_traversable = { version = "0.1.0-alpha.6", path = "crates/brk_traversable", features = ["pco", "derive"] } brk_traversable = { version = "0.1.0-alpha.6", path = "crates/brk_traversable", features = ["pco", "derive"] }
brk_traversable_derive = { version = "0.1.0-alpha.6", path = "crates/brk_traversable_derive" } brk_traversable_derive = { version = "0.1.0-alpha.6", path = "crates/brk_traversable_derive" }
brk_types = { version = "0.1.0-alpha.6", path = "crates/brk_types" } brk_types = { version = "0.1.0-alpha.6", path = "crates/brk_types" }
brk_website = { version = "0.1.0-alpha.6", path = "crates/brk_website" }
byteview = "0.10.0" byteview = "0.10.0"
color-eyre = "0.6.5" color-eyre = "0.6.5"
derive_more = { version = "2.1.1", features = ["deref", "deref_mut"] } derive_more = { version = "2.1.1", features = ["deref", "deref_mut"] }
@@ -78,6 +79,8 @@ serde_json = { version = "1.0.149", features = ["float_roundtrip", "preserve_ord
smallvec = "1.15.1" smallvec = "1.15.1"
tokio = { version = "1.49.0", features = ["rt-multi-thread"] } tokio = { version = "1.49.0", features = ["rt-multi-thread"] }
tracing = { version = "0.1", default-features = false, features = ["std"] } tracing = { version = "0.1", default-features = false, features = ["std"] }
tower-http = { version = "0.6.8", features = ["catch-panic", "compression-br", "compression-gzip", "compression-zstd", "cors", "normalize-path", "timeout", "trace"] }
tower-layer = "0.3"
vecdb = { version = "0.5.11", features = ["derive", "serde_json", "pco", "schemars"] } vecdb = { version = "0.5.11", features = ["derive", "serde_json", "pco", "schemars"] }
# vecdb = { path = "../anydb/crates/vecdb", features = ["derive", "serde_json", "pco", "schemars"] } # vecdb = { path = "../anydb/crates/vecdb", features = ["derive", "serde_json", "pco", "schemars"] }

View File

@@ -2689,56 +2689,6 @@ impl Price111dSmaPattern {
} }
} }
/// Pattern struct for repeated tree structure.
pub struct PercentilesPattern {
pub pct05: MetricPattern4<Dollars>,
pub pct10: MetricPattern4<Dollars>,
pub pct15: MetricPattern4<Dollars>,
pub pct20: MetricPattern4<Dollars>,
pub pct25: MetricPattern4<Dollars>,
pub pct30: MetricPattern4<Dollars>,
pub pct35: MetricPattern4<Dollars>,
pub pct40: MetricPattern4<Dollars>,
pub pct45: MetricPattern4<Dollars>,
pub pct50: MetricPattern4<Dollars>,
pub pct55: MetricPattern4<Dollars>,
pub pct60: MetricPattern4<Dollars>,
pub pct65: MetricPattern4<Dollars>,
pub pct70: MetricPattern4<Dollars>,
pub pct75: MetricPattern4<Dollars>,
pub pct80: MetricPattern4<Dollars>,
pub pct85: MetricPattern4<Dollars>,
pub pct90: MetricPattern4<Dollars>,
pub pct95: MetricPattern4<Dollars>,
}
impl PercentilesPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
pct05: MetricPattern4::new(client.clone(), _m(&acc, "pct05")),
pct10: MetricPattern4::new(client.clone(), _m(&acc, "pct10")),
pct15: MetricPattern4::new(client.clone(), _m(&acc, "pct15")),
pct20: MetricPattern4::new(client.clone(), _m(&acc, "pct20")),
pct25: MetricPattern4::new(client.clone(), _m(&acc, "pct25")),
pct30: MetricPattern4::new(client.clone(), _m(&acc, "pct30")),
pct35: MetricPattern4::new(client.clone(), _m(&acc, "pct35")),
pct40: MetricPattern4::new(client.clone(), _m(&acc, "pct40")),
pct45: MetricPattern4::new(client.clone(), _m(&acc, "pct45")),
pct50: MetricPattern4::new(client.clone(), _m(&acc, "pct50")),
pct55: MetricPattern4::new(client.clone(), _m(&acc, "pct55")),
pct60: MetricPattern4::new(client.clone(), _m(&acc, "pct60")),
pct65: MetricPattern4::new(client.clone(), _m(&acc, "pct65")),
pct70: MetricPattern4::new(client.clone(), _m(&acc, "pct70")),
pct75: MetricPattern4::new(client.clone(), _m(&acc, "pct75")),
pct80: MetricPattern4::new(client.clone(), _m(&acc, "pct80")),
pct85: MetricPattern4::new(client.clone(), _m(&acc, "pct85")),
pct90: MetricPattern4::new(client.clone(), _m(&acc, "pct90")),
pct95: MetricPattern4::new(client.clone(), _m(&acc, "pct95")),
}
}
}
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct ActivePriceRatioPattern { pub struct ActivePriceRatioPattern {
pub ratio: MetricPattern4<StoredF32>, pub ratio: MetricPattern4<StoredF32>,
@@ -2789,6 +2739,56 @@ impl ActivePriceRatioPattern {
} }
} }
/// Pattern struct for repeated tree structure.
pub struct PercentilesPattern {
pub pct05: MetricPattern4<Dollars>,
pub pct10: MetricPattern4<Dollars>,
pub pct15: MetricPattern4<Dollars>,
pub pct20: MetricPattern4<Dollars>,
pub pct25: MetricPattern4<Dollars>,
pub pct30: MetricPattern4<Dollars>,
pub pct35: MetricPattern4<Dollars>,
pub pct40: MetricPattern4<Dollars>,
pub pct45: MetricPattern4<Dollars>,
pub pct50: MetricPattern4<Dollars>,
pub pct55: MetricPattern4<Dollars>,
pub pct60: MetricPattern4<Dollars>,
pub pct65: MetricPattern4<Dollars>,
pub pct70: MetricPattern4<Dollars>,
pub pct75: MetricPattern4<Dollars>,
pub pct80: MetricPattern4<Dollars>,
pub pct85: MetricPattern4<Dollars>,
pub pct90: MetricPattern4<Dollars>,
pub pct95: MetricPattern4<Dollars>,
}
impl PercentilesPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
pct05: MetricPattern4::new(client.clone(), _m(&acc, "pct05")),
pct10: MetricPattern4::new(client.clone(), _m(&acc, "pct10")),
pct15: MetricPattern4::new(client.clone(), _m(&acc, "pct15")),
pct20: MetricPattern4::new(client.clone(), _m(&acc, "pct20")),
pct25: MetricPattern4::new(client.clone(), _m(&acc, "pct25")),
pct30: MetricPattern4::new(client.clone(), _m(&acc, "pct30")),
pct35: MetricPattern4::new(client.clone(), _m(&acc, "pct35")),
pct40: MetricPattern4::new(client.clone(), _m(&acc, "pct40")),
pct45: MetricPattern4::new(client.clone(), _m(&acc, "pct45")),
pct50: MetricPattern4::new(client.clone(), _m(&acc, "pct50")),
pct55: MetricPattern4::new(client.clone(), _m(&acc, "pct55")),
pct60: MetricPattern4::new(client.clone(), _m(&acc, "pct60")),
pct65: MetricPattern4::new(client.clone(), _m(&acc, "pct65")),
pct70: MetricPattern4::new(client.clone(), _m(&acc, "pct70")),
pct75: MetricPattern4::new(client.clone(), _m(&acc, "pct75")),
pct80: MetricPattern4::new(client.clone(), _m(&acc, "pct80")),
pct85: MetricPattern4::new(client.clone(), _m(&acc, "pct85")),
pct90: MetricPattern4::new(client.clone(), _m(&acc, "pct90")),
pct95: MetricPattern4::new(client.clone(), _m(&acc, "pct95")),
}
}
}
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct RelativePattern5 { pub struct RelativePattern5 {
pub neg_unrealized_loss_rel_to_market_cap: MetricPattern1<StoredF32>, pub neg_unrealized_loss_rel_to_market_cap: MetricPattern1<StoredF32>,
@@ -3072,6 +3072,40 @@ impl BitcoinPattern {
} }
} }
/// Pattern struct for repeated tree structure.
pub struct ClassAveragePricePattern<T> {
pub _2015: MetricPattern4<T>,
pub _2016: MetricPattern4<T>,
pub _2017: MetricPattern4<T>,
pub _2018: MetricPattern4<T>,
pub _2019: MetricPattern4<T>,
pub _2020: MetricPattern4<T>,
pub _2021: MetricPattern4<T>,
pub _2022: MetricPattern4<T>,
pub _2023: MetricPattern4<T>,
pub _2024: MetricPattern4<T>,
pub _2025: MetricPattern4<T>,
}
impl<T: DeserializeOwned> ClassAveragePricePattern<T> {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
_2015: MetricPattern4::new(client.clone(), _m(&acc, "2015_average_price")),
_2016: MetricPattern4::new(client.clone(), _m(&acc, "2016_average_price")),
_2017: MetricPattern4::new(client.clone(), _m(&acc, "2017_average_price")),
_2018: MetricPattern4::new(client.clone(), _m(&acc, "2018_average_price")),
_2019: MetricPattern4::new(client.clone(), _m(&acc, "2019_average_price")),
_2020: MetricPattern4::new(client.clone(), _m(&acc, "2020_average_price")),
_2021: MetricPattern4::new(client.clone(), _m(&acc, "2021_average_price")),
_2022: MetricPattern4::new(client.clone(), _m(&acc, "2022_average_price")),
_2023: MetricPattern4::new(client.clone(), _m(&acc, "2023_average_price")),
_2024: MetricPattern4::new(client.clone(), _m(&acc, "2024_average_price")),
_2025: MetricPattern4::new(client.clone(), _m(&acc, "2025_average_price")),
}
}
}
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct DollarsPattern<T> { pub struct DollarsPattern<T> {
pub average: MetricPattern2<T>, pub average: MetricPattern2<T>,
@@ -3106,99 +3140,6 @@ impl<T: DeserializeOwned> DollarsPattern<T> {
} }
} }
/// Pattern struct for repeated tree structure.
pub struct ClassAveragePricePattern<T> {
pub _2015: MetricPattern4<T>,
pub _2016: MetricPattern4<T>,
pub _2017: MetricPattern4<T>,
pub _2018: MetricPattern4<T>,
pub _2019: MetricPattern4<T>,
pub _2020: MetricPattern4<T>,
pub _2021: MetricPattern4<T>,
pub _2022: MetricPattern4<T>,
pub _2023: MetricPattern4<T>,
pub _2024: MetricPattern4<T>,
pub _2025: MetricPattern4<T>,
}
impl<T: DeserializeOwned> ClassAveragePricePattern<T> {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
_2015: MetricPattern4::new(client.clone(), _m(&acc, "2015_returns")),
_2016: MetricPattern4::new(client.clone(), _m(&acc, "2016_returns")),
_2017: MetricPattern4::new(client.clone(), _m(&acc, "2017_returns")),
_2018: MetricPattern4::new(client.clone(), _m(&acc, "2018_returns")),
_2019: MetricPattern4::new(client.clone(), _m(&acc, "2019_returns")),
_2020: MetricPattern4::new(client.clone(), _m(&acc, "2020_returns")),
_2021: MetricPattern4::new(client.clone(), _m(&acc, "2021_returns")),
_2022: MetricPattern4::new(client.clone(), _m(&acc, "2022_returns")),
_2023: MetricPattern4::new(client.clone(), _m(&acc, "2023_returns")),
_2024: MetricPattern4::new(client.clone(), _m(&acc, "2024_returns")),
_2025: MetricPattern4::new(client.clone(), _m(&acc, "2025_returns")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct RelativePattern {
pub neg_unrealized_loss_rel_to_market_cap: MetricPattern1<StoredF32>,
pub net_unrealized_pnl_rel_to_market_cap: MetricPattern1<StoredF32>,
pub nupl: MetricPattern1<StoredF32>,
pub supply_in_loss_rel_to_circulating_supply: MetricPattern1<StoredF64>,
pub supply_in_loss_rel_to_own_supply: MetricPattern1<StoredF64>,
pub supply_in_profit_rel_to_circulating_supply: MetricPattern1<StoredF64>,
pub supply_in_profit_rel_to_own_supply: MetricPattern1<StoredF64>,
pub supply_rel_to_circulating_supply: MetricPattern4<StoredF64>,
pub unrealized_loss_rel_to_market_cap: MetricPattern1<StoredF32>,
pub unrealized_profit_rel_to_market_cap: MetricPattern1<StoredF32>,
}
impl RelativePattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
neg_unrealized_loss_rel_to_market_cap: MetricPattern1::new(
client.clone(),
_m(&acc, "neg_unrealized_loss_rel_to_market_cap"),
),
net_unrealized_pnl_rel_to_market_cap: MetricPattern1::new(
client.clone(),
_m(&acc, "net_unrealized_pnl_rel_to_market_cap"),
),
nupl: MetricPattern1::new(client.clone(), _m(&acc, "nupl")),
supply_in_loss_rel_to_circulating_supply: MetricPattern1::new(
client.clone(),
_m(&acc, "supply_in_loss_rel_to_circulating_supply"),
),
supply_in_loss_rel_to_own_supply: MetricPattern1::new(
client.clone(),
_m(&acc, "supply_in_loss_rel_to_own_supply"),
),
supply_in_profit_rel_to_circulating_supply: MetricPattern1::new(
client.clone(),
_m(&acc, "supply_in_profit_rel_to_circulating_supply"),
),
supply_in_profit_rel_to_own_supply: MetricPattern1::new(
client.clone(),
_m(&acc, "supply_in_profit_rel_to_own_supply"),
),
supply_rel_to_circulating_supply: MetricPattern4::new(
client.clone(),
_m(&acc, "supply_rel_to_circulating_supply"),
),
unrealized_loss_rel_to_market_cap: MetricPattern1::new(
client.clone(),
_m(&acc, "unrealized_loss_rel_to_market_cap"),
),
unrealized_profit_rel_to_market_cap: MetricPattern1::new(
client.clone(),
_m(&acc, "unrealized_profit_rel_to_market_cap"),
),
}
}
}
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct RelativePattern2 { pub struct RelativePattern2 {
pub neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1<StoredF32>, pub neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1<StoredF32>,
@@ -3261,6 +3202,65 @@ impl RelativePattern2 {
} }
} }
/// Pattern struct for repeated tree structure.
pub struct RelativePattern {
pub neg_unrealized_loss_rel_to_market_cap: MetricPattern1<StoredF32>,
pub net_unrealized_pnl_rel_to_market_cap: MetricPattern1<StoredF32>,
pub nupl: MetricPattern1<StoredF32>,
pub supply_in_loss_rel_to_circulating_supply: MetricPattern1<StoredF64>,
pub supply_in_loss_rel_to_own_supply: MetricPattern1<StoredF64>,
pub supply_in_profit_rel_to_circulating_supply: MetricPattern1<StoredF64>,
pub supply_in_profit_rel_to_own_supply: MetricPattern1<StoredF64>,
pub supply_rel_to_circulating_supply: MetricPattern4<StoredF64>,
pub unrealized_loss_rel_to_market_cap: MetricPattern1<StoredF32>,
pub unrealized_profit_rel_to_market_cap: MetricPattern1<StoredF32>,
}
impl RelativePattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
neg_unrealized_loss_rel_to_market_cap: MetricPattern1::new(
client.clone(),
_m(&acc, "neg_unrealized_loss_rel_to_market_cap"),
),
net_unrealized_pnl_rel_to_market_cap: MetricPattern1::new(
client.clone(),
_m(&acc, "net_unrealized_pnl_rel_to_market_cap"),
),
nupl: MetricPattern1::new(client.clone(), _m(&acc, "nupl")),
supply_in_loss_rel_to_circulating_supply: MetricPattern1::new(
client.clone(),
_m(&acc, "supply_in_loss_rel_to_circulating_supply"),
),
supply_in_loss_rel_to_own_supply: MetricPattern1::new(
client.clone(),
_m(&acc, "supply_in_loss_rel_to_own_supply"),
),
supply_in_profit_rel_to_circulating_supply: MetricPattern1::new(
client.clone(),
_m(&acc, "supply_in_profit_rel_to_circulating_supply"),
),
supply_in_profit_rel_to_own_supply: MetricPattern1::new(
client.clone(),
_m(&acc, "supply_in_profit_rel_to_own_supply"),
),
supply_rel_to_circulating_supply: MetricPattern4::new(
client.clone(),
_m(&acc, "supply_rel_to_circulating_supply"),
),
unrealized_loss_rel_to_market_cap: MetricPattern1::new(
client.clone(),
_m(&acc, "unrealized_loss_rel_to_market_cap"),
),
unrealized_profit_rel_to_market_cap: MetricPattern1::new(
client.clone(),
_m(&acc, "unrealized_profit_rel_to_market_cap"),
),
}
}
}
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct CountPattern2<T> { pub struct CountPattern2<T> {
pub average: MetricPattern1<T>, pub average: MetricPattern1<T>,
@@ -3466,25 +3466,25 @@ impl PeriodCagrPattern {
} }
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct _0satsPattern2 { pub struct _10yTo12yPattern {
pub activity: ActivityPattern2, pub activity: ActivityPattern2,
pub cost_basis: CostBasisPattern, pub cost_basis: CostBasisPattern2,
pub outputs: OutputsPattern, pub outputs: OutputsPattern,
pub realized: RealizedPattern, pub realized: RealizedPattern2,
pub relative: RelativePattern4, pub relative: RelativePattern2,
pub supply: SupplyPattern2, pub supply: SupplyPattern2,
pub unrealized: UnrealizedPattern, pub unrealized: UnrealizedPattern,
} }
impl _0satsPattern2 { impl _10yTo12yPattern {
/// Create a new pattern node with accumulated metric name. /// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self { pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self { Self {
activity: ActivityPattern2::new(client.clone(), acc.clone()), activity: ActivityPattern2::new(client.clone(), acc.clone()),
cost_basis: CostBasisPattern::new(client.clone(), acc.clone()), cost_basis: CostBasisPattern2::new(client.clone(), acc.clone()),
outputs: OutputsPattern::new(client.clone(), _m(&acc, "utxo_count")), outputs: OutputsPattern::new(client.clone(), _m(&acc, "utxo_count")),
realized: RealizedPattern::new(client.clone(), acc.clone()), realized: RealizedPattern2::new(client.clone(), acc.clone()),
relative: RelativePattern4::new(client.clone(), _m(&acc, "supply_in")), relative: RelativePattern2::new(client.clone(), acc.clone()),
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")), supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()), unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
} }
@@ -3518,25 +3518,25 @@ impl _10yPattern {
} }
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct _10yTo12yPattern { pub struct _0satsPattern2 {
pub activity: ActivityPattern2, pub activity: ActivityPattern2,
pub cost_basis: CostBasisPattern2, pub cost_basis: CostBasisPattern,
pub outputs: OutputsPattern, pub outputs: OutputsPattern,
pub realized: RealizedPattern2, pub realized: RealizedPattern,
pub relative: RelativePattern2, pub relative: RelativePattern4,
pub supply: SupplyPattern2, pub supply: SupplyPattern2,
pub unrealized: UnrealizedPattern, pub unrealized: UnrealizedPattern,
} }
impl _10yTo12yPattern { impl _0satsPattern2 {
/// Create a new pattern node with accumulated metric name. /// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self { pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self { Self {
activity: ActivityPattern2::new(client.clone(), acc.clone()), activity: ActivityPattern2::new(client.clone(), acc.clone()),
cost_basis: CostBasisPattern2::new(client.clone(), acc.clone()), cost_basis: CostBasisPattern::new(client.clone(), acc.clone()),
outputs: OutputsPattern::new(client.clone(), _m(&acc, "utxo_count")), outputs: OutputsPattern::new(client.clone(), _m(&acc, "utxo_count")),
realized: RealizedPattern2::new(client.clone(), acc.clone()), realized: RealizedPattern::new(client.clone(), acc.clone()),
relative: RelativePattern2::new(client.clone(), acc.clone()), relative: RelativePattern4::new(client.clone(), _m(&acc, "supply_in")),
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")), supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()), unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
} }
@@ -3655,24 +3655,6 @@ impl<T: DeserializeOwned> SplitPattern2<T> {
} }
} }
/// Pattern struct for repeated tree structure.
pub struct CostBasisPattern2 {
pub max: MetricPattern1<Dollars>,
pub min: MetricPattern1<Dollars>,
pub percentiles: PercentilesPattern,
}
impl CostBasisPattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
max: MetricPattern1::new(client.clone(), _m(&acc, "max_cost_basis")),
min: MetricPattern1::new(client.clone(), _m(&acc, "min_cost_basis")),
percentiles: PercentilesPattern::new(client.clone(), _m(&acc, "cost_basis")),
}
}
}
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct CoinbasePattern { pub struct CoinbasePattern {
pub bitcoin: BitcoinPattern, pub bitcoin: BitcoinPattern,
@@ -3692,19 +3674,55 @@ impl CoinbasePattern {
} }
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct ActiveSupplyPattern { pub struct CoinbasePattern2 {
pub bitcoin: MetricPattern1<Bitcoin>, pub bitcoin: BlockCountPattern<Bitcoin>,
pub dollars: MetricPattern1<Dollars>, pub dollars: BlockCountPattern<Dollars>,
pub sats: MetricPattern1<Sats>, pub sats: BlockCountPattern<Sats>,
} }
impl ActiveSupplyPattern { impl CoinbasePattern2 {
/// Create a new pattern node with accumulated metric name. /// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self { pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self { Self {
bitcoin: MetricPattern1::new(client.clone(), _m(&acc, "btc")), bitcoin: BlockCountPattern::new(client.clone(), _m(&acc, "btc")),
dollars: MetricPattern1::new(client.clone(), _m(&acc, "usd")), dollars: BlockCountPattern::new(client.clone(), _m(&acc, "usd")),
sats: MetricPattern1::new(client.clone(), acc.clone()), sats: BlockCountPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct SegwitAdoptionPattern {
pub base: MetricPattern11<StoredF32>,
pub cumulative: MetricPattern2<StoredF32>,
pub sum: MetricPattern2<StoredF32>,
}
impl SegwitAdoptionPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
base: MetricPattern11::new(client.clone(), acc.clone()),
cumulative: MetricPattern2::new(client.clone(), _m(&acc, "cumulative")),
sum: MetricPattern2::new(client.clone(), _m(&acc, "sum")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct CostBasisPattern2 {
pub max: MetricPattern1<Dollars>,
pub min: MetricPattern1<Dollars>,
pub percentiles: PercentilesPattern,
}
impl CostBasisPattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
max: MetricPattern1::new(client.clone(), _m(&acc, "max_cost_basis")),
min: MetricPattern1::new(client.clone(), _m(&acc, "min_cost_basis")),
percentiles: PercentilesPattern::new(client.clone(), _m(&acc, "cost_basis")),
} }
} }
} }
@@ -3727,24 +3745,6 @@ impl UnclaimedRewardsPattern {
} }
} }
/// Pattern struct for repeated tree structure.
pub struct CoinbasePattern2 {
pub bitcoin: BlockCountPattern<Bitcoin>,
pub dollars: BlockCountPattern<Dollars>,
pub sats: BlockCountPattern<Sats>,
}
impl CoinbasePattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
bitcoin: BlockCountPattern::new(client.clone(), _m(&acc, "btc")),
dollars: BlockCountPattern::new(client.clone(), _m(&acc, "usd")),
sats: BlockCountPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct _2015Pattern { pub struct _2015Pattern {
pub bitcoin: MetricPattern4<Bitcoin>, pub bitcoin: MetricPattern4<Bitcoin>,
@@ -3764,19 +3764,19 @@ impl _2015Pattern {
} }
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct SegwitAdoptionPattern { pub struct ActiveSupplyPattern {
pub base: MetricPattern11<StoredF32>, pub bitcoin: MetricPattern1<Bitcoin>,
pub cumulative: MetricPattern2<StoredF32>, pub dollars: MetricPattern1<Dollars>,
pub sum: MetricPattern2<StoredF32>, pub sats: MetricPattern1<Sats>,
} }
impl SegwitAdoptionPattern { impl ActiveSupplyPattern {
/// Create a new pattern node with accumulated metric name. /// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self { pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self { Self {
base: MetricPattern11::new(client.clone(), acc.clone()), bitcoin: MetricPattern1::new(client.clone(), _m(&acc, "btc")),
cumulative: MetricPattern2::new(client.clone(), _m(&acc, "cumulative")), dollars: MetricPattern1::new(client.clone(), _m(&acc, "usd")),
sum: MetricPattern2::new(client.clone(), _m(&acc, "sum")), sats: MetricPattern1::new(client.clone(), acc.clone()),
} }
} }
} }
@@ -3797,6 +3797,22 @@ impl _1dReturns1mSdPattern {
} }
} }
/// Pattern struct for repeated tree structure.
pub struct SupplyPattern2 {
pub halved: ActiveSupplyPattern,
pub total: ActiveSupplyPattern,
}
impl SupplyPattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
halved: ActiveSupplyPattern::new(client.clone(), _m(&acc, "halved")),
total: ActiveSupplyPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct CostBasisPattern { pub struct CostBasisPattern {
pub max: MetricPattern1<Dollars>, pub max: MetricPattern1<Dollars>,
@@ -3835,22 +3851,6 @@ impl RelativePattern4 {
} }
} }
/// Pattern struct for repeated tree structure.
pub struct SupplyPattern2 {
pub halved: ActiveSupplyPattern,
pub total: ActiveSupplyPattern,
}
impl SupplyPattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
halved: ActiveSupplyPattern::new(client.clone(), _m(&acc, "halved")),
total: ActiveSupplyPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct BitcoinPattern2<T> { pub struct BitcoinPattern2<T> {
pub cumulative: MetricPattern2<T>, pub cumulative: MetricPattern2<T>,
@@ -3899,20 +3899,6 @@ impl<T: DeserializeOwned> BlockCountPattern<T> {
} }
} }
/// Pattern struct for repeated tree structure.
pub struct OutputsPattern {
pub utxo_count: MetricPattern1<StoredU64>,
}
impl OutputsPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
utxo_count: MetricPattern1::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure. /// Pattern struct for repeated tree structure.
pub struct RealizedPriceExtraPattern { pub struct RealizedPriceExtraPattern {
pub ratio: MetricPattern4<StoredF32>, pub ratio: MetricPattern4<StoredF32>,
@@ -3927,6 +3913,20 @@ impl RealizedPriceExtraPattern {
} }
} }
/// Pattern struct for repeated tree structure.
pub struct OutputsPattern {
pub utxo_count: MetricPattern1<StoredU64>,
}
impl OutputsPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
utxo_count: MetricPattern1::new(client.clone(), acc.clone()),
}
}
}
// Metrics tree // Metrics tree
/// Metrics tree node. /// Metrics tree node.
@@ -6191,8 +6191,8 @@ impl MetricsTree_Market_Ath {
/// Metrics tree node. /// Metrics tree node.
pub struct MetricsTree_Market_Dca { pub struct MetricsTree_Market_Dca {
pub class_average_price: MetricsTree_Market_Dca_ClassAveragePrice, pub class_average_price: ClassAveragePricePattern<Dollars>,
pub class_returns: ClassAveragePricePattern<StoredF32>, pub class_returns: MetricsTree_Market_Dca_ClassReturns,
pub class_stack: MetricsTree_Market_Dca_ClassStack, pub class_stack: MetricsTree_Market_Dca_ClassStack,
pub period_average_price: PeriodAveragePricePattern<Dollars>, pub period_average_price: PeriodAveragePricePattern<Dollars>,
pub period_cagr: PeriodCagrPattern, pub period_cagr: PeriodCagrPattern,
@@ -6204,11 +6204,14 @@ pub struct MetricsTree_Market_Dca {
impl MetricsTree_Market_Dca { impl MetricsTree_Market_Dca {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self { pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self { Self {
class_average_price: MetricsTree_Market_Dca_ClassAveragePrice::new( class_average_price: ClassAveragePricePattern::new(
client.clone(), client.clone(),
format!("{base_path}_class_average_price"), "dca_class".to_string(),
),
class_returns: MetricsTree_Market_Dca_ClassReturns::new(
client.clone(),
format!("{base_path}_class_returns"),
), ),
class_returns: ClassAveragePricePattern::new(client.clone(), "dca_class".to_string()),
class_stack: MetricsTree_Market_Dca_ClassStack::new( class_stack: MetricsTree_Market_Dca_ClassStack::new(
client.clone(), client.clone(),
format!("{base_path}_class_stack"), format!("{base_path}_class_stack"),
@@ -6232,34 +6235,34 @@ impl MetricsTree_Market_Dca {
} }
/// Metrics tree node. /// Metrics tree node.
pub struct MetricsTree_Market_Dca_ClassAveragePrice { pub struct MetricsTree_Market_Dca_ClassReturns {
pub _2015: MetricPattern4<Dollars>, pub _2015: MetricPattern4<StoredF32>,
pub _2016: MetricPattern4<Dollars>, pub _2016: MetricPattern4<StoredF32>,
pub _2017: MetricPattern4<Dollars>, pub _2017: MetricPattern4<StoredF32>,
pub _2018: MetricPattern4<Dollars>, pub _2018: MetricPattern4<StoredF32>,
pub _2019: MetricPattern4<Dollars>, pub _2019: MetricPattern4<StoredF32>,
pub _2020: MetricPattern4<Dollars>, pub _2020: MetricPattern4<StoredF32>,
pub _2021: MetricPattern4<Dollars>, pub _2021: MetricPattern4<StoredF32>,
pub _2022: MetricPattern4<Dollars>, pub _2022: MetricPattern4<StoredF32>,
pub _2023: MetricPattern4<Dollars>, pub _2023: MetricPattern4<StoredF32>,
pub _2024: MetricPattern4<Dollars>, pub _2024: MetricPattern4<StoredF32>,
pub _2025: MetricPattern4<Dollars>, pub _2025: MetricPattern4<StoredF32>,
} }
impl MetricsTree_Market_Dca_ClassAveragePrice { impl MetricsTree_Market_Dca_ClassReturns {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self { pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self { Self {
_2015: MetricPattern4::new(client.clone(), "dca_class_2015_average_price".to_string()), _2015: MetricPattern4::new(client.clone(), "dca_class_2015_returns".to_string()),
_2016: MetricPattern4::new(client.clone(), "dca_class_2016_average_price".to_string()), _2016: MetricPattern4::new(client.clone(), "dca_class_2016_returns".to_string()),
_2017: MetricPattern4::new(client.clone(), "dca_class_2017_average_price".to_string()), _2017: MetricPattern4::new(client.clone(), "dca_class_2017_returns".to_string()),
_2018: MetricPattern4::new(client.clone(), "dca_class_2018_average_price".to_string()), _2018: MetricPattern4::new(client.clone(), "dca_class_2018_returns".to_string()),
_2019: MetricPattern4::new(client.clone(), "dca_class_2019_average_price".to_string()), _2019: MetricPattern4::new(client.clone(), "dca_class_2019_returns".to_string()),
_2020: MetricPattern4::new(client.clone(), "dca_class_2020_average_price".to_string()), _2020: MetricPattern4::new(client.clone(), "dca_class_2020_returns".to_string()),
_2021: MetricPattern4::new(client.clone(), "dca_class_2021_average_price".to_string()), _2021: MetricPattern4::new(client.clone(), "dca_class_2021_returns".to_string()),
_2022: MetricPattern4::new(client.clone(), "dca_class_2022_average_price".to_string()), _2022: MetricPattern4::new(client.clone(), "dca_class_2022_returns".to_string()),
_2023: MetricPattern4::new(client.clone(), "dca_class_2023_average_price".to_string()), _2023: MetricPattern4::new(client.clone(), "dca_class_2023_returns".to_string()),
_2024: MetricPattern4::new(client.clone(), "dca_class_2024_average_price".to_string()), _2024: MetricPattern4::new(client.clone(), "dca_class_2024_returns".to_string()),
_2025: MetricPattern4::new(client.clone(), "dca_class_2025_average_price".to_string()), _2025: MetricPattern4::new(client.clone(), "dca_class_2025_returns".to_string()),
} }
} }
} }
@@ -7599,7 +7602,7 @@ pub struct BrkClient {
impl BrkClient { impl BrkClient {
/// Client version. /// Client version.
pub const VERSION: &'static str = "v0.1.0-alpha.3"; pub const VERSION: &'static str = "v0.1.0-alpha.6";
/// Create a new client with the given base URL. /// Create a new client with the given base URL.
pub fn new(base_url: impl Into<String>) -> Self { pub fn new(base_url: impl Into<String>) -> Self {

View File

@@ -32,5 +32,6 @@ vecdb = { workspace = true }
[dev-dependencies] [dev-dependencies]
brk_alloc = { workspace = true } brk_alloc = { workspace = true }
plotters = "0.3"
brk_bencher = { workspace = true } brk_bencher = { workspace = true }
color-eyre = { workspace = true } color-eyre = { workspace = true }

View File

@@ -4,7 +4,7 @@ use brk_error::Result;
use brk_indexer::Indexer; use brk_indexer::Indexer;
use brk_traversable::Traversable; use brk_traversable::Traversable;
use brk_types::{ use brk_types::{
EmptyAddressData, EmptyAddressIndex, Height, LoadedAddressData, LoadedAddressIndex, DateIndex, EmptyAddressData, EmptyAddressIndex, Height, LoadedAddressData, LoadedAddressIndex,
SupplyState, Version, SupplyState, Version,
}; };
use tracing::info; use tracing::info;
@@ -242,6 +242,21 @@ impl Vecs {
(recovered_height, chain_state) (recovered_height, chain_state)
}; };
// Update starting_indexes if we need to recompute from an earlier point
if starting_height < starting_indexes.height {
starting_indexes.height = starting_height;
// Also update dateindex to match
if starting_height.is_zero() {
starting_indexes.dateindex = DateIndex::from(0);
} else {
starting_indexes.dateindex = indexes
.height
.dateindex
.read_once(starting_height.decremented().unwrap())?
.into();
}
}
// 2b. Validate computed versions // 2b. Validate computed versions
let base_version = VERSION; let base_version = VERSION;
self.utxo_cohorts.validate_computed_versions(base_version)?; self.utxo_cohorts.validate_computed_versions(base_version)?;

View File

@@ -15,14 +15,14 @@ mod blocks;
mod cointime; mod cointime;
mod constants; mod constants;
mod distribution; mod distribution;
mod indexes; pub mod indexes;
mod inputs; mod inputs;
mod internal; mod internal;
mod market; mod market;
mod outputs; mod outputs;
mod pools; mod pools;
mod positions; mod positions;
mod price; pub mod price;
mod scripts; mod scripts;
mod supply; mod supply;
mod traits; mod traits;

7
crates/brk_playground/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
# Ignore everything in playground except essential files
*
!.gitignore
!Cargo.toml
!src/
!src/lib.rs
!README.md

View File

@@ -0,0 +1,20 @@
[package]
name = "brk_playground"
description = "Experimental playground for brk development"
version.workspace = true
edition.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
publish = false
[dependencies]
brk_computer = { workspace = true }
brk_error = { workspace = true }
brk_fetcher = { workspace = true }
brk_indexer = { workspace = true }
brk_logger = { workspace = true }
brk_types = { workspace = true }
plotters = "0.3"
tracing = { workspace = true }
vecdb = { workspace = true }

View File

@@ -0,0 +1,4 @@
//! Experimental playground for brk development.
//!
//! This crate is for experiments and prototypes.
//! Most contents are git-ignored.

View File

@@ -6,7 +6,6 @@ edition.workspace = true
license.workspace = true license.workspace = true
homepage.workspace = true homepage.workspace = true
repository.workspace = true repository.workspace = true
include = ["src/**/*", "website/**/*", "examples/**/*", "Cargo.toml", "README.md"]
[dependencies] [dependencies]
aide = { workspace = true } aide = { workspace = true }
@@ -22,10 +21,8 @@ brk_reader = { workspace = true }
brk_rpc = { workspace = true } brk_rpc = { workspace = true }
brk_types = { workspace = true } brk_types = { workspace = true }
brk_traversable = { workspace = true } brk_traversable = { workspace = true }
brk_website = { workspace = true }
derive_more = { workspace = true } derive_more = { workspace = true }
include_dir = "0.7"
# importmap = { path = "../../../importmap", features = ["embedded"] }
importmap = { version = "0.3.0", features = ["embedded"] }
vecdb = { workspace = true } vecdb = { workspace = true }
jiff = { workspace = true } jiff = { workspace = true }
quick_cache = "0.6.18" quick_cache = "0.6.18"
@@ -34,8 +31,8 @@ serde = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }
tracing = { workspace = true } tracing = { workspace = true }
tower-http = { version = "0.6.8", features = ["catch-panic", "compression-br", "compression-gzip", "compression-zstd", "cors", "normalize-path", "timeout", "trace"] } tower-http = { workspace = true }
tower-layer = "0.3" tower-layer = { workspace = true }
[dev-dependencies] [dev-dependencies]
brk_mempool = { workspace = true } brk_mempool = { workspace = true }

View File

@@ -1,5 +1,3 @@
use std::path::Path;
use axum::http::{ use axum::http::{
HeaderMap, HeaderMap,
header::{self, IF_NONE_MATCH}, header::{self, IF_NONE_MATCH},
@@ -7,31 +5,29 @@ use axum::http::{
pub trait HeaderMapExtended { pub trait HeaderMapExtended {
fn has_etag(&self, etag: &str) -> bool; fn has_etag(&self, etag: &str) -> bool;
fn insert_etag(&mut self, etag: &str);
fn insert_cache_control(&mut self, value: &str); fn insert_cache_control(&mut self, value: &str);
fn insert_cache_control_must_revalidate(&mut self); fn insert_cache_control_must_revalidate(&mut self);
fn insert_cache_control_immutable(&mut self);
fn insert_etag(&mut self, etag: &str);
fn insert_content_disposition_attachment(&mut self); fn insert_content_disposition_attachment(&mut self);
fn insert_content_type(&mut self, path: &Path);
fn insert_content_type_image_icon(&mut self);
fn insert_content_type_image_jpeg(&mut self);
fn insert_content_type_image_png(&mut self);
fn insert_content_type_application_javascript(&mut self);
fn insert_content_type_application_json(&mut self); fn insert_content_type_application_json(&mut self);
fn insert_content_type_application_manifest_json(&mut self);
fn insert_content_type_application_pdf(&mut self);
fn insert_content_type_text_css(&mut self);
fn insert_content_type_text_csv(&mut self); fn insert_content_type_text_csv(&mut self);
fn insert_content_type_text_html(&mut self);
fn insert_content_type_text_plain(&mut self); fn insert_content_type_text_plain(&mut self);
fn insert_content_type_font_woff2(&mut self);
fn insert_content_type_octet_stream(&mut self); fn insert_content_type_octet_stream(&mut self);
} }
impl HeaderMapExtended for HeaderMap { impl HeaderMapExtended for HeaderMap {
fn has_etag(&self, etag: &str) -> bool {
self.get(IF_NONE_MATCH)
.is_some_and(|prev_etag| etag == prev_etag)
}
fn insert_etag(&mut self, etag: &str) {
self.insert(header::ETAG, etag.parse().unwrap());
}
fn insert_cache_control(&mut self, value: &str) { fn insert_cache_control(&mut self, value: &str) {
self.insert(header::CACHE_CONTROL, value.parse().unwrap()); self.insert(header::CACHE_CONTROL, value.parse().unwrap());
} }
@@ -40,99 +36,22 @@ impl HeaderMapExtended for HeaderMap {
self.insert_cache_control("public, max-age=1, must-revalidate"); self.insert_cache_control("public, max-age=1, must-revalidate");
} }
fn insert_cache_control_immutable(&mut self) {
self.insert_cache_control("public, max-age=31536000, immutable");
}
fn insert_content_disposition_attachment(&mut self) { fn insert_content_disposition_attachment(&mut self) {
self.insert(header::CONTENT_DISPOSITION, "attachment".parse().unwrap()); self.insert(header::CONTENT_DISPOSITION, "attachment".parse().unwrap());
} }
fn insert_etag(&mut self, etag: &str) {
self.insert(header::ETAG, etag.parse().unwrap());
}
fn has_etag(&self, etag: &str) -> bool {
self.get(IF_NONE_MATCH)
.is_some_and(|prev_etag| etag == prev_etag)
}
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
fn insert_content_type(&mut self, path: &Path) {
match path
.extension()
.map(|s| s.to_str().unwrap_or_default())
.unwrap_or_default()
{
"js" | "mjs" => self.insert_content_type_application_javascript(),
"json" | "map" => self.insert_content_type_application_json(),
"html" => self.insert_content_type_text_html(),
"css" => self.insert_content_type_text_css(),
"toml" | "txt" => self.insert_content_type_text_plain(),
"pdf" => self.insert_content_type_application_pdf(),
"woff2" => self.insert_content_type_font_woff2(),
"ico" => self.insert_content_type_image_icon(),
"jpg" | "jpeg" => self.insert_content_type_image_jpeg(),
"png" => self.insert_content_type_image_png(),
"webmanifest" => self.insert_content_type_application_manifest_json(),
_ => {}
}
}
fn insert_content_type_image_icon(&mut self) {
self.insert(header::CONTENT_TYPE, "image/x-icon".parse().unwrap());
}
fn insert_content_type_image_jpeg(&mut self) {
self.insert(header::CONTENT_TYPE, "image/jpeg".parse().unwrap());
}
fn insert_content_type_image_png(&mut self) {
self.insert(header::CONTENT_TYPE, "image/png".parse().unwrap());
}
fn insert_content_type_application_javascript(&mut self) {
self.insert(
header::CONTENT_TYPE,
"application/javascript".parse().unwrap(),
);
}
fn insert_content_type_application_json(&mut self) { fn insert_content_type_application_json(&mut self) {
self.insert(header::CONTENT_TYPE, "application/json".parse().unwrap()); self.insert(header::CONTENT_TYPE, "application/json".parse().unwrap());
} }
fn insert_content_type_application_manifest_json(&mut self) {
self.insert(
header::CONTENT_TYPE,
"application/manifest+json".parse().unwrap(),
);
}
fn insert_content_type_application_pdf(&mut self) {
self.insert(header::CONTENT_TYPE, "application/pdf".parse().unwrap());
}
fn insert_content_type_text_css(&mut self) {
self.insert(header::CONTENT_TYPE, "text/css".parse().unwrap());
}
fn insert_content_type_text_csv(&mut self) { fn insert_content_type_text_csv(&mut self) {
self.insert(header::CONTENT_TYPE, "text/csv".parse().unwrap()); self.insert(header::CONTENT_TYPE, "text/csv".parse().unwrap());
} }
fn insert_content_type_text_html(&mut self) {
self.insert(header::CONTENT_TYPE, "text/html".parse().unwrap());
}
fn insert_content_type_text_plain(&mut self) { fn insert_content_type_text_plain(&mut self) {
self.insert(header::CONTENT_TYPE, "text/plain".parse().unwrap()); self.insert(header::CONTENT_TYPE, "text/plain".parse().unwrap());
} }
fn insert_content_type_font_woff2(&mut self) {
self.insert(header::CONTENT_TYPE, "font/woff2".parse().unwrap());
}
fn insert_content_type_octet_stream(&mut self) { fn insert_content_type_octet_stream(&mut self) {
self.insert( self.insert(
header::CONTENT_TYPE, header::CONTENT_TYPE,

View File

@@ -1,25 +0,0 @@
use aide::axum::ApiRouter;
use axum::{response::Redirect, routing::get};
use super::AppState;
mod file;
mod website;
use file::{file_handler, index_handler};
pub use website::*;
pub trait FilesRoutes {
fn add_files_routes(self, website: &Website) -> Self;
}
impl FilesRoutes for ApiRouter<AppState> {
fn add_files_routes(self, website: &Website) -> Self {
if website.is_enabled() {
self.route("/{*path}", get(file_handler))
.route("/", get(index_handler))
} else {
self.route("/", get(Redirect::temporary("/api")))
}
}
}

View File

@@ -18,7 +18,6 @@ use axum::{
serve, serve,
}; };
use brk_query::AsyncQuery; use brk_query::AsyncQuery;
use include_dir::{Dir, include_dir};
use quick_cache::sync::Cache; use quick_cache::sync::Cache;
use tokio::net::TcpListener; use tokio::net::TcpListener;
use tower_http::{ use tower_http::{
@@ -29,23 +28,17 @@ use tower_http::{
use tower_layer::Layer; use tower_layer::Layer;
use tracing::{error, info}; use tracing::{error, info};
/// Embedded website assets
pub static EMBEDDED_WEBSITE: Dir = include_dir!("$CARGO_MANIFEST_DIR/website");
mod api; mod api;
pub mod cache; pub mod cache;
mod error; mod error;
mod extended; mod extended;
mod files;
mod state; mod state;
use api::*; use api::*;
pub use brk_types::Port; pub use brk_types::Port;
pub use brk_website::Website;
pub use cache::{CacheParams, CacheStrategy}; pub use cache::{CacheParams, CacheStrategy};
pub use error::{Error, Result}; pub use error::{Error, Result};
use extended::*;
use files::FilesRoutes;
pub use files::Website;
use state::*; use state::*;
pub const VERSION: &str = env!("CARGO_PKG_VERSION"); pub const VERSION: &str = env!("CARGO_PKG_VERSION");
@@ -69,10 +62,7 @@ impl Server {
pub async fn serve(self, port: Option<Port>) -> brk_error::Result<()> { pub async fn serve(self, port: Option<Port>) -> brk_error::Result<()> {
let state = self.0; let state = self.0;
let compression_layer = CompressionLayer::new() let compression_layer = CompressionLayer::new().br(true).gzip(true).zstd(true);
.br(true)
.gzip(true)
.zstd(true);
let response_uri_layer = axum::middleware::from_fn( let response_uri_layer = axum::middleware::from_fn(
async |request: Request<Body>, next: Next| -> Response<Body> { async |request: Request<Body>, next: Next| -> Response<Body> {
@@ -107,35 +97,23 @@ impl Server {
.on_eos(()); .on_eos(());
let vecs = state.query.inner().vecs(); let vecs = state.query.inner().vecs();
let router = ApiRouter::new()
.add_api_routes() let website_router = brk_website::router(state.website.clone());
.add_files_routes(&state.website) let mut router = ApiRouter::new().add_api_routes();
.route( if !state.website.is_enabled() {
"/discord", router = router.route("/", get(Redirect::temporary("/api")));
get(Redirect::temporary("https://discord.gg/WACpShCB7M")), }
) let router = router
.route("/crate", get(Redirect::temporary("https://crates.io/crates/brk")))
.route(
"/status",
get(Redirect::temporary("https://status.bitview.space")),
)
.route("/github", get(Redirect::temporary("https://github.com/bitcoinresearchkit/brk")))
.route("/changelog", get(Redirect::temporary("https://github.com/bitcoinresearchkit/brk/blob/main/docs/CHANGELOG.md")))
.route(
"/install",
get(Redirect::temporary("https://github.com/bitcoinresearchkit/brk/blob/main/crates/brk_cli/README.md#brk_cli")),
)
.route(
"/service",
get(Redirect::temporary("https://github.com/bitcoinresearchkit/brk?tab=readme-ov-file#professional-hosting")),
)
.route("/nostr", get(Redirect::temporary("https://primal.net/p/npub1jagmm3x39lmwfnrtvxcs9ac7g300y3dusv9lgzhk2e4x5frpxlrqa73v44")))
.with_state(state) .with_state(state)
.merge(website_router)
.layer(CatchPanicLayer::new()) .layer(CatchPanicLayer::new())
.layer(compression_layer) .layer(compression_layer)
.layer(response_uri_layer) .layer(response_uri_layer)
.layer(trace_layer) .layer(trace_layer)
.layer(TimeoutLayer::with_status_code(StatusCode::GATEWAY_TIMEOUT, Duration::from_secs(5))) .layer(TimeoutLayer::with_status_code(
StatusCode::GATEWAY_TIMEOUT,
Duration::from_secs(5),
))
.layer(CorsLayer::permissive()); .layer(CorsLayer::permissive());
let (listener, port) = match port { let (listener, port) = match port {

View File

@@ -0,0 +1,21 @@
[package]
name = "brk_website"
description = "Standalone website server for BRK"
version.workspace = true
edition.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
include = ["src/**/*", "website/**/*", "examples/**/*", "Cargo.toml", "README.md"]
[dependencies]
axum = { workspace = true }
include_dir = "0.7"
importmap = { version = "0.3.0", features = ["embedded"] }
tracing = { workspace = true }
[dev-dependencies]
brk_logger = { workspace = true }
tokio = { workspace = true }
tower-http = { workspace = true }
tower-layer = { workspace = true }

View File

@@ -0,0 +1,44 @@
# brk_website
Website serving for BRK with minimal dependencies.
## Features
- **Embedded assets**: Website files compiled into binary
- **Filesystem mode**: Serve from custom path for development
- **SPA support**: Routes without extensions fallback to index.html
- **ImportMap**: Auto-generates import maps for hashed assets
## Usage
```rust,ignore
use brk_website::{Website, router};
// Create router for website
let website_router = router(Website::Default);
// Merge with your app
let app = your_api_router.merge(website_router);
```
## Website Enum
| Variant | Description |
|---------|-------------|
| `Default` | Filesystem in debug, embedded in release |
| `Filesystem(path)` | Always serve from specified path |
| `Disabled` | No routes registered |
## Standalone Server
See the `website` example for a complete standalone server with compression, tracing, and other middleware.
```sh
cargo run -p brk_website --example website
```
## Dependencies
- `axum` - HTTP routing
- `include_dir` - embedded assets
- `importmap` - asset hashing

View File

@@ -0,0 +1,100 @@
use std::time::Duration;
use axum::{
ServiceExt,
body::Body,
http::{Request, Response, StatusCode, Uri},
middleware::Next,
};
use brk_website::{Website, router};
use tokio::net::TcpListener;
use tower_http::{
catch_panic::CatchPanicLayer,
classify::ServerErrorsFailureClass,
compression::CompressionLayer,
cors::CorsLayer,
normalize_path::NormalizePathLayer,
timeout::TimeoutLayer,
trace::TraceLayer,
};
use tower_layer::Layer;
use tracing::{error, info};
#[tokio::main]
async fn main() -> std::io::Result<()> {
let _ = brk_logger::init(None);
// Use the embedded website (default in release mode)
// Or use Website::Filesystem(path) to serve from a custom path
let website = Website::Default;
if !website.is_enabled() {
eprintln!("Website is disabled");
return Ok(());
}
website.log();
let compression_layer = CompressionLayer::new()
.br(true)
.gzip(true)
.zstd(true);
let response_uri_layer = axum::middleware::from_fn(
async |request: Request<Body>, next: Next| -> Response<Body> {
let uri = request.uri().clone();
let mut response = next.run(request).await;
response.extensions_mut().insert(uri);
response
},
);
let trace_layer = TraceLayer::new_for_http()
.on_request(())
.on_response(
|response: &Response<Body>, latency: Duration, _: &tracing::Span| {
let status = response.status().as_u16();
let Some(uri) = response.extensions().get::<Uri>() else {
return;
};
match response.status() {
StatusCode::OK
| StatusCode::NOT_MODIFIED
| StatusCode::TEMPORARY_REDIRECT
| StatusCode::PERMANENT_REDIRECT => info!(status, %uri, ?latency),
_ => error!(status, %uri, ?latency),
}
},
)
.on_body_chunk(())
.on_failure(
|error: ServerErrorsFailureClass, latency: Duration, _: &tracing::Span| {
error!(?error, ?latency, "request failed");
},
)
.on_eos(());
let app = router(website)
.layer(CatchPanicLayer::new())
.layer(compression_layer)
.layer(response_uri_layer)
.layer(trace_layer)
.layer(TimeoutLayer::with_status_code(
StatusCode::GATEWAY_TIMEOUT,
Duration::from_secs(5),
))
.layer(CorsLayer::permissive());
let port = 3110;
let listener = TcpListener::bind(format!("0.0.0.0:{port}")).await?;
info!("website server listening on port {port}");
let service = NormalizePathLayer::trim_trailing_slash().layer(app);
axum::serve(
listener,
ServiceExt::<Request<Body>>::into_make_service(service),
)
.await
}

View File

@@ -0,0 +1,23 @@
use axum::{
body::Body,
http::{Response, StatusCode},
response::IntoResponse,
};
/// Website result type.
pub type Result<T> = std::result::Result<T, Error>;
/// Website error type that maps to HTTP status codes.
pub struct Error(StatusCode, String);
impl Error {
pub fn not_found(msg: impl Into<String>) -> Self {
Self(StatusCode::NOT_FOUND, msg.into())
}
}
impl IntoResponse for Error {
fn into_response(self) -> Response<Body> {
(self.0, self.1).into_response()
}
}

View File

@@ -1,23 +1,23 @@
use std::path::Path; use std::path::Path;
use axum::{body::Body, extract::State, response::Response}; use axum::{body::Body, extract::State, http::Response};
use crate::{AppState, HeaderMapExtended, Result}; use crate::{HeaderMapExtended, Result, Website};
pub async fn file_handler( pub async fn file_handler(
State(state): State<AppState>, State(website): State<Website>,
path: axum::extract::Path<String>, path: axum::extract::Path<String>,
) -> Result<Response> { ) -> Result<Response<Body>> {
serve(&state, &path.0) serve(&website, &path.0)
} }
pub async fn index_handler(State(state): State<AppState>) -> Result<Response> { pub async fn index_handler(State(website): State<Website>) -> Result<Response<Body>> {
serve(&state, "") serve(&website, "")
} }
fn serve(state: &AppState, path: &str) -> Result<Response> { fn serve(website: &Website, path: &str) -> Result<Response<Body>> {
let path = sanitize(path); let path = sanitize(path);
let content = state.website.get_file(&path)?; let content = website.get_file(&path)?;
let mut response = Response::new(Body::from(content)); let mut response = Response::new(Body::from(content));
let headers = response.headers_mut(); let headers = response.headers_mut();

View File

@@ -0,0 +1,53 @@
use std::path::Path;
use axum::http::{HeaderMap, header};
pub trait HeaderMapExtended {
fn insert_cache_control_must_revalidate(&mut self);
fn insert_cache_control_immutable(&mut self);
fn insert_content_type(&mut self, path: &Path);
fn insert_content_type_text_html(&mut self);
}
impl HeaderMapExtended for HeaderMap {
fn insert_cache_control_must_revalidate(&mut self) {
self.insert(
header::CACHE_CONTROL,
"public, max-age=1, must-revalidate".parse().unwrap(),
);
}
fn insert_cache_control_immutable(&mut self) {
self.insert(
header::CACHE_CONTROL,
"public, max-age=31536000, immutable".parse().unwrap(),
);
}
fn insert_content_type(&mut self, path: &Path) {
let content_type = match path
.extension()
.map(|s| s.to_str().unwrap_or_default())
.unwrap_or_default()
{
"js" | "mjs" => "application/javascript",
"json" | "map" => "application/json",
"html" => "text/html",
"css" => "text/css",
"toml" | "txt" => "text/plain",
"pdf" => "application/pdf",
"woff2" => "font/woff2",
"ico" => "image/x-icon",
"jpg" | "jpeg" => "image/jpeg",
"png" => "image/png",
"svg" => "image/svg+xml",
"webmanifest" => "application/manifest+json",
_ => return,
};
self.insert(header::CONTENT_TYPE, content_type.parse().unwrap());
}
fn insert_content_type_text_html(&mut self) {
self.insert(header::CONTENT_TYPE, "text/html".parse().unwrap());
}
}

View File

@@ -0,0 +1,17 @@
//! Standalone website serving for BRK.
//!
//! This crate provides website serving without any BRK data layer dependencies.
//! It can serve the embedded website or from a filesystem path.
//!
//! See the `website` example for how to run a standalone server.
mod error;
mod handlers;
mod headers;
mod router;
mod website;
pub use error::{Error, Result};
pub use headers::HeaderMapExtended;
pub use router::router;
pub use website::{EMBEDDED_WEBSITE, Website};

View File

@@ -0,0 +1,17 @@
use axum::{Router, routing::get};
use crate::{Website, handlers::{file_handler, index_handler}};
/// Create a router for serving the website.
///
/// Returns an empty router if the website is disabled.
pub fn router(website: Website) -> Router {
if website.is_enabled() {
Router::new()
.route("/{*path}", get(file_handler))
.route("/", get(index_handler))
.with_state(website)
} else {
Router::new()
}
}

View File

@@ -5,17 +5,22 @@ use std::{
}; };
use importmap::ImportMap; use importmap::ImportMap;
use include_dir::{Dir, include_dir};
use tracing::{error, info}; use tracing::{error, info};
use crate::{EMBEDDED_WEBSITE, Error, Result}; use crate::{Error, Result};
/// Embedded website assets
pub static EMBEDDED_WEBSITE: Dir = include_dir!("$CARGO_MANIFEST_DIR/website");
/// Cached index.html with importmap injected /// Cached index.html with importmap injected
static INDEX_HTML: OnceLock<String> = OnceLock::new(); static INDEX_HTML: OnceLock<String> = OnceLock::new();
/// Source for serving the website /// Source for serving the website
#[derive(Debug, Clone)] #[derive(Debug, Clone, Default)]
pub enum Website { pub enum Website {
Disabled, Disabled,
#[default]
Default, Default,
Filesystem(PathBuf), Filesystem(PathBuf),
} }
@@ -42,7 +47,12 @@ impl Website {
} }
/// Get file content by path (handles hash-stripping, SPA fallback, importmap) /// Get file content by path (handles hash-stripping, SPA fallback, importmap)
///
/// Returns an error if the website is disabled.
pub fn get_file(&self, path: &str) -> Result<Vec<u8>> { pub fn get_file(&self, path: &str) -> Result<Vec<u8>> {
if !self.is_enabled() {
return Err(Error::not_found("Website is disabled"));
}
match self.filesystem_path() { match self.filesystem_path() {
None => self.get_embedded(path), None => self.get_embedded(path),
Some(base) => self.get_filesystem(&base, path), Some(base) => self.get_filesystem(&base, path),
@@ -52,15 +62,15 @@ impl Website {
/// Log which website source is being used (call once at startup) /// Log which website source is being used (call once at startup)
pub fn log(&self) { pub fn log(&self) {
match self { match self {
Self::Disabled => info!("Website: disabled"), Self::Disabled => info!("website: disabled"),
Self::Default => { Self::Default => {
if let Some(p) = self.filesystem_path() { if let Some(p) = self.filesystem_path() {
info!("Website: filesystem ({})", p.display()); info!("website: filesystem ({})", p.display());
} else { } else {
info!("Website: embedded"); info!("website: embedded");
} }
} }
Self::Filesystem(p) => info!("Website: filesystem ({})", p.display()), Self::Filesystem(p) => info!("website: filesystem ({})", p.display()),
} }
} }

View File

@@ -1645,59 +1645,6 @@ function createPrice111dSmaPattern(client, acc) {
}; };
} }
/**
* @typedef {Object} PercentilesPattern
* @property {MetricPattern4<Dollars>} pct05
* @property {MetricPattern4<Dollars>} pct10
* @property {MetricPattern4<Dollars>} pct15
* @property {MetricPattern4<Dollars>} pct20
* @property {MetricPattern4<Dollars>} pct25
* @property {MetricPattern4<Dollars>} pct30
* @property {MetricPattern4<Dollars>} pct35
* @property {MetricPattern4<Dollars>} pct40
* @property {MetricPattern4<Dollars>} pct45
* @property {MetricPattern4<Dollars>} pct50
* @property {MetricPattern4<Dollars>} pct55
* @property {MetricPattern4<Dollars>} pct60
* @property {MetricPattern4<Dollars>} pct65
* @property {MetricPattern4<Dollars>} pct70
* @property {MetricPattern4<Dollars>} pct75
* @property {MetricPattern4<Dollars>} pct80
* @property {MetricPattern4<Dollars>} pct85
* @property {MetricPattern4<Dollars>} pct90
* @property {MetricPattern4<Dollars>} pct95
*/
/**
* Create a PercentilesPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {PercentilesPattern}
*/
function createPercentilesPattern(client, acc) {
return {
pct05: createMetricPattern4(client, _m(acc, 'pct05')),
pct10: createMetricPattern4(client, _m(acc, 'pct10')),
pct15: createMetricPattern4(client, _m(acc, 'pct15')),
pct20: createMetricPattern4(client, _m(acc, 'pct20')),
pct25: createMetricPattern4(client, _m(acc, 'pct25')),
pct30: createMetricPattern4(client, _m(acc, 'pct30')),
pct35: createMetricPattern4(client, _m(acc, 'pct35')),
pct40: createMetricPattern4(client, _m(acc, 'pct40')),
pct45: createMetricPattern4(client, _m(acc, 'pct45')),
pct50: createMetricPattern4(client, _m(acc, 'pct50')),
pct55: createMetricPattern4(client, _m(acc, 'pct55')),
pct60: createMetricPattern4(client, _m(acc, 'pct60')),
pct65: createMetricPattern4(client, _m(acc, 'pct65')),
pct70: createMetricPattern4(client, _m(acc, 'pct70')),
pct75: createMetricPattern4(client, _m(acc, 'pct75')),
pct80: createMetricPattern4(client, _m(acc, 'pct80')),
pct85: createMetricPattern4(client, _m(acc, 'pct85')),
pct90: createMetricPattern4(client, _m(acc, 'pct90')),
pct95: createMetricPattern4(client, _m(acc, 'pct95')),
};
}
/** /**
* @typedef {Object} ActivePriceRatioPattern * @typedef {Object} ActivePriceRatioPattern
* @property {MetricPattern4<StoredF32>} ratio * @property {MetricPattern4<StoredF32>} ratio
@@ -1751,6 +1698,59 @@ function createActivePriceRatioPattern(client, acc) {
}; };
} }
/**
* @typedef {Object} PercentilesPattern
* @property {MetricPattern4<Dollars>} pct05
* @property {MetricPattern4<Dollars>} pct10
* @property {MetricPattern4<Dollars>} pct15
* @property {MetricPattern4<Dollars>} pct20
* @property {MetricPattern4<Dollars>} pct25
* @property {MetricPattern4<Dollars>} pct30
* @property {MetricPattern4<Dollars>} pct35
* @property {MetricPattern4<Dollars>} pct40
* @property {MetricPattern4<Dollars>} pct45
* @property {MetricPattern4<Dollars>} pct50
* @property {MetricPattern4<Dollars>} pct55
* @property {MetricPattern4<Dollars>} pct60
* @property {MetricPattern4<Dollars>} pct65
* @property {MetricPattern4<Dollars>} pct70
* @property {MetricPattern4<Dollars>} pct75
* @property {MetricPattern4<Dollars>} pct80
* @property {MetricPattern4<Dollars>} pct85
* @property {MetricPattern4<Dollars>} pct90
* @property {MetricPattern4<Dollars>} pct95
*/
/**
* Create a PercentilesPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {PercentilesPattern}
*/
function createPercentilesPattern(client, acc) {
return {
pct05: createMetricPattern4(client, _m(acc, 'pct05')),
pct10: createMetricPattern4(client, _m(acc, 'pct10')),
pct15: createMetricPattern4(client, _m(acc, 'pct15')),
pct20: createMetricPattern4(client, _m(acc, 'pct20')),
pct25: createMetricPattern4(client, _m(acc, 'pct25')),
pct30: createMetricPattern4(client, _m(acc, 'pct30')),
pct35: createMetricPattern4(client, _m(acc, 'pct35')),
pct40: createMetricPattern4(client, _m(acc, 'pct40')),
pct45: createMetricPattern4(client, _m(acc, 'pct45')),
pct50: createMetricPattern4(client, _m(acc, 'pct50')),
pct55: createMetricPattern4(client, _m(acc, 'pct55')),
pct60: createMetricPattern4(client, _m(acc, 'pct60')),
pct65: createMetricPattern4(client, _m(acc, 'pct65')),
pct70: createMetricPattern4(client, _m(acc, 'pct70')),
pct75: createMetricPattern4(client, _m(acc, 'pct75')),
pct80: createMetricPattern4(client, _m(acc, 'pct80')),
pct85: createMetricPattern4(client, _m(acc, 'pct85')),
pct90: createMetricPattern4(client, _m(acc, 'pct90')),
pct95: createMetricPattern4(client, _m(acc, 'pct95')),
};
}
/** /**
* @typedef {Object} RelativePattern5 * @typedef {Object} RelativePattern5
* @property {MetricPattern1<StoredF32>} negUnrealizedLossRelToMarketCap * @property {MetricPattern1<StoredF32>} negUnrealizedLossRelToMarketCap
@@ -2005,6 +2005,45 @@ function createBitcoinPattern(client, acc) {
}; };
} }
/**
* @template T
* @typedef {Object} ClassAveragePricePattern
* @property {MetricPattern4<T>} _2015
* @property {MetricPattern4<T>} _2016
* @property {MetricPattern4<T>} _2017
* @property {MetricPattern4<T>} _2018
* @property {MetricPattern4<T>} _2019
* @property {MetricPattern4<T>} _2020
* @property {MetricPattern4<T>} _2021
* @property {MetricPattern4<T>} _2022
* @property {MetricPattern4<T>} _2023
* @property {MetricPattern4<T>} _2024
* @property {MetricPattern4<T>} _2025
*/
/**
* Create a ClassAveragePricePattern pattern node
* @template T
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {ClassAveragePricePattern<T>}
*/
function createClassAveragePricePattern(client, acc) {
return {
_2015: createMetricPattern4(client, _m(acc, '2015_average_price')),
_2016: createMetricPattern4(client, _m(acc, '2016_average_price')),
_2017: createMetricPattern4(client, _m(acc, '2017_average_price')),
_2018: createMetricPattern4(client, _m(acc, '2018_average_price')),
_2019: createMetricPattern4(client, _m(acc, '2019_average_price')),
_2020: createMetricPattern4(client, _m(acc, '2020_average_price')),
_2021: createMetricPattern4(client, _m(acc, '2021_average_price')),
_2022: createMetricPattern4(client, _m(acc, '2022_average_price')),
_2023: createMetricPattern4(client, _m(acc, '2023_average_price')),
_2024: createMetricPattern4(client, _m(acc, '2024_average_price')),
_2025: createMetricPattern4(client, _m(acc, '2025_average_price')),
};
}
/** /**
* @template T * @template T
* @typedef {Object} DollarsPattern * @typedef {Object} DollarsPattern
@@ -2045,41 +2084,37 @@ function createDollarsPattern(client, acc) {
} }
/** /**
* @template T * @typedef {Object} RelativePattern2
* @typedef {Object} ClassAveragePricePattern * @property {MetricPattern1<StoredF32>} negUnrealizedLossRelToOwnMarketCap
* @property {MetricPattern4<T>} _2015 * @property {MetricPattern1<StoredF32>} negUnrealizedLossRelToOwnTotalUnrealizedPnl
* @property {MetricPattern4<T>} _2016 * @property {MetricPattern1<StoredF32>} netUnrealizedPnlRelToOwnMarketCap
* @property {MetricPattern4<T>} _2017 * @property {MetricPattern1<StoredF32>} netUnrealizedPnlRelToOwnTotalUnrealizedPnl
* @property {MetricPattern4<T>} _2018 * @property {MetricPattern1<StoredF64>} supplyInLossRelToOwnSupply
* @property {MetricPattern4<T>} _2019 * @property {MetricPattern1<StoredF64>} supplyInProfitRelToOwnSupply
* @property {MetricPattern4<T>} _2020 * @property {MetricPattern1<StoredF32>} unrealizedLossRelToOwnMarketCap
* @property {MetricPattern4<T>} _2021 * @property {MetricPattern1<StoredF32>} unrealizedLossRelToOwnTotalUnrealizedPnl
* @property {MetricPattern4<T>} _2022 * @property {MetricPattern1<StoredF32>} unrealizedProfitRelToOwnMarketCap
* @property {MetricPattern4<T>} _2023 * @property {MetricPattern1<StoredF32>} unrealizedProfitRelToOwnTotalUnrealizedPnl
* @property {MetricPattern4<T>} _2024
* @property {MetricPattern4<T>} _2025
*/ */
/** /**
* Create a ClassAveragePricePattern pattern node * Create a RelativePattern2 pattern node
* @template T
* @param {BrkClientBase} client * @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name * @param {string} acc - Accumulated metric name
* @returns {ClassAveragePricePattern<T>} * @returns {RelativePattern2}
*/ */
function createClassAveragePricePattern(client, acc) { function createRelativePattern2(client, acc) {
return { return {
_2015: createMetricPattern4(client, _m(acc, '2015_returns')), negUnrealizedLossRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_market_cap')),
_2016: createMetricPattern4(client, _m(acc, '2016_returns')), negUnrealizedLossRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_total_unrealized_pnl')),
_2017: createMetricPattern4(client, _m(acc, '2017_returns')), netUnrealizedPnlRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_market_cap')),
_2018: createMetricPattern4(client, _m(acc, '2018_returns')), netUnrealizedPnlRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_total_unrealized_pnl')),
_2019: createMetricPattern4(client, _m(acc, '2019_returns')), supplyInLossRelToOwnSupply: createMetricPattern1(client, _m(acc, 'supply_in_loss_rel_to_own_supply')),
_2020: createMetricPattern4(client, _m(acc, '2020_returns')), supplyInProfitRelToOwnSupply: createMetricPattern1(client, _m(acc, 'supply_in_profit_rel_to_own_supply')),
_2021: createMetricPattern4(client, _m(acc, '2021_returns')), unrealizedLossRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_market_cap')),
_2022: createMetricPattern4(client, _m(acc, '2022_returns')), unrealizedLossRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_total_unrealized_pnl')),
_2023: createMetricPattern4(client, _m(acc, '2023_returns')), unrealizedProfitRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_market_cap')),
_2024: createMetricPattern4(client, _m(acc, '2024_returns')), unrealizedProfitRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_total_unrealized_pnl')),
_2025: createMetricPattern4(client, _m(acc, '2025_returns')),
}; };
} }
@@ -2118,41 +2153,6 @@ function createRelativePattern(client, acc) {
}; };
} }
/**
* @typedef {Object} RelativePattern2
* @property {MetricPattern1<StoredF32>} negUnrealizedLossRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} negUnrealizedLossRelToOwnTotalUnrealizedPnl
* @property {MetricPattern1<StoredF32>} netUnrealizedPnlRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} netUnrealizedPnlRelToOwnTotalUnrealizedPnl
* @property {MetricPattern1<StoredF64>} supplyInLossRelToOwnSupply
* @property {MetricPattern1<StoredF64>} supplyInProfitRelToOwnSupply
* @property {MetricPattern1<StoredF32>} unrealizedLossRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} unrealizedLossRelToOwnTotalUnrealizedPnl
* @property {MetricPattern1<StoredF32>} unrealizedProfitRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} unrealizedProfitRelToOwnTotalUnrealizedPnl
*/
/**
* Create a RelativePattern2 pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {RelativePattern2}
*/
function createRelativePattern2(client, acc) {
return {
negUnrealizedLossRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_market_cap')),
negUnrealizedLossRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_total_unrealized_pnl')),
netUnrealizedPnlRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_market_cap')),
netUnrealizedPnlRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_total_unrealized_pnl')),
supplyInLossRelToOwnSupply: createMetricPattern1(client, _m(acc, 'supply_in_loss_rel_to_own_supply')),
supplyInProfitRelToOwnSupply: createMetricPattern1(client, _m(acc, 'supply_in_profit_rel_to_own_supply')),
unrealizedLossRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_market_cap')),
unrealizedLossRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_total_unrealized_pnl')),
unrealizedProfitRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_market_cap')),
unrealizedProfitRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_total_unrealized_pnl')),
};
}
/** /**
* @template T * @template T
* @typedef {Object} CountPattern2 * @typedef {Object} CountPattern2
@@ -2387,29 +2387,29 @@ function createPeriodCagrPattern(client, acc) {
} }
/** /**
* @typedef {Object} _0satsPattern2 * @typedef {Object} _10yTo12yPattern
* @property {ActivityPattern2} activity * @property {ActivityPattern2} activity
* @property {CostBasisPattern} costBasis * @property {CostBasisPattern2} costBasis
* @property {OutputsPattern} outputs * @property {OutputsPattern} outputs
* @property {RealizedPattern} realized * @property {RealizedPattern2} realized
* @property {RelativePattern4} relative * @property {RelativePattern2} relative
* @property {SupplyPattern2} supply * @property {SupplyPattern2} supply
* @property {UnrealizedPattern} unrealized * @property {UnrealizedPattern} unrealized
*/ */
/** /**
* Create a _0satsPattern2 pattern node * Create a _10yTo12yPattern pattern node
* @param {BrkClientBase} client * @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name * @param {string} acc - Accumulated metric name
* @returns {_0satsPattern2} * @returns {_10yTo12yPattern}
*/ */
function create_0satsPattern2(client, acc) { function create_10yTo12yPattern(client, acc) {
return { return {
activity: createActivityPattern2(client, acc), activity: createActivityPattern2(client, acc),
costBasis: createCostBasisPattern(client, acc), costBasis: createCostBasisPattern2(client, acc),
outputs: createOutputsPattern(client, _m(acc, 'utxo_count')), outputs: createOutputsPattern(client, _m(acc, 'utxo_count')),
realized: createRealizedPattern(client, acc), realized: createRealizedPattern2(client, acc),
relative: createRelativePattern4(client, _m(acc, 'supply_in')), relative: createRelativePattern2(client, acc),
supply: createSupplyPattern2(client, _m(acc, 'supply')), supply: createSupplyPattern2(client, _m(acc, 'supply')),
unrealized: createUnrealizedPattern(client, acc), unrealized: createUnrealizedPattern(client, acc),
}; };
@@ -2445,29 +2445,29 @@ function create_10yPattern(client, acc) {
} }
/** /**
* @typedef {Object} _10yTo12yPattern * @typedef {Object} _0satsPattern2
* @property {ActivityPattern2} activity * @property {ActivityPattern2} activity
* @property {CostBasisPattern2} costBasis * @property {CostBasisPattern} costBasis
* @property {OutputsPattern} outputs * @property {OutputsPattern} outputs
* @property {RealizedPattern2} realized * @property {RealizedPattern} realized
* @property {RelativePattern2} relative * @property {RelativePattern4} relative
* @property {SupplyPattern2} supply * @property {SupplyPattern2} supply
* @property {UnrealizedPattern} unrealized * @property {UnrealizedPattern} unrealized
*/ */
/** /**
* Create a _10yTo12yPattern pattern node * Create a _0satsPattern2 pattern node
* @param {BrkClientBase} client * @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name * @param {string} acc - Accumulated metric name
* @returns {_10yTo12yPattern} * @returns {_0satsPattern2}
*/ */
function create_10yTo12yPattern(client, acc) { function create_0satsPattern2(client, acc) {
return { return {
activity: createActivityPattern2(client, acc), activity: createActivityPattern2(client, acc),
costBasis: createCostBasisPattern2(client, acc), costBasis: createCostBasisPattern(client, acc),
outputs: createOutputsPattern(client, _m(acc, 'utxo_count')), outputs: createOutputsPattern(client, _m(acc, 'utxo_count')),
realized: createRealizedPattern2(client, acc), realized: createRealizedPattern(client, acc),
relative: createRelativePattern2(client, acc), relative: createRelativePattern4(client, _m(acc, 'supply_in')),
supply: createSupplyPattern2(client, _m(acc, 'supply')), supply: createSupplyPattern2(client, _m(acc, 'supply')),
unrealized: createUnrealizedPattern(client, acc), unrealized: createUnrealizedPattern(client, acc),
}; };
@@ -2581,27 +2581,6 @@ function createSplitPattern2(client, acc) {
}; };
} }
/**
* @typedef {Object} CostBasisPattern2
* @property {MetricPattern1<Dollars>} max
* @property {MetricPattern1<Dollars>} min
* @property {PercentilesPattern} percentiles
*/
/**
* Create a CostBasisPattern2 pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {CostBasisPattern2}
*/
function createCostBasisPattern2(client, acc) {
return {
max: createMetricPattern1(client, _m(acc, 'max_cost_basis')),
min: createMetricPattern1(client, _m(acc, 'min_cost_basis')),
percentiles: createPercentilesPattern(client, _m(acc, 'cost_basis')),
};
}
/** /**
* @typedef {Object} CoinbasePattern * @typedef {Object} CoinbasePattern
* @property {BitcoinPattern} bitcoin * @property {BitcoinPattern} bitcoin
@@ -2624,23 +2603,65 @@ function createCoinbasePattern(client, acc) {
} }
/** /**
* @typedef {Object} ActiveSupplyPattern * @typedef {Object} CoinbasePattern2
* @property {MetricPattern1<Bitcoin>} bitcoin * @property {BlockCountPattern<Bitcoin>} bitcoin
* @property {MetricPattern1<Dollars>} dollars * @property {BlockCountPattern<Dollars>} dollars
* @property {MetricPattern1<Sats>} sats * @property {BlockCountPattern<Sats>} sats
*/ */
/** /**
* Create a ActiveSupplyPattern pattern node * Create a CoinbasePattern2 pattern node
* @param {BrkClientBase} client * @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name * @param {string} acc - Accumulated metric name
* @returns {ActiveSupplyPattern} * @returns {CoinbasePattern2}
*/ */
function createActiveSupplyPattern(client, acc) { function createCoinbasePattern2(client, acc) {
return { return {
bitcoin: createMetricPattern1(client, _m(acc, 'btc')), bitcoin: createBlockCountPattern(client, _m(acc, 'btc')),
dollars: createMetricPattern1(client, _m(acc, 'usd')), dollars: createBlockCountPattern(client, _m(acc, 'usd')),
sats: createMetricPattern1(client, acc), sats: createBlockCountPattern(client, acc),
};
}
/**
* @typedef {Object} SegwitAdoptionPattern
* @property {MetricPattern11<StoredF32>} base
* @property {MetricPattern2<StoredF32>} cumulative
* @property {MetricPattern2<StoredF32>} sum
*/
/**
* Create a SegwitAdoptionPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {SegwitAdoptionPattern}
*/
function createSegwitAdoptionPattern(client, acc) {
return {
base: createMetricPattern11(client, acc),
cumulative: createMetricPattern2(client, _m(acc, 'cumulative')),
sum: createMetricPattern2(client, _m(acc, 'sum')),
};
}
/**
* @typedef {Object} CostBasisPattern2
* @property {MetricPattern1<Dollars>} max
* @property {MetricPattern1<Dollars>} min
* @property {PercentilesPattern} percentiles
*/
/**
* Create a CostBasisPattern2 pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {CostBasisPattern2}
*/
function createCostBasisPattern2(client, acc) {
return {
max: createMetricPattern1(client, _m(acc, 'max_cost_basis')),
min: createMetricPattern1(client, _m(acc, 'min_cost_basis')),
percentiles: createPercentilesPattern(client, _m(acc, 'cost_basis')),
}; };
} }
@@ -2665,27 +2686,6 @@ function createUnclaimedRewardsPattern(client, acc) {
}; };
} }
/**
* @typedef {Object} CoinbasePattern2
* @property {BlockCountPattern<Bitcoin>} bitcoin
* @property {BlockCountPattern<Dollars>} dollars
* @property {BlockCountPattern<Sats>} sats
*/
/**
* Create a CoinbasePattern2 pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {CoinbasePattern2}
*/
function createCoinbasePattern2(client, acc) {
return {
bitcoin: createBlockCountPattern(client, _m(acc, 'btc')),
dollars: createBlockCountPattern(client, _m(acc, 'usd')),
sats: createBlockCountPattern(client, acc),
};
}
/** /**
* @typedef {Object} _2015Pattern * @typedef {Object} _2015Pattern
* @property {MetricPattern4<Bitcoin>} bitcoin * @property {MetricPattern4<Bitcoin>} bitcoin
@@ -2708,23 +2708,23 @@ function create_2015Pattern(client, acc) {
} }
/** /**
* @typedef {Object} SegwitAdoptionPattern * @typedef {Object} ActiveSupplyPattern
* @property {MetricPattern11<StoredF32>} base * @property {MetricPattern1<Bitcoin>} bitcoin
* @property {MetricPattern2<StoredF32>} cumulative * @property {MetricPattern1<Dollars>} dollars
* @property {MetricPattern2<StoredF32>} sum * @property {MetricPattern1<Sats>} sats
*/ */
/** /**
* Create a SegwitAdoptionPattern pattern node * Create a ActiveSupplyPattern pattern node
* @param {BrkClientBase} client * @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name * @param {string} acc - Accumulated metric name
* @returns {SegwitAdoptionPattern} * @returns {ActiveSupplyPattern}
*/ */
function createSegwitAdoptionPattern(client, acc) { function createActiveSupplyPattern(client, acc) {
return { return {
base: createMetricPattern11(client, acc), bitcoin: createMetricPattern1(client, _m(acc, 'btc')),
cumulative: createMetricPattern2(client, _m(acc, 'cumulative')), dollars: createMetricPattern1(client, _m(acc, 'usd')),
sum: createMetricPattern2(client, _m(acc, 'sum')), sats: createMetricPattern1(client, acc),
}; };
} }
@@ -2747,6 +2747,25 @@ function create_1dReturns1mSdPattern(client, acc) {
}; };
} }
/**
* @typedef {Object} SupplyPattern2
* @property {ActiveSupplyPattern} halved
* @property {ActiveSupplyPattern} total
*/
/**
* Create a SupplyPattern2 pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {SupplyPattern2}
*/
function createSupplyPattern2(client, acc) {
return {
halved: createActiveSupplyPattern(client, _m(acc, 'halved')),
total: createActiveSupplyPattern(client, acc),
};
}
/** /**
* @typedef {Object} CostBasisPattern * @typedef {Object} CostBasisPattern
* @property {MetricPattern1<Dollars>} max * @property {MetricPattern1<Dollars>} max
@@ -2785,25 +2804,6 @@ function createRelativePattern4(client, acc) {
}; };
} }
/**
* @typedef {Object} SupplyPattern2
* @property {ActiveSupplyPattern} halved
* @property {ActiveSupplyPattern} total
*/
/**
* Create a SupplyPattern2 pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {SupplyPattern2}
*/
function createSupplyPattern2(client, acc) {
return {
halved: createActiveSupplyPattern(client, _m(acc, 'halved')),
total: createActiveSupplyPattern(client, acc),
};
}
/** /**
* @template T * @template T
* @typedef {Object} BitcoinPattern2 * @typedef {Object} BitcoinPattern2
@@ -2867,23 +2867,6 @@ function createBlockCountPattern(client, acc) {
}; };
} }
/**
* @typedef {Object} OutputsPattern
* @property {MetricPattern1<StoredU64>} utxoCount
*/
/**
* Create a OutputsPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {OutputsPattern}
*/
function createOutputsPattern(client, acc) {
return {
utxoCount: createMetricPattern1(client, acc),
};
}
/** /**
* @typedef {Object} RealizedPriceExtraPattern * @typedef {Object} RealizedPriceExtraPattern
* @property {MetricPattern4<StoredF32>} ratio * @property {MetricPattern4<StoredF32>} ratio
@@ -2901,6 +2884,23 @@ function createRealizedPriceExtraPattern(client, acc) {
}; };
} }
/**
* @typedef {Object} OutputsPattern
* @property {MetricPattern1<StoredU64>} utxoCount
*/
/**
* Create a OutputsPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {OutputsPattern}
*/
function createOutputsPattern(client, acc) {
return {
utxoCount: createMetricPattern1(client, acc),
};
}
// Catalog tree typedefs // Catalog tree typedefs
/** /**
@@ -3696,8 +3696,8 @@ function createRealizedPriceExtraPattern(client, acc) {
/** /**
* @typedef {Object} MetricsTree_Market_Dca * @typedef {Object} MetricsTree_Market_Dca
* @property {MetricsTree_Market_Dca_ClassAveragePrice} classAveragePrice * @property {ClassAveragePricePattern<Dollars>} classAveragePrice
* @property {ClassAveragePricePattern<StoredF32>} classReturns * @property {MetricsTree_Market_Dca_ClassReturns} classReturns
* @property {MetricsTree_Market_Dca_ClassStack} classStack * @property {MetricsTree_Market_Dca_ClassStack} classStack
* @property {PeriodAveragePricePattern<Dollars>} periodAveragePrice * @property {PeriodAveragePricePattern<Dollars>} periodAveragePrice
* @property {PeriodCagrPattern} periodCagr * @property {PeriodCagrPattern} periodCagr
@@ -3707,18 +3707,18 @@ function createRealizedPriceExtraPattern(client, acc) {
*/ */
/** /**
* @typedef {Object} MetricsTree_Market_Dca_ClassAveragePrice * @typedef {Object} MetricsTree_Market_Dca_ClassReturns
* @property {MetricPattern4<Dollars>} _2015 * @property {MetricPattern4<StoredF32>} _2015
* @property {MetricPattern4<Dollars>} _2016 * @property {MetricPattern4<StoredF32>} _2016
* @property {MetricPattern4<Dollars>} _2017 * @property {MetricPattern4<StoredF32>} _2017
* @property {MetricPattern4<Dollars>} _2018 * @property {MetricPattern4<StoredF32>} _2018
* @property {MetricPattern4<Dollars>} _2019 * @property {MetricPattern4<StoredF32>} _2019
* @property {MetricPattern4<Dollars>} _2020 * @property {MetricPattern4<StoredF32>} _2020
* @property {MetricPattern4<Dollars>} _2021 * @property {MetricPattern4<StoredF32>} _2021
* @property {MetricPattern4<Dollars>} _2022 * @property {MetricPattern4<StoredF32>} _2022
* @property {MetricPattern4<Dollars>} _2023 * @property {MetricPattern4<StoredF32>} _2023
* @property {MetricPattern4<Dollars>} _2024 * @property {MetricPattern4<StoredF32>} _2024
* @property {MetricPattern4<Dollars>} _2025 * @property {MetricPattern4<StoredF32>} _2025
*/ */
/** /**
@@ -4259,7 +4259,7 @@ function createRealizedPriceExtraPattern(client, acc) {
* @extends BrkClientBase * @extends BrkClientBase
*/ */
class BrkClient extends BrkClientBase { class BrkClient extends BrkClientBase {
VERSION = "v0.1.0-alpha.3"; VERSION = "v0.1.0-alpha.6";
INDEXES = /** @type {const} */ ([ INDEXES = /** @type {const} */ ([
"dateindex", "dateindex",
@@ -5726,20 +5726,20 @@ class BrkClient extends BrkClientBase {
yearsSincePriceAth: createMetricPattern4(this, 'years_since_price_ath'), yearsSincePriceAth: createMetricPattern4(this, 'years_since_price_ath'),
}, },
dca: { dca: {
classAveragePrice: { classAveragePrice: createClassAveragePricePattern(this, 'dca_class'),
_2015: createMetricPattern4(this, 'dca_class_2015_average_price'), classReturns: {
_2016: createMetricPattern4(this, 'dca_class_2016_average_price'), _2015: createMetricPattern4(this, 'dca_class_2015_returns'),
_2017: createMetricPattern4(this, 'dca_class_2017_average_price'), _2016: createMetricPattern4(this, 'dca_class_2016_returns'),
_2018: createMetricPattern4(this, 'dca_class_2018_average_price'), _2017: createMetricPattern4(this, 'dca_class_2017_returns'),
_2019: createMetricPattern4(this, 'dca_class_2019_average_price'), _2018: createMetricPattern4(this, 'dca_class_2018_returns'),
_2020: createMetricPattern4(this, 'dca_class_2020_average_price'), _2019: createMetricPattern4(this, 'dca_class_2019_returns'),
_2021: createMetricPattern4(this, 'dca_class_2021_average_price'), _2020: createMetricPattern4(this, 'dca_class_2020_returns'),
_2022: createMetricPattern4(this, 'dca_class_2022_average_price'), _2021: createMetricPattern4(this, 'dca_class_2021_returns'),
_2023: createMetricPattern4(this, 'dca_class_2023_average_price'), _2022: createMetricPattern4(this, 'dca_class_2022_returns'),
_2024: createMetricPattern4(this, 'dca_class_2024_average_price'), _2023: createMetricPattern4(this, 'dca_class_2023_returns'),
_2025: createMetricPattern4(this, 'dca_class_2025_average_price'), _2024: createMetricPattern4(this, 'dca_class_2024_returns'),
_2025: createMetricPattern4(this, 'dca_class_2025_returns'),
}, },
classReturns: createClassAveragePricePattern(this, 'dca_class'),
classStack: { classStack: {
_2015: create_2015Pattern(this, 'dca_class_2015_stack'), _2015: create_2015Pattern(this, 'dca_class_2015_stack'),
_2016: create_2015Pattern(this, 'dca_class_2016_stack'), _2016: create_2015Pattern(this, 'dca_class_2016_stack'),

View File

@@ -1883,31 +1883,6 @@ class Price111dSmaPattern:
self.ratio_pct99_usd: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'ratio_pct99_usd')) self.ratio_pct99_usd: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'ratio_pct99_usd'))
self.ratio_sd: Ratio1ySdPattern = Ratio1ySdPattern(client, _m(acc, 'ratio')) self.ratio_sd: Ratio1ySdPattern = Ratio1ySdPattern(client, _m(acc, 'ratio'))
class PercentilesPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.pct05: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct05'))
self.pct10: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct10'))
self.pct15: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct15'))
self.pct20: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct20'))
self.pct25: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct25'))
self.pct30: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct30'))
self.pct35: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct35'))
self.pct40: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct40'))
self.pct45: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct45'))
self.pct50: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct50'))
self.pct55: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct55'))
self.pct60: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct60'))
self.pct65: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct65'))
self.pct70: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct70'))
self.pct75: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct75'))
self.pct80: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct80'))
self.pct85: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct85'))
self.pct90: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct90'))
self.pct95: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct95'))
class ActivePriceRatioPattern: class ActivePriceRatioPattern:
"""Pattern struct for repeated tree structure.""" """Pattern struct for repeated tree structure."""
@@ -1933,6 +1908,31 @@ class ActivePriceRatioPattern:
self.ratio_pct99_usd: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct99_usd')) self.ratio_pct99_usd: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct99_usd'))
self.ratio_sd: Ratio1ySdPattern = Ratio1ySdPattern(client, acc) self.ratio_sd: Ratio1ySdPattern = Ratio1ySdPattern(client, acc)
class PercentilesPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.pct05: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct05'))
self.pct10: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct10'))
self.pct15: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct15'))
self.pct20: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct20'))
self.pct25: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct25'))
self.pct30: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct30'))
self.pct35: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct35'))
self.pct40: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct40'))
self.pct45: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct45'))
self.pct50: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct50'))
self.pct55: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct55'))
self.pct60: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct60'))
self.pct65: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct65'))
self.pct70: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct70'))
self.pct75: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct75'))
self.pct80: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct80'))
self.pct85: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct85'))
self.pct90: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct90'))
self.pct95: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'pct95'))
class RelativePattern5: class RelativePattern5:
"""Pattern struct for repeated tree structure.""" """Pattern struct for repeated tree structure."""
@@ -2049,6 +2049,23 @@ class BitcoinPattern:
self.pct90: MetricPattern6[Bitcoin] = MetricPattern6(client, _m(acc, 'pct90')) self.pct90: MetricPattern6[Bitcoin] = MetricPattern6(client, _m(acc, 'pct90'))
self.sum: MetricPattern2[Bitcoin] = MetricPattern2(client, _m(acc, 'sum')) self.sum: MetricPattern2[Bitcoin] = MetricPattern2(client, _m(acc, 'sum'))
class ClassAveragePricePattern(Generic[T]):
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self._2015: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2015_average_price'))
self._2016: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2016_average_price'))
self._2017: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2017_average_price'))
self._2018: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2018_average_price'))
self._2019: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2019_average_price'))
self._2020: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2020_average_price'))
self._2021: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2021_average_price'))
self._2022: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2022_average_price'))
self._2023: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2023_average_price'))
self._2024: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2024_average_price'))
self._2025: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2025_average_price'))
class DollarsPattern(Generic[T]): class DollarsPattern(Generic[T]):
"""Pattern struct for repeated tree structure.""" """Pattern struct for repeated tree structure."""
@@ -2066,22 +2083,21 @@ class DollarsPattern(Generic[T]):
self.pct90: MetricPattern6[T] = MetricPattern6(client, _m(acc, 'pct90')) self.pct90: MetricPattern6[T] = MetricPattern6(client, _m(acc, 'pct90'))
self.sum: MetricPattern2[T] = MetricPattern2(client, _m(acc, 'sum')) self.sum: MetricPattern2[T] = MetricPattern2(client, _m(acc, 'sum'))
class ClassAveragePricePattern(Generic[T]): class RelativePattern2:
"""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):
"""Create pattern node with accumulated metric name.""" """Create pattern node with accumulated metric name."""
self._2015: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2015_returns')) self.neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_market_cap'))
self._2016: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2016_returns')) self.neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_total_unrealized_pnl'))
self._2017: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2017_returns')) self.net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_market_cap'))
self._2018: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2018_returns')) self.net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_total_unrealized_pnl'))
self._2019: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2019_returns')) self.supply_in_loss_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'supply_in_loss_rel_to_own_supply'))
self._2020: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2020_returns')) self.supply_in_profit_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'supply_in_profit_rel_to_own_supply'))
self._2021: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2021_returns')) self.unrealized_loss_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_market_cap'))
self._2022: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2022_returns')) self.unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_total_unrealized_pnl'))
self._2023: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2023_returns')) self.unrealized_profit_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_market_cap'))
self._2024: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2024_returns')) self.unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_total_unrealized_pnl'))
self._2025: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2025_returns'))
class RelativePattern: class RelativePattern:
"""Pattern struct for repeated tree structure.""" """Pattern struct for repeated tree structure."""
@@ -2099,22 +2115,6 @@ class RelativePattern:
self.unrealized_loss_rel_to_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_market_cap')) self.unrealized_loss_rel_to_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_market_cap'))
self.unrealized_profit_rel_to_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_market_cap')) self.unrealized_profit_rel_to_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_market_cap'))
class RelativePattern2:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_market_cap'))
self.neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_total_unrealized_pnl'))
self.net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_market_cap'))
self.net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_total_unrealized_pnl'))
self.supply_in_loss_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'supply_in_loss_rel_to_own_supply'))
self.supply_in_profit_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'supply_in_profit_rel_to_own_supply'))
self.unrealized_loss_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_market_cap'))
self.unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_total_unrealized_pnl'))
self.unrealized_profit_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_market_cap'))
self.unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_total_unrealized_pnl'))
class CountPattern2(Generic[T]): class CountPattern2(Generic[T]):
"""Pattern struct for repeated tree structure.""" """Pattern struct for repeated tree structure."""
@@ -2217,16 +2217,16 @@ class PeriodCagrPattern:
self._6y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('6y', acc)) self._6y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('6y', acc))
self._8y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('8y', acc)) self._8y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('8y', acc))
class _0satsPattern2: class _10yTo12yPattern:
"""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):
"""Create pattern node with accumulated metric name.""" """Create pattern node with accumulated metric name."""
self.activity: ActivityPattern2 = ActivityPattern2(client, acc) self.activity: ActivityPattern2 = ActivityPattern2(client, acc)
self.cost_basis: CostBasisPattern = CostBasisPattern(client, acc) self.cost_basis: CostBasisPattern2 = CostBasisPattern2(client, acc)
self.outputs: OutputsPattern = OutputsPattern(client, _m(acc, 'utxo_count')) self.outputs: OutputsPattern = OutputsPattern(client, _m(acc, 'utxo_count'))
self.realized: RealizedPattern = RealizedPattern(client, acc) self.realized: RealizedPattern2 = RealizedPattern2(client, acc)
self.relative: RelativePattern4 = RelativePattern4(client, _m(acc, 'supply_in')) self.relative: RelativePattern2 = RelativePattern2(client, acc)
self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply')) self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply'))
self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc) self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc)
@@ -2243,16 +2243,16 @@ class _10yPattern:
self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply')) self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply'))
self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc) self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc)
class _10yTo12yPattern: class _0satsPattern2:
"""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):
"""Create pattern node with accumulated metric name.""" """Create pattern node with accumulated metric name."""
self.activity: ActivityPattern2 = ActivityPattern2(client, acc) self.activity: ActivityPattern2 = ActivityPattern2(client, acc)
self.cost_basis: CostBasisPattern2 = CostBasisPattern2(client, acc) self.cost_basis: CostBasisPattern = CostBasisPattern(client, acc)
self.outputs: OutputsPattern = OutputsPattern(client, _m(acc, 'utxo_count')) self.outputs: OutputsPattern = OutputsPattern(client, _m(acc, 'utxo_count'))
self.realized: RealizedPattern2 = RealizedPattern2(client, acc) self.realized: RealizedPattern = RealizedPattern(client, acc)
self.relative: RelativePattern2 = RelativePattern2(client, acc) self.relative: RelativePattern4 = RelativePattern4(client, _m(acc, 'supply_in'))
self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply')) self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply'))
self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc) self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc)
@@ -2303,15 +2303,6 @@ class SplitPattern2(Generic[T]):
self.low: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'low')) self.low: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'low'))
self.open: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'open')) self.open: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'open'))
class CostBasisPattern2:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.max: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'max_cost_basis'))
self.min: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'min_cost_basis'))
self.percentiles: PercentilesPattern = PercentilesPattern(client, _m(acc, 'cost_basis'))
class CoinbasePattern: class CoinbasePattern:
"""Pattern struct for repeated tree structure.""" """Pattern struct for repeated tree structure."""
@@ -2321,14 +2312,32 @@ class CoinbasePattern:
self.dollars: DollarsPattern[Dollars] = DollarsPattern(client, _m(acc, 'usd')) self.dollars: DollarsPattern[Dollars] = DollarsPattern(client, _m(acc, 'usd'))
self.sats: DollarsPattern[Sats] = DollarsPattern(client, acc) self.sats: DollarsPattern[Sats] = DollarsPattern(client, acc)
class ActiveSupplyPattern: class CoinbasePattern2:
"""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):
"""Create pattern node with accumulated metric name.""" """Create pattern node with accumulated metric name."""
self.bitcoin: MetricPattern1[Bitcoin] = MetricPattern1(client, _m(acc, 'btc')) self.bitcoin: BlockCountPattern[Bitcoin] = BlockCountPattern(client, _m(acc, 'btc'))
self.dollars: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd')) self.dollars: BlockCountPattern[Dollars] = BlockCountPattern(client, _m(acc, 'usd'))
self.sats: MetricPattern1[Sats] = MetricPattern1(client, acc) self.sats: BlockCountPattern[Sats] = BlockCountPattern(client, acc)
class SegwitAdoptionPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.base: MetricPattern11[StoredF32] = MetricPattern11(client, acc)
self.cumulative: MetricPattern2[StoredF32] = MetricPattern2(client, _m(acc, 'cumulative'))
self.sum: MetricPattern2[StoredF32] = MetricPattern2(client, _m(acc, 'sum'))
class CostBasisPattern2:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.max: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'max_cost_basis'))
self.min: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'min_cost_basis'))
self.percentiles: PercentilesPattern = PercentilesPattern(client, _m(acc, 'cost_basis'))
class UnclaimedRewardsPattern: class UnclaimedRewardsPattern:
"""Pattern struct for repeated tree structure.""" """Pattern struct for repeated tree structure."""
@@ -2339,15 +2348,6 @@ class UnclaimedRewardsPattern:
self.dollars: BlockCountPattern[Dollars] = BlockCountPattern(client, _m(acc, 'usd')) self.dollars: BlockCountPattern[Dollars] = BlockCountPattern(client, _m(acc, 'usd'))
self.sats: BlockCountPattern[Sats] = BlockCountPattern(client, acc) self.sats: BlockCountPattern[Sats] = BlockCountPattern(client, acc)
class CoinbasePattern2:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.bitcoin: BlockCountPattern[Bitcoin] = BlockCountPattern(client, _m(acc, 'btc'))
self.dollars: BlockCountPattern[Dollars] = BlockCountPattern(client, _m(acc, 'usd'))
self.sats: BlockCountPattern[Sats] = BlockCountPattern(client, acc)
class _2015Pattern: class _2015Pattern:
"""Pattern struct for repeated tree structure.""" """Pattern struct for repeated tree structure."""
@@ -2357,14 +2357,14 @@ class _2015Pattern:
self.dollars: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'usd')) self.dollars: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'usd'))
self.sats: MetricPattern4[Sats] = MetricPattern4(client, acc) self.sats: MetricPattern4[Sats] = MetricPattern4(client, acc)
class SegwitAdoptionPattern: class ActiveSupplyPattern:
"""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):
"""Create pattern node with accumulated metric name.""" """Create pattern node with accumulated metric name."""
self.base: MetricPattern11[StoredF32] = MetricPattern11(client, acc) self.bitcoin: MetricPattern1[Bitcoin] = MetricPattern1(client, _m(acc, 'btc'))
self.cumulative: MetricPattern2[StoredF32] = MetricPattern2(client, _m(acc, 'cumulative')) self.dollars: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd'))
self.sum: MetricPattern2[StoredF32] = MetricPattern2(client, _m(acc, 'sum')) self.sats: MetricPattern1[Sats] = MetricPattern1(client, acc)
class _1dReturns1mSdPattern: class _1dReturns1mSdPattern:
"""Pattern struct for repeated tree structure.""" """Pattern struct for repeated tree structure."""
@@ -2374,6 +2374,14 @@ class _1dReturns1mSdPattern:
self.sd: MetricPattern4[StoredF32] = MetricPattern4(client, _m(acc, 'sd')) self.sd: MetricPattern4[StoredF32] = MetricPattern4(client, _m(acc, 'sd'))
self.sma: MetricPattern4[StoredF32] = MetricPattern4(client, _m(acc, 'sma')) self.sma: MetricPattern4[StoredF32] = MetricPattern4(client, _m(acc, 'sma'))
class SupplyPattern2:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.halved: ActiveSupplyPattern = ActiveSupplyPattern(client, _m(acc, 'halved'))
self.total: ActiveSupplyPattern = ActiveSupplyPattern(client, acc)
class CostBasisPattern: class CostBasisPattern:
"""Pattern struct for repeated tree structure.""" """Pattern struct for repeated tree structure."""
@@ -2390,14 +2398,6 @@ class RelativePattern4:
self.supply_in_loss_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'loss_rel_to_own_supply')) self.supply_in_loss_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'loss_rel_to_own_supply'))
self.supply_in_profit_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'profit_rel_to_own_supply')) self.supply_in_profit_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'profit_rel_to_own_supply'))
class SupplyPattern2:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.halved: ActiveSupplyPattern = ActiveSupplyPattern(client, _m(acc, 'halved'))
self.total: ActiveSupplyPattern = ActiveSupplyPattern(client, acc)
class BitcoinPattern2(Generic[T]): class BitcoinPattern2(Generic[T]):
"""Pattern struct for repeated tree structure.""" """Pattern struct for repeated tree structure."""
@@ -2422,13 +2422,6 @@ class BlockCountPattern(Generic[T]):
self.cumulative: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'cumulative')) self.cumulative: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'cumulative'))
self.sum: MetricPattern1[T] = MetricPattern1(client, acc) self.sum: MetricPattern1[T] = MetricPattern1(client, acc)
class OutputsPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.utxo_count: MetricPattern1[StoredU64] = MetricPattern1(client, acc)
class RealizedPriceExtraPattern: class RealizedPriceExtraPattern:
"""Pattern struct for repeated tree structure.""" """Pattern struct for repeated tree structure."""
@@ -2436,6 +2429,13 @@ class RealizedPriceExtraPattern:
"""Create pattern node with accumulated metric name.""" """Create pattern node with accumulated metric name."""
self.ratio: MetricPattern4[StoredF32] = MetricPattern4(client, acc) self.ratio: MetricPattern4[StoredF32] = MetricPattern4(client, acc)
class OutputsPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.utxo_count: MetricPattern1[StoredU64] = MetricPattern1(client, acc)
# Metrics tree classes # Metrics tree classes
class MetricsTree_Addresses: class MetricsTree_Addresses:
@@ -3269,21 +3269,21 @@ class MetricsTree_Market_Ath:
self.price_drawdown: MetricPattern3[StoredF32] = MetricPattern3(client, 'price_drawdown') self.price_drawdown: MetricPattern3[StoredF32] = MetricPattern3(client, 'price_drawdown')
self.years_since_price_ath: MetricPattern4[StoredF32] = MetricPattern4(client, 'years_since_price_ath') self.years_since_price_ath: MetricPattern4[StoredF32] = MetricPattern4(client, 'years_since_price_ath')
class MetricsTree_Market_Dca_ClassAveragePrice: class MetricsTree_Market_Dca_ClassReturns:
"""Metrics tree node.""" """Metrics tree node."""
def __init__(self, client: BrkClientBase, base_path: str = ''): def __init__(self, client: BrkClientBase, base_path: str = ''):
self._2015: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2015_average_price') self._2015: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2015_returns')
self._2016: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2016_average_price') self._2016: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2016_returns')
self._2017: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2017_average_price') self._2017: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2017_returns')
self._2018: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2018_average_price') self._2018: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2018_returns')
self._2019: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2019_average_price') self._2019: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2019_returns')
self._2020: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2020_average_price') self._2020: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2020_returns')
self._2021: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2021_average_price') self._2021: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2021_returns')
self._2022: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2022_average_price') self._2022: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2022_returns')
self._2023: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2023_average_price') self._2023: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2023_returns')
self._2024: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2024_average_price') self._2024: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2024_returns')
self._2025: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2025_average_price') self._2025: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2025_returns')
class MetricsTree_Market_Dca_ClassStack: class MetricsTree_Market_Dca_ClassStack:
"""Metrics tree node.""" """Metrics tree node."""
@@ -3305,8 +3305,8 @@ class MetricsTree_Market_Dca:
"""Metrics tree node.""" """Metrics tree node."""
def __init__(self, client: BrkClientBase, base_path: str = ''): def __init__(self, client: BrkClientBase, base_path: str = ''):
self.class_average_price: MetricsTree_Market_Dca_ClassAveragePrice = MetricsTree_Market_Dca_ClassAveragePrice(client) self.class_average_price: ClassAveragePricePattern[Dollars] = ClassAveragePricePattern(client, 'dca_class')
self.class_returns: ClassAveragePricePattern[StoredF32] = ClassAveragePricePattern(client, 'dca_class') self.class_returns: MetricsTree_Market_Dca_ClassReturns = MetricsTree_Market_Dca_ClassReturns(client)
self.class_stack: MetricsTree_Market_Dca_ClassStack = MetricsTree_Market_Dca_ClassStack(client) self.class_stack: MetricsTree_Market_Dca_ClassStack = MetricsTree_Market_Dca_ClassStack(client)
self.period_average_price: PeriodAveragePricePattern[Dollars] = PeriodAveragePricePattern(client, 'dca_average_price') self.period_average_price: PeriodAveragePricePattern[Dollars] = PeriodAveragePricePattern(client, 'dca_average_price')
self.period_cagr: PeriodCagrPattern = PeriodCagrPattern(client, 'dca_cagr') self.period_cagr: PeriodCagrPattern = PeriodCagrPattern(client, 'dca_cagr')
@@ -3900,7 +3900,7 @@ class MetricsTree:
class BrkClient(BrkClientBase): class BrkClient(BrkClientBase):
"""Main BRK client with metrics tree and API methods.""" """Main BRK client with metrics tree and API methods."""
VERSION = "v0.1.0-alpha.3" VERSION = "v0.1.0-alpha.6"
INDEXES = [ INDEXES = [
"dateindex", "dateindex",