global: snap

This commit is contained in:
nym21
2026-04-15 12:51:30 +02:00
parent 39da441d14
commit 08ba4ad996
24 changed files with 1076 additions and 620 deletions

View File

@@ -3,7 +3,7 @@ use std::path::Path;
use brk_error::Result;
use brk_types::Version;
use super::{Vecs, realized_envelope::RealizedEnvelope};
use super::{Vecs, rarity_meter::RarityMeter};
use crate::{
indexes,
internal::{
@@ -40,7 +40,7 @@ impl Vecs {
let stock_to_flow = PerBlock::forced_import(&db, "stock_to_flow", v, indexes)?;
let seller_exhaustion = PerBlock::forced_import(&db, "seller_exhaustion", v, indexes)?;
let realized_envelope = RealizedEnvelope::forced_import(&db, v, indexes)?;
let rarity_meter = RarityMeter::forced_import(&db, v, indexes)?;
let this = Self {
db,
@@ -54,7 +54,7 @@ impl Vecs {
dormancy,
stock_to_flow,
seller_exhaustion,
realized_envelope,
rarity_meter,
};
finalize_db(&this.db, &this)?;
Ok(this)

View File

@@ -1,7 +1,7 @@
mod compute;
mod gini;
mod import;
pub mod realized_envelope;
pub mod rarity_meter;
mod vecs;
pub use vecs::Vecs;

View File

@@ -4,13 +4,12 @@ use brk_types::{Cents, Height, Indexes, StoredI8, Version};
use vecdb::{AnyVec, Database, Exit, ReadableVec, Rw, StorageMode, WritableVec};
use crate::{
cointime, distribution, indexes,
indexes,
internal::{PerBlock, Price, RatioPerBlockPercentiles},
prices,
};
#[derive(Traversable)]
pub struct RealizedEnvelope<M: StorageMode = Rw> {
pub struct RarityMeterInner<M: StorageMode = Rw> {
pub pct0_5: Price<PerBlock<Cents, M>>,
pub pct1: Price<PerBlock<Cents, M>>,
pub pct2: Price<PerBlock<Cents, M>>,
@@ -23,113 +22,85 @@ pub struct RealizedEnvelope<M: StorageMode = Rw> {
pub score: PerBlock<StoredI8, M>,
}
const VERSION: Version = Version::new(3);
impl RealizedEnvelope {
impl RarityMeterInner {
pub(crate) fn forced_import(
db: &Database,
prefix: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
let v = version + VERSION;
Ok(Self {
pct0_5: Price::forced_import(db, "realized_envelope_pct0_5", v, indexes)?,
pct1: Price::forced_import(db, "realized_envelope_pct01", v, indexes)?,
pct2: Price::forced_import(db, "realized_envelope_pct02", v, indexes)?,
pct5: Price::forced_import(db, "realized_envelope_pct05", v, indexes)?,
pct95: Price::forced_import(db, "realized_envelope_pct95", v, indexes)?,
pct98: Price::forced_import(db, "realized_envelope_pct98", v, indexes)?,
pct99: Price::forced_import(db, "realized_envelope_pct99", v, indexes)?,
pct99_5: Price::forced_import(db, "realized_envelope_pct99_5", v, indexes)?,
index: PerBlock::forced_import(db, "realized_envelope_index", v, indexes)?,
score: PerBlock::forced_import(db, "realized_envelope_score", v, indexes)?,
pct0_5: Price::forced_import(db, &format!("{prefix}_pct0_5"), version, indexes)?,
pct1: Price::forced_import(db, &format!("{prefix}_pct01"), version, indexes)?,
pct2: Price::forced_import(db, &format!("{prefix}_pct02"), version, indexes)?,
pct5: Price::forced_import(db, &format!("{prefix}_pct05"), version, indexes)?,
pct95: Price::forced_import(db, &format!("{prefix}_pct95"), version, indexes)?,
pct98: Price::forced_import(db, &format!("{prefix}_pct98"), version, indexes)?,
pct99: Price::forced_import(db, &format!("{prefix}_pct99"), version, indexes)?,
pct99_5: Price::forced_import(db, &format!("{prefix}_pct99_5"), version, indexes)?,
index: PerBlock::forced_import(db, &format!("{prefix}_index"), version, indexes)?,
score: PerBlock::forced_import(db, &format!("{prefix}_score"), version, indexes)?,
})
}
pub(crate) fn compute(
pub(super) fn compute(
&mut self,
distribution: &distribution::Vecs,
cointime: &cointime::Vecs,
prices: &prices::Vecs,
models: &[&RatioPerBlockPercentiles],
spot: &impl ReadableVec<Height, Cents>,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let realized = &distribution.utxo_cohorts.all.metrics.realized;
let ct = &cointime.prices;
let sth_realized = &distribution.utxo_cohorts.sth.metrics.realized;
let lth_realized = &distribution.utxo_cohorts.lth.metrics.realized;
let models: [&RatioPerBlockPercentiles; 10] = [
&realized.price_ratio_percentiles,
&realized.investor.price.percentiles,
&sth_realized.price_ratio_percentiles,
&sth_realized.investor.price.percentiles,
&lth_realized.price_ratio_percentiles,
&lth_realized.investor.price.percentiles,
&ct.vaulted.percentiles,
&ct.active.percentiles,
&ct.true_market_mean.percentiles,
&ct.cointime.percentiles,
];
macro_rules! sources {
($pct:ident) => {
models.each_ref().map(|m| &m.$pct.price.cents.height)
};
}
let gather = |f: fn(&RatioPerBlockPercentiles) -> &_| -> Vec<_> {
models.iter().map(|m| f(m)).collect()
};
// Lower percentiles: max across all models (tightest lower bound)
self.pct0_5.cents.height.compute_max_of_others(
starting_indexes.height,
&sources!(pct0_5),
&gather(|m| &m.pct0_5.price.cents.height),
exit,
)?;
self.pct1.cents.height.compute_max_of_others(
starting_indexes.height,
&sources!(pct1),
&gather(|m| &m.pct1.price.cents.height),
exit,
)?;
self.pct2.cents.height.compute_max_of_others(
starting_indexes.height,
&sources!(pct2),
&gather(|m| &m.pct2.price.cents.height),
exit,
)?;
self.pct5.cents.height.compute_max_of_others(
starting_indexes.height,
&sources!(pct5),
&gather(|m| &m.pct5.price.cents.height),
exit,
)?;
// Upper percentiles: min across all models (tightest upper bound)
self.pct95.cents.height.compute_min_of_others(
starting_indexes.height,
&sources!(pct95),
&gather(|m| &m.pct95.price.cents.height),
exit,
)?;
self.pct98.cents.height.compute_min_of_others(
starting_indexes.height,
&sources!(pct98),
&gather(|m| &m.pct98.price.cents.height),
exit,
)?;
self.pct99.cents.height.compute_min_of_others(
starting_indexes.height,
&sources!(pct99),
&gather(|m| &m.pct99.price.cents.height),
exit,
)?;
self.pct99_5.cents.height.compute_min_of_others(
starting_indexes.height,
&sources!(pct99_5),
&gather(|m| &m.pct99_5.price.cents.height),
exit,
)?;
let spot = &prices.spot.cents.height;
// Zone: spot vs own envelope bands (-4 to +4)
self.compute_index(spot, starting_indexes, exit)?;
// Temperature: per-model band crossings (-40 to +40)
self.compute_score(&models, spot, starting_indexes, exit)?;
self.compute_score(models, spot, starting_indexes, exit)?;
Ok(())
}
@@ -140,7 +111,7 @@ impl RealizedEnvelope {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let bands: [&_; 8] = [
let bands = [
&self.pct0_5.cents.height,
&self.pct1.cents.height,
&self.pct2.cents.height,
@@ -213,7 +184,7 @@ impl RealizedEnvelope {
fn compute_score(
&mut self,
models: &[&RatioPerBlockPercentiles; 10],
models: &[&RatioPerBlockPercentiles],
spot: &impl ReadableVec<Height, Cents>,
starting_indexes: &Indexes,
exit: &Exit,

View File

@@ -0,0 +1,88 @@
mod inner;
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Indexes, Version};
use vecdb::{Database, Exit, Rw, StorageMode};
use crate::{distribution, indexes, prices};
pub use inner::RarityMeterInner;
#[derive(Traversable)]
pub struct RarityMeter<M: StorageMode = Rw> {
pub full: RarityMeterInner<M>,
pub local: RarityMeterInner<M>,
pub cycle: RarityMeterInner<M>,
}
const VERSION: Version = Version::new(4);
impl RarityMeter {
pub(crate) fn forced_import(
db: &Database,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
let v = version + VERSION;
Ok(Self {
full: RarityMeterInner::forced_import(db, "rarity_meter", v, indexes)?,
local: RarityMeterInner::forced_import(db, "local_rarity_meter", v, indexes)?,
cycle: RarityMeterInner::forced_import(db, "cycle_rarity_meter", v, indexes)?,
})
}
pub(crate) fn compute(
&mut self,
distribution: &distribution::Vecs,
prices: &prices::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let realized = &distribution.utxo_cohorts.all.metrics.realized;
let sth_realized = &distribution.utxo_cohorts.sth.metrics.realized;
let lth_realized = &distribution.utxo_cohorts.lth.metrics.realized;
let spot = &prices.spot.cents.height;
// Full: all + sth + lth (rp + ip), 6 models
self.full.compute(
&[
&realized.price_ratio_percentiles,
&realized.investor.price.percentiles,
&sth_realized.price_ratio_percentiles,
&sth_realized.investor.price.percentiles,
&lth_realized.price_ratio_percentiles,
&lth_realized.investor.price.percentiles,
],
spot,
starting_indexes,
exit,
)?;
// Local: sth only, 2 models
self.local.compute(
&[
&sth_realized.price_ratio_percentiles,
&sth_realized.investor.price.percentiles,
],
spot,
starting_indexes,
exit,
)?;
// Cycle: all + lth, 4 models
self.cycle.compute(
&[
&realized.price_ratio_percentiles,
&realized.investor.price.percentiles,
&lth_realized.price_ratio_percentiles,
&lth_realized.investor.price.percentiles,
],
spot,
starting_indexes,
exit,
)?;
Ok(())
}
}

View File

@@ -2,7 +2,7 @@ use brk_traversable::Traversable;
use brk_types::{BasisPoints16, BasisPoints32, StoredF32};
use vecdb::{Database, Rw, StorageMode};
use super::realized_envelope::RealizedEnvelope;
use super::rarity_meter::RarityMeter;
use crate::internal::{PerBlock, PercentPerBlock, RatioPerBlock};
#[derive(Traversable)]
@@ -25,5 +25,5 @@ pub struct Vecs<M: StorageMode = Rw> {
pub dormancy: DormancyVecs<M>,
pub stock_to_flow: PerBlock<StoredF32, M>,
pub seller_exhaustion: PerBlock<StoredF32, M>,
pub realized_envelope: RealizedEnvelope<M>,
pub rarity_meter: RarityMeter<M>,
}

View File

@@ -467,9 +467,8 @@ impl Computer {
Ok(())
})?;
self.indicators.realized_envelope.compute(
self.indicators.rarity_meter.compute(
&self.distribution,
&self.cointime,
&self.prices,
&starting_indexes,
exit,