mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: snapshot
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -20,6 +20,7 @@ _*
|
||||
/*.html
|
||||
/research
|
||||
/filter_*
|
||||
/heatmaps
|
||||
|
||||
# Logs
|
||||
*.log*
|
||||
|
||||
33
Cargo.lock
generated
33
Cargo.lock
generated
@@ -463,6 +463,7 @@ dependencies = [
|
||||
"color-eyre",
|
||||
"derive_more",
|
||||
"pco",
|
||||
"plotters",
|
||||
"rayon",
|
||||
"rustc-hash",
|
||||
"schemars",
|
||||
@@ -562,6 +563,21 @@ dependencies = [
|
||||
"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]]
|
||||
name = "brk_query"
|
||||
version = "0.1.0-alpha.6"
|
||||
@@ -628,9 +644,8 @@ dependencies = [
|
||||
"brk_rpc",
|
||||
"brk_traversable",
|
||||
"brk_types",
|
||||
"brk_website",
|
||||
"derive_more",
|
||||
"importmap",
|
||||
"include_dir",
|
||||
"jiff",
|
||||
"quick_cache",
|
||||
"schemars",
|
||||
@@ -695,6 +710,20 @@ dependencies = [
|
||||
"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]]
|
||||
name = "brotli"
|
||||
version = "8.0.2"
|
||||
|
||||
@@ -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_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_website = { version = "0.1.0-alpha.6", path = "crates/brk_website" }
|
||||
byteview = "0.10.0"
|
||||
color-eyre = "0.6.5"
|
||||
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"
|
||||
tokio = { version = "1.49.0", features = ["rt-multi-thread"] }
|
||||
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 = { path = "../anydb/crates/vecdb", features = ["derive", "serde_json", "pco", "schemars"] }
|
||||
|
||||
|
||||
@@ -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.
|
||||
pub struct ActivePriceRatioPattern {
|
||||
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.
|
||||
pub struct RelativePattern5 {
|
||||
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.
|
||||
pub struct DollarsPattern<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.
|
||||
pub struct RelativePattern2 {
|
||||
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.
|
||||
pub struct CountPattern2<T> {
|
||||
pub average: MetricPattern1<T>,
|
||||
@@ -3466,25 +3466,25 @@ impl PeriodCagrPattern {
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _0satsPattern2 {
|
||||
pub struct _10yTo12yPattern {
|
||||
pub activity: ActivityPattern2,
|
||||
pub cost_basis: CostBasisPattern,
|
||||
pub cost_basis: CostBasisPattern2,
|
||||
pub outputs: OutputsPattern,
|
||||
pub realized: RealizedPattern,
|
||||
pub relative: RelativePattern4,
|
||||
pub realized: RealizedPattern2,
|
||||
pub relative: RelativePattern2,
|
||||
pub supply: SupplyPattern2,
|
||||
pub unrealized: UnrealizedPattern,
|
||||
}
|
||||
|
||||
impl _0satsPattern2 {
|
||||
impl _10yTo12yPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
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")),
|
||||
realized: RealizedPattern::new(client.clone(), acc.clone()),
|
||||
relative: RelativePattern4::new(client.clone(), _m(&acc, "supply_in")),
|
||||
realized: RealizedPattern2::new(client.clone(), acc.clone()),
|
||||
relative: RelativePattern2::new(client.clone(), acc.clone()),
|
||||
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
|
||||
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
@@ -3518,25 +3518,25 @@ impl _10yPattern {
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _10yTo12yPattern {
|
||||
pub struct _0satsPattern2 {
|
||||
pub activity: ActivityPattern2,
|
||||
pub cost_basis: CostBasisPattern2,
|
||||
pub cost_basis: CostBasisPattern,
|
||||
pub outputs: OutputsPattern,
|
||||
pub realized: RealizedPattern2,
|
||||
pub relative: RelativePattern2,
|
||||
pub realized: RealizedPattern,
|
||||
pub relative: RelativePattern4,
|
||||
pub supply: SupplyPattern2,
|
||||
pub unrealized: UnrealizedPattern,
|
||||
}
|
||||
|
||||
impl _10yTo12yPattern {
|
||||
impl _0satsPattern2 {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
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")),
|
||||
realized: RealizedPattern2::new(client.clone(), acc.clone()),
|
||||
relative: RelativePattern2::new(client.clone(), acc.clone()),
|
||||
realized: RealizedPattern::new(client.clone(), acc.clone()),
|
||||
relative: RelativePattern4::new(client.clone(), _m(&acc, "supply_in")),
|
||||
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
|
||||
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.
|
||||
pub struct CoinbasePattern {
|
||||
pub bitcoin: BitcoinPattern,
|
||||
@@ -3692,19 +3674,55 @@ impl CoinbasePattern {
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct ActiveSupplyPattern {
|
||||
pub bitcoin: MetricPattern1<Bitcoin>,
|
||||
pub dollars: MetricPattern1<Dollars>,
|
||||
pub sats: MetricPattern1<Sats>,
|
||||
pub struct CoinbasePattern2 {
|
||||
pub bitcoin: BlockCountPattern<Bitcoin>,
|
||||
pub dollars: BlockCountPattern<Dollars>,
|
||||
pub sats: BlockCountPattern<Sats>,
|
||||
}
|
||||
|
||||
impl ActiveSupplyPattern {
|
||||
impl CoinbasePattern2 {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
bitcoin: MetricPattern1::new(client.clone(), _m(&acc, "btc")),
|
||||
dollars: MetricPattern1::new(client.clone(), _m(&acc, "usd")),
|
||||
sats: MetricPattern1::new(client.clone(), acc.clone()),
|
||||
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.
|
||||
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.
|
||||
pub struct _2015Pattern {
|
||||
pub bitcoin: MetricPattern4<Bitcoin>,
|
||||
@@ -3764,19 +3764,19 @@ impl _2015Pattern {
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct SegwitAdoptionPattern {
|
||||
pub base: MetricPattern11<StoredF32>,
|
||||
pub cumulative: MetricPattern2<StoredF32>,
|
||||
pub sum: MetricPattern2<StoredF32>,
|
||||
pub struct ActiveSupplyPattern {
|
||||
pub bitcoin: MetricPattern1<Bitcoin>,
|
||||
pub dollars: MetricPattern1<Dollars>,
|
||||
pub sats: MetricPattern1<Sats>,
|
||||
}
|
||||
|
||||
impl SegwitAdoptionPattern {
|
||||
impl ActiveSupplyPattern {
|
||||
/// 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")),
|
||||
bitcoin: MetricPattern1::new(client.clone(), _m(&acc, "btc")),
|
||||
dollars: MetricPattern1::new(client.clone(), _m(&acc, "usd")),
|
||||
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.
|
||||
pub struct CostBasisPattern {
|
||||
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.
|
||||
pub struct BitcoinPattern2<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.
|
||||
pub struct RealizedPriceExtraPattern {
|
||||
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 node.
|
||||
@@ -6191,8 +6191,8 @@ impl MetricsTree_Market_Ath {
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Market_Dca {
|
||||
pub class_average_price: MetricsTree_Market_Dca_ClassAveragePrice,
|
||||
pub class_returns: ClassAveragePricePattern<StoredF32>,
|
||||
pub class_average_price: ClassAveragePricePattern<Dollars>,
|
||||
pub class_returns: MetricsTree_Market_Dca_ClassReturns,
|
||||
pub class_stack: MetricsTree_Market_Dca_ClassStack,
|
||||
pub period_average_price: PeriodAveragePricePattern<Dollars>,
|
||||
pub period_cagr: PeriodCagrPattern,
|
||||
@@ -6204,11 +6204,14 @@ pub struct MetricsTree_Market_Dca {
|
||||
impl MetricsTree_Market_Dca {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
class_average_price: MetricsTree_Market_Dca_ClassAveragePrice::new(
|
||||
class_average_price: ClassAveragePricePattern::new(
|
||||
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(
|
||||
client.clone(),
|
||||
format!("{base_path}_class_stack"),
|
||||
@@ -6232,34 +6235,34 @@ impl MetricsTree_Market_Dca {
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Market_Dca_ClassAveragePrice {
|
||||
pub _2015: MetricPattern4<Dollars>,
|
||||
pub _2016: MetricPattern4<Dollars>,
|
||||
pub _2017: MetricPattern4<Dollars>,
|
||||
pub _2018: MetricPattern4<Dollars>,
|
||||
pub _2019: MetricPattern4<Dollars>,
|
||||
pub _2020: MetricPattern4<Dollars>,
|
||||
pub _2021: MetricPattern4<Dollars>,
|
||||
pub _2022: MetricPattern4<Dollars>,
|
||||
pub _2023: MetricPattern4<Dollars>,
|
||||
pub _2024: MetricPattern4<Dollars>,
|
||||
pub _2025: MetricPattern4<Dollars>,
|
||||
pub struct MetricsTree_Market_Dca_ClassReturns {
|
||||
pub _2015: MetricPattern4<StoredF32>,
|
||||
pub _2016: MetricPattern4<StoredF32>,
|
||||
pub _2017: MetricPattern4<StoredF32>,
|
||||
pub _2018: MetricPattern4<StoredF32>,
|
||||
pub _2019: MetricPattern4<StoredF32>,
|
||||
pub _2020: MetricPattern4<StoredF32>,
|
||||
pub _2021: MetricPattern4<StoredF32>,
|
||||
pub _2022: MetricPattern4<StoredF32>,
|
||||
pub _2023: MetricPattern4<StoredF32>,
|
||||
pub _2024: MetricPattern4<StoredF32>,
|
||||
pub _2025: MetricPattern4<StoredF32>,
|
||||
}
|
||||
|
||||
impl MetricsTree_Market_Dca_ClassAveragePrice {
|
||||
impl MetricsTree_Market_Dca_ClassReturns {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
_2015: MetricPattern4::new(client.clone(), "dca_class_2015_average_price".to_string()),
|
||||
_2016: MetricPattern4::new(client.clone(), "dca_class_2016_average_price".to_string()),
|
||||
_2017: MetricPattern4::new(client.clone(), "dca_class_2017_average_price".to_string()),
|
||||
_2018: MetricPattern4::new(client.clone(), "dca_class_2018_average_price".to_string()),
|
||||
_2019: MetricPattern4::new(client.clone(), "dca_class_2019_average_price".to_string()),
|
||||
_2020: MetricPattern4::new(client.clone(), "dca_class_2020_average_price".to_string()),
|
||||
_2021: MetricPattern4::new(client.clone(), "dca_class_2021_average_price".to_string()),
|
||||
_2022: MetricPattern4::new(client.clone(), "dca_class_2022_average_price".to_string()),
|
||||
_2023: MetricPattern4::new(client.clone(), "dca_class_2023_average_price".to_string()),
|
||||
_2024: MetricPattern4::new(client.clone(), "dca_class_2024_average_price".to_string()),
|
||||
_2025: MetricPattern4::new(client.clone(), "dca_class_2025_average_price".to_string()),
|
||||
_2015: MetricPattern4::new(client.clone(), "dca_class_2015_returns".to_string()),
|
||||
_2016: MetricPattern4::new(client.clone(), "dca_class_2016_returns".to_string()),
|
||||
_2017: MetricPattern4::new(client.clone(), "dca_class_2017_returns".to_string()),
|
||||
_2018: MetricPattern4::new(client.clone(), "dca_class_2018_returns".to_string()),
|
||||
_2019: MetricPattern4::new(client.clone(), "dca_class_2019_returns".to_string()),
|
||||
_2020: MetricPattern4::new(client.clone(), "dca_class_2020_returns".to_string()),
|
||||
_2021: MetricPattern4::new(client.clone(), "dca_class_2021_returns".to_string()),
|
||||
_2022: MetricPattern4::new(client.clone(), "dca_class_2022_returns".to_string()),
|
||||
_2023: MetricPattern4::new(client.clone(), "dca_class_2023_returns".to_string()),
|
||||
_2024: MetricPattern4::new(client.clone(), "dca_class_2024_returns".to_string()),
|
||||
_2025: MetricPattern4::new(client.clone(), "dca_class_2025_returns".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7599,7 +7602,7 @@ pub struct BrkClient {
|
||||
|
||||
impl BrkClient {
|
||||
/// 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.
|
||||
pub fn new(base_url: impl Into<String>) -> Self {
|
||||
|
||||
@@ -32,5 +32,6 @@ vecdb = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
brk_alloc = { workspace = true }
|
||||
plotters = "0.3"
|
||||
brk_bencher = { workspace = true }
|
||||
color-eyre = { workspace = true }
|
||||
|
||||
@@ -4,7 +4,7 @@ use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
EmptyAddressData, EmptyAddressIndex, Height, LoadedAddressData, LoadedAddressIndex,
|
||||
DateIndex, EmptyAddressData, EmptyAddressIndex, Height, LoadedAddressData, LoadedAddressIndex,
|
||||
SupplyState, Version,
|
||||
};
|
||||
use tracing::info;
|
||||
@@ -242,6 +242,21 @@ impl Vecs {
|
||||
(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
|
||||
let base_version = VERSION;
|
||||
self.utxo_cohorts.validate_computed_versions(base_version)?;
|
||||
|
||||
@@ -15,14 +15,14 @@ mod blocks;
|
||||
mod cointime;
|
||||
mod constants;
|
||||
mod distribution;
|
||||
mod indexes;
|
||||
pub mod indexes;
|
||||
mod inputs;
|
||||
mod internal;
|
||||
mod market;
|
||||
mod outputs;
|
||||
mod pools;
|
||||
mod positions;
|
||||
mod price;
|
||||
pub mod price;
|
||||
mod scripts;
|
||||
mod supply;
|
||||
mod traits;
|
||||
|
||||
7
crates/brk_playground/.gitignore
vendored
Normal file
7
crates/brk_playground/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# Ignore everything in playground except essential files
|
||||
*
|
||||
!.gitignore
|
||||
!Cargo.toml
|
||||
!src/
|
||||
!src/lib.rs
|
||||
!README.md
|
||||
20
crates/brk_playground/Cargo.toml
Normal file
20
crates/brk_playground/Cargo.toml
Normal 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 }
|
||||
4
crates/brk_playground/src/lib.rs
Normal file
4
crates/brk_playground/src/lib.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
//! Experimental playground for brk development.
|
||||
//!
|
||||
//! This crate is for experiments and prototypes.
|
||||
//! Most contents are git-ignored.
|
||||
@@ -6,7 +6,6 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
include = ["src/**/*", "website/**/*", "examples/**/*", "Cargo.toml", "README.md"]
|
||||
|
||||
[dependencies]
|
||||
aide = { workspace = true }
|
||||
@@ -22,10 +21,8 @@ brk_reader = { workspace = true }
|
||||
brk_rpc = { workspace = true }
|
||||
brk_types = { workspace = true }
|
||||
brk_traversable = { workspace = true }
|
||||
brk_website = { 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 }
|
||||
jiff = { workspace = true }
|
||||
quick_cache = "0.6.18"
|
||||
@@ -34,8 +31,8 @@ serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tokio = { 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-layer = "0.3"
|
||||
tower-http = { workspace = true }
|
||||
tower-layer = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
brk_mempool = { workspace = true }
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
use std::path::Path;
|
||||
|
||||
use axum::http::{
|
||||
HeaderMap,
|
||||
header::{self, IF_NONE_MATCH},
|
||||
@@ -7,31 +5,29 @@ use axum::http::{
|
||||
|
||||
pub trait HeaderMapExtended {
|
||||
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_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_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_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_html(&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);
|
||||
}
|
||||
|
||||
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) {
|
||||
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");
|
||||
}
|
||||
|
||||
fn insert_cache_control_immutable(&mut self) {
|
||||
self.insert_cache_control("public, max-age=31536000, immutable");
|
||||
}
|
||||
|
||||
fn insert_content_disposition_attachment(&mut self) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
self.insert(
|
||||
header::CONTENT_TYPE,
|
||||
|
||||
@@ -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")))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ use axum::{
|
||||
serve,
|
||||
};
|
||||
use brk_query::AsyncQuery;
|
||||
use include_dir::{Dir, include_dir};
|
||||
use quick_cache::sync::Cache;
|
||||
use tokio::net::TcpListener;
|
||||
use tower_http::{
|
||||
@@ -29,23 +28,17 @@ use tower_http::{
|
||||
use tower_layer::Layer;
|
||||
use tracing::{error, info};
|
||||
|
||||
/// Embedded website assets
|
||||
pub static EMBEDDED_WEBSITE: Dir = include_dir!("$CARGO_MANIFEST_DIR/website");
|
||||
|
||||
mod api;
|
||||
pub mod cache;
|
||||
mod error;
|
||||
mod extended;
|
||||
mod files;
|
||||
mod state;
|
||||
|
||||
use api::*;
|
||||
pub use brk_types::Port;
|
||||
pub use brk_website::Website;
|
||||
pub use cache::{CacheParams, CacheStrategy};
|
||||
pub use error::{Error, Result};
|
||||
use extended::*;
|
||||
use files::FilesRoutes;
|
||||
pub use files::Website;
|
||||
use state::*;
|
||||
|
||||
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<()> {
|
||||
let state = self.0;
|
||||
|
||||
let compression_layer = CompressionLayer::new()
|
||||
.br(true)
|
||||
.gzip(true)
|
||||
.zstd(true);
|
||||
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> {
|
||||
@@ -107,35 +97,23 @@ impl Server {
|
||||
.on_eos(());
|
||||
|
||||
let vecs = state.query.inner().vecs();
|
||||
let router = ApiRouter::new()
|
||||
.add_api_routes()
|
||||
.add_files_routes(&state.website)
|
||||
.route(
|
||||
"/discord",
|
||||
get(Redirect::temporary("https://discord.gg/WACpShCB7M")),
|
||||
)
|
||||
.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")))
|
||||
|
||||
let website_router = brk_website::router(state.website.clone());
|
||||
let mut router = ApiRouter::new().add_api_routes();
|
||||
if !state.website.is_enabled() {
|
||||
router = router.route("/", get(Redirect::temporary("/api")));
|
||||
}
|
||||
let router = router
|
||||
.with_state(state)
|
||||
.merge(website_router)
|
||||
.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(TimeoutLayer::with_status_code(
|
||||
StatusCode::GATEWAY_TIMEOUT,
|
||||
Duration::from_secs(5),
|
||||
))
|
||||
.layer(CorsLayer::permissive());
|
||||
|
||||
let (listener, port) = match port {
|
||||
|
||||
21
crates/brk_website/Cargo.toml
Normal file
21
crates/brk_website/Cargo.toml
Normal 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 }
|
||||
44
crates/brk_website/README.md
Normal file
44
crates/brk_website/README.md
Normal 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
|
||||
100
crates/brk_website/examples/website.rs
Normal file
100
crates/brk_website/examples/website.rs
Normal 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
|
||||
}
|
||||
23
crates/brk_website/src/error.rs
Normal file
23
crates/brk_website/src/error.rs
Normal 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()
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,23 @@
|
||||
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(
|
||||
State(state): State<AppState>,
|
||||
State(website): State<Website>,
|
||||
path: axum::extract::Path<String>,
|
||||
) -> Result<Response> {
|
||||
serve(&state, &path.0)
|
||||
) -> Result<Response<Body>> {
|
||||
serve(&website, &path.0)
|
||||
}
|
||||
|
||||
pub async fn index_handler(State(state): State<AppState>) -> Result<Response> {
|
||||
serve(&state, "")
|
||||
pub async fn index_handler(State(website): State<Website>) -> Result<Response<Body>> {
|
||||
serve(&website, "")
|
||||
}
|
||||
|
||||
fn serve(state: &AppState, path: &str) -> Result<Response> {
|
||||
fn serve(website: &Website, path: &str) -> Result<Response<Body>> {
|
||||
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 headers = response.headers_mut();
|
||||
53
crates/brk_website/src/headers.rs
Normal file
53
crates/brk_website/src/headers.rs
Normal 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());
|
||||
}
|
||||
}
|
||||
17
crates/brk_website/src/lib.rs
Normal file
17
crates/brk_website/src/lib.rs
Normal 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};
|
||||
17
crates/brk_website/src/router.rs
Normal file
17
crates/brk_website/src/router.rs
Normal 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()
|
||||
}
|
||||
}
|
||||
@@ -5,17 +5,22 @@ use std::{
|
||||
};
|
||||
|
||||
use importmap::ImportMap;
|
||||
use include_dir::{Dir, include_dir};
|
||||
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
|
||||
static INDEX_HTML: OnceLock<String> = OnceLock::new();
|
||||
|
||||
/// Source for serving the website
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub enum Website {
|
||||
Disabled,
|
||||
#[default]
|
||||
Default,
|
||||
Filesystem(PathBuf),
|
||||
}
|
||||
@@ -42,7 +47,12 @@ impl Website {
|
||||
}
|
||||
|
||||
/// 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>> {
|
||||
if !self.is_enabled() {
|
||||
return Err(Error::not_found("Website is disabled"));
|
||||
}
|
||||
match self.filesystem_path() {
|
||||
None => self.get_embedded(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)
|
||||
pub fn log(&self) {
|
||||
match self {
|
||||
Self::Disabled => info!("Website: disabled"),
|
||||
Self::Disabled => info!("website: disabled"),
|
||||
Self::Default => {
|
||||
if let Some(p) = self.filesystem_path() {
|
||||
info!("Website: filesystem ({})", p.display());
|
||||
info!("website: filesystem ({})", p.display());
|
||||
} else {
|
||||
info!("Website: embedded");
|
||||
info!("website: embedded");
|
||||
}
|
||||
}
|
||||
Self::Filesystem(p) => info!("Website: filesystem ({})", p.display()),
|
||||
Self::Filesystem(p) => info!("website: filesystem ({})", p.display()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
* @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
|
||||
* @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
|
||||
* @typedef {Object} DollarsPattern
|
||||
@@ -2045,41 +2084,37 @@ function createDollarsPattern(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
|
||||
* @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 ClassAveragePricePattern pattern node
|
||||
* @template T
|
||||
* Create a RelativePattern2 pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {ClassAveragePricePattern<T>}
|
||||
* @returns {RelativePattern2}
|
||||
*/
|
||||
function createClassAveragePricePattern(client, acc) {
|
||||
function createRelativePattern2(client, acc) {
|
||||
return {
|
||||
_2015: createMetricPattern4(client, _m(acc, '2015_returns')),
|
||||
_2016: createMetricPattern4(client, _m(acc, '2016_returns')),
|
||||
_2017: createMetricPattern4(client, _m(acc, '2017_returns')),
|
||||
_2018: createMetricPattern4(client, _m(acc, '2018_returns')),
|
||||
_2019: createMetricPattern4(client, _m(acc, '2019_returns')),
|
||||
_2020: createMetricPattern4(client, _m(acc, '2020_returns')),
|
||||
_2021: createMetricPattern4(client, _m(acc, '2021_returns')),
|
||||
_2022: createMetricPattern4(client, _m(acc, '2022_returns')),
|
||||
_2023: createMetricPattern4(client, _m(acc, '2023_returns')),
|
||||
_2024: createMetricPattern4(client, _m(acc, '2024_returns')),
|
||||
_2025: createMetricPattern4(client, _m(acc, '2025_returns')),
|
||||
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')),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
* @typedef {Object} CountPattern2
|
||||
@@ -2387,29 +2387,29 @@ function createPeriodCagrPattern(client, acc) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} _0satsPattern2
|
||||
* @typedef {Object} _10yTo12yPattern
|
||||
* @property {ActivityPattern2} activity
|
||||
* @property {CostBasisPattern} costBasis
|
||||
* @property {CostBasisPattern2} costBasis
|
||||
* @property {OutputsPattern} outputs
|
||||
* @property {RealizedPattern} realized
|
||||
* @property {RelativePattern4} relative
|
||||
* @property {RealizedPattern2} realized
|
||||
* @property {RelativePattern2} relative
|
||||
* @property {SupplyPattern2} supply
|
||||
* @property {UnrealizedPattern} unrealized
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a _0satsPattern2 pattern node
|
||||
* Create a _10yTo12yPattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {_0satsPattern2}
|
||||
* @returns {_10yTo12yPattern}
|
||||
*/
|
||||
function create_0satsPattern2(client, acc) {
|
||||
function create_10yTo12yPattern(client, acc) {
|
||||
return {
|
||||
activity: createActivityPattern2(client, acc),
|
||||
costBasis: createCostBasisPattern(client, acc),
|
||||
costBasis: createCostBasisPattern2(client, acc),
|
||||
outputs: createOutputsPattern(client, _m(acc, 'utxo_count')),
|
||||
realized: createRealizedPattern(client, acc),
|
||||
relative: createRelativePattern4(client, _m(acc, 'supply_in')),
|
||||
realized: createRealizedPattern2(client, acc),
|
||||
relative: createRelativePattern2(client, acc),
|
||||
supply: createSupplyPattern2(client, _m(acc, 'supply')),
|
||||
unrealized: createUnrealizedPattern(client, acc),
|
||||
};
|
||||
@@ -2445,29 +2445,29 @@ function create_10yPattern(client, acc) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} _10yTo12yPattern
|
||||
* @typedef {Object} _0satsPattern2
|
||||
* @property {ActivityPattern2} activity
|
||||
* @property {CostBasisPattern2} costBasis
|
||||
* @property {CostBasisPattern} costBasis
|
||||
* @property {OutputsPattern} outputs
|
||||
* @property {RealizedPattern2} realized
|
||||
* @property {RelativePattern2} relative
|
||||
* @property {RealizedPattern} realized
|
||||
* @property {RelativePattern4} relative
|
||||
* @property {SupplyPattern2} supply
|
||||
* @property {UnrealizedPattern} unrealized
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a _10yTo12yPattern pattern node
|
||||
* Create a _0satsPattern2 pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {_10yTo12yPattern}
|
||||
* @returns {_0satsPattern2}
|
||||
*/
|
||||
function create_10yTo12yPattern(client, acc) {
|
||||
function create_0satsPattern2(client, acc) {
|
||||
return {
|
||||
activity: createActivityPattern2(client, acc),
|
||||
costBasis: createCostBasisPattern2(client, acc),
|
||||
costBasis: createCostBasisPattern(client, acc),
|
||||
outputs: createOutputsPattern(client, _m(acc, 'utxo_count')),
|
||||
realized: createRealizedPattern2(client, acc),
|
||||
relative: createRelativePattern2(client, acc),
|
||||
realized: createRealizedPattern(client, acc),
|
||||
relative: createRelativePattern4(client, _m(acc, 'supply_in')),
|
||||
supply: createSupplyPattern2(client, _m(acc, 'supply')),
|
||||
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
|
||||
* @property {BitcoinPattern} bitcoin
|
||||
@@ -2624,23 +2603,65 @@ function createCoinbasePattern(client, acc) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} ActiveSupplyPattern
|
||||
* @property {MetricPattern1<Bitcoin>} bitcoin
|
||||
* @property {MetricPattern1<Dollars>} dollars
|
||||
* @property {MetricPattern1<Sats>} sats
|
||||
* @typedef {Object} CoinbasePattern2
|
||||
* @property {BlockCountPattern<Bitcoin>} bitcoin
|
||||
* @property {BlockCountPattern<Dollars>} dollars
|
||||
* @property {BlockCountPattern<Sats>} sats
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a ActiveSupplyPattern pattern node
|
||||
* Create a CoinbasePattern2 pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {ActiveSupplyPattern}
|
||||
* @returns {CoinbasePattern2}
|
||||
*/
|
||||
function createActiveSupplyPattern(client, acc) {
|
||||
function createCoinbasePattern2(client, acc) {
|
||||
return {
|
||||
bitcoin: createMetricPattern1(client, _m(acc, 'btc')),
|
||||
dollars: createMetricPattern1(client, _m(acc, 'usd')),
|
||||
sats: createMetricPattern1(client, acc),
|
||||
bitcoin: createBlockCountPattern(client, _m(acc, 'btc')),
|
||||
dollars: createBlockCountPattern(client, _m(acc, 'usd')),
|
||||
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
|
||||
* @property {MetricPattern4<Bitcoin>} bitcoin
|
||||
@@ -2708,23 +2708,23 @@ function create_2015Pattern(client, acc) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} SegwitAdoptionPattern
|
||||
* @property {MetricPattern11<StoredF32>} base
|
||||
* @property {MetricPattern2<StoredF32>} cumulative
|
||||
* @property {MetricPattern2<StoredF32>} sum
|
||||
* @typedef {Object} ActiveSupplyPattern
|
||||
* @property {MetricPattern1<Bitcoin>} bitcoin
|
||||
* @property {MetricPattern1<Dollars>} dollars
|
||||
* @property {MetricPattern1<Sats>} sats
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a SegwitAdoptionPattern pattern node
|
||||
* Create a ActiveSupplyPattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {SegwitAdoptionPattern}
|
||||
* @returns {ActiveSupplyPattern}
|
||||
*/
|
||||
function createSegwitAdoptionPattern(client, acc) {
|
||||
function createActiveSupplyPattern(client, acc) {
|
||||
return {
|
||||
base: createMetricPattern11(client, acc),
|
||||
cumulative: createMetricPattern2(client, _m(acc, 'cumulative')),
|
||||
sum: createMetricPattern2(client, _m(acc, 'sum')),
|
||||
bitcoin: createMetricPattern1(client, _m(acc, 'btc')),
|
||||
dollars: createMetricPattern1(client, _m(acc, 'usd')),
|
||||
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
|
||||
* @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
|
||||
* @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
|
||||
* @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
|
||||
|
||||
/**
|
||||
@@ -3696,8 +3696,8 @@ function createRealizedPriceExtraPattern(client, acc) {
|
||||
|
||||
/**
|
||||
* @typedef {Object} MetricsTree_Market_Dca
|
||||
* @property {MetricsTree_Market_Dca_ClassAveragePrice} classAveragePrice
|
||||
* @property {ClassAveragePricePattern<StoredF32>} classReturns
|
||||
* @property {ClassAveragePricePattern<Dollars>} classAveragePrice
|
||||
* @property {MetricsTree_Market_Dca_ClassReturns} classReturns
|
||||
* @property {MetricsTree_Market_Dca_ClassStack} classStack
|
||||
* @property {PeriodAveragePricePattern<Dollars>} periodAveragePrice
|
||||
* @property {PeriodCagrPattern} periodCagr
|
||||
@@ -3707,18 +3707,18 @@ function createRealizedPriceExtraPattern(client, acc) {
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} MetricsTree_Market_Dca_ClassAveragePrice
|
||||
* @property {MetricPattern4<Dollars>} _2015
|
||||
* @property {MetricPattern4<Dollars>} _2016
|
||||
* @property {MetricPattern4<Dollars>} _2017
|
||||
* @property {MetricPattern4<Dollars>} _2018
|
||||
* @property {MetricPattern4<Dollars>} _2019
|
||||
* @property {MetricPattern4<Dollars>} _2020
|
||||
* @property {MetricPattern4<Dollars>} _2021
|
||||
* @property {MetricPattern4<Dollars>} _2022
|
||||
* @property {MetricPattern4<Dollars>} _2023
|
||||
* @property {MetricPattern4<Dollars>} _2024
|
||||
* @property {MetricPattern4<Dollars>} _2025
|
||||
* @typedef {Object} MetricsTree_Market_Dca_ClassReturns
|
||||
* @property {MetricPattern4<StoredF32>} _2015
|
||||
* @property {MetricPattern4<StoredF32>} _2016
|
||||
* @property {MetricPattern4<StoredF32>} _2017
|
||||
* @property {MetricPattern4<StoredF32>} _2018
|
||||
* @property {MetricPattern4<StoredF32>} _2019
|
||||
* @property {MetricPattern4<StoredF32>} _2020
|
||||
* @property {MetricPattern4<StoredF32>} _2021
|
||||
* @property {MetricPattern4<StoredF32>} _2022
|
||||
* @property {MetricPattern4<StoredF32>} _2023
|
||||
* @property {MetricPattern4<StoredF32>} _2024
|
||||
* @property {MetricPattern4<StoredF32>} _2025
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -4259,7 +4259,7 @@ function createRealizedPriceExtraPattern(client, acc) {
|
||||
* @extends BrkClientBase
|
||||
*/
|
||||
class BrkClient extends BrkClientBase {
|
||||
VERSION = "v0.1.0-alpha.3";
|
||||
VERSION = "v0.1.0-alpha.6";
|
||||
|
||||
INDEXES = /** @type {const} */ ([
|
||||
"dateindex",
|
||||
@@ -5726,20 +5726,20 @@ class BrkClient extends BrkClientBase {
|
||||
yearsSincePriceAth: createMetricPattern4(this, 'years_since_price_ath'),
|
||||
},
|
||||
dca: {
|
||||
classAveragePrice: {
|
||||
_2015: createMetricPattern4(this, 'dca_class_2015_average_price'),
|
||||
_2016: createMetricPattern4(this, 'dca_class_2016_average_price'),
|
||||
_2017: createMetricPattern4(this, 'dca_class_2017_average_price'),
|
||||
_2018: createMetricPattern4(this, 'dca_class_2018_average_price'),
|
||||
_2019: createMetricPattern4(this, 'dca_class_2019_average_price'),
|
||||
_2020: createMetricPattern4(this, 'dca_class_2020_average_price'),
|
||||
_2021: createMetricPattern4(this, 'dca_class_2021_average_price'),
|
||||
_2022: createMetricPattern4(this, 'dca_class_2022_average_price'),
|
||||
_2023: createMetricPattern4(this, 'dca_class_2023_average_price'),
|
||||
_2024: createMetricPattern4(this, 'dca_class_2024_average_price'),
|
||||
_2025: createMetricPattern4(this, 'dca_class_2025_average_price'),
|
||||
classAveragePrice: createClassAveragePricePattern(this, 'dca_class'),
|
||||
classReturns: {
|
||||
_2015: createMetricPattern4(this, 'dca_class_2015_returns'),
|
||||
_2016: createMetricPattern4(this, 'dca_class_2016_returns'),
|
||||
_2017: createMetricPattern4(this, 'dca_class_2017_returns'),
|
||||
_2018: createMetricPattern4(this, 'dca_class_2018_returns'),
|
||||
_2019: createMetricPattern4(this, 'dca_class_2019_returns'),
|
||||
_2020: createMetricPattern4(this, 'dca_class_2020_returns'),
|
||||
_2021: createMetricPattern4(this, 'dca_class_2021_returns'),
|
||||
_2022: createMetricPattern4(this, 'dca_class_2022_returns'),
|
||||
_2023: createMetricPattern4(this, 'dca_class_2023_returns'),
|
||||
_2024: createMetricPattern4(this, 'dca_class_2024_returns'),
|
||||
_2025: createMetricPattern4(this, 'dca_class_2025_returns'),
|
||||
},
|
||||
classReturns: createClassAveragePricePattern(this, 'dca_class'),
|
||||
classStack: {
|
||||
_2015: create_2015Pattern(this, 'dca_class_2015_stack'),
|
||||
_2016: create_2015Pattern(this, 'dca_class_2016_stack'),
|
||||
|
||||
@@ -1883,31 +1883,6 @@ class Price111dSmaPattern:
|
||||
self.ratio_pct99_usd: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'ratio_pct99_usd'))
|
||||
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:
|
||||
"""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_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:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
@@ -2049,6 +2049,23 @@ class BitcoinPattern:
|
||||
self.pct90: MetricPattern6[Bitcoin] = MetricPattern6(client, _m(acc, 'pct90'))
|
||||
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]):
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
@@ -2066,22 +2083,21 @@ class DollarsPattern(Generic[T]):
|
||||
self.pct90: MetricPattern6[T] = MetricPattern6(client, _m(acc, 'pct90'))
|
||||
self.sum: MetricPattern2[T] = MetricPattern2(client, _m(acc, 'sum'))
|
||||
|
||||
class ClassAveragePricePattern(Generic[T]):
|
||||
class RelativePattern2:
|
||||
"""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_returns'))
|
||||
self._2016: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2016_returns'))
|
||||
self._2017: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2017_returns'))
|
||||
self._2018: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2018_returns'))
|
||||
self._2019: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2019_returns'))
|
||||
self._2020: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2020_returns'))
|
||||
self._2021: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2021_returns'))
|
||||
self._2022: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2022_returns'))
|
||||
self._2023: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2023_returns'))
|
||||
self._2024: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2024_returns'))
|
||||
self._2025: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2025_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.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 RelativePattern:
|
||||
"""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_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]):
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
@@ -2217,16 +2217,16 @@ class PeriodCagrPattern:
|
||||
self._6y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('6y', acc))
|
||||
self._8y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('8y', acc))
|
||||
|
||||
class _0satsPattern2:
|
||||
class _10yTo12yPattern:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
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.realized: RealizedPattern = RealizedPattern(client, acc)
|
||||
self.relative: RelativePattern4 = RelativePattern4(client, _m(acc, 'supply_in'))
|
||||
self.realized: RealizedPattern2 = RealizedPattern2(client, acc)
|
||||
self.relative: RelativePattern2 = RelativePattern2(client, acc)
|
||||
self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply'))
|
||||
self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc)
|
||||
|
||||
@@ -2243,16 +2243,16 @@ class _10yPattern:
|
||||
self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply'))
|
||||
self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc)
|
||||
|
||||
class _10yTo12yPattern:
|
||||
class _0satsPattern2:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
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.realized: RealizedPattern2 = RealizedPattern2(client, acc)
|
||||
self.relative: RelativePattern2 = RelativePattern2(client, acc)
|
||||
self.realized: RealizedPattern = RealizedPattern(client, acc)
|
||||
self.relative: RelativePattern4 = RelativePattern4(client, _m(acc, 'supply_in'))
|
||||
self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply'))
|
||||
self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc)
|
||||
|
||||
@@ -2303,15 +2303,6 @@ class SplitPattern2(Generic[T]):
|
||||
self.low: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'low'))
|
||||
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:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
@@ -2321,14 +2312,32 @@ class CoinbasePattern:
|
||||
self.dollars: DollarsPattern[Dollars] = DollarsPattern(client, _m(acc, 'usd'))
|
||||
self.sats: DollarsPattern[Sats] = DollarsPattern(client, acc)
|
||||
|
||||
class ActiveSupplyPattern:
|
||||
class CoinbasePattern2:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self.bitcoin: MetricPattern1[Bitcoin] = MetricPattern1(client, _m(acc, 'btc'))
|
||||
self.dollars: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd'))
|
||||
self.sats: MetricPattern1[Sats] = MetricPattern1(client, acc)
|
||||
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 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:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -2339,15 +2348,6 @@ class UnclaimedRewardsPattern:
|
||||
self.dollars: BlockCountPattern[Dollars] = BlockCountPattern(client, _m(acc, 'usd'))
|
||||
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:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
@@ -2357,14 +2357,14 @@ class _2015Pattern:
|
||||
self.dollars: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'usd'))
|
||||
self.sats: MetricPattern4[Sats] = MetricPattern4(client, acc)
|
||||
|
||||
class SegwitAdoptionPattern:
|
||||
class ActiveSupplyPattern:
|
||||
"""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'))
|
||||
self.bitcoin: MetricPattern1[Bitcoin] = MetricPattern1(client, _m(acc, 'btc'))
|
||||
self.dollars: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd'))
|
||||
self.sats: MetricPattern1[Sats] = MetricPattern1(client, acc)
|
||||
|
||||
class _1dReturns1mSdPattern:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -2374,6 +2374,14 @@ class _1dReturns1mSdPattern:
|
||||
self.sd: MetricPattern4[StoredF32] = MetricPattern4(client, _m(acc, 'sd'))
|
||||
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:
|
||||
"""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_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]):
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
@@ -2422,13 +2422,6 @@ class BlockCountPattern(Generic[T]):
|
||||
self.cumulative: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'cumulative'))
|
||||
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:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
@@ -2436,6 +2429,13 @@ class RealizedPriceExtraPattern:
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
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
|
||||
|
||||
class MetricsTree_Addresses:
|
||||
@@ -3269,21 +3269,21 @@ class MetricsTree_Market_Ath:
|
||||
self.price_drawdown: MetricPattern3[StoredF32] = MetricPattern3(client, 'price_drawdown')
|
||||
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."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||
self._2015: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2015_average_price')
|
||||
self._2016: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2016_average_price')
|
||||
self._2017: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2017_average_price')
|
||||
self._2018: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2018_average_price')
|
||||
self._2019: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2019_average_price')
|
||||
self._2020: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2020_average_price')
|
||||
self._2021: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2021_average_price')
|
||||
self._2022: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2022_average_price')
|
||||
self._2023: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2023_average_price')
|
||||
self._2024: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2024_average_price')
|
||||
self._2025: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2025_average_price')
|
||||
self._2015: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2015_returns')
|
||||
self._2016: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2016_returns')
|
||||
self._2017: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2017_returns')
|
||||
self._2018: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2018_returns')
|
||||
self._2019: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2019_returns')
|
||||
self._2020: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2020_returns')
|
||||
self._2021: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2021_returns')
|
||||
self._2022: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2022_returns')
|
||||
self._2023: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2023_returns')
|
||||
self._2024: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2024_returns')
|
||||
self._2025: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2025_returns')
|
||||
|
||||
class MetricsTree_Market_Dca_ClassStack:
|
||||
"""Metrics tree node."""
|
||||
@@ -3305,8 +3305,8 @@ class MetricsTree_Market_Dca:
|
||||
"""Metrics tree node."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||
self.class_average_price: MetricsTree_Market_Dca_ClassAveragePrice = MetricsTree_Market_Dca_ClassAveragePrice(client)
|
||||
self.class_returns: ClassAveragePricePattern[StoredF32] = ClassAveragePricePattern(client, 'dca_class')
|
||||
self.class_average_price: ClassAveragePricePattern[Dollars] = 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.period_average_price: PeriodAveragePricePattern[Dollars] = PeriodAveragePricePattern(client, 'dca_average_price')
|
||||
self.period_cagr: PeriodCagrPattern = PeriodCagrPattern(client, 'dca_cagr')
|
||||
@@ -3900,7 +3900,7 @@ class MetricsTree:
|
||||
class BrkClient(BrkClientBase):
|
||||
"""Main BRK client with metrics tree and API methods."""
|
||||
|
||||
VERSION = "v0.1.0-alpha.3"
|
||||
VERSION = "v0.1.0-alpha.6"
|
||||
|
||||
INDEXES = [
|
||||
"dateindex",
|
||||
|
||||
Reference in New Issue
Block a user