global: snapshot

This commit is contained in:
nym21
2026-03-07 17:05:45 +01:00
parent d4faedfba1
commit cbad78962f
18 changed files with 349 additions and 82 deletions
+50 -12
View File
@@ -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<StoredF64>,
pub sopr: _24hPattern<StoredF64>,
pub sopr_24h_ema: _1m1wPattern,
pub sopr_extended: _1m1w1yPattern<StoredF64>,
pub upper_price_band: CentsSatsUsdPattern,
pub value_created: MetricPattern1<Cents>,
pub value_created_sum: _1m1w1y24hPattern<Cents>,
pub value_created_sum: _24hPattern<Cents>,
pub value_created_sum_extended: _1m1w1yPattern<Cents>,
pub value_destroyed: MetricPattern1<Cents>,
pub value_destroyed_sum: _1m1w1y24hPattern<Cents>,
pub value_destroyed_sum: _24hPattern<Cents>,
pub value_destroyed_sum_extended: _1m1w1yPattern<Cents>,
}
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<Cents>,
pub sent_in_loss: BaseCumulativePattern,
pub sent_in_profit: BaseCumulativePattern,
pub sopr: _1m1w1y24hPattern<StoredF64>,
pub sopr: _24hPattern<StoredF64>,
pub value_created: MetricPattern1<Cents>,
pub value_created_sum: _1m1w1y24hPattern<Cents>,
pub value_created_sum: _24hPattern<Cents>,
pub value_destroyed: MetricPattern1<Cents>,
pub value_destroyed_sum: _1m1w1y24hPattern<Cents>,
pub value_destroyed_sum: _24hPattern<Cents>,
}
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<T> {
pub _1m: MetricPattern1<T>,
pub _1w: MetricPattern1<T>,
pub _1y: MetricPattern1<T>,
}
impl<T: DeserializeOwned> _1m1w1yPattern<T> {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, 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<T> {
pub _6b: AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern<T>,
@@ -2649,6 +2673,20 @@ impl _2wPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct _24hPattern<T> {
pub _24h: MetricPattern1<T>,
}
impl<T: DeserializeOwned> _24hPattern<T> {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
_24h: MetricPattern1::new(client.clone(), acc.clone()),
}
}
}
// Metrics tree
/// Metrics tree node.
@@ -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<T: NumericValue + JsonSchema> ConfigImport for RollingWindows<T> {
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
}
}
impl<T: NumericValue + JsonSchema> ConfigImport for RollingWindow24h<T> {
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
}
}
impl<T: NumericValue + JsonSchema> ConfigImport for RollingWindowsFrom1w<T> {
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
}
}
impl<T: NumericValue + JsonSchema> ConfigImport for RollingEmas1w1m<T> {
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
@@ -26,17 +26,15 @@ impl RealizedAdjusted {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
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,
@@ -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<M: StorageMode = Rw> {
pub value_created: ComputedFromHeight<Cents, M>,
pub value_destroyed: ComputedFromHeight<Cents, M>,
pub value_created_sum: RollingWindows<Cents, M>,
pub value_destroyed_sum: RollingWindows<Cents, M>,
pub sopr: RollingWindows<StoredF64, M>,
pub value_created_sum: RollingWindow24h<Cents, M>,
pub value_destroyed_sum: RollingWindow24h<Cents, M>,
pub sopr: RollingWindow24h<StoredF64, M>,
pub sent_in_profit: ValueFromHeightCumulative<M>,
pub sent_in_loss: ValueFromHeightCumulative<M>,
@@ -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::<Cents, Cents, RatioCents64>(
starting_indexes.height,
&vc.height,
&vd.height,
exit,
)?;
}
self.sopr._24h.compute_binary::<Cents, Cents, RatioCents64>(
starting_indexes.height,
&self.value_created_sum._24h.height,
&self.value_destroyed_sum._24h.height,
exit,
)?;
Ok(())
}
@@ -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<M: StorageMode = Rw> {
pub sopr_24h_ema: RollingEmas1w1m<StoredF64, M>,
pub value_created_sum_extended: RollingWindowsFrom1w<Cents, M>,
pub value_destroyed_sum_extended: RollingWindowsFrom1w<Cents, M>,
pub sopr_extended: RollingWindowsFrom1w<StoredF64, M>,
pub sent_in_profit_ema: RollingEmas2w<M>,
pub sent_in_loss_ema: RollingEmas2w<M>,
@@ -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::<Cents, Cents, RatioCents64>(
starting_indexes.height,
&vc.height,
&vd.height,
exit,
)?;
}
// Realized P/L rel to realized cap
self.realized_profit_rel_to_realized_cap
.compute_binary::<Cents, Cents, RatioCentsBp32>(
@@ -60,3 +60,127 @@ where
Ok(())
}
}
/// Single 24h rolling window (1 stored vec).
#[derive(Traversable)]
pub struct RollingWindow24h<T, M: StorageMode = Rw>
where
T: ComputedVecValue + PartialOrd + JsonSchema,
{
#[traversable(rename = "24h")]
pub _24h: ComputedFromHeight<T, M>,
}
impl<T> RollingWindow24h<T>
where
T: NumericValue + JsonSchema,
{
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
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<Height, Height>,
source: &impl ReadableVec<Height, T>,
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<T, M: StorageMode = Rw>
where
T: ComputedVecValue + PartialOrd + JsonSchema,
{
#[traversable(rename = "1w")]
pub _1w: ComputedFromHeight<T, M>,
#[traversable(rename = "1m")]
pub _1m: ComputedFromHeight<T, M>,
#[traversable(rename = "1y")]
pub _1y: ComputedFromHeight<T, M>,
}
impl<T> RollingWindowsFrom1w<T>
where
T: NumericValue + JsonSchema,
{
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
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<T>; 3] {
[&self._1w, &self._1m, &self._1y]
}
pub fn as_mut_array(&mut self) -> [&mut ComputedFromHeight<T>; 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<Height, T>,
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(())
}
}
+9
View File
@@ -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<T> 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(',');
+3 -4
View File
@@ -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<proc_macro2::TokenStream> = generics
+1
View File
@@ -119,6 +119,7 @@ impl Formattable for DifficultyEpoch {
impl From<f64> for DifficultyEpoch {
#[inline]
fn from(value: f64) -> Self {
debug_assert!(value >= 0.0);
Self(value.round() as u16)
}
}
+1
View File
@@ -125,6 +125,7 @@ impl Formattable for HalvingEpoch {
impl From<f64> for HalvingEpoch {
#[inline]
fn from(value: f64) -> Self {
debug_assert!(value >= 0.0);
Self(value.round() as u8)
}
}
+1 -3
View File
@@ -83,9 +83,7 @@ impl AddAssign for StoredU16 {
impl From<f64> 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)
}
}
+1 -3
View File
@@ -135,9 +135,7 @@ impl Mul<usize> for StoredU32 {
impl From<f64> 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)
}
}
+1 -3
View File
@@ -108,9 +108,7 @@ impl SubAssign for StoredU64 {
impl From<f64> 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)
}
}
+1 -3
View File
@@ -60,9 +60,7 @@ impl AddAssign for StoredU8 {
impl From<f64> 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)
}
}
+1 -3
View File
@@ -165,9 +165,7 @@ impl AddAssign for Timestamp {
impl From<f64> 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)
}
}
+1
View File
@@ -76,6 +76,7 @@ impl From<usize> for Weight {
impl From<f64> for Weight {
#[inline]
fn from(value: f64) -> Self {
debug_assert!(value >= 0.0);
Self(value as u64)
}
}