diff --git a/crates/brk_client/src/lib.rs b/crates/brk_client/src/lib.rs index 6862940d5..5407d15bc 100644 --- a/crates/brk_client/src/lib.rs +++ b/crates/brk_client/src/lib.rs @@ -988,13 +988,16 @@ pub struct CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSell pub sent_in_loss_ema: _2wPattern, pub sent_in_profit: BaseCumulativePattern, pub sent_in_profit_ema: _2wPattern, - pub sopr: _1m1w1y24hPattern, + pub sopr: _24hPattern, pub sopr_24h_ema: _1m1wPattern, + pub sopr_extended: _1m1w1yPattern, pub upper_price_band: CentsSatsUsdPattern, pub value_created: MetricPattern1, - pub value_created_sum: _1m1w1y24hPattern, + pub value_created_sum: _24hPattern, + pub value_created_sum_extended: _1m1w1yPattern, pub value_destroyed: MetricPattern1, - pub value_destroyed_sum: _1m1w1y24hPattern, + pub value_destroyed_sum: _24hPattern, + pub value_destroyed_sum_extended: _1m1w1yPattern, } impl CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSoprUpperValuePattern { @@ -1048,13 +1051,16 @@ impl CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentSo sent_in_loss_ema: _2wPattern::new(client.clone(), _m(&acc, "sent_in_loss_ema_2w")), sent_in_profit: BaseCumulativePattern::new(client.clone(), _m(&acc, "sent_in_profit")), sent_in_profit_ema: _2wPattern::new(client.clone(), _m(&acc, "sent_in_profit_ema_2w")), - sopr: _1m1w1y24hPattern::new(client.clone(), _m(&acc, "sopr")), + sopr: _24hPattern::new(client.clone(), _m(&acc, "sopr_24h")), sopr_24h_ema: _1m1wPattern::new(client.clone(), _m(&acc, "sopr_24h_ema")), + sopr_extended: _1m1w1yPattern::new(client.clone(), _m(&acc, "sopr")), upper_price_band: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "upper_price_band")), value_created: MetricPattern1::new(client.clone(), _m(&acc, "value_created")), - value_created_sum: _1m1w1y24hPattern::new(client.clone(), _m(&acc, "value_created")), + value_created_sum: _24hPattern::new(client.clone(), _m(&acc, "value_created_24h")), + value_created_sum_extended: _1m1w1yPattern::new(client.clone(), _m(&acc, "value_created")), value_destroyed: MetricPattern1::new(client.clone(), _m(&acc, "value_destroyed")), - value_destroyed_sum: _1m1w1y24hPattern::new(client.clone(), _m(&acc, "value_destroyed")), + value_destroyed_sum: _24hPattern::new(client.clone(), _m(&acc, "value_destroyed_24h")), + value_destroyed_sum_extended: _1m1w1yPattern::new(client.clone(), _m(&acc, "value_destroyed")), } } } @@ -1237,11 +1243,11 @@ pub struct MvrvNegNetRealizedSentSoprValuePattern { pub realized_profit: CumulativeHeightPattern, pub sent_in_loss: BaseCumulativePattern, pub sent_in_profit: BaseCumulativePattern, - pub sopr: _1m1w1y24hPattern, + pub sopr: _24hPattern, pub value_created: MetricPattern1, - pub value_created_sum: _1m1w1y24hPattern, + pub value_created_sum: _24hPattern, pub value_destroyed: MetricPattern1, - pub value_destroyed_sum: _1m1w1y24hPattern, + pub value_destroyed_sum: _24hPattern, } impl MvrvNegNetRealizedSentSoprValuePattern { @@ -1260,11 +1266,11 @@ impl MvrvNegNetRealizedSentSoprValuePattern { realized_profit: CumulativeHeightPattern::new(client.clone(), _m(&acc, "realized_profit")), sent_in_loss: BaseCumulativePattern::new(client.clone(), _m(&acc, "sent_in_loss")), sent_in_profit: BaseCumulativePattern::new(client.clone(), _m(&acc, "sent_in_profit")), - sopr: _1m1w1y24hPattern::new(client.clone(), _m(&acc, "sopr")), + sopr: _24hPattern::new(client.clone(), _m(&acc, "sopr_24h")), value_created: MetricPattern1::new(client.clone(), _m(&acc, "value_created")), - value_created_sum: _1m1w1y24hPattern::new(client.clone(), _m(&acc, "value_created")), + value_created_sum: _24hPattern::new(client.clone(), _m(&acc, "value_created_24h")), value_destroyed: MetricPattern1::new(client.clone(), _m(&acc, "value_destroyed")), - value_destroyed_sum: _1m1w1y24hPattern::new(client.clone(), _m(&acc, "value_destroyed")), + value_destroyed_sum: _24hPattern::new(client.clone(), _m(&acc, "value_destroyed_24h")), } } } @@ -2375,6 +2381,24 @@ impl ChangeHalvedTotalPattern { } } +/// Pattern struct for repeated tree structure. +pub struct _1m1w1yPattern { + pub _1m: MetricPattern1, + pub _1w: MetricPattern1, + pub _1y: MetricPattern1, +} + +impl _1m1w1yPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + _1m: MetricPattern1::new(client.clone(), _m(&acc, "1m")), + _1w: MetricPattern1::new(client.clone(), _m(&acc, "1w")), + _1y: MetricPattern1::new(client.clone(), _m(&acc, "1y")), + } + } +} + /// Pattern struct for repeated tree structure. pub struct _6bBlockTxindexPattern { pub _6b: AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern, @@ -2649,6 +2673,20 @@ impl _2wPattern { } } +/// Pattern struct for repeated tree structure. +pub struct _24hPattern { + pub _24h: MetricPattern1, +} + +impl _24hPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + _24h: MetricPattern1::new(client.clone(), acc.clone()), + } + } +} + // Metrics tree /// Metrics tree node. diff --git a/crates/brk_computer/src/distribution/metrics/config.rs b/crates/brk_computer/src/distribution/metrics/config.rs index f1bf371ef..3793d2248 100644 --- a/crates/brk_computer/src/distribution/metrics/config.rs +++ b/crates/brk_computer/src/distribution/metrics/config.rs @@ -12,8 +12,8 @@ use crate::{ CentsType, ComputedFromHeight, ComputedFromHeightCumulative, ComputedFromHeightCumulativeSum, ComputedFromHeightRatio, FiatFromHeight, NumericValue, PercentFromHeight, PercentRollingEmas1w1m, PercentRollingWindows, Price, RollingEmas1w1m, - RollingEmas2w, RollingWindows, ValueFromHeight, ValueFromHeightChange, - ValueFromHeightCumulative, + RollingEmas2w, RollingWindow24h, RollingWindows, RollingWindowsFrom1w, + ValueFromHeight, ValueFromHeightChange, ValueFromHeightCumulative, }, }; @@ -71,6 +71,16 @@ impl ConfigImport for RollingWindows { Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes) } } +impl ConfigImport for RollingWindow24h { + fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result { + Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes) + } +} +impl ConfigImport for RollingWindowsFrom1w { + fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result { + Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes) + } +} impl ConfigImport for RollingEmas1w1m { fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result { Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes) diff --git a/crates/brk_computer/src/distribution/metrics/realized/adjusted.rs b/crates/brk_computer/src/distribution/metrics/realized/adjusted.rs index 2a9ae8ae8..026be7135 100644 --- a/crates/brk_computer/src/distribution/metrics/realized/adjusted.rs +++ b/crates/brk_computer/src/distribution/metrics/realized/adjusted.rs @@ -26,17 +26,15 @@ impl RealizedAdjusted { pub(crate) fn forced_import(cfg: &ImportConfig) -> Result { Ok(RealizedAdjusted { adjusted_value_created: cfg.import("adjusted_value_created", Version::ZERO)?, - adjusted_value_destroyed: cfg - .import("adjusted_value_destroyed", Version::ZERO)?, - adjusted_value_created_sum: cfg - .import("adjusted_value_created", Version::ONE)?, - adjusted_value_destroyed_sum: cfg - .import("adjusted_value_destroyed", Version::ONE)?, + adjusted_value_destroyed: cfg.import("adjusted_value_destroyed", Version::ZERO)?, + adjusted_value_created_sum: cfg.import("adjusted_value_created", Version::ONE)?, + adjusted_value_destroyed_sum: cfg.import("adjusted_value_destroyed", Version::ONE)?, adjusted_sopr: cfg.import("adjusted_sopr", Version::ONE)?, adjusted_sopr_ema: cfg.import("adjusted_sopr_24h", Version::ONE)?, }) } + #[allow(clippy::too_many_arguments)] pub(crate) fn compute_rest_part2( &mut self, blocks: &blocks::Vecs, diff --git a/crates/brk_computer/src/distribution/metrics/realized/base.rs b/crates/brk_computer/src/distribution/metrics/realized/base.rs index 564ab53a7..df5a68d8b 100644 --- a/crates/brk_computer/src/distribution/metrics/realized/base.rs +++ b/crates/brk_computer/src/distribution/metrics/realized/base.rs @@ -10,9 +10,8 @@ use crate::{ blocks, distribution::state::RealizedOps, internal::{ - ByUnit, ComputedFromHeight, ComputedFromHeightCumulative, LazyFromHeight, - NegCentsUnsignedToDollars, RatioCents64, RollingWindows, SatsToCents, - ValueFromHeightCumulative, + ComputedFromHeight, ComputedFromHeightCumulative, LazyFromHeight, + NegCentsUnsignedToDollars, RatioCents64, RollingWindow24h, ValueFromHeightCumulative, }, prices, }; @@ -35,9 +34,9 @@ pub struct RealizedBase { pub value_created: ComputedFromHeight, pub value_destroyed: ComputedFromHeight, - pub value_created_sum: RollingWindows, - pub value_destroyed_sum: RollingWindows, - pub sopr: RollingWindows, + pub value_created_sum: RollingWindow24h, + pub value_destroyed_sum: RollingWindow24h, + pub sopr: RollingWindow24h, pub sent_in_profit: ValueFromHeightCumulative, pub sent_in_loss: ValueFromHeightCumulative, @@ -182,35 +181,26 @@ impl RealizedBase { exit, )?; - // SOPR: rolling sums of stateful value_created/destroyed, then ratio, then EMAs - let window_starts = blocks.count.window_starts(); + // SOPR 24h: rolling sum of stateful value_created/destroyed, then ratio self.value_created_sum.compute_rolling_sum( starting_indexes.height, - &window_starts, + &blocks.count.height_24h_ago, &self.value_created.height, exit, )?; self.value_destroyed_sum.compute_rolling_sum( starting_indexes.height, - &window_starts, + &blocks.count.height_24h_ago, &self.value_destroyed.height, exit, )?; - for ((sopr, vc), vd) in self - .sopr - .as_mut_array() - .into_iter() - .zip(self.value_created_sum.as_array()) - .zip(self.value_destroyed_sum.as_array()) - { - sopr.compute_binary::( - starting_indexes.height, - &vc.height, - &vd.height, - exit, - )?; - } + self.sopr._24h.compute_binary::( + starting_indexes.height, + &self.value_created_sum._24h.height, + &self.value_destroyed_sum._24h.height, + exit, + )?; Ok(()) } diff --git a/crates/brk_computer/src/distribution/metrics/realized/full.rs b/crates/brk_computer/src/distribution/metrics/realized/full.rs index 67a132175..bd6fcb094 100644 --- a/crates/brk_computer/src/distribution/metrics/realized/full.rs +++ b/crates/brk_computer/src/distribution/metrics/realized/full.rs @@ -19,7 +19,7 @@ use crate::{ ComputedFromHeightRatioStdDevBands, LazyFromHeight, PercentFromHeight, PercentRollingEmas1w1m, PercentRollingWindows, Price, RatioCents64, RatioCentsBp32, RatioCentsSignedCentsBps32, RatioCentsSignedDollarsBps32, RatioDollarsBp32, - RollingEmas1w1m, RollingEmas2w, RollingWindows, + RollingEmas1w1m, RollingEmas2w, RollingWindows, RollingWindowsFrom1w, }, prices, }; @@ -82,6 +82,10 @@ pub struct RealizedFull { pub sopr_24h_ema: RollingEmas1w1m, + pub value_created_sum_extended: RollingWindowsFrom1w, + pub value_destroyed_sum_extended: RollingWindowsFrom1w, + pub sopr_extended: RollingWindowsFrom1w, + pub sent_in_profit_ema: RollingEmas2w, pub sent_in_loss_ema: RollingEmas2w, @@ -154,6 +158,9 @@ impl RealizedFull { let realized_loss_ema_1w = cfg.import("realized_loss_ema_1w", v0)?; let net_realized_pnl_ema_1w = cfg.import("net_realized_pnl_ema_1w", v0)?; let sopr_24h_ema = cfg.import("sopr_24h", v1)?; + let value_created_sum_extended = cfg.import("value_created", v1)?; + let value_destroyed_sum_extended = cfg.import("value_destroyed", v1)?; + let sopr_extended = cfg.import("sopr", v1)?; let sent_in_profit_ema = cfg.import("sent_in_profit", v0)?; let sent_in_loss_ema = cfg.import("sent_in_loss", v0)?; @@ -195,6 +202,9 @@ impl RealizedFull { realized_loss_ema_1w, net_realized_pnl_ema_1w, sopr_24h_ema, + value_created_sum_extended, + value_destroyed_sum_extended, + sopr_extended, sent_in_profit_ema, sent_in_loss_ema, realized_price_ratio_percentiles: ComputedFromHeightRatioPercentiles::forced_import( @@ -314,6 +324,35 @@ impl RealizedFull { exit, )?; + // Extended rolling windows (1w, 1m, 1y) for value_created/destroyed/sopr + let window_starts = blocks.count.window_starts(); + self.value_created_sum_extended.compute_rolling_sum( + starting_indexes.height, + &window_starts, + &self.core.value_created.height, + exit, + )?; + self.value_destroyed_sum_extended.compute_rolling_sum( + starting_indexes.height, + &window_starts, + &self.core.value_destroyed.height, + exit, + )?; + for ((sopr, vc), vd) in self + .sopr_extended + .as_mut_array() + .into_iter() + .zip(self.value_created_sum_extended.as_array()) + .zip(self.value_destroyed_sum_extended.as_array()) + { + sopr.compute_binary::( + starting_indexes.height, + &vc.height, + &vd.height, + exit, + )?; + } + // Realized P/L rel to realized cap self.realized_profit_rel_to_realized_cap .compute_binary::( diff --git a/crates/brk_computer/src/internal/rolling/windows.rs b/crates/brk_computer/src/internal/rolling/windows.rs index 3bd9c7a69..7e2a6577a 100644 --- a/crates/brk_computer/src/internal/rolling/windows.rs +++ b/crates/brk_computer/src/internal/rolling/windows.rs @@ -60,3 +60,127 @@ where Ok(()) } } + +/// Single 24h rolling window (1 stored vec). +#[derive(Traversable)] +pub struct RollingWindow24h +where + T: ComputedVecValue + PartialOrd + JsonSchema, +{ + #[traversable(rename = "24h")] + pub _24h: ComputedFromHeight, +} + +impl RollingWindow24h +where + T: NumericValue + JsonSchema, +{ + pub(crate) fn forced_import( + db: &Database, + name: &str, + version: Version, + indexes: &indexes::Vecs, + ) -> Result { + Ok(Self { + _24h: ComputedFromHeight::forced_import( + db, + &format!("{name}_24h"), + version, + indexes, + )?, + }) + } + + pub(crate) fn compute_rolling_sum( + &mut self, + max_from: Height, + height_24h_ago: &impl ReadableVec, + source: &impl ReadableVec, + exit: &Exit, + ) -> Result<()> + where + T: Default + SubAssign, + { + self._24h + .height + .compute_rolling_sum(max_from, height_24h_ago, source, exit)?; + Ok(()) + } +} + +/// Extended rolling windows: 1w + 1m + 1y (3 stored vecs). +#[derive(Traversable)] +pub struct RollingWindowsFrom1w +where + T: ComputedVecValue + PartialOrd + JsonSchema, +{ + #[traversable(rename = "1w")] + pub _1w: ComputedFromHeight, + #[traversable(rename = "1m")] + pub _1m: ComputedFromHeight, + #[traversable(rename = "1y")] + pub _1y: ComputedFromHeight, +} + +impl RollingWindowsFrom1w +where + T: NumericValue + JsonSchema, +{ + pub(crate) fn forced_import( + db: &Database, + name: &str, + version: Version, + indexes: &indexes::Vecs, + ) -> Result { + Ok(Self { + _1w: ComputedFromHeight::forced_import( + db, + &format!("{name}_1w"), + version, + indexes, + )?, + _1m: ComputedFromHeight::forced_import( + db, + &format!("{name}_1m"), + version, + indexes, + )?, + _1y: ComputedFromHeight::forced_import( + db, + &format!("{name}_1y"), + version, + indexes, + )?, + }) + } + + pub fn as_array(&self) -> [&ComputedFromHeight; 3] { + [&self._1w, &self._1m, &self._1y] + } + + pub fn as_mut_array(&mut self) -> [&mut ComputedFromHeight; 3] { + [&mut self._1w, &mut self._1m, &mut self._1y] + } + + pub(crate) fn compute_rolling_sum( + &mut self, + max_from: Height, + windows: &WindowStarts<'_>, + source: &impl ReadableVec, + exit: &Exit, + ) -> Result<()> + where + T: Default + SubAssign, + { + self._1w + .height + .compute_rolling_sum(max_from, windows._1w, source, exit)?; + self._1m + .height + .compute_rolling_sum(max_from, windows._1m, source, exit)?; + self._1y + .height + .compute_rolling_sum(max_from, windows._1y, source, exit)?; + Ok(()) + } +} diff --git a/crates/brk_query/src/impl/metrics.rs b/crates/brk_query/src/impl/metrics.rs index 8fa5136ff..a2ee28ddf 100644 --- a/crates/brk_query/src/impl/metrics.rs +++ b/crates/brk_query/src/impl/metrics.rs @@ -63,6 +63,15 @@ impl Query { num_cols * CSV_HEADER_BYTES_PER_COL + num_rows * num_cols * CSV_CELL_BYTES; let mut csv = String::with_capacity(estimated_size); + // Single-column fast path: stream directly, no Vec materialization + if num_cols == 1 { + let col = columns[0]; + csv.push_str(col.name()); + csv.push('\n'); + col.write_csv_column(Some(start), Some(end), &mut csv)?; + return Ok(csv); + } + for (i, col) in columns.iter().enumerate() { if i > 0 { csv.push(','); diff --git a/crates/brk_traversable_derive/src/lib.rs b/crates/brk_traversable_derive/src/lib.rs index 93d06c519..eb2f973a2 100644 --- a/crates/brk_traversable_derive/src/lib.rs +++ b/crates/brk_traversable_derive/src/lib.rs @@ -646,10 +646,9 @@ fn find_bare_field_params<'a>( && type_path.path.segments.len() == 1 && let Some(seg) = type_path.path.segments.first() && seg.arguments.is_empty() + && let Some(tp) = type_params.iter().find(|tp| tp.ident == seg.ident) { - if let Some(tp) = type_params.iter().find(|tp| tp.ident == seg.ident) { - bare.push(&tp.ident); - } + bare.push(&tp.ident); } } bare @@ -845,7 +844,7 @@ fn gen_read_only_clone_generics( return quote! {}; } - let is_container = |ident: &syn::Ident| container_params.iter().any(|cp| *cp == ident); + let is_container = |ident: &syn::Ident| container_params.contains(&ident); // Impl params: containers get ReadOnlyClone (+ original bounds), others keep their bounds. let impl_params: Vec = generics diff --git a/crates/brk_types/src/difficultyepoch.rs b/crates/brk_types/src/difficultyepoch.rs index b3d07b555..0dbd866f8 100644 --- a/crates/brk_types/src/difficultyepoch.rs +++ b/crates/brk_types/src/difficultyepoch.rs @@ -119,6 +119,7 @@ impl Formattable for DifficultyEpoch { impl From for DifficultyEpoch { #[inline] fn from(value: f64) -> Self { + debug_assert!(value >= 0.0); Self(value.round() as u16) } } diff --git a/crates/brk_types/src/halvingepoch.rs b/crates/brk_types/src/halvingepoch.rs index 205ecbb78..14f7877a9 100644 --- a/crates/brk_types/src/halvingepoch.rs +++ b/crates/brk_types/src/halvingepoch.rs @@ -125,6 +125,7 @@ impl Formattable for HalvingEpoch { impl From for HalvingEpoch { #[inline] fn from(value: f64) -> Self { + debug_assert!(value >= 0.0); Self(value.round() as u8) } } diff --git a/crates/brk_types/src/stored_u16.rs b/crates/brk_types/src/stored_u16.rs index a4a3f9dee..54c5818a5 100644 --- a/crates/brk_types/src/stored_u16.rs +++ b/crates/brk_types/src/stored_u16.rs @@ -83,9 +83,7 @@ impl AddAssign for StoredU16 { impl From for StoredU16 { #[inline] fn from(value: f64) -> Self { - if value < 0.0 || value > u16::MAX as f64 { - panic!() - } + debug_assert!(value >= 0.0 && value <= u16::MAX as f64); Self(value as u16) } } diff --git a/crates/brk_types/src/stored_u32.rs b/crates/brk_types/src/stored_u32.rs index 8d35f2e23..b697b9aa9 100644 --- a/crates/brk_types/src/stored_u32.rs +++ b/crates/brk_types/src/stored_u32.rs @@ -135,9 +135,7 @@ impl Mul for StoredU32 { impl From for StoredU32 { #[inline] fn from(value: f64) -> Self { - if value < 0.0 || value > u32::MAX as f64 { - panic!() - } + debug_assert!(value >= 0.0 && value <= u32::MAX as f64); Self(value as u32) } } diff --git a/crates/brk_types/src/stored_u64.rs b/crates/brk_types/src/stored_u64.rs index 057c32387..ddd7f9137 100644 --- a/crates/brk_types/src/stored_u64.rs +++ b/crates/brk_types/src/stored_u64.rs @@ -108,9 +108,7 @@ impl SubAssign for StoredU64 { impl From for StoredU64 { #[inline] fn from(value: f64) -> Self { - if value < 0.0 || value > u32::MAX as f64 { - panic!() - } + debug_assert!(value >= 0.0); Self(value as u64) } } diff --git a/crates/brk_types/src/stored_u8.rs b/crates/brk_types/src/stored_u8.rs index 2b932d045..32698f49b 100644 --- a/crates/brk_types/src/stored_u8.rs +++ b/crates/brk_types/src/stored_u8.rs @@ -60,9 +60,7 @@ impl AddAssign for StoredU8 { impl From for StoredU8 { #[inline] fn from(value: f64) -> Self { - if value < 0.0 || value > u32::MAX as f64 { - panic!() - } + debug_assert!(value >= 0.0 && value <= u8::MAX as f64); Self(value as u8) } } diff --git a/crates/brk_types/src/timestamp.rs b/crates/brk_types/src/timestamp.rs index 80655bd90..00091d549 100644 --- a/crates/brk_types/src/timestamp.rs +++ b/crates/brk_types/src/timestamp.rs @@ -165,9 +165,7 @@ impl AddAssign for Timestamp { impl From for Timestamp { #[inline] fn from(value: f64) -> Self { - if value < 0.0 || value > u32::MAX as f64 { - panic!() - } + debug_assert!(value >= 0.0 && value <= u32::MAX as f64); Self(value as u32) } } diff --git a/crates/brk_types/src/weight.rs b/crates/brk_types/src/weight.rs index 83332452c..21ff506fc 100644 --- a/crates/brk_types/src/weight.rs +++ b/crates/brk_types/src/weight.rs @@ -76,6 +76,7 @@ impl From for Weight { impl From for Weight { #[inline] fn from(value: f64) -> Self { + debug_assert!(value >= 0.0); Self(value as u64) } } diff --git a/modules/brk-client/index.js b/modules/brk-client/index.js index d07cdbcab..4ac737c47 100644 --- a/modules/brk-client/index.js +++ b/modules/brk-client/index.js @@ -1623,13 +1623,16 @@ function createMetricPattern35(client, name) { return /** @type {MetricPattern35 * @property {_2wPattern} sentInLossEma * @property {BaseCumulativePattern} sentInProfit * @property {_2wPattern} sentInProfitEma - * @property {_1m1w1y24hPattern} sopr + * @property {_24hPattern} sopr * @property {_1m1wPattern} sopr24hEma + * @property {_1m1w1yPattern} soprExtended * @property {CentsSatsUsdPattern} upperPriceBand * @property {MetricPattern1} valueCreated - * @property {_1m1w1y24hPattern} valueCreatedSum + * @property {_24hPattern} valueCreatedSum + * @property {_1m1w1yPattern} valueCreatedSumExtended * @property {MetricPattern1} valueDestroyed - * @property {_1m1w1y24hPattern} valueDestroyedSum + * @property {_24hPattern} valueDestroyedSum + * @property {_1m1w1yPattern} valueDestroyedSumExtended */ /** @@ -1687,13 +1690,16 @@ function createCapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealized sentInLossEma: create_2wPattern(client, _m(acc, 'sent_in_loss_ema_2w')), sentInProfit: createBaseCumulativePattern(client, _m(acc, 'sent_in_profit')), sentInProfitEma: create_2wPattern(client, _m(acc, 'sent_in_profit_ema_2w')), - sopr: create_1m1w1y24hPattern(client, _m(acc, 'sopr')), + sopr: create_24hPattern(client, _m(acc, 'sopr_24h')), sopr24hEma: create_1m1wPattern(client, _m(acc, 'sopr_24h_ema')), + soprExtended: create_1m1w1yPattern(client, _m(acc, 'sopr')), upperPriceBand: createCentsSatsUsdPattern(client, _m(acc, 'upper_price_band')), valueCreated: createMetricPattern1(client, _m(acc, 'value_created')), - valueCreatedSum: create_1m1w1y24hPattern(client, _m(acc, 'value_created')), + valueCreatedSum: create_24hPattern(client, _m(acc, 'value_created_24h')), + valueCreatedSumExtended: create_1m1w1yPattern(client, _m(acc, 'value_created')), valueDestroyed: createMetricPattern1(client, _m(acc, 'value_destroyed')), - valueDestroyedSum: create_1m1w1y24hPattern(client, _m(acc, 'value_destroyed')), + valueDestroyedSum: create_24hPattern(client, _m(acc, 'value_destroyed_24h')), + valueDestroyedSumExtended: create_1m1w1yPattern(client, _m(acc, 'value_destroyed')), }; } @@ -1884,11 +1890,11 @@ function createInvestedNetNuplSupplyUnrealizedPattern3(client, acc) { * @property {CumulativeHeightPattern} realizedProfit * @property {BaseCumulativePattern} sentInLoss * @property {BaseCumulativePattern} sentInProfit - * @property {_1m1w1y24hPattern} sopr + * @property {_24hPattern} sopr * @property {MetricPattern1} valueCreated - * @property {_1m1w1y24hPattern} valueCreatedSum + * @property {_24hPattern} valueCreatedSum * @property {MetricPattern1} valueDestroyed - * @property {_1m1w1y24hPattern} valueDestroyedSum + * @property {_24hPattern} valueDestroyedSum */ /** @@ -1911,11 +1917,11 @@ function createMvrvNegNetRealizedSentSoprValuePattern(client, acc) { realizedProfit: createCumulativeHeightPattern(client, _m(acc, 'realized_profit')), sentInLoss: createBaseCumulativePattern(client, _m(acc, 'sent_in_loss')), sentInProfit: createBaseCumulativePattern(client, _m(acc, 'sent_in_profit')), - sopr: create_1m1w1y24hPattern(client, _m(acc, 'sopr')), + sopr: create_24hPattern(client, _m(acc, 'sopr_24h')), valueCreated: createMetricPattern1(client, _m(acc, 'value_created')), - valueCreatedSum: create_1m1w1y24hPattern(client, _m(acc, 'value_created')), + valueCreatedSum: create_24hPattern(client, _m(acc, 'value_created_24h')), valueDestroyed: createMetricPattern1(client, _m(acc, 'value_destroyed')), - valueDestroyedSum: create_1m1w1y24hPattern(client, _m(acc, 'value_destroyed')), + valueDestroyedSum: create_24hPattern(client, _m(acc, 'value_destroyed_24h')), }; } @@ -3157,6 +3163,29 @@ function createChangeHalvedTotalPattern(client, acc) { }; } +/** + * @template T + * @typedef {Object} _1m1w1yPattern + * @property {MetricPattern1} _1m + * @property {MetricPattern1} _1w + * @property {MetricPattern1} _1y + */ + +/** + * Create a _1m1w1yPattern pattern node + * @template T + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {_1m1w1yPattern} + */ +function create_1m1w1yPattern(client, acc) { + return { + _1m: createMetricPattern1(client, _m(acc, '1m')), + _1w: createMetricPattern1(client, _m(acc, '1w')), + _1y: createMetricPattern1(client, _m(acc, '1y')), + }; +} + /** * @template T * @typedef {Object} _6bBlockTxindexPattern @@ -3488,6 +3517,25 @@ function create_2wPattern(client, acc) { }; } +/** + * @template T + * @typedef {Object} _24hPattern + * @property {MetricPattern1} _24h + */ + +/** + * Create a _24hPattern pattern node + * @template T + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {_24hPattern} + */ +function create_24hPattern(client, acc) { + return { + _24h: createMetricPattern1(client, acc), + }; +} + // Catalog tree typedefs /** diff --git a/packages/brk_client/brk_client/__init__.py b/packages/brk_client/brk_client/__init__.py index 114085b4c..8fc15e5de 100644 --- a/packages/brk_client/brk_client/__init__.py +++ b/packages/brk_client/brk_client/__init__.py @@ -2118,13 +2118,16 @@ class CapCapitulationGrossInvestorLossLowerMvrvNegNetPeakProfitRealizedSellSentS self.sent_in_loss_ema: _2wPattern = _2wPattern(client, _m(acc, 'sent_in_loss_ema_2w')) self.sent_in_profit: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_profit')) self.sent_in_profit_ema: _2wPattern = _2wPattern(client, _m(acc, 'sent_in_profit_ema_2w')) - self.sopr: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, _m(acc, 'sopr')) + self.sopr: _24hPattern[StoredF64] = _24hPattern(client, _m(acc, 'sopr_24h')) self.sopr_24h_ema: _1m1wPattern = _1m1wPattern(client, _m(acc, 'sopr_24h_ema')) + self.sopr_extended: _1m1w1yPattern[StoredF64] = _1m1w1yPattern(client, _m(acc, 'sopr')) self.upper_price_band: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'upper_price_band')) self.value_created: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'value_created')) - self.value_created_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'value_created')) + self.value_created_sum: _24hPattern[Cents] = _24hPattern(client, _m(acc, 'value_created_24h')) + self.value_created_sum_extended: _1m1w1yPattern[Cents] = _1m1w1yPattern(client, _m(acc, 'value_created')) self.value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'value_destroyed')) - self.value_destroyed_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'value_destroyed')) + self.value_destroyed_sum: _24hPattern[Cents] = _24hPattern(client, _m(acc, 'value_destroyed_24h')) + self.value_destroyed_sum_extended: _1m1w1yPattern[Cents] = _1m1w1yPattern(client, _m(acc, 'value_destroyed')) class _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdSmaZscorePattern: """Pattern struct for repeated tree structure.""" @@ -2225,11 +2228,11 @@ class MvrvNegNetRealizedSentSoprValuePattern: self.realized_profit: CumulativeHeightPattern[Cents] = CumulativeHeightPattern(client, _m(acc, 'realized_profit')) self.sent_in_loss: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_loss')) self.sent_in_profit: BaseCumulativePattern = BaseCumulativePattern(client, _m(acc, 'sent_in_profit')) - self.sopr: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, _m(acc, 'sopr')) + self.sopr: _24hPattern[StoredF64] = _24hPattern(client, _m(acc, 'sopr_24h')) self.value_created: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'value_created')) - self.value_created_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'value_created')) + self.value_created_sum: _24hPattern[Cents] = _24hPattern(client, _m(acc, 'value_created_24h')) self.value_destroyed: MetricPattern1[Cents] = MetricPattern1(client, _m(acc, 'value_destroyed')) - self.value_destroyed_sum: _1m1w1y24hPattern[Cents] = _1m1w1y24hPattern(client, _m(acc, 'value_destroyed')) + self.value_destroyed_sum: _24hPattern[Cents] = _24hPattern(client, _m(acc, 'value_destroyed_24h')) class BpsRatioPattern2: """Pattern struct for repeated tree structure.""" @@ -2784,6 +2787,15 @@ class ChangeHalvedTotalPattern: self.halved: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, _m(acc, 'halved')) self.total: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, acc) +class _1m1w1yPattern(Generic[T]): + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self._1m: MetricPattern1[T] = MetricPattern1(client, _m(acc, '1m')) + self._1w: MetricPattern1[T] = MetricPattern1(client, _m(acc, '1w')) + self._1y: MetricPattern1[T] = MetricPattern1(client, _m(acc, '1y')) + class _6bBlockTxindexPattern(Generic[T]): """Pattern struct for repeated tree structure.""" @@ -2921,6 +2933,13 @@ class _2wPattern: """Create pattern node with accumulated metric name.""" self._2w: BtcCentsSatsUsdPattern = BtcCentsSatsUsdPattern(client, acc) +class _24hPattern(Generic[T]): + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self._24h: MetricPattern1[T] = MetricPattern1(client, acc) + # Metrics tree classes class MetricsTree_Blocks_Difficulty: